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