Назад | Перейти на главную страницу

марионеточное выполнение скрипта Python, когда команда os.system (…) не работает

Я пытаюсь управлять пользователями Unix с помощью марионетки. Puppet предоставляет достаточно инструментов для создания учетных записей и предоставления файлов authorized_keys, например, но не для установки пароля пользователя, и он сообщает пользователю.

Я сделал скрипт на Python, который генерирует случайный пароль и отправляет его пользователю по электронной почте. Проблема в том, что невозможно запустить команду passwd Unix с помощью python, я написал сценарий bash с командой:

echo -ne "$password\n$password\n" | passwd $user
passwd -e $user

Запущенный вручную скрипт работает нормально, а пароль созданному пользователю отправляется по электронной почте. Но когда марионетка запускает его, выполняется только сценарий python, как если бы os.system ('/ bin / bash my_bash_script') игнорировалась. Ошибка не отображается. И пользователь получает свой пароль, но команды passwd не запускаются.

Есть ли какие-либо ограничения с марионеткой, мешающие выполнять то, что я описал? Или как иначе я могу изменить учетную запись пользователя, срок ее действия и отправить пароль по электронной почте?

Я могу предоставить дополнительную информацию, но сейчас я не знаю, какая из них точна.

Большое спасибо!

РЕДАКТИРОВАТЬ: вот базовый код с такими же симптомами:

питон: setuserpassword.py

#!/usr/bin/python
import os
import sys

user = sys.argv[1]
mail = sys.argv[2]
os.system('/bin/bash /root/tools/setuserpassword.sh '+user+' '+mail)

bash: setuserpassword.sh

#!/bin/bash
# Password setup for the account
password=`pwgen -N1 --secure 10`
echo -ne "$password\n$password\n" | passwd $USER > /dev/null 2>&1
[[ $? -ne 0 ]] && exit 2

# Setup the expirancy label to make sure user
# change its password upon fist success login
chage -d0 $USER

# Email sending to inform user of his new password
echo -ne "Hello, $USER;\n
The password is:\n
$password\n" | mail -s "$USER account created" $MAIL

Вот модуль (с этой стороны проблем нет)

define add_user ( $email, $uid, $gid ) { 

$username = $title

user { $username:
  comment => "$email",
  home    => "/home/$username",
  shell   => "/bin/bash",
  uid     => $uid,
  gid     => $gid,
}   

exec { "/root/tools/setuserpassword.py $username $email":
   path           => "/bin:/usr/bin:/usr/sbin/sbin",
   refreshonly    => true,
   subscribe      => user[$username],
   onlyif         => "cat /etc/shadow | grep $username | grep '!'",
   require        => Package['pwgen'],
}   

Нет необходимости использовать bash-скрипт, просто используйте следующую функцию, которую я использую для других вещей, чтобы сгенерировать зашифрованный теневой пароль:

 def shadow(self,password):
  SomeZolt="$6$"+''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(9))+"$"
  return crypt.crypt(password, SomeZolt)

После этого напишите дополнительные функции в ваш скрипт python, который откроет файл / etc / shadow и запишет зашифрованный пароль, который вы получите с помощью этой функции для этого пользователя, таким образом сделав строку вроде:

some_user:!!:15579:0:99999:7:::

сделать вид:

some_user:$1$JShdquwdjsd38hSJhdqwdkwd:15579:0:99999:7:::

Таким образом some_user будет иметь назначенный пароль.
Кроме того, вы можете установить пользователя прямо в операторе марионетки, изменив его на:

user { $username:
  comment => "$email",
  home    => "/home/$username",
  shell   => "/bin/bash",
  uid     => $uid,
  gid     => $gid,
  password => "SomeAlreadyEncryptedPassword",
}   

Вы можете использовать указанную функцию, чтобы получить зашифрованный пароль, а затем вставить его в оператор.

Спасибо за ваш ответ, я последовал вашему совету и закодировал def для генерации хэша пароля и поместил его в файл / etc / shadow.

Вот сценарий, который я написал, если кому-то может быть интересно:

class Unix_Account:

 def __init__(self, user):
    self.user      = user
    self.password  = ''.join(
       random.choice(
          string.ascii_uppercase + string.ascii_lowercase + string.digits
       ) for x in range(password_length)
    )
    self.salt      = '$6$'+''.join(
       random.choice(string.ascii_uppercase + string.digits
    ) for x in range(9))+'$'
    self.line      = self.user+':'+crypt.crypt(self.password, self.salt)+':0:0:99999:7:::'

 def change_password(self):
    self.result = re.sub(self.user+".*", self.line, file('/etc/shadow', 'r').read())
    file('/etc/shadow', 'w').write(self.result)

Затем другой класс отправляет пароль пользователю.

Дата истечения срока действия пароля установлена ​​на 0, поэтому пользователь вынужден изменить его при первом подключении.

Подключение осуществляется по SSH, для установки пароля необходимо использовать соответствующий ключ. Пароль используется для команды sudo.

Еще раз спасибо!