]> git.cameronkatri.com Git - pw-darwin.git/blobdiff - pw/pw_user.c
Changes so the 'pw' command will allow '$' as the last character in a userid
[pw-darwin.git] / pw / pw_user.c
index c1bfd947f7dc366991bb4f19af65146d5ff8b1f2..a2d5e78dbbd5e33695ee67819b9a604106a50350 100644 (file)
@@ -67,7 +67,7 @@ static char    *pw_shellpolicy(struct userconf * cnf, struct cargs * args, char
 static char    *pw_password(struct userconf * cnf, struct cargs * args, char const * user);
 static char    *shell_path(char const * path, char *shells[], char *sh);
 static void     rmat(uid_t uid);
-static void    rmskey(char const * name);
+static void     rmopie(char const * name);
 
 /*-
  * -C config      configuration file
@@ -113,6 +113,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
        struct group   *grp;
        struct stat     st;
        char            line[_PASSWORD_LEN+1];
+       FILE           *fp;
 
        static struct passwd fakeuser =
        {
@@ -375,10 +376,10 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
 
                        if (!PWALTDIR()) {
                                /*
-                                * Remove skey record from /etc/skeykeys
+                                * Remove opie record from /etc/opiekeys
                                 */
 
-                               rmskey(pwd->pw_name);
+                               rmopie(pwd->pw_name);
 
                                /*
                                 * Remove crontabs
@@ -719,7 +720,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
                errx(EX_NOUSER, "user '%s' disappeared during update", a_name->val);
 
        grp = GETGRGID(pwd->pw_gid);
-       pw_log(cnf, mode, W_USER, "%s(%ld):%s(%d):%s:%s:%s",
+       pw_log(cnf, mode, W_USER, "%s(%ld):%s(%ld):%s:%s:%s",
               pwd->pw_name, (long) pwd->pw_uid,
            grp ? grp->gr_name : "unknown", (long) (grp ? grp->gr_gid : -1),
               pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell);
@@ -730,39 +731,16 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
         * doesn't hurt anything to create the empty mailfile
         */
        if (mode == M_ADD) {
-               FILE           *fp;
-
                if (!PWALTDIR()) {
                        sprintf(line, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
                        close(open(line, O_RDWR | O_CREAT, 0600));      /* Preserve contents &
                                                                         * mtime */
                        chown(line, pwd->pw_uid, pwd->pw_gid);
-
-                       /*
-                        * Send mail to the new user as well, if we are asked to
-                        */
-                       if (cnf->newmail && *cnf->newmail && (fp = fopen(cnf->newmail, "r")) != NULL) {
-                               FILE           *pfp = popen(_PATH_SENDMAIL " -t", "w");
-
-                               if (pfp == NULL)
-                                       warn("sendmail");
-                               else {
-                                       fprintf(pfp, "From: root\n" "To: %s\n" "Subject: Welcome!\n\n", pwd->pw_name);
-                                       while (fgets(line, sizeof(line), fp) != NULL) {
-                                               /* Do substitutions? */
-                                               fputs(line, pfp);
-                                       }
-                                       pclose(pfp);
-                                       pw_log(cnf, mode, W_USER, "%s(%ld) new user mail sent",
-                                              pwd->pw_name, (long) pwd->pw_uid);
-                               }
-                               fclose(fp);
-                       }
                }
        }
 
        /*
-        * Finally, let's create and populate the user's home directory. Note
+        * Let's create and populate the user's home directory. Note
         * that this also `works' for editing users if -m is used, but
         * existing files will *not* be overwritten.
         */
@@ -772,6 +750,28 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args)
                       pwd->pw_name, (long) pwd->pw_uid, pwd->pw_dir);
        }
 
+
+       /*
+        * Finally, send mail to the new user as well, if we are asked to
+        */
+       if (mode == M_ADD && !PWALTDIR() && cnf->newmail && *cnf->newmail && (fp = fopen(cnf->newmail, "r")) != NULL) {
+               FILE           *pfp = popen(_PATH_SENDMAIL " -t", "w");
+               
+               if (pfp == NULL)
+                       warn("sendmail");
+               else {
+                       fprintf(pfp, "From: root\n" "To: %s\n" "Subject: Welcome!\n\n", pwd->pw_name);
+                       while (fgets(line, sizeof(line), fp) != NULL) {
+                               /* Do substitutions? */
+                               fputs(line, pfp);
+                       }
+                       pclose(pfp);
+                       pw_log(cnf, mode, W_USER, "%s(%ld) new user mail sent",
+                           pwd->pw_name, (long) pwd->pw_uid);
+               }
+               fclose(fp);
+       }
+
        return EXIT_SUCCESS;
 }
 
@@ -1194,21 +1194,58 @@ print_user(struct passwd * pwd, int pretty, int v7)
 char    *
 pw_checkname(u_char *name, int gecos)
 {
-       int             l = 0;
-       char const     *notch = gecos ? ":!@" : " ,\t:+&#%$^()!@~*?<>=|\\/\"";
-
-       while (name[l]) {
-               if (strchr(notch, name[l]) != NULL || name[l] < ' ' || name[l] == 127 ||
-                       (!gecos && l==0 && name[l] == '-') ||   /* leading '-' */
-                       (!gecos && name[l] & 0x80))     /* 8-bit */
-                       errx(EX_DATAERR, (name[l] >= ' ' && name[l] < 127)
-                                           ? "invalid character `%c' in field"
-                                           : "invalid character 0x%02x in field",
-                                           name[l]);
-               ++l;
+       char showch[8];
+       u_char const *badchars, *ch, *showtype;
+       int reject;
+
+       ch = name;
+       reject = 0;
+       if (gecos) {
+               /* See if the name is valid as a gecos (comment) field. */
+               badchars = ":!@";
+               showtype = "gecos field";
+       } else {
+               /* See if the name is valid as a userid or group. */
+               badchars = " ,\t:+&#%$^()!@~*?<>=|\\/\"";
+               showtype = "userid/group name";
+               /* Userids and groups can not have a leading '-'. */
+               if (*ch == '-')
+                       reject = 1;
+       }
+       if (!reject) {
+               while (*ch) {
+                       if (strchr(badchars, *ch) != NULL || *ch < ' ' ||
+                           *ch == 127) {
+                               reject = 1;
+                               break;
+                       }
+                       /* 8-bit characters are only allowed in GECOS fields */
+                       if (!gecos && (*ch & 0x80)) {
+                               reject = 1;
+                               break;
+                       }
+                       ch++;
+               }
+       }
+       /*
+        * A `$' is allowed as the final character for userids and groups,
+        * mainly for the benefit of samba.
+        */
+       if (reject && !gecos) {
+               if (*ch == '$' && *(ch + 1) == '\0') {
+                       reject = 0;
+                       ch++;
+               }
+       }
+       if (reject) {
+               snprintf(showch, sizeof(showch), (*ch >= ' ' && *ch < 127)
+                   ? "`%c'" : "0x%02x", *ch);
+               errx(EX_DATAERR, "invalid character %s at position %d in %s",
+                   showch, (ch - name), showtype);
        }
-       if (!gecos && l > LOGNAMESIZE)
-               errx(EX_DATAERR, "name too long `%s'", name);
+       if (!gecos && (ch - name) > LOGNAMESIZE)
+               errx(EX_DATAERR, "name too long `%s' (max is %d)", name,
+                   LOGNAMESIZE);
        return (char *)name;
 }
 
@@ -1239,10 +1276,10 @@ rmat(uid_t uid)
 }
 
 static void
-rmskey(char const * name)
+rmopie(char const * name)
 {
-       static const char etcskey[] = "/etc/skeykeys";
-       FILE   *fp = fopen(etcskey, "r+");
+       static const char etcopie[] = "/etc/opiekeys";
+       FILE   *fp = fopen(etcopie, "r+");
 
        if (fp != NULL) {
                char    tmp[1024];