PEP8: fix E127: continuation line over-indented for visual indent
[samba.git] / python / samba / netcmd / user.py
index 478e263a9bde6556ed3e9dc00f17bbc9e5e93539..f002c1a2b0418de7de98ea0a20d84a23f506db57 100644 (file)
@@ -45,7 +45,7 @@ from samba import (
     gensec,
     generate_random_password,
     Ldb,
-    )
+)
 from samba.net import Net
 
 from samba.netcmd import (
@@ -53,8 +53,8 @@ from samba.netcmd import (
     CommandError,
     SuperCommand,
     Option,
-    )
-
+)
+from samba.compat import text_type
 
 try:
     import io
@@ -64,22 +64,22 @@ try:
 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:
@@ -119,7 +119,7 @@ def get_crypt_value(alg, utf8pw, rounds=0):
     # 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)
@@ -161,7 +161,7 @@ try:
     h = hashlib.sha1()
     h = None
     virtual_attributes["virtualSSHA"] = {
-        }
+    }
 except ImportError as e:
     reason = "hashlib.sha1()"
     if random_reason:
@@ -169,7 +169,7 @@ except ImportError as e:
     reason += " required"
     disabled_virtual_attributes["virtualSSHA"] = {
         "reason" : reason,
-        }
+    }
 
 for (alg, attr) in [("5", "virtualCryptSHA256"), ("6", "virtualCryptSHA512")]:
     try:
@@ -180,7 +180,7 @@ for (alg, attr) in [("5", "virtualCryptSHA256"), ("6", "virtualCryptSHA512")]:
         v = get_crypt_value(alg, "")
         v = None
         virtual_attributes[attr] = {
-            }
+        }
     except ImportError as e:
         reason = "crypt"
         if random_reason:
@@ -188,12 +188,12 @@ for (alg, attr) in [("5", "virtualCryptSHA256"), ("6", "virtualCryptSHA512")]:
         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):
@@ -249,22 +249,22 @@ Example5 shows how to create an RFC2307/NIS domain enabled user account. If
 
     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),
@@ -281,11 +281,11 @@ Example5 shows how to create an RFC2307/NIS domain enabled user account. If
         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),
@@ -299,7 +299,7 @@ Example5 shows how to create an RFC2307/NIS domain enabled user account. If
         "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,
@@ -378,7 +378,7 @@ Example5 shows how to create an RFC2307/NIS domain enabled user account. If
                           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)
@@ -429,7 +429,7 @@ Example2 shows how to delete a user in the domain against the local server.   su
         "sambaopts": options.SambaOptions,
         "credopts": options.CredentialsOptions,
         "versionopts": options.VersionOptions,
-        }
+    }
 
     def run(self, username, credopts=None, sambaopts=None, versionopts=None,
             H=None):
@@ -440,7 +440,7 @@ Example2 shows how to delete a user in the domain against the local server.   su
                       credentials=creds, lp=lp)
 
         filter = ("(&(sAMAccountName=%s)(sAMAccountType=805306368))" %
-                   username)
+                  ldb.binary_encode(username))
 
         try:
             res = samdb.search(base=samdb.domain_dn(),
@@ -453,7 +453,7 @@ Example2 shows how to delete a user in the domain against the local server.   su
 
         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)
 
@@ -466,13 +466,13 @@ class cmd_user_list(Command):
     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()
@@ -538,7 +538,7 @@ Example3 shows how to enable a user in the domain against a local LDAP server.
         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?"]
 
@@ -557,7 +557,7 @@ Example3 shows how to enable a user in the domain against a local LDAP server.
             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))
 
@@ -571,7 +571,7 @@ class cmd_user_disable(Command):
         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?"]
 
@@ -579,7 +579,7 @@ class cmd_user_disable(Command):
         "sambaopts": options.SambaOptions,
         "credopts": options.CredentialsOptions,
         "versionopts": options.VersionOptions,
-        }
+    }
 
     def run(self, username=None, sambaopts=None, credopts=None,
             versionopts=None, filter=None, H=None):
@@ -596,7 +596,7 @@ class cmd_user_disable(Command):
             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))
 
 
@@ -615,7 +615,7 @@ samba-tool user setexpiry User1 --days=20 --URL=ldap://samba.samdom.example.com
 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.
 
@@ -663,7 +663,7 @@ Example4 shows how to set the account expiration so that it will never expire.
 
         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))
@@ -683,16 +683,16 @@ class cmd_user_password(Command):
 
     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)
@@ -713,8 +713,10 @@ class cmd_user_password(Command):
                 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")
@@ -764,15 +766,15 @@ Example3 shows how an administrator would reset TestUser3 user's password to pas
                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?"]
 
@@ -832,7 +834,7 @@ Example3 shows how an administrator would reset TestUser3 user's password to pas
                 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")
@@ -847,7 +849,7 @@ Example3 shows how an administrator would reset TestUser3 user's password to pas
                 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")
@@ -1037,7 +1039,8 @@ class GetPasswordCommand(Command):
                     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:
@@ -1207,8 +1210,8 @@ class GetPasswordCommand(Command):
 
             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)
@@ -1246,7 +1249,7 @@ class GetPasswordCommand(Command):
                 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)
@@ -1425,7 +1428,7 @@ samba-tool user getpassword --filter=samaccountname=TestUser3 --attributes=msDS-
         Option("--decrypt-samba-gpg",
                help=decrypt_samba_gpg_help,
                action="store_true", default=False, dest="decrypt_samba_gpg"),
-        ]
+    ]
 
     takes_args = ["username?"]
 
@@ -1604,7 +1607,7 @@ following dirsyncAttributes:
   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".
@@ -1685,7 +1688,7 @@ samba-tool user syncpasswords --terminate \\
         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,
@@ -1748,7 +1751,7 @@ samba-tool user syncpasswords --terminate \\
             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*))" + \
                              ")"
 
@@ -1807,7 +1810,7 @@ samba-tool user syncpasswords --terminate \\
                     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)
@@ -1860,13 +1863,13 @@ samba-tool user syncpasswords --terminate \\
                 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:
@@ -1878,7 +1881,7 @@ samba-tool user syncpasswords --terminate \\
                 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:
@@ -1969,8 +1972,9 @@ samba-tool user syncpasswords --terminate \\
                 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
@@ -1982,7 +1986,8 @@ samba-tool user syncpasswords --terminate \\
             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))
@@ -2001,7 +2006,8 @@ samba-tool user syncpasswords --terminate \\
             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
@@ -2011,7 +2017,8 @@ samba-tool user syncpasswords --terminate \\
 
             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))
 
@@ -2022,11 +2029,12 @@ samba-tool user syncpasswords --terminate \\
             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))
@@ -2048,7 +2056,8 @@ samba-tool user syncpasswords --terminate \\
                     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
@@ -2212,7 +2221,7 @@ samba-tool user syncpasswords --terminate \\
             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:
@@ -2279,7 +2288,8 @@ samba-tool user syncpasswords --terminate \\
 
             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))
 
@@ -2335,7 +2345,7 @@ LDAP server using the 'nano' editor.
         "sambaopts": options.SambaOptions,
         "credopts": options.CredentialsOptions,
         "versionopts": options.VersionOptions,
-        }
+    }
 
     def run(self, username, credopts=None, sambaopts=None, versionopts=None,
             H=None, editor=None):
@@ -2467,7 +2477,7 @@ Example3 shows how to display a users objectSid and memberOf attributes.
         "sambaopts": options.SambaOptions,
         "credopts": options.CredentialsOptions,
         "versionopts": options.VersionOptions,
-        }
+    }
 
     def run(self, username, credopts=None, sambaopts=None, versionopts=None,
             H=None, user_attrs=None):
@@ -2539,7 +2549,7 @@ class cmd_user_move(Command):
         "sambaopts": options.SambaOptions,
         "credopts": options.CredentialsOptions,
         "versionopts": options.VersionOptions,
-        }
+    }
 
     def run(self, username, new_parent_dn, credopts=None, sambaopts=None,
             versionopts=None, H=None):
@@ -2561,7 +2571,7 @@ class cmd_user_move(Command):
 
         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))
 
@@ -2571,7 +2581,7 @@ class cmd_user_move(Command):
 
         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))