<s> '''<STR_LIT>''' <EOL> from __future__ import absolute_import <EOL> from datetime import datetime <EOL> import time <EOL> try : <EOL> from shlex import quote as _cmd_quote <EOL> except : <EOL> from pipes import quote as _cmd_quote <EOL> import salt . utils <EOL> from salt . ext . six import string_types <EOL> from salt . exceptions import CommandExecutionError <EOL> import logging <EOL> log = logging . getLogger ( __name__ ) <EOL> try : <EOL> import pywintypes <EOL> import wmi <EOL> import pythoncom <EOL> import win32api <EOL> import win32con <EOL> import win32net <EOL> import win32netcon <EOL> import win32profile <EOL> import win32security <EOL> import win32ts <EOL> HAS_WIN32NET_MODS = True <EOL> except ImportError : <EOL> HAS_WIN32NET_MODS = False <EOL> __virtualname__ = '<STR_LIT:user>' <EOL> def __virtual__ ( ) : <EOL> '''<STR_LIT>''' <EOL> if HAS_WIN32NET_MODS and salt . utils . is_windows ( ) : <EOL> return __virtualname__ <EOL> return ( False , "<STR_LIT>" ) <EOL> def add ( name , <EOL> password = None , <EOL> fullname = False , <EOL> description = None , <EOL> groups = None , <EOL> home = None , <EOL> homedrive = None , <EOL> profile = None , <EOL> logonscript = None ) : <EOL> '''<STR_LIT>''' <EOL> user_info = { } <EOL> if name : <EOL> user_info [ '<STR_LIT:name>' ] = name <EOL> else : <EOL> return False <EOL> user_info [ '<STR_LIT:password>' ] = password <EOL> user_info [ '<STR_LIT>' ] = win32netcon . USER_PRIV_USER <EOL> user_info [ '<STR_LIT>' ] = home <EOL> user_info [ '<STR_LIT>' ] = description <EOL> user_info [ '<STR_LIT>' ] = win32netcon . UF_SCRIPT <EOL> user_info [ '<STR_LIT>' ] = logonscript <EOL> try : <EOL> win32net . NetUserAdd ( None , <NUM_LIT:1> , user_info ) <EOL> except win32net . error as exc : <EOL> ( number , context , message ) = exc <EOL> log . error ( '<STR_LIT>' . format ( name ) ) <EOL> log . error ( '<STR_LIT>' . format ( number ) ) <EOL> log . error ( '<STR_LIT>' . format ( context ) ) <EOL> log . error ( '<STR_LIT>' . format ( message ) ) <EOL> return False <EOL> update ( name = name , <EOL> homedrive = homedrive , <EOL> profile = profile , <EOL> fullname = fullname ) <EOL> ret = chgroups ( name , groups ) if groups else True <EOL> return ret <EOL> def update ( name , <EOL> password = None , <EOL> fullname = None , <EOL> description = None , <EOL> home = None , <EOL> homedrive = None , <EOL> logonscript = None , <EOL> profile = None , <EOL> expiration_date = None , <EOL> expired = None , <EOL> account_disabled = None , <EOL> unlock_account = None , <EOL> password_never_expires = None , <EOL> disallow_change_password = None ) : <EOL> r'''<STR_LIT>''' <EOL> try : <EOL> user_info = win32net . NetUserGetInfo ( None , name , <NUM_LIT:4> ) <EOL> except win32net . error as exc : <EOL> ( number , context , message ) = exc <EOL> log . error ( '<STR_LIT>' . format ( name ) ) <EOL> log . error ( '<STR_LIT>' . format ( number ) ) <EOL> log . error ( '<STR_LIT>' . format ( context ) ) <EOL> log . error ( '<STR_LIT>' . format ( message ) ) <EOL> return False <EOL> if password : <EOL> user_info [ '<STR_LIT:password>' ] = password <EOL> if home : <EOL> user_info [ '<STR_LIT>' ] = home <EOL> if homedrive : <EOL> user_info [ '<STR_LIT>' ] = homedrive <EOL> if description : <EOL> user_info [ '<STR_LIT>' ] = description <EOL> if logonscript : <EOL> user_info [ '<STR_LIT>' ] = logonscript <EOL> if fullname : <EOL> user_info [ '<STR_LIT>' ] = fullname <EOL> if profile : <EOL> user_info [ '<STR_LIT>' ] = profile <EOL> if expiration_date : <EOL> if expiration_date == '<STR_LIT>' : <EOL> user_info [ '<STR_LIT>' ] = win32netcon . TIMEQ_FOREVER <EOL> else : <EOL> try : <EOL> dt_obj = salt . utils . date_cast ( expiration_date ) <EOL> except ( ValueError , RuntimeError ) : <EOL> return '<STR_LIT>' . format ( expiration_date ) <EOL> user_info [ '<STR_LIT>' ] = time . mktime ( dt_obj . timetuple ( ) ) <EOL> if expired is not None : <EOL> if expired : <EOL> user_info [ '<STR_LIT>' ] = <NUM_LIT:1> <EOL> else : <EOL> user_info [ '<STR_LIT>' ] = <NUM_LIT:0> <EOL> if account_disabled is not None : <EOL> if account_disabled : <EOL> user_info [ '<STR_LIT>' ] |= win32netcon . UF_ACCOUNTDISABLE <EOL> else : <EOL> user_info [ '<STR_LIT>' ] ^= win32netcon . UF_ACCOUNTDISABLE <EOL> if unlock_account is not None : <EOL> if unlock_account : <EOL> user_info [ '<STR_LIT>' ] ^= win32netcon . UF_LOCKOUT <EOL> if password_never_expires is not None : <EOL> if password_never_expires : <EOL> user_info [ '<STR_LIT>' ] |= win32netcon . UF_DONT_EXPIRE_PASSWD <EOL> else : <EOL> user_info [ '<STR_LIT>' ] ^= win32netcon . UF_DONT_EXPIRE_PASSWD <EOL> if disallow_change_password is not None : <EOL> if disallow_change_password : <EOL> user_info [ '<STR_LIT>' ] |= win32netcon . UF_PASSWD_CANT_CHANGE <EOL> else : <EOL> user_info [ '<STR_LIT>' ] ^= win32netcon . UF_PASSWD_CANT_CHANGE <EOL> try : <EOL> win32net . NetUserSetInfo ( None , name , <NUM_LIT:4> , user_info ) <EOL> except win32net . error as exc : <EOL> ( number , context , message ) = exc <EOL> log . error ( '<STR_LIT>' . format ( name ) ) <EOL> log . error ( '<STR_LIT>' . format ( number ) ) <EOL> log . error ( '<STR_LIT>' . format ( context ) ) <EOL> log . error ( '<STR_LIT>' . format ( message ) ) <EOL> return False <EOL> return True <EOL> def delete ( name , <EOL> purge = False , <EOL> force = False ) : <EOL> '''<STR_LIT>''' <EOL> try : <EOL> user_info = win32net . NetUserGetInfo ( None , name , <NUM_LIT:4> ) <EOL> except win32net . error as exc : <EOL> ( number , context , message ) = exc <EOL> log . error ( '<STR_LIT>' . format ( name ) ) <EOL> log . error ( '<STR_LIT>' . format ( number ) ) <EOL> log . error ( '<STR_LIT>' . format ( context ) ) <EOL> log . error ( '<STR_LIT>' . format ( message ) ) <EOL> return False <EOL> try : <EOL> sess_list = win32ts . WTSEnumerateSessions ( ) <EOL> except win32ts . error as exc : <EOL> ( number , context , message ) = exc <EOL> log . error ( '<STR_LIT>' ) <EOL> log . error ( '<STR_LIT>' . format ( number ) ) <EOL> log . error ( '<STR_LIT>' . format ( context ) ) <EOL> log . error ( '<STR_LIT>' . format ( message ) ) <EOL> logged_in = False <EOL> session_id = None <EOL> for sess in sess_list : <EOL> if win32ts . WTSQuerySessionInformation ( None , sess [ '<STR_LIT>' ] , win32ts . WTSUserName ) == name : <EOL> session_id = sess [ '<STR_LIT>' ] <EOL> logged_in = True <EOL> if logged_in : <EOL> if force : <EOL> try : <EOL> win32ts . WTSLogoffSession ( win32ts . WTS_CURRENT_SERVER_HANDLE , session_id , True ) <EOL> except win32ts . error as exc : <EOL> ( number , context , message ) = exc <EOL> log . error ( '<STR_LIT>' . format ( name ) ) <EOL> log . error ( '<STR_LIT>' . format ( number ) ) <EOL> log . error ( '<STR_LIT>' . format ( context ) ) <EOL> log . error ( '<STR_LIT>' . format ( message ) ) <EOL> return False <EOL> else : <EOL> log . error ( '<STR_LIT>' . format ( name ) ) <EOL> return False <EOL> if purge : <EOL> try : <EOL> sid = getUserSid ( name ) <EOL> win32profile . DeleteProfile ( sid ) <EOL> except pywintypes . error as exc : <EOL> ( number , context , message ) = exc <EOL> if number == <NUM_LIT:2> : <EOL> pass <EOL> else : <EOL> log . error ( '<STR_LIT>' . format ( name ) ) <EOL> log . error ( '<STR_LIT>' . format ( number ) ) <EOL> log . error ( '<STR_LIT>' . format ( context ) ) <EOL> log . error ( '<STR_LIT>' . format ( message ) ) <EOL> return False <EOL> try : <EOL> win32net . NetUserDel ( None , name ) <EOL> except win32net . error as exc : <EOL> ( number , context , message ) = exc <EOL> log . error ( '<STR_LIT>' . format ( name ) ) <EOL> log . error ( '<STR_LIT>' . format ( number ) ) <EOL> log . error ( '<STR_LIT>' . format ( context ) ) <EOL> log . error ( '<STR_LIT>' . format ( message ) ) <EOL> return False <EOL> return True <EOL> def getUserSid ( username ) : <EOL> '''<STR_LIT>''' <EOL> domain = win32api . GetComputerName ( ) <EOL> if username . find ( u'<STR_LIT:\\>' ) != - <NUM_LIT:1> : <EOL> domain = username . split ( u'<STR_LIT:\\>' ) [ <NUM_LIT:0> ] <EOL> username = username . split ( u'<STR_LIT:\\>' ) [ - <NUM_LIT:1> ] <EOL> domain = domain . upper ( ) <EOL> return win32security . ConvertSidToStringSid ( win32security . LookupAccountName ( None , domain + u'<STR_LIT:\\>' + username ) [ <NUM_LIT:0> ] ) <EOL> def setpassword ( name , password ) : <EOL> '''<STR_LIT>''' <EOL> return update ( name = name , password = password ) <EOL> def addgroup ( name , group ) : <EOL> '''<STR_LIT>''' <EOL> name = _cmd_quote ( name ) <EOL> group = _cmd_quote ( group ) . lstrip ( '<STR_LIT>' ) . rstrip ( '<STR_LIT>' ) <EOL> user = info ( name ) <EOL> if not user : <EOL> return False <EOL> if group in user [ '<STR_LIT>' ] : <EOL> return True <EOL> cmd = '<STR_LIT>' . format ( group , name ) <EOL> ret = __salt__ [ '<STR_LIT>' ] ( cmd , python_shell = True ) <EOL> return ret [ '<STR_LIT>' ] == <NUM_LIT:0> <EOL> def removegroup ( name , group ) : <EOL> '''<STR_LIT>''' <EOL> name = _cmd_quote ( name ) <EOL> group = _cmd_quote ( group ) . lstrip ( '<STR_LIT>' ) . rstrip ( '<STR_LIT>' ) <EOL> user = info ( name ) <EOL> if not user : <EOL> return False <EOL> if group not in user [ '<STR_LIT>' ] : <EOL> return True <EOL> cmd = '<STR_LIT>' . format ( group , name ) <EOL> ret = __salt__ [ '<STR_LIT>' ] ( cmd , python_shell = True ) <EOL> return ret [ '<STR_LIT>' ] == <NUM_LIT:0> <EOL> def chhome ( name , home , persist = False ) : <EOL> '''<STR_LIT>''' <EOL> pre_info = info ( name ) <EOL> if not pre_info : <EOL> return False <EOL> if home == pre_info [ '<STR_LIT>' ] : <EOL> return True <EOL> if not update ( name = name , home = home ) : <EOL> return False <EOL> if persist and home is not None and pre_info [ '<STR_LIT>' ] is not None : <EOL> cmd = '<STR_LIT>' . format ( pre_info [ '<STR_LIT>' ] , home ) <EOL> if __salt__ [ '<STR_LIT>' ] ( cmd , python_shell = False ) != <NUM_LIT:0> : <EOL> log . debug ( '<STR_LIT>' ) <EOL> post_info = info ( name ) <EOL> if post_info [ '<STR_LIT>' ] != pre_info [ '<STR_LIT>' ] : <EOL> return post_info [ '<STR_LIT>' ] == home <EOL> return False <EOL> def chprofile ( name , profile ) : <EOL> '''<STR_LIT>''' <EOL> return update ( name = name , profile = profile ) <EOL> def chfullname ( name , fullname ) : <EOL> '''<STR_LIT>''' <EOL> return update ( name = name , fullname = fullname ) <EOL> def chgroups ( name , groups , append = True ) : <EOL> '''<STR_LIT>''' <EOL> if isinstance ( groups , string_types ) : <EOL> groups = groups . split ( '<STR_LIT:U+002C>' ) <EOL> groups = [ x . strip ( '<STR_LIT>' ) for x in groups ] <EOL> ugrps = set ( list_groups ( name ) ) <EOL> if ugrps == set ( groups ) : <EOL> return True <EOL> name = _cmd_quote ( name ) <EOL> if not append : <EOL> for group in ugrps : <EOL> group = _cmd_quote ( group ) . lstrip ( '<STR_LIT>' ) . rstrip ( '<STR_LIT>' ) <EOL> if group not in groups : <EOL> cmd = '<STR_LIT>' . format ( group , name ) <EOL> __salt__ [ '<STR_LIT>' ] ( cmd , python_shell = True ) <EOL> for group in groups : <EOL> if group in ugrps : <EOL> continue <EOL> group = _cmd_quote ( group ) . lstrip ( '<STR_LIT>' ) . rstrip ( '<STR_LIT>' ) <EOL> cmd = '<STR_LIT>' . format ( group , name ) <EOL> __salt__ [ '<STR_LIT>' ] ( cmd , python_shell = True ) <EOL> agrps = set ( list_groups ( name ) ) <EOL> return len ( ugrps - agrps ) == <NUM_LIT:0> <EOL> def info ( name ) : <EOL> '''<STR_LIT>''' <EOL> ret = { } <EOL> items = { } <EOL> try : <EOL> items = win32net . NetUserGetInfo ( None , name , <NUM_LIT:4> ) <EOL> except win32net . error : <EOL> pass <EOL> if items : <EOL> groups = [ ] <EOL> try : <EOL> groups = win32net . NetUserGetLocalGroups ( None , name ) <EOL> except win32net . error : <EOL> pass <EOL> ret [ '<STR_LIT>' ] = items [ '<STR_LIT>' ] <EOL> ret [ '<STR_LIT:name>' ] = items [ '<STR_LIT:name>' ] <EOL> ret [ '<STR_LIT>' ] = win32security . ConvertSidToStringSid ( items [ '<STR_LIT>' ] ) <EOL> ret [ '<STR_LIT>' ] = items [ '<STR_LIT:password>' ] <EOL> ret [ '<STR_LIT>' ] = items [ '<STR_LIT>' ] <EOL> ret [ '<STR_LIT:description>' ] = items [ '<STR_LIT>' ] <EOL> ret [ '<STR_LIT>' ] = ( not bool ( items [ '<STR_LIT>' ] & win32netcon . UF_ACCOUNTDISABLE ) ) <EOL> ret [ '<STR_LIT>' ] = items [ '<STR_LIT>' ] <EOL> ret [ '<STR_LIT>' ] = items [ '<STR_LIT>' ] <EOL> ret [ '<STR_LIT>' ] = items [ '<STR_LIT>' ] <EOL> ret [ '<STR_LIT>' ] = items [ '<STR_LIT>' ] <EOL> secs = time . mktime ( datetime . now ( ) . timetuple ( ) ) - items [ '<STR_LIT>' ] <EOL> ret [ '<STR_LIT>' ] = datetime . fromtimestamp ( secs ) . strftime ( '<STR_LIT>' ) <EOL> if items [ '<STR_LIT>' ] == <NUM_LIT:0> : <EOL> ret [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> else : <EOL> ret [ '<STR_LIT>' ] = datetime . fromtimestamp ( items [ '<STR_LIT>' ] ) . strftime ( '<STR_LIT>' ) <EOL> ret [ '<STR_LIT>' ] = datetime . fromtimestamp ( items [ '<STR_LIT>' ] ) . strftime ( '<STR_LIT>' ) <EOL> ret [ '<STR_LIT>' ] = items [ '<STR_LIT>' ] == <NUM_LIT:1> <EOL> if not ret [ '<STR_LIT>' ] : <EOL> ret [ '<STR_LIT>' ] = _get_userprofile_from_registry ( name , ret [ '<STR_LIT>' ] ) <EOL> ret [ '<STR_LIT>' ] = items [ '<STR_LIT>' ] <EOL> ret [ '<STR_LIT>' ] = items [ '<STR_LIT>' ] <EOL> if not ret [ '<STR_LIT>' ] : <EOL> ret [ '<STR_LIT>' ] = ret [ '<STR_LIT>' ] <EOL> ret [ '<STR_LIT>' ] = groups <EOL> if items [ '<STR_LIT>' ] & win32netcon . UF_DONT_EXPIRE_PASSWD == <NUM_LIT:0> : <EOL> ret [ '<STR_LIT>' ] = False <EOL> else : <EOL> ret [ '<STR_LIT>' ] = True <EOL> if items [ '<STR_LIT>' ] & win32netcon . UF_ACCOUNTDISABLE == <NUM_LIT:0> : <EOL> ret [ '<STR_LIT>' ] = False <EOL> else : <EOL> ret [ '<STR_LIT>' ] = True <EOL> if items [ '<STR_LIT>' ] & win32netcon . UF_LOCKOUT == <NUM_LIT:0> : <EOL> ret [ '<STR_LIT>' ] = False <EOL> else : <EOL> ret [ '<STR_LIT>' ] = True <EOL> if items [ '<STR_LIT>' ] & win32netcon . UF_PASSWD_CANT_CHANGE == <NUM_LIT:0> : <EOL> ret [ '<STR_LIT>' ] = False <EOL> else : <EOL> ret [ '<STR_LIT>' ] = True <EOL> ret [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> return ret <EOL> else : <EOL> return False <EOL> def _get_userprofile_from_registry ( user , sid ) : <EOL> '''<STR_LIT>''' <EOL> profile_dir = __salt__ [ '<STR_LIT>' ] ( <EOL> '<STR_LIT>' , <EOL> u'<STR_LIT>' . format ( sid ) , <EOL> '<STR_LIT>' <EOL> ) [ '<STR_LIT>' ] <EOL> log . debug ( u'<STR_LIT>' . format ( user , profile_dir , sid ) ) <EOL> return profile_dir <EOL> def list_groups ( name ) : <EOL> '''<STR_LIT>''' <EOL> ugrp = set ( ) <EOL> try : <EOL> user = info ( name ) [ '<STR_LIT>' ] <EOL> except KeyError : <EOL> return False <EOL> for group in user : <EOL> ugrp . add ( group . strip ( '<STR_LIT>' ) ) <EOL> return sorted ( list ( ugrp ) ) <EOL> def getent ( refresh = False ) : <EOL> '''<STR_LIT>''' <EOL> if '<STR_LIT>' in __context__ and not refresh : <EOL> return __context__ [ '<STR_LIT>' ] <EOL> ret = [ ] <EOL> for user in __salt__ [ '<STR_LIT>' ] ( ) : <EOL> stuff = { } <EOL> user_info = __salt__ [ '<STR_LIT>' ] ( user ) <EOL> stuff [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> stuff [ '<STR_LIT>' ] = user_info [ '<STR_LIT>' ] <EOL> stuff [ '<STR_LIT>' ] = user_info [ '<STR_LIT>' ] <EOL> stuff [ '<STR_LIT:name>' ] = user_info [ '<STR_LIT:name>' ] <EOL> stuff [ '<STR_LIT>' ] = user_info [ '<STR_LIT>' ] <EOL> stuff [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> stuff [ '<STR_LIT>' ] = user_info [ '<STR_LIT>' ] <EOL> ret . append ( stuff ) <EOL> __context__ [ '<STR_LIT>' ] = ret <EOL> return ret <EOL> def list_users ( ) : <EOL> '''<STR_LIT>''' <EOL> res = <NUM_LIT:0> <EOL> users = [ ] <EOL> user_list = [ ] <EOL> dowhile = True <EOL> try : <EOL> while res or dowhile : <EOL> dowhile = False <EOL> ( users , _ , res ) = win32net . NetUserEnum ( <EOL> None , <EOL> <NUM_LIT:0> , <EOL> win32netcon . FILTER_NORMAL_ACCOUNT , <EOL> res , <EOL> win32netcon . MAX_PREFERRED_LENGTH <EOL> ) <EOL> for user in users : <EOL> user_list . append ( user [ '<STR_LIT:name>' ] ) <EOL> return user_list <EOL> except win32net . error : <EOL> pass <EOL> def rename ( name , new_name ) : <EOL> '''<STR_LIT>''' <EOL> current_info = info ( name ) <EOL> if not current_info : <EOL> raise CommandExecutionError ( '<STR_LIT>' . format ( name ) ) <EOL> new_info = info ( new_name ) <EOL> if new_info : <EOL> raise CommandExecutionError ( <EOL> '<STR_LIT>' . format ( new_name ) <EOL> ) <EOL> pythoncom . CoInitialize ( ) <EOL> c = wmi . WMI ( find_classes = <NUM_LIT:0> ) <EOL> try : <EOL> user = c . Win32_UserAccount ( Name = name ) [ <NUM_LIT:0> ] <EOL> except IndexError : <EOL> raise CommandExecutionError ( '<STR_LIT>' . format ( name ) ) <EOL> result = user . Rename ( new_name ) [ <NUM_LIT:0> ] <EOL> if not result == <NUM_LIT:0> : <EOL> error_dict = { <NUM_LIT:0> : '<STR_LIT>' , <EOL> <NUM_LIT:1> : '<STR_LIT>' , <EOL> <NUM_LIT:2> : '<STR_LIT>' , <EOL> <NUM_LIT:3> : '<STR_LIT>' , <EOL> <NUM_LIT:4> : '<STR_LIT>' , <EOL> <NUM_LIT:5> : '<STR_LIT>' , <EOL> <NUM_LIT:6> : '<STR_LIT>' , <EOL> <NUM_LIT:7> : '<STR_LIT>' , <EOL> <NUM_LIT:8> : '<STR_LIT>' , <EOL> <NUM_LIT:9> : '<STR_LIT>' , <EOL> <NUM_LIT:10> : '<STR_LIT>' } <EOL> raise CommandExecutionError ( <EOL> '<STR_LIT>' <EOL> . format ( name , new_name , error_dict [ result ] ) <EOL> ) <EOL> return info ( new_name ) . get ( '<STR_LIT:name>' ) == new_name <EOL> def current ( sam = False ) : <EOL> '''<STR_LIT>''' <EOL> try : <EOL> if sam : <EOL> user_name = win32api . GetUserNameEx ( win32con . NameSamCompatible ) <EOL> else : <EOL> user_name = win32api . GetUserName ( ) <EOL> except pywintypes . error as exc : <EOL> ( number , context , message ) = exc <EOL> log . error ( '<STR_LIT>' ) <EOL> log . error ( '<STR_LIT>' . format ( number ) ) <EOL> log . error ( '<STR_LIT>' . format ( context ) ) <EOL> log . error ( '<STR_LIT>' . format ( message ) ) <EOL> return False <EOL> if not user_name : <EOL> return False <EOL> return user_name </s>
