[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-102-g98e154c

Jeremy Allison jra at samba.org
Wed Oct 24 21:17:35 GMT 2007


The branch, v3-2-test has been updated
       via  98e154c3125d5732c37a72d74b0eb5cd7b6155fd (commit)
      from  4d4ab9aeb9d85b4c98cbf8a8363a9cefecd4b365 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit 98e154c3125d5732c37a72d74b0eb5cd7b6155fd
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Oct 24 14:16:54 2007 -0700

    This is a large patch (sorry). Migrate from struct in_addr
    to struct sockaddr_storage in most places that matter (ie.
    not the nmbd and NetBIOS lookups). This passes make test
    on an IPv4 box, but I'll have to do more work/testing on
    IPv6 enabled boxes. This should now give us a framework
    for testing and finishing the IPv6 migration. It's at
    the state where someone with a working IPv6 setup should
    (theorecically) be able to type :
    smbclient //ipv6-address/share
    and have it work.
    Jeremy.

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

Summary of changes:
 source/auth/auth_domain.c              |   20 +-
 source/auth/auth_server.c              |   10 +-
 source/client/client.c                 |   18 +-
 source/include/ads.h                   |    2 +-
 source/include/client.h                |    2 +-
 source/include/includes.h              |    2 +-
 source/include/smb.h                   |    4 +-
 source/include/smb_macros.h            |    5 +-
 source/lib/interface.c                 |   14 +-
 source/lib/util_sock.c                 |  206 +++++--
 source/lib/util_str.c                  |   83 ++-
 source/libads/kerberos.c               |   38 +-
 source/libads/krb5_setpw.c             |   28 +-
 source/libads/ldap.c                   |   35 +-
 source/libsmb/cliconnect.c             |  152 +++--
 source/libsmb/clidfs.c                 |   20 +-
 source/libsmb/clidgram.c               |   27 +-
 source/libsmb/clikrb5.c                |    4 +-
 source/libsmb/libsmbclient.c           |  106 ++--
 source/libsmb/namecache.c              |  156 +++--
 source/libsmb/namequery.c              | 1126 +++++++++++++++++++-------------
 source/libsmb/namequery_dc.c           |   75 ++-
 source/libsmb/nmblib.c                 |   15 +-
 source/libsmb/passchange.c             |    6 +-
 source/libsmb/trusts_util.c            |    6 +-
 source/nmbd/nmbd.c                     |   65 ++-
 source/nmbd/nmbd_become_dmb.c          |    2 +-
 source/nmbd/nmbd_browsesync.c          |    2 +-
 source/nmbd/nmbd_lmhosts.c             |   11 +-
 source/nmbd/nmbd_namelistdb.c          |    4 +-
 source/nmbd/nmbd_nameregister.c        |    2 +-
 source/nmbd/nmbd_packets.c             |    4 +-
 source/nmbd/nmbd_subnetdb.c            |    8 +-
 source/nmbd/nmbd_synclists.c           |    4 +-
 source/nmbd/nmbd_winsserver.c          |   24 +-
 source/nsswitch/winbind_krb5_locator.c |    4 +
 source/nsswitch/wins.c                 |   16 +-
 source/rpc_server/srv_netlog_nt.c      |    6 +-
 source/rpc_server/srv_spoolss_nt.c     |   30 +-
 source/rpcclient/rpcclient.c           |   46 +-
 source/smbd/change_trust_pw.c          |    6 +-
 source/smbd/server.c                   |  169 +++--
 source/torture/locktest.c              |   10 +-
 source/torture/masktest.c              |   10 +-
 source/torture/torture.c               |   10 +-
 source/utils/net.c                     |  196 ++++---
 source/utils/net.h                     |    2 +-
 source/utils/net_ads.c                 |   36 +-
 source/utils/net_lookup.c              |   93 ++-
 source/utils/net_rpc.c                 |   30 +-
 source/utils/net_rpc_join.c            |    6 +-
 source/utils/net_rpc_printer.c         |   13 +-
 source/utils/net_time.c                |   14 +-
 source/utils/netlookup.c               |   10 +-
 source/utils/nmblookup.c               |  400 +++++++-----
 source/utils/smbcacls.c                |   15 +-
 source/utils/smbcquotas.c              |   15 +-
 source/web/diagnose.c                  |   16 +-
 source/winbindd/winbindd.h             |    2 +-
 source/winbindd/winbindd_ads.c         |   18 +-
 source/winbindd/winbindd_cm.c          |  169 ++++--
 source/winbindd/winbindd_rpc.c         |   16 +-
 source/winbindd/winbindd_util.c        |    6 +-
 source/winbindd/winbindd_wins.c        |   74 ++-
 64 files changed, 2235 insertions(+), 1489 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/auth/auth_domain.c b/source/auth/auth_domain.c
index 72bdbab..7cddabb 100644
--- a/source/auth/auth_domain.c
+++ b/source/auth/auth_domain.c
@@ -42,7 +42,7 @@ extern bool global_machine_password_needs_changing;
 static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
 						const char *domain,
 						const char *dc_name,
-						struct in_addr dc_ip, 
+						struct sockaddr_storage *dc_ss, 
 						struct rpc_pipe_client **pipe_ret,
 						bool *retry)
 {
@@ -73,7 +73,7 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
 	
 	/* Attempt connection */
 	*retry = True;
-	result = cli_full_connection(cli, global_myname(), dc_name, &dc_ip, 0, 
+	result = cli_full_connection(cli, global_myname(), dc_name, dc_ss, 0, 
 		"IPC$", "IPC", "", "", "", 0, Undefined, retry);
 
 	if (!NT_STATUS_IS_OK(result)) {
@@ -183,7 +183,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
 					uchar chal[8],
 					auth_serversupplied_info **server_info, 
 					const char *dc_name,
-					struct in_addr dc_ip)
+					struct sockaddr_storage *dc_ss)
 
 {
 	NET_USER_INFO_3 info3;
@@ -207,7 +207,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
 		nt_status = connect_to_domain_password_server(&cli,
 							domain,
 							dc_name,
-							dc_ip,
+							dc_ss,
 							&netlogon_pipe,
 							&retry);
 	}
@@ -305,7 +305,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
 	NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
 	const char *domain = lp_workgroup();
 	fstring dc_name;
-	struct in_addr dc_ip;
+	struct sockaddr_storage dc_ss;
 
 	if ( lp_server_role() != ROLE_DOMAIN_MEMBER ) {
 		DEBUG(0,("check_ntdomain_security: Configuration error!  Cannot use "
@@ -331,7 +331,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
 
 	/* we need our DC to send the net_sam_logon() request to */
 
-	if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) {
+	if ( !get_dc_name(domain, NULL, dc_name, &dc_ss) ) {
 		DEBUG(5,("check_ntdomain_security: unable to locate a DC for domain %s\n",
 			user_info->domain));
 		return NT_STATUS_NO_LOGON_SERVERS;
@@ -343,7 +343,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
 					(uchar *)auth_context->challenge.data,
 					server_info,
 					dc_name,
-					dc_ip);
+					&dc_ss);
 		
 	return nt_status;
 }
@@ -377,7 +377,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
 	time_t last_change_time;
 	DOM_SID sid;
 	fstring dc_name;
-	struct in_addr dc_ip;
+	struct sockaddr_storage dc_ss;
 
 	if (!user_info || !server_info || !auth_context) {
 		DEBUG(1,("check_trustdomain_security: Critical variables not present.  Failing.\n"));
@@ -433,7 +433,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
 	/* use get_dc_name() for consistency even through we know that it will be 
 	   a netbios name */
 	   
-	if ( !get_dc_name(user_info->domain, NULL, dc_name, &dc_ip) ) {
+	if ( !get_dc_name(user_info->domain, NULL, dc_name, &dc_ss) ) {
 		DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n",
 			user_info->domain));
 		return NT_STATUS_NO_LOGON_SERVERS;
@@ -445,7 +445,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte
 					(uchar *)auth_context->challenge.data,
 					server_info,
 					dc_name,
-					dc_ip);
+					&dc_ss);
 
 	return nt_status;
 }
diff --git a/source/auth/auth_server.c b/source/auth/auth_server.c
index 815c119..8b10be9 100644
--- a/source/auth/auth_server.c
+++ b/source/auth/auth_server.c
@@ -33,7 +33,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
 {
 	struct cli_state *cli = NULL;
 	fstring desthost;
-	struct in_addr dest_ip;
+	struct sockaddr_storage dest_ss;
 	const char *p;
 	char *pserver;
 	bool connected_ok = False;
@@ -54,12 +54,12 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
 				   desthost, sizeof(desthost));
 		strupper_m(desthost);
 
-		if(!resolve_name( desthost, &dest_ip, 0x20)) {
+		if(!resolve_name( desthost, &dest_ss, 0x20)) {
 			DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost));
 			continue;
 		}
 
-		if (ismyip_v4(dest_ip)) {
+		if (ismyaddr(&dest_ss)) {
 			DEBUG(1,("Password server loop - disabling password server %s\n",desthost));
 			continue;
 		}
@@ -73,7 +73,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
 			return NULL;
 		}
 
-		status = cli_connect(cli, desthost, &dest_ip);
+		status = cli_connect(cli, desthost, &dest_ss);
 		if (NT_STATUS_IS_OK(status)) {
 			DEBUG(3,("connected to password server %s\n",desthost));
 			connected_ok = True;
@@ -91,7 +91,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
 	}
 	
 	if (!attempt_netbios_session_request(&cli, global_myname(), 
-					     desthost, &dest_ip)) {
+					     desthost, &dest_ss)) {
 		release_server_mutex();
 		DEBUG(1,("password server fails session request\n"));
 		cli_shutdown(cli);
diff --git a/source/client/client.c b/source/client/client.c
index f3d454e..7561ecb 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -79,7 +79,7 @@ static bool recurse = False;
 static bool showacls = False;
 bool lowercase = False;
 
-static struct in_addr dest_ip;
+static struct sockaddr_storage dest_ss;
 
 #define SEPARATORS " \t\n\r"
 
@@ -3839,7 +3839,7 @@ static int do_tar_op(char *base_directory)
 
 static int do_message_op(void)
 {
-	struct in_addr ip;
+	struct sockaddr_storage ss;
 	struct nmb_name called, calling;
 	fstring server_name;
 	char name_type_hex[10];
@@ -3853,9 +3853,9 @@ static int do_message_op(void)
 	snprintf(name_type_hex, sizeof(name_type_hex), "#%X", name_type);
 	fstrcat(server_name, name_type_hex);
 
-        zero_ip_v4(&ip);
-	if (have_ip) 
-		ip = dest_ip;
+        zero_addr(&ss,AF_INET);
+	if (have_ip)
+		ss = dest_ss;
 
 	/* we can only do messages over port 139 (to windows clients at least) */
 
@@ -3866,7 +3866,7 @@ static int do_message_op(void)
 		return 1;
 	}
 
-	status = cli_connect(cli, server_name, &ip);
+	status = cli_connect(cli, server_name, &ss);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("Connection to %s failed. Error %s\n", desthost, nt_errstr(status));
 		return 1;
@@ -3993,12 +3993,12 @@ static int do_message_op(void)
  			break;
 		case 'I':
 			{
-				dest_ip = *interpret_addr2(poptGetOptArg(pc));
-				if (is_zero_ip_v4(dest_ip))
+				if (!interpret_string_addr(&dest_ss, poptGetOptArg(pc), 0)) {
 					exit(1);
+				}
 				have_ip = True;
 
-				cli_cm_set_dest_ip( dest_ip );
+				cli_cm_set_dest_ss(&dest_ss);
 			}
 			break;
 		case 'E':
diff --git a/source/include/ads.h b/source/include/ads.h
index 37d09f1..a75eaf8 100644
--- a/source/include/ads.h
+++ b/source/include/ads.h
@@ -87,7 +87,7 @@ typedef struct ads_struct {
 #ifdef HAVE_LDAP
 	struct {
 		LDAP *ld;
-		struct in_addr ip; /* the ip of the active connection, if any */
+		struct sockaddr_storage ss; /* the ip of the active connection, if any */
 		time_t last_attempt; /* last attempt to reconnect */
 		int port;
 
diff --git a/source/include/client.h b/source/include/client.h
index 597348d..c4669db 100644
--- a/source/include/client.h
+++ b/source/include/client.h
@@ -112,7 +112,7 @@ struct cli_state {
 	struct nmb_name called;
 	struct nmb_name calling;
 	fstring full_dest_host_name;
-	struct in_addr dest_ip;
+	struct sockaddr_storage dest_ss;
 
 	DATA_BLOB secblob; /* cryptkey or negTokenInit */
 	uint32 sesskey;
diff --git a/source/include/includes.h b/source/include/includes.h
index 0d51c3d..fc9e43e 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -1123,7 +1123,7 @@ void krb5_free_unparsed_name(krb5_context ctx, char *val);
 #endif
 
 /* Samba wrapper function for krb5 functionality. */
-void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr);
+void setup_kaddr_v4( krb5_address *pkaddr, struct sockaddr *paddr);
 int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
 int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, krb5_enctype enctype);
 bool get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt);
diff --git a/source/include/smb.h b/source/include/smb.h
index 6d4effd..4c51acf 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -629,7 +629,7 @@ typedef struct connection_struct {
 	char *user; /* name of user who *opened* this connection */
 	uid_t uid; /* uid of user who *opened* this connection */
 	gid_t gid; /* gid of user who *opened* this connection */
-	char client_address[18]; /* String version of client IP address. */
+	char client_address[INET6_ADDRSTRLEN]; /* String version of client IP address. */
 
 	uint16 vuid; /* vuid of user who *opened* this connection, or UID_FIELD_INVALID */
 
@@ -1850,7 +1850,7 @@ typedef struct _smb_iconv_t {
 
 /* used by the IP comparison function */
 struct ip_service {
-	struct in_addr ip;
+	struct sockaddr_storage ss;
 	unsigned port;
 };
 
diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h
index aea429d..9af6345 100644
--- a/source/include/smb_macros.h
+++ b/source/include/smb_macros.h
@@ -206,11 +206,10 @@ values
 	 ((int)(tvalnew)->tv_usec - (int)(tvalold)->tv_usec)/1000)
 
 /****************************************************************************
-true if two IP addresses are equal
+true if two IPv4 addresses are equal
 ****************************************************************************/
 
-#define ip_equal(ip1,ip2) ((ip1).s_addr == (ip2).s_addr)
-#define ip_service_equal(ip1,ip2) ( ((ip1).ip.s_addr == (ip2).ip.s_addr) && ((ip1).port == (ip2).port) )
+#define ip_equal_v4(ip1,ip2) ((ip1).s_addr == (ip2).s_addr)
 
 /*****************************************************************
  splits out the last subkey of a key
diff --git a/source/lib/interface.c b/source/lib/interface.c
index 0696329..49bbcec 100644
--- a/source/lib/interface.c
+++ b/source/lib/interface.c
@@ -269,7 +269,7 @@ const struct sockaddr_storage *iface_ip(const struct sockaddr_storage *ip)
   return True if a IP is directly reachable on one of our interfaces
 */
 
-bool iface_local(struct sockaddr_storage *ip)
+bool iface_local(const struct sockaddr_storage *ip)
 {
 	return iface_find(ip, True) ? true : false;
 }
@@ -285,8 +285,7 @@ static void add_interface(const struct iface_struct *ifs)
 
 	if (iface_find(&ifs->ip, False)) {
 		DEBUG(3,("add_interface: not adding duplicate interface %s\n",
-			print_sockaddr(addr, sizeof(addr),
-				&ifs->ip, sizeof(struct sockaddr_storage)) ));
+			print_sockaddr(addr, sizeof(addr), &ifs->ip) ));
 		return;
 	}
 
@@ -317,16 +316,13 @@ static void add_interface(const struct iface_struct *ifs)
 
 	DEBUG(2,("added interface %s ip=%s ",
 		iface->name,
-		print_sockaddr(addr, sizeof(addr),
-			&iface->ip, sizeof(struct sockaddr_storage)) ));
+		print_sockaddr(addr, sizeof(addr), &iface->ip) ));
 	DEBUG(2,("bcast=%s ",
 		print_sockaddr(addr, sizeof(addr),
-			&iface->bcast,
-			sizeof(struct sockaddr_storage)) ));
+			&iface->bcast) ));
 	DEBUG(2,("netmask=%s\n",
 		print_sockaddr(addr, sizeof(addr),
-			&iface->netmask,
-			sizeof(struct sockaddr_storage)) ));
+			&iface->netmask) ));
 }
 
 /****************************************************************************
diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c
index c6b1311..2d78471 100644
--- a/source/lib/util_sock.c
+++ b/source/lib/util_sock.c
@@ -63,6 +63,27 @@ bool is_ipaddress(const char *str)
 	return is_ipaddress_v4(str);
 }
 
+/****************************************************************************
+ Is a sockaddr_storage a broadcast address ? 
+****************************************************************************/
+
+bool is_broadcast_addr(const struct sockaddr_storage *pss)
+{
+#if defined(HAVE_IPV6)
+	if (pss->ss_family == AF_INET6) {
+		const struct in6_addr *sin6 =
+			&((const struct sockaddr_in6 *)pss)->sin6_addr;
+		return IN6_IS_ADDR_MULTICAST(sin6);
+	}
+#endif
+	if (pss->ss_family == AF_INET) {
+		uint32_t addr =
+		ntohl(((const struct sockaddr_in *)pss)->sin_addr.s_addr);
+		return addr == INADDR_BROADCAST;
+	}
+	return false;
+}
+
 /*******************************************************************
  Wrap getaddrinfo...
 ******************************************************************/
@@ -181,7 +202,7 @@ bool interpret_string_addr(struct sockaddr_storage *pss,
 {
 	struct addrinfo *res = NULL;
 
-	memset(pss,'\0', sizeof(*pss));
+	zero_addr(pss, AF_INET);
 
 	if (!interpret_string_addr_internal(&res, str, flags|AI_ADDRCONFIG)) {
 		return false;
@@ -275,6 +296,17 @@ void zero_ip_v4(struct in_addr *ip)
 }
 
 /*******************************************************************
+ Set an address to INADDR_ANY, or IN6ADDR_ANY.
+******************************************************************/
+
+void zero_addr(struct sockaddr_storage *pss, int family)
+{
+	memset(pss, '\0', sizeof(*pss));
+	/* Ensure we're at least a valid sockaddr-storage. */
+	pss->ss_family = family;
+}
+
+/*******************************************************************
  Are two IPs on the same subnet - IPv4 version ?
 ********************************************************************/
 
@@ -385,7 +417,6 @@ bool addr_equal(const struct sockaddr_storage *ip1,
 	return false;
 }
 
-
 /****************************************************************************
  Is an IP address the INADDR_ANY or in6addr_any value ?
 ****************************************************************************/
@@ -417,7 +448,7 @@ bool is_address_any(const struct sockaddr_storage *psa)
  Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
 ****************************************************************************/
 
-char *print_sockaddr(char *dest,
+char *print_sockaddr_len(char *dest,
 			size_t destlen,
 			const struct sockaddr_storage *psa,
 			socklen_t psalen)
@@ -434,6 +465,75 @@ char *print_sockaddr(char *dest,
 }
 
 /****************************************************************************
+ Print out an IPv4 or IPv6 address from a struct sockaddr_storage.
+****************************************************************************/
+
+char *print_sockaddr(char *dest,
+			size_t destlen,
+			const struct sockaddr_storage *psa)
+{
+	return print_sockaddr_len(dest, destlen, psa, sizeof(*psa));
+}
+
+/****************************************************************************
+ Print out a canonical IPv4 or IPv6 address from a struct sockaddr_storage.
+****************************************************************************/
+
+char *print_canonical_sockaddr(TALLOC_CTX *ctx,
+			const struct sockaddr_storage *pss)
+{
+	char addr[INET6_ADDRSTRLEN];
+	char *dest = NULL;
+	int ret;
+
+	ret = getnameinfo((const struct sockaddr *)pss,
+			sizeof(struct sockaddr_storage),
+			addr, sizeof(addr),
+			NULL, 0,
+			NI_NUMERICHOST);
+	if (ret) {
+		return NULL;
+	}
+	if (pss->ss_family != AF_INET) {
+#if defined(HAVE_IPV6)
+		/* IPv6 */
+		const struct sockaddr_in6 *sa6 =
+			(const struct sockaddr_in6 *)pss;
+		uint16_t port = ntohs(sa6->sin6_port);
+
+		if (port) {
+			dest = talloc_asprintf(ctx,
+					"[%s]:%d",
+					addr,
+					(unsigned int)port);
+		} else {
+			dest = talloc_asprintf(ctx,
+					"[%s]",
+					addr);
+		}
+#else
+		return NULL;
+#endif
+	} else {
+		const struct sockaddr_in *sa =
+			(const struct sockaddr_in *)pss;
+		uint16_t port = ntohs(sa->sin_port);
+
+		if (port) {
+			dest = talloc_asprintf(ctx,
+					"%s:%d",
+					addr,
+					(unsigned int)port);
+		} else {
+			dest = talloc_asprintf(ctx,
+					"%s",
+					addr);
+		}
+	}
+	return dest;
+}
+
+/****************************************************************************
  Set the global client_fd variable.
 ****************************************************************************/
 
@@ -472,7 +572,7 @@ static const char *get_socket_addr(int fd)
 		return addr_buf;
 	}
 
-	return print_sockaddr(addr_buf, sizeof(addr_buf), &sa, length);
+	return print_sockaddr_len(addr_buf, sizeof(addr_buf), &sa, length);
 }
 
 /****************************************************************************
@@ -1274,24 +1374,26 @@ bool send_smb(int fd, char *buffer)
 ****************************************************************************/
 
 int open_socket_in(int type,
-		int port,
+		uint16_t port,
 		int dlevel,
-		uint32 socket_addr, /* NETWORK BYTE ORDER */
-		bool rebind )
+		const struct sockaddr_storage *psock,
+		bool rebind)
 {
-	struct sockaddr_in sock;
+	struct sockaddr_storage sock;
 	int res;
 
-	memset( (char *)&sock, '\0', sizeof(sock) );


-- 
Samba Shared Repository


More information about the samba-cvs mailing list