Example #1
0
static uint32_t
spoolss_make_sd(ndr_xa_t *mxa, spoolss_sd_t *secdesc)
{
	smb_sd_t	sd;
	uint8_t		*sd_buf;
	uint32_t	sd_len;
	uint32_t	status;

	bzero(&sd, sizeof (smb_sd_t));

	if ((status = spoolss_format_sd(&sd)) != ERROR_SUCCESS)
		return (status);

	sd_len = smb_sd_len(&sd, SMB_ALL_SECINFO);

	if ((sd_buf = NDR_MALLOC(mxa, sd_len)) == NULL)
		return (ERROR_NOT_ENOUGH_MEMORY);

	secdesc->sd_buf = sd_buf;
	secdesc->sd_size = sd_len;

	status = srvsvc_sd_set_relative(&sd, sd_buf);
	smb_sd_term(&sd);
	return (status);
}
Example #2
0
/*
 * lsarpc_s_QueryInfoPolicy
 *
 * This is the server side function for handling LSA information policy
 * queries. Currently, we only support primary domain and account
 * domain queries. This is just a front end to switch on the request
 * and hand it off to the appropriate function to actually deal with
 * obtaining and building the response.
 */
static int
lsarpc_s_QueryInfoPolicy(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_QueryInfoPolicy *param = arg;
	union mslsa_PolicyInfoResUnion *ru = &param->ru;
	int security_mode;
	DWORD status;

	param->switch_value = param->info_class;

	switch (param->info_class) {
	case MSLSA_POLICY_AUDIT_EVENTS_INFO:
		ru->audit_events.enabled = 0;
		ru->audit_events.count = 1;
		ru->audit_events.settings
		    = NDR_MALLOC(mxa, sizeof (DWORD));
		bzero(ru->audit_events.settings, sizeof (DWORD));
		status = NT_STATUS_SUCCESS;
		break;

	case MSLSA_POLICY_PRIMARY_DOMAIN_INFO:
		status = lsarpc_s_PrimaryDomainInfo(&ru->pd_info, mxa);
		break;

	case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO:
		status = lsarpc_s_AccountDomainInfo(&ru->ad_info, mxa);
		break;

	case MSLSA_POLICY_SERVER_ROLE_INFO:
		security_mode = smb_config_get_secmode();

		if (security_mode == SMB_SECMODE_DOMAIN)
			ru->server_role.role = LSA_ROLE_MEMBER_SERVER;
		else
			ru->server_role.role = LSA_ROLE_STANDALONE_SERVER;

		ru->server_role.pad = 0;
		status = NT_STATUS_SUCCESS;
		break;

	default:
		bzero(param, sizeof (struct mslsa_QueryInfoPolicy));
		param->status = NT_SC_ERROR(NT_STATUS_INVALID_INFO_CLASS);
		return (NDR_DRC_OK);
	}

	if (status != NT_STATUS_SUCCESS)
		param->status = NT_SC_ERROR(status);
	else
		param->status = NT_STATUS_SUCCESS;
	param->address = (DWORD)(uintptr_t)ru;

	return (NDR_DRC_OK);
}
Example #3
0
int
spoolss_s_GetPrinter(void *arg, ndr_xa_t *mxa)
{
	struct spoolss_GetPrinter	*param = arg;
	struct spoolss_GetPrinter0	*pinfo0;
	struct spoolss_GetPrinter1	*pinfo1;
	struct spoolss_GetPrinter2	*pinfo2;
	struct spoolss_DeviceMode	*devmode2;
	ndr_hdid_t	*id = (ndr_hdid_t *)&param->handle;
	spoolss_sd_t	secdesc;
	char		server[MAXNAMELEN];
	char		printer[MAXNAMELEN];
	DWORD		status = ERROR_SUCCESS;
	char		*wname;
	uint32_t	offset;
	uint8_t		*tmpbuf;

	if (ndr_hdlookup(mxa, id) == NULL) {
		status = ERROR_INVALID_HANDLE;
		goto error_out;
	}

	if (spoolss_getservername(server, MAXNAMELEN) != 0) {
		status = ERROR_INTERNAL_ERROR;
		goto error_out;
	}

	(void) snprintf(printer, MAXNAMELEN, "%s\\%s", server, SPOOLSS_PRINTER);

	switch (param->switch_value) {
	case 0:
	case 1:
		param->needed = 460;
		break;
	case 2:
		param->needed = 712;
		break;
	default:
		status = ERROR_INVALID_LEVEL;
		goto error_out;
	}

	if (param->BufCount < param->needed) {
		param->BufCount = 0;
		param->Buf = NULL;
		param->status = ERROR_INSUFFICIENT_BUFFER;
		return (NDR_DRC_OK);
	}

	if ((param->Buf = NDR_MALLOC(mxa, param->BufCount)) == NULL) {
		status = ERROR_NOT_ENOUGH_MEMORY;
		goto error_out;
	}

	bzero(param->Buf, param->BufCount);
	wname = (char *)param->Buf;
	offset = param->needed;

	switch (param->switch_value) {
	case 0:
		/*LINTED E_BAD_PTR_CAST_ALIGN*/
		pinfo0 = (struct spoolss_GetPrinter0 *)param->Buf;

		smb_rpc_off(wname, server, &offset, &pinfo0->servername);
		smb_rpc_off(wname, printer, &offset, &pinfo0->printername);
		pinfo0->cjobs = 0;
		pinfo0->total_jobs = 6;
		pinfo0->total_bytes = 1040771;
		pinfo0->time0 = 0;
		pinfo0->time1 = 0;
		pinfo0->time2 = 3;
		pinfo0->time3 = 0;
		pinfo0->global_counter = 2162710;
		pinfo0->total_pages = 21495865;
		pinfo0->version = 10;
		pinfo0->session_counter = 1;
		pinfo0->job_error = 0x6;
		pinfo0->change_id  = 0x1;
		pinfo0->status = 0;
		pinfo0->c_setprinter = 0;
		break;
	case 1:
		/*LINTED E_BAD_PTR_CAST_ALIGN*/
		pinfo1 = (struct spoolss_GetPrinter1 *)param->Buf;

		pinfo1->flags = PRINTER_ENUM_ICON8;
		smb_rpc_off(wname, printer, &offset, &pinfo1->flags);
		smb_rpc_off(wname, printer, &offset, &pinfo1->description);
		smb_rpc_off(wname, printer, &offset, &pinfo1->comment);
		break;
	case 2:
		/*LINTED E_BAD_PTR_CAST_ALIGN*/
		pinfo2 = (struct spoolss_GetPrinter2 *)param->Buf;

		smb_rpc_off(wname, server, &offset, &pinfo2->servername);
		smb_rpc_off(wname, printer, &offset, &pinfo2->printername);
		smb_rpc_off(wname, SPOOLSS_PRINTER, &offset,
		    &pinfo2->sharename);
		smb_rpc_off(wname, "CIFS Printer Port", &offset,
		    &pinfo2->portname);
		smb_rpc_off(wname, "", &offset, &pinfo2->drivername);
		smb_rpc_off(wname, SPOOLSS_PRINTER, &offset,
		    &pinfo2->comment);
		smb_rpc_off(wname, "farside", &offset, &pinfo2->location);

		offset -= sizeof (struct spoolss_DeviceMode);
		pinfo2->devmode = offset;
		/*LINTED E_BAD_PTR_CAST_ALIGN*/
		devmode2 = (struct spoolss_DeviceMode *)(param->Buf + offset);

		smb_rpc_off(wname, "farside", &offset, &pinfo2->sepfile);
		smb_rpc_off(wname, "winprint", &offset,
		    &pinfo2->printprocessor);
		smb_rpc_off(wname, "RAW", &offset, &pinfo2->datatype);
		smb_rpc_off(wname, "", &offset, &pinfo2->parameters);

		status = spoolss_make_sd(mxa, &secdesc);
		if (status == ERROR_SUCCESS) {
			offset -= secdesc.sd_size;
			pinfo2->secdesc = offset;
			tmpbuf = (uint8_t *)(param->Buf + offset);
			bcopy(secdesc.sd_buf, tmpbuf, secdesc.sd_size);
		}

		pinfo2->attributes = 0x00001048;
		pinfo2->status = 0x00000000;
		pinfo2->starttime = 0;
		pinfo2->untiltime = 0;
		pinfo2->cjobs = 0;
		pinfo2->averageppm = 0;
		pinfo2->defaultpriority = 0;

		/*LINTED E_BAD_PTR_CAST_ALIGN*/
		(void) smb_mbstowcs((smb_wchar_t *)devmode2->devicename,
		    printer, 32);
		devmode2->specversion = 0x0401;
		devmode2->driverversion = 1024;
		devmode2->size = 220;
		devmode2->driverextra_length = 0;
		devmode2->fields = 0x00014713;
		devmode2->orientation = 1;
		devmode2->papersize = 1;
		devmode2->paperlength = 0;
		devmode2->paperwidth = 0;
		devmode2->scale = 100;
		devmode2->copies = 1;
		devmode2->defaultsource = 15;
		devmode2->printquality = 65532;
		devmode2->color = 1;
		devmode2->duplex = 1;
		devmode2->yresolution = 1;
		devmode2->ttoption = 1;
		devmode2->collate = 0;
		/*LINTED E_BAD_PTR_CAST_ALIGN*/
		(void) smb_mbstowcs((smb_wchar_t *)devmode2->formname,
		    "Letter", 32);
		devmode2->logpixels = 0;
		devmode2->bitsperpel = 0;
		devmode2->pelswidth = 0;
		devmode2->pelsheight = 0;
		devmode2->displayflags = 0;
		devmode2->displayfrequency = 0;
		devmode2->icmmethod = 0;
		devmode2->icmintent = 0;
		devmode2->mediatype = 0;
		devmode2->dithertype = 0;
		devmode2->reserved1 = 0;
		devmode2->reserved2 = 0;
		devmode2->panningwidth = 0;
		devmode2->panningheight = 0;
		break;

	default:
		break;
	}

	param->status = status;
	return (NDR_DRC_OK);

error_out:
	smb_tracef("spoolss_s_GetPrinter: error %u", status);
	bzero(param, sizeof (struct spoolss_GetPrinter));
	param->status = status;
	return (NDR_DRC_OK);
}
Example #4
0
/*
 * GetPrinterData is used t obtain values from the registry for a
 * printer or a print server.  See [MS-RPRN] for value descriptions.
 * The registry returns ERROR_FILE_NOT_FOUND for unknown keys.
 */
static int
spoolss_s_GetPrinterData(void *arg, ndr_xa_t *mxa)
{
	static spoolss_winreg_t	reg[] = {
		{ "ChangeId",			0x0050acf2 },
		{ "W3SvcInstalled",		0x00000000 },
		{ "BeepEnabled",		0x00000000 },
		{ "EventLog",			0x0000001f },
		{ "NetPopup",			0x00000000 },
		{ "NetPopupToComputer",		0x00000000 },
		{ "MajorVersion",		0x00000003 },
		{ "MinorVersion",		0x00000000 },
		{ "DsPresent",			0x00000000 }
	};

	struct spoolss_GetPrinterData *param = arg;
	char			*name = (char *)param->pValueName;
	char			buf[MAXPATHLEN];
	static uint8_t		reserved_buf[4];
	spoolss_winreg_t	*rp;
	smb_share_t		si;
	smb_version_t		*osversion;
	struct utsname		sysname;
	smb_wchar_t		*wcs;
	uint32_t		value;
	uint32_t		status;
	int			wcslen;
	int			i;

	if (name == NULL || *name == '\0') {
		status = ERROR_FILE_NOT_FOUND;
		goto report_error;
	}

	for (i = 0; i < sizeof (reg) / sizeof (reg[0]); ++i) {
		param->pType = WINREG_DWORD;
		param->Needed = sizeof (uint32_t);
		rp = &reg[i];

		if (strcasecmp(name, rp->name) != 0)
			continue;

		if (param->Size < sizeof (uint32_t)) {
			param->Size = 0;
			goto need_more_data;
		}

		if ((param->Buf = NDR_NEW(mxa, uint32_t)) == NULL) {
			status = ERROR_NOT_ENOUGH_MEMORY;
			goto report_error;
		}

		value = rp->value;

		if ((strcasecmp(name, "DsPresent") == 0) &&
		    (smb_config_get_secmode() == SMB_SECMODE_DOMAIN))
			value = 0x00000001;

		bcopy(&value, param->Buf, sizeof (uint32_t));
		param->Size = sizeof (uint32_t);
		param->status = ERROR_SUCCESS;
		return (NDR_DRC_OK);
	}

	if (strcasecmp(name, "OSVersion") == 0) {
		param->pType = WINREG_BINARY;
		param->Needed = sizeof (smb_version_t);

		if (param->Size < sizeof (smb_version_t)) {
			param->Size = sizeof (smb_version_t);
			goto need_more_data;
		}

		if ((osversion = NDR_NEW(mxa, smb_version_t)) == NULL) {
			status = ERROR_NOT_ENOUGH_MEMORY;
			goto report_error;
		}

		smb_config_get_version(osversion);
		param->Buf = (uint8_t *)osversion;
		param->status = ERROR_SUCCESS;
		return (NDR_DRC_OK);
	}

	if (strcasecmp(name, "DNSMachineName") == 0) {
		param->pType = WINREG_SZ;
		buf[0] = '\0';
		(void) smb_getfqhostname(buf, MAXHOSTNAMELEN);
		goto encode_string;
	}

	if (strcasecmp(name, "DefaultSpoolDirectory") == 0) {
		param->pType = WINREG_SZ;
		buf[0] = '\0';

		if (smb_shr_get(SMB_SHARE_PRINT, &si) != NERR_Success) {
			status = ERROR_FILE_NOT_FOUND;
			goto report_error;
		}

		(void) snprintf(buf, MAXPATHLEN, "C:/%s", si.shr_path);
		(void) strcanon(buf, "/\\");
		(void) strsubst(buf, '/', '\\');
		goto encode_string;
	}

	if (strcasecmp(name, "Architecture") == 0) {
		param->pType = WINREG_SZ;

		if (uname(&sysname) < 0)
			(void) strlcpy(buf, "Solaris", MAXPATHLEN);
		else
			(void) snprintf(buf, MAXPATHLEN, "%s %s",
			    sysname.sysname, sysname.machine);

		goto encode_string;
	}

	status = ERROR_FILE_NOT_FOUND;

report_error:
	bzero(param, sizeof (struct spoolss_GetPrinterData));
	param->Buf = reserved_buf;
	param->status = status;
	return (NDR_DRC_OK);

encode_string:
	wcslen = smb_wcequiv_strlen(buf) + sizeof (smb_wchar_t);
	if (param->Size < wcslen) {
		param->Needed = wcslen;
		goto need_more_data;
	}

	if ((wcs = NDR_MALLOC(mxa, wcslen)) == NULL) {
		status = ERROR_NOT_ENOUGH_MEMORY;
		goto report_error;
	}

	(void) ndr_mbstowcs(NULL, wcs, buf, wcslen);
	param->Buf = (uint8_t *)wcs;
	param->Needed = wcslen;
	param->status = ERROR_SUCCESS;
	return (NDR_DRC_OK);

need_more_data:
	param->Size = 0;
	param->Buf = reserved_buf;
	param->status = ERROR_MORE_DATA;
	return (NDR_DRC_OK);
}