|
|
1.1 ! root 1: /* ! 2: * login [ -f name ] [ -p passwdline ] [ command ] ! 3: * -f: if su, log in with no password ! 4: * -p: if su, use entire password line. ! 5: * command: if given, just execute command ! 6: */ ! 7: ! 8: #include <sys/types.h> ! 9: #include <sgtty.h> ! 10: #include <utmp.h> ! 11: #include <signal.h> ! 12: #include <pwd.h> ! 13: #include <stdio.h> ! 14: #include <sys/stat.h> ! 15: #define SCPYN(a, b) strncpy(a, b, sizeof(a)) ! 16: ! 17: #define ISIZE 32 ! 18: #define POSTMKSIZ sizeof "From Sun Jan 00 00:00:00 1979" ! 19: char maildir[30] = "/usr/spool/mail/"; ! 20: struct passwd nouser = {"", "nope"}; ! 21: struct sgttyb ttyb; ! 22: struct utmp utmp; ! 23: char minusnam[16] = "-"; ! 24: char homedir[64] = "HOME="; ! 25: char path[] = "PATH=:/bin:/usr/bin"; ! 26: char **env; ! 27: int nenv = 0; ! 28: char nolog[] = "/etc/nologin"; ! 29: struct passwd *pwd; ! 30: struct passwd *pwdecode(); ! 31: char *cmd; ! 32: ! 33: struct passwd *getpwnam(); ! 34: char *strcat(); ! 35: int setpwent(); ! 36: char *ttyname(); ! 37: char *crypt(); ! 38: char *getpass(); ! 39: char *rindex(), *index(); ! 40: extern char **environ; ! 41: ! 42: main(argc, argv) ! 43: char **argv; ! 44: { ! 45: register char *namep; ! 46: char input[ISIZE]; ! 47: char pwline[128]; ! 48: int t, f, c; ! 49: char *ttyn; ! 50: int neednopass = 0; ! 51: int hangitup = 0; ! 52: int ntries = 0; ! 53: FILE *nlfd; ! 54: int i; ! 55: ! 56: alarm(60); ! 57: signal(SIGQUIT, SIG_IGN); ! 58: signal(SIGINT, SIG_IGN); ! 59: signal(SIGHUP, SIG_IGN); ! 60: nice(-100); ! 61: nice(20); ! 62: nice(0); ! 63: gtty(0, &ttyb); ! 64: #define ONOFILE 20 ! 65: for (t=NSYSFILE; t<ONOFILE; t++) ! 66: close(t); ! 67: ttyn = ttyname(0); ! 68: if (ttyn==0) ! 69: ttyn = "/dev/tty??"; ! 70: SCPYN(input, ""); ! 71: switch(argc) { ! 72: ! 73: case 0: ! 74: case 1: ! 75: break; ! 76: ! 77: case 2: ! 78: SCPYN(input, argv[1]); ! 79: break; ! 80: ! 81: default: ! 82: if (strcmp(argv[1], "-f")==0 || strcmp(argv[1], "-p")==0) { ! 83: if (getuid()!=0) { ! 84: printf("login: not super-user\n"); ! 85: exit(1); ! 86: } ! 87: neednopass++; ! 88: if (strcmp(argv[1], "-f")==0) ! 89: SCPYN(input, argv[2]); ! 90: else { ! 91: SCPYN(pwline, argv[2]); ! 92: pwd = pwdecode(pwline); ! 93: SCPYN(input, pwd->pw_name); ! 94: } ! 95: if (argc>3) ! 96: cmd = argv[3]; ! 97: } else ! 98: exit(1); ! 99: } ! 100: loop: ! 101: if (ntries) { ! 102: if (ntries > 5 || hangitup) { ! 103: ttyb.sg_ispeed = ttyb.sg_ospeed = 0; ! 104: stty(0, &ttyb); ! 105: sleep(5); ! 106: exit(1); ! 107: } ! 108: neednopass = 0; ! 109: pwd = NULL; ! 110: SCPYN(input, ""); ! 111: } ! 112: ntries++; ! 113: while (input[0] == '\0') { ! 114: namep = input; ! 115: printf("login: "); ! 116: while ((c = getchar()) != '\n') { ! 117: if(c == ' ') ! 118: c = '_'; ! 119: if (c == EOF) ! 120: exit(0); ! 121: if (namep < input + ISIZE - 1) ! 122: *namep++ = c; ! 123: } ! 124: *namep = NULL; ! 125: } ! 126: SCPYN(utmp.ut_name, input); ! 127: utmp.ut_time = 0; ! 128: if (pwd == NULL) { ! 129: setpwent(); ! 130: if ((pwd = getpwnam(input)) == NULL) ! 131: pwd = &nouser; ! 132: endpwent(); ! 133: } ! 134: if (namep = index(utmp.ut_name, '\001')) ! 135: if (namep[1]=='L' && namep[2]=='\002') /* loopback? */ ! 136: hangitup++; ! 137: time(&utmp.ut_time); ! 138: SCPYN(utmp.ut_line, index(ttyn+1, '/')+1); ! 139: if (pwd->pw_uid == 0) /* root loses */ ! 140: neednopass = 0; ! 141: if (*pwd->pw_passwd != '\0' && !neednopass) { ! 142: namep = crypt(getpass("Password:"), pwd->pw_passwd); ! 143: if (strcmp(namep, pwd->pw_passwd)) { ! 144: /* magic string detects loopbacks */ ! 145: printf("\001L\002ogin incorrect\n"); ! 146: f = open("/usr/adm/xtmp", 1); ! 147: if (f > 0) { ! 148: lseek(f, 0L, 2); ! 149: write(f, (char *)&utmp, sizeof(utmp)); ! 150: close(f); ! 151: } ! 152: goto loop; ! 153: } ! 154: } ! 155: if(pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r")) != NULL){ ! 156: while((c = getc(nlfd)) != EOF) ! 157: putchar(c); ! 158: exit(0); ! 159: } ! 160: if(chdir(pwd->pw_dir) < 0) { ! 161: printf("No directory\n"); ! 162: if(pwd->pw_uid != 0 || (access(nolog, 0) < 0)) ! 163: goto loop; ! 164: } ! 165: if (cmd) { /* remote exec */ ! 166: t = strlen(utmp.ut_name); ! 167: if (t < sizeof(utmp.ut_name)) ! 168: utmp.ut_name[t] = '*'; ! 169: } ! 170: t = ttyslot(); ! 171: if (t>0 && (f = open("/etc/utmp", 1)) >= 0) { ! 172: lseek(f, (long)(t*sizeof(utmp)), 0); ! 173: write(f, (char *)&utmp, sizeof(utmp)); ! 174: close(f); ! 175: } ! 176: if (t>0 && (f = open("/usr/adm/wtmp", 1)) >= 0) { ! 177: lseek(f, 0L, 2); ! 178: write(f, (char *)&utmp, sizeof(utmp)); ! 179: close(f); ! 180: } ! 181: chown(ttyn, pwd->pw_uid, pwd->pw_gid); ! 182: chmod(ttyn, 0622); ! 183: setgid(pwd->pw_gid); ! 184: setuid(pwd->pw_uid); ! 185: if (*pwd->pw_shell == '\0') ! 186: pwd->pw_shell = "/bin/sh"; ! 187: strncat(homedir, pwd->pw_dir, sizeof(homedir)-6); ! 188: nenv = 0; ! 189: for(i = 0; environ[i]; i++) ! 190: ; ! 191: env = (char **) malloc(sizeof(char *) * (i + 10)); ! 192: if (env == NULL) { ! 193: printf("No memory for environment.\n"); ! 194: exit(1); ! 195: } ! 196: for (i = 0; environ[i]; i++) { ! 197: if (strncmp(environ[i], "HOME=", 5) == 0) ! 198: continue; ! 199: if (strncmp(environ[i], "PATH=", 5) == 0) ! 200: continue; ! 201: env[nenv++] = environ[i]; ! 202: } ! 203: if(homedir[0]) ! 204: env[nenv++] = homedir; ! 205: if(path[0]) ! 206: env[nenv++] = path; ! 207: env[nenv] = NULL; ! 208: if ((namep = rindex(pwd->pw_shell, '/')) == NULL) ! 209: namep = pwd->pw_shell; ! 210: else ! 211: namep++; ! 212: strcat(minusnam, namep); ! 213: alarm(0); ! 214: umask(02); ! 215: if (cmd==NULL) { ! 216: showmotd(); ! 217: strcat(maildir, pwd->pw_name); ! 218: if(access(maildir,4)==0) { ! 219: struct stat statb; ! 220: stat(maildir, &statb); ! 221: if (statb.st_size > POSTMKSIZ) ! 222: printf("You have mail.\n"); ! 223: } ! 224: } ! 225: signal(SIGQUIT, SIG_DFL); ! 226: signal(SIGINT, SIG_DFL); ! 227: signal(SIGHUP, SIG_DFL); ! 228: environ = env; ! 229: if (cmd==NULL) ! 230: execlp(pwd->pw_shell, minusnam, 0); ! 231: else { ! 232: env[nenv++] = "REXEC=1"; ! 233: ioctl(0, TIOCEXCL, NULL); ! 234: env[nenv] = 0; ! 235: execlp(pwd->pw_shell, minusnam, "-c", cmd, (char *)0); ! 236: } ! 237: printf("No shell\n"); ! 238: exit(0); ! 239: } ! 240: ! 241: int stopmotd; ! 242: catch() ! 243: { ! 244: signal(SIGINT, SIG_IGN); ! 245: stopmotd++; ! 246: } ! 247: ! 248: showmotd() ! 249: { ! 250: FILE *mf; ! 251: register c; ! 252: ! 253: signal(SIGINT, catch); ! 254: if((mf = fopen("/etc/motd","r")) != NULL) { ! 255: while((c = getc(mf)) != EOF && stopmotd == 0) ! 256: putchar(c); ! 257: fclose(mf); ! 258: } ! 259: signal(SIGINT, SIG_IGN); ! 260: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.