summaryrefslogtreecommitdiff
path: root/libgpo
diff options
context:
space:
mode:
Diffstat (limited to 'libgpo')
-rw-r--r--libgpo/gpo_ldap.c140
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);
}