00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023 #ifdef HAVE_LDAP
00024
00025
00026
00027
00028
00029 ADS_STATUS ads_parse_gp_ext(TALLOC_CTX *mem_ctx,
00030 const char *extension_raw,
00031 struct GP_EXT *gp_ext)
00032 {
00033 char **ext_list;
00034 char **ext_strings = NULL;
00035 int i;
00036
00037 DEBUG(20,("ads_parse_gp_ext: %s\n", extension_raw));
00038
00039 ext_list = str_list_make_talloc(mem_ctx, extension_raw, "]");
00040 if (ext_list == NULL) {
00041 goto parse_error;
00042 }
00043
00044 for (i = 0; ext_list[i] != NULL; i++) {
00045
00046 }
00047
00048 gp_ext->num_exts = i;
00049
00050 if (gp_ext->num_exts) {
00051 gp_ext->extensions = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_ext->num_exts);
00052 gp_ext->extensions_guid = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_ext->num_exts);
00053 gp_ext->snapins = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_ext->num_exts);
00054 gp_ext->snapins_guid = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_ext->num_exts);
00055 } else {
00056 gp_ext->extensions = NULL;
00057 gp_ext->extensions_guid = NULL;
00058 gp_ext->snapins = NULL;
00059 gp_ext->snapins_guid = NULL;
00060 }
00061
00062 if (gp_ext->extensions == NULL || gp_ext->extensions_guid == NULL ||
00063 gp_ext->snapins == NULL || gp_ext->snapins_guid == NULL ||
00064 gp_ext->gp_extension == NULL) {
00065 goto parse_error;
00066 }
00067
00068 gp_ext->gp_extension = talloc_strdup(mem_ctx, extension_raw);
00069
00070 for (i = 0; ext_list[i] != NULL; i++) {
00071
00072 int k;
00073 char *p, *q;
00074
00075 DEBUGADD(10,("extension #%d\n", i));
00076
00077 p = ext_list[i];
00078
00079 if (p[0] == '[') {
00080 p++;
00081 }
00082
00083 ext_strings = str_list_make_talloc(mem_ctx, p, "}");
00084 if (ext_strings == NULL) {
00085 goto parse_error;
00086 }
00087
00088 for (k = 0; ext_strings[k] != NULL; k++) {
00089
00090 }
00091
00092 q = ext_strings[0];
00093
00094 if (q[0] == '{') {
00095 q++;
00096 }
00097
00098 gp_ext->extensions[i] = talloc_strdup(mem_ctx, cse_gpo_guid_string_to_name(q));
00099 gp_ext->extensions_guid[i] = talloc_strdup(mem_ctx, q);
00100
00101
00102 if (gp_ext->extensions_guid[i] == NULL) {
00103 goto parse_error;
00104 }
00105
00106 for (k = 1; ext_strings[k] != NULL; k++) {
00107
00108 char *m = ext_strings[k];
00109
00110 if (m[0] == '{') {
00111 m++;
00112 }
00113
00114
00115 gp_ext->snapins[i] = talloc_strdup(mem_ctx, cse_snapin_gpo_guid_string_to_name(m));
00116 gp_ext->snapins_guid[i] = talloc_strdup(mem_ctx, m);
00117
00118
00119 if (gp_ext->snapins_guid[i] == NULL) {
00120 goto parse_error;
00121 }
00122 }
00123 }
00124
00125 if (ext_list) {
00126 str_list_free_talloc(mem_ctx, &ext_list);
00127 }
00128 if (ext_strings) {
00129 str_list_free_talloc(mem_ctx, &ext_strings);
00130 }
00131
00132 return ADS_ERROR(LDAP_SUCCESS);
00133
00134 parse_error:
00135 if (ext_list) {
00136 str_list_free_talloc(mem_ctx, &ext_list);
00137 }
00138 if (ext_strings) {
00139 str_list_free_talloc(mem_ctx, &ext_strings);
00140 }
00141
00142 return ADS_ERROR(LDAP_NO_MEMORY);
00143 }
00144
00145
00146
00147
00148
00149 ADS_STATUS ads_parse_gplink(TALLOC_CTX *mem_ctx,
00150 const char *gp_link_raw,
00151 uint32 options,
00152 struct GP_LINK *gp_link)
00153 {
00154 char **link_list;
00155 int i;
00156
00157 DEBUG(10,("ads_parse_gplink: gPLink: %s\n", gp_link_raw));
00158
00159 link_list = str_list_make_talloc(mem_ctx, gp_link_raw, "]");
00160 if (link_list == NULL) {
00161 goto parse_error;
00162 }
00163
00164 for (i = 0; link_list[i] != NULL; i++) {
00165
00166 }
00167
00168 gp_link->gp_opts = options;
00169 gp_link->num_links = i;
00170
00171 if (gp_link->num_links) {
00172 gp_link->link_names = TALLOC_ZERO_ARRAY(mem_ctx, char *, gp_link->num_links);
00173 gp_link->link_opts = TALLOC_ZERO_ARRAY(mem_ctx, uint32, gp_link->num_links);
00174 } else {
00175 gp_link->link_names = NULL;
00176 gp_link->link_opts = NULL;
00177 }
00178
00179 gp_link->gp_link = talloc_strdup(mem_ctx, gp_link_raw);
00180
00181 if (gp_link->link_names == NULL || gp_link->link_opts == NULL || gp_link->gp_link == NULL) {
00182 goto parse_error;
00183 }
00184
00185 for (i = 0; link_list[i] != NULL; i++) {
00186
00187 char *p, *q;
00188
00189 DEBUGADD(10,("ads_parse_gplink: processing link #%d\n", i));
00190
00191 q = link_list[i];
00192 if (q[0] == '[') {
00193 q++;
00194 };
00195
00196 p = strchr(q, ';');
00197
00198 if (p == NULL) {
00199 goto parse_error;
00200 }
00201
00202 gp_link->link_names[i] = talloc_strdup(mem_ctx, q);
00203 if (gp_link->link_names[i] == NULL) {
00204 goto parse_error;
00205 }
00206 gp_link->link_names[i][PTR_DIFF(p, q)] = 0;
00207
00208 gp_link->link_opts[i] = atoi(p + 1);
00209
00210 DEBUGADD(10,("ads_parse_gplink: link: %s\n", gp_link->link_names[i]));
00211 DEBUGADD(10,("ads_parse_gplink: opt: %d\n", gp_link->link_opts[i]));
00212
00213 }
00214
00215 if (link_list) {
00216 str_list_free_talloc(mem_ctx, &link_list);
00217 }
00218
00219 return ADS_ERROR(LDAP_SUCCESS);
00220
00221 parse_error:
00222 if (link_list) {
00223 str_list_free_talloc(mem_ctx, &link_list);
00224 }
00225
00226 return ADS_ERROR(LDAP_NO_MEMORY);
00227 }
00228
00229
00230
00231
00232
00233 ADS_STATUS ads_get_gpo_link(ADS_STRUCT *ads,
00234 TALLOC_CTX *mem_ctx,
00235 const char *link_dn,
00236 struct GP_LINK *gp_link_struct)
00237 {
00238 ADS_STATUS status;
00239 const char *attrs[] = {"gPLink", "gPOptions", NULL};
00240 LDAPMessage *res = NULL;
00241 const char *gp_link;
00242 uint32 gp_options;
00243
00244 ZERO_STRUCTP(gp_link_struct);
00245
00246 status = ads_search_dn(ads, &res, link_dn, attrs);
00247 if (!ADS_ERR_OK(status)) {
00248 DEBUG(10,("ads_get_gpo_link: search failed with %s\n", ads_errstr(status)));
00249 return status;
00250 }
00251
00252 if (ads_count_replies(ads, res) != 1) {
00253 DEBUG(10,("ads_get_gpo_link: no result\n"));
00254 ads_msgfree(ads, res);
00255 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
00256 }
00257
00258 gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink");
00259 if (gp_link == NULL) {
00260 DEBUG(10,("ads_get_gpo_link: no 'gPLink' attribute found\n"));
00261 ads_msgfree(ads, res);
00262 return ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE);
00263 }
00264
00265
00266 if (!ads_pull_uint32(ads, res, "gPOptions", &gp_options)) {
00267 DEBUG(10,("ads_get_gpo_link: no 'gPOptions' attribute found\n"));
00268 gp_options = 0;
00269 }
00270
00271 ads_msgfree(ads, res);
00272
00273 return ads_parse_gplink(mem_ctx, gp_link, gp_options, gp_link_struct);
00274 }
00275
00276
00277
00278
00279
00280 ADS_STATUS ads_add_gpo_link(ADS_STRUCT *ads,
00281 TALLOC_CTX *mem_ctx,
00282 const char *link_dn,
00283 const char *gpo_dn,
00284 uint32 gpo_opt)
00285 {
00286 ADS_STATUS status;
00287 const char *attrs[] = {"gPLink", NULL};
00288 LDAPMessage *res = NULL;
00289 const char *gp_link, *gp_link_new;
00290 ADS_MODLIST mods;
00291
00292
00293
00294
00295 if (!strnequal(gpo_dn, "LDAP://CN={", strlen("LDAP://CN={")) != 0) {
00296 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
00297 }
00298
00299 status = ads_search_dn(ads, &res, link_dn, attrs);
00300 if (!ADS_ERR_OK(status)) {
00301 DEBUG(10,("ads_add_gpo_link: search failed with %s\n", ads_errstr(status)));
00302 return status;
00303 }
00304
00305 if (ads_count_replies(ads, res) != 1) {
00306 DEBUG(10,("ads_add_gpo_link: no result\n"));
00307 ads_msgfree(ads, res);
00308 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
00309 }
00310
00311 gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink");
00312 if (gp_link == NULL) {
00313 gp_link_new = talloc_asprintf(mem_ctx, "[%s;%d]", gpo_dn, gpo_opt);
00314 } else {
00315 gp_link_new = talloc_asprintf(mem_ctx, "%s[%s;%d]", gp_link, gpo_dn, gpo_opt);
00316 }
00317
00318 ads_msgfree(ads, res);
00319 ADS_ERROR_HAVE_NO_MEMORY(gp_link_new);
00320
00321 mods = ads_init_mods(mem_ctx);
00322 ADS_ERROR_HAVE_NO_MEMORY(mods);
00323
00324 status = ads_mod_str(mem_ctx, &mods, "gPLink", gp_link_new);
00325 if (!ADS_ERR_OK(status)) {
00326 return status;
00327 }
00328
00329 return ads_gen_mod(ads, link_dn, mods);
00330 }
00331
00332
00333
00334
00335
00336
00337 ADS_STATUS ads_delete_gpo_link(ADS_STRUCT *ads,
00338 TALLOC_CTX *mem_ctx,
00339 const char *link_dn,
00340 const char *gpo_dn)
00341 {
00342 ADS_STATUS status;
00343 const char *attrs[] = {"gPLink", NULL};
00344 LDAPMessage *res = NULL;
00345 const char *gp_link, *gp_link_new = NULL;
00346 ADS_MODLIST mods;
00347
00348
00349 if (gpo_dn[0] != '[') {
00350 DEBUG(10,("ads_delete_gpo_link: first char not: [\n"));
00351 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
00352 }
00353
00354 if (gpo_dn[strlen(gpo_dn)] != ']') {
00355 DEBUG(10,("ads_delete_gpo_link: last char not: ]\n"));
00356 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
00357 }
00358
00359 status = ads_search_dn(ads, &res, link_dn, attrs);
00360 if (!ADS_ERR_OK(status)) {
00361 DEBUG(10,("ads_delete_gpo_link: search failed with %s\n", ads_errstr(status)));
00362 return status;
00363 }
00364
00365 if (ads_count_replies(ads, res) != 1) {
00366 DEBUG(10,("ads_delete_gpo_link: no result\n"));
00367 ads_msgfree(ads, res);
00368 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
00369 }
00370
00371 gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink");
00372 if (gp_link == NULL) {
00373 return ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE);
00374 }
00375
00376
00377
00378
00379 ads_msgfree(ads, res);
00380 ADS_ERROR_HAVE_NO_MEMORY(gp_link_new);
00381
00382 mods = ads_init_mods(mem_ctx);
00383 ADS_ERROR_HAVE_NO_MEMORY(mods);
00384
00385 status = ads_mod_str(mem_ctx, &mods, "gPLink", gp_link_new);
00386 if (!ADS_ERR_OK(status)) {
00387 return status;
00388 }
00389
00390 return ads_gen_mod(ads, link_dn, mods);
00391 }
00392
00393
00394
00395
00396
00397 ADS_STATUS ads_parse_gpo(ADS_STRUCT *ads,
00398 TALLOC_CTX *mem_ctx,
00399 LDAPMessage *res,
00400 const char *gpo_dn,
00401 struct GROUP_POLICY_OBJECT *gpo)
00402 {
00403 ZERO_STRUCTP(gpo);
00404
00405 ADS_ERROR_HAVE_NO_MEMORY(res);
00406
00407 if (gpo_dn) {
00408 gpo->ds_path = talloc_strdup(mem_ctx, gpo_dn);
00409 } else {
00410 gpo->ds_path = ads_get_dn(ads, res);
00411 }
00412
00413 ADS_ERROR_HAVE_NO_MEMORY(gpo->ds_path);
00414
00415 if (!ads_pull_uint32(ads, res, "versionNumber", &gpo->version)) {
00416 return ADS_ERROR(LDAP_NO_MEMORY);
00417 }
00418
00419
00420 if (!ads_pull_uint32(ads, res, "flags", &gpo->options)) {
00421 return ADS_ERROR(LDAP_NO_MEMORY);
00422 }
00423
00424 gpo->file_sys_path = ads_pull_string(ads, mem_ctx, res, "gPCFileSysPath");
00425 ADS_ERROR_HAVE_NO_MEMORY(gpo->file_sys_path);
00426
00427 gpo->display_name = ads_pull_string(ads, mem_ctx, res, "displayName");
00428 ADS_ERROR_HAVE_NO_MEMORY(gpo->display_name);
00429
00430 gpo->name = ads_pull_string(ads, mem_ctx, res, "name");
00431 ADS_ERROR_HAVE_NO_MEMORY(gpo->name);
00432
00433
00434 gpo->machine_extensions = ads_pull_string(ads, mem_ctx, res, "gPCMachineExtensionNames");
00435 gpo->user_extensions = ads_pull_string(ads, mem_ctx, res, "gPCUserExtensionNames");
00436
00437 return ADS_ERROR(LDAP_SUCCESS);
00438 }
00439
00440
00441
00442
00443
00444 ADS_STATUS ads_get_gpo(ADS_STRUCT *ads,
00445 TALLOC_CTX *mem_ctx,
00446 const char *gpo_dn,
00447 const char *display_name,
00448 const char *guid_name,
00449 struct GROUP_POLICY_OBJECT *gpo)
00450 {
00451 ADS_STATUS status;
00452 LDAPMessage *res = NULL;
00453 char *dn;
00454 const char *filter;
00455 const char *attrs[] = { "cn", "displayName", "flags", "gPCFileSysPath",
00456 "gPCFunctionalityVersion", "gPCMachineExtensionNames",
00457 "gPCUserExtensionNames", "gPCWQLFilter", "name",
00458 "versionNumber", NULL};
00459
00460 ZERO_STRUCTP(gpo);
00461
00462 if (!gpo_dn && !display_name && !guid_name) {
00463 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
00464 }
00465
00466 if (gpo_dn) {
00467
00468 if (strnequal(gpo_dn, "LDAP://", strlen("LDAP://")) != 0) {
00469 gpo_dn = gpo_dn + strlen("LDAP://");
00470 }
00471
00472 status = ads_search_dn(ads, &res, gpo_dn, attrs);
00473
00474 } else if (display_name || guid_name) {
00475
00476 filter = talloc_asprintf(mem_ctx,
00477 "(&(objectclass=groupPolicyContainer)(%s=%s))",
00478 display_name ? "displayName" : "name",
00479 display_name ? display_name : guid_name);
00480 ADS_ERROR_HAVE_NO_MEMORY(filter);
00481
00482 status = ads_do_search_all(ads, ads->config.bind_path,
00483 LDAP_SCOPE_SUBTREE, filter,
00484 attrs, &res);
00485 }
00486
00487 if (!ADS_ERR_OK(status)) {
00488 DEBUG(10,("ads_get_gpo: search failed with %s\n", ads_errstr(status)));
00489 return status;
00490 }
00491
00492 if (ads_count_replies(ads, res) != 1) {
00493 DEBUG(10,("ads_get_gpo: no result\n"));
00494 ads_msgfree(ads, res);
00495 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
00496 }
00497
00498 dn = ads_get_dn(ads, res);
00499 if (dn == NULL) {
00500 ads_msgfree(ads, res);
00501 return ADS_ERROR(LDAP_NO_MEMORY);
00502 }
00503
00504 status = ads_parse_gpo(ads, mem_ctx, res, dn, gpo);
00505 ads_msgfree(ads, res);
00506 ads_memfree(ads, dn);
00507
00508 return status;
00509 }
00510
00511
00512
00513
00514
00515 ADS_STATUS add_gplink_to_gpo_list(ADS_STRUCT *ads,
00516 TALLOC_CTX *mem_ctx,
00517 struct GROUP_POLICY_OBJECT **gpo_list,
00518 const char *link_dn,
00519 struct GP_LINK *gp_link,
00520 enum GPO_LINK_TYPE link_type,
00521 BOOL only_add_forced_gpos)
00522 {
00523 ADS_STATUS status;
00524 int i;
00525
00526 for (i = 0; i < gp_link->num_links; i++) {
00527
00528 struct GROUP_POLICY_OBJECT *new_gpo = NULL;
00529
00530 if (gp_link->link_opts[i] & GPO_LINK_OPT_DISABLED) {
00531 DEBUG(10,("skipping disabled GPO\n"));
00532 continue;
00533 }
00534
00535 if (only_add_forced_gpos) {
00536
00537 if (! (gp_link->link_opts[i] & GPO_LINK_OPT_ENFORCED)) {
00538 DEBUG(10,("skipping nonenforced GPO link because GPOPTIONS_BLOCK_INHERITANCE has been set\n"));
00539 continue;
00540 } else {
00541 DEBUG(10,("adding enforced GPO link although the GPOPTIONS_BLOCK_INHERITANCE has been set\n"));
00542 }
00543 }
00544
00545 new_gpo = TALLOC_P(mem_ctx, struct GROUP_POLICY_OBJECT);
00546 ADS_ERROR_HAVE_NO_MEMORY(new_gpo);
00547
00548 ZERO_STRUCTP(new_gpo);
00549
00550 status = ads_get_gpo(ads, mem_ctx, gp_link->link_names[i], NULL, NULL, new_gpo);
00551 if (!ADS_ERR_OK(status)) {
00552 return status;
00553 }
00554
00555 new_gpo->link = link_dn;
00556 new_gpo->link_type = link_type;
00557
00558 DLIST_ADD(*gpo_list, new_gpo);
00559
00560 DEBUG(10,("add_gplink_to_gplist: added GPLINK #%d %s to GPO list\n",
00561 i, gp_link->link_names[i]));
00562 }
00563
00564 return ADS_ERROR(LDAP_SUCCESS);
00565 }
00566
00567
00568
00569
00570
00571 ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads,
00572 TALLOC_CTX *mem_ctx,
00573 const char *dn,
00574 uint32 flags,
00575 struct GROUP_POLICY_OBJECT **gpo_list)
00576 {
00577
00578
00579 ADS_STATUS status;
00580 struct GP_LINK gp_link;
00581 const char *parent_dn, *site_dn, *tmp_dn;
00582 BOOL add_only_forced_gpos = False;
00583
00584 ZERO_STRUCTP(gpo_list);
00585
00586 DEBUG(10,("ads_get_gpo_list: getting GPO list for [%s]\n", dn));
00587
00588
00589
00590
00591
00592
00593
00594 if (flags & GPO_LIST_FLAG_MACHINE) {
00595
00596 status = ads_site_dn_for_machine(ads, mem_ctx, ads->config.ldap_server_name, &site_dn);
00597 if (!ADS_ERR_OK(status)) {
00598 return status;
00599 }
00600
00601 DEBUG(10,("ads_get_gpo_list: query SITE: [%s] for GPOs\n", site_dn));
00602
00603 status = ads_get_gpo_link(ads, mem_ctx, site_dn, &gp_link);
00604 if (ADS_ERR_OK(status)) {
00605
00606 if (DEBUGLEVEL >= 100) {
00607 dump_gplink(ads, mem_ctx, &gp_link);
00608 }
00609
00610 status = add_gplink_to_gpo_list(ads, mem_ctx, gpo_list,
00611 site_dn, &gp_link, GP_LINK_SITE,
00612 add_only_forced_gpos);
00613 if (!ADS_ERR_OK(status)) {
00614 return status;
00615 }
00616
00617 if (flags & GPO_LIST_FLAG_SITEONLY) {
00618 return ADS_ERROR(LDAP_SUCCESS);
00619 }
00620
00621
00622 }
00623 }
00624
00625 tmp_dn = dn;
00626
00627 while ( (parent_dn = ads_parent_dn(tmp_dn)) &&
00628 (!strequal(parent_dn, ads_parent_dn(ads->config.bind_path))) ) {
00629
00630
00631
00632
00633 if (strncmp(parent_dn, "DC=", strlen("DC=")) == 0) {
00634
00635 DEBUG(10,("ads_get_gpo_list: query DC: [%s] for GPOs\n", parent_dn));
00636
00637 status = ads_get_gpo_link(ads, mem_ctx, parent_dn, &gp_link);
00638 if (ADS_ERR_OK(status)) {
00639
00640 if (DEBUGLEVEL >= 100) {
00641 dump_gplink(ads, mem_ctx, &gp_link);
00642 }
00643
00644
00645 if (gp_link.gp_opts & GPOPTIONS_BLOCK_INHERITANCE) {
00646 add_only_forced_gpos = True;
00647 }
00648
00649 status = add_gplink_to_gpo_list(ads, mem_ctx,
00650 gpo_list, parent_dn,
00651 &gp_link, GP_LINK_DOMAIN,
00652 add_only_forced_gpos);
00653 if (!ADS_ERR_OK(status)) {
00654 return status;
00655 }
00656 }
00657 }
00658
00659 tmp_dn = parent_dn;
00660 }
00661
00662
00663 tmp_dn = dn;
00664
00665 while ( (parent_dn = ads_parent_dn(tmp_dn)) &&
00666 (!strequal(parent_dn, ads_parent_dn(ads->config.bind_path))) ) {
00667
00668
00669
00670
00671
00672 if (strncmp(parent_dn, "OU=", strlen("OU=")) == 0) {
00673
00674 DEBUG(10,("ads_get_gpo_list: query OU: [%s] for GPOs\n", parent_dn));
00675
00676 status = ads_get_gpo_link(ads, mem_ctx, parent_dn, &gp_link);
00677 if (ADS_ERR_OK(status)) {
00678
00679 if (DEBUGLEVEL >= 100) {
00680 dump_gplink(ads, mem_ctx, &gp_link);
00681 }
00682
00683
00684 if (gp_link.gp_opts & GPOPTIONS_BLOCK_INHERITANCE) {
00685 add_only_forced_gpos = True;
00686 }
00687
00688 status = add_gplink_to_gpo_list(ads, mem_ctx,
00689 gpo_list, parent_dn,
00690 &gp_link, GP_LINK_OU,
00691 add_only_forced_gpos);
00692 if (!ADS_ERR_OK(status)) {
00693 return status;
00694 }
00695 }
00696 }
00697
00698 tmp_dn = parent_dn;
00699
00700 };
00701
00702 return ADS_ERROR(LDAP_SUCCESS);
00703 }
00704
00705 #endif