transaction: Return errors wrapping pam.Error values on failure

If the transaction fails during start, there's no way to get the error
detail in a programmatic way, so let's wrap the pam.Error to allow more
per-type checks.
This commit is contained in:
Marco Trevisan (Treviño)
2023-09-25 13:44:45 +02:00
parent ea51cc0fe4
commit a5f5ad6470
2 changed files with 14 additions and 4 deletions

View File

@@ -22,7 +22,7 @@ package pam
import "C" import "C"
import ( import (
"errors" "fmt"
"runtime" "runtime"
"runtime/cgo" "runtime/cgo"
"strings" "strings"
@@ -164,7 +164,9 @@ func StartFunc(service, user string, handler func(Style, string) (string, error)
// transaction provides an interface to the remainder of the API. // transaction provides an interface to the remainder of the API.
func StartConfDir(service, user string, handler ConversationHandler, confDir string) (*Transaction, error) { func StartConfDir(service, user string, handler ConversationHandler, confDir string) (*Transaction, error) {
if !CheckPamHasStartConfdir() { if !CheckPamHasStartConfdir() {
return nil, errors.New("StartConfDir() was used, but the pam version on the system is not recent enough") return nil, fmt.Errorf(
"%w: StartConfDir was used, but the pam version on the system is not recent enough",
ErrSystem)
} }
return start(service, user, handler, confDir) return start(service, user, handler, confDir)
@@ -174,7 +176,8 @@ func start(service, user string, handler ConversationHandler, confDir string) (*
switch handler.(type) { switch handler.(type) {
case BinaryConversationHandler: case BinaryConversationHandler:
if !CheckPamHasBinaryProtocol() { if !CheckPamHasBinaryProtocol() {
return nil, errors.New("BinaryConversationHandler() was used, but it is not supported by this platform") return nil, fmt.Errorf("%w: BinaryConversationHandler was used, but it is not supported by this platform",
ErrSystem)
} }
} }
t := &Transaction{ t := &Transaction{
@@ -198,7 +201,7 @@ func start(service, user string, handler ConversationHandler, confDir string) (*
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 != success { if t.status != success {
return nil, t return nil, Error(t.status)
} }
return t, nil return t, nil
} }

View File

@@ -208,6 +208,13 @@ func TestPAM_ConfDir_FailNoServiceOrUnsupported(t *testing.T) {
if len(s) == 0 { if len(s) == 0 {
t.Fatalf("error #expected an error message") t.Fatalf("error #expected an error message")
} }
var pamErr Error
if !errors.As(err, &pamErr) {
t.Fatalf("error #unexpected type: %#v", err)
}
if pamErr != ErrAbort {
t.Fatalf("error #unexpected status: %v", pamErr)
}
} }
func TestPAM_ConfDir_InfoMessage(t *testing.T) { func TestPAM_ConfDir_InfoMessage(t *testing.T) {