1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-04 17:47:26 +03:00

spoolss: clear JobInfo on GetJob error

In handling a spoolss GetJob request, the _spoolss_GetJob() handler may
return an immediate error if one of the input parameters is invalid. If
this is done without zeroing the pre-allocated @info pointer, then
api_spoolss_GetJob() will attempt to marshall @info, which in the case
of an @offered value of zero results in a marshalling error:

ndr_push_error(7): Bad subcontext (PUSH) content_size 64 is larger
than size_is(0)

Bug: https://bugzilla.samba.org/show_bug.cgi?id=10984

Signed-off-by: David Disseldorp <ddiss@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
David Disseldorp 2014-12-04 20:03:39 +01:00 committed by Andreas Schneider
parent 8dd37327b0
commit 89869e090c

View File

@ -9484,7 +9484,8 @@ WERROR _spoolss_GetJob(struct pipes_struct *p,
/* that's an [in out] buffer */ /* that's an [in out] buffer */
if (!r->in.buffer && (r->in.offered != 0)) { if (!r->in.buffer && (r->in.offered != 0)) {
return WERR_INVALID_PARAM; result = WERR_INVALID_PARAM;
goto err_jinfo_free;
} }
DEBUG(5,("_spoolss_GetJob\n")); DEBUG(5,("_spoolss_GetJob\n"));
@ -9492,12 +9493,14 @@ WERROR _spoolss_GetJob(struct pipes_struct *p,
*r->out.needed = 0; *r->out.needed = 0;
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) { if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
return WERR_BADFID; result = WERR_BADFID;
goto err_jinfo_free;
} }
svc_name = lp_const_servicename(snum); svc_name = lp_const_servicename(snum);
if (svc_name == NULL) { if (svc_name == NULL) {
return WERR_INVALID_PARAM; result = WERR_INVALID_PARAM;
goto err_jinfo_free;
} }
result = winreg_get_printer_internal(p->mem_ctx, result = winreg_get_printer_internal(p->mem_ctx,
@ -9506,22 +9509,22 @@ WERROR _spoolss_GetJob(struct pipes_struct *p,
svc_name, svc_name,
&pinfo2); &pinfo2);
if (!W_ERROR_IS_OK(result)) { if (!W_ERROR_IS_OK(result)) {
return result; goto err_jinfo_free;
} }
pdb = get_print_db_byname(svc_name); pdb = get_print_db_byname(svc_name);
if (pdb == NULL) { if (pdb == NULL) {
DEBUG(3, ("failed to get print db for svc %s\n", svc_name)); DEBUG(3, ("failed to get print db for svc %s\n", svc_name));
TALLOC_FREE(pinfo2); result = WERR_INVALID_PARAM;
return WERR_INVALID_PARAM; goto err_pinfo_free;
} }
sysjob = jobid_to_sysjob_pdb(pdb, r->in.job_id); sysjob = jobid_to_sysjob_pdb(pdb, r->in.job_id);
release_print_db(pdb); release_print_db(pdb);
if (sysjob == -1) { if (sysjob == -1) {
DEBUG(3, ("no sysjob for spoolss jobid %u\n", r->in.job_id)); DEBUG(3, ("no sysjob for spoolss jobid %u\n", r->in.job_id));
TALLOC_FREE(pinfo2); result = WERR_INVALID_PARAM;
return WERR_INVALID_PARAM; goto err_pinfo_free;
} }
count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status); count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
@ -9551,8 +9554,7 @@ WERROR _spoolss_GetJob(struct pipes_struct *p,
TALLOC_FREE(pinfo2); TALLOC_FREE(pinfo2);
if (!W_ERROR_IS_OK(result)) { if (!W_ERROR_IS_OK(result)) {
TALLOC_FREE(r->out.info); goto err_jinfo_free;
return result;
} }
*r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info, *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
@ -9560,6 +9562,12 @@ WERROR _spoolss_GetJob(struct pipes_struct *p,
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
err_pinfo_free:
TALLOC_FREE(pinfo2);
err_jinfo_free:
TALLOC_FREE(r->out.info);
return result;
} }
/**************************************************************** /****************************************************************