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 *get_next_domain(struct sss_domain_info *domain, uint32_t gnd_flags) { struct sss_domain_info *dom; bool descend = gnd_flags & SSS_GND_DESCEND; bool include_disabled = gnd_flags & SSS_GND_INCLUDE_DISABLED; dom = domain; while (dom) { if (descend && dom->subdomains) { dom = dom->subdomains; } else if (dom->next) { dom = dom->next; } else if (descend && IS_SUBDOMAIN(dom) && dom->parent->next) { dom = dom->parent->next; } else { dom = NULL; } if (dom) { if (sss_domain_get_state(dom) == DOM_DISABLED && !include_disabled) { continue; } else { /* Next domain found. */ break; } } } return dom; }
static errno_t sudosrv_query_cache(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char **attrs, const char *filter, struct sysdb_attrs ***_rules, uint32_t *_count) { TALLOC_CTX *tmp_ctx; errno_t ret; size_t count; struct sysdb_attrs **rules; struct ldb_message **msgs; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } DEBUG(SSSDBG_FUNC_DATA, "Searching sysdb with [%s]\n", filter); if (IS_SUBDOMAIN(domain)) { /* rules are stored inside parent domain tree */ domain = domain->parent; } ret = sysdb_search_custom(tmp_ctx, domain, filter, SUDORULE_SUBDIR, attrs, &count, &msgs); if (ret == ENOENT) { *_rules = NULL; *_count = 0; ret = EOK; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up SUDO rules\n"); goto done; } ret = sysdb_msg2attrs(tmp_ctx, count, msgs, &rules); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not convert ldb message to sysdb_attrs\n"); goto done; } *_rules = talloc_steal(mem_ctx, rules); *_count = (uint32_t)count; ret = EOK; done: talloc_free(tmp_ctx); return ret; }
char *subdomain_create_conf_path(TALLOC_CTX *mem_ctx, struct sss_domain_info *subdomain) { if (!IS_SUBDOMAIN(subdomain)) { DEBUG(SSSDBG_OP_FAILURE, "The domain \"%s\" is not a subdomain.\n", subdomain->name); return NULL; } return subdomain_create_conf_path_from_str(mem_ctx, subdomain->parent->name, subdomain->name); }
struct sss_domain_info *get_next_domain(struct sss_domain_info *domain, bool descend) { struct sss_domain_info *dom; dom = domain; while (dom) { if (descend && dom->subdomains) { dom = dom->subdomains; } else if (dom->next) { dom = dom->next; } else if (descend && IS_SUBDOMAIN(dom) && dom->parent->next) { dom = dom->parent->next; } else { dom = NULL; } if (dom && !dom->disabled) break; } return dom; }
errno_t sdap_check_ad_group_type(struct sss_domain_info *dom, struct sdap_options *opts, struct sysdb_attrs *group_attrs, const char *group_name, bool *_need_filter) { int32_t ad_group_type; errno_t ret = EOK; *_need_filter = false; if (opts->schema_type == SDAP_SCHEMA_AD) { ret = sysdb_attrs_get_int32_t(group_attrs, SYSDB_GROUP_TYPE, &ad_group_type); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_int32_t failed.\n"); return ret; } DEBUG(SSSDBG_TRACE_ALL, "AD group [%s] has type flags %#x.\n", group_name, ad_group_type); /* Only security groups from AD are considered for POSIX groups. * Additionally only global and universal group are taken to account * for trusted domains. */ if (!(ad_group_type & SDAP_AD_GROUP_TYPE_SECURITY) || (IS_SUBDOMAIN(dom) && (!((ad_group_type & SDAP_AD_GROUP_TYPE_GLOBAL) || (ad_group_type & SDAP_AD_GROUP_TYPE_UNIVERSAL))))) { DEBUG(SSSDBG_TRACE_FUNC, "Filtering AD group [%s].\n", group_name); *_need_filter = true; } } return ret; }
errno_t sss_write_domain_mappings(struct sss_domain_info *domain, bool add_capaths) { struct sss_domain_info *dom; struct sss_domain_info *parent_dom; errno_t ret; errno_t err; TALLOC_CTX *tmp_ctx; const char *mapping_file; char *sanitized_domain; char *tmp_file = NULL; int fd = -1; mode_t old_mode; FILE *fstream = NULL; int i; bool capaths_started; char *uc_forest; char *uc_parent; if (domain == NULL || domain->name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No domain name provided\n"); return EINVAL; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; sanitized_domain = talloc_strdup(tmp_ctx, domain->name); if (sanitized_domain == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n"); return ENOMEM; } /* only alpha-numeric chars, dashes and underscores are allowed in * krb5 include directory */ for (i = 0; sanitized_domain[i] != '\0'; i++) { if (!isalnum(sanitized_domain[i]) && sanitized_domain[i] != '-' && sanitized_domain[i] != '_') { sanitized_domain[i] = '_'; } } mapping_file = talloc_asprintf(tmp_ctx, "%s/domain_realm_%s", KRB5_MAPPING_DIR, sanitized_domain); if (!mapping_file) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_FUNC_DATA, "Mapping file for domain [%s] is [%s]\n", domain->name, mapping_file); tmp_file = talloc_asprintf(tmp_ctx, "%sXXXXXX", mapping_file); if (tmp_file == NULL) { ret = ENOMEM; goto done; } old_mode = umask(077); fd = mkstemp(tmp_file); umask(old_mode); if (fd < 0) { DEBUG(SSSDBG_OP_FAILURE, "creating the temp file [%s] for domain-realm " "mappings failed.", tmp_file); ret = EIO; talloc_zfree(tmp_ctx); goto done; } fstream = fdopen(fd, "a"); if (!fstream) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "fdopen failed [%d]: %s\n", ret, strerror(ret)); ret = close(fd); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fclose failed [%d][%s].\n", ret, strerror(ret)); /* Nothing to do here, just report the failure */ } ret = EIO; goto done; } ret = fprintf(fstream, "[domain_realm]\n"); if (ret < 0) { DEBUG(SSSDBG_OP_FAILURE, "fprintf failed\n"); ret = EIO; goto done; } for (dom = get_next_domain(domain, true); dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */ dom = get_next_domain(dom, false)) { ret = fprintf(fstream, ".%s = %s\n%s = %s\n", dom->name, dom->realm, dom->name, dom->realm); if (ret < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "fprintf failed\n"); goto done; } } if (add_capaths) { capaths_started = false; parent_dom = domain; uc_parent = get_uppercase_realm(tmp_ctx, parent_dom->name); if (uc_parent == NULL) { DEBUG(SSSDBG_OP_FAILURE, "get_uppercase_realm failed.\n"); ret = ENOMEM; goto done; } for (dom = get_next_domain(domain, true); dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */ dom = get_next_domain(dom, false)) { if (dom->forest == NULL) { continue; } uc_forest = get_uppercase_realm(tmp_ctx, dom->forest); if (uc_forest == NULL) { DEBUG(SSSDBG_OP_FAILURE, "get_uppercase_realm failed.\n"); ret = ENOMEM; goto done; } if (!capaths_started) { ret = fprintf(fstream, "[capaths]\n"); if (ret < 0) { DEBUG(SSSDBG_OP_FAILURE, "fprintf failed\n"); ret = EIO; goto done; } capaths_started = true; } ret = fprintf(fstream, "%s = {\n %s = %s\n}\n%s = {\n %s = %s\n}\n", dom->realm, uc_parent, uc_forest, uc_parent, dom->realm, uc_forest); if (ret < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "fprintf failed\n"); goto done; } } } ret = fclose(fstream); fstream = NULL; if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fclose failed [%d][%s].\n", ret, strerror(ret)); goto done; } ret = rename(tmp_file, mapping_file); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "rename failed [%d][%s].\n", ret, strerror(ret)); goto done; } talloc_zfree(tmp_file); ret = chmod(mapping_file, 0644); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fchmod failed [%d][%s].\n", ret, strerror(ret)); goto done; } ret = EOK; done: err = sss_krb5_touch_config(); if (err != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to change last modification time " "of krb5.conf. Created mappings may not be loaded.\n"); /* Ignore */ } if (fstream) { err = fclose(fstream); if (err != 0) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fclose failed [%d][%s].\n", err, strerror(err)); /* Nothing to do here, just report the failure */ } } if (tmp_file) { err = unlink(tmp_file); if (err < 0) { err = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Could not remove file [%s]: [%d]: %s", tmp_file, err, strerror(err)); } } talloc_free(tmp_ctx); return ret; }
/* FIXME: support storing additional attributes */ int sdap_save_user(TALLOC_CTX *memctx, struct sdap_options *opts, struct sss_domain_info *dom, struct sysdb_attrs *attrs, char **_usn_value, time_t now) { struct ldb_message_element *el; int ret; const char *user_name = NULL; const char *fullname = NULL; const char *pwd; const char *gecos; const char *homedir; const char *shell; const char *orig_dn = NULL; uid_t uid; gid_t gid; struct sysdb_attrs *user_attrs; char *upn = NULL; size_t i; int cache_timeout; char *usn_value = NULL; char **missing = NULL; TALLOC_CTX *tmpctx = NULL; bool use_id_mapping; char *sid_str; char *dom_sid_str = NULL; struct sss_domain_info *subdomain; DEBUG(SSSDBG_TRACE_FUNC, "Save user\n"); tmpctx = talloc_new(NULL); if (!tmpctx) { ret = ENOMEM; goto done; } user_attrs = sysdb_new_attrs(tmpctx); if (user_attrs == NULL) { ret = ENOMEM; goto done; } /* Always store SID string if available */ ret = sdap_attrs_get_sid_str(tmpctx, opts->idmap_ctx, attrs, opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name, &sid_str); if (ret == EOK) { ret = sysdb_attrs_add_string(user_attrs, SYSDB_SID_STR, sid_str); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not add SID string: [%s]\n", sss_strerror(ret)); goto done; } } else if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_ALL, "objectSID: not available for user\n"); sid_str = NULL; } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not identify objectSID: [%s]\n", sss_strerror(ret)); sid_str = NULL; } /* Always store UUID if available */ ret = sysdb_handle_original_uuid(opts->user_map[SDAP_AT_USER_UUID].def_name, attrs, opts->user_map[SDAP_AT_USER_UUID].sys_name, user_attrs, SYSDB_UUID); if (ret != EOK) { DEBUG((ret == ENOENT) ? SSSDBG_TRACE_ALL : SSSDBG_MINOR_FAILURE, "Failed to retrieve UUID [%d][%s].\n", ret, sss_strerror(ret)); } /* If this object has a SID available, we will determine the correct * domain by its SID. */ if (sid_str != NULL) { subdomain = find_domain_by_sid(get_domains_head(dom), sid_str); if (subdomain) { dom = subdomain; } else { DEBUG(SSSDBG_TRACE_FUNC, "SID %s does not belong to any known " "domain\n", sid_str); } } ret = sdap_get_user_primary_name(memctx, opts, attrs, dom, &user_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get user name\n"); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Processing user %s\n", user_name); if (opts->schema_type == SDAP_SCHEMA_AD) { ret = sysdb_attrs_get_string(attrs, opts->user_map[SDAP_AT_USER_FULLNAME].sys_name, &fullname); if (ret == EOK) { ret = sysdb_attrs_add_string(user_attrs, SYSDB_FULLNAME, fullname); if (ret != EOK) { goto done; } } else if (ret != ENOENT) { goto done; } } ret = sysdb_attrs_get_el(attrs, opts->user_map[SDAP_AT_USER_PWD].sys_name, &el); if (ret) goto done; if (el->num_values == 0) pwd = NULL; else pwd = (const char *)el->values[0].data; ret = sysdb_attrs_get_el(attrs, opts->user_map[SDAP_AT_USER_GECOS].sys_name, &el); if (ret) goto done; if (el->num_values == 0) gecos = NULL; else gecos = (const char *)el->values[0].data; if (!gecos) { /* Fall back to the user's full name */ ret = sysdb_attrs_get_el( attrs, opts->user_map[SDAP_AT_USER_FULLNAME].sys_name, &el); if (ret) goto done; if (el->num_values > 0) gecos = (const char *)el->values[0].data; } ret = sysdb_attrs_get_el(attrs, opts->user_map[SDAP_AT_USER_HOME].sys_name, &el); if (ret) goto done; if (el->num_values == 0) homedir = NULL; else homedir = (const char *)el->values[0].data; ret = sysdb_attrs_get_el(attrs, opts->user_map[SDAP_AT_USER_SHELL].sys_name, &el); if (ret) goto done; if (el->num_values == 0) shell = NULL; else shell = (const char *)el->values[0].data; use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(opts->idmap_ctx, dom->name, sid_str); /* Retrieve or map the UID as appropriate */ if (use_id_mapping) { if (sid_str == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "SID not available, cannot map a " \ "unix ID to user [%s].\n", user_name); ret = ENOENT; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Mapping user [%s] objectSID [%s] to unix ID\n", user_name, sid_str); /* Convert the SID into a UNIX user ID */ ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &uid); if (ret == ENOTSUP) { DEBUG(SSSDBG_TRACE_FUNC, "Skipping built-in object.\n"); ret = EOK; goto done; } else if (ret != EOK) { goto done; } /* Store the UID in the ldap_attrs so it doesn't get * treated as a missing attribute from LDAP and removed. */ ret = sdap_replace_id(attrs, SYSDB_UIDNUM, uid); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set the id-mapped UID\n"); goto done; } } else { ret = sysdb_attrs_get_uint32_t(attrs, opts->user_map[SDAP_AT_USER_UID].sys_name, &uid); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "no uid provided for [%s] in domain [%s].\n", user_name, dom->name); ret = EINVAL; goto done; } } /* check that the uid is valid for this domain */ if (OUT_OF_ID_RANGE(uid, dom->id_min, dom->id_max)) { DEBUG(SSSDBG_OP_FAILURE, "User [%s] filtered out! (uid out of range)\n", user_name); ret = EINVAL; goto done; } if (use_id_mapping) { ret = sdap_get_idmap_primary_gid(opts, attrs, sid_str, dom_sid_str, &gid); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get the GID for [%s] in domain [%s].\n", user_name, dom->name); goto done; } if (IS_SUBDOMAIN(dom)) { /* For subdomain users, only create the private group as * the subdomain is an MPG domain. * But we have to save the GID of the original primary group * becasuse otherwise this information might be lost because * typically (Unix and AD) the user is not listed in his primary * group as a member. */ ret = sysdb_attrs_add_uint32(user_attrs, SYSDB_PRIMARY_GROUP_GIDNUM, (uint32_t) gid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_uint32 failed.\n"); goto done; } gid = 0; } /* Store the GID in the ldap_attrs so it doesn't get * treated as a missing attribute from LDAP and removed. */ ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid); if (ret != EOK) goto done; } else { ret = sysdb_attrs_get_uint32_t(attrs, opts->user_map[SDAP_AT_USER_GID].sys_name, &gid); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "no gid provided for [%s] in domain [%s].\n", user_name, dom->name); ret = EINVAL; goto done; } } /* check that the gid is valid for this domain */ if (IS_SUBDOMAIN(dom) == false && OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) { DEBUG(SSSDBG_CRIT_FAILURE, "User [%s] filtered out! (primary gid out of range)\n", user_name); ret = EINVAL; goto done; } ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el); if (ret) { goto done; } if (!el || el->num_values == 0) { DEBUG(SSSDBG_MINOR_FAILURE, "originalDN is not available for [%s].\n", user_name); } else { orig_dn = (const char *) el->values[0].data; DEBUG(SSSDBG_TRACE_INTERNAL, "Adding originalDN [%s] to attributes " "of [%s].\n", orig_dn, user_name); ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_DN, orig_dn); if (ret) { goto done; } } ret = sysdb_attrs_get_el(attrs, SYSDB_MEMBEROF, &el); if (ret) { goto done; } if (el->num_values == 0) { DEBUG(SSSDBG_TRACE_FUNC, "Original memberOf is not available for [%s].\n", user_name); } else { DEBUG(SSSDBG_TRACE_FUNC, "Adding original memberOf attributes to [%s].\n", user_name); for (i = 0; i < el->num_values; i++) { ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_MEMBEROF, (const char *) el->values[i].data); if (ret) { goto done; } } } ret = sdap_attrs_add_string(attrs, opts->user_map[SDAP_AT_USER_MODSTAMP].sys_name, "original mod-Timestamp", user_name, user_attrs); if (ret != EOK) { goto done; } ret = sysdb_attrs_get_el(attrs, opts->user_map[SDAP_AT_USER_USN].sys_name, &el); if (ret) { goto done; } if (el->num_values == 0) { DEBUG(SSSDBG_TRACE_FUNC, "Original USN value is not available for [%s].\n", user_name); } else { ret = sysdb_attrs_add_string(user_attrs, opts->user_map[SDAP_AT_USER_USN].sys_name, (const char*)el->values[0].data); if (ret) { goto done; } usn_value = talloc_strdup(tmpctx, (const char*)el->values[0].data); if (!usn_value) { ret = ENOMEM; goto done; } } ret = sysdb_attrs_get_el(attrs, opts->user_map[SDAP_AT_USER_PRINC].sys_name, &el); if (ret) { goto done; } if (el->num_values == 0) { DEBUG(SSSDBG_TRACE_FUNC, "User principal is not available for [%s].\n", user_name); } else { upn = talloc_strdup(user_attrs, (const char*) el->values[0].data); if (!upn) { ret = ENOMEM; goto done; } if (dp_opt_get_bool(opts->basic, SDAP_FORCE_UPPER_CASE_REALM)) { make_realm_upper_case(upn); } DEBUG(SSSDBG_TRACE_FUNC, "Adding user principal [%s] to attributes of [%s].\n", upn, user_name); ret = sysdb_attrs_add_string(user_attrs, SYSDB_UPN, upn); if (ret) { goto done; } } for (i = SDAP_FIRST_EXTRA_USER_AT; i < opts->user_map_cnt; i++) { ret = sdap_attrs_add_list(attrs, opts->user_map[i].sys_name, NULL, user_name, user_attrs); if (ret) { goto done; } } cache_timeout = dom->user_timeout; ret = sdap_save_all_names(user_name, attrs, dom, user_attrs); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to save user names\n"); goto done; } /* Make sure that any attributes we requested from LDAP that we * did not receive are also removed from the sysdb */ ret = list_missing_attrs(user_attrs, opts->user_map, opts->user_map_cnt, attrs, &missing); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Storing info for user %s\n", user_name); ret = sysdb_store_user(dom, user_name, pwd, uid, gid, gecos, homedir, shell, orig_dn, user_attrs, missing, cache_timeout, now); if (ret) goto done; if (_usn_value) { *_usn_value = talloc_steal(memctx, usn_value); } talloc_steal(memctx, user_attrs); ret = EOK; done: if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to save user [%s]\n", user_name ? user_name : "Unknown"); } talloc_free(tmpctx); return ret; }
int main(int argc, const char *argv[]) { errno_t ret; struct cache_tool_ctx *tctx = NULL; struct sysdb_ctx *sysdb; bool skipped = true; struct sss_domain_info *dinfo; ret = init_context(argc, argv, &tctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error initializing context for the application\n"); goto done; } for (dinfo = tctx->domains; dinfo; dinfo = get_next_domain(dinfo, true)) { sysdb = dinfo->sysdb; if (!IS_SUBDOMAIN(dinfo)) { /* Update list of subdomains for this domain */ ret = sysdb_update_subdomains(dinfo); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to update subdomains for domain %s.\n", dinfo->name); } } sysdb = dinfo->sysdb; /* Update filters for each domain */ ret = update_all_filters(tctx, dinfo); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to update filters.\n"); goto done; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not start the transaction!\n"); goto done; } skipped &= !invalidate_entries(tctx, dinfo, TYPE_USER, tctx->user_filter, tctx->user_name); skipped &= !invalidate_entries(tctx, dinfo, TYPE_GROUP, tctx->group_filter, tctx->group_name); skipped &= !invalidate_entries(tctx, dinfo, TYPE_NETGROUP, tctx->netgroup_filter, tctx->netgroup_name); skipped &= !invalidate_entries(tctx, dinfo, TYPE_SERVICE, tctx->service_filter, tctx->service_name); skipped &= !invalidate_entries(tctx, dinfo, TYPE_AUTOFSMAP, tctx->autofs_filter, tctx->autofs_name); ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not commit the transaction!\n"); ret = sysdb_transaction_cancel(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } } if (skipped == true) { ERROR("No cache object matched the specified search\n"); ret = ENOENT; goto done; } else { ret = sss_memcache_clear_all(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to clear memory cache.\n"); goto done; } } ret = EOK; done: if (tctx) talloc_free(tctx); return ret; }
errno_t sss_get_domain_mappings_content(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, char **content) { int ret; char *o = NULL; struct sss_domain_info *dom; struct sss_domain_info *parent_dom; char *uc_parent = NULL; char *uc_forest = NULL; char *parent_capaths = NULL; bool capaths_started = false; if (domain == NULL || content == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing parameter.\n"); return EINVAL; } o = talloc_strdup(mem_ctx, "[domain_realm]\n"); if (o == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } /* This loops skips the starting parent and start rigth with the first * subdomain. Although in all the interesting cases (AD and IPA) the * default is that realm and DNS domain are the same strings (expect case) * and no domain_realm mapping is needed we might consider to add this * domain here as well to cover corner cases? */ for (dom = get_next_domain(domain, SSS_GND_DESCEND); dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */ dom = get_next_domain(dom, 0)) { o = talloc_asprintf_append(o, ".%s = %s\n%s = %s\n", dom->name, dom->realm, dom->name, dom->realm); if (o == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf_append failed.\n"); ret = ENOMEM; goto done; } } parent_dom = domain; uc_parent = get_uppercase_realm(mem_ctx, parent_dom->name); if (uc_parent == NULL) { DEBUG(SSSDBG_OP_FAILURE, "get_uppercase_realm failed.\n"); ret = ENOMEM; goto done; } for (dom = get_next_domain(domain, SSS_GND_DESCEND); dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */ dom = get_next_domain(dom, 0)) { if (dom->forest == NULL) { continue; } talloc_free(uc_forest); uc_forest = get_uppercase_realm(mem_ctx, dom->forest); if (uc_forest == NULL) { DEBUG(SSSDBG_OP_FAILURE, "get_uppercase_realm failed.\n"); ret = ENOMEM; goto done; } if (!capaths_started) { o = talloc_asprintf_append(o, "[capaths]\n"); if (o == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf_append failed.\n"); ret = ENOMEM; goto done; } capaths_started = true; } o = talloc_asprintf_append(o, "%s = {\n %s = %s\n}\n", dom->realm, uc_parent, uc_forest); if (o == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf_append failed.\n"); ret = ENOMEM; goto done; } if (parent_capaths == NULL) { parent_capaths = talloc_asprintf(mem_ctx, " %s = %s\n", dom->realm, uc_forest); } else { parent_capaths = talloc_asprintf_append(parent_capaths, " %s = %s\n", dom->realm, uc_forest); } if (parent_capaths == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf/talloc_asprintf_append failed.\n"); ret = ENOMEM; goto done; } } if (parent_capaths != NULL) { o = talloc_asprintf_append(o, "%s = {\n%s}\n", uc_parent, parent_capaths); if (o == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf_append failed.\n"); ret = ENOMEM; goto done; } } ret = EOK; done: talloc_free(parent_capaths); talloc_free(uc_parent); talloc_free(uc_forest); if (ret == EOK) { *content = o; } else { talloc_free(o); } return ret; }