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