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(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(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(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");
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");
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(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(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(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(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(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(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(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(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(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(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(int argc
, const char **argv
)
532 mem_ctx
= talloc_init("delete_gpo_link");
533 if (mem_ctx
== NULL
) {
537 status
= ads_startup(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(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(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(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(argc
, argv
, func
, net_ads_gpo_usage
);
618 #endif /* HAVE_ADS */