package main import ( "fmt" "gopkg.in/jcmturner/gokrb5.v5/client" "gopkg.in/jcmturner/gokrb5.v5/config" "log" "os/exec" "strings" ) var suffixMap map[string]string = map[string]string{ "SSO": "", "EDUROAM": "/ppp", "TACACS": "/net", } func CheckDuplicatePw(username, password string) error { for suffix, _ := range suffixMap { err := checkKerberosDuplicatePw(suffix, username, password) if err != nil { return err } } return nil } func checkKerberosDuplicatePw(suffix, username, password string) error { principal := username + suffixMap[suffix] config, err := config.Load(pwman.Krb5Conf) kclient := client.NewClientWithPassword(principal, "NORDU.NET", password) kclient.WithConfig(config) err = kclient.Login() if err != nil { // error either means bad password or no connection etc. if containsEither(err.Error(), "KDC_ERR_PREAUTH", "Decrypting_Error", "KDC_ERR_C_PRINCIPAL_UNKNOWN") { // Password did not match return nil } fmt.Println("ERROR", err) return fmt.Errorf("Error while checking %s password for duplicate, got error: %v", suffix, err) } return fmt.Errorf("Password already used with: %s account", suffix) } func containsEither(what string, substr ...string) bool { for _, str := range substr { if strings.Contains(what, str) { return true } } return false } func ChangeKerberosPw(suffix, username, new_password string) error { kerberos_uid := fmt.Sprintf("%s%s", username, suffixMap[suffix]) // call script cmd := exec.Command(pwman.ChangePwScript) stdin, err := cmd.StdinPipe() if err != nil { return fmt.Errorf("Unable to open pipe for kerberos script: %v", err) } go func() { defer stdin.Close() fmt.Fprintf(stdin, "%s@NORDU.NET %s", kerberos_uid, new_password) }() out, err := cmd.CombinedOutput() if err != nil { log.Println("ERROR", "Error running change password script, got error:", err, "with script output:", string(out)) return fmt.Errorf("Error running change password script, got error: %v", err) } return nil }