Script de serviços de diretório sem senhas

1

Eu estou em um ambiente onde as informações do usuário / grupo são mantidas nos arquivos / etc / passwd e / etc / group, que são montados pelo NFS. Isso é bom porque podemos apenas editar arquivos simples para alterar as informações do usuário / grupo. No entanto, as máquinas do OS X em nossa configuração não gostam muito disso, porque o Directory Services não atende quando esses arquivos mudam.

Portanto, estou planejando configurar um cron job para executar algo assim uma vez por dia:

dsimport -g /etc/group /Local/Default O -T xDSStandardGroup -u $ADMIN_USER -p $ADMIN_PASS

O problema é esses dois últimos argumentos no final: usuário e senha. Eu quero evitar escrever senhas em scripts, para reduzir o risco deles serem comprometidos. Existe alguma maneira de usar dscl ou dsimport sem ter que fornecer uma senha, mas ao invés disso, eles devem simplesmente usar os privilégios do usuário executando o comando? (Você sabe, a maneira que todo comando Unix padrão faz.) Ou existe alguma outra maneira de realizar isso sem escrever senhas em texto puro?

    
por singingwolfboy 14.12.2009 / 22:08

1 resposta

1

Apenas navegando em minhas anotações no dscl, que eu escrevi bastante extensivamente. Tenho quase certeza de que a resposta é não, não há como evitar o fornecimento da senha. A única exceção pode ser se você fosse root na caixa local (que, no seu exemplo, parece ser o caso). [Eu praticamente fiz alterações na rede].

Se você usar espera ou pexpect , você pode codificar a senha em um script (de maneira reversível) e, em seguida, chamar o programa de que precisa. [Eu inventei um método para codificar / decodificar algo que se parece com gobbledygook, mas é a segurança através da obscuridade, eu tenho medo.]

Para usar pexpect, algo nesse sentido funcionaria [note que este exemplo usa dscl e não dsimport! (Eu imagino que poderia ser simplificado um pouco para o seu propósito; ligar o comando de registro para a criança dscl ajuda ao configurar as coisas)]:

#!/usr/bin/env python

import pexpect
# If you don't have pexpect, you should be able to run
# 'sudo easy_install pexpect' to get it

### Fill in these variables
diradmin = "diradmin"
host = "host"
directory = '/Local/Default'   # '/LDAPv3/127.0.0.1'
# Note: it is possible to encode the data here so it is not in plain text!
password = "password"

DSCL_PROMPT = " > " # Don't change this (unless the dscl tool changes)

def ReplyOnGoodResult(child, desired, reply):
    """Helps analyze the results as we try to set passwords.

    child = a pexpect child process
    desired = The value we hope to see 
    reply = text to send if we get the desired result (or None for no reply)
    If we do get the desired result, we send the reply and return true.
    If not, we return false."""

    expectations = [ pexpect.EOF, pexpect.TIMEOUT, '(?i)error', desired ]
    desired_index = len(expectations) - 1

    index = child.expect(expectations)
    if index == desired_index:
        if reply:
            child.sendline(reply)
        return True
    else:
        return False

def RunDSCLCommand(dscl_child, command):
    """Issues one dscl command; returns if it succeeded or failed.

    command = the command to be sent to dscl, such as 'passwd Users/foo newpword'   
    """

    assert dscl_child is not None, "No connection successfully established"

    # We should be logged in with a prompt awaiting us
    expected_list = [ pexpect.EOF, pexpect.TIMEOUT,
                     '(?i)error', 'Invalid Path', DSCL_PROMPT ]
    desired_index = len(expected_list) - 1
    invalid_path_index = desired_index - 1

    dscl_child.sendline(command)
    reply_index = dscl_child.expect(expected_list)
    if reply_index == desired_index:
        return True

    # Find the next prompt so that on the next call to a command like this
    # one, we will know we are at a consistent starting place
    # Looking at the self.dscl_child.before will likely contain
    # the error that occured, but for now:
    dscl_child.expect(DSCL_PROMPT)

    if invalid_path_is_success and reply_index == invalid_path_index:
        # The item doesn't exist, but we will still count it
        # as a success.  (Most likely we were told to delete the item).
        return True

    # one of the error conditions was triggered
    return False


# Here is the part of the program where we start doing things

prompt = DSCL_PROMPT

dscl_child = pexpect.spawn("dscl -u %s -p %s" % (diradmin, host))
#dscl_child.logfile = file("dscl_child.log", "w") # log what is going on

success = False

if (ReplyOnGoodResult(self.dscl_child, "Password:", password) and
   ReplyOnGoodResult(self.dscl_child, prompt, "cd %s" % directory) and
   ReplyOnGoodResult(self.dscl_child, prompt, "auth %s %s" % (diradmin, password)) and
   ReplyOnGoodResult(self.dscl_child, prompt, None)):
 success = True

if success:
 # Now issue a command
 success = RunDSCLCommand(dscl_child, 'passwd Users/foo newpword')

dscl_child.close()

Eu postei alguns dos códigos que estou usando aqui ; Temo que não seja suportado (e postado no grupo pymacadmin sobre isso aqui . Infelizmente, não parece que eu escrevi qualquer coisa sobre como usá-lo: (

    
por 14.12.2009 / 23:31