0

我在使用 C++ 时遇到了一些问题,不要经常使用这种语言!

我正在尝试处理 NTFS 目录中的 ACL,以便输出目录中存在的所有允许和拒绝权限的完整列表。

我已经从目录中获得了 ACL,并且对于大多数记录,我已经获得了 Domain\Account 名称。然而,在某些情况下,输出这个只会给我????????\??????????。

我已经确定了两个原因。

1) 用户帐户已从机器中删除,因此 SID 是孤立的。我可以使用 GetLastError() = 1332 来确定这一点。

2) 它是一个“众所周知的 SID”,即某种内置 SID,因此没有要映射到的用户名 - LookupAccountSid 此时不报告错误。如果不将所有众所周知的 SID 映射到文件中并进行交叉引用(慢),我无法(据我所知)识别这些案例。我想要做的只是输出 SID 而不是 ????????。LPTSTR myTrusteeName 是从 LookupAccountSid() 返回的字符串,呈现为 ????????。我不知道它的实际值是多少,如果我知道我可以轻松地执行一个 IF 语句来打印 SID。

        //this is part of a loop.
        if (IsValidSid(mySid)){
            //cout << "SID supplied is valid\n";
            //cout << GetLengthSid(mySid) << "\n";

            LPWSTR mySidName = NULL;
            ConvertSidToStringSid((PSID)mySid, &mySidName);




            //Make an initial lookup to find out how big the names are
            LookupAccountSid(
                NULL
                , (PSID) mySid
                , myTrusteeName
                , (LPDWORD)&myDwordNameLength
                , myDomainName
                , (LPDWORD)&myDwordDomLength
                , &myNameUse
                ); //at this point error 122 is thrown as the length of myTrusteeName is too short.

            //alter the size of these variables rather than just getting the 1st letter and some gibberish
            myTrusteeName = (LPTSTR)GlobalAlloc(GMEM_FIXED, myDwordNameLength);
            myDomainName = (LPTSTR)GlobalAlloc(GMEM_FIXED, myDwordDomLength);

            //do the lookup again this time with genuine sizes
            LookupAccountSid(
                NULL
                , (PSID)mySid
                , myTrusteeName
                , (LPDWORD)&myDwordNameLength
                , myDomainName
                , (LPDWORD)&myDwordDomLength
                , &myNameUse
                );

            wcout << GetLastError() << "\n"; //this will output "122" even when successful because of the first attempt.

            _tprintf(TEXT("%s\n"), myTrusteeName); //when there is no name this outputs ????????

            wcout << myTrusteeName << "\n"; //when there is no name this completely screws myTrusteeName so that it fails to print for the rest of the loop


            //if we only have ???? then it's wrong
            if (myTrusteeName == NULL){ /// WHAT IN HELL DO I PUT IN THIS COMPARISON TO IDENTIFY myTrusteeName VALUES THAT PRINT ????????
                wcout << "we are changing trustee because it's blank\n";
                myTrusteeName = _T("");//maybe change this to the value of mySidName
                wcout << "length of trustee is now " << _tcslen(myTrusteeName) << "\n";
            }
            wcout << "\n";



        }

现在......在写这篇文章时,我意识到有一个名为IsWellKnownSid() facepalm的函数

这会从WELL_KNOWN_SID_TYPE枚举中输出一个项目

我应该可以使用它......我不确定如何获得众所周知的 sid 类型(即“用户”)的字符串表示,就像你在 ACL 编辑器中看到的那样......如果任何人对此有任何建议,我将不胜感激。

我还没有完成这个小项目,所以我想无论如何我都会发布这个,以防它在未来对其他人有用!

我仍然很好奇——如果没有 IsWellKnownSid() 函数,我将如何在尝试打印之前检测拒绝打印的字符串值?

非常感谢您的阅读和最好的问候本

4

1 回答 1

0

您应该检查ConvertSidToStringSidLookupAccountSid返回 TRUE。如果他们这样做了,那么 LookupAccountSid 将向myTrusteeName. 如果 LookupAccountSid 返回 FALSE,则 LookupAccountSid 不会更改 的内容myTrusteeName,因此它会像GlobalAlloc返回的一样未初始化。

于 2015-01-30T13:11:01.380 回答