External Authentication

I would like to authenticate users with an external authentication script written in Python. Is it possible? If it is, what are the arguments (argv) passed to the script and what should the script return (exit code).

I've looked everywhere for documentation on this but I can't find any. I've read the example perl script but can't really understand it. Could anybody please help me on this. Cheers.

External Authentication

It looks like the external script does the following:

- Accepts an optional single argument of the domain, i'm not sure in what instance this
argument is passed... it appears that ejabberd calls it without args so I'm not sure
why that's in the script.

- Takes, as standard in, the following:
AABBBBBBBBB.....
A. 2 bytes of length data (a short in network byte order)
B. a string of length found in A that contains:
operation code:username:password
all in plain text

operation codes are as follows:
auth: check if a username/password pair is correct
setpass: set user's password
isuser: check if it's a valid user

- External script/command is then expected to write to standard out two shorts in
network byte order:
AABB
AA: the number 2 (i imagine this is the length in bytes of the result code)
BB: the result code, should be 1 for success/valid, or 0 for failure/invalid

- Script is also expected to run indefinitely apparantly, answering 'infinite' requests.

Does that help any?

External Auth Args

Looks like you can simply specify external args in ejabberd.cfg: Ie:
myscript arg1 arg2 arg3
So args are completely up to you.
(thanks to teo for pointing that out)

External Authentication - password passed in for isuser()?

Thanks for the great help. I'm working on an ntlm authentication in python right now and I need a bit more information.

As you were saying:
operation code:username:password
all in plain text

operation codes are as follows:
auth: check if a username/password pair is correct
setpass: set user's password
isuser: check if it's a valid user

I'm pretty sure the username is passed with all operations but how about the password? Is is passed in for the isuser operation?

Re: Externel Authentication - password passed in for isuser()?

I'm afraid I really don't know. I would say just give it a whirl, watch some debug output, and see if it is passed.

External Authentication(NTLM) in python.

Hi there guys, thanks for the explaination. But I still can't really get it. I've written the code for the three operations, can anybody help me with the stdin, stdout stuff?

#!/usr/bin/env python

import win32api
import win32con
import win32security
import win32net
import win32netcon

def auth(usr, pwd, domain, verb=0):
""" Authenticates user credentials to a Windows domain.
    usr - account username.
    pwd - account password.
    dom - windows domain name.
    verb - (verbose) flag to print out informative messages.
"""
    try:
        htoken = win32security.LogonUser(
        usr, domain, pwd, win32security.LOGON32_LOGON_NETWORK,
            win32security.LOGON32_PROVIDER_DEFAULT)
    except win32security.error, err:
        if verb: print err
        return
    else:
        if htoken: return 1

def isuser(usr, dc, verb=0):
""" Checks user validity in the domain. Localhost must be part of             domain.
usr - account username.
dc - domain controller netbios name.
verb - (verbose) flag to print out informative messages.
"""
server = ''.join(['\\\\', dc])
resume = 'init'
userlist = []
while resume:
if resume == 'init': resume = 0
try:
users, total, resume = win32net.NetUserEnum(
server, 0, win32netcon.FILTER_NORMAL_ACCOUNT
, 0)
except win32net.error, err:
if verb: print err
return
else:
userlist += users
for userinfo in userlist:
if usr.lower() == str(userinfo['name']).lower():
return 1

def setpass(usr, oldpwd, newpwd, domain, dc=None, verb=0):
""" Changes the password for the specified user.
usr - account username.
oldpwd - old password.
newpwd - new password
domain - windows domain.
dc - domain controller netbios name.
verb - (verbose) flag to print out informative messages.
"""
# Get the domain controller netbios name if not provided.
if not dc:
try:
dc = win32net.NetGetAnyDCName(None, domain)
except win32net.error, err:
# Authenticate against the computer's SAM database if not found.
dc = domain

# SE_CHANGE_NOTIFY_NAME privilege must be enabled for non-system accounts.
p = win32security.LookupPrivilegeValue(dc, win32con.SE_CHANGE_NOTIFY_NAME)
newstate = [(p, win32con.SE_PRIVILEGE_ENABLED)]
# Grab the process token and adjust its privileges.

htoken = win32security.OpenProcessToken(
win32api.GetCurrentProcess(), win32con.TOKEN_ALL_ACCESS)
win32security.AdjustTokenPrivileges(htoken, False, newstate)

# Let's change passwords.
server = ''.join(['\\\\', dc])
try:
print win32net.NetUserChangePassword(server, usr, oldpwd, newpwd)
except win32net.error, err:
if verb: print err
return
else:
return 1
Syndicate content