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