Closed mintyhippoxyz closed 1 year ago
There are two ways sudo's LDAP code can support netgroups for users.
(&(objectClass=sudoRole)(|(sudoUser=+*)(sudoUser=!+*)))
to get all the rules containing netgroups and iterate over the result using innetgr(3)
to match the results to the user.The matching of a host to a netgroup always uses the innetgr(3)
C library function. That matching happens outside the LDAP code so you will need to configure a debug file in the /etc/sudo.conf file. For example:
Debug sudoers.so /var/log/sudoers_debug match@debug
would log debug info about user and host matches. The debug info you are looking for should be in the netgr_matches()
function that looks like:
netgroup alpine-test matches (alpine-test|alpine-test.example.com, , example.com): true
or
netgroup alpine-test matches (alpine-test|alpine-test.example.com, , example.com): false
However, it doesn't look to me like musl libc supports the innetgr()
function. If that is the case you won't see that output for netgr_matches()
.
In both cases I get the same debug output when it comes across +assist
Mar 7 03:22:11.206 sudo[8979] host alpine-test (alpine-test) matches sudoers host +assist: false
Mar 7 03:22:11.206 sudo[8979] <- host_matches @ ./match.c:364 := -1
Mar 7 03:22:11.206 sudo[8979] <- hostlist_matches_int @ ./match.c:301 := -1
Mar 7 03:22:11.206 sudo[8979] -> hostlist_matches_int @ ./match.c:294
Mar 7 03:22:11.206 sudo[8979] -> host_matches @ ./match.c:328
Mar 7 03:22:11.206 sudo[8979] -> netgr_matches @ ./match.c:641
Mar 7 03:22:11.206 sudo[8979] netgroups are disabled
Mar 7 03:22:11.206 sudo[8979] <- netgr_matches @ ./match.c:645 := false
I think as far as I'm following things (knowing very little about c) I can see why without netgroup_base I don't see the (&(objectClass=sudoRole)(|(sudoUser=+*)(sudoUser=!+*)))
query.
I should say, I do have a Buildroot system that I'm pretty sure uses musl libc and has sudo working with netgroups.
sudo: searching from base 'ou=sudoers,dc=example,dc=com'
sudo: adding search result
sudo: result now has 1 entries
sudo: ldap search '(&(objectClass=sudoRole)(sudoUser=*)(sudoUser=+*))'
sudo: searching from base 'ou=sudoers,dc=example,dc=com'
sudo: adding search result
sudo: result now has 1 entries
sudo: sorting remaining 1 entries
sudo: searching LDAP for sudoers entries
sudo: Command allowed
sudo: LDAP entry: 0x903ae10
sudo: done with LDAP searches
sudo: user_matches=true
sudo: host_matches=true
sudo: sudo_ldap_lookup(0)=0x02
Mar 6 22:16:43 sudo[11258] netgroup all matches (buildroot-host.example.com|buildroot-host, , ): true @ netgr_matches() ./match.c:998
Mar 6 22:16:43 sudo[11258] <- netgr_matches @ ./match.c:1001 := true
Mar 6 22:16:43 sudo[11258] -> addr_matches @ ./match_addr.c:195
Mar 6 22:16:43 sudo[11258] -> addr_matches_if @ ./match_addr.c:56
Mar 6 22:16:43 sudo[11258] <- addr_matches_if @ ./match_addr.c:66 := false
It's not using netgroup_base and I can see it running a slight variation of that query (&(objectClass=sudoRole)(sudoUser=*)(sudoUser=+*))
, maybe due to being an older version (1.9.8p2)
Is there anything useful I could maybe gather from that system?
I just checked my alpine build log:
checking for innetgr... no
So I don't think you can use host netgroups on that system.
Alright, thanks for the clarification. At least it's not a deal breaking issue.
Just noticed you've been putting in some work on supporting this. Wasn't expecting that but it's very much appreciated!
Maybe jumping the gun here but doesn't seem to be working yet compiling from git/main.
host alpine-test.example.com (alpine-test) matches sudoers host +assist: false
If there's any value I can add testing/debugging let me know.
It should work if _netgroupbase is set in sudo's ldap.conf file. If that doesn't work, you can enable debugging in either sudo.conf or ldap.conf to see the exact query sudo is using and try that with, e.g. the ldapsearch utility. For example, in my testing I get debug output like the following with sudoers_debug set to 2 in ldap.conf:
sudo: searching from netgroup_base 'ou=netgroup,dc=sudo,dc=ws'
sudo: ldap netgroup search filter: '(&(objectClass=nisNetgroup)(cn=sudo-hosts))'
With sudo.conf debugging there are more details (date strings removed for readability):
sudo[17435] -> sudo_ldap_innetgr_base @ ../../../trunk/plugins/sudoers/ldap_innetgr.c:148
sudo[17435] ldap netgroup search filter: '(&(objectClass=nisNetgroup)(cn=sudo-test-hosts))'
sudo[17435] searching from netgroup_base 'ou=netgroup,dc=sudo,dc=ws'
sudo[17435] -> sudo_ldap_innetgr_base @ ../../../trunk/plugins/sudoers/ldap_innetgr.c:148
sudo[17435] ldap netgroup search filter: '(&(objectClass=nisNetgroup)(cn=sudo-hosts))'
sudo[17435] searching from netgroup_base 'ou=netgroup,dc=sudo,dc=ws'
sudo[17435] -> sudo_ldap_match_netgroup @ ../../../trunk/plugins/sudoers/ldap_innetgr.c:98
sudo[17435] sudo_ldap_match_netgroup: matching (xerxes,,sudo.ws) against (xerxes,,)
sudo[17435] -> sudo_ldap_netgroup_match_str @ ../../../trunk/plugins/sudoers/ldap_innetgr.c:55
sudo[17435] sudo_ldap_netgroup_match_str: compare "xerxes" to "xerxes"
sudo[17435] <- sudo_ldap_netgroup_match_str @ ../../../trunk/plugins/sudoers/ldap_innetgr.c:80 := true
sudo[17435] -> sudo_ldap_netgroup_match_str @ ../../../trunk/plugins/sudoers/ldap_innetgr.c:55
sudo[17435] sudo_ldap_netgroup_match_str: compare "" to ""
sudo[17435] <- sudo_ldap_netgroup_match_str @ ../../../trunk/plugins/sudoers/ldap_innetgr.c:72 := true
sudo[17435] -> sudo_ldap_netgroup_match_str @ ../../../trunk/plugins/sudoers/ldap_innetgr.c:55
sudo[17435] sudo_ldap_netgroup_match_str: compare "sudo.ws" to ""
sudo[17435] <- sudo_ldap_netgroup_match_str @ ../../../trunk/plugins/sudoers/ldap_innetgr.c:72 := true
sudo[17435] <- sudo_ldap_match_netgroup @ ../../../trunk/plugins/sudoers/ldap_innetgr.c:130 := 1
sudo[17435] <- sudo_ldap_innetgr_base @ ../../../trunk/plugins/sudoers/ldap_innetgr.c:229 := 1
Got netgroup_base
defined.
It's still looking for a triple containing my username.
sudo: sudo_ldap_query: ldap search user matta, host alpine-test.example.com
sudo: Looking up netgroups for matta
sudo: ldap netgroup search filter: '(&(objectClass=nisNetgroup)(|(nisNetgroupTriple=\28*,matta,*\29)))'
sudo: searching from netgroup_base 'ou=Netgroup,dc=example,dc=com'
And I don't see any of the sudo_ldap_innetgr_base
output in the sudoers_debug log like you have there.
Your LDAP server may not support querying nisNetgroupTriple. OpenLDAP's slapd, for example, does not support that in their nis schema. The sudoers.ldap man page talk about this in the section on NETGROUP_BASE.
Oh, yes, that does appear to be the case... I'm using OpenLDAP
attributetype ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple'
DESC 'Netgroup triple'
SYNTAX 1.3.6.1.1.1.0.0 )
I'll look into changing that but does make me curious why it's never been a problem on Gentoo.
If you are not using netgroup_base
sudo will query all sudoRole objects where sudoUser starts with a '+' and then use the system innetgr() to determine whether the invoking user is a member. So it is just a different mechanism. It would be possible for sudo to do this itself but there would need to be another ldap.conf (or perhaps sudoOption) setting to enable it.
Sadly the schema change seems to have made no difference. Must be some other weirdness with my setup or I'm just missing something.
Not sure if this is useful but out of curiosity I tried setting my username in the triple (alpine-test,matta,)
and even that doesn't work. With that I do see something different sudo: ldap netgroup search filter: '(&(objectClass=nisNetgroup)(|(memberNisNetgroup=assist)))'
but none of the sudo_ldap_innetgr_base
debug info. From what you shared it looks like I should be seeing '(&(objectClass=nisNetgroup)(cn=assist))'
instead.
FYI, I think I found the issue with this on Alpine. The problem is that sudo checks for the innetgr() function and, if it doesn't exist, avoids compiling some of sudo's netgroup support. I changed that in 6fddb2875c23c437f4fe911e92435b9fa3ac35c3 and have been able to do netgroup queries on Alpine using sudo's own LDAP netgroup code.
I've been trying to get sudo setup on Alpine Linux with ldap auth. I got it working for the most part but I'm having issues getting it to use netgroups.
Netgroups & sudoers are setup like this in ldap, which works with my Gentoo systems.
I've been compiling with these args
--with-pam --with-ldap --with-ldap-conf-file=/etc/ldap.conf.sudo
And I've tried both with and without nsswitch
--with-nsswitch=no
--with-nsswitch=/etc/nsswitch.conf.sudo
(I didn't use the standardnsswitch.conf
becausemusl-nscd
gets a syntax error withsudoers: ldap
)ldap.conf.sudo
nsswitch.conf.sudo
The filter in the "ldap search" debug output
'(&(objectClass=sudoRole)(|(sudoUser=matta)...
does getcn=assist,ou=sudoers,dc=example,dc=com
in it's results, if that's helpful at all.I do see this one debug difference on Gentoo
Compared to Alpine
Then this may be sending me in the wrong direction since I've never set it on Gentoo but I've noticed that when I set
netgroup_base
in ldap.conf.sudo I get some additional debug output that I don't see w/o it. It appears to append a filter that would only match if I set a username in the nisNetgroupTriple. I actually tried that to no avail as well.