📄 login.c
字号:
if (i<1) ultrix_v.v_major = 0;#ifndef ULTRIX_RELEASE_DATE#define ULTRIX_RELEASE_DATE 0x7fffffff#endif if (lmf_probe_license("ULTRIX", 0, &ultrix_v, ULTRIX_RELEASE_DATE, 0) != 0 && pwd->pw_uid != 0) /* Always let root in */ switch(errno) { case EDQUOT: sendreq(ERROR, "Too many users logged on already.\nTry again later.\n"); sendreq(ERRORNXIT, (char *) 0); cleanup(10, 1, "Too many users"); break; case ERANGE: sendreq(ERROR, "License not valid for this version of ULTRIX.\n"); sendreq(ERRORNXIT, (char *) 0); cleanup(10, 1, "License version not valid"); break; default: sendreq(ERROR, "No valid license found for ULTRIX.\n"); sendreq(ERRORNXIT, (char *) 0); cleanup(10, 1, "No valid license"); break; } alarm(0); /* Mark this as a login process in the kernel. */ setsysinfo(SSI_LOGIN, 0, 0, 0, 0); time(&utmp.ut_time); if(!notty) { t = ttyslot(); } else { struct ttyent *tent; setttyent(); for(t = 1; (tent = getttyent()) != NULL; t++ ) { if (strcmp(tent->ty_name, tty) == 0) { endttyent(); break; } } } if (t > 0 && (f = open("/etc/utmp", O_WRONLY)) >= 0) { lseek(f, (long)(t*sizeof(utmp)), 0); SCPYN(utmp.ut_line, tty); write(f, (char *)&utmp, sizeof(utmp)); close(f); } if ((f = open("/usr/adm/wtmp", O_WRONLY|O_APPEND)) >= 0) { write(f, (char *)&utmp, sizeof(utmp)); close(f); } lastmessage[0] = '\0'; if ((f = open(lastlog, O_RDWR)) >= 0) { struct lastlog ll; char *cp=lastmessage; if(!notty) { lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0); if (read(f, (char *) &ll, sizeof ll) == sizeof ll && ll.ll_time != 0) { sprintf(cp, "Last login: %.*s ", 24-5, (char *)ctime(&ll.ll_time)); cp += strlen(cp); if (*ll.ll_host != '\0') sprintf(cp, "from %.*s", sizeof (ll.ll_host), ll.ll_host); else sprintf(cp, "on %.*s", sizeof (ll.ll_line), ll.ll_line); } } lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0); time(&ll.ll_time); SCPYN(ll.ll_line, tty); SCPYN(ll.ll_host, utmp.ut_host); write(f, (char *) &ll, sizeof ll); close(f); } if(!notty) { struct group *gp; gp = getgrnam("tty"); chown(ttyn, pwd->pw_uid, gp?gp->gr_gid:pwd->pw_gid); chmod(ttyn, 0620); } if(setgid(pwd->pw_gid) < 0) { char line[40]; sprintf(line, "Unable to set gid to %d\n", pwd->pw_gid); sendreq(ERROR, line); sendreq(ERRORNXIT, (char *)0); cleanup(5, 1, "Unable to set gid"); } strncpy(name, utmp.ut_name, NMAX); name[NMAX] = '\0'; initgroups(name, pwd->pw_gid); if(!notty) quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0);#ifndef NOAUDIT/* * Set audit infomation for user. */ if(auth) { if(audcntl(SET_PROC_ACNTL, (char *) 0, 0, auth->a_audit_control, 0) < 0) { sendreq(ERROR, "audit control error.\n"); sendreq(ERRORNXIT, (char *)0); cleanup(5, 1, "Error in audit control"); } if(audcntl(SET_PROC_AMASK, auth->a_audit_mask, SYSCALL_MASK_LEN+TRUSTED_MASK_LEN, 0, 0) < 0) { sendreq(ERROR, "audit mask error.\n"); sendreq(ERRORNXIT, (char *)0); cleanup(5, 1, "Error in audit mask"); } if(audcntl(SETPAID, (char *) 0, 0, 0, auth->a_audit_id) < 0) { sendreq(ERROR, "Error setting audit ID.\n"); sendreq(ERRORNXIT, (char *)0); cleanup(5, 1, "Error in audit ID"); } } else { audcntl(SET_PROC_ACNTL, (char *)0, 0, AUDIT_OR, 0); A_PROCMASK_SET(buf, SYS_setgroups, 0, 0); A_PROCMASK_SET(buf, LOGIN, 0, 0); audcntl(SET_PROC_AMASK, buf, LEN, 0, 0); }#endif NOAUDIT/* Generate audit record for successful login.*/ audit_event(0, "Login succeeded");#ifndef NOPRIV/* * Set up privileges */ if(setpriv(P_SET_PROC|P_SET_INHL, auth->a_privs) < 0) { sendreq(ERROR, "privilege mask error.\n"); sendreq(ERRORNXIT, (char *)0); cleanup(5, 1, "Error in privilege mask"); }#endif if(sec_level >= SEC_UPGRADE) endauthent(); endpwent(); if(setuid(pwd->pw_uid) < 0) { char line[40]; sprintf(line, "Unable to setuid to %d\n", pwd->pw_uid); sendreq(ERROR, line); sendreq(ERRORNXIT, (char *)0); cleanup(5, 1, "Error setting UID"); }/* * Change to home directory. Don't hang if it's an unavailable NFS partition. */ signal(SIGALRM, SIG_DFL); signal(SIGTSTP, SIG_IGN); signal(SIGQUIT, no_dir); signal(SIGINT, no_dir); siginterrupt(SIGQUIT, 1); siginterrupt(SIGINT, 1); if (chdir(pwd->pw_dir) < 0) { if(strcmp(pwd->pw_name, "root") && !shell_supported(pwd->pw_shell)) { sendreq(ERROR, "No directory!\n"); sendreq(ERRORNXIT, (char *)0); cleanup(5, 1, "No directory"); } sendreq(ERROR, "No directory! Logging in with home=/\n"); pwd->pw_dir = "/"; if(chdir(pwd->pw_dir) < 0) sendreq(ERROR, "No directory!\n"); } /* Finally, we can see if this is to be a quiet login */ if(!notty ) quietlog = (access(qlog, F_OK) == 0); /* destroy environment unless user has asked to preserve it */ if (pflag == 0) environ = envinit; /* set up environment, this time without destruction */ /* copy the environment before setenving */ { int i = 0; char **envnew; while (environ [i] != NULL) i++; envnew = (char **) malloc (sizeof (char *) * (i + 1)); for (; i >= 0; i--) envnew [i] = environ [i]; environ = envnew; } setenv("HOME=",pwd->pw_dir); setenv("SHELL=",pwd->pw_shell); if (term[0] == '\0') strncpy (term,stypeof(tty), sizeof(term)); setenv("TERM=",term); setenv("USER=",pwd->pw_name); setenv("PATH=",":/usr/ucb:/bin:/usr/bin"); if ((namep = rindex(pwd->pw_shell, '/')) == NULL) namep = pwd->pw_shell; else namep++; strcat(minusnam, namep); umask(022); if (!notty && tty[sizeof("tty")-1] == 'd') syslog(LOG_NOTICE, "DIALUP %s %s", tty, pwd->pw_name); if (!notty && !quietlog) { /* */ struct stat statb; int status; puts(lastmessage); showmotd(); strcat(maildir, pwd->pw_name); if((status=stat(maildir, &statb)) >= 0) { if((statb.st_mode & S_IFMT) == S_IFDIR) { strcat(maildir, "/"); strcat(maildir, pwd->pw_name); status = stat(maildir, &statb); } if (status >= 0 && access(maildir, R_OK) == 0) if (statb.st_size) puts("You have mail."); } } signal(SIGALRM, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGINT, SIG_DFL); signal(SIGTSTP, SIG_IGN); closelog(); if(notty) { fcntl(0, F_SETFD, 1); fcntl(1, F_SETFD, 1); } if(cmd != NULL) { char buf[4096]; sprintf(buf, "exec %s %s", cmd, tty); execlp(pwd->pw_shell, minusnam, "-c", buf, 0); } else { execlp(pwd->pw_shell, minusnam, 0); } /* * Emergency clause in case the password file gets totaled or other * such extremes. Look for username of root to prevent other users * (such as operator users) who would have a uid of 0 from getting * /bin/sh. */ if ((pwd->pw_uid == 0) && ((strncmp(pwd->pw_name,"root",strlen(pwd->pw_name))) == 0)) { static char binshell[] = "/bin/sh"; sendreq(ERROR, "Bad shell, root will use /bin/sh\n"); if(cmd != NULL) { char buf[4096]; sprintf(buf, "exec %s %s", cmd, tty); execl(binshell, "-sh", "-c", buf, 0); } else { execl(binshell, "-sh", 0); } } if(!notty) perror(pwd->pw_shell); sendreq(ERROR, "No shell\n"); sendreq(ERRORNXIT, (char *)0); cleanup(0, 1, (char *) 0);}#define SHELLS "/etc/shells"/* * Function to match a shell name against a pathname. */static int path_match(path, shell)char *path, *shell;{ char *cp; cp = strchr(path, '\n'); if(cp) *cp = '\0'; if(*shell != '/') { cp = strrchr(path, '/'); if(!cp) cp = path; else cp++; } else cp = path; if(!strcmp(shell, cp)) { return 1; } return 0;}static int shell_supported(shell)char *shell;{ FILE *fp; int i; if(!(fp=fopen(SHELLS, "r"))) { static char *shells[] = { "/bin/sh", "/bin/csh", "/usr/bin/sh5", "/usr/bin/ksh", (char *)0 }; for(i=0; shells[i]; i++) if(path_match(shells[i], shell)) return 1; } else { char line[BUFSIZ]; while(fgets(line, sizeof line, fp)) if(path_match(line, shell)) { close(fp); return 1; } close(fp); } return 0;}getloginname(up) register struct utmp *up;{ register char *namep; char c; static CRYPT_PASSWORD password; while (up->ut_name[0] == '\0') { namep = up->ut_name; fputs("login: ", stdout); while ((c = getchar()) != '\n') { if (c == ' ') c = '_'; if (c == EOF) cleanup(0, 0, (char *) 0); if (namep < up->ut_name+NMAX) *namep++ = c; } } strncpy(lusername, up->ut_name, NMAX); lusername[NMAX] = 0; if ((pwd = getpwnam(lusername)) == NULL) pwd = &nouser; else { bcopy(pwd, &pwd_save, sizeof pwd_save); pwd = &pwd_save; if(sec_level >= SEC_UPGRADE) { auth = getauthuid(pwd->pw_uid); if(sec_level > SEC_UPGRADE && !auth) pwd = &nouser; }/* else { if(!strcmp(pwd->pw_passwd, "*")) { strncpy(password, auth->a_password, sizeof password); pwd->pw_passwd = password; } }*/ }}voidtimedout(sig, code, scp)int sig, code;struct sigcontext *scp;{ printf("Login timed out after %d seconds\n", timeout); cleanup(0, 0, (char *) 0);}rootterm(tty) char *tty;{ register struct ttyent *t; if ((t = getttynam(tty)) != NULL) { if (t->ty_status & TTY_SECURE) return (1); } return (0);}showmotd(){ FILE *mf; register c; intcount = 0; if ((mf = fopen("/etc/motd", "r")) != NULL) { while ((c = getc(mf)) != EOF && intcount == 0) putchar(c); fclose(mf); }}#undef UNKNOWN#define UNKNOWN "su"char *stypeof(ttyid) char *ttyid;{ register struct ttyent *t; if (ttyid == NULL || (t = getttynam(ttyid)) == NULL) return (UNKNOWN); return (t->ty_type);}dodecnetlogin(){ char *getenv(); char *cp; int proxy = 1; static CRYPT_PASSWORD password; /* * check environment variables are present, and defined for DECnet * if "NETWORK" != "DECnet", force login * if "ACCESS" == "DEFAULT", force login * if "USER" is not defined, or is too long, force * login */ if (((cp = getenv("NETWORK")) == 0) || (strcmp(cp, "DECnet") != 0)) proxy = 0; /* Else we break telnet */ /* * if terminal type is defined, use it for local terminal */ if (cp = getenv("TERM")) { if (strcmp(cp, "none")) strncat(term, cp, sizeof(term)-6); } /* * don't login if using default access */ if (((cp = getenv("ACCESS")) == 0) || (strcmp(cp, "DEFAULT") == 0)) proxy = 0; /* * if local name is too long, can't log user in */ if (((cp = getenv("USER")) == 0) || (strlen(cp) > NMAX)) { if (getenv("USERNAME") == NULL) return(0); else proxy = 0; } else strcpy(lusername, cp); /* * save the connecting host name */ if (cp = getenv("REMNODE")) SCPYN(utmp.ut_host, cp); /* * Get username from environment if this is not a proxy line. */ if (*lusername == '\000') { if (cp = getenv("USERNAME")) strcpy(lusername,cp); proxy = -1; } pwd = getpwnam(lusername); if (pwd == NULL) { pwd = &nouser; proxy = -1; } else { bcopy(pwd, &pwd_save, sizeof pwd_save); pwd = &pwd_save; if(sec_level >= SEC_UPGRADE) if((auth=getauthuid(pwd->pw_uid)) == NULL) { pwd = &nouser; proxy = -1; }/* else { strncpy(password, auth->a_password, sizeof password); pwd->pw_passwd = password; }*/ } return(proxy);}doremotelogin(host) char *host;{ static CRYPT_PASSWORD password; getstr(rusername, sizeof (rusername), "remuser"); getstr(lusername, sizeof (lusername), "locuser"); getstr(term, sizeof(term), "Terminal type"); if (getuid()) { pwd = &nouser; return(-1); } pwd = getpwnam(lusername); if (pwd == NULL) { pwd = &nouser; return(-1); } else { bcopy(pwd, &pwd_save, sizeof pwd_save); pwd = &pwd_save; if(sec_level >= SEC_UPGRADE) if((auth=getauthuid(pwd->pw_uid)) == NULL) { pwd = &nouser; return -1; }/* else { strncpy(password, auth->a_password, sizeof password); pwd->pw_passwd = password; }*/ } /* ruserok returns -1 on error. Force it to return a 1 on success */ return(ruserok(host, (pwd->pw_uid == 0), rusername, lusername) < 0 ? -1 : 1);}getstr(buf, cnt, err) char *buf; int cnt; char *err;{ char c; do { if (read(0, &c, 1) != 1) cleanup(0, 1, "EOF reading input"); if (--cnt < 0) { printf("%s too long\r\n", err); cleanup(0, 1, "Input line too long"); } *buf++ = c; } while (c != 0);}char *speeds[] = { "0", "50", "75", "110", "134", "150", "200", "300", "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };#define NSPEEDS (sizeof (speeds) / sizeof (speeds[0]))doremoteterm(term, tp) char *term; struct sgttyb *tp;{ char *cp = index(term, '/'); register int i; if (cp) { *cp++ = 0; for (i = 0; i < NSPEEDS; i++) if (!strcmp(speeds[i], cp)) { tp->sg_ispeed = tp->sg_ospeed = i; break; } } tp->sg_flags = ECHO|CRMOD|ANYP|XTABS;}setenv (var, value)/* sets the value of var to be arg in the Unix 4.2 BSD environment env. Var should end with '='. (bindings are of the form "var=value") This procedure assumes the memory for the first level of environ was allocated using malloc. */char *var, *value;{ extern char **environ; int index = 0; while (environ [index] != NULL) { if (strncmp (environ [index], var, strlen (var)) == 0) { /* found it */ environ [index] = (char *) malloc (strlen (var) + strlen (value) + 1); strcpy (environ [index], var); strcat (environ [index], value); return; } index ++; } if ((environ = (char **) realloc (environ, sizeof (char *) * (index + 2))) == NULL) { fputs("Setenv: malloc out of memory\n", stderr); cleanup(0, 1, "Unable to allocate memory for environment variables"); } environ [index] = (char *) malloc (strlen (var) + strlen (value) + 1); strcpy (environ [index], var); strcat (environ [index], value); environ [++index] = NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -