*/
#include "includes.h"
+#include "system/syslog.h"
+#include "system/filesys.h"
#include "printing.h"
-#include "librpc/gen_ndr/messaging.h"
#include "../librpc/gen_ndr/ndr_spoolss.h"
#include "nt_printing.h"
#include "../librpc/gen_ndr/netlogon.h"
+#include "printing/notify.h"
+#include "printing/pcap.h"
+#include "printing/printer_list.h"
+#include "printing/queue_process.h"
+#include "serverid.h"
+#include "smbd/smbd.h"
+#include "auth.h"
+#include "messages.h"
+#include "util_tdb.h"
+#include "lib/param/loadparm.h"
extern struct current_user current_user;
extern userdom_struct current_user_info;
key.dptr = (uint8 *)&jinfo;
key.dsize = sizeof(jinfo);
- data = tdb_fetch(rap_tdb, key);
+ data = tdb_fetch_compat(rap_tdb, key);
if (data.dptr && data.dsize == sizeof(uint16)) {
rap_jobid = SVAL(data.dptr, 0);
SAFE_FREE(data.dptr);
SSVAL(buf,0,rap_jobid);
key.dptr = buf;
key.dsize = sizeof(rap_jobid);
- data = tdb_fetch(rap_tdb, key);
+ data = tdb_fetch_compat(rap_tdb, key);
if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
{
struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
key.dptr = (uint8 *)&jinfo;
key.dsize = sizeof(jinfo);
- data = tdb_fetch(rap_tdb, key);
+ data = tdb_fetch_compat(rap_tdb, key);
if (!data.dptr || (data.dsize != sizeof(uint16))) {
DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
(unsigned int)jobid ));
int services = lp_numservices();
int snum;
+ if (!printer_list_parent_init()) {
+ return false;
+ }
+
unlink(cache_path("printing.tdb"));
mkdir(cache_path("printing"),0755);
pdb = get_print_db_byname(lp_const_servicename(snum));
if (!pdb)
continue;
- if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
+ if (tdb_lock_bystring(pdb->tdb, sversion) != 0) {
DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
release_print_db(pdb);
return False;
return NULL;
}
- ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
+ ret = tdb_fetch_compat(pdb->tdb, print_key(jobid, &tmp));
release_print_db(pdb);
if (!ret.dptr) {
****************************************************************************/
static const struct {
- uint32 lpq_status;
- uint32 spoolss_status;
+ uint32_t lpq_status;
+ uint32_t spoolss_status;
} lpq_to_spoolss_status_map[] = {
{ LPQ_QUEUED, JOB_STATUS_QUEUED },
{ LPQ_PAUSED, JOB_STATUS_PAUSED },
{ LPQ_DELETED, JOB_STATUS_DELETED },
{ LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
{ LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
- { -1, 0 }
+ { (uint32_t)-1, 0 }
};
/* Convert a lpq status value stored in printing.tdb into the
key = string_tdb_data("INFO/jobs_changed");
- if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
+ if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) != 0)
goto out;
gotlock = True;
- data = tdb_fetch(pdb->tdb, key);
+ data = tdb_fetch_compat(pdb->tdb, key);
if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
goto out;
if (i < job_count -1 )
memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
data.dsize -= 4;
- if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
+ if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) != 0)
goto out;
break;
}
/* Get old data */
- old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
+ old_data = tdb_fetch_compat(pdb->tdb, print_key(jobid, &tmp));
/* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
key = string_tdb_data(keystr);
- data = tdb_fetch(pdb->tdb, key);
+ data = tdb_fetch_compat(pdb->tdb, key);
release_print_db(pdb);
if (!data.dptr || data.dsize != sizeof(pid_t)) {
SAFE_FREE(data.dptr);
fstring keystr;
TDB_DATA key;
TDB_DATA data;
- pid_t updating_pid = sys_getpid();
+ pid_t updating_pid = getpid();
uint8 buffer[4];
struct tdb_print_db *pdb = get_print_db_byname(sharename);
ZERO_STRUCT(data);
- data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
+ data = tdb_fetch_compat(pdb->tdb, string_tdb_data("INFO/jobs_added"));
if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
SAFE_FREE(data.dptr);
ZERO_STRUCT(data);
}
/****************************************************************************
- main work for updating the lpq cahe for a printer queue
+ main work for updating the lpq cache for a printer queue
****************************************************************************/
static void print_queue_update_internal( struct tevent_context *ev,
slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
/* Only wait 10 seconds for this. */
- if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
+ if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) != 0) {
DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
release_print_db(pdb);
return;
/****************************************************************************
this is the receive function of the background lpq updater
****************************************************************************/
-static void print_queue_receive(struct messaging_context *msg,
+void print_queue_receive(struct messaging_context *msg,
void *private_data,
uint32_t msg_type,
struct server_id server_id,
return;
}
-static void printing_pause_fd_handler(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags,
- void *private_data)
-{
- /*
- * If pause_pipe[1] is closed it means the parent smbd
- * and children exited or aborted.
- */
- exit_server_cleanly(NULL);
-}
-
-extern struct child_pid *children;
-extern int num_children;
-
-static void add_child_pid(pid_t pid)
-{
- struct child_pid *child;
-
- child = SMB_MALLOC_P(struct child_pid);
- if (child == NULL) {
- DEBUG(0, ("Could not add child struct -- malloc failed\n"));
- return;
- }
- child->pid = pid;
- DLIST_ADD(children, child);
- num_children += 1;
-}
-
-static pid_t background_lpq_updater_pid = -1;
-
-/****************************************************************************
-main thread of the background lpq updater
-****************************************************************************/
-void start_background_queue(struct tevent_context *ev,
- struct messaging_context *msg_ctx)
-{
- /* Use local variables for this as we don't
- * need to save the parent side of this, just
- * ensure it closes when the process exits.
- */
- int pause_pipe[2];
-
- DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
-
- if (pipe(pause_pipe) == -1) {
- DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
- exit(1);
- }
-
- background_lpq_updater_pid = sys_fork();
-
- if (background_lpq_updater_pid == -1) {
- DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
- exit(1);
- }
-
- /* Track the printing pid along with other smbd children */
- add_child_pid(background_lpq_updater_pid);
-
- if(background_lpq_updater_pid == 0) {
- struct tevent_fd *fde;
- int ret;
- NTSTATUS status;
-
- /* Child. */
- DEBUG(5,("start_background_queue: background LPQ thread started\n"));
-
- close(pause_pipe[0]);
- pause_pipe[0] = -1;
-
- status = reinit_after_fork(msg_ctx, ev, procid_self(), true);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("reinit_after_fork() failed\n"));
- smb_panic("reinit_after_fork() failed");
- }
-
- smbd_setup_sig_term_handler();
- smbd_setup_sig_hup_handler(ev, msg_ctx);
-
- if (!serverid_register(procid_self(),
- FLAG_MSG_GENERAL|FLAG_MSG_SMBD
- |FLAG_MSG_PRINT_GENERAL)) {
- exit(1);
- }
-
- if (!locking_init()) {
- exit(1);
- }
-
- messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
- print_queue_receive);
-
- fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ,
- printing_pause_fd_handler,
- NULL);
- if (!fde) {
- DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
- smb_panic("tevent_add_fd() failed for pause_pipe");
- }
-
- DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
- ret = tevent_loop_wait(ev);
- /* should not be reached */
- DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
- ret, (ret == 0) ? "out of events" : strerror(errno)));
- exit(1);
- }
-
- close(pause_pipe[1]);
-}
-
/****************************************************************************
update the internal database from the system print queue for a queue
****************************************************************************/
+extern pid_t background_lpq_updater_pid;
+
static void print_queue_update(struct messaging_context *msg_ctx,
int snum, bool force)
{
struct tdb_print_db *pdb = NULL;
TDB_CONTEXT *tdb = NULL;
const char *printername;
- uint32 mypid = (uint32)sys_getpid();
+ uint32_t mypid = (uint32_t)getpid();
bool ret = False;
size_t i;
tdb = pdb->tdb;
}
- if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
+ if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) != 0) {
DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
printername));
if (pdb)
}
/* Store back the record. */
- if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
+ if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) != 0) {
DEBUG(0,("print_notify_register_pid: Failed to update pid \
list for printer %s\n", printername));
goto done;
struct tdb_print_db *pdb = NULL;
TDB_CONTEXT *tdb = NULL;
const char *printername;
- uint32 mypid = (uint32)sys_getpid();
+ uint32_t mypid = (uint32_t)getpid();
size_t i;
bool ret = False;
tdb = pdb->tdb;
}
- if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
+ if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) != 0) {
DEBUG(0,("print_notify_register_pid: Failed to lock \
printer %s database\n", printername));
if (pdb)
SAFE_FREE(data.dptr);
/* Store back the record. */
- if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
+ if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) != 0) {
DEBUG(0,("print_notify_register_pid: Failed to update pid \
list for printer %s\n", printername));
goto done;
char *print_job_fname(const char* sharename, uint32 jobid)
{
struct printjob *pjob = print_job_find(sharename, jobid);
- if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
+ if (!pjob || pjob->spooled || pjob->pid != getpid())
return NULL;
return pjob->filename;
}
struct printjob *pjob;
pjob = print_job_find(sharename, jobid);
- if (!pjob || pjob->pid != sys_getpid())
+ if (!pjob || pjob->pid != getpid())
return False;
fstrcpy(pjob->jobname, name);
struct printjob *pjob;
pjob = print_job_find(sharename, jobid);
- if (!pjob || pjob->pid != sys_getpid()) {
+ if (!pjob || pjob->pid != getpid()) {
return false;
}
key = string_tdb_data("INFO/jobs_added");
- if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
+ if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) != 0)
goto out;
gotlock = True;
- data = tdb_fetch(pdb->tdb, key);
+ data = tdb_fetch_compat(pdb->tdb, key);
if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
goto out;
if (i < job_count -1 )
memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
data.dsize -= 4;
- if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
+ if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) != 0)
goto out;
break;
}
Return true if the current user owns the print job.
****************************************************************************/
-static bool is_owner(const struct auth_serversupplied_info *server_info,
+static bool is_owner(const struct auth_session_info *server_info,
const char *servicename,
uint32 jobid)
{
if (!pjob || !server_info)
return False;
- return strequal(pjob->user, server_info->sanitized_username);
+ return strequal(pjob->user, server_info->unix_info->sanitized_username);
}
/****************************************************************************
Delete a print job.
****************************************************************************/
-WERROR print_job_delete(const struct auth_serversupplied_info *server_info,
+WERROR print_job_delete(const struct auth_session_info *server_info,
struct messaging_context *msg_ctx,
int snum, uint32_t jobid)
{
sys_adminlog( LOG_ERR,
"Permission denied-- user not allowed to delete, \
pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(server_info->utok.uid),
+ uidtoname(server_info->unix_token->uid),
lp_printername(snum) );
/* END_ADMIN_LOG */
Pause a job.
****************************************************************************/
-bool print_job_pause(const struct auth_serversupplied_info *server_info,
+bool print_job_pause(const struct auth_session_info *server_info,
struct messaging_context *msg_ctx,
int snum, uint32 jobid, WERROR *errcode)
{
sys_adminlog( LOG_ERR,
"Permission denied-- user not allowed to delete, \
pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(server_info->utok.uid),
+ uidtoname(server_info->unix_token->uid),
lp_printername(snum) );
/* END_ADMIN_LOG */
Resume a job.
****************************************************************************/
-bool print_job_resume(const struct auth_serversupplied_info *server_info,
+bool print_job_resume(const struct auth_session_info *server_info,
struct messaging_context *msg_ctx,
int snum, uint32 jobid, WERROR *errcode)
{
sys_adminlog( LOG_ERR,
"Permission denied-- user not allowed to delete, \
pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(server_info->utok.uid),
+ uidtoname(server_info->unix_token->uid),
lp_printername(snum) );
/* END_ADMIN_LOG */
return False;
if (!pjob)
return -1;
/* don't allow another process to get this info - it is meaningless */
- if (pjob->pid != sys_getpid())
+ if (pjob->pid != getpid())
return -1;
/* if SMBD is spooling this can't be allowed */
if (status) {
fstr_sprintf(keystr, "STATUS/%s", sharename);
- data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
+ data = tdb_fetch_compat(pdb->tdb, string_tdb_data(keystr));
if (data.dptr) {
if (data.dsize == sizeof(print_status_struct))
/* this memcpy is ok since the status struct was
/* Lock the database - only wait 20 seconds. */
ret = tdb_lock_bystring_with_timeout(pdb->tdb,
"INFO/nextjob", 20);
- if (ret == -1) {
+ if (ret != 0) {
DEBUG(0, ("allocate_print_jobid: "
"Failed to lock printing database %s\n",
sharename));
jobid = NEXT_JOBID(jobid);
ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
- if (ret == -1) {
+ if (ret != 0) {
terr = tdb_error(pdb->tdb);
DEBUG(3, ("allocate_print_jobid: "
"Failed to store INFO/nextjob.\n"));
dum.dptr = NULL;
dum.dsize = 0;
if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
- TDB_INSERT) == -1) {
+ TDB_INSERT) != 0) {
DEBUG(3, ("allocate_print_jobid: "
"jobid (%d) failed to store placeholder.\n",
jobid ));
Do all checks needed to determine if we can start a job.
***************************************************************************/
-static WERROR print_job_checks(const struct auth_serversupplied_info *server_info,
+static WERROR print_job_checks(const struct auth_session_info *server_info,
struct messaging_context *msg_ctx,
int snum, int *njobs)
{
Start spooling a job - return the jobid.
***************************************************************************/
-WERROR print_job_start(const struct auth_serversupplied_info *server_info,
+WERROR print_job_start(const struct auth_session_info *server_info,
struct messaging_context *msg_ctx,
const char *clientmachine,
int snum, const char *docname, const char *filename,
ZERO_STRUCT(pjob);
- pjob.pid = sys_getpid();
+ pjob.pid = getpid();
pjob.sysjob = -1;
pjob.fd = -1;
pjob.starttime = time(NULL);
fstrcpy(pjob.clientmachine, clientmachine);
fstrcpy(pjob.user, lp_printjob_username(snum));
- standard_sub_advanced(sharename, server_info->sanitized_username,
- path, server_info->utok.gid,
- server_info->sanitized_username,
- server_info->info3->base.domain.string,
- pjob.user, sizeof(pjob.user)-1);
- /* ensure NULL termination */
- pjob.user[sizeof(pjob.user)-1] = '\0';
+ standard_sub_advanced(sharename, server_info->unix_info->sanitized_username,
+ path, server_info->unix_token->gid,
+ server_info->unix_info->sanitized_username,
+ server_info->info->domain_name,
+ pjob.user, sizeof(pjob.user));
fstrcpy(pjob.queuename, lp_const_servicename(snum));
if (!pjob)
return;
/* don't allow another process to get this info - it is meaningless */
- if (pjob->pid != sys_getpid())
+ if (pjob->pid != getpid())
return;
pjob->page_count++;
return NT_STATUS_PRINT_CANCELLED;
}
- if (pjob->spooled || pjob->pid != sys_getpid()) {
+ if (pjob->spooled || pjob->pid != getpid()) {
return NT_STATUS_ACCESS_DENIED;
}
ZERO_STRUCT(cgdata);
/* Get the stored queue data. */
- data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
+ data = tdb_fetch_compat(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
if (data.dptr && data.dsize >= sizeof(qcount))
len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
/* Get the added jobs list. */
- cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
+ cgdata = tdb_fetch_compat(pdb->tdb, string_tdb_data("INFO/jobs_added"));
if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
extra_count = cgdata.dsize/4;
/* Get the changed jobs list. */
- jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
+ jcdata = tdb_fetch_compat(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0))
changed_count = jcdata.dsize / 4;
slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
key = string_tdb_data(keystr);
- data = tdb_fetch(pdb->tdb, key);
+ data = tdb_fetch_compat(pdb->tdb, key);
if (data.dptr) {
if (data.dsize == sizeof(*status)) {
/* this memcpy is ok since the status struct was
Pause a queue.
****************************************************************************/
-WERROR print_queue_pause(const struct auth_serversupplied_info *server_info,
+WERROR print_queue_pause(const struct auth_session_info *server_info,
struct messaging_context *msg_ctx, int snum)
{
int ret;
Resume a queue.
****************************************************************************/
-WERROR print_queue_resume(const struct auth_serversupplied_info *server_info,
+WERROR print_queue_resume(const struct auth_session_info *server_info,
struct messaging_context *msg_ctx, int snum)
{
int ret;
Purge a queue - implemented by deleting all jobs that we can delete.
****************************************************************************/
-WERROR print_queue_purge(const struct auth_serversupplied_info *server_info,
+WERROR print_queue_purge(const struct auth_session_info *server_info,
struct messaging_context *msg_ctx, int snum)
{
print_queue_struct *queue;