#include "rpc_client/cli_lsarpc.h"
#include "../librpc/gen_ndr/ndr_dssetup_c.h"
#include "libads/sitename_cache.h"
-#include "librpc/gen_ndr/messaging.h"
+#include "libsmb/libsmb.h"
#include "libsmb/clidgram.h"
#include "ads.h"
#include "secrets.h"
#include "../libcli/security/security.h"
+#include "passdb.h"
+#include "messages.h"
+#include "auth/gensec/gensec.h"
+#include "../libcli/smb/smbXcli_base.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
struct dc_name_ip *dcs = NULL;
int num_dcs = 0;
TALLOC_CTX *mem_ctx = NULL;
- pid_t parent_pid = sys_getpid();
+ pid_t parent_pid = getpid();
char *lfile = NULL;
+ NTSTATUS status;
if (domain->dc_probe_pid != (pid_t)-1) {
/*
domain->dc_probe_pid = (pid_t)-1;
}
- domain->dc_probe_pid = sys_fork();
+ domain->dc_probe_pid = fork();
if (domain->dc_probe_pid == (pid_t)-1) {
DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno)));
}
}
- if (!winbindd_reinit_after_fork(lfile)) {
+ status = winbindd_reinit_after_fork(NULL, lfile);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
+ nt_errstr(status)));
messaging_send_buf(winbind_messaging_context(),
pid_to_procid(parent_pid),
MSG_WINBIND_FAILED_TO_GO_ONLINE,
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;
char *ipc_username = NULL;
char *ipc_domain = NULL;
char *ipc_password = NULL;
+ int flags = 0;
+ uint16_t sec_mode = 0;
struct named_mutex *mutex;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- struct sockaddr peeraddr;
- socklen_t peeraddr_len;
-
- struct sockaddr_in *peeraddr_in =
- (struct sockaddr_in *)(void *)&peeraddr;
-
DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
controller, domain->name ));
mutex = grab_named_mutex(talloc_tos(), controller,
WINBIND_SERVER_MUTEX_WAIT_TIME);
if (mutex == NULL) {
+ close(sockfd);
DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
controller));
result = NT_STATUS_POSSIBLE_DEADLOCK;
goto done;
}
- if ((*cli = cli_initialise()) == NULL) {
+ flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
+
+ *cli = cli_state_create(NULL, sockfd,
+ controller, domain->alt_name,
+ SMB_SIGNING_DEFAULT, flags);
+ if (*cli == NULL) {
+ close(sockfd);
DEBUG(1, ("Could not cli_initialize\n"));
result = NT_STATUS_NO_MEMORY;
goto done;
}
- (*cli)->timeout = 10000; /* 10 seconds */
- (*cli)->fd = sockfd;
- fstrcpy((*cli)->desthost, controller);
- (*cli)->use_kerberos = True;
-
- peeraddr_len = sizeof(peeraddr);
+ cli_set_timeout(*cli, 10000); /* 10 seconds */
- if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0)) {
- DEBUG(0,("cm_prepare_connection: getpeername failed with: %s\n",
- strerror(errno)));
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- if ((peeraddr_len != sizeof(struct sockaddr_in))
-#ifdef HAVE_IPV6
- && (peeraddr_len != sizeof(struct sockaddr_in6))
-#endif
- ) {
- DEBUG(0,("cm_prepare_connection: got unexpected peeraddr len %d\n",
- peeraddr_len));
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- if ((peeraddr_in->sin_family != PF_INET)
-#ifdef HAVE_IPV6
- && (peeraddr_in->sin_family != PF_INET6)
-#endif
- ) {
- DEBUG(0,("cm_prepare_connection: got unexpected family %d\n",
- peeraddr_in->sin_family));
- result = NT_STATUS_UNSUCCESSFUL;
- goto done;
- }
-
- result = cli_negprot(*cli);
+ result = cli_negprot(*cli, PROTOCOL_SMB2_02);
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)->protocol >= PROTOCOL_NT1 &&
- (*cli)->capabilities & CAP_EXTENDED_SECURITY)
- {
- ADS_STATUS ads_status;
+ 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);
(*cli)->use_kerberos = True;
DEBUG(5, ("connecting to %s from %s with kerberos principal "
- "[%s] and realm [%s]\n", controller, global_myname(),
+ "[%s] and realm [%s]\n", controller, lp_netbios_name(),
machine_krb5_principal, domain->alt_name));
winbindd_set_locator_kdc_envs(domain);
- ads_status = cli_session_setup_spnego(*cli,
- machine_krb5_principal,
- machine_password,
- lp_workgroup(),
- domain->alt_name);
+ result = cli_session_setup(*cli,
+ machine_krb5_principal,
+ machine_password,
+ strlen(machine_password)+1,
+ machine_password,
+ strlen(machine_password)+1,
+ lp_workgroup());
- if (!ADS_ERR_OK(ads_status)) {
+ if (!NT_STATUS_IS_OK(result)) {
DEBUG(4,("failed kerberos session setup with %s\n",
- ads_errstr(ads_status)));
+ nt_errstr(result)));
}
- result = ads_ntstatus(ads_status);
if (NT_STATUS_IS_OK(result)) {
/* Ensure creds are stored for NTLMSSP authenticated pipe access. */
result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
(*cli)->use_kerberos = False;
DEBUG(5, ("connecting to %s from %s with username "
- "[%s]\\[%s]\n", controller, global_myname(),
+ "[%s]\\[%s]\n", controller, lp_netbios_name(),
lp_workgroup(), machine_account));
- ads_status = cli_session_setup_spnego(*cli,
- machine_account,
- machine_password,
- lp_workgroup(),
- NULL);
- if (!ADS_ERR_OK(ads_status)) {
+ result = cli_session_setup(*cli,
+ machine_account,
+ machine_password,
+ strlen(machine_password)+1,
+ machine_password,
+ strlen(machine_password)+1,
+ lp_workgroup());
+ if (!NT_STATUS_IS_OK(result)) {
DEBUG(4, ("authenticated session setup failed with %s\n",
- ads_errstr(ads_status)));
+ nt_errstr(result)));
}
- result = ads_ntstatus(ads_status);
if (NT_STATUS_IS_OK(result)) {
/* Ensure creds are stored for NTLMSSP authenticated pipe access. */
result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
- if ((((*cli)->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 */
DEBUG(5, ("connecting to %s from %s with username "
- "[%s]\\[%s]\n", controller, global_myname(),
+ "[%s]\\[%s]\n", controller, lp_netbios_name(),
ipc_domain, ipc_username));
if (NT_STATUS_IS_OK(cli_session_setup(
"connection for DC %s\n",
controller ));
- if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
- NULL, 0, ""))) {
+ result = cli_session_setup(*cli, "", NULL, 0, NULL, 0, "");
+ if (NT_STATUS_IS_OK(result)) {
DEBUG(5, ("Connected anonymously\n"));
result = cli_init_creds(*cli, "", "", "");
if (!NT_STATUS_IS_OK(result)) {
goto session_setup_done;
}
- result = cli_nt_error(*cli);
-
- if (NT_STATUS_IS_OK(result))
- result = NT_STATUS_UNSUCCESSFUL;
-
/* We can't session setup */
-
goto done;
session_setup_done:
/* cache the server name for later connections */
- saf_store( domain->name, (*cli)->desthost );
+ saf_store(domain->name, controller);
if (domain->alt_name && (*cli)->use_kerberos) {
- saf_store( domain->alt_name, (*cli)->desthost );
+ saf_store(domain->alt_name, controller);
}
winbindd_set_locator_kdc_envs(domain);
- result = cli_tcon_andx(*cli, "IPC$", "IPC", "", 0);
+ result = cli_tree_connect(*cli, "IPC$", "IPC", "", 0);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
(struct sockaddr *)(void *)pss))
return False;
- *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
+ *dcs = talloc_realloc(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
if (*dcs == NULL)
return False;
struct sockaddr_storage *pss, uint16 port,
struct sockaddr_storage **addrs, int *num)
{
- *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
+ *addrs = talloc_realloc(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
if (*addrs == NULL) {
*num = 0;
ip_list.ss = *pss;
ip_list.port = 0;
-#ifdef WITH_ADS
+#ifdef HAVE_ADS
/* For active directory servers, try to get the ldap server name.
None of these failures should be considered critical for now */
}
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)) {
&dcnames, &num_dcnames)) {
return False;
}
- if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 445,
+ if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, TCP_SMB_PORT,
&addrs, &num_addrs)) {
return False;
}
return False;
status = smbsock_any_connect(addrs, dcnames, NULL, NULL, NULL,
- num_addrs, 0, fd, &fd_index, NULL);
+ num_addrs, 0, 10, fd, &fd_index, NULL);
if (!NT_STATUS_IS_OK(status)) {
for (i=0; i<num_dcs; i++) {
char ab[INET6_ADDRSTRLEN];
char *key = NULL;
char *value = NULL;
- if (cli == NULL) {
- return;
- }
- if (cli->fd == -1) {
+ if (!cli_state_is_connected(cli)) {
return;
}
- get_peer_addr(cli->fd, addr, sizeof(addr));
+
+ print_sockaddr(addr, sizeof(addr),
+ smbXcli_conn_remote_sockaddr(cli->conn));
key = current_dc_key(talloc_tos(), domain_name);
if (key == NULL) {
return NT_STATUS_UNSUCCESSFUL;
}
if (dcip_to_name(mem_ctx, domain, &ss, saf_name )) {
- fstrcpy( domain->dcname, saf_name );
+ strlcpy(domain->dcname, saf_name, sizeof(domain->dcname));
} else {
winbind_add_failed_connection_entry(
domain, saf_servername,
status = smbsock_connect(&domain->dcaddr, 0,
NULL, -1, NULL, -1,
- &fd, NULL);
+ &fd, NULL, 10);
if (!NT_STATUS_IS_OK(status)) {
fd = -1;
}
if (conn->lsa_pipe_tcp != NULL) {
if (is_valid_policy_hnd(&conn->lsa_policy)) {
- dcerpc_lsa_Close(conn->lsa_pipe->binding_handle,
+ dcerpc_lsa_Close(conn->lsa_pipe_tcp->binding_handle,
talloc_tos(),
&conn->lsa_policy,
&result);
void close_conns_after_fork(void)
{
struct winbindd_domain *domain;
+ struct winbindd_cli_state *cli_state;
for (domain = domain_list(); domain; domain = domain->next) {
- struct cli_state *cli = domain->conn.cli;
-
/*
* first close the low level SMB TCP connection
* so that we don't generate any SMBclose
* requests in invalidate_cm_connection()
*/
- if (cli && cli->fd != -1) {
- close(domain->conn.cli->fd);
- domain->conn.cli->fd = -1;
+ if (cli_state_is_connected(domain->conn.cli)) {
+ cli_state_disconnect(domain->conn.cli);
}
invalidate_cm_connection(&domain->conn);
}
+
+ for (cli_state = winbindd_client_list();
+ cli_state != NULL;
+ cli_state = cli_state->next) {
+ if (cli_state->sock >= 0) {
+ close(cli_state->sock);
+ cli_state->sock = -1;
+ }
+ }
}
static bool connection_ok(struct winbindd_domain *domain)
"running active directory.\n", domain->name,
domain->active_directory ? "" : "NOT "));
+ domain->can_do_ncacn_ip_tcp = domain->active_directory;
+ domain->can_do_validation6 = domain->active_directory;
domain->initialized = True;
* no_dssetup mode here as well to get domain->initialized
* set - gd */
- if (NT_STATUS_V(status) == DCERPC_FAULT_OP_RNG_ERROR) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
goto no_dssetup;
}
/* We have an authenticated connection. Use a NTLMSSP SPNEGO
authenticated SAMR pipe with sign & seal. */
- status = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
- &ndr_table_samr.syntax_id,
- NCACN_NP,
- DCERPC_AUTH_LEVEL_PRIVACY,
- domain_name,
- machine_account,
- machine_password,
- &conn->samr_pipe);
+ status = cli_rpc_pipe_open_spnego(conn->cli,
+ &ndr_table_samr,
+ NCACN_NP,
+ GENSEC_OID_NTLMSSP,
+ DCERPC_AUTH_LEVEL_PRIVACY,
+ smbXcli_conn_remote_name(conn->cli->conn),
+ domain_name,
+ machine_account,
+ machine_password,
+ &conn->samr_pipe);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
/* We have an authenticated connection. Use a NTLMSSP SPNEGO
* authenticated LSA pipe with sign & seal. */
- result = cli_rpc_pipe_open_spnego_ntlmssp
- (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
+ result = cli_rpc_pipe_open_spnego
+ (conn->cli, &ndr_table_lsarpc, NCACN_NP,
+ GENSEC_OID_NTLMSSP,
DCERPC_AUTH_LEVEL_PRIVACY,
+ smbXcli_conn_remote_name(conn->cli->conn),
conn->cli->domain, conn->cli->user_name, conn->cli->password,
&conn->lsa_pipe);
netlogon_pipe,
domain->dcname, /* server name. */
domain->name, /* domain name */
- global_myname(), /* client name */
+ lp_netbios_name(), /* client name */
account_name, /* machine account */
mach_pwd, /* machine password */
sec_chan_type, /* from get_trust_pw */
for (domain = domain_list(); domain != NULL; domain = domain->next) {
char sockaddr[INET6_ADDRSTRLEN];
- if (domain->conn.cli == NULL) {
- continue;
- }
- if (domain->conn.cli->fd == -1) {
+
+ if (!cli_state_is_connected(domain->conn.cli)) {
continue;
}
- client_socket_addr(domain->conn.cli->fd, sockaddr,
- sizeof(sockaddr));
+
+ print_sockaddr(sockaddr, sizeof(sockaddr),
+ smbXcli_conn_local_sockaddr(domain->conn.cli->conn));
+
if (strequal(sockaddr, addr)) {
- close(domain->conn.cli->fd);
- domain->conn.cli->fd = -1;
+ cli_state_disconnect(domain->conn.cli);
}
}
TALLOC_FREE(freeit);