Initial commit
This commit is contained in:
20
Makefile
Normal file
20
Makefile
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
include $(GOROOT)/src/Make.inc
|
||||||
|
|
||||||
|
.PHONY: all pam install examples clean
|
||||||
|
|
||||||
|
all: install examples
|
||||||
|
|
||||||
|
pam:
|
||||||
|
gomake -C pam
|
||||||
|
|
||||||
|
install: pam
|
||||||
|
gomake -C pam install
|
||||||
|
|
||||||
|
examples:
|
||||||
|
gomake -C examples
|
||||||
|
|
||||||
|
clean:
|
||||||
|
gomake -C pam clean
|
||||||
|
gomake -C examples clean
|
||||||
|
|
||||||
|
|
||||||
14
README
Normal file
14
README
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
It's Go! It's PAM (Pluggable Authentication Modules)! It's GoPAM!
|
||||||
|
|
||||||
|
This is a Go wrapper for the PAM application API. There's not much
|
||||||
|
else to be said. PAM is a simple API and now it's available for use in Go
|
||||||
|
applications.
|
||||||
|
|
||||||
|
There's an example of a "fake login" program in the examples
|
||||||
|
directory. Look at the pam module's godocs for details about the Go
|
||||||
|
API; for a more general PAM application API reference, peep
|
||||||
|
|
||||||
|
http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/adg-interface-by-app-expected.html
|
||||||
|
|
||||||
|
In the future, maybe the module API will be wrapped too. I don't know!
|
||||||
|
|
||||||
11
examples/Makefile
Normal file
11
examples/Makefile
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
# Use of this source code is governed by a BSD-style
|
||||||
|
# license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
include $(GOROOT)/src/Make.inc
|
||||||
|
|
||||||
|
TARG=fakelogin
|
||||||
|
GOFILES=\
|
||||||
|
fakelogin.go
|
||||||
|
|
||||||
|
include $(GOROOT)/src/Make.cmd
|
||||||
74
examples/fakelogin.go
Normal file
74
examples/fakelogin.go
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
// This is a fake login implementation! It uses whatever default
|
||||||
|
// PAM service configuration is available on the system, and tries
|
||||||
|
// to authenticate any user. This should cause PAM to ask its
|
||||||
|
// conversation handler for a username and password, in sequence.
|
||||||
|
//
|
||||||
|
// This application will handle those requests by displaying the
|
||||||
|
// PAM-provided prompt and sending back the first line of stdin input
|
||||||
|
// it can read for each.
|
||||||
|
//
|
||||||
|
// Keep in mind that unless run as root (or setuid root), the only
|
||||||
|
// user's authentication that can succeed is that of the process owner.
|
||||||
|
//
|
||||||
|
// It's not a real login for several reasons:
|
||||||
|
//
|
||||||
|
// (!WARNING!) It echos your password to the terminal (!WARNING!)
|
||||||
|
// It doesn't switch users.
|
||||||
|
// It's not a real login.
|
||||||
|
//
|
||||||
|
// It does however demonstrate a simple but powerful use of Go PAM.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import(
|
||||||
|
"fmt"
|
||||||
|
"pam"
|
||||||
|
"os"
|
||||||
|
"bufio"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetLine(prompt string) (string,bool) {
|
||||||
|
fmt.Print(prompt)
|
||||||
|
in := bufio.NewReader(os.Stdin)
|
||||||
|
input,err := in.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
return "",false
|
||||||
|
}
|
||||||
|
return input[:len(input)-1],true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Echo on/off is ignored; echo will always happen.
|
||||||
|
func DumbPrompter(style int, msg string) (string,bool) {
|
||||||
|
switch style {
|
||||||
|
case pam.PROMPT_ECHO_OFF:
|
||||||
|
return GetLine(msg)
|
||||||
|
case pam.PROMPT_ECHO_ON:
|
||||||
|
return GetLine(msg)
|
||||||
|
case pam.ERROR_MSG:
|
||||||
|
fmt.Fprintf(os.Stderr, "Error: %s\n", msg)
|
||||||
|
return "",true
|
||||||
|
case pam.TEXT_INFO:
|
||||||
|
fmt.Println(msg)
|
||||||
|
return "",true
|
||||||
|
}
|
||||||
|
return "",false
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
t,status := pam.Start("", "", pam.ResponseFunc(DumbPrompter))
|
||||||
|
if status != pam.SUCCESS {
|
||||||
|
fmt.Fprintf(os.Stderr, "Start() failed: %s\n", t.Error(status))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer func(){ t.End(status) }()
|
||||||
|
|
||||||
|
status = t.Authenticate(0)
|
||||||
|
if status != pam.SUCCESS {
|
||||||
|
fmt.Fprintf(os.Stderr, "Auth failed: %s\n", t.Error(status))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Authentication succeeded!\n")
|
||||||
|
fmt.Printf("Goodbye, friend.\n")
|
||||||
|
}
|
||||||
|
|
||||||
16
pam/Makefile
Normal file
16
pam/Makefile
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
include $(GOROOT)/src/Make.inc
|
||||||
|
TARG=pam
|
||||||
|
GOFILES:=pamdefs.go
|
||||||
|
CGOFILES:=pam.go
|
||||||
|
CGO_LDFLAGS:=-lpam
|
||||||
|
CGO_OFILES:=gopam.o
|
||||||
|
|
||||||
|
include $(GOROOT)/src/Make.pkg
|
||||||
|
|
||||||
|
DOLLAR:="$"
|
||||||
|
|
||||||
|
pamdefs.go: pamdefs.c
|
||||||
|
godefs `echo -n $(CGO_FLAGS) | sed 's/\(^ ^$(DOLLAR)]*\)/-f \1/g'` -g pam pamdefs.c > pamdefs.go
|
||||||
|
gofmt -w pamdefs.go
|
||||||
|
|
||||||
|
|
||||||
68
pam/gopam.c
Normal file
68
pam/gopam.c
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#include <security/_pam_types.h>
|
||||||
|
#include <security/pam_appl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "gopam.h"
|
||||||
|
#include "_cgo_export.h"
|
||||||
|
|
||||||
|
/* Simplification of pam_get_item to remove type ambiguity. Will never
|
||||||
|
be called (promise) with a type that returns anything other than a string */
|
||||||
|
get_item_result pam_get_item_string(pam_handle_t *handle, int type) {
|
||||||
|
get_item_result result;
|
||||||
|
result.status = pam_get_item(handle, type, (const void **)&result.str);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The universal conversation callback for gopam transactions. appdata_ptr
|
||||||
|
is always taken as a raw pointer to a Go-side pam.conversation object.
|
||||||
|
In order to avoid nightmareish unsafe pointer math all over the Go
|
||||||
|
implementation, this universal callback deals with memory allocation of
|
||||||
|
response buffers, as well as unpacking and repackaging incoming messages
|
||||||
|
and responses, calling a Go-side callback that handles each one on an
|
||||||
|
individual basis. */
|
||||||
|
int gopam_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr)
|
||||||
|
{
|
||||||
|
int i, ok = 1;
|
||||||
|
struct pam_response *responses = (struct pam_response*)malloc(sizeof(struct pam_response) * num_msg);
|
||||||
|
memset(responses, 0, sizeof(struct pam_response) * num_msg);
|
||||||
|
|
||||||
|
for(i = 0; i < num_msg; ++i) {
|
||||||
|
const struct pam_message *m = msg[i];
|
||||||
|
struct goPAMConv_return result = goPAMConv(m->msg_style, (char*)m->msg, appdata_ptr);
|
||||||
|
if(result.r1 == PAM_SUCCESS)
|
||||||
|
responses[i].resp = result.r0;
|
||||||
|
else {
|
||||||
|
ok = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ok) {
|
||||||
|
*resp = responses;
|
||||||
|
return PAM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In the case of failure PAM will never see these responses. The
|
||||||
|
resp strings that have been allocated by Go-side C.CString calls
|
||||||
|
must be freed lest we leak them. */
|
||||||
|
for(i = 0; i < num_msg; ++i)
|
||||||
|
if(responses[i].resp != NULL)
|
||||||
|
free(responses[i].resp);
|
||||||
|
|
||||||
|
free(responses);
|
||||||
|
return PAM_CONV_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This allocates a new pam_conv struct and fills in its fields:
|
||||||
|
The conv function pointer always points to the universal gopam_conv.
|
||||||
|
The appdata_ptr will be set to the incoming void* argument, which
|
||||||
|
is always a Go-side *pam.conversation whose handler was given
|
||||||
|
to pam.Start(). */
|
||||||
|
struct pam_conv* make_gopam_conv(void *goconv)
|
||||||
|
{
|
||||||
|
struct pam_conv* conv = (struct pam_conv*)malloc(sizeof(struct pam_conv));
|
||||||
|
conv->conv = gopam_conv;
|
||||||
|
conv->appdata_ptr = goconv;
|
||||||
|
return conv;
|
||||||
|
}
|
||||||
|
|
||||||
11
pam/gopam.h
Normal file
11
pam/gopam.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#include <security/pam_appl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *str;
|
||||||
|
int status;
|
||||||
|
} get_item_result;
|
||||||
|
|
||||||
|
get_item_result pam_get_item_string(pam_handle_t *handle, int type);
|
||||||
|
struct pam_conv* make_gopam_conv(void *goconv);
|
||||||
|
|
||||||
185
pam/pam.go
Normal file
185
pam/pam.go
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
// Package pam provides a wrapper for the application layer of the
|
||||||
|
// Pluggable Authentication Modules library.
|
||||||
|
package pam
|
||||||
|
|
||||||
|
import (
|
||||||
|
//#include "gopam.h"
|
||||||
|
"C"
|
||||||
|
"unsafe"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Objects implementing the ConversationHandler interface can
|
||||||
|
// be registered as conversation callbacks to be used during
|
||||||
|
// PAM authentication. RespondPAM receives a message style
|
||||||
|
// (one of PROMPT_ECHO_OFF, PROMPT_ECHO_ON, ERROR_MSG, or
|
||||||
|
// TEXT_INFO) and a message string. It is expected to return
|
||||||
|
// a response string and a bool indicating success or failure.
|
||||||
|
type ConversationHandler interface {
|
||||||
|
RespondPAM(msg_style int, msg string) (string,bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResponseFunc is an adapter to allow the use of ordinary
|
||||||
|
// functions as conversation callbacks. ResponseFunc(f) is
|
||||||
|
// a ConversationHandler that calls f, where f must have
|
||||||
|
// the signature func(int,string)(string,bool).
|
||||||
|
type ResponseFunc func(int,string) (string,bool)
|
||||||
|
func (f ResponseFunc) RespondPAM(style int, msg string) (string,bool) {
|
||||||
|
return f(style,msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal conversation structure
|
||||||
|
type conversation struct {
|
||||||
|
handler ConversationHandler
|
||||||
|
cconv *C.struct_pam_conv
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cosntructs a new conversation object with a given handler and a newly
|
||||||
|
// allocated pam_conv struct that uses this object as its appdata_ptr
|
||||||
|
func newConversation(handler ConversationHandler) *conversation {
|
||||||
|
conv := &conversation{}
|
||||||
|
conv.handler = handler
|
||||||
|
conv.cconv = C.make_gopam_conv(unsafe.Pointer(conv))
|
||||||
|
return conv
|
||||||
|
}
|
||||||
|
|
||||||
|
//export goPAMConv
|
||||||
|
// Go-side function for processing a single conversational message. Ultimately
|
||||||
|
// this calls the associated ConversationHandler's ResponsePAM callback with data
|
||||||
|
// coming in from a C-side call.
|
||||||
|
func goPAMConv(msg_style C.int, msg *C.char, appdata unsafe.Pointer) (*C.char,int) {
|
||||||
|
conv := (*conversation)(appdata)
|
||||||
|
resp,ok := conv.handler.RespondPAM(int(msg_style), C.GoString(msg))
|
||||||
|
if ok {
|
||||||
|
return C.CString(resp),SUCCESS
|
||||||
|
}
|
||||||
|
return nil,CONV_ERR
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transaction is the application's handle for a single PAM transaction.
|
||||||
|
type Transaction struct {
|
||||||
|
handle *C.pam_handle_t
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start initiates a new PAM transaction. serviceName is treated identically
|
||||||
|
// to how pam_start internally treats it. The same applies to user, except that
|
||||||
|
// the empty string is passed to PAM as nil; therefore the empty string should be
|
||||||
|
// used to signal that no username is being provided.
|
||||||
|
//
|
||||||
|
// All application calls to PAM begin with Start(). The returned *Transaction
|
||||||
|
// provides an interface to the remainder of the API.
|
||||||
|
//
|
||||||
|
// The returned status int may be ABORT, BUF_ERR, SUCCESS, or SYSTEM_ERR, as per
|
||||||
|
// the official PAM documentation.
|
||||||
|
func Start(serviceName, user string, handler ConversationHandler) (*Transaction,int) {
|
||||||
|
t := &Transaction{}
|
||||||
|
conv := newConversation(handler)
|
||||||
|
var status C.int
|
||||||
|
if len(user) == 0 {
|
||||||
|
status = C.pam_start(C.CString(serviceName), nil, conv.cconv, &t.handle)
|
||||||
|
} else {
|
||||||
|
status = C.pam_start(C.CString(serviceName), C.CString(user), conv.cconv, &t.handle)
|
||||||
|
}
|
||||||
|
return t, int(status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ends a PAM transaction. From Linux-PAM documentation: "The [status] argument
|
||||||
|
// should be set to the value returned by the last PAM library call."
|
||||||
|
//
|
||||||
|
// This may return SUCCESS, or SYSTEM_ERR.
|
||||||
|
func (t *Transaction) End(status int) {
|
||||||
|
C.pam_end(t.handle, C.int(status))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets a PAM informational item. Legal values of itemType are listed here (excluding Linux extensions):
|
||||||
|
//
|
||||||
|
// http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/adg-interface-by-app-expected.html#adg-pam_set_item
|
||||||
|
//
|
||||||
|
// the CONV item type is also not supported in order to simplify the Go API (and due to
|
||||||
|
// the fact that it is completely unnecessary).
|
||||||
|
func (t *Transaction) SetItem(itemType int, item string) int {
|
||||||
|
if itemType == CONV { return BAD_ITEM }
|
||||||
|
cs := unsafe.Pointer(C.CString(item))
|
||||||
|
defer C.free(cs)
|
||||||
|
return int(C.pam_set_item(t.handle, C.int(itemType), cs))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets a PAM item. Legal values of itemType are as specified by the documentation of SetItem.
|
||||||
|
func (t *Transaction) GetItem(itemType int) (string,int) {
|
||||||
|
if itemType == CONV { return "",BAD_ITEM }
|
||||||
|
result := C.pam_get_item_string(t.handle, C.int(itemType))
|
||||||
|
return C.GoString(result.str),int(result.status)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error returns a PAM error string from a PAM error code
|
||||||
|
func (t *Transaction) Error(errnum int) string {
|
||||||
|
return C.GoString(C.pam_strerror(t.handle, C.int(errnum)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// pam_authenticate
|
||||||
|
func (t *Transaction) Authenticate(flags int) int {
|
||||||
|
return int(C.pam_authenticate(t.handle, C.int(flags)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// pam_setcred
|
||||||
|
func (t* Transaction) SetCred(flags int) int {
|
||||||
|
return int(C.pam_setcred(t.handle, C.int(flags)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// pam_acctmgmt
|
||||||
|
func (t* Transaction) AcctMgmt(flags int) int {
|
||||||
|
return int(C.pam_acct_mgmt(t.handle, C.int(flags)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// pam_chauthtok
|
||||||
|
func (t* Transaction) ChangeAuthTok(flags int) int {
|
||||||
|
return int(C.pam_chauthtok(t.handle, C.int(flags)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// pam_open_session
|
||||||
|
func (t* Transaction) OpenSession(flags int) int {
|
||||||
|
return int(C.pam_open_session(t.handle, C.int(flags)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// pam_close_session
|
||||||
|
func (t* Transaction) CloseSession(flags int) int {
|
||||||
|
return int(C.pam_close_session(t.handle, C.int(flags)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// pam_putenv
|
||||||
|
func (t* Transaction) PutEnv(nameval string) int {
|
||||||
|
cs := C.CString(nameval)
|
||||||
|
defer C.free(unsafe.Pointer(cs))
|
||||||
|
return int(C.pam_putenv(t.handle, cs))
|
||||||
|
}
|
||||||
|
|
||||||
|
// pam_getenv. Returns an additional argument indicating
|
||||||
|
// the actual existence of the given environment variable.
|
||||||
|
func (t* Transaction) GetEnv(name string) (string,bool) {
|
||||||
|
cs := C.CString(name)
|
||||||
|
defer C.free(unsafe.Pointer(cs))
|
||||||
|
value := C.pam_getenv(t.handle, cs)
|
||||||
|
if value != nil {
|
||||||
|
return C.GoString(value),true
|
||||||
|
}
|
||||||
|
return "",false
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEnvList internally calls pam_getenvlist and then uses some very
|
||||||
|
// dangerous code to pull out the returned environment data and mash
|
||||||
|
// it into a map[string]string. This call may be safe, but it hasn't
|
||||||
|
// been tested on enough platforms/architectures/PAM-implementations to
|
||||||
|
// be sure.
|
||||||
|
func (t* Transaction) GetEnvList() map[string]string {
|
||||||
|
env := make(map[string]string)
|
||||||
|
list := (uintptr)(unsafe.Pointer(C.pam_getenvlist(t.handle)))
|
||||||
|
for *(*uintptr)(unsafe.Pointer(list)) != 0 {
|
||||||
|
entry := *(*uintptr)(unsafe.Pointer(list))
|
||||||
|
nameval := C.GoString((*C.char)(unsafe.Pointer(entry)))
|
||||||
|
chunks := strings.Split(nameval, "=", 2)
|
||||||
|
env[chunks[0]] = chunks[1]
|
||||||
|
list += (uintptr)(unsafe.Sizeof(list))
|
||||||
|
}
|
||||||
|
return env
|
||||||
|
}
|
||||||
|
|
||||||
74
pam/pamdefs.c
Normal file
74
pam/pamdefs.c
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
#include <security/pam_appl.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
$SUCCESS = PAM_SUCCESS,
|
||||||
|
$OPEN_ERR = PAM_OPEN_ERR,
|
||||||
|
$SYMBOL_ERR = PAM_SYMBOL_ERR,
|
||||||
|
$SERVICE_ERR = PAM_SERVICE_ERR,
|
||||||
|
$SYSTEM_ERR = PAM_SYSTEM_ERR,
|
||||||
|
$BUF_ERR = PAM_BUF_ERR,
|
||||||
|
$PERM_DENIED = PAM_PERM_DENIED,
|
||||||
|
$AUTH_ERR = PAM_AUTH_ERR,
|
||||||
|
$CRED_INSUFFICIENT = PAM_CRED_INSUFFICIENT,
|
||||||
|
$AUTHINFO_UNAVAIL = PAM_AUTHINFO_UNAVAIL,
|
||||||
|
$USER_UNKNOWN = PAM_USER_UNKNOWN,
|
||||||
|
$MAXTRIES = PAM_MAXTRIES,
|
||||||
|
$NEW_AUTHOTK_REQD = PAM_NEW_AUTHTOK_REQD,
|
||||||
|
$ACCT_EXPIRED = PAM_ACCT_EXPIRED,
|
||||||
|
$SESSION_ERR = PAM_SESSION_ERR,
|
||||||
|
$CRED_UNAVAIL = PAM_CRED_UNAVAIL,
|
||||||
|
$CRED_EXPIRED = PAM_CRED_EXPIRED,
|
||||||
|
$CRED_ERR = PAM_CRED_ERR,
|
||||||
|
$NO_MODULE_DATA = PAM_NO_MODULE_DATA,
|
||||||
|
$CONV_ERR = PAM_CONV_ERR,
|
||||||
|
$AUTHTOK_ERR = PAM_AUTHTOK_ERR,
|
||||||
|
$AUTHTOK_RECOVERY_ERR = PAM_AUTHTOK_RECOVERY_ERR,
|
||||||
|
$AUTHTOK_LOCK_BUSY = PAM_AUTHTOK_LOCK_BUSY,
|
||||||
|
$AUTHTOK_DISABLE_AGING = PAM_AUTHTOK_DISABLE_AGING,
|
||||||
|
$TRY_AGAIN = PAM_TRY_AGAIN,
|
||||||
|
$IGNORE = PAM_IGNORE,
|
||||||
|
$ABORT = PAM_ABORT,
|
||||||
|
$AUTHTOK_EXPIRED = PAM_AUTHTOK_EXPIRED,
|
||||||
|
$MODULE_UNKNOWN = PAM_MODULE_UNKNOWN,
|
||||||
|
$BAD_ITEM = PAM_BAD_ITEM,
|
||||||
|
$CONV_AGAIN = PAM_CONV_AGAIN,
|
||||||
|
$INCOMPLETE = PAM_INCOMPLETE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
$SILENT = PAM_SILENT,
|
||||||
|
$DISALLOW_NULL_AUTHTOK = PAM_DISALLOW_NULL_AUTHTOK,
|
||||||
|
$ESTABLISH_CRED = PAM_ESTABLISH_CRED,
|
||||||
|
$DELETE_CRED = PAM_DELETE_CRED,
|
||||||
|
$REINITIALIZE_CRED = PAM_REINITIALIZE_CRED,
|
||||||
|
$REFRESH_CRED = PAM_REFRESH_CRED,
|
||||||
|
$CHANGE_EXPIRED_AUTHTOK = PAM_CHANGE_EXPIRED_AUTHTOK
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
$SERVICE = PAM_SERVICE,
|
||||||
|
$USER = PAM_USER,
|
||||||
|
$TTY = PAM_TTY,
|
||||||
|
$RHOST = PAM_RHOST,
|
||||||
|
$CONV = PAM_CONV,
|
||||||
|
$AUTHTOK = PAM_AUTHTOK,
|
||||||
|
$OLDAUTHTOK = PAM_OLDAUTHTOK,
|
||||||
|
$RUSER = PAM_RUSER,
|
||||||
|
$USER_PROMPT = PAM_USER_PROMPT,
|
||||||
|
|
||||||
|
/* Linux-PAM extensions. Leaving these out, for now...
|
||||||
|
$FAIL_DELAY = PAM_FAIL_DELAY,
|
||||||
|
$XDISPLAY = PAM_XDISPLAY,
|
||||||
|
$XAUTHDATA = PAM_XAUTHDATA,
|
||||||
|
$AUTHTOK_TYPE = PAM_AUTHTOK_TYPE
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
$PROMPT_ECHO_OFF = PAM_PROMPT_ECHO_OFF,
|
||||||
|
$PROMPT_ECHO_ON = PAM_PROMPT_ECHO_ON,
|
||||||
|
$ERROR_MSG = PAM_ERROR_MSG,
|
||||||
|
$TEXT_INFO = PAM_TEXT_INFO
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
63
pam/pamdefs.go
Normal file
63
pam/pamdefs.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
// godefs -g pam pamdefs.c
|
||||||
|
|
||||||
|
// MACHINE GENERATED - DO NOT EDIT.
|
||||||
|
|
||||||
|
package pam
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
const (
|
||||||
|
SUCCESS = 0
|
||||||
|
OPEN_ERR = 0x1
|
||||||
|
SYMBOL_ERR = 0x2
|
||||||
|
SERVICE_ERR = 0x3
|
||||||
|
SYSTEM_ERR = 0x4
|
||||||
|
BUF_ERR = 0x5
|
||||||
|
PERM_DENIED = 0x6
|
||||||
|
AUTH_ERR = 0x7
|
||||||
|
CRED_INSUFFICIENT = 0x8
|
||||||
|
AUTHINFO_UNAVAIL = 0x9
|
||||||
|
USER_UNKNOWN = 0xa
|
||||||
|
MAXTRIES = 0xb
|
||||||
|
NEW_AUTHOTK_REQD = 0xc
|
||||||
|
ACCT_EXPIRED = 0xd
|
||||||
|
SESSION_ERR = 0xe
|
||||||
|
CRED_UNAVAIL = 0xf
|
||||||
|
CRED_EXPIRED = 0x10
|
||||||
|
CRED_ERR = 0x11
|
||||||
|
NO_MODULE_DATA = 0x12
|
||||||
|
CONV_ERR = 0x13
|
||||||
|
AUTHTOK_ERR = 0x14
|
||||||
|
AUTHTOK_RECOVERY_ERR = 0x15
|
||||||
|
AUTHTOK_LOCK_BUSY = 0x16
|
||||||
|
AUTHTOK_DISABLE_AGING = 0x17
|
||||||
|
TRY_AGAIN = 0x18
|
||||||
|
IGNORE = 0x19
|
||||||
|
ABORT = 0x1a
|
||||||
|
AUTHTOK_EXPIRED = 0x1b
|
||||||
|
MODULE_UNKNOWN = 0x1c
|
||||||
|
BAD_ITEM = 0x1d
|
||||||
|
CONV_AGAIN = 0x1e
|
||||||
|
INCOMPLETE = 0x1f
|
||||||
|
SILENT = 0x8000
|
||||||
|
DISALLOW_NULL_AUTHTOK = 0x1
|
||||||
|
ESTABLISH_CRED = 0x2
|
||||||
|
DELETE_CRED = 0x4
|
||||||
|
REINITIALIZE_CRED = 0x8
|
||||||
|
REFRESH_CRED = 0x10
|
||||||
|
CHANGE_EXPIRED_AUTHTOK = 0x20
|
||||||
|
SERVICE = 0x1
|
||||||
|
USER = 0x2
|
||||||
|
TTY = 0x3
|
||||||
|
RHOST = 0x4
|
||||||
|
CONV = 0x5
|
||||||
|
AUTHTOK = 0x6
|
||||||
|
OLDAUTHTOK = 0x7
|
||||||
|
RUSER = 0x8
|
||||||
|
USER_PROMPT = 0x9
|
||||||
|
PROMPT_ECHO_OFF = 0x1
|
||||||
|
PROMPT_ECHO_ON = 0x2
|
||||||
|
ERROR_MSG = 0x3
|
||||||
|
TEXT_INFO = 0x4
|
||||||
|
)
|
||||||
|
|
||||||
|
// Types
|
||||||
Reference in New Issue
Block a user