File indexing completed on 2024-04-28 16:59:49

0001 /*
0002    Copyright (C) 2015 Andreas Hartmetz <ahartmetz@gmail.com>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LGPL.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017    Boston, MA 02110-1301, USA.
0018 
0019    Alternatively, this file is available under the Mozilla Public License
0020    Version 1.1.  You may obtain a copy of the License at
0021    http://www.mozilla.org/MPL/
0022 */
0023 
0024 #include "winutil.h"
0025 
0026 #include <iostream>
0027 
0028 #ifdef _WIN32
0029 #define WIN32_LEAN_AND_MEAN
0030 #include <windows.h>
0031 #include <sddl.h>
0032 #endif
0033 
0034 std::string fetchWindowsSid()
0035 {
0036     // Since this code is adapted from libdbus, keep the processId parameter which is only used
0037     // by the server, in case we need it later. The fixed value should let currently dead code
0038     // get optimized out.
0039     const DWORD processId = 0;
0040     const HANDLE processHandle = processId == 0 ? GetCurrentProcess() :
0041                                  OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId);
0042 
0043     bool ok = true;
0044 
0045     HANDLE processToken = INVALID_HANDLE_VALUE;
0046     if (ok && !OpenProcessToken(processHandle, TOKEN_QUERY, &processToken)) {
0047         ok = false;
0048         std::cerr << "OpenProcessToken failed " << GetLastError() << '\n';
0049     }
0050 
0051     PSID psid;
0052     if (ok) {
0053         DWORD n;
0054         SetLastError(0);
0055         GetTokenInformation(processToken, TokenUser, nullptr, 0, &n);
0056         TOKEN_USER *token_user = static_cast<TOKEN_USER *>(alloca(n));
0057         // std::cerr << "GetTokenInformation to get length: length is " << n
0058         //           << " and GetLastError() returns " << GetLastError() << ".\n";
0059         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || !token_user) {
0060             n = 0;
0061         }
0062         if (GetTokenInformation(processToken, TokenUser, token_user, n, &n)) {
0063             psid = token_user->User.Sid;
0064         } else {
0065             ok = false;
0066             std::cerr << "GetTokenInformation failed " << GetLastError() << '\n';
0067         }
0068     }
0069 
0070     if (ok && !IsValidSid(psid)) {
0071         ok = false;
0072         std::cerr << "IsValidSid() says no\n";
0073     }
0074 
0075     std::string ret;
0076     if (ok) {
0077         char *sidChar = nullptr;
0078         if (ConvertSidToStringSidA(psid, &sidChar)) {
0079             ret = sidChar;
0080             LocalFree(sidChar);
0081         } else {
0082             ok = false;
0083             std::cerr << "invalid SID in ConvertSidToStringSidA()\n";
0084         }
0085     }
0086 
0087     CloseHandle(processHandle);
0088     if (processToken != INVALID_HANDLE_VALUE) {
0089         CloseHandle(processToken);
0090     }
0091 
0092     return ret;
0093 }