summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan (Treviño) <[email protected]>2023-09-22 16:59:03 +0200
committerMarco Trevisan (Treviño) <[email protected]>2023-11-30 01:16:39 +0100
commit6bb315c571d62ac8b55b6c088d02411ec5844cc1 (patch)
tree9d5481548ee8a6c0102022034a63e71192e03c8c
parent44c364e364c1eb5ccdfad3b11f574787152adbd2 (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.go94
-rw-r--r--transaction.go39
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) {