@ -206,7 +206,9 @@ options:
- Forces the use of " local " command alternatives on platforms that implement it .
- Forces the use of " local " command alternatives on platforms that implement it .
- This is useful in environments that use centralized authentification when you want to manipulate the local users
- This is useful in environments that use centralized authentification when you want to manipulate the local users
( i . e . it uses C ( luseradd ) instead of C ( useradd ) ) .
( i . e . it uses C ( luseradd ) instead of C ( useradd ) ) .
- This requires that these commands exist on the targeted host , otherwise it will be a fatal error .
- This will check C ( / etc / passwd ) for an existing account before invoking commands . If the local account database
exists somewhere other than C ( / etc / passwd ) , this setting will not work properly .
- This requires that the above commands as well as C ( / etc / passwd ) must exist on the target host , otherwise it will be a fatal error .
type : bool
type : bool
default : no
default : no
version_added : " 2.4 "
version_added : " 2.4 "
@ -446,6 +448,7 @@ class User(object):
platform = ' Generic '
platform = ' Generic '
distribution = None
distribution = None
PASSWORDFILE = ' /etc/passwd '
SHADOWFILE = ' /etc/shadow '
SHADOWFILE = ' /etc/shadow '
SHADOWFILE_EXPIRE_INDEX = 7
SHADOWFILE_EXPIRE_INDEX = 7
LOGIN_DEFS = ' /etc/login.defs '
LOGIN_DEFS = ' /etc/login.defs '
@ -840,6 +843,30 @@ class User(object):
return groups
return groups
def user_exists ( self ) :
def user_exists ( self ) :
# The pwd module does not distinguish between local and directory accounts.
# It's output cannot be used to determine whether or not an account exists locally.
# It returns True if the account exists locally or in the directory, so instead
# look in the local PASSWORD file for an existing account.
if self . local :
if not os . path . exists ( self . PASSWORDFILE ) :
self . module . fail_json ( msg = " ' local: true ' specified but unable to find local account file {0} to parse. " . format ( self . PASSWORDFILE ) )
exists = False
name_test = ' {0} : ' . format ( self . name )
with open ( self . PASSWORDFILE , ' rb ' ) as f :
reversed_lines = f . readlines ( ) [ : : - 1 ]
for line in reversed_lines :
if line . startswith ( to_bytes ( name_test ) ) :
exists = True
break
self . module . warn (
" ' local: true ' specified and user was not found in {file} . "
" The local user account may already exist if the local account database exists somewhere other than {file} . " . format ( file = self . PASSWORDFILE ) )
return exists
else :
try :
try :
if pwd . getpwnam ( self . name ) :
if pwd . getpwnam ( self . name ) :
return True
return True