def createOpsiSetupUser(self, admin=True, delete_existing=False): # pylint: disable=no-self-use,too-many-branches # https://bugs.python.org/file46988/issue.py user_info = { "name": OPSI_SETUP_USER_NAME, "full_name": "opsi setup user", "comment": "auto created by opsi", "password": f"/{''.join((random.choice(string.ascii_letters + string.digits) for i in range(8)))}?", "priv": win32netcon.USER_PRIV_USER, "flags": win32netcon.UF_NORMAL_ACCOUNT | win32netcon.UF_SCRIPT | win32netcon.UF_DONT_EXPIRE_PASSWD } # Test if user exists user_sid = None try: win32net.NetUserGetInfo(None, user_info["name"], 1) user_sid = win32security.ConvertSidToStringSid( win32security.LookupAccountName(None, user_info["name"])[0]) logger.info("User '%s' exists, sid is '%s'", user_info["name"], user_sid) except Exception as err: # pylint: disable=broad-except logger.info(err) self.cleanup_opsi_setup_user( keep_sid=None if delete_existing else user_sid) if delete_existing: user_sid = None # Hide user from login try: winreg.CreateKeyEx( winreg.HKEY_LOCAL_MACHINE, r'Software\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts', 0, winreg.KEY_WOW64_64KEY | winreg.KEY_ALL_ACCESS # sysnative ) except WindowsError: # pylint: disable=undefined-variable pass try: winreg.CreateKeyEx( winreg.HKEY_LOCAL_MACHINE, r'Software\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList', 0, winreg.KEY_WOW64_64KEY | winreg.KEY_ALL_ACCESS # sysnative ) except WindowsError: # pylint: disable=undefined-variable pass with winreg.OpenKey( winreg.HKEY_LOCAL_MACHINE, r'Software\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList', 0, winreg.KEY_SET_VALUE | winreg.KEY_WOW64_64KEY # sysnative ) as reg_key: winreg.SetValueEx(reg_key, user_info["name"], 0, winreg.REG_DWORD, 0) if user_sid: logger.info("Updating password of user '%s'", user_info["name"]) user_info_update = win32net.NetUserGetInfo(None, user_info["name"], 1) user_info_update["password"] = user_info["password"] win32net.NetUserSetInfo(None, user_info["name"], 1, user_info_update) else: logger.info("Creating user '%s'", user_info["name"]) win32net.NetUserAdd(None, 1, user_info) user_sid = win32security.ConvertSidToStringSid( win32security.LookupAccountName(None, user_info["name"])[0]) subprocess.run([ "icacls", os.path.dirname(sys.argv[0]), "/grant:r", f"*{user_sid}:(OI)(CI)RX" ], check=False) subprocess.run([ "icacls", os.path.dirname(config.get("global", "log_file")), "/grant:r", f"*{user_sid}:(OI)(CI)F" ], check=False) subprocess.run([ "icacls", os.path.dirname(config.get("global", "tmp_dir")), "/grant:r", f"*{user_sid}:(OI)(CI)F" ], check=False) local_admin_group_sid = win32security.ConvertStringSidToSid( "S-1-5-32-544") local_admin_group_name = win32security.LookupAccountSid( None, local_admin_group_sid)[0] try: if admin: logger.info("Adding user '%s' to admin group", user_info["name"]) win32net.NetLocalGroupAddMembers( None, local_admin_group_name, 3, [{ "domainandname": user_info["name"] }]) else: logger.info("Removing user '%s' from admin group", user_info["name"]) win32net.NetLocalGroupDelMembers(None, local_admin_group_name, [user_info["name"]]) except pywintypes.error as err: # 1377 - ERROR_MEMBER_NOT_IN_ALIAS # The specified account name is not a member of the group. # 1378 # ERROR_MEMBER_IN_ALIAS # The specified account name is already a member of the group. if err.winerror not in (1377, 1378): raise user_info_4 = win32net.NetUserGetInfo(None, user_info["name"], 4) user_info_4["password"] = user_info["password"] return user_info_4
def add( name, password=None, fullname=None, description=None, groups=None, home=None, homedrive=None, profile=None, logonscript=None, ): """ Add a user to the minion. Args: name (str): User name password (str, optional): User's password in plain text. fullname (str, optional): The user's full name. description (str, optional): A brief description of the user account. groups (str, optional): A list of groups to add the user to. (see chgroups) home (str, optional): The path to the user's home directory. homedrive (str, optional): The drive letter to assign to the home directory. Must be the Drive Letter followed by a colon. ie: U: profile (str, optional): An explicit path to a profile. Can be a UNC or a folder on the system. If left blank, windows uses its default profile directory. logonscript (str, optional): Path to a login script to run when the user logs on. Returns: bool: True if successful. False is unsuccessful. CLI Example: .. code-block:: bash salt '*' user.add name password """ if six.PY2: name = _to_unicode(name) password = _to_unicode(password) fullname = _to_unicode(fullname) description = _to_unicode(description) home = _to_unicode(home) homedrive = _to_unicode(homedrive) profile = _to_unicode(profile) logonscript = _to_unicode(logonscript) user_info = {} if name: user_info["name"] = name else: return False user_info["password"] = password user_info["priv"] = win32netcon.USER_PRIV_USER user_info["home_dir"] = home user_info["comment"] = description user_info["flags"] = win32netcon.UF_SCRIPT user_info["script_path"] = logonscript try: win32net.NetUserAdd(None, 1, user_info) except win32net.error as exc: log.error("Failed to create user %s", name) log.error("nbr: %s", exc.winerror) log.error("ctx: %s", exc.funcname) log.error("msg: %s", exc.strerror) return False update(name=name, homedrive=homedrive, profile=profile, fullname=fullname) ret = chgroups(name, groups) if groups else True return ret
def add_user(self, ): try: win32net.NetUserAdd(None, 1, self.user_info) except: print('Add new user [{}] fail'.format(self.user_info['name'])) pass
def add(name, password=None, fullname=None, description=None, groups=None, home=None, homedrive=None, profile=None, logonscript=None): ''' Add a user to the minion. :param str name: User name :param str password: User's password in plain text. :param str fullname: The user's full name. :param str description: A brief description of the user account. :param list groups: A list of groups to add the user to. :param str home: The path to the user's home directory. :param str homedrive: The drive letter to assign to the home directory. Must be the Drive Letter followed by a colon. ie: U: :param str profile: An explicit path to a profile. Can be a UNC or a folder on the system. If left blank, windows uses it's default profile directory. :param str logonscript: Path to a login script to run when the user logs on. :return: True if successful. False is unsuccessful. :rtype: bool CLI Example: .. code-block:: bash salt '*' user.add name password ''' user_info = {} if name: user_info['name'] = name else: return False user_info['password'] = password user_info['priv'] = win32netcon.USER_PRIV_USER user_info['home_dir'] = home user_info['comment'] = description user_info['flags'] = win32netcon.UF_SCRIPT user_info['script_path'] = logonscript try: win32net.NetUserAdd(None, 1, user_info) except win32net.error as exc: (number, context, message) = exc log.error('Failed to create user {0}'.format(name)) log.error('nbr: {0}'.format(number)) log.error('ctx: {0}'.format(context)) log.error('msg: {0}'.format(message)) return False update(name=name, homedrive=homedrive, profile=profile, fullname=fullname) ret = chgroups(name, groups) if groups else True return ret
def create_user (user, password): user_info = dict ( name = user, password = password, priv = win32netcon.USER_PRIV_USER, home_dir = None, comment = None, flags = win32netcon.UF_SCRIPT, script_path = None ) try: win32net.NetUserDel (None, user) except win32net.error, (number, context, message): if number <> 2221: raise win32net.NetUserAdd (None, 1, user_info) def create_group (group): group_info = dict ( name = group ) try: win32net.NetLocalGroupDel (None, group) except win32net.error, (number, context, message): if number <> 2220: raise win32net.NetLocalGroupAdd (None, 0, group_info) def add_user_to_group (user, group): user_group_info = dict ( domainandname = user