summaryrefslogtreecommitdiff
path: root/source3/nsswitch/winbindd_cm.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch/winbindd_cm.c')
-rw-r--r--source3/nsswitch/winbindd_cm.c513
1 files changed, 309 insertions, 204 deletions
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
index 14221483ad..c91f955568 100644
--- a/source3/nsswitch/winbindd_cm.c
+++ b/source3/nsswitch/winbindd_cm.c
@@ -73,7 +73,7 @@
SAMR pipe as well for now. --jerry
******************************************************************/
-#define DISABLE_SCHANNEL_WIN2K3_SP1 1
+/* #define DISABLE_SCHANNEL_WIN2K3_SP1 1 */
/* Choose between anonymous or authenticated connections. We need to use
@@ -113,8 +113,8 @@ static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
fstring dcname, struct in_addr *dc_ip)
{
struct winbindd_domain *our_domain;
+ struct rpc_pipe_client *netlogon_pipe;
NTSTATUS result;
- struct rpc_pipe_client *cli;
TALLOC_CTX *mem_ctx;
fstring tmp;
@@ -123,30 +123,26 @@ static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
/* Hmmmm. We can only open one connection to the NETLOGON pipe at the
* moment.... */
- if (IS_DC)
+ if (IS_DC) {
return False;
+ }
- if (domain->primary)
+ if (domain->primary) {
return False;
+ }
our_domain = find_our_domain();
- if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL)
+ if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
return False;
-
- {
- /* These var's can be ignored -- we're not requesting
- anything in the credential chain here */
- unsigned char *session_key;
- DOM_CRED *creds;
- result = cm_connect_netlogon(our_domain, mem_ctx, &cli,
- &session_key, &creds);
}
- if (!NT_STATUS_IS_OK(result))
+ result = cm_connect_netlogon(our_domain, &netlogon_pipe);
+ if (!NT_STATUS_IS_OK(result)) {
return False;
+ }
- result = rpccli_netlogon_getdcname(cli, mem_ctx, domain->dcname,
+ result = rpccli_netlogon_getdcname(netlogon_pipe, mem_ctx, domain->dcname,
domain->name, tmp);
talloc_destroy(mem_ctx);
@@ -156,13 +152,18 @@ static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
/* cli_netlogon_getdcname gives us a name with \\ */
p = tmp;
- if (*p == '\\') p+=1;
- if (*p == '\\') p+=1;
+ if (*p == '\\') {
+ p+=1;
+ }
+ if (*p == '\\') {
+ p+=1;
+ }
fstrcpy(dcname, p);
- if (!resolve_name(dcname, dc_ip, 0x20))
+ if (!resolve_name(dcname, dc_ip, 0x20)) {
return False;
+ }
return True;
}
@@ -178,7 +179,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
struct cli_state **cli,
BOOL *retry)
{
- char *machine_password, *machine_krb5_principal;
+ char *machine_password, *machine_krb5_principal, *machine_account;
char *ipc_username, *ipc_domain, *ipc_password;
BOOL got_mutex;
@@ -194,8 +195,14 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL,
NULL);
+ if (asprintf(&machine_account, "%s$", global_myname()) == -1) {
+ SAFE_FREE(machine_password);
+ return NT_STATUS_NO_MEMORY;
+ }
+
if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(),
lp_realm()) == -1) {
+ SAFE_FREE(machine_account);
SAFE_FREE(machine_password);
return NT_STATUS_NO_MEMORY;
}
@@ -257,33 +264,61 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
goto done;
}
- /* Krb5 session */
- if ((lp_security() == SEC_ADS)
- && ((*cli)->protocol >= PROTOCOL_NT1 &&
- (*cli)->capabilities & CAP_EXTENDED_SECURITY)) {
-
+ if ((*cli)->protocol >= PROTOCOL_NT1 && (*cli)->capabilities & CAP_EXTENDED_SECURITY) {
ADS_STATUS ads_status;
- (*cli)->use_kerberos = True;
- DEBUG(5, ("connecting to %s from %s with kerberos principal "
- "[%s]\n", controller, global_myname(),
- machine_krb5_principal));
+
+ if (lp_security() == SEC_ADS) {
+
+ /* Try a krb5 session */
+
+ (*cli)->use_kerberos = True;
+ DEBUG(5, ("connecting to %s from %s with kerberos principal "
+ "[%s]\n", controller, global_myname(),
+ machine_krb5_principal));
+
+ ads_status = cli_session_setup_spnego(*cli,
+ machine_krb5_principal,
+ machine_password,
+ lp_workgroup());
+
+ if (!ADS_ERR_OK(ads_status)) {
+ DEBUG(4,("failed kerberos session setup with %s\n",
+ ads_errstr(ads_status)));
+ }
+
+ result = ads_ntstatus(ads_status);
+ if (NT_STATUS_IS_OK(result)) {
+ /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
+ cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
+ goto session_setup_done;
+ }
+ }
+
+ /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
+ (*cli)->use_kerberos = False;
+
+ DEBUG(5, ("connecting to %s from %s with username "
+ "[%s]\\[%s]\n", controller, global_myname(),
+ machine_account, machine_password));
ads_status = cli_session_setup_spnego(*cli,
- machine_krb5_principal,
+ machine_account,
machine_password,
lp_workgroup());
-
- if (!ADS_ERR_OK(ads_status))
- DEBUG(4,("failed kerberos session setup with %s\n",
- ads_errstr(ads_status)));
+ if (!ADS_ERR_OK(ads_status)) {
+ DEBUG(4, ("authenticated session setup failed with %s\n",
+ ads_errstr(ads_status)));
+ }
result = ads_ntstatus(ads_status);
+ if (NT_STATUS_IS_OK(result)) {
+ /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
+ cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
+ goto session_setup_done;
+ }
}
- if (NT_STATUS_IS_OK(result))
- goto session_setup_done;
-
/* Fall back to non-kerberos session setup */
(*cli)->use_kerberos = False;
@@ -301,8 +336,12 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
ipc_password, strlen(ipc_password)+1,
ipc_password, strlen(ipc_password)+1,
ipc_domain)) {
- DEBUG(5, ("authenticated session setup failed\n"));
+ /* Successful logon with given username. */
+ cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
goto session_setup_done;
+ } else {
+ DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
+ ipc_domain, ipc_username ));
}
}
@@ -310,6 +349,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
if (cli_session_setup(*cli, "", NULL, 0, NULL, 0, "")) {
DEBUG(5, ("Connected anonymously\n"));
+ cli_init_creds(*cli, "", "", "");
goto session_setup_done;
}
@@ -342,26 +382,28 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
*retry = False;
/* set the domain if empty; needed for schannel connections */
- if ( !*(*cli)->domain )
+ if ( !*(*cli)->domain ) {
fstrcpy( (*cli)->domain, domain->name );
-
- (*cli)->pipe_auth_flags = 0;
+ }
result = NT_STATUS_OK;
add_failed_connection = False;
done:
- if (got_mutex)
+ if (got_mutex) {
secrets_named_mutex_release(controller);
+ }
+ SAFE_FREE(machine_account);
SAFE_FREE(machine_password);
SAFE_FREE(machine_krb5_principal);
SAFE_FREE(ipc_username);
SAFE_FREE(ipc_domain);
SAFE_FREE(ipc_password);
- if (add_failed_connection)
+ if (add_failed_connection) {
add_failed_connection_entry(domain->name, controller, result);
+ }
return result;
}
@@ -721,7 +763,7 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
for (retries = 0; retries < 3; retries++) {
int fd = -1;
- BOOL retry;
+ BOOL retry = False;
result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
@@ -758,27 +800,23 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
void invalidate_cm_connection(struct winbindd_cm_conn *conn)
{
if (conn->samr_pipe != NULL) {
- cli_rpc_close(conn->samr_pipe);
+ cli_rpc_pipe_close(conn->samr_pipe);
conn->samr_pipe = NULL;
}
if (conn->lsa_pipe != NULL) {
- cli_rpc_close(conn->lsa_pipe);
+ cli_rpc_pipe_close(conn->lsa_pipe);
conn->lsa_pipe = NULL;
}
- if (conn->netlogon_auth2_pipe != NULL) {
- cli_rpc_close(conn->netlogon_auth2_pipe);
- conn->netlogon_auth2_pipe = NULL;
- }
-
if (conn->netlogon_pipe != NULL) {
- cli_rpc_close(conn->netlogon_pipe);
+ cli_rpc_pipe_close(conn->netlogon_pipe);
conn->netlogon_pipe = NULL;
}
- if (conn->cli)
+ if (conn->cli) {
cli_shutdown(conn->cli);
+ }
conn->cli = NULL;
}
@@ -872,7 +910,7 @@ void set_dc_type_and_flags( struct winbindd_domain *domain )
return;
}
- cli = cli_rpc_open_noauth(domain->conn.cli, PI_LSARPC_DS);
+ cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS, &result);
if (cli == NULL) {
DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
@@ -885,7 +923,7 @@ void set_dc_type_and_flags( struct winbindd_domain *domain )
result = rpccli_ds_getprimarydominfo(cli, cli->cli->mem_ctx,
DsRolePrimaryDomainInfoBasic,
&ctr);
- cli_rpc_close(cli);
+ cli_rpc_pipe_close(cli);
if (!NT_STATUS_IS_OK(result)) {
domain->initialized = True;
@@ -896,7 +934,7 @@ void set_dc_type_and_flags( struct winbindd_domain *domain )
!(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) )
domain->native_mode = True;
- cli = cli_rpc_open_noauth(domain->conn.cli, PI_LSARPC);
+ cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
if (cli == NULL) {
domain->initialized = True;
@@ -907,6 +945,7 @@ void set_dc_type_and_flags( struct winbindd_domain *domain )
domain->name);
if (!mem_ctx) {
DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
+ cli_rpc_pipe_close(cli);
return;
}
@@ -956,7 +995,7 @@ void set_dc_type_and_flags( struct winbindd_domain *domain )
}
done:
- cli_rpc_close(cli);
+ cli_rpc_pipe_close(cli);
talloc_destroy(mem_ctx);
@@ -965,20 +1004,28 @@ done:
return;
}
-static BOOL cm_get_schannel_key(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- unsigned char **session_key)
+#ifndef DISABLE_SCHANNEL_WIN2K3_SP1
+static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain, struct dcinfo **ppdc)
{
- struct rpc_pipe_client *cli;
- DOM_CRED *credentials;
+ NTSTATUS result;
+ struct rpc_pipe_client *netlogon_pipe;
- if (lp_client_schannel() == False)
+ if (lp_client_schannel() == False) {
return False;
+ }
- return NT_STATUS_IS_OK(cm_connect_netlogon(domain, mem_ctx,
- &cli, session_key,
- &credentials));
+ result = cm_connect_netlogon(domain, &netlogon_pipe);
+ if (!NT_STATUS_IS_OK(result)) {
+ return False;
+ }
+
+ /* Return a pointer to the struct dcinfo from the
+ netlogon pipe. */
+
+ *ppdc = domain->conn.netlogon_pipe->dc;
+ return True;
}
+#endif
NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
struct rpc_pipe_client **cli, POLICY_HND *sam_handle)
@@ -987,24 +1034,85 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
NTSTATUS result;
result = init_dc_connection(domain);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
return result;
+ }
conn = &domain->conn;
if (conn->samr_pipe == NULL) {
+ /*
+ * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO
+ * authenticated sign and sealed pipe using the machine
+ * account password by preference. If we can't - try schannel,
+ * if that fails, try anonymous.
+ */
+
+ fstring conn_pwd;
+ pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
+ if (conn->cli->user_name[0] && conn->cli->domain[0] &&
+ conn_pwd[0]) {
+ /* We have an authenticated connection. Use
+ a NTLMSSP SPNEGO authenticated SAMR pipe with
+ sign & seal. */
+ conn->samr_pipe =
+ cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
+ PI_SAMR,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ conn->cli->domain,
+ conn->cli->user_name,
+ conn_pwd,
+ &result);
+ if (conn->samr_pipe == NULL) {
+ DEBUG(10,("cm_connect_sam: failed to connect "
+ "to SAMR pipe for domain %s using "
+ "NTLMSSP authenticated pipe: user "
+ "%s\\%s. Error was %s\n",
+ domain->name, conn->cli->domain,
+ conn->cli->user_name,
+ nt_errstr(result)));
+ } else {
+ DEBUG(10,("cm_connect_sam: connected to SAMR "
+ "pipe for domain %s using NTLMSSP "
+ "authenticated pipe: user %s\\%s\n",
+ domain->name, conn->cli->domain,
+ conn->cli->user_name ));
+ }
+ }
+
#ifndef DISABLE_SCHANNEL_WIN2K3_SP1
- unsigned char *session_key;
-
- if (cm_get_schannel_key(domain, mem_ctx, &session_key))
- conn->samr_pipe = cli_rpc_open_schannel(conn->cli,
- PI_SAMR,
- session_key,
- domain->name);
- else
+ /* Fall back to schannel if it's a W2K pre-SP1 box. */
+ if (conn->samr_pipe == NULL) {
+ struct dcinfo *p_dcinfo;
+
+ if (cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
+ conn->samr_pipe =
+ cli_rpc_pipe_open_schannel_with_key(conn->cli,
+ PI_SAMR,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ domain->name,
+ p_dcinfo,
+ &result);
+ }
+ if (conn->samr_pipe == NULL) {
+ DEBUG(10,("cm_connect_sam: failed to connect "
+ "to SAMR pipe for domain %s using "
+ "schannel authenticated. Error "
+ "was %s\n", domain->name,
+ nt_errstr(result) ));
+ } else {
+ DEBUG(10,("cm_connect_sam: connected to SAMR "
+ "pipe for domain %s using schannel.\n",
+ domain->name ));
+ }
+ }
#endif /* DISABLE_SCHANNEL_WIN2K3_SP1 */
- conn->samr_pipe = cli_rpc_open_noauth(conn->cli,
- PI_SAMR);
+
+ /* Finally fall back to anonymous. */
+ if (conn->samr_pipe == NULL) {
+ conn->samr_pipe =
+ cli_rpc_pipe_open_noauth(conn->cli, PI_SAMR, &result);
+ }
if (conn->samr_pipe == NULL) {
result = NT_STATUS_PIPE_NOT_AVAILABLE;
@@ -1014,8 +1122,12 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
SEC_RIGHTS_MAXIMUM_ALLOWED,
&conn->sam_connect_handle);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(10,("cm_connect_sam: rpccli_samr_connect failed "
+ "for domain %s Error was %s\n",
+ domain->name, nt_errstr(result) ));
goto done;
+ }
result = rpccli_samr_open_domain(conn->samr_pipe,
mem_ctx,
@@ -1026,9 +1138,10 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
}
done:
+
if (!NT_STATUS_IS_OK(result)) {
invalidate_cm_connection(conn);
- return NT_STATUS_UNSUCCESSFUL;
+ return result;
}
*cli = conn->samr_pipe;
@@ -1049,18 +1162,72 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
conn = &domain->conn;
if (conn->lsa_pipe == NULL) {
+ fstring conn_pwd;
+ pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
+ if (conn->cli->user_name[0] && conn->cli->domain[0] &&
+ conn_pwd[0]) {
+ /* We have an authenticated connection. Use
+ a NTLMSSP SPNEGO authenticated LSA pipe with
+ sign & seal. */
+ conn->lsa_pipe =
+ cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
+ PI_LSARPC,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ conn->cli->domain,
+ conn->cli->user_name,
+ conn_pwd,
+ &result);
+ if (conn->lsa_pipe == NULL) {
+ DEBUG(10,("cm_connect_lsa: failed to connect "
+ "to LSA pipe for domain %s using "
+ "NTLMSSP authenticated pipe: user "
+ "%s\\%s. Error was %s\n",
+ domain->name, conn->cli->domain,
+ conn->cli->user_name,
+ nt_errstr(result)));
+ } else {
+ DEBUG(10,("cm_connect_lsa: connected to LSA "
+ "pipe for domain %s using NTLMSSP "
+ "authenticated pipe: user %s\\%s\n",
+ domain->name, conn->cli->domain,
+ conn->cli->user_name ));
+ }
+ }
+
#ifndef DISABLE_SCHANNEL_WIN2K3_SP1
- unsigned char *session_key;
-
- if (cm_get_schannel_key(domain, mem_ctx, &session_key))
- conn->lsa_pipe = cli_rpc_open_schannel(conn->cli,
- PI_LSARPC,
- session_key,
- domain->name);
- else
+ /* Fall back to schannel if it's a W2K pre-SP1 box. */
+ if (conn->lsa_pipe == NULL) {
+ struct dcinfo *p_dcinfo;
+
+ if (cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
+ conn->lsa_pipe =
+ cli_rpc_pipe_open_schannel_with_key(conn->cli,
+ PI_LSARPC,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ domain->name,
+ p_dcinfo,
+ &result);
+ }
+ if (conn->lsa_pipe == NULL) {
+ DEBUG(10,("cm_connect_lsa: failed to connect "
+ "to LSA pipe for domain %s using "
+ "schannel authenticated. Error "
+ "was %s\n", domain->name,
+ nt_errstr(result) ));
+ } else {
+ DEBUG(10,("cm_connect_lsa: connected to LSA "
+ "pipe for domain %s using schannel.\n",
+ domain->name ));
+ }
+ }
#endif /* DISABLE_SCHANNEL_WIN2K3_SP1 */
- conn->lsa_pipe = cli_rpc_open_noauth(conn->cli,
- PI_LSARPC);
+
+ /* Finally fall back to anonymous. */
+ if (conn->lsa_pipe == NULL) {
+ conn->lsa_pipe = cli_rpc_pipe_open_noauth(conn->cli,
+ PI_LSARPC,
+ &result);
+ }
if (conn->lsa_pipe == NULL) {
result = NT_STATUS_PIPE_NOT_AVAILABLE;
@@ -1083,55 +1250,12 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
return result;
}
-/*******************************************************************
- wrapper around retrieving the trust account password
-*******************************************************************/
+/****************************************************************************
+ Open the netlogon pipe to this DC. Use schannel if specified in client conf.
+ session key stored in conn->netlogon_pipe->dc->sess_key.
+****************************************************************************/
-static BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16],
- uint32 *channel)
-{
- DOM_SID sid;
- char *pwd;
- time_t last_set_time;
-
- /* if we are a DC and this is not our domain, then lookup an account
- for the domain trust */
-
- if ( IS_DC && !strequal(domain, lp_workgroup()) &&
- lp_allow_trusted_domains() ) {
-
- if (!secrets_fetch_trusted_domain_password(domain, &pwd, &sid,
- &last_set_time)) {
- DEBUG(0, ("get_trust_pw: could not fetch trust "
- "account password for trusted domain %s\n",
- domain));
- return False;
- }
-
- *channel = SEC_CHAN_DOMAIN;
- E_md4hash(pwd, ret_pwd);
- SAFE_FREE(pwd);
-
- return True;
- }
-
- /* Just get the account for the requested domain. In the future this
- * might also cover to be member of more than one domain. */
-
- if (secrets_fetch_trust_account_password(domain, ret_pwd,
- &last_set_time, channel))
- return True;
-
- DEBUG(5, ("get_trust_pw: could not fetch trust account "
- "password for domain %s\n", domain));
- return False;
-}
-
-NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- struct rpc_pipe_client **cli,
- unsigned char **session_key,
- DOM_CRED **credentials)
+NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, struct rpc_pipe_client **cli)
{
struct winbindd_cm_conn *conn;
NTSTATUS result;
@@ -1139,119 +1263,100 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
uint8 mach_pwd[16];
uint32 sec_chan_type;
- DOM_CHAL clnt_chal, srv_chal, rcv_chal;
- const char *server_name;
const char *account_name;
- UTIME zerotime;
+ struct rpc_pipe_client *netlogon_pipe;
result = init_dc_connection(domain);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
return result;
+ }
conn = &domain->conn;
if (conn->netlogon_pipe != NULL) {
*cli = conn->netlogon_pipe;
- *session_key = (unsigned char *)&conn->sess_key;
- *credentials = &conn->clnt_cred;
return NT_STATUS_OK;
}
- if (!get_trust_pw(domain->name, mach_pwd, &sec_chan_type))
+ if (!get_trust_pw(domain->name, mach_pwd, &sec_chan_type)) {
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
- conn->netlogon_auth2_pipe = cli_rpc_open_noauth(conn->cli,
- PI_NETLOGON);
- if (conn->netlogon_auth2_pipe == NULL)
- return NT_STATUS_UNSUCCESSFUL;
+ netlogon_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_NETLOGON, &result);
+ if (netlogon_pipe == NULL) {
+ return result;
+ }
- if (lp_client_schannel() != False)
+ if (lp_client_schannel() != False) {
neg_flags |= NETLOGON_NEG_SCHANNEL;
-
- generate_random_buffer(clnt_chal.data, 8);
-
- server_name = talloc_asprintf(mem_ctx, "\\\\%s", domain->dcname);
+ }
/* if we are a DC and this is a trusted domain, then we need to use our
domain name in the net_req_auth2() request */
- if ( IS_DC
+ if ( IS_DC
&& !strequal(domain->name, lp_workgroup())
&& lp_allow_trusted_domains() )
{
- account_name = talloc_asprintf( mem_ctx, "%s$", lp_workgroup() );
- }
- else {
- account_name = talloc_asprintf(mem_ctx, "%s$",
- domain->primary ? global_myname() : domain->name);
+ account_name = lp_workgroup();
+ } else {
+ account_name = domain->primary ? global_myname() : domain->name;
}
- if ((server_name == NULL) || (account_name == NULL))
+ if (account_name == NULL) {
+ cli_rpc_pipe_close(netlogon_pipe);
return NT_STATUS_NO_MEMORY;
+ }
- result = rpccli_net_req_chal(conn->netlogon_auth2_pipe, server_name,
- global_myname(), &clnt_chal, &srv_chal);
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- /**************** Long-term Session key **************/
-
- /* calculate the session key */
- cred_session_key(&clnt_chal, &srv_chal, mach_pwd, conn->sess_key);
- memset((char *)conn->sess_key+8, '\0', 8);
-
- /* calculate auth2 credentials */
- zerotime.time = 0;
- cred_create(conn->sess_key, &clnt_chal, zerotime,
- &conn->clnt_cred.challenge);
-
- result = rpccli_net_auth2(conn->netlogon_auth2_pipe, server_name,
- account_name, sec_chan_type, global_myname(),
- &conn->clnt_cred.challenge, &neg_flags,
- &rcv_chal);
+ result = rpccli_netlogon_setup_creds(netlogon_pipe,
+ domain->dcname, /* server name. */
+ domain->name, /* domain name */
+ account_name, /* machine account */
+ mach_pwd, /* machine password */
+ sec_chan_type, /* from get_trust_pw */
+ &neg_flags);
- if (!NT_STATUS_IS_OK(result))
+ if (!NT_STATUS_IS_OK(result)) {
+ cli_rpc_pipe_close(netlogon_pipe);
return result;
-
- zerotime.time = 0;
- if (!cred_assert(&rcv_chal, conn->sess_key, &srv_chal, zerotime)) {
- DEBUG(0, ("Server replied with bad credential\n"));
- return NT_STATUS_ACCESS_DENIED;
}
if ((lp_client_schannel() == True) &&
- ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
+ ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
DEBUG(3, ("Server did not offer schannel\n"));
- cli_rpc_close(conn->netlogon_auth2_pipe);
- conn->netlogon_auth2_pipe = NULL;
+ cli_rpc_pipe_close(netlogon_pipe);
return NT_STATUS_ACCESS_DENIED;
}
if ((lp_client_schannel() == False) ||
- ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
- /* keep the existing connection to NETLOGON open */
- conn->netlogon_pipe = conn->netlogon_auth2_pipe;
- conn->netlogon_auth2_pipe = NULL;
+ ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
+ /* We're done - just keep the existing connection to NETLOGON open */
+ conn->netlogon_pipe = netlogon_pipe;
*cli = conn->netlogon_pipe;
- *session_key = (unsigned char *)&conn->sess_key;
- *credentials = &conn->clnt_cred;
return NT_STATUS_OK;
}
- conn->netlogon_pipe = cli_rpc_open_schannel(conn->cli, PI_NETLOGON,
- conn->sess_key,
- domain->name);
+ /* Using the credentials from the first pipe, open a signed and sealed
+ second netlogon pipe. The session key is stored in the schannel
+ part of the new pipe auth struct.
+ */
+
+ conn->netlogon_pipe = cli_rpc_pipe_open_schannel_with_key(conn->cli,
+ PI_NETLOGON,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ domain->name,
+ netlogon_pipe->dc,
+ &result);
+
+ /* We can now close the initial netlogon pipe. */
+ cli_rpc_pipe_close(netlogon_pipe);
if (conn->netlogon_pipe == NULL) {
- DEBUG(3, ("Could not open schannel'ed NETLOGON pipe\n"));
- cli_rpc_close(conn->netlogon_auth2_pipe);
- conn->netlogon_auth2_pipe = NULL;
- return NT_STATUS_ACCESS_DENIED;
+ DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error was %s\n",
+ nt_errstr(result)));
+ return result;
}
*cli = conn->netlogon_pipe;
- *session_key = (unsigned char *)&conn->sess_key;
- *credentials = &conn->clnt_cred;
-
return NT_STATUS_OK;
}