예제 #1
0
파일: mono-security.c 프로젝트: LevNNN/mono
static gboolean
ProtectUser (gunichar2 *path)
{
    DWORD retval = -1;

    PSID pCurrentSid = GetCurrentUserSid ();
    if (pCurrentSid) {
        PACL pDACL = NULL;
        EXPLICIT_ACCESS ea;
        ZeroMemory (&ea, sizeof (EXPLICIT_ACCESS));

        /* grant exclusive access to the current user */
        BuildTrusteeWithSidW (&ea.Trustee, pCurrentSid);
        ea.grfAccessPermissions = GENERIC_ALL;
        ea.grfAccessMode = SET_ACCESS;
        ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
        ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
        ea.Trustee.TrusteeType = TRUSTEE_IS_USER;

        retval = SetEntriesInAcl (1, &ea, NULL, &pDACL);
        if (retval == ERROR_SUCCESS) {
            /* with PROTECTED_DACL_SECURITY_INFORMATION we
               remove any existing ACL (like inherited ones) */
            retval = SetNamedSecurityInfo (path, SE_FILE_OBJECT,
                                           DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
                                           NULL, NULL, pDACL, NULL);
        }

        if (pDACL)
            LocalFree (pDACL);
        g_free (pCurrentSid); /* g_malloc0 */
    }

    return (retval == ERROR_SUCCESS);
}
예제 #2
0
// 设置注册表的存取权限
BOOL RegKeySetACL(LPTSTR lpKeyName, DWORD AccessPermissions, ACCESS_MODE AccessMode)
{
    PSECURITY_DESCRIPTOR	SD;
    EXPLICIT_ACCESS			ea;
    PACL			OldDACL, NewDACL;
    SE_OBJECT_TYPE	ObjectType = SE_REGISTRY_KEY; //#include <aclapi.h>

    //默认返回值为FALSE
    BOOL bRet = FALSE;
    //建立一个空的ACL;
    if (SetEntriesInAcl(0, NULL, NULL, &OldDACL) != ERROR_SUCCESS)
        return bRet;

    if (SetEntriesInAcl(0, NULL, NULL, &NewDACL) != ERROR_SUCCESS)
        return bRet;

    //获取现有的ACL列表到OldDACL:
    if(GetNamedSecurityInfo(lpKeyName, ObjectType,
                            DACL_SECURITY_INFORMATION,
                            NULL, NULL,
                            &OldDACL,
                            NULL, &SD) != ERROR_SUCCESS)
    {
        return bRet;
    }

    //设置用户名"Everyone"对指定的键有所有操作权到结构ea:
    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));

    char	*lpUsers[] = {"SYSTEM", "Administrators", "Everyone", "Users"};
    for (int i = 0; i < sizeof(lpUsers) / sizeof(char *); i++)
    {
        BuildExplicitAccessWithName(&ea,
                                    lpUsers[i],      // name of trustee
                                    AccessPermissions,    // type of access
                                    AccessMode,      // access mode
                                    SUB_CONTAINERS_AND_OBJECTS_INHERIT); //子键继承它的权限

    }
    //合并结构ea和OldDACL的权限列表到新的NewDACL:
    if (SetEntriesInAcl(1, &ea, NULL, &NewDACL) == ERROR_SUCCESS)
    {
        //把新的ACL写入到指定的键:
        SetNamedSecurityInfo(lpKeyName, ObjectType,
                             DACL_SECURITY_INFORMATION,
                             NULL, NULL,
                             NewDACL,
                             NULL);
        bRet = TRUE;
    }
    //释放指针

    if(SD != NULL)
        LocalFree((HLOCAL) SD);
    if(NewDACL != NULL)
        LocalFree((HLOCAL) NewDACL);
    if(OldDACL != NULL)
        LocalFree((HLOCAL) OldDACL);
    return bRet;
}
예제 #3
0
// 'Corrects' the security on a file by taking ownership of it and giving the current user full control
// For directories these will do a complete recursive correction.
static void CorrectSecurity(TCHAR *f, DWORD attrib, BOOL takeownership, PSID sid, PACL acl, BOOL oneVolumeOnly) {
	BY_HANDLE_FILE_INFORMATION info;
	if (attrib != INVALID_FILE_ATTRIBUTES) {
		DWORD err;
		if (sid && takeownership) {
			err = SetNamedSecurityInfo(f, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, sid, NULL, NULL, NULL);
			if (err != ERROR_SUCCESS) { LogFileError(TEXT("SetNamedSecurityInfo (change owner)"), f, err); }
		}
		if (sid && acl) {
			err = SetNamedSecurityInfo(f, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, acl, NULL);
			if (err != ERROR_SUCCESS) { LogFileError(TEXT("SetNamedSecurityInfo (change DACL)"), f, err); }
		}
		if ((attrib & FILE_ATTRIBUTE_DIRECTORY) && !(oneVolumeOnly && FileChangesVolume(f))) {
			// Recursively go through the directories
			WIN32_FIND_DATA ffd;
			TCHAR full[BIG_PATH+5], *file = copyStr(f);
			HANDLE hFind;
			DWORD dwError;
			DWORD len = _tcslen(file);
			while (len > 0 && file[len-1] == L'\\')
				file[--len] = 0;
			file[len  ] = TEXT('\\');
			file[len+1] = TEXT('*');
			file[len+2] = 0;
			hFind = FindFirstFileEx(file, FindExInfoBasic, &ffd, FindExSearchNameMatch, NULL, FIND_FIRST_EX_LARGE_FETCH);
			if (hFind == INVALID_HANDLE_VALUE) {
				dwError = GetLastError();
				if (dwError != ERROR_FILE_NOT_FOUND && dwError != ERROR_ACCESS_DENIED)
					LogFileError(TEXT("FindFirstFileEx in CorrectSecurity failed for"), file, dwError);
			} else {
				do {
					if (_tcscmp(ffd.cFileName, TEXT("..")) == 0 || _tcscmp(ffd.cFileName, TEXT(".")) == 0)
						continue;
					CorrectSecurity(makeFullPath(f, ffd.cFileName, full), ffd.dwFileAttributes, takeownership, sid, acl, oneVolumeOnly);
				} while (FindNextFile(hFind, &ffd) != 0);
				dwError = GetLastError();
				if (dwError != ERROR_NO_MORE_FILES)
					LogError(TEXT("FindNextFile in CorrectSecurity"), dwError);
				FindClose(hFind);
			}
			free(file);
		}
		if (attrib & FILE_ATTRIBUTE_READONLY) { // Remove the read-only attribute
			SetFileAttributes(f, attrib&!FILE_ATTRIBUTE_READONLY);
		}
	}
}
static void ChangeDACL(const SchemeType * scheme, TCHAR * path, DWORD mode, BOOL noinherit)
{
  TCHAR * param = (TCHAR *)LocalAlloc(LPTR, g_string_size*sizeof(TCHAR));
	TCHAR * trusteeName = NULL;
  PSID pSid = NULL;
  DWORD trusteeForm = TRUSTEE_IS_NAME;
  DWORD permissions = 0;

  PACL pOldAcl = NULL;
  PACL pNewAcl = NULL;
  EXPLICIT_ACCESS access;

  DWORD ret = 0;

  if (popstring(param))
    ABORT("Trustee is missing");

  if (NULL == (trusteeName = ParseTrustee(param, &trusteeForm)))
    ABORT_s("Bad trustee (%s)", param);

  if (popstring(param))
    ABORT("Permission flags are missing");

  if (0 == (permissions = ParsePermissions(scheme, param)))
    ABORT_s("Bad permission flags (%s)", param);

  ret = GetNamedSecurityInfo(path, scheme->type,
          DACL_SECURITY_INFORMATION,
          NULL, NULL, &pOldAcl, NULL, NULL);
  if (ret != ERROR_SUCCESS)
    ABORT_d("Cannot read access control list. Error code: %d", ret);

  BuildExplicitAccessWithName(&access, _T(""), permissions, (ACCESS_MODE)mode, 
    scheme->defaultInheritance);

  access.Trustee.TrusteeForm = (TRUSTEE_FORM)trusteeForm;
  access.Trustee.ptstrName = trusteeName;
  if (noinherit)
    access.grfInheritance = NO_INHERITANCE;

  ret = SetEntriesInAcl(1, &access, pOldAcl, &pNewAcl);
  if (ret != ERROR_SUCCESS)
    ABORT_d("Cannot build new access control list. Error code: %d", ret);

  ret = SetNamedSecurityInfo(path, scheme->type,
          DACL_SECURITY_INFORMATION,
          NULL, NULL, pNewAcl, NULL);
  if (ret != ERROR_SUCCESS)
    ABORT_d("Cannot apply new access control list. Error code: %d", ret);

cleanup:
  if (NULL != pNewAcl)
    LocalFree(pNewAcl);
  if (NULL != pOldAcl)
    LocalFree(pOldAcl);

  LocalFree(trusteeName);
  LocalFree(param);
}
static void ChangeOwner(const SchemeType * scheme, TCHAR * path, ChangeMode mode)
{
  TCHAR * param = (TCHAR *)LocalAlloc(LPTR, g_string_size*sizeof(TCHAR));
  SECURITY_INFORMATION what;
  PSID pSidOwner = NULL;
  PSID pSidGroup = NULL;
  PSID pSid = NULL;

  DWORD ret = 0;

  HANDLE hToken;

  if (popstring(param))
    ABORT("Trustee is missing");

  if (NULL == (pSid = ParseSid(param)))
    ABORT_s("Bad trustee (%s)", param);

  switch(mode)
  {
  case ChangeMode_Owner:
    what = OWNER_SECURITY_INFORMATION;
    pSidOwner = pSid;
    break;

  case ChangeMode_Group:
    what = GROUP_SECURITY_INFORMATION;
    pSidGroup = pSid;
    break;

  default:
    ABORT_d("Bug: Unsupported change mode: %d", mode);
  }

  if (!OpenProcessToken(GetCurrentProcess(),
    TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
    ABORT_d("Cannot open process token. Error code: %d", GetLastError());

  if (!SetPrivilege(hToken, SE_RESTORE_NAME, TRUE))
    ABORT("Unable to give SE_RESTORE_NAME privilege.");
  ret = SetNamedSecurityInfo(path, scheme->type, 
          what, pSidOwner, pSidGroup, NULL, NULL);
  if (ret != ERROR_SUCCESS)
    ABORT_d("Cannot apply new ownership. Error code: %d", ret);

cleanup:
  SetPrivilege(hToken, SE_RESTORE_NAME, FALSE);
  CloseHandle(hToken);
  LocalFree(param);
}
예제 #6
0
int enable_access(char *filename)
{
	int	retval = 1;
	PACL myacl = generate_acl();

	if ( ERROR_SUCCESS!=SetNamedSecurityInfo(filename, SE_FILE_OBJECT, 
		DACL_SECURITY_INFORMATION, 
		NULL, NULL, myacl, NULL) ) {
		retval = 0;
	}

	if ( NULL!=myacl ) {
		LocalFree(myacl);
	}
	return retval;
}
예제 #7
0
bool SetOwnerInternal(LPCWSTR Object, LPCWSTR Owner)
{
	bool Result = false;

	PSID Sid = nullptr;
	//в winapi от mingw.org неправильный тип параметра.
	if(!ConvertStringSidToSid((LPWSTR)Owner, &Sid))
	{
		SID_NAME_USE Use;
		DWORD cSid=0, ReferencedDomain=0;
		LookupAccountName(nullptr, Owner, nullptr, &cSid, nullptr, &ReferencedDomain, &Use);
		if(cSid)
		{
			Sid = LocalAlloc(LMEM_FIXED, cSid);
			if(Sid)
			{
				LPWSTR ReferencedDomainName = new WCHAR[ReferencedDomain];
				if(ReferencedDomainName)
				{
					if(LookupAccountName(nullptr, Owner, Sid, &cSid, ReferencedDomainName, &ReferencedDomain, &Use))
					{
					}
					delete[] ReferencedDomainName;
				}
			}
		}
	}
	if(Sid)
	{
		Privilege TakeOwnershipPrivilege(SE_TAKE_OWNERSHIP_NAME);
		Privilege RestorePrivilege(SE_RESTORE_NAME);
		DWORD dwResult = SetNamedSecurityInfo(const_cast<LPWSTR>(Object), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, Sid, nullptr, nullptr, nullptr);
		if(dwResult == ERROR_SUCCESS)
		{
			Result = true;
		}
		else
		{
			SetLastError(dwResult);
		}
	}
	if(Sid)
	{
		LocalFree(Sid);
	}
	return Result;
}
예제 #8
0
파일: mono-security.c 프로젝트: LevNNN/mono
static gboolean
ProtectMachine (gunichar2 *path)
{
    PSID pEveryoneSid = GetEveryoneSid ();
    PSID pAdminsSid = GetAdministratorsSid ();
    DWORD retval = -1;

    if (pEveryoneSid && pAdminsSid) {
        PACL pDACL = NULL;
        EXPLICIT_ACCESS ea [2];
        ZeroMemory (&ea, 2 * sizeof (EXPLICIT_ACCESS));

        /* grant all access to the BUILTIN\Administrators group */
        BuildTrusteeWithSidW (&ea [0].Trustee, pAdminsSid);
        ea [0].grfAccessPermissions = GENERIC_ALL;
        ea [0].grfAccessMode = SET_ACCESS;
        ea [0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
        ea [0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
        ea [0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;

        /* read-only access everyone */
        BuildTrusteeWithSidW (&ea [1].Trustee, pEveryoneSid);
        ea [1].grfAccessPermissions = GENERIC_READ;
        ea [1].grfAccessMode = SET_ACCESS;
        ea [1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
        ea [1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
        ea [1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;

        retval = SetEntriesInAcl (2, ea, NULL, &pDACL);
        if (retval == ERROR_SUCCESS) {
            /* with PROTECTED_DACL_SECURITY_INFORMATION we */
            /* remove any existing ACL (like inherited ones) */
            retval = SetNamedSecurityInfo (path, SE_FILE_OBJECT,
                                           DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
                                           NULL, NULL, pDACL, NULL);
        }
        if (pDACL)
            LocalFree (pDACL);
    }

    if (pEveryoneSid)
        FreeSid (pEveryoneSid);
    if (pAdminsSid)
        FreeSid (pAdminsSid);
    return (retval == ERROR_SUCCESS);
}
예제 #9
0
DWORD ModLoader::AdjustGroupPolicy(std::wstring wstrFilePath)
{
	PACL pOldDACL = NULL, pNewDACL = NULL;
	PSECURITY_DESCRIPTOR pSD = NULL;
	EXPLICIT_ACCESS eaAccess;
	SECURITY_INFORMATION siInfo = DACL_SECURITY_INFORMATION;
	DWORD dwResult = ERROR_SUCCESS;
	PSID pSID;

	// Get a pointer to the existing DACL (Conditionaly).
	dwResult = GetNamedSecurityInfo(wstrFilePath.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSD);
	if (dwResult != ERROR_SUCCESS)
		goto Cleanup;

	ConvertStringSidToSid(L"S-1-15-2-1", &pSID);
	if (pSID == NULL)
		goto Cleanup;

	ZeroMemory(&eaAccess, sizeof(EXPLICIT_ACCESS));
	eaAccess.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE;
	eaAccess.grfAccessMode = SET_ACCESS;
	eaAccess.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
	eaAccess.Trustee.TrusteeForm = TRUSTEE_IS_SID;
	eaAccess.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
	eaAccess.Trustee.ptstrName = (LPWSTR)pSID;

	// Create a new ACL that merges the new ACE into the existing DACL.
	dwResult = SetEntriesInAcl(1, &eaAccess, pOldDACL, &pNewDACL);
	if (ERROR_SUCCESS != dwResult)
		goto Cleanup;

	// Attach the new ACL as the object's DACL.
	dwResult = SetNamedSecurityInfo((LPWSTR)wstrFilePath.c_str(), SE_FILE_OBJECT, siInfo, NULL, NULL, pNewDACL, NULL);
	if (ERROR_SUCCESS != dwResult)
		goto Cleanup;

Cleanup:
	if (pSD != NULL)
		LocalFree((HLOCAL)pSD);
	if (pNewDACL != NULL)
		LocalFree((HLOCAL)pNewDACL);

	return dwResult;
}
static void ChangeInheritance(const SchemeType * scheme, TCHAR * path, BOOL inherit)
{
  PACL pOldAcl = NULL;
  DWORD ret = 0;

  ret = GetNamedSecurityInfo(path, scheme->type,
          DACL_SECURITY_INFORMATION,
          NULL, NULL, &pOldAcl, NULL, NULL);
  if (ret != ERROR_SUCCESS)
    ABORT_d("Cannot read access control list. Error code: %d", ret);

  ret = SetNamedSecurityInfo(path, scheme->type,
          DACL_SECURITY_INFORMATION | (inherit ? UNPROTECTED_DACL_SECURITY_INFORMATION : PROTECTED_DACL_SECURITY_INFORMATION),
          NULL, NULL, pOldAcl, NULL);
  if (ret != ERROR_SUCCESS)
    ABORT_d("Cannot change access control list inheritance. Error code: %d", ret);

cleanup:
  LocalFree(pOldAcl);
}
예제 #11
0
bool SetOwnerInternal(const string& Object, const string& Owner)
{
	bool Result = false;

	PSID Sid = nullptr;
	SCOPE_EXIT { LocalFree(Sid); };

	if(!ConvertStringSidToSid(Owner.data(), &Sid))
	{
		SID_NAME_USE Use;
		DWORD cSid=0, ReferencedDomain=0;
		LookupAccountName(nullptr, Owner.data(), nullptr, &cSid, nullptr, &ReferencedDomain, &Use);
		if(cSid)
		{
			Sid = LocalAlloc(LMEM_FIXED, cSid);
			if(Sid)
			{
				std::vector<wchar_t> ReferencedDomainName(ReferencedDomain);
				if(LookupAccountName(nullptr, Owner.data(), Sid, &cSid, ReferencedDomainName.data(), &ReferencedDomain, &Use))
				{
					;
				}
			}
		}
	}
	if(Sid)
	{
		SCOPED_ACTION(Privilege)(SE_TAKE_OWNERSHIP_NAME);
		SCOPED_ACTION(Privilege)(SE_RESTORE_NAME);
		DWORD dwResult = SetNamedSecurityInfo(const_cast<LPWSTR>(Object.data()), SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, Sid, nullptr, nullptr, nullptr);
		if(dwResult == ERROR_SUCCESS)
		{
			Result = true;
		}
		else
		{
			SetLastError(dwResult);
		}
	}
	return Result;
}
예제 #12
0
bool CWinSecurity::SetFileOwner(const string& filename,
                                const string& owner, const string& group, 
                                unsigned int* uid, unsigned int* gid)
{
    if ( uid ) *uid = 0;
    if ( gid ) *gid = 0;

    if ( owner.empty()  &&  group.empty() ) {
        CNcbiError::Set(CNcbiError::eInvalidArgument);
        return false;
    }

    HANDLE  token     = INVALID_HANDLE_VALUE;
    PSID    owner_sid = NULL;
    PSID    group_sid = NULL;
    bool    success   = false;

    // Get SIDs for new owner and group
    if ( !owner.empty() ) {
        owner_sid = x_GetAccountSidByName(owner, SidTypeUser);
        if (!owner_sid) {
            return false;
        }
    }
    if ( !group.empty() ) {
        group_sid = x_GetAccountSidByName(group, SidTypeGroup);
        if (!group_sid) {
            goto cleanup;
        }
    }
    if (uid || gid) {
        s_GetOwnerGroupFromSIDs(owner_sid, group_sid, NULL, NULL, uid, gid);
    }

    // Change owner

    SECURITY_INFORMATION security_info = 0;
    if ( owner_sid ) {
        security_info |= OWNER_SECURITY_INFORMATION;
    }
    if ( group_sid ) {
        security_info |= GROUP_SECURITY_INFORMATION;
    }

    // Set new owner/group in the object's security descriptor
    if ( SetNamedSecurityInfo((TXChar*)_T_XCSTRING(filename),
                              SE_FILE_OBJECT, security_info,
                              owner_sid, group_sid, NULL, NULL) == ERROR_SUCCESS ) {
        success = true;
        goto cleanup;
    }

    // If the previous call failed because access was denied,
    // enable the necessary admin privileges for the current thread and try again.

    token = s_GetThreadToken(TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY);
    if ( token == INVALID_HANDLE_VALUE) {
        goto cleanup;
    }
    bool prev_ownership_name;
    bool prev_restore_name;

    if ( !SetTokenPrivilege(token, SE_TAKE_OWNERSHIP_NAME, true, &prev_ownership_name) ||
         !SetTokenPrivilege(token, SE_RESTORE_NAME, true, &prev_restore_name) ) {
        goto cleanup;
    }
    if ( SetNamedSecurityInfo((TXChar*)_T_XCSTRING(filename),
                              SE_FILE_OBJECT, security_info,
                              owner_sid, group_sid, NULL, NULL) == ERROR_SUCCESS ) {
        success = true;
    }
    // Restore privileges
    SetTokenPrivilege(token, SE_TAKE_OWNERSHIP_NAME, prev_ownership_name);
    SetTokenPrivilege(token, SE_RESTORE_NAME, prev_restore_name);


cleanup:
    if ( owner_sid ) LocalFree(owner_sid);
    if ( group_sid ) LocalFree(group_sid);
    if ( token != INVALID_HANDLE_VALUE) CloseHandle(token);

    return success;
}
예제 #13
0
bool
perm::set_acls( const char *filename )
{
	PACL newDACL, oldDACL;
	PSECURITY_DESCRIPTOR pSD;
	DWORD err;
	EXPLICIT_ACCESS ea;
	PEXPLICIT_ACCESS entryList;
	ULONG entryCount;
	unsigned int i;
	
	pSD = NULL;
	newDACL = oldDACL = NULL;
	
	
	// If this is not on an NTFS volume, we're done.  In fact, we'll
	// likely crash if we try all the below ACL junk on a volume which
	// does not support ACLs. Dooo!
	if ( !volume_has_acls(filename) ) 
	{
		dprintf(D_FULLDEBUG, "perm::set_acls(%s): volume has no ACLS\n",
				filename);
		// return true (success) here, so upper layers do not consider
		// this a fatal error --- thus allowing us to run on FAT32.
		return true;
	}
	
	// Make sure we have the sid.
	
	if ( psid == NULL ) 
	{
		dprintf(D_ALWAYS, "perm::set_acls(%s): do not have SID for user\n",
				filename);
		return false;
	}

	// first get the file's old DACL so we can copy it into the new one.

	err = GetNamedSecurityInfo((char*)filename, SE_FILE_OBJECT,
			DACL_SECURITY_INFORMATION, NULL, NULL, &oldDACL, NULL, &pSD);

	if ( ERROR_SUCCESS != err ) {
		// this is intentionally D_FULLDEBUG, since this error often occurs
		// if the caller doesn't have WRITE_DAC access to the path. The 
		// remedy in that case is to call set_owner() on the path first.
		dprintf(D_FULLDEBUG, "perm::set_acls(%s): failed to get security info. "
				"err=%d\n", filename, err);
		return false;
	}

	// now, check to make sure we don't already have an entry in ACL
	// that matches the one we're about to insert.
	err = GetExplicitEntriesFromAcl(oldDACL, &entryCount, &entryList); 

	if ( ERROR_SUCCESS != err ) {
		dprintf(D_ALWAYS, "perm::set_acls(%s): failed to get entries from ACL. "
				"err=%d\n", filename, err);
		LocalFree(oldDACL);
		return false;
	}

	for (i=0; i<entryCount; i++) {
		if (	( entryList[i].grfAccessPermissions == GENERIC_ALL ) &&
				( entryList[i].grfAccessMode == GRANT_ACCESS ) &&
				( entryList[i].Trustee.TrusteeForm == TRUSTEE_IS_SID ) &&
				( EqualSid(entryList[i].Trustee.ptstrName, psid) ) ) {

			// MATCH - the ACE is already in the ACL,
			// so just return success.
			
			dprintf(D_FULLDEBUG, "set_acls() found a matching ACE already "
					"in the ACL, so skipping the add\n");

			LocalFree(entryList);
			LocalFree(oldDACL);
			return true;
		}
	}
	
	// didn't find the ACE in there already, so proceed to add it.
	LocalFree(entryList);

	// now set up an EXPLICIT_ACCESS structure for the new ACE
	
	ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
	ea.grfAccessPermissions = GENERIC_ALL;
	ea.grfAccessMode        = GRANT_ACCESS;
	ea.grfInheritance       = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
	ea.Trustee.pMultipleTrustee = NULL;
	ea.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
	ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
	ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
	ea.Trustee.ptstrName = (char*)psid;

	// create the new ACL with the new ACE
	err = SetEntriesInAcl(1, &ea, oldDACL, &newDACL);

	if ( ERROR_SUCCESS != err ) {
		dprintf(D_ALWAYS, "perm::set_acls(%s): failed to add new ACE "
				"(err=%d)\n", filename, err);

		LocalFree(oldDACL);
		return false;
	}

	// Attach new ACL to the file

	// PROTECTED_DACL_SECURITY_INFORMATION causes the function to NOT
	// inherit its parent's ACL. I believe this is what we want.
	err = SetNamedSecurityInfo((char*)filename, SE_FILE_OBJECT,
		DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
		NULL,NULL,newDACL,NULL); 
	
	if ( err == ERROR_ACCESS_DENIED ) {
		// set the SE_SECURITY_NAME privilege and try again.
		
		dprintf(D_FULLDEBUG, "SetFileSecurity() failed; "
				"adding SE_SECURITY_NAME priv and trying again.\n");

		HANDLE hToken = NULL;

		if (!OpenProcessToken(GetCurrentProcess(), 
			TOKEN_ADJUST_PRIVILEGES, &hToken)) {

          dprintf(D_ALWAYS, "perm: OpenProcessToken failed: %u\n",
				  GetLastError()); 
       } else {

	    	// Enable the SE_SECURITY_NAME privilege.
    		if (!SetPrivilege(hToken, SE_SECURITY_NAME, TRUE)) {
	   			dprintf(D_ALWAYS, "perm: can't set SE_SECURITY_NAME privs "
					   "to set ACLs.\n");
    		} else { 
				err = SetNamedSecurityInfo((char*)filename, SE_FILE_OBJECT,
				DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
				NULL,NULL,newDACL,NULL); 
			}
			CloseHandle(hToken);
		}
	}

	// clean up our memory.
	LocalFree(oldDACL);
	LocalFree(newDACL);

	if (err != ERROR_SUCCESS)
	{
		dprintf(D_ALWAYS, "perm::set_acls(%s): Unable to set file ACL"
				"(err=%d).\n", filename,GetLastError() );
		return false;
	}
	
	return true;
}
JNIEXPORT void JNICALL Java_com_microsoft_tfs_jni_internal_filesystem_NativeFileSystem_nativeRemoveExplicitAllowEntries(
    JNIEnv *env, jclass cls, jstring jPath, jstring jUserSIDString)
{
	const WCHAR * path = NULL;
	const WCHAR * userSIDString = NULL;
	PSID userSID = NULL;
	DWORD result = 0;
	PACL dacl = NULL;
	PSECURITY_DESCRIPTOR securityDescriptor = NULL;
	ACL_SIZE_INFORMATION aclSizeInfo;
	ULONG aceCount = 0;
	BOOL modifiedDACL = FALSE;

	if (jPath == NULL)
    {
       	throwRuntimeExceptionString(env, "path must not be null");
		goto cleanup;
    }

	if (jUserSIDString == NULL)
    {
       	throwRuntimeExceptionString(env, "user must not be null");
		goto cleanup;
    }
	
	// Convert the SID string to a struct
	if ((userSIDString = javaStringToPlatformChars(env, jUserSIDString)) == NULL)
	{
		// String allocation failed, exception already thrown
		goto cleanup;
	}

	if (ConvertStringSidToSidW(userSIDString, &userSID) == FALSE)
	{
		throwRuntimeExceptionCode(env, GetLastError(), "Error converting string sid %S to sid", userSIDString);
		goto cleanup;
	}

	if ((path = javaStringToPlatformChars(env, jPath)) == NULL)
	{
		// String allocation failed, exception already thrown
		goto cleanup;
	}

	// Get file's DACL
	result = GetNamedSecurityInfo(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 
		NULL, NULL, &dacl, NULL, &securityDescriptor);
	if (result != ERROR_SUCCESS)
	{
		throwRuntimeExceptionCode(env, result, "Error getting file security info for %S", path);
		goto cleanup;
	}

	// Get the count of entries int the DACL
	if (GetAclInformation(dacl, &aclSizeInfo, sizeof(aclSizeInfo), AclSizeInformation) == 0)
	{
		throwRuntimeExceptionCode(env, GetLastError(), "Error getting DACL");
		goto cleanup;
	}

	// Loop over the DACL backwards, removing matching entries
	for (aceCount = aclSizeInfo.AceCount; aceCount > 0; aceCount--)
	{
		ULONG aceIndex = aceCount - 1;
		ACCESS_ALLOWED_ACE * ace = NULL;
		PSID sid = NULL;

		if (GetAce(dacl, aceIndex, (LPVOID *) &ace) == 0)
		{
			throwRuntimeExceptionCode(env, GetLastError(), "Error getting ACE at index %d", aceIndex);
			goto cleanup;
		}

		// Skip inherited (non-explicit) entries
		if ((((ACE_HEADER *) ace)->AceFlags & INHERITED_ACE) == INHERITED_ACE)
		{
			continue;
		}

		// Extract the SID for "allow" types
		switch(((ACE_HEADER *) ace)->AceType)
		{
			case ACCESS_ALLOWED_ACE_TYPE:
				sid = (PSID) &((ACCESS_ALLOWED_ACE *) ace)->SidStart;
				break;
			case ACCESS_ALLOWED_CALLBACK_ACE_TYPE:
				sid = (PSID) &((ACCESS_ALLOWED_CALLBACK_ACE *) ace)->SidStart;
				break;
			case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
				sid = (PSID) &((ACCESS_ALLOWED_CALLBACK_OBJECT_ACE *) ace)->SidStart;
				break;
			case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
				sid = (PSID) &((ACCESS_ALLOWED_OBJECT_ACE *) ace)->SidStart;
				break;
			default:
				// These are "deny" or other entries
				break;
		}

		if (sid != NULL && EqualSid(sid, userSID))
		{
			if (DeleteAce(dacl, aceIndex) == 0)
			{
				throwRuntimeExceptionCode(env, GetLastError(), "Error deleting ACE at index %d", aceIndex);
				goto cleanup;
			}

			modifiedDACL = TRUE;
		}

		// Nothing to free in the loop, all pointers are into dacl
	}

	if (modifiedDACL)
	{
		result = SetNamedSecurityInfo((WCHAR *) path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
			NULL, NULL, dacl, NULL);
		if (result != ERROR_SUCCESS)
		{
			throwRuntimeExceptionCode(env, result, "Error setting security info for %S", path);
			goto cleanup;
		}
	}

cleanup:

	if (path != NULL)
	{
		releasePlatformChars(env, jPath, path);
	}
	if (userSID != NULL)
	{
		LocalFree(userSID);
	}
	if (userSIDString != NULL)
	{
	   releasePlatformChars(env, jUserSIDString, userSIDString);
	}
	// dacl points inside securityDescriptor
	if (securityDescriptor != NULL)
	{
		LocalFree(securityDescriptor);
	}
}
JNIEXPORT void JNICALL Java_com_microsoft_tfs_jni_internal_filesystem_NativeFileSystem_nativeCopyExplicitDACLEntries(
    JNIEnv *env, jclass cls, jstring jSourcePath, jstring jTargetPath)
{
	const WCHAR * sourcePath = NULL;
	const WCHAR * targetPath = NULL;
	DWORD result = 0;
	PACL sourceDACL = NULL;
	PACL targetDACL = NULL;
	PACL newDACL = NULL;
	PSECURITY_DESCRIPTOR sourceSecurityDescriptor = NULL;
	PSECURITY_DESCRIPTOR targetSecurityDescriptor = NULL;
	PEXPLICIT_ACCESS sourceExplicitEntries = NULL;
	ULONG sourceExplicitEntriesCount = 0;

	if (jSourcePath == NULL)
    {
       	throwRuntimeExceptionString(env, "source path must not be null");
		goto cleanup;
    }

	if (jTargetPath == NULL)
	{
		throwRuntimeExceptionString(env, "target path must not be null");
		goto cleanup;
	}

	if ((sourcePath = javaStringToPlatformChars(env, jSourcePath)) == NULL)
	{
		// String allocation failed, exception already thrown
		goto cleanup;
	}

	if ((targetPath = javaStringToPlatformChars(env, jTargetPath)) == NULL)
	{
		// String allocation failed, exception already thrown
		goto cleanup;
	}

	// Get source's DACL
	result = GetNamedSecurityInfo(sourcePath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 
		NULL, NULL, &sourceDACL, NULL, &sourceSecurityDescriptor);
	if (result != ERROR_SUCCESS)
	{
		throwRuntimeExceptionCode(env, result, "Error getting security info for %S", sourcePath);
		goto cleanup;
	}

	// Get the explicit entries in the source DACL
	result = GetExplicitEntriesFromAcl(sourceDACL, &sourceExplicitEntriesCount, &sourceExplicitEntries);
	if (result != ERROR_SUCCESS)
	{
		throwRuntimeExceptionCode(env, result, "Error getting ACL entries");
		goto cleanup;
	}

	if (sourceExplicitEntries == 0)
	{
		goto cleanup;
	}

	// Get target's DACL
	result = GetNamedSecurityInfo(targetPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 
		NULL, NULL, &targetDACL, NULL, &targetSecurityDescriptor);
	if (result != ERROR_SUCCESS)
	{
		throwRuntimeExceptionCode(env, result, "Error getting security info for %S", targetPath);
		goto cleanup;
	}

	// Merge the source entries into the target list
	result = SetEntriesInAcl(sourceExplicitEntriesCount, sourceExplicitEntries, targetDACL, &newDACL);
    if (result != ERROR_SUCCESS)
	{
		throwRuntimeExceptionCode(env, result, "Error setting entries in ACL");
        goto cleanup;
    }

	// Set the list on the target path
	result = SetNamedSecurityInfo((WCHAR *) targetPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
		NULL, NULL, newDACL, NULL);
	if (result != ERROR_SUCCESS)
	{
		throwRuntimeExceptionCode(env, result, "Error setting security info for %S", targetPath);
        goto cleanup;
	}

cleanup:

	if (sourcePath != NULL)
	{
		releasePlatformChars(env, jSourcePath, sourcePath);
	}
	if (targetPath != NULL)
	{
		releasePlatformChars(env, jTargetPath, targetPath);
	}
	// sourceDACL points into sourceSecurityDescriptor
	if (sourceSecurityDescriptor != NULL)
	{
		LocalFree(sourceSecurityDescriptor);
	}
	// targetDACL points into targetSecurityDescriptor
	if (targetSecurityDescriptor != NULL)
	{
		LocalFree(targetSecurityDescriptor);
	}
	if (sourceExplicitEntries != NULL)
	{
		LocalFree(sourceExplicitEntries);
	}
	if (newDACL != NULL)
	{
		LocalFree(newDACL);
	}
}
예제 #16
0
파일: utility.cpp 프로젝트: Kaldaien/BMT
BOOL TakeOwnership (LPTSTR lpszOwnFile)
{

  BOOL bRetval = FALSE;

  HANDLE hToken = NULL;
  PSID pSIDAdmin = NULL;
  PSID pSIDEveryone = NULL;
  PACL pACL = NULL;
  SID_IDENTIFIER_AUTHORITY SIDAuthWorld =
    SECURITY_WORLD_SID_AUTHORITY;
  SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
  const int NUM_ACES = 2;
  EXPLICIT_ACCESS ea [NUM_ACES];
  DWORD dwRes;

  // Specify the DACL to use.
  // Create a SID for the Everyone group.
  if (!AllocateAndInitializeSid (&SIDAuthWorld, 1,
    SECURITY_WORLD_RID,
    0,
    0, 0, 0, 0, 0, 0,
    &pSIDEveryone))
  {
    //printf ("AllocateAndInitializeSid (Everyone) error %u\n",
      //GetLastError ());
    goto Cleanup;
  }

  // Create a SID for the BUILTIN\Administrators group.
  if (!AllocateAndInitializeSid (&SIDAuthNT, 2,
    SECURITY_BUILTIN_DOMAIN_RID,
    DOMAIN_ALIAS_RID_ADMINS,
    0, 0, 0, 0, 0, 0,
    &pSIDAdmin))
  {
    //printf ("AllocateAndInitializeSid (Admin) error %u\n",
      //GetLastError ());
    goto Cleanup;
  }

  ZeroMemory (&ea, NUM_ACES * sizeof (EXPLICIT_ACCESS));

  // Set full control for Everyone.
  ea [0].grfAccessPermissions = GENERIC_ALL;// GENERIC_READ;
  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)pSIDEveryone;

  // Set full control for Administrators.
  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_GROUP;
  ea [1].Trustee.ptstrName = (LPTSTR)pSIDAdmin;

  if (ERROR_SUCCESS != SetEntriesInAcl (NUM_ACES,
    ea,
    NULL,
    &pACL))
  {
    //printf ("Failed SetEntriesInAcl\n");
    goto Cleanup;
  }

  // Try to modify the object's DACL.
  dwRes = SetNamedSecurityInfo (
    lpszOwnFile,                 // name of the object
    SE_FILE_OBJECT,              // type of object
    DACL_SECURITY_INFORMATION,   // change only the object's DACL
    NULL, NULL,                  // do not change owner or group
    pACL,                        // DACL specified
    NULL);                       // do not change SACL

  if (ERROR_SUCCESS == dwRes)
  {
    //printf ("Successfully changed DACL\n");
    bRetval = TRUE;
    // No more processing needed.
    goto Cleanup;
  }
  if (dwRes != ERROR_ACCESS_DENIED)
  {
    //printf ("First SetNamedSecurityInfo call failed: %u\n",
      //dwRes);
    goto Cleanup;
  }

  // If the preceding call failed because access was denied, 
  // enable the SE_TAKE_OWNERSHIP_NAME privilege, create a SID for 
  // the Administrators group, take ownership of the object, and 
  // disable the privilege. Then try again to set the object's DACL.

  // Open a handle to the access token for the calling process.
  if (!OpenProcessToken (GetCurrentProcess (),
    TOKEN_ADJUST_PRIVILEGES,
    &hToken))
  {
    //printf ("OpenProcessToken failed: %u\n", GetLastError ());
    goto Cleanup;
  }

  // Enable the SE_TAKE_OWNERSHIP_NAME privilege.
  if (!SetPrivilege (hToken, SE_TAKE_OWNERSHIP_NAME, TRUE))
  {
    //printf ("You must be logged on as Administrator.\n");
    goto Cleanup;
  }

  // Set the owner in the object's security descriptor.
  dwRes = SetNamedSecurityInfo (
    lpszOwnFile,                 // name of the object
    SE_FILE_OBJECT,              // type of object
    OWNER_SECURITY_INFORMATION,  // change only the object's owner
    pSIDAdmin,                   // SID of Administrator group
    NULL,
    NULL,
    NULL);

  if (dwRes != ERROR_SUCCESS)
  {
    //printf ("Could not set owner. Error: %u\n", dwRes);
    goto Cleanup;
  }

  // Disable the SE_TAKE_OWNERSHIP_NAME privilege.
  if (!SetPrivilege (hToken, SE_TAKE_OWNERSHIP_NAME, FALSE))
  {
    //printf ("Failed SetPrivilege call unexpectedly.\n");
    goto Cleanup;
  }

  // Try again to modify the object's DACL,
  // now that we are the owner.
  dwRes = SetNamedSecurityInfo (
    lpszOwnFile,                 // name of the object
    SE_FILE_OBJECT,              // type of object
    DACL_SECURITY_INFORMATION,   // change only the object's DACL
    NULL, NULL,                  // do not change owner or group
    pACL,                        // DACL specified
    NULL);                       // do not change SACL

  if (dwRes == ERROR_SUCCESS)
  {
    //printf ("Successfully changed DACL\n");
    bRetval = TRUE;
  }
  else
  {
    //printf ("Second SetNamedSecurityInfo call failed: %u\n",
      //dwRes);
  }

Cleanup:

  if (pSIDAdmin)
    FreeSid (pSIDAdmin);

  if (pSIDEveryone)
    FreeSid (pSIDEveryone);

  if (pACL)
    LocalFree (pACL);

  if (hToken)
    CloseHandle (hToken);

  return bRetval;
}
JNIEXPORT void JNICALL Java_com_microsoft_tfs_jni_internal_filesystem_NativeFileSystem_nativeGrantInheritableFullControl(
    JNIEnv *env, jclass cls, jstring jPath, jstring jUserSIDString, jstring jCopyExplicitRulesFromPath)
{
	const WCHAR * path = NULL;
	const WCHAR * userSIDString = NULL;
	const WCHAR * copyExplicitRulesFromPath = NULL;
	DWORD result = 0;
	PACL existingDACL = NULL;
	PACL newDACL = NULL;
	PSECURITY_DESCRIPTOR securityDescriptor = NULL;
	PSID userSID = NULL;
	EXPLICIT_ACCESS fullControl;
	
	if (jPath == NULL)
    {
       	throwRuntimeExceptionString(env, "path must not be null");
		goto cleanup;
    }

	if (jUserSIDString == NULL)
	{
		throwRuntimeExceptionString(env, "user must not be null");
		goto cleanup;
	}

	// Get the existing DACL entries
	if (jCopyExplicitRulesFromPath != NULL)
	{
		if ((copyExplicitRulesFromPath = javaStringToPlatformChars(env, jCopyExplicitRulesFromPath)) == NULL)
		{
			// String allocation failed, exception already thrown
			goto cleanup;
		}

		result = GetNamedSecurityInfo(copyExplicitRulesFromPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 
			NULL, NULL, &existingDACL, NULL, &securityDescriptor);

		if (result != ERROR_SUCCESS)
		{
			throwRuntimeExceptionCode(env, result, "Error getting file security info for %S", copyExplicitRulesFromPath);
			goto cleanup;
	    }
	}

	// Convert the string SID to a structure
	if ((userSIDString = javaStringToPlatformChars(env, jUserSIDString)) == NULL)
	{
		// String allocation failed, exception already thrown
		goto cleanup;
	}

	if (ConvertStringSidToSidW(userSIDString, &userSID) == FALSE)
	{
		throwRuntimeExceptionCode(env, GetLastError(), "Error converting string sid %S to sid", userSIDString);
		goto cleanup;
	}

	/*
	 * Create a new explicit access entry with rights equivalent to .NET's 
	 * FileSystemRights.FullControl (0x1F01FF; see FileSecurity.cs) and
	 * full inheritance.
	 */
	ZeroMemory(&fullControl, sizeof(EXPLICIT_ACCESS));
    fullControl.grfAccessPermissions = 0x1F01FF;
    fullControl.grfAccessMode = GRANT_ACCESS;
    fullControl.grfInheritance= CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
    fullControl.Trustee.TrusteeForm = TRUSTEE_IS_SID;
	fullControl.Trustee.TrusteeType = TRUSTEE_IS_USER;
    fullControl.Trustee.ptstrName = userSID;
	
	// Merge new entry with old entries into a new list
	result = SetEntriesInAcl(1, &fullControl, existingDACL, &newDACL);
    if (result != ERROR_SUCCESS)
	{
		throwRuntimeExceptionCode(env, result, "Error setting entries in ACL");
        goto cleanup;
    }

	// Set the list on the path
	if ((path = javaStringToPlatformChars(env, jPath)) == NULL)
	{
		// String allocation failed, exception already thrown
		goto cleanup;
	}

	result = SetNamedSecurityInfo((WCHAR *) path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
		NULL, NULL, newDACL, NULL);
	if (result != ERROR_SUCCESS)
	{
		throwRuntimeExceptionCode(env, result, "Error setting file security info for %S", path);
        goto cleanup;
	}

cleanup:

	if (path != NULL)
	{
		releasePlatformChars(env, jPath, path);
	}
	if (userSIDString != NULL)
	{
		releasePlatformChars(env, jUserSIDString, userSIDString);
	}
	if (copyExplicitRulesFromPath != NULL)
	{
		releasePlatformChars(env, jCopyExplicitRulesFromPath, copyExplicitRulesFromPath);
	}
	if (securityDescriptor != NULL)
	{
		LocalFree(securityDescriptor);
	}
	if (userSID != NULL)
	{
		LocalFree(userSID);
	}
	if (newDACL != NULL)
	{
		LocalFree(newDACL);
	}
	// existingDACL points inside securityDescriptor
}
/**
 * @todo Format code style.
 * @todo Add full unicode support.
 * @todo Add event log capabilities / check return values.
 */
static DWORD vboxServiceWinAddAceToObjectsSecurityDescriptor(LPTSTR pszObjName,
                                                             SE_OBJECT_TYPE ObjectType,
                                                             LPTSTR pszTrustee,
                                                             TRUSTEE_FORM TrusteeForm,
                                                             DWORD dwAccessRights,
                                                             ACCESS_MODE AccessMode,
                                                             DWORD dwInheritance)
{
    DWORD dwRes = 0;
    PACL pOldDACL = NULL, pNewDACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    EXPLICIT_ACCESS ea;

    if (NULL == pszObjName)
        return ERROR_INVALID_PARAMETER;

    /* Get a pointer to the existing DACL. */
    dwRes = GetNamedSecurityInfo(pszObjName, ObjectType,
                                 DACL_SECURITY_INFORMATION,
                                 NULL, NULL, &pOldDACL, NULL, &pSD);
    if (ERROR_SUCCESS != dwRes)
    {
        if (dwRes == ERROR_FILE_NOT_FOUND)
            VBoxServiceError("AddAceToObjectsSecurityDescriptor: Object not found/installed: %s\n", pszObjName);
        else
            VBoxServiceError("AddAceToObjectsSecurityDescriptor: GetNamedSecurityInfo: Error %u\n", dwRes);
        goto l_Cleanup;
    }

    /* Initialize an EXPLICIT_ACCESS structure for the new ACE. */
    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
    ea.grfAccessPermissions = dwAccessRights;
    ea.grfAccessMode = AccessMode;
    ea.grfInheritance= dwInheritance;
    ea.Trustee.TrusteeForm = TrusteeForm;
    ea.Trustee.ptstrName = pszTrustee;

    /* Create a new ACL that merges the new ACE into the existing DACL. */
    dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
    if (ERROR_SUCCESS != dwRes)
    {
        VBoxServiceError("AddAceToObjectsSecurityDescriptor: SetEntriesInAcl: Error %u\n", dwRes);
        goto l_Cleanup;
    }

    /* Attach the new ACL as the object's DACL. */
    dwRes = SetNamedSecurityInfo(pszObjName, ObjectType,
                                 DACL_SECURITY_INFORMATION,
                                 NULL, NULL, pNewDACL, NULL);
    if (ERROR_SUCCESS != dwRes)
    {
        VBoxServiceError("AddAceToObjectsSecurityDescriptor: SetNamedSecurityInfo: Error %u\n", dwRes);
        goto l_Cleanup;
    }

    /** @todo get rid of that spaghetti jump ... */
l_Cleanup:

    if(pSD != NULL)
        LocalFree((HLOCAL) pSD);
    if(pNewDACL != NULL)
        LocalFree((HLOCAL) pNewDACL);

    return dwRes;
}
예제 #19
0
void setSecurityACLs()
{
	CString fullPath = getPathToCurrentExeContainer();
	// Check to make sure that the dll has the ACLs to load in an appcontainer
	// We're doing this here as the adapter has no setup script and should be xcopy deployable/removeable

	PACL pOldDACL = NULL, pNewDACL = NULL;
	PSECURITY_DESCRIPTOR pSD = NULL;
	EXPLICIT_ACCESS ea;
	SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;

	// The check is done on the folder and should be inherited to all objects
	DWORD dwRes = GetNamedSecurityInfo(fullPath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, &pSD);

	// Get the SID for "ALL APPLICATION PACAKGES" since it is localized
	PSID pAllAppPackagesSID = NULL;
	bool bResult = ConvertStringSidToSid(L"S-1-15-2-1", &pAllAppPackagesSID);

	if (bResult)
	{
		// Initialize an EXPLICIT_ACCESS structure for the new ACE. 
		ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
		ea.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE;
		ea.grfAccessMode = SET_ACCESS;
		ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
		ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;;
		ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
		ea.Trustee.ptstrName = (LPTSTR)pAllAppPackagesSID;

		// Create a new ACL that merges the new ACE into the existing DACL.
		dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
		if (dwRes == ERROR_SUCCESS)
		{
			dwRes = SetNamedSecurityInfo(fullPath.GetBuffer(), SE_FILE_OBJECT, si, NULL, NULL, pNewDACL, NULL);
			if (dwRes == ERROR_SUCCESS)
			{

			}
			else
			{
				// The ACL was not set, this isn't fatal as it only impacts IE in EPM and Edge and the user can set it manually
				wcout << L"Could not set ACL to allow access to IE EPM or Edge.";
				wcout << L"\n";
				wcout << Helpers::GetLastErrorMessage().GetBuffer();
				wcout << L"\n";
				wcout << L"You can set the ACL manually by adding Read & Execute permissions for 'All APPLICATION PACAKGES' to each dll.";
				wcout << L"\n";
			}
		}
	}
	else
	{
		std::cerr << "Failed to get the SID for ALL_APP_PACKAGES." << std::endl;
		std::cerr << "Win32 error code: " << GetLastError() << std::endl;
	}

	if (pAllAppPackagesSID != NULL)
	{
		LocalFree(pAllAppPackagesSID);
	}

	if (pSD != NULL)
	{
		LocalFree((HLOCAL)pSD);
	}
	if (pNewDACL != NULL)
	{
		LocalFree((HLOCAL)pNewDACL);
	}
}
예제 #20
0
BOOL SetOwner(LPCTSTR filename, LPCTSTR newOwner)
{
  PSID sid = nullptr;
  BOOL res = TRUE;
  PACL pacl = nullptr;

  // get the SID for the new owner
  TCHAR domainUnused[4096];
  DWORD sidSize = 0;
  DWORD domainBufSize = 4096;
  SID_NAME_USE sidUse;
  // pre-flight to determine required size of the sid
  LookupAccountName(nullptr, newOwner, nullptr, &sidSize, domainUnused, &domainBufSize, &sidUse);
  sid = (PSID)malloc(sidSize);
  // determine sid for account name
  if (!LookupAccountName(nullptr, newOwner, sid, &sidSize, domainUnused, &domainBufSize, &sidUse)) {
    qCritical("failed to look up account name: %ls", newOwner);
    res = FALSE;
  } else {
    EXPLICIT_ACCESS access;
    ZeroMemory(&access, sizeof(EXPLICIT_ACCESS));

    wchar_t ownerTemp[UNLEN + 1];
    wcsncpy(ownerTemp, newOwner, UNLEN + 1);

    // Set full control for Administrators.
    access.grfAccessPermissions = GENERIC_ALL;
    access.grfAccessMode = SET_ACCESS;
    access.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
    access.Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    access.Trustee.ptstrName = (LPTSTR)sid;

    DWORD secRes = SetEntriesInAcl(1, &access, nullptr, &pacl);
    if (secRes != ERROR_SUCCESS) {
      qCritical("failed to set up acls: %lu", secRes);
      return FALSE;
    }


    // filename parameter for SetNamedSecurityInfo isn't const
    // which is odd since it is documented to be a input parameter...
    TCHAR *fileNameBuf = new TCHAR[32768];
    wcsncpy_s(fileNameBuf, 32768, filename, 32768);
    // Set the owner on the file and give him full access
    secRes = SetNamedSecurityInfo(
        fileNameBuf, SE_FILE_OBJECT,
        OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
        sid, nullptr, pacl, nullptr);

    delete [] fileNameBuf;
    if (secRes != NOERROR) {
      qCritical("failed to set file owner: %d", secRes);
      res = false;
    }
  }

  if (sid != nullptr) {
    free(sid);
  }

  return res;
}
예제 #21
0
/////////////////////////////////////////////////////////////////////
// 
// Function:    
//
// Description: 
//
/////////////////////////////////////////////////////////////////////
UINT CARestorePermissionBOINCData::OnExecution()
{
    DWORD               dwRes = 0;
    PACL                pACL = NULL;
    ULONGLONG           rgSidSY[(SECURITY_MAX_SID_SIZE+sizeof(ULONGLONG)-1)/sizeof(ULONGLONG)]={0};
    ULONGLONG           rgSidBA[(SECURITY_MAX_SID_SIZE+sizeof(ULONGLONG)-1)/sizeof(ULONGLONG)]={0};
    DWORD               dwSidSize;
    EXPLICIT_ACCESS     ea[2];
    ULONG               ulEntries = 0;
    tstring             strBOINCDataDirectory;
    UINT                uiReturnValue = -1;

    uiReturnValue = GetProperty( _T("DATADIR"), strBOINCDataDirectory );
    if ( uiReturnValue ) return uiReturnValue;


    // Initialize an EXPLICIT_ACCESS structure for all ACEs.
    ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));

    // Create a SID for the SYSTEM.
    dwSidSize = sizeof( rgSidSY );
    if(!CreateWellKnownSid(WinLocalSystemSid, NULL, rgSidSY, &dwSidSize))
    {
        LogMessage(
            INSTALLMESSAGE_ERROR,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("CreateWellKnownSid Error for SYSTEM")
        );
        return ERROR_INSTALL_FAILURE;
    }

    // Create a SID for the Administrators group.
    dwSidSize = sizeof( rgSidBA );
    if(!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, rgSidBA, &dwSidSize))
    {
        LogMessage(
            INSTALLMESSAGE_ERROR,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("CreateWellKnownSid Error for BUILTIN\\Administrators")
        );
        return ERROR_INSTALL_FAILURE;
    }

    ulEntries = 2;

    // SYSTEM
    ea[0].grfAccessPermissions = GENERIC_ALL;
    ea[0].grfAccessMode = SET_ACCESS;
    ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[0].Trustee.ptstrName = (LPTSTR)rgSidSY;

    // Administrators
    ea[1].grfAccessPermissions = GENERIC_ALL;
    ea[1].grfAccessMode = SET_ACCESS;
    ea[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[1].Trustee.ptstrName = (LPTSTR)rgSidBA;

    // Create a new ACL that contains the new ACEs.
    dwRes = SetEntriesInAcl(ulEntries, &ea[0], NULL, &pACL);
    if (ERROR_SUCCESS != dwRes) 
    {
        LogMessage(
            INSTALLMESSAGE_INFO,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("SetEntriesInAcl Error")
        );
        LogMessage(
            INSTALLMESSAGE_ERROR,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("SetEntriesInAcl Error")
        );
        return ERROR_INSTALL_FAILURE;
    }

    // Set the ACL on the Data Directory itself.
    dwRes = SetNamedSecurityInfo( 
        (LPWSTR)strBOINCDataDirectory.c_str(),
        SE_FILE_OBJECT,
        DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
        NULL,
        NULL,
        pACL,
        NULL
    );
    if (ERROR_SUCCESS != dwRes) 
    {
        LogMessage(
            INSTALLMESSAGE_INFO,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("SetNamedSecurityInfo Error")
        );
        LogMessage(
            INSTALLMESSAGE_ERROR,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("SetNamedSecurityInfo Error")
        );
        return ERROR_INSTALL_FAILURE;
    }

    // Set ACLs on all files and sub folders.
    RecursiveSetPermissions(strBOINCDataDirectory, pACL);


    if (pACL) 
        LocalFree(pACL);

    return ERROR_SUCCESS;
}
예제 #22
0
bool CSecRunAsUser::SetObjectPermission(CString strDirFile, DWORD lGrantedAccess){
	if (!m_hADVAPI32_DLL){
		ASSERT ( false );
		return false;
	}
	if ( strDirFile.IsEmpty() )
		return true;

	SID_NAME_USE   snuType;
	TCHAR* szDomain = NULL;
	LPVOID pUserSID = NULL;
	PACL pNewACL = NULL;
	PSECURITY_DESCRIPTOR pSD = NULL;
	BOOL fAPISuccess;
	
	try {
		// get user sid
		DWORD cbDomain = 0;
		DWORD cbUserSID = 0;
		fAPISuccess = LookupAccountName(NULL, EMULEACCOUNTW, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType);
		if ( (!fAPISuccess) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
			throw CString(_T("Run as unpriveleged user: Error: LookupAccountName() failed,"));

		pUserSID = MHeapAlloc(cbUserSID);
		if (!pUserSID)
			throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,"));
		
		szDomain = (TCHAR*)MHeapAlloc(cbDomain * sizeof(TCHAR));
		if (!szDomain)
			throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,"));

		fAPISuccess = LookupAccountName(NULL, EMULEACCOUNTW, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType);

		if (!fAPISuccess)
			throw CString(_T("Run as unpriveleged user: Error: LookupAccountName()2 failed"));

		if (CStringW(szDomain) != m_strDomain)
			throw CString(_T("Run as unpriveleged user: Logical Error: Domainname mismatch"));

		// get old ACL
		PACL pOldACL = NULL;
		fAPISuccess = GetNamedSecurityInfo(strDirFile.GetBuffer(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldACL, NULL, &pSD);
		strDirFile.ReleaseBuffer();
		if (fAPISuccess != ERROR_SUCCESS){
			throw CString(_T("Run as unpriveleged user: Error: GetNamedSecurityInfo() failed"));
		}

		// calculate size for new ACL
		ACL_SIZE_INFORMATION AclInfo;
		AclInfo.AceCount = 0; // Assume NULL DACL.
		AclInfo.AclBytesFree = 0;
		AclInfo.AclBytesInUse = sizeof(ACL);

		if (pOldACL != NULL && !GetAclInformation(pOldACL, &AclInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation))  
			throw CString(_T("Run as unpriveleged user: Error: GetAclInformation() failed"));

		// Create new ACL
		DWORD cbNewACL = AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pUserSID) - sizeof(DWORD);

		pNewACL = (PACL)MHeapAlloc(cbNewACL);
		if (!pNewACL)
			throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,"));

		if (!InitializeAcl(pNewACL, cbNewACL, ACL_REVISION2))
			throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,"));


		// copy the entries form the old acl into the new one and enter a new ace in the right order
		uint32 newAceIndex = 0;
		uint32 CurrentAceIndex = 0;
		if (AclInfo.AceCount) {
			for (CurrentAceIndex = 0; CurrentAceIndex < AclInfo.AceCount; CurrentAceIndex++) {

					LPVOID pTempAce = NULL;
					if (!GetAce(pOldACL, CurrentAceIndex, &pTempAce))
						throw CString(_T("Run as unpriveleged user: Error: GetAce() failed,"));

					if (((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags
						& INHERITED_ACE)
						break;
					// no multiple entries
					if (EqualSid(pUserSID, &(((ACCESS_ALLOWED_ACE *)pTempAce)->SidStart)))
						continue;

					if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER) pTempAce)->AceSize))
						throw CString(_T("Run as unpriveleged user: Error: AddAce()1 failed,"));
					newAceIndex++;
			}
		}
		// here we add the actually entry
		if (!AddAccessAllowedAceEx(pNewACL, ACL_REVISION2, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, lGrantedAccess, pUserSID))
			throw CString(_T("Run as unpriveleged user: Error: AddAccessAllowedAceEx() failed,"));	
		
		// copy the rest
		if (AclInfo.AceCount) {
			for (; CurrentAceIndex < AclInfo.AceCount; CurrentAceIndex++) {

					LPVOID pTempAce = NULL;
					if (!GetAce(pOldACL, CurrentAceIndex, &pTempAce))
						throw CString(_T("Run as unpriveleged user: Error: GetAce()2 failed,"));

					if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER) pTempAce)->AceSize))
						throw CString(_T("Run as unpriveleged user: Error: AddAce()2 failed,"));
				}
		}

		fAPISuccess = SetNamedSecurityInfo(strDirFile.GetBuffer(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL);
		strDirFile.ReleaseBuffer();
		if (fAPISuccess != ERROR_SUCCESS)
			throw CString(_T("Run as unpriveleged user: Error: SetNamedSecurityInfo() failed,"));
		fAPISuccess = TRUE;
	}
	catch(CString error){
		fAPISuccess = FALSE;
		theApp.QueueDebugLogLine(false, error);
	}
	// clean up
	if (pUserSID != NULL)
		MHeapFree(pUserSID);
	if (szDomain != NULL)
		MHeapFree(szDomain);
	if (pNewACL != NULL)
		MHeapFree(pNewACL);
	if (pSD != NULL)
		LocalFree(pSD);

	// finished
	return fAPISuccess!=FALSE;
}
/////////////////////////////////////////////////////////////////////
// 
// Function:    
//
// Description: 
//
/////////////////////////////////////////////////////////////////////
UINT CASetPermissionBOINCDataProjects::OnExecution()
{
    DWORD               dwRes = 0;
    PACL                pACL = NULL;
    ULONGLONG           rgSidSY[(SECURITY_MAX_SID_SIZE+sizeof(ULONGLONG)-1)/sizeof(ULONGLONG)]={0};
    ULONGLONG           rgSidBA[(SECURITY_MAX_SID_SIZE+sizeof(ULONGLONG)-1)/sizeof(ULONGLONG)]={0};
    ULONGLONG           rgSidBU[(SECURITY_MAX_SID_SIZE+sizeof(ULONGLONG)-1)/sizeof(ULONGLONG)]={0};
    DWORD               dwSidSize;
    EXPLICIT_ACCESS     ea[6];
    ULONG               ulEntries = 0;
    tstring             strBOINCAdminsGroupAlias;
    tstring             strBOINCUsersGroupAlias;
    tstring             strBOINCProjectsGroupAlias;
    tstring             strBOINCDataDirectory;
    tstring             strBOINCDataProjectsDirectory;
    tstring             strEnableProtectedApplicationExecution;
    tstring             strEnableUseByAllUsers;
    UINT                uiReturnValue = -1;

    uiReturnValue = GetProperty( _T("BOINC_ADMINS_GROUPNAME"), strBOINCAdminsGroupAlias );
    if ( uiReturnValue ) return uiReturnValue;

    uiReturnValue = GetProperty( _T("BOINC_USERS_GROUPNAME"), strBOINCUsersGroupAlias );
    if ( uiReturnValue ) return uiReturnValue;

    uiReturnValue = GetProperty( _T("BOINC_PROJECTS_GROUPNAME"), strBOINCProjectsGroupAlias );
    if ( uiReturnValue ) return uiReturnValue;

    uiReturnValue = GetProperty( _T("DATADIR"), strBOINCDataDirectory );
    if ( uiReturnValue ) return uiReturnValue;

    uiReturnValue = GetProperty( _T("ENABLEPROTECTEDAPPLICATIONEXECUTION3"), strEnableProtectedApplicationExecution );
    if ( uiReturnValue ) return uiReturnValue;

    uiReturnValue = GetProperty( _T("ENABLEUSEBYALLUSERS"), strEnableUseByAllUsers );
    if ( uiReturnValue ) return uiReturnValue;


    // If we are not installing as a service, we do not need to modify the
    // projects directory permissions
    if (_T("1") != strEnableProtectedApplicationExecution) {
        return ERROR_SUCCESS;
    }


    strBOINCDataProjectsDirectory = strBOINCDataDirectory + _T("\\projects");


    // Initialize an EXPLICIT_ACCESS structure for all ACEs.
    ZeroMemory(&ea, 6 * sizeof(EXPLICIT_ACCESS));

    // Create a SID for the SYSTEM.
    dwSidSize = sizeof( rgSidSY );
    if(!CreateWellKnownSid(WinLocalSystemSid, NULL, rgSidSY, &dwSidSize))
    {
        LogMessage(
            INSTALLMESSAGE_ERROR,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("CreateWellKnownSid Error for SYSTEM")
        );
        return ERROR_INSTALL_FAILURE;
    }

    // Create a SID for the Administrators group.
    dwSidSize = sizeof( rgSidBA );
    if(!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, rgSidBA, &dwSidSize))
    {
        LogMessage(
            INSTALLMESSAGE_ERROR,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("CreateWellKnownSid Error for BUILTIN\\Administrators")
        );
        return ERROR_INSTALL_FAILURE;
    }

    // Create a SID for the Users group.
    dwSidSize = sizeof( rgSidBU );
    if(!CreateWellKnownSid(WinBuiltinUsersSid, NULL, rgSidBU, &dwSidSize))
    {
        LogMessage(
            INSTALLMESSAGE_ERROR,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("CreateWellKnownSid Error for BUILTIN\\Users")
        );
        return ERROR_INSTALL_FAILURE;
    }

    ulEntries = 5;

    // SYSTEM
    ea[0].grfAccessPermissions = GENERIC_ALL;
    ea[0].grfAccessMode = SET_ACCESS;
    ea[0].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[0].Trustee.ptstrName  = (LPTSTR)rgSidSY;

    // Administrators
    ea[1].grfAccessPermissions = GENERIC_ALL;
    ea[1].grfAccessMode = SET_ACCESS;
    ea[1].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[1].Trustee.ptstrName  = (LPTSTR)rgSidBA;

    // boinc_admins
    ea[2].grfAccessPermissions = GENERIC_ALL;
    ea[2].grfAccessMode = SET_ACCESS;
    ea[2].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea[2].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea[2].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    ea[2].Trustee.ptstrName  = (LPTSTR)strBOINCAdminsGroupAlias.c_str();

    // boinc_users
    ea[3].grfAccessPermissions = GENERIC_READ|GENERIC_EXECUTE;
    ea[3].grfAccessMode = SET_ACCESS;
    ea[3].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea[3].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea[3].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    ea[3].Trustee.ptstrName  = (LPTSTR)strBOINCUsersGroupAlias.c_str();

    // boinc_projects
    ea[4].grfAccessPermissions = GENERIC_ALL;
    ea[4].grfAccessMode = SET_ACCESS;
    ea[4].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea[4].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea[4].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    ea[4].Trustee.ptstrName  = (LPTSTR)strBOINCProjectsGroupAlias.c_str();

    // Users
    if (_T("1") == strEnableUseByAllUsers) {
        ulEntries = 6;

        ea[5].grfAccessPermissions = GENERIC_READ|GENERIC_EXECUTE;
        ea[5].grfAccessMode = SET_ACCESS;
        ea[5].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
        ea[5].Trustee.TrusteeForm = TRUSTEE_IS_SID;
        ea[5].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
        ea[5].Trustee.ptstrName  = (LPTSTR)rgSidBU;
    }

    // Create a new ACL that contains the new ACEs.
    dwRes = SetEntriesInAcl(ulEntries, &ea[0], NULL, &pACL);
    if (ERROR_SUCCESS != dwRes) 
    {
        LogMessage(
            INSTALLMESSAGE_INFO,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("SetEntriesInAcl Error")
        );
        LogMessage(
            INSTALLMESSAGE_ERROR,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("SetEntriesInAcl Error")
        );
        return ERROR_INSTALL_FAILURE;
    }

    // Set the ACL on the Data Directory itself.
    dwRes = SetNamedSecurityInfo( 
        (LPWSTR)strBOINCDataProjectsDirectory.c_str(),
        SE_FILE_OBJECT,
        DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
        NULL,
        NULL,
        pACL,
        NULL
    );
    if (ERROR_SUCCESS != dwRes) 
    {
        LogMessage(
            INSTALLMESSAGE_INFO,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("SetNamedSecurityInfo Error")
        );
        LogMessage(
            INSTALLMESSAGE_ERROR,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("SetNamedSecurityInfo Error")
        );
        return ERROR_INSTALL_FAILURE;
    }

    // Set ACLs on all files and sub folders.
    RecursiveSetPermissions(strBOINCDataProjectsDirectory, pACL);


    if (pACL) 
        LocalFree(pACL);

    return ERROR_SUCCESS;
}
예제 #24
0
BOOL CNTService::ModifyVistaDefaultAuditing(string dir, int remove)
{
	PSECURITY_DESCRIPTOR pSD = NULL;
	HANDLE hToken;
	PACL mySacl=NULL;
	DWORD ret=0;

	TOKEN_PRIVILEGES tp;
	LUID luid;

	if ( !LookupPrivilegeValue(NULL,SE_SECURITY_NAME,&luid)) {
		printf("LookupPrivilegeValue error: %u\n", GetLastError() ); 
		return FALSE; 
	}

	tp.PrivilegeCount = 1;
	tp.Privileges[0].Luid = luid;
	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

	// Enable the privilege or disable all privileges.
	OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
	if ( !AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL)) { 
		  printf("AdjustTokenPrivileges error: %u\n", GetLastError() ); 
		  return FALSE; 
	} 

	if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
		  printf("The token does not have the specified privilege. \n");
		  return FALSE;
	} 

	//recurse through the dir
	WIN32_FIND_DATA findData;
	char Match[32], Replace[32];
	if (remove){
		strncpy_s(Match,_countof(Match),"Everyone",_TRUNCATE);
		strncpy_s(Replace,_countof(Replace),"ANONYMOUS LOGON",_TRUNCATE);
	} else {
		strncpy_s(Match,_countof(Match),"ANONYMOUS LOGON",_TRUNCATE);
		strncpy_s(Replace,_countof(Replace),"Everyone",_TRUNCATE);
	}

	HANDLE hFind=FindFirstFile((dir+"\\*.*").c_str(), &findData);

	if (hFind == INVALID_HANDLE_VALUE) {
		return TRUE;
	}

	// iterate over file names in directory
	do {
		string sFileName(findData.cFileName);

		if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
			// Directory
			if (sFileName != "." && sFileName != "..") {
				// descent recursively
				if (!ModifyVistaDefaultAuditing(dir+"\\"+sFileName, remove)) return FALSE;
			}
		} else {
			// File
			// grab and modify the file SACL
			ret = GetNamedSecurityInfo((char *)(dir+"\\"+findData.cFileName).c_str(),SE_FILE_OBJECT,SACL_SECURITY_INFORMATION,NULL,NULL,NULL,&mySacl,&pSD);
			if (ret == ERROR_SUCCESS && mySacl != NULL && mySacl->AceCount > 0) {
				int SetNewAcl=0;
				PACL pNewAcl;
				ACL_SIZE_INFORMATION aclSizeInfo;
				ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
				aclSizeInfo.AclBytesInUse = sizeof(ACL);
				
				if (!GetAclInformation(mySacl,(LPVOID)&aclSizeInfo,sizeof(ACL_SIZE_INFORMATION),AclSizeInformation)) {
					printf("Can't find ACL info, exiting\n");
					return FALSE;
				}
				pNewAcl = (PACL)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,aclSizeInfo.AclBytesInUse);
				if (!pNewAcl) {
					printf("Can't allocate new ACL, exiting\n");
					return FALSE;
				}
				if (!InitializeAcl(pNewAcl,aclSizeInfo.AclBytesInUse,ACL_REVISION)) {
					printf("Can't allocate new ACL, exiting\n");
					return FALSE;
				}
				//printf("Checking: %s[%d]\n",(char *)(dir+"\\"+findData.cFileName).c_str(),mySacl->AceCount);
				for (int i=0; i< mySacl->AceCount; i++) {
					PVOID pAce;//PACE_HEADER?
					SID *pAceSid, *pNewAceSid=NULL;
					DWORD dwCbName = 0;
					DWORD dwCbDomainName = 0;
					SID_NAME_USE SidNameUse;
					TCHAR bufName[MAX_PATH]="";
					TCHAR bufDomain[MAX_PATH]="";
					ACCESS_MASK mask;
					SYSTEM_AUDIT_ACE *SA_Ace;
					TCHAR bufNewDomain[MAX_PATH];
					DWORD dwNewCbDomainName = 0;
					DWORD dwSidSize = 0;
					dwNewCbDomainName = _countof(bufNewDomain);
					BOOL bSuccess;
					
					if (GetAce(mySacl,i,&pAce)) {
						if (((ACE_HEADER *)pAce)->AceType != SYSTEM_AUDIT_ACE_TYPE) {
							printf("ACE ERROR: not SYSTEM_AUDIT_ACE_TYPE\n");
							continue;
						}
						SA_Ace = (SYSTEM_AUDIT_ACE *)pAce;
						pAceSid = (SID *)(&SA_Ace->SidStart);
						mask = SA_Ace->Mask;
						dwCbName = _countof(bufName);
						dwCbDomainName = _countof(bufDomain);

						bSuccess = LookupAccountSid(NULL, pAceSid, bufName, &dwCbName, bufDomain, &dwCbDomainName, &SidNameUse);
						if (!bSuccess) {
							printf("Failed to grab SID [%d]", GetLastError());
							return FALSE;
						}
						//printf("ACE of %s\\%s: %d\n", bufDomain, bufName, mask);
						if (!strcmp(bufName,Match)) {
							bSuccess = LookupAccountName(NULL, Replace, NULL, &dwSidSize, bufNewDomain, &dwNewCbDomainName,&SidNameUse);
							if (!bSuccess && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
								pNewAceSid = (SID *)malloc(dwSidSize);
								if (!pNewAceSid) {
									printf("memory failed\n");
									if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
									return FALSE;
								}
								bSuccess = LookupAccountName(NULL, Replace, pNewAceSid, &dwSidSize, bufNewDomain, &dwNewCbDomainName,&SidNameUse);
								if (bSuccess) {
									if (!AddAuditAccessAce(pNewAcl,ACL_REVISION,mask,pNewAceSid,TRUE,TRUE)) {
										printf("Failed to updated ACL[%d]\n",GetLastError());
										free(pNewAceSid);
										if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
										return FALSE;
									}
									SetNewAcl=1;
								} else {
									printf("FAILED: %d\n", GetLastError());
									//printf("\n");
								}
								free(pNewAceSid);
							} else {
								printf("FAILED to find %s\n",Replace);
							}
						} else {
							if (!AddAce(pNewAcl,ACL_REVISION,MAXDWORD,pAce,((PACE_HEADER)pAce)->AceSize)) {
								printf("Couldn't add ACE to acl [%d]\n",GetLastError());
								if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
								return FALSE;
							}
						}
					} else {
						printf("ACE error %d:%d[%d]\n",mySacl->AceCount,i,GetLastError());
						return FALSE;
					}
				}
				if (SetNewAcl && pNewAcl) {
					ret = SetNamedSecurityInfo((char *)(dir+"\\"+findData.cFileName).c_str(),SE_FILE_OBJECT,SACL_SECURITY_INFORMATION,NULL,NULL,NULL,pNewAcl);
					if (ret == ERROR_SUCCESS) {
						printf("Fixed: %s\n",(char *)(dir+"\\"+findData.cFileName).c_str());
					} else {
						printf("Failed to fix: %s\n",(char *)(dir+"\\"+findData.cFileName).c_str());
					}
				}
				if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
			} else {
				if (ret) printf("fail %d %s\n", ret,(char *)(dir+"\\"+findData.cFileName).c_str());
				//else printf("NO SACL: %s\n",(char *)(dir+"\\"+findData.cFileName).c_str());
			}
			if (pSD) LocalFree(pSD);
		}
	} while (FindNextFile(hFind, &findData));
	return TRUE;
}
예제 #25
0
// allow different users to read\write\delete files in lock directory
// in case of any error just log it and don't stop engine execution
void adjustLockDirectoryAccess(const char* pathname)
{
	PSECURITY_DESCRIPTOR pSecDesc = NULL;
	PSID pSID_Users = NULL;
	PSID pSID_Administrators = NULL;
	PACL pNewACL = NULL;
	try
	{
		// We should pass root directory in format "C:\" into GetVolumeInformation().
		// In case of pathname is not local folder (i.e. \\share\folder) let
		// GetVolumeInformation() return an error.
		Firebird::PathName root(pathname);
		const Firebird::PathName::size_type pos = root.find(':', 0);
		if (pos == 1)
		{
			root.erase(pos + 1, root.length());
			PathUtils::ensureSeparator(root);
		}

		DWORD fsflags;
		if (!GetVolumeInformation(root.c_str(), NULL, 0, NULL, NULL, &fsflags, NULL, 0))
			Firebird::system_error::raise("GetVolumeInformation");

		if (!(fsflags & FS_PERSISTENT_ACLS))
			return;

		// Adjust security for our new folder : allow BUILTIN\Users group to
		// read\write\delete files
		PACL pOldACL = NULL;

		if (GetNamedSecurityInfo((LPSTR) pathname,
				SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
				NULL, NULL, &pOldACL, NULL,
				&pSecDesc) != ERROR_SUCCESS)
		{
			Firebird::system_error::raise("GetNamedSecurityInfo");
		}

		SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY;
		if (!AllocateAndInitializeSid(&sidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
			DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &pSID_Users))
		{
			Firebird::system_error::raise("AllocateAndInitializeSid");
		}

		if (!AllocateAndInitializeSid(&sidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
			DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSID_Administrators))
		{
			Firebird::system_error::raise("AllocateAndInitializeSid");
		}

		EXPLICIT_ACCESS eas[2];
		memset(eas, 0, sizeof(eas));

		eas[0].grfAccessPermissions = FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE;
		eas[0].grfAccessMode = GRANT_ACCESS;
		eas[0].grfInheritance = SUB_OBJECTS_ONLY_INHERIT;
		eas[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
		eas[0].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
		eas[0].Trustee.ptstrName  = (LPSTR) pSID_Users;

		eas[1].grfAccessPermissions = FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE;
		eas[1].grfAccessMode = GRANT_ACCESS;
		eas[1].grfInheritance = SUB_OBJECTS_ONLY_INHERIT;
		eas[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
		eas[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
		eas[1].Trustee.ptstrName  = (LPSTR) pSID_Administrators;

		if (SetEntriesInAcl(2, eas, pOldACL, &pNewACL) != ERROR_SUCCESS)
			Firebird::system_error::raise("SetEntriesInAcl");

		if (SetNamedSecurityInfo((LPSTR) pathname,
				SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
				NULL, NULL, pNewACL, NULL) != ERROR_SUCCESS)
		{
			Firebird::system_error::raise("SetNamedSecurityInfo");
		}
	}
	catch (const Firebird::Exception& ex)
	{
		Firebird::string str;
		str.printf("Error adjusting access rights for folder \"%s\" :", pathname);

		iscLogException(str.c_str(), ex);
	}

	if (pSID_Users) {
		FreeSid(pSID_Users);
	}
	if (pSID_Administrators) {
		FreeSid(pSID_Administrators);
	}
	if (pNewACL) {
		LocalFree(pNewACL);
	}
	if (pSecDesc) {
		LocalFree(pSecDesc);
	}
}
/////////////////////////////////////////////////////////////////////
// 
// Function:    
//
// Description: 
//
/////////////////////////////////////////////////////////////////////
UINT CASetPermissionBOINCDataProjects::OnExecution()
{
    DWORD               dwRes = 0;
    PACL                pACL = NULL;
    PSID                psidAdministrators = NULL;
    PSID                psidEveryone = NULL;
    EXPLICIT_ACCESS     ea[5];
    ULONG               ulEntries = 4;
    tstring             strBOINCAdminsGroupAlias;
    tstring             strBOINCUsersGroupAlias;
    tstring             strBOINCProjectsGroupAlias;
    tstring             strBOINCDataDirectory;
    tstring             strBOINCDataProjectsDirectory;
    tstring             strEnableUseByAllUsers;
    UINT                uiReturnValue = -1;

    SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;

    uiReturnValue = GetProperty( _T("BOINC_ADMINS_GROUPNAME"), strBOINCAdminsGroupAlias );
    if ( uiReturnValue ) return uiReturnValue;

    uiReturnValue = GetProperty( _T("BOINC_USERS_GROUPNAME"), strBOINCUsersGroupAlias );
    if ( uiReturnValue ) return uiReturnValue;

    uiReturnValue = GetProperty( _T("BOINC_PROJECTS_GROUPNAME"), strBOINCProjectsGroupAlias );
    if ( uiReturnValue ) return uiReturnValue;

    uiReturnValue = GetProperty( _T("DATADIR"), strBOINCDataDirectory );
    if ( uiReturnValue ) return uiReturnValue;

    uiReturnValue = GetProperty( _T("ENABLEUSEBYALLUSERS"), strEnableUseByAllUsers );
    if ( uiReturnValue ) return uiReturnValue;


    strBOINCDataProjectsDirectory = strBOINCDataDirectory + _T("\\projects");


    // Initialize an EXPLICIT_ACCESS structure for all ACEs.
    ZeroMemory(&ea, 5 * sizeof(EXPLICIT_ACCESS));

    // Administrators
    if(!AllocateAndInitializeSid(
        &SIDAuthNT,
        2,
        SECURITY_BUILTIN_DOMAIN_RID,
        DOMAIN_ALIAS_RID_ADMINS,
        0, 0, 0, 0, 0, 0,
        &psidAdministrators))
    {
        LogMessage(
            INSTALLMESSAGE_INFO,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("AllocateAndInitializeSid Error for Administrators group")
        );
        LogMessage(
            INSTALLMESSAGE_ERROR,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("AllocateAndInitializeSid Error for Administrators group")
        );
    }

    ea[0].grfAccessPermissions = GENERIC_ALL;
    ea[0].grfAccessMode = SET_ACCESS;
    ea[0].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    ea[0].Trustee.ptstrName  = (LPTSTR)psidAdministrators;

    // boinc_admins
    ea[1].grfAccessPermissions = GENERIC_ALL;
    ea[1].grfAccessMode = SET_ACCESS;
    ea[1].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    ea[1].Trustee.ptstrName  = (LPTSTR)strBOINCAdminsGroupAlias.c_str();

    // boinc_users
    ea[2].grfAccessPermissions = GENERIC_READ|GENERIC_EXECUTE;
    ea[2].grfAccessMode = SET_ACCESS;
    ea[2].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea[2].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea[2].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    ea[2].Trustee.ptstrName  = (LPTSTR)strBOINCUsersGroupAlias.c_str();

    // boinc_projects
    ea[3].grfAccessPermissions = GENERIC_ALL;
    ea[3].grfAccessMode = SET_ACCESS;
    ea[3].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
    ea[3].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea[3].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    ea[3].Trustee.ptstrName  = (LPTSTR)strBOINCProjectsGroupAlias.c_str();

    // Everyone
    if (_T("1") == strEnableUseByAllUsers) {

        // Create a well-known SID for the Everyone group.
        if(!AllocateAndInitializeSid(
                         &SIDAuthWorld, 1,
                         SECURITY_WORLD_RID,
                         0, 0, 0, 0, 0, 0, 0,
                         &psidEveryone
          ))
        {
            LogMessage(
                INSTALLMESSAGE_INFO,
                NULL, 
                NULL,
                NULL,
                GetLastError(),
                _T("AllocateAndInitializeSid Error for Everyone group")
            );
            LogMessage(
                INSTALLMESSAGE_ERROR,
                NULL, 
                NULL,
                NULL,
                GetLastError(),
                _T("AllocateAndInitializeSid Error for Everyone group")
            );
        }

        ulEntries = 5;

        ea[4].grfAccessPermissions = GENERIC_READ|GENERIC_EXECUTE;
        ea[4].grfAccessMode = SET_ACCESS;
        ea[4].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
        ea[4].Trustee.TrusteeForm = TRUSTEE_IS_SID;
        ea[4].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
        ea[4].Trustee.ptstrName  = (LPTSTR)psidEveryone;
    }


    // Create a new ACL that contains the new ACEs.
    dwRes = SetEntriesInAcl(ulEntries, &ea[0], NULL, &pACL);
    if (ERROR_SUCCESS != dwRes) 
    {
        LogMessage(
            INSTALLMESSAGE_INFO,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("SetEntriesInAcl Error")
        );
        LogMessage(
            INSTALLMESSAGE_ERROR,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("SetEntriesInAcl Error")
        );
        return ERROR_INSTALL_FAILURE;
    }

    // Set the ACL on the Data Directory itself.
    dwRes = SetNamedSecurityInfo( 
        (LPWSTR)strBOINCDataProjectsDirectory.c_str(),
        SE_FILE_OBJECT,
        DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
        NULL,
        NULL,
        pACL,
        NULL
    );
    if (ERROR_SUCCESS != dwRes) 
    {
        LogMessage(
            INSTALLMESSAGE_INFO,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("SetNamedSecurityInfo Error")
        );
        LogMessage(
            INSTALLMESSAGE_ERROR,
            NULL, 
            NULL,
            NULL,
            GetLastError(),
            _T("SetNamedSecurityInfo Error")
        );
        return ERROR_INSTALL_FAILURE;
    }

    // Set ACLs on all files and sub folders.
    RecursiveSetPermissions(strBOINCDataProjectsDirectory, pACL);


    if (pACL) 
        LocalFree(pACL);
    if (psidAdministrators)
        FreeSid(psidAdministrators);
    if (psidEveryone)
        FreeSid(psidEveryone);

    return ERROR_SUCCESS;
}
예제 #27
0
bool CFileControlTool::DisableWFP(LPTSTR pszFileName)
{
	bool bRetval = FALSE;
	OSVERSIONINFO osviVersionInfo;

	ZeroMemory(&osviVersionInfo, sizeof(OSVERSIONINFO));
	osviVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&osviVersionInfo);
	if (osviVersionInfo.dwMajorVersion == 5 && osviVersionInfo.dwMinorVersion == 1)
	{
		typedef DWORD(__stdcall *CPP) (DWORD param1, PWCHAR param2, DWORD param3);

		HINSTANCE hMod = LoadLibrary(_T("sfc_os.dll"));
		if(!hMod)return FALSE;

		CPP SetSfcFileException = (CPP)GetProcAddress(hMod, (LPCSTR)5);

		bRetval = SetSfcFileException(0,(wchar_t *)t2ws(pszFileName).c_str(), -1);

	}else if (osviVersionInfo.dwMajorVersion == 6 && osviVersionInfo.dwMinorVersion == 1)
	{	
		PSID pSIDAdmin = NULL;
		PSID pSIDEveryone = NULL;
		PACL pACL = NULL;

		do 
		{
			SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
			SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
			const int NUM_ACES  = 2;
			EXPLICIT_ACCESS ea[NUM_ACES];
			DWORD dwRes;
			// Specify the DACL to use.
			// Create a SID for the Everyone group.
			if (!AllocateAndInitializeSid(&SIDAuthWorld, 1,SECURITY_WORLD_RID,0,0, 0, 0, 0, 0, 0,&pSIDEveryone)) 
			{
				//printf("AllocateAndInitializeSid (Everyone) error %u\n",GetLastError());
				break;
			}
			// Create a SID for the BUILTIN\Administrators group.
			if (!AllocateAndInitializeSid(&SIDAuthNT, 2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0, 0, 0, 0, 0, 0,&pSIDAdmin)) 
			{
				//printf("AllocateAndInitializeSid (Admin) error %u\n",GetLastError());
				break;
			}
			ZeroMemory(&ea, NUM_ACES * sizeof(EXPLICIT_ACCESS));
			// Set read access for Everyone.
			ea[0].grfAccessPermissions = GENERIC_READ;
			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) pSIDEveryone;
			// Set full control for Administrators.
			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_GROUP;
			ea[1].Trustee.ptstrName = (LPTSTR) pSIDAdmin;
			if (ERROR_SUCCESS != SetEntriesInAcl(NUM_ACES,ea,NULL,&pACL))
			{
				//printf("Failed SetEntriesInAcl\n");
				break;
			}
			// Try to modify the object's DACL.
			dwRes = SetNamedSecurityInfo(pszFileName,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,NULL, NULL,pACL,NULL);
			if (ERROR_SUCCESS == dwRes) 
			{
				//printf("Successfully changed DACL\n");
				bRetval = TRUE;// No more processing needed.
				break;
			}
			if (dwRes != ERROR_ACCESS_DENIED)
			{
				//printf("First SetNamedSecurityInfo call failed: %u\n",dwRes); 
				break;
			}
			// If the preceding call failed because access was denied, 
			// enable the SE_TAKE_OWNERSHIP_NAME privilege, create a SID for 
			// the Administrators group, take ownership of the object, and 
			// disable the privilege. Then try again to set the object's DACL.
			// Open a handle to the access token for the calling process.
			// Enable the SE_TAKE_OWNERSHIP_NAME privilege.
			if (!OperatePrivilege4Process(SE_TAKE_OWNERSHIP_NAME, TRUE)) 
			{
				//printf("You must be logged on as Administrator.\n");
				break;
			}
			// Set the owner in the object's security descriptor.
			dwRes = SetNamedSecurityInfo(pszFileName,SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION,pSIDAdmin,NULL,NULL,NULL);
			if (dwRes != ERROR_SUCCESS) 
			{
				//printf("Could not set owner. Error: %u\n", dwRes); 
				break;
			}

			// Disable the SE_TAKE_OWNERSHIP_NAME privilege.
			if (!OperatePrivilege4Process(SE_TAKE_OWNERSHIP_NAME, FALSE)) 
			{
				//printf("Failed SetPrivilege call unexpectedly.\n");
				break;
			}
			// Try again to modify the object's DACL,
			// now that we are the owner.
			dwRes = SetNamedSecurityInfo(pszFileName,SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,NULL, NULL,pACL,NULL);                       // do not change SACL
			if (dwRes == ERROR_SUCCESS)
			{
				//printf("Successfully changed DACL\n");
				bRetval = TRUE; 
			}
			else
			{
				//printf("Second SetNamedSecurityInfo call failed: %u\n",dwRes); 
			}
		} while (FALSE);

		if (pSIDAdmin)
			FreeSid(pSIDAdmin);
		if (pSIDEveryone)
			FreeSid(pSIDEveryone);
		if (pACL)
			LocalFree(pACL);
	}

	return bRetval;
}
예제 #28
0
USHORT SERVICES_grant_access_rights(const char* service_name, const TEXT* account, pfnSvcError err_handler)
{
/*********************************************************
 *
 * S E R V I C E S _ g r a n t _ a c c e s s _ r i g h t s
 *
 *********************************************************
 *
 * Functional description
 *
 * Grant access rights to service 'service_name' so that user 'account'
 * can control it (start, stop, query).
 * Intended to be called after SERVICES_install().
 * By doing so to the Firebird server service object, we can set the Guardian
 * to run as the same specific user, yet still be able to start the Firebird
 * server from the Guardian.
 * 'account' is of format : DOMAIN\User or SERVER\User.
 * Returns FB_SUCCESS or FB_FAILURE.
 *
 * OM - SEP 2003 - Initial implementation
 *
 *********************************************************/

	PACL pOldDACL = NULL;
	PSECURITY_DESCRIPTOR pSD = NULL;

	// Get Security Information on the service. Will of course fail if we're
	// not allowed to do this. Administrators should be allowed, by default.
	// CVC: Only GetNamedSecurityInfoEx has the first param declared const, so we need
	// to make the compiler happy after Blas' cleanup.
	if (GetNamedSecurityInfo(const_cast<CHAR*>(service_name), SE_SERVICE, DACL_SECURITY_INFORMATION,
		NULL /*Owner Sid*/, NULL /*Group Sid*/,
		&pOldDACL, NULL /*Sacl*/, &pSD) != ERROR_SUCCESS)
	{
		return (*err_handler)(GetLastError(), "GetNamedSecurityInfo", NULL);
	}

	// Initialize an EXPLICIT_ACCESS structure.
	EXPLICIT_ACCESS ea;
	ZeroMemory(&ea, sizeof(ea));
	ea.grfAccessPermissions = GENERIC_READ | GENERIC_EXECUTE;
	ea.grfAccessMode = SET_ACCESS;
	ea.grfInheritance = NO_INHERITANCE;
	ea.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
	ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
	ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
	ea.Trustee.ptstrName = const_cast<char*>(account); // safe

	// Create a new DACL, adding this right to whatever exists.
	PACL pNewDACL = NULL;
	if (SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL) != ERROR_SUCCESS)
	{
		DWORD err = GetLastError();
		LocalFree(pSD);
		return (*err_handler)(err, "SetEntriesInAcl", NULL);
	}

	// Updates the new rights in the object
	if (SetNamedSecurityInfo(const_cast<CHAR*>(service_name), SE_SERVICE, DACL_SECURITY_INFORMATION,
		NULL /*Owner Sid*/, NULL /*Group Sid*/,
		pNewDACL, NULL /*Sacl*/) != ERROR_SUCCESS)
	{
		DWORD err = GetLastError();
		LocalFree(pSD);
		LocalFree(pNewDACL);
		return (*err_handler)(err, "SetNamedSecurityInfo", NULL);
	}

	return FB_SUCCESS;
}
예제 #29
0
// sets the owner of the file. Unfortunately, this 
// function will fail if you're not running with 
// Administrator priviledges. Also, this function
// can set the owner on a local or remote file or 
// directory on a NTFS file system, Windows NT network 
// sharename, registry key, semaphore, event, mutex, 
// file mapping, or waitable timer. Phew!
bool perm::set_owner( const char *location ) {
	PSID owner_SID;
	DWORD size=0, d_size=0;
	SID_NAME_USE usage;
	char qualified_name[1024];

	domainBufferSize = COUNTOF(domainBuffer);
	sidBufferSize = COUNTOF(sidBuffer);

	owner_SID = (PSID)sidBuffer;

	if ( Domain_name ) {

		if ( 0 > _snprintf(qualified_name, 1023, "%s\\%s",
		   	Domain_name, Account_name) ) {
		
			dprintf(D_ALWAYS, "Perm: domain\\account (%s\\%s) "
				"string too long!\n", Domain_name, Account_name );
			return false;
		}
	} else {
		strncpy(qualified_name, Account_name, 1023);
	}

	if ( !LookupAccountName( NULL,			// System
		qualified_name,						// Account name
		owner_SID, &sidBufferSize,			// Sid
		domainBuffer, &domainBufferSize,	// Domain
		&usage) ) {							// SID TYPE
		dprintf(D_ALWAYS, "perm: LookupAccountName(%s, size) failed "
				"(err=%d)\n", qualified_name, GetLastError());
		return false;
	}

	DWORD err = SetNamedSecurityInfo((char*)location,
		SE_FILE_OBJECT,
		OWNER_SECURITY_INFORMATION,
		owner_SID,
		NULL,
		NULL,
		NULL);

	if ( err == ERROR_ACCESS_DENIED ) {

		// We have to enable the SE_TAKE_OWNERSHIP_NAME priv
		// for our access token. So do that, and try 
		// SetNamedSecurityInfo() again.

		HANDLE hToken = NULL;

		if (!OpenProcessToken(GetCurrentProcess(), 
			TOKEN_ADJUST_PRIVILEGES, &hToken)) 
       {
          dprintf(D_ALWAYS, "perm: OpenProcessToken failed: %u\n",
				  GetLastError()); 
       } else {

	    	// Enable the SE_TAKE_OWNERSHIP_NAME privilege.
    		if (!SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, TRUE)) {
	   			dprintf(D_ALWAYS, "perm: lacking Administrator privs "
					   "to set owner.\n");
    		} else { 
				err = SetNamedSecurityInfo((char*)location,
				SE_FILE_OBJECT,
				OWNER_SECURITY_INFORMATION,
				owner_SID,
				NULL,
				NULL,
				NULL);
			}
			CloseHandle(hToken);
		}
	}

	if ( err != ERROR_SUCCESS ) {
		dprintf(D_ALWAYS, "perm: SetNamedSecurityInfo(%s) failed (err=%d)\n",
				location, err);
		return false; 
	}

	dprintf(D_FULLDEBUG, "perm: successfully set owner on %s to %s\n",
		   	location, qualified_name);
	return true;
}
예제 #30
-1
HRESULT CSecurityInformation::SetSecurity(
			SECURITY_INFORMATION SecurityInformation,
			PSECURITY_DESCRIPTOR pSecurityDescriptor)
{
	HRESULT hr = 1;

	// Get the Dacl
	PACL pDACL = NULL;
	BOOL fPresent, fDefaulted;
	GetSecurityDescriptorDacl(pSecurityDescriptor, &fPresent, &pDACL, &fDefaulted);

	// Get the SACL
	PACL pSACL = NULL;
	GetSecurityDescriptorSacl(pSecurityDescriptor, &fPresent, &pSACL, &fDefaulted);

	// Get the owner
	PSID psidOwner = NULL;
	GetSecurityDescriptorOwner(pSecurityDescriptor, &psidOwner, &fDefaulted);

	// Get the group
	PSID psidGroup = NULL;
	GetSecurityDescriptorOwner(pSecurityDescriptor, &psidGroup, &fDefaulted);

	// Find out if DACL and SACL inherit from parent objects
	SECURITY_DESCRIPTOR_CONTROL sdCtrl = NULL;
	ULONG ulRevision;
	GetSecurityDescriptorControl(pSecurityDescriptor, &sdCtrl, &ulRevision);

	if ((sdCtrl & SE_DACL_PROTECTED) != SE_DACL_PROTECTED)
		SecurityInformation  |= UNPROTECTED_DACL_SECURITY_INFORMATION;
	else
		SecurityInformation  |= PROTECTED_DACL_SECURITY_INFORMATION;

	if ((sdCtrl & SE_SACL_PROTECTED) != SE_SACL_PROTECTED)
		SecurityInformation  |= UNPROTECTED_SACL_SECURITY_INFORMATION;
	else
		SecurityInformation  |= PROTECTED_SACL_SECURITY_INFORMATION;

	// Set the security
	ULONG lErr;
	if (m_Info.m_szName[0] != 0) // Is it named
	{
		lErr = SetNamedSecurityInfo(m_Info.m_szName, 
					m_Type.m_objSecurType, SecurityInformation, psidOwner, 
					psidGroup, pDACL, pSACL);
	}
	else
	{
		// Is it a handle case
		lErr = SetSecurityInfo(m_Info.m_hHandle, m_Type.m_objSecurType,
					SecurityInformation, psidOwner, psidGroup, pDACL, pSACL);
	}

	// Report error
	if (lErr != ERROR_SUCCESS)
	{
		MessageBox(NULL,
			TEXT("An error occurred saving security information for this object,\n")
			TEXT("possibly due to insufficient access rights.\n"),
			TEXT("Security Notice"), MB_OK);
	}
	else
	{
		hr = S_OK;
	}

	return(hr);
}