2013b7b9ca831db98a94dec056dc4ea405b4a648
[openafs.git] / src / WINNT / client_config / isadmin.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include <windows.h>
16 #include <WINNT/TaLocale.h>
17
18
19 /*
20  * ISWINNT ____________________________________________________________________
21  *
22  */
23
24 BOOL IsWindowsNT (void)
25 {
26    static BOOL fChecked = FALSE;
27    static BOOL fIsWinNT = FALSE;
28
29    if (!fChecked)
30       {
31       fChecked = TRUE;
32
33       OSVERSIONINFO Version;
34       memset (&Version, 0x00, sizeof(Version));
35       Version.dwOSVersionInfoSize = sizeof(Version);
36
37       if (GetVersionEx (&Version))
38          {
39          if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT)
40             fIsWinNT = TRUE;
41          }
42       }
43
44    return fIsWinNT;
45 }
46
47
48 /*
49  * ISADMIN ____________________________________________________________________
50  *
51  */
52
53 #define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins"
54
55 BOOL IsAdmin (void)
56 {
57     static BOOL fAdmin = FALSE;
58     static BOOL fTested = FALSE;
59
60     if (!fTested)
61     {
62         /* Obtain the SID for the AFS client admin group.  If the group does
63          * not exist, then assume we have AFS client admin privileges.
64          */
65         PSID psidAdmin = NULL;
66         DWORD dwSize, dwSize2;
67         char pszAdminGroup[ MAX_COMPUTERNAME_LENGTH + sizeof(AFSCLIENT_ADMIN_GROUPNAME) + 2 ];
68         char *pszRefDomain = NULL;
69         SID_NAME_USE snu = SidTypeGroup;
70
71         dwSize = sizeof(pszAdminGroup);
72
73         if (!GetComputerName(pszAdminGroup, &dwSize)) {
74             /* Can't get computer name.  We return false in this case.
75                Retain fAdmin and fTested. This shouldn't happen.*/
76             return FALSE;
77         }
78
79         fTested = TRUE;
80
81         dwSize = 0;
82         dwSize2 = 0;
83
84         strcat(pszAdminGroup,"\\");
85         strcat(pszAdminGroup, AFSCLIENT_ADMIN_GROUPNAME);
86
87         LookupAccountName(NULL, pszAdminGroup, NULL, &dwSize, NULL, &dwSize2, &snu);
88         /* that should always fail. */
89
90         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
91             /* if we can't find the group, then we allow the operation */
92             fAdmin = TRUE;
93             return TRUE;
94         }
95
96         if (dwSize == 0 || dwSize2 == 0) {
97             /* Paranoia */
98             fAdmin = TRUE;
99             return TRUE;
100         }
101
102         psidAdmin = (PSID) malloc(dwSize); memset(psidAdmin,0,dwSize);
103         pszRefDomain = (char *)malloc(dwSize2);
104
105         if (!LookupAccountName(NULL, pszAdminGroup, psidAdmin, &dwSize, pszRefDomain, &dwSize2, &snu)) {
106             /* We can't lookup the group now even though we looked it up earlier.  
107                Could this happen? */
108             fAdmin = TRUE;
109         } else {
110             /* Then open our current ProcessToken */
111             HANDLE hToken;
112
113             if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken))
114             {
115                 /* We'll have to allocate a chunk of memory to store the list of
116                  * groups to which this user belongs; find out how much memory
117                  * we'll need.
118                  */
119                 DWORD dwSize = 0;
120                 PTOKEN_GROUPS pGroups;
121                 
122                 GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize);
123             
124                 pGroups = (PTOKEN_GROUPS)malloc(dwSize);
125                 
126                 /* Allocate that buffer, and read in the list of groups. */
127                 if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize))
128                 {
129                     /* Look through the list of group SIDs and see if any of them
130                      * matches the AFS Client Admin group SID.
131                      */
132                     size_t iGroup = 0;
133                     for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup)
134                     {
135                         if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) {
136                             fAdmin = TRUE;
137                         }
138                     }
139                 }
140
141                 if (pGroups)
142                     free(pGroups);
143             }
144         }
145
146         free(psidAdmin);
147         free(pszRefDomain);
148     }
149
150     return fAdmin;
151 }
152