From 4ff64f69706cc94d5dba7762754d00790c476963 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Jul 2002 19:12:17 +0000 Subject: [PATCH] Gone back to explicit queue number passing as snum - removed encoding of queueid in job number. This means we must have an internal tdb to store mapping from 16 bit RAP jobid's to 32 bit RPC jobids. Jeremy. --- source/param/loadparm.c | 4 - source/printing/printfsp.c | 6 +- source/printing/printing.c | 367 ++++++++++------------------- source/rpc_server/srv_spoolss_nt.c | 31 ++- source/smbd/fileio.c | 2 +- source/smbd/lanman.c | 33 +-- source/smbd/reply.c | 5 +- source/smbd/server.c | 2 - source/smbd/trans2.c | 7 +- 9 files changed, 170 insertions(+), 287 deletions(-) diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 37f8bb3ca48..0602e901a41 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -1974,8 +1974,6 @@ static BOOL lp_add_ipc(char *ipc_name, BOOL guest_ok) return (True); } -BOOL (*register_printer_fn)(const char *); - /*************************************************************************** add a new printer service, with defaults coming from service iFrom. ***************************************************************************/ @@ -2008,8 +2006,6 @@ BOOL lp_add_printer(char *pszPrintername, int iDefaultService) DEBUG(3, ("adding printer service %s\n", pszPrintername)); update_server_announce_as_printserver(); - if (register_printer_fn && (!(*register_printer_fn)(pszPrintername))) - return False; return (True); } diff --git a/source/printing/printfsp.c b/source/printing/printfsp.c index 9f33d57ad52..ff50ac47c49 100644 --- a/source/printing/printfsp.c +++ b/source/printing/printfsp.c @@ -54,7 +54,7 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname) /* setup a full fsp */ fsp->print_jobid = jobid; - fsp->fd = print_job_fd(jobid); + fsp->fd = print_job_fd(SNUM(conn),jobid); GetTimeOfDay(&fsp->open_time); fsp->vuid = current_user.vuid; fsp->size = 0; @@ -70,7 +70,7 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname) fsp->is_directory = False; fsp->directory_delete_on_close = False; fsp->conn = conn; - string_set(&fsp->fsp_name,print_job_fname(jobid)); + string_set(&fsp->fsp_name,print_job_fname(SNUM(conn),jobid)); fsp->wbmpx_ptr = NULL; fsp->wcp = NULL; conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf); @@ -96,7 +96,7 @@ void print_fsp_end(files_struct *fsp, BOOL normal_close) sys_ftruncate(fsp->fd, 0); } - print_job_end(fsp->print_jobid, normal_close); + print_job_end(SNUM(fsp->conn),fsp->print_jobid, normal_close); if (fsp->fsp_name) { string_free(&fsp->fsp_name); diff --git a/source/printing/printing.c b/source/printing/printing.c index f8dfea0a126..9b0e8cdfb0a 100644 --- a/source/printing/printing.c +++ b/source/printing/printing.c @@ -47,10 +47,11 @@ static struct printif *current_printif = &generic_printif; static TDB_CONTEXT *rap_tdb; static uint16 next_rap_jobid; -uint16 pjobid_to_rap(uint32 jobid) +uint16 pjobid_to_rap(int snum, uint32 jobid) { uint16 rap_jobid; TDB_DATA data, key; + char jinfo[8]; if (!rap_tdb) { /* Create the in-memory tdb. */ @@ -59,8 +60,11 @@ uint16 pjobid_to_rap(uint32 jobid) return 0; } - key.dptr = (char *)&jobid; - key.dsize = sizeof(jobid); + SIVAL(&jinfo,0,(int32)snum); + SIVAL(&jinfo,4,jobid); + + key.dptr = (char *)&jinfo; + key.dsize = sizeof(jinfo); data = tdb_fetch(rap_tdb, key); if (data.dptr && data.dsize == sizeof(uint16)) { memcpy(&rap_jobid, data.dptr, sizeof(uint16)); @@ -78,33 +82,40 @@ uint16 pjobid_to_rap(uint32 jobid) return rap_jobid; } -uint32 rap_to_pjobid(uint16 rap_jobid) +BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid) { TDB_DATA data, key; - uint32 jobid = 0; + char jinfo[8]; if (!rap_tdb) - return 0; + return False; key.dptr = (char *)&rap_jobid; key.dsize = sizeof(rap_jobid); data = tdb_fetch(rap_tdb, key); - if (data.dptr && data.dsize == sizeof(uint32)) { - memcpy(&jobid, data.dptr, sizeof(uint32)); + if (data.dptr && data.dsize == sizeof(jinfo)) { + *psnum = IVAL(&jinfo,0); + *pjobid = IVAL(&jinfo,4); SAFE_FREE(data.dptr); + return True; } - return jobid; + return False; } -static void rap_jobid_delete(uint32 jobid) +static void rap_jobid_delete(int snum, uint32 jobid) { TDB_DATA key, data; uint16 rap_jobid; + char jinfo[8]; if (!rap_tdb) return; - key.dptr = (char *)&jobid; - key.dsize = sizeof(jobid); + + SIVAL(&jinfo,0,(int32)snum); + SIVAL(&jinfo,4,jobid); + + key.dptr = (char *)&jinfo; + key.dsize = sizeof(jinfo); data = tdb_fetch(rap_tdb, key); if (!data.dptr || (data.dsize != sizeof(uint16))) return; @@ -119,96 +130,6 @@ static void rap_jobid_delete(uint32 jobid) static pid_t local_pid; -/* Mapping between printer names and queue id's in job id's. */ -struct printer_queueid_map { - struct printer_queueid_map *next, *prev; - char *printername; - uint32 queueid; -}; - -static struct printer_queueid_map *printer_queueid_map_head; -static uint32 last_queueid; - -#define QUEUEID_BITS 12 -#define QUEUEID_MASK ((1<<(QUEUEID_BITS))-1) -#define QUEUEID_TO_JOBID(queueid) (((queueid) & QUEUEID_MASK) << 20 ) - -/**************************************************************************** - Create an association between a printer name and a queueid. Used to encode - the printer queueid in jobid's. - This could be converted to use an internal tdb if searching the list is - too slow. JRA. -****************************************************************************/ - -BOOL create_printer_queueid(const char *printername) -{ - struct printer_queueid_map *p; - - for (p = printer_queueid_map_head; p; p = p->next) { - if (strequal(p->printername, printername)) - return True; - } - - p = (struct printer_queueid_map *)malloc(sizeof(*p)); - if (!p) { - DEBUG(0,("create_printer_queueid: malloc fail !\n")); - return False; - } - ZERO_STRUCTP(p); - p->printername = strdup(printername); - if (!p->printername) { - DEBUG(0,("create_printer_queueid: malloc fail !\n")); - SAFE_FREE(p); - return False; - } - p->queueid = (++last_queueid); - if (p->queueid > QUEUEID_MASK) { - DEBUG(0,("create_printer_queueid: malloc fail !\n")); - SAFE_FREE(p->printername); - SAFE_FREE(p); - return False; - } - DLIST_ADD(printer_queueid_map_head, p); - return True; -} - -void set_register_printer_fn(void) -{ - extern BOOL (*register_printer_fn)(const char *); - register_printer_fn = create_printer_queueid; -} - -/**************************************************************************** - Lookups. -****************************************************************************/ - -static uint32 get_printer_queueid_byname(const char *printername) -{ - struct printer_queueid_map *p; - - for (p = printer_queueid_map_head; p; p = p->next) { - if (strequal(p->printername, printername)) - return p->queueid; - } - return 0; -} - -/**************************************************************************** - Lookups. -****************************************************************************/ - -static const char *get_printer_name_byjobid(uint32 jobid) -{ - struct printer_queueid_map *p; - uint32 queueid = (((jobid)>>20) & QUEUEID_MASK); - - for (p = printer_queueid_map_head; p; p = p->next) { - if (p->queueid == queueid) - return p->printername; - } - return NULL; -} - static int get_queue_status(int, print_status_struct *); #define MAX_PRINT_DBS_OPEN 1 @@ -279,14 +200,6 @@ static struct tdb_print_db *get_print_db_byname(const char *printername) return p; } -static struct tdb_print_db *get_print_db_byjobid( uint32 jobid) -{ - const char *printername = get_printer_name_byjobid(jobid); - if (!printername) - return NULL; - return get_print_db_byname(printername); -} - /**************************************************************************** Initialise the printing backend. Called once at startup. Does not survive a fork @@ -294,9 +207,10 @@ static struct tdb_print_db *get_print_db_byjobid( uint32 jobid) BOOL print_backend_init(void) { - struct printer_queueid_map *p; char *sversion = "INFO/version"; pstring printing_path; + int services = lp_numservices(); + int snum; if (local_pid == sys_getpid()) return True; @@ -309,9 +223,12 @@ BOOL print_backend_init(void) /* handle a Samba upgrade */ - for (p = printer_queueid_map_head; p; p = p->next) { - struct tdb_print_db *pdb = get_print_db_byname(p->printername); + for (snum = 0; snum < services; snum++) { + struct tdb_print_db *pdb; + if (!lp_print_ok(snum)) + continue; + pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) continue; tdb_lock_bystring(pdb->tdb, sversion); @@ -369,11 +286,11 @@ static TDB_DATA print_key(uint32 jobid) Useful function to find a print job in the database. ****************************************************************************/ -static struct printjob *print_job_find(uint32 jobid) +static struct printjob *print_job_find(int snum, uint32 jobid) { static struct printjob pjob; TDB_DATA ret; - struct tdb_print_db *pdb = get_print_db_byjobid(jobid); + struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) return NULL; @@ -417,11 +334,16 @@ static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, uint32 sysjob_to_jobid(int unix_jobid) { - struct printer_queueid_map *p; + int services = lp_numservices(); + int snum; + sysjob_to_jobid_value = (uint32)-1; - for (p = printer_queueid_map_head; p; p = p->next) { - struct tdb_print_db *pdb = get_print_db_byname(p->printername); + for (snum = 0; snum < services; snum++) { + struct tdb_print_db *pdb; + if (!lp_print_ok(snum)) + continue; + pdb = get_print_db_byname(lp_const_servicename(snum)); if (pdb) tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid); if (sysjob_to_jobid_value != (uint32)-1) @@ -468,14 +390,10 @@ static uint32 map_to_spoolss_status(uint32 lpq_status) return 0; } -static void pjob_store_notify(uint32 jobid, struct printjob *old_data, +static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data, struct printjob *new_data) { BOOL new_job = False; - int snum = print_job_snum(jobid); - - if (snum == -1) - return; if (!old_data) new_job = True; @@ -510,11 +428,11 @@ static void pjob_store_notify(uint32 jobid, struct printjob *old_data, Store a job structure back to the database. ****************************************************************************/ -static BOOL pjob_store(uint32 jobid, struct printjob *pjob) +static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob) { TDB_DATA old_data, new_data; BOOL ret; - struct tdb_print_db *pdb = get_print_db_byjobid(jobid); + struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) return False; @@ -533,7 +451,7 @@ static BOOL pjob_store(uint32 jobid, struct printjob *pjob) if (ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob))) { pjob_store_notify( - jobid, (struct printjob *)old_data.dptr, + snum, jobid, (struct printjob *)old_data.dptr, (struct printjob *)new_data.dptr); free(old_data.dptr); } @@ -545,12 +463,11 @@ static BOOL pjob_store(uint32 jobid, struct printjob *pjob) Remove a job structure from the database. ****************************************************************************/ -static void pjob_delete(uint32 jobid) +static void pjob_delete(int snum, uint32 jobid) { - int snum; - struct printjob *pjob = print_job_find(jobid); + struct printjob *pjob = print_job_find(snum, jobid); uint32 job_status = 0; - struct tdb_print_db *pdb = get_print_db_byjobid(jobid); + struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) return; @@ -569,7 +486,6 @@ static void pjob_delete(uint32 jobid) JOB_STATUS_DELETED for the port monitor to delete the job properly. */ - snum = print_job_snum(jobid); job_status |= JOB_STATUS_DELETING; notify_job_status(snum, jobid, job_status); @@ -579,7 +495,7 @@ static void pjob_delete(uint32 jobid) /* Remove from printing.tdb */ tdb_delete(pdb->tdb, print_key(jobid)); - rap_jobid_delete(jobid); + rap_jobid_delete(snum, jobid); } /**************************************************************************** @@ -607,13 +523,12 @@ static uint32 print_parse_jobid(char *fname) static void print_unix_job(int snum, print_queue_struct *q) { - uint32 queueid = get_printer_queueid_byname(PRINTERNAME(snum)); - uint32 jobid = (q->job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid); + uint32 jobid = q->job + UNIX_JOB_START; struct printjob pj, *old_pj; /* Preserve the timestamp on an existing unix print job */ - old_pj = print_job_find(jobid); + old_pj = print_job_find(snum, jobid); ZERO_STRUCT(pj); @@ -630,7 +545,7 @@ static void print_unix_job(int snum, print_queue_struct *q) fstrcpy(pj.user, q->fs_user); fstrcpy(pj.queuename, lp_const_servicename(snum)); - pjob_store(jobid, &pj); + pjob_store(snum, jobid, &pj); } @@ -645,7 +560,6 @@ struct traverse_struct { static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state) { - uint32 queueid; struct traverse_struct *ts = (struct traverse_struct *)state; struct printjob pjob; uint32 jobid; @@ -661,18 +575,16 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void return 0; } - queueid = get_printer_queueid_byname(pjob.queuename); - if (!pjob.smbjob) { /* remove a unix job if it isn't in the system queue any more */ for (i=0;iqcount;i++) { - uint32 u_jobid = ((ts->queue[i].job + UNIX_JOB_START) | QUEUEID_TO_JOBID(queueid)); + uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START); if (jobid == u_jobid) break; } if (i == ts->qcount) - pjob_delete(jobid); + pjob_delete(ts->snum, jobid); else ts->total_jobs++; return 0; @@ -684,14 +596,14 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void exist then kill it. This cleans up after smbd deaths */ if (!process_exists(pjob.pid)) - pjob_delete(jobid); + pjob_delete(ts->snum, jobid); else ts->total_jobs++; return 0; } for (i=0;iqcount;i++) { - uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file) | QUEUEID_TO_JOBID(queueid); + uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file); if (jobid == curr_jobid) break; } @@ -711,7 +623,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void submitted less than lp_lpqcachetime() seconds ago. */ if ((cur_t - pjob.starttime) > lp_lpqcachetime()) - pjob_delete(jobid); + pjob_delete(ts->snum, jobid); else ts->total_jobs++; } @@ -772,7 +684,7 @@ static pid_t get_updating_pid(fstring printer_name) in the tdb. ****************************************************************************/ -static void set_updating_pid(fstring printer_name, BOOL delete) +static void set_updating_pid(const fstring printer_name, BOOL delete) { fstring keystr; TDB_DATA key; @@ -897,7 +809,7 @@ static void print_queue_update(int snum) } /* we have an active SMB print job - update its status */ - pjob = print_job_find(jobid); + pjob = print_job_find(snum, jobid); if (!pjob) { /* err, somethings wrong. Probably smbd was restarted with jobs in the queue. All we can do is treat them @@ -909,7 +821,7 @@ static void print_queue_update(int snum) pjob->sysjob = queue[i].job; pjob->status = queue[i].status; - pjob_store(jobid, pjob); + pjob_store(snum, jobid, pjob); } /* now delete any queued entries that don't appear in the @@ -955,36 +867,21 @@ static void print_queue_update(int snum) Check if a jobid is valid. It is valid if it exists in the database. ****************************************************************************/ -BOOL print_job_exists(uint32 jobid) +BOOL print_job_exists(int snum, uint32 jobid) { - struct tdb_print_db *pdb = get_print_db_byjobid(jobid); + struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) return False; return tdb_exists(pdb->tdb, print_key(jobid)); } -/**************************************************************************** - Work out which service a jobid is for. - Note that we have to look up by queue name to ensure that it works for - other than the process that started the job. -****************************************************************************/ - -int print_job_snum(uint32 jobid) -{ - struct printjob *pjob = print_job_find(jobid); - if (!pjob) - return -1; - - return find_service(pjob->queuename); -} - /**************************************************************************** Give the fd used for a jobid. ****************************************************************************/ -int print_job_fd(uint32 jobid) +int print_job_fd(int snum, uint32 jobid) { - struct printjob *pjob = print_job_find(jobid); + struct printjob *pjob = print_job_find(snum, jobid); if (!pjob) return -1; /* don't allow another process to get this info - it is meaningless */ @@ -999,9 +896,9 @@ int print_job_fd(uint32 jobid) has not been spooled. ****************************************************************************/ -char *print_job_fname(uint32 jobid) +char *print_job_fname(int snum, uint32 jobid) { - struct printjob *pjob = print_job_find(jobid); + struct printjob *pjob = print_job_find(snum, jobid); if (!pjob || pjob->spooled || pjob->pid != local_pid) return NULL; return pjob->filename; @@ -1011,7 +908,7 @@ char *print_job_fname(uint32 jobid) Set the place in the queue for a job. ****************************************************************************/ -BOOL print_job_set_place(uint32 jobid, int place) +BOOL print_job_set_place(int snum, uint32 jobid, int place) { DEBUG(2,("print_job_set_place not implemented yet\n")); return False; @@ -1021,24 +918,24 @@ BOOL print_job_set_place(uint32 jobid, int place) Set the name of a job. Only possible for owner. ****************************************************************************/ -BOOL print_job_set_name(uint32 jobid, char *name) +BOOL print_job_set_name(int snum, uint32 jobid, char *name) { - struct printjob *pjob = print_job_find(jobid); + struct printjob *pjob = print_job_find(snum, jobid); if (!pjob || pjob->pid != local_pid) return False; fstrcpy(pjob->jobname, name); - return pjob_store(jobid, pjob); + return pjob_store(snum, jobid, pjob); } /**************************************************************************** Delete a print job - don't update queue. ****************************************************************************/ -static BOOL print_job_delete1(uint32 jobid) +static BOOL print_job_delete1(int snum, uint32 jobid) { - struct printjob *pjob = print_job_find(jobid); - int snum, result = 0; + struct printjob *pjob = print_job_find(snum, jobid); + int result = 0; if (!pjob) return False; @@ -1050,12 +947,6 @@ static BOOL print_job_delete1(uint32 jobid) if (pjob->status == LPQ_DELETING) return True; - snum = print_job_snum(jobid); - if (snum == -1) { - DEBUG(5,("print_job_delete1: unknown service number for jobid %u\n", (unsigned int)jobid)); - return False; - } - /* Hrm - we need to be able to cope with deleting a job before it has reached the spooler. */ @@ -1066,7 +957,7 @@ static BOOL print_job_delete1(uint32 jobid) /* Set the tdb entry to be deleting. */ pjob->status = LPQ_DELETING; - pjob_store(jobid, pjob); + pjob_store(snum, jobid, pjob); if (pjob->spooled && pjob->sysjob != -1) result = (*(current_printif->job_delete))(snum, pjob); @@ -1075,7 +966,7 @@ static BOOL print_job_delete1(uint32 jobid) been spooled. */ if (result == 0) - pjob_delete(jobid); + pjob_delete(snum, jobid); return (result == 0); } @@ -1084,9 +975,9 @@ static BOOL print_job_delete1(uint32 jobid) Return true if the current user owns the print job. ****************************************************************************/ -static BOOL is_owner(struct current_user *user, uint32 jobid) +static BOOL is_owner(struct current_user *user, int snum, uint32 jobid) { - struct printjob *pjob = print_job_find(jobid); + struct printjob *pjob = print_job_find(snum, jobid); user_struct *vuser; if (!pjob || !user) @@ -1103,17 +994,11 @@ static BOOL is_owner(struct current_user *user, uint32 jobid) Delete a print job. ****************************************************************************/ -BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode) +BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { - int snum = print_job_snum(jobid); BOOL owner; - if (snum == -1) { - DEBUG(5,("print_job_delete: unknown service number for jobid %d\n", jobid)); - return False; - } - - owner = is_owner(user, jobid); + owner = is_owner(user, snum, jobid); /* Check access against security descriptor or whether the user owns their job. */ @@ -1125,7 +1010,7 @@ BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode) return False; } - if (!print_job_delete1(jobid)) + if (!print_job_delete1(snum, jobid)) return False; /* force update the database and say the delete failed if the @@ -1133,17 +1018,17 @@ BOOL print_job_delete(struct current_user *user, uint32 jobid, WERROR *errcode) print_queue_update(snum); - return !print_job_exists(jobid); + return !print_job_exists(snum, jobid); } /**************************************************************************** Pause a job. ****************************************************************************/ -BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode) +BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { - struct printjob *pjob = print_job_find(jobid); - int snum, ret = -1; + struct printjob *pjob = print_job_find(snum, jobid); + int ret = -1; if (!pjob || !user) return False; @@ -1151,13 +1036,7 @@ BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode) if (!pjob->spooled || pjob->sysjob == -1) return False; - snum = print_job_snum(jobid); - if (snum == -1) { - DEBUG(5,("print_job_pause: unknown service number for jobid %u\n", (unsigned int)jobid)); - return False; - } - - if (!is_owner(user, jobid) && + if (!is_owner(user, snum, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("pause denied by security descriptor\n")); *errcode = WERR_ACCESS_DENIED; @@ -1188,10 +1067,10 @@ BOOL print_job_pause(struct current_user *user, uint32 jobid, WERROR *errcode) Resume a job. ****************************************************************************/ -BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode) +BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode) { - struct printjob *pjob = print_job_find(jobid); - int snum, ret; + struct printjob *pjob = print_job_find(snum, jobid); + int ret; if (!pjob || !user) return False; @@ -1199,13 +1078,7 @@ BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode) if (!pjob->spooled || pjob->sysjob == -1) return False; - snum = print_job_snum(jobid); - if (snum == -1) { - DEBUG(5,("print_job_resume: unknown service number for jobid %u\n", (unsigned int)jobid)); - return False; - } - - if (!is_owner(user, jobid) && + if (!is_owner(user, snum, jobid) && !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) { DEBUG(3, ("resume denied by security descriptor\n")); *errcode = WERR_ACCESS_DENIED; @@ -1233,10 +1106,10 @@ BOOL print_job_resume(struct current_user *user, uint32 jobid, WERROR *errcode) Write to a print file. ****************************************************************************/ -int print_job_write(uint32 jobid, const char *buf, int size) +int print_job_write(int snum, uint32 jobid, const char *buf, int size) { int return_code; - struct printjob *pjob = print_job_find(jobid); + struct printjob *pjob = print_job_find(snum, jobid); if (!pjob) return -1; @@ -1247,7 +1120,7 @@ int print_job_write(uint32 jobid, const char *buf, int size) return_code = write(pjob->fd, buf, size); if (return_code>0) { pjob->size += size; - pjob_store(jobid, pjob); + pjob_store(snum, jobid, pjob); } return return_code; } @@ -1345,17 +1218,23 @@ int print_queue_length(int snum, print_status_struct *pstatus) static int get_total_jobs(void) { int total_jobs; - struct printer_queueid_map *p; + int snum; + int services = lp_numservices(); - for (p = printer_queueid_map_head; p; p = p->next) { + for (snum = 0; snum < services; snum++) { + struct tdb_print_db *pdb; int jobs; - struct tdb_print_db *pdb = get_print_db_byname(p->printername); + + if (!lp_print_ok(snum)) + continue; + + pdb = get_print_db_byname(lp_const_servicename(snum)); if (!pdb) continue; /* make sure the database is up to date */ - if (print_cache_expired(lp_servicenumber(p->printername))) - print_queue_update(lp_servicenumber(p->printername)); + if (print_cache_expired(snum)) + print_queue_update(snum); jobs = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs"); if (jobs > 0) @@ -1378,7 +1257,6 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) int njobs = 0; const char *printername = lp_const_servicename(snum); struct tdb_print_db *pdb = get_print_db_byname(printername); - uint32 queueid = queueid = get_printer_queueid_byname(printername); errno = 0; @@ -1460,10 +1338,10 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) next_jobid = 1; for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) { - if (!print_job_exists(jobid | QUEUEID_TO_JOBID(queueid))) + if (!print_job_exists(snum, jobid)) break; } - if (jobid == next_jobid || !pjob_store(jobid | QUEUEID_TO_JOBID(queueid), &pjob)) { + if (jobid == next_jobid || !pjob_store(snum, jobid, &pjob)) { DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or pjob_store failed.\n", jobid, next_jobid )); jobid = -1; @@ -1476,9 +1354,6 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname) goto fail; } - /* Ensure the queuid is added to the jobid. */ - jobid |= QUEUEID_TO_JOBID(queueid); - /* we have a job entry - now create the spool file */ slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", path, PRINT_SPOOL_PREFIX, (unsigned int)jobid); @@ -1497,7 +1372,7 @@ to open spool file %s.\n", pjob.filename)); goto fail; } - pjob_store(jobid, &pjob); + pjob_store(snum, jobid, &pjob); tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); @@ -1509,14 +1384,14 @@ to open spool file %s.\n", pjob.filename)); * tim@fsg.com 09/06/94 */ if (lp_postscript(snum)) { - print_job_write(jobid, "%!\n",3); + print_job_write(snum, jobid, "%!\n",3); } return jobid; fail: if (jobid != -1) - pjob_delete(jobid); + pjob_delete(snum, jobid); tdb_unlock_bystring(pdb->tdb, "INFO/nextjob"); @@ -1528,9 +1403,9 @@ to open spool file %s.\n", pjob.filename)); Update the number of pages spooled to jobid ****************************************************************************/ -void print_job_endpage(uint32 jobid) +void print_job_endpage(int snum, uint32 jobid) { - struct printjob *pjob = print_job_find(jobid); + struct printjob *pjob = print_job_find(snum, jobid); if (!pjob) return; /* don't allow another process to get this info - it is meaningless */ @@ -1538,7 +1413,7 @@ void print_job_endpage(uint32 jobid) return; pjob->page_count++; - pjob_store(jobid, pjob); + pjob_store(snum, jobid, pjob); } /**************************************************************************** @@ -1547,10 +1422,10 @@ void print_job_endpage(uint32 jobid) error. ****************************************************************************/ -BOOL print_job_end(uint32 jobid, BOOL normal_close) +BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close) { - struct printjob *pjob = print_job_find(jobid); - int snum, ret; + struct printjob *pjob = print_job_find(snum, jobid); + int ret; SMB_STRUCT_STAT sbuf; if (!pjob) @@ -1559,12 +1434,6 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close) if (pjob->spooled || pjob->pid != local_pid) return False; - snum = print_job_snum(jobid); - if (snum == -1) { - DEBUG(5,("print_job_end: unknown service number for jobid %u\n", (unsigned int)jobid)); - return False; - } - if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) { pjob->size = sbuf.st_size; close(pjob->fd); @@ -1589,7 +1458,7 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close) DEBUG(5,("print_job_end: canceling spool of %s (%s)\n", pjob->filename, pjob->size ? "deleted" : "zero length" )); unlink(pjob->filename); - pjob_delete(jobid); + pjob_delete(snum, jobid); return True; } @@ -1602,7 +1471,7 @@ BOOL print_job_end(uint32 jobid, BOOL normal_close) pjob->spooled = True; pjob->status = LPQ_QUEUED; - pjob_store(jobid, pjob); + pjob_store(snum, jobid, pjob); /* make sure the database is up to date */ if (print_cache_expired(snum)) @@ -1615,7 +1484,7 @@ fail: /* The print job was not succesfully started. Cleanup */ /* Still need to add proper error return propagation! 010122:JRR */ unlink(pjob->filename); - pjob_delete(jobid); + pjob_delete(snum, jobid); return False; } @@ -1877,10 +1746,10 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode) njobs = print_queue_status(snum, &queue, &status); for (i=0;idocument_started=False; - print_job_end(Printer->jobid,True); + print_job_end(snum, Printer->jobid,True); /* error codes unhandled so far ... */ return WERR_OK; @@ -4793,6 +4797,7 @@ WERROR _spoolss_startpageprinter(pipes_struct *p, SPOOL_Q_STARTPAGEPRINTER *q_u, WERROR _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPOOL_R_ENDPAGEPRINTER *r_u) { POLICY_HND *handle = &q_u->handle; + int snum; Printer_entry *Printer = find_printer_index_by_hnd(p, handle); @@ -4801,8 +4806,11 @@ WERROR _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPO return WERR_BADFID; } + if (!get_printer_snum(p, handle, &snum)) + return WERR_BADFID; + Printer->page_started=False; - print_job_endpage(Printer->jobid); + print_job_endpage(snum, Printer->jobid); return WERR_OK; } @@ -4819,7 +4827,6 @@ WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S /* uint32 level = q_u->doc_info_container.level; - notused. */ DOC_INFO *docinfo = &q_u->doc_info_container.docinfo; uint32 *jobid = &r_u->jobid; - DOC_INFO_1 *info_1 = &docinfo->doc_info_1; int snum; pstring jobname; @@ -4898,7 +4905,7 @@ WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R uint32 buffer_size = q_u->buffer_size; uint8 *buffer = q_u->buffer; uint32 *buffer_written = &q_u->buffer_size2; - + int snum; Printer_entry *Printer = find_printer_index_by_hnd(p, handle); if (!Printer) { @@ -4907,8 +4914,10 @@ WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R return WERR_BADFID; } - (*buffer_written) = print_job_write(Printer->jobid, (char *)buffer, buffer_size); + if (!get_printer_snum(p, handle, &snum)) + return WERR_BADFID; + (*buffer_written) = print_job_write(snum, Printer->jobid, (char *)buffer, buffer_size); r_u->buffer_written = q_u->buffer_size2; @@ -5907,7 +5916,7 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u return WERR_BADFID; } - if (!print_job_exists(jobid)) { + if (!print_job_exists(snum, jobid)) { return WERR_INVALID_PRINTER_NAME; } @@ -5916,18 +5925,18 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u switch (command) { case JOB_CONTROL_CANCEL: case JOB_CONTROL_DELETE: - if (print_job_delete(&user, jobid, &errcode)) { + if (print_job_delete(&user, snum, jobid, &errcode)) { errcode = WERR_OK; } break; case JOB_CONTROL_PAUSE: - if (print_job_pause(&user, jobid, &errcode)) { + if (print_job_pause(&user, snum, jobid, &errcode)) { errcode = WERR_OK; } break; case JOB_CONTROL_RESTART: case JOB_CONTROL_RESUME: - if (print_job_resume(&user, jobid, &errcode)) { + if (print_job_resume(&user, snum, jobid, &errcode)) { errcode = WERR_OK; } break; diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c index 710ba396d8d..89f05092b45 100644 --- a/source/smbd/fileio.c +++ b/source/smbd/fileio.c @@ -163,7 +163,7 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n) int write_path = -1; if (fsp->print_file) - return print_job_write(fsp->print_jobid, data, n); + return print_job_write(SNUM(fsp->conn), fsp->print_jobid, data, n); if (!fsp->can_write) { errno = EPERM; diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c index 619ecd736aa..049dae98e3f 100644 --- a/source/smbd/lanman.c +++ b/source/smbd/lanman.c @@ -443,7 +443,7 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel, /* the client expects localtime */ t -= TimeDiff(t); - PACKI(desc,"W",pjobid_to_rap(queue->job)); /* uJobId */ + PACKI(desc,"W",pjobid_to_rap(snum,queue->job)); /* uJobId */ if (uLevel == 1) { PACKS(desc,"B21",queue->fs_user); /* szUserName */ PACKS(desc,"B",""); /* pad */ @@ -2181,11 +2181,14 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param char *str1 = param+2; char *str2 = skip_string(str1,1); char *p = skip_string(str2,1); - int jobid, errcode; + uint32 jobid; + int snum; + int errcode; extern struct current_user current_user; WERROR werr = WERR_OK; - jobid = rap_to_pjobid(SVAL(p,0)); + if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid)) + return False; /* check it's a supported varient */ if (!(strcsequal(str1,"W") && strcsequal(str2,""))) @@ -2195,7 +2198,7 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param *rparam = REALLOC(*rparam,*rparam_len); *rdata_len = 0; - if (!print_job_exists(jobid)) { + if (!print_job_exists(snum, jobid)) { errcode = NERR_JobNotFound; goto out; } @@ -2204,15 +2207,15 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param switch (function) { case 81: /* delete */ - if (print_job_delete(¤t_user, jobid, &werr)) + if (print_job_delete(¤t_user, snum, jobid, &werr)) errcode = NERR_Success; break; case 82: /* pause */ - if (print_job_pause(¤t_user, jobid, &werr)) + if (print_job_pause(¤t_user, snum, jobid, &werr)) errcode = NERR_Success; break; case 83: /* resume */ - if (print_job_resume(¤t_user, jobid, &werr)) + if (print_job_resume(¤t_user, snum, jobid, &werr)) errcode = NERR_Success; break; } @@ -2313,12 +2316,14 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha char *str1 = param+2; char *str2 = skip_string(str1,1); char *p = skip_string(str2,1); - int jobid; + uint32 jobid; + int snum; int uLevel = SVAL(p,2); int function = SVAL(p,4); int place, errcode; - jobid = rap_to_pjobid(SVAL(p,0)); + if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid)) + return False; *rparam_len = 4; *rparam = REALLOC(*rparam,*rparam_len); @@ -2329,7 +2334,7 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha (!check_printjob_info(&desc,uLevel,str2))) return(False); - if (!print_job_exists(jobid)) { + if (!print_job_exists(snum, jobid)) { errcode=NERR_JobNotFound; goto out; } @@ -2341,14 +2346,14 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha /* change job place in the queue, data gives the new place */ place = SVAL(data,0); - if (print_job_set_place(jobid, place)) { + if (print_job_set_place(snum, jobid, place)) { errcode=NERR_Success; } break; case 0xb: /* change print job name, data gives the name */ - if (print_job_set_name(jobid, data)) { + if (print_job_set_name(snum, jobid, data)) { errcode=NERR_Success; } break; @@ -3011,8 +3016,8 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para if (strcmp(str1,"WWrLh") != 0) return False; if (!check_printjob_info(&desc,uLevel,str2)) return False; - jobid = rap_to_pjobid(SVAL(p,0)); - snum = print_job_snum(jobid); + if(!rap_to_pjobid(SVAL(p,0),&snum,&jobid)) + return False; if (snum < 0 || !VALID_SNUM(snum)) return(False); diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 0ccdf7c241b..8f666910a51 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -354,10 +354,13 @@ int reply_ioctl(connection_struct *conn, switch (ioctl_code) { case IOCTL_QUERY_JOB_INFO: - SSVAL(p,0,fsp->print_jobid); /* Job number */ + { + uint16 rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid); + SSVAL(p,0,rap_jobid); /* Job number */ srvstr_push(outbuf, p+2, global_myname, 15, STR_TERMINATE|STR_ASCII); srvstr_push(outbuf, p+18, lp_servicename(SNUM(conn)), 13, STR_TERMINATE|STR_ASCII); break; + } } END_PROFILE(SMBioctl); diff --git a/source/smbd/server.c b/source/smbd/server.c index 6f0d0238b0d..e1e65136597 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -382,8 +382,6 @@ BOOL reload_services(BOOL test) { BOOL ret; - set_register_printer_fn(); - if (lp_loaded()) { pstring fname; pstrcpy(fname,lp_configfile()); diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index f1dfb39aacf..2532096dea3 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -2970,9 +2970,11 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf, { char *pdata = *ppdata; files_struct *fsp = file_fsp(inbuf,smb_vwv15); - + if ((SVAL(inbuf,(smb_setup+4)) == LMCAT_SPL) && (SVAL(inbuf,(smb_setup+6)) == LMFUNC_GETJOBID)) { + uint16 rap_jobid; + pdata = Realloc(*ppdata, 32); if(pdata == NULL) return ERROR_DOS(ERRDOS,ERRnomem); @@ -2981,7 +2983,8 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf, /* NOTE - THIS IS ASCII ONLY AT THE MOMENT - NOT SURE IF OS/2 CAN ACCEPT THIS IN UNICODE. JRA. */ - SSVAL(pdata,0,fsp->print_jobid); /* Job number */ + rap_jobid = pjobid_to_rap(SNUM(fsp->conn), fsp->print_jobid); /* Job number */ + SSVAL(pdata,0,rap_jobid); /* Job number */ srvstr_push( outbuf, pdata + 2, global_myname, 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */ srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */ send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32); -- 2.34.1