diff options
Diffstat (limited to 'libgpo')
-rw-r--r-- | libgpo/gpo_ldap.c | 140 |
1 files changed, 77 insertions, 63 deletions
diff --git a/libgpo/gpo_ldap.c b/libgpo/gpo_ldap.c index 7ede12c3c21..8fb5fdc40c1 100644 --- a/libgpo/gpo_ldap.c +++ b/libgpo/gpo_ldap.c @@ -561,10 +561,16 @@ static ADS_STATUS add_gplink_to_gpo_list(ADS_STRUCT *ads, const struct security_token *token) { ADS_STATUS status; - int i; - - for (i = 0; i < gp_link->num_links; i++) { - + uint32_t count; + + /* + * Note: DLIST_ADD pushes to the front, + * so loop from last to first to get the + * order right. + */ + for (count = gp_link->num_links; count > 0; count--) { + /* NB. Index into arrays is one less than counter. */ + uint32_t i = count - 1; struct GROUP_POLICY_OBJECT *new_gpo = NULL; if (gp_link->link_opts[i] & GPO_LINK_OPT_DISABLED) { @@ -726,7 +732,15 @@ ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads, const struct security_token *token, struct GROUP_POLICY_OBJECT **gpo_list) { - /* (L)ocal (S)ite (D)omain (O)rganizational(U)nit */ + /* + * Push GPOs to gpo_list so that the traversal order of the list matches + * the order of application: + * (L)ocal (S)ite (D)omain (O)rganizational(U)nit + * Within domains and OUs: parent-to-child. + * Since GPOs are pushed to the front of gpo_list, GPOs have to be + * pushed in the opposite order of application (OUs first, local last, + * child-to-parent). + */ ADS_STATUS status; struct GP_LINK gp_link; @@ -745,63 +759,18 @@ ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads, DEBUG(10,("ads_get_gpo_list: getting GPO list for [%s]\n", dn)); - /* (L)ocal */ - status = add_local_policy_to_gpo_list(mem_ctx, gpo_list, - GP_LINK_LOCAL); - if (!ADS_ERR_OK(status)) { - return status; - } - - /* (S)ite */ - - /* are site GPOs valid for users as well ??? */ - if (flags & GPO_LIST_FLAG_MACHINE) { - - status = ads_site_dn_for_machine(ads, mem_ctx, - ads->config.ldap_server_name, - &site_dn); - if (!ADS_ERR_OK(status)) { - return status; - } - - DEBUG(10,("ads_get_gpo_list: query SITE: [%s] for GPOs\n", - site_dn)); - - status = ads_get_gpo_link(ads, mem_ctx, site_dn, &gp_link); - if (ADS_ERR_OK(status)) { - - if (DEBUGLEVEL >= 100) { - dump_gplink(&gp_link); - } - - status = add_gplink_to_gpo_list(ads, mem_ctx, gpo_list, - site_dn, &gp_link, - GP_LINK_SITE, - add_only_forced_gpos, - token); - if (!ADS_ERR_OK(status)) { - return status; - } - - if (flags & GPO_LIST_FLAG_SITEONLY) { - return ADS_ERROR(LDAP_SUCCESS); - } - - /* inheritance can't be blocked at the site level */ - } - } - tmp_dn = dn; while ((parent_dn = ads_parent_dn(tmp_dn)) && (!strequal(parent_dn, ads_parent_dn(ads->config.bind_path)))) { - /* (D)omain */ - /* An account can just be a member of one domain */ - if (strncmp(parent_dn, "DC=", strlen("DC=")) == 0) { + /* (O)rganizational(U)nit */ - DEBUG(10,("ads_get_gpo_list: query DC: [%s] for GPOs\n", + /* An account can be a member of more OUs */ + if (strncmp(parent_dn, "OU=", strlen("OU=")) == 0) { + + DEBUG(10,("ads_get_gpo_list: query OU: [%s] for GPOs\n", parent_dn)); status = ads_get_gpo_link(ads, mem_ctx, parent_dn, @@ -817,7 +786,7 @@ ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads, gpo_list, parent_dn, &gp_link, - GP_LINK_DOMAIN, + GP_LINK_OU, add_only_forced_gpos, token); if (!ADS_ERR_OK(status)) { @@ -833,6 +802,7 @@ ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads, } tmp_dn = parent_dn; + } /* reset dn again */ @@ -841,13 +811,12 @@ ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads, while ((parent_dn = ads_parent_dn(tmp_dn)) && (!strequal(parent_dn, ads_parent_dn(ads->config.bind_path)))) { + /* (D)omain */ - /* (O)rganizational(U)nit */ - - /* An account can be a member of more OUs */ - if (strncmp(parent_dn, "OU=", strlen("OU=")) == 0) { + /* An account can just be a member of one domain */ + if (strncmp(parent_dn, "DC=", strlen("DC=")) == 0) { - DEBUG(10,("ads_get_gpo_list: query OU: [%s] for GPOs\n", + DEBUG(10,("ads_get_gpo_list: query DC: [%s] for GPOs\n", parent_dn)); status = ads_get_gpo_link(ads, mem_ctx, parent_dn, @@ -863,7 +832,7 @@ ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads, gpo_list, parent_dn, &gp_link, - GP_LINK_OU, + GP_LINK_DOMAIN, add_only_forced_gpos, token); if (!ADS_ERR_OK(status)) { @@ -879,8 +848,53 @@ ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads, } tmp_dn = parent_dn; + } + + /* (S)ite */ + + /* are site GPOs valid for users as well ??? */ + if (flags & GPO_LIST_FLAG_MACHINE) { - }; + status = ads_site_dn_for_machine(ads, mem_ctx, + ads->config.ldap_server_name, + &site_dn); + if (!ADS_ERR_OK(status)) { + return status; + } + + DEBUG(10,("ads_get_gpo_list: query SITE: [%s] for GPOs\n", + site_dn)); + + status = ads_get_gpo_link(ads, mem_ctx, site_dn, &gp_link); + if (ADS_ERR_OK(status)) { + + if (DEBUGLEVEL >= 100) { + dump_gplink(&gp_link); + } + + status = add_gplink_to_gpo_list(ads, mem_ctx, gpo_list, + site_dn, &gp_link, + GP_LINK_SITE, + add_only_forced_gpos, + token); + if (!ADS_ERR_OK(status)) { + return status; + } + + if (flags & GPO_LIST_FLAG_SITEONLY) { + return ADS_ERROR(LDAP_SUCCESS); + } + + /* inheritance can't be blocked at the site level */ + } + } + + /* (L)ocal */ + status = add_local_policy_to_gpo_list(mem_ctx, gpo_list, + GP_LINK_LOCAL); + if (!ADS_ERR_OK(status)) { + return status; + } return ADS_ERROR(LDAP_SUCCESS); } |