dns: Use new DNS debugclass in DNS server
[kai/samba.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->ops                = &libnet_samsync_display_ops;
133         ctx->domain_name        = domain_name;
134
135         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
136         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
137
138         parse_samsync_partial_replication_objects(ctx, argc, argv,
139                                                   &ctx->single_object_replication,
140                                                   &ctx->objects,
141                                                   &ctx->num_objects);
142
143         libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
144
145         libnet_samsync(SAM_DATABASE_BUILTIN, ctx);
146
147         libnet_samsync(SAM_DATABASE_PRIVS, ctx);
148
149         TALLOC_FREE(ctx);
150
151         return NT_STATUS_OK;
152 }
153
154 /**
155  * Basic usage function for 'net rpc vampire'
156  *
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
161  **/
162
163 int rpc_vampire_usage(struct net_context *c, int argc, const char **argv)
164 {
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"));
173
174         net_common_flags_usage(c, argc, argv);
175         return -1;
176 }
177
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)
186 {
187         NTSTATUS status;
188         struct dssync_context *ctx = NULL;
189
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;
203         }
204
205         status = libnet_dssync_init_context(mem_ctx,
206                                             &ctx);
207         if (!NT_STATUS_IS_OK(status)) {
208                 return status;
209         }
210
211         ctx->cli                = pipe_hnd;
212         ctx->domain_name        = domain_name;
213         ctx->ops                = &libnet_dssync_passdb_ops;
214
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;
219         }
220
221         if (ctx->result_message) {
222                 d_fprintf(stdout, "%s\n", ctx->result_message);
223         }
224
225  out:
226         TALLOC_FREE(ctx);
227
228         return status;
229 }
230
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)
240 {
241         NTSTATUS result;
242         struct samsync_context *ctx = NULL;
243
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;
257         }
258
259         result = libnet_samsync_init_context(mem_ctx,
260                                              domain_sid,
261                                              &ctx);
262         if (!NT_STATUS_IS_OK(result)) {
263                 return result;
264         }
265
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;
270
271         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
272         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
273
274         parse_samsync_partial_replication_objects(ctx, argc, argv,
275                                                   &ctx->single_object_replication,
276                                                   &ctx->objects,
277                                                   &ctx->num_objects);
278
279         /* fetch domain */
280         result = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
281
282         if (!NT_STATUS_IS_OK(result) && ctx->error_message) {
283                 d_fprintf(stderr, "%s\n", ctx->error_message);
284                 goto fail;
285         }
286
287         if (ctx->result_message) {
288                 d_fprintf(stdout, "%s\n", ctx->result_message);
289         }
290
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);
295
296         if (!NT_STATUS_IS_OK(result) && ctx->error_message) {
297                 d_fprintf(stderr, "%s\n", ctx->error_message);
298                 goto fail;
299         }
300
301         if (ctx->result_message) {
302                 d_fprintf(stdout, "%s\n", ctx->result_message);
303         }
304
305  fail:
306         TALLOC_FREE(ctx);
307         return result;
308 }
309
310 int rpc_vampire_passdb(struct net_context *c, int argc, const char **argv)
311 {
312         int ret = 0;
313         NTSTATUS status;
314         struct cli_state *cli = NULL;
315         struct net_dc_info dc_info;
316
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;
324         }
325
326         status = net_make_ipc_connection(c, 0, &cli);
327         if (!NT_STATUS_IS_OK(status)) {
328                 return -1;
329         }
330
331         status = net_scan_dc(c, cli, &dc_info);
332         if (!NT_STATUS_IS_OK(status)) {
333                 return -1;
334         }
335
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,
339                                       0,
340                                       rpc_vampire_internals, argc, argv);
341                 return ret;
342         }
343
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;
351         }
352
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,
360                                       0,
361                                       rpc_vampire_internals, argc, argv);
362         }
363
364         return ret;
365 }
366
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)
375 {
376         NTSTATUS status;
377         struct samsync_context *ctx = NULL;
378
379         status = libnet_samsync_init_context(mem_ctx,
380                                              domain_sid,
381                                              &ctx);
382         if (!NT_STATUS_IS_OK(status)) {
383                 return status;
384         }
385
386         if (argc >= 1) {
387                 ctx->output_filename = argv[0];
388         }
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);
394         }
395
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;
400
401         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
402         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
403
404         /* fetch domain */
405         status = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
406
407         if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
408                 d_fprintf(stderr, "%s\n", ctx->error_message);
409                 goto fail;
410         }
411
412         if (ctx->result_message) {
413                 d_fprintf(stdout, "%s\n", ctx->result_message);
414         }
415
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);
420
421         if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
422                 d_fprintf(stderr, "%s\n", ctx->error_message);
423                 goto fail;
424         }
425
426         if (ctx->result_message) {
427                 d_fprintf(stdout, "%s\n", ctx->result_message);
428         }
429
430  fail:
431         TALLOC_FREE(ctx);
432         return status;
433 }
434
435 int rpc_vampire_ldif(struct net_context *c, int argc, const char **argv)
436 {
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;
445         }
446
447         return run_rpc_command(c, NULL, &ndr_table_netlogon, 0,
448                                rpc_vampire_ldif_internals, argc, argv);
449 }
450
451
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)
460 {
461         NTSTATUS status;
462         struct samsync_context *ctx = NULL;
463
464         status = libnet_samsync_init_context(mem_ctx,
465                                              domain_sid,
466                                              &ctx);
467         if (!NT_STATUS_IS_OK(status)) {
468                 return status;
469         }
470
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];
476         }
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);
482         }
483
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;
490
491         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
492         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
493
494         /* fetch domain */
495         status = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
496
497         if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
498                 d_fprintf(stderr, "%s\n", ctx->error_message);
499                 goto out;
500         }
501
502         if (ctx->result_message) {
503                 d_fprintf(stdout, "%s\n", ctx->result_message);
504         }
505
506  out:
507         TALLOC_FREE(ctx);
508
509         return status;
510 }
511
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)
520 {
521         NTSTATUS status;
522         struct dssync_context *ctx = NULL;
523
524         status = libnet_dssync_init_context(mem_ctx,
525                                             &ctx);
526         if (!NT_STATUS_IS_OK(status)) {
527                 return status;
528         }
529
530         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
531         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
532
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];
538         }
539
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;
545         }
546
547         ctx->cli                = pipe_hnd;
548         ctx->domain_name        = domain_name;
549         ctx->ops                = &libnet_dssync_keytab_ops;
550
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;
555         }
556
557         if (ctx->result_message) {
558                 d_fprintf(stdout, "%s\n", ctx->result_message);
559         }
560
561  out:
562         TALLOC_FREE(ctx);
563
564         return status;
565 }
566
567 /**
568  * Basic function for 'net rpc vampire keytab'
569  *
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
574  **/
575
576 int rpc_vampire_keytab(struct net_context *c, int argc, const char **argv)
577 {
578         int ret = 0;
579         NTSTATUS status;
580         struct cli_state *cli = NULL;
581         struct net_dc_info dc_info;
582
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;
590         }
591
592         status = net_make_ipc_connection(c, 0, &cli);
593         if (!NT_STATUS_IS_OK(status)) {
594                 return -1;
595         }
596
597         status = net_scan_dc(c, cli, &dc_info);
598         if (!NT_STATUS_IS_OK(status)) {
599                 return -1;
600         }
601
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,
605                                       0,
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,
615                                               0,
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
622                 }
623         }
624
625         return ret;
626 }