osi_rwlock_t smb_globalLock;
osi_rwlock_t smb_rctLock;
osi_mutex_t smb_ListenerLock;
+osi_mutex_t smb_StartedLock;
-char smb_LANadapter;
+unsigned char smb_LANadapter = LANA_INVALID;
unsigned char smb_sharename[NCBNAMSZ+1] = {0};
+int smb_LanAdapterChangeDetected = 0;
BOOL isGateway = FALSE;
EVENT_HANDLE **NCBreturns;
EVENT_HANDLE **NCBShutdown;
EVENT_HANDLE *smb_ServerShutdown;
+EVENT_HANDLE ListenerShutdown[256];
DWORD NCBsessions[NCB_MAX];
NCB *NCBs[NCB_MAX];
struct smb_packet *bufs[NCB_MAX];
int lanas[SESSION_MAX];
BOOL dead_sessions[SESSION_MAX];
LANA_ENUM lana_list;
-
/* for raw I/O */
osi_mutex_t smb_RawBufLock;
char *smb_RawBufs;
/* forward decl */
void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp,
NCB *ncbp, raw_write_cont_t *rwcp);
-int smb_NetbiosInit(void);
+int smb_NetbiosInit(int);
#ifdef LOG_PACKET
void smb_LogPacket(smb_packet_t *packet);
*/
NTSTATUS nts = STATUS_UNSUCCESSFUL, ntsEx = STATUS_UNSUCCESSFUL;
MSV1_0_LM20_CHALLENGE_REQUEST lsaReq;
- PMSV1_0_LM20_CHALLENGE_RESPONSE lsaResp;
+ PMSV1_0_LM20_CHALLENGE_RESPONSE lsaResp = NULL;
ULONG lsaRespSize = 0;
lsaReq.MessageType = MsV1_0Lm20ChallengeRequest;
&lsaResp,
&lsaRespSize,
&ntsEx);
- if (nts != STATUS_SUCCESS)
+ if (nts != STATUS_SUCCESS || ntsEx != STATUS_SUCCESS) {
osi_Log4(smb_logp,"MsV1_0Lm20ChallengeRequest failure: nts 0x%x ntsEx 0x%x respSize is %u needs %u",
nts, ntsEx, sizeof(lsaReq), lsaRespSize);
+ afsi_log("MsV1_0Lm20ChallengeRequest failure: nts 0x%x ntsEx 0x%x respSize %u",
+ nts, ntsEx, lsaRespSize);
+ }
osi_assertx(nts == STATUS_SUCCESS, "LsaCallAuthenticationPackage failed"); /* this had better work! */
- memcpy(vcp->encKey, lsaResp->ChallengeToClient, MSV1_0_CHALLENGE_LENGTH);
- LsaFreeReturnBuffer(lsaResp);
+ if (ntsEx == STATUS_SUCCESS) {
+ memcpy(vcp->encKey, lsaResp->ChallengeToClient, MSV1_0_CHALLENGE_LENGTH);
+ LsaFreeReturnBuffer(lsaResp);
+ } else {
+ /*
+ * This will cause the subsequent authentication to fail but
+ * that is better than us dereferencing a NULL pointer and
+ * crashing.
+ */
+ memset(vcp->encKey, 0, MSV1_0_CHALLENGE_LENGTH);
+ }
}
else
memset(vcp->encKey, 0, MSV1_0_CHALLENGE_LENGTH);
}
if (_stricmp(shareName, "IPC$") == 0 ||
+ _stricmp(shareName, "srvsvc") == 0 ||
+ _stricmp(shareName, "wkssvc") == 0 ||
_stricmp(shareName, SMB_IOCTL_FILENAME_NOSLASH) == 0 ||
_stricmp(shareName, "DESKTOP.INI") == 0
) {
NTStatus = 0xC09820FBL; /* SMB use standard */
}
else if (code == CM_ERROR_QUOTA) {
-#ifdef COMMENT
NTStatus = 0xC0000044L; /* Quota exceeded */
-#else
- NTStatus = 0xC000007FL; /* Disk full */
-#endif
}
else if (code == CM_ERROR_SPACE) {
NTStatus = 0xC000007FL; /* Disk full */
else if (code == CM_ERROR_PATH_NOT_COVERED) {
NTStatus = 0xC0000257L; /* Path Not Covered */
}
-#ifdef COMMENT
else if (code == CM_ERROR_ALLBUSY) {
- NTStatus = 0xC00000BFL; /* Network Busy */
+ NTStatus = 0xC000022DL; /* Retry */
}
else if (code == CM_ERROR_ALLOFFLINE || code == CM_ERROR_ALLDOWN) {
- NTStatus = 0xC0000350L; /* Remote Host Down */
- }
-#else
- /* we do not want to be telling the SMB/CIFS client that
- * the AFS Client Service is busy or down.
- */
- else if (code == CM_ERROR_ALLBUSY ||
- code == CM_ERROR_ALLOFFLINE ||
- code == CM_ERROR_ALLDOWN) {
NTStatus = 0xC00000BEL; /* Bad Network Path */
- }
-#endif
- else if (code == RXKADUNKNOWNKEY) {
- NTStatus = 0xC0000322L; /* Bad Kerberos key */
+ }
+ else if (code >= ERROR_TABLE_BASE_RXK && code < ERROR_TABLE_BASE_RXK + 256) {
+ NTStatus = 0xC0000322L; /* No Kerberos key */
}
else if (code == CM_ERROR_BAD_LEVEL) {
NTStatus = 0xC0000148L; /* Invalid Level */
- } else {
+ }
+ else if (code == CM_ERROR_RANGE_NOT_LOCKED) {
+ NTStatus = 0xC000007EL; /* Range Not Locked */
+ }
+ else {
NTStatus = 0xC0982001L; /* SMB non-specific error */
}
/* mask starts out all blanks */
memset(maskp, ' ', 11);
+ maskp[11] = '\0';
/* find last backslash, or use whole thing if there is none */
tp = strrchr(pathp, '\\');
- if (!tp) tp = pathp;
- else tp++; /* skip slash */
+ if (!tp)
+ tp = pathp;
+ else
+ tp++; /* skip slash */
up = maskp;
/* names starting with a dot are illegal */
- if (*tp == '.') valid8Dot3 = 0;
+ if (*tp == '.')
+ valid8Dot3 = 0;
for(i=0;; i++) {
tc = *tp++;
- if (tc == 0) return valid8Dot3;
- if (tc == '.' || tc == '"') break;
- if (i < 8) *up++ = tc;
- else valid8Dot3 = 0;
+ if (tc == 0)
+ return valid8Dot3;
+ if (tc == '.' || tc == '"')
+ break;
+ if (i < 8)
+ *up++ = tc;
+ else
+ valid8Dot3 = 0;
}
/* if we get here, tp point after the dot */
{
unsigned char *pathp;
unsigned char *tp;
- unsigned char mask[11];
+ unsigned char mask[12];
unsigned char *statBlockp;
unsigned char initStatBlock[21];
int statLen;
return 0;
}
-long smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp,
- cm_user_t *userp, cm_req_t *reqp)
+static long
+smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp,
+ char * tidPathp, char * relPathp,
+ cm_user_t *userp, cm_req_t *reqp)
{
long code = 0;
cm_scache_t *scp;
char attr;
smb_dirListPatch_t *patchp;
smb_dirListPatch_t *npatchp;
+ char path[AFSPATHMAX];
for (patchp = *dirPatchespp; patchp; patchp =
(smb_dirListPatch_t *) osi_QNext(&patchp->q)) {
dptr = patchp->dptr;
+ snprintf(path, AFSPATHMAX, "%s\\%s", relPathp ? relPathp : "", patchp->dep->name);
+ reqp->relPathp = path;
+ reqp->tidPathp = tidPathp;
+
code = cm_GetSCache(&patchp->fid, &scp, userp, reqp);
+ reqp->relPathp = reqp->tidPathp = NULL;
+
if (code) {
if( patchp->flags & SMB_DIRLISTPATCH_DOTFILE )
*dptr++ = SMB_ATTR_HIDDEN;
char *tp;
long code = 0;
char *pathp;
- cm_dirEntry_t *dep;
+ cm_dirEntry_t *dep = 0;
int maxCount;
smb_dirListPatch_t *dirListPatchesp;
smb_dirListPatch_t *curPatchp;
char shortName[13];
char *actualName;
char *shortNameEnd;
- char mask[11];
+ char mask[12];
int returnedNames;
long nextEntryCookie;
int numDirChunks; /* # of 32 byte dir chunks in this entry */
int starPattern;
int rootPath = 0;
int caseFold;
- char *tidPathp;
+ char *tidPathp = 0;
cm_req_t req;
cm_fid_t fid;
int fileType;
dsp = smb_NewDirSearch(0);
dsp->attribute = attribute;
smb_Get8Dot3MaskFromPath(mask, pathp);
- memcpy(dsp->mask, mask, 11);
+ memcpy(dsp->mask, mask, 12);
/* track if this is likely to match a lot of entries */
if (smb_IsStarMask(mask))
*/
memcpy(&clientCookie, &inCookiep[17], 4);
- memcpy(mask, dsp->mask, 11);
+ memcpy(mask, dsp->mask, 12);
/* assume we're doing a star match if it has continued for more
* than one call.
smb_ReleaseDirSearch(dsp);
return CM_ERROR_NOFILES;
}
+ strcpy(dsp->tidPath, tidPathp ? tidPathp : "/");
+ strcpy(dsp->relPath, spacep->data);
+
code = cm_NameI(cm_data.rootSCachep, spacep->data,
caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &scp);
if (code == 0) {
#ifdef DFS_SUPPORT
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, spacep->data);
cm_ReleaseSCache(scp);
lock_ReleaseMutex(&dsp->mx);
cm_ReleaseUser(userp);
smb_DeleteDirSearch(dsp);
smb_ReleaseDirSearch(dsp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
* the status info for files in the dir.
*/
if (starPattern) {
- smb_ApplyDirListPatches(&dirListPatchesp, userp, &req);
+ smb_ApplyDirListPatches(&dirListPatchesp, dsp->tidPath, dsp->relPath, userp, &req);
lock_ObtainMutex(&scp->mx);
if ((dsp->flags & SMB_DIRSEARCH_BULKST) &&
LargeIntegerGreaterThanOrEqualTo(thyper,
/* apply and free last set of patches; if not doing a star match, this
* will be empty, but better safe (and freeing everything) than sorry.
*/
- smb_ApplyDirListPatches(&dirListPatchesp, userp, &req);
+ smb_ApplyDirListPatches(&dirListPatchesp, dsp->tidPath, dsp->relPath, userp, &req);
/* special return code for unsuccessful search */
if (code == 0 && dataLength < 21 && returnedNames == 0)
#ifdef DFS_SUPPORT
if (newScp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newScp, tidPathp, pathp);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (newScp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newScp, tidPathp, pathp);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
if (code == 0) {
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
- if ( WANTS_DFS_PATHNAMES(inp) )
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (newScp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newScp, tidPathp, pathp);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, pathp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
cm_DirEntryListAdd(dep->name, &rockp->matches);
- rockp->any = 1;
+ rockp->any = 1;
- /* If we made a case sensitive exact match, we might as well quit now. */
- if (!(rockp->flags & SMB_MASKFLAG_CASEFOLD) && !strcmp(matchName, rockp->maskp))
- code = CM_ERROR_STOPNOW;
+ /* If we made a case sensitive exact match, we might as well quit now. */
+ if (!(rockp->flags & SMB_MASKFLAG_CASEFOLD) && !strcmp(matchName, rockp->maskp))
+ code = CM_ERROR_STOPNOW;
else
code = 0;
}
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp,spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (oldDscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(oldDscp, tidPathp, spacep->data);
cm_ReleaseSCache(oldDscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (newDscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newDscp, tidPathp, spacep->data);
cm_ReleaseSCache(oldDscp);
cm_ReleaseSCache(newDscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (oldDscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(oldDscp, tidPathp, spacep->data);
cm_ReleaseSCache(oldDscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (newDscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newDscp, tidPathp, spacep->data);
cm_ReleaseSCache(newDscp);
cm_ReleaseSCache(oldDscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->data);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
char cname[MAX_COMPUTERNAME_LENGTH+1];
int cnamelen = MAX_COMPUTERNAME_LENGTH+1;
INT_PTR lana = (INT_PTR) parmp;
+ char eventName[MAX_PATH];
+
+ sprintf(eventName,"smb_Listener_lana_%d", (char)lana);
+ ListenerShutdown[lana] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName);
+ if ( GetLastError() == ERROR_ALREADY_EXISTS )
+ thrd_ResetEvent(ListenerShutdown[lana]);
ncbp = GetNCB();
code = Netbios(ncbp);
- if (code == NRC_BRIDGE) {
- int lanaRemaining = 0;
+ if (code == NRC_NAMERR) {
+ /* An smb shutdown or Vista resume must have taken place */
+ osi_Log2(smb_logp,
+ "NCBLISTEN lana=%d failed with NRC_NAMERR.",
+ ncbp->ncb_lana_num, code);
- if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1) {
- ExitThread(1);
+ if (lock_TryMutex(&smb_StartedLock)) {
+ lana_list.lana[i] = LANA_INVALID;
+ lock_ReleaseMutex(&smb_StartedLock);
}
+ break;
+ } else if (code == NRC_BRIDGE || code != 0) {
+ int lanaRemaining = 0;
- osi_Log2(smb_logp,
- "NCBLISTEN lana=%d failed with NRC_BRIDGE. Listener thread exiting.",
- ncbp->ncb_lana_num, code);
+ while (!lock_TryMutex(&smb_StartedLock)) {
+ if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1)
+ goto exit_thread;
+ Sleep(50);
+ }
+
+ osi_Log2(smb_logp,
+ "NCBLISTEN lana=%d failed with %s. Listener thread exiting.",
+ ncbp->ncb_lana_num, ncb_error_string(code));
for (i = 0; i < lana_list.length; i++) {
- if (lana_list.lana[i] == ncbp->ncb_lana_num) {
- smb_StopListener(ncbp, lana_list.lana[i]);
- lana_list.lana[i] = 255;
+ if (lana_list.lana[i] == lana) {
+ smb_StopListener(ncbp, lana_list.lana[i], FALSE);
+ lana_list.lana[i] = LANA_INVALID;
}
- if (lana_list.lana[i] != 255)
+ if (lana_list.lana[i] != LANA_INVALID)
lanaRemaining++;
}
#endif
);
smb_ListenerState = SMB_LISTENER_STOPPED;
- smb_LANadapter = -1;
+ smb_LANadapter = LANA_INVALID;
lana_list.length = 0;
}
- FreeNCB(ncbp);
- return;
- } else if (code != 0) {
+ lock_ReleaseMutex(&smb_StartedLock);
+ break;
+ }
+#if 0
+ else if (code != 0) {
char tbuffer[AFSPATHMAX];
/* terminate silently if shutdown flag is set */
- if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1) {
- ExitThread(1);
+ while (!lock_TryMutex(&smb_StartedLock)) {
+ if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1)
+ goto exit_thread;
+ Sleep(50);
}
- osi_Log2(smb_logp,
- "NCBLISTEN lana=%d failed with code %d",
- ncbp->ncb_lana_num, code);
+ osi_Log3(smb_logp,
+ "NCBLISTEN lana=%d failed with code %d [%s]",
+ ncbp->ncb_lana_num, code, ncb_error_string(code));
osi_Log0(smb_logp,
"Client exiting due to network failure. Please restart client.\n");
sprintf(tbuffer,
"Client exiting due to network failure. Please restart client.\n"
- "NCBLISTEN lana=%d failed with code %d",
- ncbp->ncb_lana_num, code);
+ "NCBLISTEN lana=%d failed with code %d [%s]",
+ ncbp->ncb_lana_num, code, ncb_error_string(code));
if (showErrors)
code = (*smb_MBfunc)(NULL, tbuffer, "AFS Client Service: Fatal Error",
MB_OK|MB_SERVICE_NOTIFICATION);
osi_panic(tbuffer, __FILE__, __LINE__);
+
+ lock_ReleaseMutex(&smb_StartedLock);
+ break;
}
+#endif /* 0 */
/* check for remote conns */
/* first get remote name and insert null terminator */
lock_ReleaseMutex(&smb_ListenerLock);
} /* dispatch while loop */
+exit_thread:
FreeNCB(ncbp);
+ thrd_SetEvent(ListenerShutdown[lana]);
+ return;
+}
+
+static void
+smb_LanAdapterChangeThread(void *param)
+{
+ /*
+ * Give the IPAddrDaemon thread a chance
+ * to block before we trigger.
+ */
+ Sleep(30000);
+ smb_LanAdapterChange(0);
+}
+
+void smb_SetLanAdapterChangeDetected(void)
+{
+ int lpid;
+ thread_t phandle;
+
+ lock_ObtainMutex(&smb_StartedLock);
+
+ if (!powerStateSuspended) {
+ phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_LanAdapterChangeThread,
+ NULL, 0, &lpid, "smb_LanAdapterChange");
+ osi_assertx(phandle != NULL, "smb_LanAdapterChangeThread thread creation failure");
+ thrd_CloseHandle(phandle);
+ }
+
+ smb_LanAdapterChangeDetected = 1;
+ lock_ReleaseMutex(&smb_StartedLock);
+}
+
+void smb_LanAdapterChange(int locked) {
+ lana_number_t lanaNum;
+ BOOL bGateway;
+ char NetbiosName[MAX_NB_NAME_LENGTH] = "";
+ int change = 0;
+ LANA_ENUM temp_list;
+ long code;
+ int i;
+
+
+ afsi_log("smb_LanAdapterChange");
+
+ if (!locked)
+ lock_ObtainMutex(&smb_StartedLock);
+
+ smb_LanAdapterChangeDetected = 0;
+
+ if (!powerStateSuspended &&
+ SUCCEEDED(lana_GetUncServerNameEx(NetbiosName, &lanaNum, &bGateway,
+ LANA_NETBIOS_NAME_FULL)) &&
+ lanaNum != LANA_INVALID && smb_LANadapter != lanaNum) {
+ if ( isGateway != bGateway ||
+ strcmp(cm_NetbiosName, NetbiosName) ) {
+ change = 1;
+ } else {
+ NCB *ncbp = GetNCB();
+ ncbp->ncb_command = NCBENUM;
+ ncbp->ncb_buffer = (PUCHAR)&temp_list;
+ ncbp->ncb_length = sizeof(temp_list);
+ code = Netbios(ncbp);
+ if (code == 0) {
+ if (temp_list.length != lana_list.length)
+ change = 1;
+ else {
+ for (i=0; i<lana_list.length; i++) {
+ if ( temp_list.lana[i] != lana_list.lana[i] ) {
+ change = 1;
+ break;
+ }
+ }
+ }
+ }
+ FreeNCB(ncbp);
+ }
+ }
+
+ if (change) {
+ afsi_log("Lan Adapter Change detected");
+ smb_StopListeners(1);
+ smb_RestartListeners(1);
+ }
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
}
/* initialize Netbios */
-int smb_NetbiosInit(void)
+int smb_NetbiosInit(int locked)
{
NCB *ncbp;
int i, lana, code, l;
int lana_found = 0;
lana_number_t lanaNum;
+ if (!locked)
+ lock_ObtainMutex(&smb_StartedLock);
+
+ if (smb_ListenerState != SMB_LISTENER_UNINITIALIZED &&
+ smb_ListenerState != SMB_LISTENER_STOPPED) {
+
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
+ return 0;
+ }
/* setup the NCB system */
ncbp = GetNCB();
if (SUCCEEDED(code = lana_GetUncServerNameEx(cm_NetbiosName, &lanaNum, &isGateway, LANA_NETBIOS_NAME_FULL))) {
smb_LANadapter = (lanaNum == LANA_INVALID)? -1: lanaNum;
- if (smb_LANadapter != -1)
+ if (smb_LANadapter != LANA_INVALID)
afsi_log("LAN adapter number %d", smb_LANadapter);
else
afsi_log("LAN adapter number not determined");
afsi_log("smb_localNamep is >%s<", smb_localNamep);
- if (smb_LANadapter == -1) {
+ if (smb_LANadapter == LANA_INVALID) {
ncbp->ncb_command = NCBENUM;
ncbp->ncb_buffer = (PUCHAR)&lana_list;
ncbp->ncb_length = sizeof(lana_list);
code = ncbp->ncb_retcode;
if (code != 0) {
afsi_log("Netbios NCBRESET lana %d error code %d", lana_list.lana[i], code);
- lana_list.lana[i] = 255; /* invalid lana */
+ lana_list.lana[i] = LANA_INVALID; /* invalid lana */
} else {
afsi_log("Netbios NCBRESET lana %d succeeded", lana_list.lana[i]);
}
else {
afsi_log("Netbios NCBADDNAME lana %d error code %d", lana, code);
if (code == NRC_BRIDGE) { /* invalid LANA num */
- lana_list.lana[l] = 255;
+ lana_list.lana[l] = LANA_INVALID;
continue;
}
else if (code == NRC_DUPNAME) {
afsi_log("Netbios NCBDELNAME lana %d error code %d\n", lana, code);
}
if (code != 0 || delname_tried) {
- lana_list.lana[l] = 255;
+ lana_list.lana[l] = LANA_INVALID;
}
else if (code == 0) {
if (!delname_tried) {
}
else {
afsi_log("Netbios NCBADDNAME lana %d error code %d", lana, code);
- lana_list.lana[l] = 255; /* invalid lana */
+ lana_list.lana[l] = LANA_INVALID; /* invalid lana */
}
}
if (code == 0) {
+ smb_LANadapter = lana;
lana_found = 1; /* at least one worked */
}
}
if (!lana_found) {
afsi_log("No valid LANA numbers found!");
lana_list.length = 0;
- smb_LANadapter = -1;
+ smb_LANadapter = LANA_INVALID;
smb_ListenerState = SMB_LISTENER_STOPPED;
cm_VolStatus_Network_Stopped(cm_NetbiosName
#ifdef _WIN64
/* we're done with the NCB now */
FreeNCB(ncbp);
+ afsi_log("smb_NetbiosInit smb_LANadapter=%d",smb_LANadapter);
+ if (lana_list.length > 0)
+ osi_assert(smb_LANadapter != LANA_INVALID);
+
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
+
return (lana_list.length > 0 ? 1 : 0);
}
-void smb_StartListeners()
+void smb_StartListeners(int locked)
{
int i;
int lpid;
thread_t phandle;
- if (smb_ListenerState == SMB_LISTENER_STARTED)
+ if (!locked)
+ lock_ObtainMutex(&smb_StartedLock);
+
+ if (smb_ListenerState == SMB_LISTENER_STARTED) {
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
return;
-
+ }
+
+ afsi_log("smb_StartListeners");
smb_ListenerState = SMB_LISTENER_STARTED;
cm_VolStatus_Network_Started(cm_NetbiosName
#ifdef _WIN64
);
for (i = 0; i < lana_list.length; i++) {
- if (lana_list.lana[i] == 255)
+ if (lana_list.lana[i] == LANA_INVALID)
continue;
phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_Listener,
(void*)lana_list.lana[i], 0, &lpid, "smb_Listener");
osi_assertx(phandle != NULL, "smb_Listener thread creation failure");
thrd_CloseHandle(phandle);
}
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
}
-void smb_RestartListeners()
+void smb_RestartListeners(int locked)
{
- if (!powerStateSuspended && smb_ListenerState == SMB_LISTENER_STOPPED) {
- if (smb_NetbiosInit())
- smb_StartListeners();
+ if (!locked)
+ lock_ObtainMutex(&smb_StartedLock);
+
+ if (powerStateSuspended)
+ afsi_log("smb_RestartListeners called while suspended");
+
+ if (!powerStateSuspended && smb_ListenerState != SMB_LISTENER_UNINITIALIZED) {
+ if (smb_ListenerState == SMB_LISTENER_STOPPED) {
+ if (smb_NetbiosInit(1))
+ smb_StartListeners(1);
+ } else if (smb_LanAdapterChangeDetected) {
+ smb_LanAdapterChange(1);
+ }
}
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
}
-void smb_StopListener(NCB *ncbp, int lana)
+void smb_StopListener(NCB *ncbp, int lana, int wait)
{
long code;
} else {
afsi_log("Netbios NCBRESET lana %d succeeded", lana);
}
+
+ if (wait)
+ thrd_WaitForSingleObject_Event(ListenerShutdown[lana], INFINITE);
}
-void smb_StopListeners(void)
+void smb_StopListeners(int locked)
{
NCB *ncbp;
int lana, l;
- if (smb_ListenerState == SMB_LISTENER_STOPPED)
+ if (!locked)
+ lock_ObtainMutex(&smb_StartedLock);
+
+ if (smb_ListenerState == SMB_LISTENER_STOPPED) {
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
return;
+ }
+ afsi_log("smb_StopListeners");
smb_ListenerState = SMB_LISTENER_STOPPED;
cm_VolStatus_Network_Stopped(cm_NetbiosName
#ifdef _WIN64
for (l = 0; l < lana_list.length; l++) {
lana = lana_list.lana[l];
- if (lana != 255) {
- smb_StopListener(ncbp, lana);
+ if (lana != LANA_INVALID) {
+ smb_StopListener(ncbp, lana, TRUE);
/* mark the adapter invalid */
- lana_list.lana[l] = 255; /* invalid lana */
+ lana_list.lana[l] = LANA_INVALID; /* invalid lana */
}
}
/* force a re-evaluation of the network adapters */
lana_list.length = 0;
- smb_LANadapter = -1;
+ smb_LANadapter = LANA_INVALID;
FreeNCB(ncbp);
- Sleep(1000); /* give the listener threads a chance to exit */
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
}
void smb_Init(osi_log_t *logp, int useV3,
struct tm myTime;
EVENT_HANDLE retHandle;
char eventName[MAX_PATH];
+ int startListeners = 0;
smb_TlsRequestSlot = TlsAlloc();
lock_InitializeMutex(&smb_RawBufLock, "smb raw buffer lock");
lock_InitializeMutex(&smb_ListenerLock, "smb listener lock");
+ lock_InitializeMutex(&smb_StartedLock, "smb started lock");
/* 4 Raw I/O buffers */
smb_RawBufs = calloc(65536,1);
smb_ncbFreeListp = NULL;
smb_packetFreeListp = NULL;
- smb_NetbiosInit();
+ lock_ObtainMutex(&smb_StartedLock);
+ startListeners = smb_NetbiosInit(1);
/* Initialize listener and server structures */
numVCs = 0;
}
/* Start listeners, waiters, servers, and daemons */
-
- smb_StartListeners();
+ if (startListeners)
+ smb_StartListeners(1);
phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_ClientWaiter,
NULL, 0, &lpid, "smb_ClientWaiter");
- osi_assertx(phandle != NULL, , "smb_ClientWaiter thread creation failure");
+ osi_assertx(phandle != NULL, "smb_ClientWaiter thread creation failure");
thrd_CloseHandle(phandle);
phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_ServerWaiter,
osi_assertx(phandle != NULL, "smb_WaitingLocksDaemon thread creation failure");
thrd_CloseHandle(phandle);
+ lock_ReleaseMutex(&smb_StartedLock);
return;
}
/* Delete Netbios name */
memset((char *)ncbp, 0, sizeof(NCB));
for (i = 0; i < lana_list.length; i++) {
- if (lana_list.lana[i] == 255) continue;
+ if (lana_list.lana[i] == LANA_INVALID) continue;
ncbp->ncb_command = NCBDELNAME;
ncbp->ncb_lana_num = lana_list.lana[i];
memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ);
long smb_IsNetworkStarted(void)
{
- return (smb_ListenerState == SMB_LISTENER_STARTED && smbShutdownFlag == 0);
+ long rc;
+ lock_ObtainWrite(&smb_globalLock);
+ rc = (smb_ListenerState == SMB_LISTENER_STARTED && smbShutdownFlag == 0);
+ lock_ReleaseWrite(&smb_globalLock);
+ return rc;
}