[BACK]Return to su.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / su

Diff for /src/usr.bin/su/su.c between version 1.7 and 1.8

version 1.7, 1996/10/12 17:13:57 version 1.8, 1996/10/12 20:40:37
Line 47 
Line 47 
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/time.h>  #include <sys/time.h>
 #include <sys/resource.h>  #include <sys/resource.h>
 #include <syslog.h>  
   #include <err.h>
   #include <errno.h>
   #include <grp.h>
   #include <paths.h>
   #include <pwd.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <pwd.h>  
 #include <grp.h>  
 #include <string.h>  #include <string.h>
   #include <syslog.h>
 #include <unistd.h>  #include <unistd.h>
 #include <paths.h>  
   
   #ifdef  SKEY
   #include <skey.h>
   #endif
   
 #ifdef KERBEROS  #ifdef KERBEROS
 #include <kerberosIV/des.h>  #include <kerberosIV/des.h>
 #include <kerberosIV/krb.h>  #include <kerberosIV/krb.h>
Line 68 
Line 75 
 #define ARGSTR  "-flm"  #define ARGSTR  "-flm"
 #endif  #endif
   
 extern char *crypt();  char   *ontty __P((void));
 int chshell();  int     chshell __P((char *));
   
 int  int
 main(argc, argv)  main(argc, argv)
Line 77 
Line 84 
         char **argv;          char **argv;
 {  {
         extern char **environ;          extern char **environ;
         extern int errno, optind;  
         register struct passwd *pwd;          register struct passwd *pwd;
         register char *p, **g;          register char *p, **g;
         struct group *gr;          struct group *gr;
Line 86 
Line 92 
         enum { UNSET, YES, NO } iscsh = UNSET;          enum { UNSET, YES, NO } iscsh = UNSET;
         char *user, *shell, *avshell, *username, *cleanenv[10], **np;          char *user, *shell, *avshell, *username, *cleanenv[10], **np;
         char shellbuf[MAXPATHLEN], avshellbuf[MAXPATHLEN];          char shellbuf[MAXPATHLEN], avshellbuf[MAXPATHLEN];
         char *getpass(), *getenv(), *getlogin(), *ontty();  
   
         asme = asthem = fastlogin = 0;          asme = asthem = fastlogin = 0;
         while ((ch = getopt(argc, argv, ARGSTR)) != EOF)          while ((ch = getopt(argc, argv, ARGSTR)) != EOF)
Line 130 
Line 135 
         if (username == NULL || (pwd = getpwnam(username)) == NULL ||          if (username == NULL || (pwd = getpwnam(username)) == NULL ||
             pwd->pw_uid != ruid)              pwd->pw_uid != ruid)
                 pwd = getpwuid(ruid);                  pwd = getpwuid(ruid);
         if (pwd == NULL) {          if (pwd == NULL)
                 fprintf(stderr, "su: who are you?\n");                  errx(1, "who are you?");
                 exit(1);  
         }  
         username = strdup(pwd->pw_name);          username = strdup(pwd->pw_name);
         if (asme)          if (asme)
                 if (pwd->pw_shell && *pwd->pw_shell)                  if (pwd->pw_shell && *pwd->pw_shell)
Line 147 
Line 150 
         user = *argv ? *argv : "root";          user = *argv ? *argv : "root";
         np = *argv ? argv : argv-1;          np = *argv ? argv : argv-1;
   
         if ((pwd = getpwnam(user)) == NULL) {          if ((pwd = getpwnam(user)) == NULL)
                 fprintf(stderr, "su: unknown login %s\n", user);                  errx(1, "unknown login %s", user);
                 exit(1);  
         }  
   
         if (ruid) {          if (ruid) {
 #ifdef KERBEROS  #ifdef KERBEROS
Line 161 
Line 162 
                 if (pwd->pw_uid == 0 && (gr = getgrgid((gid_t)0))                  if (pwd->pw_uid == 0 && (gr = getgrgid((gid_t)0))
                     && gr->gr_mem && *(gr->gr_mem))                      && gr->gr_mem && *(gr->gr_mem))
                         for (g = gr->gr_mem;; ++g) {                          for (g = gr->gr_mem;; ++g) {
                                 if (!*g) {                                  if (!*g)
                                         (void)fprintf(stderr,                                          errx(1, "you are not in the correct group to su %s.", user);
                             "su: you are not in the correct group to su %s.\n",                                  if (strcmp(username, *g) == 0)
                                             user);  
                                         exit(1);  
                                 }  
                                 if (!strcmp(username, *g))  
                                         break;                                          break;
                 }                  }
                 /* if target requires a password, verify it */                  /* if target requires a password, verify it */
Line 175 
Line 172 
                         p = getpass("Password:");                          p = getpass("Password:");
 #ifdef SKEY  #ifdef SKEY
                         if (strcasecmp(p, "s/key") == 0) {                          if (strcasecmp(p, "s/key") == 0) {
                                 if (skey_haskey(user)) {                                  if (skey_haskey(user))
                                         fprintf(stderr, "Sorry, you have no s/key.\n");                                          errx(1, "Sorry, you have no s/key.");
                                         exit(1);                                  else if (skey_authenticate(user))
                                 } else {                                          goto badlogin;
                                         if (skey_authenticate(user)) {  
                                                 goto badlogin;  
                                         }  
                                 }  
   
                         } else                          } else
 #endif  #endif
                         if (strcmp(pwd->pw_passwd, crypt(p, pwd->pw_passwd))) {                          if (strcmp(pwd->pw_passwd, crypt(p, pwd->pw_passwd))) {
Line 196 
Line 188 
                         }                          }
                 }                  }
             }              }
               if (pwd->pw_expire && time(NULL) >= pwd->pw_expire) {
                       fprintf(stderr, "Sorry - account expired\n");
                       syslog(LOG_AUTH|LOG_WARNING, "BAD SU %s to %s%s", username,
                               user, ontty());
                       exit(1);
               }
         }          }
   
         if (asme) {          if (asme) {
                 /* if asme and non-standard target shell, must be root */                  /* if asme and non-standard target shell, must be root */
                 if (!chshell(pwd->pw_shell) && ruid) {                  if (!chshell(pwd->pw_shell) && ruid)
                         (void)fprintf(stderr,                          errx(1, "permission denied (shell).");
                                 "su: permission denied (shell).\n");  
                         exit(1);  
                 }  
         } else if (pwd->pw_shell && *pwd->pw_shell) {          } else if (pwd->pw_shell && *pwd->pw_shell) {
                 shell = pwd->pw_shell;                  shell = pwd->pw_shell;
                 iscsh = UNSET;                  iscsh = UNSET;
Line 213 
Line 208 
                 iscsh = NO;                  iscsh = NO;
         }          }
   
         if (p = rindex(shell, '/'))          if (p = strrchr(shell, '/'))
                 avshell = p+1;                  avshell = p+1;
         else          else
                 avshell = shell;                  avshell = shell;
Line 223 
Line 218 
                 iscsh = strcmp(avshell, "csh") ? NO : YES;                  iscsh = strcmp(avshell, "csh") ? NO : YES;
   
         /* set permissions */          /* set permissions */
         if (setgid(pwd->pw_gid) < 0) {          if (setgid(pwd->pw_gid) < 0)
                 perror("su: setgid");                  err(1, "setgid");
                 exit(1);          if (initgroups(user, pwd->pw_gid))
         }                  err(1, "initgroups failed");
         if (initgroups(user, pwd->pw_gid)) {          if (setuid(pwd->pw_uid) < 0)
                 (void)fprintf(stderr, "su: initgroups failed.\n");                  err(1, "setuid");
                 exit(1);  
         }  
         if (setuid(pwd->pw_uid) < 0) {  
                 perror("su: setuid");  
                 exit(1);  
         }  
   
         if (!asme) {          if (!asme) {
                 if (asthem) {                  if (asthem) {
Line 247 
Line 236 
   
                         seteuid(pwd->pw_uid);                          seteuid(pwd->pw_uid);
                         setegid(pwd->pw_gid);                          setegid(pwd->pw_gid);
                         if (chdir(pwd->pw_dir) < 0) {                          if (chdir(pwd->pw_dir) < 0)
                                 fprintf(stderr, "su: no directory\n");                                  errx(1, "no directory");
                                 exit(1);  
                         }  
                         seteuid(0);                          seteuid(0);
                         setegid(0);     /* XXX use a saved gid instead? */                          setegid(0);     /* XXX use a saved gid instead? */
                 }                  }
Line 287 
Line 274 
         (void)setpriority(PRIO_PROCESS, 0, prio);          (void)setpriority(PRIO_PROCESS, 0, prio);
   
         execv(shell, np);          execv(shell, np);
         (void)fprintf(stderr, "su: %s not found.\n", shell);          err(1, "%s", shell);
         exit(1);  
 }  }
   
 int  int
Line 296 
Line 282 
         char *sh;          char *sh;
 {  {
         register char *cp;          register char *cp;
         char *getusershell();  
   
         while ((cp = getusershell()) != NULL)          while ((cp = getusershell()) != NULL)
                 if (!strcmp(cp, sh))                  if (strcmp(cp, sh) == 0)
                         return (1);                          return (1);
         return (0);          return (0);
 }  }
Line 312 
Line 297 
   
         buf[0] = 0;          buf[0] = 0;
         if (p = ttyname(STDERR_FILENO))          if (p = ttyname(STDERR_FILENO))
                 sprintf(buf, " on %s", p);                  snprintf(buf, sizeof(buf), " on %s", p);
         return (buf);          return (buf);
 }  }
   
Line 337 
Line 322 
                 (void)fprintf(stderr, "kerberos su: not in %s's ACL.\n", user);                  (void)fprintf(stderr, "kerberos su: not in %s's ACL.\n", user);
                 return (1);                  return (1);
         }          }
         (void)sprintf(krbtkfile, "%s_%s_%d", TKT_ROOT, user, getuid());          (void)snprintf(krbtkfile, sizeof(krbtkfile), "%s_%s_%d", TKT_ROOT,
                   user, getuid());
   
         (void)setenv("KRBTKFILE", krbtkfile, 1);          (void)setenv("KRBTKFILE", krbtkfile, 1);
         (void)krb_set_tkt_string(krbtkfile);          (void)krb_set_tkt_string(krbtkfile);
Line 346 
Line 332 
          * to make the kerberos library do the right thing.           * to make the kerberos library do the right thing.
          */           */
         if (setuid(0) < 0) {          if (setuid(0) < 0) {
                 perror("su: setuid");                  warn("setuid");
                 return (1);                  return (1);
         }          }
   
Line 366 
Line 352 
   
         if (kerno != KSUCCESS) {          if (kerno != KSUCCESS) {
                 if (kerno == KDC_PR_UNKNOWN) {                  if (kerno == KDC_PR_UNKNOWN) {
                         fprintf(stderr, "principal unknown: %s.%s@%s\n",                          warnx("kerberos principal unknown: %s.%s@%s",
                                 (uid == 0 ? username : user),                                  (uid == 0 ? username : user),
                                 (uid == 0 ? "root" : ""), lrealm);                                  (uid == 0 ? "root" : ""), lrealm);
                         return (1);                          return (1);
                 }                  }
                 (void)fprintf(stderr, "su: unable to su: %s\n",                  warnx("unable to su: %s", krb_err_txt[kerno]);
                     krb_err_txt[kerno]);  
                 syslog(LOG_NOTICE|LOG_AUTH,                  syslog(LOG_NOTICE|LOG_AUTH,
                     "BAD Kerberos SU: %s to %s%s: %s",                      "BAD Kerberos SU: %s to %s%s: %s",
                     username, user, ontty(), krb_err_txt[kerno]);                      username, user, ontty(), krb_err_txt[kerno]);
Line 380 
Line 365 
         }          }
   
         if (chown(krbtkfile, uid, -1) < 0) {          if (chown(krbtkfile, uid, -1) < 0) {
                 perror("su: chown:");                  warn("chown");
                 (void)unlink(krbtkfile);                  (void)unlink(krbtkfile);
                 return (1);                  return (1);
         }          }
Line 388 
Line 373 
         (void)setpriority(PRIO_PROCESS, 0, -2);          (void)setpriority(PRIO_PROCESS, 0, -2);
   
         if (gethostname(hostname, sizeof(hostname)) == -1) {          if (gethostname(hostname, sizeof(hostname)) == -1) {
                 perror("su: gethostname");                  warn("gethostname");
                 dest_tkt();                  dest_tkt();
                 return (1);                  return (1);
         }          }
Line 399 
Line 384 
         kerno = krb_mk_req(&ticket, "rcmd", savehost, lrealm, 33);          kerno = krb_mk_req(&ticket, "rcmd", savehost, lrealm, 33);
   
         if (kerno == KDC_PR_UNKNOWN) {          if (kerno == KDC_PR_UNKNOWN) {
                 (void)fprintf(stderr, "Warning: TGT not verified.\n");                  warnx("Warning: TGT not verified.");
                 syslog(LOG_NOTICE|LOG_AUTH,                  syslog(LOG_NOTICE|LOG_AUTH,
                     "%s to %s%s, TGT not verified (%s); %s.%s not registered?",                      "%s to %s%s, TGT not verified (%s); %s.%s not registered?",
                     username, user, ontty(), krb_err_txt[kerno],                      username, user, ontty(), krb_err_txt[kerno],
                     "rcmd", savehost);                      "rcmd", savehost);
         } else if (kerno != KSUCCESS) {          } else if (kerno != KSUCCESS) {
                 (void)fprintf(stderr, "Unable to use TGT: %s\n",                  warnx("Unable to use TGT: %s", krb_err_txt[kerno]);
                     krb_err_txt[kerno]);  
                 syslog(LOG_NOTICE|LOG_AUTH, "failed su: %s to %s%s: %s",                  syslog(LOG_NOTICE|LOG_AUTH, "failed su: %s to %s%s: %s",
                     username, user, ontty(), krb_err_txt[kerno]);                      username, user, ontty(), krb_err_txt[kerno]);
                 dest_tkt();                  dest_tkt();
                 return (1);                  return (1);
         } else {          } else {
                 if (!(hp = gethostbyname(hostname))) {                  if (!(hp = gethostbyname(hostname))) {
                         (void)fprintf(stderr, "su: can't get addr of %s\n",                          warnx("can't get addr of %s", hostname);
                             hostname);  
                         dest_tkt();                          dest_tkt();
                         return (1);                          return (1);
                 }                  }
Line 422 
Line 405 
   
                 if ((kerno = krb_rd_req(&ticket, "rcmd", savehost, faddr,                  if ((kerno = krb_rd_req(&ticket, "rcmd", savehost, faddr,
                     &authdata, "")) != KSUCCESS) {                      &authdata, "")) != KSUCCESS) {
                         (void)fprintf(stderr,                          warnx("unable to verify rcmd ticket: %s",
                             "su: unable to verify rcmd ticket: %s\n",                                krb_err_txt[kerno]);
                             krb_err_txt[kerno]);  
                         syslog(LOG_NOTICE|LOG_AUTH,                          syslog(LOG_NOTICE|LOG_AUTH,
                             "failed su: %s to %s%s: %s", username,                              "failed su: %s to %s%s: %s", username,
                              user, ontty(), krb_err_txt[kerno]);                               user, ontty(), krb_err_txt[kerno]);

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.8