📄 deslogind.c
字号:
if (res == (char **) 0) { if (newEntry != (char *) 0) { free(newEntry); } return (char **) 0; } dstp = res; if (ep != (char **) 0) { chpp = ep; while (*chpp != (char *) 0) { *dstp++ = *chpp++; } } *dstp = (char *) 0; if (newEntry != (char *) 0) { *dstp++ = newEntry; } *dstp++ = (char *) 0; if (ep != (char **) 0) { free(ep); } return res;}char **setupEnv(userName, shell, cwd, path, tz) char *userName, *cwd, *shell, *path, *tz;{ register char **envp = updateEnv((char **) 0, (char *) 0, (char *) 0);#ifdef DEFAULT_MAIL char envLine[1024];#endif envp = updateEnv(envp, "HOME", cwd); /* sun POSIX xdm */ envp = updateEnv(envp, "PATH", path); /* sun POSIX xdm */ envp = updateEnv(envp, "LOGNAME", userName); /* sun POSIX */#ifdef USER_ENV /* BSD xdm */ envp = updateEnv(envp, USER_ENV, userName); #endif envp = updateEnv(envp, "SHELL", shell); /* sun xdm */ if (tz != (char *) 0) { envp = updateEnv(envp, "TZ", tz); /* POSIX */ } envp = updateEnv(envp, "TERM", DEFAULT_TERM); /* sun POSIX */#ifdef DEFAULT_MAIL /* hpux */ strcpy(envLine, DEFAULT_MAIL); strcat(envLine, userName); envp = updateEnv(envp, "MAIL", envLine);#endif /* * rlogin propigates TERM, baud rate, changes to window sizes */ return envp;}/* * Get information about the named user. Returns -1 for failure, 0 for success */int getUserInfo(userName, shell, cwd, uid, gid) char *userName; char **shell; char **cwd; uid_t *gid; uid_t *uid;{ register struct passwd *pwentp; register int res = -1; pwentp = getpwnam(userName); if (pwentp != (struct passwd *) 0) { *uid = pwentp->pw_uid; *gid = pwentp->pw_gid; *cwd = newString(pwentp->pw_dir); *shell = newString(pwentp->pw_shell); res = 0; } return res;}/* * Return CPU time consumed by this process and it's children in 1/10 seconds. * * Processes run by the shell "time" command will not be accumulted. */long cpuTime(){ struct tms pt; clock_t curTime; long res; curTime = times(&pt); res = pt.tms_utime + pt.tms_cutime + pt.tms_stime + pt.tms_cstime; res = (res * 10) / sysconf(_SC_CLK_TCK); return res;}/* * Get and validate the userfile cipher key. Returns the binary key or -1. * * If noUserKey is 1, then userKey is 0, and the userFile is not encrypted. * Otherwise, it's expected to have been encrypted with the cipher program. */keyType getUserFileKey(userFile, userPhrase, noUserKey) char *userFile; char *userPhrase; int noUserKey;{ int res; char passPhrase[PHRASE_SIZE]; keyType userKey = 0; if (noUserKey && userPhrase) { log("%s: can't use -n option if UserFile cipher key given\n", progName); return (keyType) -1; } if (!noUserKey) { if (userPhrase == (char *) 0) { /* user for passphrase if none given */ res = askTty("UserFile cipher key: ", passPhrase, PHRASE_SIZE-1, 0); if (res < 0) { log("%s: couldn't get key\n", progName); return (keyType) -1; } userPhrase = passPhrase; } if (userPhrase == (char *) -1) { userKey = (keyType) &defaultKey[0]; /* use compile-time key */ } else { userKey = mkKey(userPhrase); memset(userPhrase, '\0', strlen(userPhrase)); /* possibly optarg */ if (userKey == (keyType) 0) { log("%s: couldn't make key\n", progName); return (keyType) -1; } } } /* * Make userfile exists and the correct key was specified */ res = getUserPhrase(userFile, passPhrase, PHRASE_SIZE, "#", userKey); if (res == -1) { log("%s: cannot open \"%s\" for user database\n", progName, userFile); return (keyType) -1; } if (res == -2) { log("%s: incorrect decryption key for user database \"%s\"\n", progName, userFile); return (keyType) -1; } return userKey;}int handleSignals() { register char *chp; /* * To make sure we cleanup utmp with atexit if we're aborted */ chp = (char *) psignal(SIGINT, sigHandler); if (chp == (char *) SIG_ERR) { log("%s: sigaction SIGINT failed--%s\n", progName, ERRMSG); return -1; } /* * Sent by kill command with no arguments */ chp = (char *) psignal(SIGTERM, sigHandler); if (chp == (char *) SIG_ERR) { log("%s: sigaction SIGTERM failed--%s\n", progName, ERRMSG); return -1; } /* * Controlling terminal hangup, or death of controlling process */ chp = (char *) psignal(SIGHUP, sigHandler); if (chp == (char *) SIG_ERR) { log("%s: sigaction SIGHUP failed--%s\n", progName, ERRMSG); return -1; } return 0;}/* * Became a deamon */pid_t becomeDaemon() { pid_t pid = getpid(); if (debug < 2) { /* deamon: disassociate from controlling terminal */ pid = fork(); /* make pgid != pid for setsid() */ if (pid < 0) { log("%s: unable to fork as daemon--%s\n", progName, ERRMSG); return -1; } if (pid > 0) { /* the parent is finished */ exit(1); } /* child */ setProgName(); pid = setsid(); /* break control terminal affiliation */ if (pid == -1) { log("%s: setsid failed--%s\n", progName, ERRMSG); return -1; } /* * We may still have a problem here. When the child dies, we will * create a zombie which will have to be waited for by the parent! * Since we're a session leader, presumably that parent is now init. */ } return pid;}/* * Negotiate protocol with remote site. * Return the selected protocol or 0 for failure. */char *serverHandshake(nfd, rhostName, rport, timeout) int nfd; char *rhostName; int rport; unsigned timeout;{ int len, res, count; static char protover[VERS_SIZE]; len = strlen(PROTOCOL_VERS); res = write(nfd, PROTOCOL_VERS, len+1); if (debug) { log("%s: server protocol \"%-.*s\"\n", progName, len, PROTOCOL_VERS); } if (res < 0) { log("%s: write (%d, \"%-.*s\", %d) failed--%s\n", progName, nfd, len, PROTOCOL_VERS, len+1, ERRMSG); return 0; } count = getString(nfd, protover, VERS_SIZE-1, SETUP_TIMEOUT); if (count == 0) { log("%s: NOPROTO %s:%d\n", progName, rhostName, rport); return 0; } if (debug) { log("%s: client protocol \"%-.*s\"\n", progName, VERS_SIZE-1, protover); } if (protover[0] != PROTOCOL_VERS[0]) { log("%s: BADPROTO(%-.*s) %s:%d\n", progName, VERS_SIZE-1, protover, rhostName, rport); return 0; } return &protover[0];}int main(argc, argv) int argc; char *argv[];{ int ch, count, sin, sout, serr, res, ttyfd, chldStat, noUserKey = 0; long cpuUsed; char *chp, *shell, *cwd, *arg0, *tz, *protocol; char *path = USERPATH, *userFile = USER_FILE, *logName = LOG_FILE, buf[2]; char **cargv = defaultArgv, **cenv = (char **) 0; char ruser[USERNAME_SIZE], userName[USERNAME_SIZE], passPhrase[PHRASE_SIZE]; char *userPhrase = (char *) 0; char mname[PTY_NAMESIZE], rhostName[MAX_HOSTNAME]; unsigned port = 0, rport = 0; unsigned connTimeout = 1000 * INACTIVITY_TIMEOUT; unsigned loginTimeout = 1000 * LOGIN_TIMEOUT; /* login timer */ unsigned bufSize = 128; /* connection bufsize */ int masterpty = -1, slavepty = -1, nfd = -1, pty = 1; int pipe0[2], pipe1[2], pipe2[2]; int ngroups, groups, stype; /* number of supplementary group ids */ mode_t newmask = DEFAULT_UMASK, oldmask; pid_t pid, pid_res; uid_t uid; gid_t gid, *gidset; time_t loginTime; keyType key = (keyType) 0, userKey; argcName = *argv; if ((chp = strrchr(argcName, '/')) != (char *) 0) argcName = chp + 1; progName = argcName; stype = issocket(0); if (stype > 0) { /* if we're invoked from inetd */ res = openLog(logName); if (res < 0) { _exit(1); } } while ((ch = getopt(argc, argv, "k:Pl:t:i:f:p:dvnc")) != EOF) switch (ch) { case 'c': /* user compile'd userFile key */ userPhrase = (char *) -1; break; case 'k': /* user file cipher key */ userPhrase = optarg; break; case 'n': /* no user file cipher key */ noUserKey++; break; case 'P': pty = 0; /* pipeline instead of pty */ break; case 'l': logName = optarg; break; case 'i': count = sscanf(optarg, "%u", &connTimeout); /* in seconds */ if (count != 1) goto usage; connTimeout *= 1000; break; case 't': count = sscanf(optarg, "%u", &loginTimeout); /* in seconds */ if (count != 1) goto usage; loginTimeout *= 1000; break; case 'f': userFile = optarg; break; case 'p': count = sscanf(optarg, "%u", &port); if (count != 1) goto usage; break; case 'v': verbose++; break; case 'd': debug++; break; default:usage: log("usage: %s [-dn] [-i inactiveSecs ] [-t loginSecs ] [-l logfile ] [-f userfile ] [-k userfileCipherKey ] [-p port ]\n", progName); return 1; } argc -= optind; argv += optind; if (debug > 1) { log("%s: issocket(0) returned %d\n", progName, stype); } userKey = getUserFileKey(userFile, userPhrase, noUserKey); if (userKey == (keyType) -1) { return 1; } /* * Open log *after* options parsed and some simple error checking, * and *before* closing fd's 0,1, and 2. */ res = openLog(logName); /* leaves existing log if failed */ if (res < 0) { log("%s: couldn't open logfile \"%s\"--%s\n", progName, logName, ERRMSG); return 1; } setProgName(); res = handleSignals(); /* handle quit attempts */ if (res < 0) { return 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -