Ejemplo n.º 1
0
/*
 * BuildExplicitAccessWithSid() - counterpart to the Win32 API function
 *     BuildExplicitAccessWithName() (surprisingly, MS doesn't provide this).
 */
static void
BuildExplicitAccessWithSid(PEXPLICIT_ACCESS explicitAccessP, PSID trusteeSidP,
			   DWORD accessPerm, ACCESS_MODE accessMode,
			   DWORD inheritance)
{
    if (explicitAccessP != NULL) {
	explicitAccessP->grfAccessPermissions = accessPerm;
	explicitAccessP->grfAccessMode = accessMode;
	explicitAccessP->grfInheritance = inheritance;
	BuildTrusteeWithSid(&explicitAccessP->Trustee, trusteeSidP);
    }
}
nsresult TestPermissions()
{

    nsresult rv; // Return value

    // File variables
    HANDLE tempFileHandle;
    nsCOMPtr<nsILocalFile> tempFile;
    nsCOMPtr<nsILocalFile> tempDirectory1;
    nsCOMPtr<nsILocalFile> tempDirectory2;
    WCHAR filePath[MAX_PATH];
    WCHAR dir1Path[MAX_PATH];
    WCHAR dir2Path[MAX_PATH];

    // Security variables
    DWORD result;
    PSID everyoneSID = NULL, adminSID = NULL;
    PACL dirACL = NULL, fileACL = NULL;
    PSECURITY_DESCRIPTOR dirSD = NULL, fileSD = NULL;
    EXPLICIT_ACCESS ea[2];
    SID_IDENTIFIER_AUTHORITY SIDAuthWorld =
            SECURITY_WORLD_SID_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
    SECURITY_ATTRIBUTES sa;
    TRUSTEE everyoneTrustee;
    ACCESS_MASK everyoneRights;

    // Create a well-known SID for the Everyone group.
    if(!AllocateAndInitializeSid(&SIDAuthWorld, 1,
                     SECURITY_WORLD_RID,
                     0, 0, 0, 0, 0, 0, 0,
                     &everyoneSID))
    {
        fail("NTFS Permissions: AllocateAndInitializeSid Error");
        return NS_ERROR_FAILURE;
    }

    // Create a SID for the Administrators group.
    if(! AllocateAndInitializeSid(&SIDAuthNT, 2,
                     SECURITY_BUILTIN_DOMAIN_RID,
                     DOMAIN_ALIAS_RID_ADMINS,
                     0, 0, 0, 0, 0, 0,
                     &adminSID)) 
    {
        fail("NTFS Permissions: AllocateAndInitializeSid Error");
        return NS_ERROR_FAILURE; 
    }

    // Initialize an EXPLICIT_ACCESS structure for an ACE.
    // The ACE will allow Everyone read access to the directory.
    ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));
    ea[0].grfAccessPermissions = GENERIC_READ;
    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) everyoneSID;

    // Initialize an EXPLICIT_ACCESS structure for an ACE.
    // The ACE will allow the Administrators group full access
    ea[1].grfAccessPermissions = GENERIC_ALL | STANDARD_RIGHTS_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_GROUP;
    ea[1].Trustee.ptstrName  = (LPTSTR) adminSID;

    // Create a new ACL that contains the new ACEs.
    result = SetEntriesInAcl(2, ea, NULL, &dirACL);
    if (ERROR_SUCCESS != result) 
    {
        fail("NTFS Permissions: SetEntriesInAcl Error");
        return NS_ERROR_FAILURE; 
    }

    // Initialize a security descriptor.  
    dirSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, 
                             SECURITY_DESCRIPTOR_MIN_LENGTH); 
    if (NULL == dirSD) 
    { 
        fail("NTFS Permissions: LocalAlloc Error");
        return NS_ERROR_FAILURE; 
    }

    if (!InitializeSecurityDescriptor(dirSD,
            SECURITY_DESCRIPTOR_REVISION)) 
    {  
        fail("NTFS Permissions: InitializeSecurityDescriptor Error");
        return NS_ERROR_FAILURE; 
    } 

    // Add the ACL to the security descriptor. 
    if (!SetSecurityDescriptorDacl(dirSD, true, dirACL, false)) 
    {  
        fail("NTFS Permissions: SetSecurityDescriptorDacl Error");
        return NS_ERROR_FAILURE;  
    } 

    // Initialize a security attributes structure.
    sa.nLength = sizeof (SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = dirSD;
    sa.bInheritHandle = false;

    // Create and open first temporary directory
    if(!CreateDirectoryW(L".\\NTFSPERMTEMP1", &sa))
    {
        fail("NTFS Permissions: Creating Temporary Directory");
        return NS_ERROR_FAILURE;
    }

    GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP1", MAX_PATH, dir1Path, NULL);


    rv = NS_NewLocalFile(nsEmbedString(dir1Path), false,
                         getter_AddRefs(tempDirectory1));
    if (NS_FAILED(rv))
    {
        fail("NTFS Permissions: Opening Temporary Directory 1");
        return rv;
    }


    // Create and open temporary file
    tempFileHandle = CreateFileW(L".\\NTFSPERMTEMP1\\NTFSPerm.tmp", 
                            GENERIC_READ | GENERIC_WRITE,
                            0, 
                            NULL, //default security
                            CREATE_ALWAYS,        
                            FILE_ATTRIBUTE_NORMAL,
                            NULL);  

    if(tempFileHandle == INVALID_HANDLE_VALUE)
    {
        fail("NTFS Permissions: Creating Temporary File");
        return NS_ERROR_FAILURE;
    }

    CloseHandle(tempFileHandle);

    GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP1\\NTFSPerm.tmp", 
                        MAX_PATH, filePath, NULL);

    rv = NS_NewLocalFile(nsEmbedString(filePath), false,
                         getter_AddRefs(tempFile));
    if (NS_FAILED(rv))
    {
        fail("NTFS Permissions: Opening Temporary File");
                return rv;
    }

    // Update Everyone Explict_Acess to full access.
    ea[0].grfAccessPermissions = GENERIC_ALL | STANDARD_RIGHTS_ALL;

    // Update the ACL to contain the new ACEs.
    result = SetEntriesInAcl(2, ea, NULL, &dirACL);
    if (ERROR_SUCCESS != result) 
    {
        fail("NTFS Permissions: SetEntriesInAcl 2 Error");
        return NS_ERROR_FAILURE; 
    }

    // Add the new ACL to the security descriptor. 
    if (!SetSecurityDescriptorDacl(dirSD, true, dirACL, false)) 
    {  
        fail("NTFS Permissions: SetSecurityDescriptorDacl 2 Error");
        return NS_ERROR_FAILURE;  
    } 

    // Create and open second temporary directory
    if(!CreateDirectoryW(L".\\NTFSPERMTEMP2", &sa))
    {
        fail("NTFS Permissions: Creating Temporary Directory 2");
        return NS_ERROR_FAILURE;
    }

    GetFullPathNameW((LPCWSTR)L".\\NTFSPERMTEMP2", MAX_PATH, dir2Path, NULL);


    rv = NS_NewLocalFile(nsEmbedString(dir2Path), false,
                         getter_AddRefs(tempDirectory2));
    if (NS_FAILED(rv))
    {
        fail("NTFS Permissions: Opening Temporary Directory 2");
        return rv;
    }

    // Move the file.
    rv = tempFile->MoveTo(tempDirectory2, EmptyString());

    if (NS_FAILED(rv))
    {
        fail("NTFS Permissions: Moving");
        return rv;
    }

    // Access the ACL of the file
    result = GetNamedSecurityInfoW(L".\\NTFSPERMTEMP2\\NTFSPerm.tmp", 
                                        SE_FILE_OBJECT,
                                        DACL_SECURITY_INFORMATION | 
                                        UNPROTECTED_DACL_SECURITY_INFORMATION,
                                        NULL, NULL, &fileACL, NULL, &fileSD);
    if (ERROR_SUCCESS != result) 
    {
        fail("NTFS Permissions: GetNamedSecurityDescriptor Error");
        return NS_ERROR_FAILURE; 
    }

    // Build a trustee representing "Everyone"
    BuildTrusteeWithSid(&everyoneTrustee, everyoneSID);

    // Get Everyone's effective rights.
    result = GetEffectiveRightsFromAcl(fileACL, &everyoneTrustee, 
                                        &everyoneRights);
    if (ERROR_SUCCESS != result) 
    {
        fail("NTFS Permissions: GetEffectiveRightsFromAcl Error");
        return NS_ERROR_FAILURE; 
    }

    // Check for delete access, which we won't have unless permissions have 
    // updated
    if((everyoneRights & DELETE) == (DELETE))
    {
        passed("NTFS Permissions Test");
        rv = NS_OK;
    }
    else
    {
        fail("NTFS Permissions: Access check.");
        rv = NS_ERROR_FAILURE;
    }

    // Cleanup
    if (everyoneSID) 
        FreeSid(everyoneSID);
    if (adminSID) 
        FreeSid(adminSID);
    if (dirACL) 
        LocalFree(dirACL);
    if (dirSD) 
        LocalFree(dirSD);
    if(fileACL)
        LocalFree(fileACL);

    tempDirectory1->Remove(true);
    tempDirectory2->Remove(true);
    
    return rv;
}
Ejemplo n.º 3
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;
}