netcmd: user: readpasswords: move getpassword command to readpasswords
[Samba.git] / python / samba / netcmd / user / setpassword.py
blob6069a0113ce73819ea0da6b1f93ce956f91bf269
1 # user management
3 # user setpassword 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 from getpass import getpass
24 import samba.getopt as options
25 from samba import dsdb, generate_random_password, gensec, ldb
26 from samba.auth import system_session
27 from samba.netcmd import Command, CommandError, Option
28 from samba.samdb import SamDB
31 class cmd_user_setpassword(Command):
32 """Set or reset the password of a user account.
34 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.
36 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.
38 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.
40 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.
42 Example1:
43 samba-tool user setpassword TestUser1 --newpassword=passw0rd --URL=ldap://samba.samdom.example.com -Uadministrator%passw1rd
45 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.
47 Example2:
48 sudo samba-tool user setpassword TestUser2 --newpassword=passw0rd --must-change-at-next-login
50 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.
52 Example3:
53 samba-tool user setpassword --filter=samaccountname=TestUser3 --newpassword=passw0rd
55 Example3 shows how an administrator would reset TestUser3 user's password to passw0rd using the --filter= option to specify the username.
57 """
58 synopsis = "%prog (<username>|--filter <filter>) [options]"
60 takes_optiongroups = {
61 "sambaopts": options.SambaOptions,
62 "versionopts": options.VersionOptions,
63 "credopts": options.CredentialsOptions,
66 takes_options = [
67 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
68 metavar="URL", dest="H"),
69 Option("--filter", help="LDAP Filter to set password on", type=str),
70 Option("--newpassword", help="Set password", type=str),
71 Option("--must-change-at-next-login",
72 help="Force password to be changed on next login",
73 action="store_true"),
74 Option("--random-password",
75 help="Generate random password",
76 action="store_true"),
77 Option("--smartcard-required",
78 help="Require a smartcard for interactive logons",
79 action="store_true"),
80 Option("--clear-smartcard-required",
81 help="Don't require a smartcard for interactive logons",
82 action="store_true"),
85 takes_args = ["username?"]
87 def run(self, username=None, filter=None, credopts=None, sambaopts=None,
88 versionopts=None, H=None, newpassword=None,
89 must_change_at_next_login=False, random_password=False,
90 smartcard_required=False, clear_smartcard_required=False):
91 if filter is None and username is None:
92 raise CommandError("Either the username or '--filter' must be specified!")
94 password = newpassword
96 if smartcard_required:
97 if password is not None and password != '':
98 raise CommandError('It is not allowed to specify '
99 '--newpassword '
100 'together with --smartcard-required.')
101 if must_change_at_next_login:
102 raise CommandError('It is not allowed to specify '
103 '--must-change-at-next-login '
104 'together with --smartcard-required.')
105 if clear_smartcard_required:
106 raise CommandError('It is not allowed to specify '
107 '--clear-smartcard-required '
108 'together with --smartcard-required.')
110 if random_password and not smartcard_required:
111 password = generate_random_password(128, 255)
113 while True:
114 if smartcard_required:
115 break
116 if password is not None and password != '':
117 break
118 password = getpass("New Password: ")
119 passwordverify = getpass("Retype Password: ")
120 if not password == passwordverify:
121 password = None
122 self.outf.write("Sorry, passwords do not match.\n")
124 if filter is None:
125 filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
127 lp = sambaopts.get_loadparm()
128 creds = credopts.get_credentials(lp)
130 creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)
132 samdb = SamDB(url=H, session_info=system_session(),
133 credentials=creds, lp=lp)
135 if smartcard_required:
136 command = ""
137 try:
138 command = "Failed to set UF_SMARTCARD_REQUIRED for user '%s'" % (username or filter)
139 flags = dsdb.UF_SMARTCARD_REQUIRED
140 samdb.toggle_userAccountFlags(filter, flags, on=True)
141 command = "Failed to enable account for user '%s'" % (username or filter)
142 samdb.enable_account(filter)
143 except Exception as msg:
144 # FIXME: catch more specific exception
145 raise CommandError("%s: %s" % (command, msg))
146 self.outf.write("Added UF_SMARTCARD_REQUIRED OK\n")
147 else:
148 command = ""
149 try:
150 if clear_smartcard_required:
151 command = "Failed to remove UF_SMARTCARD_REQUIRED for user '%s'" % (username or filter)
152 flags = dsdb.UF_SMARTCARD_REQUIRED
153 samdb.toggle_userAccountFlags(filter, flags, on=False)
154 command = "Failed to set password for user '%s'" % (username or filter)
155 samdb.setpassword(filter, password,
156 force_change_at_next_login=must_change_at_next_login,
157 username=username)
158 except Exception as msg:
159 # FIXME: catch more specific exception
160 raise CommandError("%s: %s" % (command, msg))
161 self.outf.write("Changed password OK\n")