def write(self, dn, attributes, parameters): # get group names and check against requested group name names = attributes['cn'] if 'cn' in parameters: if parameters['cn'] not in names: return names = ( parameters['cn'], ) # get group group password passwd = attributes['userPassword'][0] # get group id(s) gids = ( parameters['gidNumber'], ) if 'gidNumber' in parameters else attributes['gidNumber'] gids = [ int(x) for x in gids ] # build member list members = set() if self.wantmembers: # add the memberUid values for member in clean(attributes['memberUid']): if common.isvalidname(member): members.add(member) # translate and add the member values for memberdn in clean(attributes['member']): member = dn2uid(self.conn, memberdn) if member and common.isvalidname(member): members.add(member) # actually return the results for name in names: if not common.isvalidname(name): print 'Warning: group entry %s contains invalid group name: "%s"' % ( dn, name ) else: for gid in gids: self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) self.fp.write_string(name) self.fp.write_string(passwd) self.fp.write_gid_t(gid) self.fp.write_stringlist(members)
def get_members(self, attributes, members, subgroups, seen): # add the memberUid values for member in clean(attributes['memberUid']): if common.isvalidname(member): members.add(member) # translate and add the member values for memberdn in clean(attributes['member']): if memberdn in seen: continue seen.add(memberdn) member = passwd.dn2uid(self.conn, memberdn) if member and common.isvalidname(member): members.add(member) elif cfg.nss_nested_groups: subgroups.append(memberdn)
def validate(self, parameters): """This method checks the provided username for validity and fills in the DN if needed.""" # check username for validity common.validate_name(parameters['username']) # look up user DN entry = passwd.uid2entry(self.conn, parameters['username']) if not entry: # FIXME: we should close the stream with an empty response here raise ValueError('%r: user not found' % parameters['username']) # save the DN parameters['userdn'] = entry[0] # get the "real" username value = passwd.attmap.get_rdn_value(entry[0], 'uid') if not value: # get the username from the uid attribute values = entry[1]['uid'] if not values or not values[0]: logging.warning('%s: is missing a %s attribute', entry[0], passwd.attmap['uid']) value = values[0] # check the username if value and not common.isvalidname(value): raise ValueError('%s: has invalid %s attribute', entry[0], passwd.attmap['uid']) # check if the username is different and update it if needed if value != parameters['username']: logging.info('username changed from %r to %r', parameters['username'], value) parameters['username'] = value
def convert(self, dn, attributes, parameters): # get group names and check against requested group name names = attributes['cn'] # get group group password passwd = attributes['userPassword'][0] # get group id(s) gids = [int(x) for x in attributes['gidNumber']] # build member list members = set() subgroups = [] seen = set([dn]) self.get_members(attributes, members, subgroups, seen) # go over subgroups to find more members while subgroups: memberdn = subgroups.pop(0) for dn2, attributes2 in self.search(self.conn, base=memberdn, scope=ldap.SCOPE_BASE): self.get_members(attributes2, members, subgroups, seen) # actually return the results for name in names: if not common.isvalidname(name): logging.warning('%s: %s: denied by validnames option', dn, attmap['cn']) else: for gid in gids: yield (name, passwd, gid, members)
def write(self, dn, attributes, parameters): # get uid attribute and check against requested user name names = attributes['uid'] if 'uid' in parameters: if parameters['uid'] not in names: return names = ( parameters['uid'], ) # get user password entry if 'shadowAccount' in attributes['objectClass']: passwd = 'x' else: passwd = attributes['userPassword'][0] # get numeric user and group ids uids = ( parameters['uidNumber'], ) if 'uidNumber' in parameters else attributes['uidNumber'] uids = [ int(x) for x in uids ] # get other passwd properties gid = int(attributes['gidNumber'][0]) gecos = attributes['gecos'][0] home = attributes['homeDirectory'][0] shell = attributes['loginShell'][0] # write results for name in names: if not common.isvalidname(name): print 'Warning: passwd entry %s contains invalid user name: "%s"' % ( dn, name ) else: for uid in uids: self.fp.write_int32(constants.NSLCD_RESULT_BEGIN) self.fp.write_string(name) self.fp.write_string(passwd) self.fp.write_uid_t(uid) self.fp.write_gid_t(gid) self.fp.write_string(gecos) self.fp.write_string(home) self.fp.write_string(shell)
def validate_request(self, parameters): """This method checks the provided username for validity and fills in the DN if needed.""" # check username for validity common.validate_name(parameters['username']) # look up user DN if not known if not parameters['userdn']: entry = passwd.uid2entry(self.conn, parameters['username']) if not entry: raise ValueError('%r: user not found' % parameters['username']) # save the DN parameters['userdn'] = entry[0] # get the "real" username value = common.get_rdn_value(entry[0], passwd.attmap['uid']) if not value: # get the username from the uid attribute values = myldap_get_values(entry, passwd.attmap['uid']) if not values or not values[0]: logging.warn('%s: is missing a %s attribute', dn, passwd.attmap['uid']) value = values[0] # check the username if value and not common.isvalidname(value): raise ValueError('%s: has invalid %s attribute', dn, passwd.attmap['uid']) # check if the username is different and update it if needed if value != parameters['username']: logging.info('username changed from %r to %r', parameters['username'], value) parameters['username'] = value
def convert(self, dn, attributes, parameters): names = attributes['uid'] if 'shadowAccount' in attributes['objectClass']: passwd = 'x' else: passwd = attributes['userPassword'][0] uids = [int(x) for x in attributes['uidNumber']] gid = int(attributes['gidNumber'][0]) gecos = attributes['gecos'][0] home = attributes['homeDirectory'][0] shell = attributes['loginShell'][0] for name in names: if not common.isvalidname(name): logging.warning('%s: %s: denied by validnames option', dn, attmap['uid']) else: for uid in uids: if uid >= cfg.nss_min_uid: yield (name, passwd, uid, gid, gecos, home, shell)