1 #include "error.h"
2 #include "pathexec.h"
3 #include "prot.h"
4 
5 extern char *crypt();
6 #include <pwd.h>
7 static struct passwd *pw;
8 
9 #include "hasspnam.h"
10 #ifdef HASGETSPNAM
11 #include <shadow.h>
12 static struct spwd *spw;
13 #endif
14 
15 #include "hasuserpw.h"
16 #ifdef HASUSERPW
17 #include <userpw.h>
18 static struct userpw *upw;
19 #endif
20 
21 static char up[513];
22 static int uplen;
23 
main(int argc,char ** argv)24 main(int argc,char **argv)
25 {
26   char *login;
27   char *password;
28   char *encrypted;
29   char *stored;
30   int r;
31   int i;
32 
33   if (!argv[1]) _exit(2);
34 
35   uplen = 0;
36   for (;;) {
37     do
38       r = read(3,up + uplen,sizeof(up) - uplen);
39     while ((r == -1) && (errno == error_intr));
40     if (r == -1) _exit(111);
41     if (r == 0) break;
42     uplen += r;
43     if (uplen >= sizeof(up)) _exit(1);
44   }
45   close(3);
46 
47   i = 0;
48   if (i >= uplen) _exit(2);
49   login = up + i;
50   while (up[i++]) if (i >= uplen) _exit(2);
51   password = up + i;
52   if (i >= uplen) _exit(2);
53   while (up[i++]) if (i >= uplen) _exit(2);
54 
55   pw = getpwnam(login);
56   if (pw)
57     stored = pw->pw_passwd;
58   else {
59     if (errno == error_txtbsy) _exit(111);
60     _exit(1);
61   }
62 #ifdef HASUSERPW
63   upw = getuserpw(login);
64   if (upw)
65     stored = upw->upw_passwd;
66   else
67     if (errno == error_txtbsy) _exit(111);
68 #endif
69 #ifdef HASGETSPNAM
70   spw = getspnam(login);
71   if (spw)
72     stored = spw->sp_pwdp;
73   else
74     if (errno == error_txtbsy) _exit(111);
75 #endif
76   if (!stored) _exit(1);
77 
78   encrypted = crypt(password,stored);
79   for (i = 0;i < sizeof(up);++i) up[i] = 0;
80 
81   if (!*stored || strcmp(encrypted,stored)) _exit(1);
82 
83   if (prot_gid((int) pw->pw_gid) == -1) _exit(1);
84   if (prot_uid((int) pw->pw_uid) == -1) _exit(1);
85   if (chdir(pw->pw_dir) == -1) _exit(111);
86 
87   if (!pathexec_env("USER",pw->pw_name)) _exit(111);
88   if (!pathexec_env("HOME",pw->pw_dir)) _exit(111);
89   if (!pathexec_env("SHELL",pw->pw_shell)) _exit(111);
90   pathexec(argv + 1);
91   _exit(111);
92 }
93