spoolss: return the spoolss job ID in notifications
authorDavid Disseldorp <ddiss@samba.org>
Fri, 20 Sep 2013 03:31:37 +0000 (20:31 -0700)
committerDavid Disseldorp <ddiss@samba.org>
Mon, 18 Nov 2013 15:03:59 +0000 (16:03 +0100)
Print job notifications currently carry the system print job identifier
from the queue structure. Instead, the spoolss job identifier should be
resolved and returned.

Print clients can use notification job-ids in subsequent spoolss SetJob
requests. Returning an incorrect identifier can result in the failure of
such requests, e.g. spoolss_SetJob(SPOOLSS_JOB_CONTROL_DELETE).

BUG: https://bugzilla.samba.org/show_bug.cgi?id=10271

Signed-off-by: David Disseldorp <ddiss@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
source3/include/printing.h
source3/printing/printing.c
source3/rpc_server/spoolss/srv_spoolss_nt.c

index 391fb7ae823c25acc1e22f8acd7b8e7fae6f12df..ec5a53b7fd6e21202851ec8f18000a09444be2f1 100644 (file)
@@ -193,6 +193,7 @@ uint16_t print_spool_rap_jobid(struct print_file_data *print_file);
 
 /* The following definitions come from printing/printing.c  */
 
+uint32 sysjob_to_jobid_pdb(struct tdb_print_db *pdb, int sysjob);
 uint32 sysjob_to_jobid(int unix_jobid);
 bool print_notify_register_pid(int snum);
 bool print_notify_deregister_pid(int snum);
index 43f75e5c4382a4cba2a42968403d9a99b4675b7d..57d2f0cf71408ddd7096a37288ff16e4c09b16e0 100644 (file)
@@ -519,7 +519,7 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
        return 0;
 }
 
-static uint32 sysjob_to_jobid_pdb(struct tdb_print_db *pdb, int sysjob)
+uint32 sysjob_to_jobid_pdb(struct tdb_print_db *pdb, int sysjob)
 {
        struct unixjob_traverse_state state;
 
index d37c24df6fd3b6803ec6a965ffb9e47e3c699caf..a6201d4f55e7dcec9a88a53d6356ac4e63bd4b4c 100644 (file)
@@ -3612,6 +3612,7 @@ static WERROR printer_notify_info(struct pipes_struct *p,
        print_status_struct status;
        struct spoolss_PrinterInfo2 *pinfo2 = NULL;
        WERROR result;
+       struct tdb_print_db *pdb;
 
        DEBUG(4,("printer_notify_info\n"));
 
@@ -3635,13 +3636,19 @@ static WERROR printer_notify_info(struct pipes_struct *p,
                return WERR_BADFID;
        }
 
+       pdb = get_print_db_byname(Printer->sharename);
+       if (pdb == NULL) {
+               return WERR_BADFID;
+       }
+
        /* Maybe we should use the SYSTEM session_info here... */
        result = winreg_get_printer_internal(mem_ctx,
                                    get_session_info_system(),
                                    p->msg_ctx,
                                    lp_servicename(talloc_tos(), snum), &pinfo2);
        if (!W_ERROR_IS_OK(result)) {
-               return WERR_BADFID;
+               result = WERR_BADFID;
+               goto err_pdb_drop;
        }
 
        /*
@@ -3650,10 +3657,11 @@ static WERROR printer_notify_info(struct pipes_struct *p,
         */
        pinfo2->servername = talloc_strdup(pinfo2, Printer->servername);
        if (pinfo2->servername == NULL) {
-               return WERR_NOMEM;
+               result = WERR_NOMEM;
+               goto err_pdb_drop;
        }
 
-       for (i=0; i<option->count; i++) {
+       for (i = 0; i < option->count; i++) {
                option_type = option->types[i];
 
                switch (option_type.type) {
@@ -3672,12 +3680,21 @@ static WERROR printer_notify_info(struct pipes_struct *p,
                        count = print_queue_status(p->msg_ctx, snum, &queue,
                                                   &status);
 
-                       for (j=0; j<count; j++) {
+                       for (j = 0; j < count; j++) {
+                               uint32_t jobid;
+                               jobid = sysjob_to_jobid_pdb(pdb,
+                                                           queue[j].sysjob);
+                               if (jobid == (uint32_t)-1) {
+                                       DEBUG(2, ("ignoring untracked job %d\n",
+                                                 queue[j].sysjob));
+                                       continue;
+                               }
+                               /* FIXME check return value */
                                construct_notify_jobs_info(p->msg_ctx,
                                                           &queue[j], info,
                                                           pinfo2, snum,
                                                           &option_type,
-                                                          queue[j].sysjob,
+                                                          jobid,
                                                           mem_ctx);
                        }
 
@@ -3702,7 +3719,10 @@ static WERROR printer_notify_info(struct pipes_struct *p,
        */
 
        talloc_free(pinfo2);
-       return WERR_OK;
+       result = WERR_OK;
+err_pdb_drop:
+       release_print_db(pdb);
+       return result;
 }
 
 /****************************************************************