TIPS & TRICKS

Scripted auth in preview

Hey Kids,

How are things? so I’ve made some progress in my attempt to code myself out of a job. Just checked the scripted auth into the preview branch which should be released in a few days. It’s very basic right now with more improvements to come. At the moment userLogin, getUserType and getUserInfo are the only methods you need to fill in.

I’ve written up a sample that interfaces with PAM on the linux, using /etc/passwd to get user lists. Mac users skip the pamauth.c compile you don’t need this app and pam don’t like macs ( can’t say I blame pam on that score)

First off a pamauth.c program to compile that will talk to pam for ya. Donated by Phillppe Troin, thank you fif. Feel free to take and edit for your own purposes, but you must send fif a chocolate chip cookie if you found it useful.

File pamauth.c is attach due to severe lameness on part of wordpress, insisting on screwing with the #include’s

pamauth.c

Compile that puppy like so
gcc -Wall -Wextra -o pamauth pamauth.c -lpam

You may need to create an entry for pam
edit /etc/pam.d/pamauth and put this line in
auth sufficient pam_unix.so

To access pam root access is usually required so we will just set the pamauth script setuid instead of running splunk as root (which would be deeply stupid BTW).

as root:
chown root.root pamauth; chmod a+s pamauth

You can test it by doing echo PASSWORD | ./pamauth username
returns 0 for auth passed
returns 1 on fail.

K now that you have your nifty pam app running you need to add your python script that will interface
with splunk. As they say on cooking shows, here’s one we made earlier.

# Required functions;
# 1. userLogin : login with username password pair
# 2. getUserInfo : get user information. passed back in the form.userId;username;password;realname;userType
# 3. getUserType : the splunk role to attach that user to.
# optional functions
# 1. getUsers : Enumerate all users in the system, these will then be displayed on the user page in splunk.
# Later release
# 1. checkSession : Current version just auths and then splunk managed the session, this will allow
# session management to be handled here. Careful though splunkd and the frontend
# are quite chatty this will be called alot. If it’s slow it will degrade performance.

import sys
import subprocess

SUCCESS = “success”
FAILED = “fail”

PAM_EXE = “”

def writeToStdout( listIn ):
result = “”
for fu in listIn:
result = result + “[” + fu + “]”

sys.stdout.write( result )

def readFromStdin( ):
input = sys.stdin

inStr = “”
for line in input:
inStr = inStr + line

inStr = inStr.replace( “[“, “” )
return inStr.split( ‘]’ )

def userLogin( infoIn ):
listFu = []
username = infoIn[0]
password = infoIn[1]

command = PAM_EXE + infoIn[0]

# our check with pam is done with a setuid program called pamauth
proc = subprocess.Popen( PAM_EXE + ‘ %s’ % username,
shell=True,
stdin=subprocess.PIPE,
)
proc.communicate( password)
retCode = proc.wait()

if retCode == 0:
listFu.append( SUCCESS )
else:
listFu.append( FAILED )

return listFu

def getUsers( infoIn ):
listFu = []
listFu.append( SUCCESS )
# just going to use /etc/passwd here but you may use any method you wish.
FILE = open(“/etc/passwd” ,”r”)
fileLines = FILE.readlines()

for line in fileLines:
userBits = line.split( “:” )
if userBits[6].find( ‘/bin/bash’ ) != -1:
realname = userBits[4]
if realname == “” :
realname = userBits[0]
# userId username password realName userType/splunk role
listFu.append( userBits[2] + “;” +userBits[0] + “;***********;” + realname + “;Admin” )

FILE.close()

return listFu

# IN UserId
# OUT [RESULT(SUCCESS|FAILED)][userType]
def getUserType( infoIn ):
# Here you are given a userId
# you must return the user type (splunk role)
# I’m just going to make everyone an admin.
listFu = []
listFu.append( SUCCESS )
listFu.append( “Admin” )
return listFu

def getUserInfo( infoIn ):
listFu = []
listFu.append( SUCCESS )
#userId;
listFu.append( infoIn[0] + “;” + infoIn[0] + “;***********;” + infoIn[0] + “;Admin” )
return listFu

if __name__ == “__main__”:
callName = sys.argv[1]
listIn = []
listIn = readFromStdin( )

returnList = []
if callName == “userLogin”:
returnList = userLogin( listIn )
elif callName == “checkSession”:
returnList = checkSession( listIn )
elif callName == “getUsers”:
returnList = getUsers( listIn )
elif callName == “getUserType”:
returnList = getUserType( listIn )
elif callName == “getUserInfo”:
returnList = getUserInfo( listIn )
else:
returnList.append(“ERROR call name no known” )
returnList.append( callName )

writeToStdout( returnList )

Change the PAM_EXE variable in the script to point to the app that will check the password. On linux : the pamauth module you just compiled. On Mac (the piano-accordion of computers): use chkpasswd program shipped with mac.

Now that you have a script auth plugin ready to go all you need to do now is tell splunk about it.

Example of the authentication.conf bundle.

[auth]
authSettings = fubar
authType = Scripted

[fubar]
programPath = /opt/splunk/bin/python
scriptPath = /home/boo/splunk/scriptedAuth/flubber.py   # my python auth script.

Now pay attention here you do need to edit programPath and scriptPath to paths on your system.

Things left to do.
1. Allow users to pass back search filters on userLogin and getUserType.
2. Allow session management to be handled by scripted input. ( right not once auth is confirmed as correct splunk takes over session management).

Also this script will not return user lists on the mac ( not big deal you just can’t see all users in the admin/users tab ). Erik Swan has volunteered to fix this because he loves macs, a little too much really it’s kinda unhealthy.

Download this and play with it, let me know of any problems.

I will publish more details on the communication between splunkd and the script but for the moment you folks can reverse engineer this, it’s pretty simple, a lame wilder beast could figure it out.

More later, for now it’s time for beer pong, played for cold hard cash and ugly women.

by Rory Greene

Splunk
Posted by

Splunk