/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
*/
+#include <afsconfig.h>
#include <afs/param.h>
+#include <roken.h>
+
#include <afs/stds.h>
#include <windows.h>
#pragma warning(disable: 4005)
#include <ntstatus.h>
#pragma warning(pop)
+#include <sddl.h>
#include <stddef.h>
#include <stdlib.h>
#include <malloc.h>
#include <WINNT\afsreg.h>
#include "smb.h"
+#include "msrpc.h"
#include "lanahelper.h"
#define STRSAFE_NO_DEPRECATE
smb_dirSearch_t *smb_firstDirSearchp;
smb_dirSearch_t *smb_lastDirSearchp;
+/* Initial mode bits for files and directories. Set to 0 to use
+ defaults. */
+int smb_unixModeDefaultFile = 0666;
+int smb_unixModeDefaultDir = 0777;
+
/* hide dot files? */
int smb_hideDotFiles;
*/
time_t smb_localZero = 0;
-#define USE_NUMERIC_TIME_CONV 1
-
-#ifndef USE_NUMERIC_TIME_CONV
-/* Time difference for converting to kludge-GMT */
-afs_uint32 smb_NowTZ;
-#endif /* USE_NUMERIC_TIME_CONV */
-
char *smb_localNamep = NULL;
smb_vc_t *smb_allVCsp;
smb_waitingLockRequest_t *smb_allWaitingLocks;
-DWORD smb_TlsRequestSlot = -1;
-
/* forward decl */
void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp,
NCB *ncbp, raw_write_cont_t *rwcp);
#ifdef LOG_PACKET
void smb_LogPacket(smb_packet_t *packet);
#endif /* LOG_PACKET */
-
+
clientchar_t smb_ServerDomainName[MAX_COMPUTERNAME_LENGTH + 1] = _C(""); /* domain name */
int smb_ServerDomainNameLength = 0;
clientchar_t smb_ServerOS[] = _C("Windows 5.0"); /* Faux OS String */
reqp->flags |= CM_REQ_SOURCE_SMB;
}
-void smb_ResetServerPriority()
-{
- void * p = TlsGetValue(smb_TlsRequestSlot);
- if (p) {
- free(p);
- TlsSetValue(smb_TlsRequestSlot, NULL);
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
- }
-}
-
-void smb_SetRequestStartTime()
-{
- time_t * tp = TlsGetValue(smb_TlsRequestSlot);
- if (!tp)
- tp = malloc(sizeof(time_t));
- if (tp) {
- *tp = osi_Time();
-
- if (!TlsSetValue(smb_TlsRequestSlot, tp))
- free(tp);
- }
-}
-
-void smb_UpdateServerPriority()
-{
- time_t *tp = TlsGetValue(smb_TlsRequestSlot);
-
- if (tp) {
- time_t now = osi_Time();
-
- /* Give one priority boost for each 15 seconds */
- SetThreadPriority(GetCurrentThread(), (int)((now - *tp) / 15));
- }
-}
-
-
const char * ncb_error_string(int code)
{
const char * s;
switch ( code ) {
- case 0x01: s = "NRC_BUFLEN llegal buffer length"; break;
- case 0x03: s = "NRC_ILLCMD illegal command"; break;
- case 0x05: s = "NRC_CMDTMO command timed out"; break;
- case 0x06: s = "NRC_INCOMP message incomplete, issue another command"; break;
- case 0x07: s = "NRC_BADDR illegal buffer address"; break;
- case 0x08: s = "NRC_SNUMOUT session number out of range"; break;
- case 0x09: s = "NRC_NORES no resource available"; break;
- case 0x0a: s = "NRC_SCLOSED asession closed"; break;
- case 0x0b: s = "NRC_CMDCAN command cancelled"; break;
- case 0x0d: s = "NRC_DUPNAME duplicate name"; break;
- case 0x0e: s = "NRC_NAMTFUL name table full"; break;
- case 0x0f: s = "NRC_ACTSES no deletions, name has active sessions"; break;
- case 0x11: s = "NRC_LOCTFUL local session table full"; break;
- case 0x12: s = "NRC_REMTFUL remote session table full"; break;
- case 0x13: s = "NRC_ILLNN illegal name number"; break;
- case 0x14: s = "NRC_NOCALL no callname"; break;
- case 0x15: s = "NRC_NOWILD cannot put * in NCB_NAME"; break;
- case 0x16: s = "NRC_INUSE name in use on remote adapter"; break;
- case 0x17: s = "NRC_NAMERR name deleted"; break;
- case 0x18: s = "NRC_SABORT session ended abnormally"; break;
- case 0x19: s = "NRC_NAMCONF name conflict detected"; break;
- case 0x21: s = "NRC_IFBUSY interface busy, IRET before retrying"; break;
+ case 0x01: s = "NRC_BUFLEN llegal buffer length"; break;
+ case 0x03: s = "NRC_ILLCMD illegal command"; break;
+ case 0x05: s = "NRC_CMDTMO command timed out"; break;
+ case 0x06: s = "NRC_INCOMP message incomplete, issue another command"; break;
+ case 0x07: s = "NRC_BADDR illegal buffer address"; break;
+ case 0x08: s = "NRC_SNUMOUT session number out of range"; break;
+ case 0x09: s = "NRC_NORES no resource available"; break;
+ case 0x0a: s = "NRC_SCLOSED asession closed"; break;
+ case 0x0b: s = "NRC_CMDCAN command cancelled"; break;
+ case 0x0d: s = "NRC_DUPNAME duplicate name"; break;
+ case 0x0e: s = "NRC_NAMTFUL name table full"; break;
+ case 0x0f: s = "NRC_ACTSES no deletions, name has active sessions"; break;
+ case 0x11: s = "NRC_LOCTFUL local session table full"; break;
+ case 0x12: s = "NRC_REMTFUL remote session table full"; break;
+ case 0x13: s = "NRC_ILLNN illegal name number"; break;
+ case 0x14: s = "NRC_NOCALL no callname"; break;
+ case 0x15: s = "NRC_NOWILD cannot put * in NCB_NAME"; break;
+ case 0x16: s = "NRC_INUSE name in use on remote adapter"; break;
+ case 0x17: s = "NRC_NAMERR name deleted"; break;
+ case 0x18: s = "NRC_SABORT session ended abnormally"; break;
+ case 0x19: s = "NRC_NAMCONF name conflict detected"; break;
+ case 0x21: s = "NRC_IFBUSY interface busy, IRET before retrying"; break;
case 0x22: s = "NRC_TOOMANY too many commands outstanding, retry later";break;
- case 0x23: s = "NRC_BRIDGE ncb_lana_num field invalid"; break;
- case 0x24: s = "NRC_CANOCCR command completed while cancel occurring "; break;
- case 0x26: s = "NRC_CANCEL command not valid to cancel"; break;
- case 0x30: s = "NRC_DUPENV name defined by anther local process"; break;
- case 0x34: s = "NRC_ENVNOTDEF xenvironment undefined. RESET required"; break;
- case 0x35: s = "NRC_OSRESNOTAV required OS resources exhausted"; break;
- case 0x36: s = "NRC_MAXAPPS max number of applications exceeded"; break;
- case 0x37: s = "NRC_NOSAPS no saps available for netbios"; break;
- case 0x38: s = "NRC_NORESOURCES requested resources are not available"; break;
- case 0x39: s = "NRC_INVADDRESS invalid ncb address or length > segment"; break;
- case 0x3B: s = "NRC_INVDDID invalid NCB DDID"; break;
- case 0x3C: s = "NRC_LOCKFAILlock of user area failed"; break;
- case 0x3f: s = "NRC_OPENERR NETBIOS not loaded"; break;
- case 0x40: s = "NRC_SYSTEM system error"; break;
+ case 0x23: s = "NRC_BRIDGE ncb_lana_num field invalid"; break;
+ case 0x24: s = "NRC_CANOCCR command completed while cancel occurring "; break;
+ case 0x26: s = "NRC_CANCEL command not valid to cancel"; break;
+ case 0x30: s = "NRC_DUPENV name defined by anther local process"; break;
+ case 0x34: s = "NRC_ENVNOTDEF xenvironment undefined. RESET required"; break;
+ case 0x35: s = "NRC_OSRESNOTAV required OS resources exhausted"; break;
+ case 0x36: s = "NRC_MAXAPPS max number of applications exceeded"; break;
+ case 0x37: s = "NRC_NOSAPS no saps available for netbios"; break;
+ case 0x38: s = "NRC_NORESOURCES requested resources are not available"; break;
+ case 0x39: s = "NRC_INVADDRESS invalid ncb address or length > segment"; break;
+ case 0x3B: s = "NRC_INVDDID invalid NCB DDID"; break;
+ case 0x3C: s = "NRC_LOCKFAILlock of user area failed"; break;
+ case 0x3f: s = "NRC_OPENERR NETBIOS not loaded"; break;
+ case 0x40: s = "NRC_SYSTEM system error"; break;
default: s = "unknown error";
}
return s;
default:
return "unknown SMB op";
}
-}
+}
char * myCrt_2Dispatch(int i)
{
case 17:
return "S(11)_ReceiveTran2ReportDfsInconsistency";
}
-}
+}
char * myCrt_RapDispatch(int i)
{
* turns out to be impolitic in NT. See defect 10007.
*/
#ifdef notdef
- if ((scp->unixModeBits & 0222) == 0 || (scp->flags & CM_SCACHEFLAG_RO))
+ if ((scp->unixModeBits & 0200) == 0 || (scp->flags & CM_SCACHEFLAG_RO))
attrs |= SMB_ATTR_READONLY; /* turn on read-only flag */
#else
- if ((scp->unixModeBits & 0222) == 0)
+ if ((scp->unixModeBits & 0200) == 0)
attrs |= SMB_ATTR_READONLY; /* turn on read-only flag */
#endif
return attrs;
}
+void smb_SetInitialModeBitsForFile(int smb_attr, cm_attr_t * attr)
+{
+ if (smb_unixModeDefaultFile != 0) {
+ attr->mask |= CM_ATTRMASK_UNIXMODEBITS;
+ attr->unixModeBits = smb_unixModeDefaultFile;
+ if (smb_attr & SMB_ATTR_READONLY)
+ attr->unixModeBits &= ~0222;
+ }
+}
+
+void smb_SetInitialModeBitsForDir(int smb_attr, cm_attr_t * attr)
+{
+ if (smb_unixModeDefaultDir != 0) {
+ attr->mask |= CM_ATTRMASK_UNIXMODEBITS;
+ attr->unixModeBits = smb_unixModeDefaultDir;
+ }
+}
+
/* Check if the named file/dir is a dotfile/dotdir */
/* String pointed to by lastComp can have leading slashes, but otherwise should have
no other patch components */
if (!*s)
return 0;
if (*s == _C('.')) {
- if (!*(s + 1))
+ if (!*(s + 1))
return 0;
- if(*(s+1) == _C('.') && !*(s + 2))
+ if(*(s+1) == _C('.') && !*(s + 2))
return 0;
return 1;
}
WORD num;
end = start + len;
-
+
num = bits << (16 - end);
num = num >> ((16 - end) + start);
FILETIME ft;
WORD wDate, wTime;
- smb_LargeSearchTimeFromUnixTime(&ft, unixTime);
+ cm_LargeSearchTimeFromUnixTime(&ft, unixTime);
if (!FileTimeToDosDateTime(&ft, &wDate, &wTime))
osi_Log1(smb_logp, "Failed to convert filetime to dos datetime: %d", GetLastError());
sprintf(msg, "%s = %02d-%02d-%04d %02d:%02d:%02d", FuncName, month, day, year, hour, min, sec);
osi_Log1(smb_logp, "%s", osi_LogSaveString(smb_logp, msg));
}
-}
+}
/* Determine if we are observing daylight savings time */
void GetTimeZoneInfo(BOOL *pDST, LONG *pDstBias, LONG *pBias)
GetSystemTime(&utc);
/* Convert UTC time to local time using the time zone info. If we are
- observing DST, the calculated local time will include this.
+ observing DST, the calculated local time will include this.
*/
SystemTimeToTzSpecificLocalTime(&timeZoneInformation, &utc, &localDST);
/* Set the daylight bias to 0. The daylight bias is the amount of change
* in time that we use for daylight savings time. By setting this to 0
- * we cause there to be no change in time during daylight savings time.
+ * we cause there to be no change in time during daylight savings time.
*/
timeZoneInformation.DaylightBias = 0;
/* Convert the utc time to local time again, but this time without any
- adjustment for daylight savings time.
+ adjustment for daylight savings time.
*/
SystemTimeToTzSpecificLocalTime(&timeZoneInformation, &utc, &local);
observing daylight savings time.
*/
*pDST = localDST.wHour != local.wHour;
-}
-
+}
+
void CompensateForSmbClientLastWriteTimeBugs(afs_uint32 *pLastWriteTime)
{
/* Now adjust for a positive offset from GMT (a negative bias). */
if (bias < 0)
*pLastWriteTime -= (-bias * 60); /* Convert bias to seconds */
-}
-
-#ifndef USE_NUMERIC_TIME_CONV
-/*
- * Calculate the difference (in seconds) between local time and GMT.
- * This enables us to convert file times to kludge-GMT.
- */
-static void
-smb_CalculateNowTZ()
-{
- time_t t;
- struct tm gmt_tm, local_tm;
- int days, hours, minutes, seconds;
-
- t = time(NULL);
- gmt_tm = *(gmtime(&t));
- local_tm = *(localtime(&t));
-
- days = local_tm.tm_yday - gmt_tm.tm_yday;
- hours = 24 * days + local_tm.tm_hour - gmt_tm.tm_hour;
- minutes = 60 * hours + local_tm.tm_min - gmt_tm.tm_min;
- seconds = 60 * minutes + local_tm.tm_sec - gmt_tm.tm_sec;
-
- smb_NowTZ = seconds;
-}
-#endif /* USE_NUMERIC_TIME_CONV */
-
-#ifdef USE_NUMERIC_TIME_CONV
-void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, time_t unixTime)
-{
- // Note that LONGLONG is a 64-bit value
- LONGLONG ll;
-
- ll = Int32x32To64(unixTime, 10000000) + 116444736000000000;
- largeTimep->dwLowDateTime = (DWORD)(ll & 0xFFFFFFFF);
- largeTimep->dwHighDateTime = (DWORD)(ll >> 32);
-}
-#else
-void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, time_t unixTime)
-{
- struct tm *ltp;
- SYSTEMTIME stm;
- struct tm localJunk;
- time_t ersatz_unixTime;
-
- /*
- * Must use kludge-GMT instead of real GMT.
- * kludge-GMT is computed by adding time zone difference to localtime.
- *
- * real GMT would be:
- * ltp = gmtime(&unixTime);
- */
- ersatz_unixTime = unixTime - smb_NowTZ;
- ltp = localtime(&ersatz_unixTime);
-
- /* if we fail, make up something */
- if (!ltp) {
- ltp = &localJunk;
- localJunk.tm_year = 89 - 20;
- localJunk.tm_mon = 4;
- localJunk.tm_mday = 12;
- localJunk.tm_hour = 0;
- localJunk.tm_min = 0;
- localJunk.tm_sec = 0;
- }
-
- stm.wYear = ltp->tm_year + 1900;
- stm.wMonth = ltp->tm_mon + 1;
- stm.wDayOfWeek = ltp->tm_wday;
- stm.wDay = ltp->tm_mday;
- stm.wHour = ltp->tm_hour;
- stm.wMinute = ltp->tm_min;
- stm.wSecond = ltp->tm_sec;
- stm.wMilliseconds = 0;
-
- SystemTimeToFileTime(&stm, largeTimep);
-}
-#endif /* USE_NUMERIC_TIME_CONV */
-
-#ifdef USE_NUMERIC_TIME_CONV
-void smb_UnixTimeFromLargeSearchTime(time_t *unixTimep, FILETIME *largeTimep)
-{
- // Note that LONGLONG is a 64-bit value
- LONGLONG ll;
-
- ll = largeTimep->dwHighDateTime;
- ll <<= 32;
- ll += largeTimep->dwLowDateTime;
-
- ll -= 116444736000000000;
- ll /= 10000000;
-
- *unixTimep = (DWORD)ll;
-}
-#else /* USE_NUMERIC_TIME_CONV */
-void smb_UnixTimeFromLargeSearchTime(time_t *unixTimep, FILETIME *largeTimep)
-{
- SYSTEMTIME stm;
- struct tm lt;
- long save_timezone;
-
- FileTimeToSystemTime(largeTimep, &stm);
-
- lt.tm_year = stm.wYear - 1900;
- lt.tm_mon = stm.wMonth - 1;
- lt.tm_wday = stm.wDayOfWeek;
- lt.tm_mday = stm.wDay;
- lt.tm_hour = stm.wHour;
- lt.tm_min = stm.wMinute;
- lt.tm_sec = stm.wSecond;
- lt.tm_isdst = -1;
-
- save_timezone = _timezone;
- _timezone += smb_NowTZ;
- *unixTimep = mktime(<);
- _timezone = save_timezone;
-}
-#endif /* USE_NUMERIC_TIME_CONV */
-
-void smb_SearchTimeFromUnixTime(afs_uint32 *searchTimep, time_t unixTime)
-{
- struct tm *ltp;
- int dosDate;
- int dosTime;
- struct tm localJunk;
- time_t t = unixTime;
-
- ltp = localtime(&t);
-
- /* if we fail, make up something */
- if (!ltp) {
- ltp = &localJunk;
- localJunk.tm_year = 89 - 20;
- localJunk.tm_mon = 4;
- localJunk.tm_mday = 12;
- localJunk.tm_hour = 0;
- localJunk.tm_min = 0;
- localJunk.tm_sec = 0;
- }
-
- dosDate = ((ltp->tm_year-80)<<9) | ((ltp->tm_mon+1) << 5) | (ltp->tm_mday);
- dosTime = (ltp->tm_hour<<11) | (ltp->tm_min << 5) | (ltp->tm_sec / 2);
- *searchTimep = (dosDate<<16) | dosTime;
-}
-
-void smb_UnixTimeFromSearchTime(time_t *unixTimep, afs_uint32 searchTime)
-{
- unsigned short dosDate;
- unsigned short dosTime;
- struct tm localTm;
-
- dosDate = (unsigned short) (searchTime & 0xffff);
- dosTime = (unsigned short) ((searchTime >> 16) & 0xffff);
-
- localTm.tm_year = 80 + ((dosDate>>9) & 0x3f);
- localTm.tm_mon = ((dosDate >> 5) & 0xf) - 1; /* January is 0 in localTm */
- localTm.tm_mday = (dosDate) & 0x1f;
- localTm.tm_hour = (dosTime>>11) & 0x1f;
- localTm.tm_min = (dosTime >> 5) & 0x3f;
- localTm.tm_sec = (dosTime & 0x1f) * 2;
- localTm.tm_isdst = -1; /* compute whether DST in effect */
-
- *unixTimep = mktime(&localTm);
}
void smb_DosUTimeFromUnixTime(afs_uint32 *dosUTimep, time_t unixTime)
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",
+ osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp",
__FILE__, __LINE__);
if (vcp == exclude)
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",
+ osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp",
__FILE__, __LINE__);
lock_ObtainMutex(&vcp->mx);
vcp->secCtx = NULL;
if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) {
- /* We must obtain a challenge for extended auth
- * in case the client negotiates smb v3
+ /* We must obtain a challenge for extended auth
+ * in case the client negotiates smb v3
*/
NTSTATUS nts = STATUS_UNSUCCESSFUL, ntsEx = STATUS_UNSUCCESSFUL;
MSV1_0_LM20_CHALLENGE_REQUEST lsaReq;
if (ntsEx == STATUS_SUCCESS) {
memcpy(vcp->encKey, lsaResp->ChallengeToClient, MSV1_0_CHALLENGE_LENGTH);
} else {
- /*
+ /*
* This will cause the subsequent authentication to fail but
- * that is better than us dereferencing a NULL pointer and
+ * that is better than us dereferencing a NULL pointer and
* crashing.
*/
memset(vcp->encKey, 0, MSV1_0_CHALLENGE_LENGTH);
{
int i;
clientchar_t tc;
-
+
for(i=0; i<11; i++) {
tc = *maskp++;
if (tc == _C('?') || tc == _C('*') || tc == _C('>'))
static int smb_IsStarMask(clientchar_t *maskp)
{
clientchar_t tc;
-
+
while (*maskp) {
tc = *maskp++;
if (tc == _C('?') || tc == _C('*') || tc == _C('>'))
*vcpp = vcp->nextp;
break;
}
- }
+ }
lock_FinalizeMutex(&vcp->mx);
memset(vcp,0,sizeof(smb_vc_t));
free(vcp);
}
} else if (vcp->flags & SMB_VCFLAG_ALREADYDEAD) {
/* The reference count is non-zero but the VC is dead.
- * This implies that some FIDs, TIDs, etc on the VC have yet to
+ * This implies that some FIDs, TIDs, etc on the VC have yet to
* be cleaned up. If we were not called by smb_CleanupDeadVC(),
* add a reference that will be dropped by
* smb_CleanupDeadVC() and try to cleanup the VC again.
lock_AssertWrite(&smb_rctLock);
osi_Log2(smb_logp,"smb_ReleaseVCNoLock vcp %x ref %d",vcp, vcp->refCount);
smb_ReleaseVCInternal(vcp);
-}
+}
#ifdef DEBUG_SMB_REFCOUNT
void smb_ReleaseVCDbg(smb_vc_t *vcp, char * file, long line)
osi_Log2(smb_logp,"smb_ReleaseVC vcp %x ref %d",vcp, vcp->refCount);
smb_ReleaseVCInternal(vcp);
lock_ReleaseWrite(&smb_rctLock);
-}
+}
#ifdef DEBUG_SMB_REFCOUNT
void smb_HoldVCNoLockDbg(smb_vc_t *vcp, char * file, long line)
#else
osi_Log2(smb_logp,"smb_HoldVCNoLock vcp %x ref %d",vcp, vcp->refCount);
#endif
-}
+}
#ifdef DEBUG_SMB_REFCOUNT
void smb_HoldVCDbg(smb_vc_t *vcp, char * file, long line)
osi_Log2(smb_logp,"smb_HoldVC vcp %x ref %d",vcp, vcp->refCount);
#endif
lock_ReleaseWrite(&smb_rctLock);
-}
+}
void smb_CleanupDeadVC(smb_vc_t *vcp)
{
/* remove VCP from smb_allVCsp */
for (vcpp = &smb_allVCsp; *vcpp; vcpp = &((*vcpp)->nextp)) {
if ((*vcpp)->magic != SMB_VC_MAGIC)
- osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp",
+ osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp",
__FILE__, __LINE__);
if (*vcpp == vcp) {
*vcpp = vcp->nextp;
}
/* The vcp is now on the deadVCsp list. We intentionally drop the
- * reference so that the refcount can reach 0 and we can delete it
+ * reference so that the refcount can reach 0 and we can delete it
*
- * If the refCount == 1 going into the ReleaseVCNoLock call
- * the object will be freed and it won't be safe to clear
+ * If the refCount == 1 going into the ReleaseVCNoLock call
+ * the object will be freed and it won't be safe to clear
* the flag.
*/
refCount = vcp->refCount;
if (tidp->deleteOk) {
ltpp = &tidp->vcp->tidsp;
for(tp = *ltpp; tp; ltpp = &tp->nextp, tp = *ltpp) {
- if (tp == tidp)
+ if (tp == tidp)
break;
}
osi_assertx(tp != NULL, "null smb_tid_t");
lock_ReleaseWrite(&smb_rctLock);
if (userp)
cm_ReleaseUser(userp);
-}
+}
smb_user_t *smb_FindUID(smb_vc_t *vcp, unsigned short uid, int flags)
{
if (uid == uidp->userID) {
uidp->refCount++;
osi_Log3(smb_logp, "smb_FindUID vcp[0x%p] found-uid[%d] name[%S]",
- vcp, uidp->userID,
+ vcp, uidp->userID,
((uidp->unp)? osi_LogSaveClientString(smb_logp, uidp->unp->name):_C("")));
break;
}
}
lock_ReleaseWrite(&smb_rctLock);
return uidp;
-}
+}
+
+afs_int32 smb_userIsLocalSystem(smb_user_t *uidp)
+{
+ SID *pSid = NULL;
+ DWORD dwSize1 = 0, dwSize2 = 0;
+ wchar_t *pszRefDomain = NULL;
+ SID_NAME_USE snu = SidTypeGroup;
+ clientchar_t * secSidString = NULL;
+ DWORD gle;
+ afs_int32 isSystem = 0;
+
+ if (uidp->unp->flags & SMB_USERNAMEFLAG_SID) {
+ isSystem = !cm_ClientStrCmp(NTSID_LOCAL_SYSTEM, uidp->unp->name);
+ return isSystem;
+ }
+
+ /*
+ * The input name is not a SID for the user. See if we can
+ * obtain the SID for the specified name. If we can, use
+ * that instead of the name provided for the comparison.
+ */
+
+ LookupAccountNameW( NULL /* System Name to begin Search */,
+ uidp->unp->name,
+ NULL, &dwSize1,
+ NULL, &dwSize2,
+ &snu);
+ gle = GetLastError();
+ if (gle == ERROR_INSUFFICIENT_BUFFER) {
+ pSid = malloc(dwSize1);
+ /*
+ * Although dwSize2 is supposed to include the terminating
+ * NUL character, on Win7 it does not.
+ */
+ pszRefDomain = malloc((dwSize2 + 1) * sizeof(wchar_t));
+ }
+
+ if ( pSid && pszRefDomain ) {
+ memset(pSid, 0, dwSize1);
+
+ if (LookupAccountNameW( NULL /* System Name to begin Search */,
+ uidp->unp->name,
+ pSid, &dwSize1,
+ pszRefDomain, &dwSize2,
+ &snu))
+ ConvertSidToStringSidW(pSid, &secSidString);
+ }
+
+ if (secSidString) {
+ isSystem = !cm_ClientStrCmp(NTSID_LOCAL_SYSTEM, secSidString);
+ LocalFree(secSidString);
+ }
+
+ if (pSid)
+ free(pSid);
+ if (pszRefDomain)
+ free(pszRefDomain);
+
+ return isSystem;
+}
smb_username_t *smb_FindUserByName(clientchar_t *usern, clientchar_t *machine,
afs_uint32 flags)
lock_ReleaseWrite(&smb_rctLock);
return unp;
-}
+}
smb_user_t *smb_FindUserByNameThisSession(smb_vc_t *vcp, clientchar_t *usern)
{
lock_ObtainWrite(&smb_rctLock);
for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) {
- if (!uidp->unp)
+ if (!uidp->unp)
continue;
if (cm_stricmp_utf16(uidp->unp->name, usern) == 0) {
uidp->refCount++;
break;
} else
continue;
- }
+ }
lock_ReleaseWrite(&smb_rctLock);
return uidp;
-}
+}
void smb_ReleaseUsername(smb_username_t *unp)
{
(unp->flags & SMB_USERNAMEFLAG_LOGOFF)) {
lupp = &usernamesp;
for(up = *lupp; up; lupp = &up->nextp, up = *lupp) {
- if (up == unp)
+ if (up == unp)
break;
}
osi_assertx(up != NULL, "null smb_username_t");
lock_ReleaseWrite(&smb_rctLock);
if (userp)
cm_ReleaseUser(userp);
-}
+}
void smb_HoldUIDNoLock(smb_user_t *uidp)
{
if (uidp->refCount == 0) {
lupp = &uidp->vcp->usersp;
for(up = *lupp; up; lupp = &up->nextp, up = *lupp) {
- if (up == uidp)
+ if (up == uidp)
break;
}
osi_assertx(up != NULL, "null smb_user_t");
smb_ReleaseVCNoLock(uidp->vcp);
uidp->vcp = NULL;
free(uidp);
- }
+ }
lock_ReleaseWrite(&smb_rctLock);
if (unp) {
cm_ReleaseUserVCRef(unp->userp);
smb_ReleaseUsername(unp);
}
-}
+}
cm_user_t *smb_GetUserFromUID(smb_user_t *uidp)
{
if (!uidp)
return NULL;
-
+
lock_ObtainMutex(&uidp->mx);
if (uidp->unp) {
up = uidp->unp->userp;
uidp = smb_FindUID(vcp, smbp->uid, 0);
if (!uidp)
return NULL;
-
+
up = smb_GetUserFromUID(uidp);
smb_ReleaseUID(uidp);
*/
int smb_ChainFID(int fid, smb_packet_t *inp)
{
- if (inp->fid == 0 || inp->inCount == 0)
+ if (inp->fid == 0 || inp->inCount == 0)
return fid;
- else
+ else
return inp->fid;
}
}
/* find a file ID. If we pass in 0 we select an unused File ID.
- * If the SMB_FLAG_CREATE flag is set, we allocate a new
+ * If the SMB_FLAG_CREATE flag is set, we allocate a new
* smb_fid_t data structure if desired File ID cannot be found.
*/
#ifdef DEBUG_SMB_REFCOUNT
{
smb_fid_t *fidp;
int newFid = 0;
-
- if (fid == 0 && !(flags & SMB_FLAG_CREATE))
- return NULL;
- lock_ObtainWrite(&smb_rctLock);
- /* figure out if we need to allocate a new file ID */
if (fid == 0) {
+ if (!(flags & SMB_FLAG_CREATE))
+ return NULL;
newFid = 1;
- fid = vcp->fidCounter;
}
+ lock_ObtainWrite(&smb_rctLock);
+ if (newFid)
+ fid = vcp->fidCounter;
retry:
+
for(fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q)) {
if (fidp->refCount == 0 && fidp->deleteOk) {
fidp->refCount++;
lock_ReleaseWrite(&smb_rctLock);
smb_ReleaseFID(fidp);
lock_ObtainWrite(&smb_rctLock);
+ /*
+ * We dropped the smb_rctLock so the fid value we are using
+ * may now be used by another thread. Start over with the
+ * current vcp->fidCounter.
+ */
+ if (newFid)
+ fid = vcp->fidCounter;
goto retry;
}
if (fid == fidp->fid) {
if (newFid) {
+ osi_Log1(smb_logp, "smb_FindFID New Fid Requested. fid %d found -- retrying ...", fid);
fid++;
if (fid == 0xFFFF) {
osi_Log1(smb_logp,
if (!fidp && (flags & SMB_FLAG_CREATE)) {
char eventName[MAX_PATH];
EVENT_HANDLE event;
+
+ if (!newFid)
+ osi_Log1(smb_logp, "smb_FindFID New Fid Not Requested, Fid %d Not Found and CREATE flag set.", fid);
+ else
+ osi_Log1(smb_logp, "smb_FindFID New Fid Requested. Creating fid %d", fid);
+
sprintf(eventName,"fid_t event vcp=%d fid=%d", vcp->vcID, fid);
event = thrd_CreateEvent(NULL, FALSE, TRUE, eventName);
if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
#endif
{
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
+ * was processed by smb_CloseFID() and the *fidp is
* no longer valid for use.
*/
lock_ObtainWrite(&smb_rctLock);
userp = fidp->userp;
fidp->userp = NULL;
- if (vcp->fidsp)
+ if (vcp->fidsp)
osi_QRemove((osi_queue_t **) &vcp->fidsp, &fidp->q);
thrd_CloseHandle(fidp->raw_write_event);
lock_ReleaseWrite(&smb_rctLock);
/* now release the scache structure */
- if (scp)
+ if (scp)
cm_ReleaseSCache(scp);
if (userp)
cm_ReleaseUser(userp);
-}
+}
/*
* Case-insensitive search for one string in another;
matchType = SMB_FINDSHARE_EXACT_MATCH;
else
matchType = SMB_FINDSHARE_PARTIAL_MATCH;
- if(vrock->match)
+ if(vrock->match)
free(vrock->match);
vrock->match = cm_FsStringToClientStringAlloc(dep->name, -1, NULL);
vrock->matchType = matchType;
DWORD code;
DWORD allSubmount = 1;
- /* if allSubmounts == 0, only return the //mountRoot/all share
- * if in fact it has been been created in the subMounts table.
- * This is to allow sites that want to restrict access to the
+ /* if allSubmounts == 0, only return the //mountRoot/all share
+ * if in fact it has been been created in the subMounts table.
+ * This is to allow sites that want to restrict access to the
* world to do so.
*/
code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
}
/* In case, the all share is disabled we need to still be able
- * to handle ioctl requests
+ * to handle ioctl requests
*/
if (cm_ClientStrCmpI(shareName, _C("ioctl$")) == 0) {
*pathNamep = cm_ClientStrDup(_C("/.__ioctl__"));
return 1;
}
- if (cm_ClientStrCmpIA(shareName, _C("IPC$")) == 0 ||
- cm_ClientStrCmpIA(shareName, _C("srvsvc")) == 0 ||
- cm_ClientStrCmpIA(shareName, _C("wkssvc")) == 0 ||
- cm_ClientStrCmpIA(shareName, _C("spoolss")) == 0 ||
- cm_ClientStrCmpIA(shareName, _C("winreg")) == 0 ||
+ if (MSRPC_IsWellKnownService(shareName) ||
cm_ClientStrCmpIA(shareName, _C(SMB_IOCTL_FILENAME_NOSLASH)) == 0 ||
cm_ClientStrCmpIA(shareName, _C("DESKTOP.INI")) == 0
) {
}
/* Check for volume references
- *
+ *
* They look like <cell>{%,#}<volume>
*/
if (cm_ClientStrChr(shareName, '%') != NULL ||
cchlen = cblen / sizeof(clientchar_t);
if (cchlen != 0 && cchlen != lengthof(pathName) - 1) {
/* We can accept either unix or PC style AFS pathnames. Convert
- * Unix-style to PC style here for internal use.
+ * Unix-style to PC style here for internal use.
*/
p = pathName;
cchlen = lengthof(pathName);
- /* within this code block, we maintain, cchlen = writeable
+ /* within this code block, we maintain, cchlen = writable
buffer length of p */
if (cm_ClientStrCmpN(p, cm_mountRootC, cm_mountRootCLen) == 0) {
else
smb_subst(p, cchlen, var, lengthof(VNUserName), _C(" "));
}
- else if (var = smb_stristr(p, VNLCUserName))
+ else if (var = smb_stristr(p, VNLCUserName))
{
if (uidp && uidp->unp)
cm_ClientStrCpy(temp, lengthof(temp), uidp->unp->name);
- else
+ else
cm_ClientStrCpy(temp, lengthof(temp), _C(" "));
cm_ClientStrLwr(temp);
smb_subst(p, cchlen, var, lengthof(VNLCUserName), temp);
}
- else if (var = smb_stristr(p, VNComputerName))
+ else if (var = smb_stristr(p, VNComputerName))
{
sizeTemp = lengthof(temp);
GetComputerNameW(temp, &sizeTemp);
smb_subst(p, cchlen, var, lengthof(VNComputerName), temp);
}
- else if (var = smb_stristr(p, VNLCComputerName))
+ else if (var = smb_stristr(p, VNLCComputerName))
{
sizeTemp = lengthof(temp);
GetComputerName((LPTSTR)temp, &sizeTemp);
cm_ClientStrLwr(temp);
smb_subst(p, cchlen, var, lengthof(VNLCComputerName), temp);
}
- else
+ else
break;
}
*pathNamep = cm_ClientStrDup(p);
return 1;
- }
+ }
else
{
/* First lookup shareName in root.afs */
smb_findShare_rock_t vrock;
osi_hyper_t thyper;
fschar_t ftemp[1024];
- clientchar_t * p = shareName;
+ clientchar_t * p = shareName;
int rw = 0;
+ cm_scache_t * rscp;
+ cm_user_t *userp;
/* attempt to locate a partial match in root.afs. This is because
when using the ANSI RAP calls, the share name is limited to 13 chars
thyper.LowPart = 0;
vrock.shareName = cm_ClientStringToNormStringAlloc(shareName, -1, NULL);
- if (vrock.shareName == NULL)
+ if (vrock.shareName == NULL)
return 0;
vrock.match = NULL;
vrock.matchType = 0;
- cm_HoldSCache(cm_data.rootSCachep);
- code = cm_ApplyDir(cm_data.rootSCachep, smb_FindShareProc, &vrock, &thyper,
- (uidp? (uidp->unp ? uidp->unp->userp : NULL) : NULL), &req, NULL);
- cm_ReleaseSCache(cm_data.rootSCachep);
+ userp = (uidp? (uidp->unp ? uidp->unp->userp : cm_rootUserp) : cm_rootUserp);
+ rscp = cm_RootSCachep(userp, &req);
+ cm_HoldSCache(rscp);
+ code = cm_ApplyDir(rscp, smb_FindShareProc, &vrock, &thyper,
+ userp, &req, NULL);
+ cm_ReleaseSCache(rscp);
free(vrock.shareName);
vrock.shareName = NULL;
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;
code = cm_SearchCellByDNS(cellname, ftemp, &ttl, 0, 0);
}
-#endif
if (cellname)
free(cellname);
HKEY hkCSCPolicy;
int retval = CSC_POLICY_MANUAL;
- RegCreateKeyEx( HKEY_LOCAL_MACHINE,
- AFSREG_CLT_OPENAFS_SUBKEY "\\CSCPolicy",
- 0,
- "AFS",
- REG_OPTION_NON_VOLATILE,
- KEY_READ,
- NULL,
- &hkCSCPolicy,
- NULL );
+ if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ AFSREG_CLT_OPENAFS_SUBKEY "\\CSCPolicy",
+ 0,
+ "AFS",
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ,
+ NULL,
+ &hkCSCPolicy,
+ NULL ) != ERROR_SUCCESS)
+ retval = cm_ClientStrCmpIA(_C("all"),shareName) ? CSC_POLICY_MANUAL : CSC_POLICY_DISABLE;
len = sizeof(policy);
if ( RegQueryValueExW( hkCSCPolicy, shareName, 0, &dwType, (LPBYTE) policy, &len ) ||
len == 0) {
retval = cm_ClientStrCmpIA(_C("all"),shareName) ? CSC_POLICY_MANUAL : CSC_POLICY_DISABLE;
}
+ else if (cm_ClientStrCmpIA(policy, _C("manual")) == 0)
+ {
+ retval = CSC_POLICY_MANUAL;
+ }
else if (cm_ClientStrCmpIA(policy, _C("documents")) == 0)
{
retval = CSC_POLICY_DOCUMENTS;
{
retval = CSC_POLICY_DISABLE;
}
-
+
RegCloseKey(hkCSCPolicy);
return retval;
}
smb_dirSearch_t *smb_FindDirSearchNoLock(long cookie)
{
smb_dirSearch_t *dsp;
-
+
for (dsp = smb_firstDirSearchp; dsp; dsp = (smb_dirSearch_t *) osi_QNext(&dsp->q)) {
if (dsp->cookie == cookie) {
if (dsp != smb_firstDirSearchp) {
}
}
return dsp;
-}
+}
void smb_DeleteDirSearch(smb_dirSearch_t *dsp)
{
lock_ObtainMutex(&dsp->mx);
- osi_Log3(smb_logp,"smb_DeleteDirSearch cookie %d dsp 0x%p scp 0x%p",
+ osi_Log3(smb_logp,"smb_DeleteDirSearch cookie %d dsp 0x%p scp 0x%p",
dsp->cookie, dsp, dsp->scp);
dsp->flags |= SMB_DIRSEARCH_DELETE;
if (dsp->scp != NULL) {
dsp->flags &= ~SMB_DIRSEARCH_BULKST;
dsp->scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING;
dsp->scp->bulkStatProgress = hzero;
- }
+ }
lock_ReleaseWrite(&dsp->scp->rw);
- }
+ }
lock_ReleaseMutex(&dsp->mx);
-}
+}
/* Must be called with the smb_globalLock held */
void smb_ReleaseDirSearchNoLock(smb_dirSearch_t *dsp)
lock_ReleaseMutex(&dsp->mx);
lock_FinalizeMutex(&dsp->mx);
scp = dsp->scp;
- osi_Log3(smb_logp,"smb_ReleaseDirSearch cookie %d dsp 0x%p scp 0x%p",
+ osi_Log3(smb_logp,"smb_ReleaseDirSearch cookie %d dsp 0x%p scp 0x%p",
dsp->cookie, dsp, scp);
free(dsp);
} else {
}
}
/* do this now to avoid spurious locking hierarchy creation */
- if (scp)
+ if (scp)
cm_ReleaseSCache(scp);
-}
+}
void smb_ReleaseDirSearch(smb_dirSearch_t *dsp)
{
lock_ObtainWrite(&smb_globalLock);
smb_ReleaseDirSearchNoLock(dsp);
lock_ReleaseWrite(&smb_globalLock);
-}
+}
/* find a dir search structure by cookie value, and return it held */
smb_dirSearch_t *smb_FindDirSearch(long cookie)
smb_dirSearch_t *victimsp[SMB_DIRSEARCH_GCMAX];
int victimCount;
int i;
-
+
victimCount = 0; /* how many have we got so far */
for (dsp = smb_lastDirSearchp; dsp; dsp=prevp) {
/* we'll move tp from queue, so
* do this early.
*/
- prevp = (smb_dirSearch_t *) osi_QPrev(&dsp->q);
+ prevp = (smb_dirSearch_t *) osi_QPrev(&dsp->q);
/* if no one is using this guy, and we're either in the new protocol,
* or we're in the old one and this is a small enough ID to be useful
* to the old protocol, GC this guy.
}
/* don't do more than this */
- if (victimCount >= SMB_DIRSEARCH_GCMAX)
+ if (victimCount >= SMB_DIRSEARCH_GCMAX)
break;
}
-
+
/* now release them */
for (i = 0; i < victimCount; i++) {
smb_ReleaseDirSearchNoLock(victimsp[i]);
/* twice so we have enough tries to find guys we GC after one pass;
* 10 extra is just in case I mis-counted.
*/
- if (++counter > 2*maxAllowed+10)
+ if (++counter > 2*maxAllowed+10)
osi_panic("afsd: dir search cookie leak", __FILE__, __LINE__);
- if (smb_dirSearchCounter > maxAllowed) {
+ if (smb_dirSearchCounter > maxAllowed) {
smb_dirSearchCounter = 1;
}
if (smb_dirSearchCounter == start) {
dsp->refCount--;
++smb_dirSearchCounter;
continue;
- }
+ }
dsp = malloc(sizeof(*dsp));
memset(dsp, 0, sizeof(*dsp));
lock_InitializeMutex(&dsp->mx, "cm_dirSearch_t", LOCK_HIERARCHY_SMB_DIRSEARCH);
dsp->lastTime = osi_Time();
osi_QAdd((osi_queue_t **) &smb_firstDirSearchp, &dsp->q);
- if (!smb_lastDirSearchp)
+ if (!smb_lastDirSearchp)
smb_lastDirSearchp = (smb_dirSearch_t *) &dsp->q;
-
- osi_Log2(smb_logp,"smb_NewDirSearch cookie %d dsp 0x%p",
+
+ osi_Log2(smb_logp,"smb_NewDirSearch cookie %d dsp 0x%p",
dsp->cookie, dsp);
break;
- }
+ }
lock_ReleaseWrite(&smb_globalLock);
return dsp;
}
lock_ObtainWrite(&smb_globalLock);
tbp = smb_packetFreeListp;
- if (tbp)
+ if (tbp)
smb_packetFreeListp = tbp->nextp;
lock_ReleaseWrite(&smb_globalLock);
if (!tbp) {
lock_ObtainWrite(&smb_globalLock);
tbp = smb_ncbFreeListp;
- if (tbp)
+ if (tbp)
smb_ncbFreeListp = tbp->nextp;
lock_ReleaseWrite(&smb_globalLock);
if (!tbp) {
tbp = calloc(sizeof(*tbp),1);
tbp->magic = SMB_NCBMAGIC;
}
-
+
osi_assertx(tbp->magic == SMB_NCBMAGIC, "invalid smb_packet_t magic");
memset(&tbp->ncb, 0, sizeof(NCB));
{
smb_vc_t * vcp = NULL;
osi_assertx(tbp->magic == SMB_PACKETMAGIC, "invalid smb_packet_t magic");
-
+
lock_ObtainWrite(&smb_globalLock);
tbp->nextp = smb_packetFreeListp;
smb_packetFreeListp = tbp;
static void smb_FreeNCB(NCB *bufferp)
{
smb_ncb_t *tbp;
-
+
tbp = (smb_ncb_t *) bufferp;
osi_assertx(tbp->magic == SMB_NCBMAGIC, "invalid smb_packet_t magic");
-
+
lock_ObtainWrite(&smb_globalLock);
tbp->nextp = smb_ncbFreeListp;
smb_ncbFreeListp = tbp;
parmBytes = *smbp->wctp << 1;
afterParmsp = smbp->wctp + parmBytes + 1;
-
+
dataBytes = afterParmsp[0] + (afterParmsp[1]<<8);
if (nbytesp) *nbytesp = dataBytes;
-
+
/* don't forget to skip the data byte count, since it follows
* the parameters; that's where the "2" comes from below.
*/
unsigned char *afterParmsp;
afterParmsp = smbp->wctp + ((*smbp->wctp)<<1) + 1;
-
+
*afterParmsp++ = dsize & 0xff;
*afterParmsp = (dsize>>8) & 0xff;
-}
+}
/* return the parm'th parameter in the smbp packet */
unsigned short smb_GetSMBParm(smb_packet_t *smbp, int parm)
parm, parmCount, smbp->ncb_length);
osi_Log3(smb_logp,"Bad SMB param %d out of %d, ncb len %d",
parm, parmCount, smbp->ncb_length);
- LogEvent(EVENTLOG_ERROR_TYPE, MSG_BAD_SMB_PARAM,
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_BAD_SMB_PARAM,
__FILE__, __LINE__, parm, parmCount, smbp->ncb_length);
osi_panic(s, __FILE__, __LINE__);
}
parmDatap = smbp->wctp + (2*parm) + 1;
-
+
return parmDatap[0] + (parmDatap[1] << 8);
}
parm, parmCount, smbp->ncb_length);
osi_Log3(smb_logp,"Bad SMB param %d out of %d, ncb len %d",
parm, parmCount, smbp->ncb_length);
- LogEvent(EVENTLOG_ERROR_TYPE, MSG_BAD_SMB_PARAM,
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_BAD_SMB_PARAM,
__FILE__, __LINE__, parm, parmCount, smbp->ncb_length);
osi_panic(s, __FILE__, __LINE__);
}
parmDatap = smbp->wctp + (2*parm) + 1;
-
+
return parmDatap[0];
}
parm, parmCount, smbp->ncb_length);
osi_Log3(smb_logp,"Bad SMB param %d out of %d, ncb len %d",
parm, parmCount, smbp->ncb_length);
- LogEvent(EVENTLOG_ERROR_TYPE, MSG_BAD_SMB_PARAM,
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_BAD_SMB_PARAM,
__FILE__, __LINE__, parm, parmCount, smbp->ncb_length);
osi_panic(s, __FILE__, __LINE__);
}
parmDatap = smbp->wctp + (2*parm) + 1;
-
+
return parmDatap[0] + (parmDatap[1] << 8) + (parmDatap[2] << 16) + (parmDatap[3] << 24);
}
sprintf(s, "Bad SMB param %d offset %d out of %d, ncb len %d",
parm, offset, parmCount, smbp->ncb_length);
- LogEvent(EVENTLOG_ERROR_TYPE, MSG_BAD_SMB_PARAM_WITH_OFFSET,
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_BAD_SMB_PARAM_WITH_OFFSET,
__FILE__, __LINE__, parm, offset, parmCount, smbp->ncb_length);
osi_Log4(smb_logp, "Bad SMB param %d offset %d out of %d, ncb len %d",
parm, offset, parmCount, smbp->ncb_length);
osi_panic(s, __FILE__, __LINE__);
}
parmDatap = smbp->wctp + (2*parm) + 1 + offset;
-
+
return parmDatap[0] + (parmDatap[1] << 8);
}
unsigned char *parmDatap;
/* make sure we have enough slots */
- if (*smbp->wctp <= slot)
+ if (*smbp->wctp <= slot)
*smbp->wctp = slot+1;
-
+
parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte;
*parmDatap++ = parmValue & 0xff;
*parmDatap = (parmValue>>8) & 0xff;
-}
+}
void smb_SetSMBParmLong(smb_packet_t *smbp, int slot, unsigned int parmValue)
{
unsigned char *parmDatap;
/* make sure we have enough slots */
- if (*smbp->wctp <= slot)
+ if (*smbp->wctp <= slot)
*smbp->wctp = slot+2;
parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte;
int i;
/* make sure we have enough slots */
- if (*smbp->wctp <= slot)
+ if (*smbp->wctp <= slot)
*smbp->wctp = slot+4;
parmDatap = smbp->wctp + 2*slot + 1 + smbp->oddByte;
for (i=0; i<8; i++)
*parmDatap++ = *parmValuep++;
-}
+}
void smb_SetSMBParmByte(smb_packet_t *smbp, int slot, unsigned int parmValue)
{
clientchar_t *inPathp)
{
clientchar_t *lastSlashp;
-
+ clientchar_t *streamp = NULL;
+ clientchar_t *typep = NULL;
+
lastSlashp = cm_ClientStrRChr(inPathp, '\\');
- if (lastComponentp)
+ if (lastComponentp) {
*lastComponentp = lastSlashp;
+ }
if (lastSlashp) {
+ /*
+ * If the name contains a stream name and a type
+ * and the stream name is the nul-string and the
+ * type is $DATA, then strip "::$DATA" from the
+ * last component string that is returned.
+ *
+ * Otherwise, return the full path name and allow
+ * the file name to be rejected because it contains
+ * a colon.
+ */
+ typep = cm_ClientStrRChr(lastSlashp, L':');
+ if (typep && cm_ClientStrCmpI(typep, L":$DATA") == 0) {
+ *typep = '\0';
+ streamp = cm_ClientStrRChr(lastSlashp, L':');
+ if (streamp && cm_ClientStrCmpI(streamp, L":") == 0) {
+ *streamp = '\0';
+ } else
+ *typep = ':';
+ osi_Log2(smb_logp, "smb_StripLastComponent found stream [%S] type [%S]",
+ osi_LogSaveClientString(smb_logp,streamp),
+ osi_LogSaveClientString(smb_logp,typep));
+ }
+
while (1) {
- if (inPathp == lastSlashp)
+ if (inPathp == lastSlashp)
break;
*outPathp++ = *inPathp++;
}
size_t cb;
afs_uint32 type = *inp++;
- /*
+ /*
* The first byte specifies the type of the input string.
* CIFS TR 1.0 3.2.10. This function only parses null terminated
* strings.
{
int tlen;
- if (*inp++ != 0x5)
+ if (*inp++ != 0x5)
return NULL;
tlen = inp[0] + (inp[1]<<8);
inp += 2; /* skip length field */
if (chainpp) {
*chainpp = inp + tlen;
}
-
- if (lengthp)
+
+ if (lengthp)
*lengthp = tlen;
-
+
return inp;
-}
+}
unsigned char *smb_ParseDataBlock(unsigned char *inp, char **chainpp, int *lengthp)
{
if (*inp++ != 0x1) return NULL;
tlen = inp[0] + (inp[1]<<8);
inp += 2; /* skip length field */
-
+
if (chainpp) {
*chainpp = inp + tlen;
- }
+ }
if (lengthp) *lengthp = tlen;
-
+
return inp;
}
smb_t *inSmbp;
outp = (smb_t *) op;
-
+
/* zero the basic structure through the smb_wct field, and zero the data
- * size field, assuming that wct stays zero; otherwise, you have to
+ * size field, assuming that wct stays zero; otherwise, you have to
* explicitly set the data size field, too.
*/
inSmbp = (smb_t *) inp;
/* copy fields in generic packet area */
op->wctp = &outp->wct;
-}
+}
/* send a (probably response) packet; vcp tells us to whom to send it.
* we compute the length by looking at wct and bcc fields.
long code = 0;
unsigned char *tp;
int localNCB = 0;
-
+
ncbp = inp->ncbp;
if (ncbp == NULL) {
ncbp = smb_GetNCB();
localNCB = 1;
}
-
- memset((char *)ncbp, 0, sizeof(NCB));
+
+ memset(ncbp, 0, sizeof(NCB));
extra = 2 * (*inp->wctp); /* space used by parms, in bytes */
tp = inp->wctp + 1+ extra; /* points to count of data bytes */
extra += tp[0] + (tp[1]<<8);
extra += (unsigned int)(inp->wctp - inp->data); /* distance to last wct field */
extra += 3; /* wct and length fields */
-
+
ncbp->ncb_length = extra; /* bytes to send */
ncbp->ncb_lsn = (unsigned char) vcp->lsn; /* vc to use */
ncbp->ncb_lana_num = vcp->lana;
ncbp->ncb_command = NCBSEND; /* op means send data */
ncbp->ncb_buffer = (char *) inp;/* packet */
code = Netbios(ncbp);
-
+
if (code != 0) {
const char * s = ncb_error_string(code);
osi_Log2(smb_logp, "SendPacket failure code %d \"%s\"", code, s);
/* NT Status codes are listed in ntstatus.h not winerror.h */
if (code == 0) {
NTStatus = 0;
- }
+ }
else if (code == CM_ERROR_NOSUCHCELL) {
- NTStatus = 0xC000000FL; /* No such file */
+ NTStatus = 0xC0000034L; /* Name not found */
}
else if (code == CM_ERROR_NOSUCHVOLUME) {
- NTStatus = 0xC000000FL; /* No such file */
+ NTStatus = 0xC0000034L; /* Name not found */
}
else if (code == CM_ERROR_TIMEDOUT) {
#ifdef COMMENT
NTStatus = 0xC00000CFL; /* Sharing Paused */
-#else
+
+ /* Do not send Timeout to the SMB redirector.
+ * It causes the redirector to drop the connection */
NTStatus = 0x00000102L; /* Timeout */
+ /* do not send Retry to the SMB redirector.
+ * It believes the error comes from the transport
+ * layer not from the SMB server. */
+ NTStatus = 0xC000022DL; /* Retry */
+#else
+ NTStatus = 0xC00000B5L; /* I/O Timeout */
#endif
}
else if (code == CM_ERROR_RETRY) {
+#ifdef COMMENT
NTStatus = 0xC000022DL; /* Retry */
+#else
+ NTStatus = 0xC00000B5L; /* I/O Timeout */
+#endif
}
else if (code == CM_ERROR_NOACCESS) {
NTStatus = 0xC0000022L; /* Access denied */
}
else if (code == CM_ERROR_NOSUCHFILE ||
code == CM_ERROR_BPLUS_NOMATCH) {
- NTStatus = 0xC000000FL; /* No such file */
+ NTStatus = 0xC0000034L; /* Name not found */
}
else if (code == CM_ERROR_NOSUCHPATH) {
NTStatus = 0xC000003AL; /* Object path not found */
- }
+ }
else if (code == CM_ERROR_TOOBIG) {
NTStatus = 0xC000007BL; /* Invalid image format */
}
else if (code == CM_ERROR_BADFDOP) {
NTStatus = 0xC0000022L; /* Access denied */
}
+ else if (code == CM_ERROR_UNKNOWN) {
+ NTStatus = 0xC0000022L; /* Access denied */
+ }
else if (code == CM_ERROR_EXISTS) {
NTStatus = 0xC0000035L; /* Object name collision */
}
else if (code == CM_ERROR_NOTEMPTY) {
NTStatus = 0xC0000101L; /* Directory not empty */
- }
+ }
else if (code == CM_ERROR_CROSSDEVLINK) {
NTStatus = 0xC00000D4L; /* Not same device */
}
else if (code == CM_ERROR_NOIPC) {
#ifdef COMMENT
NTStatus = 0xC0000022L; /* Access Denied */
-#else
+#else
NTStatus = 0xC000013DL; /* Remote Resources */
#endif
}
- else if (code == CM_ERROR_CLOCKSKEW) {
+ else if (code == CM_ERROR_CLOCKSKEW ||
+ code == RXKADNOAUTH) {
NTStatus = 0xC0000133L; /* Time difference at DC */
}
else if (code == CM_ERROR_BADTID) {
else if (code == CM_ERROR_BUFFERTOOSMALL) {
NTStatus = 0xC0000023L; /* Buffer too small */
}
+ else if (code == CM_ERROR_BUFFER_OVERFLOW) {
+ NTStatus = 0x80000005L; /* Buffer overflow */
+ }
else if (code == CM_ERROR_AMBIGUOUS_FILENAME) {
NTStatus = 0xC0000035L; /* Object name collision */
- }
+ }
else if (code == CM_ERROR_BADPASSWORD) {
NTStatus = 0xC000006DL; /* unknown username or bad password */
}
}
else if (code == CM_ERROR_PATH_NOT_COVERED) {
NTStatus = 0xC0000257L; /* Path Not Covered */
- }
+ }
else if (code == CM_ERROR_ALLBUSY) {
+#ifdef COMMENT
NTStatus = 0xC000022DL; /* Retry */
- }
+#else
+ NTStatus = 0xC0020018L; /* RPC_NT_SERVER_TOO_BUSY */
+#endif
+ }
else if (code == CM_ERROR_ALLOFFLINE || code == CM_ERROR_ALLDOWN) {
+#ifdef COMMENT
NTStatus = 0xC000003AL; /* Path not found */
- }
+#else
+ NTStatus = 0xC0020017L; /* RPC_NT_SERVER_UNAVAILABLE */
+#endif
+ }
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 if (code == CM_ERROR_RANGE_NOT_LOCKED) {
NTStatus = 0xC000007EL; /* Range Not Locked */
- }
+ }
else if (code == CM_ERROR_NOSUCHDEVICE) {
NTStatus = 0xC000000EL; /* No Such Device */
}
*NTStatusp = NTStatus;
osi_Log2(smb_logp, "SMB SEND code %lX as NT %lX", code, NTStatus);
-}
+}
-/*
- * NTSTATUS <-> Win32 Error Translation
- * http://support.microsoft.com/kb/113996
+/*
+ * NTSTATUS <-> Win32 Error Translation
+ * http://support.microsoft.com/kb/113996
*/
void smb_MapWin32Error(long code, unsigned long *Win32Ep)
{
/* map CM_ERROR_* errors to Win32 32-bit error codes */
if (code == 0) {
Win32E = 0;
- }
+ }
else if (code == CM_ERROR_NOSUCHCELL) {
Win32E = ERROR_FILE_NOT_FOUND; /* No such file */
}
}
else if (code == CM_ERROR_NOSUCHPATH) {
Win32E = ERROR_PATH_NOT_FOUND; /* Object path not found */
- }
+ }
else if (code == CM_ERROR_TOOBIG) {
Win32E = ERROR_BAD_EXE_FORMAT; /* Invalid image format */
}
else if (code == CM_ERROR_BADFDOP) {
Win32E = ERROR_ACCESS_DENIED; /* Access denied */
}
+ else if (code == CM_ERROR_UNKNOWN) {
+ Win32E = ERROR_ACCESS_DENIED; /* Access denied */
+ }
else if (code == CM_ERROR_EXISTS) {
Win32E = ERROR_ALREADY_EXISTS; /* Object name collision */
}
else if (code == CM_ERROR_NOTEMPTY) {
Win32E = ERROR_DIR_NOT_EMPTY; /* Directory not empty */
- }
+ }
else if (code == CM_ERROR_CROSSDEVLINK) {
Win32E = ERROR_NOT_SAME_DEVICE; /* Not same device */
}
else if (code == CM_ERROR_NOIPC) {
#ifdef COMMENT
Win32E = ERROR_ACCESS_DENIED; /* Access Denied */
-#else
+#else
Win32E = ERROR_REM_NOT_LIST; /* Remote Resources */
#endif
}
- else if (code == CM_ERROR_CLOCKSKEW) {
+ else if (code == CM_ERROR_CLOCKSKEW ||
+ code == RXKADNOAUTH) {
Win32E = ERROR_TIME_SKEW; /* Time difference at DC */
}
else if (code == CM_ERROR_BADTID) {
}
else if (code == CM_ERROR_AMBIGUOUS_FILENAME) {
Win32E = ERROR_ALREADY_EXISTS; /* Object name collision */
- }
+ }
else if (code == CM_ERROR_BADPASSWORD) {
Win32E = ERROR_LOGON_FAILURE; /* unknown username or bad password */
}
}
else if (code == CM_ERROR_PATH_NOT_COVERED) {
Win32E = ERROR_HOST_UNREACHABLE; /* Path Not Covered */
- }
+ }
else if (code == CM_ERROR_ALLBUSY) {
Win32E = ERROR_RETRY; /* Retry */
- }
+ }
else if (code == CM_ERROR_ALLOFFLINE || code == CM_ERROR_ALLDOWN) {
Win32E = ERROR_HOST_UNREACHABLE; /* Path not found */
- }
+ }
else if (code >= ERROR_TABLE_BASE_RXK && code < ERROR_TABLE_BASE_RXK + 256) {
Win32E = SEC_E_NO_KERB_KEY; /* No Kerberos key */
- }
+ }
else if (code == CM_ERROR_BAD_LEVEL) {
Win32E = ERROR_INVALID_LEVEL; /* Invalid Level */
- }
+ }
else if (code == CM_ERROR_RANGE_NOT_LOCKED) {
Win32E = ERROR_NOT_LOCKED; /* Range Not Locked */
- }
+ }
else if (code == CM_ERROR_NOSUCHDEVICE) {
Win32E = ERROR_FILE_NOT_FOUND; /* No Such Device */
}
*Win32Ep = Win32E;
osi_Log2(smb_logp, "SMB SEND code %lX as Win32 %lX", code, Win32E);
-}
+}
void smb_MapCoreError(long code, smb_vc_t *vcp, unsigned short *scodep,
unsigned char *classp)
else if (code == CM_ERROR_ISDIR) {
class = 1; /* access denied; DOS doesn't have a good match */
error = 5;
- }
+ }
else if (code == CM_ERROR_BADOP) {
class = 2;
error = 65535;
*scodep = error;
*classp = class;
osi_Log3(smb_logp, "SMB SEND code %lX as SMB %d: %d", code, class, error);
-}
+}
long smb_SendCoreBadOp(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
if (*inp->wctp == 10) {
/* we were sent a request with 64-bit file offsets */
-#ifdef AFS_LARGEFILES
offset.HighPart = smb_GetSMBParm(inp, 8) | (smb_GetSMBParm(inp, 9) << 16);
if (LargeIntegerLessThanZero(offset)) {
osi_Log0(smb_logp, "smb_ReceiveCoreReadRaw received negative 64-bit offset");
goto send1;
}
-#else
- if ((smb_GetSMBParm(inp, 8) | (smb_GetSMBParm(inp, 9) << 16)) != 0) {
- osi_Log0(smb_logp, "smb_ReceiveCoreReadRaw received 64-bit file offset. Dropping request.");
- goto send1;
- } else {
- offset.HighPart = 0;
- }
-#endif
} else {
/* we were sent a request with 32-bit file offsets */
offset.HighPart = 0;
fd, offset.HighPart, offset.LowPart, count);
fidp = smb_FindFID(vcp, fd, 0);
- if (!fidp)
+ if (!fidp) {
+ osi_Log2(smb_logp, "smb_ReceiveCoreReadRaw Unknown SMB Fid vcp 0x%p fid %d",
+ vcp, fd);
goto send1;
-
+ }
lock_ObtainMutex(&fidp->mx);
if (!fidp->scp) {
lock_ReleaseMutex(&fidp->mx);
lock_ObtainWrite(&fidp->scp->rw);
code = cm_LockCheckRead(fidp->scp, LOffset, LLength, key);
lock_ReleaseWrite(&fidp->scp->rw);
- }
+ }
if (code) {
lock_ReleaseMutex(&fidp->mx);
goto send1a;
/* Give back raw buffer */
lock_ObtainMutex(&smb_RawBufLock);
*((char **) rawBuf) = smb_RawBufs;
-
+
smb_RawBufs = rawBuf;
lock_ReleaseMutex(&smb_RawBufLock);
}
send1:
ncbp = outp->ncbp;
- memset((char *)ncbp, 0, sizeof(NCB));
+ memset(ncbp, 0, sizeof(NCB));
ncbp->ncb_length = (unsigned short) finalCount;
ncbp->ncb_lsn = (unsigned char) vcp->lsn;
*/
if (strcmp("PC NETWORK PROGRAM 1.0", namep+1) == 0) {
coreProtoIndex = tcounter;
- }
+ }
else if (smb_useV3 && strcmp("LM1.2X002", namep+1) == 0) {
v3ProtoIndex = tcounter;
}
if (VistaProtoIndex != -1) {
protoIndex = VistaProtoIndex;
vcp->flags |= (SMB_VCFLAG_USENT | SMB_VCFLAG_USEV3);
- } else
-#endif
+ } else
+#endif
if (NTProtoIndex != -1) {
protoIndex = NTProtoIndex;
vcp->flags |= (SMB_VCFLAG_USENT | SMB_VCFLAG_USEV3);
else if (v3ProtoIndex != -1) {
protoIndex = v3ProtoIndex;
vcp->flags |= SMB_VCFLAG_USEV3;
- }
+ }
else if (coreProtoIndex != -1) {
protoIndex = coreProtoIndex;
vcp->flags |= SMB_VCFLAG_USECORE;
- }
+ }
else protoIndex = -1;
lock_ReleaseMutex(&vcp->mx);
/* The session key is not a well documented field however most clients
* will echo back the session key to the server. Currently we are using
* the same value for all sessions. We should generate a random value
- * and store it into the vcp
+ * and store it into the vcp
*/
- smb_SetSMBParm(outp, 7, 1); /* next 2: session key */
- smb_SetSMBParm(outp, 8, 1);
- /*
+ smb_SetSMBParmLong(outp, 7, 0x1a2b3c4d); /* session key */
+ /*
* Tried changing the capabilities to support for W2K - defect 117695
* Maybe something else needs to be changed here?
*/
/*
- if (isWindows2000)
+ if (isWindows2000)
smb_SetSMBParmLong(outp, 9, 0x43fd);
- else
+ else
smb_SetSMBParmLong(outp, 9, 0x251);
*/
/* Capabilities: *
* 32-bit error codes *
* and NT Find *
* and NT SMB's *
- * and raw mode
+ * and raw mode
* and DFS
* and Unicode */
caps = NTNEGOTIATE_CAPABILITY_NTSTATUS |
#ifdef DFS_SUPPORT
NTNEGOTIATE_CAPABILITY_DFS |
#endif
-#ifdef AFS_LARGEFILES
NTNEGOTIATE_CAPABILITY_LARGEFILES |
-#endif
NTNEGOTIATE_CAPABILITY_NTFIND |
NTNEGOTIATE_CAPABILITY_RAWMODE |
NTNEGOTIATE_CAPABILITY_NTSMB;
smb_SetSMBParmLong(outp, 9, caps);
time(&unixTime);
- smb_SearchTimeFromUnixTime(&dosTime, unixTime);
+ cm_SearchTimeFromUnixTime(&dosTime, unixTime);
smb_SetSMBParmLong(outp, 11, LOWORD(dosTime));/* server time */
smb_SetSMBParmLong(outp, 13, HIWORD(dosTime));/* server date */
smb_NegotiateExtendedSecurity(&secBlob, &secBlobLength);
smb_SetSMBDataLength(outp, secBlobLength + sizeof(smb_ServerGUID));
-
+
datap = smb_GetSMBData(outp, NULL);
memcpy(datap, &smb_ServerGUID, sizeof(smb_ServerGUID));
free(secBlob);
}
} else {
- smb_SetSMBParmByte(outp, 16, 0); /* Encryption key length */
- smb_SetSMBDataLength(outp, 0); /* Perhaps we should specify 8 bytes anyway */
+ smb_SetSMBParmByte(outp, 16, 0);/* Challenge length */
+ smb_SetSMBDataLength(outp, smb_ServerDomainNameLength);
+ datap = smb_GetSMBData(outp, NULL);
+ /* the faux domain name */
+ cm_ClientStringToUtf8(smb_ServerDomainName, -1,
+ datap,
+ (int)(sizeof(outp->data)/sizeof(char) - (datap - outp->data)));
}
}
else if (v3ProtoIndex != -1) {
smb_SetSMBParm(outp, 0, protoIndex);
/* NOTE: Extended authentication cannot be negotiated with v3
- * therefore we fail over to NTLM
+ * therefore we fail over to NTLM
*/
if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) {
smb_SetSMBParm(outp, 1,
smb_SetSMBParm(outp, 6, 1); /* next 2: session key */
smb_SetSMBParm(outp, 7, 1);
time(&unixTime);
- smb_SearchTimeFromUnixTime(&dosTime, unixTime);
+ cm_SearchTimeFromUnixTime(&dosTime, unixTime);
smb_SetSMBParm(outp, 8, LOWORD(dosTime)); /* server time */
smb_SetSMBParm(outp, 9, HIWORD(dosTime)); /* server date */
smb_SetSMBParm(outp, 10, (unsigned short) tzi.Bias); /* server tzone */
/* NOTE: Extended authentication cannot be negotiated with v3
- * therefore we fail over to NTLM
+ * therefore we fail over to NTLM
*/
if (smb_authType == SMB_AUTH_NTLM || smb_authType == SMB_AUTH_EXTENDED) {
smb_SetSMBParm(outp, 11, MSV1_0_CHALLENGE_LENGTH); /* encryption key length */
smb_vc_t * vcp, *nextp;
smb_packet_t * outp = smb_GetPacket();
smb_t *smbp;
-
+
lock_ObtainWrite(&smb_rctLock);
- for ( vcp=smb_allVCsp, nextp=NULL; vcp; vcp = nextp )
+ for ( vcp=smb_allVCsp, nextp=NULL; vcp; vcp = nextp )
{
if (vcp->magic != SMB_VC_MAGIC)
- osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp",
+ osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp",
__FILE__, __LINE__);
/* on the first pass hold 'vcp' which was not held as 'nextp' */
if (vcp != nextp)
smb_HoldVCNoLock(vcp);
- /*
+ /*
* obtain a reference to 'nextp' now because we drop the
- * smb_rctLock later and the list contents could change
+ * smb_rctLock later and the list contents could change
* or 'vcp' could be destroyed when released.
*/
nextp = vcp->nextp;
if (smbShutdownFlag == 1)
break;
-
+
if ((count % 72) == 0) { /* every five minutes */
struct tm myTime;
time_t old_localZero = smb_localZero;
-
+
/* Initialize smb_localZero */
myTime.tm_isdst = -1; /* compute whether on DST or not */
myTime.tm_year = 70;
myTime.tm_sec = 0;
smb_localZero = mktime(&myTime);
-#ifndef USE_NUMERIC_TIME_CONV
- smb_CalculateNowTZ();
-#endif /* USE_NUMERIC_TIME_CONV */
#ifdef AFS_FREELANCE
if ( smb_localZero != old_localZero )
- cm_noteLocalMountPointChange();
+ cm_noteLocalMountPointChange(FALSE);
#endif
smb_CheckVCs();
smb_username_t *unp;
lock_ObtainMutex(&(*unpp)->mx);
- if ( (*unpp)->refCount > 0 ||
- ((*unpp)->flags & SMB_USERNAMEFLAG_AFSLOGON) ||
+ if ( (*unpp)->refCount > 0 ||
+ ((*unpp)->flags & SMB_USERNAMEFLAG_AFSLOGON) ||
!((*unpp)->flags & SMB_USERNAMEFLAG_LOGOFF))
;
else if (!smb_LogoffTokenTransfer ||
if (deleteOk) {
cm_user_t * userp;
- unp = *unpp;
+ unp = *unpp;
*unpp = unp->nextp;
unp->nextp = NULL;
lock_FinalizeMutex(&unp->mx);
}
osi_assertx(wl->state != SMB_WAITINGLOCKSTATE_ERROR, "!SMB_WAITINGLOCKSTATE_ERROR");
-
+
/* wl->state is either _DONE or _WAITING. _ERROR
would no longer be on the queue. */
code = cm_RetryLock( wl->lockp,
for (wl = wlRequest->locks; wl; wl = wlNext) {
wlNext = (smb_waitingLock_t *) osi_QNext(&wl->q);
-
+
if (wl->state == SMB_WAITINGLOCKSTATE_DONE)
- cm_Unlock(scp, wlRequest->lockType, wl->LOffset,
+ cm_Unlock(scp, wlRequest->lockType, wl->LOffset,
wl->LLength, wl->key, 0, NULL, &req);
osi_QRemove((osi_queue_t **) &wlRequest->locks, &wl->q);
free(wl);
}
-
+
lock_ReleaseWrite(&scp->rw);
} else {
/* find last backslash, or use whole thing if there is none */
tp = cm_ClientStrRChr(pathp, '\\');
- if (!tp)
+ if (!tp)
tp = pathp;
- else
+ else
tp++; /* skip slash */
-
+
up = maskp;
/* names starting with a dot are illegal */
- if (*tp == '.')
+ if (*tp == '.')
valid8Dot3 = 0;
for(i=0;; i++) {
tc = *tp++;
- if (tc == 0)
+ if (tc == 0)
return valid8Dot3;
- if (tc == '.' || tc == '"')
+ if (tc == '.' || tc == '"')
break;
- if (i < 8)
+ if (i < 8)
*up++ = tc;
else
valid8Dot3 = 0;
}
-
+
/* if we get here, tp point after the dot */
up = maskp+8; /* ext goes here */
for(i=0;;i++) {
tc = *tp++;
- if (tc == 0)
+ if (tc == 0)
return valid8Dot3;
/* too many dots */
- if (tc == '.' || tc == '"')
+ if (tc == '.' || tc == '"')
valid8Dot3 = 0;
/* copy extension if not too long */
- if (i < 3)
+ if (i < 3)
*up++ = tc;
- else
+ else
valid8Dot3 = 0;
- }
+ }
/* unreachable */
}
/* XXX redo this, calling cm_MatchMask with a converted mask */
valid = smb_Get8Dot3MaskFromPath(umask, unixNamep);
- if (!valid)
+ if (!valid)
return 0;
-
+
/* otherwise, we have a valid 8.3 name; see if we have a match,
* treating '?' as a wildcard in maskp (but not in the file name).
*/
tc2 = *tp2++; /* clientchar_t from mask */
tc1 = (clientchar_t) cm_foldUpper[(clientchar_t)tc1];
tc2 = (clientchar_t) cm_foldUpper[(clientchar_t)tc2];
- if (tc1 == tc2)
+ if (tc1 == tc2)
continue;
- if (tc2 == '?' && tc1 != ' ')
+ if (tc2 == '?' && tc1 != ' ')
continue;
- if (tc2 == '>')
+ if (tc2 == '>')
continue;
return 0;
}
clientchar_t *smb_FindMask(clientchar_t *pathp)
{
clientchar_t *tp;
-
+
tp = cm_ClientStrRChr(pathp, '\\'); /* find last slash */
- if (tp)
+ if (tp)
return tp+1; /* skip the slash */
- else
+ else
return pathp; /* no slash, return the entire path */
-}
+}
/* SMB_COM_SEARCH for a volume label
unsigned char *statBlockp;
unsigned char initStatBlock[21];
int statLen;
-
+
osi_Log0(smb_logp, "SMB receive search volume");
/* pull pathname and stat block out of request */
statBlockp = initStatBlock;
statBlockp[0] = 8;
}
-
+
/* for returning to caller */
smb_Get8Dot3MaskFromPath(mask, pathp);
*/
smb_SetSMBDataLength(outp, 46);
return 0;
-}
+}
-static long
+static long
smb_ApplyDirListPatches(cm_scache_t * dscp, smb_dirListPatch_t **dirPatchespp,
clientchar_t * tidPathp, clientchar_t * relPathp,
cm_user_t *userp, cm_req_t *reqp)
memset(bsp, 0, sizeof(cm_bulkStat_t));
- for (patchp = *dirPatchespp, count=0;
- patchp;
+ for (patchp = *dirPatchespp, count=0;
+ patchp;
patchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q)) {
cm_scache_t *tscp = cm_FindSCache(&patchp->fid);
int i;
break;
default:
/* if we get here we either have a normal file
- * or we have a file for which we have never
+ * or we have a file for which we have never
* received status info. In this case, we can
* check the even/odd value of the entry's vnode.
* odd means it is to be treated as a directory
shortTemp = (unsigned short) ((dosTime>>16) & 0xffff);
*((u_short *)dptr) = shortTemp;
dptr += 2;
-
+
/* copy out file length */
*((u_long *)dptr) = 0;
dptr += 4;
*dptr++ = attr;
/* get dos time */
- smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
-
+ cm_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
+
/* copy out time */
shortTemp = (unsigned short) (dosTime & 0xffff);
*((u_short *)dptr) = shortTemp;
shortTemp = (unsigned short) ((dosTime>>16) & 0xffff);
*((u_short *)dptr) = shortTemp;
dptr += 2;
-
+
/* copy out file length */
*((u_long *)dptr) = scp->length.LowPart;
dptr += 4;
}
cm_ReleaseSCache(scp);
}
-
+
/* now free the patches */
for (patchp = *dirPatchespp; patchp; patchp = npatchp) {
npatchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q);
free(patchp);
- }
-
+ }
+
/* and mark the list as empty */
*dirPatchespp = NULL;
maxCount = smb_GetSMBParm(inp, 0);
dirListPatchesp = NULL;
-
+
caseFold = CM_FLAG_CASEFOLD;
tp = smb_GetSMBData(inp, NULL);
memcpy(dsp->mask, mask, 12);
/* track if this is likely to match a lot of entries */
- if (smb_Is8Dot3StarMask(mask))
+ if (smb_Is8Dot3StarMask(mask))
starPattern = 1;
- else
+ else
starPattern = 0;
} else {
/* pull the next cookie value out of the search status block */
cm_ClientStrCpy(dsp->tidPath, lengthof(dsp->tidPath), tidPathp ? tidPathp : _C("/"));
cm_ClientStrCpy(dsp->relPath, lengthof(dsp->relPath), spacep->wdata);
- code = cm_NameI(cm_data.rootSCachep, spacep->wdata,
+ code = cm_NameI(cm_RootSCachep(userp, &req), spacep->wdata,
caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &scp);
if (code == 0) {
#ifdef DFS_SUPPORT
smb_ReleaseDirSearch(dsp);
return code;
}
-
+
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
dirLength = scp->length;
returnedNames, maxCount);
break;
}
-
+
/* check if we've passed the dir's EOF */
if (LargeIntegerGreaterThanOrEqualTo(curOffset, dirLength)) break;
if (bufferp) {
buf_Release(bufferp);
bufferp = NULL;
- }
+ }
lock_ReleaseWrite(&scp->rw);
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
+ /* now, if we're doing a star match, do bulk fetching of all of
* the status info for files in the dir.
*/
if (starPattern)
osi_Log2(smb_logp, "SMB search dir cm_SyncOp scp %x failed %d", scp, code);
break;
}
-
+
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
if (cm_HaveBuffer(scp, bufferp, 0)) {
/* otherwise, load the buffer and try again */
code = cm_GetBuffer(scp, bufferp, NULL, userp, &req);
if (code) {
- osi_Log3(smb_logp, "SMB search dir cm_GetBuffer failed scp %x bufferp %x code %d",
+ osi_Log3(smb_logp, "SMB search dir cm_GetBuffer failed scp %x bufferp %x code %d",
scp, bufferp, code);
break;
}
osi_assertx(temp == (43 * returnedNames), "unexpected data length");
origOp[1] = (unsigned char)(temp & 0xff);
origOp[2] = (unsigned char)((temp>>8) & 0xff);
- if (returnedNames == 0)
+ if (returnedNames == 0)
smb_DeleteDirSearch(dsp);
smb_ReleaseDirSearch(dsp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
return code;
-}
+}
/* verify that this is a valid path to a directory. I don't know why they
return CM_ERROR_BADSMB;
osi_Log1(smb_logp, "SMB receive check path %S",
osi_LogSaveClientString(smb_logp, pathp));
-
- rootScp = cm_data.rootSCachep;
-
+
userp = smb_GetUserFromVCP(vcp, inp);
+ rootScp = cm_RootSCachep(userp, &req);
+
caseFold = CM_FLAG_CASEFOLD;
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
cm_ReleaseUser(userp);
return code;
}
-
+
#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);
return code;
-}
+}
/* SMB_COM_SET_INFORMATION */
long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
pathp = smb_ParseASCIIBlock(inp, datap, NULL, SMB_STRF_ANSIPATH);
if (!pathp)
return CM_ERROR_BADSMB;
-
+
osi_Log2(smb_logp, "SMB receive setfile attributes time %d, attr 0x%x",
dosTime, attribute);
- rootScp = cm_data.rootSCachep;
-
userp = smb_GetUserFromVCP(vcp, inp);
+ rootScp = cm_RootSCachep(userp, &req);
+
caseFold = CM_FLAG_CASEFOLD;
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
attr.mask |= CM_ATTRMASK_CLIENTMODTIME;
smb_UnixTimeFromDosUTime(&attr.clientModTime, dosTime);
}
- if ((newScp->unixModeBits & 0222) && (attribute & SMB_ATTR_READONLY) != 0) {
+ if ((newScp->unixModeBits & 0200) && (attribute & SMB_ATTR_READONLY) != 0) {
/* we're told to make a writable file read-only */
attr.unixModeBits = newScp->unixModeBits & ~0222;
attr.mask |= CM_ATTRMASK_UNIXMODEBITS;
}
- else if ((newScp->unixModeBits & 0222) == 0 && (attribute & SMB_ATTR_READONLY) == 0) {
+ else if ((newScp->unixModeBits & 0200) == 0 && (attribute & SMB_ATTR_READONLY) == 0) {
/* we're told to make a read-only file writable */
attr.unixModeBits = newScp->unixModeBits | 0222;
attr.mask |= CM_ATTRMASK_UNIXMODEBITS;
code = cm_SetAttr(newScp, &attr, userp, &req);
else
code = 0;
-
+
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
pathp = smb_ParseASCIIBlock(inp, datap, NULL, SMB_STRF_ANSIPATH);
if (!pathp)
return CM_ERROR_BADSMB;
-
+
if (*pathp == 0) /* null path */
pathp = _C("\\");
osi_Log1(smb_logp, "SMB receive getfile attributes path %S",
osi_LogSaveClientString(smb_logp, pathp));
- rootScp = cm_data.rootSCachep;
-
userp = smb_GetUserFromVCP(vcp, inp);
+ rootScp = cm_RootSCachep(userp, &req);
+
/* we shouldn't need this for V3 requests, but we seem to */
caseFold = CM_FLAG_CASEFOLD;
if (dscp->fileType == CM_SCACHETYPE_MOUNTPOINT && !dscp->mountRootFid.volume)
code = CM_ERROR_NOSUCHFILE;
else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) {
- cm_buf_t *bp = buf_Find(dscp, &hzero);
+ cm_buf_t *bp = buf_Find(&dscp->fid, &hzero);
if (bp) {
buf_Release(bp);
bp = NULL;
return code;
}
}
+ else if (code != CM_ERROR_NOSUCHFILE &&
+ code != CM_ERROR_NOSUCHPATH &&
+ code != CM_ERROR_BPLUS_NOMATCH)
+ {
+ cm_ReleaseUser(userp);
+ return code;
+ }
}
#endif /* SPECIAL_FOLDERS */
cm_ReleaseUser(userp);
return code;
}
-
+
#ifdef DFS_SUPPORT
if (newScp->fileType == CM_SCACHETYPE_DFSLINK) {
int pnc = cm_VolStatus_Notify_DFS_Mapping(newScp, tidPathp, pathp);
attrs = smb_Attributes(newScp);
smb_SetSMBParm(outp, 0, attrs);
-
+
smb_DosUTimeFromUnixTime(&dosTime, newScp->clientModTime);
smb_SetSMBParm(outp, 1, (unsigned int)(dosTime & 0xffff));
smb_SetSMBParm(outp, 2, (unsigned int)((dosTime>>16) & 0xffff));
cm_ReleaseUser(userp);
return 0;
-}
+}
/* SMB_COM_TREE_DISCONNECT */
long smb_ReceiveCoreTreeDisconnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
smb_tid_t *tidp;
-
+
osi_Log0(smb_logp, "SMB receive tree disconnect");
/* find the tree and free it */
}
#endif
+ share = smb_GetSMBParm(inp, 0);
+ attribute = smb_GetSMBParm(inp, 1);
+
+ spacep = inp->spacep;
+ /* smb_StripLastComponent will strip "::$DATA" if present */
+ smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
+
if (!cm_IsValidClientString(pathp)) {
#ifdef DEBUG
clientchar_t * hexp;
return CM_ERROR_BADNTFILENAME;
}
- share = smb_GetSMBParm(inp, 0);
- attribute = smb_GetSMBParm(inp, 1);
-
- spacep = inp->spacep;
- smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
if (lastNamep && cm_ClientStrCmp(lastNamep, _C(SMB_IOCTL_FILENAME)) == 0) {
/* special case magic file name for receiving IOCTL requests
* (since IOCTL calls themselves aren't getting through).
cm_ReleaseUser(userp);
return CM_ERROR_NOSUCHPATH;
}
- code = cm_NameI(cm_data.rootSCachep, pathp, caseFold | CM_FLAG_FOLLOW, userp,
+ code = cm_NameI(cm_RootSCachep(userp, &req), pathp, caseFold | CM_FLAG_FOLLOW, userp,
tidPathp, &req, &scp);
-
+
if (code) {
cm_ReleaseUser(userp);
return code;
fidp->flags |= SMB_FID_OPENREAD_LISTDIR;
else if ((share & 0xf) == 1)
fidp->flags |= SMB_FID_OPENWRITE;
- else
+ else
fidp->flags |= (SMB_FID_OPENREAD_LISTDIR | SMB_FID_OPENWRITE);
/* save the user */
osi_Log2(smb_logp,"smb_ReceiveCoreOpen fidp 0x%p scp 0x%p", fidp, scp);
lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
-
+
smb_SetSMBParm(outp, 0, fidp->fid);
smb_SetSMBParm(outp, 1, smb_Attributes(scp));
smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime);
smb_SetSMBDataLength(outp, 0);
lock_ReleaseMutex(&fidp->mx);
lock_ReleaseRead(&scp->rw);
-
+
/* notify open */
cm_Open(scp, 0, userp);
int caseFold;
int match;
normchar_t matchName[MAX_PATH];
-
+
rockp = vrockp;
caseFold = ((rockp->flags & SMB_MASKFLAG_CASEFOLD)? CM_FLAG_CASEFOLD : 0);
memset(&rock, 0, sizeof(rock));
attribute = smb_GetSMBParm(inp, 0);
-
+
tp = smb_GetSMBData(inp, NULL);
pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
if (!pathp)
cm_ReleaseUser(userp);
return CM_ERROR_NOSUCHPATH;
}
- code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold, userp, tidPathp,
+ code = cm_NameI(cm_RootSCachep(userp, &req), spacep->wdata, caseFold, userp, tidPathp,
&req, &dscp);
if (code) {
cm_ReleaseUser(userp);
return code;
}
-
+
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata);
#endif /* DFS_SUPPORT */
/* otherwise, scp points to the parent directory. */
- if (!lastNamep)
+ if (!lastNamep)
lastNamep = pathp;
- else
+ else
lastNamep++;
rock.any = 0;
rock.vcp = vcp;
rock.matches = NULL;
- /* Now, if we aren't dealing with a wildcard match, we first try an exact
- * match. If that fails, we do a case insensitve match.
+ /* Now, if we aren't dealing with a wildcard match, we first try an exact
+ * match. If that fails, we do a case insensitve match.
*/
if (!(rock.flags & SMB_MASKFLAG_TILDE) &&
!smb_IsStarMask(rock.maskp)) {
rock.flags |= SMB_MASKFLAG_CASEFOLD;
}
}
-
+
if (!rock.any)
code = cm_ApplyDir(dscp, smb_UnlinkProc, &rock, &thyper, userp, &req, NULL);
-
- if (code == CM_ERROR_STOPNOW)
+
+ if (code == CM_ERROR_STOPNOW)
code = 0;
if (code == 0 && rock.matches) {
done:
if (userp)
cm_ReleaseUser(userp);
-
+
if (dscp)
cm_ReleaseSCache(dscp);
if (code == 0 && !rock.any)
code = CM_ERROR_NOSUCHFILE;
return code;
-}
+}
typedef struct smb_renameRock {
cm_scache_t *odscp; /* old dir */
}
-long
+long
smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, clientchar_t * oldPathp, clientchar_t * newPathp, int attrs)
{
long code = 0;
smb_StripLastComponent(spacep->wdata, &oldLastNamep, oldPathp);
caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD;
- code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold,
+ code = cm_NameI(cm_RootSCachep(userp, &req), spacep->wdata, caseFold,
userp, tidPathp, &req, &oldDscp);
if (code) {
cm_ReleaseUser(userp);
return code;
}
-
+
#ifdef DFS_SUPPORT
if (oldDscp->fileType == CM_SCACHETYPE_DFSLINK) {
int pnc = cm_VolStatus_Notify_DFS_Mapping(oldDscp, tidPathp, spacep->wdata);
#endif /* DFS_SUPPORT */
smb_StripLastComponent(spacep->wdata, &newLastNamep, newPathp);
- code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold,
+ code = cm_NameI(cm_RootSCachep(userp, &req), spacep->wdata, caseFold,
userp, tidPathp, &req, &newDscp);
if (code) {
*/
/* handle the old name first */
- if (!oldLastNamep)
+ if (!oldLastNamep)
oldLastNamep = oldPathp;
- else
+ else
oldLastNamep++;
/* and handle the new name, too */
- if (!newLastNamep)
+ if (!newLastNamep)
newLastNamep = newPathp;
- else
+ else
newLastNamep++;
/* TODO: The old name could be a wildcard. The new name must not be */
/* Check if the file already exists; if so return error */
code = cm_Lookup(newDscp,newLastNamep,CM_FLAG_CHECKPATH,userp,&req,&tmpscp);
if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_BPLUS_NOMATCH) &&
- (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) )
+ (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) )
{
osi_Log2(smb_logp, " lookup returns %ld for [%S]", code,
osi_LogSaveClientString(smb_logp, newLastNamep));
/* Check if the old and the new names differ only in case. If so return
- * success, else return CM_ERROR_EXISTS
+ * success, else return CM_ERROR_EXISTS
*/
if (!code && oldDscp == newDscp && !cm_ClientStrCmpI(oldLastNamep, newLastNamep)) {
/* This would be a success only if the old file is *as same as* the new file */
code = cm_Lookup(oldDscp, oldLastNamep, CM_FLAG_CHECKPATH, userp, &req, &tmpscp2);
if (!code) {
- if (tmpscp == tmpscp2)
+ if (tmpscp == tmpscp2)
code = 0;
- else
+ else
code = CM_ERROR_EXISTS;
cm_ReleaseSCache(tmpscp2);
tmpscp2 = NULL;
}
done:
- if (tmpscp != NULL)
+ if (tmpscp != NULL)
cm_ReleaseSCache(tmpscp);
if (userp)
cm_ReleaseUser(userp);
free(rock.maskp);
return code;
-}
+}
-long
-smb_Link(smb_vc_t *vcp, smb_packet_t *inp, clientchar_t * oldPathp, clientchar_t * newPathp)
+long
+smb_Link(smb_vc_t *vcp, smb_packet_t *inp, clientchar_t * oldPathp, clientchar_t * newPathp)
{
long code = 0;
cm_space_t *spacep = NULL;
spacep = inp->spacep;
smb_StripLastComponent(spacep->wdata, &oldLastNamep, oldPathp);
-
- code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold,
+
+ code = cm_NameI(cm_RootSCachep(userp, &req), spacep->wdata, caseFold,
userp, tidPathp, &req, &oldDscp);
if (code) {
cm_ReleaseUser(userp);
return code;
}
-
+
#ifdef DFS_SUPPORT
if (oldDscp->fileType == CM_SCACHETYPE_DFSLINK) {
int pnc = cm_VolStatus_Notify_DFS_Mapping(oldDscp, tidPathp, spacep->wdata);
#endif /* DFS_SUPPORT */
smb_StripLastComponent(spacep->wdata, &newLastNamep, newPathp);
- code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold,
+ code = cm_NameI(cm_RootSCachep(userp, &req), spacep->wdata, caseFold,
userp, tidPathp, &req, &newDscp);
if (code) {
cm_ReleaseSCache(oldDscp);
}
/* handle the old name first */
- if (!oldLastNamep)
+ if (!oldLastNamep)
oldLastNamep = oldPathp;
- else
+ else
oldLastNamep++;
/* and handle the new name, too */
- if (!newLastNamep)
+ if (!newLastNamep)
newLastNamep = newPathp;
- else
+ else
newLastNamep++;
/* now lookup the old name */
/* Check if the file already exists; if so return error */
code = cm_Lookup(newDscp,newLastNamep,CM_FLAG_CHECKPATH,userp,&req,&tmpscp);
- if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_BPLUS_NOMATCH) &&
- (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) )
+ if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_BPLUS_NOMATCH) &&
+ (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) )
{
osi_Log2(smb_logp, " lookup returns %ld for [%S]", code,
osi_LogSaveClientString(smb_logp, newLastNamep));
cm_ReleaseSCache(newDscp);
cm_ReleaseSCache(oldDscp);
cm_ReleaseUser(userp);
- return code;
+ return code;
}
/* now create the hardlink */
NULL, TRUE);
}
- if (tmpscp != NULL)
+ if (tmpscp != NULL)
cm_ReleaseSCache(tmpscp);
cm_ReleaseUser(userp);
cm_ReleaseSCache(sscp);
}
/* SMB_COM_RENAME */
-long
+long
smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
clientchar_t *oldPathp;
} smb_rmdirRock_t;
int smb_RmdirProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp)
-{
+{
long code = 0;
smb_rmdirRock_t *rockp;
int match;
normchar_t matchName[MAX_PATH];
-
+
rockp = (smb_rmdirRock_t *) vrockp;
if (cm_FsStringToNormString(dep->name, -1, matchName, lengthof(matchName)) == 0) {
!cm_Is8Dot3(matchName)) {
cm_Gen8Dot3Name(dep, matchName, NULL);
match = (cm_ClientStrCmpI(matchName, rockp->maskp) == 0);
- }
+ }
if (match) {
rockp->any = 1;
cm_ReleaseUser(userp);
return CM_ERROR_NOSUCHPATH;
}
- code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold | CM_FLAG_FOLLOW,
+ code = cm_NameI(cm_RootSCachep(userp, &req), spacep->wdata, caseFold | CM_FLAG_FOLLOW,
userp, tidPathp, &req, &dscp);
if (code) {
cm_ReleaseUser(userp);
return code;
}
-
+
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata);
#endif /* DFS_SUPPORT */
/* otherwise, scp points to the parent directory. */
- if (!lastNamep)
+ if (!lastNamep)
lastNamep = pathp;
- else
+ else
lastNamep++;
-
+
rock.any = 0;
rock.maskp = cm_ClientStringToNormStringAlloc(lastNamep, -1, NULL);
if (!rock.maskp) {
if (userp)
cm_ReleaseUser(userp);
-
+
if (dscp)
cm_ReleaseSCache(dscp);
if (code == 0 && !rock.any)
- code = CM_ERROR_NOSUCHFILE;
+ code = CM_ERROR_NOSUCHFILE;
if (rock.maskp)
free(rock.maskp);
fid = smb_ChainFID(fid, inp);
fidp = smb_FindFID(vcp, fid, 0);
- if (!fidp)
+ if (!fidp) {
+ osi_Log2(smb_logp, "smb_ReceiveCoreFlush Unknown SMB Fid vcp 0x%p fid %d",
+ vcp, fid);
return CM_ERROR_BADFD;
-
+ }
userp = smb_GetUserFromVCP(vcp, inp);
lock_ObtainMutex(&fidp->mx);
cm_scache_t * scp = fidp->scp;
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
- code = cm_FSync(scp, userp, &req);
+ code = cm_FSync(scp, userp, &req, FALSE);
cm_ReleaseSCache(scp);
} else {
lock_ReleaseMutex(&fidp->mx);
code = 0;
}
-
+
cm_ReleaseUser(userp);
- smb_ReleaseFID(fidp);
+ smb_ReleaseFID(fidp);
return code;
}
rock.name = pathp;
rock.vnode = scp;
- code = cm_ApplyDir(dscp, smb_FullNameProc, &rock, NULL, userp, reqp, NULL);
+ code = cm_ApplyDir(dscp, smb_FullNameProc, &rock, NULL, userp, reqp, NULL);
if (code == CM_ERROR_STOPNOW) {
*newPathp = rock.fullName;
*originalPathp = rock.originalName;
osi_Log0(smb_logp, " No user specified. Not closing fid");
return CM_ERROR_BADFD;
}
-
+
userp = fidp->userp; /* no hold required since fidp is held
throughout the function */
lock_ReleaseMutex(&fidp->mx);
lock_ObtainWrite(&smb_rctLock);
if (fidp->deleteOk) {
osi_Log0(smb_logp, " Fid already closed.");
- lock_ReleaseWrite(&smb_rctLock);
+ lock_ReleaseWrite(&smb_rctLock);
return CM_ERROR_BADFD;
}
fidp->deleteOk = 1;
lock_ObtainMutex(&fidp->mx);
if (fidp->NTopen_dscp) {
- dscp = fidp->NTopen_dscp;
+ dscp = fidp->NTopen_dscp;
cm_HoldSCache(dscp);
}
(fidp->flags & (SMB_FID_OPENWRITE | SMB_FID_DELONCLOSE))
== SMB_FID_OPENWRITE) {
if (dosTime != 0 && dosTime != -1) {
+ lock_ObtainWrite(&fidp->scp->rw);
scp->mask |= CM_SCACHEMASK_CLIENTMODTIME;
/* This fixes defect 10958 */
CompensateForSmbClientLastWriteTimeBugs(&dosTime);
smb_UnixTimeFromDosUTime(&scp->clientModTime, dosTime);
+ lock_ReleaseWrite(&fidp->scp->rw);
}
if (smb_AsyncStore != 2) {
lock_ReleaseMutex(&fidp->mx);
- code = cm_FSync(scp, userp, &req);
+ code = cm_FSync(scp, userp, &req, FALSE);
lock_ObtainMutex(&fidp->mx);
}
}
- else
+ else
code = 0;
/* unlock any pending locks */
}
} else {
code = cm_Unlink(dscp, originalNamep, fullPathp, userp, &req);
- if (code == 0) {
+ if (code == 0) {
if (dscp->flags & CM_SCACHEFLAG_ANYWATCH)
smb_NotifyChange(FILE_ACTION_REMOVED,
FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION,
fid = smb_ChainFID(fid, inp);
fidp = smb_FindFID(vcp, fid, 0);
if (!fidp) {
+ osi_Log2(smb_logp, "smb_ReceiveCoreClose Unknown SMB Fid vcp 0x%p fid %d",
+ vcp, fid);
return CM_ERROR_BADFD;
}
-
+
userp = smb_GetUserFromVCP(vcp, inp);
code = smb_CloseFID(vcp, fidp, userp, dosTime);
-
+
smb_ReleaseFID(fidp);
cm_ReleaseUser(userp);
return code;
code = CM_ERROR_BADFD;
goto done2;
}
-
+
smb_InitReq(&req);
bufferp = NULL;
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- if (code)
+ if (code)
goto done;
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
count = 0;
else
count = thyper.LowPart;
- }
+ }
*readp = count;
code = cm_SyncOp(scp, bufferp, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK |
CM_SCACHESYNC_READ);
- if (code)
+ if (code)
goto done;
-
+
cm_SyncOpDone(scp, bufferp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
if (cm_HaveBuffer(scp, bufferp, 0)) break;
/* now copy the data */
memcpy(op, bufferp->datap + bufIndex, nbytes);
-
+
/* adjust counters, pointers, etc. */
op += nbytes;
count -= nbytes;
osi_hyper_t writeBackOffset;/* offset of region to write back when I/O is done */
DWORD filter = 0;
cm_req_t req;
+ int needSyncOpDone = 0;
osi_Log3(smb_logp, "smb_WriteData fid %d, off 0x%x, size 0x%x",
fidp->fid, offsetp->LowPart, count);
code = CM_ERROR_BADFDOP;
goto done2;
}
-
+
smb_InitReq(&req);
scp = fidp->scp;
CM_SCACHESYNC_NEEDCALLBACK
| CM_SCACHESYNC_SETSTATUS
| CM_SCACHESYNC_GETSTATUS);
- if (code)
+ if (code)
goto done;
-
+
cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_GETSTATUS);
/* now we have the entry locked, look up the length */
* different storeback windows, remember to store back the previous
* storeback window when we're done with the write.
*
- * the purpose of this logic is to slow down the CIFS client
+ * the purpose of this logic is to slow down the CIFS client
* in order to avoid the client disconnecting during the CLOSE
* operation if there are too many dirty buffers left to write
* than can be accomplished during 45 seconds. This used to be
* based upon cm_chunkSize but we desire cm_chunkSize to be large
* so that we can read larger amounts of data at a time.
*/
- if (smb_AsyncStore == 1 &&
+ if (smb_AsyncStore == 1 &&
(thyper.LowPart & ~(smb_AsyncStoreSize-1)) !=
(offset.LowPart & ~(smb_AsyncStoreSize-1))) {
/* they're different */
/* now, copy the data one buffer at a time, until we've filled the
* request packet */
- while (1) {
- /* if we've copied all the data requested, we're done */
- if (count <= 0)
- break;
+ while (count != 0) {
/* handle over quota or out of space */
if (scp->flags & (CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE)) {
if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) {
/* wrong buffer */
if (bufferp) {
+ if (needSyncOpDone) {
+ cm_SyncOpDone(scp, bufferp,
+ CM_SCACHESYNC_NEEDCALLBACK
+ | CM_SCACHESYNC_WRITE
+ | CM_SCACHESYNC_BUFLOCKED);
+ needSyncOpDone = 0;
+ }
lock_ReleaseMutex(&bufferp->mx);
buf_Release(bufferp);
bufferp = NULL;
- }
+ }
lock_ReleaseWrite(&scp->rw);
code = buf_Get(scp, &thyper, &req, &bufferp);
bufferOffset = thyper;
/* now get the data in the cache */
- while (1) {
- code = cm_SyncOp(scp, bufferp, userp, &req, 0,
- CM_SCACHESYNC_NEEDCALLBACK
- | CM_SCACHESYNC_WRITE
- | CM_SCACHESYNC_BUFLOCKED);
- if (code)
- goto done;
-
- cm_SyncOpDone(scp, bufferp,
- CM_SCACHESYNC_NEEDCALLBACK
- | CM_SCACHESYNC_WRITE
- | CM_SCACHESYNC_BUFLOCKED);
+ while (code == 0) {
+ if (!needSyncOpDone) {
+ code = cm_SyncOp(scp, bufferp, userp, &req, 0,
+ CM_SCACHESYNC_NEEDCALLBACK
+ | CM_SCACHESYNC_WRITE
+ | CM_SCACHESYNC_BUFLOCKED);
+ if (code)
+ goto done;
+
+ needSyncOpDone = 1;
+ }
/* If we're overwriting the entire buffer, or
* if we're writing at or past EOF, mark the
* buffer as current so we don't call
* cm_GetBuffer. This skips the fetch from the
- * server in those cases where we're going to
+ * server in those cases where we're going to
* obliterate all the data in the buffer anyway,
* or in those cases where there is no useful
* data at the server to start with.
* Use minLength instead of scp->length, since
* the latter has already been updated by this
* call.
+ *
+ * The scp lock has been dropped multiple times
+ * so the minLength must be refreshed before it
+ * is used.
*/
+
+ minLength = scp->length;
+ if (LargeIntegerGreaterThan(minLength, scp->serverLength))
+ minLength = scp->serverLength;
+
if (LargeIntegerGreaterThanOrEqualTo(bufferp->offset, minLength)
|| LargeIntegerEqualTo(offset, bufferp->offset)
&& (count >= cm_data.buf_blockSize
if (cm_HaveBuffer(scp, bufferp, 1)) break;
/* otherwise, load the buffer and try again */
+ cm_SyncOpDone(scp, bufferp,
+ CM_SCACHESYNC_NEEDCALLBACK
+ | CM_SCACHESYNC_WRITE
+ | CM_SCACHESYNC_BUFLOCKED);
+ needSyncOpDone = 0;
+
lock_ReleaseMutex(&bufferp->mx);
code = cm_GetBuffer(scp, bufferp, NULL, userp,
&req);
lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&bufferp->mx);
lock_ObtainWrite(&scp->rw);
- if (code) break;
}
- if (code) {
- lock_ReleaseMutex(&bufferp->mx);
- buf_Release(bufferp);
- bufferp = NULL;
+ if (code)
goto done;
- }
} /* if (wrong buffer) ... */
/* now we have the right buffer loaded. Copy out the
/* and figure out how many bytes we want from this buffer */
nbytes = cm_data.buf_blockSize - bufIndex; /* what remains in buffer */
- if (nbytes > count)
+ if (nbytes > count)
nbytes = count; /* don't go past end of request */
/* now copy the data */
op += nbytes;
count -= nbytes;
written += nbytes;
- thyper.LowPart = nbytes;
- thyper.HighPart = 0;
- offset = LargeIntegerAdd(thyper, offset);
- } /* while 1 */
+ offset = LargeIntegerAdd(offset, ConvertLongToLargeInteger(nbytes));
+ } /* while count != 0 */
done:
+ if (bufferp && needSyncOpDone) {
+ cm_SyncOpDone(scp, bufferp,
+ CM_SCACHESYNC_NEEDCALLBACK
+ | CM_SCACHESYNC_WRITE
+ | CM_SCACHESYNC_BUFLOCKED);
+ }
+
lock_ReleaseWrite(&scp->rw);
if (bufferp) {
lock_ObtainMutex(&fidp->mx);
if (code == 0 && filter != 0 && (fidp->flags & SMB_FID_NTOPEN)
- && (fidp->NTopen_dscp->flags & CM_SCACHEFLAG_ANYWATCH))
+ && (fidp->NTopen_dscp->flags & CM_SCACHEFLAG_ANYWATCH))
{
lock_ReleaseMutex(&fidp->mx);
smb_NotifyChange(FILE_ACTION_MODIFIED, filter,
fidp->fid, code2);
lock_ReleaseWrite(&scp->rw);
cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart,
- writeBackOffset.HighPart,
+ writeBackOffset.HighPart,
smb_AsyncStoreSize, 0, userp);
/* cm_SyncOpDone is called at the completion of cm_BkgStore */
}
osi_Log3(smb_logp, "smb_ReceiveCoreWrite fid %d, off 0x%x, size 0x%x",
fd, offset.LowPart, count);
-
+
fd = smb_ChainFID(fd, inp);
fidp = smb_FindFID(vcp, fd, 0);
if (!fidp) {
- osi_Log0(smb_logp, "smb_ReceiveCoreWrite fid not found");
+ osi_Log2(smb_logp, "smb_ReceiveCoreWrite Unknown SMB Fid vcp 0x%p fid %d",
+ vcp, fd);
return CM_ERROR_BADFD;
}
-
+
lock_ObtainMutex(&fidp->mx);
if (fidp->flags & SMB_FID_IOCTL) {
lock_ReleaseMutex(&fidp->mx);
cm_req_t req;
osi_Log1(smb_logp, "smb_ReceiveCoreWrite truncation to length 0x%x", offset.LowPart);
-
+
smb_InitReq(&req);
truncAttr.mask = CM_ATTRMASK_LENGTH;
*/
lock_ObtainMutex(&fidp->mx);
if ((fidp->flags & SMB_FID_MTIMESETDONE) != SMB_FID_MTIMESETDONE) {
+ lock_ObtainWrite(&fidp->scp->rw);
fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME;
fidp->scp->clientModTime = time(NULL);
+ lock_ReleaseWrite(&fidp->scp->rw);
}
lock_ReleaseMutex(&fidp->mx);
total_written += written;
written = 0;
}
-
+
osi_Log2(smb_logp, "smb_ReceiveCoreWrite total written 0x%x code 0x%x",
total_written, code);
-
+
/* set the packet data length to 3 bytes for the data block header,
* plus the size of the data.
*/
return;
}
lock_ReleaseMutex(&fidp->mx);
-
+
osi_Log3(smb_logp, "Completing Raw Write offset 0x%x:%08x count %x",
rwcp->offset.HighPart, rwcp->offset.LowPart, rwcp->count);
if (*inp->wctp == 14) {
/* we received a 64-bit file offset */
-#ifdef AFS_LARGEFILES
offset.HighPart = smb_GetSMBParm(inp, 12) | (smb_GetSMBParm(inp, 13) << 16);
if (LargeIntegerLessThanZero(offset)) {
offset.HighPart, offset.LowPart);
return CM_ERROR_BADSMB;
}
-#else
- if ((smb_GetSMBParm(inp, 12) | (smb_GetSMBParm(inp, 13) << 16)) != 0) {
- osi_Log0(smb_logp,
- "smb_ReceiveCoreWriteRaw received 64-bit file offset, but we don't support large files");
- return CM_ERROR_BADSMB;
- }
-
- offset.HighPart = 0;
-#endif
} else {
offset.HighPart = 0; /* 32-bit file offset */
}
-
+
osi_Log4(smb_logp,
"smb_ReceiveCoreWriteRaw fd %d, off 0x%x:%08x, size 0x%x",
fd, offset.HighPart, offset.LowPart, count);
osi_Log1(smb_logp,
" WriteRaw WriteMode 0x%x",
writeMode);
-
+
fd = smb_ChainFID(fd, inp);
fidp = smb_FindFID(vcp, fd, 0);
- if (!fidp)
+ if (!fidp) {
+ osi_Log2(smb_logp, "smb_ReceiveCoreWriteRaw Unknown SMB Fid vcp 0x%p fid %d",
+ vcp, fd);
return CM_ERROR_BADFD;
-
+ }
lock_ObtainMutex(&fidp->mx);
if (!fidp->scp) {
lock_ReleaseMutex(&fidp->mx);
return code;
}
}
-
+
userp = smb_GetUserFromVCP(vcp, inp);
/*
*/
lock_ObtainMutex(&fidp->mx);
if ((fidp->flags & SMB_FID_LOOKSLIKECOPY) != SMB_FID_LOOKSLIKECOPY) {
+ lock_ObtainWrite(&fidp->scp->rw);
fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME;
fidp->scp->clientModTime = time(NULL);
+ lock_ReleaseWrite(&fidp->scp->rw);
}
lock_ReleaseMutex(&fidp->mx);
}
else
code = CM_ERROR_USESTD;
-
+
lock_ReleaseMutex(&smb_RawBufLock);
}
cm_user_t *userp;
cm_scache_t *scp;
char *op;
-
+
fd = smb_GetSMBParm(inp, 0);
count = smb_GetSMBParm(inp, 1);
offset.HighPart = 0; /* too bad */
offset.LowPart = smb_GetSMBParm(inp, 2) | (smb_GetSMBParm(inp, 3) << 16);
-
+
osi_Log3(smb_logp, "smb_ReceiveCoreRead fd %d, off 0x%x, size 0x%x",
fd, offset.LowPart, count);
-
+
fd = smb_ChainFID(fd, inp);
fidp = smb_FindFID(vcp, fd, 0);
- if (!fidp)
+ if (!fidp) {
+ osi_Log2(smb_logp, "smb_ReceiveCoreRead Unknown SMB Fid vcp 0x%p fid %d",
+ vcp, fd);
return CM_ERROR_BADFD;
-
+ }
lock_ObtainMutex(&fidp->mx);
if (fidp->flags & SMB_FID_IOCTL) {
lock_ReleaseMutex(&fidp->mx);
LOffset.LowPart = offset.LowPart;
LLength.HighPart = 0;
LLength.LowPart = count;
-
+
lock_ObtainWrite(&scp->rw);
code = cm_LockCheckRead(scp, LOffset, LLength, key);
lock_ReleaseWrite(&scp->rw);
smb_ReleaseFID(fidp);
return code;
}
-
+
userp = smb_GetUserFromVCP(vcp, inp);
/* remember this for final results */
* plus the size of the data.
*/
smb_SetSMBDataLength(outp, count+3);
-
+
/* get op ptr after putting in the parms, since otherwise we don't
* know where the data really is.
*/
*op++ = 1; /* data block marker */
*op++ = (unsigned char) (count & 0xff);
*op++ = (unsigned char) ((count >> 8) & 0xff);
-
+
code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount);
/* fix some things up */
smb_SetSMBDataLength(outp, finalCount+3);
smb_ReleaseFID(fidp);
-
+
cm_ReleaseUser(userp);
cm_ReleaseSCache(scp);
return code;
smb_InitReq(&req);
scp = NULL;
-
+
/* compute initial mode bits based on read-only flag in attributes */
initialModeBits = 0777;
-
+
tp = smb_GetSMBData(inp, NULL);
pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
if (!pathp)
return CM_ERROR_NOSUCHPATH;
}
- code = cm_NameI(cm_data.rootSCachep, spacep->wdata,
+ code = cm_NameI(cm_RootSCachep(userp, &req), spacep->wdata,
caseFold | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH,
userp, tidPathp, &req, &dscp);
cm_ReleaseUser(userp);
return code;
}
-
+
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata);
/* otherwise, scp points to the parent directory. Do a lookup, and
* fail if we find it. Otherwise, we do the create.
*/
- if (!lastNamep)
+ if (!lastNamep)
lastNamep = pathp;
- else
+ else
lastNamep++;
code = cm_Lookup(dscp, lastNamep, 0, userp, &req, &scp);
if (scp) cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
return code;
}
-
+
setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
setAttr.clientModTime = time(NULL);
+ smb_SetInitialModeBitsForDir(0, &setAttr);
+
code = cm_MakeDir(dscp, lastNamep, 0, &setAttr, userp, &req, NULL);
if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
smb_NotifyChange(FILE_ACTION_ADDED,
FILE_NOTIFY_CHANGE_DIR_NAME,
dscp, lastNamep, NULL, TRUE);
-
+
/* we don't need this any longer */
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
return code;
}
-
+
/* otherwise we succeeded */
smb_SetSMBDataLength(outp, 0);
cm_ReleaseUser(userp);
BOOL smb_IsLegalFilename(clientchar_t *filename)
{
- /*
+ /*
* Find the longest substring of filename that does not contain
* any of the chars in illegalChars. If that substring is less
* than the length of the whole string, then one or more of the
- * illegal chars is in filename.
+ * illegal chars is in filename.
*/
if (cm_ClientStrCSpn(filename, illegalChars) < cm_ClientStrLen(filename))
return FALSE;
cm_scache_t *dscp; /* dir we're dealing with */
cm_scache_t *scp; /* file we're creating */
cm_attr_t setAttr;
- int initialModeBits;
smb_fid_t *fidp;
int attributes;
clientchar_t *lastNamep;
scp = NULL;
excl = (inp->inCom == 0x03)? 0 : 1;
-
+
attributes = smb_GetSMBParm(inp, 0);
dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16);
-
- /* compute initial mode bits based on read-only flag in attributes */
- initialModeBits = 0666;
- if (attributes & SMB_ATTR_READONLY)
- initialModeBits &= ~0222;
-
+
tp = smb_GetSMBData(inp, NULL);
pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
if (!pathp)
return CM_ERROR_BADSMB;
+ spacep = inp->spacep;
+ /* smb_StripLastComponent will strip "::$DATA" if present */
+ smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
+
if (!cm_IsValidClientString(pathp)) {
#ifdef DEBUG
clientchar_t * hexp;
return CM_ERROR_BADNTFILENAME;
}
- spacep = inp->spacep;
- smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
-
userp = smb_GetUserFromVCP(vcp, inp);
caseFold = CM_FLAG_CASEFOLD;
cm_ReleaseUser(userp);
return CM_ERROR_NOSUCHPATH;
}
- code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold | CM_FLAG_FOLLOW,
+ code = cm_NameI(cm_RootSCachep(userp, &req), spacep->wdata, caseFold | CM_FLAG_FOLLOW,
userp, tidPathp, &req, &dscp);
if (code) {
cm_ReleaseUser(userp);
return code;
}
-
+
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata);
/* otherwise, scp points to the parent directory. Do a lookup, and
* truncate the file if we find it, otherwise we create the file.
*/
- if (!lastNamep)
+ if (!lastNamep)
lastNamep = pathp;
- else
+ else
lastNamep++;
if (!smb_IsLegalFilename(lastNamep))
DEBUG_EVENT2("AFS", "CoreCreate H[%s] A[%s]", hexp, lastNamep );
free(hexp);
}
-#endif
+#endif
code = cm_Lookup(dscp, lastNamep, 0, userp, &req, &scp);
if (code && code != CM_ERROR_NOSUCHFILE && code != CM_ERROR_BPLUS_NOMATCH) {
cm_ReleaseUser(userp);
return code;
}
-
+
/* if we get here, if code is 0, the file exists and is represented by
* scp. Otherwise, we have to create it.
*/
else {
setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
smb_UnixTimeFromDosUTime(&setAttr.clientModTime, dosTime);
+ smb_SetInitialModeBitsForFile(attributes, &setAttr);
+
code = cm_Create(dscp, lastNamep, 0, &setAttr, &scp, userp,
&req);
if (code == 0) {
created = 1;
if (dscp->flags & CM_SCACHEFLAG_ANYWATCH)
- smb_NotifyChange(FILE_ACTION_ADDED,
+ smb_NotifyChange(FILE_ACTION_ADDED,
FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION,
dscp, lastNamep, NULL, TRUE);
} else if (!excl && code == CM_ERROR_EXISTS) {
}
}
}
-
+
/* we don't need this any longer */
cm_ReleaseSCache(dscp);
/* now all we have to do is open the file itself */
fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
osi_assertx(fidp, "null smb_fid_t");
-
+
cm_HoldUser(userp);
lock_ObtainMutex(&fidp->mx);
lock_ObtainWrite(&scp->rw);
scp->flags |= CM_SCACHEFLAG_SMB_FID;
lock_ReleaseWrite(&scp->rw);
-
+
/* and the user */
fidp->userp = userp;
lock_ReleaseMutex(&fidp->mx);
cm_req_t req;
smb_InitReq(&req);
-
+
fd = smb_GetSMBParm(inp, 0);
whence = smb_GetSMBParm(inp, 1);
offset = smb_GetSMBParm(inp, 2) | (smb_GetSMBParm(inp, 3) << 16);
-
+
/* try to find the file descriptor */
fd = smb_ChainFID(fd, inp);
fidp = smb_FindFID(vcp, fd, 0);
- if (!fidp)
+ if (!fidp) {
+ osi_Log2(smb_logp, "smb_ReceiveCoreSeek Unknown SMB Fid vcp 0x%p fid %d",
+ vcp, fd);
return CM_ERROR_BADFD;
-
+ }
lock_ObtainMutex(&fidp->mx);
if (!fidp->scp || (fidp->flags & SMB_FID_IOCTL)) {
lock_ReleaseMutex(&fidp->mx);
/* Sanity check */
if (ncbp->ncb_length < offsetof(struct smb, vdata)) {
/* log it and discard it */
- LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_TOO_SHORT,
+ LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_TOO_SHORT,
__FILE__, __LINE__, ncbp->ncb_length);
osi_Log1(smb_logp, "SMB message too short, len %d", ncbp->ncb_length);
return;
outWctp[0] = 0; /* wct of zero */
outWctp[1] = 0; /* and bcc (word) of zero */
outWctp[2] = 0;
- }
+ }
/* once set, stays set. Doesn't matter, since we never chain
* "no response" calls.
smbp = (smb_t *) inp;
osi_Log5(smb_logp,"Dispatch %s mid 0x%x vcp 0x%p lana %d lsn %d",
- opName, smbp->mid, vcp,vcp->lana,vcp->lsn);
+ opName, smbp->mid, vcp, vcp->lana, vcp->lsn);
if (inp->inCom == 0x1d) {
/* Raw Write */
code = smb_ReceiveCoreWriteRaw (vcp, inp, outp, rwcp);
} else {
code = (*(dp->procp)) (vcp, inp, outp);
- }
+ }
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);
+ code, smbp->mid, vcp, vcp->lana, vcp->lsn);
newTime = GetTickCount();
- osi_Log3(smb_logp, "Dispatch %s mid 0x%x duration %d ms",
+ osi_Log3(smb_logp, "Dispatch %s mid 0x%x duration %d ms",
opName, smbp->mid, newTime - oldTime);
#ifdef LOG_PACKET
pathname = inp->stringsp->wdata;
}
- 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,
+ 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,
+ pathname,
afid.cell, afid.volume, afid.vnode, afid.unique);
if (fidp)
}
if (oldGen != sessionGen) {
- LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_WRONG_SESSION,
+ LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_WRONG_SESSION,
newTime - oldTime, ncbp->ncb_length);
osi_Log3(smb_logp, "Request %s straddled session startup, "
"took %d ms, ncb length %d", opName, newTime - oldTime, ncbp->ncb_length);
sprintf(tbuffer, "Received bad SMB req 0x%x", inp->inCom);
code = (*smb_MBfunc)(NULL, tbuffer, "Cancel: don't show again",
MB_OKCANCEL|MB_SERVICE_NOTIFICATION);
- if (code == IDCANCEL)
+ if (code == IDCANCEL)
showErrors = 0;
}
code = CM_ERROR_BADOP;
/* catastrophic failure: log as much as possible */
if (code == CM_ERROR_BADSMB) {
- LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_INVALID,
+ LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_INVALID,
ncbp->ncb_length);
#ifdef LOG_PACKET
smb_LogPacket(inp);
outWctp = outp->wctp;
smbp = (smb_t *) &outp->data;
if (code != CM_ERROR_PARTIALWRITE
- && code != CM_ERROR_BUFFERTOOSMALL
+ && code != CM_ERROR_BUFFERTOOSMALL
&& code != CM_ERROR_GSSCONTINUE) {
/* nuke wct and bcc. For a partial
- * write or an in-process authentication handshake,
+ * write or an in-process authentication handshake,
* assume they're OK.
*/
*outWctp++ = 0;
* parm fields are required, and are
* AndXCommand/AndXReserved and
* AndXOffset. */
- if (tp[0] < 2) break;
+ if (tp[0] < 2) break;
if (tp[1] == 0xff) break; /* no more chained opcodes */
inp->inCom = tp[1];
inp->wctp = inp->data + tp[3] + (tp[4] << 8);
osi_Log0(smb_logp, "Error: smb_ClientWaiter WAIT_IO_COMPLETION\n");
continue;
}
-
+
if (code == WAIT_TIMEOUT)
{
osi_Log1(smb_logp, "Error: smb_ClientWaiter WAIT_TIMEOUT, errno %d\n", GetLastError());
}
idx = code - WAIT_OBJECT_0;
-
+
/* check idx range! */
if (idx < 0 || idx > (sizeof(NCBevents) / sizeof(NCBevents[0])))
{
osi_Log1(smb_logp, "Fatal: NCBevents idx [ %d ] out of range.\n", idx);
osi_assertx(0, "invalid index");
}
-
+
thrd_ResetEvent(NCBevents[idx]);
thrd_SetEvent(NCBreturns[0][idx]);
}
int abandonIdx = code - WAIT_ABANDONED_0;
osi_Log2(smb_logp, "Error: smb_ServerWaiter (SessionEvents) event %d abandoned, errno %d\n", abandonIdx, GetLastError());
}
-
+
if (code == WAIT_IO_COMPLETION)
{
osi_Log0(smb_logp, "Error: smb_ServerWaiter (SessionEvents) WAIT_IO_COMPLETION\n");
continue;
}
-
+
if (code == WAIT_TIMEOUT)
{
osi_Log1(smb_logp, "Error: smb_ServerWaiter (SessionEvents) WAIT_TIMEOUT, errno %d\n", GetLastError());
}
-
+
if (code == WAIT_FAILED)
{
osi_Log1(smb_logp, "Error: smb_ServerWaiter (SessionEvents) WAIT_FAILED, errno %d\n", GetLastError());
}
-
+
idx_session = code - WAIT_OBJECT_0;
/* check idx range! */
code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBavails,
FALSE, INFINITE);
if (code == WAIT_OBJECT_0) {
- if (smbShutdownFlag == 1)
+ if (smbShutdownFlag == 1)
break;
else
goto NCBretry;
int abandonIdx = code - WAIT_ABANDONED_0;
osi_Log2(smb_logp, "Error: smb_ClientWaiter (NCBavails) event %d abandoned, errno %d\n", abandonIdx, GetLastError());
}
-
+
if (code == WAIT_IO_COMPLETION)
{
osi_Log0(smb_logp, "Error: smb_ClientWaiter (NCBavails) WAIT_IO_COMPLETION\n");
continue;
}
-
+
if (code == WAIT_TIMEOUT)
{
osi_Log1(smb_logp, "Error: smb_ClientWaiter (NCBavails) WAIT_TIMEOUT, errno %d\n", GetLastError());
}
-
+
if (code == WAIT_FAILED)
{
osi_Log1(smb_logp, "Error: smb_ClientWaiter (NCBavails) WAIT_FAILED, errno %d\n", GetLastError());
}
-
+
idx_NCB = code - WAIT_OBJECT_0;
/* check idx range! */
}
}
+typedef struct _monitored_task {
+ osi_queue_t q;
+ INT_PTR task_id;
+ LARGE_INTEGER start_time;
+ BOOL started;
+ BOOL trace_timer_hit;
+ BOOL dump_timer_hit;
+} monitored_task;
+
+typedef struct osi_queueHT {
+ osi_queue_t * headp;
+ osi_queue_t * tailp;
+} osi_queueHT_t;
+
+static osi_queue_t *smb_monitored_tasks = NULL;
+static osi_queue_t *smb_free_monitored_tasks = NULL;
+
+static osi_mutex_t _monitor_mx;
+
+static HANDLE h_monitored_task_queue = NULL;
+static HANDLE h_monitored_task_shutdown = NULL;
+
+static time_t smb_last_dump_time = 0;
+
+DWORD smb_monitorReqs = 0;
+
+/* FILETIME comparison fuzz */
+#define MONITOR_FUZZ_TIMEOUT (1 * 10000000i64)
+
+/* Trace timeout is at 60 seconds */
+#define MONITOR_TRACE_TIMEOUT (60 * 10000000i64)
+
+/* Dump timeout is at 120 seconds */
+#define MONITOR_DUMP_TIMEOUT (120 * 10000000i64)
+
+/* Time before another dump is performed in seconds*/
+#define MONITOR_DUMP_RESET_TIMEOUT (600)
+
+static void smb_PurgeOldTaskMonitors(osi_queueHT_t * taskmq)
+{
+ FILETIME now;
+ LARGE_INTEGER earliest;
+ monitored_task * t;
+
+ GetSystemTimeAsFileTime(&now);
+ earliest.LowPart = now.dwLowDateTime;
+ earliest.HighPart = now.dwHighDateTime;
+ earliest.QuadPart -= MONITOR_FUZZ_TIMEOUT + MONITOR_DUMP_TIMEOUT;
+
+ while ((t = (monitored_task *) taskmq->headp) != NULL &&
+
+ (t->start_time.QuadPart < earliest.QuadPart ||
+
+ t->dump_timer_hit)) {
+
+ osi_QRemoveHT(&taskmq->headp,
+ &taskmq->tailp,
+ &t->q);
+
+ lock_ObtainMutex(&_monitor_mx);
+ osi_QAdd(&smb_free_monitored_tasks, &t->q);
+ lock_ReleaseMutex(&_monitor_mx);
+ }
+
+#ifdef INVARIANT_CHECK
+ {
+ LARGE_INTEGER last;
+
+ last.QuadPart = 0;
+
+ for (t = (monitored_task *) taskmq->headp;
+ t;
+ t = (monitored_task *) osi_QNext(&t->q)) {
+ osi_assert(last.QuadPart <= t->start_time.QuadPart);
+ last.QuadPart = t->start_time.QuadPart;
+ }
+ }
+#endif
+}
+
+static void smb_SlurpNewTaskMonitors(osi_queueHT_t * taskmq)
+{
+ monitored_task * task;
+ monitored_task * tasks;
+
+ lock_ObtainMutex(&_monitor_mx);
+ tasks = (monitored_task *) smb_monitored_tasks;
+ smb_monitored_tasks = NULL;
+ lock_ReleaseMutex(&_monitor_mx);
+
+ while (tasks) {
+
+ task = tasks;
+ osi_QRemove((osi_queue_t **) &tasks, &task->q);
+
+ if (task->started) {
+
+ osi_queue_t q;
+ osi_queue_t *p;
+
+ q.nextp = NULL;
+ q.prevp = taskmq->tailp;
+
+ /* Insertion sort by start_time. Earliest request is
+ first. Since we are likely to receive new requests
+ later, we start inserting from the back. */
+ for (p = &q;
+ osi_QPrev(p) &&
+ ((monitored_task *) osi_QPrev(p))->start_time.QuadPart > task->start_time.QuadPart;
+ p = osi_QPrev(p));
+
+ if (p == &q)
+ osi_QAddT(&taskmq->headp, &taskmq->tailp, &task->q);
+ else if (p->prevp == NULL)
+ osi_QAddH(&taskmq->headp, &taskmq->tailp, &task->q);
+ else {
+ osi_queue_t *o = p->prevp;
+
+ osi_assert(o->nextp == p);
+
+ task->q.nextp = p;
+ task->q.prevp = o;
+ p->prevp = &task->q;
+ o->nextp = &task->q;
+ }
+
+ } else {
+ /* Some task ending */
+
+ osi_queue_t * p;
+
+ for (p = taskmq->headp;
+ p != NULL;
+ p = osi_QNext(p)) {
+
+ monitored_task * mt = (monitored_task *) p;
+
+ if (mt->task_id == task->task_id) {
+
+ osi_QRemoveHT(&taskmq->headp,
+ &taskmq->tailp, p);
+
+ lock_ObtainMutex(&_monitor_mx);
+ osi_QAdd(&smb_free_monitored_tasks, p);
+ lock_ReleaseMutex(&_monitor_mx);
+
+ break;
+ }
+ }
+
+ lock_ObtainMutex(&_monitor_mx);
+ osi_QAdd(&smb_free_monitored_tasks, &task->q);
+ lock_ReleaseMutex(&_monitor_mx);
+ }
+ }
+
+#ifdef INVARIANT_CHECK
+ {
+ LARGE_INTEGER last;
+ monitored_task * t;
+
+ last.QuadPart = 0;
+
+ for (t = (monitored_task *) taskmq->headp;
+ t;
+ t = (monitored_task *) osi_QNext(&t->q)) {
+ osi_assert(last.QuadPart <= t->start_time.QuadPart);
+ last.QuadPart = t->start_time.QuadPart;
+ }
+ }
+#endif
+}
+
+static void smb_HandleTaskMonitorEvent(monitored_task * task)
+{
+ if (!task->trace_timer_hit) {
+
+ task->trace_timer_hit = TRUE;
+
+ osi_LogEnable(afsd_logp);
+ rx_DebugOnOff(TRUE);
+
+ } else if (!task->dump_timer_hit) {
+ time_t now;
+
+ time(&now);
+
+ if (smb_last_dump_time + MONITOR_DUMP_RESET_TIMEOUT < now) {
+ task->dump_timer_hit = TRUE;
+ smb_last_dump_time = now;
+
+ GenerateMiniDump(NULL);
+ }
+ }
+}
+
+/**
+ * Server request monitoring
+ *
+ * The server monitor runs in a separate thread and monitors server
+ * requests for potential timeouts. It examines notifcations queued
+ * by smb_NotifyRequestEvent() and waits for potential timeout events:
+ *
+ * - After MONITOR_TRACE_TIMEOUT threshold elapses, the monitor
+ * enables trace logging.
+ *
+ * - After MONITOR_DUMP_TIMEOUT threshold elapses, the monitor writes
+ * out a dump file that will hopefully contain enough evidence to
+ * figure out why the timeout event occurred.
+ *
+ */
+void smb_ServerMonitor(VOID * parmp)
+{
+ osi_queueHT_t in_progress = { NULL, NULL };
+ HANDLE h_timer = NULL;
+
+ HANDLE h_all[3];
+
+ h_monitored_task_queue = CreateEvent(NULL, FALSE, FALSE, "Local\\OpenAFSTaskMonitor");
+ h_monitored_task_shutdown = CreateEvent(NULL, FALSE, FALSE, "Local\\OpenAFSTaskMonitorShutdown");
+ h_timer = CreateWaitableTimer(NULL, FALSE, "Local\\OpenAFSTaskMonitorTimer");
+
+ lock_InitializeMutex(&_monitor_mx, "Request monitor lock", LOCK_HIERARCHY_SMB_MONITOR);
+
+ h_all[0] = h_monitored_task_queue;
+ h_all[1] = h_timer;
+ h_all[2] = h_monitored_task_shutdown;
+
+ while(1) {
+ DWORD rv;
+
+ rv = WaitForMultipleObjects(3, h_all, FALSE, INFINITE);
+
+ if (rv == WAIT_OBJECT_0) {
+
+ smb_SlurpNewTaskMonitors(&in_progress);
+
+ } else if (rv == WAIT_OBJECT_0 + 1) {
+
+ smb_HandleTaskMonitorEvent((monitored_task *) in_progress.headp);
+
+ } else {
+
+ break;
+
+ }
+
+ /* refresh timers */
+ {
+ monitored_task * t;
+
+ smb_PurgeOldTaskMonitors(&in_progress);
+ t = (monitored_task *) in_progress.headp;
+
+ if (t && !t->trace_timer_hit) {
+ LARGE_INTEGER due;
+
+ due = t->start_time;
+ due.QuadPart += MONITOR_TRACE_TIMEOUT;
+
+ SetWaitableTimer(h_timer, &due, 0, NULL, NULL, FALSE);
+ } else if (t && !t->dump_timer_hit) {
+
+ LARGE_INTEGER due;
+
+ due = t->start_time;
+ due.QuadPart += MONITOR_DUMP_TIMEOUT;
+
+ SetWaitableTimer(h_timer, &due, 0, NULL, NULL, FALSE);
+ } else {
+ CancelWaitableTimer(h_timer);
+
+ /* CancelWaitableTimer() doesn't reset the timer if it
+ was already signalled. */
+ WaitForSingleObject(h_timer, 0);
+ }
+ }
+ }
+
+ {
+ HANDLE h;
+
+ h = h_monitored_task_queue;
+ h_monitored_task_queue = NULL;
+ CloseHandle(h);
+
+ h = h_monitored_task_shutdown;
+ h_monitored_task_shutdown = NULL;
+ CloseHandle(h);
+
+ CloseHandle(h_timer);
+
+ lock_FinalizeMutex(&_monitor_mx);
+ }
+
+ {
+ monitored_task * task;
+
+ while (in_progress.headp) {
+ task = (monitored_task *) in_progress.headp;
+ osi_QRemoveHT(&in_progress.headp, &in_progress.tailp, &task->q);
+ free(task);
+ }
+
+ for (task = (monitored_task *) smb_free_monitored_tasks;
+ task; task = (monitored_task *) smb_free_monitored_tasks) {
+ osi_QRemove(&smb_free_monitored_tasks, &task->q);
+ free(task);
+ }
+
+ for (task = (monitored_task *) smb_monitored_tasks;
+ task; task = (monitored_task *) smb_monitored_tasks) {
+ osi_QRemove(&smb_monitored_tasks, &task->q);
+ free(task);
+ }
+ }
+}
+
+void smb_NotifyRequestEvent(INT_PTR task_id, BOOL started)
+{
+ monitored_task * task;
+
+ lock_ObtainMutex(&_monitor_mx);
+ task = (monitored_task *) smb_free_monitored_tasks;
+ if (task)
+ osi_QRemove(&smb_free_monitored_tasks, &task->q);
+ lock_ReleaseMutex(&_monitor_mx);
+
+ if (task == NULL)
+ task = malloc(sizeof(monitored_task));
+ memset(task, 0, sizeof(*task));
+
+ task->task_id = task_id;
+ task->started = started;
+
+ {
+ FILETIME now;
+
+ GetSystemTimeAsFileTime(&now);
+ task->start_time.HighPart = now.dwHighDateTime;
+ task->start_time.LowPart = now.dwLowDateTime;
+ }
+
+ lock_ObtainMutex(&_monitor_mx);
+ osi_QAdd(&smb_monitored_tasks, &task->q);
+ lock_ReleaseMutex(&_monitor_mx);
+
+ SetEvent(h_monitored_task_queue);
+}
+
+void smb_ShutdownMonitor()
+{
+ SetEvent(h_monitored_task_shutdown);
+}
+
/*
* The top level loop for handling SMB request messages. Each server thread
* has its own NCB and buffer for sending replies (outncbp, outbufp), but the
UCHAR rc;
smb_vc_t *vcp = NULL;
smb_t *smbp;
- extern void rx_StartClientThread(void);
rx_StartClientThread();
vcp = NULL;
}
- smb_ResetServerPriority();
+ cm_ResetServerPriority();
code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBreturns[myIdx],
FALSE, INFINITE);
int abandonIdx = code - WAIT_ABANDONED_0;
osi_Log3(smb_logp, "Error: smb_Server ( NCBreturns[%d] ) event %d abandoned, errno %d\n", myIdx, abandonIdx, GetLastError());
}
-
+
if (code == WAIT_IO_COMPLETION)
{
osi_Log1(smb_logp, "Error: smb_Server ( NCBreturns[%d] ) WAIT_IO_COMPLETION\n", myIdx);
continue;
}
-
+
if (code == WAIT_TIMEOUT)
{
osi_Log2(smb_logp, "Error: smb_Server ( NCBreturns[%d] ) WAIT_TIMEOUT, errno %d\n", myIdx, GetLastError());
}
-
+
if (code == WAIT_FAILED)
{
osi_Log2(smb_logp, "Error: smb_Server ( NCBreturns[%d] ) WAIT_FAILED, errno %d\n", myIdx, GetLastError());
}
idx_NCB = code - WAIT_OBJECT_0;
-
+
/* check idx range! */
if (idx_NCB < 0 || idx_NCB > (sizeof(NCBs) / sizeof(NCBs[0])))
{
osi_Log3(smb_logp, "NCBRECV failure lsn %d session %d: %s", ncbp->ncb_lsn, idx_session, ncb_error_string(rc));
switch (rc) {
- case NRC_GOODRET:
+ case NRC_GOODRET:
vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]);
break;
case NRC_INCOMP:
/* Treat as transient error */
- LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_INCOMPLETE,
+ LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_INCOMPLETE,
ncbp->ncb_length);
osi_Log1(smb_logp,
"dispatch smb recv failed, message incomplete, ncb_length %d",
* b) Netbios screwed up the call.
* c) The VC was already marked dead before we were able to
* process the call
- * Obviously this implies that
+ * Obviously this implies that
* ( LSNs[idx_session] != ncbp->ncb_lsn ||
* lanas[idx_session] != ncbp->ncb_lana_num )
* Either way, we can't do anything with this packet.
continue;
}
- smb_SetRequestStartTime();
+ cm_SetRequestStartTime();
+ if (smb_monitorReqs) {
+ smb_NotifyRequestEvent(GetCurrentThreadId(), TRUE);
+ }
vcp->errorCount = 0;
bufp = (struct smb_packet *) ncbp->ncb_buffer;
if (smbp->com == 0x1d) {
/* Special handling for Write Raw */
raw_write_cont_t rwc;
-
+
smb_DispatchPacket(vcp, bufp, outbufp, ncbp, &rwc);
if (rwc.code == 0) {
EVENT_HANDLE rwevent;
thrd_SetEvent(SessionEvents[idx_session]);
if (rwc.code == 0)
smb_CompleteWriteRaw(vcp, bufp, outbufp, ncbp, &rwc);
- }
+ }
else if (smbp->com == 0xa0) {
- /*
- * Serialize the handling for NT Transact
+ /*
+ * Serialize the handling for NT Transact
* (defect 11626)
*/
smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL);
/* TODO: what else needs to be serialized? */
smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL);
}
-#ifndef NOTRACE
+#ifndef NOTRACE
}
__except( smb_ServerExceptionFilter() ) {
}
#endif
+ if (smb_monitorReqs) {
+ smb_NotifyRequestEvent(GetCurrentThreadId(), FALSE);
+ }
smb_concurrentCalls--;
doneWithNCB:
afsd_ForceTrace(TRUE);
buf_ForceTrace(TRUE);
return EXCEPTION_CONTINUE_SEARCH;
-}
+}
/*
* Create a new NCB and associated events, packet buffer, and "space" buffer.
len = (long)strlen(smb_localNamep);
strncpy(ncbp->ncb_name, smb_localNamep, NCBNAMSZ);
for (i=len; i<NCBNAMSZ; i++) ncbp->ncb_name[i] = ' ';
-
+
strcpy(ncbp->ncb_callname, "*");
for (i=1; i<NCBNAMSZ; i++) ncbp->ncb_callname[i] = ' ';
-
+
ncbp->ncb_lana_num = (UCHAR)lana;
code = Netbios(ncbp);
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));
Sleep(50);
}
- osi_Log3(smb_logp,
+ 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,
+ osi_Log0(smb_logp,
"Client exiting due to network failure. Please restart client.\n");
- sprintf(tbuffer,
+ sprintf(tbuffer,
"Client exiting due to network failure. Please restart client.\n"
"NCBLISTEN lana=%d failed with code %d [%s]",
ncbp->ncb_lana_num, code, ncb_error_string(code));
if (reportSessionStartups) {
LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_SMB_SESSION_START, ongoingOps);
}
-
+
lock_ObtainMutex(&vcp->mx);
cm_Utf8ToUtf16(rname, -1, vcp->rname, lengthof(vcp->rname));
vcp->flags |= flags;
}
lock_ReleaseWrite(&smb_globalLock);
} else {
- /* We are re-using an existing VC because the lsn and lana
+ /* We are re-using an existing VC because the lsn and lana
* were re-used */
session = vcp->session;
smb_packet_t * outp = smb_GetPacket();
unsigned char *outWctp;
smb_t *smbp;
-
+
smb_FormatResponsePacket(vcp, NULL, outp);
outp->ncbp = ncbp;
LSNs[session] = ncbp->ncb_lsn;
lanas[session] = ncbp->ncb_lana_num;
lock_ReleaseWrite(&smb_globalLock);
-
+
if (session == numSessions) {
/* Add new NCB for new session */
char eventName[MAX_PATH];
/* 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]
* (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
+ * (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
+ * 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
+ * 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.
+ * service session that set it.
*/
HKEY hkLsa;
HKEY hkMSV10;
DWORD dwSize, dwAllocSize;
DWORD dwValue;
PBYTE pHostNames = NULL, pName = NULL;
- BOOL bNameFound = FALSE;
+ BOOL bNameFound = FALSE;
static BOOL bLoopbackCheckDisabled = FALSE;
/* BackConnectionHostNames and DisableLoopbackCheck */
- if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0",
0,
KEY_READ|KEY_WRITE,
&hkMSV10) == ERROR_SUCCESS )
{
- if ((RegQueryValueEx( hkMSV10, "BackConnectionHostNames", 0,
+ if ((RegQueryValueEx( hkMSV10, "BackConnectionHostNames", 0,
&dwType, NULL, &dwAllocSize) == ERROR_SUCCESS) &&
- (dwType == REG_MULTI_SZ))
+ (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)
+ if (RegQueryValueEx( hkMSV10, "BackConnectionHostNames", 0, &dwType,
+ pHostNames, &dwSize) == ERROR_SUCCESS)
{
- for (pName = pHostNames;
- (pName - pHostNames < (int) dwSize) && *pName ;
+ 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 ) {
dwSize = (DWORD)(pName - pHostNames + 1);
RegSetValueEx( hkMSV10, "BackConnectionHostNames", 0, dwType, pHostNames, dwSize);
- if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Control\\Lsa",
0,
KEY_READ|KEY_WRITE,
dwValue = 1;
RegSetValueEx( hkLsa, "DisableLoopbackCheck", 0, dwType, (LPBYTE)&dwValue, dwSize);
- if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
AFSREG_CLT_OPENAFS_SUBKEY,
0,
NULL,
}
}
} else if (!bLoopbackCheckDisabled) {
- if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
AFSREG_CLT_OPENAFS_SUBKEY,
0,
NULL,
dwSize = sizeof(DWORD);
if ( RegQueryValueEx( hkClient, "RemoveDisableLoopbackCheck", 0, &dwType, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS &&
dwValue == 1 ) {
- if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Control\\Lsa",
0,
KEY_READ|KEY_WRITE,
* [HKLM\SYSTEM\CurrentControlSet\Services\LanManWorkstation\Parameters]
* "ReconnectableServers" REG_MULTI_SZ
* "ExtendedSessTimeout" REG_DWORD (seconds)
- * "ServersWithExtendedSessTimeout" REG_MULTI_SZ
- *
+ * "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.
*/
DWORD dwSize, dwAllocSize;
DWORD dwValue;
PBYTE pHostNames = NULL, pName = NULL;
- BOOL bNameFound = FALSE;
+ BOOL bNameFound = FALSE;
- if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\LanManWorkstation\\Parameters",
0,
KEY_READ|KEY_WRITE,
&hkLanMan) == ERROR_SUCCESS )
{
- if ((RegQueryValueEx( hkLanMan, "ReconnectableServers", 0,
+ if ((RegQueryValueEx( hkLanMan, "ReconnectableServers", 0,
&dwType, NULL, &dwAllocSize) == ERROR_SUCCESS) &&
- (dwType == REG_MULTI_SZ))
+ (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)
+ if (RegQueryValueEx( hkLanMan, "ReconnectableServers", 0, &dwType,
+ pHostNames, &dwSize) == ERROR_SUCCESS)
{
- for (pName = pHostNames;
- (pName - pHostNames < (int) dwSize) && *pName ;
+ 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 ) {
free(pHostNames);
pHostNames = NULL;
}
-
- if ((RegQueryValueEx( hkLanMan, "ServersWithExtendedSessTimeout", 0,
+
+ if ((RegQueryValueEx( hkLanMan, "ServersWithExtendedSessTimeout", 0,
&dwType, NULL, &dwAllocSize) == ERROR_SUCCESS) &&
- (dwType == REG_MULTI_SZ))
+ (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)
+ if (RegQueryValueEx( hkLanMan, "ServersWithExtendedSessTimeout", 0, &dwType,
+ pHostNames, &dwSize) == ERROR_SUCCESS)
{
- for (pName = pHostNames;
- (pName - pHostNames < (int) dwSize) && *pName ;
+ 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 = NULL;
}
- if ((RegQueryValueEx( hkLanMan, "ExtendedSessTimeout", 0,
+ if ((RegQueryValueEx( hkLanMan, "ExtendedSessTimeout", 0,
&dwType, (LPBYTE)&dwValue, &dwAllocSize) != ERROR_SUCCESS) ||
- (dwType != REG_DWORD))
+ (dwType != REG_DWORD))
{
dwType = REG_DWORD;
dwSize = sizeof(dwValue);
static void
smb_LanAdapterChangeThread(void *param)
{
- /*
+ /*
* Give the IPAddrDaemon thread a chance
* to block before we trigger.
*/
if (!powerStateSuspended) {
phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_LanAdapterChangeThread,
NULL, 0, &lpid, "smb_LanAdapterChange");
- osi_assertx(phandle != NULL, "smb_LanAdapterChangeThread thread creation failure");
+ if (phandle == NULL) {
+ DWORD gle;
+ char msg[128];
+
+ gle = GetLastError();
+ StringCchPrintf( msg, sizeof(msg)/sizeof(msg[0]),
+ "smb_LanAdapterChangeThread thread creation failure - gle 0x%x",
+ gle);
+ osi_assertx(TRUE, msg);
+ }
thrd_CloseHandle(phandle);
}
BOOL bGateway;
char NetbiosName[MAX_NB_NAME_LENGTH] = "";
int change = 0;
- LANA_ENUM temp_list;
+ LANA_ENUM temp_list;
long code;
int i;
if (!locked)
lock_ObtainMutex(&smb_StartedLock);
-
+
smb_LanAdapterChangeDetected = 0;
- if (!powerStateSuspended &&
- SUCCEEDED(lana_GetUncServerNameEx(NetbiosName, &lanaNum, &bGateway,
- LANA_NETBIOS_NAME_FULL)) &&
+ if (!powerStateSuspended &&
+ SUCCEEDED(lana_GetUncServerNameEx(NetbiosName, &lanaNum, &bGateway,
+ LANA_NETBIOS_NAME_FULL | LANA_NETBIOS_NO_RESET)) &&
lanaNum != LANA_INVALID && smb_LANadapter != lanaNum) {
if ( isGateway != bGateway ) {
afsi_log("Lan Adapter Change detected (%d != %d): gateway %d != %d",
}
smb_FreeNCB(ncbp);
}
- }
+ }
if (change) {
smb_StopListeners(1);
/* setup the NCB system */
ncbp = smb_GetNCB();
- /* Call lanahelper to get Netbios name, lan adapter number and gateway flag */
+ /*
+ * Call lanahelper to get Netbios name, lan adapter number and gateway flag
+ * This will reset all of the network adapter's netbios state.
+ */
if (SUCCEEDED(code = lana_GetUncServerNameEx(cm_NetbiosName, &lanaNum, &isGateway, LANA_NETBIOS_NAME_FULL))) {
smb_LANadapter = (lanaNum == LANA_INVALID)? -1: lanaNum;
lana_list.length = 1;
lana_list.lana[0] = smb_LANadapter;
}
-
+
for (i = 0; i < lana_list.length; i++) {
/* reset the adaptor: in Win32, this is required for every process, and
* acts as an init call, not as a real hardware reset.
ncbp->ncb_callname[2] = 100;
ncbp->ncb_lana_num = lana_list.lana[i];
code = Netbios(ncbp);
- if (code == 0)
+ if (code == 0)
code = ncbp->ncb_retcode;
if (code != 0) {
afsi_log("Netbios NCBRESET lana %d error code %d", lana_list.lana[i], code);
ncbp->ncb_lana_num = lana;
memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ);
code = Netbios(ncbp);
-
+
afsi_log("Netbios NCBADDNAME lana=%d code=%d retcode=%d complete=%d",
lana, code, ncbp->ncb_retcode, ncbp->ncb_cmd_cplt);
{
afsi_log("Netbios NCBADDNAME added new name >%s<",name);
}
- if (code == 0)
+ if (code == 0)
code = ncbp->ncb_retcode;
if (code == 0) {
memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ);
ncbp->ncb_lana_num = lana;
code = Netbios(ncbp);
- if (code == 0)
+ if (code == 0)
code = ncbp->ncb_retcode;
else {
afsi_log("Netbios NCBDELNAME lana %d error code %d\n", lana, code);
#endif
);
}
-
+
/* we're done with the NCB now */
smb_FreeNCB(ncbp);
);
for (i = 0; i < lana_list.length; i++) {
- if (lana_list.lana[i] == LANA_INVALID)
+ 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");
ncbp->ncb_lana_num = lana;
memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ);
code = Netbios(ncbp);
-
+
afsi_log("StopListener: Netbios NCBDELNAME lana=%d code=%d retcode=%d complete=%d",
lana, code, ncbp->ncb_retcode, ncbp->ncb_cmd_cplt);
ncbp->ncb_callname[2] = 100;
ncbp->ncb_lana_num = lana;
code = Netbios(ncbp);
- if (code == 0)
+ if (code == 0)
code = ncbp->ncb_retcode;
if (code != 0) {
afsi_log("StopListener: Netbios NCBRESET lana %d error code %d", lana, code);
{
thread_t phandle;
int lpid;
- INT_PTR i;
+ UINT_PTR i;
struct tm myTime;
EVENT_HANDLE retHandle;
char eventName[MAX_PATH];
int startListeners = 0;
- smb_TlsRequestSlot = TlsAlloc();
-
smb_MBfunc = aMBfunc;
smb_useV3 = useV3;
myTime.tm_sec = 0;
smb_localZero = mktime(&myTime);
-#ifndef USE_NUMERIC_TIME_CONV
- /* Initialize kludge-GMT */
- smb_CalculateNowTZ();
-#endif /* USE_NUMERIC_TIME_CONV */
#ifdef AFS_FREELANCE_CLIENT
/* Make sure the root.afs volume has the correct time */
- cm_noteLocalMountPointChange();
+ cm_noteLocalMountPointChange(FALSE);
#endif
/* initialize the remote debugging log */
smb_logp = logp;
-
+
/* and the global lock */
lock_InitializeRWLock(&smb_globalLock, "smb global lock", LOCK_HIERARCHY_SMB_GLOBAL);
lock_InitializeRWLock(&smb_rctLock, "smb refct and tree struct lock", LOCK_HIERARCHY_SMB_RCT_GLOBAL);
lock_InitializeMutex(&smb_ListenerLock, "smb listener lock", LOCK_HIERARCHY_SMB_LISTENER);
lock_InitializeMutex(&smb_StartedLock, "smb started lock", LOCK_HIERARCHY_SMB_STARTED);
-
+
/* 4 Raw I/O buffers */
smb_RawBufs = calloc(65536,1);
*((char **)smb_RawBufs) = NULL;
packageName.MaximumLength = packageName.Length + 1;
nts = LsaLookupAuthenticationPackage(smb_lsaHandle, &packageName , &smb_lsaSecPackage);
if (nts == STATUS_SUCCESS) {
- /* BEGIN
- * This code forces Windows to authenticate against the Logon Cache
- * first instead of attempting to authenticate against the Domain
+ /* BEGIN
+ * This code forces Windows to authenticate against the Logon Cache
+ * first instead of attempting to authenticate against the Domain
* Controller. When the Windows logon cache is enabled this improves
* performance by removing the network access and works around a bug
* seen at sites which are using a MIT Kerberos principal to login
RtlZeroMemory(&OptionsRequest, sizeof(OptionsRequest));
OptionsRequest.MessageType = (MSV1_0_PROTOCOL_MESSAGE_TYPE) MsV1_0SetProcessOption;
- OptionsRequest.ProcessOptions = MSV1_0_OPTION_TRY_CACHE_FIRST;
+ OptionsRequest.ProcessOptions = MSV1_0_OPTION_TRY_CACHE_FIRST;
OptionsRequest.DisableOptions = FALSE;
nts = LsaCallAuthenticationPackage( smb_lsaHandle,
* external Kerberos principal mapped to a local account.
*/
else if ( smb_authType == SMB_AUTH_EXTENDED) {
- /* Test to see if there is anything to negotiate. If SPNEGO is not going to be used
- * then the only option is NTLMSSP anyway; so just fallback.
+ /* Test to see if there is anything to negotiate. If SPNEGO is not going to be used
+ * then the only option is NTLMSSP anyway; so just fallback.
*/
void * secBlob;
int secBlobLength;
/* Now get ourselves a domain name. */
/* For now we are using the local computer name as the domain name.
* It is actually the domain for local logins, and we are acting as
- * a local SMB server.
+ * a local SMB server.
*/
bufsize = lengthof(smb_ServerDomainName) - 1;
GetComputerNameW(smb_ServerDomainName, &bufsize);
osi_assertx(phandle != NULL, "smb_WaitingLocksDaemon thread creation failure");
thrd_CloseHandle(phandle);
+ if (smb_monitorReqs) {
+ phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_ServerMonitor,
+ NULL, 0, &lpid, "smb_ServerMonitor");
+ osi_assertx(phandle != NULL, "smb_ServerMonitor thread creation failure");
+ thrd_CloseHandle(phandle);
+ }
+
lock_ReleaseMutex(&smb_StartedLock);
return;
}
smb_vc_t *vcp;
/*fprintf(stderr, "Entering smb_Shutdown\n");*/
-
+
/* setup the NCB system */
ncbp = smb_GetNCB();
smbShutdownFlag = 1;
/* Hang up all sessions */
- memset((char *)ncbp, 0, sizeof(NCB));
+ memset(ncbp, 0, sizeof(NCB));
for (i = 1; i < numSessions; i++)
{
if (dead_sessions[i])
continue;
-
+
/*fprintf(stderr, "NCBHANGUP session %d LSN %d\n", i, LSNs[i]);*/
ncbp->ncb_command = NCBHANGUP;
ncbp->ncb_lana_num = lanas[i]; /*smb_LANadapter;*/
}
}
- /* Trigger the shutdown of all SMB threads */
- for (i = 0; i < smb_NumServerThreads; i++)
- thrd_SetEvent(NCBreturns[i][0]);
-
- thrd_SetEvent(NCBevents[0]);
- thrd_SetEvent(SessionEvents[0]);
- thrd_SetEvent(NCBavails[0]);
-
- for (i = 0;i < smb_NumServerThreads; i++) {
- DWORD code = thrd_WaitForSingleObject_Event(smb_ServerShutdown[i], 500);
- if (code == WAIT_OBJECT_0) {
- continue;
- } else {
- afsi_log("smb_Shutdown thread [%d] did not stop; retry ...",i);
- thrd_SetEvent(NCBreturns[i--][0]);
- }
- }
+ /* Trigger the shutdown of all SMB threads */
+ for (i = 0; i < smb_NumServerThreads; i++)
+ thrd_SetEvent(NCBreturns[i][0]);
+
+ thrd_SetEvent(NCBevents[0]);
+ thrd_SetEvent(SessionEvents[0]);
+ thrd_SetEvent(NCBavails[0]);
+
+ for (i = 0;i < smb_NumServerThreads; i++) {
+ DWORD code = thrd_WaitForSingleObject_Event(smb_ServerShutdown[i], 500);
+ if (code == WAIT_OBJECT_0) {
+ continue;
+ } else {
+ afsi_log("smb_Shutdown thread [%d] did not stop; retry ...",i);
+ thrd_SetEvent(NCBreturns[i--][0]);
+ }
+ }
/* Delete Netbios name */
- memset((char *)ncbp, 0, sizeof(NCB));
+ memset(ncbp, 0, sizeof(NCB));
for (i = 0; i < lana_list.length; i++) {
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);
code = Netbios(ncbp);
- if (code == 0)
+ if (code == 0)
code = ncbp->ncb_retcode;
if (code != 0) {
fprintf(stderr, "Shutdown: Netbios NCBDELNAME lana %d error code %d",
ncbp->ncb_lana_num, code);
- }
+ }
fflush(stderr);
}
/* Release the reference counts held by the VCs */
lock_ObtainWrite(&smb_rctLock);
- for (vcp = smb_allVCsp; vcp; vcp=vcp->nextp)
+ for (vcp = smb_allVCsp; vcp; vcp=vcp->nextp)
{
smb_fid_t *fidp;
smb_tid_t *tidp;
-
+
if (vcp->magic != SMB_VC_MAGIC)
- osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp",
+ osi_panic("afsd: invalid smb_vc_t detected in smb_allVCsp",
__FILE__, __LINE__);
for (fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q))
}
lock_ReleaseWrite(&smb_rctLock);
smb_FreeNCB(ncbp);
- TlsFree(smb_TlsRequestSlot);
+
+ if (smb_monitorReqs) {
+ smb_ShutdownMonitor();
+ }
}
/* Get the UNC \\<servername>\<sharename> prefix. */
{
int zilch;
char output[4196];
-
+
smb_vc_t *vcp;
smb_username_t *unp;
smb_waitingLockRequest_t *wlrp;
if (lock)
lock_ObtainRead(&smb_rctLock);
-
+
sprintf(output, "begin dumping smb_username_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
- for (unp = usernamesp; unp; unp=unp->nextp)
+ for (unp = usernamesp; unp; unp=unp->nextp)
{
cm_ucell_t *ucellp;
- sprintf(output, "%s -- smb_unp=0x%p, refCount=%d, cm_userp=0x%p, flags=0x%x, logoff=%u, name=%S, machine=%S\r\n",
+ sprintf(output, "%s -- smb_unp=0x%p, refCount=%d, cm_userp=0x%p, flags=0x%x, logoff=%u, name=%S, machine=%S\r\n",
cookie, unp, unp->refCount, unp->userp, unp->flags, unp->last_logoff_t,
- unp->name ? unp->name : _C("NULL"),
+ unp->name ? unp->name : _C("NULL"),
unp->machine ? unp->machine : _C("NULL"));
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
for ( ucellp = unp->userp->cellInfop; ucellp; ucellp = ucellp->nextp ) {
- sprintf(output, " %s -- ucellp=0x%p, cellp=0x%p, flags=0x%x, tktLen=%04u, kvno=%03u, expires=%I64u, gen=%d, name=%s, cellname=%s\r\n",
- cookie, ucellp, ucellp->cellp, ucellp->flags, ucellp->ticketLen, ucellp->kvno,
- ucellp->expirationTime, ucellp->gen,
+ sprintf(output, " %s -- ucellp=0x%p, cellp=0x%p, flags=0x%x, tktLen=%04u, kvno=%03u, expires=%I64u, gen=%d, name=%s, cellname=%s\r\n",
+ cookie, ucellp, ucellp->cellp, ucellp->flags, ucellp->ticketLen, ucellp->kvno,
+ ucellp->expirationTime, ucellp->gen,
ucellp->userName,
ucellp->cellp->name);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
sprintf(output, "%s wlrp=0x%p vcp=0x%p, scp=0x%p, type=0x%x, start_t=0x%I64u msTimeout=0x%x\r\n",
cookie, wlrp, wlrp->vcp, wlrp->scp, wlrp->lockType, wlrp->start_t, wlrp->msTimeout);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
-
+
sprintf(output, " begin dumping smb_waitingLock_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
for (lockp = wlrp->locks; lockp; lockp = (smb_waitingLock_t *) osi_QNext(&lockp->q)) {
- sprintf(output, " %s -- waitlockp=0x%p lockp=0x%p key=0x%I64x offset=0x%I64x length=0x%I64x state=0x%x\r\n",
+ sprintf(output, " %s -- waitlockp=0x%p lockp=0x%p key=0x%I64x offset=0x%I64x length=0x%I64x state=0x%x\r\n",
cookie, lockp, lockp->lockp, lockp->key, lockp->LOffset.QuadPart, lockp->LLength.QuadPart, lockp->state);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
sprintf(output, "begin dumping smb_vc_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
- for (vcp = smb_allVCsp; vcp; vcp=vcp->nextp)
+ for (vcp = smb_allVCsp; vcp; vcp=vcp->nextp)
{
smb_fid_t *fidp;
smb_tid_t *tidp;
smb_user_t *userp;
-
+
sprintf(output, "%s vcp=0x%p, refCount=%d, flags=0x%x, vcID=%d, lsn=%d, uidCounter=%d, tidCounter=%d, fidCounter=%d\r\n",
cookie, vcp, vcp->refCount, vcp->flags, vcp->vcID, vcp->lsn, vcp->uidCounter, vcp->tidCounter, vcp->fidCounter);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
-
+
sprintf(output, " begin dumping smb_user_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
for (userp = vcp->usersp; userp; userp = userp->nextp) {
- sprintf(output, " %s -- smb_userp=0x%p, refCount=%d, uid=%d, vcp=0x%p, unp=0x%p, flags=0x%x, delOk=%d\r\n",
+ sprintf(output, " %s -- smb_userp=0x%p, refCount=%d, uid=%d, vcp=0x%p, unp=0x%p, flags=0x%x, delOk=%d\r\n",
cookie, userp, userp->refCount, userp->userID, userp->vcp, userp->unp, userp->flags, userp->deleteOk);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
sprintf(output, " begin dumping smb_tid_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
for (tidp = vcp->tidsp; tidp; tidp = tidp->nextp) {
- sprintf(output, " %s -- smb_tidp=0x%p, refCount=%d, tid=%d, vcp=0x%p, cm_userp=0x%p, flags=0x%x, delOk=%d, path=%S\r\n",
+ sprintf(output, " %s -- smb_tidp=0x%p, refCount=%d, tid=%d, vcp=0x%p, cm_userp=0x%p, flags=0x%x, delOk=%d, path=%S\r\n",
cookie, tidp, tidp->refCount, tidp->tid, tidp->vcp, tidp->userp, tidp->flags, tidp->deleteOk,
tidp->pathname ? tidp->pathname : _C("NULL"));
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
for (fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q))
{
- sprintf(output, " %s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, userp=0x%p, ioctlp=0x%p, flags=0x%x, delOk=%d, NTopen_pathp=%S, NTopen_wholepathp=%S\r\n",
+ sprintf(output, " %s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, userp=0x%p, ioctlp=0x%p, flags=0x%x, delOk=%d, NTopen_pathp=%S, NTopen_wholepathp=%S\r\n",
cookie, fidp, fidp->refCount, fidp->fid, fidp->vcp, fidp->scp, fidp->userp, fidp->ioctlp, fidp->flags, fidp->deleteOk,
- fidp->NTopen_pathp ? fidp->NTopen_pathp : _C("NULL"),
+ fidp->NTopen_pathp ? fidp->NTopen_pathp : _C("NULL"),
fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : _C("NULL"));
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
-
+
sprintf(output, " done dumping smb_fid_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
sprintf(output, "done dumping smb_vc_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
-
+
sprintf(output, "begin dumping DEAD smb_vc_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
- for (vcp = smb_deadVCsp; vcp; vcp=vcp->nextp)
+ for (vcp = smb_deadVCsp; vcp; vcp=vcp->nextp)
{
smb_fid_t *fidp;
smb_tid_t *tidp;
sprintf(output, "%s vcp=0x%p, refCount=%d, flags=0x%x, vcID=%d, lsn=%d, uidCounter=%d, tidCounter=%d, fidCounter=%d\r\n",
cookie, vcp, vcp->refCount, vcp->flags, vcp->vcID, vcp->lsn, vcp->uidCounter, vcp->tidCounter, vcp->fidCounter);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
-
+
sprintf(output, " begin dumping smb_user_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
for (userp = vcp->usersp; userp; userp = userp->nextp) {
- sprintf(output, " %s -- smb_userp=0x%p, refCount=%d, uid=%d, vcp=0x%p, unp=0x%p, flags=0x%x, delOk=%d\r\n",
+ sprintf(output, " %s -- smb_userp=0x%p, refCount=%d, uid=%d, vcp=0x%p, unp=0x%p, flags=0x%x, delOk=%d\r\n",
cookie, userp, userp->refCount, userp->userID, userp->vcp, userp->unp, userp->flags, userp->deleteOk);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
sprintf(output, " begin dumping smb_tid_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
for (tidp = vcp->tidsp; tidp; tidp = tidp->nextp) {
- sprintf(output, " %s -- smb_tidp=0x%p, refCount=%d, tid=%d, vcp=0x%p, cm_userp=0x%p, flags=0x%x, delOk=%d, path=%S\r\n",
+ sprintf(output, " %s -- smb_tidp=0x%p, refCount=%d, tid=%d, vcp=0x%p, cm_userp=0x%p, flags=0x%x, delOk=%d, path=%S\r\n",
cookie, tidp, tidp->refCount, tidp->tid, tidp->vcp, tidp->userp, tidp->flags, tidp->deleteOk,
tidp->pathname ? tidp->pathname : _C("NULL"));
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
for (fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q))
{
- sprintf(output, " %s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, userp=0x%p, ioctlp=0x%p, flags=0x%x, delOk=%d, NTopen_pathp=%S, NTopen_wholepathp=%S\r\n",
+ sprintf(output, " %s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, userp=0x%p, ioctlp=0x%p, flags=0x%x, delOk=%d, NTopen_pathp=%S, NTopen_wholepathp=%S\r\n",
cookie, fidp, fidp->refCount, fidp->fid, fidp->vcp, fidp->scp, fidp->userp, fidp->ioctlp, fidp->flags, fidp->deleteOk,
- fidp->NTopen_pathp ? fidp->NTopen_pathp : _C("NULL"),
+ fidp->NTopen_pathp ? fidp->NTopen_pathp : _C("NULL"),
fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : _C("NULL"));
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
-
+
sprintf(output, " done dumping smb_fid_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
sprintf(output, "done dumping DEAD smb_vc_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
-
+
if (lock)
lock_ReleaseRead(&smb_rctLock);
return 0;