errno_t sysdb_getservbyname(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char *proto, struct ldb_result **_res) { errno_t ret; TALLOC_CTX *tmp_ctx; static const char *attrs[] = SYSDB_SVC_ATTRS; char *sanitized_name; char *sanitized_proto; char *subfilter; struct ldb_result *res = NULL; struct ldb_message **msgs; size_t msgs_count; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sss_filter_sanitize(tmp_ctx, name, &sanitized_name); if (ret != EOK) { goto done; } if (proto) { ret = sss_filter_sanitize(tmp_ctx, proto, &sanitized_proto); if (ret != EOK) { goto done; } } subfilter = talloc_asprintf(tmp_ctx, SYSDB_SVC_BYNAME_FILTER, proto ? sanitized_proto : "*", sanitized_name, sanitized_name); if (!subfilter) { ret = ENOMEM; goto done; } ret = sysdb_search_services(mem_ctx, domain, subfilter, attrs, &msgs_count, &msgs); if (ret == EOK) { res = talloc_zero(mem_ctx, struct ldb_result); if (!res) { ret = ENOMEM; goto done; } res->count = msgs_count; res->msgs = talloc_steal(res, msgs); }
static errno_t sssctl_fetch_object(TALLOC_CTX *mem_ctx, struct sssctl_object_info *info, struct sss_domain_info *domains, struct sss_domain_info *domain, sssctl_basedn_fn basedn_fn, enum cache_object obj_type, const char *attr_name, const char *attr_value, struct sysdb_attrs **_entry, struct sss_domain_info **_dom) { TALLOC_CTX *tmp_ctx; struct sysdb_attrs *entry; struct sss_domain_info *dom; const char **attrs; char *sanitized; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } ret = sss_filter_sanitize(tmp_ctx, attr_value, &sanitized); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to sanitize input [%d]: %s\n", ret, sss_strerror(ret)); goto done; } attrs = sssctl_build_attrs(tmp_ctx, info); if (attrs == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get attribute list!\n"); ret = ENOMEM; goto done; } ret = sssctl_find_object(tmp_ctx, domains, domain, basedn_fn, obj_type, attr_name, sanitized, attrs, &entry, &dom); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to query cache [%d]: %s\n", ret, sss_strerror(ret)); goto done; } *_entry = talloc_steal(mem_ctx, entry); *_dom = dom; done: talloc_free(tmp_ctx); return ret; }
END_TEST START_TEST(test_sss_filter_sanitize) { errno_t ret; char *sanitized = NULL; TALLOC_CTX *test_ctx = talloc_new(NULL); fail_if (test_ctx == NULL, "Out of memory"); const char no_specials[] = "username"; ret = sss_filter_sanitize(test_ctx, no_specials, &sanitized); fail_unless(ret == EOK, "no_specials error [%d][%s]", ret, strerror(ret)); fail_unless(strcmp(no_specials, sanitized)==0, "Expected [%s], got [%s]", no_specials, sanitized); const char has_asterisk[] = "*username"; const char has_asterisk_expected[] = "\\2ausername"; ret = sss_filter_sanitize(test_ctx, has_asterisk, &sanitized); fail_unless(ret == EOK, "has_asterisk error [%d][%s]", ret, strerror(ret)); fail_unless(strcmp(has_asterisk_expected, sanitized)==0, "Expected [%s], got [%s]", has_asterisk_expected, sanitized); const char has_lparen[] = "user(name"; const char has_lparen_expected[] = "user\\28name"; ret = sss_filter_sanitize(test_ctx, has_lparen, &sanitized); fail_unless(ret == EOK, "has_lparen error [%d][%s]", ret, strerror(ret)); fail_unless(strcmp(has_lparen_expected, sanitized)==0, "Expected [%s], got [%s]", has_lparen_expected, sanitized); const char has_rparen[] = "user)name"; const char has_rparen_expected[] = "user\\29name"; ret = sss_filter_sanitize(test_ctx, has_rparen, &sanitized); fail_unless(ret == EOK, "has_rparen error [%d][%s]", ret, strerror(ret)); fail_unless(strcmp(has_rparen_expected, sanitized)==0, "Expected [%s], got [%s]", has_rparen_expected, sanitized); const char has_backslash[] = "username\\"; const char has_backslash_expected[] = "username\\5c"; ret = sss_filter_sanitize(test_ctx, has_backslash, &sanitized); fail_unless(ret == EOK, "has_backslash error [%d][%s]", ret, strerror(ret)); fail_unless(strcmp(has_backslash_expected, sanitized)==0, "Expected [%s], got [%s]", has_backslash_expected, sanitized); const char has_all[] = "\\(user)*name"; const char has_all_expected[] = "\\5c\\28user\\29\\2aname"; ret = sss_filter_sanitize(test_ctx, has_all, &sanitized); fail_unless(ret == EOK, "has_all error [%d][%s]", ret, strerror(ret)); fail_unless(strcmp(has_all_expected, sanitized)==0, "Expected [%s], got [%s]", has_all_expected, sanitized); talloc_free(test_ctx); }
int sdap_get_map(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, struct sdap_attr_map *def_map, int num_entries, struct sdap_attr_map **_map) { struct sdap_attr_map *map; char *name; int i, ret; map = talloc_array(memctx, struct sdap_attr_map, num_entries); if (!map) { return ENOMEM; } for (i = 0; i < num_entries; i++) { map[i].opt_name = def_map[i].opt_name; map[i].def_name = def_map[i].def_name; map[i].sys_name = def_map[i].sys_name; ret = confdb_get_string(cdb, map, conf_path, map[i].opt_name, map[i].def_name, &name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to retrieve value for %s\n", map[i].opt_name)); talloc_zfree(map); return EINVAL; } if (name) { ret = sss_filter_sanitize(map, name, &map[i].name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("Could not sanitize attribute [%s]\n", name)); talloc_zfree(map); return EINVAL; } talloc_zfree(name); } else { map[i].name = NULL; } if (map[i].def_name && !map[i].name) { DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to retrieve value for %s\n", map[i].opt_name)); talloc_zfree(map); return EINVAL; } DEBUG(SSSDBG_TRACE_FUNC, ("Option %s has%s value %s\n", map[i].opt_name, map[i].name ? "" : " no", map[i].name ? map[i].name : "")); } *_map = map; return EOK; }
/* issue refresh of specific sudo rules */ static struct tevent_req *sdap_sudo_rules_refresh_send(TALLOC_CTX *mem_ctx, struct sdap_sudo_ctx *sudo_ctx, struct be_ctx *be_ctx, struct sdap_options *opts, struct sdap_id_conn_cache *conn_cache, char **rules) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_sudo_rules_refresh_state *state = NULL; TALLOC_CTX *tmp_ctx = NULL; char *ldap_filter = NULL; char *ldap_full_filter = NULL; char *sysdb_filter = NULL; char *safe_rule = NULL; int ret; int i; if (rules == NULL) { return NULL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return NULL; } req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_rules_refresh_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } ldap_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */ sysdb_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */ /* Download only selected rules from LDAP */ /* Remove all selected rules from cache */ for (i = 0; rules[i] != NULL; i++) { ret = sss_filter_sanitize(tmp_ctx, rules[i], &safe_rule); if (ret != EOK) { ret = ENOMEM; goto immediately; } ldap_filter = talloc_asprintf_append_buffer(ldap_filter, "(%s=%s)", opts->sudorule_map[SDAP_AT_SUDO_NAME].name, safe_rule); if (ldap_filter == NULL) { ret = ENOMEM; goto immediately; } sysdb_filter = talloc_asprintf_append_buffer(sysdb_filter, "(%s=%s)", SYSDB_SUDO_CACHE_AT_CN, safe_rule); if (sysdb_filter == NULL) { ret = ENOMEM; goto immediately; } } state->id_ctx = sudo_ctx->id_ctx; state->num_rules = i; ldap_filter = talloc_asprintf(tmp_ctx, "(&"SDAP_SUDO_FILTER_CLASS"(|%s))", opts->sudorule_map[SDAP_OC_SUDORULE].name, ldap_filter); if (ldap_filter == NULL) { ret = ENOMEM; goto immediately; } ldap_full_filter = sdap_sudo_get_filter(tmp_ctx, opts->sudorule_map, sudo_ctx, ldap_filter); if (ldap_full_filter == NULL) { ret = ENOMEM; goto immediately; } sysdb_filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(|%s))", SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC, sysdb_filter); if (sysdb_filter == NULL) { ret = ENOMEM; goto immediately; } subreq = sdap_sudo_refresh_send(req, be_ctx, opts, conn_cache, ldap_full_filter, sysdb_filter); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_sudo_rules_refresh_done, req); ret = EOK; immediately: talloc_free(tmp_ctx); if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, be_ctx->ev); } return req; }
static char * build_filter(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, hash_table_t *table, struct sdap_attr_map *map, ipa_sudo_conv_rdn_fn rdn_fn) { TALLOC_CTX *tmp_ctx; hash_key_t *keys; unsigned long int count; unsigned long int i; char *filter; char *rdn_val; const char *rdn_attr; char *safe_rdn; errno_t ret; int hret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return NULL; } hret = hash_keys(table, &count, &keys); if (hret != HASH_SUCCESS) { ret = ENOMEM; goto done; } talloc_steal(tmp_ctx, keys); filter = talloc_strdup(tmp_ctx, ""); if (filter == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < count; i++) { ret = rdn_fn(tmp_ctx, map, sysdb, keys[i].str, &rdn_val, &rdn_attr); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get member %s [%d]: %s\n", keys[i].str, ret, sss_strerror(ret)); goto done; } ret = sss_filter_sanitize(tmp_ctx, rdn_val, &safe_rdn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to sanitize DN " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } filter = talloc_asprintf_append(filter, "(%s=%s)", rdn_attr, safe_rdn); if (filter == NULL) { ret = ENOMEM; goto done; } } /* objectClass is always first */ filter = talloc_asprintf(filter, "(&(objectClass=%s)(|%s))", map[0].name, filter); if (filter == NULL) { ret = ENOMEM; goto done; } talloc_steal(mem_ctx, filter); ret = EOK; done: talloc_free(tmp_ctx); if (ret != EOK) { return NULL; } return filter; }
errno_t sysdb_get_map_byname(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char *map_name, struct ldb_message **_map) { errno_t ret; TALLOC_CTX *tmp_ctx; const char *filter; char *safe_map_name; size_t count; struct ldb_message **msgs; const char *attrs[] = { SYSDB_OBJECTCLASS, SYSDB_CACHE_EXPIRE, SYSDB_LAST_UPDATE, SYSDB_AUTOFS_MAP_NAME, SYSDB_MEMBER, NULL }; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; ret = sss_filter_sanitize(tmp_ctx, map_name, &safe_map_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot sanitize map [%s] error [%d]: %s\n", map_name, ret, strerror(ret))); goto done; } filter = talloc_asprintf(tmp_ctx, "(&(objectclass=%s)(%s=%s))", SYSDB_AUTOFS_MAP_OC, SYSDB_NAME, safe_map_name); if (!filter) { ret = ENOMEM; goto done; } ret = sysdb_search_custom(tmp_ctx, sysdb, domain, filter, AUTOFS_MAP_SUBDIR, attrs, &count, &msgs); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, ("Error looking up autofs map [%s]", safe_map_name)); goto done; } else if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, ("No such map\n")); *_map = NULL; goto done; } if (count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, ("More than one map named %s\n", safe_map_name)); goto done; } *_map = talloc_steal(mem_ctx, msgs[0]); ret = EOK; done: talloc_free(tmp_ctx); return ret; }
/* * Functions to convert sysdb_attrs to the hbac_rule format */ static errno_t hbac_host_attrs_to_rule(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *rule_name, struct sysdb_attrs *rule_attrs, const char *category_attr, const char *member_attr, size_t *host_count, struct hbac_rule_element **hosts) { errno_t ret; TALLOC_CTX *tmp_ctx; struct hbac_rule_element *new_hosts; const char *attrs[] = { SYSDB_FQDN, SYSDB_NAME, NULL }; struct ldb_message_element *el; size_t num_hosts = 0; size_t num_hostgroups = 0; size_t i; char *member_dn; char *filter; size_t count; struct ldb_message **msgs; const char *name; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) return ENOMEM; new_hosts = talloc_zero(tmp_ctx, struct hbac_rule_element); if (new_hosts == NULL) { ret = ENOMEM; goto done; } /* First check for host category */ ret = hbac_get_category(rule_attrs, category_attr, &new_hosts->category); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not identify host categories\n"); goto done; } if (new_hosts->category & HBAC_CATEGORY_ALL) { /* Short-cut to the exit */ ret = EOK; goto done; } /* Get the list of DNs from the member_attr */ ret = sysdb_attrs_get_el(rule_attrs, member_attr, &el); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_get_el failed.\n"); goto done; } if (ret == ENOENT || el->num_values == 0) { el->num_values = 0; DEBUG(SSSDBG_CONF_SETTINGS, "No host specified, rule will never apply.\n"); } /* Assume maximum size; We'll trim it later */ new_hosts->names = talloc_array(new_hosts, const char *, el->num_values +1); if (new_hosts->names == NULL) { ret = ENOMEM; goto done; } new_hosts->groups = talloc_array(new_hosts, const char *, el->num_values + 1); if (new_hosts->groups == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < el->num_values; i++) { ret = sss_filter_sanitize(tmp_ctx, (const char *)el->values[i].data, &member_dn); if (ret != EOK) goto done; filter = talloc_asprintf(member_dn, "(%s=%s)", SYSDB_ORIG_DN, member_dn); if (filter == NULL) { ret = ENOMEM; goto done; } /* First check if this is a specific host */ ret = sysdb_search_custom(tmp_ctx, domain, filter, HBAC_HOSTS_SUBDIR, attrs, &count, &msgs); if (ret != EOK && ret != ENOENT) goto done; if (ret == EOK && count == 0) { ret = ENOENT; } if (ret == EOK) { if (count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Original DN matched multiple hosts. Skipping \n"); talloc_zfree(member_dn); continue; } /* Original DN matched a single host. Get the hostname */ name = ldb_msg_find_attr_as_string(msgs[0], SYSDB_FQDN, NULL); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "FQDN is missing!\n"); ret = EFAULT; goto done; } new_hosts->names[num_hosts] = talloc_strdup(new_hosts->names, name); if (new_hosts->names[num_hosts] == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Added host [%s] to rule [%s]\n", name, rule_name); num_hosts++; } else { /* ret == ENOENT */ /* Check if this is a hostgroup */ ret = sysdb_search_custom(tmp_ctx, domain, filter, HBAC_HOSTGROUPS_SUBDIR, attrs, &count, &msgs); if (ret != EOK && ret != ENOENT) goto done; if (ret == EOK && count == 0) { ret = ENOENT; } if (ret == EOK) { if (count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Original DN matched multiple hostgroups. " "Skipping\n"); talloc_zfree(member_dn); continue; } /* Original DN matched a single group. Get the groupname */ name = ldb_msg_find_attr_as_string(msgs[0], SYSDB_NAME, NULL); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Hostgroup name is missing!\n"); ret = EFAULT; goto done; } new_hosts->groups[num_hostgroups] = talloc_strdup(new_hosts->groups, name); if (new_hosts->groups[num_hostgroups] == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Added hostgroup [%s] to rule [%s]\n", name, rule_name); num_hostgroups++; } else { /* ret == ENOENT */ /* Neither a host nor a hostgroup? Skip it */ DEBUG(SSSDBG_TRACE_LIBS, "[%s] does not map to either a host or hostgroup. " "Skipping\n", member_dn); } } talloc_zfree(member_dn); } new_hosts->names[num_hosts] = NULL; new_hosts->groups[num_hostgroups] = NULL; /* Shrink the arrays down to their real sizes */ new_hosts->names = talloc_realloc(new_hosts, new_hosts->names, const char *, num_hosts + 1); if (new_hosts->names == NULL) { ret = ENOMEM; goto done; } new_hosts->groups = talloc_realloc(new_hosts, new_hosts->groups, const char *, num_hostgroups + 1); if (new_hosts->groups == NULL) { ret = ENOMEM; goto done; } ret = EOK; done: if (ret == EOK) { *hosts = talloc_steal(mem_ctx, new_hosts); if (host_count) *host_count = num_hosts; } talloc_free(tmp_ctx); return ret; }