r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text
[ira/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 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 "  ADDLINK      Link a container to a GPO\n"\
31 /* "  APPLY        Apply all GPOs\n"\ */
32 /* "  DELETELINK   Delete a gPLink from a container\n"\ */
33 "  REFRESH      Lists all GPOs assigned to an account and downloads them\n"\
34 "  GETGPO       Lists specified GPO\n"\
35 "  GETLINK      Lists gPLink of a containter\n"\
36 "  HELP         Prints this help message\n"\
37 "  LIST         Lists all GPOs\n"\
38 "\n"
39                 );
40         return -1;
41 }
42
43 static int net_ads_gpo_refresh(int argc, const char **argv)
44 {
45         TALLOC_CTX *mem_ctx;
46         ADS_STRUCT *ads;
47         ADS_STATUS status;
48         const char *dn = NULL;
49         struct GROUP_POLICY_OBJECT *gpo_list = NULL;
50         uint32 uac = 0;
51         uint32 flags = 0;
52         struct GROUP_POLICY_OBJECT *gpo;
53         NTSTATUS result;
54         
55         if (argc < 1) {
56                 printf("usage: net ads gpo refresh <username|machinename>\n");
57                 return -1;
58         }
59
60         mem_ctx = talloc_init("net_ads_gpo_refresh");
61         if (mem_ctx == NULL) {
62                 return -1;
63         }
64
65         status = ads_startup(False, &ads);
66         if (!ADS_ERR_OK(status)) {
67                 goto out;
68         }
69
70         status = ads_find_samaccount(ads, mem_ctx, argv[0], &uac, &dn);
71         if (!ADS_ERR_OK(status)) {
72                 printf("failed to find samaccount for %s\n", argv[0]);
73                 goto out;
74         }
75
76         if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
77                 flags |= GPO_LIST_FLAG_MACHINE;
78         }
79
80         printf("\n%s: '%s' has dn: '%s'\n\n", 
81                 (uac & UF_WORKSTATION_TRUST_ACCOUNT) ? "machine" : "user", 
82                 argv[0], dn);
83
84         status = ads_get_gpo_list(ads, mem_ctx, dn, flags, &gpo_list);
85         if (!ADS_ERR_OK(status)) {
86                 goto out;
87         }
88
89         if (!NT_STATUS_IS_OK(result = check_refresh_gpo_list(ads, mem_ctx, gpo_list))) {
90                 printf("failed to refresh GPOs: %s\n", nt_errstr(result));
91                 goto out;
92         }
93
94         for (gpo = gpo_list; gpo; gpo = gpo->next) {
95
96                 char *server, *share, *nt_path, *unix_path;
97
98                 printf("--------------------------------------\n");
99                 printf("Name:\t\t\t%s\n", gpo->display_name);
100                 printf("LDAP GPO version:\t%d (user: %d, machine: %d)\n",
101                         gpo->version,
102                         GPO_VERSION_USER(gpo->version),
103                         GPO_VERSION_MACHINE(gpo->version));
104
105                 result = gpo_explode_filesyspath(mem_ctx, gpo->file_sys_path,
106                                                  &server, &share, &nt_path, &unix_path);
107                 if (!NT_STATUS_IS_OK(result)) {
108                         printf("got: %s\n", nt_errstr(result));
109                 }
110
111                 printf("GPO stored on server: %s, share: %s\n", server, share);
112                 printf("\tremote path:\t%s\n", nt_path);
113                 printf("\tlocal path:\t%s\n", unix_path);
114         }
115
116  out:
117         ads_destroy(&ads);
118         talloc_destroy(mem_ctx);
119         return 0;
120 }
121
122 static int net_ads_gpo_list(int argc, const char **argv)
123 {
124         ADS_STRUCT *ads;
125         ADS_STATUS status;
126         LDAPMessage *res = NULL;
127         int num_reply = 0;
128         LDAPMessage *msg = NULL;
129         struct GROUP_POLICY_OBJECT gpo;
130         TALLOC_CTX *mem_ctx;
131         char *dn;
132         const char *attrs[] = {
133                 "versionNumber",
134                 "flags",
135                 "gPCFileSysPath",
136                 "displayName",
137                 "name",
138                 "gPCMachineExtensionNames",
139                 "gPCUserExtensionNames",
140                 NULL
141         };
142
143         mem_ctx = talloc_init("net_ads_gpo_list");
144         if (mem_ctx == NULL) {
145                 return -1;
146         }
147
148         status = ads_startup(False, &ads);
149         if (!ADS_ERR_OK(status)) {
150                 goto out;
151         }
152
153         status = ads_do_search_all(ads, ads->config.bind_path,
154                                    LDAP_SCOPE_SUBTREE,
155                                    "(objectclass=groupPolicyContainer)", attrs, &res);
156         if (!ADS_ERR_OK(status)) {
157                 d_printf("search failed: %s\n", ads_errstr(status));
158                 goto out;
159         }       
160
161         num_reply = ads_count_replies(ads, res);
162         
163         d_printf("Got %d replies\n\n", num_reply);
164
165         /* dump the results */
166         for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) {
167
168                 if ((dn = ads_get_dn(ads, msg)) == NULL) {
169                         goto out;
170                 }
171
172                 status = ads_parse_gpo(ads, mem_ctx, msg, dn, &gpo);
173
174                 if (!ADS_ERR_OK(status)) {
175                         d_printf("parse failed: %s\n", ads_errstr(status));
176                         ads_memfree(ads, dn);
177                         goto out;
178                 }       
179
180                 dump_gpo(mem_ctx, &gpo, 1);
181                 ads_memfree(ads, dn);
182         }
183
184 out:
185         ads_msgfree(ads, res);
186
187         talloc_destroy(mem_ctx);
188         ads_destroy(&ads);
189         
190         return 0;
191 }
192
193 #if 0 /* not yet */
194
195 static int net_ads_gpo_apply(int argc, const char **argv)
196 {
197         TALLOC_CTX *mem_ctx;
198         ADS_STRUCT *ads;
199         ADS_STATUS status;
200         const char *dn = NULL;
201         struct GROUP_POLICY_OBJECT *gpo_list;
202         uint32 uac = 0;
203         uint32 flags = 0;
204         
205         if (argc < 1) {
206                 printf("usage: net ads gpo apply <username|machinename>\n");
207                 return -1;
208         }
209
210         mem_ctx = talloc_init("net_ads_gpo_apply");
211         if (mem_ctx == NULL) {
212                 goto out;
213         }
214
215         status = ads_startup(False, &ads);
216         if (!ADS_ERR_OK(status)) {
217                 goto out;
218         }
219
220         status = ads_find_samaccount(ads, mem_ctx, argv[0], &uac, &dn);
221         if (!ADS_ERR_OK(status)) {
222                 goto out;
223         }
224
225         if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
226                 flags |= GPO_LIST_FLAG_MACHINE;
227         }
228
229         printf("%s: '%s' has dn: '%s'\n", 
230                 (uac & UF_WORKSTATION_TRUST_ACCOUNT) ? "machine" : "user", 
231                 argv[0], dn);
232
233         status = ads_get_gpo_list(ads, mem_ctx, dn, flags, &gpo_list);
234         if (!ADS_ERR_OK(status)) {
235                 goto out;
236         }
237
238         /* FIXME: allow to process just a single extension */
239         status = gpo_process_gpo_list(ads, mem_ctx, gpo_list, NULL, flags); 
240         if (!ADS_ERR_OK(status)) {
241                 goto out;
242         }
243
244 out:
245         ads_destroy(&ads);
246         talloc_destroy(mem_ctx);
247         return 0;
248 }
249
250 #endif
251
252 static int net_ads_gpo_get_link(int argc, const char **argv)
253 {
254         ADS_STRUCT *ads;
255         ADS_STATUS status;
256         TALLOC_CTX *mem_ctx;
257         struct GP_LINK gp_link;
258
259         if (argc < 1) {
260                 printf("usage: net ads gpo getlink <linkname>\n");
261                 return -1;
262         }
263
264         mem_ctx = talloc_init("add_gpo_link");
265         if (mem_ctx == NULL) {
266                 return -1;
267         }
268
269         status = ads_startup(False, &ads);
270         if (!ADS_ERR_OK(status)) {
271                 goto out;
272         }
273
274         status = ads_get_gpo_link(ads, mem_ctx, argv[0], &gp_link);
275         if (!ADS_ERR_OK(status)) {
276                 d_printf("get link for %s failed: %s\n", argv[0], ads_errstr(status));
277                 goto out;
278         }       
279
280         dump_gplink(ads, mem_ctx, &gp_link);
281
282 out:
283         talloc_destroy(mem_ctx);
284         ads_destroy(&ads);
285
286         return 0;
287 }
288
289 static int net_ads_gpo_add_link(int argc, const char **argv)
290 {
291         ADS_STRUCT *ads;
292         ADS_STATUS status;
293         uint32 gpo_opt = 0;
294         TALLOC_CTX *mem_ctx;
295
296         if (argc < 2) {
297                 printf("usage: net ads gpo addlink <linkdn> <gpodn> [options]\n");
298                 printf("note: DNs must be provided properly escaped.\n      See RFC 4514 for details\n");
299                 return -1;
300         }
301
302         mem_ctx = talloc_init("add_gpo_link");
303         if (mem_ctx == NULL) {
304                 return -1;
305         }
306
307         if (argc == 3) {
308                 gpo_opt = atoi(argv[2]);
309         }
310
311         status = ads_startup(False, &ads);
312         if (!ADS_ERR_OK(status)) {
313                 goto out;
314         }
315
316         status = ads_add_gpo_link(ads, mem_ctx, argv[0], argv[1], gpo_opt);
317         if (!ADS_ERR_OK(status)) {
318                 d_printf("add link failed: %s\n", ads_errstr(status));
319                 goto out;
320         }
321
322 out:
323         talloc_destroy(mem_ctx);
324         ads_destroy(&ads);
325
326         return 0;
327 }
328
329 #if 0 /* broken */
330
331 static int net_ads_gpo_delete_link(int argc, const char **argv)
332 {
333         ADS_STRUCT *ads;
334         ADS_STATUS status;
335         TALLOC_CTX *mem_ctx;
336
337         if (argc < 2) {
338                 return -1;
339         }
340
341         mem_ctx = talloc_init("delete_gpo_link");
342         if (mem_ctx == NULL) {
343                 return -1;
344         }
345
346         status = ads_startup(False, &ads);
347         if (!ADS_ERR_OK(status)) {
348                 goto out;
349         }
350
351         status = ads_delete_gpo_link(ads, mem_ctx, argv[0], argv[1]);
352         if (!ADS_ERR_OK(status)) {
353                 d_printf("delete link failed: %s\n", ads_errstr(status));
354                 goto out;
355         }       
356
357 out:
358         talloc_destroy(mem_ctx);
359         ads_destroy(&ads);
360
361         return 0;
362 }
363
364 #endif
365
366 static int net_ads_gpo_get_gpo(int argc, const char **argv)
367 {
368         ADS_STRUCT *ads;
369         ADS_STATUS status;
370         TALLOC_CTX *mem_ctx;
371         struct GROUP_POLICY_OBJECT gpo;
372
373         if (argc < 1) {
374                 printf("usage: net ads gpo getgpo <gpo>\n");
375                 return -1;
376         }
377
378         mem_ctx = talloc_init("add_gpo_get_gpo");
379         if (mem_ctx == NULL) {
380                 return -1;
381         }
382
383         status = ads_startup(False, &ads);
384         if (!ADS_ERR_OK(status)) {
385                 goto out;
386         }
387
388         if (strnequal(argv[0], "CN={", strlen("CN={"))) {
389                 status = ads_get_gpo(ads, mem_ctx, argv[0], NULL, NULL, &gpo);
390         } else {
391                 status = ads_get_gpo(ads, mem_ctx, NULL, argv[0], NULL, &gpo);
392         }
393
394         if (!ADS_ERR_OK(status)) {
395                 d_printf("get gpo for [%s] failed: %s\n", argv[0], ads_errstr(status));
396                 goto out;
397         }       
398
399         dump_gpo(mem_ctx, &gpo, 1);
400
401 out:
402         talloc_destroy(mem_ctx);
403         ads_destroy(&ads);
404
405         return 0;
406 }
407
408 int net_ads_gpo(int argc, const char **argv)
409 {
410         struct functable func[] = {
411                 {"LIST", net_ads_gpo_list},
412                 {"REFRESH", net_ads_gpo_refresh},
413                 {"ADDLINK", net_ads_gpo_add_link},
414                 /* {"DELETELINK", net_ads_gpo_delete_link}, */
415                 {"GETLINK", net_ads_gpo_get_link},
416                 {"GETGPO", net_ads_gpo_get_gpo},
417                 {"HELP", net_ads_gpo_usage},
418                 /* {"APPLY", net_ads_gpo_apply}, */
419                 {NULL, NULL}
420         };
421
422         return net_run_function(argc, argv, func, net_ads_gpo_usage);
423 }
424
425 #endif /* HAVE_ADS */