diff options
| author | Crist J. Clark <cjc@FreeBSD.org> | 2002-03-18 02:22:53 +0000 |
|---|---|---|
| committer | Crist J. Clark <cjc@FreeBSD.org> | 2002-03-18 02:22:53 +0000 |
| commit | f51ea5a6dc09ca726b14a65d08ee2496cb81c117 (patch) | |
| tree | 8cec45bbb7c84f57abf64bb0014b19524fa22395 /chpass/pw_copy.c | |
| parent | 18a996f84742152003f9358a7078921d43450ef5 (diff) | |
| download | pw-darwin-f51ea5a6dc09ca726b14a65d08ee2496cb81c117.tar.gz pw-darwin-f51ea5a6dc09ca726b14a65d08ee2496cb81c117.zip | |
It was possible for an unprivileged user to tie up the password
information (no one else can vipw(8), chpass(1), or even passwd(1)),
either on purpose or by accident, until an administrator manually
intervened. Instead, do not lock the master.passwd file while a user
is editing his information. But once we go to write the new
information, check that the modified user's information has not
changed in the password database since we started. Abort the changes
if it has.
Add a $FreeBSD$ to pw_copy.h.
PR: i386/35816
Obtained from: NetBSD
MFC after: 1 week
Diffstat (limited to 'chpass/pw_copy.c')
| -rw-r--r-- | chpass/pw_copy.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/chpass/pw_copy.c b/chpass/pw_copy.c index d475757..2e86dc3 100644 --- a/chpass/pw_copy.c +++ b/chpass/pw_copy.c @@ -48,15 +48,41 @@ static const char sccsid[] = "@(#)pw_copy.c 8.4 (Berkeley) 4/2/94"; #include <string.h> #include <unistd.h> +#include <pw_scan.h> #include <pw_util.h> + #include "pw_copy.h" extern char *tempname; +/* for use in pw_copy(). Compare a pw entry to a pw struct. */ +static int +pw_equal(char *buf, struct passwd *pw) +{ + struct passwd buf_pw; + int len; + + len = strlen (buf); + if (buf[len-1] == '\n') + buf[len-1] = '\0'; + if (!__pw_scan(buf, &buf_pw, _PWSCAN_MASTER)) + return 0; + return (strcmp(pw->pw_name, buf_pw.pw_name) == 0 + && pw->pw_uid == buf_pw.pw_uid + && pw->pw_gid == buf_pw.pw_gid + && strcmp(pw->pw_class, buf_pw.pw_class) == 0 + && (long)pw->pw_change == (long)buf_pw.pw_change + && (long)pw->pw_expire == (long)buf_pw.pw_expire + && strcmp(pw->pw_gecos, buf_pw.pw_gecos) == 0 + && strcmp(pw->pw_dir, buf_pw.pw_dir) == 0 + && strcmp(pw->pw_shell, buf_pw.pw_shell) == 0); +} + + void -pw_copy(ffd, tfd, pw) +pw_copy(ffd, tfd, pw, old_pw) int ffd, tfd; - struct passwd *pw; + struct passwd *pw, *old_pw; { FILE *from, *to; int done; @@ -108,6 +134,12 @@ pw_copy(ffd, tfd, pw) goto err; continue; } + *p = ':'; + if (old_pw && !pw_equal(buf, old_pw)) { + warnx("%s: entry for %s has changed", + _PATH_MASTERPASSWD, pw->pw_name); + pw_error(NULL, 0, 1); + } (void)fprintf(to, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n", pw->pw_name, pw->pw_passwd, pw->pw_fields & _PWF_UID ? uidstr : "", |
