2 Samba Unix/Linux SMB client library
3 net ads commands for Group Policy
4 Copyright (C) 2005 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 2 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, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "utils/net.h"
26 static int net_ads_gpo_usage(int argc
, const char **argv
)
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"\
44 static int net_ads_gpo_refresh(int argc
, const char **argv
)
49 const char *attrs
[] = { "userAccountControl", NULL
};
50 LDAPMessage
*res
= NULL
;
53 struct GROUP_POLICY_OBJECT
*gpo_list
;
56 struct GROUP_POLICY_OBJECT
*gpo
;
60 printf("usage: net ads gpo refresh <username|machinename>\n");
64 mem_ctx
= talloc_init("net_ads_gpo_refresh");
65 if (mem_ctx
== NULL
) {
69 filter
= talloc_asprintf(mem_ctx
, "(&(objectclass=user)(sAMAccountName=%s))", argv
[0]);
74 status
= ads_startup(False
, &ads
);
75 if (!ADS_ERR_OK(status
)) {
79 status
= ads_do_search_all(ads
, ads
->config
.bind_path
,
83 if (!ADS_ERR_OK(status
)) {
87 if (ads_count_replies(ads
, res
) != 1) {
88 printf("no result\n");
92 dn
= ads_get_dn(ads
, res
);
97 if (!ads_pull_uint32(ads
, res
, "userAccountControl", &uac
)) {
101 if (uac
& UF_WORKSTATION_TRUST_ACCOUNT
) {
102 flags
|= GPO_LIST_FLAG_MACHINE
;
105 printf("\n%s: '%s' has dn: '%s'\n\n",
106 (uac
& UF_WORKSTATION_TRUST_ACCOUNT
) ? "machine" : "user",
109 status
= ads_get_gpo_list(ads
, mem_ctx
, dn
, flags
, &gpo_list
);
110 if (!ADS_ERR_OK(status
)) {
114 if (!NT_STATUS_IS_OK(result
= check_refresh_gpo_list(ads
, mem_ctx
, gpo_list
))) {
115 printf("failed to refresh GPOs: %s\n", nt_errstr(result
));
119 for (gpo
= gpo_list
; gpo
; gpo
= gpo
->next
) {
121 char *server
, *share
, *nt_path
, *unix_path
;
123 printf("--------------------------------------\n");
124 printf("Name:\t\t\t%s\n", gpo
->display_name
);
125 printf("LDAP GPO version:\t%d (user: %d, machine: %d)\n",
127 GPO_VERSION_USER(gpo
->version
),
128 GPO_VERSION_MACHINE(gpo
->version
));
130 result
= ads_gpo_explode_filesyspath(ads
, mem_ctx
, gpo
->file_sys_path
,
131 &server
, &share
, &nt_path
, &unix_path
);
132 if (!NT_STATUS_IS_OK(result
)) {
133 printf("got: %s\n", nt_errstr(result
));
136 printf("GPO stored on server: %s, share: %s\n", server
, share
);
137 printf("\tremote path:\t%s\n", nt_path
);
138 printf("\tlocal path:\t%s\n", unix_path
);
142 ads_memfree(ads
, dn
);
143 ads_msgfree(ads
, res
);
146 talloc_destroy(mem_ctx
);
150 static int net_ads_gpo_list(int argc
, const char **argv
)
154 LDAPMessage
*res
= NULL
;
156 LDAPMessage
*msg
= NULL
;
157 struct GROUP_POLICY_OBJECT gpo
;
160 const char *attrs
[] = {
166 "gPCMachineExtensionNames",
167 "gPCUserExtensionNames",
171 mem_ctx
= talloc_init("net_ads_gpo_list");
172 if (mem_ctx
== NULL
) {
176 status
= ads_startup(False
, &ads
);
177 if (!ADS_ERR_OK(status
)) {
181 status
= ads_do_search_all(ads
, ads
->config
.bind_path
,
183 "(objectclass=groupPolicyContainer)", attrs
, &res
);
184 if (!ADS_ERR_OK(status
)) {
185 d_printf("search failed: %s\n", ads_errstr(status
));
189 num_reply
= ads_count_replies(ads
, res
);
191 d_printf("Got %d replies\n\n", num_reply
);
193 /* dump the results */
194 for (msg
= ads_first_entry(ads
, res
); msg
; msg
= ads_next_entry(ads
, msg
)) {
196 if ((dn
= ads_get_dn(ads
, msg
)) == NULL
) {
200 status
= ads_parse_gpo(ads
, mem_ctx
, msg
, dn
, &gpo
);
202 if (!ADS_ERR_OK(status
)) {
203 d_printf("parse failed: %s\n", ads_errstr(status
));
204 ads_memfree(ads
, dn
);
208 dump_gpo(mem_ctx
, &gpo
, 1);
209 ads_memfree(ads
, dn
);
213 ads_msgfree(ads
, res
);
215 talloc_destroy(mem_ctx
);
223 static int net_ads_gpo_apply(int argc
, const char **argv
)
228 const char *attrs
[] = {"distinguishedName", "userAccountControl", NULL
};
229 LDAPMessage
*res
= NULL
;
232 struct GROUP_POLICY_OBJECT
*gpo_list
;
237 printf("usage: net ads gpo apply <username|machinename>\n");
241 mem_ctx
= talloc_init("net_ads_gpo_apply");
242 if (mem_ctx
== NULL
) {
246 filter
= talloc_asprintf(mem_ctx
, "(&(objectclass=user)(sAMAccountName=%s))", argv
[0]);
247 if (filter
== NULL
) {
251 status
= ads_startup(False
, &ads
);
252 if (!ADS_ERR_OK(status
)) {
256 status
= ads_do_search_all(ads
, ads
->config
.bind_path
,
258 filter
, attrs
, &res
);
260 if (!ADS_ERR_OK(status
)) {
264 if (ads_count_replies(ads
, res
) != 1) {
265 printf("no result\n");
269 dn
= ads_get_dn(ads
, res
);
274 if (!ads_pull_uint32(ads
, res
, "userAccountControl", &uac
)) {
278 if (uac
& UF_WORKSTATION_TRUST_ACCOUNT
) {
279 flags
|= GPO_LIST_FLAG_MACHINE
;
282 printf("%s: '%s' has dn: '%s'\n",
283 (uac
& UF_WORKSTATION_TRUST_ACCOUNT
) ? "machine" : "user",
286 status
= ads_get_gpo_list(ads
, mem_ctx
, dn
, flags
, &gpo_list
);
287 if (!ADS_ERR_OK(status
)) {
291 /* FIXME: allow to process just a single extension */
292 status
= gpo_process_gpo_list(ads
, mem_ctx
, &gpo_list
, NULL
, flags
);
293 if (!ADS_ERR_OK(status
)) {
298 ads_memfree(ads
, dn
);
299 ads_msgfree(ads
, res
);
302 talloc_destroy(mem_ctx
);
308 static int net_ads_gpo_get_link(int argc
, const char **argv
)
313 struct GP_LINK gp_link
;
316 printf("usage: net ads gpo getlink <linkname>\n");
320 mem_ctx
= talloc_init("add_gpo_link");
321 if (mem_ctx
== NULL
) {
325 status
= ads_startup(False
, &ads
);
326 if (!ADS_ERR_OK(status
)) {
330 status
= ads_get_gpo_link(ads
, mem_ctx
, argv
[0], &gp_link
);
331 if (!ADS_ERR_OK(status
)) {
332 d_printf("get link for %s failed: %s\n", argv
[0], ads_errstr(status
));
336 dump_gplink(ads
, mem_ctx
, &gp_link
);
339 talloc_destroy(mem_ctx
);
345 static int net_ads_gpo_add_link(int argc
, const char **argv
)
353 printf("usage: net ads gpo addlink <linkdn> <gpodn> [options]\n");
354 printf("note: DNs must be provided properly escaped.\n See RFC 4514 for details\n");
358 mem_ctx
= talloc_init("add_gpo_link");
359 if (mem_ctx
== NULL
) {
364 gpo_opt
= atoi(argv
[2]);
367 status
= ads_startup(False
, &ads
);
368 if (!ADS_ERR_OK(status
)) {
372 status
= ads_add_gpo_link(ads
, mem_ctx
, argv
[0], argv
[1], gpo_opt
);
373 if (!ADS_ERR_OK(status
)) {
374 d_printf("add link failed: %s\n", ads_errstr(status
));
379 talloc_destroy(mem_ctx
);
387 static int net_ads_gpo_delete_link(int argc
, const char **argv
)
397 mem_ctx
= talloc_init("delete_gpo_link");
398 if (mem_ctx
== NULL
) {
402 status
= ads_startup(False
, &ads
);
403 if (!ADS_ERR_OK(status
)) {
407 status
= ads_delete_gpo_link(ads
, mem_ctx
, argv
[0], argv
[1]);
408 if (!ADS_ERR_OK(status
)) {
409 d_printf("delete link failed: %s\n", ads_errstr(status
));
414 talloc_destroy(mem_ctx
);
422 static int net_ads_gpo_get_gpo(int argc
, const char **argv
)
427 struct GROUP_POLICY_OBJECT gpo
;
430 printf("usage: net ads gpo getgpo <gpo>\n");
434 mem_ctx
= talloc_init("add_gpo_get_gpo");
435 if (mem_ctx
== NULL
) {
439 status
= ads_startup(False
, &ads
);
440 if (!ADS_ERR_OK(status
)) {
444 if (strnequal(argv
[0], "CN={", strlen("CN={"))) {
445 status
= ads_get_gpo(ads
, mem_ctx
, argv
[0], NULL
, NULL
, &gpo
);
447 status
= ads_get_gpo(ads
, mem_ctx
, NULL
, argv
[0], NULL
, &gpo
);
450 if (!ADS_ERR_OK(status
)) {
451 d_printf("get gpo for [%s] failed: %s\n", argv
[0], ads_errstr(status
));
455 dump_gpo(mem_ctx
, &gpo
, 1);
458 talloc_destroy(mem_ctx
);
464 int net_ads_gpo(int argc
, const char **argv
)
466 struct functable func
[] = {
467 {"LIST", net_ads_gpo_list
},
468 {"REFRESH", net_ads_gpo_refresh
},
469 {"ADDLINK", net_ads_gpo_add_link
},
470 /* {"DELETELINK", net_ads_gpo_delete_link}, */
471 {"GETLINK", net_ads_gpo_get_link
},
472 {"GETGPO", net_ads_gpo_get_gpo
},
473 {"HELP", net_ads_gpo_usage
},
474 /* {"APPLY", net_ads_gpo_apply}, */
478 return net_run_function(argc
, argv
, func
, net_ads_gpo_usage
);
481 #endif /* HAVE_ADS */