[csw-devel] SF.net SVN: gar:[8957] csw/mgar/pkg/cswclassutils/trunk/files/ CSWcswclassutils.i.cswusergroup

skayser at users.sourceforge.net skayser at users.sourceforge.net
Wed Mar 3 22:41:41 CET 2010


Revision: 8957
          http://gar.svn.sourceforge.net/gar/?rev=8957&view=rev
Author:   skayser
Date:     2010-03-03 21:41:32 +0000 (Wed, 03 Mar 2010)

Log Message:
-----------
i.cswusergroup: added configurable UID/GID range via csw.conf

Modified Paths:
--------------
    csw/mgar/pkg/cswclassutils/trunk/files/CSWcswclassutils.i.cswusergroup

Property Changed:
----------------
    csw/mgar/pkg/cswclassutils/trunk/files/CSWcswclassutils.i.cswusergroup

Modified: csw/mgar/pkg/cswclassutils/trunk/files/CSWcswclassutils.i.cswusergroup
===================================================================
--- csw/mgar/pkg/cswclassutils/trunk/files/CSWcswclassutils.i.cswusergroup	2010-03-03 21:02:49 UTC (rev 8956)
+++ csw/mgar/pkg/cswclassutils/trunk/files/CSWcswclassutils.i.cswusergroup	2010-03-03 21:41:32 UTC (rev 8957)
@@ -9,25 +9,238 @@
 # 2009-02-10 First release
 #
 # Documentation: http://wiki.opencsw.org/cswclassutils-package
+#
+# Known issues:
+# ! calls to useradd, groupadd, and getent are not PKG_INSTALL_ROOT aware,
+#   but CAS via -R are flawed anyway. See:
+#   http://wiki.opencsw.org/cswclassutils-package#toc5
+# ! path to /etc/shadow in set_user_nologin() are not PKG_INSTALL_ROOT aware
+#
 
-DEBUG=		# clear to disable debug, set to anything to enable
+# Safety measure during coding, bail out on access of unset variables
+set -u
 
-if [ "$DEBUG" ]; then
-  echo PACKAGE: $PKGINST
+# Set DEBUG to anything via environment to display debugging messages
+DEBUG=${DEBUG:-}
+
+# Avoid unset errors for variables which are usually unset during CLI tests
+PKGINST=${PKGINST:-}
+PKG_INSTALL_ROOT=${PKG_INSTALL_ROOT:-}
+
+UID_MIN_DEFAULT=100
+UID_MAX_DEFAULT=999
+GID_MIN_DEFAULT=100
+GID_MAX_DEFAULT=999
+
+# Retrieve min/max UID/GID settings from csw.conf. Use usergroup_ variables
+# to be naming-consistant with the already existing usergroup_remove variable.
+# See http://www.opencsw.org/mantis/view.php?id=3637
+#
+# Internally, we use shorter var names which makes it IMHO easier to
+# code (particularly WRT to 80 chars width) and read the code, but it's a bit
+# of a PITA at the same time. Thoughts?
+
+if [ -f $PKG_INSTALL_ROOT/opt/csw/etc/csw.conf ] ; then
+  . $PKG_INSTALL_ROOT/opt/csw/etc/csw.conf
 fi
+if [ -f $PKG_INSTALL_ROOT/etc/opt/csw/csw.conf ] ; then
+  . $PKG_INSTALL_ROOT/etc/opt/csw/csw.conf
+fi
 
+UID_MIN_CFGNAME=usergroup_uid_low
+UID_MAX_CFGNAME=usergroup_uid_high
+GID_MIN_CFGNAME=usergroup_gid_low
+GID_MAX_CFGNAME=usergroup_gid_high
+
+UID_MIN=`eval echo \$\{$UID_MIN_CFGNAME:-$UID_MIN_DEFAULT}`
+UID_MAX=`eval echo \$\{$UID_MAX_CFGNAME:-$UID_MAX_DEFAULT}`
+GID_MIN=`eval echo \$\{$GID_MIN_CFGNAME:-$GID_MIN_DEFAULT}`
+GID_MAX=`eval echo \$\{$GID_MAX_CFGNAME:-$GID_MAX_DEFAULT}`
+
+# Functions
+
+exit_error() {
+  echo "ERROR: $*" >&2
+  exit 1
+}
+
+debug_echo() {
+  [ -n "$DEBUG" ] && echo "DEBUG: $*" >&2
+}
+
+is_numeric() {
+  case "$1" in *[!0-9]*) return 1;; esac
+  [ -z "$1" ] && return 1
+  return 0
+}
+
+# Return the first available UID where UID_MIN <= UID <= UID_MAX.
+# Return -1 if no UID is available. Done in two steps:
+# 1) One getent call -> store all occupied UIDs from the target range
+# 2) Iterate over the target range, return the first non-taken UID
+first_avail_uid() {
+  for uid in `/usr/bin/getent passwd | cut -d: -f3 | sort -n`
+  do
+    [ $uid -lt $UID_MIN ] && continue
+    [ $uid -gt $UID_MAX ] && break
+    eval UID_TAKEN_$uid=1
+  done
+
+  uid=$UID_MIN
+  while test $uid -le $UID_MAX
+  do
+    [ `eval echo \$\{UID_TAKEN_$uid:-0}` -eq 1 ] || { echo $uid; return; }
+    uid=`expr $uid + 1`
+  done
+  echo -1
+}
+
+# Same as first_avail_uid (see above) just for GIDs.
+first_avail_gid() {
+  for gid in `/usr/bin/getent group | cut -d: -f3 | sort -n`
+  do
+    [ $gid -lt $GID_MIN ] && continue
+    [ $gid -gt $GID_MAX ] && break
+    eval GID_TAKEN_$gid=1
+  done
+
+  gid=$GID_MIN
+  while test $gid -le $GID_MAX
+  do
+    [ `eval echo \$\{GID_TAKEN_$gid:-0}` -eq 1 ] || { echo $gid; return; }
+    gid=`expr $gid + 1`
+  done
+  echo -1
+}
+
+# Validate ID range configuration, ref. useradd(1m) and groupadd(1m) for sys
+# limit, currently defined by MAXUID in /usr/include/sys/param.h -> 2147483647
+
+is_numeric $UID_MIN || exit_error "$UID_MIN_CFGNAME is non-numeric ($UID_MIN)"
+is_numeric $UID_MAX || exit_error "$UID_MAX_CFGNAME is non-numeric ($UID_MAX)"
+is_numeric $GID_MIN || exit_error "$GID_MIN_CFGNAME is non-numeric ($GID_MIN)"
+is_numeric $GID_MAX || exit_error "$GID_MAX_CFGNAME is non-numeric ($GID_MAX)"
+
+test $UID_MIN -ge 0 \
+    -a $UID_MAX -le 2147483647 \
+    -a $UID_MIN -lt $UID_MAX \
+    -a $GID_MIN -ge 0 \
+    -a $GID_MAX -le 2147483647 \
+    -a $GID_MIN -lt $GID_MAX || \
+  exit_error "usergroup ID range settings are invalid
+
+Settings are
+  $UID_MIN_CFGNAME: $UID_MIN
+  $UID_MAX_CFGNAME: $UID_MAX
+  $GID_MIN_CFGNAME: $GID_MIN
+  $GID_MAX_CFGNAME: $GID_MAX
+
+Constraints are
+  $UID_MIN_CFGNAME and $GID_MIN_CFGNAME must be >0
+  $UID_MAX_CFGNAME and $GID_MAX_CFGNAME must be <2147483647
+  $UID_MIN_CFGNAME must be < $UID_MAX_CFGNAME
+  $GID_MIN_CFGNAME must be < $GID_MAX_CFGNAME
+"
+
+create_group() {
+
+  group="$1"
+
+  if /bin/getent group $group > /dev/null; then
+    echo Group $group already exists
+    return
+  fi
+
+  gid=`first_avail_gid`
+  [ "$gid" = "-1" ] && exit_error "Failed to determine GID for group $group"
+  is_numeric "$gid" || exit_error "Failed to determine GID for group $group"
+
+  debug_echo "/usr/sbin/groupadd -g $gid $group"
+  if /usr/sbin/groupadd -g $gid $group > /dev/null; then
+    echo Group $group has been added
+  else
+    exit_error "Failed to add group $group"
+  fi
+}
+
+create_user() {
+  user="$1"
+  group="$2"
+  gcos="$3"
+  dir="$4"
+  shell="$5"
+  create="$6" 
+
+  if getent passwd $user > /dev/null; then
+    echo User $user already exists
+    return
+  fi
+
+  uid=`first_avail_uid`
+  [ "$uid" = "-1" ] && exit_error "Failed to determine UID for user $user"
+  is_numeric "$uid" || exit_error "Failed to determine UID for user $user"
+
+  [ -n "$group" ] && group="-g $group"
+  [ -n "$gcos" ] && gcos="-c $gcos"
+  [ -n "$dir" ] && dir="-d $dir"
+  [ -n "$shell" ] && shell="-s $shell"
+  [ -n "$create" ] && create="-m"
+
+  debug_echo "/usr/sbin/useradd -g $uid $gcos $group $create $dir $shell $user"
+  if /usr/sbin/useradd \
+       -u $uid $gcos $group $create $dir $shell $user > /dev/null
+  then
+    echo User $user has been added
+  else
+    exit_error "Failed to add user $user"
+  fi
+}
+
+set_user_nologin() {
+  case "`uname -r`" in
+  5.8|5.9)
+    # for old solaris, we munge the shadow file manually.
+    omask=`umask`
+    umask 0377
+
+    awk 'BEGIN { FS=":"; OFS=":" } $1 == "'$user'" { $2 = "NP" } { print }' /etc/shadow > /etc/shadow.$PKGINST
+    if [ $? -ne 0 ]; then
+      rm /etc/shadow.$PKGINST
+      exit_error "Setting NP for '$user' failed."
+    fi
+
+    if cmp -s /etc/shadow /etc/shadow.$PKGINST; then
+      rm /etc/shadow.$PKGINST
+    else
+      echo "Updating account '$user' to be no-login (NP)"
+      chgrp sys /etc/shadow.$PKGINST
+      cp -p /etc/shadow /etc/shadow.CSW && \
+      mv /etc/shadow.$PKGINST /etc/shadow
+    fi
+	umask $omask
+  ;;
+  *)
+    # for modern solaris, use the built-in tools
+    if ! passwd -N $user; then
+      exit_error "Setting NP for '$user' failed."
+    fi
+  ;;
+  esac
+}
+
+debug_echo "PACKAGE: $PKGINST"
+
 # Copy files
 echo "Installing class <cswusergroup> ..."
 
 while read src dest; do
-  if [ "$DEBUG" ]; then
-    echo SRC: $src DEST: $dest
-  fi
+  debug_echo "SRC: $src DEST: $dest"
 
   # Copy the conf-file
   /usr/bin/cp $src $dest || exit 2
 
   for i in `cat $dest | sed 's/ /_/g'`; do
+
     user=`echo $i | awk -F':' '{print $1}'`
     group=`echo $i | awk -F':' '{print $2}'`
     gcos=`echo $i | awk -F':' '{print $3}'`
@@ -35,88 +248,21 @@
     shell=`echo $i | awk -F':' '{print $5}'`
     create=`echo $i | awk -F':' '{print $6}'`
     nopass=`echo $i | awk -F':' '{print $8}'`
+
     if [ -n "$group" ]; then
-      /bin/getent group $group > /dev/null
-      if [ $? -ne 0 ]; then
-        /usr/sbin/groupadd $group > /dev/null
-        if [ $? -eq 0 ]; then
-          echo Group $group has been added
-        else
-          echo ERROR: Failed to add group $group
-        fi
-      else
-        echo Group $group already exists
-      fi
+      create_group $group
     else
       echo No group to create
     fi
 
     if [ -n "$user" ]; then
-      /bin/getent passwd $user > /dev/null
-      if [ $? -ne 0 ]; then
-        if [ -n "$group" ]; then
-          group="-g $group"
-        fi
-        if [ -n "$gcos" ]; then
-          gcos="-c $gcos"
-        fi
-        if [ -n "$dir" ]; then
-          dir="-d $dir"
-        fi
-        if [ -n "$shell" ]; then
-          shell="-s $shell"
-        fi
-        if [ -n "$create" ]; then
-          create="-m"
-        fi
-        /usr/sbin/useradd $gcos $group $create $dir $shell $user > /dev/null
-        if [ $? -eq 0 ]; then
-          echo User $user has been added
-        else
-          echo ERROR: Failed to add user $user
-        fi
-      else
-        echo User $user already exists
-      fi
-
-      if [ -n "$nopass" ]; then
-	  case "`uname -r`" in
-	      5.8|5.9)
-		  # for old solaris, we munge the shadow file manually.
-		  omask=`umask`
-		  umask 0377
-		  awk 'BEGIN { FS=":"; OFS=":" } $1 == "'$user'" { $2 = "NP" } { print }' /etc/shadow > /etc/shadow.$PKGINST
-		  if [ $? -eq 0 ]; then
-		      cmp -s /etc/shadow /etc/shadow.$PKGINST
-		      if [ $? -ne 0 ]; then
-			  echo "Updating account '$user' to be no-login (NP)"
-			  chgrp sys /etc/shadow.$PKGINST
-			  cp -p /etc/shadow /etc/shadow.CSW && \
-			      mv /etc/shadow.$PKGINST /etc/shadow
-		      else
-			  rm /etc/shadow.$PKGINST
-		      fi
-		  else
-		      echo "ERROR: Setting NP for '$user' failed."
-		      rm /etc/shadow.$PKGINST
-		  fi
-		  umask $omask
-		  ;;
-	      *)
-		  # for modern solaris, use the built-in tools
-		  passwd -N $user
-		  if [ $? -ne 0 ]; then
-		      echo "ERROR: Setting NP for '$user' failed."
-		  fi
-		  ;;
-	      esac
-      fi
+      create_user "$user" "$group" "$gcos" "$dir" "$shell" "$create"
+      [ -n "$nopass" ] && set_user_nologin "$user"
     else
       echo No user to create
     fi
     echo
   done
-
 done
 
 exit 0


Property changes on: csw/mgar/pkg/cswclassutils/trunk/files/CSWcswclassutils.i.cswusergroup
___________________________________________________________________
Added: svn:mergeinfo
   + /csw/mgar/pkg/cswclassutils/branches/cswclassutils-usergroup-idrange/files/CSWcswclassutils.i.cswusergroup:8421-8956


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.


More information about the devel mailing list