Example #1
0
static int wins_ldb_init(struct ldb_module *module)
{
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	struct winsdb_handle *h;
	const char *owner;
	struct loadparm_context *lp_ctx = ldb_get_opaque(ldb, "loadparm");

	ldb_module_set_private(module, NULL);

	owner = lpcfg_parm_string(lp_ctx, NULL, "winsdb", "local_owner");
	if (!owner) {
		struct interface *ifaces;
		load_interface_list(module, lp_ctx, &ifaces);
		owner = iface_list_first_v4(ifaces);
		if (!owner) {
			owner = "0.0.0.0";
		}
	}

	h = talloc_zero(module, struct winsdb_handle);
	if (!h) goto failed;
	h->ldb		= ldb;
	h->caller	= WINSDB_HANDLE_CALLER_ADMIN;
	h->local_owner	= talloc_strdup(h, owner);
	if (!h->local_owner) goto failed;

	return ldb_set_opaque(ldb, "winsdb_handle", h);

failed:
	talloc_free(h);
	return LDB_ERR_OTHER;
}
Example #2
0
/*
  startup the nbtd task
*/
static void nbtd_task_init(struct task_server *task)
{
	struct nbtd_server *nbtsrv;
	NTSTATUS status;
	struct interface *ifaces;

	load_interface_list(task, task->lp_ctx, &ifaces);

	if (iface_list_count(ifaces) == 0) {
		task_server_terminate(task, "nbtd: no network interfaces configured", false);
		return;
	}

	if (lpcfg_disable_netbios(task->lp_ctx)) {
		task_server_terminate(task, "nbtd: 'disable netbios = yes' set in smb.conf, shutting down nbt server", false);
		return;
	}

	task_server_set_title(task, "task[nbtd]");

	nbtsrv = talloc(task, struct nbtd_server);
	if (nbtsrv == NULL) {
		task_server_terminate(task, "nbtd: out of memory", true);
		return;
	}

	nbtsrv->task            = task;
	nbtsrv->interfaces      = NULL;
	nbtsrv->bcast_interface = NULL;
	nbtsrv->wins_interface  = NULL;

	/* start listening on the configured network interfaces */
	status = nbtd_startup_interfaces(nbtsrv, task->lp_ctx, ifaces);
	if (!NT_STATUS_IS_OK(status)) {
		task_server_terminate(task, "nbtd failed to setup interfaces", true);
		return;
	}

	nbtsrv->sam_ctx = samdb_connect(nbtsrv, task->event_ctx, task->lp_ctx, system_session(task->lp_ctx), 0);
	if (nbtsrv->sam_ctx == NULL) {
		task_server_terminate(task, "nbtd failed to open samdb", true);
		return;
	}

	/* start the WINS server, if appropriate */
	status = nbtd_winsserver_init(nbtsrv);
	if (!NT_STATUS_IS_OK(status)) {
		task_server_terminate(task, "nbtd failed to start WINS server", true);
		return;
	}

	nbtd_register_irpc(nbtsrv);

	/* start the process of registering our names on all interfaces */
	nbtd_register_names(nbtsrv);

	irpc_add_name(task->msg_ctx, "nbt_server");
}
Example #3
0
/*
  open the smb server sockets
*/
static void samba3_smb_task_init(struct task_server *task)
{
	NTSTATUS status;
	const struct model_ops *model_ops;

	model_ops = process_model_startup("standard");

	if (model_ops == NULL) {
		goto failed;
	}

	task_server_set_title(task, "task[samba3_smb]");

	if (lpcfg_interfaces(task->lp_ctx)
	    && lpcfg_bind_interfaces_only(task->lp_ctx)) {
		int num_interfaces;
		int i;
		struct interface *ifaces;

		load_interface_list(task, task->lp_ctx, &ifaces);

		num_interfaces = iface_list_count(ifaces);

		/* We have been given an interfaces line, and been
		   told to only bind to those interfaces. Create a
		   socket per interface and bind to only these.
		*/
		for(i = 0; i < num_interfaces; i++) {
			const char *address = iface_list_n_ip(ifaces, i);
			status = samba3_add_socket(task,
						   task->event_ctx,
						   task->lp_ctx,
						   model_ops, address);
			if (!NT_STATUS_IS_OK(status)) goto failed;
		}
	} else {
		const char **wcard;
		int i;
		wcard = iface_list_wildcard(task, task->lp_ctx);
		if (wcard == NULL) {
			DEBUG(0,("No wildcard addresses available\n"));
			goto failed;
		}
		for (i=0; wcard[i]; i++) {
			status = samba3_add_socket(task,
						   task->event_ctx, task->lp_ctx,
						   model_ops,
						   wcard[i]);
			if (!NT_STATUS_IS_OK(status)) goto failed;
		}
		talloc_free(wcard);
	}

	return;
failed:
	task_server_terminate(task, "Failed to startup samba3 smb task", true);
}
Example #4
0
/*
  startup the cldapd task
*/
static void cldapd_task_init(struct task_server *task)
{
	struct cldapd_server *cldapd;
	NTSTATUS status;
	struct interface *ifaces;
	
	load_interface_list(task, task->lp_ctx, &ifaces);

	if (iface_list_count(ifaces) == 0) {
		task_server_terminate(task, "cldapd: no network interfaces configured", false);
		return;
	}

	switch (lpcfg_server_role(task->lp_ctx)) {
	case ROLE_STANDALONE:
		task_server_terminate(task, "cldap_server: no CLDAP server required in standalone configuration", 
				      false);
		return;
	case ROLE_DOMAIN_MEMBER:
		task_server_terminate(task, "cldap_server: no CLDAP server required in member server configuration",
				      false);
		return;
	case ROLE_ACTIVE_DIRECTORY_DC:
		/* Yes, we want an CLDAP server */
		break;
	}

	task_server_set_title(task, "task[cldapd]");

	cldapd = talloc(task, struct cldapd_server);
	if (cldapd == NULL) {
		task_server_terminate(task, "cldapd: out of memory", true);
		return;
	}

	cldapd->task = task;
	cldapd->samctx = samdb_connect(cldapd,
				       task->event_ctx,
				       task->lp_ctx,
				       system_session(task->lp_ctx),
				       NULL,
				       0);
	if (cldapd->samctx == NULL) {
		task_server_terminate(task, "cldapd failed to open samdb", true);
		return;
	}

	/* start listening on the configured network interfaces */
	status = cldapd_startup_interfaces(cldapd, task->lp_ctx, ifaces);
	if (!NT_STATUS_IS_OK(status)) {
		task_server_terminate(task, "cldapd failed to setup interfaces", true);
		return;
	}

	irpc_add_name(task->msg_ctx, "cldap_server");
}
Example #5
0
/*
  startup the WINS server, if configured
*/
NTSTATUS nbtd_winsserver_init(struct nbtd_server *nbtsrv)
{
	uint32_t tmp;
	const char *owner;

	if (!lpcfg_we_are_a_wins_server(nbtsrv->task->lp_ctx)) {
		nbtsrv->winssrv = NULL;
		return NT_STATUS_OK;
	}

	nbtsrv->winssrv = talloc_zero(nbtsrv, struct wins_server);
	NT_STATUS_HAVE_NO_MEMORY(nbtsrv->winssrv);

	nbtsrv->winssrv->config.max_renew_interval = lpcfg_max_wins_ttl(nbtsrv->task->lp_ctx);
	nbtsrv->winssrv->config.min_renew_interval = lpcfg_min_wins_ttl(nbtsrv->task->lp_ctx);
	tmp = lpcfg_parm_int(nbtsrv->task->lp_ctx, NULL, "wreplsrv", "tombstone_interval", 6*24*60*60);
	nbtsrv->winssrv->config.tombstone_interval = tmp;
	tmp = lpcfg_parm_int(nbtsrv->task->lp_ctx, NULL, "wreplsrv"," tombstone_timeout", 1*24*60*60);
	nbtsrv->winssrv->config.tombstone_timeout = tmp;

	owner = lpcfg_parm_string(nbtsrv->task->lp_ctx, NULL, "winsdb", "local_owner");

	if (owner == NULL) {
		struct interface *ifaces;
		load_interface_list(nbtsrv->task, nbtsrv->task->lp_ctx, &ifaces);
		owner = iface_list_first_v4(ifaces);
	}

	nbtsrv->winssrv->wins_db     = winsdb_connect(nbtsrv->winssrv, nbtsrv->task->event_ctx, 
						      nbtsrv->task->lp_ctx,
						      owner, WINSDB_HANDLE_CALLER_NBTD);
	if (!nbtsrv->winssrv->wins_db) {
		return NT_STATUS_INTERNAL_DB_ERROR;
	}

	irpc_add_name(nbtsrv->task->msg_ctx, "wins_server");

	return NT_STATUS_OK;
}
Example #6
0
/*
  startup the kdc task
*/
static void kdc_task_init(struct task_server *task)
{
	struct kdc_server *kdc;
	krb5_kdc_configuration *kdc_config = NULL;
	NTSTATUS status;
	krb5_error_code ret;
	struct interface *ifaces;
	int ldb_ret;

	switch (lpcfg_server_role(task->lp_ctx)) {
	case ROLE_STANDALONE:
		task_server_terminate(task, "kdc: no KDC required in standalone configuration", false);
		return;
	case ROLE_DOMAIN_MEMBER:
		task_server_terminate(task, "kdc: no KDC required in member server configuration", false);
		return;
	case ROLE_DOMAIN_PDC:
	case ROLE_DOMAIN_BDC:
		task_server_terminate(task, "Cannot start KDC as a 'classic Samba' DC", true);
		return;
	case ROLE_ACTIVE_DIRECTORY_DC:
		/* Yes, we want a KDC */
		break;
	}

	load_interface_list(task, task->lp_ctx, &ifaces);

	if (iface_list_count(ifaces) == 0) {
		task_server_terminate(task, "kdc: no network interfaces configured", false);
		return;
	}

	task_server_set_title(task, "task[kdc]");

	kdc = talloc_zero(task, struct kdc_server);
	if (kdc == NULL) {
		task_server_terminate(task, "kdc: out of memory", true);
		return;
	}

	kdc->task = task;


	/* get a samdb connection */
	kdc->samdb = samdb_connect(kdc,
				   kdc->task->event_ctx,
				   kdc->task->lp_ctx,
				   system_session(kdc->task->lp_ctx),
				   NULL,
				   0);
	if (!kdc->samdb) {
		DEBUG(1,("kdc_task_init: unable to connect to samdb\n"));
		task_server_terminate(task, "kdc: krb5_init_context samdb connect failed", true);
		return;
	}

	ldb_ret = samdb_rodc(kdc->samdb, &kdc->am_rodc);
	if (ldb_ret != LDB_SUCCESS) {
		DEBUG(1, ("kdc_task_init: Cannot determine if we are an RODC: %s\n",
			  ldb_errstring(kdc->samdb)));
		task_server_terminate(task, "kdc: krb5_init_context samdb RODC connect failed", true);
		return;
	}

	kdc->proxy_timeout = lpcfg_parm_int(kdc->task->lp_ctx, NULL, "kdc", "proxy timeout", 5);

	initialize_krb5_error_table();

	ret = smb_krb5_init_context(kdc, task->lp_ctx, &kdc->smb_krb5_context);
	if (ret) {
		DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n",
			 error_message(ret)));
		task_server_terminate(task, "kdc: krb5_init_context failed", true);
		return;
	}

	krb5_add_et_list(kdc->smb_krb5_context->krb5_context, initialize_hdb_error_table_r);

	ret = krb5_kdc_get_config(kdc->smb_krb5_context->krb5_context,
				  &kdc_config);
	if(ret) {
		task_server_terminate(task, "kdc: failed to get KDC configuration", true);
		return;
	}

	kdc_config->logf = (krb5_log_facility *)kdc->smb_krb5_context->pvt_log_data;
	kdc_config->db = talloc(kdc, struct HDB *);
	if (!kdc_config->db) {
		task_server_terminate(task, "kdc: out of memory", true);
		return;
	}
	kdc_config->num_db = 1;

	/*
	 * This restores the behavior before
	 * commit 255e3e18e00f717d99f3bc57c8a8895ff624f3c3
	 * s4:heimdal: import lorikeet-heimdal-201107150856
	 * (commit 48936803fae4a2fb362c79365d31f420c917b85b)
	 *
	 * as_use_strongest_session_key,preauth_use_strongest_session_key
	 * and tgs_use_strongest_session_key are input to the
	 * _kdc_find_etype() function. The old bahavior is in
	 * the use_strongest_session_key=FALSE code path.
	 * (The only remaining difference in _kdc_find_etype()
	 *  is the is_preauth parameter.)
	 *
	 * The old behavior in the _kdc_get_preferred_key()
	 * function is use_strongest_server_key=TRUE.
	 */
	kdc_config->as_use_strongest_session_key = false;
	kdc_config->preauth_use_strongest_session_key = false;
	kdc_config->tgs_use_strongest_session_key = false;
	kdc_config->use_strongest_server_key = true;

	kdc_config->autodetect_referrals = false;

	/* Register hdb-samba4 hooks for use as a keytab */

	kdc->base_ctx = talloc_zero(kdc, struct samba_kdc_base_context);
	if (!kdc->base_ctx) {
		task_server_terminate(task, "kdc: out of memory", true);
		return;
	}

	kdc->base_ctx->ev_ctx = task->event_ctx;
	kdc->base_ctx->lp_ctx = task->lp_ctx;
	kdc->base_ctx->msg_ctx = task->msg_ctx;

	status = hdb_samba4_create_kdc(kdc->base_ctx,
				       kdc->smb_krb5_context->krb5_context,
				       &kdc_config->db[0]);
	if (!NT_STATUS_IS_OK(status)) {
		task_server_terminate(task, "kdc: hdb_samba4_create_kdc (setup KDC database) failed", true);
		return;
	}

	ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
				   PLUGIN_TYPE_DATA, "hdb",
				   &hdb_samba4_interface);
	if(ret) {
		task_server_terminate(task, "kdc: failed to register hdb plugin", true);
		return;
	}

	ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops);
	if(ret) {
		task_server_terminate(task, "kdc: failed to register keytab plugin", true);
		return;
	}

	kdc->keytab_name = talloc_asprintf(kdc, "HDB:samba4&%p", kdc->base_ctx);
	if (kdc->keytab_name == NULL) {
		task_server_terminate(task,
				      "kdc: Failed to set keytab name",
				      true);
		return;
	}

	/* Register WinDC hooks */
	ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
				   PLUGIN_TYPE_DATA, "windc",
				   &windc_plugin_table);
	if(ret) {
		task_server_terminate(task, "kdc: failed to register windc plugin", true);
		return;
	}

	ret = krb5_kdc_windc_init(kdc->smb_krb5_context->krb5_context);

	if(ret) {
		task_server_terminate(task, "kdc: failed to init windc plugin", true);
		return;
	}

	ret = krb5_kdc_pkinit_config(kdc->smb_krb5_context->krb5_context, kdc_config);

	if(ret) {
		task_server_terminate(task, "kdc: failed to init kdc pkinit subsystem", true);
		return;
	}
	kdc->private_data = kdc_config;

	/* start listening on the configured network interfaces */
	status = kdc_startup_interfaces(kdc, task->lp_ctx, ifaces,
					task->model_ops);
	if (!NT_STATUS_IS_OK(status)) {
		task_server_terminate(task, "kdc failed to setup interfaces", true);
		return;
	}

	status = IRPC_REGISTER(task->msg_ctx, irpc, KDC_CHECK_GENERIC_KERBEROS,
			       kdc_check_generic_kerberos, kdc);
	if (!NT_STATUS_IS_OK(status)) {
		task_server_terminate(task, "kdc failed to setup monitoring", true);
		return;
	}

	irpc_add_name(task->msg_ctx, "kdc_server");
}
Example #7
0
/*
  main program
*/
int main(int argc, const char *argv[])
{
	bool ret = true;
	struct interface *ifaces;
	struct tevent_context *ev;
	poptContext pc;
	int opt;
	enum {
		OPT_BROADCAST_ADDRESS	= 1000,
		OPT_UNICAST_ADDRESS,
		OPT_FIND_MASTER,
		OPT_WINS_LOOKUP,
		OPT_NODE_STATUS,
		OPT_ROOT_PORT,
		OPT_LOOKUP_BY_IP,
		OPT_CASE_SENSITIVE
	};
	struct poptOption long_options[] = {
		POPT_AUTOHELP
		{ "broadcast", 'B', POPT_ARG_STRING, NULL, OPT_BROADCAST_ADDRESS,
		  "Specify address to use for broadcasts", "BROADCAST-ADDRESS" },

		{ "unicast", 'U', POPT_ARG_STRING, NULL, OPT_UNICAST_ADDRESS,
		  "Specify address to use for unicast", NULL },

		{ "master-browser", 'M', POPT_ARG_NONE, NULL, OPT_FIND_MASTER,
		  "Search for a master browser", NULL },

		{ "wins", 'W', POPT_ARG_NONE, NULL, OPT_WINS_LOOKUP,
		  "Do a WINS lookup", NULL },

		{ "status", 'S', POPT_ARG_NONE, NULL, OPT_NODE_STATUS, 
		  "Lookup node status as well", NULL },

		{ "root-port", 'r', POPT_ARG_NONE, NULL, OPT_ROOT_PORT, 
		  "Use root port 137 (Win95 only replies to this)", NULL },

		{ "lookup-by-ip", 'A', POPT_ARG_NONE, NULL, OPT_LOOKUP_BY_IP, 
		  "Do a node status on <name> as an IP Address", NULL },

		{ "case-sensitive", 0, POPT_ARG_NONE, NULL, OPT_CASE_SENSITIVE, 
		  "Don't uppercase the name before sending", NULL },

		POPT_COMMON_SAMBA
		{ 0, 0, 0, 0 }
	};
	
	pc = poptGetContext("nmblookup", argc, argv, long_options, 
			    POPT_CONTEXT_KEEP_FIRST);

	poptSetOtherOptionHelp(pc, "<NODE> ...");

	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch(opt) {
		case OPT_BROADCAST_ADDRESS:
			options.broadcast_address = poptGetOptArg(pc);
			break;
		case OPT_UNICAST_ADDRESS:
			options.unicast_address = poptGetOptArg(pc);
			break;
		case OPT_FIND_MASTER:
			options.find_master = true;
			break;
		case OPT_WINS_LOOKUP:
			options.wins_lookup = true;
			break;
		case OPT_NODE_STATUS:
			options.node_status = true;
			break;
		case OPT_ROOT_PORT:
			options.root_port = true;
			break;
		case OPT_LOOKUP_BY_IP:
			options.lookup_by_ip = true;
			break;
		case OPT_CASE_SENSITIVE:
			options.case_sensitive = true;
			break;
		}
	}

	/* swallow argv[0] */
	poptGetArg(pc);

	if(!poptPeekArg(pc)) { 
		poptPrintUsage(pc, stderr, 0);
		exit(1);
	}

	load_interface_list(NULL, cmdline_lp_ctx, &ifaces);

	ev = s4_event_context_init(talloc_autofree_context());

	while (poptPeekArg(pc)) {
		const char *name = poptGetArg(pc);

		ret &= process_one(cmdline_lp_ctx, ev, ifaces, name, lpcfg_nbt_port(cmdline_lp_ctx));
	}

	talloc_free(ev);

	talloc_free(ifaces);

	poptFreeContext(pc);

	if (!ret) {
		return 1;
	}

	return 0;
}
Example #8
0
/*
  fill in the cldap netlogon union for a given version
*/
NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
					 TALLOC_CTX *mem_ctx,
					 const char *domain,
					 const char *netbios_domain,
					 struct dom_sid *domain_sid,
					 const char *domain_guid,
					 const char *user,
					 uint32_t acct_control,
					 const char *src_address,
					 uint32_t version,
					 struct loadparm_context *lp_ctx,
					 struct netlogon_samlogon_response *netlogon,
					 bool fill_on_blank_request)
{
	const char *dom_attrs[] = {"objectGUID", NULL};
	const char *none_attrs[] = {NULL};
	struct ldb_result *dom_res = NULL, *user_res = NULL;
	int ret;
	const char **services = lpcfg_server_services(lp_ctx);
	uint32_t server_type;
	const char *pdc_name;
	struct GUID domain_uuid;
	const char *dns_domain;
	const char *forest_domain;
	const char *pdc_dns_name;
	const char *flatname;
	const char *server_site;
	const char *client_site;
	const char *pdc_ip;
	struct ldb_dn *domain_dn = NULL;
	struct interface *ifaces;
	bool user_known, am_rodc;
	NTSTATUS status;

	/* the domain parameter could have an optional trailing "." */
	if (domain && domain[strlen(domain)-1] == '.') {
		domain = talloc_strndup(mem_ctx, domain, strlen(domain)-1);
		NT_STATUS_HAVE_NO_MEMORY(domain);
	}

	/* Lookup using long or short domainname */
	if (domain && (strcasecmp_m(domain, lpcfg_dnsdomain(lp_ctx)) == 0)) {
		domain_dn = ldb_get_default_basedn(sam_ctx);
	}
	if (netbios_domain && (strcasecmp_m(netbios_domain, lpcfg_sam_name(lp_ctx)) == 0)) {
		domain_dn = ldb_get_default_basedn(sam_ctx);
	}
	if (domain_dn) {
		const char *domain_identifier = domain != NULL ? domain
							: netbios_domain;
		ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
				 domain_dn, LDB_SCOPE_BASE, dom_attrs,
				 "objectClass=domain");
		if (ret != LDB_SUCCESS) {
			DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n",
				 domain_identifier,
				 ldb_dn_get_linearized(domain_dn),
				 ldb_errstring(sam_ctx)));
			return NT_STATUS_NO_SUCH_DOMAIN;
		}
		if (dom_res->count != 1) {
			DEBUG(2,("Error finding domain '%s'/'%s' in sam\n",
				 domain_identifier,
				 ldb_dn_get_linearized(domain_dn)));
			return NT_STATUS_NO_SUCH_DOMAIN;
		}
	}

	/* Lookup using GUID or SID */
	if ((dom_res == NULL) && (domain_guid || domain_sid)) {
		if (domain_guid) {
			struct GUID binary_guid;
			struct ldb_val guid_val;

			/* By this means, we ensure we don't have funny stuff in the GUID */

			status = GUID_from_string(domain_guid, &binary_guid);
			if (!NT_STATUS_IS_OK(status)) {
				return status;
			}

			/* And this gets the result into the binary format we want anyway */
			status = GUID_to_ndr_blob(&binary_guid, mem_ctx, &guid_val);
			if (!NT_STATUS_IS_OK(status)) {
				return status;
			}
			ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
						 NULL, LDB_SCOPE_SUBTREE, 
						 dom_attrs, 
						 "(&(objectCategory=DomainDNS)(objectGUID=%s))", 
						 ldb_binary_encode(mem_ctx, guid_val));
		} else { /* domain_sid case */
			ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
					 NULL, LDB_SCOPE_SUBTREE,
					 dom_attrs,
					 "(&(objectCategory=DomainDNS)(objectSid=%s))",
					 dom_sid_string(mem_ctx, domain_sid));
		}
		
		if (ret != LDB_SUCCESS) {
			DEBUG(2,("Unable to find a correct reference to GUID '%s' or SID '%s' in sam: %s\n",
				 domain_guid, dom_sid_string(mem_ctx, domain_sid),
				 ldb_errstring(sam_ctx)));
			return NT_STATUS_NO_SUCH_DOMAIN;
		} else if (dom_res->count == 1) {
			/* Ok, now just check it is our domain */
			if (ldb_dn_compare(ldb_get_default_basedn(sam_ctx),
					   dom_res->msgs[0]->dn) != 0) {
				DEBUG(2,("The GUID '%s' or SID '%s' doesn't identify our domain\n",
					 domain_guid,
					 dom_sid_string(mem_ctx, domain_sid)));
				return NT_STATUS_NO_SUCH_DOMAIN;
			}
		} else {
			DEBUG(2,("Unable to find a correct reference to GUID '%s' or SID '%s' in sam\n",
				 domain_guid, dom_sid_string(mem_ctx, domain_sid)));
			return NT_STATUS_NO_SUCH_DOMAIN;
		}
	}

	if (dom_res == NULL && fill_on_blank_request) {
		/* blank inputs gives our domain - tested against
		   w2k8r2. Without this ADUC on Win7 won't start */
		domain_dn = ldb_get_default_basedn(sam_ctx);
		ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
				 domain_dn, LDB_SCOPE_BASE, dom_attrs,
				 "objectClass=domain");
		if (ret != LDB_SUCCESS) {
			DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n",
				 lpcfg_dnsdomain(lp_ctx),
				 ldb_dn_get_linearized(domain_dn),
				 ldb_errstring(sam_ctx)));
			return NT_STATUS_NO_SUCH_DOMAIN;
		}
	}

        if (dom_res == NULL) {
		DEBUG(2,(__location__ ": Unable to get domain information with no inputs\n"));
		return NT_STATUS_NO_SUCH_DOMAIN;
	}

	/* work around different inputs for not-specified users */
	if (!user) {
		user = "";
	}

	/* Enquire about any valid username with just a CLDAP packet -
	 * if kerberos didn't also do this, the security folks would
	 * scream... */
	if (user[0]) {							\
		/* Only allow some bits to be enquired:  [MS-ATDS] 7.3.3.2 */
		if (acct_control == (uint32_t)-1) {
			acct_control = 0;
		}
		acct_control = acct_control & (ACB_TEMPDUP | ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST);

		/* We must exclude disabled accounts, but otherwise do the bitwise match the client asked for */
		ret = ldb_search(sam_ctx, mem_ctx, &user_res,
					 dom_res->msgs[0]->dn, LDB_SCOPE_SUBTREE, 
					 none_attrs, 
					 "(&(objectClass=user)(samAccountName=%s)"
					 "(!(userAccountControl:" LDB_OID_COMPARATOR_AND ":=%u))"
					 "(userAccountControl:" LDB_OID_COMPARATOR_OR ":=%u))", 
					 ldb_binary_encode_string(mem_ctx, user),
					 UF_ACCOUNTDISABLE, ds_acb2uf(acct_control));
		if (ret != LDB_SUCCESS) {
			DEBUG(2,("Unable to find reference to user '%s' with ACB 0x%8x under %s: %s\n",
				 user, acct_control, ldb_dn_get_linearized(dom_res->msgs[0]->dn),
				 ldb_errstring(sam_ctx)));
			return NT_STATUS_NO_SUCH_USER;
		} else if (user_res->count == 1) {
			user_known = true;
		} else {
			user_known = false;
		}

	} else {
		user_known = true;
	}
		
	server_type      = 
		DS_SERVER_DS | DS_SERVER_TIMESERV |
		DS_SERVER_GOOD_TIMESERV;

	if (samdb_is_pdc(sam_ctx)) {
		server_type |= DS_SERVER_PDC;
	}

	if (dsdb_functional_level(sam_ctx) >= DS_DOMAIN_FUNCTION_2008) {
		server_type |= DS_SERVER_FULL_SECRET_DOMAIN_6;
	}

	if (samdb_is_gc(sam_ctx)) {
		server_type |= DS_SERVER_GC;
	}

	if (str_list_check(services, "ldap")) {
		server_type |= DS_SERVER_LDAP;
	}

	if (str_list_check(services, "kdc")) {
		server_type |= DS_SERVER_KDC;
	}

	if (samdb_rodc(sam_ctx, &am_rodc) == LDB_SUCCESS && !am_rodc) {
		server_type |= DS_SERVER_WRITABLE;
	}

	pdc_name         = talloc_asprintf(mem_ctx, "\\\\%s",
					   lpcfg_netbios_name(lp_ctx));
	NT_STATUS_HAVE_NO_MEMORY(pdc_name);
	domain_uuid      = samdb_result_guid(dom_res->msgs[0], "objectGUID");
	dns_domain       = lpcfg_dnsdomain(lp_ctx);
	forest_domain    = samdb_forest_name(sam_ctx, mem_ctx);
	NT_STATUS_HAVE_NO_MEMORY(forest_domain);
	pdc_dns_name     = talloc_asprintf(mem_ctx, "%s.%s", 
					   strlower_talloc(mem_ctx, 
							   lpcfg_netbios_name(lp_ctx)),
					   dns_domain);
	NT_STATUS_HAVE_NO_MEMORY(pdc_dns_name);
	flatname         = lpcfg_workgroup(lp_ctx);

	server_site      = samdb_server_site_name(sam_ctx, mem_ctx);
	NT_STATUS_HAVE_NO_MEMORY(server_site);
	client_site      = samdb_client_site_name(sam_ctx, mem_ctx,
						  src_address, NULL);
	NT_STATUS_HAVE_NO_MEMORY(client_site);
	if (strcasecmp(server_site, client_site) == 0) {
		server_type |= DS_SERVER_CLOSEST;
	}

	load_interface_list(mem_ctx, lp_ctx, &ifaces);
	if (src_address) {
		pdc_ip = iface_list_best_ip(ifaces, src_address);
	} else {
		pdc_ip = iface_list_first_v4(ifaces);
	}
	if (pdc_ip == NULL || !is_ipaddress_v4(pdc_ip)) {
		/* this matches windows behaviour */
		pdc_ip = "127.0.0.1";
	}

	ZERO_STRUCTP(netlogon);

	/* check if either of these bits is present */
	if (version & (NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_5EX_WITH_IP)) {
		uint32_t extra_flags = 0;
		netlogon->ntver = NETLOGON_NT_VERSION_5EX;

		/* could check if the user exists */
		if (user_known) {
			netlogon->data.nt5_ex.command      = LOGON_SAM_LOGON_RESPONSE_EX;
		} else {
			netlogon->data.nt5_ex.command      = LOGON_SAM_LOGON_USER_UNKNOWN_EX;
		}
		netlogon->data.nt5_ex.pdc_name     = pdc_name;
		netlogon->data.nt5_ex.user_name    = user;
		netlogon->data.nt5_ex.domain_name  = flatname;
		netlogon->data.nt5_ex.domain_uuid  = domain_uuid;
		netlogon->data.nt5_ex.forest       = forest_domain;
		netlogon->data.nt5_ex.dns_domain   = dns_domain;
		netlogon->data.nt5_ex.pdc_dns_name = pdc_dns_name;
		netlogon->data.nt5_ex.server_site  = server_site;
		netlogon->data.nt5_ex.client_site  = client_site;
		if (version & NETLOGON_NT_VERSION_5EX_WITH_IP) {
			/* note that this is always a IPV4 address */
			extra_flags = NETLOGON_NT_VERSION_5EX_WITH_IP;
			netlogon->data.nt5_ex.sockaddr.sockaddr_family    = 2;
			netlogon->data.nt5_ex.sockaddr.pdc_ip       = pdc_ip;
			netlogon->data.nt5_ex.sockaddr.remaining = data_blob_talloc_zero(mem_ctx, 8);
		}
		netlogon->data.nt5_ex.server_type  = server_type;
		netlogon->data.nt5_ex.nt_version   = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5EX|extra_flags;
		netlogon->data.nt5_ex.lmnt_token   = 0xFFFF;
		netlogon->data.nt5_ex.lm20_token   = 0xFFFF;

	} else if (version & NETLOGON_NT_VERSION_5) {
		netlogon->ntver = NETLOGON_NT_VERSION_5;

		/* could check if the user exists */
		if (user_known) {
			netlogon->data.nt5.command      = LOGON_SAM_LOGON_RESPONSE;
		} else {
			netlogon->data.nt5.command      = LOGON_SAM_LOGON_USER_UNKNOWN;
		}
		netlogon->data.nt5.pdc_name     = pdc_name;
		netlogon->data.nt5.user_name    = user;
		netlogon->data.nt5.domain_name  = flatname;
		netlogon->data.nt5.domain_uuid  = domain_uuid;
		netlogon->data.nt5.forest       = forest_domain;
		netlogon->data.nt5.dns_domain   = dns_domain;
		netlogon->data.nt5.pdc_dns_name = pdc_dns_name;
		netlogon->data.nt5.pdc_ip       = pdc_ip;
		netlogon->data.nt5.server_type  = server_type;
		netlogon->data.nt5.nt_version   = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5;
		netlogon->data.nt5.lmnt_token   = 0xFFFF;
		netlogon->data.nt5.lm20_token   = 0xFFFF;

	} else /* (version & NETLOGON_NT_VERSION_1) and all other cases */ {
		netlogon->ntver = NETLOGON_NT_VERSION_1;
		/* could check if the user exists */
		if (user_known) {
			netlogon->data.nt4.command      = LOGON_SAM_LOGON_RESPONSE;
		} else {
			netlogon->data.nt4.command      = LOGON_SAM_LOGON_USER_UNKNOWN;
		}
		netlogon->data.nt4.pdc_name    = pdc_name;
		netlogon->data.nt4.user_name   = user;
		netlogon->data.nt4.domain_name = flatname;
		netlogon->data.nt4.nt_version  = NETLOGON_NT_VERSION_1;
		netlogon->data.nt4.lmnt_token  = 0xFFFF;
		netlogon->data.nt4.lm20_token  = 0xFFFF;
	}

	return NT_STATUS_OK;
}
Example #9
0
/*
  return the list of interface IPs we have configured
  takes an loadparm context, returns a list of IPs in string form

  Does not return addresses on 127.0.0.0/8
 */
static PyObject *py_interface_ips(PyObject *self, PyObject *args)
{
	PyObject *pylist;
	int count;
	TALLOC_CTX *tmp_ctx;
	PyObject *py_lp_ctx;
	struct loadparm_context *lp_ctx;
	struct interface *ifaces;
	int i, ifcount;
	int all_interfaces = 1;

	if (!PyArg_ParseTuple(args, "O|i", &py_lp_ctx, &all_interfaces))
		return NULL;

	tmp_ctx = talloc_new(NULL);
	if (tmp_ctx == NULL) {
		PyErr_NoMemory();
		return NULL;
	}

	lp_ctx = lpcfg_from_py_object(tmp_ctx, py_lp_ctx);
	if (lp_ctx == NULL) {
		talloc_free(tmp_ctx);
		return NULL;
	}

	load_interface_list(tmp_ctx, lp_ctx, &ifaces);

	count = iface_list_count(ifaces);

	/* first count how many are not loopback addresses */
	for (ifcount = i = 0; i<count; i++) {
		const char *ip = iface_list_n_ip(ifaces, i);

		if (all_interfaces) {
			ifcount++;
			continue;
		}

		if (iface_list_same_net(ip, "127.0.0.1", "255.0.0.0")) {
			continue;
		}

		if (iface_list_same_net(ip, "169.254.0.0", "255.255.0.0")) {
			continue;
		}

		if (iface_list_same_net(ip, "::1", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")) {
			continue;
		}

		if (iface_list_same_net(ip, "fe80::", "ffff:ffff:ffff:ffff::")) {
			continue;
		}

		ifcount++;
	}

	pylist = PyList_New(ifcount);
	for (ifcount = i = 0; i<count; i++) {
		const char *ip = iface_list_n_ip(ifaces, i);

		if (all_interfaces) {
			PyList_SetItem(pylist, ifcount, PyString_FromString(ip));
			ifcount++;
			continue;
		}

		if (iface_list_same_net(ip, "127.0.0.1", "255.0.0.0")) {
			continue;
		}

		if (iface_list_same_net(ip, "169.254.0.0", "255.255.0.0")) {
			continue;
		}

		if (iface_list_same_net(ip, "::1", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")) {
			continue;
		}

		if (iface_list_same_net(ip, "fe80::", "ffff:ffff:ffff:ffff::")) {
			continue;
		}

		PyList_SetItem(pylist, ifcount, PyString_FromString(ip));
		ifcount++;
	}
	talloc_free(tmp_ctx);
	return pylist;
}
Example #10
0
/* test UDP/138 netlogon requests */
static bool nbt_test_netlogon(struct torture_context *tctx)
{
	struct dgram_mailslot_handler *dgmslot;
	struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(tctx, tctx->ev);
	struct socket_address *dest;
	const char *myaddress;
	struct nbt_netlogon_packet logon;
	struct nbt_netlogon_response *response;
	struct nbt_name myname;
	NTSTATUS status;
	struct timeval tv = timeval_current();

	struct socket_address *socket_address;

	const char *address;
	struct nbt_name name;

	struct interface *ifaces;

	name.name = lpcfg_workgroup(tctx->lp_ctx);
	name.type = NBT_NAME_LOGON;
	name.scope = NULL;

	/* do an initial name resolution to find its IP */
	torture_assert_ntstatus_ok(tctx, 
				   resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
						   0, 0,
						   &name, tctx, &address, tctx->ev),
				   talloc_asprintf(tctx, "Failed to resolve %s", name.name));

	load_interface_list(tctx, tctx->lp_ctx, &ifaces);
	myaddress = talloc_strdup(dgmsock, iface_list_best_ip(ifaces, address));


	socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
						     myaddress, lpcfg_dgram_port(tctx->lp_ctx));
	torture_assert(tctx, socket_address != NULL, "Error getting address");

	/* try receiving replies on port 138 first, which will only
	   work if we are root and smbd/nmbd are not running - fall
	   back to listening on any port, which means replies from
	   most windows versions won't be seen */
	status = socket_listen(dgmsock->sock, socket_address, 0, 0);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(socket_address);
		socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
							     myaddress, 0);
		torture_assert(tctx, socket_address != NULL, "Error getting address");

		socket_listen(dgmsock->sock, socket_address, 0, 0);
	}

	/* setup a temporary mailslot listener for replies */
	dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
				      netlogon_handler, NULL);
	torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC");

	ZERO_STRUCT(logon);
	logon.command = LOGON_PRIMARY_QUERY;
	logon.req.pdc.computer_name = TEST_NAME;
	logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
	logon.req.pdc.unicode_name  = TEST_NAME;
	logon.req.pdc.nt_version    = 1;
	logon.req.pdc.lmnt_token    = 0xFFFF;
	logon.req.pdc.lm20_token    = 0xFFFF;

	make_nbt_name_client(&myname, TEST_NAME);

	dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
					   address, lpcfg_dgram_port(tctx->lp_ctx));
	torture_assert(tctx, dest != NULL, "Error getting address");

	status = dgram_mailslot_netlogon_send(dgmsock, &name, dest,
					      NBT_MAILSLOT_NETLOGON, 
					      &myname, &logon);
	torture_assert_ntstatus_ok(tctx, status, "Failed to send netlogon request");

	while (timeval_elapsed(&tv) < 5 && !dgmslot->private_data) {
		tevent_loop_once(dgmsock->event_ctx);
	}

	response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);

	torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");

	torture_assert(tctx, response->response_type == NETLOGON_GET_PDC, "Got incorrect type of netlogon response");
	torture_assert(tctx, response->data.get_pdc.command == NETLOGON_RESPONSE_FROM_PDC, "Got incorrect netlogon response command");

	return true;
}
Example #11
0
/* test UDP/138 ntlogon requests */
static bool nbt_test_ntlogon(struct torture_context *tctx)
{
	struct dgram_mailslot_handler *dgmslot;
	struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(tctx, tctx->ev);
	struct socket_address *dest;
	struct test_join *join_ctx;
	const struct dom_sid *dom_sid;
	struct cli_credentials *machine_credentials;

	const char *myaddress;
	struct nbt_netlogon_packet logon;
	struct nbt_netlogon_response *response;
	struct nbt_name myname;
	NTSTATUS status;
	struct timeval tv = timeval_current();

	struct socket_address *socket_address;
	const char *address;
	struct nbt_name name;

	struct interface *ifaces;
	
	name.name = lpcfg_workgroup(tctx->lp_ctx);
	name.type = NBT_NAME_LOGON;
	name.scope = NULL;

	/* do an initial name resolution to find its IP */
	torture_assert_ntstatus_ok(tctx, 
				   resolve_name_ex(lpcfg_resolve_context(tctx->lp_ctx),
						   0, 0, &name, tctx, &address, tctx->ev),
				   talloc_asprintf(tctx, "Failed to resolve %s", name.name));

	load_interface_list(tctx, tctx->lp_ctx, &ifaces);
	myaddress = talloc_strdup(dgmsock, iface_list_best_ip(ifaces, address));

	socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
						     myaddress, lpcfg_dgram_port(tctx->lp_ctx));
	torture_assert(tctx, socket_address != NULL, "Error getting address");

	/* try receiving replies on port 138 first, which will only
	   work if we are root and smbd/nmbd are not running - fall
	   back to listening on any port, which means replies from
	   most windows versions won't be seen */
	status = socket_listen(dgmsock->sock, socket_address, 0, 0);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(socket_address);
		socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
							     myaddress, 0);
		torture_assert(tctx, socket_address != NULL, "Error getting address");

		socket_listen(dgmsock->sock, socket_address, 0, 0);
	}

	join_ctx = torture_join_domain(tctx, TEST_NAME, 
				       ACB_WSTRUST, &machine_credentials);

	torture_assert(tctx, join_ctx != NULL,
		       talloc_asprintf(tctx, "Failed to join domain %s as %s\n",
				       lpcfg_workgroup(tctx->lp_ctx), TEST_NAME));
	dom_sid = torture_join_sid(join_ctx);

	/* setup a temporary mailslot listener for replies */
	dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
				      netlogon_handler, NULL);
	torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC");

	ZERO_STRUCT(logon);
	logon.command = LOGON_SAM_LOGON_REQUEST;
	logon.req.logon.request_count = 0;
	logon.req.logon.computer_name = TEST_NAME;
	logon.req.logon.user_name     = TEST_NAME"$";
	logon.req.logon.mailslot_name = dgmslot->mailslot_name;
	logon.req.logon.acct_control  = ACB_WSTRUST;
	/* Try with a SID this time */
	logon.req.logon.sid           = *dom_sid;
	logon.req.logon.nt_version    = 1;
	logon.req.logon.lmnt_token    = 0xFFFF;
	logon.req.logon.lm20_token    = 0xFFFF;

	make_nbt_name_client(&myname, TEST_NAME);

	dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
					   address, lpcfg_dgram_port(tctx->lp_ctx));
	torture_assert(tctx, dest != NULL, "Error getting address");
	status = dgram_mailslot_netlogon_send(dgmsock, 
					      &name, dest, 
					      NBT_MAILSLOT_NTLOGON, 
					      &myname, &logon);
	torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");

	while (timeval_elapsed(&tv) < 5 && dgmslot->private_data == NULL) {
		tevent_loop_once(dgmsock->event_ctx);
	}

	response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);

	torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");

	torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
	map_netlogon_samlogon_response(&response->data.samlogon);

	torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");

	torture_assert_str_equal(tctx, response->data.samlogon.data.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");

	torture_assert(tctx,
		       strstr(response->data.samlogon.data.nt5_ex.pdc_name, "\\\\") != NULL,
		       "PDC name should be in UNC form");

	/* setup a temporary mailslot listener for replies */
	dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
				      netlogon_handler, NULL);
	torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC");

	ZERO_STRUCT(logon);
	logon.command = LOGON_SAM_LOGON_REQUEST;
	logon.req.logon.request_count = 0;
	logon.req.logon.computer_name = TEST_NAME;
	logon.req.logon.user_name     = TEST_NAME"$";
	logon.req.logon.mailslot_name = dgmslot->mailslot_name;
	logon.req.logon.acct_control  = ACB_WSTRUST;
	/* Leave sid as all zero */
	logon.req.logon.nt_version    = 1;
	logon.req.logon.lmnt_token    = 0xFFFF;
	logon.req.logon.lm20_token    = 0xFFFF;

	make_nbt_name_client(&myname, TEST_NAME);

	dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
					   address, lpcfg_dgram_port(tctx->lp_ctx));
	torture_assert(tctx, dest != NULL, "Error getting address");
	status = dgram_mailslot_netlogon_send(dgmsock, 
					      &name, dest, 
					      NBT_MAILSLOT_NTLOGON, 
					      &myname, &logon);
	torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");

	while (timeval_elapsed(&tv) < 5 && dgmslot->private_data == NULL) {
		tevent_loop_once(dgmsock->event_ctx);
	}

	response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);

	torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");

	torture_assert_int_equal(tctx, response->response_type, NETLOGON_SAMLOGON, "Got incorrect type of netlogon response");
	map_netlogon_samlogon_response(&response->data.samlogon);

	torture_assert_int_equal(tctx, response->data.samlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE, "Got incorrect netlogon response command");

	torture_assert_str_equal(tctx, response->data.samlogon.data.nt5_ex.user_name, TEST_NAME"$", "Got incorrect user in netlogon response");

	torture_assert(tctx,
		       strstr(response->data.samlogon.data.nt5_ex.pdc_name, "\\\\") != NULL,
		       "PDC name should be in UNC form");

	/* setup (another) temporary mailslot listener for replies */
	dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
				      netlogon_handler, NULL);
	torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC");
	
	ZERO_STRUCT(logon);
	logon.command = LOGON_PRIMARY_QUERY;
	logon.req.pdc.computer_name = TEST_NAME;
	logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
	logon.req.pdc.unicode_name  = TEST_NAME;
	logon.req.pdc.nt_version    = 1;
	logon.req.pdc.lmnt_token    = 0xFFFF;
	logon.req.pdc.lm20_token    = 0xFFFF;

	make_nbt_name_client(&myname, TEST_NAME);

	dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
					   address, lpcfg_dgram_port(tctx->lp_ctx));
	torture_assert(tctx, dest != NULL, "Error getting address");
	status = dgram_mailslot_netlogon_send(dgmsock, 
					      &name, dest, 
					      NBT_MAILSLOT_NTLOGON, 
					      &myname, &logon);
	torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");

	while (timeval_elapsed(&tv) < 5 && !dgmslot->private_data) {
		tevent_loop_once(dgmsock->event_ctx);
	}

	response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);

	torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");

	torture_assert_int_equal(tctx, response->response_type, NETLOGON_GET_PDC, "Got incorrect type of ntlogon response");
	torture_assert_int_equal(tctx, response->data.get_pdc.command, NETLOGON_RESPONSE_FROM_PDC, "Got incorrect ntlogon response command");

	torture_leave_domain(tctx, join_ctx);

	/* setup (another) temporary mailslot listener for replies */
	dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
				      netlogon_handler, NULL);
	torture_assert(tctx, dgmslot != NULL, "Error temporary mailslot for GetDC");
	
	ZERO_STRUCT(logon);
	logon.command = LOGON_PRIMARY_QUERY;
	logon.req.pdc.computer_name = TEST_NAME;
	logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
	logon.req.pdc.unicode_name  = TEST_NAME;
	logon.req.pdc.nt_version    = 1;
	logon.req.pdc.lmnt_token    = 0xFFFF;
	logon.req.pdc.lm20_token    = 0xFFFF;

	make_nbt_name_client(&myname, TEST_NAME);

	dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
					   address, lpcfg_dgram_port(tctx->lp_ctx));
	torture_assert(tctx, dest != NULL, "Error getting address");
	status = dgram_mailslot_netlogon_send(dgmsock, 
					      &name, dest, 
					      NBT_MAILSLOT_NTLOGON, 
					      &myname, &logon);
	torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");

	while (timeval_elapsed(&tv) < 5 && !dgmslot->private_data) {
		tevent_loop_once(dgmsock->event_ctx);
	}

	response = talloc_get_type(dgmslot->private_data, struct nbt_netlogon_response);

	torture_assert(tctx, response != NULL, "Failed to receive a netlogon reply packet");

	torture_assert_int_equal(tctx, response->response_type, NETLOGON_GET_PDC, "Got incorrect type of ntlogon response");
	torture_assert_int_equal(tctx, response->data.get_pdc.command, NETLOGON_RESPONSE_FROM_PDC, "Got incorrect ntlogon response command");


	return true;
}
Example #12
0
/*
  startup the wrepl port 42 server sockets
*/
NTSTATUS wreplsrv_setup_sockets(struct wreplsrv_service *service, struct loadparm_context *lp_ctx)
{
	NTSTATUS status;
	struct task_server *task = service->task;
	const struct model_ops *model_ops;
	const char *address;
	uint16_t port = WINS_REPLICATION_PORT;

	/* within the wrepl task we want to be a single process, so
	   ask for the single process model ops and pass these to the
	   stream_setup_socket() call. */
	model_ops = process_model_startup("single");
	if (!model_ops) {
		DEBUG(0,("Can't find 'single' process model_ops"));
		return NT_STATUS_INTERNAL_ERROR;
	}

	if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
		int num_interfaces;
		int i;
		struct interface *ifaces;

		load_interface_list(task, lp_ctx, &ifaces);

		num_interfaces = iface_list_count(ifaces);

		/* We have been given an interfaces line, and been 
		   told to only bind to those interfaces. Create a
		   socket per interface and bind to only these.
		*/
		for(i = 0; i < num_interfaces; i++) {
			if (!iface_list_n_is_v4(ifaces, i)) {
				continue;
			}
			address = iface_list_n_ip(ifaces, i);
			status = stream_setup_socket(task, task->event_ctx,
						     task->lp_ctx, model_ops,
						     &wreplsrv_stream_ops,
						     "ipv4", address, &port, 
					              lpcfg_socket_options(task->lp_ctx),
						     service);
			if (!NT_STATUS_IS_OK(status)) {
				DEBUG(0,("stream_setup_socket(address=%s,port=%u) failed - %s\n",
					 address, port, nt_errstr(status)));
				return status;
			}
		}
	} else {
		address = "0.0.0.0";
		status = stream_setup_socket(task, task->event_ctx, task->lp_ctx,
					     model_ops, &wreplsrv_stream_ops,
					     "ipv4", address, &port, lpcfg_socket_options(task->lp_ctx),
					     service);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0,("stream_setup_socket(address=%s,port=%u) failed - %s\n",
				 address, port, nt_errstr(status)));
			return status;
		}
	}

	return NT_STATUS_OK;
}
Example #13
0
struct dnsserver_serverinfo *dnsserver_init_serverinfo(TALLOC_CTX *mem_ctx,
							struct loadparm_context *lp_ctx,
							struct ldb_context *samdb)
{
	struct dnsserver_serverinfo *serverinfo;
	struct dcerpc_server_info *dinfo;
	struct ldb_dn *domain_dn, *forest_dn;
	struct interface *ifaces;
	int num_interfaces, i;

	serverinfo = talloc_zero(mem_ctx, struct dnsserver_serverinfo);
	if (serverinfo == NULL) {
		return NULL;
	}

	dinfo = lpcfg_dcerpc_server_info(mem_ctx, lp_ctx);
	if (dinfo) {
		serverinfo->dwVersion = (dinfo->version_build & 0x0000FFFF) << 16 |
				(dinfo->version_minor & 0x000000FF) << 8 |
				(dinfo->version_major & 0x000000FF);
		talloc_free(dinfo);
	} else {
		serverinfo->dwVersion = 0x0ECE0205; /* build, os_minor, os_major */;
	}

	serverinfo->fBootMethod = DNS_BOOT_METHOD_DIRECTORY;
	serverinfo->fAdminConfigured = 0;
	serverinfo->fAllowUpdate = 1;
	serverinfo->fDsAvailable = 1;

	serverinfo->pszServerName = talloc_asprintf(mem_ctx, "%s.%s",
					lpcfg_netbios_name(lp_ctx),
					lpcfg_dnsdomain(lp_ctx));

	domain_dn = ldb_get_default_basedn(samdb);
	forest_dn = ldb_get_root_basedn(samdb);

	serverinfo->pszDsContainer = talloc_asprintf(mem_ctx,
					"CN=MicrosoftDNS,DC=DomainDnsZones,%s",
					ldb_dn_get_linearized(domain_dn));

	serverinfo->dwDsForestVersion = dsdb_forest_functional_level(samdb);
	serverinfo->dwDsDomainVersion = dsdb_functional_level(samdb);
	serverinfo->dwDsDsaVersion = 4; /* need to do ldb search here */

	serverinfo->pszDomainName = samdb_dn_to_dns_domain(mem_ctx, domain_dn);
	serverinfo->pszForestName = samdb_dn_to_dns_domain(mem_ctx, forest_dn);

	serverinfo->pszDomainDirectoryPartition = talloc_asprintf(mem_ctx,
							"DC=DomainDnsZones,%s",
							ldb_dn_get_linearized(domain_dn));
	serverinfo->pszForestDirectoryPartition = talloc_asprintf(mem_ctx,
							"DC=ForestDnsZones,%s",
							ldb_dn_get_linearized(forest_dn));

	load_interface_list(mem_ctx, lp_ctx, &ifaces);
	num_interfaces = iface_list_count(ifaces);

	serverinfo->aipServerAddrs = talloc_zero(mem_ctx, struct IP4_ARRAY);

	if (serverinfo->aipServerAddrs) {
		serverinfo->aipServerAddrs->AddrCount = num_interfaces;
		if (num_interfaces > 0) {
			serverinfo->aipServerAddrs->AddrArray = talloc_zero_array(mem_ctx,
									unsigned int,
									num_interfaces);
			if (serverinfo->aipServerAddrs->AddrArray) {
				for (i=0; i<num_interfaces; i++) {
					serverinfo->aipServerAddrs->AddrArray[i] = inet_addr(iface_list_n_ip(ifaces, i));
				}
			} else {
				serverinfo->aipServerAddrs->AddrCount = 0;
			}
		}
Example #14
0
/*
  startup the web server task
*/
static void websrv_task_init(struct task_server *task)
{
	NTSTATUS status;
	uint16_t port = lpcfg_web_port(task->lp_ctx);
	const struct model_ops *model_ops;
	struct web_server_data *wdata;

	task_server_set_title(task, "task[websrv]");

	/* run the web server as a single process */
	model_ops = process_model_startup("single");
	if (!model_ops) goto failed;

	/* startup the Python processor - unfortunately we can't do this
	   per connection as that wouldn't allow for session variables */
	wdata = talloc_zero(task, struct web_server_data);
	if (wdata == NULL) goto failed;

	wdata->task = task;
	task->private_data = wdata;

	if (lpcfg_interfaces(task->lp_ctx) && lpcfg_bind_interfaces_only(task->lp_ctx)) {
		int num_interfaces;
		int i;
		struct interface *ifaces;

		load_interface_list(NULL, task->lp_ctx, &ifaces);

		num_interfaces = iface_list_count(ifaces);
		for(i = 0; i < num_interfaces; i++) {
			const char *address = iface_list_n_ip(ifaces, i);
			status = stream_setup_socket(task,
						     task->event_ctx,
						     task->lp_ctx, model_ops,
						     &web_stream_ops, 
						     "ip", address,
						     &port, lpcfg_socket_options(task->lp_ctx),
						     task);
			if (!NT_STATUS_IS_OK(status)) goto failed;
		}

		talloc_free(ifaces);
	} else {
		char **wcard;
		int i;
		wcard = iface_list_wildcard(task);
		if (wcard == NULL) {
			DEBUG(0,("No wildcard addresses available\n"));
			goto failed;
		}
		for (i=0; wcard[i]; i++) {
			status = stream_setup_socket(task, task->event_ctx,
						     task->lp_ctx, model_ops,
						     &web_stream_ops,
						     "ip", wcard[i],
						     &port, lpcfg_socket_options(task->lp_ctx),
						     wdata);
			if (!NT_STATUS_IS_OK(status)) goto failed;
		}
		talloc_free(wcard);
	}

	wdata->tls_params = tls_initialise(wdata, task->lp_ctx);
	if (wdata->tls_params == NULL) goto failed;

	if (!wsgi_initialize(wdata)) goto failed;


	return;

failed:
	task_server_terminate(task, "websrv_task_init: failed to startup web server task", true);
}
Example #15
0
File: wins.c Project: Arkhont/samba
/*
  test operations against a WINS server
*/
static bool nbt_test_wins_name(struct torture_context *tctx, const char *address,
			       struct nbt_name *name, uint16_t nb_flags,
			       bool try_low_port,
			       uint8_t register_rcode)
{
	struct nbt_name_register_wins io;
	struct nbt_name_register name_register;
	struct nbt_name_query query;
	struct nbt_name_refresh_wins refresh;
	struct nbt_name_release release;
	struct nbt_name_request *req;
	NTSTATUS status;
	struct nbt_name_socket *nbtsock = torture_init_nbt_socket(tctx);
	const char *myaddress;
	struct socket_address *socket_address;
	struct interface *ifaces;
	bool low_port = try_low_port;

	load_interface_list(tctx, tctx->lp_ctx, &ifaces);

	myaddress = talloc_strdup(tctx, iface_list_best_ip(ifaces, address));

	socket_address = socket_address_from_strings(tctx, 
						     nbtsock->sock->backend_name,
						     myaddress, lpcfg_nbt_port(tctx->lp_ctx));
	torture_assert(tctx, socket_address != NULL, 
				   "Error getting address");

	/* we do the listen here to ensure the WINS server receives the packets from
	   the right IP */
	status = socket_listen(nbtsock->sock, socket_address, 0, 0);
	talloc_free(socket_address);
	if (!NT_STATUS_IS_OK(status)) {
		low_port = false;
		socket_address = socket_address_from_strings(tctx,
							     nbtsock->sock->backend_name,
							     myaddress, 0);
		torture_assert(tctx, socket_address != NULL,
			       "Error getting address");

		status = socket_listen(nbtsock->sock, socket_address, 0, 0);
		talloc_free(socket_address);
		torture_assert_ntstatus_ok(tctx, status,
					   "socket_listen for WINS failed");
	}

	torture_comment(tctx, "Testing name registration to WINS with name %s at %s nb_flags=0x%x\n", 
	       nbt_name_string(tctx, name), myaddress, nb_flags);

	torture_comment(tctx, "release the name\n");
	release.in.name = *name;
	release.in.dest_port = lpcfg_nbt_port(tctx->lp_ctx);
	release.in.dest_addr = address;
	release.in.address = myaddress;
	release.in.nb_flags = nb_flags;
	release.in.broadcast = false;
	release.in.timeout = 3;
	release.in.retries = 0;

	status = nbt_name_release(nbtsock, tctx, &release);
	torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "Bad response from %s for name query", address));
	CHECK_VALUE(tctx, release.out.rcode, 0);

	if (nb_flags & NBT_NM_GROUP) {
		/* ignore this for group names */
	} else if (!low_port) {
		torture_comment(tctx, "no low port - skip: register the name with a wrong address\n");
	} else {
		torture_comment(tctx, "register the name with a wrong address (makes the next request slow!)\n");
		io.in.name = *name;
		io.in.wins_port = lpcfg_nbt_port(tctx->lp_ctx);
		io.in.wins_servers = const_str_list(
			str_list_make_single(tctx, address));
		io.in.addresses = const_str_list(
			str_list_make_single(tctx, "127.64.64.1"));
		io.in.nb_flags = nb_flags;
		io.in.ttl = 300000;

		status = nbt_name_register_wins(nbtsock, tctx, &io);
		if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
			torture_assert_ntstatus_ok(tctx, status,
				talloc_asprintf(tctx, "No response from %s for name register\n",
						address));
		}
		torture_assert_ntstatus_ok(tctx, status,
			talloc_asprintf(tctx, "Bad response from %s for name register\n",
					address));

		CHECK_STRING(tctx, io.out.wins_server, address);
		CHECK_VALUE(tctx, io.out.rcode, 0);

		torture_comment(tctx, "register the name correct address\n");
		name_register.in.name		= *name;
		name_register.in.dest_port	= lpcfg_nbt_port(tctx->lp_ctx);
		name_register.in.dest_addr	= address;
		name_register.in.address	= myaddress;
		name_register.in.nb_flags	= nb_flags;
		name_register.in.register_demand= false;
		name_register.in.broadcast	= false;
		name_register.in.multi_homed	= true;
		name_register.in.ttl		= 300000;
		name_register.in.timeout	= 3;
		name_register.in.retries	= 2;

		/*
		 * test if the server ignores resent requests
		 */
		req = nbt_name_register_send(nbtsock, &name_register);
		while (true) {
			event_loop_once(nbtsock->event_ctx);
			if (req->state != NBT_REQUEST_WAIT) {
				break;
			}
			if (req->received_wack) {
				/*
				 * if we received the wack response
				 * we resend the request and the
				 * server should ignore that
				 * and not handle it as new request
				 */
				req->state = NBT_REQUEST_SEND;
				DLIST_ADD_END(nbtsock->send_queue, req,
					      struct nbt_name_request *);
				EVENT_FD_WRITEABLE(nbtsock->fde);
				break;
			}
		}

		status = nbt_name_register_recv(req, tctx, &name_register);
		if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
			torture_assert_ntstatus_ok(tctx, status,
				talloc_asprintf(tctx, "No response from %s for name register\n",
						address));
		}
		torture_assert_ntstatus_ok(tctx, status,
			talloc_asprintf(tctx, "Bad response from %s for name register\n",
					address));

		CHECK_VALUE(tctx, name_register.out.rcode, 0);
		CHECK_STRING(tctx, name_register.out.reply_addr, myaddress);
	}