#NEWLINE# def present( name , uid = None , gid = None , gid_from_name = False , groups = None , optional_groups = None , remove_groups = True , home = None , createhome = True , password = None , hash_password = False , enforce_password = True , empty_password = False , shell = None , unique = True , system = False , fullname = None , roomnumber = None , workphone = None , homephone = None , loginclass = None , date = None , mindays = None , maxdays = None , inactdays = None , warndays = None , expire = None , win_homedrive = None , win_profile = None , win_logonscript = None , win_description = None ) : #NEWLINE# #INDENT# '\n    Ensure that the named user is present with the specified properties\n\n    name\n        The name of the user to manage\n\n    uid\n        The user id to assign, if left empty then the next available user id\n        will be assigned\n\n    gid\n        The default group id. Also accepts group name.\n\n    gid_from_name\n        If True, the default group id will be set to the id of the group with\n        the same name as the user, Default is ``False``.\n\n    groups\n        A list of groups to assign the user to, pass a list object. If a group\n        specified here does not exist on the minion, the state will fail.\n        If set to the empty list, the user will be removed from all groups\n        except the default group. If unset, salt will assume current groups\n        are still wanted (see issue #28706).\n\n    optional_groups\n        A list of groups to assign the user to, pass a list object. If a group\n        specified here does not exist on the minion, the state will silently\n        ignore it.\n\n    NOTE: If the same group is specified in both "groups" and\n    "optional_groups", then it will be assumed to be required and not optional.\n\n    remove_groups\n        Remove groups that the user is a member of that weren\'t specified in\n        the state, Default is ``True``.\n\n    home\n        The custom login directory of user. Uses default value of underlying\n        system if not set. Notice that this directory does not have to exist.\n        This also the location of the home directory to create if createhome is\n        set to True.\n\n    createhome\n        If False, the home directory will not be created if it doesn\'t exist.\n        Please note that directories leading up to the home directory\n        will NOT be created, Default is ``True``.\n\n    password\n        A password hash to set for the user. This field is only supported on\n        Linux, FreeBSD, NetBSD, OpenBSD, and Solaris. If the ``empty_password``\n        argument is set to ``True`` then ``password`` is ignored.\n        For Windows this is the plain text password.\n        For Linux, the hash can be generated with ``openssl passwd -1``.\n\n    .. versionchanged:: 0.16.0\n       BSD support added.\n\n    hash_password\n        Set to True to hash the clear text password. Default is ``False``.\n\n\n    enforce_password\n        Set to False to keep the password from being changed if it has already\n        been set and the password hash differs from what is specified in the\n        "password" field. This option will be ignored if "password" is not\n        specified, Default is ``True``.\n\n    empty_password\n        Set to True to enable password-less login for user, Default is ``False``.\n\n    shell\n        The login shell, defaults to the system default shell\n\n    unique\n        Require a unique UID, Default is ``True``.\n\n    system\n        Choose UID in the range of FIRST_SYSTEM_UID and LAST_SYSTEM_UID, Default is\n        ``False``.\n\n    loginclass\n        The login class, defaults to empty\n        (BSD only)\n\n    User comment field (GECOS) support (currently Linux, BSD, and MacOS\n    only):\n\n    The below values should be specified as strings to avoid ambiguities when\n    the values are loaded. (Especially the phone and room number fields which\n    are likely to contain numeric data)\n\n    fullname\n        The user\'s full name\n\n    roomnumber\n        The user\'s room number (not supported in MacOS)\n\n    workphone\n        The user\'s work phone number (not supported in MacOS)\n\n    homephone\n        The user\'s home phone number (not supported in MacOS)\n\n    .. versionchanged:: 2014.7.0\n       Shadow attribute support added.\n\n    Shadow attributes support (currently Linux only):\n\n    The below values should be specified as integers.\n\n    date\n        Date of last change of password, represented in days since epoch\n        (January 1, 1970).\n\n    mindays\n        The minimum number of days between password changes.\n\n    maxdays\n        The maximum number of days between password changes.\n\n    inactdays\n        The number of days after a password expires before an account is\n        locked.\n\n    warndays\n        Number of days prior to maxdays to warn users.\n\n    expire\n        Date that account expires, represented in days since epoch (January 1,\n        1970).\n\n    The below parameters apply to windows only:\n\n    win_homedrive (Windows Only)\n        The drive letter to use for the home directory. If not specified the\n        home directory will be a unc path. Otherwise the home directory will be\n        mapped to the specified drive. Must be a letter followed by a colon.\n        Because of the colon, the value must be surrounded by single quotes. ie:\n        - win_homedrive: \'U:\n\n        .. versionchanged:: 2015.8.0\n\n    win_profile (Windows Only)\n        The custom profile directory of the user. Uses default value of\n        underlying system if not set.\n\n        .. versionchanged:: 2015.8.0\n\n    win_logonscript (Windows Only)\n        The full path to the logon script to run when the user logs in.\n\n        .. versionchanged:: 2015.8.0\n\n    win_description (Windows Only)\n        A brief description of the purpose of the users account.\n\n        .. versionchanged:: 2015.8.0\n    ' #NEWLINE# if ( password and hash_password ) : #NEWLINE# #INDENT# log . debug ( 'Hashing a clear text password' ) #NEWLINE# password = __salt__ [ 'shadow.gen_password' ] ( password ) #NEWLINE# #UNINDENT# if ( fullname is not None ) : #NEWLINE# #INDENT# fullname = sdecode ( fullname ) #NEWLINE# #UNINDENT# if ( roomnumber is not None ) : #NEWLINE# #INDENT# roomnumber = sdecode ( roomnumber ) #NEWLINE# #UNINDENT# if ( workphone is not None ) : #NEWLINE# #INDENT# workphone = sdecode ( workphone ) #NEWLINE# #UNINDENT# if ( homephone is not None ) : #NEWLINE# #INDENT# homephone = sdecode ( homephone ) #NEWLINE# #UNINDENT# ret = { #NEWLINE# #INDENT# 'name' : name , #NEWLINE# 'changes' : { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } , #NEWLINE# 'result' : True , #NEWLINE# 'comment' : 'User {0} is present and up to date' . format ( name ) , #NEWLINE# #UNINDENT# } #NEWLINE# for gecos_field in [ 'fullname' , 'roomnumber' , 'workphone' , 'homephone' ] : #NEWLINE# #INDENT# if ( isinstance ( gecos_field , string_types ) and ( ',' in gecos_field ) ) : #NEWLINE# #INDENT# ret [ 'comment' ] = "Unsupported char ',' in {0}" . format ( gecos_field ) #NEWLINE# ret [ 'result' ] = False #NEWLINE# return ret #NEWLINE# #UNINDENT# #UNINDENT# if groups : #NEWLINE# #INDENT# missing_groups = [ x for x in groups if ( not __salt__ [ 'group.info' ] ( x ) ) ] #NEWLINE# if missing_groups : #NEWLINE# #INDENT# ret [ 'comment' ] = 'The following group(s) are not present: {0}' . format ( ',' . join ( missing_groups ) ) #NEWLINE# ret [ 'result' ] = False #NEWLINE# return ret #NEWLINE# #UNINDENT# #UNINDENT# if optional_groups : #NEWLINE# #INDENT# present_optgroups = [ x for x in optional_groups if __salt__ [ 'group.info' ] ( x ) ] #NEWLINE# for missing_optgroup in [ x for x in optional_groups if ( x not in present_optgroups ) ] : #NEWLINE# #INDENT# log . debug ( 'Optional group "{0}" for user "{1}" is not present' . format ( missing_optgroup , name ) ) #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# present_optgroups = None #NEWLINE# #UNINDENT# if ( groups and optional_groups ) : #NEWLINE# #INDENT# for isected in set ( groups ) . intersection ( optional_groups ) : #NEWLINE# #INDENT# log . warning ( 'Group "{0}" specified in both groups and optional_groups for user {1}' . format ( isected , name ) ) #NEWLINE# #UNINDENT# #UNINDENT# if gid_from_name : #NEWLINE# #INDENT# gid = __salt__ [ 'file.group_to_gid' ] ( name ) #NEWLINE# #UNINDENT# if empty_password : #NEWLINE# #INDENT# __salt__ [ 'shadow.del_password' ] ( name ) #NEWLINE# #UNINDENT# changes = _changes ( name , uid , gid , groups , present_optgroups , remove_groups , home , createhome , password , enforce_password , empty_password , shell , fullname , roomnumber , workphone , homephone , loginclass , date , mindays , maxdays , inactdays , warndays , expire , win_homedrive , win_profile , win_logonscript , win_description ) #NEWLINE# if changes : #NEWLINE# #INDENT# if __opts__ [ 'test' ] : #NEWLINE# #INDENT# ret [ 'result' ] = None #NEWLINE# ret [ 'comment' ] = 'The following user attributes are set to be changed:\n' #NEWLINE# for ( key , val ) in iteritems ( changes ) : #NEWLINE# #INDENT# if ( key == 'password' ) : #NEWLINE# #INDENT# val = 'XXX-REDACTED-XXX' #NEWLINE# #UNINDENT# ret [ 'comment' ] += '{0}: {1}\n' . format ( key , val ) #NEWLINE# #UNINDENT# return ret #NEWLINE# #UNINDENT# if ( 'shadow.info' in __salt__ ) : #NEWLINE# #INDENT# lshad = __salt__ [ 'shadow.info' ] ( name ) #NEWLINE# #UNINDENT# if ( __grains__ [ 'kernel' ] in ( 'OpenBSD' , 'FreeBSD' ) ) : #NEWLINE# #INDENT# lcpre = __salt__ [ 'user.get_loginclass' ] ( gid ) #NEWLINE# #UNINDENT# pre = __salt__ [ 'user.info' ] ( name ) #NEWLINE# for ( key , val ) in iteritems ( changes ) : #NEWLINE# #INDENT# if ( ( key == 'passwd' ) and ( not empty_password ) ) : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_password' ] ( name , password ) #NEWLINE# continue #NEWLINE# #UNINDENT# if ( key == 'date' ) : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_date' ] ( name , date ) #NEWLINE# continue #NEWLINE# #UNINDENT# if ( ( key == 'home' ) and ( 'homeDoesNotExist' not in changes ) ) : #NEWLINE# #INDENT# if ( __grains__ [ 'kernel' ] == 'Darwin' ) : #NEWLINE# #INDENT# __salt__ [ 'user.chhome' ] ( name , val ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# __salt__ [ 'user.chhome' ] ( name , val , False ) #NEWLINE# #UNINDENT# continue #NEWLINE# #UNINDENT# if ( key == 'homeDoesNotExist' ) : #NEWLINE# #INDENT# if ( __grains__ [ 'kernel' ] == 'Darwin' ) : #NEWLINE# #INDENT# __salt__ [ 'user.chhome' ] ( name , val ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# __salt__ [ 'user.chhome' ] ( name , val , True ) #NEWLINE# #UNINDENT# if ( not os . path . isdir ( val ) ) : #NEWLINE# #INDENT# __salt__ [ 'file.mkdir' ] ( val , pre [ 'uid' ] , pre [ 'gid' ] , 493 ) #NEWLINE# #UNINDENT# continue #NEWLINE# #UNINDENT# if ( key == 'mindays' ) : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_mindays' ] ( name , mindays ) #NEWLINE# continue #NEWLINE# #UNINDENT# if ( key == 'maxdays' ) : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_maxdays' ] ( name , maxdays ) #NEWLINE# continue #NEWLINE# #UNINDENT# if ( key == 'inactdays' ) : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_inactdays' ] ( name , inactdays ) #NEWLINE# continue #NEWLINE# #UNINDENT# if ( key == 'warndays' ) : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_warndays' ] ( name , warndays ) #NEWLINE# continue #NEWLINE# #UNINDENT# if ( key == 'expire' ) : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_expire' ] ( name , expire ) #NEWLINE# continue #NEWLINE# #UNINDENT# if ( key == 'win_homedrive' ) : #NEWLINE# #INDENT# __salt__ [ 'user.update' ] ( name = name , homedrive = val ) #NEWLINE# continue #NEWLINE# #UNINDENT# if ( key == 'win_profile' ) : #NEWLINE# #INDENT# __salt__ [ 'user.update' ] ( name = name , profile = val ) #NEWLINE# continue #NEWLINE# #UNINDENT# if ( key == 'win_logonscript' ) : #NEWLINE# #INDENT# __salt__ [ 'user.update' ] ( name = name , logonscript = val ) #NEWLINE# continue #NEWLINE# #UNINDENT# if ( key == 'win_description' ) : #NEWLINE# #INDENT# __salt__ [ 'user.update' ] ( name = name , description = val ) #NEWLINE# continue #NEWLINE# #UNINDENT# if ( key == 'groups' ) : #NEWLINE# #INDENT# __salt__ [ 'user.ch{0}' . format ( key ) ] ( name , val , ( not remove_groups ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# __salt__ [ 'user.ch{0}' . format ( key ) ] ( name , val ) #NEWLINE# #UNINDENT# #UNINDENT# post = __salt__ [ 'user.info' ] ( name ) #NEWLINE# spost = { #NEWLINE# #INDENT# #NEWLINE# #UNINDENT# } #NEWLINE# if ( ( 'shadow.info' in __salt__ ) and ( lshad [ 'passwd' ] != password ) ) : #NEWLINE# #INDENT# spost = __salt__ [ 'shadow.info' ] ( name ) #NEWLINE# #UNINDENT# if ( __grains__ [ 'kernel' ] in ( 'OpenBSD' , 'FreeBSD' ) ) : #NEWLINE# #INDENT# lcpost = __salt__ [ 'user.get_loginclass' ] ( name ) #NEWLINE# #UNINDENT# for key in post : #NEWLINE# #INDENT# if ( post [ key ] != pre [ key ] ) : #NEWLINE# #INDENT# ret [ 'changes' ] [ key ] = post [ key ] #NEWLINE# #UNINDENT# #UNINDENT# if ( 'shadow.info' in __salt__ ) : #NEWLINE# #INDENT# for key in spost : #NEWLINE# #INDENT# if ( lshad [ key ] != spost [ key ] ) : #NEWLINE# #INDENT# if ( key == 'passwd' ) : #NEWLINE# #INDENT# ret [ 'changes' ] [ key ] = 'XXX-REDACTED-XXX' #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# ret [ 'changes' ] [ key ] = spost [ key ] #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# if ( ( __grains__ [ 'kernel' ] in ( 'OpenBSD' , 'FreeBSD' ) ) and ( lcpost != lcpre ) ) : #NEWLINE# #INDENT# ret [ 'changes' ] [ 'loginclass' ] = lcpost #NEWLINE# #UNINDENT# if ret [ 'changes' ] : #NEWLINE# #INDENT# ret [ 'comment' ] = 'Updated user {0}' . format ( name ) #NEWLINE# #UNINDENT# changes = _changes ( name , uid , gid , groups , present_optgroups , remove_groups , home , createhome , password , enforce_password , empty_password , shell , fullname , roomnumber , workphone , homephone , loginclass , date , mindays , maxdays , inactdays , warndays , expire , win_homedrive , win_profile , win_logonscript , win_description ) #NEWLINE# if changes : #NEWLINE# #INDENT# ret [ 'comment' ] = 'These values could not be changed: {0}' . format ( changes ) #NEWLINE# ret [ 'result' ] = False #NEWLINE# #UNINDENT# return ret #NEWLINE# #UNINDENT# if ( changes is False ) : #NEWLINE# #INDENT# if __opts__ [ 'test' ] : #NEWLINE# #INDENT# ret [ 'result' ] = None #NEWLINE# ret [ 'comment' ] = 'User {0} set to be added' . format ( name ) #NEWLINE# return ret #NEWLINE# #UNINDENT# if ( groups and present_optgroups ) : #NEWLINE# #INDENT# groups . extend ( present_optgroups ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if present_optgroups : #NEWLINE# #INDENT# groups = present_optgroups [ : ] #NEWLINE# #UNINDENT# #UNINDENT# if ( not salt . utils . is_windows ( ) ) : #NEWLINE# #INDENT# params = { #NEWLINE# #INDENT# 'name' : name , #NEWLINE# 'uid' : uid , #NEWLINE# 'gid' : gid , #NEWLINE# 'groups' : groups , #NEWLINE# 'home' : home , #NEWLINE# 'shell' : shell , #NEWLINE# 'unique' : unique , #NEWLINE# 'system' : system , #NEWLINE# 'fullname' : fullname , #NEWLINE# 'roomnumber' : roomnumber , #NEWLINE# 'workphone' : workphone , #NEWLINE# 'homephone' : homephone , #NEWLINE# 'createhome' : createhome , #NEWLINE# 'loginclass' : loginclass , #NEWLINE# #UNINDENT# } #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# params = { #NEWLINE# #INDENT# 'name' : name , #NEWLINE# 'password' : password , #NEWLINE# 'fullname' : fullname , #NEWLINE# 'description' : win_description , #NEWLINE# 'groups' : groups , #NEWLINE# 'home' : home , #NEWLINE# 'homedrive' : win_homedrive , #NEWLINE# 'profile' : win_profile , #NEWLINE# 'logonscript' : win_logonscript , #NEWLINE# #UNINDENT# } #NEWLINE# #UNINDENT# if __salt__ [ 'user.add' ] ( ** params ) : #NEWLINE# #INDENT# ret [ 'comment' ] = 'New user {0} created' . format ( name ) #NEWLINE# ret [ 'changes' ] = __salt__ [ 'user.info' ] ( name ) #NEWLINE# if ( not createhome ) : #NEWLINE# #INDENT# ret [ 'changes' ] [ 'home' ] = '' #NEWLINE# #UNINDENT# if ( ( 'shadow.info' in __salt__ ) and ( not salt . utils . is_windows ( ) ) and ( not salt . utils . is_darwin ( ) ) ) : #NEWLINE# #INDENT# if ( password and ( not empty_password ) ) : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_password' ] ( name , password ) #NEWLINE# spost = __salt__ [ 'shadow.info' ] ( name ) #NEWLINE# if ( spost [ 'passwd' ] != password ) : #NEWLINE# #INDENT# ret [ 'comment' ] = 'User {0} created but failed to set password to {1}' . format ( name , 'XXX-REDACTED-XXX' ) #NEWLINE# ret [ 'result' ] = False #NEWLINE# #UNINDENT# ret [ 'changes' ] [ 'password' ] = 'XXX-REDACTED-XXX' #NEWLINE# #UNINDENT# if date : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_date' ] ( name , date ) #NEWLINE# spost = __salt__ [ 'shadow.info' ] ( name ) #NEWLINE# if ( spost [ 'lstchg' ] != date ) : #NEWLINE# #INDENT# ret [ 'comment' ] = 'User {0} created but failed to set last change date to {1}' . format ( name , date ) #NEWLINE# ret [ 'result' ] = False #NEWLINE# #UNINDENT# ret [ 'changes' ] [ 'date' ] = date #NEWLINE# #UNINDENT# if mindays : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_mindays' ] ( name , mindays ) #NEWLINE# spost = __salt__ [ 'shadow.info' ] ( name ) #NEWLINE# if ( spost [ 'min' ] != mindays ) : #NEWLINE# #INDENT# ret [ 'comment' ] = 'User {0} created but failed to set minimum days to {1}' . format ( name , mindays ) #NEWLINE# ret [ 'result' ] = False #NEWLINE# #UNINDENT# ret [ 'changes' ] [ 'mindays' ] = mindays #NEWLINE# #UNINDENT# if maxdays : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_maxdays' ] ( name , maxdays ) #NEWLINE# spost = __salt__ [ 'shadow.info' ] ( name ) #NEWLINE# if ( spost [ 'max' ] != maxdays ) : #NEWLINE# #INDENT# ret [ 'comment' ] = 'User {0} created but failed to set maximum days to {1}' . format ( name , maxdays ) #NEWLINE# ret [ 'result' ] = False #NEWLINE# #UNINDENT# ret [ 'changes' ] [ 'maxdays' ] = maxdays #NEWLINE# #UNINDENT# if inactdays : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_inactdays' ] ( name , inactdays ) #NEWLINE# spost = __salt__ [ 'shadow.info' ] ( name ) #NEWLINE# if ( spost [ 'inact' ] != inactdays ) : #NEWLINE# #INDENT# ret [ 'comment' ] = 'User {0} created but failed to set inactive days to {1}' . format ( name , inactdays ) #NEWLINE# ret [ 'result' ] = False #NEWLINE# #UNINDENT# ret [ 'changes' ] [ 'inactdays' ] = inactdays #NEWLINE# #UNINDENT# if warndays : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_warndays' ] ( name , warndays ) #NEWLINE# spost = __salt__ [ 'shadow.info' ] ( name ) #NEWLINE# if ( spost [ 'warn' ] != warndays ) : #NEWLINE# #INDENT# ret [ 'comment' ] = 'User {0} created but failed to set warn days to {1}' . format ( name , warndays ) #NEWLINE# ret [ 'result' ] = False #NEWLINE# #UNINDENT# ret [ 'changes' ] [ 'warndays' ] = warndays #NEWLINE# #UNINDENT# if expire : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_expire' ] ( name , expire ) #NEWLINE# spost = __salt__ [ 'shadow.info' ] ( name ) #NEWLINE# if ( spost [ 'expire' ] != expire ) : #NEWLINE# #INDENT# ret [ 'comment' ] = 'User {0} created but failed to set expire days to {1}' . format ( name , expire ) #NEWLINE# ret [ 'result' ] = False #NEWLINE# #UNINDENT# ret [ 'changes' ] [ 'expire' ] = expire #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if salt . utils . is_windows ( ) : #NEWLINE# #INDENT# if ( password and ( not empty_password ) ) : #NEWLINE# #INDENT# if ( not __salt__ [ 'user.setpassword' ] ( name , password ) ) : #NEWLINE# #INDENT# ret [ 'comment' ] = 'User {0} created but failed to set password to {1}' . format ( name , 'XXX-REDACTED-XXX' ) #NEWLINE# ret [ 'result' ] = False #NEWLINE# #UNINDENT# ret [ 'changes' ] [ 'passwd' ] = 'XXX-REDACTED-XXX' #NEWLINE# #UNINDENT# if expire : #NEWLINE# #INDENT# __salt__ [ 'shadow.set_expire' ] ( name , expire ) #NEWLINE# spost = __salt__ [ 'shadow.info' ] ( name ) #NEWLINE# if ( salt . utils . date_format ( spost [ 'expire' ] ) != salt . utils . date_format ( expire ) ) : #NEWLINE# #INDENT# ret [ 'comment' ] = 'User {0} created but failed to set expire days to {1}' . format ( name , expire ) #NEWLINE# ret [ 'result' ] = False #NEWLINE# #UNINDENT# ret [ 'changes' ] [ 'expiration_date' ] = spost [ 'expire' ] #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( salt . utils . is_darwin ( ) and password and ( not empty_password ) ) : #NEWLINE# #INDENT# if ( not __salt__ [ 'shadow.set_password' ] ( name , password ) ) : #NEWLINE# #INDENT# ret [ 'comment' ] = 'User {0} created but failed to set password to {1}' . format ( name , 'XXX-REDACTED-XXX' ) #NEWLINE# ret [ 'result' ] = False #NEWLINE# #UNINDENT# ret [ 'changes' ] [ 'passwd' ] = 'XXX-REDACTED-XXX' #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# ret [ 'comment' ] = 'Failed to create new user {0}' . format ( name ) #NEWLINE# ret [ 'result' ] = False #NEWLINE# #UNINDENT# #UNINDENT# return ret