Pergunta

Eu tenho uma pergunta um tanto obscuro aqui.

O que eu preciso:. Para determinar se as permissões (ou, a rigor, uma ACE específica de um DACL) de um arquivo / pasta foi herdado

Como eu tentei resolver isso: usando ligações winapi para python (módulo win32security, para ser preciso). Aqui é a versão reduzida, que faz exatamente isso, -. Ele simplesmente toma um caminho para um arquivo como um argumento e imprime ACEs um a um, indicando que flags estão definidas

#!/usr/bin/env python
from win32security import *
import sys

def decode_flags(flags):
    _flags = {
        SE_DACL_PROTECTED:"SE_DACL_PROTECTED",
        SE_DACL_AUTO_INHERITED:"SE_DACL_AUTO_INHERITED",
        OBJECT_INHERIT_ACE:"OBJECT_INHERIT_ACE",
        CONTAINER_INHERIT_ACE:"CONTAINER_INHERIT_ACE",
        INHERIT_ONLY_ACE:"INHERIT_ONLY_ACE",
        NO_INHERITANCE:"NO_INHERITANCE",
        NO_PROPAGATE_INHERIT_ACE:"NO_PROPAGATE_INHERIT_ACE",
        INHERITED_ACE:"INHERITED_ACE"
    }
    for key in _flags.keys():
        if (flags & key):
            print '\t','\t',_flags[key],"is set!"


def main(argv):
    target = argv[0]
    print target

    security_descriptor = GetFileSecurity(target,DACL_SECURITY_INFORMATION)

    dacl = security_descriptor.GetSecurityDescriptorDacl()

    for ace_index in range(dacl.GetAceCount()):
        (ace_type,ace_flags),access_mask,sid = dacl.GetAce(ace_index)
        name,domain,account_type = LookupAccountSid(None,sid)
        print '\t',domain+'\\'+name,hex(ace_flags)
        decode_flags(ace_flags)


if __name__ == '__main__':
    main(sys.argv[1:])

bastante simples - obter um descritor de segurança, obter um DACL a partir dele, em seguida, percorrer os ACEs na DACL. O bit realmente importante aqui é a bandeira acesso INHERITED_ACE. Deve ser definido quando a ACE é herdada e não definir explicitamente.

Quando você cria uma pasta / arquivo, a ACL é preenchido com ACEs de acordo com as ACEs do objeto pai (pasta), que estão definidos para propagar para as crianças. No entanto, a menos que você fazer qualquer alteração à lista de acesso, a bandeira INHERITED_ACE não serão definidas! Mas as permissões herdadas estão lá e eles não funcionam.

Se você fizer qualquer alteração ligeira (por exemplo, adicionar uma entrada à lista de acesso, aplicar as alterações e excluí-lo), a bandeira aparece magicamente (o comportamento não muda de forma alguma, porém, ele trabalhou antes e ele funciona depois )! O que eu quero é encontrar a origem deste comportamento da bandeira INHERITED_ACE e, talvez encontrar outro confiável maneira de determinar se o ACE foi herdada ou não.

Como reproduzir:

  1. Criar um objeto (arquivo ou pasta)
  2. Verifique as permissões no Windows Explorer, ver que eles foram propagadas do objeto pai (usando, por exemplo, guia de propriedades do arquivo de segurança de diálogo do Windows Explorer).
  3. Verifique as bandeiras utilizando, por exemplo, o script que eu estava usando (INHERITED_ACE não será definido em qualquer ACEs).
  4. Alterar permissões de um objeto (aplicar alterações), mudá-los de volta, mesmo.
  5. Verifique as bandeiras (INHERITED_ACE irá estar lá)
  6. .. agitar sua cabeça em descrença (eu sei que eu fiz)

Sorry for um post um tanto longo, espero que isso faz com que, pelo menos, um pouco de sentido.

Foi útil?

Solução

No meu Win XP Home Edition este código não parece trabalho em tudo: -)

eu recebo este rastreamento de pilha:

Traceback (chamada mais recente passada):
Arquivo "C: \ 1.py", linha 37, em principal (sys.argv [1:])
Arquivo "C: \ 1.py", linha 29, no principal para ace_index na faixa (dacl.GetAceCount ()):

AttributeError: objeto 'NoneType' tem nenhum atributo 'GetAceCount'

Você pode apenas tentar "empurrar" a DACL a ser preenchido? Quer dizer, se você sabe que está indo para o trabalho depois de fazer uma pequena mudança nele ... fazer uma ligeira alteração programaticamente, adicione um esboço ACE e removê-lo. Você pode?

UPDATE. Eu fiz uma experiência com um programa C # na minha máquina de trabalho (com Win XP Prof) e devo dizer-lhe que o caminho .net de obter esta informação de segurança realmente funciona. Então, quando eu criar um novo arquivo, meus C # detecta programas que as ACEs foram herdadas, enquanto seu código python não.

Aqui está o exemplo de saída de minhas corridas:

C:> csharp_tricks.exe 2.txt

FullControl -> IsInherited: True

FullControl -> IsInherited: True

ReadAndExecute, Sincronizar -> IsInherited: True


C:> 1.py 2.txt

2.txt

BUILTIN \ Administradores 0x0

NT AUTHORITY \ SYSTEM 0x0

BUILTIN \ Users 0x0

Meu classe C #:

public class InheritedAce
{
    public static string GetDACLReport(string path)
    {
        StringBuilder result = new StringBuilder();
        FileSecurity fs = new FileSecurity(path, AccessControlSections.Access);
        foreach (var rule in fs.GetAccessRules(true, true, typeof(SecurityIdentifier)).OfType<FileSystemAccessRule>())
        {
            result.AppendFormat("{0}  -->  IsInherited:  {1}", rule.FileSystemRights, rule.IsInherited);
            result.AppendLine();
        }

        return result.ToString();
    }
}

Assim, parece ser um bug na biblioteca de segurança pywin32 python. Talvez eles não estão fazendo todo o sistema necessário chama ...

Outras dicas

Você pode usar o framework .Net

System.Security.AccessControl

Isto cobre ACL e DACL e SACL.

Eu acho que o cartaz original está vendo o comportamento detalhado no

Esta postagem newsgroup

Observe que os sinalizadores de controle definidas no contêiner pode mudar simplesmente un-assinalando e re-assinalando a caixa de herança no GUI.

Além disso, note que simplesmente adicionando um ACE ao DACL usando ferramentas da Microsoft também irá alterar os sinalizadores de controle.

Além disso, note que a GUI, cacls e icacls não pode ser invocado quando se trata de herança devido a muitos erros sutis como discutido na postagem de grupo de notícias.

Parece que a "velha" maneira de controlar a herança era usar os sinalizadores de controle no recipiente em combinação com bandeiras ECA relacionados herança.

A forma "nova" não usa os sinalizadores de controle no recipiente e em vez disso usa ACEs duplicados; um para controlar o acesso no objeto e um segundo para controlar o que é herdada por objetos filho.

Mas, parece que as ferramentas da Microsoft existentes (por exemplo Vista) não pode trabalhar no modo "novo" ainda, então quando você faz uma mudança simples usando as ferramentas, recorre à velha maneira de usar sinalizadores de controle no contêiner .

Se você criar uma nova partição no Vista, em seguida, criar uma nova pasta, em seguida, olhar para as bandeiras e ACEs, ele vai ser algo como isto

ControlFlags : 0x8004
Owner : BUILTIN\Administrators
Group : WS1\None
S-1-5-32-544 : BUILTIN\Administrators : 0x0 : 0x0 : 0x1F01FF
S-1-5-32-544 : BUILTIN\Administrators : 0x0 : 0xB : 0x10000000
S-1-5-18 : NT AUTHORITY\SYSTEM : 0x0 : 0x0 : 0x1F01FF
S-1-5-18 : NT AUTHORITY\SYSTEM : 0x0 : 0xB : 0x10000000
S-1-5-11 : NT AUTHORITY\Authenticated Users : 0x0 : 0x0 : 0x1301BF
S-1-5-11 : NT AUTHORITY\Authenticated Users : 0x0 : 0xB : 0xE0010000
S-1-5-32-545 : BUILTIN\Users : 0x0 : 0x0 : 0x1200A9
S-1-5-32-545 : BUILTIN\Users : 0x0 : 0xB : 0xA0000000

Observe os ControlFlags e as ACEs duplicados.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top