Make it possible to 'net rpc samdump' of any domain you are currently joined
authorAndrew Bartlett <abartlet@samba.org>
Sun, 8 Feb 2004 10:59:09 +0000 (10:59 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 8 Feb 2004 10:59:09 +0000 (10:59 +0000)
to, despite any smb.conf settings.

Work to allow the same for 'net rpc vampire', but instead give a clear
error message on what is incorrect.

Andrew Bartlett
(This used to be commit 6b629344c5a4061d6052fa91f8429b337bab95fb)

source3/utils/net.h
source3/utils/net_rpc.c
source3/utils/net_rpc_samsync.c

index 78c0aad86a7c1b537493d44eb7f3b94a9a7152e6..94e6de9d181d2f6fa15197227db5010379f5bf4c 100644 (file)
@@ -35,6 +35,8 @@
 /* We want an anonymous connection */
 #define NET_FLAGS_ANONYMOUS 16 
 
+/* don't open an RPC pipe */
+#define NET_FLAGS_NO_PIPE 32
 
 extern int opt_maxusers;
 extern const char *opt_comment;
index dddfec2255f5261d9ef48e125b7cfa3a0ed34b5e..c7e014131b8a6a39256dd41f69277ee8e243e2f0 100644 (file)
@@ -37,7 +37,8 @@
 
 
 /* A function of this type is passed to the 'run_rpc_command' wrapper */
-typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, struct cli_state *, TALLOC_CTX *, int, const char **);
+typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, const char *, 
+                                  struct cli_state *, TALLOC_CTX *, int, const char **);
 
 /**
  * Many of the RPC functions need the domain sid.  This function gets
@@ -48,13 +49,12 @@ typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *, struct cli_state *, TALLOC_C
  * @return The Domain SID of the remote machine.
  **/
 
-static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx)
+static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx, char **domain_name)
 {
        DOM_SID *domain_sid;
        POLICY_HND pol;
        NTSTATUS result = NT_STATUS_OK;
        uint32 info_class = 5;
-        char *domain_name;
        
        if (!cli_nt_session_open (cli, PI_LSARPC)) {
                fprintf(stderr, "could not initialise lsa pipe\n");
@@ -69,7 +69,7 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem
        }
 
        result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class, 
-                                          &domain_name, &domain_sid);
+                                          domain_name, &domain_sid);
        if (!NT_STATUS_IS_OK(result)) {
  error:
                fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
@@ -107,6 +107,7 @@ static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int co
        TALLOC_CTX *mem_ctx;
        NTSTATUS nt_status;
        DOM_SID *domain_sid;
+       char *domain_name;
 
        /* make use of cli_state handed over as an argument, if possible */
        if (!cli_arg)
@@ -126,13 +127,15 @@ static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int co
                return -1;
        }
        
-       domain_sid = net_get_remote_domain_sid(cli, mem_ctx);
+       domain_sid = net_get_remote_domain_sid(cli, mem_ctx, &domain_name);
 
-       if (!cli_nt_session_open(cli, pipe_idx)) {
-               DEBUG(0, ("Could not initialise pipe\n"));
+       if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
+               if (!cli_nt_session_open(cli, pipe_idx)) {
+                       DEBUG(0, ("Could not initialise pipe\n"));
+               }
        }
        
-       nt_status = fn(domain_sid, cli, mem_ctx, argc, argv);
+       nt_status = fn(domain_sid, domain_name, cli, mem_ctx, argc, argv);
        
        if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(1, ("rpc command function failed! (%s)\n", nt_errstr(nt_status)));
@@ -140,10 +143,11 @@ static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int co
                DEBUG(5, ("rpc command function succedded\n"));
        }
                
-           
-       if (cli->nt_pipe_fnum)
-               cli_nt_session_close(cli);
-       
+       if (!(conn_flags & NET_FLAGS_NO_PIPE)) {
+               if (cli->nt_pipe_fnum)
+                       cli_nt_session_close(cli);
+       }
+
        /* close the connection only if it was opened here */
        if (!cli_arg)
                cli_shutdown(cli);
@@ -173,8 +177,9 @@ static int run_rpc_command(struct cli_state *cli_arg, const int pipe_idx, int co
  * @return Normal NTSTATUS return.
  **/
 
-static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, 
-                                      int argc, const char **argv) {
+static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, const char *domain_name, 
+                                           struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                                           int argc, const char **argv) {
        
        return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup);
 }
@@ -191,7 +196,8 @@ static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cl
 
 int net_rpc_changetrustpw(int argc, const char **argv) 
 {
-       return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals,
+       return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, 
+                              rpc_changetrustpw_internals,
                               argc, argv);
 }
 
@@ -219,9 +225,10 @@ int net_rpc_changetrustpw(int argc, const char **argv)
  * @return Normal NTSTATUS return.
  **/
 
-static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid, struct cli_state *cli, 
-                                           TALLOC_CTX *mem_ctx, 
-                                           int argc, const char **argv) {
+static NTSTATUS rpc_oldjoin_internals(const DOM_SID *domain_sid, const char *domain_name, 
+                                     struct cli_state *cli, 
+                                     TALLOC_CTX *mem_ctx, 
+                                     int argc, const char **argv) {
        
        fstring trust_passwd;
        unsigned char orig_trust_passwd_hash[16];
@@ -367,7 +374,8 @@ int net_rpc_join(int argc, const char **argv)
  **/
 
 static NTSTATUS 
-rpc_info_internals(const DOM_SID *domain_sid, struct cli_state *cli,
+rpc_info_internals(const DOM_SID *domain_sid, const char *domain_name, 
+                  struct cli_state *cli,
                   TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
        POLICY_HND connect_pol, domain_pol;
@@ -442,16 +450,17 @@ int net_rpc_info(int argc, const char **argv)
  **/
 
 static NTSTATUS 
-rpc_getsid_internals(const DOM_SID *domain_sid, struct cli_state *cli,
-                  TALLOC_CTX *mem_ctx, int argc, const char **argv)
+rpc_getsid_internals(const DOM_SID *domain_sid, const char *domain_name, 
+                    struct cli_state *cli,
+                    TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
        fstring sid_str;
 
        sid_to_string(sid_str, domain_sid);
        d_printf("Storing SID %s for Domain %s in secrets.tdb\n",
-                sid_str, lp_workgroup());
+                sid_str, domain_name);
 
-       if (!secrets_store_domain_sid(global_myname(), domain_sid)) {
+       if (!secrets_store_domain_sid(domain_name, domain_sid)) {
                DEBUG(0,("Can't store domain SID\n"));
                return NT_STATUS_UNSUCCESSFUL;
        }
@@ -504,7 +513,8 @@ static int rpc_user_usage(int argc, const char **argv)
  * @return Normal NTSTATUS return.
  **/
 
-static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, const char *domain_name, 
+                                      struct cli_state *cli, TALLOC_CTX *mem_ctx, 
                                       int argc, const char **argv) {
        
        POLICY_HND connect_pol, domain_pol, user_pol;
@@ -593,6 +603,7 @@ static int rpc_user_add(int argc, const char **argv)
  **/
 
 static NTSTATUS rpc_user_del_internals(const DOM_SID *domain_sid, 
+                                      const char *domain_name, 
                                       struct cli_state *cli, 
                                       TALLOC_CTX *mem_ctx, 
                                       int argc, const char **argv)
@@ -694,6 +705,7 @@ static int rpc_user_delete(int argc, const char **argv)
  **/
 
 static NTSTATUS rpc_user_password_internals(const DOM_SID *domain_sid, 
+                                           const char *domain_name, 
                                            struct cli_state *cli, 
                                            TALLOC_CTX *mem_ctx, 
                                            int argc, const char **argv)
@@ -823,7 +835,8 @@ static int rpc_user_password(int argc, const char **argv)
  **/
 
 static NTSTATUS 
-rpc_user_info_internals(const DOM_SID *domain_sid, struct cli_state *cli,
+rpc_user_info_internals(const DOM_SID *domain_sid, const char *domain_name, 
+                       struct cli_state *cli,
                        TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
        POLICY_HND connect_pol, domain_pol, user_pol;
@@ -925,7 +938,8 @@ static int rpc_user_info(int argc, const char **argv)
  **/
 
 static NTSTATUS 
-rpc_user_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
+rpc_user_list_internals(const DOM_SID *domain_sid, const char *domain_name, 
+                       struct cli_state *cli,
                        TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
        POLICY_HND connect_pol, domain_pol;
@@ -1047,7 +1061,8 @@ static int rpc_group_usage(int argc, const char **argv)
  **/
 
 static NTSTATUS 
-rpc_group_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
+rpc_group_list_internals(const DOM_SID *domain_sid, const char *domain_name, 
+                        struct cli_state *cli,
                         TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
        POLICY_HND connect_pol, domain_pol;
@@ -1237,7 +1252,8 @@ static int rpc_group_list(int argc, const char **argv)
 }
  
 static NTSTATUS 
-rpc_group_members_internals(const DOM_SID *domain_sid, struct cli_state *cli,
+rpc_group_members_internals(const DOM_SID *domain_sid, const char *domain_name, 
+                           struct cli_state *cli,
                            TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
        NTSTATUS result;
@@ -1387,7 +1403,8 @@ static int rpc_share_usage(int argc, const char **argv)
  * @return Normal NTSTATUS return.
  **/
 static NTSTATUS 
-rpc_share_add_internals(const DOM_SID *domain_sid, struct cli_state *cli,
+rpc_share_add_internals(const DOM_SID *domain_sid, const char *domain_name, 
+                       struct cli_state *cli,
                        TALLOC_CTX *mem_ctx,int argc, const char **argv)
 {
        WERROR result;
@@ -1435,7 +1452,8 @@ static int rpc_share_add(int argc, const char **argv)
  * @return Normal NTSTATUS return.
  **/
 static NTSTATUS 
-rpc_share_del_internals(const DOM_SID *domain_sid, struct cli_state *cli,
+rpc_share_del_internals(const DOM_SID *domain_sid, const char *domain_name, 
+                       struct cli_state *cli,
                        TALLOC_CTX *mem_ctx,int argc, const char **argv)
 {
        WERROR result;
@@ -1504,7 +1522,8 @@ static void display_share_info_1(SRV_SHARE_INFO_1 *info1)
  **/
 
 static NTSTATUS 
-rpc_share_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
+rpc_share_list_internals(const DOM_SID *domain_sid, const char *domain_name, 
+                        struct cli_state *cli,
                         TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
        SRV_SHARE_INFO_CTR ctr;
@@ -1580,7 +1599,8 @@ static int rpc_file_usage(int argc, const char **argv)
  * @return Normal NTSTATUS return.
  **/
 static NTSTATUS 
-rpc_file_close_internals(const DOM_SID *domain_sid, struct cli_state *cli,
+rpc_file_close_internals(const DOM_SID *domain_sid, const char *domain_name, 
+                        struct cli_state *cli,
                         TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
        WERROR result;
@@ -1644,7 +1664,8 @@ static void display_file_info_3(FILE_INFO_3 *info3, FILE_INFO_3_STR *str3)
  **/
 
 static NTSTATUS 
-rpc_file_list_internals(const DOM_SID *domain_sid, struct cli_state *cli,
+rpc_file_list_internals(const DOM_SID *domain_sid, const char *domain_name, 
+                       struct cli_state *cli,
                        TALLOC_CTX *mem_ctx, int argc, const char **argv)
 {
        SRV_FILE_INFO_CTR ctr;
@@ -1748,6 +1769,7 @@ int net_rpc_file(int argc, const char **argv)
  **/
 
 static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid, 
+                                            const char *domain_name, 
                                             struct cli_state *cli, 
                                             TALLOC_CTX *mem_ctx, 
                                             int argc, const char **argv) 
@@ -1782,6 +1804,7 @@ static NTSTATUS rpc_shutdown_abort_internals(const DOM_SID *domain_sid,
  **/
 
 static NTSTATUS rpc_reg_shutdown_abort_internals(const DOM_SID *domain_sid, 
+                                                const char *domain_name, 
                                                 struct cli_state *cli, 
                                                 TALLOC_CTX *mem_ctx, 
                                                 int argc, const char **argv) 
@@ -1840,7 +1863,9 @@ static int rpc_shutdown_abort(int argc, const char **argv)
  * @return Normal NTSTATUS return.
  **/
 
-static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+static NTSTATUS rpc_shutdown_internals(const DOM_SID *domain_sid, 
+                                      const char *domain_name, 
+                                      struct cli_state *cli, TALLOC_CTX *mem_ctx, 
                                       int argc, const char **argv) 
 {
        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
@@ -1925,7 +1950,9 @@ static int rpc_shutdown(int argc, const char **argv)
  * @return normal NTSTATUS return code
  */
 
-static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid, 
+                                          const char *domain_name, 
+                                          struct cli_state *cli, TALLOC_CTX *mem_ctx, 
                                            int argc, const char **argv) {
 
        POLICY_HND connect_pol, domain_pol, user_pol;
@@ -2280,8 +2307,10 @@ static int rpc_trustdom_usage(int argc, const char **argv)
 }
 
 
-static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
-                              int argc, const char **argv)
+static NTSTATUS rpc_query_domain_sid(const DOM_SID *domain_sid, 
+                                    const char *domain_name, 
+                                    struct cli_state *cli, TALLOC_CTX *mem_ctx,
+                                    int argc, const char **argv)
 {
        fstring str_sid;
        sid_to_string(str_sid, domain_sid);
@@ -2592,7 +2621,17 @@ BOOL net_rpc_check(unsigned flags)
        return ret;
 }
 
+/* dump sam database via samsync rpc calls */
+static int rpc_samdump(int argc, const char **argv) {
+       return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_samdump_internals,
+                              argc, argv);
+}
 
+/* syncronise sam database via samsync rpc calls */
+static int rpc_vampire(int argc, const char **argv) {
+       return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS, rpc_vampire_internals,
+                              argc, argv);
+}
 /****************************************************************************/
 
 
index cb395de828f9ac19d415522ec33c9363cf3b5f5f..882f3a02bc28b55e431af899d7fbaf4c3cb48fa6 100644 (file)
@@ -196,36 +196,29 @@ static void dump_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret
 }
 
 /* dump sam database via samsync rpc calls */
-int rpc_samdump(int argc, const char **argv)
+NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid, 
+                              const char *domain_name, 
+                              struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                              int argc, const char **argv) 
 {
-       struct cli_state *cli = NULL;
+       NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
        uchar trust_password[16];
        DOM_CRED ret_creds;
        uint32 sec_channel;
 
        ZERO_STRUCT(ret_creds);
 
-       /* Connect to remote machine */
-       if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC))) {
-               return 1;
-       }
-
-       fstrcpy(cli->domain, lp_workgroup());
-
-       if (!cli_nt_session_open(cli, PI_NETLOGON)) {
-               DEBUG(0,("Could not open connection to NETLOGON pipe\n"));
-               goto fail;
-       }
+       fstrcpy(cli->domain, domain_name);
 
-       if (!secrets_fetch_trust_account_password(lp_workgroup(),
+       if (!secrets_fetch_trust_account_password(domain_name,
                                                  trust_password,
                                                  NULL, &sec_channel)) {
                DEBUG(0,("Could not fetch trust account password\n"));
                goto fail;
        }
 
-       if (!NT_STATUS_IS_OK(cli_nt_establish_netlogon(cli, sec_channel,
-                                                      trust_password))) {
+       if (!NT_STATUS_IS_OK(nt_status = cli_nt_establish_netlogon(cli, sec_channel,
+                                                                  trust_password))) {
                DEBUG(0,("Error connecting to NETLOGON pipe\n"));
                goto fail;
        }
@@ -234,15 +227,11 @@ int rpc_samdump(int argc, const char **argv)
        dump_database(cli, SAM_DATABASE_BUILTIN, &ret_creds);
        dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds);
 
-       cli_nt_session_close(cli);
-        
-        return 0;
+        nt_status = NT_STATUS_OK;
 
 fail:
-       if (cli) {
-               cli_nt_session_close(cli);
-       }
-       return -1;
+       cli_nt_session_close(cli);
+       return nt_status;
 }
 
 /* Convert a SAM_ACCOUNT_DELTA to a SAM_ACCOUNT. */
@@ -457,7 +446,6 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
                        nt_ret = NT_STATUS_NO_SUCH_USER;
                        goto done;
                }
-                       
        }
        
        sid_copy(&user_sid, get_global_sam_sid());
@@ -1020,75 +1008,73 @@ fetch_database(struct cli_state *cli, unsigned db_type, DOM_CRED *ret_creds,
 }
 
 /* dump sam database via samsync rpc calls */
-int rpc_vampire(int argc, const char **argv)
+NTSTATUS rpc_vampire_internals(const DOM_SID *domain_sid, 
+                              const char *domain_name, 
+                              struct cli_state *cli, TALLOC_CTX *mem_ctx, 
+                              int argc, const char **argv) 
 {
         NTSTATUS result;
-       struct cli_state *cli = NULL;
        uchar trust_password[16];
        DOM_CRED ret_creds;
-       DOM_SID dom_sid;
+       fstring my_dom_sid_str;
+       fstring rem_dom_sid_str;
        uint32 sec_channel;
 
        ZERO_STRUCT(ret_creds);
 
-       /* Connect to remote machine */
-       if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS |
-                                           NET_FLAGS_PDC))) {
-               return 1;
+       if (!sid_equal(domain_sid, get_global_sam_sid())) {
+               d_printf("Cannot import users from %s at this time, "
+                        "as the current domain:\n\t%s: %s\nconflicts "
+                        "with the remote domain\n\t%s: %s\n"
+                        "Perhaps you need to set: \n\n\tsecurity=user\n\tworkgroup=%s\n\n in your smb.conf?\n",
+                        domain_name,
+                        get_global_sam_name(), sid_to_string(my_dom_sid_str, 
+                                                             get_global_sam_sid()),
+                        domain_name, sid_to_string(rem_dom_sid_str, domain_sid),
+                        domain_name);
+               return NT_STATUS_UNSUCCESSFUL;
        }
 
-       if (!cli_nt_session_open(cli, PI_NETLOGON)) {
-               DEBUG(0,("Error connecting to NETLOGON pipe\n"));
-               goto fail;
-       }
+       fstrcpy(cli->domain, domain_name);
 
-       if (!secrets_fetch_trust_account_password(opt_target_workgroup,
+       if (!secrets_fetch_trust_account_password(domain_name,
                                                  trust_password, NULL,
                                                  &sec_channel)) {
+               result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
                d_printf("Could not retrieve domain trust secret\n");
                goto fail;
        }
        
-       result = cli_nt_establish_netlogon(cli, sec_channel,  trust_password);
+       result = cli_nt_establish_netlogon(cli, sec_channel, trust_password);
 
        if (!NT_STATUS_IS_OK(result)) {
                d_printf("Failed to setup BDC creds\n");
                goto fail;
        }
 
-       sid_copy( &dom_sid, get_global_sam_sid() );
-       result = fetch_database(cli, SAM_DATABASE_DOMAIN, &ret_creds, dom_sid);
+       result = fetch_database(cli, SAM_DATABASE_DOMAIN, &ret_creds, *domain_sid);
 
        if (!NT_STATUS_IS_OK(result)) {
                d_printf("Failed to fetch domain database: %s\n",
                         nt_errstr(result));
                if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED))
                        d_printf("Perhaps %s is a Windows 2000 native mode "
-                                "domain?\n", opt_target_workgroup);
+                                "domain?\n", domain_name);
                goto fail;
        }
 
-       sid_copy(&dom_sid, &global_sid_Builtin);
-
        result = fetch_database(cli, SAM_DATABASE_BUILTIN, &ret_creds, 
-                               dom_sid);
+                               global_sid_Builtin);
 
        if (!NT_STATUS_IS_OK(result)) {
                d_printf("Failed to fetch builtin database: %s\n",
                         nt_errstr(result));
                goto fail;
-       }       
+       }
 
        /* Currently we crash on PRIVS somewhere in unmarshalling */
        /* Dump_database(cli, SAM_DATABASE_PRIVS, &ret_creds); */
 
-       cli_nt_session_close(cli);
-        
-        return 0;
-
 fail:
-       if (cli)
-               cli_nt_session_close(cli);
-
-       return -1;
+       return result;
 }