22
22
from passlib .hosts import linux_context
23
23
from psutil import users
24
24
from pwd import getpwall
25
- from pwd import getpwnam
26
25
from pwd import getpwuid
27
26
from sys import exit
28
27
from time import sleep
39
38
from vyos .utils .auth import EPasswdStrength
40
39
from vyos .utils .auth import evaluate_strength
41
40
from vyos .utils .auth import get_current_user
41
+ from vyos .utils .auth import get_local_users
42
+ from vyos .utils .auth import get_user_home_dir
43
+ from vyos .utils .auth import MIN_USER_UID
42
44
from vyos .utils .configfs import delete_cli_node
43
45
from vyos .utils .configfs import add_cli_node
44
46
from vyos .utils .dict import dict_search
47
+ from vyos .utils .file import move_recursive
45
48
from vyos .utils .permission import chown
46
49
from vyos .utils .process import cmd
47
50
from vyos .utils .process import call
59
62
nss_config_file = "/etc/nsswitch.conf"
60
63
login_motd_dsa_warning = r'/run/motd.d/92-vyos-user-dsa-deprecation-warning'
61
64
62
- # Minimum UID used when adding system users
63
- MIN_USER_UID : int = 1000
64
- # Maximim UID used when adding system users
65
- MAX_USER_UID : int = 59999
66
- # LOGIN_TIMEOUT from /etc/loign.defs minus 10 sec0
65
+ # LOGIN_TIMEOUT from /etc/loign.defs minus 10 sec
67
66
MAX_RADIUS_TIMEOUT : int = 50
68
67
# MAX_RADIUS_TIMEOUT divided by 2 sec (minimum recomended timeout)
69
68
MAX_RADIUS_COUNT : int = 8
70
69
# Maximum number of supported TACACS servers
71
70
MAX_TACACS_COUNT : int = 8
72
71
# Minimum USER id for TACACS users
73
72
MIN_TACACS_UID = 900
74
- # List of local user accounts that must be preserved
75
- SYSTEM_USER_SKIP_LIST : list = ['radius_user' , 'radius_priv_user' , 'tacacs0' , 'tacacs1' ,
76
- 'tacacs2' , 'tacacs3' , 'tacacs4' , 'tacacs5' , 'tacacs6' ,
77
- 'tacacs7' , 'tacacs8' , 'tacacs9' , 'tacacs10' ,' tacacs11' ,
78
- 'tacacs12' , 'tacacs13' , 'tacacs14' , 'tacacs15' ]
79
73
80
74
# As of OpenSSH 9.8p1 in Debian trixie, DSA keys are no longer supported
81
75
SSH_DSA_DEPRECATION_WARNING : str = f'{ SSH_DSA_DEPRECATION_WARNING } ' \
82
76
'The following users are using SSH-DSS keys for authentication.'
83
77
84
- def get_local_users (min_uid = MIN_USER_UID , max_uid = MAX_USER_UID ):
85
- """Return list of dynamically allocated users (see Debian Policy Manual)"""
86
- local_users = []
87
- for s_user in getpwall ():
88
- if getpwnam (s_user .pw_name ).pw_uid < min_uid :
89
- continue
90
- if getpwnam (s_user .pw_name ).pw_uid > max_uid :
91
- continue
92
- if s_user .pw_name in SYSTEM_USER_SKIP_LIST :
93
- continue
94
- local_users .append (s_user .pw_name )
95
-
96
- return local_users
97
78
98
79
def get_shadow_password (username ):
99
80
with open ('/etc/shadow' ) as f :
@@ -389,9 +370,10 @@ def apply(login):
389
370
tmp = dict_search ('full_name' , user_config )
390
371
if tmp : command += f" --comment '{ tmp } '"
391
372
392
- tmp = dict_search ('home_directory' , user_config )
393
- if tmp : command += f" --home '{ tmp } '"
394
- else : command += f" --home '/home/{ user } '"
373
+ home_directory = dict_search ('home_directory' , user_config )
374
+ if not home_directory :
375
+ home_directory = f'/home/{ user } '
376
+ command += f" --home '{ home_directory } '"
395
377
396
378
if 'operator' not in user_config :
397
379
command += f' --groups frr,frrvty,vyattacfg,sudo,adm,dip,disk,_kea'
@@ -404,7 +386,7 @@ def apply(login):
404
386
# crazy user will choose username root or any other system user which will fail.
405
387
#
406
388
# XXX: Should we deny using root at all?
407
- home_dir = getpwnam (user ). pw_dir
389
+ home_dir = get_user_home_dir (user )
408
390
# always re-render SSH keys with appropriate permissions
409
391
render (f'{ home_dir } /.ssh/authorized_keys' , 'login/authorized_keys.j2' ,
410
392
user_config , permission = 0o600 ,
@@ -424,6 +406,17 @@ def apply(login):
424
406
except Exception as e :
425
407
raise ConfigError (f'Adding user "{ user } " raised exception: "{ e } "' )
426
408
409
+ # After invoking 'useradd' for each user, if /var/.users_backups/{user} exists, restore the
410
+ # backed up files to the newly created home directory. This reinstates the user's
411
+ # SSH environment and avoids loss of access or trust relationships due to the user
412
+ # creation process, which does not copy such custom files by default.
413
+ #
414
+ # More details: https://github.com/vyos/vyos-1x/pull/4678#pullrequestreview-3169648265
415
+ backup_directory = f"/var/.users_backups/{ user } "
416
+ if command .startswith ('useradd' ) and os .path .exists (backup_directory ):
417
+ move_recursive (backup_directory , home_dir )
418
+ chown (home_dir , user = user , group = 'users' , recursive = True )
419
+
427
420
# T5875: ensure UID is properly set on home directory if user is re-added
428
421
# the home directory will always exist, as it's created above by --create-home,
429
422
# retrieve current owner of home directory and adjust on demand
@@ -459,7 +452,7 @@ def apply(login):
459
452
# Disable user to prevent re-login
460
453
call (f'usermod -s /sbin/nologin { user } ' )
461
454
462
- home_dir = getpwnam (user ). pw_dir
455
+ home_dir = get_user_home_dir (user )
463
456
# Remove SSH authorized keys file
464
457
authorized_keys_file = f'{ home_dir } /.ssh/authorized_keys'
465
458
if os .path .exists (authorized_keys_file ):
0 commit comments