Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*
* S E C U R I T Y . C P P * * Url security checks. While these would seem to only apply to HttpEXT, * all impls. that care about ASP execution should really think about this. * * Bits stolen from the IIS5 project 'iis5\infocom\cache2\filemisc.cxx' and * cleaned up to fit in with the DAV sources. * * Copyright 1986-1997 Microsoft Corporation, All Rights Reserved */
#include "_davprs.h"
// This function takes a suspected NT/Win95 short filename and checks
// if there's an equivalent long filename.
//
// For example, c:\foobar\ABCDEF~1.ABC is the same as
// c:\foobar\abcdefghijklmnop.abc.
//
// If there is an equivalent, we need to FAIL this path, because our metabase
// will NOT have the correct values listed under the short paths!
// If there is no equivalent, this path can be allowed through, because it
// might be a real storage entitiy (not an alias for a real storage entity).
//
// NOTE: This function should be called unimpersonated - the FindFirstFile()
// must be called in the system context since most systems have traverse
// checking turned off - except for the UNC case where we must be impersonated
// to get network access.
//
SCODE __fastcall ScCheckIfShortFileName ( /* [in] */ LPCWSTR pwszPath, /* [in] */ const HANDLE hitUser) { WIN32_FIND_DATAW fd; LPCWSTR pwsz; BOOL fUNC = FALSE;
// Skip forward to find the first '~'
//
if (NULL == (pwsz = wcschr(pwszPath, L'~'))) return S_OK;
//$ REVIEW: this is not sufficient for DavEX, but it is unclear that
// this function applies there. Certainly the FindFirstFile() call
// will fail at this time.
//
fUNC = (*pwszPath == L'\\'); Assert (!fUNC || (NULL != hitUser));
// We actually need to loop in case multiple '~' appear in the filename
//
do { // At this point, pwsz should be pointing to the '~'
//
Assert (L'~' == *pwsz);
// Is the next char a digit?
//
pwsz++; if ((*pwsz >= L'0') && (*pwsz <= L'9')) { WCHAR wszTmp[MAX_PATH]; const WCHAR * pwchEndSeg; const WCHAR * pwchBeginSeg; HANDLE hFind;
// Isolate the path up to the segment with the
// '~' and do the FindFirstFile with that path
//
pwchEndSeg = wcschr (pwsz, L'\\'); if (!pwchEndSeg) { pwchEndSeg = pwsz + wcslen (pwsz); }
// If the string is beyond MAX_PATH then we fail it.
// urls this long don't need to have '~N' in them.
//
// Also check that our buffer is big enough to handle anything
// that gets through this check.
//
// NOTE: We are assuming that other code outside this function
// will catch paths that are larger than MAX_PATH and FAIL them.
//
//$ REVIEW: the MAX_PATH restriction is very important because
// the call to FindFirstFile() will fail if the path is larger
// than MAX_PATH. Should we ever decide to support larger paths
// in HttpEXT, this code will have to change.
//
Assert (MAX_PATH == CElems(wszTmp)); if ((pwchEndSeg - pwszPath) >= MAX_PATH) return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
// Make a copy of the string up to this point in the path
//
wcsncpy (wszTmp, pwszPath, pwchEndSeg - pwszPath); wszTmp[pwchEndSeg - pwszPath] = 0;
// If we are not accessing a unc, then we need to revert
// for our call to FindFirstFile() -- see comment above.
//
if (!fUNC) { safe_revert (const_cast<HANDLE>(hitUser)); hFind = FindFirstFileW (wszTmp, &fd); } else hFind = FindFirstFileW (wszTmp, &fd);
if (hFind == INVALID_HANDLE_VALUE) { // If the FindFirstFile() fails to find the file then
// the filename cannot be a short name.
//
DWORD dw = GetLastError(); if ((ERROR_FILE_NOT_FOUND != dw) && (ERROR_PATH_NOT_FOUND != dw)) return HRESULT_FROM_WIN32(dw);
return S_OK; }
// Make sure the find context gets closed.
//
FindClose (hFind);
// Isolate the last segment of the string which should be
// the potential short name equivalency
//
pwchBeginSeg = wcsrchr (wszTmp, '\\'); Assert (pwchBeginSeg); pwchBeginSeg++;
// If the last segment doesn't match the long name then
// this is the short name version (alias) of the path -- so
// fail this function.
//
if (_wcsicmp (fd.cFileName, pwchBeginSeg)) { DebugTrace ("Dav: Url: refers to shortname for file\n"); Assert (!_wcsicmp (fd.cAlternateFileName, pwchBeginSeg)); return E_DAV_SHORT_FILENAME; } } } while (NULL != (pwsz = wcschr (pwsz, L'~'))); return S_OK; }
SCODE __fastcall ScCheckForAltFileStream ( /* [in] */ LPCWSTR pwszPath) { // Avoid the infamous ::$DATA bug
//
if (wcsstr (pwszPath, L"::")) return E_DAV_ALT_FILESTREAM;
return S_OK; }
|