A PAM module scriptable using Lua
A PAM module scriptable using Lua.
make lua=5.1
Set 5.1
to whatever Lua version you want to use, according to pkg-config, 5.1
/-5.1
for Lua 5.1, jit
for luajit, etc…
pam_lua.so
to /lib/security
or alternative for wherever your distribution wants PAM modules to reside in./usr/lib
.
if pam.handler == "authenticate" then
local username = pam.get_user()
local password = pam.readline("Password: ", false) -- password prompt with hidden input
if username == "user" and password == "letmein" then
return pam.ret.success -- correct credentials, allow login!
end
return pam.ret.perm_denied
else -- not authenticate
return pam.ret.ignore -- ignore this handler, cause it doesn't apply.
end
pam_lua.so
, say auth sufficient pam_lua.so script=/path/to/script.lua
A dynamic MOTD generator I made is here: motd.lua.
It ain’t the prettiest code-wise, but it does the job. Ships with Clippy!
pam.type
auth
account
session
password
pam.handler
setcred
authenticate
acc_mgnt
open_session
close_session
chauthtok
authenticate
.active = pam.flag[name]
silent
: If the service should not generate any messages.authenticate
:disallow_null_authtok
: If the service should return pam.ret.auth_error
when the auth token is null.setcred
:establish_cred
: set credentialsdelete_cred
: delete credentialsreinitialize_cred
: reinitialize credentials, like resetting passwordrefresh_cred
: extend lifetime of credentialschauthtok
:change_expired_authtok
: only update those passwords if they have aged, otherwise update them unconditionally.user = pam.get_user([login_prompt])
input[, failure_code] = pam.readline(prompt[, visible])
visible
is false
then the input is hidden.nil, error_code
, which is the numerical representation of a PAM error.return_code = pam.info(text)
return_code = pam.error(text)
textual_return_code = pam.code[numerical_return_code]
numerical_return_code = pam.ret[textual_return_code]
"ignore"
: Skip handler."success"
: Success, allow login/go to next handler."perm_denied"
: Permission denied, drop out if handler is required."abort"
: Abort."try_again"
: Try again!value = pam.getenv(key)
return_code = pam.setenv(key[, value])
key
will be deleted instead of set.Make sure to return a return code, like pam.ret.success
or pam.ret.perm_denied
.
If you do not plan to do anything in a specific PAM hook, return pam.ret.ignore
.
MIT