char *svcname;
char *docname;
char *filename;
+ uint64_t offset;
+ struct rpc_pipe_client *spoolss_pipe;
struct policy_handle handle;
uint32_t jobid;
uint16_t rap_jobid;
lp_path(talloc_tos(),
SNUM(fsp->conn)),
PRINT_SPOOL_PREFIX);
+ pf->filename = talloc_asprintf(pf, "%s.raw", pf->docname);
if (!pf->filename) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
errno = 0;
mask = umask(S_IRWXO | S_IRWXG);
- fd = mkstemp(pf->filename);
+ fd = -1;// mkstemp(pf->filename);
umask(mask);
- if (fd == -1) {
- if (errno == EACCES) {
- /* Common setup error, force a report. */
- DEBUG(0, ("Insufficient permissions "
- "to open spool file %s.\n",
- pf->filename));
- } else {
- /* Normal case, report at level 3 and above. */
- DEBUG(3, ("can't open spool file %s,\n",
- pf->filename));
- DEBUGADD(3, ("errno = %d (%s).\n",
- errno, strerror(errno)));
- }
- status = map_nt_error_from_unix(errno);
- goto done;
- }
+ //if (fd == -1) {
+ // if (errno == EACCES) {
+ // /* Common setup error, force a report. */
+ // DEBUG(0, ("Insufficient permissions "
+ // "to open spool file %s.\n",
+ // pf->filename));
+ // } else {
+ // /* Normal case, report at level 3 and above. */
+ // DEBUG(3, ("can't open spool file %s,\n",
+ // pf->filename));
+ // DEBUGADD(3, ("errno = %d (%s).\n",
+ // errno, strerror(errno)));
+ // }
+ // status = map_nt_error_from_unix(errno);
+ // goto done;
+ //}
/* now open a document over spoolss so that it does
* all printer verification, and eventually assigns
fsp->conn->sconn->remote_address,
fsp->conn->sconn->local_address,
fsp->conn->sconn->msg_ctx,
- &fsp->conn->spoolss_pipe);
+ &pf->spoolss_pipe);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- b = fsp->conn->spoolss_pipe->binding_handle;
+ b = pf->spoolss_pipe->binding_handle;
ZERO_STRUCT(devmode_ctr);
goto done;
}
- if (sys_fstat(fd, &fsp->fsp_name->st, false) != 0) {
- status = map_nt_error_from_unix(errno);
- goto done;
- }
+ //if (sys_fstat(fd, &fsp->fsp_name->st, false) != 0) {
+ // status = map_nt_error_from_unix(errno);
+ // goto done;
+ //}
- fsp->file_id = vfs_file_id_from_sbuf(fsp->conn, &fsp->fsp_name->st);
- fsp->fh->fd = fd;
+ //fsp->file_id = vfs_file_id_from_sbuf(fsp->conn, &fsp->fsp_name->st);
+ //fsp->fh->fd = fd;
fsp->vuid = current_vuid;
fsp->can_lock = false;
if (pf && pf->jobid) {
print_spool_terminate(fsp->conn, pf);
}
+ TALLOC_FREE(pf);
}
talloc_free(tmp_ctx);
return status;
const char *data, uint32_t size,
off_t offset, uint32_t *written)
{
+ struct print_file_data *pf = fsp->print_file;
+ NTSTATUS status;
+ TALLOC_CTX *tmp_ctx = talloc_tos();
+ struct dcerpc_binding_handle *b = NULL;
+ DATA_BLOB buffer;
+ //int fd = -1;
+ WERROR werr;
SMB_STRUCT_STAT st;
ssize_t n;
int ret;
+ uint64_t remaining;
*written = 0;
+ if (pf == NULL) {
+ return EBADF;
+ }
+ if (pf->spoolss_pipe == NULL) {
+ return EBADF;
+ }
+ b = pf->spoolss_pipe->binding_handle;
+
+ /* When print files go beyond 4GB, the 32-bit offset sent in
+ * old SMBwrite calls is relative to the current 4GB chunk
+ * we're writing to.
+ * Discovered by Sebastian Kloska <oncaphillis@snafu.de>.
+ */
+ if (offset < 0xffffffff00000000LL) {
+ offset = (pf->offset & 0xffffffff00000000LL) + offset;
+ }
+
+ if ((uint64_t)offset != pf->offset) {
+ // TODO: check what windows does, with non sequential
+ // writes.
+ ret = EINVAL;
+ goto error;
+ }
+
+ remaining = UINT64_MAX - pf->offset;
+ if (size > remaining) {
+ ret = EINVAL;
+ goto error;
+ }
+
+ buffer = data_blob_const(data, size);
+
+ status = dcerpc_spoolss_WritePrinter(b, tmp_ctx,
+ &pf->handle,
+ buffer,
+ buffer.length,
+ written,
+ &werr);
+ if (!NT_STATUS_IS_OK(status)) {
+ ret = EINVAL;
+ goto error;
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ //status = werror_to_ntstatus(werr);
+ ret = EINVAL;
+ goto error;
+ }
+
+ if (*written > size) {
+ //status = NT_STATUS_INVALID_PARAMETER;
+ ret = EINVAL;
+ goto error;
+ }
+
+ pf->offset += *written;
+ return 0;
+error:
+ print_spool_terminate(fsp->conn, fsp->print_file);
+ return ret;
/* first of all stat file to find out if it is still there.
* spoolss may have deleted it to signal someone has killed
* the job through it's interface */
void print_spool_end(files_struct *fsp, enum file_close_type close_type)
{
+ struct print_file_data *pf = fsp->print_file;
NTSTATUS status;
WERROR werr;
struct dcerpc_binding_handle *b = NULL;
}
}
- b = fsp->conn->spoolss_pipe->binding_handle;
+ if (pf->spoolss_pipe == NULL) {
+ return;
+ }
+ b = pf->spoolss_pipe->binding_handle;
switch (close_type) {
case NORMAL_CLOSE:
print_spool_terminate(fsp->conn, fsp->print_file);
break;
}
+ TALLOC_FREE(fsp->print_file);
}
rap_jobid_delete(print_file->svcname, print_file->jobid);
- status = rpc_pipe_open_interface(conn,
- &ndr_table_spoolss,
- conn->session_info,
- conn->sconn->remote_address,
- conn->sconn->local_address,
- conn->sconn->msg_ctx,
- &conn->spoolss_pipe);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("print_spool_terminate: "
- "Failed to get spoolss pipe [%s]\n",
- nt_errstr(status)));
+ //status = rpc_pipe_open_interface(conn,
+ // &ndr_table_spoolss,
+ // conn->session_info,
+ // conn->sconn->remote_address,
+ // conn->sconn->local_address,
+ // conn->sconn->msg_ctx,
+ // &conn->spoolss_pipe);
+ //if (!NT_STATUS_IS_OK(status)) {
+ // DEBUG(0, ("print_spool_terminate: "
+ // "Failed to get spoolss pipe [%s]\n",
+ // nt_errstr(status)));
+ // return;
+ //}
+ if (print_file->spoolss_pipe == NULL) {
return;
}
- b = conn->spoolss_pipe->binding_handle;
+ b = print_file->spoolss_pipe->binding_handle;
- status = dcerpc_spoolss_SetJob(b, print_file,
- &print_file->handle,
- print_file->jobid,
- NULL, SPOOLSS_JOB_CONTROL_DELETE,
- &werr);
+ status = dcerpc_spoolss_AbortPrinter(b, print_file,
+ &print_file->handle,
+ &werr);
if (!NT_STATUS_IS_OK(status) ||
!NT_STATUS_IS_OK(status = werror_to_ntstatus(werr))) {
- DEBUG(3, ("Failed to delete job %d [%s]\n",
+ DEBUG(3, ("Failed to abort printer job %d [%s]\n",
print_file->jobid, nt_errstr(status)));
return;
}