home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / npasswd / part02 / pw_userinfo.c < prev   
Encoding:
C/C++ Source or Header  |  1991-12-19  |  6.6 KB  |  270 lines

  1.  
  2. /* --------------------------------------------------------------------  */
  3. /*                                                                       */
  4. /*                         Author: Clyde Hoover                          */
  5. /*                          Computation Center                           */
  6. /*                   The University of Texas at Austin                   */
  7. /*                          Austin, Texas 78712                          */
  8. /*                         clyde@emx.utexas.edu                          */
  9. /*                   uunet!cs.utexas.edu!ut-emx!clyde                    */
  10. /*                                                                       */
  11. /*This code may be distributed freely, provided this notice is retained. */
  12. /*                                                                       */
  13. /* --------------------------------------------------------------------  */
  14. /*
  15.  *    pw_userinfo.c - UTEXAS CC UNIX User Information Data Base
  16.  *        backend for npasswd
  17.  */
  18. #ifndef lint
  19. static char sccsid[] = "@(#)pw_userinfo.c    1.4 8/7/90 (cc.utexas.edu) /tmp_mnt/usr/share/src/private/ut/share/bin/passwd/SCCS/s.pw_userinfo.c";
  20. #endif
  21.  
  22. #include <stdio.h>
  23. #include <errno.h>
  24. #include <syslog.h>
  25. #include <strings.h>
  26. #include <signal.h>
  27. #include <pwd.h>
  28. #include <local/userinfo.h>
  29.  
  30. static userdata    theUser,    /* User having password changed */
  31.         Me;        /* User doing password change */
  32.  
  33. #define    P_USER    1
  34. #define    P_PRIV    2
  35. #define    P_SU    3
  36.  
  37. static short    priv = P_USER;    /* Privlege level of <Me> */
  38.  
  39. #define    QUOTEC    '"'        /* Character to start plaintext pwd */
  40. #define    XPWLEN    3        /* Length of 'original CDC password' */
  41.  
  42. extern char    *getlogin(),
  43.         *crypt(),
  44.         *index(),
  45.         *rindex();
  46.  
  47. /*
  48.  *    pw_initialize - set up
  49.  */
  50. pw_initialize()
  51. {
  52.     char    *myname = getlogin();        /* Login name */
  53.     struct passwd *pw;            /* If getlogin() fails... */
  54.     userptr    u;            /* Temp */
  55.  
  56.     if (myname == NULL || *myname == '\0') {
  57.         if ((pw = getpwuid(getuid())) == ((struct passwd *)NULL))
  58.             quit(1, "Cannot get user name.\n");
  59.         else
  60.             myname = pw->pw_name;
  61.     }
  62.     bzero((char *)&theUser, sizeof(theUser));
  63.     bzero((char *)&Me, sizeof(Me));
  64.     if ((u = getuserbyname(myname)) == NULL)
  65.         quit(1, "Cannot get user identification.\n");
  66.     Me = *u;
  67.     if (Me.ui_priv.p_acct_maint)    /* Account maintenance priv? */
  68.         priv = P_PRIV;
  69.     if (getuid() == 0)        /* SuperUser? */
  70.         priv = P_SU;
  71. }
  72.  
  73. /*
  74.  *    pw_getuserbyname - Get userinfo data by name
  75.  *
  76.  *    Returns 1 if passwd info found for <name>
  77.  *        0 otherwise
  78.  */
  79. pw_getuserbyname(name, passwdb)
  80. char    *name,            /* Login name */
  81.     *passwdb;        /* Where to stash password */
  82. {
  83.     userptr    u;            /* Temp */
  84.  
  85.     if ((u = getuserbyname(name)) == NULL)
  86.         return(0);
  87.     theUser = *u;
  88.     (void) strcpy(passwdb, theUser.ui_password);
  89.     return(1);
  90. }
  91.  
  92. /*
  93.  *    pw_permission - check if this user can change this password
  94.  */
  95. pw_permission()
  96. {
  97.     int    mypasswd        /* Wanting to change own password? */
  98.         = (theUser.ui_uid == Me.ui_uid);
  99.  
  100.     /*
  101.      * Must be su to change root password.
  102.      */
  103.     if (theUser.ui_uid == 0 && priv != P_SU) {
  104.         fprintf(stderr, "Permission denied.\n");
  105.         return(0);
  106.     }
  107.  
  108.     /*
  109.      * Must be su or have 'account maintenace' capability to change
  110.      * someone else's password.
  111.      */
  112.     if (!mypasswd && priv < P_PRIV) {
  113.         fprintf(stderr, "Permission denied.\n");
  114.         return(0);
  115.     }
  116.  
  117.     /*
  118.      * If 'password change' capability denied, then user cannot
  119.      * change their own password.
  120.      */
  121.     if (theUser.ui_priv.p_nopwchange && mypasswd) {
  122.         fprintf(stderr, "Permission denied.\n");
  123.         return(0);
  124.     }
  125.     /*
  126.      * We know at this point that the
  127.      * invoker does have permission to change the password.
  128.      */
  129.     return(1);
  130. }
  131.  
  132. /*
  133.  *    pw_compare - compare old and new passwords
  134.  *
  135.  *    Returns 1 if check = new, 0 if not
  136.  */
  137. pw_compare(current, check)
  138. char    *current,
  139.     *check;
  140. {
  141.     if (!*current)
  142.         return(1);
  143.     return(strcmp(current, crypt(check, current)) == 0);
  144. }
  145.  
  146. /*
  147.  *    pw_check - sanity check password.  Performs some site-specific
  148.  *        checks, then calls the checkpasswd() code.
  149.  *
  150.  *    Returns 1 if password is ok to use, 0 otherwise
  151.  */
  152. pw_check(new)
  153. char    *new;        /* New password (plaintext) */
  154. {
  155.     /* Setting null password? */
  156.     if (strcmp(new, "@") == 0) {
  157.         if (theUser.ui_priv.p_null_pass == 0 || priv < P_PRIV) {
  158.             fprintf(stderr, "Cannot set null password.\n");
  159.             return(0);
  160.         }
  161.         else
  162.             return(1);
  163.     }
  164.  
  165.     /* A plain text password (enclosed in ""s)? */
  166.     if (*new == QUOTEC) {
  167.         char    *p = &new[1];
  168.  
  169.         while (*p) p++;
  170.         if (p[-1] == QUOTEC) {
  171.             if (priv == P_SU)    /* Reserved for superuser */
  172.                 return(1);
  173.             else {
  174.                 fprintf(stderr,
  175.                     "Cannot set plaintext password.\n");
  176.                 return(0);
  177.             }
  178.         }
  179.     }
  180.  
  181.     /* Special password (reserved for superuser) */
  182.     if (strlen(new) == XPWLEN && priv == P_SU)
  183.         return(1); 
  184.  
  185.     /* Dispatch to general password checker */
  186.     return(checkpasswd(theUser.ui_uid, new));
  187. }
  188.  
  189. /*
  190.  *    pw_replace - Replace password in Userinfo database
  191.  */
  192. pw_replace(new, current)
  193. char    *new,        /* New password (plaintext) */
  194.     *current;    /* Current password (plaintext) [unused] */
  195. {
  196.     userptr    newu;            /* Temp */
  197.     int    rc;            /* Temp */
  198.     long    oldsigs,        /* Saved signal mask */
  199.         blockedsigs = sigmask(SIGINT) |        /* Signals to block */
  200.                   sigmask(SIGQUIT) |    /* while updating */
  201.                   sigmask(SIGTSTP);        /* the database */
  202.     extern int    errno;
  203.  
  204.     /*
  205.      * Password has already been validated by pw_check()
  206.      */
  207.     if ((newu = getuserbyuid(theUser.ui_uid)) == NULL)
  208.         quit(1, "pw_replace: Cannot refetch user information.\n");
  209.  
  210.     if (strcmp(new, "@") == 0) {
  211.         printf("Password removed from %s\n", theUser.ui_name);
  212. #ifndef    DEBUG
  213.         syslog(LOG_INFO, "Password removed from %s\n", theUser.ui_name);
  214. #endif
  215.         newu->ui_password[0] = 0;
  216.     }
  217.     else {
  218.         char    salt[2];
  219.  
  220.         randomstring(salt, sizeof(salt));
  221.         (void) strcpy(newu->ui_password, crypt(new, salt));
  222.         if (*new == QUOTEC && priv == P_SU) {
  223.             char    *p = new;
  224.  
  225.             while (*p) p++;
  226.             if (*--p == QUOTEC) {
  227.                 *p = 0;
  228.                 (void) strcpy(newu->ui_password, &new[1]);
  229.                 printf("Setting plain text password.\n");
  230.             }
  231.         }
  232.     }
  233.     ui_acct(newu)->a_pwchanged = time((time_t *)0);
  234.  
  235. #if    0
  236.     if (UIRecordChanged(newu))
  237.         quit(1, "Record synchronization error\n");
  238. #endif
  239. #ifdef    DEBUG
  240.     printf("replace %s %s\n", theUser.ui_password, newu->ui_password);
  241. #else
  242.     errno = 0;
  243.     oldsigs = sigblock(blockedsigs);
  244.     if (lockuser(theUser.ui_uid) < 0) {
  245.         if (errno == ETXTBSY)
  246.             quit(1,
  247.                 "pw_replace: Data for %s locked out.\n",
  248.                 theUser.ui_name);
  249.         else
  250.             quit(1,
  251.                 "pw_replace: Data lock failure for user %s\n",
  252.                 theUser.ui_name);
  253.     }
  254.     rc = UIReplaceEntry(newu);
  255.     (void) sigsetmask(oldsigs);
  256.     unlockuser(theUser.ui_uid);
  257.     if (rc < 0)
  258.         quit(1, "Userinfo update failure %s\n", UIErrorMessage);
  259. #endif
  260. }
  261.  
  262. /*
  263.  *    pw_cleanup - cleanup routine
  264.  */
  265. pw_cleanup()
  266. {
  267.     /* Do nothing */
  268. }
  269. /*    End pw_userinfo.c        */
  270.