示例#1
0
/*
 * Use the RPC context handle to find the fd and write the document content.
 */
static int
spoolss_s_WritePrinter(void *arg, ndr_xa_t *mxa)
{
	struct spoolss_WritePrinter *param = arg;
	int written = 0;
	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
	int spfd;

	if (ndr_hdlookup(mxa, id) == NULL) {
		param->written = 0;
		param->status = ERROR_INVALID_HANDLE;
		smb_tracef("spoolss_s_WritePrinter: invalid handle");
		return (NDR_DRC_OK);
	}

	if ((spfd = spoolss_find_document(id)) < 0) {
		param->written = 0;
		param->status = ERROR_INVALID_HANDLE;
		smb_tracef("spoolss_s_WritePrinter: document not found");
		return (NDR_DRC_OK);
	}

	written = write(spfd, param->pBuf, param->BufCount);
	if (written < param->BufCount) {
		smb_tracef("spoolss_s_WritePrinter: write failed");
		param->written = 0;
		param->status = ERROR_CANTWRITE;
		return (NDR_DRC_OK);
	}

	param->written = written;
	param->status = ERROR_SUCCESS;
	return (NDR_DRC_OK);
}
示例#2
0
static int
spoolss_s_DeleteForm(void *arg, ndr_xa_t *mxa)
{
	struct spoolss_DeleteForm *param = arg;
	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;

	if (ndr_hdlookup(mxa, id) == NULL) {
		bzero(param, sizeof (struct spoolss_DeleteForm));
		param->status = ERROR_INVALID_HANDLE;
		return (NDR_DRC_OK);
	}

	bzero(param, sizeof (struct spoolss_DeleteForm));
	param->status = ERROR_SUCCESS;
	return (NDR_DRC_OK);
}
示例#3
0
static int
spoolss_s_ClosePrinter(void *arg, ndr_xa_t *mxa)
{
	struct spoolss_ClosePrinter *param = arg;
	ndr_hdid_t	*id = (ndr_hdid_t *)&param->handle;
	ndr_handle_t	*hd;

	if ((hd = ndr_hdlookup(mxa, id)) != NULL) {
		free(hd->nh_data);
		hd->nh_data = NULL;
	}

	ndr_hdfree(mxa, id);
	bzero(&param->result_handle, sizeof (spoolss_handle_t));
	param->status = ERROR_SUCCESS;
	return (NDR_DRC_OK);
}
示例#4
0
static int
lsarpc_s_OpenSecret(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_OpenSecret *param = arg;
	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
	ndr_handle_t *hd;

	hd = ndr_hdlookup(mxa, id);
	if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) {
		bzero(param, sizeof (struct mslsa_OpenAccount));
		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
		return (NDR_DRC_OK);
	}

	bzero(&param->secret_handle, sizeof (mslsa_handle_t));
	param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
	return (NDR_DRC_OK);
}
示例#5
0
/*
 * Windows XP and 2000 use this mechanism to write spool files
 * Search the spooldoc list for a matching RPC handle and pass
 * the spool the file for printing.
 */
static int
spoolss_s_EndDocPrinter(void *arg, ndr_xa_t *mxa)
{
	struct spoolss_EndDocPrinter *param = arg;
	ndr_hdid_t	*id = (ndr_hdid_t *)&param->handle;
	smb_spooldoc_t	*sp;

	if (ndr_hdlookup(mxa, id) == NULL) {
		smb_tracef("spoolss_s_EndDocPrinter: invalid handle");
		param->status = ERROR_INVALID_HANDLE;
		return (NDR_DRC_OK);
	}

	param->status = ERROR_INVALID_HANDLE;
	(void) rw_wrlock(&spoolss_splist.sp_rwl);

	sp = list_head(&spoolss_splist.sp_list);
	while (sp != NULL) {
		if (!memcmp(id, &(sp->sd_handle), sizeof (ndr_hdid_t))) {
			spoolss_copyfile(&sp->sd_ipaddr,
			    sp->sd_username, sp->sd_path, sp->sd_doc_name);
			(void) close(sp->sd_fd);
			list_remove(&spoolss_splist.sp_list, sp);
			free(sp);
			param->status = ERROR_SUCCESS;
			break;
		}

		sp = list_next(&spoolss_splist.sp_list, sp);
	}

	(void) rw_unlock(&spoolss_splist.sp_rwl);

	if (param->status != ERROR_SUCCESS)
		smb_tracef("spoolss_s_EndDocPrinter: document not found");
	return (NDR_DRC_OK);
}
示例#6
0
/*
 * lsarpc_s_OpenAccount
 *
 * This is a request to open an account handle.
 */
static int
lsarpc_s_OpenAccount(void *arg, ndr_xa_t *mxa)
{
	struct mslsa_OpenAccount *param = arg;
	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
	ndr_handle_t *hd;

	hd = ndr_hdlookup(mxa, id);
	if ((hd == NULL) || (hd->nh_data != &lsarpc_key_domain)) {
		bzero(param, sizeof (struct mslsa_OpenAccount));
		param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
		return (NDR_DRC_OK);
	}

	if ((id = ndr_hdalloc(mxa, &lsarpc_key_account)) != NULL) {
		bcopy(id, &param->account_handle, sizeof (mslsa_handle_t));
		param->status = NT_STATUS_SUCCESS;
	} else {
		bzero(&param->account_handle, sizeof (mslsa_handle_t));
		param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
	}

	return (NDR_DRC_OK);
}
示例#7
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);
}
示例#8
0
/*
 * Windows XP and 2000 use this mechanism to write spool files.
 * Create a spool file fd to be used by spoolss_s_WritePrinter
 * and add it to the tail of the spool list.
 */
static int
spoolss_s_StartDocPrinter(void *arg, ndr_xa_t *mxa)
{
	struct spoolss_StartDocPrinter *param = arg;
	ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
	smb_spooldoc_t *spfile;
	spoolss_DocInfo_t *docinfo;
	char g_path[MAXPATHLEN];
	smb_share_t si;
	int rc;
	int fd;

	if (ndr_hdlookup(mxa, id) == NULL) {
		smb_tracef("spoolss_s_StartDocPrinter: invalid handle");
		param->status = ERROR_INVALID_HANDLE;
		return (NDR_DRC_OK);
	}

	if ((docinfo = param->dinfo.DocInfoContainer) == NULL) {
		param->status = ERROR_INVALID_PARAMETER;
		return (NDR_DRC_OK);
	}

	if ((rc = smb_shr_get(SMB_SHARE_PRINT, &si)) != NERR_Success) {
		smb_tracef("spoolss_s_StartDocPrinter: %s error=%d",
		    SMB_SHARE_PRINT, rc);
		param->status = rc;
		return (NDR_DRC_OK);
	}

	if ((spfile = calloc(1, sizeof (smb_spooldoc_t))) == NULL) {
		param->status = ERROR_NOT_ENOUGH_MEMORY;
		return (NDR_DRC_OK);
	}

	if (docinfo->doc_name != NULL)
		(void) strlcpy(spfile->sd_doc_name,
		    (char *)docinfo->doc_name, MAXNAMELEN);
	else
		(void) strlcpy(spfile->sd_doc_name, "document", MAXNAMELEN);

	if (docinfo->printer_name != NULL)
		(void) strlcpy(spfile->sd_printer_name,
		    (char *)docinfo->printer_name, MAXPATHLEN);
	else
		(void) strlcpy(spfile->sd_printer_name, "printer", MAXPATHLEN);

	spfile->sd_ipaddr = mxa->pipe->np_user->ui_ipaddr;
	(void) strlcpy((char *)spfile->sd_username,
	    mxa->pipe->np_user->ui_account, MAXNAMELEN);
	(void) memcpy(&spfile->sd_handle, &param->handle, sizeof (ndr_hdid_t));

	/*
	 *	write temporary spool file to print$
	 */
	(void) snprintf(g_path, MAXPATHLEN, "%s/%s%d", si.shr_path,
	    spfile->sd_username, spoolss_cnt);
	atomic_inc_32(&spoolss_cnt);

	fd = open(g_path, O_CREAT | O_RDWR, 0600);
	if (fd == -1) {
		smb_tracef("spoolss_s_StartDocPrinter: %s: %s",
		    g_path, strerror(errno));
		param->status = ERROR_OPEN_FAILED;
		free(spfile);
	} else {
		(void) strlcpy((char *)spfile->sd_path, g_path, MAXPATHLEN);
		spfile->sd_fd = (uint16_t)fd;

		/*
		 * Add the document to the spool list.
		 */
		(void) rw_wrlock(&spoolss_splist.sp_rwl);
		list_insert_tail(&spoolss_splist.sp_list, spfile);
		spoolss_splist.sp_cnt++;
		(void) rw_unlock(&spoolss_splist.sp_rwl);

		/*
		 * JobId isn't used now, but if printQ management is added
		 * this will have to be incremented per job submitted.
		 */
		param->JobId = 46;
		param->status = ERROR_SUCCESS;
	}
	return (NDR_DRC_OK);
}