windows-freelance-symlink-20041027
authorJeffrey Altman <jaltman@mit.edu>
Thu, 28 Oct 2004 02:13:51 +0000 (02:13 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Thu, 28 Oct 2004 02:13:51 +0000 (02:13 +0000)
 * Remove the fallback to KRB4 in afskfw when obtaining tokens

 * Add support for symlinks to Freelance root.afs volume
   Stored at HKLM\SOFTWARE\OpenAFS\Client\Freelance\Symlinks
       <number>  =  "<linkname>:<relative-path>."
   Use symlink.exe to create, list, or remove

src/WINNT/afsd/afskfw.c
src/WINNT/afsd/cm_freelance.c
src/WINNT/afsd/cm_freelance.h
src/WINNT/afsd/cm_ioctl.c
src/WINNT/afsd/cm_scache.c
src/WINNT/afsd/symlink.c

index c0b31ec..01ace95 100644 (file)
@@ -56,7 +56,7 @@
 
 
 #define USE_MS2MIT
-#define USE_KRB4
+#undef  USE_KRB4
 #include "afskfw-int.h"
 #include "afskfw.h"
 
@@ -288,6 +288,7 @@ FUNC_INFO k5_fi[] = {
     END_FUNC_INFO
 };
 
+#ifdef USE_KRB4
 FUNC_INFO k4_fi[] = {
     MAKE_FUNC_INFO(krb_get_cred),
     MAKE_FUNC_INFO(krb_get_tf_realm),
@@ -295,6 +296,7 @@ FUNC_INFO k4_fi[] = {
     MAKE_FUNC_INFO(tkt_string),
     END_FUNC_INFO
 };
+#endif
 
 FUNC_INFO k524_fi[] = {
     MAKE_FUNC_INFO(krb524_init_ets),
@@ -388,7 +390,9 @@ KFW_initialize(void)
         if ( !inited ) {
             inited = 1;
             LoadFuncs(KRB5_DLL, k5_fi, &hKrb5, 0, 1, 0, 0);
+#ifdef USE_KRB4
             LoadFuncs(KRB4_DLL, k4_fi, &hKrb4, 0, 1, 0, 0);
+#endif /* USE_KRB4 */
             LoadFuncs(COMERR_DLL, ce_fi, &hComErr, 0, 0, 1, 0);
             LoadFuncs(SERVICE_DLL, service_fi, &hService, 0, 1, 0, 0);
 #ifdef USE_MS2MIT
@@ -2639,7 +2643,8 @@ KFW_AFS_klog(
         }       
     }
 #else
-    goto cleanup;
+    if (!try_krb5)
+        goto cleanup;
 #endif
     strcpy(realm_of_cell, afs_realm_of_cell(ctx, &ak_cellconfig));
 
@@ -2696,7 +2701,7 @@ KFW_AFS_klog(
         code = pkrb5_get_credentials(ctx, 0, cc, &increds, &k5creds);
         if (code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
              code == KRB5KRB_ERR_GENERIC /* heimdal */ ||
-                        code == KRB5KRB_AP_ERR_MSG_TYPE) {
+             code == KRB5KRB_AP_ERR_MSG_TYPE) {
             /* Or service@REALM */
             pkrb5_free_principal(ctx,increds.server);
             increds.server = 0;
@@ -2726,7 +2731,7 @@ KFW_AFS_klog(
 
         if ((code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
               code == KRB5KRB_ERR_GENERIC /* heimdal */ ||
-                         code == KRB5KRB_AP_ERR_MSG_TYPE) &&
+              code == KRB5KRB_AP_ERR_MSG_TYPE) &&
              strcmp(RealmName, realm_of_cell)) {
             /* Or service/cell@REALM_OF_CELL */
             strcpy(RealmName, realm_of_cell);
@@ -3017,7 +3022,7 @@ KFW_AFS_klog(
     if (ctx && (ctx != alt_ctx))
         pkrb5_free_context(ctx);
 
-       return(rc? rc : code);
+    return(rc? rc : code);
 }
 
 /**************************************/
index 2933c0f..e6b0a85 100644 (file)
@@ -73,6 +73,45 @@ void cm_FreelanceChangeNotifier(void * parmp) {
         }
     }
 }
+
+void cm_FreelanceSymlinkChangeNotifier(void * parmp) {
+    HANDLE hFreelanceSymlinkChangeEvent = 0;
+    HKEY   hkFreelance = 0;
+
+    if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, 
+                      "SOFTWARE\\OpenAFS\\Client\\Freelance\\Symlinks",
+                      0,
+                      KEY_NOTIFY,
+                      &hkFreelance) == ERROR_SUCCESS) {
+
+        hFreelanceSymlinkChangeEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+        if (hFreelanceSymlinkChangeEvent == NULL) {
+            RegCloseKey(hkFreelance);
+            return;
+        }
+    }
+
+    while ( TRUE ) {
+    /* check hFreelanceSymlinkChangeEvent to see if it is set. 
+     * if so, call cm_noteLocalMountPointSymlinkChange()
+     */
+        if (RegNotifyChangeKeyValue( hkFreelance,   /* hKey */
+                                     FALSE,         /* bWatchSubtree */
+                                     REG_NOTIFY_CHANGE_LAST_SET, /* dwNotifyFilter */
+                                     hFreelanceSymlinkChangeEvent, /* hEvent */
+                                     TRUE          /* fAsynchronous */
+                                     ) != ERROR_SUCCESS) {
+            RegCloseKey(hkFreelance);
+            CloseHandle(hFreelanceSymlinkChangeEvent);
+            return;
+        }
+
+        if (WaitForSingleObject(hFreelanceSymlinkChangeEvent, INFINITE) == WAIT_OBJECT_0)
+        {
+            cm_noteLocalMountPointChange();
+        }
+    }
+}
 #endif
 
 void cm_InitFreelance() {
@@ -98,13 +137,17 @@ void cm_InitFreelance() {
                           NULL, 0, &lpid, "cm_FreelanceChangeNotifier");
     osi_assert(phandle != NULL);
     thrd_CloseHandle(phandle);
+
+    phandle = thrd_Create(NULL, 65536, (ThreadFunc) cm_FreelanceSymlinkChangeNotifier,
+                          NULL, 0, &lpid, "cm_FreelanceSymlinkChangeNotifier");
+    osi_assert(phandle != NULL);
+    thrd_CloseHandle(phandle);
 #endif
 }
 
 /* yj: Initialization of the fake root directory */
 /* to be called while holding freelance lock unless during init. */
 void cm_InitFakeRootDir() {
-       
     int i, t1, t2;
     char* currentPos;
     int noChunks;
@@ -398,12 +441,12 @@ long cm_InitLocalMountPoints() {
     long code;
     char rootCellName[256];
 #if !defined(DJGPP)
-    HKEY hkFreelance = 0;
+    HKEY hkFreelance = 0, hkFreelanceSymlinks = 0;
     DWORD dwType, dwSize;
-    DWORD dwMountPoints;
+    DWORD dwMountPoints = 0;
     DWORD dwIndex;
+    DWORD dwSymlinks = 0;
     FILETIME ftLastWriteTime;
-    afs_uint32 unixTime;
 #endif
 
 #if !defined(DJGPP)
@@ -440,9 +483,34 @@ long cm_InitLocalMountPoints() {
             dwMountPoints = 2;
         }
 
+        if (RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
+                          "SOFTWARE\\OpenAFS\\Client\\Freelance\\Symlinks",
+                          0,
+                          NULL,
+                          REG_OPTION_NON_VOLATILE,
+                          KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+                          NULL,
+                          &hkFreelanceSymlinks,
+                          NULL) == ERROR_SUCCESS) {
+
+            RegQueryInfoKey( hkFreelanceSymlinks,
+                             NULL,  /* lpClass */
+                             NULL,  /* lpcClass */
+                             NULL,  /* lpReserved */
+                             NULL,  /* lpcSubKeys */
+                             NULL,  /* lpcMaxSubKeyLen */
+                             NULL,  /* lpcMaxClassLen */
+                             &dwSymlinks, /* lpcValues */
+                             NULL,  /* lpcMaxValueNameLen */
+                             NULL,  /* lpcMaxValueLen */
+                             NULL,  /* lpcbSecurityDescriptor */
+                             NULL   /* lpftLastWriteTime */
+                             );
+        }
+
         // get the number of entries there are from the first line
         // that we read
-        cm_noLocalMountPoints = dwMountPoints;
+        cm_noLocalMountPoints = dwMountPoints + dwSymlinks;
 
         // create space to store the local mount points
         cm_localMountPoints = malloc(sizeof(cm_localMountPoint_t) * cm_noLocalMountPoints);
@@ -478,14 +546,16 @@ long cm_InitLocalMountPoints() {
                 cm_noLocalMountPoints--;
                 continue;
             }
+
+            aLocalMountPoint->fileType = CM_SCACHETYPE_MOUNTPOINT;
             aLocalMountPoint->namep=malloc(t-line+1);
             strncpy(aLocalMountPoint->namep, line, t-line);
             aLocalMountPoint->namep[t-line] = '\0';
                
-            /* copy the mount point string without the trailing dot */
+            /* copy the mount point string */
             aLocalMountPoint->mountPointStringp=malloc(strlen(t));
-                       strncpy(aLocalMountPoint->mountPointStringp, t, strlen(t)-1);
-                       aLocalMountPoint->mountPointStringp[strlen(t)-1] = '\0';
+            strncpy(aLocalMountPoint->mountPointStringp, t, strlen(t)-1);
+            aLocalMountPoint->mountPointStringp[strlen(t)-1] = '\0';
     
             osi_Log2(afsd_logp,"found mount point: name %s, string %s",
                       osi_LogSaveString(afsd_logp,aLocalMountPoint->namep),
@@ -494,6 +564,48 @@ long cm_InitLocalMountPoints() {
             aLocalMountPoint++;
         }
 
+        for ( dwIndex = 0 ; dwIndex < dwSymlinks; dwIndex++ ) {
+            TCHAR szValueName[16];
+            DWORD dwValueSize = 16;
+            dwSize = sizeof(line);
+            RegEnumValue( hkFreelanceSymlinks, dwIndex, szValueName, &dwValueSize, NULL,
+                          &dwType, line, &dwSize);
+
+            /* find the trailing dot; null terminate after it */
+            t2 = strrchr(line, '.');
+            if (t2)
+                *(t2+1) = '\0';
+
+            // line is not empty, so let's parse it
+            t = strchr(line, ':');
+
+            // make sure that there is a ':' separator in the line
+            if (!t) {
+                afsi_log("error occurred while parsing symlink entry: no ':' separator in line %d", dwIndex);
+                fprintf(stderr, "error occurred while parsing symlink entry: no ':' separator in line %d", dwIndex);
+                cm_noLocalMountPoints--;
+                continue;
+            }
+
+            aLocalMountPoint->fileType = CM_SCACHETYPE_SYMLINK;
+            aLocalMountPoint->namep=malloc(t-line+1);
+            strncpy(aLocalMountPoint->namep, line, t-line);
+            aLocalMountPoint->namep[t-line] = '\0';
+               
+            /* copy the symlink string */
+            aLocalMountPoint->mountPointStringp=malloc(strlen(t)-1);
+            strncpy(aLocalMountPoint->mountPointStringp, t+1, strlen(t)-2);
+            aLocalMountPoint->mountPointStringp[strlen(t)-2] = '\0';
+    
+            osi_Log2(afsd_logp,"found symlink: name %s, string %s",
+                      osi_LogSaveString(afsd_logp,aLocalMountPoint->namep),
+                      osi_LogSaveString(afsd_logp,aLocalMountPoint->mountPointStringp));
+
+            aLocalMountPoint++;
+        }
+
+        if ( hkFreelanceSymlinks )
+            RegCloseKey( hkFreelanceSymlinks );
         RegCloseKey(hkFreelance);
         return 0;
     }
@@ -625,10 +737,6 @@ int cm_getNoLocalMountPoints() {
     return cm_noLocalMountPoints;
 }
 
-cm_localMountPoint_t* cm_getLocalMountPoint(int vnode) {
-    return 0;
-}
-
 long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw, cm_fid_t *fidp)
 {
     FILE *fp;
@@ -668,7 +776,7 @@ long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw,
 
 #if !defined(DJGPP)
     if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, 
-                      "SOFTWARE\\OpenAFS\\Client\\Freelance",
+                      "SOFTWARE\\OpenAFS\\Client\\Freelance\\Symlinks",
                       0,
                       KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
                       &hkFreelance) == ERROR_SUCCESS) {
@@ -688,22 +796,35 @@ long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw,
                          );
 
         if (rw)
-            sprintf(line, "%s%%%s:%s\n", filename, fullname, volume);
+            sprintf(line, "%s%%%s:%s", filename, fullname, volume);
         else
-            sprintf(line, "%s#%s:%s\n", filename, fullname, volume);
+            sprintf(line, "%s#%s:%s", filename, fullname, volume);
 
         /* If we are adding a new value, there must be an unused name
          * within the range 0 to dwMountPoints 
          */
         for ( dwIndex = 0; dwIndex <= dwMountPoints; dwIndex++ ) {
             char szIndex[16];
+            char szMount[1024];
+
+            dwSize = sizeof(szMount);
             sprintf(szIndex, "%d", dwIndex);
-            if (RegQueryValueEx( hkFreelance, szIndex, 0, &dwType, NULL, &dwSize) != ERROR_SUCCESS) {
+            if (RegQueryValueEx( hkFreelance, szIndex, 0, &dwType, szMount, &dwSize) != ERROR_SUCCESS) {
                 /* found an unused value */
                 dwType = REG_SZ;
                 dwSize = strlen(line) + 1;
                 RegSetValueEx( hkFreelance, szIndex, 0, dwType, line, dwSize);
                 break;
+            } else {
+                               int len = strlen(filename);
+                               if ( dwType == REG_SZ && !strncmp(filename, szMount, len) && 
+                                       (szMount[len] == '%' || szMount[len] == '#')) {
+                    /* Replace the existing value */
+                    dwType = REG_SZ;
+                    dwSize = strlen(line) + 1;
+                    RegSetValueEx( hkFreelance, szIndex, 0, dwType, line, dwSize);
+                    break;
+                }
             }
         }
         RegCloseKey(hkFreelance);
@@ -847,4 +968,160 @@ long cm_FreelanceRemoveMount(char *toremove)
     return 0;
 }
 
+long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp)
+{
+    FILE *fp;
+    char hfile[120];
+    char line[512];
+    char fullname[200];
+    int n;
+    int alias = 0;
+#if !defined(DJGPP)
+    HKEY hkFreelanceSymlinks = 0;
+    DWORD dwType, dwSize;
+    DWORD dwSymlinks;
+    DWORD dwIndex;
+#endif
+
+    /* before adding, verify the cell name; if it is not a valid cell,
+       don't add the mount point.
+       allow partial matches as a means of poor man's alias. */
+    /* major performance issue? */
+    osi_Log2(afsd_logp,"Freelance Add Symlink request: filename=%s destination=%s",
+              osi_LogSaveString(afsd_logp,filename), 
+              osi_LogSaveString(afsd_logp,destination));
+    
+    lock_ObtainMutex(&cm_Freelance_Lock);
+
+#if !defined(DJGPP)
+    if (RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
+                        "SOFTWARE\\OpenAFS\\Client\\Freelance\\Symlinks",
+                        0,
+                        NULL,
+                        REG_OPTION_NON_VOLATILE,
+                        KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+                        NULL,
+                        &hkFreelanceSymlinks,
+                        NULL) == ERROR_SUCCESS) {
+
+        RegQueryInfoKey( hkFreelanceSymlinks,
+                         NULL,  /* lpClass */
+                         NULL,  /* lpcClass */
+                         NULL,  /* lpReserved */
+                         NULL,  /* lpcSubKeys */
+                         NULL,  /* lpcMaxSubKeyLen */
+                         NULL,  /* lpcMaxClassLen */
+                         &dwSymlinks, /* lpcValues */
+                         NULL,  /* lpcMaxValueNameLen */
+                         NULL,  /* lpcMaxValueLen */
+                         NULL,  /* lpcbSecurityDescriptor */
+                         NULL   /* lpftLastWriteTime */
+                         );
+
+        sprintf(line, "%s:%s.", filename, destination);
+
+        /* If we are adding a new value, there must be an unused name
+         * within the range 0 to dwSymlinks 
+         */
+        for ( dwIndex = 0; dwIndex <= dwSymlinks; dwIndex++ ) {
+            char szIndex[16];
+            char szLink[1024];
+
+            dwSize = sizeof(szLink);
+            sprintf(szIndex, "%d", dwIndex);
+            if (RegQueryValueEx( hkFreelanceSymlinks, szIndex, 0, &dwType, szLink, &dwSize) != ERROR_SUCCESS) {
+                /* found an unused value */
+                dwType = REG_SZ;
+                dwSize = strlen(line) + 1;
+                RegSetValueEx( hkFreelanceSymlinks, szIndex, 0, dwType, line, dwSize);
+                break;
+            } else {
+                               int len = strlen(filename);
+                               if ( dwType == REG_SZ && !strncmp(filename, szLink, len) && szLink[len] == ':') {
+                    /* Replace the existing value */
+                    dwType = REG_SZ;
+                    dwSize = strlen(line) + 1;
+                    RegSetValueEx( hkFreelanceSymlinks, szIndex, 0, dwType, line, dwSize);
+                    break;
+                }
+            }
+        }
+        RegCloseKey(hkFreelanceSymlinks);
+    } 
+#endif
+    lock_ReleaseMutex(&cm_Freelance_Lock);
+
+    /* cm_reInitLocalMountPoints(); */
+    if (fidp) {
+        fidp->unique = 1;
+        fidp->vnode = cm_noLocalMountPoints + 1;   /* vnode value of last mt pt */
+    }
+    cm_noteLocalMountPointChange();
+    return 0;
+}
+
+long cm_FreelanceRemoveSymlink(char *toremove)
+{
+    int i, n;
+    char* cp;
+    char line[512];
+    char shortname[200];
+    char hfile[120], hfile2[120];
+    FILE *fp1, *fp2;
+    int found=0;
+#if !defined(DJGPP)
+    HKEY hkFreelanceSymlinks = 0;
+    DWORD dwType, dwSize;
+    DWORD dwSymlinks;
+    DWORD dwIndex;
+#endif
+
+    lock_ObtainMutex(&cm_Freelance_Lock);
+
+
+#if !defined(DJGPP)
+    if (RegOpenKeyEx( HKEY_LOCAL_MACHINE, 
+                      "SOFTWARE\\OpenAFS\\Client\\Freelance\\Symlinks",
+                      0,
+                      KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+                      &hkFreelanceSymlinks) == ERROR_SUCCESS) {
+
+        RegQueryInfoKey( hkFreelanceSymlinks,
+                         NULL,  /* lpClass */
+                         NULL,  /* lpcClass */
+                         NULL,  /* lpReserved */
+                         NULL,  /* lpcSubKeys */
+                         NULL,  /* lpcMaxSubKeyLen */
+                         NULL,  /* lpcMaxClassLen */
+                         &dwSymlinks, /* lpcValues */
+                         NULL,  /* lpcMaxValueNameLen */
+                         NULL,  /* lpcMaxValueLen */
+                         NULL,  /* lpcbSecurityDescriptor */
+                         NULL   /* lpftLastWriteTime */
+                         );
+
+        for ( dwIndex = 0; dwIndex < dwSymlinks; dwIndex++ ) {
+            TCHAR szValueName[16];
+            DWORD dwValueSize = 16;
+            dwSize = sizeof(line);
+            RegEnumValue( hkFreelanceSymlinks, dwIndex, szValueName, &dwValueSize, NULL,
+                          &dwType, line, &dwSize);
+
+            cp=strchr(line, ':');
+            memcpy(shortname, line, cp-line);
+            shortname[cp-line]=0;
+
+            if (!strcmp(shortname, toremove)) {
+                RegDeleteValue( hkFreelanceSymlinks, szValueName );
+                break;
+            }
+        }
+        RegCloseKey(hkFreelanceSymlinks);
+    }
+#endif
+    
+    lock_ReleaseMutex(&cm_Freelance_Lock);
+    cm_noteLocalMountPointChange();
+    return 0;
+}
 #endif /* AFS_FREELANCE_CLIENT */
index 3d02b9e..b47c66a 100644 (file)
@@ -3,16 +3,16 @@
 
 
 typedef struct cm_localMountPoint {
-       char* namep;
-       char* mountPointStringp;
-       struct cm_localMountPoint* next;
+    char*                       namep;
+    char*                       mountPointStringp;
+    unsigned int                fileType;
+    struct cm_localMountPoint*  next;
 } cm_localMountPoint_t;
 
 extern int cm_getNoLocalMountPoints();
 extern long cm_InitLocalMountPoints();
 extern int cm_getLocalMountPointChange();
 extern int cm_reInitLocalMountPoints();
-extern cm_localMountPoint_t* cm_getLocalMountPoint(int vnode);
 extern void cm_InitFreelance();
 extern long cm_FreelanceRemoveMount(char *toremove);
 extern long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw, cm_fid_t *fidp);
index b63c379..8ccc321 100644 (file)
@@ -1510,6 +1510,26 @@ long cm_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
     cp = ioctlp->inDatap;              /* contents of link */
 
+#ifdef AFS_FREELANCE_CLIENT
+    if (cm_freelanceEnabled && dscp == cm_rootSCachep) {
+        /* we are adding the symlink to the root dir., so call
+         * the freelance code to do the add. */
+        if (cp[0] == cp[1] && cp[1] == '\\' && 
+            !_strnicmp(cm_NetbiosName,cp+2,strlen(cm_NetbiosName))) 
+        {
+            /* skip \\AFS\ or \\AFS\all\ */
+            char * p;
+            p = cp + 2 + strlen(cm_NetbiosName) + 1;
+            if ( !_strnicmp("all", p, 3) )
+                p += 4;
+            cp = p;
+        }
+        osi_Log0(afsd_logp,"IoctlCreateSymlink within Freelance root dir");
+        code = cm_FreelanceAddSymlink(leaf, cp, NULL);
+        return code;
+    }
+#endif
+
     /* Create symlink with mode 0755. */
     tattr.mask = CM_ATTRMASK_UNIXMODEBITS;
     tattr.unixModeBits = 0755;
@@ -1619,6 +1639,16 @@ long cm_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
     cp = ioctlp->inDatap;
 
+#ifdef AFS_FREELANCE_CLIENT
+    if (cm_freelanceEnabled && dscp == cm_rootSCachep) {
+        /* we are adding the mount point to the root dir., so call
+         * the freelance code to do the add. */
+        osi_Log0(afsd_logp,"IoctlDeletelink from Freelance root dir");
+        code = cm_FreelanceRemoveSymlink(cp);
+        return code;
+    }
+#endif
+
     code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp);
         
     /* if something went wrong, bail out now */
index 89eb799..cfd3c38 100644 (file)
@@ -329,7 +329,7 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp,
         cm_hashTablep[hash]=scp;
         scp->flags |= CM_SCACHEFLAG_INHASH;
         scp->refCount = 1;
-        scp->fileType = CM_SCACHETYPE_MOUNTPOINT;
+        scp->fileType = (cm_localMountPoints+fidp->vnode-2)->fileType;
 
         lock_ObtainMutex(&cm_Freelance_Lock);
         scp->length.LowPart = strlen(mp)+4;
index 69fe625..5be1511 100644 (file)
@@ -232,6 +232,11 @@ static MakeLinkCmd(as)
 register struct cmd_syndesc *as; {
     register afs_int32 code;
     struct ViceIoctl blob;
+#ifdef WIN32
+    char cm_NetbiosName[MAX_NB_NAME_LENGTH] = "";
+    BOOL isGateway = FALSE;
+    lana_number_t lanaNum;
+#endif
 
     if (!InAFS(Parent(as->parms[0].items->data))) {
        fprintf(stderr,"%s: symlinks must be created within the AFS file system\n", pn);
@@ -243,6 +248,11 @@ register struct cmd_syndesc *as; {
     /* create symlink with a special pioctl for Windows NT, since it doesn't
      * have a symlink system call.
      */
+
+    /* TODO: Code needs to go here to prevent the creation of symlinks
+     * in \\AFS\all when not in the "AFS Client Admins" group.
+     */
+
     blob.out_size = 0;
     blob.in_size = 1 + strlen(space);
     blob.in = space;