[PATCH][SAMBA3] msdfs janitorial path

James Peach jpeach at sgi.com
Tue Jun 28 06:22:53 GMT 2005


Hi all,

The attached patch against svn HEAD tidies up a few small issues with
the msdfs code:
    - adds and applies an "msdfs" debug channel
    - prevents a (possible but unlikely) buffer overrun with large numbers
      of DFS referrals
    - prevent a memory leak due to incomplete free'ing of a
      connection_struct in form_junctions()

-- 
James Peach | jpeach at sgi.com | SGI Australian Software Group
I don't speak for SGI.
-------------- next part --------------
Index: source/smbd/msdfs.c
===================================================================
--- source/smbd/msdfs.c	(revision 7977)
+++ source/smbd/msdfs.c	(working copy)
@@ -20,6 +20,7 @@
 
 */
 
+#define DBGC_CLASS DBGC_MSDFS
 #include "includes.h"
 
 extern uint32 global_client_caps;
@@ -576,7 +577,9 @@
 	requestedpathlen = rpcstr_push(uni_requestedpath, pathname, -1,
 				       STR_TERMINATE);
 
-	dump_data(10, (const char *) uni_requestedpath,requestedpathlen);
+	if (DEBUGLVL(10)) {
+	    dump_data(0, (const char *) uni_requestedpath,requestedpathlen);
+	}
 
 	DEBUG(10,("ref count = %u\n",junction->referral_count));
 
@@ -671,7 +674,9 @@
 
 	reqpathlen = rpcstr_push(uni_reqpath, pathname, -1, STR_TERMINATE);
 	
-	dump_data(10, (char *) uni_reqpath,reqpathlen);
+	if (DEBUGLVL(10)) {
+	    dump_data(0, (char *) uni_reqpath,reqpathlen);
+	}
 
 	uni_reqpathoffset1 = REFERRAL_HEADER_SIZE + VERSION3_REFERRAL_SIZE * junction->referral_count;
 	uni_reqpathoffset2 = uni_reqpathoffset1 + reqpathlen;
@@ -797,8 +802,11 @@
 		return -1;
 	}
       
-	DEBUG(10,("DFS Referral pdata:\n"));
-	dump_data(10,*ppdata,reply_size);
+	if (DEBUGLVL(10)) {
+	    DEBUGADD(0,("DFS Referral pdata:\n"));
+	    dump_data(0,*ppdata,reply_size);
+	}
+
 	return reply_size;
 }
 
@@ -937,29 +945,30 @@
 	return ret;
 }
 
-static BOOL form_junctions(int snum, struct junction_map* jucn, int* jn_count)
+static int form_junctions(int snum, struct junction_map* jucn, int jn_remain)
 {
-	int cnt = *jn_count;
+	int cnt = 0;
 	DIR *dirp;
 	char* dname;
 	pstring connect_path;
 	char* service_name = lp_servicename(snum);
-	connection_struct conns;
-	connection_struct *conn = &conns;
+	connection_struct conn;
 	struct referral *ref = NULL;
-	BOOL ret = False;
  
+	if (jn_remain <= 0)
+	    return(0);
+
 	pstrcpy(connect_path,lp_pathname(snum));
 
 	if(*connect_path == '\0')
-		return False;
+		return 0;
 
 	/*
 	 * Fake up a connection struct for the VFS layer.
 	 */
 
-	if (!create_conn_struct(conn, snum, connect_path))
-		return False;
+	if (!create_conn_struct(&conn, snum, connect_path))
+		return 0;
 
 	/* form a junction for the msdfs root - convention 
 	   DO NOT REMOVE THIS: NT clients will not work with us
@@ -979,22 +988,25 @@
 	ref->ttl = REFERRAL_TTL;
 	if (*lp_msdfs_proxy(snum) != '\0') {
 		pstrcpy(ref->alternate_path, lp_msdfs_proxy(snum));
-		*jn_count = ++cnt;
-		ret = True;
 		goto out;
 	}
 		
 	slprintf(ref->alternate_path, sizeof(pstring)-1,
 		 "\\\\%s\\%s", get_local_machine_name(), service_name);
 	cnt++;
-	
+
 	/* Now enumerate all dfs links */
-	dirp = SMB_VFS_OPENDIR(conn, ".", NULL, 0);
+	dirp = SMB_VFS_OPENDIR(&conn, ".", NULL, 0);
 	if(!dirp)
 		goto out;
 
-	while((dname = vfs_readdirname(conn, dirp)) != NULL) {
-		if (is_msdfs_link(conn, dname, &(jucn[cnt].referral_list),
+	while ((dname = vfs_readdirname(&conn, dirp)) != NULL) {
+		if (cnt >= jn_remain) {
+			SMB_VFS_CLOSEDIR(&conn,dirp);
+			DEBUG(2, ("ran out of MSDFS junction slots"));
+			goto out;
+		}
+		if (is_msdfs_link(&conn, dname, &(jucn[cnt].referral_list),
 				  &(jucn[cnt].referral_count), NULL)) {
 			pstrcpy(jucn[cnt].service_name, service_name);
 			pstrcpy(jucn[cnt].volume_name, dname);
@@ -1002,14 +1014,13 @@
 		}
 	}
 	
-	SMB_VFS_CLOSEDIR(conn,dirp);
-	*jn_count = cnt;
+	SMB_VFS_CLOSEDIR(&conn,dirp);
 out:
-	talloc_destroy(conn->mem_ctx);
-	return ret;
+	conn_free(&conn);
+	return cnt;
 }
 
-int enum_msdfs_links(struct junction_map* jucn)
+int enum_msdfs_links(struct junction_map* jucn, int jn_max)
 {
 	int i=0;
 	int jn_count = 0;
@@ -1017,9 +1028,9 @@
 	if(!lp_host_msdfs())
 		return 0;
 
-	for(i=0;i < lp_numservices();i++) {
+	for(i=0;i < lp_numservices() && (jn_max - jn_count) > 0;i++) {
 		if(lp_msdfs_root(i)) 
-			form_junctions(i,jucn,&jn_count);
+			jn_count += form_junctions(i,jucn,jn_max - jn_count);
 	}
 	return jn_count;
 }
Index: source/lib/debug.c
===================================================================
--- source/lib/debug.c	(revision 7977)
+++ source/lib/debug.c	(working copy)
@@ -166,6 +166,7 @@
 	"acls",		     /* DBGC_ACLS	  */
 	"printerdb",	     /* DBGC_PRINTERDB	  */
 	"locking",	     /* DBGC_LOCKING	  */
+	"msdfs",	     /* DBGC_MSDFS	  */
 	NULL
 };
 
Index: source/rpc_server/srv_dfs.c
===================================================================
--- source/rpc_server/srv_dfs.c	(revision 7977)
+++ source/rpc_server/srv_dfs.c	(working copy)
@@ -27,10 +27,8 @@
 #include "includes.h"
 #include "nterr.h"
 
-#define MAX_MSDFS_JUNCTIONS 256
-
 #undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
+#define DBGC_CLASS DBGC_MSDFS
 
 /**********************************************************************
  api_dfs_exist
Index: source/rpc_server/srv_dfs_nt.c
===================================================================
--- source/rpc_server/srv_dfs_nt.c	(revision 7977)
+++ source/rpc_server/srv_dfs_nt.c	(working copy)
@@ -27,10 +27,8 @@
 #include "nterr.h"
 
 #undef DBGC_CLASS
-#define DBGC_CLASS DBGC_RPC_SRV
+#define DBGC_CLASS DBGC_MSDFS
 
-#define MAX_MSDFS_JUNCTIONS 256
-
 /* This function does not return a WERROR or NTSTATUS code but rather 1 if
    dfs exists, or 0 otherwise. */
 
@@ -321,7 +319,7 @@
 	struct junction_map jn[MAX_MSDFS_JUNCTIONS];
 	int num_jn = 0;
 
-	num_jn = enum_msdfs_links(jn);
+	num_jn = enum_msdfs_links(jn, ARRAY_SIZE(jn));
 	vfs_ChDir(p->conn,p->conn->connectpath);
     
 	DEBUG(5,("make_reply_dfs_enum: %d junctions found in Dfs, doing level %d\n", num_jn, level));
Index: source/include/msdfs.h
===================================================================
--- source/include/msdfs.h	(revision 7977)
+++ source/include/msdfs.h	(working copy)
@@ -36,6 +36,7 @@
 
 /* Maximum number of referrals for each Dfs volume */
 #define MAX_REFERRAL_COUNT   256
+#define MAX_MSDFS_JUNCTIONS 256
 
 typedef struct _client_referral {
 	uint32 proximity;
Index: source/include/debug.h
===================================================================
--- source/include/debug.h	(revision 7977)
+++ source/include/debug.h	(working copy)
@@ -96,6 +96,7 @@
 #define DBGC_ACLS		15
 #define DBGC_PRINTERDB		16
 #define DBGC_LOCKING		17
+#define DBGC_MSDFS		18
 
 /* So you can define DBGC_CLASS before including debug.h */
 #ifndef DBGC_CLASS


More information about the samba-technical mailing list