summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2000-10-10 21:52:36 +0000
committerJeremy Allison <jra@samba.org>2000-10-10 21:52:36 +0000
commit5e09611acf02bff78647608274fb4a544c4f51a6 (patch)
treefe6864ebff9ff3a602cf440bcf3e93f13b8c479f
parentb17eadb2220c0fc85cea57466887c3ff9c6481ab (diff)
downloadsamba-5e09611acf02bff78647608274fb4a544c4f51a6.tar.gz
samba-5e09611acf02bff78647608274fb4a544c4f51a6.tar.xz
samba-5e09611acf02bff78647608274fb4a544c4f51a6.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.
-rw-r--r--source/include/proto.h1
-rw-r--r--source/printing/printing.c43
-rw-r--r--source/smbd/process.c6
-rw-r--r--source/smbd/server.c4
4 files changed, 53 insertions, 1 deletions
diff --git a/source/include/proto.h b/source/include/proto.h
index 4f4e22504ff..627f0d07eaf 100644
--- a/source/include/proto.h
+++ b/source/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/source/printing/printing.c b/source/printing/printing.c
index 9054c8f36a4..486ef5d2c72 100644
--- a/source/printing/printing.c
+++ b/source/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/source/smbd/process.c b/source/smbd/process.c
index 1599ade12d6..9ed83ec88c5 100644
--- a/source/smbd/process.c
+++ b/source/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/source/smbd/server.c b/source/smbd/server.c
index 4442a1f71f6..22a95fdd18c 100644
--- a/source/smbd/server.c
+++ b/source/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();