2 Unix SMB/CIFS implementation.
3 dump the remote SAM using rpc samsync operations
5 Copyright (C) Andrew Tridgell 2002
6 Copyright (C) Tim Potter 2001,2002
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005
8 Modified by Volker Lendecke 2002
9 Copyright (C) Jeremy Allison 2005.
10 Copyright (C) Guenther Deschner 2008.
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include "utils/net.h"
28 #include "../librpc/gen_ndr/ndr_netlogon.h"
29 #include "../librpc/gen_ndr/ndr_drsuapi.h"
30 #include "libnet/libnet_samsync.h"
31 #include "libnet/libnet_dssync.h"
32 #include "../libcli/security/security.h"
33 #include "passdb/machine_sid.h"
35 static void parse_samsync_partial_replication_objects(TALLOC_CTX *mem_ctx,
38 bool *do_single_object_replication,
39 struct samsync_object **objects,
40 uint32_t *num_objects)
45 *do_single_object_replication = true;
48 for (i=0; i<argc; i++) {
50 struct samsync_object o;
54 if (!strncasecmp_m(argv[i], "user_rid=", strlen("user_rid="))) {
55 o.object_identifier.rid = get_int_param(argv[i]);
56 o.object_type = NETR_DELTA_USER;
57 o.database_id = SAM_DATABASE_DOMAIN;
59 if (!strncasecmp_m(argv[i], "group_rid=", strlen("group_rid="))) {
60 o.object_identifier.rid = get_int_param(argv[i]);
61 o.object_type = NETR_DELTA_GROUP;
62 o.database_id = SAM_DATABASE_DOMAIN;
64 if (!strncasecmp_m(argv[i], "group_member_rid=", strlen("group_member_rid="))) {
65 o.object_identifier.rid = get_int_param(argv[i]);
66 o.object_type = NETR_DELTA_GROUP_MEMBER;
67 o.database_id = SAM_DATABASE_DOMAIN;
69 if (!strncasecmp_m(argv[i], "alias_rid=", strlen("alias_rid="))) {
70 o.object_identifier.rid = get_int_param(argv[i]);
71 o.object_type = NETR_DELTA_ALIAS;
72 o.database_id = SAM_DATABASE_BUILTIN;
74 if (!strncasecmp_m(argv[i], "alias_member_rid=", strlen("alias_member_rid="))) {
75 o.object_identifier.rid = get_int_param(argv[i]);
76 o.object_type = NETR_DELTA_ALIAS_MEMBER;
77 o.database_id = SAM_DATABASE_BUILTIN;
79 if (!strncasecmp_m(argv[i], "account_sid=", strlen("account_sid="))) {
80 const char *sid_str = get_string_param(argv[i]);
81 string_to_sid(&o.object_identifier.sid, sid_str);
82 o.object_type = NETR_DELTA_ACCOUNT;
83 o.database_id = SAM_DATABASE_PRIVS;
85 if (!strncasecmp_m(argv[i], "policy_sid=", strlen("policy_sid="))) {
86 const char *sid_str = get_string_param(argv[i]);
87 string_to_sid(&o.object_identifier.sid, sid_str);
88 o.object_type = NETR_DELTA_POLICY;
89 o.database_id = SAM_DATABASE_PRIVS;
91 if (!strncasecmp_m(argv[i], "trustdom_sid=", strlen("trustdom_sid="))) {
92 const char *sid_str = get_string_param(argv[i]);
93 string_to_sid(&o.object_identifier.sid, sid_str);
94 o.object_type = NETR_DELTA_TRUSTED_DOMAIN;
95 o.database_id = SAM_DATABASE_PRIVS;
97 if (!strncasecmp_m(argv[i], "secret_name=", strlen("secret_name="))) {
98 o.object_identifier.name = get_string_param(argv[i]);
99 o.object_type = NETR_DELTA_SECRET;
100 o.database_id = SAM_DATABASE_PRIVS;
103 if (o.object_type > 0) {
104 ADD_TO_ARRAY(mem_ctx, struct samsync_object, o,
105 objects, num_objects);
110 /* dump sam database via samsync rpc calls */
111 NTSTATUS rpc_samdump_internals(struct net_context *c,
112 const struct dom_sid *domain_sid,
113 const char *domain_name,
114 struct cli_state *cli,
115 struct rpc_pipe_client *pipe_hnd,
120 struct samsync_context *ctx = NULL;
123 status = libnet_samsync_init_context(mem_ctx,
126 if (!NT_STATUS_IS_OK(status)) {
130 ctx->mode = NET_SAMSYNC_MODE_DUMP;
132 ctx->ops = &libnet_samsync_display_ops;
133 ctx->domain_name = domain_name;
135 ctx->force_full_replication = c->opt_force_full_repl ? true : false;
136 ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
138 parse_samsync_partial_replication_objects(ctx, argc, argv,
139 &ctx->single_object_replication,
143 libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
145 libnet_samsync(SAM_DATABASE_BUILTIN, ctx);
147 libnet_samsync(SAM_DATABASE_PRIVS, ctx);
155 * Basic usage function for 'net rpc vampire'
157 * @param c A net_context structure
158 * @param argc Standard main() style argc
159 * @param argc Standard main() style argv. Initial components are already
163 int rpc_vampire_usage(struct net_context *c, int argc, const char **argv)
165 d_printf(_("net rpc vampire ([ldif [<ldif-filename>] | [keytab] "
166 "[<keytab-filename]) [options]\n"
167 "\t to pull accounts from a remote PDC where we are a BDC\n"
168 "\t\t no args puts accounts in local passdb from smb.conf\n"
169 "\t\t ldif - put accounts in ldif format (file defaults to "
171 "\t\t keytab - put account passwords in krb5 keytab "
172 "(defaults to system keytab)\n"));
174 net_common_flags_usage(c, argc, argv);
178 static NTSTATUS rpc_vampire_ds_internals(struct net_context *c,
179 const struct dom_sid *domain_sid,
180 const char *domain_name,
181 struct cli_state *cli,
182 struct rpc_pipe_client *pipe_hnd,
188 struct dssync_context *ctx = NULL;
190 if (!dom_sid_equal(domain_sid, get_global_sam_sid())) {
191 d_printf(_("Cannot import users from %s at this time, "
192 "as the current domain:\n\t%s: %s\nconflicts "
193 "with the remote domain\n\t%s: %s\n"
194 "Perhaps you need to set: \n\n\tsecurity=user\n\t"
195 "workgroup=%s\n\n in your smb.conf?\n"),
197 get_global_sam_name(),
198 sid_string_dbg(get_global_sam_sid()),
200 sid_string_dbg(domain_sid),
202 return NT_STATUS_UNSUCCESSFUL;
205 status = libnet_dssync_init_context(mem_ctx,
207 if (!NT_STATUS_IS_OK(status)) {
212 ctx->domain_name = domain_name;
213 ctx->ops = &libnet_dssync_passdb_ops;
215 status = libnet_dssync(mem_ctx, ctx);
216 if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
217 d_fprintf(stderr, "%s\n", ctx->error_message);
221 if (ctx->result_message) {
222 d_fprintf(stdout, "%s\n", ctx->result_message);
231 /* dump sam database via samsync rpc calls */
232 static NTSTATUS rpc_vampire_internals(struct net_context *c,
233 const struct dom_sid *domain_sid,
234 const char *domain_name,
235 struct cli_state *cli,
236 struct rpc_pipe_client *pipe_hnd,
242 struct samsync_context *ctx = NULL;
244 if (!dom_sid_equal(domain_sid, get_global_sam_sid())) {
245 d_printf(_("Cannot import users from %s at this time, "
246 "as the current domain:\n\t%s: %s\nconflicts "
247 "with the remote domain\n\t%s: %s\n"
248 "Perhaps you need to set: \n\n\tsecurity=user\n\t"
249 "workgroup=%s\n\n in your smb.conf?\n"),
251 get_global_sam_name(),
252 sid_string_dbg(get_global_sam_sid()),
254 sid_string_dbg(domain_sid),
256 return NT_STATUS_UNSUCCESSFUL;
259 result = libnet_samsync_init_context(mem_ctx,
262 if (!NT_STATUS_IS_OK(result)) {
266 ctx->mode = NET_SAMSYNC_MODE_FETCH_PASSDB;
268 ctx->ops = &libnet_samsync_passdb_ops;
269 ctx->domain_name = domain_name;
271 ctx->force_full_replication = c->opt_force_full_repl ? true : false;
272 ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
274 parse_samsync_partial_replication_objects(ctx, argc, argv,
275 &ctx->single_object_replication,
280 result = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
282 if (!NT_STATUS_IS_OK(result) && ctx->error_message) {
283 d_fprintf(stderr, "%s\n", ctx->error_message);
287 if (ctx->result_message) {
288 d_fprintf(stdout, "%s\n", ctx->result_message);
292 ctx->domain_sid = dom_sid_dup(mem_ctx, &global_sid_Builtin);
293 ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid);
294 result = libnet_samsync(SAM_DATABASE_BUILTIN, ctx);
296 if (!NT_STATUS_IS_OK(result) && ctx->error_message) {
297 d_fprintf(stderr, "%s\n", ctx->error_message);
301 if (ctx->result_message) {
302 d_fprintf(stdout, "%s\n", ctx->result_message);
310 int rpc_vampire_passdb(struct net_context *c, int argc, const char **argv)
314 struct cli_state *cli = NULL;
315 struct net_dc_info dc_info;
317 if (c->display_usage) {
319 "net rpc vampire passdb\n"
322 _("Dump remote SAM database to passdb"));
326 status = net_make_ipc_connection(c, 0, &cli);
327 if (!NT_STATUS_IS_OK(status)) {
331 status = net_scan_dc(c, cli, &dc_info);
332 if (!NT_STATUS_IS_OK(status)) {
336 if (!dc_info.is_ad) {
337 printf(_("DC is not running Active Directory\n"));
338 ret = run_rpc_command(c, cli, &ndr_table_netlogon,
340 rpc_vampire_internals, argc, argv);
346 "net rpc vampire passdb\n"
349 _("Should not be used against Active Directory, maybe use --force"));
353 ret = run_rpc_command(c, cli, &ndr_table_drsuapi,
354 NET_FLAGS_SEAL | NET_FLAGS_TCP,
355 rpc_vampire_ds_internals, argc, argv);
356 if (ret != 0 && dc_info.is_mixed_mode) {
357 printf(_("Fallback to NT4 vampire on Mixed-Mode AD "
359 ret = run_rpc_command(c, cli, &ndr_table_netlogon,
361 rpc_vampire_internals, argc, argv);
367 static NTSTATUS rpc_vampire_ldif_internals(struct net_context *c,
368 const struct dom_sid *domain_sid,
369 const char *domain_name,
370 struct cli_state *cli,
371 struct rpc_pipe_client *pipe_hnd,
377 struct samsync_context *ctx = NULL;
379 status = libnet_samsync_init_context(mem_ctx,
382 if (!NT_STATUS_IS_OK(status)) {
387 ctx->output_filename = argv[0];
390 parse_samsync_partial_replication_objects(ctx, argc-1, argv+1,
391 &ctx->single_object_replication,
396 ctx->mode = NET_SAMSYNC_MODE_FETCH_LDIF;
398 ctx->ops = &libnet_samsync_ldif_ops;
399 ctx->domain_name = domain_name;
401 ctx->force_full_replication = c->opt_force_full_repl ? true : false;
402 ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
405 status = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
407 if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
408 d_fprintf(stderr, "%s\n", ctx->error_message);
412 if (ctx->result_message) {
413 d_fprintf(stdout, "%s\n", ctx->result_message);
417 ctx->domain_sid = dom_sid_dup(mem_ctx, &global_sid_Builtin);
418 ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid);
419 status = libnet_samsync(SAM_DATABASE_BUILTIN, ctx);
421 if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
422 d_fprintf(stderr, "%s\n", ctx->error_message);
426 if (ctx->result_message) {
427 d_fprintf(stdout, "%s\n", ctx->result_message);
435 int rpc_vampire_ldif(struct net_context *c, int argc, const char **argv)
437 if (c->display_usage) {
439 "net rpc vampire ldif\n"
442 _("Dump remote SAM database to LDIF file or "
447 return run_rpc_command(c, NULL, &ndr_table_netlogon, 0,
448 rpc_vampire_ldif_internals, argc, argv);
452 static NTSTATUS rpc_vampire_keytab_internals(struct net_context *c,
453 const struct dom_sid *domain_sid,
454 const char *domain_name,
455 struct cli_state *cli,
456 struct rpc_pipe_client *pipe_hnd,
462 struct samsync_context *ctx = NULL;
464 status = libnet_samsync_init_context(mem_ctx,
467 if (!NT_STATUS_IS_OK(status)) {
472 /* the caller should ensure that a filename is provided */
473 return NT_STATUS_INVALID_PARAMETER;
475 ctx->output_filename = argv[0];
478 parse_samsync_partial_replication_objects(ctx, argc-1, argv+1,
479 &ctx->single_object_replication,
484 ctx->mode = NET_SAMSYNC_MODE_FETCH_KEYTAB;
486 ctx->ops = &libnet_samsync_keytab_ops;
487 ctx->domain_name = domain_name;
488 ctx->username = c->opt_user_name;
489 ctx->password = c->opt_password;
491 ctx->force_full_replication = c->opt_force_full_repl ? true : false;
492 ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
495 status = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
497 if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
498 d_fprintf(stderr, "%s\n", ctx->error_message);
502 if (ctx->result_message) {
503 d_fprintf(stdout, "%s\n", ctx->result_message);
512 static NTSTATUS rpc_vampire_keytab_ds_internals(struct net_context *c,
513 const struct dom_sid *domain_sid,
514 const char *domain_name,
515 struct cli_state *cli,
516 struct rpc_pipe_client *pipe_hnd,
522 struct dssync_context *ctx = NULL;
524 status = libnet_dssync_init_context(mem_ctx,
526 if (!NT_STATUS_IS_OK(status)) {
530 ctx->force_full_replication = c->opt_force_full_repl ? true : false;
531 ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
534 /* the caller should ensure that a filename is provided */
535 return NT_STATUS_INVALID_PARAMETER;
537 ctx->output_filename = argv[0];
541 ctx->object_dns = &argv[1];
542 ctx->object_count = argc - 1;
543 ctx->single_object_replication = c->opt_single_obj_repl ? true
548 ctx->domain_name = domain_name;
549 ctx->ops = &libnet_dssync_keytab_ops;
551 status = libnet_dssync(mem_ctx, ctx);
552 if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
553 d_fprintf(stderr, "%s\n", ctx->error_message);
557 if (ctx->result_message) {
558 d_fprintf(stdout, "%s\n", ctx->result_message);
568 * Basic function for 'net rpc vampire keytab'
570 * @param c A net_context structure
571 * @param argc Standard main() style argc
572 * @param argc Standard main() style argv. Initial components are already
576 int rpc_vampire_keytab(struct net_context *c, int argc, const char **argv)
580 struct cli_state *cli = NULL;
581 struct net_dc_info dc_info;
583 if (c->display_usage || (argc < 1)) {
586 _("net rpc vampire keytab <keytabfile>\n"
587 " Dump remote SAM database to Kerberos keytab "
592 status = net_make_ipc_connection(c, 0, &cli);
593 if (!NT_STATUS_IS_OK(status)) {
597 status = net_scan_dc(c, cli, &dc_info);
598 if (!NT_STATUS_IS_OK(status)) {
602 if (!dc_info.is_ad) {
603 printf(_("DC is not running Active Directory\n"));
604 ret = run_rpc_command(c, cli, &ndr_table_netlogon,
606 rpc_vampire_keytab_internals, argc, argv);
608 ret = run_rpc_command(c, cli, &ndr_table_drsuapi,
609 NET_FLAGS_SEAL | NET_FLAGS_TCP,
610 rpc_vampire_keytab_ds_internals, argc, argv);
611 if (ret != 0 && dc_info.is_mixed_mode) {
612 printf(_("Fallback to NT4 vampire on Mixed-Mode AD "
614 ret = run_rpc_command(c, cli, &ndr_table_netlogon,
616 rpc_vampire_keytab_internals, argc, argv);
619 printf(_("Vampire requested against AD DC but ADS"
620 " support not built in: HAVE_ADS is not defined\n"));