diff -ruN dovecot-1.1.11.orig/src/plugins/quota/quota-fs.c dovecot-1.1.11/src/plugins/quota/quota-fs.c
--- dovecot-1.1.11.orig/src/plugins/quota/quota-fs.c	2009-01-06 17:33:51.000000000 +0300
+++ dovecot-1.1.11/src/plugins/quota/quota-fs.c	2009-02-11 12:57:55.000000000 +0300
@@ -288,17 +288,26 @@
 
 #ifdef HAVE_RQUOTA
 /* retrieve user quota from a remote host */
-static int do_rquota(struct fs_quota_root *root, bool bytes,
+static int do_rquota(struct fs_quota_root *root, bool group, bool bytes,
 		     uint64_t *value_r, uint64_t *limit_r)
 {
-	struct getquota_rslt result;
-	struct getquota_args args;
-	struct timeval timeout;
+        struct getquota_rslt *result;
+        static struct getquota_rslt clnt_res;	
 	enum clnt_stat call_status;
-	CLIENT *cl;
+	CLIENT *clnt;
 	struct fs_quota_mountpoint *mount = root->mount;
 	const char *host;
 	char *path;
+	int type, id;	
+	struct timeval timeout = { 2, 0 };
+	
+	union {
+		getquota_args arg;
+		ext_getquota_args ext_arg;
+	} args;
+	
+	type = group ? GRPQUOTA : USRQUOTA;
+	id = group ? root->gid : root->uid;
 
 	path = strchr(mount->device_path, ':');
 	if (path == NULL) {
@@ -311,82 +320,211 @@
 	path++;
 
 	if (getenv("DEBUG") != NULL) {
+	    if (group) {
+		i_info("quota-fs: host=%s, path=%s, gid=%s",
+			host, path, dec2str(root->gid));
+	    } else {
 		i_info("quota-fs: host=%s, path=%s, uid=%s",
 			host, path, dec2str(root->uid));
+	    }
 	}
 
-	/* clnt_create() polls for a while to establish a connection */
-	cl = clnt_create(host, RQUOTAPROG, RQUOTAVERS, "udp");
-	if (cl == NULL) {
-		i_error("quota-fs: could not contact RPC service on %s",
-			host);
-		return -1;
-	}
-
-	/* Establish some RPC credentials */
-	auth_destroy(cl->cl_auth);
-	cl->cl_auth = authunix_create_default();
-
-	/* make the rquota call on the remote host */
-	args.gqa_pathp = path;
-	args.gqa_uid = root->uid;
-
-	timeout.tv_sec = RQUOTA_GETQUOTA_TIMEOUT_SECS;
-	timeout.tv_usec = 0;
-	call_status = clnt_call(cl, RQUOTAPROC_GETQUOTA,
-				(xdrproc_t)xdr_getquota_args, (char *)&args,
-				(xdrproc_t)xdr_getquota_rslt, (char *)&result,
-				timeout);
+	/*
+	 * First try EXT_RQUOTAPROG (Extended (LINUX) RPC quota program)
+	 */
+	args.ext_arg.gqa_pathp = path;
+	args.ext_arg.gqa_id = id;
+	args.ext_arg.gqa_type = type;
 	
-	/* the result has been deserialized, let the client go */
-	auth_destroy(cl->cl_auth);
-	clnt_destroy(cl);
-
-	if (call_status != RPC_SUCCESS) {
-		const char *rpc_error_msg = clnt_sperrno(call_status);
-
+	/*
+	 * Create a RPC client.
+	 */
+
+	if ((clnt = clnt_create(host, RQUOTAPROG, EXT_RQUOTAVERS, "udp")) != NULL) {
+	    /*
+	     * Initialize unix authentication
+	     */
+	    clnt->cl_auth = authunix_create_default();
+	    
+	    /*
+	     * Setup protocol timeout.
+	     */
+	    clnt_control(clnt, CLSET_TIMEOUT, (caddr_t) & timeout);
+
+	    /*
+	     * Do RPC call and check result.
+	     */	
+
+	    memset((char *)&clnt_res, 0, sizeof(clnt_res));		    
+	    call_status = clnt_call (clnt, RQUOTAPROC_GETQUOTA,
+				     (xdrproc_t) xdr_ext_getquota_args, (caddr_t) &args.ext_arg,
+				     (xdrproc_t) xdr_getquota_rslt, (caddr_t) &clnt_res,		
+				     timeout);	    
+	    result = &clnt_res;
+	    /*
+	     * Destroy unix authentication and RPC client structure.
+	     */
+	    auth_destroy(clnt->cl_auth);
+	    clnt_destroy(clnt);
+	    
+	    if (call_status != RPC_SUCCESS) {
+		const char *rpc_error_msg = clnt_sperrno(call_status);	    
 		i_error("quota-fs: remote rquota call failed: %s",
 			rpc_error_msg);
 		return -1;
-	}
-
-	switch (result.status) {
-	case Q_OK: {
+	    }
+	 
+	    switch (result->status) {
+	    case Q_OK: {
 		/* convert the results from blocks to bytes */
-		rquota *rq = &result.getquota_rslt_u.gqr_rquota;
+		rquota *rq = &result->getquota_rslt_u.gqr_rquota;
 
 		if (rq->rq_active) {
-			if (bytes) {
-				*value_r = (uint64_t)rq->rq_curblocks *
-					(uint64_t)rq->rq_bsize;
-				*limit_r = (uint64_t)rq->rq_bsoftlimit *
-					(uint64_t)rq->rq_bsize;
-			} else {
-				*value_r = rq->rq_curfiles;
-				*limit_r = rq->rq_fsoftlimit;
-			}
+		    if (bytes) {
+			*value_r = (uint64_t)rq->rq_curblocks *
+			    (uint64_t)rq->rq_bsize;
+			*limit_r = (uint64_t)rq->rq_bsoftlimit *
+			    (uint64_t)rq->rq_bsize;
+		    } else {
+			*value_r = rq->rq_curfiles;
+			*limit_r = rq->rq_fsoftlimit;
+		    }
 		}
 		if (getenv("DEBUG") != NULL) {
+		    if (group) {
+			i_info("quota-fs: gid=%s, value=%llu, "
+			       "limit=%llu, active=%d", dec2str(root->gid),
+			       (unsigned long long)*value_r,
+			       (unsigned long long)*limit_r, rq->rq_active);
+		    } else {
 			i_info("quota-fs: uid=%s, value=%llu, "
 			       "limit=%llu, active=%d", dec2str(root->uid),
 			       (unsigned long long)*value_r,
 			       (unsigned long long)*limit_r, rq->rq_active);
+		    }
 		}
 		return 1;
-	}
-	case Q_NOQUOTA:
+	    }
+	    case Q_NOQUOTA:
 		if (getenv("DEBUG") != NULL) {
+		    if (group) {
+			i_info("quota-fs: gid=%s, limit=unlimited",
+			       dec2str(root->gid));
+		    } else {
 			i_info("quota-fs: uid=%s, limit=unlimited",
 			       dec2str(root->uid));
+		    }
 		}
 		return 1;
-	case Q_EPERM:
+	    case Q_EPERM:
 		i_error("quota-fs: permission denied to rquota service");
 		return -1;
-	default:
+	    default:
 		i_error("quota-fs: unrecognized status code (%d) "
-			"from rquota service", result.status);
+			"from rquota service", result->status);
 		return -1;
+	    }	    
+	} else {
+	    result = NULL;
+	}
+	
+	if (result == NULL || !result->status) {
+		if (type == USRQUOTA) {
+		    /*
+		     * Try RQUOTAPROG because server doesn't seem to understand EXT_RQUOTAPROG. (NON-LINUX servers.)
+		     */
+		    args.arg.gqa_pathp = path;
+		    args.arg.gqa_uid = id;
+
+		    /*
+		     * Create a RPC client.
+		     */
+		    if ((clnt = clnt_create(host, RQUOTAPROG, RQUOTAVERS, "udp")) != NULL) {
+			/*
+			 * Initialize unix authentication
+			 */
+			clnt->cl_auth = authunix_create_default();
+			
+			/*
+			 * Setup protocol timeout.
+			 */
+			clnt_control(clnt, CLSET_TIMEOUT, (caddr_t) & timeout);
+			
+			/*
+			 * Do RPC call and check result.
+			 */
+			memset((char *)&clnt_res, 0, sizeof(clnt_res));
+			call_status = clnt_call (clnt, RQUOTAPROC_GETQUOTA,
+						 (xdrproc_t) xdr_getquota_args, (caddr_t) &args.arg,
+						 (xdrproc_t) xdr_getquota_rslt, (caddr_t) &clnt_res,		
+						 timeout);	
+			result = &clnt_res;
+			/*
+			 * Destroy unix authentication and RPC client structure.
+			 */
+			auth_destroy(clnt->cl_auth);
+			clnt_destroy(clnt);
+
+			if (call_status != RPC_SUCCESS) {
+			    const char *rpc_error_msg = clnt_sperrno(call_status);	    
+			    i_error("quota-fs: remote rquota call failed: %s",
+				    rpc_error_msg);
+			    return -1;
+			}
+			
+			switch (result->status) {
+			case Q_OK: {
+			    /* convert the results from blocks to bytes */
+			    rquota *rq = &result->getquota_rslt_u.gqr_rquota;
+			    
+			    if (rq->rq_active) {
+				if (bytes) {
+				    *value_r = (uint64_t)rq->rq_curblocks *
+					(uint64_t)rq->rq_bsize;
+				    *limit_r = (uint64_t)rq->rq_bsoftlimit *
+					(uint64_t)rq->rq_bsize;
+				} else {
+				    *value_r = rq->rq_curfiles;
+				    *limit_r = rq->rq_fsoftlimit;
+				}
+			    }
+			    if (getenv("DEBUG") != NULL) {
+				if (group) {
+				    i_info("quota-fs: gid=%s, value=%llu, "
+					   "limit=%llu, active=%d", dec2str(root->gid),
+					   (unsigned long long)*value_r,
+					   (unsigned long long)*limit_r, rq->rq_active);
+				} else {
+				    i_info("quota-fs: uid=%s, value=%llu, "
+					   "limit=%llu, active=%d", dec2str(root->uid),
+					   (unsigned long long)*value_r,
+					   (unsigned long long)*limit_r, rq->rq_active);
+				}
+			    }
+			    return 1;
+			}
+			case Q_NOQUOTA:
+			    if (getenv("DEBUG") != NULL) {
+				if (group) {
+				    i_info("quota-fs: gid=%s, limit=unlimited",
+					   dec2str(root->gid));
+				} else {
+				    i_info("quota-fs: uid=%s, limit=unlimited",
+			       dec2str(root->uid));
+				}
+			    }
+			    return 1;
+			case Q_EPERM:
+			    i_error("quota-fs: permission denied to rquota service");
+			    return -1;
+			default:
+			    i_error("quota-fs: unrecognized status code (%d) "
+				    "from rquota service", result->status);
+			    return -1;
+			}	    			
+			
+		    }
+		}
 	}
 }
 #endif
@@ -602,6 +740,7 @@
 	uint64_t limit = 0;
 	bool bytes;
 	int ret;
+	bool group;	
 
 	*value_r = 0;
 
@@ -614,7 +753,12 @@
 #ifdef HAVE_RQUOTA
 	if (strcmp(root->mount->type, "nfs") == 0) {
 		T_BEGIN {
-			ret = do_rquota(root, bytes, value_r, &limit);
+		    if (root->group_disabled){
+			group = FALSE;
+		    } else {
+			group = TRUE;
+		    }
+		    ret = do_rquota(root, group, bytes, value_r, &limit);
 		} T_END;
 	} else
 #endif
