From 504a7e8750169300bea1bbcf4c4a2e4dcdfe7804 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 16 Nov 2011 14:09:59 +0100 Subject: [PATCH 3/6] Use the case sensitivity flag in responders --- src/confdb/confdb.c | 7 + src/confdb/confdb.h | 2 + src/config/SSSDConfig.py | 1 + src/config/SSSDConfigTest.py | 2 + src/config/etc/sssd.api.conf | 1 + src/man/sssd.conf.5.xml | 12 ++ src/responder/common/negcache.c | 267 +++++++++++++++++++++---------- src/responder/common/negcache.h | 10 +- src/responder/common/responder_common.c | 1 - src/responder/nss/nsssrv_cmd.c | 39 +++-- src/responder/nss/nsssrv_netgroup.c | 21 ++- src/responder/pam/pamsrv_cmd.c | 34 ++++- 12 files changed, 285 insertions(+), 112 deletions(-) diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c index 3f668dd3dec337afc05cea4459a4eff123161cb9..9ebe0127da81c7d26e75eca4e4136472317e534d 100644 --- a/src/confdb/confdb.c +++ b/src/confdb/confdb.c @@ -856,6 +856,13 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb, goto done; } + ret = get_entry_as_bool(res->msgs[0], &domain->case_sensitive, + CONFDB_DOMAIN_CASE_SENSITIVE, true); + if(ret != EOK) { + DEBUG(0, ("Invalid value for %s\n", CONFDB_DOMAIN_CASE_SENSITIVE)); + goto done; + } + *_domain = domain; ret = EOK; done: diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index 266e4d27189dd14d282045cc5c7e857ebc00f974..2ebbf4f46369161a443b5ba80a58245990651948 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -117,6 +117,7 @@ #define CONFDB_DOMAIN_FAMILY_ORDER "lookup_family_order" #define CONFDB_DOMAIN_ACCOUNT_CACHE_EXPIRATION "account_cache_expiration" #define CONFDB_DOMAIN_OVERRIDE_GID "override_gid" +#define CONFDB_DOMAIN_CASE_SENSITIVE "case_sensitive" /* Local Provider */ #define CONFDB_LOCAL_DEFAULT_SHELL "default_shell" @@ -150,6 +151,7 @@ struct sss_domain_info { bool cache_credentials; bool legacy_passwords; + bool case_sensitive; gid_t override_gid; const char *override_homedir; diff --git a/src/config/SSSDConfig.py b/src/config/SSSDConfig.py index 84c9bdc527bd02233eb22164593eeba8c5378196..814e1d1f7ab8531bfad620a16dc7bfda834cd58d 100644 --- a/src/config/SSSDConfig.py +++ b/src/config/SSSDConfig.py @@ -92,6 +92,7 @@ option_strings = { 'dns_resolver_timeout' : _('How long to wait for replies from DNS when resolving servers (seconds)'), 'dns_discovery_domain' : _('The domain part of service discovery DNS query'), 'override_gid' : _('Override GID value from the identity provider with this value'), + 'case_sensitive' : _('Treat usernames as case sensitive'), # [provider/ipa] 'ipa_domain' : _('IPA domain'), diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py index 16ddfe5012654dc1600b79ad90493a409b0d5c9d..8421a09147dcbc25f628b4b75f278b4824413d18 100755 --- a/src/config/SSSDConfigTest.py +++ b/src/config/SSSDConfigTest.py @@ -484,6 +484,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): 'dns_resolver_timeout', 'dns_discovery_domain', 'override_gid', + 'case_sensitive', 'override_homedir', 'id_provider', 'auth_provider', @@ -801,6 +802,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): 'dns_resolver_timeout', 'dns_discovery_domain', 'override_gid', + 'case_sensitive', 'override_homedir', 'id_provider', 'auth_provider', diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf index 6813901ed7c2598724323a5c06529ddd62121a58..c2c425cefa9ebbb2a4169e0a13d4de2594a275dd 100644 --- a/src/config/etc/sssd.api.conf +++ b/src/config/etc/sssd.api.conf @@ -72,6 +72,7 @@ filter_groups = list, str, false dns_resolver_timeout = int, None, false dns_discovery_domain = str, None, false override_gid = int, None, false +case_sensitive = bool, None, false override_homedir = str, None, false diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml index 1ed408f2e1b5ccda3f551744cbc3ea8cac7a74bf..944d8bf351beea10649e3f1eedb7b352a46be302 100644 --- a/src/man/sssd.conf.5.xml +++ b/src/man/sssd.conf.5.xml @@ -931,6 +931,18 @@ + + + case_sensitive (boolean) + + + Treat user and group names as case sensitive + + + Default: True + + + diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c index 3926574a12c898db30a1fe22ec763c2ed1d94f72..aa89bc2ab38096f98d95c032aa4df105828c2345 100644 --- a/src/responder/common/negcache.c +++ b/src/responder/common/negcache.c @@ -21,6 +21,7 @@ #include "util/util.h" #include "confdb/confdb.h" +#include "responder/common/responder.h" #include #include #include "tdb.h" @@ -158,55 +159,98 @@ done: return ret; } +static int sss_ncache_check_user_int(struct sss_nc_ctx *ctx, int ttl, + const char *domain, const char *name) +{ + char *str; + int ret; + + if (!name || !*name) return EINVAL; + + str = talloc_asprintf(ctx, "%s/%s/%s", NC_USER_PREFIX, domain, name); + if (!str) return ENOMEM; + + ret = sss_ncache_check_str(ctx, str, ttl); + + talloc_free(str); + return ret; +} + +static int sss_ncache_check_group_int(struct sss_nc_ctx *ctx, int ttl, + const char *domain, const char *name) +{ + char *str; + int ret; + + if (!name || !*name) return EINVAL; + + str = talloc_asprintf(ctx, "%s/%s/%s", NC_GROUP_PREFIX, domain, name); + if (!str) return ENOMEM; + + ret = sss_ncache_check_str(ctx, str, ttl); + + talloc_free(str); + return ret; +} + +static int sss_ncache_check_netgr_int(struct sss_nc_ctx *ctx, int ttl, + const char *domain, const char *name) +{ + char *str; + int ret; + + if (!name || !*name) return EINVAL; + + str = talloc_asprintf(ctx, "%s/%s/%s", NC_NETGROUP_PREFIX, domain, name); + if (!str) return ENOMEM; + + ret = sss_ncache_check_str(ctx, str, ttl); + + talloc_free(str); + return ret; +} + +typedef int (*ncache_check_byname_fn_t)(struct sss_nc_ctx *, int, + const char *, const char *); + +static int sss_cache_check_ent(struct sss_nc_ctx *ctx, int ttl, + struct sss_domain_info *dom, const char *name, + ncache_check_byname_fn_t checker) +{ + char *lower; + errno_t ret; + + if (dom->case_sensitive == false) { + lower = sss_tc_utf8_tolower(ctx, name); + if (!lower) return ENOMEM; + ret = checker(ctx, ttl, dom->name, lower); + talloc_free(lower); + } else { + ret = checker(ctx, ttl, dom->name, name); + } + + return ret; +} + int sss_ncache_check_user(struct sss_nc_ctx *ctx, int ttl, - const char *domain, const char *name) + struct sss_domain_info *dom, const char *name) { - char *str; - int ret; - - if (!name || !*name) return EINVAL; - - str = talloc_asprintf(ctx, "%s/%s/%s", NC_USER_PREFIX, domain, name); - if (!str) return ENOMEM; - - ret = sss_ncache_check_str(ctx, str, ttl); - - talloc_free(str); - return ret; + return sss_cache_check_ent(ctx, ttl, dom, name, + sss_ncache_check_user_int); } int sss_ncache_check_group(struct sss_nc_ctx *ctx, int ttl, - const char *domain, const char *name) + struct sss_domain_info *dom, const char *name) { - char *str; - int ret; - - if (!name || !*name) return EINVAL; - - str = talloc_asprintf(ctx, "%s/%s/%s", NC_GROUP_PREFIX, domain, name); - if (!str) return ENOMEM; - - ret = sss_ncache_check_str(ctx, str, ttl); - - talloc_free(str); - return ret; + return sss_cache_check_ent(ctx, ttl, dom, name, + sss_ncache_check_group_int); } int sss_ncache_check_netgr(struct sss_nc_ctx *ctx, int ttl, - const char *domain, const char *name) + struct sss_domain_info *dom, const char *name) { - char *str; - int ret; - - if (!name || !*name) return EINVAL; - - str = talloc_asprintf(ctx, "%s/%s/%s", NC_NETGROUP_PREFIX, domain, name); - if (!str) return ENOMEM; - - ret = sss_ncache_check_str(ctx, str, ttl); - - talloc_free(str); - return ret; + return sss_cache_check_ent(ctx, ttl, dom, name, + sss_ncache_check_netgr_int); } int sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, uid_t uid) @@ -237,55 +281,96 @@ int sss_ncache_check_gid(struct sss_nc_ctx *ctx, int ttl, gid_t gid) return ret; } +static int sss_ncache_set_user_int(struct sss_nc_ctx *ctx, bool permanent, + const char *domain, const char *name) +{ + char *str; + int ret; + + if (!name || !*name) return EINVAL; + + str = talloc_asprintf(ctx, "%s/%s/%s", NC_USER_PREFIX, domain, name); + if (!str) return ENOMEM; + + ret = sss_ncache_set_str(ctx, str, permanent); + + talloc_free(str); + return ret; +} + +static int sss_ncache_set_group_int(struct sss_nc_ctx *ctx, bool permanent, + const char *domain, const char *name) +{ + char *str; + int ret; + + if (!name || !*name) return EINVAL; + + str = talloc_asprintf(ctx, "%s/%s/%s", NC_GROUP_PREFIX, domain, name); + if (!str) return ENOMEM; + + ret = sss_ncache_set_str(ctx, str, permanent); + + talloc_free(str); + return ret; +} + +static int sss_ncache_set_netgr_int(struct sss_nc_ctx *ctx, bool permanent, + const char *domain, const char *name) +{ + char *str; + int ret; + + if (!name || !*name) return EINVAL; + + str = talloc_asprintf(ctx, "%s/%s/%s", NC_NETGROUP_PREFIX, domain, name); + if (!str) return ENOMEM; + + ret = sss_ncache_set_str(ctx, str, permanent); + + talloc_free(str); + return ret; +} + +typedef int (*ncache_set_byname_fn_t)(struct sss_nc_ctx *, bool, + const char *, const char *); + +static int sss_ncache_set_ent(struct sss_nc_ctx *ctx, bool permanent, + struct sss_domain_info *dom, const char *name, + ncache_set_byname_fn_t setter) +{ + char *lower; + errno_t ret; + + if (dom->case_sensitive == false) { + lower = sss_tc_utf8_tolower(ctx, name); + if (!lower) return ENOMEM; + ret = setter(ctx, permanent, dom->name, lower); + talloc_free(lower); + } else { + ret = setter(ctx, permanent, dom->name, name); + } + + return ret; +} + + int sss_ncache_set_user(struct sss_nc_ctx *ctx, bool permanent, - const char *domain, const char *name) + struct sss_domain_info *dom, const char *name) { - char *str; - int ret; - - if (!name || !*name) return EINVAL; - - str = talloc_asprintf(ctx, "%s/%s/%s", NC_USER_PREFIX, domain, name); - if (!str) return ENOMEM; - - ret = sss_ncache_set_str(ctx, str, permanent); - - talloc_free(str); - return ret; + return sss_ncache_set_ent(ctx, permanent, dom, name, sss_ncache_set_user_int); } int sss_ncache_set_group(struct sss_nc_ctx *ctx, bool permanent, - const char *domain, const char *name) + struct sss_domain_info *dom, const char *name) { - char *str; - int ret; - - if (!name || !*name) return EINVAL; - - str = talloc_asprintf(ctx, "%s/%s/%s", NC_GROUP_PREFIX, domain, name); - if (!str) return ENOMEM; - - ret = sss_ncache_set_str(ctx, str, permanent); - - talloc_free(str); - return ret; + return sss_ncache_set_ent(ctx, permanent, dom, name, sss_ncache_set_group_int); } int sss_ncache_set_netgr(struct sss_nc_ctx *ctx, bool permanent, - const char *domain, const char *name) + struct sss_domain_info *dom, const char *name) { - char *str; - int ret; - - if (!name || !*name) return EINVAL; - - str = talloc_asprintf(ctx, "%s/%s/%s", NC_NETGROUP_PREFIX, domain, name); - if (!str) return ENOMEM; - - ret = sss_ncache_set_str(ctx, str, permanent); - - talloc_free(str); - return ret; + return sss_ncache_set_ent(ctx, permanent, dom, name, sss_ncache_set_netgr_int); } int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool permanent, uid_t uid) @@ -409,7 +494,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache, continue; } - ret = sss_ncache_set_user(ncache, true, dom->name, name); + ret = sss_ncache_set_user(ncache, true, dom, name); if (ret != EOK) { DEBUG(1, ("Failed to store permanent user filter for [%s]" " (%d [%s])\n", filter_list[i], @@ -447,7 +532,14 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache, continue; } if (domainname) { - ret = sss_ncache_set_user(ncache, true, domainname, name); + dom = responder_get_domain(domain_list, domainname); + if (!dom) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Invalid domain name [%s]\n", domainname)); + continue; + } + + ret = sss_ncache_set_user(ncache, true, dom, name); if (ret != EOK) { DEBUG(1, ("Failed to store permanent user filter for [%s]" " (%d [%s])\n", filter_list[i], @@ -456,7 +548,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache, } } else { for (dom = domain_list; dom; dom = dom->next) { - ret = sss_ncache_set_user(ncache, true, dom->name, name); + ret = sss_ncache_set_user(ncache, true, dom, name); if (ret != EOK) { DEBUG(1, ("Failed to store permanent user filter for" " [%s:%s] (%d [%s])\n", @@ -499,7 +591,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache, continue; } - ret = sss_ncache_set_group(ncache, true, dom->name, name); + ret = sss_ncache_set_group(ncache, true, dom, name); if (ret != EOK) { DEBUG(1, ("Failed to store permanent group filter for [%s]" " (%d [%s])\n", filter_list[i], @@ -537,7 +629,14 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache, continue; } if (domainname) { - ret = sss_ncache_set_group(ncache, true, domainname, name); + dom = responder_get_domain(domain_list, domainname); + if (!dom) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Invalid domain name [%s]\n", domainname)); + continue; + } + + ret = sss_ncache_set_group(ncache, true, dom, name); if (ret != EOK) { DEBUG(1, ("Failed to store permanent group filter for" " [%s] (%d [%s])\n", filter_list[i], @@ -546,7 +645,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache, } } else { for (dom = domain_list; dom; dom = dom->next) { - ret = sss_ncache_set_group(ncache, true, dom->name, name); + ret = sss_ncache_set_group(ncache, true, dom, name); if (ret != EOK) { DEBUG(1, ("Failed to store permanent group filter for" " [%s:%s] (%d [%s])\n", diff --git a/src/responder/common/negcache.h b/src/responder/common/negcache.h index fc857fce1608b2d71a75de10a6d63158dc20ce1e..72b99c969043d42c6f1329d8b0d549cadaddb998 100644 --- a/src/responder/common/negcache.h +++ b/src/responder/common/negcache.h @@ -29,9 +29,9 @@ int sss_ncache_init(TALLOC_CTX *memctx, struct sss_nc_ctx **_ctx); /* check if the user is expired according to the passed in time to live */ int sss_ncache_check_user(struct sss_nc_ctx *ctx, int ttl, - const char *domain, const char *name); + struct sss_domain_info *dom, const char *name); int sss_ncache_check_group(struct sss_nc_ctx *ctx, int ttl, - const char *domain, const char *name); + struct sss_domain_info *dom, const char *name); int sss_ncache_check_netgr(struct sss_nc_ctx *ctx, int ttl, const char *domain, const char *name); int sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, uid_t uid); @@ -42,11 +42,11 @@ int sss_ncache_check_gid(struct sss_nc_ctx *ctx, int ttl, gid_t gid); * and the negative cache never expires (used to permanently filter out * users and groups) */ int sss_ncache_set_user(struct sss_nc_ctx *ctx, bool permanent, - const char *domain, const char *name); + struct sss_domain_info *dom, const char *name); int sss_ncache_set_group(struct sss_nc_ctx *ctx, bool permanent, - const char *domain, const char *name); + struct sss_domain_info *dom, const char *name); int sss_ncache_set_netgr(struct sss_nc_ctx *ctx, bool permanent, - const char *domain, const char *name); + struct sss_domain_info *dom, const char *name); int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool permanent, uid_t uid); int sss_ncache_set_gid(struct sss_nc_ctx *ctx, bool permanent, gid_t gid); diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c index 99b1a23aa8581e01fb2a02d36657df6c20717812..a48ac556abe82579bf9455bf7b1eb94917e391b6 100644 --- a/src/responder/common/responder_common.c +++ b/src/responder/common/responder_common.c @@ -33,7 +33,6 @@ #include #include #include "util/util.h" -#include "util/sss_utf8.h" #include "db/sysdb.h" #include "confdb/confdb.h" #include "dbus/dbus.h" diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index f0270acd26659e8005a043fd9e154723cc868d0d..b545c5ca854cba633728de55ed5c59aa7696146f 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -394,7 +394,7 @@ static int fill_pwent(struct sss_packet *packet, if (filter_users) { ncret = sss_ncache_check_user(nctx->ncache, nctx->neg_timeout, - domain, name); + dom, name); if (ncret == EEXIST) { DEBUG(4, ("User [%s@%s] filtered out! (negative cache)\n", name, domain)); @@ -715,7 +715,7 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct sss_domain_info *dom = dctx->domain; struct cli_ctx *cctx = cmdctx->cctx; - const char *name = cmdctx->name; + char *name = NULL; struct sysdb_ctx *sysdb; struct nss_ctx *nctx; int ret; @@ -740,10 +740,15 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) /* make sure to update the dctx if we changed domain */ dctx->domain = dom; + talloc_free(name); + name = dom->case_sensitive ? talloc_strdup(dctx, cmdctx->name) : + sss_tc_utf8_tolower(dctx, cmdctx->name); + if (!name) return ENOMEM; + /* verify this user has not yet been negatively cached, * or has been permanently filtered */ ret = sss_ncache_check_user(nctx->ncache, nctx->neg_timeout, - dom->name, name); + dom, name); /* if neg cached, return we didn't find it */ if (ret == EEXIST) { @@ -781,7 +786,7 @@ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) if (dctx->res->count == 0 && !dctx->check_provider) { /* set negative cache only if not result of cache check */ - ret = sss_ncache_set_user(nctx->ncache, false, dom->name, name); + ret = sss_ncache_set_user(nctx->ncache, false, dom, name); if (ret != EOK) { return ret; } @@ -1788,7 +1793,7 @@ static int fill_grent(struct sss_packet *packet, if (filter_groups) { ret = sss_ncache_check_group(nctx->ncache, - nctx->neg_timeout, domain, name); + nctx->neg_timeout, dom, name); if (ret == EEXIST) { DEBUG(4, ("Group [%s@%s] filtered out! (negative cache)\n", name, domain)); @@ -1866,7 +1871,7 @@ static int fill_grent(struct sss_packet *packet, if (nctx->filter_users_in_groups) { ret = sss_ncache_check_user(nctx->ncache, nctx->neg_timeout, - domain, name); + dom, name); if (ret == EEXIST) { DEBUG(6, ("Group [%s] member [%s@%s] filtered out!" " (negative cache)\n", @@ -2002,7 +2007,7 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx) struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct sss_domain_info *dom = dctx->domain; struct cli_ctx *cctx = cmdctx->cctx; - const char *name = cmdctx->name; + char *name = NULL; struct sysdb_ctx *sysdb; struct nss_ctx *nctx; int ret; @@ -2027,10 +2032,15 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx) /* make sure to update the dctx if we changed domain */ dctx->domain = dom; + talloc_free(name); + name = dom->case_sensitive ? talloc_strdup(dctx, cmdctx->name) : + sss_tc_utf8_tolower(dctx, cmdctx->name); + if (!name) return ENOMEM; + /* verify this group has not yet been negatively cached, * or has been permanently filtered */ ret = sss_ncache_check_group(nctx->ncache, nctx->neg_timeout, - dom->name, name); + dom, name); /* if neg cached, return we didn't find it */ if (ret == EEXIST) { @@ -2068,7 +2078,7 @@ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx) if (dctx->res->count == 0 && !dctx->check_provider) { /* set negative cache only if not result of cache check */ - ret = sss_ncache_set_group(nctx->ncache, false, dom->name, name); + ret = sss_ncache_set_group(nctx->ncache, false, dom, name); if (ret != EOK) { return ret; } @@ -3068,7 +3078,7 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx) struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct sss_domain_info *dom = dctx->domain; struct cli_ctx *cctx = cmdctx->cctx; - const char *name = cmdctx->name; + const char *name = NULL; struct sysdb_ctx *sysdb; struct nss_ctx *nctx; int ret; @@ -3093,10 +3103,15 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx) /* make sure to update the dctx if we changed domain */ dctx->domain = dom; + talloc_free(NULL); + name = dom->case_sensitive ? talloc_strdup(dctx, cmdctx->name) : + sss_tc_utf8_tolower(dctx, cmdctx->name); + if (!name) return ENOMEM; + /* verify this user has not yet been negatively cached, * or has been permanently filtered */ ret = sss_ncache_check_user(nctx->ncache, nctx->neg_timeout, - dom->name, name); + dom, name); /* if neg cached, return we didn't find it */ if (ret == EEXIST) { @@ -3130,7 +3145,7 @@ static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx) if (dctx->res->count == 0 && !dctx->check_provider) { /* set negative cache only if not result of cache check */ - ret = sss_ncache_set_user(nctx->ncache, false, dom->name, name); + ret = sss_ncache_set_user(nctx->ncache, false, dom, name); if (ret != EOK) { return ret; } diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c index 09d07df105c2ab0681a63e58bfdd231711429eb5..113bcdd3ff98f7e8a2a29b9ef7074fee656bba29 100644 --- a/src/responder/nss/nsssrv_netgroup.c +++ b/src/responder/nss/nsssrv_netgroup.c @@ -378,6 +378,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx) struct sss_domain_info *dom = step_ctx->dctx->domain; struct getent_ctx *netgr; struct sysdb_ctx *sysdb; + char *name = NULL; /* Check each domain for this netgroup name */ while (dom) { @@ -400,8 +401,13 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx) /* make sure to update the dctx if we changed domain */ step_ctx->dctx->domain = dom; + talloc_free(NULL); + name = dom->case_sensitive ? \ + talloc_strdup(step_ctx, step_ctx->name) : + sss_tc_utf8_tolower(step_ctx, step_ctx->name); + DEBUG(4, ("Requesting info for [%s@%s]\n", - step_ctx->name, dom->name)); + name, dom->name)); ret = sysdb_get_ctx_from_list(step_ctx->rctx->db_list, dom, &sysdb); if (ret != EOK) { DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n")); @@ -409,7 +415,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx) } /* Look up the netgroup in the cache */ - ret = sysdb_getnetgr(step_ctx->dctx, sysdb, step_ctx->name, + ret = sysdb_getnetgr(step_ctx->dctx, sysdb, name, &step_ctx->dctx->res); if (ret == ENOENT) { /* This netgroup was not found in this domain */ @@ -442,7 +448,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx) if (ret == ENOENT) { /* This netgroup was not found in this domain */ DEBUG(2, ("No results for netgroup %s (domain %s)\n", - step_ctx->name, dom->name)); + name, dom->name)); if (!step_ctx->dctx->check_provider) { if (step_ctx->check_next) { @@ -469,7 +475,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx) step_ctx->nctx, step_ctx->dctx->res, SSS_DP_NETGR, - step_ctx->name, 0, + name, 0, lookup_netgr_dp_callback, step_ctx); if (ret != EOK) { @@ -482,7 +488,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx) /* Results found */ DEBUG(6, ("Returning info for netgroup [%s@%s]\n", - step_ctx->name, dom->name)); + name, dom->name)); netgr->ready = true; netgr->found = true; set_netgr_lifetime(dom->entry_cache_timeout, step_ctx, netgr); @@ -490,8 +496,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx) } /* If we've gotten here, then no domain contained this netgroup */ - DEBUG(2, ("No matching domain found for [%s], fail!\n", - step_ctx->name)); + DEBUG(2, ("No matching domain found for [%s], fail!\n", name)); netgr = talloc_zero(step_ctx->nctx, struct getent_ctx); if (netgr == NULL) { @@ -501,7 +506,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx) netgr->found = false; netgr->entries = NULL; netgr->lookup_table = step_ctx->nctx->netgroups; - netgr->name = talloc_strdup(netgr, step_ctx->name); + netgr->name = talloc_strdup(netgr, name); if (netgr->name == NULL) { DEBUG(1, ("talloc_strdup failed.\n")); talloc_free(netgr); diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c index 5f77697fd33779d9cb48f993d7a8368cef8b3928..24ccaf13354c60a0ca4e71f84a3f478cac3f8f87 100644 --- a/src/responder/pam/pamsrv_cmd.c +++ b/src/responder/pam/pamsrv_cmd.c @@ -93,6 +93,25 @@ static int extract_uint32_t(uint32_t *var, size_t size, uint8_t *body, return EOK; } +static int pd_set_primary_name(const struct ldb_message *msg,struct pam_data *pd) +{ + const char *name; + + name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, 0); + if (!name) { + DEBUG(SSSDBG_CRIT_FAILURE, ("A user with no name?\n")); + return EIO; + } + + if (strcmp(pd->user, name)) { + DEBUG(SSSDBG_TRACE_FUNC, ("User's primary name is %s\n", name)); + pd->user = talloc_strdup(pd, name); + if (!pd->user) return ENOMEM; + } + + return EOK; +} + static int pam_parse_in_data_v2(struct sss_names_ctx *snctx, struct pam_data *pd, uint8_t *body, size_t blen) @@ -767,7 +786,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd) if (dom->fqnames) continue; ncret = sss_ncache_check_user(pctx->ncache, pctx->neg_timeout, - dom->name, pd->user); + dom, pd->user); if (ncret == ENOENT) { /* User not found in the negative cache * Proceed with PAM actions @@ -810,7 +829,7 @@ static int pam_check_user_search(struct pam_auth_req *preq) { struct sss_domain_info *dom = preq->domain; struct cli_ctx *cctx = preq->cctx; - const char *name = preq->pd->user; + const char *name = NULL; struct sysdb_ctx *sysdb; time_t cacheExpire; int ret; @@ -835,6 +854,10 @@ static int pam_check_user_search(struct pam_auth_req *preq) /* make sure to update the preq if we changed domain */ preq->domain = dom; + talloc_free(NULL); + name = dom->case_sensitive ? talloc_strdup(preq, preq->pd->user) : + sss_tc_utf8_tolower(preq, preq->pd->user); + /* Refresh the user's cache entry on any PAM query * We put a timeout in the client context so that we limit * the number of updates within a reasonable timeout @@ -890,6 +913,13 @@ static int pam_check_user_search(struct pam_auth_req *preq) DEBUG(6, ("Returning info for user [%s@%s]\n", name, dom->name)); + /* We might have searched by alias. Pass on the primary name */ + ret = pd_set_primary_name(preq->res->msgs[0], preq->pd); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, ("Could not canonicalize username\n")); + return ret; + } + return EOK; } -- 1.7.7.3