home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume3 / chsh < prev    next >
Text File  |  1986-11-30  |  3KB  |  134 lines

  1. Subject: chsh chfn for SV
  2. Newsgroups: mod.sources
  3. Approved: jpn@panda.UUCP
  4.  
  5. Mod.sources:  Volume 3, Issue 98
  6. Submitted by: decvax!cwruecmp!rexago1!rich (K. Richard Magill)
  7.  
  8. I got tired of editting passwd files so...
  9.  
  10. This is tested & running on a 3b2/300 SV.2.2.  It uses a lot of library
  11. routines that probably don't exist outside SV.  (sorry).
  12.  
  13. ----hack & slash here----
  14. /*
  15.  *    I AM NOT A SHELL ARCHIVE!
  16.  *
  17.  *    This file is chsh.c and contains a public domain version
  18.  *    of chsh/chfn intended for SV.  Calling sequence is
  19.  *
  20.  *        chfn user new_name
  21.  *    or    chsh user new_shell
  22.  *    
  23.  *    A null name means a null name. A null shell means /bin/sh.
  24.  *    Your old passwd file is stored in /etc/passwd~.  Protections
  25.  *    and passwd requests work like su.  To install use:
  26.  *
  27.  *        make chsh
  28.  *        chmod 4555 chsh
  29.  *        ln chsh /usr/lbin (or some such)
  30.  *        ln chsh /usr/lbin/chfn
  31.  *
  32.  *    AAAAnyway, you get the idea.
  33.  *
  34.  *    K. Richard Magill, 26-jan-86.
  35.  *    Last Mod 26-jan-86, rich.
  36.  */
  37.  
  38. #include <stdio.h>
  39. #include <sys/types.h>
  40. #include <sys/stat.h>
  41. #include <pwd.h>
  42.  
  43. #define WATCH(x)    if(x){perror(argv[0]);return(-1);}
  44.  
  45. char *PASSWD = "/etc/passwd";
  46. char *BACKUP = "/etc/passwd~";
  47. char *TEMP = "/tmp/chshXXXXXX";
  48.  
  49. void endpwent(), perror();
  50. char *crypt(), *getpass(), *mktemp();
  51. struct passwd *getpwent(), *getpwnam(), *fgetpwent();
  52.  
  53. main(argc, argv)
  54. int argc;
  55. char **argv;
  56. {
  57.     register int i;
  58.     register struct passwd *p;
  59.     FILE *fin, *fout;
  60.     int target_id;
  61.     struct stat stat_buf;
  62.  
  63.     if (argc < 2 || argc > 3) {
  64.         (void) fprintf(stderr, "usage: %s login shell\n", argv[0]);
  65.         return(-1);
  66.     }    /* if usage error */
  67.  
  68.     /* is this person real? */
  69.  
  70.     if ((p = getpwnam(argv[1])) == NULL) {
  71.         (void) fprintf(stderr, "%s: don't know %s\n",
  72.             argv[0], argv[1]);
  73.         return(-1);
  74.     }    /* if person isn't real */
  75.  
  76.     /* do we have permission to do this? */
  77.     target_id = p->pw_uid;
  78.  
  79.     if ((i = getuid()) != 0 && i != target_id) {
  80.         char salt[3];
  81.  
  82.         salt[0] = p->pw_passwd[0];
  83.         salt[1] = p->pw_passwd[1];
  84.         salt[3] = '\0';
  85.  
  86.         if (*p->pw_passwd != '\0'
  87.             && strncmp(crypt(getpass("Password: "), salt),
  88.             p->pw_passwd, 8)) {
  89.             (void) fprintf(stderr, "Sorry.\n");
  90.             return(-1);
  91.         }    /* passwd didn't match */
  92.     }    /* check for permission */
  93.  
  94.     /* set up files */
  95.  
  96.     endpwent();    /* close passwd file */
  97.  
  98.     WATCH((fin = fopen(PASSWD, "r")) == NULL);
  99.     WATCH((fout = fopen(mktemp(TEMP), "w")) == NULL);
  100.  
  101.     while ((p = fgetpwent(fin)) != NULL) {
  102.         if (p->pw_uid == target_id) {
  103.             if (strcmp(argv[0], "chsh")) {
  104.                 p->pw_gecos = argv[2];
  105.             } else {
  106.                 p->pw_shell = argv[2] == NULL ? "/bin/sh"
  107.                     : argv[2];
  108.             }
  109.         }    /* if this is entry to be changed */
  110.  
  111.         WATCH(putpwent(p, fout));
  112.     }    /* while not eof (we couldn't recognize an error) */
  113.  
  114.     /* close files */
  115.     WATCH(fclose(fin) || fclose(fout));
  116.  
  117.     /* remove old backup if it exists */
  118.     WATCH(!stat(BACKUP, &stat_buf) && unlink(BACKUP));
  119.  
  120.     /* make current passwd file backup */
  121.     WATCH(link(PASSWD, BACKUP) || unlink(PASSWD));
  122.  
  123.     /* make new file passwd */
  124.     WATCH(link(TEMP, PASSWD) || unlink(TEMP));
  125.  
  126.     /* must have succeeded */
  127.     return(0);
  128. }    /* main */
  129.  
  130.  
  131. /* EOF */
  132.  
  133.  
  134.