int len;
};
-#if defined(_WIN32)
-#include "win32util.h"
-static int UtilTokenHasGroup(HANDLE token, SID *group);
-#endif
#ifdef VM_X86_64
# if defined(__GNUC__) && (!defined(USING_AUTOCONF) || defined(HAVE_UNWIND_H))
return 0;
}
-
-#if defined(_WIN32)
/*
- *-----------------------------------------------------------------------------
- *
- * UtilTokenHasGroup --
- *
- * Determine if the specified token has a particular group
- *
- * Results:
- * 1 if yes
- * 0 if no
- * <0 on error
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
+ * MS does not want us disribute code based on their KB samples in
+ * open source products.
*/
-static int
-UtilTokenHasGroup(HANDLE token,
- SID *group)
-{
- /*
- * The code is from
- * http://support.microsoft.com/support/kb/articles/Q118/6/26.ASP
- * (HOWTO: Determine Whether a Thread Is Running in User Context of Local
- * Administrator Account), modified as follows:
- *
- * . Removed the exception stuff
- *
- * . Fixed the token handle leak
- *
- * . Used DuplicateToken() which does just what we need instead of
- * ImpersonateSelf()/RevertToSelf() which does more, and which I believe
- * will not work if we are already impersonating ourselves
- *
- * . Allocated the SD on the stack
- *
- * . Got rid of the hardcoded DWORD in the computation of the ACL size
- *
- * . Used malloc()/free() instead of Local*()
- *
- * . Added comments
- *
- * --hpreg
- */
-
- /*
- * Make up private access rights --hpreg
- */
-#define Util_HasAdminPriv_Read (1 << 0)
-#define Util_HasAdminPriv_Write (1 << 1)
-
- int ret;
- HANDLE iToken;
- SECURITY_DESCRIPTOR sd;
- DWORD aclLen;
- ACL *acl;
- GENERIC_MAPPING gm;
- PRIVILEGE_SET ps;
- DWORD psLen;
- DWORD granted;
- BOOL status;
-
- iToken = INVALID_HANDLE_VALUE;
- acl = NULL;
-
- /*
- * Duplicate the token, because AccessCheck() requires an impersonation
- * token --hpreg
- */
-
- if (DuplicateToken(token, SecurityImpersonation, &iToken) == 0) {
- ret = -3;
- goto end;
- }
-
- /*
- * Construct a Security Descriptor with a Discretionary Access Control List
- * that contains an Access Control Entry for the administrator group's
- * Security IDentifier --hpreg
- */
-
- if (InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION) == 0) {
- ret = -5;
- goto end;
- }
-
- /*
- * This magic formula comes from the documentation for
- * InitializeAcl() --hpreg
- */
-
- aclLen = sizeof(ACL)
- + ( sizeof(ACCESS_ALLOWED_ACE)
- - sizeof(((ACCESS_ALLOWED_ACE *)0)->SidStart)
- + GetLengthSid(group));
- acl = malloc(aclLen);
- if (acl == NULL) {
- ret = -6;
- goto end;
- }
-
- if (InitializeAcl(acl, aclLen, ACL_REVISION) == 0) {
- ret = -7;
- goto end;
- }
-
- if (AddAccessAllowedAce(acl, ACL_REVISION,
- Util_HasAdminPriv_Read | Util_HasAdminPriv_Write, group) == 0) {
- ret = -8;
- goto end;
- }
-
- if (SetSecurityDescriptorDacl(&sd, TRUE, acl, FALSE) == 0) {
- ret = -9;
- goto end;
- }
-
- /*
- * Set the owner and group of the SD, because AccessCheck() requires
- * it --hpreg
- */
-
- if (SetSecurityDescriptorGroup(&sd, group, FALSE) == 0) {
- ret = -10;
- goto end;
- }
-
- if (SetSecurityDescriptorOwner(&sd, group, FALSE) == 0) {
- ret = -11;
- goto end;
- }
-
- /*
- * Finally, check if the SD grants access to the calling thread --hpreg
- */
-
- gm.GenericRead = Util_HasAdminPriv_Read;
- gm.GenericWrite = Util_HasAdminPriv_Write;
- gm.GenericExecute = 0;
- gm.GenericAll = Util_HasAdminPriv_Read | Util_HasAdminPriv_Write;
-
- psLen = sizeof(ps);
- if (AccessCheck(&sd, iToken, Util_HasAdminPriv_Read, &gm, &ps, &psLen,
- &granted, &status) == 0) {
- ret = -12;
- goto end;
- }
-
- ret = status ? 1 : 0;
-
-end:
-
- if (iToken != INVALID_HANDLE_VALUE) {
- if (CloseHandle(iToken) == 0 && ret >= 0) {
- ret = -14;
- }
- }
-
- free(acl);
-
- return ret;
-
-#undef Util_HasAdminPriv_Read
-#undef Util_HasAdminPriv_Write
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Util_TokenHasAdminPriv --
- *
- * Determine if the specified token has administrator privileges
- *
- * Results:
- * 1 if yes
- * 0 if no
- * <0 on error
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-int
-Util_TokenHasAdminPriv(HANDLE token)
-{
- SID_IDENTIFIER_AUTHORITY sidIdentAuth = SECURITY_NT_AUTHORITY;
- SID *adminGrp = NULL;
- int ret;
-
- /*
- * Build the Security IDentifier of the administrator group --hpreg
- */
-
- if (AllocateAndInitializeSid(&sidIdentAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
- DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
- &adminGrp) == 0) {
- ret = -4;
- goto end;
- }
-
- ret = UtilTokenHasGroup(token, adminGrp);
-
-end:
- if (adminGrp) {
- FreeSid(adminGrp);
- }
- return ret;
-}
-
-
-/*
- *-----------------------------------------------------------------------------
- *
- * Util_TokenHasInteractPriv --
- *
- * Determine if the specified token is logged in interactively.
- * -- local logons and Remote Desktops logons
- *
- * Results:
- * 1 if yes
- * 0 if no
- * <0 on error
- *
- * Side effects:
- * None
- *
- *-----------------------------------------------------------------------------
- */
-
-int
-Util_TokenHasInteractPriv(HANDLE token)
-{
- SID_IDENTIFIER_AUTHORITY sidIdentAuth = SECURITY_NT_AUTHORITY;
- SID *interactiveGrp = NULL;
- int ret;
-
- /*
- * Build the Security IDentifier of the administrator group --hpreg
- */
-
- if (AllocateAndInitializeSid(&sidIdentAuth, 1, SECURITY_INTERACTIVE_RID,
- 0, 0, 0, 0, 0, 0, 0,
- &interactiveGrp) == 0) {
- ret = -4;
- goto end;
- }
-
- ret = UtilTokenHasGroup(token, interactiveGrp);
-
-end:
- if (interactiveGrp) {
- FreeSid(interactiveGrp);
- }
- return ret;
-}
-
-#endif
-
/*
*-----------------------------------------------------------------------------