mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
netcmd: user: move user setpassword command
Signed-off-by: Rob van der Linde <rob@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
a6e1b5694f
commit
65fc147205
@ -26,7 +26,6 @@ import errno
|
|||||||
import time
|
import time
|
||||||
import base64
|
import base64
|
||||||
from subprocess import Popen, PIPE, STDOUT, check_call, CalledProcessError
|
from subprocess import Popen, PIPE, STDOUT, check_call, CalledProcessError
|
||||||
from getpass import getpass
|
|
||||||
from samba.auth import system_session
|
from samba.auth import system_session
|
||||||
from samba.samdb import SamDB, SamDBError
|
from samba.samdb import SamDB, SamDBError
|
||||||
from samba.dcerpc import misc
|
from samba.dcerpc import misc
|
||||||
@ -34,8 +33,6 @@ from samba.dcerpc import security
|
|||||||
from samba.ndr import ndr_unpack
|
from samba.ndr import ndr_unpack
|
||||||
from samba import (
|
from samba import (
|
||||||
dsdb,
|
dsdb,
|
||||||
gensec,
|
|
||||||
generate_random_password,
|
|
||||||
Ldb,
|
Ldb,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -65,142 +62,10 @@ from .getgroups import cmd_user_getgroups
|
|||||||
from .list import cmd_user_list
|
from .list import cmd_user_list
|
||||||
from .password import cmd_user_password
|
from .password import cmd_user_password
|
||||||
from .setexpiry import cmd_user_setexpiry
|
from .setexpiry import cmd_user_setexpiry
|
||||||
|
from .setpassword import cmd_user_setpassword
|
||||||
from .setprimarygroup import cmd_user_setprimarygroup
|
from .setprimarygroup import cmd_user_setprimarygroup
|
||||||
|
|
||||||
|
|
||||||
class cmd_user_setpassword(Command):
|
|
||||||
"""Set or reset the password of a user account.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Example1:
|
|
||||||
samba-tool user setpassword TestUser1 --newpassword=passw0rd --URL=ldap://samba.samdom.example.com -Uadministrator%passw1rd
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Example2:
|
|
||||||
sudo samba-tool user setpassword TestUser2 --newpassword=passw0rd --must-change-at-next-login
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Example3:
|
|
||||||
samba-tool user setpassword --filter=samaccountname=TestUser3 --newpassword=passw0rd
|
|
||||||
|
|
||||||
Example3 shows how an administrator would reset TestUser3 user's password to passw0rd using the --filter= option to specify the username.
|
|
||||||
|
|
||||||
"""
|
|
||||||
synopsis = "%prog (<username>|--filter <filter>) [options]"
|
|
||||||
|
|
||||||
takes_optiongroups = {
|
|
||||||
"sambaopts": options.SambaOptions,
|
|
||||||
"versionopts": options.VersionOptions,
|
|
||||||
"credopts": options.CredentialsOptions,
|
|
||||||
}
|
|
||||||
|
|
||||||
takes_options = [
|
|
||||||
Option("-H", "--URL", help="LDB URL for database or target server", type=str,
|
|
||||||
metavar="URL", dest="H"),
|
|
||||||
Option("--filter", help="LDAP Filter to set password on", type=str),
|
|
||||||
Option("--newpassword", help="Set password", type=str),
|
|
||||||
Option("--must-change-at-next-login",
|
|
||||||
help="Force password to be changed on next login",
|
|
||||||
action="store_true"),
|
|
||||||
Option("--random-password",
|
|
||||||
help="Generate random password",
|
|
||||||
action="store_true"),
|
|
||||||
Option("--smartcard-required",
|
|
||||||
help="Require a smartcard for interactive logons",
|
|
||||||
action="store_true"),
|
|
||||||
Option("--clear-smartcard-required",
|
|
||||||
help="Don't require a smartcard for interactive logons",
|
|
||||||
action="store_true"),
|
|
||||||
]
|
|
||||||
|
|
||||||
takes_args = ["username?"]
|
|
||||||
|
|
||||||
def run(self, username=None, filter=None, credopts=None, sambaopts=None,
|
|
||||||
versionopts=None, H=None, newpassword=None,
|
|
||||||
must_change_at_next_login=False, random_password=False,
|
|
||||||
smartcard_required=False, clear_smartcard_required=False):
|
|
||||||
if filter is None and username is None:
|
|
||||||
raise CommandError("Either the username or '--filter' must be specified!")
|
|
||||||
|
|
||||||
password = newpassword
|
|
||||||
|
|
||||||
if smartcard_required:
|
|
||||||
if password is not None and password != '':
|
|
||||||
raise CommandError('It is not allowed to specify '
|
|
||||||
'--newpassword '
|
|
||||||
'together with --smartcard-required.')
|
|
||||||
if must_change_at_next_login:
|
|
||||||
raise CommandError('It is not allowed to specify '
|
|
||||||
'--must-change-at-next-login '
|
|
||||||
'together with --smartcard-required.')
|
|
||||||
if clear_smartcard_required:
|
|
||||||
raise CommandError('It is not allowed to specify '
|
|
||||||
'--clear-smartcard-required '
|
|
||||||
'together with --smartcard-required.')
|
|
||||||
|
|
||||||
if random_password and not smartcard_required:
|
|
||||||
password = generate_random_password(128, 255)
|
|
||||||
|
|
||||||
while True:
|
|
||||||
if smartcard_required:
|
|
||||||
break
|
|
||||||
if password is not None and password != '':
|
|
||||||
break
|
|
||||||
password = getpass("New Password: ")
|
|
||||||
passwordverify = getpass("Retype Password: ")
|
|
||||||
if not password == passwordverify:
|
|
||||||
password = None
|
|
||||||
self.outf.write("Sorry, passwords do not match.\n")
|
|
||||||
|
|
||||||
if filter is None:
|
|
||||||
filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
|
|
||||||
|
|
||||||
lp = sambaopts.get_loadparm()
|
|
||||||
creds = credopts.get_credentials(lp)
|
|
||||||
|
|
||||||
creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)
|
|
||||||
|
|
||||||
samdb = SamDB(url=H, session_info=system_session(),
|
|
||||||
credentials=creds, lp=lp)
|
|
||||||
|
|
||||||
if smartcard_required:
|
|
||||||
command = ""
|
|
||||||
try:
|
|
||||||
command = "Failed to set UF_SMARTCARD_REQUIRED for user '%s'" % (username or filter)
|
|
||||||
flags = dsdb.UF_SMARTCARD_REQUIRED
|
|
||||||
samdb.toggle_userAccountFlags(filter, flags, on=True)
|
|
||||||
command = "Failed to enable account for user '%s'" % (username or filter)
|
|
||||||
samdb.enable_account(filter)
|
|
||||||
except Exception as msg:
|
|
||||||
# FIXME: catch more specific exception
|
|
||||||
raise CommandError("%s: %s" % (command, msg))
|
|
||||||
self.outf.write("Added UF_SMARTCARD_REQUIRED OK\n")
|
|
||||||
else:
|
|
||||||
command = ""
|
|
||||||
try:
|
|
||||||
if clear_smartcard_required:
|
|
||||||
command = "Failed to remove UF_SMARTCARD_REQUIRED for user '%s'" % (username or filter)
|
|
||||||
flags = dsdb.UF_SMARTCARD_REQUIRED
|
|
||||||
samdb.toggle_userAccountFlags(filter, flags, on=False)
|
|
||||||
command = "Failed to set password for user '%s'" % (username or filter)
|
|
||||||
samdb.setpassword(filter, password,
|
|
||||||
force_change_at_next_login=must_change_at_next_login,
|
|
||||||
username=username)
|
|
||||||
except Exception as msg:
|
|
||||||
# FIXME: catch more specific exception
|
|
||||||
raise CommandError("%s: %s" % (command, msg))
|
|
||||||
self.outf.write("Changed password OK\n")
|
|
||||||
|
|
||||||
|
|
||||||
class cmd_user_getpassword(GetPasswordCommand):
|
class cmd_user_getpassword(GetPasswordCommand):
|
||||||
"""Get the password fields of a user/computer account.
|
"""Get the password fields of a user/computer account.
|
||||||
|
|
||||||
|
161
python/samba/netcmd/user/setpassword.py
Normal file
161
python/samba/netcmd/user/setpassword.py
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
# user management
|
||||||
|
#
|
||||||
|
# user setpassword command
|
||||||
|
#
|
||||||
|
# Copyright Jelmer Vernooij 2010 <jelmer@samba.org>
|
||||||
|
# Copyright Theresa Halloran 2011 <theresahalloran@gmail.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
from getpass import getpass
|
||||||
|
|
||||||
|
import samba.getopt as options
|
||||||
|
from samba import dsdb, generate_random_password, gensec, ldb
|
||||||
|
from samba.auth import system_session
|
||||||
|
from samba.netcmd import Command, CommandError, Option
|
||||||
|
from samba.samdb import SamDB
|
||||||
|
|
||||||
|
|
||||||
|
class cmd_user_setpassword(Command):
|
||||||
|
"""Set or reset the password of a user account.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Example1:
|
||||||
|
samba-tool user setpassword TestUser1 --newpassword=passw0rd --URL=ldap://samba.samdom.example.com -Uadministrator%passw1rd
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Example2:
|
||||||
|
sudo samba-tool user setpassword TestUser2 --newpassword=passw0rd --must-change-at-next-login
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Example3:
|
||||||
|
samba-tool user setpassword --filter=samaccountname=TestUser3 --newpassword=passw0rd
|
||||||
|
|
||||||
|
Example3 shows how an administrator would reset TestUser3 user's password to passw0rd using the --filter= option to specify the username.
|
||||||
|
|
||||||
|
"""
|
||||||
|
synopsis = "%prog (<username>|--filter <filter>) [options]"
|
||||||
|
|
||||||
|
takes_optiongroups = {
|
||||||
|
"sambaopts": options.SambaOptions,
|
||||||
|
"versionopts": options.VersionOptions,
|
||||||
|
"credopts": options.CredentialsOptions,
|
||||||
|
}
|
||||||
|
|
||||||
|
takes_options = [
|
||||||
|
Option("-H", "--URL", help="LDB URL for database or target server", type=str,
|
||||||
|
metavar="URL", dest="H"),
|
||||||
|
Option("--filter", help="LDAP Filter to set password on", type=str),
|
||||||
|
Option("--newpassword", help="Set password", type=str),
|
||||||
|
Option("--must-change-at-next-login",
|
||||||
|
help="Force password to be changed on next login",
|
||||||
|
action="store_true"),
|
||||||
|
Option("--random-password",
|
||||||
|
help="Generate random password",
|
||||||
|
action="store_true"),
|
||||||
|
Option("--smartcard-required",
|
||||||
|
help="Require a smartcard for interactive logons",
|
||||||
|
action="store_true"),
|
||||||
|
Option("--clear-smartcard-required",
|
||||||
|
help="Don't require a smartcard for interactive logons",
|
||||||
|
action="store_true"),
|
||||||
|
]
|
||||||
|
|
||||||
|
takes_args = ["username?"]
|
||||||
|
|
||||||
|
def run(self, username=None, filter=None, credopts=None, sambaopts=None,
|
||||||
|
versionopts=None, H=None, newpassword=None,
|
||||||
|
must_change_at_next_login=False, random_password=False,
|
||||||
|
smartcard_required=False, clear_smartcard_required=False):
|
||||||
|
if filter is None and username is None:
|
||||||
|
raise CommandError("Either the username or '--filter' must be specified!")
|
||||||
|
|
||||||
|
password = newpassword
|
||||||
|
|
||||||
|
if smartcard_required:
|
||||||
|
if password is not None and password != '':
|
||||||
|
raise CommandError('It is not allowed to specify '
|
||||||
|
'--newpassword '
|
||||||
|
'together with --smartcard-required.')
|
||||||
|
if must_change_at_next_login:
|
||||||
|
raise CommandError('It is not allowed to specify '
|
||||||
|
'--must-change-at-next-login '
|
||||||
|
'together with --smartcard-required.')
|
||||||
|
if clear_smartcard_required:
|
||||||
|
raise CommandError('It is not allowed to specify '
|
||||||
|
'--clear-smartcard-required '
|
||||||
|
'together with --smartcard-required.')
|
||||||
|
|
||||||
|
if random_password and not smartcard_required:
|
||||||
|
password = generate_random_password(128, 255)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
if smartcard_required:
|
||||||
|
break
|
||||||
|
if password is not None and password != '':
|
||||||
|
break
|
||||||
|
password = getpass("New Password: ")
|
||||||
|
passwordverify = getpass("Retype Password: ")
|
||||||
|
if not password == passwordverify:
|
||||||
|
password = None
|
||||||
|
self.outf.write("Sorry, passwords do not match.\n")
|
||||||
|
|
||||||
|
if filter is None:
|
||||||
|
filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))
|
||||||
|
|
||||||
|
lp = sambaopts.get_loadparm()
|
||||||
|
creds = credopts.get_credentials(lp)
|
||||||
|
|
||||||
|
creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)
|
||||||
|
|
||||||
|
samdb = SamDB(url=H, session_info=system_session(),
|
||||||
|
credentials=creds, lp=lp)
|
||||||
|
|
||||||
|
if smartcard_required:
|
||||||
|
command = ""
|
||||||
|
try:
|
||||||
|
command = "Failed to set UF_SMARTCARD_REQUIRED for user '%s'" % (username or filter)
|
||||||
|
flags = dsdb.UF_SMARTCARD_REQUIRED
|
||||||
|
samdb.toggle_userAccountFlags(filter, flags, on=True)
|
||||||
|
command = "Failed to enable account for user '%s'" % (username or filter)
|
||||||
|
samdb.enable_account(filter)
|
||||||
|
except Exception as msg:
|
||||||
|
# FIXME: catch more specific exception
|
||||||
|
raise CommandError("%s: %s" % (command, msg))
|
||||||
|
self.outf.write("Added UF_SMARTCARD_REQUIRED OK\n")
|
||||||
|
else:
|
||||||
|
command = ""
|
||||||
|
try:
|
||||||
|
if clear_smartcard_required:
|
||||||
|
command = "Failed to remove UF_SMARTCARD_REQUIRED for user '%s'" % (username or filter)
|
||||||
|
flags = dsdb.UF_SMARTCARD_REQUIRED
|
||||||
|
samdb.toggle_userAccountFlags(filter, flags, on=False)
|
||||||
|
command = "Failed to set password for user '%s'" % (username or filter)
|
||||||
|
samdb.setpassword(filter, password,
|
||||||
|
force_change_at_next_login=must_change_at_next_login,
|
||||||
|
username=username)
|
||||||
|
except Exception as msg:
|
||||||
|
# FIXME: catch more specific exception
|
||||||
|
raise CommandError("%s: %s" % (command, msg))
|
||||||
|
self.outf.write("Changed password OK\n")
|
Loading…
Reference in New Issue
Block a user