fs-sysname-20040619
authorJeffrey Altman <jaltman@mit.edu>
Sat, 19 Jun 2004 17:00:13 +0000 (17:00 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 19 Jun 2004 17:00:13 +0000 (17:00 +0000)
Begin the process of supporting multiple sysnames on Windows as is
done on Unix.  These changes replace the internal variable with a list
of sysnames.

Still to do:  change command line interface to allow entry of multiple
names; and replace cm_ExpandSysName() with code similar to Unix which
allows expansion of one element in the list at a time.

src/WINNT/afsd/cm_ioctl.c
src/WINNT/afsd/cm_ioctl.h
src/WINNT/afsd/cm_vnodeops.c
src/WINNT/afsd/fs.c

index c2b0c7c..cb35ba2 100644 (file)
@@ -1079,7 +1079,6 @@ long cm_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
     */  
   
     cm_cell_t *cp;
-    cm_cell_t *tcp;
   
     cm_SkipIoctlPath(ioctlp);
     lock_ObtainWrite(&cm_cellLock);
@@ -1137,30 +1136,94 @@ long cm_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp)
 
 long cm_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp)
 {
-       long setSysName;
-        char *cp;
+       long setSysName, foundname = 0;
+    char *cp, *cp2, inname[MAXSYSNAME], outname[MAXSYSNAME];
+    int t, count, num = 0;
+    char **sysnamelist[MAXSYSNAME];
         
        cm_SkipIoctlPath(ioctlp);
 
-        memcpy(&setSysName, ioctlp->inDatap, sizeof(long));
-        ioctlp->inDatap += sizeof(long);
+    memcpy(&setSysName, ioctlp->inDatap, sizeof(long));
+    ioctlp->inDatap += sizeof(long);
         
-        if (setSysName) {
-               strcpy(cm_sysName, ioctlp->inDatap);
+    if (setSysName) {
+        /* check my args */
+        if ( setSysName < 0 || setSysName > MAXNUMSYSNAMES )
+            return EINVAL;
+        cp2 = ioctlp->inDatap;
+        for ( cp=ioctlp->inDatap, count = 0; count < setSysName; count++ ) {
+            /* won't go past end of ioctlp->inDatap since maxsysname*num < ioctlp->inDatap length */
+            t = strlen(cp);
+            if (t >= MAXSYSNAME || t <= 0)
+                return EINVAL;
+            /* check for names that can shoot us in the foot */
+            if (*cp == '.' && (cp[1] == 0 || (cp[1] == '.' && cp[2] == 0)))
+                return EINVAL;
+            cp += t + 1;
         }
-        else {
+        /* args ok */
+
+        /* inname gets first entry in case we're being a translator */
+        /* (we are never a translator) */
+        t = strlen(ioctlp->inDatap);
+        memcpy(inname, ioctlp->inDatap, t + 1);
+        ioctlp->inDatap += t + 1;
+        num = count;
+    }
+
+    /* Not xlating, so local case */
+    if (!cm_sysName)
+        osi_panic("cm_IoctlSysName: !cm_sysName\n", __FILE__, __LINE__);
+
+    if (!setSysName) {      /* user just wants the info */
+        strcpy(outname, cm_sysName);
+        foundname = cm_sysNameCount;
+        *sysnamelist = cm_sysNameList;
+    } else {                /* Local guy; only root can change sysname */
+        /* clear @sys entries from the dnlc, once afs_lookup can
+         * do lookups of @sys entries and thinks it can trust them */
+        /* privs ok, store the entry, ... */
+        strcpy(cm_sysName, inname);
+        if (setSysName > 1) {       /* ... or list */
+            cp = ioctlp->inDatap;
+            for (count = 1; count < setSysName; ++count) {
+                if (!cm_sysNameList[count])
+                    osi_panic
+                        ("cm_IoctlSysName: no cm_sysNameList entry to write\n"
+                          , __FILE__, __LINE__);
+                t = strlen(cp);
+                memcpy(cm_sysNameList[count], cp, t + 1);  /* include null */
+                cp += t + 1;
+            }
+        }
+        cm_sysNameCount = setSysName;
+    }
+
+    if (!setSysName) {
                /* return the sysname to the caller */
-                setSysName = 1;        /* really means "found sys name */
                cp = ioctlp->outDatap;
-                memcpy(cp, &setSysName, sizeof(long));
-                cp += sizeof(long);    /* skip found flag */
-                strcpy(cp, cm_sysName);
-                cp += strlen(cp) + 1;  /* skip name and terminating null char */
-                ioctlp->outDatap = cp;
+        memcpy(cp, (char *)&foundname, sizeof(afs_int32));
+        cp += sizeof(afs_int32);       /* skip found flag */
+        if (foundname) {
+            strcpy(cp, outname);
+            cp += strlen(outname) + 1; /* skip name and terminating null char */
+            for ( count=1; count < foundname ; ++count) {   /* ... or list */
+                if ( !(*sysnamelist)[count] )
+                    osi_panic("cm_IoctlSysName: no cm_sysNameList entry to read\n"
+                               , __FILE__, __LINE__);
+                t = strlen((*sysnamelist)[count]);
+                if (t >= MAXSYSNAME)
+                    osi_panic("cm_IoctlSysName: sysname entry garbled\n"
+                               , __FILE__, __LINE__);
+                strcpy(cp, (*sysnamelist)[count]);
+                cp += t + 1;
+            }
         }
+        ioctlp->outDatap = cp;
+    }
         
        /* done: success */
-        return 0;
+    return 0;
 }
 
 long cm_IoctlGetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
index 4e9089e..c9ba932 100644 (file)
@@ -41,6 +41,12 @@ typedef struct cm_SSetPref {
 } cm_SSetPref_t;
 
 
+#define MAXNUMSYSNAMES    16      /* max that current constants allow */
+#define   MAXSYSNAME      128     /* max sysname (i.e. @sys) size */
+extern char *cm_sysName;
+extern int   cm_sysNameCount;
+extern char *cm_sysNameList[MAXNUMSYSNAMES];
+
 #ifndef __CM_IOCTL_INTERFACES_ONLY__
 
 void cm_InitIoctl(void);
index 00b90d3..3fc9bbf 100644 (file)
@@ -34,8 +34,6 @@ extern void afsi_log(char *pattern, ...);
 
 unsigned int cm_mountRootGen = 0;
 
-char cm_sysName[100];
-
 /*
  * Case-folding array.  This was constructed by inspecting of SMBtrace output.
  * I do not know anything more about it.
@@ -943,24 +941,24 @@ done:
 int cm_ExpandSysName(char *inp, char *outp, long outSize)
 {
        char *tp;
-        int prefixCount;
-        
-        tp = strrchr(inp, '@');
-        if (tp == NULL) return 0;              /* no @sys */
-        
-        if (strcmp(tp, "@sys") != 0) return 0; /* no @sys */
-        
+    int prefixCount;
+
+    tp = strrchr(inp, '@');
+    if (tp == NULL) return 0;          /* no @sys */
+
+    if (strcmp(tp, "@sys") != 0) return 0;     /* no @sys */
+
        /* caller just wants to know if this is a valid @sys type of name */
        if (outp == NULL) return 1;
 
        /* otherwise generate the properly expanded @sys name */
-        prefixCount = tp - inp;
-        
-        strncpy(outp, inp, prefixCount);       /* copy out "a." from "a.@sys" */
-        outp[prefixCount] = 0;                 /* null terminate the "a." */
-        strcat(outp, cm_sysName);              /* append i386_nt40 */
-        return 1;
-}
+    prefixCount = tp - inp;
+
+    strncpy(outp, inp, prefixCount);   /* copy out "a." from "a.@sys" */
+    outp[prefixCount] = 0;                     /* null terminate the "a." */
+    strcat(outp, cm_sysName);          /* append i386_nt40 */
+    return 1;
+}   
 
 long cm_Lookup(cm_scache_t *dscp, char *namep, long flags, cm_user_t *userp,
        cm_req_t *reqp, cm_scache_t **outpScpp)
index 560c255..cae83b6 100644 (file)
@@ -2096,9 +2096,9 @@ static SysNameCmd(as)
 register struct cmd_syndesc *as; {
     register afs_int32 code;
     struct ViceIoctl blob;
-    register struct cmd_item *ti;
+    struct cmd_item *ti;
     char *input = space;
-    afs_int32 setp = 1;
+    afs_int32 setp = 0;
     
     ti = as->parms[0].items;
     if (ti) {
@@ -2113,39 +2113,51 @@ register struct cmd_syndesc *as; {
         return EACCES;
     }
 #endif /* WIN32 */
-    } else {
-        setp = 0;
     }
+
     blob.in = space;
     blob.out = space;
     blob.out_size = MAXSIZE;
     blob.in_size = sizeof(afs_int32);
     memcpy(input, &setp, sizeof(afs_int32));
     input += sizeof(afs_int32);
-    if (ti) {
-       strcpy(input, ti->data);
-       blob.in_size += strlen(ti->data) + 1;
-       input += strlen(ti->data);
-       *(input++) = '\0';
+    for (; ti; ti = ti->next) {
+        setp++;
+        blob.in_size += strlen(ti->data) + 1;
+        if (blob.in_size > MAXSIZE) {
+            fprintf(stderr, "%s: sysname%s too long.\n", pn,
+                     setp > 1 ? "s" : "");
+            return 1;
+        }
+        strcpy(input, ti->data);
+        input += strlen(ti->data);
+        *(input++) = '\0';
     }
+    memcpy(space, &setp, sizeof(afs_int32));
     code = pioctl(0, VIOC_AFS_SYSNAME, &blob, 1);
     if (code) {
-       Die(errno, 0);
-       exit(1);
+        Die(errno, 0);
+        return 1;
     }    
     if (setp) {
-       printf("%s: new sysname set.\n", pn);
+        printf("%s: new sysname%s set.\n", pn, setp > 1 ? "s" : "");
+        return 0;
     }
-    else {
+
        input = space;
        memcpy(&setp, input, sizeof(afs_int32));
        input += sizeof(afs_int32);
        if (!setp) {
            fprintf(stderr,"No sysname name value was found\n");
-       } else {
-           printf("Current sysname is '%s'\n", input);
+        return 1;
+       } 
+    
+    printf("Current sysname%s", setp > 1 ? "s are" : " is");
+    for (; setp > 0; --setp ) {
+        printf(" \'%s\'", input);
+        input += strlen(input) + 1;
        }
-    }
+    printf("\n");
     return 0;
 }