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);
}
}
}
+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 ));
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);
}
}
/* 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 {
}
if (!strupper_m(*machine_krb5_principal)) {
- SAFE_FREE(machine_krb5_principal);
+ SAFE_FREE(*machine_krb5_principal);
return NT_STATUS_INVALID_PARAMETER;
}
}
cli_set_timeout(*cli, 10000); /* 10 seconds */
- result = smbXcli_negprot((*cli)->conn, (*cli)->timeout, PROTOCOL_CORE,
- PROTOCOL_LATEST);
+ 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)));
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 );
&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;
}
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 */
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;
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_our_sam(&domain->sid)) {
return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
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,
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;
}
invalidate_cm_connection(&domain->conn);
status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
}
- if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_IS_OK(status)) {
return status;
}
- return NT_STATUS_OK;
+ /*
+ * 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);
NTSTATUS result;
uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS | NETLOGON_NEG_SUPPORTS_AES;
- uint8 mach_pwd[16];
+ 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);