summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2000-10-10 21:52:31 +0000
committerJeremy Allison <jra@samba.org>2000-10-10 21:52:31 +0000
commitcdb71ca5181aa1e06bebe2fffb02dc39de83645e (patch)
tree19b23d77aa31da1d109bf54cc03b18111a05b083 /source3
parente8912baf025a1356aa8c02f971fbe3d67adc9b0a (diff)
downloadsamba-cdb71ca5181aa1e06bebe2fffb02dc39de83645e.tar.gz
samba-cdb71ca5181aa1e06bebe2fffb02dc39de83645e.tar.bz2
samba-cdb71ca5181aa1e06bebe2fffb02dc39de83645e.zip
Fixes to periodically scan printing.tdb in idle time and occasionally
on exit. Needed to fix printing.tdb from groving to 300Mb+ if being driven by smbclient clients that never ask for status... (effective DOS attack :-). Jeremy. (This used to be commit 6581066b93a674fadf6f9b92441428d2cc8b4a02)
Diffstat (limited to 'source3')
-rw-r--r--source3/include/proto.h1
-rw-r--r--source3/printing/printing.c43
-rw-r--r--source3/smbd/process.c6
-rw-r--r--source3/smbd/server.c4
4 files changed, 53 insertions, 1 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 6911c43be7..0ea92c35aa 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1787,6 +1787,7 @@ int print_queue_snum(char *qname);
BOOL print_queue_pause(struct current_user *user, int snum, int *errcode);
BOOL print_queue_resume(struct current_user *user, int snum, int *errcode);
BOOL print_queue_purge(struct current_user *user, int snum, int *errcode);
+void process_print_queue(time_t t);
#endif
/*The following definitions come from profile/profile.c */
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index 9054c8f36a..486ef5d2c7 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -300,6 +300,14 @@ static void print_queue_update(int snum)
fstring keystr;
TDB_DATA data, key;
+ /*
+ * Update the cache time FIRST ! Stops others doing this
+ * if the lpq takes a long time.
+ */
+
+ slprintf(keystr, sizeof(keystr), "CACHE/%s", lp_servicename(snum));
+ tdb_store_int(tdb, keystr, (int)time(NULL));
+
slprintf(tmp_file, sizeof(tmp_file), "%s/smblpq.%d", path, local_pid);
unlink(tmp_file);
@@ -380,7 +388,11 @@ static void print_queue_update(int snum)
key.dsize = strlen(keystr);
tdb_store(tdb, key, data, TDB_REPLACE);
- /* update the cache time */
+ /*
+ * Update the cache time again. We want to do this call
+ * as little as possible...
+ */
+
slprintf(keystr, sizeof(keystr), "CACHE/%s", lp_servicename(snum));
tdb_store_int(tdb, keystr, (int)time(NULL));
}
@@ -1008,7 +1020,36 @@ BOOL print_queue_purge(struct current_user *user, int snum, int *errcode)
}
print_cache_flush(snum);
+ safe_free(queue);
return True;
}
+
+/****************************************************************************
+ Periodically run a status on all the queues to ensure the tdb doesn't grow.
+ Note that this will have no effect if the client is doing its own status
+ queries. This code is here to clean up jobs submitted by non-Windows printer
+ clients (eg. smbclient) that never do a status check.
+****************************************************************************/
+
+void process_print_queue(time_t t)
+{
+ static time_t last_check_time;
+ int services = lp_numservices();
+ print_queue_struct *queue;
+ print_status_struct status;
+ int snum;
+
+ if ((t != (time_t)-1) && ((t - last_check_time) < lp_lpqcachetime()))
+ return;
+
+ last_check_time = t;
+
+ for (snum = 0; snum < services; snum++) {
+ if (lp_snum_ok(snum) && lp_print_ok(snum) && lp_browseable(snum)) {
+ (void)print_queue_status(snum, &queue,&status);
+ safe_free(queue);
+ }
+ }
+}
#undef OLD_NTDOMAIN
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 1599ade12d..9ed83ec88c 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -994,6 +994,12 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup ));
process_pending_change_notify_queue(t);
/*
+ * Ensure the print queue tdb doesn't grow too
+ * big by periodically scanning it.
+ */
+ process_print_queue(t);
+
+ /*
* Now we are root, check if the log files need pruning.
*/
if(need_to_check_log_size())
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 4442a1f71f..22a95fdd18 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -422,6 +422,10 @@ void exit_server(char *reason)
respond_to_all_remaining_local_messages();
+ /* Don't do this on every exit... */
+ if (sys_random() % 10)
+ process_print_queue(time(NULL));
+
#ifdef WITH_DFS
if (dcelogin_atmost_once) {
dfs_unlogin();