changeset 1500:cf77c4939385 draft

The only illegal characters in a username are ":" (field separator), "\n" (line separator), and "/" (filename separator). Restricting usernames to the legacy posix character allowed set (for filenames, so the $HOME directory is creatable on VFAT and similar) means you can't have UTF-8 usernames. Linux allows any character but / and NUL in filenames. Since root is creating these entries, we assume root knows what it's doing.
author Rob Landley <rob@landley.net>
date Fri, 26 Sep 2014 18:49:44 -0500
parents 319e79bab052
children c51a4dbe5db7
files lib/password.c lib/pending.h toys/pending/groupadd.c toys/pending/useradd.c
diffstat 4 files changed, 8 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/lib/password.c	Fri Sep 26 18:42:23 2014 -0500
+++ b/lib/password.c	Fri Sep 26 18:49:44 2014 -0500
@@ -19,11 +19,7 @@
       int len = al[i].len;
       char *s = salt;
 
-      if (al[i].id) {
-        *s++ = '$';
-        *s++ = '0'+al[i].id;
-        *s++ = '$';
-      }
+      if (al[i].id) s += sprintf(s, "$%c$", '0'+al[i].id);
 
       // Read appropriate number of random bytes for salt
       i = xopen("/dev/urandom", O_RDONLY);
@@ -233,29 +229,3 @@
   free(filenamesfx);
   return ret;
 }
-
-void is_valid_username(const char *name)                                                                                              
-{
-  regex_t rp;
-  regmatch_t rm[1]; 
-  int eval;
-  char *regex = "^[_.A-Za-z0-9][-_.A-Za-z0-9]*"; //User name REGEX
-
-  xregcomp(&rp, regex, REG_NEWLINE);
-
-  /* compare string against pattern --  remember that patterns 
-     are anchored to the beginning of the line */
-  eval = regexec(&rp, name, 1, rm, 0);
-  regfree(&rp);
-  if (!eval && !rm[0].rm_so) {
-    int len = strlen(name);
-    if ((rm[0].rm_eo == len) ||
-        (rm[0].rm_eo == len - 1 && name[len - 1] == '$')) {
-      if (len >= LOGIN_NAME_MAX) error_exit("name is too long");
-      else return;
-    }
-  }
-  error_exit("'%s', not valid %sname",name,
-      (((toys.which->name[3] == 'g') || 
-        (toys.which->name[0] == 'g'))? "group" : "user"));
-}
--- a/lib/pending.h	Fri Sep 26 18:42:23 2014 -0500
+++ b/lib/pending.h	Fri Sep 26 18:49:44 2014 -0500
@@ -2,6 +2,5 @@
 
 // password.c
 #define MAX_SALT_LEN  20 //3 for id, 16 for key, 1 for '\0'
-void is_valid_username(const char *name);
 int read_password(char * buff, int buflen, char* mesg);
 int update_password(char *filename, char* username, char* encrypted);
--- a/toys/pending/groupadd.c	Fri Sep 26 18:42:23 2014 -0500
+++ b/toys/pending/groupadd.c	Fri Sep 26 18:49:44 2014 -0500
@@ -92,11 +92,12 @@
     update_password(SECURE_GROUP_PATH, grp->gr_name, entry);
     free(entry);
   } else {    //new group to be created
+    char *s = *toys.optargs;
+
     /* investigate the group to be created */
-    if ((grp = getgrnam(*toys.optargs))) 
-      error_exit("group '%s' is in use", *toys.optargs);
-    setlocale(LC_ALL, "C");
-    is_valid_username(*toys.optargs);
+    if (getgrnam(s)) error_exit("'%s' in use", s);
+    if (s[strcspn(s, ":/\n")] || strlen(s) > LOGIN_NAME_MAX)
+      error_exit("bad name");
     new_group();
   }
 }
--- a/toys/pending/useradd.c	Fri Sep 26 18:42:23 2014 -0500
+++ b/toys/pending/useradd.c	Fri Sep 26 18:49:44 2014 -0500
@@ -54,8 +54,8 @@
   }
 
   // Sanity check user to add
-  if (strchr(s, ':') || strchr(s, '/') || strlen(s) > LOGIN_NAME_MAX)
-    error_exit("bad name");
+  if (s[strcspn(s, ":/\n")] || strlen(s) > LOGIN_NAME_MAX)
+    error_exit("bad username");
   // race condition: two adds at same time?
   if (getpwnam(s)) error_exit("'%s' in use", s);