lok: vcl: fix multiple floatwin removal case more robustly.
[LibreOffice.git] / sal / osl / w32 / security.cxx
blobebd3754705ddb9cf618f3a0d5792921eb9d050a1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "system.h"
22 #include <osl/security.h>
23 #include <osl/diagnose.h>
24 #include <osl/thread.h>
25 #include <osl/file.h>
26 #include <systools/win32/uwinapi.h>
27 #include <sddl.h>
28 #include <sal/macros.h>
29 #include <sal/log.hxx>
30 #include <o3tl/char16_t2wchar_t.hxx>
31 #include "secimpl.hxx"
33 /* Data for use in (un)LoadProfile Functions */
34 /* Declarations based on USERENV.H for Windows 2000 Beta 2 */
35 #define PI_NOUI 0x00000001 // Prevents displaying of messages
37 typedef struct {
38 DWORD dwSize; // Must be set to sizeof(PROFILEINFO)
39 DWORD dwFlags; // See flags above
40 LPWSTR lpUserName; // User name (required)
41 LPWSTR lpProfilePath; // Roaming profile path
42 LPWSTR lpDefaultPath; // Default user profile path
43 LPWSTR lpServerName; // Validating DC name in netbios format
44 LPWSTR lpPolicyPath; // Path to the NT4 style policy file
45 HANDLE hProfile; // Registry key handle - filled by function
46 } PROFILEINFOW, FAR * LPPROFILEINFOW;
48 /* Typedefs for function pointers in USERENV.DLL */
49 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNLOADUSERPROFILE) (
50 HANDLE hToken,
51 LPPROFILEINFOW lpProfileInfo
54 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNUNLOADUSERPROFILE) (
55 HANDLE hToken,
56 HANDLE hProfile
59 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNGETUSERPROFILEDIR) (
60 HANDLE hToken,
61 LPWSTR lpProfileDir,
62 LPDWORD lpcchSize
65 /* To get an impersonation token we need to create an impersonation
66 duplicate so every access token has to be created with duplicate
67 access rights */
69 #define TOKEN_DUP_QUERY (TOKEN_QUERY|TOKEN_DUPLICATE)
71 static bool GetSpecialFolder(rtl_uString **strPath,int nFolder);
72 // We use LPCTSTR here, because we use it with SE_foo_NAME constants
73 // which are defined in winnt.h as UNICODE-dependent TEXT("PrivilegeName")
74 static BOOL Privilege(LPCTSTR pszPrivilege, BOOL bEnable);
75 static bool getUserNameImpl(oslSecurity Security, rtl_uString **strName, bool bIncludeDomain);
77 oslSecurity SAL_CALL osl_getCurrentSecurity(void)
79 oslSecurityImpl* pSecImpl = static_cast<oslSecurityImpl *>(malloc(sizeof(oslSecurityImpl)));
80 if (pSecImpl)
82 pSecImpl->m_pNetResource = nullptr;
83 pSecImpl->m_User[0] = '\0';
84 pSecImpl->m_hToken = nullptr;
85 pSecImpl->m_hProfile = nullptr;
87 return pSecImpl;
90 oslSecurityError SAL_CALL osl_loginUser( rtl_uString *strUserName, rtl_uString *strPasswd, oslSecurity *pSecurity )
92 oslSecurityError ret;
94 sal_Unicode* strUser;
95 sal_Unicode* strDomain = o3tl::toU(_wcsdup(o3tl::toW(rtl_uString_getStr(strUserName))));
96 HANDLE hUserToken;
97 LUID luid;
99 if (nullptr != (strUser = o3tl::toU(wcschr(o3tl::toW(strDomain), L'/'))))
100 *strUser++ = L'\0';
101 else
103 strUser = strDomain;
104 strDomain = nullptr;
107 // this process must have the right: 'act as a part of operatingsystem'
108 OSL_ASSERT(LookupPrivilegeValue(nullptr, SE_TCB_NAME, &luid));
109 (void) luid;
111 if (LogonUserW(o3tl::toW(strUser), strDomain ? o3tl::toW(strDomain) : L"", o3tl::toW(rtl_uString_getStr(strPasswd)),
112 LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
113 &hUserToken))
115 oslSecurityImpl* pSecImpl = static_cast<oslSecurityImpl *>(malloc(sizeof(oslSecurityImpl)));
116 if (pSecImpl)
118 pSecImpl->m_pNetResource = nullptr;
119 pSecImpl->m_hToken = hUserToken;
120 pSecImpl->m_hProfile = nullptr;
121 wcscpy(o3tl::toW(pSecImpl->m_User), o3tl::toW(strUser));
123 *pSecurity = pSecImpl;
124 ret = pSecImpl ? osl_Security_E_None : osl_Security_E_Unknown;
126 else
128 ret = osl_Security_E_UserUnknown;
131 if (strDomain)
132 free(strDomain);
133 else
134 free(strUser);
136 return ret;
139 oslSecurityError SAL_CALL osl_loginUserOnFileServer(rtl_uString *strUserName,
140 rtl_uString *strPasswd,
141 rtl_uString *strFileServer,
142 oslSecurity *pSecurity)
144 oslSecurityError ret;
145 DWORD err;
146 NETRESOURCEW netResource;
147 sal_Unicode* remoteName;
148 sal_Unicode* userName;
150 remoteName = static_cast<sal_Unicode *>(malloc((rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 4) * sizeof(sal_Unicode)));
151 userName = static_cast<sal_Unicode *>(malloc((rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 2) * sizeof(sal_Unicode)));
153 wcscpy(o3tl::toW(remoteName), L"\\\\");
154 wcscat(o3tl::toW(remoteName), o3tl::toW(rtl_uString_getStr(strFileServer)));
155 wcscat(o3tl::toW(remoteName), L"\\");
156 wcscat(o3tl::toW(remoteName), o3tl::toW(rtl_uString_getStr(strUserName)));
158 wcscpy(o3tl::toW(userName), o3tl::toW(rtl_uString_getStr(strFileServer)));
159 wcscat(o3tl::toW(userName), L"\\");
160 wcscat(o3tl::toW(userName), o3tl::toW(rtl_uString_getStr(strUserName)));
162 netResource.dwScope = RESOURCE_GLOBALNET;
163 netResource.dwType = RESOURCETYPE_DISK;
164 netResource.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
165 netResource.dwUsage = RESOURCEUSAGE_CONNECTABLE;
166 netResource.lpLocalName = nullptr;
167 netResource.lpRemoteName = o3tl::toW(remoteName);
168 netResource.lpComment = nullptr;
169 netResource.lpProvider = nullptr;
171 err = WNetAddConnection2W(&netResource, o3tl::toW(rtl_uString_getStr(strPasswd)), o3tl::toW(userName), 0);
173 if ((err == NO_ERROR) || (err == ERROR_ALREADY_ASSIGNED))
175 oslSecurityImpl* pSecImpl = static_cast<oslSecurityImpl *>(malloc(sizeof(oslSecurityImpl)));
176 if (pSecImpl)
178 pSecImpl->m_pNetResource = static_cast<NETRESOURCEW *>(malloc(sizeof(NETRESOURCE)));
179 if (pSecImpl->m_pNetResource)
181 *pSecImpl->m_pNetResource = netResource;
182 pSecImpl->m_hToken = nullptr;
183 pSecImpl->m_hProfile = nullptr;
184 wcscpy(o3tl::toW(pSecImpl->m_User), o3tl::toW(rtl_uString_getStr(strUserName)));
186 else
188 free(pSecImpl);
189 pSecImpl = nullptr;
192 *pSecurity = pSecImpl;
194 ret = pSecImpl ? osl_Security_E_None : osl_Security_E_Unknown;
196 else
198 ret = osl_Security_E_UserUnknown;
201 free(remoteName);
202 free(userName);
204 return ret;
207 sal_Bool SAL_CALL osl_isAdministrator(oslSecurity Security)
209 if (Security != nullptr)
211 HANDLE hImpersonationToken = nullptr;
212 PSID psidAdministrators;
213 SID_IDENTIFIER_AUTHORITY siaNtAuthority = { SECURITY_NT_AUTHORITY };
214 bool bSuccess = false;
216 /* If Security contains an access token we need to duplicate it to an impersonation
217 access token. NULL works with CheckTokenMembership() as the current effective
218 impersonation token
221 if ( static_cast<oslSecurityImpl*>(Security)->m_hToken )
223 if ( !DuplicateToken (static_cast<oslSecurityImpl*>(Security)->m_hToken, SecurityImpersonation, &hImpersonationToken) )
224 return false;
227 /* CheckTokenMembership() can be used on W2K and higher (NT4 no longer supported by OOo)
228 and also works on Vista to retrieve the effective user rights. Just checking for
229 membership of Administrators group is not enough on Vista this would require additional
230 complicated checks as described in KB article Q118626: http://support.microsoft.com/kb/118626/en-us
233 if (AllocateAndInitializeSid(&siaNtAuthority,
235 SECURITY_BUILTIN_DOMAIN_RID,
236 DOMAIN_ALIAS_RID_ADMINS,
237 0, 0, 0, 0, 0, 0,
238 &psidAdministrators))
240 BOOL fSuccess = FALSE;
242 if (CheckTokenMembership(hImpersonationToken, psidAdministrators, &fSuccess) && fSuccess)
243 bSuccess = true;
245 FreeSid(psidAdministrators);
248 if (hImpersonationToken)
249 CloseHandle(hImpersonationToken);
251 return bSuccess;
253 else
255 return false;
259 void SAL_CALL osl_freeSecurityHandle(oslSecurity Security)
261 if (Security)
263 oslSecurityImpl *pSecImpl = static_cast<oslSecurityImpl*>(Security);
265 if (pSecImpl->m_pNetResource != nullptr)
267 WNetCancelConnection2W(pSecImpl->m_pNetResource->lpRemoteName, 0, true);
269 free(pSecImpl->m_pNetResource->lpRemoteName);
270 free(pSecImpl->m_pNetResource);
273 if (pSecImpl->m_hToken)
274 CloseHandle(pSecImpl->m_hToken);
276 if ( pSecImpl->m_hProfile )
277 CloseHandle(pSecImpl->m_hProfile);
279 free (pSecImpl);
283 sal_Bool SAL_CALL osl_getUserIdent(oslSecurity Security, rtl_uString **strIdent)
285 if (Security != nullptr)
287 oslSecurityImpl *pSecImpl = static_cast<oslSecurityImpl*>(Security);
289 HANDLE hAccessToken = pSecImpl->m_hToken;
291 if (hAccessToken == nullptr)
292 OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);
294 if (hAccessToken)
296 DWORD nInfoBuffer = 512;
297 UCHAR* pInfoBuffer = static_cast<UCHAR *>(malloc(nInfoBuffer));
299 while (!GetTokenInformation(hAccessToken, TokenUser,
300 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
302 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
304 if (auto p = static_cast<UCHAR *>(realloc(pInfoBuffer, nInfoBuffer)))
305 pInfoBuffer = p;
306 else
308 free(pInfoBuffer);
309 pInfoBuffer = nullptr;
310 break;
313 else
315 free(pInfoBuffer);
316 pInfoBuffer = nullptr;
317 break;
321 if (pSecImpl->m_hToken == nullptr)
322 CloseHandle(hAccessToken);
324 if (pInfoBuffer)
326 PSID pSid = reinterpret_cast<PTOKEN_USER>(pInfoBuffer)->User.Sid;
328 LPWSTR pSidStr = nullptr;
329 BOOL bResult = ConvertSidToStringSidW(pSid, &pSidStr);
330 if (bResult)
332 rtl_uString_newFromStr(strIdent, o3tl::toU(pSidStr));
333 LocalFree(pSidStr);
335 else
337 const DWORD dwError = GetLastError();
338 SAL_WARN(
339 "sal.osl",
340 "ConvertSidToStringSidW failed. GetLastError returned: " << dwError);
343 free(pInfoBuffer);
345 return bResult != FALSE;
348 else
350 DWORD needed = 0;
352 WNetGetUserW(nullptr, nullptr, &needed);
353 if (needed < 16)
354 needed = 16;
356 if (auto Ident = static_cast<sal_Unicode *>(malloc(needed*sizeof(sal_Unicode))))
358 if (WNetGetUserW(nullptr, o3tl::toW(Ident), &needed) != NO_ERROR)
360 wcscpy(o3tl::toW(Ident), L"unknown");
361 Ident[7] = L'\0';
364 rtl_uString_newFromStr( strIdent, Ident);
365 free(Ident);
366 return true;
371 return false;
374 sal_Bool SAL_CALL osl_getUserName(oslSecurity Security, rtl_uString **strName)
376 return getUserNameImpl(Security, strName, true);
379 sal_Bool SAL_CALL osl_getShortUserName(oslSecurity Security, rtl_uString **strName)
381 return getUserNameImpl(Security, strName, false);
384 sal_Bool SAL_CALL osl_getHomeDir(oslSecurity Security, rtl_uString **pustrDirectory)
386 rtl_uString *ustrSysDir = nullptr;
387 bool bSuccess = false;
389 if (Security != nullptr)
391 oslSecurityImpl *pSecImpl = static_cast<oslSecurityImpl*>(Security);
393 if (pSecImpl->m_pNetResource != nullptr)
395 rtl_uString_newFromStr( &ustrSysDir, o3tl::toU(pSecImpl->m_pNetResource->lpRemoteName));
397 bSuccess = osl_File_E_None == osl_getFileURLFromSystemPath( ustrSysDir, pustrDirectory );
399 else
401 bSuccess = GetSpecialFolder(&ustrSysDir, CSIDL_PERSONAL) &&
402 (osl_File_E_None == osl_getFileURLFromSystemPath(ustrSysDir, pustrDirectory));
406 if ( ustrSysDir )
407 rtl_uString_release( ustrSysDir );
409 return bSuccess;
412 sal_Bool SAL_CALL osl_getConfigDir(oslSecurity Security, rtl_uString **pustrDirectory)
414 bool bSuccess = false;
416 if (Security != nullptr)
418 oslSecurityImpl *pSecImpl = static_cast<oslSecurityImpl*>(Security);
420 if (pSecImpl->m_pNetResource != nullptr)
422 rtl_uString *ustrSysDir = nullptr;
424 rtl_uString_newFromStr( &ustrSysDir, o3tl::toU(pSecImpl->m_pNetResource->lpRemoteName));
425 bSuccess = osl_File_E_None == osl_getFileURLFromSystemPath( ustrSysDir, pustrDirectory);
427 if ( ustrSysDir )
428 rtl_uString_release( ustrSysDir );
430 else
432 if (pSecImpl->m_hToken)
434 /* not implemented */
435 OSL_ASSERT(false);
437 else
439 rtl_uString *ustrFile = nullptr;
440 sal_Unicode sFile[_MAX_PATH];
442 if ( !GetSpecialFolder( &ustrFile, CSIDL_APPDATA) )
444 OSL_VERIFY(GetWindowsDirectoryW(o3tl::toW(sFile), _MAX_DIR) > 0);
446 rtl_uString_newFromStr( &ustrFile, sFile);
449 bSuccess = osl_File_E_None == osl_getFileURLFromSystemPath(ustrFile, pustrDirectory);
451 if ( ustrFile )
452 rtl_uString_release( ustrFile );
457 return bSuccess;
460 sal_Bool SAL_CALL osl_loadUserProfile(oslSecurity Security)
462 /* CreateProcessAsUser does not load the specified user's profile
463 into the HKEY_USERS registry key. This means that access to information
464 in the HKEY_CURRENT_USER registry key may not produce results consistent
465 with a normal interactive logon.
466 It is your responsibility to load the user's registry hive into HKEY_USERS
467 with the LoadUserProfile function before calling CreateProcessAsUser.
469 bool bOk = false;
471 RegCloseKey(HKEY_CURRENT_USER);
473 if (Privilege(SE_RESTORE_NAME, TRUE))
475 HMODULE hUserEnvLib = nullptr;
476 LPFNLOADUSERPROFILE fLoadUserProfile = nullptr;
477 LPFNUNLOADUSERPROFILE fUnloadUserProfile = nullptr;
478 HANDLE hAccessToken = static_cast<oslSecurityImpl*>(Security)->m_hToken;
480 /* try to create user profile */
481 if ( !hAccessToken )
483 /* retrieve security handle if not done before e.g. osl_getCurrentSecurity()
485 HANDLE hProcess = GetCurrentProcess();
487 if (hProcess != nullptr)
489 OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken);
490 CloseHandle(hProcess);
494 hUserEnvLib = LoadLibraryW(L"userenv.dll");
496 if (hUserEnvLib)
498 fLoadUserProfile = reinterpret_cast<LPFNLOADUSERPROFILE>(GetProcAddress(hUserEnvLib, "LoadUserProfileW"));
499 fUnloadUserProfile = reinterpret_cast<LPFNUNLOADUSERPROFILE>(GetProcAddress(hUserEnvLib, "UnloadUserProfile"));
501 if (fLoadUserProfile && fUnloadUserProfile)
503 rtl_uString *buffer = nullptr;
504 PROFILEINFOW pi;
506 getUserNameImpl(Security, &buffer, false);
508 ZeroMemory(&pi, sizeof(pi));
509 pi.dwSize = sizeof(pi);
510 pi.lpUserName = o3tl::toW(rtl_uString_getStr(buffer));
511 pi.dwFlags = PI_NOUI;
513 if (fLoadUserProfile(hAccessToken, &pi))
515 fUnloadUserProfile(hAccessToken, pi.hProfile);
517 bOk = true;
520 rtl_uString_release(buffer);
523 FreeLibrary(hUserEnvLib);
526 if (hAccessToken && (hAccessToken != static_cast<oslSecurityImpl*>(Security)->m_hToken))
527 CloseHandle(hAccessToken);
530 return bOk;
533 void SAL_CALL osl_unloadUserProfile(oslSecurity Security)
535 if ( static_cast<oslSecurityImpl*>(Security)->m_hProfile != nullptr )
537 HMODULE hUserEnvLib = nullptr;
538 LPFNUNLOADUSERPROFILE fUnloadUserProfile = nullptr;
539 HANDLE hAccessToken = static_cast<oslSecurityImpl*>(Security)->m_hToken;
541 if ( !hAccessToken )
543 /* retrieve security handle if not done before e.g. osl_getCurrentSecurity()
545 HANDLE hProcess = GetCurrentProcess();
547 if (hProcess != nullptr)
549 OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken);
550 CloseHandle(hProcess);
554 hUserEnvLib = LoadLibraryW(L"userenv.dll");
556 if (hUserEnvLib)
558 fUnloadUserProfile = reinterpret_cast<LPFNUNLOADUSERPROFILE>(GetProcAddress(hUserEnvLib, "UnloadUserProfile"));
560 if (fUnloadUserProfile)
562 /* unloading the user profile */
563 fUnloadUserProfile(hAccessToken, static_cast<oslSecurityImpl*>(Security)->m_hProfile);
566 FreeLibrary(hUserEnvLib);
569 static_cast<oslSecurityImpl*>(Security)->m_hProfile = nullptr;
571 if (hAccessToken && (hAccessToken != static_cast<oslSecurityImpl*>(Security)->m_hToken))
572 CloseHandle(hAccessToken);
576 static bool GetSpecialFolder(rtl_uString **strPath, int nFolder)
578 bool bRet = false;
579 HINSTANCE hLibrary = LoadLibraryW(L"shell32.dll");
581 if (hLibrary != nullptr)
583 sal_Unicode PathW[_MAX_PATH];
584 BOOL (WINAPI *pSHGetSpecialFolderPathW)(HWND, LPWSTR, int, BOOL) = reinterpret_cast<BOOL (WINAPI *)(HWND, LPWSTR, int, BOOL)>(GetProcAddress(hLibrary, "SHGetSpecialFolderPathW"));
586 if (pSHGetSpecialFolderPathW)
588 if (pSHGetSpecialFolderPathW(GetActiveWindow(), o3tl::toW(PathW), nFolder, TRUE))
590 rtl_uString_newFromStr( strPath, PathW);
591 bRet = true;
594 else
596 HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *) = reinterpret_cast<HRESULT (WINAPI *)(HWND, int, LPITEMIDLIST *)>(GetProcAddress(hLibrary, "SHGetSpecialFolderLocation"));
597 BOOL (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR) = reinterpret_cast<BOOL (WINAPI *)(LPCITEMIDLIST, LPWSTR)>(GetProcAddress(hLibrary, "SHGetPathFromIDListW"));
598 HRESULT (WINAPI *pSHGetMalloc)(LPMALLOC *) = reinterpret_cast<HRESULT (WINAPI *)(LPMALLOC *)>(GetProcAddress(hLibrary, "SHGetMalloc"));
600 if (pSHGetSpecialFolderLocation && pSHGetPathFromIDListW && pSHGetMalloc )
602 LPITEMIDLIST pidl;
603 LPMALLOC pMalloc;
604 HRESULT hr;
606 hr = pSHGetSpecialFolderLocation(GetActiveWindow(), nFolder, &pidl);
608 /* Get SHGetSpecialFolderLocation fails if directory does not exists. */
609 /* If it fails we try to create the directory and redo the call */
610 if (! SUCCEEDED(hr))
612 HKEY hRegKey;
614 if (RegOpenKeyW(HKEY_CURRENT_USER,
615 L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
616 &hRegKey) == ERROR_SUCCESS)
618 LONG lRet;
619 DWORD lSize = sizeof(PathW);
620 DWORD Type = REG_SZ;
622 switch (nFolder)
624 case CSIDL_APPDATA:
625 lRet = RegQueryValueExW(hRegKey, L"AppData", nullptr, &Type, reinterpret_cast<LPBYTE>(PathW), &lSize);
626 break;
628 case CSIDL_PERSONAL:
629 lRet = RegQueryValueExW(hRegKey, L"Personal", nullptr, &Type, reinterpret_cast<LPBYTE>(PathW), &lSize);
630 break;
632 default:
633 lRet = -1l;
636 if ((lRet == ERROR_SUCCESS) && (Type == REG_SZ))
638 if (_waccess(o3tl::toW(PathW), 0) < 0)
639 CreateDirectoryW(o3tl::toW(PathW), nullptr);
641 hr = pSHGetSpecialFolderLocation(GetActiveWindow(), nFolder, &pidl);
644 RegCloseKey(hRegKey);
648 if (SUCCEEDED(hr))
650 if (pSHGetPathFromIDListW(pidl, o3tl::toW(PathW)))
652 /* if directory does not exist, create it */
653 if (_waccess(o3tl::toW(PathW), 0) < 0)
654 CreateDirectoryW(o3tl::toW(PathW), nullptr);
656 rtl_uString_newFromStr( strPath, PathW);
657 bRet = true;
661 if (SUCCEEDED(pSHGetMalloc(&pMalloc)))
663 pMalloc->Free(pidl);
664 pMalloc->Release();
669 FreeLibrary(hLibrary);
672 return bRet;
675 // We use LPCTSTR here, because we use it with SE_foo_NAME constants
676 // which are defined in winnt.h as UNICODE-dependent TEXT("PrivilegeName")
677 static BOOL Privilege(LPCTSTR strPrivilege, BOOL bEnable)
679 HANDLE hToken;
680 TOKEN_PRIVILEGES tp;
682 // obtain the processes token
683 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_DUP_QUERY, &hToken))
684 return FALSE;
686 // get the luid
687 if (!LookupPrivilegeValue(nullptr, strPrivilege, &tp.Privileges[0].Luid))
688 return FALSE;
690 tp.PrivilegeCount = 1;
692 if (bEnable)
693 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
694 else
695 tp.Privileges[0].Attributes = 0;
697 // enable or disable the privilege
698 if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, nullptr, nullptr))
699 return FALSE;
701 if (!CloseHandle(hToken))
702 return FALSE;
704 return TRUE;
707 static bool getUserNameImpl(oslSecurity Security, rtl_uString **strName, bool bIncludeDomain)
709 if (Security != nullptr)
711 oslSecurityImpl *pSecImpl = static_cast<oslSecurityImpl*>(Security);
713 HANDLE hAccessToken = pSecImpl->m_hToken;
715 if (hAccessToken == nullptr)
716 OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);
718 if (hAccessToken)
720 DWORD nInfoBuffer = 512;
721 UCHAR* pInfoBuffer = static_cast<UCHAR *>(malloc(nInfoBuffer));
723 while (!GetTokenInformation(hAccessToken, TokenUser,
724 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
726 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
728 if (auto p = static_cast<UCHAR *>(realloc(pInfoBuffer, nInfoBuffer)))
729 pInfoBuffer = p;
730 else
732 free(pInfoBuffer);
733 pInfoBuffer = nullptr;
734 break;
737 else
739 free(pInfoBuffer);
740 pInfoBuffer = nullptr;
741 break;
745 if (pSecImpl->m_hToken == nullptr)
746 CloseHandle(hAccessToken);
748 if (pInfoBuffer)
750 sal_Unicode UserName[128];
751 sal_Unicode DomainName[128];
752 sal_Unicode Name[257];
753 DWORD nUserName = SAL_N_ELEMENTS(UserName);
754 DWORD nDomainName = SAL_N_ELEMENTS(DomainName);
755 SID_NAME_USE sUse;
757 if (LookupAccountSidW(nullptr, reinterpret_cast<PTOKEN_USER>(pInfoBuffer)->User.Sid,
758 o3tl::toW(UserName), &nUserName,
759 o3tl::toW(DomainName), &nDomainName, &sUse))
761 if (bIncludeDomain)
763 wcscpy(o3tl::toW(Name), o3tl::toW(DomainName));
764 wcscat(o3tl::toW(Name), L"/");
765 wcscat(o3tl::toW(Name), o3tl::toW(UserName));
767 else
769 wcscpy(o3tl::toW(Name), o3tl::toW(UserName));
772 rtl_uString_newFromStr(strName, Name);
773 free(pInfoBuffer);
774 return true;
778 else
780 DWORD needed=0;
781 sal_Unicode *pNameW=nullptr;
783 WNetGetUserW(nullptr, nullptr, &needed);
784 pNameW = static_cast<sal_Unicode *>(malloc (needed*sizeof(sal_Unicode)));
786 if (WNetGetUserW(nullptr, o3tl::toW(pNameW), &needed) == NO_ERROR)
788 rtl_uString_newFromStr( strName, pNameW);
790 if (pNameW)
791 free(pNameW);
792 return true;
794 else if (pSecImpl->m_User[0] != '\0')
796 rtl_uString_newFromStr(strName, o3tl::toU(pSecImpl->m_pNetResource->lpRemoteName));
798 if (pNameW)
799 free(pNameW);
801 return true;
804 if (pNameW)
805 free(pNameW);
809 return false;
812 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */