Wednesday, 24 August 2011

What is behind file and printer sharing in Microsoft networks

Let's say our IP address is 192.168.0.1 and public folder is put on share on 192.168.0.2 machine.

What happens when we type \\192.168.0.2 in Windows Explorer on the local machine? Windows Explorer is a process and we are issuing a command "List all network shares on \\192.168.0.2". Explorer does some magic and a list of all shared folders appears in its right pane. But what is behind that magic? Under the bonnet a special file sharing protocol is engaged and a whole set of messages is exchanged between workstation (the client; machine that wants to access shared files on a remote host) and a server (remote host that shares resources). We can monitor these packets in the Wireshark:

client <-> server
-> TCP: syn
<- TCP: syn, ack
-> TCP: ack
-> SMB: Negotiate Protocol Request
<- TCP: ack
<- SMB: Negotiate Protocol Response
-> SMB: Session Setup AndX Request, NTLMSSP_NEGOTIATE
<- SMB: Session Setup AndX Response, NTLMSSP_CHALLENGE, Error: STATUS_MORE_PROCESSING_REQUIRED
-> SMB: Session Setup AndX Request, NTLMSSP_AUTH, User: TEST-PC\test_user
<- SMB: Session Setup AndX Response; accept-completed
...
-> SMB: Tree Connect AndX Request, Path: \\192.168.0.2\IPC$
<- SMB: Tree Connect AndX Response, NT Status: STATUS_SUCCESS
-> SMB: NT Create AndX Request, Path: \srvsvc
<- SMB: NT Create AndX Response, FID: 0xabc
-> SMB: Trans2 Request, QUERY_FILE_INFO, FID: 0xabc, Query File Standard Info
<- SMB: Trans2 Response, FID: 0xabc, QUERY_FILE_INFO
-> DCERPC: Bind: call_id:2, 2 context items, 1st SRVSVC v3.0
<- SMB: Write AndX Response, FID: 0x3ba7, 116 bytes
-> SMB: Read AndX Request, FID: 0x3ba7, 1024 bytes at offset 0
<- DCERPC: Bind_ack: call_id: 2 accept max_xmit: 4280 max_recv: 4280
-> SRVSVC: NetShareEnumAll request
<- SMB: Write AndX Response, FID: 0x3ba7, 100 bytes
-> SMB: Read AndX Request, FID: 0x3ba7, 1024 bytes at offset 0
<- SMB: Read AndX Response, FID: 0x3ba7, 1024 bytes
-> SMB: Read AndX Request, FID: 0x3ba7, 2228 bytes at offset 0
<- SRVSVC: NetShareEnumAll response
-> SMB: Close Request, FID: 0x3ba7
<- SMB: Close Response, FID: 0x3ba7
...
-> SMB: Trans2 Request, GET_DFS_REFERRAL, File: \\192.168.0.2\public
<- SMB: Trans2 Response, GET_DFS_REFERRAL, Error: STATUS_NOT_FOUND
-> SMB: Tree Connect AndX Request, Path: \\192.168.0.2\PUBLIC
<- SMB: Tree Connect AndX Response, Error: STATUS_LOGON_FAILURE
...
-> SMB: Trans2 Request, GET_DFS_REFERRAL, File: \\192.168.0.2\public2
<- SMB: Trans2 Response, GET_DFS_REFERRAL, Error: STATUS_NOT_FOUND
-> SMB: Tree Connect AndX Request, Path: \\192.168.0.2\PUBLIC2
<- SMB: Tree Connect AndX Response, Error: STATUS_LOGON_FAILURE
...
-> SMB: Tree Disconnect Request
<- SMB: Tree Disconnect Response
-> SMB: Logoff AndX Request
<- SMB: Logoff AndX Response
-> TCP: ack

We can see that client establishes TCP connection on server's port microsoft-ds (445) and that further communication uses SMB protocol. SMB stands for Server Message Block, an application layer protocol for accessing shared resources on a network. SMB lays on the top of NetBIOS over TCP/IP. SMB is a client-server, request-response protocol that is based on sessions: client establishes connection to the server and then sends SMB requests to browse directories, open/read/write files etc. SMB uses NT Domain authentication to control access to shared resources.

"Session Setup" SMB message includes the user account, a hash function of the encrypted password and logon domain. A domain controller will examine all this information to determine whether the client has permissions to complete this command.

For each shared resource a set of permissions can be defined (which user/group/domain member can open/read/write/browse). SMB protocol authentication has two levels: user and share.

If we type \\192.168.0.2\public in Windows Explorer, SMB authentication considers credentials we used to log on to Windows and permissions defined on share. For example, if our host and 192.168.0.2 are on the same domain and we are logged on to our machine with local credentials, authentication dialog will appear:

------------------------------------------------------------------
Windows Security [x]
------------------------------------------------------------------
Enter Network Password
Enter your password to connect to: 192.168.0.2
------------------------------------------------------------------
User name:
Password:
Domain:
------------------------------------------------------------------
[] Remember my credentials
------------------------------------------------------------------
OK | Cancel
------------------------------------------------------------------

We need to type domain name, domain user name and password.

If both machines are workgroup machines, we need to type a proper credentials defined on 192.168.0.2.

Article "SMB: The Server Message Block Protocol" explains SMB authentication in depth.

Let us go back to Windows Explorer. Does it implement BSD itself? Does it establish connection between client and server machines itself? No. Connection is actually established between the network-related services (applications) running on client and server. Windows Explorer (and any other process which needs network share access support) just uses these services which use BSD to communicate.

So which services are we talking about?

If you open Control Panel\Network and Internet\Network Connections and look the properties of Local Area Connection, you will see it uses:

  • Client for Microsoft Networks - Allows your computer to access resources on a Microsoft Network. The Client for Microsoft Networks component is actually the Workstation service. If you remove this service, the Netlogon and RPC Locator services are also removed. Uninstalling Client for Microsoft Networks disables server message block (SMB) protocol
  • File and Printer Sharing for Microsoft Networks - Allows other computers to access resources on your computer using a Microsoft Network. The File and Printer Sharing for Microsoft Networks component is the equivalent of the Server service

Relevant services in Service Manager are:

Service Display Name: Workstation
Service Name: LanmanWorkstation
Path: C:\Windows\System32\svchost.exe -k NetworkService
Description: Creates and maintains client network connections to remote servers using the SMB protocol. If this service is stopped, these connections will be unavailable. If this service is disabled, any services that explicitly depend on it will fail to start.
Dependants: Computer Browser, Netlogon,...
This service can be configured with NET CONFIG command.

Service Display Name: Server
Service Name: LanmanServer
Path: C:\Windows\system32\svchost.exe -k netsvcs
Description: Supports file, print, and named-pipe sharing over the network for this computer. If this service is stopped, these functions will be unavailable. If this service is disabled, any services that explicitly depend on it will fail to start.
Dependants: Computer Browser,...
This service can be configured with NET CONFIG command.

Service Display Name: Netlogon
Service Name: Netlogon
Path: C:\Windows\system32\lsass.exe
Description: Maintains a secure channel between this computer and the domain controller for authenticating users and services. If this service is stopped, the computer may not authenticate users and services and the domain controller cannot register DNS records. If this service is disabled, any services that explicitly depend on it will fail to start.
Dependants: None

Story about resource sharing is not simple. Windows uses various protocols on the top of SMB. Some of them are:

Remote Administration Protocol (MS-RAP):
NetServerEnum2 obtains a list of all servers (that have put some resources on share) in a network.
NetShareEnum obtains a list of all shared resources on a specific server.

Common Internet File System (CIFS) Browser Protocol (Microsoft Browser Protocol). Local host gets a list of all shared resources on neighbouring computers via it (filter BROWSER packets in Wireshark). It lays on the top of SMB Mailslot Protocol (Mailslot Name: \MAILSLOT\BROWSE). Hosts from range 192.168.0.xxx send messages to Browse Server (e.g. 192.168.0.255). Host Announcement, Domain/Workgroup Announcement, Local Master Announcement, Request Announcement, Browser Election Request, Become Backup Browser, Get Backup List Announcement...are some of its commands.

SMB Mailslot Protocol (MS-MAIL) lays on the top of SMB and is unidirectional interprocess communications (IPC) protocol between a client and server. A mailslot server creates a mailslot, and a mailslot client writes messages to the mailslot created by the server. The server then reads these messages, thus achieving communication between the client and server. Netlogon Remote Protocol uses it (\MAILSLOT\NET\NETLOGON) to locate domain controllers. Common Internet File System (CIFS) Browser Protocol uses it (\MAILSLOT\LANMAN and \MAILSLOT\BROWSE) for inter-machine communication.

Following picture (source URL) displays all Microsoft networking protocols and their dependencies:


One more thing. We can use NET USE command in order to establish SMB session:

net use \\host_name password /USER:DOMAIN_NAME\user_name

NET USE command sends "Session Setup AndX Request" out:

client <-> server
-> TCP: syn
<- TCP: syn, ack
-> TCP: ack
-> SMB: Negotiate Protocol Request
<- TCP: ack
<- SMB: Negotiate Protocol Response
-> SMB: Session Setup AndX Request, NTLMSSP_NEGOTIATE
<- SMB: Session Setup AndX Response, NTLMSSP_CHALLENGE, Error: STATUS_MORE_PROCESSING_REQUIRED
-> SMB: Session Setup AndX Request, NTLMSSP_AUTH, User: TEST-PC\test_user
<- SMB: Session Setup AndX Response; accept-completed
-> SMB: Tree Connect AndX Request, Path: \\192.168.0.2\IPC$
<- SMB: Tree Connect AndX Response, STATUS_SUCCESS
-> TCP: ack

Links and references:

Shared resource (Wikipedia)
Browser service (Wikipedia)
Description of the Microsoft Computer Browser Service
Just what is SMB?
Net use
Net Use Command
Disable NetBIOS and SMB to protect public Web servers
How to disable NetBIOS over TCP/IP?
How to Disable SMB 2.0 on Windows Vista/2008
Comparing TCP and SMB Connections for Windows XP Embedded-based Devices
Network access validation algorithms and examples for Windows Server 2003, Windows XP, and Windows 2000
Server Message Block (SMB) Protocol Specification
File Session Traffic
Copy File (Remote to Local)
NetBIOS (Wikipedia)
NetBIOS over TCP/IP (Wikipedia)
NetBIOS Over TCP/IP (MSDN)
NetBIOS over TCP/IP (TCP/IP Fundamentals for Microsoft Windows)
NetBIOS NULL Sessions: The Good, The Bad, and The Ugly
Connecting to NetBIOS Resources Using DNS Names or IP Addresses
NET command
Windows NET USE / NetBIOS commands
NETBIOS HACKING
Remote Network Penetration via NetBios Hack/Hacking
Service overview and network port requirements for the Windows Server system
Network Connections Concepts (MSDN)
Client for Microsoft Networks
Troubleshooting Unwanted "Access Denied" Messages in Domain-Based Networks
Network Access Validation Algorithm and Example
Microsoft SMB Protocol and CIFS Protocol Overview
member of both Workgroup and Domain

Axis2/C and linkinfo.dll on Windows Server 2008

axis2_http_sender.dll depends on linkinfo.dll (use Dependency Walker to see) and might not load on Windows Server 2008 because w3wp.exe cannot find this dll (use Process Monitor to see). linkinfo.dll is usually stored in %Windir%\system32 (c:\windows\system32) but not on Windows Server 2008. In order to get it there, install Desktop Experience feature.

Links and references:
Desktop Experience Overview
When you do not install the Desktop Experience feature of Windows Server 2008, programs that require programs that are included in Desktop Experience do not run

Axis2/C Windows binary package and OpenSSL

I deployed Axis2C (1.6.0, Windows binary distribution) on IIS 7.0 running on Windows Server 2008 but simple browser-based test (http://localhost/axis2/services) failed - I got HTTP error 500 in W3SVC log:

#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) sc-status sc-substatus sc-win32-status time-taken
2011-08-24 09:02:53 ::1 GET /axis2/services - 80 - ::1 Mozilla/5.0+(compatible;+MSIE+9.0;+Windows+NT+6.0;+Trident/5.0) 500 0 0 421

Page in the browser displayed:

An IIS server error occurred
An error occurred while initilizing Axis2/C.

Axis log file showed:

[error] ..\..\util\src\class_loader.c(167) Loading shared library C:\axis2c/lib/axis2_http_sender.dll Failed. DLERROR IS DLL Load Error 126: The specified module could not be found.

I used Process Explorer to find Axis2C DLLs loaded by IIS working process and here they are:

axiom.dll
axis2_engine.dll
axis2_parser.dll
axutil.dll
guththila.dll
mod_axis2_iis.dll
neethi.dll

Some of these modules failed to load axis2_http_sender.dll. I tried to reload aforementioned URL in order to wake up w3wp.exe and make it load Axis2C modules. Process Monitor was filtering w3wp.exe events and I could see that w3wp failed to find libeay32.dll (QueryOpen would return NAME NOT FOUND for all locations listed in PATH environment variable). This dll is a part of OpenSSL and is not included in original Axi2C binary package. I downloaded OpenSSL and, just for a test, placed libeay32.dll in C:\axis2c\lib, where axis2_http_sender.dll resides. This time Process Monitor showed that ssleay32.dll could not be found. This file, just like libeay32, belongs to OpenSSL. I placed it in C:\axis2c\lib and repeated the test. Voila! I got the list of my services listed in the browser which proved that Axi2C was set properly.

Process Explorer now shows the complete list of Axis2C DLLs loaded by w3wp.exe:

axiom.dll
axis2_engine.dll
axis2_http_receiver.dll
axis2_http_sender.dll
axis2_mod_addr.dll
axis2_mod_log.dll
axis2_parser.dll
axutil.dll
guththila.dll
libeay32.dll
ssleay32.dll
mod_axis2_iis.dll
neethi.dll

Conclusion: Axis2C Windows distribution depends on OpenSSL DLLs which are not included in binary package which can be downloaded from Apache Axis2/C Releases page. OpenSSL must be installed separately. Unfortunately, this is not mentioned in Axis2/C manual.

Note: upon installing OpenSSL on your system, path to its binaries (e.g. c:\openssl\bin) should be added to PATH environment variable. Make sure you restart machine after changing environment variables as IIS gets them only upon restart - it does not lookup their update values!

Note: If OpenSSL support is not required, download Axis2C source and built it with OpenSSL disabled (--enable-openssl=no)

References and links:
Axis2/C built with SSL support. axis2_http_sender.dll fails to load
problems running default http server
axis2/c depending on openSSL
re-distribute openSSL dlls with AXIS2/c and patent issue

Tuesday, 23 August 2011

How to set common paths in VS2010

"VC++ Directories change" paragraph in Visual Studio 2010 C++ Project Upgrade Guide says:

VC++ Directories are no longer supported in VS2010 through Tools->Options page. Instead, VS2010 introduces the user settings file (Microsoft.cpp..users.props) to control global settings including Global search path. These files are located at $(USERPROFILE)\appdata\local\microsoft\msbuild\v4.0 directory. Upon migration to VS2010, the custom settings of VC++ Directories from VS2005 or VS2008 are migrated to these user files. These global settings files are imported into all the converted and newly created projects.

Here are the steps to change the settings file through UI:

  • Open up property manager by clicking on View.Property Manager.
  • Expand the project node and then the Configuration|Platform nodes, you will see "Microsoft.cpp..users" file for each Configuration|Platform. These are the files for the global settings, similar to the old tools/Options/VC++ Directories.
  • Multi-Select "Microsoft.cpp..users", right click and bring up the property page window
  • In the property page window, click on "VC++ Directories" (for example) in the left pane, add new paths for the directories such as "Include Directories". separated by semicolons
  • Make sure to save the settings before shutting down Visual Studio.
  • Re-launch Visual Studio and the new settings will be in effect.


Note: If you would like to only change the settings for one project, you can right click on the project and bring up the property page. Change the settings for “VC++ Directories”, these settings will be persisted to the project file.

How to check if some process is running (NSIS)

Use NsProcess plugin. FindProcDLL does not work properly on Windows Server 2008.

!include nsProcess.nsh
...
Section -Main SEC0000
...
App_Running_Check:
   ; is app.exe process running? result is stored in $R0
   ${nsProcess::FindProcess} "app.exe" $R0

   ${If} $R0 == 0
      MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "Please stop App.exe before continuing" /SD IDCANCEL IDRETRY App_Running_Check
      Quit
   ${EndIf}
SectionEnd

NSIS installer and locked library files

Installer tries to replace some existing library file with a new one (with the same name) but file is locked, some process is using it at the moment and installer brings up nasty dialog:

---------------------------
MyApp Setup
---------------------------
Error opening file for writing:
C:\Program Files\MyApp\a.dll
Click Abort to stop the installation, Retry to try again, or Ignore to skip this file.
---------------------------
Abort Retry Ignore
---------------------------

The solution is to recognize that file is locked, store a copy of the new file in some temporary directory, ask user to reboot machine at the end of installation, and move file to the intended location upon reboot.

Simplified code that tries to place some file to its intended path on a target machine could be like this:

SetOutPath "$SMPROGRAMS\MyApp"
SetOverwrite on
File "lib\a.dll"

If a.dll is locked, we get the dialog above. The solution is to use InstallLibmacro from a Library header which sets installer error flag if copy error occurs. Additionally, provided argument tells this macro whether to set reboot flag or not. At the end of installation, we check the state of the reboot flag and if it is set, we notify user that reboot is required:

${If} ${Installed} == "True"
   StrCpy $ALREADY_INSTALLED 1
${EndIf}
...
!insertmacro InstallLib DLL $ALREADY_INSTALLED REBOOT_NOTPROTECTED "lib\a.dll" "$SMPROGRAMS\MyApp\a.dll" $TEMP
...
Function .onInstSuccess
   WriteRegStr HKLM "${REGKEY}" 'Version' "${PRODUCT_VERSION}"

   IfRebootFlag 0 NoReboot
      MessageBox MB_YESNO|MB_ICONEXCLAMATION "A reboot is required to finish the installation. Do you wish to reboot now?" IDNO NoReboot
      Reboot
   NoReboot:
FunctionEnd

NOTE 1: If some DLL is locked and you want to see which process has loaded it, use Process Explorer. Go to Find->Find handle or DLL... and type DLL's name...

NOTE 2: To test installer with locked files, use Easy File Locker, a simple GUI tool which sets Visible/Accessable/Writable/Deletable attributes on file or folder.

Lexical string comparison in NSIS

Standard (built-in) string comparison operators are:
  • case-insensitive: ==, !=, StrCmp
  • case-sensitive: StrCmpS

They are only capable of telling whether two strings are equal or not. They don't provide information on which string is greater or less, if strings differ.

LogicLib plug-in extends this set of comparison operators with following ones:
  • case-insensitive: <, <=, >, >=
  • case-sensitive: S==, S!=

Note that operators with capital letter S are case-sensitive.

Here are some tests:

StrCpy $0 "abc"
StrCpy $1 "abc"
StrCpy $2 "Abc"
StrCpy $3 "bbc"

${If} $0 == $1
   DetailPrint "Equal to $1"
${Else}
   DetailPrint "Not equal to $1"
${EndIf}

${If} $0 == $2
   DetailPrint "Equal to $2"
${Else}
   DetailPrint "Not equal to $2"
${EndIf}

; case sensitive comparison (LogicLib operator)
${If} $0 S== $2
   DetailPrint "Equal to $2"
${Else}
   DetailPrint "Not equal to $2"
${EndIf}

${If} $0 == $3
   DetailPrint "Equal to $3"
${Else}
   DetailPrint "Not equal to $3"
${EndIf}

${If} $0 S< $2
   DetailPrint "Less than $2"
${Else}
   DetailPrint "Greater or equal than $2"
${EndIf}

${If} $0 S< $3
   DetailPrint "Less than $3"
${Else}
   DetailPrint "Greater or equal than $3"
${EndIf}

Output:

Equal to abc.
Equal to Abc.
Not equal to Abc.
Not equal to bbc.
Greater or equal than Abc.
Less than bbc.