/* login.c */ #define LOGIN_PROGRAM #include #include #include #include #include #include #include "config.h" #include "str_defs.h" #include "pw_defs.h" #include "utmp_defs.h" #include "prot_defs.h" #define SD(A,B) !str_diffn(A, B, sizeof(A)) #define SC(A,B) str_copynz(A, B, sizeof(A)) static void myexit(int n,char *s) { write(2,s,str_len(s)); write(2,"\n",1); _exit(n); } int main(int argc, char **argv, char **env) { struct passwd *pw=0; struct spwd *spwd; char buf[1200], lastlog[96]; char *tty, *dev_tty=0, *program, *username=0, *p; char *arg[8] = {buf,0,0,0, 0,0,0,0}; int fd,r,OK=0,flag_auto=0; struct termios oldtermios; if (ioctl(0, TCGETS, &oldtermios)) _exit(100); oldtermios.c_lflag &= ~(ECHO|ISIG); tcsetattr(0,TCSAFLUSH,&oldtermios); if ((dev_tty=ttyname(0)) && !str_diffn("/dev/",dev_tty,5)) tty=dev_tty+5; else { dev_tty = 0; tty="UNKNOWN"; } program=strip_slash(argv[0]); argv++; (void)argc; while ((p=argv[0]) && p[0] == '-') { if (p[1]=='f') { if (getuid()) goto do_it; if (p[2]) p += 2; else p=argv[1]; if (p && *p && *p != '-') { flag_auto=1; argv[0]=p; break; } else goto do_it; } argv++; } if (argv[0] == 0) goto do_it; if (flag_auto == 0) if (read_password(buf)) goto do_it; pw = nv_getpwnam(argv[0]); if (pw) { username = pw->pw_name; if (pw->pw_passwd[0]=='*' || pw->pw_passwd[0]=='!') goto do_it; } if (!username || *username == 0) goto do_it; if (flag_auto==1) OK=1; else { if ((spwd = nv_getspnam(username))==0) goto do_it; OK = pass_check(buf, spwd->sp_pwdp); } do_it: byte_zero(buf,sizeof(buf)); oldtermios.c_lflag |= ECHO; tcsetattr(0, TCSAFLUSH, &oldtermios); if (!username) username="UNKNOWN"; log_do(buf,OK, program,username,tty); if (!OK) { sleep(1); myexit(100,"Sorry :-)"); } utmp_do(username, tty, getpid()); lastlog_do(lastlog, pw->pw_uid, tty); get_tz(0,-1); if (dev_tty) { struct group *gr = nv_getgrnam("tty"); chown(dev_tty, pw->pw_uid, gr ? gr->gr_gid : pw->pw_gid); chmod(dev_tty, 0620); } p = 0; if (nv_initgroups(pw->pw_name,pw->pw_gid) == -1) p = "groups"; else if (setgid(pw->pw_gid) == -1) p = "gid"; else if (setuid(pw->pw_uid) == -1) p = "uid"; if (p) { mycat(buf, "unable to set", p); myexit(111, buf); } if (chdir(pw->pw_dir)) { r = mycat(buf,"unable to chdir: ",pw->pw_dir); buf[r++] = '\n'; write(1,buf,r); chdir("/"); } if ((fd=open(".hushlogin", O_RDONLY)) >=0) { close(fd); } else { if ((fd=open("/etc/motd", O_RDONLY)) != -1) { while ((r=read(fd,buf,sizeof buf)) >0) write(1,buf,r); close(fd); } write(1, lastlog, str_len(lastlog)); } p=buf; p += 1 + mycat(p,"-",strip_slash(pw->pw_shell)); arg[2]=p; p += 1 + mycat(p,"HOME=",pw->pw_dir); arg[3]=p; p += 1 + mycat(p,"USER=",pw->pw_name); arg[4]=p; p += 1 + mycat(p,"SHELL=",pw->pw_shell); for (; *env; env++) if (!str_diffn(*env,"TERM=",5)) {arg[5]=*env; break;} /* arg[7] */ oldtermios.c_lflag |= ISIG; tcsetattr(0, TCSAFLUSH, &oldtermios); execve(pw->pw_shell,arg,arg+2); return(1); }