cell-info-do-not-delete-20040604
authorJeffrey Altman <jaltman@mit.edu>
Sat, 5 Jun 2004 07:02:39 +0000 (07:02 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Sat, 5 Jun 2004 07:02:39 +0000 (07:02 +0000)
* cm_cell.h: define new bit flag CM_CELLFLAG_VLSERVER_INVALID

* cm_cell.c, cm_ioctl.c:  Do not delete cell info either because
  it has been removed from the CellServDB file or because the
  volserver info becomes invalid due to dns ttl expiration.  This
  is necessary because the cell info is pointed to by other structures
  which require continued access to the cellname and username fields.

* cm_ioctl.c: provide UNC support for the MakeMountCmd

src/WINNT/afsd/cm_cell.c
src/WINNT/afsd/cm_cell.h
src/WINNT/afsd/cm_ioctl.c

index 3de3aa8..8107329 100644 (file)
@@ -69,7 +69,7 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags)
        char fullname[200]="";
 
        lock_ObtainWrite(&cm_cellLock);
-       for(cp = cm_allCellsp; cp; cp=cp->nextp) {
+       for (cp = cm_allCellsp; cp; cp=cp->nextp) {
                if (strcmp(namep, cp->namep) == 0) {
             strcpy(fullname, cp->namep);
             break;
@@ -79,7 +79,8 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags)
        if ((!cp && (flags & CM_FLAG_CREATE))
 #ifdef AFS_AFSDB_ENV
          /* if it's from DNS, see if it has expired */
-         || (cp && (cp->flags & CM_CELLFLAG_DNS) && (time(0) > cp->timeout))
+         || (cp && (cp->flags & CM_CELLFLAG_DNS) 
+         && ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID) || (time(0) > cp->timeout)))
 #endif
          ) {
         int dns_expired = 0;
@@ -106,30 +107,18 @@ cm_cell_t *cm_GetCell_Gen(char *namep, char *newnamep, long flags)
                     afsi_log("in cm_GetCell_gen cm_SearchCellByDNS(%s) returns code= %d fullname= %s", 
                              namep, code, fullname);
                     if (dns_expired) {
-                        if ( cm_allCellsp == cp )
-                            cm_allCellsp = cp->nextp;
-                        else {
-                            cm_cell_t *tcp;
-
-                            for(tcp = cm_allCellsp; tcp->nextp; tcp=tcp->nextp) {
-                                if ( tcp->nextp == cp ) {
-                                    tcp->nextp = cp->nextp;
-                                    break;
-                                }
-                            }
-                        }
-                    
-                        lock_FinalizeMutex(&cp->mx);
-                        free(cp->namep);
-                    }
+                        cp->flags |= CM_CELLFLAG_VLSERVER_INVALID;
+                        cp = NULL;  /* set cp to NULL to indicate error */
+                    } 
                 }
                 else {   /* got cell from DNS */
                     cp->flags |= CM_CELLFLAG_DNS;
+                    cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
                     cp->timeout = time(0) + ttl;
                 }
             }
 #endif
-            if (code) {
+            if (cp && code) {     /* free newly allocated memory */
                 free(cp);
                 cp = NULL;
                 goto done;
@@ -174,7 +163,7 @@ cm_cell_t *cm_FindCellByID(long cellID)
 {
        cm_cell_t *cp;
        int ttl;
-     int code;
+    int code;
 
        lock_ObtainWrite(&cm_cellLock);
        for(cp = cm_allCellsp; cp; cp=cp->nextp) {
@@ -184,17 +173,27 @@ cm_cell_t *cm_FindCellByID(long cellID)
 
 #ifdef AFS_AFSDB_ENV
        /* if it's from DNS, see if it has expired */
-       if (cp && cm_dnsEnabled && (cp->flags & CM_CELLFLAG_DNS) && (time(0) > cp->timeout)) {
-         code = cm_SearchCellByDNS(cp->namep, NULL, &ttl, cm_AddCellProc, cp);
-         if (code == 0) {   /* got cell from DNS */
-           cp->flags |= CM_CELLFLAG_DNS;
+       if (cp && cm_dnsEnabled && (cp->flags & CM_CELLFLAG_DNS) && 
+        ((cp->flags & CM_CELLFLAG_VLSERVER_INVALID) || (time(0) > cp->timeout))) {
+        /* must empty cp->vlServersp */
+        cm_FreeServerList(&cp->vlServersp);
+        cp->vlServersp = NULL;
+
+        code = cm_SearchCellByDNS(cp->namep, NULL, &ttl, cm_AddCellProc, cp);
+        if (code == 0) {   /* got cell from DNS */
+            cp->flags |= CM_CELLFLAG_DNS;
+            cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
 #ifdef DEBUG
-           fprintf(stderr, "cell %s: ttl=%d\n", cp->namep, ttl);
+            fprintf(stderr, "cell %s: ttl=%d\n", cp->namep, ttl);
 #endif
-           cp->timeout = time(0) + ttl;
-         }
-         /* if we fail to find it this time, we'll just do nothing and leave the
-            current entry alone */
+            cp->timeout = time(0) + ttl;
+        } else {
+            cp->flags |= CM_CELLFLAG_VLSERVER_INVALID;
+            cp = NULL;      /* return NULL to indicate failure */
+        }
+        /* if we fail to find it this time, we'll just do nothing and leave the
+         * current entry alone 
+         */
        }
 #endif /* AFS_AFSDB_ENV */
 
@@ -206,11 +205,11 @@ void cm_InitCell(void)
 {
        static osi_once_t once;
         
-        if (osi_Once(&once)) {
+    if (osi_Once(&once)) {
                lock_InitializeRWLock(&cm_cellLock, "cell global lock");
-                cm_allCellsp = NULL;
+        cm_allCellsp = NULL;
                osi_EndOnce(&once);
-        }
+    }
 }
 void cm_ChangeRankCellVLServer(cm_server_t *tsp)
 {
index bf03634..e462a7f 100644 (file)
@@ -23,8 +23,10 @@ typedef struct cm_cell {
         long timeout;                   /* if dns, time at which the server addrs expire */
 } cm_cell_t;
 
-#define CM_CELLFLAG_SUID       1       /* setuid flag; not yet used */
-#define CM_CELLFLAG_DNS         2       /* cell servers are from DNS */
+/* These are bit flag values */
+#define CM_CELLFLAG_SUID           1   /* setuid flag; not yet used */
+#define CM_CELLFLAG_DNS         2   /* cell servers are from DNS */
+#define CM_CELLFLAG_VLSERVER_INVALID 4  /* cell servers are invalid */
 
 extern void cm_InitCell(void);
 
index 754a3ea..1c3eba0 100644 (file)
@@ -51,6 +51,7 @@
 osi_mutex_t cm_Afsdsbmt_Lock;
 
 extern afs_int32 cryptall;
+extern char cm_NetbiosName[];
 
 void cm_InitIoctl(void)
 {
@@ -135,7 +136,6 @@ void TranslateExtendedChars(char *str)
 long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
        cm_scache_t **scpp)
 {
-    extern char cm_NetbiosName[];
        long code;
        cm_scache_t *substRootp;
     char * relativePath = ioctlp->inDatap;
@@ -206,7 +206,6 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
                        code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
                              CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
                              userp, shareName, reqp, &substRootp);
-            free(sharePath);
             if (code) return code;
 
                        code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
@@ -289,35 +288,101 @@ long cm_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
                         cm_scache_t **scpp, char *leafp)
 {
        long code;
-        char tbuffer[1024];
-        char *tp, *jp;
+    char tbuffer[1024];
+    char *tp, *jp;
        cm_scache_t *substRootp;
 
        strcpy(tbuffer, ioctlp->inDatap);
-        tp = strrchr(tbuffer, '\\');
+    tp = strrchr(tbuffer, '\\');
        jp = strrchr(tbuffer, '/');
        if (!tp)
                tp = jp;
        else if (jp && (tp - tbuffer) < (jp - tbuffer))
                tp = jp;
-        if (!tp) {
-               strcpy(tbuffer, "\\");
-                if (leafp) strcpy(leafp, ioctlp->inDatap);
-       }
-        else {
-               *tp = 0;
-                if (leafp) strcpy(leafp, tp+1);
+    if (!tp) {
+        strcpy(tbuffer, "\\");
+        if (leafp) 
+            strcpy(leafp, ioctlp->inDatap);
        }
+    else {
+        *tp = 0;
+        if (leafp) 
+            strcpy(leafp, tp+1);
+       }   
+
+    if (tbuffer[0] == tbuffer[1] &&
+        tbuffer[1] == '\\' && 
+        !_strnicmp(cm_NetbiosName,tbuffer+2,strlen(cm_NetbiosName))) 
+    {
+        char shareName[256];
+        char *sharePath;
+        int shareFound, i;
 
-       code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
-               CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
-               userp, ioctlp->tidPathp, reqp, &substRootp);
-       if (code) return code;
+        /* We may have found a UNC path. 
+         * If the first component is the NetbiosName,
+         * then throw out the second component (the submount)
+         * since it had better expand into the value of ioctl->tidPathp
+         */
+        char * p;
+        p = tbuffer + 2 + strlen(cm_NetbiosName) + 1;
+        if ( !_strnicmp("all", p, 3) )
+            p += 4;
+
+        for (i = 0; *p && *p != '\\'; i++,p++ ) {
+            shareName[i] = *p;
+        }
+        p++;                    /* skip past trailing slash */
+        shareName[i] = 0;       /* terminate string */
+
+        shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
+        if ( shareFound ) {
+            /* we found a sharename, therefore use the resulting path */
+            code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
+                             CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+                             userp, sharePath, reqp, &substRootp);
+            free(sharePath);
+            if (code) return code;
+
+                       code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+                         userp, NULL, reqp, scpp);
+                       if (code) return code;
+        } else {
+            /* otherwise, treat the name as a cellname mounted off the afs root.
+                        * This requires that we reconstruct the shareName string with 
+                        * leading and trailing slashes.
+                        */
+            p = tbuffer + 2 + strlen(cm_NetbiosName) + 1;
+                       if ( !_strnicmp("all", p, 3) )
+                               p += 4;
+
+                       shareName[0] = '/';
+                       for (i = 1; *p && *p != '\\'; i++,p++ ) {
+                               shareName[i] = *p;
+                       }
+                       p++;                    /* skip past trailing slash */
+                       shareName[i++] = '/';   /* add trailing slash */
+                       shareName[i] = 0;       /* terminate string */
+                       
+                       code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
+                             CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+                             userp, shareName, reqp, &substRootp);
+            if (code) return code;
+
+                       code = cm_NameI(substRootp, p, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+                         userp, NULL, reqp, scpp);
+                       if (code) return code;
+        }
+    } else {
+        code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
+                    CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+                    userp, ioctlp->tidPathp, reqp, &substRootp);
+        if (code) return code;
 
         code = cm_NameI(substRootp, tbuffer, CM_FLAG_FOLLOW,
-               userp, NULL, reqp, scpp);
-       if (code) return code;
-        
+                    userp, NULL, reqp, scpp);
+        if (code) return code;
+    }
+
        /* # of bytes of path */
         code = strlen(ioctlp->inDatap) + 1;
         ioctlp->inDatap += code;
@@ -1022,46 +1087,33 @@ long cm_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
     for(cp = cm_allCellsp; cp; cp=cp->nextp) 
     {
         long code;
-      top:
         /* delete all previous server lists - cm_FreeServerList will ask for write on cm_ServerLock*/
         cm_FreeServerList(&cp->vlServersp);
         cp->vlServersp = NULL;
         code = cm_SearchCellFile(cp->namep, cp->namep, cm_AddCellProc, cp);
-               if (code) {
 #ifdef AFS_AFSDB_ENV
+               if (code) {
             if (cm_dnsEnabled) {
                 int ttl;
                 code = cm_SearchCellByDNS(cp->namep, cp->namep, &ttl, cm_AddCellProc, cp);
-                if ( code ) {
-                    if ( cm_allCellsp == cp )
-                        cm_allCellsp = cp->nextp;
-                    else {
-                        for(tcp = cm_allCellsp; tcp->nextp; tcp=tcp->nextp) {
-                            if ( tcp->nextp == cp ) {
-                                tcp->nextp = cp->nextp;
-                                break;
-                            }
-                        }
-                    }   
-                    
-                    lock_FinalizeMutex(&cp->mx);
-                    free(cp->namep);
-                }
-                else {   /* got cell from DNS */
+                if ( code == 0 ) { /* got cell from DNS */
                     cp->flags |= CM_CELLFLAG_DNS;
+                    cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
                     cp->timeout = time(0) + ttl;
                 }
             }
-#endif /* AFS_AFSDB_ENV */
+        } 
+        else {
+            cp->flags &= ~CM_CELLFLAG_DNS;
         }
+#endif /* AFS_AFSDB_ENV */
         if (code) {
-            tcp = cp;
-            cp = cp->nextp;
-            free(tcp);
-            goto top;
+            cp->flags |= CM_CELLFLAG_VLSERVER_INVALID;
         }
-        else
+        else {
+            cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
             cm_RandomizeServer(&cp->vlServersp);
+        }
     }
     
     lock_ReleaseWrite(&cm_cellLock);