Index: openafs/src/WINNT/afsd/cm_access.c diff -c openafs/src/WINNT/afsd/cm_access.c:1.7.2.14 openafs/src/WINNT/afsd/cm_access.c:1.7.2.15 *** openafs/src/WINNT/afsd/cm_access.c:1.7.2.14 Fri Feb 9 18:54:31 2007 --- openafs/src/WINNT/afsd/cm_access.c Thu Apr 26 14:08:00 2007 *************** *** 123,128 **** --- 123,137 ---- } } + /* if the user can insert, we must assume they can read/write as well + * because we do not have the ability to determine if the current user + * is the owner of the file. We will have to make the call to the + * file server and let the file server tell us if the request should + * be denied. + */ + if ((*outRightsp & PRSFS_INSERT) && (scp->creator == userp)) + *outRightsp |= PRSFS_READ | PRSFS_WRITE; + /* if the user can obtain a write-lock, read-locks are implied */ if (*outRightsp & PRSFS_WRITE) *outRightsp |= PRSFS_LOCK; Index: openafs/src/WINNT/afsd/cm_ioctl.h diff -c openafs/src/WINNT/afsd/cm_ioctl.h:1.14.2.2 openafs/src/WINNT/afsd/cm_ioctl.h:1.14.2.3 *** openafs/src/WINNT/afsd/cm_ioctl.h:1.14.2.2 Sat Apr 14 14:49:36 2007 --- openafs/src/WINNT/afsd/cm_ioctl.h Tue May 15 16:20:55 2007 *************** *** 40,45 **** --- 40,50 ---- struct cm_SPref servers[1];/* we overrun this array intentionally...*/ } cm_SSetPref_t; + #define CM_IOCTLCACHEPARMS 16 + typedef struct cm_cacheParms { + afs_uint64 parms[CM_IOCTLCACHEPARMS]; + } cm_cacheParms_t; + #define MAXNUMSYSNAMES 16 /* max that current constants allow */ #define MAXSYSNAME 128 /* max sysname (i.e. @sys) size */ Index: openafs/src/WINNT/afsd/cm_scache.c diff -c openafs/src/WINNT/afsd/cm_scache.c:1.35.2.32 openafs/src/WINNT/afsd/cm_scache.c:1.35.2.34 *** openafs/src/WINNT/afsd/cm_scache.c:1.35.2.32 Thu Feb 8 08:51:40 2007 --- openafs/src/WINNT/afsd/cm_scache.c Wed May 16 11:51:05 2007 *************** *** 189,195 **** } /* discard symlink info */ ! scp->mountPointStringp[0] = 0; memset(&scp->mountRootFid, 0, sizeof(cm_fid_t)); memset(&scp->dotdotFid, 0, sizeof(cm_fid_t)); --- 189,195 ---- } /* discard symlink info */ ! scp->mountPointStringp[0] = '\0'; memset(&scp->mountRootFid, 0, sizeof(cm_fid_t)); memset(&scp->dotdotFid, 0, sizeof(cm_fid_t)); *************** *** 1334,1342 **** scp->anyAccess = 0; scp->dataVersion = 0; ! scp->parentVnode = dscp->fid.vnode; ! scp->parentUnique = dscp->fid.unique; ! return; } else { scp->flags &= ~CM_SCACHEFLAG_EACCESS; --- 1334,1346 ---- scp->anyAccess = 0; scp->dataVersion = 0; ! if (dscp) { ! scp->parentVnode = dscp->fid.vnode; ! scp->parentUnique = dscp->fid.unique; ! } else { ! scp->parentVnode = 0; ! scp->parentUnique = 0; ! } return; } else { scp->flags &= ~CM_SCACHEFLAG_EACCESS; Index: openafs/src/WINNT/afsd/cm_vnodeops.c diff -c openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.28 openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.30 *** openafs/src/WINNT/afsd/cm_vnodeops.c:1.69.2.28 Tue Feb 13 00:47:02 2007 --- openafs/src/WINNT/afsd/cm_vnodeops.c Wed May 2 20:45:58 2007 *************** *** 951,957 **** cm_SyncOpDone(scp, bufp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ); - if (cm_HaveBuffer(scp, bufp, 0)) break; --- 951,956 ---- *************** *** 961,967 **** goto done; } /* locked, has callback, has valid data in buffer */ ! if ((tlen = scp->length.LowPart) > 1000) return CM_ERROR_TOOBIG; if (tlen <= 0) { code = CM_ERROR_INVAL; --- 960,966 ---- goto done; } /* locked, has callback, has valid data in buffer */ ! if ((tlen = scp->length.LowPart) > MOUNTPOINTLEN - 1) return CM_ERROR_TOOBIG; if (tlen <= 0) { code = CM_ERROR_INVAL; *************** *** 2211,2216 **** --- 2210,2224 ---- code = cm_SyncOp(scp, NULL, userp, reqp, PRSFS_WRITE, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_SETSIZE); + + /* If we only have 'i' bits, then we should still be able to set + the size of a file we created. */ + if (code == CM_ERROR_NOACCESS && scp->creator == userp) { + code = cm_SyncOp(scp, NULL, userp, reqp, PRSFS_INSERT, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS + | CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_SETSIZE); + } + if (code) goto done; *************** *** 3240,3245 **** --- 3248,3263 ---- #define SERVERLOCKS_ENABLED(scp) (!((scp)->flags & CM_SCACHEFLAG_RO) && cm_enableServerLocks && SCP_SUPPORTS_BRLOCKS(scp)) + #if defined(VICED_CAPABILITY_WRITELOCKACL) + #define SCP_SUPPORTS_WRITELOCKACL(scp) ((scp)->cbServerp && ((scp->cbServerp->capabilities & VICED_CAPABILITY_WRITELOCKACL))) + #else + #define SCP_SUPPORTS_WRITELOCKACL(scp) (0) + + /* This should really be defined in any build that this code is being + compiled. */ + #error VICED_CAPABILITY_WRITELOCKACL not defined. + #endif + static void cm_LockRangeSubtract(cm_range_t * pos, const cm_range_t * neg) { afs_int64 int_begin; *************** *** 3542,3555 **** - CM_ERROR_NOACCESS if not Any other error from cm_SyncOp will be sent down untranslated. */ long cm_LockCheckPerms(cm_scache_t * scp, int lock_type, cm_user_t * userp, ! cm_req_t * reqp) { long rights = 0; ! long code = 0; /* lock permissions are slightly tricky because of the 'i' bit. If the user has PRSFS_LOCK, she can read-lock the file. If the --- 3560,3578 ---- - CM_ERROR_NOACCESS if not Any other error from cm_SyncOp will be sent down untranslated. + + If CM_ERROR_NOACCESS is returned and lock_type is LockRead, then + phas_insert (if non-NULL) will receive a boolean value indicating + whether the user has INSERT permission or not. */ long cm_LockCheckPerms(cm_scache_t * scp, int lock_type, cm_user_t * userp, ! cm_req_t * reqp, ! int * phas_insert) { long rights = 0; ! long code = 0, code2 = 0; /* lock permissions are slightly tricky because of the 'i' bit. If the user has PRSFS_LOCK, she can read-lock the file. If the *************** *** 3573,3593 **** return 0; } code = cm_SyncOp(scp, NULL, userp, reqp, rights, CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); ! if (code == CM_ERROR_NOACCESS && ! lock_type == LockWrite && ! scp->creator == userp) { ! /* check for PRSFS_INSERT. */ ! code = cm_SyncOp(scp, NULL, userp, reqp, PRSFS_INSERT, CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); ! if (code == CM_ERROR_NOACCESS) ! osi_Log0(afsd_logp, "cm_LockCheckPerms user is creator but has no INSERT bits for scp"); } cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); --- 3596,3632 ---- return 0; } + if (phas_insert) + *phas_insert = FALSE; + code = cm_SyncOp(scp, NULL, userp, reqp, rights, CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); ! if (phas_insert && scp->creator == userp) { ! /* If this file was created by the user, then we check for ! PRSFS_INSERT. If the file server is recent enough, then ! this should be sufficient for her to get a write-lock (but ! not necessarily a read-lock). VICED_CAPABILITY_WRITELOCKACL ! indicates whether a file server supports getting write ! locks when the user only has PRSFS_INSERT. ! ! If the file was not created by the user we skip the check ! because the INSERT bit will not apply to this user even ! if it is set. ! */ ! ! code2 = cm_SyncOp(scp, NULL, userp, reqp, PRSFS_INSERT, CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); ! if (code2 == CM_ERROR_NOACCESS) { ! osi_Log0(afsd_logp, "cm_LockCheckPerms user has no INSERT bits"); ! } else { ! *phas_insert = TRUE; ! osi_Log0(afsd_logp, "cm_LockCheckPerms user has INSERT bits"); ! } } cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); *************** *** 3679,3689 **** if (Which == scp->serverLock || (Which == LockRead && scp->serverLock == LockWrite)) { /* we already have the lock we need */ osi_Log3(afsd_logp, " we already have the correct lock. exclusives[%d], shared[%d], serverLock[%d]", scp->exclusiveLocks, scp->sharedLocks, (int)(signed char) scp->serverLock); ! code = cm_LockCheckPerms(scp, Which, userp, reqp); /* special case: if we don't have permission to read-lock the file, then we force a clientside lock. This is to --- 3718,3730 ---- if (Which == scp->serverLock || (Which == LockRead && scp->serverLock == LockWrite)) { + int has_insert = 0; + /* we already have the lock we need */ osi_Log3(afsd_logp, " we already have the correct lock. exclusives[%d], shared[%d], serverLock[%d]", scp->exclusiveLocks, scp->sharedLocks, (int)(signed char) scp->serverLock); ! code = cm_LockCheckPerms(scp, Which, userp, reqp, &has_insert); /* special case: if we don't have permission to read-lock the file, then we force a clientside lock. This is to *************** *** 3691,3702 **** reading files off of directories that don't grant read-locks to the user. */ if (code == CM_ERROR_NOACCESS && Which == LockRead) { ! osi_Log0(afsd_logp, " User has no read-lock perms. Forcing client-side lock"); ! force_client_lock = TRUE; } } else if ((scp->exclusiveLocks > 0) || (scp->sharedLocks > 0 && scp->serverLock != LockRead)) { /* We are already waiting for some other lock. We should wait for the daemon to catch up instead of generating a --- 3732,3750 ---- reading files off of directories that don't grant read-locks to the user. */ if (code == CM_ERROR_NOACCESS && Which == LockRead) { ! ! if (has_insert && SCP_SUPPORTS_WRITELOCKACL(scp)) { ! osi_Log0(afsd_logp, " User has no read-lock perms, but has INSERT perms."); ! code = 0; ! } else { ! osi_Log0(afsd_logp, " User has no read-lock perms. Forcing client-side lock"); ! force_client_lock = TRUE; ! } } } else if ((scp->exclusiveLocks > 0) || (scp->sharedLocks > 0 && scp->serverLock != LockRead)) { + int has_insert = 0; /* We are already waiting for some other lock. We should wait for the daemon to catch up instead of generating a *************** *** 3706,3717 **** /* see if we have permission to create the lock in the first place. */ ! code = cm_LockCheckPerms(scp, Which, userp, reqp); if (code == 0) code = CM_ERROR_WOULDBLOCK; else if (code == CM_ERROR_NOACCESS && Which == LockRead) { ! osi_Log0(afsd_logp, " User has no read-lock perms. Forcing client-side lock"); ! force_client_lock = TRUE; } /* leave any other codes as-is */ --- 3754,3773 ---- /* see if we have permission to create the lock in the first place. */ ! code = cm_LockCheckPerms(scp, Which, userp, reqp, &has_insert); if (code == 0) code = CM_ERROR_WOULDBLOCK; else if (code == CM_ERROR_NOACCESS && Which == LockRead) { ! ! if (has_insert && SCP_SUPPORTS_WRITELOCKACL(scp)) { ! osi_Log0(afsd_logp, ! " User has no read-lock perms, but has INSERT perms."); ! code = CM_ERROR_WOULDBLOCK; ! } else { ! osi_Log0(afsd_logp, ! " User has no read-lock perms. Forcing client-side lock"); ! force_client_lock = TRUE; ! } } /* leave any other codes as-is */ *************** *** 3719,3742 **** } else { int newLock; int check_data_version = FALSE; /* first check if we have permission to elevate or obtain the lock. */ ! code = cm_LockCheckPerms(scp, Which, userp, reqp); if (code) { ! if (code == CM_ERROR_NOACCESS && Which == LockRead) { osi_Log0(afsd_logp, " User has no read-lock perms. Forcing client-side lock"); force_client_lock = TRUE; } goto check_code; } if (scp->serverLock == LockRead && Which == LockWrite) { /* We want to escalate the lock to a LockWrite. ! Unfortunately that's not really possible without ! letting go of the current lock. But for now we do ! it anyway. */ osi_Log0(afsd_logp, " attempting to UPGRADE from LockRead to LockWrite."); --- 3775,3802 ---- } else { int newLock; int check_data_version = FALSE; + int has_insert = 0; /* first check if we have permission to elevate or obtain the lock. */ ! code = cm_LockCheckPerms(scp, Which, userp, reqp, &has_insert); if (code) { ! if (code == CM_ERROR_NOACCESS && Which == LockRead && ! (!has_insert || !SCP_SUPPORTS_WRITELOCKACL(scp))) { osi_Log0(afsd_logp, " User has no read-lock perms. Forcing client-side lock"); force_client_lock = TRUE; } goto check_code; } + /* has_insert => (Which == LockRead, code == CM_ERROR_NOACCESS) */ + if (scp->serverLock == LockRead && Which == LockWrite) { /* We want to escalate the lock to a LockWrite. ! * Unfortunately that's not really possible without ! * letting go of the current lock. But for now we do ! * it anyway. */ osi_Log0(afsd_logp, " attempting to UPGRADE from LockRead to LockWrite."); *************** *** 3759,3775 **** } /* We need to obtain a server lock of type Which in order ! to assert this file lock */ #ifndef AGGRESSIVE_LOCKS newLock = Which; #else newLock = LockWrite; #endif code = cm_IntSetLock(scp, userp, newLock, reqp); ! if (code == CM_ERROR_WOULDBLOCK && newLock != Which) { /* we wanted LockRead. We tried LockWrite. Now try ! LockRead again */ newLock = Which; /* am I sane? */ --- 3819,3838 ---- } /* We need to obtain a server lock of type Which in order ! * to assert this file lock */ #ifndef AGGRESSIVE_LOCKS newLock = Which; #else newLock = LockWrite; #endif + code = cm_IntSetLock(scp, userp, newLock, reqp); ! #ifdef AGGRESSIVE_LOCKS ! if ((code == CM_ERROR_WOULDBLOCK || ! code == CM_ERROR_NOACCESS) && newLock != Which) { /* we wanted LockRead. We tried LockWrite. Now try ! * LockRead again */ newLock = Which; /* am I sane? */ *************** *** 3777,3788 **** code = cm_IntSetLock(scp, userp, newLock, reqp); } if (code == 0 && check_data_version && scp->dataVersion != scp->lockDataVersion) { /* We lost a race. Although we successfully obtained ! a lock, someone modified the file in between. The ! locks have all been technically lost. */ osi_Log0(afsd_logp, " Data version mismatch while upgrading lock."); --- 3840,3893 ---- code = cm_IntSetLock(scp, userp, newLock, reqp); } + #endif + + if (code == CM_ERROR_NOACCESS) { + if (Which == LockRead) { + if (has_insert && SCP_SUPPORTS_WRITELOCKACL(scp)) { + long tcode; + /* We requested a read-lock, but we have permission to + * get a write-lock. Try that */ + + tcode = cm_LockCheckPerms(scp, LockWrite, userp, reqp, NULL); + + if (tcode == 0) { + newLock = LockWrite; + + osi_Log0(afsd_logp, " User has 'i' perms and the request was for a LockRead. Trying to get a LockWrite instead"); + + code = cm_IntSetLock(scp, userp, newLock, reqp); + } + } else { + osi_Log0(afsd_logp, " User has no read-lock perms. Forcing client-side lock"); + force_client_lock = TRUE; + } + } else if (Which == LockWrite && + scp->creator == userp && !SCP_SUPPORTS_WRITELOCKACL(scp)) { + long tcode; + + /* Special case: if the lock request was for a + * LockWrite and the user owns the file and we weren't + * allowed to obtain the serverlock, we either lost a + * race (the permissions changed from under us), or we + * have 'i' bits, but we aren't allowed to lock the + * file. */ + + /* check if we lost a race... */ + tcode = cm_LockCheckPerms(scp, Which, userp, reqp, NULL); + + if (tcode == 0) { + osi_Log0(afsd_logp, " User has 'i' perms but can't obtain write locks. Using client-side locks."); + force_client_lock = TRUE; + } + } + } if (code == 0 && check_data_version && scp->dataVersion != scp->lockDataVersion) { /* We lost a race. Although we successfully obtained ! * a lock, someone modified the file in between. The ! * locks have all been technically lost. */ osi_Log0(afsd_logp, " Data version mismatch while upgrading lock."); *************** *** 4200,4205 **** --- 4305,4321 ---- scp->lockDataVersion = scp->dataVersion; osi_Log1(afsd_logp, " dataVersion on scp is %d", scp->dataVersion); + /* before we downgrade, make sure that we have enough + permissions to get the read lock. */ + code = cm_LockCheckPerms(scp, LockRead, userp, reqp, NULL); + if (code != 0) { + + osi_Log0(afsd_logp, " SKIPPING downgrade because user doesn't have perms to get downgraded lock"); + + code = 0; + goto done; + } + code = cm_IntReleaseLock(scp, userp, reqp); if (code) { *************** *** 4525,4530 **** --- 4641,4648 ---- cm_req_t req; int newLock = -1; int force_client_lock = FALSE; + int has_insert = FALSE; + int check_data_version = FALSE; cm_InitReq(&req); *************** *** 4570,4579 **** code = cm_LockCheckPerms(scp, oldFileLock->lockType, oldFileLock->userp, ! &req); if (code == CM_ERROR_NOACCESS && oldFileLock->lockType == LockRead) { force_client_lock = TRUE; code = 0; } else if (code) { lock_ReleaseMutex(&scp->mx); --- 4688,4699 ---- code = cm_LockCheckPerms(scp, oldFileLock->lockType, oldFileLock->userp, ! &req, &has_insert); if (code == CM_ERROR_NOACCESS && oldFileLock->lockType == LockRead) { + if (!has_insert || !SCP_SUPPORTS_WRITELOCKACL(scp)) { force_client_lock = TRUE; + } code = 0; } else if (code) { lock_ReleaseMutex(&scp->mx); *************** *** 4667,4672 **** --- 4787,4794 ---- oldFileLock->flags |= CM_FILELOCK_FLAG_WAITLOCK; } + osi_assert(IS_LOCK_WAITLOCK(oldFileLock)); + if (force_client_lock || !SERVERLOCKS_ENABLED(scp) || scp->serverLock == oldFileLock->lockType || *************** *** 4718,4727 **** --- 4840,4906 ---- newLock = LockWrite; #endif + if (has_insert) { + /* if has_insert is non-zero, then: + - the lock a LockRead + - we don't have permission to get a LockRead + - we do have permission to get a LockWrite + - the server supports VICED_CAPABILITY_WRITELOCKACL + */ + + newLock = LockWrite; + } + lock_ReleaseWrite(&cm_scacheLock); + /* when we get here, either we have a read-lock and want a + write-lock or we don't have any locks and we want some + lock. */ + + if (scp->serverLock == LockRead) { + + osi_assert(newLock == LockWrite); + + osi_Log0(afsd_logp, " Attempting to UPGRADE from LockRead to LockWrite"); + + scp->lockDataVersion = scp->dataVersion; + check_data_version = TRUE; + + code = cm_IntReleaseLock(scp, userp, &req); + + if (code) + goto pre_syncopdone; + else + scp->serverLock = -1; + } + code = cm_IntSetLock(scp, userp, newLock, &req); + if (code == 0) { + if (scp->dataVersion != scp->lockDataVersion) { + /* we lost a race. too bad */ + + osi_Log0(afsd_logp, + " Data version mismatch while upgrading lock."); + osi_Log2(afsd_logp, + " Data versions before=%d, after=%d", + scp->lockDataVersion, + scp->dataVersion); + osi_Log1(afsd_logp, + " Releasing stale lock for scp 0x%x", scp); + + code = cm_IntReleaseLock(scp, userp, &req); + + scp->serverLock = -1; + + code = CM_ERROR_INVAL; + + cm_LockMarkSCacheLost(scp); + } else { + scp->serverLock = newLock; + } + } + pre_syncopdone: cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK); post_syncopdone: *************** *** 4735,4742 **** scp->fileLocksT = osi_QPrev(&oldFileLock->fileq); osi_QRemoveHT(&scp->fileLocksH, &scp->fileLocksT, &oldFileLock->fileq); lock_ReleaseWrite(&cm_scacheLock); - } else if (code == 0 && IS_LOCK_WAITLOCK(oldFileLock)) { - scp->serverLock = newLock; } lock_ReleaseMutex(&scp->mx); --- 4914,4919 ---- Index: openafs/src/WINNT/afsd/cm_volume.c diff -c openafs/src/WINNT/afsd/cm_volume.c:1.14.4.6 openafs/src/WINNT/afsd/cm_volume.c:1.14.4.8 *** openafs/src/WINNT/afsd/cm_volume.c:1.14.4.6 Sat Feb 3 21:46:25 2007 --- openafs/src/WINNT/afsd/cm_volume.c Fri May 4 02:06:13 2007 *************** *** 590,597 **** --- 590,600 ---- void cm_RefreshVolumes(void) { cm_volume_t *volp; + cm_scache_t *scp; cm_data.mountRootGen = time(NULL); + + /* force a re-loading of volume data from the vldb */ lock_ObtainWrite(&cm_volumeLock); for (volp = cm_data.allVolumesp; volp; volp=volp->nextp) { volp->refCount++; *************** *** 606,612 **** } lock_ReleaseWrite(&cm_volumeLock); ! /* We should also refresh cached mount points */ } /* --- 609,632 ---- } lock_ReleaseWrite(&cm_volumeLock); ! /* force mount points to be re-evaluated so that ! * if the volume location has changed we will pick ! * that up ! */ ! for ( scp = cm_data.scacheLRUFirstp; ! scp; ! scp = (cm_scache_t *) osi_QNext(&scp->q)) { ! if ( scp->fileType == CM_SCACHETYPE_MOUNTPOINT ! #ifdef AFS_FREELANCE_CLIENT ! && !(scp->fid.cell == AFS_FAKE_ROOT_CELL_ID && scp->fid.volume == AFS_FAKE_ROOT_VOL_ID) ! #endif ! ) { ! lock_ObtainMutex(&scp->mx); ! scp->mountPointStringp[0] = '\0'; ! lock_ReleaseMutex(&scp->mx); ! } ! } ! } /* Index: openafs/src/WINNT/afsd/fs.c diff -c openafs/src/WINNT/afsd/fs.c:1.32.4.8 openafs/src/WINNT/afsd/fs.c:1.32.4.9 *** openafs/src/WINNT/afsd/fs.c:1.32.4.8 Sat Apr 14 14:49:36 2007 --- openafs/src/WINNT/afsd/fs.c Tue May 15 16:20:55 2007 *************** *** 2277,2304 **** return 0; } - #define MAXGCSIZE 16 static int GetCacheParmsCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; ! afs_uint64 parms[MAXGCSIZE]; ! memset(parms, 0, sizeof(parms)); blob.in = NULL; blob.in_size = 0; blob.out_size = sizeof(parms); ! blob.out = (char *) parms; code = pioctl(0, VIOCGETCACHEPARMS, &blob, 1); if (code) { Die(errno, NULL); return 1; } ! printf("AFS using %d of the cache's available %d 1K byte blocks.\n", ! parms[1], parms[0]); ! if (parms[1] > parms[0]) printf("[Cache guideline temporarily deliberately exceeded; it will be adjusted down but you may wish to increase the cache size.]\n"); return 0; } --- 2277,2303 ---- return 0; } static int GetCacheParmsCmd(struct cmd_syndesc *as, char *arock) { afs_int32 code; struct ViceIoctl blob; ! cm_cacheParms_t parms; ! memset(&parms, 0, sizeof(parms)); blob.in = NULL; blob.in_size = 0; blob.out_size = sizeof(parms); ! blob.out = (char *) &parms; code = pioctl(0, VIOCGETCACHEPARMS, &blob, 1); if (code) { Die(errno, NULL); return 1; } ! printf("AFS using %I64u of the cache's available %I64u 1K byte blocks.\n", ! parms.parms[1], parms.parms[0]); ! if (parms.parms[1] > parms.parms[0]) printf("[Cache guideline temporarily deliberately exceeded; it will be adjusted down but you may wish to increase the cache size.]\n"); return 0; } Index: openafs/src/WINNT/afsd/smb3.c diff -c openafs/src/WINNT/afsd/smb3.c:1.95.2.30 openafs/src/WINNT/afsd/smb3.c:1.95.2.33 *** openafs/src/WINNT/afsd/smb3.c:1.95.2.30 Fri Feb 9 19:00:44 2007 --- openafs/src/WINNT/afsd/smb3.c Wed May 16 11:55:16 2007 *************** *** 3292,3299 **** smb_fid_t *fidp; unsigned short infoLevel; smb_tran2Packet_t *outp; ! cm_user_t *userp; ! cm_scache_t *scp; cm_req_t req; cm_InitReq(&req); --- 3292,3299 ---- smb_fid_t *fidp; unsigned short infoLevel; smb_tran2Packet_t *outp; ! cm_user_t *userp = NULL; ! cm_scache_t *scp = NULL; cm_req_t req; cm_InitReq(&req); *************** *** 3320,3326 **** if (infoLevel == SMB_SET_FILE_DISPOSITION_INFO && !(fidp->flags & SMB_FID_OPENDELETE)) { osi_Log3(smb_logp,"smb_ReceiveTran2SetFileInfo !SMB_FID_OPENDELETE fidp 0x%p scp 0x%p fidp->flags 0x%x", ! fidp, scp, fidp->flags); lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOACCESS); --- 3320,3326 ---- if (infoLevel == SMB_SET_FILE_DISPOSITION_INFO && !(fidp->flags & SMB_FID_OPENDELETE)) { osi_Log3(smb_logp,"smb_ReceiveTran2SetFileInfo !SMB_FID_OPENDELETE fidp 0x%p scp 0x%p fidp->flags 0x%x", ! fidp, fidp->scp, fidp->flags); lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOACCESS); *************** *** 3330,3336 **** infoLevel == SMB_SET_FILE_END_OF_FILE_INFO) && !(fidp->flags & SMB_FID_OPENWRITE)) { osi_Log3(smb_logp,"smb_ReceiveTran2SetFileInfo !SMB_FID_OPENWRITE fidp 0x%p scp 0x%p fidp->flags 0x%x", ! fidp, scp, fidp->flags); lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOACCESS); --- 3330,3336 ---- infoLevel == SMB_SET_FILE_END_OF_FILE_INFO) && !(fidp->flags & SMB_FID_OPENWRITE)) { osi_Log3(smb_logp,"smb_ReceiveTran2SetFileInfo !SMB_FID_OPENWRITE fidp 0x%p scp 0x%p fidp->flags 0x%x", ! fidp, fidp->scp, fidp->flags); lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOACCESS); *************** *** 3654,3670 **** unsigned long lattr; smb_dirListPatch_t *patchp; smb_dirListPatch_t *npatchp; ! for(patchp = *dirPatchespp; patchp; patchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q)) { ! code = cm_GetSCache(&patchp->fid, &scp, userp, reqp); ! if (code) continue; lock_ObtainMutex(&scp->mx); ! code = cm_SyncOp(scp, NULL, userp, reqp, 0, ! CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); ! if (code) { lock_ReleaseMutex(&scp->mx); - cm_ReleaseSCache(scp); dptr = patchp->dptr; --- 3654,3690 ---- unsigned long lattr; smb_dirListPatch_t *patchp; smb_dirListPatch_t *npatchp; ! afs_uint32 rights; ! afs_int32 mustFake = 0; ! ! code = cm_FindACLCache(dscp, userp, &rights); ! if (code == 0 && !(rights & PRSFS_READ)) ! mustFake = 1; ! else if (code == -1) { ! lock_ObtainMutex(&dscp->mx); ! code = cm_SyncOp(dscp, NULL, userp, reqp, PRSFS_READ, ! CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); ! lock_ReleaseMutex(&dscp->mx); ! if (code == CM_ERROR_NOACCESS) { ! mustFake = 1; ! code = 0; ! } ! } ! if (code) ! return code; ! for(patchp = *dirPatchespp; patchp; patchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q)) { ! code = cm_GetSCache(&patchp->fid, &scp, userp, reqp); ! if (code) ! continue; ! lock_ObtainMutex(&scp->mx); ! if (mustFake == 0) ! code = cm_SyncOp(scp, NULL, userp, reqp, 0, ! CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); ! if (mustFake || code) { lock_ReleaseMutex(&scp->mx); dptr = patchp->dptr; *************** *** 3691,3699 **** *((FILETIME *)dptr) = ft; dptr += 24; /* merge in hidden attribute */ if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) { ! *((u_long *)dptr) = SMB_ATTR_HIDDEN; } dptr += 4; } else { --- 3711,3730 ---- *((FILETIME *)dptr) = ft; dptr += 24; + switch (scp->fileType) { + case CM_SCACHETYPE_DIRECTORY: + case CM_SCACHETYPE_MOUNTPOINT: + case CM_SCACHETYPE_SYMLINK: + case CM_SCACHETYPE_INVALID: + *((u_long *)dptr) = SMB_ATTR_DIRECTORY; + break; + default: + *((u_long *)dptr) = SMB_ATTR_NORMAL; + + } /* merge in hidden attribute */ if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) { ! *((u_long *)dptr) |= SMB_ATTR_HIDDEN; } dptr += 4; } else { *************** *** 3730,3742 **** *((u_short *)dptr) = shortTemp; dptr += 10; /* merge in hidden (dot file) attribute */ if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) { ! attr = SMB_ATTR_HIDDEN; ! *dptr++ = attr & 0xff; ! *dptr++ = (attr >> 8) & 0xff; } } continue; } --- 3761,3785 ---- *((u_short *)dptr) = shortTemp; dptr += 10; + /* set the attribute */ + switch (scp->fileType) { + case CM_SCACHETYPE_DIRECTORY: + case CM_SCACHETYPE_MOUNTPOINT: + case CM_SCACHETYPE_SYMLINK: + case CM_SCACHETYPE_INVALID: + attr = SMB_ATTR_DIRECTORY; + default: + attr = SMB_ATTR_NORMAL; + } /* merge in hidden (dot file) attribute */ if ( patchp->flags & SMB_DIRLISTPATCH_DOTFILE ) { ! attr |= SMB_ATTR_HIDDEN; } + *dptr++ = attr & 0xff; + *dptr++ = (attr >> 8) & 0xff; } + + cm_ReleaseSCache(scp); continue; } Index: openafs/src/WINNT/afsd/smb_iocons.h diff -c openafs/src/WINNT/afsd/smb_iocons.h:1.10.4.3 openafs/src/WINNT/afsd/smb_iocons.h:1.10.4.4 *** openafs/src/WINNT/afsd/smb_iocons.h:1.10.4.3 Sat Apr 14 14:49:36 2007 --- openafs/src/WINNT/afsd/smb_iocons.h Tue May 15 16:20:55 2007 *************** *** 41,51 **** int sb_default; }; - #define CM_IOCTLCACHEPARMS 16 - typedef struct cm_cacheParms { - afs_uint64 parms[CM_IOCTLCACHEPARMS]; - } cm_cacheParms_t; - /* set cell flags */ #define CM_SETCELLFLAG_SUID 2 --- 41,46 ---- Index: openafs/src/WINNT/aklog/aklog.c diff -c openafs/src/WINNT/aklog/aklog.c:1.14.4.3 openafs/src/WINNT/aklog/aklog.c:1.14.4.4 *** openafs/src/WINNT/aklog/aklog.c:1.14.4.3 Wed Apr 4 16:26:10 2007 --- openafs/src/WINNT/aklog/aklog.c Tue May 15 23:34:58 2007 *************** *** 255,262 **** } id = 0; strncpy(aclient->name, username, MAXKTCNAMELEN - 1); strcpy(aclient->instance, ""); ! strncpy(aclient->cell, c->realm, MAXKTCREALMLEN - 1); for ( i=0; aclient->cell[i]; i++ ) { if ( islower(aclient->cell[i]) ) --- 255,264 ---- } id = 0; strncpy(aclient->name, username, MAXKTCNAMELEN - 1); + aclient->name[MAXKTCNAMELEN - 1] = '\0'; strcpy(aclient->instance, ""); ! strncpy(aclient->cell, cell_to_use, MAXKTCREALMLEN - 1); ! aclient->cell[MAXKTCREALMLEN - 1] = '\0'; for ( i=0; aclient->cell[i]; i++ ) { if ( islower(aclient->cell[i]) ) Index: openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm diff -c openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm:1.5.4.13 openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm:1.5.4.14 *** openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm:1.5.4.13 Wed Apr 18 12:03:12 2007 --- openafs/src/WINNT/doc/install/Documentation/en_US/html/index.htm Wed May 16 18:37:08 2007 *************** *** 198,204 ****

OpenAFS for Windows

!

Version 1.5.19

 

--- 198,204 ----

OpenAFS for Windows

!

Version 1.5.20

 

Index: openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm diff -c openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm:1.1.6.14 openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm:1.1.6.15 *** openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm:1.1.6.14 Wed Apr 18 12:03:22 2007 --- openafs/src/WINNT/doc/install/Documentation/en_US/html/ReleaseNotes/logo.htm Wed May 16 18:37:13 2007 *************** *** 18,24 **** .shape {behavior:url(#default#VML);} ! OpenAFS for Windows 1.5.19 Release Notes ! OpenAFS for Windows 1.5.20 Release Notes ! OpenAFS for Windows 1.5.19 Release Notes ! OpenAFS for Windows 1.5.20 Release Notes Jeffrey Altman 2 ! 720 2006-11-29T17:26:00Z 2006-12-18T23:20:00Z ! 17 ! 16931 ! 96510 Secure Endpoints Inc. ! 804 ! 226 ! 113215 ! 11.8107

!

The AFS configuration panel for each Kerberos 5 identity is used to configure which cells credentials should be obtained for and how they should be obtained.  If the cell to realm mapping cannot be automatically determined, it can be explicitly ! specified.  If the cell does not support ! Kerberos 5 tickets as tokens, then a krb524 service can be configured.

!

The AFS configuration panel for each Kerberos v5 identity is used to configure which cells credentials should be obtained for and how they should be obtained.  If the cell to realm mapping cannot be automatically determined, it can be explicitly ! specified.  If the cell does not support Kerberos ! v5 tickets as tokens, then a krb524 service can be configured.

!

The AFS plug-in configuration panel provider can be used to check the status of the AFS Client Service and its version.  An optional checkbox is provided that will prevent the AFS System Tray Tool from being started by Windows after --- 954,960 ----

!

The OpenAFS Provider configuration panel can be used to check the status of the AFS Client Service and its version.  An optional checkbox is provided that will prevent the AFS System Tray Tool from being started by Windows after *************** *** 965,974 ****

By itself the OpenAFS Client Service does not provide robust behavior in a plug-n-play network environment.  Changes to the number of network adapters or their assigned IP addresses will cause the service to ! terminate unexpectedly.  To avoid this behavior OpenAFS for Windows installs ! a single instance of the Microsoft Loopback Adapter (MLA) on the machine.  ! With the MLA installed, the OpenAFS Client Service will not be affected by the ! configuration changes of other network adapters installed on the system. 

The MLA is installed with a name of "AFS" and a pre-assigned IP address in the 10.x.x.x range.  The MLA is bound to the --- 970,980 ----

By itself the OpenAFS Client Service does not provide robust behavior in a plug-n-play network environment.  Changes to the number of network adapters or their assigned IP addresses will cause the service to ! terminate unexpectedly.  To avoid this behavior OpenAFS for Windows ! installs a single instance of the Microsoft Loopback Adapter (MLA) on the ! machine.  With the MLA installed, the OpenAFS Client Service will not be ! affected by the configuration changes of other network adapters installed on ! the system. 

The MLA is installed with a name of "AFS" and a pre-assigned IP address in the 10.x.x.x range.  The MLA is bound to the *************** *** 1041,1052 **** modified as cells are accessed.  When the fake "root.afs" volume is initially constructed it will only contain two mount points: a regular path and read-write path mount point used to access the ! "root.cell" volume of the default AFS cell.  Any attempt to ! access a valid cell name will result in a new mount point being created in the ! fake "root.afs" volume.  If the cellname begins with a ! "." the mount point will be a read-write path; otherwise the ! mount point will be a regular path.  These mount points are ! preserved in the registry at key:

HKLM\SOFTWARE\OpenAFS\Client\Freelance

--- 1047,1058 ---- modified as cells are accessed.  When the fake "root.afs" volume is initially constructed it will only contain two mount points: a regular path and read-write path mount point used to access the ! "root.cell" volume of the default AFS cell.  Any attempt to access ! a valid cell name will result in a new mount point being created in the fake ! "root.afs" volume.  If the cellname begins with a "." ! the mount point will be a read-write path; otherwise the mount point ! will be a regular path.  These mount points are preserved in the ! registry at key:

HKLM\SOFTWARE\OpenAFS\Client\Freelance

*************** *** 1107,1116 **** provide Single Sign-On functionality (aka Integrated Logon.)  Integrated Logon can be used when the Windows username and password match the username and password associated with the default cell's Kerberos realm.  For example, ! if the Windows username is "jaltman" and the default cell is "athena.mit.edu", ! then Integrated Logon can be successfully used if the windows password matches ! the password assigned to the Kerberos principal "jaltman@ATHENA.MIT.EDU".  The realm “ATHENA.MIT.EDU” is obtained by performing a domain name to realm mapping on the hostname of one of the cell's Volume Database servers.

--- 1113,1122 ---- provide Single Sign-On functionality (aka Integrated Logon.)  Integrated Logon can be used when the Windows username and password match the username and password associated with the default cell's Kerberos realm.  For example, ! if the Windows username is "jaltman" and the default cell is ! "athena.mit.edu", then Integrated Logon can be successfully used if ! the windows password matches the password assigned to the Kerberos principal ! "jaltman@ATHENA.MIT.EDU".  The realm “ATHENA.MIT.EDU” is obtained by performing a domain name to realm mapping on the hostname of one of the cell's Volume Database servers.

*************** *** 1120,1129 **** passwords.

When KFW is configured, Integrated Logon will use it to ! obtain tokens. Use of KFW for Integrated Logon can be ! disabled via the EnableKFW registry ! value.  Use of the krb524 service can be ! configured via the Use524 registry value.

Integrated Logon will not preserve the Kerberos v5 tickets. KFW 3.1 and above implements that functionality.

--- 1126,1135 ---- passwords.

When KFW is configured, Integrated Logon will use it to ! obtain tokens. Use of KFW for Integrated Logon can be disabled via the EnableKFW registry value.  Use of the krb524 service can be configured ! via the Use524 registry value.

Integrated Logon will not preserve the Kerberos v5 tickets. KFW 3.1 and above implements that functionality.

*************** *** 1143,1148 **** --- 1149,1159 ---- style='mso-bookmark:_Toc152605047'>3.6. AFS System Tray Command Line Options +

The AFS System Tray Tool + (afscreds.exe) has been deprecated in favor of Network Identity Manager.  afscreds.exe will be removed from the OpenAFS + in a future release.

+

The AFS System Tray tool (afscreds.exe) supports several command line options:

*************** *** 1175,1182 **** tokens when afscreds.exe is started.  afscreds.exe will attempt to utilize tickets stored in the MSLSA credentials cache; any existing CCAPI credentials cache; and finally display an Obtain Tokens dialog to the user.  When used ! in combination with IP address change detection, afscreds.exe will attempt to ! acquire AFS tokens whenever the IP address list changes and the Kerberos KDC is accessible.

The renew drive maps option is used to ensure that the user --- 1186,1193 ---- tokens when afscreds.exe is started.  afscreds.exe will attempt to utilize tickets stored in the MSLSA credentials cache; any existing CCAPI credentials cache; and finally display an Obtain Tokens dialog to the user.  When used ! in combination with IP address change detection, afscreds.exe will attempt to acquire ! AFS tokens whenever the IP address list changes and the Kerberos KDC is accessible.

The renew drive maps option is used to ensure that the user *************** *** 1254,1262 **** style='font-size:9.0pt;font-family:Symbol'>·       minidump

!

The creation or removal of mount points and symlinks in the ! Freelance “root.afs” volume are also restricted to members of the “AFS Client ! Admins” group.

The initial membership of the "AFS Client Admins" group when created by the installer is equivalent to the local --- 1265,1273 ---- style='font-size:9.0pt;font-family:Symbol'>·       minidump

!

The creation or removal of mount points and symlinks in the Freelance ! “root.afs” volume are also restricted to members of the “AFS Client Admins” ! group.

The initial membership of the "AFS Client Admins" group when created by the installer is equivalent to the local *************** *** 1264,1271 **** "Administrators" group after the creation of the "AFS Client Admin" group, that user will not be an AFS Client Administrator.  Only users that are members of the "AFS Client Admins" group are AFS ! Client Administrators.  The local "SYSTEM" account is an ! implicit member of the "AFS Client Admins" group.

Setting the default sysname for a machine should be done via the registry and not via "fs --- 1275,1282 ---- "Administrators" group after the creation of the "AFS Client Admin" group, that user will not be an AFS Client Administrator.  Only users that are members of the "AFS Client Admins" group are AFS ! Client Administrators.  The local "SYSTEM" account is an implicit ! member of the "AFS Client Admins" group.

Setting the default sysname for a machine should be done via the registry and not via "fs *************** *** 1300,1310 **** name="_Toc115416115">3.9. ! OpenAFS includes aklog.exe

The OpenAFS Client ships with its own version of aklog.exe which should be used in preference to those obtained by other sources.  ! The OpenAFS aklog.exe supports Kerberos 5 as well as the ability to auto-generate AFS IDs within foreign PTS databases.

Usage: aklog [-d] [[-cell | -c] cell [-k krb_realm]]

--- 1311,1321 ---- name="_Toc115416115">3.9. ! aklog.exe

The OpenAFS Client ships with its own version of aklog.exe which should be used in preference to those obtained by other sources.  ! The OpenAFS aklog.exe supports Kerberos v5 as well as the ability to auto-generate AFS IDs within foreign PTS databases.

Usage: aklog [-d] [[-cell | -c] cell [-k krb_realm]]

*************** *** 1357,1373 **** style='mso-spacerun:yes'>  The TransarcAFSServer service will auto-start the traditional AFS bos server.  The former AFS Server Configuration wizard makes assumptions that no longer hold ! true.  As a result, the installation ! process will fail.  However, following ! the instructions for installing the AFS Servers on UNIX it is possible to ! properly configure the AFS Servers on Microsoft Windows.  The AFS Server binaries, configuration files, ! and log files are installed under %Program Files%\OpenAFS\Server.   kaserver is deprecated and its ! use is strongly discouraged.  ! Instead, Active Directory or some other Kerberos 5 KDC should be used in ! its place.

3.10.2. Using the AFS Client Service when the Server is installed

--- 1368,1383 ---- style='mso-spacerun:yes'>  The TransarcAFSServer service will auto-start the traditional AFS bos server.  The former AFS Server Configuration wizard makes assumptions that no longer hold ! true and it has therefore been disabled.  ! However, following the instructions for installing the AFS Servers on ! UNIX it is possible to properly configure the AFS Servers on Microsoft ! Windows.  The AFS Server binaries, ! configuration files, and log files are installed under %Program ! Files%\OpenAFS\Server.   kaserver has been deprecated and its use is strongly ! discouraged.  Instead, ! Active Directory or some other Kerberos v5 KDC should be used in its place.

3.10.2. Using the AFS Client Service when the Server is installed

*************** *** 1379,1386 **** style='font-size:9.0pt;font-family:Symbol'>·       Freelance mode should be disabled when the AFS Client Service is installed on the same ! machine as the AFS Server,.  Otherwise, you will be unable to manipulate the ! contents of the root.afs volume for the hosted cell without constructing an explicit mountpoint to the root.afs volume from another volume.

·       Freelance mode should be disabled when the AFS Client Service is installed on the same ! machine as the AFS Server,.  Otherwise, you will be unable to manipulate ! the contents of the root.afs volume for the hosted cell without constructing an explicit mountpoint to the root.afs volume from another volume.

MIT Kerberos for Windows should not be installed or must be disabled via the EnableKFW registry value. 

MIT Kerberos for Windows should not be installed or must be disabled via the EnableKFW registry value.

! !

·       The AFS ! Servers are not aware of power management events nor are they aware of network ! configuration changes.  It is strongly ! advised that the AFS servers be installed only on systems that will not be ! shutdown or suspended unexpectedly.   An inadvertent ! shutdown will corrupt volume data.

3.13. ! Encrypted AFS File Access

The OpenAFS for Windows installer by default activates a weak form of encrypted data transfer between the AFS client and the AFS --- 1460,1466 ---- name="_Toc115416119">3.13. ! Encrypted AFS Network Communication

The OpenAFS for Windows installer by default activates a weak form of encrypted data transfer between the AFS client and the AFS *************** *** 1458,1469 **** Authenticated Access to the OpenAFS Client Service

OpenAFS authenticates SMB connections using either NTLM or ! GSS SPNEGO (NTLM).  In previous versions of OpenAFS, the SMB connections were ! unauthenticated which opened the door for several attacks which could be used ! to obtain access to another user's tokens on shared machines.    !

!

When GSS SPNEGO attempts a Kerberos 5 authentication, the Windows SMB client will attempt to retrieve service tickets for "cifs/afs@REALM" (if the loopback adapter is in use) or "cifs/machine-afs@REALM" (if the loopback adapter is not being --- 1476,1487 ---- Authenticated Access to the OpenAFS Client Service

OpenAFS authenticates SMB connections using either NTLM or ! GSS SPNEGO (NTLM).  In previous versions of OpenAFS, the SMB connections ! were unauthenticated which opened the door for several attacks which could be ! used to obtain access to another user's tokens on shared ! machines.   

!

When GSS SPNEGO attempts a Kerberos v5 authentication, the Windows SMB client will attempt to retrieve service tickets for "cifs/afs@REALM" (if the loopback adapter is in use) or "cifs/machine-afs@REALM" (if the loopback adapter is not being *************** *** 1501,1510 ****

The OpenAFS Client is compatible with the Internet Connection Firewall that debuted with Windows XP SP2 and Windows 2003 ! SP1.  The Internet Connection Firewall will be automatically adjusted to allow ! the receipt of incoming callback messages from the AFS file server.  In ! addition, the appropriate Back Connection registry entries are added to ! allow SMB authentication to be performed across the Microsoft Loopback Adapter.

The OpenAFS Client is compatible with the Internet Connection Firewall that debuted with Windows XP SP2 and Windows 2003 ! SP1.  The Internet Connection Firewall will be automatically adjusted to ! allow the receipt of incoming callback messages from the AFS file server.  ! In addition, the appropriate Back Connection registry entries are added ! to allow SMB authentication to be performed across the Microsoft Loopback ! Adapter.

Many applications on Windows (e.g. Microsoft Office) require the use of byte range locks applied to a file either to protect against ! simultaneous file access or as a signaling mechanism.   OpenAFS for ! Windows release 1.5 (or greater) implements byte range locking within the ! CIFS-AFS gateway server.   This support for byte range locking ! obtains AFS’ advisory file server locks to simulate Microsoft Windows mandatory locks.   When an application opens a file, a lock will be obtained from AFS indicating that the file is in use.  If the lock is a write lock, access to the file will be restricted to other applications running on the same --- 1545,1554 ----

Many applications on Windows (e.g. Microsoft Office) require the use of byte range locks applied to a file either to protect against ! simultaneous file access or as a signaling mechanism.   OpenAFS for Windows ! release 1.5 (or greater) implements byte range locking within the CIFS-AFS ! gateway server.   This support for byte range locking obtains AFS’ ! advisory file server locks to simulate Microsoft Windows mandatory locks.   When an application opens a file, a lock will be obtained from AFS indicating that the file is in use.  If the lock is a write lock, access to the file will be restricted to other applications running on the same *************** *** 1547,1559 **** lock semantics on top of AFS lock semantics it is important to understand how AFS file locks work.  In Windows there are no special privileges associated with obtaining file locks.  If you can read or execute a file, ! then you can obtain shared and exclusive locks.  In general, a Windows shared ! lock equates to an AFS read lock and a Windows exclusive lock equates to an AFS ! write lock.  In AFS if you can write to a file, then you ! can obtain a write lock.  However, in AFS if you can read a file it does ! not mean that you can obtain a read lock on it.   The ability to ! obtain read locks is granted only if you have the lock (or ‘k’) privilege.  ! This behavior is required in order to allow anonymous users to read files while preventing them from being able to deny access to the files to other users.  OpenAFS 1.4.0 and earlier as well as all IBM AFS file servers have an implementation bug that prevents users with write privileges from being --- 1566,1578 ---- lock semantics on top of AFS lock semantics it is important to understand how AFS file locks work.  In Windows there are no special privileges associated with obtaining file locks.  If you can read or execute a file, ! then you can obtain shared and exclusive locks.  In general, a Windows ! shared lock equates to an AFS read lock and a Windows exclusive lock equates to ! an AFS write lock.  In AFS if you can write to a file, then you can obtain ! a write lock.  However, in AFS if you can read a file it does not mean ! that you can obtain a read lock on it.   The ability to obtain read ! locks is granted only if you have the lock (or ‘k’) privilege.  This ! behavior is required in order to allow anonymous users to read files while preventing them from being able to deny access to the files to other users.  OpenAFS 1.4.0 and earlier as well as all IBM AFS file servers have an implementation bug that prevents users with write privileges from being *************** *** 1567,1613 **** inconvenience on end users. 

    !
  • If the file is located on a read-only volume and the application requests a ! shared lock, the CIFS-AFS server will grant the lock request without asking ! the AFS file server.
  • !
  • If ! the file is located on a read-only volume and the application opens the ! file with write access and requests an exclusive lock, the CIFS-AFS server will refuse the lock request and return a read only error.
  • !
  • If ! the file is located on a read-only volume and the application opens the ! file with only read access and requests an exclusive lock, the CIFS-AFS server ! will fulfill the lock request with a read lock.
  • !
  • If the file is located on a read-write volume and the application requests an ! exclusive lock, the CIFS-AFS server will request a write lock from the AFS file ! server.  If granted by the file server, then the CIFS-AFS server will ! grant the lock request.  ! ! If the request is denied due to an access denied error and the user has the ! lookup, read and lock privileges and the file was opened for read only access, ! then the CIFS-AFS server will request a read lock from the file server.  ! ! If the request is denied due to an access denied error and the user has the ! lookup and read privileges but not the lock privilege, then the CIFS-AFS ! server will grant the request even though the AFS file server said ‘no’.  ! If the user does not have at least those permissions, the CIFS-AFS server ! will deny the request.
  • !
  • If the file is located on a read-write volume and the application requests a ! shared lock, the CIFS-AFS server will request a read lock from the AFS file ! server.  If granted by the file server, then the CIFS-AFS server grants the lock request.  If the request is denied due to an access denied error and the user has the lookup and read privileges but not the lock privilege, then the CIFS-AFS server will grant the request even though the AFS file server said ‘no’.  If the user does not have at least those permissions, the CIFS-AFS server will deny the request.
  • !
  • If multiple processes on the same machine attempt to access the same file simultaneously, the CIFS-AFS server will locally manage the granted locks and all processes will share a single lock on the AFS file server.
  • !
  • If the CIFS-AFS server is unable to renew the AFS file server locks, then it will invalidate the associated file handles.  This is the same behavior that an application will experience if it was using a Windows --- 1586,1630 ---- inconvenience on end users. 

      !
    • If the file is located on a read-only volume and the application requests a ! shared lock, the CIFS-AFS server will grant the lock request without ! asking the AFS file server.
    • !
    • If ! the file is located on a read-only volume and the application opens the ! file with write access and requests an exclusive lock, the CIFS-AFS server will refuse the lock request and return a read only error.
    • !
    • If ! the file is located on a read-only volume and the application opens the ! file with only read access and requests an exclusive lock, the CIFS-AFS ! server will fulfill the lock request with a read lock.
    • !
    • If the file is located on a read-write volume and the application requests an ! exclusive lock, the CIFS-AFS server will request a write lock from the AFS ! file server.  If granted by the file server, then the CIFS-AFS server ! will grant the lock request.  If the request is denied due to an ! access denied error and the user has the lookup, read and lock privileges ! and the file was opened for read only access, then the CIFS-AFS server ! will request a read lock from the file server.  If the request is ! denied due to an access denied error and the user has the lookup and read ! privileges but not the lock privilege, then the CIFS-AFS server will grant ! the request even though the AFS file server said ‘no’.  If the user ! does not have at least those permissions, the CIFS-AFS server will deny ! the request.
    • !
    • If the file is located on a read-write volume and the application requests a ! shared lock, the CIFS-AFS server will request a read lock from the AFS ! file server.  If granted by the file server, then the CIFS-AFS server grants the lock request.  If the request is denied due to an access denied error and the user has the lookup and read privileges but not the lock privilege, then the CIFS-AFS server will grant the request even though the AFS file server said ‘no’.  If the user does not have at least those permissions, the CIFS-AFS server will deny the request.
    • !
    • If multiple processes on the same machine attempt to access the same file simultaneously, the CIFS-AFS server will locally manage the granted locks and all processes will share a single lock on the AFS file server.
    • !
    • If the CIFS-AFS server is unable to renew the AFS file server locks, then it will invalidate the associated file handles.  This is the same behavior that an application will experience if it was using a Windows *************** *** 1740,1753 **** Filename Character Sets

OpenAFS for Windows implements an SMB server which is used ! as a gateway to the AFS filesystem.  Because of limitations of the SMB implementation, ! Windows stores all files into AFS using OEM code pages such as CP437 (United ! States) or CP850 (Western Europe).  These code pages are incompatible with ! the ISO Latin-1 character set typically used as the default on UNIX systems in ! both the United States and Western Europe.  Filenames stored by OpenAFS for ! Windows are therefore unreadable on UNIX systems if they include any of the ! following characters:

--- 1757,1770 ---- Filename Character Sets

OpenAFS for Windows implements an SMB server which is used ! as a gateway to the AFS filesystem.  Because of limitations of the SMB ! implementation, Windows stores all files into AFS using OEM code pages such as ! CP437 (United States) or CP850 (Western Europe).  These code pages are ! incompatible with the ISO Latin-1 character set typically used as the default ! on UNIX systems in both the United States ! and Western Europe.  Filenames stored by ! OpenAFS for Windows are therefore unreadable on UNIX systems if they include ! any of the following characters:

*************** *** 1755,1824 **** height:399.5pt'>
!

     [Ç]  128  ! 08/00  200  80  C cedilla

!

     [ü]  129  ! 08/01  201  81  u diaeresis

!

     [é]  130  ! 08/02  202  82  e acute

!

     [â]  131  ! 08/03  203  83  a circumflex

!

     [ä]  132  ! 08/04  204  84  a diaeresis

!

     [à]  133  ! 08/05  205  85  a grave

!

     [å]  134  ! 08/06  206  86  a ring

!

     [ç]  135  ! 08/07  207  87  c cedilla

!

     [ê]  136  08/08  ! 210  88  e circumflex

!

     [ë]  137  ! 08/09  211  89  e diaeresis

!

     [è]  138  ! 08/10  212  8A  e grave

!

     [ï]  139  ! 08/11  213  8B  i diaeresis

!

     [î]  140  ! 08/12  214  8C  i circumflex

!

     [ì]  141  ! 08/13  215  8D  i grave

!

     [Ä]  142  08/14  ! 216  8E  A diaeresis

!

     [Å]  143  ! 08/15  217  8F  A ring

!

     [É]  144  ! 09/00  220  90  E acute

!

     [æ]  145  ! 09/01  221  91  ae diphthong

!

     [Æ]  146  ! 09/02  222  92  AE diphthong

!

     [ô]  147  ! 09/03  223  93  o circumflex

!

     [ö]  148  ! 09/04  224  94  o diaeresis

!

     [ò]  149  ! 09/05  225  95  o grave

!

     [û]  150  ! 09/06  226  96  u circumflex

!

     [ù]  151  ! 09/07  227  97  u grave

!

     [ÿ]  152  ! 09/08  230  98  y diaeresis

!

     [Ö]  153  ! 09/09  231  99  O diaeresis

!

     [Ü]  154  ! 09/10  232  9A  U diaeresis

!

     [ø]  155  ! 09/11  233  9B  o slash

     [£]  156  09/12  234  9C  Pound sterling sign

!

     [Ø]  157  ! 09/13  235  9D  O slash

!

     [×]  158  ! 09/14  236  9E  Multiplication sign

!

     [ƒ]  159  ! 09/15  237  9F  Florin sign

--- 1772,1846 ---- height:399.5pt'> !

     [Ç]  128  08/00  200  ! 80  C cedilla

!

     ! [ü]  129  08/01  201  81  u diaeresis

!

     ! [é]  130  08/02  202  82  e acute

!

     ! [â]  131  08/03  203  83  a circumflex

!

     ! [ä]  132  08/04  204  84  a diaeresis

!

     ! [à]  133  08/05  205  85  a grave

!

     ! [å]  134  08/06  206  86  a ring

!

     ! [ç]  135  08/07  207  87  c cedilla

!

     ! [ê]  136  08/08  210  88  e circumflex

!

     ! [ë]  137  08/09  211  89  e diaeresis

!

     ! [è]  138  08/10  212  8A  e grave

!

     ! [ï]  139  08/11  213  8B  i diaeresis

!

     ! [î]  140  08/12  214  8C  i circumflex

!

     ! [ì]  141  08/13  215  8D  i grave

!

     ! [Ä]  142  08/14  216  8E  A diaeresis

!

     ! [Å]  143  08/15  217  8F  A ring

!

     ! [É]  144  09/00  220  90  E acute

!

     ! [æ]  145  09/01  221  91  ae diphthong

!

     ! [Æ]  146  09/02  222  92  AE diphthong

!

     ! [ô]  147  09/03  223  93  o circumflex

!

     ! [ö]  148  09/04  224  94  o diaeresis

!

     ! [ò]  149  09/05  225  95  o grave

!

     ! [û]  150  09/06  226  96  u circumflex

!

     ! [ù]  151  ! 09/07  227  97  u grave

!

     ! [ÿ]  152  09/08  230  98  y diaeresis

!

     ! [Ö]  153  ! 09/09  231  99  O diaeresis

!

     ! [Ü]  154  09/10  232  9A  U diaeresis

!

     ! [ø]  155  09/11  233  9B  o slash

     [£]  156  09/12  234  9C  Pound sterling sign

!

     [Ø]  157  09/13  235  ! 9D  O slash

!

     ! [×]  158  09/14  236  9E  Multiplication sign

!

     ! [ƒ]  159  09/15  237  9F  Florin ! sign

*************** *** 1862,1869 ****

The performance of the AFS Client Service is significantly affected by the access times associated with the AFSCache paging ! file.   When given the choice, the AFSCache file should be placed on ! a fast disk, preferably NTFS, the file should not be compressed and should consist of as few fragments as possible.   Significant performance gains can be achieved by defragmenting the AFSCache file with Sysinternal's Contig utility while the AFS Client Service is stopped.

--- 1884,1891 ----

The performance of the AFS Client Service is significantly affected by the access times associated with the AFSCache paging ! file.   When given the choice, the AFSCache file should be placed on a ! fast disk, preferably NTFS, the file should not be compressed and should consist of as few fragments as possible.   Significant performance gains can be achieved by defragmenting the AFSCache file with Sysinternal's Contig utility while the AFS Client Service is stopped.

*************** *** 2007,2014 ****

   HKLM "SOFTWARE\Microsoft\RPC\ClientProtocols" "ncadg_ip_udp"

!

   HKLM "SOFTWARE\Microsoft\RPC\ClientProtocols" ! "ncacn_http"

   HKLM "SOFTWARE\Microsoft\RPC\ClientProtocols" "ncadg_ip_udp"

!

   HKLM ! "SOFTWARE\Microsoft\RPC\ClientProtocols" "ncacn_http"

!

3.39. Delayed Write Errors with Microsoft Office Applications

Microsoft Office makes heavy use of asynchronous --- 2058,2066 ---- file.   When cloning machines that have Windows AFS client installed, the AFSCache files should be deleted as part of the cloning process.

!

3.39. Delayed Write Errors with Microsoft Office Applications

Microsoft Office makes heavy use of asynchronous *************** *** 2082,2090 **** applications should be modified to use of \\AFS\<cellname>\<path> instead of drive letters.

!

3.41. 64-bit Microsoft Windows Installations

Although 64-bit Windows platforms support both 64-bit and 32-bit applications, the OpenAFS Service installed on the machine must be --- 2104,2112 ---- applications should be modified to use of \\AFS\<cellname>\<path> instead of drive letters.

!

3.41. 64-bit Microsoft Windows Installations

Although 64-bit Windows platforms support both 64-bit and 32-bit applications, the OpenAFS Service installed on the machine must be *************** *** 2138,2460 **** Start and Stop Service features of the AFS System Tray tool and the AFS Control Panel will not work unless they are “Run as Administrator”.

!

! The help files provided with OpenAFS are in .HLP format. ! Windows Vista does not include a help engine for this format. 4. How to Debug Problems with OpenAFS for Windows:

! !

OpenAFS for Windows provides a wide range of tools to assist ! the developers in debugging problems.  The techniques available are varied ! because of the wide range of issues that have been discovered over the ! years.  When filing bug reports to the ! OpenAFS developers, please collect as much information as possible and forward ! it as part of the bug

! !

4.1. ! pioctl debugging (IoctlDebug ! registry key)

! !

pioctl (path-based ioctl) calls are used by various tools to ! communicate with the AFS Client Service.  Some of the operations performed ! include:

! !

·       setting/querying ! tokens  (tokens.exe, aklog.exe, afscreds.exe)

! !

·       setting/querying ! ACLs

! !

·       setting/querying ! cache parameters

! !

·       flushing ! files or volumes

! !

·       setting/querying ! server preferences

! !

·       querying ! path location

! !

·       checking ! the status of servers and volumes

! !

·       setting/querying ! the sysname list

! !

pioctl calls are implemented by writing to a special UNC ! path that is processed by the AFS Client Service.   If there is a ! failure to communicate with the AFS Client Service via SMB/CIFS, it will be ! impossible to perform any of the above operations.  

! !

To assist in debugging these problems, the registry value:

! !

  [HKLM\SOFTWARE\OpenAFS\Client]

! !

  REG_DWORD:  IoctlDebug   = 0x01

! !

should be set.  Then any of the commands that perform ! pioctl calls should be executed from the command prompt.  With this key ! set the pioctl library will generate debugging output to stderr.  The ! output will contain the Win32 API calls executed along with their most ! important parameters and their return code.   The MSDN Library and ! the Microsoft KnowledgeBase can be used as a reference to help you determine ! the configuration probem with your system.

! !

4.2. ! afsd_service initialization log (%WinDir%\TEMP\afsd_init.log)

! !

Every time the AFS Client Service starts it appends data ! about its progress and configuration to a file.  This file provides ! information crucial to determining why the service cannot start when there are ! problems.  When the process terminates due to a panic condition it will ! write to this file the source code file and line number of the error.  In ! many cases the panic condition is due to a misconfiguration of the ! machine.  In other cases it might be due to a programming error in the ! software.  A quick review of the location in the source code will quickly ! reveal the reason for the termination.

! !

The MaxLogSize ! registry value determines the maximum size of the %WINDIR%\TEMP\afsd_init.log ! file.  If the file is larger than this value when OpenAFS Client Service ! starts, the file will be reset to 0 bytes.  If value is set to 0, the file ! will be allowed to grow indefinitely.

! !

4.3. ! afsd_service debug logs (fs trace {-on, -off, -dump} ! ->%WinDir%\TEMP\afsd.log)

! !

When attempting to debug the behavior of the SMB/CIFS Server ! and the Cache Manager it is often useful to examine a log of the operations ! being performed.  While running the AFS Client Service keeps an in memory ! log of many of its actions.   The default number of actions preserved ! at any one time is 5000.  This can be adjusted with the registry value:

! !

  ! [HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters]

! !

  REG_DWORD  TraceBufferSize

! !

A restart of the service is necessary when adjusting this ! value.   Execute "fs trace -on" to clear to the log and ! "fs trace -dump" to output the contents of the log to the file.

! !

4.4. ! Using SysInternal’s DbgView and FileMon Tools

! !

An alternatve option to the use of "fs trace ! -dump" to capture internal OpenAFS Client Service events is to use a tool ! such as Sysinternal's DbgView to capture real-time debugging output.  When ! the OpenAFS Client Service starts and Bit 2 of the TraceOption value in the registry is set, all ! trace log events are output using the Windows Debug Monitor interface ! (OutputDebugString). 

! !

  ! [HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters]

! !

REG_DWORD   ! TraceOption = 0x04

! !

Use “fs trace –on” and “fs trace –off” to toggle the generation ! of log messages.

! !

Sysinternal’s ! FileMon utility can be use to monitor the file operations requested by ! applications and their success or failure.   Use the Volumes menu to ! restrict FileMon monitor to Network volumes only in order to reduce the ! output to just the CIFS requests.  Turn on the Advanced Output ! option in order to log with finer granularity.

! !

Turn on the Clock Time and Show Milliseconds ! options in both tools to make it easier to synchronize the application requests ! and the resulting OpenAFS Client Service operations.   The captured ! data can be stored to files for inclusion in bug reports.

! !

4.5. Microsoft MiniDumps
! (fs minidump -> %WinDir%\TEMP\afsd.dmp)

! !

If the AFS Client Service become unresponsive to any form of ! communication there may be a serious error that can only be debugged by someone ! with access to the source code and a debugger.   The "fs ! minidump" command can be used to force the generation of a MiniDump file ! containing the state of all of the threads in the AFS Client Service process.

! !

4.6. ! Single Sign-on (Integrated Logon) debugging

! !

If you are having trouble with the Integrated Logon ! operations it is often useful to be able to obtain a log of what it is ! attempting to do.   Setting Bit 0 of the TraceOption registry value:

! !

  ! [HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters]

! !

  REG_DWORD   TraceOption = 0x01

! !

will instruct the Integrated Logon Network Provider and ! Event Handlers to log information to the Windows Event Log: Application under ! the name “AFS Logon".

! !

4.7. ! RX (AFS RPC) debugging (rxdebug)

! !

The rxdebug.exe tool can be used to query a variety of ! information about the AFS services installed on a given machine.  The port ! for the AFS Cache Manager is 7001. 

! !

Usage: rxdebug -servers <server machine> [-port ! <IP port>] [-nodally]

! !

   ! [-allconnections] [-rxstats] [-onlyserver] [-onlyclient]

! !

   [-onlyport ! <show only <port>>]

! !

   [-onlyhost ! <show only <host>>]

! !

   [-onlyauth ! <show only <auth level>>] [-version]

! !

   [-noconns] ! [-peers] [-help]

! !

Where: ! -nodally         don't show dallying ! conns

! !

       ! -allconnections  don't filter out uninteresting connections

! !

       ! -rxstats         show Rx statistics

! !

       ! -onlyserver      only show server conns

! !

       ! -onlyclient      only show client conns

! !

       ! -version         show AFS version id

! !

       ! -noconns         show no connections

! !

       ! -peers           show peers

! !

4.8. ! Cache Manager debugging (cmdebug)

! !

The cmdebug.exe tool can be used to query the state of the ! AFS Cache Manager on a given machine.

! !

Usage: cmdebug -servers <server machine> [-port ! <IP port>] [-long]

! !

   [-refcounts] ! [-callbacks] [-addrs] [-cache] [-help]

! !

Where: -long       ! print all info

! !

       -refcounts  ! print only cache entries with positive reference counts

! !

       -callbacks  ! print only cache entries with callbacks

! !

       ! -addrs      print only host interfaces

! !

       ! -cache      print only cache configuration

! !

4.9. ! Persistent Cache consistency check

! !

The persistent cache is stored in a Hidden System file at ! %WinDir%\TEMP\AFSCache.  If there is a problem with the persistent cache ! that prevent the AFS Client Service from being able to start a validation check ! on the file can be performed.

! !

  afsd_service.exe --validate-cache ! <cache-path>

! !