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

Sumit Bose sbose at redhat.com
Mon Apr 29 19:06:39 UTC 2013


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
-------------- next part --------------
From 2b5563190488759f6132c376d65c7455f071dee6 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 20b8f8a0a1ccba1cd3035b5327e7aa2ff8ae8835 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 5883787f8c99719ce921919ad5434ca728b15b37 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 586d2f300c217b9c31aa4f7312fe3259ecb69bab 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 1bb18f8c6d77fb67476265a948208800a382512d 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 9e60d595244e8dec9cb6c0dbf189dc415bd369bf 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..5a38468 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_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..53be577 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_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 6d5d337ceaee88e8031a73c10097a2e7b4fa0f25 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 a0f3421584236f2f02b0f5b54a415c4476e0e471 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 2854f6944a22ffd12a82b46532398f427575b3f6 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 1f27af8..341ebf7 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -3169,3 +3169,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 75558380d1d2aa7adb7f52f1f473029e5f266c38 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 069988991e9130a89684cd65e33e730a4bf0eec5 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 06f68282772e473d5c9fa08c5ba0f8ebaad152c9 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