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