From 29426b4a50275e24020ae67898cd7d156a341a7f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Jul 2002 19:12:17 +0000 Subject: 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. (This used to be commit 4ff64f69706cc94d5dba7762754d00790c476963) --- source3/param/loadparm.c | 4 - source3/printing/printfsp.c | 6 +- source3/printing/printing.c | 367 ++++++++++++------------------------ source3/rpc_server/srv_spoolss_nt.c | 31 +-- source3/smbd/fileio.c | 2 +- source3/smbd/lanman.c | 33 ++-- source3/smbd/reply.c | 5 +- source3/smbd/server.c | 2 - source3/smbd/trans2.c | 7 +- 9 files changed, 170 insertions(+), 287 deletions(-) (limited to 'source3') diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 37f8bb3ca4..0602e901a4 100644 --- a/source3/param/loadparm.c +++ b/source3/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/source3/printing/printfsp.c b/source3/printing/printfsp.c index 9f33d57ad5..ff50ac47c4 100644 --- a/source3/printing/printfsp.c +++ b/source3/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/source3/printing/printing.c b/source3/printing/printing.c index f8dfea0a12..9b0e8cdfb0 100644 --- a/source3/printing/printing.c +++ b/source3/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/source3/smbd/fileio.c b/source3/smbd/fileio.c index 710ba396d8..89f05092b4 100644 --- a/source3/smbd/fileio.c +++ b/source3/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/source3/smbd/lanman.c b/source3/smbd/lanman.c index 619ecd736a..049dae98e3 100644 --- a/source3/smbd/lanman.c +++ b/source3/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/source3/smbd/reply.c b/source3/smbd/reply.c index 0ccdf7c241..8f666910a5 100644 --- a/source3/smbd/reply.c +++ b/source3/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/source3/smbd/server.c b/source3/smbd/server.c index 6f0d0238b0..e1e6513659 100644 --- a/source3/smbd/server.c +++ b/source3/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/source3/smbd/trans2.c b/source3/smbd/trans2.c index f1dfb39aac..2532096dea 100644 --- a/source3/smbd/trans2.c +++ b/source3/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); -- cgit