Использование pam_python в скрипте, работающем с mod_python - PullRequest
2 голосов
/ 02 апреля 2010

Я хотел бы разработать веб-интерфейс, позволяющий пользователям системы Linux выполнять определенные задачи, связанные с их учетной записью. Я решил написать бэкэнд сайта, используя Python и mod_python для Apache. Для аутентификации пользователей я подумал, что мог бы использовать python_pam для запроса службы PAM. Я адаптировал пример в комплекте с модулем и получил это:

# out is the output stream used to print debug
def auth(username, password, out):
    def pam_conv(aut, query_list, user_data):
        out.write("Query list: " + str(query_list) + "\n")

        # List to store the responses to the different queries
        resp = []

        for item in query_list:
            query, qtype = item

            # If PAM asks for an input, give the password
            if qtype == PAM.PAM_PROMPT_ECHO_ON or qtype == PAM.PAM_PROMPT_ECHO_OFF:
                resp.append((str(password), 0))

            elif qtype == PAM.PAM_PROMPT_ERROR_MSG or qtype == PAM.PAM_PROMPT_TEXT_INFO:
                resp.append(('', 0))

        out.write("Our response: " + str(resp) + "\n")
        return resp

    # If username of password is undefined, fail
    if username is None or password is None:
        return False

    service = 'login'
    pam_ = PAM.pam()
    pam_.start(service)

    # Set the username
    pam_.set_item(PAM.PAM_USER, str(username))

    # Set the conversation callback
    pam_.set_item(PAM.PAM_CONV, pam_conv)

    try:
        pam_.authenticate()
        pam_.acct_mgmt()
    except PAM.error, resp:
        out.write("Error: " + str(resp) + "\n")
        return False
    except:
        return False

    # If we get here, the authentication worked
    return True 

Моя проблема в том, что эта функция не ведет себя одинаково, использую ли я ее в простом скрипте или через mod_python. Чтобы проиллюстрировать это, я написал следующие простые случаи:

my_username = "markys"
my_good_password = "lalala"
my_bad_password = "lololo"

def handler(req):
 req.content_type = "text/plain"
 req.write("1- " + str(auth(my_username,my_good_password,req) + "\n"))
 req.write("2- " + str(auth(my_username,my_bad_password,req) + "\n"))
 return apache.OK

if __name__ == "__main__":
 print "1- " + str(auth(my_username,my_good_password,sys.__stdout__))
 print "2- " + str(auth(my_username,my_bad_password,sys.__stdout__))

Результат из сценария:

Query list: [('Password: ', 1)]
Our response: [('lalala', 0)]
1- True
Query list: [('Password: ', 1)]
Our response: [('lololo', 0)]
Error: ('Authentication failure', 7)
2- False

но результат от mod_python:

Query list: [('Password: ', 1)]
Our response: [('lalala', 0)]
Error: ('Authentication failure', 7)
1- False
Query list: [('Password: ', 1)]
Our response: [('lololo', 0)]
Error: ('Authentication failure', 7)
2- False

Я не понимаю, почему функция auth не возвращает одинаковое значение при одинаковых входах. Есть идеи, где я понял это неправильно? Здесь - это оригинальный скрипт, если это могло бы вам помочь.

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

РЕДАКТИРОВАТЬ: Хорошо, я нашел ошибку. Я запускал скрипт от имени пользователя root. mod_python запускал скрипт как пользователь веб-сервера. Только root имеет право читать тени. Я не уверен, как мне обойти это, но, по крайней мере, теперь я знаю, в чем проблема!

1 Ответ

0 голосов
/ 03 апреля 2010

Похоже, вам нужно разрешить Apache использовать PAM-аутентификацию. Взгляните на этот сайт: http://www.debianhelp.co.uk/apachepam.htm

Возможно, вы захотите взглянуть и на этот сайт: http://inming.net/?p=86

...