xref: /AOO41X/main/sal/osl/w32/security.c (revision 647f063d49501903f1667b75f5634541fc603283)
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