cli: do not dump libarchive absence warning on startup
[kai/samba-autobuild/.git] / source3 / utils / net_rpc_samsync.c
1 /*
2    Unix SMB/CIFS implementation.
3    dump the remote SAM using rpc samsync operations
4
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.
11
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.
16
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.
21
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/>.
24 */
25
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"
34
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)
41 {
42         int i;
43
44         if (argc > 0) {
45                 *do_single_object_replication = true;
46         }
47
48         for (i=0; i<argc; i++) {
49
50                 struct samsync_object o;
51
52                 ZERO_STRUCT(o);
53
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;
58                 }
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;
63                 }
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;
68                 }
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;
73                 }
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;
78                 }
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;
84                 }
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;
90                 }
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;
96                 }
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;
101                 }
102
103                 if (o.object_type > 0) {
104                         ADD_TO_ARRAY(mem_ctx, struct samsync_object, o,
105                                      objects, num_objects);
106                 }
107         }
108 }
109
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)
119 {
120         struct samsync_context *ctx = NULL;
121         NTSTATUS status;
122
123         status = libnet_samsync_init_context(mem_ctx,
124                                              domain_sid,
125                                              &ctx);
126         if (!NT_STATUS_IS_OK(status)) {
127                 return status;
128         }
129
130         ctx->mode               = NET_SAMSYNC_MODE_DUMP;
131         ctx->cli                = pipe_hnd;
132         ctx->netlogon_creds     = c->netlogon_creds;
133         ctx->ops                = &libnet_samsync_display_ops;
134         ctx->domain_name        = domain_name;
135
136         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
137         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
138
139         parse_samsync_partial_replication_objects(ctx, argc, argv,
140                                                   &ctx->single_object_replication,
141                                                   &ctx->objects,
142                                                   &ctx->num_objects);
143
144         libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
145
146         libnet_samsync(SAM_DATABASE_BUILTIN, ctx);
147
148         libnet_samsync(SAM_DATABASE_PRIVS, ctx);
149
150         TALLOC_FREE(ctx);
151
152         return NT_STATUS_OK;
153 }
154
155 /**
156  * Basic usage function for 'net rpc vampire'
157  *
158  * @param c     A net_context structure
159  * @param argc  Standard main() style argc
160  * @param argc  Standard main() style argv.  Initial components are already
161  *              stripped
162  **/
163
164 int rpc_vampire_usage(struct net_context *c, int argc, const char **argv)
165 {
166         d_printf(_("net rpc vampire ([ldif [<ldif-filename>] | [keytab] "
167                    "[<keytab-filename]) [options]\n"
168                    "\t to pull accounts from a remote PDC where we are a BDC\n"
169                    "\t\t no args puts accounts in local passdb from smb.conf\n"
170                    "\t\t ldif - put accounts in ldif format (file defaults to "
171                    "/tmp/tmp.ldif)\n"
172                    "\t\t keytab - put account passwords in krb5 keytab "
173                    "(defaults to system keytab)\n"));
174
175         net_common_flags_usage(c, argc, argv);
176         return -1;
177 }
178
179 static NTSTATUS rpc_vampire_ds_internals(struct net_context *c,
180                                          const struct dom_sid *domain_sid,
181                                          const char *domain_name,
182                                          struct cli_state *cli,
183                                          struct rpc_pipe_client *pipe_hnd,
184                                          TALLOC_CTX *mem_ctx,
185                                          int argc,
186                                          const char **argv)
187 {
188         NTSTATUS status;
189         struct dssync_context *ctx = NULL;
190
191         if (!dom_sid_equal(domain_sid, get_global_sam_sid())) {
192                 d_printf(_("Cannot import users from %s at this time, "
193                            "as the current domain:\n\t%s: %s\nconflicts "
194                            "with the remote domain\n\t%s: %s\n"
195                            "Perhaps you need to set: \n\n\tsecurity=user\n\t"
196                            "workgroup=%s\n\n in your smb.conf?\n"),
197                          domain_name,
198                          get_global_sam_name(),
199                          sid_string_dbg(get_global_sam_sid()),
200                          domain_name,
201                          sid_string_dbg(domain_sid),
202                          domain_name);
203                 return NT_STATUS_UNSUCCESSFUL;
204         }
205
206         status = libnet_dssync_init_context(mem_ctx,
207                                             &ctx);
208         if (!NT_STATUS_IS_OK(status)) {
209                 return status;
210         }
211
212         ctx->cli                = pipe_hnd;
213         ctx->domain_name        = domain_name;
214         ctx->ops                = &libnet_dssync_passdb_ops;
215
216         status = libnet_dssync(mem_ctx, ctx);
217         if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
218                 d_fprintf(stderr, "%s\n", ctx->error_message);
219                 goto out;
220         }
221
222         if (ctx->result_message) {
223                 d_fprintf(stdout, "%s\n", ctx->result_message);
224         }
225
226  out:
227         TALLOC_FREE(ctx);
228
229         return status;
230 }
231
232 /* dump sam database via samsync rpc calls */
233 static NTSTATUS rpc_vampire_internals(struct net_context *c,
234                                       const struct dom_sid *domain_sid,
235                                       const char *domain_name,
236                                       struct cli_state *cli,
237                                       struct rpc_pipe_client *pipe_hnd,
238                                       TALLOC_CTX *mem_ctx,
239                                       int argc,
240                                       const char **argv)
241 {
242         NTSTATUS result;
243         struct samsync_context *ctx = NULL;
244
245         if (!dom_sid_equal(domain_sid, get_global_sam_sid())) {
246                 d_printf(_("Cannot import users from %s at this time, "
247                            "as the current domain:\n\t%s: %s\nconflicts "
248                            "with the remote domain\n\t%s: %s\n"
249                            "Perhaps you need to set: \n\n\tsecurity=user\n\t"
250                            "workgroup=%s\n\n in your smb.conf?\n"),
251                          domain_name,
252                          get_global_sam_name(),
253                          sid_string_dbg(get_global_sam_sid()),
254                          domain_name,
255                          sid_string_dbg(domain_sid),
256                          domain_name);
257                 return NT_STATUS_UNSUCCESSFUL;
258         }
259
260         result = libnet_samsync_init_context(mem_ctx,
261                                              domain_sid,
262                                              &ctx);
263         if (!NT_STATUS_IS_OK(result)) {
264                 return result;
265         }
266
267         ctx->mode               = NET_SAMSYNC_MODE_FETCH_PASSDB;
268         ctx->cli                = pipe_hnd;
269         ctx->ops                = &libnet_samsync_passdb_ops;
270         ctx->domain_name        = domain_name;
271
272         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
273         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
274
275         parse_samsync_partial_replication_objects(ctx, argc, argv,
276                                                   &ctx->single_object_replication,
277                                                   &ctx->objects,
278                                                   &ctx->num_objects);
279
280         /* fetch domain */
281         result = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
282
283         if (!NT_STATUS_IS_OK(result) && ctx->error_message) {
284                 d_fprintf(stderr, "%s\n", ctx->error_message);
285                 goto fail;
286         }
287
288         if (ctx->result_message) {
289                 d_fprintf(stdout, "%s\n", ctx->result_message);
290         }
291
292         /* fetch builtin */
293         ctx->domain_sid = dom_sid_dup(mem_ctx, &global_sid_Builtin);
294         ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid);
295         result = libnet_samsync(SAM_DATABASE_BUILTIN, ctx);
296
297         if (!NT_STATUS_IS_OK(result) && ctx->error_message) {
298                 d_fprintf(stderr, "%s\n", ctx->error_message);
299                 goto fail;
300         }
301
302         if (ctx->result_message) {
303                 d_fprintf(stdout, "%s\n", ctx->result_message);
304         }
305
306  fail:
307         TALLOC_FREE(ctx);
308         return result;
309 }
310
311 int rpc_vampire_passdb(struct net_context *c, int argc, const char **argv)
312 {
313         int ret = 0;
314         NTSTATUS status;
315         struct cli_state *cli = NULL;
316         struct net_dc_info dc_info;
317
318         if (c->display_usage) {
319                 d_printf(  "%s\n"
320                            "net rpc vampire passdb\n"
321                            "    %s\n",
322                          _("Usage:"),
323                          _("Dump remote SAM database to passdb"));
324                 return 0;
325         }
326
327         status = net_make_ipc_connection(c, 0, &cli);
328         if (!NT_STATUS_IS_OK(status)) {
329                 return -1;
330         }
331
332         status = net_scan_dc(c, cli, &dc_info);
333         if (!NT_STATUS_IS_OK(status)) {
334                 return -1;
335         }
336
337         if (!dc_info.is_ad) {
338                 printf(_("DC is not running Active Directory\n"));
339                 ret = run_rpc_command(c, cli, &ndr_table_netlogon,
340                                       0,
341                                       rpc_vampire_internals, argc, argv);
342                 return ret;
343         }
344
345         if (!c->opt_force) {
346                 d_printf(  "%s\n"
347                            "net rpc vampire passdb\n"
348                            "    %s\n",
349                          _("Usage:"),
350                          _("Should not be used against Active Directory, maybe use --force"));
351                 return -1;
352         }
353
354         ret = run_rpc_command(c, cli, &ndr_table_drsuapi,
355                               NET_FLAGS_SEAL | NET_FLAGS_TCP,
356                               rpc_vampire_ds_internals, argc, argv);
357         if (ret != 0 && dc_info.is_mixed_mode) {
358                 printf(_("Fallback to NT4 vampire on Mixed-Mode AD "
359                          "Domain\n"));
360                 ret = run_rpc_command(c, cli, &ndr_table_netlogon,
361                                       0,
362                                       rpc_vampire_internals, argc, argv);
363         }
364
365         return ret;
366 }
367
368 static NTSTATUS rpc_vampire_ldif_internals(struct net_context *c,
369                                            const struct dom_sid *domain_sid,
370                                            const char *domain_name,
371                                            struct cli_state *cli,
372                                            struct rpc_pipe_client *pipe_hnd,
373                                            TALLOC_CTX *mem_ctx,
374                                            int argc,
375                                            const char **argv)
376 {
377         NTSTATUS status;
378         struct samsync_context *ctx = NULL;
379
380         status = libnet_samsync_init_context(mem_ctx,
381                                              domain_sid,
382                                              &ctx);
383         if (!NT_STATUS_IS_OK(status)) {
384                 return status;
385         }
386
387         if (argc >= 1) {
388                 ctx->output_filename = argv[0];
389         }
390         if (argc >= 2) {
391                 parse_samsync_partial_replication_objects(ctx, argc-1, argv+1,
392                                                           &ctx->single_object_replication,
393                                                           &ctx->objects,
394                                                           &ctx->num_objects);
395         }
396
397         ctx->mode               = NET_SAMSYNC_MODE_FETCH_LDIF;
398         ctx->cli                = pipe_hnd;
399         ctx->ops                = &libnet_samsync_ldif_ops;
400         ctx->domain_name        = domain_name;
401
402         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
403         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
404
405         /* fetch domain */
406         status = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
407
408         if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
409                 d_fprintf(stderr, "%s\n", ctx->error_message);
410                 goto fail;
411         }
412
413         if (ctx->result_message) {
414                 d_fprintf(stdout, "%s\n", ctx->result_message);
415         }
416
417         /* fetch builtin */
418         ctx->domain_sid = dom_sid_dup(mem_ctx, &global_sid_Builtin);
419         ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid);
420         status = libnet_samsync(SAM_DATABASE_BUILTIN, ctx);
421
422         if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
423                 d_fprintf(stderr, "%s\n", ctx->error_message);
424                 goto fail;
425         }
426
427         if (ctx->result_message) {
428                 d_fprintf(stdout, "%s\n", ctx->result_message);
429         }
430
431  fail:
432         TALLOC_FREE(ctx);
433         return status;
434 }
435
436 int rpc_vampire_ldif(struct net_context *c, int argc, const char **argv)
437 {
438         if (c->display_usage) {
439                 d_printf(  "%s\n"
440                            "net rpc vampire ldif\n"
441                            "    %s\n",
442                          _("Usage:"),
443                          _("Dump remote SAM database to LDIF file or "
444                            "stdout"));
445                 return 0;
446         }
447
448         return run_rpc_command(c, NULL, &ndr_table_netlogon, 0,
449                                rpc_vampire_ldif_internals, argc, argv);
450 }
451
452
453 static NTSTATUS rpc_vampire_keytab_internals(struct net_context *c,
454                                              const struct dom_sid *domain_sid,
455                                              const char *domain_name,
456                                              struct cli_state *cli,
457                                              struct rpc_pipe_client *pipe_hnd,
458                                              TALLOC_CTX *mem_ctx,
459                                              int argc,
460                                              const char **argv)
461 {
462         NTSTATUS status;
463         struct samsync_context *ctx = NULL;
464
465         status = libnet_samsync_init_context(mem_ctx,
466                                              domain_sid,
467                                              &ctx);
468         if (!NT_STATUS_IS_OK(status)) {
469                 return status;
470         }
471
472         if (argc < 1) {
473                 /* the caller should ensure that a filename is provided */
474                 return NT_STATUS_INVALID_PARAMETER;
475         } else {
476                 ctx->output_filename = argv[0];
477         }
478         if (argc >= 2) {
479                 parse_samsync_partial_replication_objects(ctx, argc-1, argv+1,
480                                                           &ctx->single_object_replication,
481                                                           &ctx->objects,
482                                                           &ctx->num_objects);
483         }
484
485         ctx->mode               = NET_SAMSYNC_MODE_FETCH_KEYTAB;
486         ctx->cli                = pipe_hnd;
487         ctx->ops                = &libnet_samsync_keytab_ops;
488         ctx->domain_name        = domain_name;
489         ctx->username           = c->opt_user_name;
490         ctx->password           = c->opt_password;
491
492         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
493         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
494
495         /* fetch domain */
496         status = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
497
498         if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
499                 d_fprintf(stderr, "%s\n", ctx->error_message);
500                 goto out;
501         }
502
503         if (ctx->result_message) {
504                 d_fprintf(stdout, "%s\n", ctx->result_message);
505         }
506
507  out:
508         TALLOC_FREE(ctx);
509
510         return status;
511 }
512
513 static NTSTATUS rpc_vampire_keytab_ds_internals(struct net_context *c,
514                                                 const struct dom_sid *domain_sid,
515                                                 const char *domain_name,
516                                                 struct cli_state *cli,
517                                                 struct rpc_pipe_client *pipe_hnd,
518                                                 TALLOC_CTX *mem_ctx,
519                                                 int argc,
520                                                 const char **argv)
521 {
522         NTSTATUS status;
523         struct dssync_context *ctx = NULL;
524
525         status = libnet_dssync_init_context(mem_ctx,
526                                             &ctx);
527         if (!NT_STATUS_IS_OK(status)) {
528                 return status;
529         }
530
531         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
532         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
533
534         if (argc < 1) {
535                 /* the caller should ensure that a filename is provided */
536                 return NT_STATUS_INVALID_PARAMETER;
537         } else {
538                 ctx->output_filename = argv[0];
539         }
540
541         if (argc >= 2) {
542                 ctx->object_dns = &argv[1];
543                 ctx->object_count = argc - 1;
544                 ctx->single_object_replication = c->opt_single_obj_repl ? true
545                                                                         : false;
546         }
547
548         ctx->cli                = pipe_hnd;
549         ctx->domain_name        = domain_name;
550         ctx->ops                = &libnet_dssync_keytab_ops;
551
552         status = libnet_dssync(mem_ctx, ctx);
553         if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
554                 d_fprintf(stderr, "%s\n", ctx->error_message);
555                 goto out;
556         }
557
558         if (ctx->result_message) {
559                 d_fprintf(stdout, "%s\n", ctx->result_message);
560         }
561
562  out:
563         TALLOC_FREE(ctx);
564
565         return status;
566 }
567
568 /**
569  * Basic function for 'net rpc vampire keytab'
570  *
571  * @param c     A net_context structure
572  * @param argc  Standard main() style argc
573  * @param argc  Standard main() style argv.  Initial components are already
574  *              stripped
575  **/
576
577 int rpc_vampire_keytab(struct net_context *c, int argc, const char **argv)
578 {
579         int ret = 0;
580         NTSTATUS status;
581         struct cli_state *cli = NULL;
582         struct net_dc_info dc_info;
583
584         if (c->display_usage || (argc < 1)) {
585                 d_printf("%s\n%s",
586                          _("Usage:"),
587                          _("net rpc vampire keytab <keytabfile>\n"
588                            "    Dump remote SAM database to Kerberos keytab "
589                            "file\n"));
590                 return 0;
591         }
592
593         status = net_make_ipc_connection(c, 0, &cli);
594         if (!NT_STATUS_IS_OK(status)) {
595                 return -1;
596         }
597
598         status = net_scan_dc(c, cli, &dc_info);
599         if (!NT_STATUS_IS_OK(status)) {
600                 return -1;
601         }
602
603         if (!dc_info.is_ad) {
604                 printf(_("DC is not running Active Directory\n"));
605                 ret = run_rpc_command(c, cli, &ndr_table_netlogon,
606                                       0,
607                                       rpc_vampire_keytab_internals, argc, argv);
608         } else {
609                 ret = run_rpc_command(c, cli, &ndr_table_drsuapi,
610                                       NET_FLAGS_SEAL | NET_FLAGS_TCP,
611                                       rpc_vampire_keytab_ds_internals, argc, argv);
612                 if (ret != 0 && dc_info.is_mixed_mode) {
613                         printf(_("Fallback to NT4 vampire on Mixed-Mode AD "
614                                  "Domain\n"));
615                         ret = run_rpc_command(c, cli, &ndr_table_netlogon,
616                                               0,
617                                               rpc_vampire_keytab_internals, argc, argv);
618                 } else {
619 #ifndef HAVE_ADS
620                         printf(_("Vampire requested against AD DC but ADS"
621                                 " support not built in: HAVE_ADS is not defined\n"));
622 #endif
623                 }
624         }
625
626         return ret;
627 }