From 7c17b0d05d99e2f6a18ff61fa927e58607136273 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 21 Sep 2012 18:30:30 +0200 Subject: [PATCH 1/3] Add new option default_domain_suffix --- src/confdb/confdb.h | 1 + src/config/SSSDConfig/__init__.py.in | 1 + src/config/SSSDConfigTest.py | 4 ++ src/config/etc/sssd.api.conf | 1 + src/man/sssd.conf.5.xml | 24 ++++++++++++++ src/responder/autofs/autofssrv_cmd.c | 3 +- src/responder/common/negcache.c | 10 ++++-- src/responder/common/responder.h | 3 ++ src/responder/common/responder_common.c | 10 ++++++ src/responder/nss/nsssrv_cmd.c | 18 +++++++--- src/responder/nss/nsssrv_netgroup.c | 3 +- src/responder/nss/nsssrv_services.c | 5 ++- src/responder/pam/pamsrv_cmd.c | 31 ++++++++++++------ src/responder/ssh/sshsrv_cmd.c | 3 +- src/responder/sudo/sudosrv_query.c | 3 +- src/util/usertools.c | 52 ++++++++++++++++++++++++------ 16 files changed, 137 insertions(+), 35 deletions(-) diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index c6611f273e6a47edde8aab2504c4fa8450209110..39267d3b1d3be25c7b035a983b577ec5a9e448f0 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -66,6 +66,7 @@ #define CONFDB_MONITOR_ACTIVE_DOMAINS "domains" #define CONFDB_MONITOR_TRY_INOTIFY "try_inotify" #define CONFDB_MONITOR_KRB5_RCACHEDIR "krb5_rcache_dir" +#define CONFDB_MONITOR_DEFAULT_DOMAIN "default_domain_suffix" /* Both monitor and domains */ #define CONFDB_NAME_REGEX "re_expression" diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in index b90a8e100e38279c934b5a36ee87062d15eba4b6..5d023d780190459317ffbe83ba9ad2753501b2b3 100644 --- a/src/config/SSSDConfig/__init__.py.in +++ b/src/config/SSSDConfig/__init__.py.in @@ -54,6 +54,7 @@ option_strings = { 're_expression' : _('Regex to parse username and domain'), 'full_name_format' : _('Printf-compatible format for displaying fully-qualified names'), 'krb5_rcache_dir' : _('Directory on the filesystem where SSSD should store Kerberos replay cache files.'), + 'default_domain_suffix' : _('Domain to add to names without a domain component.'), # [nss] 'enum_cache_timeout' : _('Enumeration cache timeout length (seconds)'), diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py index b03223f46d53d4857d2aa38aee9827f201f3465f..73e1ea6923294a86a9825619bf67a58c21a635d1 100755 --- a/src/config/SSSDConfigTest.py +++ b/src/config/SSSDConfigTest.py @@ -84,6 +84,9 @@ class SSSDConfigTestValid(unittest.TestCase): self.assertTrue('full_name_format' in new_options) self.assertEquals(new_options['full_name_format'][0], str) + self.assertTrue('default_domain_suffix' in new_options) + self.assertEquals(new_options['default_domain_suffix'][0], str) + del sssdconfig def testDomains(self): @@ -277,6 +280,7 @@ class SSSDConfigTestSSSDService(unittest.TestCase): 're_expression', 'full_name_format', 'krb5_rcache_dir', + 'default_domain_suffix', 'debug_level', 'debug_timestamps', 'debug_microseconds', diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf index fe5a096231a62382b9ef5fdc1b8cb3df72040a74..f17fbb50ff8de5ab8a5368f8ba8472ab95cabfd8 100644 --- a/src/config/etc/sssd.api.conf +++ b/src/config/etc/sssd.api.conf @@ -22,6 +22,7 @@ sbus_timeout = int, None, false re_expression = str, None, false full_name_format = str, None, false krb5_rcache_dir = str, None, false +default_domain_suffix = str, None, false [nss] # Name service diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml index 652a27345a1535058af574e567529ae9e6f1fe2a..0fec5a9cdef5ddcd70bacfa08d6dd47b1ef6587a 100644 --- a/src/man/sssd.conf.5.xml +++ b/src/man/sssd.conf.5.xml @@ -214,6 +214,30 @@ + + default_domain_suffix (string) + + + This string will be used as a default domain + name for all names without a domain name + component. The main use case are environments + were the local domain is only managing hosts + but no users and all user are coming from a + trusted domain. The option allows those users + to log in just with their user name without + giving a domain name as well. + + + Please note that if this option is set all + users from the local domain have to user their + fully qualified name, e.g. user@domain.name, + to log in. + + + Default: not set + + + diff --git a/src/responder/autofs/autofssrv_cmd.c b/src/responder/autofs/autofssrv_cmd.c index 4dfa94e40a2fcb450b3b95984bfccd9b0b151486..3af4a84685f5f86daaf3e6159cef9c671fc00c39 100644 --- a/src/responder/autofs/autofssrv_cmd.c +++ b/src/responder/autofs/autofssrv_cmd.c @@ -374,7 +374,8 @@ setautomntent_send(TALLOC_CTX *mem_ctx, dctx->cmd_ctx = state->cmdctx; state->dctx = dctx; - ret = sss_parse_name_for_domains(state, client->rctx->domains, rawname, + ret = sss_parse_name_for_domains(state, client->rctx->domains, + client->rctx->default_domain, rawname, &domname, &state->mapname); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c index b59b1f341de75e63340604bfe8023a2b390510f8..5be1ea688c8770c587e3ceed008147252bf7aeca 100644 --- a/src/responder/common/negcache.c +++ b/src/responder/common/negcache.c @@ -596,7 +596,9 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache, filter_set = true; for (i = 0; (filter_list && filter_list[i]); i++) { - ret = sss_parse_name_for_domains(tmpctx, domain_list, filter_list[i], + ret = sss_parse_name_for_domains(tmpctx, domain_list, + rctx->default_domain, + filter_list[i], &domainname, &name); if (ret != EOK) { DEBUG(1, ("Invalid name in filterUsers list: [%s] (%d)\n", @@ -641,7 +643,8 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache, else if (ret != EOK) goto done; for (i = 0; (filter_list && filter_list[i]); i++) { - ret = sss_parse_name_for_domains(tmpctx, domain_list, filter_list[i], + ret = sss_parse_name_for_domains(tmpctx, domain_list, + rctx->default_domain, filter_list[i], &domainname, &name); if (ret != EOK) { DEBUG(1, ("Invalid name in filterUsers list: [%s] (%d)\n", @@ -738,7 +741,8 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache, else if (ret != EOK) goto done; for (i = 0; (filter_list && filter_list[i]); i++) { - ret = sss_parse_name_for_domains(tmpctx, domain_list, filter_list[i], + ret = sss_parse_name_for_domains(tmpctx, domain_list, + rctx->default_domain, filter_list[i], &domainname, &name); if (ret != EOK) { DEBUG(1, ("Invalid name in filterGroups list: [%s] (%d)\n", diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h index c09262d1b962806e103e1fa0ef5058d050ee078e..5bab0d3c3aee67ad9a094a7a001a3df218e7fa16 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -101,6 +101,8 @@ struct resp_ctx { size_t allowed_uids_count; uid_t *allowed_uids; + char *default_domain; + void *pvt_ctx; }; @@ -160,6 +162,7 @@ int sss_parse_name(TALLOC_CTX *memctx, int sss_parse_name_for_domains(TALLOC_CTX *memctx, struct sss_domain_info *domains, + const char *default_domain, const char *orig, char **domain, char **name); int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain, diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c index 37a08d9489647d9b06be3f12c8f4e96650fceb59..2f8cd84d41292e7f5d4f08bc1f92f6c3954bf721 100644 --- a/src/responder/common/responder_common.c +++ b/src/responder/common/responder_common.c @@ -783,6 +783,16 @@ int sss_process_init(TALLOC_CTX *mem_ctx, return ret; } + ret = confdb_get_string(rctx->cdb, rctx, CONFDB_MONITOR_CONF_ENTRY, + CONFDB_MONITOR_DEFAULT_DOMAIN, NULL, + &rctx->default_domain); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + ("Cannnot get the default domain [%d]: %s\n", + ret, strerror(ret))); + return ret; + } + ret = sss_monitor_init(rctx, rctx->ev, monitor_intf, svc_name, svc_version, rctx, &rctx->mon_conn); diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index 64fd7a587b75d30d4517ee1500b4b3b6bf8bec14..370c3d29914e43ecda9909389ae230d322f37d42 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -806,7 +806,8 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx) rawname = (const char *)body; domname = NULL; - ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname, + ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, + cctx->rctx->default_domain, rawname, &domname, &cmdctx->name); if (ret == EAGAIN) { req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, domname); @@ -878,7 +879,8 @@ static void nss_cmd_getpwnam_cb(struct tevent_req *req) goto done; } - ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname, + ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, + cctx->rctx->default_domain, rawname, &domname, &cmdctx->name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", rawname)); @@ -2293,7 +2295,8 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx) rawname = (const char *)body; domname = NULL; - ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname, + ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, + cctx->rctx->default_domain, rawname, &domname, &cmdctx->name); if (ret == EAGAIN) { req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, domname); @@ -2365,7 +2368,8 @@ static void nss_cmd_getgrnam_cb(struct tevent_req *req) goto done; } - ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname, + ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, + cctx->rctx->default_domain, rawname, &domname, &cmdctx->name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", rawname)); @@ -3423,7 +3427,8 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx) rawname = (const char *)body; domname = NULL; - ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname, + ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, + cctx->rctx->default_domain, rawname, &domname, &cmdctx->name); if (ret == EAGAIN) { req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, domname); @@ -3495,7 +3500,8 @@ static void nss_cmd_initgroups_cb(struct tevent_req *req) goto done; } - ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, rawname, + ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, + cctx->rctx->default_domain, rawname, &domname, &cmdctx->name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", rawname)); diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c index 774d182bd95ed5d80710e54c2dd2287f6a83d803..ae993fac618ba408fcdf2bbebbf90e7c77959cb0 100644 --- a/src/responder/nss/nsssrv_netgroup.c +++ b/src/responder/nss/nsssrv_netgroup.c @@ -197,7 +197,8 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx, dctx = state->dctx; dctx->cmdctx = state->cmdctx; - ret = sss_parse_name_for_domains(state, client->rctx->domains, rawname, + ret = sss_parse_name_for_domains(state, client->rctx->domains, + client->rctx->default_domain, rawname, &domname, &state->netgr_shortname); if (ret != EOK) { DEBUG(2, ("Invalid name received [%s]\n", rawname)); diff --git a/src/responder/nss/nsssrv_services.c b/src/responder/nss/nsssrv_services.c index 880058fa81c3a6d763335490ad4dfa46282498fa..d79323c349ab5e1bb25c27c022ceb490f9d1fa9f 100644 --- a/src/responder/nss/nsssrv_services.c +++ b/src/responder/nss/nsssrv_services.c @@ -780,6 +780,7 @@ done: errno_t parse_getservbyname(TALLOC_CTX *mem_ctx, uint8_t *body, size_t blen, struct sss_domain_info *domains, + char *default_domain, char **domain_name, char **service_name, char **service_protocol); @@ -821,6 +822,7 @@ int nss_cmd_getservbyname(struct cli_ctx *cctx) ret = parse_getservbyname(cmdctx, body, blen, cctx->rctx->domains, + cctx->rctx->default_domain, &domname, &service_name, &service_protocol); @@ -871,6 +873,7 @@ done: errno_t parse_getservbyname(TALLOC_CTX *mem_ctx, uint8_t *body, size_t blen, struct sss_domain_info *domains, + char *default_domain, char **domain_name, char **service_name, char **service_protocol) @@ -959,7 +962,7 @@ errno_t parse_getservbyname(TALLOC_CTX *mem_ctx, } } - ret = sss_parse_name_for_domains(tmp_ctx, domains, rawname, + ret = sss_parse_name_for_domains(tmp_ctx, domains, default_domain, rawname, &domname, &svc_name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c index 07fa96ab83a46e82a4f501e2d73cf0ef167c3cba..2b20544d1baf78ade232f93a2c91378ec6a7645c 100644 --- a/src/responder/pam/pamsrv_cmd.c +++ b/src/responder/pam/pamsrv_cmd.c @@ -119,8 +119,9 @@ static int pd_set_primary_name(const struct ldb_message *msg,struct pam_data *pd } static int pam_parse_in_data_v2(struct sss_domain_info *domains, - struct pam_data *pd, - uint8_t *body, size_t blen) + const char *default_domain, + struct pam_data *pd, + uint8_t *body, size_t blen) { size_t c; uint32_t type; @@ -156,7 +157,8 @@ static int pam_parse_in_data_v2(struct sss_domain_info *domains, ret = extract_string(&pam_user, size, body, blen, &c); if (ret != EOK) return ret; - ret = sss_parse_name_for_domains(pd, domains, pam_user, + ret = sss_parse_name_for_domains(pd, domains, + default_domain, pam_user, &pd->domain, &pd->user); if (ret != EOK) return ret; break; @@ -209,12 +211,13 @@ static int pam_parse_in_data_v2(struct sss_domain_info *domains, } static int pam_parse_in_data_v3(struct sss_domain_info *domains, - struct pam_data *pd, - uint8_t *body, size_t blen) + const char *default_domain, + struct pam_data *pd, + uint8_t *body, size_t blen) { int ret; - ret = pam_parse_in_data_v2(domains, pd, body, blen); + ret = pam_parse_in_data_v2(domains, default_domain, pd, body, blen); if (ret != EOK) { DEBUG(1, ("pam_parse_in_data_v2 failed.\n")); return ret; @@ -229,6 +232,7 @@ static int pam_parse_in_data_v3(struct sss_domain_info *domains, } static int pam_parse_in_data(struct sss_domain_info *domains, + const char *default_domain, struct pam_data *pd, uint8_t *body, size_t blen) { @@ -244,7 +248,8 @@ static int pam_parse_in_data(struct sss_domain_info *domains, for (start = end; end < last; end++) if (body[end] == '\0') break; if (body[end++] != '\0') return EINVAL; - ret = sss_parse_name_for_domains(pd, domains, (char *)&body[start], &pd->domain, &pd->user); + ret = sss_parse_name_for_domains(pd, domains, default_domain, + (char *)&body[start], &pd->domain, &pd->user); if (ret != EOK) return ret; for (start = end; end < last; end++) if (body[end] == '\0') break; @@ -997,13 +1002,19 @@ errno_t pam_forwarder_parse_data(struct cli_ctx *cctx, struct pam_data *pd) switch (cctx->cli_protocol_version->version) { case 1: - ret = pam_parse_in_data(cctx->rctx->domains, pd, body, blen); + ret = pam_parse_in_data(cctx->rctx->domains, + cctx->rctx->default_domain, pd, + body, blen); break; case 2: - ret = pam_parse_in_data_v2(cctx->rctx->domains, pd, body, blen); + ret = pam_parse_in_data_v2(cctx->rctx->domains, + cctx->rctx->default_domain, pd, + body, blen); break; case 3: - ret = pam_parse_in_data_v3(cctx->rctx->domains, pd, body, blen); + ret = pam_parse_in_data_v3(cctx->rctx->domains, + cctx->rctx->default_domain, pd, + body, blen); break; default: DEBUG(1, ("Illegal protocol version [%d].\n", diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c index 82a1f901628022134ed8dc3f4343ad30e8ebd6a9..6c10967e2650fe5518d7befdafddccab709ee2e1 100644 --- a/src/responder/ssh/sshsrv_cmd.c +++ b/src/responder/ssh/sshsrv_cmd.c @@ -701,7 +701,8 @@ ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx) } c += name_len; - ret = sss_parse_name_for_domains(cmd_ctx, cctx->rctx->domains, name, + ret = sss_parse_name_for_domains(cmd_ctx, cctx->rctx->domains, + cctx->rctx->default_domain,name, &cmd_ctx->domname, &cmd_ctx->name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Invalid name received [%s]\n", name)); diff --git a/src/responder/sudo/sudosrv_query.c b/src/responder/sudo/sudosrv_query.c index 7ba80e2ac7ca65237516ada33df39473c43dfa5f..824f682c6c753bc47f303af09f03363ad79af987 100644 --- a/src/responder/sudo/sudosrv_query.c +++ b/src/responder/sudo/sudosrv_query.c @@ -312,7 +312,8 @@ errno_t sudosrv_parse_query(TALLOC_CTX *mem_ctx, /* parse username */ - ret = sss_parse_name_for_domains(tmp_ctx, rctx->domains, rawname, + ret = sss_parse_name_for_domains(tmp_ctx, rctx->domains, + rctx->default_domain, rawname, &domainname, &username); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("Invalid name received [%s]\n", rawname)); diff --git a/src/util/usertools.c b/src/util/usertools.c index 6a5720d7cb5061cbd4c82ae7901f8370dc0865e4..0ef395497d6e56425983a62e3f920af6b6988fb8 100644 --- a/src/util/usertools.c +++ b/src/util/usertools.c @@ -310,6 +310,7 @@ static struct sss_domain_info * match_any_domain_or_subdomain_name ( int sss_parse_name_for_domains(TALLOC_CTX *memctx, struct sss_domain_info *domains, + const char *default_domain, const char *orig, char **domain, char **name) { struct sss_domain_info *dom, *match; @@ -319,7 +320,7 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx, char *candidate_domain = NULL; bool name_mismatch = false; TALLOC_CTX *tmp_ctx; - int code; + int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) @@ -329,8 +330,8 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx, rdomain = NULL; for (dom = domains; dom != NULL; dom = dom->next) { - code = sss_parse_name(tmp_ctx, dom->names, orig, &dmatch, &nmatch); - if (code == EOK) { + ret = sss_parse_name(tmp_ctx, dom->names, orig, &dmatch, &nmatch); + if (ret == EOK) { /* * If the name matched without the domain part, make note of it. * All the other domain expressions must agree on the domain-less @@ -363,28 +364,55 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx, } /* EINVAL is returned when name doesn't match */ - } else if (code != EINVAL) { - talloc_free(tmp_ctx); - return code; + } else if (ret != EINVAL) { + goto done; } } if (rdomain == NULL && rname == NULL) { if (candidate_name && !name_mismatch) { - DEBUG(SSSDBG_FUNC_DATA, - ("name '%s' matched without domain, user is %s\n", orig, nmatch)); + DEBUG(SSSDBG_FUNC_DATA, ("name '%s' matched without domain, " \ + "user is %s\n", orig, nmatch)); rdomain = NULL; + if (default_domain != NULL) { + rdomain = talloc_strdup(tmp_ctx, default_domain); + if (default_domain == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n")); + ret = ENOMEM; + goto done; + } + + for (dom = domains; dom != NULL; dom = dom->next) { + match = match_any_domain_or_subdomain_name(dom, rdomain); + if (match != NULL) { + break; + } + } + if (match == NULL) { + DEBUG(SSSDBG_FUNC_DATA, ("default domain [%s] is currently " \ + "not know, trying to look it up.\n", + rdomain)); + *domain = talloc_steal(memctx, rdomain); + ret = EAGAIN; + goto done; + } + } + + DEBUG(SSSDBG_FUNC_DATA, ("using default domain [%s]\n", rdomain)); + rname = candidate_name; } else if (candidate_domain) { *domain = talloc_steal(memctx, candidate_domain); - return EAGAIN; + ret = EAGAIN; + goto done; } } if (rdomain == NULL && rname == NULL) { DEBUG(SSSDBG_TRACE_FUNC, ("name '%s' did not match any domain's expression\n", orig)); - return EINVAL; + ret = EINVAL; + goto done; } if (domain != NULL) { @@ -395,9 +423,11 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx, *name = talloc_steal(memctx, rname); } + ret = EOK; +done: talloc_free(tmp_ctx); - return EOK; + return ret; } char * -- 1.7.7.6