File: | /dev/shm/scanbuild/../sssd/src/providers/ad/ad_gpo.c |
Location: | line 2298, column 24 |
Description: | Function call argument is an uninitialized value |
1 | /* | |||
2 | SSSD | |||
3 | ||||
4 | Authors: | |||
5 | Yassir Elley <yelley@redhat.com> | |||
6 | ||||
7 | Copyright (C) 2013 Red Hat | |||
8 | ||||
9 | This program is free software; you can redistribute it and/or modify | |||
10 | it under the terms of the GNU General Public License as published by | |||
11 | the Free Software Foundation; either version 3 of the License, or | |||
12 | (at your option) any later version. | |||
13 | ||||
14 | This program is distributed in the hope that it will be useful, | |||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
17 | GNU General Public License for more details. | |||
18 | ||||
19 | You should have received a copy of the GNU General Public License | |||
20 | along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
21 | */ | |||
22 | ||||
23 | /* | |||
24 | * This file implements the following pair of *public* functions (see header): | |||
25 | * ad_gpo_access_send/recv: provides client-side GPO processing | |||
26 | * | |||
27 | * This file also implements the following pairs of *private* functions (which | |||
28 | * are used by the public functions): | |||
29 | * ad_gpo_process_som_send/recv: populate list of gp_som objects | |||
30 | * ad_gpo_process_gpo_send/recv: populate list of gp_gpo objects | |||
31 | * ad_gpo_process_cse_send/recv: retrieve policy file data | |||
32 | */ | |||
33 | ||||
34 | #include <security/pam_modules.h> | |||
35 | #include "util/util.h" | |||
36 | #include "util/strtonum.h" | |||
37 | #include "util/child_common.h" | |||
38 | #include "providers/data_provider.h" | |||
39 | #include "providers/dp_backend.h" | |||
40 | #include "providers/ad/ad_access.h" | |||
41 | #include "providers/ad/ad_common.h" | |||
42 | #include "providers/ad/ad_domain_info.h" | |||
43 | #include "providers/ad/ad_gpo.h" | |||
44 | #include "providers/ldap/sdap_access.h" | |||
45 | #include "providers/ldap/sdap_async.h" | |||
46 | #include "providers/ldap/sdap.h" | |||
47 | #include "providers/ldap/sdap_idmap.h" | |||
48 | #include "util/util_sss_idmap.h" | |||
49 | #include <ndr.h> | |||
50 | #include <gen_ndr/security.h> | |||
51 | ||||
52 | /* == gpo-ldap constants =================================================== */ | |||
53 | ||||
54 | #define AD_AT_DN"distinguishedName" "distinguishedName" | |||
55 | #define AD_AT_UAC"userAccountControl" "userAccountControl" | |||
56 | #define AD_AT_CONFIG_NC"configurationNamingContext" "configurationNamingContext" | |||
57 | #define AD_AT_GPLINK"gPLink" "gPLink" | |||
58 | #define AD_AT_GPOPTIONS"gpOptions" "gpOptions" | |||
59 | #define AD_AT_NT_SEC_DESC"nTSecurityDescriptor" "nTSecurityDescriptor" | |||
60 | #define AD_AT_CN"cn" "cn" | |||
61 | #define AD_AT_DISPLAY_NAME"displayName" "displayName" | |||
62 | #define AD_AT_FILE_SYS_PATH"gPCFileSysPath" "gPCFileSysPath" | |||
63 | #define AD_AT_VERSION_NUMBER"versionNumber" "versionNumber" | |||
64 | #define AD_AT_MACHINE_EXT_NAMES"gPCMachineExtensionNames" "gPCMachineExtensionNames" | |||
65 | #define AD_AT_USER_EXT_NAMES"gPCUserExtensionNames" "gPCUserExtensionNames" | |||
66 | #define AD_AT_FUNC_VERSION"gPCFunctionalityVersion" "gPCFunctionalityVersion" | |||
67 | #define AD_AT_FLAGS"flags" "flags" | |||
68 | ||||
69 | #define UAC_WORKSTATION_TRUST_ACCOUNT0x00001000 0x00001000 | |||
70 | #define AD_AGP_GUID"edacfd8f-ffb3-11d1-b41d-00a0c968f939" "edacfd8f-ffb3-11d1-b41d-00a0c968f939" | |||
71 | #define AD_AUTHENTICATED_USERS_SID"S-1-5-11" "S-1-5-11" | |||
72 | ||||
73 | /* == gpo-smb constants ==================================================== */ | |||
74 | ||||
75 | #define SMB_STANDARD_URI"smb://" "smb://" | |||
76 | ||||
77 | #define GPO_VERSION_USER(x)(x >> 16) (x >> 16) | |||
78 | #define GPO_VERSION_MACHINE(x)(x & 0xffff) (x & 0xffff) | |||
79 | ||||
80 | #define GP_EXT_GUID_SECURITY"{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" "{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" | |||
81 | #define GP_EXT_GUID_SECURITY_SUFFIX"/Microsoft/Windows NT/SecEdit/GptTmpl.inf" "/Microsoft/Windows NT/SecEdit/GptTmpl.inf" | |||
82 | ||||
83 | #ifndef SSSD_LIBEXEC_PATH"/usr/local/libexec/sssd" | |||
84 | #error "SSSD_LIBEXEC_PATH not defined" | |||
85 | #else | |||
86 | #define GPO_CHILD"/usr/local/libexec/sssd""/gpo_child" SSSD_LIBEXEC_PATH"/usr/local/libexec/sssd""/gpo_child" | |||
87 | #endif | |||
88 | ||||
89 | /* fd used by the gpo_child process for logging */ | |||
90 | int gpo_child_debug_fd = -1; | |||
91 | ||||
92 | /* == common data structures and declarations ============================= */ | |||
93 | ||||
94 | struct gp_som { | |||
95 | const char *som_dn; | |||
96 | struct gp_gplink **gplink_list; | |||
97 | int num_gplinks; | |||
98 | }; | |||
99 | ||||
100 | struct gp_gplink { | |||
101 | const char *gpo_dn; | |||
102 | bool_Bool enforced; | |||
103 | }; | |||
104 | ||||
105 | struct gp_gpo { | |||
106 | struct security_descriptor *gpo_sd; | |||
107 | const char *gpo_dn; | |||
108 | const char *gpo_guid; | |||
109 | const char *gpo_display_name; | |||
110 | const char *gpo_file_sys_path; | |||
111 | uint32_t gpo_container_version; | |||
112 | const char **gpo_cse_guids; | |||
113 | int num_gpo_cse_guids; | |||
114 | int gpo_func_version; | |||
115 | int gpo_flags; | |||
116 | }; | |||
117 | ||||
118 | enum ace_eval_status { | |||
119 | AD_GPO_ACE_DENIED, | |||
120 | AD_GPO_ACE_ALLOWED, | |||
121 | AD_GPO_ACE_NEUTRAL | |||
122 | }; | |||
123 | ||||
124 | struct tevent_req *ad_gpo_process_som_send(TALLOC_CTX *mem_ctx, | |||
125 | struct tevent_context *ev, | |||
126 | struct sdap_id_conn_ctx *conn, | |||
127 | struct ldb_context *ldb_ctx, | |||
128 | struct sdap_id_op *sdap_op, | |||
129 | struct sdap_options *opts, | |||
130 | int timeout, | |||
131 | const char *target_dn, | |||
132 | const char *domain_name); | |||
133 | int ad_gpo_process_som_recv(struct tevent_req *req, | |||
134 | TALLOC_CTX *mem_ctx, | |||
135 | struct gp_som ***som_list); | |||
136 | ||||
137 | struct tevent_req *ad_gpo_process_gpo_send(TALLOC_CTX *mem_ctx, | |||
138 | struct tevent_context *ev, | |||
139 | struct sdap_id_op *sdap_op, | |||
140 | struct sdap_options *opts, | |||
141 | char *server_hostname, | |||
142 | int timeout, | |||
143 | struct gp_som **som_list); | |||
144 | int ad_gpo_process_gpo_recv(struct tevent_req *req, | |||
145 | TALLOC_CTX *mem_ctx, | |||
146 | struct gp_gpo ***candidate_gpos, | |||
147 | int *num_candidate_gpos); | |||
148 | struct tevent_req *ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx, | |||
149 | struct tevent_context *ev, | |||
150 | char *smb_uri); | |||
151 | int ad_gpo_process_cse_recv(struct tevent_req *req, | |||
152 | TALLOC_CTX *mem_ctx, | |||
153 | int *_allowed_size, | |||
154 | char ***_allowed_sids, | |||
155 | int *_denied_size, | |||
156 | char ***_denied_sids); | |||
157 | ||||
158 | /* == ad_gpo_access_send/recv helpers =======================================*/ | |||
159 | ||||
160 | static bool_Bool | |||
161 | ad_gpo_dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2) | |||
162 | { | |||
163 | int i; | |||
164 | ||||
165 | if (sid1 == sid2) { | |||
166 | return true1; | |||
167 | } | |||
168 | ||||
169 | if (!sid1 || !sid2) { | |||
170 | return false0; | |||
171 | } | |||
172 | ||||
173 | if (sid1->sid_rev_num != sid2->sid_rev_num) { | |||
174 | return false0; | |||
175 | } | |||
176 | ||||
177 | for (i = 0; i < 6; i++) { | |||
178 | if (sid1->id_auth[i] != sid2->id_auth[i]) { | |||
179 | return false0; | |||
180 | } | |||
181 | } | |||
182 | ||||
183 | if (sid1->num_auths != sid2->num_auths) { | |||
184 | return false0; | |||
185 | } | |||
186 | ||||
187 | for (i = 0; i < sid1->num_auths; i++) { | |||
188 | if (sid1->sub_auths[i] != sid2->sub_auths[i]) { | |||
189 | return false0; | |||
190 | } | |||
191 | } | |||
192 | ||||
193 | return true1; | |||
194 | } | |||
195 | ||||
196 | ||||
197 | /* | |||
198 | * This function retrieves the SIDs corresponding to the input user and returns | |||
199 | * the user_sid, group_sids, and group_size in their respective output params. | |||
200 | * | |||
201 | * Note: since authentication must complete successfully before the | |||
202 | * gpo access checks are called, we can safely assume that the user/computer | |||
203 | * has been authenticated. As such, this function always adds the | |||
204 | * AD_AUTHENTICATED_USERS_SID to the group_sids. | |||
205 | */ | |||
206 | static errno_t | |||
207 | ad_gpo_get_sids(TALLOC_CTX *mem_ctx, | |||
208 | const char *user, | |||
209 | struct sss_domain_info *domain, | |||
210 | const char **_user_sid, | |||
211 | const char ***_group_sids, | |||
212 | int *_group_size) | |||
213 | { | |||
214 | TALLOC_CTX *tmp_ctx = NULL((void*)0); | |||
215 | struct ldb_result *res; | |||
216 | int ret = 0; | |||
217 | int i = 0; | |||
218 | int num_group_sids = 0; | |||
219 | const char *user_sid = NULL((void*)0); | |||
220 | const char *group_sid = NULL((void*)0); | |||
221 | const char **group_sids = NULL((void*)0); | |||
222 | ||||
223 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "../sssd/src/providers/ad/ad_gpo.c" ":" "223"); | |||
224 | if (tmp_ctx == NULL((void*)0)) { | |||
225 | ret = ENOMEM12; | |||
226 | goto done; | |||
227 | } | |||
228 | ||||
229 | /* first result from sysdb_initgroups is user_sid; rest are group_sids */ | |||
230 | ret = sysdb_initgroups(tmp_ctx, domain, user, &res); | |||
231 | if (ret != EOK0) { | |||
232 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 234, __FUNCTION__, __debug_macro_level, "sysdb_initgroups failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
233 | "sysdb_initgroups failed: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 234, __FUNCTION__, __debug_macro_level, "sysdb_initgroups failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
234 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 234, __FUNCTION__, __debug_macro_level, "sysdb_initgroups failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
235 | return ret; | |||
236 | } | |||
237 | ||||
238 | if (res->count == 0) { | |||
239 | ret = ENOENT2; | |||
240 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 241, __FUNCTION__, __debug_macro_level, "sysdb_initgroups returned empty result\n" ); } } while (0) | |||
241 | "sysdb_initgroups returned empty result\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 241, __FUNCTION__, __debug_macro_level, "sysdb_initgroups returned empty result\n" ); } } while (0); | |||
242 | return ret; | |||
243 | } | |||
244 | ||||
245 | user_sid = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SID_STR"objectSIDString", NULL((void*)0)); | |||
246 | num_group_sids = (res->count) - 1; | |||
247 | ||||
248 | /* include space for AD_AUTHENTICATED_USERS_SID and NULL */ | |||
249 | group_sids = talloc_array(tmp_ctx, const char *, num_group_sids + 1 + 1)(const char * *)_talloc_array(tmp_ctx, sizeof(const char *), num_group_sids + 1 + 1, "const char *"); | |||
250 | if (group_sids == NULL((void*)0)) { | |||
251 | ret = ENOMEM12; | |||
252 | goto done; | |||
253 | } | |||
254 | ||||
255 | for (i = 0; i < num_group_sids; i++) { | |||
256 | group_sid = ldb_msg_find_attr_as_string(res->msgs[i+1], | |||
257 | SYSDB_SID_STR"objectSIDString", NULL((void*)0)); | |||
258 | if (group_sid == NULL((void*)0)) { | |||
259 | continue; | |||
260 | } | |||
261 | ||||
262 | group_sids[i] = talloc_steal(group_sids, group_sid)({ __typeof__(group_sid) __talloc_steal_ret = (__typeof__(group_sid ))_talloc_steal_loc((group_sids),(group_sid), "../sssd/src/providers/ad/ad_gpo.c" ":" "262"); __talloc_steal_ret; }); | |||
263 | if (group_sids[i] == NULL((void*)0)) { | |||
264 | ret = ENOMEM12; | |||
265 | goto done; | |||
266 | } | |||
267 | } | |||
268 | group_sids[i++] = talloc_strdup(group_sids, AD_AUTHENTICATED_USERS_SID"S-1-5-11"); | |||
269 | group_sids[i] = NULL((void*)0); | |||
270 | ||||
271 | *_group_size = num_group_sids + 1; | |||
272 | *_group_sids = talloc_steal(mem_ctx, group_sids)({ __typeof__(group_sids) __talloc_steal_ret = (__typeof__(group_sids ))_talloc_steal_loc((mem_ctx),(group_sids), "../sssd/src/providers/ad/ad_gpo.c" ":" "272"); __talloc_steal_ret; }); | |||
273 | *_user_sid = talloc_steal(mem_ctx, user_sid)({ __typeof__(user_sid) __talloc_steal_ret = (__typeof__(user_sid ))_talloc_steal_loc((mem_ctx),(user_sid), "../sssd/src/providers/ad/ad_gpo.c" ":" "273"); __talloc_steal_ret; }); | |||
274 | return EOK0; | |||
275 | ||||
276 | done: | |||
277 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "../sssd/src/providers/ad/ad_gpo.c" ":" "277"); | |||
278 | return ret; | |||
279 | } | |||
280 | ||||
281 | /* | |||
282 | * This function determines whether the input ace_dom_sid matches any of the | |||
283 | * client's SIDs. The boolean result is assigned to the _included output param. | |||
284 | */ | |||
285 | static errno_t | |||
286 | ad_gpo_ace_includes_client_sid(const char *user_sid, | |||
287 | const char **group_sids, | |||
288 | int group_size, | |||
289 | struct dom_sid ace_dom_sid, | |||
290 | struct sss_idmap_ctx *idmap_ctx, | |||
291 | bool_Bool *_included) | |||
292 | { | |||
293 | int i = 0; | |||
294 | struct dom_sid *user_dom_sid; | |||
295 | struct dom_sid *group_dom_sid; | |||
296 | enum idmap_error_code err; | |||
297 | bool_Bool included = false0; | |||
298 | ||||
299 | err = sss_idmap_sid_to_smb_sid(idmap_ctx, user_sid, &user_dom_sid); | |||
300 | if (err != IDMAP_SUCCESS) { | |||
301 | DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize idmap context.\n")do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 301, __FUNCTION__, __debug_macro_level, "Failed to initialize idmap context.\n" ); } } while (0); | |||
302 | return EFAULT14; | |||
303 | } | |||
304 | ||||
305 | included = ad_gpo_dom_sid_equal(&ace_dom_sid, user_dom_sid); | |||
306 | sss_idmap_free_smb_sid(idmap_ctx, user_dom_sid); | |||
307 | if (included) { | |||
308 | *_included = true1; | |||
309 | return EOK0; | |||
310 | } | |||
311 | ||||
312 | for (i = 0; i < group_size; i++) { | |||
313 | err = sss_idmap_sid_to_smb_sid(idmap_ctx, group_sids[i], &group_dom_sid); | |||
314 | if (err != IDMAP_SUCCESS) { | |||
315 | DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize idmap context.\n")do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 315, __FUNCTION__, __debug_macro_level, "Failed to initialize idmap context.\n" ); } } while (0); | |||
316 | return EFAULT14; | |||
317 | } | |||
318 | included = ad_gpo_dom_sid_equal(&ace_dom_sid, group_dom_sid); | |||
319 | sss_idmap_free_smb_sid(idmap_ctx, group_dom_sid); | |||
320 | if (included) { | |||
321 | *_included = true1; | |||
322 | return EOK0; | |||
323 | } | |||
324 | } | |||
325 | ||||
326 | *_included = false0; | |||
327 | return EOK0; | |||
328 | } | |||
329 | ||||
330 | /* | |||
331 | * This function determines whether use of the extended right | |||
332 | * named "ApplyGroupPolicy" (AGP) is allowed, by comparing the specified | |||
333 | * user_sid and group_sids against the specified access control entry (ACE). | |||
334 | * This function returns ALLOWED, DENIED, or NEUTRAL depending on whether | |||
335 | * the ACE explictly allows, explicitly denies, or does neither. | |||
336 | * | |||
337 | * Note that the 'M' abbreviation used in the evaluation algorithm stands for | |||
338 | * "access_mask", which represents the set of access rights associated with an | |||
339 | * individual ACE. The access right of interest to the GPO code is | |||
340 | * RIGHT_DS_CONTROL_ACCESS, which serves as a container for all control access | |||
341 | * rights. The specific control access right is identified by a GUID in the | |||
342 | * ACE's ObjectType. In our case, this is the GUID corresponding to AGP. | |||
343 | * | |||
344 | * The ACE evaluation algorithm is specified in [MS-ADTS] 5.1.3.3.4: | |||
345 | * - Deny access by default | |||
346 | * - If the "Inherit Only" (IO) flag is set in the ACE, skip the ACE. | |||
347 | * - If the SID in the ACE does not match any SID in the requester's | |||
348 | * security context, skip the ACE | |||
349 | * - If the ACE type is "Object Access Allowed", the access right | |||
350 | * RIGHT_DS_CONTROL_ACCESS (CR) is present in M, and the ObjectType | |||
351 | * field in the ACE is either not present OR contains a GUID value equal | |||
352 | * to AGP, then grant requested control access right. Stop access checking. | |||
353 | * - If the ACE type is "Object Access Denied", the access right | |||
354 | * RIGHT_DS_CONTROL_ACCESS (CR) is present in M, and the ObjectType | |||
355 | * field in the ACE is either not present OR contains a GUID value equal to | |||
356 | * AGP, then deny the requested control access right. Stop access checking. | |||
357 | */ | |||
358 | static enum ace_eval_status ad_gpo_evaluate_ace(struct security_ace *ace, | |||
359 | struct sss_idmap_ctx *idmap_ctx, | |||
360 | const char *user_sid, | |||
361 | const char **group_sids, | |||
362 | int group_size) | |||
363 | { | |||
364 | bool_Bool agp_included = false0; | |||
365 | bool_Bool included = false0; | |||
366 | int ret = 0; | |||
367 | struct security_ace_object object; | |||
368 | struct GUID ext_right_agp_guid; | |||
369 | ||||
370 | if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY( 0x08 )) { | |||
371 | return AD_GPO_ACE_NEUTRAL; | |||
372 | } | |||
373 | ||||
374 | ret = ad_gpo_ace_includes_client_sid(user_sid, group_sids, group_size, | |||
375 | ace->trustee, idmap_ctx, &included); | |||
376 | ||||
377 | if (ret != EOK0) { | |||
378 | return AD_GPO_ACE_DENIED; | |||
379 | } | |||
380 | ||||
381 | if (!included) { | |||
382 | return AD_GPO_ACE_NEUTRAL; | |||
383 | } | |||
384 | ||||
385 | object = ace->object.object; | |||
386 | GUID_from_string(AD_AGP_GUID"edacfd8f-ffb3-11d1-b41d-00a0c968f939", &ext_right_agp_guid); | |||
387 | ||||
388 | if (object.flags & SEC_ACE_OBJECT_TYPE_PRESENT( 0x00000001 )) { | |||
389 | if (GUID_equal(&object.type.type, &ext_right_agp_guid)) { | |||
390 | agp_included = true1; | |||
391 | } | |||
392 | } else { | |||
393 | agp_included = false0; | |||
394 | } | |||
395 | ||||
396 | if (ace->access_mask & SEC_ADS_CONTROL_ACCESS( 0x00000100 )) { | |||
397 | if (agp_included) { | |||
398 | if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) { | |||
399 | return AD_GPO_ACE_ALLOWED; | |||
400 | } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT) { | |||
401 | return AD_GPO_ACE_DENIED; | |||
402 | } | |||
403 | } | |||
404 | } | |||
405 | ||||
406 | return AD_GPO_ACE_DENIED; | |||
407 | } | |||
408 | ||||
409 | /* | |||
410 | * This function extracts the GPO's DACL (discretionary access control list) | |||
411 | * from the GPO's specified security descriptor, and determines whether | |||
412 | * the GPO is applicable to the policy target, by comparing the specified | |||
413 | * user_sid and group_sids against each access control entry (ACE) in the DACL. | |||
414 | * The boolean result is assigned to the _access_allowed output parameter. | |||
415 | */ | |||
416 | static errno_t ad_gpo_evaluate_dacl(struct security_acl *dacl, | |||
417 | struct sss_idmap_ctx *idmap_ctx, | |||
418 | const char *user_sid, | |||
419 | const char **group_sids, | |||
420 | int group_size, | |||
421 | bool_Bool *_dacl_access_allowed) | |||
422 | { | |||
423 | uint32_t num_aces = 0; | |||
424 | enum ace_eval_status ace_status; | |||
425 | int i = 0; | |||
426 | struct security_ace *ace = NULL((void*)0); | |||
427 | ||||
428 | num_aces = dacl->num_aces; | |||
429 | ||||
430 | /* | |||
431 | * [MS-ADTS] 5.1.3.3.4: | |||
432 | * If the DACL does not have any ACE, then deny the requester the | |||
433 | * requested control access right. | |||
434 | */ | |||
435 | if (num_aces == 0) { | |||
436 | *_dacl_access_allowed = false0; | |||
437 | return EOK0; | |||
438 | } | |||
439 | ||||
440 | for (i = 0; i < dacl->num_aces; i ++) { | |||
441 | ace = &dacl->aces[i]; | |||
442 | ||||
443 | ace_status = ad_gpo_evaluate_ace(ace, idmap_ctx, user_sid, | |||
444 | group_sids, group_size); | |||
445 | ||||
446 | switch (ace_status) { | |||
447 | case AD_GPO_ACE_NEUTRAL: | |||
448 | continue; | |||
449 | case AD_GPO_ACE_ALLOWED: | |||
450 | *_dacl_access_allowed = true1; | |||
451 | return EOK0; | |||
452 | case AD_GPO_ACE_DENIED: | |||
453 | *_dacl_access_allowed = false0; | |||
454 | return EOK0; | |||
455 | } | |||
456 | } | |||
457 | ||||
458 | *_dacl_access_allowed = false0; | |||
459 | return EOK0; | |||
460 | } | |||
461 | ||||
462 | /* | |||
463 | * This function takes candidate_gpos as input, filters out any gpo that is | |||
464 | * not applicable to the policy target and assigns the result to the | |||
465 | * _dacl_filtered_gpos output parameter. The filtering algorithm is | |||
466 | * defined in [MS-GPOL] 3.2.5.1.6 | |||
467 | */ | |||
468 | ||||
469 | static errno_t | |||
470 | ad_gpo_filter_gpos_by_dacl(TALLOC_CTX *mem_ctx, | |||
471 | const char *user, | |||
472 | struct sss_domain_info *domain, | |||
473 | struct sss_idmap_ctx *idmap_ctx, | |||
474 | struct gp_gpo **candidate_gpos, | |||
475 | int num_candidate_gpos, | |||
476 | struct gp_gpo ***_dacl_filtered_gpos, | |||
477 | int *_num_dacl_filtered_gpos) | |||
478 | { | |||
479 | TALLOC_CTX *tmp_ctx = NULL((void*)0); | |||
480 | int i = 0; | |||
481 | int ret = 0; | |||
482 | struct gp_gpo *candidate_gpo = NULL((void*)0); | |||
483 | struct security_descriptor *sd = NULL((void*)0); | |||
484 | struct security_acl *dacl = NULL((void*)0); | |||
485 | const char *user_sid = NULL((void*)0); | |||
486 | const char **group_sids = NULL((void*)0); | |||
487 | int group_size = 0; | |||
488 | int gpo_dn_idx = 0; | |||
489 | bool_Bool access_allowed = false0; | |||
490 | struct gp_gpo **dacl_filtered_gpos = NULL((void*)0); | |||
491 | ||||
492 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "../sssd/src/providers/ad/ad_gpo.c" ":" "492"); | |||
493 | if (tmp_ctx == NULL((void*)0)) { | |||
494 | ret = ENOMEM12; | |||
495 | goto done; | |||
496 | } | |||
497 | ||||
498 | ret = ad_gpo_get_sids(tmp_ctx, user, domain, &user_sid, | |||
499 | &group_sids, &group_size); | |||
500 | if (ret != EOK0) { | |||
501 | ret = ERR_NO_SIDS; | |||
502 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 503, __FUNCTION__, __debug_macro_level, "Unable to retrieve SIDs: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
503 | "Unable to retrieve SIDs: [%d](%s)\n", ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 503, __FUNCTION__, __debug_macro_level, "Unable to retrieve SIDs: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
504 | goto done; | |||
505 | } | |||
506 | ||||
507 | dacl_filtered_gpos = talloc_array(tmp_ctx,(struct gp_gpo * *)_talloc_array(tmp_ctx, sizeof(struct gp_gpo *), num_candidate_gpos + 1, "struct gp_gpo *") | |||
508 | struct gp_gpo *,(struct gp_gpo * *)_talloc_array(tmp_ctx, sizeof(struct gp_gpo *), num_candidate_gpos + 1, "struct gp_gpo *") | |||
509 | num_candidate_gpos + 1)(struct gp_gpo * *)_talloc_array(tmp_ctx, sizeof(struct gp_gpo *), num_candidate_gpos + 1, "struct gp_gpo *"); | |||
510 | ||||
511 | if (dacl_filtered_gpos == NULL((void*)0)) { | |||
512 | ret = ENOMEM12; | |||
513 | goto done; | |||
514 | } | |||
515 | ||||
516 | for (i = 0; i < num_candidate_gpos; i++) { | |||
517 | ||||
518 | access_allowed = false0; | |||
519 | candidate_gpo = candidate_gpos[i]; | |||
520 | sd = candidate_gpo->gpo_sd; | |||
521 | dacl = candidate_gpo->gpo_sd->dacl; | |||
522 | ||||
523 | DEBUG(SSSDBG_TRACE_ALL, "examining dacl candidate_gpo_guid:%s\n",do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 524, __FUNCTION__, __debug_macro_level, "examining dacl candidate_gpo_guid:%s\n" , candidate_gpo->gpo_guid); } } while (0) | |||
524 | candidate_gpo->gpo_guid)do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 524, __FUNCTION__, __debug_macro_level, "examining dacl candidate_gpo_guid:%s\n" , candidate_gpo->gpo_guid); } } while (0); | |||
525 | ||||
526 | /* gpo_func_version must be set to version 2 */ | |||
527 | if (candidate_gpo->gpo_func_version != 2) { | |||
528 | DEBUG(SSSDBG_TRACE_ALL,do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 529, __FUNCTION__, __debug_macro_level, "GPO not applicable to target per security filtering\n" ); } } while (0) | |||
529 | "GPO not applicable to target per security filtering\n")do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 529, __FUNCTION__, __debug_macro_level, "GPO not applicable to target per security filtering\n" ); } } while (0); | |||
530 | continue; | |||
531 | } | |||
532 | ||||
533 | /* gpo_flags value of 2 means that GPO's computer portion is disabled */ | |||
534 | if (candidate_gpo->gpo_flags == 2) { | |||
535 | DEBUG(SSSDBG_TRACE_ALL,do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 536, __FUNCTION__, __debug_macro_level, "GPO not applicable to target per security filtering\n" ); } } while (0) | |||
536 | "GPO not applicable to target per security filtering\n")do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 536, __FUNCTION__, __debug_macro_level, "GPO not applicable to target per security filtering\n" ); } } while (0); | |||
537 | continue; | |||
538 | } | |||
539 | ||||
540 | /* | |||
541 | * [MS-ADTS] 5.1.3.3.4: | |||
542 | * If the security descriptor has no DACL or its "DACL Present" bit | |||
543 | * is not set, then grant requester the requested control access right. | |||
544 | */ | |||
545 | ||||
546 | if ((!(sd->type & SEC_DESC_DACL_PRESENT( 0x0004 ))) || (dacl == NULL((void*)0))) { | |||
547 | DEBUG(SSSDBG_TRACE_ALL, "DACL is not present\n")do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 547, __FUNCTION__, __debug_macro_level, "DACL is not present\n" ); } } while (0); | |||
548 | access_allowed = true1; | |||
549 | break; | |||
550 | } | |||
551 | ||||
552 | ad_gpo_evaluate_dacl(dacl, idmap_ctx, user_sid, group_sids, | |||
553 | group_size, &access_allowed); | |||
554 | if (access_allowed) { | |||
555 | DEBUG(SSSDBG_TRACE_ALL,do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 556, __FUNCTION__, __debug_macro_level, "GPO applicable to target per security filtering\n" ); } } while (0) | |||
556 | "GPO applicable to target per security filtering\n")do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 556, __FUNCTION__, __debug_macro_level, "GPO applicable to target per security filtering\n" ); } } while (0); | |||
557 | dacl_filtered_gpos[gpo_dn_idx] = talloc_steal(dacl_filtered_gpos,({ __typeof__(candidate_gpo) __talloc_steal_ret = (__typeof__ (candidate_gpo))_talloc_steal_loc((dacl_filtered_gpos),(candidate_gpo ), "../sssd/src/providers/ad/ad_gpo.c" ":" "558"); __talloc_steal_ret ; }) | |||
558 | candidate_gpo)({ __typeof__(candidate_gpo) __talloc_steal_ret = (__typeof__ (candidate_gpo))_talloc_steal_loc((dacl_filtered_gpos),(candidate_gpo ), "../sssd/src/providers/ad/ad_gpo.c" ":" "558"); __talloc_steal_ret ; }); | |||
559 | gpo_dn_idx++; | |||
560 | } else { | |||
561 | DEBUG(SSSDBG_TRACE_ALL,do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 562, __FUNCTION__, __debug_macro_level, "GPO not applicable to target per security filtering\n" ); } } while (0) | |||
562 | "GPO not applicable to target per security filtering\n")do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 562, __FUNCTION__, __debug_macro_level, "GPO not applicable to target per security filtering\n" ); } } while (0); | |||
563 | continue; | |||
564 | } | |||
565 | } | |||
566 | ||||
567 | dacl_filtered_gpos[gpo_dn_idx] = NULL((void*)0); | |||
568 | ||||
569 | *_dacl_filtered_gpos = talloc_steal(mem_ctx, dacl_filtered_gpos)({ __typeof__(dacl_filtered_gpos) __talloc_steal_ret = (__typeof__ (dacl_filtered_gpos))_talloc_steal_loc((mem_ctx),(dacl_filtered_gpos ), "../sssd/src/providers/ad/ad_gpo.c" ":" "569"); __talloc_steal_ret ; }); | |||
570 | *_num_dacl_filtered_gpos = gpo_dn_idx; | |||
571 | ||||
572 | ret = EOK0; | |||
573 | ||||
574 | done: | |||
575 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "../sssd/src/providers/ad/ad_gpo.c" ":" "575"); | |||
576 | return ret; | |||
577 | } | |||
578 | ||||
579 | /* | |||
580 | * This function determines whether the input cse_guid matches any of the input | |||
581 | * gpo_cse_guids. The boolean result is assigned to the _included output param. | |||
582 | */ | |||
583 | static bool_Bool | |||
584 | ad_gpo_includes_cse_guid(const char *cse_guid, | |||
585 | const char **gpo_cse_guids, | |||
586 | int num_gpo_cse_guids) | |||
587 | { | |||
588 | int i = 0; | |||
589 | const char *gpo_cse_guid = NULL((void*)0); | |||
590 | ||||
591 | for (i = 0; i < num_gpo_cse_guids; i++) { | |||
592 | gpo_cse_guid = gpo_cse_guids[i]; | |||
593 | if (strcmp(gpo_cse_guid, cse_guid)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (gpo_cse_guid) && __builtin_constant_p (cse_guid) && (__s1_len = strlen (gpo_cse_guid), __s2_len = strlen (cse_guid ), (!((size_t)(const void *)((gpo_cse_guid) + 1) - (size_t)(const void *)(gpo_cse_guid) == 1) || __s1_len >= 4) && ( !((size_t)(const void *)((cse_guid) + 1) - (size_t)(const void *)(cse_guid) == 1) || __s2_len >= 4)) ? __builtin_strcmp ( gpo_cse_guid, cse_guid) : (__builtin_constant_p (gpo_cse_guid ) && ((size_t)(const void *)((gpo_cse_guid) + 1) - (size_t )(const void *)(gpo_cse_guid) == 1) && (__s1_len = strlen (gpo_cse_guid), __s1_len < 4) ? (__builtin_constant_p (cse_guid ) && ((size_t)(const void *)((cse_guid) + 1) - (size_t )(const void *)(cse_guid) == 1) ? __builtin_strcmp (gpo_cse_guid , cse_guid) : (__extension__ ({ const unsigned char *__s2 = ( const unsigned char *) (const char *) (cse_guid); int __result = (((const unsigned char *) (const char *) (gpo_cse_guid))[0 ] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (gpo_cse_guid ))[1] - __s2[1]); if (__s1_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (gpo_cse_guid ))[2] - __s2[2]); if (__s1_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (gpo_cse_guid ))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ( cse_guid) && ((size_t)(const void *)((cse_guid) + 1) - (size_t)(const void *)(cse_guid) == 1) && (__s2_len = strlen (cse_guid), __s2_len < 4) ? (__builtin_constant_p ( gpo_cse_guid) && ((size_t)(const void *)((gpo_cse_guid ) + 1) - (size_t)(const void *)(gpo_cse_guid) == 1) ? __builtin_strcmp (gpo_cse_guid, cse_guid) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (gpo_cse_guid ); int __result = (((const unsigned char *) (const char *) (cse_guid ))[0] - __s2[0]); if (__s2_len > 0 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (cse_guid ))[1] - __s2[1]); if (__s2_len > 1 && __result == 0 ) { __result = (((const unsigned char *) (const char *) (cse_guid ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0 ) __result = (((const unsigned char *) (const char *) (cse_guid ))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (gpo_cse_guid , cse_guid)))); }) == 0) { | |||
594 | return true1; | |||
595 | } | |||
596 | } | |||
597 | ||||
598 | return false0; | |||
599 | } | |||
600 | ||||
601 | /* | |||
602 | * This function takes an input dacl_filtered_gpos list, filters out any gpo | |||
603 | * that does not contain the input cse_guid, and assigns the result to the | |||
604 | * _cse_filtered_gpos output parameter. | |||
605 | */ | |||
606 | static errno_t | |||
607 | ad_gpo_filter_gpos_by_cse_guid(TALLOC_CTX *mem_ctx, | |||
608 | const char *cse_guid, | |||
609 | struct gp_gpo **dacl_filtered_gpos, | |||
610 | int num_dacl_filtered_gpos, | |||
611 | struct gp_gpo ***_cse_filtered_gpos, | |||
612 | int *_num_cse_filtered_gpos) | |||
613 | { | |||
614 | TALLOC_CTX *tmp_ctx = NULL((void*)0); | |||
615 | int i = 0; | |||
616 | int ret = 0; | |||
617 | struct gp_gpo *dacl_filtered_gpo = NULL((void*)0); | |||
618 | int gpo_dn_idx = 0; | |||
619 | struct gp_gpo **cse_filtered_gpos = NULL((void*)0); | |||
620 | bool_Bool included; | |||
621 | ||||
622 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "../sssd/src/providers/ad/ad_gpo.c" ":" "622"); | |||
623 | if (tmp_ctx == NULL((void*)0)) { | |||
624 | ret = ENOMEM12; | |||
625 | goto done; | |||
626 | } | |||
627 | ||||
628 | cse_filtered_gpos = talloc_array(tmp_ctx,(struct gp_gpo * *)_talloc_array(tmp_ctx, sizeof(struct gp_gpo *), num_dacl_filtered_gpos + 1, "struct gp_gpo *") | |||
629 | struct gp_gpo *,(struct gp_gpo * *)_talloc_array(tmp_ctx, sizeof(struct gp_gpo *), num_dacl_filtered_gpos + 1, "struct gp_gpo *") | |||
630 | num_dacl_filtered_gpos + 1)(struct gp_gpo * *)_talloc_array(tmp_ctx, sizeof(struct gp_gpo *), num_dacl_filtered_gpos + 1, "struct gp_gpo *"); | |||
631 | if (cse_filtered_gpos == NULL((void*)0)) { | |||
632 | ret = ENOMEM12; | |||
633 | goto done; | |||
634 | } | |||
635 | ||||
636 | for (i = 0; i < num_dacl_filtered_gpos; i++) { | |||
637 | ||||
638 | dacl_filtered_gpo = dacl_filtered_gpos[i]; | |||
639 | ||||
640 | DEBUG(SSSDBG_TRACE_ALL, "examining cse candidate_gpo_guid: %s\n",do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 641, __FUNCTION__, __debug_macro_level, "examining cse candidate_gpo_guid: %s\n" , dacl_filtered_gpo->gpo_guid); } } while (0) | |||
641 | dacl_filtered_gpo->gpo_guid)do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 641, __FUNCTION__, __debug_macro_level, "examining cse candidate_gpo_guid: %s\n" , dacl_filtered_gpo->gpo_guid); } } while (0); | |||
642 | ||||
643 | included = ad_gpo_includes_cse_guid(cse_guid, | |||
644 | dacl_filtered_gpo->gpo_cse_guids, | |||
645 | dacl_filtered_gpo->num_gpo_cse_guids); | |||
646 | ||||
647 | if (included) { | |||
648 | DEBUG(SSSDBG_TRACE_ALL,do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 649, __FUNCTION__, __debug_macro_level, "GPO applicable to target per cse_guid filtering\n" ); } } while (0) | |||
649 | "GPO applicable to target per cse_guid filtering\n")do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 649, __FUNCTION__, __debug_macro_level, "GPO applicable to target per cse_guid filtering\n" ); } } while (0); | |||
650 | cse_filtered_gpos[gpo_dn_idx] = talloc_steal(cse_filtered_gpos,({ __typeof__(dacl_filtered_gpo) __talloc_steal_ret = (__typeof__ (dacl_filtered_gpo))_talloc_steal_loc((cse_filtered_gpos),(dacl_filtered_gpo ), "../sssd/src/providers/ad/ad_gpo.c" ":" "651"); __talloc_steal_ret ; }) | |||
651 | dacl_filtered_gpo)({ __typeof__(dacl_filtered_gpo) __talloc_steal_ret = (__typeof__ (dacl_filtered_gpo))_talloc_steal_loc((cse_filtered_gpos),(dacl_filtered_gpo ), "../sssd/src/providers/ad/ad_gpo.c" ":" "651"); __talloc_steal_ret ; }); | |||
652 | dacl_filtered_gpos[i] = NULL((void*)0); | |||
653 | gpo_dn_idx++; | |||
654 | } else { | |||
655 | DEBUG(SSSDBG_TRACE_ALL,do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 656, __FUNCTION__, __debug_macro_level, "GPO not applicable to target per cse_guid filtering\n" ); } } while (0) | |||
656 | "GPO not applicable to target per cse_guid filtering\n")do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 656, __FUNCTION__, __debug_macro_level, "GPO not applicable to target per cse_guid filtering\n" ); } } while (0); | |||
657 | continue; | |||
658 | } | |||
659 | } | |||
660 | ||||
661 | cse_filtered_gpos[gpo_dn_idx] = NULL((void*)0); | |||
662 | ||||
663 | *_cse_filtered_gpos = talloc_steal(mem_ctx, cse_filtered_gpos)({ __typeof__(cse_filtered_gpos) __talloc_steal_ret = (__typeof__ (cse_filtered_gpos))_talloc_steal_loc((mem_ctx),(cse_filtered_gpos ), "../sssd/src/providers/ad/ad_gpo.c" ":" "663"); __talloc_steal_ret ; }); | |||
664 | *_num_cse_filtered_gpos = gpo_dn_idx; | |||
665 | ||||
666 | ret = EOK0; | |||
667 | ||||
668 | done: | |||
669 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "../sssd/src/providers/ad/ad_gpo.c" ":" "669"); | |||
670 | return ret; | |||
671 | } | |||
672 | ||||
673 | /* | |||
674 | * This cse-specific function (GP_EXT_GUID_SECURITY) populates the output | |||
675 | * parameter (found) based on whether the input user_sid or any of the input | |||
676 | * group_sids appear in the input list of privilege_sids. | |||
677 | */ | |||
678 | static bool_Bool | |||
679 | check_rights(char **privilege_sids, | |||
680 | int privilege_size, | |||
681 | const char *user_sid, | |||
682 | const char **group_sids, | |||
683 | int group_size) | |||
684 | { | |||
685 | int i, j; | |||
686 | ||||
687 | for (i = 0; i < privilege_size; i++) { | |||
688 | if (strcmp(user_sid, privilege_sids[i])__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (user_sid) && __builtin_constant_p (privilege_sids[i ]) && (__s1_len = strlen (user_sid), __s2_len = strlen (privilege_sids[i]), (!((size_t)(const void *)((user_sid) + 1 ) - (size_t)(const void *)(user_sid) == 1) || __s1_len >= 4 ) && (!((size_t)(const void *)((privilege_sids[i]) + 1 ) - (size_t)(const void *)(privilege_sids[i]) == 1) || __s2_len >= 4)) ? __builtin_strcmp (user_sid, privilege_sids[i]) : (__builtin_constant_p (user_sid) && ((size_t)(const void *)((user_sid) + 1) - (size_t)(const void *)(user_sid) == 1) && (__s1_len = strlen (user_sid), __s1_len < 4) ? (__builtin_constant_p (privilege_sids[i]) && ((size_t)(const void *)((privilege_sids [i]) + 1) - (size_t)(const void *)(privilege_sids[i]) == 1) ? __builtin_strcmp (user_sid, privilege_sids[i]) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (privilege_sids[i]); int __result = (((const unsigned char *) (const char *) (user_sid))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (user_sid))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (user_sid))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (user_sid))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p (privilege_sids[i]) && ((size_t)(const void *)((privilege_sids[i]) + 1) - (size_t)( const void *)(privilege_sids[i]) == 1) && (__s2_len = strlen (privilege_sids[i]), __s2_len < 4) ? (__builtin_constant_p (user_sid) && ((size_t)(const void *)((user_sid) + 1 ) - (size_t)(const void *)(user_sid) == 1) ? __builtin_strcmp (user_sid, privilege_sids[i]) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (user_sid ); int __result = (((const unsigned char *) (const char *) (privilege_sids [i]))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (privilege_sids [i]))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (privilege_sids [i]))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (privilege_sids [i]))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp ( user_sid, privilege_sids[i])))); }) == 0) { | |||
689 | return true1; | |||
690 | } | |||
691 | for (j = 0; j < group_size; j++) { | |||
692 | if (strcmp(group_sids[j], privilege_sids[i])__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (group_sids[j]) && __builtin_constant_p (privilege_sids [i]) && (__s1_len = strlen (group_sids[j]), __s2_len = strlen (privilege_sids[i]), (!((size_t)(const void *)((group_sids [j]) + 1) - (size_t)(const void *)(group_sids[j]) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((privilege_sids [i]) + 1) - (size_t)(const void *)(privilege_sids[i]) == 1) || __s2_len >= 4)) ? __builtin_strcmp (group_sids[j], privilege_sids [i]) : (__builtin_constant_p (group_sids[j]) && ((size_t )(const void *)((group_sids[j]) + 1) - (size_t)(const void *) (group_sids[j]) == 1) && (__s1_len = strlen (group_sids [j]), __s1_len < 4) ? (__builtin_constant_p (privilege_sids [i]) && ((size_t)(const void *)((privilege_sids[i]) + 1) - (size_t)(const void *)(privilege_sids[i]) == 1) ? __builtin_strcmp (group_sids[j], privilege_sids[i]) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (privilege_sids[i]); int __result = (((const unsigned char * ) (const char *) (group_sids[j]))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (group_sids[j]))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (group_sids[j]))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (group_sids[j]))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p (privilege_sids[i]) && ((size_t)(const void *)((privilege_sids[i]) + 1) - (size_t)( const void *)(privilege_sids[i]) == 1) && (__s2_len = strlen (privilege_sids[i]), __s2_len < 4) ? (__builtin_constant_p (group_sids[j]) && ((size_t)(const void *)((group_sids [j]) + 1) - (size_t)(const void *)(group_sids[j]) == 1) ? __builtin_strcmp (group_sids[j], privilege_sids[i]) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (group_sids[j]); int __result = (((const unsigned char *) (const char *) (privilege_sids[i]))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (privilege_sids[i]))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (privilege_sids[i]))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (privilege_sids[i]))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (group_sids[j], privilege_sids [i])))); }) == 0) { | |||
693 | return true1; | |||
694 | } | |||
695 | } | |||
696 | } | |||
697 | ||||
698 | return false0; | |||
699 | } | |||
700 | ||||
701 | /* | |||
702 | * This cse-specific function (GP_EXT_GUID_SECURITY) performs HBAC policy | |||
703 | * application and determines whether logon access is granted or denied for | |||
704 | * the {user,domain} tuple specified in the inputs. This function returns EOK | |||
705 | * to indicate that access is granted. Any other return value indicates that | |||
706 | * access is denied. | |||
707 | * | |||
708 | * The access control algorithm first determines whether the "principal_sids" | |||
709 | * (i.e. user_sid or group_sids) appear in allowed_sids and denied_sids. | |||
710 | * | |||
711 | * For access to be granted, both the "allowed_sids_condition" *and* the | |||
712 | * "denied_sids_condition" must be met (in all other cases, access is denied). | |||
713 | * 1) The "allowed_sids_condition" is satisfied if any of the principal_sids | |||
714 | * appears in allowed_sids OR if the allowed_sids list is empty | |||
715 | * 2) The "denied_sids_condition" is satisfied if none of the principal_sids | |||
716 | * appear in denied_sids | |||
717 | * | |||
718 | * Note that a deployment that is unaware of GPO-based access-control policy | |||
719 | * settings is unaffected by them (b/c the absence of allowed_sids grants access). | |||
720 | * | |||
721 | * Note that if a principal_sid appears in both allowed_sids and denied_sids, | |||
722 | * the "allowed_sids_condition" is met, but the "denied_sids_condition" is not. | |||
723 | * In other words, Deny takes precedence over Allow. | |||
724 | */ | |||
725 | static errno_t | |||
726 | ad_gpo_access_check(TALLOC_CTX *mem_ctx, | |||
727 | const char *user, | |||
728 | struct sss_domain_info *domain, | |||
729 | char **allowed_sids, | |||
730 | int allowed_size, | |||
731 | char **denied_sids, | |||
732 | int denied_size) | |||
733 | { | |||
734 | const char *user_sid; | |||
735 | const char **group_sids; | |||
736 | int group_size = 0; | |||
737 | bool_Bool access_granted = false0; | |||
738 | bool_Bool access_denied = false0; | |||
739 | int ret; | |||
740 | int j; | |||
741 | ||||
742 | DEBUG(SSSDBG_TRACE_FUNC, "POLICY FILE:\n")do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 742, __FUNCTION__, __debug_macro_level, "POLICY FILE:\n"); } } while (0); | |||
743 | DEBUG(SSSDBG_TRACE_FUNC, "allowed_size = %d\n", allowed_size)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 743, __FUNCTION__, __debug_macro_level, "allowed_size = %d\n" , allowed_size); } } while (0); | |||
744 | for (j= 0; j < allowed_size; j++) { | |||
745 | DEBUG(SSSDBG_TRACE_FUNC, "allowed_sids[%d] = %s\n", j,do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 746, __FUNCTION__, __debug_macro_level, "allowed_sids[%d] = %s\n" , j, allowed_sids[j]); } } while (0) | |||
746 | allowed_sids[j])do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 746, __FUNCTION__, __debug_macro_level, "allowed_sids[%d] = %s\n" , j, allowed_sids[j]); } } while (0); | |||
747 | } | |||
748 | ||||
749 | DEBUG(SSSDBG_TRACE_FUNC, "denied_size = %d\n", denied_size)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 749, __FUNCTION__, __debug_macro_level, "denied_size = %d\n" , denied_size); } } while (0); | |||
750 | for (j= 0; j < denied_size; j++) { | |||
751 | DEBUG(SSSDBG_TRACE_FUNC, " denied_sids[%d] = %s\n", j,do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 752, __FUNCTION__, __debug_macro_level, " denied_sids[%d] = %s\n" , j, denied_sids[j]); } } while (0) | |||
752 | denied_sids[j])do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 752, __FUNCTION__, __debug_macro_level, " denied_sids[%d] = %s\n" , j, denied_sids[j]); } } while (0); | |||
753 | } | |||
754 | ||||
755 | ret = ad_gpo_get_sids(mem_ctx, user, domain, &user_sid, | |||
756 | &group_sids, &group_size); | |||
757 | if (ret != EOK0) { | |||
758 | ret = ERR_NO_SIDS; | |||
759 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 760, __FUNCTION__, __debug_macro_level, "Unable to retrieve SIDs: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
760 | "Unable to retrieve SIDs: [%d](%s)\n", ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 760, __FUNCTION__, __debug_macro_level, "Unable to retrieve SIDs: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
761 | goto done; | |||
762 | } | |||
763 | ||||
764 | DEBUG(SSSDBG_TRACE_FUNC, "CURRENT USER:\n")do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 764, __FUNCTION__, __debug_macro_level, "CURRENT USER:\n"); } } while (0); | |||
765 | DEBUG(SSSDBG_TRACE_FUNC, " user_sid = %s\n", user_sid)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 765, __FUNCTION__, __debug_macro_level, " user_sid = %s\n" , user_sid); } } while (0); | |||
766 | ||||
767 | for (j= 0; j < group_size; j++) { | |||
768 | DEBUG(SSSDBG_TRACE_FUNC, " group_sids[%d] = %s\n", j,do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 769, __FUNCTION__, __debug_macro_level, " group_sids[%d] = %s\n" , j, group_sids[j]); } } while (0) | |||
769 | group_sids[j])do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 769, __FUNCTION__, __debug_macro_level, " group_sids[%d] = %s\n" , j, group_sids[j]); } } while (0); | |||
770 | } | |||
771 | ||||
772 | /* If AllowLogonLocally is not defined, all users are allowed */ | |||
773 | if (allowed_size == 0) { | |||
774 | access_granted = true1; | |||
775 | } else { | |||
776 | access_granted = check_rights(allowed_sids, allowed_size, user_sid, | |||
777 | group_sids, group_size); | |||
778 | } | |||
779 | ||||
780 | DEBUG(SSSDBG_TRACE_FUNC, " access_granted = %d\n", access_granted)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 780, __FUNCTION__, __debug_macro_level, " access_granted = %d\n" , access_granted); } } while (0); | |||
781 | ||||
782 | access_denied = check_rights(denied_sids, denied_size, user_sid, | |||
783 | group_sids, group_size); | |||
784 | DEBUG(SSSDBG_TRACE_FUNC, " access_denied = %d\n", access_denied)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 784, __FUNCTION__, __debug_macro_level, " access_denied = %d\n" , access_denied); } } while (0); | |||
785 | ||||
786 | if (access_granted && !access_denied) { | |||
787 | return EOK0; | |||
788 | } else { | |||
789 | return EACCES13; | |||
790 | } | |||
791 | ||||
792 | done: | |||
793 | ||||
794 | if (ret) { | |||
795 | DEBUG(SSSDBG_CRIT_FAILURE, "Error encountered: %d.\n", ret)do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 795, __FUNCTION__, __debug_macro_level, "Error encountered: %d.\n" , ret); } } while (0); | |||
796 | } | |||
797 | ||||
798 | return ret; | |||
799 | } | |||
800 | ||||
801 | #define GPO_CHILD_LOG_FILE"gpo_child" "gpo_child" | |||
802 | static errno_t gpo_child_init(void) | |||
803 | { | |||
804 | int ret; | |||
805 | FILE *debug_filep; | |||
806 | ||||
807 | if (debug_to_file != 0 && gpo_child_debug_fd == -1) { | |||
808 | ret = open_debug_file_ex(GPO_CHILD_LOG_FILE"gpo_child", &debug_filep, false0); | |||
809 | if (ret != EOK0) { | |||
810 | DEBUG(SSSDBG_FATAL_FAILURE, "Error setting up logging (%d) [%s]\n",do { int __debug_macro_level = 0x0010; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 811, __FUNCTION__, __debug_macro_level, "Error setting up logging (%d) [%s]\n" , ret, strerror(ret)); } } while (0) | |||
811 | ret, strerror(ret))do { int __debug_macro_level = 0x0010; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 811, __FUNCTION__, __debug_macro_level, "Error setting up logging (%d) [%s]\n" , ret, strerror(ret)); } } while (0); | |||
812 | return ret; | |||
813 | } | |||
814 | ||||
815 | gpo_child_debug_fd = fileno(debug_filep); | |||
816 | if (gpo_child_debug_fd == -1) { | |||
817 | DEBUG(SSSDBG_FATAL_FAILURE,do { int __debug_macro_level = 0x0010; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 818, __FUNCTION__, __debug_macro_level, "fileno failed [%d][%s]\n" , (*__errno_location ()), strerror((*__errno_location ()))); } } while (0) | |||
818 | "fileno failed [%d][%s]\n", errno, strerror(errno))do { int __debug_macro_level = 0x0010; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 818, __FUNCTION__, __debug_macro_level, "fileno failed [%d][%s]\n" , (*__errno_location ()), strerror((*__errno_location ()))); } } while (0); | |||
819 | ret = errno(*__errno_location ()); | |||
820 | return ret; | |||
821 | } | |||
822 | } | |||
823 | ||||
824 | return EOK0; | |||
825 | } | |||
826 | ||||
827 | /* == ad_gpo_access_send/recv implementation ================================*/ | |||
828 | ||||
829 | struct ad_gpo_access_state { | |||
830 | struct tevent_context *ev; | |||
831 | struct ldb_context *ldb_ctx; | |||
832 | struct sdap_id_conn_ctx *conn; | |||
833 | struct sdap_id_op *sdap_op; | |||
834 | char *server_hostname; | |||
835 | struct sdap_options *opts; | |||
836 | int timeout; | |||
837 | struct sss_domain_info *domain; | |||
838 | const char *user; | |||
839 | const char *ad_hostname; | |||
840 | const char *target_dn; | |||
841 | struct gp_gpo **dacl_filtered_gpos; | |||
842 | int num_dacl_filtered_gpos; | |||
843 | struct gp_gpo **cse_filtered_gpos; | |||
844 | int num_cse_filtered_gpos; | |||
845 | int cse_gpo_index; | |||
846 | }; | |||
847 | ||||
848 | static void ad_gpo_connect_done(struct tevent_req *subreq); | |||
849 | static void ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq); | |||
850 | static void ad_gpo_process_som_done(struct tevent_req *subreq); | |||
851 | static void ad_gpo_process_gpo_done(struct tevent_req *subreq); | |||
852 | ||||
853 | static errno_t ad_gpo_cse_step(struct tevent_req *req); | |||
854 | static void ad_gpo_cse_done(struct tevent_req *subreq); | |||
855 | ||||
856 | struct tevent_req * | |||
857 | ad_gpo_access_send(TALLOC_CTX *mem_ctx, | |||
858 | struct tevent_context *ev, | |||
859 | struct sss_domain_info *domain, | |||
860 | struct ad_access_ctx *ctx, | |||
861 | const char *user) | |||
862 | { | |||
863 | struct tevent_req *req; | |||
864 | struct tevent_req *subreq; | |||
865 | struct ad_gpo_access_state *state; | |||
866 | char *server_uri; | |||
867 | LDAPURLDesc *lud; | |||
868 | errno_t ret; | |||
869 | ||||
870 | /* setup logging for gpo child */ | |||
871 | gpo_child_init(); | |||
872 | ||||
873 | req = tevent_req_create(mem_ctx, &state, struct ad_gpo_access_state)_tevent_req_create((mem_ctx), (&state), sizeof(struct ad_gpo_access_state ), "struct ad_gpo_access_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "873"); | |||
874 | if (req == NULL((void*)0)) { | |||
875 | DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n")do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 875, __FUNCTION__, __debug_macro_level, "tevent_req_create() failed\n" ); } } while (0); | |||
876 | return NULL((void*)0); | |||
877 | } | |||
878 | ||||
879 | state->domain = domain; | |||
880 | state->dacl_filtered_gpos = NULL((void*)0); | |||
881 | state->num_dacl_filtered_gpos = 0; | |||
882 | state->cse_filtered_gpos = NULL((void*)0); | |||
883 | state->num_cse_filtered_gpos = 0; | |||
884 | state->cse_gpo_index = -1; | |||
885 | state->ev = ev; | |||
886 | state->user = user; | |||
887 | state->ldb_ctx = sysdb_ctx_get_ldb(domain->sysdb); | |||
888 | state->ad_hostname = dp_opt_get_string(ctx->ad_options, AD_HOSTNAME)_dp_opt_get_string(ctx->ad_options, AD_HOSTNAME, __FUNCTION__ ); | |||
889 | state->opts = ctx->sdap_access_ctx->id_ctx->opts; | |||
890 | state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT)_dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT , __FUNCTION__); | |||
891 | state->conn = ad_get_dom_ldap_conn(ctx->ad_id_ctx, domain); | |||
892 | state->sdap_op = sdap_id_op_create(state, state->conn->conn_cache); | |||
893 | if (state->sdap_op == NULL((void*)0)) { | |||
894 | DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 894, __FUNCTION__, __debug_macro_level, "sdap_id_op_create failed.\n" ); } } while (0); | |||
895 | ret = ENOMEM12; | |||
896 | goto immediately; | |||
897 | } | |||
898 | ||||
899 | /* extract server_hostname from server_uri */ | |||
900 | server_uri = state->conn->service->uri; | |||
901 | ret = ldap_url_parse(server_uri, &lud); | |||
902 | if (ret != LDAP_SUCCESS0x00) { | |||
903 | DEBUG(SSSDBG_CRIT_FAILURE,do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 904, __FUNCTION__, __debug_macro_level, "Failed to parse ldap URI (%s)!\n" , server_uri); } } while (0) | |||
904 | "Failed to parse ldap URI (%s)!\n", server_uri)do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 904, __FUNCTION__, __debug_macro_level, "Failed to parse ldap URI (%s)!\n" , server_uri); } } while (0); | |||
905 | ret = EINVAL22; | |||
906 | goto immediately; | |||
907 | } | |||
908 | ||||
909 | if (lud->lud_host == NULL((void*)0)) { | |||
910 | DEBUG(SSSDBG_CRIT_FAILURE,do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 911, __FUNCTION__, __debug_macro_level, "The LDAP URI (%s) did not contain a host name\n" , server_uri); } } while (0) | |||
911 | "The LDAP URI (%s) did not contain a host name\n", server_uri)do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 911, __FUNCTION__, __debug_macro_level, "The LDAP URI (%s) did not contain a host name\n" , server_uri); } } while (0); | |||
912 | ldap_free_urldesc(lud); | |||
913 | ret = EINVAL22; | |||
914 | goto immediately; | |||
915 | } | |||
916 | ||||
917 | state->server_hostname = talloc_strdup(state, lud->lud_host); | |||
918 | ldap_free_urldesc(lud); | |||
919 | if (!state->server_hostname) { | |||
920 | ret = ENOMEM12; | |||
921 | goto immediately; | |||
922 | } | |||
923 | DEBUG(SSSDBG_TRACE_ALL, "server_hostname from uri: %s\n",do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 924, __FUNCTION__, __debug_macro_level, "server_hostname from uri: %s\n" , state->server_hostname); } } while (0) | |||
924 | state->server_hostname)do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 924, __FUNCTION__, __debug_macro_level, "server_hostname from uri: %s\n" , state->server_hostname); } } while (0); | |||
925 | ||||
926 | subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); | |||
927 | if (subreq == NULL((void*)0)) { | |||
928 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 930, __FUNCTION__, __debug_macro_level, "sdap_id_op_connect_send failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
929 | "sdap_id_op_connect_send failed: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 930, __FUNCTION__, __debug_macro_level, "sdap_id_op_connect_send failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
930 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 930, __FUNCTION__, __debug_macro_level, "sdap_id_op_connect_send failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
931 | goto immediately; | |||
932 | } | |||
933 | tevent_req_set_callback(subreq, ad_gpo_connect_done, req); | |||
934 | ||||
935 | ret = EOK0; | |||
936 | ||||
937 | immediately: | |||
938 | ||||
939 | if (ret != EOK0) { | |||
940 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "940"); | |||
941 | tevent_req_post(req, ev); | |||
942 | } | |||
943 | ||||
944 | return req; | |||
945 | } | |||
946 | ||||
947 | static void | |||
948 | ad_gpo_connect_done(struct tevent_req *subreq) | |||
949 | { | |||
950 | struct tevent_req *req; | |||
951 | struct ad_gpo_access_state *state; | |||
952 | char* filter; | |||
953 | char *sam_account_name; | |||
954 | char *domain_dn; | |||
955 | int dp_error; | |||
956 | errno_t ret; | |||
957 | ||||
958 | const char *attrs[] = {AD_AT_DN"distinguishedName", AD_AT_UAC"userAccountControl", NULL((void*)0)}; | |||
959 | ||||
960 | req = tevent_req_callback_data(subreq, struct tevent_req)(struct tevent_req *)_talloc_get_type_abort(_tevent_req_callback_data (subreq), "struct tevent_req", "../sssd/src/providers/ad/ad_gpo.c" ":" "960"); | |||
961 | state = tevent_req_data(req, struct ad_gpo_access_state)(struct ad_gpo_access_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_access_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "961"); | |||
962 | ||||
963 | ret = sdap_id_op_connect_recv(subreq, &dp_error); | |||
964 | talloc_zfree(subreq)do { _talloc_free(((void *)((uintptr_t)(subreq))), "../sssd/src/providers/ad/ad_gpo.c" ":" "964"); subreq = ((void*)0); } while(0); | |||
965 | ||||
966 | if (ret != EOK0) { | |||
967 | /* TBD: handle (dp_error == DP_ERR_OFFLINE) case */ | |||
968 | ||||
969 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 971, __FUNCTION__, __debug_macro_level, "Failed to connect to AD server: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
970 | "Failed to connect to AD server: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 971, __FUNCTION__, __debug_macro_level, "Failed to connect to AD server: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
971 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 971, __FUNCTION__, __debug_macro_level, "Failed to connect to AD server: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
972 | ||||
973 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "973"); | |||
974 | return; | |||
975 | } | |||
976 | ||||
977 | sam_account_name = talloc_asprintf(state, "%s$", state->ad_hostname); | |||
978 | if (sam_account_name == NULL((void*)0)) { | |||
979 | tevent_req_error(req, ENOMEM)_tevent_req_error(req, 12, "../sssd/src/providers/ad/ad_gpo.c" ":" "979"); | |||
980 | return; | |||
981 | } | |||
982 | ||||
983 | DEBUG(SSSDBG_TRACE_FUNC, "sam_account_name is %s\n", sam_account_name)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 983, __FUNCTION__, __debug_macro_level, "sam_account_name is %s\n" , sam_account_name); } } while (0); | |||
984 | ||||
985 | /* Convert the domain name into domain DN */ | |||
986 | ret = domain_to_basedn(state, state->domain->name, &domain_dn); | |||
987 | if (ret != EOK0) { | |||
988 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 990, __FUNCTION__, __debug_macro_level, "Cannot convert domain name [%s] to base DN [%d]: %s\n" , state->domain->name, ret, sss_strerror(ret)); } } while (0) | |||
989 | "Cannot convert domain name [%s] to base DN [%d]: %s\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 990, __FUNCTION__, __debug_macro_level, "Cannot convert domain name [%s] to base DN [%d]: %s\n" , state->domain->name, ret, sss_strerror(ret)); } } while (0) | |||
990 | state->domain->name, ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 990, __FUNCTION__, __debug_macro_level, "Cannot convert domain name [%s] to base DN [%d]: %s\n" , state->domain->name, ret, sss_strerror(ret)); } } while (0); | |||
991 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "991"); | |||
992 | return; | |||
993 | } | |||
994 | ||||
995 | /* SDAP_OC_USER objectclass covers both users and computers */ | |||
996 | filter = talloc_asprintf(state, | |||
997 | "(&(objectclass=%s)(%s=%s))", | |||
998 | state->opts->user_map[SDAP_OC_USER].name, | |||
999 | state->opts->user_map[SDAP_AT_USER_NAME].name, | |||
1000 | sam_account_name); | |||
1001 | ||||
1002 | if (filter == NULL((void*)0)) { | |||
1003 | tevent_req_error(req, ENOMEM)_tevent_req_error(req, 12, "../sssd/src/providers/ad/ad_gpo.c" ":" "1003"); | |||
1004 | return; | |||
1005 | } | |||
1006 | ||||
1007 | subreq = sdap_get_generic_send(state, state->ev, state->opts, | |||
1008 | sdap_id_op_handle(state->sdap_op), | |||
1009 | domain_dn, LDAP_SCOPE_SUBTREE((ber_int_t) 0x0002), | |||
1010 | filter, attrs, NULL((void*)0), 0, | |||
1011 | state->timeout, | |||
1012 | false0); | |||
1013 | ||||
1014 | if (subreq == NULL((void*)0)) { | |||
1015 | DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1015, __FUNCTION__, __debug_macro_level, "sdap_get_generic_send failed.\n" ); } } while (0); | |||
1016 | tevent_req_error(req, EIO)_tevent_req_error(req, 5, "../sssd/src/providers/ad/ad_gpo.c" ":" "1016"); | |||
1017 | return; | |||
1018 | } | |||
1019 | ||||
1020 | tevent_req_set_callback(subreq, ad_gpo_target_dn_retrieval_done, req); | |||
1021 | } | |||
1022 | ||||
1023 | static void | |||
1024 | ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq) | |||
1025 | { | |||
1026 | struct tevent_req *req; | |||
1027 | struct ad_gpo_access_state *state; | |||
1028 | int ret; | |||
1029 | int dp_error; | |||
1030 | size_t reply_count; | |||
1031 | struct sysdb_attrs **reply; | |||
1032 | const char *target_dn = NULL((void*)0); | |||
1033 | uint32_t uac; | |||
1034 | ||||
1035 | req = tevent_req_callback_data(subreq, struct tevent_req)(struct tevent_req *)_talloc_get_type_abort(_tevent_req_callback_data (subreq), "struct tevent_req", "../sssd/src/providers/ad/ad_gpo.c" ":" "1035"); | |||
1036 | state = tevent_req_data(req, struct ad_gpo_access_state)(struct ad_gpo_access_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_access_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "1036"); | |||
1037 | ret = sdap_get_generic_recv(subreq, state, | |||
1038 | &reply_count, &reply); | |||
1039 | talloc_zfree(subreq)do { _talloc_free(((void *)((uintptr_t)(subreq))), "../sssd/src/providers/ad/ad_gpo.c" ":" "1039"); subreq = ((void*)0); } while(0); | |||
1040 | if (ret != EOK0) { | |||
1041 | ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); | |||
1042 | /* TBD: handle (dp_error == DP_ERR_OFFLINE) case */ | |||
1043 | ||||
1044 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1046, __FUNCTION__, __debug_macro_level, "Unable to get policy target's DN: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1045 | "Unable to get policy target's DN: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1046, __FUNCTION__, __debug_macro_level, "Unable to get policy target's DN: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1046 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1046, __FUNCTION__, __debug_macro_level, "Unable to get policy target's DN: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
1047 | ret = ENOENT2; | |||
1048 | goto done; | |||
1049 | } | |||
1050 | ||||
1051 | /* make sure there is only one non-NULL reply returned */ | |||
1052 | ||||
1053 | if (reply_count < 1) { | |||
1054 | DEBUG(SSSDBG_OP_FAILURE, "No DN retrieved for policy target.\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1054, __FUNCTION__, __debug_macro_level, "No DN retrieved for policy target.\n" ); } } while (0); | |||
1055 | ret = ENOENT2; | |||
1056 | goto done; | |||
1057 | } else if (reply_count > 1) { | |||
1058 | DEBUG(SSSDBG_OP_FAILURE, "Multiple replies for policy target\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1058, __FUNCTION__, __debug_macro_level, "Multiple replies for policy target\n" ); } } while (0); | |||
1059 | ret = ERR_INTERNAL; | |||
1060 | goto done; | |||
1061 | } else if (reply == NULL((void*)0)) { | |||
1062 | DEBUG(SSSDBG_OP_FAILURE, "reply_count is 1, but reply is NULL\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1062, __FUNCTION__, __debug_macro_level, "reply_count is 1, but reply is NULL\n" ); } } while (0); | |||
1063 | ret = ERR_INTERNAL; | |||
1064 | goto done; | |||
1065 | } | |||
1066 | ||||
1067 | /* reply[0] holds requested attributes of single reply */ | |||
1068 | ret = sysdb_attrs_get_string(reply[0], AD_AT_DN"distinguishedName", &target_dn); | |||
1069 | if (ret != EOK0) { | |||
1070 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1072, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1071 | "sysdb_attrs_get_string failed: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1072, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1072 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1072, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
1073 | goto done; | |||
1074 | } | |||
1075 | state->target_dn = talloc_steal(state, target_dn)({ __typeof__(target_dn) __talloc_steal_ret = (__typeof__(target_dn ))_talloc_steal_loc((state),(target_dn), "../sssd/src/providers/ad/ad_gpo.c" ":" "1075"); __talloc_steal_ret; }); | |||
1076 | if (state->target_dn == NULL((void*)0)) { | |||
1077 | ret = ENOMEM12; | |||
1078 | goto done; | |||
1079 | } | |||
1080 | ||||
1081 | ret = sysdb_attrs_get_uint32_t(reply[0], AD_AT_UAC"userAccountControl", &uac); | |||
1082 | if (ret != EOK0) { | |||
1083 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1085, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_uint32_t failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1084 | "sysdb_attrs_get_uint32_t failed: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1085, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_uint32_t failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1085 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1085, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_uint32_t failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
1086 | goto done; | |||
1087 | } | |||
1088 | ||||
1089 | /* we only support computer policy targets, not users */ | |||
1090 | if (!(uac & UAC_WORKSTATION_TRUST_ACCOUNT0x00001000)) { | |||
1091 | ret = EINVAL22; | |||
1092 | goto done; | |||
1093 | } | |||
1094 | ||||
1095 | subreq = ad_gpo_process_som_send(state, | |||
1096 | state->ev, | |||
1097 | state->conn, | |||
1098 | state->ldb_ctx, | |||
1099 | state->sdap_op, | |||
1100 | state->opts, | |||
1101 | state->timeout, | |||
1102 | state->target_dn, | |||
1103 | state->domain->name); | |||
1104 | if (subreq == NULL((void*)0)) { | |||
1105 | ret = ENOMEM12; | |||
1106 | goto done; | |||
1107 | } | |||
1108 | ||||
1109 | tevent_req_set_callback(subreq, ad_gpo_process_som_done, req); | |||
1110 | ||||
1111 | ret = EOK0; | |||
1112 | ||||
1113 | done: | |||
1114 | ||||
1115 | if (ret != EOK0) { | |||
1116 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "1116"); | |||
1117 | } | |||
1118 | } | |||
1119 | ||||
1120 | static void | |||
1121 | ad_gpo_process_som_done(struct tevent_req *subreq) | |||
1122 | { | |||
1123 | struct tevent_req *req; | |||
1124 | struct ad_gpo_access_state *state; | |||
1125 | int ret; | |||
1126 | struct gp_som **som_list; | |||
1127 | ||||
1128 | req = tevent_req_callback_data(subreq, struct tevent_req)(struct tevent_req *)_talloc_get_type_abort(_tevent_req_callback_data (subreq), "struct tevent_req", "../sssd/src/providers/ad/ad_gpo.c" ":" "1128"); | |||
1129 | state = tevent_req_data(req, struct ad_gpo_access_state)(struct ad_gpo_access_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_access_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "1129"); | |||
1130 | ret = ad_gpo_process_som_recv(subreq, state, &som_list); | |||
1131 | talloc_zfree(subreq)do { _talloc_free(((void *)((uintptr_t)(subreq))), "../sssd/src/providers/ad/ad_gpo.c" ":" "1131"); subreq = ((void*)0); } while(0); | |||
1132 | ||||
1133 | if (ret != EOK0) { | |||
1134 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1136, __FUNCTION__, __debug_macro_level, "Unable to get som list: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1135 | "Unable to get som list: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1136, __FUNCTION__, __debug_macro_level, "Unable to get som list: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1136 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1136, __FUNCTION__, __debug_macro_level, "Unable to get som list: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
1137 | ret = ENOENT2; | |||
1138 | goto done; | |||
1139 | } | |||
1140 | ||||
1141 | subreq = ad_gpo_process_gpo_send(state, | |||
1142 | state->ev, | |||
1143 | state->sdap_op, | |||
1144 | state->opts, | |||
1145 | state->server_hostname, | |||
1146 | state->timeout, | |||
1147 | som_list); | |||
1148 | if (subreq == NULL((void*)0)) { | |||
1149 | ret = ENOMEM12; | |||
1150 | goto done; | |||
1151 | } | |||
1152 | ||||
1153 | tevent_req_set_callback(subreq, ad_gpo_process_gpo_done, req); | |||
1154 | ||||
1155 | ret = EOK0; | |||
1156 | ||||
1157 | done: | |||
1158 | ||||
1159 | if (ret != EOK0) { | |||
1160 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "1160"); | |||
1161 | } | |||
1162 | } | |||
1163 | ||||
1164 | /* | |||
1165 | * This function retrieves a list of candidate_gpos and potentially reduces it | |||
1166 | * to a list of dacl_filtered_gpos, based on each GPO's DACL. | |||
1167 | * | |||
1168 | * This function then takes the list of dacl_filtered_gpos and potentially | |||
1169 | * reduces it to a list of cse_filtered_gpos, based on whether each GPO's list | |||
1170 | * of cse_guids includes the "SecuritySettings" CSE GUID (used for HBAC). | |||
1171 | * | |||
1172 | * This function then sends each cse_filtered_gpo to the CSE processing engine | |||
1173 | * for policy application, which currently consists of HBAC functionality. | |||
1174 | */ | |||
1175 | static void | |||
1176 | ad_gpo_process_gpo_done(struct tevent_req *subreq) | |||
1177 | { | |||
1178 | struct tevent_req *req; | |||
1179 | struct ad_gpo_access_state *state; | |||
1180 | int ret; | |||
1181 | int dp_error; | |||
1182 | struct gp_gpo **candidate_gpos = NULL((void*)0); | |||
1183 | int num_candidate_gpos = 0; | |||
1184 | int i = 0; | |||
1185 | ||||
1186 | req = tevent_req_callback_data(subreq, struct tevent_req)(struct tevent_req *)_talloc_get_type_abort(_tevent_req_callback_data (subreq), "struct tevent_req", "../sssd/src/providers/ad/ad_gpo.c" ":" "1186"); | |||
1187 | state = tevent_req_data(req, struct ad_gpo_access_state)(struct ad_gpo_access_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_access_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "1187"); | |||
1188 | ret = ad_gpo_process_gpo_recv(subreq, state, &candidate_gpos, | |||
1189 | &num_candidate_gpos); | |||
1190 | ||||
1191 | talloc_zfree(subreq)do { _talloc_free(((void *)((uintptr_t)(subreq))), "../sssd/src/providers/ad/ad_gpo.c" ":" "1191"); subreq = ((void*)0); } while(0); | |||
1192 | ||||
1193 | ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); | |||
1194 | ||||
1195 | if (ret != EOK0) { | |||
1196 | /* TBD: handle (dp_error == DP_ERR_OFFLINE) case */ | |||
1197 | ||||
1198 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1200, __FUNCTION__, __debug_macro_level, "Unable to get GPO list: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1199 | "Unable to get GPO list: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1200, __FUNCTION__, __debug_macro_level, "Unable to get GPO list: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1200 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1200, __FUNCTION__, __debug_macro_level, "Unable to get GPO list: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
1201 | ret = ENOENT2; | |||
1202 | goto done; | |||
1203 | } | |||
1204 | ||||
1205 | ret = ad_gpo_filter_gpos_by_dacl(state, state->user, state->domain, | |||
1206 | state->opts->idmap_ctx->map, | |||
1207 | candidate_gpos, num_candidate_gpos, | |||
1208 | &state->dacl_filtered_gpos, | |||
1209 | &state->num_dacl_filtered_gpos); | |||
1210 | if (ret != EOK0) { | |||
1211 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1213, __FUNCTION__, __debug_macro_level, "Unable to filter GPO list by DACKL: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1212 | "Unable to filter GPO list by DACKL: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1213, __FUNCTION__, __debug_macro_level, "Unable to filter GPO list by DACKL: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1213 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1213, __FUNCTION__, __debug_macro_level, "Unable to filter GPO list by DACKL: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
1214 | goto done; | |||
1215 | } | |||
1216 | ||||
1217 | if (state->dacl_filtered_gpos[0] == NULL((void*)0)) { | |||
1218 | /* since no applicable gpos were found, there is nothing to enforce */ | |||
1219 | DEBUG(SSSDBG_TRACE_FUNC,do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1220, __FUNCTION__, __debug_macro_level, "no applicable gpos found after dacl filtering\n" ); } } while (0) | |||
1220 | "no applicable gpos found after dacl filtering\n")do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1220, __FUNCTION__, __debug_macro_level, "no applicable gpos found after dacl filtering\n" ); } } while (0); | |||
1221 | ret = EOK0; | |||
1222 | goto done; | |||
1223 | } | |||
1224 | ||||
1225 | for (i = 0; i < state->num_dacl_filtered_gpos; i++) { | |||
1226 | DEBUG(SSSDBG_TRACE_FUNC, "dacl_filtered_gpos[%d]->gpo_guid is %s\n", i,do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1227, __FUNCTION__, __debug_macro_level, "dacl_filtered_gpos[%d]->gpo_guid is %s\n" , i, state->dacl_filtered_gpos[i]->gpo_guid); } } while (0) | |||
1227 | state->dacl_filtered_gpos[i]->gpo_guid)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1227, __FUNCTION__, __debug_macro_level, "dacl_filtered_gpos[%d]->gpo_guid is %s\n" , i, state->dacl_filtered_gpos[i]->gpo_guid); } } while (0); | |||
1228 | } | |||
1229 | ||||
1230 | ret = ad_gpo_filter_gpos_by_cse_guid(state, | |||
1231 | GP_EXT_GUID_SECURITY"{827D319E-6EAC-11D2-A4EA-00C04F79F83A}", | |||
1232 | state->dacl_filtered_gpos, | |||
1233 | state->num_dacl_filtered_gpos, | |||
1234 | &state->cse_filtered_gpos, | |||
1235 | &state->num_cse_filtered_gpos); | |||
1236 | ||||
1237 | if (ret != EOK0) { | |||
1238 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1240, __FUNCTION__, __debug_macro_level, "Unable to filter GPO list by CSE_GUID: [%d](%s)\n" , ret, strerror(ret)); } } while (0) | |||
1239 | "Unable to filter GPO list by CSE_GUID: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1240, __FUNCTION__, __debug_macro_level, "Unable to filter GPO list by CSE_GUID: [%d](%s)\n" , ret, strerror(ret)); } } while (0) | |||
1240 | ret, strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1240, __FUNCTION__, __debug_macro_level, "Unable to filter GPO list by CSE_GUID: [%d](%s)\n" , ret, strerror(ret)); } } while (0); | |||
1241 | goto done; | |||
1242 | } | |||
1243 | ||||
1244 | if (state->cse_filtered_gpos[0] == NULL((void*)0)) { | |||
1245 | /* no gpos contain "SecuritySettings" cse_guid, nothing to enforce */ | |||
1246 | DEBUG(SSSDBG_TRACE_FUNC,do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1247, __FUNCTION__, __debug_macro_level, "no applicable gpos found after cse_guid filtering\n" ); } } while (0) | |||
1247 | "no applicable gpos found after cse_guid filtering\n")do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1247, __FUNCTION__, __debug_macro_level, "no applicable gpos found after cse_guid filtering\n" ); } } while (0); | |||
1248 | ret = EOK0; | |||
1249 | goto done; | |||
1250 | } | |||
1251 | ||||
1252 | for (i = 0; i < state->num_cse_filtered_gpos; i++) { | |||
1253 | DEBUG(SSSDBG_TRACE_FUNC, "cse_filtered_gpos[%d]->gpo_guid is %s\n", i,do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1254, __FUNCTION__, __debug_macro_level, "cse_filtered_gpos[%d]->gpo_guid is %s\n" , i, state->cse_filtered_gpos[i]->gpo_guid); } } while ( 0) | |||
1254 | state->cse_filtered_gpos[i]->gpo_guid)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1254, __FUNCTION__, __debug_macro_level, "cse_filtered_gpos[%d]->gpo_guid is %s\n" , i, state->cse_filtered_gpos[i]->gpo_guid); } } while ( 0); | |||
1255 | } | |||
1256 | ||||
1257 | DEBUG(SSSDBG_TRACE_FUNC, "num_cse_filtered_gpos: %d\n",do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1258, __FUNCTION__, __debug_macro_level, "num_cse_filtered_gpos: %d\n" , state->num_cse_filtered_gpos); } } while (0) | |||
1258 | state->num_cse_filtered_gpos)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1258, __FUNCTION__, __debug_macro_level, "num_cse_filtered_gpos: %d\n" , state->num_cse_filtered_gpos); } } while (0); | |||
1259 | ||||
1260 | ret = ad_gpo_cse_step(req); | |||
1261 | ||||
1262 | done: | |||
1263 | ||||
1264 | if (ret == EOK0) { | |||
1265 | tevent_req_done(req)_tevent_req_done(req, "../sssd/src/providers/ad/ad_gpo.c" ":" "1265"); | |||
1266 | } else if (ret != EAGAIN11) { | |||
1267 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "1267"); | |||
1268 | } | |||
1269 | } | |||
1270 | ||||
1271 | static errno_t | |||
1272 | ad_gpo_cse_step(struct tevent_req *req) | |||
1273 | { | |||
1274 | struct tevent_req *subreq; | |||
1275 | struct ad_gpo_access_state *state; | |||
1276 | char *smb_uri; | |||
1277 | int i = 0; | |||
1278 | ||||
1279 | state = tevent_req_data(req, struct ad_gpo_access_state)(struct ad_gpo_access_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_access_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "1279"); | |||
1280 | ||||
1281 | state->cse_gpo_index++; | |||
1282 | struct gp_gpo *cse_filtered_gpo = | |||
1283 | state->cse_filtered_gpos[state->cse_gpo_index]; | |||
1284 | ||||
1285 | /* cse_filtered_gpo is NULL only after all GPOs have been processed */ | |||
1286 | if (cse_filtered_gpo == NULL((void*)0)) return EOK0; | |||
1287 | ||||
1288 | DEBUG(SSSDBG_TRACE_FUNC, "cse filtered_gpos[%d]->gpo_guid is %s\n",do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1289, __FUNCTION__, __debug_macro_level, "cse filtered_gpos[%d]->gpo_guid is %s\n" , state->cse_gpo_index, cse_filtered_gpo->gpo_guid); } } while (0) | |||
1289 | state->cse_gpo_index, cse_filtered_gpo->gpo_guid)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1289, __FUNCTION__, __debug_macro_level, "cse filtered_gpos[%d]->gpo_guid is %s\n" , state->cse_gpo_index, cse_filtered_gpo->gpo_guid); } } while (0); | |||
1290 | DEBUG(SSSDBG_TRACE_FUNC, "cse filtered_gpos[%d]->file_sys_path is %s\n",do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1291, __FUNCTION__, __debug_macro_level, "cse filtered_gpos[%d]->file_sys_path is %s\n" , state->cse_gpo_index, cse_filtered_gpo->gpo_file_sys_path ); } } while (0) | |||
1291 | state->cse_gpo_index, cse_filtered_gpo->gpo_file_sys_path)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1291, __FUNCTION__, __debug_macro_level, "cse filtered_gpos[%d]->file_sys_path is %s\n" , state->cse_gpo_index, cse_filtered_gpo->gpo_file_sys_path ); } } while (0); | |||
1292 | for (i = 0; i < cse_filtered_gpo->num_gpo_cse_guids; i++) { | |||
1293 | DEBUG(SSSDBG_TRACE_ALL,do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1295, __FUNCTION__, __debug_macro_level, "cse_filtered_gpos[%d]->gpo_cse_guids[%d]->gpo_guid is %s\n" , state->cse_gpo_index, i, cse_filtered_gpo->gpo_cse_guids [i]); } } while (0) | |||
1294 | "cse_filtered_gpos[%d]->gpo_cse_guids[%d]->gpo_guid is %s\n",do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1295, __FUNCTION__, __debug_macro_level, "cse_filtered_gpos[%d]->gpo_cse_guids[%d]->gpo_guid is %s\n" , state->cse_gpo_index, i, cse_filtered_gpo->gpo_cse_guids [i]); } } while (0) | |||
1295 | state->cse_gpo_index, i, cse_filtered_gpo->gpo_cse_guids[i])do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1295, __FUNCTION__, __debug_macro_level, "cse_filtered_gpos[%d]->gpo_cse_guids[%d]->gpo_guid is %s\n" , state->cse_gpo_index, i, cse_filtered_gpo->gpo_cse_guids [i]); } } while (0); | |||
1296 | } | |||
1297 | ||||
1298 | smb_uri = talloc_asprintf(state, "%s%s", | |||
1299 | cse_filtered_gpo->gpo_file_sys_path, | |||
1300 | GP_EXT_GUID_SECURITY_SUFFIX"/Microsoft/Windows NT/SecEdit/GptTmpl.inf"); | |||
1301 | ||||
1302 | subreq = ad_gpo_process_cse_send(state, state->ev, smb_uri); | |||
1303 | ||||
1304 | tevent_req_set_callback(subreq, ad_gpo_cse_done, req); | |||
1305 | return EAGAIN11; | |||
1306 | } | |||
1307 | ||||
1308 | /* | |||
1309 | * This cse-specific function (GP_EXT_GUID_SECURITY) retrieves a list of | |||
1310 | * allowed_sids and denied_sids, and uses them to determine whether logon | |||
1311 | * access is granted or denied for the state's {user, domain} tuple. | |||
1312 | * | |||
1313 | * If it is determined that the current cse_filtered_gpo grants access, then | |||
1314 | * we process the next cse_filtered_gpo in the list. At any time, if access is | |||
1315 | * denied, we return immediately with an error. | |||
1316 | */ | |||
1317 | static void | |||
1318 | ad_gpo_cse_done(struct tevent_req *subreq) | |||
1319 | { | |||
1320 | struct tevent_req *req; | |||
1321 | struct ad_gpo_access_state *state; | |||
1322 | int ret; | |||
1323 | char **allowed_sids; | |||
1324 | int allowed_size; | |||
1325 | char **denied_sids; | |||
1326 | int denied_size; | |||
1327 | ||||
1328 | req = tevent_req_callback_data(subreq, struct tevent_req)(struct tevent_req *)_talloc_get_type_abort(_tevent_req_callback_data (subreq), "struct tevent_req", "../sssd/src/providers/ad/ad_gpo.c" ":" "1328"); | |||
1329 | state = tevent_req_data(req, struct ad_gpo_access_state)(struct ad_gpo_access_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_access_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "1329"); | |||
1330 | ||||
1331 | ret = ad_gpo_process_cse_recv(subreq, state, &allowed_size, &allowed_sids, | |||
1332 | &denied_size, &denied_sids); | |||
1333 | ||||
1334 | talloc_zfree(subreq)do { _talloc_free(((void *)((uintptr_t)(subreq))), "../sssd/src/providers/ad/ad_gpo.c" ":" "1334"); subreq = ((void*)0); } while(0); | |||
1335 | ||||
1336 | if (ret != EOK0) { | |||
1337 | /* TBD: handle ret error */ | |||
1338 | goto done; | |||
1339 | } | |||
1340 | ||||
1341 | /* TBD: allowed/denied_sids/size, should be retrieved from cache */ | |||
1342 | ret = ad_gpo_access_check | |||
1343 | (state, state->user, state->domain, | |||
1344 | allowed_sids, allowed_size, denied_sids, denied_size); | |||
1345 | ||||
1346 | if (ret != EOK0) { | |||
1347 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1349, __FUNCTION__, __debug_macro_level, "GPO access check failed: [%d](%s)\n" , ret, strerror(ret)); } } while (0) | |||
1348 | "GPO access check failed: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1349, __FUNCTION__, __debug_macro_level, "GPO access check failed: [%d](%s)\n" , ret, strerror(ret)); } } while (0) | |||
1349 | ret, strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1349, __FUNCTION__, __debug_macro_level, "GPO access check failed: [%d](%s)\n" , ret, strerror(ret)); } } while (0); | |||
1350 | goto done; | |||
1351 | } | |||
1352 | ||||
1353 | ret = ad_gpo_cse_step(req); | |||
1354 | ||||
1355 | done: | |||
1356 | ||||
1357 | if (ret == EOK0) { | |||
1358 | tevent_req_done(req)_tevent_req_done(req, "../sssd/src/providers/ad/ad_gpo.c" ":" "1358"); | |||
1359 | } else if (ret != EAGAIN11) { | |||
1360 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "1360"); | |||
1361 | } | |||
1362 | } | |||
1363 | ||||
1364 | errno_t | |||
1365 | ad_gpo_access_recv(struct tevent_req *req) | |||
1366 | { | |||
1367 | TEVENT_REQ_RETURN_ON_ERROR(req)do { enum tevent_req_state TRROEstate; uint64_t TRROEerr; if ( tevent_req_is_error(req, &TRROEstate, &TRROEerr)) { if (TRROEstate == TEVENT_REQ_USER_ERROR) { return TRROEerr; } return ERR_INTERNAL; } } while (0); | |||
1368 | ||||
1369 | return EOK0; | |||
1370 | } | |||
1371 | ||||
1372 | /* == ad_gpo_process_som_send/recv helpers ================================= */ | |||
1373 | ||||
1374 | /* | |||
1375 | * This function returns the parent of an LDAP DN | |||
1376 | */ | |||
1377 | static errno_t | |||
1378 | ad_gpo_parent_dn(TALLOC_CTX *mem_ctx, | |||
1379 | struct ldb_context *ldb_ctx, | |||
1380 | const char *dn, | |||
1381 | const char **_parent_dn) | |||
1382 | { | |||
1383 | struct ldb_dn *ldb_dn; | |||
1384 | struct ldb_dn *parent_ldb_dn; | |||
1385 | const char *p; | |||
1386 | int ret; | |||
1387 | TALLOC_CTX *tmp_ctx = NULL((void*)0); | |||
1388 | ||||
1389 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "../sssd/src/providers/ad/ad_gpo.c" ":" "1389"); | |||
1390 | if (tmp_ctx == NULL((void*)0)) { | |||
1391 | ret = ENOMEM12; | |||
1392 | goto done; | |||
1393 | } | |||
1394 | ||||
1395 | ldb_dn = ldb_dn_new(tmp_ctx, ldb_ctx, dn); | |||
1396 | parent_ldb_dn = ldb_dn_get_parent(tmp_ctx, ldb_dn); | |||
1397 | p = ldb_dn_get_linearized(parent_ldb_dn); | |||
1398 | ||||
1399 | *_parent_dn = talloc_steal(mem_ctx, p)({ __typeof__(p) __talloc_steal_ret = (__typeof__(p))_talloc_steal_loc ((mem_ctx),(p), "../sssd/src/providers/ad/ad_gpo.c" ":" "1399" ); __talloc_steal_ret; }); | |||
1400 | ret = EOK0; | |||
1401 | ||||
1402 | done: | |||
1403 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "../sssd/src/providers/ad/ad_gpo.c" ":" "1403"); | |||
1404 | return ret; | |||
1405 | } | |||
1406 | ||||
1407 | /* | |||
1408 | * This function populates the _som_list output parameter by parsing the input | |||
1409 | * DN into a list of gp_som objects. This function essentially repeatedly | |||
1410 | * appends the input DN's parent to the SOM List (if the parent starts with | |||
1411 | * "OU=" or "DC="), until the first "DC=" component is reached. | |||
1412 | * Example: if input DN is "CN=MyComputer,CN=Computers,OU=Sales,DC=FOO,DC=COM", | |||
1413 | * then SOM List has 2 SOM entries: {[OU=Sales,DC=FOO,DC=COM], [DC=FOO, DC=COM]} | |||
1414 | */ | |||
1415 | ||||
1416 | static errno_t | |||
1417 | ad_gpo_populate_som_list(TALLOC_CTX *mem_ctx, | |||
1418 | struct ldb_context *ldb_ctx, | |||
1419 | const char *target_dn, | |||
1420 | int *_num_soms, | |||
1421 | struct gp_som ***_som_list) | |||
1422 | { | |||
1423 | TALLOC_CTX *tmp_ctx = NULL((void*)0); | |||
1424 | int ret; | |||
1425 | int rdn_count = 0; | |||
1426 | int som_idx = 0; | |||
1427 | struct gp_som **som_list; | |||
1428 | const char *parent_dn = NULL((void*)0); | |||
1429 | const char *tmp_dn = NULL((void*)0); | |||
1430 | struct ldb_dn *ldb_target_dn; | |||
1431 | ||||
1432 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "../sssd/src/providers/ad/ad_gpo.c" ":" "1432"); | |||
1433 | if (tmp_ctx == NULL((void*)0)) { | |||
1434 | ret = ENOMEM12; | |||
1435 | goto done; | |||
1436 | } | |||
1437 | ||||
1438 | ldb_target_dn = ldb_dn_new(tmp_ctx, ldb_ctx, target_dn); | |||
1439 | if (ldb_target_dn == NULL((void*)0)) { | |||
1440 | ret = EINVAL22; | |||
1441 | goto done; | |||
1442 | } | |||
1443 | ||||
1444 | rdn_count = ldb_dn_get_comp_num(ldb_target_dn); | |||
1445 | if (rdn_count == -1) { | |||
1446 | ret = EINVAL22; | |||
1447 | goto done; | |||
1448 | } | |||
1449 | ||||
1450 | if (rdn_count == 0) { | |||
1451 | *_som_list = NULL((void*)0); | |||
1452 | ret = EOK0; | |||
1453 | goto done; | |||
1454 | } | |||
1455 | ||||
1456 | /* assume the worst-case, in which every parent is a SOM */ | |||
1457 | /* include space for Site SOM and NULL: rdn_count + 1 + 1 */ | |||
1458 | som_list = talloc_array(tmp_ctx, struct gp_som *, rdn_count + 1 + 1)(struct gp_som * *)_talloc_array(tmp_ctx, sizeof(struct gp_som *), rdn_count + 1 + 1, "struct gp_som *"); | |||
1459 | if (som_list == NULL((void*)0)) { | |||
1460 | ret = ENOMEM12; | |||
1461 | goto done; | |||
1462 | } | |||
1463 | ||||
1464 | /* first, populate the OU and Domain SOMs */ | |||
1465 | tmp_dn = target_dn;; | |||
1466 | while ((ad_gpo_parent_dn(tmp_ctx, ldb_ctx, tmp_dn, &parent_dn)) == EOK0) { | |||
1467 | ||||
1468 | if ((strncasecmp(parent_dn, "OU=", strlen("OU=")) == 0) || | |||
1469 | (strncasecmp(parent_dn, "DC=", strlen("DC=")) == 0)) { | |||
1470 | ||||
1471 | som_list[som_idx] = talloc_zero(som_list, struct gp_som)(struct gp_som *)_talloc_zero(som_list, sizeof(struct gp_som) , "struct gp_som"); | |||
1472 | if (som_list[som_idx] == NULL((void*)0)) { | |||
1473 | ret = ENOMEM12; | |||
1474 | goto done; | |||
1475 | } | |||
1476 | som_list[som_idx]->som_dn = talloc_steal(som_list[som_idx],({ __typeof__(parent_dn) __talloc_steal_ret = (__typeof__(parent_dn ))_talloc_steal_loc((som_list[som_idx]),(parent_dn), "../sssd/src/providers/ad/ad_gpo.c" ":" "1477"); __talloc_steal_ret; }) | |||
1477 | parent_dn)({ __typeof__(parent_dn) __talloc_steal_ret = (__typeof__(parent_dn ))_talloc_steal_loc((som_list[som_idx]),(parent_dn), "../sssd/src/providers/ad/ad_gpo.c" ":" "1477"); __talloc_steal_ret; }); | |||
1478 | if (som_list[som_idx]->som_dn == NULL((void*)0)) { | |||
1479 | ret = ENOMEM12; | |||
1480 | goto done; | |||
1481 | } | |||
1482 | som_idx++; | |||
1483 | } | |||
1484 | ||||
1485 | if (strncasecmp(parent_dn, "DC=", strlen("DC=")) == 0) { | |||
1486 | break; | |||
1487 | } | |||
1488 | tmp_dn = parent_dn; | |||
1489 | } | |||
1490 | ||||
1491 | som_list[som_idx] = NULL((void*)0); | |||
1492 | ||||
1493 | *_num_soms = som_idx; | |||
1494 | *_som_list = talloc_steal(mem_ctx, som_list)({ __typeof__(som_list) __talloc_steal_ret = (__typeof__(som_list ))_talloc_steal_loc((mem_ctx),(som_list), "../sssd/src/providers/ad/ad_gpo.c" ":" "1494"); __talloc_steal_ret; }); | |||
1495 | ||||
1496 | ret = EOK0; | |||
1497 | ||||
1498 | done: | |||
1499 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "../sssd/src/providers/ad/ad_gpo.c" ":" "1499"); | |||
1500 | return ret; | |||
1501 | } | |||
1502 | ||||
1503 | /* | |||
1504 | * This function populates the _gplink_list output parameter by parsing the | |||
1505 | * input raw_gplink_value into an array of gp_gplink objects, each consisting of | |||
1506 | * a GPO DN and bool enforced field. | |||
1507 | * | |||
1508 | * The raw_gplink_value is single string consisting of multiple gplink strings. | |||
1509 | * The raw_gplink_value is in the following format: | |||
1510 | * "[GPO_DN_1;GPLinkOptions_1]...[GPO_DN_n;GPLinkOptions_n]" | |||
1511 | * | |||
1512 | * Each gplink string consists of a GPO DN and a GPLinkOptions field (which | |||
1513 | * indicates whether its associated GPO DN is ignored, unenforced, or enforced). | |||
1514 | * If a GPO DN is flagged as ignored, it is discarded and will not be added to | |||
1515 | * the _gplink_list. If the allow_enforced_only input is true, AND a GPO DN is | |||
1516 | * flagged as unenforced, it will also be discarded. | |||
1517 | * | |||
1518 | * Example: if raw_gplink_value="[OU=Sales,DC=FOO,DC=COM;0][DC=FOO,DC=COM;2]" | |||
1519 | * and allow_enforced_only=FALSE, then the output would consist of following: | |||
1520 | * _gplink_list[0]: {GPO DN: "OU=Sales,DC=FOO,DC=COM", enforced: FALSE} | |||
1521 | * _gplink_list[1]: {GPO DN: "DC=FOO,DC=COM", enforced: TRUE} | |||
1522 | */ | |||
1523 | static errno_t | |||
1524 | ad_gpo_populate_gplink_list(TALLOC_CTX *mem_ctx, | |||
1525 | const char *som_dn, | |||
1526 | char *raw_gplink_value, | |||
1527 | struct gp_gplink ***_gplink_list, | |||
1528 | bool_Bool allow_enforced_only) | |||
1529 | { | |||
1530 | TALLOC_CTX *tmp_ctx = NULL((void*)0); | |||
1531 | char *ptr; | |||
1532 | char *first; | |||
1533 | char *last; | |||
1534 | char *dn; | |||
1535 | char *gplink_options; | |||
1536 | const char delim = ']'; | |||
1537 | struct gp_gplink **gplink_list; | |||
1538 | int i; | |||
1539 | int ret; | |||
1540 | uint32_t gplink_number; | |||
1541 | int gplink_count = 0; | |||
1542 | int num_enabled = 0; | |||
1543 | ||||
1544 | if (raw_gplink_value == NULL((void*)0) || | |||
1545 | *raw_gplink_value == '\0' || | |||
1546 | _gplink_list == NULL((void*)0)) { | |||
1547 | return EINVAL22; | |||
1548 | } | |||
1549 | ||||
1550 | DEBUG(SSSDBG_TRACE_ALL, "som_dn: %s\n", som_dn)do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1550, __FUNCTION__, __debug_macro_level, "som_dn: %s\n", som_dn ); } } while (0); | |||
1551 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "../sssd/src/providers/ad/ad_gpo.c" ":" "1551"); | |||
1552 | if (tmp_ctx == NULL((void*)0)) { | |||
1553 | ret = ENOMEM12; | |||
1554 | goto done; | |||
1555 | } | |||
1556 | ||||
1557 | ptr = raw_gplink_value; | |||
1558 | ||||
1559 | while ((ptr = strchr(ptr, delim)(__extension__ (__builtin_constant_p (delim) && !__builtin_constant_p (ptr) && (delim) == '\0' ? (char *) __rawmemchr (ptr , delim) : __builtin_strchr (ptr, delim))))) { | |||
1560 | ptr++; | |||
1561 | gplink_count++; | |||
1562 | } | |||
1563 | ||||
1564 | if (gplink_count == 0) { | |||
1565 | ret = EINVAL22; | |||
1566 | goto done; | |||
1567 | } | |||
1568 | ||||
1569 | gplink_list = talloc_array(tmp_ctx, struct gp_gplink *, gplink_count + 1)(struct gp_gplink * *)_talloc_array(tmp_ctx, sizeof(struct gp_gplink *), gplink_count + 1, "struct gp_gplink *"); | |||
1570 | if (gplink_list == NULL((void*)0)) { | |||
1571 | ret = ENOMEM12; | |||
1572 | goto done; | |||
1573 | } | |||
1574 | ||||
1575 | num_enabled = 0; | |||
1576 | ptr = raw_gplink_value; | |||
1577 | for (i = 0; i < gplink_count; i++) { | |||
1578 | first = ptr + 1; | |||
1579 | last = strchr(first, delim)(__extension__ (__builtin_constant_p (delim) && !__builtin_constant_p (first) && (delim) == '\0' ? (char *) __rawmemchr (first , delim) : __builtin_strchr (first, delim))); | |||
1580 | if (last == NULL((void*)0)) { | |||
1581 | ret = EINVAL22; | |||
1582 | goto done; | |||
1583 | } | |||
1584 | *last = '\0'; | |||
1585 | last++; | |||
1586 | dn = first; | |||
1587 | if ( strncasecmp(dn, "LDAP://", 7)== 0 ) { | |||
1588 | dn = dn + 7; | |||
1589 | } | |||
1590 | gplink_options = strchr(first, ';')(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p (first) && (';') == '\0' ? (char *) __rawmemchr (first , ';') : __builtin_strchr (first, ';'))); | |||
1591 | if (gplink_options == NULL((void*)0)) { | |||
1592 | ret = EINVAL22; | |||
1593 | goto done; | |||
1594 | } | |||
1595 | *gplink_options = '\0'; | |||
1596 | gplink_options++; | |||
1597 | ||||
1598 | gplink_number = strtouint32(gplink_options, NULL((void*)0), 10); | |||
1599 | if (errno(*__errno_location ()) != 0) { | |||
1600 | ret = errno(*__errno_location ()); | |||
1601 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1602, __FUNCTION__, __debug_macro_level, "strtouint32 failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1602 | "strtouint32 failed: [%d](%s)\n", ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1602, __FUNCTION__, __debug_macro_level, "strtouint32 failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
1603 | goto done; | |||
1604 | } | |||
1605 | ||||
1606 | DEBUG(SSSDBG_TRACE_ALL,do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1607, __FUNCTION__, __debug_macro_level, "gplink_list[%d]: [%s; %d]\n" , num_enabled, dn, gplink_number); } } while (0) | |||
1607 | "gplink_list[%d]: [%s; %d]\n", num_enabled, dn, gplink_number)do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1607, __FUNCTION__, __debug_macro_level, "gplink_list[%d]: [%s; %d]\n" , num_enabled, dn, gplink_number); } } while (0); | |||
1608 | ||||
1609 | if ((gplink_number == 1) || (gplink_number ==3)) { | |||
1610 | /* ignore flag is set */ | |||
1611 | DEBUG(SSSDBG_TRACE_ALL, "ignored gpo skipped\n")do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1611, __FUNCTION__, __debug_macro_level, "ignored gpo skipped\n" ); } } while (0); | |||
1612 | ptr = last; | |||
1613 | continue; | |||
1614 | } | |||
1615 | ||||
1616 | if (allow_enforced_only && (gplink_number == 0)) { | |||
1617 | /* unenforced flag is set; only enforced gpos allowed */ | |||
1618 | DEBUG(SSSDBG_TRACE_ALL, "unenforced gpo skipped\n")do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1618, __FUNCTION__, __debug_macro_level, "unenforced gpo skipped\n" ); } } while (0); | |||
1619 | ptr = last; | |||
1620 | continue; | |||
1621 | } | |||
1622 | ||||
1623 | gplink_list[num_enabled] = talloc_zero(gplink_list, struct gp_gplink)(struct gp_gplink *)_talloc_zero(gplink_list, sizeof(struct gp_gplink ), "struct gp_gplink"); | |||
1624 | if (gplink_list[num_enabled] == NULL((void*)0)) { | |||
1625 | ret = ENOMEM12; | |||
1626 | goto done; | |||
1627 | } | |||
1628 | gplink_list[num_enabled]->gpo_dn = | |||
1629 | talloc_strdup(gplink_list[num_enabled], dn); | |||
1630 | ||||
1631 | if (gplink_list[num_enabled]->gpo_dn == NULL((void*)0)) { | |||
1632 | ret = ENOMEM12; | |||
1633 | goto done; | |||
1634 | } | |||
1635 | ||||
1636 | if (gplink_number == 0) { | |||
1637 | gplink_list[num_enabled]->enforced = 0; | |||
1638 | num_enabled++; | |||
1639 | } else if (gplink_number == 2) { | |||
1640 | gplink_list[num_enabled]->enforced = 1; | |||
1641 | num_enabled++; | |||
1642 | } else { | |||
1643 | ret = EINVAL22; | |||
1644 | goto done; | |||
1645 | } | |||
1646 | ||||
1647 | ptr = last; | |||
1648 | } | |||
1649 | gplink_list[num_enabled] = NULL((void*)0); | |||
1650 | ||||
1651 | *_gplink_list = talloc_steal(mem_ctx, gplink_list)({ __typeof__(gplink_list) __talloc_steal_ret = (__typeof__(gplink_list ))_talloc_steal_loc((mem_ctx),(gplink_list), "../sssd/src/providers/ad/ad_gpo.c" ":" "1651"); __talloc_steal_ret; }); | |||
1652 | ret = EOK0; | |||
1653 | ||||
1654 | done: | |||
1655 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "../sssd/src/providers/ad/ad_gpo.c" ":" "1655"); | |||
1656 | return ret; | |||
1657 | } | |||
1658 | ||||
1659 | /* == ad_gpo_process_som_send/recv implementation ========================== */ | |||
1660 | ||||
1661 | struct ad_gpo_process_som_state { | |||
1662 | struct tevent_context *ev; | |||
1663 | struct sdap_id_op *sdap_op; | |||
1664 | struct sdap_options *opts; | |||
1665 | int timeout; | |||
1666 | bool_Bool allow_enforced_only; | |||
1667 | char *site_name; | |||
1668 | char *site_dn; | |||
1669 | struct gp_som **som_list; | |||
1670 | int som_index; | |||
1671 | int num_soms; | |||
1672 | }; | |||
1673 | ||||
1674 | static void ad_gpo_site_name_retrieval_done(struct tevent_req *subreq); | |||
1675 | static void ad_gpo_site_dn_retrieval_done(struct tevent_req *subreq); | |||
1676 | static errno_t ad_gpo_get_som_attrs_step(struct tevent_req *req); | |||
1677 | static void ad_gpo_get_som_attrs_done(struct tevent_req *subreq); | |||
1678 | ||||
1679 | /* | |||
1680 | * This function uses the input target_dn and input domain_name to populate | |||
1681 | * a list of gp_som objects. Each object in this list represents a SOM | |||
1682 | * associated with the target (such as OU, Domain, and Site). | |||
1683 | * | |||
1684 | * The inputs are used to determine the DNs of each SOM associated with the | |||
1685 | * target. In turn, the SOM object DNs are used to retrieve certain LDAP | |||
1686 | * attributes of each SOM object, that are parsed into an array of gp_gplink | |||
1687 | * objects, essentially representing the GPOs that have been linked to each | |||
1688 | * SOM object. Note that it is perfectly valid for there to be *no* GPOs | |||
1689 | * linked to a SOM object. | |||
1690 | */ | |||
1691 | struct tevent_req * | |||
1692 | ad_gpo_process_som_send(TALLOC_CTX *mem_ctx, | |||
1693 | struct tevent_context *ev, | |||
1694 | struct sdap_id_conn_ctx *conn, | |||
1695 | struct ldb_context *ldb_ctx, | |||
1696 | struct sdap_id_op *sdap_op, | |||
1697 | struct sdap_options *opts, | |||
1698 | int timeout, | |||
1699 | const char *target_dn, | |||
1700 | const char *domain_name) | |||
1701 | { | |||
1702 | struct tevent_req *req; | |||
1703 | struct tevent_req *subreq; | |||
1704 | struct ad_gpo_process_som_state *state; | |||
1705 | errno_t ret; | |||
1706 | ||||
1707 | req = tevent_req_create(mem_ctx, &state, struct ad_gpo_process_som_state)_tevent_req_create((mem_ctx), (&state), sizeof(struct ad_gpo_process_som_state ), "struct ad_gpo_process_som_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "1707"); | |||
1708 | if (req == NULL((void*)0)) { | |||
1709 | DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n")do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1709, __FUNCTION__, __debug_macro_level, "tevent_req_create() failed\n" ); } } while (0); | |||
1710 | return NULL((void*)0); | |||
1711 | } | |||
1712 | ||||
1713 | state->ev = ev; | |||
1714 | state->sdap_op = sdap_op; | |||
1715 | state->opts = opts; | |||
1716 | state->timeout = timeout; | |||
1717 | state->som_index = -1; | |||
1718 | state->allow_enforced_only = 0; | |||
1719 | ||||
1720 | ret = ad_gpo_populate_som_list(state, ldb_ctx, target_dn, | |||
1721 | &state->num_soms, &state->som_list); | |||
1722 | if (ret != EOK0) { | |||
1723 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1725, __FUNCTION__, __debug_macro_level, "Unable to retrieve SOM List : [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1724 | "Unable to retrieve SOM List : [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1725, __FUNCTION__, __debug_macro_level, "Unable to retrieve SOM List : [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1725 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1725, __FUNCTION__, __debug_macro_level, "Unable to retrieve SOM List : [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
1726 | ret = ENOENT2; | |||
1727 | goto immediately; | |||
1728 | } | |||
1729 | ||||
1730 | if (state->som_list == NULL((void*)0)) { | |||
1731 | DEBUG(SSSDBG_OP_FAILURE, "target dn must have at least one parent\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1731, __FUNCTION__, __debug_macro_level, "target dn must have at least one parent\n" ); } } while (0); | |||
1732 | ret = EINVAL22; | |||
1733 | goto immediately; | |||
1734 | } | |||
1735 | ||||
1736 | subreq = ad_master_domain_send(state, state->ev, conn, | |||
1737 | state->sdap_op, domain_name); | |||
1738 | ||||
1739 | if (subreq == NULL((void*)0)) { | |||
1740 | DEBUG(SSSDBG_OP_FAILURE, "ad_master_domain_send failed.\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1740, __FUNCTION__, __debug_macro_level, "ad_master_domain_send failed.\n" ); } } while (0); | |||
1741 | ret = ENOMEM12; | |||
1742 | goto immediately; | |||
1743 | } | |||
1744 | ||||
1745 | tevent_req_set_callback(subreq, ad_gpo_site_name_retrieval_done, req); | |||
1746 | ||||
1747 | ret = EOK0; | |||
1748 | ||||
1749 | immediately: | |||
1750 | ||||
1751 | if (ret != EOK0) { | |||
1752 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "1752"); | |||
1753 | tevent_req_post(req, ev); | |||
1754 | } | |||
1755 | ||||
1756 | return req; | |||
1757 | } | |||
1758 | ||||
1759 | static void | |||
1760 | ad_gpo_site_name_retrieval_done(struct tevent_req *subreq) | |||
1761 | { | |||
1762 | struct tevent_req *req; | |||
1763 | struct ad_gpo_process_som_state *state; | |||
1764 | int ret; | |||
1765 | char *site; | |||
1766 | const char *attrs[] = {AD_AT_CONFIG_NC"configurationNamingContext", NULL((void*)0)}; | |||
1767 | ||||
1768 | req = tevent_req_callback_data(subreq, struct tevent_req)(struct tevent_req *)_talloc_get_type_abort(_tevent_req_callback_data (subreq), "struct tevent_req", "../sssd/src/providers/ad/ad_gpo.c" ":" "1768"); | |||
1769 | state = tevent_req_data(req, struct ad_gpo_process_som_state)(struct ad_gpo_process_som_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_process_som_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "1769"); | |||
1770 | ||||
1771 | /* gpo code only cares about the site name */ | |||
1772 | ret = ad_master_domain_recv(subreq, state, NULL((void*)0), NULL((void*)0), &site, NULL((void*)0)); | |||
1773 | talloc_zfree(subreq)do { _talloc_free(((void *)((uintptr_t)(subreq))), "../sssd/src/providers/ad/ad_gpo.c" ":" "1773"); subreq = ((void*)0); } while(0); | |||
1774 | ||||
1775 | if (ret != EOK0) { | |||
1776 | DEBUG(SSSDBG_OP_FAILURE, "Cannot retrieve master domain info\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1776, __FUNCTION__, __debug_macro_level, "Cannot retrieve master domain info\n" ); } } while (0); | |||
1777 | tevent_req_error(req, ENOENT)_tevent_req_error(req, 2, "../sssd/src/providers/ad/ad_gpo.c" ":" "1777"); | |||
1778 | return; | |||
1779 | } | |||
1780 | ||||
1781 | state->site_name = talloc_asprintf(state, "cn=%s", site); | |||
1782 | if (state->site_name == NULL((void*)0)) { | |||
1783 | tevent_req_error(req, ENOMEM)_tevent_req_error(req, 12, "../sssd/src/providers/ad/ad_gpo.c" ":" "1783"); | |||
1784 | return; | |||
1785 | } | |||
1786 | ||||
1787 | /* | |||
1788 | * note: the configNC attribute is being retrieved here from the rootDSE | |||
1789 | * entry. In future, since we already make an LDAP query for the rootDSE | |||
1790 | * entry when LDAP connection is made, this attribute should really be | |||
1791 | * retrieved at that point (see https://fedorahosted.org/sssd/ticket/2276) | |||
1792 | */ | |||
1793 | subreq = sdap_get_generic_send(state, state->ev, state->opts, | |||
1794 | sdap_id_op_handle(state->sdap_op), | |||
1795 | "", LDAP_SCOPE_BASE((ber_int_t) 0x0000), | |||
1796 | "(objectclass=*)", attrs, NULL((void*)0), 0, | |||
1797 | state->timeout, | |||
1798 | false0); | |||
1799 | ||||
1800 | if (subreq == NULL((void*)0)) { | |||
1801 | DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1801, __FUNCTION__, __debug_macro_level, "sdap_get_generic_send failed.\n" ); } } while (0); | |||
1802 | tevent_req_error(req, ENOMEM)_tevent_req_error(req, 12, "../sssd/src/providers/ad/ad_gpo.c" ":" "1802"); | |||
1803 | return; | |||
1804 | } | |||
1805 | ||||
1806 | tevent_req_set_callback(subreq, ad_gpo_site_dn_retrieval_done, req); | |||
1807 | } | |||
1808 | ||||
1809 | static void | |||
1810 | ad_gpo_site_dn_retrieval_done(struct tevent_req *subreq) | |||
1811 | { | |||
1812 | struct tevent_req *req; | |||
1813 | struct ad_gpo_process_som_state *state; | |||
1814 | int ret; | |||
1815 | int dp_error; | |||
1816 | int i = 0; | |||
1817 | size_t reply_count; | |||
1818 | struct sysdb_attrs **reply; | |||
1819 | const char *configNC; | |||
1820 | ||||
1821 | req = tevent_req_callback_data(subreq, struct tevent_req)(struct tevent_req *)_talloc_get_type_abort(_tevent_req_callback_data (subreq), "struct tevent_req", "../sssd/src/providers/ad/ad_gpo.c" ":" "1821"); | |||
1822 | state = tevent_req_data(req, struct ad_gpo_process_som_state)(struct ad_gpo_process_som_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_process_som_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "1822"); | |||
1823 | ||||
1824 | ret = sdap_get_generic_recv(subreq, state, | |||
1825 | &reply_count, &reply); | |||
1826 | talloc_zfree(subreq)do { _talloc_free(((void *)((uintptr_t)(subreq))), "../sssd/src/providers/ad/ad_gpo.c" ":" "1826"); subreq = ((void*)0); } while(0); | |||
1827 | if (ret != EOK0) { | |||
1828 | ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); | |||
1829 | /* TBD: handle (dp_error == DP_ERR_OFFLINE) case */ | |||
1830 | ||||
1831 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1832, __FUNCTION__, __debug_macro_level, "Unable to get configNC: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1832 | "Unable to get configNC: [%d](%s)\n", ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1832, __FUNCTION__, __debug_macro_level, "Unable to get configNC: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
1833 | ret = ENOENT2; | |||
1834 | goto done; | |||
1835 | } | |||
1836 | ||||
1837 | /* make sure there is only one non-NULL reply returned */ | |||
1838 | ||||
1839 | if (reply_count < 1) { | |||
1840 | DEBUG(SSSDBG_OP_FAILURE, "No configNC retrieved\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1840, __FUNCTION__, __debug_macro_level, "No configNC retrieved\n" ); } } while (0); | |||
1841 | ret = ENOENT2; | |||
1842 | goto done; | |||
1843 | } else if (reply_count > 1) { | |||
1844 | DEBUG(SSSDBG_OP_FAILURE, "Multiple replies for configNC\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1844, __FUNCTION__, __debug_macro_level, "Multiple replies for configNC\n" ); } } while (0); | |||
1845 | ret = ERR_INTERNAL; | |||
1846 | goto done; | |||
1847 | } else if (reply == NULL((void*)0)) { | |||
1848 | DEBUG(SSSDBG_OP_FAILURE, "reply_count is 1, but reply is NULL\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1848, __FUNCTION__, __debug_macro_level, "reply_count is 1, but reply is NULL\n" ); } } while (0); | |||
1849 | ret = ERR_INTERNAL; | |||
1850 | goto done; | |||
1851 | } | |||
1852 | ||||
1853 | /* reply[0] holds requested attributes of single reply */ | |||
1854 | ret = sysdb_attrs_get_string(reply[0], AD_AT_CONFIG_NC"configurationNamingContext", &configNC); | |||
1855 | if (ret != EOK0) { | |||
1856 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1858, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1857 | "sysdb_attrs_get_string failed: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1858, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1858 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1858, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
1859 | goto done; | |||
1860 | } | |||
1861 | state->site_dn = | |||
1862 | talloc_asprintf(state, "%s,cn=Sites,%s", state->site_name, configNC); | |||
1863 | if (state->site_dn == NULL((void*)0)) { | |||
1864 | ret = ENOMEM12; | |||
1865 | goto done; | |||
1866 | } | |||
1867 | ||||
1868 | /* note that space was allocated for site_dn when allocating som_list */ | |||
1869 | state->som_list[state->num_soms] = | |||
1870 | talloc_zero(state->som_list, struct gp_som)(struct gp_som *)_talloc_zero(state->som_list, sizeof(struct gp_som), "struct gp_som"); | |||
1871 | if (state->som_list[state->num_soms] == NULL((void*)0)) { | |||
1872 | ret = ENOMEM12; | |||
1873 | goto done; | |||
1874 | } | |||
1875 | ||||
1876 | state->som_list[state->num_soms]->som_dn = | |||
1877 | talloc_steal(state->som_list[state->num_soms], state->site_dn)({ __typeof__(state->site_dn) __talloc_steal_ret = (__typeof__ (state->site_dn))_talloc_steal_loc((state->som_list[state ->num_soms]),(state->site_dn), "../sssd/src/providers/ad/ad_gpo.c" ":" "1877"); __talloc_steal_ret; }); | |||
1878 | ||||
1879 | if (state->som_list[state->num_soms]->som_dn == NULL((void*)0)) { | |||
1880 | ret = ENOMEM12; | |||
1881 | goto done; | |||
1882 | } | |||
1883 | ||||
1884 | state->num_soms++; | |||
1885 | state->som_list[state->num_soms] = NULL((void*)0); | |||
1886 | ||||
1887 | i = 0; | |||
1888 | while (state->som_list[i]) { | |||
1889 | DEBUG(SSSDBG_TRACE_FUNC, "som_list[%d]->som_dn is %s\n", i,do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1890, __FUNCTION__, __debug_macro_level, "som_list[%d]->som_dn is %s\n" , i, state->som_list[i]->som_dn); } } while (0) | |||
1890 | state->som_list[i]->som_dn)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1890, __FUNCTION__, __debug_macro_level, "som_list[%d]->som_dn is %s\n" , i, state->som_list[i]->som_dn); } } while (0); | |||
1891 | i++; | |||
1892 | } | |||
1893 | ||||
1894 | ret = ad_gpo_get_som_attrs_step(req); | |||
1895 | ||||
1896 | done: | |||
1897 | ||||
1898 | if (ret == EOK0) { | |||
1899 | tevent_req_done(req)_tevent_req_done(req, "../sssd/src/providers/ad/ad_gpo.c" ":" "1899"); | |||
1900 | } else if (ret != EAGAIN11) { | |||
1901 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "1901"); | |||
1902 | } | |||
1903 | ||||
1904 | } | |||
1905 | static errno_t | |||
1906 | ad_gpo_get_som_attrs_step(struct tevent_req *req) | |||
1907 | { | |||
1908 | const char *attrs[] = {AD_AT_GPLINK"gPLink", AD_AT_GPOPTIONS"gpOptions", NULL((void*)0)}; | |||
1909 | struct tevent_req *subreq; | |||
1910 | struct ad_gpo_process_som_state *state; | |||
1911 | ||||
1912 | state = tevent_req_data(req, struct ad_gpo_process_som_state)(struct ad_gpo_process_som_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_process_som_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "1912"); | |||
1913 | ||||
1914 | state->som_index++; | |||
1915 | struct gp_som *gp_som = state->som_list[state->som_index]; | |||
1916 | ||||
1917 | /* gp_som is NULL only after all SOMs have been processed */ | |||
1918 | if (gp_som == NULL((void*)0)) return EOK0; | |||
1919 | ||||
1920 | const char *som_dn = gp_som->som_dn; | |||
1921 | subreq = sdap_get_generic_send(state, state->ev, state->opts, | |||
1922 | sdap_id_op_handle(state->sdap_op), | |||
1923 | som_dn, LDAP_SCOPE_BASE((ber_int_t) 0x0000), | |||
1924 | "(objectclass=*)", attrs, NULL((void*)0), 0, | |||
1925 | state->timeout, | |||
1926 | false0); | |||
1927 | ||||
1928 | if (subreq == NULL((void*)0)) { | |||
1929 | DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1929, __FUNCTION__, __debug_macro_level, "sdap_get_generic_send failed.\n" ); } } while (0); | |||
1930 | return ENOMEM12; | |||
1931 | } | |||
1932 | ||||
1933 | tevent_req_set_callback(subreq, ad_gpo_get_som_attrs_done, req); | |||
1934 | return EAGAIN11; | |||
1935 | } | |||
1936 | ||||
1937 | static void | |||
1938 | ad_gpo_get_som_attrs_done(struct tevent_req *subreq) | |||
1939 | { | |||
1940 | struct tevent_req *req; | |||
1941 | struct ad_gpo_process_som_state *state; | |||
1942 | int ret; | |||
1943 | int dp_error; | |||
1944 | size_t num_results; | |||
1945 | struct sysdb_attrs **results; | |||
1946 | struct ldb_message_element *el = NULL((void*)0); | |||
1947 | uint8_t *raw_gplink_value; | |||
1948 | uint8_t *raw_gpoptions_value; | |||
1949 | uint32_t allow_enforced_only = 0; | |||
1950 | struct gp_som *gp_som; | |||
1951 | ||||
1952 | req = tevent_req_callback_data(subreq, struct tevent_req)(struct tevent_req *)_talloc_get_type_abort(_tevent_req_callback_data (subreq), "struct tevent_req", "../sssd/src/providers/ad/ad_gpo.c" ":" "1952"); | |||
1953 | state = tevent_req_data(req, struct ad_gpo_process_som_state)(struct ad_gpo_process_som_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_process_som_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "1953"); | |||
1954 | ret = sdap_get_generic_recv(subreq, state, | |||
1955 | &num_results, &results); | |||
1956 | talloc_zfree(subreq)do { _talloc_free(((void *)((uintptr_t)(subreq))), "../sssd/src/providers/ad/ad_gpo.c" ":" "1956"); subreq = ((void*)0); } while(0); | |||
1957 | ||||
1958 | if (ret != EOK0) { | |||
1959 | ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); | |||
1960 | /* TBD: handle (dp_error == DP_ERR_OFFLINE) case */ | |||
1961 | ||||
1962 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1964, __FUNCTION__, __debug_macro_level, "Unable to get SOM attributes: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1963 | "Unable to get SOM attributes: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1964, __FUNCTION__, __debug_macro_level, "Unable to get SOM attributes: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1964 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1964, __FUNCTION__, __debug_macro_level, "Unable to get SOM attributes: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
1965 | ret = ENOENT2; | |||
1966 | goto done; | |||
1967 | } | |||
1968 | if ((num_results < 1) || (results == NULL((void*)0))) { | |||
1969 | DEBUG(SSSDBG_OP_FAILURE, "no attrs found for SOM; try next SOM.\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1969, __FUNCTION__, __debug_macro_level, "no attrs found for SOM; try next SOM.\n" ); } } while (0); | |||
1970 | ret = ad_gpo_get_som_attrs_step(req); | |||
1971 | goto done; | |||
1972 | } else if (num_results > 1) { | |||
1973 | DEBUG(SSSDBG_OP_FAILURE, "Received multiple replies\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1973, __FUNCTION__, __debug_macro_level, "Received multiple replies\n" ); } } while (0); | |||
1974 | ret = ERR_INTERNAL; | |||
1975 | goto done; | |||
1976 | } | |||
1977 | ||||
1978 | /* Get the gplink value, if available */ | |||
1979 | ret = sysdb_attrs_get_el(results[0], AD_AT_GPLINK"gPLink", &el); | |||
1980 | ||||
1981 | if (ret != EOK0 && ret != ENOENT2) { | |||
1982 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1984, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_el() failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1983 | "sysdb_attrs_get_el() failed: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1984, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_el() failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
1984 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1984, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_el() failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
1985 | goto done; | |||
1986 | } | |||
1987 | ||||
1988 | if ((ret == ENOENT2) || (el->num_values == 0)) { | |||
1989 | DEBUG(SSSDBG_OP_FAILURE, "no attrs found for SOM; try next SOM\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1989, __FUNCTION__, __debug_macro_level, "no attrs found for SOM; try next SOM\n" ); } } while (0); | |||
1990 | ret = ad_gpo_get_som_attrs_step(req); | |||
1991 | goto done; | |||
1992 | } | |||
1993 | ||||
1994 | raw_gplink_value = el[0].values[0].data; | |||
1995 | ||||
1996 | ret = sysdb_attrs_get_el(results[0], AD_AT_GPOPTIONS"gpOptions", &el); | |||
1997 | ||||
1998 | if (ret != EOK0 && ret != ENOENT2) { | |||
1999 | DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el() failed\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 1999, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_el() failed\n" ); } } while (0); | |||
2000 | goto done; | |||
2001 | } | |||
2002 | ||||
2003 | if ((ret == ENOENT2) || (el->num_values == 0)) { | |||
2004 | DEBUG(SSSDBG_TRACE_ALL,do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2005, __FUNCTION__, __debug_macro_level, "gpoptions attr not found or has no value; defaults to 0\n" ); } } while (0) | |||
2005 | "gpoptions attr not found or has no value; defaults to 0\n")do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2005, __FUNCTION__, __debug_macro_level, "gpoptions attr not found or has no value; defaults to 0\n" ); } } while (0); | |||
2006 | allow_enforced_only = 0; | |||
2007 | } else { | |||
2008 | raw_gpoptions_value = el[0].values[0].data; | |||
2009 | allow_enforced_only = strtouint32((char *)raw_gpoptions_value, NULL((void*)0), 10); | |||
2010 | if (errno(*__errno_location ()) != 0) { | |||
2011 | ret = errno(*__errno_location ()); | |||
2012 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2013, __FUNCTION__, __debug_macro_level, "strtouint32 failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2013 | "strtouint32 failed: [%d](%s)\n", ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2013, __FUNCTION__, __debug_macro_level, "strtouint32 failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
2014 | goto done; | |||
2015 | } | |||
2016 | } | |||
2017 | ||||
2018 | gp_som = state->som_list[state->som_index]; | |||
2019 | ret = ad_gpo_populate_gplink_list(gp_som, | |||
2020 | gp_som->som_dn, | |||
2021 | (char *)raw_gplink_value, | |||
2022 | &gp_som->gplink_list, | |||
2023 | state->allow_enforced_only); | |||
2024 | ||||
2025 | if (ret != EOK0) { | |||
2026 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2027, __FUNCTION__, __debug_macro_level, "ad_gpo_populate_gplink_list() failed\n" ); } } while (0) | |||
2027 | "ad_gpo_populate_gplink_list() failed\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2027, __FUNCTION__, __debug_macro_level, "ad_gpo_populate_gplink_list() failed\n" ); } } while (0); | |||
2028 | goto done; | |||
2029 | } | |||
2030 | ||||
2031 | if (allow_enforced_only) { | |||
2032 | state->allow_enforced_only = 1; | |||
2033 | } | |||
2034 | ||||
2035 | ret = ad_gpo_get_som_attrs_step(req); | |||
2036 | ||||
2037 | done: | |||
2038 | ||||
2039 | if (ret == EOK0) { | |||
2040 | tevent_req_done(req)_tevent_req_done(req, "../sssd/src/providers/ad/ad_gpo.c" ":" "2040"); | |||
2041 | } else if (ret != EAGAIN11) { | |||
2042 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "2042"); | |||
2043 | } | |||
2044 | } | |||
2045 | ||||
2046 | int | |||
2047 | ad_gpo_process_som_recv(struct tevent_req *req, | |||
2048 | TALLOC_CTX *mem_ctx, | |||
2049 | struct gp_som ***som_list) | |||
2050 | { | |||
2051 | ||||
2052 | struct ad_gpo_process_som_state *state = | |||
2053 | tevent_req_data(req, struct ad_gpo_process_som_state)(struct ad_gpo_process_som_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_process_som_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "2053"); | |||
2054 | ||||
2055 | TEVENT_REQ_RETURN_ON_ERROR(req)do { enum tevent_req_state TRROEstate; uint64_t TRROEerr; if ( tevent_req_is_error(req, &TRROEstate, &TRROEerr)) { if (TRROEstate == TEVENT_REQ_USER_ERROR) { return TRROEerr; } return ERR_INTERNAL; } } while (0); | |||
2056 | *som_list = talloc_steal(mem_ctx, state->som_list)({ __typeof__(state->som_list) __talloc_steal_ret = (__typeof__ (state->som_list))_talloc_steal_loc((mem_ctx),(state->som_list ), "../sssd/src/providers/ad/ad_gpo.c" ":" "2056"); __talloc_steal_ret ; }); | |||
2057 | return EOK0; | |||
2058 | } | |||
2059 | ||||
2060 | /* == ad_gpo_process_gpo_send/recv helpers ================================= */ | |||
2061 | ||||
2062 | /* | |||
2063 | * This function examines the gp_gplink objects in each gp_som object specified | |||
2064 | * in the input som_list, and populates the _candidate_gpos output parameter's | |||
2065 | * gpo_dn fields with prioritized list of GPO DNs. Prioritization ensures that: | |||
2066 | * - GPOs linked to an OU will be applied after GPOs linked to a Domain, | |||
2067 | * which will be applied after GPOs linked to a Site. | |||
2068 | * - multiple GPOs linked to a single SOM are applied in their link order | |||
2069 | * (i.e. 1st GPO linked to SOM is applied after 2nd GPO linked to SOM, etc). | |||
2070 | * - enforced GPOs are applied after unenforced GPOs. | |||
2071 | * | |||
2072 | * As such, the _candidate_gpos output's dn fields looks like (in link order): | |||
2073 | * [unenforced {Site, Domain, OU}; enforced {Site, Domain, OU}] | |||
2074 | * | |||
2075 | * Note that in the case of conflicting policy settings, GPOs appearing later | |||
2076 | * in the list will trump GPOs appearing earlier in the list. | |||
2077 | */ | |||
2078 | static errno_t | |||
2079 | ad_gpo_populate_candidate_gpos(TALLOC_CTX *mem_ctx, | |||
2080 | struct gp_som **som_list, | |||
2081 | struct gp_gpo ***_candidate_gpos, | |||
2082 | int *_num_candidate_gpos) | |||
2083 | { | |||
2084 | ||||
2085 | TALLOC_CTX *tmp_ctx = NULL((void*)0); | |||
2086 | struct gp_som *gp_som = NULL((void*)0); | |||
2087 | struct gp_gplink *gp_gplink = NULL((void*)0); | |||
2088 | struct gp_gpo **candidate_gpos = NULL((void*)0); | |||
2089 | int num_candidate_gpos = 0; | |||
2090 | const char **enforced_gpo_dns = NULL((void*)0); | |||
2091 | const char **unenforced_gpo_dns = NULL((void*)0); | |||
2092 | int gpo_dn_idx = 0; | |||
2093 | int num_enforced = 0; | |||
2094 | int enforced_idx = 0; | |||
2095 | int num_unenforced = 0; | |||
2096 | int unenforced_idx = 0; | |||
2097 | int i = 0; | |||
2098 | int j = 0; | |||
2099 | int ret; | |||
2100 | ||||
2101 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "../sssd/src/providers/ad/ad_gpo.c" ":" "2101"); | |||
2102 | if (tmp_ctx == NULL((void*)0)) { | |||
2103 | ret = ENOMEM12; | |||
2104 | goto done; | |||
2105 | } | |||
2106 | ||||
2107 | while (som_list[i]) { | |||
2108 | gp_som = som_list[i]; | |||
2109 | j = 0; | |||
2110 | while (gp_som && gp_som->gplink_list && gp_som->gplink_list[j]) { | |||
2111 | gp_gplink = gp_som->gplink_list[j]; | |||
2112 | if (gp_gplink == NULL((void*)0)) { | |||
2113 | DEBUG(SSSDBG_OP_FAILURE, "unexpected null gp_gplink\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2113, __FUNCTION__, __debug_macro_level, "unexpected null gp_gplink\n" ); } } while (0); | |||
2114 | ret = EINVAL22; | |||
2115 | goto done; | |||
2116 | } | |||
2117 | if (gp_gplink->enforced) { | |||
2118 | num_enforced++; | |||
2119 | } else { | |||
2120 | num_unenforced++; | |||
2121 | } | |||
2122 | j++; | |||
2123 | } | |||
2124 | i++; | |||
2125 | } | |||
2126 | ||||
2127 | num_candidate_gpos = num_enforced + num_unenforced; | |||
2128 | ||||
2129 | if (num_candidate_gpos == 0) { | |||
2130 | *_candidate_gpos = NULL((void*)0); | |||
2131 | *_num_candidate_gpos = 0; | |||
2132 | ret = EOK0; | |||
2133 | goto done; | |||
2134 | } | |||
2135 | ||||
2136 | enforced_gpo_dns = talloc_array(tmp_ctx, const char *, num_enforced + 1)(const char * *)_talloc_array(tmp_ctx, sizeof(const char *), num_enforced + 1, "const char *"); | |||
2137 | if (enforced_gpo_dns == NULL((void*)0)) { | |||
2138 | ret = ENOMEM12; | |||
2139 | goto done; | |||
2140 | } | |||
2141 | ||||
2142 | unenforced_gpo_dns = talloc_array(tmp_ctx, const char *, num_unenforced + 1)(const char * *)_talloc_array(tmp_ctx, sizeof(const char *), num_unenforced + 1, "const char *"); | |||
2143 | if (unenforced_gpo_dns == NULL((void*)0)) { | |||
2144 | ret = ENOMEM12; | |||
2145 | goto done; | |||
2146 | } | |||
2147 | ||||
2148 | i = 0; | |||
2149 | while (som_list[i]) { | |||
2150 | gp_som = som_list[i]; | |||
2151 | j = 0; | |||
2152 | while (gp_som && gp_som->gplink_list && gp_som->gplink_list[j]) { | |||
2153 | gp_gplink = gp_som->gplink_list[j]; | |||
2154 | if (gp_gplink == NULL((void*)0)) { | |||
2155 | DEBUG(SSSDBG_OP_FAILURE, "unexpected null gp_gplink\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2155, __FUNCTION__, __debug_macro_level, "unexpected null gp_gplink\n" ); } } while (0); | |||
2156 | ret = EINVAL22; | |||
2157 | goto done; | |||
2158 | } | |||
2159 | ||||
2160 | if (gp_gplink->enforced) { | |||
2161 | enforced_gpo_dns[enforced_idx] = | |||
2162 | talloc_steal(enforced_gpo_dns, gp_gplink->gpo_dn)({ __typeof__(gp_gplink->gpo_dn) __talloc_steal_ret = (__typeof__ (gp_gplink->gpo_dn))_talloc_steal_loc((enforced_gpo_dns),( gp_gplink->gpo_dn), "../sssd/src/providers/ad/ad_gpo.c" ":" "2162"); __talloc_steal_ret; }); | |||
2163 | if (enforced_gpo_dns[enforced_idx] == NULL((void*)0)) { | |||
2164 | ret = ENOMEM12; | |||
2165 | goto done; | |||
2166 | } | |||
2167 | enforced_idx++; | |||
2168 | } else { | |||
2169 | ||||
2170 | unenforced_gpo_dns[unenforced_idx] = | |||
2171 | talloc_steal(unenforced_gpo_dns, gp_gplink->gpo_dn)({ __typeof__(gp_gplink->gpo_dn) __talloc_steal_ret = (__typeof__ (gp_gplink->gpo_dn))_talloc_steal_loc((unenforced_gpo_dns) ,(gp_gplink->gpo_dn), "../sssd/src/providers/ad/ad_gpo.c" ":" "2171"); __talloc_steal_ret; }); | |||
2172 | ||||
2173 | if (unenforced_gpo_dns[unenforced_idx] == NULL((void*)0)) { | |||
2174 | ret = ENOMEM12; | |||
2175 | goto done; | |||
2176 | } | |||
2177 | unenforced_idx++; | |||
2178 | } | |||
2179 | j++; | |||
2180 | } | |||
2181 | i++; | |||
2182 | } | |||
2183 | enforced_gpo_dns[num_enforced] = NULL((void*)0); | |||
2184 | unenforced_gpo_dns[num_unenforced] = NULL((void*)0); | |||
2185 | ||||
2186 | candidate_gpos = talloc_array(tmp_ctx,(struct gp_gpo * *)_talloc_array(tmp_ctx, sizeof(struct gp_gpo *), num_candidate_gpos + 1, "struct gp_gpo *") | |||
2187 | struct gp_gpo *,(struct gp_gpo * *)_talloc_array(tmp_ctx, sizeof(struct gp_gpo *), num_candidate_gpos + 1, "struct gp_gpo *") | |||
2188 | num_candidate_gpos + 1)(struct gp_gpo * *)_talloc_array(tmp_ctx, sizeof(struct gp_gpo *), num_candidate_gpos + 1, "struct gp_gpo *"); | |||
2189 | ||||
2190 | if (candidate_gpos == NULL((void*)0)) { | |||
2191 | ret = ENOMEM12; | |||
2192 | goto done; | |||
2193 | } | |||
2194 | ||||
2195 | gpo_dn_idx = 0; | |||
2196 | for (i = num_unenforced - 1; i >= 0; i--) { | |||
2197 | candidate_gpos[gpo_dn_idx] = talloc_zero(candidate_gpos, struct gp_gpo)(struct gp_gpo *)_talloc_zero(candidate_gpos, sizeof(struct gp_gpo ), "struct gp_gpo"); | |||
2198 | if (candidate_gpos[gpo_dn_idx] == NULL((void*)0)) { | |||
2199 | ret = ENOMEM12; | |||
2200 | goto done; | |||
2201 | } | |||
2202 | candidate_gpos[gpo_dn_idx]->gpo_dn = | |||
2203 | talloc_steal(candidate_gpos[gpo_dn_idx], unenforced_gpo_dns[i])({ __typeof__(unenforced_gpo_dns[i]) __talloc_steal_ret = (__typeof__ (unenforced_gpo_dns[i]))_talloc_steal_loc((candidate_gpos[gpo_dn_idx ]),(unenforced_gpo_dns[i]), "../sssd/src/providers/ad/ad_gpo.c" ":" "2203"); __talloc_steal_ret; }); | |||
2204 | ||||
2205 | if (candidate_gpos[gpo_dn_idx]->gpo_dn == NULL((void*)0)) { | |||
2206 | ret = ENOMEM12; | |||
2207 | goto done; | |||
2208 | } | |||
2209 | DEBUG(SSSDBG_TRACE_FUNC,do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2211, __FUNCTION__, __debug_macro_level, "candidate_gpos[%d]->gpo_dn: %s\n" , gpo_dn_idx, candidate_gpos[gpo_dn_idx]->gpo_dn); } } while (0) | |||
2210 | "candidate_gpos[%d]->gpo_dn: %s\n",do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2211, __FUNCTION__, __debug_macro_level, "candidate_gpos[%d]->gpo_dn: %s\n" , gpo_dn_idx, candidate_gpos[gpo_dn_idx]->gpo_dn); } } while (0) | |||
2211 | gpo_dn_idx, candidate_gpos[gpo_dn_idx]->gpo_dn)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2211, __FUNCTION__, __debug_macro_level, "candidate_gpos[%d]->gpo_dn: %s\n" , gpo_dn_idx, candidate_gpos[gpo_dn_idx]->gpo_dn); } } while (0); | |||
2212 | gpo_dn_idx++; | |||
2213 | } | |||
2214 | ||||
2215 | for (i = 0; i < num_enforced; i++) { | |||
2216 | ||||
2217 | candidate_gpos[gpo_dn_idx] = talloc_zero(candidate_gpos, struct gp_gpo)(struct gp_gpo *)_talloc_zero(candidate_gpos, sizeof(struct gp_gpo ), "struct gp_gpo"); | |||
2218 | if (candidate_gpos[gpo_dn_idx] == NULL((void*)0)) { | |||
2219 | ret = ENOMEM12; | |||
2220 | goto done; | |||
2221 | } | |||
2222 | ||||
2223 | candidate_gpos[gpo_dn_idx]->gpo_dn = | |||
2224 | talloc_steal(candidate_gpos[gpo_dn_idx], enforced_gpo_dns[i])({ __typeof__(enforced_gpo_dns[i]) __talloc_steal_ret = (__typeof__ (enforced_gpo_dns[i]))_talloc_steal_loc((candidate_gpos[gpo_dn_idx ]),(enforced_gpo_dns[i]), "../sssd/src/providers/ad/ad_gpo.c" ":" "2224"); __talloc_steal_ret; }); | |||
2225 | if (candidate_gpos[gpo_dn_idx]->gpo_dn == NULL((void*)0)) { | |||
2226 | ret = ENOMEM12; | |||
2227 | goto done; | |||
2228 | } | |||
2229 | ||||
2230 | DEBUG(SSSDBG_TRACE_FUNC,do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2232, __FUNCTION__, __debug_macro_level, "candidate_gpos[%d]->gpo_dn: %s\n" , gpo_dn_idx, candidate_gpos[gpo_dn_idx]->gpo_dn); } } while (0) | |||
2231 | "candidate_gpos[%d]->gpo_dn: %s\n",do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2232, __FUNCTION__, __debug_macro_level, "candidate_gpos[%d]->gpo_dn: %s\n" , gpo_dn_idx, candidate_gpos[gpo_dn_idx]->gpo_dn); } } while (0) | |||
2232 | gpo_dn_idx, candidate_gpos[gpo_dn_idx]->gpo_dn)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2232, __FUNCTION__, __debug_macro_level, "candidate_gpos[%d]->gpo_dn: %s\n" , gpo_dn_idx, candidate_gpos[gpo_dn_idx]->gpo_dn); } } while (0); | |||
2233 | gpo_dn_idx++; | |||
2234 | } | |||
2235 | ||||
2236 | candidate_gpos[gpo_dn_idx] = NULL((void*)0); | |||
2237 | ||||
2238 | *_candidate_gpos = talloc_steal(mem_ctx, candidate_gpos)({ __typeof__(candidate_gpos) __talloc_steal_ret = (__typeof__ (candidate_gpos))_talloc_steal_loc((mem_ctx),(candidate_gpos) , "../sssd/src/providers/ad/ad_gpo.c" ":" "2238"); __talloc_steal_ret ; }); | |||
2239 | *_num_candidate_gpos = num_candidate_gpos; | |||
2240 | ||||
2241 | ret = EOK0; | |||
2242 | ||||
2243 | done: | |||
2244 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "../sssd/src/providers/ad/ad_gpo.c" ":" "2244"); | |||
2245 | return ret; | |||
2246 | } | |||
2247 | ||||
2248 | /* | |||
2249 | * This function converts the input_path to an smb uri, which is used to | |||
2250 | * populate the _converted_path output parameter. The output is constructed by | |||
2251 | * concatenating the following elements: | |||
2252 | * - SMB_STANDARD_URI ("smb://") | |||
2253 | * - server_hostname (which replaces domain_name in input path) | |||
2254 | * - smb_path (which starts with the slash immediately after the domain name | |||
2255 | * Additionally, each forward slash ('\') is replaced with a back slash ('/') | |||
2256 | * | |||
2257 | * Example: if input_path = "\\foo.com\SysVol\foo.com\..." and | |||
2258 | * server_hostname = "adserver.foo.com", then _converted_path would be | |||
2259 | * "smb://adserver.foo.com/SysVol/foo.com/..." | |||
2260 | */ | |||
2261 | static errno_t | |||
2262 | ad_gpo_convert_to_smb_uri(TALLOC_CTX *mem_ctx, | |||
2263 | char *server_hostname, | |||
2264 | char *input_path, | |||
2265 | const char **_converted_path) | |||
2266 | { | |||
2267 | char *ptr; | |||
2268 | const char delim = '\\'; | |||
2269 | int ret; | |||
2270 | int num_seps = 0; | |||
2271 | char *smb_path; | |||
2272 | ||||
2273 | DEBUG(SSSDBG_TRACE_ALL, "input_path: %s\n", input_path)do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2273, __FUNCTION__, __debug_macro_level, "input_path: %s\n" , input_path); } } while (0); | |||
2274 | ||||
2275 | if (input_path == NULL((void*)0) || | |||
2276 | *input_path == '\0' || | |||
2277 | _converted_path == NULL((void*)0)) { | |||
2278 | ret = EINVAL22; | |||
2279 | goto done; | |||
2280 | } | |||
2281 | ||||
2282 | ptr = input_path; | |||
2283 | while ((ptr = strchr(ptr, delim)(__extension__ (__builtin_constant_p (delim) && !__builtin_constant_p (ptr) && (delim) == '\0' ? (char *) __rawmemchr (ptr , delim) : __builtin_strchr (ptr, delim))))) { | |||
2284 | num_seps++; | |||
2285 | if (num_seps == 3) { | |||
2286 | /* keep track of path from third slash onwards (after domain name) */ | |||
2287 | smb_path = ptr; | |||
2288 | } | |||
2289 | *ptr = '/'; | |||
2290 | ptr++; | |||
2291 | } | |||
2292 | ||||
2293 | if (num_seps == 0) { | |||
2294 | ret = EINVAL22; | |||
2295 | goto done; | |||
2296 | } | |||
2297 | ||||
2298 | *_converted_path = talloc_asprintf(mem_ctx, "%s%s%s", | |||
| ||||
2299 | SMB_STANDARD_URI"smb://", | |||
2300 | server_hostname, | |||
2301 | smb_path); | |||
2302 | ret = EOK0; | |||
2303 | ||||
2304 | done: | |||
2305 | return ret; | |||
2306 | } | |||
2307 | ||||
2308 | /* | |||
2309 | * This function populates the _cse_guid_list output parameter by parsing the | |||
2310 | * input raw_machine_ext_names_value into an array of cse_guid strings. | |||
2311 | * | |||
2312 | * The raw_machine_ext_names_value is a single string in the following format: | |||
2313 | * "[{cse_guid_1}{tool_guid1}]...[{cse_guid_n}{tool_guid_n}]" | |||
2314 | */ | |||
2315 | static errno_t | |||
2316 | ad_gpo_parse_machine_ext_names(TALLOC_CTX *mem_ctx, | |||
2317 | char *raw_machine_ext_names_value, | |||
2318 | const char ***_gpo_cse_guids, | |||
2319 | int *_num_gpo_cse_guids) | |||
2320 | { | |||
2321 | TALLOC_CTX *tmp_ctx = NULL((void*)0); | |||
2322 | char *ptr; | |||
2323 | char *first; | |||
2324 | char *last; | |||
2325 | char *cse_guid; | |||
2326 | char *tool_guid; | |||
2327 | const char delim = ']'; | |||
2328 | const char **gpo_cse_guids; | |||
2329 | int i; | |||
2330 | int ret; | |||
2331 | int num_gpo_cse_guids = 0; | |||
2332 | ||||
2333 | if (raw_machine_ext_names_value == NULL((void*)0) || | |||
2334 | *raw_machine_ext_names_value == '\0' || | |||
2335 | _gpo_cse_guids == NULL((void*)0)) { | |||
2336 | return EINVAL22; | |||
2337 | } | |||
2338 | ||||
2339 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "../sssd/src/providers/ad/ad_gpo.c" ":" "2339"); | |||
2340 | if (tmp_ctx == NULL((void*)0)) { | |||
2341 | ret = ENOMEM12; | |||
2342 | goto done; | |||
2343 | } | |||
2344 | ||||
2345 | ptr = raw_machine_ext_names_value; | |||
2346 | while ((ptr = strchr(ptr, delim)(__extension__ (__builtin_constant_p (delim) && !__builtin_constant_p (ptr) && (delim) == '\0' ? (char *) __rawmemchr (ptr , delim) : __builtin_strchr (ptr, delim))))) { | |||
2347 | ptr++; | |||
2348 | num_gpo_cse_guids++; | |||
2349 | } | |||
2350 | ||||
2351 | if (num_gpo_cse_guids == 0) { | |||
2352 | ret = EINVAL22; | |||
2353 | goto done; | |||
2354 | } | |||
2355 | ||||
2356 | gpo_cse_guids = talloc_array(tmp_ctx, const char *, num_gpo_cse_guids + 1)(const char * *)_talloc_array(tmp_ctx, sizeof(const char *), num_gpo_cse_guids + 1, "const char *"); | |||
2357 | if (gpo_cse_guids == NULL((void*)0)) { | |||
2358 | ret = ENOMEM12; | |||
2359 | goto done; | |||
2360 | } | |||
2361 | ||||
2362 | ptr = raw_machine_ext_names_value; | |||
2363 | for (i = 0; i < num_gpo_cse_guids; i++) { | |||
2364 | first = ptr + 1; | |||
2365 | last = strchr(first, delim)(__extension__ (__builtin_constant_p (delim) && !__builtin_constant_p (first) && (delim) == '\0' ? (char *) __rawmemchr (first , delim) : __builtin_strchr (first, delim))); | |||
2366 | if (last == NULL((void*)0)) { | |||
2367 | break; | |||
2368 | } | |||
2369 | *last = '\0'; | |||
2370 | last++; | |||
2371 | cse_guid = first; | |||
2372 | first ++; | |||
2373 | tool_guid = strchr(first, '{')(__extension__ (__builtin_constant_p ('{') && !__builtin_constant_p (first) && ('{') == '\0' ? (char *) __rawmemchr (first , '{') : __builtin_strchr (first, '{'))); | |||
2374 | if (tool_guid == NULL((void*)0)) { | |||
2375 | break; | |||
2376 | } | |||
2377 | *tool_guid = '\0'; | |||
2378 | gpo_cse_guids[i] = talloc_strdup(gpo_cse_guids, cse_guid); | |||
2379 | ptr = last; | |||
2380 | } | |||
2381 | gpo_cse_guids[i] = NULL((void*)0); | |||
2382 | ||||
2383 | DEBUG(SSSDBG_TRACE_ALL, "num_gpo_cse_guids: %d\n", num_gpo_cse_guids)do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2383, __FUNCTION__, __debug_macro_level, "num_gpo_cse_guids: %d\n" , num_gpo_cse_guids); } } while (0); | |||
2384 | ||||
2385 | for (i = 0; i < num_gpo_cse_guids; i++) { | |||
2386 | DEBUG(SSSDBG_TRACE_ALL,do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2387, __FUNCTION__, __debug_macro_level, "gpo_cse_guids[%d] is %s\n" , i, gpo_cse_guids[i]); } } while (0) | |||
2387 | "gpo_cse_guids[%d] is %s\n", i, gpo_cse_guids[i])do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2387, __FUNCTION__, __debug_macro_level, "gpo_cse_guids[%d] is %s\n" , i, gpo_cse_guids[i]); } } while (0); | |||
2388 | } | |||
2389 | ||||
2390 | *_gpo_cse_guids = talloc_steal(mem_ctx, gpo_cse_guids)({ __typeof__(gpo_cse_guids) __talloc_steal_ret = (__typeof__ (gpo_cse_guids))_talloc_steal_loc((mem_ctx),(gpo_cse_guids), "../sssd/src/providers/ad/ad_gpo.c" ":" "2390"); __talloc_steal_ret; }); | |||
2391 | *_num_gpo_cse_guids = num_gpo_cse_guids; | |||
2392 | ret = EOK0; | |||
2393 | ||||
2394 | done: | |||
2395 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "../sssd/src/providers/ad/ad_gpo.c" ":" "2395"); | |||
2396 | return ret; | |||
2397 | } | |||
2398 | ||||
2399 | enum ndr_err_code | |||
2400 | ad_gpo_ndr_pull_security_descriptor(struct ndr_pull *ndr, int ndr_flags, | |||
2401 | struct security_descriptor *r); | |||
2402 | ||||
2403 | /* | |||
2404 | * This function parses the input data blob and assigns the resulting | |||
2405 | * security_descriptor object to the _gpo_sd output parameter. | |||
2406 | */ | |||
2407 | static errno_t ad_gpo_parse_sd(TALLOC_CTX *mem_ctx, | |||
2408 | uint8_t *data, | |||
2409 | size_t length, | |||
2410 | struct security_descriptor **_gpo_sd) | |||
2411 | { | |||
2412 | ||||
2413 | struct ndr_pull *ndr_pull = NULL((void*)0); | |||
2414 | struct security_descriptor sd; | |||
2415 | DATA_BLOB blob; | |||
2416 | enum ndr_err_code ndr_err; | |||
2417 | ||||
2418 | blob.data = data; | |||
2419 | blob.length = length; | |||
2420 | ||||
2421 | ndr_pull = ndr_pull_init_blob(&blob, mem_ctx); | |||
2422 | if (ndr_pull == NULL((void*)0)) { | |||
2423 | DEBUG(SSSDBG_OP_FAILURE, "ndr_pull_init_blob() failed.\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2423, __FUNCTION__, __debug_macro_level, "ndr_pull_init_blob() failed.\n" ); } } while (0); | |||
2424 | return EINVAL22; | |||
2425 | } | |||
2426 | ||||
2427 | ndr_err = ad_gpo_ndr_pull_security_descriptor(ndr_pull, | |||
2428 | NDR_SCALARS0x100|NDR_BUFFERS0x200, | |||
2429 | &sd); | |||
2430 | ||||
2431 | if (ndr_err != NDR_ERR_SUCCESS) { | |||
2432 | DEBUG(SSSDBG_CRIT_FAILURE, "Failed to pull security descriptor\n")do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2432, __FUNCTION__, __debug_macro_level, "Failed to pull security descriptor\n" ); } } while (0); | |||
2433 | return EINVAL22; | |||
2434 | } | |||
2435 | ||||
2436 | *_gpo_sd = talloc_memdup(mem_ctx, &sd, sizeof(struct security_descriptor))_talloc_memdup(mem_ctx, &sd, sizeof(struct security_descriptor ), "../sssd/src/providers/ad/ad_gpo.c" ":" "2436"); | |||
2437 | ||||
2438 | return EOK0; | |||
2439 | } | |||
2440 | ||||
2441 | /* == ad_gpo_process_gpo_send/recv implementation ========================== */ | |||
2442 | ||||
2443 | struct ad_gpo_process_gpo_state { | |||
2444 | struct tevent_context *ev; | |||
2445 | struct sdap_id_op *sdap_op; | |||
2446 | struct sdap_options *opts; | |||
2447 | char *server_hostname; | |||
2448 | int timeout; | |||
2449 | struct gp_gpo **candidate_gpos; | |||
2450 | int num_candidate_gpos; | |||
2451 | int gpo_index; | |||
2452 | }; | |||
2453 | ||||
2454 | static errno_t ad_gpo_get_gpo_attrs_step(struct tevent_req *req); | |||
2455 | static void ad_gpo_get_gpo_attrs_done(struct tevent_req *subreq); | |||
2456 | ||||
2457 | /* | |||
2458 | * This function uses the input som_list to populate a prioritized list of | |||
2459 | * gp_gpo objects, prioritized based on SOM type, link order, and whether the | |||
2460 | * GPO is "enforced". This list represents the initial set of candidate GPOs | |||
2461 | * that might be applicable to the target. This list can not be expanded, but | |||
2462 | * it might be reduced based on subsequent filtering steps. The GPO object DNs | |||
2463 | * are used to retrieve certain LDAP attributes of each GPO object, that are | |||
2464 | * parsed into the various fields of the gp_gpo object. | |||
2465 | */ | |||
2466 | struct tevent_req * | |||
2467 | ad_gpo_process_gpo_send(TALLOC_CTX *mem_ctx, | |||
2468 | struct tevent_context *ev, | |||
2469 | struct sdap_id_op *sdap_op, | |||
2470 | struct sdap_options *opts, | |||
2471 | char *server_hostname, | |||
2472 | int timeout, | |||
2473 | struct gp_som **som_list) | |||
2474 | { | |||
2475 | struct tevent_req *req; | |||
2476 | struct ad_gpo_process_gpo_state *state; | |||
2477 | errno_t ret; | |||
2478 | ||||
2479 | req = tevent_req_create(mem_ctx, &state, struct ad_gpo_process_gpo_state)_tevent_req_create((mem_ctx), (&state), sizeof(struct ad_gpo_process_gpo_state ), "struct ad_gpo_process_gpo_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "2479"); | |||
2480 | if (req == NULL((void*)0)) { | |||
2481 | DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n")do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2481, __FUNCTION__, __debug_macro_level, "tevent_req_create() failed\n" ); } } while (0); | |||
2482 | return NULL((void*)0); | |||
2483 | } | |||
2484 | ||||
2485 | state->ev = ev; | |||
2486 | state->sdap_op = sdap_op; | |||
2487 | state->opts = opts; | |||
2488 | state->server_hostname = server_hostname; | |||
2489 | state->timeout = timeout; | |||
2490 | state->gpo_index = -1; | |||
2491 | state->candidate_gpos = NULL((void*)0); | |||
2492 | state->num_candidate_gpos = 0; | |||
2493 | ||||
2494 | ret = ad_gpo_populate_candidate_gpos(state, | |||
2495 | som_list, | |||
2496 | &state->candidate_gpos, | |||
2497 | &state->num_candidate_gpos); | |||
2498 | ||||
2499 | if (ret != EOK0) { | |||
2500 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2502, __FUNCTION__, __debug_macro_level, "Unable to retrieve GPO List: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2501 | "Unable to retrieve GPO List: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2502, __FUNCTION__, __debug_macro_level, "Unable to retrieve GPO List: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2502 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2502, __FUNCTION__, __debug_macro_level, "Unable to retrieve GPO List: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
2503 | ret = ENOENT2; | |||
2504 | goto immediately; | |||
2505 | } | |||
2506 | ||||
2507 | if (state->candidate_gpos == NULL((void*)0)) { | |||
2508 | DEBUG(SSSDBG_OP_FAILURE, "no gpos found\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2508, __FUNCTION__, __debug_macro_level, "no gpos found\n") ; } } while (0); | |||
2509 | ret = ENOENT2; | |||
2510 | goto immediately; | |||
2511 | } | |||
2512 | ||||
2513 | ret = ad_gpo_get_gpo_attrs_step(req); | |||
2514 | ||||
2515 | immediately: | |||
2516 | ||||
2517 | if (ret == EOK0) { | |||
2518 | tevent_req_done(req)_tevent_req_done(req, "../sssd/src/providers/ad/ad_gpo.c" ":" "2518"); | |||
2519 | tevent_req_post(req, ev); | |||
2520 | } else if (ret != EAGAIN11) { | |||
2521 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "2521"); | |||
2522 | tevent_req_post(req, ev); | |||
2523 | } | |||
2524 | ||||
2525 | return req; | |||
2526 | } | |||
2527 | ||||
2528 | static errno_t | |||
2529 | ad_gpo_get_gpo_attrs_step(struct tevent_req *req) | |||
2530 | { | |||
2531 | const char *attrs[] = {AD_AT_NT_SEC_DESC"nTSecurityDescriptor", AD_AT_CN"cn", AD_AT_DISPLAY_NAME"displayName", | |||
2532 | AD_AT_FILE_SYS_PATH"gPCFileSysPath", AD_AT_VERSION_NUMBER"versionNumber", | |||
2533 | AD_AT_MACHINE_EXT_NAMES"gPCMachineExtensionNames", AD_AT_FUNC_VERSION"gPCFunctionalityVersion", | |||
2534 | AD_AT_FLAGS"flags", NULL((void*)0)}; | |||
2535 | struct tevent_req *subreq; | |||
2536 | struct ad_gpo_process_gpo_state *state; | |||
2537 | ||||
2538 | state = tevent_req_data(req, struct ad_gpo_process_gpo_state)(struct ad_gpo_process_gpo_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_process_gpo_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "2538"); | |||
2539 | ||||
2540 | state->gpo_index++; | |||
2541 | struct gp_gpo *gp_gpo = state->candidate_gpos[state->gpo_index]; | |||
2542 | ||||
2543 | /* gp_gpo is NULL only after all GPOs have been processed */ | |||
2544 | if (gp_gpo == NULL((void*)0)) return EOK0; | |||
2545 | ||||
2546 | const char *gpo_dn = gp_gpo->gpo_dn; | |||
2547 | ||||
2548 | subreq = sdap_sd_search_send(state, state->ev, | |||
2549 | state->opts, sdap_id_op_handle(state->sdap_op), | |||
2550 | gpo_dn, SECINFO_DACL( 0x00000004 ), attrs, state->timeout); | |||
2551 | ||||
2552 | if (subreq == NULL((void*)0)) { | |||
2553 | DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2553, __FUNCTION__, __debug_macro_level, "sdap_get_generic_send failed.\n" ); } } while (0); | |||
2554 | return ENOMEM12; | |||
2555 | } | |||
2556 | ||||
2557 | tevent_req_set_callback(subreq, ad_gpo_get_gpo_attrs_done, req); | |||
2558 | return EAGAIN11; | |||
2559 | } | |||
2560 | ||||
2561 | static void | |||
2562 | ad_gpo_get_gpo_attrs_done(struct tevent_req *subreq) | |||
2563 | { | |||
2564 | struct tevent_req *req; | |||
2565 | struct ad_gpo_process_gpo_state *state; | |||
2566 | int ret; | |||
2567 | int dp_error; | |||
2568 | size_t num_results; | |||
2569 | struct sysdb_attrs **results; | |||
2570 | struct ldb_message_element *el = NULL((void*)0); | |||
2571 | const char *gpo_guid = NULL((void*)0); | |||
2572 | const char *smb_uri = NULL((void*)0); | |||
2573 | const char *gpo_display_name = NULL((void*)0); | |||
2574 | const char *raw_file_sys_path = NULL((void*)0); | |||
2575 | char *file_sys_path = NULL((void*)0); | |||
2576 | uint8_t *raw_machine_ext_names = NULL((void*)0); | |||
2577 | ||||
2578 | req = tevent_req_callback_data(subreq, struct tevent_req)(struct tevent_req *)_talloc_get_type_abort(_tevent_req_callback_data (subreq), "struct tevent_req", "../sssd/src/providers/ad/ad_gpo.c" ":" "2578"); | |||
2579 | state = tevent_req_data(req, struct ad_gpo_process_gpo_state)(struct ad_gpo_process_gpo_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_process_gpo_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "2579"); | |||
2580 | ||||
2581 | ret = sdap_sd_search_recv(subreq, state, &num_results, &results); | |||
2582 | talloc_zfree(subreq)do { _talloc_free(((void *)((uintptr_t)(subreq))), "../sssd/src/providers/ad/ad_gpo.c" ":" "2582"); subreq = ((void*)0); } while(0); | |||
2583 | ||||
2584 | if (ret != EOK0) { | |||
| ||||
2585 | ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); | |||
2586 | /* TBD: handle (dp_error == DP_ERR_OFFLINE) case */ | |||
2587 | ||||
2588 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2590, __FUNCTION__, __debug_macro_level, "Unable to get GPO attributes: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2589 | "Unable to get GPO attributes: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2590, __FUNCTION__, __debug_macro_level, "Unable to get GPO attributes: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2590 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2590, __FUNCTION__, __debug_macro_level, "Unable to get GPO attributes: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
2591 | ret = ENOENT2; | |||
2592 | goto done; | |||
2593 | } | |||
2594 | ||||
2595 | if ((num_results < 1) || (results == NULL((void*)0))) { | |||
2596 | DEBUG(SSSDBG_OP_FAILURE, "no attrs found for GPO; try next GPO.\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2596, __FUNCTION__, __debug_macro_level, "no attrs found for GPO; try next GPO.\n" ); } } while (0); | |||
2597 | ret = ad_gpo_get_gpo_attrs_step(req); | |||
2598 | goto done; | |||
2599 | } | |||
2600 | else if (num_results > 1) { | |||
2601 | DEBUG(SSSDBG_OP_FAILURE, "Received multiple replies\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2601, __FUNCTION__, __debug_macro_level, "Received multiple replies\n" ); } } while (0); | |||
2602 | ret = ERR_INTERNAL; | |||
2603 | goto done; | |||
2604 | } | |||
2605 | ||||
2606 | struct gp_gpo *gp_gpo = state->candidate_gpos[state->gpo_index]; | |||
2607 | ||||
2608 | /* retrieve AD_AT_CN */ | |||
2609 | ret = sysdb_attrs_get_string(results[0], AD_AT_CN"cn", &gpo_guid); | |||
2610 | if (ret != EOK0) { | |||
2611 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2613, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2612 | "sysdb_attrs_get_string failed: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2613, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2613 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2613, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
2614 | goto done; | |||
2615 | } | |||
2616 | ||||
2617 | gp_gpo->gpo_guid = talloc_steal(gp_gpo, gpo_guid)({ __typeof__(gpo_guid) __talloc_steal_ret = (__typeof__(gpo_guid ))_talloc_steal_loc((gp_gpo),(gpo_guid), "../sssd/src/providers/ad/ad_gpo.c" ":" "2617"); __talloc_steal_ret; }); | |||
2618 | if (gp_gpo->gpo_guid == NULL((void*)0)) { | |||
2619 | ret = ENOMEM12; | |||
2620 | goto done; | |||
2621 | } | |||
2622 | ||||
2623 | DEBUG(SSSDBG_TRACE_ALL, "populating attrs for gpo_guid: %s\n",do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2624, __FUNCTION__, __debug_macro_level, "populating attrs for gpo_guid: %s\n" , gp_gpo->gpo_guid); } } while (0) | |||
2624 | gp_gpo->gpo_guid)do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2624, __FUNCTION__, __debug_macro_level, "populating attrs for gpo_guid: %s\n" , gp_gpo->gpo_guid); } } while (0); | |||
2625 | ||||
2626 | /* retrieve AD_AT_DISPLAY_NAME */ | |||
2627 | ret = sysdb_attrs_get_string(results[0], AD_AT_DISPLAY_NAME"displayName", | |||
2628 | &gpo_display_name); | |||
2629 | if (ret != EOK0) { | |||
2630 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2632, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2631 | "sysdb_attrs_get_string failed: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2632, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2632 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2632, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
2633 | goto done; | |||
2634 | } | |||
2635 | ||||
2636 | gp_gpo->gpo_display_name = talloc_steal(gp_gpo, gpo_display_name)({ __typeof__(gpo_display_name) __talloc_steal_ret = (__typeof__ (gpo_display_name))_talloc_steal_loc((gp_gpo),(gpo_display_name ), "../sssd/src/providers/ad/ad_gpo.c" ":" "2636"); __talloc_steal_ret ; }); | |||
2637 | if (gp_gpo->gpo_display_name == NULL((void*)0)) { | |||
2638 | ret = ENOMEM12; | |||
2639 | goto done; | |||
2640 | } | |||
2641 | ||||
2642 | DEBUG(SSSDBG_TRACE_ALL, "gpo_display_name: %s\n",do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2643, __FUNCTION__, __debug_macro_level, "gpo_display_name: %s\n" , gp_gpo->gpo_display_name); } } while (0) | |||
2643 | gp_gpo->gpo_display_name)do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2643, __FUNCTION__, __debug_macro_level, "gpo_display_name: %s\n" , gp_gpo->gpo_display_name); } } while (0); | |||
2644 | ||||
2645 | /* retrieve AD_AT_FILE_SYS_PATH */ | |||
2646 | ret = sysdb_attrs_get_string(results[0], | |||
2647 | AD_AT_FILE_SYS_PATH"gPCFileSysPath", | |||
2648 | &raw_file_sys_path); | |||
2649 | ||||
2650 | if (ret != EOK0) { | |||
2651 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2653, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2652 | "sysdb_attrs_get_string failed: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2653, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2653 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2653, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_string failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
2654 | goto done; | |||
2655 | } | |||
2656 | ||||
2657 | file_sys_path = talloc_strdup(gp_gpo, raw_file_sys_path); | |||
2658 | ad_gpo_convert_to_smb_uri(state, state->server_hostname, file_sys_path, | |||
2659 | &smb_uri); | |||
2660 | ||||
2661 | gp_gpo->gpo_file_sys_path = talloc_asprintf(gp_gpo, "%s/Machine", | |||
2662 | smb_uri); | |||
2663 | if (gp_gpo->gpo_file_sys_path == NULL((void*)0)) { | |||
2664 | ret = ENOMEM12; | |||
2665 | goto done; | |||
2666 | } | |||
2667 | ||||
2668 | DEBUG(SSSDBG_TRACE_FUNC, "gpo_file_sys_path: %s\n",do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2669, __FUNCTION__, __debug_macro_level, "gpo_file_sys_path: %s\n" , gp_gpo->gpo_file_sys_path); } } while (0) | |||
2669 | gp_gpo->gpo_file_sys_path)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2669, __FUNCTION__, __debug_macro_level, "gpo_file_sys_path: %s\n" , gp_gpo->gpo_file_sys_path); } } while (0); | |||
2670 | ||||
2671 | /* retrieve AD_AT_VERSION_NUMBER */ | |||
2672 | ret = sysdb_attrs_get_uint32_t(results[0], AD_AT_VERSION_NUMBER"versionNumber", | |||
2673 | &gp_gpo->gpo_container_version); | |||
2674 | if (ret != EOK0) { | |||
2675 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2677, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_uint32_t failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2676 | "sysdb_attrs_get_uint32_t failed: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2677, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_uint32_t failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2677 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2677, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_uint32_t failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
2678 | goto done; | |||
2679 | } | |||
2680 | ||||
2681 | DEBUG(SSSDBG_TRACE_ALL, "gpo_container_version: %d\n",do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2682, __FUNCTION__, __debug_macro_level, "gpo_container_version: %d\n" , gp_gpo->gpo_container_version); } } while (0) | |||
2682 | gp_gpo->gpo_container_version)do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2682, __FUNCTION__, __debug_macro_level, "gpo_container_version: %d\n" , gp_gpo->gpo_container_version); } } while (0); | |||
2683 | ||||
2684 | /* retrieve AD_AT_MACHINE_EXT_NAMES */ | |||
2685 | ret = sysdb_attrs_get_el(results[0], AD_AT_MACHINE_EXT_NAMES"gPCMachineExtensionNames", &el); | |||
2686 | if (ret != EOK0 && ret != ENOENT2) { | |||
2687 | DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el() failed\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2687, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_el() failed\n" ); } } while (0); | |||
2688 | goto done; | |||
2689 | } | |||
2690 | if ((ret == ENOENT2) || (el->num_values == 0)) { | |||
2691 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2692, __FUNCTION__, __debug_macro_level, "machine_ext_names not found or has no value\n" ); } } while (0) | |||
2692 | "machine_ext_names not found or has no value\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2692, __FUNCTION__, __debug_macro_level, "machine_ext_names not found or has no value\n" ); } } while (0); | |||
2693 | ret = ENOENT2; | |||
2694 | goto done; | |||
2695 | } | |||
2696 | ||||
2697 | raw_machine_ext_names = el[0].values[0].data; | |||
2698 | ||||
2699 | ret = ad_gpo_parse_machine_ext_names(gp_gpo, | |||
2700 | (char *)raw_machine_ext_names, | |||
2701 | &gp_gpo->gpo_cse_guids, | |||
2702 | &gp_gpo->num_gpo_cse_guids); | |||
2703 | if (ret != EOK0) { | |||
2704 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2705, __FUNCTION__, __debug_macro_level, "ad_gpo_parse_machine_ext_names() failed\n" ); } } while (0) | |||
2705 | "ad_gpo_parse_machine_ext_names() failed\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2705, __FUNCTION__, __debug_macro_level, "ad_gpo_parse_machine_ext_names() failed\n" ); } } while (0); | |||
2706 | goto done; | |||
2707 | } | |||
2708 | ||||
2709 | /* retrieve AD_AT_FUNC_VERSION */ | |||
2710 | ret = sysdb_attrs_get_int32_t(results[0], AD_AT_FUNC_VERSION"gPCFunctionalityVersion", | |||
2711 | &gp_gpo->gpo_func_version); | |||
2712 | if (ret != EOK0) { | |||
2713 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2715, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_int32_t failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2714 | "sysdb_attrs_get_int32_t failed: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2715, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_int32_t failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2715 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2715, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_int32_t failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
2716 | goto done; | |||
2717 | } | |||
2718 | ||||
2719 | DEBUG(SSSDBG_TRACE_ALL, "gpo_func_version: %d\n",do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2720, __FUNCTION__, __debug_macro_level, "gpo_func_version: %d\n" , gp_gpo->gpo_func_version); } } while (0) | |||
2720 | gp_gpo->gpo_func_version)do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2720, __FUNCTION__, __debug_macro_level, "gpo_func_version: %d\n" , gp_gpo->gpo_func_version); } } while (0); | |||
2721 | ||||
2722 | /* retrieve AD_AT_FLAGS */ | |||
2723 | ret = sysdb_attrs_get_int32_t(results[0], AD_AT_FLAGS"flags", | |||
2724 | &gp_gpo->gpo_flags); | |||
2725 | if (ret != EOK0) { | |||
2726 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2728, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_int32_t failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2727 | "sysdb_attrs_get_int32_t failed: [%d](%s)\n",do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2728, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_int32_t failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0) | |||
2728 | ret, sss_strerror(ret))do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2728, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_int32_t failed: [%d](%s)\n" , ret, sss_strerror(ret)); } } while (0); | |||
2729 | goto done; | |||
2730 | } | |||
2731 | ||||
2732 | DEBUG(SSSDBG_TRACE_ALL, "gpo_flags: %d\n", gp_gpo->gpo_flags)do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2732, __FUNCTION__, __debug_macro_level, "gpo_flags: %d\n", gp_gpo->gpo_flags); } } while (0); | |||
2733 | ||||
2734 | /* retrieve AD_AT_NT_SEC_DESC */ | |||
2735 | ret = sysdb_attrs_get_el(results[0], AD_AT_NT_SEC_DESC"nTSecurityDescriptor", &el); | |||
2736 | if (ret != EOK0 && ret != ENOENT2) { | |||
2737 | DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el() failed\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2737, __FUNCTION__, __debug_macro_level, "sysdb_attrs_get_el() failed\n" ); } } while (0); | |||
2738 | goto done; | |||
2739 | } | |||
2740 | if ((ret == ENOENT2) || (el->num_values == 0)) { | |||
2741 | DEBUG(SSSDBG_OP_FAILURE,do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2742, __FUNCTION__, __debug_macro_level, "nt_sec_desc attribute not found or has no value\n" ); } } while (0) | |||
2742 | "nt_sec_desc attribute not found or has no value\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2742, __FUNCTION__, __debug_macro_level, "nt_sec_desc attribute not found or has no value\n" ); } } while (0); | |||
2743 | ret = ENOENT2; | |||
2744 | goto done; | |||
2745 | } | |||
2746 | ||||
2747 | ret = ad_gpo_parse_sd(gp_gpo, el[0].values[0].data, el[0].values[0].length, | |||
2748 | &gp_gpo->gpo_sd); | |||
2749 | if (ret != EOK0) { | |||
2750 | DEBUG(SSSDBG_OP_FAILURE, "ad_gpo_parse_sd() failed\n")do { int __debug_macro_level = 0x0040; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2750, __FUNCTION__, __debug_macro_level, "ad_gpo_parse_sd() failed\n" ); } } while (0); | |||
2751 | goto done; | |||
2752 | } | |||
2753 | ||||
2754 | ret = ad_gpo_get_gpo_attrs_step(req); | |||
2755 | ||||
2756 | done: | |||
2757 | ||||
2758 | if (ret == EOK0) { | |||
2759 | tevent_req_done(req)_tevent_req_done(req, "../sssd/src/providers/ad/ad_gpo.c" ":" "2759"); | |||
2760 | } else if (ret != EAGAIN11) { | |||
2761 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "2761"); | |||
2762 | } | |||
2763 | } | |||
2764 | ||||
2765 | int | |||
2766 | ad_gpo_process_gpo_recv(struct tevent_req *req, | |||
2767 | TALLOC_CTX *mem_ctx, | |||
2768 | struct gp_gpo ***candidate_gpos, | |||
2769 | int *num_candidate_gpos) | |||
2770 | { | |||
2771 | struct ad_gpo_process_gpo_state *state = | |||
2772 | tevent_req_data(req, struct ad_gpo_process_gpo_state)(struct ad_gpo_process_gpo_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_process_gpo_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "2772"); | |||
2773 | ||||
2774 | TEVENT_REQ_RETURN_ON_ERROR(req)do { enum tevent_req_state TRROEstate; uint64_t TRROEerr; if ( tevent_req_is_error(req, &TRROEstate, &TRROEerr)) { if (TRROEstate == TEVENT_REQ_USER_ERROR) { return TRROEerr; } return ERR_INTERNAL; } } while (0); | |||
2775 | ||||
2776 | *candidate_gpos = talloc_steal(mem_ctx, state->candidate_gpos)({ __typeof__(state->candidate_gpos) __talloc_steal_ret = ( __typeof__(state->candidate_gpos))_talloc_steal_loc((mem_ctx ),(state->candidate_gpos), "../sssd/src/providers/ad/ad_gpo.c" ":" "2776"); __talloc_steal_ret; }); | |||
2777 | *num_candidate_gpos = state->num_candidate_gpos; | |||
2778 | return EOK0; | |||
2779 | } | |||
2780 | ||||
2781 | /* == ad_gpo_process_cse_send/recv helpers ================================= */ | |||
2782 | ||||
2783 | static errno_t | |||
2784 | create_cse_send_buffer(TALLOC_CTX *mem_ctx, | |||
2785 | char *smb_uri, | |||
2786 | struct io_buffer **io_buf) | |||
2787 | { | |||
2788 | struct io_buffer *buf; | |||
2789 | size_t rp; | |||
2790 | int smb_uri_length; | |||
2791 | ||||
2792 | smb_uri_length = strlen(smb_uri); | |||
2793 | ||||
2794 | DEBUG(SSSDBG_TRACE_FUNC, "smb_uri: %s\n", smb_uri)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2794, __FUNCTION__, __debug_macro_level, "smb_uri: %s\n", smb_uri ); } } while (0); | |||
2795 | DEBUG(SSSDBG_TRACE_FUNC, "strlen(smb_uri): %d\n", smb_uri_length)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2795, __FUNCTION__, __debug_macro_level, "strlen(smb_uri): %d\n" , smb_uri_length); } } while (0); | |||
2796 | ||||
2797 | buf = talloc(mem_ctx, struct io_buffer)(struct io_buffer *)talloc_named_const(mem_ctx, sizeof(struct io_buffer), "struct io_buffer"); | |||
2798 | if (buf == NULL((void*)0)) { | |||
2799 | DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n")do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2799, __FUNCTION__, __debug_macro_level, "talloc failed.\n" ); } } while (0); | |||
2800 | return ENOMEM12; | |||
2801 | } | |||
2802 | ||||
2803 | buf->size = 1 * sizeof(uint32_t); | |||
2804 | if (smb_uri) { | |||
2805 | buf->size += smb_uri_length; | |||
2806 | } | |||
2807 | ||||
2808 | DEBUG(SSSDBG_TRACE_ALL, "buffer size: %zu\n", buf->size)do { int __debug_macro_level = 0x4000; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2808, __FUNCTION__, __debug_macro_level, "buffer size: %zu\n" , buf->size); } } while (0); | |||
2809 | ||||
2810 | buf->data = talloc_size(buf, buf->size)talloc_named_const(buf, buf->size, "../sssd/src/providers/ad/ad_gpo.c" ":" "2810"); | |||
2811 | if (buf->data == NULL((void*)0)) { | |||
2812 | DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n")do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2812, __FUNCTION__, __debug_macro_level, "talloc_size failed.\n" ); } } while (0); | |||
2813 | talloc_free(buf)_talloc_free(buf, "../sssd/src/providers/ad/ad_gpo.c" ":" "2813" ); | |||
2814 | return ENOMEM12; | |||
2815 | } | |||
2816 | ||||
2817 | rp = 0; | |||
2818 | /* smb_uri */ | |||
2819 | if (smb_uri) { | |||
2820 | SAFEALIGN_SET_UINT32(&buf->data[rp], smb_uri_length, &rp)do { uint32_t CV_MACRO_val = (uint32_t)(smb_uri_length); safealign_memcpy (&buf->data[rp], &CV_MACRO_val, sizeof(uint32_t), & rp); } while(0); | |||
2821 | safealign_memcpy(&buf->data[rp], smb_uri, smb_uri_length, &rp); | |||
2822 | } else { | |||
2823 | SAFEALIGN_SET_UINT32(&buf->data[rp], 0, &rp)do { uint32_t CV_MACRO_val = (uint32_t)(0); safealign_memcpy( &buf->data[rp], &CV_MACRO_val, sizeof(uint32_t), & rp); } while(0); | |||
2824 | } | |||
2825 | ||||
2826 | *io_buf = buf; | |||
2827 | return EOK0; | |||
2828 | } | |||
2829 | ||||
2830 | static errno_t | |||
2831 | parse_gpo_child_response(TALLOC_CTX *mem_ctx, | |||
2832 | uint8_t *buf, ssize_t size, | |||
2833 | char ***_allowed_sids, | |||
2834 | int *_allowed_size, | |||
2835 | char ***_denied_sids, | |||
2836 | int *_denied_size) | |||
2837 | { | |||
2838 | size_t p = 0; | |||
2839 | uint32_t res; | |||
2840 | errno_t ret; | |||
2841 | int allowed_size = 0; | |||
2842 | int denied_size = 0; | |||
2843 | int i = 0; | |||
2844 | int sid_len = 0; | |||
2845 | char **allowed_sids; | |||
2846 | char **denied_sids; | |||
2847 | TALLOC_CTX *tmp_ctx = NULL((void*)0); | |||
2848 | ||||
2849 | tmp_ctx = talloc_new(NULL)talloc_named_const(((void*)0), 0, "talloc_new: " "../sssd/src/providers/ad/ad_gpo.c" ":" "2849"); | |||
2850 | if (tmp_ctx == NULL((void*)0)) { | |||
2851 | ret = ENOMEM12; | |||
2852 | goto done; | |||
2853 | } | |||
2854 | ||||
2855 | /* operation result code */ | |||
2856 | SAFEALIGN_COPY_UINT32_CHECK(&res, buf + p, size, &p)do { if ((*(&p) + sizeof(uint32_t)) > (size) || (((size_t )(sizeof(uint32_t))) > ((18446744073709551615UL) - ((size_t )(*(&p)))))) return 22; safealign_memcpy(&res, buf + p , sizeof(uint32_t), &p); } while(0); | |||
2857 | ||||
2858 | /* allowed_size */ | |||
2859 | SAFEALIGN_COPY_UINT32_CHECK(&allowed_size, buf + p, size, &p)do { if ((*(&p) + sizeof(uint32_t)) > (size) || (((size_t )(sizeof(uint32_t))) > ((18446744073709551615UL) - ((size_t )(*(&p)))))) return 22; safealign_memcpy(&allowed_size , buf + p, sizeof(uint32_t), &p); } while(0); | |||
2860 | DEBUG(SSSDBG_TRACE_FUNC, "child response allowed_size: %d\n", allowed_size)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2860, __FUNCTION__, __debug_macro_level, "child response allowed_size: %d\n" , allowed_size); } } while (0); | |||
2861 | ||||
2862 | allowed_sids = talloc_array(tmp_ctx, char *, allowed_size)(char * *)_talloc_array(tmp_ctx, sizeof(char *), allowed_size , "char *"); | |||
2863 | if (allowed_sids == NULL((void*)0)) { | |||
2864 | ret = ENOMEM12; | |||
2865 | goto done; | |||
2866 | } | |||
2867 | ||||
2868 | for (i = 0; i < allowed_size; i++) { | |||
2869 | SAFEALIGN_COPY_UINT32_CHECK(&sid_len, buf + p, size, &p)do { if ((*(&p) + sizeof(uint32_t)) > (size) || (((size_t )(sizeof(uint32_t))) > ((18446744073709551615UL) - ((size_t )(*(&p)))))) return 22; safealign_memcpy(&sid_len, buf + p, sizeof(uint32_t), &p); } while(0); | |||
2870 | if ((p + sid_len ) > size) { | |||
2871 | ret = EINVAL22; | |||
2872 | goto done; | |||
2873 | } | |||
2874 | allowed_sids[i] = talloc_strndup(allowed_sids, | |||
2875 | (const char *)buf + p, | |||
2876 | sid_len); | |||
2877 | if (allowed_sids[i] == NULL((void*)0)) { | |||
2878 | ret = ENOMEM12; | |||
2879 | goto done; | |||
2880 | } | |||
2881 | p += sid_len; | |||
2882 | } | |||
2883 | ||||
2884 | /* denied_size */ | |||
2885 | SAFEALIGN_COPY_UINT32_CHECK(&denied_size, buf + p, size, &p)do { if ((*(&p) + sizeof(uint32_t)) > (size) || (((size_t )(sizeof(uint32_t))) > ((18446744073709551615UL) - ((size_t )(*(&p)))))) return 22; safealign_memcpy(&denied_size , buf + p, sizeof(uint32_t), &p); } while(0); | |||
2886 | DEBUG(SSSDBG_TRACE_FUNC, "child response denied_size: %d\n", denied_size)do { int __debug_macro_level = 0x0400; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2886, __FUNCTION__, __debug_macro_level, "child response denied_size: %d\n" , denied_size); } } while (0); | |||
2887 | ||||
2888 | denied_sids = talloc_array(tmp_ctx, char *, denied_size)(char * *)_talloc_array(tmp_ctx, sizeof(char *), denied_size, "char *"); | |||
2889 | if (denied_sids == NULL((void*)0)) { | |||
2890 | ret = ENOMEM12; | |||
2891 | goto done; | |||
2892 | } | |||
2893 | ||||
2894 | for (i = 0; i < denied_size; i++) { | |||
2895 | SAFEALIGN_COPY_UINT32_CHECK(&sid_len, buf + p, size, &p)do { if ((*(&p) + sizeof(uint32_t)) > (size) || (((size_t )(sizeof(uint32_t))) > ((18446744073709551615UL) - ((size_t )(*(&p)))))) return 22; safealign_memcpy(&sid_len, buf + p, sizeof(uint32_t), &p); } while(0); | |||
2896 | if ((p + sid_len ) > size) { | |||
2897 | ret = EINVAL22; | |||
2898 | goto done; | |||
2899 | } | |||
2900 | denied_sids[i] = talloc_strndup(denied_sids, | |||
2901 | (const char *)buf + p, | |||
2902 | sid_len); | |||
2903 | if (denied_sids[i] == NULL((void*)0)) { | |||
2904 | ret = ENOMEM12; | |||
2905 | goto done; | |||
2906 | } | |||
2907 | p += sid_len; | |||
2908 | } | |||
2909 | ||||
2910 | *_allowed_size = allowed_size; | |||
2911 | *_allowed_sids = talloc_steal(mem_ctx, allowed_sids)({ __typeof__(allowed_sids) __talloc_steal_ret = (__typeof__( allowed_sids))_talloc_steal_loc((mem_ctx),(allowed_sids), "../sssd/src/providers/ad/ad_gpo.c" ":" "2911"); __talloc_steal_ret; }); | |||
2912 | *_denied_size = denied_size; | |||
2913 | *_denied_sids = talloc_steal(mem_ctx, denied_sids)({ __typeof__(denied_sids) __talloc_steal_ret = (__typeof__(denied_sids ))_talloc_steal_loc((mem_ctx),(denied_sids), "../sssd/src/providers/ad/ad_gpo.c" ":" "2913"); __talloc_steal_ret; }); | |||
2914 | ||||
2915 | ret = EOK0; | |||
2916 | ||||
2917 | done: | |||
2918 | talloc_free(tmp_ctx)_talloc_free(tmp_ctx, "../sssd/src/providers/ad/ad_gpo.c" ":" "2918"); | |||
2919 | return ret; | |||
2920 | } | |||
2921 | ||||
2922 | /* == ad_gpo_process_cse_send/recv implementation ========================== */ | |||
2923 | ||||
2924 | struct ad_gpo_process_cse_state { | |||
2925 | struct tevent_context *ev; | |||
2926 | pid_t child_pid; | |||
2927 | uint8_t *buf; | |||
2928 | ssize_t len; | |||
2929 | struct io *io; | |||
2930 | }; | |||
2931 | ||||
2932 | struct io { | |||
2933 | int read_from_child_fd; | |||
2934 | int write_to_child_fd; | |||
2935 | }; | |||
2936 | ||||
2937 | static errno_t | |||
2938 | gpo_child_io_destructor(void *ptr) | |||
2939 | { | |||
2940 | int ret; | |||
2941 | struct io *io; | |||
2942 | ||||
2943 | io = talloc_get_type(ptr, struct io)(struct io *)talloc_check_name(ptr, "struct io"); | |||
2944 | if (io == NULL((void*)0)) return EOK0; | |||
2945 | ||||
2946 | if (io->write_to_child_fd != -1) { | |||
2947 | ret = close(io->write_to_child_fd); | |||
2948 | io->write_to_child_fd = -1; | |||
2949 | if (ret != EOK0) { | |||
2950 | ret = errno(*__errno_location ()); | |||
2951 | DEBUG(SSSDBG_CRIT_FAILURE,do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2952, __FUNCTION__, __debug_macro_level, "close failed [%d][%s].\n" , ret, strerror(ret)); } } while (0) | |||
2952 | "close failed [%d][%s].\n", ret, strerror(ret))do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2952, __FUNCTION__, __debug_macro_level, "close failed [%d][%s].\n" , ret, strerror(ret)); } } while (0); | |||
2953 | } | |||
2954 | } | |||
2955 | ||||
2956 | if (io->read_from_child_fd != -1) { | |||
2957 | ret = close(io->read_from_child_fd); | |||
2958 | io->read_from_child_fd = -1; | |||
2959 | if (ret != EOK0) { | |||
2960 | ret = errno(*__errno_location ()); | |||
2961 | DEBUG(SSSDBG_CRIT_FAILURE,do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2962, __FUNCTION__, __debug_macro_level, "close failed [%d][%s].\n" , ret, strerror(ret)); } } while (0) | |||
2962 | "close failed [%d][%s].\n", ret, strerror(ret))do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2962, __FUNCTION__, __debug_macro_level, "close failed [%d][%s].\n" , ret, strerror(ret)); } } while (0); | |||
2963 | } | |||
2964 | } | |||
2965 | ||||
2966 | return EOK0; | |||
2967 | } | |||
2968 | ||||
2969 | static errno_t gpo_fork_child(struct tevent_req *req); | |||
2970 | static void gpo_cse_step(struct tevent_req *subreq); | |||
2971 | static void gpo_cse_done(struct tevent_req *subreq); | |||
2972 | ||||
2973 | /* | |||
2974 | * This cse-specific function (GP_EXT_GUID_SECURITY) retrieves the data | |||
2975 | * referenced by the input smb_uri, and uses the parsed results to populate the | |||
2976 | * state's list of allowed_sids and denied_sids. | |||
2977 | */ | |||
2978 | struct tevent_req * | |||
2979 | ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx, | |||
2980 | struct tevent_context *ev, | |||
2981 | char *smb_uri) | |||
2982 | { | |||
2983 | struct tevent_req *req; | |||
2984 | struct tevent_req *subreq; | |||
2985 | struct ad_gpo_process_cse_state *state; | |||
2986 | struct io_buffer *buf = NULL((void*)0); | |||
2987 | errno_t ret; | |||
2988 | ||||
2989 | req = tevent_req_create(mem_ctx, &state, struct ad_gpo_process_cse_state)_tevent_req_create((mem_ctx), (&state), sizeof(struct ad_gpo_process_cse_state ), "struct ad_gpo_process_cse_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "2989"); | |||
2990 | if (req == NULL((void*)0)) { | |||
2991 | DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n")do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 2991, __FUNCTION__, __debug_macro_level, "tevent_req_create() failed\n" ); } } while (0); | |||
2992 | return NULL((void*)0); | |||
2993 | } | |||
2994 | ||||
2995 | state->ev = ev; | |||
2996 | state->buf = NULL((void*)0); | |||
2997 | state->len = 0; | |||
2998 | ||||
2999 | state->io = talloc(state, struct io)(struct io *)talloc_named_const(state, sizeof(struct io), "struct io" ); | |||
3000 | if (state->io == NULL((void*)0)) { | |||
3001 | DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n")do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3001, __FUNCTION__, __debug_macro_level, "talloc failed.\n" ); } } while (0); | |||
3002 | ret = ENOMEM12; | |||
3003 | goto fail; | |||
3004 | } | |||
3005 | ||||
3006 | state->io->write_to_child_fd = -1; | |||
3007 | state->io->read_from_child_fd = -1; | |||
3008 | talloc_set_destructor((void *) state->io, gpo_child_io_destructor)do { int (*_talloc_destructor_fn)(__typeof__((void *) state-> io)) = (gpo_child_io_destructor); _talloc_set_destructor(((void *) state->io), (int (*)(void *))_talloc_destructor_fn); } while(0); | |||
3009 | ||||
3010 | /* prepare the data to pass to child */ | |||
3011 | ret = create_cse_send_buffer(state, smb_uri, &buf); | |||
3012 | if (ret != EOK0) { | |||
3013 | DEBUG(SSSDBG_CRIT_FAILURE, "create_cse_send_buffer failed.\n")do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3013, __FUNCTION__, __debug_macro_level, "create_cse_send_buffer failed.\n" ); } } while (0); | |||
3014 | goto fail; | |||
3015 | } | |||
3016 | ||||
3017 | ret = gpo_fork_child(req); | |||
3018 | if (ret != EOK0) { | |||
3019 | DEBUG(SSSDBG_CRIT_FAILURE, "gpo_fork_child failed.\n")do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3019, __FUNCTION__, __debug_macro_level, "gpo_fork_child failed.\n" ); } } while (0); | |||
3020 | goto fail; | |||
3021 | } | |||
3022 | ||||
3023 | subreq = write_pipe_send(state, ev, buf->data, buf->size, | |||
3024 | state->io->write_to_child_fd); | |||
3025 | if (subreq == NULL((void*)0)) { | |||
3026 | ret = ENOMEM12; | |||
3027 | goto fail; | |||
3028 | } | |||
3029 | tevent_req_set_callback(subreq, gpo_cse_step, req); | |||
3030 | ||||
3031 | return req; | |||
3032 | ||||
3033 | fail: | |||
3034 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "3034"); | |||
3035 | tevent_req_post(req, ev); | |||
3036 | return req; | |||
3037 | } | |||
3038 | ||||
3039 | static void gpo_cse_step(struct tevent_req *subreq) | |||
3040 | { | |||
3041 | struct tevent_req *req; | |||
3042 | struct ad_gpo_process_cse_state *state; | |||
3043 | int ret; | |||
3044 | ||||
3045 | req = tevent_req_callback_data(subreq, struct tevent_req)(struct tevent_req *)_talloc_get_type_abort(_tevent_req_callback_data (subreq), "struct tevent_req", "../sssd/src/providers/ad/ad_gpo.c" ":" "3045"); | |||
3046 | state = tevent_req_data(req, struct ad_gpo_process_cse_state)(struct ad_gpo_process_cse_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_process_cse_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "3046"); | |||
3047 | ||||
3048 | ret = write_pipe_recv(subreq); | |||
3049 | talloc_zfree(subreq)do { _talloc_free(((void *)((uintptr_t)(subreq))), "../sssd/src/providers/ad/ad_gpo.c" ":" "3049"); subreq = ((void*)0); } while(0); | |||
3050 | if (ret != EOK0) { | |||
3051 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "3051"); | |||
3052 | return; | |||
3053 | } | |||
3054 | ||||
3055 | close(state->io->write_to_child_fd); | |||
3056 | state->io->write_to_child_fd = -1; | |||
3057 | ||||
3058 | subreq = read_pipe_send(state, state->ev, state->io->read_from_child_fd); | |||
3059 | ||||
3060 | if (subreq == NULL((void*)0)) { | |||
3061 | tevent_req_error(req, ENOMEM)_tevent_req_error(req, 12, "../sssd/src/providers/ad/ad_gpo.c" ":" "3061"); | |||
3062 | return; | |||
3063 | } | |||
3064 | tevent_req_set_callback(subreq, gpo_cse_done, req); | |||
3065 | } | |||
3066 | ||||
3067 | static void gpo_cse_done(struct tevent_req *subreq) | |||
3068 | { | |||
3069 | struct tevent_req *req; | |||
3070 | struct ad_gpo_process_cse_state *state; | |||
3071 | ||||
3072 | req = tevent_req_callback_data(subreq, struct tevent_req)(struct tevent_req *)_talloc_get_type_abort(_tevent_req_callback_data (subreq), "struct tevent_req", "../sssd/src/providers/ad/ad_gpo.c" ":" "3072"); | |||
3073 | state = tevent_req_data(req, struct ad_gpo_process_cse_state)(struct ad_gpo_process_cse_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_process_cse_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "3073"); | |||
3074 | int ret; | |||
3075 | ||||
3076 | ret = read_pipe_recv(subreq, state, &state->buf, &state->len); | |||
3077 | talloc_zfree(subreq)do { _talloc_free(((void *)((uintptr_t)(subreq))), "../sssd/src/providers/ad/ad_gpo.c" ":" "3077"); subreq = ((void*)0); } while(0); | |||
3078 | if (ret != EOK0) { | |||
3079 | tevent_req_error(req, ret)_tevent_req_error(req, ret, "../sssd/src/providers/ad/ad_gpo.c" ":" "3079"); | |||
3080 | return; | |||
3081 | } | |||
3082 | ||||
3083 | close(state->io->read_from_child_fd); | |||
3084 | state->io->read_from_child_fd = -1; | |||
3085 | ||||
3086 | tevent_req_done(req)_tevent_req_done(req, "../sssd/src/providers/ad/ad_gpo.c" ":" "3086"); | |||
3087 | return; | |||
3088 | } | |||
3089 | ||||
3090 | int ad_gpo_process_cse_recv(struct tevent_req *req, | |||
3091 | TALLOC_CTX *mem_ctx, | |||
3092 | int *_allowed_size, | |||
3093 | char ***_allowed_sids, | |||
3094 | int *_denied_size, | |||
3095 | char ***_denied_sids) | |||
3096 | { | |||
3097 | int ret; | |||
3098 | char **allowed_sids; | |||
3099 | int allowed_size; | |||
3100 | char **denied_sids; | |||
3101 | int denied_size; | |||
3102 | struct ad_gpo_process_cse_state *state; | |||
3103 | ||||
3104 | state = tevent_req_data(req, struct ad_gpo_process_cse_state)(struct ad_gpo_process_cse_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_process_cse_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "3104"); | |||
3105 | ||||
3106 | TEVENT_REQ_RETURN_ON_ERROR(req)do { enum tevent_req_state TRROEstate; uint64_t TRROEerr; if ( tevent_req_is_error(req, &TRROEstate, &TRROEerr)) { if (TRROEstate == TEVENT_REQ_USER_ERROR) { return TRROEerr; } return ERR_INTERNAL; } } while (0); | |||
3107 | ||||
3108 | ret = parse_gpo_child_response(mem_ctx, state->buf, state->len, | |||
3109 | &allowed_sids, | |||
3110 | &allowed_size, | |||
3111 | &denied_sids, | |||
3112 | &denied_size); | |||
3113 | ||||
3114 | if (ret != EOK0) { | |||
3115 | DEBUG(SSSDBG_CRIT_FAILURE,do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3116, __FUNCTION__, __debug_macro_level, "Cannot parse child response: [%d][%s]\n" , ret, strerror(ret)); } } while (0) | |||
3116 | "Cannot parse child response: [%d][%s]\n", ret, strerror(ret))do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3116, __FUNCTION__, __debug_macro_level, "Cannot parse child response: [%d][%s]\n" , ret, strerror(ret)); } } while (0); | |||
3117 | return ret; | |||
3118 | } | |||
3119 | ||||
3120 | *_allowed_size = allowed_size; | |||
3121 | *_allowed_sids = talloc_steal(mem_ctx, allowed_sids)({ __typeof__(allowed_sids) __talloc_steal_ret = (__typeof__( allowed_sids))_talloc_steal_loc((mem_ctx),(allowed_sids), "../sssd/src/providers/ad/ad_gpo.c" ":" "3121"); __talloc_steal_ret; }); | |||
3122 | *_denied_size = denied_size; | |||
3123 | *_denied_sids = talloc_steal(mem_ctx, denied_sids)({ __typeof__(denied_sids) __talloc_steal_ret = (__typeof__(denied_sids ))_talloc_steal_loc((mem_ctx),(denied_sids), "../sssd/src/providers/ad/ad_gpo.c" ":" "3123"); __talloc_steal_ret; }); | |||
3124 | ||||
3125 | return EOK0; | |||
3126 | } | |||
3127 | ||||
3128 | static errno_t | |||
3129 | gpo_fork_child(struct tevent_req *req) | |||
3130 | { | |||
3131 | int pipefd_to_child[2]; | |||
3132 | int pipefd_from_child[2]; | |||
3133 | pid_t pid; | |||
3134 | int ret; | |||
3135 | errno_t err; | |||
3136 | struct ad_gpo_process_cse_state *state; | |||
3137 | ||||
3138 | state = tevent_req_data(req, struct ad_gpo_process_cse_state)(struct ad_gpo_process_cse_state *)_talloc_get_type_abort(_tevent_req_data (req), "struct ad_gpo_process_cse_state", "../sssd/src/providers/ad/ad_gpo.c" ":" "3138"); | |||
3139 | ||||
3140 | ret = pipe(pipefd_from_child); | |||
3141 | if (ret == -1) { | |||
3142 | err = errno(*__errno_location ()); | |||
3143 | DEBUG(SSSDBG_CRIT_FAILURE,do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3144, __FUNCTION__, __debug_macro_level, "pipe failed [%d][%s].\n" , (*__errno_location ()), strerror((*__errno_location ()))); } } while (0) | |||
3144 | "pipe failed [%d][%s].\n", errno, strerror(errno))do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3144, __FUNCTION__, __debug_macro_level, "pipe failed [%d][%s].\n" , (*__errno_location ()), strerror((*__errno_location ()))); } } while (0); | |||
3145 | return err; | |||
3146 | } | |||
3147 | ret = pipe(pipefd_to_child); | |||
3148 | if (ret == -1) { | |||
3149 | err = errno(*__errno_location ()); | |||
3150 | DEBUG(SSSDBG_CRIT_FAILURE,do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3151, __FUNCTION__, __debug_macro_level, "pipe failed [%d][%s].\n" , (*__errno_location ()), strerror((*__errno_location ()))); } } while (0) | |||
3151 | "pipe failed [%d][%s].\n", errno, strerror(errno))do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3151, __FUNCTION__, __debug_macro_level, "pipe failed [%d][%s].\n" , (*__errno_location ()), strerror((*__errno_location ()))); } } while (0); | |||
3152 | return err; | |||
3153 | } | |||
3154 | ||||
3155 | pid = fork(); | |||
3156 | ||||
3157 | if (pid == 0) { /* child */ | |||
3158 | err = exec_child(state, | |||
3159 | pipefd_to_child, pipefd_from_child, | |||
3160 | GPO_CHILD"/usr/local/libexec/sssd""/gpo_child", gpo_child_debug_fd); | |||
3161 | DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec gpo_child: [%d][%s].\n",do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3162, __FUNCTION__, __debug_macro_level, "Could not exec gpo_child: [%d][%s].\n" , err, strerror(err)); } } while (0) | |||
3162 | err, strerror(err))do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3162, __FUNCTION__, __debug_macro_level, "Could not exec gpo_child: [%d][%s].\n" , err, strerror(err)); } } while (0); | |||
3163 | return err; | |||
3164 | } else if (pid > 0) { /* parent */ | |||
3165 | state->child_pid = pid; | |||
3166 | state->io->read_from_child_fd = pipefd_from_child[0]; | |||
3167 | close(pipefd_from_child[1]); | |||
3168 | state->io->write_to_child_fd = pipefd_to_child[1]; | |||
3169 | close(pipefd_to_child[0]); | |||
3170 | fd_nonblocking(state->io->read_from_child_fd); | |||
3171 | fd_nonblocking(state->io->write_to_child_fd); | |||
3172 | ||||
3173 | ret = child_handler_setup(state->ev, pid, NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
3174 | if (ret != EOK0) { | |||
3175 | DEBUG(SSSDBG_CRIT_FAILURE,do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3176, __FUNCTION__, __debug_macro_level, "Could not set up child signal handler\n" ); } } while (0) | |||
3176 | "Could not set up child signal handler\n")do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3176, __FUNCTION__, __debug_macro_level, "Could not set up child signal handler\n" ); } } while (0); | |||
3177 | return ret; | |||
3178 | } | |||
3179 | } else { /* error */ | |||
3180 | err = errno(*__errno_location ()); | |||
3181 | DEBUG(SSSDBG_CRIT_FAILURE,do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3182, __FUNCTION__, __debug_macro_level, "fork failed [%d][%s].\n" , (*__errno_location ()), strerror((*__errno_location ()))); } } while (0) | |||
3182 | "fork failed [%d][%s].\n", errno, strerror(errno))do { int __debug_macro_level = 0x0020; if ((debug_level & (__debug_macro_level) || (debug_level == 0 && (__debug_macro_level & (0x0010 | 0x0020))))) { debug_fn("../sssd/src/providers/ad/ad_gpo.c" , 3182, __FUNCTION__, __debug_macro_level, "fork failed [%d][%s].\n" , (*__errno_location ()), strerror((*__errno_location ()))); } } while (0); | |||
3183 | return err; | |||
3184 | } | |||
3185 | ||||
3186 | return EOK0; | |||
3187 | } |