s4 dns: Check more of the returned values for the A query
[Samba/gebeck_regimport.git] / source4 / scripting / python / samba / netcmd / user.py
blob23c751525911c4a292f936da91d1f5f97e0e7bb6
1 #!/usr/bin/env python
3 # user management
5 # Copyright Jelmer Vernooij 2010 <jelmer@samba.org>
6 # Copyright Theresa Halloran 2011 <theresahalloran@gmail.com>
7 # Copyright Giampaolo Lauria 2011 <lauria2@yahoo.com>
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 3 of the License, or
12 # (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 import samba.getopt as options
24 import sys, ldb
25 from getpass import getpass
26 from samba.auth import system_session
27 from samba.samdb import SamDB
28 from samba import gensec, generate_random_password
29 from samba import dsdb
30 from samba.net import Net
32 from samba.netcmd import (
33 Command,
34 CommandError,
35 SuperCommand,
36 Option,
40 class cmd_user_create(Command):
41 """Creates a new user
43 This command creates a new user account in the Active Directory domain. The username specified on the command is the sAMaccountName.
45 User accounts may represent physical entities, such as people or may be used as service accounts for applications. User accounts are also referred to as security principals and are assigned a security identifier (SID).
47 A user account enables a user to logon to a computer and domain with an identity that can be authenticated. To maximize security, each user should have their own unique user account and password. A user's access to domain resources is based on permissions assigned to the user account.
49 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.
51 Example1:
52 samba-tool user add User1 passw0rd --given-name=John --surname=Smith --must-change-at-next-login -H ldap://samba.samdom.example.com -Uadministrator%passw1rd
54 Example1 shows how to create a new user in the domain against a remote LDAP server. The -H parameter is used to specify the remote target server. The -U option is used to pass the userid and password authorized to issue the command remotely.
56 Example2:
57 sudo samba-tool user add User2 passw2rd --given-name=Jane --surname=Doe --must-change-at-next-login
59 Example2 shows how to create a new user in the domain against the local server. sudo is used so a user may run the command as root. In this example, after User2 is created, he/she will be forced to change their password when they logon.
61 Example3:
62 samba-tool user add User3 passw3rd --userou=OrgUnit
64 Example3 shows how to create a new user in the OrgUnit organizational unit.
66 """
67 synopsis = "%prog <username> [<password>] [options]"
69 takes_options = [
70 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
71 metavar="URL", dest="H"),
72 Option("--must-change-at-next-login",
73 help="Force password to be changed on next login",
74 action="store_true"),
75 Option("--random-password",
76 help="Generate random password",
77 action="store_true"),
78 Option("--use-username-as-cn",
79 help="Force use of username as user's CN",
80 action="store_true"),
81 Option("--userou",
82 help="Alternative location (without domainDN counterpart) to default CN=Users in which new user object will be created",
83 type=str),
84 Option("--surname", help="User's surname", type=str),
85 Option("--given-name", help="User's given name", type=str),
86 Option("--initials", help="User's initials", type=str),
87 Option("--profile-path", help="User's profile path", type=str),
88 Option("--script-path", help="User's logon script path", type=str),
89 Option("--home-drive", help="User's home drive letter", type=str),
90 Option("--home-directory", help="User's home directory path", type=str),
91 Option("--job-title", help="User's job title", type=str),
92 Option("--department", help="User's department", type=str),
93 Option("--company", help="User's company", type=str),
94 Option("--description", help="User's description", type=str),
95 Option("--mail-address", help="User's email address", type=str),
96 Option("--internet-address", help="User's home page", type=str),
97 Option("--telephone-number", help="User's phone number", type=str),
98 Option("--physical-delivery-office", help="User's office location", type=str),
101 takes_args = ["username", "password?"]
103 def run(self, username, password=None, credopts=None, sambaopts=None,
104 versionopts=None, H=None, must_change_at_next_login=False, random_password=False,
105 use_username_as_cn=False, userou=None, surname=None, given_name=None, initials=None,
106 profile_path=None, script_path=None, home_drive=None, home_directory=None,
107 job_title=None, department=None, company=None, description=None,
108 mail_address=None, internet_address=None, telephone_number=None, physical_delivery_office=None):
110 if random_password:
111 password = generate_random_password(128, 255)
113 while 1:
114 if password is not None and password is not '':
115 break
116 password = getpass("New Password: ")
118 lp = sambaopts.get_loadparm()
119 creds = credopts.get_credentials(lp)
121 try:
122 samdb = SamDB(url=H, session_info=system_session(),
123 credentials=creds, lp=lp)
124 samdb.newuser(username, password,
125 force_password_change_at_next_login_req=must_change_at_next_login,
126 useusernameascn=use_username_as_cn, userou=userou, surname=surname, givenname=given_name, initials=initials,
127 profilepath=profile_path, homedrive=home_drive, scriptpath=script_path, homedirectory=home_directory,
128 jobtitle=job_title, department=department, company=company, description=description,
129 mailaddress=mail_address, internetaddress=internet_address,
130 telephonenumber=telephone_number, physicaldeliveryoffice=physical_delivery_office)
131 except Exception, e:
132 raise CommandError("Failed to add user '%s': " % username, e)
134 self.outf.write("User '%s' created successfully\n" % username)
137 class cmd_user_add(cmd_user_create):
138 __doc__ = cmd_user_create.__doc__
139 # take this print out after the add subcommand is removed.
140 # the add subcommand is deprecated but left in for now to allow people to migrate to create
142 def run(self, *args, **kwargs):
143 self.err.write("\nNote: samba-tool user add is deprecated. Please use samba-tool user create for the same function.\n")
144 return super(self, cmd_user_add).run(*args, **kwargs)
147 class cmd_user_delete(Command):
148 """Deletes a user
150 This command deletes a user account from the Active Directory domain. The username specified on the command is the sAMAccountName.
152 Once the account is deleted, all permissions and memberships associated with that account are deleted. If a new user account is added with the same name as a previously deleted account name, the new user does not have the previous permissions. The new account user will be assigned a new security identifier (SID) and permissions and memberships will have to be added.
154 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.
156 Example1:
157 samba-tool user delete User1 -H ldap://samba.samdom.example.com --username=administrator --password=passw1rd
159 Example1 shows how to delete a user in the domain against a remote LDAP server. The -H parameter is used to specify the remote target server. The --username= and --password= options are used to pass the username and password of a user that exists on the remote server and is authorized to issue the command on that server.
161 Example2:
162 sudo samba-tool user delete User2
164 Example2 shows how to delete a user in the domain against the local server. sudo is used so a user may run the command as root.
167 synopsis = "%prog <username> [options]"
169 takes_options = [
170 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
171 metavar="URL", dest="H"),
174 takes_args = ["username"]
176 def run(self, username, credopts=None, sambaopts=None, versionopts=None, H=None):
178 lp = sambaopts.get_loadparm()
179 creds = credopts.get_credentials(lp, fallback_machine=True)
181 try:
182 samdb = SamDB(url=H, session_info=system_session(),
183 credentials=creds, lp=lp)
184 samdb.deleteuser(username)
185 except Exception, e:
186 raise CommandError('Failed to remove user "%s"' % username, e)
187 self.outf.write("Deleted user %s\n" % username)
190 class cmd_user_list(Command):
191 """List all users"""
193 synopsis = "%prog [options]"
195 takes_options = [
196 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
197 metavar="URL", dest="H"),
200 def run(self, sambaopts=None, credopts=None, versionopts=None, H=None):
201 lp = sambaopts.get_loadparm()
202 creds = credopts.get_credentials(lp, fallback_machine=True)
204 samdb = SamDB(url=H, session_info=system_session(),
205 credentials=creds, lp=lp)
207 domain_dn = samdb.domain_dn()
208 res = samdb.search(domain_dn, scope=ldb.SCOPE_SUBTREE,
209 expression=("(&(objectClass=user)(userAccountControl:%s:=%u))"
210 % (ldb.OID_COMPARATOR_AND, dsdb.UF_NORMAL_ACCOUNT)),
211 attrs=["samaccountname"])
212 if (len(res) == 0):
213 return
215 for msg in res:
216 self.outf.write("%s\n" % msg.get("samaccountname", idx=0))
219 class cmd_user_enable(Command):
220 """Enables a user
222 This command enables a user account for logon to an Active Directory domain. The username specified on the command is the sAMAccountName. The username may also be specified using the --filter option.
224 There are many reasons why an account may become disabled. These include:
225 - If a user exceeds the account policy for logon attempts
226 - If an administrator disables the account
227 - If the account expires
229 The samba-tool user enable command allows an administrator to enable an account which has become disabled.
231 Additionally, the enable function allows an administrator to have a set of created user accounts defined and setup with default permissions that can be easily enabled for use.
233 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.
235 Example1:
236 samba-tool user enable Testuser1 --URL=ldap://samba.samdom.example.com --username=administrator --password=passw1rd
238 Example1 shows how to enable a user in the domain against a remote LDAP server. The --URL parameter is used to specify the remote target server. The --username= and --password= options are used to pass the username and password of a user that exists on the remote server and is authorized to update that server.
240 Exampl2:
241 su samba-tool user enable Testuser2
243 Example2 shows how to enable user Testuser2 for use in the domain on the local server. sudo is used so a user may run the command as root.
245 Example3:
246 samba-tool user enable --filter=samaccountname=Testuser3
248 Example3 shows how to enable a user in the domain against a local LDAP server. It uses the --filter=samaccountname to specify the username.
251 synopsis = "%prog (<username>|--filter <filter>) [options]"
253 takes_options = [
254 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
255 metavar="URL", dest="H"),
256 Option("--filter", help="LDAP Filter to set password on", type=str),
259 takes_args = ["username?"]
261 def run(self, username=None, sambaopts=None, credopts=None,
262 versionopts=None, filter=None, H=None):
263 if username is None and filter is None:
264 raise CommandError("Either the username or '--filter' must be specified!")
266 if filter is None:
267 filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
269 lp = sambaopts.get_loadparm()
270 creds = credopts.get_credentials(lp, fallback_machine=True)
272 samdb = SamDB(url=H, session_info=system_session(),
273 credentials=creds, lp=lp)
274 try:
275 samdb.enable_account(filter)
276 except Exception, msg:
277 raise CommandError("Failed to enable user '%s': %s" % (username or filter, msg))
278 self.outf.write("Enabled user '%s'\n" % (username or filter))
281 class cmd_user_disable(Command):
282 """Disable a user"""
284 synopsis = "%prog (<username>|--filter <filter>) [options]"
286 takes_options = [
287 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
288 metavar="URL", dest="H"),
289 Option("--filter", help="LDAP Filter to set password on", type=str),
292 takes_args = ["username?"]
294 def run(self, username=None, sambaopts=None, credopts=None,
295 versionopts=None, filter=None, H=None):
296 if username is None and filter is None:
297 raise CommandError("Either the username or '--filter' must be specified!")
299 if filter is None:
300 filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
302 lp = sambaopts.get_loadparm()
303 creds = credopts.get_credentials(lp, fallback_machine=True)
305 samdb = SamDB(url=H, session_info=system_session(),
306 credentials=creds, lp=lp)
307 try:
308 samdb.disable_account(filter)
309 except Exception, msg:
310 raise CommandError("Failed to disable user '%s': %s" % (username or filter, msg))
313 class cmd_user_setexpiry(Command):
314 """Sets the expiration of a user account
316 This command sets the expiration of a user account. The username specified on the command is the sAMAccountName. The username may also be specified using the --filter option.
318 When a user account expires, it becomes disabled and the user is unable to logon. The administrator may issue the samba-tool user enable command to enable the account for logon. The permissions and memberships associated with the account are retained when the account is enabled.
320 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.
322 Example1:
323 samba-tool user setexpiry User1 --days=20 --URL=ldap://samba.samdom.example.com --username=administrator --password=passw1rd
325 Example1 shows how to set the expiration of an account in a remote LDAP server. The --URL parameter is used to specify the remote target server. The --username= and --password= options are used to pass the username and password of a user that exists on the remote server and is authorized to update that server.
327 Exampl2:
328 su samba-tool user setexpiry User2
330 Example2 shows how to set the account expiration of user User2 so it will never expire. The user in this example resides on the local server. sudo is used so a user may run the command as root.
332 Example3:
333 samba-tool user setexpiry --days=20 --filter=samaccountname=User3
335 Example3 shows how to set the account expiration date to end of day 20 days from the current day. The username or sAMAccountName is specified using the --filter= paramter and the username in this example is User3.
337 Example4:
338 samba-tool user setexpiry --noexpiry User4
339 Example4 shows how to set the account expiration so that it will never expire. The username and sAMAccountName in this example is User4.
342 synopsis = "%prog (<username>|--filter <filter>) [options]"
344 takes_options = [
345 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
346 metavar="URL", dest="H"),
347 Option("--filter", help="LDAP Filter to set password on", type=str),
348 Option("--days", help="Days to expiry", type=int, default=0),
349 Option("--noexpiry", help="Password does never expire", action="store_true", default=False),
352 takes_args = ["username?"]
354 def run(self, username=None, sambaopts=None, credopts=None,
355 versionopts=None, H=None, filter=None, days=None, noexpiry=None):
356 if username is None and filter is None:
357 raise CommandError("Either the username or '--filter' must be specified!")
359 if filter is None:
360 filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
362 lp = sambaopts.get_loadparm()
363 creds = credopts.get_credentials(lp)
365 samdb = SamDB(url=H, session_info=system_session(),
366 credentials=creds, lp=lp)
368 try:
369 samdb.setexpiry(filter, days*24*3600, no_expiry_req=noexpiry)
370 except Exception, msg:
371 # FIXME: Catch more specific exception
372 raise CommandError("Failed to set expiry for user '%s': %s" % (
373 username or filter, msg))
374 self.outf.write("Set expiry for user '%s' to %u days\n" % (
375 username or filter, days))
378 class cmd_user_password(Command):
379 """Change password for a user account (the one provided in authentication)
385 synopsis = "%prog [options]"
387 takes_options = [
388 Option("--newpassword", help="New password", type=str),
391 def run(self, credopts=None, sambaopts=None, versionopts=None,
392 newpassword=None):
394 lp = sambaopts.get_loadparm()
395 creds = credopts.get_credentials(lp)
397 # get old password now, to get the password prompts in the right order
398 old_password = creds.get_password()
400 net = Net(creds, lp, server=credopts.ipaddress)
402 password = newpassword
403 while 1:
404 if password is not None and password is not '':
405 break
406 password = getpass("New Password: ")
408 try:
409 net.change_password(password)
410 except Exception, msg:
411 # FIXME: catch more specific exception
412 raise CommandError("Failed to change password : %s" % msg)
413 self.outf.write("Changed password OK\n")
416 class cmd_user_setpassword(Command):
417 """Sets or resets the password of a user account
419 This command sets or resets the logon password for a user account. The username specified on the command is the sAMAccountName. The username may also be specified using the --filter option.
421 If the password is not specified on the command through the --newpassword parameter, the user is prompted for the password to be entered through the command line.
423 It is good security practice for the administrator to use the --must-change-at-next-login option which requires that when the user logs on to the account for the first time following the password change, he/she must change the password.
425 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.
427 Example1:
428 samba-tool user setpassword TestUser1 passw0rd --URL=ldap://samba.samdom.example.com -Uadministrator%passw1rd
430 Example1 shows how to set the password of user 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.
432 Example2:
433 sudo samba-tool user setpassword TestUser2 passw0rd --must-change-at-next-login
435 Example2 shows how an administrator would reset the TestUser2 user's password to passw0rd. The user is running under the root userid using the sudo command. In this example the user TestUser2 must change their password the next time they logon to the account.
437 Example3:
438 samba-tool user setpassword --filter=samaccountname=TestUser3 --password=passw0rd
440 Example3 shows how an administrator would reset TestUser3 user's password to passw0rd using the --filter= option to specify the username.
443 synopsis = "%prog (<username>|--filter <filter>) [options]"
445 takes_options = [
446 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
447 metavar="URL", dest="H"),
448 Option("--filter", help="LDAP Filter to set password on", type=str),
449 Option("--newpassword", help="Set password", type=str),
450 Option("--must-change-at-next-login",
451 help="Force password to be changed on next login",
452 action="store_true"),
453 Option("--random-password",
454 help="Generate random password",
455 action="store_true"),
458 takes_args = ["username?"]
460 def run(self, username=None, filter=None, credopts=None, sambaopts=None,
461 versionopts=None, H=None, newpassword=None,
462 must_change_at_next_login=False, random_password=False):
463 if filter is None and username is None:
464 raise CommandError("Either the username or '--filter' must be specified!")
466 if random_password:
467 password = generate_random_password(128, 255)
468 else:
469 password = newpassword
471 while 1:
472 if password is not None and password is not '':
473 break
474 password = getpass("New Password: ")
476 if filter is None:
477 filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
479 lp = sambaopts.get_loadparm()
480 creds = credopts.get_credentials(lp)
482 creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)
484 samdb = SamDB(url=H, session_info=system_session(),
485 credentials=creds, lp=lp)
487 try:
488 samdb.setpassword(filter, password,
489 force_change_at_next_login=must_change_at_next_login,
490 username=username)
491 except Exception, msg:
492 # FIXME: catch more specific exception
493 raise CommandError("Failed to set password for user '%s': %s" % (username or filter, msg))
494 self.outf.write("Changed password OK\n")
497 class cmd_user(SuperCommand):
498 """User management"""
500 subcommands = {}
501 subcommands["add"] = cmd_user_create()
502 subcommands["create"] = cmd_user_create()
503 subcommands["delete"] = cmd_user_delete()
504 subcommands["disable"] = cmd_user_disable()
505 subcommands["enable"] = cmd_user_enable()
506 subcommands["list"] = cmd_user_list()
507 subcommands["setexpiry"] = cmd_user_setexpiry()
508 subcommands["password"] = cmd_user_password()
509 subcommands["setpassword"] = cmd_user_setpassword()