bump product version to 5.0.4.1
[LibreOffice.git] / sal / qa / osl / security / osl_Security.cxx
blobadba5867725c2164d2070bf807df18840e37cd91
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <algorithm>
21 #ifdef WNT
22 #include <windows.h>
23 #undef min
24 #endif
25 #include <osl_Security_Const.h>
26 #include <osl/thread.h>
27 #include <rtl/process.h>
28 #include <rtl/strbuf.hxx>
30 using namespace osl;
31 using namespace rtl;
33 /** print a UNI_CODE String.
35 inline void printUString( const ::rtl::OUString & str )
37 rtl::OString aString;
39 //t_print("#printUString_u# " );
40 aString = ::rtl::OUStringToOString( str, RTL_TEXTENCODING_ASCII_US );
41 t_print("%s\n", aString.getStr( ) );
44 // test code start here
46 namespace osl_Security
49 /** testing the method:
50 Security()
52 class ctors : public CppUnit::TestFixture
54 public:
55 bool bRes, bRes1;
57 void ctors_001( )
59 ::osl::Security aSec;
61 CPPUNIT_ASSERT_MESSAGE( "#test comment#: create a security its handle should not be NULL.",
62 aSec.getHandle( ) != NULL );
65 CPPUNIT_TEST_SUITE( ctors );
66 CPPUNIT_TEST( ctors_001 );
67 CPPUNIT_TEST_SUITE_END( );
68 }; // class ctors
70 /** testing the methods:
71 inline sal_Bool SAL_CALL logonUser(const ::rtl::OUString& strName,
72 const ::rtl::OUString& strPasswd);
73 inline sal_Bool SAL_CALL logonUser(const ::rtl::OUString & strName,
74 const ::rtl::OUString & strPasswd,
75 const ::rtl::OUString & strFileServer);
77 class logonUser : public CppUnit::TestFixture
79 public:
80 bool bRes;
82 void logonUser_user_pwd( )
84 ::osl::Security aSec;
85 bRes = aSec.logonUser( aLogonUser, aLogonPasswd );
87 CPPUNIT_ASSERT_MESSAGE( "#test comment#: check logon user through forwarded user name, pwd, passed in (UNX), failed in (W32).",
88 bRes );
91 void logonUser_user_pwd_server( )
93 ::osl::Security aSec;
94 bRes = aSec.logonUser( aLogonUser, aLogonPasswd, aFileServer );
96 CPPUNIT_ASSERT_MESSAGE( "#test comment#: check logon user through forwarded user name, pwd and server name, failed in (UNX)(W32).",
97 bRes );
100 CPPUNIT_TEST_SUITE( logonUser );
101 if ( !aStringForward.isEmpty() && aStringForward.indexOf( (sal_Unicode)' ' ) != -1 && ( aStringForward.indexOf( ( sal_Unicode ) ' ' ) == aStringForward.lastIndexOf( ( sal_Unicode ) ' ' ) ) )
102 /// if user name and passwd are forwarded
104 CPPUNIT_TEST( logonUser_user_pwd );
106 if ( !aStringForward.isEmpty() && aStringForward.indexOf( (sal_Unicode)' ' ) != -1 && ( aStringForward.indexOf( ( sal_Unicode ) ' ' ) != aStringForward.lastIndexOf( ( sal_Unicode ) ' ' ) ) )
107 /// if user name and passwd and file server are forwarded
109 CPPUNIT_TEST( logonUser_user_pwd_server );
111 CPPUNIT_TEST_SUITE_END( );
112 }; // class logonUser
114 /** testing the method:
115 inline sal_Bool Security::getUserIdent( rtl::OUString& strIdent) const
117 class getUserIdent : public CppUnit::TestFixture
119 public:
120 bool bRes, bRes1;
122 void getUserIdent_001( )
124 ::osl::Security aSec;
125 ::rtl::OUString strID;
126 bRes = aSec.getUserIdent( strID );
128 rtl::OStringBuffer aMessage;
129 aMessage.append("strUserID: ");
130 aMessage.append(rtl::OUStringToOString(strUserID, osl_getThreadTextEncoding()));
131 aMessage.append(", strID: ");
132 aMessage.append(rtl::OUStringToOString(strID, osl_getThreadTextEncoding()));
133 aMessage.append(", bRes: ");
134 aMessage.append(bRes);
136 CPPUNIT_ASSERT_MESSAGE( aMessage.getStr(), strUserID.equals(strID) && bRes );
139 CPPUNIT_TEST_SUITE( getUserIdent );
140 CPPUNIT_TEST( getUserIdent_001 );
141 CPPUNIT_TEST_SUITE_END( );
142 }; // class getUserIdent
144 /** testing the method:
145 inline sal_Bool SAL_CALL getUserName( ::rtl::OUString& strName) const;
147 class getUserName : public CppUnit::TestFixture
149 public:
150 bool bRes, bRes1;
152 void getUserName_001( )
154 ::osl::Security aSec;
155 #ifdef WNT
156 ::rtl::OUString strName( strUserName ), strGetName;
157 #else
158 ::rtl::OUString strName( strUserName ), strGetName;
159 #endif
160 bRes = aSec.getUserName( strGetName );
162 sal_Int32 nPos = -1;
163 if (!strName.isEmpty())
165 nPos = strGetName.indexOf(strName);
167 CPPUNIT_ASSERT_MESSAGE( "#test comment#: get UserName and compare it with names got at the beginning of the test.",
168 ( nPos >= 0 ) && bRes );
171 CPPUNIT_TEST_SUITE( getUserName );
172 CPPUNIT_TEST( getUserName_001 );
173 CPPUNIT_TEST_SUITE_END( );
174 }; // class getUserName
176 /** testing the method:
177 inline sal_Bool Security::getConfigDir( rtl::OUString& strDirectory ) const
179 class getConfigDir : public CppUnit::TestFixture
181 public:
182 bool bRes, bRes1;
184 void getConfigDir_001( )
186 ::osl::Security aSec;
187 ::rtl::OUString strConfig;
188 bRes = aSec.getConfigDir( strConfig );
190 CPPUNIT_ASSERT_MESSAGE( "failed to find a ConfigDir!", bRes );
193 CPPUNIT_TEST_SUITE( getConfigDir );
194 CPPUNIT_TEST( getConfigDir_001 );
195 CPPUNIT_TEST_SUITE_END( );
196 }; // class getConfigDir
198 /** testing the method:
199 inline sal_Bool SAL_CALL isAdministrator() const;
201 class isAdministrator : public CppUnit::TestFixture
203 public:
204 bool bRes;
206 void isAdministrator_001( )
208 ::osl::Security aSec;
209 bRes = aSec.isAdministrator( );
211 CPPUNIT_ASSERT_MESSAGE( "#test comment#: check if the user is administrator at beginning, compare here.",
212 bRes == isAdmin );
215 CPPUNIT_TEST_SUITE( isAdministrator );
216 CPPUNIT_TEST( isAdministrator_001 );
217 CPPUNIT_TEST_SUITE_END( );
218 }; // class isAdministrator
220 /** testing the method:
221 inline oslSecurity getHandle() const;
223 class getHandle : public CppUnit::TestFixture
225 public:
226 bool bRes;
228 void getHandle_001( )
230 ::osl::Security aSec;
231 bRes = aSec.isAdministrator( ) == bool(osl_isAdministrator( aSec.getHandle( ) ));
233 CPPUNIT_ASSERT_MESSAGE( "#test comment#: use getHandle function to call C API.",
234 bRes );
237 CPPUNIT_TEST_SUITE( getHandle );
238 CPPUNIT_TEST( getHandle_001 );
239 CPPUNIT_TEST_SUITE_END( );
240 }; // class getHandle
242 class UserProfile : public CppUnit::TestFixture
244 public:
246 void loadUserProfile( )
248 ::osl::Security aSec;
249 bool bValue = osl_loadUserProfile(aSec.getHandle());
251 CPPUNIT_ASSERT_MESSAGE( "empty function.", !bValue );
254 void unloadUserProfile( )
256 ::osl::Security aSec;
257 osl_unloadUserProfile(aSec.getHandle());
258 CPPUNIT_ASSERT_MESSAGE( "empty function.", true );
261 CPPUNIT_TEST_SUITE( UserProfile );
262 CPPUNIT_TEST( loadUserProfile );
263 CPPUNIT_TEST( unloadUserProfile );
264 CPPUNIT_TEST_SUITE_END( );
265 }; // class UserProfile
267 class loginUserOnFileServer : public CppUnit::TestFixture
269 public:
271 void loginUserOnFileServer_001( )
273 rtl::OUString suUserName;
274 rtl::OUString suPassword;
275 rtl::OUString suFileServer;
276 ::osl::Security aSec;
277 oslSecurity pSec = aSec.getHandle();
279 oslSecurityError erg = osl_loginUserOnFileServer(suUserName.pData, suPassword.pData, suFileServer.pData, &pSec);
281 CPPUNIT_ASSERT_MESSAGE( "empty function.", erg == osl_Security_E_UserUnknown );
284 CPPUNIT_TEST_SUITE( loginUserOnFileServer );
285 CPPUNIT_TEST( loginUserOnFileServer_001 );
286 CPPUNIT_TEST_SUITE_END( );
287 }; // class loginUserOnFileServer
289 CPPUNIT_TEST_SUITE_REGISTRATION(osl_Security::ctors);
290 CPPUNIT_TEST_SUITE_REGISTRATION(osl_Security::logonUser);
291 CPPUNIT_TEST_SUITE_REGISTRATION(osl_Security::getUserIdent);
292 CPPUNIT_TEST_SUITE_REGISTRATION(osl_Security::getUserName);
293 CPPUNIT_TEST_SUITE_REGISTRATION(osl_Security::getConfigDir);
294 CPPUNIT_TEST_SUITE_REGISTRATION(osl_Security::isAdministrator);
295 CPPUNIT_TEST_SUITE_REGISTRATION(osl_Security::getHandle);
296 CPPUNIT_TEST_SUITE_REGISTRATION(osl_Security::UserProfile);
297 CPPUNIT_TEST_SUITE_REGISTRATION(osl_Security::loginUserOnFileServer);
299 } // namespace osl_Security
301 /* This defines an own TestPlugIn implementation with an own initialize()
302 method that will be called after loading the PlugIn
304 #include <cppunit/plugin/TestPlugInDefaultImpl.h>
306 class MyTestPlugInImpl: public CPPUNIT_NS::TestPlugInDefaultImpl
308 public:
309 MyTestPlugInImpl() {};
310 void initialize( CPPUNIT_NS::TestFactoryRegistry *registry,
311 const CPPUNIT_NS::PlugInParameters &parameters ) SAL_OVERRIDE;
314 void MyTestPlugInImpl::initialize( CPPUNIT_NS::TestFactoryRegistry *,
315 const CPPUNIT_NS::PlugInParameters & )
317 /// start message
318 t_print("#Initializing ...\n" );
319 t_print("#\n#logonUser function need root/Administrator account to test.\n" );
320 t_print("#You can test by login with root/Administrator, and execute:\n" );
321 t_print("#testshl2 -forward \"username password\" ../../../wntmsci9/bin/Security.dll\n" );
322 t_print("# where username and password are forwarded account info.\n" );
323 t_print("#if no text forwarded, this function will be skipped.\n" );
325 /// get system information
326 #if ( defined UNX )
327 /// some initialization work for UNIX OS
329 struct passwd* pw;
330 CPPUNIT_ASSERT_MESSAGE( "getpwuid: no password entry\n",( pw = getpwuid( getuid() ) ) != NULL );
332 /// get user ID;
333 strUserID = OUString::number( getuid( ) );
335 /// get user Name;
336 strUserName = ::rtl::OUString::createFromAscii( pw->pw_name );
338 /// get home directory;
339 char *pw_dir = pw->pw_dir;
340 if( getenv( "FAKEROOTKEY" ) )
341 pw_dir = getenv("HOME");
342 CPPUNIT_ASSERT_MESSAGE( "#Convert from system path to URL failed.",
343 ::osl::File::E_None == ::osl::File::getFileURLFromSystemPath( ::rtl::OUString::createFromAscii( pw_dir ), strHomeDirectory ) );
345 /// get config directory;
346 strConfigDirectory = strHomeDirectory.copy(0);
348 /// is administrator;
349 if( !getuid( ) )
350 isAdmin = true;
352 #endif
353 #if defined ( WNT )
354 /// some initialization work for Windows OS
356 /// Get the user name, computer name, user home directory.
357 LPTSTR lpszSystemInfo; // pointer to system information string
358 DWORD cchBuff = BUFSIZE; // size of computer or user name
359 TCHAR tchBuffer[BUFSIZE]; // buffer for string
361 lpszSystemInfo = tchBuffer;
362 cchBuff = BUFSIZE;
363 if( GetUserNameA(lpszSystemInfo, &cchBuff) )
364 strUserName = ::rtl::OUString::createFromAscii( lpszSystemInfo );
366 if( GetComputerName(lpszSystemInfo, &cchBuff) )
367 strComputerName = ::rtl::OUString::createFromAscii( lpszSystemInfo );
369 /// Get user home directory.
370 HKEY hRegKey;
371 sal_Char PathA[_MAX_PATH];
372 ::rtl::OUString strHome;
373 if (RegOpenKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &hRegKey) == ERROR_SUCCESS)
375 LONG lRet, lSize = sizeof(PathA);
376 DWORD Type;
378 lRet = RegQueryValueEx(hRegKey, "AppData", NULL, &Type, ( unsigned char * )PathA, ( unsigned long * )&lSize);
379 if ( ( lRet == ERROR_SUCCESS ) && ( Type == REG_SZ ) && ( _access( PathA, 0 ) == 0 ) )
381 CPPUNIT_ASSERT_MESSAGE( "#Convert from system path to URL failed.",
382 ::osl::File::E_None == ::osl::File::getFileURLFromSystemPath( ::rtl::OUString::createFromAscii( PathA ), strConfigDirectory ) );
385 lRet = RegQueryValueEx(hRegKey, "Personal", NULL, &Type, ( unsigned char * )PathA, ( unsigned long * )&lSize);
386 if ( ( lRet == ERROR_SUCCESS ) && ( Type == REG_SZ ) && ( _access( PathA, 0 ) == 0 ) )
388 CPPUNIT_ASSERT_MESSAGE( "#Convert from system path to URL failed.",
389 ::osl::File::E_None == ::osl::File::getFileURLFromSystemPath( ::rtl::OUString::createFromAscii( PathA ), strHomeDirectory ) );
392 RegCloseKey(hRegKey);
395 /// Get user Security ID:
397 // Create buffers that may be large enough. If a buffer is too small, the count parameter will be set to the size needed.
398 const DWORD INITIAL_SIZE = 32;
399 DWORD cbSid = 0;
400 DWORD dwSidBufferSize = INITIAL_SIZE;
401 DWORD cchDomainName = 0;
402 DWORD dwDomainBufferSize = INITIAL_SIZE;
403 WCHAR * wszDomainName = NULL;
404 SID_NAME_USE eSidType;
405 DWORD dwErrorCode = 0;
407 LPCWSTR wszAccName = ( LPWSTR ) strUserName.getStr( );
409 // Create buffers for the SID and the domain name.
410 PSID pSid = (PSID) new BYTE[dwSidBufferSize];
411 CPPUNIT_ASSERT_MESSAGE("# creating SID buffer failed.\n", pSid!= NULL );
412 memset( pSid, 0, dwSidBufferSize);
414 wszDomainName = new WCHAR[dwDomainBufferSize];
415 CPPUNIT_ASSERT_MESSAGE("# creating Domain name buffer failed.\n", wszDomainName != NULL );
416 memset(wszDomainName, 0, dwDomainBufferSize*sizeof(WCHAR));
418 // Obtain the SID for the account name passed.
419 for ( ; ; )
421 // Set the count variables to the buffer sizes and retrieve the SID.
422 cbSid = dwSidBufferSize;
423 cchDomainName = dwDomainBufferSize;
424 if (LookupAccountNameW(
425 NULL, // Computer name. NULL for the local computer
426 wszAccName,
427 pSid, // Pointer to the SID buffer. Use NULL to get the size needed,
428 &cbSid, // Size of the SID buffer needed.
429 wszDomainName, // wszDomainName,
430 &cchDomainName,
431 &eSidType
434 if (IsValidSid( pSid) == FALSE)
435 wprintf(L"# The SID for %s is invalid.\n", wszAccName);
436 break;
438 dwErrorCode = GetLastError();
440 // Check if one of the buffers was too small.
441 if (dwErrorCode == ERROR_INSUFFICIENT_BUFFER)
443 if (cbSid > dwSidBufferSize)
445 // Reallocate memory for the SID buffer.
446 wprintf(L"# The SID buffer was too small. It will be reallocated.\n");
447 FreeSid( pSid);
448 pSid = (PSID) new BYTE[cbSid];
449 CPPUNIT_ASSERT_MESSAGE("# re-creating SID buffer failed.\n", pSid!= NULL );
450 memset( pSid, 0, cbSid);
451 dwSidBufferSize = cbSid;
453 if (cchDomainName > dwDomainBufferSize)
455 // Reallocate memory for the domain name buffer.
456 wprintf(L"# The domain name buffer was too small. It will be reallocated.\n");
457 delete [] wszDomainName;
458 wszDomainName = new WCHAR[cchDomainName];
459 CPPUNIT_ASSERT_MESSAGE("# re-creating domain name buffer failed.\n", wszDomainName!= NULL );
460 memset(wszDomainName, 0, cchDomainName*sizeof(WCHAR));
461 dwDomainBufferSize = cchDomainName;
464 else
466 wprintf(L"# LookupAccountNameW failed. GetLastError returned: %d\n", dwErrorCode);
467 break;
471 // now got SID successfully, only need to compare SID, so I copied the rest lines from source to convert SID to OUString.
472 PSID_IDENTIFIER_AUTHORITY psia;
473 DWORD dwSubAuthorities;
474 DWORD dwSidRev=SID_REVISION;
475 DWORD dwCounter;
476 DWORD dwSidSize;
477 sal_Char *Ident;
479 /* obtain SidIdentifierAuthority */
480 psia=GetSidIdentifierAuthority(pSid);
482 /* obtain sidsubauthority count */
483 dwSubAuthorities=std::min((int) *GetSidSubAuthorityCount(pSid), 5);
485 /* buffer length: S-SID_REVISION- + identifierauthority- + subauthorities- + NULL */
486 Ident=(sal_Char * )malloc(88*sizeof(sal_Char));
488 /* prepare S-SID_REVISION- */
489 dwSidSize=wsprintf(Ident, TEXT("S-%lu-"), dwSidRev);
491 /* prepare SidIdentifierAuthority */
492 if ((psia->Value[0] != 0) || (psia->Value[1] != 0))
494 dwSidSize+=wsprintf(Ident + strlen(Ident),
495 TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
496 (sal_uInt16)psia->Value[0],
497 (sal_uInt16)psia->Value[1],
498 (sal_uInt16)psia->Value[2],
499 (sal_uInt16)psia->Value[3],
500 (sal_uInt16)psia->Value[4],
501 (sal_uInt16)psia->Value[5]);
503 else
505 dwSidSize+=wsprintf(Ident + strlen(Ident),
506 TEXT("%lu"),
507 (sal_uInt32)(psia->Value[5] ) +
508 (sal_uInt32)(psia->Value[4] << 8) +
509 (sal_uInt32)(psia->Value[3] << 16) +
510 (sal_uInt32)(psia->Value[2] << 24) );
513 /* loop through SidSubAuthorities */
514 for (dwCounter=0; dwCounter < dwSubAuthorities; dwCounter++)
516 dwSidSize+=wsprintf(Ident + dwSidSize, TEXT("-%lu"),
517 *GetSidSubAuthority(pSid, dwCounter) );
520 strUserID = ::rtl::OUString::createFromAscii( Ident );
522 free(Ident);
523 delete [] reinterpret_cast<BYTE*>(pSid);
524 delete [] wszDomainName;
526 /// check if logged in user is administrator:
528 BOOL b;
529 SID_IDENTIFIER_AUTHORITY NtAuthority = { SECURITY_NT_AUTHORITY };
530 PSID AdministratorsGroup;
531 b = AllocateAndInitializeSid(
532 &NtAuthority,
534 SECURITY_BUILTIN_DOMAIN_RID,
535 DOMAIN_ALIAS_RID_ADMINS,
536 0, 0, 0, 0, 0, 0,
537 &AdministratorsGroup);
538 if(b)
540 if (!CheckTokenMembership( NULL, AdministratorsGroup, &b))
542 b = FALSE;
544 FreeSid(AdministratorsGroup);
547 isAdmin = ( sal_Bool )b;
549 #endif
551 /// print the information.
552 t_print("#\n#Retrieved system information is below:\n");
554 t_print("Computer Name: ");
555 if ( strComputerName.isEmpty())
556 t_print("Not retrieved\n" );
557 else
558 printUString( strComputerName );
560 t_print("Current User Name: ");
561 if ( strUserName.isEmpty())
562 t_print("Not retrieved\n" );
563 else
564 printUString( strUserName );
566 t_print("Current User Home Directory:");
567 if ( strHomeDirectory.isEmpty())
568 t_print("Not retrieved\n" );
569 else
570 printUString( strHomeDirectory );
572 t_print("Current Config Directory: ");
573 if ( strConfigDirectory.isEmpty())
574 t_print("Not retrieved\n" );
575 else
576 printUString( strConfigDirectory );
578 t_print("Current UserID: ");
579 if ( strUserID.isEmpty())
580 t_print("Not retrieved\n" );
581 else
582 printUString( strUserID );
584 t_print("Current User is: ");
585 if ( !isAdmin )
586 t_print("NOT Administrator.\n" );
587 else
588 t_print("Administrator.\n" );
590 /// get and display forwarded text if available.
591 rtl::OUString args[ 3 ];
592 int argsCount = 0;
593 sal_uInt32 n = rtl_getAppCommandArgCount();
594 for (sal_uInt32 i = 0; i < n; ++i)
596 rtl::OUString arg;
597 rtl_getAppCommandArg(i, &arg.pData);
598 if( arg.startsWith("-") )
599 continue;
600 if( argsCount >= 3 )
602 SAL_WARN( "sal.osl", "Too many test arguments" );
603 continue;
605 args[ argsCount++ ] = arg;
607 /// only forwarded two parameters, username and password.
608 if( argsCount == 2 )
610 aLogonUser = args[ 0 ];
611 t_print("\n#Forwarded username: ");
612 printUString( aLogonUser);
614 aLogonPasswd = args[ 1 ];
615 t_print("#Forwarded password: ");
616 for (int i = 0; i < aLogonPasswd.getLength(); ++i)
617 t_print("*");
618 t_print("\n" );
620 else if( argsCount == 3 )
621 /// forwarded three parameters, username, password and fileserver.
623 aLogonUser = args[ 0 ];
624 t_print("#Forwarded username: ");
625 printUString( aLogonUser);
627 aLogonPasswd = args[ 1 ];
628 t_print("#Forwarded password: ");
629 for (int i = 0; i < aLogonPasswd.getLength(); ++i)
630 t_print("*");
631 t_print("\n" );
633 aFileServer = args[ 2 ];
634 t_print("#Forwarded FileServer: ");
635 printUString( aFileServer );
637 t_print("#\n#Initialization Done.\n" );
641 /* Instantiate and register the own TestPlugIn and instantiate the default
642 main() function.
643 (This is done by CPPUNIT_PLUGIN_IMPLEMENT() for TestPlugInDefaultImpl)
646 CPPUNIT_PLUGIN_EXPORTED_FUNCTION_IMPL( MyTestPlugInImpl );
647 CPPUNIT_PLUGIN_IMPLEMENT_MAIN();
649 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */