]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/mountd/cache.c
mountd: fix path comparison for v4 crossmnt
[nfs-utils.git] / utils / mountd / cache.c
index e32290b72be60c5e368c67d4a71059bf3b201f5c..45397db66dcd8c66d36aad9f6608456ab16cf1de 100644 (file)
@@ -125,7 +125,7 @@ void auth_unix_gid(FILE *f)
         * reply is
         *  uid expiry count list of group ids
         */
-       int uid;
+       uid_t uid;
        struct passwd *pw;
        gid_t glist[100], *groups = glist;
        int ngroups = 100;
@@ -136,7 +136,7 @@ void auth_unix_gid(FILE *f)
                return;
 
        cp = lbuf;
-       if (qword_get_int(&cp, &uid) != 0)
+       if (qword_get_uint(&cp, &uid) != 0)
                return;
 
        pw = getpwuid(uid);
@@ -153,14 +153,14 @@ void auth_unix_gid(FILE *f)
                                                  groups, &ngroups);
                }
        }
-       qword_printint(f, uid);
-       qword_printint(f, time(0)+30*60);
+       qword_printuint(f, uid);
+       qword_printuint(f, time(0)+30*60);
        if (rv >= 0) {
-               qword_printint(f, ngroups);
+               qword_printuint(f, ngroups);
                for (i=0; i<ngroups; i++)
-                       qword_printint(f, groups[i]);
+                       qword_printuint(f, groups[i]);
        } else
-               qword_printint(f, 0);
+               qword_printuint(f, 0);
        qword_eol(f);
 
        if (groups != glist)
@@ -614,6 +614,33 @@ static int dump_to_cache(FILE *f, char *domain, char *path, struct exportent *ex
        return qword_eol(f);
 }
 
+static int is_subdirectory(char *subpath, char *path)
+{
+       int l = strlen(path);
+
+       return strcmp(subpath, path) == 0
+               || (strncmp(subpath, path, l) == 0 && subpath[l] == '/');
+}
+
+static int path_matches(nfs_export *exp, char *path)
+{
+       if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT)
+               return is_subdirectory(path, exp->m_export.e_path);
+       return strcmp(path, exp->m_export.e_path) == 0;
+}
+
+static int client_matches(nfs_export *exp, char *dom, struct hostent *he)
+{
+       if (use_ipaddr)
+               return client_check(exp->m_client, he);
+       return client_member(dom, exp->m_client->m_hostname);
+}
+
+static int export_matches(nfs_export *exp, char *dom, char *path, struct hostent *he)
+{
+       return path_matches(exp, path) && client_matches(exp, dom, he);
+}
+
 static nfs_export *lookup_export(char *dom, char *path, struct hostent *he)
 {
        nfs_export *exp;
@@ -621,33 +648,20 @@ static nfs_export *lookup_export(char *dom, char *path, struct hostent *he)
        int found_type = 0;
        int i;
 
-       found = lookup_export(dom, path, he);
-       /* now find flags for this export point in this domain */
        for (i=0 ; i < MCL_MAXTYPES; i++) {
                for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
-                       if (!use_ipaddr && !client_member(dom, exp->m_client->m_hostname))
+                       if (!export_matches(exp, dom, path, he))
                                continue;
-                       if (exp->m_export.e_flags & NFSEXP_CROSSMOUNT) {
-                               /* if path is a mountpoint below e_path, then OK */
-                               int l = strlen(exp->m_export.e_path);
-                               if (strcmp(path, exp->m_export.e_path) == 0 ||
-                                   (strncmp(path, exp->m_export.e_path, l) == 0 &&
-                                    path[l] == '/' &&
-                                    is_mountpoint(path)))
-                                       /* ok */;
-                               else
-                                       continue;
-                       } else if (strcmp(path, exp->m_export.e_path) != 0)
-                               continue;
-                       if (use_ipaddr) {
-                               if (!client_check(exp->m_client, he))
-                                       continue;
-                       }
                        if (!found) {
                                found = exp;
                                found_type = i;
                                continue;
                        }
+
+                       /* Always prefer non-V4ROOT mounts */
+                       if (found->m_export.e_flags & NFSEXP_V4ROOT)
+                               continue;
+
                        /* If one is a CROSSMOUNT, then prefer the longest path */
                        if (((found->m_export.e_flags & NFSEXP_CROSSMOUNT) ||
                             (exp->m_export.e_flags & NFSEXP_CROSSMOUNT)) &&