/* Add a trusted domain to our list of domains */
static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name,
						  struct winbindd_methods *methods,
						  const struct dom_sid *sid)
{
	struct winbindd_domain *domain;
	const char *alternative_name = NULL;
	char *idmap_config_option;
	const char *param;
	const char **ignored_domains, **dom;

	ignored_domains = lp_parm_string_list(-1, "winbind", "ignore domains", NULL);
	for (dom=ignored_domains; dom && *dom; dom++) {
		if (gen_fnmatch(*dom, domain_name) == 0) {
			DEBUG(2,("Ignoring domain '%s'\n", domain_name));
			return NULL;
		}
	}

	/* use alt_name if available to allow DNS lookups */

	if (alt_name && *alt_name) {
		alternative_name = alt_name;
	}

	/* We can't call domain_list() as this function is called from
	   init_domain_list() and we'll get stuck in a loop. */
	for (domain = _domain_list; domain; domain = domain->next) {
		if (strequal(domain_name, domain->name) ||
		    strequal(domain_name, domain->alt_name))
		{
			break;
		}

		if (alternative_name && *alternative_name)
		{
			if (strequal(alternative_name, domain->name) ||
			    strequal(alternative_name, domain->alt_name))
			{
				break;
			}
		}

		if (sid)
		{
			if (is_null_sid(sid)) {
				continue;
			}

			if (dom_sid_equal(sid, &domain->sid)) {
				break;
			}
		}
	}

	if (domain != NULL) {
		/*
		 * We found a match. Possibly update the SID
		 */
		if ((sid != NULL)
		    && dom_sid_equal(&domain->sid, &global_sid_NULL)) {
			sid_copy( &domain->sid, sid );
		}
		return domain;
	}

	/* Create new domain entry */
	domain = talloc_zero(NULL, struct winbindd_domain);
	if (domain == NULL) {
		return NULL;
	}

	domain->children = talloc_zero_array(domain,
					     struct winbindd_child,
					     lp_winbind_max_domain_connections());
	if (domain->children == NULL) {
		TALLOC_FREE(domain);
		return NULL;
	}

	domain->name = talloc_strdup(domain, domain_name);
	if (domain->name == NULL) {
		TALLOC_FREE(domain);
		return NULL;
	}

	if (alternative_name) {
		domain->alt_name = talloc_strdup(domain, alternative_name);
		if (domain->alt_name == NULL) {
			TALLOC_FREE(domain);
			return NULL;
		}
	}

	domain->methods = methods;
	domain->backend = NULL;
	domain->internal = is_internal_domain(sid);
	domain->sequence_number = DOM_SEQUENCE_NONE;
	domain->last_seq_check = 0;
	domain->initialized = False;
	domain->online = is_internal_domain(sid);
	domain->check_online_timeout = 0;
	domain->dc_probe_pid = (pid_t)-1;
	if (sid) {
		sid_copy(&domain->sid, sid);
	}

	/* Link to domain list */
	DLIST_ADD_END(_domain_list, domain, struct winbindd_domain *);

	wcache_tdc_add_domain( domain );

	idmap_config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
					      domain->name);
	if (idmap_config_option == NULL) {
		DEBUG(0, ("talloc failed, not looking for idmap config\n"));
		goto done;
	}

	param = lp_parm_const_string(-1, idmap_config_option, "range", NULL);

	DEBUG(10, ("%s : range = %s\n", idmap_config_option,
		   param ? param : "not defined"));

	if (param != NULL) {
		unsigned low_id, high_id;
		if (sscanf(param, "%u - %u", &low_id, &high_id) != 2) {
			DEBUG(1, ("invalid range syntax in %s: %s\n",
				  idmap_config_option, param));
			goto done;
		}
		if (low_id > high_id) {
			DEBUG(1, ("invalid range in %s: %s\n",
				  idmap_config_option, param));
			goto done;
		}
		domain->have_idmap_config = true;
		domain->id_range_low = low_id;
		domain->id_range_high = high_id;
	}

done:

	DEBUG(2,("Added domain %s %s %s\n",
		 domain->name, domain->alt_name,
		 &domain->sid?sid_string_dbg(&domain->sid):""));

	return domain;
}
Пример #2
0
/* Add a trusted domain out of a trusted domain cache
   entry
*/
static struct winbindd_domain *
add_trusted_domain_from_tdc(const struct winbindd_tdc_domain *tdc)
{
	struct winbindd_domain *domain;
	const char *alternative_name = NULL;
	const char **ignored_domains, **dom;
	int role = lp_server_role();
	const char *domain_name = tdc->domain_name;
	const struct dom_sid *sid = &tdc->sid;

	if (is_null_sid(sid)) {
		sid = NULL;
	}

	ignored_domains = lp_parm_string_list(-1, "winbind", "ignore domains", NULL);
	for (dom=ignored_domains; dom && *dom; dom++) {
		if (gen_fnmatch(*dom, domain_name) == 0) {
			DEBUG(2,("Ignoring domain '%s'\n", domain_name));
			return NULL;
		}
	}

	/* use alt_name if available to allow DNS lookups */

	if (tdc->dns_name && *tdc->dns_name) {
		alternative_name = tdc->dns_name;
	}

	/* We can't call domain_list() as this function is called from
	   init_domain_list() and we'll get stuck in a loop. */
	for (domain = _domain_list; domain; domain = domain->next) {
		if (strequal(domain_name, domain->name) ||
		    strequal(domain_name, domain->alt_name))
		{
			break;
		}

		if (alternative_name) {
			if (strequal(alternative_name, domain->name) ||
			    strequal(alternative_name, domain->alt_name))
			{
				break;
			}
		}

		if (sid != NULL) {
			if (dom_sid_equal(sid, &domain->sid)) {
				break;
			}
		}
	}

	if (domain != NULL) {
		/*
		 * We found a match on domain->name or
		 * domain->alt_name. Possibly update the SID
		 * if the stored SID was the NULL SID
		 * and return the matching entry.
		 */
		if ((sid != NULL)
		    && dom_sid_equal(&domain->sid, &global_sid_NULL)) {
			sid_copy( &domain->sid, sid );
		}
		return domain;
	}

	/* Create new domain entry */
	domain = talloc_zero(NULL, struct winbindd_domain);
	if (domain == NULL) {
		return NULL;
	}

	domain->children = talloc_zero_array(domain,
					     struct winbindd_child,
					     lp_winbind_max_domain_connections());
	if (domain->children == NULL) {
		TALLOC_FREE(domain);
		return NULL;
	}

	domain->name = talloc_strdup(domain, domain_name);
	if (domain->name == NULL) {
		TALLOC_FREE(domain);
		return NULL;
	}

	if (alternative_name) {
		domain->alt_name = talloc_strdup(domain, alternative_name);
		if (domain->alt_name == NULL) {
			TALLOC_FREE(domain);
			return NULL;
		}
	}

	domain->backend = NULL;
	domain->internal = is_internal_domain(sid);
	domain->sequence_number = DOM_SEQUENCE_NONE;
	domain->last_seq_check = 0;
	domain->initialized = false;
	domain->online = is_internal_domain(sid);
	domain->check_online_timeout = 0;
	domain->dc_probe_pid = (pid_t)-1;
	if (sid != NULL) {
		sid_copy(&domain->sid, sid);
	}
	domain->domain_flags = tdc->trust_flags;
	domain->domain_type = tdc->trust_type;
	domain->domain_trust_attribs = tdc->trust_attribs;

	/* Is this our primary domain ? */
	if (strequal(domain_name, get_global_sam_name()) &&
			(role != ROLE_DOMAIN_MEMBER)) {
		domain->primary = true;
	} else if (strequal(domain_name, lp_workgroup()) &&
			(role == ROLE_DOMAIN_MEMBER)) {
		domain->primary = true;
	}

	if (domain->primary) {
		if (role == ROLE_ACTIVE_DIRECTORY_DC) {
			domain->active_directory = true;
		}
		if (lp_security() == SEC_ADS) {
			domain->active_directory = true;
		}
	} else if (!domain->internal) {
		if (domain->domain_type == LSA_TRUST_TYPE_UPLEVEL) {
			domain->active_directory = true;
		}
	}

	/* Link to domain list */
	DLIST_ADD_END(_domain_list, domain);

	wcache_tdc_add_domain( domain );

	setup_domain_child(domain);

	DEBUG(2,
	      ("Added domain %s %s %s\n", domain->name, domain->alt_name,
	       !is_null_sid(&domain->sid) ? sid_string_dbg(&domain->sid) : ""));

	return domain;
}