#7819 ipa-extdom-extop issue with listing external posix user with no groups
Opened 5 months ago by stop2think. Modified 4 months ago

Environment

  • RHEL 7
  • Freeipa (Red Hat idm) domain in trust with AD using posix attributes (uidnumber, gid, gidnumber etc.) defined in AD.
  • AD has some users that do not belong to any posix groups, but have their gid (primary group) attribute defined to a common 'users' group.

Issue

When listing user that has no groups with 'id' command on client computer: 'no such user' is returned.

$ id r00a030
id: r00a030: no such user

After 15 seconds (after sssd negative cache timeout expires) 'id' command for same user correctly lists this user with its primary group.

$ id r00a030
uid=18648(r00a030) gid=200(users) groups=200(users)

I'm not 100% sure why this works the second time (why the cache is populated) but I traced the first 'no such user' issue to what I believe is a bug in ipa-extdom-extop.

Version/Release/Distribution

ipa-server-4.5.4-10.el7_5.3.x86_64
ipa-client-4.5.4-10.el7_5.3.x86_64
389-ds-base-1.3.7.5-24.el7_5.x86_64
pki-ca-10.5.1-13.1.el7_5.noarch
krb5-server-1.15.1-19.el7.x86_64

Code trace:

I traced this bug through the code in ipa-extdom-extop and this is what happens:

  • A 'REQ_FULL_WITH_GROUPS' request with input type 'INP_NAME' comes in to ipa-extdom-extop and is handled by handle_name_request function.

  • All goes well until code reaches pack_ber_user function (ipa_extdom_common.c, line: 1199) which returns LDAP_NO_SUCH_OBJECT (32).

  • pack_ber_user calls get_user_grouplist (ipa_extdom_common.c, line: 545). get_user_grouplist sets variable 'ngroups' to value 128 and allocates ngroups times size of gid_t to 'groups' variable with malloc. It then passes these variables to back_extdom_getgrouplist (ipa_extdom_common.c, line:429).

  • back_extdom_getgrouplist calls sss_nss_getgrouplist_timeout (back_extdom_sss_idmap.c, line: 261) which returns with ENOENT which gets converted into NSS_STATUS_NOTFOUND. Important part here is that ngroups variable is not modified and its value is still 128.

  • get_user_grouplist does not handle the NSS_STATUS_NOTFOUND status returned by back_extdom_getgrouplist in any way and returns LDAP_SUCCESS to pack_ber_user.

  • in pack_ber_user function the code reaches a for loop: (c = 0; c < ngroups; c++) (ipa_extdom_common.c, line: 567). Note that ngroups is still 128. Inside this loop, getgrgid_r_wrapper gets called with groups[c] which is allocated but uninitialized so its value is somewhat random. This probably returns ENOENT most of the time (because of random gid number) so pack_ber_user will return LDAP_NO_SUCH_OBJECT from this loop.

Additional info:

I will most likely try to temporarily fix this for my installation with:
-- old/back_extdom_sss_idmap.c 2017-12-04 16:39:47.573152808 +0200
+++ new/back_extdom_sss_idmap.c 2018-12-25 13:02:25.433662106 +0200
@@ -254,6 +254,9 @@
* of error and translate the return code /
if (lerrno != NULL) {
lerrno = ret;
+ if (ret == ENOENT) {
+ *ngroups = 0;
+ }
}
return __convert_sss_nss2nss_status(ret);
}
Note: I have'nt tested this yet.

However I do not feel that this is a good overall solution to the issue. The main issue seems to be that the for loop in pack_ber_user will iterate over uninitialized groups[c] variables if ngroups remains 128 and status code from back_extdom_getgrouplist is not handled in get_user_grouplist.


Did some more digging...

I think there is also an issue with sssd. sss_nss_getgrouplist_timeout seems to return ENOENT when user does not belong to any group. If user does belong to some arbitrary group it will return primary group and additional arbitrary group. The behaviour is different if user is already cached.
I believe this may be due to a difference in behaviour in SSSD-s sss_get_ex function. I think it does not return ENOENT if sss_nss_mc_get (cache) returns no values but does so if sss_nss_make_request_timeout (no cache) returns no values.

Created an issue for SSSD aswell: https://pagure.io/SSSD/sssd/issue/3915

But this one is still open, i believe there are a couple of things to think about:
- There should be some status checking in get_user_grouplist so that it would not be possible to loop over uninitialized memory in pack_ber_user.
- Should the pack_ber_user function fail when get_user_grouplist will return with something other than LDAP_SUCCESS or just skip packing groups?

Thanks. It looks like a genuine issue. I'll talk to SSSD guys this week to see when we can get their part fixed.

As you said on the SSSD bug, it affects users that have no additional POSIX group other than the primary one, so scope is a bit limited and perhaps explains why it wasn't seen before.

Metadata Update from @abbra:
- Issue assigned to abbra
- Issue set to the milestone: FreeIPA 4.6

4 months ago

Login to comment on this ticket.

Metadata