Beispiel #1
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;
}
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);
}
Beispiel #3
0
STDMETHODIMP
CObjSecurity::GetSecurity(SECURITY_INFORMATION si,
                           PSECURITY_DESCRIPTOR *ppSD,
                           BOOL fDefault)
{
    DWORD dwLength = 0;
    DWORD dwErr = 0;

    *ppSD = NULL;

    if (fDefault)
        return E_NOTIMPL;

#ifdef _DEBUG
	TCHAR szDbgInfo[128];
	wsprintf(szDbgInfo, _T("CObjSecurity::GetSecurity(0x%08X,%i)\n"), si, fDefault);
	OutputDebugString(szDbgInfo);
#endif

	if (mpsz_KeyForInherit)
	{
		dwErr = GetNamedSecurityInfo(mpsz_KeyForInherit, SE_REGISTRY_KEY,
			si, NULL, NULL, NULL, NULL, ppSD);
	}
	else
	{
		// Просто отдадим копию
		dwLength = GetSecurityDescriptorLength(m_pOrigSD);
		if (dwLength)
		{
			*ppSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, dwLength);
			if (*ppSD)
				memmove(*ppSD, m_pOrigSD, dwLength);
		}
	}

    ////
    //// Assume that required privileges have already been enabled
    ////
    //GetPrivateObjectSecurity(*m_ppSD, si, NULL, 0, &dwLength);
    //if (dwLength)
    //{
    //    *ppSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, dwLength);
    //    if (*ppSD &&
    //        !GetPrivateObjectSecurity(*m_ppSD, si, *ppSD, dwLength, &dwLength))
    //    {
    //        dwErr = GetLastError();
    //        LocalFree(*ppSD);
    //        *ppSD = NULL;
    //    }
    //}
    //else
    //    dwErr = GetLastError();


    return HRESULT_FROM_WIN32(dwErr);
}
static PyObject *get_perms(PyObject *self, PyObject *args)
{

	PyObject *py_perms = PyDict_New();
	//get file or directory name
    char *file;

    if (!PyArg_ParseTuple(args, "s", &file))
        return NULL;

	//setup security code
	PSECURITY_DESCRIPTOR pSD;
	PACL pDACL; 
    //GetNamedSecurityInfo() will give you the DACL when you ask for
    //DACL_SECURITY_INFORMATION. At this point, you have SIDs in the ACEs contained in the DACL. 
	ULONG result = GetNamedSecurityInfo(file,SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, 
	&pDACL, NULL, &pSD);

	if (result != ERROR_SUCCESS){ return NULL;}
	if (result == ERROR_SUCCESS){
		ACL_SIZE_INFORMATION aclSize = {0};
		if(pDACL != NULL){   
			if(!GetAclInformation(pDACL, &aclSize, sizeof(aclSize),
				AclSizeInformation)){
				return NULL;
			}
		}
	
		file_perms *fp = new file_perms[aclSize.AceCount];
		acl_info(pDACL, aclSize.AceCount, fp );
		
		//Dict
		for (ULONG i=0;i




//Boilerplate functions

//3 parts 
//name of python function
//C++ function
//flags METH_VARARGS means function takes variable number of args
static PyMethodDef fileperm_methods[] = {
	{ "get_perms", get_perms, METH_VARARGS },
	{ NULL }
};



void initfileperm()
{

Py_InitModule("fileperm",fileperm_methods);

}
BOOL CSecurityInformation::EditSecurity( HWND hwnd )
{
	TRACE( _T("Enter CSecurityInformation::EditSecurity (0x%IX)...\n"), this );
	BOOL bRes = TRUE;
	if( this == NULL )
	{
		bRes = FALSE;
	}

	ULONG lErr = 0;
	PSECURITY_DESCRIPTOR pSD = NULL;
	SECURITY_INFORMATION RequestedInformation = DACL_SECURITY_INFORMATION;

	// Get security information

	if( bRes )
	{
		if (m_Info.m_szName[0] != 0) // Is it named
		{
			lErr = GetNamedSecurityInfo(m_Info.m_szName, 
						m_Type.m_objSecurType, RequestedInformation, NULL, NULL, 
						NULL, NULL, &pSD);
		}
		else // Is it a handle case
		{
			lErr = GetSecurityInfo(m_Info.m_hHandle, m_Type.m_objSecurType,
						RequestedInformation, NULL, NULL, NULL, NULL, &pSD);
		}

		// No matter what we still display security information
		if (lErr != ERROR_SUCCESS)
		{
			// Failure produces an empty SD
//#pragma message (WARNING "Lots of hardcoded strings!")
			MessageBox(NULL,
				TEXT("An error occurred retrieving security information for this object,\n")
				TEXT("possibly due to insufficient access rights.\n"),
				TEXT("Security Notice"), MB_OK);
			bRes = FALSE;
		}
		else
		{
			LocalFree(pSD);
		}
	}

	if( bRes )
	{
		bRes = ::EditSecurity( hwnd, this );
	}

	TRACE( _T("Leave CSecurityInformation::EditSecurity (0x%IX) (ret = %d)...\n"), this, bRes );
	return bRes != FALSE;
}
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;
}
bool IsWriteableByCurrentUser(const LPWSTR path)
{
	bool isWriteable = false;
	DWORD result;
	SECURITY_INFORMATION secInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
	PSECURITY_DESCRIPTOR secDesc;
	PSID owner;
	result = GetNamedSecurityInfo(path, SE_FILE_OBJECT, secInfo,
		&owner, NULL, NULL, NULL, &secDesc);
	if (result == ERROR_SUCCESS)
	{
		HANDLE hToken;
		DWORD dwAccessDesired = GENERIC_WRITE;
		PRIVILEGE_SET PrivilegeSet;
		DWORD dwPrivSetSize = sizeof(PRIVILEGE_SET);
		DWORD dwAccessAllowed;
		BOOL fAccessGranted = FALSE;

		GENERIC_MAPPING mapping = { 0xFFFFFFFF };
		mapping.GenericRead = FILE_GENERIC_READ;
		mapping.GenericWrite = FILE_GENERIC_WRITE;
		mapping.GenericExecute = FILE_GENERIC_EXECUTE;
		mapping.GenericAll = FILE_ALL_ACCESS;

		::MapGenericMask(&dwAccessDesired, &mapping);

		if (::OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
		{
			HANDLE hImpersonatedToken = NULL;
			if (::DuplicateToken(hToken, SecurityImpersonation, &hImpersonatedToken)) {
				if (AccessCheck(secDesc, hImpersonatedToken, dwAccessDesired, &mapping,
					&PrivilegeSet, &dwPrivSetSize, &dwAccessAllowed, &fAccessGranted))
				{
					isWriteable = (dwAccessAllowed & FILE_GENERIC_WRITE) != 0;
				}
				::CloseHandle(hImpersonatedToken);
			}
			::CloseHandle(hToken);
		}
		::LocalFree(secDesc);
	}

	return isWriteable;
}
Beispiel #8
0
bool CWinSecurity::GetObjectOwner(const string&  obj_name,
                                  SE_OBJECT_TYPE obj_type,
                                  string* owner, string* group,
                                  unsigned int* uid, unsigned int* gid)
{
    PSID sid_owner;
    PSID sid_group;
    PSECURITY_DESCRIPTOR sd;

    DWORD res = GetNamedSecurityInfo(_T_XCSTRING(obj_name), obj_type,
                                     ACCOUNT_SECURITY_INFO,
                                     &sid_owner, &sid_group, NULL, NULL, &sd );
    if ( res != ERROR_SUCCESS ) {
        CNcbiError::SetWindowsError(res);
        return false;
    }
    bool retval = s_GetOwnerGroupFromSIDs(sid_owner, sid_group, owner, group, uid, gid);
    LocalFree(sd);
    return retval;
}
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);
}
HRESULT CSecurityInformation::GetSecurity(
			SECURITY_INFORMATION RequestedInformation, 
			PSECURITY_DESCRIPTOR* ppSecurityDescriptor, BOOL fDefault)
{
	ARG_USED( fDefault );

	HRESULT hr = 1;
	PSECURITY_DESCRIPTOR pSD = NULL;

	// Get security information
	ULONG lErr;
	if (m_Info.m_szName[0] != 0) // Is it named
	{
		lErr = GetNamedSecurityInfo(m_Info.m_szName, 
					m_Type.m_objSecurType, RequestedInformation, NULL, NULL, 
					NULL, NULL, &pSD);
	}
	else // Is it a handle case
	{
		lErr = GetSecurityInfo(m_Info.m_hHandle, m_Type.m_objSecurType,
					RequestedInformation, NULL, NULL, NULL, NULL, &pSD);
	}

	// No matter what we still display security information
	if (lErr != ERROR_SUCCESS)
	{
		// Failure produces an empty SD
		MessageBox(NULL,
			TEXT("An error occurred retrieving security information for this object,\n")
			TEXT("possibly due to insufficient access rights.\n")
			TEXT("Empty security descriptor was created for editing."),
			TEXT("Security Notice"), MB_OK);
	}
	else
	{
		hr = S_OK;
		*ppSecurityDescriptor = pSD;
	}

	return(hr);
}
static void GetOwner(const SchemeType * scheme, TCHAR * path, ChangeMode mode, TCHAR * owner)
{
  SECURITY_INFORMATION what;
  PSID pSidOwner = NULL;
  PSID pSidGroup = NULL;
  PSID pSid = NULL;
  SID_NAME_USE eUse = SidTypeUnknown;
  DWORD dwOwner = g_string_size;
  TCHAR * domain = (TCHAR *)LocalAlloc(LPTR, g_string_size*sizeof(TCHAR));
  DWORD dwDomain = g_string_size;

  DWORD ret = 0;

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

  case ChangeMode_Group:
    what = GROUP_SECURITY_INFORMATION;
    break;

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

  ret = GetNamedSecurityInfo(path, scheme->type, 
          what, &pSidOwner, &pSidGroup, NULL, NULL, NULL);
  if (ret != ERROR_SUCCESS)
    ABORT_d("Cannot get current ownership. Error code: %d", ret);

  if (!LookupAccountSid(NULL, (pSidOwner ? pSidOwner : pSidGroup),
          owner, &dwOwner, domain, &dwDomain, &eUse))
    ABORT_d("Cannot look up owner. Error code: %d", GetLastError());

cleanup:
  LocalFree(domain);
}
Beispiel #12
0
void foo() {

	PACL pOldDACL = NULL; 
	PACL pNewDACL = NULL;
	PSECURITY_DESCRIPTOR pSD = NULL;

	DWORD dwRes = GetNamedSecurityInfo(REG_SCRIPTING_FULL, SE_REGISTRY_KEY,
		DACL_SECURITY_INFORMATION, 
		NULL, NULL, &pOldDACL, NULL, &pSD);

	if (ERROR_SUCCESS != dwRes) {
		printf( "GetNamedSecurityInfo Error %u\n", dwRes );
	}  

	if(pSD == NULL) {
		printf("coudn't get security descriptor");
		return;
	}

	/* useful for debugging
	SECURITY_DESCRIPTOR sd = *((SECURITY_DESCRIPTOR*) pSD);
	*/

}
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);
	}
}
Beispiel #14
0
int main(int argc, char* argv[])
{
	// ACL tests
	char* exename = getenv("WINDIR");

	PSID psidOwner;
	PSID psidGroup;
	PACL pDacl;
	PSECURITY_DESCRIPTOR pSecurityDesc;

	DWORD result = GetNamedSecurityInfo(
		exename, // pObjectName
		SE_FILE_OBJECT, // ObjectType
		DACL_SECURITY_INFORMATION | // SecurityInfo
		GROUP_SECURITY_INFORMATION |
		OWNER_SECURITY_INFORMATION,
		&psidOwner, // ppsidOwner,
		&psidGroup, // ppsidGroup,
		&pDacl,     // ppDacl,
		NULL,       // ppSacl,
		&pSecurityDesc // ppSecurityDescriptor
	);
	if (result != ERROR_SUCCESS)
	{
		printf("Error getting security info for '%s': error %d",
			exename, result);
	}
	assert(result == ERROR_SUCCESS);

	char namebuf[1024];
	char domainbuf[1024];
	SID_NAME_USE nametype;
	DWORD namelen = sizeof(namebuf);
	DWORD domainlen = sizeof(domainbuf);

	assert(LookupAccountSid(NULL, psidOwner, namebuf, &namelen,
		domainbuf, &domainlen, &nametype));

	printf("Owner:\n");
	printf("User name:   %s\n", namebuf);
	printf("Domain name: %s\n", domainbuf);
	printf("Name type:   %d\n", nametype);
	printf("\n");

	namelen = sizeof(namebuf);
	domainlen = sizeof(domainbuf);

	assert(LookupAccountSid(NULL, psidGroup, namebuf, &namelen,
		domainbuf, &domainlen, &nametype));

	printf("Group:\n");
	printf("User name:   %s\n", namebuf);
	printf("Domain name: %s\n", domainbuf);
	printf("Name type:   %d\n", nametype);
	printf("\n");

	ULONG numEntries;
	PEXPLICIT_ACCESS pEntries;
	result = GetExplicitEntriesFromAcl
	(
		pDacl,       // pAcl
		&numEntries, // pcCountOfExplicitEntries,
		&pEntries    // pListOfExplicitEntries
	);
	assert(result == ERROR_SUCCESS);

	printf("Found %lu explicit DACL entries for '%s'\n\n",
		(unsigned long)numEntries, exename);

	for (ULONG i = 0; i < numEntries; i++)
	{
		EXPLICIT_ACCESS* pEntry = &(pEntries[i]);
		printf("DACL entry %lu:\n", (unsigned long)i);

		DWORD perms = pEntry->grfAccessPermissions;
		printf("  Access permissions: ", perms);

		#define PRINT_PERM(name) \
		if (perms & name) \
		{ \
			printf(#name " "); \
			perms &= ~name; \
		}

		PRINT_PERM(FILE_ADD_FILE);
		PRINT_PERM(FILE_ADD_SUBDIRECTORY);
		PRINT_PERM(FILE_ALL_ACCESS);
		PRINT_PERM(FILE_APPEND_DATA);
		PRINT_PERM(FILE_CREATE_PIPE_INSTANCE);
		PRINT_PERM(FILE_DELETE_CHILD);
		PRINT_PERM(FILE_EXECUTE);
		PRINT_PERM(FILE_LIST_DIRECTORY);
		PRINT_PERM(FILE_READ_ATTRIBUTES);
		PRINT_PERM(FILE_READ_DATA);
		PRINT_PERM(FILE_READ_EA);
		PRINT_PERM(FILE_TRAVERSE);
		PRINT_PERM(FILE_WRITE_ATTRIBUTES);
		PRINT_PERM(FILE_WRITE_DATA);
		PRINT_PERM(FILE_WRITE_EA);
		PRINT_PERM(STANDARD_RIGHTS_READ);
		PRINT_PERM(STANDARD_RIGHTS_WRITE);
		PRINT_PERM(SYNCHRONIZE);
		PRINT_PERM(DELETE);
		PRINT_PERM(READ_CONTROL);
		PRINT_PERM(WRITE_DAC);
		PRINT_PERM(WRITE_OWNER);
		PRINT_PERM(MAXIMUM_ALLOWED);
		PRINT_PERM(GENERIC_ALL);
		PRINT_PERM(GENERIC_EXECUTE);
		PRINT_PERM(GENERIC_WRITE);
		PRINT_PERM(GENERIC_READ);
		printf("\n");

		if (perms)
		{
			printf("  Bits left over: %08x\n", perms);
		}
		assert(!perms);

		printf("  Access mode: ");
		switch(pEntry->grfAccessMode)
		{
		case NOT_USED_ACCESS:
			printf("NOT_USED_ACCESS\n"); break;
		case GRANT_ACCESS:
			printf("GRANT_ACCESS\n"); break;
		case DENY_ACCESS:
			printf("DENY_ACCESS\n"); break;
		case REVOKE_ACCESS:
			printf("REVOKE_ACCESS\n"); break;
		case SET_AUDIT_SUCCESS:
			printf("SET_AUDIT_SUCCESS\n"); break;
		case SET_AUDIT_FAILURE:
			printf("SET_AUDIT_FAILURE\n"); break;
		default:
			printf("Unknown (%08x)\n", pEntry->grfAccessMode);
		}

		printf("  Trustee: ");
		assert(pEntry->Trustee.pMultipleTrustee == NULL);
		assert(pEntry->Trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE);
		switch(pEntry->Trustee.TrusteeForm)
		{
		case TRUSTEE_IS_SID:
			{
				PSID trusteeSid = (PSID)(pEntry->Trustee.ptstrName);

				namelen = sizeof(namebuf);
				domainlen = sizeof(domainbuf);

				assert(LookupAccountSid(NULL, trusteeSid, namebuf, &namelen,
					domainbuf, &domainlen, &nametype));

				printf("SID of %s\\%s (%d)\n", domainbuf, namebuf, nametype);
			}
			break;
		case TRUSTEE_IS_NAME:
			printf("Name\n"); break;
		case TRUSTEE_BAD_FORM:
			printf("Bad form\n"); assert(0);
		case TRUSTEE_IS_OBJECTS_AND_SID:
			printf("Objects and SID\n"); break;
		case TRUSTEE_IS_OBJECTS_AND_NAME:
			printf("Objects and name\n"); break;
		default:
			printf("Unknown form\n"); assert(0);
		}

		printf("  Trustee type: ");
		switch(pEntry->Trustee.TrusteeType)
		{
		case TRUSTEE_IS_UNKNOWN:
			printf("Unknown type.\n"); break;
		case TRUSTEE_IS_USER:
			printf("User\n"); break;
		case TRUSTEE_IS_GROUP:
			printf("Group\n"); break;
		case TRUSTEE_IS_DOMAIN:
			printf("Domain\n"); break;
		case TRUSTEE_IS_ALIAS:
			printf("Alias\n"); break;
		case TRUSTEE_IS_WELL_KNOWN_GROUP:
			printf("Well-known group\n"); break;
		case TRUSTEE_IS_DELETED:
			printf("Deleted account\n"); break;
		case TRUSTEE_IS_INVALID:
			printf("Invalid trustee type\n"); break;
		case TRUSTEE_IS_COMPUTER:
			printf("Computer\n"); break;
		default:
			printf("Unknown type %d\n", pEntry->Trustee.TrusteeType); 
			assert(0);
		}

		printf("\n");
	}

	assert(LocalFree((HLOCAL)pEntries) == 0);
	assert(LocalFree((HLOCAL)pSecurityDesc) == 0);

	chdir("c:\\tmp");
	openfile("test", O_CREAT, 0);
	struct stat ourfs;
	//test our opendir, readdir and closedir
	//functions
	DIR *ourDir = opendir("C:");

	if ( ourDir != NULL )
	{
		struct dirent *info;
		do
		{
			info = readdir(ourDir);
			if (info) printf("File/Dir name is : %s\r\n", info->d_name);
		}
		while (info != NULL);

		closedir(ourDir);
	}
	
	std::string diry("C:\\Projects\\boxbuild\\testfiles\\");
	ourDir = opendir(diry.c_str());
	if ( ourDir != NULL )
	{
		struct dirent *info;
		do
		{
			info = readdir(ourDir);
			if (info == NULL) break;
			std::string file(diry + info->d_name);
			stat(file.c_str(), &ourfs);
			if (info) printf("File/Dir name is : %s\r\n", info->d_name);
		}
		while ( info != NULL );

		closedir(ourDir);

	}

	stat("c:\\windows", &ourfs);
	stat("c:\\autoexec.bat", &ourfs);
	printf("Finished dir read\n");

	//test our getopt function
	char * test_argv[] = 
	{
		"foobar.exe",
		"-qwc",
		"-",
		"-c",
		"fgfgfg",
		"-f",
		"-l",
		"hello",
		"-",
		"force-sync",
		NULL
	};
	int test_argc;
	for (test_argc = 0; test_argv[test_argc]; test_argc++) { }
	const char* opts = "qwc:l:";

	assert(getopt(test_argc, test_argv, opts) == 'q');
	assert(getopt(test_argc, test_argv, opts) == 'w');
	assert(getopt(test_argc, test_argv, opts) == 'c');
	assert(strcmp(optarg, "-") == 0);
	assert(getopt(test_argc, test_argv, opts) == 'c');
	assert(strcmp(optarg, "fgfgfg") == 0);
	assert(getopt(test_argc, test_argv, opts) == '?');
	assert(optopt == 'f');
	assert(getopt(test_argc, test_argv, opts) == 'l');
	assert(strcmp(optarg, "hello") == 0);
	assert(getopt(test_argc, test_argv, opts) == -1);
	// assert(optopt == 0); // no more options
	assert(strcmp(test_argv[optind], "-") == 0);
	assert(strcmp(test_argv[optind+1], "force-sync") == 0);
	//end of getopt test
	
	//now test our statfs funct
	stat("c:\\cert.cer", &ourfs);

	char *timee;
	
	timee = ctime(&ourfs.st_mtime);

	if (S_ISREG(ourfs.st_mode))
	{
		printf("is a normal file\n");
	}
	else
	{
		printf("is a directory?\n");
		exit(1);
	}

	lstat(getenv("WINDIR"), &ourfs);

	if ( S_ISDIR(ourfs.st_mode))
	{
		printf("is a directory\n");
	}
	else
	{
		printf("is a file?\n");
		exit(1);
	}

	//test the syslog functions
	openlog("Box Backup", 0,0);
	//the old ones are the best...
	syslog(LOG_ERR, "Hello World");
	syslog(LOG_ERR, "Value of int is: %i", 6);

	closelog();

	/*
	//first off get the path name for the default 
	char buf[MAX_PATH];
	
	GetModuleFileName(NULL, buf, sizeof(buf));
	std::string buffer(buf);
	std::string conf("-c " + buffer.substr(0,(buffer.find("win32test.exe"))) + "bbackupd.conf");
	//std::string conf( "-c " + buffer.substr(0,(buffer.find("bbackupd.exe"))) + "bbackupd.conf");
	*/

	return 0;
}
Beispiel #15
0
static int TransferRights(char *filename, ServerFileGetState *args, struct stat *sb)
{
#ifdef __MINGW32__
    SECURITY_DESCRIPTOR *secDesc;
    SID *ownerSid;

    if (GetNamedSecurityInfo
        (filename, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, (PSID *) & ownerSid, NULL, NULL, NULL,
         (void **)&secDesc) == ERROR_SUCCESS)
    {
        if (IsValidSid((args->connect)->sid) && EqualSid(ownerSid, (args->connect)->sid))
        {
            Log(LOG_LEVEL_DEBUG, "Caller '%s' is the owner of the file", (args->connect)->username);
        }
        else
        {
            // If the process doesn't own the file, we can access if we are
            // root AND granted root map

            LocalFree(secDesc);

            if (args->connect->maproot)
            {
                Log(LOG_LEVEL_VERBOSE, "Caller '%s' not owner of '%s', but mapping privilege",
                      (args->connect)->username, filename);
                return true;
            }
            else
            {
                Log(LOG_LEVEL_VERBOSE, "Remote user denied right to file '%s' (consider maproot?)", filename);
                return false;
            }
        }

        LocalFree(secDesc);
    }
    else
    {
        Log(LOG_LEVEL_ERR, "Could not retreive existing owner of '%s'. (GetNamedSecurityInfo)", filename);
        return false;
    }

#else

    uid_t uid = (args->connect)->uid;

    if ((uid != 0) && (!args->connect->maproot))    /* should remote root be local root */
    {
        if (sb->st_uid == uid)
        {
            Log(LOG_LEVEL_DEBUG, "Caller '%s' is the owner of the file", (args->connect)->username);
        }
        else
        {
            if (sb->st_mode & S_IROTH)
            {
                Log(LOG_LEVEL_DEBUG, "Caller %s not owner of the file but permission granted", (args->connect)->username);
            }
            else
            {
                Log(LOG_LEVEL_DEBUG, "Caller '%s' is not the owner of the file", (args->connect)->username);
                Log(LOG_LEVEL_VERBOSE, "Remote user denied right to file '%s' (consider maproot?)", filename);
                return false;
            }
        }
    }
#endif

    return true;
}
/**
 * @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;
}
Beispiel #17
0
/**
 * @brief
 * 	perm_granted_admin_and_name: returns 0 if permission mask in 'disallow' has
 *	been granted to only admin-type of accounts and 'owner'. 'owner' can be
 *	set to NULL. Otherwise, it will return the values EPERM or EACCESS with
 *	error message returned in 'errmsg'.
 */
int
perm_granted_admin_and_owner(char *path, int disallow, char *owner, char *errmsg)
{
	int	rc;
	DWORD	i, j;
	SID	*powner = NULL;
	char	*powner_s = NULL;

	ACL	   *pdacl = NULL;
	SECURITY_DESCRIPTOR *psd = NULL;
	ACL_SIZE_INFORMATION	sizeInfo;
	ACCESS_ALLOWED_ACE	*pace;
	int			violate = 0;
	struct	accessinfo	*allowed = NULL;
	struct  accessinfo	*denied = NULL;
	int			mask;
	char			*name;
	SID			*esid = getusersid("Everyone");

	if (GetNamedSecurityInfo(path, SE_FILE_OBJECT,
		OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION,
		&powner, 0, &pdacl, 0, &psd) != ERROR_SUCCESS) {
		errno = GetLastError();
		rc = errno;
		sprintf(errmsg, "GetNameSecurityInfo on file %s failed", path);
		goto chkerr;
	}

	/* is owner SID a privilege user? */
	powner_s = getusername(powner);
	if (powner_s == NULL)
		powner_s = getgrpname(powner);

	if (powner_s != NULL) {
		if ( !sidIsAdminPrivilege(powner) || \
			( (owner != NULL) && strcmp(owner, powner_s) != 0 )  ) {
			rc = EPERM;
			sprintf(errmsg, "File %s not owned by user %s or an admin-type user!",
				path, owner);
			goto chkerr;
		}
	}

	/* make sure perm mask granted only to privilege groups or the
	 special 'owner' */

	GetAclInformation(pdacl, &sizeInfo, sizeof(sizeInfo),
		AclSizeInformation);

	allowed = (struct accessinfo *)malloc(sizeof(struct accessinfo)*sizeInfo.AceCount);
	denied = (struct accessinfo *)malloc(sizeof(struct accessinfo)*sizeInfo.AceCount);

	if (allowed == NULL || denied == NULL) {
		rc = errno;
		strcpy(errmsg, "malloc of allowed or denied struct failed!");
		goto chkerr;
	}

	accessinfo_init(allowed, sizeInfo.AceCount);
	accessinfo_init(denied, sizeInfo.AceCount);

	for (i=0; i < sizeInfo.AceCount; i++) {

		GetAce(pdacl, i, (void **)&pace);
		name = getgrpname_full((SID *)&pace->SidStart);
		if (name == NULL)
			name = getusername((SID *)&pace->SidStart);

		/* later, we need to also check denied access which */
		/* overrides allowed access. */
		if ( pace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE &&\
			 (mask=(pace->Mask & disallow)) && \
			 ( EqualSid((SID *)&pace->SidStart, esid) || \
			sid2rid((SID *)&pace->SidStart) != \
					 SECURITY_CREATOR_OWNER_RID ) && \
			(!sidIsAdminPrivilege( (SID *)&pace->SidStart)) || \
   			((owner != NULL) && strcmp(name, owner) != 0) ) {
			(void)accessinfo_add(allowed, sizeInfo.AceCount,
				name, (mask & 0xFFFF));
		} else if (pace->Header.AceType == ACCESS_DENIED_ACE_TYPE) {
			(void)accessinfo_add(denied, sizeInfo.AceCount,
				name, (pace->Mask & 0xFFFF));
		} else {
			if (name) {
				(void)free(name);
			}
		}
	}
	/* validate */
	for (i=0; i < sizeInfo.AceCount; i++) {
		for (j=0; j < sizeInfo.AceCount; j++) {
			if( allowed[i].group == NULL || \
						denied[j].group == NULL )
				continue;

			if (strcmp(allowed[i].group, denied[j].group) == 0)
				allowed[i].mask &= ~denied[j].mask;
			/* unset the denied mask from allowed */
		}
	}


	if (!accessinfo_mask_allzero(allowed, sizeInfo.AceCount)) {
		rc = EACCES;
		sprintf(errmsg, "File %s has following disallowed perm masks: ",
			path);
		strcat(errmsg, accessinfo_values(allowed, sizeInfo.AceCount));
		goto chkerr;
	}

	rc = 0;

chkerr:
	if (powner_s)(void)free(powner_s);
	/* NOTE: powner and pdacl hang off of psd, so a free of psd would */
	/* automatically free them */
	if (psd) LocalFree(psd);
	if (allowed) accessinfo_free(allowed, sizeInfo.AceCount);
	if (denied) accessinfo_free(denied, sizeInfo.AceCount);
	if (esid) LocalFree(esid);

	return (rc);
}
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);
	}
}
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
}
Beispiel #21
0
int win32_write_access (char *path)
{
    SID *sid = NULL;
    ACL *dacl = NULL;
    LPTSTR domain = NULL;
    SECURITY_DESCRIPTOR *sd = NULL;
    TRUSTEE t;
    DWORD sidsize = 0, dlen = 0;
    SID_NAME_USE stype;
    ACCESS_MASK amask;
    const char *username;
    int ret, ok = 0, err = 0;

    /* screen for the read-only attribute first */
    if (access(path, W_OK) != 0) {
	return 0;
    }

    username = g_get_user_name();

    /* get the size of the SID and domain */
    LookupAccountName(NULL, username, NULL, &sidsize, 
		      NULL, &dlen, &stype);

    sid = LocalAlloc(0, sidsize);
    domain = LocalAlloc(0, dlen * sizeof *domain);
    if (sid == NULL || domain == NULL) {
	err = 1;
    } 

    if (!err) {
	/* call the function for real */
	ret = LookupAccountName(NULL, username, sid, &sidsize, 
				domain, &dlen, &stype);
	err = (ret == 0);
    }

    if (!err) {
	/* build a trustee and get the file's DACL */
	BuildTrusteeWithSid(&t, sid);
	ret = GetNamedSecurityInfo(path, SE_FILE_OBJECT, 
				   DACL_SECURITY_INFORMATION, 
				   NULL, NULL, &dacl, NULL, 
				   (void **) &sd);
	err = (ret != ERROR_SUCCESS);
    }

    if (!err) {
	/* get the access mask for this trustee */
	ret = GetEffectiveRightsFromAcl(dacl, &t, &amask);
        if (ret != ERROR_SUCCESS) {
            fprintf(stderr, "GetEffectiveRights...: ret=%d\n", ret);   
            if (ret != RPC_S_SERVER_UNAVAILABLE && ret != ERROR_NO_SUCH_DOMAIN) {
                err = 1;
            }
        } else if (amask & STANDARD_RIGHTS_WRITE) {
	    ok = 1;
	}
    }

    if (dacl != NULL) {
	LocalFree(dacl);
    }
    if (sid != NULL) {
	LocalFree(sid);
    }    
    if (sd != NULL) {
	LocalFree(sd);
    }
    if (domain != NULL) {
	LocalFree(domain);
    }

    if (err) {
	win_show_last_error();
    }

    return ok;
}
Beispiel #22
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;
}
Beispiel #23
0
int
perm_granted(char *path, int perm_mask, char *user, char *realuser)
{
	int	rc;
	DWORD	i, j;
	ACL	   *pdacl = NULL;
	SECURITY_DESCRIPTOR *psd = NULL;
	ACL_SIZE_INFORMATION	sizeInfo;
	ACCESS_ALLOWED_ACE	*pace;
	struct	accessinfo	*allowed = NULL;
	struct  accessinfo	*denied = NULL;
	int			mask;
	char			*name;
	SID			*usid;

	if (GetNamedSecurityInfo(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
		0, 0, &pdacl, 0, &psd) != ERROR_SUCCESS) {
		errno = GetLastError();
		rc = 1;
		goto perm_chkerr;
	}

	usid = getusersid2(user, realuser);
	if (usid == NULL) {
		rc = 2;
		goto perm_chkerr;
	}

	/* make sure perm mask granted only to privilege groups or the
	 special 'owner' */

	GetAclInformation(pdacl, &sizeInfo, sizeof(sizeInfo),
		AclSizeInformation);

	allowed = (struct accessinfo *)malloc(sizeof(struct accessinfo)*sizeInfo.AceCount);
	denied = (struct accessinfo *)malloc(sizeof(struct accessinfo)*sizeInfo.AceCount);

	if (allowed == NULL || denied == NULL) {
		rc = 3;
		goto perm_chkerr;
	}

	accessinfo_init(allowed, sizeInfo.AceCount);
	accessinfo_init(denied, sizeInfo.AceCount);

	for (i=0; i < sizeInfo.AceCount; i++) {

		GetAce(pdacl, i, (void **)&pace);
		name = getgrpname_full((SID *)&pace->SidStart);
		if (name == NULL)
			name = getusername((SID *)&pace->SidStart);

		/* later, we need to also check denied access which */
		/* overrides allowed access. */
		if ( (pace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) && \
			(mask=(pace->Mask & perm_mask)) && \
			     EqualSid((SID *)&pace->SidStart, usid) ) {
			(void)accessinfo_add(allowed, sizeInfo.AceCount,
				name, (mask & 0xFFFF));
		} else if (pace->Header.AceType == ACCESS_DENIED_ACE_TYPE) {
			(void)accessinfo_add(denied, sizeInfo.AceCount,
				name, (pace->Mask & 0xFFFF));
		} else {
			if (name) {
				(void)free(name);
			}
		}

	}
	/* filter the allowed pool so that none appear in denied */
	for (i=0; i < sizeInfo.AceCount; i++) {
		for (j=0; j < sizeInfo.AceCount; j++) {
			if( allowed[i].group == NULL || \
						denied[j].group == NULL )
				continue;

			if (strcmp(allowed[i].group, denied[j].group) == 0)
				allowed[i].mask &= ~denied[j].mask;
			/* unset the denied mask from allowed */
		}
	}

	/* now filter perm_mask to those specified in allowed */
	for (i=0; i < sizeInfo.AceCount; i++) {
		if (allowed[i].group == NULL)
			continue;

		/* unset the allowed mask from perm_mask */
		perm_mask &= ~allowed[i].mask;
	}

	if (perm_mask != 0) {
		rc = 4;
		goto perm_chkerr;
	}

	rc = 0;

perm_chkerr:
	if (pdacl) LocalFree(pdacl);
	if (psd) LocalFree(psd);
	if (allowed) accessinfo_free(allowed, sizeInfo.AceCount);
	if (denied) accessinfo_free(denied, sizeInfo.AceCount);
	if (usid) LocalFree(usid);

	return (rc);
}
Beispiel #24
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;
}
Beispiel #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);
	}
}
Beispiel #26
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;
}
Beispiel #27
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;
}
Beispiel #28
0
/**
   stat a file on winnt - this is *very* painful
**/
int win_filestat(stat_b *st, char *path, unsigned int want, unsigned int *give, char **err) {
    WIN32_FILE_ATTRIBUTE_DATA stat;
    SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
    PSID owner, group, world = NULL;
    PACL dacl;
    PSECURITY_DESCRIPTOR pdesc;
    int have_sec = 0;

    *give = 0;
    
    if (!GetFileAttributesEx(path, GetFileExInfoStandard, &stat)) {
		int ret, ecode = GetLastError();

		*err = get_error_msg(ecode);
		switch (ecode) {
		case ERROR_FILE_NOT_FOUND:
		case ERROR_PATH_NOT_FOUND: ret = FX_NO_SUCH_FILE; break;
		case ERROR_ACCESS_DENIED:  ret = FX_PERMISSION_DENIED; break;
		default: ret = FX_FAILURE;
		}
		return ret;
    }

    /* create a PSID for well known group "world"  - this is equivalent to "others" on POSIX */
    if (!AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &world)) 
		world = NULL;
    
    memset(st, 0x0, sizeof(*st));
    
    *give |= ATTR_SIZE;
    if (!(stat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
		st->size = ((unsigned __int64)stat.nFileSizeHigh << 32) + (unsigned __int64)stat.nFileSizeLow;
    else 
		st->size = 0;

    if (GetNamedSecurityInfo(path, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION 
							 | DACL_SECURITY_INFORMATION, &owner, &group, &dacl, NULL, &pdesc) != ERROR_SUCCESS) {
		ERR(have_sec, "Could not retrieve security info");
		have_sec = 0;
    } else
		have_sec = 1;

    if (have_sec) {
		/* fake unix style uid & gid.
		   We will do this by getting the string representations of the owner & group PIDS
		   and converting them to numbers (hopefully unique)
	
		   char *temp;
		   ConvertSidToStringSid(owner, &temp);
		   st->uid = st->gid = atol(temp);
		   printf("(%s) sid = %l , %l\n", temp, st->uid, st->gid);
		   LocalFree(temp);
		*/
		st->uid = st->gid = 42;
		*give |= ATTR_UIDGID;
    }
    /*
      not applicable for v3 - the commented code is for v6

	  if ((want & ATTR_UIDGID) & have_sec){
	  wchar_t uname[UNLEN + 1], dname[DNLEN + 1], gname[1000], gname2[1000];
	  DWORD unlen = UNLEN, dnlen = DNLEN, gnlen = 1000, gnlen2 = 1000;
	  SID_NAME_USE stype;
	
	  st->owner = malloc(UNLEN + DNLEN + 2);
	  if (!LookupAccountSidW(NULL, owner, uname, &unlen, dname, &dnlen, &stype)) {
	  ERR(GetLastError(), "Could not lookup ownername");
	  free(st->owner);
	  st->owner = NULL;
	  } else 
	  swprintf(st->owner, UNLEN + DNLEN + 2, L"%s@%s", uname, dname);
	
	  st->group = malloc(UNLEN + DNLEN + 2 + 2000);
	  if (!LookupAccountSidW(NULL, group, gname, &gnlen, gname2, &gnlen2, &stype)) {
	  ERR(GetLastError(), "Could not lookup group name");
	  if (st->owner) 
	  swprintf(st->group, UNLEN + DNLEN + 2 + 2000, L"None@%", dname);
	  else {
	  free(st->group);
	  st->group = NULL;
	  }
	  } else 
	  swprintf(st->group, UNLEN + DNLEN + 2 + 2000, L"%s@%s", gname, gname2);

	  *give |= ATTR_OWNERGROUP;
	  } 
    */
    st->perms = 0;
    st->perms |= stat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? FX_S_IFDIR : FX_S_IFREG;

    if (have_sec) {
		TRUSTEE_W ident = {NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID};
		ACCESS_MASK acc;
	
		ident.TrusteeType = TRUSTEE_IS_USER;
		ident.ptstrName = owner;
		if (GetEffectiveRightsFromAclW(dacl, &ident, &acc) == ERROR_SUCCESS) {
			if (acc & FILE_EXECUTE) 
				st->perms |= FX_S_IXUSR;
			if (acc & FILE_WRITE_DATA)
				st->perms |= FX_S_IWUSR;
			if (acc & FILE_READ_DATA)
				st->perms |= FX_S_IRUSR;
		}
		ident.TrusteeType = TRUSTEE_IS_GROUP;
		ident.ptstrName = group;
		if (GetEffectiveRightsFromAclW(dacl, &ident, &acc) == ERROR_SUCCESS) {
			if (acc & FILE_EXECUTE) 
				st->perms |= FX_S_IXGRP;
			if (acc & FILE_WRITE_DATA)
				st->perms |= FX_S_IWGRP;
			if (acc & FILE_READ_DATA)
				st->perms |= FX_S_IRGRP;
		}
	
		if (world) {
			ident.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
			ident.ptstrName = world;
			if (GetEffectiveRightsFromAclW(dacl, &ident, &acc) == ERROR_SUCCESS) {
				if (acc & FILE_EXECUTE)
					st->perms |= FX_S_IROTH;
				if (acc & FILE_WRITE_DATA)
					st->perms |= FX_S_IWOTH;
				if (acc & FILE_READ_DATA)
					st->perms |= FX_S_IROTH;
			}
		}
		/* we can't do shit about the S_ISUID, S_ISGUID & S_ISVTX flags */
		*give |= ATTR_PERMISSIONS;
    }
    
    win_to_unix_time(stat.ftLastAccessTime, &st->atime);
    win_to_unix_time(stat.ftLastWriteTime, &st->mtime);
    *give |= ATTR_ACMODTIME;

    /*
	  st->acl = NULL;
	  if (want & ATTR_BITS) {
	  st->attrib_bits_valid = ATTR_ARCHIVE | ATTR_COMPRESSED | ATTR_READONLY
	  | ATTR_SYSTEM | ATTR_SPARSE | ATTR_HIDDEN | ATTR_ENCRYPTED;
	  st->attrib_bits = (stat.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) 
	  | (stat.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)
	  | (stat.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
	  | (stat.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
	  | (stat.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE)
	  | (stat.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
	  | (stat.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED);
	  *give |= ATTR_BITS;
	  }
    */

    if (world) 
		FreeSid(world);
    if (pdesc)
		LocalFree(pdesc);
    return FX_OK;
}