github.com/jcmturner/gokrb5/v8@v8.4.4/client/passwd.go (about)

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