diff options
-rw-r--r-- | source3/utils/net_ads.c | 42 | ||||
-rw-r--r-- | source3/utils/net_rpc.c | 2 | ||||
-rw-r--r-- | source3/utils/net_rpc_join.c | 101 |
3 files changed, 125 insertions, 20 deletions
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index f74f633cf9..6916bcb406 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -32,6 +32,8 @@ int net_ads_usage(int argc, const char **argv) "\n\tjoins the local machine to a ADS realm\n"\ "\nnet ads leave"\ "\n\tremoves the local machine from a ADS realm\n"\ +"\nnet ads testjoin"\ +"\n\ttests that an exiting join is OK\n"\ "\nnet ads user"\ "\n\tlist, add, or delete users in the realm\n"\ "\nnet ads group"\ @@ -537,6 +539,45 @@ static int net_ads_leave(int argc, const char **argv) return 0; } +static int net_ads_join_ok(void) +{ + ADS_STRUCT *ads = NULL; + extern pstring global_myname; + + if (!secrets_init()) { + DEBUG(1,("Failed to initialise secrets database\n")); + return -1; + } + + asprintf(&opt_user_name, "%s$", global_myname); + opt_password = secrets_fetch_machine_password(); + + if (!(ads = ads_startup())) { + return -1; + } + + ads_destroy(&ads); + return 0; +} + +/* + check that an existing join is OK + */ +int net_ads_testjoin(int argc, const char **argv) +{ + /* Display success or failure */ + if (net_ads_join_ok() != 0) { + fprintf(stderr,"Join to domain is not valid\n"); + return -1; + } + + printf("Join is OK\n"); + return 0; +} + +/* + join a domain using ADS + */ int net_ads_join(int argc, const char **argv) { ADS_STRUCT *ads; @@ -948,6 +989,7 @@ int net_ads(int argc, const char **argv) struct functable func[] = { {"INFO", net_ads_info}, {"JOIN", net_ads_join}, + {"TESTJOIN", net_ads_testjoin}, {"LEAVE", net_ads_leave}, {"STATUS", net_ads_status}, {"USER", net_ads_user}, diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index ae956076d5..55e8a497cc 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -2120,6 +2120,7 @@ int net_rpc_usage(int argc, const char **argv) { d_printf(" net rpc info \t\t\tshow basic info about a domain \n"); d_printf(" net rpc join \t\t\tto join a domain \n"); + d_printf(" net rpc testjoin \t\t\ttests that a join is valid\n"); d_printf(" net rpc user \t\t\tto add, delete and list users\n"); d_printf(" net rpc group \t\tto list groups\n"); d_printf(" net rpc share \t\tto add, delete, and list shares\n"); @@ -2182,6 +2183,7 @@ int net_rpc(int argc, const char **argv) struct functable func[] = { {"info", net_rpc_info}, {"join", net_rpc_join}, + {"testjoin", net_rpc_testjoin}, {"user", net_rpc_user}, {"group", net_rpc_group}, {"share", net_rpc_share}, diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index cfa37d25df..c8be93c39c 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -35,6 +35,61 @@ goto done; \ } + +/** + * confirm that a domain join is still valid + * + * @return A shell status integer (0 for success) + * + **/ +int net_rpc_join_ok(const char *domain) +{ + struct cli_state *cli; + uchar stored_md4_trust_password[16]; + int retval = 1; + uint32 channel; + NTSTATUS result; + + /* Connect to remote machine */ + if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC))) { + return 1; + } + + if (!cli_nt_session_open(cli, PIPE_NETLOGON)) { + DEBUG(0,("Error connecting to NETLOGON pipe\n")); + goto done; + } + + if (!secrets_fetch_trust_account_password(domain, + stored_md4_trust_password, NULL)) { + DEBUG(0,("Could not reterive domain trust secret")); + goto done; + } + + if (lp_server_role() == ROLE_DOMAIN_BDC || + lp_server_role() == ROLE_DOMAIN_PDC) { + channel = SEC_CHAN_BDC; + } else { + channel = SEC_CHAN_WKSTA; + } + + CHECK_RPC_ERR(cli_nt_setup_creds(cli, + channel, + stored_md4_trust_password), + "error in domain join verification"); + + retval = 0; /* Success! */ + +done: + /* Close down pipe - this will clean up open policy handles */ + if (cli->nt_pipe_fnum) + cli_nt_session_close(cli); + + cli_shutdown(cli); + + return retval; +} + /** * Join a domain using the administrator username and password * @@ -67,7 +122,6 @@ int net_rpc_join_newstyle(int argc, const char **argv) char *clear_trust_password = NULL; fstring ucs2_trust_password; int ucs2_pw_len; - uchar stored_md4_trust_password[16]; uchar pwbuf[516], sess_key[16]; SAM_USERINFO_CTR ctr; SAM_USER_INFO_24 p24; @@ -256,28 +310,10 @@ int net_rpc_join_newstyle(int argc, const char **argv) } /* Now check the whole process from top-to-bottom */ - cli_samr_close(cli, mem_ctx, &user_pol); - cli_nt_session_close(cli); /* Done with this pipe */ - if (!cli_nt_session_open(cli, PIPE_NETLOGON)) { - DEBUG(0, ("Error connecting to NETLOGON pipe\n")); - goto done; - } - - if (!secrets_fetch_trust_account_password(domain, - stored_md4_trust_password, NULL)) { - DEBUG(0, ("Could not reterive secrets we just stored!")); - goto done; - } - - CHECK_RPC_ERR(cli_nt_setup_creds(cli, - (acb_info & ACB_SVRTRUST) ? SEC_CHAN_BDC : SEC_CHAN_WKSTA, - stored_md4_trust_password), - "error in domain join verification"); - - retval = 0; /* Success! */ + retval = net_rpc_join_ok(domain); done: /* Close down pipe - this will clean up open policy handles */ @@ -300,3 +336,28 @@ done: return retval; } + + +/** + * check that a join is OK + * + * @return A shell status integer (0 for success) + * + **/ +int net_rpc_testjoin(int argc, const char **argv) +{ + char *domain = lp_workgroup(); + + domain = smb_xstrdup(domain); + + /* Display success or failure */ + if (net_rpc_join_ok(domain) != 0) { + fprintf(stderr,"Join to domain '%s' is not valid\n",domain); + free(domain); + return -1; + } + + printf("Join to '%s' is OK\n",domain); + free(domain); + return 0; +} |