All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: "Philippe Mathieu-Daudé" <philmd@redhat.com>
Cc: qemu-devel@nongnu.org, "Markus Armbruster" <armbru@redhat.com>,
	"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
	"Eric Blake" <eblake@redhat.com>,
	"Andreas Färber" <afaerber@suse.de>,
	"Marc-André Lureau" <marcandre.lureau@redhat.com>,
	"Gerd Hoffmann" <kraxel@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v8 10/11] authz: add QAuthZPAM object type for authorizing using PAM
Date: Fri, 22 Feb 2019 14:49:12 +0000	[thread overview]
Message-ID: <20190222144912.GC25234@redhat.com> (raw)
In-Reply-To: <23bcdd12-bcc6-f452-f1df-55bcbcd90bec@redhat.com>

On Fri, Feb 22, 2019 at 02:27:26PM +0100, Philippe Mathieu-Daudé wrote:
> Hi Daniel,
> 
> On 2/22/19 1:24 PM, Daniel P. Berrangé wrote:
> > On Fri, Feb 22, 2019 at 01:34:12AM +0100, Philippe Mathieu-Daudé wrote:
> >> Hi Daniel,
> >>
> >> On 2/15/19 4:57 PM, Daniel P. Berrangé wrote:
> >>> From: "Daniel P. Berrange" <berrange@redhat.com>
> >>>
> >>> Add an authorization backend that talks to PAM to check whether the user
> >>> identity is allowed. This only uses the PAM account validation facility,
> >>> which is essentially just a check to see if the provided username is permitted
> >>> access. It doesn't use the authentication or session parts of PAM, since
> >>> that's dealt with by the relevant part of QEMU (eg VNC server).
> >>>
> >>> Consider starting QEMU with a VNC server and telling it to use TLS with
> >>> x509 client certificates and configuring it to use an PAM to validate
> >>> the x509 distinguished name. In this example we're telling it to use PAM
> >>> for the QAuthZ impl with a service name of "qemu-vnc"
> >>>
> >>>  $ qemu-system-x86_64 \
> >>>      -object tls-creds-x509,id=tls0,dir=/home/berrange/security/qemutls,\
> >>>              endpoint=server,verify-peer=yes \
> >>>      -object authz-pam,id=authz0,service=qemu-vnc \
> >>>      -vnc :1,tls-creds=tls0,tls-authz=authz0
> >>>
> >>> This requires an /etc/pam/qemu-vnc file to be created with the auth
> >>> rules. A very simple file based whitelist can be setup using
> >>>
> >>>   $ cat > /etc/pam/qemu-vnc <<EOF
> >>>   account         requisite       pam_listfile.so item=user sense=allow file=/etc/qemu/vnc.allow
> >>>   EOF
> >>>
> >>> The /etc/qemu/vnc.allow file simply contains one username per line. Any
> >>> username not in the file is denied. The usernames in this example are
> >>> the x509 distinguished name from the client's x509 cert.
> >>>
> >>>   $ cat > /etc/qemu/vnc.allow <<EOF
> >>>   CN=laptop.berrange.com,O=Berrange Home,L=London,ST=London,C=GB
> >>>   EOF
> >>>
> >>> More interesting would be to configure PAM to use an LDAP backend, so
> >>> that the QEMU authorization check data can be centralized instead of
> >>> requiring each compute host to have file maintained.
> >>>
> >>> The main limitation with this PAM module is that the rules apply to all
> >>> QEMU instances on the host. Setting up different rules per VM, would
> >>> require creating a separate PAM service name & config file for every
> >>> guest. An alternative approach for the future might be to not pass in
> >>> the plain username to PAM, but instead combine the VM name or UUID with
> >>> the username. This requires further consideration though.
> >>>
> >>> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> >>> ---
> > 
> >>> +static bool qauthz_pam_is_allowed(QAuthZ *authz,
> >>> +                                  const char *identity,
> >>> +                                  Error **errp)
> >>> +{
> >>> +    QAuthZPAM *pauthz = QAUTHZ_PAM(authz);
> >>> +    const struct pam_conv pam_conversation = { 0 };
> >>> +    pam_handle_t *pamh = NULL;
> >>> +    int ret;
> >>> +
> >>> +    trace_qauthz_pam_check(authz, identity, pauthz->service);
> >>> +    ret = pam_start(pauthz->service,
> >>> +                    identity,
> >>> +                    &pam_conversation,
> >>> +                    &pamh);
> >>> +    if (ret != PAM_SUCCESS) {
> >>> +        error_setg(errp, "Unable to start PAM transaction: %s",
> >>> +                   pam_strerror(NULL, ret));
> 
> "In an error case is the content of pamh undefined."
> So it is safer to use NULL here indeed.
> 
> >>> +        return false;
> >>> +    }
> >>> +
> >>> +    ret = pam_acct_mgmt(pamh, PAM_SILENT);
> >>> +    if (ret != PAM_SUCCESS) {
> >>> +        error_setg(errp, "Unable to authorize user '%s': %s",
> >>> +                   identity, pam_strerror(pamh, ret));
> >>> +        goto cleanup;
> >>> +    }
> >>> +
> >>> + cleanup:
> >>> +    pam_end(pamh, ret);
> >>> +    return ret == PAM_SUCCESS;
> 
> Hmm I find this fragile.
> 
> A 'cleanup' label means (to me) you expect someone to eventually add
> more code around, and I'm worried someone add a pam_smth() call after
> pam_acct_mgmt(), that sets ret to PAM_SUCCESS.
> 
> It looks safer to me to simply not use any label here (for the current
> code, if it is extended, we'll see).

> 
> If you agree on removing the 'cleanup' label in qauthz_pam_is_allowed(),
> for the whole patch:
> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>

Thanks, I will squash this in:

diff --git a/authz/pamacct.c b/authz/pamacct.c
index 8fe4c8ee11..5038358cdc 100644
--- a/authz/pamacct.c
+++ b/authz/pamacct.c
@@ -47,15 +47,14 @@ static bool qauthz_pam_is_allowed(QAuthZ *authz,
     }
 
     ret = pam_acct_mgmt(pamh, PAM_SILENT);
+    pam_end(pamh, ret);
     if (ret != PAM_SUCCESS) {
         error_setg(errp, "Unable to authorize user '%s': %s",
                    identity, pam_strerror(pamh, ret));
-        goto cleanup;
+        return false;
     }
 
- cleanup:
-    pam_end(pamh, ret);
-    return ret == PAM_SUCCESS;
+    return true;
 }
 
 

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|

  reply	other threads:[~2019-02-22 14:58 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-15 15:56 [Qemu-devel] [PATCH v8 00/11] Add a standard authorization framework Daniel P. Berrangé
2019-02-15 15:56 ` [Qemu-devel] [PATCH v8 01/11] util: add helper APIs for dealing with inotify in portable manner Daniel P. Berrangé
2022-01-28 16:17   ` Peter Maydell
2022-01-28 16:42     ` Daniel P. Berrangé
2019-02-15 15:57 ` [Qemu-devel] [PATCH v8 02/11] qom: don't require user creatable objects to be registered Daniel P. Berrangé
2019-02-15 15:57 ` [Qemu-devel] [PATCH v8 03/11] hw/usb: don't set IN_ISDIR for inotify watch in MTP driver Daniel P. Berrangé
2019-02-15 15:57 ` [Qemu-devel] [PATCH v8 04/11] hw/usb: fix const-ness for string params " Daniel P. Berrangé
2019-02-15 15:57 ` [Qemu-devel] [PATCH v8 05/11] hw/usb: switch MTP to use new inotify APIs Daniel P. Berrangé
2019-02-16 11:28   ` Marc-André Lureau
2019-02-15 15:57 ` [Qemu-devel] [PATCH v8 06/11] authz: add QAuthZ object as an authorization base class Daniel P. Berrangé
2019-02-15 15:57 ` [Qemu-devel] [PATCH v8 07/11] authz: add QAuthZSimple object type for easy whitelist auth checks Daniel P. Berrangé
2019-02-16 11:31   ` Marc-André Lureau
2019-02-15 15:57 ` [Qemu-devel] [PATCH v8 08/11] authz: add QAuthZList object type for an access control list Daniel P. Berrangé
2019-02-16 11:35   ` Marc-André Lureau
2019-02-15 15:57 ` [Qemu-devel] [PATCH v8 09/11] authz: add QAuthZListFile object type for a file " Daniel P. Berrangé
2019-02-16 11:40   ` Marc-André Lureau
2019-02-15 15:57 ` [Qemu-devel] [PATCH v8 10/11] authz: add QAuthZPAM object type for authorizing using PAM Daniel P. Berrangé
2019-02-22  0:34   ` Philippe Mathieu-Daudé
2019-02-22 12:24     ` Daniel P. Berrangé
2019-02-22 13:27       ` Philippe Mathieu-Daudé
2019-02-22 14:49         ` Daniel P. Berrangé [this message]
2019-02-15 15:57 ` [Qemu-devel] [PATCH v8 11/11] authz: delete existing ACL implementation Daniel P. Berrangé

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190222144912.GC25234@redhat.com \
    --to=berrange@redhat.com \
    --cc=afaerber@suse.de \
    --cc=armbru@redhat.com \
    --cc=dgilbert@redhat.com \
    --cc=eblake@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=philmd@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.