summaryrefslogtreecommitdiff
path: root/contrib/opie/opiesu.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/opie/opiesu.c')
-rw-r--r--contrib/opie/opiesu.c502
1 files changed, 0 insertions, 502 deletions
diff --git a/contrib/opie/opiesu.c b/contrib/opie/opiesu.c
deleted file mode 100644
index e2bbdb8075376..0000000000000
--- a/contrib/opie/opiesu.c
+++ /dev/null
@@ -1,502 +0,0 @@
-/* opiesu.c: main body of code for the su(1m) program
-
-%%% portions-copyright-cmetz-96
-Portions of this software are Copyright 1996-1998 by Craig Metz, All Rights
-Reserved. The Inner Net License Version 2 applies to these portions of
-the software.
-You should have received a copy of the license with this software. If
-you didn't get a copy, you may request one from <license@inner.net>.
-
-Portions of this software are Copyright 1995 by Randall Atkinson and Dan
-McDonald, All Rights Reserved. All Rights under this copyright are assigned
-to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
-License Agreement applies to this software.
-
- History:
-
- Modified by cmetz for OPIE 2.32. Set up TERM and PATH correctly.
- Modified by cmetz for OPIE 2.31. Fix sulog(). Replaced Getlogin() with
- currentuser. Fixed fencepost error in month printed by sulog().
- Modified by cmetz for OPIE 2.3. Limit the length of TERM on full login.
- Use HAVE_SULOG instead of DOSULOG.
- Modified by cmetz for OPIE 2.2. Don't try to clear non-blocking I/O.
- Use opiereadpass(). Minor speedup. Removed termios manipulation
- -- that's opiereadpass()'s job. Change opiereadpass() calls
- to add echo arg. Removed useless strings (I don't think that
- removing the ucb copyright one is a problem -- please let me
- know if I'm wrong). Use FUNCTION declaration et al. Ifdef
- around some headers. Make everything static. Removed
- closelog() prototype. Use the same catchexit() trickery as
- opielogin.
- Modified at NRL for OPIE 2.2. Changed opiestrip_crlf to
- opiestripcrlf.
- Modified at NRL for OPIE 2.1. Added struct group declaration.
- Added Solaris(+others?) sulog capability. Symbol changes
- for autoconf. Removed des_crypt.h. File renamed to
- opiesu.c. Symbol+misc changes for autoconf. Added bletch
- for setpriority.
- Modified at NRL for OPIE 2.02. Added SU_STAR_CHECK (turning a bug
- into a feature ;). Fixed Solaris shadow password problem
- introduced in OPIE 2.01 (the shadow password structure is
- spwd, not spasswd).
- Modified at NRL for OPIE 2.01. Changed password lookup handling
- to use a static structure to avoid problems with drain-
- bamaged shadow password packages. Always log failures.
- Make sure to close syslog by function to avoid problems
- with drain bamaged syslog implementations. Log a few
- interesting errors.
- Modified at NRL for OPIE 2.0.
- Modified at Bellcore for the S/Key Version 1 software distribution.
- Originally from BSD.
-*/
-
-/*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
-#include "opie_cfg.h"
-
-#include <stdio.h>
-#if HAVE_PWD_H
-#include <pwd.h>
-#endif /* HAVE_PWD_H */
-#include <grp.h>
-#include <syslog.h>
-#include <sys/types.h>
-#if HAVE_SETPRIORITY && HAVE_SYS_RESOURCE_H
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else /* TIME_WITH_SYS_TIME */
-#if HAVE_SYS_TIME_H
-#include <sys/time.h>
-#else /* HAVE_SYS_TIME_H */
-#include <time.h>
-#endif /* HAVE_SYS_TIME_H */
-#endif /* TIME_WITH_SYS_TIME */
-#include <sys/resource.h>
-#else /* HAVE_SETPRIORITY && HAVE_SYS_RESOURCE_H */
-#if TM_IN_SYS_TIME
-#include <sys/time.h>
-#else /* TM_IN_SYS_TIME */
-#include <time.h>
-#endif /* TM_IN_SYS_TIME */
-#endif /* HAVE_SETPRIORITY && HAVE_SYS_RESOURCE_H */
-#if HAVE_STDLIB_H
-#include <stdlib.h>
-#endif /* HAVE_STDLIB_H */
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#if HAVE_STRING_H
-#include <string.h>
-#endif /* HAVE_STRING_H */
-#include <errno.h>
-
-#include "opie.h"
-
-static char userbuf[16] = "USER=";
-static char homebuf[128] = "HOME=";
-static char shellbuf[128] = "SHELL=";
-static char pathbuf[sizeof("PATH") + sizeof(DEFAULT_PATH) - 1] = "PATH=";
-static char termbuf[32] = "TERM=";
-static char *cleanenv[] = {userbuf, homebuf, shellbuf, pathbuf, 0, 0};
-static char *user = "root";
-static char *shell = "/bin/sh";
-static int fulllogin;
-#if 0
-static int fastlogin;
-#else /* 0 */
-static int force = 0;
-#endif /* 0 */
-
-static char currentuser[65];
-
-extern char **environ;
-static struct passwd thisuser, nouser;
-
-#if HAVE_SHADOW_H
-#include <shadow.h>
-#endif /* HAVE_SHADOW_H */
-
-#if HAVE_CRYPT_H
-#include <crypt.h>
-#endif /* HAVE_CRYPT_H */
-
-static VOIDRET catchexit FUNCTION_NOARGS
-{
- int i;
- closelog();
- for (i = sysconf(_SC_OPEN_MAX); i > 2; i--)
- close(i);
-}
-
-/* We allow the malloc()s to potentially leak data out because we can
-only call this routine about four times in the lifetime of this process
-and the kernel will free all heap memory when we exit or exec. */
-static int lookupuser FUNCTION((name), char *name)
-{
- struct passwd *pwd;
-#if HAVE_SHADOW
- struct spwd *spwd;
-#endif /* HAVE_SHADOW */
-
- memcpy(&thisuser, &nouser, sizeof(thisuser));
-
- if (!(pwd = getpwnam(name)))
- return -1;
-
- thisuser.pw_uid = pwd->pw_uid;
- thisuser.pw_gid = pwd->pw_gid;
-
- if (!(thisuser.pw_name = malloc(strlen(pwd->pw_name) + 1)))
- goto lookupuserbad;
- strcpy(thisuser.pw_name, pwd->pw_name);
-
- if (!(thisuser.pw_dir = malloc(strlen(pwd->pw_dir) + 1)))
- goto lookupuserbad;
- strcpy(thisuser.pw_dir, pwd->pw_dir);
-
- if (!(thisuser.pw_shell = malloc(strlen(pwd->pw_shell) + 1)))
- goto lookupuserbad;
- strcpy(thisuser.pw_shell, pwd->pw_shell);
-
-#if HAVE_SHADOW
- if (!(spwd = getspnam(name)))
- goto lookupuserbad;
-
- pwd->pw_passwd = spwd->sp_pwdp;
-
- endspent();
-#endif /* HAVE_SHADOW */
-
- if (!(thisuser.pw_passwd = malloc(strlen(pwd->pw_passwd) + 1)))
- goto lookupuserbad;
- strcpy(thisuser.pw_passwd, pwd->pw_passwd);
-
- endpwent();
-
-#if SU_STAR_CHECK
- return ((thisuser.pw_passwd[0] == '*') || (thisuser.pw_passwd[0] == '#'));
-#else /* SU_STAR_CHECK */
- return 0;
-#endif /* SU_STAR_CHECK */
-
-lookupuserbad:
- memcpy(&thisuser, &nouser, sizeof(thisuser));
- return -1;
-}
-
-static VOIDRET lsetenv FUNCTION((ename, eval, buf), char *ename AND char *eval AND char *buf)
-{
- register char *cp, *dp;
- register char **ep = environ;
-
- /* this assumes an environment variable "ename" already exists */
- while (dp = *ep++) {
- for (cp = ename; *cp == *dp && *cp; cp++, dp++)
- continue;
- if (*cp == 0 && (*dp == '=' || *dp == 0)) {
- strcat(buf, eval);
- *--ep = buf;
- return;
- }
- }
-}
-
-#if HAVE_SULOG
-static int sulog FUNCTION((status, who), int status AND char *who)
-{
- char *from;
- char *ttynam;
- struct tm *tm;
- FILE *f;
- time_t now;
-
- if (who)
- from = who;
- else
- from = currentuser;
-
- if (!strncmp(ttynam = ttyname(2), "/dev/", 5))
- ttynam += 5;
-
- now = time(NULL);
- tm = localtime(&now);
-
- if (!(f = fopen("/var/adm/sulog", "a"))) {
- fprintf(stderr, "Can't update su log!\n");
- exit(1);
- }
-
- fprintf(f, "SU %02d/%02d %02d:%02d %c %s %s-%s\n",
- tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
- status ? '+' : '-', ttynam, from, user);
- fclose(f);
-}
-#endif /* HAVE_SULOG */
-
-int main FUNCTION((argc, argv), int argc AND char *argv[])
-{
- char *p;
- struct opie opie;
- int i;
- char pbuf[256];
- char opieprompt[80];
- int console = 0;
- char *argvbuf;
-
- for (i = sysconf(_SC_OPEN_MAX); i > 2; i--)
- close(i);
-
- openlog("su", LOG_ODELAY, LOG_AUTH);
- atexit(catchexit);
-
- {
- int argvsize = 0;
- for (i = 0; i < argc; argvsize += strlen(argv[i++]));
- argvsize += argc;
- if (!(argvbuf = malloc(argvsize))) {
- syslog(LOG_ERR, "can't allocate memory to store command line");
- exit(1);
- };
- for (i = 0, *argvbuf = 0; i < argc;) {
- strcat(argvbuf, argv[i]);
- if (++i < argc)
- strcat(argvbuf, " ");
- };
- };
-
- strcat(pathbuf, DEFAULT_PATH);
-
-again:
- if (argc > 1 && strcmp(argv[1], "-f") == 0) {
-#if 0
- fastlogin++;
-#else /* 0 */
-#if INSECURE_OVERRIDE
- force = 1;
-#else /* INSECURE_OVERRIDE */
- fprintf(stderr, "Sorry, but the -f option is not supported by this build of OPIE.\n");
-#endif /* INSECURE_OVERRIDE */
-#endif /* 0 */
- argc--, argv++;
- goto again;
- }
- if (argc > 1 && strcmp(argv[1], "-c") == 0) {
- console++;
- argc--, argv++;
- goto again;
- }
- if (argc > 1 && strcmp(argv[1], "-") == 0) {
- fulllogin++;
- argc--;
- argv++;
- goto again;
- }
- if (argc > 1 && argv[1][0] != '-') {
- user = argv[1];
- argc--;
- argv++;
- }
-
- {
- struct passwd *pwd;
- char *p = getlogin();
- char buf[32];
-
- if ((pwd = getpwuid(getuid())) == NULL) {
- syslog(LOG_CRIT, "'%s' failed for unknown uid %d on %s", argvbuf, getuid(), ttyname(2));
-#if HAVE_SULOG
- sulog(0, "unknown");
-#endif /* HAVE_SULOG */
- exit(1);
- }
- strncpy(buf, pwd->pw_name, sizeof(buf)-1);
- buf[sizeof(buf)-1] = 0;
-
- if (!p)
- p = "unknown";
-
- strncpy(currentuser, p, 31);
- currentuser[31] = 0;
-
- if (p && *p && strcmp(currentuser, buf)) {
- strcat(currentuser, "(");
- strcat(currentuser, buf);
- strcat(currentuser, ")");
- };
-
- if (lookupuser(user)) {
- syslog(LOG_CRIT, "'%s' failed for %s on %s", argvbuf, currentuser, ttyname(2));
-#if HAVE_SULOG
- sulog(0, NULL);
-#endif /* HAVE_SULOG */
- fprintf(stderr, "Unknown user: %s\n", user);
- exit(1);
- }
-
-/* Implement the BSD "wheel group" su restriction. */
-#if DOWHEEL
- /* Only allow those in group zero to su to root? */
- if (thisuser.pw_uid == 0) {
- struct group *gr;
- if ((gr = getgrgid(0)) != NULL) {
- for (i = 0; gr->gr_mem[i] != NULL; i++)
- if (strcmp(buf, gr->gr_mem[i]) == 0)
- goto userok;
- fprintf(stderr, "You do not have permission to su %s\n", user);
- exit(1);
- }
-userok:
- ;
-#if HAVE_SETPRIORITY && HAVE_SYS_RESOURCE_H
- setpriority(PRIO_PROCESS, 0, -2);
-#endif /* HAVE_SETPRIORITY && HAVE_SYS_RESOURCE_H */
- }
-#endif /* DOWHEEL */
- };
-
- if (!thisuser.pw_passwd[0] || getuid() == 0)
- goto ok;
-
- if (console) {
- if (!opiealways(thisuser.pw_dir)) {
- fprintf(stderr, "That account requires OTP responses.\n");
- exit(1);
- };
- /* Get user's secret password */
- fprintf(stderr, "Reminder - Only use this method from the console; NEVER from remote. If you\n");
- fprintf(stderr, "are using telnet, xterm, or a dial-in, type ^C now or exit with no password.\n");
- fprintf(stderr, "Then run su without the -c parameter.\n");
- if (opieinsecure()) {
- fprintf(stderr, "Sorry, but you don't seem to be on the console or a secure terminal.\n");
-#if INSECURE_OVERRIDE
- if (force)
- fprintf(stderr, "Warning: Continuing could disclose your secret pass phrase to an attacker!\n");
- else
-#endif /* INSECURE_OVERRIDE */
- exit(1);
- };
-#if NEW_PROMPTS
- printf("%s's system password: ", thisuser.pw_name);
- if (!opiereadpass(pbuf, sizeof(pbuf), 0))
- goto error;
-#endif /* NEW_PROMPTS */
- } else {
- /* Attempt an OTP challenge */
- i = opiechallenge(&opie, user, opieprompt);
- printf("%s\n", opieprompt);
-#if NEW_PROMPTS
- printf("%s's response: ", thisuser.pw_name);
- if (!opiereadpass(pbuf, sizeof(pbuf), 1))
- goto error;
-#else /* NEW_PROMPTS */
- printf("(OTP response required)\n");
-#endif /* NEW_PROMPTS */
- fflush(stdout);
- };
-#if !NEW_PROMPTS
- printf("%s's password: ", thisuser.pw_name);
- if (!opiereadpass(pbuf, sizeof(pbuf), 0))
- goto error;
-#endif /* !NEW_PROMPTS */
-
-#if !NEW_PROMPTS
- if (!pbuf[0] && !console) {
- /* Null line entered; turn echoing back on and read again */
- printf(" (echo on)\n%s's password: ", thisuser.pw_name);
- if (!opiereadpass(pbuf, sizeof(pbuf), 1))
- goto error;
- }
-#endif /* !NEW_PROMPTS */
-
- if (console) {
- /* Try regular password check, if allowed */
- if (!strcmp(crypt(pbuf, thisuser.pw_passwd), thisuser.pw_passwd))
- goto ok;
- } else {
- int i = opiegetsequence(&opie);
- if (!opieverify(&opie, pbuf)) {
- /* OPIE authentication succeeded */
- if (i < 5)
- fprintf(stderr, "Warning: Change %s's OTP secret pass phrase NOW!\n", user);
- else
- if (i < 10)
- fprintf(stderr, "Warning: Change %s's OTP secret pass phrase soon.\n", user);
- goto ok;
- };
- };
-error:
- if (!console)
- opieverify(&opie, "");
- fprintf(stderr, "Sorry\n");
- syslog(LOG_CRIT, "'%s' failed for %s on %s", argvbuf, currentuser, ttyname(2));
-#if HAVE_SULOG
- sulog(0, NULL);
-#endif /* HAVE_SULOG */
- exit(2);
-
-ok:
- syslog(LOG_NOTICE, "'%s' by %s on %s", argvbuf, currentuser, ttyname(2));
-#if HAVE_SULOG
- sulog(1, NULL);
-#endif /* HAVE_SULOG */
-
- if (setgid(thisuser.pw_gid) < 0) {
- perror("su: setgid");
- exit(3);
- }
- if (initgroups(user, thisuser.pw_gid)) {
- fprintf(stderr, "su: initgroups failed (errno=%d)\n", errno);
- exit(4);
- }
- if (setuid(thisuser.pw_uid) < 0) {
- perror("su: setuid");
- exit(5);
- }
- if (thisuser.pw_shell && *thisuser.pw_shell)
- shell = thisuser.pw_shell;
- if (fulllogin) {
- if ((p = getenv("TERM")) && (strlen(termbuf) + strlen(p) - 1 < sizeof(termbuf))) {
- strcat(termbuf, p);
- cleanenv[4] = termbuf;
- }
- environ = cleanenv;
- }
- if (fulllogin || strcmp(user, "root") != 0)
- lsetenv("USER", thisuser.pw_name, userbuf);
- lsetenv("SHELL", shell, shellbuf);
- lsetenv("HOME", thisuser.pw_dir, homebuf);
-
-#if HAVE_SETPRIORITY && HAVE_SYS_RESOURCE_H
- setpriority(PRIO_PROCESS, 0, 0);
-#endif /* HAVE_SETPRIORITY && HAVE_SYS_RESOURCE_H */
-
-#if 0
- if (fastlogin) {
- *argv-- = "-f";
- *argv = "su";
- } else
-#endif /* 0 */
- if (fulllogin) {
- if (chdir(thisuser.pw_dir) < 0) {
- fprintf(stderr, "No directory\n");
- exit(6);
- }
- *argv = "-su";
- } else {
- *argv = "su";
- }
-
- catchexit();
-
-#if DEBUG
- syslog(LOG_DEBUG, "execing %s", shell);
-#endif /* DEBUG */
- execv(shell, argv);
- fprintf(stderr, "No shell\n");
- exit(7);
-}