Example #1
0
def SetInfo(userName=None):
    "Attempts to change the current users comment, then set it back"
    if userName is None: userName = win32api.GetUserName()
    oldData = win32net.NetUserGetInfo(server, userName, 3)
    try:
        d = oldData.copy()
        d["usr_comment"] = "Test comment"
        win32net.NetUserSetInfo(server, userName, 3, d)
        new = win32net.NetUserGetInfo(server, userName, 3)['usr_comment']
        if str(new) != "Test comment":
            raise RuntimeError, "Could not read the same comment back - got %s" % new
        print "Changed the data for the user"
    finally:
        win32net.NetUserSetInfo(server, userName, 3, oldData)
Example #2
0
def disablePasswdExpiry(user, servername=SERVERNAME):
    try:
        userinfo = win32net.NetUserGetInfo(servername, user, 3)
        userinfo['flags'] |= win32netcon.UF_DONT_EXPIRE_PASSWD
        win32net.NetUserSetInfo(servername, user, 3, userinfo)
    except win32net.error:
        mesg("\n    @@@ Warning: Could not disable password expiry for user %s. @@@\n\n", user)
Example #3
0
def setPasswd(user, password, servername=SERVERNAME):
    try:
        userinfo = win32net.NetUserGetInfo(servername, user, 2)
        userinfo['password'] = password
        win32net.NetUserSetInfo(servername, user, 2, userinfo)
    except win32net.error:
        mesg("\n    @@@ Warning: Could not set password for user %s. @@@\n\n", user)
Example #4
0
def create_local_student_account(user_name, full_name, password):
    global STUDENTS_GROUP

    # Ensure the Students group exists
    ret = create_local_students_group()

    # Create local student account
    student = None
    try:
        print("\tAdding student account...")
        accounts.User.create(user_name, password)
    except pywintypes.error as err:
        if err[2] == "The account already exists.":
            pass
        else:
            # Unexpected error
            print(str(err))
            ret = False

    # Get the student object
    student = accounts.user(user_name)
    # Set properties for this student
    # win32net.NetUserChangePassword(None, user_name, old_pw, password)

    user_data = dict()
    user_data['name'] = user_name
    user_data['full_name'] = full_name
    user_data['password'] = password
    user_data[
        'flags'] = win32netcon.UF_NORMAL_ACCOUNT | win32netcon.UF_PASSWD_CANT_CHANGE | win32netcon.UF_DONT_EXPIRE_PASSWD | win32netcon.UF_SCRIPT
    user_data['priv'] = win32netcon.USER_PRIV_USER
    user_data['comment'] = 'OPE Student Account'
    # user_data['home_dir'] = home_dir
    # user_data['home_dir_drive'] = "h:"
    user_data['primary_group_id'] = ntsecuritycon.DOMAIN_GROUP_RID_USERS
    user_data['password_expired'] = 0
    user_data['acct_expires'] = win32netcon.TIMEQ_FOREVER

    win32net.NetUserSetInfo(None, user_name, 3, user_data)

    # Add student to the students group
    print("\tAdding student to students group...")
    grp = accounts.LocalGroup(accounts.group(STUDENTS_GROUP).sid)
    try:
        grp.add(student)
    except pywintypes.error as err:
        if err[2] == "The specified account name is already a member of the group.":
            pass
        else:
            # Unexpected error
            print(str(err))
            ret = False

    # # home_dir = "%s\\%s" % (server_name, user_name)
    #

    return ret
Example #5
0
    def create_local_admin_account(user_name, full_name, password):
        # Create local admin account
        ret = True

        try:
            p("}}yn\tAdding Admin account (" + user_name + ")...}}xx")
            accounts.User.create(user_name, password)
            # p("}}yn\t\tDone.}}xx")
        # except pywintypes.error as ex:
        except Exception as ex:
            if ex.args[2] == "The account already exists.":
                pass
            else:
                # Unexpected error
                p("}}rb" + str(ex) + "}}xx")
                ret = False

        user_data = dict()
        user_data['name'] = user_name
        user_data['full_name'] = full_name
        #user_data['password'] = UserAccounts.generate_random_password()
        user_data['flags'] = UserAccounts.ENABLE_ACCOUNT_FLAGS
        user_data['priv'] = win32netcon.USER_PRIV_ADMIN
        user_data['comment'] = 'OPE Admin Account'
        # user_data['home_dir'] = home_dir
        # user_data['home_dir_drive'] = "h:"
        user_data['primary_group_id'] = ntsecuritycon.DOMAIN_GROUP_RID_USERS
        user_data['password_expired'] = 0
        user_data['acct_expires'] = win32netcon.TIMEQ_FOREVER

        win32net.NetUserSetInfo(None, user_name, 3, user_data)

        # Set password
        try:
            user_data['password'] = password
            win32net.NetUserSetInfo(None, user_name, 3, user_data)
        except Exception as ex:
            p("}}rbERROR setting password for " + user_name + "}}xx\n" +
              str(ex))

        if not UserAccounts.set_default_groups_for_admin(user_name):
            ret = False

        return ret
Example #6
0
    def change_password_next_logon(self, username):
        """Force the given user to change the password at next logon."""
        user_info = self._get_user_info(username, 4)
        user_info["flags"] &= ~win32netcon.UF_DONT_EXPIRE_PASSWD
        user_info["password_expired"] = 1

        try:
            win32net.NetUserSetInfo(None, username, 4, user_info)
        except win32net.error as ex:
            raise exception.CloudbaseInitException(
                "Setting password expiration failed: %s" % ex.args[2])
def disable_account(name):
    user_info = get_account_info(name)

    # disable account
    user_info['flags'] = user_info.get('flags') | win32netcon.UF_ACCOUNTDISABLE

    try:
        win32net.NetUserSetInfo(None, name, 4, user_info)
    except pywintypes.error as e:
        print("ERROR: permission denied.")
        print(e)
        sys.exit(1)
    print("OK: account \"{}\" is disabled.".format(name))
Example #8
0
def changeUserPassword(user: str, oldPassword: str, newPassword: str) -> None:
    # lpUser = LPCWSTR(user)
    # lpOldPassword = LPCWSTR(oldPassword)
    # lpNewPassword = LPCWSTR(newPassword)

    # res = ctypes.windll.netapi32.NetUserChangePassword(None, lpUser, lpOldPassword, lpNewPassword)
    # Try to set new password "a las bravas", ignoring old one. This will not work with domain users
    res = win32net.NetUserSetInfo(None, user, 1003, {'password': newPassword})

    if res:
        # Log the error, and raise exception to parent
        error = getErrorMessage(res)
        raise Exception('Error changing password for user {}: {} {}'.format(user, res, error))
Example #9
0
    def set_user_password(self, username, password, password_expires=False):
        user_info = self._get_user_info(username, 1)
        user_info["password"] = password

        if password_expires:
            user_info["flags"] &= ~win32netcon.UF_DONT_EXPIRE_PASSWD
        else:
            user_info["flags"] |= win32netcon.UF_DONT_EXPIRE_PASSWD

        try:
            win32net.NetUserSetInfo(None, username, 1, user_info)
        except win32net.error as ex:
            raise exception.CloudbaseInitException(
                "Set user password failed: %s" % ex.args[2])
Example #10
0
 def disable_account(account_name=None):
     if account_name is None:
         account_name = util.get_param(2, None)
     if account_name is None:
         p("}}enInvalid User name - not disabling account!}}xx")
         return False
     try:
         user_data = dict()
         user_data['flags'] = UserAccounts.DISABLE_ACCOUNT_FLAGS
         #win32netcon.UF_SCRIPT | win32netcon.UF_ACCOUNTDISABLE
         win32net.NetUserSetInfo(None, account_name, 1008, user_data)
     except Exception as ex:
         p("}}rnError - Unable to disable account: " + str(account_name) + "}}xx\n" + \
             str(ex))
         return False
     return True
Example #11
0
def update(name,
           password=None,
           fullname=None,
           description=None,
           home=None,
           homedrive=None,
           logonscript=None,
           profile=None,
           expiration_date=None,
           expired=None,
           account_disabled=None,
           unlock_account=None,
           password_never_expires=None,
           disallow_change_password=None):
    r'''
    Updates settings for the windows user. Name is the only required parameter.
    Settings will only be changed if the parameter is passed a value.

    .. versionadded:: 2015.8.0

    Args:
        name (str): The user name to update.

        password (str, optional): New user password in plain text.

        fullname (str, optional): The user's full name.

        description (str, optional): A brief description of the user account.

        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:

        logonscript (str, optional): The path to the logon script.

        profile (str, optional): The path to the user's profile directory.

        expiration_date (date, optional): The date and time when the account
            expires. Can be a valid date/time string. To set to never expire
            pass the string 'Never'.

        expired (bool, optional): Pass `True` to expire the account. The user
            will be prompted to change their password at the next logon. Pass
            `False` to mark the account as 'not expired'. You can't use this to
            negate the expiration if the expiration was caused by the account
            expiring. You'll have to change the `expiration_date` as well.

        account_disabled (bool, optional): True disables the account. False
            enables the account.

        unlock_account (bool, optional): True unlocks a locked user account.
            False is ignored.

        password_never_expires (bool, optional): True sets the password to never
            expire. False allows the password to expire.

        disallow_change_password (bool, optional): True blocks the user from
            changing the password. False allows the user to change the password.

    Returns:
        bool: True if successful. False is unsuccessful.

    CLI Example:

    .. code-block:: bash

        salt '*' user.update bob password=secret profile=C:\Users\Bob
                 home=\\server\homeshare\bob homedrive=U:
    '''
    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)
        logonscript = _to_unicode(logonscript)
        profile = _to_unicode(profile)

    # Make sure the user exists
    # Return an object containing current settings for the user
    try:
        user_info = win32net.NetUserGetInfo(None, name, 4)
    except win32net.error as exc:
        (number, context, message) = exc
        log.error('Failed to update user {0}'.format(name))
        log.error('nbr: {0}'.format(exc.winerror))
        log.error('ctx: {0}'.format(exc.funcname))
        log.error('msg: {0}'.format(exc.strerror))
        return False

    # Check parameters to update
    # Update the user object with new settings
    if password:
        user_info['password'] = password
    if home:
        user_info['home_dir'] = home
    if homedrive:
        user_info['home_dir_drive'] = homedrive
    if description:
        user_info['comment'] = description
    if logonscript:
        user_info['script_path'] = logonscript
    if fullname:
        user_info['full_name'] = fullname
    if profile:
        user_info['profile'] = profile
    if expiration_date:
        if expiration_date == 'Never':
            user_info['acct_expires'] = win32netcon.TIMEQ_FOREVER
        else:
            try:
                dt_obj = salt.utils.dateutils.date_cast(expiration_date)
            except (ValueError, RuntimeError):
                return 'Invalid Date/Time Format: {0}'.format(expiration_date)
            user_info['acct_expires'] = time.mktime(dt_obj.timetuple())
    if expired is not None:
        if expired:
            user_info['password_expired'] = 1
        else:
            user_info['password_expired'] = 0
    if account_disabled is not None:
        if account_disabled:
            user_info['flags'] |= win32netcon.UF_ACCOUNTDISABLE
        else:
            user_info['flags'] &= ~win32netcon.UF_ACCOUNTDISABLE
    if unlock_account is not None:
        if unlock_account:
            user_info['flags'] &= ~win32netcon.UF_LOCKOUT
    if password_never_expires is not None:
        if password_never_expires:
            user_info['flags'] |= win32netcon.UF_DONT_EXPIRE_PASSWD
        else:
            user_info['flags'] &= ~win32netcon.UF_DONT_EXPIRE_PASSWD
    if disallow_change_password is not None:
        if disallow_change_password:
            user_info['flags'] |= win32netcon.UF_PASSWD_CANT_CHANGE
        else:
            user_info['flags'] &= ~win32netcon.UF_PASSWD_CANT_CHANGE

    # Apply new settings
    try:
        win32net.NetUserSetInfo(None, name, 4, user_info)
    except win32net.error as exc:
        (number, context, message) = exc
        log.error('Failed to update user {0}'.format(name))
        log.error('nbr: {0}'.format(exc.winerror))
        log.error('ctx: {0}'.format(exc.funcname))
        log.error('msg: {0}'.format(exc.strerror))
        return False

    return True
Example #12
0
def update(name,
           password=None,
           fullname=None,
           description=None,
           home=None,
           homedrive=None,
           logonscript=None,
           profile=None):
    r'''
    Updates settings for the windows user. Name is the only required parameter.
    Settings will only be changed if the parameter is passed a value.

    .. versionadded:: 2015.8.0

    :param name: str
    The user name to update.

    :param password: str
    New user password in plain text.

    :param fullname: str
    The user's full name.

    :param description: str
    A brief description of the user account.

    :param home: str
    The path to the user's home directory.

    :param homedrive: str
    The drive letter to assign to the home directory. Must be the Drive Letter
    followed by a colon. ie: U:

    :param logonscript: str
    The path to the logon script.

    :param profile: str
    The path to the user's profile directory.

    :return: bool
    True if successful. False is unsuccessful.

    CLI Example:

    .. code-block:: bash

        salt '*' user.update bob password=secret profile=C:\Users\Bob
                 home=\\server\homeshare\bob homedrive=U:
    '''

    # Make sure the user exists
    # Return an object containing current settings for the user
    try:
        user_info = win32net.NetUserGetInfo(None, name, 4)
    except win32net.error as exc:
        (number, context, message) = exc
        log.error('Failed to update user {0}'.format(name))
        log.error('nbr: {0}'.format(number))
        log.error('ctx: {0}'.format(context))
        log.error('msg: {0}'.format(message))
        return False

    # Check parameters to update
    # Update the user object with new settings
    if password:
        user_info['password'] = password
    if home:
        user_info['home_dir'] = home
    if homedrive:
        user_info['home_dir_drive'] = homedrive
    if description:
        user_info['comment'] = description
    if logonscript:
        user_info['script_path'] = logonscript
    if fullname:
        user_info['full_name'] = fullname
    if profile:
        user_info['profile'] = profile

    # Apply new settings
    try:
        win32net.NetUserSetInfo(None, name, 4, user_info)
    except win32net.error as exc:
        (number, context, message) = exc
        log.error('Failed to update user {0}'.format(name))
        log.error('nbr: {0}'.format(number))
        log.error('ctx: {0}'.format(context))
        log.error('msg: {0}'.format(message))
        return False

    return True
Example #13
0
    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
Example #14
0
def create_local_admin_account(user_name, full_name, password):
    # Create local admin account
    ret = True
    admin = None

    try:
        p("}}yn\tAdding Admin account (" + user_name + ")...}}xx")
        accounts.User.create(user_name, password)
        # p("}}yn\t\tDone.}}xx")
    # except pywintypes.error as err:
    except Exception as err:
        if err.args[2] == "The account already exists.":
            pass
        else:
            # Unexpected error
            p("}}rb" + str(err) + "}}xx")
            ret = False

    # Get the student object
    admin = accounts.user(user_name)
    # Set properties for this student
    # win32net.NetUserChangePassword(None, user_name, old_pw, password)

    user_data = dict()
    user_data['name'] = user_name
    user_data['full_name'] = full_name
    user_data['password'] = password
    user_data[
        'flags'] = win32netcon.UF_NORMAL_ACCOUNT | win32netcon.UF_PASSWD_CANT_CHANGE | win32netcon.UF_DONT_EXPIRE_PASSWD | win32netcon.UF_SCRIPT
    user_data['priv'] = win32netcon.USER_PRIV_ADMIN
    user_data['comment'] = 'OPE Admin Account'
    # user_data['home_dir'] = home_dir
    # user_data['home_dir_drive'] = "h:"
    user_data['primary_group_id'] = ntsecuritycon.DOMAIN_GROUP_RID_USERS
    user_data['password_expired'] = 0
    user_data['acct_expires'] = win32netcon.TIMEQ_FOREVER

    win32net.NetUserSetInfo(None, user_name, 3, user_data)

    # Add user to the required groups
    p("}}yn\tAdding user to Administrators group...}}xx")
    grp = accounts.LocalGroup(accounts.group("Administrators").sid)
    users_grp = accounts.LocalGroup(accounts.group("Users").sid)
    try:
        # Add to administrators group
        grp.add(admin)
    # except pywintypes.error as err:
    except Exception as err:
        if err.args[
                2] == "The specified account name is already a member of the group.":
            pass
        else:
            # Unexpected error
            p("}}rb" + str(err) + "}}xx")
            ret = False
    try:
        # Add to users group
        users_grp.add(admin)
    # except pywintypes.error as err:
    except Exception as err:
        if err.args[
                2] == "The specified account name is already a member of the group.":
            pass
        else:
            # Unexpected error
            p("}}rb" + str(err) + "}}xx")
            ret = False

    return ret
Example #15
0
def disable_account(account_name):
    user_data = dict()
    user_data['flags'] = win32netcon.UF_SCRIPT | win32netcon.UF_ACCOUNTDISABLE
    win32net.NetUserSetInfo(None, account_name, 1008, user_data)
Example #16
0
 def rename(self, old_name, new_name):
     super(QubesWniVmStorage, self).rename(old_name, new_name)
     user_data = {}
     user_data['name'] = self._get_username(new_name)
     win32net.NetUserSetInfo(None, self._get_username(old_name), 0,
                             user_data)
Example #17
0
    def create_local_student_account(user_name=None,
                                     full_name=None,
                                     password=None):
        ret = True
        # Make sure we have parameters
        if user_name is None:
            user_name = util.get_param(2, None)
        if full_name is None:
            full_name = util.get_param(3, None)
        if password is None:
            password = util.get_param(4, None)
        if user_name is None or full_name is None or password is None:
            p("}}rbError - Invalid parameters to create new student user!}}xx",
              debug_level=1)
            return False

        # Create local student account
        try:
            p("}}yn\tAdding student account (" + user_name + ")...}}xx")
            accounts.User.create(user_name, password)
        # except pywintypes.error as ex:
        except Exception as ex:
            if ex.args[2] == "The account already exists.":
                pass
            else:
                # Unexpected error
                p("}}rb" + str(ex) + "}}xx")
                ret = False

        # Set info for the student
        user_data = dict()
        user_data['name'] = user_name
        user_data['full_name'] = full_name
        # Start w a random complex password
        user_data['password'] = UserAccounts.generate_random_password(
        )  # password
        # NOTE - Student accounts are always created disabled!
        user_data['flags'] = UserAccounts.DISABLE_ACCOUNT_FLAGS
        user_data['priv'] = win32netcon.USER_PRIV_USER
        user_data['comment'] = 'OPE Student Account'
        # user_data['home_dir'] = home_dir
        # user_data['home_dir_drive'] = "h:"
        user_data['primary_group_id'] = ntsecuritycon.DOMAIN_GROUP_RID_USERS
        user_data['password_expired'] = 0
        user_data['acct_expires'] = win32netcon.TIMEQ_FOREVER

        win32net.NetUserSetInfo(None, user_name, 3, user_data)

        # Make sure the password is complex enough
        tmp_password = password
        if len(tmp_password) < 8:
            p("}}rbStudent Password Too Short! Padding with !s to 8 characters}}xx"
              )
            pad_chars = (8 - len(tmp_password)) * "!"
        # Set the password
        try:
            user_data['password'] = tmp_password
            win32net.NetUserSetInfo(None, user_name, 3, user_data)
        except Exception as ex:
            p("}}rbERROR setting password for " + user_name + "}}xx\n" +
              str(ex))

        # Add student to the students group
        p("}}yn\tAdding student to students group...}}xx")

        if not UserAccounts.set_default_groups_for_student(user_name):
            ret = False

        return ret
Example #18
0
def update(name,
           password=None,
           fullname=None,
           description=None,
           home=None,
           homedrive=None,
           logonscript=None,
           profile=None,
           expiration_date=None,
           expired=None,
           account_disabled=None,
           unlock_account=None,
           password_never_expires=None,
           disallow_change_password=None):
    r'''
    Updates settings for the windows user. Name is the only required parameter.
    Settings will only be changed if the parameter is passed a value.

    .. versionadded:: 2015.8.0

    :param str name:
        The user name to update.

    :param str password:
        New user password in plain text.

    :param str fullname:
        The user's full name.

    :param str description:
        A brief description of the user account.

    :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 logonscript:
        The path to the logon script.

    :param str profile:
        The path to the user's profile directory.

    :param date expiration_date: The date and time when the account expires. Can
        be a valid date/time string. To set to never expire pass the string 'Never'.

    :param bool expired: Pass `True` to expire the account. The user will be
        prompted to change their password at the next logon. Pass `False` to mark
        the account as 'not expired'. You can't use this to negate the expiration if
        the expiration was caused by the account expiring. You'll have to change
        the `expiration_date` as well.

    :param bool account_disabled: True disables the account. False enables the
        account.

    :param bool unlock_account: True unlocks a locked user account. False is
        ignored.

    :param bool password_never_expires: True sets the password to never expire.
        False allows the password to expire.

    :param bool disallow_change_password: True blocks the user from changing
        the password. False allows the user to change the password.

    :return: True if successful. False is unsuccessful.

    :rtype: bool

    CLI Example:

    .. code-block:: bash

        salt '*' user.update bob password=secret profile=C:\Users\Bob
                 home=\\server\homeshare\bob homedrive=U:
    '''

    # Make sure the user exists
    # Return an object containing current settings for the user
    try:
        user_info = win32net.NetUserGetInfo(None, name, 4)
    except win32net.error as exc:
        (number, context, message) = exc
        log.error('Failed to update user {0}'.format(name))
        log.error('nbr: {0}'.format(number))
        log.error('ctx: {0}'.format(context))
        log.error('msg: {0}'.format(message))
        return False

    # Check parameters to update
    # Update the user object with new settings
    if password:
        user_info['password'] = password
    if home:
        user_info['home_dir'] = home
    if homedrive:
        user_info['home_dir_drive'] = homedrive
    if description:
        user_info['comment'] = description
    if logonscript:
        user_info['script_path'] = logonscript
    if fullname:
        user_info['full_name'] = fullname
    if profile:
        user_info['profile'] = profile
    if expiration_date:
        if expiration_date == 'Never':
            user_info['acct_expires'] = win32netcon.TIMEQ_FOREVER
        else:
            date_format = _get_date_time_format(expiration_date)
            if date_format:
                dt_obj = datetime.strptime(expiration_date, date_format)
            else:
                return 'Invalid start_date'
            user_info['acct_expires'] = time.mktime(dt_obj.timetuple())
    if expired is not None:
        if expired:
            user_info['password_expired'] = 1
        else:
            user_info['password_expired'] = 0
    if account_disabled is not None:
        if account_disabled:
            user_info['flags'] |= win32netcon.UF_ACCOUNTDISABLE
        else:
            user_info['flags'] ^= win32netcon.UF_ACCOUNTDISABLE
    if unlock_account is not None:
        if unlock_account:
            user_info['flags'] ^= win32netcon.UF_LOCKOUT
    if password_never_expires is not None:
        if password_never_expires:
            user_info['flags'] |= win32netcon.UF_DONT_EXPIRE_PASSWD
        else:
            user_info['flags'] ^= win32netcon.UF_DONT_EXPIRE_PASSWD
    if disallow_change_password is not None:
        if disallow_change_password:
            user_info['flags'] |= win32netcon.UF_PASSWD_CANT_CHANGE
        else:
            user_info['flags'] ^= win32netcon.UF_PASSWD_CANT_CHANGE

    # Apply new settings
    try:
        win32net.NetUserSetInfo(None, name, 4, user_info)
    except win32net.error as exc:
        (number, context, message) = exc
        log.error('Failed to update user {0}'.format(name))
        log.error('nbr: {0}'.format(number))
        log.error('ctx: {0}'.format(context))
        log.error('msg: {0}'.format(message))
        return False

    return True