oslSecurityError SAL_CALL osl_loginUser( rtl_uString *strUserName, rtl_uString *strPasswd, oslSecurity *pSecurity ) { oslSecurityError ret; if (!isWNT()) { *pSecurity = osl_getCurrentSecurity(); ret = osl_Security_E_None; } else { sal_Unicode* strUser; sal_Unicode* strDomain = _wcsdup(rtl_uString_getStr(strUserName)); HANDLE hUserToken; #if OSL_DEBUG_LEVEL > 0 LUID luid; #endif if (NULL != (strUser = wcschr(strDomain, L'/'))) *strUser++ = L'\0'; else { strUser = strDomain; strDomain = NULL; } // this process must have the right: 'act as a part of operatingsystem' OSL_ASSERT(LookupPrivilegeValue(NULL, SE_TCB_NAME, &luid)); if (LogonUserW(strUser, strDomain ? strDomain : L"", rtl_uString_getStr(strPasswd), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hUserToken)) { oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl)); pSecImpl->m_pNetResource = NULL; pSecImpl->m_hToken = hUserToken; pSecImpl->m_hProfile = NULL; wcscpy(pSecImpl->m_User, strUser); *pSecurity = (oslSecurity)pSecImpl; ret = osl_Security_E_None; } else ret = osl_Security_E_UserUnknown; if (strDomain) free(strDomain); else free(strUser); } return ret; }
oslPipe SAL_CALL osl_createPipe(rtl_uString *ustrPipeName, oslPipeOptions Options, oslSecurity Security) { oslPipe pPipe=0; rtl_String* strPipeName=0; sal_Char* pszPipeName=0; if ( ustrPipeName != 0 ) { rtl_uString2String( &strPipeName, rtl_uString_getStr(ustrPipeName), rtl_uString_getLength(ustrPipeName), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS ); pszPipeName = rtl_string_getStr(strPipeName); pPipe = osl_psz_createPipe(pszPipeName, Options, Security); if ( strPipeName != 0 ) { rtl_string_release(strPipeName); } } return pPipe; }
/* Path of the application, with trailing slash. */ static rtl_uString * get_app_path( const char *pAppExec ) { char pRealPath[PATH_MAX]; rtl_uString *pResult; sal_Int32 len; char* dummy; char *pOrigPath = strdup( pAppExec ); char *pPath = dirname( pOrigPath ); dummy = realpath( pPath, pRealPath ); (void)dummy; pResult = charp_to_ustr( pRealPath ); free( pOrigPath ); len = rtl_uString_getLength(pResult); if (len > 0 && rtl_uString_getStr(pResult)[len - 1] != '/') { rtl_uString *pSlash = NULL; rtl_uString_newFromAscii(&pSlash, "/"); rtl_uString_newConcat(&pResult, pResult, pSlash); rtl_uString_release(pSlash); } return pResult; }
/* Compute the OOo md5 hash from 'pText' */ static rtl_uString * get_md5hash( rtl_uString *pText ) { rtl_uString *pResult = NULL; sal_Int32 nCapacity = 100; unsigned char *pData = NULL; sal_uInt32 nSize = 0; rtlDigest digest; sal_uInt32 md5_key_len = 0; sal_uInt8* md5_buf = NULL; sal_uInt32 i = 0; #if OSL_DEBUG_LEVEL > 1 rtl_String *pOut; #endif if ( !pText ) return NULL; #if OSL_DEBUG_LEVEL > 1 pOut = ustr_to_str( pText ); fprintf (stderr, "Generate pipe md5 for '%s'\n", pOut->buffer); rtl_string_release( pOut ); #endif pData = (unsigned char *)rtl_uString_getStr( pText ); nSize = rtl_uString_getLength( pText ) * sizeof( sal_Unicode ); if ( !pData ) return NULL; digest = rtl_digest_create( rtl_Digest_AlgorithmMD5 ); if ( digest == 0 ) return NULL; md5_key_len = rtl_digest_queryLength( digest ); md5_buf = (sal_uInt8 *)calloc( md5_key_len, sizeof( sal_uInt8 ) ); rtl_digest_init( digest, pData , nSize ); rtl_digest_update( digest, pData, nSize ); rtl_digest_get( digest, md5_buf, md5_key_len ); rtl_digest_destroy( digest ); /* create hex-value string from the MD5 value to keep the string size minimal */ rtl_uString_new_WithLength( &pResult, nCapacity ); for ( ; i < md5_key_len; ++i ) { char val[3]; snprintf( val, 3, "%x", md5_buf[i] ); /* sic! we ignore some of the 0's */ rtl_uStringbuffer_insert_ascii( &pResult, &nCapacity, rtl_uString_getLength( pResult ), val, strlen( val ) ); } /* cleanup */ free( md5_buf ); return pResult; }
/* Easier conversions: rtl_uString to rtl_String */ static rtl_String * ustr_to_str( rtl_uString *pStr ) { rtl_String *pOut = NULL; rtl_uString2String( &pOut, rtl_uString_getStr( pStr ), rtl_uString_getLength( pStr ), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS ); return pOut; }
oslSecurityError SAL_CALL osl_loginUserOnFileServer(rtl_uString *strUserName, rtl_uString *strPasswd, rtl_uString *strFileServer, oslSecurity *pSecurity) { oslSecurityError ret; DWORD err; NETRESOURCEW netResource; sal_Unicode* remoteName; sal_Unicode* userName; remoteName = malloc((rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 4) * sizeof(sal_Unicode)); userName = malloc((rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 2) * sizeof(sal_Unicode)); wcscpy(remoteName, L"\\\\"); wcscat(remoteName, rtl_uString_getStr(strFileServer)); wcscat(remoteName, L"\\"); wcscat(remoteName, rtl_uString_getStr(strUserName)); wcscpy(userName, rtl_uString_getStr(strFileServer)); wcscat(userName, L"\\"); wcscat(userName, rtl_uString_getStr(strUserName)); netResource.dwScope = RESOURCE_GLOBALNET; netResource.dwType = RESOURCETYPE_DISK; netResource.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE; netResource.dwUsage = RESOURCEUSAGE_CONNECTABLE; netResource.lpLocalName = NULL; netResource.lpRemoteName = remoteName; netResource.lpComment = NULL; netResource.lpProvider = NULL; err = WNetAddConnection2W(&netResource, rtl_uString_getStr(strPasswd), userName, 0); if ((err == NO_ERROR) || (err == ERROR_ALREADY_ASSIGNED)) { oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl)); pSecImpl->m_pNetResource = malloc(sizeof(NETRESOURCE)); *pSecImpl->m_pNetResource = netResource; pSecImpl->m_hToken = NULL; pSecImpl->m_hProfile = NULL; wcscpy(pSecImpl->m_User, rtl_uString_getStr(strUserName)); *pSecurity = (oslSecurity)pSecImpl; ret = osl_Security_E_None; } else ret = osl_Security_E_UserUnknown; free(remoteName); free(userName); return ret; }
sal_Bool SAL_CALL osl_loadUserProfile(oslSecurity Security) { /* CreateProcessAsUser does not load the specified user's profile into the HKEY_USERS registry key. This means that access to information in the HKEY_CURRENT_USER registry key may not produce results consistent with a normal interactive logon. It is your responsibility to load the user's registry hive into HKEY_USERS with the LoadUserProfile function before calling CreateProcessAsUser. */ BOOL bOk = FALSE; RegCloseKey(HKEY_CURRENT_USER); if (Privilege(SE_RESTORE_NAME, TRUE)) { HMODULE hUserEnvLib = NULL; LPFNLOADUSERPROFILE fLoadUserProfile = NULL; LPFNUNLOADUSERPROFILE fUnloadUserProfile = NULL; HANDLE hAccessToken = ((oslSecurityImpl*)Security)->m_hToken; /* try to create user profile */ if ( !hAccessToken ) { /* retrieve security handle if not done before e.g. osl_getCurrentSecurity() */ HANDLE hProcess = GetCurrentProcess(); if (hProcess != NULL) { OpenProcessToken(hProcess, TOKEN_IMPERSONATE, &hAccessToken); CloseHandle(hProcess); } } hUserEnvLib = LoadLibraryA("userenv.dll"); if (hUserEnvLib) { fLoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "LoadUserProfileW"); fUnloadUserProfile = (LPFNUNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "UnloadUserProfile"); if (fLoadUserProfile && fUnloadUserProfile) { rtl_uString *buffer = 0; PROFILEINFOW pi; getUserNameImpl(Security, &buffer, sal_False); ZeroMemory( &pi, sizeof(pi) ); pi.dwSize = sizeof(pi); pi.lpUserName = rtl_uString_getStr(buffer); pi.dwFlags = PI_NOUI; if (fLoadUserProfile(hAccessToken, &pi)) { fUnloadUserProfile(hAccessToken, pi.hProfile); bOk = TRUE; } rtl_uString_release(buffer); } FreeLibrary(hUserEnvLib); } if (hAccessToken && (hAccessToken != ((oslSecurityImpl*)Security)->m_hToken)) CloseHandle(hAccessToken); } return (sal_Bool)bOk; }
/* Send args to the OOo instance (using the 'fd' file descriptor) */ static sal_Bool send_args( int fd, rtl_uString *pCwdPath ) { rtl_uString *pBuffer = NULL, *pTmp = NULL; sal_Int32 nCapacity = 1000; rtl_String *pOut = NULL; sal_Bool bResult; size_t nLen; rtl_uString *pEscapedCwdPath = escape_path( pCwdPath ); sal_uInt32 nArg = 0; sal_uInt32 nArgCount = rtl_getAppCommandArgCount(); rtl_uString_new_WithLength( &pBuffer, nCapacity ); rtl_uString_new( &pTmp ); rtl_uStringbuffer_insert_ascii( &pBuffer, &nCapacity, rtl_uString_getLength( pBuffer ), RTL_CONSTASCII_STRINGPARAM( "InternalIPC::Arguments" ) ); if ( rtl_uString_getLength( pEscapedCwdPath ) ) { rtl_uStringbuffer_insert_ascii( &pBuffer, &nCapacity, rtl_uString_getLength( pBuffer ), RTL_CONSTASCII_STRINGPARAM( "1" ) ); rtl_uStringbuffer_insert( &pBuffer, &nCapacity, rtl_uString_getLength( pBuffer ), rtl_uString_getStr( pEscapedCwdPath ), rtl_uString_getLength( pEscapedCwdPath ) ); } else { rtl_uStringbuffer_insert_ascii( &pBuffer, &nCapacity, rtl_uString_getLength( pBuffer ), RTL_CONSTASCII_STRINGPARAM( "0" ) ); } for ( nArg = 0; nArg < nArgCount; ++nArg ) { rtl_uString *pEscapedTmp = NULL; rtl_uStringbuffer_insert_ascii( &pBuffer, &nCapacity, rtl_uString_getLength( pBuffer ), ",", 1 ); rtl_getAppCommandArg( nArg, &pTmp ); pEscapedTmp = escape_path( pTmp ); rtl_uStringbuffer_insert( &pBuffer, &nCapacity, rtl_uString_getLength( pBuffer ), rtl_uString_getStr( pEscapedTmp ), rtl_uString_getLength( pEscapedTmp ) ); rtl_uString_release( pEscapedTmp ); } if ( !rtl_convertUStringToString( &pOut, rtl_uString_getStr( pBuffer ), rtl_uString_getLength( pBuffer ), RTL_TEXTENCODING_UTF8, ( RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR ) ) ) { fprintf( stderr, "ERROR: cannot convert arguments to UTF-8\n" ); exit( 1 ); } nLen = rtl_string_getLength( pOut ) + 1; bResult = ( write( fd, rtl_string_getStr( pOut ), nLen ) == (ssize_t) nLen ); if ( bResult ) { char resp[ strlen( "InternalIPC::ProcessingDone" ) ]; ssize_t n = read( fd, resp, SAL_N_ELEMENTS( resp ) ); bResult = n == (ssize_t) SAL_N_ELEMENTS( resp ) && (memcmp( resp, "InternalIPC::ProcessingDone", SAL_N_ELEMENTS( resp ) ) == 0); } /* cleanup */ rtl_uString_release( pEscapedCwdPath ); rtl_uString_release( pBuffer ); rtl_uString_release( pTmp ); rtl_string_release( pOut ); return bResult; }
static oslFileError osl_create_temp_file_impl_( const rtl_uString* pustr_base_directory, oslFileHandle* file_handle, rtl_uString** ppustr_temp_file_name) { rtl_uString* rand_name = 0; sal_uInt32 len_base_dir = 0; rtl_uString* tmp_file_path = 0; rtl_uString* tmp_file_url = 0; sal_Int32 capacity = 0; oslFileError osl_error = osl_File_E_None; sal_Int32 offset_file_name; const sal_Unicode* puchr; OSL_PRECOND(pustr_base_directory, "Invalid Parameter"); OSL_PRECOND(file_handle, "Invalid Parameter"); OSL_PRECOND(ppustr_temp_file_name, "Invalid Parameter"); len_base_dir = rtl_uString_getLength(pustr_base_directory); rtl_uStringbuffer_newFromStr_WithLength( &tmp_file_path, rtl_uString_getStr((rtl_uString*)pustr_base_directory), len_base_dir); rtl_uStringbuffer_ensureCapacity( &tmp_file_path, &capacity, (len_base_dir + 1 + RAND_NAME_LENGTH)); offset_file_name = len_base_dir; puchr = rtl_uString_getStr(tmp_file_path); /* ensure that the last character is a '/' */ if ((sal_Unicode)'/' != puchr[len_base_dir - 1]) { rtl_uStringbuffer_insert_ascii( &tmp_file_path, &capacity, len_base_dir, "/", 1); offset_file_name++; } while(1) /* try until success */ { osl_gen_random_name_impl_(&rand_name); rtl_uStringbuffer_insert( &tmp_file_path, &capacity, offset_file_name, rtl_uString_getStr(rand_name), rtl_uString_getLength(rand_name)); osl_error = osl_getFileURLFromSystemPath( tmp_file_path, &tmp_file_url); if (osl_File_E_None == osl_error) { /* RW permission for the user only! */ mode_t old_mode = umask(077); osl_error = osl_openFile( tmp_file_url, file_handle, osl_File_OpenFlag_Read | osl_File_OpenFlag_Write | osl_File_OpenFlag_Create); umask(old_mode); } /* in case of error osl_File_E_EXIST we simply try again else we give up */ if ((osl_File_E_None == osl_error) || (osl_error != osl_File_E_EXIST)) { if (rand_name) rtl_uString_release(rand_name); if (tmp_file_url) rtl_uString_release(tmp_file_url); break; } } /* while(1) */ if (osl_File_E_None == osl_error) rtl_uString_assign(ppustr_temp_file_name, tmp_file_path); if (tmp_file_path) rtl_uString_release(tmp_file_path); return osl_error; }
oslProcessError SAL_CALL osl_executeProcess_WithRedirectedIO( rtl_uString *ustrImageName, rtl_uString *ustrArguments[], sal_uInt32 nArguments, oslProcessOption Options, oslSecurity Security, rtl_uString *ustrWorkDir, rtl_uString *ustrEnvironment[], sal_uInt32 nEnvironmentVars, oslProcess *pProcess, oslFileHandle *pInputWrite, oslFileHandle *pOutputRead, oslFileHandle *pErrorRead ) { oslProcessError Error; sal_Char* pszWorkDir=0; sal_Char** pArguments=0; sal_Char** pEnvironment=0; unsigned int idx; char szImagePath[PATH_MAX] = ""; char szWorkDir[PATH_MAX] = ""; if ( ustrImageName && ustrImageName->length ) { FileURLToPath( szImagePath, PATH_MAX, ustrImageName ); } if ( ustrWorkDir != 0 && ustrWorkDir->length ) { FileURLToPath( szWorkDir, PATH_MAX, ustrWorkDir ); pszWorkDir = szWorkDir; } if ( pArguments == 0 && nArguments > 0 ) { pArguments = (sal_Char**) malloc( ( nArguments + 2 ) * sizeof(sal_Char*) ); } for ( idx = 0 ; idx < nArguments ; ++idx ) { rtl_String* strArg =0; rtl_uString2String( &strArg, rtl_uString_getStr(ustrArguments[idx]), rtl_uString_getLength(ustrArguments[idx]), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS ); pArguments[idx]=strdup(rtl_string_getStr(strArg)); rtl_string_release(strArg); pArguments[idx+1]=0; } for ( idx = 0 ; idx < nEnvironmentVars ; ++idx ) { rtl_String* strEnv=0; if ( pEnvironment == 0 ) { pEnvironment = (sal_Char**) malloc( ( nEnvironmentVars + 2 ) * sizeof(sal_Char*) ); } rtl_uString2String( &strEnv, rtl_uString_getStr(ustrEnvironment[idx]), rtl_uString_getLength(ustrEnvironment[idx]), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS ); pEnvironment[idx]=strdup(rtl_string_getStr(strEnv)); rtl_string_release(strEnv); pEnvironment[idx+1]=0; } Error = osl_psz_executeProcess(szImagePath, pArguments, Options, Security, pszWorkDir, pEnvironment, pProcess, pInputWrite, pOutputRead, pErrorRead ); if ( pArguments != 0 ) { for ( idx = 0 ; idx < nArguments ; ++idx ) { if ( pArguments[idx] != 0 ) { free(pArguments[idx]); } } free(pArguments); } if ( pEnvironment != 0 ) { for ( idx = 0 ; idx < nEnvironmentVars ; ++idx ) { if ( pEnvironment[idx] != 0 ) { free(pEnvironment[idx]); } } free(pEnvironment); } return Error; }