SDMGMT.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:12k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*++
  2. DCOM Permission Configuration Sample
  3. Copyright (c) 1996, Microsoft Corporation. All rights reserved.
  4. Module Name:
  5.     sdmgmt.cpp
  6. Abstract:
  7.     Routines to manage security descriptors
  8. Author:
  9.     Michael Nelson
  10. Environment:
  11.     Windows NT
  12. --*/
  13. #include <windows.h>
  14. #include <stdio.h>
  15. #include <conio.h>
  16. #include <tchar.h>
  17. #include "ntsecapi.h"
  18. #include "dcomperm.h"
  19. DWORD
  20. CreateNewSD (
  21.     SECURITY_DESCRIPTOR **SD
  22.     )
  23. {
  24.     PACL    dacl;
  25.     DWORD   sidLength;
  26.     PSID    sid;
  27.     PSID    groupSID;
  28.     PSID    ownerSID;
  29.     DWORD   returnValue;
  30.     *SD = NULL;
  31.     returnValue = GetCurrentUserSID (&sid);
  32.     if (returnValue != ERROR_SUCCESS)
  33.         return returnValue;
  34.     sidLength = GetLengthSid (sid);
  35.     *SD = (SECURITY_DESCRIPTOR *) malloc (
  36.         (sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength) +
  37.         (2 * sidLength) +
  38.         sizeof (SECURITY_DESCRIPTOR));
  39.     groupSID = (SID *) (*SD + 1);
  40.     ownerSID = (SID *) (((BYTE *) groupSID) + sidLength);
  41.     dacl = (ACL *) (((BYTE *) ownerSID) + sidLength);
  42.     if (!InitializeSecurityDescriptor (*SD, SECURITY_DESCRIPTOR_REVISION))
  43.     {
  44.         free (*SD);
  45.         free (sid);
  46.         return GetLastError();
  47.     }
  48.     if (!InitializeAcl (dacl,
  49.                         sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength,
  50.                         ACL_REVISION2))
  51.     {
  52.         free (*SD);
  53.         free (sid);
  54.         return GetLastError();
  55.     }
  56.     if (!AddAccessAllowedAce (dacl,
  57.                               ACL_REVISION2,
  58.                               COM_RIGHTS_EXECUTE,
  59.                               sid))
  60.     {
  61.         free (*SD);
  62.         free (sid);
  63.         return GetLastError();
  64.     }
  65.     if (!SetSecurityDescriptorDacl (*SD, TRUE, dacl, FALSE))
  66.     {
  67.         free (*SD);
  68.         free (sid);
  69.         return GetLastError();
  70.     }
  71.     memcpy (groupSID, sid, sidLength);
  72.     if (!SetSecurityDescriptorGroup (*SD, groupSID, FALSE))
  73.     {
  74.         free (*SD);
  75.         free (sid);
  76.         return GetLastError();
  77.     }
  78.     memcpy (ownerSID, sid, sidLength);
  79.     if (!SetSecurityDescriptorOwner (*SD, ownerSID, FALSE))
  80.     {
  81.         free (*SD);
  82.         free (sid);
  83.         return GetLastError();
  84.     }
  85.     return ERROR_SUCCESS;
  86. }
  87. DWORD
  88. MakeSDAbsolute (
  89.     PSECURITY_DESCRIPTOR OldSD,
  90.     PSECURITY_DESCRIPTOR *NewSD
  91.     )
  92. {
  93.     PSECURITY_DESCRIPTOR  sd;
  94.     DWORD                 descriptorSize;
  95.     DWORD                 daclSize;
  96.     DWORD                 saclSize;
  97.     DWORD                 ownerSIDSize;
  98.     DWORD                 groupSIDSize;
  99.     PACL                  dacl;
  100.     PACL                  sacl;
  101.     PSID                  ownerSID;
  102.     PSID                  groupSID;
  103.     BOOL                  present;
  104.     BOOL                  systemDefault;
  105.     //
  106.     // Get SACL
  107.     //
  108.     if (!GetSecurityDescriptorSacl (OldSD, &present, &sacl, &systemDefault))
  109.         return GetLastError();
  110.     if (sacl && present)
  111.     {
  112.         saclSize = sacl->AclSize;
  113.     } else saclSize = 0;
  114.     //
  115.     // Get DACL
  116.     //
  117.     if (!GetSecurityDescriptorDacl (OldSD, &present, &dacl, &systemDefault))
  118.         return GetLastError();
  119.     if (dacl && present)
  120.     {
  121.         daclSize = dacl->AclSize;
  122.     } else daclSize = 0;
  123.     //
  124.     // Get Owner
  125.     //
  126.     if (!GetSecurityDescriptorOwner (OldSD, &ownerSID, &systemDefault))
  127.         return GetLastError();
  128.     ownerSIDSize = GetLengthSid (ownerSID);
  129.     //
  130.     // Get Group
  131.     //
  132.     if (!GetSecurityDescriptorGroup (OldSD, &groupSID, &systemDefault))
  133.         return GetLastError();
  134.     groupSIDSize = GetLengthSid (groupSID);
  135.     //
  136.     // Do the conversion
  137.     //
  138.     descriptorSize = 0;
  139.     MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl,
  140.                     &saclSize, ownerSID, &ownerSIDSize, groupSID,
  141.                     &groupSIDSize);
  142.     sd = (PSECURITY_DESCRIPTOR) new BYTE [SECURITY_DESCRIPTOR_MIN_LENGTH];
  143.     if (!InitializeSecurityDescriptor (sd, SECURITY_DESCRIPTOR_REVISION))
  144.         return GetLastError();
  145.     if (!MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl,
  146.                          &saclSize, ownerSID, &ownerSIDSize, groupSID,
  147.                          &groupSIDSize))
  148.         return GetLastError();
  149.     *NewSD = sd;
  150.     return ERROR_SUCCESS;
  151. }
  152. DWORD
  153. SetNamedValueSD (
  154.     HKEY RootKey,
  155.     LPTSTR KeyName,
  156.     LPTSTR ValueName,
  157.     SECURITY_DESCRIPTOR *SD
  158.     )
  159. {
  160.     DWORD   returnValue;
  161.     DWORD   disposition;
  162.     HKEY    registryKey;
  163.     //
  164.     // Create new key or open existing key
  165.     //
  166.     returnValue = RegCreateKeyEx (RootKey, KeyName, 0, TEXT(""), 0, KEY_ALL_ACCESS, NULL, &registryKey, &disposition);
  167.     if (returnValue != ERROR_SUCCESS)
  168.         return returnValue;
  169.     //
  170.     // Write the security descriptor
  171.     //
  172.     returnValue = RegSetValueEx (registryKey, ValueName, 0, REG_BINARY, (LPBYTE) SD, GetSecurityDescriptorLength (SD));
  173.     if (returnValue != ERROR_SUCCESS)
  174.         return returnValue;
  175.     RegCloseKey (registryKey);
  176.     return ERROR_SUCCESS;
  177. }
  178. DWORD
  179. GetNamedValueSD (
  180.     HKEY RootKey,
  181.     LPTSTR KeyName,
  182.     LPTSTR ValueName,
  183.     SECURITY_DESCRIPTOR **SD,
  184.     BOOL *NewSD
  185.     )
  186. {
  187.     DWORD               returnValue;
  188.     HKEY                registryKey;
  189.     DWORD               valueType;
  190.     DWORD               valueSize;
  191.     *NewSD = FALSE;
  192.     //
  193.     // Get the security descriptor from the named value. If it doesn't
  194.     // exist, create a fresh one.
  195.     //
  196.     returnValue = RegOpenKeyEx (RootKey, KeyName, 0, KEY_ALL_ACCESS, &registryKey);
  197.     if (returnValue != ERROR_SUCCESS)
  198.     {
  199.         if (returnValue == ERROR_FILE_NOT_FOUND)
  200.         {
  201.             *SD = NULL;
  202.             returnValue = CreateNewSD (SD);
  203.             if (returnValue != ERROR_SUCCESS)
  204.                 return returnValue;
  205.             *NewSD = TRUE;
  206.             return ERROR_SUCCESS;
  207.         } else
  208.             return returnValue;
  209.     }
  210.     returnValue = RegQueryValueEx (registryKey, ValueName, NULL, &valueType, NULL, &valueSize);
  211.     if (returnValue && returnValue != ERROR_INSUFFICIENT_BUFFER)
  212.     {
  213.         *SD = NULL;
  214.         returnValue = CreateNewSD (SD);
  215.         if (returnValue != ERROR_SUCCESS)
  216.             return returnValue;
  217.         *NewSD = TRUE;
  218.     } else
  219.     {
  220.         *SD = (SECURITY_DESCRIPTOR *) malloc (valueSize);
  221.         returnValue = RegQueryValueEx (registryKey, ValueName, NULL, &valueType, (LPBYTE) *SD, &valueSize);
  222.         if (returnValue)
  223.         {
  224.             free (*SD);
  225.             *SD = NULL;
  226.             returnValue = CreateNewSD (SD);
  227.             if (returnValue != ERROR_SUCCESS)
  228.                 return returnValue;
  229.             *NewSD = TRUE;
  230.         }
  231.     }
  232.     RegCloseKey (registryKey);
  233.     return ERROR_SUCCESS;
  234. }
  235. DWORD
  236. ListNamedValueSD (
  237.     HKEY RootKey,
  238.     LPTSTR KeyName,
  239.     LPTSTR ValueName
  240.     )
  241. {
  242.     DWORD               returnValue;
  243.     SECURITY_DESCRIPTOR *sd;
  244.     BOOL                present;
  245.     BOOL                defaultDACL;
  246.     PACL                dacl;
  247.     BOOL                newSD = FALSE;
  248.     returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD);
  249.     if ((returnValue != ERROR_SUCCESS) || (newSD == TRUE))
  250.     {
  251.         _tprintf (TEXT("<Using Default Permissions>n"));
  252.         free (sd);
  253.         return returnValue;
  254.     }
  255.     if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL))
  256.     {
  257.         free (sd);
  258.         return GetLastError();
  259.     }
  260.     if (!present)
  261.     {
  262.         _tprintf (TEXT("<Access is denied to everyone>n"));
  263.         free (sd);
  264.         return ERROR_SUCCESS;
  265.     }
  266.     ListACL (dacl);
  267.     free (sd);
  268.     return ERROR_SUCCESS;
  269. }
  270. DWORD
  271. AddPrincipalToNamedValueSD (
  272.     HKEY RootKey,
  273.     LPTSTR KeyName,
  274.     LPTSTR ValueName,
  275.     LPTSTR Principal,
  276.     BOOL Permit
  277.     )
  278. {
  279.     DWORD               returnValue;
  280.     SECURITY_DESCRIPTOR *sd;
  281.     SECURITY_DESCRIPTOR *sdSelfRelative;
  282.     SECURITY_DESCRIPTOR *sdAbsolute;
  283.     DWORD               secDescSize;
  284.     BOOL                present;
  285.     BOOL                defaultDACL;
  286.     PACL                dacl;
  287.     BOOL                newSD = FALSE;
  288.     returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD);
  289.     //
  290.     // Get security descriptor from registry or create a new one
  291.     //
  292.     if (returnValue != ERROR_SUCCESS)
  293.         return returnValue;
  294.     if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL))
  295.         return GetLastError();
  296.     if (newSD)
  297.     {
  298.         AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, TEXT("SYSTEM"));
  299.         AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, TEXT("INTERACTIVE"));
  300.     }
  301.     //
  302.     // Add the Principal that the caller wants added
  303.     //
  304.     if (Permit)
  305.         returnValue = AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, Principal); else
  306.         returnValue = AddAccessDeniedACEToACL (&dacl, GENERIC_ALL, Principal);
  307.     if (returnValue != ERROR_SUCCESS)
  308.     {
  309.         free (sd);
  310.         return returnValue;
  311.     }
  312.     //
  313.     // Make the security descriptor absolute if it isn't new
  314.     //
  315.     if (!newSD)
  316.         MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute); else
  317.         sdAbsolute = sd;
  318.     //
  319.     // Set the discretionary ACL on the security descriptor
  320.     //
  321.     if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE))
  322.         return GetLastError();
  323.     //
  324.     // Make the security descriptor self-relative so that we can
  325.     // store it in the registry
  326.     //
  327.     secDescSize = 0;
  328.     MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize);
  329.     sdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (secDescSize);
  330.     if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize))
  331.         return GetLastError();
  332.     //
  333.     // Store the security descriptor in the registry
  334.     //
  335.     SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative);
  336.     free (sd);
  337.     free (sdSelfRelative);
  338.     free (sdAbsolute);
  339.     return ERROR_SUCCESS;
  340. }
  341. DWORD
  342. RemovePrincipalFromNamedValueSD (
  343.     HKEY RootKey,
  344.     LPTSTR KeyName,
  345.     LPTSTR ValueName,
  346.     LPTSTR Principal
  347.     )
  348. {
  349.     DWORD               returnValue;
  350.     SECURITY_DESCRIPTOR *sd;
  351.     SECURITY_DESCRIPTOR *sdSelfRelative;
  352.     SECURITY_DESCRIPTOR *sdAbsolute;
  353.     DWORD               secDescSize;
  354.     BOOL                present;
  355.     BOOL                defaultDACL;
  356.     PACL                dacl;
  357.     BOOL                newSD = FALSE;
  358.     returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD);
  359.     //
  360.     // Get security descriptor from registry or create a new one
  361.     //
  362.     if (returnValue != ERROR_SUCCESS)
  363.         return returnValue;
  364.     if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL))
  365.         return GetLastError();
  366.     //
  367.     // If the security descriptor is new, add the required Principals to it
  368.     //
  369.     if (newSD)
  370.     {
  371.         AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, TEXT("SYSTEM"));
  372.         AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, TEXT("INTERACTIVE"));
  373.     }
  374.     //
  375.     // Remove the Principal that the caller wants removed
  376.     //
  377.     returnValue = RemovePrincipalFromACL (dacl, Principal);
  378.     if (returnValue != ERROR_SUCCESS)
  379.     {
  380.         free (sd);
  381.         return returnValue;
  382.     }
  383.     //
  384.     // Make the security descriptor absolute if it isn't new
  385.     //
  386.     if (!newSD)
  387.         MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute); else
  388.         sdAbsolute = sd;
  389.     //
  390.     // Set the discretionary ACL on the security descriptor
  391.     //
  392.     if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE))
  393.         return GetLastError();
  394.     //
  395.     // Make the security descriptor self-relative so that we can
  396.     // store it in the registry
  397.     //
  398.     secDescSize = 0;
  399.     MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize);
  400.     sdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (secDescSize);
  401.     if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize))
  402.         return GetLastError();
  403.     //
  404.     // Store the security descriptor in the registry
  405.     //
  406.     SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative);
  407.     free (sd);
  408.     free (sdSelfRelative);
  409.     free (sdAbsolute);
  410.     return ERROR_SUCCESS;
  411. }