1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include "system.h"
21 #include <userenv.h>
22
23 #include <cassert>
24 #include <osl/security.h>
25 #include <osl/diagnose.h>
26 #include <osl/thread.h>
27 #include <osl/file.h>
28 #include <systools/win32/uwinapi.h>
29 #include <sddl.h>
30 #include <sal/macros.h>
31 #include <sal/log.hxx>
32 #include <o3tl/char16_t2wchar_t.hxx>
33 #include "secimpl.hxx"
34
35 /* To get an impersonation token we need to create an impersonation
36 duplicate so every access token has to be created with duplicate
37 access rights */
38
39 #define TOKEN_DUP_QUERY (TOKEN_QUERY|TOKEN_DUPLICATE)
40
41 static bool GetSpecialFolder(rtl_uString **strPath, REFKNOWNFOLDERID rFolder);
42 // We use LPCTSTR here, because we use it with SE_foo_NAME constants
43 // which are defined in winnt.h as UNICODE-dependent TEXT("PrivilegeName")
44 static BOOL Privilege(LPCTSTR pszPrivilege, BOOL bEnable);
45 static bool getUserNameImpl(oslSecurity Security, rtl_uString **strName, bool bIncludeDomain);
46
osl_getCurrentSecurity(void)47 oslSecurity SAL_CALL osl_getCurrentSecurity(void)
48 {
49 oslSecurityImpl* pSecImpl = static_cast<oslSecurityImpl *>(malloc(sizeof(oslSecurityImpl)));
50 if (pSecImpl)
51 {
52 pSecImpl->m_pNetResource = nullptr;
53 pSecImpl->m_User[0] = '\0';
54 pSecImpl->m_hToken = nullptr;
55 pSecImpl->m_hProfile = nullptr;
56 }
57 return pSecImpl;
58 }
59
osl_loginUser(rtl_uString * strUserName,rtl_uString * strPasswd,oslSecurity * pSecurity)60 oslSecurityError SAL_CALL osl_loginUser( rtl_uString *strUserName, rtl_uString *strPasswd, oslSecurity *pSecurity )
61 {
62 oslSecurityError ret;
63
64 sal_Unicode* strUser;
65 sal_Unicode* strDomain = o3tl::toU(_wcsdup(o3tl::toW(rtl_uString_getStr(strUserName))));
66 HANDLE hUserToken;
67 LUID luid;
68
69 if (nullptr != (strUser = o3tl::toU(wcschr(o3tl::toW(strDomain), L'/'))))
70 *strUser++ = L'\0';
71 else
72 {
73 strUser = strDomain;
74 strDomain = nullptr;
75 }
76
77 // this process must have the right: 'act as a part of operatingsystem'
78 OSL_ASSERT(LookupPrivilegeValue(nullptr, SE_TCB_NAME, &luid));
79 (void) luid;
80
81 if (LogonUserW(o3tl::toW(strUser), strDomain ? o3tl::toW(strDomain) : L"", o3tl::toW(rtl_uString_getStr(strPasswd)),
82 LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
83 &hUserToken))
84 {
85 oslSecurityImpl* pSecImpl = static_cast<oslSecurityImpl *>(malloc(sizeof(oslSecurityImpl)));
86 if (pSecImpl)
87 {
88 pSecImpl->m_pNetResource = nullptr;
89 pSecImpl->m_hToken = hUserToken;
90 pSecImpl->m_hProfile = nullptr;
91 wcscpy(o3tl::toW(pSecImpl->m_User), o3tl::toW(strUser));
92 }
93 *pSecurity = pSecImpl;
94 ret = pSecImpl ? osl_Security_E_None : osl_Security_E_Unknown;
95 }
96 else
97 {
98 ret = osl_Security_E_UserUnknown;
99 }
100
101 if (strDomain)
102 free(strDomain);
103 else
104 free(strUser);
105
106 return ret;
107 }
108
osl_loginUserOnFileServer(rtl_uString * strUserName,rtl_uString * strPasswd,rtl_uString * strFileServer,oslSecurity * pSecurity)109 oslSecurityError SAL_CALL osl_loginUserOnFileServer(rtl_uString *strUserName,
110 rtl_uString *strPasswd,
111 rtl_uString *strFileServer,
112 oslSecurity *pSecurity)
113 {
114 oslSecurityError ret;
115 DWORD err;
116 NETRESOURCEW netResource;
117 sal_Unicode* remoteName;
118 sal_Unicode* userName;
119
120 remoteName = static_cast<sal_Unicode *>(malloc((rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 4) * sizeof(sal_Unicode)));
121 userName = static_cast<sal_Unicode *>(malloc((rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 2) * sizeof(sal_Unicode)));
122
123 wcscpy(o3tl::toW(remoteName), L"\\\\");
124 wcscat(o3tl::toW(remoteName), o3tl::toW(rtl_uString_getStr(strFileServer)));
125 wcscat(o3tl::toW(remoteName), L"\\");
126 wcscat(o3tl::toW(remoteName), o3tl::toW(rtl_uString_getStr(strUserName)));
127
128 wcscpy(o3tl::toW(userName), o3tl::toW(rtl_uString_getStr(strFileServer)));
129 wcscat(o3tl::toW(userName), L"\\");
130 wcscat(o3tl::toW(userName), o3tl::toW(rtl_uString_getStr(strUserName)));
131
132 netResource.dwScope = RESOURCE_GLOBALNET;
133 netResource.dwType = RESOURCETYPE_DISK;
134 netResource.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
135 netResource.dwUsage = RESOURCEUSAGE_CONNECTABLE;
136 netResource.lpLocalName = nullptr;
137 netResource.lpRemoteName = o3tl::toW(remoteName);
138 netResource.lpComment = nullptr;
139 netResource.lpProvider = nullptr;
140
141 err = WNetAddConnection2W(&netResource, o3tl::toW(rtl_uString_getStr(strPasswd)), o3tl::toW(userName), 0);
142
143 if ((err == NO_ERROR) || (err == ERROR_ALREADY_ASSIGNED))
144 {
145 oslSecurityImpl* pSecImpl = static_cast<oslSecurityImpl *>(malloc(sizeof(oslSecurityImpl)));
146 if (pSecImpl)
147 {
148 pSecImpl->m_pNetResource = static_cast<NETRESOURCEW *>(malloc(sizeof(NETRESOURCE)));
149 if (pSecImpl->m_pNetResource)
150 {
151 *pSecImpl->m_pNetResource = netResource;
152 pSecImpl->m_hToken = nullptr;
153 pSecImpl->m_hProfile = nullptr;
154 wcscpy(o3tl::toW(pSecImpl->m_User), o3tl::toW(rtl_uString_getStr(strUserName)));
155 }
156 else
157 {
158 free(pSecImpl);
159 pSecImpl = nullptr;
160 }
161 }
162 *pSecurity = pSecImpl;
163
164 ret = pSecImpl ? osl_Security_E_None : osl_Security_E_Unknown;
165 }
166 else
167 {
168 ret = osl_Security_E_UserUnknown;
169 }
170
171 free(remoteName);
172 free(userName);
173
174 return ret;
175 }
176
osl_isAdministrator(oslSecurity Security)177 sal_Bool SAL_CALL osl_isAdministrator(oslSecurity Security)
178 {
179 if (Security != nullptr)
180 {
181 HANDLE hImpersonationToken = nullptr;
182 PSID psidAdministrators;
183 SID_IDENTIFIER_AUTHORITY siaNtAuthority = { SECURITY_NT_AUTHORITY };
184 bool bSuccess = false;
185
186 /* If Security contains an access token we need to duplicate it to an impersonation
187 access token. NULL works with CheckTokenMembership() as the current effective
188 impersonation token
189 */
190
191 if ( static_cast<oslSecurityImpl*>(Security)->m_hToken )
192 {
193 if ( !DuplicateToken (static_cast<oslSecurityImpl*>(Security)->m_hToken, SecurityImpersonation, &hImpersonationToken) )
194 return false;
195 }
196
197 /* CheckTokenMembership() can be used on W2K and higher (NT4 no longer supported by OOo)
198 and also works on Vista to retrieve the effective user rights. Just checking for
199 membership of Administrators group is not enough on Vista this would require additional
200 complicated checks as described in KB article Q118626: http://support.microsoft.com/kb/118626/en-us
201 */
202
203 if (AllocateAndInitializeSid(&siaNtAuthority,
204 2,
205 SECURITY_BUILTIN_DOMAIN_RID,
206 DOMAIN_ALIAS_RID_ADMINS,
207 0, 0, 0, 0, 0, 0,
208 &psidAdministrators))
209 {
210 BOOL fSuccess = FALSE;
211
212 if (CheckTokenMembership(hImpersonationToken, psidAdministrators, &fSuccess) && fSuccess)
213 bSuccess = true;
214
215 FreeSid(psidAdministrators);
216 }
217
218 if (hImpersonationToken)
219 CloseHandle(hImpersonationToken);
220
221 return bSuccess;
222 }
223 else
224 {
225 return false;
226 }
227 }
228
osl_freeSecurityHandle(oslSecurity Security)229 void SAL_CALL osl_freeSecurityHandle(oslSecurity Security)
230 {
231 if (Security)
232 {
233 oslSecurityImpl *pSecImpl = static_cast<oslSecurityImpl*>(Security);
234
235 if (pSecImpl->m_pNetResource != nullptr)
236 {
237 WNetCancelConnection2W(pSecImpl->m_pNetResource->lpRemoteName, 0, true);
238
239 free(pSecImpl->m_pNetResource->lpRemoteName);
240 free(pSecImpl->m_pNetResource);
241 }
242
243 if (pSecImpl->m_hToken)
244 CloseHandle(pSecImpl->m_hToken);
245
246 if ( pSecImpl->m_hProfile )
247 CloseHandle(pSecImpl->m_hProfile);
248
249 free (pSecImpl);
250 }
251 }
252
osl_getUserIdent(oslSecurity Security,rtl_uString ** strIdent)253 sal_Bool SAL_CALL osl_getUserIdent(oslSecurity Security, rtl_uString **strIdent)
254 {
255 if (Security != nullptr)
256 {
257 oslSecurityImpl *pSecImpl = static_cast<oslSecurityImpl*>(Security);
258
259 HANDLE hAccessToken = pSecImpl->m_hToken;
260
261 if (hAccessToken == nullptr)
262 OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);
263
264 if (hAccessToken)
265 {
266 DWORD nInfoBuffer = 512;
267 UCHAR* pInfoBuffer = static_cast<UCHAR *>(malloc(nInfoBuffer));
268
269 while (!GetTokenInformation(hAccessToken, TokenUser,
270 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
271 {
272 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
273 {
274 if (auto p = static_cast<UCHAR *>(realloc(pInfoBuffer, nInfoBuffer)))
275 pInfoBuffer = p;
276 else
277 {
278 free(pInfoBuffer);
279 pInfoBuffer = nullptr;
280 break;
281 }
282 }
283 else
284 {
285 free(pInfoBuffer);
286 pInfoBuffer = nullptr;
287 break;
288 }
289 }
290
291 if (pSecImpl->m_hToken == nullptr)
292 CloseHandle(hAccessToken);
293
294 if (pInfoBuffer)
295 {
296 PSID pSid = reinterpret_cast<PTOKEN_USER>(pInfoBuffer)->User.Sid;
297
298 LPWSTR pSidStr = nullptr;
299 BOOL bResult = ConvertSidToStringSidW(pSid, &pSidStr);
300 if (bResult)
301 {
302 rtl_uString_newFromStr(strIdent, o3tl::toU(pSidStr));
303 LocalFree(pSidStr);
304 }
305 else
306 {
307 const DWORD dwError = GetLastError();
308 SAL_WARN(
309 "sal.osl",
310 "ConvertSidToStringSidW failed. GetLastError returned: " << dwError);
311 }
312
313 free(pInfoBuffer);
314
315 return bResult != FALSE;
316 }
317 }
318 else
319 {
320 DWORD needed = 0;
321
322 WNetGetUserW(nullptr, nullptr, &needed);
323 if (needed < 16)
324 needed = 16;
325
326 if (auto Ident = static_cast<sal_Unicode *>(malloc(needed*sizeof(sal_Unicode))))
327 {
328 if (WNetGetUserW(nullptr, o3tl::toW(Ident), &needed) != NO_ERROR)
329 {
330 wcscpy(o3tl::toW(Ident), L"unknown");
331 Ident[7] = L'\0';
332 }
333
334 rtl_uString_newFromStr( strIdent, Ident);
335 free(Ident);
336 return true;
337 }
338 }
339 }
340
341 return false;
342 }
343
osl_getUserName(oslSecurity Security,rtl_uString ** strName)344 sal_Bool SAL_CALL osl_getUserName(oslSecurity Security, rtl_uString **strName)
345 {
346 return getUserNameImpl(Security, strName, true);
347 }
348
osl_getShortUserName(oslSecurity Security,rtl_uString ** strName)349 sal_Bool SAL_CALL osl_getShortUserName(oslSecurity Security, rtl_uString **strName)
350 {
351 return getUserNameImpl(Security, strName, false);
352 }
353
osl_getHomeDir(oslSecurity Security,rtl_uString ** pustrDirectory)354 sal_Bool SAL_CALL osl_getHomeDir(oslSecurity Security, rtl_uString **pustrDirectory)
355 {
356 rtl_uString *ustrSysDir = nullptr;
357 bool bSuccess = false;
358
359 if (Security != nullptr)
360 {
361 oslSecurityImpl *pSecImpl = static_cast<oslSecurityImpl*>(Security);
362
363 if (pSecImpl->m_pNetResource != nullptr)
364 {
365 rtl_uString_newFromStr( &ustrSysDir, o3tl::toU(pSecImpl->m_pNetResource->lpRemoteName));
366
367 bSuccess = osl_File_E_None == osl_getFileURLFromSystemPath( ustrSysDir, pustrDirectory );
368 }
369 else
370 {
371 bSuccess = GetSpecialFolder(&ustrSysDir, FOLDERID_Documents) &&
372 (osl_File_E_None == osl_getFileURLFromSystemPath(ustrSysDir, pustrDirectory));
373 }
374 }
375
376 if ( ustrSysDir )
377 rtl_uString_release( ustrSysDir );
378
379 return bSuccess;
380 }
381
osl_getConfigDir(oslSecurity Security,rtl_uString ** pustrDirectory)382 sal_Bool SAL_CALL osl_getConfigDir(oslSecurity Security, rtl_uString **pustrDirectory)
383 {
384 bool bSuccess = false;
385
386 if (Security != nullptr)
387 {
388 oslSecurityImpl *pSecImpl = static_cast<oslSecurityImpl*>(Security);
389
390 if (pSecImpl->m_pNetResource != nullptr)
391 {
392 rtl_uString *ustrSysDir = nullptr;
393
394 rtl_uString_newFromStr( &ustrSysDir, o3tl::toU(pSecImpl->m_pNetResource->lpRemoteName));
395 bSuccess = osl_File_E_None == osl_getFileURLFromSystemPath( ustrSysDir, pustrDirectory);
396
397 if ( ustrSysDir )
398 rtl_uString_release( ustrSysDir );
399 }
400 else
401 {
402 if (pSecImpl->m_hToken)
403 {
404 /* not implemented */
405 OSL_ASSERT(false);
406 }
407 else
408 {
409 rtl_uString *ustrFile = nullptr;
410 sal_Unicode sFile[_MAX_PATH];
411
412 if ( !GetSpecialFolder( &ustrFile, FOLDERID_RoamingAppData) )
413 {
414 OSL_VERIFY(GetWindowsDirectoryW(o3tl::toW(sFile), _MAX_DIR) > 0);
415
416 rtl_uString_newFromStr( &ustrFile, sFile);
417 }
418
419 bSuccess = osl_File_E_None == osl_getFileURLFromSystemPath(ustrFile, pustrDirectory);
420
421 if ( ustrFile )
422 rtl_uString_release( ustrFile );
423 }
424 }
425 }
426
427 return bSuccess;
428 }
429
osl_loadUserProfile(oslSecurity Security)430 sal_Bool SAL_CALL osl_loadUserProfile(oslSecurity Security)
431 {
432 /* CreateProcessAsUser does not load the specified user's profile
433 into the HKEY_USERS registry key. This means that access to information
434 in the HKEY_CURRENT_USER registry key may not produce results consistent
435 with a normal interactive logon.
436 It is your responsibility to load the user's registry hive into HKEY_USERS
437 with the LoadUserProfile function before calling CreateProcessAsUser.
438 */
439 bool bOk = false;
440
441 RegCloseKey(HKEY_CURRENT_USER);
442
443 if (Privilege(SE_RESTORE_NAME, TRUE))
444 {
445 HANDLE hAccessToken = static_cast<oslSecurityImpl*>(Security)->m_hToken;
446
447 /* try to create user profile */
448 if ( !hAccessToken )
449 {
450 /* retrieve security handle if not done before e.g. osl_getCurrentSecurity()
451 */
452 HANDLE hProcess = GetCurrentProcess();
453
454 if (hProcess != nullptr)
455 {
456 OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken);
457 CloseHandle(hProcess);
458 }
459 }
460
461 rtl_uString *buffer = nullptr;
462 PROFILEINFOW pi;
463
464 getUserNameImpl(Security, &buffer, false);
465
466 ZeroMemory(&pi, sizeof(pi));
467 pi.dwSize = sizeof(pi);
468 pi.lpUserName = o3tl::toW(rtl_uString_getStr(buffer));
469 pi.dwFlags = PI_NOUI;
470
471 if (LoadUserProfileW(hAccessToken, &pi))
472 {
473 UnloadUserProfile(hAccessToken, pi.hProfile);
474
475 bOk = true;
476 }
477
478 rtl_uString_release(buffer);
479
480 if (hAccessToken && (hAccessToken != static_cast<oslSecurityImpl*>(Security)->m_hToken))
481 CloseHandle(hAccessToken);
482 }
483
484 return bOk;
485 }
486
osl_unloadUserProfile(oslSecurity Security)487 void SAL_CALL osl_unloadUserProfile(oslSecurity Security)
488 {
489 if ( static_cast<oslSecurityImpl*>(Security)->m_hProfile != nullptr )
490 {
491 HANDLE hAccessToken = static_cast<oslSecurityImpl*>(Security)->m_hToken;
492
493 if ( !hAccessToken )
494 {
495 /* retrieve security handle if not done before e.g. osl_getCurrentSecurity()
496 */
497 HANDLE hProcess = GetCurrentProcess();
498
499 if (hProcess != nullptr)
500 {
501 OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken);
502 CloseHandle(hProcess);
503 }
504 }
505
506 /* unloading the user profile */
507 UnloadUserProfile(hAccessToken, static_cast<oslSecurityImpl*>(Security)->m_hProfile);
508
509 static_cast<oslSecurityImpl*>(Security)->m_hProfile = nullptr;
510
511 if (hAccessToken && (hAccessToken != static_cast<oslSecurityImpl*>(Security)->m_hToken))
512 CloseHandle(hAccessToken);
513 }
514 }
515
GetSpecialFolder(rtl_uString ** strPath,REFKNOWNFOLDERID rFolder)516 static bool GetSpecialFolder(rtl_uString **strPath, REFKNOWNFOLDERID rFolder)
517 {
518 bool bRet = false;
519 PWSTR PathW;
520 if (SUCCEEDED(SHGetKnownFolderPath(rFolder, KF_FLAG_CREATE, nullptr, &PathW)))
521 {
522 rtl_uString_newFromStr(strPath, o3tl::toU(PathW));
523 CoTaskMemFree(PathW);
524 bRet = true;
525 }
526
527 return bRet;
528 }
529
530 // We use LPCTSTR here, because we use it with SE_foo_NAME constants
531 // which are defined in winnt.h as UNICODE-dependent TEXT("PrivilegeName")
Privilege(LPCTSTR strPrivilege,BOOL bEnable)532 static BOOL Privilege(LPCTSTR strPrivilege, BOOL bEnable)
533 {
534 HANDLE hToken;
535 TOKEN_PRIVILEGES tp;
536
537 // obtain the processes token
538 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_DUP_QUERY, &hToken))
539 return FALSE;
540
541 // get the luid
542 if (!LookupPrivilegeValue(nullptr, strPrivilege, &tp.Privileges[0].Luid))
543 return FALSE;
544
545 tp.PrivilegeCount = 1;
546
547 if (bEnable)
548 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
549 else
550 tp.Privileges[0].Attributes = 0;
551
552 // enable or disable the privilege
553 if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, nullptr, nullptr))
554 return FALSE;
555
556 if (!CloseHandle(hToken))
557 return FALSE;
558
559 return TRUE;
560 }
561
getUserNameImpl(oslSecurity Security,rtl_uString ** strName,bool bIncludeDomain)562 static bool getUserNameImpl(oslSecurity Security, rtl_uString **strName, bool bIncludeDomain)
563 {
564 if (Security != nullptr)
565 {
566 oslSecurityImpl *pSecImpl = static_cast<oslSecurityImpl*>(Security);
567
568 HANDLE hAccessToken = pSecImpl->m_hToken;
569
570 if (hAccessToken == nullptr)
571 OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);
572
573 if (hAccessToken)
574 {
575 DWORD nInfoBuffer = 512;
576 UCHAR* pInfoBuffer = static_cast<UCHAR *>(malloc(nInfoBuffer));
577
578 while (!GetTokenInformation(hAccessToken, TokenUser,
579 pInfoBuffer, nInfoBuffer, &nInfoBuffer))
580 {
581 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
582 {
583 if (auto p = static_cast<UCHAR *>(realloc(pInfoBuffer, nInfoBuffer)))
584 pInfoBuffer = p;
585 else
586 {
587 free(pInfoBuffer);
588 pInfoBuffer = nullptr;
589 break;
590 }
591 }
592 else
593 {
594 free(pInfoBuffer);
595 pInfoBuffer = nullptr;
596 break;
597 }
598 }
599
600 if (pSecImpl->m_hToken == nullptr)
601 CloseHandle(hAccessToken);
602
603 if (pInfoBuffer)
604 {
605 sal_Unicode UserName[128];
606 sal_Unicode DomainName[128];
607 sal_Unicode Name[257];
608 DWORD nUserName = SAL_N_ELEMENTS(UserName);
609 DWORD nDomainName = SAL_N_ELEMENTS(DomainName);
610 SID_NAME_USE sUse;
611
612 if (LookupAccountSidW(nullptr, reinterpret_cast<PTOKEN_USER>(pInfoBuffer)->User.Sid,
613 o3tl::toW(UserName), &nUserName,
614 o3tl::toW(DomainName), &nDomainName, &sUse))
615 {
616 if (bIncludeDomain)
617 {
618 wcscpy(o3tl::toW(Name), o3tl::toW(DomainName));
619 wcscat(o3tl::toW(Name), L"/");
620 wcscat(o3tl::toW(Name), o3tl::toW(UserName));
621 }
622 else
623 {
624 wcscpy(o3tl::toW(Name), o3tl::toW(UserName));
625 }
626
627 rtl_uString_newFromStr(strName, Name);
628 free(pInfoBuffer);
629 return true;
630 }
631 }
632 }
633 else
634 {
635 DWORD needed=0;
636 sal_Unicode *pNameW=nullptr;
637
638 WNetGetUserW(nullptr, nullptr, &needed);
639 pNameW = static_cast<sal_Unicode *>(malloc (needed*sizeof(sal_Unicode)));
640 assert(pNameW); // Don't handle OOM conditions
641
642 if (WNetGetUserW(nullptr, o3tl::toW(pNameW), &needed) == NO_ERROR)
643 {
644 rtl_uString_newFromStr( strName, pNameW);
645
646 if (pNameW)
647 free(pNameW);
648 return true;
649 }
650 else if (pSecImpl->m_User[0] != '\0')
651 {
652 rtl_uString_newFromStr(strName, o3tl::toU(pSecImpl->m_pNetResource->lpRemoteName));
653
654 if (pNameW)
655 free(pNameW);
656
657 return true;
658 }
659
660 if (pNameW)
661 free(pNameW);
662 }
663 }
664
665 return false;
666 }
667
668 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
669