锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

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

Windows访问控制模型的SID


9. Pick your poison (choose your language)选择你的语言

At the end of part 1, I asked you to choose which language to program in. I presented four choices for you:

  1. The low level method.
  2. The Windows 2000 method.
  3. The ATL method.
  4. The .NET method. (If you chose this, skip this part and go straight to part 3.)
  5. 在第1部分的结尾,我要求您选择要编程的语言。我为您提供了四种选择:

    1. 底层方法。
    2. Windows 2000方法。
    3. ATL方法。
    4. .NET方法。(如果选择此选项,请跳过此部分,直接进入第3部分。)

A detailed look at each method每种方法的详细介绍

  • The low level method involves using the original security APIs to create and read the security objects (dating back to day one of Windows NT in 1988). This method has the advantage of working in Windows NT3.x and NT4.x. It also has the advantage of not being reliant on any external DLLs, or require you to buy Visual Studio .NET (this method doesn't work on Win9x, so you'll have to rely on dynamic loading if you care about backward compatibility).底层方法涉及使用原始安全性API创建和读取安全性对象(可追溯到1988年Windows NT的第一天)。此方法的优点是可以在Windows NT3.x和NT4.x中使用。它还具有不依赖任何外部DLL的优点,或者要求您购买Visual Studio .NET(此方法在Win9x上不起作用,因此,如果您关心向后兼容性,则必须依靠动态加载)。

    In order to get this method to work, you have to call some of the most confusing APIs in the Windows SDK! These low level APIs know nothing about the inheritance model of Windows 2000 (using these APIs will lead to a security bug on Windows 2000). There's no consistency as to whether the functions return bools, errnos, pointers, or voids. And one API expects you to manage five memory buffers, all from the LocalAlloc() heap! It's very easy to make a mistake developing with this method.为了使该方法起作用,您必须调用Windows SDK中一些最令人困惑的API!这些低级API对Windows 2000的继承模型一无所知(使用这些API将导致Windows 2000上的安全性错误)。函数是否返回bools,errnos,指针或voids不一致。一个API期望您从LocalAlloc()堆中管理五个内存缓冲区!使用这种方法开发错误很容易。

    The only reason you'd want to use this technique is if your target market still uses Windows NT3.x or 4.x (and you enjoy being on the security mailing lists). New programs must not choose this technique at all. If you need to support just one Win9x or Win2000 client, you must not develop using this method. I feel sorry for you if you're forced to develop with this method of Access Control. Since your target environment is crippled, I will be assuming that your development environment is crippled (i.e. you don't have a reliable C++ compiler). This method will be programmed in C.

    1. 您想要使用此技术的唯一原因是,如果您的目标市场仍然使用Windows NT3.x或4.x(并且您喜欢被列入安全邮件列表中)。新程序绝对不能选择这种技术。如果只需要支持一个Win9x或Win2000客户端,则不能使用此方法进行开发。如果您被迫使用这种访​​问控制方法进行开发,我为您感到抱歉。由于您的目标环境很糟糕,因此我假设您的开发环境也很糟糕(即您没有可靠的C ++编译器)。此方法将用C编程。


  • New programs should not be considering anything below this method. This method bears the advantage that you don't need Visual Studio .NET to develop with security, and it is the most comfortable language to program with for people who don't like ATL. However, this method bears the disadvantage that it only works on Windows 2000 and later. Coding with security descriptors becomes a little tough with this method too (unless you've coded textual parsers before).新程序不应考虑使用此方法之外的任何方法。此方法的优点是您无需使用Visual Studio .NET即可安全地进行开发,并且它是不喜欢ATL的人员最容易编程的语言。但是,此方法具有只能在Windows 2000及更高版本上运行的缺点。使用此方法对安全描述符进行编码也变得有些困难(除非您之前已经对文本解析器进行了编码)。

    During Windows NT 4 and 2000, Microsoft added a new set of APIs to make security programming easier. Perhaps the most significant result was the addition of the Security Descriptor Definition Language (SDDL).在Windows NT 4和2000中,Microsoft添加了一组新的API,以简化安全编程。也许最重要的结果是添加了安全描述符定义语言(SDDL)。

    The Security Descriptor Definition Language (SDDL) presents security descriptors as a data-driven structure rather than as a programmatic structure, so both developers and administrators can now write security descriptors. At first sight SDDL seems to be just as non-descript as the low level structures, but if you look at enough SDDL strings, you will see it is far simpler to make SDDL strings than raw structures. The ConvertSecurityDescriptorToStringSecurityDescriptor() and ConvertStringSecurityDescriptorToSecurityDescriptor() functions make it easy to convert SDDL to security descriptors.安全描述符定义语言(SDDL)将安全描述符以数据驱动的结构而不是程序结构的形式呈现,因此开发人员和管理员现在都可以编写安全描述符。乍一看,SDDL似乎与底层结构一样没有描述性,但是如果您查看足够的SDDL字符串,就会发现制作SDDL字符串要比原始结构简单得多。该ConvertSecurityDescriptorToStringSecurityDescriptor()和ConvertStringSecurityDescriptorToSecurityDescriptor()功能可以很容易地SDDL转换为安全描述符。

    The other significant addition to Windows 2000 was the automatic inheritance of DACLs (described in part 1). The support of automatic inheritance required the addition of new APIs to manipulate them, and you can find this new functionality in the GetSecurityInfo() functions (or the GetPrivateObjectSecurityEx() functions if you are using a custom class).Windows 2000的另一个重要添加是DACL的自动继承(在第1部分中进行了介绍)。对自动继承的支持要求添加新的API来对其进行操作,并且您可以在GetSecurityInfo()函数(或GetPrivateObjectSecurityEx()使用自定义类的函数)中找到此新功能。

  • During the Trustworthy Computing Initiative, Microsoft added a set of classes to ATL that allowed ATL projects to manipulate security descriptors and Access Control lists as easily as calling a COM server. This method bears the advantage of providing a fully object oriented framework for Access Control editing (the way security should have been implemented from day one). There is no longer a need to manage buffers, or check the type of the return code, or create text parsers.在“可信赖计算计划”期间,Microsoft向ATL添加了一组类,这些类使ATL项目可以像调用COM服务器一样轻松地操作安全描述符和访问控制列表。这种方法的优点是为访问控制编辑提供了一个完全面向对象的框架(从一开始就应该实现安全性)。不再需要管理缓冲区,检查返回码的类型或创建文本解析器。

    If you work carefully enough, you can make this technique run on Windows NT! This article will not tell you how to do this (you'll just have to read the documentation carefully) but it is possible.如果您足够仔细地工作,则可以使该技术在Windows NT上运行!本文不会告诉您如何执行此操作(您只需要仔细阅读文档即可),但是有可能。

    There is a requirement that you have to redistribute the ATL DLLs (or expect for a bloated application), and if you don't own Visual Studio .NET, this method will be unavailable. Finally, if you are one of those that loath ATL, you are unlikely to choose this method.有一个要求,您必须重新分发ATL DLL(或期望用于application肿的应用程序),并且,如果您不拥有Visual Studio .NET,则此方法将不可用。最后,如果您不喜欢ATL,则不太可能选择此方法。

  • (This will be discussed in the next part).(这将在下一部分中讨论)。
  • You most likely based your decision either on your previous experience of Access Control, or your programming background. Now unfortunately, for this article I have already made the decision for you: "All the code in this article will use the ATL way". But don't worry! The demo project includes equivalent programs for all the four methods. And I will discuss all the solutions to the problem, one for each method (it's just the code that will be presented in ATL).您很可能会根据您以前的访问控制经验或编程背景来做出决定。现在不幸的是,对于本文,我已经为您做出了决定:“本文中的所有代码都将使用ATL方式”。但是不用担心!该演示项目包括所有四种方法的等效程序。我将讨论该问题的所有解决方案,每种方法一个(这只是将在ATL中提供的代码)。

    10. Fun with SIDs SID的乐趣

    Q. Retrieve the SID for the LocalSystem account. Print the SID in textual form, and dump it into a TRUSTEE structure.问:检索LocalSystem帐户的SID。以文本形式打印SID,并将其转储到TRUSTEE结构中。

    The LocalSystem account is a special NT user that represents the username for the kernel and system services. In English Windows, it has the name "NT AUTHORITY\SYSTEM" (English Windows only), and generally has unrestricted access to your local workstation.

    1. If you were doing this the low level way, you would need to perform some hacks. You'll note that NT names the LocalSystem account "NT AUTHORITY\SYSTEM". By passing this name to LookupAccountName(), you can retrieve the SID for the LocalSystem account. You can then make use of this function to print the SID. A TRUSTEE only works with APIs not available in NT3.x, and since the only reason you'd want to choose this method is to support NT3.x a TRUSTEE is rather useless to you.
    2. In Windows 2000, you can cheat a little by utilizing SDDL. The SDDL form of LocalSystem is "SY". Passing this string to ConvertStringSidToSid() gives you the required SID. Then you just have to use BuildTrusteeWithSid() to make the TRUSTEE.
    3. You can retrieve the SID of the system from the SID's namespace. Now, that you have the SID, you'll probably want to wrap it in ATL's CSid class. Printing out the SID is really easy with ATL, just print the output of the CSid::Sid() method, and that's it. The last thing to do, is fill out a TRUSTEE, that can be accomplished with BuildTrusteeWithSid().
    4. 该LocalSystem帐户是一个特殊的NT用户,代表内核和系统服务的用户名。在英文Windows中,它的名称为“ NT AUTHORITY\SYSTEM”(仅英文Windows),并且通常可以不受限制地访问您的本地工作站。

      1. 如果您以低级方式进行此操作,则需要执行一些技巧。您会注意到,NT将LocalSystem帐户命名为“ NT AUTHORITY \ SYSTEM”。通过将此名称传递给LookupAccountName(),您可以检索该LocalSystem帐户的SID 。然后,您可以使用此功能[ ^ ]打印SID。ATRUSTEE仅适用于NT3.x中不可用的API,并且由于您要选择此方法的唯一原因是对NT3.xa的支持,因此TRUSTEE对您来说毫无用处。
      2. 在Windows 2000中,您可以利用SDDL进行一些欺骗。SDDL的格式LocalSystem为“ SY”。将此字符串传递ConvertStringSidToSid()给您将提供所需的SID。然后,您只需使用BuildTrusteeWithSid()即可TRUSTEE。
      3. 您可以从SID的命名空间中检索系统的SID。现在,有了SID,您可能需要将其包装在ATL的CSid类中。使用ATL确实可以很容易地打印出SID,仅打印CSid::Sid()方法的输出即可。最后要做的是填写TRUSTEE,可以用完成BuildTrusteeWithSid()。
    int WellKnownSid2Trustee(void)
    {
      /* Wrap up the object in a CSid */
      ATL::CSid SidUser(ATL::Sids::System());
    
      std::wcout << SidUser.Sid();
    
      TRUSTEE TrusteeSid = {0};
      ::BuildTrusteeWithSid(&TrusteeSid, 
           const_cast(SidUser.GetPSID()));
    
      return 0;
    }

    Figure 9: Converting a well known SID into a TRUSTEE

    Q. You have obtained your username from your thread token. Unfortunately, it's in SID form. It's needed in a user friendly form. Convert the SID to a user name.问:您已经从线程令牌中获取了用户名。不幸的是,它是SID形式。以用户友好的形式需要它。将SID转换为用户名。

    1. If you had no trouble with fig. 8, this exercise should be of little trouble. It's basically the reverse of the above exercise. You are supplied a SID, so all you need to do is call LookupAccountSid(). The returned user name can be formatted in SAM form, alias form, or domain form (dependent on the value of SidType).
    2. To show there is more than one way to skin a cat, WMI will be used to obtain the user. After you have connected to the "root\cimv2" namespace, you would want to execute the following query: SELECT * FROM Win32_UserAccount WHERE Sid = "<SidUser>" (replace <SidUser> with the supplied SID). This query should return one result, which you can open to get the Win32_UserAccount associated with this user. The user name is located in the Name property, so retrieve it and finally convert the BSTR into a normal string. Phew! You don't have to do all that. If you don't want to, you can simply duplicate method 1. (I included WMI as a solution to get you considering WMI as an alternative API for programming Windows security).
    3. It's highly recommended you wrap the SID in a CSid class. That way you can simply use the methods of the CSid class to obtain your username (in this case CSid::AccountName()).
    4. 如果您对图8无忧。这个练习应该没什么大麻烦。基本上与上述练习相反。系统会为您提供一个SID,因此您所需要做的就是call LookupAccountSid()。可以使用SAM形式,别名形式或域形式(取决于的值SidType)来格式化返回的用户名。
    5. 为了说明有多种方法可以进行,将使用WMI来吸引用户。连接到“ root \ cimv2”命名空间后,您将要执行以下查询:(用提供的SIDSELECT * FROM Win32_UserAccount WHERE Sid = "<SidUser>"代替<SidUser>)。此查询应返回一个结果,您可以打开该结果以获取Win32_UserAccount与此用户相关联。用户名位于Name属性中,因此,请对其进行检索,最后将转换BSTR为普通字符串。!您不必做所有的事情。如果您不想这样做,可以简单地复制方法1。(我将WMI作为解决方案,让您考虑将WMI作为编程Windows安全性的替代API)。
    6. 强烈建议您将SID包装在一个CSid类中。这样,您可以简单地使用CSid类的方法来获取用户名(在这种情况下CSid::AccountName())。
    void Sid2UserName(const SID *UserSid)
    {
      ATL::CSid UserCSid(UserSid /*, Domain */);
      /** This line would be unnecessary if we passed in a
      * CSid rather than an unwrapped SID
      **/
      std::wcout << UserCSid.AccountName();
    }

    Figure 10: Getting the Username from a SID.

    友情链接
    版权所有 Copyright(c)2004-2015 锐英源软件

    公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768

    地址:郑州市文化路47号院1号楼4层(47-1楼位于文化路和红专路十字路口东北角,郑州大学工学院招待所南边,工学院科技报告厅西边。)