2 Samba Unix/Linux SMB client library
3 net ads commands for Group Policy
4 Copyright (C) 2005-2008 Guenther Deschner (gd@samba.org)
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.
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.
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/>.
21 #include "utils/net.h"
25 static int net_ads_gpo_usage(struct net_context *c, int argc, const char **argv)
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"\
44 static int net_ads_gpo_refresh(struct net_context *c, int argc, const char **argv)
49 const char *dn = NULL;
50 struct GROUP_POLICY_OBJECT *gpo_list = NULL;
51 struct GROUP_POLICY_OBJECT *read_list = NULL;
54 struct GROUP_POLICY_OBJECT *gpo;
56 struct nt_user_token *token = NULL;
59 printf("usage: net ads gpo refresh <username|machinename>\n");
63 mem_ctx = talloc_init("net_ads_gpo_refresh");
64 if (mem_ctx == NULL) {
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));
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]);
80 if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
81 flags |= GPO_LIST_FLAG_MACHINE;
84 printf("\n%s: '%s' has dn: '%s'\n\n",
85 (uac & UF_WORKSTATION_TRUST_ACCOUNT) ? "machine" : "user",
88 printf("* fetching token ");
89 if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
90 status = gp_get_machine_token(ads, mem_ctx, dn, &token);
92 status = ads_get_sid_token(ads, mem_ctx, dn, &token);
95 if (!ADS_ERR_OK(status)) {
96 printf("failed: %s\n", ads_errstr(status));
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));
107 printf("finished\n");
109 printf("* refreshing Group Policy Data ");
110 if (!NT_STATUS_IS_OK(result = check_refresh_gpo_list(ads, mem_ctx,
113 printf("failed: %s\n", nt_errstr(result));
116 printf("finished\n");
118 printf("* storing GPO list to registry ");
121 WERROR werr = gp_reg_state_store(mem_ctx, flags, dn,
123 if (!W_ERROR_IS_OK(werr)) {
124 printf("failed: %s\n", dos_errstr(werr));
129 printf("finished\n");
131 if (c->opt_verbose) {
133 printf("* dumping GPO list\n");
135 for (gpo = gpo_list; gpo; gpo = gpo->next) {
137 dump_gpo(ads, mem_ctx, gpo, 0);
139 char *server, *share, *nt_path, *unix_path;
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",
145 GPO_VERSION_USER(gpo->version),
146 GPO_VERSION_MACHINE(gpo->version));
148 result = gpo_explode_filesyspath(mem_ctx, gpo->file_sys_path,
149 &server, &share, &nt_path,
151 if (!NT_STATUS_IS_OK(result)) {
152 printf("got: %s\n", nt_errstr(result));
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);
162 printf("* re-reading GPO list from registry ");
165 WERROR werr = gp_reg_state_read(mem_ctx, flags,
166 &token->user_sids[0],
168 if (!W_ERROR_IS_OK(werr)) {
169 printf("failed: %s\n", dos_errstr(werr));
174 printf("finished\n");
176 if (c->opt_verbose) {
178 printf("* dumping GPO list from registry\n");
180 for (gpo = read_list; gpo; gpo = gpo->next) {
182 dump_gpo(ads, mem_ctx, gpo, 0);
185 char *server, *share, *nt_path, *unix_path;
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",
191 GPO_VERSION_USER(gpo->version),
192 GPO_VERSION_MACHINE(gpo->version));
194 result = gpo_explode_filesyspath(mem_ctx, gpo->file_sys_path,
195 &server, &share, &nt_path,
197 if (!NT_STATUS_IS_OK(result)) {
198 printf("got: %s\n", nt_errstr(result));
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);
210 talloc_destroy(mem_ctx);
214 static int net_ads_gpo_list_all(struct net_context *c, int argc, const char **argv)
218 LDAPMessage *res = NULL;
220 LDAPMessage *msg = NULL;
221 struct GROUP_POLICY_OBJECT gpo;
224 const char *attrs[] = {
230 "gPCMachineExtensionNames",
231 "gPCUserExtensionNames",
232 "ntSecurityDescriptor",
236 mem_ctx = talloc_init("net_ads_gpo_list_all");
237 if (mem_ctx == NULL) {
241 status = ads_startup(c, false, &ads);
242 if (!ADS_ERR_OK(status)) {
246 status = ads_do_search_all_sd_flags(ads, ads->config.bind_path,
248 "(objectclass=groupPolicyContainer)",
250 DACL_SECURITY_INFORMATION,
253 if (!ADS_ERR_OK(status)) {
254 d_printf("search failed: %s\n", ads_errstr(status));
258 num_reply = ads_count_replies(ads, res);
260 d_printf("Got %d replies\n\n", num_reply);
262 /* dump the results */
263 for (msg = ads_first_entry(ads, res);
265 msg = ads_next_entry(ads, msg)) {
267 if ((dn = ads_get_dn(ads, msg)) == NULL) {
271 status = ads_parse_gpo(ads, mem_ctx, msg, dn, &gpo);
273 if (!ADS_ERR_OK(status)) {
274 d_printf("ads_parse_gpo failed: %s\n",
276 ads_memfree(ads, dn);
280 dump_gpo(ads, mem_ctx, &gpo, 0);
281 ads_memfree(ads, dn);
285 ads_msgfree(ads, res);
287 talloc_destroy(mem_ctx);
293 static int net_ads_gpo_list(struct net_context *c, int argc, const char **argv)
297 LDAPMessage *res = NULL;
299 const char *dn = NULL;
302 struct GROUP_POLICY_OBJECT *gpo_list;
303 struct nt_user_token *token = NULL;
306 printf("usage: net ads gpo list <username|machinename>\n");
310 mem_ctx = talloc_init("net_ads_gpo_list");
311 if (mem_ctx == NULL) {
315 status = ads_startup(c, false, &ads);
316 if (!ADS_ERR_OK(status)) {
320 status = ads_find_samaccount(ads, mem_ctx, argv[0], &uac, &dn);
321 if (!ADS_ERR_OK(status)) {
325 if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
326 flags |= GPO_LIST_FLAG_MACHINE;
329 printf("%s: '%s' has dn: '%s'\n",
330 (uac & UF_WORKSTATION_TRUST_ACCOUNT) ? "machine" : "user",
333 if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
334 status = gp_get_machine_token(ads, mem_ctx, dn, &token);
336 status = ads_get_sid_token(ads, mem_ctx, dn, &token);
339 if (!ADS_ERR_OK(status)) {
343 status = ads_get_gpo_list(ads, mem_ctx, dn, flags, token, &gpo_list);
344 if (!ADS_ERR_OK(status)) {
348 dump_gpo_list(ads, mem_ctx, gpo_list, 0);
351 ads_msgfree(ads, res);
353 talloc_destroy(mem_ctx);
360 static int net_ads_gpo_apply(struct net_context *c, int argc, const char **argv)
365 const char *dn = NULL;
366 struct GROUP_POLICY_OBJECT *gpo_list;
369 struct nt_user_token *token = NULL;
370 const char *filter = NULL;
373 printf("usage: net ads gpo apply <username|machinename>\n");
377 mem_ctx = talloc_init("net_ads_gpo_apply");
378 if (mem_ctx == NULL) {
383 filter = cse_gpo_name_to_guid_string(argv[1]);
386 status = ads_startup(c, false, &ads);
387 if (!ADS_ERR_OK(status)) {
388 printf("got: %s\n", ads_errstr(status));
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));
399 if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
400 flags |= GPO_LIST_FLAG_MACHINE;
404 flags |= GPO_INFO_FLAG_VERBOSE;
407 printf("%s: '%s' has dn: '%s'\n",
408 (uac & UF_WORKSTATION_TRUST_ACCOUNT) ? "machine" : "user",
411 if (uac & UF_WORKSTATION_TRUST_ACCOUNT) {
412 status = gp_get_machine_token(ads, mem_ctx, dn, &token);
414 status = ads_get_sid_token(ads, mem_ctx, dn, &token);
417 if (!ADS_ERR_OK(status)) {
421 status = ads_get_gpo_list(ads, mem_ctx, dn, flags, token, &gpo_list);
422 if (!ADS_ERR_OK(status)) {
426 status = gpo_process_gpo_list(ads, mem_ctx, token, gpo_list,
428 if (!ADS_ERR_OK(status)) {
429 d_printf("failed to process gpo list: %s\n",
436 talloc_destroy(mem_ctx);
441 static int net_ads_gpo_link_get(struct net_context *c, int argc, const char **argv)
446 struct GP_LINK gp_link;
449 printf("usage: net ads gpo linkget <linkname>\n");
453 mem_ctx = talloc_init("add_gpo_link");
454 if (mem_ctx == NULL) {
458 status = ads_startup(c, false, &ads);
459 if (!ADS_ERR_OK(status)) {
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],
470 dump_gplink(ads, mem_ctx, &gp_link);
473 talloc_destroy(mem_ctx);
479 static int net_ads_gpo_link_add(struct net_context *c, int argc, const char **argv)
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");
493 mem_ctx = talloc_init("add_gpo_link");
494 if (mem_ctx == NULL) {
499 gpo_opt = atoi(argv[2]);
502 status = ads_startup(c, false, &ads);
503 if (!ADS_ERR_OK(status)) {
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));
514 talloc_destroy(mem_ctx);
522 static int net_ads_gpo_link_delete(struct net_context *c, int argc, const char **argv)
532 mem_ctx = talloc_init("delete_gpo_link");
533 if (mem_ctx == NULL) {
537 status = ads_startup(c, false, &ads);
538 if (!ADS_ERR_OK(status)) {
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));
549 talloc_destroy(mem_ctx);
557 static int net_ads_gpo_get_gpo(struct net_context *c, int argc, const char **argv)
562 struct GROUP_POLICY_OBJECT gpo;
565 printf("usage: net ads gpo getgpo <gpo>\n");
569 mem_ctx = talloc_init("add_gpo_get_gpo");
570 if (mem_ctx == NULL) {
574 status = ads_startup(c, false, &ads);
575 if (!ADS_ERR_OK(status)) {
579 if (strnequal(argv[0], "CN={", strlen("CN={"))) {
580 status = ads_get_gpo(ads, mem_ctx, argv[0], NULL, NULL, &gpo);
582 status = ads_get_gpo(ads, mem_ctx, NULL, argv[0], NULL, &gpo);
585 if (!ADS_ERR_OK(status)) {
586 d_printf("get gpo for [%s] failed: %s\n", argv[0],
591 dump_gpo(ads, mem_ctx, &gpo, 1);
594 talloc_destroy(mem_ctx);
600 int net_ads_gpo(struct net_context *c, int argc, const char **argv)
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},
615 return net_run_function(c, argc, argv, func, net_ads_gpo_usage);
618 #endif /* HAVE_ADS */