s3-build: only use ndr_security.h where needed.
[ira/wip.git] / libgpo / gpo_util.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  Group Policy Object Support
4  *  Copyright (C) Guenther Deschner 2005-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 #define TALLOC_DEPRECATED 1
20 #include "includes.h"
21 #include "librpc/gen_ndr/ndr_misc.h"
22 #include "../librpc/gen_ndr/ndr_security.h"
23 #include "../libgpo/gpo.h"
24 #if _SAMBA_BUILD_ == 4
25 #include "system/filesys.h"
26 #include "auth/auth.h"
27 #include "../lib/talloc/talloc.h"
28 #include "source4/libgpo/ads_convenience.h"
29 #endif
30 #undef strdup
31
32 #if 0
33 #define DEFAULT_DOMAIN_POLICY "Default Domain Policy"
34 #define DEFAULT_DOMAIN_CONTROLLERS_POLICY "Default Domain Controllers Policy"
35 #endif
36
37 /* should we store a parsed guid ? */
38 struct gp_table {
39         const char *name;
40         const char *guid_string;
41 };
42
43 #if 0 /* unused */
44 static struct gp_table gpo_default_policy[] = {
45         { DEFAULT_DOMAIN_POLICY,
46                 "31B2F340-016D-11D2-945F-00C04FB984F9" },
47         { DEFAULT_DOMAIN_CONTROLLERS_POLICY,
48                 "6AC1786C-016F-11D2-945F-00C04fB984F9" },
49         { NULL, NULL }
50 };
51 #endif
52
53 /* the following is seen in gPCMachineExtensionNames / gPCUserExtensionNames */
54
55 static struct gp_table gpo_cse_extensions[] = {
56         /* used to be "Administrative Templates Extension" */
57         /* "Registry Settings"
58         (http://support.microsoft.com/kb/216357/EN-US/) */
59         { "Registry Settings",
60                 GP_EXT_GUID_REGISTRY },
61         { "Microsoft Disc Quota",
62                 "3610EDA5-77EF-11D2-8DC5-00C04FA31A66" },
63         { "EFS recovery",
64                 "B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A" },
65         { "Folder Redirection",
66                 "25537BA6-77A8-11D2-9B6C-0000F8080861" },
67         { "IP Security",
68                 "E437BC1C-AA7D-11D2-A382-00C04F991E27" },
69         { "Internet Explorer Branding",
70                 "A2E30F80-D7DE-11d2-BBDE-00C04F86AE3B" },
71         { "QoS Packet Scheduler",
72                 "426031c0-0b47-4852-b0ca-ac3d37bfcb39" },
73         { "Scripts",
74                 GP_EXT_GUID_SCRIPTS },
75         { "Security",
76                 GP_EXT_GUID_SECURITY },
77         { "Software Installation",
78                 "C6DC5466-785A-11D2-84D0-00C04FB169F7" },
79         { "Wireless Group Policy",
80                 "0ACDD40C-75AC-BAA0-BF6DE7E7FE63" },
81         { "Application Management",
82                 "C6DC5466-785A-11D2-84D0-00C04FB169F7" },
83         { "unknown",
84                 "3060E8D0-7020-11D2-842D-00C04FA372D4" },
85         { NULL, NULL }
86 };
87
88 /* guess work */
89 static struct gp_table gpo_cse_snapin_extensions[] = {
90         { "Administrative Templates",
91                 "0F6B957D-509E-11D1-A7CC-0000F87571E3" },
92         { "Certificates",
93                 "53D6AB1D-2488-11D1-A28C-00C04FB94F17" },
94         { "EFS recovery policy processing",
95                 "B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A" },
96         { "Folder Redirection policy processing",
97                 "25537BA6-77A8-11D2-9B6C-0000F8080861" },
98         { "Folder Redirection",
99                 "88E729D6-BDC1-11D1-BD2A-00C04FB9603F" },
100         { "Registry policy processing",
101                 "35378EAC-683F-11D2-A89A-00C04FBBCFA2" },
102         { "Remote Installation Services",
103                 "3060E8CE-7020-11D2-842D-00C04FA372D4" },
104         { "Security Settings",
105                 "803E14A0-B4FB-11D0-A0D0-00A0C90F574B" },
106         { "Security policy processing",
107                 "827D319E-6EAC-11D2-A4EA-00C04F79F83A" },
108         { "unknown",
109                 "3060E8D0-7020-11D2-842D-00C04FA372D4" },
110         { "unknown2",
111                 "53D6AB1B-2488-11D1-A28C-00C04FB94F17" },
112         { NULL, NULL }
113 };
114
115 /****************************************************************
116 ****************************************************************/
117
118 static const char *name_to_guid_string(const char *name,
119                                        struct gp_table *table)
120 {
121         int i;
122
123         for (i = 0; table[i].name; i++) {
124                 if (strequal(name, table[i].name)) {
125                         return table[i].guid_string;
126                 }
127         }
128
129         return NULL;
130 }
131
132 /****************************************************************
133 ****************************************************************/
134
135 static const char *guid_string_to_name(const char *guid_string,
136                                        struct gp_table *table)
137 {
138         int i;
139
140         for (i = 0; table[i].guid_string; i++) {
141                 if (strequal(guid_string, table[i].guid_string)) {
142                         return table[i].name;
143                 }
144         }
145
146         return NULL;
147 }
148
149 /****************************************************************
150 ****************************************************************/
151
152 static const char *snapin_guid_string_to_name(const char *guid_string,
153                                               struct gp_table *table)
154 {
155         int i;
156         for (i = 0; table[i].guid_string; i++) {
157                 if (strequal(guid_string, table[i].guid_string)) {
158                         return table[i].name;
159                 }
160         }
161         return NULL;
162 }
163
164 #if 0 /* unused */
165 static const char *default_gpo_name_to_guid_string(const char *name)
166 {
167         return name_to_guid_string(name, gpo_default_policy);
168 }
169
170 static const char *default_gpo_guid_string_to_name(const char *guid)
171 {
172         return guid_string_to_name(guid, gpo_default_policy);
173 }
174 #endif
175
176 /****************************************************************
177 ****************************************************************/
178
179 const char *cse_gpo_guid_string_to_name(const char *guid)
180 {
181         return guid_string_to_name(guid, gpo_cse_extensions);
182 }
183
184 /****************************************************************
185 ****************************************************************/
186
187 const char *cse_gpo_name_to_guid_string(const char *name)
188 {
189         return name_to_guid_string(name, gpo_cse_extensions);
190 }
191
192 /****************************************************************
193 ****************************************************************/
194
195 const char *cse_snapin_gpo_guid_string_to_name(const char *guid)
196 {
197         return snapin_guid_string_to_name(guid, gpo_cse_snapin_extensions);
198 }
199
200 /****************************************************************
201 ****************************************************************/
202
203 void dump_gp_ext(struct GP_EXT *gp_ext, int debuglevel)
204 {
205         int lvl = debuglevel;
206         int i;
207
208         if (gp_ext == NULL) {
209                 return;
210         }
211
212         DEBUG(lvl,("\t---------------------\n\n"));
213         DEBUGADD(lvl,("\tname:\t\t\t%s\n", gp_ext->gp_extension));
214
215         for (i=0; i< gp_ext->num_exts; i++) {
216
217                 DEBUGADD(lvl,("\textension:\t\t\t%s\n",
218                         gp_ext->extensions_guid[i]));
219                 DEBUGADD(lvl,("\textension (name):\t\t\t%s\n",
220                         gp_ext->extensions[i]));
221
222                 DEBUGADD(lvl,("\tsnapin:\t\t\t%s\n",
223                         gp_ext->snapins_guid[i]));
224                 DEBUGADD(lvl,("\tsnapin (name):\t\t\t%s\n",
225                         gp_ext->snapins[i]));
226         }
227 }
228
229 #ifdef HAVE_LDAP
230
231 /****************************************************************
232 ****************************************************************/
233
234 void dump_gpo(ADS_STRUCT *ads,
235               TALLOC_CTX *mem_ctx,
236               struct GROUP_POLICY_OBJECT *gpo,
237               int debuglevel)
238 {
239         int lvl = debuglevel;
240
241         if (gpo == NULL) {
242                 return;
243         }
244
245         DEBUG(lvl,("---------------------\n\n"));
246
247         DEBUGADD(lvl,("name:\t\t\t%s\n", gpo->name));
248         DEBUGADD(lvl,("displayname:\t\t%s\n", gpo->display_name));
249         DEBUGADD(lvl,("version:\t\t%d (0x%08x)\n", gpo->version, gpo->version));
250         DEBUGADD(lvl,("version_user:\t\t%d (0x%04x)\n",
251                 GPO_VERSION_USER(gpo->version),
252                 GPO_VERSION_USER(gpo->version)));
253         DEBUGADD(lvl,("version_machine:\t%d (0x%04x)\n",
254                 GPO_VERSION_MACHINE(gpo->version),
255                  GPO_VERSION_MACHINE(gpo->version)));
256         DEBUGADD(lvl,("filesyspath:\t\t%s\n", gpo->file_sys_path));
257         DEBUGADD(lvl,("dspath:\t\t%s\n", gpo->ds_path));
258
259         DEBUGADD(lvl,("options:\t\t%d ", gpo->options));
260         switch (gpo->options) {
261                 case GPFLAGS_ALL_ENABLED:
262                         DEBUGADD(lvl,("GPFLAGS_ALL_ENABLED\n"));
263                         break;
264                 case GPFLAGS_USER_SETTINGS_DISABLED:
265                         DEBUGADD(lvl,("GPFLAGS_USER_SETTINGS_DISABLED\n"));
266                         break;
267                 case GPFLAGS_MACHINE_SETTINGS_DISABLED:
268                         DEBUGADD(lvl,("GPFLAGS_MACHINE_SETTINGS_DISABLED\n"));
269                         break;
270                 case GPFLAGS_ALL_DISABLED:
271                         DEBUGADD(lvl,("GPFLAGS_ALL_DISABLED\n"));
272                         break;
273                 default:
274                         DEBUGADD(lvl,("unknown option: %d\n", gpo->options));
275                         break;
276         }
277
278         DEBUGADD(lvl,("link:\t\t\t%s\n", gpo->link));
279         DEBUGADD(lvl,("link_type:\t\t%d ", gpo->link_type));
280         switch (gpo->link_type) {
281                 case GP_LINK_UNKOWN:
282                         DEBUGADD(lvl,("GP_LINK_UNKOWN\n"));
283                         break;
284                 case GP_LINK_OU:
285                         DEBUGADD(lvl,("GP_LINK_OU\n"));
286                         break;
287                 case GP_LINK_DOMAIN:
288                         DEBUGADD(lvl,("GP_LINK_DOMAIN\n"));
289                         break;
290                 case GP_LINK_SITE:
291                         DEBUGADD(lvl,("GP_LINK_SITE\n"));
292                         break;
293                 case GP_LINK_MACHINE:
294                         DEBUGADD(lvl,("GP_LINK_MACHINE\n"));
295                         break;
296                 default:
297                         break;
298         }
299
300         DEBUGADD(lvl,("machine_extensions:\t%s\n", gpo->machine_extensions));
301
302         if (gpo->machine_extensions) {
303
304                 struct GP_EXT *gp_ext = NULL;
305
306                 if (!ads_parse_gp_ext(mem_ctx, gpo->machine_extensions,
307                                       &gp_ext)) {
308                         return;
309                 }
310                 dump_gp_ext(gp_ext, lvl);
311         }
312
313         DEBUGADD(lvl,("user_extensions:\t%s\n", gpo->user_extensions));
314
315         if (gpo->user_extensions) {
316
317                 struct GP_EXT *gp_ext = NULL;
318
319                 if (!ads_parse_gp_ext(mem_ctx, gpo->user_extensions,
320                                       &gp_ext)) {
321                         return;
322                 }
323                 dump_gp_ext(gp_ext, lvl);
324         }
325         if (gpo->security_descriptor) {
326                 DEBUGADD(lvl,("security descriptor:\n"));
327
328                 NDR_PRINT_DEBUG(security_descriptor, gpo->security_descriptor);
329         }
330 }
331
332 /****************************************************************
333 ****************************************************************/
334
335 void dump_gpo_list(ADS_STRUCT *ads,
336                    TALLOC_CTX *mem_ctx,
337                    struct GROUP_POLICY_OBJECT *gpo_list,
338                    int debuglevel)
339 {
340         struct GROUP_POLICY_OBJECT *gpo = NULL;
341
342         for (gpo = gpo_list; gpo; gpo = gpo->next) {
343                 dump_gpo(ads, mem_ctx, gpo, debuglevel);
344         }
345 }
346
347 /****************************************************************
348 ****************************************************************/
349
350 void dump_gplink(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, struct GP_LINK *gp_link)
351 {
352         ADS_STATUS status;
353         int i;
354         int lvl = 10;
355
356         if (gp_link == NULL) {
357                 return;
358         }
359
360         DEBUG(lvl,("---------------------\n\n"));
361
362         DEBUGADD(lvl,("gplink: %s\n", gp_link->gp_link));
363         DEBUGADD(lvl,("gpopts: %d ", gp_link->gp_opts));
364         switch (gp_link->gp_opts) {
365                 case GPOPTIONS_INHERIT:
366                         DEBUGADD(lvl,("GPOPTIONS_INHERIT\n"));
367                         break;
368                 case GPOPTIONS_BLOCK_INHERITANCE:
369                         DEBUGADD(lvl,("GPOPTIONS_BLOCK_INHERITANCE\n"));
370                         break;
371                 default:
372                         break;
373         }
374
375         DEBUGADD(lvl,("num links: %d\n", gp_link->num_links));
376
377         for (i = 0; i < gp_link->num_links; i++) {
378
379                 DEBUGADD(lvl,("---------------------\n\n"));
380
381                 DEBUGADD(lvl,("link: #%d\n", i + 1));
382                 DEBUGADD(lvl,("name: %s\n", gp_link->link_names[i]));
383
384                 DEBUGADD(lvl,("opt: %d ", gp_link->link_opts[i]));
385                 if (gp_link->link_opts[i] & GPO_LINK_OPT_ENFORCED) {
386                         DEBUGADD(lvl,("GPO_LINK_OPT_ENFORCED "));
387                 }
388                 if (gp_link->link_opts[i] & GPO_LINK_OPT_DISABLED) {
389                         DEBUGADD(lvl,("GPO_LINK_OPT_DISABLED"));
390                 }
391                 DEBUGADD(lvl,("\n"));
392
393                 if (ads != NULL && mem_ctx != NULL) {
394
395                         struct GROUP_POLICY_OBJECT gpo;
396
397                         status = ads_get_gpo(ads, mem_ctx,
398                                              gp_link->link_names[i],
399                                              NULL, NULL, &gpo);
400                         if (!ADS_ERR_OK(status)) {
401                                 DEBUG(lvl,("get gpo for %s failed: %s\n",
402                                         gp_link->link_names[i],
403                                         ads_errstr(status)));
404                                 return;
405                         }
406                         dump_gpo(ads, mem_ctx, &gpo, lvl);
407                 }
408         }
409 }
410
411 #endif /* HAVE_LDAP */
412
413 /****************************************************************
414 ****************************************************************/
415
416 static bool gpo_get_gp_ext_from_gpo(TALLOC_CTX *mem_ctx,
417                                     uint32_t flags,
418                                     struct GROUP_POLICY_OBJECT *gpo,
419                                     struct GP_EXT **gp_ext)
420 {
421         ZERO_STRUCTP(*gp_ext);
422
423         if (flags & GPO_INFO_FLAG_MACHINE) {
424
425                 if (gpo->machine_extensions) {
426
427                         if (!ads_parse_gp_ext(mem_ctx, gpo->machine_extensions,
428                                               gp_ext)) {
429                                 return false;
430                         }
431                 }
432         } else {
433
434                 if (gpo->user_extensions) {
435
436                         if (!ads_parse_gp_ext(mem_ctx, gpo->user_extensions,
437                                               gp_ext)) {
438                                 return false;
439                         }
440                 }
441         }
442
443         return true;
444 }
445
446 /****************************************************************
447 ****************************************************************/
448
449 ADS_STATUS gpo_process_a_gpo(ADS_STRUCT *ads,
450                              TALLOC_CTX *mem_ctx,
451                              const NT_USER_TOKEN *token,
452                              struct registry_key *root_key,
453                              struct GROUP_POLICY_OBJECT *gpo,
454                              const char *extension_guid_filter,
455                              uint32_t flags)
456 {
457         struct GP_EXT *gp_ext = NULL;
458         int i;
459
460         DEBUG(10,("gpo_process_a_gpo: processing gpo %s (%s)\n",
461                 gpo->name, gpo->display_name));
462         if (extension_guid_filter) {
463                 DEBUGADD(10,("gpo_process_a_gpo: using filter %s (%s)\n",
464                         extension_guid_filter,
465                         cse_gpo_guid_string_to_name(extension_guid_filter)));
466         }
467
468         if (!gpo_get_gp_ext_from_gpo(mem_ctx, flags, gpo, &gp_ext)) {
469                 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
470         }
471
472         if (!gp_ext || !gp_ext->num_exts) {
473                 if (flags & GPO_INFO_FLAG_VERBOSE) {
474                         DEBUG(0,("gpo_process_a_gpo: "
475                                 "no policies in %s (%s) for this extension\n",
476                                 gpo->name, gpo->display_name));
477                 }
478                 return ADS_SUCCESS;
479         }
480
481         for (i=0; i<gp_ext->num_exts; i++) {
482
483                 NTSTATUS ntstatus;
484
485                 if (extension_guid_filter &&
486                     !strequal(extension_guid_filter,
487                               gp_ext->extensions_guid[i])) {
488                         continue;
489                 }
490
491                 ntstatus = gpext_process_extension(ads, mem_ctx,
492                                                    flags, token, root_key, gpo,
493                                                    gp_ext->extensions_guid[i],
494                                                    gp_ext->snapins_guid[i]);
495                 if (!NT_STATUS_IS_OK(ntstatus)) {
496                         ADS_ERROR_NT(ntstatus);
497                 }
498         }
499
500         return ADS_SUCCESS;
501 }
502
503 /****************************************************************
504 ****************************************************************/
505
506 static ADS_STATUS gpo_process_gpo_list_by_ext(ADS_STRUCT *ads,
507                                               TALLOC_CTX *mem_ctx,
508                                               const NT_USER_TOKEN *token,
509                                               struct registry_key *root_key,
510                                               struct GROUP_POLICY_OBJECT *gpo_list,
511                                               const char *extensions_guid,
512                                               uint32_t flags)
513 {
514         ADS_STATUS status;
515         struct GROUP_POLICY_OBJECT *gpo;
516
517         for (gpo = gpo_list; gpo; gpo = gpo->next) {
518
519                 if (gpo->link_type == GP_LINK_LOCAL) {
520                         continue;
521                 }
522
523
524                 /* FIXME: we need to pass down the *list* down to the
525                  * extension, otherwise we cannot store the e.g. the *list* of
526                  * logon-scripts correctly (for more then one GPO) */
527
528                 status = gpo_process_a_gpo(ads, mem_ctx, token, root_key,
529                                            gpo, extensions_guid, flags);
530
531                 if (!ADS_ERR_OK(status)) {
532                         DEBUG(0,("failed to process gpo by ext: %s\n",
533                                 ads_errstr(status)));
534                         return status;
535                 }
536         }
537
538         return ADS_SUCCESS;
539 }
540
541 /****************************************************************
542 ****************************************************************/
543
544 ADS_STATUS gpo_process_gpo_list(ADS_STRUCT *ads,
545                                 TALLOC_CTX *mem_ctx,
546                                 const NT_USER_TOKEN *token,
547                                 struct GROUP_POLICY_OBJECT *gpo_list,
548                                 const char *extensions_guid_filter,
549                                 uint32_t flags)
550 {
551         ADS_STATUS status = ADS_SUCCESS;
552         struct gp_extension *gp_ext_list = NULL;
553         struct gp_extension *gp_ext = NULL;
554         struct registry_key *root_key = NULL;
555         struct gp_registry_context *reg_ctx = NULL;
556 #if 0
557         WERROR werr;
558 #endif
559         status = ADS_ERROR_NT(init_gp_extensions(mem_ctx));
560         if (!ADS_ERR_OK(status)) {
561                 return status;
562         }
563
564         gp_ext_list = get_gp_extension_list();
565         if (!gp_ext_list) {
566                 return ADS_ERROR_NT(NT_STATUS_DLL_INIT_FAILED);
567         }
568 /* FIXME Needs to be replaced with new patchfile_preg calls */
569 #if 0
570         /* get the key here */
571         if (flags & GPO_LIST_FLAG_MACHINE) {
572                 werr = gp_init_reg_ctx(mem_ctx, KEY_HKLM, REG_KEY_WRITE,
573                                        get_system_token(),
574                                        &reg_ctx);
575         } else {
576                 werr = gp_init_reg_ctx(mem_ctx, KEY_HKCU, REG_KEY_WRITE,
577                                        token,
578                                        &reg_ctx);
579         }
580         if (!W_ERROR_IS_OK(werr)) {
581                 talloc_free(reg_ctx);
582                 return ADS_ERROR_NT(werror_to_ntstatus(werr));
583         }
584 #endif
585
586         root_key = reg_ctx->curr_key;
587
588         for (gp_ext = gp_ext_list; gp_ext; gp_ext = gp_ext->next) {
589
590                 const char *guid_str = NULL;
591
592                 guid_str = GUID_string(mem_ctx, gp_ext->guid);
593                 if (!guid_str) {
594                         status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
595                         goto done;
596                 }
597
598                 if (extensions_guid_filter &&
599                     (!strequal(guid_str, extensions_guid_filter)))  {
600                         continue;
601                 }
602
603                 DEBUG(0,("-------------------------------------------------\n"));
604                 DEBUG(0,("gpo_process_gpo_list: processing ext: %s {%s}\n",
605                         gp_ext->name, guid_str));
606
607
608                 status = gpo_process_gpo_list_by_ext(ads, mem_ctx, token,
609                                                      root_key, gpo_list,
610                                                      guid_str, flags);
611                 if (!ADS_ERR_OK(status)) {
612                         goto done;
613                 }
614         }
615
616  done:
617         talloc_free(reg_ctx);
618         talloc_free(root_key);
619         free_gp_extensions();
620
621         return status;
622 }
623
624
625 /****************************************************************
626  check wether the version number in a GROUP_POLICY_OBJECT match those of the
627  locally stored version. If not, fetch the required policy via CIFS
628 ****************************************************************/
629
630 NTSTATUS check_refresh_gpo(ADS_STRUCT *ads,
631                            TALLOC_CTX *mem_ctx,
632                            const char *cache_dir,
633                            struct loadparm_context *lp_ctx,
634                            uint32_t flags,
635                            struct GROUP_POLICY_OBJECT *gpo)
636 {
637         NTSTATUS result;
638         char *server = NULL;
639         char *share = NULL;
640         char *nt_path = NULL;
641         char *unix_path = NULL;
642         uint32_t sysvol_gpt_version = 0;
643         char *display_name = NULL;
644
645         result = gpo_explode_filesyspath(mem_ctx, cache_dir, gpo->file_sys_path,
646                                          &server, &share, &nt_path, &unix_path);
647
648         if (!NT_STATUS_IS_OK(result)) {
649                 goto out;
650         }
651
652         result = gpo_get_sysvol_gpt_version(mem_ctx,
653                                             unix_path,
654                                             &sysvol_gpt_version,
655                                             &display_name);
656         if (!NT_STATUS_IS_OK(result) &&
657             !NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_FILE)) {
658                 DEBUG(10,("check_refresh_gpo: "
659                         "failed to get local gpt version: %s\n",
660                         nt_errstr(result)));
661                 goto out;
662         }
663
664         DEBUG(10,("check_refresh_gpo: versions gpo %d sysvol %d\n",
665                 gpo->version, sysvol_gpt_version));
666
667         /* FIXME: handle GPO_INFO_FLAG_FORCED_REFRESH from flags */
668
669         while (gpo->version > sysvol_gpt_version) {
670
671                 DEBUG(1,("check_refresh_gpo: need to refresh GPO\n"));
672
673                 result = gpo_fetch_files(mem_ctx, ads, lp_ctx, cache_dir, gpo);
674                 if (!NT_STATUS_IS_OK(result)) {
675                         goto out;
676                 }
677
678                 result = gpo_get_sysvol_gpt_version(mem_ctx,
679                                                     unix_path,
680                                                     &sysvol_gpt_version,
681                                                     &display_name);
682                 if (!NT_STATUS_IS_OK(result)) {
683                         DEBUG(10,("check_refresh_gpo: "
684                                 "failed to get local gpt version: %s\n",
685                                 nt_errstr(result)));
686                         goto out;
687                 }
688
689                 if (gpo->version == sysvol_gpt_version) {
690                         break;
691                 }
692         }
693
694         DEBUG(10,("Name:\t\t\t%s (%s)\n", gpo->display_name, gpo->name));
695         DEBUGADD(10,("sysvol GPT version:\t%d (user: %d, machine: %d)\n",
696                 sysvol_gpt_version,
697                 GPO_VERSION_USER(sysvol_gpt_version),
698                 GPO_VERSION_MACHINE(sysvol_gpt_version)));
699         DEBUGADD(10,("LDAP GPO version:\t%d (user: %d, machine: %d)\n",
700                 gpo->version,
701                 GPO_VERSION_USER(gpo->version),
702                 GPO_VERSION_MACHINE(gpo->version)));
703         DEBUGADD(10,("LDAP GPO link:\t\t%s\n", gpo->link));
704
705         result = NT_STATUS_OK;
706
707  out:
708         return result;
709
710 }
711
712 /****************************************************************
713  check wether the version numbers in the gpo_list match the locally stored, if
714  not, go and get each required GPO via CIFS
715  ****************************************************************/
716
717 NTSTATUS check_refresh_gpo_list(ADS_STRUCT *ads,
718                                 TALLOC_CTX *mem_ctx,
719                                 const char *cache_dir,
720                                 struct loadparm_context *lp_ctx,
721                                 uint32_t flags,
722                                 struct GROUP_POLICY_OBJECT *gpo_list)
723 {
724         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
725         struct GROUP_POLICY_OBJECT *gpo;
726
727         if (!gpo_list) {
728                 return NT_STATUS_INVALID_PARAMETER;
729         }
730
731         for (gpo = gpo_list; gpo; gpo = gpo->next) {
732
733                 result = check_refresh_gpo(ads, mem_ctx, cache_dir, lp_ctx, flags, gpo);
734                 if (!NT_STATUS_IS_OK(result)) {
735                         goto out;
736                 }
737         }
738
739         result = NT_STATUS_OK;
740
741  out:
742         /* FIXME close cli connection */
743
744         return result;
745 }
746
747 /****************************************************************
748 ****************************************************************/
749
750 NTSTATUS gpo_get_unix_path(TALLOC_CTX *mem_ctx,
751                            const char *cache_dir,
752                            struct GROUP_POLICY_OBJECT *gpo,
753                            char **unix_path)
754 {
755         char *server, *share, *nt_path;
756         return gpo_explode_filesyspath(mem_ctx, cache_dir, gpo->file_sys_path,
757                                        &server, &share, &nt_path, unix_path);
758 }
759
760 /****************************************************************
761 ****************************************************************/
762
763 char *gpo_flag_str(TALLOC_CTX *ctx, uint32_t flags)
764 {
765         char *str = NULL;
766
767         if (flags == 0) {
768                 return NULL;
769         }
770
771         if (flags & GPO_INFO_FLAG_SLOWLINK)
772                 str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_SLOWLINK ");
773         if (flags & GPO_INFO_FLAG_VERBOSE)
774                 str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_VERBOSE ");
775         if (flags & GPO_INFO_FLAG_SAFEMODE_BOOT)
776                 str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_SAFEMODE_BOOT ");
777         if (flags & GPO_INFO_FLAG_NOCHANGES)
778                 str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_NOCHANGES ");
779         if (flags & GPO_INFO_FLAG_MACHINE)
780                 str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_MACHINE ");
781         if (flags & GPO_INFO_FLAG_LOGRSOP_TRANSITION)
782                 str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_LOGRSOP_TRANSITION ");
783         if (flags & GPO_INFO_FLAG_LINKTRANSITION)
784                 str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_LINKTRANSITION ");
785         if (flags & GPO_INFO_FLAG_FORCED_REFRESH)
786                 str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_FORCED_REFRESH ");
787         if (flags & GPO_INFO_FLAG_BACKGROUND)
788                 str = talloc_append_string(ctx, str, "GPO_INFO_FLAG_BACKGROUND ");
789
790         return str;
791 }
792
793 /****************************************************************
794 ****************************************************************/
795
796 NTSTATUS gp_find_file(TALLOC_CTX *mem_ctx,
797                       uint32_t flags,
798                       const char *filename,
799                       const char *suffix,
800                       const char **filename_out)
801 {
802         const char *tmp = NULL;
803         struct stat sbuf;
804         const char *path = NULL;
805
806         if (flags & GPO_LIST_FLAG_MACHINE) {
807                 path = "Machine";
808         } else {
809                 path = "User";
810         }
811
812         tmp = talloc_asprintf(mem_ctx, "%s/%s/%s", filename,
813                               path, suffix);
814         NT_STATUS_HAVE_NO_MEMORY(tmp);
815
816         if (stat(tmp, &sbuf) == 0) {
817                 *filename_out = tmp;
818                 return NT_STATUS_OK;
819         }
820
821         path = talloc_strdup_upper(mem_ctx, path);
822         NT_STATUS_HAVE_NO_MEMORY(path);
823
824         tmp = talloc_asprintf(mem_ctx, "%s/%s/%s", filename,
825                               path, suffix);
826         NT_STATUS_HAVE_NO_MEMORY(tmp);
827
828         if (stat(tmp, &sbuf) == 0) {
829                 *filename_out = tmp;
830                 return NT_STATUS_OK;
831         }
832
833         return NT_STATUS_NO_SUCH_FILE;
834 }
835
836 /****************************************************************
837 ****************************************************************/
838
839 ADS_STATUS gp_get_machine_token(ADS_STRUCT *ads,
840                                 TALLOC_CTX *mem_ctx,
841                                 struct loadparm_context *lp_ctx,
842                                 const char *dn,
843                                 NT_USER_TOKEN **token)
844 {
845         NT_USER_TOKEN *ad_token = NULL;
846         ADS_STATUS status;
847 #if _SAMBA_BUILD_ == 4
848         struct auth_session_info *info;
849 #else
850         NTSTATUS ntstatus;
851 #endif
852
853 #ifndef HAVE_ADS
854         return ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED);
855 #endif
856         status = ads_get_sid_token(ads, mem_ctx, dn, &ad_token);
857         if (!ADS_ERR_OK(status)) {
858                 return status;
859         }
860 #if _SAMBA_BUILD_ == 4
861         info = system_session(mem_ctx, lp_ctx);
862         *token = info->security_token;
863 #else
864         ntstatus = merge_nt_token(mem_ctx, ad_token, get_system_token(),
865                                   token);
866         if (!NT_STATUS_IS_OK(ntstatus)) {
867                 return ADS_ERROR_NT(ntstatus);
868         }
869 #endif
870         return ADS_SUCCESS;
871 }