Example #1
0
/*
  reply to a GETDC request
 */
static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, 
				struct nbtd_interface *iface,
				struct nbt_dgram_packet *packet, 
				const struct socket_address *src,
				struct nbt_netlogon_packet *netlogon)
{
	struct nbt_name *name = &packet->data.msg.dest_name;
	struct nbtd_interface *reply_iface = nbtd_find_reply_iface(iface, src->addr, false);
	struct nbt_netlogon_response_from_pdc *pdc;
	struct ldb_context *samctx;
	struct nbt_netlogon_response netlogon_response;

	/* only answer getdc requests on the PDC or LOGON names */
	if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) {
		return;
	}

	samctx = iface->nbtsrv->sam_ctx;

	if (lpcfg_server_role(iface->nbtsrv->task->lp_ctx) != ROLE_DOMAIN_CONTROLLER
	    || !samdb_is_pdc(samctx)) {
		DEBUG(2, ("Not a PDC, so not processing LOGON_PRIMARY_QUERY\n"));
		return;		
	}

	if (strcasecmp_m(name->name, lpcfg_workgroup(iface->nbtsrv->task->lp_ctx)) != 0) {
		DEBUG(5,("GetDC requested for a domian %s that we don't host\n", name->name));
		return;
	}

	/* setup a GETDC reply */
	ZERO_STRUCT(netlogon_response);
	netlogon_response.response_type = NETLOGON_GET_PDC;
	pdc = &netlogon_response.data.get_pdc;

	pdc->command = NETLOGON_RESPONSE_FROM_PDC;
	pdc->pdc_name         = lpcfg_netbios_name(iface->nbtsrv->task->lp_ctx);
	pdc->unicode_pdc_name = pdc->pdc_name;
	pdc->domain_name      = lpcfg_workgroup(iface->nbtsrv->task->lp_ctx);
	pdc->nt_version       = 1;
	pdc->lmnt_token       = 0xFFFF;
	pdc->lm20_token       = 0xFFFF;

	dgram_mailslot_netlogon_reply(reply_iface->dgmsock, 
				      packet, 
				      lpcfg_netbios_name(iface->nbtsrv->task->lp_ctx),
				      netlogon->req.pdc.mailslot_name,
				      &netlogon_response);
}
Example #2
0
/**
 * Return a anonymous logon for anonymous users (username = "")
 *
 * Typically used as the first module in the auth chain, this allows
 * anonymou logons to be dealt with in one place.  Non-anonymou logons 'fail'
 * and pass onto the next module.
 **/
static NTSTATUS anonymous_check_password(struct auth_method_context *ctx,
			      		 TALLOC_CTX *mem_ctx,
					 const struct auth_usersupplied_info *user_info, 
					 struct auth_user_info_dc **_user_info_dc)
{
	return auth_anonymous_user_info_dc(mem_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx), _user_info_dc);
}
Example #3
0
/*
  handle incoming netlogon mailslot requests
*/
void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot,
				    struct nbt_dgram_packet *packet,
				    struct socket_address *src)
{
	NTSTATUS status = NT_STATUS_NO_MEMORY;
	struct nbtd_interface *iface =
		talloc_get_type(dgmslot->private_data, struct nbtd_interface);
	struct nbtd_interface *reply_iface = nbtd_find_reply_iface(
		iface, src->addr, false);
	struct nbt_netlogon_response *response = NULL;
	char *reply_mailslot = NULL;

	if (reply_iface->ip_address == NULL) {
		DBG_WARNING("Could not obtain own IP address for datagram "
			    "socket\n");
		return;
	}

	status = nbtd_mailslot_netlogon_reply(
		iface, packet, src, dgmslot, &response, &reply_mailslot);

	if (NT_STATUS_IS_OK(status)) {
		dgram_mailslot_netlogon_reply(
			reply_iface->dgmsock, packet,
			lpcfg_netbios_name(iface->nbtsrv->task->lp_ctx),
			reply_mailslot, response);
	}

	TALLOC_FREE(response);
	TALLOC_FREE(reply_mailslot);
}
Example #4
0
/*
  ioctl - used for job query
*/
static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs,
			    struct ntvfs_request *req, union smb_ioctl *io)
{
	char *p;

	if (io->generic.level != RAW_IOCTL_IOCTL) {
		return NT_STATUS_NOT_IMPLEMENTED;
	}

	if (io->ioctl.in.request == IOCTL_QUERY_JOB_INFO) {

		/* a request for the print job id of an open print job */
		io->ioctl.out.blob = data_blob_talloc(req, NULL, 32);

		data_blob_clear(&io->ioctl.out.blob);

		p = (char *)io->ioctl.out.blob.data;
		SSVAL(p,0, 1 /* REWRITE: fsp->rap_print_jobid */);
		push_string(p+2, lpcfg_netbios_name(ntvfs->ctx->lp_ctx), 15, STR_TERMINATE|STR_ASCII);
		push_string(p+18, ntvfs->ctx->config->name, 13, STR_TERMINATE|STR_ASCII);
		return NT_STATUS_OK;
	}

	return NT_STATUS_INVALID_PARAMETER;
}
NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, 
				  struct loadparm_context *lp_ctx,
				  struct auth_session_info **_session_info) 
{
	NTSTATUS nt_status;
	struct auth_user_info_dc *user_info_dc = NULL;
	struct auth_session_info *session_info = NULL;
	TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
	
	nt_status = auth_system_user_info_dc(mem_ctx, lpcfg_netbios_name(lp_ctx),
					    &user_info_dc);
	if (!NT_STATUS_IS_OK(nt_status)) {
		talloc_free(mem_ctx);
		return nt_status;
	}

	/* references the user_info_dc into the session_info */
	nt_status = auth_generate_session_info(parent_ctx, NULL, NULL, user_info_dc, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES, &session_info);
	talloc_free(mem_ctx);

	NT_STATUS_NOT_OK_RETURN(nt_status);

	session_info->credentials = cli_credentials_init(session_info);
	if (!session_info->credentials) {
		return NT_STATUS_NO_MEMORY;
	}

	cli_credentials_set_conf(session_info->credentials, lp_ctx);

	cli_credentials_set_machine_account_pending(session_info->credentials, lp_ctx);
	*_session_info = session_info;

	return NT_STATUS_OK;
}
Example #6
0
/*
  setup our listening sockets on the configured network interfaces
*/
NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_context *lp_ctx,
				 struct interface *ifaces)
{
	int num_interfaces = iface_count(ifaces);
	int i;
	TALLOC_CTX *tmp_ctx = talloc_new(nbtsrv);
	NTSTATUS status;

	/* if we are allowing incoming packets from any address, then
	   we also need to bind to the wildcard address */
	if (!lpcfg_bind_interfaces_only(lp_ctx)) {
		const char *primary_address;

		/* the primary address is the address we will return
		   for non-WINS queries not made on a specific
		   interface */
		if (num_interfaces > 0) {
			primary_address = iface_n_ip(ifaces, 0);
		} else {
			primary_address = inet_ntoa(interpret_addr2(
							lpcfg_netbios_name(lp_ctx)));
		}
		primary_address = talloc_strdup(tmp_ctx, primary_address);
		NT_STATUS_HAVE_NO_MEMORY(primary_address);

		status = nbtd_add_socket(nbtsrv, 
					 lp_ctx,
					 "0.0.0.0",
					 primary_address,
					 talloc_strdup(tmp_ctx, "255.255.255.255"),
					 talloc_strdup(tmp_ctx, "0.0.0.0"));
		NT_STATUS_NOT_OK_RETURN(status);
	}

	for (i=0; i<num_interfaces; i++) {
		const char *bcast = iface_n_bcast(ifaces, i);
		const char *address, *netmask;

		/* we can't assume every interface is broadcast capable */
		if (bcast == NULL) continue;

		address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i));
		bcast   = talloc_strdup(tmp_ctx, bcast);
		netmask = talloc_strdup(tmp_ctx, iface_n_netmask(ifaces, i));

		status = nbtd_add_socket(nbtsrv, lp_ctx,
					 address, address, bcast, netmask);
		NT_STATUS_NOT_OK_RETURN(status);
	}

	if (lpcfg_wins_server_list(lp_ctx)) {
		status = nbtd_add_wins_socket(nbtsrv);
		NT_STATUS_NOT_OK_RETURN(status);
	}

	talloc_free(tmp_ctx);

	return NT_STATUS_OK;
}
/* 
  spoolss_RemoteFindFirstPrinterChangeNotifyEx 
*/
static WERROR dcesrv_spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
		       struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
{
	struct dcerpc_pipe *p;
	struct dcerpc_binding *binding;
	NTSTATUS status;
	struct spoolss_ReplyOpenPrinter rop;
	struct cli_credentials *creds;
	struct policy_handle notify_handle;

	DEBUG(2, ("Received RFFPCNex from %s\n", r->in.local_machine));

	/*
	 * TODO: for now just open a connection to the client and drop it again
	 *       to keep the w2k3 PrintServer 
	 *       happy to allow to open the Add Printer GUI
	 *       and the torture suite passing
	 */

	binding = talloc_zero(mem_ctx, struct dcerpc_binding);

	binding->transport = NCACN_NP; 
	if (strncmp(r->in.local_machine, "\\\\", 2))
		return WERR_INVALID_COMPUTERNAME;
	binding->host = r->in.local_machine+2;

	creds = cli_credentials_init_anon(mem_ctx); /* FIXME: Use machine credentials instead ? */

	status = dcerpc_pipe_connect_b(mem_ctx, &p, binding, &ndr_table_spoolss, 
				       creds, dce_call->event_ctx,
				       dce_call->conn->dce_ctx->lp_ctx);

	if (NT_STATUS_IS_ERR(status)) {
		DEBUG(0, ("unable to call back to %s\n", r->in.local_machine));
		return WERR_SERVER_UNAVAILABLE;
	}

	ZERO_STRUCT(rop);
	rop.in.server_name = lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx);
	W_ERROR_HAVE_NO_MEMORY(rop.in.server_name);
	rop.in.printer_local = 0;
	rop.in.type = REG_NONE;
	rop.in.bufsize = 0;
	rop.in.buffer = NULL;
	rop.out.handle = &notify_handle;

	status = dcerpc_spoolss_ReplyOpenPrinter_r(p->binding_handle, mem_ctx, &rop);
	if (NT_STATUS_IS_ERR(status)) {
		DEBUG(0, ("unable to open remote printer %s\n",
			r->in.local_machine));
		return WERR_SERVER_UNAVAILABLE;
	}

	talloc_free(p);

	return WERR_OK;
}
Example #8
0
File: util.c Project: amitay/samba
const char *lpcfg_sam_name(struct loadparm_context *lp_ctx)
{
	switch (lpcfg_server_role(lp_ctx)) {
	case ROLE_DOMAIN_BDC:
	case ROLE_DOMAIN_PDC:
		return lpcfg_workgroup(lp_ctx);
	default:
		return lpcfg_netbios_name(lp_ctx);
	}
}
Example #9
0
/**
 * Specifies default values for domain, workstation and realm
 * from the smb.conf configuration file
 *
 * @param cred Credentials structure to fill in
 */
_PUBLIC_ void cli_credentials_set_conf(struct cli_credentials *cred, 
			      struct loadparm_context *lp_ctx)
{
	cli_credentials_set_username(cred, "", CRED_UNINITIALISED);
	if (lpcfg_parm_is_cmdline(lp_ctx, "workgroup")) {
		cli_credentials_set_domain(cred, lpcfg_workgroup(lp_ctx), CRED_SPECIFIED);
	} else {
		cli_credentials_set_domain(cred, lpcfg_workgroup(lp_ctx), CRED_UNINITIALISED);
	}
	if (lpcfg_parm_is_cmdline(lp_ctx, "netbios name")) {
		cli_credentials_set_workstation(cred, lpcfg_netbios_name(lp_ctx), CRED_SPECIFIED);
	} else {
		cli_credentials_set_workstation(cred, lpcfg_netbios_name(lp_ctx), CRED_UNINITIALISED);
	}
	if (lpcfg_parm_is_cmdline(lp_ctx, "realm")) {
		cli_credentials_set_realm(cred, lpcfg_realm(lp_ctx), CRED_SPECIFIED);
	} else {
		cli_credentials_set_realm(cred, lpcfg_realm(lp_ctx), CRED_UNINITIALISED);
	}
}
Example #10
0
/*
  reply to a ADS style GETDC request
 */
static void nbtd_netlogon_samlogon(struct dgram_mailslot_handler *dgmslot,
				   struct nbtd_interface *iface,
				   struct nbt_dgram_packet *packet, 
				   const struct socket_address *src,
				   struct nbt_netlogon_packet *netlogon)
{
	struct nbt_name *name = &packet->data.msg.dest_name;
	struct nbtd_interface *reply_iface = nbtd_find_reply_iface(iface, src->addr, false);
	struct ldb_context *samctx;
	const char *my_ip = reply_iface->ip_address; 
	struct dom_sid *sid;
	struct nbt_netlogon_response netlogon_response;
	NTSTATUS status;

	if (!my_ip) {
		DEBUG(0, ("Could not obtain own IP address for datagram socket\n"));
		return;
	}

	/* only answer getdc requests on the PDC or LOGON names */
	if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) {
		return;
	}

	samctx = iface->nbtsrv->sam_ctx;

	if (netlogon->req.logon.sid_size) {
		sid = &netlogon->req.logon.sid;
	} else {
		sid = NULL;
	}

	status = fill_netlogon_samlogon_response(samctx, packet, NULL, name->name, sid, NULL, 
						 netlogon->req.logon.user_name, netlogon->req.logon.acct_control, src->addr, 
						 netlogon->req.logon.nt_version, iface->nbtsrv->task->lp_ctx, &netlogon_response.data.samlogon, false);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(2,("NBT netlogon query failed domain=%s sid=%s version=%d - %s\n",
			 name->name, dom_sid_string(packet, sid), netlogon->req.logon.nt_version, nt_errstr(status)));
		return;
	}

	netlogon_response.response_type = NETLOGON_SAMLOGON;

	packet->data.msg.dest_name.type = 0;

	dgram_mailslot_netlogon_reply(reply_iface->dgmsock, 
				      packet, 
				      lpcfg_netbios_name(iface->nbtsrv->task->lp_ctx),
				      netlogon->req.logon.mailslot_name,
				      &netlogon_response);
}
Example #11
0
const char *dcesrv_common_get_server_name(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, const char *server_unc)
{
	const char *p = server_unc;

	/* if there's no string return our NETBIOS name */
	if (!p) {
		return talloc_strdup(mem_ctx, lpcfg_netbios_name(dce_ctx->lp_ctx));
	}

	/* if there're '\\\\' in front remove them otherwise just pass the string */
	if (p[0] == '\\' && p[1] == '\\') {
		p += 2;
	}

	return talloc_strdup(mem_ctx, p);
}
Example #12
0
File: util.c Project: amitay/samba
/**
  see if a string matches either our primary or one of our secondary 
  netbios aliases. do a case insensitive match
*/
bool lpcfg_is_myname(struct loadparm_context *lp_ctx, const char *name)
{
	const char **aliases;
	int i;

	if (strcasecmp_m(name, lpcfg_netbios_name(lp_ctx)) == 0) {
		return true;
	}

	aliases = lpcfg_netbios_aliases(lp_ctx);
	for (i=0; aliases && aliases[i]; i++) {
		if (strcasecmp_m(name, aliases[i]) == 0) {
			return true;
		}
	}

	return false;
}
Example #13
0
NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx,
				struct hdb_entry_ex *client,
				DATA_BLOB **_pac_blob)
{
	struct samba_kdc_entry *p = talloc_get_type(client->ctx, struct samba_kdc_entry);
	struct auth_user_info_dc *user_info_dc;
	DATA_BLOB *pac_blob;
	NTSTATUS nt_status;

	/* The user account may be set not to want the PAC */
	if ( ! samba_princ_needs_pac(client)) {
		*_pac_blob = NULL;
		return NT_STATUS_OK;
	}

	pac_blob = talloc_zero(mem_ctx, DATA_BLOB);
	if (!pac_blob) {
		return NT_STATUS_NO_MEMORY;
	}

	nt_status = authsam_make_user_info_dc(mem_ctx, p->kdc_db_ctx->samdb,
					     lpcfg_netbios_name(p->kdc_db_ctx->lp_ctx),
					     lpcfg_sam_name(p->kdc_db_ctx->lp_ctx),
					     p->realm_dn,
					     p->msg,
					     data_blob(NULL, 0),
					     data_blob(NULL, 0),
					     &user_info_dc);
	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(0, ("Getting user info for PAC failed: %s\n",
			  nt_errstr(nt_status)));
		return nt_status;
	}

	nt_status = samba_get_logon_info_pac_blob(mem_ctx, user_info_dc, pac_blob);
	if (!NT_STATUS_IS_OK(nt_status)) {
		DEBUG(0, ("Building PAC failed: %s\n",
			  nt_errstr(nt_status)));
		return nt_status;
	}

	*_pac_blob = pac_blob;
	return NT_STATUS_OK;
}
/**
   \details This function replaces network address from the binding
   strings returned by Exchange for the PR_EMS_AB_NETWORK_ADDRESS
   property and limit the binding strings scope to ncacn_ip_tcp.

   \param dce_call pointer to the session context
   \param r pointer to the NspiGetProps structure

   \return true on success, otherwise false
 */
bool mapiproxy_NspiGetProps(struct dcesrv_call_state *dce_call, struct NspiGetProps *r)
{
	uint32_t		i;
	uint32_t		propID = -1;
	struct SPropTagArray	*SPropTagArray = NULL;
	struct PropertyRow_r	*Row;
	struct StringArray_r	*slpstr;
	struct PropertyValue_r	*lpProp;

	/* Sanity checks */
	if (!r->out.ppRows) return false;
	if (!(*r->out.ppRows)->cValues) return false;

	/* Step 1. Find PR_EMS_AB_NETWORK_ADDRESS index */
	propID = -1;
	SPropTagArray = r->in.pPropTags;
	for (i = 0; i < SPropTagArray->cValues; i++) {
		if (SPropTagArray->aulPropTag[i] == PR_EMS_AB_NETWORK_ADDRESS) {
			propID = i;
			break;
		}
	}
	if (propID == -1) return false;

	/* Step 2. Retrieve the SLPSTRArray */
	Row = *r->out.ppRows;
	lpProp = &Row->lpProps[propID];

	if (!lpProp) return false;
	if (lpProp->ulPropTag != PR_EMS_AB_NETWORK_ADDRESS) return false;

	slpstr = &(lpProp->value.MVszA);

	/* Step 3. Modify Exchange binding strings and only return ncacn_ip_tcp */
	slpstr->cValues = 1;
	slpstr->lppszA[0] = talloc_asprintf(dce_call, "ncacn_ip_tcp:%s.%s", 
					    lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx), 
					    lpcfg_realm(dce_call->conn->dce_ctx->lp_ctx));
	slpstr->lppszA[0] = strlower_talloc(dce_call, slpstr->lppszA[0]);

	return true;
}
Example #15
0
static bool torture_winbind_struct_netbios_name(struct torture_context *torture)
{
	struct winbindd_response rep;
	const char *expected;

	ZERO_STRUCT(rep);

	torture_comment(torture, "Running WINBINDD_NETBIOS_NAME (struct based)\n");

	DO_STRUCT_REQ_REP(WINBINDD_NETBIOS_NAME, NULL, &rep);

	expected = torture_setting_string(torture,
					  "winbindd_netbios_name",
					  lpcfg_netbios_name(torture->lp_ctx));
	expected = strupper_talloc(torture, expected);

	torture_assert_str_equal(torture,
				 rep.data.netbios_name, expected,
				 "winbindd's netbios name doesn't match");

	return true;
}
/**
   \details exchange_ds_rfr RfrGetNewDSA (0x0) function

   \param dce_call pointer to the session context
   \param mem_ctx pointer to the memory context
   \param r pointer to the RfrGetNewDSA request data

   \note We incorrectly assume input pUserDN is correct and available,
   but it is OK for now.

   \return MAPI_E_SUCCESS on success
 */
static enum MAPISTATUS dcesrv_RfrGetNewDSA(struct dcesrv_call_state *dce_call,
					   TALLOC_CTX *mem_ctx,
					   struct RfrGetNewDSA *r)
{
	const char		*netbiosname = NULL;
	const char		*realm = NULL;
	char			*fqdn = NULL;

	OC_DEBUG(5, "exchange_ds_rfr: RfrGetNewDSA (0x0)");

	/* Step 0. Ensure incoming user is authenticated */
	if (!dcesrv_call_authenticated(dce_call)) {
		OC_DEBUG(1, "No challenge requested by client, cannot authenticate");

		r->out.ppszUnused = NULL;
		r->out.ppszServer = NULL;
		r->out.result = MAPI_E_LOGON_FAILED;
		return MAPI_E_LOGON_FAILED;
	}

	/* Step 1. We don't have load-balancing support yet, just return Samba FQDN name */
	netbiosname = lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx);
	realm = lpcfg_realm(dce_call->conn->dce_ctx->lp_ctx);
	if (!netbiosname || !realm) {
		r->out.ppszUnused = NULL;
		r->out.ppszServer = NULL;
		r->out.result = MAPI_E_NO_SUPPORT;
		return MAPI_E_NO_SUPPORT;			
	}

	fqdn = talloc_asprintf(mem_ctx, "%s.%s", netbiosname, realm);
	r->out.ppszUnused = NULL;
	r->out.ppszServer = talloc_array(mem_ctx, const char *, 2);
	r->out.ppszServer[0] = strlower_talloc(mem_ctx, fqdn);
	r->out.ppszServer[1] = NULL;
	r->out.result = MAPI_E_SUCCESS;

	return MAPI_E_SUCCESS;
}
Example #17
0
/*
  startup the winbind task
*/
static void winbind_task_init(struct task_server *task)
{
	uint16_t port = 1;
	const struct model_ops *model_ops;
	NTSTATUS status;
	struct wbsrv_service *service;
	struct wbsrv_listen_socket *listen_socket;
	char *errstring;
	struct dom_sid *primary_sid;
	bool ok;

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

	/* within the winbind 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) {
		task_server_terminate(task,
				      "Can't find 'single' process model_ops", true);
		return;
	}

	/* Make sure the directory for the Samba3 socket exists, and is of the correct permissions */
	ok = directory_create_or_exist_strict(lpcfg_winbindd_socket_directory(task->lp_ctx),
					      geteuid(), 0755);
	if (!ok) {
		task_server_terminate(task,
				      "Cannot create winbindd pipe directory", true);
		return;
	}

	/* Make sure the directory for the Samba3 socket exists, and is of the correct permissions */
	ok = directory_create_or_exist_strict(lpcfg_winbindd_privileged_socket_directory(task->lp_ctx),
			geteuid(), 0750);
	if (!ok) {
		task_server_terminate(task,
				      "Cannot create winbindd privileged pipe directory", true);
		return;
	}

	service = talloc_zero(task, struct wbsrv_service);
	if (!service) goto nomem;
	service->task	= task;


	/* Find the primary SID, depending if we are a standalone
	 * server (what good is winbind in this case, but anyway...),
	 * or are in a domain as a member or a DC */
	switch (lpcfg_server_role(service->task->lp_ctx)) {
	case ROLE_STANDALONE:
		primary_sid = secrets_get_domain_sid(service,
						     service->task->lp_ctx,
						     lpcfg_netbios_name(service->task->lp_ctx),
						     &service->sec_channel_type,
						     &errstring);
		if (!primary_sid) {
			char *message = talloc_asprintf(task, 
							"Cannot start Winbind (standalone configuration): %s: "
							"Have you provisioned this server (%s) or changed it's name?", 
							errstring, lpcfg_netbios_name(service->task->lp_ctx));
			task_server_terminate(task, message, true);
			return;
		}
		break;
	case ROLE_DOMAIN_MEMBER:
		primary_sid = secrets_get_domain_sid(service,
						     service->task->lp_ctx,
						     lpcfg_workgroup(service->task->lp_ctx),
						     &service->sec_channel_type,
						     &errstring);
		if (!primary_sid) {
			char *message = talloc_asprintf(task, "Cannot start Winbind (domain member): %s: "
							"Have you joined the %s domain?", 
							errstring, lpcfg_workgroup(service->task->lp_ctx));
			task_server_terminate(task, message, true);
			return;
		}
		break;
	case ROLE_ACTIVE_DIRECTORY_DC:
		primary_sid = secrets_get_domain_sid(service,
						     service->task->lp_ctx,
						     lpcfg_workgroup(service->task->lp_ctx),
						     &service->sec_channel_type,
						     &errstring);
		if (!primary_sid) {
			char *message = talloc_asprintf(task, "Cannot start Winbind (domain controller): %s: "
							"Have you provisioned the %s domain?", 
							errstring, lpcfg_workgroup(service->task->lp_ctx));
			task_server_terminate(task, message, true);
			return;
		}
		break;
	case ROLE_DOMAIN_PDC:
	case ROLE_DOMAIN_BDC:
		task_server_terminate(task, "Cannot start 'samba' winbindd as a 'classic samba' DC: use winbindd instead", true);
		return;
	}
	service->primary_sid = primary_sid;

	service->idmap_ctx = idmap_init(service, task->event_ctx, task->lp_ctx);
	if (service->idmap_ctx == NULL) {
		task_server_terminate(task, "Failed to load idmap database", true);
		return;
	}

	service->priv_pipe_dir = lpcfg_winbindd_privileged_socket_directory(task->lp_ctx);
	service->pipe_dir = lpcfg_winbindd_socket_directory(task->lp_ctx);

	/* setup the unprivileged samba3 socket */
	listen_socket = talloc(service, struct wbsrv_listen_socket);
	if (!listen_socket) goto nomem;
	listen_socket->socket_path	= talloc_asprintf(listen_socket, "%s/%s", 
							  service->pipe_dir, 
							  WINBINDD_SOCKET_NAME);
	if (!listen_socket->socket_path) goto nomem;
	listen_socket->service		= service;
	listen_socket->privileged	= false;
	status = stream_setup_socket(task, task->event_ctx, task->lp_ctx, model_ops,
				     &wbsrv_ops, "unix",
				     listen_socket->socket_path, &port,
				     lpcfg_socket_options(task->lp_ctx),
				     listen_socket);
	if (!NT_STATUS_IS_OK(status)) goto listen_failed;

	/* setup the privileged samba3 socket */
	listen_socket = talloc(service, struct wbsrv_listen_socket);
	if (!listen_socket) goto nomem;
	listen_socket->socket_path 
		= talloc_asprintf(listen_socket, "%s/%s", 
				  service->priv_pipe_dir,
				  WINBINDD_SOCKET_NAME);
	if (!listen_socket->socket_path) goto nomem;
	listen_socket->service		= service;
	listen_socket->privileged	= true;
	status = stream_setup_socket(task, task->event_ctx, task->lp_ctx, model_ops,
				     &wbsrv_ops, "unix",
				     listen_socket->socket_path, &port,
				     lpcfg_socket_options(task->lp_ctx),
				     listen_socket);
	if (!NT_STATUS_IS_OK(status)) goto listen_failed;

	status = wbsrv_init_irpc(service);
	if (!NT_STATUS_IS_OK(status)) goto irpc_failed;

	return;

listen_failed:
	DEBUG(0,("stream_setup_socket(path=%s) failed - %s\n",
		 listen_socket->socket_path, nt_errstr(status)));
	task_server_terminate(task, nt_errstr(status), true);
	return;
irpc_failed:
	DEBUG(0,("wbsrv_init_irpc() failed - %s\n",
		 nt_errstr(status)));
	task_server_terminate(task, nt_errstr(status), true);
	return;
nomem:
	task_server_terminate(task, nt_errstr(NT_STATUS_NO_MEMORY), true);
	return;
}
Example #18
0
/*
  connect to a share - used when a tree_connect operation comes in.
*/
static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, 
			     struct ntvfs_request *req,
			     union smb_tcon *tcon)
{
	NTSTATUS status;
	struct cvfs_private *p;
	const char *host, *user, *pass, *domain, *remote_share;
	struct smb_composite_connect io;
	struct composite_context *creq;
	struct share_config *scfg = ntvfs->ctx->config;

	struct cli_credentials *credentials;
	bool machine_account;
	bool s4u2proxy;
	const char* sharename;

	switch (tcon->generic.level) {
	case RAW_TCON_TCON:
		sharename = tcon->tcon.in.service;
		break;
	case RAW_TCON_TCONX:
		sharename = tcon->tconx.in.path;
		break;
	case RAW_TCON_SMB2:
		sharename = tcon->smb2.in.path;
		break;
	default:
		return NT_STATUS_INVALID_LEVEL;
	}

	if (strncmp(sharename, "\\\\", 2) == 0) {
		char *str = strchr(sharename+2, '\\');
		if (str) {
			sharename = str + 1;
		}
	}

	/* Here we need to determine which server to connect to.
	 * For now we use parametric options, type cifs.
	 * Later we will use security=server and auth_server.c.
	 */
	host = share_string_option(scfg, CIFS_SERVER, NULL);
	user = share_string_option(scfg, CIFS_USER, NULL);
	pass = share_string_option(scfg, CIFS_PASSWORD, NULL);
	domain = share_string_option(scfg, CIFS_DOMAIN, NULL);
	remote_share = share_string_option(scfg, CIFS_SHARE, NULL);
	if (!remote_share) {
		remote_share = sharename;
	}

	machine_account = share_bool_option(scfg, CIFS_USE_MACHINE_ACCT, CIFS_USE_MACHINE_ACCT_DEFAULT);
	s4u2proxy = share_bool_option(scfg, CIFS_USE_S4U2PROXY, CIFS_USE_S4U2PROXY_DEFAULT);

	p = talloc_zero(ntvfs, struct cvfs_private);
	if (!p) {
		return NT_STATUS_NO_MEMORY;
	}

	ntvfs->private_data = p;

	if (!host) {
		DEBUG(1,("CIFS backend: You must supply server\n"));
		return NT_STATUS_INVALID_PARAMETER;
	} 
	
	if (user && pass) {
		DEBUG(5, ("CIFS backend: Using specified password\n"));
		credentials = cli_credentials_init(p);
		if (!credentials) {
			return NT_STATUS_NO_MEMORY;
		}
		cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx);
		cli_credentials_set_username(credentials, user, CRED_SPECIFIED);
		if (domain) {
			cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
		}
		cli_credentials_set_password(credentials, pass, CRED_SPECIFIED);
	} else if (machine_account) {
		DEBUG(5, ("CIFS backend: Using machine account\n"));
		credentials = cli_credentials_init(p);
		cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx);
		if (domain) {
			cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
		}
		status = cli_credentials_set_machine_account(credentials, ntvfs->ctx->lp_ctx);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}
	} else if (req->session_info->credentials) {
		DEBUG(5, ("CIFS backend: Using delegated credentials\n"));
		credentials = req->session_info->credentials;
	} else if (s4u2proxy) {
		struct ccache_container *ccc = NULL;
		const char *err_str = NULL;
		int ret;
		char *impersonate_principal;
		char *self_service;
		char *target_service;

		impersonate_principal = talloc_asprintf(req, "%s@%s",
						req->session_info->info->account_name,
						req->session_info->info->domain_name);

		self_service = talloc_asprintf(req, "cifs/%s",
					       lpcfg_netbios_name(ntvfs->ctx->lp_ctx));

		target_service = talloc_asprintf(req, "cifs/%s", host);

		DEBUG(5, ("CIFS backend: Using S4U2Proxy credentials\n"));

		credentials = cli_credentials_init(p);
		cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx);
		if (domain) {
			cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED);
		}
		status = cli_credentials_set_machine_account(credentials, ntvfs->ctx->lp_ctx);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}
		cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
		cli_credentials_set_impersonate_principal(credentials,
							  impersonate_principal,
							  self_service);
		cli_credentials_set_target_service(credentials, target_service);
		ret = cli_credentials_get_ccache(credentials,
						 ntvfs->ctx->event_ctx,
						 ntvfs->ctx->lp_ctx,
						 &ccc,
						 &err_str);
		if (ret != 0) {
			status = NT_STATUS_CROSSREALM_DELEGATION_FAILURE;
			DEBUG(1,("S4U2Proxy: cli_credentials_get_ccache() gave: ret[%d] str[%s] - %s\n",
				ret, err_str, nt_errstr(status)));
			return status;
		}

	} else {
		DEBUG(1,("CIFS backend: NO delegated credentials found: You must supply server, user and password or the client must supply delegated credentials\n"));
		return NT_STATUS_INTERNAL_ERROR;
	}

	/* connect to the server, using the smbd event context */
	io.in.dest_host = host;
	io.in.dest_ports = lpcfg_smb_ports(ntvfs->ctx->lp_ctx);
	io.in.socket_options = lpcfg_socket_options(ntvfs->ctx->lp_ctx);
	io.in.called_name = host;
	io.in.credentials = credentials;
	io.in.fallback_to_anonymous = false;
	io.in.workgroup = lpcfg_workgroup(ntvfs->ctx->lp_ctx);
	io.in.service = remote_share;
	io.in.service_type = "?????";
	io.in.gensec_settings = lpcfg_gensec_settings(p, ntvfs->ctx->lp_ctx);
	lpcfg_smbcli_options(ntvfs->ctx->lp_ctx, &io.in.options);
	lpcfg_smbcli_session_options(ntvfs->ctx->lp_ctx, &io.in.session_options);

	if (!(ntvfs->ctx->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS)) {
		io.in.options.use_level2_oplocks = false;
	}

	creq = smb_composite_connect_send(&io, p,
					  lpcfg_resolve_context(ntvfs->ctx->lp_ctx),
					  ntvfs->ctx->event_ctx);
	status = smb_composite_connect_recv(creq, p);
	NT_STATUS_NOT_OK_RETURN(status);

	p->tree = io.out.tree;

	p->transport = p->tree->session->transport;
	SETUP_PID;
	p->ntvfs = ntvfs;

	ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "NTFS");
	NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->fs_type);
	ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:");
	NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type);

	if (tcon->generic.level == RAW_TCON_TCONX) {
		tcon->tconx.out.fs_type = ntvfs->ctx->fs_type;
		tcon->tconx.out.dev_type = ntvfs->ctx->dev_type;
	}

	/* we need to receive oplock break requests from the server */
	smbcli_oplock_handler(p->transport, oplock_handler, p);

	p->map_generic = share_bool_option(scfg, CIFS_MAP_GENERIC, CIFS_MAP_GENERIC_DEFAULT);

	p->map_trans2 = share_bool_option(scfg, CIFS_MAP_TRANS2, CIFS_MAP_TRANS2_DEFAULT);

	return NT_STATUS_OK;
}
Example #19
0
/*
  format a record for bind9
 */
static bool b9_format(struct dlz_bind9_data *state,
		      TALLOC_CTX *mem_ctx,
		      struct dnsp_DnssrvRpcRecord *rec,
		      const char **type, const char **data)
{
	switch (rec->wType) {
	case DNS_TYPE_A:
		*type = "a";
		*data = rec->data.ipv4;
		break;

	case DNS_TYPE_AAAA:
		*type = "aaaa";
		*data = rec->data.ipv6;
		break;

	case DNS_TYPE_CNAME:
		*type = "cname";
		*data = rec->data.cname;
		break;

	case DNS_TYPE_TXT:
		*type = "txt";
		*data = rec->data.txt;
		break;

	case DNS_TYPE_PTR:
		*type = "ptr";
		*data = rec->data.ptr;
		break;

	case DNS_TYPE_SRV:
		*type = "srv";
		*data = talloc_asprintf(mem_ctx, "%u %u %u %s",
					rec->data.srv.wPriority,
					rec->data.srv.wWeight,
					rec->data.srv.wPort,
					rec->data.srv.nameTarget);
		break;

	case DNS_TYPE_MX:
		*type = "mx";
		*data = talloc_asprintf(mem_ctx, "%u %s",
					rec->data.mx.wPriority,
					rec->data.mx.nameTarget);
		break;

	case DNS_TYPE_HINFO:
		*type = "hinfo";
		*data = talloc_asprintf(mem_ctx, "%s %s",
					rec->data.hinfo.cpu,
					rec->data.hinfo.os);
		break;

	case DNS_TYPE_NS:
		*type = "ns";
		*data = rec->data.ns;
		break;

	case DNS_TYPE_SOA: {
		const char *mname;
		*type = "soa";

		/* we need to fake the authoritative nameserver to
		 * point at ourselves. This is how AD DNS servers
		 * force clients to send updates to the right local DC
		 */
		mname = talloc_asprintf(mem_ctx, "%s.%s",
					lpcfg_netbios_name(state->lp), lpcfg_dnsdomain(state->lp));
		if (mname == NULL) {
			return false;
		}
		mname = strlower_talloc(mem_ctx, mname);
		if (mname == NULL) {
			return false;
		}

		state->soa_serial = rec->data.soa.serial;

		*data = talloc_asprintf(mem_ctx, "%s %s %u %u %u %u %u",
					mname,
					rec->data.soa.rname,
					rec->data.soa.serial,
					rec->data.soa.refresh,
					rec->data.soa.retry,
					rec->data.soa.expire,
					rec->data.soa.minimum);
		break;
	}

	default:
		state->log(ISC_LOG_ERROR, "samba b9_putrr: unhandled record type %u",
			   rec->wType);
		return false;
	}

	return true;
}
Example #20
0
		},{
			.version		= WITNESS_V2,
			.expected_status	= NT_STATUS_OK,
			.expected_result	= WERR_REVISION_MISMATCH
		},{
			.version		= WITNESS_V1,
			.net_name		= "",
			.ip_address		= "",
			.client_computer_name	= "",
			.expected_status	= NT_STATUS_OK,
			.expected_result	= WERR_INVALID_PARAMETER
		},{
			.version		= WITNESS_V1,
			.net_name		= NULL,
			.ip_address		= NULL,
			.client_computer_name	= lpcfg_netbios_name(tctx->lp_ctx),
			.expected_status	= NT_STATUS_OK,
			.expected_result	= WERR_INVALID_PARAMETER
		},{
			.version		= WITNESS_V2,
			.net_name		= NULL,
			.ip_address		= NULL,
			.client_computer_name	= lpcfg_netbios_name(tctx->lp_ctx),
			.expected_status	= NT_STATUS_OK,
			.expected_result	= WERR_REVISION_MISMATCH
		},{
			.version		= WITNESS_V1,
			.net_name		= dcerpc_server_name(p),
			.ip_address		= NULL,
			.client_computer_name	= lpcfg_netbios_name(tctx->lp_ctx),
			.expected_status	= NT_STATUS_OK,
Example #21
0
static WERROR sptr_PrintServerData(struct ntptr_GenericHandle *server,
				   TALLOC_CTX *mem_ctx,
				   const char *value_name,
				   union spoolss_PrinterData *r,
				   enum winreg_Type *type)
{
	struct dcerpc_server_info *server_info = lpcfg_dcerpc_server_info(mem_ctx, server->ntptr->lp_ctx);
	if (strcmp("W3SvcInstalled", value_name) == 0) {
		*type		= REG_DWORD;
		r->value	= 0;
		return WERR_OK;
	} else if (strcmp("BeepEnabled", value_name) == 0) {
		*type		= REG_DWORD;
		r->value	= 0;
		return WERR_OK;
	} else if (strcmp("EventLog", value_name) == 0) {
		*type		= REG_DWORD;
		r->value	= 0;
		return WERR_OK;
	} else if (strcmp("NetPopup", value_name) == 0) {
		*type		= REG_DWORD;
		r->value	= 0;
		return WERR_OK;
	} else if (strcmp("NetPopupToComputer", value_name) == 0) {
		*type		= REG_DWORD;
		r->value	= 0;
		return  WERR_OK;
	} else if (strcmp("MajorVersion", value_name) == 0) {
		*type		= REG_DWORD;
		r->value	= 3;
		return WERR_OK;
	} else if (strcmp("MinorVersion", value_name) == 0) {
		*type		= REG_DWORD;
		r->value	= 0;
		return WERR_OK;
	} else if (strcmp("DefaultSpoolDirectory", value_name) == 0) {
		*type		= REG_SZ;
		r->string	= "C:\\PRINTERS";
		return  WERR_OK;
	} else if (strcmp("Architecture", value_name) == 0) {
		*type		= REG_SZ;
		r->string	= SPOOLSS_ARCHITECTURE_NT_X86;
		return  WERR_OK;
	} else if (strcmp("DsPresent", value_name) == 0) {
		*type		= REG_DWORD;
		r->value	= 1;
		return WERR_OK;
	} else if (strcmp("OSVersion", value_name) == 0) {
		DATA_BLOB blob;
		enum ndr_err_code ndr_err;
		struct spoolss_OSVersion os;

		os.major		= server_info->version_major;
		os.minor		= server_info->version_minor;
		os.build		= server_info->version_build;
		os.extra_string		= "";

		ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			return WERR_GENERAL_FAILURE;
		}

		*type		= REG_BINARY;
		r->binary	= blob;
		return WERR_OK;
	} else if (strcmp("OSVersionEx", value_name) == 0) {
		DATA_BLOB blob;
		enum ndr_err_code ndr_err;
		struct spoolss_OSVersionEx os_ex;

		os_ex.major		= server_info->version_major;
		os_ex.minor		= server_info->version_minor;
		os_ex.build		= server_info->version_build;
		os_ex.extra_string	= "";
		os_ex.service_pack_major= 0;
		os_ex.service_pack_minor= 0;
		os_ex.suite_mask	= 0;
		os_ex.product_type	= 0;
		os_ex.reserved		= 0;

		ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os_ex, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersionEx);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			return WERR_GENERAL_FAILURE;
		}

		*type		= REG_BINARY;
		r->binary	= blob;
		return WERR_OK;
	} else if (strcmp("DNSMachineName", value_name) == 0) {
		const char *dnsdomain = lpcfg_dnsdomain(server->ntptr->lp_ctx);

		if (dnsdomain == NULL) return WERR_INVALID_PARAM;

		*type		= REG_SZ;
		r->string	= talloc_asprintf(mem_ctx, "%s.%s",
							  lpcfg_netbios_name(server->ntptr->lp_ctx),
							  dnsdomain);
		W_ERROR_HAVE_NO_MEMORY(r->string);
		return WERR_OK;
	}

	return WERR_INVALID_PARAM;
}
Example #22
0
static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mode, 
					 struct loadparm_context *lp_ctx,
					 char *buf, int length, void **private1,
					 unsigned int mux_id, void **private2) 
{
	char *request, *parameter;	
	static DATA_BLOB challenge;
	static DATA_BLOB lm_response;
	static DATA_BLOB nt_response;
	static char *full_username;
	static char *username;
	static char *domain;
	static char *plaintext_password;
	static bool ntlm_server_1_user_session_key;
	static bool ntlm_server_1_lm_session_key;
	
	if (strequal(buf, ".")) {
		if (!full_username && !username) {	
			mux_printf(mux_id, "Error: No username supplied!\n");
		} else if (plaintext_password) {
			/* handle this request as plaintext */
			if (!full_username) {
				if (asprintf(&full_username, "%s%c%s", domain, *lpcfg_winbind_separator(lp_ctx), username) < 0) {
					mux_printf(mux_id, "Error: Out of memory in asprintf!\n.\n");
					return;
				}
			}
			if (check_plaintext_auth(full_username, plaintext_password, false)) {
				mux_printf(mux_id, "Authenticated: Yes\n");
			} else {
				mux_printf(mux_id, "Authenticated: No\n");
			}
		} else if (!lm_response.data && !nt_response.data) {
			mux_printf(mux_id, "Error: No password supplied!\n");
		} else if (!challenge.data) {	
			mux_printf(mux_id, "Error: No lanman-challenge supplied!\n");
		} else {
			char *error_string = NULL;
			DATA_BLOB lm_key;
			DATA_BLOB user_session_key;
			uint32_t flags = 0;

			if (full_username && !username) {
				SAFE_FREE(username);
				SAFE_FREE(domain);
				if (!parse_ntlm_auth_domain_user(full_username, &username, 
												 &domain, 
												 *lpcfg_winbind_separator(lp_ctx))) {
					/* username might be 'tainted', don't print into our new-line deleimianted stream */
					mux_printf(mux_id, "Error: Could not parse into domain and username\n");
				}
			}

			if (!domain) {
				domain = smb_xstrdup(lpcfg_workgroup(lp_ctx));
			}

			if (ntlm_server_1_lm_session_key) 
				flags |= NTLM_AUTH_FLAG_LMKEY;
			
			if (ntlm_server_1_user_session_key) 
				flags |= NTLM_AUTH_FLAG_USER_SESSION_KEY;

			if (!NT_STATUS_IS_OK(
				    local_pw_check_specified(lp_ctx,
							     username, 
							      domain, 
							      lpcfg_netbios_name(lp_ctx),
							      &challenge, 
							      &lm_response, 
							      &nt_response, 
							      flags, 
							      &lm_key, 
							      &user_session_key,
							      &error_string,
							      NULL))) {

				mux_printf(mux_id, "Authenticated: No\n");
				mux_printf(mux_id, "Authentication-Error: %s\n.\n", error_string);
				SAFE_FREE(error_string);
			} else {
				static char zeros[16];
				char *hex_lm_key;
				char *hex_user_session_key;

				mux_printf(mux_id, "Authenticated: Yes\n");

				if (ntlm_server_1_lm_session_key 
				    && lm_key.length 
				    && (memcmp(zeros, lm_key.data, 
								lm_key.length) != 0)) {
					hex_encode(lm_key.data,
						   lm_key.length,
						   &hex_lm_key);
					mux_printf(mux_id, "LANMAN-Session-Key: %s\n", hex_lm_key);
					SAFE_FREE(hex_lm_key);
				}

				if (ntlm_server_1_user_session_key 
				    && user_session_key.length 
				    && (memcmp(zeros, user_session_key.data, 
					       user_session_key.length) != 0)) {
					hex_encode(user_session_key.data, 
						   user_session_key.length, 
						   &hex_user_session_key);
					mux_printf(mux_id, "User-Session-Key: %s\n", hex_user_session_key);
					SAFE_FREE(hex_user_session_key);
				}
			}
		}
		/* clear out the state */
		challenge = data_blob(NULL, 0);
		nt_response = data_blob(NULL, 0);
		lm_response = data_blob(NULL, 0);
		SAFE_FREE(full_username);
		SAFE_FREE(username);
		SAFE_FREE(domain);
		SAFE_FREE(plaintext_password);
		ntlm_server_1_user_session_key = false;
		ntlm_server_1_lm_session_key = false;
		mux_printf(mux_id, ".\n");

		return;
	}

	request = buf;

	/* Indicates a base64 encoded structure */
	parameter = strstr(request, ":: ");
	if (!parameter) {
		parameter = strstr(request, ": ");
		
		if (!parameter) {
			DEBUG(0, ("Parameter not found!\n"));
			mux_printf(mux_id, "Error: Parameter not found!\n.\n");
			return;
		}
		
		parameter[0] ='\0';
		parameter++;
		parameter[0] ='\0';
		parameter++;

	} else {
		parameter[0] ='\0';
		parameter++;
		parameter[0] ='\0';
		parameter++;
		parameter[0] ='\0';
		parameter++;

		base64_decode_inplace(parameter);
	}

	if (strequal(request, "LANMAN-Challenge")) {
		challenge = strhex_to_data_blob(NULL, parameter);
		if (challenge.length != 8) {
			mux_printf(mux_id, "Error: hex decode of %s failed! (got %d bytes, expected 8)\n.\n", 
				  parameter,
				  (int)challenge.length);
			challenge = data_blob(NULL, 0);
		}
	} else if (strequal(request, "NT-Response")) {
		nt_response = strhex_to_data_blob(NULL, parameter);
		if (nt_response.length < 24) {
			mux_printf(mux_id, "Error: hex decode of %s failed! (only got %d bytes, needed at least 24)\n.\n", 
				  parameter,
				  (int)nt_response.length);
			nt_response = data_blob(NULL, 0);
		}
	} else if (strequal(request, "LANMAN-Response")) {
		lm_response = strhex_to_data_blob(NULL, parameter);
		if (lm_response.length != 24) {
			mux_printf(mux_id, "Error: hex decode of %s failed! (got %d bytes, expected 24)\n.\n", 
				  parameter,
				  (int)lm_response.length);
			lm_response = data_blob(NULL, 0);
		}
	} else if (strequal(request, "Password")) {
		plaintext_password = smb_xstrdup(parameter);
	} else if (strequal(request, "NT-Domain")) {
		domain = smb_xstrdup(parameter);
	} else if (strequal(request, "Username")) {
		username = smb_xstrdup(parameter);
	} else if (strequal(request, "Full-Username")) {
		full_username = smb_xstrdup(parameter);
	} else if (strequal(request, "Request-User-Session-Key")) {
		ntlm_server_1_user_session_key = strequal(parameter, "Yes");
	} else if (strequal(request, "Request-LanMan-Session-Key")) {
		ntlm_server_1_lm_session_key = strequal(parameter, "Yes");
	} else {
		mux_printf(mux_id, "Error: Unknown request %s\n.\n", request);
	}
}
Example #23
0
/**
 * Start NTLMSSP on the server side
 *
 */
NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
{
	NTSTATUS nt_status;
	struct ntlmssp_state *ntlmssp_state;
	struct gensec_ntlmssp_context *gensec_ntlmssp;
	const char *netbios_name;
	const char *netbios_domain;
	const char *dns_name;
	const char *dns_domain;
	enum server_role role;

	role = lpcfg_server_role(gensec_security->settings->lp_ctx);

	nt_status = gensec_ntlmssp_start(gensec_security);
	NT_STATUS_NOT_OK_RETURN(nt_status);

	gensec_ntlmssp =
		talloc_get_type_abort(gensec_security->private_data,
				      struct gensec_ntlmssp_context);

	ntlmssp_state = talloc_zero(gensec_ntlmssp,
				    struct ntlmssp_state);
	if (!ntlmssp_state) {
		return NT_STATUS_NO_MEMORY;
	}
	gensec_ntlmssp->ntlmssp_state = ntlmssp_state;

	ntlmssp_state->role = NTLMSSP_SERVER;

	ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;

	ntlmssp_state->allow_lm_response =
		lpcfg_lanman_auth(gensec_security->settings->lp_ctx);

	if (ntlmssp_state->allow_lm_response &&
	    gensec_setting_bool(gensec_security->settings,
				"ntlmssp_server", "allow_lm_key", false))
	{
		ntlmssp_state->allow_lm_key = true;
	}

	ntlmssp_state->force_old_spnego = false;

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "force_old_spnego", false)) {
		/*
		 * For testing Windows 2000 mode
		 */
		ntlmssp_state->force_old_spnego = true;
	}

	ntlmssp_state->neg_flags =
		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION;

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
	}

	if (ntlmssp_state->allow_lm_key) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
	}

	/*
	 * We always allow NTLMSSP_NEGOTIATE_SIGN and NTLMSSP_NEGOTIATE_SEAL.
	 *
	 * These will be removed if the client doesn't want them.
	 */
	ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
	ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;

	if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
	}
	if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;

		if (gensec_security->want_features & GENSEC_FEATURE_LDAP_STYLE) {
			/*
			 * We need to handle NTLMSSP_NEGOTIATE_SIGN as
			 * NTLMSSP_NEGOTIATE_SEAL if GENSEC_FEATURE_LDAP_STYLE
			 * is requested.
			 */
			ntlmssp_state->force_wrap_seal = true;
		}
	}
	if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
	}

	if (role == ROLE_STANDALONE) {
		ntlmssp_state->server.is_standalone = true;
	} else {
		ntlmssp_state->server.is_standalone = false;
	}

	if (gensec_security->settings->server_netbios_name) {
		netbios_name = gensec_security->settings->server_netbios_name;
	} else {
		netbios_name = lpcfg_netbios_name(gensec_security->settings->lp_ctx);
	}

	if (gensec_security->settings->server_netbios_domain) {
		netbios_domain = gensec_security->settings->server_netbios_domain;
	} else {
		netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
	}

	if (gensec_security->settings->server_dns_name) {
		dns_name = gensec_security->settings->server_dns_name;
	} else {
		const char *dnsdomain = lpcfg_dnsdomain(gensec_security->settings->lp_ctx);
		char *lower_netbiosname;

		lower_netbiosname = strlower_talloc(ntlmssp_state, netbios_name);
		NT_STATUS_HAVE_NO_MEMORY(lower_netbiosname);

		/* Find out the DNS host name */
		if (dnsdomain && dnsdomain[0] != '\0') {
			dns_name = talloc_asprintf(ntlmssp_state, "%s.%s",
						   lower_netbiosname,
						   dnsdomain);
			talloc_free(lower_netbiosname);
			NT_STATUS_HAVE_NO_MEMORY(dns_name);
		} else {
			dns_name = lower_netbiosname;
		}
	}

	if (gensec_security->settings->server_dns_domain) {
		dns_domain = gensec_security->settings->server_dns_domain;
	} else {
		dns_domain = lpcfg_dnsdomain(gensec_security->settings->lp_ctx);
	}

	ntlmssp_state->server.netbios_name = talloc_strdup(ntlmssp_state, netbios_name);
	NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.netbios_name);

	ntlmssp_state->server.netbios_domain = talloc_strdup(ntlmssp_state, netbios_domain);
	NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.netbios_domain);

	ntlmssp_state->server.dns_name = talloc_strdup(ntlmssp_state, dns_name);
	NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_name);

	ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state, dns_domain);
	NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain);

	ntlmssp_state->neg_flags |= ntlmssp_state->required_flags;
	ntlmssp_state->conf_flags = ntlmssp_state->neg_flags;

	return NT_STATUS_OK;
}
Example #24
0
NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, 
			   enum auth_password_state to_state,
			   const struct auth_usersupplied_info *user_info_in,
			   const struct auth_usersupplied_info **user_info_encrypted)
{
	NTSTATUS nt_status;
	struct auth_usersupplied_info *user_info_temp;
	switch (to_state) {
	case AUTH_PASSWORD_RESPONSE:
		switch (user_info_in->password_state) {
		case AUTH_PASSWORD_PLAIN:
		{
			const struct auth_usersupplied_info *user_info_temp2;
			nt_status = encrypt_user_info(mem_ctx, auth_context, 
						      AUTH_PASSWORD_HASH, 
						      user_info_in, &user_info_temp2);
			if (!NT_STATUS_IS_OK(nt_status)) {
				return nt_status;
			}
			user_info_in = user_info_temp2;
			/* fall through */
		}
		case AUTH_PASSWORD_HASH:
		{
			uint8_t chal[8];
			DATA_BLOB chall_blob;
			user_info_temp = talloc_zero(mem_ctx, struct auth_usersupplied_info);
			if (!user_info_temp) {
				return NT_STATUS_NO_MEMORY;
			}
			if (!talloc_reference(user_info_temp, user_info_in)) {
				return NT_STATUS_NO_MEMORY;
			}
			*user_info_temp = *user_info_in;
			user_info_temp->mapped_state = to_state;
			
			nt_status = auth_get_challenge(auth_context, chal);
			if (!NT_STATUS_IS_OK(nt_status)) {
				return nt_status;
			}
			
			chall_blob = data_blob_talloc(mem_ctx, chal, 8);
			if (lpcfg_client_ntlmv2_auth(auth_context->lp_ctx)) {
				DATA_BLOB names_blob = NTLMv2_generate_names_blob(mem_ctx,  lpcfg_netbios_name(auth_context->lp_ctx), lpcfg_workgroup(auth_context->lp_ctx));
				DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key, ntlmv2_session_key;
				
				if (!SMBNTLMv2encrypt_hash(user_info_temp,
							   user_info_in->client.account_name, 
							   user_info_in->client.domain_name, 
							   user_info_in->password.hash.nt->hash,
							   &chall_blob,
							   NULL, /* server_timestamp */
							   &names_blob,
							   &lmv2_response, &ntlmv2_response, 
							   &lmv2_session_key, &ntlmv2_session_key)) {
					data_blob_free(&names_blob);
					return NT_STATUS_NO_MEMORY;
				}
				data_blob_free(&names_blob);
				user_info_temp->password.response.lanman = lmv2_response;
				user_info_temp->password.response.nt = ntlmv2_response;
				
				data_blob_free(&lmv2_session_key);
				data_blob_free(&ntlmv2_session_key);
			} else {
				DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24);
				SMBOWFencrypt(user_info_in->password.hash.nt->hash, chal, blob.data);

				user_info_temp->password.response.nt = blob;
				if (lpcfg_client_lanman_auth(auth_context->lp_ctx) && user_info_in->password.hash.lanman) {
					DATA_BLOB lm_blob = data_blob_talloc(mem_ctx, NULL, 24);
					SMBOWFencrypt(user_info_in->password.hash.lanman->hash, chal, blob.data);
					user_info_temp->password.response.lanman = lm_blob;
				} else {
					/* if not sending the LM password, send the NT password twice */
					user_info_temp->password.response.lanman = user_info_temp->password.response.nt;
				}
			}

			user_info_in = user_info_temp;
			/* fall through */
		}
		case AUTH_PASSWORD_RESPONSE:
			*user_info_encrypted = user_info_in;
		}
		break;
	case AUTH_PASSWORD_HASH:
	{	
		switch (user_info_in->password_state) {
		case AUTH_PASSWORD_PLAIN:
		{
			struct samr_Password lanman;
			struct samr_Password nt;
			
			user_info_temp = talloc_zero(mem_ctx, struct auth_usersupplied_info);
			if (!user_info_temp) {
				return NT_STATUS_NO_MEMORY;
			}
			if (!talloc_reference(user_info_temp, user_info_in)) {
				return NT_STATUS_NO_MEMORY;
			}
			*user_info_temp = *user_info_in;
			user_info_temp->mapped_state = to_state;
			
			if (E_deshash(user_info_in->password.plaintext, lanman.hash)) {
				user_info_temp->password.hash.lanman = talloc(user_info_temp,
									      struct samr_Password);
				*user_info_temp->password.hash.lanman = lanman;
			} else {
				user_info_temp->password.hash.lanman = NULL;
			}
			
			E_md4hash(user_info_in->password.plaintext, nt.hash);
			user_info_temp->password.hash.nt = talloc(user_info_temp,
								   struct samr_Password);
			*user_info_temp->password.hash.nt = nt;
			
			user_info_in = user_info_temp;
			/* fall through */
		}
		case AUTH_PASSWORD_HASH:
			*user_info_encrypted = user_info_in;
			break;
		default:
			return NT_STATUS_INVALID_PARAMETER;
			break;
		}
		break;
	}
Example #25
0
/**
 * Start NTLMSSP on the server side 
 *
 */
NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
{
	NTSTATUS nt_status;
	struct ntlmssp_state *ntlmssp_state;
	struct gensec_ntlmssp_context *gensec_ntlmssp;

	nt_status = gensec_ntlmssp_start(gensec_security);
	NT_STATUS_NOT_OK_RETURN(nt_status);

	gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data,
					       struct gensec_ntlmssp_context);
	ntlmssp_state = gensec_ntlmssp->ntlmssp_state;

	ntlmssp_state->role = NTLMSSP_SERVER;

	ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;

	ntlmssp_state->allow_lm_key = (lpcfg_lanman_auth(gensec_security->settings->lp_ctx)
					  && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false));

	ntlmssp_state->neg_flags =
		NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION;

	ntlmssp_state->lm_resp = data_blob(NULL, 0);
	ntlmssp_state->nt_resp = data_blob(NULL, 0);

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
	}

	if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
	}

	if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
	}
	if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
	}

	ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
	ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
	ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
	ntlmssp_state->check_password = auth_ntlmssp_check_password;
	if (lpcfg_server_role(gensec_security->settings->lp_ctx) == ROLE_STANDALONE) {
		ntlmssp_state->server.is_standalone = true;
	} else {
		ntlmssp_state->server.is_standalone = false;
	}

	ntlmssp_state->server.netbios_name = lpcfg_netbios_name(gensec_security->settings->lp_ctx);

	ntlmssp_state->server.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);

	{
		const char *dnsdomain = lpcfg_dnsdomain(gensec_security->settings->lp_ctx);
		char *dnsname, *lower_netbiosname;
		lower_netbiosname = strlower_talloc(ntlmssp_state, ntlmssp_state->server.netbios_name);

		/* Find out the DNS host name */
		if (dnsdomain && dnsdomain[0] != '\0') {
			dnsname = talloc_asprintf(ntlmssp_state, "%s.%s",
						  lower_netbiosname,
						  dnsdomain);
			talloc_free(lower_netbiosname);
			ntlmssp_state->server.dns_name = dnsname;
		} else {
			ntlmssp_state->server.dns_name = lower_netbiosname;
		}

		NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_name);

		ntlmssp_state->server.dns_domain
			= talloc_strdup(ntlmssp_state,
					lpcfg_dnsdomain(gensec_security->settings->lp_ctx));
		NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain);
	}

	return NT_STATUS_OK;
}
Example #26
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 #27
0
_PUBLIC_ struct test_join *torture_join_domain(struct torture_context *tctx,
					       const char *machine_name, 
				      uint32_t acct_flags,
				      struct cli_credentials **machine_credentials)
{
	NTSTATUS status;
	struct libnet_context *libnet_ctx;
	struct libnet_JoinDomain *libnet_r;
	struct test_join *tj;
	struct samr_SetUserInfo s;
	union samr_UserInfo u;
	
	tj = talloc_zero(tctx, struct test_join);
	if (!tj) return NULL;

	libnet_r = talloc_zero(tj, struct libnet_JoinDomain);
	if (!libnet_r) {
		talloc_free(tj);
		return NULL;
	}
	
	libnet_ctx = libnet_context_init(tctx->ev, tctx->lp_ctx);
	if (!libnet_ctx) {
		talloc_free(tj);
		return NULL;
	}
	
	tj->libnet_r = libnet_r;
		
	libnet_ctx->cred = cmdline_credentials;
	libnet_r->in.binding = torture_setting_string(tctx, "binding", NULL);
	if (!libnet_r->in.binding) {
		libnet_r->in.binding = talloc_asprintf(libnet_r, "ncacn_np:%s", torture_setting_string(tctx, "host", NULL));
	}
	libnet_r->in.level = LIBNET_JOINDOMAIN_SPECIFIED;
	libnet_r->in.netbios_name = machine_name;
	libnet_r->in.account_name = talloc_asprintf(libnet_r, "%s$", machine_name);
	if (!libnet_r->in.account_name) {
		talloc_free(tj);
		return NULL;
	}
	
	libnet_r->in.acct_type = acct_flags;
	libnet_r->in.recreate_account = true;

	status = libnet_JoinDomain(libnet_ctx, libnet_r, libnet_r);
	if (!NT_STATUS_IS_OK(status)) {
		if (libnet_r->out.error_string) {
			DEBUG(0, ("Domain join failed - %s\n", libnet_r->out.error_string));
		} else {
			DEBUG(0, ("Domain join failed - %s\n", nt_errstr(status)));
		}
		talloc_free(tj);
                return NULL;
	}
	tj->p = libnet_r->out.samr_pipe;
	tj->user_handle = *libnet_r->out.user_handle;
	tj->dom_sid = libnet_r->out.domain_sid;
	talloc_steal(tj, libnet_r->out.domain_sid);
	tj->dom_netbios_name	= libnet_r->out.domain_name;
	talloc_steal(tj, libnet_r->out.domain_name);
	tj->dom_dns_name	= libnet_r->out.realm;
	talloc_steal(tj, libnet_r->out.realm);
	tj->user_guid = libnet_r->out.account_guid;
	tj->netbios_name = talloc_strdup(tj, machine_name);
	if (!tj->netbios_name) {
		talloc_free(tj);
		return NULL;
	}

	ZERO_STRUCT(u);
	s.in.user_handle = &tj->user_handle;
	s.in.info = &u;
	s.in.level = 21;

	u.info21.fields_present = SAMR_FIELD_DESCRIPTION | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME;
	u.info21.comment.string = talloc_asprintf(tj, 
						  "Tortured by Samba4: %s", 
						  timestring(tj, time(NULL)));
	u.info21.full_name.string = talloc_asprintf(tj, 
						    "Torture account for Samba4: %s", 
						    timestring(tj, time(NULL)));
	
	u.info21.description.string = talloc_asprintf(tj, 
						      "Samba4 torture account created by host %s: %s", 
						      lpcfg_netbios_name(tctx->lp_ctx), timestring(tj, time(NULL)));

	status = dcerpc_samr_SetUserInfo_r(tj->p->binding_handle, tj, &s);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo (non-critical) failed - %s\n", nt_errstr(status));
	}
	if (!NT_STATUS_IS_OK(s.out.result)) {
		printf("SetUserInfo (non-critical) failed - %s\n", nt_errstr(s.out.result));
	}

	*machine_credentials = cli_credentials_init(tj);
	cli_credentials_set_conf(*machine_credentials, tctx->lp_ctx);
	cli_credentials_set_workstation(*machine_credentials, machine_name, CRED_SPECIFIED);
	cli_credentials_set_domain(*machine_credentials, libnet_r->out.domain_name, CRED_SPECIFIED);
	if (libnet_r->out.realm) {
		cli_credentials_set_realm(*machine_credentials, libnet_r->out.realm, CRED_SPECIFIED);
	}
	cli_credentials_set_username(*machine_credentials, libnet_r->in.account_name, CRED_SPECIFIED);
	cli_credentials_set_password(*machine_credentials, libnet_r->out.join_password, CRED_SPECIFIED);
	cli_credentials_set_kvno(*machine_credentials, libnet_r->out.kvno);
	if (acct_flags & ACB_SVRTRUST) {
		cli_credentials_set_secure_channel_type(*machine_credentials,
							SEC_CHAN_BDC);
	} else if (acct_flags & ACB_WSTRUST) {
		cli_credentials_set_secure_channel_type(*machine_credentials,
							SEC_CHAN_WKSTA);
	} else {
		DEBUG(0, ("Invalid account type specificed to torture_join_domain\n"));
		talloc_free(*machine_credentials);
		return NULL;
	}

	return tj;
}
Example #28
0
struct test_join *torture_create_testuser_max_pwlen(struct torture_context *torture,
						    const char *username,
						    const char *domain,
						    uint16_t acct_type,
						    const char **random_password,
						    int max_pw_len)
{
	NTSTATUS status;
	struct samr_Connect c;
	struct samr_CreateUser2 r;
	struct samr_OpenDomain o;
	struct samr_LookupDomain l;
	struct dom_sid2 *sid = NULL;
	struct samr_GetUserPwInfo pwp;
	struct samr_PwInfo info;
	struct samr_SetUserInfo s;
	union samr_UserInfo u;
	struct policy_handle handle;
	uint32_t access_granted;
	uint32_t rid;
	DATA_BLOB session_key;
	struct lsa_String name;
	
	int policy_min_pw_len = 0;
	struct test_join *join;
	char *random_pw;
	const char *dc_binding = torture_setting_string(torture, "dc_binding", NULL);
	struct dcerpc_binding_handle *b = NULL;

	join = talloc(NULL, struct test_join);
	if (join == NULL) {
		return NULL;
	}

	ZERO_STRUCTP(join);

	printf("Connecting to SAMR\n");
	
	if (dc_binding) {
		status = dcerpc_pipe_connect(join,
					     &join->p,
					     dc_binding,
					     &ndr_table_samr,
					     cmdline_credentials, NULL, torture->lp_ctx);
					     
	} else {
		status = torture_rpc_connection(torture, 
						&join->p, 
						&ndr_table_samr);
	}
	if (!NT_STATUS_IS_OK(status)) {
		return NULL;
	}
	b = join->p->binding_handle;

	c.in.system_name = NULL;
	c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	c.out.connect_handle = &handle;

	status = dcerpc_samr_Connect_r(b, join, &c);
	if (!NT_STATUS_IS_OK(status)) {
		const char *errstr = nt_errstr(status);
		printf("samr_Connect failed - %s\n", errstr);
		return NULL;
	}
	if (!NT_STATUS_IS_OK(c.out.result)) {
		const char *errstr = nt_errstr(c.out.result);
		printf("samr_Connect failed - %s\n", errstr);
		return NULL;
	}

	if (domain) {
		printf("Opening domain %s\n", domain);

		name.string = domain;
		l.in.connect_handle = &handle;
		l.in.domain_name = &name;
		l.out.sid = &sid;

		status = dcerpc_samr_LookupDomain_r(b, join, &l);
		if (!NT_STATUS_IS_OK(status)) {
			printf("LookupDomain failed - %s\n", nt_errstr(status));
			goto failed;
		}
		if (!NT_STATUS_IS_OK(l.out.result)) {
			printf("LookupDomain failed - %s\n", nt_errstr(l.out.result));
			goto failed;
		}
	} else {
		struct samr_EnumDomains e;
		uint32_t resume_handle = 0, num_entries;
		struct samr_SamArray *sam;
		int i;

		e.in.connect_handle = &handle;
		e.in.buf_size = (uint32_t)-1;
		e.in.resume_handle = &resume_handle;
		e.out.sam = &sam;
		e.out.num_entries = &num_entries;
		e.out.resume_handle = &resume_handle;

		status = dcerpc_samr_EnumDomains_r(b, join, &e);
		if (!NT_STATUS_IS_OK(status)) {
			printf("EnumDomains failed - %s\n", nt_errstr(status));
			goto failed;
		}
		if (!NT_STATUS_IS_OK(e.out.result)) {
			printf("EnumDomains failed - %s\n", nt_errstr(e.out.result));
			goto failed;
		}
		if ((num_entries != 2) || (sam && sam->count != 2)) {
			printf("unexpected number of domains\n");
			goto failed;
		}
		for (i=0; i < 2; i++) {
			if (!strequal(sam->entries[i].name.string, "builtin")) {
				domain = sam->entries[i].name.string;
				break;
			}
		}
		if (domain) {
			printf("Opening domain %s\n", domain);

			name.string = domain;
			l.in.connect_handle = &handle;
			l.in.domain_name = &name;
			l.out.sid = &sid;

			status = dcerpc_samr_LookupDomain_r(b, join, &l);
			if (!NT_STATUS_IS_OK(status)) {
				printf("LookupDomain failed - %s\n", nt_errstr(status));
				goto failed;
			}
			if (!NT_STATUS_IS_OK(l.out.result)) {
				printf("LookupDomain failed - %s\n", nt_errstr(l.out.result));
				goto failed;
			}
		} else {
			printf("cannot proceed without domain name\n");
			goto failed;
		}
	}

	talloc_steal(join, *l.out.sid);
	join->dom_sid = *l.out.sid;
	join->dom_netbios_name = talloc_strdup(join, domain);
	if (!join->dom_netbios_name) goto failed;

	o.in.connect_handle = &handle;
	o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	o.in.sid = *l.out.sid;
	o.out.domain_handle = &join->domain_handle;

	status = dcerpc_samr_OpenDomain_r(b, join, &o);
	if (!NT_STATUS_IS_OK(status)) {
		printf("OpenDomain failed - %s\n", nt_errstr(status));
		goto failed;
	}
	if (!NT_STATUS_IS_OK(o.out.result)) {
		printf("OpenDomain failed - %s\n", nt_errstr(o.out.result));
		goto failed;
	}

	printf("Creating account %s\n", username);

again:
	name.string = username;
	r.in.domain_handle = &join->domain_handle;
	r.in.account_name = &name;
	r.in.acct_flags = acct_type;
	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
	r.out.user_handle = &join->user_handle;
	r.out.access_granted = &access_granted;
	r.out.rid = &rid;

	status = dcerpc_samr_CreateUser2_r(b, join, &r);
	if (!NT_STATUS_IS_OK(status)) {
		printf("CreateUser2 failed - %s\n", nt_errstr(status));
		goto failed;
	}

	if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_USER_EXISTS)) {
		status = DeleteUser_byname(b, join, &join->domain_handle, name.string);
		if (NT_STATUS_IS_OK(status)) {
			goto again;
		}
	}

	if (!NT_STATUS_IS_OK(r.out.result)) {
		printf("CreateUser2 failed - %s\n", nt_errstr(r.out.result));
		goto failed;
	}

	join->user_sid = dom_sid_add_rid(join, join->dom_sid, rid);

	pwp.in.user_handle = &join->user_handle;
	pwp.out.info = &info;

	status = dcerpc_samr_GetUserPwInfo_r(b, join, &pwp);
	if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(pwp.out.result)) {
		policy_min_pw_len = pwp.out.info->min_password_length;
	}

	random_pw = generate_random_password(join, MAX(8, policy_min_pw_len), max_pw_len);

	printf("Setting account password '%s'\n", random_pw);

	ZERO_STRUCT(u);
	s.in.user_handle = &join->user_handle;
	s.in.info = &u;
	s.in.level = 24;

	encode_pw_buffer(u.info24.password.data, random_pw, STR_UNICODE);
	u.info24.password_expired = 0;

	status = dcerpc_fetch_session_key(join->p, &session_key);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo level %u - no session key - %s\n",
		       s.in.level, nt_errstr(status));
		torture_leave_domain(torture, join);
		goto failed;
	}

	arcfour_crypt_blob(u.info24.password.data, 516, &session_key);

	status = dcerpc_samr_SetUserInfo_r(b, join, &s);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo failed - %s\n", nt_errstr(status));
		goto failed;
	}
	if (!NT_STATUS_IS_OK(s.out.result)) {
		printf("SetUserInfo failed - %s\n", nt_errstr(s.out.result));
		goto failed;
	}

	ZERO_STRUCT(u);
	s.in.user_handle = &join->user_handle;
	s.in.info = &u;
	s.in.level = 21;

	u.info21.acct_flags = acct_type | ACB_PWNOEXP;
	u.info21.fields_present = SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_DESCRIPTION | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME;

	u.info21.comment.string = talloc_asprintf(join, 
						  "Tortured by Samba4: %s", 
						  timestring(join, time(NULL)));
	
	u.info21.full_name.string = talloc_asprintf(join, 
						    "Torture account for Samba4: %s", 
						    timestring(join, time(NULL)));
	
	u.info21.description.string = talloc_asprintf(join, 
					 "Samba4 torture account created by host %s: %s", 
					 lpcfg_netbios_name(torture->lp_ctx),
					 timestring(join, time(NULL)));

	printf("Resetting ACB flags, force pw change time\n");

	status = dcerpc_samr_SetUserInfo_r(b, join, &s);
	if (!NT_STATUS_IS_OK(status)) {
		printf("SetUserInfo failed - %s\n", nt_errstr(status));
		goto failed;
	}
	if (!NT_STATUS_IS_OK(s.out.result)) {
		printf("SetUserInfo failed - %s\n", nt_errstr(s.out.result));
		goto failed;
	}

	if (random_password) {
		*random_password = random_pw;
	}

	return join;

failed:
	torture_leave_domain(torture, join);
	return NULL;
}
Example #29
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 #30
0
static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx,
						 TALLOC_CTX *mem_ctx,
						 const struct auth_usersupplied_info *user_info, 
						 struct auth_user_info_dc **user_info_dc)
{
	NTSTATUS nt_status;
	const char *account_name = user_info->mapped.account_name;
	struct ldb_message *msg;
	struct ldb_dn *domain_dn;
	DATA_BLOB user_sess_key, lm_sess_key;
	TALLOC_CTX *tmp_ctx;

	if (ctx->auth_ctx->sam_ctx == NULL) {
		DEBUG(0, ("No SAM available, cannot log in users\n"));
		return NT_STATUS_INVALID_SYSTEM_SERVICE;
	}

	if (!account_name || !*account_name) {
		/* 'not for me' */
		return NT_STATUS_NOT_IMPLEMENTED;
	}

	tmp_ctx = talloc_new(mem_ctx);
	if (!tmp_ctx) {
		return NT_STATUS_NO_MEMORY;
	}

	domain_dn = ldb_get_default_basedn(ctx->auth_ctx->sam_ctx);
	if (domain_dn == NULL) {
		talloc_free(tmp_ctx);
		return NT_STATUS_NO_SUCH_DOMAIN;
	}

	nt_status = authsam_search_account(tmp_ctx, ctx->auth_ctx->sam_ctx, account_name, domain_dn, &msg);
	if (!NT_STATUS_IS_OK(nt_status)) {
		talloc_free(tmp_ctx);
		return nt_status;
	}

	nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, ctx->auth_ctx->sam_ctx, domain_dn, msg, user_info,
					 &user_sess_key, &lm_sess_key);
	if (!NT_STATUS_IS_OK(nt_status)) {
		talloc_free(tmp_ctx);
		return nt_status;
	}

	nt_status = authsam_make_user_info_dc(tmp_ctx, ctx->auth_ctx->sam_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx),
					     lpcfg_sam_name(ctx->auth_ctx->lp_ctx),
					     domain_dn,
					     msg,
					     user_sess_key, lm_sess_key,
					     user_info_dc);
	if (!NT_STATUS_IS_OK(nt_status)) {
		talloc_free(tmp_ctx);
		return nt_status;
	}

	talloc_steal(mem_ctx, *user_info_dc);
	talloc_free(tmp_ctx);

	return NT_STATUS_OK;
}