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