libgpo: allow to pass down a list of deleted GPOs in gpo_process_gpo_list().
[sfrench/samba-autobuild/.git] / source3 / utils / net_ads_gpo.c
1 /*
2    Samba Unix/Linux SMB client library
3    net ads commands for Group Policy
4    Copyright (C) 2005-2008 Guenther Deschner (gd@samba.org)
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 #include "utils/net.h"
22 #include "ads.h"
23 #include "../libgpo/gpo.h"
24 #include "libgpo/gpo_proto.h"
25 #include "../libds/common/flags.h"
26
27 #ifdef HAVE_ADS
28
29 static int net_ads_gpo_refresh(struct net_context *c, int argc, const char **argv)
30 {
31         TALLOC_CTX *mem_ctx;
32         ADS_STRUCT *ads;
33         ADS_STATUS status;
34         const char *dn = NULL;
35         struct GROUP_POLICY_OBJECT *gpo_list = NULL;
36         struct GROUP_POLICY_OBJECT *read_list = NULL;
37         uint32 uac = 0;
38         uint32 flags = 0;
39         struct GROUP_POLICY_OBJECT *gpo;
40         NTSTATUS result;
41         struct security_token *token = NULL;
42
43         if (argc < 1 || c->display_usage) {
44                 d_printf("%s\n%s\n%s",
45                          _("Usage:"),
46                          _("net ads gpo refresh <username|machinename>"),
47                          _("  Lists all GPOs assigned to an account and "
48                            "downloads them\n"
49                            "    username\tUser to refresh GPOs for\n"
50                            "    machinename\tMachine to refresh GPOs for\n"));
51                 return -1;
52         }
53
54         mem_ctx = talloc_init("net_ads_gpo_refresh");
55         if (mem_ctx == NULL) {
56                 return -1;
57         }
58
59         status = ads_startup(c, false, &ads);
60         if (!ADS_ERR_OK(status)) {
61                 d_printf(_("failed to connect AD server: %s\n"), ads_errstr(status));
62                 goto out;
63         }
64
65         status = ads_find_samaccount(ads, mem_ctx, argv[0], &uac, &dn);
66         if (!ADS_ERR_OK(status)) {
67                 d_printf(_("failed to find samaccount for %s\n"), argv[0]);
68                 goto out;
69         }
70
71         if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
72                 flags |= GPO_LIST_FLAG_MACHINE;
73         }
74
75         d_printf(_("\n%s: '%s' has dn: '%s'\n\n"),
76                 (uac & UF_WORKSTATION_TRUST_ACCOUNT) ? _("machine") : _("user"),
77                 argv[0], dn);
78
79         d_printf(_("* fetching token "));
80         if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
81                 status = gp_get_machine_token(ads, mem_ctx, dn, &token);
82         } else {
83                 status = ads_get_sid_token(ads, mem_ctx, dn, &token);
84         }
85
86         if (!ADS_ERR_OK(status)) {
87                 d_printf(_("failed: %s\n"), ads_errstr(status));
88                 goto out;
89         }
90         d_printf(_("finished\n"));
91
92         d_printf(_("* fetching GPO List "));
93         status = ads_get_gpo_list(ads, mem_ctx, dn, flags, token, &gpo_list);
94         if (!ADS_ERR_OK(status)) {
95                 d_printf(_("failed: %s\n"),
96                          ads_errstr(status));
97                 goto out;
98         }
99         d_printf(_("finished\n"));
100
101         d_printf(_("* Refreshing Group Policy Data "));
102         if (!NT_STATUS_IS_OK(result = check_refresh_gpo_list(ads, mem_ctx,
103                                                              cache_path(GPO_CACHE_DIR),
104                                                              flags,
105                                                              gpo_list))) {
106                 d_printf(_("failed: %s\n"), nt_errstr(result));
107                 goto out;
108         }
109         d_printf(_("finished\n"));
110
111         d_printf(_("* storing GPO list to registry "));
112
113         {
114                 WERROR werr = gp_reg_state_store(mem_ctx, flags, dn,
115                                                  token, gpo_list);
116                 if (!W_ERROR_IS_OK(werr)) {
117                         d_printf(_("failed: %s\n"), win_errstr(werr));
118                         goto out;
119                 }
120         }
121
122         d_printf(_("finished\n"));
123
124         if (c->opt_verbose) {
125
126                 d_printf(_("* dumping GPO list\n"));
127
128                 for (gpo = gpo_list; gpo; gpo = gpo->next) {
129
130                         dump_gpo(gpo, 0);
131 #if 0
132                 char *server, *share, *nt_path, *unix_path;
133
134                 d_printf("--------------------------------------\n");
135                 d_printf("Name:\t\t\t%s\n", gpo->display_name);
136                 d_printf("LDAP GPO version:\t%d (user: %d, machine: %d)\n",
137                         gpo->version,
138                         GPO_VERSION_USER(gpo->version),
139                         GPO_VERSION_MACHINE(gpo->version));
140
141                 result = gpo_explode_filesyspath(mem_ctx, gpo->file_sys_path,
142                                                  &server, &share, &nt_path,
143                                                  &unix_path);
144                 if (!NT_STATUS_IS_OK(result)) {
145                         d_printf("got: %s\n", nt_errstr(result));
146                 }
147
148                 d_printf("GPO stored on server: %s, share: %s\n", server, share);
149                 d_printf("\tremote path:\t%s\n", nt_path);
150                 d_printf("\tlocal path:\t%s\n", unix_path);
151 #endif
152                 }
153         }
154
155         d_printf(_("* re-reading GPO list from registry "));
156
157         {
158                 WERROR werr = gp_reg_state_read(mem_ctx, flags,
159                                                 &token->sids[0],
160                                                 &read_list);
161                 if (!W_ERROR_IS_OK(werr)) {
162                         d_printf(_("failed: %s\n"), win_errstr(werr));
163                         goto out;
164                 }
165         }
166
167         d_printf(_("finished\n"));
168
169         if (c->opt_verbose) {
170
171                 d_printf(_("* dumping GPO list from registry\n"));
172
173                 for (gpo = read_list; gpo; gpo = gpo->next) {
174
175                         dump_gpo(gpo, 0);
176
177 #if 0
178                 char *server, *share, *nt_path, *unix_path;
179
180                 d_printf("--------------------------------------\n");
181                 d_printf("Name:\t\t\t%s\n", gpo->display_name);
182                 d_printf("LDAP GPO version:\t%d (user: %d, machine: %d)\n",
183                         gpo->version,
184                         GPO_VERSION_USER(gpo->version),
185                         GPO_VERSION_MACHINE(gpo->version));
186
187                 result = gpo_explode_filesyspath(mem_ctx, gpo->file_sys_path,
188                                                  &server, &share, &nt_path,
189                                                  &unix_path);
190                 if (!NT_STATUS_IS_OK(result)) {
191                         d_printf("got: %s\n", nt_errstr(result));
192                 }
193
194                 d_printf("GPO stored on server: %s, share: %s\n", server, share);
195                 d_printf("\tremote path:\t%s\n", nt_path);
196                 d_printf("\tlocal path:\t%s\n", unix_path);
197 #endif
198                 }
199         }
200
201  out:
202         ads_destroy(&ads);
203         talloc_destroy(mem_ctx);
204         return 0;
205 }
206
207 static int net_ads_gpo_list_all(struct net_context *c, int argc, const char **argv)
208 {
209         ADS_STRUCT *ads;
210         ADS_STATUS status;
211         LDAPMessage *res = NULL;
212         int num_reply = 0;
213         LDAPMessage *msg = NULL;
214         struct GROUP_POLICY_OBJECT gpo;
215         TALLOC_CTX *mem_ctx;
216         char *dn;
217         const char *attrs[] = {
218                 "versionNumber",
219                 "flags",
220                 "gPCFileSysPath",
221                 "displayName",
222                 "name",
223                 "gPCMachineExtensionNames",
224                 "gPCUserExtensionNames",
225                 "ntSecurityDescriptor",
226                 NULL
227         };
228
229         if (c->display_usage) {
230                 d_printf(  "%s\n"
231                            "net ads gpo listall\n"
232                            "    %s\n",
233                          _("Usage:"),
234                          _("List all GPOs on the DC"));
235                 return 0;
236         }
237
238         mem_ctx = talloc_init("net_ads_gpo_list_all");
239         if (mem_ctx == NULL) {
240                 return -1;
241         }
242
243         status = ads_startup(c, false, &ads);
244         if (!ADS_ERR_OK(status)) {
245                 goto out;
246         }
247
248         status = ads_do_search_all_sd_flags(ads, ads->config.bind_path,
249                                             LDAP_SCOPE_SUBTREE,
250                                             "(objectclass=groupPolicyContainer)",
251                                             attrs,
252                                             SECINFO_DACL,
253                                             &res);
254
255         if (!ADS_ERR_OK(status)) {
256                 d_printf(_("search failed: %s\n"), ads_errstr(status));
257                 goto out;
258         }
259
260         num_reply = ads_count_replies(ads, res);
261
262         d_printf(_("Got %d replies\n\n"), num_reply);
263
264         /* dump the results */
265         for (msg = ads_first_entry(ads, res);
266              msg;
267              msg = ads_next_entry(ads, msg)) {
268
269                 if ((dn = ads_get_dn(ads, mem_ctx, msg)) == NULL) {
270                         goto out;
271                 }
272
273                 status = ads_parse_gpo(ads, mem_ctx, msg, dn, &gpo);
274
275                 if (!ADS_ERR_OK(status)) {
276                         d_printf(_("ads_parse_gpo failed: %s\n"),
277                                 ads_errstr(status));
278                         goto out;
279                 }
280
281                 dump_gpo(&gpo, 0);
282         }
283
284 out:
285         ads_msgfree(ads, res);
286
287         TALLOC_FREE(mem_ctx);
288         ads_destroy(&ads);
289
290         return 0;
291 }
292
293 static int net_ads_gpo_list(struct net_context *c, int argc, const char **argv)
294 {
295         ADS_STRUCT *ads = NULL;
296         ADS_STATUS status;
297         LDAPMessage *res = NULL;
298         TALLOC_CTX *mem_ctx;
299         const char *dn = NULL;
300         uint32 uac = 0;
301         uint32 flags = 0;
302         struct GROUP_POLICY_OBJECT *gpo_list;
303         struct security_token *token = NULL;
304
305         if (argc < 1 || c->display_usage) {
306                 d_printf("%s\n%s\n%s",
307                          _("Usage:"),
308                          _("net ads gpo list <username|machinename>"),
309                          _("  Lists all GPOs for machine/user\n"
310                            "    username\tUser to list GPOs for\n"
311                            "    machinename\tMachine to list GPOs for\n"));
312                 return -1;
313         }
314
315         mem_ctx = talloc_init("net_ads_gpo_list");
316         if (mem_ctx == NULL) {
317                 goto out;
318         }
319
320         status = ads_startup(c, false, &ads);
321         if (!ADS_ERR_OK(status)) {
322                 goto out;
323         }
324
325         status = ads_find_samaccount(ads, mem_ctx, argv[0], &uac, &dn);
326         if (!ADS_ERR_OK(status)) {
327                 goto out;
328         }
329
330         if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
331                 flags |= GPO_LIST_FLAG_MACHINE;
332         }
333
334         d_printf(_("%s: '%s' has dn: '%s'\n"),
335                 (uac & UF_WORKSTATION_TRUST_ACCOUNT) ? _("machine") : _("user"),
336                 argv[0], dn);
337
338         if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
339                 status = gp_get_machine_token(ads, mem_ctx, dn, &token);
340         } else {
341                 status = ads_get_sid_token(ads, mem_ctx, dn, &token);
342         }
343
344         if (!ADS_ERR_OK(status)) {
345                 goto out;
346         }
347
348         status = ads_get_gpo_list(ads, mem_ctx, dn, flags, token, &gpo_list);
349         if (!ADS_ERR_OK(status)) {
350                 goto out;
351         }
352
353         dump_gpo_list(gpo_list, 0);
354
355 out:
356         ads_msgfree(ads, res);
357
358         talloc_destroy(mem_ctx);
359         ads_destroy(&ads);
360
361         return 0;
362 }
363
364 static int net_ads_gpo_apply(struct net_context *c, int argc, const char **argv)
365 {
366         TALLOC_CTX *mem_ctx;
367         ADS_STRUCT *ads;
368         ADS_STATUS status;
369         const char *dn = NULL;
370         struct GROUP_POLICY_OBJECT *gpo_list;
371         uint32 uac = 0;
372         uint32 flags = 0;
373         struct security_token *token = NULL;
374         const char *filter = NULL;
375
376         if (argc < 1 || c->display_usage) {
377                 d_printf("Usage:\n"
378                          "net ads gpo apply <username|machinename>\n"
379                          "  Apply GPOs for machine/user\n"
380                          "    username\tUsername to apply GPOs for\n"
381                          "    machinename\tMachine to apply GPOs for\n");
382                 return -1;
383         }
384
385         mem_ctx = talloc_init("net_ads_gpo_apply");
386         if (mem_ctx == NULL) {
387                 goto out;
388         }
389
390         if (argc >= 2) {
391                 filter = cse_gpo_name_to_guid_string(argv[1]);
392         }
393
394         status = ads_startup(c, false, &ads);
395         /* filter = cse_gpo_name_to_guid_string("Security"); */
396
397         if (!ADS_ERR_OK(status)) {
398                 d_printf("got: %s\n", ads_errstr(status));
399                 goto out;
400         }
401
402         status = ads_find_samaccount(ads, mem_ctx, argv[0], &uac, &dn);
403         if (!ADS_ERR_OK(status)) {
404                 d_printf("failed to find samaccount for %s: %s\n",
405                         argv[0], ads_errstr(status));
406                 goto out;
407         }
408
409         if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
410                 flags |= GPO_LIST_FLAG_MACHINE;
411         }
412
413         if (c->opt_verbose) {
414                 flags |= GPO_INFO_FLAG_VERBOSE;
415         }
416
417         d_printf("%s: '%s' has dn: '%s'\n",
418                 (uac & UF_WORKSTATION_TRUST_ACCOUNT) ? "machine" : "user",
419                 argv[0], dn);
420
421         if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
422                 status = gp_get_machine_token(ads, mem_ctx, dn, &token);
423         } else {
424                 status = ads_get_sid_token(ads, mem_ctx, dn, &token);
425         }
426
427         if (!ADS_ERR_OK(status)) {
428                 goto out;
429         }
430
431         status = ads_get_gpo_list(ads, mem_ctx, dn, flags, token, &gpo_list);
432         if (!ADS_ERR_OK(status)) {
433                 goto out;
434         }
435
436         status = ADS_ERROR_NT(gpo_process_gpo_list(mem_ctx, token, NULL, gpo_list,
437                                                    filter, flags));
438         if (!ADS_ERR_OK(status)) {
439                 d_printf("failed to process gpo list: %s\n",
440                         ads_errstr(status));
441                 goto out;
442         }
443
444 out:
445         ads_destroy(&ads);
446         talloc_destroy(mem_ctx);
447         return 0;
448 }
449
450 static int net_ads_gpo_link_get(struct net_context *c, int argc, const char **argv)
451 {
452         ADS_STRUCT *ads;
453         ADS_STATUS status;
454         TALLOC_CTX *mem_ctx;
455         struct GP_LINK gp_link;
456
457         if (argc < 1 || c->display_usage) {
458                 d_printf("%s\n%s\n%s",
459                          _("Usage:"),
460                          _("net ads gpo linkget <container>"),
461                          _("  Lists gPLink of a containter\n"
462                            "    container\tContainer to get link for\n"));
463                 return -1;
464         }
465
466         mem_ctx = talloc_init("add_gpo_link");
467         if (mem_ctx == NULL) {
468                 return -1;
469         }
470
471         status = ads_startup(c, false, &ads);
472         if (!ADS_ERR_OK(status)) {
473                 goto out;
474         }
475
476         status = ads_get_gpo_link(ads, mem_ctx, argv[0], &gp_link);
477         if (!ADS_ERR_OK(status)) {
478                 d_printf(_("get link for %s failed: %s\n"), argv[0],
479                         ads_errstr(status));
480                 goto out;
481         }
482
483         dump_gplink(&gp_link);
484
485 out:
486         talloc_destroy(mem_ctx);
487         ads_destroy(&ads);
488
489         return 0;
490 }
491
492 static int net_ads_gpo_link_add(struct net_context *c, int argc, const char **argv)
493 {
494         ADS_STRUCT *ads;
495         ADS_STATUS status;
496         uint32 gpo_opt = 0;
497         TALLOC_CTX *mem_ctx;
498
499         if (argc < 2 || c->display_usage) {
500                 d_printf("%s\n%s\n%s",
501                          _("Usage:"),
502                          _("net ads gpo linkadd <linkdn> <gpodn> [options]"),
503                          _("  Link a container to a GPO\n"
504                            "    linkdn\tContainer to link to a GPO\n"
505                            "    gpodn\tGPO to link container to\n"));
506                 d_printf(_("note: DNs must be provided properly escaped.\n"
507                            "See RFC 4514 for details\n"));
508                 return -1;
509         }
510
511         mem_ctx = talloc_init("add_gpo_link");
512         if (mem_ctx == NULL) {
513                 return -1;
514         }
515
516         if (argc == 3) {
517                 gpo_opt = atoi(argv[2]);
518         }
519
520         status = ads_startup(c, false, &ads);
521         if (!ADS_ERR_OK(status)) {
522                 goto out;
523         }
524
525         status = ads_add_gpo_link(ads, mem_ctx, argv[0], argv[1], gpo_opt);
526         if (!ADS_ERR_OK(status)) {
527                 d_printf(_("link add failed: %s\n"), ads_errstr(status));
528                 goto out;
529         }
530
531 out:
532         talloc_destroy(mem_ctx);
533         ads_destroy(&ads);
534
535         return 0;
536 }
537
538 #if 0 /* broken */
539
540 static int net_ads_gpo_link_delete(struct net_context *c, int argc, const char **argv)
541 {
542         ADS_STRUCT *ads;
543         ADS_STATUS status;
544         TALLOC_CTX *mem_ctx;
545
546         if (argc < 2 || c->display_usage) {
547                 d_printf("Usage:\n"
548                          "net ads gpo linkdelete <linkdn> <gpodn>\n"
549                          "  Delete a GPO link\n"
550                          "    <linkdn>\tContainer to delete GPO from\n"
551                          "    <gpodn>\tGPO to delete from container\n");
552                 return -1;
553         }
554
555         mem_ctx = talloc_init("delete_gpo_link");
556         if (mem_ctx == NULL) {
557                 return -1;
558         }
559
560         status = ads_startup(c, false, &ads);
561         if (!ADS_ERR_OK(status)) {
562                 goto out;
563         }
564
565         status = ads_delete_gpo_link(ads, mem_ctx, argv[0], argv[1]);
566         if (!ADS_ERR_OK(status)) {
567                 d_printf("delete link failed: %s\n", ads_errstr(status));
568                 goto out;
569         }
570
571 out:
572         talloc_destroy(mem_ctx);
573         ads_destroy(&ads);
574
575         return 0;
576 }
577
578 #endif
579
580 static int net_ads_gpo_get_gpo(struct net_context *c, int argc, const char **argv)
581 {
582         ADS_STRUCT *ads;
583         ADS_STATUS status;
584         TALLOC_CTX *mem_ctx;
585         struct GROUP_POLICY_OBJECT gpo;
586
587         if (argc < 1 || c->display_usage) {
588                 d_printf("%s\n%s\n%s",
589                          _("Usage:"),
590                          _("net ads gpo getgpo <gpo>"),
591                          _("  List speciefied GPO\n"
592                            "    gpo\t\tGPO to list\n"));
593                 return -1;
594         }
595
596         mem_ctx = talloc_init("ads_gpo_get_gpo");
597         if (mem_ctx == NULL) {
598                 return -1;
599         }
600
601         status = ads_startup(c, false, &ads);
602         if (!ADS_ERR_OK(status)) {
603                 goto out;
604         }
605
606         if (strnequal(argv[0], "CN={", strlen("CN={"))) {
607                 status = ads_get_gpo(ads, mem_ctx, argv[0], NULL, NULL, &gpo);
608         } else {
609                 status = ads_get_gpo(ads, mem_ctx, NULL, argv[0], NULL, &gpo);
610         }
611
612         if (!ADS_ERR_OK(status)) {
613                 d_printf(_("get gpo for [%s] failed: %s\n"), argv[0],
614                         ads_errstr(status));
615                 goto out;
616         }
617
618         dump_gpo(&gpo, 1);
619
620 out:
621         talloc_destroy(mem_ctx);
622         ads_destroy(&ads);
623
624         return 0;
625 }
626
627 int net_ads_gpo(struct net_context *c, int argc, const char **argv)
628 {
629         struct functable func[] = {
630                 {
631                         "apply",
632                         net_ads_gpo_apply,
633                         NET_TRANSPORT_ADS,
634                         "Apply GPO to container",
635                         "net ads gpo apply\n"
636                         "    Apply GPO to container"
637                 },
638                 {
639                         "getgpo",
640                         net_ads_gpo_get_gpo,
641                         NET_TRANSPORT_ADS,
642                         N_("List specified GPO"),
643                         N_("net ads gpo getgpo\n"
644                            "    List specified GPO")
645                 },
646                 {
647                         "linkadd",
648                         net_ads_gpo_link_add,
649                         NET_TRANSPORT_ADS,
650                         N_("Link a container to a GPO"),
651                         N_("net ads gpo linkadd\n"
652                            "    Link a container to a GPO")
653                 },
654 #if 0
655                 {
656                         "linkdelete",
657                         net_ads_gpo_link_delete,
658                         NET_TRANSPORT_ADS,
659                         "Delete GPO link from a container",
660                         "net ads gpo linkdelete\n"
661                         "    Delete GPO link from a container"
662                 },
663 #endif
664                 {
665                         "linkget",
666                         net_ads_gpo_link_get,
667                         NET_TRANSPORT_ADS,
668                         N_("Lists gPLink of containter"),
669                         N_("net ads gpo linkget\n"
670                            "    Lists gPLink of containter")
671                 },
672                 {
673                         "list",
674                         net_ads_gpo_list,
675                         NET_TRANSPORT_ADS,
676                         N_("Lists all GPOs for machine/user"),
677                         N_("net ads gpo list\n"
678                            "    Lists all GPOs for machine/user")
679                 },
680                 {
681                         "listall",
682                         net_ads_gpo_list_all,
683                         NET_TRANSPORT_ADS,
684                         N_("Lists all GPOs on a DC"),
685                         N_("net ads gpo listall\n"
686                            "    Lists all GPOs on a DC")
687                 },
688                 {
689                         "refresh",
690                         net_ads_gpo_refresh,
691                         NET_TRANSPORT_ADS,
692                         N_("Lists all GPOs assigned to an account and "
693                            "downloads them"),
694                         N_("net ads gpo refresh\n"
695                            "    Lists all GPOs assigned to an account and "
696                            "downloads them")
697                 },
698                 {NULL, NULL, 0, NULL, NULL}
699         };
700
701         return net_run_function(c, argc, argv, "net ads gpo", func);
702 }
703
704 #endif /* HAVE_ADS */