transaction: Add PAM Error types Go definitions
And use them instead of C ones. Given that we have strings for them we can easily implement error interfaces for it too.
This commit is contained in:
94
errors.go
Normal file
94
errors.go
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
package pam
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <security/pam_appl.h>
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// Error is the Type for PAM Return types
|
||||||
|
type Error int
|
||||||
|
|
||||||
|
// Pam Return types
|
||||||
|
const (
|
||||||
|
// OpenErr indicates a dlopen() failure when dynamically loading a
|
||||||
|
// service module.
|
||||||
|
ErrOpen Error = C.PAM_OPEN_ERR
|
||||||
|
// ErrSymbol indicates a symbol not found.
|
||||||
|
ErrSymbol Error = C.PAM_SYMBOL_ERR
|
||||||
|
// ErrService indicates a error in service module.
|
||||||
|
ErrService Error = C.PAM_SERVICE_ERR
|
||||||
|
// ErrSystem indicates a system error.
|
||||||
|
ErrSystem Error = C.PAM_SYSTEM_ERR
|
||||||
|
// ErrBuf indicates a memory buffer error.
|
||||||
|
ErrBuf Error = C.PAM_BUF_ERR
|
||||||
|
// ErrPermDenied indicates a permission denied.
|
||||||
|
ErrPermDenied Error = C.PAM_PERM_DENIED
|
||||||
|
// ErrAuth indicates a authentication failure.
|
||||||
|
ErrAuth Error = C.PAM_AUTH_ERR
|
||||||
|
// ErrCredInsufficient indicates a can not access authentication data due to
|
||||||
|
// insufficient credentials.
|
||||||
|
ErrCredInsufficient Error = C.PAM_CRED_INSUFFICIENT
|
||||||
|
// ErrAuthinfoUnavail indicates that the underlying authentication service
|
||||||
|
// can not retrieve authentication information.
|
||||||
|
ErrAuthinfoUnavail Error = C.PAM_AUTHINFO_UNAVAIL
|
||||||
|
// ErrUserUnknown indicates a user not known to the underlying authentication
|
||||||
|
// module.
|
||||||
|
ErrUserUnknown Error = C.PAM_USER_UNKNOWN
|
||||||
|
// ErrMaxtries indicates that an authentication service has maintained a retry
|
||||||
|
// count which has been reached. No further retries should be attempted.
|
||||||
|
ErrMaxtries Error = C.PAM_MAXTRIES
|
||||||
|
// ErrNewAuthtokReqd indicates a new authentication token required. This is
|
||||||
|
// normally returned if the machine security policies require that the
|
||||||
|
// password should be changed because the password is nil or it has aged.
|
||||||
|
ErrNewAuthtokReqd Error = C.PAM_NEW_AUTHTOK_REQD
|
||||||
|
// ErrAcctExpired indicates that an user account has expired.
|
||||||
|
ErrAcctExpired Error = C.PAM_ACCT_EXPIRED
|
||||||
|
// ErrSession indicates a can not make/remove an entry for the
|
||||||
|
// specified session.
|
||||||
|
ErrSession Error = C.PAM_SESSION_ERR
|
||||||
|
// ErrCredUnavail indicates that an underlying authentication service can not
|
||||||
|
// retrieve user credentials.
|
||||||
|
ErrCredUnavail Error = C.PAM_CRED_UNAVAIL
|
||||||
|
// ErrCredExpired indicates that an user credentials expired.
|
||||||
|
ErrCredExpired Error = C.PAM_CRED_EXPIRED
|
||||||
|
// ErrCred indicates a failure setting user credentials.
|
||||||
|
ErrCred Error = C.PAM_CRED_ERR
|
||||||
|
// ErrNoModuleData indicates a no module specific data is present.
|
||||||
|
ErrNoModuleData Error = C.PAM_NO_MODULE_DATA
|
||||||
|
// ErrConv indicates a conversation error.
|
||||||
|
ErrConv Error = C.PAM_CONV_ERR
|
||||||
|
// ErrAuthtokErr indicates an authentication token manipulation error.
|
||||||
|
ErrAuthtok Error = C.PAM_AUTHTOK_ERR
|
||||||
|
// ErrAuthtokRecoveryErr indicates an authentication information cannot
|
||||||
|
// be recovered.
|
||||||
|
ErrAuthtokRecovery Error = C.PAM_AUTHTOK_RECOVERY_ERR
|
||||||
|
// ErrAuthtokLockBusy indicates am authentication token lock busy.
|
||||||
|
ErrAuthtokLockBusy Error = C.PAM_AUTHTOK_LOCK_BUSY
|
||||||
|
// ErrAuthtokDisableAging indicates an authentication token aging disabled.
|
||||||
|
ErrAuthtokDisableAging Error = C.PAM_AUTHTOK_DISABLE_AGING
|
||||||
|
// ErrTryAgain indicates a preliminary check by password service.
|
||||||
|
ErrTryAgain Error = C.PAM_TRY_AGAIN
|
||||||
|
// ErrIgnore indicates to ignore underlying account module regardless of
|
||||||
|
// whether the control flag is required, optional, or sufficient.
|
||||||
|
ErrIgnore Error = C.PAM_IGNORE
|
||||||
|
// ErrAbort indicates a critical error (module fail now request).
|
||||||
|
ErrAbort Error = C.PAM_ABORT
|
||||||
|
// ErrAuthtokExpired indicates an user's authentication token has expired.
|
||||||
|
ErrAuthtokExpired Error = C.PAM_AUTHTOK_EXPIRED
|
||||||
|
// ErrModuleUnknown indicates a module is not known.
|
||||||
|
ErrModuleUnknown Error = C.PAM_MODULE_UNKNOWN
|
||||||
|
// ErrBadItem indicates a bad item passed to pam_*_item().
|
||||||
|
ErrBadItem Error = C.PAM_BAD_ITEM
|
||||||
|
// ErrConvAgain indicates a conversation function is event driven and data
|
||||||
|
// is not available yet.
|
||||||
|
ErrConvAgain Error = C.PAM_CONV_AGAIN
|
||||||
|
// ErrIncomplete indicates to please call this function again to complete
|
||||||
|
// authentication stack. Before calling again, verify that conversation
|
||||||
|
// is completed.
|
||||||
|
ErrIncomplete Error = C.PAM_INCOMPLETE
|
||||||
|
)
|
||||||
|
|
||||||
|
// Error returns the error message for the given status.
|
||||||
|
func (status Error) Error() string {
|
||||||
|
return C.GoString(C.pam_strerror(nil, C.int(status)))
|
||||||
|
}
|
||||||
@@ -29,6 +29,9 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// success indicates a successful function return.
|
||||||
|
const success = C.PAM_SUCCESS
|
||||||
|
|
||||||
// Style is the type of message that the conversation handler should display.
|
// Style is the type of message that the conversation handler should display.
|
||||||
type Style int
|
type Style int
|
||||||
|
|
||||||
@@ -100,25 +103,25 @@ func cbPAMConv(s C.int, msg *C.char, c C.uintptr_t) (*C.char, C.int) {
|
|||||||
if style == BinaryPrompt {
|
if style == BinaryPrompt {
|
||||||
bytes, err := cb.RespondPAMBinary(BinaryPointer(msg))
|
bytes, err := cb.RespondPAMBinary(BinaryPointer(msg))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, C.PAM_CONV_ERR
|
return nil, C.int(ErrConv)
|
||||||
}
|
}
|
||||||
return (*C.char)(C.CBytes(bytes)), C.PAM_SUCCESS
|
return (*C.char)(C.CBytes(bytes)), success
|
||||||
}
|
}
|
||||||
handler = cb
|
handler = cb
|
||||||
case ConversationHandler:
|
case ConversationHandler:
|
||||||
if style == BinaryPrompt {
|
if style == BinaryPrompt {
|
||||||
return nil, C.PAM_AUTHINFO_UNAVAIL
|
return nil, C.int(ErrConv)
|
||||||
}
|
}
|
||||||
handler = cb
|
handler = cb
|
||||||
}
|
}
|
||||||
if handler == nil {
|
if handler == nil {
|
||||||
return nil, C.PAM_CONV_ERR
|
return nil, C.int(ErrConv)
|
||||||
}
|
}
|
||||||
r, err = handler.RespondPAM(style, C.GoString(msg))
|
r, err = handler.RespondPAM(style, C.GoString(msg))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, C.PAM_CONV_ERR
|
return nil, C.int(ErrConv)
|
||||||
}
|
}
|
||||||
return C.CString(r), C.PAM_SUCCESS
|
return C.CString(r), success
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transaction is the application's handle for a PAM transaction.
|
// Transaction is the application's handle for a PAM transaction.
|
||||||
@@ -194,14 +197,14 @@ func start(service, user string, handler ConversationHandler, confDir string) (*
|
|||||||
defer C.free(unsafe.Pointer(c))
|
defer C.free(unsafe.Pointer(c))
|
||||||
t.status = C.pam_start_confdir(s, u, t.conv, c, &t.handle)
|
t.status = C.pam_start_confdir(s, u, t.conv, c, &t.handle)
|
||||||
}
|
}
|
||||||
if t.status != C.PAM_SUCCESS {
|
if t.status != success {
|
||||||
return nil, t
|
return nil, t
|
||||||
}
|
}
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transaction) Error() string {
|
func (t *Transaction) Error() string {
|
||||||
return C.GoString(C.pam_strerror(t.handle, t.status))
|
return Error(t.status).Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Item is a an PAM information type.
|
// Item is a an PAM information type.
|
||||||
@@ -232,7 +235,7 @@ func (t *Transaction) SetItem(i Item, item string) error {
|
|||||||
cs := unsafe.Pointer(C.CString(item))
|
cs := unsafe.Pointer(C.CString(item))
|
||||||
defer C.free(cs)
|
defer C.free(cs)
|
||||||
t.status = C.pam_set_item(t.handle, C.int(i), cs)
|
t.status = C.pam_set_item(t.handle, C.int(i), cs)
|
||||||
if t.status != C.PAM_SUCCESS {
|
if t.status != success {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -242,7 +245,7 @@ func (t *Transaction) SetItem(i Item, item string) error {
|
|||||||
func (t *Transaction) GetItem(i Item) (string, error) {
|
func (t *Transaction) GetItem(i Item) (string, error) {
|
||||||
var s unsafe.Pointer
|
var s unsafe.Pointer
|
||||||
t.status = C.pam_get_item(t.handle, C.int(i), &s)
|
t.status = C.pam_get_item(t.handle, C.int(i), &s)
|
||||||
if t.status != C.PAM_SUCCESS {
|
if t.status != success {
|
||||||
return "", t
|
return "", t
|
||||||
}
|
}
|
||||||
return C.GoString((*C.char)(s)), nil
|
return C.GoString((*C.char)(s)), nil
|
||||||
@@ -281,7 +284,7 @@ const (
|
|||||||
// Valid flags: Silent, DisallowNullAuthtok
|
// Valid flags: Silent, DisallowNullAuthtok
|
||||||
func (t *Transaction) Authenticate(f Flags) error {
|
func (t *Transaction) Authenticate(f Flags) error {
|
||||||
t.status = C.pam_authenticate(t.handle, C.int(f))
|
t.status = C.pam_authenticate(t.handle, C.int(f))
|
||||||
if t.status != C.PAM_SUCCESS {
|
if t.status != success {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -293,7 +296,7 @@ func (t *Transaction) Authenticate(f Flags) error {
|
|||||||
// Valid flags: EstablishCred, DeleteCred, ReinitializeCred, RefreshCred
|
// Valid flags: EstablishCred, DeleteCred, ReinitializeCred, RefreshCred
|
||||||
func (t *Transaction) SetCred(f Flags) error {
|
func (t *Transaction) SetCred(f Flags) error {
|
||||||
t.status = C.pam_setcred(t.handle, C.int(f))
|
t.status = C.pam_setcred(t.handle, C.int(f))
|
||||||
if t.status != C.PAM_SUCCESS {
|
if t.status != success {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -304,7 +307,7 @@ func (t *Transaction) SetCred(f Flags) error {
|
|||||||
// Valid flags: Silent, DisallowNullAuthtok
|
// Valid flags: Silent, DisallowNullAuthtok
|
||||||
func (t *Transaction) AcctMgmt(f Flags) error {
|
func (t *Transaction) AcctMgmt(f Flags) error {
|
||||||
t.status = C.pam_acct_mgmt(t.handle, C.int(f))
|
t.status = C.pam_acct_mgmt(t.handle, C.int(f))
|
||||||
if t.status != C.PAM_SUCCESS {
|
if t.status != success {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -315,7 +318,7 @@ func (t *Transaction) AcctMgmt(f Flags) error {
|
|||||||
// Valid flags: Silent, ChangeExpiredAuthtok
|
// Valid flags: Silent, ChangeExpiredAuthtok
|
||||||
func (t *Transaction) ChangeAuthTok(f Flags) error {
|
func (t *Transaction) ChangeAuthTok(f Flags) error {
|
||||||
t.status = C.pam_chauthtok(t.handle, C.int(f))
|
t.status = C.pam_chauthtok(t.handle, C.int(f))
|
||||||
if t.status != C.PAM_SUCCESS {
|
if t.status != success {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -326,7 +329,7 @@ func (t *Transaction) ChangeAuthTok(f Flags) error {
|
|||||||
// Valid flags: Slient
|
// Valid flags: Slient
|
||||||
func (t *Transaction) OpenSession(f Flags) error {
|
func (t *Transaction) OpenSession(f Flags) error {
|
||||||
t.status = C.pam_open_session(t.handle, C.int(f))
|
t.status = C.pam_open_session(t.handle, C.int(f))
|
||||||
if t.status != C.PAM_SUCCESS {
|
if t.status != success {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -337,7 +340,7 @@ func (t *Transaction) OpenSession(f Flags) error {
|
|||||||
// Valid flags: Silent
|
// Valid flags: Silent
|
||||||
func (t *Transaction) CloseSession(f Flags) error {
|
func (t *Transaction) CloseSession(f Flags) error {
|
||||||
t.status = C.pam_close_session(t.handle, C.int(f))
|
t.status = C.pam_close_session(t.handle, C.int(f))
|
||||||
if t.status != C.PAM_SUCCESS {
|
if t.status != success {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -352,7 +355,7 @@ func (t *Transaction) PutEnv(nameval string) error {
|
|||||||
cs := C.CString(nameval)
|
cs := C.CString(nameval)
|
||||||
defer C.free(unsafe.Pointer(cs))
|
defer C.free(unsafe.Pointer(cs))
|
||||||
t.status = C.pam_putenv(t.handle, cs)
|
t.status = C.pam_putenv(t.handle, cs)
|
||||||
if t.status != C.PAM_SUCCESS {
|
if t.status != success {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -378,7 +381,7 @@ func (t *Transaction) GetEnvList() (map[string]string, error) {
|
|||||||
env := make(map[string]string)
|
env := make(map[string]string)
|
||||||
p := C.pam_getenvlist(t.handle)
|
p := C.pam_getenvlist(t.handle)
|
||||||
if p == nil {
|
if p == nil {
|
||||||
t.status = C.PAM_BUF_ERR
|
t.status = C.int(ErrBuf)
|
||||||
return nil, t
|
return nil, t
|
||||||
}
|
}
|
||||||
for q := p; *q != nil; q = next(q) {
|
for q := p; *q != nil; q = next(q) {
|
||||||
|
|||||||
Reference in New Issue
Block a user