.gitlab-ci-main.yml: Add safe.directory '*'
[Samba.git] / python / samba / netcmd / user / setprimarygroup.py
blob90b957fbea8ba0faeb9fc6b0b95a7dacf6f20c11
1 # user management
3 # user setprimarygroup command
5 # Copyright Jelmer Vernooij 2010 <jelmer@samba.org>
6 # Copyright Theresa Halloran 2011 <theresahalloran@gmail.com>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 import samba.getopt as options
23 from samba import ldb
24 from samba.auth import system_session
25 from samba.dcerpc import security
26 from samba.ndr import ndr_unpack
27 from samba.netcmd import Command, CommandError, Option
28 from samba.samdb import SamDB
31 class cmd_user_setprimarygroup(Command):
32 """Set the primary group a user account.
34 This command sets the primary group a user account. The username specified on
35 the command is the sAMAccountName. The primarygroupname is the sAMAccountName
36 of the new primary group. The user must be a member of the group.
38 The command may be run from the root userid or another authorized userid. The
39 -H or --URL= option can be used to execute the command against a remote server.
41 Example1:
42 samba-tool user setprimarygroup TestUser1 newPrimaryGroup --URL=ldap://samba.samdom.example.com -Uadministrator%passw1rd
44 Example1 shows how to set the primary group for TestUser1 on a remote LDAP
45 server. The --URL parameter is used to specify the remote target server. The
46 -U option is used to pass the username and password of a user that exists on
47 the remote server and is authorized to update the server.
48 """
49 synopsis = "%prog <username> <primarygroupname> [options]"
51 takes_optiongroups = {
52 "sambaopts": options.SambaOptions,
53 "versionopts": options.VersionOptions,
54 "credopts": options.CredentialsOptions,
57 takes_options = [
58 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
59 metavar="URL", dest="H"),
62 takes_args = ["username", "primarygroupname"]
64 def run(self, username, primarygroupname, credopts=None, sambaopts=None,
65 versionopts=None, H=None):
67 lp = sambaopts.get_loadparm()
68 creds = credopts.get_credentials(lp)
70 samdb = SamDB(url=H, session_info=system_session(),
71 credentials=creds, lp=lp)
73 filter = ("(&(sAMAccountName=%s)(objectClass=user))" %
74 ldb.binary_encode(username))
75 try:
76 res = samdb.search(base=samdb.domain_dn(),
77 expression=filter,
78 scope=ldb.SCOPE_SUBTREE,
79 controls=["extended_dn:1:1"],
80 attrs=["objectSid",
81 "memberOf",
82 "primaryGroupID"])
83 user_sid_binary = res[0].get('objectSid', idx=0)
84 user_sid = ndr_unpack(security.dom_sid, user_sid_binary)
85 (user_dom_sid, user_rid) = user_sid.split()
86 user_sid_dn = "<SID=%s>" % user_sid
87 user_pgid = int(res[0].get('primaryGroupID', idx=0))
88 user_groups = res[0].get('memberOf')
89 if user_groups is None:
90 user_groups = []
91 except IndexError:
92 raise CommandError("Unable to find user '%s'" % (username))
94 user_group_sids = []
95 for user_group in user_groups:
96 user_group_dn = ldb.Dn(samdb, str(user_group))
97 user_group_binary_sid = user_group_dn.get_extended_component("SID")
98 user_group_sid = ndr_unpack(security.dom_sid, user_group_binary_sid)
99 user_group_sids.append(user_group_sid)
101 filter = ("(&(sAMAccountName=%s)(objectClass=group))" %
102 ldb.binary_encode(primarygroupname))
103 try:
104 res = samdb.search(base=samdb.domain_dn(),
105 expression=filter,
106 scope=ldb.SCOPE_SUBTREE,
107 attrs=["objectSid"])
108 group_sid_binary = res[0].get('objectSid', idx=0)
109 except IndexError:
110 raise CommandError("Unable to find group '%s'" % (primarygroupname))
112 primarygroup_sid = ndr_unpack(security.dom_sid, group_sid_binary)
113 (primarygroup_dom_sid, primarygroup_rid) = primarygroup_sid.split()
115 if user_dom_sid != primarygroup_dom_sid:
116 raise CommandError("Group '%s' does not belong to the user's "
117 "domain" % primarygroupname)
119 if primarygroup_rid != user_pgid and primarygroup_sid not in user_group_sids:
120 raise CommandError("User '%s' is not member of group '%s'" %
121 (username, primarygroupname))
123 setprimarygroup_ldif = """
124 dn: %s
125 changetype: modify
126 delete: primaryGroupID
127 primaryGroupID: %u
128 add: primaryGroupID
129 primaryGroupID: %u
130 """ % (user_sid_dn, user_pgid, primarygroup_rid)
132 try:
133 samdb.modify_ldif(setprimarygroup_ldif)
134 except Exception as msg:
135 raise CommandError("Failed to set primary group '%s' "
136 "for user '%s': %s" %
137 (primarygroupname, username, msg))
138 self.outf.write("Changed primary group to '%s'\n" % primarygroupname)