s3-printing: remove print_parse_jobid() calls from printing.c
[ddiss/samba.git] / source3 / printing / printing.c
index b620db03d5623f2a9a9d256d156e5d45c6d78824..11feae28222bcf343cd1f002b39afbfd5f0b02fc 100644 (file)
 */
 
 #include "includes.h"
+#include "system/syslog.h"
+#include "system/filesys.h"
 #include "printing.h"
-#include "librpc/gen_ndr/messaging.h"
+#include "../librpc/gen_ndr/ndr_spoolss.h"
+#include "nt_printing.h"
+#include "../librpc/gen_ndr/netlogon.h"
+#include "printing/notify.h"
+#include "printing/pcap.h"
+#include "printing/printer_list.h"
+#include "printing/queue_process.h"
+#include "serverid.h"
+#include "smbd/smbd.h"
+#include "auth.h"
+#include "messages.h"
+#include "util_tdb.h"
+#include "lib/param/loadparm.h"
 
 extern struct current_user current_user;
 extern userdom_struct current_user_info;
 
 /* Current printer interface */
-static bool remove_from_jobs_changed(const char* sharename, uint32 jobid);
+static bool remove_from_jobs_added(const char* sharename, uint32 jobid);
 
 /*
    the printing backend revolves around a tdb database that stores the
@@ -77,7 +91,7 @@ uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
        key.dptr = (uint8 *)&jinfo;
        key.dsize = sizeof(jinfo);
 
-       data = tdb_fetch(rap_tdb, key);
+       data = tdb_fetch_compat(rap_tdb, key);
        if (data.dptr && data.dsize == sizeof(uint16)) {
                rap_jobid = SVAL(data.dptr, 0);
                SAFE_FREE(data.dptr);
@@ -114,7 +128,7 @@ bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
        SSVAL(buf,0,rap_jobid);
        key.dptr = buf;
        key.dsize = sizeof(rap_jobid);
-       data = tdb_fetch(rap_tdb, key);
+       data = tdb_fetch_compat(rap_tdb, key);
        if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
        {
                struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
@@ -152,7 +166,7 @@ void rap_jobid_delete(const char* sharename, uint32 jobid)
        key.dptr = (uint8 *)&jinfo;
        key.dsize = sizeof(jinfo);
 
-       data = tdb_fetch(rap_tdb, key);
+       data = tdb_fetch_compat(rap_tdb, key);
        if (!data.dptr || (data.dsize != sizeof(uint16))) {
                DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
                        (unsigned int)jobid ));
@@ -184,6 +198,10 @@ bool print_backend_init(struct messaging_context *msg_ctx)
        int services = lp_numservices();
        int snum;
 
+       if (!printer_list_parent_init()) {
+               return false;
+       }
+
        unlink(cache_path("printing.tdb"));
        mkdir(cache_path("printing"),0755);
 
@@ -197,7 +215,7 @@ bool print_backend_init(struct messaging_context *msg_ctx)
                pdb = get_print_db_byname(lp_const_servicename(snum));
                if (!pdb)
                        continue;
-               if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
+               if (tdb_lock_bystring(pdb->tdb, sversion) != 0) {
                        DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
                        release_print_db(pdb);
                        return False;
@@ -275,22 +293,107 @@ static TDB_DATA print_key(uint32 jobid, uint32 *tmp)
        return ret;
 }
 
+/****************************************************************************
+ Pack the devicemode to store it in a tdb.
+****************************************************************************/
+static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen)
+{
+       enum ndr_err_code ndr_err;
+       DATA_BLOB blob;
+       int len = 0;
+
+       if (devmode) {
+               ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
+                                              devmode,
+                                              (ndr_push_flags_fn_t)
+                                              ndr_push_spoolss_DeviceMode);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       DEBUG(10, ("pack_devicemode: "
+                                  "error encoding spoolss_DeviceMode\n"));
+                       goto done;
+               }
+       } else {
+               ZERO_STRUCT(blob);
+       }
+
+       len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
+
+       if (devmode) {
+               DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
+       }
+
+done:
+       return len;
+}
+
+/****************************************************************************
+ Unpack the devicemode to store it in a tdb.
+****************************************************************************/
+static int unpack_devicemode(TALLOC_CTX *mem_ctx,
+                     const uint8 *buf, int buflen,
+                     struct spoolss_DeviceMode **devmode)
+{
+       struct spoolss_DeviceMode *dm;
+       enum ndr_err_code ndr_err;
+       char *data = NULL;
+       int data_len = 0;
+       DATA_BLOB blob;
+       int len = 0;
+
+       *devmode = NULL;
+
+       len = tdb_unpack(buf, buflen, "B", &data_len, &data);
+       if (!data) {
+               return len;
+       }
+
+       dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
+       if (!dm) {
+               goto done;
+       }
+
+       blob = data_blob_const(data, data_len);
+
+       ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
+                       (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DEBUG(10, ("unpack_devicemode: "
+                          "error parsing spoolss_DeviceMode\n"));
+               goto done;
+       }
+
+       DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
+                 dm->devicename, dm->formname));
+       if (dm->driverextra_data.data) {
+               DEBUG(8, ("with a private section of %d bytes\n",
+                         dm->__driverextra_length));
+       }
+
+       *devmode = dm;
+
+done:
+       SAFE_FREE(data);
+       return len;
+}
+
 /***********************************************************************
  unpack a pjob from a tdb buffer
 ***********************************************************************/
 
-int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
+static int unpack_pjob(uint8 *buf, int buflen, struct printjob *pjob)
 {
        int     len = 0;
        int     used;
-       uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
+       uint32 pjpid, pjjobid, pjsysjob, pjfd, pjstarttime, pjstatus;
        uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
 
-       if ( !buf || !pjob )
+       if (!buf || !pjob) {
                return -1;
+       }
 
-       len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
+       len += tdb_unpack(buf+len, buflen-len, "ddddddddddfffff",
                                &pjpid,
+                               &pjjobid,
                                &pjsysjob,
                                &pjfd,
                                &pjstarttime,
@@ -302,10 +405,12 @@ int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
                                pjob->filename,
                                pjob->jobname,
                                pjob->user,
+                               pjob->clientmachine,
                                pjob->queuename);
 
-       if ( len == -1 )
+       if (len == -1) {
                return -1;
+       }
 
         used = unpack_devicemode(NULL, buf+len, buflen-len, &pjob->devmode);
         if (used == -1) {
@@ -315,6 +420,7 @@ int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
        len += used;
 
        pjob->pid = pjpid;
+       pjob->jobid = pjjobid;
        pjob->sysjob = pjsysjob;
        pjob->fd = pjfd;
        pjob->starttime = pjstarttime;
@@ -346,7 +452,7 @@ static struct printjob *print_job_find(const char *sharename, uint32 jobid)
                return NULL;
        }
 
-       ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
+       ret = tdb_fetch_compat(pdb->tdb, print_key(jobid, &tmp));
        release_print_db(pdb);
 
        if (!ret.dptr) {
@@ -368,6 +474,7 @@ static struct printjob *print_job_find(const char *sharename, uint32 jobid)
 
        DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
                        (int)pjob.sysjob, (unsigned int)jobid ));
+       SMB_ASSERT(pjob.jobid == jobid);
 
        return &pjob;
 }
@@ -394,15 +501,25 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
                return 0;
 
        if (state->sysjob == pjob->sysjob) {
-               uint32 jobid = IVAL(key.dptr,0);
-
-               state->sysjob_to_jobid_value = jobid;
+               state->sysjob_to_jobid_value = pjob->jobid;
                return 1;
        }
 
        return 0;
 }
 
+static uint32 sysjob_to_jobid_pdb(struct tdb_print_db *pdb, int sysjob)
+{
+       struct unixjob_traverse_state state;
+
+       state.sysjob = sysjob;
+       state.sysjob_to_jobid_value = (uint32)-1;
+
+       tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
+
+       return state.sysjob_to_jobid_value;
+}
+
 /****************************************************************************
  This is a *horribly expensive call as we have to iterate through all the
  current printer tdb's. Don't do this often ! JRA.
@@ -438,8 +555,8 @@ uint32 sysjob_to_jobid(int unix_jobid)
 ****************************************************************************/
 
 static const struct {
-       uint32 lpq_status;
-       uint32 spoolss_status;
+       uint32_t lpq_status;
+       uint32_t spoolss_status;
 } lpq_to_spoolss_status_map[] = {
        { LPQ_QUEUED, JOB_STATUS_QUEUED },
        { LPQ_PAUSED, JOB_STATUS_PAUSED },
@@ -452,7 +569,7 @@ static const struct {
        { LPQ_DELETED, JOB_STATUS_DELETED },
        { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
        { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
-       { -1, 0 }
+       { (uint32_t)-1, 0 }
 };
 
 /* Convert a lpq status value stored in printing.tdb into the
@@ -471,16 +588,97 @@ static uint32 map_to_spoolss_status(uint32 lpq_status)
        return 0;
 }
 
-static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
-                             struct printjob *new_data)
+/***************************************************************************
+ Append a jobid to the 'jobs changed' list.
+***************************************************************************/
+
+static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32_t jobid)
+{
+       TDB_DATA data;
+       uint32_t store_jobid;
+
+       SIVAL(&store_jobid, 0, jobid);
+       data.dptr = (uint8 *) &store_jobid;
+       data.dsize = 4;
+
+       DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
+
+       return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
+                          data) == 0);
+}
+
+/***************************************************************************
+ Remove a jobid from the 'jobs changed' list.
+***************************************************************************/
+
+static bool remove_from_jobs_changed(const char* sharename, uint32_t jobid)
 {
-       bool new_job = False;
+       struct tdb_print_db *pdb = get_print_db_byname(sharename);
+       TDB_DATA data, key;
+       size_t job_count, i;
+       bool ret = False;
+       bool gotlock = False;
+
+       if (!pdb) {
+               return False;
+       }
+
+       ZERO_STRUCT(data);
+
+       key = string_tdb_data("INFO/jobs_changed");
+
+       if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) != 0)
+               goto out;
+
+       gotlock = True;
+
+       data = tdb_fetch_compat(pdb->tdb, key);
+
+       if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
+               goto out;
+
+       job_count = data.dsize / 4;
+       for (i = 0; i < job_count; i++) {
+               uint32 ch_jobid;
+
+               ch_jobid = IVAL(data.dptr, i*4);
+               if (ch_jobid == jobid) {
+                       if (i < job_count -1 )
+                               memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
+                       data.dsize -= 4;
+                       if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) != 0)
+                               goto out;
+                       break;
+               }
+       }
 
-       if (!old_data)
-               new_job = True;
+       ret = True;
+  out:
+
+       if (gotlock)
+               tdb_chainunlock(pdb->tdb, key);
+       SAFE_FREE(data.dptr);
+       release_print_db(pdb);
+       if (ret)
+               DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
+       else
+               DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
+       return ret;
+}
 
-       /* Job attributes that can't be changed.  We only send
-          notification for these on a new job. */
+static void pjob_store_notify(struct tevent_context *ev,
+                             struct messaging_context *msg_ctx,
+                             const char* sharename, uint32 jobid,
+                             struct printjob *old_data,
+                             struct printjob *new_data,
+                             bool *pchanged)
+{
+       bool new_job = false;
+       bool changed = false;
+
+       if (old_data == NULL) {
+               new_job = true;
+       }
 
        /* ACHTUNG!  Due to a bug in Samba's spoolss parsing of the
           NOTIFY_INFO_DATA buffer, we *have* to send the job submission
@@ -490,34 +688,54 @@ static void pjob_store_notify(const char* sharename, uint32 jobid, struct printj
           --jerry (i'll feel dirty for this) */
 
        if (new_job) {
-               notify_job_submitted(sharename, jobid, new_data->starttime);
-               notify_job_username(sharename, jobid, new_data->user);
-       }
-
-       if (new_job || !strequal(old_data->jobname, new_data->jobname))
-               notify_job_name(sharename, jobid, new_data->jobname);
-
-       /* Job attributes of a new job or attributes that can be
-          modified. */
+               notify_job_submitted(ev, msg_ctx,
+                                    sharename, jobid, new_data->starttime);
+               notify_job_username(ev, msg_ctx,
+                                   sharename, jobid, new_data->user);
+               notify_job_name(ev, msg_ctx,
+                               sharename, jobid, new_data->jobname);
+               notify_job_status(ev, msg_ctx,
+                                 sharename, jobid, map_to_spoolss_status(new_data->status));
+               notify_job_total_bytes(ev, msg_ctx,
+                                      sharename, jobid, new_data->size);
+               notify_job_total_pages(ev, msg_ctx,
+                                      sharename, jobid, new_data->page_count);
+       } else {
+               if (!strequal(old_data->jobname, new_data->jobname)) {
+                       notify_job_name(ev, msg_ctx, sharename,
+                                       jobid, new_data->jobname);
+                       changed = true;
+               }
 
-       if (new_job || !strequal(old_data->jobname, new_data->jobname))
-               notify_job_name(sharename, jobid, new_data->jobname);
+               if (old_data->status != new_data->status) {
+                       notify_job_status(ev, msg_ctx,
+                                         sharename, jobid,
+                                         map_to_spoolss_status(new_data->status));
+               }
 
-       if (new_job || old_data->status != new_data->status)
-               notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status));
+               if (old_data->size != new_data->size) {
+                       notify_job_total_bytes(ev, msg_ctx,
+                                              sharename, jobid, new_data->size);
+               }
 
-       if (new_job || old_data->size != new_data->size)
-               notify_job_total_bytes(sharename, jobid, new_data->size);
+               if (old_data->page_count != new_data->page_count) {
+                       notify_job_total_pages(ev, msg_ctx,
+                                              sharename, jobid,
+                                              new_data->page_count);
+               }
+       }
 
-       if (new_job || old_data->page_count != new_data->page_count)
-               notify_job_total_pages(sharename, jobid, new_data->page_count);
+       *pchanged = changed;
 }
 
 /****************************************************************************
  Store a job structure back to the database.
 ****************************************************************************/
 
-static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
+static bool pjob_store(struct tevent_context *ev,
+                      struct messaging_context *msg_ctx,
+                      const char* sharename, uint32 jobid,
+                      struct printjob *pjob)
 {
        uint32_t tmp;
        TDB_DATA                old_data, new_data;
@@ -532,7 +750,7 @@ static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjo
 
        /* Get old data */
 
-       old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
+       old_data = tdb_fetch_compat(pdb->tdb, print_key(jobid, &tmp));
 
        /* Doh!  Now we have to pack/unpack data since the NT_DEVICEMODE was added */
 
@@ -541,8 +759,9 @@ static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjo
        do {
                len = 0;
                buflen = newlen;
-               len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
+               len += tdb_pack(buf+len, buflen-len, "ddddddddddfffff",
                                (uint32)pjob->pid,
+                               (uint32)pjob->jobid,
                                (uint32)pjob->sysjob,
                                (uint32)pjob->fd,
                                (uint32)pjob->starttime,
@@ -554,6 +773,7 @@ static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjo
                                pjob->filename,
                                pjob->jobname,
                                pjob->user,
+                               pjob->clientmachine,
                                pjob->queuename);
 
                len += pack_devicemode(pjob->devmode, buf+len, buflen-len);
@@ -576,27 +796,38 @@ static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjo
        ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
                         TDB_REPLACE) == 0);
 
-       release_print_db(pdb);
-
        /* Send notify updates for what has changed */
 
        if ( ret ) {
+               bool changed = false;
                struct printjob old_pjob;
 
                if ( old_data.dsize )
                {
                        if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
                        {
-                               pjob_store_notify( sharename, jobid, &old_pjob , pjob );
+                               pjob_store_notify(server_event_context(),
+                                                 msg_ctx,
+                                                 sharename, jobid, &old_pjob,
+                                                 pjob,
+                                                 &changed);
                                talloc_free(old_pjob.devmode);
+
+                               if (changed) {
+                                       add_to_jobs_changed(pdb, jobid);
+                               }
                        }
+
                }
                else {
                        /* new job */
-                       pjob_store_notify( sharename, jobid, NULL, pjob );
+                       pjob_store_notify(server_event_context(), msg_ctx,
+                                         sharename, jobid, NULL, pjob,
+                                         &changed);
                }
        }
 
+       release_print_db(pdb);
 done:
        SAFE_FREE( old_data.dptr );
        SAFE_FREE( buf );
@@ -608,7 +839,9 @@ done:
  Remove a job structure from the database.
 ****************************************************************************/
 
-void pjob_delete(const char* sharename, uint32 jobid)
+static void pjob_delete(struct tevent_context *ev,
+                       struct messaging_context *msg_ctx,
+                       const char* sharename, uint32 jobid)
 {
        uint32_t tmp;
        struct printjob *pjob;
@@ -634,12 +867,12 @@ void pjob_delete(const char* sharename, uint32 jobid)
            properly. */
 
        job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
-       notify_job_status(sharename, jobid, job_status);
+       notify_job_status(ev, msg_ctx, sharename, jobid, job_status);
 
        /* Remove from printing.tdb */
 
        tdb_delete(pdb->tdb, print_key(jobid, &tmp));
-       remove_from_jobs_changed(sharename, jobid);
+       remove_from_jobs_added(sharename, jobid);
        release_print_db( pdb );
        rap_jobid_delete(sharename, jobid);
 }
@@ -648,12 +881,15 @@ void pjob_delete(const char* sharename, uint32 jobid)
  List a unix job in the print database.
 ****************************************************************************/
 
-static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
+static void print_unix_job(struct tevent_context *ev,
+                          struct messaging_context *msg_ctx,
+                          const char *sharename, print_queue_struct *q,
+                          uint32 jobid)
 {
        struct printjob pj, *old_pj;
 
        if (jobid == (uint32)-1)
-               jobid = q->job + UNIX_JOB_START;
+               jobid = q->sysjob + UNIX_JOB_START;
 
        /* Preserve the timestamp on an existing unix print job */
 
@@ -662,7 +898,8 @@ static void print_unix_job(const char *sharename, print_queue_struct *q, uint32
        ZERO_STRUCT(pj);
 
        pj.pid = (pid_t)-1;
-       pj.sysjob = q->job;
+       pj.jobid = jobid;
+       pj.sysjob = q->sysjob;
        pj.fd = -1;
        pj.starttime = old_pj ? old_pj->starttime : q->time;
        pj.status = q->status;
@@ -679,7 +916,7 @@ static void print_unix_job(const char *sharename, print_queue_struct *q, uint32
        fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
        fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
 
-       pjob_store(sharename, jobid, &pj);
+       pjob_store(ev, msg_ctx, sharename, jobid, &pj);
 }
 
 
@@ -690,6 +927,8 @@ struct traverse_struct {
        time_t lpq_time;
        const char *lprm_command;
        struct printif *print_if;
+       struct tevent_context *ev;
+       struct messaging_context *msg_ctx;
 };
 
 /****************************************************************************
@@ -706,24 +945,23 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
        if (  key.dsize != sizeof(jobid) )
                return 0;
 
-       jobid = IVAL(key.dptr, 0);
-       if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
+       if (unpack_pjob(data.dptr, data.dsize, &pjob) == -1)
                return 0;
        talloc_free(pjob.devmode);
-
+       jobid = pjob.jobid;
 
        if (!pjob.smbjob) {
                /* remove a unix job if it isn't in the system queue any more */
-
                for (i=0;i<ts->qcount;i++) {
-                       uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
-                       if (jobid == u_jobid)
+                       if (ts->queue[i].sysjob == pjob.sysjob) {
                                break;
+                       }
                }
                if (i == ts->qcount) {
                        DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
                                                (unsigned int)jobid ));
-                       pjob_delete(ts->sharename, jobid);
+                       pjob_delete(ts->ev, ts->msg_ctx,
+                                   ts->sharename, jobid);
                        return 0;
                }
 
@@ -739,7 +977,8 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
                if (!process_exists_by_pid(pjob.pid)) {
                        DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
                                                (unsigned int)jobid, (unsigned int)pjob.pid ));
-                       pjob_delete(ts->sharename, jobid);
+                       pjob_delete(ts->ev, ts->msg_ctx,
+                                   ts->sharename, jobid);
                } else
                        ts->total_jobs++;
                return 0;
@@ -747,16 +986,12 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
 
        /* this check only makes sense for jobs submitted from Windows clients */
 
-       if ( pjob.smbjob ) {
+       if (pjob.smbjob) {
                for (i=0;i<ts->qcount;i++) {
-                       uint32 curr_jobid;
-
                        if ( pjob.status == LPQ_DELETED )
                                continue;
 
-                       curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
-
-                       if (jobid == curr_jobid) {
+                       if (ts->queue[i].sysjob == pjob.sysjob) {
 
                                /* try to clean up any jobs that need to be deleted */
 
@@ -769,11 +1004,14 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
                                        if ( result != 0 ) {
                                                /* if we can't delete, then reset the job status */
                                                pjob.status = LPQ_QUEUED;
-                                               pjob_store(ts->sharename, jobid, &pjob);
+                                               pjob_store(ts->ev, ts->msg_ctx,
+                                                          ts->sharename, jobid, &pjob);
                                        }
                                        else {
                                                /* if we deleted the job, the remove the tdb record */
-                                               pjob_delete(ts->sharename, jobid);
+                                               pjob_delete(ts->ev,
+                                                           ts->msg_ctx,
+                                                           ts->sharename, jobid);
                                                pjob.status = LPQ_DELETED;
                                        }
 
@@ -801,17 +1039,15 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
                                                (unsigned int)jobid,
                                                (unsigned int)pjob.starttime,
                                                (unsigned int)ts->lpq_time ));
-                       pjob_delete(ts->sharename, jobid);
+                       pjob_delete(ts->ev, ts->msg_ctx,
+                                   ts->sharename, jobid);
                } else
                        ts->total_jobs++;
                return 0;
        }
 
-       /* Save the pjob attributes we will store.
-          FIXME!!! This is the only place where queue->job
-          represents the SMB jobid      --jerry */
-
-       ts->queue[i].job = jobid;
+       /* Save the pjob attributes we will store. */
+       ts->queue[i].sysjob = pjob.sysjob;
        ts->queue[i].size = pjob.size;
        ts->queue[i].page_count = pjob.page_count;
        ts->queue[i].status = pjob.status;
@@ -857,7 +1093,7 @@ static pid_t get_updating_pid(const char *sharename)
        slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
        key = string_tdb_data(keystr);
 
-       data = tdb_fetch(pdb->tdb, key);
+       data = tdb_fetch_compat(pdb->tdb, key);
        release_print_db(pdb);
        if (!data.dptr || data.dsize != sizeof(pid_t)) {
                SAFE_FREE(data.dptr);
@@ -883,7 +1119,7 @@ static void set_updating_pid(const fstring sharename, bool updating)
        fstring keystr;
        TDB_DATA key;
        TDB_DATA data;
-       pid_t updating_pid = sys_getpid();
+       pid_t updating_pid = getpid();
        uint8 buffer[4];
 
        struct tdb_print_db *pdb = get_print_db_byname(sharename);
@@ -962,7 +1198,7 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct
 
                qcount++;
                data.dsize += tdb_pack(NULL, 0, "ddddddff",
-                               (uint32)queue[i].job,
+                               (uint32)queue[i].sysjob,
                                (uint32)queue[i].size,
                                (uint32)queue[i].page_count,
                                (uint32)queue[i].status,
@@ -982,7 +1218,7 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct
                        continue;
 
                len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
-                               (uint32)queue[i].job,
+                               (uint32)queue[i].sysjob,
                                (uint32)queue[i].size,
                                (uint32)queue[i].page_count,
                                (uint32)queue[i].status,
@@ -998,13 +1234,13 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct
        return;
 }
 
-static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
+static TDB_DATA get_jobs_added_data(struct tdb_print_db *pdb)
 {
        TDB_DATA data;
 
        ZERO_STRUCT(data);
 
-       data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
+       data = tdb_fetch_compat(pdb->tdb, string_tdb_data("INFO/jobs_added"));
        if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
                SAFE_FREE(data.dptr);
                ZERO_STRUCT(data);
@@ -1013,7 +1249,7 @@ static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
        return data;
 }
 
-static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
+static void check_job_added(const char *sharename, TDB_DATA data, uint32 jobid)
 {
        unsigned int i;
        unsigned int job_count = data.dsize / 4;
@@ -1023,7 +1259,7 @@ static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid
 
                ch_jobid = IVAL(data.dptr, i*4);
                if (ch_jobid == jobid)
-                       remove_from_jobs_changed(sharename, jobid);
+                       remove_from_jobs_added(sharename, jobid);
        }
 }
 
@@ -1093,12 +1329,14 @@ done:
 }
 
 /****************************************************************************
- main work for updating the lpq cahe for a printer queue
+ main work for updating the lpq cache for a printer queue
 ****************************************************************************/
 
-static void print_queue_update_internal( const char *sharename,
-                                         struct printif *current_printif,
-                                         char *lpq_command, char *lprm_command )
+static void print_queue_update_internal(struct tevent_context *ev,
+                                       struct messaging_context *msg_ctx,
+                                       const char *sharename,
+                                        struct printif *current_printif,
+                                        char *lpq_command, char *lprm_command)
 {
        int i, qcount;
        print_queue_struct *queue = NULL;
@@ -1153,14 +1391,14 @@ static void print_queue_update_internal( const char *sharename,
          fill in any system job numbers as we go
        */
 
-       jcdata = get_jobs_changed_data(pdb);
+       jcdata = get_jobs_added_data(pdb);
 
        for (i=0; i<qcount; i++) {
-               uint32 jobid = print_parse_jobid(queue[i].fs_file);
-
+               uint32 jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob);
                if (jobid == (uint32)-1) {
                        /* assume its a unix print job */
-                       print_unix_job(sharename, &queue[i], jobid);
+                       print_unix_job(ev, msg_ctx,
+                                      sharename, &queue[i], jobid);
                        continue;
                }
 
@@ -1170,20 +1408,24 @@ static void print_queue_update_internal( const char *sharename,
                        /* err, somethings wrong. Probably smbd was restarted
                           with jobs in the queue. All we can do is treat them
                           like unix jobs. Pity. */
-                       print_unix_job(sharename, &queue[i], jobid);
+                       DEBUG(1, ("queued print job %d not found in jobs list, "
+                                 "assuming unix job\n", jobid));
+                       print_unix_job(ev, msg_ctx,
+                                      sharename, &queue[i], jobid);
                        continue;
                }
 
-               pjob->sysjob = queue[i].job;
+               /* FIXME this is already confirmed by sysjob_to_jobid_pdb() */
+               pjob->sysjob = queue[i].sysjob;
 
                /* don't reset the status on jobs to be deleted */
 
                if ( pjob->status != LPQ_DELETING )
                        pjob->status = queue[i].status;
 
-               pjob_store(sharename, jobid, pjob);
+               pjob_store(ev, msg_ctx, sharename, jobid, pjob);
 
-               check_job_changed(sharename, jcdata, jobid);
+               check_job_added(sharename, jcdata, jobid);
        }
 
        SAFE_FREE(jcdata.dptr);
@@ -1198,6 +1440,8 @@ static void print_queue_update_internal( const char *sharename,
        tstruct.sharename = sharename;
        tstruct.lprm_command = lprm_command;
        tstruct.print_if = current_printif;
+       tstruct.ev = ev;
+       tstruct.msg_ctx = msg_ctx;
 
        tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
 
@@ -1255,7 +1499,9 @@ static void print_queue_update_internal( const char *sharename,
  smbd processes maytry to update the lpq cache concurrently).
 ****************************************************************************/
 
-static void print_queue_update_with_lock( const char *sharename,
+static void print_queue_update_with_lock( struct tevent_context *ev,
+                                         struct messaging_context *msg_ctx,
+                                         const char *sharename,
                                           struct printif *current_printif,
                                           char *lpq_command, char *lprm_command )
 {
@@ -1287,7 +1533,7 @@ static void print_queue_update_with_lock( const char *sharename,
 
        slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
        /* Only wait 10 seconds for this. */
-       if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
+       if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) != 0) {
                DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
                release_print_db(pdb);
                return;
@@ -1324,8 +1570,9 @@ static void print_queue_update_with_lock( const char *sharename,
 
        /* do the main work now */
 
-       print_queue_update_internal( sharename, current_printif,
-               lpq_command, lprm_command );
+       print_queue_update_internal(ev, msg_ctx,
+                                   sharename, current_printif,
+                                   lpq_command, lprm_command);
 
        /* Delete our pid from the db. */
        set_updating_pid(sharename, False);
@@ -1335,7 +1582,7 @@ static void print_queue_update_with_lock( const char *sharename,
 /****************************************************************************
 this is the receive function of the background lpq updater
 ****************************************************************************/
-static void print_queue_receive(struct messaging_context *msg,
+void print_queue_receive(struct messaging_context *msg,
                                void *private_data,
                                uint32_t msg_type,
                                struct server_id server_id,
@@ -1359,7 +1606,7 @@ static void print_queue_receive(struct messaging_context *msg,
                return;
        }
 
-       print_queue_update_with_lock(sharename,
+       print_queue_update_with_lock(server_event_context(), msg, sharename,
                get_printer_fns_from_type((enum printing_types)printing_type),
                lpqcommand, lprmcommand );
 
@@ -1368,127 +1615,14 @@ static void print_queue_receive(struct messaging_context *msg,
        return;
 }
 
-static void printing_pause_fd_handler(struct tevent_context *ev,
-                                     struct tevent_fd *fde,
-                                     uint16_t flags,
-                                     void *private_data)
-{
-       /*
-        * If pause_pipe[1] is closed it means the parent smbd
-        * and children exited or aborted.
-        */
-       exit_server_cleanly(NULL);
-}
-
-extern struct child_pid *children;
-extern int num_children;
-
-static void add_child_pid(pid_t pid)
-{
-       struct child_pid *child;
-
-        child = SMB_MALLOC_P(struct child_pid);
-        if (child == NULL) {
-                DEBUG(0, ("Could not add child struct -- malloc failed\n"));
-                return;
-        }
-        child->pid = pid;
-        DLIST_ADD(children, child);
-        num_children += 1;
-}
-
-static pid_t background_lpq_updater_pid = -1;
-
-/****************************************************************************
-main thread of the background lpq updater
-****************************************************************************/
-void start_background_queue(void)
-{
-       /* Use local variables for this as we don't
-        * need to save the parent side of this, just
-        * ensure it closes when the process exits.
-        */
-       int pause_pipe[2];
-
-       DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
-
-       if (pipe(pause_pipe) == -1) {
-               DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
-               exit(1);
-       }
-
-       background_lpq_updater_pid = sys_fork();
-
-       if (background_lpq_updater_pid == -1) {
-               DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
-               exit(1);
-       }
-
-       /* Track the printing pid along with other smbd children */
-       add_child_pid(background_lpq_updater_pid);
-
-       if(background_lpq_updater_pid == 0) {
-               struct tevent_fd *fde;
-               int ret;
-               NTSTATUS status;
-
-               /* Child. */
-               DEBUG(5,("start_background_queue: background LPQ thread started\n"));
-
-               close(pause_pipe[0]);
-               pause_pipe[0] = -1;
-
-               status = reinit_after_fork(server_messaging_context(),
-                                          server_event_context(),
-                                          procid_self(), true);
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(0,("reinit_after_fork() failed\n"));
-                       smb_panic("reinit_after_fork() failed");
-               }
-
-               smbd_setup_sig_term_handler();
-               smbd_setup_sig_hup_handler();
-
-               if (!serverid_register(procid_self(),
-                                      FLAG_MSG_GENERAL|FLAG_MSG_SMBD
-                                      |FLAG_MSG_PRINT_GENERAL)) {
-                       exit(1);
-               }
-
-               if (!locking_init()) {
-                       exit(1);
-               }
-
-               messaging_register(server_messaging_context(), NULL,
-                                  MSG_PRINTER_UPDATE, print_queue_receive);
-
-               fde = tevent_add_fd(server_event_context(),
-                                   server_event_context(),
-                                   pause_pipe[1], TEVENT_FD_READ,
-                                   printing_pause_fd_handler,
-                                   NULL);
-               if (!fde) {
-                       DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
-                       smb_panic("tevent_add_fd() failed for pause_pipe");
-               }
-
-               DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
-               ret = tevent_loop_wait(server_event_context());
-               /* should not be reached */
-               DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
-                        ret, (ret == 0) ? "out of events" : strerror(errno)));
-               exit(1);
-       }
-
-       close(pause_pipe[1]);
-}
-
 /****************************************************************************
 update the internal database from the system print queue for a queue
 ****************************************************************************/
 
-static void print_queue_update(int snum, bool force)
+extern pid_t background_lpq_updater_pid;
+
+static void print_queue_update(struct messaging_context *msg_ctx,
+                              int snum, bool force)
 {
        fstring key;
        fstring sharename;
@@ -1554,7 +1688,9 @@ static void print_queue_update(int snum, bool force)
        if ( force || background_lpq_updater_pid == -1 ) {
                DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
                current_printif = get_printer_fns( snum );
-               print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
+               print_queue_update_with_lock(server_event_context(), msg_ctx,
+                                            sharename, current_printif,
+                                            lpqcommand, lprmcommand);
 
                return;
        }
@@ -1607,8 +1743,7 @@ static void print_queue_update(int snum, bool force)
 
        /* finally send the message */
 
-       messaging_send_buf(server_messaging_context(),
-                          pid_to_procid(background_lpq_updater_pid),
+       messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid),
                           MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
 
        SAFE_FREE( buffer );
@@ -1627,7 +1762,7 @@ bool print_notify_register_pid(int snum)
        struct tdb_print_db *pdb = NULL;
        TDB_CONTEXT *tdb = NULL;
        const char *printername;
-       uint32 mypid = (uint32)sys_getpid();
+       uint32_t mypid = (uint32_t)getpid();
        bool ret = False;
        size_t i;
 
@@ -1656,7 +1791,7 @@ bool print_notify_register_pid(int snum)
                tdb = pdb->tdb;
        }
 
-       if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
+       if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) != 0) {
                DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
                                        printername));
                if (pdb)
@@ -1690,7 +1825,7 @@ bool print_notify_register_pid(int snum)
        }
 
        /* Store back the record. */
-       if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
+       if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) != 0) {
                DEBUG(0,("print_notify_register_pid: Failed to update pid \
 list for printer %s\n", printername));
                goto done;
@@ -1718,7 +1853,7 @@ bool print_notify_deregister_pid(int snum)
        struct tdb_print_db *pdb = NULL;
        TDB_CONTEXT *tdb = NULL;
        const char *printername;
-       uint32 mypid = (uint32)sys_getpid();
+       uint32_t mypid = (uint32_t)getpid();
        size_t i;
        bool ret = False;
 
@@ -1746,7 +1881,7 @@ bool print_notify_deregister_pid(int snum)
                tdb = pdb->tdb;
        }
 
-       if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
+       if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) != 0) {
                DEBUG(0,("print_notify_register_pid: Failed to lock \
 printer %s database\n", printername));
                if (pdb)
@@ -1780,7 +1915,7 @@ printer %s database\n", printername));
                SAFE_FREE(data.dptr);
 
        /* Store back the record. */
-       if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
+       if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) != 0) {
                DEBUG(0,("print_notify_register_pid: Failed to update pid \
 list for printer %s\n", printername));
                goto done;
@@ -1823,7 +1958,7 @@ bool print_job_exists(const char* sharename, uint32 jobid)
 char *print_job_fname(const char* sharename, uint32 jobid)
 {
        struct printjob *pjob = print_job_find(sharename, jobid);
-       if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
+       if (!pjob || pjob->spooled || pjob->pid != getpid())
                return NULL;
        return pjob->filename;
 }
@@ -1849,16 +1984,18 @@ struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid
  Set the name of a job. Only possible for owner.
 ****************************************************************************/
 
-bool print_job_set_name(const char *sharename, uint32 jobid, const char *name)
+bool print_job_set_name(struct tevent_context *ev,
+                       struct messaging_context *msg_ctx,
+                       const char *sharename, uint32 jobid, const char *name)
 {
        struct printjob *pjob;
 
        pjob = print_job_find(sharename, jobid);
-       if (!pjob || pjob->pid != sys_getpid())
+       if (!pjob || pjob->pid != getpid())
                return False;
 
        fstrcpy(pjob->jobname, name);
-       return pjob_store(sharename, jobid, pjob);
+       return pjob_store(ev, msg_ctx, sharename, jobid, pjob);
 }
 
 /****************************************************************************
@@ -1870,7 +2007,7 @@ bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t job
        struct printjob *pjob;
 
        pjob = print_job_find(sharename, jobid);
-       if (!pjob || pjob->pid != sys_getpid()) {
+       if (!pjob || pjob->pid != getpid()) {
                return false;
        }
 
@@ -1884,10 +2021,10 @@ bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t job
 
 
 /***************************************************************************
- Remove a jobid from the 'jobs changed' list.
+ Remove a jobid from the 'jobs added' list.
 ***************************************************************************/
 
-static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
+static bool remove_from_jobs_added(const char* sharename, uint32 jobid)
 {
        struct tdb_print_db *pdb = get_print_db_byname(sharename);
        TDB_DATA data, key;
@@ -1901,14 +2038,14 @@ static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
 
        ZERO_STRUCT(data);
 
-       key = string_tdb_data("INFO/jobs_changed");
+       key = string_tdb_data("INFO/jobs_added");
 
-       if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
+       if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) != 0)
                goto out;
 
        gotlock = True;
 
-       data = tdb_fetch(pdb->tdb, key);
+       data = tdb_fetch_compat(pdb->tdb, key);
 
        if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
                goto out;
@@ -1922,7 +2059,7 @@ static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
                        if (i < job_count -1 )
                                memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
                        data.dsize -= 4;
-                       if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
+                       if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) != 0)
                                goto out;
                        break;
                }
@@ -1936,9 +2073,9 @@ static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
        SAFE_FREE(data.dptr);
        release_print_db(pdb);
        if (ret)
-               DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
+               DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid ));
        else
-               DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
+               DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid ));
        return ret;
 }
 
@@ -1946,7 +2083,9 @@ static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
  Delete a print job - don't update queue.
 ****************************************************************************/
 
-static bool print_job_delete1(int snum, uint32 jobid)
+static bool print_job_delete1(struct tevent_context *ev,
+                             struct messaging_context *msg_ctx,
+                             int snum, uint32 jobid)
 {
        const char* sharename = lp_const_servicename(snum);
        struct printjob *pjob = print_job_find(sharename, jobid);
@@ -1975,7 +2114,7 @@ static bool print_job_delete1(int snum, uint32 jobid)
        /* Set the tdb entry to be deleting. */
 
        pjob->status = LPQ_DELETING;
-       pjob_store(sharename, jobid, pjob);
+       pjob_store(ev, msg_ctx, sharename, jobid, pjob);
 
        if (pjob->spooled && pjob->sysjob != -1)
        {
@@ -1993,14 +2132,14 @@ static bool print_job_delete1(int snum, uint32 jobid)
 
                        if (!pdb)
                                return False;
-                       pjob_delete(sharename, jobid);
+                       pjob_delete(ev, msg_ctx, sharename, jobid);
                        /* Ensure we keep a rough count of the number of total jobs... */
                        tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
                        release_print_db(pdb);
                }
        }
 
-       remove_from_jobs_changed( sharename, jobid );
+       remove_from_jobs_added( sharename, jobid );
 
        return (result == 0);
 }
@@ -2009,7 +2148,7 @@ static bool print_job_delete1(int snum, uint32 jobid)
  Return true if the current user owns the print job.
 ****************************************************************************/
 
-static bool is_owner(struct auth_serversupplied_info *server_info,
+static bool is_owner(const struct auth_session_info *server_info,
                     const char *servicename,
                     uint32 jobid)
 {
@@ -2018,14 +2157,15 @@ static bool is_owner(struct auth_serversupplied_info *server_info,
        if (!pjob || !server_info)
                return False;
 
-       return strequal(pjob->user, server_info->sanitized_username);
+       return strequal(pjob->user, server_info->unix_info->sanitized_username);
 }
 
 /****************************************************************************
  Delete a print job.
 ****************************************************************************/
 
-WERROR print_job_delete(struct auth_serversupplied_info *server_info,
+WERROR print_job_delete(const struct auth_session_info *server_info,
+                       struct messaging_context *msg_ctx,
                        int snum, uint32_t jobid)
 {
        const char* sharename = lp_const_servicename(snum);
@@ -2039,14 +2179,15 @@ WERROR print_job_delete(struct auth_serversupplied_info *server_info,
           owns their job. */
 
        if (!owner &&
-           !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
+           !print_access_check(server_info, msg_ctx, snum,
+                               JOB_ACCESS_ADMINISTER)) {
                DEBUG(3, ("delete denied by security descriptor\n"));
 
                /* BEGIN_ADMIN_LOG */
                sys_adminlog( LOG_ERR,
                              "Permission denied-- user not allowed to delete, \
 pause, or resume print job. User name: %s. Printer name: %s.",
-                             uidtoname(server_info->utok.uid),
+                             uidtoname(server_info->unix_token->uid),
                              lp_printername(snum) );
                /* END_ADMIN_LOG */
 
@@ -2070,14 +2211,14 @@ pause, or resume print job. User name: %s. Printer name: %s.",
                }
        }
 
-       if (!print_job_delete1(snum, jobid)) {
+       if (!print_job_delete1(server_event_context(), msg_ctx, snum, jobid)) {
                return WERR_ACCESS_DENIED;
        }
 
        /* force update the database and say the delete failed if the
            job still exists */
 
-       print_queue_update(snum, True);
+       print_queue_update(msg_ctx, snum, True);
 
        pjob = print_job_find(sharename, jobid);
        if (pjob && (pjob->status != LPQ_DELETING)) {
@@ -2091,8 +2232,9 @@ pause, or resume print job. User name: %s. Printer name: %s.",
  Pause a job.
 ****************************************************************************/
 
-bool print_job_pause(struct auth_serversupplied_info *server_info, int snum,
-                    uint32 jobid, WERROR *errcode)
+bool print_job_pause(const struct auth_session_info *server_info,
+                    struct messaging_context *msg_ctx,
+                    int snum, uint32 jobid, WERROR *errcode)
 {
        const char* sharename = lp_const_servicename(snum);
        struct printjob *pjob;
@@ -2114,14 +2256,15 @@ bool print_job_pause(struct auth_serversupplied_info *server_info, int snum,
        }
 
        if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
-           !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
+           !print_access_check(server_info, msg_ctx, snum,
+                               JOB_ACCESS_ADMINISTER)) {
                DEBUG(3, ("pause denied by security descriptor\n"));
 
                /* BEGIN_ADMIN_LOG */
                sys_adminlog( LOG_ERR,
                        "Permission denied-- user not allowed to delete, \
 pause, or resume print job. User name: %s. Printer name: %s.",
-                             uidtoname(server_info->utok.uid),
+                             uidtoname(server_info->unix_token->uid),
                              lp_printername(snum) );
                /* END_ADMIN_LOG */
 
@@ -2142,7 +2285,8 @@ pause, or resume print job. User name: %s. Printer name: %s.",
 
        /* Send a printer notify message */
 
-       notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
+       notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
+                         JOB_STATUS_PAUSED);
 
        /* how do we tell if this succeeded? */
 
@@ -2153,8 +2297,9 @@ pause, or resume print job. User name: %s. Printer name: %s.",
  Resume a job.
 ****************************************************************************/
 
-bool print_job_resume(struct auth_serversupplied_info *server_info, int snum,
-                     uint32 jobid, WERROR *errcode)
+bool print_job_resume(const struct auth_session_info *server_info,
+                     struct messaging_context *msg_ctx,
+                     int snum, uint32 jobid, WERROR *errcode)
 {
        const char *sharename = lp_const_servicename(snum);
        struct printjob *pjob;
@@ -2176,7 +2321,8 @@ bool print_job_resume(struct auth_serversupplied_info *server_info, int snum,
        }
 
        if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
-           !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
+           !print_access_check(server_info, msg_ctx, snum,
+                               JOB_ACCESS_ADMINISTER)) {
                DEBUG(3, ("resume denied by security descriptor\n"));
                *errcode = WERR_ACCESS_DENIED;
 
@@ -2184,7 +2330,7 @@ bool print_job_resume(struct auth_serversupplied_info *server_info, int snum,
                sys_adminlog( LOG_ERR,
                         "Permission denied-- user not allowed to delete, \
 pause, or resume print job. User name: %s. Printer name: %s.",
-                             uidtoname(server_info->utok.uid),
+                             uidtoname(server_info->unix_token->uid),
                              lp_printername(snum) );
                /* END_ADMIN_LOG */
                return False;
@@ -2202,7 +2348,8 @@ pause, or resume print job. User name: %s. Printer name: %s.",
 
        /* Send a printer notify message */
 
-       notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
+       notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
+                         JOB_STATUS_QUEUED);
 
        return True;
 }
@@ -2211,7 +2358,9 @@ pause, or resume print job. User name: %s. Printer name: %s.",
  Write to a print file.
 ****************************************************************************/
 
-ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
+ssize_t print_job_write(struct tevent_context *ev,
+                       struct messaging_context *msg_ctx,
+                       int snum, uint32 jobid, const char *buf, size_t size)
 {
        const char* sharename = lp_const_servicename(snum);
        ssize_t return_code;
@@ -2222,7 +2371,7 @@ ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos,
        if (!pjob)
                return -1;
        /* don't allow another process to get this info - it is meaningless */
-       if (pjob->pid != sys_getpid())
+       if (pjob->pid != getpid())
                return -1;
 
        /* if SMBD is spooling this can't be allowed */
@@ -2230,11 +2379,11 @@ ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos,
                return -1;
        }
 
-       return_code = write_data_at_offset(pjob->fd, buf, size, pos);
+       return_code = write_data(pjob->fd, buf, size);
 
        if (return_code>0) {
                pjob->size += size;
-               pjob_store(sharename, jobid, pjob);
+               pjob_store(ev, msg_ctx, sharename, jobid, pjob);
        }
        return return_code;
 }
@@ -2259,7 +2408,7 @@ static int get_queue_status(const char* sharename, print_status_struct *status)
 
        if (status) {
                fstr_sprintf(keystr, "STATUS/%s", sharename);
-               data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
+               data = tdb_fetch_compat(pdb->tdb, string_tdb_data(keystr));
                if (data.dptr) {
                        if (data.dsize == sizeof(print_status_struct))
                                /* this memcpy is ok since the status struct was
@@ -2277,7 +2426,8 @@ static int get_queue_status(const char* sharename, print_status_struct *status)
  Determine the number of jobs in a queue.
 ****************************************************************************/
 
-int print_queue_length(int snum, print_status_struct *pstatus)
+int print_queue_length(struct messaging_context *msg_ctx, int snum,
+                      print_status_struct *pstatus)
 {
        const char* sharename = lp_const_servicename( snum );
        print_status_struct status;
@@ -2287,7 +2437,7 @@ int print_queue_length(int snum, print_status_struct *pstatus)
 
        /* make sure the database is up to date */
        if (print_cache_expired(lp_const_servicename(snum), True))
-               print_queue_update(snum, False);
+               print_queue_update(msg_ctx, snum, False);
 
        /* also fetch the queue status */
        memset(&status, 0, sizeof(status));
@@ -2317,7 +2467,7 @@ static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
                /* Lock the database - only wait 20 seconds. */
                ret = tdb_lock_bystring_with_timeout(pdb->tdb,
                                                     "INFO/nextjob", 20);
-               if (ret == -1) {
+               if (ret != 0) {
                        DEBUG(0, ("allocate_print_jobid: "
                                  "Failed to lock printing database %s\n",
                                  sharename));
@@ -2345,7 +2495,7 @@ static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
                jobid = NEXT_JOBID(jobid);
 
                ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
-               if (ret == -1) {
+               if (ret != 0) {
                        terr = tdb_error(pdb->tdb);
                        DEBUG(3, ("allocate_print_jobid: "
                                  "Failed to store INFO/nextjob.\n"));
@@ -2378,7 +2528,7 @@ static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
                dum.dptr = NULL;
                dum.dsize = 0;
                if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
-                             TDB_INSERT) == -1) {
+                             TDB_INSERT) != 0) {
                        DEBUG(3, ("allocate_print_jobid: "
                                  "jobid (%d) failed to store placeholder.\n",
                                  jobid ));
@@ -2392,10 +2542,10 @@ static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
 }
 
 /***************************************************************************
- Append a jobid to the 'jobs changed' list.
+ Append a jobid to the 'jobs added' list.
 ***************************************************************************/
 
-static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
+static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32 jobid)
 {
        TDB_DATA data;
        uint32 store_jobid;
@@ -2404,9 +2554,9 @@ static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
        data.dptr = (uint8 *)&store_jobid;
        data.dsize = 4;
 
-       DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
+       DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
 
-       return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
+       return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"),
                           data) == 0);
 }
 
@@ -2415,7 +2565,8 @@ static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
  Do all checks needed to determine if we can start a job.
 ***************************************************************************/
 
-static WERROR print_job_checks(struct auth_serversupplied_info *server_info,
+static WERROR print_job_checks(const struct auth_session_info *server_info,
+                              struct messaging_context *msg_ctx,
                               int snum, int *njobs)
 {
        const char *sharename = lp_const_servicename(snum);
@@ -2423,13 +2574,14 @@ static WERROR print_job_checks(struct auth_serversupplied_info *server_info,
        uint64_t minspace;
        int ret;
 
-       if (!print_access_check(server_info, snum, PRINTER_ACCESS_USE)) {
+       if (!print_access_check(server_info, msg_ctx, snum,
+                               PRINTER_ACCESS_USE)) {
                DEBUG(3, ("print_job_checks: "
                          "job start denied by security descriptor\n"));
                return WERR_ACCESS_DENIED;
        }
 
-       if (!print_time_access_check(server_info, sharename)) {
+       if (!print_time_access_check(server_info, msg_ctx, sharename)) {
                DEBUG(3, ("print_job_checks: "
                          "job start denied by time check\n"));
                return WERR_ACCESS_DENIED;
@@ -2454,7 +2606,7 @@ static WERROR print_job_checks(struct auth_serversupplied_info *server_info,
        }
 
        /* Insure the maximum queue size is not violated */
-       *njobs = print_queue_length(snum, NULL);
+       *njobs = print_queue_length(msg_ctx, snum, NULL);
        if (*njobs > lp_maxprintjobs(snum)) {
                DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
                          "larger than max printjobs per queue (%d).\n",
@@ -2539,7 +2691,9 @@ static WERROR print_job_spool_file(int snum, uint32_t jobid,
  Start spooling a job - return the jobid.
 ***************************************************************************/
 
-WERROR print_job_start(struct auth_serversupplied_info *server_info,
+WERROR print_job_start(const struct auth_session_info *server_info,
+                      struct messaging_context *msg_ctx,
+                      const char *clientmachine,
                       int snum, const char *docname, const char *filename,
                       struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
 {
@@ -2557,7 +2711,7 @@ WERROR print_job_start(struct auth_serversupplied_info *server_info,
 
        path = lp_pathname(snum);
 
-       werr = print_job_checks(server_info, snum, &njobs);
+       werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
        if (!W_ERROR_IS_OK(werr)) {
                release_print_db(pdb);
                return werr;
@@ -2576,7 +2730,8 @@ WERROR print_job_start(struct auth_serversupplied_info *server_info,
 
        ZERO_STRUCT(pjob);
 
-       pjob.pid = sys_getpid();
+       pjob.pid = getpid();
+       pjob.jobid = jobid;
        pjob.sysjob = -1;
        pjob.fd = -1;
        pjob.starttime = time(NULL);
@@ -2588,14 +2743,14 @@ WERROR print_job_start(struct auth_serversupplied_info *server_info,
 
        fstrcpy(pjob.jobname, docname);
 
+       fstrcpy(pjob.clientmachine, clientmachine);
+
        fstrcpy(pjob.user, lp_printjob_username(snum));
-       standard_sub_advanced(sharename, server_info->sanitized_username,
-                             path, server_info->utok.gid,
-                             server_info->sanitized_username,
-                             server_info->info3->base.domain.string,
-                             pjob.user, sizeof(pjob.user)-1);
-       /* ensure NULL termination */
-       pjob.user[sizeof(pjob.user)-1] = '\0';
+       standard_sub_advanced(sharename, server_info->unix_info->sanitized_username,
+                             path, server_info->unix_token->gid,
+                             server_info->unix_info->sanitized_username,
+                             server_info->info->domain_name,
+                             pjob.user, sizeof(pjob.user));
 
        fstrcpy(pjob.queuename, lp_const_servicename(snum));
 
@@ -2605,10 +2760,10 @@ WERROR print_job_start(struct auth_serversupplied_info *server_info,
                goto fail;
        }
 
-       pjob_store(sharename, jobid, &pjob);
+       pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob);
 
-       /* Update the 'jobs changed' entry used by print_queue_status. */
-       add_to_jobs_changed(pdb, jobid);
+       /* Update the 'jobs added' entry used by print_queue_status. */
+       add_to_jobs_added(pdb, jobid);
 
        /* Ensure we keep a rough count of the number of total jobs... */
        tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
@@ -2620,7 +2775,7 @@ WERROR print_job_start(struct auth_serversupplied_info *server_info,
 
 fail:
        if (jobid != -1) {
-               pjob_delete(sharename, jobid);
+               pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
        }
 
        release_print_db(pdb);
@@ -2634,7 +2789,8 @@ fail:
  Update the number of pages spooled to jobid
 ****************************************************************************/
 
-void print_job_endpage(int snum, uint32 jobid)
+void print_job_endpage(struct messaging_context *msg_ctx,
+                      int snum, uint32 jobid)
 {
        const char* sharename = lp_const_servicename(snum);
        struct printjob *pjob;
@@ -2643,11 +2799,11 @@ void print_job_endpage(int snum, uint32 jobid)
        if (!pjob)
                return;
        /* don't allow another process to get this info - it is meaningless */
-       if (pjob->pid != sys_getpid())
+       if (pjob->pid != getpid())
                return;
 
        pjob->page_count++;
-       pjob_store(sharename, jobid, pjob);
+       pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
 }
 
 /****************************************************************************
@@ -2656,7 +2812,8 @@ void print_job_endpage(int snum, uint32 jobid)
  error.
 ****************************************************************************/
 
-NTSTATUS print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
+NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
+                      uint32 jobid, enum file_close_type close_type)
 {
        const char* sharename = lp_const_servicename(snum);
        struct printjob *pjob;
@@ -2671,7 +2828,7 @@ NTSTATUS print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
                return NT_STATUS_PRINT_CANCELLED;
        }
 
-       if (pjob->spooled || pjob->pid != sys_getpid()) {
+       if (pjob->spooled || pjob->pid != getpid()) {
                return NT_STATUS_ACCESS_DENIED;
        }
 
@@ -2722,7 +2879,7 @@ NTSTATUS print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
                DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
                        pjob->filename, pjob->size ? "deleted" : "zero length" ));
                unlink(pjob->filename);
-               pjob_delete(sharename, jobid);
+               pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
                return NT_STATUS_OK;
        }
 
@@ -2737,11 +2894,11 @@ NTSTATUS print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
 
        pjob->spooled = True;
        pjob->status = LPQ_QUEUED;
-       pjob_store(sharename, jobid, pjob);
+       pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
 
        /* make sure the database is up to date */
        if (print_cache_expired(lp_const_servicename(snum), True))
-               print_queue_update(snum, False);
+               print_queue_update(msg_ctx, snum, False);
 
        return NT_STATUS_OK;
 
@@ -2751,7 +2908,7 @@ fail:
        /* Still need to add proper error return propagation! 010122:JRR */
        pjob->fd = -1;
        unlink(pjob->filename);
-       pjob_delete(sharename, jobid);
+       pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
        return status;
 }
 
@@ -2759,12 +2916,15 @@ fail:
  Get a snapshot of jobs in the system without traversing.
 ****************************************************************************/
 
-static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
+static bool get_stored_queue_info(struct messaging_context *msg_ctx,
+                                 struct tdb_print_db *pdb, int snum,
+                                 int *pcount, print_queue_struct **ppqueue)
 {
-       TDB_DATA data, cgdata;
+       TDB_DATA data, cgdata, jcdata;
        print_queue_struct *queue = NULL;
        uint32 qcount = 0;
        uint32 extra_count = 0;
+       uint32_t changed_count = 0;
        int total_count = 0;
        size_t len = 0;
        uint32 i;
@@ -2774,7 +2934,7 @@ static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
 
        /* make sure the database is up to date */
        if (print_cache_expired(lp_const_servicename(snum), True))
-               print_queue_update(snum, False);
+               print_queue_update(msg_ctx, snum, False);
 
        *pcount = 0;
        *ppqueue = NULL;
@@ -2783,16 +2943,21 @@ static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
        ZERO_STRUCT(cgdata);
 
        /* Get the stored queue data. */
-       data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
+       data = tdb_fetch_compat(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
 
        if (data.dptr && data.dsize >= sizeof(qcount))
                len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
 
-       /* Get the changed jobs list. */
-       cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
+       /* Get the added jobs list. */
+       cgdata = tdb_fetch_compat(pdb->tdb, string_tdb_data("INFO/jobs_added"));
        if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
                extra_count = cgdata.dsize/4;
 
+       /* Get the changed jobs list. */
+       jcdata = tdb_fetch_compat(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
+       if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0))
+               changed_count = jcdata.dsize / 4;
+
        DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
 
        /* Allocate the queue size. */
@@ -2815,7 +2980,7 @@ static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
                                &qtime,
                                queue[i].fs_user,
                                queue[i].fs_file);
-               queue[i].job = qjob;
+               queue[i].sysjob = qjob;
                queue[i].size = qsize;
                queue[i].page_count = qpage_count;
                queue[i].status = qstatus;
@@ -2825,21 +2990,21 @@ static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
 
        total_count = qcount;
 
-       /* Add in the changed jobids. */
+       /* Add new jobids to the queue. */
        for( i  = 0; i < extra_count; i++) {
                uint32 jobid;
                struct printjob *pjob;
 
                jobid = IVAL(cgdata.dptr, i*4);
-               DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
+               DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid));
                pjob = print_job_find(lp_const_servicename(snum), jobid);
                if (!pjob) {
-                       DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
-                       remove_from_jobs_changed(sharename, jobid);
+                       DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid));
+                       remove_from_jobs_added(sharename, jobid);
                        continue;
                }
 
-               queue[total_count].job = jobid;
+               queue[total_count].sysjob = jobid;
                queue[total_count].size = pjob->size;
                queue[total_count].page_count = pjob->page_count;
                queue[total_count].status = pjob->status;
@@ -2850,6 +3015,50 @@ static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
                total_count++;
        }
 
+       /* Update the changed jobids. */
+       for (i = 0; i < changed_count; i++) {
+               uint32_t jobid = IVAL(jcdata.dptr, i * 4);
+               uint32_t j;
+               bool found = false;
+
+               for (j = 0; j < total_count; j++) {
+                       if (queue[j].sysjob == jobid) {
+                               found = true;
+                               break;
+                       }
+               }
+
+               if (found) {
+                       struct printjob *pjob;
+
+                       DEBUG(5,("get_stored_queue_info: changed job: %u\n",
+                                (unsigned int) jobid));
+
+                       pjob = print_job_find(sharename, jobid);
+                       if (pjob == NULL) {
+                               DEBUG(5,("get_stored_queue_info: failed to find "
+                                        "changed job = %u\n",
+                                        (unsigned int) jobid));
+                               remove_from_jobs_changed(sharename, jobid);
+                               continue;
+                       }
+
+                       queue[j].sysjob = jobid;
+                       queue[j].size = pjob->size;
+                       queue[j].page_count = pjob->page_count;
+                       queue[j].status = pjob->status;
+                       queue[j].priority = 1;
+                       queue[j].time = pjob->starttime;
+                       fstrcpy(queue[j].fs_user, pjob->user);
+                       fstrcpy(queue[j].fs_file, pjob->jobname);
+
+                       DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n",
+                                (unsigned int) j, (unsigned int) jobid, pjob->jobname));
+               }
+
+               remove_from_jobs_changed(sharename, jobid);
+       }
+
        /* Sort the queue by submission time otherwise they are displayed
           in hash order. */
 
@@ -2877,7 +3086,7 @@ static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
  set queue = NULL and status = NULL if you just want to update the cache
 ****************************************************************************/
 
-int print_queue_status(int snum,
+int print_queue_status(struct messaging_context *msg_ctx, int snum,
                       print_queue_struct **ppqueue,
                       print_status_struct *status)
 {
@@ -2890,7 +3099,7 @@ int print_queue_status(int snum,
        /* make sure the database is up to date */
 
        if (print_cache_expired(lp_const_servicename(snum), True))
-               print_queue_update(snum, False);
+               print_queue_update(msg_ctx, snum, False);
 
        /* return if we are done */
        if ( !ppqueue || !status )
@@ -2912,7 +3121,7 @@ int print_queue_status(int snum,
        slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
        key = string_tdb_data(keystr);
 
-       data = tdb_fetch(pdb->tdb, key);
+       data = tdb_fetch_compat(pdb->tdb, key);
        if (data.dptr) {
                if (data.dsize == sizeof(*status)) {
                        /* this memcpy is ok since the status struct was
@@ -2927,7 +3136,7 @@ int print_queue_status(int snum,
         * of entries, and then only retrieve the queue if necessary.
         */
 
-       if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
+       if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
                release_print_db(pdb);
                return 0;
        }
@@ -2940,12 +3149,13 @@ int print_queue_status(int snum,
  Pause a queue.
 ****************************************************************************/
 
-WERROR print_queue_pause(struct auth_serversupplied_info *server_info, int snum)
+WERROR print_queue_pause(const struct auth_session_info *server_info,
+                        struct messaging_context *msg_ctx, int snum)
 {
        int ret;
        struct printif *current_printif = get_printer_fns( snum );
 
-       if (!print_access_check(server_info, snum,
+       if (!print_access_check(server_info, msg_ctx, snum,
                                PRINTER_ACCESS_ADMINISTER)) {
                return WERR_ACCESS_DENIED;
        }
@@ -2966,7 +3176,8 @@ WERROR print_queue_pause(struct auth_serversupplied_info *server_info, int snum)
 
        /* Send a printer notify message */
 
-       notify_printer_status(snum, PRINTER_STATUS_PAUSED);
+       notify_printer_status(server_event_context(), msg_ctx, snum,
+                             PRINTER_STATUS_PAUSED);
 
        return WERR_OK;
 }
@@ -2975,12 +3186,13 @@ WERROR print_queue_pause(struct auth_serversupplied_info *server_info, int snum)
  Resume a queue.
 ****************************************************************************/
 
-WERROR print_queue_resume(struct auth_serversupplied_info *server_info, int snum)
+WERROR print_queue_resume(const struct auth_session_info *server_info,
+                         struct messaging_context *msg_ctx, int snum)
 {
        int ret;
        struct printif *current_printif = get_printer_fns( snum );
 
-       if (!print_access_check(server_info, snum,
+       if (!print_access_check(server_info, msg_ctx, snum,
                                PRINTER_ACCESS_ADMINISTER)) {
                return WERR_ACCESS_DENIED;
        }
@@ -2997,11 +3209,12 @@ WERROR print_queue_resume(struct auth_serversupplied_info *server_info, int snum
 
        /* make sure the database is up to date */
        if (print_cache_expired(lp_const_servicename(snum), True))
-               print_queue_update(snum, True);
+               print_queue_update(msg_ctx, snum, True);
 
        /* Send a printer notify message */
 
-       notify_printer_status(snum, PRINTER_STATUS_OK);
+       notify_printer_status(server_event_context(), msg_ctx, snum,
+                             PRINTER_STATUS_OK);
 
        return WERR_OK;
 }
@@ -3010,7 +3223,8 @@ WERROR print_queue_resume(struct auth_serversupplied_info *server_info, int snum
  Purge a queue - implemented by deleting all jobs that we can delete.
 ****************************************************************************/
 
-WERROR print_queue_purge(struct auth_serversupplied_info *server_info, int snum)
+WERROR print_queue_purge(const struct auth_session_info *server_info,
+                        struct messaging_context *msg_ctx, int snum)
 {
        print_queue_struct *queue;
        print_status_struct status;
@@ -3018,21 +3232,24 @@ WERROR print_queue_purge(struct auth_serversupplied_info *server_info, int snum)
        bool can_job_admin;
 
        /* Force and update so the count is accurate (i.e. not a cached count) */
-       print_queue_update(snum, True);
+       print_queue_update(msg_ctx, snum, True);
 
-       can_job_admin = print_access_check(server_info, snum,
+       can_job_admin = print_access_check(server_info,
+                                          msg_ctx,
+                                          snum,
                                           JOB_ACCESS_ADMINISTER);
-       njobs = print_queue_status(snum, &queue, &status);
+       njobs = print_queue_status(msg_ctx, snum, &queue, &status);
 
        if ( can_job_admin )
                become_root();
 
        for (i=0;i<njobs;i++) {
                bool owner = is_owner(server_info, lp_const_servicename(snum),
-                                     queue[i].job);
+                                     queue[i].sysjob);
 
                if (owner || can_job_admin) {
-                       print_job_delete1(snum, queue[i].job);
+                       print_job_delete1(server_event_context(), msg_ctx,
+                                         snum, queue[i].sysjob);
                }
        }
 
@@ -3040,7 +3257,7 @@ WERROR print_queue_purge(struct auth_serversupplied_info *server_info, int snum)
                unbecome_root();
 
        /* update the cache */
-       print_queue_update( snum, True );
+       print_queue_update(msg_ctx, snum, True);
 
        SAFE_FREE(queue);