*unixTimep = dosTime + smb_localZero;
}
+void smb_MarkAllVCsDead(smb_vc_t * exclude)
+{
+ smb_vc_t *vcp;
+ smb_vc_t **vcp_to_cleanup = NULL;
+ int n_to_cleanup = 0;
+ int i;
+
+ osi_Log1(smb_logp, "Marking all VCs as dead excluding %p", exclude);
+
+ lock_ObtainWrite(&smb_globalLock); /* for dead_sessions[] */
+ lock_ObtainWrite(&smb_rctLock);
+ for (vcp = smb_allVCsp; vcp; vcp = vcp->nextp) {
+
+ if (vcp->magic != SMB_VC_MAGIC)
+ osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp",
+ __FILE__, __LINE__);
+
+ if (vcp == exclude)
+ continue;
+
+ lock_ObtainMutex(&vcp->mx);
+ if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
+ vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
+ lock_ReleaseMutex(&vcp->mx);
+ dead_sessions[vcp->session] = TRUE;
+ } else {
+ lock_ReleaseMutex(&vcp->mx);
+ }
+ n_to_cleanup ++;
+ }
+
+ vcp_to_cleanup = malloc(sizeof(vcp_to_cleanup[0]) * n_to_cleanup);
+ i = 0;
+ for (vcp = smb_allVCsp; vcp; vcp = vcp->nextp) {
+ if (vcp == exclude)
+ continue;
+
+ vcp_to_cleanup[i++] = vcp;
+ smb_HoldVCNoLock(vcp);
+ }
+
+ osi_assert(i == n_to_cleanup);
+
+ lock_ReleaseWrite(&smb_rctLock);
+ lock_ReleaseWrite(&smb_globalLock);
+
+ for (i=0; i < n_to_cleanup; i++) {
+ smb_CleanupDeadVC(vcp_to_cleanup[i]);
+ smb_ReleaseVC(vcp_to_cleanup[i]);
+ vcp_to_cleanup[i] = 0;
+ }
+
+ free(vcp_to_cleanup);
+}
+
#ifdef DEBUG_SMB_REFCOUNT
smb_vc_t *smb_FindVCDbg(unsigned short lsn, int flags, int lana, char *file, long line)
#else
osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp",
__FILE__, __LINE__);
+ lock_ObtainMutex(&vcp->mx);
if (lsn == vcp->lsn && lana == vcp->lana &&
!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
+ lock_ReleaseMutex(&vcp->mx);
smb_HoldVCNoLock(vcp);
break;
}
+ lock_ReleaseMutex(&vcp->mx);
}
if (!vcp && (flags & SMB_FLAG_CREATE)) {
vcp = malloc(sizeof(*vcp));
free(tidp);
}
}
+ if (vcp)
+ smb_ReleaseVCNoLock(vcp);
if (!locked)
lock_ReleaseWrite(&smb_rctLock);
if (userp)
cm_ReleaseUser(userp);
- if (vcp)
- smb_ReleaseVCNoLock(vcp);
}
smb_user_t *smb_FindUID(smb_vc_t *vcp, unsigned short uid, int flags)
return fidp;
}
+
+/* Must not be called with scp->rw held because smb_ReleaseFID might be called */
#ifdef DEBUG_SMB_REFCOUNT
smb_fid_t *smb_FindFIDByScacheDbg(smb_vc_t *vcp, cm_scache_t * scp, char *file, long line)
#else
smb_fid_t *smb_FindFIDByScache(smb_vc_t *vcp, cm_scache_t * scp)
#endif
{
- smb_fid_t *fidp = NULL;
- int newFid = 0;
+ smb_fid_t *fidp = NULL, *nextp = NULL;
if (!scp)
return NULL;
+ /*
+ * If the fidp->scp changes out from under us then
+ * we must not grab a refCount. It means the *fidp
+ * was processed by smb_CloseFID() and the *fidp is
+ * no longer valid for use.
+ */
lock_ObtainWrite(&smb_rctLock);
- for(fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q)) {
+ for(fidp = vcp->fidsp, (fidp ? fidp->refCount++ : 0); fidp; fidp = nextp, nextp = NULL) {
+ nextp = (smb_fid_t *) osi_QNext(&fidp->q);
+ if (nextp)
+ nextp->refCount++;
+
if (scp == fidp->scp) {
+ lock_ReleaseWrite(&smb_rctLock);
lock_ObtainMutex(&fidp->mx);
+ lock_ObtainWrite(&smb_rctLock);
if (scp == fidp->scp) {
- fidp->refCount++;
lock_ReleaseMutex(&fidp->mx);
break;
}
lock_ReleaseMutex(&fidp->mx);
}
+
+ if (fidp->refCount > 1) {
+ fidp->refCount--;
+ } else {
+ lock_ReleaseWrite(&smb_rctLock);
+ smb_ReleaseFID(fidp);
+ lock_ObtainWrite(&smb_rctLock);
+ }
}
+
+ if (nextp) {
+ if (nextp->refCount > 1) {
+ nextp->refCount--;
+ } else {
+ lock_ReleaseWrite(&smb_rctLock);
+ smb_ReleaseFID(nextp);
+ lock_ObtainWrite(&smb_rctLock);
+ }
+ }
+
#ifdef DEBUG_SMB_REFCOUNT
if (fidp) {
afsi_log("%s:%d smb_FindFIDByScache fidp 0x%p ref %d", file, line, fidp, fidp->refCount);
}
#endif
lock_ReleaseWrite(&smb_rctLock);
- return fidp;
+ return (fidp);
}
#ifdef DEBUG_SMB_REFCOUNT
}
-/* smb_ReleaseFID cannot be called while an cm_scache_t mutex lock is held */
-/* the sm_fid_t->mx and smb_rctLock must not be held */
+/* smb_ReleaseFID cannot be called while a cm_scache_t rwlock is held */
+/* the smb_fid_t->mx and smb_rctLock must not be held */
#ifdef DEBUG_SMB_REFCOUNT
void smb_ReleaseFIDDbg(smb_fid_t *fidp, char *file, long line)
#else
}
/* Get the full name for this cell */
cellname = cm_ClientStringToFsStringAlloc(p, -1, NULL);
- code = cm_SearchCellFile(cellname, ftemp, 0, 0);
+ code = cm_SearchCellRegistry(1, cellname, ftemp, 0, 0, 0);
+ if (code && code != CM_ERROR_FORCE_DNS_LOOKUP)
+ code = cm_SearchCellFile(cellname, ftemp, 0, 0);
#ifdef AFS_AFSDB_ENV
if (code && cm_dnsEnabled) {
int ttl;
#endif /* COMMENT */
}
else if (code == CM_ERROR_BADSHARENAME) {
- NTStatus = 0xC00000CCL; /* Bad network name */
+ NTStatus = 0xC00000BEL; /* Bad network path (server valid, share bad) */
}
else if (code == CM_ERROR_NOIPC) {
#ifdef COMMENT
NTStatus = 0xC000022DL; /* Retry */
}
else if (code == CM_ERROR_ALLOFFLINE || code == CM_ERROR_ALLDOWN) {
- NTStatus = 0xC00000BEL; /* Bad Network Path */
+ NTStatus = 0xC000003AL; /* Path not found */
}
else if (code >= ERROR_TABLE_BASE_RXK && code < ERROR_TABLE_BASE_RXK + 256) {
NTStatus = 0xC0000322L; /* No Kerberos key */
goto send1;
lock_ObtainMutex(&fidp->mx);
- if (fidp->scp && (fidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
+ if (!fidp->scp) {
+ lock_ReleaseMutex(&fidp->mx);
+ smb_ReleaseFID(fidp);
+ return CM_ERROR_BADFD;
+ }
+
+ if (fidp->scp->flags & CM_SCACHEFLAG_DELETED) {
lock_ReleaseMutex(&fidp->mx);
smb_CloseFID(vcp, fidp, NULL, 0);
code = CM_ERROR_NOSUCHFILE;
if (wl->state == SMB_WAITINGLOCKSTATE_DONE)
cm_Unlock(scp, wlRequest->lockType, wl->LOffset,
- wl->LLength, wl->key, NULL, &req);
+ wl->LLength, wl->key, 0, NULL, &req);
osi_QRemove((osi_queue_t **) &wlRequest->locks, &wl->q);
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
bufferp = NULL;
}
lock_ReleaseWrite(&scp->rw);
- code = buf_Get(scp, &thyper, &bufferp);
+ code = buf_Get(scp, &thyper, &req, &bufferp);
lock_ObtainMutex(&dsp->mx);
/* now, if we're doing a star match, do bulk fetching of all of
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
} else
#endif /* DFS_SUPPORT */
if (dscp->fileType == CM_SCACHETYPE_MOUNTPOINT && !dscp->mountRootFid.volume)
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
userp = smb_GetUserFromVCP(vcp, inp);
lock_ObtainMutex(&fidp->mx);
- if (fidp->scp && (fidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
- lock_ReleaseMutex(&fidp->mx);
+ if (!fidp->scp || (fidp->flags & SMB_FID_IOCTL)) {
cm_ReleaseUser(userp);
- smb_CloseFID(vcp, fidp, NULL, 0);
+ lock_ReleaseMutex(&fidp->mx);
smb_ReleaseFID(fidp);
- return CM_ERROR_NOSUCHFILE;
+ return CM_ERROR_BADFD;
}
- if (fidp->flags & SMB_FID_IOCTL) {
- cm_ReleaseUser(userp);
+ if (fidp->scp->flags & CM_SCACHEFLAG_DELETED) {
lock_ReleaseMutex(&fidp->mx);
+ cm_ReleaseUser(userp);
+ smb_CloseFID(vcp, fidp, NULL, 0);
smb_ReleaseFID(fidp);
- return CM_ERROR_BADFD;
+ return CM_ERROR_NOSUCHFILE;
}
- if (fidp->scp && (fidp->flags & SMB_FID_OPENWRITE) && smb_AsyncStore != 2) {
+ if ((fidp->flags & SMB_FID_OPENWRITE) && smb_AsyncStore != 2) {
cm_scache_t * scp = fidp->scp;
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
}
lock_ReleaseWrite(&scp->rw);
- code = buf_Get(scp, &thyper, &bufferp);
+ code = buf_Get(scp, &thyper, &req, &bufferp);
lock_ObtainWrite(&scp->rw);
if (code) goto done;
}
lock_ReleaseWrite(&scp->rw);
- code = buf_Get(scp, &thyper, &bufferp);
+ code = buf_Get(scp, &thyper, &req, &bufferp);
lock_ObtainMutex(&bufferp->mx);
lock_ObtainWrite(&scp->rw);
return CM_ERROR_BADFD;
}
- lock_ObtainMutex(&fidp->mx);
- if (fidp->scp && (fidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
- lock_ReleaseMutex(&fidp->mx);
- smb_CloseFID(vcp, fidp, NULL, 0);
- smb_ReleaseFID(fidp);
- return CM_ERROR_NOSUCHFILE;
- }
-
+ lock_ObtainMutex(&fidp->mx);
if (fidp->flags & SMB_FID_IOCTL) {
lock_ReleaseMutex(&fidp->mx);
code = smb_IoctlWrite(fidp, vcp, inp, outp);
return CM_ERROR_BADFD;
}
+ if (fidp->scp->flags & CM_SCACHEFLAG_DELETED) {
+ lock_ReleaseMutex(&fidp->mx);
+ smb_CloseFID(vcp, fidp, NULL, 0);
+ smb_ReleaseFID(fidp);
+ return CM_ERROR_NOSUCHFILE;
+ }
+
scp = fidp->scp;
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
fidp = smb_FindFID(vcp, fd, 0);
lock_ObtainMutex(&fidp->mx);
- if (fidp->scp && (fidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
+ if (!fidp->scp) {
+ lock_ReleaseMutex(&fidp->mx);
+ smb_ReleaseFID(fidp);
+ return;
+ }
+
+ if (fidp->scp->flags & CM_SCACHEFLAG_DELETED) {
lock_ReleaseMutex(&fidp->mx);
smb_CloseFID(vcp, fidp, NULL, 0);
smb_ReleaseFID(fidp);
return CM_ERROR_BADFD;
lock_ObtainMutex(&fidp->mx);
- if (fidp->scp && (fidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
+ if (!fidp->scp) {
lock_ReleaseMutex(&fidp->mx);
- smb_CloseFID(vcp, fidp, NULL, 0);
smb_ReleaseFID(fidp);
- return CM_ERROR_NOSUCHFILE;
+ return CM_ERROR_BADFD;
}
- if (!fidp->scp) {
+ if (fidp->scp->flags & CM_SCACHEFLAG_DELETED) {
lock_ReleaseMutex(&fidp->mx);
+ smb_CloseFID(vcp, fidp, NULL, 0);
smb_ReleaseFID(fidp);
- return CM_ERROR_BADFDOP;
+ return CM_ERROR_NOSUCHFILE;
}
+
scp = fidp->scp;
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
if (!fidp)
return CM_ERROR_BADFD;
- lock_ObtainMutex(&fidp->mx);
- if (fidp->scp && (fidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
- lock_ReleaseMutex(&fidp->mx);
- smb_CloseFID(vcp, fidp, NULL, 0);
- smb_ReleaseFID(fidp);
- return CM_ERROR_NOSUCHFILE;
- }
-
+ lock_ObtainMutex(&fidp->mx);
if (fidp->flags & SMB_FID_IOCTL) {
lock_ReleaseMutex(&fidp->mx);
code = smb_IoctlRead(fidp, vcp, inp, outp);
if (!fidp->scp) {
lock_ReleaseMutex(&fidp->mx);
smb_ReleaseFID(fidp);
- return CM_ERROR_BADFDOP;
+ return CM_ERROR_BADFD;
+ }
+
+ if (fidp->scp->flags & CM_SCACHEFLAG_DELETED) {
+ lock_ReleaseMutex(&fidp->mx);
+ smb_CloseFID(vcp, fidp, NULL, 0);
+ smb_ReleaseFID(fidp);
+ return CM_ERROR_NOSUCHFILE;
}
+
scp = fidp->scp;
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
return CM_ERROR_BADFD;
lock_ObtainMutex(&fidp->mx);
- if (fidp->scp && (fidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
- lock_ReleaseMutex(&fidp->mx);
- smb_CloseFID(vcp, fidp, NULL, 0);
- smb_ReleaseFID(fidp);
- return CM_ERROR_NOSUCHFILE;
- }
-
- if (fidp->flags & SMB_FID_IOCTL) {
+ if (!fidp->scp || (fidp->flags & SMB_FID_IOCTL)) {
lock_ReleaseMutex(&fidp->mx);
smb_ReleaseFID(fidp);
return CM_ERROR_BADFD;
}
- if (!fidp->scp) {
+ if (fidp->scp->flags & CM_SCACHEFLAG_DELETED) {
lock_ReleaseMutex(&fidp->mx);
+ smb_CloseFID(vcp, fidp, NULL, 0);
smb_ReleaseFID(fidp);
- return CM_ERROR_BADFDOP;
+ return CM_ERROR_NOSUCHFILE;
}
lock_ReleaseMutex(&fidp->mx);
if (dp->procp) {
/* we have a recognized operation */
char * opName = myCrt_Dispatch(inp->inCom);
+ smb_t *smbp;
+
+ smbp = (smb_t *) inp;
- if (inp->inCom == 0x1d)
+ osi_Log5(smb_logp,"Dispatch %s mid 0x%x vcp 0x%p lana %d lsn %d",
+ opName, smbp->mid, vcp,vcp->lana,vcp->lsn);
+ if (inp->inCom == 0x1d) {
/* Raw Write */
code = smb_ReceiveCoreWriteRaw (vcp, inp, outp, rwcp);
- else {
- osi_Log4(smb_logp,"Dispatch %s vcp 0x%p lana %d lsn %d",
- opName,vcp,vcp->lana,vcp->lsn);
+ } else {
code = (*(dp->procp)) (vcp, inp, outp);
- osi_Log4(smb_logp,"Dispatch return code 0x%x vcp 0x%p lana %d lsn %d",
- code,vcp,vcp->lana,vcp->lsn);
-#ifdef LOG_PACKET
- if ( code == CM_ERROR_BADSMB ||
- code == CM_ERROR_BADOP )
- smb_LogPacket(inp);
-#endif /* LOG_PACKET */
}
+ osi_Log5(smb_logp,"Dispatch return code 0x%x mid 0x%x vcp 0x%p lana %d lsn %d",
+ code, smbp->mid, vcp,vcp->lana,vcp->lsn);
newTime = GetTickCount();
- osi_Log2(smb_logp, "Dispatch %s duration %d ms", opName, newTime - oldTime);
+ osi_Log3(smb_logp, "Dispatch %s mid 0x%x duration %d ms",
+ opName, smbp->mid, newTime - oldTime);
+
+#ifdef LOG_PACKET
+ if ( code == CM_ERROR_BADSMB ||
+ code == CM_ERROR_BADOP )
+ smb_LogPacket(inp);
+#endif /* LOG_PACKET */
/* ReceiveV3Tran2A handles its own logging */
if (inp->inCom != 0x32 && newTime - oldTime > 45000) {
cm_fid_t afid = {0,0,0,0,0};
uidp = smb_FindUID(vcp, smbp->uid, 0);
- smb_LookupTIDPath(vcp,((smb_t *)inp)->tid, &treepath);
+ smb_LookupTIDPath(vcp, smbp->tid, &treepath);
fidp = smb_FindFID(vcp, inp->fid, 0);
if (fidp) {
pathname = inp->stringsp->wdata;
}
- afsi_log("Request %s duration %d ms user %S tid \"%S\" path? \"%S\" afid (%d.%d.%d.%d)",
- opName, newTime - oldTime,
- uidp ? uidp->unp->name : NULL,
+ afsi_log("Request %s duration %d ms user 0x%x \"%S\" pid 0x%x mid 0x%x tid 0x%x \"%S\" path? \"%S\" afid (%d.%d.%d.%d)",
+ opName, newTime - oldTime,
+ smbp->uid, uidp ? uidp->unp->name : NULL,
+ smbp->pid, smbp->mid, smbp->tid,
treepath,
pathname,
afid.cell, afid.volume, afid.vnode, afid.unique);
}
static void
+configureBackConnectionHostNames(void)
+{
+ /* On Windows XP SP2, Windows 2003 SP1, and all future Windows operating systems
+ * there is a restriction on the use of SMB authentication on loopback connections.
+ * There are two work arounds available:
+ *
+ * (1) We can disable the check for matching host names. This does not
+ * require a reboot:
+ * [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa]
+ * "DisableLoopbackCheck"=dword:00000001
+ *
+ * (2) We can add the AFS SMB/CIFS service name to an approved list. This
+ * does require a reboot:
+ * [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0]
+ * "BackConnectionHostNames"=multi-sz
+ *
+ * The algorithm will be:
+ * (1) Check to see if cm_NetbiosName exists in the BackConnectionHostNames list
+ * (2a) If not, add it to the list. (This will not take effect until the next reboot.)
+ * (2b1) and check to see if DisableLoopbackCheck is set.
+ * (2b2) If not set, set the DisableLoopbackCheck value to 0x1
+ * (2b3) and create HKLM\SOFTWARE\OpenAFS\Client UnsetDisableLoopbackCheck
+ * (2c) else If cm_NetbiosName exists in the BackConnectionHostNames list,
+ * check for the UnsetDisableLoopbackCheck value.
+ * If set, set the DisableLoopbackCheck flag to 0x0
+ * and delete the UnsetDisableLoopbackCheck value
+ *
+ * Starting in Longhorn Beta 1, an entry in the BackConnectionHostNames value will
+ * force Windows to use the loopback authentication mechanism for the specified
+ * services.
+ *
+ * Do not permit the "DisableLoopbackCheck" value to be removed within the same
+ * service session that set it.
+ */
+ HKEY hkLsa;
+ HKEY hkMSV10;
+ HKEY hkClient;
+ DWORD dwType;
+ DWORD dwSize, dwAllocSize;
+ DWORD dwValue;
+ PBYTE pHostNames = NULL, pName = NULL;
+ BOOL bNameFound = FALSE;
+ static BOOL bLoopbackCheckDisabled = FALSE;
+
+ /* BackConnectionHostNames and DisableLoopbackCheck */
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0",
+ 0,
+ KEY_READ|KEY_WRITE,
+ &hkMSV10) == ERROR_SUCCESS )
+ {
+ if ((RegQueryValueEx( hkMSV10, "BackConnectionHostNames", 0,
+ &dwType, NULL, &dwAllocSize) == ERROR_SUCCESS) &&
+ (dwType == REG_MULTI_SZ))
+ {
+ dwAllocSize += 1 /* in case the source string is not nul terminated */
+ + (DWORD)strlen(cm_NetbiosName) + 2;
+ pHostNames = malloc(dwAllocSize);
+ dwSize = dwAllocSize;
+ if (RegQueryValueEx( hkMSV10, "BackConnectionHostNames", 0, &dwType,
+ pHostNames, &dwSize) == ERROR_SUCCESS)
+ {
+ for (pName = pHostNames;
+ (pName - pHostNames < (int) dwSize) && *pName ;
+ pName += strlen(pName) + 1)
+ {
+ if ( !stricmp(pName, cm_NetbiosName) ) {
+ bNameFound = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !bNameFound ) {
+ size_t size = strlen(cm_NetbiosName) + 2;
+ if ( !pHostNames ) {
+ pHostNames = malloc(size);
+ pName = pHostNames;
+ }
+ StringCbCopyA(pName, size, cm_NetbiosName);
+ pName += size - 1;
+ *pName = '\0'; /* add a second nul terminator */
+
+ dwType = REG_MULTI_SZ;
+ dwSize = (DWORD)(pName - pHostNames + 1);
+ RegSetValueEx( hkMSV10, "BackConnectionHostNames", 0, dwType, pHostNames, dwSize);
+
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Control\\Lsa",
+ 0,
+ KEY_READ|KEY_WRITE,
+ &hkLsa) == ERROR_SUCCESS )
+ {
+ dwSize = sizeof(DWORD);
+ if ( RegQueryValueEx( hkLsa, "DisableLoopbackCheck", 0, &dwType, (LPBYTE)&dwValue, &dwSize) != ERROR_SUCCESS ||
+ dwValue == 0 ) {
+ dwType = REG_DWORD;
+ dwSize = sizeof(DWORD);
+ dwValue = 1;
+ RegSetValueEx( hkLsa, "DisableLoopbackCheck", 0, dwType, (LPBYTE)&dwValue, dwSize);
+
+ if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ AFSREG_CLT_OPENAFS_SUBKEY,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ|KEY_WRITE,
+ NULL,
+ &hkClient,
+ NULL) == ERROR_SUCCESS) {
+
+ dwType = REG_DWORD;
+ dwSize = sizeof(DWORD);
+ dwValue = 1;
+ RegSetValueEx( hkClient, "RemoveDisableLoopbackCheck", 0, dwType, (LPBYTE)&dwValue, dwSize);
+ bLoopbackCheckDisabled = TRUE;
+ RegCloseKey(hkClient);
+ }
+ RegCloseKey(hkLsa);
+ }
+ }
+ } else if (!bLoopbackCheckDisabled) {
+ if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ AFSREG_CLT_OPENAFS_SUBKEY,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ|KEY_WRITE,
+ NULL,
+ &hkClient,
+ NULL) == ERROR_SUCCESS) {
+
+ dwSize = sizeof(DWORD);
+ if ( RegQueryValueEx( hkClient, "RemoveDisableLoopbackCheck", 0, &dwType, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS &&
+ dwValue == 1 ) {
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Control\\Lsa",
+ 0,
+ KEY_READ|KEY_WRITE,
+ &hkLsa) == ERROR_SUCCESS )
+ {
+ RegDeleteValue(hkLsa, "DisableLoopbackCheck");
+ RegCloseKey(hkLsa);
+ }
+ }
+ RegDeleteValue(hkClient, "RemoveDisableLoopbackCheck");
+ RegCloseKey(hkClient);
+ }
+ }
+
+ if (pHostNames) {
+ free(pHostNames);
+ pHostNames = NULL;
+ }
+
+ RegCloseKey(hkMSV10);
+ }
+}
+
+
+static void
+configureExtendedSMBSessionTimeouts(void)
+{
+ /*
+ * In a Hot Fix to Windows 2003 SP2, the smb redirector was given the following
+ * new functionality:
+ *
+ * [HKLM\SYSTEM\CurrentControlSet\Services\LanManWorkstation\Parameters]
+ * "ReconnectableServers" REG_MULTI_SZ
+ * "ExtendedSessTimeout" REG_DWORD (seconds)
+ * "ServersWithExtendedSessTimeout" REG_MULTI_SZ
+ *
+ * These values can be used to prevent the smb redirector from timing out
+ * smb connection to the afs smb server prematurely.
+ */
+ HKEY hkLanMan;
+ DWORD dwType;
+ DWORD dwSize, dwAllocSize;
+ DWORD dwValue;
+ PBYTE pHostNames = NULL, pName = NULL;
+ BOOL bNameFound = FALSE;
+
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Services\\LanManWorkstation\\Parameters",
+ 0,
+ KEY_READ|KEY_WRITE,
+ &hkLanMan) == ERROR_SUCCESS )
+ {
+ if ((RegQueryValueEx( hkLanMan, "ReconnectableServers", 0,
+ &dwType, NULL, &dwAllocSize) == ERROR_SUCCESS) &&
+ (dwType == REG_MULTI_SZ))
+ {
+ dwAllocSize += 1 /* in case the source string is not nul terminated */
+ + (DWORD)strlen(cm_NetbiosName) + 2;
+ pHostNames = malloc(dwAllocSize);
+ dwSize = dwAllocSize;
+ if (RegQueryValueEx( hkLanMan, "ReconnectableServers", 0, &dwType,
+ pHostNames, &dwSize) == ERROR_SUCCESS)
+ {
+ for (pName = pHostNames;
+ (pName - pHostNames < (int) dwSize) && *pName ;
+ pName += strlen(pName) + 1)
+ {
+ if ( !stricmp(pName, cm_NetbiosName) ) {
+ bNameFound = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !bNameFound ) {
+ size_t size = strlen(cm_NetbiosName) + 2;
+ if ( !pHostNames ) {
+ pHostNames = malloc(size);
+ pName = pHostNames;
+ }
+ StringCbCopyA(pName, size, cm_NetbiosName);
+ pName += size - 1;
+ *pName = '\0'; /* add a second nul terminator */
+
+ dwType = REG_MULTI_SZ;
+ dwSize = (DWORD)(pName - pHostNames + 1);
+ RegSetValueEx( hkLanMan, "ReconnectableServers", 0, dwType, pHostNames, dwSize);
+ }
+
+ if (pHostNames) {
+ free(pHostNames);
+ pHostNames = NULL;
+ }
+
+ if ((RegQueryValueEx( hkLanMan, "ServersWithExtendedSessTimeout", 0,
+ &dwType, NULL, &dwAllocSize) == ERROR_SUCCESS) &&
+ (dwType == REG_MULTI_SZ))
+ {
+ dwAllocSize += 1 /* in case the source string is not nul terminated */
+ + (DWORD)strlen(cm_NetbiosName) + 2;
+ pHostNames = malloc(dwAllocSize);
+ dwSize = dwAllocSize;
+ if (RegQueryValueEx( hkLanMan, "ServersWithExtendedSessTimeout", 0, &dwType,
+ pHostNames, &dwSize) == ERROR_SUCCESS)
+ {
+ for (pName = pHostNames;
+ (pName - pHostNames < (int) dwSize) && *pName ;
+ pName += strlen(pName) + 1)
+ {
+ if ( !stricmp(pName, cm_NetbiosName) ) {
+ bNameFound = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !bNameFound ) {
+ size_t size = strlen(cm_NetbiosName) + 2;
+ if ( !pHostNames ) {
+ pHostNames = malloc(size);
+ pName = pHostNames;
+ }
+ StringCbCopyA(pName, size, cm_NetbiosName);
+ pName += size - 1;
+ *pName = '\0'; /* add a second nul terminator */
+
+ dwType = REG_MULTI_SZ;
+ dwSize = (DWORD)(pName - pHostNames + 1);
+ RegSetValueEx( hkLanMan, "ServersWithExtendedSessTimeout", 0, dwType, pHostNames, dwSize);
+ }
+
+ if (pHostNames) {
+ free(pHostNames);
+ pHostNames = NULL;
+ }
+
+ if ((RegQueryValueEx( hkLanMan, "ExtendedSessTimeout", 0,
+ &dwType, (LPBYTE)&dwValue, &dwAllocSize) != ERROR_SUCCESS) ||
+ (dwType != REG_DWORD))
+ {
+ dwType = REG_DWORD;
+ dwSize = sizeof(dwValue);
+ dwValue = 600; /* 10 minutes */
+ RegSetValueEx( hkLanMan, "ExtendedSessTimeout", 0, dwType, (const BYTE *)&dwValue, dwSize);
+ }
+ RegCloseKey(hkLanMan);
+ }
+}
+
+static void
smb_LanAdapterChangeThread(void *param)
{
/*
}
afsi_log("smb_StartListeners");
+ /* Ensure the AFS Netbios Name is registered to allow loopback access */
+ configureBackConnectionHostNames();
+
+ /* Configure Extended SMB Session Timeouts */
+ configureExtendedSMBSessionTimeouts();
+
smb_ListenerState = SMB_LISTENER_STARTED;
cm_VolStatus_Network_Started(cm_NetbiosName
#ifdef _WIN64
);
if (nts != STATUS_SUCCESS && ntsEx != STATUS_SUCCESS) {
- char message[AFSPATHMAX];
- sprintf(message,"MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x",
- nts, ntsEx);
- OutputDebugString(message);
- afsi_log(message);
+ osi_Log2(smb_logp, "MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x",
+ nts, ntsEx);
+
+ afsi_log("MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x", nts, ntsEx);
} else {
- OutputDebugString("MsV1_0SetProcessOption success");
+ osi_Log0(smb_logp, "MsV1_0SetProcessOption success");
afsi_log("MsV1_0SetProcessOption success");
}
/* END - code from Larry */