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; }
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; }
/* * 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; }
isc_result_t isc_fsaccess_changeowner(const char *filename, const char *user) { SECURITY_DESCRIPTOR psd; BYTE sidBuffer[500]; BYTE groupBuffer[500]; PSID psid=(PSID) &sidBuffer; DWORD sidBufferSize = sizeof(sidBuffer); char domainBuffer[100]; DWORD domainBufferSize = sizeof(domainBuffer); SID_NAME_USE snu; PSID pSidGroup = (PSID) &groupBuffer; DWORD groupBufferSize = sizeof(groupBuffer); /* * Determine if this is a FAT or NTFS disk and * call the appropriate function to set the ownership * FAT disks do not have ownership attributes so it's * a noop. */ if (is_ntfs(filename) == FALSE) return (ISC_R_SUCCESS); if (!InitializeSecurityDescriptor(&psd, SECURITY_DESCRIPTOR_REVISION)) return (ISC_R_NOPERM); if (!LookupAccountName(0, user, psid, &sidBufferSize, domainBuffer, &domainBufferSize, &snu)) return (ISC_R_NOPERM); /* Make sure administrators can get to it */ domainBufferSize = sizeof(domainBuffer); if (!LookupAccountName(0, "Administrators", pSidGroup, &groupBufferSize, domainBuffer, &domainBufferSize, &snu)) return (ISC_R_NOPERM); if (!SetSecurityDescriptorOwner(&psd, psid, FALSE)) return (ISC_R_NOPERM); if (!SetSecurityDescriptorGroup(&psd, pSidGroup, FALSE)) return (ISC_R_NOPERM); if (!SetFileSecurity(filename, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION, &psd)) return (ISC_R_NOPERM); return (ISC_R_SUCCESS); }
/*---------------------------------------------------------------------------*\ * 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; }
//Code taken from http://stackoverflow.com/questions/1453497/discover-if-user-has-admin-rights Have not checked if it is valid yet.... TODO!!! bool RemoteDesktop::IsUserAdmin(){ struct Data { PACL pACL; PSID psidAdmin; HANDLE hToken; HANDLE hImpersonationToken; PSECURITY_DESCRIPTOR psdAdmin; Data() : pACL(NULL), psidAdmin(NULL), hToken(NULL), hImpersonationToken(NULL), psdAdmin(NULL) {} ~Data() { if (pACL) LocalFree(pACL); if (psdAdmin) LocalFree(psdAdmin); if (psidAdmin) FreeSid(psidAdmin); if (hImpersonationToken) CloseHandle(hImpersonationToken); if (hToken) CloseHandle(hToken); } } data; BOOL fReturn = FALSE; DWORD dwStructureSize = sizeof(PRIVILEGE_SET); PRIVILEGE_SET ps; GENERIC_MAPPING GenericMapping; SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY; const DWORD ACCESS_READ = 1; const DWORD ACCESS_WRITE = 2; if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &data.hToken)) { if (GetLastError() != ERROR_NO_TOKEN) return false; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &data.hToken)) return false; } if (!DuplicateToken(data.hToken, SecurityImpersonation, &data.hImpersonationToken)) return false; if (!AllocateAndInitializeSid(&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &data.psidAdmin)) return false; data.psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if (data.psdAdmin == NULL) return false; if (!InitializeSecurityDescriptor(data.psdAdmin, SECURITY_DESCRIPTOR_REVISION)) return false; // Compute size needed for the ACL. auto dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(data.psidAdmin) - sizeof(DWORD); data.pACL = (PACL)LocalAlloc(LPTR, dwACLSize); if (data.pACL == NULL) return false; if (!InitializeAcl(data.pACL, dwACLSize, ACL_REVISION2)) return false; DWORD dwAccessMask = ACCESS_READ | ACCESS_WRITE; if (!AddAccessAllowedAce(data.pACL, ACL_REVISION2, dwAccessMask, data.psidAdmin)) return false; if (!SetSecurityDescriptorDacl(data.psdAdmin, TRUE, data.pACL, FALSE)) return false; // AccessCheck validates a security descriptor somewhat; set the group // and owner so that enough of the security descriptor is filled out // to make AccessCheck happy. SetSecurityDescriptorGroup(data.psdAdmin, data.psidAdmin, FALSE); SetSecurityDescriptorOwner(data.psdAdmin, data.psidAdmin, FALSE); if (!IsValidSecurityDescriptor(data.psdAdmin)) return false; DWORD dwAccessDesired = ACCESS_READ; GenericMapping.GenericRead = ACCESS_READ; GenericMapping.GenericWrite = ACCESS_WRITE; GenericMapping.GenericExecute = 0; GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE; DWORD dwStatus = 0; if (!AccessCheck(data.psdAdmin, data.hImpersonationToken, dwAccessDesired, &GenericMapping, &ps, &dwStructureSize, &dwStatus, &fReturn)) { return false; } return fReturn == TRUE; }
// Basically Microsoft 118626 // Needed for vista as it fakes the admin rights on the registry and screws everything up bool CGlobalSettings::isAdmin() { static int isAd = 0; bool fReturn = false; DWORD dwStatus; DWORD dwAccessMask; DWORD dwAccessDesired; DWORD dwACLSize; DWORD dwStructureSize = sizeof(PRIVILEGE_SET); PACL pACL = NULL; PSID psidAdmin = NULL; HANDLE hToken = NULL; HANDLE hImpersonationToken = NULL; PRIVILEGE_SET ps; GENERIC_MAPPING GenericMapping; PSECURITY_DESCRIPTOR psdAdmin = NULL; SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY; if(isAd) return isAd>0?true:false; __try { if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, TRUE, &hToken)) { if (GetLastError() != ERROR_NO_TOKEN) __leave; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &hToken)) __leave; } if (!DuplicateToken (hToken, SecurityImpersonation, &hImpersonationToken)) __leave; if (!AllocateAndInitializeSid(&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0, 0, 0, 0, 0, 0, &psidAdmin)) __leave; psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if (psdAdmin == NULL) __leave; if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION)) __leave; // Compute size needed for the ACL. dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD); pACL = (PACL)LocalAlloc(LPTR, dwACLSize); if (pACL == NULL) __leave; if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2)) __leave; dwAccessMask = ACCESS_READ | ACCESS_WRITE; if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin)) __leave; if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE)) __leave; SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE); SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE); if (!IsValidSecurityDescriptor(psdAdmin)) __leave; dwAccessDesired = ACCESS_READ; GenericMapping.GenericRead = ACCESS_READ; GenericMapping.GenericWrite = ACCESS_WRITE; GenericMapping.GenericExecute = 0; GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE; BOOL bRet; if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired, &GenericMapping, &ps, &dwStructureSize, &dwStatus, &bRet)) __leave; fReturn = bRet?true:false; } __finally { // Clean up. if (pACL) LocalFree(pACL); if (psdAdmin) LocalFree(psdAdmin); if (psidAdmin) FreeSid(psidAdmin); if (hImpersonationToken) CloseHandle (hImpersonationToken); if (hToken) CloseHandle (hToken); } isAd=fReturn?1:-1; return fReturn; }
int secure_file2(char *path, char *user, ACCESS_MASK mask, char *user2, ACCESS_MASK mask2) { SECURITY_DESCRIPTOR sd; SID *usid = NULL; SID *gsid; ACL *pdacl; struct stat sbuf; SECURITY_INFORMATION si = 0; char logb[LOG_BUF_SIZE] = {'\0' } ; char *gname = NULL; if (path == NULL) return (0); if (lstat(path, &sbuf) == -1) return (0); /* ignore non-existent files! */ if (!has_privilege(SE_RESTORE_NAME)) ena_privilege(SE_RESTORE_NAME); if (!has_privilege(SE_TAKE_OWNERSHIP_NAME)) ena_privilege(SE_TAKE_OWNERSHIP_NAME); InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); /* make PBS service account as the owner */ usid = create_administrators_sid(); if (usid == NULL) usid = getusersid(getlogin()); if (usid) { if (SetSecurityDescriptorOwner(&sd, usid, FALSE) == 0) { sprintf(logb, "error setting owner for file %s", path); log_err(-1, "secure_file2", logb); LocalFree(usid); return (0); } si |= OWNER_SECURITY_INFORMATION; /* trick with setting perms, set ownership first! */ if (SetFileSecurity(path, si, &sd) == 0) { sprintf(logb, "error setting actual owner for file %s", path); log_err(-1, "secure_file2", logb); LocalFree(usid); return (0); } InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); si = 0; } /* can't use gsid=getgid() since gsid here must be LocalFree()d */ if ((gname=getdefgrpname(getlogin()))) { gsid = getgrpsid(gname); (void)free(gname); } else { gsid = NULL; } if (gsid) { if (SetSecurityDescriptorGroup(&sd, gsid, FALSE) == 0) { sprintf(logb, "error setting group for file %s", path); log_err(-1, "secure_file2", logb); if (usid) LocalFree(usid); LocalFree(gsid); return (0); } si |= GROUP_SECURITY_INFORMATION; } pdacl = create_secure_dacl2(user, mask, user2, mask2, usid); if (pdacl == NULL) { sprintf(logb, "failed to create secure dacl for file %s", path); log_err(-1, "secure_file2", logb); if (usid) LocalFree(usid); if (gsid) LocalFree(gsid); return (0); } if (SetSecurityDescriptorDacl(&sd, TRUE, pdacl, TRUE) == 0) { sprintf(logb, "error setting dacl for file %s", path); log_err(-1, "secure_file2", logb); if (usid) LocalFree(usid); if (gsid) LocalFree(gsid); (void)free(pdacl); return (0); } si |= DACL_SECURITY_INFORMATION; if (SetFileSecurity(path, si, &sd) == 0) { sprintf(logb, "error setting security for file %s", path); log_err(-1, "secure_file2", logb); if (usid) LocalFree(usid); if (gsid) LocalFree(gsid); (void)free(pdacl); return (0); } if (usid) LocalFree(usid); if (gsid) LocalFree(gsid); (void)free(pdacl); /* Even though permissions have been set on the file, it can be */ /* overriden if a file attribute was given say a */ /* FILE_ATTRIBUTE_READONLY flag previously outside of PBS. Any */ /* writes to the file would still fail even if Administrators */ /* have been given write permission. */ /* The following call is to clear any special attributes that */ /* may have gotten set outside of PBS, negating PBS' permission */ /* change. */ (void)SetFileAttributes(path, FILE_ATTRIBUTE_NORMAL); return (1); }
// Initialize the User Conversation Interface. DWORD InitConvInterface ( VOID ) { HANDLE hThread, hThreadTcpip; DWORD dwThreadID, dwThreadIDTcpip; PSID pOwnerSid = NULL, pGroupSid = NULL; BOOL fSuccess = TRUE; PACL pAcl = NULL; DWORD cbAcl; DWORD dwRetCode; PSID pSystemSid = NULL, pAnonymousSid = NULL, pInteractiveSid = NULL; __try { #ifndef TREESVR_STANDALONE pOwnerSid = GetUserSid(); if( pOwnerSid == NULL ) __leave; /* fSuccess = GetAccountSid( NULL, "TreeServer Users", &pGroupSid ); if ( !fSuccess ) __leave; */ pGroupSid = CreateWorldSid(); if( pGroupSid == NULL ) __leave; pSystemSid = CreateSystemSid(); if( pSystemSid == NULL ) __leave; pAnonymousSid = CreateAnonymousSid(); if( pAnonymousSid == NULL ) __leave; pInteractiveSid = CreateInteractiveSid(); if( pInteractiveSid == NULL ) __leave; cbAcl = GetLengthSid( pOwnerSid ) + GetLengthSid( pGroupSid ) + GetLengthSid( pSystemSid ) + GetLengthSid( pAnonymousSid ) + GetLengthSid( pInteractiveSid ) + sizeof(ACL) + (5 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD))); pAcl = (PACL) HeapAlloc(GetProcessHeap(), 0, cbAcl); if (NULL == pAcl) __leave; fSuccess = InitializeAcl(pAcl, cbAcl, ACL_REVISION); if (FALSE == fSuccess) __leave; fSuccess = AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pOwnerSid); if (FALSE == fSuccess) __leave; fSuccess = AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL,//GENERIC_READ|GENERIC_WRITE, pGroupSid); if (FALSE == fSuccess) __leave; fSuccess = AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pSystemSid); if (FALSE == fSuccess) __leave; fSuccess = AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pInteractiveSid); if (FALSE == fSuccess) __leave; fSuccess = AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pAnonymousSid); if (FALSE == fSuccess) __leave; InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION ); fSuccess = SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE); if (FALSE == fSuccess) __leave; fSuccess = SetSecurityDescriptorOwner( &sd, pOwnerSid, FALSE ); if ( !fSuccess ) __leave; fSuccess = SetSecurityDescriptorGroup( &sd, pGroupSid, FALSE ); if ( !fSuccess ) __leave; sa.nLength = sizeof( SECURITY_ATTRIBUTES ); sa.lpSecurityDescriptor = (LPVOID)&sd; sa.bInheritHandle = FALSE; #endif // Create the NamedPipe server thread, Process the user's connection. hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)PipeSelectConnectThread, (LPVOID)NULL, 0, &dwThreadID ); // If operation not completed, return the system error code. if( hThread == NULL ) { fSuccess = FALSE; __leave; } #ifndef TREESVR_STANDALONE hThreadTcpip = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)TcpipSelectConnectThread, (LPVOID)NULL, 0, &dwThreadIDTcpip ); // If operation not completed, return the system error code. if( hThreadTcpip == NULL ) { fSuccess = FALSE; __leave; } #endif } __finally { if( fSuccess ) { // Set the thread Prority Class. SetThreadPriority( hThread, THREAD_PRIORITY_ABOVE_NORMAL ); SystemResInfo.hConvThread = hThread; SystemResInfo.dwConvThreadId = dwThreadID; #ifndef TREESVR_STANDALONE // Set the thread Prority Class. SetThreadPriority( hThreadTcpip, THREAD_PRIORITY_ABOVE_NORMAL ); SystemResInfo.hConvThreadTcpip = hThreadTcpip; SystemResInfo.dwConvThreadIdTcpip = dwThreadIDTcpip; #endif dwRetCode = TERR_SUCCESS; } else { if( hThread != NULL ) { CloseHandle( hThread ); } dwRetCode = GetLastError(); if( pOwnerSid ) HeapFree( GetProcessHeap(), 0, pOwnerSid ); if( pGroupSid ) HeapFree( GetProcessHeap(), 0, pGroupSid ); if( pSystemSid ) HeapFree( GetProcessHeap(), 0, pSystemSid ); if( pInteractiveSid ) HeapFree( GetProcessHeap(), 0, pInteractiveSid ); if( pAnonymousSid ) HeapFree( GetProcessHeap(), 0, pAnonymousSid ); if( pAcl ) HeapFree( GetProcessHeap(), 0, pAcl ); } } return dwRetCode; }
void CheckNddeShare() { DWORD dwAvail; WORD wItems=0; BYTE buffer[200]; //LPBYTE buffer; CHAR szres[255]; DWORD err=0; char szerror[16]; char *sztopiclist = {"bugboard|bugboard\0bugboard|bugboard\0bugboard|bugboard\0\0"}; //FARPROC fpNDdeShareGetInfo; PSID pworldsid; PACL pacl; SID_IDENTIFIER_AUTHORITY IdentifierAuthority = SECURITY_WORLD_SID_AUTHORITY; SECURITY_DESCRIPTOR sd; //HINSTANCE hinstNDDEAPI=NULL; SetErrorMode(SEM_FAILCRITICALERRORS); //_NOOPENFILEERRORBOX); HINSTANCE hinstNDDEAPI = LoadLibrary("NDDEAPI.DLL"); if (NULL == hinstNDDEAPI) // <= HINSTANCE_ERROR) { MessageBox(NULL, "NDDEAPI.DLL not found in path", "bugboard.exe", MB_OK | MB_ICONSTOP); return; } SGIPROC fpNDdeShareGetInfo = (SGIPROC) GetProcAddress(hinstNDDEAPI, "NDdeShareGetInfoA"); if (fpNDdeShareGetInfo == NULL) { FreeLibrary(hinstNDDEAPI); return; } UINT ret = (*fpNDdeShareGetInfo)(NULL, "bugboard$", 2, buffer, sizeof(buffer), &dwAvail, &wItems); if (ret != NDDE_SHARE_NOT_EXIST) { return; } NDDESHAREINFO *pnddeInfo = (NDDESHAREINFO *)buffer; SAPROC lpfnNDdeShareAdd = (SAPROC) GetProcAddress(hinstNDDEAPI, "NDdeShareAddA"); if (lpfnNDdeShareAdd == NULL) { FreeLibrary(hinstNDDEAPI); return; } /* this is all different for win32 (NT) lstrcpy(pnddeInfo->szShareName, "bugboard$"); pnddeInfo->lpszTargetApp = "bugboard"; pnddeInfo->lpszTargetTopic = "bugboard"; pnddeInfo->lpbPassword1 = (LPBYTE) ""; pnddeInfo->cbPassword1 = 0; pnddeInfo->dwPermissions1 = 15; pnddeInfo->lpbPassword2 = (LPBYTE) ""; pnddeInfo->cbPassword2 = 0; pnddeInfo->dwPermissions2 = 0; pnddeInfo->lpszItem = ""; pnddeInfo->cAddItems = 0; pnddeInfo->lpNDdeShareItemInfo = NULL; */ // current structure pnddeInfo->lRevision = 1L; pnddeInfo->lpszShareName = _strdup("bugboard$"); pnddeInfo->lShareType = SHARE_TYPE_NEW | SHARE_TYPE_OLD | SHARE_TYPE_STATIC; pnddeInfo->lpszAppTopicList = (LPTSTR)sztopiclist; pnddeInfo->fSharedFlag = 1; pnddeInfo->fService = 0; pnddeInfo->fStartAppFlag = 0; pnddeInfo->nCmdShow = SW_SHOWMAXIMIZED; pnddeInfo->qModifyId[0] = 0; pnddeInfo->qModifyId[1] = 0; pnddeInfo->cNumItems = 0; pnddeInfo->lpszItemList = "\0"; if (!AllocateAndInitializeSid( &IdentifierAuthority, 1, SECURITY_WORLD_RID, 0,0,0,0,0,0,0, &pworldsid)) { FreeLibrary(hinstNDDEAPI); return; } pacl = (ACL*)malloc(sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pworldsid) - sizeof(DWORD) ) ; InitializeAcl(pacl, sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pworldsid) - sizeof(DWORD), ACL_REVISION); if (!IsValidAcl) { MessageBox(NULL, "ACL not valid", "bugboard.exe", MB_OK | MB_ICONSTOP); FreeLibrary(hinstNDDEAPI); return; } if (!AddAccessAllowedAce(pacl, ACL_REVISION, STANDARD_RIGHTS_ALL | MAXIMUM_ALLOWED | GENERIC_ALL | ACCESS_SYSTEM_SECURITY, pworldsid)) { MessageBox(NULL, "Add ACE failed", "bugboard.exe", MB_OK | MB_ICONSTOP); FreeLibrary(hinstNDDEAPI); return; } if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) { MessageBox(NULL, "Init sd failed", "bugboard.exe", MB_OK | MB_ICONSTOP); FreeLibrary(hinstNDDEAPI); return; } if (!SetSecurityDescriptorOwner(&sd, NULL, FALSE)) { FreeLibrary(hinstNDDEAPI); return; } if (!SetSecurityDescriptorGroup(&sd, NULL, FALSE)) { FreeLibrary(hinstNDDEAPI); return; } if (!SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE)) { FreeLibrary(hinstNDDEAPI); return; } if (!IsValidSecurityDescriptor(&sd)) { MessageBox(NULL, "Invalid sd", "bugboard.exe", MB_OK | MB_ICONSTOP); FreeLibrary(hinstNDDEAPI); return; } ret = (*lpfnNDdeShareAdd)(NULL, 2, &sd, buffer, sizeof(buffer)); if (ret != NDDE_NO_ERROR && ret != NDDE_SHARE_ALREADY_EXIST) { SGSPROC lpfnNDdeGetErrorString = (SGSPROC) GetProcAddress(hinstNDDEAPI, "NDdeGetErrorStringA"); if (lpfnNDdeGetErrorString == NULL) { FreeLibrary(hinstNDDEAPI); return; } (*lpfnNDdeGetErrorString)(ret, (LPSTR)szres, 255); MessageBox(NULL, (LPSTR)szres, "ERROR bugboard.exe", MB_OK | MB_ICONSTOP); FreeLibrary(hinstNDDEAPI); return; } SSTPROC lpfnNDdeSetTrustedShare = (SSTPROC) GetProcAddress(hinstNDDEAPI, "NDdeSetTrustedShareA"); if (NDDE_NO_ERROR != ((*lpfnNDdeSetTrustedShare)(NULL, pnddeInfo->lpszShareName, NDDE_TRUST_SHARE_INIT))) { MessageBox(NULL, "Unable to set trusted share", "ERROR bugboard.exe", MB_OK | MB_ICONSTOP); } FreeLibrary(hinstNDDEAPI); }
BOOL OsIsAdmin(void) { BOOL fReturn = FALSE; DWORD dwStatus; DWORD dwAccessMask; DWORD dwAccessDesired; DWORD dwACLSize; DWORD dwStructureSize = sizeof(PRIVILEGE_SET); PACL pACL = NULL; PSID psidAdmin = NULL; HANDLE hToken = NULL; HANDLE hImpersonationToken = NULL; PRIVILEGE_SET ps; GENERIC_MAPPING GenericMapping; PSECURITY_DESCRIPTOR psdAdmin = NULL; SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY; const DWORD ACCESS_READ = 1; const DWORD ACCESS_WRITE = 2; __try { /* AccessCheck() requires an impersonation token. We first get a primary token and then create a duplicate impersonation token. The impersonation token is not actually assigned to the thread, but is used in the call to AccessCheck. Thus, this function itself never impersonates, but does use the identity of the thread. If the thread was impersonating already, this function uses that impersonation context. */ if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, TRUE, &hToken)) { if (GetLastError() != ERROR_NO_TOKEN) __leave; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &hToken)) __leave; } if (!DuplicateToken (hToken, SecurityImpersonation, &hImpersonationToken)) __leave; /* Create the binary representation of the well-known SID that represents the local administrators group. Then create the security descriptor and DACL with an ACE that allows only local admins access. After that, perform the access check. This will determine whether the current user is a local admin. */ if (!AllocateAndInitializeSid(&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin)) __leave; psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if (psdAdmin == NULL) __leave; if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION)) __leave; // Compute size needed for the ACL. dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD); pACL = (PACL)LocalAlloc(LPTR, dwACLSize); if (pACL == NULL) __leave; if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2)) __leave; dwAccessMask= ACCESS_READ | ACCESS_WRITE; if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin)) __leave; if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE)) __leave; /* AccessCheck validates a security descriptor somewhat; set the group and owner so that enough of the security descriptor is filled out to make AccessCheck happy. */ SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE); SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE); if (!IsValidSecurityDescriptor(psdAdmin)) __leave; dwAccessDesired = ACCESS_READ; /* Initialize GenericMapping structure even though you do not use generic rights. */ GenericMapping.GenericRead = ACCESS_READ; GenericMapping.GenericWrite = ACCESS_WRITE; GenericMapping.GenericExecute = 0; GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE; if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired, &GenericMapping, &ps, &dwStructureSize, &dwStatus, &fReturn)) { fReturn = FALSE; __leave; } } __finally { // Clean up. if (pACL) LocalFree(pACL); if (hImpersonationToken) CloseHandle (hImpersonationToken); if (hToken) CloseHandle (hToken); if (psdAdmin) LocalFree(psdAdmin); if (psidAdmin) FreeSid(psidAdmin); } return fReturn; }
/* Create a temporary file */ int mkstemp_ex(char *tmp_path) { DWORD dwResult; int result; int status = -1; HANDLE h = NULL; PACL pACL = NULL; PSECURITY_DESCRIPTOR pSD = NULL; EXPLICIT_ACCESS ea[2]; SECURITY_ATTRIBUTES sa; PSID pAdminGroupSID = NULL; PSID pSystemGroupSID = NULL; SID_IDENTIFIER_AUTHORITY SIDAuthNT = {SECURITY_NT_AUTHORITY}; #if defined(_MSC_VER) && _MSC_VER >= 1500 result = _mktemp_s(tmp_path, strlen(tmp_path) + 1); if (result != 0) { log2file( "%s: ERROR: Could not create temporary file (%s) which returned (%d)", __local_name, tmp_path, result ); return (-1); } #else if (_mktemp(tmp_path) == NULL) { log2file( "%s: ERROR: Could not create temporary file (%s) which returned [(%d)-(%s)]", __local_name, tmp_path, errno, strerror(errno) ); return (-1); } #endif /* Create SID for the BUILTIN\Administrators group */ result = AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminGroupSID ); if (!result) { log2file( "%s: ERROR: Could not create BUILTIN\\Administrators group SID which returned (%lu)", __local_name, GetLastError() ); goto cleanup; } /* Create SID for the SYSTEM group */ result = AllocateAndInitializeSid( &SIDAuthNT, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &pSystemGroupSID ); if (!result) { log2file( "%s: ERROR: Could not create SYSTEM group SID which returned (%lu)", __local_name, GetLastError() ); goto cleanup; } /* Initialize an EXPLICIT_ACCESS structure for an ACE */ ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS)); /* Add Administrators group */ ea[0].grfAccessPermissions = GENERIC_ALL; ea[0].grfAccessMode = SET_ACCESS; ea[0].grfInheritance = NO_INHERITANCE; ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea[0].Trustee.ptstrName = (LPTSTR)pAdminGroupSID; /* Add SYSTEM group */ ea[1].grfAccessPermissions = GENERIC_ALL; ea[1].grfAccessMode = SET_ACCESS; ea[1].grfInheritance = NO_INHERITANCE; ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea[1].Trustee.ptstrName = (LPTSTR)pSystemGroupSID; /* Set entries in ACL */ dwResult = SetEntriesInAcl(2, ea, NULL, &pACL); if (dwResult != ERROR_SUCCESS) { log2file( "%s: ERROR: Could not set ACL entries which returned (%lu)", __local_name, dwResult ); goto cleanup; } /* Initialize security descriptor */ pSD = (PSECURITY_DESCRIPTOR)LocalAlloc( LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH ); if (pSD == NULL) { log2file( "%s: ERROR: Could not initalize SECURITY_DESCRIPTOR because of a LocalAlloc() failure which returned (%lu)", __local_name, GetLastError() ); goto cleanup; } if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { log2file( "%s: ERROR: Could not initalize SECURITY_DESCRIPTOR because of an InitializeSecurityDescriptor() failure which returned (%lu)", __local_name, GetLastError() ); goto cleanup; } /* Set owner */ if (!SetSecurityDescriptorOwner(pSD, NULL, FALSE)) { log2file( "%s: ERROR: Could not set owner which returned (%lu)", __local_name, GetLastError() ); goto cleanup; } /* Set group owner */ if (!SetSecurityDescriptorGroup(pSD, NULL, FALSE)) { log2file( "%s: ERROR: Could not set group owner which returned (%lu)", __local_name, GetLastError() ); goto cleanup; } /* Add ACL to security descriptor */ if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) { log2file( "%s: ERROR: Could not set SECURITY_DESCRIPTOR DACL which returned (%lu)", __local_name, GetLastError() ); goto cleanup; } /* Initialize security attributes structure */ sa.nLength = sizeof (SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = pSD; sa.bInheritHandle = FALSE; h = CreateFileA( tmp_path, GENERIC_WRITE, 0, &sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL ); if (h == INVALID_HANDLE_VALUE) { log2file( "%s: ERROR: Could not create temporary file (%s) which returned (%lu)", __local_name, tmp_path, GetLastError() ); goto cleanup; } if (!CloseHandle(h)) { log2file( "%s: ERROR: Could not close file handle to (%s) which returned (%lu)", __local_name, tmp_path, GetLastError() ); goto cleanup; } /* Success */ status = 0; cleanup: if (pAdminGroupSID) { FreeSid(pAdminGroupSID); } if (pSystemGroupSID) { FreeSid(pSystemGroupSID); } if (pACL) { LocalFree(pACL); } if (pSD) { LocalFree(pSD); } return (status); }
//********************************************************************** // // FUNCTION: IsAdmin - This function checks the token of the // calling thread to see if the caller belongs to // the Administrators group. // // PARAMETERS: none // // RETURN VALUE: TRUE if the caller is an administrator on the local // machine. Otherwise, FALSE. // //********************************************************************** BOOL IsAdmin(void) { HANDLE hToken; DWORD dwStatus; DWORD dwAccessMask; DWORD dwAccessDesired; DWORD dwACLSize; DWORD dwStructureSize = sizeof(PRIVILEGE_SET); PACL pACL = NULL; PSID psidAdmin = NULL; BOOL bReturn = FALSE; PRIVILEGE_SET ps; GENERIC_MAPPING GenericMapping; PSECURITY_DESCRIPTOR psdAdmin = NULL; SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY; __try { // AccessCheck() requires an impersonation token. ImpersonateSelf(SecurityImpersonation); if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken)) { if (GetLastError() != ERROR_NO_TOKEN) __leave; // If the thread does not have an access token, we'll // examine the access token associated with the process. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) __leave; } if (!AllocateAndInitializeSid(&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin)) __leave; psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if (psdAdmin == NULL) __leave; if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION)) __leave; // Compute size needed for the ACL. dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD); // Allocate memory for ACL. pACL = (PACL)LocalAlloc(LPTR, dwACLSize); if (pACL == NULL) __leave; // Initialize the new ACL. if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2)) __leave; dwAccessMask = ACCESS_READ | ACCESS_WRITE; // Add the access-allowed ACE to the DACL. if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin)) __leave; // Set the DACL to the SD. if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE)) __leave; // AccessCheck is sensitive about what is in the SD; set // the group and owner. SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE); SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE); if (!IsValidSecurityDescriptor(psdAdmin)) __leave; dwAccessDesired = ACCESS_READ; // // Initialize GenericMapping structure even though you // do not use generic rights. // GenericMapping.GenericRead = ACCESS_READ; GenericMapping.GenericWrite = ACCESS_WRITE; GenericMapping.GenericExecute = 0; GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE; if (!AccessCheck(psdAdmin, hToken, dwAccessDesired, &GenericMapping, &ps, &dwStructureSize, &dwStatus, &bReturn)) { printf("AccessCheck() failed with error %lu\n", GetLastError()); __leave; } RevertToSelf(); } __finally { // Clean up. if (pACL) LocalFree(pACL); if (psdAdmin) LocalFree(psdAdmin); if (psidAdmin) FreeSid(psidAdmin); } return bReturn; }
DWORD CreateNewSD ( SECURITY_DESCRIPTOR **SD ) { PACL dacl; DWORD sidLength; PSID sid; PSID groupSID; PSID ownerSID; DWORD returnValue; *SD = NULL; returnValue = GetCurrentUserSID (&sid); if (returnValue != ERROR_SUCCESS) return returnValue; sidLength = GetLengthSid (sid); *SD = (SECURITY_DESCRIPTOR *) malloc ( (sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength) + (2 * sidLength) + sizeof (SECURITY_DESCRIPTOR)); groupSID = (SID *) (*SD + 1); ownerSID = (SID *) (((BYTE *) groupSID) + sidLength); dacl = (ACL *) (((BYTE *) ownerSID) + sidLength); if (!InitializeSecurityDescriptor (*SD, SECURITY_DESCRIPTOR_REVISION)) { free (*SD); free (sid); return GetLastError(); } if (!InitializeAcl (dacl, sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength, ACL_REVISION2)) { free (*SD); free (sid); return GetLastError(); } if (!AddAccessAllowedAce (dacl, ACL_REVISION2, COM_RIGHTS_EXECUTE, sid)) { free (*SD); free (sid); return GetLastError(); } if (!SetSecurityDescriptorDacl (*SD, TRUE, dacl, FALSE)) { free (*SD); free (sid); return GetLastError(); } memcpy (groupSID, sid, sidLength); if (!SetSecurityDescriptorGroup (*SD, groupSID, FALSE)) { free (*SD); free (sid); return GetLastError(); } memcpy (ownerSID, sid, sidLength); if (!SetSecurityDescriptorOwner (*SD, ownerSID, FALSE)) { free (*SD); free (sid); return GetLastError(); } return ERROR_SUCCESS; }
gboolean isadmin_win32() { BOOL bRet; PACL pACL; DWORD dwLen, dwStatus; PSID psidAdmin; HANDLE hTok, hItok; PRIVILEGE_SET ps; PSECURITY_DESCRIPTOR psdAdmin; GENERIC_MAPPING gmap = {ACCESS_READ, ACCESS_WRITE, 0, ACCESS_READ | ACCESS_WRITE}; SID_IDENTIFIER_AUTHORITY SSidAuth = {SECURITY_NT_AUTHORITY}; if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &hTok)) { if (GetLastError() != ERROR_NO_TOKEN) return FALSE; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &hTok)) return FALSE; } if (!DuplicateToken(hTok, SecurityImpersonation, &hItok)) return FALSE; if (!AllocateAndInitializeSid(&SSidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin)) return FALSE; if (!(psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH))) return FALSE; if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION)) return FALSE; dwLen = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD); if (!(pACL = (PACL)LocalAlloc(LPTR, dwLen))) return FALSE; if (!InitializeAcl(pACL, dwLen, ACL_REVISION2)) return FALSE; if (!AddAccessAllowedAce(pACL, ACL_REVISION2, ACCESS_READ | ACCESS_WRITE, psidAdmin)) return FALSE; if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE)) return FALSE; SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE); SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE); if (!IsValidSecurityDescriptor(psdAdmin)) return FALSE; dwLen = sizeof(PRIVILEGE_SET); if (!AccessCheck(psdAdmin, hItok, ACCESS_READ, &gmap, &ps, &dwLen, &dwStatus, &bRet)) { bRet = FALSE; g_print("ERROR: %lu\n", GetLastError()); } if (pACL) LocalFree(pACL); if (psdAdmin) LocalFree(psdAdmin); if (psidAdmin) FreeSid(psidAdmin); if (hItok) CloseHandle(hItok); if (hTok) CloseHandle(hTok); return (gboolean)bRet; }
/* * Construct a security descriptor whose discretionary access-control * list implements the specified mode bits. The SIDs for owner, group, * and everyone are obtained from the global _pr_nt_sids structure. * Both the security descriptor and access-control list are returned * and should be freed by a _PR_NT_FreeSecurityDescriptorACL call. * * The accessTable array maps NSPR's read, write, and execute access * rights to the corresponding NT access rights for the securable * object. */ PRStatus _PR_NT_MakeSecurityDescriptorACL( PRIntn mode, DWORD accessTable[], PSECURITY_DESCRIPTOR *resultSD, PACL *resultACL) { PSECURITY_DESCRIPTOR pSD = NULL; PACL pACL = NULL; DWORD cbACL; /* size of ACL */ DWORD accessMask; if (_pr_nt_sids.owner == NULL) { PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); return PR_FAILURE; } pSD = (PSECURITY_DESCRIPTOR) PR_Malloc(SECURITY_DESCRIPTOR_MIN_LENGTH); if (pSD == NULL) { _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); goto failed; } if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); goto failed; } if (!SetSecurityDescriptorOwner(pSD, _pr_nt_sids.owner, FALSE)) { _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); goto failed; } if (!SetSecurityDescriptorGroup(pSD, _pr_nt_sids.group, FALSE)) { _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); goto failed; } /* * Construct a discretionary access-control list with three * access-control entries, one each for owner, primary group, * and Everyone. */ cbACL = sizeof(ACL) + 3 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + GetLengthSid(_pr_nt_sids.owner) + GetLengthSid(_pr_nt_sids.group) + GetLengthSid(_pr_nt_sids.everyone); pACL = (PACL) PR_Malloc(cbACL); if (pACL == NULL) { _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); goto failed; } if (!InitializeAcl(pACL, cbACL, ACL_REVISION)) { _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); goto failed; } accessMask = 0; if (mode & 00400) accessMask |= accessTable[0]; if (mode & 00200) accessMask |= accessTable[1]; if (mode & 00100) accessMask |= accessTable[2]; if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask, _pr_nt_sids.owner)) { _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); goto failed; } accessMask = 0; if (mode & 00040) accessMask |= accessTable[0]; if (mode & 00020) accessMask |= accessTable[1]; if (mode & 00010) accessMask |= accessTable[2]; if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask, _pr_nt_sids.group)) { _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); goto failed; } accessMask = 0; if (mode & 00004) accessMask |= accessTable[0]; if (mode & 00002) accessMask |= accessTable[1]; if (mode & 00001) accessMask |= accessTable[2]; if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask, _pr_nt_sids.everyone)) { _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); goto failed; } if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) { _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); goto failed; } *resultSD = pSD; *resultACL = pACL; return PR_SUCCESS; failed: if (pSD) { PR_Free(pSD); } if (pACL) { PR_Free(pACL); } return PR_FAILURE; }