From a12e6ac8001025174cf201bcaa2143edb1b0c017 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Thu, 2 Nov 2017 10:32:41 +0100 Subject: [PATCH 30/31] nss-idmap: add timeout version of old sss_nss_* calls Reviewed-by: Jakub Hrozek (cherry picked from commit e54db68cbb9c12d8a6867f2c7766fb2115ab0997) --- Makefile.am | 2 +- src/sss_client/idmap/sss_nss_idmap.c | 126 ++++++++++++++++++-------- src/sss_client/idmap/sss_nss_idmap.exports | 7 ++ src/sss_client/idmap/sss_nss_idmap.h | 124 +++++++++++++++++++++++++ src/sss_client/idmap/sss_nss_idmap.unit_tests | 2 +- src/tests/cmocka/sss_nss_idmap-tests.c | 13 +-- 6 files changed, 229 insertions(+), 45 deletions(-) diff --git a/Makefile.am b/Makefile.am index dd25d1f7ea1be66388aa1b393bac290c4d7501a2..286ba47e3c421864362717be5258de960efca9f2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2974,7 +2974,6 @@ test_sysdb_domain_resolution_order_LDADD = \ test_wbc_calls_SOURCES = \ src/tests/cmocka/test_wbc_calls.c \ - src/sss_client/idmap/sss_nss_idmap.c \ src/sss_client/libwbclient/wbc_sid_sssd.c \ src/sss_client/libwbclient/wbclient_common.c \ src/sss_client/libwbclient/wbc_sid_common.c \ @@ -2993,6 +2992,7 @@ test_wbc_calls_LDADD = \ $(TALLOC_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ libsss_test_common.la \ + libsss_nss_idmap.la \ $(NULL) test_be_ptask_SOURCES = \ diff --git a/src/sss_client/idmap/sss_nss_idmap.c b/src/sss_client/idmap/sss_nss_idmap.c index 6f3af267a1e763e7dce77e3862be377ae2bfe984..6e7685d2b1d80956b6a6668e9bbb146abd9e86ed 100644 --- a/src/sss_client/idmap/sss_nss_idmap.c +++ b/src/sss_client/idmap/sss_nss_idmap.c @@ -28,10 +28,13 @@ #include "sss_client/sss_cli.h" #include "sss_client/idmap/sss_nss_idmap.h" +#include "sss_client/idmap/sss_nss_idmap_private.h" #include "util/strtonum.h" #define DATA_START (3 * sizeof(uint32_t)) #define LIST_START (2 * sizeof(uint32_t)) +#define NO_TIMEOUT ((unsigned int) -1) + union input { const char *str; uint32_t id; @@ -198,8 +201,8 @@ done: return ret; } -static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd , - struct output *out) +static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd, + unsigned int timeout, struct output *out) { int ret; size_t inp_len; @@ -215,6 +218,7 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd , struct sss_nss_kv *kv_list; char **names; enum sss_id_type *types; + int time_left = SSS_CLI_SOCKET_TIMEOUT; switch (cmd) { case SSS_NSS_GETSIDBYNAME: @@ -250,9 +254,14 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd , return EINVAL; } - sss_nss_lock(); + if (timeout == NO_TIMEOUT) { + sss_nss_lock(); + } else { + sss_nss_timedlock(timeout, &time_left); + } - nret = sss_nss_make_request(cmd, &rd, &repbuf, &replen, &errnop); + nret = sss_nss_make_request_timeout(cmd, &rd, time_left, &repbuf, &replen, + &errnop); if (nret != NSS_STATUS_SUCCESS) { ret = nss_status_to_errno(nret); goto done; @@ -347,8 +356,8 @@ done: return ret; } -int sss_nss_getsidbyname(const char *fq_name, char **sid, - enum sss_id_type *type) +int sss_nss_getsidbyname_timeout(const char *fq_name, unsigned int timeout, + char **sid, enum sss_id_type *type) { int ret; union input inp; @@ -360,7 +369,7 @@ int sss_nss_getsidbyname(const char *fq_name, char **sid, inp.str = fq_name; - ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYNAME, &out); + ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYNAME, timeout, &out); if (ret == EOK) { *sid = out.d.str; *type = out.type; @@ -369,7 +378,14 @@ int sss_nss_getsidbyname(const char *fq_name, char **sid, return ret; } -int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type) +int sss_nss_getsidbyname(const char *fq_name, char **sid, + enum sss_id_type *type) +{ + return sss_nss_getsidbyname_timeout(fq_name, NO_TIMEOUT, sid, type); +} + +int sss_nss_getsidbyid_timeout(uint32_t id, unsigned int timeout, + char **sid, enum sss_id_type *type) { int ret; union input inp; @@ -381,7 +397,7 @@ int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type) inp.id = id; - ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYID, &out); + ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYID, timeout, &out); if (ret == EOK) { *sid = out.d.str; *type = out.type; @@ -390,8 +406,13 @@ int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type) return ret; } -int sss_nss_getnamebysid(const char *sid, char **fq_name, - enum sss_id_type *type) +int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type) +{ + return sss_nss_getsidbyid_timeout(id, NO_TIMEOUT, sid, type); +} + +int sss_nss_getnamebysid_timeout(const char *sid, unsigned int timeout, + char **fq_name, enum sss_id_type *type) { int ret; union input inp; @@ -403,7 +424,7 @@ int sss_nss_getnamebysid(const char *sid, char **fq_name, inp.str = sid; - ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYSID, &out); + ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYSID, timeout, &out); if (ret == EOK) { *fq_name = out.d.str; *type = out.type; @@ -412,7 +433,14 @@ int sss_nss_getnamebysid(const char *sid, char **fq_name, return ret; } -int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type) +int sss_nss_getnamebysid(const char *sid, char **fq_name, + enum sss_id_type *type) +{ + return sss_nss_getnamebysid_timeout(sid, NO_TIMEOUT, fq_name, type); +} + +int sss_nss_getidbysid_timeout(const char *sid, unsigned int timeout, + uint32_t *id, enum sss_id_type *id_type) { int ret; union input inp; @@ -424,7 +452,7 @@ int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type) inp.str = sid; - ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETIDBYSID, &out); + ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETIDBYSID, timeout, &out); if (ret == EOK) { *id = out.d.id; *id_type = out.type; @@ -433,8 +461,14 @@ int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type) return ret; } -int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list, - enum sss_id_type *type) +int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type) +{ + return sss_nss_getidbysid_timeout(sid, NO_TIMEOUT, id, id_type); +} + +int sss_nss_getorigbyname_timeout(const char *fq_name, unsigned int timeout, + struct sss_nss_kv **kv_list, + enum sss_id_type *type) { int ret; union input inp; @@ -446,7 +480,7 @@ int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list, inp.str = fq_name; - ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETORIGBYNAME, &out); + ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETORIGBYNAME, timeout, &out); if (ret == EOK) { *kv_list = out.d.kv_list; *type = out.type; @@ -455,30 +489,42 @@ int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list, return ret; } +int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list, + enum sss_id_type *type) +{ + return sss_nss_getorigbyname_timeout(fq_name, NO_TIMEOUT, kv_list, type); +} + +int sss_nss_getnamebycert_timeout(const char *cert, unsigned int timeout, + 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_GETNAMEBYCERT, timeout, &out); + if (ret == EOK) { + *fq_name = out.d.str; + *type = out.type; + } + + return ret; +} + int sss_nss_getnamebycert(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_GETNAMEBYCERT, &out); - if (ret == EOK) { - *fq_name = out.d.str; - *type = out.type; - } - - return ret; + return sss_nss_getnamebycert_timeout(cert, NO_TIMEOUT, fq_name, type); } -int sss_nss_getlistbycert(const char *cert, char ***fq_name, - enum sss_id_type **type) +int sss_nss_getlistbycert_timeout(const char *cert, unsigned int timeout, + char ***fq_name, enum sss_id_type **type) { int ret; union input inp; @@ -490,7 +536,7 @@ int sss_nss_getlistbycert(const char *cert, char ***fq_name, inp.str = cert; - ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETLISTBYCERT, &out); + ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETLISTBYCERT, timeout, &out); if (ret == EOK) { *fq_name = out.d.names; *type = out.types; @@ -498,3 +544,9 @@ int sss_nss_getlistbycert(const char *cert, char ***fq_name, return ret; } + +int sss_nss_getlistbycert(const char *cert, char ***fq_name, + enum sss_id_type **type) +{ + return sss_nss_getlistbycert_timeout(cert, NO_TIMEOUT, fq_name, type); +} diff --git a/src/sss_client/idmap/sss_nss_idmap.exports b/src/sss_client/idmap/sss_nss_idmap.exports index 788d05ecc3bd56fa88e68a98b9c8096cf7140a09..8d0a24f42aa3fb3dd9c2ed125bf79e2c7792993f 100644 --- a/src/sss_client/idmap/sss_nss_idmap.exports +++ b/src/sss_client/idmap/sss_nss_idmap.exports @@ -40,4 +40,11 @@ SSS_NSS_IDMAP_0.4.0 { sss_nss_getgrnam_timeout; sss_nss_getgrgid_timeout; sss_nss_getgrouplist_timeout; + sss_nss_getsidbyname_timeout; + sss_nss_getsidbyid_timeout; + sss_nss_getnamebysid_timeout; + sss_nss_getidbysid_timeout; + sss_nss_getorigbyname_timeout; + sss_nss_getnamebycert_timeout; + sss_nss_getlistbycert_timeout; } SSS_NSS_IDMAP_0.3.0; diff --git a/src/sss_client/idmap/sss_nss_idmap.h b/src/sss_client/idmap/sss_nss_idmap.h index 3755643312f05a31d1cf1aa76dfc22848ef1e3ec..125e72a6486f5916f90d37f27e1743d181bfa3e5 100644 --- a/src/sss_client/idmap/sss_nss_idmap.h +++ b/src/sss_client/idmap/sss_nss_idmap.h @@ -303,5 +303,129 @@ int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp, int sss_nss_getgrouplist_timeout(const char *name, gid_t group, gid_t *groups, int *ngroups, uint32_t flags, unsigned int timeout); +/** + * @brief Find SID by fully qualified name with timeout + * + * @param[in] fq_name Fully qualified name of a user or a group + * @param[in] timeout timeout in milliseconds + * @param[out] sid String representation of the SID of the requested user + * or group, must be freed by the caller + * @param[out] type Type of the object related to the given name + * + * @return + * - 0 (EOK): success, sid contains the requested SID + * - ENOENT: requested object was not found in the domain extracted from the given name + * - ENETUNREACH: SSSD does not know how to handle the domain extracted from the given name + * - ENOSYS: this call is not supported by the configured provider + * - EINVAL: input cannot be parsed + * - EIO: remote servers cannot be reached + * - EFAULT: any other error + * - ETIME: request timed out but was send to SSSD + * - ETIMEDOUT: request timed out but was not send to SSSD + */ +int sss_nss_getsidbyname_timeout(const char *fq_name, unsigned int timeout, + char **sid, enum sss_id_type *type); + +/** + * @brief Find SID by a POSIX UID or GID with timeout + * + * @param[in] id POSIX UID or GID + * @param[in] timeout timeout in milliseconds + * @param[out] sid String representation of the SID of the requested user + * or group, must be freed by the caller + * @param[out] type Type of the object related to the given ID + * + * @return + * - see #sss_nss_getsidbyname_timeout + */ +int sss_nss_getsidbyid_timeout(uint32_t id, unsigned int timeout, + char **sid, enum sss_id_type *type); + +/** + * @brief Return the fully qualified name for the given SID with timeout + * + * @param[in] sid String representation of the SID + * @param[in] timeout timeout in milliseconds + * @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 + * + * @return + * - see #sss_nss_getsidbyname_timeout + */ +int sss_nss_getnamebysid_timeout(const char *sid, unsigned int timeout, + char **fq_name, enum sss_id_type *type); + +/** + * @brief Return the POSIX ID for the given SID with timeout + * + * @param[in] sid String representation of the SID + * @param[in] timeout timeout in milliseconds + * @param[out] id POSIX ID related to the SID + * @param[out] id_type Type of the object related to the SID + * + * @return + * - see #sss_nss_getsidbyname_timeout + */ +int sss_nss_getidbysid_timeout(const char *sid, unsigned int timeout, + uint32_t *id, enum sss_id_type *id_type); + +/** + * @brief Find original data by fully qualified name with timeout + * + * @param[in] fq_name Fully qualified name of a user or a group + * @param[in] timeout timeout in milliseconds + * @param[out] kv_list A NULL terminate list of key-value pairs where the key + * is the attribute name in the cache of SSSD, + * must be freed by the caller with sss_nss_free_kv() + * @param[out] type Type of the object related to the given name + * + * @return + * - 0 (EOK): success, sid contains the requested SID + * - ENOENT: requested object was not found in the domain extracted from the given name + * - ENETUNREACH: SSSD does not know how to handle the domain extracted from the given name + * - ENOSYS: this call is not supported by the configured provider + * - EINVAL: input cannot be parsed + * - EIO: remote servers cannot be reached + * - EFAULT: any other error + * - ETIME: request timed out but was send to SSSD + * - ETIMEDOUT: request timed out but was not send to SSSD + */ +int sss_nss_getorigbyname_timeout(const char *fq_name, unsigned int timeout, + struct sss_nss_kv **kv_list, + enum sss_id_type *type); + +/** + * @brief Return the fully qualified name for the given base64 encoded + * X.509 certificate in DER format with timeout + * + * @param[in] cert base64 encoded certificate + * @param[in] timeout timeout in milliseconds + * @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 cert + * + * @return + * - see #sss_nss_getsidbyname_timeout + */ +int sss_nss_getnamebycert_timeout(const char *cert, unsigned int timeout, + 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 with timeout + * + * @param[in] cert base64 encoded certificate + * @param[in] timeout timeout in milliseconds + * @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_timeout + */ +int sss_nss_getlistbycert_timeout(const char *cert, unsigned int timeout, + char ***fq_name, enum sss_id_type **type); + #endif /* IPA_389DS_PLUGIN_HELPER_CALLS */ #endif /* SSS_NSS_IDMAP_H_ */ diff --git a/src/sss_client/idmap/sss_nss_idmap.unit_tests b/src/sss_client/idmap/sss_nss_idmap.unit_tests index 361cc3b134ead52cf458afe27c055739d6728441..05c474f008e1d59aae5976acfd81613c3c3e6540 100644 --- a/src/sss_client/idmap/sss_nss_idmap.unit_tests +++ b/src/sss_client/idmap/sss_nss_idmap.unit_tests @@ -2,5 +2,5 @@ UNIT_TEST_ONLY { # should not be part of installed library global: - sss_nss_make_request; + sss_nss_make_request_timeout; }; diff --git a/src/tests/cmocka/sss_nss_idmap-tests.c b/src/tests/cmocka/sss_nss_idmap-tests.c index 8807eca619d7b07d919168e5629042cf38f654ac..2e37040d2d3523bea157804706685fa0b36df16a 100644 --- a/src/tests/cmocka/sss_nss_idmap-tests.c +++ b/src/tests/cmocka/sss_nss_idmap-tests.c @@ -61,10 +61,11 @@ uint8_t buf_orig1[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0 #error "unknow endianess" #endif -enum nss_status sss_nss_make_request(enum sss_cli_command cmd, - struct sss_cli_req_data *rd, - uint8_t **repbuf, size_t *replen, - int *errnop) +enum nss_status sss_nss_make_request_timeout(enum sss_cli_command cmd, + struct sss_cli_req_data *rd, + int timeout, + uint8_t **repbuf, size_t *replen, + int *errnop) { struct sss_nss_make_request_test_data *d; @@ -114,7 +115,7 @@ void test_getsidbyname(void **state) sid = NULL; for (c = 0; d[c].d.repbuf != NULL; c++) { - will_return(sss_nss_make_request, &d[0].d); + will_return(sss_nss_make_request_timeout, &d[0].d); ret = sss_nss_getsidbyname("test", &sid, &type); assert_int_equal(ret, d[0].ret); @@ -134,7 +135,7 @@ void test_getorigbyname(void **state) enum sss_id_type type; struct sss_nss_make_request_test_data d = {buf_orig1, sizeof(buf_orig1), 0, NSS_STATUS_SUCCESS}; - will_return(sss_nss_make_request, &d); + will_return(sss_nss_make_request_timeout, &d); ret = sss_nss_getorigbyname("test", &kv_list, &type); assert_int_equal(ret, EOK); assert_int_equal(type, SSS_ID_TYPE_UID); -- 2.13.6