您的位置:首页 > 其它

NT下判断用户是否有管理员权限

2012-12-20 11:42 399 查看


NT下判断用户是否有管理员权限

OK, Thanks to Loaden found out that my original code to determine whether an user is in Administrators group is totally bullshit.

And after googling for a while, I found something and test it, simply works. I will just paste the code here. Thanks to the author and google
and God.

http://www.mihai-nita.net/article.php?artID=20070413a

// IsAdminAPI.cpp : Tests if user is Administrator using plain Win32 API

// Copyright (c) April 2007, Mihai Nita

//

#include <wtypes.h>

#include <Lm.h>

// for ASSERT

#include <crtdbg.h>

#include "IsAdminAPI.h"

bool IsAdminAPI( WCHAR const *szUserName )

{

_ASSERT(szUserName);

bool bAdmin = FALSE;

LOCALGROUP_USERS_INFO_0* localGroups;

DWORD entriesread, totalentries;

NET_API_STATUS nts = NetUserGetLocalGroups( NULL, szUserName, 0, 0, (unsigned char**)&localGroups, MAX_PREFERRED_LENGTH, &entriesread, &totalentries);

if( nts != NERR_Success ) {

NetApiBufferFree(localGroups);

return FALSE;

}

// Retrieve the Administrators group well-known SID

// For some reason CreateWellKnownSid generates error C3861 on Developer Studio .NET:

// error C3861: 'CreateWellKnownSid': identifier not found, even with argument-dependent lookup

BYTE SidAuth[] = SECURITY_NT_AUTHORITY;

PSID pAdminSid;

AllocateAndInitializeSid( (PSID_IDENTIFIER_AUTHORITY)SidAuth,

2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,

NULL, NULL, NULL, NULL, NULL, NULL, &pAdminSid );

// Will use this to retrieve the SID of the group

BYTE buffSid[SECURITY_MAX_SID_SIZE];

wchar_t buffDomain[DNLEN+1];

DWORD dwSidSize;

DWORD dwDomainSize;

SID_NAME_USE m_sidnameuse;

for( DWORD i = 0; i < entriesread; ++i ) {

dwSidSize = sizeof(buffSid);

dwDomainSize = DNLEN;

// Although in general is a bad idea to call directly the W or A versions of API

// we do it here to avoid converting the localGroups[i].lgrui0_name back to ANSI

// This kind of security API is only present on NT/2000/XP family only, so

// the W version is present and safe to use

if( LookupAccountNameW( NULL, localGroups[i].lgrui0_name, buffSid, &dwSidSize, (LPWSTR)buffDomain, &dwDomainSize, &m_sidnameuse) ) // no sid for the actual group

if( EqualSid( buffSid, pAdminSid ) ) {

bAdmin = TRUE;

break;

}

}

FreeSid( pAdminSid );

NetApiBufferFree(localGroups);

return bAdmin;

}

注意有时我们只需要判断当前process是否以管理员权限运行。貌似可以通过调用GetTokenInformation 和AllocateAndInitializeSid 来判断,

google "Searching for a SID in an Access Token in C++" site:msdn.microsoft.com可找到一段代码, 请自行研究自行测试。

#define MAX_NAME 256

BOOL SearchTokenGroupsForSID (VOID)

{

DWORD i, dwSize = 0, dwResult = 0;

HANDLE hToken;

PTOKEN_GROUPS pGroupInfo;

SID_NAME_USE SidType;

char lpName[MAX_NAME];

char lpDomain[MAX_NAME];

BYTE sidBuffer[100];

PSID pSID = (PSID)&sidBuffer;

SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;

// Open a handle to the access token for the calling process.

if (!OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken )) {

printf( "OpenProcessToken Error %u\n", GetLastError() );

return FALSE;

}

// Call GetTokenInformation to get the buffer size.

if(!GetTokenInformation(hToken, TokenGroups, NULL, dwSize, &dwSize)) {

dwResult = GetLastError();

if( dwResult != ERROR_INSUFFICIENT_BUFFER ) {

printf( "GetTokenInformation Error %u\n", dwResult );

return FALSE;

}

}

// Allocate the buffer.

pGroupInfo = (PTOKEN_GROUPS) GlobalAlloc( GPTR, dwSize );

// Call GetTokenInformation again to get the group information.

if(! GetTokenInformation(hToken, TokenGroups, pGroupInfo,

dwSize, &dwSize ) ) {

printf( "GetTokenInformation Error %u\n", GetLastError() );

return FALSE;

}

// Create a SID for the BUILTIN\Administrators group.

if(! AllocateAndInitializeSid( &SIDAuth, 2,

SECURITY_BUILTIN_DOMAIN_RID,

DOMAIN_ALIAS_RID_ADMINS,

0, 0, 0, 0, 0, 0,

&pSID) ) {

printf( "AllocateAndInitializeSid Error %u\n", GetLastError() );

return FALSE;

}

// Loop through the group SIDs looking for the administrator SID.

for(i=0; i<pGroupInfo->GroupCount; i++) {

if ( EqualSid(pSID, pGroupInfo->Groups[i].Sid) ) {

// Lookup the account name and print it.

dwSize = MAX_NAME;

if( !LookupAccountSid( NULL, pGroupInfo->Groups[i].Sid,

lpName, &dwSize, lpDomain,

&dwSize, &SidType ) ) {

dwResult = GetLastError();

if( dwResult == ERROR_NONE_MAPPED )

strcpy_s (lpName, dwSize, "NONE_MAPPED" );

else {

printf("LookupAccountSid Error %u\n", GetLastError());

return FALSE;

}

}

printf( "Current user is a member of the %s\\%s group\n",

lpDomain, lpName );

// Find out whether the SID is enabled in the token.

if (pGroupInfo->Groups[i].Attributes & SE_GROUP_ENABLED)

printf("The group SID is enabled.\n");

else if (pGroupInfo->Groups[i].Attributes &

SE_GROUP_USE_FOR_DENY_ONLY)

printf("The group SID is a deny-only SID.\n");

else

printf("The group SID is not enabled.\n");

}

}

if (pSID)

FreeSid(pSID);

if ( pGroupInfo )

GlobalFree( pGroupInfo );

return TRUE;

}

向曾被我误导的同志表示真挚的道歉和沉痛的悼念。

NSIS下判断当前用户是否管理员:

http://nsis.sourceforge.net/Check_if_the_current_user_is_an_Administrator

!macro IsUserAdmin RESULT

!define Index "Line${__LINE__}"

StrCpy ${RESULT} 0

System::Call '*(&i1 0,&i4 0,&i1 5)i.r0'

System::Call 'advapi32::AllocateAndInitializeSid(i r0,i 2,i 32,i 544,i 0,i 0,i 0,i 0,i 0, \

i 0,*i .R0)i.r5'

System::Free $0

System::Call 'advapi32::CheckTokenMembership(i n,i R0,*i .R1)i.r5'

StrCmp $5 0 ${Index}_Error

StrCpy ${RESULT} $R1

Goto ${Index}_End

${Index}_Error:

StrCpy ${RESULT} -1

${Index}_End:

System::Call 'advapi32::FreeSid(i R0)i.r5'

!undef Index

!macroend
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: