home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / passwd / local_passwd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-06  |  4.2 KB  |  146 lines

  1. /*-
  2.  * Copyright (c) 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)local_passwd.c    5.5 (Berkeley) 5/6/91";
  36. #endif /* not lint */
  37.  
  38. #include <sys/types.h>
  39. #include <pwd.h>
  40. #include <errno.h>
  41. #include <stdio.h>
  42.  
  43. uid_t uid;
  44.  
  45. char *progname = "passwd";
  46. char *tempname;
  47.  
  48. local_passwd(uname)
  49.     char *uname;
  50. {
  51.     struct passwd *pw;
  52.     int pfd, tfd;
  53.     char *getnewpasswd();
  54.  
  55.     if (!(pw = getpwnam(uname))) {
  56.         (void)fprintf(stderr, "passwd: unknown user %s.\n", uname);
  57.         exit(1);
  58.     }
  59.  
  60.     uid = getuid();
  61.     if (uid && uid != pw->pw_uid) {
  62.         (void)fprintf(stderr, "passwd: %s\n", strerror(EACCES));
  63.         exit(1);
  64.     }
  65.  
  66.     pw_init();
  67.     pfd = pw_lock();
  68.     tfd = pw_tmp();
  69.  
  70.     /*
  71.      * Get the new password.  Reset passwd change time to zero; when
  72.      * classes are implemented, go and get the "offset" value for this
  73.      * class and reset the timer.
  74.      */
  75.     pw->pw_passwd = getnewpasswd(pw);
  76.     pw->pw_change = 0;
  77.     pw_copy(pfd, tfd, pw);
  78.  
  79.     if (!pw_mkdb())
  80.         pw_error((char *)NULL, 0, 1);
  81.     exit(0);
  82. }
  83.  
  84. char *
  85. getnewpasswd(pw)
  86.     register struct passwd *pw;
  87. {
  88.     register char *p, *t;
  89.     int tries;
  90.     char buf[_PASSWORD_LEN+1], salt[9], *crypt(), *getpass();
  91.  
  92.     (void)printf("Changing local password for %s.\n", pw->pw_name);
  93.  
  94.     if (uid && pw->pw_passwd &&
  95.         strcmp(crypt(getpass("Old password:"), pw->pw_passwd),
  96.         pw->pw_passwd)) {
  97.         errno = EACCES;
  98.         pw_error(NULL, 1, 1);
  99.     }
  100.  
  101.     for (buf[0] = '\0', tries = 0;;) {
  102.         p = getpass("New password:");
  103.         if (!*p) {
  104.             (void)printf("Password unchanged.\n");
  105.             pw_error(NULL, 0, 0);
  106.         }
  107.         if (strlen(p) <= 5 && (uid != 0 || ++tries < 2)) {
  108.             (void)printf("Please enter a longer password.\n");
  109.             continue;
  110.         }
  111.         for (t = p; *t && islower(*t); ++t);
  112.         if (!*t && (uid != 0 || ++tries < 2)) {
  113.             (void)printf("Please don't use an all-lower case password.\nUnusual capitalization, control characters or digits are suggested.\n");
  114.             continue;
  115.         }
  116.         (void)strcpy(buf, p);
  117.         if (!strcmp(buf, getpass("Retype new password:")))
  118.             break;
  119.         (void)printf("Mismatch; try again, EOF to quit.\n");
  120.     }
  121.     /* grab a random printable character that isn't a colon */
  122.     (void)srandom((int)time((time_t *)NULL));
  123. #ifdef NEWSALT
  124.     salt[0] = _PASSWORD_EFMT1;
  125.     to64(&salt[1], (long)(29 * 25), 4);
  126.     to64(&salt[5], random(), 4);
  127. #else
  128.     to64(&salt[0], random(), 2);
  129. #endif
  130.     return(crypt(buf, salt));
  131. }
  132.  
  133. static unsigned char itoa64[] =        /* 0 ... 63 => ascii - 64 */
  134.     "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  135.  
  136. to64(s, v, n)
  137.     register char *s;
  138.     register long v;
  139.     register int n;
  140. {
  141.     while (--n >= 0) {
  142.         *s++ = itoa64[v&0x3f];
  143.         v >>= 6;
  144.     }
  145. }
  146.