Resolves: rhbz#1310664 - [RFE] IPA: resolve external group memberships of IPA

groups during getgrnam and getgrgid
- Resolves: rhbz#1301303 - sss_obfuscate: SyntaxError: Missing parentheses
                           in call to 'print'
This commit is contained in:
Lukas Slebodnik 2016-02-25 13:58:00 +01:00
parent 00dde99057
commit e32d50862e
32 changed files with 4543 additions and 1 deletions

View File

@ -0,0 +1,108 @@
From 931a3a8fe35897552da09d6c0ca90b373538c094 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Mon, 18 Jan 2016 22:02:55 +0100
Subject: [PATCH 51/86] NSS: do not skip cache check for netgoups
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When refresh_expired_interval was not zero,
the NSS responder only refreshed netgroup cache
using background periodic task and ignored
SYSDB_CACHE_EXPIRE attribute.
With this behaviour it was impossible to
get new netgroup from remote server even
after sss_cache tool was used to expire
existing entry in the cache.
Resolves:
https://fedorahosted.org/sssd/ticket/2912
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 1b8858b1611db5048592f477059ca5ad66d7ceb1)
(cherry picked from commit 66c6bf86da1241c3253d23aa7e68850d6ec14d15)
---
src/responder/nss/nsssrv_cmd.c | 47 +++++++++++++++++++++---------------------
1 file changed, 23 insertions(+), 24 deletions(-)
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index b8bd6425e2c937ce6008fd6663fe0312ad68f01e..c6f8284571be382dad5dfda651a25e4df6a14cb1 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -579,10 +579,9 @@ static int nss_cmd_getpw_send_reply(struct nss_dom_ctx *dctx, bool filter)
return EOK;
}
-/* Currently only refreshing expired netgroups is supported. */
static bool
is_refreshed_on_bg(enum sss_dp_acct_type req_type,
- enum sss_dp_acct_type refresh_expired_interval)
+ uint32_t refresh_expired_interval)
{
if (refresh_expired_interval == 0) {
return false;
@@ -590,6 +589,8 @@ is_refreshed_on_bg(enum sss_dp_acct_type req_type,
switch (req_type) {
case SSS_DP_NETGR:
+ case SSS_DP_USER:
+ case SSS_DP_GROUP:
return true;
default:
return false;
@@ -753,31 +754,29 @@ errno_t check_cache(struct nss_dom_ctx *dctx,
get_dp_name_and_id(dctx->cmdctx, dctx->domain, req_type, opt_name, opt_id,
&name, &id);
- /* if we have any reply let's check cache validity, but ignore netgroups
- * if refresh_expired_interval is set (which implies that another method
- * is used to refresh netgroups)
- */
+ /* if we have any reply let's check cache validity */
if (res->count > 0) {
- if (is_refreshed_on_bg(req_type,
- dctx->domain->refresh_expired_interval)) {
- ret = EOK;
+ bool refreshed_on_bg;
+ uint32_t bg_refresh_interval = dctx->domain->refresh_expired_interval;
+
+ if (req_type == SSS_DP_INITGROUPS) {
+ cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
+ SYSDB_INITGR_EXPIRE,
+ 0);
} else {
- if (req_type == SSS_DP_INITGROUPS) {
- cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
- SYSDB_INITGR_EXPIRE,
- 0);
- } else {
- cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
- SYSDB_CACHE_EXPIRE,
- 0);
- }
-
- /* if we have any reply let's check cache validity */
- ret = sss_cmd_check_cache(res->msgs[0],
- nctx->cache_refresh_percent,
- cacheExpire);
+ cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
+ SYSDB_CACHE_EXPIRE,
+ 0);
}
- if (ret == EOK) {
+
+ /* Check if background refresh is enabled for this entry */
+ refreshed_on_bg = is_refreshed_on_bg(req_type, bg_refresh_interval);
+
+ /* if we have any reply let's check cache validity */
+ ret = sss_cmd_check_cache(res->msgs[0],
+ nctx->cache_refresh_percent,
+ cacheExpire);
+ if (ret == EOK || (ret == EAGAIN && refreshed_on_bg)) {
DEBUG(SSSDBG_TRACE_FUNC, "Cached entry is valid, returning..\n");
return EOK;
} else if (ret != EAGAIN && ret != ENOENT) {
--
2.5.0

View File

@ -0,0 +1,131 @@
From 4a3e2e2d6c6197cd40eec986f581e2a1abb9ef04 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 6 Jan 2016 12:08:18 +0100
Subject: [PATCH 52/86] cache_req: simplify cache_req_cache_check()
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 46f34279204c537a53a0fac7e3fd8022359bfa09)
(cherry picked from commit 97e764f55211c209f2f97debe27f65d0185f4f50)
---
src/responder/common/responder_cache_req.c | 79 ++++++++++++++++++------------
1 file changed, 48 insertions(+), 31 deletions(-)
diff --git a/src/responder/common/responder_cache_req.c b/src/responder/common/responder_cache_req.c
index 4ab52b8188859f1143ba1ffa3de03d14ecc028c2..3a436d8e560c36f36553ca6b92204cc47d58dc2e 100644
--- a/src/responder/common/responder_cache_req.c
+++ b/src/responder/common/responder_cache_req.c
@@ -568,6 +568,47 @@ static bool cache_req_bypass_cache(struct cache_req_input *input)
return false;
}
+static errno_t cache_req_expiration_status(struct cache_req_input *input,
+ struct ldb_result *result,
+ time_t cache_refresh_percent)
+{
+ time_t expire;
+
+ if (result == NULL || result->count == 0 || cache_req_bypass_cache(input)) {
+ return ENOENT;
+ }
+
+ if (input->type == CACHE_REQ_INITGROUPS) {
+ expire = ldb_msg_find_attr_as_uint64(result->msgs[0],
+ SYSDB_INITGR_EXPIRE, 0);
+ } else {
+ expire = ldb_msg_find_attr_as_uint64(result->msgs[0],
+ SYSDB_CACHE_EXPIRE, 0);
+ }
+
+ return sss_cmd_check_cache(result->msgs[0], cache_refresh_percent, expire);
+}
+
+static void cache_req_dpreq_params(struct cache_req_input *input,
+ const char **_string,
+ uint32_t *_id,
+ const char **_flag)
+{
+ *_id = input->id;
+ *_string = input->dom_objname;
+
+ if (input->type == CACHE_REQ_USER_BY_CERT) {
+ *_string = input->cert;
+ }
+
+ *_flag = NULL;
+ if (DOM_HAS_VIEWS(input->domain)) {
+ *_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
+ } else if (cache_req_input_is_upn(input)) {
+ *_flag = EXTRA_NAME_IS_UPN;
+ }
+}
+
struct cache_req_cache_state {
/* input data */
struct tevent_context *ev;
@@ -669,38 +710,16 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
struct cache_req_cache_state *state = NULL;
struct tevent_req *subreq = NULL;
const char *extra_flag = NULL;
- uint64_t cache_expire = 0;
- errno_t ret;
const char *search_str;
+ uint32_t search_id;
+ errno_t ret;
state = tevent_req_data(req, struct cache_req_cache_state);
- if (state->result == NULL || state->result->count == 0 ||
- cache_req_bypass_cache(state->input) == true) {
- ret = ENOENT;
- } else {
- if (state->input->type == CACHE_REQ_INITGROUPS) {
- cache_expire = ldb_msg_find_attr_as_uint64(state->result->msgs[0],
- SYSDB_INITGR_EXPIRE, 0);
- } else {
- cache_expire = ldb_msg_find_attr_as_uint64(state->result->msgs[0],
- SYSDB_CACHE_EXPIRE, 0);
- }
+ cache_req_dpreq_params(state->input, &search_str, &search_id, &extra_flag);
- ret = sss_cmd_check_cache(state->result->msgs[0],
- state->cache_refresh_percent, cache_expire);
- }
-
- search_str = state->input->dom_objname;
- if (state->input->type == CACHE_REQ_USER_BY_CERT) {
- search_str = state->input->cert;
- }
-
- if (DOM_HAS_VIEWS(state->input->domain)) {
- extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
- } else if (cache_req_input_is_upn(state->input)) {
- extra_flag = EXTRA_NAME_IS_UPN;
- }
+ ret = cache_req_expiration_status(state->input, state->result,
+ state->cache_refresh_percent);
switch (ret) {
case EOK:
@@ -715,8 +734,7 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
subreq = sss_dp_get_account_send(state, state->rctx,
state->input->domain, true,
state->input->dp_type,
- search_str,
- state->input->id, extra_flag);
+ search_str, search_id, extra_flag);
if (subreq == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending out-of-band "
"data provider request\n");
@@ -733,8 +751,7 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
subreq = sss_dp_get_account_send(state, state->rctx,
state->input->domain, true,
state->input->dp_type,
- search_str,
- state->input->id, extra_flag);
+ search_str, search_id, extra_flag);
if (subreq == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Out of memory sending data provider request\n");
--
2.5.0

View File

@ -0,0 +1,146 @@
From 6d3c0f1d269193c366945dcdaeff45dd139230cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 6 Jan 2016 12:45:38 +0100
Subject: [PATCH 53/86] cache_req: do not lookup views if possible
This is needed for LOCAL view but also creates a shortcut for
server side overrides.
Resolves:
https://fedorahosted.org/sssd/ticket/2849
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 5f2b1986a16a394ecbecd16f82c7265b5b47b546)
(cherry picked from commit f840cfd6c2ad61045160f301d6ae7276e3e33f54)
---
src/responder/common/responder_cache_req.c | 98 +++++++++++++++++++++++++++---
1 file changed, 88 insertions(+), 10 deletions(-)
diff --git a/src/responder/common/responder_cache_req.c b/src/responder/common/responder_cache_req.c
index 3a436d8e560c36f36553ca6b92204cc47d58dc2e..2344b0f09c6c4242ff3f769ae565f21c1d2b3e3b 100644
--- a/src/responder/common/responder_cache_req.c
+++ b/src/responder/common/responder_cache_req.c
@@ -589,24 +589,101 @@ static errno_t cache_req_expiration_status(struct cache_req_input *input,
return sss_cmd_check_cache(result->msgs[0], cache_refresh_percent, expire);
}
-static void cache_req_dpreq_params(struct cache_req_input *input,
+static void cache_req_dpreq_params(TALLOC_CTX *mem_ctx,
+ struct cache_req_input *input,
+ struct ldb_result *result,
const char **_string,
uint32_t *_id,
const char **_flag)
{
+ struct ldb_result *user = NULL;
+ const char *name = NULL;
+ uint32_t id = 0;
+ errno_t ret;
+
*_id = input->id;
*_string = input->dom_objname;
-
- if (input->type == CACHE_REQ_USER_BY_CERT) {
- *_string = input->cert;
- }
-
*_flag = NULL;
- if (DOM_HAS_VIEWS(input->domain)) {
- *_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
- } else if (cache_req_input_is_upn(input)) {
+
+ if (cache_req_input_is_upn(input)) {
*_flag = EXTRA_NAME_IS_UPN;
+ return;
}
+
+ if (input->type == CACHE_REQ_USER_BY_CERT) {
+ *_string = input->cert;
+ return;
+ }
+
+ if (!DOM_HAS_VIEWS(input->domain)) {
+ return;
+ }
+
+ /* We must search with views. */
+ if (result == NULL || result->count == 0) {
+ *_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
+ return;
+ }
+
+ /* If domain has views we will try to user original values instead of the
+ * overridden ones. This is a must for the LOCAL view since we can't look
+ * it up otherwise. But it is also a shortcut for non-local views where
+ * we will not fail over to the overridden value. */
+
+ switch (input->type) {
+ case CACHE_REQ_USER_BY_NAME:
+ case CACHE_REQ_GROUP_BY_NAME:
+ name = ldb_msg_find_attr_as_string(result->msgs[0], SYSDB_NAME, NULL);
+ if (name == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL\n");
+ }
+ break;
+ case CACHE_REQ_USER_BY_ID:
+ id = ldb_msg_find_attr_as_uint64(result->msgs[0], SYSDB_UIDNUM, 0);
+ if (id == 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Bug: id cannot be 0\n");
+ }
+ break;
+ case CACHE_REQ_GROUP_BY_ID:
+ id = ldb_msg_find_attr_as_uint64(result->msgs[0], SYSDB_GIDNUM, 0);
+ if (id == 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Bug: id cannot be 0\n");
+ }
+ break;
+ case CACHE_REQ_INITGROUPS:
+ ret = sysdb_getpwnam_with_views(NULL, input->domain,
+ input->dom_objname, &user);
+ if (ret != EOK || user == NULL || user->count != 1) {
+ /* Case where the user is not found has been already handled. If
+ * this is not OK, it is an error. */
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to match initgroups user "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ break;
+ }
+
+ name = ldb_msg_find_attr_as_string(user->msgs[0], SYSDB_NAME,
+ NULL);
+ if (name == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL\n");
+ break;
+ }
+
+ talloc_steal(mem_ctx, name);
+ talloc_free(user);
+ break;
+ default:
+ return;
+ }
+
+ /* Now we have the original name and id. We don't have to search with
+ * views unless some error occurred. */
+ if (name == NULL && id == 0) {
+ *_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
+ return;
+ }
+
+ *_string = talloc_steal(mem_ctx, name);
+ *_id = id;
}
struct cache_req_cache_state {
@@ -716,7 +793,8 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
state = tevent_req_data(req, struct cache_req_cache_state);
- cache_req_dpreq_params(state->input, &search_str, &search_id, &extra_flag);
+ cache_req_dpreq_params(state, state->input, state->result,
+ &search_str, &search_id, &extra_flag);
ret = cache_req_expiration_status(state->input, state->result,
state->cache_refresh_percent);
--
2.5.0

View File

@ -0,0 +1,54 @@
From 521ef4f7839216e19ad93420f0464ba969fead8b Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Fri, 22 Jan 2016 12:30:23 -0500
Subject: [PATCH 54/86] IDMAP: Fix minor memory leak
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit 5554a2a679f72f19f266d660a5681e3b0c657379)
(cherry picked from commit fe8d58c75da2b9b3704bb2ae19f8014323797757)
---
src/lib/idmap/sss_idmap.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/lib/idmap/sss_idmap.c b/src/lib/idmap/sss_idmap.c
index 269ef0132ff3b9ffbfbe65006361fac6d4f88cf9..e3e9972b802748770a5f7440fa8ddc8ba75d3362 100644
--- a/src/lib/idmap/sss_idmap.c
+++ b/src/lib/idmap/sss_idmap.c
@@ -607,13 +607,13 @@ get_helpers(struct sss_idmap_ctx *ctx,
for (int i = 0; i < ctx->idmap_opts.extra_slice_init; i++) {
secondary_name = generate_sec_slice_name(ctx, domain_sid, first_rid);
if (secondary_name == NULL) {
- return IDMAP_OUT_OF_MEMORY;
+ err = IDMAP_OUT_OF_MEMORY;
+ goto fail;
}
err = generate_slice(ctx, secondary_name, first_rid, &slice);
if (err != IDMAP_SUCCESS) {
- ctx->free_func(secondary_name, ctx->alloc_pvt);
- return err;
+ goto fail;
}
first_rid += ctx->idmap_opts.rangesize;
@@ -631,6 +631,14 @@ get_helpers(struct sss_idmap_ctx *ctx,
*_sec_slices = sec_slices;
return IDMAP_SUCCESS;
+
+fail:
+ ctx->free_func(secondary_name, ctx->alloc_pvt);
+
+ /* Free already generated helpers. */
+ free_helpers(ctx, sec_slices, true);
+
+ return err;
}
enum idmap_error_code sss_idmap_add_domain_ex(struct sss_idmap_ctx *ctx,
--
2.5.0

View File

@ -0,0 +1,30 @@
From 92281a16d6e8988dec661fe40eac6361b7bcfb4a Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 1 Feb 2016 09:34:08 +0100
Subject: [PATCH 55/86] CONFIGURE: Replace obsoleted macro AC_PROG_LIBTOOL
The AC_PROG_LIBTOOL macro is obsoleted since libtool 2.0
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 700d45751e997c634504a4f22facd2edf82edea7)
(cherry picked from commit dba300fe84fe40919a17a82bc4f4b9b672ed195d)
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 1ab64765968e9ffe94da9075496be2491bf33e9a..8ef2493c79a144d348200213f0ce1681d0fa3c1f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,7 +19,7 @@ AM_PROG_CC_C_O
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_DISABLE_STATIC
AC_PROG_INSTALL
-AC_PROG_LIBTOOL
+LT_INIT
m4_ifdef([AC_PROG_MKDIR_P],
[AC_PROG_MKDIR_P],
[AC_SUBST([MKDIR_P], "mkdir -p")])
--
2.5.0

View File

@ -0,0 +1,146 @@
From c53781ec735a14c346fa111749ac02030e550fb5 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 13 Jan 2016 15:06:06 +0100
Subject: [PATCH 56/86] TESTS: Fix race condition in python test
Python tests for pyhbac and pysss_murmur created symbolic
links in shared directory ".libs". It happened that both
tests created symbolic link in the same time and therefore
python2 test could try to import link to python3 module
which caused failures in tests.
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 9e1de5c83371d91e200254cceef70852f5f94fd2)
(cherry picked from commit 94bafaad2401bc647a31a22953ad2d985c88b06e)
---
src/tests/pyhbac-test.py | 33 ++++++++++++++++-----------------
src/tests/pysss_murmur-test.py | 33 ++++++++++++++++-----------------
2 files changed, 32 insertions(+), 34 deletions(-)
diff --git a/src/tests/pyhbac-test.py b/src/tests/pyhbac-test.py
index 9d8fd1a333bf54ecf21d14d3b6293f7294a0d53e..09867311ed42cad1e3b44e10616edb084716ce10 100755
--- a/src/tests/pyhbac-test.py
+++ b/src/tests/pyhbac-test.py
@@ -5,11 +5,12 @@ import unittest
import sys
import os
import copy
-import sys
-import errno
+import tempfile
+
+BUILD_DIR = os.getenv('builddir') or "."
+TEST_DIR = os.getenv('SSS_TEST_DIR') or "."
+MODPATH = tempfile.mkdtemp(prefix="tp_pyhbac_", dir=TEST_DIR)
-srcdir = os.getenv('builddir') or "."
-MODPATH = srcdir + "/.libs" #FIXME - is there a way to get this from libtool?
if sys.version_info[0] > 2:
unicode = str
@@ -40,22 +41,15 @@ class PyHbacImport(unittest.TestCase):
def testImport(self):
" Import the module and assert it comes from tree "
try:
- cwd_backup = os.getcwd()
+ dest_module_path = MODPATH + "/pyhbac.so"
- try:
- os.unlink(MODPATH + "/pyhbac.so")
- except OSError as e:
- if e.errno == errno.ENOENT:
- pass
- else:
- raise e
-
- os.chdir(MODPATH)
if sys.version_info[0] > 2:
- os.symlink("_py3hbac.so", "pyhbac.so")
+ src_module_path = BUILD_DIR + "/.libs/_py3hbac.so"
else:
- os.symlink("_py2hbac.so", "pyhbac.so")
- os.chdir(cwd_backup)
+ src_module_path = BUILD_DIR + "/.libs/_py2hbac.so"
+
+ src_module_path = os.path.abspath(src_module_path)
+ os.symlink(src_module_path, dest_module_path)
import pyhbac
except ImportError as e:
@@ -456,6 +450,11 @@ class PyHbacRequestTest(unittest.TestCase):
self.assertRaises(TypeError, req.evaluate, (allow_rule, None))
class PyHbacModuleTest(unittest.TestCase):
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(MODPATH + "/pyhbac.so")
+ os.rmdir(MODPATH)
+
def testHasResultTypes(self):
assert hasattr(pyhbac, "HBAC_EVAL_ALLOW")
assert hasattr(pyhbac, "HBAC_EVAL_DENY")
diff --git a/src/tests/pysss_murmur-test.py b/src/tests/pysss_murmur-test.py
index faa8bb2d33b9d94d380b8f7045ba45aa06ac4793..1cbbe4d03172804ef16b630d3dd1c3a22e09a20a 100755
--- a/src/tests/pysss_murmur-test.py
+++ b/src/tests/pysss_murmur-test.py
@@ -22,11 +22,12 @@ from __future__ import print_function
import unittest
import sys
import os
-import copy
-import errno
+import tempfile
+
+BUILD_DIR = os.getenv('builddir') or "."
+TEST_DIR = os.getenv('SSS_TEST_DIR') or "."
+MODPATH = tempfile.mkdtemp(prefix="tp_pysss_murmur_", dir=TEST_DIR)
-srcdir = os.getenv('builddir') or "."
-MODPATH = srcdir + "/.libs" #FIXME - is there a way to get this from libtool?
def compat_assertItemsEqual(this, expected_seq, actual_seq, msg=None):
return this.assertEqual(sorted(expected_seq), sorted(actual_seq))
@@ -56,22 +57,15 @@ class PySssMurmurImport(unittest.TestCase):
def testImport(self):
" Import the module and assert it comes from tree "
try:
- cwd_backup = os.getcwd()
+ dest_module_path = MODPATH + "/pysss_murmur.so"
- try:
- os.unlink(MODPATH + "/pysss_murmur.so")
- except OSError as e:
- if e.errno == errno.ENOENT:
- pass
- else:
- raise e
-
- os.chdir(MODPATH)
if sys.version_info[0] > 2:
- os.symlink("_py3sss_murmur.so", "pysss_murmur.so")
+ src_module_path = BUILD_DIR + "/.libs/_py3sss_murmur.so"
else:
- os.symlink("_py2sss_murmur.so", "pysss_murmur.so")
- os.chdir(cwd_backup)
+ src_module_path = BUILD_DIR + "/.libs/_py2sss_murmur.so"
+
+ src_module_path = os.path.abspath(src_module_path)
+ os.symlink(src_module_path, dest_module_path)
import pysss_murmur
except ImportError as e:
@@ -80,6 +74,11 @@ class PySssMurmurImport(unittest.TestCase):
self.assertEqual(pysss_murmur.__file__, MODPATH + "/pysss_murmur.so")
class PySssMurmurTest(unittest.TestCase):
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(MODPATH + "/pysss_murmur.so")
+ os.rmdir(MODPATH)
+
def testExpectedHash(self):
hash = pysss_murmur.murmurhash3("S-1-5-21-2153326666-2176343378-3404031434", 41, 0xdeadbeef)
self.assertEqual(hash, 93103853)
--
2.5.0

View File

@ -0,0 +1,100 @@
From 8fc61f5bba2f8c06b0d86d177f2e11d5c7f5d874 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 27 Jan 2016 16:02:33 +0100
Subject: [PATCH 57/86] PYTHON: sss_obfuscate should work with python3
Based on patch from: Steven W. Elling <ellingsw+29044@gmail.com>
Resolves:
https://fedorahosted.org/sssd/ticket/2937
Reviewed-by: Martin Basti <mbasti@redhat.com>
(cherry picked from commit 11496692da75a330de01d5f15b7183d2439efd3c)
(cherry picked from commit 683b9d012117016483b99620c333be666a6c888e)
---
src/tools/sss_obfuscate | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/src/tools/sss_obfuscate b/src/tools/sss_obfuscate
index fbea1213d8f7e99ab3b1a6d7d24accf8a6194094..68ef30e386ced95b85afbea87696e3c69bea7b51 100644
--- a/src/tools/sss_obfuscate
+++ b/src/tools/sss_obfuscate
@@ -1,5 +1,7 @@
#!/usr/bin/python
+from __future__ import print_function
+
import sys
from optparse import OptionParser
@@ -33,11 +35,11 @@ def parse_options():
def main():
options, args = parse_options()
if not options:
- print >> sys.stderr, "Cannot parse options"
+ print("Cannot parse options", file=sys.stderr)
return 1
if not options.domain:
- print >> sys.stderr, "No domain specified"
+ print("No domain specified", file=sys.stderr)
return 1
if not options.stdin:
@@ -59,7 +61,8 @@ def main():
password = p1
except EOFError:
- print >> sys.stderr, '\nUnexpected end-of-file. Password change aborted'
+ print('\nUnexpected end-of-file. Password change aborted',
+ file=sys.stderr)
return 1
except KeyboardInterrupt:
return 1
@@ -78,26 +81,26 @@ def main():
try:
sssdconfig = SSSDConfig.SSSDConfig()
except IOError:
- print "Cannot read internal configuration files."
+ print("Cannot read internal configuration files.")
return 1
try:
sssdconfig.import_config(options.filename)
except IOError:
- print "Permissions error reading config file"
+ print("Permissions error reading config file")
return 1
try:
domain = sssdconfig.get_domain(options.domain)
except SSSDConfig.NoDomainError:
- print "No such domain %s" % options.domain
+ print("No such domain %s" % options.domain)
return 1
try:
domain.set_option('ldap_default_authtok_type', 'obfuscated_password')
domain.set_option('ldap_default_authtok', obfpwd)
except SSSDConfig.NoOptionError:
- print "The domain %s does not seem to support the required options" % \
- options.domain
+ print("The domain %s does not seem to support the required options"
+ % options.domain)
return 1
@@ -106,9 +109,8 @@ def main():
sssdconfig.write()
except IOError:
# File could not be written
- print >> sys.stderr, "Could not write to config file. Check that " \
- "you have the appropriate permissions to edit " \
- "this file."
+ print("Could not write to config file. Check that you have the "
+ "appropriate permissions to edit this file.", file=sys.stderr)
return 1
return 0
--
2.5.0

View File

@ -0,0 +1,82 @@
From 1d7742a2b98c1494af2ce1c3eb3d6850ea1e78e9 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 27 Jan 2016 17:49:45 +0100
Subject: [PATCH 58/86] PYTHON: Fix pep8 errors in sss_obfuscate
src/tools/sss_obfuscate:12:1: E302 expected 2 blank lines, found 1
src/tools/sss_obfuscate:29:80: E501 line too long (111 > 79 characters)
src/tools/sss_obfuscate:35:1: E302 expected 2 blank lines, found 1
src/tools/sss_obfuscate:47:80: E501 line too long (107 > 79 characters)
src/tools/sss_obfuscate:50:13: E265 block comment should start with '# '
src/tools/sss_obfuscate:58:17: E265 block comment should start with '# '
src/tools/sss_obfuscate:107:5: E303 too many blank lines (2)
Reviewed-by: Martin Basti <mbasti@redhat.com>
(cherry picked from commit 37ea8e70fa13ff9ba563300fb15de0e5e6185d68)
(cherry picked from commit f61eb0c92251dbe65a2868aa1ded470d1f2739c8)
---
src/tools/sss_obfuscate | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/tools/sss_obfuscate b/src/tools/sss_obfuscate
index 68ef30e386ced95b85afbea87696e3c69bea7b51..5981e81410af68fd8123781a5e21a0c7fa3bcb23 100644
--- a/src/tools/sss_obfuscate
+++ b/src/tools/sss_obfuscate
@@ -9,6 +9,7 @@ import pysss
import SSSDConfig
import getpass
+
def parse_options():
parser = OptionParser()
parser.set_description("sss_obfuscate converts a given password into \
@@ -26,12 +27,14 @@ def parse_options():
metavar="DOMNAME")
parser.add_option("-f", "--file",
dest="filename", default=None,
- help="Set input file to FILE (default: Use system default, usually /etc/sssd/sssd.conf)",
+ help="Set input file to FILE (default: Use system "
+ "default, usually /etc/sssd/sssd.conf)",
metavar="FILE")
(options, args) = parser.parse_args()
return options, args
+
def main():
options, args = parse_options()
if not options:
@@ -44,10 +47,11 @@ def main():
if not options.stdin:
try:
- pprompt = lambda: (getpass.getpass("Enter password: "), getpass.getpass("Re-enter password: "))
+ pprompt = lambda: (getpass.getpass("Enter password: "),
+ getpass.getpass("Re-enter password: "))
p1, p2 = pprompt()
- #Work around bug in Python 2.6
+ # Work around bug in Python 2.6
if '\x03' in p1 or '\x03' in p2:
raise KeyboardInterrupt
@@ -55,7 +59,7 @@ def main():
print('Passwords do not match. Try again')
p1, p2 = pprompt()
- #Work around bug in Python 2.6
+ # Work around bug in Python 2.6
if '\x03' in p1 or '\x03' in p2:
raise KeyboardInterrupt
password = p1
@@ -103,7 +107,6 @@ def main():
% options.domain)
return 1
-
sssdconfig.save_domain(domain)
try:
sssdconfig.write()
--
2.5.0

View File

@ -0,0 +1,37 @@
From 33a029f9d2b55887fef08676234bebc4b6b5f7e4 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Thu, 28 Jan 2016 05:03:40 -0500
Subject: [PATCH 59/86] IDMAP: Man change for ldap_idmap_range_size option
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves:
https://fedorahosted.org/sssd/ticket/2922
Reviewed-by: Nathaniel McCallum <npmccallum@redhat.com>
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit d9de4b26f44a344025bbfa23104b7b67935fae35)
(cherry picked from commit c2fa17edf4b9d385302ddd24ce599a1cef7250a6)
---
src/man/include/ldap_id_mapping.xml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/man/include/ldap_id_mapping.xml b/src/man/include/ldap_id_mapping.xml
index a088c4e81d81c5670edea8ae8081abe80927446a..9252b1caa56b086b640ab0b2a79069616cef6443 100644
--- a/src/man/include/ldap_id_mapping.xml
+++ b/src/man/include/ldap_id_mapping.xml
@@ -178,7 +178,9 @@ ldap_schema = ad
<para>
For example, if your most recently-added Active Directory user has
objectSid=S-1-5-21-2153326666-2176343378-3404031434-1107,
- <quote>ldap_idmap_range_size</quote> must be at least 1107.
+ <quote>ldap_idmap_range_size</quote> must be at least 1108 as
+ range size is equal to maximal SID minus minimal SID plus one
+ (e.g. 1108 = 1107 - 0 + 1).
</para>
<para>
It is important to plan ahead for future expansion, as changing this
--
2.5.0

View File

@ -0,0 +1,107 @@
From df9da4a4d83e1ebc235a2b5ead445e0a406c1234 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Fri, 27 Nov 2015 07:53:00 -0500
Subject: [PATCH 60/86] NSS: Fix memory leak netgroup
Resolves:
https://fedorahosted.org/sssd/ticket/2865
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 4231a17e66e0809a9c3d42207b45f95429cbb46c)
(cherry picked from commit 3bca87239e3368d61c25f2f6bd2329191eca0dee)
---
src/responder/nss/nsssrv_netgroup.c | 41 ++++++++++++++++++++++++++-----------
1 file changed, 29 insertions(+), 12 deletions(-)
diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c
index 9a78c1119c2f4e06e43ebec29ace775adc997e08..383b44a2c9b1fb87d3abfdce071b226a561e22a7 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -435,14 +435,18 @@ static errno_t create_negcache_netgr(struct setent_step_ctx *step_ctx)
errno_t ret;
struct getent_ctx *netgr;
- netgr = talloc_zero(step_ctx->nctx, struct getent_ctx);
- if (netgr == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n");
- ret = ENOMEM;
- goto done;
- } else {
- netgr->ready = true;
- netgr->found = false;
+ /* Is there already netgroup with such name? */
+ ret = get_netgroup_entry(step_ctx->nctx, step_ctx->name,
+ &netgr);
+ if (ret != EOK || netgr == NULL) {
+
+ netgr = talloc_zero(step_ctx->nctx, struct getent_ctx);
+ if (netgr == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
netgr->entries = NULL;
netgr->lookup_table = step_ctx->nctx->netgroups;
netgr->name = talloc_strdup(netgr, step_ctx->name);
@@ -457,13 +461,20 @@ static errno_t create_negcache_netgr(struct setent_step_ctx *step_ctx)
DEBUG(SSSDBG_CRIT_FAILURE, "set_netgroup_entry failed.\n");
goto done;
}
- set_netgr_lifetime(step_ctx->nctx->neg_timeout, step_ctx, netgr);
}
+ netgr->ready = true;
+ netgr->found = false;
+
+ set_netgr_lifetime(step_ctx->nctx->neg_timeout, step_ctx, netgr);
+
+ ret = EOK;
+
done:
if (ret != EOK) {
talloc_free(netgr);
}
+
return ret;
}
@@ -474,6 +485,12 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
struct getent_ctx *netgr;
char *name = NULL;
uint32_t lifetime;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
/* Check each domain for this netgroup name */
while (dom) {
@@ -494,8 +511,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
/* make sure to update the dctx if we changed domain */
step_ctx->dctx->domain = dom;
- talloc_free(name);
- name = sss_get_cased_name(step_ctx, step_ctx->name,
+ name = sss_get_cased_name(tmp_ctx, step_ctx->name,
dom->case_sensitive);
if (!name) {
DEBUG(SSSDBG_CRIT_FAILURE, "sss_get_cased_name failed\n");
@@ -623,10 +639,11 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
"create_negcache_netgr failed with: %d:[%s], ignored.\n",
ret, sss_strerror(ret));
}
+
ret = ENOENT;
done:
- talloc_free(name);
+ talloc_free(tmp_ctx);
return ret;
}
--
2.5.0

View File

@ -0,0 +1,189 @@
From e3e319e537e6def0248351118f3801213b5a2475 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Fri, 22 Jan 2016 08:34:14 -0500
Subject: [PATCH 61/86] IDMAP: Add test to validate off by one bug
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves:
https://fedorahosted.org/sssd/ticket/2922
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit 9d17f436795a36b1b1126f444923aa847fd0f93a)
(cherry picked from commit 8c1f3b27d8e20b271dfea0c41fd864e9af5476f5)
---
src/tests/cmocka/test_sss_idmap.c | 113 ++++++++++++++++++++++++++++++++++++--
1 file changed, 109 insertions(+), 4 deletions(-)
diff --git a/src/tests/cmocka/test_sss_idmap.c b/src/tests/cmocka/test_sss_idmap.c
index 00e03ffd9ab1532fb55795b9935b254c8a89ec16..f82e3dc51601850a480cf1daa6d5f6dbd940ddcb 100644
--- a/src/tests/cmocka/test_sss_idmap.c
+++ b/src/tests/cmocka/test_sss_idmap.c
@@ -43,6 +43,9 @@
#define TEST_OFFSET 1000000
#define TEST_OFFSET_STR "1000000"
+const int TEST_2922_MIN_ID = 1842600000;
+const int TEST_2922_MAX_ID = 1842799999;
+
struct test_ctx {
TALLOC_CTX *mem_idmap;
struct sss_idmap_ctx *idmap_ctx;
@@ -128,7 +131,38 @@ static int setup_ranges(struct test_ctx *test_ctx, bool external_mapping,
return 0;
}
-static int test_sss_idmap_setup_with_domains(void **state) {
+static int setup_ranges_2922(struct test_ctx *test_ctx)
+{
+ const int TEST_2922_DFL_SLIDE = 9212;
+ struct sss_idmap_range range;
+ enum idmap_error_code err;
+ const char *name;
+ const char *sid;
+ /* Pick a new slice. */
+ id_t slice_num = -1;
+
+ assert_non_null(test_ctx);
+
+ name = TEST_DOM_NAME;
+ sid = TEST_DOM_SID;
+
+ err = sss_idmap_calculate_range(test_ctx->idmap_ctx, sid, &slice_num,
+ &range);
+ assert_int_equal(err, IDMAP_SUCCESS);
+ /* Range computation should be deterministic. Lets validate that. */
+ assert_int_equal(range.min, TEST_2922_MIN_ID);
+ assert_int_equal(range.max, TEST_2922_MAX_ID);
+ assert_int_equal(slice_num, TEST_2922_DFL_SLIDE);
+
+ err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, name, sid, &range,
+ NULL, 0, false /* No external mapping */);
+ assert_int_equal(err, IDMAP_SUCCESS);
+
+ return 0;
+}
+
+static int test_sss_idmap_setup_with_domains(void **state)
+{
struct test_ctx *test_ctx;
test_sss_idmap_setup(state);
@@ -140,7 +174,21 @@ static int test_sss_idmap_setup_with_domains(void **state) {
return 0;
}
-static int test_sss_idmap_setup_with_domains_sec_slices(void **state) {
+static int test_sss_idmap_setup_with_domains_2922(void **state)
+{
+ struct test_ctx *test_ctx;
+
+ test_sss_idmap_setup(state);
+
+ test_ctx = talloc_get_type(*state, struct test_ctx);
+ assert_non_null(test_ctx);
+
+ setup_ranges_2922(test_ctx);
+ return 0;
+}
+
+static int test_sss_idmap_setup_with_domains_sec_slices(void **state)
+{
struct test_ctx *test_ctx;
test_sss_idmap_setup(state);
@@ -152,7 +200,8 @@ static int test_sss_idmap_setup_with_domains_sec_slices(void **state) {
return 0;
}
-static int test_sss_idmap_setup_with_external_mappings(void **state) {
+static int test_sss_idmap_setup_with_external_mappings(void **state)
+{
struct test_ctx *test_ctx;
test_sss_idmap_setup(state);
@@ -164,7 +213,8 @@ static int test_sss_idmap_setup_with_external_mappings(void **state) {
return 0;
}
-static int test_sss_idmap_setup_with_both(void **state) {
+static int test_sss_idmap_setup_with_both(void **state)
+{
struct test_ctx *test_ctx;
test_sss_idmap_setup(state);
@@ -298,6 +348,58 @@ void test_map_id(void **state)
sss_idmap_free_sid(test_ctx->idmap_ctx, sid);
}
+/* https://fedorahosted.org/sssd/ticket/2922 */
+/* ID mapping - bug in computing max id for slice range */
+void test_map_id_2922(void **state)
+{
+ const char* TEST_2922_FIRST_SID = TEST_DOM_SID"-0";
+ /* Last SID = first SID + (default) rangesize -1 */
+ const char* TEST_2922_LAST_SID = TEST_DOM_SID"-199999";
+ /* Last SID = first SID + rangesize */
+ const char* TEST_2922_LAST_SID_PLUS_ONE = TEST_DOM_SID"-200000";
+ struct test_ctx *test_ctx;
+ enum idmap_error_code err;
+ uint32_t id;
+ char *sid = NULL;
+
+ test_ctx = talloc_get_type(*state, struct test_ctx);
+
+ assert_non_null(test_ctx);
+
+ /* Min UNIX ID to SID */
+ err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_2922_MIN_ID, &sid);
+ assert_int_equal(err, IDMAP_SUCCESS);
+ assert_string_equal(sid, TEST_2922_FIRST_SID);
+ sss_idmap_free_sid(test_ctx->idmap_ctx, sid);
+
+ /* First SID to UNIX ID */
+ err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_2922_FIRST_SID, &id);
+ assert_int_equal(err, IDMAP_SUCCESS);
+ assert_int_equal(id, TEST_2922_MIN_ID);
+
+ /* Max UNIX ID to SID */
+ err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_2922_MAX_ID, &sid);
+ assert_int_equal(err, IDMAP_SUCCESS);
+ assert_string_equal(sid, TEST_2922_LAST_SID);
+ sss_idmap_free_sid(test_ctx->idmap_ctx, sid);
+
+ /* Last SID to UNIX ID */
+ err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_2922_LAST_SID, &id);
+ assert_int_equal(err, IDMAP_SUCCESS);
+ assert_int_equal(id, TEST_2922_MAX_ID);
+
+ /* Max UNIX ID + 1 to SID */
+ err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_2922_MAX_ID + 1,
+ &sid);
+ assert_int_equal(err, IDMAP_NO_DOMAIN);
+
+ /* Last SID + 1 to UNIX ID */
+ err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx,
+ TEST_2922_LAST_SID_PLUS_ONE, &id);
+ /* Auto adding new ranges is disable in this test. */
+ assert_int_equal(err, IDMAP_NO_RANGE);
+}
+
void test_map_id_sec_slices(void **state)
{
struct test_ctx *test_ctx;
@@ -589,6 +691,9 @@ int main(int argc, const char *argv[])
cmocka_unit_test_setup_teardown(test_map_id,
test_sss_idmap_setup_with_domains,
test_sss_idmap_teardown),
+ cmocka_unit_test_setup_teardown(test_map_id_2922,
+ test_sss_idmap_setup_with_domains_2922,
+ test_sss_idmap_teardown),
cmocka_unit_test_setup_teardown(test_map_id_sec_slices,
test_sss_idmap_setup_with_domains_sec_slices,
test_sss_idmap_teardown),
--
2.5.0

View File

@ -0,0 +1,119 @@
From 4f1dec56127c91c02908f40161cde42313ff93e4 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Fri, 5 Feb 2016 07:27:38 -0500
Subject: [PATCH 62/86] SDAP: Add return code ERR_ACCOUNT_LOCKED
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add code to distinquish state when account is locked in Active
Directory server.
Tested against Windows Server 2012
This patch is best effort only as decision whether account is actually
locked is based on parsing error message returned by AD. The format and
content of this error message might be subject of change in future
releases and also can be modified by AD administrators.
If account is locked bind operation is expected to return following
error message:
-----------------------------------------------------------------------
Invalid credentials(49), 80090308: LdapErr: DSID-0C0903C5, comment:
AcceptSecurityContext error, data 775, v23f0
-----------------------------------------------------------------------
Where sub string 'data 775' implies that account is locked
(ERROR_ACCOUNT_LOCKED_OUT) [1]. However the 80090308 (error code
0x80090308, SEC_E_INVALID_TOKEN) is the only guaranteed part of error
string [2].
Error message is described in further detail as [3]:
-----------------------------------------------------------------------
When the server fails an LDAP operation with an error, and the server
has sufficient resources to compute a string value for the errorMessage
field of the LDAPResult, it includes a string in the errorMessage field
of the LDAPResult (see [RFC2251] section 4.1.10). The string contains
further information about the error.
The first eight characters of the errorMessage string are a 32-bit
integer, expressed in hexadecimal. Where protocol specifies the extended
error code "<unrestricted>" there is no restriction on the value of the
32-bit integer. It is recommended that implementations use a Windows
error code for the 32-bit integer in this case in order to improve
usability of the directory for clients. Where protocol specifies an
extended error code which is a Windows error code, the 32-bit integer is
the specified Windows error code. Any data after the eighth character
is strictly informational and used only for debugging. Conformant
implementations need not put any value beyond the eighth character of
the errorMessage field.
-----------------------------------------------------------------------
[1] https://msdn.microsoft.com/en-us/library/windows/desktop/ms681386%28v=vs.85%29.aspx
[2] https://social.msdn.microsoft.com/Forums/en-US/e1d600c8-60b7-4ed0-94cb-20ddd6c1a1c6/msadts-user-locking-password-policies?forum=os_windowsprotocols
[3] MS-ADTS 3.1.1.3.1.9
https://msdn.microsoft.com/en-us/library/cc223253.aspx
Resolves:
https://fedorahosted.org/sssd/ticket/2839
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Reviewed-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit ff275f4c0b8cc1a098dbd0c5f6d52d6a93cda597)
(cherry picked from commit 81cb4057920c6296b7f7e6b7c651fdb601ff0338)
---
src/providers/data_provider.h | 2 ++
src/providers/ldap/ldap_auth.c | 4 ++++
src/providers/ldap/sdap_async_connection.c | 6 ++++++
3 files changed, 12 insertions(+)
diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index 39051b90c3aad96f62dcbb86a20bcfd8c954879b..7332b677d19f70f4736e4d0b68d55cdd3c67a4af 100644
--- a/src/providers/data_provider.h
+++ b/src/providers/data_provider.h
@@ -182,6 +182,8 @@ struct pam_data {
bool offline_auth;
bool last_auth_saved;
int priv;
+ int account_locked;
+
#ifdef USE_KEYRING
key_serial_t key_serial;
#endif
diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
index 217e80fd07abc41f2594d19397783683d44600cd..2fab92e5d22a4dae870c5e9dde7ef162fc36cbe2 100644
--- a/src/providers/ldap/ldap_auth.c
+++ b/src/providers/ldap/ldap_auth.c
@@ -1302,6 +1302,10 @@ static void sdap_pam_auth_done(struct tevent_req *req)
case ERR_PASSWORD_EXPIRED:
state->pd->pam_status = PAM_NEW_AUTHTOK_REQD;
break;
+ case ERR_ACCOUNT_LOCKED:
+ state->pd->account_locked = true;
+ state->pd->pam_status = PAM_PERM_DENIED;
+ break;
default:
state->pd->pam_status = PAM_SYSTEM_ERR;
dp_err = DP_ERR_FATAL;
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index 85b7aaa5bf5acedf3511ffe6f8636be007d5a136..40256de99006815c97ee9390dfd2e997cf6fc072 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -754,6 +754,12 @@ static void simple_bind_done(struct sdap_op *op,
if (result == LDAP_SUCCESS) {
ret = EOK;
+ } else if (result == LDAP_INVALID_CREDENTIALS
+ && errmsg != NULL && strstr(errmsg, "data 775,") != NULL) {
+ /* Value 775 is described in
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/ms681386%28v=vs.85%29.aspx
+ * for more details please see commit message. */
+ ret = ERR_ACCOUNT_LOCKED;
} else {
ret = ERR_AUTH_FAILED;
}
--
2.5.0

View File

@ -0,0 +1,198 @@
From fdc7e4acad41e7f0dff4926690f14bf94c009e38 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Fri, 5 Feb 2016 07:31:45 -0500
Subject: [PATCH 63/86] PAM: Pass account lockout status and display message
Tested against Windows Server 2012.
Resolves:
https://fedorahosted.org/sssd/ticket/2839
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 4180d485829969d4626cc7d49d2b5f7146512f21)
(cherry picked from commit 1b9f294dab02e6bcd4ce54e3447648d3d664ceaa)
---
src/confdb/confdb.h | 1 +
src/config/SSSDConfig/__init__.py.in | 1 +
src/config/etc/sssd.api.conf | 1 +
src/man/sssd.conf.5.xml | 21 +++++++++++++++++++++
src/providers/dp_auth_util.c | 19 +++++++++++++++++++
src/responder/pam/pamsrv_cmd.c | 31 +++++++++++++++++++++++--------
6 files changed, 66 insertions(+), 8 deletions(-)
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index c6a5e3f61d8bfd045eb2699d0f5e279cb7d89f86..6d8601b31cf4ce1a42f824a8400cef8c4ffadf9a 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -117,6 +117,7 @@
#define CONFDB_PAM_TRUSTED_USERS "pam_trusted_users"
#define CONFDB_PAM_PUBLIC_DOMAINS "pam_public_domains"
#define CONFDB_PAM_ACCOUNT_EXPIRED_MESSAGE "pam_account_expired_message"
+#define CONFDB_PAM_ACCOUNT_LOCKED_MESSAGE "pam_account_locked_message"
#define CONFDB_PAM_CERT_AUTH "pam_cert_auth"
#define CONFDB_PAM_CERT_DB_PATH "pam_cert_db_path"
#define CONFDB_PAM_P11_CHILD_TIMEOUT "p11_child_timeout"
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 6abdbc3a43cd4dbd74208efa8602b889f6e84d2b..09284fdd7c8e630b3745367b33b8ea0424ff466f 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -90,6 +90,7 @@ option_strings = {
'pam_trusted_users' : _('List of trusted uids or user\'s name'),
'pam_public_domains' : _('List of domains accessible even for untrusted users.'),
'pam_account_expired_message' : _('Message printed when user account is expired.'),
+ 'pam_account_locked_message' : _('Message printed when user account is locked.'),
'p11_child_timeout' : _('How many seconds will pam_sss wait for p11_child to finish'),
# [sudo]
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index b6a396a75e564355d0828fa24858337eb06ff4bf..6e00a87918b4c3972c1f05e5d66d0fc8a71a5cf7 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -60,6 +60,7 @@ get_domains_timeout = int, None, false
pam_trusted_users = str, None, false
pam_public_domains = str, None, false
pam_account_expired_message = str, None, false
+pam_account_locked_message = str, None, false
p11_child_timeout = int, None, false
[sudo]
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 7b1c4f0fff9c042ce9ade2473bfe4582909212c4..cf2301f06d03b580f0bd5cea3567599af45eed02 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1024,6 +1024,27 @@ pam_account_expired_message = Account expired, please call help desk.
</listitem>
</varlistentry>
<varlistentry>
+ <term>pam_account_locked_message (string)</term>
+ <listitem>
+ <para>
+ If user is authenticating and
+ account is locked then by default
+ 'Permission denied' is output. This output will
+ be changed to content of this variable if it is
+ set.
+ </para>
+ <para>
+ example:
+ <programlisting>
+pam_account_locked_message = Account locked, please call help desk.
+ </programlisting>
+ </para>
+ <para>
+ Default: none
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term>p11_child_timeout (integer)</term>
<listitem>
<para>
diff --git a/src/providers/dp_auth_util.c b/src/providers/dp_auth_util.c
index f8a30c5d4e6da7ce6ac28723032241e2458ea473..8e261ef5e4af7479ffce087370844caa1cad43d7 100644
--- a/src/providers/dp_auth_util.c
+++ b/src/providers/dp_auth_util.c
@@ -160,6 +160,14 @@ bool dp_pack_pam_response(DBusMessage *msg, struct pam_data *pd)
return false;
}
+ /* Append the lockout of account */
+ dbret = dbus_message_iter_append_basic(&iter,
+ DBUS_TYPE_UINT32,
+ &pd->account_locked);
+ if (!dbret) {
+ return false;
+ }
+
/* Create an array of response structures */
dbret = dbus_message_iter_open_container(&iter,
DBUS_TYPE_ARRAY, "(uay)",
@@ -246,6 +254,17 @@ bool dp_unpack_pam_response(DBusMessage *msg, struct pam_data *pd, DBusError *db
return false;
}
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n");
+ return false;
+ }
+ dbus_message_iter_get_basic(&iter, &(pd->account_locked));
+
+ if (!dbus_message_iter_next(&iter)) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "pam response has too few arguments.\n");
+ return false;
+ }
+
/* After this point will be an array of pam data */
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n");
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 38636088e63ede159df0bc9376c255d05bf7de0b..c4ea9cd3e8970db7d281086453d22f3218b05c47 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -53,10 +53,10 @@ pam_get_last_online_auth_with_curr_token(struct sss_domain_info *domain,
static void pam_reply(struct pam_auth_req *preq);
-static errno_t pack_user_info_account_expired(TALLOC_CTX *mem_ctx,
- const char *user_error_message,
- size_t *resp_len,
- uint8_t **_resp)
+static errno_t pack_user_info_msg(TALLOC_CTX *mem_ctx,
+ const char *user_error_message,
+ size_t *resp_len,
+ uint8_t **_resp)
{
uint32_t resp_type = SSS_PAM_USER_INFO_ACCOUNT_EXPIRED;
size_t err_len;
@@ -83,14 +83,13 @@ static errno_t pack_user_info_account_expired(TALLOC_CTX *mem_ctx,
return EOK;
}
-static void inform_account_expired(struct pam_data* pd,
- const char *pam_message)
+static void inform_user(struct pam_data* pd, const char *pam_message)
{
size_t msg_len;
uint8_t *msg;
errno_t ret;
- ret = pack_user_info_account_expired(pd, pam_message, &msg_len, &msg);
+ ret = pack_user_info_msg(pd, pam_message, &msg_len, &msg);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
"pack_user_info_account_expired failed.\n");
@@ -601,6 +600,7 @@ static void pam_reply(struct pam_auth_req *preq)
time_t exp_date = -1;
time_t delay_until = -1;
char* pam_account_expired_message;
+ char* pam_account_locked_message;
int pam_verbosity;
pd = preq->pd;
@@ -762,7 +762,22 @@ static void pam_reply(struct pam_auth_req *preq)
goto done;
}
- inform_account_expired(pd, pam_account_expired_message);
+ inform_user(pd, pam_account_expired_message);
+ }
+
+ if (pd->account_locked) {
+
+ ret = confdb_get_string(pctx->rctx->cdb, pd, CONFDB_PAM_CONF_ENTRY,
+ CONFDB_PAM_ACCOUNT_LOCKED_MESSAGE, "",
+ &pam_account_locked_message);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Failed to get expiration message: %d:[%s].\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ inform_user(pd, pam_account_locked_message);
}
ret = filter_responses(pctx->rctx->cdb, pd->resp_list);
--
2.5.0

View File

@ -0,0 +1,65 @@
From 03dde14c2cc236e20456f24910dae4308dc96f16 Mon Sep 17 00:00:00 2001
From: Dan Lavu <dlavu@redhat.com>
Date: Fri, 5 Feb 2016 09:28:41 -0500
Subject: [PATCH 64/86] PAM: Fix man for pam_account_{expired,locked}_message
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 09092b6535b711b9b734ed0c047c671de9e6cafd)
(cherry picked from commit ffe3df61d85c2890a31d627c5e6fe8890f1e26d8)
---
src/man/sssd.conf.5.xml | 35 +++++++++++++++++++++++++++++------
1 file changed, 29 insertions(+), 6 deletions(-)
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index cf2301f06d03b580f0bd5cea3567599af45eed02..d7e324f457a42403133c9d25f34d702d703fc9b8 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1006,16 +1006,39 @@ fallback_homedir = /home/%u
<term>pam_account_expired_message (string)</term>
<listitem>
<para>
- If user is authenticating using SSH keys and
- account is expired then by default
- 'Permission denied' is output. This output will
- be changed to content of this variable if it is
- set.
+ Allows a custom expiration message to be set,
+ replacing the default 'Permission denied'
+ message.
+ </para>
+ <para>
+ Note: Please be aware that message is only
+ printed for the SSH service unless pam_verbostiy
+ is set to 3 (show all messages and debug
+ information).
+ </para>
+ <para>
+ example:
+ <programlisting>
+pam_account_expired_message = Account expired, please contact help desk.
+ </programlisting>
+ </para>
+ <para>
+ Default: none
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>pam_account_locked_message (string)</term>
+ <listitem>
+ <para>
+ Allows a custom lockout message to be set,
+ replacing the default 'Permission denied'
+ message.
</para>
<para>
example:
<programlisting>
-pam_account_expired_message = Account expired, please call help desk.
+pam_account_locked_message = Account locked, please contact help desk.
</programlisting>
</para>
<para>
--
2.5.0

View File

@ -0,0 +1,45 @@
From 90933a2aa0bc149fd8a1ca4feef0527ddfcf7258 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 17 Feb 2016 17:58:10 +0100
Subject: [PATCH 65/86] UTIL: Backport error code ERR_ACCOUNT_LOCKED
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Required by:
https://fedorahosted.org/sssd/ticket/2839
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit af717c5b022d5c28141333fc02d5d9e1f322505c)
---
src/util/util_errors.c | 1 +
src/util/util_errors.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/src/util/util_errors.c b/src/util/util_errors.c
index 1d684d387b90b8db37609d5bc022e06fcac708f9..59ae63ab8d6e834a772349b162bf282f9a4f1c72 100644
--- a/src/util/util_errors.c
+++ b/src/util/util_errors.c
@@ -82,6 +82,7 @@ struct err_string error_to_str[] = {
{ "Address family not supported" }, /* ERR_ADDR_FAMILY_NOT_SUPPORTED */
{ "Message sender is the bus" }, /* ERR_SBUS_SENDER_BUS */
{ "Subdomain is inactive" }, /* ERR_SUBDOM_INACTIVE */
+ { "Account is locked" }, /* ERR_ACCOUNT_LOCKED */
{ "AD renewal child failed" }, /* ERR_RENEWAL_CHILD */
{ "ERR_LAST" } /* ERR_LAST */
};
diff --git a/src/util/util_errors.h b/src/util/util_errors.h
index 5c02fdd8b4c6e0c59f7fd6f66a3fc8a8e48dc607..05791f2f08f107a8b4830b810b8826983763174f 100644
--- a/src/util/util_errors.h
+++ b/src/util/util_errors.h
@@ -104,6 +104,7 @@ enum sssd_errors {
ERR_ADDR_FAMILY_NOT_SUPPORTED,
ERR_SBUS_SENDER_BUS,
ERR_SUBDOM_INACTIVE,
+ ERR_ACCOUNT_LOCKED,
ERR_RENEWAL_CHILD,
ERR_LAST /* ALWAYS LAST */
};
--
2.5.0

View File

@ -0,0 +1,51 @@
From 5897690a889c6f2a11135d1ed33089409ddb8c57 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 17 Feb 2016 17:23:37 +0100
Subject: [PATCH 66/86] sss_idmap-tests: Fix segmentation fault
I can reproduce it only with clang.
But it's tipical off by one error.
sh$ ./sss_idmap-tests
Running suite(s): IDMAP
Segmentation fault (core dumped)
Running suite(s): IDMAP
==2644== Process terminating with default action of signal 11 (SIGSEGV)
==2644== Access not within mapped region at address 0xA08F430
==2644== at 0x4C2CC53: strcmp (vg_replace_strmem.c:842)
==2644== by 0x4060DA: idmap_test_sid2uid_additional_secondary_slices (sss_idmap-tests.c:451)
==2644== by 0x503C78A: ??? (in /usr/lib64/libcheck.so.0.0.0)
==2644== by 0x503CB7C: srunner_run (in /usr/lib64/libcheck.so.0.0.0)
==2644== by 0x4061EE: main (sss_idmap-tests.c:965)
==2644== If you believe this happened as a result of a stack
==2644== overflow in your program's main thread (unlikely but
==2644== possible), you can try to increase the size of the
==2644== main thread stack using the --main-stacksize= flag.
==2644== The main thread stack size used in this run was 8388608.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 4f3a996561445ba82c854bb2b674f975f596e884)
(cherry picked from commit 999af61d6a55bf816d86dbfc94214383436b18d3)
---
src/tests/sss_idmap-tests.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/tests/sss_idmap-tests.c b/src/tests/sss_idmap-tests.c
index 900b7bff1cd4f3c6f9cdffc4b012864d05e72913..885913645ed286636758f3f48a5a62d87cc9ab75 100644
--- a/src/tests/sss_idmap-tests.c
+++ b/src/tests/sss_idmap-tests.c
@@ -427,8 +427,8 @@ START_TEST(idmap_test_sid2uid_additional_secondary_slices)
struct TALLOC_CTX *tmp_ctx;
const char *dom_prefix = "S-1-5-21-1-2-3";
const int max_rid = 80;
- const char *sids[max_rid];
- unsigned int ids[max_rid];
+ const char *sids[max_rid + 1];
+ unsigned int ids[max_rid + 1];
tmp_ctx = talloc_new(NULL);
fail_unless(tmp_ctx != NULL, "Out of memory.");
--
2.5.0

View File

@ -0,0 +1,74 @@
From 40ccad84a0558eb21ebd351ea837c5042fa38966 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Fri, 29 Jan 2016 13:30:49 +0100
Subject: [PATCH 67/86] krb5_child: Warn if user cannot read krb5.conf
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Attached patch should siplify troubleshoting of
issues with permission of krb5.conf. It's not clear from
krb5_child.log even with full debug level.
[sss_get_ccache_name_for_principal] (0x4000):
Location: [FILE:/tmp/krb5cc_12069_XXXXXX]
[sss_get_ccache_name_for_principal] (0x2000):
krb5_cc_cache_match failed: [-1765328243]
[Can't find client principal user@EXAMPLE.COM in cache collection]
[create_ccache] (0x0020): 735: [13][Permission denied]
Resolves:
https://fedorahosted.org/sssd/ticket/2931
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit 38f251e531b1c68e70eaa98dfecaf78da5f36ccc)
(cherry picked from commit 760d655881e87f52db033a4a56b05fbe91dce146)
---
src/providers/krb5/krb5_child.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 619e76372f962279ddffadadc607d9bbb20fbffb..6fd88815a5224809c7c448198495ae009f47097e 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -2572,6 +2572,29 @@ static krb5_error_code privileged_krb5_setup(struct krb5_req *kr,
return 0;
}
+static void try_open_krb5_conf(void)
+{
+ int fd;
+ int ret;
+
+ fd = open("/etc/krb5.conf", O_RDONLY);
+ if (fd != -1) {
+ close(fd);
+ } else {
+ ret = errno;
+ if (ret == EACCES || ret == EPERM) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "User with uid:%"SPRIuid" gid:%"SPRIgid" cannot read "
+ "/etc/krb5.conf. It might cause problems\n",
+ geteuid(), getegid());
+ } else {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Cannot open /etc/krb5.conf [%d]: %s\n",
+ ret, strerror(ret));
+ }
+ }
+}
+
int main(int argc, const char *argv[])
{
struct krb5_req *kr = NULL;
@@ -2673,6 +2696,7 @@ int main(int argc, const char *argv[])
DEBUG(SSSDBG_TRACE_INTERNAL,
"Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid());
+ try_open_krb5_conf();
ret = k5c_setup(kr, offline);
if (ret != EOK) {
--
2.5.0

View File

@ -0,0 +1,197 @@
From 7832b422ec442ec2d80cf00bb1189ac2f38a783b Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Fri, 12 Feb 2016 22:05:21 +0100
Subject: [PATCH 68/86] Fix typos reported by lintian
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 42604cc8d11743febf5aa892cb3a7d3c32bfed48)
(cherry picked from commit 7870820e8b188d755fef9fb31ef95b518c0f905b)
---
src/ldb_modules/memberof.c | 10 +++++-----
src/providers/krb5/krb5_utils.c | 2 +-
src/providers/ldap/sdap.c | 2 +-
src/python/pysss.c | 2 +-
src/responder/common/negcache.c | 2 +-
src/responder/nss/nsssrv_mmap_cache.c | 2 +-
src/responder/pam/pamsrv_p11.c | 2 +-
src/tools/tools_util.c | 2 +-
src/util/nscd.c | 6 +++---
9 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/src/ldb_modules/memberof.c b/src/ldb_modules/memberof.c
index 4d7b23ea1b95bed0ec5c7cc717b95e6da3cd0717..83d93196c34854d75fcd8ac91ad056f64b26b659 100644
--- a/src/ldb_modules/memberof.c
+++ b/src/ldb_modules/memberof.c
@@ -411,7 +411,7 @@ static int mbof_add_fill_ghop_ex(struct mbof_add_ctx *add_ctx,
return LDB_SUCCESS;
default:
- /* an error occured, return */
+ /* an error occurred, return */
return ret;
}
@@ -911,7 +911,7 @@ static int mbof_add_operation(struct mbof_add_operation *addop)
break;
default:
- /* an error occured, return */
+ /* an error occurred, return */
return ret;
}
@@ -2133,7 +2133,7 @@ static int mbof_del_mod_entry(struct mbof_del_operation *delop)
is_user = false;
break;
default:
- /* an error occured, return */
+ /* an error occurred, return */
return ret;
}
@@ -2457,7 +2457,7 @@ static int mbof_del_fill_muop(struct mbof_del_ctx *del_ctx,
return LDB_SUCCESS;
default:
- /* an error occured, return */
+ /* an error occurred, return */
return ret;
}
@@ -2520,7 +2520,7 @@ static int mbof_del_fill_ghop_ex(struct mbof_del_ctx *del_ctx,
return LDB_SUCCESS;
default:
- /* an error occured, return */
+ /* an error occurred, return */
return ret;
}
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
index 0b73880eca6015fc9dffa4a850b230afc5dfddfc..7fd490514a52f0bfa3f1ced75f2b6496a77dada6 100644
--- a/src/providers/krb5/krb5_utils.c
+++ b/src/providers/krb5/krb5_utils.c
@@ -386,7 +386,7 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
rerun = true;
continue;
} else if (strncmp(n , S_EXP_EUID, L_EXP_EUID) == 0) {
- /* SSSD does not distinguish betwen uid and euid,
+ /* SSSD does not distinguish between uid and euid,
* so we treat both the same way */
action = 'U';
n += L_EXP_EUID - 1;
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index f9b9ff7e6913c406547f36d341300b936e121693..c0863a6d5bbe4f8f074e25634cb5e236075ce55a 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -1284,7 +1284,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
break;
default:
DEBUG(SSSDBG_CRIT_FAILURE,
- "Unkown error (%d) checking rootdse!\n", ret);
+ "Unknown error (%d) checking rootdse!\n", ret);
}
} else {
if (!entry_usn_name) {
diff --git a/src/python/pysss.c b/src/python/pysss.c
index 50f80421739e579ff94e5b8d1c5b97433b460e06..6bd8f5a9261aefe5b8ca90998e14878dd3896eef 100644
--- a/src/python/pysss.c
+++ b/src/python/pysss.c
@@ -461,7 +461,7 @@ static PyObject *py_sss_usermod(PySssLocalObject *self,
if (lock && lock != DO_LOCK && lock != DO_UNLOCK) {
PyErr_SetString(PyExc_ValueError,
- "Unkown value for lock parameter");
+ "Unknown value for lock parameter");
goto fail;
}
diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index f7af9e0280737f6c89c3034e8b19a6ecd393d355..5b0517ceba85d6e35515a935423412314c218143 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -806,7 +806,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
if (domainname && strcmp(domainname, dom->name)) {
DEBUG(SSSDBG_CRIT_FAILURE,
- "Mismatch betwen domain name (%s) and name "
+ "Mismatch between domain name (%s) and name "
"set in FQN (%s), skipping group %s\n",
dom->name, domainname, name);
continue;
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index 62f4c543c628712810b6dfbc669c586c39ca609d..f7f62733941cd3ae3b071d6d54c801f9be1ce800 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -1348,7 +1348,7 @@ errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem,
if (mc_ctx == NULL || (*mc_ctx) == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE,
- "Unable to re-init unitialized memory cache.\n");
+ "Unable to re-init uninitialized memory cache.\n");
return EINVAL;
}
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index ad1670136dbf8efc41df6950af744ff8b06e6a11..7a8002c2828c14e55ef2d827e37398035a0c6726 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -144,7 +144,7 @@ static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf,
if (buf_len < 0) {
DEBUG(SSSDBG_CRIT_FAILURE,
- "Error occured while reading data from p11_child.\n");
+ "Error occurred while reading data from p11_child.\n");
return EIO;
}
diff --git a/src/tools/tools_util.c b/src/tools/tools_util.c
index 68f6588ea887da6391159fa59916fdece102472b..3112171a6c06a50b7099f1c1b58ea1ad581c7cb3 100644
--- a/src/tools/tools_util.c
+++ b/src/tools/tools_util.c
@@ -324,7 +324,7 @@ fini:
* Check is path is owned by uid
* returns 0 - owns
* -1 - does not own
- * >0 - an error occured, error code
+ * >0 - an error occurred, error code
*/
static int is_owner(uid_t uid, const char *path)
{
diff --git a/src/util/nscd.c b/src/util/nscd.c
index f58aebcad69924bdd841a4bb51aedb0308237ac4..ab29f3d271970911a0c1467b83147ba4774c1ecb 100644
--- a/src/util/nscd.c
+++ b/src/util/nscd.c
@@ -139,7 +139,7 @@ errno_t sss_nscd_parse_conf(const char *conf_path)
{
FILE *fp;
int ret = EOK;
- unsigned int occured = 0;
+ unsigned int occurred = 0;
char *line, *entry, *service, *enabled, *pad;
size_t linelen = 0;
@@ -195,7 +195,7 @@ errno_t sss_nscd_parse_conf(const char *conf_path)
if (!strcmp(entry, "enable-cache") &&
!strcmp(enabled, "yes")) {
- occured |= sss_nscd_check_service(service);
+ occurred |= sss_nscd_check_service(service);
}
};
@@ -209,7 +209,7 @@ errno_t sss_nscd_parse_conf(const char *conf_path)
}
ret = EOK;
- if (occured != 0) {
+ if (occurred != 0) {
ret = EEXIST;
goto done;
}
--
2.5.0

View File

@ -0,0 +1,97 @@
From f468d11fce4257bf3acc07b7f5a8d45cfbe52a60 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 11 Jan 2016 18:54:40 +0100
Subject: [PATCH 69/86] UTIL: Use prefix for debug function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 2a44a8c6683cfea218ee5329bcfad953dfeb6746)
(cherry picked from commit 4772bb86902552cb2fc18c3127b74f8cde5252ea)
---
src/util/debug.c | 12 ++++++------
src/util/sss_semanage.c | 2 +-
src/util/util.h | 16 ++++++++--------
3 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/src/util/debug.c b/src/util/debug.c
index b6ab368db824bbd297dcb410c3e669d911ff0d33..570c80273c0bdda1cc8df0e6af825595cfa339e0 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -206,11 +206,11 @@ journal_done:
}
#endif /* WiTH_JOURNALD */
-void debug_fn(const char *file,
- long line,
- const char *function,
- int level,
- const char *format, ...)
+void sss_debug_fn(const char *file,
+ long line,
+ const char *function,
+ int level,
+ const char *format, ...)
{
va_list ap;
struct timeval tv;
@@ -301,7 +301,7 @@ void ldb_debug_messages(void *context, enum ldb_debug_level level,
}
if (DEBUG_IS_SET(loglevel))
- debug_fn(__FILE__, __LINE__, "ldb", loglevel, "%s\n", message);
+ sss_debug_fn(__FILE__, __LINE__, "ldb", loglevel, "%s\n", message);
free(message);
}
diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c
index d1d03988c05dc011dbd465051d50fe6acca4f845..4fb9df589bbfddcc815ed321b6e3b32655d44a0c 100644
--- a/src/util/sss_semanage.c
+++ b/src/util/sss_semanage.c
@@ -64,7 +64,7 @@ static void sss_semanage_error_callback(void *varg,
}
if (DEBUG_IS_SET(level))
- debug_fn(__FILE__, __LINE__, "libsemanage", level, "%s\n", message);
+ sss_debug_fn(__FILE__, __LINE__, "libsemanage", level, "%s\n", message);
free(message);
}
diff --git a/src/util/util.h b/src/util/util.h
index c0db6779f7f6fae44a5d956ae52a166f0f4eefc6..0b50d5abf6f1651dcf350e2c235702b5a21536d1 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -71,11 +71,11 @@ extern int debug_microseconds;
extern int debug_to_file;
extern int debug_to_stderr;
extern const char *debug_log_file;
-void debug_fn(const char *file,
- long line,
- const char *function,
- int level,
- const char *format, ...) SSS_ATTRIBUTE_PRINTF(5,6);
+void sss_debug_fn(const char *file,
+ long line,
+ const char *function,
+ int level,
+ const char *format, ...) SSS_ATTRIBUTE_PRINTF(5, 6);
int debug_convert_old_level(int old_level);
errno_t set_debug_file_from_fd(const int fd);
int get_fd_from_debug_file(void);
@@ -129,9 +129,9 @@ int get_fd_from_debug_file(void);
#define DEBUG(level, format, ...) do { \
int __debug_macro_level = level; \
if (DEBUG_IS_SET(__debug_macro_level)) { \
- debug_fn(__FILE__, __LINE__, __FUNCTION__, \
- __debug_macro_level, \
- format, ##__VA_ARGS__); \
+ sss_debug_fn(__FILE__, __LINE__, __FUNCTION__, \
+ __debug_macro_level, \
+ format, ##__VA_ARGS__); \
} \
} while (0)
--
2.5.0

View File

@ -0,0 +1,97 @@
From 55928e9989e53b8333ce44cded97ce244b5ce048 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 11 Jan 2016 11:06:22 +0100
Subject: [PATCH 70/86] UTIL: Provide varargs version of debug_fn
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 22bbd95a48d21452fa5bb1a96b43334503bf8132)
(cherry picked from commit c99096a5f0a6e47c50e91ecd9ebbdf2a18195fa8)
---
src/util/debug.c | 29 +++++++++++++++++++----------
src/util/util.h | 6 ++++++
2 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/src/util/debug.c b/src/util/debug.c
index 570c80273c0bdda1cc8df0e6af825595cfa339e0..1b7aef467ff336e3316ab39f3a7d0b22ff3a0ed0 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -206,13 +206,13 @@ journal_done:
}
#endif /* WiTH_JOURNALD */
-void sss_debug_fn(const char *file,
- long line,
- const char *function,
- int level,
- const char *format, ...)
+void sss_vdebug_fn(const char *file,
+ long line,
+ const char *function,
+ int level,
+ const char *format,
+ va_list ap)
{
- va_list ap;
struct timeval tv;
struct tm *tm;
char datetime[20];
@@ -230,10 +230,8 @@ void sss_debug_fn(const char *file,
* can also provide extra structuring data to make it more easily
* searchable.
*/
- va_start(ap, format);
va_copy(ap_fallback, ap);
ret = journal_send(file, line, function, level, format, ap);
- va_end(ap);
if (ret != EOK) {
/* Emergency fallback, send to STDERR */
debug_vprintf(format, ap_fallback);
@@ -266,12 +264,23 @@ void sss_debug_fn(const char *file,
debug_prg_name, function, level);
}
- va_start(ap, format);
debug_vprintf(format, ap);
- va_end(ap);
debug_fflush();
}
+void sss_debug_fn(const char *file,
+ long line,
+ const char *function,
+ int level,
+ const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ sss_vdebug_fn(file, line, function, level, format, ap);
+ va_end(ap);
+}
+
void ldb_debug_messages(void *context, enum ldb_debug_level level,
const char *fmt, va_list ap)
{
diff --git a/src/util/util.h b/src/util/util.h
index 0b50d5abf6f1651dcf350e2c235702b5a21536d1..9b5262995630b1b98f8658b3c32e1b83b0d31307 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -71,6 +71,12 @@ extern int debug_microseconds;
extern int debug_to_file;
extern int debug_to_stderr;
extern const char *debug_log_file;
+void sss_vdebug_fn(const char *file,
+ long line,
+ const char *function,
+ int level,
+ const char *format,
+ va_list ap);
void sss_debug_fn(const char *file,
long line,
const char *function,
--
2.5.0

View File

@ -0,0 +1,84 @@
From 7b06c5415f24fe7d20253b101a6462d1944854d0 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 11 Jan 2016 19:13:06 +0100
Subject: [PATCH 71/86] UTIL: Use sss_vdebug_fn for callbacks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit f6c1f6a561bdd5b4bba03c02988a724da3dad387)
(cherry picked from commit 86ba562d09e1ee9aa55819d748722c2d3ac00600)
---
src/util/debug.c | 13 ++-----------
src/util/sss_semanage.c | 14 +++-----------
2 files changed, 5 insertions(+), 22 deletions(-)
diff --git a/src/util/debug.c b/src/util/debug.c
index 1b7aef467ff336e3316ab39f3a7d0b22ff3a0ed0..03dc26d6d4e976866a3f9395598840e28997f69a 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -285,8 +285,6 @@ void ldb_debug_messages(void *context, enum ldb_debug_level level,
const char *fmt, va_list ap)
{
int loglevel = SSSDBG_UNRESOLVED;
- int ret;
- char * message = NULL;
switch(level) {
case LDB_DEBUG_FATAL:
@@ -303,16 +301,9 @@ void ldb_debug_messages(void *context, enum ldb_debug_level level,
break;
}
- ret = vasprintf(&message, fmt, ap);
- if (ret < 0) {
- /* ENOMEM */
- return;
+ if (DEBUG_IS_SET(loglevel)) {
+ sss_vdebug_fn(__FILE__, __LINE__, "ldb", loglevel, fmt, ap);
}
-
- if (DEBUG_IS_SET(loglevel))
- sss_debug_fn(__FILE__, __LINE__, "ldb", loglevel, "%s\n", message);
-
- free(message);
}
/* In cases SSSD used to run as the root user, but runs as the SSSD user now,
diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c
index 4fb9df589bbfddcc815ed321b6e3b32655d44a0c..7f746491174730acbf1539acaf3f6467ff92afcf 100644
--- a/src/util/sss_semanage.c
+++ b/src/util/sss_semanage.c
@@ -39,8 +39,6 @@ static void sss_semanage_error_callback(void *varg,
const char *fmt, ...)
{
int level = SSSDBG_INVALID;
- int ret;
- char * message = NULL;
va_list ap;
switch (semanage_msg_get_level(handle)) {
@@ -56,16 +54,10 @@ static void sss_semanage_error_callback(void *varg,
}
va_start(ap, fmt);
- ret = vasprintf(&message, fmt, ap);
+ if (DEBUG_IS_SET(level)) {
+ sss_vdebug_fn(__FILE__, __LINE__, "libsemanage", level, fmt, ap);
+ }
va_end(ap);
- if (ret < 0) {
- /* ENOMEM */
- return;
- }
-
- if (DEBUG_IS_SET(level))
- sss_debug_fn(__FILE__, __LINE__, "libsemanage", level, "%s\n", message);
- free(message);
}
static void sss_semanage_close(semanage_handle_t *handle)
--
2.5.0

View File

@ -0,0 +1,75 @@
From 910cd1c35859213319537072c48429e768b53b86 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 25 Jan 2016 11:46:54 +0100
Subject: [PATCH 72/86] Revert "DEBUG: Preventing chown_debug_file if journald
on"
This reverts commit 6e2822b151c21ce6e3287a0cf25d40e9f10a6127.
The function chown_debug_file is called before initialization
of debug stuff in sssd. Therefore variable debug_file cannot be
initialized. Therefore reverted commit completely turned off
changing owner of debug files. Side effect of this change
was that annoying error messages was not logged in case of
journald.
Resolves:
https://fedorahosted.org/sssd/ticket/2938
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 9f1186e7be7ece4d2b9bbbe444d3fc42ab57b808)
---
src/util/debug.c | 35 ++++++++++++++++-------------------
1 file changed, 16 insertions(+), 19 deletions(-)
diff --git a/src/util/debug.c b/src/util/debug.c
index 03dc26d6d4e976866a3f9395598840e28997f69a..d10b456acd14f32590e8b4111596f95a555ac828 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -316,27 +316,24 @@ int chown_debug_file(const char *filename,
const char *log_file;
errno_t ret;
- if (debug_file) {
+ if (filename == NULL) {
+ log_file = debug_log_file;
+ } else {
+ log_file = filename;
+ }
- if (filename == NULL) {
- log_file = debug_log_file;
- } else {
- log_file = filename;
- }
+ ret = asprintf(&logpath, "%s/%s.log", LOG_PATH, log_file);
+ if (ret == -1) {
+ return ENOMEM;
+ }
- ret = asprintf(&logpath, "%s/%s.log", LOG_PATH, log_file);
- if (ret == -1) {
- return ENOMEM;
- }
-
- ret = chown(logpath, uid, gid);
- free(logpath);
- if (ret != 0) {
- ret = errno;
- DEBUG(SSSDBG_FATAL_FAILURE, "chown failed for [%s]: [%d]\n",
- log_file, ret);
- return ret;
- }
+ ret = chown(logpath, uid, gid);
+ free(logpath);
+ if (ret != 0) {
+ ret = errno;
+ DEBUG(SSSDBG_FATAL_FAILURE, "chown failed for [%s]: [%d]\n",
+ log_file, ret);
+ return ret;
}
return EOK;
--
2.5.0

View File

@ -0,0 +1,35 @@
From 214a61d2169329106da654c06a5faaeaf645852d Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Fri, 22 Jan 2016 15:04:48 +0100
Subject: [PATCH 73/86] DEBUG: Ignore ENOENT for change owner of log files
Resolves:
https://fedorahosted.org/sssd/ticket/2493
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit cbb04b9439d73fff027e193093a49cdac3cdb499)
---
src/util/debug.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/util/debug.c b/src/util/debug.c
index d10b456acd14f32590e8b4111596f95a555ac828..a014bc3850641ad1f37c72df5a6181fed8391cfb 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -331,6 +331,13 @@ int chown_debug_file(const char *filename,
free(logpath);
if (ret != 0) {
ret = errno;
+ if (ret == ENOENT) {
+ /* Log does not exist. We might log to journald
+ * or starting for first time.
+ * It's not a failure. */
+ return EOK;
+ }
+
DEBUG(SSSDBG_FATAL_FAILURE, "chown failed for [%s]: [%d]\n",
log_file, ret);
return ret;
--
2.5.0

View File

@ -0,0 +1,39 @@
From dd7a1a508bdc60b62b5ef4ce22fcf31dace3f3c2 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Fri, 19 Feb 2016 16:18:02 +0100
Subject: [PATCH 74/86] TOOLS: Fix minor memory leak in sss_colondb_writeline
The variable line was initialized to NULL.
The we created temporary context tmp_ctx.
We use talloc_asprintf_append to append string to line which is initially
NULL and therefore new context which was not connected to tmp_ctx.
man 3 talloc_string -> talloc_asprintf_append
Reviewed-by: Petr Cech <pcech@redhat.com>
(cherry picked from commit 6977d7c84145ac69195be58b3330861b9b8a3b72)
(cherry picked from commit d75ac50d0c065974a7ec2330f60657ae85e487c0)
---
src/tools/common/sss_colondb.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/tools/common/sss_colondb.c b/src/tools/common/sss_colondb.c
index a41b12fb9c097ff0e03da6d1c5cfe2fb24b63d54..b9af5f7e50c1166ca518a4e342637dc62518c567 100644
--- a/src/tools/common/sss_colondb.c
+++ b/src/tools/common/sss_colondb.c
@@ -198,6 +198,13 @@ errno_t sss_colondb_writeline(struct sss_colondb *db,
return ENOMEM;
}
+ line = talloc_strdup(tmp_ctx, "");
+ if (line == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
for (i = 0; table[i].type != SSS_COLONDB_SENTINEL; i++) {
switch (table[i].type) {
case SSS_COLONDB_UINT32:
--
2.5.0

View File

@ -0,0 +1,47 @@
From 38bd263de5b83710898406640a77c15edea712fe Mon Sep 17 00:00:00 2001
From: Petr Cech <pcech@redhat.com>
Date: Thu, 18 Feb 2016 06:33:53 -0500
Subject: [PATCH 75/86] TOOLS: Fix memory leak after getline() failed
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch fixes buffer freeing in case if getline() failed
in function sss_colondb_readline().
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
If *lineptr is set to NULL and *n is set 0 before the call, then
getline() will allocate a buffer for storing the line. This buffer
should be freed by the user program even if getline() failed.
man 3 getline
This patch fix buffer freeing in case if getline() failed.
Resolves:
https://fedorahosted.org/sssd/ticket/2764
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit 2dd75ea79a57615808754c0ce550786edbc17d69)
(cherry picked from commit 34ba0c53d0d966c64ea11a6269cdd0ad985f4068)
---
src/tools/common/sss_colondb.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/tools/common/sss_colondb.c b/src/tools/common/sss_colondb.c
index b9af5f7e50c1166ca518a4e342637dc62518c567..e8aeb315c9ed0efde15553e2d741d04c5d895b1a 100644
--- a/src/tools/common/sss_colondb.c
+++ b/src/tools/common/sss_colondb.c
@@ -121,6 +121,10 @@ errno_t sss_colondb_readline(TALLOC_CTX *mem_ctx,
readchars = getline(&line, &linelen, db->file);
if (readchars == -1) {
/* Nothing was read. */
+
+ free(line);
+ line = NULL;
+
if (errno != 0) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read line [%d]: %s\n",
--
2.5.0

View File

@ -0,0 +1,74 @@
From 3ca35b1781ef5a1f50c5165882b9ff4cebbbb7ac Mon Sep 17 00:00:00 2001
From: Petr Cech <pcech@redhat.com>
Date: Tue, 24 Nov 2015 10:34:10 -0500
Subject: [PATCH 76/86] TOOLS: Add comments on functions in colondb
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The colondb API provides three function:
* sss_colondb_open()
* sss_colondb_write_field()
* sss_colondb_read_field()
It is not obvious that sss_colondb_open() add destructor on talloc
context which close the colondb during free context. And there is
expectation that SSS_COLONDB_SENTINEL is type of last item in line.
So this patch adds simple lightening comments in doxygen style.
Resolves:
https://fedorahosted.org/sssd/ticket/2764
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit cf1109e30320a994187edeb438ac7cdc36f0dd2b)
(cherry picked from commit fbf7d5683287fa2c7b450b8f5b0df63673f25d83)
---
src/tools/common/sss_colondb.h | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/src/tools/common/sss_colondb.h b/src/tools/common/sss_colondb.h
index 6edd99cbe3b9ef5c86a48632ac3fc71e8a3e55fe..cb9040088c65fdbe35c787b8942aaf1b14a2778d 100644
--- a/src/tools/common/sss_colondb.h
+++ b/src/tools/common/sss_colondb.h
@@ -59,14 +59,37 @@ struct sss_colondb_read_field {
union sss_colondb_read_data data;
};
+/**
+ * Open colon DB and return connection.
+ * @param[in|out] mem_ctx Memory context. Internal sss_colondb_close() is set
+ * on destructor of this memory context.
+ * @param[in] mode Open mode of db: SSS_COLONDB_READ or SSS_COLONDB_WRITE.
+ * @param[in] filename Name of file.
+ * @return Pointer to structure holding DB connection, or NULL if fail.
+ */
struct sss_colondb *sss_colondb_open(TALLOC_CTX *mem_ctx,
enum sss_colondb_mode mode,
const char *filename);
+/**
+ * Read line from colon DB.
+ * @param[in|out] mem_ctx Memory context.
+ * @param[in] db Pointer to structure holding DB connection.
+ * @param[in|out] table Array of expected structure of line. It is expected
+ * that last item has SSS_COLONDB_SENTINEL type.
+ * @return EOK if success, else error code.
+ */
errno_t sss_colondb_readline(TALLOC_CTX *mem_ctx,
struct sss_colondb *db,
struct sss_colondb_read_field *table);
+/**
+ * Write line to colon DB.
+ * @param[in] db Pointer to structure holding DB connection.
+ * @param[in] table Array with data. It is expected that last item has
+ * SSS_COLONDB_SENTINEL type.
+ * @return EOK if success, else error code.
+ */
errno_t sss_colondb_writeline(struct sss_colondb *db,
struct sss_colondb_write_field *table);
--
2.5.0

View File

@ -0,0 +1,504 @@
From eb2ce6f47fd9a676bf5405deda2ccfabc42a437c Mon Sep 17 00:00:00 2001
From: Petr Cech <pcech@redhat.com>
Date: Fri, 27 Nov 2015 06:39:37 -0500
Subject: [PATCH 77/86] TEST_TOOLS_COLONDB: Add tests for sss_colondb_*
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There are three functions at API of colondb wrapper:
* sss_colondb_open()
* sss_colondb_readline()
* sss_colondb_writeline()
This patch adds tests for all of them.
We test those cases:
* open nonexisting file for read
* open nonexisting file for write
* open existing empty file for read
* open existing file with records for read
* open existing empty file for write
* open existing file with records for write
* write to empty file
* write to file with existing records
* sss_colondb_open()
* sss_colondb_readline()
* sss_colondb_write_line()
* write to empty file and read it
Resolves:
https://fedorahosted.org/sssd/ticket/2764
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit b590f44c06158485357d69cc5b24d5af05f1bb95)
(cherry picked from commit b269edafff139510ee1e9c00bdbc8f27e8aea691)
---
Makefile.am | 17 ++
src/tests/cmocka/test_tools_colondb.c | 419 ++++++++++++++++++++++++++++++++++
2 files changed, 436 insertions(+)
create mode 100644 src/tests/cmocka/test_tools_colondb.c
diff --git a/Makefile.am b/Makefile.am
index 22653cfe08ca1fa42f551bdd585868a7e56046ba..9bd5d0ba895bf699c0b9a46f86419adbd266aece 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -241,6 +241,7 @@ if HAVE_CMOCKA
pam-srv-tests \
test_ipa_subdom_util \
test_ipa_subdom_server \
+ test_tools_colondb \
test_krb5_wait_queue \
test_cert_utils \
test_ldap_id_cleanup \
@@ -2579,6 +2580,22 @@ test_ipa_subdom_server_LDADD = \
libdlopen_test_providers.la \
$(NULL)
+test_tools_colondb_SOURCES = \
+ src/tests/cmocka/test_tools_colondb.c \
+ src/tools/common/sss_colondb.c \
+ $(NULL)
+test_tools_colondb_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(NULL)
+test_tools_colondb_LDFLAGS = \
+ $(NULL)
+test_tools_colondb_LDADD = \
+ $(CMOCKA_LIBS) \
+ $(SSSD_INTERNAL_LTLIBS) \
+ $(POPT_LIBS) \
+ libsss_test_common.la \
+ $(NULL)
+
test_krb5_wait_queue_SOURCES = \
src/tests/cmocka/common_mock_be.c \
src/tests/cmocka/test_krb5_wait_queue.c \
diff --git a/src/tests/cmocka/test_tools_colondb.c b/src/tests/cmocka/test_tools_colondb.c
new file mode 100644
index 0000000000000000000000000000000000000000..5aa105896b3690127b5bf3241fe2b27d2ae2f920
--- /dev/null
+++ b/src/tests/cmocka/test_tools_colondb.c
@@ -0,0 +1,419 @@
+/*
+ Authors:
+ Petr Čech <pcech@redhat.com>
+
+ Copyright (C) 2015 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <talloc.h>
+#include <errno.h>
+#include <popt.h>
+
+#include "tests/cmocka/common_mock.h"
+#include "src/tools/common/sss_colondb.h"
+
+#define TESTS_PATH "tp_" BASE_FILE_STEM
+#define TESTS_FILE "test_colondb.ldb"
+
+const char *TEST_STRING1 = "white";
+const int TEST_INT1 = 12;
+
+const char *TEST_STRING2 = "black";
+const int TEST_INT2 = 34;
+
+static void create_dir(const char *path)
+{
+ errno_t ret;
+
+ errno = 0;
+ ret = mkdir(path, 0775);
+ assert_return_code(ret, errno);
+}
+
+static void create_empty_file(TALLOC_CTX *test_ctx, const char *path,
+ const char *name)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ char *file_name = NULL;
+ FILE *fp = NULL;
+
+ tmp_ctx = talloc_new(test_ctx);
+ assert_non_null(tmp_ctx);
+
+ create_dir(path);
+
+ file_name = talloc_asprintf(tmp_ctx, "%s/%s", path, name);
+ assert_non_null(file_name);
+
+ fp = fopen(file_name, "w");
+ assert_non_null(fp);
+ fclose(fp);
+
+ talloc_free(tmp_ctx);
+}
+
+static void create_nonempty_file(TALLOC_CTX *test_ctx,
+ const char *path, const char *name)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ struct sss_colondb *db = NULL;
+ errno_t ret;
+ struct sss_colondb_write_field table[] = {
+ { SSS_COLONDB_STRING, { .str = TEST_STRING2 } },
+ { SSS_COLONDB_UINT32, { .uint32 = TEST_INT2 } },
+ { SSS_COLONDB_SENTINEL, { 0 } }
+ };
+
+ tmp_ctx = talloc_new(test_ctx);
+ assert_non_null(tmp_ctx);
+
+ create_empty_file(test_ctx, TESTS_PATH, TESTS_FILE);
+
+ db = sss_colondb_open(tmp_ctx, SSS_COLONDB_WRITE,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+
+ ret = sss_colondb_writeline(db, table);
+ assert_int_equal(ret, EOK);
+
+ talloc_free(db);
+ talloc_free(tmp_ctx);
+}
+
+static int setup(void **state, int file_state)
+{
+ TALLOC_CTX *test_ctx = NULL;
+
+ assert_true(leak_check_setup());
+
+ check_leaks_push(global_talloc_context);
+ test_ctx = talloc_new(global_talloc_context);
+ assert_non_null(test_ctx);
+
+ switch (file_state) {
+ case 0:
+ break;
+ case 1:
+ create_empty_file(test_ctx, TESTS_PATH, TESTS_FILE);
+ break;
+ case 2:
+ create_nonempty_file(test_ctx, TESTS_PATH, TESTS_FILE);
+ break;
+ default:
+ break;
+ }
+
+ check_leaks_push(test_ctx);
+ *state = test_ctx;
+
+ return 0;
+}
+
+static int without_file_setup(void **state)
+{
+ return setup(state, 0);
+}
+
+static int with_empty_file_setup(void **state)
+{
+ return setup(state, 1);
+}
+
+static int with_nonempty_file_setup(void **state)
+{
+ return setup(state, 2);
+}
+
+static int teardown(void **state)
+{
+ errno_t ret;
+
+ errno = 0;
+ ret = unlink(TESTS_PATH "/" TESTS_FILE);
+ if (ret != 0) {
+ assert_int_equal(errno, ENOENT);
+ }
+
+ assert_true(check_leaks_pop(*state));
+ talloc_zfree(*state);
+
+ test_dom_suite_cleanup(TESTS_PATH, NULL, NULL);
+ assert_true(check_leaks_pop(global_talloc_context));
+ assert_true(leak_check_teardown());
+
+ return 0;
+}
+
+void test_open_nonexist_for_read(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_READ,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_null(db);
+ talloc_free(db);
+}
+
+void test_open_nonexist_for_write(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_null(db);
+ talloc_free(db);
+}
+
+void test_open_exist_for_read(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_READ,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+ talloc_free(db);
+}
+
+void test_open_exist_for_write(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+ talloc_free(db);
+}
+
+void test_open_nonempty_for_read(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_READ,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+ talloc_free(db);
+}
+
+void test_open_nonempty_for_write(void **state)
+{
+
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+ talloc_free(db);
+}
+
+void test_write_to_empty(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+ struct sss_colondb_write_field table[] = {
+ { SSS_COLONDB_STRING, { .str = TEST_STRING1 } },
+ { SSS_COLONDB_UINT32, { .uint32 = TEST_INT1 } },
+ { SSS_COLONDB_SENTINEL, { 0 } }
+ };
+ errno_t ret;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+
+ ret = sss_colondb_writeline(db, table);
+ assert_int_equal(ret, 0);
+
+ talloc_free(db);
+}
+
+void test_write_to_nonempty(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+ struct sss_colondb_write_field table[] = {
+ { SSS_COLONDB_STRING, { .str = TEST_STRING1 } },
+ { SSS_COLONDB_UINT32, { .uint32 = TEST_INT1 } },
+ { SSS_COLONDB_SENTINEL, { 0 } }
+ };
+ errno_t ret;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+
+ ret = sss_colondb_writeline(db, table);
+ assert_int_equal(ret, 0);
+
+ talloc_free(db);
+}
+
+void test_read_from_nonempty(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+ errno_t ret;
+ const char *string = NULL;
+ uint32_t number;
+ struct sss_colondb_read_field table[] = {
+ { SSS_COLONDB_STRING, { .str = &string } },
+ { SSS_COLONDB_UINT32, { .uint32 = &number } },
+ { SSS_COLONDB_SENTINEL, { 0 } }
+ };
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_READ,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+
+ ret = sss_colondb_readline(test_ctx, db, table);
+ assert_int_equal(ret, 0);
+ assert_string_equal(string, TEST_STRING2);
+ assert_int_equal(number, TEST_INT2);
+
+ talloc_zfree(string);
+ talloc_free(db);
+}
+
+void test_read_from_empty(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+ errno_t ret;
+ const char *string;
+ uint32_t number;
+ struct sss_colondb_read_field table[] = {
+ { SSS_COLONDB_STRING, { .str = &string } },
+ { SSS_COLONDB_UINT32, { .uint32 = &number } },
+ { SSS_COLONDB_SENTINEL, { 0 } }
+ };
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_READ,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+
+ ret = sss_colondb_readline(test_ctx, db, table);
+ assert_int_equal(ret, EOF);
+
+ talloc_free(db);
+}
+
+void test_write_read(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+ errno_t ret;
+ const char *string = NULL;
+ uint32_t number;
+ struct sss_colondb_write_field table_in[] = {
+ { SSS_COLONDB_STRING, { .str = TEST_STRING2 } },
+ { SSS_COLONDB_UINT32, { .uint32 = TEST_INT2 } },
+ { SSS_COLONDB_SENTINEL, { 0 } }
+ };
+ struct sss_colondb_read_field table_out[] = {
+ { SSS_COLONDB_STRING, { .str = &string } },
+ { SSS_COLONDB_UINT32, { .uint32 = &number } },
+ { SSS_COLONDB_SENTINEL, { 0 } }
+ };
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+
+ ret = sss_colondb_writeline(db, table_in);
+ assert_int_equal(ret, 0);
+
+ talloc_free(db);
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_READ,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+
+ ret = sss_colondb_readline(test_ctx, db, table_out);
+ assert_int_equal(ret, 0);
+ assert_string_equal(string, TEST_STRING2);
+ assert_int_equal(number, TEST_INT2);
+
+ talloc_zfree(string);
+ talloc_free(db);
+}
+
+int main(int argc, const char *argv[])
+{
+ poptContext pc;
+ int opt;
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ SSSD_DEBUG_OPTS
+ POPT_TABLEEND
+ };
+
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(test_open_nonexist_for_read,
+ without_file_setup, teardown),
+ cmocka_unit_test_setup_teardown(test_open_nonexist_for_write,
+ without_file_setup, teardown),
+ cmocka_unit_test_setup_teardown(test_open_exist_for_read,
+ with_empty_file_setup, teardown),
+ cmocka_unit_test_setup_teardown(test_open_exist_for_write,
+ with_empty_file_setup, teardown),
+ cmocka_unit_test_setup_teardown(test_open_nonempty_for_read,
+ with_nonempty_file_setup, teardown),
+ cmocka_unit_test_setup_teardown(test_open_nonempty_for_write,
+ with_nonempty_file_setup, teardown),
+
+ cmocka_unit_test_setup_teardown(test_write_to_empty,
+ with_empty_file_setup, teardown),
+ cmocka_unit_test_setup_teardown(test_write_to_nonempty,
+ with_nonempty_file_setup, teardown),
+
+ cmocka_unit_test_setup_teardown(test_read_from_empty,
+ with_empty_file_setup, teardown),
+ cmocka_unit_test_setup_teardown(test_read_from_nonempty,
+ with_nonempty_file_setup, teardown),
+
+ cmocka_unit_test_setup_teardown(test_write_read,
+ with_empty_file_setup, teardown),
+ };
+
+ /* Set debug level to invalid value so we can decide if -d 0 was used. */
+ debug_level = SSSDBG_INVALID;
+
+ pc = poptGetContext(argv[0], argc, argv, long_options, 0);
+ while ((opt = poptGetNextOpt(pc)) != -1) {
+ switch (opt) {
+ default:
+ fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0),
+ poptStrerror(opt));
+ poptPrintUsage(pc, stderr, 0);
+ return 1;
+ }
+ }
+ poptFreeContext(pc);
+
+ DEBUG_CLI_INIT(debug_level);
+
+ /* Even though normally the tests should clean up after themselves
+ * they might not after a failed run. Remove the old db to be sure */
+ tests_set_cwd();
+ test_dom_suite_cleanup(TESTS_PATH, NULL, NULL);
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
--
2.5.0

View File

@ -0,0 +1,178 @@
From 7dcecb5e2fb9fe83c3bbf52306e7c2b0365ff96d Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 25 Jan 2016 16:03:23 +0100
Subject: [PATCH 78/86] Add a new option ldap_group_external_member
Required for:
https://fedorahosted.org/sssd/ticket/2522
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 3cf7fdfcaedb986f42a6640e26aa057007b64045)
(cherry picked from commit 7db3bdfd6b1b845866c1ff062d25de5804141e89)
---
src/config/SSSDConfig/__init__.py.in | 1 +
src/config/etc/sssd.api.d/sssd-ad.conf | 1 +
src/config/etc/sssd.api.d/sssd-ipa.conf | 1 +
src/config/etc/sssd.api.d/sssd-ldap.conf | 1 +
src/db/sysdb.h | 1 +
src/man/sssd-ldap.5.xml | 16 ++++++++++++++++
src/providers/ad/ad_opts.c | 1 +
src/providers/ipa/ipa_opts.c | 1 +
src/providers/ldap/ldap_opts.c | 3 +++
src/providers/ldap/sdap.h | 1 +
10 files changed, 27 insertions(+)
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 09284fdd7c8e630b3745367b33b8ea0424ff466f..a400c831eb0e44f562c010f2a3649def21913287 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -333,6 +333,7 @@ option_strings = {
'ldap_group_objectsid' : _("objectSID attribute"),
'ldap_group_modify_timestamp' : _('Modification time attribute for groups'),
'ldap_group_type' : _('Type of the group and other flags'),
+ 'ldap_group_external_member' : _('The LDAP group external member attribute'),
#replaced by ldap_entry_usn# 'ldap_group_entry_usn' : _('entryUSN attribute'),
'ldap_group_nesting_level' : _('Maximum nesting level SSSd will follow'),
diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
index 149590f4f30de3438f2fc5534ae65c98ee0f10ad..23006d26ca6fe7ca2b912ef091b4c73d5d23bee1 100644
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
@@ -110,6 +110,7 @@ ldap_group_objectsid = str, None, false
ldap_group_modify_timestamp = str, None, false
ldap_group_entry_usn = str, None, false
ldap_group_type = int, None, false
+ldap_group_external_member = str, None, false
ldap_force_upper_case_realm = bool, None, false
ldap_group_nesting_level = int, None, false
ldap_netgroup_search_base = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index 822599db6390ad2244a71db770c0b162345a3321..8cd20c0c621a513ca7bc85be6908de41d024b148 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -104,6 +104,7 @@ ldap_group_objectsid = str, None, false
ldap_group_modify_timestamp = str, None, false
ldap_group_entry_usn = str, None, false
ldap_group_type = int, None, false
+ldap_group_external_member = str, None, false
ldap_force_upper_case_realm = bool, None, false
ldap_group_nesting_level = int, None, false
ldap_netgroup_search_base = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
index fc9fcefce94891760a3f3ada4c044dbcaf156945..8b52f268af195bc68d45389cda52a0ad0aba1aa3 100644
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
@@ -98,6 +98,7 @@ ldap_group_objectsid = str, None, false
ldap_group_modify_timestamp = str, None, false
ldap_group_entry_usn = str, None, false
ldap_group_type = int, None, false
+ldap_group_external_member = str, None, false
ldap_group_nesting_level = int, None, false
ldap_force_upper_case_realm = bool, None, false
ldap_netgroup_search_base = str, None, false
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 2e797fd7fa39163c2ab6a10e51228e0f1af3f9e3..95a9086766228a6c36c56d3a68a0bb0e493c0cbe 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -81,6 +81,7 @@
#define SYSDB_USER_CATEGORY "userCategory"
#define SYSDB_HOST_CATEGORY "hostCategory"
#define SYSDB_GROUP_TYPE "groupType"
+#define SYSDB_EXTERNAL_MEMBER "externalMember"
#define SYSDB_GECOS "gecos"
#define SYSDB_LAST_LOGIN "lastLogin"
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index 66b9024bcdc6faced67c4e44f9cde7caa9a5ecc8..a30100408c6e77f9156878cb6ff63dfbf7b041d1 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -942,6 +942,22 @@
</varlistentry>
<varlistentry>
+ <term>ldap_group_external_member (string)</term>
+ <listitem>
+ <para>
+ The LDAP attribute that references group
+ members that are defined in an external
+ domain. At the moment, only IPA's external
+ members are supported.
+ </para>
+ <para>
+ Default: ipaExternalMember in the IPA provider,
+ otherwise unset.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>ldap_group_nesting_level (integer)</term>
<listitem>
<para>
diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c
index 28d4768b20bd035f7c1971c95f9b6b690844816e..15024adb7959de9e16cdc92ca30daa74bb5f648d 100644
--- a/src/providers/ad/ad_opts.c
+++ b/src/providers/ad/ad_opts.c
@@ -233,6 +233,7 @@ struct sdap_attr_map ad_2008r2_group_map[] = {
{ "ldap_group_modify_timestamp", "whenChanged", SYSDB_ORIG_MODSTAMP, NULL },
{ "ldap_group_entry_usn", SDAP_AD_USN, SYSDB_USN, NULL },
{ "ldap_group_type", "groupType", SYSDB_GROUP_TYPE, NULL },
+ { "ldap_group_external_member", NULL, SYSDB_EXTERNAL_MEMBER, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c
index cd87852e5891fd43d7ec728f76860f3050a54d2f..fe469852b527ad872502b3346c8c11ef9eea3bcd 100644
--- a/src/providers/ipa/ipa_opts.c
+++ b/src/providers/ipa/ipa_opts.c
@@ -219,6 +219,7 @@ struct sdap_attr_map ipa_group_map[] = {
{ "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
{ "ldap_group_entry_usn", NULL, SYSDB_USN, NULL },
{ "ldap_group_type", NULL, SYSDB_GROUP_TYPE, NULL },
+ { "ldap_group_external_member", "ipaExternalMember", SYSDB_EXTERNAL_MEMBER, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
diff --git a/src/providers/ldap/ldap_opts.c b/src/providers/ldap/ldap_opts.c
index 84ba2b54271bcb6650e0336131ace8bfc1a40fc8..ff9bf0d8b6d4a8f677e08219e5105e3750b7a4a8 100644
--- a/src/providers/ldap/ldap_opts.c
+++ b/src/providers/ldap/ldap_opts.c
@@ -195,6 +195,7 @@ struct sdap_attr_map rfc2307_group_map[] = {
{ "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
{ "ldap_group_entry_usn", NULL, SYSDB_USN, NULL },
{ "ldap_group_type", NULL, SYSDB_GROUP_TYPE, NULL },
+ { "ldap_group_external_member", NULL, SYSDB_EXTERNAL_MEMBER, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
@@ -251,6 +252,7 @@ struct sdap_attr_map rfc2307bis_group_map[] = {
{ "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
{ "ldap_group_entry_usn", NULL, SYSDB_USN, NULL },
{ "ldap_group_type", NULL, SYSDB_GROUP_TYPE, NULL },
+ { "ldap_group_external_member", NULL, SYSDB_EXTERNAL_MEMBER, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
@@ -307,6 +309,7 @@ struct sdap_attr_map gen_ad2008r2_group_map[] = {
{ "ldap_group_modify_timestamp", "whenChanged", SYSDB_ORIG_MODSTAMP, NULL },
{ "ldap_group_entry_usn", SDAP_AD_USN, SYSDB_USN, NULL },
{ "ldap_group_type", "groupType", SYSDB_GROUP_TYPE, NULL },
+ { "ldap_group_external_member", NULL, SYSDB_EXTERNAL_MEMBER, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index e06f2b6ac47990f21985fb86f8ad3f3ae5a74df3..9dc2e16a0da76246a1f4492cf70e9124edba4a31 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -304,6 +304,7 @@ enum sdap_group_attrs {
SDAP_AT_GROUP_MODSTAMP,
SDAP_AT_GROUP_USN,
SDAP_AT_GROUP_TYPE,
+ SDAP_AT_GROUP_EXT_MEMBER,
SDAP_OPTS_GROUP /* attrs counter */
};
--
2.5.0

View File

@ -0,0 +1,446 @@
From 3725d2a83ae64be47c1bb645933f3a2abc91bd08 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 25 Jan 2016 16:11:59 +0100
Subject: [PATCH 79/86] IPA: Add interface to call into IPA provider from LDAP
provider
https://fedorahosted.org/sssd/ticket/2522
Adds a pluggable interface that is able to resolve the IPA group's
external members. At the moment, the request calls the full be_
interface to make sure all corner cases like id-views are handled
internally.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit e2d96566aeb881bd89e5c9236d663f6a9a88019a)
(cherry picked from commit 00ee45423f0712b83926c6f8b354a1a18ff741c8)
---
src/providers/ipa/ipa_id.c | 5 +-
src/providers/ipa/ipa_init.c | 28 +++
src/providers/ipa/ipa_subdomains.h | 11 ++
src/providers/ipa/ipa_subdomains_ext_groups.c | 275 ++++++++++++++++++++++++++
src/providers/ipa/ipa_subdomains_id.c | 1 +
src/providers/ldap/sdap.h | 23 +++
6 files changed, 342 insertions(+), 1 deletion(-)
diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c
index 27cc2548d8802c81311c6c5bd10a0db4e8930fa1..29e22982c415220c931f0422e10cd06dfa1a195b 100644
--- a/src/providers/ipa/ipa_id.c
+++ b/src/providers/ipa/ipa_id.c
@@ -405,7 +405,10 @@ static int ipa_initgr_get_overrides_step(struct tevent_req *req)
/* This should never happen, the search filter used to get the list
* of groups includes "uuid=*"
*/
- DEBUG(SSSDBG_OP_FAILURE, "A group with no UUID, error!\n");
+ DEBUG(SSSDBG_OP_FAILURE,
+ "The group %s has no UUID attribute %s, error!\n",
+ ldb_dn_get_linearized(state->groups[state->group_idx]->dn),
+ state->groups_id_attr);
return EINVAL;
}
diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
index 0e16dd97c78a087256fb77be500c9741484867c5..453e2b25673ac709c9fa3809d35b7885630c8b24 100644
--- a/src/providers/ipa/ipa_init.c
+++ b/src/providers/ipa/ipa_init.c
@@ -139,6 +139,24 @@ int common_ipa_init(struct be_ctx *bectx)
return EOK;
}
+static struct sdap_ext_member_ctx *
+ipa_create_ext_members_ctx(TALLOC_CTX *mem_ctx,
+ struct ipa_id_ctx *id_ctx)
+{
+ struct sdap_ext_member_ctx *ext_ctx = NULL;
+
+ ext_ctx = talloc_zero(mem_ctx, struct sdap_ext_member_ctx);
+ if (ext_ctx == NULL) {
+ return NULL;
+ }
+
+ ext_ctx->pvt = id_ctx;
+ ext_ctx->ext_member_resolve_send = ipa_ext_group_member_send;
+ ext_ctx->ext_member_resolve_recv = ipa_ext_group_member_recv;
+
+ return ext_ctx;
+}
+
int sssm_ipa_id_init(struct be_ctx *bectx,
struct bet_ops **ops,
void **pvt_data)
@@ -360,6 +378,16 @@ int sssm_ipa_id_init(struct be_ctx *bectx,
"will not work [%d]: %s\n", ret, strerror(ret));
}
+ ipa_ctx->sdap_id_ctx->opts->ext_ctx = ipa_create_ext_members_ctx(
+ ipa_ctx->sdap_id_ctx->opts,
+ ipa_ctx);
+ if (ipa_ctx->sdap_id_ctx->opts->ext_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Unable to set SRV the extrernal group ctx\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
*ops = &ipa_id_ops;
*pvt_data = ipa_ctx;
ret = EOK;
diff --git a/src/providers/ipa/ipa_subdomains.h b/src/providers/ipa/ipa_subdomains.h
index 0c13f8ed2eeda87237dfb097f532c7137095ddf1..23c3b7e3cd3ee1e0ac1dbcf98dc71a6c2337b835 100644
--- a/src/providers/ipa/ipa_subdomains.h
+++ b/src/providers/ipa/ipa_subdomains.h
@@ -137,4 +137,15 @@ struct tevent_req *ipa_get_ad_memberships_send(TALLOC_CTX *mem_ctx,
const char *domain);
errno_t ipa_get_ad_memberships_recv(struct tevent_req *req, int *dp_error_out);
+
+struct tevent_req *ipa_ext_group_member_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ const char *ext_member,
+ void *pvt);
+errno_t ipa_ext_group_member_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req,
+ enum sysdb_member_type *_member_type,
+ struct sss_domain_info **_dom,
+ struct sysdb_attrs **_member);
+
#endif /* _IPA_SUBDOMAINS_H_ */
diff --git a/src/providers/ipa/ipa_subdomains_ext_groups.c b/src/providers/ipa/ipa_subdomains_ext_groups.c
index d487a58b8adffabe09ff50e31cb750b800b1d252..5dc6d0d6417ec3fb5e7865e4cbaf3c07f4afbd07 100644
--- a/src/providers/ipa/ipa_subdomains_ext_groups.c
+++ b/src/providers/ipa/ipa_subdomains_ext_groups.c
@@ -923,3 +923,278 @@ static errno_t ipa_add_ad_memberships_recv(struct tevent_req *req,
return EOK;
}
+
+static errno_t
+search_user_or_group_by_sid_str(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *sid_str,
+ enum sysdb_member_type *_member_type,
+ struct ldb_message **_msg)
+{
+ errno_t ret;
+ struct ldb_message *msg = NULL;
+ const char *attrs[] = { SYSDB_NAME,
+ SYSDB_SID_STR,
+ SYSDB_ORIG_DN,
+ SYSDB_OBJECTCLASS,
+ SYSDB_CACHE_EXPIRE,
+ NULL };
+ TALLOC_CTX *tmp_ctx = NULL;
+ char *sanitized_sid = NULL;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+ return ENOMEM;
+ }
+
+ /* In theory SID shouldn't contain any special LDAP characters, but let's
+ * be paranoid
+ */
+ ret = sss_filter_sanitize(tmp_ctx, sid_str, &sanitized_sid);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = sysdb_search_user_by_sid_str(tmp_ctx, domain,
+ sid_str, attrs, &msg);
+ if (ret == EOK) {
+ *_member_type = SYSDB_MEMBER_USER;
+ } else if (ret == ENOENT) {
+ ret = sysdb_search_group_by_sid_str(tmp_ctx, domain,
+ sid_str, attrs, &msg);
+ if (ret == EOK) {
+ *_member_type = SYSDB_MEMBER_GROUP;
+ }
+ }
+
+ switch (ret) {
+ case EOK:
+ DEBUG(SSSDBG_TRACE_FUNC, "Found %s in sysdb\n", sid_str);
+ *_msg = talloc_steal(mem_ctx, msg);
+ break;
+ case ENOENT:
+ DEBUG(SSSDBG_TRACE_FUNC,
+ "Could not find %s in sysdb", sid_str);
+ break;
+ default:
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Error looking for %s in sysdb [%d]: %s\n",
+ sid_str, ret, sss_strerror(ret));
+ break;
+ }
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+static errno_t
+ipa_ext_group_member_check(TALLOC_CTX *mem_ctx,
+ struct ipa_id_ctx *ipa_ctx,
+ struct sss_domain_info *member_dom,
+ const char *ext_member,
+ enum sysdb_member_type *_member_type,
+ struct sysdb_attrs **_member)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ errno_t ret;
+ uint64_t expire;
+ time_t now = time(NULL);
+ struct ldb_message *msg;
+ struct sysdb_attrs **members;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+ return ENOMEM;
+ }
+
+ ret = search_user_or_group_by_sid_str(tmp_ctx, member_dom, ext_member,
+ _member_type, &msg);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Error looking up sid %s: [%d]: %s\n",
+ ext_member, ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = sysdb_msg2attrs(tmp_ctx, 1, &msg, &members);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Could not convert result to sysdb_attrs [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ /* Return the member both expired and valid */
+ *_member = talloc_steal(mem_ctx, members[0]);
+
+ expire = ldb_msg_find_attr_as_uint64(msg, SYSDB_CACHE_EXPIRE, 0);
+ if (expire != 0 && expire <= now) {
+ DEBUG(SSSDBG_TRACE_FUNC, "%s is expired", ext_member);
+ ret = EAGAIN;
+ goto done;
+ }
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+/* For the IPA external member resolution, we expect a SID as the input.
+ * The _recv() function output is the member and a type (user/group)
+ * since nothing else can be a group member.
+ */
+struct ipa_ext_member_state {
+ const char *ext_member;
+ struct sss_domain_info *dom;
+
+ enum sysdb_member_type member_type;
+ struct sysdb_attrs *member;
+};
+
+static void ipa_ext_group_member_done(struct tevent_req *subreq);
+
+struct tevent_req *ipa_ext_group_member_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ const char *ext_member,
+ void *pvt)
+{
+ struct ipa_id_ctx *ipa_ctx;
+ struct ipa_ext_member_state *state;
+ struct tevent_req *req;
+ struct tevent_req *subreq;
+ struct be_acct_req *ar;
+ errno_t ret;
+
+ req = tevent_req_create(mem_ctx, &state, struct ipa_ext_member_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->ext_member = ext_member;
+
+ ipa_ctx = talloc_get_type(pvt, struct ipa_id_ctx);
+ if (ipa_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Wrong private context!\n");
+ ret = EINVAL;
+ goto immediate;
+ }
+
+ state->dom = find_domain_by_sid(ipa_ctx->sdap_id_ctx->be->domain,
+ ext_member);
+ if (state->dom == NULL) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Cannot find domain of SID [%s]\n", ext_member);
+ ret = ENOENT;
+ goto immediate;
+ }
+
+ ret = ipa_ext_group_member_check(state, ipa_ctx, state->dom, ext_member,
+ &state->member_type, &state->member);
+ if (ret == EOK) {
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ "external member %s already cached\n", ext_member);
+ goto immediate;
+ }
+
+ ret = get_be_acct_req_for_sid(state, ext_member, state->dom->name, &ar);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Cannot create the account request for [%s]\n", ext_member);
+ goto immediate;
+ }
+
+ subreq = be_get_account_info_send(state, ev, NULL,
+ ipa_ctx->sdap_id_ctx->be, ar);
+ if (subreq == NULL) {
+ ret = ENOMEM;
+ goto immediate;
+ }
+ tevent_req_set_callback(subreq, ipa_ext_group_member_done, req);
+
+ return req;
+
+immediate:
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ } else {
+ tevent_req_done(req);
+ }
+ tevent_req_post(req, ev);
+ return req;
+}
+
+static void ipa_ext_group_member_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct ipa_ext_member_state *state = tevent_req_data(req,
+ struct ipa_ext_member_state);
+ errno_t ret;
+ int err_maj;
+ int err_min;
+ const char *err_msg;
+ struct ldb_message *msg;
+ struct sysdb_attrs **members;
+
+ ret = be_get_account_info_recv(subreq, state,
+ &err_maj, &err_min, &err_msg);
+ talloc_free(subreq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "be request failed %d:%d: %s\n", err_maj, err_min, err_msg);
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ ret = search_user_or_group_by_sid_str(state,
+ state->dom,
+ state->ext_member,
+ &state->member_type,
+ &msg);
+ if (ret != EOK) {
+ DEBUG(ret == ENOENT ? SSSDBG_TRACE_FUNC : SSSDBG_OP_FAILURE,
+ "Could not find %s in sysdb [%d]: %s\n",
+ state->ext_member, ret, sss_strerror(ret));
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ ret = sysdb_msg2attrs(state, 1, &msg, &members);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Could not convert result to sysdb_attrs [%d]: %s\n",
+ ret, sss_strerror(ret));
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ state->member = members[0];
+ tevent_req_done(req);
+}
+
+errno_t ipa_ext_group_member_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req,
+ enum sysdb_member_type *_member_type,
+ struct sss_domain_info **_dom,
+ struct sysdb_attrs **_member)
+{
+ struct ipa_ext_member_state *state = tevent_req_data(req,
+ struct ipa_ext_member_state);
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ if (_member_type != NULL) {
+ *_member_type = state->member_type;
+ }
+
+ if (_dom) {
+ *_dom = state->dom;
+ }
+
+ if (_member != NULL) {
+ *_member = talloc_steal(mem_ctx, state->member);
+ }
+
+ return EOK;
+}
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
index 472985d4ab4f785aa9c4af94bf8021829ca1c3c8..70a1b6a12799b5a645bbf69f8cc19c30dcff82c5 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -1230,6 +1230,7 @@ static errno_t ipa_get_ad_apply_override_step(struct tevent_req *req)
* attributes set, i.e. where overrides might not have been applied. */
ret = sysdb_asq_search(state, state->obj_dom, state->obj_msg->dn,
"(&("SYSDB_GC")("SYSDB_GIDNUM"=*)" \
+ "("SYSDB_POSIX"=TRUE)" \
"(!("ORIGINALAD_PREFIX SYSDB_GIDNUM"=*))" \
"(!("ORIGINALAD_PREFIX SYSDB_NAME"=*)))",
SYSDB_INITGR_ATTR,
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 9dc2e16a0da76246a1f4492cf70e9124edba4a31..e0e05da0c8270a8f131870bc755da862e43783cb 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -423,6 +423,26 @@ struct sdap_domain {
void *pvt;
};
+typedef struct tevent_req *
+(*ext_member_send_fn_t)(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ const char *ext_member,
+ void *pvt);
+typedef errno_t
+(*ext_member_recv_fn_t)(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req,
+ enum sysdb_member_type *member_type,
+ struct sss_domain_info **_dom,
+ struct sysdb_attrs **_member);
+
+struct sdap_ext_member_ctx {
+ /* Typically ID context of the external ID provider */
+ void *pvt;
+
+ ext_member_send_fn_t ext_member_resolve_send;
+ ext_member_recv_fn_t ext_member_resolve_recv;
+};
+
struct sdap_options {
struct dp_option *basic;
struct sdap_attr_map *gen_map;
@@ -435,6 +455,9 @@ struct sdap_options {
/* ID-mapping support */
struct sdap_idmap_ctx *idmap_ctx;
+ /* Resolving external members */
+ struct sdap_ext_member_ctx *ext_ctx;
+
/* FIXME - should this go to a special struct to avoid mixing with name-service-switch maps? */
struct sdap_attr_map *sudorule_map;
struct sdap_attr_map *autofs_mobject_map;
--
2.5.0

View File

@ -0,0 +1,913 @@
From 78e95161eb7e27f2160d47580c650930db42b5e8 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 25 Jan 2016 16:13:03 +0100
Subject: [PATCH 80/86] LDAP: Use the IPA provider interface to resolve
external group members
Resolves:
https://fedorahosted.org/sssd/ticket/2522
Currently the approach is not optimized for performance, because each
external member is resolved in a full transaction to make sure even ID
views and similar information is processed.
In future, we should implement https://fedorahosted.org/sssd/ticket/2943
we will again be able to process all the data in a single transaction.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3e)
(cherry picked from commit 19194cb18a1cc20f02423861dd831aa5bc3a1003)
---
src/providers/ldap/sdap_async_groups.c | 49 +-
src/providers/ldap/sdap_async_nested_groups.c | 615 +++++++++++++++++++++++++-
src/providers/ldap/sdap_async_private.h | 16 +-
src/tests/cmocka/test_nested_groups.c | 4 +-
4 files changed, 656 insertions(+), 28 deletions(-)
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index 31e0b86a94f1c3969c8fcafe463c591423a835f0..3c274bfccbe65aac9a7ce0fac55839fe05840b79 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -1758,6 +1758,7 @@ struct sdap_get_groups_state {
struct sysdb_attrs **groups;
size_t count;
size_t check_count;
+ hash_table_t *missing_external;
hash_table_t *user_hash;
hash_table_t *group_hash;
@@ -2333,6 +2334,8 @@ int sdap_get_groups_recv(struct tevent_req *req,
return EOK;
}
+static void sdap_nested_ext_done(struct tevent_req *subreq);
+
static void sdap_nested_done(struct tevent_req *subreq)
{
errno_t ret, tret;
@@ -2348,7 +2351,8 @@ static void sdap_nested_done(struct tevent_req *subreq)
struct sdap_get_groups_state);
ret = sdap_nested_group_recv(state, subreq, &user_count, &users,
- &group_count, &groups);
+ &group_count, &groups,
+ &state->missing_external);
talloc_zfree(subreq);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Nested group processing failed: [%d][%s]\n",
@@ -2387,8 +2391,25 @@ static void sdap_nested_done(struct tevent_req *subreq)
}
in_transaction = false;
- /* Processing complete */
- tevent_req_done(req);
+ if (hash_count(state->missing_external) == 0) {
+ /* No external members. Processing complete */
+ DEBUG(SSSDBG_TRACE_INTERNAL, "No external members, done");
+ tevent_req_done(req);
+ return;
+ }
+
+ /* At the moment, we need to save the direct groups & members in one
+ * transaction and then query the others in a separate requests
+ */
+ subreq = sdap_nested_group_lookup_external_send(state, state->ev,
+ state->dom,
+ state->opts->ext_ctx,
+ state->missing_external);
+ if (subreq == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ tevent_req_set_callback(subreq, sdap_nested_ext_done, req);
return;
fail:
@@ -2401,6 +2422,28 @@ fail:
tevent_req_error(req, ret);
}
+static void sdap_nested_ext_done(struct tevent_req *subreq)
+{
+ errno_t ret;
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct sdap_get_groups_state *state = tevent_req_data(req,
+ struct sdap_get_groups_state);
+
+ ret = sdap_nested_group_lookup_external_recv(state, subreq);
+ talloc_free(subreq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Cannot resolve external members [%d]: %s\n",
+ ret, sss_strerror(ret));
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ tevent_req_done(req);
+ return;
+}
+
static errno_t sdap_nested_group_populate_users(TALLOC_CTX *mem_ctx,
struct sysdb_ctx *sysdb,
struct sss_domain_info *domain,
diff --git a/src/providers/ldap/sdap_async_nested_groups.c b/src/providers/ldap/sdap_async_nested_groups.c
index 9d715225243d8672850563473bd3938d4cc5db6b..f0d04fa0948abd58470785d07b8d42f3cfeb9eb0 100644
--- a/src/providers/ldap/sdap_async_nested_groups.c
+++ b/src/providers/ldap/sdap_async_nested_groups.c
@@ -56,6 +56,13 @@ struct sdap_nested_group_member {
const char *group_filter;
};
+const size_t external_members_chunk = 16;
+
+struct sdap_external_missing_member {
+ const char **parent_group_dns;
+ size_t parent_dn_idx;
+};
+
struct sdap_nested_group_ctx {
struct sss_domain_info *domain;
struct sdap_options *opts;
@@ -64,6 +71,7 @@ struct sdap_nested_group_ctx {
struct sdap_handle *sh;
hash_table_t *users;
hash_table_t *groups;
+ hash_table_t *missing_external;
bool try_deref;
int deref_treshold;
int max_nesting_level;
@@ -184,37 +192,32 @@ done:
return ret;
}
-static errno_t sdap_nested_group_hash_entry(hash_table_t *table,
- struct sysdb_attrs *entry,
- const char *table_name)
+static errno_t sdap_nested_group_hash_insert(hash_table_t *table,
+ const char *entry_key,
+ void *entry_value,
+ bool overwrite,
+ const char *table_name)
{
hash_key_t key;
hash_value_t value;
- const char *name = NULL;
- errno_t ret;
int hret;
- ret = sysdb_attrs_get_string(entry, SYSDB_ORIG_DN, &name);
- if (ret != EOK) {
- return ret;
- }
-
DEBUG(SSSDBG_TRACE_ALL, "Inserting [%s] into hash table [%s]\n",
- name, table_name);
+ entry_key, table_name);
key.type = HASH_KEY_STRING;
- key.str = talloc_strdup(NULL, name);
+ key.str = talloc_strdup(NULL, entry_key);
if (key.str == NULL) {
return ENOMEM;
}
- if (hash_has_key(table, &key)) {
+ if (overwrite == false && hash_has_key(table, &key)) {
talloc_free(key.str);
return EEXIST;
}
value.type = HASH_VALUE_PTR;
- value.ptr = entry;
+ value.ptr = entry_value;
hret = hash_enter(table, &key, &value);
if (hret != HASH_SUCCESS) {
@@ -228,6 +231,21 @@ static errno_t sdap_nested_group_hash_entry(hash_table_t *table,
return EOK;
}
+static errno_t sdap_nested_group_hash_entry(hash_table_t *table,
+ struct sysdb_attrs *entry,
+ const char *table_name)
+{
+ const char *name = NULL;
+ errno_t ret;
+
+ ret = sysdb_attrs_get_string(entry, SYSDB_ORIG_DN, &name);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ return sdap_nested_group_hash_insert(table, name, entry, false, table_name);
+}
+
static errno_t
sdap_nested_group_hash_user(struct sdap_nested_group_ctx *group_ctx,
struct sysdb_attrs *user)
@@ -297,6 +315,76 @@ sdap_nested_group_hash_group(struct sdap_nested_group_ctx *group_ctx,
return sdap_nested_group_hash_entry(group_ctx->groups, group, "groups");
}
+static errno_t sdap_nested_group_external_add(hash_table_t *table,
+ const char *ext_member,
+ const char *parent_group_dn)
+{
+ hash_key_t key;
+ hash_value_t value;
+ int hret;
+ int ret;
+ struct sdap_external_missing_member *ext_mem;
+
+ key.type = HASH_KEY_STRING;
+ key.str = discard_const(ext_member);
+
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Inserting external member [%s] into external members hash table\n",
+ ext_member);
+
+ hret = hash_lookup(table, &key, &value);
+ switch (hret) {
+ case HASH_ERROR_KEY_NOT_FOUND:
+ ext_mem = talloc_zero(table, struct sdap_external_missing_member);
+ if (ext_mem == NULL) {
+ return ENOMEM;
+ }
+ ext_mem->parent_group_dns = talloc_zero_array(ext_mem,
+ const char *,
+ external_members_chunk);
+ if (ext_mem->parent_group_dns == NULL) {
+ talloc_free(ext_mem);
+ return ENOMEM;
+ }
+
+ ret = sdap_nested_group_hash_insert(table, ext_member, ext_mem,
+ true, "missing external users");
+ if (ret != EOK) {
+ return ret;
+ }
+ break;
+
+ case HASH_SUCCESS:
+ ext_mem = talloc_get_type(value.ptr,
+ struct sdap_external_missing_member);
+ if (ext_mem->parent_dn_idx == \
+ talloc_array_length(ext_mem->parent_group_dns)) {
+ ext_mem->parent_group_dns = talloc_realloc(ext_mem,
+ ext_mem->parent_group_dns,
+ const char *,
+ ext_mem->parent_dn_idx + \
+ external_members_chunk);
+ if (ext_mem->parent_group_dns == NULL) {
+ talloc_free(ext_mem);
+ return ENOMEM;
+ }
+ }
+ break;
+ default:
+ return EIO;
+ }
+
+ ext_mem->parent_group_dns[ext_mem->parent_dn_idx] = \
+ talloc_strdup(ext_mem->parent_group_dns,
+ parent_group_dn);
+ if (ext_mem->parent_group_dns[ext_mem->parent_dn_idx] == NULL) {
+ return ENOMEM;
+ }
+ ext_mem->parent_dn_idx++;
+
+ return EOK;
+}
+
static errno_t sdap_nested_group_sysdb_search(struct sss_domain_info *domain,
const char *filter,
bool user)
@@ -478,6 +566,13 @@ sdap_nested_group_split_members(TALLOC_CTX *mem_ctx,
errno_t ret;
int i;
+ if (members == NULL) {
+ *_missing = NULL;
+ *_num_missing = 0;
+ *_num_groups = 0;
+ return EOK;
+ }
+
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
@@ -619,6 +714,65 @@ done:
return ret;
}
+static errno_t
+sdap_nested_group_add_ext_members(TALLOC_CTX *mem_ctx,
+ struct sdap_nested_group_ctx *group_ctx,
+ struct sysdb_attrs *group,
+ struct ldb_message_element *ext_members)
+{
+ errno_t ret;
+ const char *ext_member_attr;
+ const char *orig_dn;
+
+ if (ext_members == NULL) {
+ return EOK;
+ }
+
+ ret = sysdb_attrs_get_string(group, SYSDB_ORIG_DN, &orig_dn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "A group with no originalDN!?!\n");
+ return ret;
+ }
+
+ for (size_t i = 0; i < ext_members->num_values; i++) {
+ ext_member_attr = (const char *) ext_members->values[i].data;
+
+ ret = sdap_nested_group_external_add(group_ctx->missing_external,
+ ext_member_attr,
+ orig_dn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Cannot add %s into external members [%d]: %s\n",
+ ext_member_attr, ret, sss_strerror(ret));
+ return ret;
+ }
+ }
+
+ return EOK;
+}
+
+static struct ldb_message_element *
+sdap_nested_group_ext_members(struct sdap_options *opts,
+ struct sysdb_attrs *group)
+{
+ errno_t ret;
+ struct ldb_message_element *ext_members = NULL;
+
+ if (opts->ext_ctx == NULL) {
+ return NULL;
+ }
+
+ ret = sysdb_attrs_get_el_ext(group,
+ opts->group_map[SDAP_AT_GROUP_EXT_MEMBER].sys_name,
+ false, &ext_members);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve external member list "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ }
+
+ return ext_members;
+}
+
struct sdap_nested_group_state {
struct sdap_nested_group_ctx *group_ctx;
@@ -667,6 +821,14 @@ sdap_nested_group_send(TALLOC_CTX *mem_ctx,
goto immediately;
}
+ ret = sss_hash_create(state->group_ctx, 32,
+ &state->group_ctx->missing_external);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n",
+ ret, strerror(ret));
+ goto immediately;
+ }
+
state->group_ctx->try_deref = true;
state->group_ctx->deref_treshold = dp_opt_get_int(opts->basic,
SDAP_DEREF_THRESHOLD);
@@ -760,7 +922,8 @@ errno_t sdap_nested_group_recv(TALLOC_CTX *mem_ctx,
unsigned long *_num_users,
struct sysdb_attrs ***_users,
unsigned long *_num_groups,
- struct sysdb_attrs ***_groups)
+ struct sysdb_attrs ***_groups,
+ hash_table_t **_missing_external)
{
struct sdap_nested_group_state *state = NULL;
struct sysdb_attrs **users = NULL;
@@ -807,6 +970,11 @@ errno_t sdap_nested_group_recv(TALLOC_CTX *mem_ctx,
*_groups = talloc_steal(mem_ctx, groups);
}
+ if (_missing_external) {
+ *_missing_external = talloc_steal(mem_ctx,
+ state->group_ctx->missing_external);
+ }
+
return EOK;
}
@@ -816,6 +984,7 @@ struct sdap_nested_group_process_state {
struct sdap_nested_group_member *missing;
int num_missing_total;
int num_missing_groups;
+ struct ldb_message_element *ext_members;
int nesting_level;
char *group_dn;
bool deref;
@@ -866,13 +1035,16 @@ sdap_nested_group_process_send(TALLOC_CTX *mem_ctx,
DEBUG(SSSDBG_TRACE_INTERNAL, "About to process group [%s]\n", orig_dn);
- /* get member list */
+ /* get member list, both direct and external */
+ state->ext_members = sdap_nested_group_ext_members(state->group_ctx->opts,
+ group);
+
ret = sysdb_attrs_get_el_ext(group, group_map[SDAP_AT_GROUP_MEMBER].sys_name,
false, &members);
- if (ret == ENOENT) {
- ret = EOK; /* no members */
+ if (ret == ENOENT && state->ext_members == NULL) {
+ ret = EOK; /* no members, direct or external */
goto immediately;
- } else if (ret != EOK) {
+ } else if (ret != EOK && ret != ENOENT) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve member list "
"[%d]: %s\n", ret, strerror(ret));
goto immediately;
@@ -890,14 +1062,31 @@ sdap_nested_group_process_send(TALLOC_CTX *mem_ctx,
goto immediately;
}
- DEBUG(SSSDBG_TRACE_INTERNAL, "Looking up %d/%d members of group [%s]\n",
- state->num_missing_total, members->num_values, orig_dn);
+ ret = sdap_nested_group_add_ext_members(state,
+ state->group_ctx,
+ group,
+ state->ext_members);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to split external member list "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto immediately;
+ }
- if (state->num_missing_total == 0) {
+ if (state->num_missing_total == 0
+ && hash_count(state->group_ctx->missing_external) == 0) {
ret = EOK; /* we're done */
goto immediately;
}
+ /* If there are only indirect members of the group, it's still safe to
+ * proceed and let the direct lookup code just fall through.
+ */
+
+ DEBUG(SSSDBG_TRACE_INTERNAL, "Looking up %d/%d members of group [%s]\n",
+ state->num_missing_total,
+ members ? members->num_values : 0,
+ orig_dn);
+
/* process members */
if (group_ctx->try_deref
&& state->num_missing_total > group_ctx->deref_treshold) {
@@ -2268,3 +2457,385 @@ static errno_t sdap_nested_group_deref_recv(struct tevent_req *req)
return EOK;
}
+
+struct sdap_ext_member {
+ struct sdap_external_missing_member *missing_mem;
+ const char *ext_member_attr;
+
+ enum sysdb_member_type member_type;
+ struct sss_domain_info *dom;
+ struct sysdb_attrs *attrs;
+};
+
+struct sdap_nested_group_lookup_external_state {
+ struct tevent_context *ev;
+ struct sdap_ext_member_ctx *ext_ctx;
+ struct sss_domain_info *group_dom;
+ hash_table_t *missing_external;
+
+ hash_entry_t *entries;
+ unsigned long n_entries;
+ unsigned long eniter;
+
+ struct sdap_ext_member *ext_members;
+
+ ext_member_send_fn_t ext_member_resolve_send;
+ ext_member_recv_fn_t ext_member_resolve_recv;
+};
+
+static errno_t
+sdap_nested_group_lookup_external_step(struct tevent_req *req);
+static void
+sdap_nested_group_lookup_external_done(struct tevent_req *subreq);
+static errno_t
+sdap_nested_group_lookup_external_link(struct tevent_req *req);
+static errno_t
+sdap_nested_group_lookup_external_link_member(
+ struct sdap_nested_group_lookup_external_state *state,
+ struct sdap_ext_member *member);
+static errno_t
+sdap_nested_group_memberof_dn_by_original_dn(
+ TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *group_dom,
+ const char *original_dn,
+ const char ***_parents);
+
+struct tevent_req *
+sdap_nested_group_lookup_external_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sss_domain_info *group_dom,
+ struct sdap_ext_member_ctx *ext_ctx,
+ hash_table_t *missing_external)
+{
+ struct sdap_nested_group_lookup_external_state *state = NULL;
+ struct tevent_req *req = NULL;
+ errno_t ret;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct sdap_nested_group_lookup_external_state);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
+ return NULL;
+ }
+
+ state->ev = ev;
+ state->group_dom = group_dom;
+ state->ext_ctx = ext_ctx;
+ state->missing_external = missing_external;
+
+ if (state->ext_ctx->ext_member_resolve_send == NULL
+ || state->ext_ctx->ext_member_resolve_recv == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Wrong private context\n");
+ ret = EINVAL;
+ goto immediately;
+ }
+
+ ret = hash_entries(state->missing_external,
+ &state->n_entries, &state->entries);
+ if (ret != HASH_SUCCESS) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "hash_entries returned %d\n", ret);
+ ret = EIO;
+ goto immediately;
+ }
+ state->eniter = 0;
+
+ state->ext_members = talloc_zero_array(state,
+ struct sdap_ext_member,
+ state->n_entries);
+ if (state->ext_members == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ ret = sdap_nested_group_lookup_external_step(req);
+ if (ret != EAGAIN) {
+ goto immediately;
+ }
+
+ return req;
+
+immediately:
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_error(req, ret);
+ }
+ tevent_req_post(req, ev);
+ return req;
+}
+
+static errno_t
+sdap_nested_group_lookup_external_step(struct tevent_req *req)
+{
+ struct tevent_req *subreq = NULL;
+ struct sdap_nested_group_lookup_external_state *state = NULL;
+ state = tevent_req_data(req,
+ struct sdap_nested_group_lookup_external_state);
+
+ subreq = state->ext_ctx->ext_member_resolve_send(state,
+ state->ev,
+ state->entries[state->eniter].key.str,
+ state->ext_ctx->pvt);
+ if (subreq == NULL) {
+ return ENOMEM;
+ }
+ DEBUG(SSSDBG_TRACE_FUNC, "Refreshing member %lu/%lu\n",
+ state->eniter, state->n_entries);
+ tevent_req_set_callback(subreq,
+ sdap_nested_group_lookup_external_done,
+ req);
+
+ return EAGAIN;
+}
+
+static void
+sdap_nested_group_lookup_external_done(struct tevent_req *subreq)
+{
+ errno_t ret;
+ struct tevent_req *req = NULL;
+ struct sdap_nested_group_lookup_external_state *state = NULL;
+ enum sysdb_member_type member_type;
+ struct sysdb_attrs *member;
+ struct sss_domain_info *member_dom;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req,
+ struct sdap_nested_group_lookup_external_state);
+
+ ret = state->ext_ctx->ext_member_resolve_recv(state, subreq,
+ &member_type,
+ &member_dom,
+ &member);
+ talloc_free(subreq);
+ if (ret == EOK) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Refreshing member %lu\n", state->eniter);
+ state->ext_members[state->eniter].missing_mem = \
+ state->entries[state->eniter].value.ptr;
+ state->ext_members[state->eniter].dom = member_dom;
+
+ state->ext_members[state->eniter].ext_member_attr = \
+ talloc_steal(state->ext_members,
+ state->entries[state->eniter].key.str);
+ state->ext_members[state->eniter].member_type = member_type;
+ state->ext_members[state->eniter].attrs = \
+ talloc_steal(state->ext_members, member);
+ }
+
+ state->eniter++;
+ if (state->eniter >= state->n_entries) {
+ DEBUG(SSSDBG_TRACE_FUNC, "All external members processed\n");
+ ret = sdap_nested_group_lookup_external_link(req);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+ tevent_req_done(req);
+ return;
+ }
+
+ ret = sdap_nested_group_lookup_external_step(req);
+ if (ret != EOK && ret != EAGAIN) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ return;
+}
+
+static errno_t
+sdap_nested_group_lookup_external_link(struct tevent_req *req)
+{
+ errno_t ret, tret;
+ bool in_transaction = false;
+ struct sdap_nested_group_lookup_external_state *state = NULL;
+ state = tevent_req_data(req,
+ struct sdap_nested_group_lookup_external_state);
+
+ ret = sysdb_transaction_start(state->group_dom->sysdb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
+ goto fail;
+ }
+ in_transaction = true;
+
+
+ for (size_t i = 0; i < state->eniter; i++) {
+ if (state->ext_members[i].attrs == NULL) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "The member %s could not be resolved\n",
+ state->ext_members[i].ext_member_attr);
+ continue;
+ }
+
+ ret = sdap_nested_group_lookup_external_link_member(state,
+ &state->ext_members[i]);
+ if (ret != EOK) {
+ goto fail;
+ }
+ }
+
+ ret = sysdb_transaction_commit(state->group_dom->sysdb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
+ goto fail;
+ }
+ in_transaction = false;
+
+ return EOK;
+
+fail:
+ if (in_transaction) {
+ tret = sysdb_transaction_cancel(state->group_dom->sysdb);
+ if (tret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n");
+ }
+ }
+ return EFAULT;
+}
+
+static errno_t
+sdap_nested_group_lookup_external_link_member(
+ struct sdap_nested_group_lookup_external_state *state,
+ struct sdap_ext_member *member)
+{
+ const char *name;
+ int ret;
+ const char **parents = NULL;
+ size_t i;
+ TALLOC_CTX *tmp_ctx;
+ const char *orig_dn;
+
+ tmp_ctx = talloc_new(state);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sysdb_attrs_get_string(member->attrs, SYSDB_NAME, &name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "No name for a user\n");
+ goto done;
+ }
+
+ /* This only works because the groups were saved in a previous
+ * transaction */
+ for (i=0; i < member->missing_mem->parent_dn_idx; i++) {
+ orig_dn = member->missing_mem->parent_group_dns[i];
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ "Linking external members %s from domain %s to parents of %s\n",
+ name, member->dom->name, orig_dn);
+ ret = sdap_nested_group_memberof_dn_by_original_dn(tmp_ctx,
+ state->group_dom,
+ orig_dn,
+ &parents);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Cannot find parents of %s\n", orig_dn);
+ continue;
+ }
+
+ /* We don't have to remove the members here, since all members attributes
+ * are always written anew
+ */
+ ret = sysdb_update_members_dn(member->dom, name, member->member_type,
+ parents, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot link %s@%s to its parents\n",
+ name, member->dom->name);
+ goto done;
+ }
+
+ }
+
+ ret = EOK;
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+static errno_t
+sdap_nested_group_memberof_dn_by_original_dn(
+ TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *group_dom,
+ const char *original_dn,
+ const char ***_parents)
+{
+ errno_t ret;
+ char *sanitized_dn;
+ char *filter;
+ const char *attrs[] = { SYSDB_NAME,
+ SYSDB_MEMBEROF,
+ NULL };
+ struct ldb_message **msgs = NULL;
+ size_t count;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_message_element *memberof;
+ const char **parents;
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sss_filter_sanitize(tmp_ctx, original_dn, &sanitized_dn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Cannot sanitize originalDN [%s]\n", original_dn);
+ goto done;
+ }
+
+ filter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_ORIG_DN, sanitized_dn);
+ if (filter == NULL) {
+ goto done;
+ }
+
+ ret = sysdb_search_groups(tmp_ctx, group_dom, filter, attrs,
+ &count, &msgs);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ if (count != 1) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "More than one entry found by originalDN?\n");
+ goto done;
+ }
+
+ memberof = ldb_msg_find_element(msgs[0], SYSDB_MEMBEROF);
+ if (memberof == NULL || memberof->num_values == 0) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "The external group is not a member of any groups\n");
+ ret = ENOENT;
+ goto done;
+ }
+
+ parents = talloc_zero_array(tmp_ctx,
+ const char *,
+ memberof->num_values + 1);
+ if (parents == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ for (size_t i = 0; i < memberof->num_values; i++) {
+ parents[i] = talloc_strdup(parents,
+ (const char *) memberof->values[i].data);
+ if (parents[i] == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ *_parents = talloc_steal(mem_ctx, parents);
+ ret = EOK;
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+errno_t
+sdap_nested_group_lookup_external_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req)
+{
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ return EOK;
+}
diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h
index db542eaf869efcd53d0937bef3fc6e99cc78b938..9cde6f5dfe0114f797135b4989b9a4bd336a3f27 100644
--- a/src/providers/ldap/sdap_async_private.h
+++ b/src/providers/ldap/sdap_async_private.h
@@ -130,8 +130,20 @@ errno_t sdap_nested_group_recv(TALLOC_CTX *mem_ctx,
unsigned long *_num_users,
struct sysdb_attrs ***_users,
unsigned long *_num_groups,
- struct sysdb_attrs ***_groups);
+ struct sysdb_attrs ***_groups,
+ hash_table_t **missing_external);
+struct tevent_req *
+sdap_nested_group_lookup_external_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sss_domain_info *group_dom,
+ struct sdap_ext_member_ctx *ext_ctx,
+ hash_table_t *missing_external);
+errno_t
+sdap_nested_group_lookup_external_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req);
+
+/* from sdap_async_initgroups.c */
errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
struct sss_domain_info *domain,
struct sdap_options *opts,
@@ -139,7 +151,7 @@ errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
struct sysdb_attrs **ldap_groups,
int ldap_groups_count);
-/* from sdap_async_nested_groups.c */
+/* from sdap_ad_groups.c */
errno_t sdap_check_ad_group_type(struct sss_domain_info *dom,
struct sdap_options *opts,
struct sysdb_attrs *group_attrs,
diff --git a/src/tests/cmocka/test_nested_groups.c b/src/tests/cmocka/test_nested_groups.c
index dc29768c5660d5815d5fab56ee70cc8c9caab330..a3345ef5e087fc90466ce8400dda549fa5d79af8 100644
--- a/src/tests/cmocka/test_nested_groups.c
+++ b/src/tests/cmocka/test_nested_groups.c
@@ -57,6 +57,7 @@ struct nested_groups_test_ctx {
struct sdap_domain *sdap_domain;
struct sdap_idmap_ctx *idmap_ctx;
struct sdap_id_ctx *sdap_id_ctx;
+ hash_table_t *missing_external;
struct sysdb_attrs **users;
struct sysdb_attrs **groups;
@@ -110,7 +111,8 @@ static void nested_groups_test_done(struct tevent_req *req)
ctx->tctx->error = sdap_nested_group_recv(ctx, req,
&ctx->num_users, &ctx->users,
- &ctx->num_groups, &ctx->groups);
+ &ctx->num_groups, &ctx->groups,
+ &ctx->missing_external);
talloc_zfree(req);
ctx->tctx->done = true;
--
2.5.0

View File

@ -0,0 +1,37 @@
From 245710d26dfa11db998f8a1406b086e76fb8f49b Mon Sep 17 00:00:00 2001
From: David Disseldorp <ddiss@samba.org>
Date: Wed, 24 Feb 2016 17:18:00 +0100
Subject: [PATCH 81/86] build: detect endianness at configure time
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
WORDS_BIGENDIAN, HAVE_BIG_ENDIAN and HAVE_LITTLE_ENDIAN are needed by
Samba. See Samba's byteorder.h header for an example.
Signed-off-by: David Disseldorp <ddiss@samba.org>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit faa16fc9f0c9a02b26497e7cf148a92586144c08)
(cherry picked from commit 15ccbb564d5cc7d6fc8e856811b7ed71c0e220a9)
---
configure.ac | 3 +++
1 file changed, 3 insertions(+)
diff --git a/configure.ac b/configure.ac
index 8ef2493c79a144d348200213f0ce1681d0fa3c1f..aebb3c3e9e8d3702295b1b5da28a04c46303af9b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,6 +76,9 @@ AC_CHECK_FUNCS([ utimensat \
#Check for endian headers
AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h])
+AC_C_BIGENDIAN([AC_DEFINE(HAVE_BIG_ENDIAN, [1], [whether platform is big endian])],
+ [AC_DEFINE(HAVE_LITTLE_ENDIAN, [1], [whether platform is little endian])])
+
#Set the NSS library install path
AC_ARG_ENABLE([nsslibdir], [AS_HELP_STRING([--enable-nsslibdir],
[Where to install nss libraries ($libdir)])],
--
2.5.0

View File

@ -24,7 +24,7 @@
Name: sssd
Version: 1.13.3
Release: 4%{?dist}
Release: 5%{?dist}
Group: Applications/System
Summary: System Security Services Daemon
License: GPLv3+
@ -83,6 +83,37 @@ Patch0047: 0047-p11-add-gnome-screensaver-to-list-of-allowed-service.patch
Patch0048: 0048-IDMAP-Fix-computing-max-id-for-slice-range.patch
Patch0049: 0049-IDMAP-New-structure-for-domain-range-params.patch
Patch0050: 0050-IDMAP-Add-support-for-automatic-adding-of-ranges.patch
Patch0051: 0051-NSS-do-not-skip-cache-check-for-netgoups.patch
Patch0052: 0052-cache_req-simplify-cache_req_cache_check.patch
Patch0053: 0053-cache_req-do-not-lookup-views-if-possible.patch
Patch0054: 0054-IDMAP-Fix-minor-memory-leak.patch
Patch0055: 0055-CONFIGURE-Replace-obsoleted-macro-AC_PROG_LIBTOOL.patch
Patch0056: 0056-TESTS-Fix-race-condition-in-python-test.patch
Patch0057: 0057-PYTHON-sss_obfuscate-should-work-with-python3.patch
Patch0058: 0058-PYTHON-Fix-pep8-errors-in-sss_obfuscate.patch
Patch0059: 0059-IDMAP-Man-change-for-ldap_idmap_range_size-option.patch
Patch0060: 0060-NSS-Fix-memory-leak-netgroup.patch
Patch0061: 0061-IDMAP-Add-test-to-validate-off-by-one-bug.patch
Patch0062: 0062-SDAP-Add-return-code-ERR_ACCOUNT_LOCKED.patch
Patch0063: 0063-PAM-Pass-account-lockout-status-and-display-message.patch
Patch0064: 0064-PAM-Fix-man-for-pam_account_-expired-locked-_message.patch
Patch0065: 0065-UTIL-Backport-error-code-ERR_ACCOUNT_LOCKED.patch
Patch0066: 0066-sss_idmap-tests-Fix-segmentation-fault.patch
Patch0067: 0067-krb5_child-Warn-if-user-cannot-read-krb5.conf.patch
Patch0068: 0068-Fix-typos-reported-by-lintian.patch
Patch0069: 0069-UTIL-Use-prefix-for-debug-function.patch
Patch0070: 0070-UTIL-Provide-varargs-version-of-debug_fn.patch
Patch0071: 0071-UTIL-Use-sss_vdebug_fn-for-callbacks.patch
Patch0072: 0072-Revert-DEBUG-Preventing-chown_debug_file-if-journald.patch
Patch0073: 0073-DEBUG-Ignore-ENOENT-for-change-owner-of-log-files.patch
Patch0074: 0074-TOOLS-Fix-minor-memory-leak-in-sss_colondb_writeline.patch
Patch0075: 0075-TOOLS-Fix-memory-leak-after-getline-failed.patch
Patch0076: 0076-TOOLS-Add-comments-on-functions-in-colondb.patch
Patch0077: 0077-TEST_TOOLS_COLONDB-Add-tests-for-sss_colondb_.patch
Patch0078: 0078-Add-a-new-option-ldap_group_external_member.patch
Patch0079: 0079-IPA-Add-interface-to-call-into-IPA-provider-from-LDA.patch
Patch0080: 0080-LDAP-Use-the-IPA-provider-interface-to-resolve-exter.patch
Patch0081: 0081-build-detect-endianness-at-configure-time.patch
Patch0100: 0100-FO-Don-t-free-rc-allocated-structure.patch
Patch0101: 0101-tests-Reduce-failover-code-duplication.patch
Patch0102: 0102-FO-Use-refcount-to-keep-track-of-servers-returned-to.patch
@ -1073,6 +1104,12 @@ fi
%{_libdir}/%{name}/modules/libwbclient.so
%changelog
* Thu Feb 25 2016 Lukas Slebodnik <lslebodn@redhat.com> - 1.13.3-5
- Resolves: rhbz#1310664 - [RFE] IPA: resolve external group memberships of IPA
groups during getgrnam and getgrgid
- Resolves: rhbz#1301303 - sss_obfuscate: SyntaxError: Missing parentheses
in call to 'print'
* Fri Feb 05 2016 Fedora Release Engineering <releng@fedoraproject.org> - 1.13.3-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild