ad_gpo.c revision 16cb0969f0a9ea71524d852077d6a480740d4f12
22dd6d9af47163ee081d6c505d0a13dbf40ba87aChristian Maeder Yassir Elley <yelley@redhat.com>
22dd6d9af47163ee081d6c505d0a13dbf40ba87aChristian Maeder Copyright (C) 2013 Red Hat
95c3e5d11dcee331dc3876a9bf0c1d6daa38e2caChristian Maeder This program is free software; you can redistribute it and/or modify
e6d40133bc9f858308654afb1262b8b483ec5922Till Mossakowski it under the terms of the GNU General Public License as published by
679d3f541f7a9ede4079e045f7758873bb901872Till Mossakowski the Free Software Foundation; either version 3 of the License, or
679d3f541f7a9ede4079e045f7758873bb901872Till Mossakowski (at your option) any later version.
95c3e5d11dcee331dc3876a9bf0c1d6daa38e2caChristian Maeder This program is distributed in the hope that it will be useful,
f3faf4e4346b6224a3aaeeac11bac8b5c8932a29Christian Maeder but WITHOUT ANY WARRANTY; without even the implied warranty of
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maeder MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
46947810076241f06f3e2919edb2289ed84d6c15Christian Maeder GNU General Public License for more details.
4a8f990902448d0562fbe1a98ce685ddbd531d38Christian Maeder You should have received a copy of the GNU General Public License
f3faf4e4346b6224a3aaeeac11bac8b5c8932a29Christian Maeder along with this program. If not, see <http://www.gnu.org/licenses/>.
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maeder * This file implements the following pair of *public* functions (see header):
74b841a4b332085d5fd79975a13313c2681ae595Christian Maeder * ad_gpo_access_send/recv: provides client-side GPO processing
f3faf4e4346b6224a3aaeeac11bac8b5c8932a29Christian Maeder * This file also implements the following pairs of *private* functions (which
010997ddd12186698c1ebdbcddb63a670552b3c2Adrián Riesco * are used by the public functions):
f3faf4e4346b6224a3aaeeac11bac8b5c8932a29Christian Maeder * ad_gpo_process_som_send/recv: populate list of gp_som objects
95c3e5d11dcee331dc3876a9bf0c1d6daa38e2caChristian Maeder * ad_gpo_process_gpo_send/recv: populate list of gp_gpo objects
43b4c41fbb07705c9df321221ab9cb9832460407Christian Maeder * ad_gpo_process_cse_send/recv: retrieve policy file data
ad270004874ce1d0697fb30d7309f180553bb315Christian Maeder/* == gpo-ldap constants =================================================== */
c5bc8d60f7c753f81746828329d9e92db1ab7abaChristian Maeder#define AD_AT_CONFIG_NC "configurationNamingContext"
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder#define AD_AT_NT_SEC_DESC "nTSecurityDescriptor"
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder#define AD_AT_FILE_SYS_PATH "gPCFileSysPath"
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder#define AD_AT_MACHINE_EXT_NAMES "gPCMachineExtensionNames"
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder#define AD_AT_FUNC_VERSION "gPCFunctionalityVersion"
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder#define UAC_WORKSTATION_TRUST_ACCOUNT 0x00001000
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder#define AD_AGP_GUID "edacfd8f-ffb3-11d1-b41d-00a0c968f939"
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder#define AD_AUTHENTICATED_USERS_SID "S-1-5-11"
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder/* == gpo-smb constants ==================================================== */
f1b14608f0f3db464c3aded480e49522d73b08e5Christian Maeder#define ALLOW_LOGON_INTERACTIVE "SeInteractiveLogonRight"
f1b14608f0f3db464c3aded480e49522d73b08e5Christian Maeder#define DENY_LOGON_INTERACTIVE "SeDenyInteractiveLogonRight"
f1b14608f0f3db464c3aded480e49522d73b08e5Christian Maeder#define ALLOW_LOGON_REMOTE_INTERACTIVE "SeRemoteInteractiveLogonRight"
c5bc8d60f7c753f81746828329d9e92db1ab7abaChristian Maeder#define DENY_LOGON_REMOTE_INTERACTIVE "SeDenyRemoteInteractiveLogonRight"
9192fdd8f0e682ac0f0183dd854d5210fbfa4ec5Christian Maeder#define ALLOW_LOGON_NETWORK "SeNetworkLogonRight"
f1b14608f0f3db464c3aded480e49522d73b08e5Christian Maeder#define DENY_LOGON_NETWORK "SeDenyNetworkLogonRight"
f1b14608f0f3db464c3aded480e49522d73b08e5Christian Maeder#define ALLOW_LOGON_BATCH "SeBatchLogonRight"
f1b14608f0f3db464c3aded480e49522d73b08e5Christian Maeder#define DENY_LOGON_BATCH "SeDenyBatchLogonRight"
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder#define ALLOW_LOGON_SERVICE "SeServiceLogonRight"
7688e20f844fe88f75c04016841ebb5e5e3d927fChristian Maeder#define DENY_LOGON_SERVICE "SeDenyServiceLogonRight"
a05cad7f2f387b795a71a3aaec543c78e1b89d38Christian Maeder#define GP_EXT_GUID_SECURITY "{827D319E-6EAC-11D2-A4EA-00C04F79F83A}"
be3f5e3e69900ececafea5b010a8400f26af5362Christian Maeder#define GP_EXT_GUID_SECURITY_SUFFIX "/Machine/Microsoft/Windows NT/SecEdit/GptTmpl.inf"
be3f5e3e69900ececafea5b010a8400f26af5362Christian Maeder#define GPO_CHILD SSSD_LIBEXEC_PATH"/gpo_child"
a05cad7f2f387b795a71a3aaec543c78e1b89d38Christian Maeder/* fd used by the gpo_child process for logging */
12368e292c1abf7eaf975f20ee30ef7820ac5dd5Christian Maeder/* == common data structures and declarations ============================= */
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maederstruct tevent_req *ad_gpo_process_som_send(TALLOC_CTX *mem_ctx,
81337d455794a0b50fae10b53d0ed85d9e8f2fafChristian Maederint ad_gpo_process_som_recv(struct tevent_req *req,
412aa5e819f3cd18f0be10b5571661036515b151Christian Maederstruct tevent_req *ad_gpo_process_gpo_send(TALLOC_CTX *mem_ctx,
46947810076241f06f3e2919edb2289ed84d6c15Christian Maederint ad_gpo_process_gpo_recv(struct tevent_req *req,
46947810076241f06f3e2919edb2289ed84d6c15Christian Maederstruct tevent_req *ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx,
cc4537e2e13b93e08fc8391d3abb8e412cb71b80Christian Maederint ad_gpo_process_cse_recv(struct tevent_req *req);
cc4537e2e13b93e08fc8391d3abb8e412cb71b80Christian Maeder/* == ad_gpo_parse_map_options and helpers ==================================*/
cc4537e2e13b93e08fc8391d3abb8e412cb71b80Christian Maeder#define GPO_GDM_FINGERPRINT "gdm-fingerprint"
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maederconst char *gpo_map_interactive_defaults[] =
1af66b491a6164e07ac202abfa0d06c6c2462d64Christian Maeder GPO_GDM_FINGERPRINT, GPO_GDM_PASSWORD, GPO_GDM_SMARTCARD, GPO_KDM, NULL};
1af66b491a6164e07ac202abfa0d06c6c2462d64Christian Maederconst char *gpo_map_remote_interactive_defaults[] = {GPO_SSHD, NULL};
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maederconst char *gpo_map_network_defaults[] = {GPO_FTP, GPO_SAMBA, NULL};
1af66b491a6164e07ac202abfa0d06c6c2462d64Christian Maederconst char *gpo_map_batch_defaults[] = {GPO_CROND, NULL};
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maederconst char *gpo_map_service_defaults[] = {NULL};
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maederconst char *gpo_map_permit_defaults[] = {GPO_SUDO, GPO_SUDO_I, NULL};
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maederconst char *gpo_map_deny_defaults[] = {NULL};
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maederstruct gpo_map_option_entry gpo_map_option_entries[] = {
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder {GPO_MAP_INTERACTIVE, AD_GPO_MAP_INTERACTIVE, gpo_map_interactive_defaults,
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder ALLOW_LOGON_INTERACTIVE, DENY_LOGON_INTERACTIVE},
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder {GPO_MAP_REMOTE_INTERACTIVE, AD_GPO_MAP_REMOTE_INTERACTIVE,
7297175957c5ad3c0498032190b1dee9ec5fb873Christian Maeder ALLOW_LOGON_REMOTE_INTERACTIVE, DENY_LOGON_REMOTE_INTERACTIVE},
792df0347edab377785d98c63e2be8e2ce0a8bdeChristian Maeder {GPO_MAP_NETWORK, AD_GPO_MAP_NETWORK, gpo_map_network_defaults,
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder {GPO_MAP_BATCH, AD_GPO_MAP_BATCH, gpo_map_batch_defaults,
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder {GPO_MAP_SERVICE, AD_GPO_MAP_SERVICE, gpo_map_service_defaults,
3f9fabb8ac5cfd9234431ecf19b51ff3e985595aChristian Maeder {GPO_MAP_PERMIT, AD_GPO_MAP_PERMIT, gpo_map_permit_defaults, NULL, NULL},
3f9fabb8ac5cfd9234431ecf19b51ff3e985595aChristian Maeder {GPO_MAP_DENY, AD_GPO_MAP_DENY, gpo_map_deny_defaults, NULL, NULL},
c30cfe2a6ab063befdfb47449bc286caee6d8fc3Christian Maederconst char* gpo_map_type_string(int gpo_map_type)
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder case GPO_MAP_INTERACTIVE: return "Interactive";
df098122ddc81fe1cb033a151f7305c1dda2dc81Christian Maeder case GPO_MAP_REMOTE_INTERACTIVE: return "Remote Interactive";
c0380b947eef252db81ee562246bb732555427f4Till Mossakowskistatic inline bool
2afae0880da7ca73c9376fd4d653ab19833fe858Christian Maederad_gpo_service_in_list(char **list, size_t nlist, const char *str)
0d0047d6eb457b56ff10987569769a420754a56fChristian Maeder for (i = 0; i < nlist; i++) {
c0380b947eef252db81ee562246bb732555427f4Till Mossakowski return (i < nlist) ? true : false;
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maederad_gpo_parse_map_option_helper(enum gpo_map_type gpo_map_type,
a05cad7f2f387b795a71a3aaec543c78e1b89d38Christian Maeder hret = hash_lookup(options_table, &key, &val);
9192fdd8f0e682ac0f0183dd854d5210fbfa4ec5Christian Maeder if (hret != HASH_SUCCESS && hret != HASH_ERROR_KEY_NOT_FOUND) {
22dd6d9af47163ee081d6c505d0a13dbf40ba87aChristian Maeder DEBUG(SSSDBG_OP_FAILURE, "Error checking hash table: [%s]\n",
4c7f058cdd19ce67b2b5d4b7f69703d0f8a21e38Christian Maeder /* handle unexpected case where mapping for key already exists */
a05cad7f2f387b795a71a3aaec543c78e1b89d38Christian Maeder /* mapping for key exists for same map type; no error */
a05cad7f2f387b795a71a3aaec543c78e1b89d38Christian Maeder "PAM service %s maps to %s multiple times\n", key.str,
c5bc8d60f7c753f81746828329d9e92db1ab7abaChristian Maeder /* mapping for key exists for different map type; error! */
a05cad7f2f387b795a71a3aaec543c78e1b89d38Christian Maeder "PAM service %s maps to both %s and %s\n", key.str,
9192fdd8f0e682ac0f0183dd854d5210fbfa4ec5Christian Maeder gpo_map_type_string(val.i), gpo_map_type_string(gpo_map_type));
5a87ed846cc38cb0e3adf8f736d95614d3e724a3Christian Maeder /* handle expected case where mapping for key doesn't already exist */
24f14a27a838087b661c2e66fdec4e436ddbd832Christian Maeder hret = hash_enter(options_table, &key, &val);
24f14a27a838087b661c2e66fdec4e436ddbd832Christian Maeder DEBUG(SSSDBG_OP_FAILURE, "Error checking hash table: [%s]\n",
a4cb1786d23060c8521a88f08f9909589fa83a12Christian Maederad_gpo_parse_map_option(TALLOC_CTX *mem_ctx,
c0380b947eef252db81ee562246bb732555427f4Till Mossakowski DEBUG(SSSDBG_TRACE_ALL, "gpo_map_type: %s\n",
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maeder ret = split_on_separator(tmp_ctx, conf_str, ',', true, true,
0d0047d6eb457b56ff10987569769a420754a56fChristian Maeder "Cannot parse list of service names %s: %d\n", conf_str, ret);
37d0b201b8ba5d6056691e3055dd803e7928e163Christian Maeder add_list = talloc_zero_array(tmp_ctx, char *, conf_list_size);
9192fdd8f0e682ac0f0183dd854d5210fbfa4ec5Christian Maeder remove_list = talloc_zero_array(tmp_ctx, char *, conf_list_size);
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder if (add_list == NULL || remove_list == NULL) {
6157bf81d295795067c177aa870fedff83cbe750Christian Maeder for (i = 0; i < conf_list_size; i++) {
cc4537e2e13b93e08fc8391d3abb8e412cb71b80Christian Maeder switch (conf_list[i][0]) {
7d5f239f3f1c1397e5d80caea12929bdf8abe2d8Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "ad_gpo_map values must start with"
7d5f239f3f1c1397e5d80caea12929bdf8abe2d8Christian Maeder "either '+' (for adding service) or '-' (for removing service), "
283fdbf051a1cbcfe003ffdcb434564495106f13Christian Maeder "got '%s'\n",
7d5f239f3f1c1397e5d80caea12929bdf8abe2d8Christian Maeder /* Start by adding explicitly added services ('+') to hashtable */
7d5f239f3f1c1397e5d80caea12929bdf8abe2d8Christian Maeder for (i = 0; i < ai; i++) {
89ab08979dc23d72e9e09c8990a8c44847041d6fChristian Maeder /* if the service is explicitly configured to be removed, skip it */
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder if (ad_gpo_service_in_list(remove_list, ri, add_list[i])) {
412aa5e819f3cd18f0be10b5571661036515b151Christian Maeder ret = ad_gpo_parse_map_option_helper(gpo_map_type, key, options_table);
412aa5e819f3cd18f0be10b5571661036515b151Christian Maeder DEBUG(SSSDBG_OP_FAILURE, "Invalid configuration: %d\n", ret);
412aa5e819f3cd18f0be10b5571661036515b151Christian Maeder DEBUG(SSSDBG_TRACE_ALL, "Explicitly added service: %s\n", key.str);
cc4537e2e13b93e08fc8391d3abb8e412cb71b80Christian Maeder /* Add defaults to hashtable */
c5653d37b37dcc025ff6dd1eada95ae67116e699Christian Maeder for (i = 0; defaults[i]; i++) {
cc4537e2e13b93e08fc8391d3abb8e412cb71b80Christian Maeder /* if the service is explicitly configured to be removed, skip it */
13d0d9a3df7f3998f3c18c2fccbf2e3bbacbd4b5Christian Maeder if (ad_gpo_service_in_list(remove_list, ri, defaults[i])) {
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder key.str = talloc_strdup(mem_ctx, defaults[i]);
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder ret = ad_gpo_parse_map_option_helper(gpo_map_type, key, options_table);
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder DEBUG(SSSDBG_OP_FAILURE, "Invalid configuration: %d\n", ret);
06afcb70f335c6de74007dc5d6bb19a7d06de457Christian Maeder DEBUG(SSSDBG_TRACE_ALL, "Default service (not explicitly removed): %s\n",
ba5c87b3f4a921f0932a08de48a3aedd3ca4d25bTill Mossakowskiad_gpo_parse_map_options(struct ad_access_ctx *access_ctx)
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder for (i = 0; i < GPO_MAP_NUM_OPTS; i++) {
b3dca469a9e267d6d71acfdeca7bf284d0581dc7Till Mossakowski struct gpo_map_option_entry entry = gpo_map_option_entries[i];
ba5c87b3f4a921f0932a08de48a3aedd3ca4d25bTill Mossakowski char *entry_config = dp_opt_get_string(access_ctx->ad_options,
ba5c87b3f4a921f0932a08de48a3aedd3ca4d25bTill Mossakowski ret = ad_gpo_parse_map_option(access_ctx, entry.gpo_map_type,
c40822a6238ef14ebd3df830204c2790a68c8076Christian Maeder DEBUG(SSSDBG_OP_FAILURE, "Invalid configuration: %d\n", ret);
c30cfe2a6ab063befdfb47449bc286caee6d8fc3Christian Maeder /* default right (applicable for services without any mapping) */
b3dca469a9e267d6d71acfdeca7bf284d0581dc7Till Mossakowski dp_opt_get_string(access_ctx->ad_options, AD_GPO_DEFAULT_RIGHT);
22dd6d9af47163ee081d6c505d0a13dbf40ba87aChristian Maeder DEBUG(SSSDBG_TRACE_ALL, "gpo_default_right_config: %s\n",
5a87ed846cc38cb0e3adf8f736d95614d3e724a3Christian Maeder /* if default right not set in config, set them to DENY */
5a87ed846cc38cb0e3adf8f736d95614d3e724a3Christian Maeder } else if (strncasecmp(gpo_default_right_config, "interactive",
5a87ed846cc38cb0e3adf8f736d95614d3e724a3Christian Maeder } else if (strncasecmp(gpo_default_right_config, "remote_interactive",
5a87ed846cc38cb0e3adf8f736d95614d3e724a3Christian Maeder gpo_default_right = GPO_MAP_REMOTE_INTERACTIVE;
c5bc8d60f7c753f81746828329d9e92db1ab7abaChristian Maeder } else if (strncasecmp(gpo_default_right_config, "network",
22250d2b3c9f86fe19cba665d71c301de03db142Christian Maeder } else if (strncasecmp(gpo_default_right_config, "batch",
5a87ed846cc38cb0e3adf8f736d95614d3e724a3Christian Maeder } else if (strncasecmp(gpo_default_right_config, "service",
5a87ed846cc38cb0e3adf8f736d95614d3e724a3Christian Maeder } else if (strncasecmp(gpo_default_right_config, "permit",
5a87ed846cc38cb0e3adf8f736d95614d3e724a3Christian Maeder } else if (strncasecmp(gpo_default_right_config, "deny",
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maeder DEBUG(SSSDBG_TRACE_ALL, "gpo_default_right: %d\n", gpo_default_right);
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder access_ctx->gpo_default_right = gpo_default_right;
2701083ab584807a8dec6f2c8bc03237a25d9809Christian Maeder/* == ad_gpo_access_send/recv helpers =======================================*/
1805f9816e3414ab184fb8546ab1abc6241f04cdChristian Maederad_gpo_dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2)
1805f9816e3414ab184fb8546ab1abc6241f04cdChristian Maeder return false;
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maeder if (sid1->sid_rev_num != sid2->sid_rev_num) {
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maeder return false;
6157bf81d295795067c177aa870fedff83cbe750Christian Maeder for (i = 0; i < 6; i++) {
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder if (sid1->id_auth[i] != sid2->id_auth[i]) {
95c27038582e8a2ce24923bee69ef15931b8b87bChristian Maeder return false;
627ed7abdbae641636a2d0f2510c0d450f5ee915Christian Maeder return false;
22dd6d9af47163ee081d6c505d0a13dbf40ba87aChristian Maeder if (sid1->sub_auths[i] != sid2->sub_auths[i]) {
2701083ab584807a8dec6f2c8bc03237a25d9809Christian Maeder return false;
22dd6d9af47163ee081d6c505d0a13dbf40ba87aChristian Maeder * This function retrieves the SIDs corresponding to the input user and returns
22dd6d9af47163ee081d6c505d0a13dbf40ba87aChristian Maeder * the user_sid, group_sids, and group_size in their respective output params.
52aad0502f0ddd332a28ae3fcd3327fa66d002f7Till Mossakowski * Note: since authentication must complete successfully before the
52aad0502f0ddd332a28ae3fcd3327fa66d002f7Till Mossakowski * gpo access checks are called, we can safely assume that the user/computer
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maeder * has been authenticated. As such, this function always adds the
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maeder * AD_AUTHENTICATED_USERS_SID to the group_sids.
a80f2865b6b40a922bcccfce0cb0d047edc33e3aChristian Maeder /* first result from sysdb_initgroups is user_sid; rest are group_sids */
62607bfd8541a700d18aee4f9cdb037aded5ab0bChristian Maeder ret = sysdb_initgroups(tmp_ctx, domain, user, &res);
a80f2865b6b40a922bcccfce0cb0d047edc33e3aChristian Maeder "sysdb_initgroups failed: [%d](%s)\n",
a80f2865b6b40a922bcccfce0cb0d047edc33e3aChristian Maeder "sysdb_initgroups returned empty result\n");
de66af0f4b27f08f81c7ca9c573ef9cdf7ca7a07Christian Maeder user_sid = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SID_STR, NULL);
12368e292c1abf7eaf975f20ee30ef7820ac5dd5Christian Maeder /* include space for AD_AUTHENTICATED_USERS_SID and NULL */
a80f2865b6b40a922bcccfce0cb0d047edc33e3aChristian Maeder group_sids = talloc_array(tmp_ctx, const char *, num_group_sids + 1 + 1);
37d0b201b8ba5d6056691e3055dd803e7928e163Christian Maeder for (i = 0; i < num_group_sids; i++) {
4c7f058cdd19ce67b2b5d4b7f69703d0f8a21e38Christian Maeder group_sid = ldb_msg_find_attr_as_string(res->msgs[i+1],
1bc5dccbf0083a620ae1181c717fea75e4af5e5cChristian Maeder group_sids[i] = talloc_steal(group_sids, group_sid);
22dd6d9af47163ee081d6c505d0a13dbf40ba87aChristian Maeder group_sids[i++] = talloc_strdup(group_sids, AD_AUTHENTICATED_USERS_SID);
79ee6b8eb396ed31807784a4bb1c9cc2ce094835Till Mossakowski *_group_sids = talloc_steal(mem_ctx, group_sids);
79ee6b8eb396ed31807784a4bb1c9cc2ce094835Till Mossakowski *_user_sid = talloc_steal(mem_ctx, user_sid);
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maeder * This function determines whether the input ace_dom_sid matches any of the
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maeder * client's SIDs. The boolean result is assigned to the _included output param.
f8fe1f095d5b7fd96bde0784289b001446e60d0bChristian Maederad_gpo_ace_includes_client_sid(const char *user_sid,
083a5256468076d5a9bfeb22a6e97076c224252eChristian Maeder err = sss_idmap_sid_to_smb_sid(idmap_ctx, user_sid, &user_dom_sid);
a89e661aad28f1b39f4fc9f9f9a4d46074234123Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize idmap context.\n");
a89e661aad28f1b39f4fc9f9f9a4d46074234123Christian Maeder included = ad_gpo_dom_sid_equal(&ace_dom_sid, user_dom_sid);
95c3e5d11dcee331dc3876a9bf0c1d6daa38e2caChristian Maeder sss_idmap_free_smb_sid(idmap_ctx, user_dom_sid);
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maeder for (i = 0; i < group_size; i++) {
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder err = sss_idmap_sid_to_smb_sid(idmap_ctx, group_sids[i], &group_dom_sid);
f8fe1f095d5b7fd96bde0784289b001446e60d0bChristian Maeder DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize idmap context.\n");
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maeder included = ad_gpo_dom_sid_equal(&ace_dom_sid, group_dom_sid);
c528d35d975276f43d31dec4db9b4e1bf08e1fe2Christian Maeder sss_idmap_free_smb_sid(idmap_ctx, group_dom_sid);
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder * This function determines whether use of the extended right
8ecf5884934cad4efbcd60b92671b74e4aaeb62bChristian Maeder * named "ApplyGroupPolicy" (AGP) is allowed, by comparing the specified
8ecf5884934cad4efbcd60b92671b74e4aaeb62bChristian Maeder * user_sid and group_sids against the specified access control entry (ACE).
1b2649da700cc49d0d49e463e3962c07770f6204Christian Maeder * This function returns ALLOWED, DENIED, or NEUTRAL depending on whether
1b2649da700cc49d0d49e463e3962c07770f6204Christian Maeder * the ACE explictly allows, explicitly denies, or does neither.
89ab08979dc23d72e9e09c8990a8c44847041d6fChristian Maeder * Note that the 'M' abbreviation used in the evaluation algorithm stands for
89ab08979dc23d72e9e09c8990a8c44847041d6fChristian Maeder * "access_mask", which represents the set of access rights associated with an
89ab08979dc23d72e9e09c8990a8c44847041d6fChristian Maeder * individual ACE. The access right of interest to the GPO code is
89ab08979dc23d72e9e09c8990a8c44847041d6fChristian Maeder * RIGHT_DS_CONTROL_ACCESS, which serves as a container for all control access
89ab08979dc23d72e9e09c8990a8c44847041d6fChristian Maeder * rights. The specific control access right is identified by a GUID in the
8ecf5884934cad4efbcd60b92671b74e4aaeb62bChristian Maeder * ACE's ObjectType. In our case, this is the GUID corresponding to AGP.
8ecf5884934cad4efbcd60b92671b74e4aaeb62bChristian Maeder * The ACE evaluation algorithm is specified in [MS-ADTS] 5.1.3.3.4:
8ecf5884934cad4efbcd60b92671b74e4aaeb62bChristian Maeder * - Deny access by default
8ecf5884934cad4efbcd60b92671b74e4aaeb62bChristian Maeder * - If the "Inherit Only" (IO) flag is set in the ACE, skip the ACE.
8ecf5884934cad4efbcd60b92671b74e4aaeb62bChristian Maeder * - If the SID in the ACE does not match any SID in the requester's
c5653d37b37dcc025ff6dd1eada95ae67116e699Christian Maeder * security context, skip the ACE
8ecf5884934cad4efbcd60b92671b74e4aaeb62bChristian Maeder * - If the ACE type is "Object Access Allowed", the access right
c5653d37b37dcc025ff6dd1eada95ae67116e699Christian Maeder * RIGHT_DS_CONTROL_ACCESS (CR) is present in M, and the ObjectType
13d0d9a3df7f3998f3c18c2fccbf2e3bbacbd4b5Christian Maeder * field in the ACE is either not present OR contains a GUID value equal
13d0d9a3df7f3998f3c18c2fccbf2e3bbacbd4b5Christian Maeder * to AGP, then grant requested control access right. Stop access checking.
8ecf5884934cad4efbcd60b92671b74e4aaeb62bChristian Maeder * - If the ACE type is "Object Access Denied", the access right
c5653d37b37dcc025ff6dd1eada95ae67116e699Christian Maeder * RIGHT_DS_CONTROL_ACCESS (CR) is present in M, and the ObjectType
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder * field in the ACE is either not present OR contains a GUID value equal to
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder * AGP, then deny the requested control access right. Stop access checking.
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maederstatic enum ace_eval_status ad_gpo_evaluate_ace(struct security_ace *ace,
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
89ab08979dc23d72e9e09c8990a8c44847041d6fChristian Maeder ret = ad_gpo_ace_includes_client_sid(user_sid, group_sids, group_size,
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder GUID_from_string(AD_AGP_GUID, &ext_right_agp_guid);
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder if (object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) {
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder if (GUID_equal(&object.type.type, &ext_right_agp_guid)) {
3d774b4dfa0e459c1a3b08b4aa32c85aa4875362Christian Maeder if (ace->access_mask & SEC_ADS_CONTROL_ACCESS) {
c5653d37b37dcc025ff6dd1eada95ae67116e699Christian Maeder if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) {
1d10e9a6a3b03c7aa4306ff936ccaeacf474059aChristian Maeder } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT) {
1d10e9a6a3b03c7aa4306ff936ccaeacf474059aChristian Maeder * This function extracts the GPO's DACL (discretionary access control list)
1d10e9a6a3b03c7aa4306ff936ccaeacf474059aChristian Maeder * from the GPO's specified security descriptor, and determines whether
1d10e9a6a3b03c7aa4306ff936ccaeacf474059aChristian Maeder * the GPO is applicable to the policy target, by comparing the specified
cdcca7a63a02d363730ee1060e2500343da76afaChristian Maeder * user_sid and group_sids against each access control entry (ACE) in the DACL.
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski * The boolean result is assigned to the _access_allowed output parameter.
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowskistatic errno_t ad_gpo_evaluate_dacl(struct security_acl *dacl,
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian Maeder * [MS-ADTS] 5.1.3.3.4:
3476beb5baf84bef7cc7d627b130de9d48700399Christian Maeder * If the DACL does not have any ACE, then deny the requester the
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski * requested control access right.
7297175957c5ad3c0498032190b1dee9ec5fb873Christian Maeder ace_status = ad_gpo_evaluate_ace(ace, idmap_ctx, user_sid,
22dd6d9af47163ee081d6c505d0a13dbf40ba87aChristian Maeder * This function takes candidate_gpos as input, filters out any gpo that is
58b671de3fe578346fef9642ffa3c5a0a0edb3cbTill Mossakowski * not applicable to the policy target and assigns the result to the
3476beb5baf84bef7cc7d627b130de9d48700399Christian Maeder * _dacl_filtered_gpos output parameter. The filtering algorithm is
22dd6d9af47163ee081d6c505d0a13dbf40ba87aChristian Maeder * defined in [MS-GPOL] 3.2.5.1.6
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maederad_gpo_filter_gpos_by_dacl(TALLOC_CTX *mem_ctx,
4c7f058cdd19ce67b2b5d4b7f69703d0f8a21e38Christian Maeder ret = ad_gpo_get_sids(tmp_ctx, user, domain, &user_sid,
996a56a455d65cfac4ddedd44fd90cfc1ea849aeChristian Maeder "Unable to retrieve SIDs: [%d](%s)\n", ret, sss_strerror(ret));
ef2affdc0cdf3acd5c051597c04ab9b08a346a7dChristian Maeder for (i = 0; i < num_candidate_gpos; i++) {
95c3e5d11dcee331dc3876a9bf0c1d6daa38e2caChristian Maeder DEBUG(SSSDBG_TRACE_ALL, "examining dacl candidate_gpo_guid:%s\n",
22dd6d9af47163ee081d6c505d0a13dbf40ba87aChristian Maeder /* gpo_func_version must be set to version 2 */
a80f2865b6b40a922bcccfce0cb0d047edc33e3aChristian Maeder if (candidate_gpo->gpo_func_version != 2) {
a80f2865b6b40a922bcccfce0cb0d047edc33e3aChristian Maeder "GPO not applicable to target per security filtering\n");
a80f2865b6b40a922bcccfce0cb0d047edc33e3aChristian Maeder /* gpo_flags value of 2 means that GPO's computer portion is disabled */
7297175957c5ad3c0498032190b1dee9ec5fb873Christian Maeder "GPO not applicable to target per security filtering\n");
4a8f990902448d0562fbe1a98ce685ddbd531d38Christian Maeder * [MS-ADTS] 5.1.3.3.4:
4a8f990902448d0562fbe1a98ce685ddbd531d38Christian Maeder * If the security descriptor has no DACL or its "DACL Present" bit
4a8f990902448d0562fbe1a98ce685ddbd531d38Christian Maeder * is not set, then grant requester the requested control access right.
dbbcdfeafa68c87e0b2be0096788844e2be08345Christian Maeder if ((!(sd->type & SEC_DESC_DACL_PRESENT)) || (dacl == NULL)) {
dbbcdfeafa68c87e0b2be0096788844e2be08345Christian Maeder DEBUG(SSSDBG_TRACE_ALL, "DACL is not present\n");
1af66b491a6164e07ac202abfa0d06c6c2462d64Christian Maeder ret = ad_gpo_evaluate_dacl(dacl, idmap_ctx, user_sid, group_sids,
4a8f990902448d0562fbe1a98ce685ddbd531d38Christian Maeder DEBUG(SSSDBG_MINOR_FAILURE, "Could not determine if GPO is applicable\n");
4a8f990902448d0562fbe1a98ce685ddbd531d38Christian Maeder "GPO applicable to target per security filtering\n");
6b00a9239fe7c804524099ca3d25f4ffc6079ceeChristian Maeder dacl_filtered_gpos[gpo_dn_idx] = talloc_steal(dacl_filtered_gpos,
1af66b491a6164e07ac202abfa0d06c6c2462d64Christian Maeder "GPO not applicable to target per security filtering\n");
1af66b491a6164e07ac202abfa0d06c6c2462d64Christian Maeder *_dacl_filtered_gpos = talloc_steal(mem_ctx, dacl_filtered_gpos);
done:
return ret;
const char **gpo_cse_guids,
int num_gpo_cse_guids)
for (i = 0; i < num_gpo_cse_guids; i++) {
static errno_t
const char *cse_guid,
int *_num_cse_filtered_gpos)
int ret = 0;
int gpo_dn_idx = 0;
bool included;
goto done;
struct gp_gpo *,
goto done;
for (i = 0; i < num_dacl_filtered_gpos; i++) {
if (included) {
gpo_dn_idx++;
done:
return ret;
int privilege_size,
const char *user_sid,
const char **group_sids,
int group_size)
for (i = 0; i < privilege_size; i++) {
for (j = 0; j < group_size; j++) {
static errno_t
const char *policy_setting_key,
char **_policy_setting_value)
int ret;
const char *policy_setting_value;
if (ret != 0) {
goto done;
goto done;
if (ret != 0) {
goto done;
if (policy_setting_value[0]) {
if (!*_policy_setting_value) {
goto done;
done:
return ret;
static errno_t
const char *filename)
int ret;
goto done;
if (ret != 0) {
goto done;
if (ret != 0) {
goto done;
if (ret != 0) {
goto done;
for (i = 0; i < GPO_MAP_NUM_OPTS; i++) {
&allow_value);
goto done;
goto done;
&deny_value);
goto done;
goto done;
done:
return ret;
static errno_t
const char *user,
char **allowed_sids,
int allowed_size,
char **denied_sids,
int denied_size)
const char *user_sid;
const char **group_sids;
int group_size = 0;
bool access_granted = false;
bool access_denied = false;
int ret;
for (j= 0; j < allowed_size; j++) {
for (j= 0; j < denied_size; j++) {
goto done;
for (j= 0; j < group_size; j++) {
group_sids[j]);
if (allowed_size == 0) {
access_granted = true;
return EOK;
switch (gpo_mode) {
return ERR_ACCESS_DENIED;
return EOK;
return EINVAL;
done:
if (ret) {
return ret;
const char *key,
char ***_sids_list,
int *_sids_list_size)
int ret;
const char *value;
int sids_list_size;
goto done;
sids_list_size = 0;
goto done;
for (i = 0; i < sids_list_size; i++) {
sids_list[i]++;
done:
return ret;
static errno_t
const char *user,
int ret;
char **allow_sids;
int allow_size ;
char **deny_sids;
int deny_size;
goto done;
goto done;
goto done;
done:
return ret;
/* == ad_gpo_access_send/recv implementation ================================*/
struct ad_gpo_access_state {
char *server_hostname;
int timeout;
const char *user;
int gpo_timeout_option;
const char *ad_hostname;
const char *target_dn;
int cse_gpo_index;
struct tevent_req *
const char *user,
const char *service)
char *server_uri;
int hret;
return NULL;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
return req;
static errno_t
const char *user,
user,
domain);
goto done;
done:
return ret;
char *filter;
char *sam_account_name;
char *domain_dn;
int dp_error;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
done:
int ret;
int dp_error;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
done:
int ret;
goto done;
som_list);
goto done;
done:
int ret;
int dp_error;
int num_candidate_gpos = 0;
const char **cse_filtered_gpo_guids;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
switch (ret) {
case ENOENT:
goto done;
done:
static errno_t
bool send_to_child = true;
int cached_gpt_version = 0;
return ENOMEM;
&res);
send_to_child = false;
return ret;
return EAGAIN;
* with the user_sid/group_sids of interest.
int ret;
goto done;
goto done;
done:
return EOK;
/* == ad_gpo_process_som_send/recv helpers ================================= */
static errno_t
const char *dn,
const char **_parent_dn)
int ret;
goto done;
done:
return ret;
static errno_t
const char *target_dn,
int *_num_soms,
int ret;
int rdn_count = 0;
int som_idx = 0;
goto done;
goto done;
goto done;
if (rdn_count == 0) {
goto done;
goto done;
goto done;
goto done;
som_idx++;
done:
return ret;
static errno_t
const char *som_dn,
char *raw_gplink_value,
bool allow_enforced_only)
char *ptr;
char *first;
char *last;
char *dn;
char *gplink_options;
int ret;
int gplink_count = 0;
int num_enabled = 0;
return EINVAL;
goto done;
ptr++;
gplink_count++;
if (gplink_count == 0) {
goto done;
goto done;
num_enabled = 0;
for (i = 0; i < gplink_count; i++) {
goto done;
last++;
goto done;
if (errno != 0) {
goto done;
goto done;
goto done;
if (gplink_number == 0) {
num_enabled++;
num_enabled++;
goto done;
done:
return ret;
/* == ad_gpo_process_som_send/recv implementation ========================== */
struct ad_gpo_process_som_state {
int timeout;
bool allow_enforced_only;
char *site_name;
char *site_dn;
int som_index;
int num_soms;
struct tevent_req *
int timeout,
const char *target_dn,
const char *domain_name)
return NULL;
goto immediately;
goto immediately;
goto immediately;
return req;
int ret;
char *site;
* retrieved at that point (see https://fedorahosted.org/sssd/ticket/2276)
int ret;
int dp_error;
const char *configNC;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
done:
static errno_t
return ENOMEM;
return EAGAIN;
int ret;
int dp_error;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
allow_enforced_only = 0;
if (errno != 0) {
goto done;
(char *)raw_gplink_value,
goto done;
if (allow_enforced_only) {
done:
return EOK;
/* == ad_gpo_process_gpo_send/recv helpers ================================= */
static errno_t
int *_num_candidate_gpos)
int num_candidate_gpos = 0;
int gpo_dn_idx = 0;
int num_enforced = 0;
int enforced_idx = 0;
int num_unenforced = 0;
int unenforced_idx = 0;
int ret;
goto done;
while (som_list[i]) {
goto done;
num_enforced++;
if (num_candidate_gpos == 0) {
*_num_candidate_gpos = 0;
goto done;
goto done;
goto done;
while (som_list[i]) {
goto done;
goto done;
enforced_idx++;
goto done;
struct gp_gpo *,
goto done;
gpo_dn_idx = 0;
goto done;
goto done;
gpo_dn_idx++;
for (i = 0; i < num_enforced; i++) {
goto done;
goto done;
gpo_dn_idx++;
done:
return ret;
* server_hostname = "adserver.foo.com", then
* _smb_server = "smb://adserver.foo.com"
* _smb_path = "/foo.com/..."
* For example, input_path = "\\foo.com\SysVol" is not a valid input_path,
static errno_t
char *server_hostname,
char *input_path,
const char **_smb_server,
const char **_smb_share,
const char **_smb_path)
char *ptr;
int ret;
int num_seps = 0;
goto done;
num_seps++;
ptr++;
ptr++;
ptr++;
if (num_seps == 0) {
goto done;
goto done;
goto done;
goto done;
goto done;
done:
return ret;
static errno_t
char *raw_machine_ext_names_value,
const char ***_gpo_cse_guids,
int *_num_gpo_cse_guids)
char *ptr;
char *first;
char *last;
char *cse_guid;
char *tool_guid;
const char **gpo_cse_guids;
int ret;
int num_gpo_cse_guids = 0;
return EINVAL;
goto done;
ptr++;
if (num_gpo_cse_guids == 0) {
goto done;
goto done;
for (i = 0; i < num_gpo_cse_guids; i++) {
last++;
first ++;
for (i = 0; i < num_gpo_cse_guids; i++) {
done:
return ret;
enum ndr_err_code
struct security_descriptor *r);
return EINVAL;
&sd);
return EINVAL;
return EOK;
/* == ad_gpo_process_gpo_send/recv implementation ========================== */
struct ad_gpo_process_gpo_state {
char *server_hostname;
int timeout;
int num_candidate_gpos;
int gpo_index;
struct tevent_req *
char *server_hostname,
int timeout,
return NULL;
goto immediately;
goto immediately;
return req;
static errno_t
return ENOMEM;
return EAGAIN;
int ret;
int dp_error;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
(char *)raw_machine_ext_names,
goto done;
done:
int *num_candidate_gpos)
return EOK;
/* == ad_gpo_process_cse_send/recv helpers ================================= */
static errno_t
const char *smb_server,
const char *smb_share,
const char *smb_path,
const char *smb_cse_suffix,
int cached_gpt_version,
int smb_server_length;
int smb_share_length;
int smb_path_length;
return ENOMEM;
return ENOMEM;
rp = 0;
return EOK;
static errno_t
int ret;
size_t p = 0;
return ret;
/* == ad_gpo_process_cse_send/recv implementation ========================== */
struct ad_gpo_process_cse_state {
int gpo_timeout_option;
const char *gpo_guid;
const char *smb_path;
const char *smb_cse_suffix;
struct tevent_req *
bool send_to_child,
const char *gpo_guid,
const char *smb_server,
const char *smb_share,
const char *smb_path,
const char *smb_cse_suffix,
int cached_gpt_version,
int gpo_timeout_option)
return NULL;
if (!send_to_child) {
goto immediately;
goto immediately;
goto immediately;
goto immediately;
goto immediately;
return req;
return req;
int ret;
int ret;
} else if (child_result != 0){
return EOK;
static errno_t
int ret;
return err;
return err;
return err;
return ret;
return err;
return EOK;