r23801: The FSF has moved around a lot. This fixes their Mass Ave address.
[sfrench/samba-autobuild/.git] / source / libgpo / gpo_util.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  Group Policy Object Support
4  *  Copyright (C) Guenther Deschner 2005-2006
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 #ifdef HAVE_LDAP
23
24 #define DEFAULT_DOMAIN_POLICY "Default Domain Policy"
25 #define DEFAULT_DOMAIN_CONTROLLERS_POLICY "Default Domain Controllers Policy"
26
27 /* should we store a parsed guid ? */
28 struct gpo_table {
29         const char *name;
30         const char *guid_string;
31 };
32
33 struct snapin_table {
34         const char *name;
35         const char *guid_string;
36         ADS_STATUS (*snapin_fn)(ADS_STRUCT *, TALLOC_CTX *mem_ctx, const char *, const char *);
37 };
38
39 #if 0 /* unused */
40 static struct gpo_table gpo_default_policy[] = {
41         { DEFAULT_DOMAIN_POLICY, 
42                 "31B2F340-016D-11D2-945F-00C04FB984F9" },
43         { DEFAULT_DOMAIN_CONTROLLERS_POLICY, 
44                 "6AC1786C-016F-11D2-945F-00C04fB984F9" },
45         { NULL, NULL }
46 };
47 #endif
48
49 /* the following is seen in gPCMachineExtensionNames or gPCUserExtensionNames */
50
51 static struct gpo_table gpo_cse_extensions[] = {
52         { "Administrative Templates Extension", 
53                 "35378EAC-683F-11D2-A89A-00C04FBBCFA2" }, /* Registry Policy ? */
54         { "Microsoft Disc Quota", 
55                 "3610EDA5-77EF-11D2-8DC5-00C04FA31A66" },
56         { "EFS recovery", 
57                 "B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A" },
58         { "Folder Redirection", 
59                 "25537BA6-77A8-11D2-9B6C-0000F8080861" },
60         { "IP Security", 
61                 "E437BC1C-AA7D-11D2-A382-00C04F991E27" },
62         { "Internet Explorer Branding", 
63                 "A2E30F80-D7DE-11d2-BBDE-00C04F86AE3B" },
64         { "QoS Packet Scheduler", 
65                 "426031c0-0b47-4852-b0ca-ac3d37bfcb39" },
66         { "Scripts", 
67                 "42B5FAAE-6536-11D2-AE5A-0000F87571E3" },
68         { "Security", 
69                 "827D319E-6EAC-11D2-A4EA-00C04F79F83A" },
70         { "Software Installation", 
71                 "C6DC5466-785A-11D2-84D0-00C04FB169F7" },
72         { "Wireless Group Policy", 
73                 "0ACDD40C-75AC-BAA0-BF6DE7E7FE63" },
74         { NULL, NULL }
75 };
76
77 /* guess work */
78 static struct snapin_table gpo_cse_snapin_extensions[] = {
79         { "Administrative Templates", 
80                 "0F6B957D-509E-11D1-A7CC-0000F87571E3", gpo_snapin_handler_none },
81         { "Certificates", 
82                 "53D6AB1D-2488-11D1-A28C-00C04FB94F17", gpo_snapin_handler_none },
83         { "EFS recovery policy processing", 
84                 "B1BE8D72-6EAC-11D2-A4EA-00C04F79F83A", gpo_snapin_handler_none },
85         { "Folder Redirection policy processing", 
86                 "25537BA6-77A8-11D2-9B6C-0000F8080861", gpo_snapin_handler_none },
87         { "Folder Redirection", 
88                 "88E729D6-BDC1-11D1-BD2A-00C04FB9603F", gpo_snapin_handler_none },
89         { "Registry policy processing", 
90                 "35378EAC-683F-11D2-A89A-00C04FBBCFA2", gpo_snapin_handler_none },
91         { "Remote Installation Services", 
92                 "3060E8CE-7020-11D2-842D-00C04FA372D4", gpo_snapin_handler_none },
93         { "Security Settings", 
94                 "803E14A0-B4FB-11D0-A0D0-00A0C90F574B", gpo_snapin_handler_security_settings },
95         { "Security policy processing", 
96                 "827D319E-6EAC-11D2-A4EA-00C04F79F83A", gpo_snapin_handler_security_settings },
97         { "unknown", 
98                 "3060E8D0-7020-11D2-842D-00C04FA372D4", gpo_snapin_handler_none },
99         { "unknown2", 
100                 "53D6AB1B-2488-11D1-A28C-00C04FB94F17", gpo_snapin_handler_none },
101         { NULL, NULL, NULL }
102 };
103
104 static const char *name_to_guid_string(const char *name, struct gpo_table *table)
105 {
106         int i;
107
108         for (i = 0; table[i].name; i++) {
109                 if (strequal(name, table[i].name)) {
110                         return table[i].guid_string;
111                 }
112         }
113         
114         return NULL;
115 }
116
117 static const char *guid_string_to_name(const char *guid_string, struct gpo_table *table)
118 {
119         int i;
120
121         for (i = 0; table[i].guid_string; i++) {
122                 if (strequal(guid_string, table[i].guid_string)) {
123                         return table[i].name;
124                 }
125         }
126         
127         return NULL;
128 }
129
130 static const char *snapin_guid_string_to_name(const char *guid_string, 
131                                               struct snapin_table *table)
132 {
133         int i;
134         for (i = 0; table[i].guid_string; i++) {
135                 if (strequal(guid_string, table[i].guid_string)) {
136                         return table[i].name;
137                 }
138         }
139         return NULL;
140 }
141
142 #if 0 /* unused */
143 static const char *default_gpo_name_to_guid_string(const char *name)
144 {
145         return name_to_guid_string(name, gpo_default_policy);
146 }
147
148 static const char *default_gpo_guid_string_to_name(const char *guid)
149 {
150         return guid_string_to_name(guid, gpo_default_policy);
151 }
152 #endif
153
154 const char *cse_gpo_guid_string_to_name(const char *guid)
155 {
156         return guid_string_to_name(guid, gpo_cse_extensions);
157 }
158
159 static const char *cse_gpo_name_to_guid_string(const char *name)
160 {
161         return name_to_guid_string(name, gpo_cse_extensions);
162 }
163
164 const char *cse_snapin_gpo_guid_string_to_name(const char *guid)
165 {
166         return snapin_guid_string_to_name(guid, gpo_cse_snapin_extensions);
167 }
168
169 void dump_gp_ext(struct GP_EXT *gp_ext, int debuglevel)
170 {
171         int lvl = debuglevel;
172         int i;
173
174         if (gp_ext == NULL) {
175                 return;
176         }
177
178         DEBUG(lvl,("\t---------------------\n\n"));
179         DEBUGADD(lvl,("\tname:\t\t\t%s\n", gp_ext->gp_extension));
180
181         for (i=0; i< gp_ext->num_exts; i++) {
182
183                 DEBUGADD(lvl,("\textension:\t\t\t%s\n", gp_ext->extensions_guid[i]));
184                 DEBUGADD(lvl,("\textension (name):\t\t\t%s\n", gp_ext->extensions[i]));
185                 
186                 DEBUGADD(lvl,("\tsnapin:\t\t\t%s\n", gp_ext->snapins_guid[i]));
187                 DEBUGADD(lvl,("\tsnapin (name):\t\t\t%s\n", gp_ext->snapins[i]));
188         }
189 }
190
191 void dump_gpo(TALLOC_CTX *mem_ctx, struct GROUP_POLICY_OBJECT *gpo, int debuglevel) 
192 {
193         int lvl = debuglevel;
194
195         if (gpo == NULL) {
196                 return;
197         }
198
199         DEBUG(lvl,("---------------------\n\n"));
200
201         DEBUGADD(lvl,("name:\t\t\t%s\n", gpo->name));
202         DEBUGADD(lvl,("displayname:\t\t%s\n", gpo->display_name));
203         DEBUGADD(lvl,("version:\t\t%d (0x%08x)\n", gpo->version, gpo->version));
204         DEBUGADD(lvl,("version_user:\t\t%d (0x%04x)\n", GPO_VERSION_USER(gpo->version), 
205                                                         GPO_VERSION_USER(gpo->version)));
206         DEBUGADD(lvl,("version_machine:\t%d (0x%04x)\n", GPO_VERSION_MACHINE(gpo->version), 
207                                                          GPO_VERSION_MACHINE(gpo->version)));
208         DEBUGADD(lvl,("filesyspath:\t\t%s\n", gpo->file_sys_path));
209         DEBUGADD(lvl,("dspath:\t\t%s\n", gpo->ds_path));
210
211         DEBUGADD(lvl,("options:\t\t%d ", gpo->options));
212         if (gpo->options & GPFLAGS_USER_SETTINGS_DISABLED) {
213                 DEBUGADD(lvl,("GPFLAGS_USER_SETTINGS_DISABLED ")); 
214         }
215         if (gpo->options & GPFLAGS_MACHINE_SETTINGS_DISABLED) {
216                 DEBUGADD(lvl,("GPFLAGS_MACHINE_SETTINGS_DISABLED")); 
217         }
218         DEBUGADD(lvl,("\n"));
219
220         DEBUGADD(lvl,("link:\t\t\t%s\n", gpo->link));
221         DEBUGADD(lvl,("link_type:\t\t%d ", gpo->link_type));
222         switch (gpo->link_type) {
223                 case GP_LINK_UNKOWN:
224                         DEBUGADD(lvl,("GP_LINK_UNKOWN\n"));
225                         break;
226                 case GP_LINK_OU:
227                         DEBUGADD(lvl,("GP_LINK_OU\n"));
228                         break;
229                 case GP_LINK_DOMAIN:
230                         DEBUGADD(lvl,("GP_LINK_DOMAIN\n"));
231                         break;
232                 case GP_LINK_SITE:
233                         DEBUGADD(lvl,("GP_LINK_SITE\n"));
234                         break;
235                 case GP_LINK_MACHINE:
236                         DEBUGADD(lvl,("GP_LINK_MACHINE\n"));
237                         break;
238                 default:
239                         break;
240         }
241
242         DEBUGADD(lvl,("machine_extensions:\t%s\n", gpo->machine_extensions));
243
244         if (gpo->machine_extensions) {
245
246                 struct GP_EXT *gp_ext = NULL;
247                 ADS_STATUS status;
248
249                 status = ads_parse_gp_ext(mem_ctx, gpo->machine_extensions, &gp_ext);
250                 if (!ADS_ERR_OK(status)) {
251                         return;
252                 }
253                 dump_gp_ext(gp_ext, lvl);
254         }
255         
256         DEBUGADD(lvl,("user_extensions:\t%s\n", gpo->user_extensions));
257
258         if (gpo->user_extensions) {
259         
260                 struct GP_EXT *gp_ext = NULL;
261                 ADS_STATUS status;
262                 
263                 status = ads_parse_gp_ext(mem_ctx, gpo->user_extensions, &gp_ext);
264                 if (!ADS_ERR_OK(status)) {
265                         return;
266                 }
267                 dump_gp_ext(gp_ext, lvl);
268         }
269 }
270
271 /****************************************************************
272 ****************************************************************/
273
274 void dump_gpo_list(TALLOC_CTX *mem_ctx, 
275                    struct GROUP_POLICY_OBJECT *gpo_list, 
276                    int debuglevel)
277 {
278         struct GROUP_POLICY_OBJECT *gpo = NULL;
279
280         for (gpo = gpo_list; gpo; gpo = gpo->next) {
281                 dump_gpo(mem_ctx, gpo, debuglevel);
282         }
283 }
284
285 /****************************************************************
286 ****************************************************************/
287
288 void dump_gplink(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, struct GP_LINK *gp_link)
289 {
290         ADS_STATUS status;
291         int i;
292         int lvl = 10;
293
294         if (gp_link == NULL) {
295                 return;
296         }
297
298         DEBUG(lvl,("---------------------\n\n"));
299
300         DEBUGADD(lvl,("gplink: %s\n", gp_link->gp_link));
301         DEBUGADD(lvl,("gpopts: %d ", gp_link->gp_opts));
302         switch (gp_link->gp_opts) {
303                 case GPOPTIONS_INHERIT:
304                         DEBUGADD(lvl,("GPOPTIONS_INHERIT\n"));
305                         break;
306                 case GPOPTIONS_BLOCK_INHERITANCE:
307                         DEBUGADD(lvl,("GPOPTIONS_BLOCK_INHERITANCE\n"));
308                         break;
309                 default:
310                         break;
311         }
312
313         DEBUGADD(lvl,("num links: %d\n", gp_link->num_links));
314
315         for (i = 0; i < gp_link->num_links; i++) {
316         
317                 DEBUGADD(lvl,("---------------------\n\n"));
318         
319                 DEBUGADD(lvl,("link: #%d\n", i + 1));
320                 DEBUGADD(lvl,("name: %s\n", gp_link->link_names[i]));
321
322                 DEBUGADD(lvl,("opt: %d ", gp_link->link_opts[i]));
323                 if (gp_link->link_opts[i] & GPO_LINK_OPT_ENFORCED) {
324                         DEBUGADD(lvl,("GPO_LINK_OPT_ENFORCED "));
325                 }
326                 if (gp_link->link_opts[i] & GPO_LINK_OPT_DISABLED) {
327                         DEBUGADD(lvl,("GPO_LINK_OPT_DISABLED"));
328                 }
329                 DEBUGADD(lvl,("\n"));
330
331                 if (ads != NULL && mem_ctx != NULL) {
332
333                         struct GROUP_POLICY_OBJECT gpo;
334
335                         status = ads_get_gpo(ads, mem_ctx, gp_link->link_names[i], NULL, NULL, &gpo);
336                         if (!ADS_ERR_OK(status)) {
337                                 DEBUG(lvl,("get gpo for %s failed: %s\n", gp_link->link_names[i], ads_errstr(status)));
338                                 return;
339                         }
340                         dump_gpo(mem_ctx, &gpo, lvl);
341                 }
342         }
343 }
344
345 /****************************************************************
346 ****************************************************************/
347
348 ADS_STATUS process_extension_with_snapin(ADS_STRUCT *ads,
349                                          TALLOC_CTX *mem_ctx,
350                                          const char *extension_guid,
351                                          const char *snapin_guid)
352 {
353         int i;
354
355         for (i=0; gpo_cse_snapin_extensions[i].guid_string; i++) {
356         
357                 if (strcmp(gpo_cse_snapin_extensions[i].guid_string, snapin_guid) == 0) {
358                 
359                         return gpo_cse_snapin_extensions[i].snapin_fn(ads, mem_ctx, 
360                                                                       extension_guid, snapin_guid);
361                 }
362         }
363
364         DEBUG(10,("process_extension_with_snapin: no snapin handler for extension %s (%s) found\n", 
365                 extension_guid, snapin_guid));
366
367         return ADS_SUCCESS;
368 }
369
370 /****************************************************************
371 ****************************************************************/
372
373 ADS_STATUS gpo_process_a_gpo(ADS_STRUCT *ads,
374                              TALLOC_CTX *mem_ctx,
375                              struct GROUP_POLICY_OBJECT *gpo,
376                              const char *extension_guid_filter,
377                              uint32 flags)
378 {
379         ADS_STATUS status;
380         struct GP_EXT *gp_ext = NULL;
381         int i;
382         
383         if (flags & GPO_LIST_FLAG_MACHINE) {
384
385                 if (gpo->machine_extensions) {
386
387                         status = ads_parse_gp_ext(mem_ctx, gpo->machine_extensions, &gp_ext);
388
389                         if (!ADS_ERR_OK(status)) {
390                                 return status;
391                         }
392
393                 } else {
394                         /* nothing to apply */
395                         return ADS_SUCCESS;
396                 }
397         
398         } else {
399
400                 if (gpo->user_extensions) {
401                 
402                         status = ads_parse_gp_ext(mem_ctx, gpo->user_extensions, &gp_ext);
403
404                         if (!ADS_ERR_OK(status)) {
405                                 return status;
406                         }
407                 } else {
408                         /* nothing to apply */
409                         return ADS_SUCCESS;
410                 }
411         }
412
413         for (i=0; i<gp_ext->num_exts; i++) {
414
415                 if (extension_guid_filter && !strequal(extension_guid_filter, gp_ext->extensions_guid[i])) {
416                         continue;
417                 }
418
419                 status = process_extension_with_snapin(ads, mem_ctx,
420                                                        gp_ext->extensions_guid[i], 
421                                                        gp_ext->snapins_guid[i]);
422                 if (!ADS_ERR_OK(status)) {
423                         return status;
424                 }
425         }
426
427         return ADS_SUCCESS;
428 }
429
430 /****************************************************************
431 ****************************************************************/
432
433 ADS_STATUS gpo_process_gpo_list(ADS_STRUCT *ads,
434                                 TALLOC_CTX *mem_ctx,
435                                 struct GROUP_POLICY_OBJECT *gpo_list,
436                                 const char *extensions_guid,
437                                 uint32 flags)
438 {
439         ADS_STATUS status;
440         struct GROUP_POLICY_OBJECT *gpo;
441
442         for (gpo = gpo_list; gpo; gpo = gpo->next) {
443         
444                 status = gpo_process_a_gpo(ads, mem_ctx, gpo, 
445                                            extensions_guid, flags);
446         
447                 if (!ADS_ERR_OK(status)) {
448                         return status;
449                 }
450
451         }
452
453         return ADS_SUCCESS;
454 }
455
456 ADS_STATUS gpo_snapin_handler_none(ADS_STRUCT *ads, 
457                                    TALLOC_CTX *mem_ctx, 
458                                    const char *extension_guid, 
459                                    const char *snapin_guid)
460 {
461         DEBUG(10,("gpo_snapin_handler_none\n"));
462
463         return ADS_SUCCESS;
464 }
465
466 ADS_STATUS gpo_snapin_handler_security_settings(ADS_STRUCT *ads, 
467                                                 TALLOC_CTX *mem_ctx, 
468                                                 const char *extension_guid, 
469                                                 const char *snapin_guid)
470 {
471         DEBUG(10,("gpo_snapin_handler_security_settings\n"));
472
473         return ADS_SUCCESS;
474 }
475
476 ADS_STATUS gpo_lockout_policy(ADS_STRUCT *ads,
477                               TALLOC_CTX *mem_ctx,
478                               const char *hostname,
479                               SAM_UNK_INFO_12 *lockout_policy)
480 {
481         return ADS_ERROR_NT(NT_STATUS_NOT_IMPLEMENTED);
482 }
483
484 /****************************************************************
485 ****************************************************************/
486
487 ADS_STATUS gpo_password_policy(ADS_STRUCT *ads,
488                                TALLOC_CTX *mem_ctx,
489                                const char *hostname,
490                                SAM_UNK_INFO_1 *password_policy)
491 {
492         ADS_STATUS status;
493         struct GROUP_POLICY_OBJECT *gpo_list;
494         const char *attrs[] = {"distinguishedName", "userAccountControl", NULL};
495         char *filter, *dn;
496         LDAPMessage *res = NULL;
497         uint32 uac;
498
499         filter = talloc_asprintf(mem_ctx, "(&(objectclass=user)(sAMAccountName=%s))", hostname);
500         if (filter == NULL) {
501                 return ADS_ERROR(LDAP_NO_MEMORY);
502         }
503
504         status = ads_do_search_all(ads, ads->config.bind_path,
505                                    LDAP_SCOPE_SUBTREE,
506                                    filter, attrs, &res);
507         
508         if (!ADS_ERR_OK(status)) {
509                 return status;
510         }
511
512         if (ads_count_replies(ads, res) != 1) {
513                 ads_msgfree(ads, res);
514                 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
515         }
516
517         dn = ads_get_dn(ads, res);
518         if (dn == NULL) {
519                 ads_msgfree(ads, res);
520                 return ADS_ERROR(LDAP_NO_MEMORY);
521         }
522
523         if (!ads_pull_uint32(ads, res, "userAccountControl", &uac)) {
524                 ads_msgfree(ads, res);
525                 ads_memfree(ads, dn);
526                 return ADS_ERROR(LDAP_NO_MEMORY);
527         }
528
529         ads_msgfree(ads, res);
530
531         if (!(uac & UF_WORKSTATION_TRUST_ACCOUNT)) {
532                 ads_memfree(ads, dn);
533                 return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
534         }
535
536         status = ads_get_gpo_list(ads, mem_ctx, dn, GPO_LIST_FLAG_MACHINE, &gpo_list);
537         if (!ADS_ERR_OK(status)) {
538                 ads_memfree(ads, dn);
539                 return status;
540         }
541
542         ads_memfree(ads, dn);
543
544         status = gpo_process_gpo_list(ads, mem_ctx, gpo_list, 
545                                       cse_gpo_name_to_guid_string("Security"), 
546                                       GPO_LIST_FLAG_MACHINE); 
547         if (!ADS_ERR_OK(status)) {
548                 return status;
549         }
550
551         return ADS_SUCCESS;
552 }
553
554 /****************************************************************
555  check wether the version number in a GROUP_POLICY_OBJECT match those of the
556  locally stored version. If not, fetch the required policy via CIFS
557 ****************************************************************/
558
559 NTSTATUS check_refresh_gpo(ADS_STRUCT *ads, 
560                            TALLOC_CTX *mem_ctx,
561                            struct GROUP_POLICY_OBJECT *gpo,
562                            struct cli_state **cli_out)
563 {
564         NTSTATUS result;
565         char *server = NULL;
566         char *share = NULL;
567         char *nt_path = NULL;
568         char *unix_path = NULL;
569         uint32 sysvol_gpt_version = 0;
570         char *display_name = NULL;
571         struct cli_state *cli = NULL;
572
573         result = gpo_explode_filesyspath(mem_ctx, gpo->file_sys_path, 
574                                          &server, &share, &nt_path, &unix_path);
575
576         if (!NT_STATUS_IS_OK(result)) {
577                 goto out;
578         }
579
580         result = gpo_get_sysvol_gpt_version(mem_ctx, 
581                                             unix_path,
582                                             &sysvol_gpt_version,
583                                             &display_name);
584         if (!NT_STATUS_IS_OK(result) && 
585             !NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_FILE)) {
586                 DEBUG(10,("check_refresh_gpo: failed to get local gpt version: %s\n", 
587                         nt_errstr(result)));
588                 goto out;
589         }
590
591         while (gpo->version > sysvol_gpt_version) {
592
593                 DEBUG(1,("check_refresh_gpo: need to refresh GPO\n"));
594
595                 if (*cli_out == NULL) {
596
597                         result = cli_full_connection(&cli, global_myname(), 
598                                                      server, /* ads->config.ldap_server_name, */
599                                                      NULL, 0,
600                                                      share, "A:",
601                                                      ads->auth.user_name, NULL, ads->auth.password,
602                                                      CLI_FULL_CONNECTION_USE_KERBEROS,
603                                                      Undefined, NULL);
604                         if (!NT_STATUS_IS_OK(result)) {
605                                 DEBUG(10,("check_refresh_gpo: failed to connect: %s\n", nt_errstr(result)));
606                                 goto out;
607                         }
608
609                         *cli_out = cli;
610                 }
611
612                 result = gpo_fetch_files(mem_ctx, *cli_out, gpo);
613                 if (!NT_STATUS_IS_OK(result)) {
614                         goto out;
615                 }
616
617                 result = gpo_get_sysvol_gpt_version(mem_ctx, 
618                                                     unix_path, 
619                                                     &sysvol_gpt_version,
620                                                     &display_name); 
621                 if (!NT_STATUS_IS_OK(result)) {
622                         DEBUG(10,("check_refresh_gpo: failed to get local gpt version: %s\n", 
623                                 nt_errstr(result)));
624                         goto out;
625                 }
626                 
627                 if (gpo->version == sysvol_gpt_version) {
628                         break;
629                 }
630         } 
631
632         DEBUG(10,("Name:\t\t\t%s\n", gpo->display_name));
633         DEBUGADD(10,("sysvol GPT version:\t%d (user: %d, machine: %d)\n", 
634                 sysvol_gpt_version, 
635                 GPO_VERSION_USER(sysvol_gpt_version), 
636                 GPO_VERSION_MACHINE(sysvol_gpt_version))); 
637         DEBUGADD(10,("LDAP GPO version:\t%d (user: %d, machine: %d)\n", 
638                 gpo->version,
639                 GPO_VERSION_USER(gpo->version),
640                 GPO_VERSION_MACHINE(gpo->version)));
641
642         result = NT_STATUS_OK;
643
644  out:
645         return result;
646
647 }
648
649 /****************************************************************
650  check wether the version numbers in the gpo_list match the locally stored, if
651  not, go and get each required GPO via CIFS
652  ****************************************************************/
653
654 NTSTATUS check_refresh_gpo_list(ADS_STRUCT *ads, 
655                                 TALLOC_CTX *mem_ctx, 
656                                 struct GROUP_POLICY_OBJECT *gpo_list)
657 {
658         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
659         struct cli_state *cli = NULL;
660         struct GROUP_POLICY_OBJECT *gpo;
661
662         if (!gpo_list) {
663                 return NT_STATUS_INVALID_PARAMETER;
664         }
665
666         for (gpo = gpo_list; gpo; gpo = gpo->next) {
667
668                 result = check_refresh_gpo(ads, mem_ctx, gpo, &cli);
669                 if (!NT_STATUS_IS_OK(result)) {
670                         goto out;
671                 }
672         }
673
674         result = NT_STATUS_OK;
675
676  out:
677         if (cli) {
678                 cli_shutdown(cli);
679         }
680
681         return result;
682 }
683
684 #endif /* HAVE_LDAP */