forked from josephlim75/go-libnss
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpasswd-nss.go
96 lines (80 loc) · 2.36 KB
/
passwd-nss.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package nss
//#include <pwd.h>
//#include <errno.h>
import "C"
import(
. "github.com/naimols/go-libnss/structs"
"bytes"
"syscall"
"unsafe"
)
var entries_passwd = make([]Passwd, 0)
var entry_index_passwd int
//export go_setpwent
func go_setpwent() Status {
var status Status
status, entries_passwd = implemented.PasswdAll()
entry_index_passwd = 0
return status;
}
//export go_endpwent
func go_endpwent() Status {
entries_passwd = make([]Passwd, 0)
entry_index_passwd = 0
return StatusSuccess;
}
//export go_getpwent
func go_getpwent(passwd *C.struct_passwd, buf *C.char, buflen C.size_t, errnop *C.int) Status {
if entry_index_passwd == len(entries_passwd) {
return StatusNotfound
}
setCPasswd(&entries_passwd[entry_index_passwd], passwd, buf, buflen, errnop)
entry_index_passwd++
return StatusSuccess;
}
//export go_getpwnam
func go_getpwnam(name string, passwd *C.struct_passwd, buf *C.char, buflen C.size_t, errnop *C.int) Status {
status, pwd := implemented.PasswdByName(name)
if status != StatusSuccess {
return status
}
setCPasswd(&pwd, passwd, buf, buflen, errnop)
return StatusSuccess;
}
//export go_getpwuid
func go_getpwuid(uid uint, passwd *C.struct_passwd, buf *C.char, buflen C.size_t, errnop *C.int) Status {
status, pwd := implemented.PasswdByUid(uid)
if status != StatusSuccess {
return status
}
setCPasswd(&pwd, passwd, buf, buflen, errnop)
return StatusSuccess;
}
// Sets the C values for libnss
func setCPasswd(p *Passwd, passwd *C.struct_passwd, buf *C.char, buflen C.size_t, errnop *C.int) Status {
if len(p.Username)+len(p.Password)+len(p.Gecos)+len(p.Dir)+len(p.Shell)+5 > int(buflen) {
*errnop = C.int(syscall.EAGAIN)
return StatusTryagain
}
gobuf := C.GoBytes(unsafe.Pointer(buf), C.int(buflen))
b := bytes.NewBuffer(gobuf)
b.Reset()
passwd.pw_name = (*C.char)(unsafe.Pointer(&gobuf[b.Len()]))
b.WriteString(p.Username)
b.WriteByte(0)
passwd.pw_passwd = (*C.char)(unsafe.Pointer(&gobuf[b.Len()]))
b.WriteString(p.Password)
b.WriteByte(0)
passwd.pw_gecos = (*C.char)(unsafe.Pointer(&gobuf[b.Len()]))
b.WriteString(p.Gecos)
b.WriteByte(0)
passwd.pw_dir = (*C.char)(unsafe.Pointer(&gobuf[b.Len()]))
b.WriteString(p.Dir)
b.WriteByte(0)
passwd.pw_shell = (*C.char)(unsafe.Pointer(&gobuf[b.Len()]))
b.WriteString(p.Shell)
b.WriteByte(0)
passwd.pw_uid = C.uint(p.UID)
passwd.pw_gid = C.uint(p.GID)
return StatusSuccess
}