[Server-devel] [PATCH] Restrict XO users using rssh

Douglas Bagnall douglas at paradise.net.nz
Mon Aug 11 19:24:09 EDT 2008


    
    As per ticket #7606, until now XO users have had full shell access
    over ssh.  This (with related commits in ds-backup and xs-config),
    confines them to rsync over ssh only.
    
    The update_users.py script fixes existing users, while create_user
    will now set the shell of new users.
    
    The users' group is also set to "xousers", which will allow further
    restrictions in due course.

diff --git a/Makefile b/Makefile
index c87dd6f..59b425d 100644
--- a/Makefile
+++ b/Makefile
@@ -20,16 +20,17 @@ CREATE_REGISTRATION = create_registration
 LIST_REGISTRATION = list_registration
 IDMGR_INIT = idmgr
 IDMGR_CONFIG = idmgr.conf
+UPDATE_USERS = update_users.py
 # This is a directory (w. subdirectories)
 SERVER = idmgr/
 
 #  All scripts
 SRC_FILES = $(CONF_SRC)/$(CREATE_USER) $(CONF_SRC)/$(CREATE_REGISTRATION) \
 	$(CONF_SRC)/$(LIST_REGISTRATION) $(CONF_SRC)/$(IDMGR_INIT) \
-	$(CONF_SRC)/$(IDMGR_CONFIG)
+	$(CONF_SRC)/$(IDMGR_CONFIG) $(CONF_SRC)/$(UPDATE_USERS)
 FILES = $(BIN_DST)/$(CREATE_USER) $(BIN_DST)/$(CREATE_REGISTRATION) \
 	$(BIN_DST)/$(LIST_REGISTRATION) $(INIT_DST)/$(IDMGR_INIT) \
-	$(CONFIG_DST)/$(IDMGR_CONFIG)
+	$(CONFIG_DST)/$(IDMGR_CONFIG) $(BIN_DST)/$(UPDATE_USERS)
 
 # install rules
 $(DESTDIR):
@@ -47,6 +48,9 @@ $(CONFIG_DST): $(DESTDIR)
 $(BIN_DST)/$(CREATE_USER): $(CONF_SRC)/$(CREATE_USER) $(BIN_DST)
 	cp $(CONF_SRC)/$(CREATE_USER) $(BIN_DST)
 
+$(BIN_DST)/$(UPDATE_USERS): $(CONF_SRC)/$(UPDATE_USERS) $(BIN_DST)
+	cp $(CONF_SRC)/$(UPDATE_USERS) $(BIN_DST)
+
 $(BIN_DST)/$(CREATE_REGISTRATION): $(CONF_SRC)/$(CREATE_REGISTRATION) $(BIN_DST)
 	cp $(CONF_SRC)/$(CREATE_REGISTRATION) $(BIN_DST)
 
diff --git a/conf.schoolserver/create_user b/conf.schoolserver/create_user
index 55e5cfe..40f63e3 100755
--- a/conf.schoolserver/create_user
+++ b/conf.schoolserver/create_user
@@ -38,11 +38,17 @@ read uuid
 read pubkey
 
 homedir=/library/users/$username
+XO_USERS_GROUP=xousers
+
+#make sure the xousers group exists
+getent group $XO_USERS_GROUP > /dev/null 2>&1 || groupadd $XO_USERS_GROUP
 
 if getent passwd "$username" > /dev/null 2>&1; then
     true   # User exists
-else
-    /usr/sbin/adduser -c "$full_name" -d $homedir "$username" || die "Unable to
create user"
+else 
+    /usr/sbin/useradd -c "$full_name" -d "$homedir"  \
+        -G $XO_USERS_GROUP -s /usr/bin/rssh "$username" \
+        || die "Unable to create user"
     echo $uuid | passwd --stdin "$username" || die "Unable to set password"
 fi
 
diff --git a/conf.schoolserver/update_users.py b/conf.schoolserver/update_users.py
new file mode 100755
index 0000000..3684f08
--- /dev/null
+++ b/conf.schoolserver/update_users.py
@@ -0,0 +1,62 @@
+#!/usr/bin/python
+#
+# update_users.py
+#
+# In the past, when an XO user registered, they were given their own
+# group and no more.  Now we want them to all be in the same group
+# because it makes the management of restricted ssh access (and
+# possibly other things) easier.  
+
+#The group we are using is "xousers", and we're finding the XO users
+# by the location of their home directories.
+
+
+import os
+import sys
+import pwd, grp
+import subprocess
+
+XO_USER_HOME = '/library/users'
+XO_USER_GROUP = 'xousers'
+RSSH_PATH = '/usr/bin/rssh'
+
+# first, make sure the group is there
+# much like `getent group xousers || groupadd xousers`
+try:
+    group = grp.getgrnam(XO_USER_GROUP)
+except KeyError, e:
+    print >> sys.stderr, e
+    result = subprocess.call(['groupadd', XO_USER_GROUP])
+    if result:
+        raise RuntimeError("couldn't add %s group" % XO_USER_GROUP)
+
+# just make sure the rssh executable is there
+if not os.access(RSSH_PATH, os.F_OK | os.R_OK | os.X_OK):
+    raise RuntimeError("%s seems to be missing or otherwise inaccessable" %
RSSH_PATH)
+    
+
+# now find each user who has a /library/users/* home directory and try
+# to change their group.
+# Execution will stop when one fails BUT any users who's groups have
+# been changed will not be changed back.
+
+users = [ x for x in pwd.getpwall() 
+          if os.path.dirname(x.pw_dir) == XO_USER_HOME ]
+
+for user in users:
+    #if for some reason the user's name isn't already a group (e.g.,
+    #they were created with `usermod -g some-other-group`.
+    try:
+        group = grp.getgrnam(user.pw_name)
+    except KeyError, e:
+        print >> sys.stderr, e
+        result = subprocess.call(['groupadd', user.pw_name])
+        if result:
+            raise RuntimeError("couldn't add %s group" % XO_USER_GROUP)
+    
+    result = subprocess.call(['usermod', '-g', user.pw_name, '-G', XO_USER_GROUP,
+                              '-s', RSSH_PATH, user.pw_name])
+    if result:
+        raise RuntimeError("couldn't change group for user %s (out of %s)" 
+                           % (user.pw_name, users))
+
diff --git a/idmgr.spec b/idmgr.spec
index 5616a7f..bc00da0 100644
--- a/idmgr.spec
+++ b/idmgr.spec
@@ -35,6 +35,8 @@ fi
 if [ ! -d /library/users/ ] ; then
    mkdir -p /library/users
 fi
+# Make  sure the xousers group exists
+getent group xousers > /dev/null 2>&1 || groupadd xousers
 
 %post
 #  Make the server script executable
@@ -46,6 +48,9 @@ fi
 /sbin/chkconfig --add idmgr
 /sbin/service idmgr condrestart
 
+# Existing users might not be in the xousers group. Fix that. 
+/home/idmgr/update_users.py
+
 %preun
 if [ $1 -eq 0 ]; then
     /sbin/service idmgr stop &>/dev/null || :
@@ -69,6 +74,7 @@ rm -rf $RPM_BUILD_ROOT
 /etc/idmgr.conf
 /home/idmgr/create_registration
 /home/idmgr/create_user
+/home/idmgr/update_users.py
 /home/idmgr/idmgr/CONFIG.py
 /home/idmgr/idmgr/CONFIG.pyc
 /home/idmgr/idmgr/CONFIG.pyo
diff --git a/idmgr/server.py b/idmgr/server.py
old mode 100644
new mode 100755



More information about the Server-devel mailing list