#include "passdb.h"
#include "messages.h"
#include "auth/gensec/gensec.h"
+#include "../libcli/smb/smbXcli_base.h"
+#include "lib/param/loadparm.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
messaging_send_buf(winbind_messaging_context(),
pid_to_procid(parent_pid),
MSG_WINBIND_FAILED_TO_GO_ONLINE,
- (uint8 *)domain->name,
+ (const uint8_t *)domain->name,
strlen(domain->name)+1);
_exit(1);
}
messaging_send_buf(winbind_messaging_context(),
pid_to_procid(parent_pid),
MSG_WINBIND_FAILED_TO_GO_ONLINE,
- (uint8 *)domain->name,
+ (const uint8_t *)domain->name,
strlen(domain->name)+1);
_exit(1);
}
messaging_send_buf(winbind_messaging_context(),
pid_to_procid(parent_pid),
MSG_WINBIND_FAILED_TO_GO_ONLINE,
- (uint8 *)domain->name,
+ (const uint8_t *)domain->name,
strlen(domain->name)+1);
_exit(0);
}
messaging_send_buf(winbind_messaging_context(),
pid_to_procid(parent_pid),
MSG_WINBIND_TRY_TO_GO_ONLINE,
- (uint8 *)domain->name,
+ (const uint8_t *)domain->name,
strlen(domain->name)+1);
_exit(0);
}
Handler triggered if we're offline to try and detect a DC.
****************************************************************/
-static void check_domain_online_handler(struct event_context *ctx,
- struct timed_event *te,
+static void check_domain_online_handler(struct tevent_context *ctx,
+ struct tevent_timer *te,
struct timeval now,
void *private_data)
{
}
}
+void winbind_msg_domain_offline(struct messaging_context *msg_ctx,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
+{
+ const char *domain_name = (const char *)data->data;
+ struct winbindd_domain *domain;
+
+ domain = find_domain_from_name_noinit(domain_name);
+ if (domain == NULL) {
+ return;
+ }
+
+ domain->online = false;
+
+ DEBUG(10, ("Domain %s is marked as offline now.\n",
+ domain_name));
+}
+
+void winbind_msg_domain_online(struct messaging_context *msg_ctx,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
+{
+ const char *domain_name = (const char *)data->data;
+ struct winbindd_domain *domain;
+
+ domain = find_domain_from_name_noinit(domain_name);
+ if (domain == NULL) {
+ return;
+ }
+
+ domain->online = true;
+
+ DEBUG(10, ("Domain %s is marked as online now.\n",
+ domain_name));
+}
+
/****************************************************************
Set domain offline and also add handler to put us back online
if we detect a DC.
void set_domain_offline(struct winbindd_domain *domain)
{
+ pid_t parent_pid = getppid();
+
DEBUG(10,("set_domain_offline: called for domain %s\n",
domain->name ));
calc_new_online_timeout_check(domain);
- domain->check_online_event = event_add_timed(winbind_event_context(),
+ domain->check_online_event = tevent_add_timer(winbind_event_context(),
NULL,
timeval_current_ofs(domain->check_online_timeout,0),
check_domain_online_handler,
DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
domain->name ));
+ /* Send a message to the parent that the domain is offline. */
+ if (parent_pid > 1 && !domain->internal) {
+ messaging_send_buf(winbind_messaging_context(),
+ pid_to_procid(parent_pid),
+ MSG_WINBIND_DOMAIN_OFFLINE,
+ (uint8 *)domain->name,
+ strlen(domain->name) + 1);
+ }
+
/* Send an offline message to the idmap child when our
primary domain goes offline */
messaging_send_buf(winbind_messaging_context(),
pid_to_procid(idmap->pid),
MSG_WINBIND_OFFLINE,
- (uint8 *)domain->name,
+ (const uint8_t *)domain->name,
strlen(domain->name)+1);
}
}
static void set_domain_online(struct winbindd_domain *domain)
{
+ pid_t parent_pid = getppid();
+
DEBUG(10,("set_domain_online: called for domain %s\n",
domain->name ));
domain->online = True;
+ /* Send a message to the parent that the domain is online. */
+ if (parent_pid > 1 && !domain->internal) {
+ messaging_send_buf(winbind_messaging_context(),
+ pid_to_procid(parent_pid),
+ MSG_WINBIND_DOMAIN_ONLINE,
+ (uint8 *)domain->name,
+ strlen(domain->name) + 1);
+ }
+
/* Send an online message to the idmap child when our
primary domain comes online */
messaging_send_buf(winbind_messaging_context(),
pid_to_procid(idmap->pid),
MSG_WINBIND_ONLINE,
- (uint8 *)domain->name,
+ (const uint8_t *)domain->name,
strlen(domain->name)+1);
}
}
TALLOC_FREE(domain->check_online_event);
- domain->check_online_event = event_add_timed(winbind_event_context(),
+ domain->check_online_event = tevent_add_timer(winbind_event_context(),
NULL,
tev,
check_domain_online_handler,
/* If this was the saf name for the last thing we talked to,
remove it. */
saf_delete(domain->name);
- if (*domain->alt_name) {
+ if (domain->alt_name != NULL) {
add_failed_connection_entry(domain->alt_name, server, result);
saf_delete(domain->alt_name);
}
talloc_destroy(mem_ctx);
return false;
}
- if (strlen(domain->alt_name) == 0) {
- fstrcpy(domain->alt_name,
- domain_info->domain_name);
+ if (domain->alt_name == NULL) {
+ domain->alt_name = talloc_strdup(domain,
+ domain_info->domain_name);
+ if (domain->alt_name == NULL) {
+ DEBUG(0, ("talloc_strdup failed\n"));
+ talloc_destroy(mem_ctx);
+ return false;
+ }
}
- if (strlen(domain->forest_name) == 0) {
- fstrcpy(domain->forest_name,
- domain_info->forest_name);
+ if (domain->forest_name == NULL) {
+ domain->forest_name = talloc_strdup(domain,
+ domain_info->forest_name);
+ if (domain->forest_name == NULL) {
+ DEBUG(0, ("talloc_strdup failed\n"));
+ talloc_destroy(mem_ctx);
+ return false;
+ }
}
}
} else {
return NT_STATUS_NO_MEMORY;
}
- strupper_m(*machine_krb5_principal);
+ if (!strupper_m(*machine_krb5_principal)) {
+ SAFE_FREE(*machine_krb5_principal);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
}
return NT_STATUS_OK;
struct cli_state **cli,
bool *retry)
{
+ bool try_spnego = false;
+ bool try_ipc_auth = false;
char *machine_password = NULL;
char *machine_krb5_principal = NULL;
char *machine_account = NULL;
cli_set_timeout(*cli, 10000); /* 10 seconds */
- result = cli_negprot(*cli, PROTOCOL_NT1);
+ result = smbXcli_negprot((*cli)->conn, (*cli)->timeout,
+ lp_cli_minprotocol(),
+ lp_cli_maxprotocol());
if (!NT_STATUS_IS_OK(result)) {
DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result)));
goto done;
}
- if (!is_dc_trusted_domain_situation(domain->name) &&
- cli_state_protocol(*cli) >= PROTOCOL_NT1 &&
- cli_state_capabilities(*cli) & CAP_EXTENDED_SECURITY)
- {
+ if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_NT1 &&
+ smb1cli_conn_capabilities((*cli)->conn) & CAP_EXTENDED_SECURITY) {
+ try_spnego = true;
+ } else if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) {
+ try_spnego = true;
+ }
+
+ if (!is_dc_trusted_domain_situation(domain->name) && try_spnego) {
result = get_trust_creds(domain, &machine_password,
&machine_account,
&machine_krb5_principal);
cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
- sec_mode = cli_state_security_mode(*cli);
- if (((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
- (strlen(ipc_username) > 0)) {
+ sec_mode = smb1cli_conn_server_security_mode((*cli)->conn);
+
+ try_ipc_auth = false;
+ if (try_spnego) {
+ try_ipc_auth = true;
+ } else if (sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) {
+ try_ipc_auth = true;
+ }
+
+ if (try_ipc_auth && (strlen(ipc_username) > 0)) {
/* Only try authenticated if we have a username */
session_setup_done:
+ /*
+ * This should be a short term hack until
+ * dynamic re-authentication is implemented.
+ *
+ * See Bug 9175 - winbindd doesn't recover from
+ * NT_STATUS_NETWORK_SESSION_EXPIRED
+ */
+ if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) {
+ smbXcli_session_set_disconnect_expired((*cli)->smb2.session);
+ }
+
/* cache the server name for later connections */
saf_store(domain->name, controller);
if ( !(*cli)->domain[0] ) {
result = cli_set_domain((*cli), domain->name);
if (!NT_STATUS_IS_OK(result)) {
+ SAFE_FREE(ipc_username);
+ SAFE_FREE(ipc_domain);
+ SAFE_FREE(ipc_password);
return result;
}
}
static bool dcip_to_name(TALLOC_CTX *mem_ctx,
const struct winbindd_domain *domain,
struct sockaddr_storage *pss,
- fstring name )
+ char **name)
{
struct ip_service ip_list;
uint32_t nt_version = NETLOGON_NT_VERSION_1;
NTSTATUS status;
const char *dc_name;
+ fstring nbtname;
ip_list.ss = *pss;
ip_list.port = 0;
ads_status = ads_connect(ads);
if (ADS_ERR_OK(ads_status)) {
/* We got a cldap packet. */
- fstrcpy(name, ads->config.ldap_server_name);
- namecache_store(name, 0x20, 1, &ip_list);
+ *name = talloc_strdup(mem_ctx,
+ ads->config.ldap_server_name);
+ if (*name == NULL) {
+ return false;
+ }
+ namecache_store(*name, 0x20, 1, &ip_list);
DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
if (ads_closest_dc(ads)) {
- char *sitename = sitename_fetch(ads->config.realm);
+ char *sitename = sitename_fetch(mem_ctx, ads->config.realm);
/* We're going to use this KDC for this realm/domain.
If we are using sites, then force the krb5 libs
domain->name,
sitename,
pss,
- name);
+ *name);
- SAFE_FREE(sitename);
+ TALLOC_FREE(sitename);
} else {
/* use an off site KDC */
create_local_private_krb5_conf_for_domain(domain->alt_name,
domain->name,
NULL,
pss,
- name);
+ *name);
}
winbindd_set_locator_kdc_envs(domain);
/* Ensure we contact this DC also. */
- saf_store( domain->name, name);
- saf_store( domain->alt_name, name);
+ saf_store(domain->name, *name);
+ saf_store(domain->alt_name, *name);
}
ads_destroy( &ads );
}
ads_destroy( &ads );
+ return false;
}
#endif
- status = nbt_getdc(winbind_messaging_context(), pss, domain->name,
+ status = nbt_getdc(winbind_messaging_context(), 10, pss, domain->name,
&domain->sid, nt_version, mem_ctx, &nt_version,
&dc_name, NULL);
if (NT_STATUS_IS_OK(status)) {
- fstrcpy(name, dc_name);
- namecache_store(name, 0x20, 1, &ip_list);
+ *name = talloc_strdup(mem_ctx, dc_name);
+ if (*name == NULL) {
+ return false;
+ }
+ namecache_store(*name, 0x20, 1, &ip_list);
return True;
}
/* try node status request */
- if ( name_status_find(domain->name, 0x1c, 0x20, pss, name) ) {
- namecache_store(name, 0x20, 1, &ip_list);
- return True;
+ if (name_status_find(domain->name, 0x1c, 0x20, pss, nbtname) ) {
+ namecache_store(nbtname, 0x20, 1, &ip_list);
+
+ if (name != NULL) {
+ *name = talloc_strdup(mem_ctx, nbtname);
+ if (*name == NULL) {
+ return false;
+ }
+ }
+
+ return true;
}
return False;
}
get_dc_name(domain->name, domain->alt_name, dcname, &ss);
- sitename = sitename_fetch(domain->alt_name);
+ sitename = sitename_fetch(mem_ctx, domain->alt_name);
if (sitename) {
/* Do the site-specific AD dns lookup first. */
}
SAFE_FREE(ip_list);
- SAFE_FREE(sitename);
+ TALLOC_FREE(sitename);
iplist_size = 0;
}
iplist_size = 0;
}
- /* Try standard netbios queries if no ADS */
+ /* Try standard netbios queries if no ADS and fall back to DNS queries
+ * if alt_name is available */
if (*num_dcs == 0) {
get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size,
- False);
+ false);
+ if (iplist_size == 0) {
+ if (domain->alt_name != NULL) {
+ get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
+ &iplist_size, true);
+ }
+ }
for ( i=0; i<iplist_size; i++ ) {
char addr[INET6_ADDRSTRLEN];
static bool find_new_dc(TALLOC_CTX *mem_ctx,
struct winbindd_domain *domain,
- fstring dcname, struct sockaddr_storage *pss, int *fd)
+ char **dcname, struct sockaddr_storage *pss, int *fd)
{
struct dc_name_ip *dcs = NULL;
int num_dcs = 0;
if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
/* Ok, we've got a name for the DC */
- fstrcpy(dcname, dcnames[fd_index]);
- return True;
+ *dcname = talloc_strdup(mem_ctx, dcnames[fd_index]);
+ if (*dcname == NULL) {
+ return false;
+ }
+ return true;
}
/* Try to figure out the name */
}
print_sockaddr(addr, sizeof(addr),
- cli_state_remote_sockaddr(cli));
+ smbXcli_conn_remote_sockaddr(cli->conn));
key = current_dc_key(talloc_tos(), domain_name);
if (key == NULL) {
const char *domain_name,
char **p_dc_name, char **p_dc_ip)
{
- char *key, *value, *p;
+ char *key, *p;
+ char *value = NULL;
bool ret = false;
char *dc_name = NULL;
char *dc_ip = NULL;
if (key == NULL) {
goto done;
}
- if (!gencache_get(key, &value, NULL)) {
+ if (!gencache_get(key, mem_ctx, &value, NULL)) {
goto done;
}
p = strchr(value, ' ');
TALLOC_FREE(dc_name);
TALLOC_FREE(dc_ip);
TALLOC_FREE(key);
+ TALLOC_FREE(value);
return ret;
}
{
TALLOC_CTX *mem_ctx;
NTSTATUS result;
- char *saf_servername = saf_fetch( domain->name );
+ char *saf_servername;
int retries;
if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
- SAFE_FREE(saf_servername);
set_domain_offline(domain);
return NT_STATUS_NO_MEMORY;
}
+ saf_servername = saf_fetch(mem_ctx, domain->name );
+
/* we have to check the server affinity cache here since
later we select a DC based on response time and not preference */
/* convert an ip address to a name */
if (is_ipaddress( saf_servername ) ) {
- fstring saf_name;
+ char *dcname = NULL;
struct sockaddr_storage ss;
if (!interpret_string_addr(&ss, saf_servername,
AI_NUMERICHOST)) {
+ TALLOC_FREE(mem_ctx);
return NT_STATUS_UNSUCCESSFUL;
}
- if (dcip_to_name(mem_ctx, domain, &ss, saf_name )) {
- strlcpy(domain->dcname, saf_name, sizeof(domain->dcname));
+ if (dcip_to_name(mem_ctx, domain, &ss, &dcname)) {
+ domain->dcname = talloc_strdup(domain,
+ dcname);
+ if (domain->dcname == NULL) {
+ TALLOC_FREE(mem_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
} else {
winbind_add_failed_connection_entry(
domain, saf_servername,
NT_STATUS_UNSUCCESSFUL);
}
} else {
- fstrcpy( domain->dcname, saf_servername );
+ domain->dcname = talloc_strdup(domain, saf_servername);
+ if (domain->dcname == NULL) {
+ TALLOC_FREE(mem_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
}
-
- SAFE_FREE( saf_servername );
}
for (retries = 0; retries < 3; retries++) {
int fd = -1;
bool retry = False;
+ char *dcname = NULL;
result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
- domain->dcname, domain->name ));
+ domain->dcname ? domain->dcname : "", domain->name ));
- if (*domain->dcname
+ if (domain->dcname != NULL
&& NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
&& (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
{
}
}
- if ((fd == -1)
- && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
+ if ((fd == -1) &&
+ !find_new_dc(mem_ctx, domain, &dcname, &domain->dcaddr, &fd))
{
/* This is the one place where we will
set the global winbindd offline state
set_global_winbindd_state_offline();
break;
}
+ if (dcname != NULL) {
+ talloc_free(domain->dcname);
+
+ domain->dcname = talloc_move(domain, &dcname);
+ if (domain->dcname == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ break;
+ }
+ }
new_conn->cli = NULL;
result = cm_prepare_connection(domain, fd, domain->dcname,
&new_conn->cli, &retry);
+ if (!NT_STATUS_IS_OK(result)) {
+ /* Don't leak the smb connection socket */
+ close(fd);
+ }
if (!retry)
break;
* requests in invalidate_cm_connection()
*/
if (cli_state_is_connected(domain->conn.cli)) {
- cli_state_disconnect(domain->conn.cli);
+ smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
}
invalidate_cm_connection(&domain->conn);
return NT_STATUS_OK;
}
- if (!winbindd_can_contact_domain(domain)) {
- invalidate_cm_connection(&domain->conn);
- domain->initialized = True;
- return NT_STATUS_OK;
- }
-
if (connection_ok(domain)) {
if (!domain->initialized) {
set_dc_type_and_flags(domain);
DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
status = cli_rpc_pipe_open_noauth(domain->conn.cli,
- &ndr_table_dssetup.syntax_id,
+ &ndr_table_dssetup,
&cli);
if (!NT_STATUS_IS_OK(status)) {
no_dssetup:
status = cli_rpc_pipe_open_noauth(domain->conn.cli,
- &ndr_table_lsarpc.syntax_id, &cli);
+ &ndr_table_lsarpc, &cli);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
domain->active_directory = True;
if (lsa_info->dns.name.string) {
- fstrcpy(domain->name, lsa_info->dns.name.string);
+ talloc_free(domain->name);
+ domain->name = talloc_strdup(domain,
+ lsa_info->dns.name.string);
+ if (domain->name == NULL) {
+ goto done;
+ }
}
if (lsa_info->dns.dns_domain.string) {
- fstrcpy(domain->alt_name,
- lsa_info->dns.dns_domain.string);
+ talloc_free(domain->alt_name);
+ domain->alt_name =
+ talloc_strdup(domain,
+ lsa_info->dns.dns_domain.string);
+ if (domain->alt_name == NULL) {
+ goto done;
+ }
}
/* See if we can set some domain trust flags about
ourself */
if (lsa_info->dns.dns_forest.string) {
- fstrcpy(domain->forest_name,
- lsa_info->dns.dns_forest.string);
+ talloc_free(domain->forest_name);
+ domain->forest_name =
+ talloc_strdup(domain,
+ lsa_info->dns.dns_forest.string);
+ if (domain->forest_name == NULL) {
+ goto done;
+ }
if (strequal(domain->forest_name, domain->alt_name)) {
domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
if (lsa_info->account_domain.name.string) {
- fstrcpy(domain->name,
- lsa_info->account_domain.name.string);
+ talloc_free(domain->name);
+ domain->name =
+ talloc_strdup(domain,
+ lsa_info->account_domain.name.string);
}
if (lsa_info->account_domain.sid) {
struct netlogon_creds_CredentialState *p_creds;
char *machine_password = NULL;
char *machine_account = NULL;
- char *domain_name = NULL;
+ const char *domain_name = NULL;
- if (sid_check_is_domain(&domain->sid)) {
+ if (sid_check_is_our_sam(&domain->sid)) {
return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
}
NCACN_NP,
GENSEC_OID_NTLMSSP,
DCERPC_AUTH_LEVEL_PRIVACY,
- cli_state_remote_name(conn->cli),
+ smbXcli_conn_remote_name(conn->cli->conn),
domain_name,
machine_account,
machine_password,
goto anonymous;
}
status = cli_rpc_pipe_open_schannel_with_key
- (conn->cli, &ndr_table_samr.syntax_id, NCACN_NP,
+ (conn->cli, &ndr_table_samr, NCACN_NP,
DCERPC_AUTH_LEVEL_PRIVACY,
domain->name, &p_creds, &conn->samr_pipe);
anonymous:
/* Finally fall back to anonymous. */
- status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
+ status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr,
&conn->samr_pipe);
if (!NT_STATUS_IS_OK(status)) {
}
status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
- &ndr_table_lsarpc.syntax_id,
+ &ndr_table_lsarpc,
NCACN_IP_TCP,
DCERPC_AUTH_LEVEL_PRIVACY,
domain->name,
(conn->cli, &ndr_table_lsarpc, NCACN_NP,
GENSEC_OID_NTLMSSP,
DCERPC_AUTH_LEVEL_PRIVACY,
- cli_state_remote_name(conn->cli),
+ smbXcli_conn_remote_name(conn->cli->conn),
conn->cli->domain, conn->cli->user_name, conn->cli->password,
&conn->lsa_pipe);
goto anonymous;
}
result = cli_rpc_pipe_open_schannel_with_key
- (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
+ (conn->cli, &ndr_table_lsarpc, NCACN_NP,
DCERPC_AUTH_LEVEL_PRIVACY,
domain->name, &p_creds, &conn->lsa_pipe);
anonymous:
result = cli_rpc_pipe_open_noauth(conn->cli,
- &ndr_table_lsarpc.syntax_id,
+ &ndr_table_lsarpc,
&conn->lsa_pipe);
if (!NT_STATUS_IS_OK(result)) {
- result = NT_STATUS_PIPE_NOT_AVAILABLE;
goto done;
}
return result;
}
+/****************************************************************************
+Open a LSA connection to a DC, suiteable for LSA lookup calls.
+****************************************************************************/
+
+NTSTATUS cm_connect_lsat(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ struct rpc_pipe_client **cli,
+ struct policy_handle *lsa_policy)
+{
+ NTSTATUS status;
+
+ if (domain->can_do_ncacn_ip_tcp) {
+ status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
+ invalidate_cm_connection(&domain->conn);
+ status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
+ }
+ if (NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /*
+ * we tried twice to connect via ncan_ip_tcp and schannel and
+ * failed - maybe it is a trusted domain we can't connect to ?
+ * do not try tcp next time - gd
+ */
+ domain->can_do_ncacn_ip_tcp = false;
+ }
+
+ status = cm_connect_lsa(domain, mem_ctx, cli, lsa_policy);
+
+ return status;
+}
+
/****************************************************************************
Open the netlogon pipe to this DC. Use schannel if specified in client conf.
session key stored in conn->netlogon_pipe->dc->sess_key.
struct winbindd_cm_conn *conn;
NTSTATUS result;
- uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
- uint8 mach_pwd[16];
+ uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
+ uint8_t mach_pwd[16];
enum netr_SchannelType sec_chan_type;
const char *account_name;
struct rpc_pipe_client *netlogon_pipe = NULL;
TALLOC_FREE(conn->netlogon_pipe);
result = cli_rpc_pipe_open_noauth(conn->cli,
- &ndr_table_netlogon.syntax_id,
+ &ndr_table_netlogon,
&netlogon_pipe);
if (!NT_STATUS_IS_OK(result)) {
return result;
*/
result = cli_rpc_pipe_open_schannel_with_key(
- conn->cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
+ conn->cli, &ndr_table_netlogon, NCACN_NP,
DCERPC_AUTH_LEVEL_PRIVACY, domain->name, &netlogon_pipe->dc,
&conn->netlogon_pipe);
}
print_sockaddr(sockaddr, sizeof(sockaddr),
- cli_state_local_sockaddr(domain->conn.cli));
+ smbXcli_conn_local_sockaddr(domain->conn.cli->conn));
if (strequal(sockaddr, addr)) {
- cli_state_disconnect(domain->conn.cli);
+ smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
}
}
TALLOC_FREE(freeit);