passwd.go 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package client
  2. import (
  3. "fmt"
  4. "net"
  5. "gopkg.in/jcmturner/gokrb5.v7/kadmin"
  6. "gopkg.in/jcmturner/gokrb5.v7/messages"
  7. )
  8. // Kpasswd server response codes.
  9. const (
  10. KRB5_KPASSWD_SUCCESS = 0
  11. KRB5_KPASSWD_MALFORMED = 1
  12. KRB5_KPASSWD_HARDERROR = 2
  13. KRB5_KPASSWD_AUTHERROR = 3
  14. KRB5_KPASSWD_SOFTERROR = 4
  15. KRB5_KPASSWD_ACCESSDENIED = 5
  16. KRB5_KPASSWD_BAD_VERSION = 6
  17. KRB5_KPASSWD_INITIAL_FLAG_NEEDED = 7
  18. )
  19. // ChangePasswd changes the password of the client to the value provided.
  20. func (cl *Client) ChangePasswd(newPasswd string) (bool, error) {
  21. ASReq, err := messages.NewASReqForChgPasswd(cl.Credentials.Domain(), cl.Config, cl.Credentials.CName())
  22. if err != nil {
  23. return false, err
  24. }
  25. ASRep, err := cl.ASExchange(cl.Credentials.Domain(), ASReq, 0)
  26. if err != nil {
  27. return false, err
  28. }
  29. msg, key, err := kadmin.ChangePasswdMsg(cl.Credentials.CName(), cl.Credentials.Domain(), newPasswd, ASRep.Ticket, ASRep.DecryptedEncPart.Key)
  30. if err != nil {
  31. return false, err
  32. }
  33. r, err := cl.sendToKPasswd(msg)
  34. if err != nil {
  35. return false, err
  36. }
  37. err = r.Decrypt(key)
  38. if err != nil {
  39. return false, err
  40. }
  41. if r.ResultCode != KRB5_KPASSWD_SUCCESS {
  42. return false, fmt.Errorf("error response from kadmin: code: %d; result: %s; krberror: %v", r.ResultCode, r.Result, r.KRBError)
  43. }
  44. cl.Credentials.WithPassword(newPasswd)
  45. return true, nil
  46. }
  47. func (cl *Client) sendToKPasswd(msg kadmin.Request) (r kadmin.Reply, err error) {
  48. _, kps, err := cl.Config.GetKpasswdServers(cl.Credentials.Domain(), true)
  49. if err != nil {
  50. return
  51. }
  52. addr := kps[1]
  53. b, err := msg.Marshal()
  54. if err != nil {
  55. return
  56. }
  57. if len(b) <= cl.Config.LibDefaults.UDPPreferenceLimit {
  58. return cl.sendKPasswdUDP(b, addr)
  59. }
  60. return cl.sendKPasswdTCP(b, addr)
  61. }
  62. func (cl *Client) sendKPasswdTCP(b []byte, kadmindAddr string) (r kadmin.Reply, err error) {
  63. tcpAddr, err := net.ResolveTCPAddr("tcp", kadmindAddr)
  64. if err != nil {
  65. return
  66. }
  67. conn, err := net.DialTCP("tcp", nil, tcpAddr)
  68. if err != nil {
  69. return
  70. }
  71. rb, err := cl.sendTCP(conn, b)
  72. err = r.Unmarshal(rb)
  73. return
  74. }
  75. func (cl *Client) sendKPasswdUDP(b []byte, kadmindAddr string) (r kadmin.Reply, err error) {
  76. udpAddr, err := net.ResolveUDPAddr("udp", kadmindAddr)
  77. if err != nil {
  78. return
  79. }
  80. conn, err := net.DialUDP("udp", nil, udpAddr)
  81. if err != nil {
  82. return
  83. }
  84. rb, err := cl.sendUDP(conn, b)
  85. err = r.Unmarshal(rb)
  86. return
  87. }