// return a copy of the SID of the owner of the current process // const PSID my_user_Sid() { PSID psid = NULL; HANDLE hToken = NULL; if ( ! OpenProcessToken(GetCurrentProcess(),TOKEN_READ,&hToken)) { dprintf(D_ALWAYS, "my_user_Sid: OpenProcessToken failed error = %d", GetLastError()); return NULL; } BYTE buf[256]; DWORD cbBuf = sizeof(buf); if ( ! GetTokenInformation(hToken, TokenUser, &buf, cbBuf, &cbBuf)) { dprintf(D_ALWAYS, "my_user_Sid: GetTokenInformation failed error = %d", GetLastError()); } else { TOKEN_USER * ptu = (TOKEN_USER*)buf; DWORD cbSid = GetLengthSid(ptu->User.Sid); psid = malloc(cbSid); if (psid) { CopySid(cbSid, psid, ptu->User.Sid); } } CloseHandle(hToken); return psid; }
static int iwin32_file_get_group (const char *file, group_id_t *gid) { char file_sd_buf [256]; DWORD sd_size = 256; PSECURITY_DESCRIPTOR file_sd = (PSECURITY_DESCRIPTOR) &file_sd_buf; PSID sid; BOOL dummy; assert (file != NULL); assert (gid != NULL); if (!InitializeSecurityDescriptor (file_sd, SECURITY_DESCRIPTOR_REVISION)) return 0; if (!GetFileSecurity (file, (SECURITY_INFORMATION)(GROUP_SECURITY_INFORMATION), file_sd, sizeof (file_sd_buf), &sd_size)) return 0; if (!GetSecurityDescriptorGroup (file_sd, &sid, &dummy)) return 0; if (!IsValidSid (sid)) return 0; gid->value = malloc (sd_size); if (!gid->value) return 0; if (!CopySid (sd_size, gid->value, sid)) return 0; return 1; }
static SECURITY_ATTRIBUTES* security_attributes(void) { static int initialized; static SECURITY_ATTRIBUTES asa; static int aclbuf[512]; static ACL* acl = (ACL*)&aclbuf[0]; static SECURITY_DESCRIPTOR asd; static int sid[SID_BUF_MAX]; if (initialized < 0) return 0; if (initialized > 0) return &asa; initialized = -1; CopySid(sizeof(sid), (SID*)sid, &admins_sid_hdr); *GetSidSubAuthority((SID*)sid, 1) = DOMAIN_ALIAS_RID_ADMINS; InitializeSecurityDescriptor(&asd, SECURITY_DESCRIPTOR_REVISION); if (!SetSecurityDescriptorGroup(&asd, (SID*)sid, 0)) return 0; if (!InitializeAcl(acl, sizeof(ACL) + 2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + GetLengthSid((SID*)sid) + GetLengthSid(&worldsid), ACL_REVISION)) return 0; if (!AddAccessAllowedAce(acl, ACL_REVISION, GENERIC_ALL|READ_CONTROL|WRITE_DAC, (SID*)sid)) return 0; if (!AddAccessAllowedAce(acl, ACL_REVISION, GENERIC_READ, &worldsid)) return 0; if (!SetSecurityDescriptorDacl(&asd, 1, acl, 0)) return 0; asa.nLength = sizeof(asa); asa.bInheritHandle = 0; asa.lpSecurityDescriptor = &asd; initialized = 1; return &asa; }
static sid make_sid(PSID Sid) { DWORD Size = GetLengthSid(Sid); sid Copy(Size); CopySid(Size, Copy.get(), Sid); return Copy; };
auto_buffer<PSID> GetLogonSID(HANDLE token) { // Determine the needed buffer size. DWORD groups_length = 0; if (!GetTokenInformation(token, TokenGroups, NULL, 0, &groups_length)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { return auto_buffer<PSID>(); } } auto_buffer<PTOKEN_GROUPS> ptg(groups_length); // Get the token group information from the access token. if (!GetTokenInformation(token, TokenGroups, ptg.get(), groups_length, &groups_length)) { return auto_buffer<PSID>(); } // Loop through the groups to find the logon SID. for (int i = 0; i != ptg->GroupCount; ++i) { if ((ptg->Groups[i].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID) { DWORD sid_length = GetLengthSid(ptg->Groups[i].Sid); auto_buffer<PSID> r(sid_length); if (CopySid(sid_length, r.get(), ptg->Groups[i].Sid)) { return r; } break; } } return auto_buffer<PSID>(); }
/** copy sid @param from sif to copy from @return copied sid, need to be free'd with free @note null sid's are handled too */ PSID copySid(PSID from) { if (!from) { return 0; } int sidLength = GetLengthSid(from); PSID to = (PSID) malloc(sidLength); CopySid(sidLength, to, from); return to; }
CIdentity* CServer::GetSID() { PSID pSid = NULL; HANDLE hToken = INVALID_HANDLE_VALUE; hToken = GetToken(); if(hToken!=INVALID_HANDLE_VALUE) { DWORD dwNeeded=0; BOOL bRes=GetTokenInformation(hToken, TokenUser, NULL, 0, &dwNeeded ); if(bRes==FALSE && GetLastError()==ERROR_INSUFFICIENT_BUFFER) { TOKEN_USER* pBuffer=(TOKEN_USER*) new BYTE[dwNeeded]; if(pBuffer!=NULL) { BOOL bRes=GetTokenInformation(hToken, TokenUser, (LPVOID)pBuffer, dwNeeded, &dwNeeded ); if(bRes==TRUE) { DWORD dwSidLen=GetLengthSid(pBuffer->User.Sid); pSid=(PSID) new BYTE[dwSidLen]; if(pSid!=NULL) { if(CopySid(dwSidLen, pSid, pBuffer->User.Sid)==FALSE) { delete[] pSid; pSid=NULL; } } } delete[] pBuffer; } } CloseHandle(hToken); } CSID* pIdentity=NULL ; if(pSid!=NULL) { pIdentity=new CSID(pSid); if(pIdentity==NULL) { delete[] pSid; } } return (CIdentity*) pIdentity; }
PSID get_user_sid(void) { HANDLE proc = NULL, tok = NULL; TOKEN_USER *user = NULL; DWORD toklen, sidlen; PSID sid = NULL, ret = NULL; if (usersid) return usersid; if (!got_advapi()) goto cleanup; if ((proc = OpenProcess(MAXIMUM_ALLOWED, FALSE, GetCurrentProcessId())) == NULL) goto cleanup; if (!p_OpenProcessToken(proc, TOKEN_QUERY, &tok)) goto cleanup; if (!p_GetTokenInformation(tok, TokenUser, NULL, 0, &toklen) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto cleanup; if ((user = (TOKEN_USER *)LocalAlloc(LPTR, toklen)) == NULL) goto cleanup; if (!p_GetTokenInformation(tok, TokenUser, user, toklen, &toklen)) goto cleanup; sidlen = GetLengthSid(user->User.Sid); sid = (PSID)smalloc(sidlen); if (!CopySid(sidlen, sid, user->User.Sid)) goto cleanup; /* Success. Move sid into the return value slot, and null it out * to stop the cleanup code freeing it. */ ret = usersid = sid; sid = NULL; cleanup: if (proc != NULL) CloseHandle(proc); if (tok != NULL) CloseHandle(tok); if (user != NULL) LocalFree(user); if (sid != NULL) sfree(sid); return ret; }
PSID vncImportACL::CopySID(PSID pSID){ PSID pNewSID = NULL; DWORD sidLength = 0; if (IsValidSid(pSID)){ sidLength = GetLengthSid(pSID); pNewSID = (PSID) new char[sidLength]; CopySid(sidLength, pNewSID, pSID); } return pNewSID; }
HRESULT COpcSecurity::SetGroup(PSID pGroupSid, BOOL bDefaulted) { OPCASSERT(m_pSD); // Mark the SD as having no Group if (!SetSecurityDescriptorGroup(m_pSD, NULL, bDefaulted)) { HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); OPCASSERT(FALSE); return hr; } if (m_pGroup) { free(m_pGroup); m_pGroup = NULL; } // If they asked for no Group don't do the copy if (pGroupSid == NULL) return S_OK; // Make a copy of the Sid for the return value DWORD dwSize = GetLengthSid(pGroupSid); m_pGroup = (PSID) malloc(dwSize); if (m_pGroup == NULL) return E_OUTOFMEMORY; if (!CopySid(dwSize, m_pGroup, pGroupSid)) { HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); OPCASSERT(FALSE); free(m_pGroup); m_pGroup = NULL; return hr; } OPCASSERT(IsValidSid(m_pGroup)); if (!SetSecurityDescriptorGroup(m_pSD, m_pGroup, bDefaulted)) { HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); OPCASSERT(FALSE); free(m_pGroup); m_pGroup = NULL; return hr; } return S_OK; }
VOID WINAPI CachedGetUserFromSid( PSID pSid, LPWSTR pUserName, PULONG pcwcUserName) { PLIST_ENTRY pCur; PSIDTOUSERNAME pEntry; ULONG cbSid, cwcUserName; cwcUserName = *pcwcUserName; /* Walk through the list */ for(pCur = SidToUserNameHead.Flink; pCur != &SidToUserNameHead; pCur = pCur->Flink) { pEntry = CONTAINING_RECORD(pCur, SIDTOUSERNAME, List); if (EqualSid((PSID)&pEntry->Data, pSid)) { wcsncpy(pUserName, pEntry->pszName, cwcUserName); *pcwcUserName = cwcUserName; return; } } /* We didn't find the SID in the list, get the name conventional */ SidToUserName(pSid, pUserName, cwcUserName); /* Allocate a new entry */ *pcwcUserName = wcslen(pUserName); cwcUserName = *pcwcUserName + 1; cbSid = GetLengthSid(pSid); pEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(SIDTOUSERNAME) + cbSid + cwcUserName * sizeof(WCHAR)); /* Copy the Sid and name to our entry */ CopySid(cbSid, (PSID)&pEntry->Data, pSid); pEntry->pszName = (LPWSTR)(pEntry->Data + cbSid); wcsncpy(pEntry->pszName, pUserName, cwcUserName); /* Insert the new entry */ pEntry->List.Flink = &SidToUserNameHead; pEntry->List.Blink = SidToUserNameHead.Blink; SidToUserNameHead.Blink->Flink = &pEntry->List; SidToUserNameHead.Blink = &pEntry->List; return; }
PSID tsrm_win32_get_token_sid(HANDLE hToken) { DWORD dwLength = 0; PTOKEN_USER pTokenUser = NULL; DWORD sid_len; PSID pResultSid = NULL; /* Get the actual size of the TokenUser structure */ if (!GetTokenInformation( hToken, TokenUser, (LPVOID) pTokenUser, 0, &dwLength)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { goto Finished; } pTokenUser = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); if (pTokenUser == NULL) { goto Finished; } } /* and fetch it now */ if (!GetTokenInformation( hToken, TokenUser, (LPVOID) pTokenUser, dwLength, &dwLength)) { goto Finished; } sid_len = GetLengthSid(pTokenUser->User.Sid); /* ConvertSidToStringSid(pTokenUser->User.Sid, &ptcSidOwner); */ pResultSid = malloc(sid_len); if (!pResultSid) { goto Finished; } if (!CopySid(sid_len, pResultSid, pTokenUser->User.Sid)) { goto Finished; } HeapFree(GetProcessHeap(), 0, (LPVOID)pTokenUser); return pResultSid; Finished: if (pResultSid) { free(pResultSid); } /* Free the buffer for the token groups. */ if (pTokenUser != NULL) { HeapFree(GetProcessHeap(), 0, (LPVOID)pTokenUser); } return NULL; }
static void add_sid_cache(wchar_t *computer,PSID sid,bool full,wchar_t **username) { *username=(wchar_t*)L"Account Unknown"; CacheRecord *new_rec=(CacheRecord *)malloc(sizeof(CacheRecord)); if(new_rec) { new_rec->sid=(PSID)malloc(GetLengthSid(sid)); if(new_rec->sid) { DWORD name_size=0,domain_size=0; SID_NAME_USE type; CopySid(GetLengthSid(sid),new_rec->sid,sid); if(!LookupAccountSidW(computer,sid,NULL,&name_size,NULL,&domain_size,&type)) if(GetLastError()==ERROR_INSUFFICIENT_BUFFER) { new_rec->username=(wchar_t*)malloc((name_size+domain_size)*sizeof(wchar_t)); if(new_rec->username) { wchar_t *domain_ptr=new_rec->username,*user_ptr=new_rec->username+domain_size; if(domain_size==1) { user_ptr=new_rec->username; domain_ptr=new_rec->username+name_size; } if(LookupAccountSidW(computer,sid,user_ptr,&name_size,domain_ptr,&domain_size,&type)) { if(domain_size) new_rec->username[domain_size]='\\'; new_rec->username_only=user_ptr; new_rec->next=sid_cache; sid_cache=new_rec; if(full) { *username=new_rec->username; } else { *username=new_rec->username_only; } return; } } } } free(new_rec->sid); free(new_rec->username); free(new_rec); } }
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); }
SIDCacheItem(const wchar_t *Computer,PSID InitSID) { Sid=xf_malloc(GetLengthSid(InitSID)); if(Sid) { if(CopySid(GetLengthSid(InitSID),Sid,InitSID)) { DWORD AccountLength=0,DomainLength=0; SID_NAME_USE snu; LookupAccountSid(Computer,Sid,nullptr,&AccountLength,nullptr,&DomainLength,&snu); if (AccountLength && DomainLength) { string strAccountName,strDomainName; LPWSTR AccountName=strAccountName.GetBuffer(AccountLength); LPWSTR DomainName=strDomainName.GetBuffer(DomainLength); if (AccountName && DomainName) { if(LookupAccountSid(Computer,Sid,AccountName,&AccountLength,DomainName,&DomainLength,&snu)) { strUserName=string(DomainName).Append(L"\\").Append(AccountName); } } } else { LPWSTR StrSid; if(ConvertSidToStringSid(Sid, &StrSid)) { strUserName = StrSid; LocalFree(StrSid); } } } } if(strUserName.IsEmpty()) { xf_free(Sid); Sid=nullptr; } }
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; }
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; }
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; }
/* * @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; }
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( __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; }
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; }
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; }
///////////////////////////////////////////////////////////////////////// // // OnSetCurrentUser() // // Sets the current user of the device. // // Parameters: // user [in] // A const pointer to a SID that identifies the new current user of the // device. Note that ownership of the SID is NOT passed to the callee. // // Return Values: // S_OK: The user has been set to the SID passed in, or the SID passed in // is the same as the user currently set // ///////////////////////////////////////////////////////////////////////// __override HRESULT CWssBasicDDI::OnSetCurrentUser(_In_ const SID* pUser) { HRESULT hr = S_OK; if (NULL == pUser) { return E_POINTER; } if (NULL == m_pUserSID) { return E_OUTOFMEMORY; } // If the SID passed in is the same as the user currently set, then there is no work to do if (TRUE == EqualSid(m_pUserSID, const_cast<SID*>(pUser))) { return S_OK; } // Set the current user to the SID passed in if (TRUE == CopySid((DWORD)m_cbUserSID, m_pUserSID, const_cast<SID*>(pUser))) { if (NULL != g_pDataManager) { // A new user has logged on. For this sample, we want to wipe the data off the device hr = g_pDataManager->DeleteAllApplications(); if (SUCCEEDED(hr)) { APPLICATION_ID* pAppIds = NULL; DWORD cAppIds = 0; // Get the cached application order from the property store for this user hr = GetStoredApplicationOrder(&pAppIds, &cAppIds); if (SUCCEEDED(hr)) { // Set the application order in the data manager HRESULT hrChangeSortOrder = g_pDataManager->ChangeSortOrder(pAppIds, cAppIds); if (FAILED(hrChangeSortOrder)) { hr = hrChangeSortOrder; } } else { // Not a failure; it just means we don't have any stored order hr = S_OK; } if (NULL != pAppIds) { ::CoTaskMemFree(pAppIds); } } } else { hr = E_POINTER; } } else { hr = HRESULT_FROM_WIN32(GetLastError()); } return hr; }
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; }
/** * 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; }