diff options
author | Marco Trevisan (Treviño) <[email protected]> | 2023-09-22 16:59:03 +0200 |
---|---|---|
committer | Marco Trevisan (Treviño) <[email protected]> | 2023-11-30 01:16:39 +0100 |
commit | 6bb315c571d62ac8b55b6c088d02411ec5844cc1 (patch) | |
tree | 9d5481548ee8a6c0102022034a63e71192e03c8c | |
parent | 44c364e364c1eb5ccdfad3b11f574787152adbd2 (diff) |
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.
-rw-r--r-- | errors.go | 94 | ||||
-rw-r--r-- | transaction.go | 39 |
2 files changed, 115 insertions, 18 deletions
diff --git a/errors.go b/errors.go new file mode 100644 index 0000000..2f81a9a --- /dev/null +++ b/errors.go @@ -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))) +} diff --git a/transaction.go b/transaction.go index fcba3d5..1142fdc 100644 --- a/transaction.go +++ b/transaction.go @@ -29,6 +29,9 @@ import ( "unsafe" ) +// success indicates a successful function return. +const success = C.PAM_SUCCESS + // Style is the type of message that the conversation handler should display. 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 { bytes, err := cb.RespondPAMBinary(BinaryPointer(msg)) 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 case ConversationHandler: if style == BinaryPrompt { - return nil, C.PAM_AUTHINFO_UNAVAIL + return nil, C.int(ErrConv) } handler = cb } if handler == nil { - return nil, C.PAM_CONV_ERR + return nil, C.int(ErrConv) } r, err = handler.RespondPAM(style, C.GoString(msg)) 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. @@ -194,14 +197,14 @@ func start(service, user string, handler ConversationHandler, confDir string) (* defer C.free(unsafe.Pointer(c)) 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 t, nil } 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. @@ -232,7 +235,7 @@ func (t *Transaction) SetItem(i Item, item string) error { cs := unsafe.Pointer(C.CString(item)) defer C.free(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 nil @@ -242,7 +245,7 @@ func (t *Transaction) SetItem(i Item, item string) error { func (t *Transaction) GetItem(i Item) (string, error) { var s unsafe.Pointer 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 C.GoString((*C.char)(s)), nil @@ -281,7 +284,7 @@ const ( // Valid flags: Silent, DisallowNullAuthtok func (t *Transaction) Authenticate(f Flags) error { t.status = C.pam_authenticate(t.handle, C.int(f)) - if t.status != C.PAM_SUCCESS { + if t.status != success { return t } return nil @@ -293,7 +296,7 @@ func (t *Transaction) Authenticate(f Flags) error { // Valid flags: EstablishCred, DeleteCred, ReinitializeCred, RefreshCred func (t *Transaction) SetCred(f Flags) error { t.status = C.pam_setcred(t.handle, C.int(f)) - if t.status != C.PAM_SUCCESS { + if t.status != success { return t } return nil @@ -304,7 +307,7 @@ func (t *Transaction) SetCred(f Flags) error { // Valid flags: Silent, DisallowNullAuthtok func (t *Transaction) AcctMgmt(f Flags) error { t.status = C.pam_acct_mgmt(t.handle, C.int(f)) - if t.status != C.PAM_SUCCESS { + if t.status != success { return t } return nil @@ -315,7 +318,7 @@ func (t *Transaction) AcctMgmt(f Flags) error { // Valid flags: Silent, ChangeExpiredAuthtok func (t *Transaction) ChangeAuthTok(f Flags) error { t.status = C.pam_chauthtok(t.handle, C.int(f)) - if t.status != C.PAM_SUCCESS { + if t.status != success { return t } return nil @@ -326,7 +329,7 @@ func (t *Transaction) ChangeAuthTok(f Flags) error { // Valid flags: Slient func (t *Transaction) OpenSession(f Flags) error { t.status = C.pam_open_session(t.handle, C.int(f)) - if t.status != C.PAM_SUCCESS { + if t.status != success { return t } return nil @@ -337,7 +340,7 @@ func (t *Transaction) OpenSession(f Flags) error { // Valid flags: Silent func (t *Transaction) CloseSession(f Flags) error { t.status = C.pam_close_session(t.handle, C.int(f)) - if t.status != C.PAM_SUCCESS { + if t.status != success { return t } return nil @@ -352,7 +355,7 @@ func (t *Transaction) PutEnv(nameval string) error { cs := C.CString(nameval) defer C.free(unsafe.Pointer(cs)) t.status = C.pam_putenv(t.handle, cs) - if t.status != C.PAM_SUCCESS { + if t.status != success { return t } return nil @@ -378,7 +381,7 @@ func (t *Transaction) GetEnvList() (map[string]string, error) { env := make(map[string]string) p := C.pam_getenvlist(t.handle) if p == nil { - t.status = C.PAM_BUF_ERR + t.status = C.int(ErrBuf) return nil, t } for q := p; *q != nil; q = next(q) { |