2011-12-27 2 views
1

У меня есть один пользователь test.Как установить пароль при первом вызове команды из paramiko?

Я установил смену пароля при входе пользователя в систему с помощью команды chage.

chage -E 2012-01-25 -M 30 -d 0 -W 10 -I 5 test 

Так что, когда я пытаюсь запустить команду ls

[[email protected] ~]# ssh [email protected] "ls" 
WARNING: Your password has expired. 
Password change required but no TTY available. 
You have new mail in /var/spool/mail/root 

Тогда я пытаюсь соединиться с ssh

[[email protected] ~]# ssh [email protected] 
You are required to change your password immediately (root enforced) 
Last login: Tue Dec 27 09:55:55 2011 from localhost 
WARNING: Your password has expired. 
You must change your password now and login again! 
Changing password for user test. 
Changing password for test. 
(current) UNIX password: 

И чем я могу установить пароль для пользователя.

Если я попытаюсь установить соединение с paramiko.

In [1]: import paramiko 

In [2]: ssh_conn = paramiko.SSHClient() 

In [3]: ssh_conn.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 

In [4]: ssh_conn.load_system_host_keys() 

In [5]: ssh_conn.connect('n2001', username='root_acc23', password='test') 

In [6]: a = ssh_conn.exec_command('ls') 

In [7]: print a[2].read() 
WARNING: Your password has expired. 
Password change required but no TTY available. 

Тогда я немного Google и найти какое-то решение, чтобы установить новый пароль с invoke_shell шоу, которое я написал один функции

def chage_password_change(ssh_conn, password, curr_pass): 
    ''' 
    If got error on login then set with interactive mode. 
    ''' 
    interact = ssh_conn.invoke_shell() 
    buff = '' 
    while not buff.endswith('UNIX password: '): 
     resp = interact.recv(9999) 
     buff += resp 
    interact.send(curr_pass + '\n') 

    buff = '' 
    while not buff.endswith('New password: '): 
     resp = interact.recv(9999) 
     buff += resp 

    interact.send(password + '\n') 

    buff = '' 
    while not buff.endswith('Retype new password: '): 
     resp = interact.recv(9999) 
     buff += resp 

    interact.send(password + '\n') 


    interact.shutdown(2) 
    if interact.exit_status_ready(): 
     print "EXIT :", interact.recv_exit_status() 

    print "Last Password" 
    print "LST :", interact.recv(-1) 

Это работает в некоторых случаях, как, когда мы даем правильный пароль с цифрами, Alpa и специальная комбинация символов.

Но когда мы даем некоторый короткий пароль или ошибка происходит в изменении пароля, как этот

[[email protected] ~]# ssh [email protected] 
You are required to change your password immediately (root enforced) 
Last login: Tue Dec 27 10:41:15 2011 from localhost 
WARNING: Your password has expired. 
You must change your password now and login again! 
Changing password for user test. 
Changing password for test. 
(current) UNIX password: 
New password: 
Retype new password: 
BAD PASSWORD: it is too short 

В этой команде мы получили ошибку BAD PASSWORD: он слишком короткий Так что я не могу определить, в моей функции. Я получаю эту ошибку, когда я делаю interact.recv(-1), но это, как мне кажется, стандартный вывод. Итак, есть ли способ определить, что это ошибка.

Я проверяю документ paramiko и обнаруживаю, что класс Channel имеет некоторый метод recv_stderr_ready и recv_stderr, но эта ошибка не входит в эти данные.

Thx за вашу помощь заранее.

ответ

3

Простой ответ заключается в том, чтобы ваша функция проверяла длину пароля ДО того, как вы вызываете свою оболочку, если знаете, что такое отсечка. Лучшая производительность. Но если вы не знаете обреза, это не сработает.

Я не понимаю вашего описания, но если сообщение BAD PASSWORD возвращается из interactive.recv (-1), то вы знаете, что это произошло, и можете действовать соответствующим образом. Кажется, что он должен возвращаться из std err или stdout, поэтому проверьте оба. Если вы знаете, какой текст возвращается, если новый пароль был принят, вы также можете проверить это; в зависимости от того, что вы получите, сначала расскажет вам, что произошло, и ваша функция может продолжаться оттуда.

+2

Thx @ScottHunter за ответ. Я знаю, что ошибка может быть 2-3 возможных слов. Я хочу повысить ошибку, если я получаю вывод в stderr без проверки stdout. Если мне нужно проверить stdout и stderr на ошибку, тогда я должен проверять каждый раз в stdout. – Nilesh

+0

К сожалению, если stdout - это то, где написано сообщение об ошибке, вы должны его прочитать. Сожалею. –

+0

Okey Я прочитаю от STDOUT THX за вашу помощь. – Nilesh

1

Следующие строки могут быть проблематичным и может вызвать некоторые ошибки:

while not buff.endswith('Retype new password: '): 
     resp = interact.recv(9999) 
     buff += resp // this will append the output from the shell 

Исправление кода:

будет лучше использовать его таким образом

while not buff.endswith('Retype new password: '): 
    resp = interact.recv(9999) 
    buff = resp 

теперь каждую итерацию цикл, будет анализировать текущий \ обновленный, выводить текст из оболочки.

С уважением, Eldad

Смежные вопросы