s3-winbindd: rework reconnect logic in winbindd_lookup_sids().
[Samba.git] / source3 / utils / net_rpc_samsync.c
blob772651f8b2883e3404277f81551f93ad90ebd2a1
1 /*
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/>.
26 #include "includes.h"
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,
36 int argc,
37 const char **argv,
38 bool *do_single_object_replication,
39 struct samsync_object **objects,
40 uint32_t *num_objects)
42 int i;
44 if (argc > 0) {
45 *do_single_object_replication = true;
48 for (i=0; i<argc; i++) {
50 struct samsync_object o;
52 ZERO_STRUCT(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,
116 TALLOC_CTX *mem_ctx,
117 int argc,
118 const char **argv)
120 struct samsync_context *ctx = NULL;
121 NTSTATUS status;
123 status = libnet_samsync_init_context(mem_ctx,
124 domain_sid,
125 &ctx);
126 if (!NT_STATUS_IS_OK(status)) {
127 return status;
130 ctx->mode = NET_SAMSYNC_MODE_DUMP;
131 ctx->cli = pipe_hnd;
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,
140 &ctx->objects,
141 &ctx->num_objects);
143 libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
145 libnet_samsync(SAM_DATABASE_BUILTIN, ctx);
147 libnet_samsync(SAM_DATABASE_PRIVS, ctx);
149 TALLOC_FREE(ctx);
151 return NT_STATUS_OK;
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
160 * stripped
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 "
170 "/tmp/tmp.ldif)\n"
171 "\t\t keytab - put account passwords in krb5 keytab "
172 "(defaults to system keytab)\n"));
174 net_common_flags_usage(c, argc, argv);
175 return -1;
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,
183 TALLOC_CTX *mem_ctx,
184 int argc,
185 const char **argv)
187 NTSTATUS status;
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"),
196 domain_name,
197 get_global_sam_name(),
198 sid_string_dbg(get_global_sam_sid()),
199 domain_name,
200 sid_string_dbg(domain_sid),
201 domain_name);
202 return NT_STATUS_UNSUCCESSFUL;
205 status = libnet_dssync_init_context(mem_ctx,
206 &ctx);
207 if (!NT_STATUS_IS_OK(status)) {
208 return status;
211 ctx->cli = pipe_hnd;
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);
218 goto out;
221 if (ctx->result_message) {
222 d_fprintf(stdout, "%s\n", ctx->result_message);
225 out:
226 TALLOC_FREE(ctx);
228 return status;
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,
237 TALLOC_CTX *mem_ctx,
238 int argc,
239 const char **argv)
241 NTSTATUS result;
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"),
250 domain_name,
251 get_global_sam_name(),
252 sid_string_dbg(get_global_sam_sid()),
253 domain_name,
254 sid_string_dbg(domain_sid),
255 domain_name);
256 return NT_STATUS_UNSUCCESSFUL;
259 result = libnet_samsync_init_context(mem_ctx,
260 domain_sid,
261 &ctx);
262 if (!NT_STATUS_IS_OK(result)) {
263 return result;
266 ctx->mode = NET_SAMSYNC_MODE_FETCH_PASSDB;
267 ctx->cli = pipe_hnd;
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,
276 &ctx->objects,
277 &ctx->num_objects);
279 /* fetch domain */
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);
284 goto fail;
287 if (ctx->result_message) {
288 d_fprintf(stdout, "%s\n", ctx->result_message);
291 /* fetch builtin */
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);
298 goto fail;
301 if (ctx->result_message) {
302 d_fprintf(stdout, "%s\n", ctx->result_message);
305 fail:
306 TALLOC_FREE(ctx);
307 return result;
310 int rpc_vampire_passdb(struct net_context *c, int argc, const char **argv)
312 int ret = 0;
313 NTSTATUS status;
314 struct cli_state *cli = NULL;
315 struct net_dc_info dc_info;
317 if (c->display_usage) {
318 d_printf( "%s\n"
319 "net rpc vampire passdb\n"
320 " %s\n",
321 _("Usage:"),
322 _("Dump remote SAM database to passdb"));
323 return 0;
326 status = net_make_ipc_connection(c, 0, &cli);
327 if (!NT_STATUS_IS_OK(status)) {
328 return -1;
331 status = net_scan_dc(c, cli, &dc_info);
332 if (!NT_STATUS_IS_OK(status)) {
333 return -1;
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);
341 return ret;
344 if (!c->opt_force) {
345 d_printf( "%s\n"
346 "net rpc vampire passdb\n"
347 " %s\n",
348 _("Usage:"),
349 _("Should not be used against Active Directory, maybe use --force"));
350 return -1;
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 "
358 "Domain\n"));
359 ret = run_rpc_command(c, cli, &ndr_table_netlogon,
361 rpc_vampire_internals, argc, argv);
364 return ret;
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,
372 TALLOC_CTX *mem_ctx,
373 int argc,
374 const char **argv)
376 NTSTATUS status;
377 struct samsync_context *ctx = NULL;
379 status = libnet_samsync_init_context(mem_ctx,
380 domain_sid,
381 &ctx);
382 if (!NT_STATUS_IS_OK(status)) {
383 return status;
386 if (argc >= 1) {
387 ctx->output_filename = argv[0];
389 if (argc >= 2) {
390 parse_samsync_partial_replication_objects(ctx, argc-1, argv+1,
391 &ctx->single_object_replication,
392 &ctx->objects,
393 &ctx->num_objects);
396 ctx->mode = NET_SAMSYNC_MODE_FETCH_LDIF;
397 ctx->cli = pipe_hnd;
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;
404 /* fetch domain */
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);
409 goto fail;
412 if (ctx->result_message) {
413 d_fprintf(stdout, "%s\n", ctx->result_message);
416 /* fetch builtin */
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);
423 goto fail;
426 if (ctx->result_message) {
427 d_fprintf(stdout, "%s\n", ctx->result_message);
430 fail:
431 TALLOC_FREE(ctx);
432 return status;
435 int rpc_vampire_ldif(struct net_context *c, int argc, const char **argv)
437 if (c->display_usage) {
438 d_printf( "%s\n"
439 "net rpc vampire ldif\n"
440 " %s\n",
441 _("Usage:"),
442 _("Dump remote SAM database to LDIF file or "
443 "stdout"));
444 return 0;
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,
457 TALLOC_CTX *mem_ctx,
458 int argc,
459 const char **argv)
461 NTSTATUS status;
462 struct samsync_context *ctx = NULL;
464 status = libnet_samsync_init_context(mem_ctx,
465 domain_sid,
466 &ctx);
467 if (!NT_STATUS_IS_OK(status)) {
468 return status;
471 if (argc < 1) {
472 /* the caller should ensure that a filename is provided */
473 return NT_STATUS_INVALID_PARAMETER;
474 } else {
475 ctx->output_filename = argv[0];
477 if (argc >= 2) {
478 parse_samsync_partial_replication_objects(ctx, argc-1, argv+1,
479 &ctx->single_object_replication,
480 &ctx->objects,
481 &ctx->num_objects);
484 ctx->mode = NET_SAMSYNC_MODE_FETCH_KEYTAB;
485 ctx->cli = pipe_hnd;
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;
494 /* fetch domain */
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);
499 goto out;
502 if (ctx->result_message) {
503 d_fprintf(stdout, "%s\n", ctx->result_message);
506 out:
507 TALLOC_FREE(ctx);
509 return status;
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,
517 TALLOC_CTX *mem_ctx,
518 int argc,
519 const char **argv)
521 NTSTATUS status;
522 struct dssync_context *ctx = NULL;
524 status = libnet_dssync_init_context(mem_ctx,
525 &ctx);
526 if (!NT_STATUS_IS_OK(status)) {
527 return 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;
533 if (argc < 1) {
534 /* the caller should ensure that a filename is provided */
535 return NT_STATUS_INVALID_PARAMETER;
536 } else {
537 ctx->output_filename = argv[0];
540 if (argc >= 2) {
541 ctx->object_dns = &argv[1];
542 ctx->object_count = argc - 1;
543 ctx->single_object_replication = c->opt_single_obj_repl ? true
544 : false;
547 ctx->cli = pipe_hnd;
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);
554 goto out;
557 if (ctx->result_message) {
558 d_fprintf(stdout, "%s\n", ctx->result_message);
561 out:
562 TALLOC_FREE(ctx);
564 return status;
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
573 * stripped
576 int rpc_vampire_keytab(struct net_context *c, int argc, const char **argv)
578 int ret = 0;
579 NTSTATUS status;
580 struct cli_state *cli = NULL;
581 struct net_dc_info dc_info;
583 if (c->display_usage || (argc < 1)) {
584 d_printf("%s\n%s",
585 _("Usage:"),
586 _("net rpc vampire keytab <keytabfile>\n"
587 " Dump remote SAM database to Kerberos keytab "
588 "file\n"));
589 return 0;
592 status = net_make_ipc_connection(c, 0, &cli);
593 if (!NT_STATUS_IS_OK(status)) {
594 return -1;
597 status = net_scan_dc(c, cli, &dc_info);
598 if (!NT_STATUS_IS_OK(status)) {
599 return -1;
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);
607 } else {
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 "
613 "Domain\n"));
614 ret = run_rpc_command(c, cli, &ndr_table_netlogon,
616 rpc_vampire_keytab_internals, argc, argv);
617 } else {
618 #ifndef HAVE_ADS
619 printf(_("Vampire requested against AD DC but ADS"
620 " support not built in: HAVE_ADS is not defined\n"));
621 #endif
625 return ret;