在 C# 中使用 SetEntriesInAcl:错误 1332

发布于 2024-12-20 22:05:17 字数 2206 浏览 0 评论 0原文

我需要创建共享文件夹,为此显然我必须使用 pinvoke NetShare* 方法。 这部分很好,但我想向共享文件夹添加一些共享权限。 我使用 SetEntriesInAcl 但不断收到错误 1332:未完成帐户名称和安全 ID 之间的映射。

定义:

internal enum MULTIPLE_TRUSTEE_OPERATION : uint
{
    NO_MULTIPLE_TRUSTEE = 0,
    TRUSTEE_IS_IMPERSONATE = 1
}

internal enum TRUSTEE_FORM : uint
{
    TRUSTEE_IS_SID = 0,
    TRUSTEE_IS_NAME = 1,
    ...
}

internal enum TRUSTEE_TYPE : uint
{
    TRUSTEE_IS_UNKNOWN = 0,
    TRUSTEE_IS_USER = 1,
    TRUSTEE_IS_GROUP = 2,
    ...
}

internal enum ACCESS_MODE : uint
{
    NOT_USED_ACCESS = 0,
    GRANT_ACCESS = 1,
    ...
}

internal enum ACCESS_MASK : uint
{
    GENERIC_ALL = 0x10000000, //268435456,
    GENERIC_READ = 0x80000000, //2147483648L,
    GENERIC_WRITE = 0x40000000, //1073741824,
    GENERIC_EXECUTE = 0x20000000, //536870912,
    STANDARD_RIGHTS_READ = 0x00020000, //131072
    STANDARD_RIGHTS_WRITE = 0x00020000,
}

[DllImport("advapi32.dll", SetLastError = true)]
private static extern uint SetEntriesInAcl(
    int cCountOfExplicitEntries, 
    ref EXPLICIT_ACCESS pListOfExplicitEntries, 
    IntPtr OldAcl, 
    out IntPtr NewAcl
    );

这是我调用它的方式:

//This pointer will hold the full ACL (access control list) once the loop below has completed
IntPtr aclPtr = default(IntPtr);

EXPLICIT_ACCESS explicitAccessRule = new EXPLICIT_ACCESS();
TRUSTEE account = new TRUSTEE();
{
    account.MultipleTrusteeOperation = MULTIPLE_TRUSTEE_OPERATION.NO_MULTIPLE_TRUSTEE;
    account.pMultipleTrustee = 0;
    account.TrusteeForm = TRUSTEE_FORM.TRUSTEE_IS_NAME;
    account.ptstrName = "Everyone";
    account.TrusteeType = TRUSTEE_TYPE.TRUSTEE_IS_USER;
}
explicitAccessRule.grfAccessMode = ACCESS_MODE.GRANT_ACCESS;
explicitAccessRule.grfAccessPermissions = ACCESS_MASK.GENERIC_READ | ACCESS_MASK.STANDARD_RIGHTS_READ | ACCESS_MASK.GENERIC_EXECUTE;
explicitAccessRule.grfInheritance = NO_INHERITANCE;
//Set the Trustee to the TRUSTEE structure we created earlier in the loop
explicitAccessRule.Trustee = account;

//Add this explicit access rule to the ACL
uint SetEntriesResult = SetEntriesInAcl(1, ref explicitAccessRule, aclPtr, out aclPtr);

有人知道我缺少什么吗? 或者还有其他方法可以做到这一点吗?

谢谢。

I need to create shared folder and for this apparently I have to use pinvoke NetShare* methods.
This part is fine but I want to add some share permissions to the shared folder.
I use SetEntriesInAcl but I keep getting error 1332 : No mapping between account names and security IDs was done.

The definitions :

internal enum MULTIPLE_TRUSTEE_OPERATION : uint
{
    NO_MULTIPLE_TRUSTEE = 0,
    TRUSTEE_IS_IMPERSONATE = 1
}

internal enum TRUSTEE_FORM : uint
{
    TRUSTEE_IS_SID = 0,
    TRUSTEE_IS_NAME = 1,
    ...
}

internal enum TRUSTEE_TYPE : uint
{
    TRUSTEE_IS_UNKNOWN = 0,
    TRUSTEE_IS_USER = 1,
    TRUSTEE_IS_GROUP = 2,
    ...
}

internal enum ACCESS_MODE : uint
{
    NOT_USED_ACCESS = 0,
    GRANT_ACCESS = 1,
    ...
}

internal enum ACCESS_MASK : uint
{
    GENERIC_ALL = 0x10000000, //268435456,
    GENERIC_READ = 0x80000000, //2147483648L,
    GENERIC_WRITE = 0x40000000, //1073741824,
    GENERIC_EXECUTE = 0x20000000, //536870912,
    STANDARD_RIGHTS_READ = 0x00020000, //131072
    STANDARD_RIGHTS_WRITE = 0x00020000,
}

[DllImport("advapi32.dll", SetLastError = true)]
private static extern uint SetEntriesInAcl(
    int cCountOfExplicitEntries, 
    ref EXPLICIT_ACCESS pListOfExplicitEntries, 
    IntPtr OldAcl, 
    out IntPtr NewAcl
    );

And here is how I invoke it:

//This pointer will hold the full ACL (access control list) once the loop below has completed
IntPtr aclPtr = default(IntPtr);

EXPLICIT_ACCESS explicitAccessRule = new EXPLICIT_ACCESS();
TRUSTEE account = new TRUSTEE();
{
    account.MultipleTrusteeOperation = MULTIPLE_TRUSTEE_OPERATION.NO_MULTIPLE_TRUSTEE;
    account.pMultipleTrustee = 0;
    account.TrusteeForm = TRUSTEE_FORM.TRUSTEE_IS_NAME;
    account.ptstrName = "Everyone";
    account.TrusteeType = TRUSTEE_TYPE.TRUSTEE_IS_USER;
}
explicitAccessRule.grfAccessMode = ACCESS_MODE.GRANT_ACCESS;
explicitAccessRule.grfAccessPermissions = ACCESS_MASK.GENERIC_READ | ACCESS_MASK.STANDARD_RIGHTS_READ | ACCESS_MASK.GENERIC_EXECUTE;
explicitAccessRule.grfInheritance = NO_INHERITANCE;
//Set the Trustee to the TRUSTEE structure we created earlier in the loop
explicitAccessRule.Trustee = account;

//Add this explicit access rule to the ACL
uint SetEntriesResult = SetEntriesInAcl(1, ref explicitAccessRule, aclPtr, out aclPtr);

Anyone knows what I am missing ?
Or is there another way to do that ?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迎风吟唱 2024-12-27 22:05:17

看来 Ansi 名称无法映射。
如果您使用 Unicode 版本 SetEntriesInAclW 或者显式设置 CharSet 属性,它会起作用。

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern uint SetEntriesInAcl(
    int cCountOfExplicitEntries,
    ref EXPLICIT_ACCESS pListOfExplicitEntries,
    IntPtr OldAcl,
    out IntPtr NewAcl);

您还可以使用 BuildExplicitAccessWithName 函数来拟合 EXPLICIT_ACCESS 结构。

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern void BuildExplicitAccessWithName(
    ref EXPLICIT_ACCESS pExplicitAccess,
    string pTrusteeName,
    uint AccessPermissions,
    uint AccessMode,
    uint Inheritance);

It seems that Ansi names cann't be mapped.
It works if you use Unicode version SetEntriesInAclW or if you explicitely set CharSet property.

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern uint SetEntriesInAcl(
    int cCountOfExplicitEntries,
    ref EXPLICIT_ACCESS pListOfExplicitEntries,
    IntPtr OldAcl,
    out IntPtr NewAcl);

You can also fit EXPLICIT_ACCESS structure with BuildExplicitAccessWithName function.

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern void BuildExplicitAccessWithName(
    ref EXPLICIT_ACCESS pExplicitAccess,
    string pTrusteeName,
    uint AccessPermissions,
    uint AccessMode,
    uint Inheritance);
墟烟 2024-12-27 22:05:17

由于缺少 CharSet、结构和方法定义之间的定义不一致以及字符串参数的编组不正确,我遇到了所有相同的问题。

我将代码示例放在不同的线程上,这样您就不必浪费几天的时间来尝试清除并不总是那么有帮助的 Win32 错误。

更新文件共享的权限:

正在运行的 . NET 示例使用 SetEntriesInAcl 互操作操作

I ran into all the same problems because of the lack of the CharSet, inconsistent definitions across my structs and method definitions and incorrect marshalling of string parameters.

I put code examples on a different thread so that you don't have to lose days of time trying to weed through the Win32 errors that are not always so helpful.

Updating permissions on a file share:

A working .NET example using SetEntriesInAcl interop in action

美煞众生 2024-12-27 22:05:17

对于初学者来说,变量 aclPtr 是一个输入变量。理想情况下,它应该从 API GetSecurityInfo 获取其值。 ( http://msdn.microsoft .com/en-us/library/windows/desktop/aa446654(v=vs.85).aspx )谢谢。

For starters the variable aclPtr is an input variable. Ideally it should have got its value from the API GetSecurityInfo. ( http://msdn.microsoft.com/en-us/library/windows/desktop/aa446654(v=vs.85).aspx ) Thanks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文