/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ #include #include extern "C" { #include #include } #include #include /* * ISWINNT ____________________________________________________________________ * */ BOOL IsWindowsNT (void) { static BOOL fChecked = FALSE; static BOOL fIsWinNT = FALSE; if (!fChecked) { fChecked = TRUE; OSVERSIONINFO Version; memset (&Version, 0x00, sizeof(Version)); Version.dwOSVersionInfoSize = sizeof(Version); if (GetVersionEx (&Version)) { if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT) fIsWinNT = TRUE; } } return fIsWinNT; } /* * ISADMIN ____________________________________________________________________ * */ #define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins" BOOL IsAdmin (void) { static BOOL fAdmin = FALSE; static BOOL fTested = FALSE; if (!fTested) { /* Obtain the SID for the AFS client admin group. If the group does * not exist, then assume we have AFS client admin privileges. */ PSID psidAdmin = NULL; DWORD dwSize, dwSize2; char pszAdminGroup[ MAX_COMPUTERNAME_LENGTH + sizeof(AFSCLIENT_ADMIN_GROUPNAME) + 2 ]; char *pszRefDomain = NULL; SID_NAME_USE snu = SidTypeGroup; dwSize = sizeof(pszAdminGroup); if (!GetComputerName(pszAdminGroup, &dwSize)) { /* Can't get computer name. We return false in this case. Retain fAdmin and fTested. This shouldn't happen.*/ return FALSE; } dwSize = 0; dwSize2 = 0; strcat(pszAdminGroup,"\\"); strcat(pszAdminGroup, AFSCLIENT_ADMIN_GROUPNAME); LookupAccountName(NULL, pszAdminGroup, NULL, &dwSize, NULL, &dwSize2, &snu); /* that should always fail. */ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { /* if we can't find the group, then we allow the operation */ fAdmin = TRUE; return TRUE; } if (dwSize == 0 || dwSize2 == 0) { /* Paranoia */ fAdmin = TRUE; return TRUE; } psidAdmin = (PSID)malloc(dwSize); memset(psidAdmin,0,dwSize); pszRefDomain = (char *)malloc(dwSize2); if (!LookupAccountName(NULL, pszAdminGroup, psidAdmin, &dwSize, pszRefDomain, &dwSize2, &snu)) { /* We can't lookup the group now even though we looked it up earlier. Could this happen? */ fAdmin = TRUE; } else { /* Then open our current ProcessToken */ HANDLE hToken; if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken)) { if (!CheckTokenMembership(hToken, psidAdmin, &fAdmin)) { /* We'll have to allocate a chunk of memory to store the list of * groups to which this user belongs; find out how much memory * we'll need. */ DWORD dwSize = 0; PTOKEN_GROUPS pGroups; GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize); pGroups = (PTOKEN_GROUPS)malloc(dwSize); /* Allocate that buffer, and read in the list of groups. */ if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize)) { /* Look through the list of group SIDs and see if any of them * matches the AFS Client Admin group SID. */ size_t iGroup = 0; for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup) { if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) { fAdmin = TRUE; } } } if (pGroups) free(pGroups); } /* if do not have permission because we were not explicitly listed * in the Admin Client Group let's see if we are the SYSTEM account */ if (!fAdmin) { PTOKEN_USER pTokenUser; SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY; PSID pSidLocalSystem = 0; DWORD gle; GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize); pTokenUser = (PTOKEN_USER)malloc(dwSize); if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize)) gle = GetLastError(); if (AllocateAndInitializeSid( &SIDAuth, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &pSidLocalSystem)) { if (EqualSid(pTokenUser->User.Sid, pSidLocalSystem)) { fAdmin = TRUE; } FreeSid(pSidLocalSystem); } if ( pTokenUser ) free(pTokenUser); } } } free(psidAdmin); free(pszRefDomain); fTested = TRUE; } return fAdmin; }