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

Sumit Bose sbose at redhat.com
Wed May 22 12:10:11 UTC 2013


On Tue, May 14, 2013 at 06:07:05PM +0200, Jakub Hrozek wrote:
> On Mon, May 13, 2013 at 12:33:46PM +0200, Sumit Bose wrote:
> > 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
> 
> [PATCH 1/4] IPA: Always initialize ID mapping
> >      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;
> >  
> 
> Ack, I would just like to move all assignments to sdap_auth_ctx together
> and then assign to ipa_options->auth_ctx for better readability.

Hi Jakub,

thank you for the review. I have fixed all your comments, new versions
attached.

bye,
Sumit
-------------- next part --------------
From 662fa282ba970074708cb6ae71673e0567bf6489 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 |   14 ++++++++++----
 1 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
index 0a5d6e5..9676b78 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;
@@ -306,13 +311,14 @@ int sssm_ipa_auth_init(struct be_ctx *bectx,
     }
     sdap_auth_ctx->be =  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;
+
+    ipa_options->auth_ctx->sdap_auth_ctx = sdap_auth_ctx;
 
     ret = setup_tls_config(sdap_auth_ctx->opts->basic);
     if (ret != EOK) {
-- 
1.7.7.6

-------------- next part --------------
From b2f2da225884c52cbfb4826456942a5dde4fa2c6 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 |   29 ++++++++++++++++++++---------
 1 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index ddc88ab..acb24b1 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -1583,15 +1583,26 @@ 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 df334b73a4401554da27b5ccd24609957ec29d11 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 7ecfa515b611335d175ada12bc12438c92ece3ab 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 |  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 4d373a4..eb43f8d 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");
+}
-- 
1.7.7.6



More information about the sssd-devel mailing list