summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/param/loadparm.c4
-rw-r--r--source3/printing/printfsp.c6
-rw-r--r--source3/printing/printing.c367
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c31
-rw-r--r--source3/smbd/fileio.c2
-rw-r--r--source3/smbd/lanman.c33
-rw-r--r--source3/smbd/reply.c5
-rw-r--r--source3/smbd/server.c2
-rw-r--r--source3/smbd/trans2.c7
9 files changed, 170 insertions, 287 deletions
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;i<ts->qcount;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;i<ts->qcount;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;i<njobs;i++) {
- BOOL owner = is_owner(user, queue[i].job);
+ BOOL owner = is_owner(user, snum, queue[i].job);
if (owner || can_job_admin) {
- print_job_delete1(queue[i].job);
+ print_job_delete1(snum, queue[i].job);
}
}
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 68c792f8b0..ca5557a0db 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -65,7 +65,7 @@ typedef struct _Printer{
struct _Printer *prev, *next;
BOOL document_started;
BOOL page_started;
- int jobid; /* jobid in printing backend */
+ uint32 jobid; /* jobid in printing backend */
BOOL printer_type;
union {
fstring handlename;
@@ -1443,14 +1443,18 @@ BOOL convert_devicemode(char *printername, const DEVICEMODE *devmode,
static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
{
Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
-
+ int snum;
+
if (!Printer) {
DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
return WERR_BADFID;
}
+ if (!get_printer_snum(p, handle, &snum))
+ return WERR_BADFID;
+
Printer->document_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(&current_user, jobid, &werr))
+ if (print_job_delete(&current_user, snum, jobid, &werr))
errcode = NERR_Success;
break;
case 82: /* pause */
- if (print_job_pause(&current_user, jobid, &werr))
+ if (print_job_pause(&current_user, snum, jobid, &werr))
errcode = NERR_Success;
break;
case 83: /* resume */
- if (print_job_resume(&current_user, jobid, &werr))
+ if (print_job_resume(&current_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);