vlserver: --enable-ubik-read-while-write configure option
[openafs.git] / src / vlserver / vlprocs.c
index 4377616..016ff51 100644 (file)
@@ -206,8 +206,11 @@ Init_VLdbase(struct vl_ctx *ctx,
            code = ubik_BeginTrans(VL_dbase, UBIK_WRITETRANS, &ctx->trans);
            wl = 1;
        } else if (locktype == LOCKREAD) {
-           code =
-               ubik_BeginTransReadAnyWrite(VL_dbase, UBIK_READTRANS, &ctx->trans);
+#ifdef UBIK_READ_WHILE_WRITE
+           code = ubik_BeginTransReadAnyWrite(VL_dbase, UBIK_READTRANS, &ctx->trans);
+#else
+           code = ubik_BeginTransReadAny(VL_dbase, UBIK_READTRANS, &ctx->trans);
+#endif
            wl = 0;
        } else {
            code = ubik_BeginTrans(VL_dbase, UBIK_WRITETRANS, &ctx->trans);
@@ -624,6 +627,9 @@ GetEntryByName(struct rx_call *rxcall,
     if (NameIsId(volname)) {
        return GetEntryByID(rxcall, strtoul(volname, NULL, 10), -1, aentry, new, this_op);
     }
+
+    countRequest(this_op);
+
     if (InvalidVolname(volname))
        return VL_BADNAME;
     if ((code = Init_VLdbase(&ctx, LOCKREAD, this_op)))
@@ -1656,10 +1662,12 @@ ListAttributesN2(struct rx_call *rxcall,
     afs_int32 blockindex = 0, count = 0, k, match;
     afs_int32 matchindex = 0;
     int serverindex = -1;      /* no server found */
-    int findserver = 0, findpartition = 0, findflag = 0;
+    int findserver = 0, findpartition = 0, findflag = 0, findname = 0;
     int pollcount = 0;
     int namematchRWBK, namematchRO, thismatch;
     int matchtype = 0;
+    int size;
+    char volumename[VL_MAXNAMELEN+3]; /* regex anchors */
     char rxstr[AFS_RXINFO_LEN];
 #ifdef HAVE_POSIX_REGEX
     regex_t re;
@@ -1713,7 +1721,8 @@ ListAttributesN2(struct rx_call *rxcall,
     }
 
     /* Search each entry in the database and return all entries
-     * that match the request. It checks entry flags, server, and partition.
+     * that match the request. It checks volumename (with
+     * wildcarding), entry flags, server, and partition.
      */
     else {
        /* Get the server index for matching server address */
@@ -1727,9 +1736,29 @@ ListAttributesN2(struct rx_call *rxcall,
        findpartition = ((attributes->Mask & VLLIST_PARTITION) ? 1 : 0);
        findflag = ((attributes->Mask & VLLIST_FLAG) ? 1 : 0);
        if (name && (strcmp(name, ".*") != 0) && (strcmp(name, "") != 0)) {
-           /* regex-matching code has been disabled for security reasons. */
-           code = VL_BADNAME;
-           goto done;
+           if (!afsconf_SuperUser(vldb_confdir, rxcall, NULL)) {
+               code = VL_PERM;
+               goto done;
+           }
+           size = snprintf(volumename, sizeof(volumename), "^%s$", name);
+           if (size < 0 || size >= sizeof(volumename)) {
+               code = VL_BADNAME;
+               goto done;
+           }
+#ifdef HAVE_POSIX_REGEX
+           if (regcomp(&re, volumename, REG_NOSUB) != 0) {
+               code = VL_BADNAME;
+               goto done;
+           }
+           need_regfree = 1;
+#else
+           t = (char *)re_comp(volumename);
+           if (t) {
+               code = VL_BADNAME;
+               goto done;
+           }
+#endif
+           findname = 1;
        }
 
        /* Read each entry and see if it is the one we want */
@@ -1759,12 +1788,49 @@ ListAttributesN2(struct rx_call *rxcall,
                if (tentry.serverFlags[k] & VLSF_RWVOL) {
                    /* Does the name match the RW name */
                    if (tentry.flags & VLF_RWEXISTS) {
-                       thismatch = VLSF_RWVOL;
+                       if (findname) {
+                           size = snprintf(volumename, sizeof(volumename),
+                                           "%s", tentry.name);
+                           if (size < 0 || size >= sizeof(volumename)) {
+                               code = VL_BADNAME;
+                               goto done;
+                           }
+#ifdef HAVE_POSIX_REGEX
+                           if (regexec(&re, volumename, 0, NULL, 0) == 0) {
+                               thismatch = VLSF_RWVOL;
+                           }
+#else
+                           if (re_exec(volumename)) {
+                               thismatch = VLSF_RWVOL;
+                           }
+#endif
+                       } else {
+                           thismatch = VLSF_RWVOL;
+                       }
                    }
 
                    /* Does the name match the BK name */
                    if (!thismatch && (tentry.flags & VLF_BACKEXISTS)) {
-                       thismatch = VLSF_BACKVOL;
+                       if (findname) {
+                           /* If this fails, the tentry.name is invalid */
+                           size = snprintf(volumename, sizeof(volumename),
+                                           "%s.backup", tentry.name);
+                           if (size < 0 || size >= sizeof(volumename)) {
+                               code = VL_BADNAME;
+                               goto done;
+                           }
+#ifdef HAVE_POSIX_REGEX
+                           if (regexec(&re, volumename, 0, NULL, 0) == 0) {
+                               thismatch = VLSF_BACKVOL;
+                           }
+#else
+                           if (re_exec(volumename)) {
+                               thismatch = VLSF_BACKVOL;
+                           }
+#endif
+                       } else {
+                           thismatch = VLSF_BACKVOL;
+                       }
                    }
 
                    namematchRWBK = (thismatch ? 1 : 2);
@@ -1776,7 +1842,30 @@ ListAttributesN2(struct rx_call *rxcall,
                 */
                else {
                    if (tentry.flags & VLF_ROEXISTS) {
-                       thismatch = VLSF_ROVOL;
+                       if (findname) {
+                           if (namematchRO) {
+                               thismatch =
+                                   ((namematchRO == 1) ? VLSF_ROVOL : 0);
+                           } else {
+                               /* If this fails, the tentry.name is invalid */
+                               size = snprintf(volumename, sizeof(volumename),
+                                               "%s.readonly", tentry.name);
+                               if (size < 0 || size >= sizeof(volumename)) {
+                                   code = VL_BADNAME;
+                                   goto done;
+                               }
+#ifdef HAVE_POSIX_REGEX
+                           if (regexec(&re, volumename, 0, NULL, 0) == 0) {
+                               thismatch = VLSF_ROVOL;
+                           }
+#else
+                               if (re_exec(volumename))
+                                   thismatch = VLSF_ROVOL;
+#endif
+                           }
+                       } else {
+                           thismatch = VLSF_ROVOL;
+                       }
                    }
                    namematchRO = (thismatch ? 1 : 2);
                }