v0.1.0 c541a90

binding_linux.go RawHistoryFolder

1//go:build linux && (amd64 || arm64)
2
3package pam
4
5import (
6	"fmt"
7	"unsafe"
8
9	"github.com/bnema/purego"
10)
11
12// libraryFunctions is the test seam; tests use Mockery, never replace functions.
13type libraryFunctions interface {
14	Start(service, user, conversation, output unsafe.Pointer) Status
15	Authenticate(handle unsafe.Pointer, flags Flags) Status
16	AcctMgmt(handle unsafe.Pointer, flags Flags) Status
17	End(handle unsafe.Pointer, status Status) Status
18}
19
20type boundFunctions struct {
21	start        func(unsafe.Pointer, unsafe.Pointer, unsafe.Pointer, unsafe.Pointer) Status
22	authenticate func(unsafe.Pointer, Flags) Status
23	acctMgmt     func(unsafe.Pointer, Flags) Status
24	end          func(unsafe.Pointer, Status) Status
25}
26
27func (b *boundFunctions) Start(s, u, c, o unsafe.Pointer) Status        { return b.start(s, u, c, o) }
28func (b *boundFunctions) Authenticate(h unsafe.Pointer, f Flags) Status { return b.authenticate(h, f) }
29func (b *boundFunctions) AcctMgmt(h unsafe.Pointer, f Flags) Status     { return b.acctMgmt(h, f) }
30func (b *boundFunctions) End(h unsafe.Pointer, s Status) Status         { return b.end(h, s) }
31
32// Open loads the system libpam and libc with eager, local symbol resolution.
33// It performs no PAM transaction or authentication. Library operations must be
34// serialized by the caller; Close is rejected while transactions are active.
35func Open() (*Library, error) {
36	pamHandle, err := purego.Dlopen("libpam.so.0", purego.RTLD_NOW|purego.RTLD_LOCAL)
37	if err != nil {
38		return nil, fmt.Errorf("pam: load libpam: %w", err)
39	}
40	libcHandle, err := purego.Dlopen("libc.so.6", purego.RTLD_NOW|purego.RTLD_LOCAL)
41	if err != nil {
42		return nil, fmt.Errorf("pam: load libc: %w", errorsWithClose(err, pamHandle))
43	}
44	functions := &boundFunctions{}
45	memory := &nativeAllocator{}
46	bindings := []struct {
47		handle uintptr
48		name   string
49		target any
50	}{
51		{pamHandle, "pam_start", &functions.start},
52		{pamHandle, "pam_authenticate", &functions.authenticate},
53		{pamHandle, "pam_acct_mgmt", &functions.acctMgmt},
54		{pamHandle, "pam_end", &functions.end},
55		{libcHandle, "malloc", &memory.malloc},
56		{libcHandle, "free", &memory.freeFn},
57	}
58	for _, binding := range bindings {
59		if err := register(binding.target, binding.handle, binding.name); err != nil {
60			return nil, errorsWithClose(errorsWithClose(err, libcHandle), pamHandle)
61		}
62	}
63	return &Library{calls: functions, memory: memory, pamHandle: pamHandle, libcHandle: libcHandle}, nil
64}
65
66// RegisterLibFunc panics on lookup/registration failure; turn that boundary into
67// an Open error so a partially bound library is never exposed.
68func register(target any, handle uintptr, name string) (err error) {
69	defer func() {
70		if recovered := recover(); recovered != nil {
71			err = fmt.Errorf("pam: bind %s: %v", name, recovered)
72		}
73	}()
74	purego.RegisterLibFunc(target, handle, name)
75	return nil
76}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 1

↑↓ moveenter openesc close