rx: Remove RX_CALL_BUSY
[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 #include <winsock2.h>
11 #include <ws2tcpip.h>
12
13 extern "C" {
14 #include <afs/param.h>
15 #include <afs/stds.h>
16 }
17
18 #include <windows.h>
19 #include <WINNT/TaLocale.h>
20
21
22 /*
23  * ISWINNT ____________________________________________________________________
24  *
25  */
26
27 BOOL IsWindowsNT (void)
28 {
29    static BOOL fChecked = FALSE;
30    static BOOL fIsWinNT = FALSE;
31
32    if (!fChecked)
33       {
34       fChecked = TRUE;
35
36       OSVERSIONINFO Version;
37       memset (&Version, 0x00, sizeof(Version));
38       Version.dwOSVersionInfoSize = sizeof(Version);
39
40       if (GetVersionEx (&Version))
41          {
42          if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT)
43             fIsWinNT = TRUE;
44          }
45       }
46
47    return fIsWinNT;
48 }
49
50
51 /*
52  * ISADMIN ____________________________________________________________________
53  *
54  */
55
56 #define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins"
57
58 BOOL IsAdmin (void)
59 {
60     static BOOL fAdmin = FALSE;
61     static BOOL fTested = FALSE;
62
63     if (!fTested)
64     {
65         /* Obtain the SID for the AFS client admin group.  If the group does
66          * not exist, then assume we have AFS client admin privileges.
67          */
68         PSID psidAdmin = NULL;
69         DWORD dwSize, dwSize2;
70         char pszAdminGroup[ MAX_COMPUTERNAME_LENGTH + sizeof(AFSCLIENT_ADMIN_GROUPNAME) + 2 ];
71         char *pszRefDomain = NULL;
72         SID_NAME_USE snu = SidTypeGroup;
73
74         dwSize = sizeof(pszAdminGroup);
75
76         if (!GetComputerName(pszAdminGroup, &dwSize)) {
77             /* Can't get computer name.  We return false in this case.
78                Retain fAdmin and fTested. This shouldn't happen.*/
79             return FALSE;
80         }
81
82         dwSize = 0;
83         dwSize2 = 0;
84
85         strcat(pszAdminGroup,"\\");
86         strcat(pszAdminGroup, AFSCLIENT_ADMIN_GROUPNAME);
87
88         LookupAccountName(NULL, pszAdminGroup, NULL, &dwSize, NULL, &dwSize2, &snu);
89         /* that should always fail. */
90
91         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
92             /* if we can't find the group, then we allow the operation */
93             fAdmin = TRUE;
94             return TRUE;
95         }
96
97         if (dwSize == 0 || dwSize2 == 0) {
98             /* Paranoia */
99             fAdmin = TRUE;
100             return TRUE;
101         }
102
103         psidAdmin = (PSID)malloc(dwSize); memset(psidAdmin,0,dwSize);
104         pszRefDomain = (char *)malloc(dwSize2);
105
106         if (!LookupAccountName(NULL, pszAdminGroup, psidAdmin, &dwSize, pszRefDomain, &dwSize2, &snu)) {
107             /* We can't lookup the group now even though we looked it up earlier.
108                Could this happen? */
109             fAdmin = TRUE;
110         } else {
111             /* Then open our current ProcessToken */
112             HANDLE hToken;
113
114             if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken))
115             {
116
117                 if (!CheckTokenMembership(hToken, psidAdmin, &fAdmin)) {
118                     /* We'll have to allocate a chunk of memory to store the list of
119                      * groups to which this user belongs; find out how much memory
120                      * we'll need.
121                      */
122                     DWORD dwSize = 0;
123                     PTOKEN_GROUPS pGroups;
124
125                     GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize);
126
127                     pGroups = (PTOKEN_GROUPS)malloc(dwSize);
128
129                     /* Allocate that buffer, and read in the list of groups. */
130                     if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize))
131                     {
132                         /* Look through the list of group SIDs and see if any of them
133                          * matches the AFS Client Admin group SID.
134                          */
135                         size_t iGroup = 0;
136                         for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup)
137                         {
138                             if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) {
139                                 fAdmin = TRUE;
140                             }
141                         }
142                     }
143
144                     if (pGroups)
145                         free(pGroups);
146                 }
147
148                 /* if do not have permission because we were not explicitly listed
149                  * in the Admin Client Group let's see if we are the SYSTEM account
150                  */
151                 if (!fAdmin) {
152                     PTOKEN_USER pTokenUser;
153                     SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
154                     PSID pSidLocalSystem = 0;
155                     DWORD gle;
156
157                     GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize);
158
159                     pTokenUser = (PTOKEN_USER)malloc(dwSize);
160
161                     if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwSize, &dwSize))
162                         gle = GetLastError();
163
164                     if (AllocateAndInitializeSid( &SIDAuth, 1,
165                                                   SECURITY_LOCAL_SYSTEM_RID,
166                                                   0, 0, 0, 0, 0, 0, 0,
167                                                   &pSidLocalSystem))
168                     {
169                         if (EqualSid(pTokenUser->User.Sid, pSidLocalSystem)) {
170                             fAdmin = TRUE;
171                         }
172
173                         FreeSid(pSidLocalSystem);
174                     }
175
176                     if ( pTokenUser )
177                         free(pTokenUser);
178                 }
179             }
180         }
181
182         free(psidAdmin);
183         free(pszRefDomain);
184
185         fTested = TRUE;
186     }
187
188     return fAdmin;
189 }
190