----- Original Message ----- > On (29/05/14 09:06), Yassir Elley wrote: > >----- Original Message ----- > >> On Thu, May 29, 2014 at 04:09:21AM -0400, Yassir Elley wrote: > >> > Also note that some (but not all) of the changes that were pushed to > >> > master > >> > as part of my patch titled "add libsmbclient to makefiles" seem to have > >> > been > >> > deleted by subsequent pushes to master. As such, this patch reintroduces > >> > those changes (which only affect configure.ac and libsmbclient.m4). > >> > >> That would be worrisome, what changes in particular? I'm not aware of > >> pushing anything else than acked patches from the list.. > >> > >> Are you talking about the autoconf refactor Lukas did? IIRC that one > >> only merged some code duplicates into a single file.. > >> _______________________________________________ > >> sssd-devel mailing list > >> sssd-devel@lists.fedorahosted.org > >> https://lists.fedorahosted.org/mailman/listinfo/sssd-devel > >> > > > >Hi Jakub, > > > >You are right. I overlooked the fact that the autoconf refactor had moved > >things around. My mistake. > > > >Revised patch attached. > > > >Regards, > >Yassir. > > >From abc4ac3e664ccbeeb58d131dc6c37cc314f5ba3d Mon Sep 17 00:00:00 2001 > >From: Yassir Elley <yel...@redhat.com> > >Date: Wed, 21 May 2014 15:11:36 -0400 > >Subject: [PATCH] AD-GPO: Add initial gpo-smb implementation > > > >--- > > src/providers/ad/ad_gpo.c | 680 > > +++++++++++++++++++++++++++++++++++++++++++++- > > 1 file changed, 676 insertions(+), 4 deletions(-) > > > >diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c > >index > >168ed2d7e8657799a7c773ec8b24897cdd303ec4..519c0dbec4d85e7f6e41db672ae0f2c2f720d81b > >100644 > >--- a/src/providers/ad/ad_gpo.c > >+++ b/src/providers/ad/ad_gpo.c > >@@ -31,6 +31,9 @@ > > */ > > > > #include <security/pam_modules.h> > >+#include <libsmbclient.h> > >+#include <ini_configobj.h> > >+#include <ini_config.h> > ^^^^^^^^^^^^ > This is the old ini_config interface. You can remove this line. > > > #include "util/util.h" > > #include "util/strtonum.h" > > #include "providers/data_provider.h" > > // snip > > >+ int ret; > >+ char **allow_sids = NULL; char **deny_sids = NULL; > >+ int allow_size = 0; int deny_size = 0; > >+ > >+ ret = ini_config_create(&ini_config); > >+ if (ret) goto done; > >+ ret = ini_config_file_from_mem(data_buf, data_len, &file_ctx); > ^^^^^^^^^^^^^^^^^^^^^^^^ > This function is available in libini_config-1.1 > Please, update buildrequires in spec file. > > diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in > index b5e7903..10704ae 100644 > --- a/contrib/sssd.spec.in > +++ b/contrib/sssd.spec.in > @@ -97,7 +97,7 @@ BuildRequires: libtdb-devel > BuildRequires: libldb-devel > BuildRequires: libdhash-devel >= 0.4.2 > BuildRequires: libcollection-devel > -BuildRequires: libini_config-devel > +BuildRequires: libini_config-devel >= 1.1 > BuildRequires: dbus-devel > BuildRequires: dbus-libs > %if 0%{?rhel5_minor} >= 7 > > LS
Revised patch attached. Also, I successfully tested the code after installing the ding-libs packages from lslebodn's repo. Previously, I was using rpms that I had manually compiled (for the ini_config_file_from_mem functionality). Thanks, Yassir.
From 24625d6cd02faeb39e8522769d470b3a8beed513 Mon Sep 17 00:00:00 2001 From: Yassir Elley <yel...@redhat.com> Date: Wed, 21 May 2014 15:11:36 -0400 Subject: [PATCH] AD-GPO: Add initial gpo-smb implementation --- contrib/sssd.spec.in | 2 +- src/providers/ad/ad_gpo.c | 679 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 676 insertions(+), 5 deletions(-) diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in index b5e7903713ccc6944fbed4f84c2f0413a257b760..10704ae48cf5636de2a5cbbb42fc00b99052144f 100644 --- a/contrib/sssd.spec.in +++ b/contrib/sssd.spec.in @@ -97,7 +97,7 @@ BuildRequires: libtdb-devel BuildRequires: libldb-devel BuildRequires: libdhash-devel >= 0.4.2 BuildRequires: libcollection-devel -BuildRequires: libini_config-devel +BuildRequires: libini_config-devel >= 1.1 BuildRequires: dbus-devel BuildRequires: dbus-libs %if 0%{?rhel5_minor} >= 7 diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c index bb6896e70ae96036b1a9e58a6c8e25d3d8f1543f..9a0f09f9d2735158d970bb19d631645eb8ae9cfa 100644 --- a/src/providers/ad/ad_gpo.c +++ b/src/providers/ad/ad_gpo.c @@ -31,6 +31,8 @@ */ #include <security/pam_modules.h> +#include <libsmbclient.h> +#include <ini_configobj.h> #include "util/util.h" #include "util/strtonum.h" #include "providers/data_provider.h" @@ -47,6 +49,8 @@ #include <ndr.h> #include <gen_ndr/security.h> +/* == gpo-ldap constants =================================================== */ + #define AD_AT_DN "distinguishedName" #define AD_AT_UAC "userAccountControl" #define AD_AT_CONFIG_NC "configurationNamingContext" @@ -66,6 +70,20 @@ #define AD_AGP_GUID "edacfd8f-ffb3-11d1-b41d-00a0c968f939" #define AD_AUTHENTICATED_USERS_SID "S-1-5-11" +/* == gpo-smb constants ==================================================== */ + +#define GPO_VERSION_USER(x) (x >> 16) +#define GPO_VERSION_MACHINE(x) (x & 0xffff) + +#define RIGHTS_SECTION "Privilege Rights" +#define ALLOW_LOGON_LOCALLY "SeInteractiveLogonRight" +#define DENY_LOGON_LOCALLY "SeDenyInteractiveLogonRight" + +#define SMB_BUFFER_SIZE 65536 + +#define GP_EXT_GUID_SECURITY "{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" +#define GP_EXT_GUID_SECURITY_SUFFIX "/Microsoft/Windows NT/SecEdit/GptTmpl.inf" + /* == common data structures and declarations ============================= */ struct gp_som { @@ -121,6 +139,16 @@ int ad_gpo_process_gpo_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct gp_gpo ***candidate_gpos, int *num_candidate_gpos); +struct tevent_req *ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + char *smb_uri, + struct gp_gpo *cse_filtered_gpo); +int ad_gpo_process_cse_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + char ***allowed_sids, + int *allowed_size, + char ***denied_sids, + int *denied_size); /* == ad_gpo_access_send/recv helpers =======================================*/ @@ -543,6 +571,235 @@ ad_gpo_filter_gpos_by_dacl(TALLOC_CTX *mem_ctx, return ret; } +/* + * This function determines whether the input cse_guid matches any of the input + * gpo_cse_guids. The boolean result is assigned to the _included output param. + */ +static errno_t +ad_gpo_includes_cse_guid(const char *cse_guid, + const char **gpo_cse_guids, + int num_gpo_cse_guids, + bool *_included) +{ + int i = 0; + const char *gpo_cse_guid = NULL; + + for (i = 0; i < num_gpo_cse_guids; i++) { + gpo_cse_guid = gpo_cse_guids[i]; + if (strcmp(gpo_cse_guid, cse_guid) == 0) { + *_included = true; + return EOK; + } + } + + *_included = false; + return EOK; +} + +/* + * This function takes an input dacl_filtered_gpos list, filters out any gpo + * that does not contain the input cse_guid, and assigns the result to the + * _cse_filtered_gpos output parameter. + */ +static errno_t +ad_gpo_filter_gpos_by_cse_guid(TALLOC_CTX *mem_ctx, + const char *cse_guid, + struct gp_gpo **dacl_filtered_gpos, + int num_dacl_filtered_gpos, + struct gp_gpo ***_cse_filtered_gpos, + int *_num_cse_filtered_gpos) +{ + TALLOC_CTX *tmp_ctx = NULL; + int i = 0; + int ret = 0; + struct gp_gpo *dacl_filtered_gpo = NULL; + int gpo_dn_idx = 0; + struct gp_gpo **cse_filtered_gpos = NULL; + bool included; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + ret = ENOMEM; + goto done; + } + + cse_filtered_gpos = talloc_array(tmp_ctx, + struct gp_gpo *, + num_dacl_filtered_gpos + 1); + if (cse_filtered_gpos == NULL) { + ret = ENOMEM; + goto done; + } + + for (i = 0; i < num_dacl_filtered_gpos; i++) { + + dacl_filtered_gpo = dacl_filtered_gpos[i]; + + DEBUG(SSSDBG_TRACE_ALL, "examining cse candidate_gpo_guid: %s\n", + dacl_filtered_gpo->gpo_guid); + + ret = ad_gpo_includes_cse_guid(cse_guid, + dacl_filtered_gpo->gpo_cse_guids, + dacl_filtered_gpo->num_gpo_cse_guids, + &included); + if (included) { + DEBUG(SSSDBG_TRACE_ALL, + "GPO applicable to target per cse_guid filtering\n"); + cse_filtered_gpos[gpo_dn_idx] = talloc_steal(cse_filtered_gpos, + dacl_filtered_gpo); + gpo_dn_idx++; + } else { + DEBUG(SSSDBG_TRACE_ALL, + "GPO not applicable to target per cse_guid filtering\n"); + continue; + } + } + + cse_filtered_gpos[gpo_dn_idx] = NULL; + + *_cse_filtered_gpos = talloc_steal(mem_ctx, cse_filtered_gpos); + *_num_cse_filtered_gpos = gpo_dn_idx; + + ret = EOK; + + done: + talloc_free(tmp_ctx); + return ret; +} + +/* + * This cse-specific function (GP_EXT_GUID_SECURITY) populates the output + * parameter (found) based on whether the input user_sid or any of the input + * group_sids appear in the input list of privilege_sids. + */ +static void +check_rights(char **privilege_sids, + int privilege_size, + const char *user_sid, + const char **group_sids, + int group_size, + int *found) +{ + int match = 0; + int i, j; + + for (i = 0; i < privilege_size; i++) { + if (strcmp(user_sid, privilege_sids[i]) == 0) { + match = 1; + break; + } + for (j = 0; j < group_size; j++) { + if (strcmp(group_sids[j], privilege_sids[i]) == 0) { + match = 1; + break; + } + } + } + + *found = match; +} + +/* + * This cse-specific function (GP_EXT_GUID_SECURITY) performs HBAC policy + * application and determines whether logon access is granted or denied for + * the {user,domain} tuple specified in the inputs. This function returns EOK + * to indicate that access is granted. Any other return value indicates that + * access is denied. + * + * The access control algorithm first determines whether the "principal_sids" + * (i.e. user_sid or group_sids) appear in allowed_sids and denied_sids. + * + * For access to be granted, both the "allowed_sids_condition" *and* the + * "denied_sids_condition" must be met (in all other cases, access is denied). + * 1) The "allowed_sids_condition" is satisfied if any of the principal_sids + * appears in allowed_sids OR if the allowed_sids list is empty + * 2) The "denied_sids_condition" is satisfied if none of the principal_sids + * appear in denied_sids + * + * Note that a deployment that is unaware of GPO-based access-control policy + * settings is unaffected by them (b/c the absence of allowed_sids grants access). + * + * Note that if a principal_sid appears in both allowed_sids and denied_sids, + * the "allowed_sids_condition" is met, but the "denied_sids_condition" is not. + * In other words, Deny takes precedence over Allow. + */ +static errno_t +ad_gpo_access_check(TALLOC_CTX *mem_ctx, + const char *user, + struct sss_domain_info *domain, + char **allowed_sids, + int allowed_size, + char **denied_sids, + int denied_size) +{ + const char *user_sid; + const char **group_sids; + int group_size = 0; + int access_granted = 0; + int access_denied = 0; + int ret; + int j; + + DEBUG(SSSDBG_TRACE_FUNC, "POLICY FILE:\n"); + DEBUG(SSSDBG_TRACE_FUNC, "allowed_size = %d\n", allowed_size); + for (j= 0; j < allowed_size; j++) { + DEBUG(SSSDBG_TRACE_FUNC, "allowed_sids[%d] = %s\n", j, + allowed_sids[j]); + } + + DEBUG(SSSDBG_TRACE_FUNC, "denied_size = %d\n", denied_size); + for (j= 0; j < denied_size; j++) { + DEBUG(SSSDBG_TRACE_FUNC, " denied_sids[%d] = %s\n", j, + denied_sids[j]); + } + + ret = ad_gpo_get_sids(mem_ctx, user, domain, &user_sid, + &group_sids, &group_size); + if (ret != EOK) { + ret = ERR_NO_SIDS; + DEBUG(SSSDBG_OP_FAILURE, + "Unable to retrieve SIDs: [%d](%s)\n", ret, sss_strerror(ret)); + goto done; + } + + DEBUG(SSSDBG_TRACE_FUNC, "CURRENT USER:\n"); + DEBUG(SSSDBG_TRACE_FUNC, " user_sid = %s\n", user_sid); + + for (j= 0; j < group_size; j++) { + DEBUG(SSSDBG_TRACE_FUNC, " group_sids[%d] = %s\n", j, + group_sids[j]); + } + + /* If AllowLogonLocally is not defined, all users are allowed */ + if (allowed_size == 0) { + access_granted = 1; + } else { + check_rights(allowed_sids, allowed_size, user_sid, + group_sids, group_size, &access_granted); + } + + DEBUG(SSSDBG_TRACE_FUNC, " access_granted = %d\n", access_granted); + + check_rights(denied_sids, denied_size, user_sid, + group_sids, group_size, &access_denied); + DEBUG(SSSDBG_TRACE_FUNC, " access_denied = %d\n", access_denied); + + if (access_granted && !access_denied) { + return EOK; + } else { + return EACCES; + } + + done: + + if (ret) { + DEBUG(SSSDBG_CRIT_FAILURE, "Error encountered: %d.\n", ret); + } + + return ret; +} + + /* == ad_gpo_access_send/recv implementation ================================*/ struct ad_gpo_access_state { @@ -558,6 +815,9 @@ struct ad_gpo_access_state { const char *target_dn; struct gp_gpo **dacl_filtered_gpos; int num_dacl_filtered_gpos; + struct gp_gpo **cse_filtered_gpos; + int num_cse_filtered_gpos; + int cse_gpo_index; }; static void ad_gpo_connect_done(struct tevent_req *subreq); @@ -565,6 +825,9 @@ static void ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq); static void ad_gpo_process_som_done(struct tevent_req *subreq); static void ad_gpo_process_gpo_done(struct tevent_req *subreq); +static errno_t ad_gpo_cse_step(struct tevent_req *req); +static void ad_gpo_cse_done(struct tevent_req *subreq); + struct tevent_req * ad_gpo_access_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -586,6 +849,9 @@ ad_gpo_access_send(TALLOC_CTX *mem_ctx, state->domain = domain; state->dacl_filtered_gpos = NULL; state->num_dacl_filtered_gpos = 0; + state->cse_filtered_gpos = NULL; + state->num_cse_filtered_gpos = 0; + state->cse_gpo_index = -1; state->ev = ev; state->user = user; state->ldb_ctx = sysdb_ctx_get_ldb(domain->sysdb); @@ -840,6 +1106,13 @@ ad_gpo_process_som_done(struct tevent_req *subreq) /* * This function retrieves a list of candidate_gpos and potentially reduces it * to a list of dacl_filtered_gpos, based on each GPO's DACL. + * + * This function then takes the list of dacl_filtered_gpos and potentially + * reduces it to a list of cse_filtered_gpos, based on whether each GPO's list + * of cse_guids includes the "SecuritySettings" CSE GUID (used for HBAC). + * + * This function then sends each cse_filtered_gpo to the CSE processing engine + * for policy application, which currently consists of HBAC functionality. */ static void ad_gpo_process_gpo_done(struct tevent_req *subreq) @@ -878,7 +1151,7 @@ ad_gpo_process_gpo_done(struct tevent_req *subreq) &state->num_dacl_filtered_gpos); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, - "Unable to filter GPO list: [%d](%s)\n", + "Unable to filter GPO list by DACKL: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } @@ -896,10 +1169,133 @@ ad_gpo_process_gpo_done(struct tevent_req *subreq) state->dacl_filtered_gpos[i]->gpo_guid); } - /* TBD: initiate SMB retrieval */ - DEBUG(SSSDBG_TRACE_FUNC, "time for SMB retrieval\n"); + ret = ad_gpo_filter_gpos_by_cse_guid(state, + GP_EXT_GUID_SECURITY, + state->dacl_filtered_gpos, + state->num_dacl_filtered_gpos, + &state->cse_filtered_gpos, + &state->num_cse_filtered_gpos); - ret = EOK; + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Unable to filter GPO list by CSE_GUID: [%d](%s)\n", + ret, strerror(ret)); + goto done; + } + + if (state->cse_filtered_gpos[0] == NULL) { + /* no gpos contain "SecuritySettings" cse_guid, nothing to enforce */ + DEBUG(SSSDBG_TRACE_FUNC, + "no applicable gpos found after cse_guid filtering\n"); + ret = EOK; + 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); + } + + DEBUG(SSSDBG_TRACE_FUNC, "num_cse_filtered_gpos: %d\n", + state->num_cse_filtered_gpos); + + ret = ad_gpo_cse_step(req); + + done: + + if (ret == EOK) { + tevent_req_done(req); + } else if (ret != EAGAIN) { + tevent_req_error(req, ret); + } +} + +static errno_t +ad_gpo_cse_step(struct tevent_req *req) +{ + struct tevent_req *subreq; + struct ad_gpo_access_state *state; + char *smb_uri; + int i = 0; + + state = tevent_req_data(req, struct ad_gpo_access_state); + + state->cse_gpo_index++; + struct gp_gpo *cse_filtered_gpo = + state->cse_filtered_gpos[state->cse_gpo_index]; + + /* cse_filtered_gpo is NULL only after all GPOs have been processed */ + if (cse_filtered_gpo == NULL) return EOK; + + DEBUG(SSSDBG_TRACE_FUNC, "cse filtered_gpos[%d]->gpo_guid is %s\n", + state->cse_gpo_index, cse_filtered_gpo->gpo_guid); + DEBUG(SSSDBG_TRACE_FUNC, "cse filtered_gpos[%d]->file_sys_path is %s\n", + state->cse_gpo_index, cse_filtered_gpo->gpo_file_sys_path); + for (i = 0; i < cse_filtered_gpo->num_gpo_cse_guids; i++) { + DEBUG(SSSDBG_TRACE_ALL, + "cse_filtered_gpos[%d]->gpo_cse_guids[%d]->gpo_guid is %s\n", + state->cse_gpo_index, i, cse_filtered_gpo->gpo_cse_guids[i]); + } + + smb_uri = talloc_asprintf(state, "%s%s", + cse_filtered_gpo->gpo_file_sys_path, + GP_EXT_GUID_SECURITY_SUFFIX); + + subreq = ad_gpo_process_cse_send(state, state->ev, smb_uri, cse_filtered_gpo); + + tevent_req_set_callback(subreq, ad_gpo_cse_done, req); + return EAGAIN; +} + +/* + * This cse-specific function (GP_EXT_GUID_SECURITY) retrieves a list of + * allowed_sids and denied_sids, and uses them to determine whether logon + * access is granted or denied for the state's {user, domain} tuple. + * + * If it is determined that the current cse_filtered_gpo grants access, then + * we process the next cse_filtered_gpo in the list. At any time, if access is + * denied, we return immediately with an error. + */ +static void +ad_gpo_cse_done(struct tevent_req *subreq) +{ + struct tevent_req *req; + struct ad_gpo_access_state *state; + int ret; + char **allowed_sids; + int allowed_size; + char **denied_sids; + int denied_size; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ad_gpo_access_state); + + ret = ad_gpo_process_cse_recv(subreq, state, &allowed_sids, &allowed_size, + &denied_sids, &denied_size); + + talloc_zfree(subreq); + + if (ret != EOK) { + /* TBD: handle ret error */ + goto done; + } + + /* TBD: allowed/denied_sids/size, should be retrieved from cache */ + ret = ad_gpo_access_check + (state, state->user, state->domain, + allowed_sids, allowed_size, denied_sids, denied_size); + + if (ret == EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "ret is EOK\n"); + } else { + DEBUG(SSSDBG_CRIT_FAILURE, "ret is not EOK\n"); + DEBUG(SSSDBG_OP_FAILURE, + "GPO check failed: [%d](%s)\n", + ret, strerror(ret)); + goto done; + } + + ret = ad_gpo_cse_step(req); done: @@ -2307,3 +2703,278 @@ ad_gpo_process_gpo_recv(struct tevent_req *req, *num_candidate_gpos = state->num_candidate_gpos; return EOK; } + +/* == ad_gpo_process_cse_send/recv helpers ================================= */ + +/* + * This function uses the input ini_config object to parse the logon right value + * associated with the input name. This value is a list of sids, and is used + * to populate the output parameters. The input name can be either + * ALLOW_LOGON_LOCALLY or DENY_LOGON_LOCALLY. + */ +static errno_t +parse_logon_right_with_libini(struct ini_cfgobj *ini_config, + const char *name, + int *_size, + char ***_sids) +{ + int ret = 0; + struct value_obj *vobj = NULL; + char **sids = NULL; + int num_sids = 0; + int i; + + ret = ini_get_config_valueobj(RIGHTS_SECTION, name, ini_config, + INI_GET_FIRST_VALUE, &vobj); + if (vobj == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "section/name not found: [%s][%s]\n", + RIGHTS_SECTION, name); + return EOK; + } + sids = ini_get_string_config_array(vobj, NULL, &num_sids, &ret); + + if (ret) { + DEBUG(SSSDBG_CRIT_FAILURE, + "ini_get_string_config_array failed [%d][%s]\n", ret, strerror(ret)); + return ret; + } + + for (i = 0; i <num_sids; i++) { + if (sids[i][0] == '*') { + sids[i]++; + } + } + + *_size = num_sids; + *_sids = sids; + + return EOK; +} + +/* + * This function parses the cse-specific (GP_EXT_GUID_SECURITY) input data_buf, + * and uses the results to populate the output parameters with the list of + * allowed_sids and denied_sids + */ +static errno_t +ad_gpo_parse_security_cse_buffer(uint8_t *data_buf, + int data_len, + char ***allowed_sids, + int *allowed_size, + char ***denied_sids, + int *denied_size) +{ + struct ini_cfgfile *file_ctx = NULL; + struct ini_cfgobj *ini_config = NULL; + int ret; + char **allow_sids = NULL; char **deny_sids = NULL; + int allow_size = 0; int deny_size = 0; + + ret = ini_config_create(&ini_config); + if (ret) goto done; + ret = ini_config_file_from_mem(data_buf, data_len, &file_ctx); + if (ret) goto done; + ret = ini_config_parse(file_ctx, INI_STOP_ON_NONE, 0, 0, ini_config); + if (ret) goto done; + + ret = parse_logon_right_with_libini(ini_config, + ALLOW_LOGON_LOCALLY, + &allow_size, + &allow_sids); + if (ret) {goto done;} + + ret = parse_logon_right_with_libini(ini_config, + DENY_LOGON_LOCALLY, + &deny_size, + &deny_sids); + if (ret) {goto done;} + + *allowed_sids = allow_sids; + *allowed_size = allow_size; + *denied_sids = deny_sids; + *denied_size = deny_size; + + done: + + if (ret) { + DEBUG(SSSDBG_CRIT_FAILURE, "Error encountered: %d.\n", ret); + } + + ini_config_file_close(file_ctx); + return ret; +} + +static void +sssd_krb_get_auth_data_fn(const char * pServer, + const char * pShare, + char * pWorkgroup, + int maxLenWorkgroup, + char * pUsername, + int maxLenUsername, + char * pPassword, + int maxLenPassword) +{ + /* since we are using kerberos for authentication, we simply return */ + return; +} + + +/* + * This cse-specific function (GP_EXT_GUID_SECURITY) opens an SMB connection, + * retrieves the data referenced by the input smb_uri, and then closes the SMB + * connection. The data is then parsed and the results are used to populate the + * output parameters with the list of allowed_sids and denied_sids + */ +static errno_t +process_security_settings_cse(TALLOC_CTX *mem_ctx, + const char *smb_uri, + char ***_allowed_sids, + int *_allowed_size, + char ***_denied_sids, + int *_denied_size) +{ + SMBCCTX *context; + int ret = 0; + uint8_t *buf = NULL; + int bytesread = 0; + + char **allowed_sids; + char **denied_sids; + int allowed_size = 0; + int denied_size = 0; + + DEBUG(SSSDBG_TRACE_ALL, "%s\n", smb_uri); + + context = smbc_new_context(); + if (!context) { + DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate new smbc context\n"); + } + + smbc_setFunctionAuthData(context, sssd_krb_get_auth_data_fn); + smbc_setOptionUseKerberos(context, 1); + + /* Initialize the context using the previously specified options */ + if (!smbc_init_context(context)) { + smbc_free_context(context, 0); + DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize smbc context\n"); + } + + /* Tell the compatibility layer to use this context */ + smbc_set_context(context); + + int remotehandle = smbc_open(smb_uri, O_RDONLY, 0755); + if (remotehandle < 0) DEBUG(SSSDBG_CRIT_FAILURE, "smbc_open failed\n"); + + buf = talloc_array(mem_ctx, uint8_t, SMB_BUFFER_SIZE); + bytesread = smbc_read(remotehandle, buf, SMB_BUFFER_SIZE); + if(bytesread < 0) DEBUG(SSSDBG_CRIT_FAILURE, "smbc_read failed\n"); + + DEBUG(SSSDBG_CRIT_FAILURE, "bytesread: %d\n", bytesread); + + smbc_close(remotehandle); + + ret = ad_gpo_parse_security_cse_buffer(buf, + bytesread, + &allowed_sids, + &allowed_size, + &denied_sids, + &denied_size); + + /* TBD: allowed/denied_sids/size should be stored in cache */ + + *_allowed_sids = allowed_sids; + *_allowed_size = allowed_size; + *_denied_sids = denied_sids; + *_denied_size = denied_size; + + return ret; +} + +/* == ad_gpo_process_cse_send/recv implementation ========================== */ + +struct ad_gpo_process_cse_state { + struct tevent_context *ev; + char **allowed_sids; + int allowed_size; + char **denied_sids; + int denied_size; + struct gp_gpo *cse_filtered_gpo; +}; + +/* + * This cse-specific function (GP_EXT_GUID_SECURITY) retrieves the data + * referenced by the input smb_uri, and uses the parsed results to populate the + * state's list of allowed_sids and denied_sids. + */ +struct tevent_req * +ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + char *smb_uri, + struct gp_gpo *cse_filtered_gpo) +{ + struct tevent_req *req; + struct ad_gpo_process_cse_state *state; + errno_t ret; + + char **allowed_sids; + int allowed_size; + char **denied_sids; + int denied_size; + + req = tevent_req_create(mem_ctx, &state, struct ad_gpo_process_cse_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); + return NULL; + } + + state->ev = ev; + state->cse_filtered_gpo = cse_filtered_gpo; + + ret = process_security_settings_cse + (state, smb_uri, &allowed_sids, &allowed_size, + &denied_sids, &denied_size); + + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "process_security_settings_cse FAILED\n"); + goto done; + } + + state->allowed_sids = allowed_sids; + state->allowed_size = allowed_size; + state->denied_sids = denied_sids; + state->denied_size = denied_size; + + ret = EOK; + + done: + + if (ret == EOK) { + tevent_req_done(req); + tevent_req_post(req, ev); + } else { + tevent_req_error(req, ret); + tevent_req_post(req, ev); + } + + return req; +} + +int ad_gpo_process_cse_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + char ***allowed_sids, + int *allowed_size, + char ***denied_sids, + int *denied_size) +{ + struct ad_gpo_process_cse_state *state = + tevent_req_data(req, struct ad_gpo_process_cse_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + *allowed_sids = state->allowed_sids; + *allowed_size = state->allowed_size; + *denied_sids = state->denied_sids; + *denied_size = state->denied_size; + + return EOK; +} -- 1.8.5.3
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/sssd-devel