summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/utils/net_ads.c42
-rw-r--r--source3/utils/net_rpc.c2
-rw-r--r--source3/utils/net_rpc_join.c101
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;
+}