diff options
Diffstat (limited to 'kdc.go')
-rw-r--r-- | kdc.go | 93 |
1 files changed, 70 insertions, 23 deletions
@@ -2,12 +2,18 @@ package main import ( "fmt" - "gopkg.in/jcmturner/gokrb5.v5/client" - "gopkg.in/jcmturner/gokrb5.v5/config" "log" + "os" "os/exec" + "strings" ) +type Krb5Conf struct { + Principal string + Keytab string + Realm string +} + var suffixMap map[string]string = map[string]string{ "SSO": "", "EDUROAM": "/ppp", @@ -25,42 +31,83 @@ func CheckDuplicatePw(username, password string) error { } func checkKerberosDuplicatePw(suffix, username, password string) error { - principal := username + suffixMap[suffix] + // KRB5_CONFIG env for heimdal-kinit + // KRB5CCNAME for setting the cache name + + principal := fmt.Sprintf("%s%s@%s", username, suffixMap[suffix], pwman.Krb5Conf.Realm) + + cmd := exec.Command("kinit", "--password-file=STDIN", principal) + cmd.Env = append(os.Environ()) + cmd.Stdin = strings.NewReader(password) + + out, err := cmd.CombinedOutput() - 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 + // everything is fine, it should fail + if containsEither(string(out), "kinit: Password incorrect", "krb5_get_init_creds") { return nil } - fmt.Println("ERROR", err) - return fmt.Errorf("Error while checking %s password for duplicate, got error: %v", suffix, err) + return fmt.Errorf("Error while checking %s password for duplicate, got error: %v, Output: %s", suffix, err, out) } + + // Run kdestroy to log out + kdest := exec.Command("kdestroy") + kdest.Run() + return fmt.Errorf("Password already used with: %s account", suffix) } 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() + conf := pwman.Krb5Conf + kerberos_uid := fmt.Sprintf("%s%s@%s", username, suffixMap[suffix], conf.Realm) + + err := ensureCreatedKerberosPrincipal(kerberos_uid) + if err != nil { - return fmt.Errorf("Unable to open pipe for kerberos script: %v", err) + return err } - go func() { - defer stdin.Close() - fmt.Fprintf(stdin, "%s@NORDU.NET %s", kerberos_uid, new_password) - }() + cmd := exec.Command("kadmin", "-K", conf.Keytab, "-p", conf.Principal, "cpw", "-p", new_password, kerberos_uid) 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) + log.Println("ERROR", "Error runing kadmin for change password, got error:", err, "with script output:", string(out)) + return fmt.Errorf("Error could not change password, got error: %v", err) } return nil } + +func ensureCreatedKerberosPrincipal(principal string) error { + conf := pwman.Krb5Conf + exists, err := checkKerberosPrincipalExists(principal) + + if err != nil { + return err + } + + if !exists { + cmd := exec.Command("kadmin", "-K", conf.Keytab, "-p", conf.Principal, "add", "--use-defaults", "--random-password", principal) + out, err := cmd.CombinedOutput() + + if err != nil { + fmt.Errorf("Could not create principal %s, got error: %v, output: %s", principal, err, out) + } + } + return nil +} + +func checkKerberosPrincipalExists(principal string) (bool, error) { + conf := pwman.Krb5Conf + cmd := exec.Command("kadmin", "-K", conf.Keytab, "-p", conf.Principal, "get", principal) + // get markus/ppp: Principal does not exist + out, err := cmd.CombinedOutput() + + if err != nil { + if containsEither(string(out), "Principal does not exist") { + return false, nil + } + return false, fmt.Errorf("Could not check if principal %s exists, got error: %v, output: %s", principal, err, out) + } + return true, nil +} |