subgroup support, courtesy of luk
authorPeter Palfrader <peter@palfrader.org>
Sun, 23 Nov 2008 20:13:40 +0000 (21:13 +0100)
committerPeter Palfrader <peter@palfrader.org>
Sun, 23 Nov 2008 20:13:40 +0000 (21:13 +0100)
debian/changelog
ud-generate
userdir-ldap.schema

index 7790d5b..8da79cb 100644 (file)
@@ -2,8 +2,15 @@ userdir-ldap (0.3.XX) unstable; urgency=low
 
   * Update template/welcome-message-800 to match the actual template used
     on db.debian.org.
 
   * Update template/welcome-message-800 to match the actual template used
     on db.debian.org.
-
- -- Peter Palfrader <weasel@debian.org>  Sun, 23 Nov 2008 14:20:10 +0100
+  * Add subgroup support:  A group can now have subgroups.  This means
+    that if a user is a member of a group he also becomes a member of
+    all its subgroups.  E.g. members of a wb-all group will automatically
+    be members of wb-i386, wb-arm, wb-mips, etc.  [Luk Claes]
+  * Extend that support so that subgroups work on a per host basis too,
+    so that for instance the debbugs group can be in group
+    maillog@rietz.debian.org.
+
+ -- Peter Palfrader <weasel@debian.org>  Sun, 23 Nov 2008 21:06:53 +0100
 
 userdir-ldap (0.3.50) unstable; urgency=low
 
 
 userdir-ldap (0.3.50) unstable; urgency=low
 
index e25411c..5f2a482 100755 (executable)
@@ -9,6 +9,7 @@
 #   Copyright (c) 2008 Peter Palfrader <peter@palfrader.org>
 #   Copyright (c) 2008 Andreas Barth <aba@not.so.argh.org>
 #   Copyright (c) 2008 Mark Hymers <mhy@debian.org>
 #   Copyright (c) 2008 Peter Palfrader <peter@palfrader.org>
 #   Copyright (c) 2008 Andreas Barth <aba@not.so.argh.org>
 #   Copyright (c) 2008 Mark Hymers <mhy@debian.org>
+#   Copyright (c) 2008 Luk Claes <luk@debian.org>
 #
 #   This program is free software; you can redistribute it and/or modify
 #   it under the terms of the GNU General Public License as published by
 #
 #   This program is free software; you can redistribute it and/or modify
 #   it under the terms of the GNU General Public License as published by
@@ -32,6 +33,7 @@ global CurrentHost;
 
 PasswdAttrs = None;
 GroupIDMap = {};
 
 PasswdAttrs = None;
 GroupIDMap = {};
+SubGroupMap = {};
 Allowed = None;
 CurrentHost = "";
 
 Allowed = None;
 CurrentHost = "";
 
@@ -355,6 +357,31 @@ def GenSSHtarballs(userlist, SSHFiles, grouprevmap, target):
    tf.close()
    os.rename(os.path.join(GlobalDir, 'ssh-keys-%s.tar.gz' % CurrentHost), target)
 
    tf.close()
    os.rename(os.path.join(GlobalDir, 'ssh-keys-%s.tar.gz' % CurrentHost), target)
 
+# add a list of groups to existing groups,
+# including all subgroups thereof, recursively.
+# basically this proceduces the transitive hull of the groups in
+# addgroups.
+def addGroups(existingGroups, newGroups, uid):
+   for group in newGroups:
+      # if it's a <group>@host, split it and verify it's on the current host.
+      s = group.split('@', 1)
+      if len(s) == 2 and s[1] != CurrentHost:
+         continue;
+      group = s[0]
+
+      # let's see if we handled this group already
+      if group in existingGroups:
+        continue
+
+      if not GroupIDMap.has_key(group):
+         print "Group does not exist ",group,"but",uid,"is in it"
+         continue
+
+      existingGroups.append(group)
+
+      if SubGroupMap.has_key(group):
+         addGroups(existingGroups, SubGroupMap[group])
+
 # Generate the group list
 def GenGroup(l,File):
   grouprevmap = {}
 # Generate the group list
 def GenGroup(l,File):
   grouprevmap = {}
@@ -374,20 +401,16 @@ def GenGroup(l,File):
 
    # Sort them into a list of groups having a set of users
    for x in PasswdAttrs:
 
    # Sort them into a list of groups having a set of users
    for x in PasswdAttrs:
+      uid = GetAttr(x,"uid")
       if x[1].has_key("uidNumber") == 0 or IsInGroup(x) == 0:
          continue;
       if x[1].has_key("supplementaryGid") == 0:
          continue;
 
       if x[1].has_key("uidNumber") == 0 or IsInGroup(x) == 0:
          continue;
       if x[1].has_key("supplementaryGid") == 0:
          continue;
 
-      for I in x[1]["supplementaryGid"]:
-         s = I.split('@', 1)
-         group = s[0]
-         if len(s) == 2 and s[1] != CurrentHost:
-            continue;
-         if GroupMap.has_key(group):
-            GroupMap[group].append(GetAttr(x,"uid"));
-         else:
-            print "Group does not exist ",group,"but",GetAttr(x,"uid"),"is in it";
+      supgroups=[]
+      addGroups(supgroups, x[1]["supplementaryGid"], uid)
+      for g in supgroups:
+         GroupMap[g].append(uid);
 
    # Output the group file.
    J = 0;
 
    # Output the group file.
    J = 0;
@@ -944,13 +967,15 @@ l.simple_bind_s("uid="+Pass[0]+","+BaseDn,Pass[1]);
 # Fetch all the groups
 GroupIDMap = {};
 Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"gid=*",\
 # Fetch all the groups
 GroupIDMap = {};
 Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"gid=*",\
-                  ["gid","gidNumber"]);
+                  ["gid","gidNumber","subGroup"]);
 
 
-# Generate the GroupMap and GroupIDMap
+# Generate the SubGroupMap and GroupIDMap
 for x in Attrs:
    if x[1].has_key("gidNumber") == 0:
       continue;
    GroupIDMap[x[1]["gid"][0]] = int(x[1]["gidNumber"][0]);
 for x in Attrs:
    if x[1].has_key("gidNumber") == 0:
       continue;
    GroupIDMap[x[1]["gid"][0]] = int(x[1]["gidNumber"][0]);
+   if x[1].has_key("subGroup") != 0:
+      SubGroupMap.setdefault(x[1]["gid"][0], []).extend(x[1]["subGroup"]);
 
 # Fetch all the users
 PasswdAttrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"uid=*",\
 
 # Fetch all the users
 PasswdAttrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"uid=*",\
index 33a6922..76afce6 100644 (file)
@@ -4,6 +4,7 @@
 #   - [PP] Now version controlled in db.d.o bzr repository - 2007-12-25
 #   - [HE] Add 'purpose', 'physicalHost' to debianServer - 2007-12-25
 #   - [zobel] Add 'VoIP' - 2008-05-10
 #   - [PP] Now version controlled in db.d.o bzr repository - 2007-12-25
 #   - [HE] Add 'purpose', 'physicalHost' to debianServer - 2007-12-25
 #   - [zobel] Add 'VoIP' - 2008-05-10
+#   - [luk] Add 'subGroup' to group - 2008-11-22
 #
 # 0.7 [RM]
 #   - Add 'gender' and 'birthDate' to debianDeveloper
 #
 # 0.7 [RM]
 #   - Add 'gender' and 'birthDate' to debianDeveloper
 #   .34 - physicalHost
 #   .35 - VoIP
 #   .36 - sudoPassword
 #   .34 - physicalHost
 #   .35 - VoIP
 #   .36 - sudoPassword
+#   .37 - subGroup
 #
 # .3 - experimental LDAP objectClasses
 #   .1 - debianDeveloper
 #
 # .3 - experimental LDAP objectClasses
 #   .1 - debianDeveloper
@@ -366,6 +368,13 @@ attributetype ( 1.3.6.1.4.1.9586.100.4.2.36
        EQUALITY octetStringMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
 
        EQUALITY octetStringMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
 
+attributetype ( 1.3.6.1.4.1.9586.100.4.2.37
+       NAME 'subGroup'
+       DESC 'name of other group for which membership implied by memberschip to this group'
+       EQUALITY caseIgnoreIA5Match
+       SUBSTR caseIgnoreIA5SubstringsMatch
+       SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
 
 # Public object classes
 
 
 # Public object classes
 
@@ -381,7 +390,7 @@ objectclass ( 1.3.6.1.4.1.9586.100.4.1.2
        SUP top STRUCTURAL
        DESC 'attributes used for Debian groups'
        MUST ( gid $ gidNumber )
        SUP top STRUCTURAL
        DESC 'attributes used for Debian groups'
        MUST ( gid $ gidNumber )
-       MAY ( description ) )
+       MAY ( description $ subGroup ) )
 
 # Experimental attribute types
 
 
 # Experimental attribute types