From 252e456d08d32e9861e50d735170deefea95fc71 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sat, 1 Jan 1983 21:24:54 -0800 Subject: [PATCH] date and time created 83/01/01 13:24:54 by sam SCCS-vsn: usr.bin/passwd/passwd.c 4.1 --- usr/src/usr.bin/passwd/passwd.c | 183 ++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 usr/src/usr.bin/passwd/passwd.c diff --git a/usr/src/usr.bin/passwd/passwd.c b/usr/src/usr.bin/passwd/passwd.c new file mode 100644 index 0000000000..7e2ed023e7 --- /dev/null +++ b/usr/src/usr.bin/passwd/passwd.c @@ -0,0 +1,183 @@ +#ifndef lint +static char sccsid[] = "@(#)passwd.c 4.1 (Berkeley) %G%"; +#endif + +/* + * enter a password in the password file + * this program should be suid with owner + * with an owner with write permission on /etc/passwd + */ +#include + +#include +#include +#include +#include + +char passwd[] = "/etc/passwd"; +char temp[] = "/etc/ptmp"; +struct passwd *pwd; +struct passwd *getpwent(); +int endpwent(); +char *strcpy(); +char *crypt(); +char *getpass(); +char *getlogin(); +char *pw; +char pwbuf[10]; +extern int errno; + +main(argc, argv) + char *argv[]; +{ + char *p; + int i; + char saltc[2]; + long salt; + int u; + int insist; + int ok, flags; + int c, pwlen, fd; + FILE *tf; + char *uname; + + insist = 0; + if (argc < 2) { + if ((uname = getlogin()) == NULL) { + printf ("Usage: passwd user\n"); + exit(1); + } + printf("Changing password for %s\n", uname); + } else + uname = argv[1]; + while (((pwd = getpwent()) != NULL) && strcmp(pwd->pw_name, uname)) + ; + u = getuid(); + if (pwd == NULL || (u != 0 && u != pwd->pw_uid)) { + printf("Permission denied.\n"); + exit(1); + } + endpwent(); + if (pwd->pw_passwd[0] && u != 0) { + strcpy(pwbuf, getpass("Old password:")); + pw = crypt(pwbuf, pwd->pw_passwd); + if (strcmp(pw, pwd->pw_passwd) != 0) { + printf("Sorry.\n"); + exit(1); + } + } +tryagain: + strcpy(pwbuf, getpass("New password:")); + pwlen = strlen(pwbuf); + if (pwlen == 0) { + printf("Password unchanged.\n"); + exit(1); + } + /* + * Insure password is of reasonable length and + * composition. If we really wanted to make things + * sticky, we could check the dictionary for common + * words, but then things would really be slow. + */ + ok = 0; + flags = 0; + p = pwbuf; + while (c = *p++) { + if (c >= 'a' && c <= 'z') + flags |= 2; + else if (c >= 'A' && c <= 'Z') + flags |= 4; + else if (c >= '0' && c <= '9') + flags |= 1; + else + flags |= 8; + } + if (flags >= 7 && pwlen >= 4) + ok = 1; + if ((flags == 2 || flags == 4) && pwlen >= 6) + ok = 1; + if ((flags == 3 || flags == 5 || flags == 6) && pwlen >= 5) + ok = 1; + if (!ok && insist < 2) { + if (flags == 1) + printf("Please use %s.\n", flags == 1 ? + "at least one non-numeric character" : + "a longer password"); + insist++; + goto tryagain; + } + if (strcmp(pwbuf, getpass("Retype new password:")) != 0) { + printf("Mismatch - password unchanged.\n"); + exit(1); + } + time(&salt); + salt = 9 * getpid(); + saltc[0] = salt & 077; + saltc[1] = (salt>>6) & 077; + for (i = 0; i < 2; i++) { + c = saltc[i] + '.'; + if (c > '9') + c += 7; + if (c > 'Z') + c += 6; + saltc[i] = c; + } + pw = crypt(pwbuf, saltc); + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + /* + * The mode here could be 644 except then old versions + * of passwd that don't honor the advisory locks might + * sneak in and mess things up. If we could believe the + * locking were honored, then we could also eliminate the + * chmod below after the rename. + */ + fd = open(temp, FWRONLY|FCREATE|FEXLOCK|FNBLOCK, 0600); + if (fd < 0) { + fprintf(stderr, "passwd: "); + if (errno == EBUSY) + fprintf(stderr, "password file busy - try again.\n"); + else + perror(temp); + exit(1); + } + signal(SIGTSTP, SIG_IGN); + if ((tf = fdopen(fd, "w")) == NULL) { + fprintf(stderr, "passwd: fdopen failed?\n"); + exit(1); + } + /* + * Copy passwd to temp, replacing matching lines + * with new password. + */ + while ((pwd = getpwent()) != NULL) { + if (strcmp(pwd->pw_name,uname) == 0) { + u = getuid(); + if (u && u != pwd->pw_uid) { + fprintf(stderr, "passwd: permission denied.\n"); + unlink(temp); + exit(1); + } + pwd->pw_passwd = pw; + if (pwd->pw_gecos[0] == '*') + pwd->pw_gecos++; + } + fprintf(tf,"%s:%s:%d:%d:%s:%s:%s\n", + pwd->pw_name, + pwd->pw_passwd, + pwd->pw_uid, + pwd->pw_gid, + pwd->pw_gecos, + pwd->pw_dir, + pwd->pw_shell); + } + endpwent(); + if (rename(temp, passwd) < 0) { + fprintf(stderr, "passwd: "); perror("rename"); + unlink(temp); + exit(1); + } + chmod(passwd, 0644); + fclose(tf); +} -- 2.20.1