[SCM] Samba Shared Repository - branch master updated

Andreas Schneider asn at samba.org
Fri Aug 8 08:34:04 MDT 2014


The branch, master has been updated
       via  1ad71f7 printing: reload printer shares on OpenPrinter
       via  2706af4 smbd: split printer reload processing
       via  2685df1 server: remove duplicate snum_is_shared_printer()
       via  a2182e0 smbd: only reprocess printer_list.tdb if it changed
       via  30ce835 printing: return last change time with pcap_cache_loaded()
       via  6d75e20 printing: remove pcap_cache_add()
       via  e5e6e2c printing: reload printer_list.tdb from in memory list
       via  4f4501a printing: only reload printer shares on client enum
       via  1e83435 printing: traverse_read the printer list for share updates
      from  9c5470b lib/krb5_wrap: provide krb5_warnx() replacement.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 1ad71f79eb473822d36d9629cf52c2fca4c53752
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Aug 5 17:33:33 2014 +0200

    printing: reload printer shares on OpenPrinter
    
    The printer share inventory should be reloaded on open _and_
    enumeration, as there are some clients, such as cupsaddsmb, that do not
    perform an enumeration prior to access.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10652
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    
    Autobuild-User(master): Andreas Schneider <asn at cryptomilk.org>
    Autobuild-Date(master): Fri Aug  8 16:33:50 CEST 2014 on sn-devel-104

commit 2706af4d78fc9a47a4ac45b373edf276e3a9b354
Author: David Disseldorp <ddiss at samba.org>
Date:   Fri Aug 1 16:25:59 2014 +0200

    smbd: split printer reload processing
    
    All printer inventory updates are currently done via
    delete_and_reload_printers(), which handles registry.tdb updates for
    added or removed printers, AD printer unpublishing on removal, as well
    as share service creation and deletion.
    
    This change splits this functionality into two functions such that
    per-client smbd processes do not perform registry.tdb updates or printer
    unpublishing. This is now only performed by the process that performs
    the printcap cache update.
    
    This change is similar to ac6604868d1325dd4c872dc0f6ab056d10ebaecf from
    the 3.6 branch.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10652
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 2685df1177ffd39b1af34eb116bd7b24d4b12974
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Aug 5 18:45:24 2014 +0200

    server: remove duplicate snum_is_shared_printer()
    
    Only keep a single definition in server_reload.c
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10652
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit a2182e03a061de6c1f111ce083cb5f668fe75e4e
Author: David Disseldorp <ddiss at samba.org>
Date:   Wed Jul 23 14:42:00 2014 +0200

    smbd: only reprocess printer_list.tdb if it changed
    
    The per-client smbd printer share inventory is currently updated from
    printer_list.tdb when a client enumerates printers, via EnumPrinters or
    NetShareEnum.
    printer_list.tdb is populated by the background print process, based on
    the latest printcap values retrieved from the printing backend (e.g.
    CUPS) at regular intervals.
    This change ensures that per-client smbd processes don't reparse
    printer_list.tdb if it hasn't been updated since the last enumeration.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10652
    
    Suggested-by: Volker Lendecke <vl at samba.org>
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 30ce835670a6aeca6fb960ea7c4fe1b982bdd5b0
Author: David Disseldorp <ddiss at samba.org>
Date:   Wed Jul 23 12:12:34 2014 +0200

    printing: return last change time with pcap_cache_loaded()
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10652
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 6d75e20ca8acf1a55838694ac77940e21e9a1e6a
Author: David Disseldorp <ddiss at samba.org>
Date:   Fri Jul 25 12:18:54 2014 +0200

    printing: remove pcap_cache_add()
    
    All print list updates are now done via pcap_cache_replace(), which can
    call into the print_list code directly.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10652
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit e5e6e2c796f026ee6b04f99b327941d57b9bd026
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Jul 22 20:17:38 2014 +0200

    printing: reload printer_list.tdb from in memory list
    
    This will allow in future for a single atomic printer_list.tdb update.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10652
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 4f4501ac1f35ab15f25d207c0d33e7c4d1abdf38
Author: David Disseldorp <ddiss at samba.org>
Date:   Fri Jul 11 17:00:05 2014 +0200

    printing: only reload printer shares on client enum
    
    Currently, automatic printer share updates are handled in the following
    way:
    - Background printer process (BPP) forked on startup
    - Parent smbd and per-client children await MSG_PRINTER_PCAP messages
    - BPP periodically polls the printing backend for printcap data
    	- printcap data written to printer_list.tdb
    	- MSG_PRINTER_PCAP sent to all smbd processes following update
    - smbd processes all read the latest printer_list.tdb data, and update
      their share listings
    
    This procedure is not scalable, as all smbd processes hit
    printer_list.tdb in parallel, resulting in a large spike in CPU usage.
    
    This change sees smbd processes only update their printer share lists
    only when a client asks for this information, e.g. via NetShareEnum or
    EnumPrinters.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10652
    
    Suggested-by: Volker Lendecke <vl at samba.org>
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 1e83435eac2cef03fccb4cf69ef5e0bfbd710410
Author: David Disseldorp <ddiss at samba.org>
Date:   Thu Jul 10 00:18:10 2014 +0200

    printing: traverse_read the printer list for share updates
    
    The printcap update procedure involves the background printer process
    obtaining the printcap information from the printing backend, writing
    this to printer_list.tdb, and then notifying all smbd processes of the
    new list. The processes then all attempt to simultaneously traverse
    printer_list.tdb, in order to update their local share lists.
    
    With a large number of printers, and a large number of per-client smbd
    processes, this traversal results in significant lock contention, mostly
    due to the fact that the traversal is unnecessarily done with an
    exclusive (write) lock on the printer_list.tdb database.
    
    This commit changes the share update code path to perform a read-only
    traversal.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10652
    
    Reported-by: Alex K <korobkin+samba at gmail.com>
    Reported-by: Franz Pförtsch <franz.pfoertsch at brose.com>
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/printing/load.c                     |    4 +-
 source3/printing/pcap.c                     |   54 +++++++-------
 source3/printing/pcap.h                     |   13 ++--
 source3/printing/print_aix.c                |   17 ++++-
 source3/printing/print_iprint.c             |   16 +++--
 source3/printing/print_standard.c           |    8 ++-
 source3/printing/print_svid.c               |   11 ++-
 source3/printing/printer_list.c             |   17 +++--
 source3/printing/printer_list.h             |    4 +-
 source3/printing/queue_process.c            |  102 +++++++++++++++++++++++++-
 source3/printing/spoolssd.c                 |   38 ++--------
 source3/rpc_server/spoolss/srv_spoolss_nt.c |   30 +++++---
 source3/rpc_server/srvsvc/srv_srvsvc_nt.c   |    1 +
 source3/smbd/lanman.c                       |    1 +
 source3/smbd/proto.h                        |    1 +
 source3/smbd/server.c                       |   20 -----
 source3/smbd/server_reload.c                |   74 ++++++++------------
 17 files changed, 241 insertions(+), 170 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/printing/load.c b/source3/printing/load.c
index 136d055..238998d 100644
--- a/source3/printing/load.c
+++ b/source3/printing/load.c
@@ -65,11 +65,11 @@ load automatic printer services from pre-populated pcap cache
 void load_printers(struct tevent_context *ev,
 		   struct messaging_context *msg_ctx)
 {
-	SMB_ASSERT(pcap_cache_loaded());
+	SMB_ASSERT(pcap_cache_loaded(NULL));
 
 	add_auto_printers();
 
 	/* load all printcap printers */
 	if (lp_load_printers() && lp_servicenumber(PRINTERS_NAME) >= 0)
-		pcap_printer_fn(lp_add_one_printer, NULL);
+		pcap_printer_read_fn(lp_add_one_printer, NULL);
 }
diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c
index dd7ba62..c5524ad 100644
--- a/source3/printing/pcap.c
+++ b/source3/printing/pcap.c
@@ -83,28 +83,26 @@ void pcap_cache_destroy_specific(struct pcap_cache **pp_cache)
 	*pp_cache = NULL;
 }
 
-bool pcap_cache_add(const char *name, const char *comment, const char *location)
-{
-	NTSTATUS status;
-	time_t t = time_mono(NULL);
-
-	status = printer_list_set_printer(talloc_tos(), name, comment, location, t);
-	return NT_STATUS_IS_OK(status);
-}
-
-bool pcap_cache_loaded(void)
+bool pcap_cache_loaded(time_t *_last_change)
 {
 	NTSTATUS status;
 	time_t last;
 
 	status = printer_list_get_last_refresh(&last);
-	return NT_STATUS_IS_OK(status);
+	if (!NT_STATUS_IS_OK(status)) {
+		return false;
+	}
+	if (_last_change != NULL) {
+		*_last_change = last;
+	}
+	return true;
 }
 
 bool pcap_cache_replace(const struct pcap_cache *pcache)
 {
 	const struct pcap_cache *p;
 	NTSTATUS status;
+	time_t t = time_mono(NULL);
 
 	status = printer_list_mark_reload();
 	if (!NT_STATUS_IS_OK(status)) {
@@ -113,7 +111,11 @@ bool pcap_cache_replace(const struct pcap_cache *pcache)
 	}
 
 	for (p = pcache; p; p = p->next) {
-		pcap_cache_add(p->name, p->comment, p->location);
+		status = printer_list_set_printer(talloc_tos(), p->name,
+						  p->comment, p->location, t);
+		if (!NT_STATUS_IS_OK(status)) {
+			return false;
+		}
 	}
 
 	status = printer_list_clean_old();
@@ -132,8 +134,8 @@ void pcap_cache_reload(struct tevent_context *ev,
 {
 	const char *pcap_name = lp_printcapname();
 	bool pcap_reloaded = False;
-	NTSTATUS status;
 	bool post_cache_fill_fn_handled = false;
+	struct pcap_cache *pcache = NULL;
 
 	DEBUG(3, ("reloading printcap cache\n"));
 
@@ -143,12 +145,6 @@ void pcap_cache_reload(struct tevent_context *ev,
 		return;
 	}
 
-	status = printer_list_mark_reload();
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("Failed to mark printer list for reload!\n"));
-		return;
-	}
-
 #ifdef HAVE_CUPS
 	if (strequal(pcap_name, "cups")) {
 		pcap_reloaded = cups_cache_reload(ev, msg_ctx,
@@ -164,26 +160,26 @@ void pcap_cache_reload(struct tevent_context *ev,
 
 #ifdef HAVE_IPRINT
 	if (strequal(pcap_name, "iprint")) {
-		pcap_reloaded = iprint_cache_reload();
+		pcap_reloaded = iprint_cache_reload(&pcache);
 		goto done;
 	}
 #endif
 
 #if defined(SYSV) || defined(HPUX)
 	if (strequal(pcap_name, "lpstat")) {
-		pcap_reloaded = sysv_cache_reload();
+		pcap_reloaded = sysv_cache_reload(&pcache);
 		goto done;
 	}
 #endif
 
 #ifdef AIX
 	if (strstr_m(pcap_name, "/qconfig") != NULL) {
-		pcap_reloaded = aix_cache_reload();
+		pcap_reloaded = aix_cache_reload(&pcache);
 		goto done;
 	}
 #endif
 
-	pcap_reloaded = std_pcap_cache_reload(pcap_name);
+	pcap_reloaded = std_pcap_cache_reload(pcap_name, &pcache);
 
 done:
 	DEBUG(3, ("reload status: %s\n", (pcap_reloaded) ? "ok" : "error"));
@@ -192,14 +188,16 @@ done:
 		/* cleanup old entries only if the operation was successful,
 		 * otherwise keep around the old entries until we can
 		 * successfully reload */
-		status = printer_list_clean_old();
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(0, ("Failed to cleanup printer list!\n"));
+
+		if (!pcap_cache_replace(pcache)) {
+			DEBUG(0, ("Failed to replace printer list!\n"));
 		}
+
 		if (post_cache_fill_fn != NULL) {
 			post_cache_fill_fn(ev, msg_ctx);
 		}
 	}
+	pcap_cache_destroy_specific(&pcache);
 
 	return;
 }
@@ -229,11 +227,11 @@ void pcap_printer_fn_specific(const struct pcap_cache *pc,
 	return;
 }
 
-void pcap_printer_fn(void (*fn)(const char *, const char *, const char *, void *), void *pdata)
+void pcap_printer_read_fn(void (*fn)(const char *, const char *, const char *, void *), void *pdata)
 {
 	NTSTATUS status;
 
-	status = printer_list_run_fn(fn, pdata);
+	status = printer_list_read_run_fn(fn, pdata);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(3, ("Failed to run fn for all printers!\n"));
 	}
diff --git a/source3/printing/pcap.h b/source3/printing/pcap.h
index 7056213..8fc9e9d 100644
--- a/source3/printing/pcap.h
+++ b/source3/printing/pcap.h
@@ -35,11 +35,10 @@ struct pcap_cache;
 
 bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment, const char *location);
 void pcap_cache_destroy_specific(struct pcap_cache **ppcache);
-bool pcap_cache_add(const char *name, const char *comment, const char *location);
-bool pcap_cache_loaded(void);
+bool pcap_cache_loaded(time_t *_last_change);
 bool pcap_cache_replace(const struct pcap_cache *cache);
 void pcap_printer_fn_specific(const struct pcap_cache *, void (*fn)(const char *, const char *, const char *, void *), void *);
-void pcap_printer_fn(void (*fn)(const char *, const char *, const char *, void *), void *);
+void pcap_printer_read_fn(void (*fn)(const char *, const char *, const char *, void *), void *);
 
 void pcap_cache_reload(struct tevent_context *ev,
 		       struct messaging_context *msg_ctx,
@@ -49,7 +48,7 @@ bool pcap_printername_ok(const char *printername);
 
 /* The following definitions come from printing/print_aix.c  */
 
-bool aix_cache_reload(void);
+bool aix_cache_reload(struct pcap_cache **_pcache);
 
 /* The following definitions come from printing/print_cups.c  */
 
@@ -60,13 +59,13 @@ bool cups_cache_reload(struct tevent_context *ev,
 
 /* The following definitions come from printing/print_iprint.c  */
 
-bool iprint_cache_reload(void);
+bool iprint_cache_reload(struct pcap_cache **_pcache);
 
 /* The following definitions come from printing/print_svid.c  */
 
-bool sysv_cache_reload(void);
+bool sysv_cache_reload(struct pcap_cache **_pcache);
 
 /* The following definitions come from printing/print_standard.c  */
-bool std_pcap_cache_reload(const char *pcap_name);
+bool std_pcap_cache_reload(const char *pcap_name, struct pcap_cache **_pcache);
 
 #endif /* _PRINTING_PCAP_H_ */
diff --git a/source3/printing/print_aix.c b/source3/printing/print_aix.c
index 23d9a86..927a71b 100644
--- a/source3/printing/print_aix.c
+++ b/source3/printing/print_aix.c
@@ -29,12 +29,13 @@
 #include "printing/pcap.h"
 
 #ifdef AIX
-bool aix_cache_reload(void)
+bool aix_cache_reload(struct pcap_cache **_pcache)
 {
 	int iEtat;
 	XFILE *pfile;
 	char *line = NULL, *p;
 	char *name = NULL;
+	struct pcap_cache *pcache = NULL;
 	TALLOC_CTX *ctx = talloc_init("aix_cache_reload");
 
 	if (!ctx) {
@@ -52,6 +53,8 @@ bool aix_cache_reload(void)
 	iEtat = 0;
 	/* scan qconfig file for searching <printername>:	*/
 	for (;(line = fgets_slash(NULL, 1024, pfile)); free(line)) {
+		bool ok;
+
 		if (*line == '*' || *line == 0)
 			continue;
 
@@ -67,6 +70,7 @@ bool aix_cache_reload(void)
 				if (strcmp(p, "bsh") != 0) {
 					name = talloc_strdup(ctx, p);
 					if (!name) {
+						pcap_cache_destroy_specific(&pcache);
 						SAFE_FREE(line);
 						x_fclose(pfile);
 						TALLOC_FREE(ctx);
@@ -86,7 +90,10 @@ bool aix_cache_reload(void)
 				/* name is found without stanza device  */
 				/* probably a good printer ???		*/
 				iEtat = 0;
-				if (!pcap_cache_add(name, NULL, NULL)) {
+				ok = pcap_cache_add_specific(&pcache,
+							     name, NULL, NULL);
+				if (!ok) {
+					pcap_cache_destroy_specific(&pcache);
 					SAFE_FREE(line);
 					x_fclose(pfile);
 					TALLOC_FREE(ctx);
@@ -101,7 +108,10 @@ bool aix_cache_reload(void)
 			} else if (strstr_m(line, "device")) {
 				/* it's a good virtual printer */
 				iEtat = 0;
-				if (!pcap_cache_add(name, NULL, NULL)) {
+				ok = pcap_cache_add_specific(&pcache,
+							     name, NULL, NULL);
+				if (!ok) {
+					pcap_cache_destroy_specific(&pcache);
 					SAFE_FREE(line);
 					x_fclose(pfile);
 					TALLOC_FREE(ctx);
@@ -113,6 +123,7 @@ bool aix_cache_reload(void)
 		}
 	}
 
+	*_pcache = pcache;
 	x_fclose(pfile);
 	TALLOC_FREE(ctx);
 	return true;
diff --git a/source3/printing/print_iprint.c b/source3/printing/print_iprint.c
index ad61a0a..eeb193c 100644
--- a/source3/printing/print_iprint.c
+++ b/source3/printing/print_iprint.c
@@ -206,7 +206,8 @@ static int iprint_get_server_version(http_t *http, char* serviceUri)
 
 static int iprint_cache_add_printer(http_t *http,
 				   int reqId,
-				   char* url)
+				   char *url,
+				   struct pcap_cache **pcache)
 {
 	ipp_t		*request = NULL,	/* IPP Request */
 			*response = NULL;	/* IPP Response */
@@ -342,7 +343,7 @@ static int iprint_cache_add_printer(http_t *http,
 		*/
 
 		if (name != NULL && !secure && smb_enabled) 
-			pcap_cache_add(name, info, NULL);
+			pcap_cache_add_specific(pcache, name, info, NULL);
 	}
 
  out:
@@ -351,7 +352,7 @@ static int iprint_cache_add_printer(http_t *http,
 	return(0);
 }
 
-bool iprint_cache_reload(void)
+bool iprint_cache_reload(struct pcap_cache **_pcache)
 {
 	http_t		*http = NULL;		/* HTTP connection to server */
 	ipp_t		*request = NULL,	/* IPP Request */
@@ -359,7 +360,8 @@ bool iprint_cache_reload(void)
 	ipp_attribute_t	*attr;			/* Current attribute */
 	cups_lang_t	*language = NULL;	/* Default language */
 	int		i;
-	bool ret = False;
+	bool ret = false;
+	struct pcap_cache *pcache = NULL;
 
 	DEBUG(5, ("reloading iprint printcap cache\n"));
 
@@ -441,14 +443,16 @@ bool iprint_cache_reload(void)
 					char *url = ippGetString(attr, i, NULL);
 					if (!url || !strlen(url))
 						continue;
-					iprint_cache_add_printer(http, i+2, url);
+					iprint_cache_add_printer(http, i+2, url,
+								 &pcache);
 				}
 			}
 			attr = ippNextAttribute(response);
 		}
 	}
 
-	ret = True;
+	ret = true;
+	*_pcache = pcache;
 
  out:
 	if (response)
diff --git a/source3/printing/print_standard.c b/source3/printing/print_standard.c
index c4f9c5b..b5f1056 100644
--- a/source3/printing/print_standard.c
+++ b/source3/printing/print_standard.c
@@ -59,10 +59,11 @@
 #include "printing/pcap.h"
 
 /* handle standard printcap - moved from pcap_printer_fn() */
-bool std_pcap_cache_reload(const char *pcap_name)
+bool std_pcap_cache_reload(const char *pcap_name, struct pcap_cache **_pcache)
 {
 	XFILE *pcap_file;
 	char *pcap_line;
+	struct pcap_cache *pcache = NULL;
 
 	if ((pcap_file = x_fopen(pcap_name, O_RDONLY, 0)) == NULL) {
 		DEBUG(0, ("Unable to open printcap file %s for read!\n", pcap_name));
@@ -117,12 +118,15 @@ bool std_pcap_cache_reload(const char *pcap_name)
 			}
 		}
 
-		if (*name && !pcap_cache_add(name, comment, NULL)) {
+		if ((*name != '\0')
+		 && !pcap_cache_add_specific(&pcache, name, comment, NULL)) {
 			x_fclose(pcap_file);
+			pcap_cache_destroy_specific(&pcache);
 			return false;
 		}
 	}
 
 	x_fclose(pcap_file);
+	*_pcache = pcache;
 	return true;
 }
diff --git a/source3/printing/print_svid.c b/source3/printing/print_svid.c
index 2226493..879661b 100644
--- a/source3/printing/print_svid.c
+++ b/source3/printing/print_svid.c
@@ -35,10 +35,11 @@
 #include "printing/pcap.h"
 
 #if defined(SYSV) || defined(HPUX)
-bool sysv_cache_reload(void)
+bool sysv_cache_reload(struct pcap_cache **_pcache)
 {
 	char **lines;
 	int i;
+	struct pcap_cache *pcache = NULL;
 
 #if defined(HPUX)
 	DEBUG(5, ("reloading hpux printcap cache\n"));
@@ -111,14 +112,16 @@ bool sysv_cache_reload(void)
 			*tmp = '\0';
 		
 		/* add it to the cache */
-		if (!pcap_cache_add(name, NULL, NULL)) {
+		if (!pcap_cache_add_specific(&pcache, name, NULL, NULL)) {
 			TALLOC_FREE(lines);
-			return False;
+			pcap_cache_destroy_specific(&pcache);
+			return false;
 		}
 	}
 
 	TALLOC_FREE(lines);
-	return True;
+	*_pcache = pcache;
+	return true;
 }
 
 #else
diff --git a/source3/printing/printer_list.c b/source3/printing/printer_list.c
index 4a66b96..9a9fa0b 100644
--- a/source3/printing/printer_list.c
+++ b/source3/printing/printer_list.c
@@ -284,7 +284,8 @@ done:
 typedef int (printer_list_trv_fn_t)(struct db_record *, void *);
 
 static NTSTATUS printer_list_traverse(printer_list_trv_fn_t *fn,
-						void *private_data)
+				      void *private_data,
+				      bool read_only)
 {
 	struct db_context *db;
 	NTSTATUS status;
@@ -294,7 +295,11 @@ static NTSTATUS printer_list_traverse(printer_list_trv_fn_t *fn,
 		return NT_STATUS_INTERNAL_DB_CORRUPTION;
 	}
 
-	status = dbwrap_traverse(db, fn, private_data, NULL);
+	if (read_only) {
+		status = dbwrap_traverse_read(db, fn, private_data, NULL);
+	} else {
+		status = dbwrap_traverse(db, fn, private_data, NULL);
+	}
 
 	return status;
 }
@@ -364,7 +369,7 @@ NTSTATUS printer_list_clean_old(void)
 
 	state.status = NT_STATUS_OK;
 
-	status = printer_list_traverse(printer_list_clean_fn, &state);
+	status = printer_list_traverse(printer_list_clean_fn, &state, false);
 	if (NT_STATUS_EQUAL(status, NT_STATUS_UNSUCCESSFUL) &&
 	    !NT_STATUS_IS_OK(state.status)) {
 		status = state.status;
@@ -417,8 +422,8 @@ static int printer_list_exec_fn(struct db_record *rec, void *private_data)
 	return 0;
 }
 
-NTSTATUS printer_list_run_fn(void (*fn)(const char *, const char *, const char *, void *),
-			     void *private_data)
+NTSTATUS printer_list_read_run_fn(void (*fn)(const char *, const char *, const char *, void *),
+				  void *private_data)
 {
 	struct printer_list_exec_state state;
 	NTSTATUS status;
@@ -427,7 +432,7 @@ NTSTATUS printer_list_run_fn(void (*fn)(const char *, const char *, const char *
 	state.private_data = private_data;
 	state.status = NT_STATUS_OK;
 
-	status = printer_list_traverse(printer_list_exec_fn, &state);
+	status = printer_list_traverse(printer_list_exec_fn, &state, true);
 	if (NT_STATUS_EQUAL(status, NT_STATUS_UNSUCCESSFUL) &&
 	    !NT_STATUS_IS_OK(state.status)) {
 		status = state.status;
diff --git a/source3/printing/printer_list.h b/source3/printing/printer_list.h
index fb2e007..b12c192 100644
--- a/source3/printing/printer_list.h
+++ b/source3/printing/printer_list.h
@@ -100,6 +100,6 @@ NTSTATUS printer_list_mark_reload(void);
  */
 NTSTATUS printer_list_clean_old(void);
 
-NTSTATUS printer_list_run_fn(void (*fn)(const char *, const char *, const char *, void *),
-			     void *private_data);
+NTSTATUS printer_list_read_run_fn(void (*fn)(const char *, const char *, const char *, void *),
+				  void *private_data);
 #endif /* _PRINTER_LIST_H_ */
diff --git a/source3/printing/queue_process.c b/source3/printing/queue_process.c
index aa0d0fb..88196b4 100644
--- a/source3/printing/queue_process.c
+++ b/source3/printing/queue_process.c
@@ -33,10 +33,102 @@
 #include "rpc_server/rpc_config.h"
 #include "printing/load.h"
 #include "rpc_server/spoolss/srv_spoolss_nt.h"
+#include "auth.h"
+#include "nt_printing.h"
 
 extern pid_t start_spoolssd(struct tevent_context *ev_ctx,
 			    struct messaging_context *msg_ctx);
 
+/**
+ * @brief Purge stale printers and reload from pre-populated pcap cache.
+ *
+ * This function should normally only be called as a callback on a successful
+ * pcap_cache_reload().
+ *
+ * This function can cause DELETION of printers and drivers from our registry,
+ * so calling it on a failed pcap reload may REMOVE permanently all printers
+ * and drivers.
+ *
+ * @param[in] ev        The event context.
+ *


-- 
Samba Shared Repository


More information about the samba-cvs mailing list