Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP6:Update
sssd
0006-sssctl-manage-gpo-cache.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0006-sssctl-manage-gpo-cache.patch of Package sssd
From 0b4a925b5f591fd98a064e3217efb1fb1d3bc09f Mon Sep 17 00:00:00 2001 From: Andre Boscatto <andreboscatto@gmail.com> Date: Wed, 7 Feb 2024 12:28:28 +0100 Subject: [PATCH 01/15] sssd: adding mail as case insensitive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves: https://github.com/SSSD/sssd/issues/7173 Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> (cherry picked from commit 945cebcf72ef53ea0368f19c09e710f7fff11b51) --- src/db/sysdb_init.c | 7 ++++++ src/db/sysdb_private.h | 5 +++- src/db/sysdb_upgrade.c | 56 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/db/sysdb_init.c b/src/db/sysdb_init.c index c2ea6c369..38a9cd64a 100644 --- a/src/db/sysdb_init.c +++ b/src/db/sysdb_init.c @@ -603,6 +603,13 @@ static errno_t sysdb_domain_cache_upgrade(TALLOC_CTX *mem_ctx, } } + if (strcmp(version, SYSDB_VERSION_0_23) == 0) { + ret = sysdb_upgrade_23(sysdb, &version); + if (ret != EOK) { + goto done; + } + } + ret = EOK; done: sysdb->ldb = save_ldb; diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h index 1f55007bc..63f7b5601 100644 --- a/src/db/sysdb_private.h +++ b/src/db/sysdb_private.h @@ -23,6 +23,7 @@ #ifndef __INT_SYS_DB_H__ #define __INT_SYS_DB_H__ +#define SYSDB_VERSION_0_24 "0.24" #define SYSDB_VERSION_0_23 "0.23" #define SYSDB_VERSION_0_22 "0.22" #define SYSDB_VERSION_0_21 "0.21" @@ -47,7 +48,7 @@ #define SYSDB_VERSION_0_2 "0.2" #define SYSDB_VERSION_0_1 "0.1" -#define SYSDB_VERSION SYSDB_VERSION_0_23 +#define SYSDB_VERSION SYSDB_VERSION_0_24 #define SYSDB_BASE_LDIF \ "dn: @ATTRIBUTES\n" \ @@ -60,6 +61,7 @@ "objectclass: CASE_INSENSITIVE\n" \ "ipHostNumber: CASE_INSENSITIVE\n" \ "ipNetworkNumber: CASE_INSENSITIVE\n" \ + "mail: CASE_INSENSITIVE\n" \ "\n" \ "dn: @INDEXLIST\n" \ "@IDXATTR: cn\n" \ @@ -191,6 +193,7 @@ int sysdb_upgrade_19(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_20(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_21(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_22(struct sysdb_ctx *sysdb, const char **ver); +int sysdb_upgrade_23(struct sysdb_ctx *sysdb, const char **ver); int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver); diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c index 346a1cb0b..56083e6be 100644 --- a/src/db/sysdb_upgrade.c +++ b/src/db/sysdb_upgrade.c @@ -2718,6 +2718,62 @@ done: return ret; } +int sysdb_upgrade_23(struct sysdb_ctx *sysdb, const char **ver) +{ + TALLOC_CTX *tmp_ctx; + int ret; + struct ldb_message *msg; + struct upgrade_ctx *ctx; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + return ENOMEM; + } + + ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_24, &ctx); + if (ret) { + return ret; + } + + /* Add new indexes */ + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES"); + if (!msg->dn) { + ret = ENOMEM; + goto done; + } + + /* Case insensitive search for mail */ + ret = ldb_msg_add_empty(msg, SYSDB_USER_EMAIL, LDB_FLAG_MOD_ADD, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_string(msg, SYSDB_USER_EMAIL, "CASE_INSENSITIVE"); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_modify(sysdb->ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + /* conversion done, update version number */ + ret = update_version(ctx); + +done: + ret = finish_upgrade(ret, &ctx, ver); + talloc_free(tmp_ctx); + return ret; +} + int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver) { struct upgrade_ctx *ctx; -- 2.44.0 From 2a56eeacd0b04624f32158d52d558a8305b199bf Mon Sep 17 00:00:00 2001 From: Samuel Cabrero <scabrero@suse.de> Date: Tue, 13 Feb 2024 16:58:08 +0100 Subject: [PATCH 02/15] GPO: Defer SMB server choice until id connection established when processing referrals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes referral processing when the connection to the referred domain has not yet been initialized. This may happen when sssd has just started as state->conn->service->uri of referred subdomain may not have been resolved yet. Defer the decision on which SMB server to download the GPO files from until the id connection has been established as the user might have forced the DC to use (ad_server parameter). Related to: https://github.com/SSSD/sssd/issues/3686 Signed-off-by: Samuel Cabrero <scabrero@suse.de> Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> --- src/providers/ad/ad_gpo.c | 40 ++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c index 44e9cbb27..52c35293b 100644 --- a/src/providers/ad/ad_gpo.c +++ b/src/providers/ad/ad_gpo.c @@ -4958,25 +4958,6 @@ ad_gpo_get_sd_referral_send(TALLOC_CTX *mem_ctx, goto done; } - /* Get the hostname we're going to connect to. - * We'll need this later for performing the samba - * connection. - */ - ret = ldap_url_parse(state->conn->service->uri, &lud); - if (ret != LDAP_SUCCESS) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Failed to parse service URI (%s)!\n", referral); - ret = EINVAL; - goto done; - } - - state->smb_host = talloc_strdup(state, lud->lud_host); - ldap_free_urldesc(lud); - if (!state->smb_host) { - ret = ENOMEM; - goto done; - } - /* Start an ID operation for the referral */ state->ref_op = sdap_id_op_create(state, state->conn->conn_cache); if (!state->ref_op) { @@ -5012,6 +4993,7 @@ ad_gpo_get_sd_referral_conn_done(struct tevent_req *subreq) errno_t ret; int dp_error; const char *attrs[] = AD_GPO_ATTRS; + LDAPURLDesc *lud = NULL; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); @@ -5035,6 +5017,26 @@ ad_gpo_get_sd_referral_conn_done(struct tevent_req *subreq) return; } + /* + * Save the hostname we have connected to. We'll need this later for + * performing the smb connection. The GPO referral URL can't be directly used + * because the user might have forced the DC to use (ad_server option) + */ + ret = ldap_url_parse(state->conn->service->uri, &lud); + if (ret != LDAP_SUCCESS) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse service URI (%s)!\n", + state->conn->service->uri); + tevent_req_error(req, EINVAL); + return; + } + + state->smb_host = talloc_strdup(state, lud->lud_host); + ldap_free_urldesc(lud); + lud = NULL; + if (tevent_req_nomem(state->smb_host, req)) { + return; + } + /* Request the referred GPO data */ subreq = sdap_sd_search_send(state, state->ev, state->opts, sdap_id_op_handle(state->ref_op), -- 2.44.0 From 176c77222e77fcc9b2c72dead671f1dea93aed6e Mon Sep 17 00:00:00 2001 From: Samuel Cabrero <scabrero@suse.de> Date: Tue, 23 Jan 2024 12:51:38 +0100 Subject: [PATCH 03/15] GPO: Remove unused local variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Samuel Cabrero <scabrero@suse.de> Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> --- src/providers/ad/ad_gpo.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c index 52c35293b..317e5a842 100644 --- a/src/providers/ad/ad_gpo.c +++ b/src/providers/ad/ad_gpo.c @@ -2438,7 +2438,6 @@ ad_gpo_process_gpo_done(struct tevent_req *subreq) struct gp_gpo **candidate_gpos = NULL; int num_candidate_gpos = 0; int i = 0; - const char **cse_filtered_gpo_guids; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_gpo_access_state); @@ -2571,23 +2570,9 @@ ad_gpo_process_gpo_done(struct tevent_req *subreq) goto done; } - /* we create and populate an array of applicable gpo-guids */ - cse_filtered_gpo_guids = - talloc_array(state, const char *, state->num_cse_filtered_gpos); - if (cse_filtered_gpo_guids == NULL) { - ret = ENOMEM; - goto done; - } - for (i = 0; i < state->num_cse_filtered_gpos; i++) { DEBUG(SSSDBG_TRACE_FUNC, "cse_filtered_gpos[%d]->gpo_guid is %s\n", i, state->cse_filtered_gpos[i]->gpo_guid); - cse_filtered_gpo_guids[i] = talloc_steal(cse_filtered_gpo_guids, - state->cse_filtered_gpos[i]->gpo_guid); - if (cse_filtered_gpo_guids[i] == NULL) { - ret = ENOMEM; - goto done; - } } DEBUG(SSSDBG_TRACE_FUNC, "num_cse_filtered_gpos: %d\n", -- 2.44.0 From 5eb02805732aec3417ba705ee7b9ed7b5b5fa732 Mon Sep 17 00:00:00 2001 From: Samuel Cabrero <scabrero@suse.de> Date: Fri, 19 Jan 2024 10:59:41 +0100 Subject: [PATCH 04/15] SYSDB: Add sysdb_gpos_base_dn() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves: https://github.com/SSSD/sssd/issues/4523 Signed-off-by: Samuel Cabrero <scabrero@suse.de> Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> --- src/db/sysdb.h | 3 +++ src/db/sysdb_gpo.c | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 55c6437f2..250cb08ed 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -1525,6 +1525,9 @@ errno_t sysdb_gpo_get_gpos(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **_result); +struct ldb_dn *sysdb_gpos_base_dn(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom); + /* === Functions related to GPO Result object === */ #define SYSDB_GPO_RESULT_OC "gpo_result" diff --git a/src/db/sysdb_gpo.c b/src/db/sysdb_gpo.c index e5af91bd8..777d467cb 100644 --- a/src/db/sysdb_gpo.c +++ b/src/db/sysdb_gpo.c @@ -683,3 +683,10 @@ done: return ret; } + +struct ldb_dn *sysdb_gpos_base_dn(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom) +{ + return ldb_dn_new_fmt(mem_ctx, dom->sysdb->ldb, + SYSDB_TMPL_GPO_BASE, dom->name); +} -- 2.44.0 From a18cccf93ecab70a86b827ec06ec3e4c2af9d2ad Mon Sep 17 00:00:00 2001 From: Samuel Cabrero <scabrero@suse.de> Date: Mon, 22 Jan 2024 11:20:11 +0100 Subject: [PATCH 05/15] GPO: Fetch the GPO's displayName attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves: https://github.com/SSSD/sssd/issues/4523 Signed-off-by: Samuel Cabrero <scabrero@suse.de> Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> --- src/providers/ad/ad_gpo.c | 36 +++++++++++++++++++++++++++++++++--- src/providers/ad/ad_gpo.h | 3 ++- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c index 317e5a842..a626af2ec 100644 --- a/src/providers/ad/ad_gpo.c +++ b/src/providers/ad/ad_gpo.c @@ -57,6 +57,7 @@ /* == gpo-ldap constants =================================================== */ +#define AD_AT_DISPLAY_NAME "displayName" #define AD_AT_DN "distinguishedName" #define AD_AT_UAC "userAccountControl" #define AD_AT_SAMACCOUNTNAME "sAMAccountName" @@ -126,6 +127,7 @@ struct gp_gplink { struct gp_gpo { struct security_descriptor *gpo_sd; const char *gpo_dn; + const char *gpo_dpname; const char *gpo_guid; const char *smb_server; const char *smb_share; @@ -178,6 +180,7 @@ struct tevent_req *ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx, bool send_to_child, struct sss_domain_info *domain, const char *gpo_guid, + const char *gpo_dpname, const char *smb_server, const char *smb_share, const char *smb_path, @@ -2699,6 +2702,7 @@ ad_gpo_cse_step(struct tevent_req *req) send_to_child, state->host_domain, cse_filtered_gpo->gpo_guid, + cse_filtered_gpo->gpo_dpname, cse_filtered_gpo->smb_server, cse_filtered_gpo->smb_share, cse_filtered_gpo->smb_path, @@ -2732,8 +2736,10 @@ ad_gpo_cse_done(struct tevent_req *subreq) state->cse_filtered_gpos[state->cse_gpo_index]; const char *gpo_guid = cse_filtered_gpo->gpo_guid; + const char *gpo_dpname = cse_filtered_gpo->gpo_dpname; - DEBUG(SSSDBG_TRACE_FUNC, "gpo_guid: %s\n", gpo_guid); + DEBUG(SSSDBG_TRACE_FUNC, "gpo_guid: %s, display name: %s\n", + gpo_guid, gpo_dpname); ret = ad_gpo_process_cse_recv(subreq); @@ -4270,23 +4276,25 @@ ad_gpo_missing_or_unreadable_attr(struct ad_gpo_process_gpo_state *state, "Group Policy Container with DN [%s] is unreadable or has " "unreadable or missing attributes. In order to fix this " "make sure that this AD object has following attributes " - "readable: nTSecurityDescriptor, cn, gPCFileSysPath, " + "readable: %s, nTSecurityDescriptor, cn, gPCFileSysPath, " "gPCMachineExtensionNames, gPCFunctionalityVersion, flags. " "Alternatively if you do not have access to the server or can " "not change permissions on this object, you can use option " "ad_gpo_ignore_unreadable = True which will skip this GPO. " "See ad_gpo_ignore_unreadable in 'man sssd-ad' for details.\n", + AD_AT_DISPLAY_NAME, state->candidate_gpos[state->gpo_index]->gpo_dn); sss_log(SSS_LOG_ERR, "Group Policy Container with DN [%s] is unreadable or has " "unreadable or missing attributes. In order to fix this " "make sure that this AD object has following attributes " - "readable: nTSecurityDescriptor, cn, gPCFileSysPath, " + "readable: %s, nTSecurityDescriptor, cn, gPCFileSysPath, " "gPCMachineExtensionNames, gPCFunctionalityVersion, flags. " "Alternatively if you do not have access to the server or can " "not change permissions on this object, you can use option " "ad_gpo_ignore_unreadable = True which will skip this GPO. " "See ad_gpo_ignore_unreadable in 'man sssd-ad' for details.\n", + AD_AT_DISPLAY_NAME, state->candidate_gpos[state->gpo_index]->gpo_dn); return EFAULT; } @@ -4301,6 +4309,7 @@ ad_gpo_sd_process_attrs(struct tevent_req *req, struct gp_gpo *gp_gpo; int ret; struct ldb_message_element *el = NULL; + const char *gpo_dpname = NULL; const char *gpo_guid = NULL; const char *raw_file_sys_path = NULL; char *file_sys_path = NULL; @@ -4309,6 +4318,24 @@ ad_gpo_sd_process_attrs(struct tevent_req *req, state = tevent_req_data(req, struct ad_gpo_process_gpo_state); gp_gpo = state->candidate_gpos[state->gpo_index]; + /* retrieve AD_AT_DISPLAY_NAME */ + ret = sysdb_attrs_get_string(result, AD_AT_DISPLAY_NAME, &gpo_dpname); + if (ret == ENOENT) { + ret = ad_gpo_missing_or_unreadable_attr(state, req); + goto done; + } else if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "sysdb_attrs_get_string failed: [%d](%s)\n", + ret, sss_strerror(ret)); + goto done; + } + + gp_gpo->gpo_dpname = talloc_steal(gp_gpo, gpo_dpname); + if (gp_gpo->gpo_dpname == NULL) { + ret = ENOMEM; + goto done; + } + /* retrieve AD_AT_CN */ ret = sysdb_attrs_get_string(result, AD_AT_CN, &gpo_guid); if (ret == ENOENT) { @@ -4569,6 +4596,7 @@ struct ad_gpo_process_cse_state { struct tevent_context *ev; struct sss_domain_info *domain; int gpo_timeout_option; + const char *gpo_dpname; const char *gpo_guid; const char *smb_path; const char *smb_cse_suffix; @@ -4595,6 +4623,7 @@ ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx, bool send_to_child, struct sss_domain_info *domain, const char *gpo_guid, + const char *gpo_dpname, const char *smb_server, const char *smb_share, const char *smb_path, @@ -4629,6 +4658,7 @@ ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx, state->domain = domain; state->gpo_timeout_option = gpo_timeout_option; state->gpo_guid = gpo_guid; + state->gpo_dpname = gpo_dpname; state->smb_path = smb_path; state->smb_cse_suffix = smb_cse_suffix; state->io = talloc(state, struct child_io_fds); diff --git a/src/providers/ad/ad_gpo.h b/src/providers/ad/ad_gpo.h index 8066511b1..80237e5f3 100644 --- a/src/providers/ad/ad_gpo.h +++ b/src/providers/ad/ad_gpo.h @@ -27,7 +27,8 @@ #define AD_GPO_CHILD_OUT_FILENO 3 -#define AD_GPO_ATTRS {AD_AT_NT_SEC_DESC, \ +#define AD_GPO_ATTRS {AD_AT_DISPLAY_NAME, \ + AD_AT_NT_SEC_DESC, \ AD_AT_CN, AD_AT_FILE_SYS_PATH, \ AD_AT_MACHINE_EXT_NAMES, \ AD_AT_FUNC_VERSION, \ -- 2.44.0 From e485ae783ac72352a1062104e47cf66329a8be9a Mon Sep 17 00:00:00 2001 From: Samuel Cabrero <scabrero@suse.de> Date: Mon, 22 Jan 2024 11:21:32 +0100 Subject: [PATCH 06/15] SYSDB: Store GPO's displayName in sysdb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves: https://github.com/SSSD/sssd/issues/4523 Signed-off-by: Samuel Cabrero <scabrero@suse.de> Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> --- src/db/sysdb.h | 1 + src/db/sysdb_gpo.c | 44 +++++++++++++++++++++++++++++++++++++++ src/providers/ad/ad_gpo.c | 5 +++-- src/tests/sysdb-tests.c | 6 ++++-- 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 250cb08ed..700cb097b 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -1511,6 +1511,7 @@ errno_t sysdb_remove_mapped_data(struct sss_domain_info *domain, NULL } errno_t sysdb_gpo_store_gpo(struct sss_domain_info *domain, + const char *gpo_dpname, const char *gpo_guid, int gpo_version, int cache_timeout, diff --git a/src/db/sysdb_gpo.c b/src/db/sysdb_gpo.c index 777d467cb..44669f954 100644 --- a/src/db/sysdb_gpo.c +++ b/src/db/sysdb_gpo.c @@ -48,6 +48,7 @@ sysdb_gpo_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, errno_t sysdb_gpo_store_gpo(struct sss_domain_info *domain, + const char *gpo_dpname, const char *gpo_guid, int gpo_version, int cache_timeout, @@ -65,6 +66,13 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain, tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; + if (domain->case_sensitive == false) { + gpo_dpname = sss_tc_utf8_str_tolower(tmp_ctx, gpo_dpname); + if (gpo_dpname == NULL) { + return ENOMEM; + } + } + update_msg = ldb_msg_new(tmp_ctx); if (!update_msg) { ret = ENOMEM; @@ -161,6 +169,24 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain, goto done; } + /* Add the GPO description */ + if (gpo_dpname != NULL) { + lret = ldb_msg_add_empty(update_msg, SYSDB_NAME, + LDB_FLAG_MOD_ADD, NULL); + if (lret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(lret); + goto done; + } + + lret = ldb_msg_add_string(update_msg, + SYSDB_NAME, + gpo_dpname); + if (lret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(lret); + goto done; + } + } + lret = ldb_add(domain->sysdb->ldb, update_msg); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, @@ -205,6 +231,24 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain, goto done; } + /* Add the description */ + if (gpo_dpname != NULL) { + lret = ldb_msg_add_empty(update_msg, SYSDB_NAME, + LDB_FLAG_MOD_REPLACE, NULL); + if (lret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(lret); + goto done; + } + + lret = ldb_msg_add_string(update_msg, + SYSDB_NAME, + gpo_dpname); + if (lret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(lret); + goto done; + } + } + lret = ldb_modify(domain->sysdb->ldb, update_msg); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c index a626af2ec..60af886f8 100644 --- a/src/providers/ad/ad_gpo.c +++ b/src/providers/ad/ad_gpo.c @@ -4784,8 +4784,9 @@ static void gpo_cse_done(struct tevent_req *subreq) now = time(NULL); DEBUG(SSSDBG_TRACE_FUNC, "sysvol_gpt_version: %d\n", sysvol_gpt_version); - ret = sysdb_gpo_store_gpo(state->domain, state->gpo_guid, sysvol_gpt_version, - state->gpo_timeout_option, now); + ret = sysdb_gpo_store_gpo(state->domain, state->gpo_dpname, state->gpo_guid, + sysvol_gpt_version, state->gpo_timeout_option, + now); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to store gpo cache entry: [%d](%s}\n", ret, sss_strerror(ret)); diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index b6cd1b195..816f31333 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -7162,6 +7162,7 @@ START_TEST(test_gpo_store_retrieve) const char *guid; int version; static const char *test_guid = "3610EDA5-77EF-11D2-8DC5-00C04FA31A66"; + static const char *test_dpname = "TEST GPO"; ret = setup_sysdb_tests(&test_ctx); sss_ck_fail_if_msg(ret != EOK, "Could not set up the test"); @@ -7174,7 +7175,7 @@ START_TEST(test_gpo_store_retrieve) ret = sysdb_gpo_get_gpos(test_ctx, test_ctx->domain, &result); sss_ck_fail_if_msg(ret != ENOENT, "GPO present in cache before store op"); - ret = sysdb_gpo_store_gpo(test_ctx->domain, + ret = sysdb_gpo_store_gpo(test_ctx->domain, test_dpname, test_guid, 1, 5, 0); sss_ck_fail_if_msg(ret != EOK, "Could not store a test GPO"); @@ -7209,6 +7210,7 @@ START_TEST(test_gpo_replace) const char *guid; int version; static const char *test_guid = "3610EDA5-77EF-11D2-8DC5-00C04FA31A66"; + static const char *test_dpname = "TEST GPO"; ret = setup_sysdb_tests(&test_ctx); sss_ck_fail_if_msg(ret != EOK, "Could not setup the test"); @@ -7228,7 +7230,7 @@ START_TEST(test_gpo_replace) ck_assert_int_eq(version, 1); /* Modify the version */ - ret = sysdb_gpo_store_gpo(test_ctx->domain, + ret = sysdb_gpo_store_gpo(test_ctx->domain, test_dpname, test_guid, 2, 5, 0); sss_ck_fail_if_msg(ret != EOK, "Could not store a test GPO"); -- 2.44.0 From 7803f5de37143f9cccae0cfbc5faf78348bc1f85 Mon Sep 17 00:00:00 2001 From: Samuel Cabrero <scabrero@suse.de> Date: Tue, 23 Jan 2024 14:14:59 +0100 Subject: [PATCH 07/15] SYSDB: Store the GPO's filesystem path in sysdb entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves: https://github.com/SSSD/sssd/issues/4523 Signed-off-by: Samuel Cabrero <scabrero@suse.de> Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> --- src/db/sysdb.h | 2 ++ src/db/sysdb_gpo.c | 31 +++++++++++++++++++++++++++++++ src/providers/ad/ad_gpo.c | 12 ++++++++++-- src/tests/sysdb-tests.c | 6 ++++-- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 700cb097b..9838451af 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -1499,6 +1499,7 @@ errno_t sysdb_remove_mapped_data(struct sss_domain_info *domain, #define SYSDB_GPO_GUID_ATTR "gpoGUID" #define SYSDB_GPO_VERSION_ATTR "gpoVersion" #define SYSDB_GPO_TIMEOUT_ATTR "gpoPolicyFileTimeout" +#define SYSDB_GPO_PATH_ATTR "gpoPath" #define SYSDB_TMPL_GPO_BASE SYSDB_GPO_CONTAINER","SYSDB_DOM_BASE #define SYSDB_TMPL_GPO SYSDB_GPO_GUID_ATTR"=%s,"SYSDB_TMPL_GPO_BASE @@ -1513,6 +1514,7 @@ errno_t sysdb_remove_mapped_data(struct sss_domain_info *domain, errno_t sysdb_gpo_store_gpo(struct sss_domain_info *domain, const char *gpo_dpname, const char *gpo_guid, + const char *gpo_cache_path, int gpo_version, int cache_timeout, time_t now); diff --git a/src/db/sysdb_gpo.c b/src/db/sysdb_gpo.c index 44669f954..f99fefbdc 100644 --- a/src/db/sysdb_gpo.c +++ b/src/db/sysdb_gpo.c @@ -50,6 +50,7 @@ errno_t sysdb_gpo_store_gpo(struct sss_domain_info *domain, const char *gpo_dpname, const char *gpo_guid, + const char *gpo_cache_path, int gpo_version, int cache_timeout, time_t now) @@ -138,6 +139,21 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain, goto done; } + /* Add the cache path */ + lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_PATH_ATTR, + LDB_FLAG_MOD_ADD, + NULL); + if (lret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(lret); + goto done; + } + + lret = ldb_msg_add_string(update_msg, SYSDB_GPO_PATH_ATTR, gpo_cache_path); + if (lret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(lret); + goto done; + } + /* Add the Version */ lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_VERSION_ATTR, LDB_FLAG_MOD_ADD, @@ -200,6 +216,21 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain, DEBUG(SSSDBG_TRACE_ALL, "Updating new GPO [%s][%s]\n", domain->name, gpo_guid); + /* Add the cache path */ + lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_PATH_ATTR, + LDB_FLAG_MOD_REPLACE, + NULL); + if (lret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(lret); + goto done; + } + + lret = ldb_msg_add_string(update_msg, SYSDB_GPO_PATH_ATTR, gpo_cache_path); + if (lret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(lret); + goto done; + } + /* Add the Version */ lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_VERSION_ATTR, LDB_FLAG_MOD_REPLACE, diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c index 60af886f8..9d56efd1f 100644 --- a/src/providers/ad/ad_gpo.c +++ b/src/providers/ad/ad_gpo.c @@ -4600,6 +4600,7 @@ struct ad_gpo_process_cse_state { const char *gpo_guid; const char *smb_path; const char *smb_cse_suffix; + const char *gpo_cache_path; pid_t child_pid; uint8_t *buf; ssize_t len; @@ -4668,6 +4669,13 @@ ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx, goto immediately; } + state->gpo_cache_path = + talloc_asprintf(state, "%s%s", GPO_CACHE_PATH, state->smb_path); + if (state->gpo_cache_path == NULL) { + ret = ENOMEM; + goto immediately; + } + state->io->write_to_child_fd = -1; state->io->read_from_child_fd = -1; talloc_set_destructor((void *) state->io, child_io_destructor); @@ -4785,8 +4793,8 @@ static void gpo_cse_done(struct tevent_req *subreq) now = time(NULL); DEBUG(SSSDBG_TRACE_FUNC, "sysvol_gpt_version: %d\n", sysvol_gpt_version); ret = sysdb_gpo_store_gpo(state->domain, state->gpo_dpname, state->gpo_guid, - sysvol_gpt_version, state->gpo_timeout_option, - now); + state->gpo_cache_path, sysvol_gpt_version, + state->gpo_timeout_option, now); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to store gpo cache entry: [%d](%s}\n", ret, sss_strerror(ret)); diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index 816f31333..8ac5ecd71 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -7163,6 +7163,7 @@ START_TEST(test_gpo_store_retrieve) int version; static const char *test_guid = "3610EDA5-77EF-11D2-8DC5-00C04FA31A66"; static const char *test_dpname = "TEST GPO"; + static const char *test_path = "/tmp/test/gpo"; ret = setup_sysdb_tests(&test_ctx); sss_ck_fail_if_msg(ret != EOK, "Could not set up the test"); @@ -7176,7 +7177,7 @@ START_TEST(test_gpo_store_retrieve) sss_ck_fail_if_msg(ret != ENOENT, "GPO present in cache before store op"); ret = sysdb_gpo_store_gpo(test_ctx->domain, test_dpname, - test_guid, 1, 5, 0); + test_guid, test_path, 1, 5, 0); sss_ck_fail_if_msg(ret != EOK, "Could not store a test GPO"); ret = sysdb_gpo_get_gpos(test_ctx, test_ctx->domain, &result); @@ -7211,6 +7212,7 @@ START_TEST(test_gpo_replace) int version; static const char *test_guid = "3610EDA5-77EF-11D2-8DC5-00C04FA31A66"; static const char *test_dpname = "TEST GPO"; + static const char *test_path = "/tmp/test/gpo"; ret = setup_sysdb_tests(&test_ctx); sss_ck_fail_if_msg(ret != EOK, "Could not setup the test"); @@ -7231,7 +7233,7 @@ START_TEST(test_gpo_replace) /* Modify the version */ ret = sysdb_gpo_store_gpo(test_ctx->domain, test_dpname, - test_guid, 2, 5, 0); + test_guid, test_path, 2, 5, 0); sss_ck_fail_if_msg(ret != EOK, "Could not store a test GPO"); ret = sysdb_gpo_get_gpo_by_guid(test_ctx, test_ctx->domain, -- 2.44.0 From 8ed976f8af4bc3d30396abba77742bfcd57269cb Mon Sep 17 00:00:00 2001 From: Samuel Cabrero <scabrero@suse.de> Date: Mon, 22 Jan 2024 11:57:21 +0100 Subject: [PATCH 08/15] SYSDB: Always canonicalize GPO guid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Always store the guid uppercased and enclosed in curly brackets. Resolves: https://github.com/SSSD/sssd/issues/4523 Signed-off-by: Samuel Cabrero <scabrero@suse.de> Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> --- src/db/sysdb.h | 5 ++ src/db/sysdb_gpo.c | 100 ++++++++++++++++++++++++++++++++++------ src/tests/sysdb-tests.c | 17 +++++-- 3 files changed, 106 insertions(+), 16 deletions(-) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 9838451af..2f325d63d 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -1531,6 +1531,11 @@ errno_t sysdb_gpo_get_gpos(TALLOC_CTX *mem_ctx, struct ldb_dn *sysdb_gpos_base_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom); +errno_t +sysdb_gpo_canon_guid(const char *gpo_guid, + TALLOC_CTX *mem_ctx, + char **canon_gpo_guid); + /* === Functions related to GPO Result object === */ #define SYSDB_GPO_RESULT_OC "gpo_result" diff --git a/src/db/sysdb_gpo.c b/src/db/sysdb_gpo.c index f99fefbdc..fc148abfe 100644 --- a/src/db/sysdb_gpo.c +++ b/src/db/sysdb_gpo.c @@ -23,25 +23,84 @@ #include "db/sysdb.h" #include "db/sysdb_private.h" +#include <ctype.h> + +errno_t +sysdb_gpo_canon_guid(const char *gpo_guid, + TALLOC_CTX *mem_ctx, + char **canon_gpo_guid) +{ + char *canon = NULL; + char *p = NULL; + + if (gpo_guid == NULL || strlen(gpo_guid) == 0) { + return EINVAL; + } + + canon = talloc_strdup(mem_ctx, gpo_guid); + if (canon == NULL) { + return ENOMEM; + } + + if (strlen(canon) < 36) { + talloc_free(canon); + return EINVAL; + } + + for (p = canon; *p != '\0'; p++) { + *p = toupper(*p); + } + + if (canon[0] != '{') { + char *old = canon; + canon = talloc_asprintf(mem_ctx, "{%s", old); + talloc_free(old); + if (canon == NULL) { + return ENOMEM; + } + } + + if (canon[strlen(canon) - 1] != '}') { + char *old = canon; + canon = talloc_asprintf(mem_ctx, "%s}", old); + talloc_free(old); + if (canon == NULL) { + return ENOMEM; + } + } + + *canon_gpo_guid = talloc_move(mem_ctx, &canon); + + return EOK; +} static struct ldb_dn * sysdb_gpo_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *gpo_guid) { errno_t ret; - char *clean_gpo_guid; + char *canon_guid; + char *clean_canon_guid; struct ldb_dn *dn; - ret = sysdb_dn_sanitize(NULL, gpo_guid, &clean_gpo_guid); + ret = sysdb_gpo_canon_guid(gpo_guid, mem_ctx, &canon_guid); if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to canonicalize GPO guid '%s': %s\n", + gpo_guid, strerror(ret)); return NULL; } - DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO"\n", clean_gpo_guid, domain->name); + ret = sysdb_dn_sanitize(NULL, canon_guid, &clean_canon_guid); + if (ret != EOK) { + return NULL; + } + + DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO"\n", clean_canon_guid, domain->name); dn = ldb_dn_new_fmt(mem_ctx, domain->sysdb->ldb, SYSDB_TMPL_GPO, - clean_gpo_guid, domain->name); - talloc_free(clean_gpo_guid); + clean_canon_guid, domain->name); + talloc_free(clean_canon_guid); + talloc_free(canon_guid); return dn; } @@ -63,6 +122,7 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain, size_t count; bool in_transaction = false; TALLOC_CTX *tmp_ctx; + char *canon_guid; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; @@ -74,13 +134,20 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain, } } + ret = sysdb_gpo_canon_guid(gpo_guid, tmp_ctx, &canon_guid); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to canonicalize GPO guid '%s': %s\n", + gpo_guid, strerror(ret)); + goto done; + } + update_msg = ldb_msg_new(tmp_ctx); if (!update_msg) { ret = ENOMEM; goto done; } - update_msg->dn = sysdb_gpo_dn(update_msg, domain, gpo_guid); + update_msg->dn = sysdb_gpo_dn(update_msg, domain, canon_guid); if (!update_msg->dn) { ret = ENOMEM; goto done; @@ -105,8 +172,8 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain, if (ret == ENOENT) { /* Create new GPO */ DEBUG(SSSDBG_TRACE_FUNC, - "Adding new GPO [gpo_guid:%s][gpo_version:%d]\n", - gpo_guid, gpo_version); + "Adding new GPO [canon_guid:%s][gpo_version:%d]\n", + canon_guid, gpo_version); /* Add the objectClass */ lret = ldb_msg_add_empty(update_msg, SYSDB_OBJECTCLASS, @@ -133,7 +200,7 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain, goto done; } - lret = ldb_msg_add_string(update_msg, SYSDB_GPO_GUID_ATTR, gpo_guid); + lret = ldb_msg_add_string(update_msg, SYSDB_GPO_GUID_ATTR, canon_guid); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; @@ -214,7 +281,7 @@ sysdb_gpo_store_gpo(struct sss_domain_info *domain, } else if (ret == EOK && count == 1) { /* Update the existing GPO */ - DEBUG(SSSDBG_TRACE_ALL, "Updating new GPO [%s][%s]\n", domain->name, gpo_guid); + DEBUG(SSSDBG_TRACE_ALL, "Updating new GPO [%s][%s]\n", domain->name, canon_guid); /* Add the cache path */ lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_PATH_ATTR, @@ -323,14 +390,21 @@ sysdb_gpo_get_gpo_by_guid(TALLOC_CTX *mem_ctx, struct ldb_dn *base_dn; TALLOC_CTX *tmp_ctx; struct ldb_result *res; - const char *attrs[] = SYSDB_GPO_ATTRS; + char *canon_guid; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO_BASE"\n", domain->name); + ret = sysdb_gpo_canon_guid(gpo_guid, tmp_ctx, &canon_guid); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to canonicalize GPO guid '%s': %s\n", + gpo_guid, strerror(ret)); + goto done; + } + base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_GPO_BASE, domain->name); @@ -340,7 +414,7 @@ sysdb_gpo_get_gpo_by_guid(TALLOC_CTX *mem_ctx, } lret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn, - LDB_SCOPE_SUBTREE, attrs, SYSDB_GPO_GUID_FILTER, gpo_guid); + LDB_SCOPE_SUBTREE, attrs, SYSDB_GPO_GUID_FILTER, canon_guid); if (lret) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not locate GPO: [%s]\n", @@ -351,7 +425,7 @@ sysdb_gpo_get_gpo_by_guid(TALLOC_CTX *mem_ctx, if (res->count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Search for GUID [%s] returned more than " \ - "one object.\n", gpo_guid); + "one object.\n", canon_guid); ret = EINVAL; goto done; } else if (res->count == 0) { diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index 8ac5ecd71..bf8668094 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -7164,6 +7164,7 @@ START_TEST(test_gpo_store_retrieve) static const char *test_guid = "3610EDA5-77EF-11D2-8DC5-00C04FA31A66"; static const char *test_dpname = "TEST GPO"; static const char *test_path = "/tmp/test/gpo"; + char *canon_guid = NULL; ret = setup_sysdb_tests(&test_ctx); sss_ck_fail_if_msg(ret != EOK, "Could not set up the test"); @@ -7194,7 +7195,11 @@ START_TEST(test_gpo_store_retrieve) guid = ldb_msg_find_attr_as_string(result->msgs[0], SYSDB_GPO_GUID_ATTR, NULL); - ck_assert_str_eq(guid, test_guid); + ck_assert_str_ne(guid, test_guid); + + ret = sysdb_gpo_canon_guid(test_guid, test_ctx, &canon_guid); + sss_ck_fail_if_msg(ret != EOK, "Failed to canonicalize guid"); + ck_assert_str_eq(guid, canon_guid); version = ldb_msg_find_attr_as_uint(result->msgs[0], SYSDB_GPO_VERSION_ATTR, 0); @@ -7213,10 +7218,14 @@ START_TEST(test_gpo_replace) static const char *test_guid = "3610EDA5-77EF-11D2-8DC5-00C04FA31A66"; static const char *test_dpname = "TEST GPO"; static const char *test_path = "/tmp/test/gpo"; + char *canon_guid = NULL; ret = setup_sysdb_tests(&test_ctx); sss_ck_fail_if_msg(ret != EOK, "Could not setup the test"); + ret = sysdb_gpo_canon_guid(test_guid, test_ctx, &canon_guid); + sss_ck_fail_if_msg(ret != EOK, "Failed to canonicalize guid"); + ret = sysdb_gpo_get_gpo_by_guid(test_ctx, test_ctx->domain, test_guid, &result); sss_ck_fail_if_msg(ret != EOK, "GPO not in cache after store op"); @@ -7225,7 +7234,8 @@ START_TEST(test_gpo_replace) guid = ldb_msg_find_attr_as_string(result->msgs[0], SYSDB_GPO_GUID_ATTR, NULL); - ck_assert_str_eq(guid, test_guid); + ck_assert_str_ne(guid, test_guid); + ck_assert_str_eq(guid, canon_guid); version = ldb_msg_find_attr_as_uint(result->msgs[0], SYSDB_GPO_VERSION_ATTR, 0); @@ -7244,7 +7254,8 @@ START_TEST(test_gpo_replace) guid = ldb_msg_find_attr_as_string(result->msgs[0], SYSDB_GPO_GUID_ATTR, NULL); - ck_assert_str_eq(guid, test_guid); + ck_assert_str_ne(guid, test_guid); + ck_assert_str_eq(guid, canon_guid); version = ldb_msg_find_attr_as_uint(result->msgs[0], SYSDB_GPO_VERSION_ATTR, 0); -- 2.44.0 From 4e3d6e37164b72692354d3fba7d63bd1ab21a972 Mon Sep 17 00:00:00 2001 From: Samuel Cabrero <scabrero@suse.de> Date: Tue, 13 Feb 2024 13:40:37 +0100 Subject: [PATCH 09/15] SYSDB: Add new index for gpoGUID and make searches on it case insensitive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Samuel Cabrero <scabrero@suse.de> Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> --- src/db/sysdb_private.h | 2 ++ src/db/sysdb_upgrade.c | 48 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h index 63f7b5601..2d7d6f62d 100644 --- a/src/db/sysdb_private.h +++ b/src/db/sysdb_private.h @@ -62,6 +62,7 @@ "ipHostNumber: CASE_INSENSITIVE\n" \ "ipNetworkNumber: CASE_INSENSITIVE\n" \ "mail: CASE_INSENSITIVE\n" \ + "gpoGUID: CASE_INSENSITIVE\n" \ "\n" \ "dn: @INDEXLIST\n" \ "@IDXATTR: cn\n" \ @@ -90,6 +91,7 @@ "@IDXATTR: ipHostNumber\n" \ "@IDXATTR: ipNetworkNumber\n" \ "@IDXATTR: originalADgidNumber\n" \ + "@IDXATTR: gpoGUID\n" \ "\n" \ "dn: @MODULES\n" \ "@LIST: asq,memberof\n" \ diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c index 56083e6be..10f73bab7 100644 --- a/src/db/sysdb_upgrade.c +++ b/src/db/sysdb_upgrade.c @@ -2735,7 +2735,6 @@ int sysdb_upgrade_23(struct sysdb_ctx *sysdb, const char **ver) return ret; } - /* Add new indexes */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; @@ -2759,12 +2758,59 @@ int sysdb_upgrade_23(struct sysdb_ctx *sysdb, const char **ver) goto done; } + /* Case insensitive search for gpoGUID */ + ret = ldb_msg_add_empty(msg, SYSDB_GPO_GUID_ATTR, LDB_FLAG_MOD_ADD, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + ret = ldb_msg_add_string(msg, SYSDB_GPO_GUID_ATTR, "CASE_INSENSITIVE"); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } + talloc_free(msg); + + /* Add new indices */ + msg = ldb_msg_new(ctx); + if (msg == NULL) { + ret = ENOMEM; + goto done; + } + + msg->dn = ldb_dn_new(msg, sysdb->ldb, "@INDEXLIST"); + if (msg->dn == NULL) { + ret = ENOMEM; + goto done; + } + + ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_msg_add_string(msg, "@IDXATTR", SYSDB_GPO_GUID_ATTR); + if (ret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + ret = ldb_modify(sysdb->ldb, msg); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); + goto done; + } + + talloc_free(msg); + /* conversion done, update version number */ ret = update_version(ctx); -- 2.44.0 From 617682d200d3212a5f4590ee7ffbda8d0eec9d0a Mon Sep 17 00:00:00 2001 From: Samuel Cabrero <scabrero@suse.de> Date: Tue, 13 Feb 2024 12:56:08 +0100 Subject: [PATCH 10/15] SSSCTL: Prepare for extended help in subcommands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Samuel Cabrero <scabrero@suse.de> Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> --- src/tools/common/sss_tools.c | 11 ++++++++++- src/tools/common/sss_tools.h | 1 + src/tools/sss_override.c | 8 ++++---- src/tools/sssctl/sssctl_access_report.c | 2 +- src/tools/sssctl/sssctl_cache.c | 13 +++++++++---- src/tools/sssctl/sssctl_cert.c | 6 +++--- src/tools/sssctl/sssctl_data.c | 2 +- src/tools/sssctl/sssctl_domains.c | 2 +- src/tools/sssctl/sssctl_logs.c | 4 ++-- src/tools/sssctl/sssctl_user_checks.c | 2 +- 10 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/tools/common/sss_tools.c b/src/tools/common/sss_tools.c index e67de3a66..7f0b578cc 100644 --- a/src/tools/common/sss_tools.c +++ b/src/tools/common/sss_tools.c @@ -384,6 +384,7 @@ static struct poptOption *nonnull_popt_table(struct poptOption *options) errno_t sss_tool_popt_ex(struct sss_cmdline *cmdline, struct poptOption *options, + const char *extended_help, enum sss_tool_opt require_option, sss_popt_fn popt_fn, void *popt_fn_pvt, @@ -426,6 +427,14 @@ errno_t sss_tool_popt_ex(struct sss_cmdline *cmdline, return ENOMEM; } + if (extended_help != NULL) { + help = talloc_asprintf_append(help, "\n\n%s", extended_help); + if (help == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append() failed\n"); + return ENOMEM; + } + } + /* Create popt context. This function is supposed to be called on * command argv which does not contain executable (argv[0]), therefore * we need to use KEEP_FIRST that ensures argv[0] is also processed. */ @@ -526,7 +535,7 @@ errno_t sss_tool_popt(struct sss_cmdline *cmdline, sss_popt_fn popt_fn, void *popt_fn_pvt) { - return sss_tool_popt_ex(cmdline, options, require_option, + return sss_tool_popt_ex(cmdline, options, NULL, require_option, popt_fn, popt_fn_pvt, NULL, NULL, SSS_TOOL_OPT_REQUIRED, NULL, NULL); } diff --git a/src/tools/common/sss_tools.h b/src/tools/common/sss_tools.h index af4967501..69d35bde0 100644 --- a/src/tools/common/sss_tools.h +++ b/src/tools/common/sss_tools.h @@ -74,6 +74,7 @@ enum sss_tool_opt { errno_t sss_tool_popt_ex(struct sss_cmdline *cmdline, struct poptOption *options, + const char *extended_help, enum sss_tool_opt require_option, sss_popt_fn popt_fn, void *popt_fn_pvt, diff --git a/src/tools/sss_override.c b/src/tools/sss_override.c index cfd8f17fa..775231970 100644 --- a/src/tools/sss_override.c +++ b/src/tools/sss_override.c @@ -70,7 +70,7 @@ static errno_t parse_cmdline(struct sss_cmdline *cmdline, *_input_name = NULL; require = options == NULL ? SSS_TOOL_OPT_OPTIONAL : SSS_TOOL_OPT_REQUIRED; - ret = sss_tool_popt_ex(cmdline, options, require, + ret = sss_tool_popt_ex(cmdline, options, NULL, require, NULL, NULL, "NAME", _("Specify name."), SSS_TOOL_OPT_REQUIRED, &input_name, NULL); if (ret != EXIT_SUCCESS) { @@ -171,7 +171,7 @@ static errno_t parse_cmdline_find(struct sss_cmdline *cmdline, POPT_TABLEEND }; - ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL, + ret = sss_tool_popt_ex(cmdline, options, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, NULL, NULL, SSS_TOOL_OPT_REQUIRED, NULL, NULL); if (ret != EOK) { @@ -201,7 +201,7 @@ static errno_t parse_cmdline_import(struct sss_cmdline *cmdline, { errno_t ret; - ret = sss_tool_popt_ex(cmdline, NULL, SSS_TOOL_OPT_OPTIONAL, + ret = sss_tool_popt_ex(cmdline, NULL, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, "FILE", "File to import the data from.", SSS_TOOL_OPT_REQUIRED, _file, NULL); if (ret != EOK) { @@ -217,7 +217,7 @@ static errno_t parse_cmdline_export(struct sss_cmdline *cmdline, { errno_t ret; - ret = sss_tool_popt_ex(cmdline, NULL, SSS_TOOL_OPT_OPTIONAL, + ret = sss_tool_popt_ex(cmdline, NULL, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, "FILE", "File to export the data to.", SSS_TOOL_OPT_REQUIRED, _file, NULL); if (ret != EOK) { diff --git a/src/tools/sssctl/sssctl_access_report.c b/src/tools/sssctl/sssctl_access_report.c index 5ae873d76..ddcb05417 100644 --- a/src/tools/sssctl/sssctl_access_report.c +++ b/src/tools/sssctl/sssctl_access_report.c @@ -391,7 +391,7 @@ errno_t sssctl_access_report(struct sss_cmdline *cmdline, sssctl_dom_access_reporter_fn reporter; struct sss_domain_info *dom; - ret = sss_tool_popt_ex(cmdline, NULL, SSS_TOOL_OPT_OPTIONAL, + ret = sss_tool_popt_ex(cmdline, NULL, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, "DOMAIN", _("Specify domain name."), SSS_TOOL_OPT_REQUIRED, &domname, NULL); if (ret != EOK) { diff --git a/src/tools/sssctl/sssctl_cache.c b/src/tools/sssctl/sssctl_cache.c index 5a62a2646..81adc3565 100644 --- a/src/tools/sssctl/sssctl_cache.c +++ b/src/tools/sssctl/sssctl_cache.c @@ -554,6 +554,7 @@ done: static errno_t parse_cmdline(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, struct poptOption *options, + const char *extended_help, const char **_orig_name, struct sss_domain_info **_domain) { @@ -562,7 +563,8 @@ static errno_t parse_cmdline(struct sss_cmdline *cmdline, struct sss_domain_info *domain; int ret; - ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL, + ret = sss_tool_popt_ex(cmdline, options, extended_help, + SSS_TOOL_OPT_OPTIONAL, NULL, NULL, "NAME", _("Specify name."), SSS_TOOL_OPT_REQUIRED, &input_name, NULL); if (ret != EOK) { @@ -617,7 +619,8 @@ errno_t sssctl_user_show(struct sss_cmdline *cmdline, SSSCTL_CACHE_NULL }; - ret = parse_cmdline(cmdline, tool_ctx, options, &opts.value, &opts.domain); + ret = parse_cmdline(cmdline, tool_ctx, options, NULL, &opts.value, + &opts.domain); if (ret != EOK) { return ret; } @@ -663,7 +666,8 @@ errno_t sssctl_group_show(struct sss_cmdline *cmdline, SSSCTL_CACHE_NULL }; - ret = parse_cmdline(cmdline, tool_ctx, options, &opts.value, &opts.domain); + ret = parse_cmdline(cmdline, tool_ctx, options, NULL, &opts.value, + &opts.domain); if (ret != EOK) { return ret; } @@ -701,7 +705,8 @@ errno_t sssctl_netgroup_show(struct sss_cmdline *cmdline, SSSCTL_CACHE_NULL }; - ret = parse_cmdline(cmdline, tool_ctx, NULL, &opts.value, &opts.domain); + ret = parse_cmdline(cmdline, tool_ctx, NULL, NULL, &opts.value, + &opts.domain); if (ret != EOK) { return ret; } diff --git a/src/tools/sssctl/sssctl_cert.c b/src/tools/sssctl/sssctl_cert.c index d2cdc2dff..36385ac00 100644 --- a/src/tools/sssctl/sssctl_cert.c +++ b/src/tools/sssctl/sssctl_cert.c @@ -52,7 +52,7 @@ errno_t sssctl_cert_show(struct sss_cmdline *cmdline, POPT_TABLEEND }; - ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL, + ret = sss_tool_popt_ex(cmdline, options, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, "CERTIFICATE-BASE64-ENCODED", _("Specify base64 encoded certificate."), SSS_TOOL_OPT_REQUIRED, &cert_b64, NULL); @@ -111,7 +111,7 @@ errno_t sssctl_cert_map(struct sss_cmdline *cmdline, POPT_TABLEEND }; - ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL, + ret = sss_tool_popt_ex(cmdline, options, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, "CERTIFICATE-BASE64-ENCODED", _("Specify base64 encoded certificate."), SSS_TOOL_OPT_REQUIRED, &cert_b64, NULL); @@ -218,7 +218,7 @@ errno_t sssctl_cert_eval_rule(struct sss_cmdline *cmdline, POPT_TABLEEND }; - ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL, + ret = sss_tool_popt_ex(cmdline, options, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, "CERTIFICATE-BASE64-ENCODED", _("Specify base64 encoded certificate."), SSS_TOOL_OPT_REQUIRED, &cert_b64, NULL); diff --git a/src/tools/sssctl/sssctl_data.c b/src/tools/sssctl/sssctl_data.c index 82f80c61e..cf44a428b 100644 --- a/src/tools/sssctl/sssctl_data.c +++ b/src/tools/sssctl/sssctl_data.c @@ -470,7 +470,7 @@ errno_t sssctl_cache_index(struct sss_cmdline *cmdline, POPT_TABLEEND }; - ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, + ret = sss_tool_popt_ex(cmdline, options, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, "ACTION", "create | delete | list", SSS_TOOL_OPT_REQUIRED, &action_str, NULL); if (ret != EOK) { diff --git a/src/tools/sssctl/sssctl_domains.c b/src/tools/sssctl/sssctl_domains.c index ee8cb138c..448e4d8ad 100644 --- a/src/tools/sssctl/sssctl_domains.c +++ b/src/tools/sssctl/sssctl_domains.c @@ -329,7 +329,7 @@ errno_t sssctl_domain_status(struct sss_cmdline *cmdline, POPT_TABLEEND }; - ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL, + ret = sss_tool_popt_ex(cmdline, options, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, "DOMAIN", _("Specify domain name."), SSS_TOOL_OPT_REQUIRED, &opts.domain, &opt_set); if (ret != EOK) { diff --git a/src/tools/sssctl/sssctl_logs.c b/src/tools/sssctl/sssctl_logs.c index f8f5a6580..2fa566d0d 100644 --- a/src/tools/sssctl/sssctl_logs.c +++ b/src/tools/sssctl/sssctl_logs.c @@ -480,7 +480,7 @@ errno_t sssctl_logs_fetch(struct sss_cmdline *cmdline, glob_t globbuf; /* Parse command line. */ - ret = sss_tool_popt_ex(cmdline, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, + ret = sss_tool_popt_ex(cmdline, NULL, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, "FILE", "Output file", SSS_TOOL_OPT_REQUIRED, &file, NULL); if (ret != EOK) { @@ -547,7 +547,7 @@ errno_t sssctl_debug_level(struct sss_cmdline *cmdline, goto fini; } - ret = sss_tool_popt_ex(cmdline, long_options, SSS_TOOL_OPT_OPTIONAL, NULL, + ret = sss_tool_popt_ex(cmdline, long_options, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, "DEBUG_LEVEL_TO_SET", _("Specify debug level you want to set"), SSS_TOOL_OPT_OPTIONAL, &debug_as_string, NULL); diff --git a/src/tools/sssctl/sssctl_user_checks.c b/src/tools/sssctl/sssctl_user_checks.c index 41cf765e9..58313b803 100644 --- a/src/tools/sssctl/sssctl_user_checks.c +++ b/src/tools/sssctl/sssctl_user_checks.c @@ -236,7 +236,7 @@ errno_t sssctl_user_checks(struct sss_cmdline *cmdline, POPT_TABLEEND }; - ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL, + ret = sss_tool_popt_ex(cmdline, options, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, "USERNAME", _("Specify user name."), SSS_TOOL_OPT_REQUIRED, &user, NULL); if (ret != EOK) { -- 2.44.0 From f69f356bade42a62e594e033a667b123bd5cc1b4 Mon Sep 17 00:00:00 2001 From: Samuel Cabrero <scabrero@suse.de> Date: Mon, 22 Jan 2024 12:00:44 +0100 Subject: [PATCH 11/15] SSSCTL: Add gpo-show command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves: https://github.com/SSSD/sssd/issues/4523 Signed-off-by: Samuel Cabrero <scabrero@suse.de> Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> --- src/tools/sssctl/sssctl.c | 2 + src/tools/sssctl/sssctl.h | 5 ++ src/tools/sssctl/sssctl_cache.c | 103 +++++++++++++++++++++++++++++++- 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c index 04c41aa9a..515c566ee 100644 --- a/src/tools/sssctl/sssctl.c +++ b/src/tools/sssctl/sssctl.c @@ -343,6 +343,8 @@ int main(int argc, const char **argv) SSS_TOOL_COMMAND_FLAGS("cert-show", "Print information about the certificate", 0, sssctl_cert_show, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), SSS_TOOL_COMMAND("cert-map", "Show users mapped to the certificate", 0, sssctl_cert_map), SSS_TOOL_COMMAND_FLAGS("cert-eval-rule", "Check mapping and matching rule with a certificate", 0, sssctl_cert_eval_rule, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), + SSS_TOOL_DELIMITER("GPOs related tools:"), + SSS_TOOL_COMMAND("gpo-show", "Information about cached GPO", 0, sssctl_gpo_show), #ifdef BUILD_PASSKEY SSS_TOOL_DELIMITER("Passkey related tools:"), SSS_TOOL_COMMAND_FLAGS("passkey-register", "Perform passkey registration", 0, sssctl_passkey_register, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), diff --git a/src/tools/sssctl/sssctl.h b/src/tools/sssctl/sssctl.h index 3a53a8904..b0792b566 100644 --- a/src/tools/sssctl/sssctl.h +++ b/src/tools/sssctl/sssctl.h @@ -149,4 +149,9 @@ errno_t sssctl_passkey_register(struct sss_cmdline *cmdline, errno_t sssctl_cert_eval_rule(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt); + +errno_t sssctl_gpo_show(struct sss_cmdline *cmdline, + struct sss_tool_ctx *tool_ctx, + void *pvt); + #endif /* _SSSCTL_H_ */ diff --git a/src/tools/sssctl/sssctl_cache.c b/src/tools/sssctl/sssctl_cache.c index 81adc3565..229302f1c 100644 --- a/src/tools/sssctl/sssctl_cache.c +++ b/src/tools/sssctl/sssctl_cache.c @@ -35,12 +35,18 @@ #define SSSCTL_CACHE_UPDATE {_("Cache entry last update time"), SYSDB_LAST_UPDATE, get_attr_time} #define SSSCTL_CACHE_EXPIRE {_("Cache entry expiration time"), SYSDB_CACHE_EXPIRE, get_attr_expire} #define SSSCTL_CACHE_IFP {_("Cached in InfoPipe"), SYSDB_IFP_CACHED, get_attr_yesno} +#define SSSCTL_CACHE_GPO_NAME {_("Policy Name"), SYSDB_NAME, get_attr_string} +#define SSSCTL_CACHE_GPO_GUID {_("Policy GUID"), SYSDB_GPO_GUID_ATTR, get_attr_string} +#define SSSCTL_CACHE_GPO_PATH {_("Policy Path"), SYSDB_GPO_PATH_ATTR, get_attr_string} +#define SSSCTL_CACHE_GPO_TIMEOUT {_("Policy file timeout"), SYSDB_GPO_TIMEOUT_ATTR, get_attr_time} +#define SSSCTL_CACHE_GPO_VERSION {_("Policy version"), SYSDB_GPO_VERSION_ATTR, get_attr_string} #define SSSCTL_CACHE_NULL {NULL, NULL, NULL} enum cache_object { CACHED_USER, CACHED_GROUP, CACHED_NETGROUP, + CACHED_GPO, }; typedef errno_t (*sssctl_attr_fn)(TALLOC_CTX *mem_ctx, @@ -167,6 +173,26 @@ static errno_t get_attr_expire(TALLOC_CTX *mem_ctx, return time_to_string(mem_ctx, value, _value); } +static errno_t get_attr_string(TALLOC_CTX *mem_ctx, + struct sysdb_attrs *entry, + struct sss_domain_info *dom, + const char *attr, const char **_value) +{ + errno_t ret; + const char *value; + + ret = sysdb_attrs_get_string(entry, attr, &value); + if (ret == ENOENT) { + value = "-"; + } else if (ret != EOK) { + return ret; + } + + *_value = value; + + return EOK; +} + static errno_t attr_initgr(TALLOC_CTX *mem_ctx, struct sysdb_attrs *entry, struct sss_domain_info *dom, @@ -322,6 +348,9 @@ static const char *sssctl_create_filter(TALLOC_CTX *mem_ctx, case CACHED_NETGROUP: class = SYSDB_NETGROUP_CLASS; break; + case CACHED_GPO: + class = SYSDB_GPO_OC; + break; default: DEBUG(SSSDBG_FATAL_FAILURE, "sssctl doesn't handle this object type (type=%d)\n", obj_type); @@ -337,7 +366,20 @@ static const char *sssctl_create_filter(TALLOC_CTX *mem_ctx, return NULL; } - if (dom->case_sensitive == false) { + if (obj_type == CACHED_GPO && strcmp(attr_name, SYSDB_GPO_GUID_ATTR) == 0) { + char *filter_value_old; + errno_t ret; + + filter_value_old = filter_value; + ret = sysdb_gpo_canon_guid(filter_value, mem_ctx, &filter_value); + talloc_free(filter_value_old); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Failed to canonicalize GPO GUID '%s': %s\n", + filter_value, strerror(ret)); + return NULL; + } + } else if (dom->case_sensitive == false) { char *filter_value_old; filter_value_old = filter_value; @@ -346,7 +388,9 @@ static const char *sssctl_create_filter(TALLOC_CTX *mem_ctx, } filter = talloc_asprintf(mem_ctx, "(&(%s=%s)(|(%s=%s)(%s=%s)))", - obj_type == CACHED_NETGROUP ? SYSDB_OBJECTCLASS : SYSDB_OBJECTCATEGORY, + (obj_type == CACHED_NETGROUP || + obj_type == CACHED_GPO) ? + SYSDB_OBJECTCLASS : SYSDB_OBJECTCATEGORY, class, attr_name, filter_value, SYSDB_NAME_ALIAS, filter_value); @@ -593,6 +637,7 @@ struct sssctl_cache_opts { const char *value; int sid; int id; + const char *guid; }; errno_t sssctl_user_show(struct sss_cmdline *cmdline, @@ -718,6 +763,60 @@ errno_t sssctl_netgroup_show(struct sss_cmdline *cmdline, return ret; } + return EOK; +} + +errno_t sssctl_gpo_show(struct sss_cmdline *cmdline, + struct sss_tool_ctx *tool_ctx, + void *pvt) +{ + struct sssctl_cache_opts opts = {0}; + const char *attr; + errno_t ret; + const char *extended_help = + "This command requires the domain name to be given because the " + "same policy name (or GUID) might exists in different domains.\nE.g.:\n" + " 'Default Domain Policy'@one.test\n" + " 'Default Domain Policy'@two.test"; + + struct sssctl_object_info info[] = { + SSSCTL_CACHE_GPO_NAME, + SSSCTL_CACHE_GPO_GUID, + SSSCTL_CACHE_GPO_PATH, + SSSCTL_CACHE_GPO_VERSION, + SSSCTL_CACHE_GPO_TIMEOUT, + SSSCTL_CACHE_NULL + }; + + struct poptOption options[] = { + {"guid", 'g', POPT_ARG_NONE, &opts.guid, 0, _("Search by GPO guid"), NULL }, + POPT_TABLEEND + }; + + ret = parse_cmdline(cmdline, tool_ctx, options, extended_help, &opts.value, + &opts.domain); + if (ret != EOK) { + ERROR("Failed to parse command line: %s\n", sss_strerror(ret)); + return ret; + } + + if (opts.domain == NULL) { + ERROR("%s\n", extended_help); + return EINVAL; + } + + attr = SYSDB_NAME; + if (opts.guid) { + attr = SYSDB_GPO_GUID_ATTR; + } + + ret = sssctl_print_object(info, tool_ctx->domains, opts.domain, + sysdb_gpos_base_dn, NOT_FOUND_MSG("GPO"), + CACHED_GPO, attr, opts.value); + if (ret != EOK) { + ERROR("Failed to print object: %s\n", sss_strerror(ret)); + return ret; + } return EOK; } -- 2.44.0 From 907caa434dc66ea6e89c7009c6506548801c011f Mon Sep 17 00:00:00 2001 From: Samuel Cabrero <scabrero@suse.de> Date: Mon, 22 Jan 2024 14:50:23 +0100 Subject: [PATCH 12/15] SSSCTL: Add sssctl gpo-list command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves: https://github.com/SSSD/sssd/issues/4523 Signed-off-by: Samuel Cabrero <scabrero@suse.de> Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> --- src/tools/sssctl/sssctl.c | 1 + src/tools/sssctl/sssctl.h | 4 + src/tools/sssctl/sssctl_cache.c | 161 ++++++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+) diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c index 515c566ee..7ee0f03f2 100644 --- a/src/tools/sssctl/sssctl.c +++ b/src/tools/sssctl/sssctl.c @@ -345,6 +345,7 @@ int main(int argc, const char **argv) SSS_TOOL_COMMAND_FLAGS("cert-eval-rule", "Check mapping and matching rule with a certificate", 0, sssctl_cert_eval_rule, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), SSS_TOOL_DELIMITER("GPOs related tools:"), SSS_TOOL_COMMAND("gpo-show", "Information about cached GPO", 0, sssctl_gpo_show), + SSS_TOOL_COMMAND("gpo-list", "Enumerate cached GPOs", 0, sssctl_gpo_list), #ifdef BUILD_PASSKEY SSS_TOOL_DELIMITER("Passkey related tools:"), SSS_TOOL_COMMAND_FLAGS("passkey-register", "Perform passkey registration", 0, sssctl_passkey_register, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), diff --git a/src/tools/sssctl/sssctl.h b/src/tools/sssctl/sssctl.h index b0792b566..9cae7ddd7 100644 --- a/src/tools/sssctl/sssctl.h +++ b/src/tools/sssctl/sssctl.h @@ -154,4 +154,8 @@ errno_t sssctl_gpo_show(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt); +errno_t sssctl_gpo_list(struct sss_cmdline *cmdline, + struct sss_tool_ctx *tool_ctx, + void *pvt); + #endif /* _SSSCTL_H_ */ diff --git a/src/tools/sssctl/sssctl_cache.c b/src/tools/sssctl/sssctl_cache.c index 229302f1c..2d33a4341 100644 --- a/src/tools/sssctl/sssctl_cache.c +++ b/src/tools/sssctl/sssctl_cache.c @@ -820,3 +820,164 @@ errno_t sssctl_gpo_show(struct sss_cmdline *cmdline, return EOK; } + +typedef errno_t (*sssctl_gpo_traverse_func)(struct sss_domain_info *, + struct sssctl_object_info *, + struct sysdb_attrs *, + void *); + +static int sssctl_gpo_traverse(TALLOC_CTX *mem_ctx, + const char *domain_prompt, + struct sss_domain_info *domains, + sssctl_gpo_traverse_func fn, + void *private_data) +{ + TALLOC_CTX *tmp_ctx = NULL; + struct sssctl_object_info info[] = { + SSSCTL_CACHE_GPO_NAME, + SSSCTL_CACHE_GPO_GUID, + SSSCTL_CACHE_GPO_PATH, + SSSCTL_CACHE_NULL + }; + struct sss_domain_info *dom = NULL; + const char **attrs = NULL; + const char *filter = NULL; + errno_t ret; + + tmp_ctx = talloc_new(mem_ctx); + if (tmp_ctx == NULL) { + ERROR("talloc failed\n"); + return ENOMEM; + } + + attrs = sssctl_build_attrs(tmp_ctx, info); + if (attrs == NULL) { + ERROR("Unable to get attribute list!\n"); + ret = ENOMEM; + goto done; + } + + filter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_OBJECTCLASS, SYSDB_GPO_OC); + if (filter == NULL) { + ERROR("Unable to create filter\n"); + ret = ENOMEM; + goto done; + } + + for (dom = domains; dom != NULL; + dom = get_next_domain(dom, SSS_GND_DESCEND)) { + struct ldb_message **msgs = NULL; + struct sysdb_attrs **sysdb_attrs = NULL; + struct ldb_dn *base_dn = NULL; + size_t count; + + if (domain_prompt != NULL) { + PRINT("%s [%s]:\n", domain_prompt, dom->name); + } + + base_dn = sysdb_gpos_base_dn(tmp_ctx, dom); + if (base_dn == NULL) { + ERROR("Unable to get GPOs base DN\n"); + ret = ENOMEM; + goto done; + } + + ret = sysdb_search_entry(tmp_ctx, dom->sysdb, base_dn, LDB_SCOPE_SUBTREE, + filter, attrs, &count, &msgs); + if (ret == ENOENT) { + continue; + } else if (ret != EOK) { + ERROR("Unable to search sysdb: %s\n", sss_strerror(ret)); + goto done; + } + + ret = sysdb_msg2attrs(tmp_ctx, count, msgs, &sysdb_attrs); + if (ret != EOK) { + ERROR("Unable to convert message to sysdb attrs: %s\n", sss_strerror(ret)); + goto done; + } + TALLOC_FREE(msgs); + + for (size_t i = 0; i < count; i++) { + struct sysdb_attrs *entry = sysdb_attrs[i]; + + if (fn) { + ret = fn(dom, info, entry, private_data); + if (ret != EOK) { + break; + } + } + } + } + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t sssctl_gpo_print(struct sss_domain_info *dom, + struct sssctl_object_info *info, + struct sysdb_attrs *entry, + void *private_data) +{ + TALLOC_CTX *tmp_ctx = NULL; + const char *value = NULL; + errno_t ret; + + tmp_ctx = talloc_new(entry); + if (tmp_ctx == NULL) { + ERROR("talloc failed\n"); + return ENOMEM; + } + + for (size_t j = 0; info[j].attr != NULL; j++) { + ret = info[j].attr_fn(tmp_ctx, entry, dom, info[j].attr, &value); + if (ret == ENOENT) { + continue; + } else if (ret != EOK) { + ERROR("%s: Unable to read value [%d]: %s\n", + info[j].msg, ret, sss_strerror(ret)); + goto done; + } + PRINT("\t%s: %s\n", info[j].msg, value); + } + PRINT("\n"); + ret = EOK; +done: + talloc_free(tmp_ctx); + + return ret; +} + +errno_t sssctl_gpo_list(struct sss_cmdline *cmdline, + struct sss_tool_ctx *tool_ctx, + void *pvt) +{ + TALLOC_CTX *tmp_ctx = NULL; + const char *domain_prompt = NULL; + errno_t ret; + + tmp_ctx = talloc_new(tool_ctx); + if (tmp_ctx == NULL) { + ERROR("talloc failed\n"); + return ENOMEM; + } + + domain_prompt = talloc_strdup(tmp_ctx, "Cached GPOs in domain"); + if (domain_prompt == NULL) { + ERROR("talloc failed\n"); + ret = ENOMEM; + goto done; + } + + ret = sssctl_gpo_traverse(tmp_ctx, domain_prompt, tool_ctx->domains, + sssctl_gpo_print, NULL); + +done: + talloc_free(tmp_ctx); + + return ret; +} -- 2.44.0 From aee5d029c0ed6dc57f033c1d3aa4a1ef410af084 Mon Sep 17 00:00:00 2001 From: Samuel Cabrero <scabrero@suse.de> Date: Tue, 23 Jan 2024 20:19:23 +0100 Subject: [PATCH 13/15] SYSDB: Add a function to delete GPO entry by GPO GUID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves: https://github.com/SSSD/sssd/issues/4523 Signed-off-by: Samuel Cabrero <scabrero@suse.de> Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> --- src/db/sysdb.h | 4 ++++ src/db/sysdb_gpo.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 2f325d63d..68d9bfc4f 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -1536,6 +1536,10 @@ sysdb_gpo_canon_guid(const char *gpo_guid, TALLOC_CTX *mem_ctx, char **canon_gpo_guid); +errno_t sysdb_gpo_delete_gpo_by_guid(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *gpo_guid); + /* === Functions related to GPO Result object === */ #define SYSDB_GPO_RESULT_OC "gpo_result" diff --git a/src/db/sysdb_gpo.c b/src/db/sysdb_gpo.c index fc148abfe..bb4198703 100644 --- a/src/db/sysdb_gpo.c +++ b/src/db/sysdb_gpo.c @@ -839,3 +839,53 @@ struct ldb_dn *sysdb_gpos_base_dn(TALLOC_CTX *mem_ctx, return ldb_dn_new_fmt(mem_ctx, dom->sysdb->ldb, SYSDB_TMPL_GPO_BASE, dom->name); } + +errno_t sysdb_gpo_delete_gpo_by_guid(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *gpo_guid) +{ + struct ldb_result *res = NULL; + bool in_transaction = false; + errno_t ret, sret; + + ret = sysdb_transaction_start(domain->sysdb); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); + goto done; + } + + in_transaction = true; + + ret = sysdb_gpo_get_gpo_by_guid(mem_ctx, domain, gpo_guid, &res); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_OP_FAILURE, + "Could not delete GPO object: %d\n", ret); + goto done; + } else if (ret != ENOENT) { + DEBUG(SSSDBG_TRACE_FUNC, "Deleting GPO object\n"); + + ret = sysdb_delete_entry(domain->sysdb, res->msgs[0]->dn, true); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Could not delete GPO cache entry\n"); + goto done; + } + } + + ret = sysdb_transaction_commit(domain->sysdb); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not commit transaction: [%s]\n", strerror(ret)); + goto done; + } + in_transaction = false; + +done: + if (in_transaction) { + sret = sysdb_transaction_cancel(domain->sysdb); + if (sret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); + } + } + return ret; +} -- 2.44.0 From ff3e0c2e8a1ce55b4b1da6ac11fbaefdd78c6de1 Mon Sep 17 00:00:00 2001 From: Samuel Cabrero <scabrero@suse.de> Date: Tue, 23 Jan 2024 20:19:59 +0100 Subject: [PATCH 14/15] SSSCTL: Add sssctl gpo-remove command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves: https://github.com/SSSD/sssd/issues/4523 Signed-off-by: Samuel Cabrero <scabrero@suse.de> Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> --- src/tools/sssctl/sssctl.c | 1 + src/tools/sssctl/sssctl.h | 4 + src/tools/sssctl/sssctl_cache.c | 209 ++++++++++++++++++++++++++++++++ 3 files changed, 214 insertions(+) diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c index 7ee0f03f2..9f681c910 100644 --- a/src/tools/sssctl/sssctl.c +++ b/src/tools/sssctl/sssctl.c @@ -346,6 +346,7 @@ int main(int argc, const char **argv) SSS_TOOL_DELIMITER("GPOs related tools:"), SSS_TOOL_COMMAND("gpo-show", "Information about cached GPO", 0, sssctl_gpo_show), SSS_TOOL_COMMAND("gpo-list", "Enumerate cached GPOs", 0, sssctl_gpo_list), + SSS_TOOL_COMMAND("gpo-remove", "Remove cached GPO", 0, sssctl_gpo_remove), #ifdef BUILD_PASSKEY SSS_TOOL_DELIMITER("Passkey related tools:"), SSS_TOOL_COMMAND_FLAGS("passkey-register", "Perform passkey registration", 0, sssctl_passkey_register, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), diff --git a/src/tools/sssctl/sssctl.h b/src/tools/sssctl/sssctl.h index 9cae7ddd7..7c7b6b069 100644 --- a/src/tools/sssctl/sssctl.h +++ b/src/tools/sssctl/sssctl.h @@ -158,4 +158,8 @@ errno_t sssctl_gpo_list(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt); +errno_t sssctl_gpo_remove(struct sss_cmdline *cmdline, + struct sss_tool_ctx *tool_ctx, + void *pvt); + #endif /* _SSSCTL_H_ */ diff --git a/src/tools/sssctl/sssctl_cache.c b/src/tools/sssctl/sssctl_cache.c index 2d33a4341..60eb9ef68 100644 --- a/src/tools/sssctl/sssctl_cache.c +++ b/src/tools/sssctl/sssctl_cache.c @@ -975,6 +975,215 @@ errno_t sssctl_gpo_list(struct sss_cmdline *cmdline, ret = sssctl_gpo_traverse(tmp_ctx, domain_prompt, tool_ctx->domains, sssctl_gpo_print, NULL); +done: + talloc_free(tmp_ctx); + + return ret; +} + +static bool confirm(const char *prompt) +{ + char str[5]; + + fprintf(stdout, "%s [y/n]\n", prompt); + fflush(stdout); + + if (fgets(str, sizeof(str), stdin) == NULL) { + return false; + } + + if (str[strlen(str) - 1] == '\n') { + str[strlen(str) - 1] = '\0'; + } + + if (strcmp(str, "y") == 0 || strcmp(str, "yes") == 0) { + return true; + } + + fprintf(stdout, "Aborted.\n"); + fflush(stdout); + + return false; +} + +static errno_t sssctl_gpo_remove_entry(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom, + struct sysdb_attrs *entry) +{ + TALLOC_CTX *tmp_ctx = NULL; + const char *gpo_name = NULL; + const char *gpo_guid = NULL; + const char *gpo_path = NULL; + char gpo_cache_realpath[PATH_MAX]; + char gpo_realpath[PATH_MAX]; + char *prompt = NULL; + errno_t ret; + + tmp_ctx = talloc_new(mem_ctx); + if (tmp_ctx == NULL) { + ERROR("talloc failed\n"); + return ENOMEM; + } + + ret = get_attr_string(tmp_ctx, entry, dom, SYSDB_GPO_GUID_ATTR, &gpo_guid); + if (ret != EOK) { + ERROR("Could not find GUID attribute from GPO entry\n"); + ret = ENOENT; + goto done; + } + + ret = get_attr_string(tmp_ctx, entry, dom, SYSDB_NAME, &gpo_name); + if (ret != EOK) { + ERROR("Could not find description attribute from GPO entry\n"); + ret = ENOENT; + goto done; + } + + prompt = talloc_asprintf(tmp_ctx, + "About to delete GPO entry named [%s] with GUID " + "[%s] from database. Proceed?", + gpo_name, gpo_guid); + if (prompt == NULL) { + ERROR("talloc failed\n"); + ret = ENOMEM; + goto done; + } + + if (!confirm(prompt)) { + ret = EOK; + goto done; + } + + ret = sysdb_gpo_delete_gpo_by_guid(tmp_ctx, dom, gpo_guid); + if (ret != EOK) { + ERROR("Could not delete GPO entry from cache\n"); + goto done; + } + + ret = sysdb_attrs_get_string(entry, SYSDB_GPO_PATH_ATTR, &gpo_path); + if (ret == ENOENT) { + PRINT("The GPO path was not yet stored in cache. Please remove files " + "manually from [%s]\n", GPO_CACHE_PATH); + goto done; + } else if (ret != EOK) { + return ret; + } + + if (realpath(gpo_path, gpo_realpath) == NULL) { + ret = errno; + ERROR("Could not determine real path for [%s]: %s\n", gpo_path, strerror(ret)); + goto done; + } + + if (realpath(GPO_CACHE_PATH, gpo_cache_realpath) == NULL) { + ret = errno; + ERROR("Could not determine real path for [%s]: %s\n", GPO_CACHE_PATH, strerror(ret)); + goto done; + } + + if (strncmp(gpo_realpath, gpo_cache_realpath, strlen(gpo_cache_realpath)) != 0) { + ERROR("The cached GPO path [%s] is not under [%s], ignoring.\n", + gpo_realpath, gpo_cache_realpath); + ret = EOK; + goto done; + } + + prompt = talloc_asprintf(tmp_ctx, + "About to recursively delete GPO downloaded " + "files [%s]. Proceed?", + gpo_path); + if (prompt == NULL) { + ERROR("talloc failed\n"); + ret = ENOMEM; + goto done; + } + + if (!confirm(prompt)) { + ret = EOK; + goto done; + } + + ret = sss_remove_tree(gpo_path); + if (ret != EOK) { + ERROR("Unable to remove downloaded GPO files: %s\n", sss_strerror(ret)); + goto done; + } + +done: + talloc_free(tmp_ctx); + + return ret; +} + +errno_t sssctl_gpo_remove(struct sss_cmdline *cmdline, + struct sss_tool_ctx *tool_ctx, + void *pvt) +{ + TALLOC_CTX *tmp_ctx = NULL; + struct sssctl_cache_opts opts = {0}; + const char *attr; + errno_t ret; + struct sssctl_object_info info[] = { + SSSCTL_CACHE_GPO_NAME, + SSSCTL_CACHE_GPO_GUID, + SSSCTL_CACHE_GPO_PATH, + SSSCTL_CACHE_GPO_VERSION, + SSSCTL_CACHE_GPO_TIMEOUT, + SSSCTL_CACHE_NULL + }; + struct sysdb_attrs *entry = NULL; + struct sss_domain_info *dom = NULL; + struct poptOption options[] = { + {"guid", 'g', POPT_ARG_NONE, &opts.guid, 0, _("Search by GPO guid"), NULL }, + POPT_TABLEEND + }; + const char *extended_help = + "This command requires the domain name to be given because the " + "same policy name (or GUID) might exists in different domains.\nE.g.:\n" + " 'Default Domain Policy'@one.test\n" + " 'Default Domain Policy'@two.test"; + + tmp_ctx = talloc_new(tool_ctx); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + ret = parse_cmdline(cmdline, tool_ctx, options, extended_help, &opts.value, + &opts.domain); + if (ret != EOK) { + ERROR("Failed to parse command line: %s\n", sss_strerror(ret)); + goto done; + } + + if (opts.domain == NULL) { + ERROR("%s\n", extended_help); + return EINVAL; + } + + attr = SYSDB_NAME; + if (opts.guid) { + attr = SYSDB_GPO_GUID_ATTR; + } + + ret = sssctl_fetch_object(tmp_ctx, info, tool_ctx->domains, opts.domain, + sysdb_gpos_base_dn, CACHED_GPO, attr, opts.value, + &entry, &dom); + if (ret == ENOENT) { + PRINT(NOT_FOUND_MSG("GPO"), opts.value); + ret = EOK; + goto done; + } else if (ret != EOK) { + ERROR("Failed to fetch cache entry: %s\n", sss_strerror(ret)); + goto done; + } + + if (dom == NULL) { + ERROR("Could not determine object domain\n"); + ret = ERR_DOMAIN_NOT_FOUND; + goto done; + } + + ret = sssctl_gpo_remove_entry(tmp_ctx, dom, entry); done: talloc_free(tmp_ctx); -- 2.44.0 From cf0c5f1bc257bb1da370ecaeaef2e23dcfd7a3e1 Mon Sep 17 00:00:00 2001 From: Samuel Cabrero <scabrero@suse.de> Date: Tue, 23 Jan 2024 21:33:06 +0100 Subject: [PATCH 15/15] SSSCTL: Add gpo-purge command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves: https://github.com/SSSD/sssd/issues/4523 Signed-off-by: Samuel Cabrero <scabrero@suse.de> Reviewed-by: Sumit Bose <sbose@redhat.com> Reviewed-by: Tomáš Halman <thalman@redhat.com> --- src/tools/sssctl/sssctl.c | 1 + src/tools/sssctl/sssctl.h | 4 + src/tools/sssctl/sssctl_cache.c | 137 ++++++++++++++++++++++++++------ 3 files changed, 116 insertions(+), 26 deletions(-) diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c index 9f681c910..9daf09b6a 100644 --- a/src/tools/sssctl/sssctl.c +++ b/src/tools/sssctl/sssctl.c @@ -347,6 +347,7 @@ int main(int argc, const char **argv) SSS_TOOL_COMMAND("gpo-show", "Information about cached GPO", 0, sssctl_gpo_show), SSS_TOOL_COMMAND("gpo-list", "Enumerate cached GPOs", 0, sssctl_gpo_list), SSS_TOOL_COMMAND("gpo-remove", "Remove cached GPO", 0, sssctl_gpo_remove), + SSS_TOOL_COMMAND("gpo-purge", "Remove all cached GPOs", 0, sssctl_gpo_purge), #ifdef BUILD_PASSKEY SSS_TOOL_DELIMITER("Passkey related tools:"), SSS_TOOL_COMMAND_FLAGS("passkey-register", "Perform passkey registration", 0, sssctl_passkey_register, SSS_TOOL_FLAG_SKIP_CMD_INIT|SSS_TOOL_FLAG_SKIP_ROOT_CHECK), diff --git a/src/tools/sssctl/sssctl.h b/src/tools/sssctl/sssctl.h index 7c7b6b069..d29fd4be2 100644 --- a/src/tools/sssctl/sssctl.h +++ b/src/tools/sssctl/sssctl.h @@ -162,4 +162,8 @@ errno_t sssctl_gpo_remove(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt); +errno_t sssctl_gpo_purge(struct sss_cmdline *cmdline, + struct sss_tool_ctx *tool_ctx, + void *pvt); + #endif /* _SSSCTL_H_ */ diff --git a/src/tools/sssctl/sssctl_cache.c b/src/tools/sssctl/sssctl_cache.c index 60eb9ef68..77454217e 100644 --- a/src/tools/sssctl/sssctl_cache.c +++ b/src/tools/sssctl/sssctl_cache.c @@ -1008,7 +1008,8 @@ static bool confirm(const char *prompt) static errno_t sssctl_gpo_remove_entry(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, - struct sysdb_attrs *entry) + struct sysdb_attrs *entry, + bool ask_for_confirm) { TALLOC_CTX *tmp_ctx = NULL; const char *gpo_name = NULL; @@ -1039,19 +1040,21 @@ static errno_t sssctl_gpo_remove_entry(TALLOC_CTX *mem_ctx, goto done; } - prompt = talloc_asprintf(tmp_ctx, - "About to delete GPO entry named [%s] with GUID " - "[%s] from database. Proceed?", - gpo_name, gpo_guid); - if (prompt == NULL) { - ERROR("talloc failed\n"); - ret = ENOMEM; - goto done; - } + if (ask_for_confirm) { + prompt = talloc_asprintf(tmp_ctx, + "About to delete GPO entry named [%s] with GUID " + "[%s] from database. Proceed?", + gpo_name, gpo_guid); + if (prompt == NULL) { + ERROR("talloc failed\n"); + ret = ENOMEM; + goto done; + } - if (!confirm(prompt)) { - ret = EOK; - goto done; + if (!confirm(prompt)) { + ret = EOK; + goto done; + } } ret = sysdb_gpo_delete_gpo_by_guid(tmp_ctx, dom, gpo_guid); @@ -1088,19 +1091,21 @@ static errno_t sssctl_gpo_remove_entry(TALLOC_CTX *mem_ctx, goto done; } - prompt = talloc_asprintf(tmp_ctx, - "About to recursively delete GPO downloaded " - "files [%s]. Proceed?", - gpo_path); - if (prompt == NULL) { - ERROR("talloc failed\n"); - ret = ENOMEM; - goto done; - } + if (ask_for_confirm) { + prompt = talloc_asprintf(tmp_ctx, + "About to recursively delete GPO downloaded " + "files [%s]. Proceed?", + gpo_path); + if (prompt == NULL) { + ERROR("talloc failed\n"); + ret = ENOMEM; + goto done; + } - if (!confirm(prompt)) { - ret = EOK; - goto done; + if (!confirm(prompt)) { + ret = EOK; + goto done; + } } ret = sss_remove_tree(gpo_path); @@ -1183,8 +1188,88 @@ errno_t sssctl_gpo_remove(struct sss_cmdline *cmdline, goto done; } - ret = sssctl_gpo_remove_entry(tmp_ctx, dom, entry); + ret = sssctl_gpo_remove_entry(tmp_ctx, dom, entry, true); + +done: + talloc_free(tmp_ctx); + + return ret; +} + +static errno_t sssctl_gpo_traverse_remove(struct sss_domain_info *dom, + struct sssctl_object_info *info, + struct sysdb_attrs *entry, + void *private_data) +{ + TALLOC_CTX *tmp_ctx = NULL; + const char *gpo_guid = NULL; + errno_t ret; + + tmp_ctx = talloc_new(entry); + if (tmp_ctx == NULL) { + ERROR("talloc failed\n"); + return ENOMEM; + } + + ret = get_attr_string(tmp_ctx, entry, dom, SYSDB_GPO_GUID_ATTR, &gpo_guid); + if (ret != EOK) { + ERROR("Could not find GUID attribute in GPO entry\n"); + goto done; + } + + ret = sssctl_gpo_remove_entry(tmp_ctx, dom, entry, false); + if (ret != EOK) { + ERROR("Failed to delete GPO: %s\n", sss_strerror(ret)); + ret = EOK; + goto done; + } + PRINT("%s removed from cache\n", gpo_guid); + + ret = EOK; +done: + talloc_free(tmp_ctx); + + return ret; +} + +errno_t sssctl_gpo_purge(struct sss_cmdline *cmdline, + struct sss_tool_ctx *tool_ctx, + void *pvt) +{ + TALLOC_CTX *tmp_ctx = NULL; + const char *domain_prompt = NULL; + const char *prompt = NULL; + errno_t ret; + tmp_ctx = talloc_new(tool_ctx); + if (tmp_ctx == NULL) { + ERROR("talloc failed\n"); + return ENOMEM; + } + + domain_prompt = talloc_strdup(tmp_ctx, "Removing GPOs from domain"); + if (domain_prompt == NULL) { + ERROR("talloc failed\n"); + ret = ENOMEM; + goto done; + } + + prompt = talloc_asprintf(tmp_ctx, + "About to delete all cached GPO entries from the database and their " + "associated downloaded files. Proceed?"); + if (prompt == NULL) { + ERROR("talloc failed\n"); + ret = ENOMEM; + goto done; + } + + if (!confirm(prompt)) { + ret = EOK; + goto done; + } + + ret = sssctl_gpo_traverse(tmp_ctx, domain_prompt, tool_ctx->domains, + sssctl_gpo_traverse_remove, NULL); done: talloc_free(tmp_ctx); -- 2.44.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor