transaction: Move PAM app side function only to app-transaction
In this way all these features not even compiled when creating modules, avoiding generating unused code.
This commit is contained in:
@@ -3,12 +3,46 @@
|
|||||||
package pam
|
package pam
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include <security/pam_appl.h>
|
#include "transaction.h"
|
||||||
#include <stdint.h>
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import "runtime/cgo"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime/cgo"
|
||||||
|
"sync/atomic"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ConversationHandler is an interface for objects that can be used as
|
||||||
|
// conversation callbacks during PAM authentication.
|
||||||
|
type ConversationHandler interface {
|
||||||
|
// RespondPAM receives a message style and a message string. If the
|
||||||
|
// message Style is PromptEchoOff or PromptEchoOn then the function
|
||||||
|
// should return a response string.
|
||||||
|
RespondPAM(Style, string) (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BinaryConversationHandler is an interface for objects that can be used as
|
||||||
|
// conversation callbacks during PAM authentication if binary protocol is going
|
||||||
|
// to be supported.
|
||||||
|
type BinaryConversationHandler interface {
|
||||||
|
ConversationHandler
|
||||||
|
// RespondPAMBinary receives a pointer to the binary message. It's up to
|
||||||
|
// the receiver to parse it according to the protocol specifications.
|
||||||
|
// The function can return a byte array that will passed as pointer back
|
||||||
|
// to the module.
|
||||||
|
RespondPAMBinary(BinaryPointer) ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConversationFunc is an adapter to allow the use of ordinary functions as
|
||||||
|
// conversation callbacks.
|
||||||
|
type ConversationFunc func(Style, string) (string, error)
|
||||||
|
|
||||||
|
// RespondPAM is a conversation callback adapter.
|
||||||
|
func (f ConversationFunc) RespondPAM(s Style, msg string) (string, error) {
|
||||||
|
return f(s, msg)
|
||||||
|
}
|
||||||
|
|
||||||
// _go_pam_conv_handler is a C wrapper for the conversation callback function.
|
// _go_pam_conv_handler is a C wrapper for the conversation callback function.
|
||||||
//
|
//
|
||||||
@@ -22,3 +56,181 @@ func _go_pam_conv_handler(msg *C.struct_pam_message, c C.uintptr_t, outMsg **C.c
|
|||||||
*outMsg = replyMsg
|
*outMsg = replyMsg
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pamConvHandler is a Go wrapper for the conversation callback function.
|
||||||
|
func pamConvHandler(style Style, msg *C.char, handler ConversationHandler) (*C.char, C.int) {
|
||||||
|
var r string
|
||||||
|
var err error
|
||||||
|
switch cb := handler.(type) {
|
||||||
|
case BinaryConversationHandler:
|
||||||
|
if style == BinaryPrompt {
|
||||||
|
bytes, err := cb.RespondPAMBinary(BinaryPointer(msg))
|
||||||
|
if err != nil {
|
||||||
|
return nil, C.int(ErrConv)
|
||||||
|
}
|
||||||
|
if bytes == nil {
|
||||||
|
return nil, success
|
||||||
|
}
|
||||||
|
return (*C.char)(C.CBytes(bytes)), success
|
||||||
|
}
|
||||||
|
handler = cb
|
||||||
|
case ConversationHandler:
|
||||||
|
if style == BinaryPrompt {
|
||||||
|
return nil, C.int(ErrConv)
|
||||||
|
}
|
||||||
|
handler = cb
|
||||||
|
default:
|
||||||
|
return nil, C.int(ErrConv)
|
||||||
|
}
|
||||||
|
r, err = handler.RespondPAM(style, C.GoString(msg))
|
||||||
|
if err != nil {
|
||||||
|
return nil, C.int(ErrConv)
|
||||||
|
}
|
||||||
|
return C.CString(r), success
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transaction is the application's handle for a PAM transaction.
|
||||||
|
type Transaction struct {
|
||||||
|
transactionBase
|
||||||
|
|
||||||
|
conv *C.struct_pam_conv
|
||||||
|
c cgo.Handle
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start initiates a new PAM transaction. Service is treated identically to
|
||||||
|
// how pam_start treats it internally.
|
||||||
|
//
|
||||||
|
// All application calls to PAM begin with Start*. The returned
|
||||||
|
// transaction provides an interface to the remainder of the API.
|
||||||
|
//
|
||||||
|
// It's responsibility of the Transaction owner to release all the resources
|
||||||
|
// allocated underneath by PAM by calling End() once done.
|
||||||
|
//
|
||||||
|
// It's not advised to End the transaction using a runtime.SetFinalizer unless
|
||||||
|
// you're absolutely sure that your stack is multi-thread friendly (normally it
|
||||||
|
// is not!) and using a LockOSThread/UnlockOSThread pair.
|
||||||
|
func Start(service, user string, handler ConversationHandler) (*Transaction, error) {
|
||||||
|
return start(service, user, handler, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartFunc registers the handler func as a conversation handler and starts
|
||||||
|
// the transaction (see Start() documentation).
|
||||||
|
func StartFunc(service, user string, handler func(Style, string) (string, error)) (*Transaction, error) {
|
||||||
|
return start(service, user, ConversationFunc(handler), "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartConfDir initiates a new PAM transaction. Service is treated identically to
|
||||||
|
// how pam_start treats it internally.
|
||||||
|
// confdir allows to define where all pam services are defined. This is used to provide
|
||||||
|
// custom paths for tests.
|
||||||
|
//
|
||||||
|
// All application calls to PAM begin with Start*. The returned
|
||||||
|
// transaction provides an interface to the remainder of the API.
|
||||||
|
//
|
||||||
|
// It's responsibility of the Transaction owner to release all the resources
|
||||||
|
// allocated underneath by PAM by calling End() once done.
|
||||||
|
//
|
||||||
|
// It's not advised to End the transaction using a runtime.SetFinalizer unless
|
||||||
|
// you're absolutely sure that your stack is multi-thread friendly (normally it
|
||||||
|
// is not!) and using a LockOSThread/UnlockOSThread pair.
|
||||||
|
func StartConfDir(service, user string, handler ConversationHandler, confDir string) (*Transaction, error) {
|
||||||
|
if !CheckPamHasStartConfdir() {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
func start(service, user string, handler ConversationHandler, confDir string) (*Transaction, error) {
|
||||||
|
switch handler.(type) {
|
||||||
|
case BinaryConversationHandler:
|
||||||
|
if !CheckPamHasBinaryProtocol() {
|
||||||
|
return nil, fmt.Errorf("%w: BinaryConversationHandler was used, but it is not supported by this platform",
|
||||||
|
ErrSystem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t := &Transaction{
|
||||||
|
conv: &C.struct_pam_conv{},
|
||||||
|
c: cgo.NewHandle(handler),
|
||||||
|
}
|
||||||
|
|
||||||
|
C.init_pam_conv(t.conv, C.uintptr_t(t.c))
|
||||||
|
s := C.CString(service)
|
||||||
|
defer C.free(unsafe.Pointer(s))
|
||||||
|
var u *C.char
|
||||||
|
if len(user) != 0 {
|
||||||
|
u = C.CString(user)
|
||||||
|
defer C.free(unsafe.Pointer(u))
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
if confDir == "" {
|
||||||
|
err = t.handlePamStatus(C.pam_start(s, u, t.conv, &t.handle))
|
||||||
|
} else {
|
||||||
|
c := C.CString(confDir)
|
||||||
|
defer C.free(unsafe.Pointer(c))
|
||||||
|
err = t.handlePamStatus(C.pam_start_confdir(s, u, t.conv, c, &t.handle))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
var _ = t.End()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Authenticate is used to authenticate the user.
|
||||||
|
//
|
||||||
|
// Valid flags: Silent, DisallowNullAuthtok
|
||||||
|
func (t *Transaction) Authenticate(f Flags) error {
|
||||||
|
return t.handlePamStatus(C.pam_authenticate(t.handle, C.int(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCred is used to establish, maintain and delete the credentials of a
|
||||||
|
// user.
|
||||||
|
//
|
||||||
|
// Valid flags: EstablishCred, DeleteCred, ReinitializeCred, RefreshCred
|
||||||
|
func (t *Transaction) SetCred(f Flags) error {
|
||||||
|
return t.handlePamStatus(C.pam_setcred(t.handle, C.int(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AcctMgmt is used to determine if the user's account is valid.
|
||||||
|
//
|
||||||
|
// Valid flags: Silent, DisallowNullAuthtok
|
||||||
|
func (t *Transaction) AcctMgmt(f Flags) error {
|
||||||
|
return t.handlePamStatus(C.pam_acct_mgmt(t.handle, C.int(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChangeAuthTok is used to change the authentication token.
|
||||||
|
//
|
||||||
|
// Valid flags: Silent, ChangeExpiredAuthtok
|
||||||
|
func (t *Transaction) ChangeAuthTok(f Flags) error {
|
||||||
|
return t.handlePamStatus(C.pam_chauthtok(t.handle, C.int(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenSession sets up a user session for an authenticated user.
|
||||||
|
//
|
||||||
|
// Valid flags: Slient
|
||||||
|
func (t *Transaction) OpenSession(f Flags) error {
|
||||||
|
return t.handlePamStatus(C.pam_open_session(t.handle, C.int(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// CloseSession closes a previously opened session.
|
||||||
|
//
|
||||||
|
// Valid flags: Silent
|
||||||
|
func (t *Transaction) CloseSession(f Flags) error {
|
||||||
|
return t.handlePamStatus(C.pam_close_session(t.handle, C.int(f)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// End cleans up the PAM handle and deletes the callback function.
|
||||||
|
// It must be called when done with the transaction.
|
||||||
|
func (t *Transaction) End() error {
|
||||||
|
handle := atomic.SwapPointer((*unsafe.Pointer)(unsafe.Pointer(&t.handle)), nil)
|
||||||
|
if handle == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
defer t.c.Delete()
|
||||||
|
return t.handlePamStatus(C.pam_end((*C.pam_handle_t)(handle),
|
||||||
|
C.int(t.lastStatus.Load())))
|
||||||
|
}
|
||||||
|
|||||||
210
transaction.go
210
transaction.go
@@ -8,8 +8,6 @@ package pam
|
|||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"runtime/cgo"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
@@ -40,73 +38,11 @@ const (
|
|||||||
BinaryPrompt Style = C.PAM_BINARY_PROMPT
|
BinaryPrompt Style = C.PAM_BINARY_PROMPT
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConversationHandler is an interface for objects that can be used as
|
|
||||||
// conversation callbacks during PAM authentication.
|
|
||||||
type ConversationHandler interface {
|
|
||||||
// RespondPAM receives a message style and a message string. If the
|
|
||||||
// message Style is PromptEchoOff or PromptEchoOn then the function
|
|
||||||
// should return a response string.
|
|
||||||
RespondPAM(Style, string) (string, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// BinaryPointer exposes the type used for the data in a binary conversation
|
// BinaryPointer exposes the type used for the data in a binary conversation
|
||||||
// it represents a pointer to data that is produced by the module and that
|
// it represents a pointer to data that is produced by the module and that
|
||||||
// must be parsed depending on the protocol in use
|
// must be parsed depending on the protocol in use
|
||||||
type BinaryPointer unsafe.Pointer
|
type BinaryPointer unsafe.Pointer
|
||||||
|
|
||||||
// BinaryConversationHandler is an interface for objects that can be used as
|
|
||||||
// conversation callbacks during PAM authentication if binary protocol is going
|
|
||||||
// to be supported.
|
|
||||||
type BinaryConversationHandler interface {
|
|
||||||
ConversationHandler
|
|
||||||
// RespondPAMBinary receives a pointer to the binary message. It's up to
|
|
||||||
// the receiver to parse it according to the protocol specifications.
|
|
||||||
// The function can return a byte array that will passed as pointer back
|
|
||||||
// to the module.
|
|
||||||
RespondPAMBinary(BinaryPointer) ([]byte, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConversationFunc is an adapter to allow the use of ordinary functions as
|
|
||||||
// conversation callbacks.
|
|
||||||
type ConversationFunc func(Style, string) (string, error)
|
|
||||||
|
|
||||||
// RespondPAM is a conversation callback adapter.
|
|
||||||
func (f ConversationFunc) RespondPAM(s Style, msg string) (string, error) {
|
|
||||||
return f(s, msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
// pamConvHandler is a Go wrapper for the conversation callback function.
|
|
||||||
func pamConvHandler(style Style, msg *C.char, handler ConversationHandler) (*C.char, C.int) {
|
|
||||||
var r string
|
|
||||||
var err error
|
|
||||||
switch cb := handler.(type) {
|
|
||||||
case BinaryConversationHandler:
|
|
||||||
if style == BinaryPrompt {
|
|
||||||
bytes, err := cb.RespondPAMBinary(BinaryPointer(msg))
|
|
||||||
if err != nil {
|
|
||||||
return nil, C.int(ErrConv)
|
|
||||||
}
|
|
||||||
if bytes == nil {
|
|
||||||
return nil, success
|
|
||||||
}
|
|
||||||
return (*C.char)(C.CBytes(bytes)), success
|
|
||||||
}
|
|
||||||
handler = cb
|
|
||||||
case ConversationHandler:
|
|
||||||
if style == BinaryPrompt {
|
|
||||||
return nil, C.int(ErrConv)
|
|
||||||
}
|
|
||||||
handler = cb
|
|
||||||
default:
|
|
||||||
return nil, C.int(ErrConv)
|
|
||||||
}
|
|
||||||
r, err = handler.RespondPAM(style, C.GoString(msg))
|
|
||||||
if err != nil {
|
|
||||||
return nil, C.int(ErrConv)
|
|
||||||
}
|
|
||||||
return C.CString(r), success
|
|
||||||
}
|
|
||||||
|
|
||||||
// NativeHandle is the type of the native PAM handle for a transaction so that
|
// NativeHandle is the type of the native PAM handle for a transaction so that
|
||||||
// it can be exported
|
// it can be exported
|
||||||
type NativeHandle = *C.pam_handle_t
|
type NativeHandle = *C.pam_handle_t
|
||||||
@@ -119,27 +55,6 @@ type transactionBase struct {
|
|||||||
lastStatus atomic.Int32
|
lastStatus atomic.Int32
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transaction is the application's handle for a PAM transaction.
|
|
||||||
type Transaction struct {
|
|
||||||
transactionBase
|
|
||||||
|
|
||||||
conv *C.struct_pam_conv
|
|
||||||
c cgo.Handle
|
|
||||||
}
|
|
||||||
|
|
||||||
// End cleans up the PAM handle and deletes the callback function.
|
|
||||||
// It must be called when done with the transaction.
|
|
||||||
func (t *Transaction) End() error {
|
|
||||||
handle := atomic.SwapPointer((*unsafe.Pointer)(unsafe.Pointer(&t.handle)), nil)
|
|
||||||
if handle == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
defer t.c.Delete()
|
|
||||||
return t.handlePamStatus(C.pam_end((*C.pam_handle_t)(handle),
|
|
||||||
C.int(t.lastStatus.Load())))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allows to call pam functions managing return status
|
// Allows to call pam functions managing return status
|
||||||
func (t *transactionBase) handlePamStatus(cStatus C.int) error {
|
func (t *transactionBase) handlePamStatus(cStatus C.int) error {
|
||||||
t.lastStatus.Store(int32(cStatus))
|
t.lastStatus.Store(int32(cStatus))
|
||||||
@@ -149,88 +64,6 @@ func (t *transactionBase) handlePamStatus(cStatus C.int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start initiates a new PAM transaction. Service is treated identically to
|
|
||||||
// how pam_start treats it internally.
|
|
||||||
//
|
|
||||||
// All application calls to PAM begin with Start*. The returned
|
|
||||||
// transaction provides an interface to the remainder of the API.
|
|
||||||
//
|
|
||||||
// It's responsibility of the Transaction owner to release all the resources
|
|
||||||
// allocated underneath by PAM by calling End() once done.
|
|
||||||
//
|
|
||||||
// It's not advised to End the transaction using a runtime.SetFinalizer unless
|
|
||||||
// you're absolutely sure that your stack is multi-thread friendly (normally it
|
|
||||||
// is not!) and using a LockOSThread/UnlockOSThread pair.
|
|
||||||
func Start(service, user string, handler ConversationHandler) (*Transaction, error) {
|
|
||||||
return start(service, user, handler, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// StartFunc registers the handler func as a conversation handler and starts
|
|
||||||
// the transaction (see Start() documentation).
|
|
||||||
func StartFunc(service, user string, handler func(Style, string) (string, error)) (*Transaction, error) {
|
|
||||||
return start(service, user, ConversationFunc(handler), "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// StartConfDir initiates a new PAM transaction. Service is treated identically to
|
|
||||||
// how pam_start treats it internally.
|
|
||||||
// confdir allows to define where all pam services are defined. This is used to provide
|
|
||||||
// custom paths for tests.
|
|
||||||
//
|
|
||||||
// All application calls to PAM begin with Start*. The returned
|
|
||||||
// transaction provides an interface to the remainder of the API.
|
|
||||||
//
|
|
||||||
// It's responsibility of the Transaction owner to release all the resources
|
|
||||||
// allocated underneath by PAM by calling End() once done.
|
|
||||||
//
|
|
||||||
// It's not advised to End the transaction using a runtime.SetFinalizer unless
|
|
||||||
// you're absolutely sure that your stack is multi-thread friendly (normally it
|
|
||||||
// is not!) and using a LockOSThread/UnlockOSThread pair.
|
|
||||||
func StartConfDir(service, user string, handler ConversationHandler, confDir string) (*Transaction, error) {
|
|
||||||
if !CheckPamHasStartConfdir() {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
func start(service, user string, handler ConversationHandler, confDir string) (*Transaction, error) {
|
|
||||||
switch handler.(type) {
|
|
||||||
case BinaryConversationHandler:
|
|
||||||
if !CheckPamHasBinaryProtocol() {
|
|
||||||
return nil, fmt.Errorf("%w: BinaryConversationHandler was used, but it is not supported by this platform",
|
|
||||||
ErrSystem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t := &Transaction{
|
|
||||||
conv: &C.struct_pam_conv{},
|
|
||||||
c: cgo.NewHandle(handler),
|
|
||||||
}
|
|
||||||
|
|
||||||
C.init_pam_conv(t.conv, C.uintptr_t(t.c))
|
|
||||||
s := C.CString(service)
|
|
||||||
defer C.free(unsafe.Pointer(s))
|
|
||||||
var u *C.char
|
|
||||||
if len(user) != 0 {
|
|
||||||
u = C.CString(user)
|
|
||||||
defer C.free(unsafe.Pointer(u))
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
if confDir == "" {
|
|
||||||
err = t.handlePamStatus(C.pam_start(s, u, t.conv, &t.handle))
|
|
||||||
} else {
|
|
||||||
c := C.CString(confDir)
|
|
||||||
defer C.free(unsafe.Pointer(c))
|
|
||||||
err = t.handlePamStatus(C.pam_start_confdir(s, u, t.conv, c, &t.handle))
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
var _ = t.End()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return t, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Item is a an PAM information type.
|
// Item is a an PAM information type.
|
||||||
type Item int
|
type Item int
|
||||||
|
|
||||||
@@ -307,49 +140,6 @@ const (
|
|||||||
ChangeExpiredAuthtok Flags = C.PAM_CHANGE_EXPIRED_AUTHTOK
|
ChangeExpiredAuthtok Flags = C.PAM_CHANGE_EXPIRED_AUTHTOK
|
||||||
)
|
)
|
||||||
|
|
||||||
// Authenticate is used to authenticate the user.
|
|
||||||
//
|
|
||||||
// Valid flags: Silent, DisallowNullAuthtok
|
|
||||||
func (t *Transaction) Authenticate(f Flags) error {
|
|
||||||
return t.handlePamStatus(C.pam_authenticate(t.handle, C.int(f)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetCred is used to establish, maintain and delete the credentials of a
|
|
||||||
// user.
|
|
||||||
//
|
|
||||||
// Valid flags: EstablishCred, DeleteCred, ReinitializeCred, RefreshCred
|
|
||||||
func (t *Transaction) SetCred(f Flags) error {
|
|
||||||
return t.handlePamStatus(C.pam_setcred(t.handle, C.int(f)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// AcctMgmt is used to determine if the user's account is valid.
|
|
||||||
//
|
|
||||||
// Valid flags: Silent, DisallowNullAuthtok
|
|
||||||
func (t *Transaction) AcctMgmt(f Flags) error {
|
|
||||||
return t.handlePamStatus(C.pam_acct_mgmt(t.handle, C.int(f)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChangeAuthTok is used to change the authentication token.
|
|
||||||
//
|
|
||||||
// Valid flags: Silent, ChangeExpiredAuthtok
|
|
||||||
func (t *Transaction) ChangeAuthTok(f Flags) error {
|
|
||||||
return t.handlePamStatus(C.pam_chauthtok(t.handle, C.int(f)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenSession sets up a user session for an authenticated user.
|
|
||||||
//
|
|
||||||
// Valid flags: Slient
|
|
||||||
func (t *Transaction) OpenSession(f Flags) error {
|
|
||||||
return t.handlePamStatus(C.pam_open_session(t.handle, C.int(f)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// CloseSession closes a previously opened session.
|
|
||||||
//
|
|
||||||
// Valid flags: Silent
|
|
||||||
func (t *Transaction) CloseSession(f Flags) error {
|
|
||||||
return t.handlePamStatus(C.pam_close_session(t.handle, C.int(f)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// PutEnv adds or changes the value of PAM environment variables.
|
// PutEnv adds or changes the value of PAM environment variables.
|
||||||
//
|
//
|
||||||
// NAME=value will set a variable to a value.
|
// NAME=value will set a variable to a value.
|
||||||
|
|||||||
Reference in New Issue
Block a user