char * sss_get_domain_name(TALLOC_CTX *mem_ctx, const char *orig_name, struct sss_domain_info *dom) { char *user_name; char *domain = NULL; int ret; /* check if the name already contains domain part */ if (dom->names != NULL) { ret = sss_parse_name(mem_ctx, dom->names, orig_name, &domain, NULL); if (ret == ERR_REGEX_NOMATCH) { DEBUG(SSSDBG_TRACE_FUNC, "sss_parse_name could not parse domain from [%s]. " "Assuming it is not FQDN.\n", orig_name); } else if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "sss_parse_name failed [%d]: %s\n", ret, sss_strerror(ret)); return NULL; } } if (IS_SUBDOMAIN(dom) && dom->fqnames && domain == NULL) { /* we always use the fully qualified name for subdomain users */ user_name = sss_tc_fqname(mem_ctx, dom->names, dom, orig_name); } else { user_name = talloc_strdup(mem_ctx, orig_name); } talloc_free(domain); return user_name; }
struct sss_domain_info * find_domain_by_object_name(struct sss_domain_info *domain, const char *object_name) { TALLOC_CTX *tmp_ctx; struct sss_domain_info *dom = NULL; char *domainname = NULL; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return NULL; } ret = sss_parse_name(tmp_ctx, domain->names, object_name, &domainname, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse name '%s' [%d]: %s\n", object_name, ret, sss_strerror(ret)); goto done; } if (domainname == NULL) { dom = domain; } else { dom = find_domain_by_name(domain, domainname, true); } done: talloc_free(tmp_ctx); return dom; }
int parse_name_domain(struct tools_ctx *tctx, const char *fullname) { int ret; char *domain = NULL; ret = sss_parse_name(tctx, tctx->snctx, fullname, &domain, &tctx->octx->name); if (ret != EOK) { DEBUG(0, ("Cannot parse full name\n")); return ret; } DEBUG(5, ("Parsed username: %s\n", tctx->octx->name)); if (domain) { DEBUG(5, ("Parsed domain: %s\n", domain)); /* only the local domain, whatever named is allowed in tools */ if (strcasecmp(domain, tctx->local->name) != 0) { DEBUG(1, ("Invalid domain %s specified in FQDN\n", domain)); return EINVAL; } } else { if (tctx->local->fqnames) { DEBUG(SSSDBG_CRIT_FAILURE, ("Name '%s' does not seem to be FQDN " "('%s = TRUE' is set)\n", fullname, CONFDB_DOMAIN_FQ)); ERROR("Name '%1$s' does not seem to be FQDN " "('%2$s = TRUE' is set)\n", fullname, CONFDB_DOMAIN_FQ); return EINVAL; } } return EOK; }
int parse_group_name_domain(struct tools_ctx *tctx, char **groups) { int i; int ret; char *name = NULL; char *domain = NULL; if (!groups) { return EOK; } for (i = 0; groups[i]; ++i) { ret = sss_parse_name(tctx, tctx->snctx, groups[i], &domain, &name); if (ret != EOK) { DEBUG(1, ("Invalid name in group list, skipping: [%s] (%d)\n", groups[i], ret)); continue; } /* If FQDN is specified, it must be within the same domain as user */ if (domain) { if (strcmp(domain, tctx->octx->domain->name) != 0) { return EINVAL; } /* Use only groupname */ talloc_zfree(groups[i]); groups[i] = talloc_strdup(tctx, name); if (groups[i] == NULL) { return ENOMEM; } } talloc_zfree(name); talloc_zfree(domain); } talloc_zfree(name); talloc_zfree(domain); return EOK; }
int sss_parse_name_const(TALLOC_CTX *memctx, struct sss_names_ctx *snctx, const char *orig, const char **_domain, const char **_name) { char *domain; char *name; int ret; ret = sss_parse_name(memctx, snctx, orig, (_domain == NULL) ? NULL : &domain, (_name == NULL) ? NULL : &name); if (ret == EOK) { if (_domain != NULL) { *_domain = domain; } if (_name != NULL) { *_name = name; } } return ret; }
int parse_name_domain(struct tools_ctx *tctx, const char *fullname) { int ret; char *domain = NULL; ret = sss_parse_name(tctx, tctx->snctx, fullname, &domain, &tctx->octx->name); if (ret != EOK) { DEBUG(0, ("Cannot parse full name\n")); return ret; } DEBUG(5, ("Parsed username: %s\n", tctx->octx->name)); if (domain) { DEBUG(5, ("Parsed domain: %s\n", domain)); /* only the local domain, whatever named is allowed in tools */ if (strcasecmp(domain, tctx->local->name) != 0) { DEBUG(1, ("Invalid domain %s specified in FQDN\n", domain)); return EINVAL; } } return EOK; }
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 = NULL; char *rdomain, *rname; char *dmatch, *nmatch; char *candidate_name = NULL; char *candidate_domain = NULL; bool name_mismatch = false; TALLOC_CTX *tmp_ctx; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } rname = NULL; rdomain = NULL; for (dom = domains; dom != NULL; dom = get_next_domain(dom, 0)) { 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 * name. */ if (dmatch == NULL) { if (candidate_name == NULL) { candidate_name = nmatch; } else if (strcasecmp(candidate_name, nmatch) != 0) { name_mismatch = true; } /* * If a domain was returned, then it must match the name of the * domain that this expression was found on, or one of the * subdomains. */ } else { match = match_any_domain_or_subdomain_name (dom, dmatch); if (match != NULL) { DEBUG(SSSDBG_FUNC_DATA, "name '%s' matched expression for " "domain '%s', user is %s\n", orig, match->name, nmatch); rdomain = talloc_strdup(tmp_ctx, match->name); if (rdomain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } rname = nmatch; break; } else if (candidate_domain == NULL) { candidate_domain = dmatch; } } /* EINVAL is returned when name doesn't match */ } 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); rdomain = NULL; if (default_domain != NULL) { rdomain = talloc_strdup(tmp_ctx, default_domain); if (rdomain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } for (dom = domains; dom != NULL; dom = get_next_domain(dom, 0)) { 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 known\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) { /* This branch is taken when the input matches the configured * regular expression, but the domain is now known. Normally, this * is the case with a FQDN of a user from subdomain that was not * yet discovered */ *domain = talloc_steal(memctx, candidate_domain); ret = EAGAIN; goto done; } } if (rdomain == NULL && rname == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "name '%s' did not match any domain's expression\n", orig); ret = EINVAL; goto done; } if (domain != NULL) { *domain = talloc_steal(memctx, rdomain); } if (name != NULL) { *name = talloc_steal(memctx, rname); } ret = EOK; done: talloc_free(tmp_ctx); return ret; }
static errno_t update_filter(struct cache_tool_ctx *tctx, struct sss_domain_info *dinfo, char *name, bool update, const char *fmt, bool force_case_sensitivity, char **_filter) { errno_t ret; char *parsed_domain = NULL; char *parsed_name = NULL; TALLOC_CTX *tmp_ctx = NULL; char *use_name = NULL; char *filter; char *sanitized; char *lc_sanitized; if (!name || !update) { /* Nothing to do */ return EOK; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n"); return ENOMEM; } ret = sss_parse_name(tmp_ctx, dinfo->names, name, &parsed_domain, &parsed_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_parse_name failed\n"); goto done; } if (parsed_domain != NULL && strcasecmp(dinfo->name, parsed_domain) != 0) { /* We were able to parse the domain from given fqdn, but it * does not match with currently processed domain. */ filter = NULL; ret = EOK; goto done; } if (!dinfo->case_sensitive && !force_case_sensitivity) { use_name = sss_tc_utf8_str_tolower(tmp_ctx, parsed_name); if (!use_name) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); ret = ENOMEM; goto done; } } else { use_name = parsed_name; } if (parsed_domain) { use_name = sss_get_domain_name(tmp_ctx, use_name, dinfo); if (!use_name) { ret = ENOMEM; goto done; } } ret = sss_filter_sanitize_for_dom(tmp_ctx, use_name, dinfo, &sanitized, &lc_sanitized); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to sanitize the given name.\n"); goto done; } if (fmt) { if (!dinfo->case_sensitive && !force_case_sensitivity) { filter = talloc_asprintf(tmp_ctx, "(|(%s=%s)(%s=%s))", SYSDB_NAME_ALIAS, lc_sanitized, SYSDB_NAME_ALIAS, sanitized); } else { filter = talloc_asprintf(tmp_ctx, fmt, SYSDB_NAME, sanitized); } } else { filter = talloc_strdup(tmp_ctx, sanitized); } if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); ret = ENOMEM; goto done; } ret = EOK; done: if (ret == EOK) { talloc_free(*_filter); *_filter = talloc_steal(tctx, filter); } talloc_free(tmp_ctx); return ret; }