root/source3/libgpo/gpext/gpext.c

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

DEFINITIONS

This source file includes following definitions.
  1. get_gp_extension_list
  2. get_extension_by_name
  3. get_methods_by_name
  4. unregister_gp_extension
  5. register_gp_extension
  6. gp_extension_init_module
  7. add_gp_extension_reg_entry_to_array
  8. add_gp_extension_reg_info_entry_to_array
  9. gp_ext_info_add_reg
  10. gp_ext_info_add_reg_table
  11. gp_ext_info_add_entry
  12. gp_extension_reg_info_verify_entry
  13. gp_extension_reg_info_verify
  14. gp_extension_store_reg_vals
  15. gp_extension_store_reg_entry
  16. gp_extension_store_reg
  17. gp_glob_ext_list
  18. shutdown_gp_extensions
  19. init_gp_extensions
  20. free_gp_extensions
  21. debug_gpext_header
  22. process_gpo_list_with_extension
  23. gpext_process_extension

   1 /*
   2  *  Unix SMB/CIFS implementation.
   3  *  Group Policy Support
   4  *  Copyright (C) Guenther Deschner 2007-2008
   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 static struct gp_extension *extensions = NULL;
  23 
  24 /****************************************************************
  25 ****************************************************************/
  26 
  27 struct gp_extension *get_gp_extension_list(void)
     /* [<][>][^][v][top][bottom][index][help] */
  28 {
  29         return extensions;
  30 }
  31 
  32 /****************************************************************
  33 ****************************************************************/
  34 
  35 /* see http://support.microsoft.com/kb/216358/en-us/ for more info */
  36 
  37 struct gp_extension_reg_table gpext_reg_vals[] = {
  38         { "DllName", REG_EXPAND_SZ },
  39         { "ProcessGroupPolicy", REG_SZ },
  40         { "NoMachinePolicy", REG_DWORD },
  41         { "NoUserPolicy", REG_DWORD },
  42         { "NoSlowLink", REG_DWORD },
  43         { "NoBackgroundPolicy", REG_DWORD },
  44         { "NoGPOListChanges", REG_DWORD },
  45         { "PerUserLocalSettings", REG_DWORD },
  46         { "RequiresSuccessfulRegistry", REG_DWORD },
  47         { "EnableAsynchronousProcessing", REG_DWORD },
  48         { "ExtensionDebugLevel", REG_DWORD },
  49         /* new */
  50         { "GenerateGroupPolicy", REG_SZ }, /* not supported on w2k */
  51         { "NotifyLinkTransition", REG_DWORD },
  52         { "ProcessGroupPolicyEx", REG_SZ }, /* not supported on w2k */
  53         { "ExtensionEventSource", REG_MULTI_SZ }, /* not supported on w2k */
  54         { "GenerateGroupPolicy", REG_SZ },
  55         { "MaxNoGPOListChangesInterval", REG_DWORD },
  56         { NULL, REG_NONE }
  57 };
  58 
  59 /****************************************************************
  60 ****************************************************************/
  61 
  62 static struct gp_extension *get_extension_by_name(struct gp_extension *be,
     /* [<][>][^][v][top][bottom][index][help] */
  63                                                   const char *name)
  64 {
  65         struct gp_extension *b;
  66 
  67         for (b = be; b; b = b->next) {
  68                 if (strequal(b->name, name)) {
  69                         return b;
  70                 }
  71         }
  72 
  73         return NULL;
  74 }
  75 
  76 /****************************************************************
  77 ****************************************************************/
  78 
  79 static struct gp_extension_methods *get_methods_by_name(struct gp_extension *be,
     /* [<][>][^][v][top][bottom][index][help] */
  80                                                         const char *name)
  81 {
  82         struct gp_extension *b;
  83 
  84         for (b = be; b; b = b->next) {
  85                 if (strequal(b->name, name)) {
  86                         return b->methods;
  87                 }
  88         }
  89 
  90         return NULL;
  91 }
  92 
  93 /****************************************************************
  94 ****************************************************************/
  95 
  96 NTSTATUS unregister_gp_extension(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
  97 {
  98         struct gp_extension *ext;
  99 
 100         ext = get_extension_by_name(extensions, name);
 101         if (!ext) {
 102                 return NT_STATUS_OK;
 103         }
 104 
 105         DLIST_REMOVE(extensions, ext);
 106         TALLOC_FREE(ext);
 107 
 108         DEBUG(2,("Successfully removed GP extension '%s'\n", name));
 109 
 110         return NT_STATUS_OK;
 111 }
 112 
 113 /****************************************************************
 114 ****************************************************************/
 115 
 116 NTSTATUS register_gp_extension(TALLOC_CTX *gpext_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 117                                int version,
 118                                const char *name,
 119                                const char *guid,
 120                                struct gp_extension_methods *methods)
 121 {
 122         struct gp_extension_methods *test;
 123         struct gp_extension *entry;
 124         NTSTATUS status;
 125 
 126         if (!gpext_ctx) {
 127                 return NT_STATUS_INTERNAL_DB_ERROR;
 128         }
 129 
 130         if ((version != SMB_GPEXT_INTERFACE_VERSION)) {
 131                 DEBUG(0,("Failed to register gp extension.\n"
 132                          "The module was compiled against "
 133                          "SMB_GPEXT_INTERFACE_VERSION %d,\n"
 134                          "current SMB_GPEXT_INTERFACE_VERSION is %d.\n"
 135                          "Please recompile against the current "
 136                          "version of samba!\n",
 137                          version, SMB_GPEXT_INTERFACE_VERSION));
 138                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
 139         }
 140 
 141         if (!guid || !name || !name[0] || !methods) {
 142                 DEBUG(0,("Called with NULL pointer or empty name!\n"));
 143                 return NT_STATUS_INVALID_PARAMETER;
 144         }
 145 
 146         test = get_methods_by_name(extensions, name);
 147         if (test) {
 148                 DEBUG(0,("GP extension module %s already registered!\n",
 149                         name));
 150                 return NT_STATUS_OBJECT_NAME_COLLISION;
 151         }
 152 
 153         entry = TALLOC_ZERO_P(gpext_ctx, struct gp_extension);
 154         NT_STATUS_HAVE_NO_MEMORY(entry);
 155 
 156         entry->name = talloc_strdup(gpext_ctx, name);
 157         NT_STATUS_HAVE_NO_MEMORY(entry->name);
 158 
 159         entry->guid = TALLOC_ZERO_P(gpext_ctx, struct GUID);
 160         NT_STATUS_HAVE_NO_MEMORY(entry->guid);
 161         status = GUID_from_string(guid, entry->guid);
 162         NT_STATUS_NOT_OK_RETURN(status);
 163 
 164         entry->methods = methods;
 165         DLIST_ADD(extensions, entry);
 166 
 167         DEBUG(2,("Successfully added GP extension '%s' %s\n",
 168                 name, GUID_string2(gpext_ctx, entry->guid)));
 169 
 170         return NT_STATUS_OK;
 171 }
 172 
 173 /****************************************************************
 174 ****************************************************************/
 175 
 176 static NTSTATUS gp_extension_init_module(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 177                                          const char *name,
 178                                          struct gp_extension **gpext)
 179 {
 180         NTSTATUS status;
 181         struct gp_extension *ext = NULL;
 182 
 183         ext = TALLOC_ZERO_P(mem_ctx, struct gp_extension);
 184         NT_STATUS_HAVE_NO_MEMORY(gpext);
 185 
 186         ext->methods = get_methods_by_name(extensions, name);
 187         if (!ext->methods) {
 188 
 189                 status = smb_probe_module(SAMBA_SUBSYSTEM_GPEXT,
 190                                           name);
 191                 if (!NT_STATUS_IS_OK(status)) {
 192                         return status;
 193                 }
 194 
 195                 ext->methods = get_methods_by_name(extensions, name);
 196                 if (!ext->methods) {
 197                         return NT_STATUS_DLL_INIT_FAILED;
 198                 }
 199         }
 200 
 201         *gpext = ext;
 202 
 203         return NT_STATUS_OK;
 204 }
 205 
 206 /****************************************************************
 207 ****************************************************************/
 208 
 209 static bool add_gp_extension_reg_entry_to_array(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 210                                                 struct gp_extension_reg_entry *entry,
 211                                                 struct gp_extension_reg_entry **entries,
 212                                                 size_t *num)
 213 {
 214         *entries = TALLOC_REALLOC_ARRAY(mem_ctx, *entries,
 215                                         struct gp_extension_reg_entry,
 216                                         (*num)+1);
 217         if (*entries == NULL) {
 218                 *num = 0;
 219                 return false;
 220         }
 221 
 222         (*entries)[*num].value = entry->value;
 223         (*entries)[*num].data = entry->data;
 224 
 225         *num += 1;
 226         return true;
 227 }
 228 
 229 /****************************************************************
 230 ****************************************************************/
 231 
 232 static bool add_gp_extension_reg_info_entry_to_array(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 233                                                      struct gp_extension_reg_info_entry *entry,
 234                                                      struct gp_extension_reg_info_entry **entries,
 235                                                      size_t *num)
 236 {
 237         *entries = TALLOC_REALLOC_ARRAY(mem_ctx, *entries,
 238                                         struct gp_extension_reg_info_entry,
 239                                         (*num)+1);
 240         if (*entries == NULL) {
 241                 *num = 0;
 242                 return false;
 243         }
 244 
 245         (*entries)[*num].guid = entry->guid;
 246         (*entries)[*num].num_entries = entry->num_entries;
 247         (*entries)[*num].entries = entry->entries;
 248 
 249         *num += 1;
 250         return true;
 251 }
 252 
 253 /****************************************************************
 254 ****************************************************************/
 255 
 256 static NTSTATUS gp_ext_info_add_reg(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 257                                     struct gp_extension_reg_info_entry *entry,
 258                                     const char *value,
 259                                     enum winreg_Type type,
 260                                     const char *data_s)
 261 {
 262         struct gp_extension_reg_entry *reg_entry = NULL;
 263         struct registry_value *data = NULL;
 264 
 265         reg_entry = TALLOC_ZERO_P(mem_ctx, struct gp_extension_reg_entry);
 266         NT_STATUS_HAVE_NO_MEMORY(reg_entry);
 267 
 268         data = TALLOC_ZERO_P(mem_ctx, struct registry_value);
 269         NT_STATUS_HAVE_NO_MEMORY(data);
 270 
 271         data->type = type;
 272 
 273         switch (type) {
 274                 case REG_SZ:
 275                 case REG_EXPAND_SZ:
 276                         data->v.sz.str = talloc_strdup(mem_ctx, data_s);
 277                         NT_STATUS_HAVE_NO_MEMORY(data->v.sz.str);
 278                         data->v.sz.len = strlen(data_s);
 279                         break;
 280                 case REG_DWORD:
 281                         data->v.dword = atoi(data_s);
 282                         break;
 283                 default:
 284                         return NT_STATUS_NOT_SUPPORTED;
 285         }
 286 
 287         reg_entry->value = value;
 288         reg_entry->data = data;
 289 
 290         if (!add_gp_extension_reg_entry_to_array(mem_ctx, reg_entry,
 291                                                  &entry->entries,
 292                                                  &entry->num_entries)) {
 293                 return NT_STATUS_NO_MEMORY;
 294         }
 295 
 296         return NT_STATUS_OK;
 297 }
 298 
 299 /****************************************************************
 300 ****************************************************************/
 301 
 302 static NTSTATUS gp_ext_info_add_reg_table(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 303                                           const char *module,
 304                                           struct gp_extension_reg_info_entry *entry,
 305                                           struct gp_extension_reg_table *table)
 306 {
 307         NTSTATUS status;
 308         const char *module_name = NULL;
 309         int i;
 310 
 311         module_name = talloc_asprintf(mem_ctx, "%s.%s", module, shlib_ext());
 312         NT_STATUS_HAVE_NO_MEMORY(module_name);
 313 
 314         status = gp_ext_info_add_reg(mem_ctx, entry,
 315                                      "DllName", REG_EXPAND_SZ, module_name);
 316         NT_STATUS_NOT_OK_RETURN(status);
 317 
 318         for (i=0; table[i].val; i++) {
 319                 status = gp_ext_info_add_reg(mem_ctx, entry,
 320                                              table[i].val,
 321                                              table[i].type,
 322                                              table[i].data);
 323                 NT_STATUS_NOT_OK_RETURN(status);
 324         }
 325 
 326         return status;
 327 }
 328 
 329 /****************************************************************
 330 ****************************************************************/
 331 
 332 NTSTATUS gp_ext_info_add_entry(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 333                                const char *module,
 334                                const char *ext_guid,
 335                                struct gp_extension_reg_table *table,
 336                                struct gp_extension_reg_info *info)
 337 {
 338         NTSTATUS status;
 339         struct gp_extension_reg_info_entry *entry = NULL;
 340 
 341         entry = TALLOC_ZERO_P(mem_ctx, struct gp_extension_reg_info_entry);
 342         NT_STATUS_HAVE_NO_MEMORY(entry);
 343 
 344         status = GUID_from_string(ext_guid, &entry->guid);
 345         NT_STATUS_NOT_OK_RETURN(status);
 346 
 347         status = gp_ext_info_add_reg_table(mem_ctx, module, entry, table);
 348         NT_STATUS_NOT_OK_RETURN(status);
 349 
 350         if (!add_gp_extension_reg_info_entry_to_array(mem_ctx, entry,
 351                                                       &info->entries,
 352                                                       &info->num_entries)) {
 353                 return NT_STATUS_NO_MEMORY;
 354         }
 355 
 356         return NT_STATUS_OK;
 357 }
 358 
 359 /****************************************************************
 360 ****************************************************************/
 361 
 362 static bool gp_extension_reg_info_verify_entry(struct gp_extension_reg_entry *entry)
     /* [<][>][^][v][top][bottom][index][help] */
 363 {
 364         int i;
 365 
 366         for (i=0; gpext_reg_vals[i].val; i++) {
 367 
 368                 if ((strequal(entry->value, gpext_reg_vals[i].val)) &&
 369                     (entry->data->type == gpext_reg_vals[i].type)) {
 370                         return true;
 371                 }
 372         }
 373 
 374         return false;
 375 }
 376 
 377 /****************************************************************
 378 ****************************************************************/
 379 
 380 static bool gp_extension_reg_info_verify(struct gp_extension_reg_info_entry *entry)
     /* [<][>][^][v][top][bottom][index][help] */
 381 {
 382         int i;
 383 
 384         for (i=0; i < entry->num_entries; i++) {
 385                 if (!gp_extension_reg_info_verify_entry(&entry->entries[i])) {
 386                         return false;
 387                 }
 388         }
 389 
 390         return true;
 391 }
 392 
 393 /****************************************************************
 394 ****************************************************************/
 395 
 396 static WERROR gp_extension_store_reg_vals(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 397                                           struct registry_key *key,
 398                                           struct gp_extension_reg_info_entry *entry)
 399 {
 400         WERROR werr = WERR_OK;
 401         size_t i;
 402 
 403         for (i=0; i < entry->num_entries; i++) {
 404 
 405                 werr = reg_setvalue(key,
 406                                     entry->entries[i].value,
 407                                     entry->entries[i].data);
 408                 W_ERROR_NOT_OK_RETURN(werr);
 409         }
 410 
 411         return werr;
 412 }
 413 
 414 /****************************************************************
 415 ****************************************************************/
 416 
 417 static WERROR gp_extension_store_reg_entry(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 418                                            struct gp_registry_context *reg_ctx,
 419                                            struct gp_extension_reg_info_entry *entry)
 420 {
 421         WERROR werr;
 422         struct registry_key *key = NULL;
 423         const char *subkeyname = NULL;
 424 
 425         if (!gp_extension_reg_info_verify(entry)) {
 426                 return WERR_INVALID_PARAM;
 427         }
 428 
 429         subkeyname = GUID_string2(mem_ctx, &entry->guid);
 430         W_ERROR_HAVE_NO_MEMORY(subkeyname);
 431 
 432         strupper_m(CONST_DISCARD(char *,subkeyname));
 433 
 434         werr = gp_store_reg_subkey(mem_ctx,
 435                                    subkeyname,
 436                                    reg_ctx->curr_key,
 437                                    &key);
 438         W_ERROR_NOT_OK_RETURN(werr);
 439 
 440         werr = gp_extension_store_reg_vals(mem_ctx,
 441                                            key,
 442                                            entry);
 443         W_ERROR_NOT_OK_RETURN(werr);
 444 
 445         return werr;
 446 }
 447 
 448 /****************************************************************
 449 ****************************************************************/
 450 
 451 static WERROR gp_extension_store_reg(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 452                                      struct gp_registry_context *reg_ctx,
 453                                      struct gp_extension_reg_info *info)
 454 {
 455         WERROR werr = WERR_OK;
 456         int i;
 457 
 458         if (!info) {
 459                 return WERR_OK;
 460         }
 461 
 462         for (i=0; i < info->num_entries; i++) {
 463                 werr = gp_extension_store_reg_entry(mem_ctx,
 464                                                     reg_ctx,
 465                                                     &info->entries[i]);
 466                 W_ERROR_NOT_OK_RETURN(werr);
 467         }
 468 
 469         return werr;
 470 }
 471 
 472 /****************************************************************
 473 ****************************************************************/
 474 
 475 static NTSTATUS gp_glob_ext_list(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 476                                  const char ***ext_list,
 477                                  size_t *ext_list_len)
 478 {
 479         SMB_STRUCT_DIR *dir = NULL;
 480         SMB_STRUCT_DIRENT *dirent = NULL;
 481 
 482         dir = sys_opendir(modules_path(SAMBA_SUBSYSTEM_GPEXT));
 483         if (!dir) {
 484                 return map_nt_error_from_unix(errno);
 485         }
 486 
 487         while ((dirent = sys_readdir(dir))) {
 488 
 489                 fstring name; /* forgive me... */
 490                 char *p;
 491 
 492                 if ((strequal(dirent->d_name, ".")) ||
 493                     (strequal(dirent->d_name, ".."))) {
 494                         continue;
 495                 }
 496 
 497                 p = strrchr(dirent->d_name, '.');
 498                 if (!p) {
 499                         sys_closedir(dir);
 500                         return NT_STATUS_NO_MEMORY;
 501                 }
 502 
 503                 if (!strcsequal(p+1, shlib_ext())) {
 504                         DEBUG(10,("gp_glob_ext_list: not a *.so file: %s\n",
 505                                 dirent->d_name));
 506                         continue;
 507                 }
 508 
 509                 fstrcpy(name, dirent->d_name);
 510                 name[PTR_DIFF(p, dirent->d_name)] = 0;
 511 
 512                 if (!add_string_to_array(mem_ctx, name, ext_list,
 513                                          (int *)ext_list_len)) {
 514                         sys_closedir(dir);
 515                         return NT_STATUS_NO_MEMORY;
 516                 }
 517         }
 518 
 519         sys_closedir(dir);
 520 
 521         return NT_STATUS_OK;
 522 }
 523 
 524 /****************************************************************
 525 ****************************************************************/
 526 
 527 NTSTATUS shutdown_gp_extensions(void)
     /* [<][>][^][v][top][bottom][index][help] */
 528 {
 529         struct gp_extension *ext = NULL;
 530 
 531         for (ext = extensions; ext; ext = ext->next) {
 532                 if (ext->methods && ext->methods->shutdown) {
 533                         ext->methods->shutdown();
 534                 }
 535         }
 536 
 537         return NT_STATUS_OK;
 538 }
 539 
 540 /****************************************************************
 541 ****************************************************************/
 542 
 543 NTSTATUS init_gp_extensions(TALLOC_CTX *mem_ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 544 {
 545         NTSTATUS status;
 546         WERROR werr;
 547         int i = 0;
 548         const char **ext_array = NULL;
 549         size_t ext_array_len = 0;
 550         struct gp_extension *gpext = NULL;
 551         struct gp_registry_context *reg_ctx = NULL;
 552 
 553         if (get_gp_extension_list()) {
 554                 return NT_STATUS_OK;
 555         }
 556 
 557         status = gp_glob_ext_list(mem_ctx, &ext_array, &ext_array_len);
 558         NT_STATUS_NOT_OK_RETURN(status);
 559 
 560         for (i=0; i<ext_array_len; i++) {
 561 
 562                 struct gp_extension_reg_info *info = NULL;
 563 
 564                 status = gp_extension_init_module(mem_ctx, ext_array[i],
 565                                                   &gpext);
 566                 if (!NT_STATUS_IS_OK(status)) {
 567                         goto out;
 568                 }
 569 
 570                 if (gpext->methods->get_reg_config) {
 571 
 572                         status = gpext->methods->initialize(mem_ctx);
 573                         if (!NT_STATUS_IS_OK(status)) {
 574                                 gpext->methods->shutdown();
 575                                 goto out;
 576                         }
 577 
 578                         status = gpext->methods->get_reg_config(mem_ctx,
 579                                                                 &info);
 580                         if (!NT_STATUS_IS_OK(status)) {
 581                                 gpext->methods->shutdown();
 582                                 goto out;
 583                         }
 584 
 585                         if (!reg_ctx) {
 586                                 struct nt_user_token *token;
 587 
 588                                 token = registry_create_system_token(mem_ctx);
 589                                 NT_STATUS_HAVE_NO_MEMORY(token);
 590 
 591                                 werr = gp_init_reg_ctx(mem_ctx,
 592                                                        KEY_WINLOGON_GPEXT_PATH,
 593                                                        REG_KEY_WRITE,
 594                                                        token,
 595                                                        &reg_ctx);
 596                                 if (!W_ERROR_IS_OK(werr)) {
 597                                         status = werror_to_ntstatus(werr);
 598                                         gpext->methods->shutdown();
 599                                         goto out;
 600                                 }
 601                         }
 602 
 603                         werr = gp_extension_store_reg(mem_ctx, reg_ctx, info);
 604                         if (!W_ERROR_IS_OK(werr)) {
 605                                 DEBUG(1,("gp_extension_store_reg failed: %s\n",
 606                                         win_errstr(werr)));
 607                                 TALLOC_FREE(info);
 608                                 gpext->methods->shutdown();
 609                                 status = werror_to_ntstatus(werr);
 610                                 goto out;
 611                         }
 612                         TALLOC_FREE(info);
 613                 }
 614 
 615         }
 616 
 617  out:
 618         TALLOC_FREE(reg_ctx);
 619 
 620         return status;
 621 }
 622 
 623 /****************************************************************
 624 ****************************************************************/
 625 
 626 NTSTATUS free_gp_extensions(void)
     /* [<][>][^][v][top][bottom][index][help] */
 627 {
 628         struct gp_extension *ext, *ext_next = NULL;
 629 
 630         for (ext = extensions; ext; ext = ext_next) {
 631                 ext_next = ext->next;
 632                 DLIST_REMOVE(extensions, ext);
 633                 TALLOC_FREE(ext);
 634         }
 635 
 636         extensions = NULL;
 637 
 638         return NT_STATUS_OK;
 639 }
 640 
 641 /****************************************************************
 642 ****************************************************************/
 643 
 644 void debug_gpext_header(int lvl,
     /* [<][>][^][v][top][bottom][index][help] */
 645                         const char *name,
 646                         uint32_t flags,
 647                         struct GROUP_POLICY_OBJECT *gpo,
 648                         const char *extension_guid,
 649                         const char *snapin_guid)
 650 {
 651         char *flags_str = NULL;
 652 
 653         DEBUG(lvl,("%s\n", name));
 654         DEBUGADD(lvl,("\tgpo:           %s (%s)\n", gpo->name,
 655                 gpo->display_name));
 656         DEBUGADD(lvl,("\tcse extension: %s (%s)\n", extension_guid,
 657                 cse_gpo_guid_string_to_name(extension_guid)));
 658         DEBUGADD(lvl,("\tgplink:        %s\n", gpo->link));
 659         DEBUGADD(lvl,("\tsnapin:        %s (%s)\n", snapin_guid,
 660                 cse_snapin_gpo_guid_string_to_name(snapin_guid)));
 661 
 662         flags_str = gpo_flag_str(flags);
 663         DEBUGADD(lvl,("\tflags:         0x%08x %s\n", flags, flags_str));
 664         SAFE_FREE(flags_str);
 665 }
 666 
 667 NTSTATUS process_gpo_list_with_extension(ADS_STRUCT *ads,
     /* [<][>][^][v][top][bottom][index][help] */
 668                            TALLOC_CTX *mem_ctx,
 669                            uint32_t flags,
 670                            const struct nt_user_token *token,
 671                            struct GROUP_POLICY_OBJECT *gpo_list,
 672                            const char *extension_guid,
 673                            const char *snapin_guid)
 674 {
 675         return NT_STATUS_OK;
 676 }
 677 
 678 /****************************************************************
 679 ****************************************************************/
 680 
 681 NTSTATUS gpext_process_extension(ADS_STRUCT *ads,
     /* [<][>][^][v][top][bottom][index][help] */
 682                                  TALLOC_CTX *mem_ctx,
 683                                  uint32_t flags,
 684                                  const struct nt_user_token *token,
 685                                  struct registry_key *root_key,
 686                                  struct GROUP_POLICY_OBJECT *gpo,
 687                                  const char *extension_guid,
 688                                  const char *snapin_guid)
 689 {
 690         NTSTATUS status;
 691         struct gp_extension *ext = NULL;
 692         struct GUID guid;
 693         bool cse_found = false;
 694 
 695         status = init_gp_extensions(mem_ctx);
 696         if (!NT_STATUS_IS_OK(status)) {
 697                 DEBUG(1,("init_gp_extensions failed: %s\n",
 698                         nt_errstr(status)));
 699                 return status;
 700         }
 701 
 702         status = GUID_from_string(extension_guid, &guid);
 703         if (!NT_STATUS_IS_OK(status)) {
 704                 return status;
 705         }
 706 
 707         for (ext = extensions; ext; ext = ext->next) {
 708 
 709                 if (GUID_equal(ext->guid, &guid)) {
 710                         cse_found = true;
 711                         break;
 712                 }
 713         }
 714 
 715         if (!cse_found) {
 716                 goto no_ext;
 717         }
 718 
 719         status = ext->methods->initialize(mem_ctx);
 720         NT_STATUS_NOT_OK_RETURN(status);
 721 
 722         status = ext->methods->process_group_policy(ads,
 723                                                     mem_ctx,
 724                                                     flags,
 725                                                     root_key,
 726                                                     token,
 727                                                     gpo,
 728                                                     extension_guid,
 729                                                     snapin_guid);
 730         if (!NT_STATUS_IS_OK(status)) {
 731                 ext->methods->shutdown();
 732         }
 733 
 734         return status;
 735 
 736  no_ext:
 737         if (flags & GPO_INFO_FLAG_VERBOSE) {
 738                 DEBUG(0,("process_extension: no extension available for:\n"));
 739                 DEBUGADD(0,("%s (%s) (snapin: %s)\n",
 740                         extension_guid,
 741                         cse_gpo_guid_string_to_name(extension_guid),
 742                         snapin_guid));
 743         }
 744 
 745         return NT_STATUS_OK;
 746 }

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