#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);
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;
case 63:
return "RAP(63)NetWkStaGetInfo";
}
-}
+}
+
+char * myCrt_NmpipeDispatch(int i)
+{
+ switch(i) {
+ case SMB_TRANS_SET_NMPIPE_STATE:
+ return "SET NMPIPE STATE";
+
+ case SMB_TRANS_RAW_READ_NMPIPE:
+ return "RAW READ NMPIPE";
+
+ case SMB_TRANS_QUERY_NMPIPE_STATE:
+ return "QUERY NMPIPE STATE";
+
+ case SMB_TRANS_QUERY_NMPIPE_INFO:
+ return "QUERY NMPIPE INFO";
+
+ case SMB_TRANS_PEEK_NMPIPE:
+ return "PEEK NMPIPE";
+
+ case SMB_TRANS_TRANSACT_NMPIPE:
+ return "TRANSACT NMPIPE";
+
+ case SMB_TRANS_RAW_WRITE_NMPIPE:
+ return "WRITE NMPIPE";
+
+ case SMB_TRANS_READ_NMPIPE:
+ return "READ NMPIPE";
+
+ case SMB_TRANS_WRITE_NMPIPE:
+ return "WRITE NMPIPE";
+
+ case SMB_TRANS_WAIT_NMPIPE:
+ return "WAIT NMPIPE";
+
+ case SMB_TRANS_CALL_NMPIPE:
+ return "CALL NMPIPE";
+ }
+ return "(Unknown)";
+}
/* scache must be locked */
unsigned int smb_Attributes(cm_scache_t *scp)
* 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 */
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());
*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)
{
time_t diff_t = unixTime - smb_localZero;
free(tidp);
}
}
+ if (vcp)
+ smb_ReleaseVCNoLock(vcp);
if (!locked)
lock_ReleaseWrite(&smb_rctLock);
if (userp)
cm_ReleaseUser(userp);
- if (vcp)
- smb_ReleaseVCNoLock(vcp);
}
smb_user_t *smb_FindUID(smb_vc_t *vcp, unsigned short uid, int flags)
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 ) {
if (ioctlp->ioctl.outAllocp)
free(ioctlp->ioctl.outAllocp);
free(ioctlp);
- }
+ }
+
+ smb_CleanupRPCFid(fidp);
+
lock_ReleaseMutex(&fidp->mx);
lock_FinalizeMutex(&fidp->mx);
free(fidp);
return 1;
}
- if (cm_ClientStrCmpIA(shareName, _C("IPC$")) == 0 ||
- cm_ClientStrCmpIA(shareName, _C("srvsvc")) == 0 ||
- cm_ClientStrCmpIA(shareName, _C("wkssvc")) == 0 ||
+ if (MSRPC_IsWellKnownService(shareName) ||
cm_ClientStrCmpIA(shareName, _C(SMB_IOCTL_FILENAME_NOSLASH)) == 0 ||
cm_ClientStrCmpIA(shareName, _C("DESKTOP.INI")) == 0
) {
}
/* Get the full name for this cell */
cellname = cm_ClientStringToFsStringAlloc(p, -1, NULL);
- code = cm_SearchCellFile(cellname, ftemp, 0, 0);
-#ifdef AFS_AFSDB_ENV
+ code = cm_SearchCellRegistry(1, cellname, ftemp, 0, 0, 0);
+ if (code && code != CM_ERROR_FORCE_DNS_LOOKUP)
+ code = cm_SearchCellFile(cellname, ftemp, 0, 0);
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;
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)
break;
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 */
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_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 */
}
#endif /* COMMENT */
}
else if (code == CM_ERROR_BADSHARENAME) {
- NTStatus = 0xC00000CCL; /* Bad network name */
+ NTStatus = 0xC00000BEL; /* Bad network path (server valid, share bad) */
}
else if (code == CM_ERROR_NOIPC) {
#ifdef COMMENT
NTStatus = 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) {
NTStatus = 0xC0000257L; /* Path Not Covered */
}
else if (code == CM_ERROR_ALLBUSY) {
+#ifdef COMMENT
NTStatus = 0xC000022DL; /* Retry */
+#else
+ NTStatus = 0xC00000B5L; /* I/O Timeout */
+#endif
}
else if (code == CM_ERROR_ALLOFFLINE || code == CM_ERROR_ALLDOWN) {
- NTStatus = 0xC00000BEL; /* Bad Network Path */
+ NTStatus = 0xC000003AL; /* Path not found */
}
else if (code >= ERROR_TABLE_BASE_RXK && code < ERROR_TABLE_BASE_RXK + 256) {
NTStatus = 0xC0000322L; /* No Kerberos key */
}
else if (code == CM_ERROR_LOCK_NOT_GRANTED) {
NTStatus = 0xC0000055L; /* Lock Not Granted */
- } else if (code == ENOMEM) {
+ }
+ else if (code == ENOMEM) {
NTStatus = 0xC0000017L; /* Out of Memory */
- } else {
+ }
+ else if (code == CM_ERROR_RPC_MOREDATA) {
+ NTStatus = 0x80000005L; /* Buffer overflow */
+ }
+ else {
NTStatus = 0xC0982001L; /* SMB non-specific error */
}
osi_Log2(smb_logp, "SMB SEND code %lX as NT %lX", code, NTStatus);
}
+/*
+ * NTSTATUS <-> Win32 Error Translation
+ * http://support.microsoft.com/kb/113996
+ */
+void smb_MapWin32Error(long code, unsigned long *Win32Ep)
+{
+ unsigned long Win32E;
+
+ /* 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_NOSUCHVOLUME) {
+ Win32E = ERROR_FILE_NOT_FOUND; /* No such file */
+ }
+ else if (code == CM_ERROR_TIMEDOUT) {
+#ifdef COMMENT
+ Win32E = ERROR_SHARING_PAUSED; /* Sharing Paused */
+#else
+ Win32E = ERROR_UNEXP_NET_ERR; /* Timeout */
+#endif
+ }
+ else if (code == CM_ERROR_RETRY) {
+ Win32E = ERROR_RETRY; /* Retry */
+ }
+ else if (code == CM_ERROR_NOACCESS) {
+ Win32E = ERROR_ACCESS_DENIED; /* Access denied */
+ }
+ else if (code == CM_ERROR_READONLY) {
+ Win32E = ERROR_WRITE_PROTECT; /* Write protected */
+ }
+ else if (code == CM_ERROR_NOSUCHFILE ||
+ code == CM_ERROR_BPLUS_NOMATCH) {
+ 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_INVAL) {
+ Win32E = ERROR_INVALID_PARAMETER;/* Invalid parameter */
+ }
+ else if (code == CM_ERROR_BADFD) {
+ Win32E = ERROR_INVALID_HANDLE; /* Invalid handle */
+ }
+ 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_NOTDIR) {
+ Win32E = ERROR_DIRECTORY; /* Not a directory */
+ }
+ else if (code == CM_ERROR_ISDIR) {
+ Win32E = ERROR_ACCESS_DENIED; /* File is a directory */
+ }
+ else if (code == CM_ERROR_BADOP) {
+ Win32E = ERROR_NOT_SUPPORTED; /* Not supported */
+ }
+ else if (code == CM_ERROR_BADSHARENAME) {
+ Win32E = ERROR_BAD_NETPATH; /* Bad network path (server valid, share bad) */
+ }
+ else if (code == CM_ERROR_NOIPC) {
+#ifdef COMMENT
+ Win32E = ERROR_ACCESS_DENIED; /* Access Denied */
+#else
+ Win32E = ERROR_REM_NOT_LIST; /* Remote Resources */
+#endif
+ }
+ else if (code == CM_ERROR_CLOCKSKEW ||
+ code == RXKADNOAUTH) {
+ Win32E = ERROR_TIME_SKEW; /* Time difference at DC */
+ }
+ else if (code == CM_ERROR_BADTID) {
+ Win32E = ERROR_FILE_NOT_FOUND; /* SMB bad TID */
+ }
+ else if (code == CM_ERROR_USESTD) {
+ Win32E = ERROR_ACCESS_DENIED; /* SMB use standard */
+ }
+ else if (code == CM_ERROR_QUOTA) {
+ Win32E = ERROR_NOT_ENOUGH_QUOTA;/* Quota exceeded */
+ }
+ else if (code == CM_ERROR_SPACE) {
+ Win32E = ERROR_DISK_FULL; /* Disk full */
+ }
+ else if (code == CM_ERROR_ATSYS) {
+ Win32E = ERROR_INVALID_NAME; /* Object name invalid */
+ }
+ else if (code == CM_ERROR_BADNTFILENAME) {
+ Win32E = ERROR_INVALID_NAME; /* Object name invalid */
+ }
+ else if (code == CM_ERROR_WOULDBLOCK) {
+ Win32E = WAIT_TIMEOUT; /* Can't wait */
+ }
+ else if (code == CM_ERROR_SHARING_VIOLATION) {
+ Win32E = ERROR_SHARING_VIOLATION; /* Sharing violation */
+ }
+ else if (code == CM_ERROR_LOCK_CONFLICT) {
+ Win32E = ERROR_LOCK_VIOLATION; /* Lock conflict */
+ }
+ else if (code == CM_ERROR_PARTIALWRITE) {
+ Win32E = ERROR_DISK_FULL; /* Disk full */
+ }
+ else if (code == CM_ERROR_BUFFERTOOSMALL) {
+ Win32E = ERROR_INSUFFICIENT_BUFFER; /* Buffer too small */
+ }
+ 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_BADLOGONTYPE) {
+ Win32E = ERROR_INVALID_LOGON_TYPE; /* logon type not granted */
+ }
+ else if (code == CM_ERROR_GSSCONTINUE) {
+ Win32E = ERROR_MORE_DATA; /* more processing required */
+ }
+ else if (code == CM_ERROR_TOO_MANY_SYMLINKS) {
+#ifdef COMMENT
+ Win32E = ERROR_CANT_RESOLVE_FILENAME; /* reparse point not resolved */
+#else
+ Win32E = ERROR_ACCESS_DENIED; /* Access Denied */
+#endif
+ }
+ 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 */
+ }
+ else if (code == CM_ERROR_LOCK_NOT_GRANTED) {
+ Win32E = ERROR_LOCK_VIOLATION; /* Lock Not Granted */
+ }
+ else if (code == ENOMEM) {
+ Win32E = ERROR_NOT_ENOUGH_MEMORY; /* Out of Memory */
+ }
+ else if (code == CM_ERROR_RPC_MOREDATA) {
+ Win32E = ERROR_MORE_DATA; /* Buffer overflow */
+ }
+ else {
+ Win32E = ERROR_GEN_FAILURE; /* SMB non-specific error */
+ }
+
+ *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)
{
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);
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;
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_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 */
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();
*dptr++ = attr;
/* get dos time */
- smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
+ cm_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
/* copy out time */
shortTemp = (unsigned short) (dosTime & 0xffff);
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
bufferp = NULL;
}
lock_ReleaseWrite(&scp->rw);
- code = buf_Get(scp, &thyper, &bufferp);
+ code = buf_Get(scp, &thyper, &req, &bufferp);
lock_ObtainMutex(&dsp->mx);
/* now, if we're doing a star match, do bulk fetching of all of
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
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;
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
} else
#endif /* DFS_SUPPORT */
if (dscp->fileType == CM_SCACHETYPE_MOUNTPOINT && !dscp->mountRootFid.volume)
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
}
#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).
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
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);
if (!userp) {
lock_ObtainMutex(&fidp->mx);
- if (!fidp->userp && !(fidp->flags & SMB_FID_IOCTL)) {
+ if (!fidp->userp && !(fidp->flags & (SMB_FID_IOCTL|
+ SMB_FID_RPC))) {
lock_ReleaseMutex(&fidp->mx);
osi_Log0(smb_logp, " No user specified. Not closing fid");
return CM_ERROR_BADFD;
(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);
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;
}
}
lock_ReleaseWrite(&scp->rw);
- code = buf_Get(scp, &thyper, &bufferp);
+ code = buf_Get(scp, &thyper, &req, &bufferp);
lock_ObtainWrite(&scp->rw);
if (code) goto done;
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);
/* 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, &bufferp);
+ code = buf_Get(scp, &thyper, &req, &bufferp);
lock_ObtainMutex(&bufferp->mx);
lock_ObtainWrite(&scp->rw);
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
* 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
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) {
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;
}
return code;
}
+ if (fidp->flags & SMB_FID_RPC) {
+ lock_ReleaseMutex(&fidp->mx);
+ code = smb_RPCWrite(fidp, vcp, inp, outp);
+ smb_ReleaseFID(fidp);
+ osi_Log1(smb_logp, "smb_ReceiveCoreWrite RPC code 0x%x", code);
+ return code;
+ }
+
if (!fidp->scp) {
lock_ReleaseMutex(&fidp->mx);
smb_ReleaseFID(fidp);
*/
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);
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);
*/
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);
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);
return code;
}
+ if (fidp->flags & SMB_FID_RPC) {
+ lock_ReleaseMutex(&fidp->mx);
+ code = smb_RPCRead(fidp, vcp, inp, outp);
+ smb_ReleaseFID(fidp);
+ return code;
+ }
+
if (!fidp->scp) {
lock_ReleaseMutex(&fidp->mx);
smb_ReleaseFID(fidp);
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
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,
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;
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;
if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
- return CM_ERROR_BADSHARENAME;
+ return CM_ERROR_NOSUCHPATH;
}
#endif /* DFS_SUPPORT */
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) {
/* 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);
if (dp->procp) {
/* we have a recognized operation */
char * opName = myCrt_Dispatch(inp->inCom);
+ smb_t *smbp;
- if (inp->inCom == 0x1d)
+ 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);
+ if (inp->inCom == 0x1d) {
/* Raw Write */
code = smb_ReceiveCoreWriteRaw (vcp, inp, outp, rwcp);
- else {
- osi_Log4(smb_logp,"Dispatch %s vcp 0x%p lana %d lsn %d",
- opName,vcp,vcp->lana,vcp->lsn);
+ } else {
code = (*(dp->procp)) (vcp, inp, outp);
- osi_Log4(smb_logp,"Dispatch return code 0x%x vcp 0x%p lana %d lsn %d",
- code,vcp,vcp->lana,vcp->lsn);
-#ifdef LOG_PACKET
- if ( code == CM_ERROR_BADSMB ||
- code == CM_ERROR_BADOP )
- smb_LogPacket(inp);
-#endif /* LOG_PACKET */
}
+ osi_Log5(smb_logp,"Dispatch return code 0x%x mid 0x%x vcp 0x%p lana %d lsn %d",
+ code, smbp->mid, vcp, vcp->lana, vcp->lsn);
newTime = GetTickCount();
- osi_Log2(smb_logp, "Dispatch %s duration %d ms", opName, newTime - oldTime);
+ osi_Log3(smb_logp, "Dispatch %s mid 0x%x duration %d ms",
+ opName, smbp->mid, newTime - oldTime);
+
+#ifdef LOG_PACKET
+ if ( code == CM_ERROR_BADSMB ||
+ code == CM_ERROR_BADOP )
+ smb_LogPacket(inp);
+#endif /* LOG_PACKET */
/* ReceiveV3Tran2A handles its own logging */
if (inp->inCom != 0x32 && newTime - oldTime > 45000) {
cm_fid_t afid = {0,0,0,0,0};
uidp = smb_FindUID(vcp, smbp->uid, 0);
- smb_LookupTIDPath(vcp,((smb_t *)inp)->tid, &treepath);
+ smb_LookupTIDPath(vcp, smbp->tid, &treepath);
fidp = smb_FindFID(vcp, inp->fid, 0);
if (fidp) {
pathname = inp->stringsp->wdata;
}
- afsi_log("Request %s duration %d ms user %S tid \"%S\" path? \"%S\" afid (%d.%d.%d.%d)",
- opName, newTime - oldTime,
- uidp ? uidp->unp->name : NULL,
+ afsi_log("Request %s duration %d ms user 0x%x \"%S\" pid 0x%x mid 0x%x tid 0x%x \"%S\" path? \"%S\" afid (%d.%d.%d.%d)",
+ opName, newTime - oldTime,
+ smbp->uid, uidp ? uidp->unp->name : NULL,
+ smbp->pid, smbp->mid, smbp->tid,
treepath,
pathname,
afid.cell, afid.volume, afid.vnode, afid.unique);
vcp = NULL;
}
- smb_ResetServerPriority();
+ cm_ResetServerPriority();
code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBreturns[myIdx],
FALSE, INFINITE);
continue;
}
- smb_SetRequestStartTime();
+ cm_SetRequestStartTime();
vcp->errorCount = 0;
bufp = (struct smb_packet *) ncbp->ncb_buffer;
}
static void
+configureBackConnectionHostNames(void)
+{
+ /* On Windows XP SP2, Windows 2003 SP1, and all future Windows operating systems
+ * there is a restriction on the use of SMB authentication on loopback connections.
+ * There are two work arounds available:
+ *
+ * (1) We can disable the check for matching host names. This does not
+ * require a reboot:
+ * [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa]
+ * "DisableLoopbackCheck"=dword:00000001
+ *
+ * (2) We can add the AFS SMB/CIFS service name to an approved list. This
+ * does require a reboot:
+ * [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0]
+ * "BackConnectionHostNames"=multi-sz
+ *
+ * The algorithm will be:
+ * (1) Check to see if cm_NetbiosName exists in the BackConnectionHostNames list
+ * (2a) If not, add it to the list. (This will not take effect until the next reboot.)
+ * (2b1) and check to see if DisableLoopbackCheck is set.
+ * (2b2) If not set, set the DisableLoopbackCheck value to 0x1
+ * (2b3) and create HKLM\SOFTWARE\OpenAFS\Client UnsetDisableLoopbackCheck
+ * (2c) else If cm_NetbiosName exists in the BackConnectionHostNames list,
+ * check for the UnsetDisableLoopbackCheck value.
+ * If set, set the DisableLoopbackCheck flag to 0x0
+ * and delete the UnsetDisableLoopbackCheck value
+ *
+ * Starting in Longhorn Beta 1, an entry in the BackConnectionHostNames value will
+ * force Windows to use the loopback authentication mechanism for the specified
+ * services.
+ *
+ * Do not permit the "DisableLoopbackCheck" value to be removed within the same
+ * service session that set it.
+ */
+ HKEY hkLsa;
+ HKEY hkMSV10;
+ HKEY hkClient;
+ DWORD dwType;
+ DWORD dwSize, dwAllocSize;
+ DWORD dwValue;
+ PBYTE pHostNames = NULL, pName = NULL;
+ BOOL bNameFound = FALSE;
+ static BOOL bLoopbackCheckDisabled = FALSE;
+
+ /* BackConnectionHostNames and DisableLoopbackCheck */
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0",
+ 0,
+ KEY_READ|KEY_WRITE,
+ &hkMSV10) == ERROR_SUCCESS )
+ {
+ if ((RegQueryValueEx( hkMSV10, "BackConnectionHostNames", 0,
+ &dwType, NULL, &dwAllocSize) == ERROR_SUCCESS) &&
+ (dwType == REG_MULTI_SZ))
+ {
+ dwAllocSize += 1 /* in case the source string is not nul terminated */
+ + (DWORD)strlen(cm_NetbiosName) + 2;
+ pHostNames = malloc(dwAllocSize);
+ dwSize = dwAllocSize;
+ if (RegQueryValueEx( hkMSV10, "BackConnectionHostNames", 0, &dwType,
+ pHostNames, &dwSize) == ERROR_SUCCESS)
+ {
+ for (pName = pHostNames;
+ (pName - pHostNames < (int) dwSize) && *pName ;
+ pName += strlen(pName) + 1)
+ {
+ if ( !stricmp(pName, cm_NetbiosName) ) {
+ bNameFound = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !bNameFound ) {
+ size_t size = strlen(cm_NetbiosName) + 2;
+ if ( !pHostNames ) {
+ pHostNames = malloc(size);
+ pName = pHostNames;
+ }
+ StringCbCopyA(pName, size, cm_NetbiosName);
+ pName += size - 1;
+ *pName = '\0'; /* add a second nul terminator */
+
+ dwType = REG_MULTI_SZ;
+ dwSize = (DWORD)(pName - pHostNames + 1);
+ RegSetValueEx( hkMSV10, "BackConnectionHostNames", 0, dwType, pHostNames, dwSize);
+
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Control\\Lsa",
+ 0,
+ KEY_READ|KEY_WRITE,
+ &hkLsa) == ERROR_SUCCESS )
+ {
+ dwSize = sizeof(DWORD);
+ if ( RegQueryValueEx( hkLsa, "DisableLoopbackCheck", 0, &dwType, (LPBYTE)&dwValue, &dwSize) != ERROR_SUCCESS ||
+ dwValue == 0 ) {
+ dwType = REG_DWORD;
+ dwSize = sizeof(DWORD);
+ dwValue = 1;
+ RegSetValueEx( hkLsa, "DisableLoopbackCheck", 0, dwType, (LPBYTE)&dwValue, dwSize);
+
+ if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ AFSREG_CLT_OPENAFS_SUBKEY,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ|KEY_WRITE,
+ NULL,
+ &hkClient,
+ NULL) == ERROR_SUCCESS) {
+
+ dwType = REG_DWORD;
+ dwSize = sizeof(DWORD);
+ dwValue = 1;
+ RegSetValueEx( hkClient, "RemoveDisableLoopbackCheck", 0, dwType, (LPBYTE)&dwValue, dwSize);
+ bLoopbackCheckDisabled = TRUE;
+ RegCloseKey(hkClient);
+ }
+ RegCloseKey(hkLsa);
+ }
+ }
+ } else if (!bLoopbackCheckDisabled) {
+ if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ AFSREG_CLT_OPENAFS_SUBKEY,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ|KEY_WRITE,
+ NULL,
+ &hkClient,
+ NULL) == ERROR_SUCCESS) {
+
+ dwSize = sizeof(DWORD);
+ if ( RegQueryValueEx( hkClient, "RemoveDisableLoopbackCheck", 0, &dwType, (LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS &&
+ dwValue == 1 ) {
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Control\\Lsa",
+ 0,
+ KEY_READ|KEY_WRITE,
+ &hkLsa) == ERROR_SUCCESS )
+ {
+ RegDeleteValue(hkLsa, "DisableLoopbackCheck");
+ RegCloseKey(hkLsa);
+ }
+ }
+ RegDeleteValue(hkClient, "RemoveDisableLoopbackCheck");
+ RegCloseKey(hkClient);
+ }
+ }
+
+ if (pHostNames) {
+ free(pHostNames);
+ pHostNames = NULL;
+ }
+
+ RegCloseKey(hkMSV10);
+ }
+}
+
+
+static void
+configureExtendedSMBSessionTimeouts(void)
+{
+ /*
+ * In a Hot Fix to Windows 2003 SP2, the smb redirector was given the following
+ * new functionality:
+ *
+ * [HKLM\SYSTEM\CurrentControlSet\Services\LanManWorkstation\Parameters]
+ * "ReconnectableServers" REG_MULTI_SZ
+ * "ExtendedSessTimeout" REG_DWORD (seconds)
+ * "ServersWithExtendedSessTimeout" REG_MULTI_SZ
+ *
+ * These values can be used to prevent the smb redirector from timing out
+ * smb connection to the afs smb server prematurely.
+ */
+ HKEY hkLanMan;
+ DWORD dwType;
+ DWORD dwSize, dwAllocSize;
+ DWORD dwValue;
+ PBYTE pHostNames = NULL, pName = NULL;
+ BOOL bNameFound = FALSE;
+
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Services\\LanManWorkstation\\Parameters",
+ 0,
+ KEY_READ|KEY_WRITE,
+ &hkLanMan) == ERROR_SUCCESS )
+ {
+ if ((RegQueryValueEx( hkLanMan, "ReconnectableServers", 0,
+ &dwType, NULL, &dwAllocSize) == ERROR_SUCCESS) &&
+ (dwType == REG_MULTI_SZ))
+ {
+ dwAllocSize += 1 /* in case the source string is not nul terminated */
+ + (DWORD)strlen(cm_NetbiosName) + 2;
+ pHostNames = malloc(dwAllocSize);
+ dwSize = dwAllocSize;
+ if (RegQueryValueEx( hkLanMan, "ReconnectableServers", 0, &dwType,
+ pHostNames, &dwSize) == ERROR_SUCCESS)
+ {
+ for (pName = pHostNames;
+ (pName - pHostNames < (int) dwSize) && *pName ;
+ pName += strlen(pName) + 1)
+ {
+ if ( !stricmp(pName, cm_NetbiosName) ) {
+ bNameFound = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !bNameFound ) {
+ size_t size = strlen(cm_NetbiosName) + 2;
+ if ( !pHostNames ) {
+ pHostNames = malloc(size);
+ pName = pHostNames;
+ }
+ StringCbCopyA(pName, size, cm_NetbiosName);
+ pName += size - 1;
+ *pName = '\0'; /* add a second nul terminator */
+
+ dwType = REG_MULTI_SZ;
+ dwSize = (DWORD)(pName - pHostNames + 1);
+ RegSetValueEx( hkLanMan, "ReconnectableServers", 0, dwType, pHostNames, dwSize);
+ }
+
+ if (pHostNames) {
+ free(pHostNames);
+ pHostNames = NULL;
+ }
+
+ if ((RegQueryValueEx( hkLanMan, "ServersWithExtendedSessTimeout", 0,
+ &dwType, NULL, &dwAllocSize) == ERROR_SUCCESS) &&
+ (dwType == REG_MULTI_SZ))
+ {
+ dwAllocSize += 1 /* in case the source string is not nul terminated */
+ + (DWORD)strlen(cm_NetbiosName) + 2;
+ pHostNames = malloc(dwAllocSize);
+ dwSize = dwAllocSize;
+ if (RegQueryValueEx( hkLanMan, "ServersWithExtendedSessTimeout", 0, &dwType,
+ pHostNames, &dwSize) == ERROR_SUCCESS)
+ {
+ for (pName = pHostNames;
+ (pName - pHostNames < (int) dwSize) && *pName ;
+ pName += strlen(pName) + 1)
+ {
+ if ( !stricmp(pName, cm_NetbiosName) ) {
+ bNameFound = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !bNameFound ) {
+ size_t size = strlen(cm_NetbiosName) + 2;
+ if ( !pHostNames ) {
+ pHostNames = malloc(size);
+ pName = pHostNames;
+ }
+ StringCbCopyA(pName, size, cm_NetbiosName);
+ pName += size - 1;
+ *pName = '\0'; /* add a second nul terminator */
+
+ dwType = REG_MULTI_SZ;
+ dwSize = (DWORD)(pName - pHostNames + 1);
+ RegSetValueEx( hkLanMan, "ServersWithExtendedSessTimeout", 0, dwType, pHostNames, dwSize);
+ }
+
+ if (pHostNames) {
+ free(pHostNames);
+ pHostNames = NULL;
+ }
+
+ if ((RegQueryValueEx( hkLanMan, "ExtendedSessTimeout", 0,
+ &dwType, (LPBYTE)&dwValue, &dwAllocSize) != ERROR_SUCCESS) ||
+ (dwType != REG_DWORD))
+ {
+ dwType = REG_DWORD;
+ dwSize = sizeof(dwValue);
+ dwValue = 300; /* 5 minutes */
+ RegSetValueEx( hkLanMan, "ExtendedSessTimeout", 0, dwType, (const BYTE *)&dwValue, dwSize);
+ }
+ RegCloseKey(hkLanMan);
+ }
+}
+
+static void
smb_LanAdapterChangeThread(void *param)
{
/*
}
afsi_log("smb_StartListeners");
+ /* Ensure the AFS Netbios Name is registered to allow loopback access */
+ configureBackConnectionHostNames();
+
+ /* Configure Extended SMB Session Timeouts */
+ if (msftSMBRedirectorSupportsExtendedTimeouts()) {
+ afsi_log("Microsoft SMB Redirector supports Extended Timeouts");
+ configureExtendedSMBSessionTimeouts();
+ }
+
smb_ListenerState = SMB_LISTENER_STARTED;
cm_VolStatus_Network_Started(cm_NetbiosName
#ifdef _WIN64
{
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();
);
if (nts != STATUS_SUCCESS && ntsEx != STATUS_SUCCESS) {
- char message[AFSPATHMAX];
- sprintf(message,"MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x",
- nts, ntsEx);
- OutputDebugString(message);
- afsi_log(message);
+ osi_Log2(smb_logp, "MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x",
+ nts, ntsEx);
+
+ afsi_log("MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x", nts, ntsEx);
} else {
- OutputDebugString("MsV1_0SetProcessOption success");
+ osi_Log0(smb_logp, "MsV1_0SetProcessOption success");
afsi_log("MsV1_0SetProcessOption success");
}
/* END - code from Larry */
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])
}
/* 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;
}
lock_ReleaseWrite(&smb_rctLock);
smb_FreeNCB(ncbp);
- TlsFree(smb_TlsRequestSlot);
}
/* Get the UNC \\<servername>\<sharename> prefix. */