chiark / gitweb /
Add debhelper token to postinst scripts.
[userv-utils.git] / groupmanage / groupmanage
index 48e7077ab34a9a0a87737b987bbb53743bddadfc..24c007b72858b84656fc7349fa957af0f26bfffd 100755 (executable)
@@ -1,22 +1,23 @@
 #!/usr/bin/perl
 #
-# Reads /etc/grouplist, in form
-# group:description:owner:manager1,manager2,manager3:home-directory
-# (as many or few managers as you like)
-# Modifies /etc/grouplist by adding or removing managers &c,
-# and /etc/group by adding or removing members.
-
-# Copyright (C)1995-8 Ian Jackson <ijackson@chiark.greenend.org.uk>
-
+# Copyright 1996-2013 Ian Jackson <ijackson@chiark.greenend.org.uk>
+# Copyright 1998 David Damerell <damerell@chiark.greenend.org.uk>
+# Copyright 1999,2003
+#    Chancellor Masters and Scholars of the University of Cambridge
+# Copyright 2010 Tony Finch <fanf@dotat.at>
+#
 # This is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# It is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with userv-utils; if not, see http://www.gnu.org/licenses/.
 
 sub usage {
     &unlock;
@@ -36,6 +37,8 @@ groupmanage: $_[0]
        --manager-remove <username> <username> ...
        --title <string>
        --owner <username>  [root only]
+groupmanage is Copyright.  It is free software, released under the GNU
+GPL v2 or later.  There is NO WARRANTY.  See the GPL for details.
 END
     exit(1);
 }
@@ -57,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',
@@ -74,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 :
@@ -92,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/;
@@ -106,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);
 }
@@ -196,7 +230,7 @@ while (@ARGV) {
     } elsif (m/^\w[-0-9A-Za-z]*$/) {
         y/\n//d;
         $chgu=$_;
-        (@pw= 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') {
@@ -229,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++) {
@@ -252,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++) {
@@ -301,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 {