diff options
| author | Björn Baumbach <bb@sernet.de> | 2018-05-16 10:19:16 +0200 |
|---|---|---|
| committer | Andreas Schneider <asn@cryptomilk.org> | 2020-01-15 12:05:33 +0000 |
| commit | 8403527bbd132ee639fdd3926bf55d15bd8dea56 (patch) | |
| tree | 0f7583d718bad0b7235e6210f94951a2eea12f04 /python/samba/netcmd | |
| parent | d512b27563b32f7bcb35da21781e87473830c906 (diff) | |
| download | samba-8403527bbd132ee639fdd3926bf55d15bd8dea56.tar.gz samba-8403527bbd132ee639fdd3926bf55d15bd8dea56.tar.bz2 samba-8403527bbd132ee639fdd3926bf55d15bd8dea56.zip | |
samba-tool: implement user setprimary group command (set primaryGroupID)
Introduce an option to set the primaryGroupID attribute of a user account.
Pair-programmed-with: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Björn Baumbach <bb@sernet.de>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'python/samba/netcmd')
| -rw-r--r-- | python/samba/netcmd/user.py | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/python/samba/netcmd/user.py b/python/samba/netcmd/user.py index 86a7a45b24e..8e07e99b71b 100644 --- a/python/samba/netcmd/user.py +++ b/python/samba/netcmd/user.py @@ -736,6 +736,116 @@ class cmd_user_password(Command): self.outf.write("Changed password OK\n") +class cmd_user_setprimarygroup(Command): + """Set the primary group a user account. + +This command sets the primary group a user account. The username specified on +the command is the sAMAccountName. The primarygroupname is the sAMAccountName +of the new primary group. The user must be a member of the group. + +The command may be run from the root userid or another authorized userid. The +-H or --URL= option can be used to execute the command against a remote server. + +Example1: +samba-tool user setprimarygroup TestUser1 newPrimaryGroup --URL=ldap://samba.samdom.example.com -Uadministrator%passw1rd + +Example1 shows how to set the primary group for TestUser1 on a remote LDAP +server. The --URL parameter is used to specify the remote target server. The +-U option is used to pass the username and password of a user that exists on +the remote server and is authorized to update the server. +""" + synopsis = "%prog <username> <primarygroupname> [options]" + + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "versionopts": options.VersionOptions, + "credopts": options.CredentialsOptions, + } + + takes_options = [ + Option("-H", "--URL", help="LDB URL for database or target server", type=str, + metavar="URL", dest="H"), + ] + + takes_args = ["username", "primarygroupname"] + + def run(self, username, primarygroupname, credopts=None, sambaopts=None, + versionopts=None, H=None): + + lp = sambaopts.get_loadparm() + creds = credopts.get_credentials(lp) + + samdb = SamDB(url=H, session_info=system_session(), + credentials=creds, lp=lp) + + filter = ("(&(sAMAccountName=%s)(objectClass=user))" % + ldb.binary_encode(username)) + try: + res = samdb.search(base=samdb.domain_dn(), + expression=filter, + scope=ldb.SCOPE_SUBTREE, + controls=["extended_dn:1:1"], + attrs=["objectSid", + "memberOf", + "primaryGroupID"]) + user_sid_binary = res[0].get('objectSid', idx=0) + user_sid = ndr_unpack(security.dom_sid, user_sid_binary) + (user_dom_sid, user_rid) = user_sid.split() + user_sid_dn = "<SID=%s>" % user_sid + user_pgid = int(res[0].get('primaryGroupID', idx=0)) + user_groups = res[0].get('memberOf') + if user_groups is None: + user_groups = [] + except IndexError: + raise CommandError("Unable to find user '%s'" % (username)) + + user_group_sids = [] + for user_group in user_groups: + user_group_dn = ldb.Dn(samdb, str(user_group)) + user_group_binary_sid = user_group_dn.get_extended_component("SID") + user_group_sid = ndr_unpack(security.dom_sid, user_group_binary_sid) + user_group_sids.append(user_group_sid) + + filter = ("(&(sAMAccountName=%s)(objectClass=group))" % + ldb.binary_encode(primarygroupname)) + try: + res = samdb.search(base=samdb.domain_dn(), + expression=filter, + scope=ldb.SCOPE_SUBTREE, + attrs=["objectSid"]) + group_sid_binary = res[0].get('objectSid', idx=0) + except IndexError: + raise CommandError("Unable to find group '%s'" % (primarygroupname)) + + primarygroup_sid = ndr_unpack(security.dom_sid, group_sid_binary) + (primarygroup_dom_sid, primarygroup_rid) = primarygroup_sid.split() + + if user_dom_sid != primarygroup_dom_sid: + raise CommandError("Group '%s' does not belong to the user's " + "domain" % primarygroupname) + + if primarygroup_rid != user_pgid and primarygroup_sid not in user_group_sids: + raise CommandError("User '%s' is not member of group '%s'" % + (username, primarygroupname)) + + setprimarygroup_ldif = """ +dn: %s +changetype: modify +delete: primaryGroupID +primaryGroupID: %u +add: primaryGroupID +primaryGroupID: %u +""" % (user_sid_dn, user_pgid, primarygroup_rid) + + try: + samdb.modify_ldif(setprimarygroup_ldif) + except Exception as msg: + raise CommandError("Failed to set primary group '%s' " + "for user '%s': %s" % + (primarygroupname, username, msg)) + self.outf.write("Changed primary group to '%s'\n" % primarygroupname) + + class cmd_user_setpassword(Command): """Set or reset the password of a user account. @@ -2894,6 +3004,7 @@ class cmd_user(SuperCommand): subcommands["list"] = cmd_user_list() subcommands["setexpiry"] = cmd_user_setexpiry() subcommands["password"] = cmd_user_password() + subcommands["setprimarygroup"] = cmd_user_setprimarygroup() subcommands["setpassword"] = cmd_user_setpassword() subcommands["getpassword"] = cmd_user_getpassword() subcommands["syncpasswords"] = cmd_user_syncpasswords() |
