// // Function : PrintPermissions // Role : Print and interpret the permissions for threads and processes // Notes : // void PrintPermissions( HANDLE hObject, bool bDesktop) { DWORD dwRet=0; DWORD dwCount=0; PACL DACL; PSECURITY_DESCRIPTOR PSD; ACCESS_ALLOWED_ACE *ACE; // http://msdn2.microsoft.com/en-us/library/aa446654.aspx dwRet = GetSecurityInfo(hObject, SE_WINDOW_OBJECT, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, NULL, NULL, &DACL, NULL, &PSD ); if(hObject==NULL || hObject==INVALID_HANDLE_VALUE) return; if (dwRet!=ERROR_SUCCESS) { DWORD dwError = GetLastError(); fprintf(stderr,"[!] Error - %d %d - GetSecurityInfo\n", dwError,dwRet); return; } else { // http://msdn2.microsoft.com/en-us/library/aa379142.aspx if(IsValidAcl(DACL) == TRUE){ // Now for each ACE in the DACL for(dwCount=0;dwCount<DACL->AceCount;dwCount++){ // http://msdn2.microsoft.com/en-us/library/aa446634.aspx // http://msdn2.microsoft.com/en-us/library/aa379608.aspx if(GetAce(DACL,dwCount,(LPVOID*)&ACE)){ // http://msdn2.microsoft.com/en-us/library/aa374892.aspx SID *sSID = (SID*)&(ACE->SidStart); if(sSID != NULL) { DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; switch(ACE->Header.AceType){ // Allowed ACE case ACCESS_ALLOWED_ACE_TYPE: // Lookup the account name and print it. // http://msdn2.microsoft.com/en-us/library/aa379554.aspx if( !LookupAccountSidA( NULL, sSID, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ) { DWORD dwResult = GetLastError(); if( dwResult == ERROR_NONE_MAPPED){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Allowed - NONMAPPED - SID %s\n", sidToText(sSID)); } else if (dwResult != ERROR_NONE_MAPPED){ fprintf(stderr,"[!] LookupAccountSid Error %u\n", GetLastError()); fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Allowed - ERROR - SID %s\n", sidToText(sSID)); //return; } else { continue; } } else { fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Allowed - %s\\%s\n",lpDomain,lpName); } // print out the ACE mask fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-> Permissions - "); if(!bDesktop){ if(ACE->Mask & WINSTA_ALL_ACCESS) fprintf(stdout,",All"); if(ACE->Mask & WINSTA_ACCESSCLIPBOARD ) fprintf(stdout,",Clipboard"); if(ACE->Mask & WINSTA_ACCESSGLOBALATOMS ) fprintf(stdout,",Global Atoms"); if(ACE->Mask & WINSTA_CREATEDESKTOP ) fprintf(stdout,",Create Desktop"); if(ACE->Mask & WINSTA_ENUMDESKTOPS ) fprintf(stdout,",Enum Desktop"); if(ACE->Mask & WINSTA_ENUMERATE) fprintf(stdout,",Enumerate"); if(ACE->Mask & WINSTA_EXITWINDOWS ) fprintf(stdout,",Exit Windows"); if(ACE->Mask & WINSTA_READATTRIBUTES ) fprintf(stdout,",Read Attributes"); if(ACE->Mask & WINSTA_READSCREEN ) fprintf(stdout,",Read Screen"); if(ACE->Mask & WINSTA_WRITEATTRIBUTES ) fprintf(stdout,",Write Attributes"); if(ACE->Mask & SYNCHRONIZE ) fprintf(stdout,",Synchronize"); if(ACE->Mask & DELETE) fprintf(stdout,",Delete"); if(ACE->Mask & READ_CONTROL) fprintf(stdout,",Read Security"); if(ACE->Mask & WRITE_OWNER) fprintf(stdout,",Change Owner"); if(ACE->Mask & WRITE_DAC) fprintf(stdout,",Change Permissions"); if(ACE->Mask & GENERIC_READ) fprintf(stdout,",Generic Read"); if(ACE->Mask & GENERIC_WRITE ) fprintf(stdout,",Generic Write"); if(ACE->Mask & GENERIC_EXECUTE) fprintf(stdout,",Generic Execute"); if(ACE->Mask & GENERIC_ALL ) fprintf(stdout,",All"); } else { if(ACE->Mask & DELETE ) fprintf(stdout,",Desktop Delete"); if(ACE->Mask & READ_CONTROL ) fprintf(stdout,",Read Security Descriptor"); if(ACE->Mask & DESKTOP_CREATEMENU ) fprintf(stdout,",Create Menu"); if(ACE->Mask & DESKTOP_CREATEWINDOW ) fprintf(stdout,",Create Window"); if(ACE->Mask & DESKTOP_ENUMERATE ) fprintf(stdout,",Enumerate"); if(ACE->Mask & DESKTOP_HOOKCONTROL) fprintf(stdout,",Hook Windows"); if(ACE->Mask & DESKTOP_JOURNALPLAYBACK ) fprintf(stdout,",Journal Playpack"); if(ACE->Mask & DESKTOP_JOURNALRECORD ) fprintf(stdout,",Journal Record"); if(ACE->Mask & DESKTOP_READOBJECTS) fprintf(stdout,",Read Objects"); if(ACE->Mask & DESKTOP_SWITCHDESKTOP ) fprintf(stdout,",Switch Desktop"); if(ACE->Mask & DESKTOP_WRITEOBJECTS) fprintf(stdout,",Write Objects"); if(ACE->Mask & GENERIC_READ) fprintf(stdout,",Generic Read"); if(ACE->Mask & GENERIC_WRITE ) fprintf(stdout,",Generic Write"); if(ACE->Mask & GENERIC_EXECUTE) fprintf(stdout,",Generic Execute"); if(ACE->Mask & GENERIC_ALL ) fprintf(stdout,",All"); } fprintf(stdout,"\n"); break; // Denied ACE case ACCESS_DENIED_ACE_TYPE: break; // Uh oh default: break; } } } else { DWORD dwError = GetLastError(); fprintf(stderr,"[!] Error - %d - GetAce\n", dwError); return; } } } else { DWORD dwError = GetLastError(); fprintf(stderr,"[!] Error - %d - IsValidAcl\n", dwError); return; } } LocalFree(PSD); }
BOOL ValidateSecurity(uch *securitydata) { PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)securitydata; PACL pAcl; PSID pSid; BOOL bAclPresent; BOOL bDefaulted; if(!IsWinNT()) return TRUE; /* don't do anything if not on WinNT */ if(!IsValidSecurityDescriptor(sd)) return FALSE; /* verify Dacl integrity */ if(!GetSecurityDescriptorDacl(sd, &bAclPresent, &pAcl, &bDefaulted)) return FALSE; if(bAclPresent && pAcl!=NULL) { if(!IsValidAcl(pAcl)) return FALSE; } /* verify Sacl integrity */ if(!GetSecurityDescriptorSacl(sd, &bAclPresent, &pAcl, &bDefaulted)) return FALSE; if(bAclPresent && pAcl!=NULL) { if(!IsValidAcl(pAcl)) return FALSE; } /* verify owner integrity */ if(!GetSecurityDescriptorOwner(sd, &pSid, &bDefaulted)) return FALSE; if(pSid != NULL) { if(!IsValidSid(pSid)) return FALSE; } /* verify group integrity */ if(!GetSecurityDescriptorGroup(sd, &pSid, &bDefaulted)) return FALSE; if(pSid != NULL) { if(!IsValidSid(pSid)) return FALSE; } return TRUE; }
/* * GetSD: Accessor function for SecurityDescriptor * Creates an (absolute) SD from the GetACL return value */ PSECURITY_DESCRIPTOR vncAccessControl::GetSD(){ PSECURITY_DESCRIPTOR pSD; PSECURITY_DESCRIPTOR pSelfRelativeSD; PACL pACL = NULL; DWORD dwBufferLength = 0; // If we can't retrieve a valid ACL we create an empty one (i.e. no access). if (!(pACL = GetACL()) || !IsValidAcl(pACL)) { pACL = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ACL)); // Initialize the new ACL. if (!InitializeAcl(pACL, sizeof(ACL), ACL_REVISION)) { ; // Todo: Report an error. } } // Construct SD pSD = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SECURITY_DESCRIPTOR_MIN_LENGTH); if(InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION) && // Set our ACL to the SD. SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE) && // AccessCheck() is picky about what is in the SD. SetSecurityDescriptorOwner(pSD, GetOwnerSID(), FALSE) && SetSecurityDescriptorGroup(pSD, GetOwnerSID(), FALSE)) { } else { // Todo: Report an error. } // Make SD self-relative and use LocalAlloc MakeSelfRelativeSD(pSD, NULL, &dwBufferLength); pSelfRelativeSD = (PSECURITY_DESCRIPTOR) LocalAlloc(0, dwBufferLength); MakeSelfRelativeSD(pSD, pSelfRelativeSD, &dwBufferLength); FreeSD(pSD); return pSelfRelativeSD; }
// @pymethod |PyACL|IsValid|Determines if the ACL is valid (IsValidAcl) PyObject *PyACL::IsValid(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":IsValid")) return NULL; PyACL *This = (PyACL *)self; return PyInt_FromLong(IsValidAcl(This->GetACL())); }
/* * SetSD: Changes the class variable pACL and the reg key. * The ACL is the DACL of the provided SD. */ BOOL vncAccessControl::SetSD(PSECURITY_DESCRIPTOR pSD){ BOOL isOK = FALSE; BOOL bDaclPresent = FALSE; BOOL bDaclDefaulted = FALSE; PACL pDACL = NULL; GetSecurityDescriptorDacl(pSD, &bDaclPresent, &pDACL, &bDaclDefaulted); if (bDaclPresent && pDACL && IsValidAcl(pDACL) && StoreACL(pDACL)) isOK = TRUE; return isOK; }
HRESULT COpcSecurity::Attach(PSECURITY_DESCRIPTOR pSelfRelativeSD) { PACL pDACL = NULL; PACL pSACL = NULL; BOOL bDACLPresent, bSACLPresent; BOOL bDefaulted; PACL m_pDACL = NULL; ACCESS_ALLOWED_ACE* pACE; HRESULT hr; PSID pUserSid; PSID pGroupSid; hr = Initialize(); if(FAILED(hr)) return hr; // get the existing DACL. if (!GetSecurityDescriptorDacl(pSelfRelativeSD, &bDACLPresent, &pDACL, &bDefaulted)) goto failed; if (bDACLPresent) { if (pDACL) { // allocate new DACL. m_pDACL = (PACL) malloc(pDACL->AclSize); if (m_pDACL == NULL) { hr = E_OUTOFMEMORY; goto failedMemory; } // initialize the DACL if (!InitializeAcl(m_pDACL, pDACL->AclSize, ACL_REVISION)) goto failed; // copy the ACES for (int i = 0; i < pDACL->AceCount; i++) { if (!GetAce(pDACL, i, (void **)&pACE)) goto failed; if (!AddAccessAllowedAce(m_pDACL, ACL_REVISION, pACE->Mask, (PSID)&(pACE->SidStart))) goto failed; } if (!IsValidAcl(m_pDACL)) goto failed; } // set the DACL if (!SetSecurityDescriptorDacl(m_pSD, m_pDACL ? TRUE : FALSE, m_pDACL, bDefaulted)) goto failed; } // get the existing SACL. if (!GetSecurityDescriptorSacl(pSelfRelativeSD, &bSACLPresent, &pSACL, &bDefaulted)) goto failed; if (bSACLPresent) { if (pSACL) { // allocate new SACL. m_pSACL = (PACL) malloc(pSACL->AclSize); if (m_pSACL == NULL) { hr = E_OUTOFMEMORY; goto failedMemory; } // initialize the SACL if (!InitializeAcl(m_pSACL, pSACL->AclSize, ACL_REVISION)) goto failed; // copy the ACES for (int i = 0; i < pSACL->AceCount; i++) { if (!GetAce(pSACL, i, (void **)&pACE)) goto failed; if (!AddAccessAllowedAce(m_pSACL, ACL_REVISION, pACE->Mask, (PSID)&(pACE->SidStart))) goto failed; } if (!IsValidAcl(m_pSACL)) goto failed; } // set the SACL if (!SetSecurityDescriptorSacl(m_pSD, m_pSACL ? TRUE : FALSE, m_pSACL, bDefaulted)) goto failed; } if (!GetSecurityDescriptorOwner(m_pSD, &pUserSid, &bDefaulted)) goto failed; if (FAILED(SetOwner(pUserSid, bDefaulted))) goto failed; if (!GetSecurityDescriptorGroup(m_pSD, &pGroupSid, &bDefaulted)) goto failed; if (FAILED(SetGroup(pGroupSid, bDefaulted))) goto failed; if (!IsValidSecurityDescriptor(m_pSD)) goto failed; return hr; failed: hr = HRESULT_FROM_WIN32(hr); failedMemory: if (m_pDACL) { free(m_pDACL); m_pDACL = NULL; } if (m_pSD) { free(m_pSD); m_pSD = NULL; } return hr; }
void PrintPermissionsTok( PACL DACL) { DWORD dwCount=0; ACCESS_ALLOWED_ACE *ACE; // http://msdn2.microsoft.com/en-us/library/aa379142.aspx if(IsValidAcl(DACL) == TRUE){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-> Default DACL for new objects created by this user\n"); // Now for each ACE in the DACL for(dwCount=0;dwCount<DACL->AceCount;dwCount++){ // http://msdn2.microsoft.com/en-us/library/aa446634.aspx // http://msdn2.microsoft.com/en-us/library/aa379608.aspx if(GetAce(DACL,dwCount,(LPVOID*)&ACE)){ // http://msdn2.microsoft.com/en-us/library/aa374892.aspx SID *sSID = (SID*)&(ACE->SidStart); if(sSID != NULL) { DWORD dwSize = 2048; char lpName[2048]; char lpDomain[2048]; SID_NAME_USE SNU; switch(ACE->Header.AceType){ // Allowed ACE case ACCESS_ALLOWED_ACE_TYPE: // Lookup the account name and print it. // http://msdn2.microsoft.com/en-us/library/aa379554.aspx if( !LookupAccountSidA( NULL, sSID, lpName, &dwSize, lpDomain, &dwSize, &SNU ) ) { DWORD dwResult = GetLastError(); if( dwResult == ERROR_NONE_MAPPED ){ fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +---+-> Allowed - NONMAPPED - SID %s\n", sidToTextTok(sSID)); } else if (dwResult != ERROR_NONE_MAPPED){ fprintf(stderr,"[!] LookupAccountSid Error %u\n", GetLastError()); fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +---+-> Allowed - ERROR - SID %s\n", sidToTextTok(sSID)); //return; } else { continue; } } else { fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +---+-> Allowed - %s\\%s\n",lpDomain,lpName); char strUserFromPID[1024]; memset(strUserFromPID,0x00,1024); if(!strcmp(lpDomain,"BUILTIN")==0 && !strcmp(lpName,"OWNER RIGHTS")==0 && !strcmp(lpDomain,"NT AUTHORITY")==0 && !strcmp(lpDomain,"NT SERVICE")==0) { fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-+-+-> Alert!\n"); } } // print out the ACE mask fprintf(stdout,"[i] |\n"); fprintf(stdout,"[i] +-> Permissions - "); if(ACE->Mask & GENERIC_ALL) fprintf(stdout,",All"); if(ACE->Mask & GENERIC_EXECUTE) fprintf(stdout,",Execute"); if(ACE->Mask & GENERIC_READ) fprintf(stdout,",Read"); if(ACE->Mask & GENERIC_WRITE) fprintf(stdout,",Write"); if(ACE->Mask & DELETE) fprintf(stdout,",Delete"); if(ACE->Mask & READ_CONTROL) fprintf(stdout,",Read control"); if(ACE->Mask & SYNCHRONIZE) fprintf(stdout,",Sync"); if(ACE->Mask & WRITE_DAC) fprintf(stdout,",Modify DACL"); if(ACE->Mask & WRITE_OWNER) fprintf(stdout,",Write Owner"); if(ACE->Mask & STANDARD_RIGHTS_ALL) fprintf(stdout,",All"); if(ACE->Mask & STANDARD_RIGHTS_EXECUTE) fprintf(stdout,",Execute"); if(ACE->Mask & STANDARD_RIGHTS_READ) fprintf(stdout,",Read Control"); if(ACE->Mask & STANDARD_RIGHTS_REQUIRED) fprintf(stdout,",Write"); if(ACE->Mask & STANDARD_RIGHTS_WRITE) fprintf(stdout,",Read Control"); fprintf(stdout,"\n"); break; // Denied ACE case ACCESS_DENIED_ACE_TYPE: break; // Uh oh default: break; } } } else { DWORD dwError = GetLastError(); fprintf(stderr,"[!] Error - %d - GetAce\n", dwError); return; } } } else { DWORD dwError = GetLastError(); fprintf(stderr,"[!] Error - %d - IsValidAcl\n", dwError); return; } }
// https://ru.wikipedia.org/wiki/DACL + https://github.com/hfiref0x/WinObjEx64/tree/master/Source BOOL AddAllowSidForDevice(PWCHAR wchPath, PSID lpSid, DWORD dwSidLength) { OBJECT_ATTRIBUTES ObjAtt; RtlZeroMemory(&ObjAtt, sizeof(ObjAtt)); UNICODE_STRING UserModeDeviceName; WCHAR PathBuffer[MAX_PATH] = { 0 }; wcscpy_s(PathBuffer, L"\\??\\"); wcscat_s(PathBuffer, wchPath); UserModeDeviceName.Buffer = PathBuffer; UserModeDeviceName.Length = (USHORT)(wcslen(PathBuffer) * sizeof(WCHAR)); UserModeDeviceName.MaximumLength = (USHORT)(UserModeDeviceName.Length + sizeof(WCHAR)); InitializeObjectAttributes(&ObjAtt, &UserModeDeviceName, 0, 0, 0); HANDLE hFile; IO_STATUS_BLOCK IoStatusBlock; NTSTATUS status = ntdll_ZwOpenFile(&hFile, WRITE_DAC | READ_CONTROL, &ObjAtt, &IoStatusBlock, 0, 0); if (status != STATUS_SUCCESS) { DebugOut("ZwOpenFile(..., %S,...) failed! (status=%x)\n", wchPath, status); return FALSE; } DWORD LastError; SECURITY_DESCRIPTOR *lpSd = NULL; // адрес дескриптора безопасности DWORD dwSdLength = 0; // длина SD if (!GetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, NULL, dwSdLength, &dwSdLength)) { LastError = GetLastError(); if (LastError == ERROR_INSUFFICIENT_BUFFER) { dwSdLength += 1000; // !! FIX_ME lpSd = (SECURITY_DESCRIPTOR*)malloc(dwSdLength); if (!GetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, lpSd, dwSdLength, &dwSdLength)) { DebugOut("GetKernelObjectSecurity[2](...) failed! (LastError=0x%x)\n", GetLastError()); CloseHandle(hFile); return FALSE; } } else { DebugOut("GetKernelObjectSecurity[1](...) failed! (LastError=0x%x)\n", LastError); CloseHandle(hFile); return FALSE; } } ACL* lpOldDacl; // указатель на старый DACL BOOL bDaclPresent; // признак присутствия списка DACL BOOL bDaclDefaulted; // признак списка DACL по умолчанию if (!GetSecurityDescriptorDacl(lpSd, &bDaclPresent, &lpOldDacl, &bDaclDefaulted)) { // получаем список DACL из дескриптора безопасности DebugOut("GetSecurityDescriptorDacl(...) failed! (LastError=0x%x)\n", GetLastError()); CloseHandle(hFile); return FALSE; } DWORD dwDaclLength = lpOldDacl->AclSize + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + dwSidLength; // определяем длину нового DACL ACL* lpNewDacl = (ACL*)malloc(dwDaclLength); if (!InitializeAcl(lpNewDacl, dwDaclLength, ACL_REVISION)) { // инициализируем новый DACL DebugOut("InitializeAcl(...) failed! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } if (!AddAccessAllowedAce(lpNewDacl, ACL_REVISION,ACCOUNT_ALLOW_RIGHTS, lpSid)) { // добавляем новый элемент в новый DACL DebugOut("AddAccessAllowedAce(...) failed! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } LPVOID lpAce; // указатель на элемент ACE if (!GetAce(lpOldDacl, 0, &lpAce)) { // получаем адрес первого ACE в старом списке DACL DebugOut("GetAce(...) failed! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } // переписываем элементы из старого DACL в новый DACL if (bDaclPresent) { if (!AddAce(lpNewDacl, ACL_REVISION, MAXDWORD, lpAce, lpOldDacl->AclSize - sizeof(ACL))) { DebugOut("AddAce(...) failed! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } } if (!IsValidAcl(lpNewDacl)) { // проверяем достоверность DACL DebugOut("IsValidAcl(...) == FALSE! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } SECURITY_DESCRIPTOR sdAbsoluteSd; // абсолютный формат SD if (!InitializeSecurityDescriptor(&sdAbsoluteSd, SECURITY_DESCRIPTOR_REVISION)) { // создаем новый дескриптор безопасности в абсолютной форме DebugOut("InitializeSecurityDescriptor(...) failed! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } if (!SetSecurityDescriptorDacl(&sdAbsoluteSd, TRUE, lpNewDacl, FALSE)) { // устанавливаем DACL в новый дескриптор безопасности DebugOut("SetSecurityDescriptorDacl(...) failed! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } // проверяем структуру дескриптора безопасности if (!IsValidSecurityDescriptor(&sdAbsoluteSd)) { DebugOut("IsValidSecurityDescriptor(...) == FALSE! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } if (!SetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, &sdAbsoluteSd)) { // устанавливаем новый дескриптор безопасности DebugOut("IsValidSecurityDescriptor(...) == FALSE! (LastError=0x%x)\n", GetLastError()); free(lpNewDacl); CloseHandle(hFile); return FALSE; } free(lpNewDacl); CloseHandle(hFile); DebugOut("ACL Rules applyed to \"%S\"\n", PathBuffer); return TRUE; }
BOOL CreateSecurityDescriptor(const char* pUserName, IN OUT SECURITY_DESCRIPTOR * psd) { BOOL fReturnCode = FALSE; PSID psidAdmins = NULL; PACL paclKey = NULL; DWORD cbReferencedDomain = 16; DWORD cbSid = 128; LPSTR lpReferencedDomain = NULL; PSID psidUser = NULL; SID_NAME_USE sidNameUse; SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY; // Here we're creating a System Identifier (SID) to represent // the Admin group. if (!AllocateAndInitializeSid(&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmins)) { goto cleanup; } // Now we'll find the System Identifier which represents // the specified user if((psidUser = HeapAlloc(GetProcessHeap(), 0, cbSid)) == NULL) { goto cleanup; } if((lpReferencedDomain = (LPSTR) HeapAlloc(GetProcessHeap(), 0, cbReferencedDomain)) == NULL) { goto cleanup; } if (!LookupAccountName(NULL, // local system pUserName, // account name psidUser, // receive SID of the account &cbSid, // size of the SID lpReferencedDomain, // buffer to receive user's domain &cbReferencedDomain, // size of UserDomain buffer &sidNameUse)) // type of the user account { fReturnCode = FALSE; goto cleanup; } if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION)) { goto cleanup; } // We want the admin group to own this key. if (!SetSecurityDescriptorOwner(psd, psidAdmins, 0)) { goto cleanup; } // Finally we must allocate and construct the discretionary // access control list (DACL) for the key. // Note that _alloca allocates memory on the stack frame // which will automatically be deallocated when this routine // exits. //if (!(paclKey = (PACL) _alloca(ACL_BUFFER_SIZE))) //{ // goto cleanup; //} if (!(paclKey = (PACL) malloc(ACL_BUFFER_SIZE))) { goto cleanup; } if (!InitializeAcl(paclKey, ACL_BUFFER_SIZE, ACL_REVISION)) { goto cleanup; } // Our DACL will contain two access control entries (ACEs). One which allows // members of the Admin group complete access to the key, and one which gives // read-only access to everyone. if (!AddAccessAllowedAce(paclKey, ACL_REVISION, KEY_ALL_ACCESS, psidAdmins)) { goto cleanup; } if (!AddAccessAllowedAce(paclKey, ACL_REVISION, KEY_ALL_ACCESS, psidUser)) { goto cleanup; } if (!IsValidAcl(paclKey)) { goto cleanup; } // We must bind this DACL to the security descriptor... if (!SetSecurityDescriptorDacl(psd, TRUE, paclKey, FALSE)) { goto cleanup; } if (!IsValidSecurityDescriptor(psd)) { goto cleanup; } fReturnCode = TRUE; cleanup: if (paclKey) { free(paclKey); paclKey = NULL; } return fReturnCode; }