#include "winbindd.h"
#include "../libcli/auth/libcli_auth.h"
#include "../librpc/gen_ndr/cli_netlogon.h"
+#include "rpc_client/cli_netlogon.h"
#include "../librpc/gen_ndr/cli_samr.h"
#include "../librpc/gen_ndr/cli_lsa.h"
+#include "rpc_client/cli_lsarpc.h"
#include "../librpc/gen_ndr/cli_dssetup.h"
#include "libads/sitename_cache.h"
+#include "librpc/gen_ndr/messaging.h"
+#include "libsmb/clidgram.h"
+#include "ads.h"
+#include "secrets.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
pid_t parent_pid = sys_getpid();
char *lfile = NULL;
- /* Stop zombies */
- CatchChild();
-
if (domain->dc_probe_pid != (pid_t)-1) {
/*
* We might already have a DC probe
peeraddr_len = sizeof(peeraddr);
- if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0) ||
- (peeraddr_len != sizeof(struct sockaddr_in)) ||
- (peeraddr_in->sin_family != PF_INET))
- {
- DEBUG(0,("cm_prepare_connection: %s\n", strerror(errno)));
+ 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;
}
create_local_private_krb5_conf_for_domain(domain->alt_name,
domain->name,
sitename,
- pss);
+ pss,
+ name);
SAFE_FREE(sitename);
} else {
create_local_private_krb5_conf_for_domain(domain->alt_name,
domain->name,
NULL,
- pss);
+ pss,
+ name);
}
winbindd_set_locator_kdc_envs(domain);
}
/* we have to check the server affinity cache here since
- later we selecte a DC based on response time and not preference */
+ later we select a DC based on response time and not preference */
/* Check the negative connection cache
before talking to it. It going down may have
}
if (conn->samr_pipe != NULL) {
+ if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
+ rpccli_samr_Close(conn->samr_pipe, talloc_tos(),
+ &conn->sam_connect_handle);
+ }
TALLOC_FREE(conn->samr_pipe);
/* Ok, it must be dead. Drop timeout to 0.5 sec. */
if (conn->cli) {
}
if (conn->lsa_pipe != NULL) {
+ if (is_valid_policy_hnd(&conn->lsa_policy)) {
+ rpccli_lsa_Close(conn->lsa_pipe, talloc_tos(),
+ &conn->lsa_policy);
+ }
TALLOC_FREE(conn->lsa_pipe);
/* Ok, it must be dead. Drop timeout to 0.5 sec. */
if (conn->cli) {
}
if (conn->lsa_pipe_tcp != NULL) {
+ if (is_valid_policy_hnd(&conn->lsa_policy)) {
+ rpccli_lsa_Close(conn->lsa_pipe, talloc_tos(),
+ &conn->lsa_policy);
+ }
TALLOC_FREE(conn->lsa_pipe_tcp);
/* Ok, it must be dead. Drop timeout to 0.5 sec. */
if (conn->cli) {
NTSTATUS init_dc_connection(struct winbindd_domain *domain)
{
+ if (domain->internal) {
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+
if (domain->initialized && !domain->online) {
/* We check for online status elsewhere. */
return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
/**********************************************************************
***********************************************************************/
-static bool cm_get_schannel_creds(struct winbindd_domain *domain,
+static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
struct netlogon_creds_CredentialState **ppdc)
{
- NTSTATUS result;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
struct rpc_pipe_client *netlogon_pipe;
if (lp_client_schannel() == False) {
- return False;
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;;
}
result = cm_connect_netlogon(domain, &netlogon_pipe);
if (!NT_STATUS_IS_OK(result)) {
- return False;
+ return result;
}
/* Return a pointer to the struct netlogon_creds_CredentialState from the
netlogon pipe. */
if (!domain->conn.netlogon_pipe->dc) {
- return false;
+ return NT_STATUS_INTERNAL_ERROR; /* This shouldn't happen. */
}
*ppdc = domain->conn.netlogon_pipe->dc;
- return True;
+ return NT_STATUS_OK;
}
NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
char *machine_account = NULL;
char *domain_name = NULL;
+ if (sid_check_is_domain(&domain->sid)) {
+ return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
+ }
+
result = init_dc_connection_rpc(domain);
if (!NT_STATUS_IS_OK(result)) {
return result;
/* Fall back to schannel if it's a W2K pre-SP1 box. */
- if (!cm_get_schannel_creds(domain, &p_creds)) {
+ result = cm_get_schannel_creds(domain, &p_creds);
+ if (!NT_STATUS_IS_OK(result)) {
/* If this call fails - conn->cli can now be NULL ! */
DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
- "for domain %s, trying anon\n", domain->name));
+ "for domain %s (error %s), trying anon\n",
+ domain->name,
+ nt_errstr(result) ));
goto anonymous;
}
result = cli_rpc_pipe_open_schannel_with_key
struct rpc_pipe_client **cli)
{
struct winbindd_cm_conn *conn;
+ struct netlogon_creds_CredentialState *creds;
NTSTATUS status;
DEBUG(10,("cm_connect_lsa_tcp\n"));
TALLOC_FREE(conn->lsa_pipe_tcp);
- status = cli_rpc_pipe_open_schannel(conn->cli,
- &ndr_table_lsarpc.syntax_id,
- NCACN_IP_TCP,
- DCERPC_AUTH_LEVEL_PRIVACY,
- domain->name,
- &conn->lsa_pipe_tcp);
+ status = cm_get_schannel_creds(domain, &creds);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
+ &ndr_table_lsarpc.syntax_id,
+ NCACN_IP_TCP,
+ DCERPC_AUTH_LEVEL_PRIVACY,
+ domain->name,
+ &creds,
+ &conn->lsa_pipe_tcp);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10,("cli_rpc_pipe_open_schannel failed: %s\n",
+ DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
nt_errstr(status)));
goto done;
}
/* Fall back to schannel if it's a W2K pre-SP1 box. */
- if (!cm_get_schannel_creds(domain, &p_creds)) {
+ result = cm_get_schannel_creds(domain, &p_creds);
+ if (!NT_STATUS_IS_OK(result)) {
/* If this call fails - conn->cli can now be NULL ! */
DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
- "for domain %s, trying anon\n", domain->name));
+ "for domain %s (error %s), trying anon\n",
+ domain->name,
+ nt_errstr(result) ));
goto anonymous;
}
result = cli_rpc_pipe_open_schannel_with_key