diff options
author | Sumit Bose <sbose@redhat.com> | 2017-03-15 14:21:26 +0100 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2017-03-23 17:23:36 +0100 |
commit | 440797cba931aa491bf418035f55935943e22b4b (patch) | |
tree | 0ca0fb3263514a230896e1da17fcab7bb43b93d5 /src/sss_client | |
parent | c44728a02d5e2c9eaced11e74820a6ae6a985f61 (diff) | |
download | sssd-440797cba931aa491bf418035f55935943e22b4b.tar.gz sssd-440797cba931aa491bf418035f55935943e22b4b.tar.xz sssd-440797cba931aa491bf418035f55935943e22b4b.zip |
nss-idmap: add sss_nss_getlistbycert()
This patch adds a getlistbycert() call to libsss_nss_idmap to make it on
par with InfoPipe.
Related to https://pagure.io/SSSD/sssd/issue/3050
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Diffstat (limited to 'src/sss_client')
-rw-r--r-- | src/sss_client/idmap/sss_nss_idmap.c | 110 | ||||
-rw-r--r-- | src/sss_client/idmap/sss_nss_idmap.exports | 6 | ||||
-rw-r--r-- | src/sss_client/idmap/sss_nss_idmap.h | 17 | ||||
-rw-r--r-- | src/sss_client/sss_cli.h | 5 |
4 files changed, 135 insertions, 3 deletions
diff --git a/src/sss_client/idmap/sss_nss_idmap.c b/src/sss_client/idmap/sss_nss_idmap.c index fa5a499e3..6f3af267a 100644 --- a/src/sss_client/idmap/sss_nss_idmap.c +++ b/src/sss_client/idmap/sss_nss_idmap.c @@ -31,6 +31,7 @@ #include "util/strtonum.h" #define DATA_START (3 * sizeof(uint32_t)) +#define LIST_START (2 * sizeof(uint32_t)) union input { const char *str; uint32_t id; @@ -38,10 +39,12 @@ union input { struct output { enum sss_id_type type; + enum sss_id_type *types; union { char *str; uint32_t id; struct sss_nss_kv *kv_list; + char **names; } d; }; @@ -72,6 +75,63 @@ void sss_nss_free_kv(struct sss_nss_kv *kv_list) } } +void sss_nss_free_list(char **l) +{ + size_t c; + + if (l != NULL) { + for (c = 0; l[c] != NULL; c++) { + free(l[c]); + } + free(l); + } +} + +static int buf_to_name_type_list(uint8_t *buf, size_t buf_len, uint32_t num, + char ***names, enum sss_id_type **types) +{ + int ret; + size_t c; + char **n = NULL; + enum sss_id_type *t = NULL; + size_t rp = 0; + + n = calloc(num + 1, sizeof(char *)); + if (n == NULL) { + ret = ENOMEM; + goto done; + } + + t = calloc(num + 1, sizeof(enum sss_id_type)); + if (t == NULL) { + ret = ENOMEM; + goto done; + } + + for (c = 0; c < num; c++) { + SAFEALIGN_COPY_UINT32(&(t[c]), buf + rp, &rp); + n[c] = strdup((char *) buf + rp); + if (n[c] == NULL) { + ret = ENOMEM; + goto done; + } + rp += strlen(n[c]) + 1; + } + + ret = EOK; + +done: + if (ret != EOK) { + sss_nss_free_list(n); + free(t); + } else { + *names = n; + *types = t; + } + + return ret; +} + static int buf_to_kv_list(uint8_t *buf, size_t buf_len, struct sss_nss_kv **kv_list) { @@ -153,13 +213,14 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd , size_t data_len; uint32_t c; struct sss_nss_kv *kv_list; + char **names; + enum sss_id_type *types; switch (cmd) { case SSS_NSS_GETSIDBYNAME: case SSS_NSS_GETNAMEBYSID: case SSS_NSS_GETIDBYSID: case SSS_NSS_GETORIGBYNAME: - case SSS_NSS_GETNAMEBYCERT: ret = sss_strnlen(inp.str, 2048, &inp_len); if (ret != EOK) { return EINVAL; @@ -169,6 +230,17 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd , rd.data = inp.str; break; + case SSS_NSS_GETNAMEBYCERT: + case SSS_NSS_GETLISTBYCERT: + ret = sss_strnlen(inp.str, 10 * 1024 , &inp_len); + if (ret != EOK) { + return EINVAL; + } + + rd.len = inp_len + 1; + rd.data = inp.str; + + break; case SSS_NSS_GETSIDBYID: rd.len = sizeof(uint32_t); rd.data = &inp.id; @@ -195,7 +267,7 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd , if (num_results == 0) { ret = ENOENT; goto done; - } else if (num_results > 1) { + } else if (num_results > 1 && cmd != SSS_NSS_GETLISTBYCERT) { ret = EBADMSG; goto done; } @@ -237,6 +309,18 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd , out->d.id = c; break; + case SSS_NSS_GETLISTBYCERT: + ret = buf_to_name_type_list(repbuf + LIST_START, replen - LIST_START, + num_results, + &names, &types); + if (ret != EOK) { + goto done; + } + + out->types = types; + out->d.names = names; + + break; case SSS_NSS_GETORIGBYNAME: ret = buf_to_kv_list(repbuf + DATA_START, data_len, &kv_list); if (ret != EOK) { @@ -392,3 +476,25 @@ int sss_nss_getnamebycert(const char *cert, char **fq_name, return ret; } + +int sss_nss_getlistbycert(const char *cert, char ***fq_name, + enum sss_id_type **type) +{ + int ret; + union input inp; + struct output out; + + if (fq_name == NULL || cert == NULL || *cert == '\0') { + return EINVAL; + } + + inp.str = cert; + + ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETLISTBYCERT, &out); + if (ret == EOK) { + *fq_name = out.d.names; + *type = out.types; + } + + return ret; +} diff --git a/src/sss_client/idmap/sss_nss_idmap.exports b/src/sss_client/idmap/sss_nss_idmap.exports index bd5d80212..49dac6fc9 100644 --- a/src/sss_client/idmap/sss_nss_idmap.exports +++ b/src/sss_client/idmap/sss_nss_idmap.exports @@ -25,3 +25,9 @@ SSS_NSS_IDMAP_0.2.0 { global: sss_nss_getnamebycert; } SSS_NSS_IDMAP_0.1.0; + +SSS_NSS_IDMAP_0.3.0 { + # public functions + global: + sss_nss_getlistbycert; +} SSS_NSS_IDMAP_0.2.0; diff --git a/src/sss_client/idmap/sss_nss_idmap.h b/src/sss_client/idmap/sss_nss_idmap.h index 8a6299194..cbf19479f 100644 --- a/src/sss_client/idmap/sss_nss_idmap.h +++ b/src/sss_client/idmap/sss_nss_idmap.h @@ -130,7 +130,7 @@ int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list, * @param[in] cert base64 encoded certificate * @param[out] fq_name Fully qualified name of a user or a group, * must be freed by the caller - * @param[out] type Type of the object related to the SID + * @param[out] type Type of the object related to the cert * * @return * - see #sss_nss_getsidbyname @@ -139,6 +139,21 @@ int sss_nss_getnamebycert(const char *cert, char **fq_name, enum sss_id_type *type); /** + * @brief Return a list of fully qualified names for the given base64 encoded + * X.509 certificate in DER format + * + * @param[in] cert base64 encoded certificate + * @param[out] fq_name List of fully qualified name of users or groups, + * must be freed by the caller + * @param[out] type List of types of the objects related to the cert + * + * @return + * - see #sss_nss_getsidbyname + */ +int sss_nss_getlistbycert(const char *cert, char ***fq_name, + enum sss_id_type **type); + +/** * @brief Free key-value list returned by sss_nss_getorigbyname() * * @param[in] kv_list Key-value list returned by sss_nss_getorigbyname(). diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h index 8091e1151..59fee7a4e 100644 --- a/src/sss_client/sss_cli.h +++ b/src/sss_client/sss_cli.h @@ -260,6 +260,11 @@ SSS_NSS_GETNAMEBYCERT = 0x0116, /**< Takes the zero terminated string of a X509 certificate and returns the zero terminated fully qualified name of the related object. */ +SSS_NSS_GETLISTBYCERT = 0x0117, /**< Takes the zero terminated string + of the base64 encoded DER representation + of a X509 certificate and returns a list + of zero terminated fully qualified names + of the related objects. */ }; /** |