锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C++API和类开源 / Windows访问控制模型的创建一个安全对象
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

Windows访问控制模型的创建一个安全对象


17. Creating a Secure object创建一个安全对象

Q. This is all very well and good for a discretionary access control list, but what about a system access control list?问:对于自由访问控制列表来说,这一切都很好,但是对于系统访问控制列表呢?

Apart from administrative and/or troubleshooting purposes, you never need a system Access Control list (I have not yet encountered an SACL other than for test purposes). Anyway, you can only set an SACL if you have the SeSecurityPrivilege enabled. If your object supports inheritance, just get the SACL from the parent. Otherwise, your SACL should be NULL or empty. Remember, if you generate an audit every time you access an object (particularly if you frequently access the object), your Security Event Log will fill up with information overload.除了行政和/或排除故障的目的,你永远需要一个系统访问控制列表(我还没有遇到过比对试验目的的SACL等)。无论如何,只有启用了SACL才能设置SACL SeSecurityPrivilege。如果您的对象支持继承,则只需从父级获取SACL。否则,您的SACL应该为NULL或为空。请记住,如果您每次访问对象时都生成审核(特别是如果您频繁访问该对象),则安全事件日志将充满信息直至过载。

To read and write an SACL, you will need to enable the SeSecurityPrivilege. Adding entries to an SACL is similar to creating a DACL.

  1. To add ACEs in low level instead of calling AddAce(), you call the AddAuditAccessAce() functions.
  2. In SDDL, a SACL is just a DACL with an S in front of it! Audit ACE strings starting with an "AU" rather than an "A" and alarms start with "AL".
  3. The only difference between a CSacl and a CDacl is the way they add ACEs. Otherwise, the rest of the methods are the same.
  4. 要读写SACL,您需要启用SeSecurityPrivilege。将条目添加到SACL,这类似于创建DACL。

    1. 要以较低级别添加ACE而不是调用AddAce(),请调用AddAuditAccessAce()函数。
    2. 在SDDL中,SACL只是前面带有S的DACL!审核ACE字符串以“ AU”而不是“ A”开头,并且警报以“ AL”开头。
    3. aCSacl和a之间的唯一区别CDacl是它们添加ACE的方式。否则,其余方法相同。
...
pSacl.AddAuditAce(ATL::Sids::Users(), WRITE_DAC, true, false);
...

Figure 21: Adding a system access control entry to an SACL.

Q. You have now created both a DACL and an SACL. Now how do you deal with the other members?问:您现在已经创建了DACL和SACL。现在您如何与其他成员打交道?

This section will cover securing a new object only. For a new object, the object by default has no owner. You can specify an owner by filling the Owner member of the security descriptor. A suggested new owner is you (you from your thread token) or your group. However, any user that has WRITE_OWNER access to the object can take ownership of it (and thus get full control to it).本节仅涉及保护新对象。对于新对象,默认情况下该对象没有所有者。您可以通过填充Owner安全描述符的成员来指定所有者。一个建议的新主人是从你的线程令牌)或你的团体。但是,任何有权WRITE_OWNER访问该对象的用户都可以拥有该对象的所有权(因此可以完全控制该对象)。

Few apps read the Group part of the security descriptor, but just in case there are, this should be set to the primary group of your token—obtained from GetTokenInformation(TokenPrimaryGroup).很少有应用程序读取安全描述符的“组”部分,但是以防万一,应将其设置为令牌的主要组-从获取GetTokenInformation(TokenPrimaryGroup)。

The Control member is a collection of flags dumped into a 32 bit integer. Windows will use this parameter to determine which members of the security descriptor are valid. If you are securing an object that supports inheritance, there are extra flags you need to set in the Control member of the security descriptor. If you get one of the flags wrong in this member (e.g.. you say that the group is valid when it in fact isn't), then you may crash.所述控制构件是倾入一个32位整数标志位的集合。Windows将使用此参数来确定安全描述符的哪些成员有效。如果要保护支持继承的对象,则需要在安全描述符的成员中设置其他标志Control。如果您在该成员中得到错误的标志之一(例如,您说该组实​​际上是无效的,则说该组是有效的),那么您可能会崩溃。

To set these members, follow your chosen method:要设置这些成员,请遵循您选择的方法:

  1. In Fig. 17, we discussed a class of functions that could obtain the pieces of a security descriptor. Those functions have corresponding Set functions that, yes you guessed it, set the parts of the security descriptor. These functions work only if the security descriptor is being built absolute (see how useful it was to create an absolute security descriptor from the start?). The SetSecurityDescriptorControl() API was made deliberately tricky so as to prevent you from accidentally turning an absolute security descriptor to a self relative security descriptor. You must supply both the replacement value, and the control bits you intend to change.
  2. If you converted the owner and group SIDs to usernames, you'll have to convert them back. Then to build the owner, append the characters "O:" and the string SID to your SDDL. For the group, append "G:" instead of "O:" first. The control bits are set directly in the "D:" and "S:" tokens.
  3. Once your members have been built up, you can set the security descriptor parts by calling the following methods: CSecurityDesc::SetControl(), CSecurityDesc::SetGroup(), CSecurityDesc::SetOwner(), CSecurityDesc::SetDacl(), CSecurityDesc::SetSacl().
  4. 在图17中,我们讨论了可以获取安全描述符片段的一类函数。这些功能具有相应的Set功能,可以的,您可以设置安全描述符的各个部分。仅当安全描述符是绝对构建的时,这些功能才起作用(请参阅从头开始创建绝对安全描述符有多有用?)。SetSecurityDescriptorControl()故意将API设置为棘手,以防止您意外将绝对安全描述符转换为自我相对安全描述符。您必须同时提供替换值和要更改的控制位。
  5. 如果将所有者和组SID转换为用户名,则必须将其转换回用户名。然后,要构建所有者,请将字符“ O:”和字符串SID附加到SDDL。对于该组,请首先附加“ G:”而不是“ O:”。控制位直接在“ D:”和“ S:”令牌中设置。
  6. 一旦您的会员已经建起来了,你可以通过调用下面的方法设置安全描述符部分:CSecurityDesc::SetControl(),CSecurityDesc::SetGroup(),CSecurityDesc::SetOwner(),CSecurityDesc::SetDacl(),CSecurityDesc::SetSacl()。
...
OutSecDesc.SetOwner(ATL::Sids::Admins(), false);
OutSecDesc.SetGroup(ATL::Sids::Admins(), false);
...

Figure 22: Finalizing the security descriptor for a new object.

Q. How does Inheritance come into this?问:继承是如何实现的?

The inheritance of a security descriptor appears in two places. Each ACE has an inheritance flag that specifies how inheritance is applied to child objects / containers. These flags (the IO, OI, CI, etc.) were described in part 1. This same flag also determines if an ACE came from a parent ACL (which you can detect with the INHERITED_ACE flag).安全描述符的继承出现在两个地方。每个ACE都有一个继承标志,用于指定如何将继承应用于子对象/容器。这些标志(的IO,OI,CI等)中进行了描述部分1。该相同标志还确定ACE是否来自父ACL(可以使用该INHERITED_ACE标志检测到)。

The Control member determines if the DACL and SACL auto-inherit ACEs from their parent. By setting the SE_DACL_AUTO_INHERITED | SE_DACL_AUTO_INHERIT_REQ control flags in a security descriptor, Windows will get the parent's DACL, attach it to the end of your DACL, and write this merged DACL to the object. These inherited ACLs cannot be edited—if you want to change something in the inherited ACL, you must either add in a deny ACE to override the inherited ACE, or stop inheriting.该Control成员决定是否从其父的DACL和SACL自动继承的ACE。通过SE_DACL_AUTO_INHERITED | SE_DACL_AUTO_INHERIT_REQ在安全描述符中设置控制标志,Windows将获取父级的DACL,将其附加到DACL的末尾,然后将此合并的DACL写入对象。这些继承的ACL无法编辑-如果要更改继承的ACL中的某些内容,则必须添加拒绝ACE来覆盖继承的ACE,或者停止继承。

To prevent inheritance, you must set your DACL to be protected (SE_DACL_PROTECTED). If you set this flag, only the explicit entries remain, meaning you may have to copy the parent's DACL into the object to get the old DACL.为了防止继承,您必须将DACL设置为保护(SE_DACL_PROTECTED)。如果设置此标志,则仅保留显式条目,这意味着您可能必须将父级的DACL复制到对象中才能获得旧的DACL。

If you have a protected DACL, and you want to stop it from being protected, you should empty the DACL, then set the SE_DACL_AUTO_INHERIT_REQ Control bit. This will disable DACL protection and enable auto-inheritance.如果您有受保护的DACL,并且想要停止对其进行保护,则应清空DACL,然后将SE_DACL_AUTO_INHERIT_REQ控制位置1。这将禁用DACL保护并启用自动继承。

  1. Inheritance is not supported by the low level methods. This should be reason enough to consider one of the other methods. At the very least, you'll have to branch out to separate code paths for different Windows versions, essentially creating two versions of your program.
  2. You can obtain inheritance information from an SDDL ACE string. In the second token, of an ACE string, there are flags that determine the inheritance of that ACE (which can be "IO", "OI", "CI", "ID" and "NP"). For the control bits, you can set the auto inheritance by post fixing the DACL delimiter with "AI", for example: D:AI(A;ID;FA;;;SY).

    The "AI" after the "D:" tells SDDL to set SE_DACL_AUTO_INHERITED in the Control bits. If instead of "AI", you had "P", then SE_DACL_PROTECTED will be set instead. The last flag, "AR", corresponds to SE_DACL_AUTO_INHERIT_REQ.

  3. You can edit the security descriptor control flags directly with CSecurityDesc::SetControl(). This function requires you to supply two parameters. One is the new value of the Control member, and the other is the flags you wish to set. This is to prevent you from accidentally changing a security descriptor from self-relative to absolute.
  4. 底层方法不支持继承。这应该是考虑其他方法之一的充分理由。至少,您必须针对不同的Windows版本分支到单独的代码路径,实际上是创建程序的两个版本。
  5. 您可以从SDDL ACE字符串获取继承信息。在ACE字符串的第二个标记中,有确定该ACE继承的标志(可以是“ IO”,“ OI”,“ CI”,“ ID”和“ NP”)。对于控制位,可以通过将DACL分隔符后缀为“ AI”来设置自动继承,例如:D:AI(A;ID;FA;;;SY)。

    “ AI”之后的“ D:”告诉SDDL设置SE_DACL_AUTO_INHERITED控制位。如果AI您有“ P”SE_DACL_PROTECTED而不是“ ”,则将被设置。最后一个标志“ AR”对应于SE_DACL_AUTO_INHERIT_REQ。

  6. 您可以直接使用编辑安全描述符控制标志CSecurityDesc::SetControl()。此功能需要您提供两个参数。一个是Control成员的新值,另一个是您要设置的标志。这是为了防止您意外地将安全描述符从自相关更改为绝对。
...
OutSecDesc.SetControl(SE_DACL_AUTO_INHERITED |
SE_DACL_PROTECTED, SE_DACL_AUTO_INHERITED);
...

Figure 23: Supporting inheritance for security descriptors.

The inheritance rules for SACLs are the same as DACLs.

Q. Create a Windows NT object that bears your security descriptor.问:创建一个带有您的安全描述符的Windows NT对象。

When you created a Windows object, you encountered a parameter asking for a SECURITY_ATTRIBUTES structure (unless you encountered a wrapper class / function for the resource). This is where you will supply the security descriptor for the new object. Note that some objects do not support all the features of security descriptors (particularly inheritance)--in this case, these extra features will be ignored (which could lead to inaccessible objects if you're not careful). Once you pass this parameter in, that should be it. How the security descriptor gets stored is the object's problem, not yours. However, to prevent surprises, you should ensure that the object is created (not merely opened). If the object already exists, then the security descriptor is not applied, and the security attributes are ignored.创建Windows对象时,遇到一个要求SECURITY_ATTRIBUTES结构的参数(除非遇到该资源的包装器类/函数)。您将在此处提供新对象的安全描述符。请注意,某些对象不支持安全描述符的所有功能(尤其是继承),在这种情况下,这些额外的功能将被忽略(如果不小心,可能会导致无法访问对象)。一旦传入此参数,就应该是它。安全描述符的存储方式是对象的问题,而不是您的问题。但是,为防止意外,应确保已创建对象(不仅仅是打开对象)。如果对象已经存在,则不应用安全描述符,并且忽略安全属性。

Generally, in order to access the SECURITY_ATTRIBUTES, you'll probably want to use the Win32 APIs directly. This is because most wrapper classes neglect the SECURITY_ATTRIBUTES parameter, and pass in NULL for this class. (CAtlFile is an exception, but by default, it passes in NULL too.)通常,为了访问SECURITY_ATTRIBUTES,您可能需要直接使用Win32 API。这是因为大多数包装器类都忽略了SECURITY_ATTRIBUTES参数,并NULL为此类传递了参数。(这CAtlFile是一个例外,但默认情况下NULL也会通过。)

if(::GetFileAttributes(FileName) == INVALID_FILE_ATTRIBUTES)
{
  SECURITY_ATTRIBUTES lpSecurityAttributes =
    {sizeof(SECURITY_ATTRIBUTES),
    const_cast
  (OutSecDesc.GetPSECURITY_DESCRIPTOR()), FALSE};

  ::SetLastError(ERROR_SUCCESS);
  /** We're going to use the low level Win32 APIs
  * instead of ATL::CAtlFile
  **/
  ATL::CHandle FileHandle (::CreateFile(FileName, GENERIC_ALL |
     READ_CONTROL | WRITE_DAC, 
     FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
     &lpSecurityAttributes,
     CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL));
  if( static_cast(FileHandle) == NULL ||
      static_cast(FileHandle) == INVALID_HANDLE_VALUE)
  {
    throw ATL::CAtlException(HRESULT_FROM_WIN32(::GetLastError()));
  }
}
/* The else part will be handled in fig. 24. */

Figure 24: Creating an object that has a custom security descriptor.

This technique doesn't work if the object already exists. If you open an existing object, the security descriptor is ignored.

Q. The object already exists. The current security descriptor needs to be edited, instead of created. How do we do that?问:该对象已存在。当前的安全描述符需要被编辑而不是创建。我们该怎么做?

This question assumes you either know the name and type of the object you are securing, or you have a handle to that object. If you are securing an existing object, you can get away with creating an incomplete security descriptor (e.g.. a security descriptor without an owner or group). You tell Windows which parts of the security descriptor are valid by passing in a SECURITY_INFORMATION variable. For example, if you are just setting the DACL of an object, you can specify DACL_SECURITY_INFORMATION.这个问题假设您知道要保护的对象的名称和类型,或者您有该对象的句柄。如果要保护现有对象,则可以创建一个不完整的安全描述符(例如,没有所有者或组的安全描述符)。您可以通过传入SECURITY_INFORMATION变量来告诉Windows安全描述符的哪些部分有效。例如,如果仅设置对象的DACL,则可以指定DACL_SECURITY_INFORMATION。

  1. In this method, the solution becomes specific to the object you are trying to set. If you take a deep look at the security documentation, you may be able to find the correct function to use. For example, to set the security descriptor for files, you need to call SetFileSecurity(). For registry keys it's RegSetKeySecurity(). None of the older APIs work with inheritance, so if you use these APIs on a Windows 2000 system, you can severely damage the inheritance.
  2. The preferred API for setting security descriptors is SetSecurityInfo(). Plus it supports inheritance (and multiple inheritance). Although this function first appeared in Windows NT 3.51, the early versions had some bugs meaning it could only be applied in limited circumstances. With Windows NT4 SP6, all these bugs have been fixed.
  3. 在这种方法中,解决方案变得特定于您要设置的对象。如果您对安全性文档进行了深入研究,则可以找到要使用的正确功能。例如,要设置文件的安全描述符,您需要调用SetFileSecurity()。对于注册表项,它是RegSetKeySecurity()。较旧的API都无法与继承一起使用,因此,如果在Windows 2000系统上使用这些API,则可能会严重破坏继承。
  4. 设置安全描述符的首选API是SetSecurityInfo()。加上它支持继承(和多重继承)。尽管此功能首次出现在Windows NT 3.51中,但早期版本有一些错误,这意味着它只能在有限的情况下应用。使用Windows NT4 SP6,所有这些错误已得到修复。
  5. If you cannot obtain a handle to the file (say, you don't have READ_CONTROL or WRITE_DAC access yet), you can call the similar SetNamedSecurityInfo() function to set the security for the file. However, the SetSecurityInfo() function can secure more objects than SetNamedSecurityInfo().如果你不能获得一个句柄的文件(比如说,你没有READ_CONTROL或WRITE_DAC访问还),你可以调用类似的SetNamedSecurityInfo()函数来设置该文件的安全性。但是,该SetSecurityInfo()功能可以保护的对象比的更多SetNamedSecurityInfo()。

    SetNamedSecurityInfo() can set the security on the following objects:

    • SE_FILE_OBJECT: a file system object (file or directory).
    • SE_SERVICE: an NT service.
    • SE_PRINTER: a local or remote printer.
    • SE_REGISTRY_KEY: a registry key.
    • SE_LMSHARE: a NetBIOS share.
    • SE_KERNEL_OBJECT: a semaphore, event, mutex, waitable timer, or file mapping.
    • SE_WINDOW_OBJECT: a window station.
    • SE_DS_OBJECT: a specific property of a Directory Services object.
    • SE_DS_OBJECT_ALL: all properties of a Directory Services object.
    • SE_PROVIDER_DEFINED_OBJECT: a provider defined object.
    • SE_WMIGUID_OBJECT: a WMI object.
    • SE_REGISTRY_WOW64_32_KEY: a WOW32 registry key (works only inside a 64 bit application).
    • SetNamedSecurityInfo() 可以对以下对象设置安全性:

      • SE_FILE_OBJECT:文件系统对象(文件或目录)。
      • SE_SERVICE:NT服务。
      • SE_PRINTER:本地或远程打印机。
      • SE_REGISTRY_KEY:注册表项。
      • SE_LMSHARE:NetBIOS共享。
      • SE_KERNEL_OBJECT:信号量,事件,互斥量,可等待的计时器或文件映射。
      • SE_WINDOW_OBJECT:窗口站。
      • SE_DS_OBJECT:目录服务对象的特定属性。
      • SE_DS_OBJECT_ALL:目录服务对象的所有属性。
      • SE_PROVIDER_DEFINED_OBJECT:提供者定义的对象。
      • SE_WMIGUID_OBJECT:一个WMI对象。
      • SE_REGISTRY_WOW64_32_KEY:WOW32注册表项(仅在64位应用程序中有效)。

    For SetNamedSecurityInfo() to work, you have to split your security descriptor back into separate pieces. You can call GetSecurityDescriptorDacl() and friends to get these members (portably). One thing to note is that SetSecurityInfo() apparently doesn't allow you to set the control bits directly. Instead, you provide the control bits in the SECURITY_INFORMATION parameter. The Control bits to SECURITY_INFORMATION mapping is as follows:为了SetNamedSecurityInfo()工作,您必须将安全描述符拆分成单独的部分。您可以打电话GetSecurityDescriptorDacl()和朋友来获得这些成员(便携式)。需要注意的一件事是,SetSecurityInfo()显然不允许您直接设置控制位。而是在SECURITY_INFORMATION参数中提供控制位。SECURITY_INFORMATION映射的控制位如下:

    • SE_DACL_PRESENT --> DACL_SECURITY_INFORMATION.
    • SE_SACL_PRESENT --> SACL_SECURITY_INFORMATION (make sure you have the SeSecurityPrivilege).
    • SE_DACL_AUTO_INHERITED --> UNPROTECTED_DACL_SECURITY_INFORMATION.
    • SE_SACL_AUTO_INHERITED --> UNPROTECTED_SACL_SECURITY_INFORMATION (make sure you have the SeSecurityPrivilege).
    • SE_DACL_PROTECTED --> PROTECTED_DACL_SECURITY_INFORMATION.
    • SE_SACL_PROTECTED --> PROTECTED_SACL_SECURITY_INFORMATION (make sure you have the SeSecurityPrivilege).
    • SE_DACL_DEFAULTED --> [None]. SetSecurityInfo() doesn't care if the security descriptor is a default..
    • SE_SACL_DEFAULTED --> [None]. SetSecurityInfo() doesn't care if the security descriptor is a default..
    • SE_GROUP_DEFAULTED --> GROUP_SECURITY_INFORMATION.
    • SE_OWNER_DEFAULTED --> OWNER_SECURITY_INFORMATION.
    • SE_SELF_RELATIVE --> [None]. SetSecurityInfo() doesn't care if the security descriptor is self relative or absolute.
    • SE_DACL_PRESENT-> DACL_SECURITY_INFORMATION。
    • SE_SACL_PRESENT-> SACL_SECURITY_INFORMATION(确保您有SeSecurityPrivilege)。
    • SE_DACL_AUTO_INHERITED-> UNPROTECTED_DACL_SECURITY_INFORMATION。
    • SE_SACL_AUTO_INHERITED-> UNPROTECTED_SACL_SECURITY_INFORMATION(确保您有SeSecurityPrivilege)。
    • SE_DACL_PROTECTED-> PROTECTED_DACL_SECURITY_INFORMATION。
    • SE_SACL_PROTECTED-> PROTECTED_SACL_SECURITY_INFORMATION(确保您有SeSecurityPrivilege)。
    • SE_DACL_DEFAULTED-> [无]。SetSecurityInfo()不管安全描述符是否为默认值。
    • SE_SACL_DEFAULTED-> [无]。SetSecurityInfo()不管安全描述符是否为默认值。
    • SE_GROUP_DEFAULTED-> GROUP_SECURITY_INFORMATION。
    • SE_OWNER_DEFAULTED-> OWNER_SECURITY_INFORMATION。
    • SE_SELF_RELATIVE-> [无]。SetSecurityInfo()不管安全描述符是自相关还是绝对的。

    Use this map to translate the control bits into SECURITY_INFORMATION flags. This new security descriptor will replace the old security descriptor. If this is not what you want (i.e. you want to add entries to the DACL rather than replace it), you have to merge the old entries with the new ones yourself, or you could apply auto-inheritance (these will be automatically applied onto the child).

    If you have the rights, the security descriptor should get applied to the object with the correct inheritance settings and sorted entries. The Set*SecurityInfo() does not support NULL DACLs, and will fail if you attempt to set one.

    使用此映射将控制位转换为SECURITY_INFORMATION标志。此新的安全描述符将替换旧的安全描述符。如果这不是您想要的(即,您想要将条目添加到DACL而不是替换它),则必须自己将旧条目与新条目合并,或者可以应用自动继承(这些将自动应用于孩子)。

    如果您拥有权限,则应该使用正确的继承设置和排序的条目将安全描述符应用于对象。,Set*SecurityInfo()不支持NULLDACL,如果您尝试设置一个,它将失败。

  6. Instead of calling SetSecurityInfo(), you are required to set the security descriptor parts one by one. To set the owner, you call AtlSetOwnerSid(). Similarly, you have AtlSetGroupSid(), AtlSetDacl() and AtlSetSacl() to set the group DACL and SACL. Internally, these functions call SetSecurityInfo(), so the rules for method 2 are the same for ATL. If you are in a debug build, ATL will flag a warning if you try to set a NULL DACL to the object.
  7. 无需调用SetSecurityInfo(),而是需要一一设置安全描述符。要设置所有者,请致电AtlSetOwnerSid()。同样,您有AtlSetGroupSid(),AtlSetDacl()并AtlSetSacl()设置了组DACL和SACL。在内部,这些函数调用SetSecurityInfo(),因此方法2的规则与ATL相同。如果您在调试版本中,则当您尝试将NULLDACL设置为对象时,ATL将标记警告。
...
ATL::AtlSetDacl(FileName, SE_FILE_OBJECT, pDacl);
ATL::CSacl pSacl;
/* We've already set the Dacl. Now set the SACL. */
OutSecDesc.GetSacl(&pSacl, &pbPresent);
if(pbPresent)
{
  ATL::AtlSetSacl(FileName, SE_FILE_OBJECT, pSacl);
}
ATL::CSid pOwner, pGroup;
if(OutSecDesc.GetOwner(&pOwner))
{
  ATL::AtlSetOwnerSid(FileName, SE_FILE_OBJECT, pOwner);
}
if(OutSecDesc.GetGroup(&pGroup))
{
  ATL::AtlSetGroupSid(FileName, SE_FILE_OBJECT, pGroup);
}

...

Figure 25: Applying the security descriptor to an existing object

In order for SetSecurityInfo() to succeed, you must have the WRITE_DAC right to set the DACL and WRITE_OWNER rights to set the owner. If you were denied the WRITE_OWNER | WRITE_DAC right, you can acquire these by taking ownership of the file. Enabling the SeTakeOwnershipPrivilege will allow you to take ownership of the file (even if WRITE_OWNER was disabled).

Although the Set*SecurityInfo() functions work with almost all of the Windows built-in objects (and even some special objects), you may want to implement security descriptors for your own classes.为了SetSecurityInfo()成功,您必须具有WRITE_DAC设置DACL的WRITE_OWNER权限和设置所有者的权限。如果您被拒绝使用该WRITE_OWNER | WRITE_DAC权利,则可以通过获取文件所有权来获取这些权利。启用SeTakeOwnershipPrivilege将允许您取得文件的所有权(即使WRITE_OWNER已禁用)。

尽管这些Set*SecurityInfo()函数可用于几乎所有Windows内置对象(甚至某些特殊对象),但是您可能希望为自己的类实现安全描述符。

友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内