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

Sumit Bose sbose at redhat.com
Thu May 2 11:57:29 UTC 2013


On Wed, May 01, 2013 at 09:08:47PM +0200, Jakub Hrozek wrote:
> On Mon, Apr 29, 2013 at 09:06:39PM +0200, Sumit Bose wrote:
> > Hi,
> > 
> > this is the first part of patches to add SID lookups, i.e. lookups by
> > SID and lookups for SIDs which is tracked by ticket
> > https://fedorahosted.org/sssd/ticket/1559 and described in
> > https://fedorahosted.org/sssd/wiki/DesignDocs/NSSResponderIDMappingCalls.
> > 
> > I split the patches into different parts to make review eaiser
> > (hopefully :-). This first part contains patches with minor code changes
> > and some new help functions. Details can be found in the commit
> > messages.
> > 
> > bye,
> > Sumit

thank you for the review, comments a re in-line.

> 
> [PATCH 01/12] Remove unused TALLOC_CTX from responder_get_domain()
> Ack
> 
> [PATCH 02/12] responder_get_domain: do not return disabled domains
> Ack, we already do the same in find_subdomain_by_name, so it makes sense
> to skip the disabled domains in responder_get_domain, too.
> 
> [PATCH 03/12] responder_get_domain(): remove timeout calculation
> Wasn't the purpose of the code to assign "ret_dom = dom"; only after
> establishing that the domain is not expired? That way the expired
> domains would be skipped.

yes, but if I read the old code correctly, there is always a domain
return. And currently the callers do not check for new domains if NULL
is returned. I think it would be code to clean this up, but I think it
can wait after the release.

> But I agree the current responder code can't really hit this situation
> because sss_dp_get_domains_send() would check using check_last_request()
> and the subdomains would be refreshed before reaching responder_get_domain()
> 
> [PATCH 04/12] LDAP: always store SID if available
> Ack
> 
> [PATCH 05/12] Add secid filter to responder-dp protocol
> Ack but the nested if-else structure in sss_dp_get_account_msg() is
> starting to look unreadable :-) Maybe we could split it into smaller
> functions in a follow up patch.

yes, I was also thinking if a struct with type and a union would help
here to make the code more readable, but I thought here as well that it
can wait after the release.

> 
> [PATCH 06/12] Add two new request types to the data-provider interface
> The functionality is good, but the names are not clear to me. What about
> BE_REQ_BY_SECID and BE_REQ_GET_SECID ?

I changed BE_REQ_SECID->BE_REQ_BY_SECID to make the purpose more clear.
I would like to keep BE_REQ_USER_AND_GROUP because although  it will be
used when a SID should be lookup up, the general purpose is the check
the users and the groups for the given name or id.

> 
> [PATCH 07/12] Add idmap context to nss context
> Ack
> 
> [PATCH 08/12] Add responder_get_domain_by_id()
> Why does responder_get_domain_by_id() calculate the timeout but
> responder_get_domain() does not?
> The code itself looks good to me.

See above.

> 
> [PATCH 09/12] sysdb: add sysdb_search_object_by_sid()
> Ack
> 
> [PATCH 10/12] Add sss_ncache_set_sid() and sss_ncache_check_sid()
> Ack
> 
> [PATCH 11/12] Remove unused attribute list
> Ack
> 
> [PATCH 12/12] Use struct to hold different types of request
> I like the idea. One question though:
> 
> >      switch (entry_type) {
> >          case BE_REQ_USER:
> > -            if (name != NULL) {
> > +            if (req_input->type == REQ_INP_NAME) {
> >                  ret = ber_printf(ber, "{ee{ss}}", INP_NAME, REQ_FULL,
> > -                                                  domain_name, name);
> > +                                                  domain_name,
> > +                                                  req_input->inp.name);
> >              } else {
> >                  ret = ber_printf(ber, "{ee{si}}", INP_POSIX_UID, REQ_FULL,
> > -                                                  domain_name, id);
> > +                                                  domain_name,
> > +                                                  req_input->inp.id);
> 
> Here REQ_INP_SECID would match, too, but I don't think secid would be
> set. I think it would be safer to:
> 
>     if (req_input->type == REQ_INP_NAME) {
>         /* Use req_input->inp.name */
>     } else if (req_input->type == REQ_INP_NAME) {
>         /* Use req_input->inp.id */
>     } else {
>         /* Error */
>     }
> 
> But maybe it would be handled in a follow up patch?

yes, it handled in the patch which adds support for REQ_INP_SECID to
the IPA subdomains.

New versions attached, but only patch 6 is changed.

bye,
Sumit
> _______________________________________________
> sssd-devel mailing list
> sssd-devel at lists.fedorahosted.org
> https://lists.fedorahosted.org/mailman/listinfo/sssd-devel
-------------- next part --------------
From 4ab136a730f690316fb0401987d8a3b2903e8201 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Thu, 18 Apr 2013 12:43:47 +0200
Subject: [PATCH 01/12] Remove unused TALLOC_CTX from responder_get_domain()

Recent refactoring removed the need to copy the domain info data of
sub-domains because the related objects will not be removed from memory
anymore.
---
 src/responder/autofs/autofssrv_cmd.c    |    2 +-
 src/responder/common/negcache.c         |    4 ++--
 src/responder/common/responder.h        |    3 +--
 src/responder/common/responder_common.c |    3 +--
 src/responder/nss/nsssrv_cmd.c          |    4 ++--
 src/responder/nss/nsssrv_netgroup.c     |    2 +-
 src/responder/nss/nsssrv_services.c     |    2 +-
 src/responder/pac/pacsrv_cmd.c          |    4 ++--
 src/responder/pam/pamsrv_cmd.c          |    4 ++--
 src/responder/ssh/sshsrv_cmd.c          |    6 ++----
 src/responder/sudo/sudosrv_query.c      |    2 +-
 11 files changed, 16 insertions(+), 20 deletions(-)

diff --git a/src/responder/autofs/autofssrv_cmd.c b/src/responder/autofs/autofssrv_cmd.c
index 491afbb..e9168ea 100644
--- a/src/responder/autofs/autofssrv_cmd.c
+++ b/src/responder/autofs/autofssrv_cmd.c
@@ -448,7 +448,7 @@ setautomntent_send(TALLOC_CTX *mem_ctx,
          state->mapname, domname?domname:"<ALL>"));
 
     if (domname) {
-        dctx->domain = responder_get_domain(dctx, client->rctx, domname);
+        dctx->domain = responder_get_domain(client->rctx, domname);
         if (!dctx->domain) {
             ret = EINVAL;
             goto fail;
diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index 57d1fc8..2e1c0af 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -652,7 +652,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
             continue;
         }
         if (domainname) {
-            dom = responder_get_domain(tmpctx, rctx, domainname);
+            dom = responder_get_domain(rctx, domainname);
             if (!dom) {
                 DEBUG(SSSDBG_CRIT_FAILURE,
                       ("Invalid domain name [%s]\n", domainname));
@@ -750,7 +750,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
             continue;
         }
         if (domainname) {
-            dom = responder_get_domain(tmpctx, rctx, domainname);
+            dom = responder_get_domain(rctx, domainname);
             if (!dom) {
                 DEBUG(SSSDBG_CRIT_FAILURE,
                       ("Invalid domain name [%s]\n", domainname));
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index 110bd38..e1b0b00 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -169,8 +169,7 @@ int sss_parse_name_for_domains(TALLOC_CTX *memctx,
 int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain,
                            struct be_conn **_conn);
 struct sss_domain_info *
-responder_get_domain(TALLOC_CTX *sd_mem_ctx, struct resp_ctx *rctx,
-                     const char *domain);
+responder_get_domain(struct resp_ctx *rctx, const char *domain);
 
 /* responder_cmd.c */
 int sss_cmd_empty_packet(struct sss_packet *packet);
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 35142c1..3292591 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -897,8 +897,7 @@ int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain,
 }
 
 struct sss_domain_info *
-responder_get_domain(TALLOC_CTX *sd_mem_ctx, struct resp_ctx *rctx,
-                     const char *name)
+responder_get_domain(struct resp_ctx *rctx, const char *name)
 {
     time_t now = time(NULL);
     time_t time_diff = 0;
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index 7402dc6..903481f 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -1023,7 +1023,7 @@ static int nss_cmd_getbynam(enum sss_cli_command cmd, struct cli_ctx *cctx)
               cmdctx->name, domname?domname:"<ALL>"));
 
     if (domname) {
-        dctx->domain = responder_get_domain(dctx, cctx->rctx, domname);
+        dctx->domain = responder_get_domain(cctx->rctx, domname);
         if (!dctx->domain) {
             ret = ENOENT;
             goto done;
@@ -1107,7 +1107,7 @@ static void nss_cmd_getbynam_done(struct tevent_req *req)
               cmdctx->name, domname?domname:"<ALL>"));
 
     if (domname) {
-        dctx->domain = responder_get_domain(dctx, cctx->rctx, domname);
+        dctx->domain = responder_get_domain(cctx->rctx, domname);
         if (dctx->domain == NULL) {
             ret = ENOENT;
             goto done;
diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c
index 3679236..4ec4161 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -209,7 +209,7 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
               state->netgr_shortname, domname?domname:"<ALL>"));
 
     if (domname) {
-        dctx->domain = responder_get_domain(dctx, client->rctx, domname);
+        dctx->domain = responder_get_domain(client->rctx, domname);
         if (!dctx->domain) {
             ret = EINVAL;
             goto error;
diff --git a/src/responder/nss/nsssrv_services.c b/src/responder/nss/nsssrv_services.c
index c990742..99fc67e 100644
--- a/src/responder/nss/nsssrv_services.c
+++ b/src/responder/nss/nsssrv_services.c
@@ -842,7 +842,7 @@ int nss_cmd_getservbyname(struct cli_ctx *cctx)
            domname ? domname : "<ALL>"));
 
     if (domname) {
-        dctx->domain = responder_get_domain(dctx, cctx->rctx, domname);
+        dctx->domain = responder_get_domain(cctx->rctx, domname);
         if (!dctx->domain) {
             ret = ENOENT;
             goto done;
diff --git a/src/responder/pac/pacsrv_cmd.c b/src/responder/pac/pacsrv_cmd.c
index b288a76..b585dd6 100644
--- a/src/responder/pac/pacsrv_cmd.c
+++ b/src/responder/pac/pacsrv_cmd.c
@@ -180,7 +180,7 @@ static errno_t pac_add_pac_user(struct cli_ctx *cctx)
         goto done;
     }
 
-    pr_ctx->dom = responder_get_domain(pr_ctx, cctx->rctx, pr_ctx->domain_name);
+    pr_ctx->dom = responder_get_domain(cctx->rctx, pr_ctx->domain_name);
     if (pr_ctx->dom == NULL) {
         req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true,
                                       pr_ctx->domain_name);
@@ -215,7 +215,7 @@ static void pac_get_domains_done(struct tevent_req *req)
         goto done;
     }
 
-    pr_ctx->dom = responder_get_domain(pr_ctx, cctx->rctx, pr_ctx->domain_name);
+    pr_ctx->dom = responder_get_domain(cctx->rctx, pr_ctx->domain_name);
     if (pr_ctx->dom == NULL) {
         DEBUG(SSSDBG_OP_FAILURE, ("Corresponding domain [%s] has not been "
                                   "found\n", pr_ctx->domain_name));
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index ba4e969..8350f65 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -795,7 +795,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
 
     /* now check user is valid */
     if (pd->domain) {
-        preq->domain = responder_get_domain(preq, cctx->rctx, pd->domain);
+        preq->domain = responder_get_domain(cctx->rctx, pd->domain);
         if (!preq->domain) {
             ret = ENOENT;
             goto done;
@@ -867,7 +867,7 @@ static void pam_forwarder_cb(struct tevent_req *req)
     }
 
     if (preq->pd->domain) {
-        preq->domain = responder_get_domain(preq, cctx->rctx, preq->pd->domain);
+        preq->domain = responder_get_domain(cctx->rctx, preq->pd->domain);
         if (preq->domain == NULL) {
             ret = ENOENT;
             goto done;
diff --git a/src/responder/ssh/sshsrv_cmd.c b/src/responder/ssh/sshsrv_cmd.c
index e0ce3c9..671160e 100644
--- a/src/responder/ssh/sshsrv_cmd.c
+++ b/src/responder/ssh/sshsrv_cmd.c
@@ -71,8 +71,7 @@ sss_ssh_cmd_get_user_pubkeys(struct cli_ctx *cctx)
     }
 
     if (cmd_ctx->domname) {
-        cmd_ctx->domain = responder_get_domain(cmd_ctx, cctx->rctx,
-                                               cmd_ctx->domname);
+        cmd_ctx->domain = responder_get_domain(cctx->rctx, cmd_ctx->domname);
         if (!cmd_ctx->domain) {
             ret = ENOENT;
             goto done;
@@ -114,8 +113,7 @@ sss_ssh_cmd_get_host_pubkeys(struct cli_ctx *cctx)
            cmd_ctx->domname ? cmd_ctx->domname : "<ALL>"));
 
     if (cmd_ctx->domname) {
-        cmd_ctx->domain = responder_get_domain(cmd_ctx, cctx->rctx,
-                                               cmd_ctx->domname);
+        cmd_ctx->domain = responder_get_domain(cctx->rctx, cmd_ctx->domname);
         if (!cmd_ctx->domain) {
             ret = ENOENT;
             goto done;
diff --git a/src/responder/sudo/sudosrv_query.c b/src/responder/sudo/sudosrv_query.c
index a8501df..d88d247 100644
--- a/src/responder/sudo/sudosrv_query.c
+++ b/src/responder/sudo/sudosrv_query.c
@@ -412,7 +412,7 @@ errno_t sudosrv_parse_query_recv(TALLOC_CTX *mem_ctx,
     if (domainname != NULL) {
         /* mem_ctx because it duplicates only subdomains not domains
          * so I cannot easily steal it */
-        domain = responder_get_domain(mem_ctx, state->rctx, domainname);
+        domain = responder_get_domain(state->rctx, domainname);
         if (domain == NULL) {
             DEBUG(SSSDBG_OP_FAILURE, ("Corresponding domain [%s] has not been "
                                       "found\n", domainname));
-- 
1.7.7.6

-------------- next part --------------
From d253346c76e26d01a507b56760be1820f5cab740 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Thu, 18 Apr 2013 12:50:18 +0200
Subject: [PATCH 02/12] responder_get_domain: do not return disabled domains

Recent refactoring introduced to concept of disabled domains, i.e.
domains which does not exists anymore. responder_get_domain() should not
return disabled domains.
---
 src/responder/common/responder_common.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 3292591..480b046 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -905,6 +905,10 @@ responder_get_domain(struct resp_ctx *rctx, const char *name)
     struct sss_domain_info *ret_dom = NULL;
 
     for (dom = rctx->domains; dom; dom = get_next_domain(dom, true)) {
+        if (dom->disabled) {
+            continue;
+        }
+
         if (!IS_SUBDOMAIN(dom)) {
             time_diff = now - dom->subdomains_last_checked.tv_sec;
         }
-- 
1.7.7.6

-------------- next part --------------
From 426211144ea5c120224d04541c41131593b2f896 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Thu, 18 Apr 2013 16:29:21 +0200
Subject: [PATCH 03/12] responder_get_domain(): remove timeout calculation

The current timout calculation code in responder_get_domain() is flawed
and I think it always was. I removed the related code because
- it currently has no effect, a match is returned even if it is expired
- that callers do not have any code to handle expired domains.
---
 src/responder/common/responder_common.c |   11 +----------
 1 files changed, 1 insertions(+), 10 deletions(-)

diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 480b046..008d622 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -899,8 +899,6 @@ int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain,
 struct sss_domain_info *
 responder_get_domain(struct resp_ctx *rctx, const char *name)
 {
-    time_t now = time(NULL);
-    time_t time_diff = 0;
     struct sss_domain_info *dom;
     struct sss_domain_info *ret_dom = NULL;
 
@@ -909,19 +907,12 @@ responder_get_domain(struct resp_ctx *rctx, const char *name)
             continue;
         }
 
-        if (!IS_SUBDOMAIN(dom)) {
-            time_diff = now - dom->subdomains_last_checked.tv_sec;
-        }
         if (strcasecmp(dom->name, name) == 0 ||
             (dom->flat_name != NULL &&
              strcasecmp(dom->flat_name, name) == 0)) {
             ret_dom = dom;
-            if (!IS_SUBDOMAIN(dom) ||
-                (IS_SUBDOMAIN(dom) && time_diff < rctx->domains_timeout)) {
-                break;
-            }
+            break;
         }
-
     }
 
     if (!ret_dom) {
-- 
1.7.7.6

-------------- next part --------------
From fcf42f9b82b6e30fda332fa7b58adc6ac5b78c3e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 19 Apr 2013 12:22:03 +0200
Subject: [PATCH 04/12] LDAP: always store SID if available

Currently the string representation of a SID is only stored in the cache
for debugging purpose if SID based ID-mapping is used. This patch
unconditionally stores the SID if available to allow SID-to-name
mappings from the cache.
---
 src/providers/ldap/sdap_async_groups.c |   49 ++++++++++++++++++-------------
 src/providers/ldap/sdap_async_users.c  |   42 +++++++++++++++++++--------
 2 files changed, 58 insertions(+), 33 deletions(-)

diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index bb88d6c..cb30d4b 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -458,34 +458,41 @@ static int sdap_save_group(TALLOC_CTX *memctx,
     }
     DEBUG(SSSDBG_TRACE_FUNC, ("Processing group %s\n", name));
 
-    if (use_id_mapping) {
-        posix_group = true;
-
-        DEBUG(SSSDBG_TRACE_LIBS,
-              ("Mapping group [%s] objectSID to unix ID\n", name));
-
-        ret = sdap_attrs_get_sid_str(
-                tmpctx, opts->idmap_ctx, attrs,
-                opts->group_map[SDAP_AT_GROUP_OBJECTSID].sys_name,
-                &sid_str);
+    /* Always store SID string if available */
+    ret = sdap_attrs_get_sid_str(tmpctx, opts->idmap_ctx, attrs,
+                              opts->group_map[SDAP_AT_GROUP_OBJECTSID].sys_name,
+                              &sid_str);
+    if (ret == EOK) {
+        ret = sysdb_attrs_add_string(group_attrs, SYSDB_SID_STR, sid_str);
         if (ret != EOK) {
-            DEBUG(SSSDBG_MINOR_FAILURE,
-                  ("Could not identify objectSID: [%s]\n",
-                   strerror(ret)));
+            DEBUG(SSSDBG_MINOR_FAILURE, ("Could not add SID string: [%s]\n",
+                                         strerror(ret)));
             goto done;
         }
+    } else if (ret == ENOENT) {
+        DEBUG(SSSDBG_TRACE_ALL, ("objectSID: not available for group [%s].\n",
+                                 name));
+        sid_str = NULL;
+    } else {
+        DEBUG(SSSDBG_MINOR_FAILURE, ("Could not identify objectSID: [%s]\n",
+                                     strerror(ret)));
+        sid_str = NULL;
+    }
 
-        /* Add string representation to the cache for easier
-         * debugging
-         */
-        ret = sysdb_attrs_add_string(group_attrs, SYSDB_SID_STR, sid_str);
-        if (ret != EOK) {
-            DEBUG(SSSDBG_MINOR_FAILURE,
-                  ("Could not add SID string: [%s]\n",
-                   strerror(ret)));
+    if (use_id_mapping) {
+        posix_group = true;
+
+        if (sid_str == NULL) {
+            DEBUG(SSSDBG_MINOR_FAILURE, ("SID not available, cannot map a " \
+                                         "unix ID to group [%s].\n", name));
+            ret = ENOENT;
             goto done;
         }
 
+        DEBUG(SSSDBG_TRACE_LIBS,
+              ("Mapping group [%s] objectSID [%s] to unix ID\n",
+               name, sid_str));
+
         /* Convert the SID into a UNIX group ID */
         ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &gid);
         if (ret == ENOTSUP) {
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index ccd2f24..68e646c 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -132,22 +132,40 @@ int sdap_save_user(TALLOC_CTX *memctx,
     if (el->num_values == 0) shell = NULL;
     else shell = (const char *)el->values[0].data;
 
+    /* Always store SID string if available */
+    ret = sdap_attrs_get_sid_str(tmpctx, opts->idmap_ctx, attrs,
+                                opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name,
+                                &sid_str);
+    if (ret == EOK) {
+        ret = sysdb_attrs_add_string(user_attrs, SYSDB_SID_STR, sid_str);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_MINOR_FAILURE, ("Could not add SID string: [%s]\n",
+                                         strerror(ret)));
+            goto done;
+        }
+    } else if (ret == ENOENT) {
+        DEBUG(SSSDBG_TRACE_ALL, ("objectSID: not available for group [%s].\n",
+                                 name));
+        sid_str = NULL;
+    } else {
+        DEBUG(SSSDBG_MINOR_FAILURE, ("Could not identify objectSID: [%s]\n",
+                                     strerror(ret)));
+        sid_str = NULL;
+    }
+
+
     /* Retrieve or map the UID as appropriate */
     if (use_id_mapping) {
-        DEBUG(SSSDBG_TRACE_LIBS,
-              ("Mapping user [%s] objectSID to unix ID\n", name));
 
-        ret = sdap_attrs_get_sid_str(
-                tmpctx, opts->idmap_ctx, attrs,
-                opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name,
-                &sid_str);
-        if (ret != EOK) goto done;
+        if (sid_str == NULL) {
+            DEBUG(SSSDBG_MINOR_FAILURE, ("SID not available, cannot map a " \
+                                         "unix ID to user [%s].\n", name));
+            ret = ENOENT;
+            goto done;
+        }
 
-        /* Add string representation to the cache for easier
-         * debugging
-         */
-        ret = sysdb_attrs_add_string(user_attrs, SYSDB_SID_STR, sid_str);
-        if (ret != EOK) goto done;
+        DEBUG(SSSDBG_TRACE_LIBS,
+              ("Mapping user [%s] objectSID [%s] to unix ID\n", name, sid_str));
 
         /* Convert the SID into a UNIX user ID */
         ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &uid);
-- 
1.7.7.6

-------------- next part --------------
From 5768d0eb04ecd751b7758802cc860dd9e7cb6b82 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Thu, 11 Apr 2013 18:23:27 +0200
Subject: [PATCH 05/12] Add secid filter to responder-dp protocol

This patch add a new filter type to the data-provider interface which
can be used for SID-based lookups.
---
 src/providers/data_provider.h       |    6 ++++++
 src/providers/data_provider_be.c    |    5 +++++
 src/providers/ldap/ldap_id.c        |    6 ++++++
 src/providers/proxy/proxy_id.c      |    6 ++++++
 src/responder/common/responder_dp.c |   18 ++++++++++++++----
 5 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index 256e608..3136814 100644
--- a/src/providers/data_provider.h
+++ b/src/providers/data_provider.h
@@ -140,6 +140,7 @@
 #define BE_FILTER_NAME 1
 #define BE_FILTER_IDNUM 2
 #define BE_FILTER_ENUM 3
+#define BE_FILTER_SECID 4
 
 #define BE_REQ_USER          0x0001
 #define BE_REQ_GROUP         0x0002
@@ -153,6 +154,11 @@
 #define BE_REQ_TYPE_MASK     0x00FF
 #define BE_REQ_FAST          0x1000
 
+#define DP_SEC_ID "secid"
+/* sizeof() counts the trailing \0 so we must substract 1 for the string
+ * length */
+#define DP_SEC_ID_LEN (sizeof(DP_SEC_ID) - 1)
+
 /* AUTH related common data and functions */
 
 #define DEBUG_PAM_DATA(level, pd) do { \
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index 823dc00..cd67156 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -1043,6 +1043,11 @@ static int be_get_account_info(DBusMessage *message, struct sbus_connection *con
             ret = split_name_extended(req, &filter[9],
                                       &req->filter_value,
                                       &req->extra_value);
+        } else if (strncmp(filter, DP_SEC_ID"=", DP_SEC_ID_LEN + 1) == 0) {
+            req->filter_type = BE_FILTER_SECID;
+            ret = split_name_extended(req, &filter[DP_SEC_ID_LEN + 1],
+                                      &req->filter_value,
+                                      &req->extra_value);
         } else if (strcmp(filter, ENUM_INDICATOR) == 0) {
             req->filter_type = BE_FILTER_ENUM;
             req->filter_value = NULL;
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index 073f686..4d373a4 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -1058,6 +1058,12 @@ void sdap_handle_account_info(struct be_req *breq, struct sdap_id_ctx *ctx)
             return sdap_handler_done(breq, DP_ERR_OK, EOK, "Success");
         }
 
+        if (ar->filter_type == BE_FILTER_SECID) {
+            ret = EINVAL;
+            err = "Invalid filter type";
+            break;
+        }
+
         req = services_get_send(breq, be_ctx->ev, ctx,
                                 ar->filter_value,
                                 ar->extra_value,
diff --git a/src/providers/proxy/proxy_id.c b/src/providers/proxy/proxy_id.c
index 7d7fab2..aae3ee8 100644
--- a/src/providers/proxy/proxy_id.c
+++ b/src/providers/proxy/proxy_id.c
@@ -1364,6 +1364,12 @@ void proxy_get_account_info(struct be_req *breq)
         return be_req_terminate(breq, DP_ERR_FATAL, EINVAL, "Invalid attr type");
     }
 
+    /* proxy provider does not support security ID lookups */
+    if (ar->filter_type == BE_FILTER_SECID) {
+        return be_req_terminate(breq, DP_ERR_FATAL, ENOSYS,
+                                "Invalid filter type");
+    }
+
     switch (ar->entry_type & BE_REQ_TYPE_MASK) {
     case BE_REQ_USER: /* user */
         switch (ar->filter_type) {
diff --git a/src/responder/common/responder_dp.c b/src/responder/common/responder_dp.c
index d23075d..53826b0 100644
--- a/src/responder/common/responder_dp.c
+++ b/src/responder/common/responder_dp.c
@@ -548,11 +548,21 @@ sss_dp_get_account_msg(void *pvt)
     }
 
     if (info->opt_name) {
-        if (info->extra) {
-            filter = talloc_asprintf(info, "name=%s:%s",
-                                     info->opt_name, info->extra);
+        if (info->type == SSS_DP_SECID) {
+            if (info->extra) {
+                filter = talloc_asprintf(info, "%s=%s:%s", DP_SEC_ID,
+                                               info->opt_name, info->extra);
+            } else {
+                filter = talloc_asprintf(info, "%s=%s", DP_SEC_ID,
+                                               info->opt_name);
+            }
         } else {
-            filter = talloc_asprintf(info, "name=%s", info->opt_name);
+            if (info->extra) {
+                filter = talloc_asprintf(info, "name=%s:%s",
+                                         info->opt_name, info->extra);
+            } else {
+                filter = talloc_asprintf(info, "name=%s", info->opt_name);
+            }
         }
     } else if (info->opt_id) {
         if (info->extra) {
-- 
1.7.7.6

-------------- next part --------------
From 4d38344b3aa24b8deac54c93f06de19fa3d47be3 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Mon, 22 Apr 2013 16:29:51 +0200
Subject: [PATCH 06/12] Add two new request types to the data-provider
 interface

The patch adds two new request types for SID related requests. The first
one is used if a SID is given and the corresponding object should be
found. The second one can be used if the SID for an object is requested
but it is not clear if the object is a user or a group.
---
 src/providers/data_provider.h       |    2 ++
 src/responder/common/responder.h    |    4 +++-
 src/responder/common/responder_dp.c |    6 ++++++
 3 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index 3136814..d086d5d2 100644
--- a/src/providers/data_provider.h
+++ b/src/providers/data_provider.h
@@ -151,6 +151,8 @@
 #define BE_REQ_SUDO_RULES    0x0007
 #define BE_REQ_AUTOFS        0x0009
 #define BE_REQ_HOST          0x0010
+#define BE_REQ_BY_SECID      0x0011
+#define BE_REQ_USER_AND_GROUP 0x0012
 #define BE_REQ_TYPE_MASK     0x00FF
 #define BE_REQ_FAST          0x1000
 
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index e1b0b00..9c54041 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -266,7 +266,9 @@ enum sss_dp_acct_type {
     SSS_DP_GROUP,
     SSS_DP_INITGROUPS,
     SSS_DP_NETGR,
-    SSS_DP_SERVICES
+    SSS_DP_SERVICES,
+    SSS_DP_SECID,
+    SSS_DP_USER_AND_GROUP
 };
 
 struct tevent_req *
diff --git a/src/responder/common/responder_dp.c b/src/responder/common/responder_dp.c
index 53826b0..c5e8fc8 100644
--- a/src/responder/common/responder_dp.c
+++ b/src/responder/common/responder_dp.c
@@ -541,6 +541,12 @@ sss_dp_get_account_msg(void *pvt)
         case SSS_DP_SERVICES:
             be_type = BE_REQ_SERVICES;
             break;
+        case SSS_DP_SECID:
+            be_type = BE_REQ_BY_SECID;
+            break;
+        case SSS_DP_USER_AND_GROUP:
+            be_type = BE_REQ_USER_AND_GROUP;
+            break;
     }
 
     if (info->fast_reply) {
-- 
1.7.7.6

-------------- next part --------------
From 5415ba55711d640d5d5d79d77c5d8d473cc80991 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 16 Apr 2013 10:48:17 +0200
Subject: [PATCH 07/12] Add idmap context to nss context

This allows the nss responder to use libsss_idmap to convert between
different SID representations.
---
 Makefile.am                |    1 +
 src/responder/nss/nsssrv.c |   19 +++++++++++++++++++
 src/responder/nss/nsssrv.h |    3 +++
 3 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index eef1836..e79d95b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -620,6 +620,7 @@ sssd_nss_SOURCES = \
 sssd_nss_LDADD = \
     $(TDB_LIBS) \
     $(SSSD_LIBS) \
+    libsss_idmap.la \
     libsss_util.la
 
 sssd_pam_SOURCES = \
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 709912c..ee8fecb 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -391,6 +391,16 @@ static void nss_dp_reconnect_init(struct sbus_connection *conn,
     /* nss_shutdown(rctx); */
 }
 
+static void *idmap_talloc(size_t size, void *pvt)
+{
+    return talloc_size(pvt, size);
+}
+
+static void idmap_free(void *ptr, void *pvt)
+{
+    talloc_free(ptr);
+}
+
 int nss_process_init(TALLOC_CTX *mem_ctx,
                      struct tevent_context *ev,
                      struct confdb_ctx *cdb)
@@ -401,6 +411,7 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
     struct nss_ctx *nctx;
     int memcache_timeout;
     int ret, max_retries;
+    enum idmap_error_code err;
     int hret;
     int fd_limit;
 
@@ -457,6 +468,14 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
                             nss_dp_reconnect_init, iter);
     }
 
+    err = sss_idmap_init(idmap_talloc, nctx, idmap_free,
+                         &nctx->idmap_ctx);
+    if (err != IDMAP_SUCCESS) {
+        DEBUG(SSSDBG_FATAL_FAILURE, ("sss_idmap_init failed.\n"));
+        ret = EFAULT;
+        goto fail;
+    }
+
     /* Create the lookup table for netgroup results */
     hret = sss_hash_create(nctx, 10, &nctx->netgroups);
     if (hret != HASH_SUCCESS) {
diff --git a/src/responder/nss/nsssrv.h b/src/responder/nss/nsssrv.h
index 354782b..b279f8a 100644
--- a/src/responder/nss/nsssrv.h
+++ b/src/responder/nss/nsssrv.h
@@ -32,6 +32,7 @@
 #include "sbus/sssd_dbus.h"
 #include "responder/common/responder_packet.h"
 #include "responder/common/responder.h"
+#include "lib/idmap/sss_idmap.h"
 
 #define NSS_PACKET_MAX_RECV_SIZE 1024
 
@@ -68,6 +69,8 @@ struct nss_ctx {
 
     struct sss_mc_ctx *pwd_mc_ctx;
     struct sss_mc_ctx *grp_mc_ctx;
+
+    struct sss_idmap_ctx *idmap_ctx;
 };
 
 struct nss_packet;
-- 
1.7.7.6

-------------- next part --------------
From ca67e3a7ce09f738a85fcd650bc898a6921e27a2 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 19 Apr 2013 11:54:14 +0200
Subject: [PATCH 08/12] Add responder_get_domain_by_id()

This new call is similar to responder_get_domain() but uses the domain
SID as search parameter. Since the length of the stored domain SID is
used in the comparison, SIDs of users and groups and be used directly
without stripping the RID component.

The functionality is not merged into responder_get_domain() to allow to
calculate the timeout correctly and return a specific error code if the
entry is expired.
---
 src/responder/common/responder.h        |    3 ++
 src/responder/common/responder_common.c |   49 +++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 0 deletions(-)

diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index 9c54041..68b4ebb 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -171,6 +171,9 @@ int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain,
 struct sss_domain_info *
 responder_get_domain(struct resp_ctx *rctx, const char *domain);
 
+errno_t responder_get_domain_by_id(struct resp_ctx *rctx, const char *id,
+                                   struct sss_domain_info **_ret_dom);
+
 /* responder_cmd.c */
 int sss_cmd_empty_packet(struct sss_packet *packet);
 int sss_cmd_send_empty(struct cli_ctx *cctx, TALLOC_CTX *freectx);
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 008d622..54701d6 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -923,6 +923,55 @@ responder_get_domain(struct resp_ctx *rctx, const char *name)
     return ret_dom;
 }
 
+errno_t responder_get_domain_by_id(struct resp_ctx *rctx, const char *id,
+                                   struct sss_domain_info **_ret_dom)
+{
+    struct sss_domain_info *dom;
+    struct sss_domain_info *ret_dom = NULL;
+    size_t id_len;
+    size_t dom_id_len;
+    int ret;
+
+    if (id == NULL || _ret_dom == NULL) {
+        return EINVAL;
+    }
+
+    id_len = strlen(id);
+
+    for (dom = rctx->domains; dom; dom = get_next_domain(dom, true)) {
+        if (dom->disabled || dom->domain_id == NULL) {
+            continue;
+        }
+
+        dom_id_len = strlen(dom->domain_id);
+        if ((id_len >= dom_id_len) &&
+            strncasecmp(dom->domain_id, id, dom_id_len) == 0) {
+            if (IS_SUBDOMAIN(dom) &&
+                ((time(NULL) - dom->parent->subdomains_last_checked.tv_sec) >
+                                                      rctx->domains_timeout)) {
+                DEBUG(SSSDBG_TRACE_FUNC, ("Domain entry with id [%s] " \
+                                          "is expired.\n", id));
+                ret = EAGAIN;
+                goto done;
+            }
+            ret_dom = dom;
+            break;
+        }
+    }
+
+    if (ret_dom == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, ("Unknown domain id [%s], checking for"
+                                  "possible subdomains!\n", id));
+        ret = ENOENT;
+    } else {
+        *_ret_dom = ret_dom;
+        ret = EOK;
+    }
+
+done:
+    return ret;
+}
+
 int responder_logrotate(DBusMessage *message,
                         struct sbus_connection *conn)
 {
-- 
1.7.7.6

-------------- next part --------------
From 345effeca00b095c6d09efd12d2737fb2b97325e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 19 Apr 2013 17:44:06 +0200
Subject: [PATCH 09/12] sysdb: add sysdb_search_object_by_sid()

The patch add a new sysdb to find objects based on their SID. Currently
only the basic attributes needed to map SIDs to POSIX IDs and names are
requested, but this list can be extended for future use cases.
---
 src/db/sysdb.h     |    8 +++++++
 src/db/sysdb_ops.c |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 0 deletions(-)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index fb5e645..e91143c 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -154,6 +154,8 @@
 #define SYSDB_NETGR_FILTER "(&("SYSDB_NC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))"
 #define SYSDB_NETGR_TRIPLES_FILTER "(|("SYSDB_NAME"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_MEMBEROF"=%s))"
 
+#define SYSDB_SID_FILTER "(&(|("SYSDB_UC")("SYSDB_GC"))("SYSDB_SID_STR"=%s))"
+
 #define SYSDB_HAS_ENUMERATED "has_enumerated"
 
 #define SYSDB_DEFAULT_ATTRS SYSDB_LAST_UPDATE, \
@@ -848,4 +850,10 @@ 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_sid(TALLOC_CTX *mem_ctx,
+                                   struct sysdb_ctx *sysdb,
+                                   struct sss_domain_info *domain,
+                                   const char *sid_str,
+                                   const char **attrs,
+                                   struct ldb_result **msg);
 #endif /* __SYS_DB_H__ */
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 45a7265..710a23b 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -3174,3 +3174,57 @@ done:
     talloc_free(msg);
     return ret;
 }
+
+errno_t sysdb_search_object_by_sid(TALLOC_CTX *mem_ctx,
+                                   struct sysdb_ctx *sysdb,
+                                   struct sss_domain_info *domain,
+                                   const char *sid_str,
+                                   const char **attrs,
+                                   struct ldb_result **msg)
+{
+    TALLOC_CTX *tmp_ctx;
+    const char *def_attrs[] = { SYSDB_NAME, SYSDB_UIDNUM, SYSDB_GIDNUM,
+                                SYSDB_OBJECTCLASS, NULL };
+    struct ldb_dn *basedn;
+    int ret;
+    struct ldb_result *res = NULL;
+
+    tmp_ctx = talloc_new(NULL);
+    if (!tmp_ctx) {
+        return ENOMEM;
+    }
+
+    basedn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE, domain->name);
+    if (basedn == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, ("ldb_dn_new_fmt failed.\n"));
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = ldb_search(sysdb->ldb, tmp_ctx, &res,
+                     basedn, LDB_SCOPE_SUBTREE, attrs?attrs:def_attrs,
+                     SYSDB_SID_FILTER, sid_str);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, ("ldb_search failed.\n"));
+        goto done;
+    }
+
+    if (res->count > 1) {
+        DEBUG(SSSDBG_CRIT_FAILURE, ("Search for SID [%s] returned more than " \
+                                    "one object.\n", sid_str));
+        ret = EINVAL;
+        goto done;
+    }
+
+    *msg = talloc_steal(mem_ctx, res);
+
+done:
+    if (ret == ENOENT) {
+        DEBUG(SSSDBG_TRACE_FUNC, ("No such entry.\n"));
+    } else if (ret) {
+        DEBUG(SSSDBG_TRACE_FUNC, ("Error: %d (%s)\n", ret, strerror(ret)));
+    }
+
+    talloc_zfree(tmp_ctx);
+    return ret;
+}
-- 
1.7.7.6

-------------- next part --------------
From 7d401aae4c9794c9fbc711b21fa8b35ca7ad11b4 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Mon, 22 Apr 2013 16:26:56 +0200
Subject: [PATCH 10/12] Add sss_ncache_set_sid() and sss_ncache_check_sid()

Two new calls are added to allow to add SID based lookups to the
negative cache.
---
 src/responder/common/negcache.c |   29 +++++++++++++++++++++++++++++
 src/responder/common/negcache.h |    2 ++
 2 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index 2e1c0af..7693463 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -33,6 +33,7 @@
 #define NC_SERVICE_PREFIX NC_ENTRY_PREFIX"SERVICE"
 #define NC_UID_PREFIX NC_ENTRY_PREFIX"UID"
 #define NC_GID_PREFIX NC_ENTRY_PREFIX"GID"
+#define NC_SID_PREFIX NC_ENTRY_PREFIX"SID"
 
 struct sss_nc_ctx {
     struct tdb_context *tdb;
@@ -401,6 +402,20 @@ int sss_ncache_check_gid(struct sss_nc_ctx *ctx, int ttl, gid_t gid)
     return ret;
 }
 
+int sss_ncache_check_sid(struct sss_nc_ctx *ctx, int ttl, const char *sid)
+{
+    char *str;
+    int ret;
+
+    str = talloc_asprintf(ctx, "%s/%s", NC_SID_PREFIX, sid);
+    if (!str) return ENOMEM;
+
+    ret = sss_ncache_check_str(ctx, str, ttl);
+
+    talloc_free(str);
+    return ret;
+}
+
 static int sss_ncache_set_user_int(struct sss_nc_ctx *ctx, bool permanent,
                                    const char *domain, const char *name)
 {
@@ -518,6 +533,20 @@ int sss_ncache_set_gid(struct sss_nc_ctx *ctx, bool permanent, gid_t gid)
     return ret;
 }
 
+int sss_ncache_set_sid(struct sss_nc_ctx *ctx, bool permanent, const char *sid)
+{
+    char *str;
+    int ret;
+
+    str = talloc_asprintf(ctx, "%s/%s", NC_SID_PREFIX, sid);
+    if (!str) return ENOMEM;
+
+    ret = sss_ncache_set_str(ctx, str, permanent);
+
+    talloc_free(str);
+    return ret;
+}
+
 static int delete_permanent(struct tdb_context *tdb,
                             TDB_DATA key, TDB_DATA data, void *state)
 {
diff --git a/src/responder/common/negcache.h b/src/responder/common/negcache.h
index b2e6a7a..0b7e00b 100644
--- a/src/responder/common/negcache.h
+++ b/src/responder/common/negcache.h
@@ -36,6 +36,7 @@ int sss_ncache_check_netgr(struct sss_nc_ctx *ctx, int ttl,
                            const char *domain, const char *name);
 int sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, uid_t uid);
 int sss_ncache_check_gid(struct sss_nc_ctx *ctx, int ttl, gid_t gid);
+int sss_ncache_check_sid(struct sss_nc_ctx *ctx, int ttl, const char *sid);
 
 int sss_ncache_check_service(struct sss_nc_ctx *ctx, int ttl,
                              struct sss_domain_info *dom,
@@ -58,6 +59,7 @@ int sss_ncache_set_netgr(struct sss_nc_ctx *ctx, bool permanent,
                          struct sss_domain_info *dom, const char *name);
 int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool permanent, uid_t uid);
 int sss_ncache_set_gid(struct sss_nc_ctx *ctx, bool permanent, gid_t gid);
+int sss_ncache_set_sid(struct sss_nc_ctx *ctx, bool permanent, const char *sid);
 int sss_ncache_set_service_name(struct sss_nc_ctx *ctx, bool permanent,
                                 struct sss_domain_info *dom,
                                 const char *name, const char *proto);
-- 
1.7.7.6

-------------- next part --------------
From 89f1eab128a40231cc78a69fa8b140640b4b97b3 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Wed, 24 Apr 2013 11:08:21 +0200
Subject: [PATCH 11/12] Remove unused attribute list

---
 src/providers/ipa/ipa_id.h            |    1 -
 src/providers/ipa/ipa_s2n_exop.c      |    3 ---
 src/providers/ipa/ipa_subdomains_id.c |   11 +----------
 3 files changed, 1 insertions(+), 14 deletions(-)

diff --git a/src/providers/ipa/ipa_id.h b/src/providers/ipa/ipa_id.h
index 82f2f48..e446406 100644
--- a/src/providers/ipa/ipa_id.h
+++ b/src/providers/ipa/ipa_id.h
@@ -54,7 +54,6 @@ struct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx,
                                               struct sdap_options *opts,
                                               struct sss_domain_info *dom,
                                               struct sdap_handle *sh,
-                                              const char **attrs,
                                               int entry_type,
                                               const char *user_name,
                                               uid_t uid);
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
index 64ee775..9421c86 100644
--- a/src/providers/ipa/ipa_s2n_exop.c
+++ b/src/providers/ipa/ipa_s2n_exop.c
@@ -511,7 +511,6 @@ struct ipa_s2n_get_user_state {
     struct sdap_options *opts;
     struct sss_domain_info *dom;
     struct sdap_handle *sh;
-    const char **expected_attrs;
 };
 
 static void ipa_s2n_get_user_done(struct tevent_req *subreq);
@@ -521,7 +520,6 @@ struct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx,
                                               struct sdap_options *opts,
                                               struct sss_domain_info *dom,
                                               struct sdap_handle *sh,
-                                              const char **attrs,
                                               int entry_type,
                                               const char *name,
                                               uint32_t id)
@@ -547,7 +545,6 @@ struct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx,
     state->opts = opts;
     state->dom = dom;
     state->sh = sh;
-    state->expected_attrs = attrs;
 
     ret = s2n_encode_request(state, dom->name, entry_type, name, id, &bv_req);
     if (ret != EOK) {
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
index 264eb03..9c4187b 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -43,8 +43,6 @@ struct ipa_get_subdom_acct {
     const char *filter;
     int filter_type;
 
-    const char **attrs;
-
     int dp_error;
 };
 
@@ -92,14 +90,8 @@ struct tevent_req *ipa_get_subdom_acct_send(TALLOC_CTX *memctx,
 
     switch (state->entry_type) {
         case BE_REQ_USER:
-            ret = build_attrs_from_map(state, ctx->opts->user_map,
-                                       SDAP_OPTS_USER, NULL,
-                                       &state->attrs, NULL);
-            break;
         case BE_REQ_GROUP:
-            ret = build_attrs_from_map(state, ctx->opts->group_map,
-                                       SDAP_OPTS_GROUP, NULL,
-                                       &state->attrs, NULL);
+            ret = EOK;
             break;
         case BE_REQ_INITGROUPS:
             ret = ENOTSUP;
@@ -173,7 +165,6 @@ static void ipa_get_subdom_acct_connected(struct tevent_req *subreq)
                                         state->ctx->opts,
                                         state->domain,
                                         sdap_id_op_handle(state->op),
-                                        state->attrs,
                                         state->entry_type,
                                         name, id);
     if (!subreq) {
-- 
1.7.7.6

-------------- next part --------------
From 53a990a7ea72f1fb86a307c15504b31a6f3f7aca Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Wed, 24 Apr 2013 10:49:22 +0200
Subject: [PATCH 12/12] Use struct to hold different types of request
 parameters

Currently the POSIX ID or the user name are passed in different
parameters to some calls. The method will get cumbersome and error-prone
if new parameters like, e.g. the SID, are added. This patch adds a union
to hold the different kind of parameters.
---
 src/providers/ipa/ipa_id.h            |    4 ++--
 src/providers/ipa/ipa_s2n_exop.c      |   31 ++++++++++++++-----------------
 src/providers/ipa/ipa_subdomains.h    |   14 ++++++++++++++
 src/providers/ipa/ipa_subdomains_id.c |   25 ++++++++++++++++++-------
 4 files changed, 48 insertions(+), 26 deletions(-)

diff --git a/src/providers/ipa/ipa_id.h b/src/providers/ipa/ipa_id.h
index e446406..7fa25e9 100644
--- a/src/providers/ipa/ipa_id.h
+++ b/src/providers/ipa/ipa_id.h
@@ -29,6 +29,7 @@
 #include "providers/ldap/ldap_common.h"
 #include "providers/ipa/ipa_common.h"
 #include "providers/ldap/sdap.h"
+#include "providers/ipa/ipa_subdomains.h"
 
 void ipa_account_info_handler(struct be_req *breq);
 struct tevent_req *ipa_get_netgroups_send(TALLOC_CTX *memctx,
@@ -55,8 +56,7 @@ struct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx,
                                               struct sss_domain_info *dom,
                                               struct sdap_handle *sh,
                                               int entry_type,
-                                              const char *user_name,
-                                              uid_t uid);
+                                              struct req_input *req_input);
 int ipa_s2n_get_acct_info_recv(struct tevent_req *req);
 
 struct tevent_req *ipa_get_subdom_acct_send(TALLOC_CTX *memctx,
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
index 9421c86..c668598 100644
--- a/src/providers/ipa/ipa_s2n_exop.c
+++ b/src/providers/ipa/ipa_s2n_exop.c
@@ -24,6 +24,7 @@
 #include "db/sysdb.h"
 #include "providers/ldap/sdap_async_private.h"
 #include "providers/ldap/ldap_common.h"
+#include "providers/ipa/ipa_subdomains.h"
 
 enum input_types {
     INP_SID = 1,
@@ -279,8 +280,7 @@ done:
 static errno_t s2n_encode_request(TALLOC_CTX *mem_ctx,
                                   const char *domain_name,
                                   int entry_type,
-                                  const char *name,
-                                  uint32_t id,
+                                  struct req_input *req_input,
                                   struct berval **_bv)
 {
     BerElement *ber = NULL;
@@ -293,21 +293,25 @@ static errno_t s2n_encode_request(TALLOC_CTX *mem_ctx,
 
     switch (entry_type) {
         case BE_REQ_USER:
-            if (name != NULL) {
+            if (req_input->type == REQ_INP_NAME) {
                 ret = ber_printf(ber, "{ee{ss}}", INP_NAME, REQ_FULL,
-                                                  domain_name, name);
+                                                  domain_name,
+                                                  req_input->inp.name);
             } else {
                 ret = ber_printf(ber, "{ee{si}}", INP_POSIX_UID, REQ_FULL,
-                                                  domain_name, id);
+                                                  domain_name,
+                                                  req_input->inp.id);
             }
             break;
         case BE_REQ_GROUP:
-            if (name != NULL) {
+            if (req_input->type == REQ_INP_NAME) {
                 ret = ber_printf(ber, "{ee{ss}}", INP_NAME, REQ_FULL,
-                                                  domain_name, name);
+                                                  domain_name,
+                                                  req_input->inp.name);
             } else {
                 ret = ber_printf(ber, "{ee{si}}", INP_POSIX_GID, REQ_FULL,
-                                                  domain_name, id);
+                                                  domain_name,
+                                                  req_input->inp.id);
             }
             break;
         default:
@@ -521,8 +525,7 @@ struct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx,
                                               struct sss_domain_info *dom,
                                               struct sdap_handle *sh,
                                               int entry_type,
-                                              const char *name,
-                                              uint32_t id)
+                                              struct req_input *req_input)
 {
     struct ipa_s2n_get_user_state *state;
     struct tevent_req *req;
@@ -530,12 +533,6 @@ struct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx,
     struct berval *bv_req = NULL;
     int ret = EFAULT;
 
-    if ((name == NULL && id == 0) || (name != NULL && id != 0)) {
-        DEBUG(SSSDBG_OP_FAILURE, ("Either a user name or a uid expected, "
-                                  "not both or nothing.\n"));
-        return NULL;
-    }
-
     req = tevent_req_create(mem_ctx, &state, struct ipa_s2n_get_user_state);
     if (req == NULL) {
         return NULL;
@@ -546,7 +543,7 @@ struct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx,
     state->dom = dom;
     state->sh = sh;
 
-    ret = s2n_encode_request(state, dom->name, entry_type, name, id, &bv_req);
+    ret = s2n_encode_request(state, dom->name, entry_type, req_input, &bv_req);
     if (ret != EOK) {
         goto fail;
     }
diff --git a/src/providers/ipa/ipa_subdomains.h b/src/providers/ipa/ipa_subdomains.h
index df7f994..c9ab82a 100644
--- a/src/providers/ipa/ipa_subdomains.h
+++ b/src/providers/ipa/ipa_subdomains.h
@@ -38,4 +38,18 @@ int ipa_subdom_init(struct be_ctx *be_ctx,
                     struct bet_ops **ops,
                     void **pvt_data);
 
+enum req_input_type {
+    REQ_INP_NAME,
+    REQ_INP_ID,
+    REQ_INP_SECID
+};
+
+struct req_input {
+    enum req_input_type type;
+    union {
+        const char *name;
+        uint32_t id;
+        const char *secid;
+    } inp;
+};
 #endif /* _IPA_SUBDOMAINS_H_ */
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
index 9c4187b..0619483 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -128,9 +128,8 @@ static void ipa_get_subdom_acct_connected(struct tevent_req *subreq)
                                                 struct ipa_get_subdom_acct);
     int dp_error = DP_ERR_FATAL;
     int ret;
-    const char *name;
-    uint32_t id;
     char *endptr;
+    struct req_input *req_input;
 
     ret = sdap_id_op_connect_recv(subreq, &dp_error);
     talloc_zfree(subreq);
@@ -140,14 +139,26 @@ static void ipa_get_subdom_acct_connected(struct tevent_req *subreq)
         return;
     }
 
+    req_input = talloc(state, struct req_input);
+    if (req_input == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, ("talloc failed.\n"));
+        tevent_req_error(req, ENOMEM);
+        return;
+    }
+
     switch (state->filter_type) {
         case BE_FILTER_NAME:
-            name = state->filter;
-            id = 0;
+            req_input->type = REQ_INP_NAME;
+            req_input->inp.name = talloc_strdup(req_input, state->filter);
+            if (req_input->inp.name == NULL) {
+                DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
+                tevent_req_error(req, ENOMEM);
+                return;
+            }
             break;
         case BE_FILTER_IDNUM:
-            name = NULL;
-            id = strtouint32(state->filter, &endptr, 10);
+            req_input->type = REQ_INP_ID;
+            req_input->inp.id = strtouint32(state->filter, &endptr, 10);
             if (errno || *endptr || (state->filter == endptr)) {
                 tevent_req_error(req, errno ? errno : EINVAL);
                 return;
@@ -166,7 +177,7 @@ static void ipa_get_subdom_acct_connected(struct tevent_req *subreq)
                                         state->domain,
                                         sdap_id_op_handle(state->op),
                                         state->entry_type,
-                                        name, id);
+                                        req_input);
     if (!subreq) {
         tevent_req_error(req, ENOMEM);
         return;
-- 
1.7.7.6



More information about the sssd-devel mailing list