Log binding ip address and port during startup
[openafs.git] / src / vlserver / vlprocs.c
index 75cf4d7..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)))
@@ -1660,7 +1666,8 @@ ListAttributesN2(struct rx_call *rxcall,
     int pollcount = 0;
     int namematchRWBK, namematchRO, thismatch;
     int matchtype = 0;
-    char volumename[VL_MAXNAMELEN+2]; /* regex anchors */
+    int size;
+    char volumename[VL_MAXNAMELEN+3]; /* regex anchors */
     char rxstr[AFS_RXINFO_LEN];
 #ifdef HAVE_POSIX_REGEX
     regex_t re;
@@ -1729,7 +1736,15 @@ 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)) {
-           sprintf(volumename, "^%s$", name);
+           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;
@@ -1774,7 +1789,12 @@ ListAttributesN2(struct rx_call *rxcall,
                    /* Does the name match the RW name */
                    if (tentry.flags & VLF_RWEXISTS) {
                        if (findname) {
-                           sprintf(volumename, "%s", tentry.name);
+                           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;
@@ -1792,7 +1812,13 @@ ListAttributesN2(struct rx_call *rxcall,
                    /* Does the name match the BK name */
                    if (!thismatch && (tentry.flags & VLF_BACKEXISTS)) {
                        if (findname) {
-                           sprintf(volumename, "%s.backup", tentry.name);
+                           /* 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;
@@ -1821,8 +1847,13 @@ ListAttributesN2(struct rx_call *rxcall,
                                thismatch =
                                    ((namematchRO == 1) ? VLSF_ROVOL : 0);
                            } else {
-                               sprintf(volumename, "%s.readonly",
-                                       tentry.name);
+                               /* 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;
@@ -3514,7 +3545,7 @@ ChangeIPAddr(struct vl_ctx *ctx, afs_uint32 ipaddr1, afs_uint32 ipaddr2)
     int i, j;
     afs_int32 code;
     struct extentaddr *exp = NULL;
-    int base;
+    int base = -1;
     int mhidx;
     afsUUID tuuid;
     afs_int32 blockindex, count;
@@ -3524,7 +3555,7 @@ ChangeIPAddr(struct vl_ctx *ctx, afs_uint32 ipaddr1, afs_uint32 ipaddr2)
     char addrbuf1[256];
     char addrbuf2[256];
 
-    /* Don't let addr change to 256.*.*.* : Causes internal error below */
+    /* Don't let addr change to 255.*.*.* : Causes internal error below */
     if ((ipaddr2 & 0xff000000) == 0xff000000)
        return (VL_BADSERVER);
 
@@ -3540,24 +3571,30 @@ ChangeIPAddr(struct vl_ctx *ctx, afs_uint32 ipaddr1, afs_uint32 ipaddr2)
     }
 
     for (i = 0; i <= MAXSERVERID; i++) {
-       code = multiHomedExtentBase(ctx, i, &exp, &base);
+       struct extentaddr *texp = NULL;
+       int tbase;
+
+       code = multiHomedExtentBase(ctx, i, &texp, &tbase);
        if (code)
            return code;
 
-       if (exp) {
+       if (texp) {
            for (mhidx = 0; mhidx < VL_MAXIPADDRS_PERMH; mhidx++) {
-               if (!exp->ex_addrs[mhidx])
+               if (!texp->ex_addrs[mhidx])
                    continue;
-               if (ntohl(exp->ex_addrs[mhidx]) == ipaddr1) {
+               if (ntohl(texp->ex_addrs[mhidx]) == ipaddr1) {
                    ipaddr1_id = i;
+                   exp = texp;
+                   base = tbase;
                }
-               if (ipaddr2 != 0 && ntohl(exp->ex_addrs[mhidx]) == ipaddr2) {
+               if (ipaddr2 != 0 && ntohl(texp->ex_addrs[mhidx]) == ipaddr2) {
                    ipaddr2_id = i;
                }
            }
        } else {
            if (ctx->hostaddress[i] == ipaddr1) {
                exp = NULL;
+               base = -1;
                ipaddr1_id = i;
            }
            if (ipaddr2 != 0 && ctx->hostaddress[i] == ipaddr2) {
@@ -3607,6 +3644,15 @@ ChangeIPAddr(struct vl_ctx *ctx, afs_uint32 ipaddr1, afs_uint32 ipaddr2)
                }
            }
        }
+    } else if (exp) {
+       /* Do not allow changing addresses in multi-homed entries.
+          Older versions of this RPC would silently "downgrade" mh entries
+          to single-homed entries and orphan the mh enties. */
+       addrbuf1[0] = '\0';
+       append_addr(addrbuf1, ipaddr1, sizeof(addrbuf1));
+       VLog(0, ("Refusing to change address %s in multi-homed entry; "
+                "use RegisterAddrs instead.\n", addrbuf1));
+       return VL_NOENT;        /* single-homed entry not found */
     }
 
     /* Log a message saying we are changing/removing an IP address */
@@ -3628,10 +3674,10 @@ ChangeIPAddr(struct vl_ctx *ctx, afs_uint32 ipaddr1, afs_uint32 ipaddr2)
     if (ipaddr2) {
        append_addr(addrbuf2, ipaddr2, sizeof(addrbuf2));
     }
-    VLog(0, ("      entry %d: [%s] -> [%s]\n", i, addrbuf1, addrbuf2));
+    VLog(0, ("      entry %d: [%s] -> [%s]\n", ipaddr1_id, addrbuf1, addrbuf2));
 
     /* Change the registered uuuid addresses */
-    if (exp) {
+    if (exp && base != -1) {
        memset(&tuuid, 0, sizeof(afsUUID));
        afs_htonuuid(&tuuid);
        exp->ex_hostuuid = tuuid;