]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
spoolss: clear JobInfo on GetJob error
authorDavid Disseldorp <ddiss@samba.org>
Thu, 4 Dec 2014 19:03:39 +0000 (20:03 +0100)
committerKarolin Seeger <kseeger@samba.org>
Wed, 14 Jan 2015 20:58:09 +0000 (21:58 +0100)
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>
(cherry picked from commit 89869e090c56a3f83b451b437f9c3f40a231dd24)

source3/rpc_server/spoolss/srv_spoolss_nt.c

index c4512124490ea384e65c1355cad911358eb90f8a..6e3012ccfbc11031871a19345bc66265beae8cdb 100644 (file)
@@ -9479,7 +9479,8 @@ WERROR _spoolss_GetJob(struct pipes_struct *p,
        /* that's an [in out] buffer */
 
        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"));
@@ -9487,12 +9488,14 @@ WERROR _spoolss_GetJob(struct pipes_struct *p,
        *r->out.needed = 0;
 
        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);
        if (svc_name == NULL) {
-               return WERR_INVALID_PARAM;
+               result = WERR_INVALID_PARAM;
+               goto err_jinfo_free;
        }
 
        result = winreg_get_printer_internal(p->mem_ctx,
@@ -9501,22 +9504,22 @@ WERROR _spoolss_GetJob(struct pipes_struct *p,
                                    svc_name,
                                    &pinfo2);
        if (!W_ERROR_IS_OK(result)) {
-               return result;
+               goto err_jinfo_free;
        }
 
        pdb = get_print_db_byname(svc_name);
        if (pdb == NULL) {
                DEBUG(3, ("failed to get print db for svc %s\n", svc_name));
-               TALLOC_FREE(pinfo2);
-               return WERR_INVALID_PARAM;
+               result = WERR_INVALID_PARAM;
+               goto err_pinfo_free;
        }
 
        sysjob = jobid_to_sysjob_pdb(pdb, r->in.job_id);
        release_print_db(pdb);
        if (sysjob == -1) {
                DEBUG(3, ("no sysjob for spoolss jobid %u\n", r->in.job_id));
-               TALLOC_FREE(pinfo2);
-               return WERR_INVALID_PARAM;
+               result = WERR_INVALID_PARAM;
+               goto err_pinfo_free;
        }
 
        count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
@@ -9546,8 +9549,7 @@ WERROR _spoolss_GetJob(struct pipes_struct *p,
        TALLOC_FREE(pinfo2);
 
        if (!W_ERROR_IS_OK(result)) {
-               TALLOC_FREE(r->out.info);
-               return result;
+               goto err_jinfo_free;
        }
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
@@ -9555,6 +9557,12 @@ WERROR _spoolss_GetJob(struct pipes_struct *p,
        r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
 
        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;
 }
 
 /****************************************************************