NAS Scan for folder Access

Started by mkelly, July 24, 2015, 02:08:12 PM

Previous topic - Next topic

mkelly

I am creating script to test a NAS folder structure to see if the logged on user (Script is running as) has admin rights to the folder.

Issues:
1.  Folder structure get larger than 255 Characters
2.  Non Ascii characters are present like a bullet

Special Note:
fafFind scan the folder sctructure fine with the non-ascii characters.  But when I trie to do anything like read permissions it places a ? in the non-ascii characters place.  I tired to at least identify the folder but really only want to check the permissions.  I do not need to identify these paths.

Since I am using icacls I cannot scan the large file paths.  I am just creating a file and then deleting it to identify permissions.  This does not work however because the filewrite command wont work.  Not sure why!

I basically just want to scan and look for folders the domain admin account I am running the script as has admin rights! 

Here is a portion of my script:
xext="NASSERVER"
SHR="Local_Files"
pth=strcat("\\?\UNC\",Hext,"\",SHR)
handle = fafOpen(pth, '*', 8|16)
nCount = 0

While 1
   sFound = fafFind( handle )
   ;sFound Example Variable "\\NASSERVER\Local_Files\IEP POD files\POD reports-presentations\2 Products for Major Contracts\Huge Folder name that makes no sense and is crazy long and should no have this many characters (data-type)\Oral Presentations\"
   If sFound == '' Then Break
   nCount = nCount + 1
   tmpf=strcat(sFound,"~temp77.tmp")  ;temp file to test Directory
   inchar=strreplace(sFound,"\\?\UNC\","\\")
   inchar = ChrUnicodeToString(inchar)
   tmpf = ChrUnicodeToString(tmpf)
   handle2 = 0
   handle2=strindexnc(inchar,"?",1,@fwdscan);Check to see if any imvalid characters in file structure
   if handle2 > 0 then handle2 = 2
   BoxTitle( nCount )
   BoxText( inchar )
   sf=strlen(sFound)
   sFound = strsub(sFound,1,sf - 1)
   if strlen(sFound) > 245
   
      handle4 = FileOpen(tmpf, "WRITE")
      ttt = Fileclose(handle4)
      
      if handle4 == 0 then iniwritepvt(SHRSVR,inchar,"Access-Denied",hostini)
      if handle2 == 0 then iniwritepvt(SHRSVR,inchar,"File Too Long",hostini)
      if handle2 == 2 then iniwritepvt(SHRSVR,inchar,"Invalid-Character",hostini)
      if handle4 > 0 then FileDelete(tmpf)
   else
      VAR=strcat("icacls",' "',sFound,'"')
      Data1 = "A"

;      if strindexnc(sFound,"?",1,@fwdscan) == 0 then Data1= doscapture (VAR)
;      ata=strlen(Data1)
      Data1= doscapture (VAR)
      Data2=strlen(Data1)
      ;if Data2 == 1 then iniwritepvt(SHRSVR,sFound,"Invalid Character",hostini)
      if Data2 == 59 then iniwritepvt(SHRSVR,inchar,"Access-Denied",hostini)
      if handle2 == 2 then iniwritepvt(SHRSVR,inchar,"Invalid-Character",hostini)
   endif
   FileWrite( filehandle, inchar )
EndWhile

td

There are several concepts than need to to be understood before you continue down your current path (pun intended.) 

The first concept is that the with a few exceptions the Windows Win32 API functions only accept file system path  up to 260 characters in length. This limit extends to the Windows shell (Explorer.exe) and other applications that use Win32 API functions like WinBatch, for example.  However, a few Win32 functions do accept longer paths but there are several restrictions. These restrictions include but are not limited to the following:

  • The path must be in a Unicode string.
  • The path must be a full path - no relative paths.
  • The path must begin with the "\\?\" prefix (\\?\UNC\ for shares.)
  • The path must be less than  32,767 Unicode characters in length.

Since the FAF extender is a Unicode only extender that only uses Win32 functions that support long file system paths and internally only uses full paths,  it can search and return long file system paths.  Also note that the FAF extender never converts a Unicode path to an Windows code page/ANSI path so 'it' is not causing your strings to be converted from Unicode to a Windows code page string.   

When ever you do something that converts a Unicode string to a Windows code page string question marks will appear as placeholders for characters that the code page does not have a representation of.  And once you convert a long file system path to a code page's characters even if you don't get any question marks in the conversion, you can no longer use the string as a path. 

This all means that you can't do anything that causes your script to convert Unicode file system paths strings to a Windows code page strings.  It also means that you can't strip the  "\\?\" namespace prefix from your paths and expect them to work as a long file system path.

Also, IIRC, the FileOpen function does not support long paths because it does parsing on the paths internally.  So you will need to write a UDF that calls the Win32 API function CreateFile (or possibly a different function) directly.  This assume you wish to continue to use your current approach to checking permissions.

There is a Tech Database article that probably explains long file system paths better than the above here:
http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/nftechsupt.web+WIL~Extenders/File~Searcher/File~And~Folder~Extender+Long~File~Path~Support.txt 

The documentation for the CreateFile function can be found here:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx

If you need further assistance, let us know and we will try to provide something hopefully useful.

 
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

A very quick and dirty example.  Would require extensive modification and testing, and there may be better
ways to test for directory access...

Code (winbatch) Select
AddExtender('WWFAF44I.DLL', 0, 'WWFAF64I.DLL')

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Check if script's process and by extension user running script has
;; read or write access to a file.
;; strFile - full path to file.
;; strMode - 'READ', 'WRITE', OR 'APPEND'
#definefunction HaveFileAccess(strFile, strMode)
   bReturn = 0
   if ItemLocate(StrUpper(strMode),"WRITE:APPEND",":")
      ModeAccess = 1073741824  ; GENERIC_WRITE     ; Open for output.
      ModeCreate = 4  ; OPEN_ALWAYS       ; (If it exists, don't erase it.)
   else
      ModeAccess = -2147483648 ; GENERIC_READ       ; Open for input.
      ModeCreate = 4  ; OPEN_ALWAYS       ;  Create if doesn't exist.
   endif
   hFile = DllCall('kernel32.dll',long:"CreateFileW",lpwstr:strFile,long:ModeAccess,long:0,long:0,long:ModeCreate,long:0,long:0)
   ;nError = DllLastError()  nError == 5, if 'access denied' error.

   ; If the API succeeded.
   if hFile != -1
      bReturn = 1
      DllCall('kernel32.dll',long:"CloseHandle",long:hFile)
      DllCall('kernel32.dll',long:"DeleteFileW",lpwstr:strFile)
   endif

   return bReturn  ; True if have access
#endfunction

;; Very lightly tested example. Expect bugs.
xext="NASSERVER"
SHR="Local_Files"
pth=strcat("\\?\UNC\",xext,"\",SHR)
handle = fafOpen(pth, '*', 8|16)

While 1
   sFound = fafFind( handle )
   If sFound == '' Then Break
   tmpf=strcat(sFound,"~temp77.tmp")  ; Temp file to test Directory
   if  HaveFileAccess(tmpf,'WRITE')
      ; Do whatever here.
      Pause( 'Have Write Access', sFound)
   endif
endwhile

:cancel
fafClose(handle)
exit
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

mkelly

I hahadve to do a Strreplace on the UNC\ for the kernal32.dll functions.  It did not like it.  Worked fine after I removed it. 

Thank You!!! 

mkelly

I finally got this script to somewhat work.  I think I found a character that even the UNICODE wont see.  FAFIND searches it fine though but when it is sent to a Unicode variable it is a ?.  Only for this character all others seems fine like ' () Ect. 

Invalid Character.  Copied and pasted it here from the browser.     Apprentice Graduation 12ïâ,¬Â¢14ïâ,¬Â¢06 




td

You may be confusing Unicode characters with character glyphs.  The Unicode character F022 does not have a glyph because it is called a 'private use character' and these characters are intentionally left without glyphs in Unicode font sets.  But as long as you don't try to display the character string it should work just fine. 
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

mkelly

Your right it is a Glyph!  when I pass the character to the kernal32.dll functions it is a ?.  I fear their is no way around it!


td

The two byte Unicode value should work  in the CreateFile and DeleteFile functions as long as you don't do anything to convert the string to an ANSI (Windows Code page) string before you pass it one of these functions.  The Unicode character is not a member of the set of characters that is not permitted in file system paths.  Of course this assumes that MSFT is following their own dictates.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade