diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2000-09-18 14:18:43 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2000-09-18 14:18:43 +0000 |
commit | 9399c662f36c385b0c705eb34e636a9aec450282 (patch) | |
tree | f502e9d9258960ff214ab90e98e31d0075e60196 /sal/osl/w32/security.c |
initial import
Diffstat (limited to 'sal/osl/w32/security.c')
-rw-r--r-- | sal/osl/w32/security.c | 1155 |
1 files changed, 1155 insertions, 0 deletions
diff --git a/sal/osl/w32/security.c b/sal/osl/w32/security.c new file mode 100644 index 000000000000..b7d9e60412a2 --- /dev/null +++ b/sal/osl/w32/security.c @@ -0,0 +1,1155 @@ +/************************************************************************* + * + * $RCSfile: security.c,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:17:23 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + + +#include "system.h" + +#include <osl/security.h> +#include <osl/diagnose.h> +#include <osl/thread.h> +#include "dirW9X.h" + +#include "secimpl.h" + + +/*****************************************************************************/ +/* Data Type Definition */ +/*****************************************************************************/ + + +/* Data for use in (un)LoadProfile Functions */ +/* Declarations based on USERENV.H for Windows 2000 Beta 2 */ +#define PI_NOUI 0x00000001 // Prevents displaying of messages +#define PI_APPLYPOLICY 0x00000002 // Apply NT4 style policy + +typedef struct _PROFILEINFOW { + DWORD dwSize; // Must be set to sizeof(PROFILEINFO) + DWORD dwFlags; // See flags above + LPWSTR lpUserName; // User name (required) + LPWSTR lpProfilePath; // Roaming profile path + LPWSTR lpDefaultPath; // Default user profile path + LPWSTR lpServerName; // Validating DC name in netbios format + LPWSTR lpPolicyPath; // Path to the NT4 style policy file + HANDLE hProfile; // Registry key handle - filled by function +} PROFILEINFOW, FAR * LPPROFILEINFOW; + +/* Typedefs for function pointers in USERENV.DLL */ +typedef BOOL (STDMETHODCALLTYPE FAR * LPFNLOADUSERPROFILE) ( + HANDLE hToken, + LPPROFILEINFOW lpProfileInfo +); + +typedef BOOL (STDMETHODCALLTYPE FAR * LPFNUNLOADUSERPROFILE) ( + HANDLE hToken, + HANDLE hProfile +); + +typedef BOOL (STDMETHODCALLTYPE FAR * LPFNGETUSERPROFILEDIR) ( + HANDLE hToken, + LPTSTR lpProfileDir, + LPDWORD lpcchSize +); + + +/*****************************************************************************/ +/* Static Module Function Declarations */ +/*****************************************************************************/ + +static sal_Bool isWNT(); +static sal_Bool GetSpecialFolder(rtl_uString **strPath,int nFolder); +static BOOL ObtainProfilePath(LPTSTR pszSid, LPTSTR pszProfilePath, DWORD dwPathSize); +static BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable); +static BOOL CheckHive(LPTSTR pszSid); +static BOOL Hive(LPTSTR pszSid, LPTSTR pszProfilePath, BOOL bLoad); +static sal_Bool SAL_CALL getUserNameImpl(oslSecurity Security, rtl_uString **strName, sal_Bool bIncludeDomain); + +/*****************************************************************************/ +/* Exported Module Functions */ +/*****************************************************************************/ + +oslSecurity SAL_CALL osl_getCurrentSecurity() +{ + oslSecurityImpl* pSecImpl = malloc(sizeof(oslSecurityImpl)); + + pSecImpl->m_pNetResource = NULL; + pSecImpl->m_User[0] = '\0'; + pSecImpl->m_hToken = NULL; + pSecImpl->m_hProfile = NULL; + + return ((oslSecurity)pSecImpl); +} + +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; + LUID luid; + + if (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; +} + +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); + userName = malloc(rtl_uString_getLength(strFileServer) + rtl_uString_getLength(strUserName) + 2); + + 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_isAdministrator(oslSecurity Security) +{ + if (Security != NULL) + { + /* ts: on Window 95 systems any user seems to be an adminstrator */ + if (!isWNT()) + { + return(sal_True); + } + else + { + HANDLE hAccessToken = ((oslSecurityImpl*)Security)->m_hToken; + UCHAR InfoBuffer[1024]; + PTOKEN_GROUPS ptgGroups = (PTOKEN_GROUPS)InfoBuffer; + DWORD dwInfoBufferSize; + PSID psidAdministrators; + SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY; + UINT x; + sal_Bool bSuccess = sal_False; + + + if (hAccessToken == NULL) + OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hAccessToken); + + if (GetTokenInformation(hAccessToken, TokenGroups, + InfoBuffer, 1024, + &dwInfoBufferSize)) + { + if (AllocateAndInitializeSid(&siaNtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &psidAdministrators)) + { + for (x = 0; (!bSuccess) && (x < ptgGroups->GroupCount); x++) + { + if (EqualSid(psidAdministrators, ptgGroups->Groups[x].Sid)) + bSuccess = sal_True; + } + + FreeSid(psidAdministrators); + } + } + + if (((oslSecurityImpl*)Security)->m_hToken == NULL) + CloseHandle(hAccessToken); + + return (bSuccess); + } + } + else + return (sal_False); +} + + +void SAL_CALL osl_freeSecurityHandle(oslSecurity Security) +{ + if (Security) + { + oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security; + + if (pSecImpl->m_pNetResource != NULL) + { + DWORD ret = WNetCancelConnection2W(pSecImpl->m_pNetResource->lpRemoteName, 0, sal_True); + + free(pSecImpl->m_pNetResource->lpRemoteName); + free(pSecImpl->m_pNetResource); + } + + if (pSecImpl->m_hToken) + CloseHandle(pSecImpl->m_hToken); + + if ( pSecImpl->m_hProfile ) + CloseHandle(pSecImpl->m_hProfile); + + free (pSecImpl); + } +} + + +sal_Bool SAL_CALL osl_getUserIdent(oslSecurity Security, rtl_uString **strIdent) +{ + if (Security != NULL) + { + oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security; + + HANDLE hAccessToken = pSecImpl->m_hToken; + + if (hAccessToken == NULL) + OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hAccessToken); + + if (hAccessToken) + { + sal_Char *Ident; + DWORD nInfoBuffer = 512; + UCHAR* pInfoBuffer = malloc(nInfoBuffer); + + + while (!GetTokenInformation(hAccessToken, TokenUser, + pInfoBuffer, nInfoBuffer, &nInfoBuffer)) + { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer); + else + { + free(pInfoBuffer); + pInfoBuffer = NULL; + break; + } + } + + if (pSecImpl->m_hToken == NULL) + CloseHandle(hAccessToken); + + if (pInfoBuffer) + { + PSID pSid = ((PTOKEN_USER)pInfoBuffer)->User.Sid; + PSID_IDENTIFIER_AUTHORITY psia; + DWORD dwSubAuthorities; + DWORD dwSidRev=SID_REVISION; + DWORD dwCounter; + DWORD dwSidSize; + + /* obtain SidIdentifierAuthority */ + psia=GetSidIdentifierAuthority(pSid); + + /* obtain sidsubauthority count */ + dwSubAuthorities=min(*GetSidSubAuthorityCount(pSid), 5); + + /* buffer length: S-SID_REVISION- + identifierauthority- + subauthorities- + NULL */ + Ident=malloc(88*sizeof(sal_Char)); + + /* prepare S-SID_REVISION- */ + dwSidSize=wsprintf(Ident, TEXT("S-%lu-"), dwSidRev); + + /* prepare SidIdentifierAuthority */ + if ((psia->Value[0] != 0) || (psia->Value[1] != 0)) + { + dwSidSize+=wsprintf(Ident + strlen(Ident), + TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"), + (USHORT)psia->Value[0], + (USHORT)psia->Value[1], + (USHORT)psia->Value[2], + (USHORT)psia->Value[3], + (USHORT)psia->Value[4], + (USHORT)psia->Value[5]); + } + else + { + dwSidSize+=wsprintf(Ident + strlen(Ident), + TEXT("%lu"), + (ULONG)(psia->Value[5] ) + + (ULONG)(psia->Value[4] << 8) + + (ULONG)(psia->Value[3] << 16) + + (ULONG)(psia->Value[2] << 24) ); + } + + /* loop through SidSubAuthorities */ + for (dwCounter=0; dwCounter < dwSubAuthorities; dwCounter++) + { + dwSidSize+=wsprintf(Ident + dwSidSize, TEXT("-%lu"), + *GetSidSubAuthority(pSid, dwCounter) ); + } + + rtl_uString_newFromAscii( strIdent, Ident ); + + free(pInfoBuffer); + free(Ident); + + return (sal_True); + } + } + else + { + DWORD needed=0; + sal_Unicode *Ident; + + WNetGetUserA(NULL, NULL, &needed); + needed = max( 16 , needed ); + Ident=malloc(needed*sizeof(sal_Unicode)); + + if (lpfnWNetGetUser(NULL, Ident, &needed) != NO_ERROR) + { + wcscpy(Ident, L"unknown"); + Ident[7] = L'\0'; + } + + rtl_uString_newFromStr( strIdent, Ident); + + free(Ident); + + return sal_True; + } + } + + return sal_False; +} + + + +sal_Bool SAL_CALL osl_getUserName(oslSecurity Security, rtl_uString **strName) +{ + return getUserNameImpl(Security, strName, sal_True); +} + + +sal_Bool SAL_CALL osl_getHomeDir(oslSecurity Security, rtl_uString **strDirectory) +{ + if (Security != NULL) + { + oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security; + + if (pSecImpl->m_pNetResource != NULL) + { + rtl_uString_newFromStr( strDirectory, pSecImpl->m_pNetResource->lpRemoteName); + + return (sal_True); + } + else + { +#if 0 + if (pSecImpl->m_hToken) + { + DWORD nInfoBuffer = 512; + UCHAR* pInfoBuffer = malloc(nInfoBuffer); + + while (!GetTokenInformation(pSecImpl->m_hToken, TokenUser, + pInfoBuffer, nInfoBuffer, &nInfoBuffer)) + { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer); + else + { + free(pInfoBuffer); + pInfoBuffer = NULL; + break; + } + } + + /* not implemented */ + OSL_ASSERT(sal_False); + + if (pInfoBuffer) + { + /* if (EqualSid() ... */ + + } + } + else +#endif + return (GetSpecialFolder(strDirectory, CSIDL_PERSONAL)); + } + } + + return sal_False; +} + +sal_Bool SAL_CALL osl_getConfigDir(oslSecurity Security, rtl_uString **strDirectory) +{ + if (Security != NULL) + { + oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security; + + if (pSecImpl->m_pNetResource != NULL) + { + rtl_uString_newFromStr( strDirectory, pSecImpl->m_pNetResource->lpRemoteName); + + return (sal_True); + } + else + { + if (pSecImpl->m_hToken) + { + /* not implemented */ + OSL_ASSERT(sal_False); + } + else + { + rtl_uString *file=0; + sal_Unicode sFile[_MAX_PATH]; + + if (! GetSpecialFolder(&file, CSIDL_APPDATA)) + { + OSL_VERIFY(lpfnGetWindowsDirectory(sFile, _MAX_DIR) > 0); + + rtl_uString_newFromStr( &file, sFile); + } + + rtl_uString_newFromString( strDirectory, file); + rtl_uString_release(file); + + return (sal_True); + } + } + } + + return sal_False; +} + + +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; + + LONG myError = 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; + DWORD nError = 0; + + /* 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; + } + else + nError = GetLastError(); + + rtl_uString_release(buffer); + } + + FreeLibrary(hUserEnvLib); + } + + if (hAccessToken && (hAccessToken != ((oslSecurityImpl*)Security)->m_hToken)) + CloseHandle(hAccessToken); + } + + return bOk; +} + + +void SAL_CALL osl_unloadUserProfile(oslSecurity Security) +{ + if ( ((oslSecurityImpl*)Security)->m_hProfile != NULL ) + { + HMODULE hUserEnvLib = NULL; + LPFNLOADUSERPROFILE fLoadUserProfile = NULL; + LPFNUNLOADUSERPROFILE fUnloadUserProfile = NULL; + BOOL bOk = FALSE; + HANDLE hAccessToken = ((oslSecurityImpl*)Security)->m_hToken; + + 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 = LoadLibrary("userenv.dll"); + + if (hUserEnvLib) + { + fLoadUserProfile = (LPFNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "LoadUserProfileA"); + fUnloadUserProfile = (LPFNUNLOADUSERPROFILE)GetProcAddress(hUserEnvLib, "UnloadUserProfile"); + + if (fLoadUserProfile && fUnloadUserProfile) + { + /* unloading the user profile */ + if (fLoadUserProfile && fUnloadUserProfile) + bOk = fUnloadUserProfile(hAccessToken, ((oslSecurityImpl*)Security)->m_hProfile); + + if (hUserEnvLib) + FreeLibrary(hUserEnvLib); + } + } + + ((oslSecurityImpl*)Security)->m_hProfile; + + if (hAccessToken && (hAccessToken != ((oslSecurityImpl*)Security)->m_hToken)) + { + CloseHandle(hAccessToken); + } + } +} + +/*****************************************************************************/ +/* Static Module Functions */ +/*****************************************************************************/ + + +static sal_Bool GetSpecialFolder(rtl_uString **strPath, int nFolder) +{ + sal_Bool bRet = sal_False; + HINSTANCE hLibrary; + sal_Char PathA[_MAX_PATH]; + sal_Unicode PathW[_MAX_PATH]; + + if ((hLibrary = LoadLibrary("shell32.dll")) != NULL) + { + BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL); + BOOL (WINAPI *pSHGetSpecialFolderPathW)(HWND, LPWSTR, int, BOOL); + + if (pSHGetSpecialFolderPathA = (BOOL (WINAPI *)(HWND, LPSTR, int, BOOL))GetProcAddress(hLibrary, "SHGetSpecialFolderPathA")) + { + if (pSHGetSpecialFolderPathA(GetActiveWindow(), PathA, nFolder, TRUE)) + { + rtl_string2UString( strPath, PathA, strlen(PathA), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS); + bRet = sal_True; + } + } + else if (pSHGetSpecialFolderPathW = (BOOL (WINAPI *)(HWND, LPWSTR, int, BOOL))GetProcAddress(hLibrary, "SHGetSpecialFolderPathW")) + { + if (pSHGetSpecialFolderPathW(GetActiveWindow(), PathW, nFolder, TRUE)) + { + rtl_uString_newFromStr( strPath, PathW); + bRet = sal_True; + } + } + else + { + HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *) = (HRESULT (WINAPI *)(HWND, int, LPITEMIDLIST *))GetProcAddress(hLibrary, "SHGetSpecialFolderLocation"); + BOOL (WINAPI *pSHGetPathFromIDListA)(LPCITEMIDLIST, LPSTR) = (BOOL (WINAPI *)(LPCITEMIDLIST, LPSTR))GetProcAddress(hLibrary, "SHGetPathFromIDListA"); + BOOL (WINAPI *pSHGetPathFromIDListW)(LPCITEMIDLIST, LPWSTR) = (BOOL (WINAPI *)(LPCITEMIDLIST, LPWSTR))GetProcAddress(hLibrary, "SHGetPathFromIDListW"); + HRESULT (WINAPI *pSHGetMalloc)(LPMALLOC *) = (HRESULT (WINAPI *)(LPMALLOC *))GetProcAddress(hLibrary, "SHGetMalloc"); + + + if (pSHGetSpecialFolderLocation && (pSHGetPathFromIDListA || pSHGetPathFromIDListW ) && pSHGetMalloc ) + { + LPITEMIDLIST pidl; + LPMALLOC pMalloc; + HRESULT hr; + + hr = pSHGetSpecialFolderLocation(GetActiveWindow(), nFolder, &pidl); + + /* Get SHGetSpecialFolderLocation fails if directory does not exists. */ + /* If it fails we try to create the directory and redo the call */ + if (! SUCCEEDED(hr)) + { + HKEY hRegKey; + + if (RegOpenKey(HKEY_CURRENT_USER, + "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", + &hRegKey) == ERROR_SUCCESS) + { + LONG lRet, lSize = sizeof(PathW); + DWORD Type; + + switch (nFolder) + { + case CSIDL_APPDATA: + lRet = RegQueryValueEx(hRegKey, "AppData", NULL, &Type, PathA, &lSize); + break; + + case CSIDL_PERSONAL: + lRet = RegQueryValueEx(hRegKey, "Personal", NULL, &Type, PathA, &lSize); + break; + + default: + lRet = -1l; + } + + if ((lRet == ERROR_SUCCESS) && (Type == REG_SZ)) + { + if (_access(PathA, 0) < 0) + CreateDirectory(PathA, NULL); + + hr = pSHGetSpecialFolderLocation(GetActiveWindow(), nFolder, &pidl); + } + + RegCloseKey(hRegKey); + } + } + + if (SUCCEEDED(hr)) + { + if (pSHGetPathFromIDListW && pSHGetPathFromIDListW(pidl, PathW)) + { + /* if directory does not exist, create it */ + if (_waccess(PathW, 0) < 0) + lpfnCreateDirectory(PathW, NULL); + + rtl_uString_newFromStr( strPath, PathW); + bRet = sal_True; + } + else if (pSHGetPathFromIDListA && pSHGetPathFromIDListA(pidl, PathA)) + { + /* if directory does not exist, create it */ + if (_access(PathA, 0) < 0) + CreateDirectoryA(PathA, NULL); + + rtl_string2UString( strPath, PathA, strlen(PathA), osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS); + bRet = sal_True; + } + } + + if (SUCCEEDED(pSHGetMalloc(&pMalloc))) + { + pMalloc->lpVtbl->Free(pMalloc, pidl); + pMalloc->lpVtbl->Release(pMalloc); + } + } + } + } + + FreeLibrary(hLibrary); + + return (bRet); +} + + +static sal_Bool isWNT() +{ + static sal_Bool isInit = sal_False; + static sal_Bool isWNT = sal_False; + + if (!isInit) + { + OSVERSIONINFO VersionInformation = + + { + sizeof(OSVERSIONINFO), + 0, + 0, + 0, + 0, + "", + }; + + if ( + GetVersionEx(&VersionInformation) && + (VersionInformation.dwPlatformId == VER_PLATFORM_WIN32_NT) + ) + { + isWNT = sal_True; + } + + isInit = sal_True; + } + + return(isWNT); +} + + +static BOOL ObtainProfilePath(LPTSTR strSid, LPTSTR strProfilePath, DWORD dwPathSize) +{ + TCHAR szRegKey[1024] = TEXT("SOFTWARE\\Microsoft\\"); + TCHAR szTemp[256] = TEXT(""); + DWORD dwSizeProfilePath = dwPathSize; + DWORD dwType; + HKEY hKey; + LONG lErrorCode; + + /* + concat sid + */ + strcat(szRegKey, TEXT("Windows NT\\CurrentVersion\\ProfileList\\")); + strcat(szRegKey, strSid); + + /* + find the hive in the registry + */ + lErrorCode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_READ, &hKey); + if (lErrorCode != ERROR_SUCCESS) + return FALSE; + + /* + query the value + */ + lErrorCode = RegQueryValueEx(hKey, TEXT("ProfileImagePath"), NULL, &dwType, (LPBYTE)strProfilePath, &dwSizeProfilePath); + if (lErrorCode != ERROR_SUCCESS) + return FALSE; + + /* + fix profile path by replacing "%SystemRoot%" with the actual path + */ + strcpy(szTemp, strProfilePath); + ZeroMemory(strProfilePath, dwPathSize); + if (!ExpandEnvironmentStrings(szTemp, strProfilePath,dwPathSize)) + return FALSE; + + /* + determine if it is a file or directory, WinNT 4.0 it is a + directory + WinNT 3.51 it is a file + */ + if ((GetFileAttributes(strProfilePath) & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) + strcat(strProfilePath, TEXT("\\ntuser.dat")); + + /* + close the key + */ + lErrorCode = RegCloseKey(hKey); + if (lErrorCode != ERROR_SUCCESS) + return FALSE; + + return TRUE; +} + +static BOOL Privilege(LPTSTR strPrivilege, BOOL bEnable) +{ + HANDLE hToken; + TOKEN_PRIVILEGES tp; + + /* + obtain the processes token + */ + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) + return FALSE; + + /* + get the luid + */ + if (!LookupPrivilegeValue(NULL, strPrivilege, &tp.Privileges[0].Luid)) + return FALSE; + + tp.PrivilegeCount = 1; + + if (bEnable) + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + else + tp.Privileges[0].Attributes = 0; + + /* + enable or disable the privilege + */ + if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0)) + return FALSE; + + if (!CloseHandle(hToken)) + return FALSE; + + return TRUE; +} + +static BOOL Hive(LPTSTR strSid, LPTSTR strProfilePath, BOOL bLoad) +{ + LONG lErrorCode; + + if (bLoad) + { + lErrorCode = RegLoadKey(HKEY_USERS, strSid, strProfilePath); + if (lErrorCode != ERROR_SUCCESS) + return FALSE; + } + else + { + lErrorCode = RegUnLoadKey(HKEY_USERS, strSid); + if (lErrorCode != ERROR_SUCCESS) + return FALSE; + } + return TRUE; +} + +static BOOL CheckHive(LPTSTR strSid) +{ + LONG lErrorCode; + HKEY hKey = NULL; + + lErrorCode = RegOpenKey(HKEY_USERS, strSid, &hKey); + + if (lErrorCode == ERROR_SUCCESS) + { + lErrorCode = RegCloseKey(hKey); + return TRUE; + } + return FALSE; +} + +static sal_Bool SAL_CALL getUserNameImpl(oslSecurity Security, rtl_uString **strName, sal_Bool bIncludeDomain) +{ + if (Security != NULL) + { + oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security; + + HANDLE hAccessToken = pSecImpl->m_hToken; + + if (hAccessToken == NULL) + OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hAccessToken); + + if (hAccessToken) + { + DWORD nInfoBuffer = 512; + UCHAR* pInfoBuffer = malloc(nInfoBuffer); + + while (!GetTokenInformation(hAccessToken, TokenUser, + pInfoBuffer, nInfoBuffer, &nInfoBuffer)) + { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer); + else + { + free(pInfoBuffer); + pInfoBuffer = NULL; + break; + } + } + + if (pSecImpl->m_hToken == NULL) + CloseHandle(hAccessToken); + + if (pInfoBuffer) + { + sal_Unicode UserName[128]; + sal_Unicode DomainName[128]; + sal_Unicode Name[257]; + DWORD nUserName = sizeof(UserName); + DWORD nDomainName = sizeof(DomainName); + SID_NAME_USE sUse; + + if (LookupAccountSidW(NULL, ((PTOKEN_USER)pInfoBuffer)->User.Sid, + UserName, &nUserName, + DomainName, &nDomainName, &sUse)) + { + if (bIncludeDomain) + { + wcscpy(Name, DomainName); + wcscat(Name, L"/"); + wcscat(Name, UserName); + } + else + { + wcscpy(Name, UserName); + } + } + rtl_uString_newFromStr( strName, Name); + + free(pInfoBuffer); + + return (sal_True); + } + } + else + { + DWORD needed=0; + sal_Unicode *pNameW=NULL; + + lpfnWNetGetUser(NULL, NULL, &needed); + pNameW = malloc (needed*sizeof(sal_Unicode)); + + if (lpfnWNetGetUser(NULL, pNameW, &needed) == NO_ERROR) + { + rtl_uString_newFromStr( strName, pNameW); + + if (pNameW) + free(pNameW); + return (sal_True); + } + else + if (wcslen(pSecImpl->m_User) > 0) + { + rtl_uString_newFromStr( strName, pSecImpl->m_pNetResource->lpRemoteName); + + if (pNameW) + free(pNameW); + + return (sal_True); + } + + if (pNameW) + free(pNameW); + } + } + + return sal_False; +} + +/************************************************************************* +* +* $Log: not supported by cvs2svn $ +* Revision 1.30 2000/09/18 14:29:02 willem.vandorp +* OpenOffice header added. +* +* Revision 1.29 2000/08/28 14:04:03 cd +* #78211# use correct malloc size for WNetGetUser call +* +* Revision 1.28 2000/06/08 10:07:55 cd +* change LogonUserW call +* +* Revision 1.27 2000/06/08 09:16:36 cd +* initialize string pointer with zero +* +* Revision 1.26 2000/05/30 11:29:42 obr +* lstrcpyW, ... not functional in Win95 +* +* Revision 1.25 2000/05/22 15:30:35 obr +* moved some unicode wrapper for 9x to kernel9x.lib +* +* Revision 1.24 2000/05/16 07:46:05 obr +* Unicode bugfixes +* +* Revision 1.23 2000/05/15 15:14:11 mba +* first UniCode Bugfixes +* +* Revision 1.22 2000/03/31 16:28:09 rs +* UNICODE-Changes +* +* Revision 1.21 1999/12/09 14:21:01 ts +* #70662# m_hProfile not initialized +* +* Revision 1.20 1999/11/19 15:22:38 ts +* load user profile before executing processes as user +* +* Revision 1.19 1999/11/18 09:35:51 mfe +* loadUserprofile moved from process.c to security.c +* +* Revision 1.18 1999/10/27 15:13:36 mfe +* Change of Copyright, removed compiler warnings, code clean up, ... +* +* Revision 1.17 1999/04/26 12:01:41 jsc +* #65104# GetSpecialFolder angepasst +* +* Revision 1.16 1999/03/19 10:32:24 ts +* #63572# Win95: logon user geht jetz immer, sdaemon hidden starten +* +* Revision 1.15 1999/03/04 10:01:23 rh +* #62429 code cleanup +* +* Revision 1.14 1999/02/15 13:32:32 ts +* #61287# unter W95 gilt jeder Benutzer als Administrator +* +* Revision 1.13 1999/02/15 13:26:10 ts +* #61287# unter W95 gilt jeder Benutzer als Administrator +* +* Revision 1.12 1999/02/11 16:16:40 rh +* #61556 Bugfix getUserIdent - convert SID to text string +* +* Revision 1.11 1999/01/20 19:09:50 jsc +* #61011# Typumstellung +* +* Revision 1.10 1998/12/08 13:41:05 ts +* #52712# Pipe-Bugs unter NT behoben +* +* Revision 1.9 1998/09/21 09:28:47 rh +* #56688# Create special folder if not exists +* +* Revision 1.8 1998/09/19 16:32:30 rh +* #56688# Inidateien suchen +* +* Revision 1.7 1998/09/18 15:33:44 rh +* #56761# neue locations f?r cfg/ini files +* +* Revision 1.6 1998/03/13 15:07:45 rh +* Cleanup of enum chaos and implemntation of pipes +* +* Revision 1.5 1998/02/16 19:34:59 rh +* Cleanup of ports, integration of Size_t, features for process +* +* Revision 1.4 1997/10/21 14:23:09 ts +* Abfrage, ob ein Benutzer Adminstratorrechte hat eingebaut +* +* Revision 1.3 1997/10/17 16:01:37 ts +* osl_logonUserOnFileServer hinzugefuegt +* +* Revision 1.2 1997/07/24 15:19:59 ts +* *** empty log message *** +* +* Revision 1.1 1997/07/23 12:00:13 rh +* added +* +*************************************************************************/ + + |