|
|
905b4d |
From 42cd56abee7c8403c585db2d85a0d32f141b05a6 Mon Sep 17 00:00:00 2001
|
|
|
905b4d |
From: Sumit Bose <sbose@redhat.com>
|
|
|
905b4d |
Date: Tue, 20 Jan 2015 12:48:19 +0100
|
|
|
905b4d |
Subject: [PATCH 170/172] nss: make fill_orig() multi-value aware
|
|
|
905b4d |
|
|
|
905b4d |
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
905b4d |
(cherry picked from commit 5f4d896ec8e06476f4282b562b1044de14c48ecf)
|
|
|
905b4d |
---
|
|
|
905b4d |
src/responder/nss/nsssrv_cmd.c | 86 ++++++++++++++++++++------
|
|
|
905b4d |
src/tests/cmocka/test_nss_srv.c | 131 +++++++++++++++++++++++++++++++++++++++-
|
|
|
905b4d |
2 files changed, 197 insertions(+), 20 deletions(-)
|
|
|
905b4d |
|
|
|
905b4d |
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
|
|
|
905b4d |
index c523dafc9455a07f3b0fd1f9db00bee551358a84..b49807e3e349942c0617253fdf45b4ad43ba2ee1 100644
|
|
|
905b4d |
--- a/src/responder/nss/nsssrv_cmd.c
|
|
|
905b4d |
+++ b/src/responder/nss/nsssrv_cmd.c
|
|
|
905b4d |
@@ -4612,13 +4612,14 @@ static errno_t fill_orig(struct sss_packet *packet,
|
|
|
905b4d |
{
|
|
|
905b4d |
int ret;
|
|
|
905b4d |
TALLOC_CTX *tmp_ctx;
|
|
|
905b4d |
- const char *tmp_str;
|
|
|
905b4d |
uint8_t *body;
|
|
|
905b4d |
size_t blen;
|
|
|
905b4d |
size_t pctr = 0;
|
|
|
905b4d |
size_t c;
|
|
|
905b4d |
+ size_t d;
|
|
|
905b4d |
size_t sum;
|
|
|
905b4d |
size_t found;
|
|
|
905b4d |
+ size_t array_size;
|
|
|
905b4d |
size_t extra_attrs_count = 0;
|
|
|
905b4d |
const char **extra_attrs_list = NULL;
|
|
|
905b4d |
const char *orig_attr_list[] = {SYSDB_SID_STR,
|
|
|
905b4d |
@@ -4637,6 +4638,8 @@ static errno_t fill_orig(struct sss_packet *packet,
|
|
|
905b4d |
struct sized_string *keys;
|
|
|
905b4d |
struct sized_string *vals;
|
|
|
905b4d |
struct nss_ctx *nctx;
|
|
|
905b4d |
+ struct ldb_message_element *el;
|
|
|
905b4d |
+ struct ldb_val *val;
|
|
|
905b4d |
|
|
|
905b4d |
tmp_ctx = talloc_new(NULL);
|
|
|
905b4d |
if (tmp_ctx == NULL) {
|
|
|
905b4d |
@@ -4652,10 +4655,9 @@ static errno_t fill_orig(struct sss_packet *packet,
|
|
|
905b4d |
extra_attrs_count++);
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
- keys = talloc_array(tmp_ctx, struct sized_string,
|
|
|
905b4d |
- sizeof(orig_attr_list) + extra_attrs_count);
|
|
|
905b4d |
- vals = talloc_array(tmp_ctx, struct sized_string,
|
|
|
905b4d |
- sizeof(orig_attr_list) + extra_attrs_count);
|
|
|
905b4d |
+ array_size = sizeof(orig_attr_list) + extra_attrs_count;
|
|
|
905b4d |
+ keys = talloc_array(tmp_ctx, struct sized_string, array_size);
|
|
|
905b4d |
+ vals = talloc_array(tmp_ctx, struct sized_string, array_size);
|
|
|
905b4d |
if (keys == NULL || vals == NULL) {
|
|
|
905b4d |
DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n");
|
|
|
905b4d |
ret = ENOMEM;
|
|
|
905b4d |
@@ -4665,26 +4667,72 @@ static errno_t fill_orig(struct sss_packet *packet,
|
|
|
905b4d |
sum = 0;
|
|
|
905b4d |
found = 0;
|
|
|
905b4d |
for (c = 0; orig_attr_list[c] != NULL; c++) {
|
|
|
905b4d |
- tmp_str = ldb_msg_find_attr_as_string(msg, orig_attr_list[c], NULL);
|
|
|
905b4d |
- if (tmp_str != NULL) {
|
|
|
905b4d |
- to_sized_string(&keys[found], orig_attr_list[c]);
|
|
|
905b4d |
- sum += keys[found].len;
|
|
|
905b4d |
- to_sized_string(&vals[found], tmp_str);
|
|
|
905b4d |
- sum += vals[found].len;
|
|
|
905b4d |
+ el = ldb_msg_find_element(msg, orig_attr_list[c]);
|
|
|
905b4d |
+ if (el != NULL && el->num_values > 0) {
|
|
|
905b4d |
+ if (el->num_values > 1) {
|
|
|
905b4d |
+ array_size += el->num_values;
|
|
|
905b4d |
+ keys = talloc_realloc(tmp_ctx, keys, struct sized_string,
|
|
|
905b4d |
+ array_size);
|
|
|
905b4d |
+ vals = talloc_realloc(tmp_ctx, vals, struct sized_string,
|
|
|
905b4d |
+ array_size);
|
|
|
905b4d |
+ if (keys == NULL || vals == NULL) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n");
|
|
|
905b4d |
+ ret = ENOMEM;
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ for (d = 0; d < el->num_values; d++) {
|
|
|
905b4d |
+ to_sized_string(&keys[found], orig_attr_list[c]);
|
|
|
905b4d |
+ sum += keys[found].len;
|
|
|
905b4d |
+ val = &(el->values[d]);
|
|
|
905b4d |
+ if (val == NULL || val->data == NULL
|
|
|
905b4d |
+ || val->data[val->length] != '\0') {
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
+ "Unexpected attribute value found for [%s].\n",
|
|
|
905b4d |
+ orig_attr_list[c]);
|
|
|
905b4d |
+ ret = EINVAL;
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ to_sized_string(&vals[found], (const char *)val->data);
|
|
|
905b4d |
+ sum += vals[found].len;
|
|
|
905b4d |
|
|
|
905b4d |
- found++;
|
|
|
905b4d |
+ found++;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
}
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
for (c = 0; c < extra_attrs_count; c++) {
|
|
|
905b4d |
- tmp_str = ldb_msg_find_attr_as_string(msg, extra_attrs_list[c], NULL);
|
|
|
905b4d |
- if (tmp_str != NULL) {
|
|
|
905b4d |
- to_sized_string(&keys[found], extra_attrs_list[c]);
|
|
|
905b4d |
- sum += keys[found].len;
|
|
|
905b4d |
- to_sized_string(&vals[found], tmp_str);
|
|
|
905b4d |
- sum += vals[found].len;
|
|
|
905b4d |
+ el = ldb_msg_find_element(msg, extra_attrs_list[c]);
|
|
|
905b4d |
+ if (el != NULL && el->num_values > 0) {
|
|
|
905b4d |
+ if (el->num_values > 1) {
|
|
|
905b4d |
+ array_size += el->num_values;
|
|
|
905b4d |
+ keys = talloc_realloc(tmp_ctx, keys, struct sized_string,
|
|
|
905b4d |
+ array_size);
|
|
|
905b4d |
+ vals = talloc_realloc(tmp_ctx, vals, struct sized_string,
|
|
|
905b4d |
+ array_size);
|
|
|
905b4d |
+ if (keys == NULL || vals == NULL) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n");
|
|
|
905b4d |
+ ret = ENOMEM;
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ for (d = 0; d < el->num_values; d++) {
|
|
|
905b4d |
+ to_sized_string(&keys[found], extra_attrs_list[c]);
|
|
|
905b4d |
+ sum += keys[found].len;
|
|
|
905b4d |
+ val = &(el->values[d]);
|
|
|
905b4d |
+ if (val == NULL || val->data == NULL
|
|
|
905b4d |
+ || val->data[val->length] != '\0') {
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
+ "Unexpected attribute value found for [%s].\n",
|
|
|
905b4d |
+ orig_attr_list[c]);
|
|
|
905b4d |
+ ret = EINVAL;
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ to_sized_string(&vals[found], (const char *)val->data);
|
|
|
905b4d |
+ sum += vals[found].len;
|
|
|
905b4d |
|
|
|
905b4d |
- found++;
|
|
|
905b4d |
+ found++;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
}
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c
|
|
|
905b4d |
index c318d94be867bbb9991de288cdae45d2ddc29b24..d7825e4384a4cc91407ed4bc66a1e190d558369f 100644
|
|
|
905b4d |
--- a/src/tests/cmocka/test_nss_srv.c
|
|
|
905b4d |
+++ b/src/tests/cmocka/test_nss_srv.c
|
|
|
905b4d |
@@ -52,7 +52,8 @@ struct nss_test_ctx {
|
|
|
905b4d |
bool ncache_hit;
|
|
|
905b4d |
};
|
|
|
905b4d |
|
|
|
905b4d |
-const char *global_extra_attrs[] = {"phone", "mobile", NULL};
|
|
|
905b4d |
+const char *global_extra_attrs[] = {"phone", "mobile", SYSDB_ORIG_MEMBEROF,
|
|
|
905b4d |
+ NULL};
|
|
|
905b4d |
|
|
|
905b4d |
struct nss_test_ctx *nss_test_ctx;
|
|
|
905b4d |
|
|
|
905b4d |
@@ -1946,6 +1947,132 @@ void test_nss_getorigbyname_extra_attrs(void **state)
|
|
|
905b4d |
assert_int_equal(ret, EOK);
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
+
|
|
|
905b4d |
+static int test_nss_getorigbyname_multi_check(uint32_t status, uint8_t *body,
|
|
|
905b4d |
+ size_t blen)
|
|
|
905b4d |
+{
|
|
|
905b4d |
+ const char *s;
|
|
|
905b4d |
+ enum sss_id_type id_type;
|
|
|
905b4d |
+ size_t rp = 2 * sizeof(uint32_t);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ assert_int_equal(status, EOK);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ SAFEALIGN_COPY_UINT32(&id_type, body+rp, &rp);
|
|
|
905b4d |
+ assert_int_equal(id_type, SSS_ID_TYPE_UID);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ /* Sequence of null terminated strings */
|
|
|
905b4d |
+ s = (char *) body+rp;
|
|
|
905b4d |
+ assert_string_equal(s, SYSDB_SID_STR);
|
|
|
905b4d |
+ rp += strlen(s) + 1;
|
|
|
905b4d |
+ assert_true(rp < blen);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ s = (char *) body+rp;
|
|
|
905b4d |
+ assert_string_equal(s, "S-1-2-3-4");
|
|
|
905b4d |
+ rp += strlen(s) + 1;
|
|
|
905b4d |
+ assert_true(rp < blen);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ s = (char *) body+rp;
|
|
|
905b4d |
+ assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_NAME);
|
|
|
905b4d |
+ rp += strlen(s) + 1;
|
|
|
905b4d |
+ assert_true(rp < blen);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ s = (char *) body+rp;
|
|
|
905b4d |
+ assert_string_equal(s, "orig_name");
|
|
|
905b4d |
+ rp += strlen(s) + 1;
|
|
|
905b4d |
+ assert_true(rp < blen);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ s = (char *) body+rp;
|
|
|
905b4d |
+ assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_UIDNUM);
|
|
|
905b4d |
+ rp += strlen(s) + 1;
|
|
|
905b4d |
+ assert_true(rp < blen);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ s = (char *) body+rp;
|
|
|
905b4d |
+ assert_string_equal(s, "1234");
|
|
|
905b4d |
+ rp += strlen(s) + 1;
|
|
|
905b4d |
+ assert_true(rp < blen);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ s = (char *) body+rp;
|
|
|
905b4d |
+ assert_string_equal(s, SYSDB_ORIG_MEMBEROF);
|
|
|
905b4d |
+ rp += strlen(s) + 1;
|
|
|
905b4d |
+ assert_true(rp < blen);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ s = (char *) body+rp;
|
|
|
905b4d |
+ assert_string_equal(s, "cn=abc");
|
|
|
905b4d |
+ rp += strlen(s) + 1;
|
|
|
905b4d |
+ assert_true(rp < blen);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ s = (char *) body+rp;
|
|
|
905b4d |
+ assert_string_equal(s, SYSDB_ORIG_MEMBEROF);
|
|
|
905b4d |
+ rp += strlen(s) + 1;
|
|
|
905b4d |
+ assert_true(rp < blen);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ s = (char *) body+rp;
|
|
|
905b4d |
+ assert_string_equal(s, "cn=def");
|
|
|
905b4d |
+ rp += strlen(s) + 1;
|
|
|
905b4d |
+ assert_true(rp < blen);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ s = (char *) body+rp;
|
|
|
905b4d |
+ assert_string_equal(s, SYSDB_ORIG_MEMBEROF);
|
|
|
905b4d |
+ rp += strlen(s) + 1;
|
|
|
905b4d |
+ assert_true(rp < blen);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ s = (char *) body+rp;
|
|
|
905b4d |
+ assert_string_equal(s, "cn=123");
|
|
|
905b4d |
+ rp += strlen(s) + 1;
|
|
|
905b4d |
+ assert_int_equal(rp, blen);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ return EOK;
|
|
|
905b4d |
+}
|
|
|
905b4d |
+void test_nss_getorigbyname_multi_value_attrs(void **state)
|
|
|
905b4d |
+{
|
|
|
905b4d |
+ errno_t ret;
|
|
|
905b4d |
+ struct sysdb_attrs *attrs;
|
|
|
905b4d |
+
|
|
|
905b4d |
+ attrs = sysdb_new_attrs(nss_test_ctx);
|
|
|
905b4d |
+ assert_non_null(attrs);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, "S-1-2-3-4");
|
|
|
905b4d |
+ assert_int_equal(ret, EOK);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ ret = sysdb_attrs_add_string(attrs, ORIGINALAD_PREFIX SYSDB_NAME,
|
|
|
905b4d |
+ "orig_name");
|
|
|
905b4d |
+ assert_int_equal(ret, EOK);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ ret = sysdb_attrs_add_uint32(attrs, ORIGINALAD_PREFIX SYSDB_UIDNUM, 1234);
|
|
|
905b4d |
+ assert_int_equal(ret, EOK);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_MEMBEROF, "cn=abc");
|
|
|
905b4d |
+ assert_int_equal(ret, EOK);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_MEMBEROF, "cn=def");
|
|
|
905b4d |
+ assert_int_equal(ret, EOK);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_MEMBEROF, "cn=123");
|
|
|
905b4d |
+ assert_int_equal(ret, EOK);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ /* Prime the cache with a valid user */
|
|
|
905b4d |
+ ret = sysdb_add_user(nss_test_ctx->tctx->dom,
|
|
|
905b4d |
+ "testuserorigmulti", 3456, 7890,
|
|
|
905b4d |
+ "test user orig multi value",
|
|
|
905b4d |
+ "/home/testuserorigextra", "/bin/sh", NULL,
|
|
|
905b4d |
+ attrs, 300, 0);
|
|
|
905b4d |
+ assert_int_equal(ret, EOK);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ mock_input_user_or_group("testuserorigmulti");
|
|
|
905b4d |
+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETORIGBYNAME);
|
|
|
905b4d |
+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ /* Query for that user, call a callback when command finishes */
|
|
|
905b4d |
+ set_cmd_cb(test_nss_getorigbyname_multi_check);
|
|
|
905b4d |
+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETORIGBYNAME,
|
|
|
905b4d |
+ nss_test_ctx->nss_cmds);
|
|
|
905b4d |
+ assert_int_equal(ret, EOK);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ /* Wait until the test finishes with EOK */
|
|
|
905b4d |
+ ret = test_ev_loop(nss_test_ctx->tctx);
|
|
|
905b4d |
+ assert_int_equal(ret, EOK);
|
|
|
905b4d |
+}
|
|
|
905b4d |
+
|
|
|
905b4d |
void nss_test_setup(void **state)
|
|
|
905b4d |
{
|
|
|
905b4d |
struct sss_test_conf_param params[] = {
|
|
|
905b4d |
@@ -2096,6 +2223,8 @@ int main(int argc, const char *argv[])
|
|
|
905b4d |
nss_test_setup, nss_test_teardown),
|
|
|
905b4d |
unit_test_setup_teardown(test_nss_getorigbyname_extra_attrs,
|
|
|
905b4d |
nss_test_setup_extra_attr, nss_test_teardown),
|
|
|
905b4d |
+ unit_test_setup_teardown(test_nss_getorigbyname_multi_value_attrs,
|
|
|
905b4d |
+ nss_test_setup_extra_attr, nss_test_teardown),
|
|
|
905b4d |
};
|
|
|
905b4d |
|
|
|
905b4d |
/* Set debug level to invalid value so we can deside if -d 0 was used. */
|
|
|
905b4d |
--
|
|
|
905b4d |
2.1.0
|
|
|
905b4d |
|