windows-query-afsid-20060420
[openafs.git] / src / WINNT / afsd / cm_ioctl.c
index d4e5ca5..70b93cb 100644 (file)
@@ -9,6 +9,9 @@
 
 #include <afs/param.h>
 #include <afs/stds.h>
+#include <afs/cellconfig.h>
+#include <afs/ptserver.h>
+#include <ubik.h>
 
 #ifndef DJGPP
 #include <windows.h>
@@ -41,6 +44,9 @@
 
 #include "cm_rpc.h"
 #include <strsafe.h>
+#include <winioctl.h>
+#include <..\afsrdr\kif.h>
+#include <rx\rx.h>
 
 #ifdef _DEBUG
 #include <crtdbg.h>
@@ -62,6 +68,22 @@ void cm_InitIoctl(void)
     lock_InitializeMutex(&cm_Afsdsbmt_Lock, "AFSDSBMT.INI Access Lock");
 }
 
+long cm_CleanFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
+{
+    long code;
+
+    lock_ObtainWrite(&scp->bufCreateLock);
+    code = buf_CleanVnode(scp, userp, reqp);
+        
+    lock_ObtainMutex(&scp->mx);
+    cm_DiscardSCache(scp);
+    lock_ReleaseMutex(&scp->mx);
+
+    lock_ReleaseWrite(&scp->bufCreateLock);
+    osi_Log2(afsd_logp,"cm_CleanFile scp 0x%x returns error: [%x]",scp, code);
+    return code;
+}
+
 long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
 {
     long code;
@@ -70,14 +92,52 @@ long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
     code = buf_FlushCleanPages(scp, userp, reqp);
         
     lock_ObtainMutex(&scp->mx);
-    scp->cbServerp = NULL;
-    scp->cbExpires = 0;
-    cm_dnlcPurgedp(scp);
-    cm_dnlcPurgevp(scp);
-    cm_FreeAllACLEnts(scp);
+    cm_DiscardSCache(scp);
+
     lock_ReleaseMutex(&scp->mx);
 
     lock_ReleaseWrite(&scp->bufCreateLock);
+    osi_Log2(afsd_logp,"cm_FlushFile scp 0x%x returns error: [%x]",scp, code);
+    return code;
+}
+
+long cm_FlushParent(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
+{
+    long code = 0;
+    cm_scache_t * pscp;
+  
+    pscp = cm_FindSCacheParent(scp);
+  
+    /* now flush the file */
+    code = cm_FlushFile(pscp, userp, reqp);
+    cm_ReleaseSCache(scp);
+
+    return code;
+}
+
+
+long cm_FlushVolume(cm_user_t *userp, cm_req_t *reqp, afs_uint32 cell, afs_uint32 volume)
+{
+    long code = 0;
+    cm_scache_t *scp;
+    int i;
+
+    lock_ObtainWrite(&cm_scacheLock);
+    for (i=0; i<cm_data.hashTableSize; i++) {
+        for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) {
+            if (scp->fid.volume == volume && scp->fid.cell == cell) {
+                cm_HoldSCacheNoLock(scp);
+                lock_ReleaseWrite(&cm_scacheLock);
+
+                /* now flush the file */
+                code = cm_FlushFile(scp, userp, reqp);
+                lock_ObtainWrite(&cm_scacheLock);
+                cm_ReleaseSCacheNoLock(scp);
+            }
+        }
+    }
+    lock_ReleaseWrite(&cm_scacheLock);
+
     return code;
 }
 
@@ -144,6 +204,13 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
     long code;
     cm_scache_t *substRootp;
     char * relativePath = ioctlp->inDatap;
+#ifdef AFSIFS
+    char * absRoot[MAX_PATH];
+    long length;
+    wchar_t absRoot_w[MAX_PATH];
+    HANDLE rootDir;
+#endif
+    osi_Log1(afsd_logp, "cm_ParseIoctlPath %s", osi_LogSaveString(afsd_logp,relativePath));
 
     /* This is usually the file name, but for StatMountPoint it is the path. */
     /* ioctlp->inDatap can be either of the form:
@@ -154,6 +221,28 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
      */
     TranslateExtendedChars(relativePath);
 
+#ifdef AFSIFS
+    /* we have passed the whole path, including the afs prefix.
+          when the pioctl call is made, we perform an ioctl to afsrdr
+          and it returns the correct (full) path.  therefore, there is
+          no drive letter, and the path is absolute. */
+    code = cm_NameI(cm_data.rootSCachep, relativePath,
+                     CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+                     userp, "", reqp, scpp);
+
+    if (code)
+        return code;
+
+    /* # of bytes of path */
+    code = strlen(ioctlp->inDatap) + 1;
+    ioctlp->inDatap += code;
+
+    /* This is usually nothing, but for StatMountPoint it is the file name. */
+    TranslateExtendedChars(ioctlp->inDatap);
+
+    return 0;
+#endif /* AFSIFS */
+
     if (relativePath[0] == relativePath[1] &&
          relativePath[1] == '\\' && 
          !_strnicmp(cm_NetbiosName,relativePath+2,strlen(cm_NetbiosName))) 
@@ -168,7 +257,7 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
          * since it had better expand into the value of ioctl->tidPathp
          */
         char * p;
-        p = relativePath + 2 + strlen(cm_NetbiosName) + 1;
+        p = relativePath + 2 + strlen(cm_NetbiosName) + 1;                     /* buffer overflow vuln.? */
         if ( !_strnicmp("all", p, 3) )
             p += 4;
 
@@ -235,7 +324,7 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
     }
 
     /* # of bytes of path */
-    code = strlen(ioctlp->inDatap) + 1;
+    code = (long)strlen(ioctlp->inDatap) + 1;
     ioctlp->inDatap += code;
 
     /* This is usually nothing, but for StatMountPoint it is the file name. */
@@ -249,7 +338,7 @@ void cm_SkipIoctlPath(smb_ioctl_t *ioctlp)
 {
     long temp;
         
-    temp = strlen(ioctlp->inDatap) + 1;
+    temp = (long) strlen(ioctlp->inDatap) + 1;
     ioctlp->inDatap += temp;
 }       
 
@@ -390,13 +479,13 @@ long cm_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
                         userp, ioctlp->tidPathp, reqp, &substRootp);
         if (code) return code;
 
-        code = cm_NameI(substRootp, tbuffer, CM_FLAG_FOLLOW,
+        code = cm_NameI(substRootp, tbuffer, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
                         userp, NULL, reqp, scpp);
         if (code) return code;
     }
 
     /* # of bytes of path */
-    code = strlen(ioctlp->inDatap) + 1;
+    code = (long)strlen(ioctlp->inDatap) + 1;
     ioctlp->inDatap += code;
 
     /* and return success */
@@ -442,7 +531,7 @@ long cm_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp)
     if (code) return code;
 
     /* skip over return data */
-    tlen = strlen(ioctlp->outDatap) + 1;
+    tlen = (int)strlen(ioctlp->outDatap) + 1;
     ioctlp->outDatap += tlen;
 
     /* and return success */
@@ -466,7 +555,7 @@ long cm_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp)
          scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
          scp->fid.volume==AFS_FAKE_ROOT_VOL_ID &&
          scp->fid.vnode==0x1 && scp->fid.unique==0x1 ) {
-        StringCbCopyA(ioctlp->outDatap, 999999, "Freelance.Local.Root");
+        StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), "Freelance.Local.Root");
         ioctlp->outDatap += strlen(ioctlp->outDatap) + 1;
         code = 0;
     } else 
@@ -474,7 +563,7 @@ long cm_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp)
     {
         cellp = cm_FindCellByID(scp->fid.cell);
         if (cellp) {
-            StringCbCopyA(ioctlp->outDatap, 999999, cellp->name);
+            StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), cellp->name);
             ioctlp->outDatap += strlen(ioctlp->outDatap) + 1;
             code = 0;
         }
@@ -509,7 +598,7 @@ long cm_IoctlSetACL(struct smb_ioctl *ioctlp, struct cm_user *userp)
     fid.Unique = scp->fid.unique;
     do {
         acl.AFSOpaque_val = ioctlp->inDatap;
-        acl.AFSOpaque_len = strlen(ioctlp->inDatap)+1;
+        acl.AFSOpaque_len = (u_int)strlen(ioctlp->inDatap)+1;
         code = cm_Conn(&scp->fid, userp, &req, &connp);
         if (code) continue;
 
@@ -530,36 +619,27 @@ long cm_IoctlSetACL(struct smb_ioctl *ioctlp, struct cm_user *userp)
     return code;
 }
 
-long cm_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp)
+
+
+long cm_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
 {
     long code;
     cm_scache_t *scp;
-    unsigned long volume;
     int i;
     cm_req_t req;
 
     cm_InitReq(&req);
 
-    code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp);
-    if (code) return code;
-        
-    volume = scp->fid.volume;
-    cm_ReleaseSCache(scp);
-
     lock_ObtainWrite(&cm_scacheLock);
     for (i=0; i<cm_data.hashTableSize; i++) {
         for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) {
-            if (scp->fid.volume == volume) {
-                cm_HoldSCacheNoLock(scp);
-                lock_ReleaseWrite(&cm_scacheLock);
+           cm_HoldSCacheNoLock(scp);
+           lock_ReleaseWrite(&cm_scacheLock);
 
-                /* now flush the file */
-                code = cm_FlushFile(scp, userp, &req);
-                if ( code )
-                    afsi_log("cm_FlushFile returns error: [%x]",code);
-                lock_ObtainWrite(&cm_scacheLock);
-                cm_ReleaseSCacheNoLock(scp);
-            }
+           /* now flush the file */
+           code = cm_FlushFile(scp, userp, &req);
+           lock_ObtainWrite(&cm_scacheLock);
+           cm_ReleaseSCacheNoLock(scp);
         }
     }
     lock_ReleaseWrite(&cm_scacheLock);
@@ -567,6 +647,28 @@ long cm_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp)
     return code;
 }
 
+long cm_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+    long code;
+    cm_scache_t *scp;
+    unsigned long volume;
+    unsigned long cell;
+    cm_req_t req;
+
+    cm_InitReq(&req);
+
+    code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp);
+    if (code) return code;
+        
+    volume = scp->fid.volume;
+    cell = scp->fid.cell;
+    cm_ReleaseSCache(scp);
+
+    code = cm_FlushVolume(userp, &req, cell, volume);
+
+    return code;
+}
+
 long cm_IoctlFlushFile(struct smb_ioctl *ioctlp, struct cm_user *userp)
 {
     long code;
@@ -663,11 +765,11 @@ long cm_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cp = ioctlp->outDatap;
     memcpy(cp, (char *)&volStat, sizeof(VolumeStatus));
     cp += sizeof(VolumeStatus);
-    StringCbCopyA(cp, 999999, volName);
+    StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), volName);
     cp += strlen(volName)+1;
-    StringCbCopyA(cp, 999999, offLineMsg);
+    StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), offLineMsg);
     cp += strlen(offLineMsg)+1;
-    StringCbCopyA(cp, 999999, motd);
+    StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), motd);
     cp += strlen(motd)+1;
 
     /* now return updated return data pointer */
@@ -719,11 +821,11 @@ long cm_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cp = ioctlp->outDatap;
     memcpy(cp, (char *)&volStat, sizeof(AFSFetchVolumeStatus));
     cp += sizeof(AFSFetchVolumeStatus);
-    StringCbCopyA(cp, 999999, volName);
+    StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), volName);
     cp += strlen(volName)+1;
-    StringCbCopyA(cp, 999999, offLineMsg);
+    StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), offLineMsg);
     cp += strlen(offLineMsg)+1;
-    StringCbCopyA(cp, 999999, motd);
+    StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), motd);
     cp += strlen(motd)+1;
 
     /* return new size */
@@ -732,6 +834,64 @@ long cm_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
     return 0;
 }
 
+long cm_IoctlGetFid(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+    cm_scache_t *scp;
+    register long code;
+    register char *cp;
+    cm_fid_t fid;
+    cm_req_t req;
+
+    cm_InitReq(&req);
+
+    code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp);
+    if (code) return code;
+
+    memset(&fid, 0, sizeof(cm_fid_t));
+    fid.volume = scp->fid.volume;
+    fid.vnode  = scp->fid.vnode;
+    fid.unique = scp->fid.unique;
+
+    cm_ReleaseSCache(scp);
+
+    /* Copy all this junk into msg->im_data, keeping track of the lengths. */
+    cp = ioctlp->outDatap;
+    memcpy(cp, (char *)&fid, sizeof(cm_fid_t));
+    cp += sizeof(cm_fid_t);
+
+    /* return new size */
+    ioctlp->outDatap = cp;
+
+    return 0;
+}
+
+long cm_IoctlGetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+    cm_scache_t *scp;
+    register long code;
+    register char *cp;
+    cm_req_t req;
+
+    cm_InitReq(&req);
+
+    code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp);
+    if (code) return code;
+
+    /* Copy all this junk into msg->im_data, keeping track of the lengths. */
+    cp = ioctlp->outDatap;
+    memcpy(cp, (char *)&scp->owner, sizeof(afs_uint32));
+    cp += sizeof(afs_uint32);
+    memcpy(cp, (char *)&scp->group, sizeof(afs_uint32));
+    cp += sizeof(afs_uint32);
+
+    /* return new size */
+    ioctlp->outDatap = cp;
+
+    cm_ReleaseSCache(scp);
+
+    return 0;
+}
+
 long cm_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp)
 {
     long code;
@@ -814,7 +974,7 @@ long cm_IoctlStatMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
     code = cm_ReadMountPoint(scp, userp, &req);
     if (code == 0) {
         cp = ioctlp->outDatap;
-        StringCbCopyA(cp, 999999, scp->mountPointStringp);
+        StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), scp->mountPointStringp);
         cp += strlen(cp) + 1;
         ioctlp->outDatap = cp;
     }
@@ -898,12 +1058,12 @@ long cm_IoctlCheckServers(struct smb_ioctl *ioctlp, struct cm_user *userp)
         memcpy(&csi, tp, sizeof(csi));
         if (csi.tinterval >= 0) {
             cp = ioctlp->outDatap;
-            memcpy(cp, (char *)&cm_daemonCheckInterval, sizeof(long));
+            memcpy(cp, (char *)&cm_daemonCheckDownInterval, sizeof(long));
             ioctlp->outDatap += sizeof(long);
             if (csi.tinterval > 0) {
                 if (!smb_SUser(userp))
                     return CM_ERROR_NOACCESS;
-                cm_daemonCheckInterval = csi.tinterval;
+                cm_daemonCheckDownInterval = csi.tinterval;
             }
             return 0;
         }
@@ -969,7 +1129,7 @@ long cm_IoctlCheckVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
 long cm_IoctlSetCacheSize(struct smb_ioctl *ioctlp, struct cm_user *userp)
 {
-    long temp;
+    afs_uint64 temp;
     long code;
 
     cm_SkipIoctlPath(ioctlp);
@@ -1007,10 +1167,12 @@ long cm_IoctlTraceControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
         if ((inValue & 1) == 0) {
             /* disable tracing */
             osi_LogDisable(afsd_logp);
+           rx_DebugOnOff(FALSE);
         }
         else {
             /* enable tracing */
             osi_LogEnable(afsd_logp);
+           rx_DebugOnOff(TRUE);
         }
     }
 
@@ -1099,7 +1261,7 @@ long cm_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
         }
         lock_ReleaseRead(&cm_serverLock);
         cp = basep + max * sizeof(afs_int32);
-        StringCbCopyA(cp, 999999, tcellp->name);
+        StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), tcellp->name);
         cp += strlen(tcellp->name)+1;
         ioctlp->outDatap = cp;
     }
@@ -1131,6 +1293,7 @@ long cm_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
     for (cp = cm_data.allCellsp; cp; cp=cp->nextp) 
     {
         long code;
+       lock_ObtainMutex(&cp->mx);
         /* delete all previous server lists - cm_FreeServerList will ask for write on cm_ServerLock*/
         cm_FreeServerList(&cp->vlServersp);
         cp->vlServersp = NULL;
@@ -1158,6 +1321,7 @@ long cm_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
             cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
             cm_RandomizeServer(&cp->vlServersp);
         }
+       lock_ReleaseMutex(&cp->mx);
     }
     
     lock_ReleaseWrite(&cm_cellLock);
@@ -1169,15 +1333,16 @@ long cm_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp)
        long code = 0;
 
        if (cm_freelanceEnabled) {
-           StringCbCopyA(ioctlp->outDatap, 999999, "Freelance.Local.Root");
-               ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
+            if (cm_GetRootCellName(ioctlp->outDatap))
+                StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), "Freelance.Local.Root");
+            ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
        } else if (cm_data.rootCellp) {
            /* return the default cellname to the caller */
-           StringCbCopyA(ioctlp->outDatap, 999999, cm_data.rootCellp->name);
+           StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), cm_data.rootCellp->name);
            ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
        } else {
            /* if we don't know our default cell, return failure */
-               code = CM_ERROR_NOSUCHCELL;
+            code = CM_ERROR_NOSUCHCELL;
     }
 
     return code;
@@ -1202,7 +1367,7 @@ long cm_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp)
         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);
+            t = (int)strlen(cp);
             if (t >= MAXSYSNAME || t <= 0)
                 return EINVAL;
             /* check for names that can shoot us in the foot */
@@ -1214,7 +1379,7 @@ long cm_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
         /* inname gets first entry in case we're being a translator */
         /* (we are never a translator) */
-        t = strlen(ioctlp->inDatap);
+        t = (int)strlen(ioctlp->inDatap);
         memcpy(inname, ioctlp->inDatap, t + 1);
         ioctlp->inDatap += t + 1;
         num = count;
@@ -1241,7 +1406,7 @@ long cm_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp)
                 if (!cm_sysNameList[count])
                     osi_panic("cm_IoctlSysName: no cm_sysNameList entry to write\n",
                                __FILE__, __LINE__);
-                t = strlen(cp);
+                t = (int)strlen(cp);
                 StringCbCopyA(cm_sysNameList[count], MAXSYSNAME, cp);
                 cp += t + 1;
             }
@@ -1255,17 +1420,17 @@ long cm_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp)
         memcpy(cp, (char *)&foundname, sizeof(afs_int32));
         cp += sizeof(afs_int32);       /* skip found flag */
         if (foundname) {
-            StringCbCopyA(cp, 999999, outname);
+            StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), 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]);
+                t = (int)strlen((*sysnamelist)[count]);
                 if (t >= MAXSYSNAME)
                     osi_panic("cm_IoctlSysName: sysname entry garbled\n", 
                                __FILE__, __LINE__);
-                StringCbCopyA(cp, 999999, (*sysnamelist)[count]);
+                StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), (*sysnamelist)[count]);
                 cp += t + 1;
             }
         }
@@ -1367,13 +1532,16 @@ long cm_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
                 /* set preferences for an existing vlserver */
                 cm_ChangeRankCellVLServer(tsp);
             }
-            cm_PutServer(tsp);  /* decrease refcount */
         }
         else   /* add a new server without a cell */
         {
             tsp = cm_NewServer(&tmp, type, NULL); /* refcount = 1 */
             tsp->ipRank = rank;
         }
+       lock_ObtainMutex(&tsp->mx);
+       tsp->flags |= CM_SERVERFLAG_PREF_SET;
+       lock_ReleaseMutex(&tsp->mx);
+       cm_PutServer(tsp);  /* decrease refcount */
     }
     return 0;
 }
@@ -1603,11 +1771,11 @@ long cm_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
     if (code == 0) {
         cp = ioctlp->outDatap;
         if (newRootScp != NULL) {
-            StringCbCopyA(cp, 999999, cm_mountRoot);
-            StringCbCatA(cp, 999999, "/");
+            StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), cm_mountRoot);
+            StringCbCatA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), "/");
             cp += strlen(cp);
         }
-        StringCbCopyA(cp, 999999, spacep->data);
+        StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), spacep->data);
         cp += strlen(cp) + 1;
         ioctlp->outDatap = cp;
         cm_FreeSpace(spacep);
@@ -1619,7 +1787,7 @@ long cm_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
                code == CM_ERROR_NOSUCHPATH &&
                 scp->fileType == CM_SCACHETYPE_INVALID) {
         cp = ioctlp->outDatap;
-        StringCbCopyA(cp, 999999, spacep->data);
+        StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), spacep->data);
         cp += strlen(cp) + 1;
         ioctlp->outDatap = cp;
         cm_FreeSpace(spacep);
@@ -1728,6 +1896,82 @@ long cm_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp)
     return code;
 }
 
+long cm_UsernameToId(char *uname, cm_ucell_t * ucellp, afs_uint32* uid)
+{
+    afs_int32 code;
+    namelist lnames;
+    idlist lids;
+    static struct afsconf_cell info;
+    struct rx_connection *serverconns[MAXSERVERS];
+    struct rx_securityClass *sc[3];
+    afs_int32 scIndex = 2;     /* authenticated - we have a token */
+    struct ubik_client *pruclient = NULL;
+    struct afsconf_dir *tdir;
+    int i;
+    char * p, * r;
+
+    tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
+    code = afsconf_GetCellInfo(tdir, ucellp->cellp->name, "afsprot", &info);
+    afsconf_Close(tdir);
+
+    sc[0] = 0;
+    sc[1] = 0;
+    sc[2] = 0;
+
+    /* we have the token that was given to us in the settoken 
+     * call.   we just have to use it. 
+     */
+    scIndex = 2;       /* kerberos ticket */
+    sc[2] = rxkad_NewClientSecurityObject(rxkad_clear, &ucellp->sessionKey,
+                                         ucellp->kvno, ucellp->ticketLen,
+                                         ucellp->ticketp);
+
+    memset(serverconns, 0, sizeof(serverconns));       /* terminate list!!! */
+    for (i = 0; i < info.numServers; i++)
+       serverconns[i] =
+           rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
+                            info.hostAddr[i].sin_port, PRSRV, sc[scIndex],
+                            scIndex);
+
+    code = ubik_ClientInit(serverconns, &pruclient);
+    if (code) {
+       return code;
+    }
+
+    code = rxs_Release(sc[scIndex]);
+
+    lids.idlist_len = 0;
+    lids.idlist_val = 0;
+    lnames.namelist_len = 1;
+    lnames.namelist_val = (prname *) malloc(PR_MAXNAMELEN);
+    strncpy(lnames.namelist_val[0], uname, PR_MAXNAMELEN);
+    lnames.namelist_val[0][PR_MAXNAMELEN-1] = '\0';
+    for ( p=lnames.namelist_val[0], r=NULL; *p; p++ ) {
+       if (isupper(*p))
+           *p = tolower(*p);
+       if (*p == '@')
+           r = p;
+    }
+    if (r && !stricmp(r+1,ucellp->cellp->name))
+       *r = '\0';
+
+    code = ubik_Call(PR_NameToID, pruclient, 0, &lnames, &lids);
+    if (lids.idlist_val) {
+       *uid = *lids.idlist_val;
+       free(lids.idlist_val);
+    }
+    if (lnames.namelist_val)
+       free(lnames.namelist_val);
+
+    if ( pruclient ) {
+       ubik_ClientDestroy(pruclient);
+       pruclient = NULL;
+    }
+
+    return 0;
+}
+
+
 long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
 {
     char *saveDataPtr;
@@ -1743,6 +1987,8 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
     int flags;
     char sessionKey[8];
     char *smbname;
+    int release_userp = 0;
+    char * wdir = NULL;
 
     saveDataPtr = ioctlp->inDatap;
 
@@ -1787,6 +2033,7 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
         uname = tp;
         tp += strlen(tp) + 1;
 
+#ifndef AFSIFS                 /* no SMB username, so we cannot log based on this */
         if (flags & PIOCTL_LOGON) {
             /* SMB user name with which to associate tokens */
             smbname = tp;
@@ -1798,6 +2045,7 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
             osi_Log1(smb_logp,"cm_IoctlSetToken for user [%s]",
                      osi_LogSaveString(smb_logp,uname));
         }
+#endif
 
 #ifndef DJGPP   /* for win95, session key is back in pioctl */
                /* uuid */
@@ -1811,7 +2059,9 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
     }
 
     if (flags & PIOCTL_LOGON) {
-        userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname);
+        userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname,
+                                    SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
+       release_userp = 1;
     }
 
     /* store the token */
@@ -1838,8 +2088,12 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
     ucellp->kvno = ct.AuthHandle;
     ucellp->expirationTime = ct.EndTimestamp;
     ucellp->gen++;
-    if (uname) 
+    ucellp->uid = ANONYMOUSID;
+    if (uname) {
         StringCbCopyA(ucellp->userName, MAXKTCNAMELEN, uname);
+
+       cm_UsernameToId(uname, ucellp, &ucellp->uid);
+    }
     ucellp->flags |= CM_UCELLFLAG_RXKAD;
     lock_ReleaseMutex(&userp->mx);
 
@@ -1849,6 +2103,9 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
     cm_ResetACLCache(userp);
 
+    if (release_userp)
+       cm_ReleaseUser(userp);
+
     return 0;
 }
 
@@ -1925,11 +2182,11 @@ long cm_IoctlGetTokenIter(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cp += sizeof(temp);
 
     /* cell name */
-    StringCbCopyA(cp, 999999, ucellp->cellp->name);
+    StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), ucellp->cellp->name);
     cp += strlen(cp) + 1;
 
     /* user name */
-    StringCbCopyA(cp, 999999, ucellp->userName);
+    StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), ucellp->userName);
     cp += strlen(cp) + 1;
 
     ioctlp->outDatap = cp;
@@ -2014,11 +2271,11 @@ long cm_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cp += sizeof(temp);
 
     /* cell name */
-    StringCbCopyA(cp, 999999, ucellp->cellp->name);
+    StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), ucellp->cellp->name);
     cp += strlen(cp) + 1;
 
     /* user name */
-    StringCbCopyA(cp, 999999, ucellp->userName);
+    StringCbCopyA(cp, SMB_IOCTL_MAXDATA - (cp - ioctlp->outAllocp), ucellp->userName);
     cp += strlen(cp) + 1;
 
     ioctlp->outDatap = cp;
@@ -2060,6 +2317,11 @@ long cm_IoctlDelToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
         free(ucellp->ticketp);
         ucellp->ticketp = NULL;
     }
+    ucellp->ticketLen = 0;
+    memset(ucellp->sessionKey.data, 0, 8);
+    ucellp->kvno = 0;
+    ucellp->expirationTime = 0;
+    ucellp->userName[0] = '\0';
     ucellp->flags &= ~CM_UCELLFLAG_RXKAD;
     ucellp->gen++;
 
@@ -2078,6 +2340,16 @@ long cm_IoctlDelAllToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
     for (ucellp = userp->cellInfop; ucellp; ucellp = ucellp->nextp) {
         osi_Log1(smb_logp,"cm_IoctlDelAllToken ucellp %lx", ucellp);
+
+       if (ucellp->ticketp) {
+           free(ucellp->ticketp);
+           ucellp->ticketp = NULL;
+       }
+       ucellp->ticketLen = 0;
+       memset(ucellp->sessionKey.data, 0, 8);
+       ucellp->kvno = 0;
+       ucellp->expirationTime = 0;
+       ucellp->userName[0] = '\0';
         ucellp->flags &= ~CM_UCELLFLAG_RXKAD;
         ucellp->gen++;
     }
@@ -2148,10 +2420,10 @@ long cm_IoctlMakeSubmount(smb_ioctl_t *ioctlp, cm_user_t *userp)
                            (strlen(&afspath[strlen(cm_mountRoot)])) ?
                            &afspath[strlen(cm_mountRoot)]:"/",
                            (strlen(&afspath[strlen(cm_mountRoot)])) ?
-                           strlen(&afspath[strlen(cm_mountRoot)])+1:2);
+                           (DWORD)strlen(&afspath[strlen(cm_mountRoot)])+1:2);
 
             RegCloseKey( hkSubmounts );
-            StringCbCopyA(ioctlp->outDatap, 999999, submountreqp);
+            StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), submountreqp);
             ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
             lock_ReleaseMutex(&cm_Afsdsbmt_Lock);
             return 0;
@@ -2163,7 +2435,7 @@ long cm_IoctlMakeSubmount(smb_ioctl_t *ioctlp, cm_user_t *userp)
          */
         cm_NormalizeAfsPath (submountPathNormalized, sizeof(submountPathNormalized), submountPath);
         if (!strcmp (submountPathNormalized, afspath)) {
-            StringCbCopyA(ioctlp->outDatap, 999999, submountreqp);
+            StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), submountreqp);
             ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
             RegCloseKey( hkSubmounts );
             lock_ReleaseMutex(&cm_Afsdsbmt_Lock);
@@ -2232,7 +2504,7 @@ long cm_IoctlMakeSubmount(smb_ioctl_t *ioctlp, cm_user_t *userp)
          */
         cm_NormalizeAfsPath (submountPathNormalized, sizeof(submountPathNormalized), submountPath);
         if (!strcmp (submountPathNormalized, afspath)) {
-            StringCbCopyA(ioctlp->outDatap, 999999, submountName);
+            StringCbCopyA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), submountName);
             ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
             RegCloseKey(hkSubmounts);
             lock_ReleaseMutex(&cm_Afsdsbmt_Lock);
@@ -2247,7 +2519,7 @@ long cm_IoctlMakeSubmount(smb_ioctl_t *ioctlp, cm_user_t *userp)
      * when writing out the submount.
      */
 
-    StringCbPrintfA(ioctlp->outDatap, 999999, "auto%ld", nextAutoSubmount);
+    StringCbPrintfA(ioctlp->outDatap, SMB_IOCTL_MAXDATA - (ioctlp->outDatap - ioctlp->outAllocp), "auto%ld", nextAutoSubmount);
 
     RegSetValueEx( hkSubmounts, 
                    ioctlp->outDatap,
@@ -2256,7 +2528,7 @@ long cm_IoctlMakeSubmount(smb_ioctl_t *ioctlp, cm_user_t *userp)
                    (strlen(&afspath[strlen(cm_mountRoot)])) ?
                    &afspath[strlen(cm_mountRoot)]:"/",
                    (strlen(&afspath[strlen(cm_mountRoot)])) ?
-                   strlen(&afspath[strlen(cm_mountRoot)])+1:2);
+                   (DWORD)strlen(&afspath[strlen(cm_mountRoot)])+1:2);
 
     ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
     RegCloseKey(hkSubmounts);
@@ -2274,10 +2546,64 @@ long cm_IoctlGetRxkcrypt(smb_ioctl_t *ioctlp, cm_user_t *userp)
 
 long cm_IoctlSetRxkcrypt(smb_ioctl_t *ioctlp, cm_user_t *userp)
 {
+    afs_int32 c = cryptall;
+
     cm_SkipIoctlPath(ioctlp);
 
     memcpy(&cryptall, ioctlp->inDatap, sizeof(cryptall));
 
+    if (c != cryptall) {
+       if (cryptall)
+            LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_CRYPT_ON);
+       else
+            LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_CRYPT_OFF);
+    }
+    return 0;
+}
+
+long cm_IoctlRxStatProcess(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+    afs_int32 flags;
+    int code = 0;
+
+    cm_SkipIoctlPath(ioctlp);
+
+    memcpy((char *)&flags, ioctlp->inDatap, sizeof(afs_int32));
+    if (!(flags & AFSCALL_RXSTATS_MASK) || (flags & ~AFSCALL_RXSTATS_MASK)) {
+        return -1;
+    }
+    if (flags & AFSCALL_RXSTATS_ENABLE) {
+        rx_enableProcessRPCStats();
+    }
+    if (flags & AFSCALL_RXSTATS_DISABLE) {
+        rx_disableProcessRPCStats();
+    }
+    if (flags & AFSCALL_RXSTATS_CLEAR) {
+        rx_clearProcessRPCStats(AFS_RX_STATS_CLEAR_ALL);
+    }
+    return 0;
+}
+
+long cm_IoctlRxStatPeer(struct smb_ioctl *ioctlp, struct cm_user *userp)
+{
+    afs_int32 flags;
+    int code = 0;
+
+    cm_SkipIoctlPath(ioctlp);
+
+    memcpy((char *)&flags, ioctlp->inDatap, sizeof(afs_int32));
+    if (!(flags & AFSCALL_RXSTATS_MASK) || (flags & ~AFSCALL_RXSTATS_MASK)) {
+       return -1;
+    }
+    if (flags & AFSCALL_RXSTATS_ENABLE) {
+        rx_enablePeerRPCStats();
+    }
+    if (flags & AFSCALL_RXSTATS_DISABLE) {
+        rx_disablePeerRPCStats();
+    }
+    if (flags & AFSCALL_RXSTATS_CLEAR) {
+        rx_clearPeerRPCStats(AFS_RX_STATS_CLEAR_ALL);
+    }
     return 0;
 }