Bump for 3.6-28
[LibreOffice.git] / sal / osl / w32 / security.c
blobd2e0ef7665a3f168bacc69c63e61c25d56a929cd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "system.h"
32 #include <osl/security.h>
33 #include <osl/diagnose.h>
34 #include <osl/thread.h>
35 #include <osl/file.h>
36 #include <systools/win32/uwinapi.h>
37 #include <sal/macros.h>
38 #include "secimpl.h"
40 /*****************************************************************************/
41 /* Data Type Definition */
42 /*****************************************************************************/
45 /* Data for use in (un)LoadProfile Functions */
46 /* Declarations based on USERENV.H for Windows 2000 Beta 2 */
47 #define PI_NOUI 0x00000001 // Prevents displaying of messages
48 #define PI_APPLYPOLICY 0x00000002 // Apply NT4 style policy
50 typedef struct _PROFILEINFOW {
51 DWORD dwSize; // Must be set to sizeof(PROFILEINFO)
52 DWORD dwFlags; // See flags above
53 LPWSTR lpUserName; // User name (required)
54 LPWSTR lpProfilePath; // Roaming profile path
55 LPWSTR lpDefaultPath; // Default user profile path
56 LPWSTR lpServerName; // Validating DC name in netbios format
57 LPWSTR lpPolicyPath; // Path to the NT4 style policy file
58 HANDLE hProfile; // Registry key handle - filled by function
59 } PROFILEINFOW, FAR * LPPROFILEINFOW;
61 /* Typedefs for function pointers in USERENV.DLL */
62 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNLOADUSERPROFILE) (
63 HANDLE hToken,
64 LPPROFILEINFOW lpProfileInfo
67 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNUNLOADUSERPROFILE) (
68 HANDLE hToken,
69 HANDLE hProfile
72 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNGETUSERPROFILEDIR) (
73 HANDLE hToken,
74 LPTSTR lpProfileDir,
75 LPDWORD lpcchSize
78 /* To get an impersonation token we need to create an impersonation
79 duplicate so every access token has to be created with duplicate
80 access rights */
82 #define TOKEN_DUP_QUERY (TOKEN_QUERY|TOKEN_DUPLICATE)
84 /*****************************************************************************/
85 /* Static Module Function Declarations */
86 /*****************************************************************************/
88 static sal_Bool GetSpecialFolder(rtl_uString **strPath,int nFolder);
89 static BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable);
90 static sal_Bool SAL_CALL getUserNameImpl(oslSecurity Security, rtl_uString **strName, sal_Bool bIncludeDomain);
92 /*****************************************************************************/
93 /* Exported Module Functions */
94 /*****************************************************************************/
96 oslSecurity SAL_CALL osl_getCurrentSecurity(void)
98 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
100 pSecImpl->m_pNetResource = NULL;
101 pSecImpl->m_User[0] = '\0';
102 pSecImpl->m_hToken = NULL;
103 pSecImpl->m_hProfile = NULL;
105 return ((oslSecurity)pSecImpl);
108 oslSecurityError SAL_CALL osl_loginUser( rtl_uString *strUserName, rtl_uString *strPasswd, oslSecurity *pSecurity )
110 oslSecurityError ret;
112 sal_Unicode* strUser;
113 sal_Unicode* strDomain = _wcsdup(rtl_uString_getStr(strUserName));
114 HANDLE hUserToken;
116 #if OSL_DEBUG_LEVEL > 0
117 LUID luid;
118 #endif
120 if (NULL != (strUser = wcschr(strDomain, L'/')))
121 *strUser++ = L'\0';
122 else
124 strUser = strDomain;
125 strDomain = NULL;
128 // this process must have the right: 'act as a part of operatingsystem'
129 OSL_ASSERT(LookupPrivilegeValue(NULL, SE_TCB_NAME, &luid));
131 if (LogonUserW(strUser, strDomain ? strDomain : L"", rtl_uString_getStr(strPasswd),
132 LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
133 &hUserToken))
135 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
137 pSecImpl->m_pNetResource = NULL;
138 pSecImpl->m_hToken = hUserToken;
139 pSecImpl->m_hProfile = NULL;
140 wcscpy(pSecImpl->m_User, strUser);
142 *pSecurity = (oslSecurity)pSecImpl;
143 ret = osl_Security_E_None;
145 else
146 ret = osl_Security_E_UserUnknown;
148 if (strDomain)
149 free(strDomain);
150 else
151 free(strUser);
153 return ret;
156 oslSecurityError SAL_CALL osl_loginUserOnFileServer(rtl_uString *strUserName,
157 rtl_uString *strPasswd,
158 rtl_uString *strFileServer,
159 oslSecurity *pSecurity)
161 oslSecurityError ret;
162 DWORD err;
163 NETRESOURCEW netResource;
164 sal_Unicode* remoteName;
165 sal_Unicode* userName;
167 remoteName = malloc((rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 4) * sizeof(sal_Unicode));
168 userName = malloc((rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 2) * sizeof(sal_Unicode));
170 wcscpy(remoteName, L"\\\\");
171 wcscat(remoteName, rtl_uString_getStr(strFileServer));
172 wcscat(remoteName, L"\\");
173 wcscat(remoteName, rtl_uString_getStr(strUserName));
175 wcscpy(userName, rtl_uString_getStr(strFileServer));
176 wcscat(userName, L"\\");
177 wcscat(userName, rtl_uString_getStr(strUserName));
179 netResource.dwScope = RESOURCE_GLOBALNET;
180 netResource.dwType = RESOURCETYPE_DISK;
181 netResource.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
182 netResource.dwUsage = RESOURCEUSAGE_CONNECTABLE;
183 netResource.lpLocalName = NULL;
184 netResource.lpRemoteName = remoteName;
185 netResource.lpComment = NULL;
186 netResource.lpProvider = NULL;
188 err = WNetAddConnection2W(&netResource, rtl_uString_getStr(strPasswd), userName, 0);
190 if ((err == NO_ERROR) || (err == ERROR_ALREADY_ASSIGNED))
192 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
194 pSecImpl->m_pNetResource = malloc(sizeof(NETRESOURCE));
195 *pSecImpl->m_pNetResource = netResource;
197 pSecImpl->m_hToken = NULL;
198 pSecImpl->m_hProfile = NULL;
199 wcscpy(pSecImpl->m_User, rtl_uString_getStr(strUserName));
201 *pSecurity = (oslSecurity)pSecImpl;
203 ret = osl_Security_E_None;
205 else
206 ret = osl_Security_E_UserUnknown;
208 free(remoteName);
209 free(userName);
211 return ret;
215 static BOOL WINAPI CheckTokenMembership_Stub( HANDLE TokenHandle, PSID SidToCheck, PBOOL IsMember )
217 typedef BOOL (WINAPI *CheckTokenMembership_PROC)( HANDLE, PSID, PBOOL );
219 static HMODULE hModule = NULL;
220 static CheckTokenMembership_PROC pCheckTokenMembership = NULL;
222 if ( !hModule )
224 /* SAL is always linked against ADVAPI32 so we can rely on that it is already mapped */
226 hModule = GetModuleHandleA( "ADVAPI32.DLL" );
228 pCheckTokenMembership = (CheckTokenMembership_PROC)GetProcAddress( hModule, "CheckTokenMembership" );
231 if ( pCheckTokenMembership )
232 return pCheckTokenMembership( TokenHandle, SidToCheck, IsMember );
233 else
235 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
236 return FALSE;
242 sal_Bool SAL_CALL osl_isAdministrator(oslSecurity Security)
244 if (Security != NULL)
246 HANDLE hImpersonationToken = NULL;
247 PSID psidAdministrators;
248 SID_IDENTIFIER_AUTHORITY siaNtAuthority = { SECURITY_NT_AUTHORITY };
249 sal_Bool bSuccess = sal_False;
252 /* If Security contains an access token we need to duplicate it to an impersonation
253 access token. NULL works with CheckTokenMembership() as the current effective
254 impersonation token
257 if ( ((oslSecurityImpl*)Security)->m_hToken )
259 if ( !DuplicateToken (((oslSecurityImpl*)Security)->m_hToken, SecurityImpersonation, &hImpersonationToken) )
260 return sal_False;
263 /* CheckTokenMembership() can be used on W2K and higher (NT4 no longer supported by OOo)
264 and also works on Vista to retrieve the effective user rights. Just checking for
265 membership of Administrators group is not enough on Vista this would require additional
266 complicated checks as described in KB arcticle Q118626: http://support.microsoft.com/kb/118626/en-us
269 if (AllocateAndInitializeSid(&siaNtAuthority,
271 SECURITY_BUILTIN_DOMAIN_RID,
272 DOMAIN_ALIAS_RID_ADMINS,
273 0, 0, 0, 0, 0, 0,
274 &psidAdministrators))
276 BOOL fSuccess = FALSE;
278 if ( CheckTokenMembership_Stub( hImpersonationToken, psidAdministrators, &fSuccess ) && fSuccess )
279 bSuccess = sal_True;
281 FreeSid(psidAdministrators);
284 if ( hImpersonationToken )
285 CloseHandle( hImpersonationToken );
287 return (bSuccess);
289 else
290 return (sal_False);
294 void SAL_CALL osl_freeSecurityHandle(oslSecurity Security)
296 if (Security)
298 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
300 if (pSecImpl->m_pNetResource != NULL)
302 WNetCancelConnection2W(pSecImpl->m_pNetResource->lpRemoteName, 0, sal_True);
304 free(pSecImpl->m_pNetResource->lpRemoteName);
305 free(pSecImpl->m_pNetResource);
308 if (pSecImpl->m_hToken)
309 CloseHandle(pSecImpl->m_hToken);
311 if ( pSecImpl->m_hProfile )
312 CloseHandle(pSecImpl->m_hProfile);
314 free (pSecImpl);
319 sal_Bool SAL_CALL osl_getUserIdent(oslSecurity Security, rtl_uString **strIdent)
321 if (Security != NULL)
323 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
325 HANDLE hAccessToken = pSecImpl->m_hToken;
327 if (hAccessToken == NULL)
328 OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);
330 if (hAccessToken)
332 sal_Char *Ident;
333 DWORD nInfoBuffer = 512;
334 UCHAR* pInfoBuffer = malloc(nInfoBuffer);
337 while (!GetTokenInformation(hAccessToken, TokenUser,
338 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
340 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
342 UCHAR* pTmp = realloc(pInfoBuffer, nInfoBuffer);
343 if (pTmp)
344 pInfoBuffer = pTmp;
345 else
347 free(pInfoBuffer);
348 pInfoBuffer = NULL;
349 break;
352 else
354 free(pInfoBuffer);
355 pInfoBuffer = NULL;
356 break;
360 if (pSecImpl->m_hToken == NULL)
361 CloseHandle(hAccessToken);
363 if (pInfoBuffer)
365 PSID pSid = ((PTOKEN_USER)pInfoBuffer)->User.Sid;
366 PSID_IDENTIFIER_AUTHORITY psia;
367 DWORD dwSubAuthorities;
368 DWORD dwSidRev=SID_REVISION;
369 DWORD dwCounter;
370 DWORD dwSidSize;
371 PUCHAR pSSACount;
373 /* obtain SidIdentifierAuthority */
374 psia=GetSidIdentifierAuthority(pSid);
376 /* obtain sidsubauthority count */
377 pSSACount = GetSidSubAuthorityCount(pSid);
378 dwSubAuthorities = (*pSSACount < 5) ? *pSSACount : 5;
380 /* buffer length: S-SID_REVISION- + identifierauthority- + subauthorities- + NULL */
381 Ident=malloc(88*sizeof(sal_Char));
383 /* prepare S-SID_REVISION- */
384 dwSidSize=wsprintf(Ident, TEXT("S-%lu-"), dwSidRev);
386 /* prepare SidIdentifierAuthority */
387 if ((psia->Value[0] != 0) || (psia->Value[1] != 0))
389 dwSidSize+=wsprintf(Ident + strlen(Ident),
390 TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
391 (USHORT)psia->Value[0],
392 (USHORT)psia->Value[1],
393 (USHORT)psia->Value[2],
394 (USHORT)psia->Value[3],
395 (USHORT)psia->Value[4],
396 (USHORT)psia->Value[5]);
398 else
400 dwSidSize+=wsprintf(Ident + strlen(Ident),
401 TEXT("%lu"),
402 (ULONG)(psia->Value[5] ) +
403 (ULONG)(psia->Value[4] << 8) +
404 (ULONG)(psia->Value[3] << 16) +
405 (ULONG)(psia->Value[2] << 24) );
408 /* loop through SidSubAuthorities */
409 for (dwCounter=0; dwCounter < dwSubAuthorities; dwCounter++)
411 dwSidSize+=wsprintf(Ident + dwSidSize, TEXT("-%lu"),
412 *GetSidSubAuthority(pSid, dwCounter) );
415 rtl_uString_newFromAscii( strIdent, Ident );
417 free(pInfoBuffer);
418 free(Ident);
420 return (sal_True);
423 else
425 DWORD needed=0;
426 sal_Unicode *Ident;
428 WNetGetUserA(NULL, NULL, &needed);
429 if (needed < 16)
431 needed = 16;
433 Ident=malloc(needed*sizeof(sal_Unicode));
435 if (WNetGetUserW(NULL, Ident, &needed) != NO_ERROR)
437 wcscpy(Ident, L"unknown");
438 Ident[7] = L'\0';
441 rtl_uString_newFromStr( strIdent, Ident);
443 free(Ident);
445 return sal_True;
449 return sal_False;
454 sal_Bool SAL_CALL osl_getUserName(oslSecurity Security, rtl_uString **strName)
456 return getUserNameImpl(Security, strName, sal_True);
460 sal_Bool SAL_CALL osl_getHomeDir(oslSecurity Security, rtl_uString **pustrDirectory)
462 rtl_uString *ustrSysDir = NULL;
463 sal_Bool bSuccess = sal_False;
465 if (Security != NULL)
467 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
469 if (pSecImpl->m_pNetResource != NULL)
471 rtl_uString_newFromStr( &ustrSysDir, pSecImpl->m_pNetResource->lpRemoteName);
473 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath( ustrSysDir, pustrDirectory ));
475 else
477 #if 0
478 if (pSecImpl->m_hToken)
480 DWORD nInfoBuffer = 512;
481 UCHAR* pInfoBuffer = malloc(nInfoBuffer);
483 while (!GetTokenInformation(pSecImpl->m_hToken, TokenUser,
484 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
486 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
487 pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer);
488 else
490 free(pInfoBuffer);
491 pInfoBuffer = NULL;
492 break;
496 /* not implemented */
497 OSL_ASSERT(sal_False);
499 if (pInfoBuffer)
501 /* if (EqualSid() ... */
505 else
506 #endif
508 bSuccess = (sal_Bool)(GetSpecialFolder(&ustrSysDir, CSIDL_PERSONAL) &&
509 (osl_File_E_None == osl_getFileURLFromSystemPath(ustrSysDir, pustrDirectory)));
513 if ( ustrSysDir )
514 rtl_uString_release( ustrSysDir );
516 return bSuccess;
519 sal_Bool SAL_CALL osl_getConfigDir(oslSecurity Security, rtl_uString **pustrDirectory)
521 sal_Bool bSuccess = sal_False;
523 if (Security != NULL)
525 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
527 if (pSecImpl->m_pNetResource != NULL)
529 rtl_uString *ustrSysDir = NULL;
531 rtl_uString_newFromStr( &ustrSysDir, pSecImpl->m_pNetResource->lpRemoteName);
532 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath( ustrSysDir, pustrDirectory));
534 if ( ustrSysDir )
535 rtl_uString_release( ustrSysDir );
537 else
539 if (pSecImpl->m_hToken)
541 /* not implemented */
542 OSL_ASSERT(sal_False);
544 else
546 rtl_uString *ustrFile = NULL;
547 sal_Unicode sFile[_MAX_PATH];
549 if ( !GetSpecialFolder( &ustrFile, CSIDL_APPDATA) )
551 OSL_VERIFY(GetWindowsDirectoryW(sFile, _MAX_DIR) > 0);
553 rtl_uString_newFromStr( &ustrFile, sFile);
556 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath(ustrFile, pustrDirectory));
558 if ( ustrFile )
559 rtl_uString_release( ustrFile );
564 return bSuccess;
568 sal_Bool SAL_CALL osl_loadUserProfile(oslSecurity Security)
570 /* CreateProcessAsUser does not load the specified user's profile
571 into the HKEY_USERS registry key. This means that access to information
572 in the HKEY_CURRENT_USER registry key may not produce results consistent
573 with a normal interactive logon.
574 It is your responsibility to load the user's registry hive into HKEY_USERS
575 with the LoadUserProfile function before calling CreateProcessAsUser.
577 BOOL bOk = FALSE;
579 RegCloseKey(HKEY_CURRENT_USER);
581 if (Privilege(SE_RESTORE_NAME, TRUE))
583 HMODULE hUserEnvLib = NULL;
584 LPFNLOADUSERPROFILE fLoadUserProfile = NULL;
585 LPFNUNLOADUSERPROFILE fUnloadUserProfile = NULL;
586 HANDLE hAccessToken = ((oslSecurityImpl*)Security)->m_hToken;
588 /* try to create user profile */
589 if ( !hAccessToken )
591 /* retrieve security handle if not done before e.g. osl_getCurrentSecurity()
593 HANDLE hProcess = GetCurrentProcess();
595 if (hProcess != NULL)
597 OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken);
598 CloseHandle(hProcess);
602 hUserEnvLib = LoadLibraryA("userenv.dll");
604 if (hUserEnvLib)
606 fLoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "LoadUserProfileW");
607 fUnloadUserProfile = (LPFNUNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "UnloadUserProfile");
609 if (fLoadUserProfile && fUnloadUserProfile)
611 rtl_uString *buffer = 0;
612 PROFILEINFOW pi;
614 getUserNameImpl(Security, &buffer, sal_False);
616 ZeroMemory( &pi, sizeof(pi) );
617 pi.dwSize = sizeof(pi);
618 pi.lpUserName = rtl_uString_getStr(buffer);
619 pi.dwFlags = PI_NOUI;
621 if (fLoadUserProfile(hAccessToken, &pi))
623 fUnloadUserProfile(hAccessToken, pi.hProfile);
625 bOk = TRUE;
628 rtl_uString_release(buffer);
631 FreeLibrary(hUserEnvLib);
634 if (hAccessToken && (hAccessToken != ((oslSecurityImpl*)Security)->m_hToken))
635 CloseHandle(hAccessToken);
638 return (sal_Bool)bOk;
642 void SAL_CALL osl_unloadUserProfile(oslSecurity Security)
644 if ( ((oslSecurityImpl*)Security)->m_hProfile != NULL )
646 HMODULE hUserEnvLib = NULL;
647 LPFNLOADUSERPROFILE fLoadUserProfile = NULL;
648 LPFNUNLOADUSERPROFILE fUnloadUserProfile = NULL;
649 HANDLE hAccessToken = ((oslSecurityImpl*)Security)->m_hToken;
651 if ( !hAccessToken )
653 /* retrieve security handle if not done before e.g. osl_getCurrentSecurity()
655 HANDLE hProcess = GetCurrentProcess();
657 if (hProcess != NULL)
659 OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken);
660 CloseHandle(hProcess);
664 hUserEnvLib = LoadLibrary("userenv.dll");
666 if (hUserEnvLib)
668 fLoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "LoadUserProfileA");
669 fUnloadUserProfile = (LPFNUNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "UnloadUserProfile");
671 if (fLoadUserProfile && fUnloadUserProfile)
673 /* unloading the user profile */
674 if (fLoadUserProfile && fUnloadUserProfile)
675 fUnloadUserProfile(hAccessToken, ((oslSecurityImpl*)Security)->m_hProfile);
677 if (hUserEnvLib)
678 FreeLibrary(hUserEnvLib);
682 ((oslSecurityImpl*)Security)->m_hProfile = NULL;
684 if (hAccessToken && (hAccessToken != ((oslSecurityImpl*)Security)->m_hToken))
686 CloseHandle(hAccessToken);
691 /*****************************************************************************/
692 /* Static Module Functions */
693 /*****************************************************************************/
696 static sal_Bool GetSpecialFolder(rtl_uString **strPath, int nFolder)
698 sal_Bool bRet = sal_False;
699 HINSTANCE hLibrary;
700 sal_Char PathA[_MAX_PATH];
701 sal_Unicode PathW[_MAX_PATH];
703 if ((hLibrary = LoadLibrary("shell32.dll")) != NULL)
705 BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL);
706 BOOL (WINAPI *pSHGetSpecialFolderPathW)(HWND, LPWSTR, int, BOOL);
708 pSHGetSpecialFolderPathA = (BOOL (WINAPI *)(HWND, LPSTR, int, BOOL))GetProcAddress(hLibrary, "SHGetSpecialFolderPathA");
709 pSHGetSpecialFolderPathW = (BOOL (WINAPI *)(HWND, LPWSTR, int, BOOL))GetProcAddress(hLibrary, "SHGetSpecialFolderPathW");
711 if (pSHGetSpecialFolderPathA)
713 if (pSHGetSpecialFolderPathA(GetActiveWindow(), PathA, nFolder, TRUE))
715 rtl_string2UString( strPath, PathA, strlen(PathA), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS);
716 OSL_ASSERT(*strPath != NULL);
717 bRet = sal_True;
720 else if (pSHGetSpecialFolderPathW)
722 if (pSHGetSpecialFolderPathW(GetActiveWindow(), PathW, nFolder, TRUE))
724 rtl_uString_newFromStr( strPath, PathW);
725 bRet = sal_True;
728 else
730 HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *) = (HRESULT (WINAPI *)(HWND, int, LPITEMIDLIST *))GetProcAddress(hLibrary, "SHGetSpecialFolderLocation");
731 BOOL (WINAPI *pSHGetPathFromIDListA)(LPCITEMIDLIST, LPSTR) = (BOOL (WINAPI *)(LPCITEMIDLIST, LPSTR))GetProcAddress(hLibrary, "SHGetPathFromIDListA");
732 BOOL (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR) = (BOOL (WINAPI *)(LPCITEMIDLIST, LPWSTR))GetProcAddress(hLibrary, "SHGetPathFromIDListW");
733 HRESULT (WINAPI *pSHGetMalloc)(LPMALLOC *) = (HRESULT (WINAPI *)(LPMALLOC *))GetProcAddress(hLibrary, "SHGetMalloc");
736 if (pSHGetSpecialFolderLocation && (pSHGetPathFromIDListA || pSHGetPathFromIDListW ) && pSHGetMalloc )
738 LPITEMIDLIST pidl;
739 LPMALLOC pMalloc;
740 HRESULT hr;
742 hr = pSHGetSpecialFolderLocation(GetActiveWindow(), nFolder, &pidl);
744 /* Get SHGetSpecialFolderLocation fails if directory does not exists. */
745 /* If it fails we try to create the directory and redo the call */
746 if (! SUCCEEDED(hr))
748 HKEY hRegKey;
750 if (RegOpenKey(HKEY_CURRENT_USER,
751 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
752 &hRegKey) == ERROR_SUCCESS)
754 LONG lRet;
755 DWORD lSize = SAL_N_ELEMENTS(PathA);
756 DWORD Type = REG_SZ;
758 switch (nFolder)
760 case CSIDL_APPDATA:
761 lRet = RegQueryValueEx(hRegKey, "AppData", NULL, &Type, (LPBYTE)PathA, &lSize);
762 break;
764 case CSIDL_PERSONAL:
765 lRet = RegQueryValueEx(hRegKey, "Personal", NULL, &Type, (LPBYTE)PathA, &lSize);
766 break;
768 default:
769 lRet = -1l;
772 if ((lRet == ERROR_SUCCESS) && (Type == REG_SZ))
774 if (_access(PathA, 0) < 0)
775 CreateDirectory(PathA, NULL);
777 hr = pSHGetSpecialFolderLocation(GetActiveWindow(), nFolder, &pidl);
780 RegCloseKey(hRegKey);
784 if (SUCCEEDED(hr))
786 if (pSHGetPathFromIDListW && pSHGetPathFromIDListW(pidl, PathW))
788 /* if directory does not exist, create it */
789 if (_waccess(PathW, 0) < 0)
790 CreateDirectoryW(PathW, NULL);
792 rtl_uString_newFromStr( strPath, PathW);
793 bRet = sal_True;
795 else if (pSHGetPathFromIDListA && pSHGetPathFromIDListA(pidl, PathA))
797 /* if directory does not exist, create it */
798 if (_access(PathA, 0) < 0)
799 CreateDirectoryA(PathA, NULL);
801 rtl_string2UString( strPath, PathA, strlen(PathA), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS);
802 OSL_ASSERT(*strPath != NULL);
803 bRet = sal_True;
807 if (SUCCEEDED(pSHGetMalloc(&pMalloc)))
809 pMalloc->lpVtbl->Free(pMalloc, pidl);
810 pMalloc->lpVtbl->Release(pMalloc);
816 FreeLibrary(hLibrary);
818 return (bRet);
822 static BOOL Privilege(LPTSTR strPrivilege, BOOL bEnable)
824 HANDLE hToken;
825 TOKEN_PRIVILEGES tp;
828 obtain the processes token
830 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_DUP_QUERY, &hToken))
831 return FALSE;
834 get the luid
836 if (!LookupPrivilegeValue(NULL, strPrivilege, &tp.Privileges[0].Luid))
837 return FALSE;
839 tp.PrivilegeCount = 1;
841 if (bEnable)
842 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
843 else
844 tp.Privileges[0].Attributes = 0;
847 enable or disable the privilege
849 if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0))
850 return FALSE;
852 if (!CloseHandle(hToken))
853 return FALSE;
855 return TRUE;
858 static sal_Bool SAL_CALL getUserNameImpl(oslSecurity Security, rtl_uString **strName, sal_Bool bIncludeDomain)
860 if (Security != NULL)
862 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
864 HANDLE hAccessToken = pSecImpl->m_hToken;
866 if (hAccessToken == NULL)
867 OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);
869 if (hAccessToken)
871 DWORD nInfoBuffer = 512;
872 UCHAR* pInfoBuffer = malloc(nInfoBuffer);
874 while (!GetTokenInformation(hAccessToken, TokenUser,
875 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
877 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
879 UCHAR* pTmp = realloc(pInfoBuffer, nInfoBuffer);
880 if (pTmp)
881 pInfoBuffer = pTmp;
882 else
884 free(pInfoBuffer);
885 pInfoBuffer = NULL;
886 break;
889 else
891 free(pInfoBuffer);
892 pInfoBuffer = NULL;
893 break;
897 if (pSecImpl->m_hToken == NULL)
898 CloseHandle(hAccessToken);
900 if (pInfoBuffer)
902 sal_Unicode UserName[128];
903 sal_Unicode DomainName[128];
904 sal_Unicode Name[257];
905 DWORD nUserName = sizeof(UserName);
906 DWORD nDomainName = sizeof(DomainName);
907 SID_NAME_USE sUse;
909 if (LookupAccountSidW(NULL, ((PTOKEN_USER)pInfoBuffer)->User.Sid,
910 UserName, &nUserName,
911 DomainName, &nDomainName, &sUse))
913 if (bIncludeDomain)
915 wcscpy(Name, DomainName);
916 wcscat(Name, L"/");
917 wcscat(Name, UserName);
919 else
921 wcscpy(Name, UserName);
924 rtl_uString_newFromStr( strName, Name);
926 free(pInfoBuffer);
928 return (sal_True);
931 else
933 DWORD needed=0;
934 sal_Unicode *pNameW=NULL;
936 WNetGetUserW(NULL, NULL, &needed);
937 pNameW = malloc (needed*sizeof(sal_Unicode));
939 if (WNetGetUserW(NULL, pNameW, &needed) == NO_ERROR)
941 rtl_uString_newFromStr( strName, pNameW);
943 if (pNameW)
944 free(pNameW);
945 return (sal_True);
947 else
948 if (wcslen(pSecImpl->m_User) > 0)
950 rtl_uString_newFromStr( strName, pSecImpl->m_pNetResource->lpRemoteName);
952 if (pNameW)
953 free(pNameW);
955 return (sal_True);
958 if (pNameW)
959 free(pNameW);
963 return sal_False;
966 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */