60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley Yassir Elley <yelley@redhat.com>
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley Copyright (C) 2013 Red Hat
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley This program is free software; you can redistribute it and/or modify
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley it under the terms of the GNU General Public License as published by
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley the Free Software Foundation; either version 3 of the License, or
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley (at your option) any later version.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley This program is distributed in the hope that it will be useful,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley but WITHOUT ANY WARRANTY; without even the implied warranty of
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley GNU General Public License for more details.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley You should have received a copy of the GNU General Public License
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley along with this program. If not, see <http://www.gnu.org/licenses/>.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This file implements the following pair of *public* functions (see header):
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * ad_gpo_access_send/recv: provides client-side GPO processing
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This file also implements the following pairs of *private* functions (which
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * are used by the public functions):
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * ad_gpo_process_som_send/recv: populate list of gp_som objects
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * ad_gpo_process_gpo_send/recv: populate list of gp_gpo objects
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * ad_gpo_process_cse_send/recv: retrieve policy file data
19d3aba12c70528708be9440aca66038a291f29eYassir Elley/* == gpo-ldap constants =================================================== */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley#define AD_AT_CONFIG_NC "configurationNamingContext"
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley#define AD_AT_NT_SEC_DESC "nTSecurityDescriptor"
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley#define AD_AT_MACHINE_EXT_NAMES "gPCMachineExtensionNames"
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley#define AD_AT_FUNC_VERSION "gPCFunctionalityVersion"
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley#define UAC_WORKSTATION_TRUST_ACCOUNT 0x00001000
5c129880ae10c80b4f79cb2994e9d127dc6dfbefMathieu Deaudelin-Lemay#define UAC_SERVER_TRUST_ACCOUNT 0x00002000
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley#define AD_AGP_GUID "edacfd8f-ffb3-11d1-b41d-00a0c968f939"
19d3aba12c70528708be9440aca66038a291f29eYassir Elley/* == gpo-smb constants ==================================================== */
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley#define ALLOW_LOGON_INTERACTIVE "SeInteractiveLogonRight"
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley#define DENY_LOGON_INTERACTIVE "SeDenyInteractiveLogonRight"
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley#define ALLOW_LOGON_REMOTE_INTERACTIVE "SeRemoteInteractiveLogonRight"
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley#define DENY_LOGON_REMOTE_INTERACTIVE "SeDenyRemoteInteractiveLogonRight"
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley#define ALLOW_LOGON_NETWORK "SeNetworkLogonRight"
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley#define DENY_LOGON_NETWORK "SeDenyNetworkLogonRight"
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley#define DENY_LOGON_BATCH "SeDenyBatchLogonRight"
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley#define ALLOW_LOGON_SERVICE "SeServiceLogonRight"
4611802d41d8954a3040f39403590adb920ca521Yassir Elley#define DENY_LOGON_SERVICE "SeDenyServiceLogonRight"
19d3aba12c70528708be9440aca66038a291f29eYassir Elley#define GP_EXT_GUID_SECURITY "{827D319E-6EAC-11D2-A4EA-00C04F79F83A}"
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley#define GP_EXT_GUID_SECURITY_SUFFIX "/Machine/Microsoft/Windows NT/SecEdit/GptTmpl.inf"
21a28c92d56a0fa3b62a951eb64bf0c48034fe5eMichal Židek/* If INI_PARSE_IGNORE_NON_KVP is not defined, use 0 (no effect) */
19d3aba12c70528708be9440aca66038a291f29eYassir Elley/* fd used by the gpo_child process for logging */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley/* == common data structures and declarations ============================= */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystruct tevent_req *ad_gpo_process_som_send(TALLOC_CTX *mem_ctx,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyint ad_gpo_process_som_recv(struct tevent_req *req,
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagherad_gpo_process_gpo_send(TALLOC_CTX *mem_ctx,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyint ad_gpo_process_gpo_recv(struct tevent_req *req,
19d3aba12c70528708be9440aca66038a291f29eYassir Elleystruct tevent_req *ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx,
0bed97f6ca4ad8bb61de9114c23051e7eaa8d1fcLukas Slebodnikint ad_gpo_process_cse_recv(struct tevent_req *req);
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley/* == ad_gpo_parse_map_options and helpers ==================================*/
293cf52a00c9c67f0ad8f264027f81c020854f66Stephen Gallagher GPO_GDM_FINGERPRINT, GPO_GDM_PASSWORD, GPO_GDM_SMARTCARD, GPO_KDM,
89376da80b2250b82d256ea85ec349ce29fe5b51Stephen Gallagher GPO_LIGHTDM, GPO_LXDM, GPO_SDDM, GPO_UNITY, GPO_XDM, NULL};
0e799bc491f636c69657d1678af13d23bf7b7c10Stephen Gallagherconst char *gpo_map_remote_interactive_defaults[] = {GPO_SSHD, GPO_COCKPIT,
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elleyconst char *gpo_map_network_defaults[] = {GPO_FTP, GPO_SAMBA, NULL};
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elleyconst char *gpo_map_batch_defaults[] = {GPO_CROND, NULL};
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elleyconst char *gpo_map_service_defaults[] = {NULL};
5597f6eb3674c084ae5a089194d84c8604696a1fStephen Gallagherconst char *gpo_map_permit_defaults[] = {GPO_POLKIT,
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elleystruct gpo_map_option_entry gpo_map_option_entries[] = {
4611802d41d8954a3040f39403590adb920ca521Yassir Elley {GPO_MAP_INTERACTIVE, AD_GPO_MAP_INTERACTIVE, gpo_map_interactive_defaults,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley ALLOW_LOGON_INTERACTIVE, DENY_LOGON_INTERACTIVE},
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley {GPO_MAP_REMOTE_INTERACTIVE, AD_GPO_MAP_REMOTE_INTERACTIVE,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley ALLOW_LOGON_REMOTE_INTERACTIVE, DENY_LOGON_REMOTE_INTERACTIVE},
4611802d41d8954a3040f39403590adb920ca521Yassir Elley {GPO_MAP_NETWORK, AD_GPO_MAP_NETWORK, gpo_map_network_defaults,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley {GPO_MAP_BATCH, AD_GPO_MAP_BATCH, gpo_map_batch_defaults,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley {GPO_MAP_SERVICE, AD_GPO_MAP_SERVICE, gpo_map_service_defaults,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley {GPO_MAP_PERMIT, AD_GPO_MAP_PERMIT, gpo_map_permit_defaults, NULL, NULL},
4611802d41d8954a3040f39403590adb920ca521Yassir Elley {GPO_MAP_DENY, AD_GPO_MAP_DENY, gpo_map_deny_defaults, NULL, NULL},
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elleyconst char* gpo_map_type_string(int gpo_map_type)
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley case GPO_MAP_INTERACTIVE: return "Interactive";
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley case GPO_MAP_REMOTE_INTERACTIVE: return "Remote Interactive";
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elleystatic inline bool
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elleyad_gpo_service_in_list(char **list, size_t nlist, const char *str)
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley for (i = 0; i < nlist; i++) {
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley return (i < nlist) ? true : false;
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elleyad_gpo_parse_map_option_helper(enum gpo_map_type gpo_map_type,
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley if (hret != HASH_SUCCESS && hret != HASH_ERROR_KEY_NOT_FOUND) {
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "Error checking hash table: [%s]\n",
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley /* handle unexpected case where mapping for key already exists */
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley /* mapping for key exists for same map type; no error */
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley "PAM service %s maps to %s multiple times\n", key.str,
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley /* mapping for key exists for different map type; error! */
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley "PAM service %s maps to both %s and %s\n", key.str,
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley gpo_map_type_string(val.i), gpo_map_type_string(gpo_map_type));
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley /* handle expected case where mapping for key doesn't already exist */
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "Error checking hash table: [%s]\n",
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley const char **defaults)
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley ret = split_on_separator(tmp_ctx, conf_str, ',', true, true,
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley "Cannot parse list of service names %s: %d\n", conf_str, ret);
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley add_list = talloc_zero_array(tmp_ctx, char *, conf_list_size);
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley remove_list = talloc_zero_array(tmp_ctx, char *, conf_list_size);
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley for (i = 0; i < conf_list_size; i++) {
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley switch (conf_list[i][0]) {
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "ad_gpo_map values must start with"
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley "either '+' (for adding service) or '-' (for removing service), "
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley "got '%s'\n",
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley /* Start by adding explicitly added services ('+') to hashtable */
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley for (i = 0; i < ai; i++) {
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley /* if the service is explicitly configured to be removed, skip it */
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley if (ad_gpo_service_in_list(remove_list, ri, add_list[i])) {
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley ret = ad_gpo_parse_map_option_helper(gpo_map_type, key, options_table);
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "Invalid configuration: %d\n", ret);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "Explicitly added service: %s\n", key.str);
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley /* Add defaults to hashtable */
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley for (i = 0; defaults[i]; i++) {
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley /* if the service is explicitly configured to be removed, skip it */
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley if (ad_gpo_service_in_list(remove_list, ri, defaults[i])) {
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley ret = ad_gpo_parse_map_option_helper(gpo_map_type, key, options_table);
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "Invalid configuration: %d\n", ret);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "Default service (not explicitly removed): %s\n",
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elleyad_gpo_parse_map_options(struct ad_access_ctx *access_ctx)
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley for (i = 0; i < GPO_MAP_NUM_OPTS; i++) {
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley struct gpo_map_option_entry entry = gpo_map_option_entries[i];
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley char *entry_config = dp_opt_get_string(access_ctx->ad_options,
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley ret = ad_gpo_parse_map_option(access_ctx, entry.gpo_map_type,
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "Invalid configuration: %d\n", ret);
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley /* default right (applicable for services without any mapping) */
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley dp_opt_get_string(access_ctx->ad_options, AD_GPO_DEFAULT_RIGHT);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "gpo_default_right_config: %s\n",
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley /* if default right not set in config, set them to DENY */
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley } else if (strncasecmp(gpo_default_right_config, "interactive",
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley } else if (strncasecmp(gpo_default_right_config, "remote_interactive",
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley gpo_default_right = GPO_MAP_REMOTE_INTERACTIVE;
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley } else if (strncasecmp(gpo_default_right_config, "network",
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley } else if (strncasecmp(gpo_default_right_config, "batch",
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley } else if (strncasecmp(gpo_default_right_config, "service",
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley } else if (strncasecmp(gpo_default_right_config, "permit",
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley } else if (strncasecmp(gpo_default_right_config, "deny",
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "gpo_default_right: %d\n", gpo_default_right);
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley access_ctx->gpo_default_right = gpo_default_right;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley/* == ad_gpo_access_send/recv helpers =======================================*/
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elleyad_gpo_dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2)
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley return true;
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley return false;
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley return false;
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley for (i = 0; i < 6; i++) {
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley return false;
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley return false;
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley if (sid1->sub_auths[i] != sid2->sub_auths[i]) {
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley return false;
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley return true;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This function retrieves the SIDs corresponding to the input user and returns
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * the user_sid, group_sids, and group_size in their respective output params.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * Note: since authentication must complete successfully before the
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * gpo access checks are called, we can safely assume that the user/computer
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * has been authenticated. As such, this function always adds the
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * AD_AUTHENTICATED_USERS_SID to the group_sids.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley const char *user,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley const char ***_group_sids,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* first result from sysdb_initgroups is user_sid; rest are group_sids */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = sysdb_initgroups(tmp_ctx, domain, user, &res);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "sysdb_initgroups failed: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "sysdb_initgroups returned empty result\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley user_sid = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SID_STR, NULL);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* include space for AD_AUTHENTICATED_USERS_SID and NULL */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley group_sids = talloc_array(tmp_ctx, const char *, num_group_sids + 1 + 1);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley for (i = 0; i < num_group_sids; i++) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley group_sid = ldb_msg_find_attr_as_string(res->msgs[i+1],
4cfab2330323834574c179f774a0c6b1fff4936eSumit Bose DEBUG(SSSDBG_CRIT_FAILURE, "Missing SID for cache entry [%s].\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley group_sids[i] = talloc_steal(group_sids, group_sid);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley group_sids[i++] = talloc_strdup(group_sids, AD_AUTHENTICATED_USERS_SID);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley *_group_sids = talloc_steal(mem_ctx, group_sids);
4e299001aff97d5aaabd7ca490cd7d3d5151823eYassir Elley * This function determines whether the input ace_dom_sid matches any of the
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * client's SIDs. The boolean result is assigned to the _included output param.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_ace_includes_client_sid(const char *user_sid,
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley err = sss_idmap_sid_to_smb_sid(idmap_ctx, user_sid, &user_dom_sid);
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize idmap context.\n");
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley included = ad_gpo_dom_sid_equal(&ace_dom_sid, user_dom_sid);
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley sss_idmap_free_smb_sid(idmap_ctx, user_dom_sid);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley for (i = 0; i < group_size; i++) {
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley err = sss_idmap_sid_to_smb_sid(idmap_ctx, group_sids[i], &group_dom_sid);
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize idmap context.\n");
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley included = ad_gpo_dom_sid_equal(&ace_dom_sid, group_dom_sid);
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley sss_idmap_free_smb_sid(idmap_ctx, group_dom_sid);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This function determines whether use of the extended right
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * named "ApplyGroupPolicy" (AGP) is allowed, by comparing the specified
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * user_sid and group_sids against the specified access control entry (ACE).
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This function returns ALLOWED, DENIED, or NEUTRAL depending on whether
a02a5ed51178b2cbede0396d66aed716b8898096René Genz * the ACE explicitly allows, explicitly denies, or does neither.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * Note that the 'M' abbreviation used in the evaluation algorithm stands for
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * "access_mask", which represents the set of access rights associated with an
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * individual ACE. The access right of interest to the GPO code is
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * RIGHT_DS_CONTROL_ACCESS, which serves as a container for all control access
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * rights. The specific control access right is identified by a GUID in the
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * ACE's ObjectType. In our case, this is the GUID corresponding to AGP.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * The ACE evaluation algorithm is specified in [MS-ADTS] 5.1.3.3.4:
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * - Deny access by default
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * - If the "Inherit Only" (IO) flag is set in the ACE, skip the ACE.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * - If the SID in the ACE does not match any SID in the requester's
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * security context, skip the ACE
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * - If the ACE type is "Object Access Allowed", the access right
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * RIGHT_DS_CONTROL_ACCESS (CR) is present in M, and the ObjectType
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * field in the ACE is either not present OR contains a GUID value equal
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * to AGP, then grant requested control access right. Stop access checking.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * - If the ACE type is "Object Access Denied", the access right
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * RIGHT_DS_CONTROL_ACCESS (CR) is present in M, and the ObjectType
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * field in the ACE is either not present OR contains a GUID value equal to
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * AGP, then deny the requested control access right. Stop access checking.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic enum ace_eval_status ad_gpo_evaluate_ace(struct security_ace *ace,
4e299001aff97d5aaabd7ca490cd7d3d5151823eYassir Elley ret = ad_gpo_ace_includes_client_sid(user_sid, group_sids, group_size,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley GUID_from_string(AD_AGP_GUID, &ext_right_agp_guid);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (GUID_equal(&object.type.type, &ext_right_agp_guid)) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (ace->access_mask & SEC_ADS_CONTROL_ACCESS) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This function extracts the GPO's DACL (discretionary access control list)
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * from the GPO's specified security descriptor, and determines whether
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * the GPO is applicable to the policy target, by comparing the specified
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * user_sid and group_sids against each access control entry (ACE) in the DACL.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * The boolean result is assigned to the _access_allowed output parameter.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic errno_t ad_gpo_evaluate_dacl(struct security_acl *dacl,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * [MS-ADTS] 5.1.3.3.4:
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * If the DACL does not have any ACE, then deny the requester the
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * requested control access right.
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley ace_status = ad_gpo_evaluate_ace(ace, idmap_ctx, user_sid,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This function takes candidate_gpos as input, filters out any gpo that is
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * not applicable to the policy target and assigns the result to the
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * _dacl_filtered_gpos output parameter. The filtering algorithm is
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * defined in [MS-GPOL] 3.2.5.1.6
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley const char *user,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = ad_gpo_get_sids(tmp_ctx, user, domain, &user_sid,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "Unable to retrieve SIDs: [%d](%s)\n", ret, sss_strerror(ret));
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley for (i = 0; i < num_candidate_gpos; i++) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "examining dacl candidate_gpo_guid:%s\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* gpo_func_version must be set to version 2 */
47680083e7e4bf5c433657171bf84cceacc83339Michal Židek "GPO not applicable to target per security filtering: "
47680083e7e4bf5c433657171bf84cceacc83339Michal Židek "gPCFunctionalityVersion is not 2\n");
6a490b312075d2588ad87bbb8a63466f1ac6a106Michal Židek DEBUG(SSSDBG_TRACE_ALL, "Security descriptor is missing\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* gpo_flags value of 2 means that GPO's computer portion is disabled */
47680083e7e4bf5c433657171bf84cceacc83339Michal Židek "GPO not applicable to target per security filtering: "
47680083e7e4bf5c433657171bf84cceacc83339Michal Židek "GPO's computer portion is disabled\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * [MS-ADTS] 5.1.3.3.4:
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * If the security descriptor has no DACL or its "DACL Present" bit
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * is not set, then grant requester the requested control access right.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if ((!(sd->type & SEC_DESC_DACL_PRESENT)) || (dacl == NULL)) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "DACL is not present\n");
210bc14aac190bbb043272821aeb3342c995a4f6Jakub Hrozek ret = ad_gpo_evaluate_dacl(dacl, idmap_ctx, user_sid, group_sids,
210bc14aac190bbb043272821aeb3342c995a4f6Jakub Hrozek DEBUG(SSSDBG_MINOR_FAILURE, "Could not determine if GPO is applicable\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "GPO applicable to target per security filtering\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley dacl_filtered_gpos[gpo_dn_idx] = talloc_steal(dacl_filtered_gpos,
47680083e7e4bf5c433657171bf84cceacc83339Michal Židek "GPO not applicable to target per security filtering: "
47680083e7e4bf5c433657171bf84cceacc83339Michal Židek "result of DACL evaluation\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley *_dacl_filtered_gpos = talloc_steal(mem_ctx, dacl_filtered_gpos);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * This function determines whether the input cse_guid matches any of the input
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * gpo_cse_guids. The boolean result is assigned to the _included output param.
19d3aba12c70528708be9440aca66038a291f29eYassir Elley for (i = 0; i < num_gpo_cse_guids; i++) {
19d3aba12c70528708be9440aca66038a291f29eYassir Elley return true;
19d3aba12c70528708be9440aca66038a291f29eYassir Elley return false;
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * This function takes an input dacl_filtered_gpos list, filters out any gpo
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * that does not contain the input cse_guid, and assigns the result to the
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * _cse_filtered_gpos output parameter.
19d3aba12c70528708be9440aca66038a291f29eYassir Elleyad_gpo_filter_gpos_by_cse_guid(TALLOC_CTX *mem_ctx,
19d3aba12c70528708be9440aca66038a291f29eYassir Elley for (i = 0; i < num_dacl_filtered_gpos; i++) {
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_TRACE_ALL, "examining cse candidate_gpo_guid: %s\n",
19d3aba12c70528708be9440aca66038a291f29eYassir Elley "GPO applicable to target per cse_guid filtering\n");
19d3aba12c70528708be9440aca66038a291f29eYassir Elley cse_filtered_gpos[gpo_dn_idx] = talloc_steal(cse_filtered_gpos,
19d3aba12c70528708be9440aca66038a291f29eYassir Elley "GPO not applicable to target per cse_guid filtering\n");
19d3aba12c70528708be9440aca66038a291f29eYassir Elley *_cse_filtered_gpos = talloc_steal(mem_ctx, cse_filtered_gpos);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * This cse-specific function (GP_EXT_GUID_SECURITY) returns a boolean value
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * based on whether the input user_sid or any of the input group_sids appear
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * in the input list of privilege_sids.
19d3aba12c70528708be9440aca66038a291f29eYassir Elley for (i = 0; i < privilege_size; i++) {
19d3aba12c70528708be9440aca66038a291f29eYassir Elley if (strcmp(user_sid, privilege_sids[i]) == 0) {
19d3aba12c70528708be9440aca66038a291f29eYassir Elley return true;
19d3aba12c70528708be9440aca66038a291f29eYassir Elley for (j = 0; j < group_size; j++) {
19d3aba12c70528708be9440aca66038a291f29eYassir Elley if (strcmp(group_sids[j], privilege_sids[i]) == 0) {
19d3aba12c70528708be9440aca66038a291f29eYassir Elley return true;
19d3aba12c70528708be9440aca66038a291f29eYassir Elley return false;
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * This function parses the input ini_config object (which represents
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * the cse-specific filename), and returns the policy_setting_value
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * corresponding to the input policy_setting_key.
4611802d41d8954a3040f39403590adb920ca521Yassir Elleyad_gpo_extract_policy_setting(TALLOC_CTX *mem_ctx,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley ret = ini_get_config_valueobj(RIGHTS_SECTION, policy_setting_key, ini_config,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley "ini_get_config_valueobj failed [%d][%s]\n", ret, strerror(ret));
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "section/name not found: [%s][%s]\n",
4611802d41d8954a3040f39403590adb920ca521Yassir Elley policy_setting_value = ini_get_string_config_value(vobj, &ret);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley "ini_get_string_config_value failed [%d][%s]\n",
4611802d41d8954a3040f39403590adb920ca521Yassir Elley *_policy_setting_value = talloc_strdup(mem_ctx, policy_setting_value);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley /* This is an explicitly empty policy setting.
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * We need to remove this from the LDB.
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * This function parses the cse-specific (GP_EXT_GUID_SECURITY) filename,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * and stores the allow_key and deny_key of all of the gpo_map_types present
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * in the file (as part of the GPO Result object in the sysdb cache).
0bed97f6ca4ad8bb61de9114c23051e7eaa8d1fcLukas Slebodnikad_gpo_store_policy_settings(struct sss_domain_info *domain,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley "ini_config_create failed [%d][%s]\n", ret, strerror(ret));
4611802d41d8954a3040f39403590adb920ca521Yassir Elley ret = ini_config_file_open(filename, 0, &file_ctx);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley "ini_config_file_open failed [%d][%s]\n", ret, strerror(ret));
4611802d41d8954a3040f39403590adb920ca521Yassir Elley ret = ini_config_parse(file_ctx, INI_STOP_ON_NONE, 0, 0, ini_config);
dad416a9b0095e1c423b7da65db7c636fa69e614Michal Židek "[%s]: ini_config_parse failed [%d][%s]\n",
dad416a9b0095e1c423b7da65db7c636fa69e614Michal Židek /* Now get specific errors if there are any */
dad416a9b0095e1c423b7da65db7c636fa69e614Michal Židek lret = ini_config_get_errors(ini_config, &errors);
dad416a9b0095e1c423b7da65db7c636fa69e614Michal Židek "Failed to get specific parse error [%d][%s]\n", lret,
dad416a9b0095e1c423b7da65db7c636fa69e614Michal Židek for (int a = 0; errors[a]; a++) {
21a28c92d56a0fa3b62a951eb64bf0c48034fe5eMichal Židek /* Do not 'goto done' here. We will try to parse
21a28c92d56a0fa3b62a951eb64bf0c48034fe5eMichal Židek * the GPO file again. */
21a28c92d56a0fa3b62a951eb64bf0c48034fe5eMichal Židek /* A problem occurred during parsing. Try again
21a28c92d56a0fa3b62a951eb64bf0c48034fe5eMichal Židek * with INI_PARSE_IGNORE_NON_KVP flag */
21a28c92d56a0fa3b62a951eb64bf0c48034fe5eMichal Židek ret = ini_config_file_open(filename, 0, &file_ctx);
21a28c92d56a0fa3b62a951eb64bf0c48034fe5eMichal Židek "ini_config_file_open failed [%d][%s]\n",
21a28c92d56a0fa3b62a951eb64bf0c48034fe5eMichal Židek "ini_config_create failed [%d][%s]\n", ret, strerror(ret));
21a28c92d56a0fa3b62a951eb64bf0c48034fe5eMichal Židek ret = ini_config_parse(file_ctx, INI_STOP_ON_NONE, 0,
21a28c92d56a0fa3b62a951eb64bf0c48034fe5eMichal Židek "[%s]: ini_config_parse failed [%d][%s]\n",
21a28c92d56a0fa3b62a951eb64bf0c48034fe5eMichal Židek /* Now get specific errors if there are any */
21a28c92d56a0fa3b62a951eb64bf0c48034fe5eMichal Židek lret = ini_config_get_errors(ini_config, &errors);
21a28c92d56a0fa3b62a951eb64bf0c48034fe5eMichal Židek "Failed to get specific parse error [%d][%s]\n", lret,
21a28c92d56a0fa3b62a951eb64bf0c48034fe5eMichal Židek for (int a = 0; errors[a]; a++) {
4611802d41d8954a3040f39403590adb920ca521Yassir Elley for (i = 0; i < GPO_MAP_NUM_OPTS; i++) {
e6e5fe349aa6ed85eb9acb3273007fa90ee99450Michal Židek /* The NO_SID val is used as special SID value for the case when
e6e5fe349aa6ed85eb9acb3273007fa90ee99450Michal Židek * no SIDs are found in the rule, but we need to store some
e6e5fe349aa6ed85eb9acb3273007fa90ee99450Michal Židek * value (SID) with the key (rule name) so that it is clear
e6e5fe349aa6ed85eb9acb3273007fa90ee99450Michal Židek * that the rule is defined on the server. */
4611802d41d8954a3040f39403590adb920ca521Yassir Elley struct gpo_map_option_entry entry = gpo_map_option_entries[i];
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "allow_key = %s\n", allow_key);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley "ad_gpo_extract_policy_setting failed for %s [%d][%s]\n",
e6e5fe349aa6ed85eb9acb3273007fa90ee99450Michal Židek const char *value = allow_value ? allow_value : empty_val;
4611802d41d8954a3040f39403590adb920ca521Yassir Elley ret = sysdb_gpo_store_gpo_result_setting(domain,
b083fec6c175989e0d32b83d8cc857a6b54d26a2Lukas Slebodnik "sysdb_gpo_store_gpo_result_setting failed for key:"
b083fec6c175989e0d32b83d8cc857a6b54d26a2Lukas Slebodnik "'%s' value:'%s' [%d][%s]\n", allow_key, allow_value,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "deny_key = %s\n", deny_key);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley "ad_gpo_extract_policy_setting failed for %s [%d][%s]\n",
e6e5fe349aa6ed85eb9acb3273007fa90ee99450Michal Židek const char *value = deny_value ? deny_value : empty_val;
4611802d41d8954a3040f39403590adb920ca521Yassir Elley ret = sysdb_gpo_store_gpo_result_setting(domain,
b083fec6c175989e0d32b83d8cc857a6b54d26a2Lukas Slebodnik "sysdb_gpo_store_gpo_result_setting failed for key:"
b083fec6c175989e0d32b83d8cc857a6b54d26a2Lukas Slebodnik "'%s' value:'%s' [%d][%s]\n", deny_key, deny_value,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "Error encountered: %d.\n", ret);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * This cse-specific function (GP_EXT_GUID_SECURITY) performs the access
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * check for determining whether logon access is granted or denied for
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * the {user,domain} tuple specified in the inputs. This function returns EOK
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * to indicate that access is granted. Any other return value indicates that
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * access is denied.
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * The access control algorithm first determines whether the "principal_sids"
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * (i.e. user_sid or group_sids) appear in allowed_sids and denied_sids.
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * For access to be granted, both the "allowed_sids_condition" *and* the
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * "denied_sids_condition" must be met (in all other cases, access is denied).
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * 1) The "allowed_sids_condition" is satisfied if any of the principal_sids
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * appears in allowed_sids OR if the allowed_sids list is empty
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * 2) The "denied_sids_condition" is satisfied if none of the principal_sids
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * appear in denied_sids
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * Note that a deployment that is unaware of GPO-based access-control policy
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * settings is unaffected by them (b/c absence of allowed_sids grants access).
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * Note that if a principal_sid appears in both allowed_sids and denied_sids,
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * the "allowed_sids_condition" is met, but the "denied_sids_condition" is not.
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * In other words, Deny takes precedence over Allow.
19d3aba12c70528708be9440aca66038a291f29eYassir Elley const char *user,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "RESULTANT POLICY:\n");
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_TRACE_FUNC, "allowed_size = %d\n", allowed_size);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley for (j= 0; j < allowed_size; j++) {
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "allowed_sids[%d] = %s\n", j, allowed_sids[j]);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_TRACE_FUNC, "denied_size = %d\n", denied_size);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley for (j= 0; j < denied_size; j++) {
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, " denied_sids[%d] = %s\n", j, denied_sids[j]);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley ret = ad_gpo_get_sids(mem_ctx, user, domain, &user_sid,
19d3aba12c70528708be9440aca66038a291f29eYassir Elley "Unable to retrieve SIDs: [%d](%s)\n", ret, sss_strerror(ret));
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_TRACE_FUNC, " user_sid = %s\n", user_sid);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley for (j= 0; j < group_size; j++) {
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_TRACE_FUNC, " group_sids[%d] = %s\n", j,
19d3aba12c70528708be9440aca66038a291f29eYassir Elley access_granted = check_rights(allowed_sids, allowed_size, user_sid,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "POLICY DECISION:\n");
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_TRACE_FUNC, " access_granted = %d\n", access_granted);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley access_denied = check_rights(denied_sids, denied_size, user_sid,
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_TRACE_FUNC, " access_denied = %d\n", access_denied);
588f8fbe74e66cc015f185a5b798173d320a65b5Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "access denied: permissive mode\n");
588f8fbe74e66cc015f185a5b798173d320a65b5Yassir Elley sss_log_ext(SSS_LOG_WARNING, LOG_AUTHPRIV, "Warning: user would " \
588f8fbe74e66cc015f185a5b798173d320a65b5Yassir Elley "have been denied GPO-based logon access if the " \
588f8fbe74e66cc015f185a5b798173d320a65b5Yassir Elley "ad_gpo_access_control option were set to enforcing " \
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "Error encountered: %d.\n", ret);
77b13371c87702aee3f858f6b2b73826cf5a01bdJakub Hrozek return child_debug_init(GPO_CHILD_LOG_FILE, &gpo_child_debug_fd);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * This function retrieves the raw policy_setting_value for the input key from
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * the GPO_Result object in the sysdb cache. It then parses the raw value and
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * uses the results to populate the output parameters with the sids_list and
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * the size of the sids_list.
4611802d41d8954a3040f39403590adb920ca521Yassir Elley const char *key,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley ret = sysdb_gpo_get_gpo_result_setting(mem_ctx, domain, key, &value);
fc2cc91a5b645180e53d46436b0d08011aac8d74Jakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, "No previous GPO result\n");
dd09bbb2578bd9f82afd7fc4d4fcc3a5659731d3Lukas Slebodnik "Cannot retrieve settings from sysdb for key: '%s' [%d][%s].\n",
4611802d41d8954a3040f39403590adb920ca521Yassir Elley "No value for key [%s] found in gpo result\n", key);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley ret = split_on_separator(mem_ctx, value, ',', true, true,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley "Cannot parse list of sids %s: %d\n", value, ret);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley for (i = 0; i < sids_list_size; i++) {
4611802d41d8954a3040f39403590adb920ca521Yassir Elley /* remove the asterisk prefix found on sids */
4611802d41d8954a3040f39403590adb920ca521Yassir Elley *_sids_list = talloc_steal(mem_ctx, sids_list);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * This cse-specific function (GP_EXT_GUID_SECURITY) performs HBAC policy
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * processing and determines whether logon access is granted or denied for
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * the {user,domain} tuple specified in the inputs. This function returns EOK
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * to indicate that access is granted. Any other return value indicates that
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * access is denied.
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * Internally, this function retrieves the allow_value and deny_value for the
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * input gpo_map_type from the GPO Result object in the sysdb cache, parses
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * the values into allow_sids and deny_sids, and executes the access control
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * algorithm which compares the allow_sids and deny_sids against the user_sid
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * and group_sids for the input user.
4611802d41d8954a3040f39403590adb920ca521Yassir Elleyad_gpo_perform_hbac_processing(TALLOC_CTX *mem_ctx,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley const char *user,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley allow_key = gpo_map_option_entries[gpo_map_type].allow_key;
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "allow_key: %s\n", allow_key);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley deny_key = gpo_map_option_entries[gpo_map_type].deny_key;
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "deny_key: %s\n", deny_key);
475d986b534c5e0dfdb8e2348ab89b13fd4874aaStephen Gallagher ret = parse_policy_setting_value(mem_ctx, host_domain, allow_key,
76ba5d2b8d95ec444c124dd9a44275ce685fb648Lukas Slebodnik "parse_policy_setting_value failed for key %s: [%d](%s)\n",
475d986b534c5e0dfdb8e2348ab89b13fd4874aaStephen Gallagher ret = parse_policy_setting_value(mem_ctx, host_domain, deny_key,
76ba5d2b8d95ec444c124dd9a44275ce685fb648Lukas Slebodnik "parse_policy_setting_value failed for key %s: [%d](%s)\n",
4611802d41d8954a3040f39403590adb920ca521Yassir Elley /* perform access check with the final resultant allow_sids and deny_sids */
475d986b534c5e0dfdb8e2348ab89b13fd4874aaStephen Gallagher ret = ad_gpo_access_check(mem_ctx, gpo_mode, gpo_map_type, user,
475d986b534c5e0dfdb8e2348ab89b13fd4874aaStephen Gallagher user_domain, allow_sids, allow_size, deny_sids,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley "GPO access check failed: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley/* == ad_gpo_access_send/recv implementation ================================*/
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic void ad_gpo_connect_done(struct tevent_req *subreq);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic void ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic void ad_gpo_process_som_done(struct tevent_req *subreq);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic void ad_gpo_process_gpo_done(struct tevent_req *subreq);
19d3aba12c70528708be9440aca66038a291f29eYassir Elleystatic errno_t ad_gpo_cse_step(struct tevent_req *req);
19d3aba12c70528708be9440aca66038a291f29eYassir Elleystatic void ad_gpo_cse_done(struct tevent_req *subreq);
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley const char *user,
19d3aba12c70528708be9440aca66038a291f29eYassir Elley /* setup logging for gpo child */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley req = tevent_req_create(mem_ctx, &state, struct ad_gpo_access_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley /* determine service's option_type (e.g. interactive, network, etc) */
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley hret = hash_lookup(ctx->gpo_map_options_table, &key, &val);
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley if (hret != HASH_SUCCESS && hret != HASH_ERROR_KEY_NOT_FOUND) {
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "Error checking hash table: [%s]\n",
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley /* if service isn't mapped, map it to value of ad_gpo_default_right option */
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "using default right\n");
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "service %s maps to %s\n", service,
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "access denied: permissive mode\n");
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley sss_log_ext(SSS_LOG_WARNING, LOG_AUTHPRIV, "Warning: user would " \
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley "have been denied GPO-based logon access if the " \
a8356a0c98ee44e7256bb1c7767159c70e1fc218Yassir Elley "ad_gpo_access_control option were set to enforcing " \
475d986b534c5e0dfdb8e2348ab89b13fd4874aaStephen Gallagher /* GPO Operations all happen against the enrolled domain,
475d986b534c5e0dfdb8e2348ab89b13fd4874aaStephen Gallagher * not the user's domain (which may be a trusted realm)
475d986b534c5e0dfdb8e2348ab89b13fd4874aaStephen Gallagher state->host_domain = get_domains_head(domain);
475d986b534c5e0dfdb8e2348ab89b13fd4874aaStephen Gallagher state->ldb_ctx = sysdb_ctx_get_ldb(state->host_domain->sysdb);
588f8fbe74e66cc015f185a5b798173d320a65b5Yassir Elley state->gpo_mode = ctx->gpo_access_control_mode;
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley state->gpo_timeout_option = ctx->gpo_cache_timeout;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state->ad_hostname = dp_opt_get_string(ctx->ad_options, AD_HOSTNAME);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state->opts = ctx->sdap_access_ctx->id_ctx->opts;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT);
475d986b534c5e0dfdb8e2348ab89b13fd4874aaStephen Gallagher state->conn = ad_get_dom_ldap_conn(ctx->ad_id_ctx, state->host_domain);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state->sdap_op = sdap_id_op_create(state, state->conn->conn_cache);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "sdap_id_op_connect_send failed: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_set_callback(subreq, ad_gpo_connect_done, req);
d3c6fca0f0d3b1c5d3dda3dcf3de0ae3ae4c0c38Yassir Elley const char *user,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "HBAC processing failed: [%d](%s}\n",
d3c6fca0f0d3b1c5d3dda3dcf3de0ae3ae4c0c38Yassir Elley /* we have successfully processed all offline gpos */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley const char *attrs[] = {AD_AT_DN, AD_AT_UAC, NULL};
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley req = tevent_req_callback_data(subreq, struct tevent_req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state = tevent_req_data(req, struct ad_gpo_access_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = sdap_id_op_connect_recv(subreq, &dp_error);
d3c6fca0f0d3b1c5d3dda3dcf3de0ae3ae4c0c38Yassir Elley "Failed to connect to AD server: [%d](%s)\n",
d3c6fca0f0d3b1c5d3dda3dcf3de0ae3ae4c0c38Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "Preparing for offline operation.\n");
d3c6fca0f0d3b1c5d3dda3dcf3de0ae3ae4c0c38Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "process_offline_gpos succeeded\n");
d3c6fca0f0d3b1c5d3dda3dcf3de0ae3ae4c0c38Yassir Elley "process_offline_gpos failed [%d](%s)\n",
ccff8e75940963a0f68f86efcddc37133318abfaJakub Hrozek /* extract server_hostname from server_uri */
ccff8e75940963a0f68f86efcddc37133318abfaJakub Hrozek "Failed to parse ldap URI (%s)!\n", server_uri);
ccff8e75940963a0f68f86efcddc37133318abfaJakub Hrozek "The LDAP URI (%s) did not contain a host name\n", server_uri);
ccff8e75940963a0f68f86efcddc37133318abfaJakub Hrozek state->server_hostname = talloc_strdup(state, lud->lud_host);
ccff8e75940963a0f68f86efcddc37133318abfaJakub Hrozek DEBUG(SSSDBG_TRACE_ALL, "server_hostname from uri: %s\n",
560b624b34895df55bf489a1d53380c6c8c82e03Sumit Bose /* SDAP_SASL_AUTHID contains the name used for kinit and SASL bind which
560b624b34895df55bf489a1d53380c6c8c82e03Sumit Bose * in the AD case is the NetBIOS name. */
560b624b34895df55bf489a1d53380c6c8c82e03Sumit Bose sam_account_name = dp_opt_get_string(state->opts->basic, SDAP_SASL_AUTHID);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "sam_account_name is %s\n", sam_account_name);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* Convert the domain name into domain DN */
475d986b534c5e0dfdb8e2348ab89b13fd4874aaStephen Gallagher ret = domain_to_basedn(state, state->host_domain->name, &domain_dn);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "Cannot convert domain name [%s] to base DN [%d]: %s\n",
475d986b534c5e0dfdb8e2348ab89b13fd4874aaStephen Gallagher state->host_domain->name, ret, sss_strerror(ret));
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* SDAP_OC_USER objectclass covers both users and computers */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "(&(objectclass=%s)(%s=%s))",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley subreq = sdap_get_generic_send(state, state->ev, state->opts,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_set_callback(subreq, ad_gpo_target_dn_retrieval_done, req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_target_dn_retrieval_done(struct tevent_req *subreq)
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley req = tevent_req_callback_data(subreq, struct tevent_req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state = tevent_req_data(req, struct ad_gpo_access_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = sdap_id_op_done(state->sdap_op, ret, &dp_error);
bdd533146cb2da71b7c39ad0efa2e5baca7257ebLukas Slebodnik if (ret == EAGAIN && dp_error == DP_ERR_OFFLINE) {
bdd533146cb2da71b7c39ad0efa2e5baca7257ebLukas Slebodnik DEBUG(SSSDBG_TRACE_FUNC, "Preparing for offline operation.\n");
bdd533146cb2da71b7c39ad0efa2e5baca7257ebLukas Slebodnik DEBUG(SSSDBG_TRACE_FUNC, "process_offline_gpos succeeded\n");
bdd533146cb2da71b7c39ad0efa2e5baca7257ebLukas Slebodnik "process_offline_gpos failed [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "Unable to get policy target's DN: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* make sure there is only one non-NULL reply returned */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "No DN retrieved for policy target.\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "Multiple replies for policy target\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "reply_count is 1, but reply is NULL\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* reply[0] holds requested attributes of single reply */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = sysdb_attrs_get_string(reply[0], AD_AT_DN, &target_dn);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "sysdb_attrs_get_string failed: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state->target_dn = talloc_steal(state, target_dn);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = sysdb_attrs_get_uint32_t(reply[0], AD_AT_UAC, &uac);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "sysdb_attrs_get_uint32_t failed: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* we only support computer policy targets, not users */
5c129880ae10c80b4f79cb2994e9d127dc6dfbefMathieu Deaudelin-Lemay if (!(uac & UAC_WORKSTATION_TRUST_ACCOUNT ||
de1131abe5ba7aaeb59f81fc3a9cd2a71c0b52ddLukas Slebodnik "Invalid userAccountControl (%x) value for machine account.\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_set_callback(subreq, ad_gpo_process_som_done, req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_process_som_done(struct tevent_req *subreq)
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley req = tevent_req_callback_data(subreq, struct tevent_req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state = tevent_req_data(req, struct ad_gpo_access_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = ad_gpo_process_som_recv(subreq, state, &som_list);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "Unable to get som list: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_set_callback(subreq, ad_gpo_process_gpo_done, req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This function retrieves a list of candidate_gpos and potentially reduces it
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * to a list of dacl_filtered_gpos, based on each GPO's DACL.
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * This function then takes the list of dacl_filtered_gpos and potentially
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * reduces it to a list of cse_filtered_gpos, based on whether each GPO's list
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * of cse_guids includes the "SecuritySettings" CSE GUID (used for HBAC).
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * Ultimately, this function then sends each cse_filtered_gpo to the gpo_child,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * which retrieves the GPT.INI and policy files (as needed). Once all files
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * have been downloaded, the ad_gpo_cse_done function performs HBAC processing.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_process_gpo_done(struct tevent_req *subreq)
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley req = tevent_req_callback_data(subreq, struct tevent_req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state = tevent_req_data(req, struct ad_gpo_access_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = ad_gpo_process_gpo_recv(subreq, state, &candidate_gpos,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = sdap_id_op_done(state->sdap_op, ret, &dp_error);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "Unable to get GPO list: [%d](%s)\n",
7c18b65dbdeb584a946c055f2db3814544b17232Stephen Gallagher "No GPOs found that apply to this system.\n");
7c18b65dbdeb584a946c055f2db3814544b17232Stephen Gallagher * Delete the result object list, since there are no
7c18b65dbdeb584a946c055f2db3814544b17232Stephen Gallagher * GPOs to include in it.
7c18b65dbdeb584a946c055f2db3814544b17232Stephen Gallagher ret = sysdb_gpo_delete_gpo_result_object(state, state->host_domain);
7c18b65dbdeb584a946c055f2db3814544b17232Stephen Gallagher DEBUG(SSSDBG_TRACE_FUNC, "No GPO Result available in cache\n");
7c18b65dbdeb584a946c055f2db3814544b17232Stephen Gallagher "Could not delete GPO Result from cache: [%s]\n",
475d986b534c5e0dfdb8e2348ab89b13fd4874aaStephen Gallagher ret = ad_gpo_filter_gpos_by_dacl(state, state->user, state->user_domain,
b1d34059533eb50f6e5a4ac7b6fa1bb6fa60a445Michal Židek "Unable to filter GPO list by DACL: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* since no applicable gpos were found, there is nothing to enforce */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "no applicable gpos found after dacl filtering\n");
7c18b65dbdeb584a946c055f2db3814544b17232Stephen Gallagher * Delete the result object list, since there are no
7c18b65dbdeb584a946c055f2db3814544b17232Stephen Gallagher * GPOs to include in it.
7c18b65dbdeb584a946c055f2db3814544b17232Stephen Gallagher ret = sysdb_gpo_delete_gpo_result_object(state, state->host_domain);
7c18b65dbdeb584a946c055f2db3814544b17232Stephen Gallagher DEBUG(SSSDBG_TRACE_FUNC, "No GPO Result available in cache\n");
7c18b65dbdeb584a946c055f2db3814544b17232Stephen Gallagher "Could not delete GPO Result from cache: [%s]\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley for (i = 0; i < state->num_dacl_filtered_gpos; i++) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "dacl_filtered_gpos[%d]->gpo_guid is %s\n", i,
19d3aba12c70528708be9440aca66038a291f29eYassir Elley "Unable to filter GPO list by CSE_GUID: [%d](%s)\n",
19d3aba12c70528708be9440aca66038a291f29eYassir Elley /* no gpos contain "SecuritySettings" cse_guid, nothing to enforce */
19d3aba12c70528708be9440aca66038a291f29eYassir Elley "no applicable gpos found after cse_guid filtering\n");
eb0cde4e6dfdbda08588860534f7ece5776ec3afYassir Elley /* we create and populate an array of applicable gpo-guids */
eb0cde4e6dfdbda08588860534f7ece5776ec3afYassir Elley talloc_array(state, const char *, state->num_cse_filtered_gpos);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley for (i = 0; i < state->num_cse_filtered_gpos; i++) {
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_TRACE_FUNC, "cse_filtered_gpos[%d]->gpo_guid is %s\n", i,
eb0cde4e6dfdbda08588860534f7ece5776ec3afYassir Elley cse_filtered_gpo_guids[i] = talloc_steal(cse_filtered_gpo_guids,
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_TRACE_FUNC, "num_cse_filtered_gpos: %d\n",
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * before we start processing each gpo, we delete the GPO Result object
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * from the sysdb cache so that any previous policy settings are cleared;
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * subsequent functions will add the GPO Result object (and populate it
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * with resultant policy settings) for this policy application
475d986b534c5e0dfdb8e2348ab89b13fd4874aaStephen Gallagher ret = sysdb_gpo_delete_gpo_result_object(state, state->host_domain);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "No GPO Result available in cache\n");
4611802d41d8954a3040f39403590adb920ca521Yassir Elley "Could not delete GPO Result from cache: [%s]\n",
19d3aba12c70528708be9440aca66038a291f29eYassir Elley state = tevent_req_data(req, struct ad_gpo_access_state);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley state->cse_filtered_gpos[state->cse_gpo_index];
4611802d41d8954a3040f39403590adb920ca521Yassir Elley /* cse_filtered_gpo is NULL after all GPO policy files have been downloaded */
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_TRACE_FUNC, "cse filtered_gpos[%d]->gpo_guid is %s\n",
19d3aba12c70528708be9440aca66038a291f29eYassir Elley state->cse_gpo_index, cse_filtered_gpo->gpo_guid);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley for (i = 0; i < cse_filtered_gpo->num_gpo_cse_guids; i++) {
19d3aba12c70528708be9440aca66038a291f29eYassir Elley "cse_filtered_gpos[%d]->gpo_cse_guids[%d]->gpo_guid is %s\n",
19d3aba12c70528708be9440aca66038a291f29eYassir Elley state->cse_gpo_index, i, cse_filtered_gpo->gpo_cse_guids[i]);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley DEBUG(SSSDBG_TRACE_FUNC, "smb_server: %s\n", cse_filtered_gpo->smb_server);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley DEBUG(SSSDBG_TRACE_FUNC, "smb_share: %s\n", cse_filtered_gpo->smb_share);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley DEBUG(SSSDBG_TRACE_FUNC, "smb_path: %s\n", cse_filtered_gpo->smb_path);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley DEBUG(SSSDBG_TRACE_FUNC, "gpo_guid: %s\n", cse_filtered_gpo->gpo_guid);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley if (cse_filtered_gpo->policy_filename == NULL) {
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley /* retrieve gpo cache entry; set cached_gpt_version to -1 if unavailable */
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "retrieving GPO from cache [%s]\n",
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley * Note: if the timeout is valid, then we can later avoid downloading
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley * the GPT.INI file, as well as any policy files (i.e. we don't need
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley * to interact with the gpo_child at all). However, even if the timeout
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley * is not valid, while we will have to interact with the gpo child to
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley * download the GPT.INI file, we may still be able to avoid downloading
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley * the policy files (if the cached_gpt_version is the same as the
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley * GPT.INI version). In other words, the timeout is *not* an expiration
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley * for the entire cache entry; the cached_gpt_version never expires.
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley cached_gpt_version = ldb_msg_find_attr_as_int(res->msgs[0],
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley policy_file_timeout = ldb_msg_find_attr_as_uint64
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley DEBUG(SSSDBG_FATAL_FAILURE, "Could not read GPO from cache: [%s]\n",
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "send_to_child: %d\n", send_to_child);
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "cached_gpt_version: %d\n", cached_gpt_version);
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley cse_filtered_gpo->send_to_child = send_to_child;
19d3aba12c70528708be9440aca66038a291f29eYassir Elley tevent_req_set_callback(subreq, ad_gpo_cse_done, req);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * This cse-specific function (GP_EXT_GUID_SECURITY) increments the
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * cse_gpo_index until the policy settings for all applicable GPOs have been
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * stored as part of the GPO Result object in the sysdb cache. Once all
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * GPOs have been processed, this functions performs HBAC processing by
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * comparing the resultant policy setting values in the GPO Result object
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * with the user_sid/group_sids of interest.
19d3aba12c70528708be9440aca66038a291f29eYassir Elley req = tevent_req_callback_data(subreq, struct tevent_req);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley state = tevent_req_data(req, struct ad_gpo_access_state);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley state->cse_filtered_gpos[state->cse_gpo_index];
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley const char *gpo_guid = cse_filtered_gpo->gpo_guid;
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley DEBUG(SSSDBG_TRACE_FUNC, "gpo_guid: %s\n", gpo_guid);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve policy data: [%d](%s}\n",
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * now that the policy file for this gpo have been downloaded to the
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * GPO CACHE, we store all of the supported keys present in the file
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * (as part of the GPO Result object in the sysdb cache).
475d986b534c5e0dfdb8e2348ab89b13fd4874aaStephen Gallagher ret = ad_gpo_store_policy_settings(state->host_domain,
818c55be478ca2539a86567280114e823d79a51fLukas Slebodnik "ad_gpo_store_policy_settings failed: [%d](%s)\n",
4611802d41d8954a3040f39403590adb920ca521Yassir Elley /* ret is EOK only after all GPO policy files have been downloaded */
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "HBAC processing failed: [%d](%s}\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley/* == ad_gpo_process_som_send/recv helpers ================================= */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This function returns the parent of an LDAP DN
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley const char *dn,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley const char *p;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley parent_ldb_dn = ldb_dn_get_parent(tmp_ctx, ldb_dn);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This function populates the _som_list output parameter by parsing the input
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * DN into a list of gp_som objects. This function essentially repeatedly
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * appends the input DN's parent to the SOM List (if the parent starts with
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * "OU=" or "DC="), until the first "DC=" component is reached.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * Example: if input DN is "CN=MyComputer,CN=Computers,OU=Sales,DC=FOO,DC=COM",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * then SOM List has 2 SOM entries: {[OU=Sales,DC=FOO,DC=COM], [DC=FOO, DC=COM]}
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ldb_target_dn = ldb_dn_new(tmp_ctx, ldb_ctx, target_dn);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley rdn_count = ldb_dn_get_comp_num(ldb_target_dn);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* assume the worst-case, in which every parent is a SOM */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* include space for Site SOM and NULL: rdn_count + 1 + 1 */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley som_list = talloc_array(tmp_ctx, struct gp_som *, rdn_count + 1 + 1);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* first, populate the OU and Domain SOMs */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley while ((ad_gpo_parent_dn(tmp_ctx, ldb_ctx, tmp_dn, &parent_dn)) == EOK) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if ((strncasecmp(parent_dn, "OU=", strlen("OU=")) == 0) ||
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley (strncasecmp(parent_dn, "DC=", strlen("DC=")) == 0)) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley som_list[som_idx] = talloc_zero(som_list, struct gp_som);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley som_list[som_idx]->som_dn = talloc_steal(som_list[som_idx],
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (strncasecmp(parent_dn, "DC=", strlen("DC=")) == 0) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This function populates the _gplink_list output parameter by parsing the
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * input raw_gplink_value into an array of gp_gplink objects, each consisting of
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * a GPO DN and bool enforced field.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * The raw_gplink_value is single string consisting of multiple gplink strings.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * The raw_gplink_value is in the following format:
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * "[GPO_DN_1;GPLinkOptions_1]...[GPO_DN_n;GPLinkOptions_n]"
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * Each gplink string consists of a GPO DN and a GPLinkOptions field (which
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * indicates whether its associated GPO DN is ignored, unenforced, or enforced).
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * If a GPO DN is flagged as ignored, it is discarded and will not be added to
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * the _gplink_list. If the allow_enforced_only input is true, AND a GPO DN is
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * flagged as unenforced, it will also be discarded.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * Example: if raw_gplink_value="[OU=Sales,DC=FOO,DC=COM;0][DC=FOO,DC=COM;2]"
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * and allow_enforced_only=FALSE, then the output would consist of following:
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * _gplink_list[0]: {GPO DN: "OU=Sales,DC=FOO,DC=COM", enforced: FALSE}
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * _gplink_list[1]: {GPO DN: "DC=FOO,DC=COM", enforced: TRUE}
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_populate_gplink_list(TALLOC_CTX *mem_ctx,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "som_dn: %s\n", som_dn);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley gplink_list = talloc_array(tmp_ctx, struct gp_gplink *, gplink_count + 1);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley for (i = 0; i < gplink_count; i++) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley gplink_number = strtouint32(gplink_options, NULL, 10);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "strtouint32 failed: [%d](%s)\n", ret, sss_strerror(ret));
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "gplink_list[%d]: [%s; %d]\n", num_enabled, dn, gplink_number);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if ((gplink_number == 1) || (gplink_number ==3)) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* ignore flag is set */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "ignored gpo skipped\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (allow_enforced_only && (gplink_number == 0)) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* unenforced flag is set; only enforced gpos allowed */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "unenforced gpo skipped\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley gplink_list[num_enabled] = talloc_zero(gplink_list, struct gp_gplink);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (gplink_list[num_enabled]->gpo_dn == NULL) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley *_gplink_list = talloc_steal(mem_ctx, gplink_list);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley/* == ad_gpo_process_som_send/recv implementation ========================== */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic void ad_gpo_site_name_retrieval_done(struct tevent_req *subreq);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic void ad_gpo_site_dn_retrieval_done(struct tevent_req *subreq);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic errno_t ad_gpo_get_som_attrs_step(struct tevent_req *req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic void ad_gpo_get_som_attrs_done(struct tevent_req *subreq);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This function uses the input target_dn and input domain_name to populate
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * a list of gp_som objects. Each object in this list represents a SOM
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * associated with the target (such as OU, Domain, and Site).
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * The inputs are used to determine the DNs of each SOM associated with the
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * target. In turn, the SOM object DNs are used to retrieve certain LDAP
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * attributes of each SOM object, that are parsed into an array of gp_gplink
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * objects, essentially representing the GPOs that have been linked to each
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * SOM object. Note that it is perfectly valid for there to be *no* GPOs
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * linked to a SOM object.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley req = tevent_req_create(mem_ctx, &state, struct ad_gpo_process_som_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = ad_gpo_populate_som_list(state, ldb_ctx, target_dn,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "Unable to retrieve SOM List : [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "target dn must have at least one parent\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley subreq = ad_master_domain_send(state, state->ev, conn,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "ad_master_domain_send failed.\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_set_callback(subreq, ad_gpo_site_name_retrieval_done, req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_site_name_retrieval_done(struct tevent_req *subreq)
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley req = tevent_req_callback_data(subreq, struct tevent_req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state = tevent_req_data(req, struct ad_gpo_process_som_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* gpo code only cares about the site name */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = ad_master_domain_recv(subreq, state, NULL, NULL, &site, NULL);
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek "Could not autodiscover AD site. This is not fatal if "
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek "ad_site option was set.\n");
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek site_override = dp_opt_get_string(state->ad_options, AD_SITE);
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek "Overriding autodiscovered AD site value '%s' with '%s' from "
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek "configuration.\n", site ? site : "none", site_override);
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek "Could not autodiscover AD site value using DNS and ad_site "
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek "option was not set in configuration. GPO will not work. "
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek "To work around this issue you can use ad_site option in SSSD "
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek "configuration.");
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek "Could not autodiscover AD site value using DNS and ad_site "
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek "option was not set in configuration. GPO will not work. "
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek "To work around this issue you can use ad_site option in SSSD "
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek "configuration.\n");
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek state->site_name = talloc_asprintf(state, "cn=%s",
744e2b4d0710c1dc850bfadbd75ae1ae7faf1148Michal Židek DEBUG(SSSDBG_TRACE_FUNC, "Using AD site '%s'.\n", state->site_name);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * note: the configNC attribute is being retrieved here from the rootDSE
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * entry. In future, since we already make an LDAP query for the rootDSE
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * entry when LDAP connection is made, this attribute should really be
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * retrieved at that point (see https://fedorahosted.org/sssd/ticket/2276)
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley subreq = sdap_get_generic_send(state, state->ev, state->opts,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_set_callback(subreq, ad_gpo_site_dn_retrieval_done, req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_site_dn_retrieval_done(struct tevent_req *subreq)
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley req = tevent_req_callback_data(subreq, struct tevent_req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state = tevent_req_data(req, struct ad_gpo_process_som_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = sdap_id_op_done(state->sdap_op, ret, &dp_error);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "Unable to get configNC: [%d](%s)\n", ret, sss_strerror(ret));
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* make sure there is only one non-NULL reply returned */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "No configNC retrieved\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "Multiple replies for configNC\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "reply_count is 1, but reply is NULL\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* reply[0] holds requested attributes of single reply */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = sysdb_attrs_get_string(reply[0], AD_AT_CONFIG_NC, &configNC);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "sysdb_attrs_get_string failed: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley talloc_asprintf(state, "%s,cn=Sites,%s", state->site_name, configNC);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* note that space was allocated for site_dn when allocating som_list */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (state->som_list[state->num_soms] == NULL) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley talloc_steal(state->som_list[state->num_soms], state->site_dn);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (state->som_list[state->num_soms]->som_dn == NULL) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "som_list[%d]->som_dn is %s\n", i,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_get_som_attrs_step(struct tevent_req *req)
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley const char *attrs[] = {AD_AT_GPLINK, AD_AT_GPOPTIONS, NULL};
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state = tevent_req_data(req, struct ad_gpo_process_som_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley struct gp_som *gp_som = state->som_list[state->som_index];
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* gp_som is NULL only after all SOMs have been processed */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley subreq = sdap_get_generic_send(state, state->ev, state->opts,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_set_callback(subreq, ad_gpo_get_som_attrs_done, req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_get_som_attrs_done(struct tevent_req *subreq)
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley req = tevent_req_callback_data(subreq, struct tevent_req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state = tevent_req_data(req, struct ad_gpo_process_som_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = sdap_id_op_done(state->sdap_op, ret, &dp_error);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "Unable to get SOM attributes: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "no attrs found for SOM; try next SOM.\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "Received multiple replies\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* Get the gplink value, if available */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = sysdb_attrs_get_el(results[0], AD_AT_GPLINK, &el);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "sysdb_attrs_get_el() failed: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if ((ret == ENOENT) || (el->num_values == 0)) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "no attrs found for SOM; try next SOM\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = sysdb_attrs_get_el(results[0], AD_AT_GPOPTIONS, &el);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el() failed\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if ((ret == ENOENT) || (el->num_values == 0)) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "gpoptions attr not found or has no value; defaults to 0\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley allow_enforced_only = strtouint32((char *)raw_gpoptions_value, NULL, 10);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "strtouint32 failed: [%d](%s)\n", ret, sss_strerror(ret));
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "ad_gpo_populate_gplink_list() failed\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_data(req, struct ad_gpo_process_som_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley *som_list = talloc_steal(mem_ctx, state->som_list);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley/* == ad_gpo_process_gpo_send/recv helpers ================================= */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This function examines the gp_gplink objects in each gp_som object specified
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * in the input som_list, and populates the _candidate_gpos output parameter's
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * gpo_dn fields with prioritized list of GPO DNs. Prioritization ensures that:
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * - GPOs linked to an OU will be applied after GPOs linked to a Domain,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * which will be applied after GPOs linked to a Site.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * - multiple GPOs linked to a single SOM are applied in their link order
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * (i.e. 1st GPO linked to SOM is applied after 2nd GPO linked to SOM, etc).
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * - enforced GPOs are applied after unenforced GPOs.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * As such, the _candidate_gpos output's dn fields looks like (in link order):
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * [unenforced {Site, Domain, OU}; enforced {Site, Domain, OU}]
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * Note that in the case of conflicting policy settings, GPOs appearing later
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * in the list will trump GPOs appearing earlier in the list.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_populate_candidate_gpos(TALLOC_CTX *mem_ctx,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley while (gp_som && gp_som->gplink_list && gp_som->gplink_list[j]) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "unexpected null gp_gplink\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley num_candidate_gpos = num_enforced + num_unenforced;
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley enforced_gpo_dns = talloc_array(tmp_ctx, const char *, num_enforced + 1);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley unenforced_gpo_dns = talloc_array(tmp_ctx, const char *, num_unenforced + 1);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley while (gp_som && gp_som->gplink_list && gp_som->gplink_list[j]) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "unexpected null gp_gplink\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley talloc_steal(enforced_gpo_dns, gp_gplink->gpo_dn);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley talloc_steal(unenforced_gpo_dns, gp_gplink->gpo_dn);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (unenforced_gpo_dns[unenforced_idx] == NULL) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley candidate_gpos[gpo_dn_idx] = talloc_zero(candidate_gpos, struct gp_gpo);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley talloc_steal(candidate_gpos[gpo_dn_idx], unenforced_gpo_dns[i]);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (candidate_gpos[gpo_dn_idx]->gpo_dn == NULL) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "candidate_gpos[%d]->gpo_dn: %s\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley gpo_dn_idx, candidate_gpos[gpo_dn_idx]->gpo_dn);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley for (i = 0; i < num_enforced; i++) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley candidate_gpos[gpo_dn_idx] = talloc_zero(candidate_gpos, struct gp_gpo);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley talloc_steal(candidate_gpos[gpo_dn_idx], enforced_gpo_dns[i]);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if (candidate_gpos[gpo_dn_idx]->gpo_dn == NULL) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "candidate_gpos[%d]->gpo_dn: %s\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley gpo_dn_idx, candidate_gpos[gpo_dn_idx]->gpo_dn);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley *_candidate_gpos = talloc_steal(mem_ctx, candidate_gpos);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley * This function parses the input_path into its components, replaces each
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley * back slash ('\') with a forward slash ('/'), and populates the output params.
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley * The smb_server output is constructed by concatenating the following elements:
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * - SMB_STANDARD_URI ("smb://")
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * - server_hostname (which replaces domain_name in input path)
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley * The smb_share and smb_path outputs are extracted from the input_path.
19d3aba12c70528708be9440aca66038a291f29eYassir Elley * Example: if input_path = "\\foo.com\SysVol\foo.com\..." and
32381402a4a9afc003782c9e2301fc59c9bda2a9Yassir Elley * server_hostname = "adserver.foo.com", then
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley * _smb_server = "smb://adserver.foo.com"
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley * _smb_share = "SysVol"
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley * _smb_path = "/foo.com/..."
32381402a4a9afc003782c9e2301fc59c9bda2a9Yassir Elley * Note that the input_path must have at least four forward slash separators.
32381402a4a9afc003782c9e2301fc59c9bda2a9Yassir Elley * For example, input_path = "\\foo.com\SysVol" is not a valid input_path,
32381402a4a9afc003782c9e2301fc59c9bda2a9Yassir Elley * because it has only three forward slash separators.
b47449d8596d9573ff13e74b6984d080b414715aYassir Elleyad_gpo_extract_smb_components(TALLOC_CTX *mem_ctx,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "input_path: %s\n", input_path);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley /* replace the slash before the share name with null string */
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley /* replace the slash after the share name with null string */
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley *_smb_server = talloc_asprintf(mem_ctx, "%s%s",
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley *_smb_share = talloc_asprintf(mem_ctx, "/%s", smb_share);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley *_smb_path = talloc_asprintf(mem_ctx, "/%s", smb_path);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This function populates the _cse_guid_list output parameter by parsing the
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * input raw_machine_ext_names_value into an array of cse_guid strings.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * The raw_machine_ext_names_value is a single string in the following format:
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * "[{cse_guid_1}{tool_guid1}]...[{cse_guid_n}{tool_guid_n}]"
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_parse_machine_ext_names(TALLOC_CTX *mem_ctx,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley gpo_cse_guids = talloc_array(tmp_ctx, const char *, num_gpo_cse_guids + 1);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley for (i = 0; i < num_gpo_cse_guids; i++) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley gpo_cse_guids[i] = talloc_strdup(gpo_cse_guids, cse_guid);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "num_gpo_cse_guids: %d\n", num_gpo_cse_guids);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley for (i = 0; i < num_gpo_cse_guids; i++) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "gpo_cse_guids[%d] is %s\n", i, gpo_cse_guids[i]);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley *_gpo_cse_guids = talloc_steal(mem_ctx, gpo_cse_guids);
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elleyad_gpo_ndr_pull_security_descriptor(struct ndr_pull *ndr, int ndr_flags,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This function parses the input data blob and assigns the resulting
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * security_descriptor object to the _gpo_sd output parameter.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic errno_t ad_gpo_parse_sd(TALLOC_CTX *mem_ctx,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "ndr_pull_init_blob() failed.\n");
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley ndr_err = ad_gpo_ndr_pull_security_descriptor(ndr_pull,
28c155e20d3ebf53581821572c6c3fe1724582c9Yassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "Failed to pull security descriptor\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley *_gpo_sd = talloc_memdup(mem_ctx, &sd, sizeof(struct security_descriptor));
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley/* == ad_gpo_process_gpo_send/recv implementation ========================== */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic errno_t ad_gpo_get_gpo_attrs_step(struct tevent_req *req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleystatic void ad_gpo_get_gpo_attrs_done(struct tevent_req *subreq);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * This function uses the input som_list to populate a prioritized list of
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * gp_gpo objects, prioritized based on SOM type, link order, and whether the
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * GPO is "enforced". This list represents the initial set of candidate GPOs
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * that might be applicable to the target. This list can not be expanded, but
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * it might be reduced based on subsequent filtering steps. The GPO object DNs
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * are used to retrieve certain LDAP attributes of each GPO object, that are
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley * parsed into the various fields of the gp_gpo object.
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley req = tevent_req_create(mem_ctx, &state, struct ad_gpo_process_gpo_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "Unable to retrieve GPO List: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_get_gpo_attrs_step(struct tevent_req *req)
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state = tevent_req_data(req, struct ad_gpo_process_gpo_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley struct gp_gpo *gp_gpo = state->candidate_gpos[state->gpo_index];
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* gp_gpo is NULL only after all GPOs have been processed */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state->opts, sdap_id_op_handle(state->sdap_op),
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "sdap_sd_search_send failed.\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_set_callback(subreq, ad_gpo_get_gpo_attrs_done, req);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagherad_gpo_sd_process_attrs(struct tevent_req *req,
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagherad_gpo_get_sd_referral_done(struct tevent_req *subreq);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagherad_gpo_get_sd_referral_send(TALLOC_CTX *mem_ctx,
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagherad_gpo_get_sd_referral_recv(struct tevent_req *req,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elleyad_gpo_get_gpo_attrs_done(struct tevent_req *subreq)
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley req = tevent_req_callback_data(subreq, struct tevent_req);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley state = tevent_req_data(req, struct ad_gpo_process_gpo_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = sdap_id_op_done(state->sdap_op, ret, &dp_error);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "Unable to get GPO attributes: [%d](%s)\n",
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher /* If we were redirected to a referral, process it.
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher * There must be a single referral result here; if we get
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher * more than one (or zero) it's a bug.
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher subreq = ad_gpo_get_sd_referral_send(state, state->ev,
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher tevent_req_set_callback(subreq, ad_gpo_get_sd_referral_done, req);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher const char *gpo_dn = state->candidate_gpos[state->gpo_index]->gpo_dn;
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "Received multiple replies\n");
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher ret = ad_gpo_sd_process_attrs(req, state->server_hostname, results[0]);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagherad_gpo_get_sd_referral_done(struct tevent_req *subreq)
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher tevent_req_callback_data(subreq, struct tevent_req);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher tevent_req_data(req, struct ad_gpo_process_gpo_state);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher ret = ad_gpo_get_sd_referral_recv(subreq, state, &smb_host, &reply);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher /* Terminate the sdap_id_op */
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher ret = sdap_id_op_done(state->sdap_op, ret, &dp_error);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher "Unable to get referred GPO attributes: [%d](%s)\n",
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher /* Lookup succeeded. Process it */
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher ret = ad_gpo_sd_process_attrs(req, smb_host, reply);
b1a8b4a1291529367b46c79eb02448eced3bf8d2Michal Židekstatic bool machine_ext_names_is_blank(char *attr_value)
b1a8b4a1291529367b46c79eb02448eced3bf8d2Michal Židek return true;
b1a8b4a1291529367b46c79eb02448eced3bf8d2Michal Židek return false;
b1a8b4a1291529367b46c79eb02448eced3bf8d2Michal Židek return true;
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagherad_gpo_sd_process_attrs(struct tevent_req *req,
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher state = tevent_req_data(req, struct ad_gpo_process_gpo_state);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher gp_gpo = state->candidate_gpos[state->gpo_index];
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* retrieve AD_AT_CN */
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher ret = sysdb_attrs_get_string(result, AD_AT_CN, &gpo_guid);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "sysdb_attrs_get_string failed: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley gp_gpo->gpo_guid = talloc_steal(gp_gpo, gpo_guid);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "populating attrs for gpo_guid: %s\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* retrieve AD_AT_FILE_SYS_PATH */
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "sysdb_attrs_get_string failed: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley file_sys_path = talloc_strdup(gp_gpo, raw_file_sys_path);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher ret = ad_gpo_extract_smb_components(gp_gpo, smb_host,
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley "unable to extract smb components from file_sys_path: [%d](%s)\n",
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley DEBUG(SSSDBG_TRACE_ALL, "smb_server: %s\n", gp_gpo->smb_server);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley DEBUG(SSSDBG_TRACE_ALL, "smb_share: %s\n", gp_gpo->smb_share);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley DEBUG(SSSDBG_TRACE_ALL, "smb_path: %s\n", gp_gpo->smb_path);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* retrieve AD_AT_FUNC_VERSION */
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher ret = sysdb_attrs_get_int32_t(result, AD_AT_FUNC_VERSION,
a02a5ed51178b2cbede0396d66aed716b8898096René Genz /* If this attribute is missing we can skip the GPO. It will
6a490b312075d2588ad87bbb8a63466f1ac6a106Michal Židek * be filtered out according to MS-GPOL:
6a490b312075d2588ad87bbb8a63466f1ac6a106Michal Židek * https://msdn.microsoft.com/en-us/library/cc232538.aspx */
6a490b312075d2588ad87bbb8a63466f1ac6a106Michal Židek DEBUG(SSSDBG_TRACE_ALL, "GPO with GUID %s is missing attribute "
6a490b312075d2588ad87bbb8a63466f1ac6a106Michal Židek AD_AT_FUNC_VERSION " and will be skipped.\n", gp_gpo->gpo_guid);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "sysdb_attrs_get_int32_t failed: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "gpo_func_version: %d\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* retrieve AD_AT_FLAGS */
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher ret = sysdb_attrs_get_int32_t(result, AD_AT_FLAGS,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "sysdb_attrs_get_int32_t failed: [%d](%s)\n",
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_TRACE_ALL, "gpo_flags: %d\n", gp_gpo->gpo_flags);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley /* retrieve AD_AT_NT_SEC_DESC */
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher ret = sysdb_attrs_get_el(result, AD_AT_NT_SEC_DESC, &el);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el() failed\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley if ((ret == ENOENT) || (el->num_values == 0)) {
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley "nt_sec_desc attribute not found or has no value\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley ret = ad_gpo_parse_sd(gp_gpo, el[0].values[0].data, el[0].values[0].length,
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "ad_gpo_parse_sd() failed\n");
4611802d41d8954a3040f39403590adb920ca521Yassir Elley /* retrieve AD_AT_MACHINE_EXT_NAMES */
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher ret = sysdb_attrs_get_el(result, AD_AT_MACHINE_EXT_NAMES, &el);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el() failed\n");
b1a8b4a1291529367b46c79eb02448eced3bf8d2Michal Židek || machine_ext_names_is_blank((char *) el[0].values[0].data)) {
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * if gpo has no machine_ext_names (which is perfectly valid: it could
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * have only user_ext_names, for example), we continue to next gpo
4611802d41d8954a3040f39403590adb920ca521Yassir Elley "machine_ext_names attribute not found or has no value\n");
4611802d41d8954a3040f39403590adb920ca521Yassir Elley "ad_gpo_parse_machine_ext_names() failed\n");
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley tevent_req_data(req, struct ad_gpo_process_gpo_state);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley *candidate_gpos = talloc_steal(mem_ctx, state->candidate_gpos);
60cab26b12df9a2153823972cde0c38ca86e01b9Yassir Elley *num_candidate_gpos = state->num_candidate_gpos;
19d3aba12c70528708be9440aca66038a291f29eYassir Elley/* == ad_gpo_process_cse_send/recv helpers ================================= */
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley smb_cse_suffix_length = strlen(smb_cse_suffix);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n");
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley buf->size += smb_server_length + smb_share_length + smb_path_length +
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_TRACE_ALL, "buffer size: %zu\n", buf->size);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n");
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley /* cached_gpt_version */
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley SAFEALIGN_SET_UINT32(&buf->data[rp], cached_gpt_version, &rp);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley /* smb_server */
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley SAFEALIGN_SET_UINT32(&buf->data[rp], smb_server_length, &rp);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley safealign_memcpy(&buf->data[rp], smb_server, smb_server_length, &rp);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley /* smb_share */
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley SAFEALIGN_SET_UINT32(&buf->data[rp], smb_share_length, &rp);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley safealign_memcpy(&buf->data[rp], smb_share, smb_share_length, &rp);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley /* smb_path */
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley SAFEALIGN_SET_UINT32(&buf->data[rp], smb_path_length, &rp);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley safealign_memcpy(&buf->data[rp], smb_path, smb_path_length, &rp);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley /* smb_cse_suffix */
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley SAFEALIGN_SET_UINT32(&buf->data[rp], smb_cse_suffix_length, &rp);
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley safealign_memcpy(&buf->data[rp], smb_cse_suffix, smb_cse_suffix_length, &rp);
0bed97f6ca4ad8bb61de9114c23051e7eaa8d1fcLukas Slebodnikad_gpo_parse_gpo_child_response(uint8_t *buf,
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley /* sysvol_gpt_version */
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley SAFEALIGN_COPY_UINT32_CHECK(&sysvol_gpt_version, buf + p, size, &p);
32381402a4a9afc003782c9e2301fc59c9bda2a9Yassir Elley /* operation result code */
32381402a4a9afc003782c9e2301fc59c9bda2a9Yassir Elley SAFEALIGN_COPY_UINT32_CHECK(&result, buf + p, size, &p);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley/* == ad_gpo_process_cse_send/recv implementation ========================== */
19d3aba12c70528708be9440aca66038a291f29eYassir Elleystatic errno_t gpo_fork_child(struct tevent_req *req);
19d3aba12c70528708be9440aca66038a291f29eYassir Elleystatic void gpo_cse_step(struct tevent_req *subreq);
19d3aba12c70528708be9440aca66038a291f29eYassir Elleystatic void gpo_cse_done(struct tevent_req *subreq);
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * This cse-specific function (GP_EXT_GUID_SECURITY) sends the input smb uri
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * components and cached_gpt_version to the gpo child, which, in turn,
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * will download the GPT.INI file and policy files (as needed) and store
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * them in the GPO_CACHE directory. Note that if the send_to_child input is
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * false, this function simply completes the request.
19d3aba12c70528708be9440aca66038a291f29eYassir Elley req = tevent_req_create(mem_ctx, &state, struct ad_gpo_process_cse_state);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * if we don't need to talk to child (b/c cache timeout is still valid),
4611802d41d8954a3040f39403590adb920ca521Yassir Elley * we simply complete the request
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley state->gpo_timeout_option = gpo_timeout_option;
06f10b2a0ebb26f2460cd445f8040e9205de7500Jakub Hrozek state->io = talloc(state, struct child_io_fds);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n");
06f10b2a0ebb26f2460cd445f8040e9205de7500Jakub Hrozek talloc_set_destructor((void *) state->io, child_io_destructor);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley /* prepare the data to pass to child */
b47449d8596d9573ff13e74b6984d080b414715aYassir Elley ret = create_cse_send_buffer(state, smb_server, smb_share, smb_path,
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "create_cse_send_buffer failed.\n");
19d3aba12c70528708be9440aca66038a291f29eYassir Elley DEBUG(SSSDBG_CRIT_FAILURE, "gpo_fork_child failed.\n");
19d3aba12c70528708be9440aca66038a291f29eYassir Elley subreq = write_pipe_send(state, ev, buf->data, buf->size,
19d3aba12c70528708be9440aca66038a291f29eYassir Elley tevent_req_set_callback(subreq, gpo_cse_step, req);
19d3aba12c70528708be9440aca66038a291f29eYassir Elleystatic void gpo_cse_step(struct tevent_req *subreq)
19d3aba12c70528708be9440aca66038a291f29eYassir Elley req = tevent_req_callback_data(subreq, struct tevent_req);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley state = tevent_req_data(req, struct ad_gpo_process_cse_state);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley subreq = read_pipe_send(state, state->ev, state->io->read_from_child_fd);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley tevent_req_set_callback(subreq, gpo_cse_done, req);
19d3aba12c70528708be9440aca66038a291f29eYassir Elleystatic void gpo_cse_done(struct tevent_req *subreq)
19d3aba12c70528708be9440aca66038a291f29eYassir Elley req = tevent_req_callback_data(subreq, struct tevent_req);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley state = tevent_req_data(req, struct ad_gpo_process_cse_state);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley ret = read_pipe_recv(subreq, state, &state->buf, &state->len);
0bed97f6ca4ad8bb61de9114c23051e7eaa8d1fcLukas Slebodnik ret = ad_gpo_parse_gpo_child_response(state->buf, state->len,
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley "ad_gpo_parse_gpo_child_response failed: [%d][%s]\n",
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley } else if (child_result != 0){
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley "Error in gpo_child: [%d][%s]\n",
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley DEBUG(SSSDBG_TRACE_FUNC, "sysvol_gpt_version: %d\n", sysvol_gpt_version);
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley ret = sysdb_gpo_store_gpo(state->domain, state->gpo_guid, sysvol_gpt_version,
ff4b603cc14ea6ea15caaf89a03e927920124af4Yassir Elley DEBUG(SSSDBG_OP_FAILURE, "Unable to store gpo cache entry: [%d](%s}\n",
0bed97f6ca4ad8bb61de9114c23051e7eaa8d1fcLukas Slebodnikint ad_gpo_process_cse_recv(struct tevent_req *req)
19d3aba12c70528708be9440aca66038a291f29eYassir Elley state = tevent_req_data(req, struct ad_gpo_process_cse_state);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley "pipe failed [%d][%s].\n", errno, strerror(errno));
19d3aba12c70528708be9440aca66038a291f29eYassir Elley "pipe failed [%d][%s].\n", errno, strerror(errno));
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek /* We should never get here */
de8815aba87d08b6b7ac5d502dcb1755787e0857Jakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Could not exec gpo_child:\n");
19d3aba12c70528708be9440aca66038a291f29eYassir Elley state->io->read_from_child_fd = pipefd_from_child[0];
19d3aba12c70528708be9440aca66038a291f29eYassir Elley state->io->write_to_child_fd = pipefd_to_child[1];
f3d91181d4ee9da3f8bbf4ddf8782951c0ae46c1Jakub Hrozek sss_fd_nonblocking(state->io->read_from_child_fd);
f3d91181d4ee9da3f8bbf4ddf8782951c0ae46c1Jakub Hrozek sss_fd_nonblocking(state->io->write_to_child_fd);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley ret = child_handler_setup(state->ev, pid, NULL, NULL, NULL);
19d3aba12c70528708be9440aca66038a291f29eYassir Elley "Could not set up child signal handler\n");
19d3aba12c70528708be9440aca66038a291f29eYassir Elley } else { /* error */
19d3aba12c70528708be9440aca66038a291f29eYassir Elley "fork failed [%d][%s].\n", errno, strerror(errno));
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagherad_gpo_get_sd_referral_conn_done(struct tevent_req *subreq);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagherad_gpo_get_sd_referral_send(TALLOC_CTX *mem_ctx,
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher struct ad_gpo_get_sd_referral_state *state;
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher /* Parse the URL for the domain */
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher "Failed to parse referral URI (%s)!\n", referral);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher state->gpo_dn = talloc_strdup(state, lud->lud_dn);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher "Could not copy referral DN (%s)!\n", lud->lud_dn);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher /* Active Directory returns the domain name as the hostname
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher * in these referrals, so we can use that to look up the
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher * necessary connection.
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher state->ref_domain = find_domain_by_name(state->host_domain,
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher "Could not find domain matching [%s]\n",
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher state->conn = ad_get_dom_ldap_conn(state->access_ctx->ad_id_ctx,
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher "No connection for %s\n", state->ref_domain->name);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher /* Get the hostname we're going to connect to.
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher * We'll need this later for performing the samba
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher ret = ldap_url_parse(state->conn->service->uri, &lud);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher "Failed to parse service URI (%s)!\n", referral);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher state->smb_host = talloc_strdup(state, lud->lud_host);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher /* Start an ID operation for the referral */
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher state->ref_op = sdap_id_op_create(state, state->conn->conn_cache);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n");
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher /* Establish the sdap_id_op connection */
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher subreq = sdap_id_op_connect_send(state->ref_op, state, &ret);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d(%s).\n",
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher tevent_req_set_callback(subreq, ad_gpo_get_sd_referral_conn_done, req);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagherad_gpo_get_sd_referral_search_done(struct tevent_req *subreq);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagherad_gpo_get_sd_referral_conn_done(struct tevent_req *subreq)
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher tevent_req_callback_data(subreq, struct tevent_req);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher struct ad_gpo_get_sd_referral_state *state =
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher tevent_req_data(req, struct ad_gpo_get_sd_referral_state);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher ret = sdap_id_op_connect_recv(subreq, &dp_error);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher "Backend is marked offline, retry later!\n");
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher "Cross-realm GPO processing failed to connect to " \
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher "referred LDAP server: (%d)[%s]\n",
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher /* Request the referred GPO data */
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher subreq = sdap_sd_search_send(state, state->ev, state->opts,
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "sdap_sd_search_send failed.\n");
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher tevent_req_set_callback(subreq, ad_gpo_get_sd_referral_search_done, req);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagherad_gpo_get_sd_referral_search_done(struct tevent_req *subreq)
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher tevent_req_callback_data(subreq, struct tevent_req);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher struct ad_gpo_get_sd_referral_state *state =
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher tevent_req_data(req, struct ad_gpo_get_sd_referral_state);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher ret = sdap_id_op_done(state->ref_op, ret, &dp_error);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher "Unable to get GPO attributes: [%d](%s)\n",
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher if ((num_results < 1) || (results == NULL)) {
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher * It's strictly possible for the referral search to return
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher * another referral value here, but it shouldn't actually
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher * happen with Active Directory. Properly handling (and
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher * limiting) the referral chain would be fairly complex, so
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher * we will do it later if it ever becomes necessary.
de1131abe5ba7aaeb59f81fc3a9cd2a71c0b52ddLukas Slebodnik "No attrs found for referred GPO [%s].\n", state->gpo_dn);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher DEBUG(SSSDBG_OP_FAILURE, "Received multiple replies\n");
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher state->reply = talloc_steal(state, results[0]);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagherad_gpo_get_sd_referral_recv(struct tevent_req *req,
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher struct ad_gpo_get_sd_referral_state *state =
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher tevent_req_data(req, struct ad_gpo_get_sd_referral_state);
31bafc0d6384a30859aa18f3bd22275aec6ee2edStephen Gallagher *_smb_host = talloc_steal(mem_ctx, state->smb_host);