chiark / gitweb /
Merge branch 'zealot'
[userv-utils.git] / groupmanage / groupmanage
index 19416062e27e5d96011fd228978d8ab0ff060f79..21a7327c76da7f544ab9daa3aec6cc476c1fd794 100755 (executable)
@@ -1,6 +1,11 @@
 #!/usr/bin/perl
 #
-# Copyright (C)1995-9 Ian Jackson <ijackson@chiark.greenend.org.uk>
+# Copyright (C) 1995-9, 2003 Ian Jackson <ijackson@chiark.greenend.org.uk>
+# Copyright (C) 1999, 2003
+#   Chancellor Masters and Scholars of the University of Cambridge
+#
+# Improved by Ben Harris <bjh21@cam.ac.uk> in 1999 and 2003 for Unix
+# Support's own nefarious purposes.
 #
 # This is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -55,16 +60,6 @@ $groupname =~ m/^\w[-0-9A-Za-z]*$/ ||
 
 @ARGV || push(@ARGV,'--info');
 
-if ($ARGV[0] eq '--info') {
-    @ARGV == 1 || &usage('no arguments allowed after --info');
-    &p_out;
-    &load;
-    &checkexists;
-    &display;
-    &p_out;
-    exit(0);
-}
-
 $callinguser= exists $ENV{'USERV_UID'} ? $ENV{'USERV_UID'} : $<;
 
 %opt= ('user-create','0',
@@ -72,13 +67,27 @@ $callinguser= exists $ENV{'USERV_UID'} ? $ENV{'USERV_UID'} : $<;
        'user-create-min','10000',
        'user-create-max','19999',
        'user-create-nameintitle','0',
-       'user-create-maxperu','5');
+       'user-create-maxperu','5',
+       'group-file','group',
+       'gtmp-file','gtmp',
+       'grouplist-file','grouplist',
+       'name-regexp','',
+       'name-maxlen','8',
+       'admin-group','',
+       'finish-command','');
 %ovalid=  ('user-create','boolean',
            'user-create-minunameu','number',
            'user-create-min','number',
            'user-create-max','number',
            'user-create-nameintitle','boolean',
-           'user-create-maxperu','number');
+           'user-create-maxperu','number',
+           'group-file','string',
+           'gtmp-file','string',
+           'grouplist-file','string',
+           'name-regexp','string',
+           'name-maxlen','number',
+           'admin-group','string',
+           'finish-command','string');
 
 sub ov_boolean {
     $cov= $_ eq 'yes' ? 1 :
@@ -90,6 +99,10 @@ sub ov_number {
     m/^[0-9]{1,10}$/ || &quit("groupmanage.conf:$.: bad numerical value");
 }
 
+sub ov_string {
+
+}
+
 open(GMC,"groupmanage.conf") || &quit("read groupmanage.conf: $!");
 while (<GMC>) {
     next if m/^\#/ || !m/\S/;
@@ -104,32 +117,55 @@ while (<GMC>) {
 }
 close(GMC);
 
+if ($ARGV[0] eq '--info') {
+    @ARGV == 1 || &usage('no arguments allowed after --info');
+    &p_out;
+    &load;
+    &checkexists;
+    &display;
+    &p_out;
+    exit(0);
+}
+
 sub naming {
     $callinguser || return;
     &p_out;
-    print(STDERR <<END) || &quit("write err re name: $!");
+    if ($opt{'user-create-minunameu'}) {
+       print(STDERR <<END) || &quit("write err re name: $!");
 groupmanage: groups you create must be named after you ...
     <usernamepart>-<identifier>
  You must quote at least $opt{'user-create-minunameu'} chars of your username $createby
  (or all of it if it is shorter).
 END
+    }
+    if ($opt{'name-regexp'}) {
+       print(STDERR <<END) || &quit("write err re name: $!");
+groupmanage: groups you create must match a pattern...
+  The pattern is the Perl regular expression /$opt{'name-regexp'}/.
+END
+    }
     exit(1);
 }
 
 if ($ARGV[0] eq '--create') {
     $opt{'user-create'} || !$callinguser ||
         &quit("group creation by users disabled by administrator");
-    length($groupname) <= 8 || &quit("group names must be 8 chars or fewer");
-    $groupname =~ m/^([-0-9A-Za-z]+)-([0-9a-z]+)$/ || &naming;
-    $upart= $1;
-    $idpart= $2;
+    length($groupname) <= $opt{'name-maxlen'} ||
+        &quit("group names must be $opt{'name-maxlen'} chars or fewer");
     $!=0; (@pw= getpwuid($callinguser))
        || &quit("cannot get your passwd entry: $!");
     $createby= $pw[0];
-    $upart eq $createby ||
-        (length($upart) >= $opt{'user-create-minunameu'} &&
-         substr($createby,0,length($upart)) eq $upart)
-            || &naming;
+    if ($opt{'user-create-minunameu'}) {
+       $groupname =~ m/^([-0-9A-Za-z]+)-([0-9a-z]+)$/ || &naming;
+       $upart= $1;
+       $idpart= $2;
+       $upart eq $createby ||
+           (length($upart) >= $opt{'user-create-minunameu'} &&
+            substr($createby,0,length($upart)) eq $upart)
+               || &naming;
+    } else {
+       $groupname =~ m/${opt{'name-regexp'}}/ || &naming;
+    }
     $create= 1;
     shift(@ARGV);
 }
@@ -194,7 +230,7 @@ while (@ARGV) {
     } elsif (m/^\w[-0-9A-Za-z]*$/) {
         y/\n//d;
         $chgu=$_;
-        getpwnam($chgu) || &quit("username $chgu does not exist");
+        defined(getpwnam($chgu)) || &quit("username $chgu does not exist");
         eval "\@l = \@$clist; 1" || &quit("internal error: $@");
         $already= grep($_ eq $chgu, @l);
         if ($action eq 'add') {
@@ -227,14 +263,17 @@ $groupfile[$groupfileix]=
     "$groupname:$password:$gid:".join(',',@members)."\n";
 $grouplist[$grouplistix]=
     "$groupname:$description:$owner:".join(',',@managers).":$homedir\n";
-&save('group',@groupfile);
-&save('grouplist',@grouplist);
-unlink('gtmp') || &quit("unlock group (remove gtmp): $!");
+&save($opt{'group-file'},@groupfile);
+&save($opt{'grouplist-file'},@grouplist);
+if ($opt{'finish-command'}) {
+    !system($opt{'finish-command'}) || &quit("finish-command: $?");
+}
+unlink($opt{'gtmp-file'}) || &quit("unlock group (remove gtmp): $!");
 &p_out;
 exit(0);
 
 sub load {
-    open(GF,"< group") || &quit("read group: $!");
+    open(GF,"< $opt{'group-file'}") || &quit("read group: $!");
     @groupfile=<GF>; close(GF);
     $groupfileix=-1;
     for ($i=0; $i<=$#groupfile; $i++) {
@@ -250,7 +289,7 @@ sub load {
         $gid= $3;
         @members= split(/,/,$4);
     }
-    open(GL,"< grouplist") || &quit("read grouplist: $!");
+    open(GL,"< $opt{'grouplist-file'}") || &quit("read grouplist: $!");
     @grouplist=<GL>; close(GL);
     $grouplistix=-1;
     for ($i=0; $i<=$#grouplist; $i++) {
@@ -299,14 +338,14 @@ sub quit {
 }
 
 sub lock {
-    link('group','gtmp') || &quit("create gtmp: $!");
+    link($opt{'group-file'},$opt{'gtmp-file'}) || &quit("create gtmp: $!");
     $locked++;
 }
 
 sub unlock {
     return unless $locked;
     $locked--;
-    unlink('gtmp') || warn("unlock group file (remove gtmp): $!\n");
+    unlink($opt{'gtmp-file'}) || warn("unlock group file (remove gtmp): $!\n");
 }
 
 sub display {