messaging_send_buf(winbind_messaging_context(),
pid_to_procid(parent_pid),
MSG_WINBIND_DOMAIN_OFFLINE,
- (uint8 *)domain->name,
+ (uint8_t *)domain->name,
strlen(domain->name) + 1);
}
messaging_send_buf(winbind_messaging_context(),
pid_to_procid(parent_pid),
MSG_WINBIND_DOMAIN_ONLINE,
- (uint8 *)domain->name,
+ (uint8_t *)domain->name,
strlen(domain->name) + 1);
}
if (NT_STATUS_EQUAL(result, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)
|| NT_STATUS_EQUAL(result, NT_STATUS_TRUSTED_DOMAIN_FAILURE)
|| NT_STATUS_EQUAL(result, NT_STATUS_INVALID_ACCOUNT_NAME)
+ || NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS)
|| NT_STATUS_EQUAL(result, NT_STATUS_LOGON_FAILURE))
{
if (cli_credentials_is_anonymous(creds)) {
*/
if (NT_STATUS_EQUAL(result, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)
|| NT_STATUS_EQUAL(result, NT_STATUS_TRUSTED_DOMAIN_FAILURE)
+ || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_ACCOUNT_NAME)
+ || NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS)
|| NT_STATUS_EQUAL(result, NT_STATUS_LOGON_FAILURE))
{
goto anon_fallback;
}
static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
- struct sockaddr_storage *pss, uint16 port,
+ struct sockaddr_storage *pss, uint16_t port,
struct sockaddr_storage **addrs, int *num)
{
*addrs = talloc_realloc(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
NTSTATUS status;
const char *dc_name;
fstring nbtname;
-
+#ifdef HAVE_ADS
+ bool is_ad_domain = false;
+#endif
ip_list.ss = *pss;
ip_list.port = 0;
None of these failures should be considered critical for now */
if ((lp_security() == SEC_ADS) && (domain->alt_name != NULL)) {
+ is_ad_domain = true;
+ } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
+ is_ad_domain = domain->active_directory;
+ }
+
+ if (is_ad_domain) {
ADS_STRUCT *ads;
ADS_STATUS ads_status;
char addr[INET6_ADDRSTRLEN];
WERROR werr;
struct netr_DomainTrustList trusts;
int i;
- uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
+ uint32_t flags = (NETR_TRUST_FLAG_IN_FOREST |
NETR_TRUST_FLAG_OUTBOUND |
NETR_TRUST_FLAG_INBOUND);
struct rpc_pipe_client *cli;
NTSTATUS status, result;
struct netlogon_creds_cli_context *p_creds;
struct cli_credentials *creds = NULL;
+ bool retry = false; /* allow one retry attempt for expired session */
if (sid_check_is_our_sam(&domain->sid)) {
if (domain->rodc == false || need_rw_dc == false) {
}
}
+retry:
status = init_dc_connection_rpc(domain, need_rw_dc);
if (!NT_STATUS_IS_OK(status)) {
return status;
result = get_trust_credentials(domain, talloc_tos(), false, &creds);
if (!NT_STATUS_IS_OK(result)) {
- DEBUG(10, ("cm_connect_sam: No no user available for "
+ DEBUG(10, ("cm_connect_sam: No user available for "
"domain %s, trying schannel\n", domain->name));
goto schannel;
}
smbXcli_conn_remote_name(conn->cli->conn),
creds,
&conn->samr_pipe);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
+ && !retry) {
+ invalidate_cm_connection(domain);
+ retry = true;
+ goto retry;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
"pipe for domain %s using NTLMSSP "
SEC_FLAG_MAXIMUM_ALLOWED,
&conn->sam_connect_handle,
&result);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
+ invalidate_cm_connection(domain);
+ TALLOC_FREE(conn->samr_pipe);
+ retry = true;
+ goto retry;
+ }
+
if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
goto open_domain;
}
nt_errstr(status) ));
goto anonymous;
}
- status = cli_rpc_pipe_open_schannel_with_key
+ TALLOC_FREE(creds);
+ result = get_trust_credentials(domain, talloc_tos(), true, &creds);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(10, ("cm_connect_sam: No user available for "
+ "domain %s (error %s), trying anon\n", domain->name,
+ nt_errstr(result)));
+ goto anonymous;
+ }
+ status = cli_rpc_pipe_open_schannel_with_creds
(conn->cli, &ndr_table_samr, NCACN_NP,
- domain->name, p_creds, &conn->samr_pipe);
+ creds, p_creds, &conn->samr_pipe);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
+ && !retry) {
+ invalidate_cm_connection(domain);
+ retry = true;
+ goto retry;
+ }
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
SEC_FLAG_MAXIMUM_ALLOWED,
&conn->sam_connect_handle,
&result);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
+ invalidate_cm_connection(domain);
+ TALLOC_FREE(conn->samr_pipe);
+ retry = true;
+ goto retry;
+ }
+
if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
goto open_domain;
}
status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr,
&conn->samr_pipe);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
+ && !retry) {
+ invalidate_cm_connection(domain);
+ retry = true;
+ goto retry;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
SEC_FLAG_MAXIMUM_ALLOWED,
&conn->sam_connect_handle,
&result);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
+ invalidate_cm_connection(domain);
+ TALLOC_FREE(conn->samr_pipe);
+ retry = true;
+ goto retry;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
"for domain %s Error was %s\n",
struct rpc_pipe_client **cli)
{
struct winbindd_cm_conn *conn;
- struct netlogon_creds_cli_context *creds;
+ struct netlogon_creds_cli_context *p_creds = NULL;
+ struct cli_credentials *creds = NULL;
NTSTATUS status;
DEBUG(10,("cm_connect_lsa_tcp\n"));
TALLOC_FREE(conn->lsa_pipe_tcp);
- status = cm_get_schannel_creds(domain, &creds);
+ status = cm_get_schannel_creds(domain, &p_creds);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = get_trust_credentials(domain, talloc_tos(), true, &creds);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
- &ndr_table_lsarpc,
- NCACN_IP_TCP,
- domain->name,
- creds,
- &conn->lsa_pipe_tcp);
+ status = cli_rpc_pipe_open_schannel_with_creds(conn->cli,
+ &ndr_table_lsarpc,
+ NCACN_IP_TCP,
+ creds,
+ p_creds,
+ &conn->lsa_pipe_tcp);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
nt_errstr(status)));
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
struct netlogon_creds_cli_context *p_creds;
struct cli_credentials *creds = NULL;
+ bool retry = false; /* allow one retry attempt for expired session */
+retry:
result = init_dc_connection_rpc(domain, false);
if (!NT_STATUS_IS_OK(result))
return result;
result = get_trust_credentials(domain, talloc_tos(), false, &creds);
if (!NT_STATUS_IS_OK(result)) {
- DEBUG(10, ("cm_connect_sam: No no user available for "
+ DEBUG(10, ("cm_connect_lsa: No user available for "
"domain %s, trying schannel\n", domain->name));
goto schannel;
}
smbXcli_conn_remote_name(conn->cli->conn),
creds,
&conn->lsa_pipe);
+
+ if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
+ && !retry) {
+ invalidate_cm_connection(domain);
+ retry = true;
+ goto retry;
+ }
+
if (!NT_STATUS_IS_OK(result)) {
DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
"domain %s using NTLMSSP authenticated pipe: user "
result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
SEC_FLAG_MAXIMUM_ALLOWED,
&conn->lsa_policy);
+ if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
+ invalidate_cm_connection(domain);
+ TALLOC_FREE(conn->lsa_pipe);
+ retry = true;
+ goto retry;
+ }
+
if (NT_STATUS_IS_OK(result)) {
goto done;
}
nt_errstr(result) ));
goto anonymous;
}
- result = cli_rpc_pipe_open_schannel_with_key
+
+ TALLOC_FREE(creds);
+ result = get_trust_credentials(domain, talloc_tos(), true, &creds);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(10, ("cm_connect_lsa: No user available for "
+ "domain %s (error %s), trying anon\n", domain->name,
+ nt_errstr(result)));
+ goto anonymous;
+ }
+ result = cli_rpc_pipe_open_schannel_with_creds
(conn->cli, &ndr_table_lsarpc, NCACN_NP,
- domain->name, p_creds, &conn->lsa_pipe);
+ creds, p_creds, &conn->lsa_pipe);
+
+ if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
+ && !retry) {
+ invalidate_cm_connection(domain);
+ retry = true;
+ goto retry;
+ }
if (!NT_STATUS_IS_OK(result)) {
DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
SEC_FLAG_MAXIMUM_ALLOWED,
&conn->lsa_policy);
+
+ if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
+ invalidate_cm_connection(domain);
+ TALLOC_FREE(conn->lsa_pipe);
+ retry = true;
+ goto retry;
+ }
+
if (NT_STATUS_IS_OK(result)) {
goto done;
}
if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
result = NT_STATUS_DOWNGRADE_DETECTED;
- DEBUG(1, ("Unwilling to make LSA connection to domain %s"
+ DEBUG(1, ("Unwilling to make LSA connection to domain %s "
"without connection level security, "
"must set 'winbind sealed pipes = false' and "
"'require strong key = false' to proceed: %s\n",
result = cli_rpc_pipe_open_noauth(conn->cli,
&ndr_table_lsarpc,
&conn->lsa_pipe);
+
+ if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
+ && !retry) {
+ invalidate_cm_connection(domain);
+ retry = true;
+ goto retry;
+ }
+
if (!NT_STATUS_IS_OK(result)) {
goto done;
}
result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
SEC_FLAG_MAXIMUM_ALLOWED,
&conn->lsa_policy);
+
+ if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
+ invalidate_cm_connection(domain);
+ TALLOC_FREE(conn->lsa_pipe);
+ retry = true;
+ goto retry;
+ }
+
done:
if (!NT_STATUS_IS_OK(result)) {
invalidate_cm_connection(domain);
struct winbindd_cm_conn *conn;
NTSTATUS result;
enum netr_SchannelType sec_chan_type;
- const char *account_name;
- const char *domain_name;
- const struct samr_Password *current_nt_hash = NULL;
- const struct samr_Password *previous_nt_hash = NULL;
struct netlogon_creds_CredentialState *netlogon_creds = NULL;
struct cli_credentials *creds = NULL;
*cli = NULL;
- result = init_dc_connection_rpc(domain, true);
+ result = init_dc_connection_rpc(domain, domain->rodc);
if (!NT_STATUS_IS_OK(result)) {
return result;
}
result = get_trust_credentials(domain, talloc_tos(), true, &creds);
if (!NT_STATUS_IS_OK(result)) {
- DEBUG(10, ("cm_connect_sam: No no user available for "
+ DEBUG(10, ("cm_connect_sam: No user available for "
"domain %s when trying schannel\n", domain->name));
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
sec_chan_type = cli_credentials_get_secure_channel_type(creds);
if (sec_chan_type == SEC_CHAN_NULL) {
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- goto no_schannel;
- }
-
- account_name = cli_credentials_get_username(creds);
- domain_name = cli_credentials_get_domain(creds);
- current_nt_hash = cli_credentials_get_nt_hash(creds, talloc_tos());
- if (current_nt_hash == NULL) {
- return NT_STATUS_NO_MEMORY;
}
- result = rpccli_create_netlogon_creds(domain->dcname,
- domain_name,
- account_name,
- sec_chan_type,
- msg_ctx,
- domain,
- &conn->netlogon_creds);
+ result = rpccli_create_netlogon_creds_with_creds(creds,
+ domain->dcname,
+ msg_ctx,
+ domain,
+ &conn->netlogon_creds);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(1, ("rpccli_create_netlogon_creds failed for %s, "
"unable to create NETLOGON credentials: %s\n",
return result;
}
- result = rpccli_setup_netlogon_creds(conn->cli, transport,
- conn->netlogon_creds,
- conn->netlogon_force_reauth,
- *current_nt_hash,
- previous_nt_hash);
+ result = rpccli_setup_netlogon_creds_with_creds(conn->cli, transport,
+ conn->netlogon_creds,
+ conn->netlogon_force_reauth,
+ creds);
conn->netlogon_force_reauth = false;
if (!NT_STATUS_IS_OK(result)) {
DEBUG(1, ("rpccli_setup_netlogon_creds failed for %s, "
conn->netlogon_flags = netlogon_creds->negotiate_flags;
TALLOC_FREE(netlogon_creds);
- no_schannel:
if (!(conn->netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
result = NT_STATUS_DOWNGRADE_DETECTED;
part of the new pipe auth struct.
*/
- result = cli_rpc_pipe_open_schannel_with_key(
+ result = cli_rpc_pipe_open_schannel_with_creds(
conn->cli, &ndr_table_netlogon, transport,
- domain->name,
+ creds,
conn->netlogon_creds,
&conn->netlogon_pipe);
if (!NT_STATUS_IS_OK(result)) {
{
NTSTATUS status;
- status = init_dc_connection_rpc(domain, true);
+ status = init_dc_connection_rpc(domain, domain->rodc);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
}
status = cm_connect_netlogon_transport(domain, NCACN_NP, cli);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
+ /*
+ * SMB2 session expired, needs reauthentication. Drop
+ * connection and retry.
+ */
+ invalidate_cm_connection(domain);
+ status = cm_connect_netlogon_transport(domain, NCACN_NP, cli);
+ }
return status;
}