📄 deslogind.c
字号:
*dstp = newEntry; return ep; } else { /* delete the entry */ *dstp = ep[envsize-1]; free(ep[envsize-1]); /* could cause problems */ ep[envsize-1] = (char *) 0; return ep; } } if (newEntry != (char *) 0) { envsize++; } res = (char **) allocate((envsize + 1) * sizeof (char *)); 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, rhostName) char *userName, *cwd, *shell, *path, *tz, *rhostName;{ register char **envp = updateEnv((char **) 0, (char *) 0, (char *) 0);#if defined(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 */#if defined(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 */#if defined(DEFAULT_MAIL) /* hpux */ strcpy(envLine, DEFAULT_MAIL); strcat(envLine, userName); envp = updateEnv(envp, "MAIL", envLine);#endif /* * Add this environment variable to help users adjust their own login * scripts to a given remote enviroment and to detect remote logins * via this program. */ envp = updateEnv(envp, "RHOSTNAME", rhostName); /* deslogin feature */ /* * 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 *) posignal(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 *) posignal(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 *) posignal(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, 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, count, protover, rhostName, rport); return 0; } return &protover[0];}/* * Set the supplementary group id's for the specified user with error checking * * Returns: 0 success, -1 if failure (warning issued) */int setupGroups(userName) char *userName;{ int res = -1, ngroups, groups; /* number of supplementary group ids */ gid_t *gidset; /* * Supplementary group ids are inherited from the parent. They * should be changed if they exist. Supplementary group id's are * checked against the target gid of chmod(), chown(). */ ngroups = (int) sysconf(_SC_NGROUPS_MAX); if (ngroups >= 0) { gidset = (gid_t *) malloc((ngroups+1) * sizeof (gid_t)); if (gidset == (gid_t *) 0) { log( "%s: WARNING--couldn't allocate %d entry supplementary group list\n", progName, ngroups); } else { groups = getLoginGroups(ngroups, gidset, userName); if (groups < 0) { log("%s: WARNING--getLoginGroups(%d, %s) failed--%s\n", progName, ngroups, userName, ERRMSG); } else { if (groups > ngroups) { log( "%s: WARNING--only first %d of %d supplementary groups set\n", progName, ngroups, res, userName); groups = ngroups; } res = setGroups(groups, gidset); if (res < 0) { log("%s: WARNING--setgroups(%d) failed--%s\n", progName, groups, ERRMSG); } } free(gidset); } } return res;}/* * Set the user's uid, gid, and supplementary gid's which determine * the capabilities for this process. */void setupUser(uid, gid, userName) uid_t uid; gid_t gid; char *userName;{ int res; res = setgid(gid); /* must setgid before setuid */ if (res != 0) { log("%s: setgid to %d failed--%s\n", progName, gid, ERRMSG); exit(1); } /* * Supplementary group ids are inherited from the parent. They * should be changed if they exist. Supplementary group id's are * checked against the target gid of chmod(), chown(). */ res = setupGroups(userName); /* * If res < 0, setupgroups failed, but that's OK, warning issued. */ /* * We may lose the ability to update the log file with log() after this */ res = setuid(uid); if (debug > 1) { log("%s: setuid: returned %ld\n", progName, (long) res); } if (res != 0) { log("%s: setuid to %d failed--%s\n", progName, uid, ERRMSG); exit(1); }}int main(argc, argv) int argc; char *argv[];{ int ch, count, sin, sout, serr, res, ttyfd, 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], passPhrase[PHRASE_SIZE]; char *userPhrase = (char *) 0, *generic = (char *) 0; char mname[PTY_NAMESIZE]; 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, stype; int pipe0[2], pipe1[2], pipe2[2]; mode_t newmask = DEFAULT_UMASK, oldmask; pid_t pid, pid_res; uid_t uid; gid_t gid; 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -