+ try:
+ OldMask = os.umask(0077)
+ File = os.path.join(GlobalDir, 'userkeys', User)
+ F = open(File + ".tmp", "w", 0600)
+ os.umask(OldMask)
+
+ for I in x[1]["sshRSAAuthKey"]:
+ MultipleLine = "%s" % I
+ MultipleLine = Sanitize(MultipleLine) + "\n"
+ F.write(MultipleLine)
+
+ Done(File, F, None)
+ userfiles.append(os.path.basename(File))
+
+ # Oops, something unspeakable happened.
+ except IOError:
+ Die(File, F, None)
+ # As neither masterFileName nor masterFile are defined at any point
+ # this will raise a NameError.
+ Die(masterFileName, masterFile, None)
+ raise
+
+ return userfiles
+
+def GenSSHtarballs(userlist, SSHFiles, grouprevmap, target):
+ OldMask = os.umask(0077)
+ tf = tarfile.open(name=os.path.join(GlobalDir, 'ssh-keys-%s.tar.gz' % CurrentHost), mode='w:gz')
+ os.umask(OldMask)
+ for f in userlist.keys():
+ if f not in SSHFiles:
+ continue
+ # If we're not exporting their primary group, don't export
+ # the key and warn
+ grname = None
+ if userlist[f] in grouprevmap.keys():
+ grname = grouprevmap[userlist[f]]
+ else:
+ try:
+ if int(userlist[f]) <= 100:
+ # In these cases, look it up in the normal way so we
+ # deal with cases where, for instance, users are in group
+ # users as their primary group.
+ grname = grp.getgrgid(userlist[f])[0]
+ except Exception, e:
+ pass
+
+ if grname is None:
+ print "User %s is supposed to have their key exported to host %s but their primary group (gid: %d) isn't in LDAP" % (f, CurrentHost, userlist[f])
+ continue
+
+ to = tf.gettarinfo(os.path.join(GlobalDir, 'userkeys', f), f)
+ # These will only be used where the username doesn't
+ # exist on the target system for some reason; hence,
+ # in those cases, the safest thing is for the file to
+ # be owned by root but group nobody. This deals with
+ # the bloody obscure case where the group fails to exist
+ # whilst the user does (in which case we want to avoid
+ # ending up with a file which is owned user:root to avoid
+ # a fairly obvious attack vector)
+ to.uid = 0
+ to.gid = 65534
+ # Using the username / groupname fields avoids any need
+ # to give a shit^W^W^Wcare about the UIDoffset stuff.
+ to.uname = f
+ to.gname = grname
+ to.mode = 0400
+
+ contents = file(os.path.join(GlobalDir, 'userkeys', f)).read()
+ lines = []
+ for line in contents.splitlines():
+ if line.startswith("allowed_hosts=") and ' ' in line:
+ machines, line = line.split('=', 1)[1].split(' ', 1)
+ if CurrentHost not in machines.split(','):
+ continue # skip this key
+ lines.append(line)
+ if not lines:
+ continue # no keys for this host
+ contents = "\n".join(lines) + "\n"
+ to.size = len(contents)
+ tf.addfile(to, StringIO(contents))
+
+ 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", group, "does not exist but", uid, "is in it"
+ continue
+
+ existingGroups.append(group)
+
+ if SubGroupMap.has_key(group):
+ addGroups(existingGroups, SubGroupMap[group], uid)