Skip to content

Commit f2ca48f

Browse files
committed
Rework handling of UUID user home in check_account_accessible to correctly
look up user X509 ID before checking account access. The default X509 user format should remain functionally unchanged despite minor adjustments. Extra care is needed while following the relative alias links from email, short ID and X509 DN to the final UUID user home. Additionally we must be cautious about the link traversal loop always terminating to avoid unpleasant surprises.
1 parent b121108 commit f2ca48f

1 file changed

Lines changed: 32 additions & 6 deletions

File tree

mig/shared/accountstate.py

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -453,17 +453,43 @@ def check_account_accessible(configuration, username, proto, environ=None,
453453
# Use client_id_dir to make it work even if already expanded
454454
home_dir = os.path.join(configuration.user_home,
455455
client_id_dir(client_id))
456+
# Expand to actual home dir and proceed from there
457+
expanded_home = os.path.realpath(home_dir)
456458
if configuration.site_user_id_format == X509_USER_ID_FORMAT:
457-
# Expand to actual home dir
458-
expanded_home = os.path.realpath(home_dir)
459+
client_dir = os.path.basename(expanded_home)
459460
elif configuration.site_user_id_format == UUID_USER_ID_FORMAT:
460-
# Only follow first username -> client_id_dir symlink with UUID
461-
expanded_home = os.readlink(home_dir)
461+
# Traverse home_dir links to X509 dir name linking to expanded_home
462+
next_link = home_dir
463+
client_dir = None
464+
expansions, max_expansions = 0, 3
465+
while os.path.islink(next_link) and expansions < max_expansions:
466+
_logger.debug("compare next link %s to expanded %s" %
467+
(next_link, expanded_home))
468+
if os.readlink(next_link) == expanded_home:
469+
# Next link is the wanted X509 link to expanded UUID home
470+
_logger.debug("found %s account ID dir: %s -> %s" %
471+
(client_id, next_link, expanded_home))
472+
client_dir = os.path.basename(next_link)
473+
break
474+
else:
475+
# follow next_link and prepend user_home if relative
476+
next_link = os.readlink(next_link)
477+
max_expansions += 1
478+
if os.path.basename(next_link) == next_link:
479+
next_link = os.path.join(configuration.user_home,
480+
next_link)
481+
if client_dir is None:
482+
_logger.debug("link traversal for %s ended at %s" %
483+
(client_id, next_link))
484+
_logger.warning("failed to lookup home and ID for %s" %
485+
username)
486+
return False
462487
else:
463488
raise ValueError("invalid user ID format requested: %s" %
464489
configuration.site_user_id_format)
465-
real_id = os.path.basename(expanded_home)
466-
client_id = client_dir_id(real_id)
490+
491+
# Now we can extract the desired X509 user ID
492+
client_id = client_dir_id(client_dir)
467493

468494
(account_accessible, account_status, _) = check_account_status(
469495
configuration, client_id)

0 commit comments

Comments
 (0)