3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov Yassir Elley <yelley@redhat.com>
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov Copyright (C) 2013 Red Hat
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov This program is free software; you can redistribute it and/or modify
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov it under the terms of the GNU General Public License as published by
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov the Free Software Foundation; either version 3 of the License, or
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov (at your option) any later version.
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov This program is distributed in the hope that it will be useful,
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov but WITHOUT ANY WARRANTY; without even the implied warranty of
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov GNU General Public License for more details.
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov You should have received a copy of the GNU General Public License
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov along with this program. If not, see <http://www.gnu.org/licenses/>.
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov * This file implements the following pair of *public* functions (see header):
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov * ad_gpo_access_send/recv: provides client-side GPO processing
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov * This file also implements the following pairs of *private* functions (which
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov * are used by the public functions):
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov * ad_gpo_process_som_send/recv: populate list of gp_som objects
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov * ad_gpo_process_gpo_send/recv: populate list of gp_gpo objects
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov * ad_gpo_process_cse_send/recv: retrieve policy file data
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov/* == gpo-ldap constants =================================================== */
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define AD_AT_CONFIG_NC "configurationNamingContext"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define AD_AT_NT_SEC_DESC "nTSecurityDescriptor"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define AD_AT_FILE_SYS_PATH "gPCFileSysPath"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define AD_AT_MACHINE_EXT_NAMES "gPCMachineExtensionNames"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define AD_AT_FUNC_VERSION "gPCFunctionalityVersion"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define UAC_WORKSTATION_TRUST_ACCOUNT 0x00001000
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov#define UAC_SERVER_TRUST_ACCOUNT 0x00002000
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define AD_AGP_GUID "edacfd8f-ffb3-11d1-b41d-00a0c968f939"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define AD_AUTHENTICATED_USERS_SID "S-1-5-11"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov/* == gpo-smb constants ==================================================== */
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define ALLOW_LOGON_INTERACTIVE "SeInteractiveLogonRight"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define DENY_LOGON_INTERACTIVE "SeDenyInteractiveLogonRight"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define ALLOW_LOGON_REMOTE_INTERACTIVE "SeRemoteInteractiveLogonRight"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define DENY_LOGON_REMOTE_INTERACTIVE "SeDenyRemoteInteractiveLogonRight"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define ALLOW_LOGON_NETWORK "SeNetworkLogonRight"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define DENY_LOGON_NETWORK "SeDenyNetworkLogonRight"
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov#define ALLOW_LOGON_BATCH "SeBatchLogonRight"
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov#define DENY_LOGON_BATCH "SeDenyBatchLogonRight"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#define ALLOW_LOGON_SERVICE "SeServiceLogonRight"
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov#define DENY_LOGON_SERVICE "SeDenyServiceLogonRight"
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov#define GP_EXT_GUID_SECURITY "{827D319E-6EAC-11D2-A4EA-00C04F79F83A}"
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov#define GP_EXT_GUID_SECURITY_SUFFIX "/Machine/Microsoft/Windows NT/SecEdit/GptTmpl.inf"
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov#define GPO_CHILD SSSD_LIBEXEC_PATH"/gpo_child"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov/* If INI_PARSE_IGNORE_NON_KVP is not defined, use 0 (no effect) */
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#warning INI_PARSE_IGNORE_NON_KVP not defined.
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov/* fd used by the gpo_child process for logging */
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov/* == common data structures and declarations ============================= */
int timeout,
const char *target_dn,
const char *domain_name);
struct tevent_req *
char *server_hostname,
int timeout,
int *num_candidate_gpos);
bool send_to_child,
const char *gpo_guid,
const char *smb_server,
const char *smb_share,
const char *smb_path,
const char *smb_cse_suffix,
int cached_gpt_version,
int gpo_timeout_option);
NULL};
switch(gpo_map_type) {
return NULL;
size_t i;
for (i = 0; i < nlist; i++) {
return (i < nlist) ? true : false;
goto done;
goto done;
goto done;
done:
return ret;
char *conf_str,
const char **defaults)
goto done;
if (conf_str) {
goto done;
goto done;
for (i = 0; i < conf_list_size; i++) {
switch (conf_list[i][0]) {
ai++;
ri++;
conf_list[i]);
goto done;
for (i = 0; i < ai; i++) {
goto done;
for (i = 0; defaults[i]; i++) {
goto done;
done:
return ret;
for (i = 0; i < GPO_MAP_NUM_OPTS; i++) {
goto fail;
goto fail;
fail:
return ret;
/* == ad_gpo_access_send/recv helpers =======================================*/
static errno_t
const char *user,
const char **_user_sid,
const char ***_group_sids,
int *_group_size)
goto done;
goto done;
goto done;
goto done;
for (i = 0; i < num_group_sids; i++) {
goto done;
goto done;
done:
return ret;
static errno_t
const char **group_sids,
int group_size,
bool *_included)
return EFAULT;
if (included) {
*_included = true;
return EOK;
for (i = 0; i < group_size; i++) {
return EFAULT;
if (included) {
*_included = true;
return EOK;
*_included = false;
return EOK;
const char *user_sid,
const char **group_sids,
int group_size)
return AD_GPO_ACE_NEUTRAL;
return AD_GPO_ACE_DENIED;
if (!included) {
return AD_GPO_ACE_NEUTRAL;
agp_included = true;
agp_included = false;
if (agp_included) {
return AD_GPO_ACE_ALLOWED;
return AD_GPO_ACE_DENIED;
return AD_GPO_ACE_DENIED;
const char *user_sid,
const char **group_sids,
int group_size,
bool *_dacl_access_allowed)
if (num_aces == 0) {
*_dacl_access_allowed = false;
return EOK;
switch (ace_status) {
case AD_GPO_ACE_NEUTRAL:
case AD_GPO_ACE_ALLOWED:
*_dacl_access_allowed = true;
return EOK;
case AD_GPO_ACE_DENIED:
*_dacl_access_allowed = false;
return EOK;
*_dacl_access_allowed = false;
return EOK;
static errno_t
const char *user,
int num_candidate_gpos,
int *_num_dacl_filtered_gpos)
goto done;
goto done;
struct gp_gpo *,
goto done;
for (i = 0; i < num_candidate_gpos; i++) {
access_allowed = false;
access_allowed = true;
if (access_allowed) {
gpo_dn_idx++;
done:
return ret;
const char **gpo_cse_guids,
int num_gpo_cse_guids)
for (i = 0; i < num_gpo_cse_guids; i++) {
static errno_t
const char *cse_guid,
int *_num_cse_filtered_gpos)
goto done;
struct gp_gpo *,
goto done;
for (i = 0; i < num_dacl_filtered_gpos; i++) {
if (included) {
gpo_dn_idx++;
done:
return ret;
int privilege_size,
const char *user_sid,
const char **group_sids,
int group_size)
for (i = 0; i < privilege_size; i++) {
for (j = 0; j < group_size; j++) {
static errno_t
const char *policy_setting_key,
char **_policy_setting_value)
if (ret != 0) {
goto done;
goto done;
if (ret != 0) {
goto done;
if (policy_setting_value[0]) {
if (!*_policy_setting_value) {
goto done;
done:
return ret;
static errno_t
const char *filename)
goto done;
if (ret != 0) {
goto done;
if (ret != 0) {
goto done;
if (ret != 0) {
if (lret != 0) {
goto done;
for (int a = 0; errors[a]; a++) {
if (ret != 0) {
goto done;
if (ret != 0) {
goto done;
if (ret != 0) {
if (lret != 0) {
goto done;
for (int a = 0; errors[a]; a++) {
goto done;
for (i = 0; i < GPO_MAP_NUM_OPTS; i++) {
&allow_value);
goto done;
goto done;
&deny_value);
goto done;
goto done;
done:
return ret;
static errno_t
const char *user,
char **allowed_sids,
int allowed_size,
char **denied_sids,
int denied_size)
for (j= 0; j < allowed_size; j++) {
for (j= 0; j < denied_size; j++) {
goto done;
for (j= 0; j < group_size; j++) {
group_sids[j]);
if (allowed_size == 0) {
access_granted = true;
return EOK;
switch (gpo_mode) {
return ERR_ACCESS_DENIED;
return EOK;
return EINVAL;
done:
if (ret) {
return ret;
const char *key,
char ***_sids_list,
int *_sids_list_size)
goto done;
sids_list_size = 0;
goto done;
for (i = 0; i < sids_list_size; i++) {
sids_list[i]++;
done:
return ret;
static errno_t
const char *user,
goto done;
goto done;
goto done;
done:
return ret;
/* == ad_gpo_access_send/recv implementation ================================*/
struct tevent_req *
const char *user,
const char *service)
return NULL;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
return req;
return req;
static errno_t
const char *user,
user,
goto done;
done:
return ret;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
done:
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
uac);
goto done;
goto done;
done:
goto done;
som_list);
goto done;
done:
goto done;
switch (ret) {
case ENOENT:
goto done;
goto done;
goto done;
switch (ret) {
case ENOENT:
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
switch (ret) {
case ENOENT:
goto done;
done:
static errno_t
return ENOMEM;
&res);
send_to_child = false;
return ret;
return EAGAIN;
* with the user_sid/group_sids of interest.
goto done;
goto done;
goto done;
done:
return EOK;
/* == ad_gpo_process_som_send/recv helpers ================================= */
static errno_t
const char *dn,
const char **_parent_dn)
goto done;
done:
return ret;
static errno_t
const char *target_dn,
int *_num_soms,
goto done;
goto done;
goto done;
if (rdn_count == 0) {
goto done;
goto done;
goto done;
goto done;
som_idx++;
done:
return ret;
static errno_t
const char *som_dn,
char *raw_gplink_value,
bool allow_enforced_only)
return EINVAL;
goto done;
ptr++;
gplink_count++;
if (gplink_count == 0) {
goto done;
goto done;
num_enabled = 0;
for (i = 0; i < gplink_count; i++) {
goto done;
last++;
goto done;
if (errno != 0) {
goto done;
goto done;
goto done;
if (gplink_number == 0) {
num_enabled++;
num_enabled++;
goto done;
done:
return ret;
/* == ad_gpo_process_som_send/recv implementation ========================== */
struct tevent_req *
int timeout,
const char *target_dn,
const char *domain_name)
return NULL;
goto immediately;
goto immediately;
goto immediately;
return req;
* retrieved at that point (see https://fedorahosted.org/sssd/ticket/2276)
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
done:
static errno_t
return ENOMEM;
return EAGAIN;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
allow_enforced_only = 0;
if (errno != 0) {
goto done;
(char *)raw_gplink_value,
goto done;
if (allow_enforced_only) {
done:
return EOK;
/* == ad_gpo_process_gpo_send/recv helpers ================================= */
static errno_t
int *_num_candidate_gpos)
goto done;
while (som_list[i]) {
goto done;
num_enforced++;
if (num_candidate_gpos == 0) {
*_num_candidate_gpos = 0;
goto done;
goto done;
goto done;
while (som_list[i]) {
goto done;
goto done;
enforced_idx++;
goto done;
struct gp_gpo *,
goto done;
gpo_dn_idx = 0;
goto done;
goto done;
gpo_dn_idx++;
for (i = 0; i < num_enforced; i++) {
goto done;
goto done;
gpo_dn_idx++;
done:
return ret;
* server_hostname = "adserver.foo.com", then
* _smb_server = "smb://adserver.foo.com"
* _smb_path = "/foo.com/..."
* For example, input_path = "\\foo.com\SysVol" is not a valid input_path,
static errno_t
char *server_hostname,
char *input_path,
const char **_smb_server,
const char **_smb_share,
const char **_smb_path)
goto done;
num_seps++;
ptr++;
ptr++;
ptr++;
if (num_seps == 0) {
goto done;
goto done;
goto done;
goto done;
goto done;
done:
return ret;
static errno_t
char *raw_machine_ext_names_value,
const char ***_gpo_cse_guids,
int *_num_gpo_cse_guids)
return EINVAL;
goto done;
ptr++;
if (num_gpo_cse_guids == 0) {
goto done;
goto done;
for (i = 0; i < num_gpo_cse_guids; i++) {
last++;
first ++;
for (i = 0; i < num_gpo_cse_guids; i++) {
done:
return ret;
enum ndr_err_code
struct security_descriptor *r);
return EINVAL;
&sd);
return EINVAL;
return EOK;
/* == ad_gpo_process_gpo_send/recv implementation ========================== */
struct tevent_req *
char *server_hostname,
int timeout,
return NULL;
goto immediately;
goto immediately;
return req;
static errno_t
return ENOMEM;
return EAGAIN;
static errno_t
char *smb_host,
static struct tevent_req *
const char *referral,
int timeout);
char **_smb_host,
goto done;
refs[0],
if (!subreq) {
goto done;
goto done;
goto done;
goto done;
done:
goto done;
done:
static errno_t
char *smb_host,
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
(char *)raw_machine_ext_names,
goto done;
done:
return ret;
int *num_candidate_gpos)
return EOK;
/* == ad_gpo_process_cse_send/recv helpers ================================= */
static errno_t
const char *smb_server,
const char *smb_share,
const char *smb_path,
const char *smb_cse_suffix,
int cached_gpt_version,
return ENOMEM;
return ENOMEM;
rp = 0;
return EOK;
static errno_t
size_t p = 0;
return ret;
/* == ad_gpo_process_cse_send/recv implementation ========================== */
struct tevent_req *
bool send_to_child,
const char *gpo_guid,
const char *smb_server,
const char *smb_share,
const char *smb_path,
const char *smb_cse_suffix,
int cached_gpt_version,
int gpo_timeout_option)
return NULL;
if (!send_to_child) {
goto immediately;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
return req;
return req;
} else if (child_result != 0){
return EOK;
static errno_t
goto fail;
goto fail;
goto fail;
goto fail;
return EOK;
fail:
return ret;
static struct tevent_req *
const char *referral,
int timeout)
struct ad_gpo_get_sd_referral_state);
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
done:
return req;
goto done;
goto done;
goto done;
done:
char **_smb_host,
return EOK;