root/source3/libgpo/gpo_ldap.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ads_parse_gp_ext
  2. gpo_parse_gplink
  3. ads_get_gpo_link
  4. ads_add_gpo_link
  5. ads_delete_gpo_link
  6. ads_parse_gpo
  7. ads_get_gpo
  8. add_gplink_to_gpo_list
  9. ads_get_sid_token
  10. add_local_policy_to_gpo_list
  11. ads_get_gpo_list

   1 /*
   2  *  Unix SMB/CIFS implementation.
   3  *  Group Policy Object Support
   4  *  Copyright (C) Guenther Deschner 2005,2007
   5  *
   6  *  This program is free software; you can redistribute it and/or modify
   7  *  it under the terms of the GNU General Public License as published by
   8  *  the Free Software Foundation; either version 3 of the License, or
   9  *  (at your option) any later version.
  10  *
  11  *  This program is distributed in the hope that it will be useful,
  12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14  *  GNU General Public License for more details.
  15  *
  16  *  You should have received a copy of the GNU General Public License
  17  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  18  */
  19 
  20 #include "includes.h"
  21 
  22 /****************************************************************
  23  parse the raw extension string into a GP_EXT structure
  24 ****************************************************************/
  25 
  26 bool ads_parse_gp_ext(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  27                       const char *extension_raw,
  28                       struct GP_EXT **gp_ext)
  29 {
  30         bool ret = false;
  31         struct GP_EXT *ext = NULL;
  32         char **ext_list = NULL;
  33         char **ext_strings = NULL;
  34         int i;
  35 
  36         if (!extension_raw) {
  37                 goto parse_error;
  38         }
  39 
  40         DEBUG(20,("ads_parse_gp_ext: %s\n", extension_raw));
  41 
  42         ext = TALLOC_ZERO_P(mem_ctx, struct GP_EXT);
  43         if (!ext) {
  44                 goto parse_error;
  45         }
  46 
  47         ext_list = str_list_make_v3(mem_ctx, extension_raw, "]");
  48         if (!ext_list) {
  49                 goto parse_error;
  50         }
  51 
  52         for (i = 0; ext_list[i] != NULL; i++) {
  53                 /* no op */
  54         }
  55 
  56         ext->num_exts = i;
  57 
  58         if (ext->num_exts) {
  59                 ext->extensions         = TALLOC_ZERO_ARRAY(mem_ctx, char *,
  60                                                             ext->num_exts);
  61                 ext->extensions_guid    = TALLOC_ZERO_ARRAY(mem_ctx, char *,
  62                                                             ext->num_exts);
  63                 ext->snapins            = TALLOC_ZERO_ARRAY(mem_ctx, char *,
  64                                                             ext->num_exts);
  65                 ext->snapins_guid       = TALLOC_ZERO_ARRAY(mem_ctx, char *,
  66                                                             ext->num_exts);
  67         }
  68 
  69         ext->gp_extension = talloc_strdup(mem_ctx, extension_raw);
  70 
  71         if (!ext->extensions || !ext->extensions_guid ||
  72             !ext->snapins || !ext->snapins_guid ||
  73             !ext->gp_extension) {
  74                 goto parse_error;
  75         }
  76 
  77         for (i = 0; ext_list[i] != NULL; i++) {
  78 
  79                 int k;
  80                 char *p, *q;
  81 
  82                 DEBUGADD(10,("extension #%d\n", i));
  83 
  84                 p = ext_list[i];
  85 
  86                 if (p[0] == '[') {
  87                         p++;
  88                 }
  89 
  90                 ext_strings = str_list_make_v3(mem_ctx, p, "}");
  91                 if (ext_strings == NULL) {
  92                         goto parse_error;
  93                 }
  94 
  95                 for (k = 0; ext_strings[k] != NULL; k++) {
  96                         /* no op */
  97                 }
  98 
  99                 q = ext_strings[0];
 100 
 101                 if (q[0] == '{') {
 102                         q++;
 103                 }
 104 
 105                 ext->extensions[i] = talloc_strdup(mem_ctx,
 106                                            cse_gpo_guid_string_to_name(q));
 107                 ext->extensions_guid[i] = talloc_strdup(mem_ctx, q);
 108 
 109                 /* we might have no name for the guid */
 110                 if (ext->extensions_guid[i] == NULL) {
 111                         goto parse_error;
 112                 }
 113 
 114                 for (k = 1; ext_strings[k] != NULL; k++) {
 115 
 116                         char *m = ext_strings[k];
 117 
 118                         if (m[0] == '{') {
 119                                 m++;
 120                         }
 121 
 122                         /* FIXME: theoretically there could be more than one
 123                          * snapin per extension */
 124                         ext->snapins[i] = talloc_strdup(mem_ctx,
 125                                 cse_snapin_gpo_guid_string_to_name(m));
 126                         ext->snapins_guid[i] = talloc_strdup(mem_ctx, m);
 127 
 128                         /* we might have no name for the guid */
 129                         if (ext->snapins_guid[i] == NULL) {
 130                                 goto parse_error;
 131                         }
 132                 }
 133         }
 134 
 135         *gp_ext = ext;
 136 
 137         ret = true;
 138 
 139  parse_error:
 140         TALLOC_FREE(ext_list);
 141         TALLOC_FREE(ext_strings);
 142 
 143         return ret;
 144 }
 145 
 146 #ifdef HAVE_LDAP
 147 
 148 /****************************************************************
 149  parse the raw link string into a GP_LINK structure
 150 ****************************************************************/
 151 
 152 static ADS_STATUS gpo_parse_gplink(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 153                                    const char *gp_link_raw,
 154                                    uint32_t options,
 155                                    struct GP_LINK *gp_link)
 156 {
 157         ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
 158         char **link_list;
 159         int i;
 160 
 161         ZERO_STRUCTP(gp_link);
 162 
 163         DEBUG(10,("gpo_parse_gplink: gPLink: %s\n", gp_link_raw));
 164 
 165         link_list = str_list_make_v3(mem_ctx, gp_link_raw, "]");
 166         if (!link_list) {
 167                 goto parse_error;
 168         }
 169 
 170         for (i = 0; link_list[i] != NULL; i++) {
 171                 /* no op */
 172         }
 173 
 174         gp_link->gp_opts = options;
 175         gp_link->num_links = i;
 176 
 177         if (gp_link->num_links) {
 178                 gp_link->link_names = TALLOC_ZERO_ARRAY(mem_ctx, char *,
 179                                                         gp_link->num_links);
 180                 gp_link->link_opts = TALLOC_ZERO_ARRAY(mem_ctx, uint32_t,
 181                                                        gp_link->num_links);
 182         }
 183 
 184         gp_link->gp_link = talloc_strdup(mem_ctx, gp_link_raw);
 185 
 186         if (!gp_link->link_names || !gp_link->link_opts || !gp_link->gp_link) {
 187                 goto parse_error;
 188         }
 189 
 190         for (i = 0; link_list[i] != NULL; i++) {
 191 
 192                 char *p, *q;
 193 
 194                 DEBUGADD(10,("gpo_parse_gplink: processing link #%d\n", i));
 195 
 196                 q = link_list[i];
 197                 if (q[0] == '[') {
 198                         q++;
 199                 };
 200 
 201                 p = strchr(q, ';');
 202 
 203                 if (p == NULL) {
 204                         goto parse_error;
 205                 }
 206 
 207                 gp_link->link_names[i] = talloc_strdup(mem_ctx, q);
 208                 if (gp_link->link_names[i] == NULL) {
 209                         goto parse_error;
 210                 }
 211                 gp_link->link_names[i][PTR_DIFF(p, q)] = 0;
 212 
 213                 gp_link->link_opts[i] = atoi(p + 1);
 214 
 215                 DEBUGADD(10,("gpo_parse_gplink: link: %s\n",
 216                         gp_link->link_names[i]));
 217                 DEBUGADD(10,("gpo_parse_gplink: opt: %d\n",
 218                         gp_link->link_opts[i]));
 219 
 220         }
 221 
 222         status = ADS_SUCCESS;
 223 
 224  parse_error:
 225         TALLOC_FREE(link_list);
 226 
 227         return status;
 228 }
 229 
 230 /****************************************************************
 231  helper call to get a GP_LINK structure from a linkdn
 232 ****************************************************************/
 233 
 234 ADS_STATUS ads_get_gpo_link(ADS_STRUCT *ads,
     /* [<][>][^][v][top][bottom][index][help] */
 235                             TALLOC_CTX *mem_ctx,
 236                             const char *link_dn,
 237                             struct GP_LINK *gp_link_struct)
 238 {
 239         ADS_STATUS status;
 240         const char *attrs[] = {"gPLink", "gPOptions", NULL};
 241         LDAPMessage *res = NULL;
 242         const char *gp_link;
 243         uint32_t gp_options;
 244 
 245         ZERO_STRUCTP(gp_link_struct);
 246 
 247         status = ads_search_dn(ads, &res, link_dn, attrs);
 248         if (!ADS_ERR_OK(status)) {
 249                 DEBUG(10,("ads_get_gpo_link: search failed with %s\n",
 250                         ads_errstr(status)));
 251                 return status;
 252         }
 253 
 254         if (ads_count_replies(ads, res) != 1) {
 255                 DEBUG(10,("ads_get_gpo_link: no result\n"));
 256                 ads_msgfree(ads, res);
 257                 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
 258         }
 259 
 260         gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink");
 261         if (gp_link == NULL) {
 262                 DEBUG(10,("ads_get_gpo_link: no 'gPLink' attribute found\n"));
 263                 ads_msgfree(ads, res);
 264                 return ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE);
 265         }
 266 
 267         /* perfectly legal to have no options */
 268         if (!ads_pull_uint32(ads, res, "gPOptions", &gp_options)) {
 269                 DEBUG(10,("ads_get_gpo_link: "
 270                         "no 'gPOptions' attribute found\n"));
 271                 gp_options = 0;
 272         }
 273 
 274         ads_msgfree(ads, res);
 275 
 276         return gpo_parse_gplink(mem_ctx, gp_link, gp_options, gp_link_struct);
 277 }
 278 
 279 /****************************************************************
 280  helper call to add a gp link
 281 ****************************************************************/
 282 
 283 ADS_STATUS ads_add_gpo_link(ADS_STRUCT *ads,
     /* [<][>][^][v][top][bottom][index][help] */
 284                             TALLOC_CTX *mem_ctx,
 285                             const char *link_dn,
 286                             const char *gpo_dn,
 287                             uint32_t gpo_opt)
 288 {
 289         ADS_STATUS status;
 290         const char *attrs[] = {"gPLink", NULL};
 291         LDAPMessage *res = NULL;
 292         const char *gp_link, *gp_link_new;
 293         ADS_MODLIST mods;
 294 
 295         /* although ADS allows to set anything here, we better check here if
 296          * the gpo_dn is sane */
 297 
 298         if (!strnequal(gpo_dn, "LDAP://CN={", strlen("LDAP://CN={")) != 0) {
 299                 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
 300         }
 301 
 302         status = ads_search_dn(ads, &res, link_dn, attrs);
 303         if (!ADS_ERR_OK(status)) {
 304                 DEBUG(10,("ads_add_gpo_link: search failed with %s\n",
 305                         ads_errstr(status)));
 306                 return status;
 307         }
 308 
 309         if (ads_count_replies(ads, res) != 1) {
 310                 DEBUG(10,("ads_add_gpo_link: no result\n"));
 311                 ads_msgfree(ads, res);
 312                 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
 313         }
 314 
 315         gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink");
 316         if (gp_link == NULL) {
 317                 gp_link_new = talloc_asprintf(mem_ctx, "[%s;%d]",
 318                         gpo_dn, gpo_opt);
 319         } else {
 320                 gp_link_new = talloc_asprintf(mem_ctx, "%s[%s;%d]",
 321                         gp_link, gpo_dn, gpo_opt);
 322         }
 323 
 324         ads_msgfree(ads, res);
 325         ADS_ERROR_HAVE_NO_MEMORY(gp_link_new);
 326 
 327         mods = ads_init_mods(mem_ctx);
 328         ADS_ERROR_HAVE_NO_MEMORY(mods);
 329 
 330         status = ads_mod_str(mem_ctx, &mods, "gPLink", gp_link_new);
 331         if (!ADS_ERR_OK(status)) {
 332                 return status;
 333         }
 334 
 335         return ads_gen_mod(ads, link_dn, mods);
 336 }
 337 
 338 /****************************************************************
 339  helper call to delete add a gp link
 340 ****************************************************************/
 341 
 342 /* untested & broken */
 343 ADS_STATUS ads_delete_gpo_link(ADS_STRUCT *ads,
     /* [<][>][^][v][top][bottom][index][help] */
 344                                TALLOC_CTX *mem_ctx,
 345                                const char *link_dn,
 346                                const char *gpo_dn)
 347 {
 348         ADS_STATUS status;
 349         const char *attrs[] = {"gPLink", NULL};
 350         LDAPMessage *res = NULL;
 351         const char *gp_link, *gp_link_new = NULL;
 352         ADS_MODLIST mods;
 353 
 354         /* check for a sane gpo_dn */
 355         if (gpo_dn[0] != '[') {
 356                 DEBUG(10,("ads_delete_gpo_link: first char not: [\n"));
 357                 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
 358         }
 359 
 360         if (gpo_dn[strlen(gpo_dn)] != ']') {
 361                 DEBUG(10,("ads_delete_gpo_link: last char not: ]\n"));
 362                 return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
 363         }
 364 
 365         status = ads_search_dn(ads, &res, link_dn, attrs);
 366         if (!ADS_ERR_OK(status)) {
 367                 DEBUG(10,("ads_delete_gpo_link: search failed with %s\n",
 368                         ads_errstr(status)));
 369                 return status;
 370         }
 371 
 372         if (ads_count_replies(ads, res) != 1) {
 373                 DEBUG(10,("ads_delete_gpo_link: no result\n"));
 374                 ads_msgfree(ads, res);
 375                 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
 376         }
 377 
 378         gp_link = ads_pull_string(ads, mem_ctx, res, "gPLink");
 379         if (gp_link == NULL) {
 380                 return ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE);
 381         }
 382 
 383         /* find link to delete */
 384         /* gp_link_new = talloc_asprintf(mem_ctx, "%s[%s;%d]", gp_link,
 385                                          gpo_dn, gpo_opt); */
 386 
 387         ads_msgfree(ads, res);
 388         ADS_ERROR_HAVE_NO_MEMORY(gp_link_new);
 389 
 390         mods = ads_init_mods(mem_ctx);
 391         ADS_ERROR_HAVE_NO_MEMORY(mods);
 392 
 393         status = ads_mod_str(mem_ctx, &mods, "gPLink", gp_link_new);
 394         if (!ADS_ERR_OK(status)) {
 395                 return status;
 396         }
 397 
 398         return ads_gen_mod(ads, link_dn, mods);
 399 }
 400 
 401 /****************************************************************
 402  parse a GROUP_POLICY_OBJECT structure from an LDAPMessage result
 403 ****************************************************************/
 404 
 405  ADS_STATUS ads_parse_gpo(ADS_STRUCT *ads,
     /* [<][>][^][v][top][bottom][index][help] */
 406                           TALLOC_CTX *mem_ctx,
 407                           LDAPMessage *res,
 408                           const char *gpo_dn,
 409                           struct GROUP_POLICY_OBJECT *gpo)
 410 {
 411         ZERO_STRUCTP(gpo);
 412 
 413         ADS_ERROR_HAVE_NO_MEMORY(res);
 414 
 415         if (gpo_dn) {
 416                 gpo->ds_path = talloc_strdup(mem_ctx, gpo_dn);
 417         } else {
 418                 gpo->ds_path = ads_get_dn(ads, mem_ctx, res);
 419         }
 420 
 421         ADS_ERROR_HAVE_NO_MEMORY(gpo->ds_path);
 422 
 423         if (!ads_pull_uint32(ads, res, "versionNumber", &gpo->version)) {
 424                 return ADS_ERROR(LDAP_NO_MEMORY);
 425         }
 426 
 427         if (!ads_pull_uint32(ads, res, "flags", &gpo->options)) {
 428                 return ADS_ERROR(LDAP_NO_MEMORY);
 429         }
 430 
 431         gpo->file_sys_path = ads_pull_string(ads, mem_ctx, res,
 432                 "gPCFileSysPath");
 433         ADS_ERROR_HAVE_NO_MEMORY(gpo->file_sys_path);
 434 
 435         gpo->display_name = ads_pull_string(ads, mem_ctx, res,
 436                 "displayName");
 437         ADS_ERROR_HAVE_NO_MEMORY(gpo->display_name);
 438 
 439         gpo->name = ads_pull_string(ads, mem_ctx, res,
 440                 "name");
 441         ADS_ERROR_HAVE_NO_MEMORY(gpo->name);
 442 
 443         gpo->machine_extensions = ads_pull_string(ads, mem_ctx, res,
 444                 "gPCMachineExtensionNames");
 445         gpo->user_extensions = ads_pull_string(ads, mem_ctx, res,
 446                 "gPCUserExtensionNames");
 447 
 448         ads_pull_sd(ads, mem_ctx, res, "ntSecurityDescriptor",
 449                 &gpo->security_descriptor);
 450         ADS_ERROR_HAVE_NO_MEMORY(gpo->security_descriptor);
 451 
 452         return ADS_ERROR(LDAP_SUCCESS);
 453 }
 454 
 455 /****************************************************************
 456  get a GROUP_POLICY_OBJECT structure based on different input parameters
 457 ****************************************************************/
 458 
 459 ADS_STATUS ads_get_gpo(ADS_STRUCT *ads,
     /* [<][>][^][v][top][bottom][index][help] */
 460                        TALLOC_CTX *mem_ctx,
 461                        const char *gpo_dn,
 462                        const char *display_name,
 463                        const char *guid_name,
 464                        struct GROUP_POLICY_OBJECT *gpo)
 465 {
 466         ADS_STATUS status;
 467         LDAPMessage *res = NULL;
 468         char *dn;
 469         const char *filter;
 470         const char *attrs[] = {
 471                 "cn",
 472                 "displayName",
 473                 "flags",
 474                 "gPCFileSysPath",
 475                 "gPCFunctionalityVersion",
 476                 "gPCMachineExtensionNames",
 477                 "gPCUserExtensionNames",
 478                 "gPCWQLFilter",
 479                 "name",
 480                 "ntSecurityDescriptor",
 481                 "versionNumber",
 482                 NULL};
 483         uint32_t sd_flags = DACL_SECURITY_INFORMATION;
 484 
 485         ZERO_STRUCTP(gpo);
 486 
 487         if (!gpo_dn && !display_name && !guid_name) {
 488                 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
 489         }
 490 
 491         if (gpo_dn) {
 492 
 493                 if (strnequal(gpo_dn, "LDAP://", strlen("LDAP://")) != 0) {
 494                         gpo_dn = gpo_dn + strlen("LDAP://");
 495                 }
 496 
 497                 status = ads_search_retry_dn_sd_flags(ads, &res,
 498                                                       sd_flags,
 499                                                       gpo_dn, attrs);
 500 
 501         } else if (display_name || guid_name) {
 502 
 503                 filter = talloc_asprintf(mem_ctx,
 504                                  "(&(objectclass=groupPolicyContainer)(%s=%s))",
 505                                  display_name ? "displayName" : "name",
 506                                  display_name ? display_name : guid_name);
 507                 ADS_ERROR_HAVE_NO_MEMORY(filter);
 508 
 509                 status = ads_do_search_all_sd_flags(ads, ads->config.bind_path,
 510                                                     LDAP_SCOPE_SUBTREE, filter,
 511                                                     attrs, sd_flags, &res);
 512         }
 513 
 514         if (!ADS_ERR_OK(status)) {
 515                 DEBUG(10,("ads_get_gpo: search failed with %s\n",
 516                         ads_errstr(status)));
 517                 return status;
 518         }
 519 
 520         if (ads_count_replies(ads, res) != 1) {
 521                 DEBUG(10,("ads_get_gpo: no result\n"));
 522                 ads_msgfree(ads, res);
 523                 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
 524         }
 525 
 526         dn = ads_get_dn(ads, mem_ctx, res);
 527         if (dn == NULL) {
 528                 ads_msgfree(ads, res);
 529                 return ADS_ERROR(LDAP_NO_MEMORY);
 530         }
 531 
 532         status = ads_parse_gpo(ads, mem_ctx, res, dn, gpo);
 533         ads_msgfree(ads, res);
 534         TALLOC_FREE(dn);
 535 
 536         return status;
 537 }
 538 
 539 /****************************************************************
 540  add a gplink to the GROUP_POLICY_OBJECT linked list
 541 ****************************************************************/
 542 
 543 static ADS_STATUS add_gplink_to_gpo_list(ADS_STRUCT *ads,
     /* [<][>][^][v][top][bottom][index][help] */
 544                                          TALLOC_CTX *mem_ctx,
 545                                          struct GROUP_POLICY_OBJECT **gpo_list,
 546                                          const char *link_dn,
 547                                          struct GP_LINK *gp_link,
 548                                          enum GPO_LINK_TYPE link_type,
 549                                          bool only_add_forced_gpos,
 550                                          const struct nt_user_token *token)
 551 {
 552         ADS_STATUS status;
 553         int i;
 554 
 555         for (i = 0; i < gp_link->num_links; i++) {
 556 
 557                 struct GROUP_POLICY_OBJECT *new_gpo = NULL;
 558 
 559                 if (gp_link->link_opts[i] & GPO_LINK_OPT_DISABLED) {
 560                         DEBUG(10,("skipping disabled GPO\n"));
 561                         continue;
 562                 }
 563 
 564                 if (only_add_forced_gpos) {
 565 
 566                         if (!(gp_link->link_opts[i] & GPO_LINK_OPT_ENFORCED)) {
 567                                 DEBUG(10,("skipping nonenforced GPO link "
 568                                         "because GPOPTIONS_BLOCK_INHERITANCE "
 569                                         "has been set\n"));
 570                                 continue;
 571                         } else {
 572                                 DEBUG(10,("adding enforced GPO link although "
 573                                         "the GPOPTIONS_BLOCK_INHERITANCE "
 574                                         "has been set\n"));
 575                         }
 576                 }
 577 
 578                 new_gpo = TALLOC_ZERO_P(mem_ctx, struct GROUP_POLICY_OBJECT);
 579                 ADS_ERROR_HAVE_NO_MEMORY(new_gpo);
 580 
 581                 status = ads_get_gpo(ads, mem_ctx, gp_link->link_names[i],
 582                                      NULL, NULL, new_gpo);
 583                 if (!ADS_ERR_OK(status)) {
 584                         DEBUG(10,("failed to get gpo: %s\n",
 585                                 gp_link->link_names[i]));
 586                         return status;
 587                 }
 588 
 589                 status = ADS_ERROR_NT(gpo_apply_security_filtering(new_gpo,
 590                                                                    token));
 591                 if (!ADS_ERR_OK(status)) {
 592                         DEBUG(10,("skipping GPO \"%s\" as object "
 593                                 "has no access to it\n",
 594                                 new_gpo->display_name));
 595                         TALLOC_FREE(new_gpo);
 596                         continue;
 597                 }
 598 
 599                 new_gpo->link = link_dn;
 600                 new_gpo->link_type = link_type;
 601 
 602                 DLIST_ADD(*gpo_list, new_gpo);
 603 
 604                 DEBUG(10,("add_gplink_to_gplist: added GPLINK #%d %s "
 605                         "to GPO list\n", i, gp_link->link_names[i]));
 606         }
 607 
 608         return ADS_ERROR(LDAP_SUCCESS);
 609 }
 610 
 611 /****************************************************************
 612 ****************************************************************/
 613 
 614 ADS_STATUS ads_get_sid_token(ADS_STRUCT *ads,
     /* [<][>][^][v][top][bottom][index][help] */
 615                              TALLOC_CTX *mem_ctx,
 616                              const char *dn,
 617                              struct nt_user_token **token)
 618 {
 619         ADS_STATUS status;
 620         DOM_SID object_sid;
 621         DOM_SID primary_group_sid;
 622         DOM_SID *ad_token_sids;
 623         size_t num_ad_token_sids = 0;
 624         DOM_SID *token_sids;
 625         size_t num_token_sids = 0;
 626         struct nt_user_token *new_token = NULL;
 627         int i;
 628 
 629         status = ads_get_tokensids(ads, mem_ctx, dn,
 630                                    &object_sid, &primary_group_sid,
 631                                    &ad_token_sids, &num_ad_token_sids);
 632         if (!ADS_ERR_OK(status)) {
 633                 return status;
 634         }
 635 
 636         token_sids = TALLOC_ARRAY(mem_ctx, DOM_SID, 1);
 637         ADS_ERROR_HAVE_NO_MEMORY(token_sids);
 638 
 639         status = ADS_ERROR_NT(add_sid_to_array_unique(mem_ctx,
 640                                                       &primary_group_sid,
 641                                                       &token_sids,
 642                                                       &num_token_sids));
 643         if (!ADS_ERR_OK(status)) {
 644                 return status;
 645         }
 646 
 647         for (i = 0; i < num_ad_token_sids; i++) {
 648 
 649                 if (sid_check_is_in_builtin(&ad_token_sids[i])) {
 650                         continue;
 651                 }
 652 
 653                 status = ADS_ERROR_NT(add_sid_to_array_unique(mem_ctx,
 654                                                               &ad_token_sids[i],
 655                                                               &token_sids,
 656                                                               &num_token_sids));
 657                 if (!ADS_ERR_OK(status)) {
 658                         return status;
 659                 }
 660         }
 661 
 662         new_token = create_local_nt_token(mem_ctx, &object_sid, false,
 663                                           num_token_sids, token_sids);
 664         ADS_ERROR_HAVE_NO_MEMORY(new_token);
 665 
 666         *token = new_token;
 667 
 668         debug_nt_user_token(DBGC_CLASS, 5, *token);
 669 
 670         return ADS_ERROR_LDAP(LDAP_SUCCESS);
 671 }
 672 
 673 /****************************************************************
 674 ****************************************************************/
 675 
 676 static ADS_STATUS add_local_policy_to_gpo_list(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 677                                                struct GROUP_POLICY_OBJECT **gpo_list,
 678                                                enum GPO_LINK_TYPE link_type)
 679 {
 680         struct GROUP_POLICY_OBJECT *gpo = NULL;
 681 
 682         ADS_ERROR_HAVE_NO_MEMORY(gpo_list);
 683 
 684         gpo = TALLOC_ZERO_P(mem_ctx, struct GROUP_POLICY_OBJECT);
 685         ADS_ERROR_HAVE_NO_MEMORY(gpo);
 686 
 687         gpo->name = talloc_strdup(mem_ctx, "Local Policy");
 688         ADS_ERROR_HAVE_NO_MEMORY(gpo->name);
 689 
 690         gpo->display_name = talloc_strdup(mem_ctx, "Local Policy");
 691         ADS_ERROR_HAVE_NO_MEMORY(gpo->display_name);
 692 
 693         gpo->link_type = link_type;
 694 
 695         DLIST_ADD(*gpo_list, gpo);
 696 
 697         return ADS_ERROR_NT(NT_STATUS_OK);
 698 }
 699 
 700 /****************************************************************
 701  get the full list of GROUP_POLICY_OBJECTs for a given dn
 702 ****************************************************************/
 703 
 704 ADS_STATUS ads_get_gpo_list(ADS_STRUCT *ads,
     /* [<][>][^][v][top][bottom][index][help] */
 705                             TALLOC_CTX *mem_ctx,
 706                             const char *dn,
 707                             uint32_t flags,
 708                             const struct nt_user_token *token,
 709                             struct GROUP_POLICY_OBJECT **gpo_list)
 710 {
 711         /* (L)ocal (S)ite (D)omain (O)rganizational(U)nit */
 712 
 713         ADS_STATUS status;
 714         struct GP_LINK gp_link;
 715         const char *parent_dn, *site_dn, *tmp_dn;
 716         bool add_only_forced_gpos = false;
 717 
 718         ZERO_STRUCTP(gpo_list);
 719 
 720         if (!dn) {
 721                 return ADS_ERROR(LDAP_PARAM_ERROR);
 722         }
 723 
 724         DEBUG(10,("ads_get_gpo_list: getting GPO list for [%s]\n", dn));
 725 
 726         /* (L)ocal */
 727         status = add_local_policy_to_gpo_list(mem_ctx, gpo_list,
 728                                               GP_LINK_LOCAL);
 729         if (!ADS_ERR_OK(status)) {
 730                 return status;
 731         }
 732 
 733         /* (S)ite */
 734 
 735         /* are site GPOs valid for users as well ??? */
 736         if (flags & GPO_LIST_FLAG_MACHINE) {
 737 
 738                 status = ads_site_dn_for_machine(ads, mem_ctx,
 739                                                  ads->config.ldap_server_name,
 740                                                  &site_dn);
 741                 if (!ADS_ERR_OK(status)) {
 742                         return status;
 743                 }
 744 
 745                 DEBUG(10,("ads_get_gpo_list: query SITE: [%s] for GPOs\n",
 746                         site_dn));
 747 
 748                 status = ads_get_gpo_link(ads, mem_ctx, site_dn, &gp_link);
 749                 if (ADS_ERR_OK(status)) {
 750 
 751                         if (DEBUGLEVEL >= 100) {
 752                                 dump_gplink(ads, mem_ctx, &gp_link);
 753                         }
 754 
 755                         status = add_gplink_to_gpo_list(ads, mem_ctx, gpo_list,
 756                                                         site_dn, &gp_link,
 757                                                         GP_LINK_SITE,
 758                                                         add_only_forced_gpos,
 759                                                         token);
 760                         if (!ADS_ERR_OK(status)) {
 761                                 return status;
 762                         }
 763 
 764                         if (flags & GPO_LIST_FLAG_SITEONLY) {
 765                                 return ADS_ERROR(LDAP_SUCCESS);
 766                         }
 767 
 768                         /* inheritance can't be blocked at the site level */
 769                 }
 770         }
 771 
 772         tmp_dn = dn;
 773 
 774         while ((parent_dn = ads_parent_dn(tmp_dn)) &&
 775                (!strequal(parent_dn, ads_parent_dn(ads->config.bind_path)))) {
 776 
 777                 /* (D)omain */
 778 
 779                 /* An account can just be a member of one domain */
 780                 if (strncmp(parent_dn, "DC=", strlen("DC=")) == 0) {
 781 
 782                         DEBUG(10,("ads_get_gpo_list: query DC: [%s] for GPOs\n",
 783                                 parent_dn));
 784 
 785                         status = ads_get_gpo_link(ads, mem_ctx, parent_dn,
 786                                                   &gp_link);
 787                         if (ADS_ERR_OK(status)) {
 788 
 789                                 if (DEBUGLEVEL >= 100) {
 790                                         dump_gplink(ads, mem_ctx, &gp_link);
 791                                 }
 792 
 793                                 /* block inheritance from now on */
 794                                 if (gp_link.gp_opts &
 795                                     GPOPTIONS_BLOCK_INHERITANCE) {
 796                                         add_only_forced_gpos = true;
 797                                 }
 798 
 799                                 status = add_gplink_to_gpo_list(ads,
 800                                                         mem_ctx,
 801                                                         gpo_list,
 802                                                         parent_dn,
 803                                                         &gp_link,
 804                                                         GP_LINK_DOMAIN,
 805                                                         add_only_forced_gpos,
 806                                                         token);
 807                                 if (!ADS_ERR_OK(status)) {
 808                                         return status;
 809                                 }
 810                         }
 811                 }
 812 
 813                 tmp_dn = parent_dn;
 814         }
 815 
 816         /* reset dn again */
 817         tmp_dn = dn;
 818 
 819         while ((parent_dn = ads_parent_dn(tmp_dn)) &&
 820                (!strequal(parent_dn, ads_parent_dn(ads->config.bind_path)))) {
 821 
 822 
 823                 /* (O)rganizational(U)nit */
 824 
 825                 /* An account can be a member of more OUs */
 826                 if (strncmp(parent_dn, "OU=", strlen("OU=")) == 0) {
 827 
 828                         DEBUG(10,("ads_get_gpo_list: query OU: [%s] for GPOs\n",
 829                                 parent_dn));
 830 
 831                         status = ads_get_gpo_link(ads, mem_ctx, parent_dn,
 832                                                   &gp_link);
 833                         if (ADS_ERR_OK(status)) {
 834 
 835                                 if (DEBUGLEVEL >= 100) {
 836                                         dump_gplink(ads, mem_ctx, &gp_link);
 837                                 }
 838 
 839                                 /* block inheritance from now on */
 840                                 if (gp_link.gp_opts &
 841                                     GPOPTIONS_BLOCK_INHERITANCE) {
 842                                         add_only_forced_gpos = true;
 843                                 }
 844 
 845                                 status = add_gplink_to_gpo_list(ads,
 846                                                         mem_ctx,
 847                                                         gpo_list,
 848                                                         parent_dn,
 849                                                         &gp_link,
 850                                                         GP_LINK_OU,
 851                                                         add_only_forced_gpos,
 852                                                         token);
 853                                 if (!ADS_ERR_OK(status)) {
 854                                         return status;
 855                                 }
 856                         }
 857                 }
 858 
 859                 tmp_dn = parent_dn;
 860 
 861         };
 862 
 863         return ADS_ERROR(LDAP_SUCCESS);
 864 }
 865 
 866 #endif /* HAVE_LDAP */

/* [<][>][^][v][top][bottom][index][help] */