Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SetSecurityInfo返回拒绝访问_C_Windows_Security_Winapi_Ipc - Fatal编程技术网

SetSecurityInfo返回拒绝访问

SetSecurityInfo返回拒绝访问,c,windows,security,winapi,ipc,C,Windows,Security,Winapi,Ipc,使用C,我试图在进程与其子进程之间建立管道连接,而子进程的强制(完整性)级别较低(较低,而父进程较高) 我编写了以下程序(如果是简化版的话),但失败了:ERROR\u ACCESS\u DENIED(0x5) 我跟着他说 要设置对象的SACL,调用者必须启用SE_SECURITY_NAME权限。: BOOL SetSeSecurityNamePrivilege() { HANDLE hToken; TOKEN_PRIVILEGES tp; LUID luid;

使用C,我试图在进程与其子进程之间建立管道连接,而子进程的强制(完整性)级别较低(较低,而父进程较高)

我编写了以下程序(如果是简化版的话),但失败了:
ERROR\u ACCESS\u DENIED(0x5)

我跟着他说
要设置对象的SACL,调用者必须启用SE_SECURITY_NAME权限。

BOOL SetSeSecurityNamePrivilege()
{
    HANDLE hToken;
    TOKEN_PRIVILEGES tp;
    LUID luid;

    if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY | TOKEN_IMPERSONATE, &hToken)
        return FALSE

    if (!LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &luid))
        return FALSE;

    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    if (bEnablePrivilege)
        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    else
        tp.Privileges[0].Attributes = 0;

    if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))
        return FALSE;

    if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
        return FALSE;

    return TRUE;
}
注意:当我尝试使用文件执行它时,我会得到相同的结果,使用
CreateFile
而不是
CreatePipe
。 此外,如果我尝试使用文件来实现这一点,并将
SetSecurityInfo
替换为
setnamedsecurityinfo
,并为其提供文件的完整路径,则效果非常好


有人知道如何让它工作吗?谢谢

在解决眼前问题的原因之前,请注意几点

首先,您根本不需要更改安全描述符,这样做不太可能帮助您实现最终目标。仅当您尝试打开对象的句柄时,才会检查安全描述符;如果已经有句柄,则安全描述符无效。由于要创建未命名的管道,因此必须将句柄而不是管道名称传递给子级,因此根本不需要ChangeMandatoryLabelHandle函数

其次,在设置
标签安全信息时,不需要
SE\u SECURITY\u NAME
权限。强制标签在逻辑上不同于SACL的其余部分,并被视为特例

第三,您的
“S:(ML;;LW;;;NW)
无效

我试图在ConvertStringSecurityDescriptorSecurityDescriptorW中使用它,但出现错误1336,访问控制列表(ACL)结构无效。相反,使用
“D:NO_ACCESS_CONTROLS:(ML;;;LW)”
或更好地使用以下代码创建具有低标签且无DACL的安全描述符:

ULONG cb = MAX_SID_SIZE;
PSID LowLabelSid = (PSID)alloca(MAX_SID_SIZE);

ULONG dwError = NOERROR;

if (CreateWellKnownSid(WinLowLabelSid, 0, LowLabelSid, &cb))
{
    PACL Sacl = (PACL)alloca(cb += sizeof(ACL) + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK));

    if (InitializeAcl(Sacl, cb, ACL_REVISION) && 
        AddMandatoryAce(Sacl, ACL_REVISION, 0, 0, LowLabelSid))
    {
        SECURITY_DESCRIPTOR sd;
        InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
        SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
        SetSecurityDescriptorSacl(&sd, TRUE, Sacl, FALSE);

        SECURITY_ATTRIBUTES sa = { sizeof(sa), &sd, TRUE };

        // todo something here
    }
    else
    {
        dwError = GetLastError();
    }
}
else
{
    dwError = GetLastError();
}
但是,您需要再次了解,为未命名对象创建安全描述符(几乎)没有任何意义。只有在打开对象时才会检查安全描述符,并且(在用户模式下)无法打开没有名称的对象

(从内核模式,我们可以使用指针打开对象。)

(在旧版本的Windows中,CreatePipe实际上创建了一个具有随机名称的管道,但从Windows 7开始,该管道实际上未命名,因此无法使用CreateFile或任何类似方法打开。)

无论如何,我认为在这种情况下使用CreatePipe是一个错误的选择。此功能设计不完善,参数太少。没有创建双向管道或以异步模式打开管道的选项。我认为最好使用CreateNamedPipeW和CreateFileW

(或者,从Windows 7开始,可以使用ZwCreateNamedPipeFile和ZwOpenFile创建和打开未命名管道。)


发布的代码最接近的问题是,当使用返回的句柄调用时,返回错误\u ACCESS\u DENIED。这是因为,如文档中所述:

需要设置的权限:写入所有者

由于没有为您提供选择打开句柄时使用的访问权限的选项,因此您无法执行此操作。如果改为使用,则可以在dwOpenMode中设置WRITE_所有者


但是,您应该注意,如果希望创建具有特殊安全描述符的对象,最好在创建对象时提供该安全描述符。使用默认安全描述符创建对象,然后更改它是没有意义的;为什么在两次手术中你能做一次?在这种情况下,可以使用传递给CreatePipe或CreateNamedPipe的
SECURITY\u属性
结构来指定安全描述符,从而提供解决当前问题的另一种方法,尽管如前所述,这实际上是没有用的。

在解决眼前问题的原因之前,请注意几点

首先,您根本不需要更改安全描述符,这样做不太可能帮助您实现最终目标。仅当您尝试打开对象的句柄时,才会检查安全描述符;如果已经有句柄,则安全描述符无效。由于要创建未命名的管道,因此必须将句柄而不是管道名称传递给子级,因此根本不需要ChangeMandatoryLabelHandle函数

其次,在设置
标签安全信息时,不需要
SE\u SECURITY\u NAME
权限。强制标签在逻辑上不同于SACL的其余部分,并被视为特例

第三,您的
“S:(ML;;LW;;;NW)
无效

我试图在ConvertStringSecurityDescriptorSecurityDescriptorW中使用它,但出现错误1336,访问控制列表(ACL)结构无效。相反,使用
“D:NO_ACCESS_CONTROLS:(ML;;;LW)”
或更好地使用以下代码创建具有低标签且无DACL的安全描述符:

ULONG cb = MAX_SID_SIZE;
PSID LowLabelSid = (PSID)alloca(MAX_SID_SIZE);

ULONG dwError = NOERROR;

if (CreateWellKnownSid(WinLowLabelSid, 0, LowLabelSid, &cb))
{
    PACL Sacl = (PACL)alloca(cb += sizeof(ACL) + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK));

    if (InitializeAcl(Sacl, cb, ACL_REVISION) && 
        AddMandatoryAce(Sacl, ACL_REVISION, 0, 0, LowLabelSid))
    {
        SECURITY_DESCRIPTOR sd;
        InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
        SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
        SetSecurityDescriptorSacl(&sd, TRUE, Sacl, FALSE);

        SECURITY_ATTRIBUTES sa = { sizeof(sa), &sd, TRUE };

        // todo something here
    }
    else
    {
        dwError = GetLastError();
    }
}
else
{
    dwError = GetLastError();
}
但是,您需要再次了解,为未命名对象创建安全描述符(几乎)没有任何意义。只有在打开对象时才会检查安全描述符,并且(在用户模式下)无法打开没有名称的对象

(从内核模式,我们可以使用指针打开对象。)

(在旧版本的Windows中,CreatePipe实际上创建了一个具有随机名称的管道,但从Windows 7开始,该管道实际上未命名,因此无法使用CreateFile或任何类似方法打开。)

无论如何,我认为在这种情况下使用CreatePipe是一个错误的选择。此功能设计不完善,p太少