home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / netds / winnt / netapi / nullsess / nullsess.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-11  |  4.8 KB  |  189 lines

  1. /*++
  2.  
  3. Copyright 1996 - 1997 Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     nullsess.c
  8.  
  9. Abstract:
  10.  
  11.     This module illustrates how to use a Null session to overcome access
  12.     problems during network related query operations.
  13.  
  14.     One example of the scenario this approach addresses is as follows:
  15.  
  16.     User logs onto workstation A as the local administrator.
  17.  
  18.     Administrator tries to query user information using the NetUserGetInfo()
  19.     API call on server B.  This call fails with ERROR_ACCESS_DENIED.
  20.  
  21.     The reason this problem occurs is that the administrator password on
  22.     workstation A does not match the administrator password on server B.
  23.  
  24.     During the network query operation, the default behavior is to establish
  25.     a connection to the remote server using the credentials of the logged-in
  26.     user.  In some scenarios, this behavior is not appropriate, and the
  27.     solution is to establish a connection using either known credentials,
  28.     or the Null credentials.  Null credentials are suitable for most query
  29.     operations against a remote machine.  However, if administrator
  30.     related actions are necessary, it is necessary to supply credentials
  31.     which have administrative privilege on the remote machine.  Valid
  32.     credentials consist of a username, password, and optional domain name.
  33.  
  34.     Establishing a connection in this manner requires that no existing
  35.     connections exist to the remote machine tied to the current logon
  36.     session.
  37.  
  38.     Note: Null sessions are those where the user credentials passed in the
  39.     session setup SMB are null.  This sample only implements a function to
  40.     establish a Null session, rather than a session with specific credentials.
  41.  
  42.     Processes and Services running in the Local System account security context
  43.     have Null credentials by default, so establishing Null sessions in this
  44.     scenario is not required.
  45.  
  46.     Applications that run only on Windows NT 4.0 and above can use
  47.     WNetAddConnection2() rather than NetUseAdd() to establish a Null session.
  48.  
  49. Author:
  50.  
  51.     Scott Field (sfield)    13-Jun-96
  52.  
  53. --*/
  54.  
  55. #include <windows.h>
  56. #include <lm.h>
  57.  
  58. #include <stdio.h>
  59.  
  60. BOOL
  61. EstablishNullSession(
  62.     LPCWSTR Server,
  63.     BOOL bEstablish
  64.     );
  65.  
  66. #define RTN_OK 0
  67. #define RTN_USAGE 1
  68. #define RTN_ERROR 13
  69.  
  70. int
  71. __cdecl
  72. wmain(
  73.     int argc,
  74.     wchar_t *argv[]
  75.     )
  76. {
  77.  
  78.     if(argc != 2) {
  79.         printf("Usage: %ls <\\\\Server>\n", argv[0]);
  80.         return RTN_USAGE;
  81.     }
  82.  
  83.     //
  84.     // try network operation here.  If this fails with an access denied
  85.     // error message, retry the operation using a Null session.
  86.     //
  87.  
  88.     //
  89.     // establish a session to the target machine with Null credentials
  90.     //
  91.  
  92.     if(EstablishNullSession( argv[1], TRUE )) {
  93.  
  94.         //
  95.         // retry network related operation here.
  96.         //
  97.  
  98.         //
  99.         // break the existing connection we made
  100.         //
  101.  
  102.         EstablishNullSession( argv[1], FALSE );
  103.     } else {
  104.  
  105.         //
  106.         // error occurred establishing Null session
  107.         //
  108.  
  109.         printf("Error establishing Null session! (rc=%lu)\n", GetLastError());
  110.         return RTN_ERROR;
  111.     }
  112.  
  113.     return RTN_OK;
  114. }
  115.  
  116. BOOL
  117. EstablishNullSession(
  118.     LPCWSTR Server,
  119.     BOOL bEstablish
  120.     )
  121. {
  122.     LPCWSTR szIpc = L"\\IPC$";
  123.     WCHAR RemoteResource[UNCLEN + 5 + 1]; // UNC len + \IPC$ + NULL
  124.     DWORD cchServer;
  125.  
  126.     NET_API_STATUS nas;
  127.  
  128.     //
  129.     // do not allow NULL or empty server name
  130.     //
  131.  
  132.     if(Server == NULL || *Server == L'\0') {
  133.         SetLastError(ERROR_INVALID_COMPUTERNAME);
  134.         return FALSE;
  135.     }
  136.  
  137.     cchServer = lstrlenW( Server );
  138.  
  139.     if(Server[0] != L'\\' && Server[1] != L'\\') {
  140.  
  141.         //
  142.         // prepend slashes and NULL terminate
  143.         //
  144.  
  145.         RemoteResource[0] = L'\\';
  146.         RemoteResource[1] = L'\\';
  147.         RemoteResource[2] = L'\0';
  148.     }
  149.     else {
  150.         cchServer -= 2; // drop slashes from count
  151.  
  152.         RemoteResource[0] = L'\0';
  153.     }
  154.  
  155.     if(cchServer > CNLEN) {
  156.         SetLastError(ERROR_INVALID_COMPUTERNAME);
  157.         return FALSE;
  158.     }
  159.  
  160.     if(lstrcatW(RemoteResource, Server) == NULL) return FALSE;
  161.     if(lstrcatW(RemoteResource, szIpc) == NULL) return FALSE;
  162.  
  163.     //
  164.     // disconnect or connect to the resource, based on bEstablish
  165.     //
  166.  
  167.     if(bEstablish) {
  168.         USE_INFO_2 ui2;
  169.  
  170.         ZeroMemory(&ui2, sizeof(ui2));
  171.  
  172.         ui2.ui2_local = NULL;
  173.         ui2.ui2_remote = (LPTSTR) RemoteResource;
  174.         ui2.ui2_asg_type = USE_IPC;
  175.         ui2.ui2_password = ui2.ui2_username = ui2.ui2_domainname = (LPTSTR) L"";
  176.  
  177.         nas = NetUseAdd(NULL, 2, (LPBYTE)&ui2, NULL);
  178.     }
  179.     else {
  180.         nas = NetUseDel(NULL, (LPTSTR) RemoteResource, 0);
  181.     }
  182.  
  183.     if( nas == NERR_Success ) return TRUE; // indicate success
  184.  
  185.     SetLastError( nas );
  186.  
  187.     return FALSE;
  188. }
  189.