1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24
25 #include "system.h"
26
27 #include <osl/security.h>
28 #include <osl/diagnose.h>
29 #include <osl/thread.h>
30 #include <osl/file.h>
31 #include <systools/win32/uwinapi.h>
32 #include "secimpl.h"
33
34 /*****************************************************************************/
35 /* Data Type Definition */
36 /*****************************************************************************/
37
38
39 /* Data for use in (un)LoadProfile Functions */
40 /* Declarations based on USERENV.H for Windows 2000 Beta 2 */
41 #define PI_NOUI 0x00000001 // Prevents displaying of messages
42 #define PI_APPLYPOLICY 0x00000002 // Apply NT4 style policy
43
44 typedef struct _PROFILEINFOW {
45 DWORD dwSize; // Must be set to sizeof(PROFILEINFO)
46 DWORD dwFlags; // See flags above
47 LPWSTR lpUserName; // User name (required)
48 LPWSTR lpProfilePath; // Roaming profile path
49 LPWSTR lpDefaultPath; // Default user profile path
50 LPWSTR lpServerName; // Validating DC name in netbios format
51 LPWSTR lpPolicyPath; // Path to the NT4 style policy file
52 HANDLE hProfile; // Registry key handle - filled by function
53 } PROFILEINFOW, FAR * LPPROFILEINFOW;
54
55 /* Typedefs for function pointers in USERENV.DLL */
56 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNLOADUSERPROFILE) (
57 HANDLE hToken,
58 LPPROFILEINFOW lpProfileInfo
59 );
60
61 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNUNLOADUSERPROFILE) (
62 HANDLE hToken,
63 HANDLE hProfile
64 );
65
66 typedef BOOL (STDMETHODCALLTYPE FAR * LPFNGETUSERPROFILEDIR) (
67 HANDLE hToken,
68 LPTSTR lpProfileDir,
69 LPDWORD lpcchSize
70 );
71
72 /* To get an impersonation token we need to create an impersonation
73 duplicate so every access token has to be created with duplicate
74 access rights */
75
76 #define TOKEN_DUP_QUERY (TOKEN_QUERY|TOKEN_DUPLICATE)
77
78 /*****************************************************************************/
79 /* Static Module Function Declarations */
80 /*****************************************************************************/
81
82 static sal_Bool isWNT(void);
83 static sal_Bool GetSpecialFolder(rtl_uString **strPath,int nFolder);
84 static BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable);
85 static sal_Bool SAL_CALL getUserNameImpl(oslSecurity Security, rtl_uString **strName, sal_Bool bIncludeDomain);
86
87 /*****************************************************************************/
88 /* Exported Module Functions */
89 /*****************************************************************************/
90
osl_getCurrentSecurity(void)91 oslSecurity SAL_CALL osl_getCurrentSecurity(void)
92 {
93 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
94
95 pSecImpl->m_pNetResource = NULL;
96 pSecImpl->m_User[0] = '\0';
97 pSecImpl->m_hToken = NULL;
98 pSecImpl->m_hProfile = NULL;
99
100 return ((oslSecurity)pSecImpl);
101 }
102
osl_loginUser(rtl_uString * strUserName,rtl_uString * strPasswd,oslSecurity * pSecurity)103 oslSecurityError SAL_CALL osl_loginUser( rtl_uString *strUserName, rtl_uString *strPasswd, oslSecurity *pSecurity )
104 {
105 oslSecurityError ret;
106
107 if (!isWNT())
108 {
109 *pSecurity = osl_getCurrentSecurity();
110 ret = osl_Security_E_None;
111 }
112 else
113 {
114 sal_Unicode* strUser;
115 sal_Unicode* strDomain = _wcsdup(rtl_uString_getStr(strUserName));
116 HANDLE hUserToken;
117
118 #if OSL_DEBUG_LEVEL > 0
119 LUID luid;
120 #endif
121
122 if (NULL != (strUser = wcschr(strDomain, L'/')))
123 *strUser++ = L'\0';
124 else
125 {
126 strUser = strDomain;
127 strDomain = NULL;
128 }
129
130 // this process must have the right: 'act as a part of operatingsystem'
131 OSL_ASSERT(LookupPrivilegeValue(NULL, SE_TCB_NAME, &luid));
132
133 if (LogonUserW(strUser, strDomain ? strDomain : L"", rtl_uString_getStr(strPasswd),
134 LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
135 &hUserToken))
136 {
137 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
138
139 pSecImpl->m_pNetResource = NULL;
140 pSecImpl->m_hToken = hUserToken;
141 pSecImpl->m_hProfile = NULL;
142 wcscpy(pSecImpl->m_User, strUser);
143
144 *pSecurity = (oslSecurity)pSecImpl;
145 ret = osl_Security_E_None;
146 }
147 else
148 ret = osl_Security_E_UserUnknown;
149
150 if (strDomain)
151 free(strDomain);
152 else
153 free(strUser);
154 }
155
156 return ret;
157 }
158
osl_loginUserOnFileServer(rtl_uString * strUserName,rtl_uString * strPasswd,rtl_uString * strFileServer,oslSecurity * pSecurity)159 oslSecurityError SAL_CALL osl_loginUserOnFileServer(rtl_uString *strUserName,
160 rtl_uString *strPasswd,
161 rtl_uString *strFileServer,
162 oslSecurity *pSecurity)
163 {
164 oslSecurityError ret;
165 DWORD err;
166 NETRESOURCEW netResource;
167 sal_Unicode* remoteName;
168 sal_Unicode* userName;
169
170 remoteName = malloc(rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 4);
171 userName = malloc(rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 2);
172
173 wcscpy(remoteName, L"\\\\");
174 wcscat(remoteName, rtl_uString_getStr(strFileServer));
175 wcscat(remoteName, L"\\");
176 wcscat(remoteName, rtl_uString_getStr(strUserName));
177
178 wcscpy(userName, rtl_uString_getStr(strFileServer));
179 wcscat(userName, L"\\");
180 wcscat(userName, rtl_uString_getStr(strUserName));
181
182 netResource.dwScope = RESOURCE_GLOBALNET;
183 netResource.dwType = RESOURCETYPE_DISK;
184 netResource.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
185 netResource.dwUsage = RESOURCEUSAGE_CONNECTABLE;
186 netResource.lpLocalName = NULL;
187 netResource.lpRemoteName = remoteName;
188 netResource.lpComment = NULL;
189 netResource.lpProvider = NULL;
190
191 err = WNetAddConnection2W(&netResource, rtl_uString_getStr(strPasswd), userName, 0);
192
193 if ((err == NO_ERROR) || (err == ERROR_ALREADY_ASSIGNED))
194 {
195 oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl));
196
197 pSecImpl->m_pNetResource = malloc(sizeof(NETRESOURCE));
198 *pSecImpl->m_pNetResource = netResource;
199
200 pSecImpl->m_hToken = NULL;
201 pSecImpl->m_hProfile = NULL;
202 wcscpy(pSecImpl->m_User, rtl_uString_getStr(strUserName));
203
204 *pSecurity = (oslSecurity)pSecImpl;
205
206 ret = osl_Security_E_None;
207 }
208 else
209 ret = osl_Security_E_UserUnknown;
210
211 free(remoteName);
212 free(userName);
213
214 return ret;
215 }
216
217
CheckTokenMembership_Stub(HANDLE TokenHandle,PSID SidToCheck,PBOOL IsMember)218 static BOOL WINAPI CheckTokenMembership_Stub( HANDLE TokenHandle, PSID SidToCheck, PBOOL IsMember )
219 {
220 typedef BOOL (WINAPI *CheckTokenMembership_PROC)( HANDLE, PSID, PBOOL );
221
222 static HMODULE hModule = NULL;
223 static CheckTokenMembership_PROC pCheckTokenMembership = NULL;
224
225 if ( !hModule )
226 {
227 /* SAL is always linked against ADVAPI32 so we can rely on that it is already mapped */
228
229 hModule = GetModuleHandleA( "ADVAPI32.DLL" );
230
231 pCheckTokenMembership = (CheckTokenMembership_PROC)GetProcAddress( hModule, "CheckTokenMembership" );
232 }
233
234 if ( pCheckTokenMembership )
235 return pCheckTokenMembership( TokenHandle, SidToCheck, IsMember );
236 else
237 {
238 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
239 return FALSE;
240 }
241
242 }
243
244
osl_isAdministrator(oslSecurity Security)245 sal_Bool SAL_CALL osl_isAdministrator(oslSecurity Security)
246 {
247 if (Security != NULL)
248 {
249 /* ts: on Window 95 systems any user seems to be an adminstrator */
250 if (!isWNT())
251 {
252 return(sal_True);
253 }
254 else
255 {
256 HANDLE hImpersonationToken = NULL;
257 PSID psidAdministrators;
258 SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
259 sal_Bool bSuccess = sal_False;
260
261
262 /* If Security contains an access token we need to duplicate it to an impersonation
263 access token. NULL works with CheckTokenMembership() as the current effective
264 impersonation token
265 */
266
267 if ( ((oslSecurityImpl*)Security)->m_hToken )
268 {
269 if ( !DuplicateToken (((oslSecurityImpl*)Security)->m_hToken, SecurityImpersonation, &hImpersonationToken) )
270 return sal_False;
271 }
272
273 /* CheckTokenMembership() can be used on W2K and higher (NT4 no longer supported by OOo)
274 and also works on Vista to retrieve the effective user rights. Just checking for
275 membership of Administrators group is not enough on Vista this would require additional
276 complicated checks as described in KB arcticle Q118626: http://support.microsoft.com/kb/118626/en-us
277 */
278
279 if (AllocateAndInitializeSid(&siaNtAuthority,
280 2,
281 SECURITY_BUILTIN_DOMAIN_RID,
282 DOMAIN_ALIAS_RID_ADMINS,
283 0, 0, 0, 0, 0, 0,
284 &psidAdministrators))
285 {
286 BOOL fSuccess = FALSE;
287
288 if ( CheckTokenMembership_Stub( hImpersonationToken, psidAdministrators, &fSuccess ) && fSuccess )
289 bSuccess = sal_True;
290
291 FreeSid(psidAdministrators);
292 }
293
294 if ( hImpersonationToken )
295 CloseHandle( hImpersonationToken );
296
297 return (bSuccess);
298 }
299 }
300 else
301 return (sal_False);
302 }
303
304
osl_freeSecurityHandle(oslSecurity Security)305 void SAL_CALL osl_freeSecurityHandle(oslSecurity Security)
306 {
307 if (Security)
308 {
309 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
310
311 if (pSecImpl->m_pNetResource != NULL)
312 {
313 WNetCancelConnection2W(pSecImpl->m_pNetResource->lpRemoteName, 0, sal_True);
314
315 free(pSecImpl->m_pNetResource->lpRemoteName);
316 free(pSecImpl->m_pNetResource);
317 }
318
319 if (pSecImpl->m_hToken)
320 CloseHandle(pSecImpl->m_hToken);
321
322 if ( pSecImpl->m_hProfile )
323 CloseHandle(pSecImpl->m_hProfile);
324
325 free (pSecImpl);
326 }
327 }
328
329
osl_getUserIdent(oslSecurity Security,rtl_uString ** strIdent)330 sal_Bool SAL_CALL osl_getUserIdent(oslSecurity Security, rtl_uString **strIdent)
331 {
332 if (Security != NULL)
333 {
334 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
335
336 HANDLE hAccessToken = pSecImpl->m_hToken;
337
338 if (hAccessToken == NULL)
339 OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);
340
341 if (hAccessToken)
342 {
343 sal_Char *Ident;
344 DWORD nInfoBuffer = 512;
345 UCHAR* pInfoBuffer = malloc(nInfoBuffer);
346
347
348 while (!GetTokenInformation(hAccessToken, TokenUser,
349 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
350 {
351 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
352 pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer);
353 else
354 {
355 free(pInfoBuffer);
356 pInfoBuffer = NULL;
357 break;
358 }
359 }
360
361 if (pSecImpl->m_hToken == NULL)
362 CloseHandle(hAccessToken);
363
364 if (pInfoBuffer)
365 {
366 PSID pSid = ((PTOKEN_USER)pInfoBuffer)->User.Sid;
367 PSID_IDENTIFIER_AUTHORITY psia;
368 DWORD dwSubAuthorities;
369 DWORD dwSidRev=SID_REVISION;
370 DWORD dwCounter;
371 DWORD dwSidSize;
372
373 /* obtain SidIdentifierAuthority */
374 psia=GetSidIdentifierAuthority(pSid);
375
376 /* obtain sidsubauthority count */
377 dwSubAuthorities=min(*GetSidSubAuthorityCount(pSid), 5);
378
379 /* buffer length: S-SID_REVISION- + identifierauthority- + subauthorities- + NULL */
380 Ident=malloc(88*sizeof(sal_Char));
381
382 /* prepare S-SID_REVISION- */
383 dwSidSize=wsprintf(Ident, TEXT("S-%lu-"), dwSidRev);
384
385 /* prepare SidIdentifierAuthority */
386 if ((psia->Value[0] != 0) || (psia->Value[1] != 0))
387 {
388 dwSidSize+=wsprintf(Ident + strlen(Ident),
389 TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
390 (USHORT)psia->Value[0],
391 (USHORT)psia->Value[1],
392 (USHORT)psia->Value[2],
393 (USHORT)psia->Value[3],
394 (USHORT)psia->Value[4],
395 (USHORT)psia->Value[5]);
396 }
397 else
398 {
399 dwSidSize+=wsprintf(Ident + strlen(Ident),
400 TEXT("%lu"),
401 (ULONG)(psia->Value[5] ) +
402 (ULONG)(psia->Value[4] << 8) +
403 (ULONG)(psia->Value[3] << 16) +
404 (ULONG)(psia->Value[2] << 24) );
405 }
406
407 /* loop through SidSubAuthorities */
408 for (dwCounter=0; dwCounter < dwSubAuthorities; dwCounter++)
409 {
410 dwSidSize+=wsprintf(Ident + dwSidSize, TEXT("-%lu"),
411 *GetSidSubAuthority(pSid, dwCounter) );
412 }
413
414 rtl_uString_newFromAscii( strIdent, Ident );
415
416 free(pInfoBuffer);
417 free(Ident);
418
419 return (sal_True);
420 }
421 }
422 else
423 {
424 DWORD needed=0;
425 sal_Unicode *Ident;
426
427 WNetGetUserA(NULL, NULL, &needed);
428 needed = max( 16 , needed );
429 Ident=malloc(needed*sizeof(sal_Unicode));
430
431 if (WNetGetUserW(NULL, Ident, &needed) != NO_ERROR)
432 {
433 wcscpy(Ident, L"unknown");
434 Ident[7] = L'\0';
435 }
436
437 rtl_uString_newFromStr( strIdent, Ident);
438
439 free(Ident);
440
441 return sal_True;
442 }
443 }
444
445 return sal_False;
446 }
447
448
449
osl_getUserName(oslSecurity Security,rtl_uString ** strName)450 sal_Bool SAL_CALL osl_getUserName(oslSecurity Security, rtl_uString **strName)
451 {
452 return getUserNameImpl(Security, strName, sal_True);
453 }
454
455
osl_getHomeDir(oslSecurity Security,rtl_uString ** pustrDirectory)456 sal_Bool SAL_CALL osl_getHomeDir(oslSecurity Security, rtl_uString **pustrDirectory)
457 {
458 rtl_uString *ustrSysDir = NULL;
459 sal_Bool bSuccess = sal_False;
460
461 if (Security != NULL)
462 {
463 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
464
465 if (pSecImpl->m_pNetResource != NULL)
466 {
467 rtl_uString_newFromStr( &ustrSysDir, pSecImpl->m_pNetResource->lpRemoteName);
468
469 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath( ustrSysDir, pustrDirectory ));
470 }
471 else
472 {
473 #if 0
474 if (pSecImpl->m_hToken)
475 {
476 DWORD nInfoBuffer = 512;
477 UCHAR* pInfoBuffer = malloc(nInfoBuffer);
478
479 while (!GetTokenInformation(pSecImpl->m_hToken, TokenUser,
480 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
481 {
482 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
483 pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer);
484 else
485 {
486 free(pInfoBuffer);
487 pInfoBuffer = NULL;
488 break;
489 }
490 }
491
492 /* not implemented */
493 OSL_ASSERT(sal_False);
494
495 if (pInfoBuffer)
496 {
497 /* if (EqualSid() ... */
498
499 }
500 }
501 else
502 #endif
503
504 bSuccess = (sal_Bool)(GetSpecialFolder(&ustrSysDir, CSIDL_PERSONAL) &&
505 (osl_File_E_None == osl_getFileURLFromSystemPath(ustrSysDir, pustrDirectory)));
506 }
507 }
508
509 if ( ustrSysDir )
510 rtl_uString_release( ustrSysDir );
511
512 return bSuccess;
513 }
514
osl_getConfigDir(oslSecurity Security,rtl_uString ** pustrDirectory)515 sal_Bool SAL_CALL osl_getConfigDir(oslSecurity Security, rtl_uString **pustrDirectory)
516 {
517 sal_Bool bSuccess = sal_False;
518
519 if (Security != NULL)
520 {
521 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
522
523 if (pSecImpl->m_pNetResource != NULL)
524 {
525 rtl_uString *ustrSysDir = NULL;
526
527 rtl_uString_newFromStr( &ustrSysDir, pSecImpl->m_pNetResource->lpRemoteName);
528 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath( ustrSysDir, pustrDirectory));
529
530 if ( ustrSysDir )
531 rtl_uString_release( ustrSysDir );
532 }
533 else
534 {
535 if (pSecImpl->m_hToken)
536 {
537 /* not implemented */
538 OSL_ASSERT(sal_False);
539 }
540 else
541 {
542 rtl_uString *ustrFile = NULL;
543 sal_Unicode sFile[_MAX_PATH];
544
545 if ( !GetSpecialFolder( &ustrFile, CSIDL_APPDATA) )
546 {
547 OSL_VERIFY(GetWindowsDirectoryW(sFile, _MAX_DIR) > 0);
548
549 rtl_uString_newFromStr( &ustrFile, sFile);
550 }
551
552 bSuccess = (sal_Bool)(osl_File_E_None == osl_getFileURLFromSystemPath(ustrFile, pustrDirectory));
553
554 if ( ustrFile )
555 rtl_uString_release( ustrFile );
556 }
557 }
558 }
559
560 return bSuccess;
561 }
562
563
osl_loadUserProfile(oslSecurity Security)564 sal_Bool SAL_CALL osl_loadUserProfile(oslSecurity Security)
565 {
566 /* CreateProcessAsUser does not load the specified user's profile
567 into the HKEY_USERS registry key. This means that access to information
568 in the HKEY_CURRENT_USER registry key may not produce results consistent
569 with a normal interactive logon.
570 It is your responsibility to load the user's registry hive into HKEY_USERS
571 with the LoadUserProfile function before calling CreateProcessAsUser.
572 */
573 BOOL bOk = FALSE;
574
575 RegCloseKey(HKEY_CURRENT_USER);
576
577 if (Privilege(SE_RESTORE_NAME, TRUE))
578 {
579 HMODULE hUserEnvLib = NULL;
580 LPFNLOADUSERPROFILE fLoadUserProfile = NULL;
581 LPFNUNLOADUSERPROFILE fUnloadUserProfile = NULL;
582 HANDLE hAccessToken = ((oslSecurityImpl*)Security)->m_hToken;
583 DWORD nError = 0;
584
585 /* try to create user profile */
586 if ( !hAccessToken )
587 {
588 /* retrieve security handle if not done before e.g. osl_getCurrentSecurity()
589 */
590 HANDLE hProcess = GetCurrentProcess();
591
592 if (hProcess != NULL)
593 {
594 OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken);
595 CloseHandle(hProcess);
596 }
597 }
598
599 hUserEnvLib = LoadLibraryA("userenv.dll");
600
601 if (hUserEnvLib)
602 {
603 fLoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "LoadUserProfileW");
604 fUnloadUserProfile = (LPFNUNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "UnloadUserProfile");
605
606 if (fLoadUserProfile && fUnloadUserProfile)
607 {
608 rtl_uString *buffer = 0;
609 PROFILEINFOW pi;
610
611 getUserNameImpl(Security, &buffer, sal_False);
612
613 ZeroMemory( &pi, sizeof(pi) );
614 pi.dwSize = sizeof(pi);
615 pi.lpUserName = rtl_uString_getStr(buffer);
616 pi.dwFlags = PI_NOUI;
617
618 if (fLoadUserProfile(hAccessToken, &pi))
619 {
620 fUnloadUserProfile(hAccessToken, pi.hProfile);
621
622 bOk = TRUE;
623 }
624 else
625 nError = GetLastError();
626
627 rtl_uString_release(buffer);
628 }
629
630 FreeLibrary(hUserEnvLib);
631 }
632
633 if (hAccessToken && (hAccessToken != ((oslSecurityImpl*)Security)->m_hToken))
634 CloseHandle(hAccessToken);
635 }
636
637 return (sal_Bool)bOk;
638 }
639
640
osl_unloadUserProfile(oslSecurity Security)641 void SAL_CALL osl_unloadUserProfile(oslSecurity Security)
642 {
643 if ( ((oslSecurityImpl*)Security)->m_hProfile != NULL )
644 {
645 HMODULE hUserEnvLib = NULL;
646 LPFNLOADUSERPROFILE fLoadUserProfile = NULL;
647 LPFNUNLOADUSERPROFILE fUnloadUserProfile = NULL;
648 BOOL bOk = FALSE;
649 HANDLE hAccessToken = ((oslSecurityImpl*)Security)->m_hToken;
650
651 if ( !hAccessToken )
652 {
653 /* retrieve security handle if not done before e.g. osl_getCurrentSecurity()
654 */
655 HANDLE hProcess = GetCurrentProcess();
656
657 if (hProcess != NULL)
658 {
659 OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken);
660 CloseHandle(hProcess);
661 }
662 }
663
664 hUserEnvLib = LoadLibrary("userenv.dll");
665
666 if (hUserEnvLib)
667 {
668 fLoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "LoadUserProfileA");
669 fUnloadUserProfile = (LPFNUNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "UnloadUserProfile");
670
671 if (fLoadUserProfile && fUnloadUserProfile)
672 {
673 /* unloading the user profile */
674 if (fLoadUserProfile && fUnloadUserProfile)
675 bOk = fUnloadUserProfile(hAccessToken, ((oslSecurityImpl*)Security)->m_hProfile);
676
677 if (hUserEnvLib)
678 FreeLibrary(hUserEnvLib);
679 }
680 }
681
682 ((oslSecurityImpl*)Security)->m_hProfile;
683
684 if (hAccessToken && (hAccessToken != ((oslSecurityImpl*)Security)->m_hToken))
685 {
686 CloseHandle(hAccessToken);
687 }
688 }
689 }
690
691 /*****************************************************************************/
692 /* Static Module Functions */
693 /*****************************************************************************/
694
695
GetSpecialFolder(rtl_uString ** strPath,int nFolder)696 static sal_Bool GetSpecialFolder(rtl_uString **strPath, int nFolder)
697 {
698 sal_Bool bRet = sal_False;
699 HINSTANCE hLibrary;
700 sal_Char PathA[_MAX_PATH];
701 sal_Unicode PathW[_MAX_PATH];
702
703 if ((hLibrary = LoadLibrary("shell32.dll")) != NULL)
704 {
705 BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL);
706 BOOL (WINAPI *pSHGetSpecialFolderPathW)(HWND, LPWSTR, int, BOOL);
707
708 pSHGetSpecialFolderPathA = (BOOL (WINAPI *)(HWND, LPSTR, int, BOOL))GetProcAddress(hLibrary, "SHGetSpecialFolderPathA");
709 pSHGetSpecialFolderPathW = (BOOL (WINAPI *)(HWND, LPWSTR, int, BOOL))GetProcAddress(hLibrary, "SHGetSpecialFolderPathW");
710
711 if (pSHGetSpecialFolderPathA)
712 {
713 if (pSHGetSpecialFolderPathA(GetActiveWindow(), PathA, nFolder, TRUE))
714 {
715 rtl_string2UString( strPath, PathA, strlen(PathA), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS);
716 OSL_ASSERT(*strPath != NULL);
717 bRet = sal_True;
718 }
719 }
720 else if (pSHGetSpecialFolderPathW)
721 {
722 if (pSHGetSpecialFolderPathW(GetActiveWindow(), PathW, nFolder, TRUE))
723 {
724 rtl_uString_newFromStr( strPath, PathW);
725 bRet = sal_True;
726 }
727 }
728 else
729 {
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");
734
735
736 if (pSHGetSpecialFolderLocation && (pSHGetPathFromIDListA || pSHGetPathFromIDListW ) && pSHGetMalloc )
737 {
738 LPITEMIDLIST pidl;
739 LPMALLOC pMalloc;
740 HRESULT hr;
741
742 hr = pSHGetSpecialFolderLocation(GetActiveWindow(), nFolder, &pidl);
743
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))
747 {
748 HKEY hRegKey;
749
750 if (RegOpenKey(HKEY_CURRENT_USER,
751 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
752 &hRegKey) == ERROR_SUCCESS)
753 {
754 LONG lRet;
755 DWORD lSize = elementsof(PathA);
756 DWORD Type = REG_SZ;
757
758 switch (nFolder)
759 {
760 case CSIDL_APPDATA:
761 lRet = RegQueryValueEx(hRegKey, "AppData", NULL, &Type, (LPBYTE)PathA, &lSize);
762 break;
763
764 case CSIDL_PERSONAL:
765 lRet = RegQueryValueEx(hRegKey, "Personal", NULL, &Type, (LPBYTE)PathA, &lSize);
766 break;
767
768 default:
769 lRet = -1l;
770 }
771
772 if ((lRet == ERROR_SUCCESS) && (Type == REG_SZ))
773 {
774 if (_access(PathA, 0) < 0)
775 CreateDirectory(PathA, NULL);
776
777 hr = pSHGetSpecialFolderLocation(GetActiveWindow(), nFolder, &pidl);
778 }
779
780 RegCloseKey(hRegKey);
781 }
782 }
783
784 if (SUCCEEDED(hr))
785 {
786 if (pSHGetPathFromIDListW && pSHGetPathFromIDListW(pidl, PathW))
787 {
788 /* if directory does not exist, create it */
789 if (_waccess(PathW, 0) < 0)
790 CreateDirectoryW(PathW, NULL);
791
792 rtl_uString_newFromStr( strPath, PathW);
793 bRet = sal_True;
794 }
795 else if (pSHGetPathFromIDListA && pSHGetPathFromIDListA(pidl, PathA))
796 {
797 /* if directory does not exist, create it */
798 if (_access(PathA, 0) < 0)
799 CreateDirectoryA(PathA, NULL);
800
801 rtl_string2UString( strPath, PathA, strlen(PathA), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS);
802 OSL_ASSERT(*strPath != NULL);
803 bRet = sal_True;
804 }
805 }
806
807 if (SUCCEEDED(pSHGetMalloc(&pMalloc)))
808 {
809 pMalloc->lpVtbl->Free(pMalloc, pidl);
810 pMalloc->lpVtbl->Release(pMalloc);
811 }
812 }
813 }
814 }
815
816 FreeLibrary(hLibrary);
817
818 return (bRet);
819 }
820
821
isWNT(void)822 static sal_Bool isWNT(void)
823 {
824 static sal_Bool isInit = sal_False;
825 static sal_Bool isWNT = sal_False;
826
827 if (!isInit)
828 {
829 OSVERSIONINFO VersionInformation =
830
831 {
832 sizeof(OSVERSIONINFO),
833 0,
834 0,
835 0,
836 0,
837 "",
838 };
839
840 if (
841 GetVersionEx(&VersionInformation) &&
842 (VersionInformation.dwPlatformId == VER_PLATFORM_WIN32_NT)
843 )
844 {
845 isWNT = sal_True;
846 }
847
848 isInit = sal_True;
849 }
850
851 return(isWNT);
852 }
853
Privilege(LPTSTR strPrivilege,BOOL bEnable)854 static BOOL Privilege(LPTSTR strPrivilege, BOOL bEnable)
855 {
856 HANDLE hToken;
857 TOKEN_PRIVILEGES tp;
858
859 /*
860 obtain the processes token
861 */
862 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_DUP_QUERY, &hToken))
863 return FALSE;
864
865 /*
866 get the luid
867 */
868 if (!LookupPrivilegeValue(NULL, strPrivilege, &tp.Privileges[0].Luid))
869 return FALSE;
870
871 tp.PrivilegeCount = 1;
872
873 if (bEnable)
874 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
875 else
876 tp.Privileges[0].Attributes = 0;
877
878 /*
879 enable or disable the privilege
880 */
881 if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0))
882 return FALSE;
883
884 if (!CloseHandle(hToken))
885 return FALSE;
886
887 return TRUE;
888 }
889
getUserNameImpl(oslSecurity Security,rtl_uString ** strName,sal_Bool bIncludeDomain)890 static sal_Bool SAL_CALL getUserNameImpl(oslSecurity Security, rtl_uString **strName, sal_Bool bIncludeDomain)
891 {
892 if (Security != NULL)
893 {
894 oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;
895
896 HANDLE hAccessToken = pSecImpl->m_hToken;
897
898 if (hAccessToken == NULL)
899 OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);
900
901 if (hAccessToken)
902 {
903 DWORD nInfoBuffer = 512;
904 UCHAR* pInfoBuffer = malloc(nInfoBuffer);
905
906 while (!GetTokenInformation(hAccessToken, TokenUser,
907 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
908 {
909 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
910 pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer);
911 else
912 {
913 free(pInfoBuffer);
914 pInfoBuffer = NULL;
915 break;
916 }
917 }
918
919 if (pSecImpl->m_hToken == NULL)
920 CloseHandle(hAccessToken);
921
922 if (pInfoBuffer)
923 {
924 sal_Unicode UserName[128];
925 sal_Unicode DomainName[128];
926 sal_Unicode Name[257];
927 DWORD nUserName = sizeof(UserName);
928 DWORD nDomainName = sizeof(DomainName);
929 SID_NAME_USE sUse;
930
931 if (LookupAccountSidW(NULL, ((PTOKEN_USER)pInfoBuffer)->User.Sid,
932 UserName, &nUserName,
933 DomainName, &nDomainName, &sUse))
934 {
935 if (bIncludeDomain)
936 {
937 wcscpy(Name, DomainName);
938 wcscat(Name, L"/");
939 wcscat(Name, UserName);
940 }
941 else
942 {
943 wcscpy(Name, UserName);
944 }
945 }
946 rtl_uString_newFromStr( strName, Name);
947
948 free(pInfoBuffer);
949
950 return (sal_True);
951 }
952 }
953 else
954 {
955 DWORD needed=0;
956 sal_Unicode *pNameW=NULL;
957
958 WNetGetUserW(NULL, NULL, &needed);
959 pNameW = malloc (needed*sizeof(sal_Unicode));
960
961 if (WNetGetUserW(NULL, pNameW, &needed) == NO_ERROR)
962 {
963 rtl_uString_newFromStr( strName, pNameW);
964
965 if (pNameW)
966 free(pNameW);
967 return (sal_True);
968 }
969 else
970 if (wcslen(pSecImpl->m_User) > 0)
971 {
972 rtl_uString_newFromStr( strName, pSecImpl->m_pNetResource->lpRemoteName);
973
974 if (pNameW)
975 free(pNameW);
976
977 return (sal_True);
978 }
979
980 if (pNameW)
981 free(pNameW);
982 }
983 }
984
985 return sal_False;
986 }
987
988