summaryrefslogtreecommitdiffstats
path: root/chpass/pw_copy.c
diff options
context:
space:
mode:
Diffstat (limited to 'chpass/pw_copy.c')
-rw-r--r--chpass/pw_copy.c36
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 : "",