GetNamedSecurityInfo返回ERROR_ACCESS_DENIED(5)书面方式远程Windows共享文件夹的所有者时, [英] GetNamedSecurityInfo returns ERROR_ACCESS_DENIED(5) when writting owner of a remote Windows shared folder

查看:722
本文介绍了GetNamedSecurityInfo返回ERROR_ACCESS_DENIED(5)书面方式远程Windows共享文件夹的所有者时,的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一个域管理员,我想采取一些共享文件夹的所有权,我的域名的某些服务器上编程的API(例如C ++)。我做了一些阅读的工作,发现一个域管理员的成员计算机的本地管理员组在默认情况下,和本地管理员的用户可以取得所有权反正。我只是wrtie一些code以这种方式,但得到使用GetNamedSecurityInfo所有者SID时还会遇到ERROR_ACCESS_DENIED?哪里的问题?

I'm a Domain Admin and I want to take ownership of some shared folders on some server of my domain programmatically in API(for example C++). I did some reading work and found that a Domain Admin is in the member machine's Local Admins group by default, and the Local Admins users can take ownership anyway. I just wrtie some code in this way but still encountered ERROR_ACCESS_DENIED when getting the owner sid using GetNamedSecurityInfo? Where's the problem?

有趣的事情:当我改变了GetNamedSecurityInfo的谢胜利说法从SE_FILE_OBJECT到SE_LMSHARE,它会成功(同时设置一个)。但我并没有看到文件夹的属性中的安全选项卡改变了主人。我知道一个共享权限是安全的不同。一个共享权限甚至没有一个老板。所以我才得到了什么主人的SE_LMSHARE参数调用GetNamedSecurityInfo时候?

Something interesting is: When I changed the GetNamedSecurityInfo's secound argument from SE_FILE_OBJECT to SE_LMSHARE, it would succeed(also set one). But I didn't see the owner changed in the "Security" tab of folder's properties. I know a "share" permission is different with "security" one. a "share" permission even don't have a owner. So what owner did I get when calling GetNamedSecurityInfo by the SE_LMSHARE argument?

下面是我用取得所有权文件夹strFileName,在服务器上strServerName功能,车主改为只是域管理员帐户被称为strDomainNamestrUserName中strPassword,原单所有者保留在pOriginSID。 我在GetNamedSecurityInfo通话(还设置一个)遇到错误code 5。我也写一个模拟方法logOnByUserPassword,这似乎不工作,我贴在下面。

Here's the function i use for Taking ownership for the folder "strFileName", on server "strServerName", the owner changed to is just the Domain Admin account known as "strDomainName" "strUserName" "strPassword", orginal owner is reserved in "pOriginSID". I got error code 5 in the GetNamedSecurityInfo call (also the Set one). I also write a impersonation method "logOnByUserPassword" which seems not to work, i paste it below.

HANDLE ADPermissionSearch :: getAccessTokenByCredential(CString的strDomainName,CString的strUserName中,CString的strPassword) {

HANDLE ADPermissionSearch::getAccessTokenByCredential(CString strDomainName, CString strUserName, CString strPassword) {

CString strUPNUserName = strUserName + _T("@") + strDomainName;

HANDLE hToken;
BOOL bResult;
//bResult = LogonUser(strUserName, strDomainName, strPassword, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT,
//  &hToken);
if (strDomainName != _T(""))
{
    bResult = LogonUser(strUPNUserName, _T(""), strPassword, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, 
        &hToken);
}
else
{
    bResult = LogonUser(strUserName, _T("."), strPassword, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, 
        &hToken);
}
if (bResult == FALSE)
{
    MyMessageBox_Error(_T("getAccessTokenByCredential Error."), _T("Error"));
    return FALSE;
}
else
{
    return hToken;
}

}

INT ADPermissionSearch :: takeOwnership(CString的strServerName,CString的strFileName,CString的strDomainName,CString的strUserName中,CString的strPassword,__out PSID和放大器; pOriginSID) {

int ADPermissionSearch::takeOwnership(CString strServerName, CString strFileName, CString strDomainName, CString strUserName, CString strPassword, __out PSID &pOriginSID) {

CString strUNCFileName = _T("\\\\") + strServerName + _T("\\") + strFileName;
_bstr_t bstrUNCFileName = _bstr_t(strUNCFileName);
PSID pSIDAdmin = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
HANDLE hToken = NULL;
DWORD dwRes;

// Create a SID for the BUILTIN\Administrators group.
if (!AllocateAndInitializeSid(&SIDAuthNT, 2,
    SECURITY_BUILTIN_DOMAIN_RID,
    DOMAIN_ALIAS_RID_ADMINS,
    0, 0, 0, 0, 0, 0,
    &pSIDAdmin))
{
    if (pSIDAdmin)
        FreeSid(pSIDAdmin);
    if (hToken)
        CloseHandle(hToken);
    MyMessageBox_Error(_T("takeOwnership"));
    return 0;
}

// If the preceding call failed because access was denied,
// enable the SE_TAKE_OWNERSHIP_NAME privilege, create a SID for
// the Administrators group, take ownership of the object, and
// disable the privilege. Then try again to set the object's DACL.

// Open a handle to the access token for the calling process.
/*
if (!OpenProcessToken(GetCurrentProcess(),
                      TOKEN_ADJUST_PRIVILEGES,
                      &hToken))
{
    if (pSIDAdmin)
        FreeSid(pSIDAdmin);
    if (hToken)
        CloseHandle(hToken);
    MyMessageBox_Error(_T("takeOwnership"));
    return 0;
}
*/
if ((hToken = getAccessTokenByCredential(strDomainName, strUserName, strPassword)) == NULL)
{
    if (pSIDAdmin)
        FreeSid(pSIDAdmin);
    if (hToken)
        CloseHandle(hToken);
    MyMessageBox_Error(_T("takeOwnership"));
    return 0;
}

// Enable the SE_TAKE_OWNERSHIP_NAME privilege.
if (!setPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE))
{
    if (pSIDAdmin)
        FreeSid(pSIDAdmin);
    if (hToken)
        CloseHandle(hToken);
    MyMessageBox_Error(_T("takeOwnership"));
    return 0;
}

// Get the original owner in the object's security descriptor.
dwRes = GetNamedSecurityInfo(
    bstrUNCFileName,             // name of the object
    SE_FILE_OBJECT,                  // type of object
    OWNER_SECURITY_INFORMATION,  // change only the object's owner
    &pOriginSID,                 // SID of Administrator group
    NULL,
    NULL,
    NULL,
    NULL);
if (dwRes != ERROR_SUCCESS)
{
    if (pSIDAdmin)
        FreeSid(pSIDAdmin);
    if (hToken)
        CloseHandle(hToken);
    MyMessageBox_Error(_T("takeOwnership"));
    return 0;
}

// Set the owner in the object's security descriptor.
dwRes = SetNamedSecurityInfo(
            bstrUNCFileName,             // name of the object
            SE_FILE_OBJECT,                  // type of object
            OWNER_SECURITY_INFORMATION,  // change only the object's owner
            pSIDAdmin,                   // SID of Administrator group
            NULL,
            NULL,
            NULL);
if (dwRes != ERROR_SUCCESS)
{
    if (pSIDAdmin)
        FreeSid(pSIDAdmin);
    if (hToken)
        CloseHandle(hToken);
    MyMessageBox_Error(_T("takeOwnership"));
    return 0;
}

// Disable the SE_TAKE_OWNERSHIP_NAME privilege.
if (!setPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, FALSE))
{
    if (pSIDAdmin)
        FreeSid(pSIDAdmin);
    if (hToken)
        CloseHandle(hToken);
    MyMessageBox_Error(_T("takeOwnership"));
    return 0;
}

return 1;

}

BOOL ADDirectorySearch :: logOnByUserPassword(CString的strDomainName,CString的strUserName中,CString的strPassword) {

BOOL ADDirectorySearch::logOnByUserPassword(CString strDomainName, CString strUserName, CString strPassword) {

CString strUPNUserName = strUserName + _T("@") + strDomainName;

HANDLE hToken;
BOOL bResult;
//bResult = LogonUser(strUserName, strDomainName, strPassword, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT,
//  &hToken);
if (strDomainName != _T(""))
{
    bResult = LogonUser(strUPNUserName, _T(""), strPassword, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, 
        &hToken);
}
else
{
    bResult = LogonUser(strUserName, _T("."), strPassword, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, 
        &hToken);
}
if (bResult == FALSE)
{
    MyMessageBox_Error(_T("logOnByUserPassword Error."), _T("Error"));
    return FALSE;
}
else
{
    bResult = ImpersonateLoggedOnUser(hToken);
    if (bResult == FALSE)
    {
        MyMessageBox_Error(_T("logOnByUserPassword Error."), _T("Error"));
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}

}

推荐答案

本地管理员都受到了常用的Windows安全检查,但有一个例外:他们总是可以在固定物体的所有权不分的权限。这保证了管理员总是能够重新获得控制权。

Local admins are subject to the usual Windows security checks with one exception: they can always take ownership of a secured object regardless of the permissions. This ensures that admins are always able to regain control.

不过,您是不是要取得所有权,您要读取当前的所有者,你不一定有权限做到这一点。

However, you are not trying to take ownership, you are trying to read the current owner and you don't necessarily have permission to do that.

这不是从你的code为什么你想读的主人清楚。你似乎并不做任何事情。也许删除调用GetNamedSecurityInfo干脆。

It's not clear from your code why you are trying to read the owner. You don't seem to do anything with it. Maybe remove the call to GetNamedSecurityInfo altogether.

更新

我们的目的是编写一个程序,检查的DACL每个份额。因此,它需要保存当前的所有者,取得所有权,阅读DACL和恢复的所有者。但目前的所有者不能被读取,直到所有权已经采取了。

The intention is to write a program that checks the DACLs on every share. So it needs to save the current owner, take ownership, read the DACLs and restore the owner. But the current owner cannot be read until ownership has been taken.

我觉得这种行为是设计使然。初衷是,管理员能够采取所有权,但不能掩盖的事实是,他们从一个对象的所有者拥有,但也有办法解决这个。例如,对于文件,您可以通过启用备份特权,要求Backu $ P $垫和解析输出(WIN32_STREAM_ID结构的序列中的每个随后数据)读取完整的安全描述符(包括老板)。我不知道是否有一个更简单的方法。

I think this behaviour is by design. The original intention was that admins were able to take ownership, but not hide the fact that they had from the owner of an object, though there are ways around this. For example, for files you can read the complete security descriptor (including the owner) by enabling the backup privilege, calling BackupRead and parsing the output (a sequence of WIN32_STREAM_ID structures each followed by data). I don't know if there's a simpler way.

有关股票的信息存储在注册表中的:

Information about shares is stored in the registry under:

系统\ CurrentControlSet \服务\ LanmanServer \股份

安全信息似乎是存储在安全子项,在一个共享的名字命名的值。这个二进制值似乎是一个安全描述符,所以你可以阅读的 GetSecurityDescriptorOwner 。您还可以阅读所有从这个安全描述符中的其他安全信息,所以你不应该需要更改主。

The security info seems to be stored in the Security subkey, in a value named after the share. This binary value seems to be a security descriptor so you can read the owner with GetSecurityDescriptorOwner. You can also read all the other security info from this security descriptor, so you shouldn't need to change the owner at all.

这篇关于GetNamedSecurityInfo返回ERROR_ACCESS_DENIED(5)书面方式远程Windows共享文件夹的所有者时,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆