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