#include #include #include #include #include "md5.h" #include "pw_defs.h" #include "utmp_defs.h" #include "time_defs.h" #define fdin 3 #define fdout 4 #define ZZ(A) if (A) byte_zero(A, str_len(A)) #define FL(X,Var) *p++ = X; p += fmt_ulong(p, Var); ++p #define FN(L,Var) p += str_copy(p,L); p += fmt_ulong(p, Var); ++p #define FS(L,Var) p += mycat(p,L,Var); ++p static struct passwd *pw; static char *stored, *encrypted; static char up[513]; static int z(int n) { byte_zero(up, sizeof(up)); ZZ(stored); ZZ(encrypted); if (n==0) return 0; close(fdin); close(fdout); _exit(n); } static void check_pass(char *program, char *tty) { char *password; /* user name is up */ int k=0, i=0, uplen; close(0); close(1); close(2); errno = 0; uplen = SAFE_IO(read, fdin, up, sizeof(up)); if (errno) z(111); if (uplen >= (int)sizeof(up)) z(1); close(fdin); if (uplen==0) z(2); while (up[i++]) if (i >= uplen) z(2); password = up + i; if (i >= uplen) z(2); while (up[i++]) if (i >= uplen) z(2); pw = nv_getpwnam(up); if (pw) { struct spwd *spw; if (ipw_passwd[0]=='*' || pw->pw_passwd[0]=='!') goto do_it; spw = nv_getspnam(up); if (spw) stored = spw->sp_pwdp; } if (!stored || str_len(stored) < 12) k=0; else { encrypted = md5crypt(password, stored); k = !str_diff(encrypted, stored); /* 1 good password */ } do_it: z(0); /* zero buffers */ if (pw) log_do(up, k, program, pw->pw_name, tty); z(!k); } int main(int argc, char **argv) { int i, n = NGROUPS_MAX; struct group *ttygr=0; gid_t groups[NGROUPS_MAX+1]; char *p, *tty, lastlog[96]; (void)argc; tty = ttyname(0); if (tty==0) tty=""; if (tty && !str_diffn(tty, "/dev/", 5)) p = tty + 5; else p = "UNKNOWN"; check_pass(strip_slash(argv[0]), p); utmp_do(pw->pw_name, p, getppid()); lastlog_do(lastlog, pw->pw_uid, p); get_tz(0,-1); if (nv_getgrouplist(pw->pw_name, pw->pw_gid, groups, &n) || n > NGROUPS_MAX) z(5); ttygr = nv_getgrnam("tty"); z(0); for (p=up,i=0; i 440) z(1); } if (p-up + str_len(pw->pw_dir) + str_len(pw->pw_name) + str_len(pw->pw_shell) + str_len(tty) + str_len(lastlog) > 400) z(1); FL('t', ttygr ? ttygr->gr_gid : (gid_t)pw->pw_gid); FN("UID=", pw->pw_uid); FN("GID=", pw->pw_gid); FS("USER=", pw->pw_name); FS("HOME=", pw->pw_dir); FS("SHELL=", pw->pw_shell); FS("TTY=", tty); p += str_copy(p, lastlog); n = (p-up)+5; if (n != SAFE_IO(write, fdout, up, n)) z(1); close(fdout); z(0); return 0; }