Blame SOURCES/0024-NSS-add-_EX-version-of-some-requests.patch

ced1f5
From 8c6cb61cc65af7d3f243476dca66fb8f4750df80 Mon Sep 17 00:00:00 2001
ced1f5
From: Sumit Bose <sbose@redhat.com>
ced1f5
Date: Wed, 11 Oct 2017 14:54:54 +0200
ced1f5
Subject: [PATCH 24/31] NSS: add *_EX version of some requests
ced1f5
ced1f5
To be able to send the flags to the SSSD responder new request types
ced1f5
with an _EX postfix are added which expect and additional 32bit flag
ced1f5
field after the name or the id of the requested object.
ced1f5
ced1f5
Related to https://pagure.io/SSSD/sssd/issue/2478
ced1f5
ced1f5
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
ced1f5
(cherry picked from commit cf93f7c2f2031078bbbff095dae01eb4f8deff85)
ced1f5
---
ced1f5
 src/responder/nss/nss_cmd.c       |  76 +++++++++++++++++++++-----
ced1f5
 src/responder/nss/nss_protocol.c  |  81 ++++++++++++++++++++++++++++
ced1f5
 src/responder/nss/nss_protocol.h  |   8 +++
ced1f5
 src/sss_client/idmap/sss_nss_ex.c | 110 +++++++++++++++++++++++++++-----------
ced1f5
 src/sss_client/sss_cli.h          |   7 +++
ced1f5
 5 files changed, 237 insertions(+), 45 deletions(-)
ced1f5
ced1f5
diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c
ced1f5
index ebf66dfe0444b83aed20d58d36ddf70d2f4fa1f9..974eaccc93cea3a330007735676da69eb9b84141 100644
ced1f5
--- a/src/responder/nss/nss_cmd.c
ced1f5
+++ b/src/responder/nss/nss_cmd.c
ced1f5
@@ -54,6 +54,7 @@ static void nss_getby_done(struct tevent_req *subreq);
ced1f5
 static void nss_getlistby_done(struct tevent_req *subreq);
ced1f5
 
ced1f5
 static errno_t nss_getby_name(struct cli_ctx *cli_ctx,
ced1f5
+                              bool ex_version,
ced1f5
                               enum cache_req_type type,
ced1f5
                               const char **attrs,
ced1f5
                               enum sss_mc_type memcache,
ced1f5
@@ -64,6 +65,7 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx,
ced1f5
     struct tevent_req *subreq;
ced1f5
     const char *rawname;
ced1f5
     errno_t ret;
ced1f5
+    uint32_t flags = 0;
ced1f5
 
ced1f5
     cmd_ctx = nss_cmd_ctx_create(cli_ctx, cli_ctx, type, fill_fn);
ced1f5
     if (cmd_ctx == NULL) {
ced1f5
@@ -71,7 +73,11 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx,
ced1f5
         goto done;
ced1f5
     }
ced1f5
 
ced1f5
-    ret = nss_protocol_parse_name(cli_ctx, &rawname);
ced1f5
+    if (ex_version) {
ced1f5
+        ret = nss_protocol_parse_name_ex(cli_ctx, &rawname, &flags);
ced1f5
+    } else {
ced1f5
+        ret = nss_protocol_parse_name(cli_ctx, &rawname);
ced1f5
+    }
ced1f5
     if (ret != EOK) {
ced1f5
         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request message!\n");
ced1f5
         goto done;
ced1f5
@@ -108,6 +114,7 @@ done:
ced1f5
 }
ced1f5
 
ced1f5
 static errno_t nss_getby_id(struct cli_ctx *cli_ctx,
ced1f5
+                            bool ex_version,
ced1f5
                             enum cache_req_type type,
ced1f5
                             const char **attrs,
ced1f5
                             enum sss_mc_type memcache,
ced1f5
@@ -118,6 +125,7 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx,
ced1f5
     struct tevent_req *subreq;
ced1f5
     uint32_t id;
ced1f5
     errno_t ret;
ced1f5
+    uint32_t flags = 0;
ced1f5
 
ced1f5
     cmd_ctx = nss_cmd_ctx_create(cli_ctx, cli_ctx, type, fill_fn);
ced1f5
     if (cmd_ctx == NULL) {
ced1f5
@@ -125,7 +133,11 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx,
ced1f5
         goto done;
ced1f5
     }
ced1f5
 
ced1f5
-    ret = nss_protocol_parse_id(cli_ctx, &id;;
ced1f5
+    if (ex_version) {
ced1f5
+        ret = nss_protocol_parse_id_ex(cli_ctx, &id, &flags);
ced1f5
+    } else {
ced1f5
+        ret = nss_protocol_parse_id(cli_ctx, &id;;
ced1f5
+    }
ced1f5
     if (ret != EOK) {
ced1f5
         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request message!\n");
ced1f5
         goto done;
ced1f5
@@ -766,14 +778,26 @@ static errno_t nss_endent(struct cli_ctx *cli_ctx,
ced1f5
 
ced1f5
 static errno_t nss_cmd_getpwnam(struct cli_ctx *cli_ctx)
ced1f5
 {
ced1f5
-    return nss_getby_name(cli_ctx, CACHE_REQ_USER_BY_NAME, NULL, SSS_MC_PASSWD,
ced1f5
-                          nss_protocol_fill_pwent);
ced1f5
+    return nss_getby_name(cli_ctx, false, CACHE_REQ_USER_BY_NAME, NULL,
ced1f5
+                          SSS_MC_PASSWD, nss_protocol_fill_pwent);
ced1f5
 }
ced1f5
 
ced1f5
 static errno_t nss_cmd_getpwuid(struct cli_ctx *cli_ctx)
ced1f5
 {
ced1f5
-    return nss_getby_id(cli_ctx, CACHE_REQ_USER_BY_ID, NULL, SSS_MC_PASSWD,
ced1f5
-                        nss_protocol_fill_pwent);
ced1f5
+    return nss_getby_id(cli_ctx, false, CACHE_REQ_USER_BY_ID, NULL,
ced1f5
+                        SSS_MC_PASSWD, nss_protocol_fill_pwent);
ced1f5
+}
ced1f5
+
ced1f5
+static errno_t nss_cmd_getpwnam_ex(struct cli_ctx *cli_ctx)
ced1f5
+{
ced1f5
+    return nss_getby_name(cli_ctx, true, CACHE_REQ_USER_BY_NAME, NULL,
ced1f5
+                          SSS_MC_PASSWD, nss_protocol_fill_pwent);
ced1f5
+}
ced1f5
+
ced1f5
+static errno_t nss_cmd_getpwuid_ex(struct cli_ctx *cli_ctx)
ced1f5
+{
ced1f5
+    return nss_getby_id(cli_ctx, true, CACHE_REQ_USER_BY_ID, NULL,
ced1f5
+                        SSS_MC_PASSWD, nss_protocol_fill_pwent);
ced1f5
 }
ced1f5
 
ced1f5
 static errno_t nss_cmd_setpwent(struct cli_ctx *cli_ctx)
ced1f5
@@ -809,16 +833,29 @@ static errno_t nss_cmd_endpwent(struct cli_ctx *cli_ctx)
ced1f5
 
ced1f5
 static errno_t nss_cmd_getgrnam(struct cli_ctx *cli_ctx)
ced1f5
 {
ced1f5
-    return nss_getby_name(cli_ctx, CACHE_REQ_GROUP_BY_NAME, NULL, SSS_MC_GROUP,
ced1f5
-                          nss_protocol_fill_grent);
ced1f5
+    return nss_getby_name(cli_ctx, false, CACHE_REQ_GROUP_BY_NAME, NULL,
ced1f5
+                          SSS_MC_GROUP, nss_protocol_fill_grent);
ced1f5
 }
ced1f5
 
ced1f5
 static errno_t nss_cmd_getgrgid(struct cli_ctx *cli_ctx)
ced1f5
 {
ced1f5
-    return nss_getby_id(cli_ctx, CACHE_REQ_GROUP_BY_ID, NULL, SSS_MC_GROUP,
ced1f5
-                        nss_protocol_fill_grent);
ced1f5
+    return nss_getby_id(cli_ctx, false, CACHE_REQ_GROUP_BY_ID, NULL,
ced1f5
+                        SSS_MC_GROUP, nss_protocol_fill_grent);
ced1f5
 }
ced1f5
 
ced1f5
+static errno_t nss_cmd_getgrnam_ex(struct cli_ctx *cli_ctx)
ced1f5
+{
ced1f5
+    return nss_getby_name(cli_ctx, true, CACHE_REQ_GROUP_BY_NAME, NULL,
ced1f5
+                          SSS_MC_GROUP, nss_protocol_fill_grent);
ced1f5
+}
ced1f5
+
ced1f5
+static errno_t nss_cmd_getgrgid_ex(struct cli_ctx *cli_ctx)
ced1f5
+{
ced1f5
+    return nss_getby_id(cli_ctx, true, CACHE_REQ_GROUP_BY_ID, NULL,
ced1f5
+                        SSS_MC_GROUP, nss_protocol_fill_grent);
ced1f5
+}
ced1f5
+
ced1f5
+
ced1f5
 static errno_t nss_cmd_setgrent(struct cli_ctx *cli_ctx)
ced1f5
 {
ced1f5
     struct nss_ctx *nss_ctx;
ced1f5
@@ -852,7 +889,13 @@ static errno_t nss_cmd_endgrent(struct cli_ctx *cli_ctx)
ced1f5
 
ced1f5
 static errno_t nss_cmd_initgroups(struct cli_ctx *cli_ctx)
ced1f5
 {
ced1f5
-    return nss_getby_name(cli_ctx, CACHE_REQ_INITGROUPS, NULL,
ced1f5
+    return nss_getby_name(cli_ctx, false, CACHE_REQ_INITGROUPS, NULL,
ced1f5
+                          SSS_MC_INITGROUPS, nss_protocol_fill_initgr);
ced1f5
+}
ced1f5
+
ced1f5
+static errno_t nss_cmd_initgroups_ex(struct cli_ctx *cli_ctx)
ced1f5
+{
ced1f5
+    return nss_getby_name(cli_ctx, true, CACHE_REQ_INITGROUPS, NULL,
ced1f5
                           SSS_MC_INITGROUPS, nss_protocol_fill_initgr);
ced1f5
 }
ced1f5
 
ced1f5
@@ -943,7 +986,7 @@ static errno_t nss_cmd_getsidbyname(struct cli_ctx *cli_ctx)
ced1f5
 {
ced1f5
     const char *attrs[] = { SYSDB_SID_STR, NULL };
ced1f5
 
ced1f5
-    return nss_getby_name(cli_ctx, CACHE_REQ_OBJECT_BY_NAME, attrs,
ced1f5
+    return nss_getby_name(cli_ctx, false, CACHE_REQ_OBJECT_BY_NAME, attrs,
ced1f5
                           SSS_MC_NONE, nss_protocol_fill_sid);
ced1f5
 }
ced1f5
 
ced1f5
@@ -951,7 +994,7 @@ static errno_t nss_cmd_getsidbyid(struct cli_ctx *cli_ctx)
ced1f5
 {
ced1f5
     const char *attrs[] = { SYSDB_SID_STR, NULL };
ced1f5
 
ced1f5
-    return nss_getby_id(cli_ctx, CACHE_REQ_OBJECT_BY_ID, attrs,
ced1f5
+    return nss_getby_id(cli_ctx, false, CACHE_REQ_OBJECT_BY_ID, attrs,
ced1f5
                         SSS_MC_NONE, nss_protocol_fill_sid);
ced1f5
 }
ced1f5
 
ced1f5
@@ -1006,7 +1049,7 @@ static errno_t nss_cmd_getorigbyname(struct cli_ctx *cli_ctx)
ced1f5
         attrs = defattrs;
ced1f5
     }
ced1f5
 
ced1f5
-    return nss_getby_name(cli_ctx, CACHE_REQ_OBJECT_BY_NAME, attrs,
ced1f5
+    return nss_getby_name(cli_ctx, false, CACHE_REQ_OBJECT_BY_NAME, attrs,
ced1f5
                           SSS_MC_NONE, nss_protocol_fill_orig);
ced1f5
 }
ced1f5
 
ced1f5
@@ -1051,6 +1094,11 @@ struct sss_cmd_table *get_nss_cmds(void)
ced1f5
         { SSS_NSS_GETORIGBYNAME, nss_cmd_getorigbyname },
ced1f5
         { SSS_NSS_GETNAMEBYCERT, nss_cmd_getnamebycert },
ced1f5
         { SSS_NSS_GETLISTBYCERT, nss_cmd_getlistbycert },
ced1f5
+        { SSS_NSS_GETPWNAM_EX, nss_cmd_getpwnam_ex },
ced1f5
+        { SSS_NSS_GETPWUID_EX, nss_cmd_getpwuid_ex },
ced1f5
+        { SSS_NSS_GETGRNAM_EX, nss_cmd_getgrnam_ex },
ced1f5
+        { SSS_NSS_GETGRGID_EX, nss_cmd_getgrgid_ex },
ced1f5
+        { SSS_NSS_INITGR_EX, nss_cmd_initgroups_ex },
ced1f5
         { SSS_CLI_NULL, NULL }
ced1f5
     };
ced1f5
 
ced1f5
diff --git a/src/responder/nss/nss_protocol.c b/src/responder/nss/nss_protocol.c
ced1f5
index 06fc4d00a7877a7990402f4f2633ddc0bd640b41..17bfc4f4e71960a72e9e04622eac95b94a865ec7 100644
ced1f5
--- a/src/responder/nss/nss_protocol.c
ced1f5
+++ b/src/responder/nss/nss_protocol.c
ced1f5
@@ -134,6 +134,61 @@ nss_protocol_parse_name(struct cli_ctx *cli_ctx, const char **_rawname)
ced1f5
 }
ced1f5
 
ced1f5
 errno_t
ced1f5
+nss_protocol_parse_name_ex(struct cli_ctx *cli_ctx, const char **_rawname,
ced1f5
+                           uint32_t *_flags)
ced1f5
+{
ced1f5
+    struct cli_protocol *pctx;
ced1f5
+    const char *rawname;
ced1f5
+    uint8_t *body;
ced1f5
+    size_t blen;
ced1f5
+    uint8_t *p;
ced1f5
+    uint32_t flags;
ced1f5
+
ced1f5
+    pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
ced1f5
+
ced1f5
+    sss_packet_get_body(pctx->creq->in, &body, &blen);
ced1f5
+
ced1f5
+    if (blen < 1 + sizeof(uint32_t)) {
ced1f5
+        DEBUG(SSSDBG_CRIT_FAILURE, "Body too short!\n");
ced1f5
+        return EINVAL;
ced1f5
+    }
ced1f5
+
ced1f5
+    /* If first argument not terminated fail. */
ced1f5
+    if (body[blen - 1 - sizeof(uint32_t)] != '\0') {
ced1f5
+        DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated!\n");
ced1f5
+        return EINVAL;
ced1f5
+    }
ced1f5
+
ced1f5
+    p = memchr(body, '\0', blen);
ced1f5
+
ced1f5
+    /* If the body isn't valid UTF-8, fail */
ced1f5
+    if (!sss_utf8_check(body, (p - body))) {
ced1f5
+        DEBUG(SSSDBG_CRIT_FAILURE, "First argument is not UTF-8 string!\n");
ced1f5
+        return EINVAL;
ced1f5
+    }
ced1f5
+
ced1f5
+    rawname = (const char *)body;
ced1f5
+    if (rawname[0] == '\0') {
ced1f5
+        DEBUG(SSSDBG_CRIT_FAILURE, "An empty name was provided!\n");
ced1f5
+        return EINVAL;
ced1f5
+    }
ced1f5
+
ced1f5
+    p++;
ced1f5
+    if ((p - body) + sizeof(uint32_t) != blen) {
ced1f5
+        DEBUG(SSSDBG_CRIT_FAILURE, "Body has unexpected size!\n");
ced1f5
+        return EINVAL;
ced1f5
+    }
ced1f5
+
ced1f5
+    SAFEALIGN_COPY_UINT32(&flags, p, NULL);
ced1f5
+    p += sizeof(uint32_t);
ced1f5
+
ced1f5
+    *_rawname = rawname;
ced1f5
+    *_flags = flags;
ced1f5
+
ced1f5
+    return EOK;
ced1f5
+}
ced1f5
+
ced1f5
+errno_t
ced1f5
 nss_protocol_parse_id(struct cli_ctx *cli_ctx, uint32_t *_id)
ced1f5
 {
ced1f5
     struct cli_protocol *pctx;
ced1f5
@@ -157,6 +212,32 @@ nss_protocol_parse_id(struct cli_ctx *cli_ctx, uint32_t *_id)
ced1f5
 }
ced1f5
 
ced1f5
 errno_t
ced1f5
+nss_protocol_parse_id_ex(struct cli_ctx *cli_ctx, uint32_t *_id,
ced1f5
+                         uint32_t *_flags)
ced1f5
+{
ced1f5
+    struct cli_protocol *pctx;
ced1f5
+    uint8_t *body;
ced1f5
+    size_t blen;
ced1f5
+    uint32_t id;
ced1f5
+    uint32_t flags;
ced1f5
+
ced1f5
+    pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol);
ced1f5
+
ced1f5
+    sss_packet_get_body(pctx->creq->in, &body, &blen);
ced1f5
+
ced1f5
+    if (blen != 2 * sizeof(uint32_t)) {
ced1f5
+        return EINVAL;
ced1f5
+    }
ced1f5
+
ced1f5
+    SAFEALIGN_COPY_UINT32(&id, body, NULL);
ced1f5
+    SAFEALIGN_COPY_UINT32(&flags, body + sizeof(uint32_t), NULL);
ced1f5
+
ced1f5
+    *_id = id;
ced1f5
+
ced1f5
+    return EOK;
ced1f5
+}
ced1f5
+
ced1f5
+errno_t
ced1f5
 nss_protocol_parse_limit(struct cli_ctx *cli_ctx, uint32_t *_limit)
ced1f5
 {
ced1f5
     return nss_protocol_parse_id(cli_ctx, _limit);
ced1f5
diff --git a/src/responder/nss/nss_protocol.h b/src/responder/nss/nss_protocol.h
ced1f5
index 417b0891615dcb8771d49f7b2f4d276342ca3150..ca5b040237dc18acdca9a7a3a7a7dbb64265aa95 100644
ced1f5
--- a/src/responder/nss/nss_protocol.h
ced1f5
+++ b/src/responder/nss/nss_protocol.h
ced1f5
@@ -89,9 +89,17 @@ errno_t
ced1f5
 nss_protocol_parse_name(struct cli_ctx *cli_ctx, const char **_rawname);
ced1f5
 
ced1f5
 errno_t
ced1f5
+nss_protocol_parse_name_ex(struct cli_ctx *cli_ctx, const char **_rawname,
ced1f5
+                           uint32_t *_flags);
ced1f5
+
ced1f5
+errno_t
ced1f5
 nss_protocol_parse_id(struct cli_ctx *cli_ctx, uint32_t *_id);
ced1f5
 
ced1f5
 errno_t
ced1f5
+nss_protocol_parse_id_ex(struct cli_ctx *cli_ctx, uint32_t *_id,
ced1f5
+                         uint32_t *_flags);
ced1f5
+
ced1f5
+errno_t
ced1f5
 nss_protocol_parse_limit(struct cli_ctx *cli_ctx, uint32_t *_limit);
ced1f5
 
ced1f5
 errno_t
ced1f5
diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c
ced1f5
index 582d1373ec35305cf128e04fd3d705457d304789..dc7610a4e528b5126f0d25d84cd3c1a22f683b75 100644
ced1f5
--- a/src/sss_client/idmap/sss_nss_ex.c
ced1f5
+++ b/src/sss_client/idmap/sss_nss_ex.c
ced1f5
@@ -61,31 +61,37 @@ errno_t sss_nss_mc_get(struct nss_input *inp)
ced1f5
 {
ced1f5
     switch(inp->cmd) {
ced1f5
     case SSS_NSS_GETPWNAM:
ced1f5
-        return sss_nss_mc_getpwnam(inp->input.name, (inp->rd.len - 1),
ced1f5
+    case SSS_NSS_GETPWNAM_EX:
ced1f5
+        return sss_nss_mc_getpwnam(inp->input.name, strlen(inp->input.name),
ced1f5
                                    inp->result.pwrep.result,
ced1f5
                                    inp->result.pwrep.buffer,
ced1f5
                                    inp->result.pwrep.buflen);
ced1f5
         break;
ced1f5
     case SSS_NSS_GETPWUID:
ced1f5
+    case SSS_NSS_GETPWUID_EX:
ced1f5
         return sss_nss_mc_getpwuid(inp->input.uid,
ced1f5
                                    inp->result.pwrep.result,
ced1f5
                                    inp->result.pwrep.buffer,
ced1f5
                                    inp->result.pwrep.buflen);
ced1f5
         break;
ced1f5
     case SSS_NSS_GETGRNAM:
ced1f5
-        return sss_nss_mc_getgrnam(inp->input.name, (inp->rd.len - 1),
ced1f5
+    case SSS_NSS_GETGRNAM_EX:
ced1f5
+        return sss_nss_mc_getgrnam(inp->input.name, strlen(inp->input.name),
ced1f5
                                    inp->result.grrep.result,
ced1f5
                                    inp->result.grrep.buffer,
ced1f5
                                    inp->result.grrep.buflen);
ced1f5
         break;
ced1f5
     case SSS_NSS_GETGRGID:
ced1f5
+    case SSS_NSS_GETGRGID_EX:
ced1f5
         return sss_nss_mc_getgrgid(inp->input.gid,
ced1f5
                                    inp->result.grrep.result,
ced1f5
                                    inp->result.grrep.buffer,
ced1f5
                                    inp->result.grrep.buflen);
ced1f5
         break;
ced1f5
     case SSS_NSS_INITGR:
ced1f5
-        return sss_nss_mc_initgroups_dyn(inp->input.name, (inp->rd.len - 1),
ced1f5
+    case SSS_NSS_INITGR_EX:
ced1f5
+        return sss_nss_mc_initgroups_dyn(inp->input.name,
ced1f5
+                                         strlen(inp->input.name),
ced1f5
                                          -1 /* currently ignored */,
ced1f5
                                          inp->result.initgrrep.start,
ced1f5
                                          inp->result.initgrrep.ngroups,
ced1f5
@@ -163,7 +169,7 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
ced1f5
         goto out;
ced1f5
     }
ced1f5
 
ced1f5
-    if (inp->cmd == SSS_NSS_INITGR) {
ced1f5
+    if (inp->cmd == SSS_NSS_INITGR || inp->cmd == SSS_NSS_INITGR_EX) {
ced1f5
         if ((*(inp->result.initgrrep.ngroups) - *(inp->result.initgrrep.start))
ced1f5
                     < num_results) {
ced1f5
             new_groups = realloc(inp->result.initgrrep.groups,
ced1f5
@@ -198,15 +204,24 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout)
ced1f5
     }
ced1f5
 
ced1f5
     len = replen - 8;
ced1f5
-    if (inp->cmd == SSS_NSS_GETPWNAM || inp->cmd == SSS_NSS_GETPWUID) {
ced1f5
+
ced1f5
+    switch(inp->cmd) {
ced1f5
+    case SSS_NSS_GETPWNAM:
ced1f5
+    case SSS_NSS_GETPWUID:
ced1f5
+    case SSS_NSS_GETPWNAM_EX:
ced1f5
+    case SSS_NSS_GETPWUID_EX:
ced1f5
         ret = sss_nss_getpw_readrep(&(inp->result.pwrep), repbuf+8, &len;;
ced1f5
-    } else if (inp->cmd == SSS_NSS_GETGRNAM || inp->cmd == SSS_NSS_GETGRGID) {
ced1f5
+        break;
ced1f5
+    case SSS_NSS_GETGRNAM:
ced1f5
+    case SSS_NSS_GETGRGID:
ced1f5
+    case SSS_NSS_GETGRNAM_EX:
ced1f5
+    case SSS_NSS_GETGRGID_EX:
ced1f5
         ret = sss_nss_getgr_readrep(&(inp->result.grrep), repbuf+8, &len;;
ced1f5
-    } else {
ced1f5
+        break;
ced1f5
+    default:
ced1f5
         ret = EINVAL;
ced1f5
-        goto out;
ced1f5
     }
ced1f5
-    if (ret) {
ced1f5
+    if (ret != 0) {
ced1f5
         goto out;
ced1f5
     }
ced1f5
 
ced1f5
@@ -223,6 +238,39 @@ out:
ced1f5
     return ret;
ced1f5
 }
ced1f5
 
ced1f5
+static int make_name_flag_req_data(const char *name, uint32_t flags,
ced1f5
+                                   struct sss_cli_req_data *rd)
ced1f5
+{
ced1f5
+    size_t len;
ced1f5
+    size_t name_len;
ced1f5
+    uint8_t *data;
ced1f5
+    int ret;
ced1f5
+
ced1f5
+    if (name == NULL) {
ced1f5
+        return EINVAL;
ced1f5
+    }
ced1f5
+
ced1f5
+    ret = sss_strnlen(name, SSS_NAME_MAX, &name_len);
ced1f5
+    if (ret != 0) {
ced1f5
+        return ret;
ced1f5
+    }
ced1f5
+    name_len++;
ced1f5
+
ced1f5
+    len = name_len + sizeof(uint32_t);
ced1f5
+    data = malloc(len);
ced1f5
+    if (data == NULL) {
ced1f5
+        return ENOMEM;
ced1f5
+    }
ced1f5
+
ced1f5
+    memcpy(data, name, name_len);
ced1f5
+    SAFEALIGN_COPY_UINT32(data + name_len, &flags, NULL);
ced1f5
+
ced1f5
+    rd->len = len;
ced1f5
+    rd->data = data;
ced1f5
+
ced1f5
+    return 0;
ced1f5
+}
ced1f5
+
ced1f5
 int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd,
ced1f5
                              char *buffer, size_t buflen,
ced1f5
                              struct passwd **result,
ced1f5
@@ -231,8 +279,7 @@ int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd,
ced1f5
     int ret;
ced1f5
     struct nss_input inp = {
ced1f5
         .input.name = name,
ced1f5
-        .cmd = SSS_NSS_GETPWNAM,
ced1f5
-        .rd.data = name,
ced1f5
+        .cmd = SSS_NSS_GETPWNAM_EX,
ced1f5
         .result.pwrep.result = pwd,
ced1f5
         .result.pwrep.buffer = buffer,
ced1f5
         .result.pwrep.buflen = buflen};
ced1f5
@@ -241,15 +288,15 @@ int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd,
ced1f5
         return ERANGE;
ced1f5
     }
ced1f5
 
ced1f5
-    ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len);
ced1f5
+    ret = make_name_flag_req_data(name, flags, &inp.rd);
ced1f5
     if (ret != 0) {
ced1f5
-        return EINVAL;
ced1f5
+        return ret;
ced1f5
     }
ced1f5
-    inp.rd.len++;
ced1f5
 
ced1f5
     *result = NULL;
ced1f5
 
ced1f5
     ret = sss_get_ex(&inp, flags, timeout);
ced1f5
+    free(discard_const(inp.rd.data));
ced1f5
     if (ret == 0) {
ced1f5
         *result = inp.result.pwrep.result;
ced1f5
     }
ced1f5
@@ -262,12 +309,12 @@ int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd,
ced1f5
                              uint32_t flags, unsigned int timeout)
ced1f5
 {
ced1f5
     int ret;
ced1f5
-    uint32_t user_uid = uid;
ced1f5
+    uint32_t req_data[2];
ced1f5
     struct nss_input inp = {
ced1f5
         .input.uid = uid,
ced1f5
-        .cmd = SSS_NSS_GETPWUID,
ced1f5
-        .rd.len = sizeof(uint32_t),
ced1f5
-        .rd.data = &user_uid,
ced1f5
+        .cmd = SSS_NSS_GETPWUID_EX,
ced1f5
+        .rd.len = 2 * sizeof(uint32_t),
ced1f5
+        .rd.data = &req_data,
ced1f5
         .result.pwrep.result = pwd,
ced1f5
         .result.pwrep.buffer = buffer,
ced1f5
         .result.pwrep.buflen = buflen};
ced1f5
@@ -276,6 +323,8 @@ int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd,
ced1f5
         return ERANGE;
ced1f5
     }
ced1f5
 
ced1f5
+    SAFEALIGN_COPY_UINT32(&req_data[0], &uid, NULL);
ced1f5
+    SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL);
ced1f5
     *result = NULL;
ced1f5
 
ced1f5
     ret = sss_get_ex(&inp, flags, timeout);
ced1f5
@@ -292,8 +341,7 @@ int sss_nss_getgrnam_timeout(const char *name, struct group *grp,
ced1f5
     int ret;
ced1f5
     struct nss_input inp = {
ced1f5
         .input.name = name,
ced1f5
-        .cmd = SSS_NSS_GETGRNAM,
ced1f5
-        .rd.data = name,
ced1f5
+        .cmd = SSS_NSS_GETGRNAM_EX,
ced1f5
         .result.grrep.result = grp,
ced1f5
         .result.grrep.buffer = buffer,
ced1f5
         .result.grrep.buflen = buflen};
ced1f5
@@ -302,15 +350,15 @@ int sss_nss_getgrnam_timeout(const char *name, struct group *grp,
ced1f5
         return ERANGE;
ced1f5
     }
ced1f5
 
ced1f5
-    ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len);
ced1f5
+    ret = make_name_flag_req_data(name, flags, &inp.rd);
ced1f5
     if (ret != 0) {
ced1f5
-        return EINVAL;
ced1f5
+        return ret;
ced1f5
     }
ced1f5
-    inp.rd.len++;
ced1f5
 
ced1f5
     *result = NULL;
ced1f5
 
ced1f5
     ret = sss_get_ex(&inp, flags, timeout);
ced1f5
+    free(discard_const(inp.rd.data));
ced1f5
     if (ret == 0) {
ced1f5
         *result = inp.result.grrep.result;
ced1f5
     }
ced1f5
@@ -322,12 +370,12 @@ int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp,
ced1f5
                              uint32_t flags, unsigned int timeout)
ced1f5
 {
ced1f5
     int ret;
ced1f5
-    uint32_t group_gid = gid;
ced1f5
+    uint32_t req_data[2];
ced1f5
     struct nss_input inp = {
ced1f5
         .input.gid = gid,
ced1f5
-        .cmd = SSS_NSS_GETGRGID,
ced1f5
-        .rd.len = sizeof(uint32_t),
ced1f5
-        .rd.data = &group_gid,
ced1f5
+        .cmd = SSS_NSS_GETGRGID_EX,
ced1f5
+        .rd.len = 2 * sizeof(uint32_t),
ced1f5
+        .rd.data = &req_data,
ced1f5
         .result.grrep.result = grp,
ced1f5
         .result.grrep.buffer = buffer,
ced1f5
         .result.grrep.buflen = buflen};
ced1f5
@@ -336,6 +384,8 @@ int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp,
ced1f5
         return ERANGE;
ced1f5
     }
ced1f5
 
ced1f5
+    SAFEALIGN_COPY_UINT32(&req_data[0], &gid, NULL);
ced1f5
+    SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL);
ced1f5
     *result = NULL;
ced1f5
 
ced1f5
     ret = sss_get_ex(&inp, flags, timeout);
ced1f5
@@ -355,18 +405,16 @@ int sss_nss_getgrouplist_timeout(const char *name, gid_t group,
ced1f5
     long int start = 1;
ced1f5
     struct nss_input inp = {
ced1f5
         .input.name = name,
ced1f5
-        .cmd = SSS_NSS_INITGR,
ced1f5
-        .rd.data = name};
ced1f5
+        .cmd = SSS_NSS_INITGR_EX};
ced1f5
 
ced1f5
     if (groups == NULL || ngroups == NULL || *ngroups == 0) {
ced1f5
         return EINVAL;
ced1f5
     }
ced1f5
 
ced1f5
-    ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len);
ced1f5
+    ret = make_name_flag_req_data(name, flags, &inp.rd);
ced1f5
     if (ret != 0) {
ced1f5
         return ret;
ced1f5
     }
ced1f5
-    inp.rd.len++;
ced1f5
 
ced1f5
     new_ngroups = MAX(1, *ngroups);
ced1f5
     new_groups = malloc(new_ngroups * sizeof(gid_t));
ced1f5
diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h
ced1f5
index 5329651a9385d138b8ea7237cb5cf4e2b8e5f371..9d2cc00c9957f5680548461129e3e6b777da5091 100644
ced1f5
--- a/src/sss_client/sss_cli.h
ced1f5
+++ b/src/sss_client/sss_cli.h
ced1f5
@@ -79,6 +79,9 @@ enum sss_cli_command {
ced1f5
     SSS_NSS_GETPWENT       = 0x0014,
ced1f5
     SSS_NSS_ENDPWENT       = 0x0015,
ced1f5
 
ced1f5
+    SSS_NSS_GETPWNAM_EX    = 0x0019,
ced1f5
+    SSS_NSS_GETPWUID_EX    = 0x001A,
ced1f5
+
ced1f5
 /* group */
ced1f5
 
ced1f5
     SSS_NSS_GETGRNAM       = 0x0021,
ced1f5
@@ -88,6 +91,10 @@ enum sss_cli_command {
ced1f5
     SSS_NSS_ENDGRENT       = 0x0025,
ced1f5
     SSS_NSS_INITGR         = 0x0026,
ced1f5
 
ced1f5
+    SSS_NSS_GETGRNAM_EX    = 0x0029,
ced1f5
+    SSS_NSS_GETGRGID_EX    = 0x002A,
ced1f5
+    SSS_NSS_INITGR_EX      = 0x002E,
ced1f5
+
ced1f5
 #if 0
ced1f5
 /* aliases */
ced1f5
 
ced1f5
-- 
ced1f5
2.13.6
ced1f5