diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/db/sysdb.h | 7 | ||||
-rw-r--r-- | src/db/sysdb_ops.c | 10 | ||||
-rw-r--r-- | src/responder/common/cache_req/cache_req.c | 1 | ||||
-rw-r--r-- | src/responder/common/cache_req/cache_req.h | 20 | ||||
-rw-r--r-- | src/responder/common/cache_req/cache_req_data.c | 15 | ||||
-rw-r--r-- | src/responder/common/cache_req/cache_req_plugin.h | 1 | ||||
-rw-r--r-- | src/responder/common/cache_req/plugins/cache_req_object_by_name.c | 234 | ||||
-rw-r--r-- | src/tests/cwrap/Makefile.am | 1 |
9 files changed, 290 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index 3483b7f2e..15d636563 100644 --- a/Makefile.am +++ b/Makefile.am @@ -497,6 +497,7 @@ SSSD_CACHE_REQ_OBJ = \ src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c \ src/responder/common/cache_req/plugins/cache_req_initgroups_by_upn.c \ src/responder/common/cache_req/plugins/cache_req_object_by_sid.c \ + src/responder/common/cache_req/plugins/cache_req_object_by_name.c \ src/responder/common/cache_req/plugins/cache_req_svc_by_name.c \ src/responder/common/cache_req/plugins/cache_req_svc_by_port.c \ src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c \ diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 5dedd97dd..350e393b3 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -203,6 +203,7 @@ #define SYSDB_SID_FILTER "(&(|("SYSDB_UC")("SYSDB_GC"))("SYSDB_SID_STR"=%s))" #define SYSDB_UUID_FILTER "(&(|("SYSDB_UC")("SYSDB_GC"))("SYSDB_UUID"=%s))" +#define SYSDB_NAME_FILTER "(&(|("SYSDB_UC")("SYSDB_GC"))("SYSDB_NAME"=%s))" #define SYSDB_USER_CERT_FILTER "(&("SYSDB_UC")%s)" #define SYSDB_HAS_ENUMERATED "has_enumerated" @@ -1193,6 +1194,12 @@ errno_t sysdb_idmap_get_mappings(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **_result); +errno_t sysdb_search_object_by_name(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *name, + const char **attrs, + struct ldb_result **res); + errno_t sysdb_search_object_by_sid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sid_str, diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index 95eb789d6..867fbf50e 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -4544,6 +4544,16 @@ done: return ret; } +errno_t sysdb_search_object_by_name(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *name, + const char **attrs, + struct ldb_result **res) +{ + return sysdb_search_object_by_str_attr(mem_ctx, domain, SYSDB_NAME_FILTER, + name, attrs, res); +} + errno_t sysdb_search_object_by_sid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sid_str, diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c index e74f28e08..8cfde94ec 100644 --- a/src/responder/common/cache_req/cache_req.c +++ b/src/responder/common/cache_req/cache_req.c @@ -45,6 +45,7 @@ cache_req_get_plugin(enum cache_req_type type) &cache_req_initgroups_by_upn, &cache_req_object_by_sid, + &cache_req_object_by_name, &cache_req_enum_users, &cache_req_enum_groups, diff --git a/src/responder/common/cache_req/cache_req.h b/src/responder/common/cache_req/cache_req.h index c0568476e..77b28b9fb 100644 --- a/src/responder/common/cache_req/cache_req.h +++ b/src/responder/common/cache_req/cache_req.h @@ -40,6 +40,7 @@ enum cache_req_type { CACHE_REQ_INITGROUPS_BY_UPN, CACHE_REQ_OBJECT_BY_SID, + CACHE_REQ_OBJECT_BY_NAME, CACHE_REQ_ENUM_USERS, CACHE_REQ_ENUM_GROUPS, @@ -63,6 +64,12 @@ cache_req_data_name(TALLOC_CTX *mem_ctx, const char *name); struct cache_req_data * +cache_req_data_name_attrs(TALLOC_CTX *mem_ctx, + enum cache_req_type type, + const char *name, + const char **attrs); + +struct cache_req_data * cache_req_data_id(TALLOC_CTX *mem_ctx, enum cache_req_type type, uint32_t id); @@ -265,6 +272,19 @@ cache_req_object_by_sid_send(TALLOC_CTX *mem_ctx, cache_req_single_domain_recv(mem_ctx, req, _result) struct tevent_req * +cache_req_object_by_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct resp_ctx *rctx, + struct sss_nc_ctx *ncache, + int cache_refresh_percent, + const char *domain, + const char *name, + const char **attrs); + +#define cache_req_object_by_name_recv(mem_ctx, req, _result) \ + cache_req_single_domain_recv(mem_ctx, req, _result) + +struct tevent_req * cache_req_enum_users_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, diff --git a/src/responder/common/cache_req/cache_req_data.c b/src/responder/common/cache_req/cache_req_data.c index 7bfdc896e..028a96bb2 100644 --- a/src/responder/common/cache_req/cache_req_data.c +++ b/src/responder/common/cache_req/cache_req_data.c @@ -90,6 +90,7 @@ cache_req_data_create(TALLOC_CTX *mem_ctx, case CACHE_REQ_INITGROUPS: case CACHE_REQ_INITGROUPS_BY_UPN: case CACHE_REQ_NETGROUP_BY_NAME: + case CACHE_REQ_OBJECT_BY_NAME: if (input->name.input == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL!\n"); ret = ERR_INTERNAL; @@ -226,6 +227,20 @@ cache_req_data_name(TALLOC_CTX *mem_ctx, } struct cache_req_data * +cache_req_data_name_attrs(TALLOC_CTX *mem_ctx, + enum cache_req_type type, + const char *name, + const char **attrs) +{ + struct cache_req_data input = { 0 }; + + input.name.input = name; + input.attrs = attrs; + + return cache_req_data_create(mem_ctx, type, &input); +} + +struct cache_req_data * cache_req_data_id(TALLOC_CTX *mem_ctx, enum cache_req_type type, uint32_t id) diff --git a/src/responder/common/cache_req/cache_req_plugin.h b/src/responder/common/cache_req/cache_req_plugin.h index f57a07d81..1ba9d540b 100644 --- a/src/responder/common/cache_req/cache_req_plugin.h +++ b/src/responder/common/cache_req/cache_req_plugin.h @@ -210,6 +210,7 @@ extern struct cache_req_plugin cache_req_user_by_cert; extern struct cache_req_plugin cache_req_user_by_filter; extern struct cache_req_plugin cache_req_group_by_filter; extern struct cache_req_plugin cache_req_object_by_sid; +extern struct cache_req_plugin cache_req_object_by_name; extern struct cache_req_plugin cache_req_enum_users; extern struct cache_req_plugin cache_req_enum_groups; extern struct cache_req_plugin cache_req_enum_svc; diff --git a/src/responder/common/cache_req/plugins/cache_req_object_by_name.c b/src/responder/common/cache_req/plugins/cache_req_object_by_name.c new file mode 100644 index 000000000..343b422c6 --- /dev/null +++ b/src/responder/common/cache_req/plugins/cache_req_object_by_name.c @@ -0,0 +1,234 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2016 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <talloc.h> +#include <ldb.h> + +#include "db/sysdb.h" +#include "util/util.h" +#include "providers/data_provider.h" +#include "responder/common/cache_req/cache_req_plugin.h" + +static errno_t +cache_req_object_by_name_well_known(TALLOC_CTX *mem_ctx, + struct cache_req *cr, + struct cache_req_data *data, + struct cache_req_result **_result) +{ + struct cache_req_result *result; + const char *sid; + char *domname; + char *name; + errno_t ret; + + ret = sss_parse_name(mem_ctx, cr->rctx->global_names, + data->name.input, &domname, &name); + if (ret != EOK) { + CACHE_REQ_DEBUG(SSSDBG_OP_FAILURE, cr, "Unable to parse name " + "[%d]: %s\n", ret, sss_strerror(ret)); + return ret; + } + + if (domname == NULL || name == NULL) { + CACHE_REQ_DEBUG(SSSDBG_OP_FAILURE, cr, "Unable to split [%s] in " + "name and odmain part. Skipping detection of " + "well-known name.\n", data->name.input); + return ENOENT; + } + + ret = name_to_well_known_sid(domname, name, &sid); + if (ret != EOK) { + return EOK; + } + + result = cache_req_well_known_sid_result(mem_ctx, cr, domname, sid, name); + talloc_free(domname); + talloc_free(name); + if (result == NULL) { + return ENOMEM; + } + + *_result = result; + + return EOK; +} + +static errno_t +cache_req_object_by_name_prepare_domain_data(struct cache_req *cr, + struct cache_req_data *data, + struct sss_domain_info *domain) +{ + TALLOC_CTX *tmp_ctx; + const char *name; + errno_t ret; + + if (cr->data->name.name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Bug: parsed name is NULL?\n"); + return ERR_INTERNAL; + } + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + name = sss_get_cased_name(tmp_ctx, cr->data->name.name, + domain->case_sensitive); + if (name == NULL) { + ret = ENOMEM; + goto done; + } + + name = sss_reverse_replace_space(tmp_ctx, name, cr->rctx->override_space); + if (name == NULL) { + ret = ENOMEM; + goto done; + } + + name = sss_create_internal_fqname(tmp_ctx, name, domain->name); + if (name == NULL) { + ret = ENOMEM; + goto done; + } + + talloc_zfree(data->name.lookup); + data->name.lookup = talloc_steal(data, name); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + +static const char * +cache_req_object_by_name_create_debug_name(TALLOC_CTX *mem_ctx, + struct cache_req_data *data, + struct sss_domain_info *domain) +{ + return talloc_strdup(mem_ctx, data->name.lookup); +} + +static errno_t +cache_req_object_by_name_ncache_check(struct sss_nc_ctx *ncache, + struct sss_domain_info *domain, + struct cache_req_data *data) +{ + errno_t ret; + + ret = sss_ncache_check_user(ncache, domain, data->name.lookup); + if (ret == EEXIST) { + ret = sss_ncache_check_group(ncache, domain, data->name.lookup); + } + + return ret; +} + +static errno_t +cache_req_object_by_name_ncache_add(struct sss_nc_ctx *ncache, + struct sss_domain_info *domain, + struct cache_req_data *data) +{ + errno_t ret; + + ret = sss_ncache_set_user(ncache, false, domain, data->name.lookup); + if (ret != EOK) { + return ret; + } + + ret = sss_ncache_set_group(ncache, false, domain, data->name.lookup); + if (ret != EOK) { + return ret; + } + + return EOK; +} + +static errno_t +cache_req_object_by_name_lookup(TALLOC_CTX *mem_ctx, + struct cache_req *cr, + struct cache_req_data *data, + struct sss_domain_info *domain, + struct ldb_result **_result) +{ + return sysdb_search_object_by_name(mem_ctx, domain, data->name.lookup, + data->attrs, _result); +} + +static errno_t +cache_req_object_by_name_dpreq_params(TALLOC_CTX *mem_ctx, + struct cache_req *cr, + struct ldb_result *result, + const char **_string, + uint32_t *_id, + const char **_flag) +{ + *_id = 0; + *_string = cr->data->name.lookup; + *_flag = NULL; + + return EOK; +} + +struct cache_req_plugin cache_req_object_by_name = { + .name = "Object by name", + .dp_type = SSS_DP_USER_AND_GROUP, + .attr_expiration = SYSDB_CACHE_EXPIRE, + .parse_name = true, + .bypass_cache = false, + .only_one_result = true, + .search_all_domains = false, + .require_enumeration = false, + .allow_missing_fqn = false, + .allow_switch_to_upn = true, + .upn_equivalent = CACHE_REQ_USER_BY_UPN, + .get_next_domain_flags = 0, + + .is_well_known_fn = cache_req_object_by_name_well_known, + .prepare_domain_data_fn = cache_req_object_by_name_prepare_domain_data, + .create_debug_name_fn = cache_req_object_by_name_create_debug_name, + .global_ncache_add_fn = NULL, + .ncache_check_fn = cache_req_object_by_name_ncache_check, + .ncache_add_fn = cache_req_object_by_name_ncache_add, + .lookup_fn = cache_req_object_by_name_lookup, + .dpreq_params_fn = cache_req_object_by_name_dpreq_params +}; + +struct tevent_req * +cache_req_object_by_name_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct resp_ctx *rctx, + struct sss_nc_ctx *ncache, + int cache_refresh_percent, + const char *domain, + const char *name, + const char **attrs) +{ + struct cache_req_data *data; + + data = cache_req_data_name_attrs(mem_ctx, CACHE_REQ_OBJECT_BY_NAME, + name, attrs); + if (data == NULL) { + return NULL; + } + + return cache_req_steal_data_and_send(mem_ctx, ev, rctx, ncache, + cache_refresh_percent, domain, data); +} diff --git a/src/tests/cwrap/Makefile.am b/src/tests/cwrap/Makefile.am index c90cccfeb..e6b7fa474 100644 --- a/src/tests/cwrap/Makefile.am +++ b/src/tests/cwrap/Makefile.am @@ -55,6 +55,7 @@ SSSD_CACHE_REQ_OBJ = \ ../../../src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c \ ../../../src/responder/common/cache_req/plugins/cache_req_initgroups_by_upn.c \ ../../../src/responder/common/cache_req/plugins/cache_req_object_by_sid.c \ + ../../../src/responder/common/cache_req/plugins/cache_req_object_by_name.c \ ../../../src/responder/common/cache_req/plugins/cache_req_svc_by_name.c \ ../../../src/responder/common/cache_req/plugins/cache_req_svc_by_port.c \ ../../../src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c \ |