summaryrefslogtreecommitdiff
path: root/kdc.go
diff options
context:
space:
mode:
authorMarkus Krogh <markus@nordu.net>2019-02-07 11:11:53 +0100
committerMarkus Krogh <markus@nordu.net>2019-02-07 11:11:53 +0100
commit7f437db53b49339615bbad9813e8beee522de493 (patch)
tree41fc0b15ea5d91141620d30ec8194845b23da3ab /kdc.go
parent51d49d000e012a99726057998dfb9fcc6c3e743c (diff)
Use kinit and kadmin directly rather than perl script
Diffstat (limited to 'kdc.go')
-rw-r--r--kdc.go93
1 files changed, 70 insertions, 23 deletions
diff --git a/kdc.go b/kdc.go
index 81dded1..0c35a16 100644
--- a/kdc.go
+++ b/kdc.go
@@ -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
+}