1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-03 04:22:09 +03:00

samba-tool group addmembers: add --member-dn option

The --member-dn option allows to specify an object by it's DN.

This is required to select a specific object if there are more than one
with the same name. Multiple contacts can exist with the same name in
different OUs.

Signed-off-by: Björn Baumbach <bb@sernet.de>
Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
Björn Baumbach
2019-12-17 16:26:23 +01:00
committed by Stefan Metzmacher
parent f2e2579926
commit aedcf6a527
2 changed files with 42 additions and 27 deletions

View File

@ -218,7 +218,7 @@ sudo samba-tool group addmembers supergroup User2
Example2 shows how to add a single user account, User2, to the supergroup AD group. It uses the sudo command to run as root when issuing the command. Example2 shows how to add a single user account, User2, to the supergroup AD group. It uses the sudo command to run as root when issuing the command.
""" """
synopsis = "%prog <groupname> <listofmembers> [options]" synopsis = "%prog <groupname> (<listofmembers>]|--member-dn=<member-dn>) [options]"
takes_optiongroups = { takes_optiongroups = {
"sambaopts": options.SambaOptions, "sambaopts": options.SambaOptions,
@ -229,6 +229,10 @@ Example2 shows how to add a single user account, User2, to the supergroup AD gro
takes_options = [ takes_options = [
Option("-H", "--URL", help="LDB URL for database or target server", type=str, Option("-H", "--URL", help="LDB URL for database or target server", type=str,
metavar="URL", dest="H"), metavar="URL", dest="H"),
Option("--member-dn",
help=("DN of the new group member to be added.\n"
"The --object-types option will be ignored."),
type=str),
Option("--object-types", Option("--object-types",
help=("Comma separated list of object types.\n" help=("Comma separated list of object types.\n"
"The types are used to filter the search for the " "The types are used to filter the search for the "
@ -240,15 +244,16 @@ Example2 shows how to add a single user account, User2, to the supergroup AD gro
type=str), type=str),
] ]
takes_args = ["groupname", "listofmembers"] takes_args = ["groupname", "listofmembers?"]
def run(self, def run(self,
groupname, groupname,
listofmembers, listofmembers=None,
credopts=None, credopts=None,
sambaopts=None, sambaopts=None,
versionopts=None, versionopts=None,
H=None, H=None,
member_dn=None,
object_types="user,group,computer"): object_types="user,group,computer"):
lp = sambaopts.get_loadparm() lp = sambaopts.get_loadparm()
@ -257,7 +262,10 @@ Example2 shows how to add a single user account, User2, to the supergroup AD gro
try: try:
samdb = SamDB(url=H, session_info=system_session(), samdb = SamDB(url=H, session_info=system_session(),
credentials=creds, lp=lp) credentials=creds, lp=lp)
groupmembers = listofmembers.split(',') if member_dn is not None:
groupmembers = [ member_dn ]
else:
groupmembers = listofmembers.split(',')
group_member_types = object_types.split(',') group_member_types = object_types.split(',')
samdb.add_remove_group_members(groupname, groupmembers, samdb.add_remove_group_members(groupname, groupmembers,
add_members_operation=True, add_members_operation=True,

View File

@ -334,35 +334,42 @@ changetype: modify
""" % (str(targetgroup[0].dn)) """ % (str(targetgroup[0].dn))
for member in members: for member in members:
filter = self.group_member_filter(member, member_types) targetmember_dn = None
foreign_msg = None
try: try:
membersid = security.dom_sid(member) membersid = security.dom_sid(member)
targetmember_dn = "<SID=%s>" % str(membersid)
except TypeError as e: except TypeError as e:
membersid = None pass
if membersid is not None: if targetmember_dn is None:
filter = '(objectSid=%s)' % str(membersid) try:
dn_str = "<SID=%s>" % str(membersid) member_dn = ldb.Dn(self, member)
foreign_msg = ldb.Message() if member_dn.get_linearized() == member_dn.extended_str(1):
foreign_msg.dn = ldb.Dn(self, dn_str) full_member_dn = self.normalize_dn_in_domain(member_dn)
else:
full_member_dn = member_dn
targetmember_dn = full_member_dn.extended_str(1)
except ValueError as e:
pass
targetmember = self.search(base=self.domain_dn(), if targetmember_dn is None:
scope=ldb.SCOPE_SUBTREE, filter = self.group_member_filter(member, member_types)
expression="%s" % filter, targetmember = self.search(base=self.domain_dn(),
attrs=[]) scope=ldb.SCOPE_SUBTREE,
expression=filter,
attrs=[])
if len(targetmember) > 1:
targetmemberlist_str = ""
for msg in targetmember:
targetmemberlist_str += "%s\n" % msg.get("dn")
raise Exception('Found multiple results for "%s":\n%s' %
(member, targetmemberlist_str))
if len(targetmember) != 1:
raise Exception('Unable to find "%s". Operation cancelled.' % member)
targetmember_dn = targetmember[0].dn.extended_str(1)
if len(targetmember) > 1:
memberlist_str = ""
for msg in targetmember:
memberlist_str += "%s\n" % msg.get("dn")
raise Exception('Found multiple results for "%s":\n%s' %
(member, memberlist_str))
if len(targetmember) == 0 and foreign_msg is not None:
targetmember = [foreign_msg]
if len(targetmember) != 1:
raise Exception('Unable to find "%s". Operation cancelled.' % member)
targetmember_dn = targetmember[0].dn.extended_str(1)
if add_members_operation is True and (targetgroup[0].get('member') is None or get_bytes(targetmember_dn) not in [str(x) for x in targetgroup[0]['member']]): if add_members_operation is True and (targetgroup[0].get('member') is None or get_bytes(targetmember_dn) not in [str(x) for x in targetgroup[0]['member']]):
modified = True modified = True
addtargettogroup += """add: member addtargettogroup += """add: member