15348: Merge branch 'master'
[arvados.git] / lib / pam / pam_arvados.go
index ddca355b87148307a1e5e58747786e9ac25c509d..389033ba963575fb8c4e7b50054c95cb05bab211 100644 (file)
@@ -2,6 +2,23 @@
 //
 // SPDX-License-Identifier: Apache-2.0
 
+// To enable, add an entry in /etc/pam.d/common-auth where pam_unix.so
+// would normally be. Examples:
+//
+// auth [success=1 default=ignore] /usr/lib/pam_arvados.so zzzzz.arvadosapi.com vmhostname.example
+// auth [success=1 default=ignore] /usr/lib/pam_arvados.so zzzzz.arvadosapi.com vmhostname.example insecure debug
+//
+// Replace zzzzz.arvadosapi.com with your controller host or
+// host:port.
+//
+// Replace vmhostname.example with the VM's name as it appears in the
+// Arvados virtual_machine object.
+//
+// Use "insecure" if your API server certificate does not pass name
+// verification.
+//
+// Use "debug" to enable debug log messages.
+
 package main
 
 import (
@@ -38,6 +55,11 @@ func init() {
        }
 }
 
+//export pam_sm_setcred
+func pam_sm_setcred(pamh *C.pam_handle_t, flags, cArgc C.int, cArgv **C.char) C.int {
+       return C.PAM_IGNORE
+}
+
 //export pam_sm_authenticate
 func pam_sm_authenticate(pamh *C.pam_handle_t, flags, cArgc C.int, cArgv **C.char) C.int {
        runtime.GOMAXPROCS(1)
@@ -65,7 +87,7 @@ func pam_sm_authenticate(pamh *C.pam_handle_t, flags, cArgc C.int, cArgv **C.cha
        return C.PAM_SUCCESS
 }
 
-func authenticate(logger logrus.FieldLogger, username, token string, argv []string) error {
+func authenticate(logger *logrus.Logger, username, token string, argv []string) error {
        hostname := ""
        apiHost := ""
        insecure := false
@@ -76,6 +98,8 @@ func authenticate(logger logrus.FieldLogger, username, token string, argv []stri
                        hostname = arg
                } else if arg == "insecure" {
                        insecure = true
+               } else if arg == "debug" {
+                       logger.SetLevel(logrus.DebugLevel)
                } else {
                        logger.Warnf("unkown option: %s\n", arg)
                }
@@ -104,7 +128,11 @@ func authenticate(logger logrus.FieldLogger, username, token string, argv []stri
                return err
        }
        if len(vms.Items) == 0 {
-               return fmt.Errorf("no results for hostname %q", hostname)
+               // It's possible there is no VM entry for the
+               // configured hostname, but typically this just means
+               // the user does not have permission to see (let alone
+               // log in to) this VM.
+               return errors.New("permission denied")
        } else if len(vms.Items) > 1 {
                return fmt.Errorf("multiple results for hostname %q", hostname)
        } else if vms.Items[0].Hostname != hostname {
@@ -117,7 +145,7 @@ func authenticate(logger logrus.FieldLogger, username, token string, argv []stri
        }
        var links arvados.LinkList
        err = arv.RequestAndDecodeContext(ctx, &links, "GET", "arvados/v1/links", nil, arvados.ListOptions{
-               Limit: 10000,
+               Limit: 1,
                Filters: []arvados.Filter{
                        {"link_class", "=", "permission"},
                        {"name", "=", "can_login"},