home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / security / winnt / aclapi / aclapi.c next >
Encoding:
C/C++ Source or Header  |  1997-10-05  |  6.4 KB  |  278 lines

  1. /*++
  2.  
  3. Copyright 1996 - 1997 Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     aclapi.c
  8.  
  9. Abstract:
  10.  
  11.     This module illustrates new Acl management API for Windows NT 4.0.
  12.  
  13.     Developers of new software which is to run on Windows NT version 4.0
  14.     and above are encouraged to utilize these security API rather than
  15.     implementing code which uses lower level security API.  The development
  16.     and test time can be drastically reduced by utilizing these new API.
  17.  
  18.     This sample illustrates this point by implementing code which modifies
  19.     the security on an existing file using the new Windows NT 4.0
  20.     Acl management API.
  21.  
  22.  
  23.     The following new API functions are illustrated in this sample:
  24.  
  25.     GetNamedSecurityInfo()
  26.     BuildExplicitAccessWithName()
  27.     SetEntriesInAcl()
  28.     SetNamedSecurityInfo()
  29.  
  30.     The following lower-level security API would have been used to achieve
  31.     the same result:
  32.  
  33.     LookupAccountName()
  34.     InitializeSecurityDescriptor()
  35.     InitializeAcl()
  36.     GetSecurityDescriptorDacl()
  37.     GetAclInformation()
  38.     GetAce()
  39.     SetSecurityDescriptorDacl()
  40.     AddAce()
  41.     AddAccessAllowedAce() / AddAccessDeniedAce()
  42.     GetFileSecurity()
  43.     SetFileSecurity()
  44.  
  45.     Less code and less complex code is required to achieve this task using
  46.     the new Windows NT 4.0 Acl management API.
  47.  
  48. Author:
  49.  
  50.     Scott Field (sfield)    02-Jun-96
  51.  
  52. --*/
  53.  
  54. #include <windows.h>
  55. #include <aclapi.h>
  56. #include <lmerr.h>
  57.  
  58. #include <stdio.h>
  59.  
  60. #define RTN_OK 0
  61. #define RTN_USAGE 1
  62. #define RTN_ERROR 13
  63.  
  64. void
  65. DisplayLastError(
  66.     LPSTR szAPI
  67.     );
  68.  
  69. int
  70. __cdecl
  71. main(
  72.     int argc,
  73.     char *argv[]
  74.     )
  75. {
  76.     LPTSTR FileName;
  77.     LPTSTR TrusteeName;
  78.  
  79.     DWORD AccessMask = GENERIC_ALL;
  80.     DWORD InheritFlag = NO_INHERITANCE;
  81.     ACCESS_MODE option;
  82.     EXPLICIT_ACCESS explicitaccess;
  83.  
  84.     PACL ExistingDacl;
  85.     PACL NewAcl = NULL;
  86.     PSECURITY_DESCRIPTOR psd = NULL;
  87.  
  88.     DWORD dwError;
  89.     BOOL bSuccess = FALSE; // assume failure
  90.  
  91.     if(argc < 4) {
  92.         printf("Usage: %s <filename> {/Deny | /Grant | /Revoke | /Set} [<trustee>] [<permissions>] [<InheritFlag>]\n", argv[0]);
  93.         return RTN_USAGE;
  94.     }
  95.  
  96.     FileName = argv[1];
  97.     TrusteeName = argv[3];
  98.  
  99.     if ( (0 == stricmp(argv[2], "/Deny") ) ||
  100.         (0 == stricmp(argv[2], "/D") ) )
  101.     {
  102.       option = DENY_ACCESS;
  103.     } else if ( ( (0 == stricmp(argv[2], "/Revoke") ) ||
  104.                  (0 == stricmp(argv[2], "/R") ) ) )
  105.     {
  106.       option = REVOKE_ACCESS;
  107.     } else if ( (0 == stricmp(argv[2], "/Set") ) ||
  108.                (0 == stricmp(argv[2], "/S") ) )
  109.     {
  110.       option = SET_ACCESS;
  111.     } else if ( (0 == stricmp(argv[2], "/Grant") ) ||
  112.                (0 == stricmp(argv[2], "/G") ) )
  113.     {
  114.       option = GRANT_ACCESS;
  115.     } else {
  116.         printf("Invalid action specified\n");
  117.         return RTN_ERROR;
  118.     }
  119.  
  120.     if (argc > 4)
  121.     {
  122.         AccessMask = atol( argv[4] );
  123.     }
  124.  
  125.     if (argc > 5)
  126.     {
  127.        InheritFlag = atol( argv[5] );
  128.     }
  129.  
  130.     //
  131.     // get current Dacl on specified file
  132.     //
  133.  
  134.     dwError = GetNamedSecurityInfo(
  135.                         FileName,
  136.                         SE_FILE_OBJECT,
  137.                         DACL_SECURITY_INFORMATION,
  138.                         NULL,
  139.                         NULL,
  140.                         &ExistingDacl,
  141.                         NULL,
  142.                         &psd
  143.                         );
  144.  
  145.     if(dwError != ERROR_SUCCESS) {
  146.         DisplayLastError("GetNamedSecurityInfo");
  147.         return RTN_ERROR;
  148.     }
  149.  
  150.     BuildExplicitAccessWithName(
  151.             &explicitaccess,
  152.             TrusteeName,
  153.             AccessMask,
  154.             option,
  155.             InheritFlag
  156.             );
  157.  
  158.     //
  159.     // add specified access to the object
  160.     //
  161.  
  162.     dwError = SetEntriesInAcl(
  163.             1,
  164.             &explicitaccess,
  165.             ExistingDacl,
  166.             &NewAcl
  167.             );
  168.  
  169.     if(dwError != ERROR_SUCCESS) {
  170.         DisplayLastError("SetEntriesInAcl");
  171.         goto cleanup;
  172.     }
  173.  
  174.     //
  175.     // apply new security to file
  176.     //
  177.  
  178.     dwError = SetNamedSecurityInfo(
  179.                     FileName,
  180.                     SE_FILE_OBJECT, // object type
  181.                     DACL_SECURITY_INFORMATION,
  182.                     NULL,
  183.                     NULL,
  184.                     NewAcl,
  185.                     NULL
  186.                     );
  187.  
  188.     if(dwError != ERROR_SUCCESS) {
  189.         DisplayLastError("SetNamedSecurityInfo");
  190.         goto cleanup;
  191.     }
  192.  
  193.     bSuccess = TRUE; // indicate success
  194.  
  195. cleanup:
  196.  
  197.     if( NewAcl != NULL ) AccFree( NewAcl );
  198.     if( psd != NULL) AccFree( psd );
  199.  
  200.  
  201.     if(!bSuccess)
  202.         return RTN_ERROR;
  203.  
  204.     return RTN_OK;
  205. }
  206.  
  207. void
  208. DisplayLastError(
  209.     LPSTR szAPI
  210.     )
  211. {
  212.     HMODULE hModule = NULL; // default to system source
  213.     DWORD dwLastError = GetLastError();
  214.     LPSTR MessageBuffer;
  215.     DWORD dwBufferLength;
  216.  
  217.     DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
  218.         FORMAT_MESSAGE_IGNORE_INSERTS |
  219.         FORMAT_MESSAGE_FROM_SYSTEM ;
  220.  
  221.     //
  222.     // if dwLastError is in the network range, load the message source
  223.     //
  224.  
  225.     if(dwLastError >= NERR_BASE && dwLastError <= MAX_NERR) {
  226.         hModule = LoadLibraryEx(
  227.             TEXT("netmsg.dll"),
  228.             NULL,
  229.             LOAD_LIBRARY_AS_DATAFILE
  230.             );
  231.  
  232.         if(hModule != NULL)
  233.             dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
  234.     }
  235.  
  236.     printf("%s error! (rc=%lu)\n", szAPI, dwLastError);
  237.  
  238.     //
  239.     // call FormatMessage() to allow for message text to be acquired
  240.     // from the system or the supplied module handle
  241.     //
  242.  
  243.     if(dwBufferLength = FormatMessageA(
  244.         dwFormatFlags,
  245.         hModule, // module to get message from (NULL == system)
  246.         dwLastError,
  247.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
  248.         (LPSTR) &MessageBuffer,
  249.         0,
  250.         NULL
  251.         ))
  252.     {
  253.         DWORD dwBytesWritten;
  254.  
  255.         //
  256.         // Output message string on stderr
  257.         //
  258.         WriteFile(
  259.             GetStdHandle(STD_ERROR_HANDLE),
  260.             MessageBuffer,
  261.             dwBufferLength,
  262.             &dwBytesWritten,
  263.             NULL
  264.             );
  265.  
  266.         //
  267.         // free the buffer allocated by the system
  268.         //
  269.         LocalFree(MessageBuffer);
  270.     }
  271.  
  272.     //
  273.     // if we loaded a message source, unload it
  274.     //
  275.     if(hModule != NULL)
  276.         FreeLibrary(hModule);
  277. }
  278.