]> git.cameronkatri.com Git - pw-darwin.git/blobdiff - adduser/adduser.perl
`pw useradd' could be used with -w without -D option.
[pw-darwin.git] / adduser / adduser.perl
index 58cffec03f6389dcd68e41e4bad034eabcc8ae5f..322bac6e254105b038df041876c037e4b1464f71 100644 (file)
@@ -30,6 +30,8 @@
 # read variables
 sub variables {
     $verbose = 1;              # verbose = [0-2]
+    $usernameregexp = "^[a-z0-9_][a-z0-9_-]*\$"; # configurable
+    $defaultusernameregexp = $usernameregexp; # remains constant
     $defaultusepassword = "yes";       # use password authentication for new users
     $defaultenableaccount = "yes"; # enable the account by default
     $defaultemptypassword = "no"; # don't create an empty password
@@ -44,7 +46,7 @@ sub variables {
     $etc_shells = "/etc/shells";
     $etc_passwd = "/etc/master.passwd";
     $group = "/etc/group";
-    $pwd_mkdb = "pwd_mkdb -p"; # program for building passwd database
+    @pwd_mkdb = qw(pwd_mkdb -p); # program for building passwd database
 
 
     # List of directories where shells located
@@ -226,7 +228,7 @@ sub home_partition_valid {
 
 # check for valid passwddb
 sub passwd_check {
-    system("$pwd_mkdb -C $etc_passwd");
+    system(@pwd_mkdb, '-C', $etc_passwd);
     die "\nInvalid $etc_passwd - cannot add any users!\n" if $?;
 }
 
@@ -235,7 +237,7 @@ sub passwd_read {
     local($p_username, $pw, $p_uid, $p_gid, $sh, %shlist);
 
     print "Check $etc_passwd\n" if $verbose;
-    open(P, "$etc_passwd") || die "$passwd: $!\n";
+    open(P, "$etc_passwd") || die "$etc_passwd: $!\n";
 
     while(<P>) {
        chop;
@@ -314,12 +316,8 @@ sub new_users_name {
     local($name);
 
     while(1) {
-       $name = &confirm_list("Enter username", 1, "a-z0-9_-", "");
-       if (length($name) > 16) {
-           warn "Username is longer than 16 chars\a\n";
-           next;
-       }
-       last if (&new_users_name_valid($name) eq $name);
+       $name = &confirm_list("Enter username", 1, $usernameregexp, "");
+       last if (&new_users_name_valid($name));
     }
     return $name;
 }
@@ -327,14 +325,29 @@ sub new_users_name {
 sub new_users_name_valid {
     local($name) = @_;
 
-    if ($name !~ /^[a-z0-9_][a-z0-9_\-]*$/ || $name eq "a-z0-9_-") {
-       warn "Wrong username. " .
-           "Please use only lowercase characters or digits\a\n";
+    if ($name eq $usernameregexp) { # user/admin just pressed <Return>
+       warn "Please enter a username\a\n";
+       return 0;
+    } elsif (length($name) > 16) {
+       warn "Username is longer than 16 characters.\a\n";
+       return 0;
+    } elsif ($name =~ /[:\n]/) {
+       warn "Username cannot contain colon or newline characters.\a\n";
+       return 0;
+    } elsif ($name !~ /$usernameregexp/) {
+       if ($usernameregexp eq $defaultusernameregexp) {
+           warn "Illegal username.\n" .
+               "Please use only lowercase Roman, decimal, underscore, " .
+               "or hyphen characters.\n" .
+               "Additionally, a username should not start with a hyphen.\a\n";
+       } else {
+           warn "Username doesn't match the regexp /$usernameregexp/\a\n";
+       }
        return 0;
-    } elsif ($username{$name}) {
+    } elsif (defined($username{$name})) {
        warn "Username ``$name'' already exists!\a\n"; return 0;
     }
-    return $name;
+    return 1;
 }
 
 # return full name
@@ -559,12 +572,13 @@ EOF
 
 # make password database
 sub new_users_pwdmkdb {
-    local($last) = @_;
+    local($last) = shift;
+    local($name) = shift;
 
-    system("$pwd_mkdb $etc_passwd");
+    system(@pwd_mkdb, '-u', $name, $etc_passwd);
     if ($?) {
        warn "$last\n";
-       warn "``$pwd_mkdb'' failed\n";
+       warn "``@pwd_mkdb'' failed\n";
        exit($? >> 8);
     }
 }
@@ -793,7 +807,7 @@ sub new_users {
            $new_entry = "$name\:" . "$cryptpwd" .
                "\:$u_id\:$g_id\:$class\:0:0:$fullname:$userhome:$sh";
            &append_file($etc_passwd, "$new_entry");
-           &new_users_pwdmkdb("$new_entry");
+           &new_users_pwdmkdb("$new_entry", $name);
            &new_users_group_update;
            &new_users_passwd_update;  print "Added user ``$name''\n";
            &new_users_sendmessage;
@@ -1047,9 +1061,9 @@ sub home_create {
     # copy files from  $dotdir to $homedir
     # rename 'dot.foo' files to '.foo'
     print "Copy files from $dotdir to $homedir\n" if $verbose;
-    system("cp -R $dotdir $homedir");
-    system("chmod -R u+wrX,go-w $homedir");
-    system("chown -R $name:$group $homedir");
+    system('cp', '-R', $dotdir, $homedir);
+    system('chmod', '-R', 'u+wrX,go-w', $homedir);
+    system('chown', '-Rh', "$name:$group", $homedir);
 
     # security
     opendir(D, $homedir);
@@ -1201,6 +1215,21 @@ sub confirm_yn {
     return 0;
 }
 
+# allow configuring usernameregexp
+sub usernameregexp_default {
+    local($r) = $usernameregexp;
+
+    while ($verbose) {
+       $r = &confirm_list("Usernames must match regular expression:", 1,
+           $r, "");
+       eval "'foo' =~ /$r/";
+       last unless $@;
+       warn "Invalid regular expression\a\n";
+    }
+    $changes++ if $r ne $usernameregexp;
+    return $r;
+}
+
 # test if $dotdir exist
 # return "no" if $dotdir not exist or dotfiles should not copied
 sub dotdir_default {
@@ -1416,6 +1445,10 @@ sub config_write {
 # verbose = [0-2]
 verbose = $verbose
 
+# regular expression usernames are checked against (see perlre(1))
+# usernameregexp = 'regexp'
+usernameregexp = '$usernameregexp'
+
 # use password-based authentication for new users
 # defaultusepassword =  "yes" | "no"
 defaultusepassword = "$defaultusepassword"
@@ -1500,6 +1533,7 @@ exit 0 if $check_only;            # only check consistence and exit
 
 # interactive
 # some questions
+$usernameregexp = &usernameregexp_default; # regexp to check usernames against
 &shells_add;                   # maybe add some new shells
 $defaultshell = &shell_default;        # enter default shell
 $home = &home_partition($home);        # find HOME partition