]> arthur.barton.de Git - netatalk.git/commitdiff
Fix handling of large number of volumes
authorRalph Boehme <sloowfranklin@gmail.com>
Wed, 11 Sep 2013 09:38:11 +0000 (11:38 +0200)
committerRalph Boehme <sloowfranklin@gmail.com>
Wed, 16 Oct 2013 08:41:02 +0000 (10:41 +0200)
o ensure only a maximum of 255 volumes is returned
o ensure the reply with the volume list fits in a certain buffer
  size, testing with 10.8.4 saw the maximum size the client would
  accept to be ~4600 bytes

Fixes bug #527

NEWS
etc/afpd/volume.c

diff --git a/NEWS b/NEWS
index cbf24f7f5fdd34a275d49f39121329fd2b4fbd60..4760eda2e09d848adf81dd9668b9b885d767ebaa 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,7 @@ Changes in 3.0.6
        "follow symlinks" is enabled. Bug #532.
 * FIX: Disable Kerberos UAM if AFP service principal name can't be
        evaluated. Fixes bug #531.
+* FIX: Fix handling of large number of volumes. Bug #527.
 
 Changes in 3.0.5
 ================
index 5f0d8a3786b3c945b84b5d59372e8d34cace4495..4efa659f02ee02eccb4f4f4fe53216ca606e5852 100644 (file)
@@ -535,7 +535,7 @@ int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf
     load_volumes(obj);
 
     data = rbuf + 5;
-    for ( vcnt = 0, volume = getvolumes(); volume; volume = volume->v_next ) {
+    for ( vcnt = 0, volume = getvolumes(); volume && vcnt < 255; volume = volume->v_next ) {
         if (!(volume->v_flags & AFPVOL_NOSTAT)) {
             struct maccess ma;
 
@@ -562,6 +562,14 @@ int afp_getsrvrparms(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf
         if (len == (size_t)-1)
             continue;
 
+        /*
+         * There seems to be an undocumented limit on how big our reply can get
+         * before the client chokes and closes the connection.
+         * Testing with 10.8.4 found the limit at ~4600 bytes. Go figure. 
+         */
+        if (((data + len + 3) - rbuf) > 4600)
+            break;
+
         /* set password bit if there's a volume password */
         *data = (volume->v_password) ? AFPSRVR_PASSWD : 0;