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 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
;
53 struct GROUP_POLICY_OBJECT
*gpo
;
55 struct nt_user_token
*token
= NULL
;
58 printf("usage: net ads gpo refresh <username|machinename>\n");
62 mem_ctx
= talloc_init("net_ads_gpo_refresh");
63 if (mem_ctx
== NULL
) {
67 status
= ads_startup(False
, &ads
);
68 if (!ADS_ERR_OK(status
)) {
72 status
= ads_find_samaccount(ads
, mem_ctx
, argv
[0], &uac
, &dn
);
73 if (!ADS_ERR_OK(status
)) {
74 printf("failed to find samaccount for %s\n", argv
[0]);
78 if (uac
& UF_WORKSTATION_TRUST_ACCOUNT
) {
79 flags
|= GPO_LIST_FLAG_MACHINE
;
82 printf("\n%s: '%s' has dn: '%s'\n\n",
83 (uac
& UF_WORKSTATION_TRUST_ACCOUNT
) ? "machine" : "user",
86 status
= ads_get_sid_token(ads
, mem_ctx
, dn
, &token
);
87 if (!ADS_ERR_OK(status
)) {
91 status
= ads_get_gpo_list(ads
, mem_ctx
, dn
, flags
, token
, &gpo_list
);
92 if (!ADS_ERR_OK(status
)) {
96 if (!NT_STATUS_IS_OK(result
= check_refresh_gpo_list(ads
, mem_ctx
, flags
, gpo_list
))) {
97 printf("failed to refresh GPOs: %s\n", nt_errstr(result
));
101 for (gpo
= gpo_list
; gpo
; gpo
= gpo
->next
) {
103 char *server
, *share
, *nt_path
, *unix_path
;
105 printf("--------------------------------------\n");
106 printf("Name:\t\t\t%s\n", gpo
->display_name
);
107 printf("LDAP GPO version:\t%d (user: %d, machine: %d)\n",
109 GPO_VERSION_USER(gpo
->version
),
110 GPO_VERSION_MACHINE(gpo
->version
));
112 result
= gpo_explode_filesyspath(mem_ctx
, gpo
->file_sys_path
,
113 &server
, &share
, &nt_path
, &unix_path
);
114 if (!NT_STATUS_IS_OK(result
)) {
115 printf("got: %s\n", nt_errstr(result
));
118 printf("GPO stored on server: %s, share: %s\n", server
, share
);
119 printf("\tremote path:\t%s\n", nt_path
);
120 printf("\tlocal path:\t%s\n", unix_path
);
125 talloc_destroy(mem_ctx
);
129 static int net_ads_gpo_list_all(int argc
, const char **argv
)
133 LDAPMessage
*res
= NULL
;
135 LDAPMessage
*msg
= NULL
;
136 struct GROUP_POLICY_OBJECT gpo
;
139 const char *attrs
[] = {
145 "gPCMachineExtensionNames",
146 "gPCUserExtensionNames",
147 "ntSecurityDescriptor",
151 mem_ctx
= talloc_init("net_ads_gpo_list_all");
152 if (mem_ctx
== NULL
) {
156 status
= ads_startup(False
, &ads
);
157 if (!ADS_ERR_OK(status
)) {
161 status
= ads_do_search_all_sd_flags(ads
, ads
->config
.bind_path
,
163 "(objectclass=groupPolicyContainer)",
165 DACL_SECURITY_INFORMATION
,
168 if (!ADS_ERR_OK(status
)) {
169 d_printf("search failed: %s\n", ads_errstr(status
));
173 num_reply
= ads_count_replies(ads
, res
);
175 d_printf("Got %d replies\n\n", num_reply
);
177 /* dump the results */
178 for (msg
= ads_first_entry(ads
, res
); msg
; msg
= ads_next_entry(ads
, msg
)) {
180 if ((dn
= ads_get_dn(ads
, msg
)) == NULL
) {
184 status
= ads_parse_gpo(ads
, mem_ctx
, msg
, dn
, &gpo
);
186 if (!ADS_ERR_OK(status
)) {
187 d_printf("ads_parse_gpo failed: %s\n", ads_errstr(status
));
188 ads_memfree(ads
, dn
);
192 dump_gpo(ads
, mem_ctx
, &gpo
, 0);
193 ads_memfree(ads
, dn
);
197 ads_msgfree(ads
, res
);
199 talloc_destroy(mem_ctx
);
205 static int net_ads_gpo_list(int argc
, const char **argv
)
209 LDAPMessage
*res
= NULL
;
211 const char *dn
= NULL
;
214 struct GROUP_POLICY_OBJECT
*gpo_list
;
215 struct nt_user_token
*token
= NULL
;
218 printf("usage: net ads gpo list <username|machinename>\n");
222 mem_ctx
= talloc_init("net_ads_gpo_list");
223 if (mem_ctx
== NULL
) {
227 status
= ads_startup(False
, &ads
);
228 if (!ADS_ERR_OK(status
)) {
232 status
= ads_find_samaccount(ads
, mem_ctx
, argv
[0], &uac
, &dn
);
233 if (!ADS_ERR_OK(status
)) {
237 if (uac
& UF_WORKSTATION_TRUST_ACCOUNT
) {
238 flags
|= GPO_LIST_FLAG_MACHINE
;
241 printf("%s: '%s' has dn: '%s'\n",
242 (uac
& UF_WORKSTATION_TRUST_ACCOUNT
) ? "machine" : "user",
245 status
= ads_get_sid_token(ads
, mem_ctx
, dn
, &token
);
246 if (!ADS_ERR_OK(status
)) {
250 status
= ads_get_gpo_list(ads
, mem_ctx
, dn
, flags
, token
, &gpo_list
);
251 if (!ADS_ERR_OK(status
)) {
255 dump_gpo_list(ads
, mem_ctx
, gpo_list
, 0);
258 ads_msgfree(ads
, res
);
260 talloc_destroy(mem_ctx
);
267 static int net_ads_gpo_apply(int argc
, const char **argv
)
272 const char *dn
= NULL
;
273 struct GROUP_POLICY_OBJECT
*gpo_list
;
278 printf("usage: net ads gpo apply <username|machinename>\n");
282 mem_ctx
= talloc_init("net_ads_gpo_apply");
283 if (mem_ctx
== NULL
) {
287 status
= ads_startup(False
, &ads
);
288 if (!ADS_ERR_OK(status
)) {
292 status
= ads_find_samaccount(ads
, mem_ctx
, argv
[0], &uac
, &dn
);
293 if (!ADS_ERR_OK(status
)) {
297 if (uac
& UF_WORKSTATION_TRUST_ACCOUNT
) {
298 flags
|= GPO_LIST_FLAG_MACHINE
;
301 printf("%s: '%s' has dn: '%s'\n",
302 (uac
& UF_WORKSTATION_TRUST_ACCOUNT
) ? "machine" : "user",
305 status
= ads_get_gpo_list(ads
, mem_ctx
, dn
, flags
, &gpo_list
);
306 if (!ADS_ERR_OK(status
)) {
310 /* FIXME: allow to process just a single extension */
311 status
= gpo_process_gpo_list(ads
, mem_ctx
, gpo_list
, NULL
, flags
);
312 if (!ADS_ERR_OK(status
)) {
318 talloc_destroy(mem_ctx
);
324 static int net_ads_gpo_link_get(int argc
, const char **argv
)
329 struct GP_LINK gp_link
;
332 printf("usage: net ads gpo linkget <linkname>\n");
336 mem_ctx
= talloc_init("add_gpo_link");
337 if (mem_ctx
== NULL
) {
341 status
= ads_startup(False
, &ads
);
342 if (!ADS_ERR_OK(status
)) {
346 status
= ads_get_gpo_link(ads
, mem_ctx
, argv
[0], &gp_link
);
347 if (!ADS_ERR_OK(status
)) {
348 d_printf("get link for %s failed: %s\n", argv
[0], ads_errstr(status
));
352 dump_gplink(ads
, mem_ctx
, &gp_link
);
355 talloc_destroy(mem_ctx
);
361 static int net_ads_gpo_link_add(int argc
, const char **argv
)
369 printf("usage: net ads gpo linkadd <linkdn> <gpodn> [options]\n");
370 printf("note: DNs must be provided properly escaped.\n See RFC 4514 for details\n");
374 mem_ctx
= talloc_init("add_gpo_link");
375 if (mem_ctx
== NULL
) {
380 gpo_opt
= atoi(argv
[2]);
383 status
= ads_startup(False
, &ads
);
384 if (!ADS_ERR_OK(status
)) {
388 status
= ads_add_gpo_link(ads
, mem_ctx
, argv
[0], argv
[1], gpo_opt
);
389 if (!ADS_ERR_OK(status
)) {
390 d_printf("link add failed: %s\n", ads_errstr(status
));
395 talloc_destroy(mem_ctx
);
403 static int net_ads_gpo_link_delete(int argc
, const char **argv
)
413 mem_ctx
= talloc_init("delete_gpo_link");
414 if (mem_ctx
== NULL
) {
418 status
= ads_startup(False
, &ads
);
419 if (!ADS_ERR_OK(status
)) {
423 status
= ads_delete_gpo_link(ads
, mem_ctx
, argv
[0], argv
[1]);
424 if (!ADS_ERR_OK(status
)) {
425 d_printf("delete link failed: %s\n", ads_errstr(status
));
430 talloc_destroy(mem_ctx
);
438 static int net_ads_gpo_get_gpo(int argc
, const char **argv
)
443 struct GROUP_POLICY_OBJECT gpo
;
446 printf("usage: net ads gpo getgpo <gpo>\n");
450 mem_ctx
= talloc_init("add_gpo_get_gpo");
451 if (mem_ctx
== NULL
) {
455 status
= ads_startup(False
, &ads
);
456 if (!ADS_ERR_OK(status
)) {
460 if (strnequal(argv
[0], "CN={", strlen("CN={"))) {
461 status
= ads_get_gpo(ads
, mem_ctx
, argv
[0], NULL
, NULL
, &gpo
);
463 status
= ads_get_gpo(ads
, mem_ctx
, NULL
, argv
[0], NULL
, &gpo
);
466 if (!ADS_ERR_OK(status
)) {
467 d_printf("get gpo for [%s] failed: %s\n", argv
[0], ads_errstr(status
));
471 dump_gpo(ads
, mem_ctx
, &gpo
, 1);
474 talloc_destroy(mem_ctx
);
480 int net_ads_gpo(int argc
, const char **argv
)
482 struct functable func
[] = {
483 /* {"APPLY", net_ads_gpo_apply}, */
484 {"GETGPO", net_ads_gpo_get_gpo
},
485 {"HELP", net_ads_gpo_usage
},
486 {"LINKADD", net_ads_gpo_link_add
},
487 /* {"LINKDELETE", net_ads_gpo_link_delete}, */
488 {"LINKGET", net_ads_gpo_link_get
},
489 {"LIST", net_ads_gpo_list
},
490 {"LISTALL", net_ads_gpo_list_all
},
491 {"REFRESH", net_ads_gpo_refresh
},
495 return net_run_function(argc
, argv
, func
, net_ads_gpo_usage
);
498 #endif /* HAVE_ADS */