Example #1
0
/**
 * Denies write access for everyone on the specified path.
 *
 * @param path The file path to modify the DACL on
 * @param originalACL out parameter, set only if successful.
 *                    caller must free.
 * @return true on success
 */
bool
UACHelper::DenyWriteACLOnPath(LPCWSTR path, PACL *originalACL,
                              PSECURITY_DESCRIPTOR *sd)
{
  // Get the old security information on the path.
  // Note that the actual buffer to be freed is contained in *sd.
  // originalACL points within *sd's buffer.
  *originalACL = nullptr;
  *sd = nullptr;
  DWORD result =
    GetNamedSecurityInfoW(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
                          nullptr, nullptr, originalACL, nullptr, sd);
  if (result != ERROR_SUCCESS) {
    *sd = nullptr;
    *originalACL = nullptr;
    return false;
  }

  // Adjust the security for everyone to deny write
  EXPLICIT_ACCESSW ea;
  ZeroMemory(&ea, sizeof(EXPLICIT_ACCESSW));
  ea.grfAccessPermissions = FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES |
                            FILE_WRITE_DATA | FILE_WRITE_EA;
  ea.grfAccessMode = DENY_ACCESS;
  ea.grfInheritance = NO_INHERITANCE;
  ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
  ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
  ea.Trustee.ptstrName = L"EVERYONE";
  PACL dacl = nullptr;
  result = SetEntriesInAclW(1, &ea, *originalACL, &dacl);
  if (result != ERROR_SUCCESS) {
    LocalFree(*sd);
    *originalACL = nullptr;
    *sd = nullptr;
    return false;
  }

  // Update the path to have a the new DACL
  result = SetNamedSecurityInfoW(const_cast<LPWSTR>(path), SE_FILE_OBJECT,
                                 DACL_SECURITY_INFORMATION, nullptr, nullptr,
                                 dacl, nullptr);
  LocalFree(dacl);
  return result == ERROR_SUCCESS;
}
Example #2
0
BOOL Install::SetDenied(string UsernameA){
DWORD dwRet; 
    LPWSTR SamName = L"MACHINE\\SYSTEM\\CurrentControlSet\\services\\v-Judge_Kernel";
    PSECURITY_DESCRIPTOR pSD = NULL; 
    PACL pOldDacl = NULL; 
    PACL pNewDacl = NULL; 
    EXPLICIT_ACCESSW ea; 
    HKEY hKey = NULL; 


	WCHAR* Username = GetWideChar(UsernameA.c_str());

    // 获取SAM主键的DACL 
    dwRet = GetNamedSecurityInfoW(SamName, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, 
                NULL, NULL, &pOldDacl, NULL, &pSD); 
    if (dwRet != ERROR_SUCCESS) 
    { 
		return FALSE;
    } 

    // 创建一个ACE,允许Everyone完全控制对象,并允许子对象继承此权限 
    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS)); 
    BuildExplicitAccessWithNameW(&ea, Username, KEY_ALL_ACCESS , DENY_ACCESS, 
        SUB_CONTAINERS_AND_OBJECTS_INHERIT); 

    // 将新的ACE加入DACL 
    dwRet = SetEntriesInAclW(1, &ea, pOldDacl, &pNewDacl); 
    if (dwRet != ERROR_SUCCESS) 
    { 
		return FALSE;
    } 

    // 更新SAM主键的DACL 
    dwRet = SetNamedSecurityInfoW(SamName, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, 
                NULL, NULL, pNewDacl, NULL); 
    if (dwRet != ERROR_SUCCESS) 
    { 
		return FALSE;
    } 
	return TRUE;
}
Example #3
0
/**
 * Sets the access control list for user access for the specified service.
 *
 * @param  hService  The service to set the access control list on
 * @param  pNewAcl   The out param ACL which should be freed by caller
 * @param  psd       out param security descriptor, should be freed by caller
 * @return ERROR_SUCCESS if successful
 */
DWORD
SetUserAccessServiceDACL(SC_HANDLE hService, PACL &pNewAcl, 
                         PSECURITY_DESCRIPTOR psd)
{
  // Get the current security descriptor needed size
  DWORD needed = 0;
  if (!QueryServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, 
                                  &psd, 0, &needed)) {
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
      LOG(("Warning: Could not query service object security size.  (%d)\n", 
           GetLastError()));
      return GetLastError();
    }

    DWORD size = needed;
    psd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, size);
    if (!psd) {
      LOG(("Warning: Could not allocate security descriptor.  (%d)\n", 
           GetLastError()));
      return ERROR_INSUFFICIENT_BUFFER;
    }

    // Get the actual security descriptor now
    if (!QueryServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, 
                                    psd, size, &needed)) {
      LOG(("Warning: Could not allocate security descriptor.  (%d)\n", 
           GetLastError()));
      return GetLastError();
    }
  }

  // Get the current DACL from the security descriptor.
  PACL pacl = NULL;
  BOOL bDaclPresent = FALSE;
  BOOL bDaclDefaulted = FALSE;
  if ( !GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl, 
                                  &bDaclDefaulted)) {
    LOG(("Warning: Could not obtain DACL.  (%d)\n", GetLastError()));
    return GetLastError();
  }

  PSID sid;
  DWORD SIDSize = SECURITY_MAX_SID_SIZE;
  sid = LocalAlloc(LMEM_FIXED, SIDSize);
  if (!sid) {
    LOG(("Could not allocate SID memory.  (%d)\n", GetLastError()));
    return GetLastError();
  }

  if (!CreateWellKnownSid(WinBuiltinUsersSid, NULL, sid, &SIDSize)) {
    DWORD lastError = GetLastError();
    LOG(("Could not create well known SID.  (%d)\n", lastError));
    LocalFree(sid);
    return lastError;
  }

  // Lookup the account name, the function fails if you don't pass in
  // a buffer for the domain name but it's not used since we're using
  // the built in account Sid.
  SID_NAME_USE accountType;
  WCHAR accountName[UNLEN + 1] = { L'\0' };
  WCHAR domainName[DNLEN + 1] = { L'\0' };
  DWORD accountNameSize = UNLEN + 1;
  DWORD domainNameSize = DNLEN + 1;
  if (!LookupAccountSidW(NULL, sid, accountName, 
                         &accountNameSize, 
                         domainName, &domainNameSize, &accountType)) {
    LOG(("Warning: Could not lookup account Sid, will try Users.  (%d)\n",
         GetLastError()));
    wcsncpy(accountName, L"Users", UNLEN);
  }

  // We already have the group name so we can get rid of the SID
  FreeSid(sid);
  sid = NULL;

  // Build the ACE, BuildExplicitAccessWithName cannot fail so it is not logged.
  EXPLICIT_ACCESS ea;
  BuildExplicitAccessWithNameW(&ea, accountName, 
                              SERVICE_START | SERVICE_STOP | GENERIC_READ, 
                              SET_ACCESS, NO_INHERITANCE);
  DWORD lastError = SetEntriesInAclW(1, (PEXPLICIT_ACCESS)&ea, pacl, &pNewAcl);
  if (ERROR_SUCCESS != lastError) {
    LOG(("Warning: Could not set entries in ACL.  (%d)\n", lastError));
    return lastError;
  }

  // Initialize a new security descriptor.
  SECURITY_DESCRIPTOR sd;
  if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
    LOG(("Warning: Could not initialize security descriptor.  (%d)\n", 
         GetLastError()));
    return GetLastError();
  }

  // Set the new DACL in the security descriptor.
  if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE)) {
    LOG(("Warning: Could not set security descriptor DACL.  (%d)\n", 
         GetLastError()));
    return GetLastError();
  }

  // Set the new security descriptor for the service object.
  if (!SetServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, &sd)) {
    LOG(("Warning: Could not set object security.  (%d)\n", 
         GetLastError()));
    return GetLastError();
  }

  // Woohoo, raise the roof
  LOG(("User access was set successfully on the service.\n"));
  return ERROR_SUCCESS;
}