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 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 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 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 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 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 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 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 450 sal_Bool SAL_CALL osl_getUserName(oslSecurity Security, rtl_uString **strName) 451 { 452 return getUserNameImpl(Security, strName, sal_True); 453 } 454 455 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 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 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 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 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 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 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 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