Rename libnet_smbconf_drop() to libnet_conf_drop().
[ira/wip.git] / source / utils / net_ads_gpo.c
1 /* 
2    Samba Unix/Linux SMB client library 
3    net ads commands for Group Policy
4    Copyright (C) 2005 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(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(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         uint32 uac = 0;
52         uint32 flags = 0;
53         struct GROUP_POLICY_OBJECT *gpo;
54         NTSTATUS result;
55         struct nt_user_token *token = NULL;
56
57         if (argc < 1) {
58                 printf("usage: net ads gpo refresh <username|machinename>\n");
59                 return -1;
60         }
61
62         mem_ctx = talloc_init("net_ads_gpo_refresh");
63         if (mem_ctx == NULL) {
64                 return -1;
65         }
66
67         status = ads_startup(False, &ads);
68         if (!ADS_ERR_OK(status)) {
69                 goto out;
70         }
71
72         status = ads_find_samaccount(ads, mem_ctx, argv[0], &uac, &dn);
73         if (!ADS_ERR_OK(status)) {
74                 printf("failed to find samaccount for %s\n", argv[0]);
75                 goto out;
76         }
77
78         if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
79                 flags |= GPO_LIST_FLAG_MACHINE;
80         }
81
82         printf("\n%s: '%s' has dn: '%s'\n\n", 
83                 (uac & UF_WORKSTATION_TRUST_ACCOUNT) ? "machine" : "user", 
84                 argv[0], dn);
85
86         status = ads_get_sid_token(ads, mem_ctx, dn, &token);
87         if (!ADS_ERR_OK(status)) {
88                 goto out;
89         }
90
91         status = ads_get_gpo_list(ads, mem_ctx, dn, flags, token, &gpo_list);
92         if (!ADS_ERR_OK(status)) {
93                 goto out;
94         }
95
96         if (!NT_STATUS_IS_OK(result = check_refresh_gpo_list(ads, mem_ctx, flags, gpo_list))) {
97                 printf("failed to refresh GPOs: %s\n", nt_errstr(result));
98                 goto out;
99         }
100
101         for (gpo = gpo_list; gpo; gpo = gpo->next) {
102
103                 char *server, *share, *nt_path, *unix_path;
104
105                 printf("--------------------------------------\n");
106                 printf("Name:\t\t\t%s\n", gpo->display_name);
107                 printf("LDAP GPO version:\t%d (user: %d, machine: %d)\n",
108                         gpo->version,
109                         GPO_VERSION_USER(gpo->version),
110                         GPO_VERSION_MACHINE(gpo->version));
111
112                 result = gpo_explode_filesyspath(mem_ctx, gpo->file_sys_path,
113                                                  &server, &share, &nt_path, &unix_path);
114                 if (!NT_STATUS_IS_OK(result)) {
115                         printf("got: %s\n", nt_errstr(result));
116                 }
117
118                 printf("GPO stored on server: %s, share: %s\n", server, share);
119                 printf("\tremote path:\t%s\n", nt_path);
120                 printf("\tlocal path:\t%s\n", unix_path);
121         }
122
123  out:
124         ads_destroy(&ads);
125         talloc_destroy(mem_ctx);
126         return 0;
127 }
128
129 static int net_ads_gpo_list_all(int argc, const char **argv)
130 {
131         ADS_STRUCT *ads;
132         ADS_STATUS status;
133         LDAPMessage *res = NULL;
134         int num_reply = 0;
135         LDAPMessage *msg = NULL;
136         struct GROUP_POLICY_OBJECT gpo;
137         TALLOC_CTX *mem_ctx;
138         char *dn;
139         const char *attrs[] = {
140                 "versionNumber",
141                 "flags",
142                 "gPCFileSysPath",
143                 "displayName",
144                 "name",
145                 "gPCMachineExtensionNames",
146                 "gPCUserExtensionNames",
147                 "ntSecurityDescriptor",
148                 NULL
149         };
150
151         mem_ctx = talloc_init("net_ads_gpo_list_all");
152         if (mem_ctx == NULL) {
153                 return -1;
154         }
155
156         status = ads_startup(False, &ads);
157         if (!ADS_ERR_OK(status)) {
158                 goto out;
159         }
160
161         status = ads_do_search_all_sd_flags(ads, ads->config.bind_path,
162                                             LDAP_SCOPE_SUBTREE,
163                                             "(objectclass=groupPolicyContainer)",
164                                             attrs,
165                                             DACL_SECURITY_INFORMATION,
166                                             &res);
167
168         if (!ADS_ERR_OK(status)) {
169                 d_printf("search failed: %s\n", ads_errstr(status));
170                 goto out;
171         }       
172
173         num_reply = ads_count_replies(ads, res);
174         
175         d_printf("Got %d replies\n\n", num_reply);
176
177         /* dump the results */
178         for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
179
180                 if ((dn = ads_get_dn(ads, msg)) == NULL) {
181                         goto out;
182                 }
183
184                 status = ads_parse_gpo(ads, mem_ctx, msg, dn, &gpo);
185
186                 if (!ADS_ERR_OK(status)) {
187                         d_printf("ads_parse_gpo failed: %s\n", ads_errstr(status));
188                         ads_memfree(ads, dn);
189                         goto out;
190                 }       
191
192                 dump_gpo(ads, mem_ctx, &gpo, 0);
193                 ads_memfree(ads, dn);
194         }
195
196 out:
197         ads_msgfree(ads, res);
198
199         talloc_destroy(mem_ctx);
200         ads_destroy(&ads);
201         
202         return 0;
203 }
204
205 static int net_ads_gpo_list(int argc, const char **argv)
206 {
207         ADS_STRUCT *ads;
208         ADS_STATUS status;
209         LDAPMessage *res = NULL;
210         TALLOC_CTX *mem_ctx;
211         const char *dn = NULL;
212         uint32 uac = 0;
213         uint32 flags = 0;
214         struct GROUP_POLICY_OBJECT *gpo_list;
215         struct nt_user_token *token = NULL;
216
217         if (argc < 1) {
218                 printf("usage: net ads gpo list <username|machinename>\n");
219                 return -1;
220         }
221
222         mem_ctx = talloc_init("net_ads_gpo_list");
223         if (mem_ctx == NULL) {
224                 goto out;
225         }
226
227         status = ads_startup(False, &ads);
228         if (!ADS_ERR_OK(status)) {
229                 goto out;
230         }
231
232         status = ads_find_samaccount(ads, mem_ctx, argv[0], &uac, &dn);
233         if (!ADS_ERR_OK(status)) {
234                 goto out;
235         }
236
237         if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
238                 flags |= GPO_LIST_FLAG_MACHINE;
239         }
240
241         printf("%s: '%s' has dn: '%s'\n", 
242                 (uac & UF_WORKSTATION_TRUST_ACCOUNT) ? "machine" : "user", 
243                 argv[0], dn);
244
245         status = ads_get_sid_token(ads, mem_ctx, dn, &token);
246         if (!ADS_ERR_OK(status)) {
247                 goto out;
248         }
249
250         status = ads_get_gpo_list(ads, mem_ctx, dn, flags, token, &gpo_list);
251         if (!ADS_ERR_OK(status)) {
252                 goto out;
253         }
254
255         dump_gpo_list(ads, mem_ctx, gpo_list, 0);
256
257 out:
258         ads_msgfree(ads, res);
259
260         talloc_destroy(mem_ctx);
261         ads_destroy(&ads);
262         
263         return 0;
264 }
265
266 #if 0 /* not yet */
267 static int net_ads_gpo_apply(int argc, const char **argv)
268 {
269         TALLOC_CTX *mem_ctx;
270         ADS_STRUCT *ads;
271         ADS_STATUS status;
272         const char *dn = NULL;
273         struct GROUP_POLICY_OBJECT *gpo_list;
274         uint32 uac = 0;
275         uint32 flags = 0;
276         
277         if (argc < 1) {
278                 printf("usage: net ads gpo apply <username|machinename>\n");
279                 return -1;
280         }
281
282         mem_ctx = talloc_init("net_ads_gpo_apply");
283         if (mem_ctx == NULL) {
284                 goto out;
285         }
286
287         status = ads_startup(False, &ads);
288         if (!ADS_ERR_OK(status)) {
289                 goto out;
290         }
291
292         status = ads_find_samaccount(ads, mem_ctx, argv[0], &uac, &dn);
293         if (!ADS_ERR_OK(status)) {
294                 goto out;
295         }
296
297         if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
298                 flags |= GPO_LIST_FLAG_MACHINE;
299         }
300
301         printf("%s: '%s' has dn: '%s'\n", 
302                 (uac & UF_WORKSTATION_TRUST_ACCOUNT) ? "machine" : "user", 
303                 argv[0], dn);
304
305         status = ads_get_gpo_list(ads, mem_ctx, dn, flags, &gpo_list);
306         if (!ADS_ERR_OK(status)) {
307                 goto out;
308         }
309
310         /* FIXME: allow to process just a single extension */
311         status = gpo_process_gpo_list(ads, mem_ctx, gpo_list, NULL, flags); 
312         if (!ADS_ERR_OK(status)) {
313                 goto out;
314         }
315
316 out:
317         ads_destroy(&ads);
318         talloc_destroy(mem_ctx);
319         return 0;
320 }
321
322 #endif
323
324 static int net_ads_gpo_link_get(int argc, const char **argv)
325 {
326         ADS_STRUCT *ads;
327         ADS_STATUS status;
328         TALLOC_CTX *mem_ctx;
329         struct GP_LINK gp_link;
330
331         if (argc < 1) {
332                 printf("usage: net ads gpo linkget <linkname>\n");
333                 return -1;
334         }
335
336         mem_ctx = talloc_init("add_gpo_link");
337         if (mem_ctx == NULL) {
338                 return -1;
339         }
340
341         status = ads_startup(False, &ads);
342         if (!ADS_ERR_OK(status)) {
343                 goto out;
344         }
345
346         status = ads_get_gpo_link(ads, mem_ctx, argv[0], &gp_link);
347         if (!ADS_ERR_OK(status)) {
348                 d_printf("get link for %s failed: %s\n", argv[0], ads_errstr(status));
349                 goto out;
350         }       
351
352         dump_gplink(ads, mem_ctx, &gp_link);
353
354 out:
355         talloc_destroy(mem_ctx);
356         ads_destroy(&ads);
357
358         return 0;
359 }
360
361 static int net_ads_gpo_link_add(int argc, const char **argv)
362 {
363         ADS_STRUCT *ads;
364         ADS_STATUS status;
365         uint32 gpo_opt = 0;
366         TALLOC_CTX *mem_ctx;
367
368         if (argc < 2) {
369                 printf("usage: net ads gpo linkadd <linkdn> <gpodn> [options]\n");
370                 printf("note: DNs must be provided properly escaped.\n      See RFC 4514 for details\n");
371                 return -1;
372         }
373
374         mem_ctx = talloc_init("add_gpo_link");
375         if (mem_ctx == NULL) {
376                 return -1;
377         }
378
379         if (argc == 3) {
380                 gpo_opt = atoi(argv[2]);
381         }
382
383         status = ads_startup(False, &ads);
384         if (!ADS_ERR_OK(status)) {
385                 goto out;
386         }
387
388         status = ads_add_gpo_link(ads, mem_ctx, argv[0], argv[1], gpo_opt);
389         if (!ADS_ERR_OK(status)) {
390                 d_printf("link add failed: %s\n", ads_errstr(status));
391                 goto out;
392         }
393
394 out:
395         talloc_destroy(mem_ctx);
396         ads_destroy(&ads);
397
398         return 0;
399 }
400
401 #if 0 /* broken */
402
403 static int net_ads_gpo_link_delete(int argc, const char **argv)
404 {
405         ADS_STRUCT *ads;
406         ADS_STATUS status;
407         TALLOC_CTX *mem_ctx;
408
409         if (argc < 2) {
410                 return -1;
411         }
412
413         mem_ctx = talloc_init("delete_gpo_link");
414         if (mem_ctx == NULL) {
415                 return -1;
416         }
417
418         status = ads_startup(False, &ads);
419         if (!ADS_ERR_OK(status)) {
420                 goto out;
421         }
422
423         status = ads_delete_gpo_link(ads, mem_ctx, argv[0], argv[1]);
424         if (!ADS_ERR_OK(status)) {
425                 d_printf("delete link failed: %s\n", ads_errstr(status));
426                 goto out;
427         }       
428
429 out:
430         talloc_destroy(mem_ctx);
431         ads_destroy(&ads);
432
433         return 0;
434 }
435
436 #endif
437
438 static int net_ads_gpo_get_gpo(int argc, const char **argv)
439 {
440         ADS_STRUCT *ads;
441         ADS_STATUS status;
442         TALLOC_CTX *mem_ctx;
443         struct GROUP_POLICY_OBJECT gpo;
444
445         if (argc < 1) {
446                 printf("usage: net ads gpo getgpo <gpo>\n");
447                 return -1;
448         }
449
450         mem_ctx = talloc_init("add_gpo_get_gpo");
451         if (mem_ctx == NULL) {
452                 return -1;
453         }
454
455         status = ads_startup(False, &ads);
456         if (!ADS_ERR_OK(status)) {
457                 goto out;
458         }
459
460         if (strnequal(argv[0], "CN={", strlen("CN={"))) {
461                 status = ads_get_gpo(ads, mem_ctx, argv[0], NULL, NULL, &gpo);
462         } else {
463                 status = ads_get_gpo(ads, mem_ctx, NULL, argv[0], NULL, &gpo);
464         }
465
466         if (!ADS_ERR_OK(status)) {
467                 d_printf("get gpo for [%s] failed: %s\n", argv[0], ads_errstr(status));
468                 goto out;
469         }       
470
471         dump_gpo(ads, mem_ctx, &gpo, 1);
472
473 out:
474         talloc_destroy(mem_ctx);
475         ads_destroy(&ads);
476
477         return 0;
478 }
479
480 int net_ads_gpo(int argc, const char **argv)
481 {
482         struct functable func[] = {
483                 /* {"APPLY", net_ads_gpo_apply}, */
484                 {"GETGPO", net_ads_gpo_get_gpo},
485                 {"HELP", net_ads_gpo_usage},
486                 {"LINKADD", net_ads_gpo_link_add},
487                 /* {"LINKDELETE", net_ads_gpo_link_delete}, */
488                 {"LINKGET", net_ads_gpo_link_get},
489                 {"LIST", net_ads_gpo_list},
490                 {"LISTALL", net_ads_gpo_list_all},
491                 {"REFRESH", net_ads_gpo_refresh},
492                 {NULL, NULL}
493         };
494
495         return net_run_function(argc, argv, func, net_ads_gpo_usage);
496 }
497
498 #endif /* HAVE_ADS */