root/source3/utils/net_rpc_samsync.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. parse_samsync_partial_replication_objects
  2. rpc_samdump_internals
  3. rpc_vampire_usage
  4. rpc_vampire_internals
  5. rpc_vampire_passdb
  6. rpc_vampire_ldif_internals
  7. rpc_vampire_ldif
  8. rpc_vampire_keytab_internals
  9. rpc_vampire_keytab_ds_internals
  10. rpc_vampire_keytab

   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 
  29 static void parse_samsync_partial_replication_objects(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  30                                                       int argc,
  31                                                       const char **argv,
  32                                                       bool *do_single_object_replication,
  33                                                       struct samsync_object **objects,
  34                                                       uint32_t *num_objects)
  35 {
  36         int i;
  37 
  38         if (argc > 0) {
  39                 *do_single_object_replication = true;
  40         }
  41 
  42         for (i=0; i<argc; i++) {
  43 
  44                 struct samsync_object o;
  45 
  46                 ZERO_STRUCT(o);
  47 
  48                 if (!StrnCaseCmp(argv[i], "user_rid=", strlen("user_rid="))) {
  49                         o.object_identifier.rid         = get_int_param(argv[i]);
  50                         o.object_type                   = NETR_DELTA_USER;
  51                         o.database_id                   = SAM_DATABASE_DOMAIN;
  52                 }
  53                 if (!StrnCaseCmp(argv[i], "group_rid=", strlen("group_rid="))) {
  54                         o.object_identifier.rid         = get_int_param(argv[i]);
  55                         o.object_type                   = NETR_DELTA_GROUP;
  56                         o.database_id                   = SAM_DATABASE_DOMAIN;
  57                 }
  58                 if (!StrnCaseCmp(argv[i], "group_member_rid=", strlen("group_member_rid="))) {
  59                         o.object_identifier.rid         = get_int_param(argv[i]);
  60                         o.object_type                   = NETR_DELTA_GROUP_MEMBER;
  61                         o.database_id                   = SAM_DATABASE_DOMAIN;
  62                 }
  63                 if (!StrnCaseCmp(argv[i], "alias_rid=", strlen("alias_rid="))) {
  64                         o.object_identifier.rid         = get_int_param(argv[i]);
  65                         o.object_type                   = NETR_DELTA_ALIAS;
  66                         o.database_id                   = SAM_DATABASE_BUILTIN;
  67                 }
  68                 if (!StrnCaseCmp(argv[i], "alias_member_rid=", strlen("alias_member_rid="))) {
  69                         o.object_identifier.rid         = get_int_param(argv[i]);
  70                         o.object_type                   = NETR_DELTA_ALIAS_MEMBER;
  71                         o.database_id                   = SAM_DATABASE_BUILTIN;
  72                 }
  73                 if (!StrnCaseCmp(argv[i], "account_sid=", strlen("account_sid="))) {
  74                         const char *sid_str = get_string_param(argv[i]);
  75                         string_to_sid(&o.object_identifier.sid, sid_str);
  76                         o.object_type                   = NETR_DELTA_ACCOUNT;
  77                         o.database_id                   = SAM_DATABASE_PRIVS;
  78                 }
  79                 if (!StrnCaseCmp(argv[i], "policy_sid=", strlen("policy_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_POLICY;
  83                         o.database_id                   = SAM_DATABASE_PRIVS;
  84                 }
  85                 if (!StrnCaseCmp(argv[i], "trustdom_sid=", strlen("trustdom_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_TRUSTED_DOMAIN;
  89                         o.database_id                   = SAM_DATABASE_PRIVS;
  90                 }
  91                 if (!StrnCaseCmp(argv[i], "secret_name=", strlen("secret_name="))) {
  92                         o.object_identifier.name        = get_string_param(argv[i]);
  93                         o.object_type                   = NETR_DELTA_SECRET;
  94                         o.database_id                   = SAM_DATABASE_PRIVS;
  95                 }
  96 
  97                 if (o.object_type > 0) {
  98                         ADD_TO_ARRAY(mem_ctx, struct samsync_object, o,
  99                                      objects, num_objects);
 100                 }
 101         }
 102 }
 103 
 104 /* dump sam database via samsync rpc calls */
 105 NTSTATUS rpc_samdump_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 106                                 const DOM_SID *domain_sid,
 107                                 const char *domain_name,
 108                                 struct cli_state *cli,
 109                                 struct rpc_pipe_client *pipe_hnd,
 110                                 TALLOC_CTX *mem_ctx,
 111                                 int argc,
 112                                 const char **argv)
 113 {
 114         struct samsync_context *ctx = NULL;
 115         NTSTATUS status;
 116 
 117         status = libnet_samsync_init_context(mem_ctx,
 118                                              domain_sid,
 119                                              &ctx);
 120         if (!NT_STATUS_IS_OK(status)) {
 121                 return status;
 122         }
 123 
 124         ctx->mode               = NET_SAMSYNC_MODE_DUMP;
 125         ctx->cli                = pipe_hnd;
 126         ctx->ops                = &libnet_samsync_display_ops;
 127         ctx->domain_name        = domain_name;
 128 
 129         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
 130         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
 131 
 132         parse_samsync_partial_replication_objects(ctx, argc, argv,
 133                                                   &ctx->single_object_replication,
 134                                                   &ctx->objects,
 135                                                   &ctx->num_objects);
 136 
 137         libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
 138 
 139         libnet_samsync(SAM_DATABASE_BUILTIN, ctx);
 140 
 141         libnet_samsync(SAM_DATABASE_PRIVS, ctx);
 142 
 143         TALLOC_FREE(ctx);
 144 
 145         return NT_STATUS_OK;
 146 }
 147 
 148 /**
 149  * Basic usage function for 'net rpc vampire'
 150  *
 151  * @param c     A net_context structure
 152  * @param argc  Standard main() style argc
 153  * @param argc  Standard main() style argv.  Initial components are already
 154  *              stripped
 155  **/
 156 
 157 int rpc_vampire_usage(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 158 {
 159         d_printf("net rpc vampire ([ldif [<ldif-filename>] | [keytab] [<keytab-filename]) [options]\n"
 160                  "\t to pull accounts from a remote PDC where we are a BDC\n"
 161                  "\t\t no args puts accounts in local passdb from smb.conf\n"
 162                  "\t\t ldif - put accounts in ldif format (file defaults to "
 163                  "/tmp/tmp.ldif)\n"
 164                  "\t\t keytab - put account passwords in krb5 keytab (defaults "
 165                  "to system keytab)\n");
 166 
 167         net_common_flags_usage(c, argc, argv);
 168         return -1;
 169 }
 170 
 171 
 172 /* dump sam database via samsync rpc calls */
 173 NTSTATUS rpc_vampire_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 174                                 const DOM_SID *domain_sid,
 175                                 const char *domain_name,
 176                                 struct cli_state *cli,
 177                                 struct rpc_pipe_client *pipe_hnd,
 178                                 TALLOC_CTX *mem_ctx,
 179                                 int argc,
 180                                 const char **argv)
 181 {
 182         NTSTATUS result;
 183         struct samsync_context *ctx = NULL;
 184 
 185         if (!sid_equal(domain_sid, get_global_sam_sid())) {
 186                 d_printf("Cannot import users from %s at this time, "
 187                          "as the current domain:\n\t%s: %s\nconflicts "
 188                          "with the remote domain\n\t%s: %s\n"
 189                          "Perhaps you need to set: \n\n\tsecurity=user\n\t"
 190                          "workgroup=%s\n\n in your smb.conf?\n",
 191                          domain_name,
 192                          get_global_sam_name(),
 193                          sid_string_dbg(get_global_sam_sid()),
 194                          domain_name,
 195                          sid_string_dbg(domain_sid),
 196                          domain_name);
 197                 return NT_STATUS_UNSUCCESSFUL;
 198         }
 199 
 200         result = libnet_samsync_init_context(mem_ctx,
 201                                              domain_sid,
 202                                              &ctx);
 203         if (!NT_STATUS_IS_OK(result)) {
 204                 return result;
 205         }
 206 
 207         ctx->mode               = NET_SAMSYNC_MODE_FETCH_PASSDB;
 208         ctx->cli                = pipe_hnd;
 209         ctx->ops                = &libnet_samsync_passdb_ops;
 210         ctx->domain_name        = domain_name;
 211 
 212         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
 213         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
 214 
 215         parse_samsync_partial_replication_objects(ctx, argc, argv,
 216                                                   &ctx->single_object_replication,
 217                                                   &ctx->objects,
 218                                                   &ctx->num_objects);
 219 
 220         /* fetch domain */
 221         result = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
 222 
 223         if (!NT_STATUS_IS_OK(result) && ctx->error_message) {
 224                 d_fprintf(stderr, "%s\n", ctx->error_message);
 225                 goto fail;
 226         }
 227 
 228         if (ctx->result_message) {
 229                 d_fprintf(stdout, "%s\n", ctx->result_message);
 230         }
 231 
 232         /* fetch builtin */
 233         ctx->domain_sid = sid_dup_talloc(mem_ctx, &global_sid_Builtin);
 234         ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid);
 235         result = libnet_samsync(SAM_DATABASE_BUILTIN, ctx);
 236 
 237         if (!NT_STATUS_IS_OK(result) && ctx->error_message) {
 238                 d_fprintf(stderr, "%s\n", ctx->error_message);
 239                 goto fail;
 240         }
 241 
 242         if (ctx->result_message) {
 243                 d_fprintf(stdout, "%s\n", ctx->result_message);
 244         }
 245 
 246  fail:
 247         TALLOC_FREE(ctx);
 248         return result;
 249 }
 250 
 251 int rpc_vampire_passdb(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 252 {
 253         if (c->display_usage) {
 254                 d_printf("Usage:\n"
 255                          "net rpc vampire passdb\n"
 256                          "    Dump remote SAM database to passdb\n");
 257                 return 0;
 258         }
 259 
 260         return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id, 0,
 261                                rpc_vampire_internals, argc, argv);
 262 }
 263 
 264 NTSTATUS rpc_vampire_ldif_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 265                                     const DOM_SID *domain_sid,
 266                                     const char *domain_name,
 267                                     struct cli_state *cli,
 268                                     struct rpc_pipe_client *pipe_hnd,
 269                                     TALLOC_CTX *mem_ctx,
 270                                     int argc,
 271                                     const char **argv)
 272 {
 273         NTSTATUS status;
 274         struct samsync_context *ctx = NULL;
 275 
 276         status = libnet_samsync_init_context(mem_ctx,
 277                                              domain_sid,
 278                                              &ctx);
 279         if (!NT_STATUS_IS_OK(status)) {
 280                 return status;
 281         }
 282 
 283         if (argc >= 1) {
 284                 ctx->output_filename = argv[0];
 285         }
 286         if (argc >= 2) {
 287                 parse_samsync_partial_replication_objects(ctx, argc-1, argv+1,
 288                                                           &ctx->single_object_replication,
 289                                                           &ctx->objects,
 290                                                           &ctx->num_objects);
 291         }
 292 
 293         ctx->mode               = NET_SAMSYNC_MODE_FETCH_LDIF;
 294         ctx->cli                = pipe_hnd;
 295         ctx->ops                = &libnet_samsync_ldif_ops;
 296         ctx->domain_name        = domain_name;
 297 
 298         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
 299         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
 300 
 301         /* fetch domain */
 302         status = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
 303 
 304         if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
 305                 d_fprintf(stderr, "%s\n", ctx->error_message);
 306                 goto fail;
 307         }
 308 
 309         if (ctx->result_message) {
 310                 d_fprintf(stdout, "%s\n", ctx->result_message);
 311         }
 312 
 313         /* fetch builtin */
 314         ctx->domain_sid = sid_dup_talloc(mem_ctx, &global_sid_Builtin);
 315         ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid);
 316         status = libnet_samsync(SAM_DATABASE_BUILTIN, ctx);
 317 
 318         if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
 319                 d_fprintf(stderr, "%s\n", ctx->error_message);
 320                 goto fail;
 321         }
 322 
 323         if (ctx->result_message) {
 324                 d_fprintf(stdout, "%s\n", ctx->result_message);
 325         }
 326 
 327  fail:
 328         TALLOC_FREE(ctx);
 329         return status;
 330 }
 331 
 332 int rpc_vampire_ldif(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 333 {
 334         if (c->display_usage) {
 335                 d_printf("Usage:\n"
 336                          "net rpc vampire ldif\n"
 337                          "    Dump remote SAM database to LDIF file or stdout\n");
 338                 return 0;
 339         }
 340 
 341         return run_rpc_command(c, NULL, &ndr_table_netlogon.syntax_id, 0,
 342                                rpc_vampire_ldif_internals, argc, argv);
 343 }
 344 
 345 
 346 NTSTATUS rpc_vampire_keytab_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 347                                       const DOM_SID *domain_sid,
 348                                       const char *domain_name,
 349                                       struct cli_state *cli,
 350                                       struct rpc_pipe_client *pipe_hnd,
 351                                       TALLOC_CTX *mem_ctx,
 352                                       int argc,
 353                                       const char **argv)
 354 {
 355         NTSTATUS status;
 356         struct samsync_context *ctx = NULL;
 357 
 358         status = libnet_samsync_init_context(mem_ctx,
 359                                              domain_sid,
 360                                              &ctx);
 361         if (!NT_STATUS_IS_OK(status)) {
 362                 return status;
 363         }
 364 
 365         if (argc < 1) {
 366                 /* the caller should ensure that a filename is provided */
 367                 return NT_STATUS_INVALID_PARAMETER;
 368         } else {
 369                 ctx->output_filename = argv[0];
 370         }
 371         if (argc >= 2) {
 372                 parse_samsync_partial_replication_objects(ctx, argc-1, argv+1,
 373                                                           &ctx->single_object_replication,
 374                                                           &ctx->objects,
 375                                                           &ctx->num_objects);
 376         }
 377 
 378         ctx->mode               = NET_SAMSYNC_MODE_FETCH_KEYTAB;
 379         ctx->cli                = pipe_hnd;
 380         ctx->ops                = &libnet_samsync_keytab_ops;
 381         ctx->domain_name        = domain_name;
 382         ctx->username           = c->opt_user_name;
 383         ctx->password           = c->opt_password;
 384 
 385         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
 386         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
 387 
 388         /* fetch domain */
 389         status = libnet_samsync(SAM_DATABASE_DOMAIN, ctx);
 390 
 391         if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
 392                 d_fprintf(stderr, "%s\n", ctx->error_message);
 393                 goto out;
 394         }
 395 
 396         if (ctx->result_message) {
 397                 d_fprintf(stdout, "%s\n", ctx->result_message);
 398         }
 399 
 400  out:
 401         TALLOC_FREE(ctx);
 402 
 403         return status;
 404 }
 405 
 406 static NTSTATUS rpc_vampire_keytab_ds_internals(struct net_context *c,
     /* [<][>][^][v][top][bottom][index][help] */
 407                                                 const DOM_SID *domain_sid,
 408                                                 const char *domain_name,
 409                                                 struct cli_state *cli,
 410                                                 struct rpc_pipe_client *pipe_hnd,
 411                                                 TALLOC_CTX *mem_ctx,
 412                                                 int argc,
 413                                                 const char **argv)
 414 {
 415         NTSTATUS status;
 416         struct dssync_context *ctx = NULL;
 417 
 418         status = libnet_dssync_init_context(mem_ctx,
 419                                             &ctx);
 420         if (!NT_STATUS_IS_OK(status)) {
 421                 return status;
 422         }
 423 
 424         ctx->force_full_replication = c->opt_force_full_repl ? true : false;
 425         ctx->clean_old_entries = c->opt_clean_old_entries ? true : false;
 426 
 427         if (argc < 1) {
 428                 /* the caller should ensure that a filename is provided */
 429                 return NT_STATUS_INVALID_PARAMETER;
 430         } else {
 431                 ctx->output_filename = argv[0];
 432         }
 433 
 434         if (argc >= 2) {
 435                 ctx->object_dns = &argv[1];
 436                 ctx->object_count = argc - 1;
 437                 ctx->single_object_replication = c->opt_single_obj_repl ? true
 438                                                                         : false;
 439         }
 440 
 441         ctx->cli                = pipe_hnd;
 442         ctx->domain_name        = domain_name;
 443         ctx->ops                = &libnet_dssync_keytab_ops;
 444 
 445         status = libnet_dssync(mem_ctx, ctx);
 446         if (!NT_STATUS_IS_OK(status) && ctx->error_message) {
 447                 d_fprintf(stderr, "%s\n", ctx->error_message);
 448                 goto out;
 449         }
 450 
 451         if (ctx->result_message) {
 452                 d_fprintf(stdout, "%s\n", ctx->result_message);
 453         }
 454 
 455  out:
 456         TALLOC_FREE(ctx);
 457 
 458         return status;
 459 }
 460 
 461 /**
 462  * Basic function for 'net rpc vampire keytab'
 463  *
 464  * @param c     A net_context structure
 465  * @param argc  Standard main() style argc
 466  * @param argc  Standard main() style argv.  Initial components are already
 467  *              stripped
 468  **/
 469 
 470 int rpc_vampire_keytab(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 471 {
 472         int ret = 0;
 473         NTSTATUS status;
 474         struct cli_state *cli = NULL;
 475         struct net_dc_info dc_info;
 476 
 477         if (c->display_usage || (argc < 1)) {
 478                 d_printf("Usage:\n"
 479                          "net rpc vampire keytab <keytabfile>\n"
 480                          "    Dump remote SAM database to Kerberos keytab file\n");
 481                 return 0;
 482         }
 483 
 484         status = net_make_ipc_connection(c, 0, &cli);
 485         if (!NT_STATUS_IS_OK(status)) {
 486                 return -1;
 487         }
 488 
 489         status = net_scan_dc(c, cli, &dc_info);
 490         if (!NT_STATUS_IS_OK(status)) {
 491                 return -1;
 492         }
 493 
 494         if (!dc_info.is_ad) {
 495                 printf("DC is not running Active Directory\n");
 496                 ret = run_rpc_command(c, cli, &ndr_table_netlogon.syntax_id,
 497                                       0,
 498                                       rpc_vampire_keytab_internals, argc, argv);
 499                 return -1;
 500         } else {
 501                 ret = run_rpc_command(c, cli, &ndr_table_drsuapi.syntax_id,
 502                                       NET_FLAGS_SEAL | NET_FLAGS_TCP,
 503                                       rpc_vampire_keytab_ds_internals, argc, argv);
 504                 if (ret != 0 && dc_info.is_mixed_mode) {
 505                         printf("Fallback to NT4 vampire on Mixed-Mode AD Domain\n");
 506                         ret = run_rpc_command(c, cli, &ndr_table_netlogon.syntax_id,
 507                                               0,
 508                                               rpc_vampire_keytab_internals, argc, argv);
 509                 }
 510         }
 511 
 512         return ret;
 513 }

/* [<][>][^][v][top][bottom][index][help] */