21
21
from passlib .hosts import linux_context
22
22
from psutil import users
23
23
from pwd import getpwall
24
- from pwd import getpwnam
25
24
from pwd import getpwuid
26
25
from sys import exit
27
26
from time import sleep
36
35
from vyos .utils .auth import EPasswdStrength
37
36
from vyos .utils .auth import evaluate_strength
38
37
from vyos .utils .auth import get_current_user
38
+ from vyos .utils .auth import get_local_users
39
+ from vyos .utils .auth import get_user_home_dir
40
+ from vyos .utils .auth import MIN_USER_UID
39
41
from vyos .utils .configfs import delete_cli_node
40
42
from vyos .utils .configfs import add_cli_node
41
43
from vyos .utils .dict import dict_search
44
+ from vyos .utils .file import move_recursive
42
45
from vyos .utils .permission import chown
43
46
from vyos .utils .process import cmd
44
47
from vyos .utils .process import call
55
58
tacacs_nss_config_file = "/etc/tacplus_nss.conf"
56
59
nss_config_file = "/etc/nsswitch.conf"
57
60
58
- # Minimum UID used when adding system users
59
- MIN_USER_UID : int = 1000
60
- # Maximim UID used when adding system users
61
- MAX_USER_UID : int = 59999
62
61
# LOGIN_TIMEOUT from /etc/loign.defs minus 10 sec
63
62
MAX_RADIUS_TIMEOUT : int = 50
64
63
# MAX_RADIUS_TIMEOUT divided by 2 sec (minimum recomended timeout)
67
66
MAX_TACACS_COUNT : int = 8
68
67
# Minimum USER id for TACACS users
69
68
MIN_TACACS_UID = 900
70
- # List of local user accounts that must be preserved
71
- SYSTEM_USER_SKIP_LIST : list = ['radius_user' , 'radius_priv_user' , 'tacacs0' , 'tacacs1' ,
72
- 'tacacs2' , 'tacacs3' , 'tacacs4' , 'tacacs5' , 'tacacs6' ,
73
- 'tacacs7' , 'tacacs8' , 'tacacs9' , 'tacacs10' ,' tacacs11' ,
74
- 'tacacs12' , 'tacacs13' , 'tacacs14' , 'tacacs15' ]
75
-
76
- def get_local_users (min_uid = MIN_USER_UID , max_uid = MAX_USER_UID ):
77
- """Return list of dynamically allocated users (see Debian Policy Manual)"""
78
- local_users = []
79
- for s_user in getpwall ():
80
- if getpwnam (s_user .pw_name ).pw_uid < min_uid :
81
- continue
82
- if getpwnam (s_user .pw_name ).pw_uid > max_uid :
83
- continue
84
- if s_user .pw_name in SYSTEM_USER_SKIP_LIST :
85
- continue
86
- local_users .append (s_user .pw_name )
87
-
88
- return local_users
69
+
89
70
90
71
def get_shadow_password (username ):
91
72
with open ('/etc/shadow' ) as f :
@@ -364,9 +345,10 @@ def apply(login):
364
345
tmp = dict_search ('full_name' , user_config )
365
346
if tmp : command += f" --comment '{ tmp } '"
366
347
367
- tmp = dict_search ('home_directory' , user_config )
368
- if tmp : command += f" --home '{ tmp } '"
369
- else : command += f" --home '/home/{ user } '"
348
+ home_directory = dict_search ('home_directory' , user_config )
349
+ if not home_directory :
350
+ home_directory = f'/home/{ user } '
351
+ command += f" --home '{ home_directory } '"
370
352
371
353
if 'operator' not in user_config :
372
354
command += f' --groups frr,frrvty,vyattacfg,sudo,adm,dip,disk,_kea'
@@ -379,7 +361,7 @@ def apply(login):
379
361
# crazy user will choose username root or any other system user which will fail.
380
362
#
381
363
# XXX: Should we deny using root at all?
382
- home_dir = getpwnam (user ). pw_dir
364
+ home_dir = get_user_home_dir (user )
383
365
# always re-render SSH keys with appropriate permissions
384
366
render (f'{ home_dir } /.ssh/authorized_keys' , 'login/authorized_keys.j2' ,
385
367
user_config , permission = 0o600 ,
@@ -399,6 +381,17 @@ def apply(login):
399
381
except Exception as e :
400
382
raise ConfigError (f'Adding user "{ user } " raised exception: "{ e } "' )
401
383
384
+ # After invoking 'useradd' for each user, if /var/.users_backups/{user} exists, restore the
385
+ # backed up files to the newly created home directory. This reinstates the user's
386
+ # SSH environment and avoids loss of access or trust relationships due to the user
387
+ # creation process, which does not copy such custom files by default.
388
+ #
389
+ # More details: https://github.com/vyos/vyos-1x/pull/4678#pullrequestreview-3169648265
390
+ backup_directory = f"/var/.users_backups/{ user } "
391
+ if command .startswith ('useradd' ) and os .path .exists (backup_directory ):
392
+ move_recursive (backup_directory , home_dir )
393
+ chown (home_dir , user = user , group = 'users' , recursive = True )
394
+
402
395
# T5875: ensure UID is properly set on home directory if user is re-added
403
396
# the home directory will always exist, as it's created above by --create-home,
404
397
# retrieve current owner of home directory and adjust on demand
@@ -434,7 +427,7 @@ def apply(login):
434
427
# Disable user to prevent re-login
435
428
call (f'usermod -s /sbin/nologin { user } ' )
436
429
437
- home_dir = getpwnam (user ). pw_dir
430
+ home_dir = get_user_home_dir (user )
438
431
# Remove SSH authorized keys file
439
432
authorized_keys_file = f'{ home_dir } /.ssh/authorized_keys'
440
433
if os .path .exists (authorized_keys_file ):
0 commit comments