gensec,
generate_random_password,
Ldb,
- )
+)
from samba.net import Net
from samba.netcmd import (
CommandError,
SuperCommand,
Option,
- )
-
+)
+from samba.compat import text_type
try:
import io
except ImportError as e:
gpgme_support = False
decrypt_samba_gpg_help = "Decrypt the SambaGPG password not supported, " + \
- "python-gpgme required"
+ "python-gpgme required"
disabled_virtual_attributes = {
- }
+}
virtual_attributes = {
"virtualClearTextUTF8": {
"flags": ldb.ATTR_FLAG_FORCE_BASE64_LDIF,
- },
+ },
"virtualClearTextUTF16": {
"flags": ldb.ATTR_FLAG_FORCE_BASE64_LDIF,
- },
+ },
"virtualSambaGPG": {
"flags": ldb.ATTR_FLAG_FORCE_BASE64_LDIF,
- },
- }
+ },
+}
get_random_bytes_fn = None
if get_random_bytes_fn is None:
# we can ignore the possible == at the end
# of the base64 string
# we just need to replace '+' by '.'
- b64salt = base64.b64encode(salt)[0:16].replace('+', '.')
+ b64salt = base64.b64encode(salt)[0:16].replace(b'+', b'.').decode('utf8')
crypt_salt = ""
if rounds != 0:
crypt_salt = "$%s$rounds=%s$%s$" % (alg, rounds, b64salt)
h = hashlib.sha1()
h = None
virtual_attributes["virtualSSHA"] = {
- }
+ }
except ImportError as e:
reason = "hashlib.sha1()"
if random_reason:
reason += " required"
disabled_virtual_attributes["virtualSSHA"] = {
"reason" : reason,
- }
+ }
for (alg, attr) in [("5", "virtualCryptSHA256"), ("6", "virtualCryptSHA512")]:
try:
v = get_crypt_value(alg, "")
v = None
virtual_attributes[attr] = {
- }
+ }
except ImportError as e:
reason = "crypt"
if random_reason:
reason += " required"
disabled_virtual_attributes[attr] = {
"reason" : reason,
- }
+ }
except NotImplementedError as e:
reason = "modern '$%s$' salt in crypt(3) required" % (alg)
disabled_virtual_attributes[attr] = {
"reason" : reason,
- }
+ }
# Add the wDigest virtual attributes, virtualWDigest01 to virtualWDigest29
for x in range(1, 30):
takes_options = [
Option("-H", "--URL", help="LDB URL for database or target server", type=str,
- metavar="URL", dest="H"),
+ metavar="URL", dest="H"),
Option("--must-change-at-next-login",
- help="Force password to be changed on next login",
- action="store_true"),
+ help="Force password to be changed on next login",
+ action="store_true"),
Option("--random-password",
- help="Generate random password",
- action="store_true"),
+ help="Generate random password",
+ action="store_true"),
Option("--smartcard-required",
- help="Require a smartcard for interactive logons",
- action="store_true"),
+ help="Require a smartcard for interactive logons",
+ action="store_true"),
Option("--use-username-as-cn",
- help="Force use of username as user's CN",
- action="store_true"),
+ help="Force use of username as user's CN",
+ action="store_true"),
Option("--userou",
- help="DN of alternative location (without domainDN counterpart) to default CN=Users in which new user object will be created. E. g. 'OU=<OU name>'",
- type=str),
+ help="DN of alternative location (without domainDN counterpart) to default CN=Users in which new user object will be created. E. g. 'OU=<OU name>'",
+ type=str),
Option("--surname", help="User's surname", type=str),
Option("--given-name", help="User's given name", type=str),
Option("--initials", help="User's initials", type=str),
Option("--telephone-number", help="User's phone number", type=str),
Option("--physical-delivery-office", help="User's office location", type=str),
Option("--rfc2307-from-nss",
- help="Copy Unix user attributes from NSS (will be overridden by explicit UID/GID/GECOS/shell)",
- action="store_true"),
+ help="Copy Unix user attributes from NSS (will be overridden by explicit UID/GID/GECOS/shell)",
+ action="store_true"),
Option("--nis-domain", help="User's Unix/RFC2307 NIS domain", type=str),
Option("--unix-home", help="User's Unix/RFC2307 home directory",
- type=str),
+ type=str),
Option("--uid", help="User's Unix/RFC2307 username", type=str),
Option("--uid-number", help="User's Unix/RFC2307 numeric UID", type=int),
Option("--gid-number", help="User's Unix/RFC2307 primary GID number", type=int),
"sambaopts": options.SambaOptions,
"credopts": options.CredentialsOptions,
"versionopts": options.VersionOptions,
- }
+ }
def run(self, username, password=None, credopts=None, sambaopts=None,
versionopts=None, H=None, must_change_at_next_login=False,
uidnumber=uid_number, gidnumber=gid_number,
gecos=gecos, loginshell=login_shell,
smartcard_required=smartcard_required)
- except Exception, e:
+ except Exception as e:
raise CommandError("Failed to add user '%s': " % username, e)
self.outf.write("User '%s' created successfully\n" % username)
"sambaopts": options.SambaOptions,
"credopts": options.CredentialsOptions,
"versionopts": options.VersionOptions,
- }
+ }
def run(self, username, credopts=None, sambaopts=None, versionopts=None,
H=None):
credentials=creds, lp=lp)
filter = ("(&(sAMAccountName=%s)(sAMAccountType=805306368))" %
- username)
+ ldb.binary_encode(username))
try:
res = samdb.search(base=samdb.domain_dn(),
try:
samdb.delete(user_dn)
- except Exception, e:
+ except Exception as e:
raise CommandError('Failed to remove user "%s"' % username, e)
self.outf.write("Deleted user %s\n" % username)
takes_options = [
Option("-H", "--URL", help="LDB URL for database or target server", type=str,
metavar="URL", dest="H"),
- ]
+ ]
takes_optiongroups = {
"sambaopts": options.SambaOptions,
"credopts": options.CredentialsOptions,
"versionopts": options.VersionOptions,
- }
+ }
def run(self, sambaopts=None, credopts=None, versionopts=None, H=None):
lp = sambaopts.get_loadparm()
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),
- ]
+ ]
takes_args = ["username?"]
credentials=creds, lp=lp)
try:
samdb.enable_account(filter)
- except Exception, msg:
+ except Exception as msg:
raise CommandError("Failed to enable user '%s': %s" % (username or filter, msg))
self.outf.write("Enabled user '%s'\n" % (username or filter))
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),
- ]
+ ]
takes_args = ["username?"]
"sambaopts": options.SambaOptions,
"credopts": options.CredentialsOptions,
"versionopts": options.VersionOptions,
- }
+ }
def run(self, username=None, sambaopts=None, credopts=None,
versionopts=None, filter=None, H=None):
credentials=creds, lp=lp)
try:
samdb.disable_account(filter)
- except Exception, msg:
+ except Exception as msg:
raise CommandError("Failed to disable user '%s': %s" % (username or filter, msg))
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.
Example2:
-su samba-tool user setexpiry User2
+sudo samba-tool user setexpiry User2 --noexpiry
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.
try:
samdb.setexpiry(filter, days*24*3600, no_expiry_req=noexpiry)
- except Exception, msg:
+ except Exception as msg:
# FIXME: Catch more specific exception
raise CommandError("Failed to set expiry for user '%s': %s" % (
username or filter, msg))
takes_options = [
Option("--newpassword", help="New password", type=str),
- ]
+ ]
takes_optiongroups = {
"sambaopts": options.SambaOptions,
"credopts": options.CredentialsOptions,
"versionopts": options.VersionOptions,
- }
+ }
def run(self, credopts=None, sambaopts=None, versionopts=None,
- newpassword=None):
+ newpassword=None):
lp = sambaopts.get_loadparm()
creds = credopts.get_credentials(lp)
self.outf.write("Sorry, passwords do not match.\n")
try:
- net.change_password(password.encode('utf-8'))
- except Exception, msg:
+ if not isinstance(password, text_type):
+ password = password.decode('utf8')
+ net.change_password(password)
+ except Exception as msg:
# FIXME: catch more specific exception
raise CommandError("Failed to change password : %s" % msg)
self.outf.write("Changed password OK\n")
help="Force password to be changed on next login",
action="store_true"),
Option("--random-password",
- help="Generate random password",
- action="store_true"),
+ help="Generate random password",
+ action="store_true"),
Option("--smartcard-required",
- help="Require a smartcard for interactive logons",
- action="store_true"),
+ 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"),
- ]
+ help="Don't require a smartcard for interactive logons",
+ action="store_true"),
+ ]
takes_args = ["username?"]
samdb.toggle_userAccountFlags(filter, flags, on=True)
command = "Failed to enable account for user '%s'" % (username or filter)
samdb.enable_account(filter)
- except Exception, msg:
+ except Exception as msg:
# FIXME: catch more specific exception
raise CommandError("%s: %s" % (command, msg))
self.outf.write("Added UF_SMARTCARD_REQUIRED OK\n")
samdb.setpassword(filter, password,
force_change_at_next_login=must_change_at_next_login,
username=username)
- except Exception, msg:
+ except Exception as msg:
# FIXME: catch more specific exception
raise CommandError("%s: %s" % (command, msg))
self.outf.write("Changed password OK\n")
nthash = tmp.get_nt_hash()
if nthash == unicodePwd:
calculated["Primary:CLEARTEXT"] = cv
- except gpgme.GpgmeError as (major, minor, msg):
+ except gpgme.GpgmeError as e1:
+ (major, minor, msg) = e1.args
if major == gpgme.ERR_BAD_SECKEY:
msg = "ERR_BAD_SECKEY: " + msg
else:
for h in up.hashes:
if (scheme_match is None and
- h.scheme == SCHEME and
- h.value.startswith(scheme_prefix)):
+ h.scheme == SCHEME and
+ h.value.startswith(scheme_prefix)):
scheme_match = h.value
if h.scheme == SCHEME and h.value.startswith(prefix):
return (h.value, scheme_match)
h.update(u8)
h.update(salt)
bv = h.digest() + salt
- v = "{SSHA}" + base64.b64encode(bv)
+ v = "{SSHA}" + base64.b64encode(bv).decode('utf8')
elif a == "virtualCryptSHA256":
rounds = get_rounds(attr_opts[a])
x = get_virtual_crypt_value(a, 5, rounds, username, account_name)
Option("--decrypt-samba-gpg",
help=decrypt_samba_gpg_help,
action="store_true", default=False, dest="decrypt_samba_gpg"),
- ]
+ ]
takes_args = ["username?"]
userPrincipalName and userAccountControl.
It recovers from LDAP disconnects and updates the cache in conservative way
-(in single steps after each succesfully processed change). An error from
+(in single steps after each successfully processed change). An error from
the script (specified by '--script') will result in fatal error and this
command will exit. But the cache state should be still valid and can be
resumed in the next "Sync Loop Run".
Option("--terminate",
help="Send a SIGTERM to an already running (daemon) process",
action="store_true", default=False, dest="terminate"),
- ]
+ ]
def run(self, cache_ldb_initialize=False, cache_ldb=None,
H=None, filter=None,
dirsync_filter = "(&" + \
"(objectClass=user)" + \
"(userAccountControl:%s:=%u)" % (
- ldb.OID_COMPARATOR_AND, dsdb.UF_NORMAL_ACCOUNT) + \
+ ldb.OID_COMPARATOR_AND, dsdb.UF_NORMAL_ACCOUNT) + \
"(!(sAMAccountName=krbtgt*))" + \
")"
logfile = self.logfile
self.logfile = None
log_msg("Closing logfile[%s] (st_nlink == 0)\n" % (logfile))
- logfd = os.open(logfile, os.O_WRONLY | os.O_APPEND | os.O_CREAT, 0600)
+ logfd = os.open(logfile, os.O_WRONLY | os.O_APPEND | os.O_CREAT, 0o600)
os.dup2(logfd, 0)
os.dup2(logfd, 1)
os.dup2(logfd, 2)
self.sync_command = sync_command
add_ldif = "dn: %s\n" % self.cache_dn
add_ldif += "objectClass: userSyncPasswords\n"
- add_ldif += "samdbUrl:: %s\n" % base64.b64encode(self.samdb_url)
- add_ldif += "dirsyncFilter:: %s\n" % base64.b64encode(self.dirsync_filter)
+ add_ldif += "samdbUrl:: %s\n" % base64.b64encode(self.samdb_url).decode('utf8')
+ add_ldif += "dirsyncFilter:: %s\n" % base64.b64encode(self.dirsync_filter).decode('utf8')
for a in self.dirsync_attrs:
- add_ldif += "dirsyncAttribute:: %s\n" % base64.b64encode(a)
+ add_ldif += "dirsyncAttribute:: %s\n" % base64.b64encode(a).decode('utf8')
add_ldif += "dirsyncControl: %s\n" % self.dirsync_controls[0]
for a in self.password_attrs:
- add_ldif += "passwordAttribute:: %s\n" % base64.b64encode(a)
+ add_ldif += "passwordAttribute:: %s\n" % base64.b64encode(a).decode('utf8')
if self.decrypt_samba_gpg == True:
add_ldif += "decryptSambaGPG: TRUE\n"
else:
self.current_pid = None
self.outf.write("Initialized cache_ldb[%s]\n" % (cache_ldb))
msgs = self.cache.parse_ldif(add_ldif)
- changetype,msg = msgs.next()
+ changetype,msg = next(msgs)
ldif = self.cache.write_ldif(msg, ldb.CHANGETYPE_NONE)
self.outf.write("%s" % ldif)
else:
flags |= os.O_CREAT
try:
- self.lockfd = os.open(self.lockfile, flags, 0600)
- except IOError as (err, msg):
+ self.lockfd = os.open(self.lockfile, flags, 0o600)
+ except IOError as e4:
+ (err, msg) = e4.args
if err == errno.ENOENT:
if terminate:
return False
try:
fcntl.lockf(self.lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB)
got_exclusive = True
- except IOError as (err, msg):
+ except IOError as e5:
+ (err, msg) = e5.args
if err != errno.EACCES and err != errno.EAGAIN:
log_msg("check_current_pid_conflict: failed to get exclusive lock[%s] - %s (%d)" %
(self.lockfile, msg, err))
if got_exclusive and terminate:
try:
os.ftruncate(self.lockfd, 0)
- except IOError as (err, msg):
+ except IOError as e2:
+ (err, msg) = e2.args
log_msg("check_current_pid_conflict: failed to truncate [%s] - %s (%d)" %
(self.lockfile, msg, err))
raise
try:
fcntl.lockf(self.lockfd, fcntl.LOCK_SH)
- except IOError as (err, msg):
+ except IOError as e6:
+ (err, msg) = e6.args
log_msg("check_current_pid_conflict: failed to get shared lock[%s] - %s (%d)" %
(self.lockfile, msg, err))
if self.lockfd != -1:
got_exclusive = False
# Try 5 times to get the exclusiv lock.
- for i in xrange(0, 5):
+ for i in range(0, 5):
try:
fcntl.lockf(self.lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB)
got_exclusive = True
- except IOError as (err, msg):
+ except IOError as e:
+ (err, msg) = e.args
if err != errno.EACCES and err != errno.EAGAIN:
log_msg("update_pid(%r): failed to get exclusive lock[%s] - %s (%d)" %
(pid, self.lockfile, msg, err))
os.ftruncate(self.lockfd, 0)
if buf is not None:
os.write(self.lockfd, buf)
- except IOError as (err, msg):
+ except IOError as e3:
+ (err, msg) = e3.args
log_msg("check_current_pid_conflict: failed to write pid to [%s] - %s (%d)" %
(self.lockfile, msg, err))
raise
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
if maxfd == resource.RLIM_INFINITY:
maxfd = 1024 # Rough guess at maximum number of open file descriptors.
- logfd = os.open(logfile, os.O_WRONLY | os.O_APPEND | os.O_CREAT, 0600)
+ logfd = os.open(logfile, os.O_WRONLY | os.O_APPEND | os.O_CREAT, 0o600)
self.outf.write("Using logfile[%s]\n" % logfile)
for fd in range(0, maxfd):
if fd == logfd:
try:
sync_loop(wait)
- except ldb.LdbError as (enum, estr):
+ except ldb.LdbError as e7:
+ (enum, estr) = e7.args
self.samdb = None
log_msg("ldb.LdbError(%d) => (%s)\n" % (enum, estr))
"sambaopts": options.SambaOptions,
"credopts": options.CredentialsOptions,
"versionopts": options.VersionOptions,
- }
+ }
def run(self, username, credopts=None, sambaopts=None, versionopts=None,
H=None, editor=None):
"sambaopts": options.SambaOptions,
"credopts": options.CredentialsOptions,
"versionopts": options.VersionOptions,
- }
+ }
def run(self, username, credopts=None, sambaopts=None, versionopts=None,
H=None, user_attrs=None):
"sambaopts": options.SambaOptions,
"credopts": options.CredentialsOptions,
"versionopts": options.VersionOptions,
- }
+ }
def run(self, username, new_parent_dn, credopts=None, sambaopts=None,
versionopts=None, H=None):
try:
full_new_parent_dn = samdb.normalize_dn_in_domain(new_parent_dn)
- except Exception, e:
+ except Exception as e:
raise CommandError('Invalid new_parent_dn "%s": %s' %
(new_parent_dn, e.message))
try:
samdb.rename(user_dn, full_new_user_dn)
- except Exception, e:
+ except Exception as e:
raise CommandError('Failed to move user "%s"' % username, e)
self.outf.write('Moved user "%s" into "%s"\n' %
(username, full_new_parent_dn))