1 # Adds a new user to a Samba4 server
2 # Copyright Jelmer Vernooij 2008
4 # Based on the original in EJS:
5 # Copyright Andrew Tridgell 2005
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 import samba.getopt as options
21 from samba.netcmd import Command, SuperCommand, CommandError, Option
23 from samba.ndr import ndr_unpack
24 from samba.dcerpc import security
26 from getpass import getpass
27 from samba.auth import system_session
28 from samba.samdb import SamDB
29 from samba.dsdb import (
30 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP,
31 GTYPE_SECURITY_GLOBAL_GROUP,
32 GTYPE_SECURITY_UNIVERSAL_GROUP,
33 GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP,
34 GTYPE_DISTRIBUTION_GLOBAL_GROUP,
35 GTYPE_DISTRIBUTION_UNIVERSAL_GROUP,
38 security_group = dict({"Domain": GTYPE_SECURITY_DOMAIN_LOCAL_GROUP, "Global": GTYPE_SECURITY_GLOBAL_GROUP, "Universal": GTYPE_SECURITY_UNIVERSAL_GROUP})
39 distribution_group = dict({"Domain": GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP, "Global": GTYPE_DISTRIBUTION_GLOBAL_GROUP, "Universal": GTYPE_DISTRIBUTION_UNIVERSAL_GROUP})
42 class cmd_group_add(Command):
43 """Creates a new AD group
45 This command creates a new Active Directory group. The groupname specified on the command is a unique sAMAccountName.
47 An Active Directory group may contain user and computer accounts as well as other groups. An administrator creates a group and adds members to that group so they can be managed as a single entity. This helps to simplify security and system administration.
49 Groups may also be used to establish email distribution lists, using --group-type=Distribution.
51 Groups are located in domains in organizational units (OUs). The group's scope is a characteristic of the group that designates the extent to which the group is applied within the domain tree or forest.
53 The group location (OU), type (security or distribution) and scope may all be specified on the samba-tool command when the group is created.
55 The command may be run from the root userid or another authorized userid. The
56 -H or --URL= option can be used to execute the command on a remote server.
59 samba-tool group add Group1 -H ldap://samba.samdom.example.com --description='Simple group'
61 Example1 adds a new group with the name Group1 added to the Users container on a remote LDAP server. The -U parameter is used to pass the userid and password of a user that exists on the remote server and is authorized to issue the command on that server. It defaults to the security type and global scope.
64 sudo samba-tool group add Group2 --group-type=Distribution
66 Example2 adds a new distribution group to the local server. The command is run under root using the sudo command.
69 synopsis = "%prog <groupname> [options]"
71 takes_optiongroups = {
72 "sambaopts": options.SambaOptions,
73 "versionopts": options.VersionOptions,
74 "credopts": options.CredentialsOptions,
78 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
79 metavar="URL", dest="H"),
81 help="Alternative location (without domainDN counterpart) to default CN=Users in which new user object will be created",
83 Option("--group-scope", type="choice", choices=["Domain", "Global", "Universal"],
84 help="Group scope (Domain | Global | Universal)"),
85 Option("--group-type", type="choice", choices=["Security", "Distribution"],
86 help="Group type (Security | Distribution)"),
87 Option("--description", help="Group's description", type=str),
88 Option("--mail-address", help="Group's email address", type=str),
89 Option("--notes", help="Groups's notes", type=str),
92 takes_args = ["groupname"]
94 def run(self, groupname, credopts=None, sambaopts=None,
95 versionopts=None, H=None, groupou=None, group_scope=None,
96 group_type=None, description=None, mail_address=None, notes=None):
98 if (group_type or "Security") == "Security":
99 gtype = security_group.get(group_scope, GTYPE_SECURITY_GLOBAL_GROUP)
101 gtype = distribution_group.get(group_scope, GTYPE_DISTRIBUTION_GLOBAL_GROUP)
103 lp = sambaopts.get_loadparm()
104 creds = credopts.get_credentials(lp, fallback_machine=True)
107 samdb = SamDB(url=H, session_info=system_session(),
108 credentials=creds, lp=lp)
109 samdb.newgroup(groupname, groupou=groupou, grouptype = gtype,
110 description=description, mailaddress=mail_address, notes=notes)
112 # FIXME: catch more specific exception
113 raise CommandError('Failed to create group "%s"' % groupname, e)
114 self.outf.write("Added group %s\n" % groupname)
117 class cmd_group_delete(Command):
118 """Deletes an AD group
120 The command deletes an existing AD group from the Active Directory domain. The groupname specified on the command is the sAMAccountName.
122 Deleting a group is a permanent operation. When a group is deleted, all permissions and rights that users in the group had inherited from the group account are deleted as well.
124 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 on a remote server.
127 samba-tool group delete Group1 -H ldap://samba.samdom.example.com -Uadministrator%passw0rd
129 Example1 shows how to delete an AD group from a remote LDAP server. The -U parameter is used to pass the userid and password of a user that exists on the remote server and is authorized to issue the command on that server.
132 sudo samba-tool group delete Group2
134 Example2 deletes group Group2 from the local server. The command is run under root using the sudo command.
137 synopsis = "%prog <groupname> [options]"
139 takes_optiongroups = {
140 "sambaopts": options.SambaOptions,
141 "versionopts": options.VersionOptions,
142 "credopts": options.CredentialsOptions,
146 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
147 metavar="URL", dest="H"),
150 takes_args = ["groupname"]
152 def run(self, groupname, credopts=None, sambaopts=None, versionopts=None, H=None):
154 lp = sambaopts.get_loadparm()
155 creds = credopts.get_credentials(lp, fallback_machine=True)
158 samdb = SamDB(url=H, session_info=system_session(),
159 credentials=creds, lp=lp)
160 samdb.deletegroup(groupname)
162 # FIXME: catch more specific exception
163 raise CommandError('Failed to remove group "%s"' % groupname, e)
164 self.outf.write("Deleted group %s\n" % groupname)
167 class cmd_group_add_members(Command):
168 """Add members to an AD group
170 This command adds one or more members to an existing Active Directory group. The command accepts one or more group member names seperated by commas. A group member may be a user or computer account or another Active Directory group.
172 When a member is added to a group the member may inherit permissions and rights from the group. Likewise, when permission or rights of a group are changed, the changes may reflect in the members through inheritance.
175 samba-tool group addmembers supergroup Group1,Group2,User1 -H ldap://samba.samdom.example.com -Uadministrator%passw0rd
177 Example1 shows how to add two groups, Group1 and Group2 and one user account, User1, to the existing AD group named supergroup. The command will be run on a remote server specified with the -H. The -U parameter is used to pass the userid and password of a user authorized to issue the command on the remote server.
180 sudo samba-tool group addmembers supergroup User2
182 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.
185 synopsis = "%prog <groupname> <listofmembers> [options]"
187 takes_optiongroups = {
188 "sambaopts": options.SambaOptions,
189 "versionopts": options.VersionOptions,
190 "credopts": options.CredentialsOptions,
194 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
195 metavar="URL", dest="H"),
198 takes_args = ["groupname", "listofmembers"]
200 def run(self, groupname, listofmembers, credopts=None, sambaopts=None,
201 versionopts=None, H=None):
203 lp = sambaopts.get_loadparm()
204 creds = credopts.get_credentials(lp, fallback_machine=True)
207 samdb = SamDB(url=H, session_info=system_session(),
208 credentials=creds, lp=lp)
209 samdb.add_remove_group_members(groupname, listofmembers, add_members_operation=True)
211 # FIXME: catch more specific exception
212 raise CommandError('Failed to add members "%s" to group "%s"' % (
213 listofmembers, groupname), e)
214 self.outf.write("Added members to group %s\n" % groupname)
217 class cmd_group_remove_members(Command):
218 """Remove members from an AD group
220 This command removes one or more members from an existing Active Directory group. The command accepts one or more group member names seperated by commas. A group member may be a user or computer account or another Active Directory group that is a member of the group specified on the command.
222 When a member is removed from a group, inherited permissions and rights will no longer apply to the member.
225 samba-tool group removemembers supergroup Group1 -H ldap://samba.samdom.example.com -Uadministrator%passw0rd
227 Example1 shows how to remove Group1 from supergroup. The command will run on the remote server specified on the -H parameter. The -U parameter is used to pass the userid and password of a user authorized to issue the command on the remote server.
230 sudo samba-tool group removemembers supergroup User1
232 Example2 shows how to remove a single user account, User2, from the supergroup AD group. It uses the sudo command to run as root when issuing the command.
235 synopsis = "%prog <groupname> <listofmembers> [options]"
237 takes_optiongroups = {
238 "sambaopts": options.SambaOptions,
239 "versionopts": options.VersionOptions,
240 "credopts": options.CredentialsOptions,
244 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
245 metavar="URL", dest="H"),
248 takes_args = ["groupname", "listofmembers"]
250 def run(self, groupname, listofmembers, credopts=None, sambaopts=None,
251 versionopts=None, H=None):
253 lp = sambaopts.get_loadparm()
254 creds = credopts.get_credentials(lp, fallback_machine=True)
257 samdb = SamDB(url=H, session_info=system_session(),
258 credentials=creds, lp=lp)
259 samdb.add_remove_group_members(groupname, listofmembers, add_members_operation=False)
261 # FIXME: Catch more specific exception
262 raise CommandError('Failed to remove members "%s" from group "%s"' % (listofmembers, groupname), e)
263 self.outf.write("Removed members from group %s\n" % groupname)
266 class cmd_group_list(Command):
267 """List all groups"""
269 synopsis = "%prog [options]"
272 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
273 metavar="URL", dest="H"),
276 takes_optiongroups = {
277 "sambaopts": options.SambaOptions,
278 "credopts": options.CredentialsOptions,
279 "versionopts": options.VersionOptions,
282 def run(self, sambaopts=None, credopts=None, versionopts=None, H=None):
283 lp = sambaopts.get_loadparm()
284 creds = credopts.get_credentials(lp, fallback_machine=True)
286 samdb = SamDB(url=H, session_info=system_session(),
287 credentials=creds, lp=lp)
289 domain_dn = samdb.domain_dn()
290 res = samdb.search(domain_dn, scope=ldb.SCOPE_SUBTREE,
291 expression=("(objectClass=group)"),
292 attrs=["samaccountname"])
297 self.outf.write("%s\n" % msg.get("samaccountname", idx=0))
300 class cmd_group_list_members(Command):
301 """List all members of an AD group
303 This command lists members from an existing Active Directory group. The command accepts one group name.
306 samba-tool group listmembers \"Domain Users\" -H ldap://samba.samdom.example.com -Uadministrator%passw0rd
309 synopsis = "%prog <groupname> [options]"
312 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
313 metavar="URL", dest="H"),
316 takes_optiongroups = {
317 "sambaopts": options.SambaOptions,
318 "credopts": options.CredentialsOptions,
319 "versionopts": options.VersionOptions,
322 takes_args = ["groupname"]
324 def run(self, groupname, credopts=None, sambaopts=None, versionopts=None, H=None):
325 lp = sambaopts.get_loadparm()
326 creds = credopts.get_credentials(lp, fallback_machine=True)
329 samdb = SamDB(url=H, session_info=system_session(),
330 credentials=creds, lp=lp)
332 search_filter = "(&(objectClass=group)(samaccountname=%s))" % groupname
333 res = samdb.search(samdb.domain_dn(), scope=ldb.SCOPE_SUBTREE,
334 expression=(search_filter),
340 group_dn = res[0].get('dn', idx=0)
341 object_sid = res[0].get('objectSid', idx=0)
343 object_sid = ndr_unpack(security.dom_sid, object_sid)
344 (group_dom_sid, rid) = object_sid.split()
346 search_filter = "(|(primaryGroupID=%s)(memberOf=%s))" % (rid, group_dn)
347 res = samdb.search(samdb.domain_dn(), scope=ldb.SCOPE_SUBTREE,
348 expression=(search_filter),
349 attrs=["samAccountName"])
355 self.outf.write("%s\n" % msg.get("samAccountName", idx=0))
358 raise CommandError('Failed to list members of "%s" group ' % groupname, e)
361 class cmd_group(SuperCommand):
362 """Group management"""
365 subcommands["add"] = cmd_group_add()
366 subcommands["delete"] = cmd_group_delete()
367 subcommands["addmembers"] = cmd_group_add_members()
368 subcommands["removemembers"] = cmd_group_remove_members()
369 subcommands["list"] = cmd_group_list()
370 subcommands["listmembers"] = cmd_group_list_members()