samba-tool: Unify usage messages.
[Samba/gebeck_regimport.git] / source4 / scripting / python / samba / netcmd / user.py
blob914e47f984511afe0569bd7e05f741b2a6a4cdc1
1 # user management
3 # Copyright Jelmer Vernooij 2010 <jelmer@samba.org>
4 # Copyright Theresa Halloran 2011 <theresahalloran@gmail.com>
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 import samba.getopt as options
21 import ldb
22 from getpass import getpass
23 from samba.auth import system_session
24 from samba.samdb import SamDB
25 from samba import (
26 dsdb,
27 gensec,
28 generate_random_password,
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 """Create 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 takes_optiongroups = {
104 "sambaopts": options.SambaOptions,
105 "credopts": options.CredentialsOptions,
106 "versionopts": options.VersionOptions,
109 def run(self, username, password=None, credopts=None, sambaopts=None,
110 versionopts=None, H=None, must_change_at_next_login=False,
111 random_password=False, use_username_as_cn=False, userou=None,
112 surname=None, given_name=None, initials=None, profile_path=None,
113 script_path=None, home_drive=None, home_directory=None,
114 job_title=None, department=None, company=None, description=None,
115 mail_address=None, internet_address=None, telephone_number=None,
116 physical_delivery_office=None):
118 if random_password:
119 password = generate_random_password(128, 255)
121 while True:
122 if password is not None and password is not '':
123 break
124 password = getpass("New Password: ")
125 passwordverify = getpass("Retype Password: ")
126 if not password == passwordverify:
127 password = None
128 self.outf.write("Sorry, passwords do not match.\n")
130 lp = sambaopts.get_loadparm()
131 creds = credopts.get_credentials(lp)
133 try:
134 samdb = SamDB(url=H, session_info=system_session(),
135 credentials=creds, lp=lp)
136 samdb.newuser(username, password, force_password_change_at_next_login_req=must_change_at_next_login,
137 useusernameascn=use_username_as_cn, userou=userou, surname=surname, givenname=given_name, initials=initials,
138 profilepath=profile_path, homedrive=home_drive, scriptpath=script_path, homedirectory=home_directory,
139 jobtitle=job_title, department=department, company=company, description=description,
140 mailaddress=mail_address, internetaddress=internet_address,
141 telephonenumber=telephone_number, physicaldeliveryoffice=physical_delivery_office)
142 except Exception, e:
143 raise CommandError("Failed to add user '%s': " % username, e)
145 self.outf.write("User '%s' created successfully\n" % username)
148 class cmd_user_add(cmd_user_create):
149 __doc__ = cmd_user_create.__doc__
150 # take this print out after the add subcommand is removed.
151 # the add subcommand is deprecated but left in for now to allow people to
152 # migrate to create
154 def run(self, *args, **kwargs):
155 self.err.write(
156 "Note: samba-tool user add is deprecated. "
157 "Please use samba-tool user create for the same function.\n")
158 return super(self, cmd_user_add).run(*args, **kwargs)
161 class cmd_user_delete(Command):
162 """Delete a user.
164 This command deletes a user account from the Active Directory domain. The username specified on the command is the sAMAccountName.
166 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.
168 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.
170 Example1:
171 samba-tool user delete User1 -H ldap://samba.samdom.example.com --username=administrator --password=passw1rd
173 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.
175 Example2:
176 sudo samba-tool user delete User2
178 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.
181 synopsis = "%prog <username> [options]"
183 takes_options = [
184 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
185 metavar="URL", dest="H"),
188 takes_args = ["username"]
189 takes_optiongroups = {
190 "sambaopts": options.SambaOptions,
191 "credopts": options.CredentialsOptions,
192 "versionopts": options.VersionOptions,
195 def run(self, username, credopts=None, sambaopts=None, versionopts=None,
196 H=None):
197 lp = sambaopts.get_loadparm()
198 creds = credopts.get_credentials(lp, fallback_machine=True)
200 try:
201 samdb = SamDB(url=H, session_info=system_session(),
202 credentials=creds, lp=lp)
203 samdb.deleteuser(username)
204 except Exception, e:
205 raise CommandError('Failed to remove user "%s"' % username, e)
206 self.outf.write("Deleted user %s\n" % username)
209 class cmd_user_list(Command):
210 """List all users."""
212 synopsis = "%prog [options]"
214 takes_options = [
215 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
216 metavar="URL", dest="H"),
219 takes_optiongroups = {
220 "sambaopts": options.SambaOptions,
221 "credopts": options.CredentialsOptions,
222 "versionopts": options.VersionOptions,
225 def run(self, sambaopts=None, credopts=None, versionopts=None, H=None):
226 lp = sambaopts.get_loadparm()
227 creds = credopts.get_credentials(lp, fallback_machine=True)
229 samdb = SamDB(url=H, session_info=system_session(),
230 credentials=creds, lp=lp)
232 domain_dn = samdb.domain_dn()
233 res = samdb.search(domain_dn, scope=ldb.SCOPE_SUBTREE,
234 expression=("(&(objectClass=user)(userAccountControl:%s:=%u))"
235 % (ldb.OID_COMPARATOR_AND, dsdb.UF_NORMAL_ACCOUNT)),
236 attrs=["samaccountname"])
237 if (len(res) == 0):
238 return
240 for msg in res:
241 self.outf.write("%s\n" % msg.get("samaccountname", idx=0))
244 class cmd_user_enable(Command):
245 """Enable an user.
247 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.
249 There are many reasons why an account may become disabled. These include:
250 - If a user exceeds the account policy for logon attempts
251 - If an administrator disables the account
252 - If the account expires
254 The samba-tool user enable command allows an administrator to enable an account which has become disabled.
256 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.
258 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.
260 Example1:
261 samba-tool user enable Testuser1 --URL=ldap://samba.samdom.example.com --username=administrator --password=passw1rd
263 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.
265 Exampl2:
266 su samba-tool user enable Testuser2
268 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.
270 Example3:
271 samba-tool user enable --filter=samaccountname=Testuser3
273 Example3 shows how to enable a user in the domain against a local LDAP server. It uses the --filter=samaccountname to specify the username.
276 synopsis = "%prog (<username>|--filter <filter>) [options]"
279 takes_optiongroups = {
280 "sambaopts": options.SambaOptions,
281 "versionopts": options.VersionOptions,
282 "credopts": options.CredentialsOptions,
285 takes_options = [
286 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
287 metavar="URL", dest="H"),
288 Option("--filter", help="LDAP Filter to set password on", type=str),
291 takes_args = ["username?"]
293 def run(self, username=None, sambaopts=None, credopts=None,
294 versionopts=None, filter=None, H=None):
295 if username is None and filter is None:
296 raise CommandError("Either the username or '--filter' must be specified!")
298 if filter is None:
299 filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
301 lp = sambaopts.get_loadparm()
302 creds = credopts.get_credentials(lp, fallback_machine=True)
304 samdb = SamDB(url=H, session_info=system_session(),
305 credentials=creds, lp=lp)
306 try:
307 samdb.enable_account(filter)
308 except Exception, msg:
309 raise CommandError("Failed to enable user '%s': %s" % (username or filter, msg))
310 self.outf.write("Enabled user '%s'\n" % (username or filter))
313 class cmd_user_disable(Command):
314 """Disable an user."""
316 synopsis = "%prog (<username>|--filter <filter>) [options]"
318 takes_options = [
319 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
320 metavar="URL", dest="H"),
321 Option("--filter", help="LDAP Filter to set password on", type=str),
324 takes_args = ["username?"]
326 takes_optiongroups = {
327 "sambaopts": options.SambaOptions,
328 "credopts": options.CredentialsOptions,
329 "versionopts": options.VersionOptions,
332 def run(self, username=None, sambaopts=None, credopts=None,
333 versionopts=None, filter=None, H=None):
334 if username is None and filter is None:
335 raise CommandError("Either the username or '--filter' must be specified!")
337 if filter is None:
338 filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
340 lp = sambaopts.get_loadparm()
341 creds = credopts.get_credentials(lp, fallback_machine=True)
343 samdb = SamDB(url=H, session_info=system_session(),
344 credentials=creds, lp=lp)
345 try:
346 samdb.disable_account(filter)
347 except Exception, msg:
348 raise CommandError("Failed to disable user '%s': %s" % (username or filter, msg))
351 class cmd_user_setexpiry(Command):
352 """Set the expiration of a user account.
354 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.
356 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.
358 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.
360 Example1:
361 samba-tool user setexpiry User1 --days=20 --URL=ldap://samba.samdom.example.com --username=administrator --password=passw1rd
363 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.
365 Exampl2:
366 su samba-tool user setexpiry User2
368 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.
370 Example3:
371 samba-tool user setexpiry --days=20 --filter=samaccountname=User3
373 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.
375 Example4:
376 samba-tool user setexpiry --noexpiry User4
377 Example4 shows how to set the account expiration so that it will never expire. The username and sAMAccountName in this example is User4.
380 synopsis = "%prog (<username>|--filter <filter>) [options]"
382 takes_optiongroups = {
383 "sambaopts": options.SambaOptions,
384 "versionopts": options.VersionOptions,
385 "credopts": options.CredentialsOptions,
388 takes_options = [
389 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
390 metavar="URL", dest="H"),
391 Option("--filter", help="LDAP Filter to set password on", type=str),
392 Option("--days", help="Days to expiry", type=int, default=0),
393 Option("--noexpiry", help="Password does never expire", action="store_true", default=False),
396 takes_args = ["username?"]
398 def run(self, username=None, sambaopts=None, credopts=None,
399 versionopts=None, H=None, filter=None, days=None, noexpiry=None):
400 if username is None and filter is None:
401 raise CommandError("Either the username or '--filter' must be specified!")
403 if filter is None:
404 filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
406 lp = sambaopts.get_loadparm()
407 creds = credopts.get_credentials(lp)
409 samdb = SamDB(url=H, session_info=system_session(),
410 credentials=creds, lp=lp)
412 try:
413 samdb.setexpiry(filter, days*24*3600, no_expiry_req=noexpiry)
414 except Exception, msg:
415 # FIXME: Catch more specific exception
416 raise CommandError("Failed to set expiry for user '%s': %s" % (
417 username or filter, msg))
418 self.outf.write("Set expiry for user '%s' to %u days\n" % (
419 username or filter, days))
422 class cmd_user_password(Command):
423 """Change password for a user account (the one provided in authentication).
426 synopsis = "%prog [options]"
428 takes_options = [
429 Option("--newpassword", help="New password", type=str),
432 takes_optiongroups = {
433 "sambaopts": options.SambaOptions,
434 "credopts": options.CredentialsOptions,
435 "versionopts": options.VersionOptions,
438 def run(self, credopts=None, sambaopts=None, versionopts=None,
439 newpassword=None):
441 lp = sambaopts.get_loadparm()
442 creds = credopts.get_credentials(lp)
444 # get old password now, to get the password prompts in the right order
445 old_password = creds.get_password()
447 net = Net(creds, lp, server=credopts.ipaddress)
449 password = newpassword
450 while True:
451 if password is not None and password is not '':
452 break
453 password = getpass("New Password: ")
454 passwordverify = getpass("Retype Password: ")
455 if not password == passwordverify:
456 password = None
457 self.outf.write("Sorry, passwords do not match.\n")
459 try:
460 net.change_password(password)
461 except Exception, msg:
462 # FIXME: catch more specific exception
463 raise CommandError("Failed to change password : %s" % msg)
464 self.outf.write("Changed password OK\n")
467 class cmd_user_setpassword(Command):
468 """Set or reset the password of a user account.
470 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.
472 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.
474 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.
476 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.
478 Example1:
479 samba-tool user setpassword TestUser1 passw0rd --URL=ldap://samba.samdom.example.com -Uadministrator%passw1rd
481 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.
483 Example2:
484 sudo samba-tool user setpassword TestUser2 passw0rd --must-change-at-next-login
486 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.
488 Example3:
489 samba-tool user setpassword --filter=samaccountname=TestUser3 --password=passw0rd
491 Example3 shows how an administrator would reset TestUser3 user's password to passw0rd using the --filter= option to specify the username.
494 synopsis = "%prog (<username>|--filter <filter>) [options]"
496 takes_optiongroups = {
497 "sambaopts": options.SambaOptions,
498 "versionopts": options.VersionOptions,
499 "credopts": options.CredentialsOptions,
502 takes_options = [
503 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
504 metavar="URL", dest="H"),
505 Option("--filter", help="LDAP Filter to set password on", type=str),
506 Option("--newpassword", help="Set password", type=str),
507 Option("--must-change-at-next-login",
508 help="Force password to be changed on next login",
509 action="store_true"),
510 Option("--random-password",
511 help="Generate random password",
512 action="store_true"),
515 takes_args = ["username?"]
517 def run(self, username=None, filter=None, credopts=None, sambaopts=None,
518 versionopts=None, H=None, newpassword=None,
519 must_change_at_next_login=False, random_password=False):
520 if filter is None and username is None:
521 raise CommandError("Either the username or '--filter' must be specified!")
523 if random_password:
524 password = generate_random_password(128, 255)
525 else:
526 password = newpassword
528 while 1:
529 if password is not None and password is not '':
530 break
531 password = getpass("New Password: ")
533 if filter is None:
534 filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
536 lp = sambaopts.get_loadparm()
537 creds = credopts.get_credentials(lp)
539 creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)
541 samdb = SamDB(url=H, session_info=system_session(),
542 credentials=creds, lp=lp)
544 try:
545 samdb.setpassword(filter, password,
546 force_change_at_next_login=must_change_at_next_login,
547 username=username)
548 except Exception, msg:
549 # FIXME: catch more specific exception
550 raise CommandError("Failed to set password for user '%s': %s" % (username or filter, msg))
551 self.outf.write("Changed password OK\n")
554 class cmd_user(SuperCommand):
555 """User management"""
557 subcommands = {}
558 subcommands["add"] = cmd_user_create()
559 subcommands["create"] = cmd_user_create()
560 subcommands["delete"] = cmd_user_delete()
561 subcommands["disable"] = cmd_user_disable()
562 subcommands["enable"] = cmd_user_enable()
563 subcommands["list"] = cmd_user_list()
564 subcommands["setexpiry"] = cmd_user_setexpiry()
565 subcommands["password"] = cmd_user_password()
566 subcommands["setpassword"] = cmd_user_setpassword()