Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow UID to be returned by the mapper script. #3795

Merged
merged 9 commits into from
Sep 25, 2024
7 changes: 7 additions & 0 deletions mod_ood_proxy/lib/ood/user_map.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ function map(r, user_map_match, user_map_cmd, remote_user)
handle:close()
end

-- if sys_user is a number, then it's the uid, so convert to username
if tonumber(sys_user) then
local pwd = require "posix.pwd"
sys_user = pwd.getpwuid(tonumber(sys_user)).pw_name
end

time_user_map = (r:clock() - now)/1000.0
r:debug("Mapped '" .. remote_user .. "' => '" .. (sys_user or "") .. "' [" .. time_user_map .. " ms]")

Expand All @@ -25,6 +31,7 @@ function map(r, user_map_match, user_map_cmd, remote_user)
return nil
end


r.subprocess_env['MAPPED_USER'] = sys_user -- set as CGI variable for later hooks (i.e., analytics)
r.subprocess_env['OOD_TIME_USER_MAP'] = time_user_map -- set as CGI variable for later hooks (i.e., analytics)
return sys_user
Expand Down
51 changes: 38 additions & 13 deletions nginx_stage/lib/nginx_stage/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,37 @@ class User
# @param user [String] the user name defining this object
# @raise [ArgumentError] if user or primary group doesn't exist on local system
def initialize(user)
@passwd = Etc.getpwnam user.to_s
@group = Etc.getgrgid gid
@groups = get_groups

if name.to_s != user.to_s
err_msg = <<~HEREDOC
Username '#{user}' is being mapped to '#{name}' in SSSD and they don't match.
Users with domain names cannot be mapped correctly. If '#{name}' still has the
domain in it you'll need to set SSSD's full_name_format to '%1$s'.
# See if user is all numbers (potentially uid), regexp is 8% faster than integer conversion
# Benchmark: 0.13 microseconds per call (1M cycles)
if user.match?(/\A\d+\z/)
# The user is composed of all numbers, (numeric string)
# 10 microseconds per call if it matches
# 203 microseconds per call if it doesn't match (only happens if username is all numbers but not a uid)
begin
@passwd = Etc.getpwuid(user.to_i)
rescue ArgumentError
# We got a number as a username but we failed the lookup, fallthrough to the string lookup
end
end

See https://github.com/OSC/ondemand/issues/1759 for more details.
HEREDOC
# Variable is not set, so the user is a string
unless @passwd
# Benchmark: 13 microseconds per call (1M cycles)
@passwd = Etc.getpwnam(user)
if name.to_s != user.to_s
err_msg = <<~HEREDOC
Username '#{user}' is being mapped to '#{name}' in SSSD and they don't match.
Users with domain names cannot be mapped correctly. If '#{name}' still has the
domain in it you'll need to set SSSD's full_name_format to '%1$s'.

See https://github.com/OSC/ondemand/issues/1759 for more details.
HEREDOC

raise StandardError, err_msg
raise StandardError, err_msg
end
end
@group = Etc.getgrgid gid
@groups = get_groups
end

# User's primary group name
Expand Down Expand Up @@ -79,7 +95,16 @@ def to_str
# Use `id` to get list of groups as the /etc/group file can give
# erroneous results
def get_groups
`id -nG #{name}`.split(' ')
# Group names can contain spaces, prevent "domain users" people from being added to the "users" group
# We retrieve GIDs and convert to names (or GID)
`id -G #{name}`.split(' ').map(&:to_i).map do |gid|
begin
Etc.getgrgid(gid).name
rescue ArgumentError
# Still return the GID as a string if the group doesn't exist
gid.to_s
end
end
end
end
end
Loading