PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/solaris_shadow.py |
""" Manage the password database on Solaris systems .. important:: If you feel that Salt should be using this module to manage passwords on a minion, and it is using a different module (or gives an error similar to *'shadow.info' is not available*), see :ref:`here <module-provider-override>`. """ import os import salt.utils.files from salt.exceptions import CommandExecutionError try: import spwd HAS_SPWD = True except ImportError: # SmartOS joyent_20130322T181205Z does not have spwd HAS_SPWD = False try: import pwd except ImportError: pass # We're most likely on a Windows machine. try: import salt.utils.pycrypto HAS_CRYPT = True except ImportError: HAS_CRYPT = False # Define the module's virtual name __virtualname__ = "shadow" def __virtual__(): """ Only work on POSIX-like systems """ if __grains__.get("kernel", "") == "SunOS": return __virtualname__ return ( False, "The solaris_shadow execution module failed to load: only available on Solaris" " systems.", ) def default_hash(): """ Returns the default hash used for unset passwords CLI Example: .. code-block:: bash salt '*' shadow.default_hash """ return "!" def info(name): """ Return information for the specified user CLI Example: .. code-block:: bash salt '*' shadow.info root """ if HAS_SPWD: try: data = spwd.getspnam(name) ret = { "name": data.sp_nam, "passwd": data.sp_pwd, "lstchg": data.sp_lstchg, "min": data.sp_min, "max": data.sp_max, "warn": data.sp_warn, "inact": data.sp_inact, "expire": data.sp_expire, } except KeyError: ret = { "name": "", "passwd": "", "lstchg": "", "min": "", "max": "", "warn": "", "inact": "", "expire": "", } return ret # SmartOS joyent_20130322T181205Z does not have spwd, but not all is lost # Return what we can know ret = { "name": "", "passwd": "", "lstchg": "", "min": "", "max": "", "warn": "", "inact": "", "expire": "", } try: data = pwd.getpwnam(name) # pylint: disable=used-before-assignment ret.update({"name": name}) except KeyError: return ret # To compensate for lack of spwd module, read in password hash from /etc/shadow s_file = "/etc/shadow" if not os.path.isfile(s_file): return ret with salt.utils.files.fopen(s_file, "r") as ifile: for line in ifile: comps = line.strip().split(":") if comps[0] == name: ret.update({"passwd": comps[1]}) # For SmartOS `passwd -s <username>` and the output format is: # name status mm/dd/yy min max warn # # Fields: # 1. Name: username # 2. Status: # - LK: locked # - NL: no login # - NP: No password # - PS: Password # 3. Last password change # 4. Minimum age # 5. Maximum age # 6. Warning period output = __salt__["cmd.run_all"](f"passwd -s {name}", python_shell=False) if output["retcode"] != 0: return ret fields = output["stdout"].split() if len(fields) == 2: # For example: # root NL return ret # We have all fields: # buildbot L 05/09/2013 0 99999 7 ret.update( { "name": data.pw_name, "lstchg": fields[2], "min": int(fields[3]), "max": int(fields[4]), "warn": int(fields[5]), "inact": "", "expire": "", } ) return ret def set_maxdays(name, maxdays): """ Set the maximum number of days during which a password is valid. See man passwd. CLI Example: .. code-block:: bash salt '*' shadow.set_maxdays username 90 """ pre_info = info(name) if maxdays == pre_info["max"]: return True cmd = f"passwd -x {maxdays} {name}" __salt__["cmd.run"](cmd, python_shell=False) post_info = info(name) if post_info["max"] != pre_info["max"]: return post_info["max"] == maxdays def set_mindays(name, mindays): """ Set the minimum number of days between password changes. See man passwd. CLI Example: .. code-block:: bash salt '*' shadow.set_mindays username 7 """ pre_info = info(name) if mindays == pre_info["min"]: return True cmd = f"passwd -n {mindays} {name}" __salt__["cmd.run"](cmd, python_shell=False) post_info = info(name) if post_info["min"] != pre_info["min"]: return post_info["min"] == mindays return False def gen_password(password, crypt_salt=None, algorithm="sha512"): """ .. versionadded:: 2015.8.8 Generate hashed password .. note:: When called this function is called directly via remote-execution, the password argument may be displayed in the system's process list. This may be a security risk on certain systems. password Plaintext password to be hashed. crypt_salt Crpytographic salt. If not given, a random 8-character salt will be generated. algorithm The following hash algorithms are supported: * md5 * blowfish (not in mainline glibc, only available in distros that add it) * sha256 * sha512 (default) CLI Example: .. code-block:: bash salt '*' shadow.gen_password 'I_am_password' salt '*' shadow.gen_password 'I_am_password' crypt_salt='I_am_salt' algorithm=sha256 """ if not HAS_CRYPT: raise CommandExecutionError( "gen_password is not available on this operating system " 'because the "crypt" python module is not available.' ) return salt.utils.pycrypto.gen_hash(crypt_salt, password, algorithm) def del_password(name): """ .. versionadded:: 2015.8.8 Delete the password from name user CLI Example: .. code-block:: bash salt '*' shadow.del_password username """ cmd = f"passwd -d {name}" __salt__["cmd.run"](cmd, python_shell=False, output_loglevel="quiet") uinfo = info(name) return not uinfo["passwd"] def set_password(name, password): """ Set the password for a named user. The password must be a properly defined hash, the password hash can be generated with this command: ``openssl passwd -1 <plaintext password>`` CLI Example: .. code-block:: bash salt '*' shadow.set_password root $1$UYCIxa628.9qXjpQCjM4a.. """ s_file = "/etc/shadow" ret = {} if not os.path.isfile(s_file): return ret lines = [] with salt.utils.files.fopen(s_file, "r") as ifile: for line in ifile: comps = line.strip().split(":") if comps[0] != name: lines.append(line) continue comps[1] = password line = ":".join(comps) lines.append(f"{line}\n") with salt.utils.files.fopen(s_file, "w+") as ofile: lines = [salt.utils.stringutils.to_str(_l) for _l in lines] ofile.writelines(lines) uinfo = info(name) return uinfo["passwd"] == password def set_warndays(name, warndays): """ Set the number of days of warning before a password change is required. See man passwd. CLI Example: .. code-block:: bash salt '*' shadow.set_warndays username 7 """ pre_info = info(name) if warndays == pre_info["warn"]: return True cmd = f"passwd -w {warndays} {name}" __salt__["cmd.run"](cmd, python_shell=False) post_info = info(name) if post_info["warn"] != pre_info["warn"]: return post_info["warn"] == warndays return False