passwd.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package client
  2. import (
  3. "fmt"
  4. "github.com/jcmturner/gokrb5/v8/kadmin"
  5. "github.com/jcmturner/gokrb5/v8/messages"
  6. )
  7. // Kpasswd server response codes.
  8. const (
  9. KRB5_KPASSWD_SUCCESS = 0
  10. KRB5_KPASSWD_MALFORMED = 1
  11. KRB5_KPASSWD_HARDERROR = 2
  12. KRB5_KPASSWD_AUTHERROR = 3
  13. KRB5_KPASSWD_SOFTERROR = 4
  14. KRB5_KPASSWD_ACCESSDENIED = 5
  15. KRB5_KPASSWD_BAD_VERSION = 6
  16. KRB5_KPASSWD_INITIAL_FLAG_NEEDED = 7
  17. )
  18. // ChangePasswd changes the password of the client to the value provided.
  19. func (cl *Client) ChangePasswd(newPasswd string) (bool, error) {
  20. ASReq, err := messages.NewASReqForChgPasswd(cl.Credentials.Domain(), cl.Config, cl.Credentials.CName())
  21. if err != nil {
  22. return false, err
  23. }
  24. ASRep, err := cl.ASExchange(cl.Credentials.Domain(), ASReq, 0)
  25. if err != nil {
  26. return false, err
  27. }
  28. msg, key, err := kadmin.ChangePasswdMsg(cl.Credentials.CName(), cl.Credentials.Domain(), newPasswd, ASRep.Ticket, ASRep.DecryptedEncPart.Key)
  29. if err != nil {
  30. return false, err
  31. }
  32. r, err := cl.sendToKPasswd(msg)
  33. if err != nil {
  34. return false, err
  35. }
  36. err = r.Decrypt(key)
  37. if err != nil {
  38. return false, err
  39. }
  40. if r.ResultCode != KRB5_KPASSWD_SUCCESS {
  41. return false, fmt.Errorf("error response from kadmin: code: %d; result: %s; krberror: %v", r.ResultCode, r.Result, r.KRBError)
  42. }
  43. cl.Credentials.WithPassword(newPasswd)
  44. return true, nil
  45. }
  46. func (cl *Client) sendToKPasswd(msg kadmin.Request) (r kadmin.Reply, err error) {
  47. _, kps, err := cl.Config.GetKpasswdServers(cl.Credentials.Domain(), true)
  48. if err != nil {
  49. return
  50. }
  51. b, err := msg.Marshal()
  52. if err != nil {
  53. return
  54. }
  55. var rb []byte
  56. if len(b) <= cl.Config.LibDefaults.UDPPreferenceLimit {
  57. rb, err = dialSendUDP(kps, b)
  58. if err != nil {
  59. return
  60. }
  61. } else {
  62. rb, err = dialSendTCP(kps, b)
  63. if err != nil {
  64. return
  65. }
  66. }
  67. err = r.Unmarshal(rb)
  68. return
  69. }