This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "printing.h"
-extern SIG_ATOMIC_T got_sig_term;
-extern SIG_ATOMIC_T reload_after_sighup;
+extern struct current_user current_user;
+extern userdom_struct current_user_info;
/* Current printer interface */
-static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid);
+static bool remove_from_jobs_changed(const char* sharename, uint32 jobid);
/*
the printing backend revolves around a tdb database that stores the
ZERO_STRUCT( jinfo );
fstrcpy( jinfo.sharename, sharename );
jinfo.jobid = jobid;
- key.dptr = (char*)&jinfo;
+ key.dptr = (uint8 *)&jinfo;
key.dsize = sizeof(jinfo);
data = tdb_fetch(rap_tdb, key);
if (rap_jobid == 0)
rap_jobid = ++next_rap_jobid;
SSVAL(buf,0,rap_jobid);
- data.dptr = (char*)buf;
+ data.dptr = buf;
data.dsize = sizeof(rap_jobid);
tdb_store(rap_tdb, key, data, TDB_REPLACE);
tdb_store(rap_tdb, data, key, TDB_REPLACE);
return rap_jobid;
}
-BOOL rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
+bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
{
TDB_DATA data, key;
uint8 buf[2];
return False;
SSVAL(buf,0,rap_jobid);
- key.dptr = (char*)buf;
+ key.dptr = buf;
key.dsize = sizeof(rap_jobid);
data = tdb_fetch(rap_tdb, key);
if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
ZERO_STRUCT( jinfo );
fstrcpy( jinfo.sharename, sharename );
jinfo.jobid = jobid;
- key.dptr = (char*)&jinfo;
+ key.dptr = (uint8 *)&jinfo;
key.dsize = sizeof(jinfo);
data = tdb_fetch(rap_tdb, key);
rap_jobid = SVAL(data.dptr, 0);
SAFE_FREE(data.dptr);
SSVAL(buf,0,rap_jobid);
- data.dptr = (char*)buf;
+ data.dptr = buf;
data.dsize = sizeof(rap_jobid);
tdb_delete(rap_tdb, key);
tdb_delete(rap_tdb, data);
Initialise the printing backend. Called once at startup before the fork().
****************************************************************************/
-BOOL print_backend_init(void)
+bool print_backend_init(struct messaging_context *msg_ctx)
{
const char *sversion = "INFO/version";
- pstring printing_path;
int services = lp_numservices();
int snum;
- unlink(lock_path("printing.tdb"));
- pstrcpy(printing_path,lock_path("printing"));
- mkdir(printing_path,0755);
+ unlink(cache_path("printing.tdb"));
+ mkdir(cache_path("printing"),0755);
/* handle a Samba upgrade */
return False;
}
if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
- tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
+ tdb_wipe_all(pdb->tdb);
tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
}
tdb_unlock_bystring(pdb->tdb, sversion);
close_all_print_db(); /* Don't leave any open. */
/* do NT print initialization... */
- return nt_printing_init();
+ return nt_printing_init(msg_ctx);
}
/****************************************************************************
Useful function to generate a tdb key.
****************************************************************************/
-static TDB_DATA print_key(uint32 jobid)
+static TDB_DATA print_key(uint32 jobid, uint32 *tmp)
{
- static uint32 j;
TDB_DATA ret;
- SIVAL(&j, 0, jobid);
- ret.dptr = (void *)&j;
- ret.dsize = sizeof(j);
+ SIVAL(tmp, 0, jobid);
+ ret.dptr = (uint8 *)tmp;
+ ret.dsize = sizeof(*tmp);
return ret;
}
unpack a pjob from a tdb buffer
***********************************************************************/
-int unpack_pjob( char* buf, int buflen, struct printjob *pjob )
+int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
{
int len = 0;
int used;
static struct printjob *print_job_find(const char *sharename, uint32 jobid)
{
static struct printjob pjob;
+ uint32_t tmp;
TDB_DATA ret;
struct tdb_print_db *pdb = get_print_db_byname(sharename);
-
+
DEBUG(10,("print_job_find: looking up job %u for share %s\n",
(unsigned int)jobid, sharename ));
return NULL;
}
- ret = tdb_fetch(pdb->tdb, print_key(jobid));
+ ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
release_print_db(pdb);
if (!ret.dptr) {
DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
return NULL;
}
-
+
if ( pjob.nt_devmode ) {
free_nt_devicemode( &pjob.nt_devmode );
}
-
+
ZERO_STRUCT( pjob );
-
+
if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
SAFE_FREE(ret.dptr);
return NULL;
}
-
+
SAFE_FREE(ret.dptr);
DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
/* Convert a unix jobid to a smb jobid */
-static uint32 sysjob_to_jobid_value;
+struct unixjob_traverse_state {
+ int sysjob;
+ uint32 sysjob_to_jobid_value;
+};
static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
- TDB_DATA data, void *state)
+ TDB_DATA data, void *private_data)
{
struct printjob *pjob;
- int *sysjob = (int *)state;
+ struct unixjob_traverse_state *state =
+ (struct unixjob_traverse_state *)private_data;
if (!data.dptr || data.dsize == 0)
return 0;
if (key.dsize != sizeof(uint32))
return 0;
- if (*sysjob == pjob->sysjob) {
+ if (state->sysjob == pjob->sysjob) {
uint32 jobid = IVAL(key.dptr,0);
- sysjob_to_jobid_value = jobid;
+ state->sysjob_to_jobid_value = jobid;
return 1;
}
{
int services = lp_numservices();
int snum;
+ struct unixjob_traverse_state state;
- sysjob_to_jobid_value = (uint32)-1;
+ state.sysjob = unix_jobid;
+ state.sysjob_to_jobid_value = (uint32)-1;
for (snum = 0; snum < services; snum++) {
struct tdb_print_db *pdb;
if (!pdb) {
continue;
}
- tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
+ tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
release_print_db(pdb);
- if (sysjob_to_jobid_value != (uint32)-1)
- return sysjob_to_jobid_value;
+ if (state.sysjob_to_jobid_value != (uint32)-1)
+ return state.sysjob_to_jobid_value;
}
return (uint32)-1;
}
Send notifications based on what has changed after a pjob_store.
****************************************************************************/
-static struct {
+static const struct {
uint32 lpq_status;
uint32 spoolss_status;
} lpq_to_spoolss_status_map[] = {
static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
struct printjob *new_data)
{
- BOOL new_job = False;
+ bool new_job = False;
if (!old_data)
new_job = True;
Store a job structure back to the database.
****************************************************************************/
-static BOOL pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
+static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
{
+ uint32_t tmp;
TDB_DATA old_data, new_data;
- BOOL ret = False;
+ bool ret = False;
struct tdb_print_db *pdb = get_print_db_byname(sharename);
- char *buf = NULL;
+ uint8 *buf = NULL;
int len, newlen, buflen;
/* Get old data */
- old_data = tdb_fetch(pdb->tdb, print_key(jobid));
+ old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
/* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
if (buflen != len) {
- buf = (char *)SMB_REALLOC(buf, len);
+ buf = (uint8 *)SMB_REALLOC(buf, len);
if (!buf) {
DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
goto done;
new_data.dptr = buf;
new_data.dsize = len;
- ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
+ ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
+ TDB_REPLACE) == 0);
release_print_db(pdb);
void pjob_delete(const char* sharename, uint32 jobid)
{
+ uint32_t tmp;
struct printjob *pjob;
uint32 job_status = 0;
struct tdb_print_db *pdb;
/* Remove from printing.tdb */
- tdb_delete(pdb->tdb, print_key(jobid));
+ tdb_delete(pdb->tdb, print_key(jobid, &tmp));
remove_from_jobs_changed(sharename, jobid);
release_print_db( pdb );
rap_jobid_delete(sharename, jobid);
Check if the print queue has been updated recently enough.
****************************************************************************/
-static void print_cache_flush(int snum)
+static void print_cache_flush(const char *sharename)
{
fstring key;
- const char *sharename = lp_const_servicename(snum);
struct tdb_print_db *pdb = get_print_db_byname(sharename);
if (!pdb)
if (!pdb)
return (pid_t)-1;
slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
+ key = string_tdb_data(keystr);
data = tdb_fetch(pdb->tdb, key);
release_print_db(pdb);
in the tdb.
****************************************************************************/
-static void set_updating_pid(const fstring sharename, BOOL updating)
+static void set_updating_pid(const fstring sharename, bool updating)
{
fstring keystr;
TDB_DATA key;
return;
slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
+ key = string_tdb_data(keystr);
DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
updating ? "" : "not ",
}
SIVAL( buffer, 0, updating_pid);
- data.dptr = (void *)buffer;
+ data.dptr = buffer;
data.dsize = 4; /* we always assume this is a 4 byte value */
tdb_store(pdb->tdb, key, data, TDB_REPLACE);
print_queue_struct *queue = pts->queue;
size_t len;
size_t i;
- uint qcount;
+ unsigned int qcount;
if (max_reported_jobs && (max_reported_jobs < pts->qcount))
pts->qcount = max_reported_jobs;
queue[i].fs_file);
}
- if ((data.dptr = SMB_MALLOC(data.dsize)) == NULL)
+ if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
return;
len = 0;
Check if the print queue has been updated recently enough.
****************************************************************************/
-static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
+static bool print_cache_expired(const char *sharename, bool check_pending)
{
fstring key;
time_t last_qscan_time, time_now = time(NULL);
struct tdb_print_db *pdb = get_print_db_byname(sharename);
- BOOL result = False;
+ bool result = False;
if (!pdb)
return False;
/* store the new queue status structure */
slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
+ key = string_tdb_data(keystr);
status.qcount = qcount;
- data.dptr = (void *)&status;
+ data.dptr = (uint8 *)&status;
data.dsize = sizeof(status);
tdb_store(pdb->tdb, key, data, TDB_REPLACE);
/****************************************************************************
this is the receive function of the background lpq updater
****************************************************************************/
-static void print_queue_receive(int msg_type, struct process_id src,
- void *buf, size_t msglen)
+static void print_queue_receive(struct messaging_context *msg,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
{
fstring sharename;
- pstring lpqcommand, lprmcommand;
+ char *lpqcommand = NULL, *lprmcommand = NULL;
int printing_type;
size_t len;
- len = tdb_unpack( buf, msglen, "fdPP",
+ len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
sharename,
&printing_type,
- lpqcommand,
- lprmcommand );
+ &lpqcommand,
+ &lprmcommand );
if ( len == -1 ) {
+ SAFE_FREE(lpqcommand);
+ SAFE_FREE(lprmcommand);
DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
return;
}
print_queue_update_with_lock(sharename,
- get_printer_fns_from_type(printing_type),
+ get_printer_fns_from_type((enum printing_types)printing_type),
lpqcommand, lprmcommand );
+ SAFE_FREE(lpqcommand);
+ SAFE_FREE(lprmcommand);
return;
}
****************************************************************************/
void start_background_queue(void)
{
+ /* Use local variables for this as we don't
+ * need to save the parent side of this, just
+ * ensure it closes when the process exits.
+ */
+ int pause_pipe[2];
+
DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
+
+ if (pipe(pause_pipe) == -1) {
+ DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
+ exit(1);
+ }
+
background_lpq_updater_pid = sys_fork();
if (background_lpq_updater_pid == -1) {
/* Child. */
DEBUG(5,("start_background_queue: background LPQ thread started\n"));
- claim_connection( NULL, "smbd lpq backend", 0, False,
+ close(pause_pipe[0]);
+ pause_pipe[0] = -1;
+
+ if (!reinit_after_fork(smbd_messaging_context(),
+ smbd_event_context(), true)) {
+ DEBUG(0,("reinit_after_fork() failed\n"));
+ smb_panic("reinit_after_fork() failed");
+ }
+
+ smbd_setup_sig_term_handler();
+ smbd_setup_sig_hup_handler();
+
+ claim_connection( NULL, "smbd lpq backend",
FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
- if (!locking_init(0)) {
+ if (!locking_init()) {
exit(1);
}
- message_register(MSG_PRINTER_UPDATE, print_queue_receive);
-
+ messaging_register(smbd_messaging_context(), NULL,
+ MSG_PRINTER_UPDATE, print_queue_receive);
+
DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
while (1) {
- pause();
-
- /* check for some essential signals first */
-
- if (got_sig_term) {
+ fd_set r_fds, w_fds;
+ int ret;
+ struct timeval to;
+ int maxfd = 0;
+
+ /* Process a signal and timed events now... */
+ if (run_events(smbd_event_context(), 0, NULL, NULL)) {
+ continue;
+ }
+
+ to.tv_sec = SMBD_SELECT_TIMEOUT;
+ to.tv_usec = 0;
+
+ /*
+ * Setup the select fd sets.
+ */
+
+ FD_ZERO(&r_fds);
+ FD_ZERO(&w_fds);
+
+ /*
+ * Are there any timed events waiting ? If so, ensure we don't
+ * select for longer than it would take to wait for them.
+ */
+
+ {
+ struct timeval now;
+ GetTimeOfDay(&now);
+
+ event_add_to_select_args(smbd_event_context(), &now,
+ &r_fds, &w_fds, &to, &maxfd);
+ }
+
+ FD_SET(pause_pipe[1], &r_fds);
+ maxfd = MAX(pause_pipe[1], maxfd);
+
+ ret = sys_select(maxfd, &r_fds, &w_fds, NULL, &to);
+
+ /* If pause_pipe[1] is closed it means the parent smbd
+ * and children exited or aborted. */
+ if (ret == 1 && FD_ISSET(pause_pipe[1], &r_fds)) {
exit_server_cleanly(NULL);
- }
-
- if (reload_after_sighup) {
- change_to_root_user();
- DEBUG(1,("Reloading services after SIGHUP\n"));
- reload_services(False);
- reload_after_sighup = 0;
- }
-
- /* now check for messages */
-
- DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
- message_dispatch();
-
- /* process any pending print change notify messages */
-
- print_notify_send_messages(0);
+ }
+
+ if (run_events(smbd_event_context(), ret, &r_fds, &w_fds)) {
+ continue;
+ }
}
}
+
+ close(pause_pipe[1]);
}
/****************************************************************************
update the internal database from the system print queue for a queue
****************************************************************************/
-static void print_queue_update(int snum, BOOL force)
+static void print_queue_update(int snum, bool force)
{
fstring key;
fstring sharename;
- pstring lpqcommand, lprmcommand;
- char *buffer = NULL;
+ char *lpqcommand = NULL;
+ char *lprmcommand = NULL;
+ uint8 *buffer = NULL;
size_t len = 0;
size_t newlen;
struct tdb_print_db *pdb;
int type;
struct printif *current_printif;
+ TALLOC_CTX *ctx = talloc_tos();
fstrcpy( sharename, lp_const_servicename(snum));
/* don't strip out characters like '$' from the printername */
-
- pstrcpy( lpqcommand, lp_lpqcommand(snum));
- string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand),
- False, False, False );
- standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) );
-
- pstrcpy( lprmcommand, lp_lprmcommand(snum));
- string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand),
- False, False, False );
- standard_sub_snum( snum, lprmcommand, sizeof(lprmcommand) );
-
- /*
- * Make sure that the background queue process exists.
- * Otherwise just do the update ourselves
+
+ lpqcommand = talloc_string_sub2(ctx,
+ lp_lpqcommand(snum),
+ "%p",
+ PRINTERNAME(snum),
+ false, false, false);
+ if (!lpqcommand) {
+ return;
+ }
+ lpqcommand = talloc_sub_advanced(ctx,
+ lp_servicename(snum),
+ current_user_info.unix_name,
+ "",
+ current_user.ut.gid,
+ get_current_username(),
+ current_user_info.domain,
+ lpqcommand);
+ if (!lpqcommand) {
+ return;
+ }
+
+ lprmcommand = talloc_string_sub2(ctx,
+ lp_lprmcommand(snum),
+ "%p",
+ PRINTERNAME(snum),
+ false, false, false);
+ if (!lprmcommand) {
+ return;
+ }
+ lprmcommand = talloc_sub_advanced(ctx,
+ lp_servicename(snum),
+ current_user_info.unix_name,
+ "",
+ current_user.ut.gid,
+ get_current_username(),
+ current_user_info.domain,
+ lprmcommand);
+ if (!lprmcommand) {
+ return;
+ }
+
+ /*
+ * Make sure that the background queue process exists.
+ * Otherwise just do the update ourselves
*/
-
+
if ( force || background_lpq_updater_pid == -1 ) {
DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
current_printif = get_printer_fns( snum );
}
type = lp_printing(snum);
-
+
/* get the length */
len = tdb_pack( NULL, 0, "fdPP",
sharename,
type,
- lpqcommand,
+ lpqcommand,
lprmcommand );
- buffer = SMB_XMALLOC_ARRAY( char, len );
+ buffer = SMB_XMALLOC_ARRAY( uint8, len );
/* now pack the buffer */
newlen = tdb_pack( buffer, len, "fdPP",
/* finally send the message */
- become_root();
- message_send_pid(pid_to_procid(background_lpq_updater_pid),
- MSG_PRINTER_UPDATE, buffer, len, False);
- unbecome_root();
+ messaging_send_buf(smbd_messaging_context(),
+ pid_to_procid(background_lpq_updater_pid),
+ MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
SAFE_FREE( buffer );
updates only to interested smbd's.
****************************************************************************/
-BOOL print_notify_register_pid(int snum)
+bool print_notify_register_pid(int snum)
{
TDB_DATA data;
struct tdb_print_db *pdb = NULL;
TDB_CONTEXT *tdb = NULL;
const char *printername;
uint32 mypid = (uint32)sys_getpid();
- BOOL ret = False;
+ bool ret = False;
size_t i;
/* if (snum == -1), then the change notify request was
if (i == data.dsize) {
/* We weren't in the list. Realloc. */
- data.dptr = SMB_REALLOC(data.dptr, data.dsize + 8);
+ data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
if (!data.dptr) {
DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
printername));
updates only to interested smbd's.
****************************************************************************/
-BOOL print_notify_deregister_pid(int snum)
+bool print_notify_deregister_pid(int snum)
{
TDB_DATA data;
struct tdb_print_db *pdb = NULL;
const char *printername;
uint32 mypid = (uint32)sys_getpid();
size_t i;
- BOOL ret = False;
+ bool ret = False;
/* if ( snum == -1 ), we are deregister a print server handle
which means to deregister on all print queues */
Check if a jobid is valid. It is valid if it exists in the database.
****************************************************************************/
-BOOL print_job_exists(const char* sharename, uint32 jobid)
+bool print_job_exists(const char* sharename, uint32 jobid)
{
struct tdb_print_db *pdb = get_print_db_byname(sharename);
- BOOL ret;
+ bool ret;
+ uint32_t tmp;
if (!pdb)
return False;
- ret = tdb_exists(pdb->tdb, print_key(jobid));
+ ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
release_print_db(pdb);
return ret;
}
Set the place in the queue for a job.
****************************************************************************/
-BOOL print_job_set_place(int snum, uint32 jobid, int place)
+bool print_job_set_place(const char *sharename, uint32 jobid, int place)
{
DEBUG(2,("print_job_set_place not implemented yet\n"));
return False;
Set the name of a job. Only possible for owner.
****************************************************************************/
-BOOL print_job_set_name(int snum, uint32 jobid, char *name)
+bool print_job_set_name(const char *sharename, uint32 jobid, char *name)
{
- const char* sharename = lp_const_servicename(snum);
struct printjob *pjob;
pjob = print_job_find(sharename, jobid);
Remove a jobid from the 'jobs changed' list.
***************************************************************************/
-static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid)
+static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
{
struct tdb_print_db *pdb = get_print_db_byname(sharename);
TDB_DATA data, key;
size_t job_count, i;
- BOOL ret = False;
- BOOL gotlock = False;
+ bool ret = False;
+ bool gotlock = False;
if (!pdb) {
return False;
Delete a print job - don't update queue.
****************************************************************************/
-static BOOL print_job_delete1(int snum, uint32 jobid)
+static bool print_job_delete1(int snum, uint32 jobid)
{
const char* sharename = lp_const_servicename(snum);
struct printjob *pjob = print_job_find(sharename, jobid);
Return true if the current user owns the print job.
****************************************************************************/
-static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
+static bool is_owner(struct auth_serversupplied_info *server_info,
+ const char *servicename,
+ uint32 jobid)
{
- struct printjob *pjob = print_job_find(lp_const_servicename(snum), jobid);
- user_struct *vuser;
+ struct printjob *pjob = print_job_find(servicename, jobid);
- if (!pjob || !user)
+ if (!pjob || !server_info)
return False;
- if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
- return strequal(pjob->user, vuser->user.smb_name);
- } else {
- return strequal(pjob->user, uidtoname(user->ut.uid));
- }
+ return strequal(pjob->user, server_info->sanitized_username);
}
/****************************************************************************
Delete a print job.
****************************************************************************/
-BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
+bool print_job_delete(struct auth_serversupplied_info *server_info, int snum,
+ uint32 jobid, WERROR *errcode)
{
const char* sharename = lp_const_servicename( snum );
struct printjob *pjob;
- BOOL owner;
+ bool owner;
char *fname;
*errcode = WERR_OK;
- owner = is_owner(user, snum, jobid);
+ owner = is_owner(server_info, lp_const_servicename(snum), jobid);
/* Check access against security descriptor or whether the user
owns their job. */
if (!owner &&
- !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
+ !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("delete denied by security descriptor\n"));
*errcode = WERR_ACCESS_DENIED;
sys_adminlog( LOG_ERR,
"Permission denied-- user not allowed to delete, \
pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->ut.uid), PRINTERNAME(snum) );
+ uidtoname(server_info->utok.uid),
+ PRINTERNAME(snum) );
/* END_ADMIN_LOG */
return False;
Pause a job.
****************************************************************************/
-BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
+bool print_job_pause(struct auth_serversupplied_info *server_info, int snum,
+ uint32 jobid, WERROR *errcode)
{
const char* sharename = lp_const_servicename(snum);
struct printjob *pjob;
pjob = print_job_find(sharename, jobid);
- if (!pjob || !user) {
+ if (!pjob || !server_info) {
DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
(unsigned int)jobid ));
return False;
return False;
}
- if (!is_owner(user, snum, jobid) &&
- !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
+ if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
+ !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("pause denied by security descriptor\n"));
/* BEGIN_ADMIN_LOG */
sys_adminlog( LOG_ERR,
"Permission denied-- user not allowed to delete, \
pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->ut.uid), PRINTERNAME(snum) );
+ uidtoname(server_info->utok.uid),
+ PRINTERNAME(snum) );
/* END_ADMIN_LOG */
*errcode = WERR_ACCESS_DENIED;
}
/* force update the database */
- print_cache_flush(snum);
+ print_cache_flush(lp_const_servicename(snum));
/* Send a printer notify message */
Resume a job.
****************************************************************************/
-BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
+bool print_job_resume(struct auth_serversupplied_info *server_info, int snum,
+ uint32 jobid, WERROR *errcode)
{
const char *sharename = lp_const_servicename(snum);
struct printjob *pjob;
struct printif *current_printif = get_printer_fns( snum );
pjob = print_job_find(sharename, jobid);
-
- if (!pjob || !user) {
+
+ if (!pjob || !server_info) {
DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
(unsigned int)jobid ));
return False;
return False;
}
- if (!is_owner(user, snum, jobid) &&
- !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
+ if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
+ !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("resume denied by security descriptor\n"));
*errcode = WERR_ACCESS_DENIED;
sys_adminlog( LOG_ERR,
"Permission denied-- user not allowed to delete, \
pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->ut.uid), PRINTERNAME(snum) );
+ uidtoname(server_info->utok.uid),
+ PRINTERNAME(snum) );
/* END_ADMIN_LOG */
return False;
}
}
/* force update the database */
- print_cache_flush(snum);
+ print_cache_flush(lp_const_servicename(snum));
/* Send a printer notify message */
Allocate a jobid. Hold the lock for as short a time as possible.
***************************************************************************/
-static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
+static bool allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
{
int i;
uint32 jobid;
/* Store a dummy placeholder. */
{
+ uint32_t tmp;
TDB_DATA dum;
dum.dptr = NULL;
dum.dsize = 0;
- if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
+ if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
+ TDB_INSERT) == -1) {
DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
jobid ));
return False;
Append a jobid to the 'jobs changed' list.
***************************************************************************/
-static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
+static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
{
TDB_DATA data;
uint32 store_jobid;
SIVAL(&store_jobid, 0, jobid);
- data.dptr = (char *)&store_jobid;
+ data.dptr = (uint8 *)&store_jobid;
data.dsize = 4;
DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
Start spooling a job - return the jobid.
***************************************************************************/
-uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
+uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum,
+ char *jobname, NT_DEVICEMODE *nt_devmode )
{
uint32 jobid;
char *path;
struct printjob pjob;
- user_struct *vuser;
const char *sharename = lp_const_servicename(snum);
struct tdb_print_db *pdb = get_print_db_byname(sharename);
int njobs;
if (!pdb)
return (uint32)-1;
- if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
+ if (!print_access_check(server_info, snum, PRINTER_ACCESS_USE)) {
DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
release_print_db(pdb);
return (uint32)-1;
}
- if (!print_time_access_check(snum)) {
+ if (!print_time_access_check(lp_servicename(snum))) {
DEBUG(3, ("print_job_start: job start denied by time check\n"));
release_print_db(pdb);
return (uint32)-1;
/* see if we have sufficient disk space */
if (lp_minprintspace(snum)) {
- SMB_BIG_UINT dspace, dsize;
+ uint64_t dspace, dsize;
if (sys_fsusage(path, &dspace, &dsize) == 0 &&
- dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
+ dspace < 2*(uint64_t)lp_minprintspace(snum)) {
DEBUG(3, ("print_job_start: disk space check failed.\n"));
release_print_db(pdb);
errno = ENOSPC;
fstrcpy(pjob.jobname, jobname);
- if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
- fstrcpy(pjob.user, vuser->user.smb_name);
- } else {
- fstrcpy(pjob.user, uidtoname(user->ut.uid));
- }
+ fstrcpy(pjob.user, lp_printjob_username(snum));
+ standard_sub_advanced(sharename, server_info->sanitized_username,
+ path, server_info->utok.gid,
+ server_info->sanitized_username,
+ pdb_get_domain(server_info->sam_account),
+ pjob.user, sizeof(pjob.user)-1);
+ /* ensure NULL termination */
+ pjob.user[sizeof(pjob.user)-1] = '\0';
fstrcpy(pjob.queuename, lp_const_servicename(snum));
error.
****************************************************************************/
-BOOL print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
+bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
{
const char* sharename = lp_const_servicename(snum);
struct printjob *pjob;
if (ret)
goto fail;
- /* The print job has been sucessfully handed over to the back-end */
+ /* The print job has been successfully handed over to the back-end */
pjob->spooled = True;
pjob->status = LPQ_QUEUED;
fail:
- /* The print job was not succesfully started. Cleanup */
+ /* The print job was not successfully started. Cleanup */
/* Still need to add proper error return propagation! 010122:JRR */
unlink(pjob->filename);
pjob_delete(sharename, jobid);
Get a snapshot of jobs in the system without traversing.
****************************************************************************/
-static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
+static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
{
TDB_DATA data, cgdata;
print_queue_struct *queue = NULL;
size_t len = 0;
uint32 i;
int max_reported_jobs = lp_max_reported_jobs(snum);
- BOOL ret = False;
+ bool ret = False;
const char* sharename = lp_servicename(snum);
/* make sure the database is up to date */
ZERO_STRUCTP(status);
slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
+ key = string_tdb_data(keystr);
+
data = tdb_fetch(pdb->tdb, key);
if (data.dptr) {
if (data.dsize == sizeof(*status)) {
Pause a queue.
****************************************************************************/
-BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
+bool print_queue_pause(struct auth_serversupplied_info *server_info, int snum,
+ WERROR *errcode)
{
int ret;
struct printif *current_printif = get_printer_fns( snum );
- if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
+ if (!print_access_check(server_info, snum,
+ PRINTER_ACCESS_ADMINISTER)) {
*errcode = WERR_ACCESS_DENIED;
return False;
}
}
/* force update the database */
- print_cache_flush(snum);
+ print_cache_flush(lp_const_servicename(snum));
/* Send a printer notify message */
Resume a queue.
****************************************************************************/
-BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
+bool print_queue_resume(struct auth_serversupplied_info *server_info, int snum,
+ WERROR *errcode)
{
int ret;
struct printif *current_printif = get_printer_fns( snum );
- if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
+ if (!print_access_check(server_info, snum,
+ PRINTER_ACCESS_ADMINISTER)) {
*errcode = WERR_ACCESS_DENIED;
return False;
}
Purge a queue - implemented by deleting all jobs that we can delete.
****************************************************************************/
-BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
+bool print_queue_purge(struct auth_serversupplied_info *server_info, int snum,
+ WERROR *errcode)
{
print_queue_struct *queue;
print_status_struct status;
int njobs, i;
- BOOL can_job_admin;
+ bool can_job_admin;
/* Force and update so the count is accurate (i.e. not a cached count) */
print_queue_update(snum, True);
- can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
+ can_job_admin = print_access_check(server_info, snum,
+ JOB_ACCESS_ADMINISTER);
njobs = print_queue_status(snum, &queue, &status);
if ( can_job_admin )
become_root();
for (i=0;i<njobs;i++) {
- BOOL owner = is_owner(user, snum, queue[i].job);
+ bool owner = is_owner(server_info, lp_const_servicename(snum),
+ queue[i].job);
if (owner || can_job_admin) {
print_job_delete1(snum, queue[i].job);