forked from jcmturner/gokrb5
/
passwd.go
75 lines (69 loc) · 1.85 KB
/
passwd.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
package client
import (
"fmt"
"github.com/jcmturner/gokrb5/v8/kadmin"
"github.com/jcmturner/gokrb5/v8/messages"
)
// Kpasswd server response codes.
const (
KRB5_KPASSWD_SUCCESS = 0
KRB5_KPASSWD_MALFORMED = 1
KRB5_KPASSWD_HARDERROR = 2
KRB5_KPASSWD_AUTHERROR = 3
KRB5_KPASSWD_SOFTERROR = 4
KRB5_KPASSWD_ACCESSDENIED = 5
KRB5_KPASSWD_BAD_VERSION = 6
KRB5_KPASSWD_INITIAL_FLAG_NEEDED = 7
)
// ChangePasswd changes the password of the client to the value provided.
func (cl *Client) ChangePasswd(newPasswd string) (bool, error) {
ASReq, err := messages.NewASReqForChgPasswd(cl.Credentials.Domain(), cl.Config, cl.Credentials.CName())
if err != nil {
return false, err
}
ASRep, err := cl.ASExchange(cl.Credentials.Domain(), ASReq, 0)
if err != nil {
return false, err
}
msg, key, err := kadmin.ChangePasswdMsg(cl.Credentials.CName(), cl.Credentials.Domain(), newPasswd, ASRep.Ticket, ASRep.DecryptedEncPart.Key)
if err != nil {
return false, err
}
r, err := cl.sendToKPasswd(msg)
if err != nil {
return false, err
}
err = r.Decrypt(key)
if err != nil {
return false, err
}
if r.ResultCode != KRB5_KPASSWD_SUCCESS {
return false, fmt.Errorf("error response from kadmin: code: %d; result: %s; krberror: %v", r.ResultCode, r.Result, r.KRBError)
}
cl.Credentials.WithPassword(newPasswd)
return true, nil
}
func (cl *Client) sendToKPasswd(msg kadmin.Request) (r kadmin.Reply, err error) {
_, kps, err := cl.Config.GetKpasswdServers(cl.Credentials.Domain(), true)
if err != nil {
return
}
b, err := msg.Marshal()
if err != nil {
return
}
var rb []byte
if len(b) <= cl.Config.LibDefaults.UDPPreferenceLimit {
rb, err = dialSendUDP(kps, b)
if err != nil {
return
}
} else {
rb, err = dialSendTCP(kps, b)
if err != nil {
return
}
}
err = r.Unmarshal(rb)
return
}