376d846026caae2828c7c0aea2db56c9a3717ac3
[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 #include "ads.h"
23 #include "../libgpo/gpo.h"
24 #include "libgpo/gpo_proto.h"
25 #include "../libds/common/flags.h"
26
27 #ifdef HAVE_ADS
28
29 static int net_ads_gpo_list_all(struct net_context *c, int argc, const char **argv)
30 {
31         ADS_STRUCT *ads;
32         ADS_STATUS status;
33         LDAPMessage *res = NULL;
34         int num_reply = 0;
35         LDAPMessage *msg = NULL;
36         struct GROUP_POLICY_OBJECT gpo;
37         TALLOC_CTX *mem_ctx;
38         char *dn;
39         const char *attrs[] = {
40                 "versionNumber",
41                 "flags",
42                 "gPCFileSysPath",
43                 "displayName",
44                 "name",
45                 "gPCMachineExtensionNames",
46                 "gPCUserExtensionNames",
47                 "ntSecurityDescriptor",
48                 NULL
49         };
50
51         if (c->display_usage) {
52                 d_printf(  "%s\n"
53                            "net ads gpo listall\n"
54                            "    %s\n",
55                          _("Usage:"),
56                          _("List all GPOs on the DC"));
57                 return 0;
58         }
59
60         mem_ctx = talloc_init("net_ads_gpo_list_all");
61         if (mem_ctx == NULL) {
62                 return -1;
63         }
64
65         status = ads_startup(c, false, mem_ctx, &ads);
66         if (!ADS_ERR_OK(status)) {
67                 goto out;
68         }
69
70         status = ads_do_search_all_sd_flags(ads, ads->config.bind_path,
71                                             LDAP_SCOPE_SUBTREE,
72                                             "(objectclass=groupPolicyContainer)",
73                                             attrs,
74                                             SECINFO_DACL,
75                                             &res);
76
77         if (!ADS_ERR_OK(status)) {
78                 d_printf(_("search failed: %s\n"), ads_errstr(status));
79                 goto out;
80         }
81
82         num_reply = ads_count_replies(ads, res);
83
84         d_printf(_("Got %d replies\n\n"), num_reply);
85
86         /* dump the results */
87         for (msg = ads_first_entry(ads, res);
88              msg;
89              msg = ads_next_entry(ads, msg)) {
90
91                 if ((dn = ads_get_dn(ads, mem_ctx, msg)) == NULL) {
92                         goto out;
93                 }
94
95                 status = ads_parse_gpo(ads, mem_ctx, msg, dn, &gpo);
96
97                 if (!ADS_ERR_OK(status)) {
98                         d_printf(_("ads_parse_gpo failed: %s\n"),
99                                 ads_errstr(status));
100                         goto out;
101                 }
102
103                 dump_gpo(&gpo, 0);
104         }
105
106 out:
107         ads_msgfree(ads, res);
108
109         TALLOC_FREE(mem_ctx);
110         ads_destroy(&ads);
111
112         return 0;
113 }
114
115 static int net_ads_gpo_list(struct net_context *c, int argc, const char **argv)
116 {
117         ADS_STRUCT *ads = NULL;
118         ADS_STATUS status;
119         LDAPMessage *res = NULL;
120         TALLOC_CTX *mem_ctx;
121         const char *dn = NULL;
122         uint32_t uac = 0;
123         uint32_t flags = 0;
124         struct GROUP_POLICY_OBJECT *gpo_list;
125         struct security_token *token = NULL;
126
127         if (argc < 1 || c->display_usage) {
128                 d_printf("%s\n%s\n%s",
129                          _("Usage:"),
130                          _("net ads gpo list <username|machinename>"),
131                          _("  Lists all GPOs for machine/user\n"
132                            "    username\tUser to list GPOs for\n"
133                            "    machinename\tMachine to list GPOs for\n"));
134                 return -1;
135         }
136
137         mem_ctx = talloc_init("net_ads_gpo_list");
138         if (mem_ctx == NULL) {
139                 goto out;
140         }
141
142         status = ads_startup(c, false, mem_ctx, &ads);
143         if (!ADS_ERR_OK(status)) {
144                 goto out;
145         }
146
147         status = ads_find_samaccount(ads, mem_ctx, argv[0], &uac, &dn);
148         if (!ADS_ERR_OK(status)) {
149                 goto out;
150         }
151
152         if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
153                 flags |= GPO_LIST_FLAG_MACHINE;
154         }
155
156         d_printf(_("%s: '%s' has dn: '%s'\n"),
157                 (uac & UF_WORKSTATION_TRUST_ACCOUNT) ? _("machine") : _("user"),
158                 argv[0], dn);
159
160         if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
161                 status = gp_get_machine_token(ads, mem_ctx, dn, &token);
162         } else {
163                 status = ads_get_sid_token(ads, mem_ctx, dn, &token);
164         }
165
166         if (!ADS_ERR_OK(status)) {
167                 goto out;
168         }
169
170         status = ads_get_gpo_list(ads, mem_ctx, dn, flags, token, &gpo_list);
171         if (!ADS_ERR_OK(status)) {
172                 goto out;
173         }
174
175         dump_gpo_list(gpo_list, 0);
176
177 out:
178         ads_msgfree(ads, res);
179
180         talloc_destroy(mem_ctx);
181         ads_destroy(&ads);
182
183         return 0;
184 }
185
186 static int net_ads_gpo_link_get(struct net_context *c, int argc, const char **argv)
187 {
188         ADS_STRUCT *ads;
189         ADS_STATUS status;
190         TALLOC_CTX *mem_ctx;
191         struct GP_LINK gp_link;
192
193         if (argc < 1 || c->display_usage) {
194                 d_printf("%s\n%s\n%s",
195                          _("Usage:"),
196                          _("net ads gpo linkget <container>"),
197                          _("  Lists gPLink of a container\n"
198                            "    container\tContainer to get link for\n"));
199                 return -1;
200         }
201
202         mem_ctx = talloc_init("add_gpo_link");
203         if (mem_ctx == NULL) {
204                 return -1;
205         }
206
207         status = ads_startup(c, false, mem_ctx, &ads);
208         if (!ADS_ERR_OK(status)) {
209                 goto out;
210         }
211
212         status = ads_get_gpo_link(ads, mem_ctx, argv[0], &gp_link);
213         if (!ADS_ERR_OK(status)) {
214                 d_printf(_("get link for %s failed: %s\n"), argv[0],
215                         ads_errstr(status));
216                 goto out;
217         }
218
219         dump_gplink(&gp_link);
220
221 out:
222         talloc_destroy(mem_ctx);
223         ads_destroy(&ads);
224
225         return 0;
226 }
227
228 static int net_ads_gpo_link_add(struct net_context *c, int argc, const char **argv)
229 {
230         ADS_STRUCT *ads;
231         ADS_STATUS status;
232         uint32_t gpo_opt = 0;
233         TALLOC_CTX *mem_ctx;
234
235         if (argc < 2 || c->display_usage) {
236                 d_printf("%s\n%s\n%s",
237                          _("Usage:"),
238                          _("net ads gpo linkadd <linkdn> <gpodn> [options]"),
239                          _("  Link a container to a GPO\n"
240                            "    linkdn\tContainer to link to a GPO\n"
241                            "    gpodn\tGPO to link container to\n"));
242                 d_printf(_("note: DNs must be provided properly escaped.\n"
243                            "See RFC 4514 for details\n"));
244                 return -1;
245         }
246
247         mem_ctx = talloc_init("add_gpo_link");
248         if (mem_ctx == NULL) {
249                 return -1;
250         }
251
252         if (argc == 3) {
253                 gpo_opt = atoi(argv[2]);
254         }
255
256         status = ads_startup(c, false, mem_ctx, &ads);
257         if (!ADS_ERR_OK(status)) {
258                 goto out;
259         }
260
261         status = ads_add_gpo_link(ads, mem_ctx, argv[0], argv[1], gpo_opt);
262         if (!ADS_ERR_OK(status)) {
263                 d_printf(_("link add failed: %s\n"), ads_errstr(status));
264                 goto out;
265         }
266
267 out:
268         talloc_destroy(mem_ctx);
269         ads_destroy(&ads);
270
271         return 0;
272 }
273
274 #if 0 /* broken */
275
276 static int net_ads_gpo_link_delete(struct net_context *c, int argc, const char **argv)
277 {
278         ADS_STRUCT *ads;
279         ADS_STATUS status;
280         TALLOC_CTX *mem_ctx;
281
282         if (argc < 2 || c->display_usage) {
283                 d_printf("Usage:\n"
284                          "net ads gpo linkdelete <linkdn> <gpodn>\n"
285                          "  Delete a GPO link\n"
286                          "    <linkdn>\tContainer to delete GPO from\n"
287                          "    <gpodn>\tGPO to delete from container\n");
288                 return -1;
289         }
290
291         mem_ctx = talloc_init("delete_gpo_link");
292         if (mem_ctx == NULL) {
293                 return -1;
294         }
295
296         status = ads_startup(c, false, mem_ctx, &ads);
297         if (!ADS_ERR_OK(status)) {
298                 goto out;
299         }
300
301         status = ads_delete_gpo_link(ads, mem_ctx, argv[0], argv[1]);
302         if (!ADS_ERR_OK(status)) {
303                 d_printf("delete link failed: %s\n", ads_errstr(status));
304                 goto out;
305         }
306
307 out:
308         talloc_destroy(mem_ctx);
309         ads_destroy(&ads);
310
311         return 0;
312 }
313
314 #endif
315
316 /*
317 Arguments:
318 - struct net_context *: Pointer to net_context*
319 - argc: Number of command line arguments passed to 'net ads gpo getgpo' command
320 - **argv: Command line argument string passed to 'net ads gpo getgpo' command
321
322 This function performs following operations:
323 1. Create  talloc context using talloc_init
324 2. Preform ads_startup()
325 3. Call ads_get_gpo() to retrieve gpo details inside 'struct GROUP_POLICY_OBJECT'
326 4. Call dumps_gpo() to dump GPO on stdout
327 */
328 static int net_ads_gpo_get_gpo(struct net_context *c, int argc, const char **argv)
329 {
330         ADS_STRUCT *ads;
331         ADS_STATUS status;
332         TALLOC_CTX *mem_ctx;
333         struct GROUP_POLICY_OBJECT gpo;
334
335         if (argc < 1 || c->display_usage) {
336                 d_printf("%s\n%s\n%s",
337                          _("Usage:"),
338                          _("net ads gpo getgpo <gpo>"),
339                          _("  List specified GPO\n"
340                            "    gpo\t\tGPO to list\n"));
341                 return -1;
342         }
343
344         mem_ctx = talloc_init("ads_gpo_get_gpo");
345         if (mem_ctx == NULL) {
346                 return -1;
347         }
348
349         status = ads_startup(c, false, mem_ctx, &ads);
350         if (!ADS_ERR_OK(status)) {
351                 goto out;
352         }
353
354         if (strnequal(argv[0], "CN={", strlen("CN={"))) {
355                 status = ads_get_gpo(ads, mem_ctx, argv[0], NULL, NULL, &gpo);
356         } else {
357                 status = ads_get_gpo(ads, mem_ctx, NULL, argv[0], NULL, &gpo);
358         }
359
360         if (!ADS_ERR_OK(status)) {
361                 d_printf(_("get gpo for [%s] failed: %s\n"), argv[0],
362                         ads_errstr(status));
363                 goto out;
364         }
365
366         dump_gpo(&gpo, 0);
367
368 out:
369         talloc_destroy(mem_ctx);
370         ads_destroy(&ads);
371
372         return 0;
373 }
374
375 int net_ads_gpo(struct net_context *c, int argc, const char **argv)
376 {
377         struct functable func[] = {
378                 {
379                         "getgpo",
380                         net_ads_gpo_get_gpo,
381                         NET_TRANSPORT_ADS,
382                         N_("List specified GPO"),
383                         N_("net ads gpo getgpo\n"
384                            "    List specified GPO")
385                 },
386                 {
387                         "linkadd",
388                         net_ads_gpo_link_add,
389                         NET_TRANSPORT_ADS,
390                         N_("Link a container to a GPO"),
391                         N_("net ads gpo linkadd\n"
392                            "    Link a container to a GPO")
393                 },
394 #if 0
395                 {
396                         "linkdelete",
397                         net_ads_gpo_link_delete,
398                         NET_TRANSPORT_ADS,
399                         "Delete GPO link from a container",
400                         "net ads gpo linkdelete\n"
401                         "    Delete GPO link from a container"
402                 },
403 #endif
404                 {
405                         "linkget",
406                         net_ads_gpo_link_get,
407                         NET_TRANSPORT_ADS,
408                         N_("Lists gPLink of container"),
409                         N_("net ads gpo linkget\n"
410                            "    Lists gPLink of container")
411                 },
412                 {
413                         "list",
414                         net_ads_gpo_list,
415                         NET_TRANSPORT_ADS,
416                         N_("Lists all GPOs for machine/user"),
417                         N_("net ads gpo list\n"
418                            "    Lists all GPOs for machine/user")
419                 },
420                 {
421                         "listall",
422                         net_ads_gpo_list_all,
423                         NET_TRANSPORT_ADS,
424                         N_("Lists all GPOs on a DC"),
425                         N_("net ads gpo listall\n"
426                            "    Lists all GPOs on a DC")
427                 },
428                 {NULL, NULL, 0, NULL, NULL}
429         };
430
431         return net_run_function(c, argc, argv, "net ads gpo", func);
432 }
433
434 #endif /* HAVE_ADS */