diff options
author | Sumit Bose <sbose@redhat.com> | 2013-05-07 14:39:42 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2013-05-27 19:09:04 +0200 |
commit | c89e13316166957c853ed61496a17306e59afc79 (patch) | |
tree | 4e71ed7f52eb777da7f8c8336fa4df6fd43876aa /src | |
parent | 4cbd4db56836dc72bfcbc73a3a7b9bc5253304c0 (diff) | |
download | sssd-c89e13316166957c853ed61496a17306e59afc79.tar.gz sssd-c89e13316166957c853ed61496a17306e59afc79.tar.xz sssd-c89e13316166957c853ed61496a17306e59afc79.zip |
Add SID related requests to the LDAP provider
The patch adds support for BE_REQ_BY_SECID and BE_REQ_USER_AND_GROUP to
the LDAP provider. Since the AD and the IPA provider use the same code
they support those request now as well.
Besides allowing that users and groups can be searched by the SID as
well the new request allows to search users and groups in one run, i.e.
if there is not user matching the search criteria groups are searched as
well.
Diffstat (limited to 'src')
-rw-r--r-- | src/providers/ldap/ldap_id.c | 235 |
1 files changed, 230 insertions, 5 deletions
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index 4d373a49..eb43f8d0 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -65,7 +65,7 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, { struct tevent_req *req; struct users_get_state *state; - const char *attr_name; + const char *attr_name = NULL; char *clean_name; char *endptr; int ret; @@ -136,11 +136,25 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, } } break; + case BE_FILTER_SECID: + attr_name = ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name; + + ret = sss_filter_sanitize(state, name, &clean_name); + if (ret != EOK) { + goto fail; + } + break; default: ret = EINVAL; goto fail; } + if (attr_name == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("Missing search attribute name.\n")); + ret = EINVAL; + goto fail; + } + state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))", attr_name, clean_name, ctx->opts->user_map[SDAP_OC_USER].name); @@ -372,7 +386,7 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx, { struct tevent_req *req; struct groups_get_state *state; - const char *attr_name; + const char *attr_name = NULL; char *clean_name; char *endptr; int ret; @@ -446,14 +460,28 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx, } } break; + case BE_FILTER_SECID: + attr_name = ctx->opts->group_map[SDAP_AT_GROUP_OBJECTSID].name; + + ret = sss_filter_sanitize(state, name, &clean_name); + if (ret != EOK) { + goto fail; + } + break; default: ret = EINVAL; goto fail; } - if (use_id_mapping) { - /* When mapping IDs, we don't want to limit ourselves - * to groups with a GID value + if (attr_name == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("Missing search attribute name.\n")); + ret = EINVAL; + goto fail; + } + + if (use_id_mapping || filter_type == BE_FILTER_SECID) { + /* When mapping IDs or looking for SIDs, we don't want to limit + * ourselves to groups with a GID value */ state->filter = talloc_asprintf(state, @@ -950,6 +978,14 @@ static void sdap_account_info_netgroups_done(struct tevent_req *req); static void sdap_account_info_services_done(struct tevent_req *req); void sdap_handle_account_info(struct be_req *breq, struct sdap_id_ctx *ctx); +static struct tevent_req *get_user_and_group_send(TALLOC_CTX *memctx, + struct tevent_context *ev, + struct sdap_id_ctx *ctx, + const char *name, + int filter_type, + int attrs_type); +static void sdap_get_user_and_group_done(struct tevent_req *req); + void sdap_account_info_handler(struct be_req *breq) { struct be_ctx *be_ctx = be_req_get_be_ctx(breq); @@ -1076,6 +1112,46 @@ void sdap_handle_account_info(struct be_req *breq, struct sdap_id_ctx *ctx) break; + case BE_REQ_BY_SECID: + if (ar->filter_type != BE_FILTER_SECID) { + ret = EINVAL; + err = "Invalid filter type"; + break; + } + + req = get_user_and_group_send(breq, be_ctx->ev, ctx, + ar->filter_value, + ar->filter_type, + ar->attr_type); + if (!req) { + return sdap_handler_done(breq, DP_ERR_FATAL, + ENOMEM,"Out of memory"); + } + + tevent_req_set_callback(req, sdap_get_user_and_group_done, breq); + + break; + + case BE_REQ_USER_AND_GROUP: + if (!(ar->filter_type == BE_FILTER_NAME || + ar->filter_type == BE_FILTER_IDNUM)) { + ret = EINVAL; + err = "Invalid filter type"; + break; + } + + req = get_user_and_group_send(breq, be_ctx->ev, ctx, + ar->filter_value, + ar->filter_type, + ar->attr_type); + if (!req) { + return sdap_handler_done(breq, DP_ERR_FATAL, + ENOMEM,"Out of memory"); + } + + tevent_req_set_callback(req, sdap_get_user_and_group_done, breq); + + break; default: /*fail*/ ret = EINVAL; err = "Invalid request type"; @@ -1162,3 +1238,152 @@ static void sdap_account_info_services_done(struct tevent_req *req) sdap_account_info_complete(breq, dp_error, ret, "Service lookup failed"); } + +struct get_user_and_group_state { + struct tevent_context *ev; + struct sdap_id_ctx *id_ctx; + struct sdap_id_op *op; + struct sysdb_ctx *sysdb; + struct sss_domain_info *domain; + + const char *filter_val; + int filter_type; + int attrs_type; + + char *filter; + const char **attrs; + + int dp_error; +}; + +static void get_user_and_group_users_done(struct tevent_req *subreq); +static void get_user_and_group_groups_done(struct tevent_req *subreq); + +static struct tevent_req *get_user_and_group_send(TALLOC_CTX *memctx, + struct tevent_context *ev, + struct sdap_id_ctx *id_ctx, + const char *filter_val, + int filter_type, + int attrs_type) +{ + struct tevent_req *req; + struct tevent_req *subreq; + struct get_user_and_group_state *state; + int ret; + + req = tevent_req_create(memctx, &state, struct get_user_and_group_state); + if (req == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("tevent_req_create failed.\n")); + return NULL; + } + + state->ev = ev; + state->id_ctx = id_ctx; + state->dp_error = DP_ERR_FATAL; + + state->op = sdap_id_op_create(state, state->id_ctx->conn_cache); + if (!state->op) { + DEBUG(SSSDBG_OP_FAILURE, ("sdap_id_op_create failed\n")); + ret = ENOMEM; + goto fail; + } + + state->sysdb = state->id_ctx->be->domain->sysdb; + state->domain = state->id_ctx->be->domain; + state->filter_val = filter_val; + state->filter_type = filter_type; + state->attrs_type = attrs_type; + + subreq = users_get_send(req, state->ev, state->id_ctx, state->filter_val, + state->filter_type, state->attrs_type); + if (subreq == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("users_get_send failed.\n")); + ret = ENOMEM; + goto fail; + } + + tevent_req_set_callback(subreq, get_user_and_group_users_done, req); + + return req; + +fail: + tevent_req_error(req, ret); + tevent_req_post(req, ev); + return req; +} + +static void get_user_and_group_users_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct get_user_and_group_state *state = tevent_req_data(req, + struct get_user_and_group_state); + int ret; + + ret = users_get_recv(subreq, &state->dp_error); + talloc_zfree(subreq); + + if (ret == EOK) { /* Matching user found */ + tevent_req_done(req); + return; + } else if (ret != ENOENT) { + tevent_req_error(req, ret); + return; + } + + subreq = groups_get_send(req, state->ev, state->id_ctx, state->filter_val, + state->filter_type, state->attrs_type); + if (subreq == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("groups_get_send failed.\n")); + tevent_req_error(req, ENOMEM); + return; + } + + tevent_req_set_callback(subreq, get_user_and_group_groups_done, req); +} + +static void get_user_and_group_groups_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct get_user_and_group_state *state = tevent_req_data(req, + struct get_user_and_group_state); + int ret; + + ret = groups_get_recv(subreq, &state->dp_error); + talloc_zfree(subreq); + + if (ret == EOK) { /* Matching group found */ + tevent_req_done(req); + } else { + tevent_req_error(req, ret); + } + + return; +} + +errno_t sdap_get_user_and_group_recv(struct tevent_req *req, int *dp_error_out) +{ + struct get_user_and_group_state *state = tevent_req_data(req, + struct get_user_and_group_state); + + if (dp_error_out) { + *dp_error_out = state->dp_error; + } + + TEVENT_REQ_RETURN_ON_ERROR(req); + + return EOK; +} + +static void sdap_get_user_and_group_done(struct tevent_req *req) +{ + struct be_req *breq = tevent_req_callback_data(req, struct be_req); + int ret; + int dp_error; + + ret = sdap_get_user_and_group_recv(req, &dp_error); + talloc_zfree(req); + + sdap_account_info_complete(breq, dp_error, ret, "Lookup by SID failed"); +} |