]> git.cameronkatri.com Git - pw-darwin.git/blobdiff - chpass/pw_copy.c
fix a serious bug where, on alpha, due to a an int/long type mismatch,
[pw-darwin.git] / chpass / pw_copy.c
index 3db04ed5f7cbff20b3d408b0694c3ec263764c01..5d5a7deb6e7e07a4c82dfcfc0b6c60b9599a6921 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)pw_copy.c  8.4 (Berkeley) 4/2/94";
+static const char sccsid[] = "@(#)pw_copy.c    8.4 (Berkeley) 4/2/94";
 #endif /* not lint */
 
 /*
@@ -44,6 +44,7 @@ static char sccsid[] = "@(#)pw_copy.c 8.4 (Berkeley) 4/2/94";
 #include <pwd.h>
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <pw_util.h>
 #include "pw_copy.h"
@@ -58,6 +59,15 @@ pw_copy(ffd, tfd, pw)
        FILE *from, *to;
        int done;
        char *p, buf[8192];
+       char uidstr[20];
+       char gidstr[20];
+       char chgstr[20];
+       char expstr[20];
+
+       snprintf(uidstr, sizeof(uidstr), "%d", pw->pw_uid);
+       snprintf(gidstr, sizeof(gidstr), "%d", pw->pw_gid);
+       snprintf(chgstr, sizeof(chgstr), "%ld", (long)pw->pw_change);
+       snprintf(expstr, sizeof(expstr), "%ld", (long)pw->pw_expire);
 
        if (!(from = fdopen(ffd, "r")))
                pw_error(_PATH_MASTERPASSWD, 1, 1);
@@ -75,6 +85,15 @@ pw_copy(ffd, tfd, pw)
                                goto err;
                        continue;
                }
+               for (p = buf; *p != '\n'; p++)
+                       if (*p != ' ' && *p != '\t')
+                               break;
+               if (*p == '#' || *p == '\n') {
+                       (void)fprintf(to, "%s", buf);
+                       if (ferror(to))
+                               goto err;
+                       continue;
+               }
                if (!(p = strchr(buf, ':'))) {
                        warnx("%s: corrupted entry", _PATH_MASTERPASSWD);
                        pw_error(NULL, 0, 1);
@@ -87,19 +106,36 @@ pw_copy(ffd, tfd, pw)
                                goto err;
                        continue;
                }
-               (void)fprintf(to, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
-                   pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,
-                   pw->pw_class, pw->pw_change, pw->pw_expire, pw->pw_gecos,
-                   pw->pw_dir, pw->pw_shell);
+               (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 : "",
+                   pw->pw_fields & _PWF_GID ? gidstr : "",
+                   pw->pw_class,
+                   pw->pw_fields & _PWF_CHANGE ? chgstr : "",
+                   pw->pw_fields & _PWF_EXPIRE ? expstr : "",
+                   pw->pw_gecos, pw->pw_dir, pw->pw_shell);
                done = 1;
                if (ferror(to))
                        goto err;
        }
-       if (!done)
-               (void)fprintf(to, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
-                   pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,
-                   pw->pw_class, pw->pw_change, pw->pw_expire, pw->pw_gecos,
-                   pw->pw_dir, pw->pw_shell);
+       if (!done) {
+#ifdef YP
+       /* Ultra paranoid: shouldn't happen. */
+               if (getuid())  {
+                       warnx("%s: not found in %s -- permission denied",
+                                       pw->pw_name, _PATH_MASTERPASSWD);
+                       pw_error(NULL, 0, 1);
+               } else
+#endif /* YP */
+               (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 : "",
+                   pw->pw_fields & _PWF_GID ? gidstr : "",
+                   pw->pw_class,
+                   pw->pw_fields & _PWF_CHANGE ? chgstr : "",
+                   pw->pw_fields & _PWF_EXPIRE ? expstr : "",
+                   pw->pw_gecos, pw->pw_dir, pw->pw_shell);
+       }
 
        if (ferror(to))
 err:           pw_error(NULL, 1, 1);