REPOST: Patches for winbindd over TCP and a "failover port" option

Nir Soffer nirs at exanet.com
Tue Feb 18 16:30:25 GMT 2003


Very well then - but this might seriously screw up wrapping:
Our product uses Samba as a component. In our product we were forced to modify certain parts of Samba, namely:

Winbindd running over TCP (to a remote host)
Smbd listening to an additional "failover" port.
Allow listening on non-broadcast interfaces.

All these changes are very minimal.
In order to comply with the GPL and provide the community with what little code we've modified, attached is the patch file between this version and Samba 3.0a20. I'm afraid we've never merged it with later versions, since they never seemed to work.

There may be some other changes thrown here and there, they may or may not work.

Naturally, the usual disclaimer applies - I don't gurantee this code will work. It might even burn your computer. Use at your own risk.

I sincerely hope this helps people,

Regards,
Nir.

=== patch ===
diff -r -u /users4/nirs/tmp/samba-3.0alpha20/source/configure.developer ./configure.developer
--- /users4/nirs/tmp/samba-3.0alpha20/source/configure.developer	Tue Sep 25 07:08:05 2001
+++ ./configure.developer	Mon Jan  6 20:39:03 2003
@@ -1,2 +1,3 @@
 #!/bin/sh
+export CFLAGS="-DWITH_FO_PORT -DWITH_WINBIND_CFG"
 `dirname $0`/configure --enable-developer $*
Only in ./: configure.exanet
diff -r -u /users4/nirs/tmp/samba-3.0alpha20/source/install-sh ./install-sh
--- /users4/nirs/tmp/samba-3.0alpha20/source/install-sh	Wed Jul 29 06:06:48 1998
+++ ./install-sh	Thu Feb 28 17:25:58 2002
@@ -184,7 +184,7 @@
 	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
 	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
 	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
-	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; true; else true ; fi
 else
 
 # If we're going to rename the final executable, determine the name now.
diff -r -u /users4/nirs/tmp/samba-3.0alpha20/source/lib/interface.c ./lib/interface.c
--- /users4/nirs/tmp/samba-3.0alpha20/source/lib/interface.c	Mon Jul 15 18:10:42 2002
+++ ./lib/interface.c	Mon Jan  6 20:31:29 2003
@@ -61,8 +61,8 @@
 	}
 
 	if (ip_equal(nmask, allones_ip)) {
-		DEBUG(3,("not adding non-broadcast interface %s\n",inet_ntoa(ip)));
-		return;
+		DEBUG(3,("adding non-broadcast interface %s\n",inet_ntoa(ip)));
+		//return;
 	}
 
 	iface = (struct interface *)malloc(sizeof(*iface));
diff -r -u /users4/nirs/tmp/samba-3.0alpha20/source/nsswitch/wb_common.c ./nsswitch/wb_common.c
--- /users4/nirs/tmp/samba-3.0alpha20/source/nsswitch/wb_common.c	Thu Sep 26 22:38:34 2002
+++ ./nsswitch/wb_common.c	Mon Jan  6 20:39:03 2003
@@ -27,6 +27,15 @@
 #include "winbind_nss_config.h"
 #include "winbindd_nss.h"
 
+#ifdef WITH_WINBIND_CFG
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <fcntl.h>
+
+#define WINBIND_CFG "/etc/winbind.cfg"
+#endif /* WITH_WINBIND_CFG */
+
 /* Global variables.  These are effectively the client state information */
 
 int winbindd_fd = -1;           /* fd for winbindd socket */
@@ -146,6 +155,60 @@
 
 /* Connect to winbindd socket */
 
+#ifdef WITH_WINBIND_CFG
+int winbind_open_tcp_sock(int tcpport, char *ip)
+{
+    struct sockaddr_in servaddr;
+
+    if (winbindd_fd != -1) {
+            return winbindd_fd;
+    }    
+
+    bzero(&servaddr, sizeof(servaddr));  	
+    servaddr.sin_port = htons(tcpport);	
+    servaddr.sin_family = AF_INET;
+	       
+    if ((winbindd_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+		perror("socket");
+        return -1;
+	}
+ 
+    inet_pton(AF_INET, ip, &servaddr.sin_addr);        
+    free(ip);
+
+    if (connect (winbindd_fd, (struct sockaddr *) &servaddr, sizeof(servaddr)) !=0 ) {
+        close_sock();        
+        return -1;
+    }   
+
+	/* Return socket */
+	return winbindd_fd;
+}
+
+int read_wb_config(int *portnum, char **ip)
+{
+    int fd;
+    int port;
+    char s[300];
+    char p[50];
+    
+
+    if ((fd = open(WINBIND_CFG, O_RDONLY)) < 0) 
+    	return 0;
+
+    read(fd, s, 300);
+   
+    sscanf(s, "%s %d", p, &port);
+
+    *portnum = port;
+
+    *ip = malloc(strlen(p) + 1);
+    strcpy(*ip, p);
+ 
+    return 1;
+}
+#endif /* (ifdef WITH_WINBIND_CFG) */ 
+
 int winbind_open_pipe_sock(void)
 {
 #ifdef HAVE_UNIXSOCKET
@@ -232,15 +295,23 @@
 int write_sock(void *buffer, int count)
 {
 	int result, nwritten;
-	
+	int portnum;
+	char *ip;
+
 	/* Open connection to winbind daemon */
 	
- restart:
+	 restart:
 	
+#ifdef WITH_WINBIND_CFG
+	if (read_wb_config(&portnum, &ip)) {
+	   if (winbind_open_tcp_sock(portnum, ip) == -1 ) {
+		return -1;
+	   }
+	} else
+#endif  /* WITH_WINBIND_CFG */
 	if (winbind_open_pipe_sock() == -1) {
 		return -1;
 	}
-	
 	/* Write data to socket */
 	
 	nwritten = 0;
diff -r -u /users4/nirs/tmp/samba-3.0alpha20/source/nsswitch/winbindd.c ./nsswitch/winbindd.c
--- /users4/nirs/tmp/samba-3.0alpha20/source/nsswitch/winbindd.c	Thu Sep 26 22:38:35 2002
+++ ./nsswitch/winbindd.c	Mon Jan  6 20:39:04 2003
@@ -191,10 +191,41 @@
 
 /* Create winbindd socket */
 
-static int create_sock(void)
+static int create_sock(int tcpport)
 {
-	return create_pipe_sock( WINBINDD_SOCKET_DIR,
+    int                 listenfd;
+    struct sockaddr_in  servaddr;
+    const int on=1;
+
+    if ( tcpport > -1 ) {
+        listenfd = socket(AF_INET, SOCK_STREAM, 0);
+        setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
+        bzero(&servaddr, sizeof(servaddr));
+        
+        servaddr.sin_family      = AF_INET;
+        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+        servaddr.sin_port = htons(tcpport);
+
+        if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr))!=0) {
+            DEBUG(0, ("bind failed on winbind socket : %s\n",
+                  strerror(errno)));
+            close(listenfd);
+            return -1;
+        };
+    if (listen(listenfd, 5)!=0) {
+        DEBUG(0, ("listen failed on winbind socket : %s\n",
+                  strerror(errno)));
+        close(listenfd);
+        return -1;
+    }
+     /* Success! */
+    return listenfd;
+
+    } else {
+	    return create_pipe_sock( WINBINDD_SOCKET_DIR,
 				 WINBINDD_SOCKET_NAME, 0755);
+    }
 }
 
 struct dispatch_table {
@@ -516,8 +547,7 @@
 static void process_loop(int accept_sock)
 {
 	/* We'll be doing this a lot */
-
-	while (1) {
+  	while (1) {
 		struct winbindd_cli_state *state;
 		fd_set r_fds, w_fds;
 		int maxfd = accept_sock, selret;
@@ -747,6 +777,7 @@
 	printf("\t-n                disable cacheing\n");
 	printf("\t-d level          set debug level\n");
 	printf("\t-s configfile     choose smb.conf location\n");
+    printf("\t-l port           listen to tcp port [port]\n");
 	printf("\t-h                show this help message\n");
 }
 
@@ -760,6 +791,7 @@
 	int accept_sock;
 	BOOL interactive = False;
 	int opt;
+    int tcpport = -1;
 
 	/* glibc (?) likes to print "User defined signal 1" and exit if a
 	   SIGUSR[12] is received before a handler is installed */
@@ -788,7 +820,7 @@
 
 	/* Initialise samba/rpc client stuff */
 
-	while ((opt = getopt(argc, argv, "id:s:nhB")) != EOF) {
+	while ((opt = getopt(argc, argv, "id:s:nl:hB")) != EOF) {
 		switch (opt) {
 
 			/* Don't become a daemon */
@@ -821,6 +853,10 @@
 			usage();
 			exit(0);
 
+        case 'l':
+            tcpport=atoi(optarg);
+            break;
+
 		default:
 			printf("Unknown option %c\n", (char)opt);
 			exit(1);
@@ -885,9 +921,9 @@
 
 	register_msg_pool_usage();
 
-	/* Create UNIX domain socket */
+	/* Create socket */
 	
-	if ((accept_sock = create_sock()) == -1) {
+	if ((accept_sock = create_sock(tcpport)) == -1) {
 		DEBUG(0, ("failed to create socket\n"));
 		return 1;
 	}
diff -r -u /users4/nirs/tmp/samba-3.0alpha20/source/param/loadparm.c ./param/loadparm.c
--- /users4/nirs/tmp/samba-3.0alpha20/source/param/loadparm.c	Thu Sep 26 22:38:35 2002
+++ ./param/loadparm.c	Mon Jan  6 20:39:04 2003
@@ -205,6 +205,9 @@
 	int winbind_cache_time;
 	int iLockSpinCount;
 	int iLockSpinTime;
+#ifdef WITH_FO_PORT
+        int foport;
+#endif /* WITH_FO_PORT */
 	char *szLdapMachineSuffix;
 	char *szLdapUserSuffix;
 	int ldap_ssl;
@@ -1000,7 +1003,9 @@
 	{"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
 	{"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
 	{"share modes", P_BOOL, P_LOCAL,  &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
-
+#ifdef WITH_FO_PORT
+        {"failover port",P_INTEGER, P_GLOBAL, &Globals.foport, NULL, NULL, 0},
+#endif /* WITH_FO_PORT */
 	{"Ldap Options", P_SEP, P_SEPARATOR},
 	
 	{"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
@@ -1367,6 +1372,10 @@
 	   a large number of sites (tridge) */
 	Globals.bHostnameLookups = False;
 
+#ifdef WITH_FO_PORT
+    Globals.foport = -1;
+
+#endif /* WITH_FO_PORT */
 	string_set(&Globals.szLdapSuffix, "");
 	string_set(&Globals.szLdapMachineSuffix, "");
 	string_set(&Globals.szLdapUserSuffix, "");
@@ -1582,6 +1591,9 @@
 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
+#ifdef WITH_FO_PORT
+FN_GLOBAL_INTEGER(lp_foport, &Globals.foport)
+#endif /* FO_PORT */
 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
 FN_GLOBAL_STRING(lp_ldap_machine_suffix, &Globals.szLdapMachineSuffix)
 FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix)
diff -r -u /users4/nirs/tmp/samba-3.0alpha20/source/smbd/server.c ./smbd/server.c
--- /users4/nirs/tmp/samba-3.0alpha20/source/smbd/server.c	Thu Sep 26 22:38:36 2002
+++ ./smbd/server.c	Thu Jan  9 11:13:49 2003
@@ -156,8 +156,9 @@
 	int s;
 	int i;
 	char *ports;
+    int foport;
 
-	if (!is_daemon) {
+    if (!is_daemon) {
 		return open_sockets_inetd();
 	}
 
@@ -280,6 +281,38 @@
         message_register(MSG_SMB_SAM_REPL, msg_sam_repl);
         message_register(MSG_SHUTDOWN, msg_exit_server);
 
+
+#ifdef WITH_FO_PORT
+	    foport=lp_foport();
+
+	    if ( foport > -1 ) { 
+            /* open an incoming socket for failover */
+	        s = open_socket_in(SOCK_STREAM, foport, 0,
+		        interpret_addr(lp_socket_address()),True);
+	        if (s == -1) {
+		        DEBUG(1,("failed open_sockets for failover port\n"));
+		        return(False);
+	        }
+	        DEBUG(1,("opened failover socket. fd is %d\n", s));
+
+	        /* ready to listen */
+	        set_socket_options(s,"SO_KEEPALIVE"); 
+	        set_socket_options(s,user_socket_options);
+            if (listen(s, 5) == -1) {
+		        DEBUG(0,("open_sockets: listen: %s\n",
+		            strerror(errno)));
+		        close(s);
+		        return False;
+	        }
+	        DEBUG(1,("failover socket listening on %d\n", foport));
+
+	        fd_listenset[num_sockets] = s;
+	        FD_SET(s,&listen_set);
+	        num_sockets++;
+	    }
+
+#endif /* WITH_FO_PORT */
+                                        
 	/* now accept incoming connections - forking a new process
 	   for each incoming connection */
 	DEBUG(2,("waiting for a connection\n"));
@@ -322,7 +355,9 @@
 		for( ; num > 0; num--) {
 			struct sockaddr addr;
 			socklen_t in_addrlen = sizeof(addr);
-			
+#ifdef WITH_FO_PORT
+			int fosock=0;
+#endif /* WITH_FO_PORT */
 			s = -1;
 			for(i = 0; i < num_sockets; i++) {
 				if(FD_ISSET(fd_listenset[i],&lfds)) {
@@ -330,12 +365,21 @@
 					/* Clear this so we don't look
 					   at it again. */
 					FD_CLR(fd_listenset[i],&lfds);
+#ifdef WITH_FO_PORT
+                    /* foport is enabled and this is the last socket in the list */
+                        if ((foport > -1) && (i == num_sockets-1)) {
+                            fosock=1;
+                            DEBUG(1, ("open_sockets_smbd: Woke on select for failover port"));
+                        }
+#endif /* WITH_FO_PORT */
+                   
 					break;
 				}
 			}
-
+            DEBUG(1, ("open_sockets_smbd: before accept, num_sockets is %d, i is %d\n", num_sockets, i));
 			smbd_set_server_fd(accept(s,&addr,&in_addrlen));
-			
+			DEBUG(1, ("open_sockets_smbd: after accept, fd is %d\n", smbd_server_fd()));
+
 			if (smbd_server_fd() == -1 && errno == EINTR)
 				continue;
 			
@@ -344,7 +388,15 @@
 					 strerror(errno)));
 				continue;
 			}
-			
+#ifdef WITH_FO_PORT
+			if (smbd_server_fd() != -1 && fosock) {
+				close(smbd_server_fd());
+				smbd_set_server_fd(-1);
+                DEBUG(1, ("open_sockets_smbd: closed connection for fosock."));
+				continue;
+			}
+#endif /* WITH_FO_PORT */
+																			
 			if (smbd_server_fd() != -1 && sys_fork()==0) {
 				/* Child code ... */
 				
@@ -821,7 +873,7 @@
 
 	if (!is_daemon && !is_a_socket(0)) {
 		if (!interactive)
-			DEBUG(0,("standard input is not a socket, assuming -D option\n"));
+			DEBUG(1,("standard input is not a socket, assuming -D option\n"));
 
 		/*
 		 * Setting is_daemon here prevents us from eventually calling

--
Nir Soffer -=- Software Engineer, Exanet Inc. -=-
"The poor little kittens; They lost their mittens;
 And now you all must die. Mew, Mew, Mew, Mew, 
 And now you all must die." www.sluggy.com, 24/10/02

> -----Original Message-----
> From: Neil Hoggarth [mailto:neil.hoggarth at physiol.ox.ac.uk]
> Sent: Tuesday, February 18, 2003 6:26 PM
> To: Nir Soffer
> Cc: Guenther Deschner; 
> Subject: Re: Patches for winbindd over TCP and a "failover 
> port" option
> 
> 
> On Tue, 18 Feb 2003, Guenther Deschner wrote:
> 
> > you have forgotten to add that patchfile :)
> 
> Note that since last month the Samba listserver has started filtering
> message attachments:
> 
> http://lists.samba.org/pipermail/samba-technical/2003-January/
> 041954.html
> 
> Inline your patches in the message body, or make sure that your mail
> program flags them as content-type text/plain.
> 
> Regards,
> -- 
> Neil Hoggarth                                 Departmental 
> Computer Officer
> <neil.hoggarth at physiol.ox.ac.uk>                   Laboratory 
> of Physiology
> http://www.physiol.ox.ac.uk/~njh/                  University 
> of Oxford, UK
> 


More information about the samba-technical mailing list