PVOID built(PSECURITY_DESCRIPTOR pSD) { PSID psidEveryone = NULL; PACL pDACL = NULL; BOOL bResult = FALSE; __try { SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY; //SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; if (!::InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) __leave; if (!::AllocateAndInitializeSid(&siaWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &psidEveryone)) __leave; DWORD dwAclLength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(psidEveryone); pDACL = (PACL)::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwAclLength); if (!pDACL) __leave; if (!::InitializeAcl(pDACL, dwAclLength, ACL_REVISION)) __leave; if (!::AddAccessAllowedAce(pDACL, ACL_REVISION, GENERIC_ALL, psidEveryone)) __leave; if (!::SetSecurityDescriptorDacl(pSD, TRUE, pDACL, FALSE)) __leave; bResult = TRUE; } __finally { if (psidEveryone) ::FreeSid(psidEveryone); } if (bResult == FALSE) { if (pDACL) ::HeapFree(::GetProcessHeap(), 0, pDACL); pDACL = NULL; } return (PVOID) pDACL; }
DWORD GetCurrentUserSID ( PSID *Sid) { TOKEN_USER *tokenUser = NULL; HANDLE tokenHandle; DWORD tokenSize; DWORD sidLength; if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &tokenHandle)) { GetTokenInformation (tokenHandle, TokenUser, tokenUser, 0, &tokenSize); tokenUser = (TOKEN_USER *) malloc (tokenSize); if (GetTokenInformation(tokenHandle, TokenUser, tokenUser, tokenSize, &tokenSize)) { sidLength = GetLengthSid (tokenUser->User.Sid); *Sid = (PSID) malloc (sidLength); memcpy (*Sid, tokenUser->User.Sid, sidLength); CloseHandle (tokenHandle); } else { free (tokenUser); return GetLastError(); } } else { free (tokenUser); return GetLastError(); } free (tokenUser); return ERROR_SUCCESS; }
NTSTATUS kuhl_m_sid_add(int argc, wchar_t * argv[]) { PLDAP ld; DWORD dwErr; PCWCHAR szName; PWCHAR domain = NULL; PLDAPMessage pMessage = NULL; BERVAL NewSid; PBERVAL pNewSid[2] = {&NewSid, NULL}; LDAPMod Modification = {LDAP_MOD_ADD | LDAP_MOD_BVALUES, L"sIDHistory"}; PLDAPMod pModification[2] = {&Modification, NULL}; Modification.mod_vals.modv_bvals = pNewSid; if(kull_m_string_args_byName(argc, argv, L"new", &szName, NULL)) { if(ConvertStringSidToSid(szName, (PSID *) &NewSid.bv_val) || kull_m_token_getSidDomainFromName(szName, (PSID *) &NewSid.bv_val, &domain, NULL, NULL)) { if(IsValidSid((PSID) NewSid.bv_val)) { NewSid.bv_len = GetLengthSid((PSID) NewSid.bv_val); if(kuhl_m_sid_quickSearch(argc, argv, TRUE, NULL, &ld, &pMessage)) { kprintf(L"\n * Will try to add \'%s\' this new SID:\'", Modification.mod_type); kull_m_string_displaySID(NewSid.bv_val); kprintf(L"\': "); dwErr = ldap_modify_s(ld, ldap_get_dn(ld, pMessage), pModification); if(dwErr == LDAP_SUCCESS) kprintf(L"OK!\n"); else PRINT_ERROR(L"ldap_modify_s 0x%x (%u)\n", dwErr, dwErr); if(pMessage) ldap_msgfree(pMessage); ldap_unbind(ld); } } else PRINT_ERROR(L"Invalid SID\n"); LocalFree(NewSid.bv_val); if(domain) LocalFree(domain); } else PRINT_ERROR_AUTO(L"ConvertStringSidToSid / kull_m_token_getSidDomainFromName"); } else PRINT_ERROR(L"/new:sid or /new:resolvable_name is needed"); return STATUS_SUCCESS; }
BOOL SetTokenIL(HANDLE hToken, DWORD dwIntegrityLevel) { BOOL fRet = FALSE; PSID pIntegritySid = NULL; TOKEN_MANDATORY_LABEL TIL = { 0 }; // Low integrity SID WCHAR wszIntegritySid[32]; if (FAILED(StringCbPrintf(wszIntegritySid, sizeof(wszIntegritySid), L"S-1-16-%d", dwIntegrityLevel))) { printf("Error creating IL SID\n"); goto CleanExit; } fRet = ConvertStringSidToSid(wszIntegritySid, &pIntegritySid); if (!fRet) { printf("Error converting IL string %ls\n", GetErrorMessage().c_str()); goto CleanExit; } TIL.Label.Attributes = SE_GROUP_INTEGRITY; TIL.Label.Sid = pIntegritySid; fRet = SetTokenInformation(hToken, TokenIntegrityLevel, &TIL, sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(pIntegritySid)); if (!fRet) { printf("Error setting IL %d\n", GetLastError()); goto CleanExit; } CleanExit: LocalFree(pIntegritySid); return fRet; }
bool SecurityHelper::GetLogonSid(HANDLE htok, void* psid, DWORD cbMax) { DWORD cb; GetTokenInformation(htok, TokenGroups, 0, 0, &cb); TOKEN_GROUPS* ptg = (TOKEN_GROUPS*)LocalAlloc(LMEM_FIXED, cb); if (!ptg) { LOOM; return false; } bool success = false; if (GetTokenInformation(htok, TokenGroups, ptg, cb, &cb)) { // search for the logon SID DWORD i = 0; for (i = 0; i < ptg->GroupCount; ++i) { if (ptg->Groups[i].Attributes & SE_GROUP_LOGON_ID) { void* logonSid = ptg->Groups[i].Sid; const DWORD cb = GetLengthSid(logonSid); if (cbMax < cb) return false; // sanity check caller's buffer size if (!CopySid(cb, psid, logonSid)) { LCF1(L"CopySid failed: %d", GetLastError()); break; } success = true; break; } } if (i == ptg->GroupCount) { LCF(L"Failed to find a logon SID in the user's access token!"); } } else LCF1(L"GetTokenInformation(TokenGroups) failed: %d", GetLastError()); LocalFree(ptg); return success; }
static int iwin32_gid_current (group_id_t *gid) { HANDLE thread_tok; DWORD needed; TOKEN_PRIMARY_GROUP *group; DWORD sid_size; assert (gid != NULL); assert (gid->value == NULL); if (!OpenProcessToken (GetCurrentProcess(), STANDARD_RIGHTS_READ | READ_CONTROL | TOKEN_QUERY, &thread_tok)) return 0; /* * Is this _really_ correct? */ if (!GetTokenInformation (thread_tok, TokenPrimaryGroup, NULL, 0, &needed)) { if (GetLastError () == ERROR_INSUFFICIENT_BUFFER) { group = malloc (needed); if (group == NULL) return 0; if (GetTokenInformation (thread_tok, TokenPrimaryGroup, group, needed, &needed)) { sid_size = GetLengthSid (group->PrimaryGroup); gid->value = malloc (sid_size); if (gid->value == NULL) { free (group); return 0; } if (!CopySid (sid_size, gid->value, group->PrimaryGroup)) { free (gid->value); free (group); return 0; } } free (group); } else { return 0; } } return 1; }
VOID QueueHashAdd(Queue *pQueue, PSID Sid, VOID *pValue, BOOL EnterCritSec) { QueueHashNode *pQueueHashNode; DWORD SidLength; ASSERT(pQueue != NULL); if (pQueue->lpCriticalSection != NULL && EnterCritSec) EnterCriticalSection(pQueue->lpCriticalSection); #ifdef DEBUG2 DbgMsgRecord(TEXT("-> QueueHashAdd\n")); #endif pQueueHashNode = (QueueHashNode *) AutoHeapAlloc(sizeof(QueueHashNode)); SidLength = GetLengthSid(Sid); // We need to copy the key so that if the original // copy gets deallocated we still have one. if ((pQueueHashNode->pKey = AutoHeapAlloc(SidLength)) == NULL) { AddToMessageLog(TEXT("QueueHashAdd: AutoHeapAlloc failed")); if (pQueue->lpCriticalSection != NULL && EnterCritSec) LeaveCriticalSection(pQueue->lpCriticalSection); return; } if (CopySid(SidLength, pQueueHashNode->pKey, Sid) == 0) { AddToMessageLogProcFailure(TEXT("QueueHashAdd: CopySid"), GetLastError()); if (pQueue->lpCriticalSection != NULL && EnterCritSec) LeaveCriticalSection(pQueue->lpCriticalSection); return; } pQueueHashNode->pValue = pValue; QueueAdd(pQueue, (VOID *) pQueueHashNode, FALSE); #ifdef DEBUG2 DbgMsgRecord(TEXT("<- QueueHashAdd\n")); #endif if (pQueue->lpCriticalSection != NULL && EnterCritSec) LeaveCriticalSection(pQueue->lpCriticalSection); }
PWCHAR kuhl_m_sid_filterFromArgs(int argc, wchar_t * argv[]) { PWCHAR filter = NULL; PCWCHAR szName; DWORD i, sidLen; size_t buffLen; PSID pSid; if(kull_m_string_args_byName(argc, argv, L"sam", &szName, NULL)) { buffLen = wcslen(L"(sAMAccountName=") + wcslen(szName) + wcslen(L")") + 1; if(filter = (PWCHAR) LocalAlloc(LPTR, buffLen * sizeof(wchar_t))) { if(swprintf_s(filter, buffLen, L"(sAMAccountName=%s)", szName) != (buffLen - 1)) filter = (PWCHAR) LocalFree(filter); } } else if(kull_m_string_args_byName(argc, argv, L"sid", &szName, NULL)) { if(ConvertStringSidToSid(szName, &pSid)) { if(IsValidSid(pSid)) { sidLen = GetLengthSid(pSid); buffLen = wcslen(L"(objectSid=") + (sidLen * 3) + wcslen(L")") + 1; if(filter = (PWCHAR) LocalAlloc(LPTR, buffLen * sizeof(wchar_t))) { RtlCopyMemory(filter, L"(objectSid=", sizeof(L"(objectSid=")); for(i = 0; i < sidLen; i++) swprintf_s(filter + ARRAYSIZE(L"(objectSid=") - 1 + (i * 3), 3 + 1, L"\\%02x", ((PBYTE) pSid)[i]); filter[buffLen - 2] = L')'; } } else PRINT_ERROR(L"Invalid SID\n"); LocalFree(pSid); } else PRINT_ERROR_AUTO(L"ConvertStringSidToSid"); } else PRINT_ERROR(L"/sam or /sid to target the account is needed\n"); return filter; }
BOOL kuhl_m_pac_marshall_sid(PISID pSid, PVOID * current, DWORD * size) { BOOL status = FALSE; PVOID newbuffer; DWORD sidSize, actualsize; sidSize = GetLengthSid(pSid); actualsize = sizeof(ULONG32) + sidSize; if(newbuffer = LocalAlloc(LPTR, *size + actualsize)) { RtlCopyMemory(newbuffer, *current, *size); (*(PULONG32) ((PBYTE) newbuffer + *size)) = pSid->SubAuthorityCount; RtlCopyMemory((PBYTE) newbuffer + *size + sizeof(ULONG32), pSid, sidSize); LocalFree(*current); *current = newbuffer; *size += actualsize; status = TRUE; } return status; }
HRESULT COpcSecurity::GetCurrentUserSID(PSID *ppSid) { HANDLE tkHandle; if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tkHandle)) { TOKEN_USER *tkUser; DWORD tkSize; DWORD sidLength; // Call to get size information for alloc GetTokenInformation(tkHandle, TokenUser, NULL, 0, &tkSize); tkUser = (TOKEN_USER *) malloc(tkSize); if (tkUser == NULL) return E_OUTOFMEMORY; // Now make the real call if (GetTokenInformation(tkHandle, TokenUser, tkUser, tkSize, &tkSize)) { sidLength = GetLengthSid(tkUser->User.Sid); *ppSid = (PSID) malloc(sidLength); if (*ppSid == NULL) return E_OUTOFMEMORY; memcpy(*ppSid, tkUser->User.Sid, sidLength); CloseHandle(tkHandle); free(tkUser); return S_OK; } else { free(tkUser); return HRESULT_FROM_WIN32(GetLastError()); } } return HRESULT_FROM_WIN32(GetLastError()); }
static PSID GetCurrentUserSid (void) { PSID sid = NULL; guint32 size = 0; gpointer token = ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken (); GetTokenInformation (token, TokenUser, NULL, size, (PDWORD)&size); if (size > 0) { TOKEN_USER *tu = g_malloc0 (size); if (GetTokenInformation (token, TokenUser, tu, size, (PDWORD)&size)) { DWORD length = GetLengthSid (tu->User.Sid); sid = (PSID) g_malloc0 (length); if (!CopySid (length, sid, tu->User.Sid)) { g_free (sid); sid = NULL; } } g_free (tu); } /* Note: this SID must be freed with g_free () */ return sid; }
PSID convert_jsstring_to_sid(JSContext * cx, JSString * curMemberString, DWORD * errorCode) { PSID curMember; if(!ConvertStringSidToSid((LPWSTR)JS_GetStringChars(curMemberString), &curMember)) { DWORD sidSize = 0, cbDomain; SID_NAME_USE peUse; *errorCode = GetLastError(); JS_YieldRequest(cx); if(!LookupAccountName(NULL, (LPWSTR)JS_GetStringChars(curMemberString), NULL, &sidSize, NULL, &cbDomain, &peUse) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { *errorCode = GetLastError(); return NULL; } curMember = (PSID)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sidSize); JS_YieldRequest(cx); LPTSTR domainName = (LPTSTR)HeapAlloc(GetProcessHeap(), 0, cbDomain * sizeof(TCHAR)); if(!LookupAccountName(NULL, (LPWSTR)JS_GetStringChars(curMemberString), curMember, &sidSize, domainName, &cbDomain, &peUse)) { *errorCode = GetLastError(); HeapFree(GetProcessHeap(), 0, curMember); HeapFree(GetProcessHeap(), 0, domainName); return NULL; } HeapFree(GetProcessHeap(), 0, domainName); *errorCode = ERROR_SUCCESS; } else { DWORD sidSize = GetLengthSid(curMember); PSID retMember = (PSID)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sidSize); CopySid(sidSize, retMember, curMember); LocalFree(curMember); curMember = retMember; } return curMember; }
void AddDefaultUserdata(PluginPanelItem* Item,int level,int sortorder,int itemtype,PSID sid,const wchar_t* wide_name,const wchar_t* filename) { TCHAR* item_filename=(TCHAR*)malloc((_tcslen(filename)+1)*sizeof(TCHAR)); Item->FileName=item_filename; if(item_filename) { if(item_filename) _tcscpy(item_filename,filename); } PluginUserData *user_data; int user_data_size=sizeof(PluginUserData),sid_size=0,name_size=0; if(sid&&IsValidSid(sid)) sid_size=GetLengthSid(sid); name_size=(wcslen(wide_name)+1)*sizeof(wchar_t); user_data_size+=sid_size+name_size; user_data=(PluginUserData *)malloc(user_data_size); if(user_data) { user_data->size=user_data_size; user_data->level=level; user_data->sortorder=sortorder; user_data->itemtype=itemtype; if(sid_size) { CopySid(sid_size,(PSID)(user_data+1),sid); user_data->user_diff=sizeof(PluginUserData); } if(name_size) { wchar_t *ptr=(wchar_t *)((char *)(user_data+1)+sid_size); user_data->wide_name_diff=sizeof(PluginUserData)+sid_size; wcscpy(ptr,wide_name); } Item->UserData.FreeData=FreeUserData; Item->UserData.Data=user_data; } }
DWORD IDMCloneSid( PSID pSid, PSID *ppNewSid ) { DWORD dwError = 0; DWORD sidLen = 0; PSID pNewSid = NULL; if (!IsValidSid(pSid)) { dwError = ERROR_INVALID_SID; BAIL_ON_ERROR(dwError); } sidLen = GetLengthSid(pSid); dwError = IDMAllocateMemory( sidLen, (PVOID*) &pNewSid); BAIL_ON_ERROR(dwError); if (!CopySid(sidLen, pNewSid, pSid)) { dwError = GetLastError(); BAIL_ON_ERROR(dwError); } *ppNewSid = pNewSid; error: if (dwError) { IDM_SAFE_FREE_MEMORY(pNewSid); } return dwError; }
BOOL RemoveAceFromWindowStation(HWINSTA hwinsta, PSID psid) { // Obtain the DACL for the window station. SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; DWORD sd_length = 0; if (!GetUserObjectSecurity(hwinsta, &si, NULL, 0, &sd_length)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { printf("GetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } } auto_buffer<PSECURITY_DESCRIPTOR> psd(sd_length); if (!GetUserObjectSecurity(hwinsta, &si, psd.get(), sd_length, &sd_length)) { printf("GetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } // Create a new DACL. auto_buffer<PSECURITY_DESCRIPTOR> psd_new(sd_length); if (!InitializeSecurityDescriptor(psd_new.get(), SECURITY_DESCRIPTOR_REVISION)) { printf("InitializeSecurityDescriptor() failed: %d\n", GetLastError()); return FALSE; } // Get the DACL from the security descriptor. BOOL bDaclPresent; PACL pacl; BOOL bDaclExist; if (!GetSecurityDescriptorDacl(psd.get(), &bDaclPresent, &pacl, &bDaclExist)) { printf("GetSecurityDescriptorDacl() failed: %d\n", GetLastError()); return FALSE; } // Initialize the ACL. ACL_SIZE_INFORMATION aclSizeInfo = {}; aclSizeInfo.AclBytesInUse = sizeof(ACL); if (NULL != pacl) { // get the file ACL size info if (!GetAclInformation(pacl, &aclSizeInfo, sizeof aclSizeInfo, AclSizeInformation)) { printf("GetAclInformation() failed: %d\n", GetLastError()); return FALSE; } } // Compute the size of the new ACL. DWORD new_acl_size = aclSizeInfo.AclBytesInUse - ((2 * sizeof(ACCESS_ALLOWED_ACE)) + (2 * GetLengthSid(psid)) - (2 * sizeof(DWORD))); auto_buffer<PACL> new_acl(new_acl_size); // Initialize the new DACL. if (!InitializeAcl(new_acl.get(), new_acl_size, ACL_REVISION)) { printf("InitializeAcl() failed: %d\n", GetLastError()); return FALSE; } // If DACL is present, copy it to a new DACL. if (bDaclPresent) { // Copy the ACEs to the new ACL. for (DWORD i = 0; i != aclSizeInfo.AceCount; ++i) { ACCESS_ALLOWED_ACE* pace; if (!GetAce(pacl, i, (void**)&pace)) { printf("GetAce() failed: %d\n", GetLastError()); return FALSE; } if (!EqualSid(psid, &pace->SidStart)) { if (!AddAce(new_acl.get(), ACL_REVISION, MAXDWORD, pace, pace->Header.AceSize)) { printf("AddAce() failed: %d\n", GetLastError()); return FALSE; } } } } // Set a new DACL for the security descriptor. if (!SetSecurityDescriptorDacl(psd_new.get(), TRUE, new_acl.get(), FALSE)) { printf("SetSecurityDescriptorDacl() failed: %d\n", GetLastError()); return FALSE; } // Set the new security descriptor for the window station. if (!SetUserObjectSecurity(hwinsta, &si, psd_new.get())) { printf("SetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } return TRUE; }
/** * This function adjusts the specified WindowStation to include the specfied * user. * * See: http://msdn2.microsoft.com/en-us/library/aa379608(VS.85).aspx **/ BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid) { ACCESS_ALLOWED_ACE *pace = NULL; ACL_SIZE_INFORMATION aclSizeInfo; BOOL bDaclExist; BOOL bDaclPresent; BOOL bSuccess = FALSE; DWORD dwNewAclSize; DWORD dwSidSize = 0; DWORD dwSdSizeNeeded; PACL pacl = NULL; PACL pNewAcl = NULL; PSECURITY_DESCRIPTOR psd = NULL; PSECURITY_DESCRIPTOR psdNew = NULL; PVOID pTempAce; SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; unsigned int i; try { // Obtain the DACL for the window station. if (!GetUserObjectSecurity( hwinsta, &si, psd, dwSidSize, &dwSdSizeNeeded) ) if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { psd = (PSECURITY_DESCRIPTOR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded); if (psd == NULL) throw; psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded); if (psdNew == NULL) throw; dwSidSize = dwSdSizeNeeded; if (!GetUserObjectSecurity( hwinsta, &si, psd, dwSidSize, &dwSdSizeNeeded) ) throw; } else throw; // Create a new DACL. if (!InitializeSecurityDescriptor( psdNew, SECURITY_DESCRIPTOR_REVISION) ) throw; // Get the DACL from the security descriptor. if (!GetSecurityDescriptorDacl( psd, &bDaclPresent, &pacl, &bDaclExist) ) throw; // Initialize the ACL. ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION)); aclSizeInfo.AclBytesInUse = sizeof(ACL); // Call only if the DACL is not NULL. if (pacl != NULL) { // get the file ACL size info if (!GetAclInformation( pacl, (LPVOID)&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation) ) throw; } // Compute the size of the new ACL. dwNewAclSize = aclSizeInfo.AclBytesInUse + (2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) - (2*sizeof(DWORD)); // Allocate memory for the new ACL. pNewAcl = (PACL)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwNewAclSize); if (pNewAcl == NULL) throw; // Initialize the new DACL. if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION)) throw; // If DACL is present, copy it to a new DACL. if (bDaclPresent) { // Copy the ACEs to the new ACL. if (aclSizeInfo.AceCount) { for (i=0; i < aclSizeInfo.AceCount; i++) { // Get an ACE. if (!GetAce(pacl, i, &pTempAce)) throw; // Add the ACE to the new ACL. if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize) ) throw; } } } // Add the first ACE to the window station. pace = (ACCESS_ALLOWED_ACE *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD) ); if (pace == NULL) throw; pace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; pace->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE; pace->Header.AceSize = (WORD)sizeof(ACCESS_ALLOWED_ACE) + (WORD)GetLengthSid(psid) - (WORD)sizeof(DWORD); pace->Mask = GENERIC_ALL; if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid)) throw; if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, (LPVOID)pace, pace->Header.AceSize) ) throw; // Add an ACE to the window station. pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE; pace->Mask = GENERIC_ALL; if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, (LPVOID)pace, pace->Header.AceSize) ) throw; // Set a new DACL for the security descriptor. if (!SetSecurityDescriptorDacl( psdNew, TRUE, pNewAcl, FALSE) ) throw; // Set the new security descriptor for the window station. if (!SetUserObjectSecurity(hwinsta, &si, psdNew)) throw; // Indicate success. bSuccess = TRUE; } catch(...) { // Free the allocated buffers. if (pace != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)pace); if (pNewAcl != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); if (psd != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psd); if (psdNew != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew); } return bSuccess; }
HRESULT COpcSecurity::GetTokenSids(HANDLE hToken, PSID* ppUserSid, PSID* ppGroupSid) { DWORD dwSize; HRESULT hr; PTOKEN_USER ptkUser = NULL; PTOKEN_PRIMARY_GROUP ptkGroup = NULL; if (ppUserSid) *ppUserSid = NULL; if (ppGroupSid) *ppGroupSid = NULL; if (ppUserSid) { // Get length required for TokenUser by specifying buffer length of 0 GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize); hr = GetLastError(); if (hr != ERROR_INSUFFICIENT_BUFFER) { // Expected ERROR_INSUFFICIENT_BUFFER OPCASSERT(FALSE); hr = HRESULT_FROM_WIN32(hr); goto failed; } ptkUser = (TOKEN_USER*) malloc(dwSize); if (ptkUser == NULL) { hr = E_OUTOFMEMORY; goto failed; } // Get Sid of process token. if (!GetTokenInformation(hToken, TokenUser, ptkUser, dwSize, &dwSize)) { // Couldn't get user info hr = HRESULT_FROM_WIN32(GetLastError()); OPCASSERT(FALSE); goto failed; } // Make a copy of the Sid for the return value dwSize = GetLengthSid(ptkUser->User.Sid); PSID pSid; pSid = (PSID) malloc(dwSize); if (pSid == NULL) { hr = E_OUTOFMEMORY; goto failed; } if (!CopySid(dwSize, pSid, ptkUser->User.Sid)) { hr = HRESULT_FROM_WIN32(GetLastError()); OPCASSERT(FALSE); goto failed; } OPCASSERT(IsValidSid(pSid)); *ppUserSid = pSid; free(ptkUser); } if (ppGroupSid) { // Get length required for TokenPrimaryGroup by specifying buffer length of 0 GetTokenInformation(hToken, TokenPrimaryGroup, NULL, 0, &dwSize); hr = GetLastError(); if (hr != ERROR_INSUFFICIENT_BUFFER) { // Expected ERROR_INSUFFICIENT_BUFFER OPCASSERT(FALSE); hr = HRESULT_FROM_WIN32(hr); goto failed; } ptkGroup = (TOKEN_PRIMARY_GROUP*) malloc(dwSize); if (ptkGroup == NULL) { hr = E_OUTOFMEMORY; goto failed; } // Get Sid of process token. if (!GetTokenInformation(hToken, TokenPrimaryGroup, ptkGroup, dwSize, &dwSize)) { // Couldn't get user info hr = HRESULT_FROM_WIN32(GetLastError()); OPCASSERT(FALSE); goto failed; } // Make a copy of the Sid for the return value dwSize = GetLengthSid(ptkGroup->PrimaryGroup); PSID pSid; pSid = (PSID) malloc(dwSize); if (pSid == NULL) { hr = E_OUTOFMEMORY; goto failed; } if (!CopySid(dwSize, pSid, ptkGroup->PrimaryGroup)) { hr = HRESULT_FROM_WIN32(GetLastError()); OPCASSERT(FALSE); goto failed; } OPCASSERT(IsValidSid(pSid)); *ppGroupSid = pSid; free(ptkGroup); } return S_OK; failed: if (ptkUser) free(ptkUser); if (ptkGroup) free (ptkGroup); return hr; }
/*---------------------------------------------------------------------------*\ * NAME: MakeSDAbsolute * --------------------------------------------------------------------------* * DESCRIPTION: Takes a self-relative security descriptor and returns a * newly created absolute security descriptor. \*---------------------------------------------------------------------------*/ DWORD MakeSDAbsolute ( PSECURITY_DESCRIPTOR psidOld, PSECURITY_DESCRIPTOR *psidNew ) { PSECURITY_DESCRIPTOR pSid = NULL; DWORD cbDescriptor = 0; DWORD cbDacl = 0; DWORD cbSacl = 0; DWORD cbOwnerSID = 0; DWORD cbGroupSID = 0; PACL pDacl = NULL; PACL pSacl = NULL; PSID psidOwner = NULL; PSID psidGroup = NULL; BOOL fPresent = FALSE; BOOL fSystemDefault = FALSE; DWORD dwReturnValue = ERROR_SUCCESS; // Get SACL if (!GetSecurityDescriptorSacl (psidOld, &fPresent, &pSacl, &fSystemDefault)) { dwReturnValue = GetLastError(); goto CLEANUP; } if (pSacl && fPresent) { cbSacl = pSacl->AclSize; } // Get DACL if (!GetSecurityDescriptorDacl (psidOld, &fPresent, &pDacl, &fSystemDefault)) { dwReturnValue = GetLastError(); goto CLEANUP; } if (pDacl && fPresent) { cbDacl = pDacl->AclSize; } // Get Owner if (!GetSecurityDescriptorOwner (psidOld, &psidOwner, &fSystemDefault)) { dwReturnValue = GetLastError(); goto CLEANUP; } cbOwnerSID = GetLengthSid (psidOwner); // Get Group if (!GetSecurityDescriptorGroup (psidOld, &psidGroup, &fSystemDefault)) { dwReturnValue = GetLastError(); goto CLEANUP; } cbGroupSID = GetLengthSid (psidGroup); // Do the conversion cbDescriptor = 0; MakeAbsoluteSD (psidOld, pSid, &cbDescriptor, pDacl, &cbDacl, pSacl, &cbSacl, psidOwner, &cbOwnerSID, psidGroup, &cbGroupSID); pSid = (PSECURITY_DESCRIPTOR) malloc(cbDescriptor); if(!pSid) { dwReturnValue = ERROR_OUTOFMEMORY; goto CLEANUP; } ZeroMemory(pSid, cbDescriptor); if (!InitializeSecurityDescriptor (pSid, SECURITY_DESCRIPTOR_REVISION)) { dwReturnValue = GetLastError(); goto CLEANUP; } if (!MakeAbsoluteSD (psidOld, pSid, &cbDescriptor, pDacl, &cbDacl, pSacl, &cbSacl, psidOwner, &cbOwnerSID, psidGroup, &cbGroupSID)) { dwReturnValue = GetLastError(); goto CLEANUP; } CLEANUP: if(dwReturnValue != ERROR_SUCCESS && pSid) { free(pSid); pSid = NULL; } *psidNew = pSid; return dwReturnValue; }
/*---------------------------------------------------------------------------*\ * NAME: CreateNewSD * --------------------------------------------------------------------------* * DESCRIPTION: Creates a new security descriptor. \*---------------------------------------------------------------------------*/ DWORD CreateNewSD ( SECURITY_DESCRIPTOR **ppSecurityDesc ) { PACL pAcl = NULL; DWORD cbSid = 0; PSID pSid = NULL; PSID psidGroup = NULL; PSID psidOwner = NULL; DWORD dwReturnValue = ERROR_SUCCESS; SID_IDENTIFIER_AUTHORITY SystemSidAuthority= SECURITY_NT_AUTHORITY; if(!ppSecurityDesc) return ERROR_BAD_ARGUMENTS; *ppSecurityDesc = NULL; //Create a SID for the owner (BUILTIN\Administrators) if ( ! AllocateAndInitializeSid ( &SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSid) ) { dwReturnValue = GetLastError(); goto CLEANUP; } cbSid = GetLengthSid (pSid); *ppSecurityDesc = (SECURITY_DESCRIPTOR *) malloc ( sizeof (ACL) + (2 * cbSid) + sizeof (SECURITY_DESCRIPTOR)); if(!*ppSecurityDesc) { dwReturnValue = ERROR_OUTOFMEMORY; goto CLEANUP; } psidGroup = (SID *) (*ppSecurityDesc + 1); psidOwner = (SID *) (((BYTE *) psidGroup) + cbSid); pAcl = (ACL *) (((BYTE *) psidOwner) + cbSid); if (!InitializeSecurityDescriptor (*ppSecurityDesc, SECURITY_DESCRIPTOR_REVISION)) { dwReturnValue = GetLastError(); goto CLEANUP; } if (!InitializeAcl (pAcl, sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+cbSid, ACL_REVISION2)) { dwReturnValue = GetLastError(); goto CLEANUP; } if (!SetSecurityDescriptorDacl (*ppSecurityDesc, TRUE, pAcl, FALSE)) { dwReturnValue = GetLastError(); goto CLEANUP; } memcpy (psidGroup, pSid, cbSid); if (!SetSecurityDescriptorGroup (*ppSecurityDesc, psidGroup, FALSE)) { dwReturnValue = GetLastError(); goto CLEANUP; } memcpy (psidOwner, pSid, cbSid); if (!SetSecurityDescriptorOwner (*ppSecurityDesc, psidOwner, FALSE)) { dwReturnValue = GetLastError(); goto CLEANUP; } CLEANUP: if(dwReturnValue != ERROR_SUCCESS) { if(*ppSecurityDesc) free (*ppSecurityDesc); } if(pSid) FreeSid(pSid); return dwReturnValue; }
int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror, DWORD owner_rights, DWORD everyone_rights) { /* Top-level SID authority */ SID_IDENTIFIER_AUTHORITY world_auth= SECURITY_WORLD_SID_AUTHORITY; PSID everyone_sid= 0; HANDLE htoken= 0; SECURITY_ATTRIBUTES *sa= 0; PACL dacl= 0; DWORD owner_token_length, dacl_length; SECURITY_DESCRIPTOR *sd; PTOKEN_USER owner_token; PSID owner_sid; My_security_attr *attr; if (! is_nt()) { *psa= 0; return 0; } /* Get SID of Everyone group. Easier to retrieve all SIDs each time this function is called than worry about thread safety. */ if (! AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyone_sid)) { *perror= "Failed to retrieve the SID of Everyone group"; goto error; } /* Get SID of the owner. Using GetSecurityInfo this task can be done in just one call instead of five, but GetSecurityInfo declared in aclapi.h, so I hesitate to use it. SIC: OpenThreadToken works only if there is an active impersonation token, hence OpenProcessToken is used. */ if (! OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &htoken)) { *perror= "Failed to retrieve thread access token"; goto error; } GetTokenInformation(htoken, TokenUser, 0, 0, &owner_token_length); if (! my_multi_malloc(MYF(MY_WME), &sa, ALIGN_SIZE(sizeof(SECURITY_ATTRIBUTES)) + sizeof(My_security_attr), &sd, sizeof(SECURITY_DESCRIPTOR), &owner_token, owner_token_length, 0)) { *perror= "Failed to allocate memory for SECURITY_ATTRIBUTES"; goto error; } bzero(owner_token, owner_token_length); if (! GetTokenInformation(htoken, TokenUser, owner_token, owner_token_length, &owner_token_length)) { *perror= "GetTokenInformation failed"; goto error; } owner_sid= owner_token->User.Sid; if (! IsValidSid(owner_sid)) { *perror= "IsValidSid failed"; goto error; } /* Calculate the amount of memory that must be allocated for the DACL */ dacl_length= sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD)) * 2 + GetLengthSid(everyone_sid) + GetLengthSid(owner_sid); /* Create an ACL */ if (! (dacl= (PACL) my_malloc(dacl_length, MYF(MY_ZEROFILL|MY_WME)))) { *perror= "Failed to allocate memory for DACL"; goto error; } if (! InitializeAcl(dacl, dacl_length, ACL_REVISION)) { *perror= "Failed to initialize DACL"; goto error; } if (! AddAccessAllowedAce(dacl, ACL_REVISION, everyone_rights, everyone_sid)) { *perror= "Failed to set up DACL"; goto error; } if (! AddAccessAllowedAce(dacl, ACL_REVISION, owner_rights, owner_sid)) { *perror= "Failed to set up DACL"; goto error; } if (! InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) { *perror= "Could not initialize security descriptor"; goto error; } if (! SetSecurityDescriptorDacl(sd, TRUE, dacl, FALSE)) { *perror= "Failed to install DACL"; goto error; } sa->nLength= sizeof(*sa); sa->bInheritHandle= TRUE; sa->lpSecurityDescriptor= sd; /* Save pointers to everyone_sid and dacl to be able to clean them up */ attr= (My_security_attr*) (((char*) sa) + ALIGN_SIZE(sizeof(*sa))); attr->everyone_sid= everyone_sid; attr->dacl= dacl; *psa= sa; CloseHandle(htoken); return 0; error: if (everyone_sid) FreeSid(everyone_sid); if (htoken) CloseHandle(htoken); my_free(sa); my_free(dacl); *psa= 0; return 1; }
size_t operator ()(const sid& Sid) const { return CRC32(0, Sid.get(), GetLengthSid(Sid.get())); }
/* * @unimplemented */ AUTHZAPI BOOL WINAPI AuthzInitializeContextFromSid(IN DWORD Flags, IN PSID UserSid, IN AUTHZ_RESOURCE_MANAGER_HANDLE AuthzResourceManager, IN PLARGE_INTEGER pExpirationTime, IN LUID Identifier, IN PVOID DynamicGroupArgs, OUT PAUTHZ_CLIENT_CONTEXT_HANDLE pAuthzClientContext) { BOOL Ret = FALSE; if (AuthzResourceManager != NULL && pExpirationTime != NULL && pAuthzClientContext != NULL && UserSid != NULL && IsValidSid(UserSid) && !(Flags & (AUTHZ_SKIP_TOKEN_GROUPS | AUTHZ_REQUIRE_S4U_LOGON))) { PAUTHZ_CLIENT_CONTEXT ClientCtx; //PAUTHZ_RESMAN ResMan = (PAUTHZ_RESMAN)AuthzResourceManager; VALIDATE_RESMAN_HANDLE(AuthzResourceManager); ClientCtx = (PAUTHZ_CLIENT_CONTEXT)LocalAlloc(LMEM_FIXED, sizeof(AUTHZ_CLIENT_CONTEXT)); if (ClientCtx != NULL) { DWORD SidLen; /* initialize the client context structure */ #if DBG ClientCtx->Tag = CLIENTCTX_TAG; #endif /* simply copy the SID */ SidLen = GetLengthSid(UserSid); ClientCtx->UserSid = (PSID)LocalAlloc(LMEM_FIXED, SidLen); if (ClientCtx->UserSid == NULL) { LocalFree((HLOCAL)ClientCtx); goto FailNoMemory; } CopySid(SidLen, ClientCtx->UserSid, UserSid); ClientCtx->AuthzResourceManager = AuthzResourceManager; ClientCtx->Luid = Identifier; ClientCtx->ExpirationTime.QuadPart = (pExpirationTime != NULL ? pExpirationTime->QuadPart : 0); ClientCtx->ServerContext = NULL; /* FIXME */ ClientCtx->DynamicGroupArgs = DynamicGroupArgs; /* return the client context handle */ *pAuthzClientContext = (AUTHZ_CLIENT_CONTEXT_HANDLE)ClientCtx; Ret = TRUE; } else { FailNoMemory: SetLastError(ERROR_NOT_ENOUGH_MEMORY); } } else SetLastError(ERROR_INVALID_PARAMETER); return Ret; }
/* * @unimplemented */ AUTHZAPI BOOL WINAPI AuthzGetInformationFromContext(IN AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext, IN AUTHZ_CONTEXT_INFORMATION_CLASS InfoClass, IN DWORD BufferSize, OUT PDWORD pSizeRequired, OUT PVOID Buffer) { BOOL Ret = FALSE; if (hAuthzClientContext != NULL && pSizeRequired != NULL) { PAUTHZ_CLIENT_CONTEXT ClientCtx = (PAUTHZ_CLIENT_CONTEXT)hAuthzClientContext; VALIDATE_CLIENTCTX_HANDLE(hAuthzClientContext); switch (InfoClass) { case AuthzContextInfoUserSid: { DWORD SidLen = GetLengthSid(ClientCtx->UserSid); *pSizeRequired = SidLen; if (BufferSize < SidLen) { SetLastError(ERROR_INSUFFICIENT_BUFFER); } else { Ret = CopySid(SidLen, (PSID)Buffer, ClientCtx->UserSid); } break; } case AuthzContextInfoGroupsSids: SetLastError(ERROR_CALL_NOT_IMPLEMENTED); break; case AuthzContextInfoRestrictedSids: SetLastError(ERROR_CALL_NOT_IMPLEMENTED); break; case AuthzContextInfoPrivileges: SetLastError(ERROR_CALL_NOT_IMPLEMENTED); break; case AuthzContextInfoExpirationTime: *pSizeRequired = sizeof(LARGE_INTEGER); if (BufferSize < sizeof(LARGE_INTEGER) || Buffer == NULL) { SetLastError(ERROR_INSUFFICIENT_BUFFER); } else { *((PLARGE_INTEGER)Buffer) = ClientCtx->ExpirationTime; Ret = TRUE; } break; case AuthzContextInfoServerContext: *pSizeRequired = sizeof(AUTHZ_CLIENT_CONTEXT_HANDLE); if (BufferSize < sizeof(AUTHZ_CLIENT_CONTEXT_HANDLE) || Buffer == NULL) { SetLastError(ERROR_INSUFFICIENT_BUFFER); } else { *((PAUTHZ_CLIENT_CONTEXT_HANDLE)Buffer) = ClientCtx->ServerContext; Ret = TRUE; } break; case AuthzContextInfoIdentifier: *pSizeRequired = sizeof(LUID); if (BufferSize < sizeof(LUID) || Buffer == NULL) { SetLastError(ERROR_INSUFFICIENT_BUFFER); } else { *((PLUID)Buffer) = ClientCtx->Luid; Ret = TRUE; } break; default: SetLastError(ERROR_INVALID_PARAMETER); break; } } else SetLastError(ERROR_INVALID_PARAMETER); return Ret; }
/** * This function adjusts the specified Desktop to include the specfied * user. * * See: http://msdn2.microsoft.com/en-us/library/aa379608(VS.85).aspx **/ BOOL AddAceToDesktop(HDESK hdesk, PSID psid) { ACL_SIZE_INFORMATION aclSizeInfo; BOOL bDaclExist; BOOL bDaclPresent; BOOL bSuccess = FALSE; DWORD dwNewAclSize; DWORD dwSidSize = 0; DWORD dwSdSizeNeeded; PACL pacl = NULL; PACL pNewAcl = NULL; PSECURITY_DESCRIPTOR psd = NULL; PSECURITY_DESCRIPTOR psdNew = NULL; PVOID pTempAce; SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; unsigned int i; try { // Obtain the security descriptor for the desktop object. if (!GetUserObjectSecurity( hdesk, &si, psd, dwSidSize, &dwSdSizeNeeded)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { psd = (PSECURITY_DESCRIPTOR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded ); if (psd == NULL) throw; psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwSdSizeNeeded); if (psdNew == NULL) throw; dwSidSize = dwSdSizeNeeded; if (!GetUserObjectSecurity( hdesk, &si, psd, dwSidSize, &dwSdSizeNeeded) ) throw; } else throw; } // Create a new security descriptor. if (!InitializeSecurityDescriptor( psdNew, SECURITY_DESCRIPTOR_REVISION) ) throw; // Obtain the DACL from the security descriptor. if (!GetSecurityDescriptorDacl( psd, &bDaclPresent, &pacl, &bDaclExist) ) throw; // Initialize. ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION)); aclSizeInfo.AclBytesInUse = sizeof(ACL); // Call only if NULL DACL. if (pacl != NULL) { // Determine the size of the ACL information. if (!GetAclInformation( pacl, (LPVOID)&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation) ) throw; } // Compute the size of the new ACL. dwNewAclSize = aclSizeInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD); // Allocate buffer for the new ACL. pNewAcl = (PACL)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwNewAclSize); if (pNewAcl == NULL) throw; // Initialize the new ACL. if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION)) throw; // If DACL is present, copy it to a new DACL. if (bDaclPresent) { // Copy the ACEs to the new ACL. if (aclSizeInfo.AceCount) { for (i=0; i < aclSizeInfo.AceCount; i++) { // Get an ACE. if (!GetAce(pacl, i, &pTempAce)) throw; // Add the ACE to the new ACL. if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize) ) throw; } } } // Add ACE to the DACL. if (!AddAccessAllowedAce( pNewAcl, ACL_REVISION, GENERIC_ALL, psid) ) throw; // Set new DACL to the new security descriptor. if (!SetSecurityDescriptorDacl( psdNew, TRUE, pNewAcl, FALSE) ) throw; // Set the new security descriptor for the desktop object. if (!SetUserObjectSecurity(hdesk, &si, psdNew)) throw; // Indicate success. bSuccess = TRUE; } catch(...) { // Free buffers. if (pNewAcl != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl); if (psd != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psd); if (psdNew != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew); } return bSuccess; }
BOOL RemoveAceFromDesktop(HDESK hdesk, PSID psid) { // Obtain the security descriptor for the desktop object. SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; DWORD sd_size = 0; if (!GetUserObjectSecurity(hdesk, &si, NULL, 0, &sd_size)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { printf("GetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } } auto_buffer<PSECURITY_DESCRIPTOR> psd(sd_size); if (!GetUserObjectSecurity(hdesk, &si, psd.get(), sd_size, &sd_size)) { printf("GetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } // Create a new security descriptor. auto_buffer<PSECURITY_DESCRIPTOR> psd_new(sd_size); if (!InitializeSecurityDescriptor(psd_new.get(), SECURITY_DESCRIPTOR_REVISION)) { printf("InitializeSecurityDescriptor() failed: %d\n", GetLastError()); return FALSE; } // Obtain the DACL from the security descriptor. BOOL bDaclPresent; PACL pacl; BOOL bDaclExist; if (!GetSecurityDescriptorDacl(psd.get(), &bDaclPresent, &pacl, &bDaclExist)) { printf("GetSecurityDescriptorDacl() failed: %d\n", GetLastError()); return FALSE; } // Initialize. ACL_SIZE_INFORMATION aclSizeInfo = {}; aclSizeInfo.AclBytesInUse = sizeof(ACL); if (pacl != NULL) { // Determine the size of the ACL information. if (!GetAclInformation(pacl, (LPVOID)&aclSizeInfo, sizeof aclSizeInfo, AclSizeInformation)) { printf("GetAclInformation() failed: %d\n", GetLastError()); return FALSE; } } // Allocate buffer for the new ACL. DWORD dwNewAclSize = aclSizeInfo.AclBytesInUse - (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD)); auto_buffer<PACL> new_acl(dwNewAclSize); // Initialize the new ACL. if (!InitializeAcl(new_acl.get(), dwNewAclSize, ACL_REVISION)) { printf("InitializeAcl() failed: %d\n", GetLastError()); return FALSE; } // If DACL is present, copy it to a new DACL. if (bDaclPresent) { // Copy the ACEs to the new ACL. for (DWORD i = 0; i != aclSizeInfo.AceCount; ++i) { // Get an ACE. ACCESS_ALLOWED_ACE* pace; if (!GetAce(pacl, i, (void**)&pace)) { printf("GetAce() failed: %d\n", GetLastError()); return FALSE; } if (!EqualSid(psid, &pace->SidStart)) { // Add the ACE to the new ACL. if (!AddAce(new_acl.get(), ACL_REVISION,MAXDWORD, pace, pace->Header.AceSize)) { printf("AddAce() failed: %d\n", GetLastError()); return FALSE; } } } } // Set new DACL to the new security descriptor. if (!SetSecurityDescriptorDacl(psd_new.get(), TRUE, new_acl.get(), FALSE)) { printf("SetSecurityDescriptorDacl() failed: %d\n", GetLastError()); return FALSE; } // Set the new security descriptor for the desktop object. if (!SetUserObjectSecurity(hdesk, &si, psd_new.get())) { printf("SetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } return TRUE; }
void impersonateToGetData(PCSTR user, PCSTR domain, PCSTR password, PCSTR kdc, PSID *sid, DWORD *rid, PCSTR usingWhat) { NTSTATUS status; DWORD ret, *aRid, *usage; ANSI_STRING aUser, aKdc, aDomain, aPass, aProg; UNICODE_STRING uUser, uKdc, uDomain, uPass, uProg; SAMPR_HANDLE hServerHandle, hDomainHandle; PSID domainSid; HANDLE hToken, hNewToken; PROCESS_INFORMATION processInfos; STARTUPINFOW startupInfo; RtlZeroMemory(&startupInfo, sizeof(STARTUPINFOW)); startupInfo.cb = sizeof(STARTUPINFOW); RtlInitString(&aUser, user); RtlInitString(&aKdc, kdc); RtlInitString(&aDomain, domain); RtlInitString(&aPass, password); RtlInitString(&aProg, usingWhat ? usingWhat : "winver.exe"); if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uUser, &aUser, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uKdc, &aKdc, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uDomain, &aDomain, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uPass, &aPass, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uProg, &aProg, TRUE))) { if(CreateProcessWithLogonW(uUser.Buffer, uDomain.Buffer, uPass.Buffer, LOGON_NETCREDENTIALS_ONLY, uProg.Buffer, NULL, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInfos)) { if(OpenProcessToken(processInfos.hProcess, TOKEN_DUPLICATE, &hToken)) { if(DuplicateTokenEx(hToken, TOKEN_QUERY | TOKEN_IMPERSONATE, NULL, SecurityDelegation, TokenImpersonation, &hNewToken)) { if(SetThreadToken(NULL, hNewToken)) { kprintf("[AUTH] Impersonation\n"); if(!(*sid && *rid)) { kprintf("[SID/RID] \'%s @ %s\' must be translated to SID/RID\n", user, domain); status = SamConnect(&uKdc, &hServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, FALSE); if(NT_SUCCESS(status)) { status = SamLookupDomainInSamServer(hServerHandle, &uDomain, &domainSid); if(NT_SUCCESS(status)) { status = SamOpenDomain(hServerHandle, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, domainSid, &hDomainHandle); if(NT_SUCCESS(status)) { status = SamLookupNamesInDomain(hDomainHandle, 1, &uUser, &aRid, &usage); if(NT_SUCCESS(status)) *rid = *aRid; else PRINT_ERROR("SamLookupNamesInDomain %08x\n", status); } else PRINT_ERROR("SamOpenDomain %08x\n", status); ret = GetLengthSid(domainSid); if(*sid = (PSID) LocalAlloc(LPTR, ret)) { if(!CopySid(ret, *sid, domainSid)) { *sid = (PSID) LocalFree(*sid); PRINT_ERROR_AUTO("CopySid"); } } SamFreeMemory(domainSid); } else PRINT_ERROR("SamLookupDomainInSamServer %08x\n", status); SamCloseHandle(hServerHandle); } else PRINT_ERROR("SamConnect %08x\n", status); } RevertToSelf(); } else PRINT_ERROR_AUTO("SetThreadToken"); CloseHandle(hNewToken); } else PRINT_ERROR_AUTO("DuplicateTokenEx"); CloseHandle(hToken); } else PRINT_ERROR_AUTO("OpenProcessToken"); TerminateProcess(processInfos.hProcess, 0); CloseHandle(processInfos.hProcess); CloseHandle(processInfos.hThread); } else PRINT_ERROR_AUTO("CreateProcessWithLogonW"); RtlFreeUnicodeString(&uProg); } RtlFreeUnicodeString(&uPass); } RtlFreeUnicodeString(&uDomain); } RtlFreeUnicodeString(&uKdc); } RtlFreeUnicodeString(&uUser); } }
DWORD Sm::GetThreadSID( SID ** ppSID ) { BidxScopeAutoSNI1( SNIAPI_TAG _T( "ppSID: %p{SID**}\n"), ppSID ); BOOL fReturn = FALSE; HANDLE TokenHandle = NULL; PTOKEN_USER pUserToken = NULL; DWORD dwSizeNeeded = 0; DWORD dwError = ERROR_SUCCESS; PSID pSID = NULL; *ppSID = NULL; BOOL fThreadSID = OpenThreadToken( GetCurrentThread(), TOKEN_READ, FALSE, &TokenHandle ); if (fThreadSID) { fReturn = GetTokenInformation( TokenHandle, TokenUser, NULL, 0, &dwSizeNeeded ); if( FALSE == fReturn ) { if( ERROR_INSUFFICIENT_BUFFER != (dwError = GetLastError()) ) { SNI_SET_LAST_ERROR( SM_PROV, SNIE_10, dwError ); goto ErrorExit; } } pUserToken = (PTOKEN_USER) NewNoX(gpmo) BYTE[dwSizeNeeded]; if( !pUserToken ) { dwError = ERROR_OUTOFMEMORY; SNI_SET_LAST_ERROR( SM_PROV, SNIE_4, dwError ); goto ErrorExit; } fReturn = GetTokenInformation( TokenHandle, TokenUser, (LPVOID) pUserToken, dwSizeNeeded, &dwSizeNeeded ); if( FALSE == fReturn ) { dwError = GetLastError(); SNI_SET_LAST_ERROR( SM_PROV, SNIE_10, dwError ); goto ErrorExit; } pSID = pUserToken->User.Sid; } //Grab the Process SID (which is already available from the SOS) else { //We merely grab the SID for the process if( ERROR_NO_TOKEN == (dwError = GetLastError())) { pSID = SOS_OS::GetProcessSID(); } else { dwError = GetLastError(); SNI_SET_LAST_ERROR( SM_PROV, SNIE_10, dwError ); goto ErrorExit; } } // Validate the SID before copying. // if( !IsValidSid( pSID ) ) { dwError = GetLastError(); SNI_SET_LAST_ERROR( SM_PROV, SNIE_10, dwError ); goto ErrorExit; } // Let's make a copy the SID // dwSizeNeeded = GetLengthSid( pSID ); *ppSID = (SID *) NewNoX(gpmo) BYTE[dwSizeNeeded]; if( !*ppSID ) { dwError = ERROR_OUTOFMEMORY; SNI_SET_LAST_ERROR( SM_PROV, SNIE_4, dwError ); goto ErrorExit; } fReturn = CopySid( dwSizeNeeded, *ppSID, pSID ); if( FALSE == fReturn ) { dwError = GetLastError(); SNI_SET_LAST_ERROR( SM_PROV, SNIE_10, dwError ); goto ErrorExit; } //We never obtained a user token at all if this is a process sid if (fThreadSID) { delete [] pUserToken; CloseHandle( TokenHandle ); } BidTraceU1( SNI_BID_TRACE_ON, RETURN_TAG _T("%d{WINERR}\n"), ERROR_SUCCESS); return ERROR_SUCCESS; ErrorExit: if( fThreadSID && pUserToken ) delete [] pUserToken; if( *ppSID ) delete [] *ppSID; *ppSID = 0; if( fThreadSID && TokenHandle ) CloseHandle( TokenHandle ); BidTraceU1( SNI_BID_TRACE_ON, RETURN_TAG _T("%d{WINERR}\n"), dwError); return dwError; }
DWORD Sm::GetThreadSID( __out SID ** ppSID ) { BidxScopeAutoSNI1( SNIAPI_TAG _T( "ppSID: %p{SID**}\n"), ppSID ); BOOL fReturn = FALSE; HANDLE TokenHandle = NULL; PTOKEN_USER pUserToken = NULL; DWORD dwSizeNeeded = 0; DWORD dwError = ERROR_SUCCESS; *ppSID = NULL; fReturn = OpenThreadToken( GetCurrentThread(), TOKEN_READ, FALSE, &TokenHandle ); if( FALSE == fReturn ) { // If this was because there was no token for the thread, then // use the token of the process if( ERROR_NO_TOKEN == (dwError = GetLastError()) ) { fReturn = OpenProcessToken( GetCurrentProcess(), TOKEN_READ, &TokenHandle ); if( FALSE == fReturn ) { dwError = GetLastError(); SNI_SET_LAST_ERROR( SM_PROV, SNIE_10, dwError ); } } else { dwError = GetLastError(); SNI_SET_LAST_ERROR( SM_PROV, SNIE_10, dwError ); } if( FALSE == fReturn ) goto ErrorExit; } fReturn = GetTokenInformation( TokenHandle, TokenUser, NULL, 0, &dwSizeNeeded ); if( FALSE == fReturn ) { if( ERROR_INSUFFICIENT_BUFFER != (dwError = GetLastError()) ) { SNI_SET_LAST_ERROR( SM_PROV, SNIE_10, dwError ); goto ErrorExit; } } pUserToken = (PTOKEN_USER) NewNoX(gpmo) BYTE[dwSizeNeeded]; if( !pUserToken ) { dwError = ERROR_OUTOFMEMORY; SNI_SET_LAST_ERROR( SM_PROV, SNIE_4, dwError ); goto ErrorExit; } fReturn = GetTokenInformation( TokenHandle, TokenUser, (LPVOID) pUserToken, dwSizeNeeded, &dwSizeNeeded ); if( FALSE == fReturn ) { dwError = GetLastError(); SNI_SET_LAST_ERROR( SM_PROV, SNIE_10, dwError ); goto ErrorExit; } // Validate the SID before copying. // if( !IsValidSid( pUserToken->User.Sid ) ) { dwError = GetLastError(); SNI_SET_LAST_ERROR( SM_PROV, SNIE_10, dwError ); goto ErrorExit; } // Let's make a copy the SID // dwSizeNeeded = GetLengthSid( pUserToken->User.Sid ); *ppSID = (SID *) NewNoX(gpmo) BYTE[dwSizeNeeded]; if( !*ppSID ) { dwError = ERROR_OUTOFMEMORY; SNI_SET_LAST_ERROR( SM_PROV, SNIE_4, dwError ); goto ErrorExit; } fReturn = CopySid( dwSizeNeeded, *ppSID, pUserToken->User.Sid ); if( FALSE == fReturn ) { dwError = GetLastError(); SNI_SET_LAST_ERROR( SM_PROV, SNIE_10, dwError ); goto ErrorExit; } delete [] pUserToken; CloseHandle( TokenHandle ); BidTraceU1( SNI_BID_TRACE_ON, RETURN_TAG _T("%d{WINERR}\n"), ERROR_SUCCESS); return ERROR_SUCCESS; ErrorExit: if( pUserToken ) delete [] pUserToken; if( *ppSID ) delete [] *ppSID; *ppSID = 0; if( TokenHandle ) CloseHandle( TokenHandle ); BidTraceU1( SNI_BID_TRACE_ON, RETURN_TAG _T("%d{WINERR}\n"), dwError); return dwError; }
BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid) { // Obtain the DACL for the window station. SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION; DWORD sd_length = 0; if (!GetUserObjectSecurity(hwinsta, &si, NULL, 0, &sd_length)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { printf("GetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } } auto_buffer<PSECURITY_DESCRIPTOR> psd(sd_length); if (!GetUserObjectSecurity(hwinsta, &si, psd.get(), sd_length, &sd_length)) { printf("GetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } // Create a new DACL. auto_buffer<PSECURITY_DESCRIPTOR> psd_new(sd_length); if (!InitializeSecurityDescriptor(psd_new.get(), SECURITY_DESCRIPTOR_REVISION)) { printf("InitializeSecurityDescriptor() failed: %d\n", GetLastError()); return FALSE; } // Get the DACL from the security descriptor. BOOL bDaclPresent; PACL pacl; BOOL bDaclExist; if (!GetSecurityDescriptorDacl(psd.get(), &bDaclPresent, &pacl, &bDaclExist)) { printf("GetSecurityDescriptorDacl() failed: %d\n", GetLastError()); return FALSE; } // Initialize the ACL. ACL_SIZE_INFORMATION aclSizeInfo = {}; aclSizeInfo.AclBytesInUse = sizeof(ACL); if (NULL != pacl) { // get the file ACL size info if (!GetAclInformation(pacl, &aclSizeInfo, sizeof aclSizeInfo, AclSizeInformation)) { printf("GetAclInformation() failed: %d\n", GetLastError()); return FALSE; } } // Compute the size of the new ACL. DWORD new_acl_size = aclSizeInfo.AclBytesInUse + (2 * sizeof(ACCESS_ALLOWED_ACE)) + (2 * GetLengthSid(psid)) - (2 * sizeof(DWORD)); auto_buffer<PACL> new_acl(new_acl_size); // Initialize the new DACL. if (!InitializeAcl(new_acl.get(), new_acl_size, ACL_REVISION)) { printf("InitializeAcl() failed: %d\n", GetLastError()); return FALSE; } // If DACL is present, copy it to a new DACL. if (bDaclPresent) { // Copy the ACEs to the new ACL. if (aclSizeInfo.AceCount) { for (DWORD i = 0; i != aclSizeInfo.AceCount; ++i) { LPVOID pTempAce; if (!GetAce(pacl, i, &pTempAce)) { printf("GetAce() failed: %d\n", GetLastError()); return FALSE; } if (!AddAce(new_acl.get(), ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize)) { printf("AddAce() failed: %d\n", GetLastError()); return FALSE; } } } } // Add the first ACE to the window station. auto_buffer<ACCESS_ALLOWED_ACE*> ace(sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD)); ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; ace->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE; ace->Header.AceSize = (WORD) (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD)); ace->Mask = GENERIC_ACCESS; if (!CopySid(GetLengthSid(psid), &ace->SidStart, psid)) { printf("CopySid() failed: %d\n", GetLastError()); return FALSE; } if (!AddAce(new_acl.get(), ACL_REVISION, MAXDWORD, ace.get(), ace->Header.AceSize)) { printf("AddAce() failed: %d\n", GetLastError()); return FALSE; } // Add the second ACE to the window station. ace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE; ace->Mask = WINSTA_ALL; if (!AddAce(new_acl.get(), ACL_REVISION,MAXDWORD, ace.get(), ace->Header.AceSize)) { printf("AddAce() failed: %d\n", GetLastError()); return FALSE; } // Set a new DACL for the security descriptor. if (!SetSecurityDescriptorDacl(psd_new.get(), TRUE, new_acl.get(), FALSE)) { printf("SetSecurityDescriptorDacl() failed: %d\n", GetLastError()); return FALSE; } // Set the new security descriptor for the window station. if (!SetUserObjectSecurity(hwinsta, &si, psd_new.get())) { printf("SetUserObjectSecurity() failed: %d\n", GetLastError()); return FALSE; } return TRUE; }
bool CSecRunAsUser::SetObjectPermission(CString strDirFile, DWORD lGrantedAccess){ if (!m_hADVAPI32_DLL){ ASSERT ( false ); return false; } if ( strDirFile.IsEmpty() ) return true; SID_NAME_USE snuType; TCHAR* szDomain = NULL; LPVOID pUserSID = NULL; PACL pNewACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; BOOL fAPISuccess; try { // get user sid DWORD cbDomain = 0; DWORD cbUserSID = 0; fAPISuccess = LookupAccountName(NULL, EMULEACCOUNTW, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType); if ( (!fAPISuccess) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) throw CString(_T("Run as unpriveleged user: Error: LookupAccountName() failed,")); pUserSID = MHeapAlloc(cbUserSID); if (!pUserSID) throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,")); szDomain = (TCHAR*)MHeapAlloc(cbDomain * sizeof(TCHAR)); if (!szDomain) throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,")); fAPISuccess = LookupAccountName(NULL, EMULEACCOUNTW, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType); if (!fAPISuccess) throw CString(_T("Run as unpriveleged user: Error: LookupAccountName()2 failed")); if (CStringW(szDomain) != m_strDomain) throw CString(_T("Run as unpriveleged user: Logical Error: Domainname mismatch")); // get old ACL PACL pOldACL = NULL; fAPISuccess = GetNamedSecurityInfo(strDirFile.GetBuffer(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldACL, NULL, &pSD); strDirFile.ReleaseBuffer(); if (fAPISuccess != ERROR_SUCCESS){ throw CString(_T("Run as unpriveleged user: Error: GetNamedSecurityInfo() failed")); } // calculate size for new ACL ACL_SIZE_INFORMATION AclInfo; AclInfo.AceCount = 0; // Assume NULL DACL. AclInfo.AclBytesFree = 0; AclInfo.AclBytesInUse = sizeof(ACL); if (pOldACL != NULL && !GetAclInformation(pOldACL, &AclInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) throw CString(_T("Run as unpriveleged user: Error: GetAclInformation() failed")); // Create new ACL DWORD cbNewACL = AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pUserSID) - sizeof(DWORD); pNewACL = (PACL)MHeapAlloc(cbNewACL); if (!pNewACL) throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,")); if (!InitializeAcl(pNewACL, cbNewACL, ACL_REVISION2)) throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,")); // copy the entries form the old acl into the new one and enter a new ace in the right order uint32 newAceIndex = 0; uint32 CurrentAceIndex = 0; if (AclInfo.AceCount) { for (CurrentAceIndex = 0; CurrentAceIndex < AclInfo.AceCount; CurrentAceIndex++) { LPVOID pTempAce = NULL; if (!GetAce(pOldACL, CurrentAceIndex, &pTempAce)) throw CString(_T("Run as unpriveleged user: Error: GetAce() failed,")); if (((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags & INHERITED_ACE) break; // no multiple entries if (EqualSid(pUserSID, &(((ACCESS_ALLOWED_ACE *)pTempAce)->SidStart))) continue; if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER) pTempAce)->AceSize)) throw CString(_T("Run as unpriveleged user: Error: AddAce()1 failed,")); newAceIndex++; } } // here we add the actually entry if (!AddAccessAllowedAceEx(pNewACL, ACL_REVISION2, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, lGrantedAccess, pUserSID)) throw CString(_T("Run as unpriveleged user: Error: AddAccessAllowedAceEx() failed,")); // copy the rest if (AclInfo.AceCount) { for (; CurrentAceIndex < AclInfo.AceCount; CurrentAceIndex++) { LPVOID pTempAce = NULL; if (!GetAce(pOldACL, CurrentAceIndex, &pTempAce)) throw CString(_T("Run as unpriveleged user: Error: GetAce()2 failed,")); if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER) pTempAce)->AceSize)) throw CString(_T("Run as unpriveleged user: Error: AddAce()2 failed,")); } } fAPISuccess = SetNamedSecurityInfo(strDirFile.GetBuffer(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL); strDirFile.ReleaseBuffer(); if (fAPISuccess != ERROR_SUCCESS) throw CString(_T("Run as unpriveleged user: Error: SetNamedSecurityInfo() failed,")); fAPISuccess = TRUE; } catch(CString error){ fAPISuccess = FALSE; theApp.QueueDebugLogLine(false, error); } // clean up if (pUserSID != NULL) MHeapFree(pUserSID); if (szDomain != NULL) MHeapFree(szDomain); if (pNewACL != NULL) MHeapFree(pNewACL); if (pSD != NULL) LocalFree(pSD); // finished return fAPISuccess!=FALSE; }