home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / unix / armlinux / alpha / PARTITIONS / USR_GZ / usr / sbin / addgroup next >
Encoding:
Text File  |  1995-06-09  |  7.3 KB  |  263 lines

  1. #!/usr/bin/perl
  2. #
  3. # addgroup: a utility to add groups to the system
  4. #     $Id: addgroup,v 0.10 1995/03/02 03:24:38 tedhajek Exp $    
  5.  
  6. #
  7. # Copyright (C) 1995 Ted Hajek <tedhajek@boombox.micro.umn.edu>
  8. # General scheme of the program adapted by the debian 'adduser'
  9. #  program by Ian A. Murdock <imurdock@gnu.ai.mit.edu>.
  10. #
  11. #    This program is free software; you can redistribute it and/or modify
  12. #    it under the terms of the GNU General Public License as published by
  13. #    the Free Software Foundation; either version 2 of the License, or
  14. #    (at your option) any later version.
  15. #
  16. #    This program is distributed in the hope that it will be useful,
  17. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. #    GNU General Public License for more details.
  20. #
  21. #    You should have received a copy of the GNU General Public License
  22. #    along with this program; if not, write to the Free Software
  23. #    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24. #
  25. # NOTE: addgroup should be used to add system, maintenance and
  26. #       project groups to the system.
  27. #
  28. #       By default, the debian 'adduser' program creates
  29. #       a group for each created user; this group has the same
  30. #       ID number as the associated user.
  31. #
  32. #       Therefore, we shouldn't create any groups with GID equal
  33. #       to or greater than the lowest UID used by adduser.
  34. #       This is given in the file /etc/adduser.conf in an entry
  35. #       such as "FIRST_UID=1000"
  36. #
  37. #       Furthermore, the first 99 GIDs are reserved for the base
  38. #       system maintainer.  Therefore, we should add groups with
  39. #       GIDs greater than or equal to 100.
  40. #
  41. #       If there is no available GID under FIRST_UID, exit with
  42. #       a suitable error message.
  43. #
  44. ##
  45. ## TODO
  46. ##
  47. # - allow users belonging to group to be specified on command line?
  48.  
  49.  
  50. # are we debugging?
  51. $debugging = 0;
  52.  
  53. ##
  54. ## need to trap signals 1 2 3 and 15 here so user can't kill us
  55. ## when things are in some half-baked state.
  56. ##
  57.  
  58. # Set up some important things:
  59. $GROUP = "/etc/group";        # the group file
  60. $GBACK = "/etc/group~";        # the backup group file
  61. $GLOCK = "/etc/gtmp";        # the lock file
  62.                                 # I don't know if this is standard,
  63.                 # but it should be :-)
  64.                 # I'll work out a better locking scheme
  65.                 # later.
  66. $DEFAULTS = "/etc/adduser.conf";
  67. $default_first_uid = 1000;    # value to use if we can't find one
  68.                 # specified in the adduser.conf file
  69. $MIN_GID = 100;            # leave some room for system stuff
  70.  
  71. ##
  72. ## check if certain conditions are met before we start
  73. ## plodding around within the group file.
  74. ##
  75.  
  76. # we must be root.
  77. if ($> != 0) {
  78.     print "$0: only root may add groups to the system.\n";
  79.     exit 1;
  80. }
  81. # the user must specify a group name to add
  82. $group_name = shift(@ARGV);
  83. print STDOUT "$group_name\n" if $debugging;
  84. if (! $group_name) {
  85.     print "$0: you must specify a group name to be added.\n";
  86.     print "For example, '$0 junk-maintainers'.\n";
  87.     exit 1;
  88. }
  89. # check if the group to be added already exists
  90. if (&group_exists($group_name)) {
  91.     print "$0: the group you specified already exists.\n";
  92.     exit 1;
  93. }
  94. # check if the group file is locked by some other process
  95. if (-f $GLOCK) {
  96.     print "$0: $GROUP is locked.  Try again later.\n";
  97.     exit 1;
  98. }
  99.  
  100. ##
  101. ## lock the group file
  102. ##
  103. link $GROUP, $GLOCK;
  104.  
  105. # read the file of defaults.
  106. $first_uid = &get_first_uid($DEFAULTS, $default_first_uid);
  107.  
  108. # suck the existing GIDs into an array
  109. @current_gids = &get_current_gids;
  110. # sort 'dem GIDs
  111. @sorted_gids = sort {$a <=> $b} @current_gids;
  112. # find the first available GID
  113. $last_one = shift(@sorted_gids);
  114. while ($this_one = shift(@sorted_gids)) {
  115.     if ($this_one <= $MIN_GID) {
  116.     $last_one = $this_one; # advance if we're under $MIN_GID
  117.     next;
  118.     }
  119.     if ($this_one > $last_one + 1) {
  120.     $lowest_available = $last_one + 1;
  121.     last;
  122.     } else {
  123.     $last_one = $this_one;
  124.     }
  125. }
  126. # if we haven't yet set $lowest_available, there's no hole.
  127. $lowest_available = ($last_one + 1) if (! $lowest_available);
  128. # make sure we're at the minimum.
  129. $lowest_available = $MIN_GID if ($lowest_available < $MIN_GID);
  130.  
  131. # make sure that we're below the ceiling
  132. if ($lowest_available >= $first_uid) {
  133.     print "$0: no GID available beneath first normal user's ID.\n";
  134.     exit 1;
  135. }
  136.  
  137. # save the original group file
  138. open (GBACK, ">$GBACK") || die "open: $!";
  139. open (GROUP, "$GROUP") || die "open: $!";
  140. while (<GROUP>) {
  141.     print GBACK;
  142. }
  143. close GROUP;
  144. close GBACK;
  145.  
  146. # write the new entry at the appropriate place in the group file
  147. open (GROUP, ">$GROUP") || die "open: $!";
  148. open (GBACK, "$GBACK") || die "open: $!";
  149. $added_new_one = 0;
  150. while($line = <GBACK>) {
  151.     chop $line;
  152.     ($name, $passwd, $gid, $members) = split(/:/, $line);
  153.     if ($gid < $lowest_available || $added_new_one) {
  154.     print GROUP $line, "\n";
  155.     print STDOUT "GID: $gid\n" if $debugging;
  156.     } else {            # we haven't added the new one yet
  157.     print GROUP "${group_name}::${lowest_available}:\n";
  158.     $added_new_one = 1;
  159.     print STDOUT "Just added new one\n" if $debugging;
  160.     print GROUP $line, "\n";
  161.     print STDOUT "GID: $gid\n" if $debugging;
  162.     }
  163. }
  164. print GROUP "${group_name}::${lowest_available}:\n" if (! $added_new_one);
  165.  
  166. close GROUP;
  167. close GBACK;
  168.  
  169. # we're done!  Unlock the group file
  170. unlink $GLOCK;
  171. print "done.\n";
  172. exit 0;
  173.  
  174. ###################################################
  175. #=================================================#
  176. ###################################################
  177.  
  178. ###
  179. ### Subroutines
  180. ###
  181.  
  182. ############################
  183. # get_current_gids
  184. ############################
  185. # iterate through the group file; return an array
  186. # containing all the GIDs
  187. sub get_current_gids {
  188.     local (@gids);
  189.     local ($name, $passwd, $gid, $members); # the return values of "getgrent";
  190.  
  191.     setgrent;
  192.     while (($name, $passwd, $gid, $members) = getgrent) {
  193.     push @gids, $gid;
  194.     }
  195.     endgrent;
  196.  
  197.     return @gids;
  198. }
  199.  
  200. ############################
  201. # get_first_uid
  202. ############################
  203. # parse the defaults file for the first user UID number.
  204. # if the default file or entry doesn't exist, return the
  205. # SYSTEM default value given in 'adduser'.
  206. sub get_first_uid {
  207.     local($conf_file, $default) = @_;
  208.     local($current_line, $tag, $uid);
  209.  
  210.     # if there's not a config file, return the default.
  211.     print "Couldn't find $conf_file\n" if ($debugging && (! -f $conf_file));
  212.     return $default if (! -f $conf_file);
  213.  
  214.     open (CONF, $conf_file) || die "open: $!";
  215.     while ($current_line = <CONF>) {
  216.     chop $current_line;
  217.     if ($current_line =~ /^FIRST_UID=(\d+)$/) {
  218.         $uid = $1;
  219.         last;
  220.     }
  221.     }
  222.     close (CONF);
  223.  
  224.     print "Got UID = $uid from $conf_file\n" if ($uid && $debugging);
  225.     return $uid if ($uid);
  226.     print "Using default UID = $default\n" if $debugging;
  227.     return $default;
  228. }
  229.  
  230.  
  231.  
  232. #############################
  233. # group_exists
  234. #############################
  235. # takes a group name as an argument.  If the group already exists,
  236. # return 1.  If it doesn't, return 0.
  237. sub group_exists {
  238.     local ($group_name) = @_;
  239.     local ($exists);        # does group exist?
  240.     local ($name, $passwd, $gid, $members); # the return values of "getgrent";
  241.  
  242.     $exists = 0;
  243.     # reset the group lookup function
  244.     setgrent;
  245.     # iterate through the group file.  If the group exists, return 1.
  246.     while (($name, $passwd, $gid, $members) = getgrent) {
  247.     if ($name eq $group_name) {
  248.         $exists = 1;
  249.         last;
  250.     }
  251.     }
  252.     # close the group file
  253.     endgrent;
  254.  
  255.     return $exists;
  256. }
  257.  
  258.  
  259.  
  260.  
  261.  
  262.