xref: /trunk/main/sal/osl/w32/security.c (revision 509a48ff)
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 administrator */
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 = NULL;
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