summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2013-09-02 19:32:23 +0200
committerStefan Metzmacher <metze@samba.org>2014-01-07 12:47:10 +0100
commit963800539cea7487fc6258f8ac8f7cacc3426b83 (patch)
tree60f71e5c7a782e74b761f58d0bf2d497526e584d
parent531bbf3aff3fb08aaf112b21038f20544db60b69 (diff)
downloadsamba-963800539cea7487fc6258f8ac8f7cacc3426b83.tar.gz
s3:libnet_join: make use of rpccli_{create,setup}_netlogon_creds()
Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-rw-r--r--source3/libnet/libnet_join.c110
-rw-r--r--source3/libnet/libnet_join.h5
-rw-r--r--source3/utils/net_rpc.c4
3 files changed, 86 insertions, 33 deletions
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index b2805eed541..6e653c3586d 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -40,6 +40,8 @@
#include "libsmb/libsmb.h"
#include "../libcli/smb/smbXcli_base.h"
#include "lib/param/loadparm.h"
+#include "libcli/auth/netlogon_creds_cli.h"
+#include "auth/credentials/credentials.h"
/****************************************************************
****************************************************************/
@@ -1189,38 +1191,52 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
/****************************************************************
****************************************************************/
-NTSTATUS libnet_join_ok(const char *netbios_domain_name,
- const char *machine_name,
+NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx,
+ const char *netbios_domain_name,
const char *dc_name,
const bool use_kerberos)
{
- uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS |
- NETLOGON_NEG_SUPPORTS_AES;
+ TALLOC_CTX *frame = talloc_stackframe();
struct cli_state *cli = NULL;
- struct rpc_pipe_client *pipe_hnd = NULL;
struct rpc_pipe_client *netlogon_pipe = NULL;
+ struct netlogon_creds_cli_context *netlogon_creds = NULL;
+ struct netlogon_creds_CredentialState *creds = NULL;
+ uint32_t netlogon_flags = 0;
+ enum netr_SchannelType sec_chan_type = 0;
NTSTATUS status;
char *machine_password = NULL;
- char *machine_account = NULL;
+ const char *machine_name = NULL;
+ const char *machine_account = NULL;
int flags = 0;
+ struct samr_Password current_nt_hash;
+ struct samr_Password *previous_nt_hash = NULL;
+ bool ok;
if (!dc_name) {
+ TALLOC_FREE(frame);
return NT_STATUS_INVALID_PARAMETER;
}
if (!secrets_init()) {
+ TALLOC_FREE(frame);
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
- machine_password = secrets_fetch_machine_password(netbios_domain_name,
- NULL, NULL);
- if (!machine_password) {
- return NT_STATUS_NO_TRUST_LSA_SECRET;
+ ok = get_trust_pw_clear(netbios_domain_name,
+ &machine_password,
+ &machine_name,
+ &sec_chan_type);
+ if (!ok) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
- if (asprintf(&machine_account, "%s$", machine_name) == -1) {
+ machine_account = talloc_asprintf(frame, "%s$", machine_name);
+ if (machine_account == NULL) {
SAFE_FREE(machine_password);
- return NT_STATUS_NO_MEMORY;
+ SAFE_FREE(previous_nt_hash);
+ TALLOC_FREE(frame);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
if (use_kerberos) {
@@ -1232,12 +1248,13 @@ NTSTATUS libnet_join_ok(const char *netbios_domain_name,
NULL, 0,
"IPC$", "IPC",
machine_account,
- NULL,
+ netbios_domain_name,
machine_password,
flags,
SMB_SIGNING_DEFAULT);
- free(machine_account);
- free(machine_password);
+
+ E_md4hash(machine_password, current_nt_hash.hash);
+ SAFE_FREE(machine_password);
if (!NT_STATUS_IS_OK(status)) {
status = cli_full_connection(&cli, NULL,
@@ -1252,36 +1269,65 @@ NTSTATUS libnet_join_ok(const char *netbios_domain_name,
}
if (!NT_STATUS_IS_OK(status)) {
+ SAFE_FREE(previous_nt_hash);
+ TALLOC_FREE(frame);
return status;
}
- status = get_schannel_session_key(cli, netbios_domain_name,
- &neg_flags, &netlogon_pipe);
+ status = rpccli_create_netlogon_creds(dc_name,
+ netbios_domain_name,
+ machine_account,
+ sec_chan_type,
+ msg_ctx,
+ frame,
+ &netlogon_creds);
if (!NT_STATUS_IS_OK(status)) {
- if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_NETWORK_RESPONSE)) {
- cli_shutdown(cli);
- return NT_STATUS_OK;
- }
+ SAFE_FREE(previous_nt_hash);
+ cli_shutdown(cli);
+ TALLOC_FREE(frame);
+ return status;
+ }
- DEBUG(0,("libnet_join_ok: failed to get schannel session "
- "key from server %s for domain %s. Error was %s\n",
- smbXcli_conn_remote_name(cli->conn),
- netbios_domain_name, nt_errstr(status)));
+ status = rpccli_setup_netlogon_creds(cli,
+ netlogon_creds,
+ true, /* force_reauth */
+ current_nt_hash,
+ previous_nt_hash);
+ SAFE_FREE(previous_nt_hash);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("connect_to_domain_password_server: "
+ "unable to open the domain client session to "
+ "machine %s. Flags[0x%08X] Error was : %s.\n",
+ dc_name, (unsigned)netlogon_flags,
+ nt_errstr(status)));
+ cli_shutdown(cli);
+ TALLOC_FREE(frame);
+ return status;
+ }
+
+ status = netlogon_creds_cli_get(netlogon_creds,
+ talloc_tos(),
+ &creds);
+ if (!NT_STATUS_IS_OK(status)) {
cli_shutdown(cli);
+ TALLOC_FREE(frame);
return status;
}
+ netlogon_flags = creds->negotiate_flags;
+ TALLOC_FREE(creds);
- if (!lp_client_schannel()) {
+ if (!(netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
cli_shutdown(cli);
+ TALLOC_FREE(frame);
return NT_STATUS_OK;
}
status = cli_rpc_pipe_open_schannel_with_key(
cli, &ndr_table_netlogon, NCACN_NP,
netbios_domain_name,
- netlogon_pipe->netlogon_creds, &pipe_hnd);
+ netlogon_creds, &netlogon_pipe);
- cli_shutdown(cli);
+ TALLOC_FREE(netlogon_pipe);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("libnet_join_ok: failed to open schannel session "
@@ -1289,9 +1335,13 @@ NTSTATUS libnet_join_ok(const char *netbios_domain_name,
"Error was %s\n",
smbXcli_conn_remote_name(cli->conn),
netbios_domain_name, nt_errstr(status)));
+ cli_shutdown(cli);
+ TALLOC_FREE(frame);
return status;
}
+ cli_shutdown(cli);
+ TALLOC_FREE(frame);
return NT_STATUS_OK;
}
@@ -1303,8 +1353,8 @@ static WERROR libnet_join_post_verify(TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
- status = libnet_join_ok(r->out.netbios_domain_name,
- r->in.machine_name,
+ status = libnet_join_ok(r->in.msg_ctx,
+ r->out.netbios_domain_name,
r->in.dc_name,
r->in.use_kerberos);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/libnet/libnet_join.h b/source3/libnet/libnet_join.h
index 58c33b2dbcd..b7e2f0b1fb6 100644
--- a/source3/libnet/libnet_join.h
+++ b/source3/libnet/libnet_join.h
@@ -23,8 +23,9 @@
/* The following definitions come from libnet/libnet_join.c */
-NTSTATUS libnet_join_ok(const char *netbios_domain_name,
- const char *machine_name,
+struct messaging_context;
+NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx,
+ const char *netbios_domain_name,
const char *dc_name,
const bool use_kerberos);
WERROR libnet_init_JoinCtx(TALLOC_CTX *mem_ctx,
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 816705e86e7..6adb3261b3b 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -493,7 +493,9 @@ int net_rpc_testjoin(struct net_context *c, int argc, const char **argv)
}
/* Display success or failure */
- status = libnet_join_ok(c->opt_workgroup, lp_netbios_name(), dc,
+ status = libnet_join_ok(c->msg_ctx,
+ c->opt_workgroup,
+ dc,
c->opt_kerberos);
if (!NT_STATUS_IS_OK(status)) {
fprintf(stderr,"Join to domain '%s' is not valid: %s\n",