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