[Samba] duplicate domains in browse list

Gerald (Jerry) Carter jerry at samba.org
Wed May 26 14:13:30 GMT 2004


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Joerg Pulz wrote:
| Hi,
|
| i recently upgraded some of my servers from 3.0.2a to 3.0.4
|
| after the upgrade my browselist shows duplicate entries
| for the domains. one domains is managed by a samba
| PDC(providing WINS too) and two samba  BDC's.
| the other domains are managed by one samba PDC.

Try this patch.






cheers, jerry
- ----------------------------------------------------------------------
Hewlett-Packard            ------------------------- http://www.hp.com
SAMBA Team                 ---------------------- http://www.samba.org
GnuPG Key                  ---- http://www.plainjoe.org/gpg_public.asc
"...a hundred billion castaways looking for a home." ----------- Sting
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFAtKYKIR7qMdg1EfYRAuiDAKCagpb3yqyFpHJ74TNcIOiP1RFLPgCfRQlq
VKobdBMtzVes0xBv8MIpdNs=
=P1de
-----END PGP SIGNATURE-----
-------------- next part --------------
Index: smbd/server.c
===================================================================
--- smbd/server.c	(revision 840)
+++ smbd/server.c	(working copy)
@@ -849,13 +849,14 @@
 	/* Setup the main smbd so that we can get messages. */
 	claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD);
 
-	/* 
-	   DO NOT ENABLE THIS TILL YOU COPE WITH KILLING THESE TASKS AND INETD
-	   THIS *killed* LOTS OF BUILD FARM MACHINES. IT CREATED HUNDREDS OF 
-	   smbd PROCESSES THAT NEVER DIE
-	   start_background_queue(); 
-	*/
+	/* only start the background queue daemon if we are 
+	   running as a daemon -- bad things will happen if
+	   smbd is launched via inetd and we fork a copy of 
+	   ourselves here */
 
+	if ( is_daemon )
+		start_background_queue(); 
+
 	if (!open_sockets_smbd(is_daemon, interactive, ports))
 		exit(1);
 
Index: printing/notify.c
===================================================================
--- printing/notify.c	(revision 840)
+++ printing/notify.c	(working copy)
@@ -463,6 +463,15 @@
 		snum, strlen(share_name) + 1, share_name);
 }
 
+void notify_printer_printername(int snum, char *printername)
+{
+	const char *printer_name = SERVICE(snum);
+
+	send_notify_field_buffer(
+		printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME,
+		snum, strlen(printername) + 1, printername);
+}
+
 void notify_printer_port(int snum, char *port_name)
 {
 	const char *printer_name = SERVICE(snum);
Index: printing/printing.c
===================================================================
--- printing/printing.c	(revision 840)
+++ printing/printing.c	(working copy)
@@ -23,6 +23,9 @@
 #include "includes.h"
 #include "printing.h"
 
+extern SIG_ATOMIC_T got_sig_term;
+extern SIG_ATOMIC_T reload_after_sighup;
+
 /* Current printer interface */
 static BOOL remove_from_jobs_changed(int snum, uint32 jobid);
 
@@ -971,7 +974,7 @@
  Update the internal database from the system print queue for a queue.
 ****************************************************************************/
 
-static void print_queue_update(int snum)
+static void print_queue_update_internal(int snum)
 {
 	int i, qcount;
 	print_queue_struct *queue = NULL;
@@ -1151,6 +1154,89 @@
 }
 
 /****************************************************************************
+this is the receive function of the background lpq updater
+****************************************************************************/
+static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len)
+{
+	int snum;
+	snum=*((int *)buf);
+	print_queue_update_internal(snum);
+}
+
+static pid_t background_lpq_updater_pid = -1;
+
+/****************************************************************************
+main thread of the background lpq updater
+****************************************************************************/
+void start_background_queue(void)
+{
+	DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
+	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);
+	}
+
+	if(background_lpq_updater_pid == 0) {
+		/* Child. */
+		DEBUG(5,("start_background_queue: background LPQ thread started\n"));
+
+		claim_connection( NULL, "smbd lpq backend", 0, False, 
+			FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINTING );
+
+		if (!locking_init(0)) {
+			exit(1);
+		}
+
+		if (!print_backend_init()) {
+			exit(1);
+		}
+
+		message_register(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) {
+                                exit_server("Caught TERM signal");
+                        }
+
+                        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();
+		}
+	}
+}
+
+/****************************************************************************
+update the internal database from the system print queue for a queue
+****************************************************************************/
+static void print_queue_update(int snum)
+{
+	/* 
+	 * Make sure that the backgroup queueu process exists.  
+	 * Otherwise just do the update ourselves 
+	 */
+	   
+	if ( background_lpq_updater_pid != -1 )
+		message_send_pid(background_lpq_updater_pid, MSG_PRINTER_UPDATE, &snum, sizeof(snum), False);
+	else
+		print_queue_update_internal( snum );
+}
+
+/****************************************************************************
  Create/Update an entry in the print tdb that will allow us to send notify
  updates only to interested smbd's. 
 ****************************************************************************/
Index: rpc_server/srv_spoolss_nt.c
===================================================================
--- rpc_server/srv_spoolss_nt.c	(revision 840)
+++ rpc_server/srv_spoolss_nt.c	(working copy)
@@ -473,9 +473,11 @@
 {
 	int snum;
 	int n_services=lp_numservices();
-	char *aprinter;
+	char *aprinter, *printername;
 	fstring sname;
 	BOOL found=False;
+	NT_PRINTER_INFO_LEVEL *printer;
+	WERROR result;
 	
 	DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename)));
 
@@ -496,16 +498,9 @@
 		aprinter=handlename;
 	}
 
-	DEBUGADD(5,("searching for [%s] (len=%lu)\n", aprinter, (unsigned long)strlen(aprinter)));
+	DEBUGADD(5, ("searching for [%s] (len=%lu)\n", aprinter, (unsigned long)strlen(aprinter)));
 
-	/*
-	 * The original code allowed smbd to store a printer name that
-	 * was different from the share name.  This is not possible 
-	 * anymore, so I've simplified this loop greatly.  Here
-	 * we are just verifying that the printer name is a valid
-	 * printer service defined in smb.conf
-	 *                          --jerry [Fri Feb 15 11:17:46 CST 2002]
-	 */
+	/* have to search on sharename and PRINTER_INFO2->printername */
 
 	for (snum=0; snum<n_services; snum++) {
 
@@ -514,13 +509,45 @@
 		
 		fstrcpy(sname, lp_servicename(snum));
 
-		DEBUGADD(5,("share:%s\n",sname));
+		DEBUGADD(10, ("share: %s\n",sname));
 		
-		if (! StrCaseCmp(sname, aprinter)) {
+		/* sharename */
+		if ( strequal(sname, aprinter) ) {
 			found = True;
 			break;
 		}
-
+		
+		/* printername */
+		printer = NULL;
+		result = get_a_printer( NULL, &printer, 2, sname );
+		if ( !W_ERROR_IS_OK(result) ) {
+			DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
+				sname, dos_errstr(result)));
+			continue;
+		}
+		
+		/* printername is always returned as \\server\printername */
+		if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
+			DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
+				printer->info_2->printername));
+			free_a_printer( &printer, 2);
+			continue;
+		}
+		
+		/* FIXME!! not mb safe here */
+		printername++;
+			
+		/* sharename */
+		if ( strequal(printername, aprinter) ) {
+			found = True;
+		}
+		
+		DEBUGADD(10, ("printername: %s\n", printername));
+		
+		free_a_printer( &printer, 2);
+		
+		if ( found )
+			break;
 	}
 
 		
@@ -5854,14 +5881,28 @@
 
 static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
 {
+	fstring printername;
+	const char *p;
+	
 	DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s portname=%s drivername=%s comment=%s location=%s\n",
 		 info->servername, info->printername, info->sharename, info->portname, info->drivername, info->comment, info->location));
 
 	/* we force some elements to "correct" values */
 	slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", get_called_name());
 	fstrcpy(info->sharename, lp_servicename(snum));
+	
+	/* make sure printername is in \\server\printername format */
+	
+	fstrcpy( printername, info->printername );
+	p = printername;
+	if ( printername[0] == '\\' && printername[1] == '\\' ) {
+		if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
+			p++;
+	}
+	
 	slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
-		 get_called_name(), info->sharename);
+		 get_called_name(), p );
+		 
 	info->attributes = PRINTER_ATTRIBUTE_SAMBA;
 	
 	
@@ -6057,14 +6098,28 @@
 
 	if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
 		init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
-		set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
-			REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
 		set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
 			REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
 
 		notify_printer_sharename(snum, printer->info_2->sharename);
 	}
 
+	if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
+		char *pname;
+		
+		if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
+			pname++;
+		else
+			pname = printer->info_2->printername;
+			
+
+		init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
+		set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
+			REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+
+		notify_printer_printername( snum, pname );
+	}
+	
 	if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
 		init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
 		set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
@@ -8750,19 +8805,19 @@
 	{
 		/* save the OID if one was specified */
 		if ( oid_string ) {
-		fstrcat( keyname, "\\" );
-		fstrcat( keyname, SPOOL_OID_KEY );
+			fstrcat( keyname, "\\" );
+			fstrcat( keyname, SPOOL_OID_KEY );
 		
-		/* 
-		 * I'm not checking the status here on purpose.  Don't know 
-		 * if this is right, but I'm returning the status from the 
-		 * previous set_printer_dataex() call.  I have no idea if 
-		 * this is right.    --jerry
-		 */
+			/* 
+			 * I'm not checking the status here on purpose.  Don't know 
+			 * if this is right, but I'm returning the status from the 
+			 * previous set_printer_dataex() call.  I have no idea if 
+			 * this is right.    --jerry
+			 */
 		 
-		set_printer_dataex( printer, keyname, valuename, 
-		                    REG_SZ, (void*)oid_string, strlen(oid_string)+1 );		
-	}
+			set_printer_dataex( printer, keyname, valuename, 
+			                    REG_SZ, (void*)oid_string, strlen(oid_string)+1 );		
+		}
 	
 		status = mod_a_printer(*printer, 2);
 	}
Index: include/messages.h
===================================================================
--- include/messages.h	(revision 840)
+++ include/messages.h	(working copy)
@@ -49,9 +49,10 @@
 
 /* printing messages */
 /* #define MSG_PRINTER_NOTIFY  2001*/ /* Obsolete */
-#define MSG_PRINTER_DRVUPGRADE 2002
-#define MSG_PRINTER_NOTIFY2     2003
+#define MSG_PRINTER_DRVUPGRADE		2002
+#define MSG_PRINTER_NOTIFY2		2003
 #define MSG_PRINTERDATA_INIT_RESET	2004
+#define MSG_PRINTER_UPDATE		2005
 
 /* smbd messages */
 #define MSG_SMB_CONF_UPDATED 3001


More information about the samba mailing list