1dedfbb334
Resolves: upstream#3588 - sssd_nss consumes more memory until restarted or machine swaps Resolves: failure in glibc tests https://sourceware.org/bugzilla/show_bug.cgi?id=22530 Resolves: upstream#3451 - When sssd is configured with id_provider proxy and auth_provider ldap, login fails if the LDAP server is not allowing anonymous binds Resolves: upstream#3285 - SSSD needs restart after incorrect clock is corrected with AD Resolves: upstream#3586 - Give a more detailed debug and system-log message if krb5_init_context() failed Resolves: rhbz#1431153 - SSSD ships a drop-in configuration snippet in /etc/systemd/system Backport few upstream features from 1.16.1
222 lines
7.7 KiB
Diff
222 lines
7.7 KiB
Diff
From 80ea108ab4263c1a1ac67ce6eac41dc6040b21dd Mon Sep 17 00:00:00 2001
|
|
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
Date: Tue, 3 Oct 2017 14:31:18 +0200
|
|
Subject: [PATCH 06/79] LDAP: Turn group request into user request for MPG
|
|
domains if needed
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
If the primary group GID or the group name is requested before the user
|
|
is, we need to also search the user space to save the user in the back
|
|
end which then allows the responder to generate the group from the
|
|
user entry.
|
|
|
|
Related:
|
|
https://pagure.io/SSSD/sssd/issue/1872
|
|
|
|
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
|
Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
|
|
---
|
|
src/providers/ldap/ldap_id.c | 162 +++++++++++++++++++++++++++++++------------
|
|
1 file changed, 118 insertions(+), 44 deletions(-)
|
|
|
|
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
|
|
index 93204d35ea3782c9aa5d622a962c295869472631..e89fc6133316f684810afe4c1a0731b8a04f2931 100644
|
|
--- a/src/providers/ldap/ldap_id.c
|
|
+++ b/src/providers/ldap/ldap_id.c
|
|
@@ -694,6 +694,8 @@ struct groups_get_state {
|
|
static int groups_get_retry(struct tevent_req *req);
|
|
static void groups_get_connect_done(struct tevent_req *subreq);
|
|
static void groups_get_posix_check_done(struct tevent_req *subreq);
|
|
+static void groups_get_mpg_done(struct tevent_req *subreq);
|
|
+static errno_t groups_get_handle_no_group(struct tevent_req *req);
|
|
static void groups_get_search(struct tevent_req *req);
|
|
static void groups_get_done(struct tevent_req *subreq);
|
|
|
|
@@ -1051,8 +1053,6 @@ static void groups_get_done(struct tevent_req *subreq)
|
|
struct tevent_req);
|
|
struct groups_get_state *state = tevent_req_data(req,
|
|
struct groups_get_state);
|
|
- char *endptr;
|
|
- gid_t gid;
|
|
int dp_error = DP_ERR_FATAL;
|
|
int ret;
|
|
|
|
@@ -1078,49 +1078,33 @@ static void groups_get_done(struct tevent_req *subreq)
|
|
return;
|
|
}
|
|
|
|
- if (ret == ENOENT && state->noexist_delete == true) {
|
|
- switch (state->filter_type) {
|
|
- case BE_FILTER_ENUM:
|
|
- tevent_req_error(req, ret);
|
|
+ if (ret == ENOENT
|
|
+ && state->domain->mpg == true) {
|
|
+ /* The requested filter did not find a group. Before giving up, we must
|
|
+ * also check if the GID can be resolved through a primary group of a
|
|
+ * user
|
|
+ */
|
|
+ subreq = users_get_send(state,
|
|
+ state->ev,
|
|
+ state->ctx,
|
|
+ state->sdom,
|
|
+ state->conn,
|
|
+ state->filter_value,
|
|
+ state->filter_type,
|
|
+ NULL,
|
|
+ state->noexist_delete);
|
|
+ if (subreq == NULL) {
|
|
+ tevent_req_error(req, ENOMEM);
|
|
return;
|
|
- case BE_FILTER_NAME:
|
|
- ret = sysdb_delete_group(state->domain, state->filter_value, 0);
|
|
- if (ret != EOK && ret != ENOENT) {
|
|
- tevent_req_error(req, ret);
|
|
- return;
|
|
- }
|
|
- break;
|
|
-
|
|
- case BE_FILTER_IDNUM:
|
|
- gid = (gid_t) strtouint32(state->filter_value, &endptr, 10);
|
|
- if (errno || *endptr || (state->filter_value == endptr)) {
|
|
- tevent_req_error(req, errno ? errno : EINVAL);
|
|
- return;
|
|
- }
|
|
-
|
|
- ret = sysdb_delete_group(state->domain, NULL, gid);
|
|
- if (ret != EOK && ret != ENOENT) {
|
|
- tevent_req_error(req, ret);
|
|
- return;
|
|
- }
|
|
- break;
|
|
-
|
|
- case BE_FILTER_SECID:
|
|
- case BE_FILTER_UUID:
|
|
- /* Since it is not clear if the SID/UUID belongs to a user or a
|
|
- * group we have nothing to do here. */
|
|
- break;
|
|
-
|
|
- case BE_FILTER_WILDCARD:
|
|
- /* We can't know if all groups are up-to-date, especially in
|
|
- * a large environment. Do not delete any records, let the
|
|
- * responder fetch the entries they are requested in.
|
|
- */
|
|
- break;
|
|
-
|
|
-
|
|
- default:
|
|
- tevent_req_error(req, EINVAL);
|
|
+ }
|
|
+ tevent_req_set_callback(subreq, groups_get_mpg_done, req);
|
|
+ return;
|
|
+ } else if (ret == ENOENT && state->noexist_delete == true) {
|
|
+ ret = groups_get_handle_no_group(req);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
+ "Could not delete group [%d]: %s\n", ret, sss_strerror(ret));
|
|
+ tevent_req_error(req, ret);
|
|
return;
|
|
}
|
|
}
|
|
@@ -1129,6 +1113,96 @@ static void groups_get_done(struct tevent_req *subreq)
|
|
tevent_req_done(req);
|
|
}
|
|
|
|
+static void groups_get_mpg_done(struct tevent_req *subreq)
|
|
+{
|
|
+ errno_t ret;
|
|
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
+ struct tevent_req);
|
|
+ struct groups_get_state *state = tevent_req_data(req,
|
|
+ struct groups_get_state);
|
|
+
|
|
+ ret = users_get_recv(subreq, &state->dp_error, &state->sdap_ret);
|
|
+ talloc_zfree(subreq);
|
|
+
|
|
+ if (ret != EOK) {
|
|
+ tevent_req_error(req, ret);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (state->sdap_ret == ENOENT && state->noexist_delete == true) {
|
|
+ ret = groups_get_handle_no_group(req);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
+ "Could not delete group [%d]: %s\n", ret, sss_strerror(ret));
|
|
+ tevent_req_error(req, ret);
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* GID resolved to a user private group, done */
|
|
+ tevent_req_done(req);
|
|
+ return;
|
|
+}
|
|
+
|
|
+static errno_t groups_get_handle_no_group(struct tevent_req *req)
|
|
+{
|
|
+ struct groups_get_state *state = tevent_req_data(req,
|
|
+ struct groups_get_state);
|
|
+ errno_t ret;
|
|
+ char *endptr;
|
|
+ gid_t gid;
|
|
+
|
|
+ switch (state->filter_type) {
|
|
+ case BE_FILTER_ENUM:
|
|
+ ret = ENOENT;
|
|
+ break;
|
|
+ case BE_FILTER_NAME:
|
|
+ ret = sysdb_delete_group(state->domain, state->filter_value, 0);
|
|
+ if (ret != EOK && ret != ENOENT) {
|
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
+ "Cannot delete group %s [%d]: %s\n",
|
|
+ state->filter_value, ret, sss_strerror(ret));
|
|
+ return ret;
|
|
+ }
|
|
+ ret = EOK;
|
|
+ break;
|
|
+ case BE_FILTER_IDNUM:
|
|
+ gid = (gid_t) strtouint32(state->filter_value, &endptr, 10);
|
|
+ if (errno || *endptr || (state->filter_value == endptr)) {
|
|
+ ret = errno ? errno : EINVAL;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ ret = sysdb_delete_group(state->domain, NULL, gid);
|
|
+ if (ret != EOK && ret != ENOENT) {
|
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
+ "Cannot delete group %"SPRIgid" [%d]: %s\n",
|
|
+ gid, ret, sss_strerror(ret));
|
|
+ return ret;
|
|
+ }
|
|
+ ret = EOK;
|
|
+ break;
|
|
+ case BE_FILTER_SECID:
|
|
+ case BE_FILTER_UUID:
|
|
+ /* Since it is not clear if the SID/UUID belongs to a user or a
|
|
+ * group we have nothing to do here. */
|
|
+ ret = EOK;
|
|
+ break;
|
|
+ case BE_FILTER_WILDCARD:
|
|
+ /* We can't know if all groups are up-to-date, especially in
|
|
+ * a large environment. Do not delete any records, let the
|
|
+ * responder fetch the entries they are requested in.
|
|
+ */
|
|
+ ret = EOK;
|
|
+ break;
|
|
+ default:
|
|
+ ret = EINVAL;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
int groups_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret)
|
|
{
|
|
struct groups_get_state *state = tevent_req_data(req,
|
|
--
|
|
2.15.1
|
|
|