[SSSD] [PATCHES] Add SID related lookups to the NSS responder - part 3

Sumit Bose sbose at redhat.com
Mon May 13 10:33:46 UTC 2013


Hi,

with these four patches the SID-to-name API can now also be used with
the AD provider and for local IPA accounts. Since this goes beyond the
functionality needed by the FreeIPA WebUI I send them in a separate
series. The patches are also a requirement for using the PAC with the AD
provider (https://fedorahosted.org/sssd/ticket/1558).

bye,
Sumit
-------------- next part --------------
From 676fb113be38e2bd52fe655f4ec5f09179dea984 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 7 May 2013 21:36:51 +0200
Subject: [PATCH 1/4] IPA: Always initialize ID mapping

Because we now always want to store SIDs in the IPA provider, we also need
to always initialize the ID mapping context.
---
 src/providers/ipa/ipa_init.c |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
index 5192bc8..61ab44d 100644
--- a/src/providers/ipa/ipa_init.c
+++ b/src/providers/ipa/ipa_init.c
@@ -38,6 +38,7 @@
 #include "providers/ipa/ipa_dyndns.h"
 #include "providers/ipa/ipa_selinux.h"
 #include "providers/ldap/sdap_access.h"
+#include "providers/ldap/sdap_idmap.h"
 #include "providers/ipa/ipa_subdomains.h"
 #include "providers/ipa/ipa_srv.h"
 #include "providers/dp_dyndns.h"
@@ -192,6 +193,10 @@ int sssm_ipa_id_init(struct be_ctx *bectx,
         goto done;
     }
 
+    /* Set up the ID mapping object */
+    ret = sdap_idmap_init(sdap_ctx, sdap_ctx, &sdap_ctx->opts->idmap_ctx);
+    if (ret != EOK) goto done;
+
     ret = sdap_id_setup_tasks(sdap_ctx);
     if (ret != EOK) {
         goto done;
@@ -308,11 +313,11 @@ int sssm_ipa_auth_init(struct be_ctx *bectx,
     sdap_auth_ctx->service = ipa_options->service->sdap;
     ipa_options->auth_ctx->sdap_auth_ctx = sdap_auth_ctx;
 
-    ret = ipa_get_id_options(ipa_options, bectx->cdb, bectx->conf_path,
-                             &sdap_auth_ctx->opts);
-    if (ret != EOK) {
+    if (ipa_options->id == NULL) {
+        ret = EINVAL;
         goto done;
     }
+    sdap_auth_ctx->opts = ipa_options->id;
 
     ret = setup_tls_config(sdap_auth_ctx->opts->basic);
     if (ret != EOK) {
-- 
1.7.7.6

-------------- next part --------------
From 3e55b37b3c85ae285e7c6654217e7b6f957196e3 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 7 May 2013 23:28:14 +0200
Subject: [PATCH 2/4] Handle SID strings in sdap_attrs_get_sid_str() as well

This patch add a basic check if the SID returned by the LDAP server is
in a string representation. If not it is assumed that a binary SID was
returned by the LDAP server which is converted into a string
representation which is returned to the caller.
---
 src/providers/ldap/ldap_common.c |   30 +++++++++++++++++++++---------
 1 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index ddc88ab..e7e3cb9 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -1583,15 +1583,27 @@ sdap_attrs_get_sid_str(TALLOC_CTX *mem_ctx,
         return ENOENT;
     }
 
-    err = sss_idmap_bin_sid_to_sid(idmap_ctx->map,
-                                   el->values[0].data,
-                                   el->values[0].length,
-                                   &sid_str);
-    if (err != IDMAP_SUCCESS) {
-        DEBUG(SSSDBG_MINOR_FAILURE,
-              ("Could not convert SID: [%s]\n",
-               idmap_error_string(err)));
-        return EIO;
+    if (el->values[0].length > 2 &&
+        el->values[0].data[0] == 'S' &&
+        el->values[0].data[1] == '-')
+    {
+        sid_str = talloc_strndup(mem_ctx, (char *) el->values[0].data,
+                                 el->values[0].length);
+        if (sid_str == NULL) {
+            DEBUG(SSSDBG_OP_FAILURE, ("talloc_strndup failed.\n"));
+            return ENOMEM;
+        }
+    } else {
+        err = sss_idmap_bin_sid_to_sid(idmap_ctx->map,
+                                       el->values[0].data,
+                                       el->values[0].length,
+                                       &sid_str);
+        if (err != IDMAP_SUCCESS) {
+            DEBUG(SSSDBG_MINOR_FAILURE,
+                  ("Could not convert SID: [%s]\n",
+                   idmap_error_string(err)));
+            return EIO;
+        }
     }
 
     *_sid_str = talloc_steal(mem_ctx, sid_str);
-- 
1.7.7.6

-------------- next part --------------
From 6aae0510832551f8c255f9e18ea743b0e83d0e86 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 7 May 2013 23:49:05 +0200
Subject: [PATCH 3/4] IPA: read user and group SID

To allow mapping of SIDs to names or POSIX IDs and back the related
attributes must be read from the FreeIPA directory server.
---
 src/providers/ipa/ipa_opts.h |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index de9592b..ca137fb 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -168,7 +168,7 @@ struct sdap_attr_map ipa_user_map[] = {
     { "ldap_user_fullname", "cn", SYSDB_FULLNAME, NULL },
     { "ldap_user_member_of", "memberOf", SYSDB_MEMBEROF, NULL },
     { "ldap_user_uuid", "nsUniqueId", SYSDB_UUID, NULL },
-    { "ldap_user_objectsid", NULL, SYSDB_SID, NULL },
+    { "ldap_user_objectsid", "ipaNTSecurityIdentifier", SYSDB_SID_STR, NULL },
     { "ldap_user_primary_group", NULL, SYSDB_PRIMARY_GROUP, NULL },
     { "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
     { "ldap_user_entry_usn", NULL, SYSDB_USN, NULL },
@@ -201,7 +201,7 @@ struct sdap_attr_map ipa_group_map[] = {
     { "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
     { "ldap_group_member", "member", SYSDB_MEMBER, NULL },
     { "ldap_group_uuid", "nsUniqueId", SYSDB_UUID, NULL },
-    { "ldap_group_objectsid", NULL, SYSDB_SID, NULL },
+    { "ldap_group_objectsid", "ipaNTSecurityIdentifier", SYSDB_SID_STR, NULL },
     { "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
     { "ldap_group_entry_usn", NULL, SYSDB_USN, NULL },
     SDAP_ATTR_MAP_TERMINATOR
-- 
1.7.7.6

-------------- next part --------------
From 8f59f19435d9d0e349c957f6abf698377f21a80f Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 7 May 2013 14:39:42 +0200
Subject: [PATCH 4/4] 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.
---
 src/providers/ldap/ldap_id.c |  216 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 213 insertions(+), 3 deletions(-)

diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index 4d373a4..c4e8dbf 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -136,6 +136,14 @@ 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;
@@ -446,14 +454,22 @@ struct tevent_req *groups_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 (use_id_mapping) {
-        /* When mapping IDs, we don't want to limit ourselves
-         * to groups with a GID value
+    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 +966,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 +1100,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 +1226,149 @@ 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(2, ("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;
+    }
+
+    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");
+}
-- 
1.7.7.6



More information about the sssd-devel mailing list