]> git.proxmox.com Git - pve-access-control.git/log
pve-access-control.git
14 months agoauth: tfa: read tfa.cfg also if the user.cfg entry has no "x" marker
Friedrich Weber [Fri, 14 Jul 2023 11:49:50 +0000 (13:49 +0200)]
auth: tfa: read tfa.cfg also if the user.cfg entry has no "x" marker

Previously, `user_get_tfa` read the `keys` user attribute from
user.cfg to determine whether a user has second factors configured.
`keys` could contain TOTP secrets or Yubico key IDs (for realms that
require TFA), or the marker "x" to signify that second factors are
defined in tfa.cfg, in which case `user_get_tfa` would additionally
read tfa.cfg.

However, syncing an LDAP realm with `remove-vanished=properties`
erases the `keys` attribute, and thus the "x" marker (unless custom
`sync_attributes` with a mapping for `keys` are defined). This would
allow TFA-enabled users to log in without a second factor after a
realm sync. This issue was first reported in the forum [1].

To fix this issue, `user_get_tfa` now reads tfa.cfg unconditionally,
and thus independently of the value of `keys`. In other words, the "x"
marker is now irrelevant for authentication. The reasoning for this
change is that most current setups define second factors in tfa.cfg
anyway.

Special care is needed to avoid breaking realms that require TFA: In
that case, `user_get_tfa` must fail authentication if neither user.cfg
nor tfa.cfg define any second factors.

This patch changes the behavior of a hypothetical (and not officially
supported) LDAP realm setup in which `sync_attributes: keys=attr` and
`remove-vanished=properties` is used to maintain `keys` in the LDAP
directory. In such a setup, an admin could enable/disable TFA for a
user who has an enabled second factor in tfa.cfg by editing their LDAP
entry and switching between "x" and "". With this patch, TFA is always
enabled for that user.

This patch makes the "x" marker irrelevant for authentication, but PVE
still *writes* it if the user has second factors configured in
tfa.cfg. This behavior is kept for now to avoid issues in cluster
upgrade scenarios, where some nodes that still rely on the "x" marker
could allow logins without a second factor.

[1] https://forum.proxmox.com/threads/130440/

Suggested-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Friedrich Weber <f.weber@proxmox.com>
15 months agobump version to 8.0.3
Thomas Lamprecht [Wed, 21 Jun 2023 17:45:32 +0000 (19:45 +0200)]
bump version to 8.0.3

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agodrop assert_new_tfa_config_available for Proxmox VE 8
Thomas Lamprecht [Wed, 21 Jun 2023 17:43:37 +0000 (19:43 +0200)]
drop assert_new_tfa_config_available for Proxmox VE 8

All nodes should be new enough, especially as this is understood
since pve-manager 7.0-15 and users must upgrade to 7.4 before
upgrading to Proxmox VE 8

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agopveum: list tfa: sort by user ID
Thomas Lamprecht [Wed, 21 Jun 2023 17:41:31 +0000 (19:41 +0200)]
pveum: list tfa: sort by user ID

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agopveum: list tfa: recovery keys have no descriptions
Thomas Lamprecht [Wed, 21 Jun 2023 17:27:41 +0000 (19:27 +0200)]
pveum: list tfa: recovery keys have no descriptions

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agobump version to 8.0.2
Thomas Lamprecht [Wed, 21 Jun 2023 16:13:58 +0000 (18:13 +0200)]
bump version to 8.0.2

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agoapi: tfa: add missing links for child-routes
Thomas Lamprecht [Thu, 15 Jun 2023 14:55:41 +0000 (16:55 +0200)]
api: tfa: add missing links for child-routes

making this more useable in things like pvesh or the HTML formatter

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agoapi: tfa: don't block tokens from viewing and list TFA entries
Thomas Lamprecht [Thu, 15 Jun 2023 07:23:33 +0000 (09:23 +0200)]
api: tfa: don't block tokens from viewing and list TFA entries

The `allowtoken` property is a total, unconditional block on using
API tokens on an endpoint. We reserve those only for a limited set of
security critical endpoints like changing passwords or second
factors, or creating a (cookie) ticket, which are exempt from this
limitations, so require to have limited access to them too.

Anyhow, listing and getting TFA entries for users, where the API
token has the correct permissions granted, is not critical, as the
API token cannot gain more permissions than they have from that
info, so drop the total block on those GET methods.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agoapi: users: sort groups
Thomas Lamprecht [Wed, 14 Jun 2023 14:07:55 +0000 (16:07 +0200)]
api: users: sort groups

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agobump version to 8.0.1
Thomas Lamprecht [Fri, 9 Jun 2023 14:12:05 +0000 (16:12 +0200)]
bump version to 8.0.1

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agotfa: cope with native versions in cluster version check
Thomas Lamprecht [Fri, 9 Jun 2023 14:06:43 +0000 (16:06 +0200)]
tfa: cope with native versions in cluster version check

Reported-by: Friedrich Weber <f.weber@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agobump version to 8.0.0
Thomas Lamprecht [Fri, 9 Jun 2023 08:14:36 +0000 (10:14 +0200)]
bump version to 8.0.0

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agoapi: roles: forbid creatin new roles starting with "PVE" namespace
Thomas Lamprecht [Thu, 8 Jun 2023 07:31:19 +0000 (09:31 +0200)]
api: roles: forbid creatin new roles starting with "PVE" namespace

makes our reasoning when adding new top-level privileges way easier
in the future.
We already had two major upgrades with role additions where we had to
add special checks in the upgrade script and breaking changes, so
let's reserve any role starting with PVE (case-insensitive to avoid
confusion potential) and forbid creating those via API.

We might also think about letting the config parser choke on that, as
otherwise one could still create them via editing the config
manually.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agoapi: roles: cleanup imports
Thomas Lamprecht [Thu, 8 Jun 2023 07:29:25 +0000 (09:29 +0200)]
api: roles: cleanup imports

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agoapi: roles: whitespace and indendation clean-ups
Thomas Lamprecht [Thu, 8 Jun 2023 07:22:00 +0000 (09:22 +0200)]
api: roles: whitespace and indendation clean-ups

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agobump version to 8.0.0~3
Thomas Lamprecht [Wed, 7 Jun 2023 17:06:58 +0000 (19:06 +0200)]
bump version to 8.0.0~3

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agotests: adapt new test for admin ACL with mapping privs
Thomas Lamprecht [Wed, 7 Jun 2023 17:12:04 +0000 (19:12 +0200)]
tests: adapt new test for admin ACL with mapping privs

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agoadd privileges and paths for cluster resource mapping
Dominik Csapak [Tue, 6 Jun 2023 13:52:00 +0000 (15:52 +0200)]
add privileges and paths for cluster resource mapping

uses the privileges:

Mapping.Use
Mapping.Modify
Mapping.Audit

on /mapping/{TYPE}/{id}

so that we can assign privileges on resource level

this will generate new roles (PVEMappingUser, PVEMappingAdmin,
PVEMappingAuditor)

note that every user with Permissions.Modify on '/' and propagate can add these
new roles to themselves

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
15 months agoadd new SDN.use privilege in PVESDNUser role
Alexandre Derumier [Tue, 6 Jun 2023 13:19:25 +0000 (15:19 +0200)]
add new SDN.use privilege in PVESDNUser role

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
FG: fix test
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
15 months agocheck_sdn_bridge: check bridge first
Fabian Grünbichler [Wed, 7 Jun 2023 09:34:33 +0000 (11:34 +0200)]
check_sdn_bridge: check bridge first

it's cheap, so let's use it for early returning

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
15 months agocheck_sdn_bridge: correctly handle noerr
Fabian Grünbichler [Wed, 7 Jun 2023 09:33:39 +0000 (11:33 +0200)]
check_sdn_bridge: correctly handle noerr

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
15 months agorpcenvironnment: add check_sdn_bridge
Alexandre Derumier [Tue, 6 Jun 2023 13:19:24 +0000 (15:19 +0200)]
rpcenvironnment: add check_sdn_bridge

check if user have access to 1 vlan of the bridge
or the bridge itself

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
15 months agoaccess control: add /sdn/zones/<zone>/<vnet>/<vlan> path
Alexandre Derumier [Tue, 6 Jun 2023 13:19:18 +0000 (15:19 +0200)]
access control: add /sdn/zones/<zone>/<vnet>/<vlan> path

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
FG: add missing /sdn/zones path

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
15 months agorpcenv: api permission heuristic: query Sys.Modify for root ACL-path
Alexandre Derumier [Mon, 27 Mar 2023 10:18:20 +0000 (12:18 +0200)]
rpcenv: api permission heuristic: query Sys.Modify for root ACL-path

Ensures that we can use this in the capabilities heuristic check in
the web UI

Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
15 months agobump version to 8.0.0~2
Thomas Lamprecht [Wed, 7 Jun 2023 09:34:33 +0000 (11:34 +0200)]
bump version to 8.0.0~2

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agoacls: restrict less-privileged ACL modifications
Fabian Grünbichler [Mon, 5 Jun 2023 14:21:37 +0000 (16:21 +0200)]
acls: restrict less-privileged ACL modifications

there are currently three possibilities to modify ACLs without the
'Permissions.Modify' privilege in PVE::RPCEnvironment::check_perm_modify:

    if ($path =~ m|^/storage/.+$|) {
push @$testperms, 'Datastore.Allocate';
    } elsif ($path =~ m|^/vms/.+$|) {
push @$testperms, 'VM.Allocate';
    } elsif ($path =~ m|^/pool/.+$|) {
push @$testperms, 'Pool.Allocate';
    }

lock those down by only allowing the currently authenticated user to hand out a
subset of their own privileges, never more.

for example, this still allows a PVEVMAdmin to create ACLs for other
users/tokens with PVEVMUser (on '/vm/XXX'), but not with Administrator or
PVEPermAdmin.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
15 months agoroles: restrict Permissions.Modify to Administrator
Fabian Grünbichler [Mon, 5 Jun 2023 14:21:36 +0000 (16:21 +0200)]
roles: restrict Permissions.Modify to Administrator

to reduce the chances of accidentally handing out privilege modification
privileges. the old default setup of having Permissions.Modify in PVESysAdmin
and PVEAdmin weakened the distinction between those roles and Administrator.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
15 months agofix module namespace of realm sync API
Thomas Lamprecht [Wed, 7 Jun 2023 07:37:46 +0000 (09:37 +0200)]
fix module namespace of realm sync API

it isn't mounted in PVE::API2::AccessControl and it doesn't lives
anywhere in /access, so using that is just confusing.

Both, API and backend could simply move to manager, but as we already
got an api package here and it does somewhat fits into the topic lets
keep it here for now.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agoapi: realm sync: die early if no job options
Thomas Lamprecht [Wed, 7 Jun 2023 07:33:16 +0000 (09:33 +0200)]
api: realm sync: die early if no job options

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agoapi: realm sync: code cleanups
Thomas Lamprecht [Wed, 7 Jun 2023 07:32:26 +0000 (09:32 +0200)]
api: realm sync: code cleanups

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agorealm sync: cleanup imports
Thomas Lamprecht [Wed, 7 Jun 2023 07:31:39 +0000 (09:31 +0200)]
realm sync: cleanup imports

with: perlimports -i --no-padding

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agoadd realm-sync plugin for jobs and CRUD api for realm-sync-jobs
Dominik Csapak [Tue, 17 Jan 2023 11:46:54 +0000 (12:46 +0100)]
add realm-sync plugin for jobs and CRUD api for realm-sync-jobs

to be able to define automated jobs that sync ldap/ad

The jobs plugin contains special handling when no node is given, since
we only want it to run on a single node when that triggers. For that,
we save a statefile in /etc/pve/priv/jobs/ which contains the
node/time/upid of the node that runs the job. The first node that
is able to lock the realm (via cfs_lock_domain) "wins" and may
sync from the ldap.

in case a specific node was selected, this is omitted and the Jobs
handling will not let it run on other nodes anyway

the API part is our usual sectionconfig CRUD api, but specialized
for the specific type of job.

the api will be at /cluster/jobs/realm-sync
(this must be done in pve-manager)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
 [ T: resolve merge conflict due to packaging/source split ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
15 months agoapi: user index: only include existing tfa lock flags
Wolfgang Bumiller [Tue, 6 Jun 2023 09:18:56 +0000 (11:18 +0200)]
api: user index: only include existing tfa lock flags

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
15 months agobump version to 8.0.0~1
Wolfgang Bumiller [Mon, 5 Jun 2023 12:52:39 +0000 (14:52 +0200)]
bump version to 8.0.0~1

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
15 months agoapi: include tfa lock status in user list
Wolfgang Bumiller [Fri, 2 Jun 2023 09:28:34 +0000 (11:28 +0200)]
api: include tfa lock status in user list

this means /access/users is now a 'protected' call to get
access to 'priv/tfa.cfg'

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
15 months agotfa: update list_tfa return schema
Wolfgang Bumiller [Thu, 1 Jun 2023 10:26:10 +0000 (12:26 +0200)]
tfa: update list_tfa return schema

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
15 months agocli: add 'tfa unlock' command
Wolfgang Bumiller [Tue, 30 May 2023 09:55:08 +0000 (11:55 +0200)]
cli: add 'tfa unlock' command

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
15 months agoapi: add /access/users/<userid>/unlock-tfa api call
Wolfgang Bumiller [Tue, 30 May 2023 11:39:15 +0000 (13:39 +0200)]
api: add /access/users/<userid>/unlock-tfa api call

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
15 months agotfa: enable lockout of users via tfa.cfg
Wolfgang Bumiller [Tue, 16 May 2023 11:43:53 +0000 (13:43 +0200)]
tfa: enable lockout of users via tfa.cfg

This will be accompanied by a change in pve-rs to finally
enable this.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
15 months agobump pve-rs dep to 0.8.3
Wolfgang Bumiller [Mon, 5 Jun 2023 10:59:26 +0000 (12:59 +0200)]
bump pve-rs dep to 0.8.3

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
15 months agopam: set PAM_RHOST
Wolfgang Bumiller [Thu, 1 Jun 2023 09:36:54 +0000 (11:36 +0200)]
pam: set PAM_RHOST

This allows pam modules to restrict users by host. For
instance, you could restrict root@pam to only 127.0.0.1.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
15 months agocli: add 'tfa list' command
Wolfgang Bumiller [Tue, 30 May 2023 11:00:04 +0000 (13:00 +0200)]
cli: add 'tfa list' command

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
15 months agodrop support for old login API
Wolfgang Bumiller [Tue, 16 May 2023 11:56:13 +0000 (13:56 +0200)]
drop support for old login API

The new-format parameter for the ticket call is now ignored
and assumed 1.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
15 months agoapi: drop old verify_tfa api call
Wolfgang Bumiller [Tue, 16 May 2023 11:48:45 +0000 (13:48 +0200)]
api: drop old verify_tfa api call

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
16 months agodepend on pve-rs 0.8.0
Wolfgang Bumiller [Mon, 22 May 2023 08:27:15 +0000 (10:27 +0200)]
depend on pve-rs 0.8.0

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
16 months agoadd anyevent to build deps
Wolfgang Bumiller [Tue, 16 May 2023 12:23:15 +0000 (14:23 +0200)]
add anyevent to build deps

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
16 months agobump version to 7.99.0
Thomas Lamprecht [Sun, 21 May 2023 10:06:18 +0000 (12:06 +0200)]
bump version to 7.99.0

use a pre-release like version as we got some breaking changes
planned for access control, so might be nice to get (most of) them in
a 8.0.0 for simpler versioned  dependencies (>= 8~), but it's also
just a bit of an experiment to see how doing such things plays out,
in the end we can cope with whatever versioning for dependency as bug
fixes might make it necessary to have a more specific version
boundary anyway.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
16 months agod/control: raise standards version compliance to 4.6.2
Thomas Lamprecht [Sun, 21 May 2023 10:38:00 +0000 (12:38 +0200)]
d/control: raise standards version compliance to 4.6.2

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
16 months agod/control: define compat level via build-depends and raise to 13
Thomas Lamprecht [Sun, 21 May 2023 09:18:56 +0000 (11:18 +0200)]
d/control: define compat level via build-depends and raise to 13

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
16 months agooathkeygen: modernize and improve error handling slightly
Thomas Lamprecht [Sun, 21 May 2023 10:34:19 +0000 (12:34 +0200)]
oathkeygen: modernize and improve error handling slightly

Note that this could also just be documented doing:

 dd if=/dev/urandom bs=1 count=10 2>/dev/null | base32

And using TOTP apps that can scan QR codes is much better UX anyway,
but its to trivial to bother deprecating it now and we'd still depend
on libmime-base32-perl, so really nothing gained in removing or
rewriting in shell..

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
16 months agobuildsys: add sbuild convenience target
Thomas Lamprecht [Sun, 21 May 2023 10:06:06 +0000 (12:06 +0200)]
buildsys: add sbuild convenience target

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
16 months agobuildsys: cleanup and expand clean target
Thomas Lamprecht [Sun, 21 May 2023 10:05:12 +0000 (12:05 +0200)]
buildsys: cleanup and expand clean target

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
16 months agosrc makefiles: convert to use simple parenthesis
Thomas Lamprecht [Sun, 21 May 2023 09:47:08 +0000 (11:47 +0200)]
src makefiles: convert to use simple parenthesis

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
16 months agobuildsys: drop useless packaging variable/includes in src
Thomas Lamprecht [Sun, 21 May 2023 09:46:27 +0000 (11:46 +0200)]
buildsys: drop useless packaging variable/includes in src

and allow overriding the PACKAGE variable, making it actually useful

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
16 months agobuildsys: rework clean target, avoid doc-gen one
Thomas Lamprecht [Sun, 21 May 2023 09:42:21 +0000 (11:42 +0200)]
buildsys: rework clean target, avoid doc-gen one

1. this really doesn't change often
2. the synopsis and opts should be in the owner repo anyway
3. the original one simply deleted all *.adoc files, far to
   aggressive

Avoids pve-docs dependency for building the DSC (without having to
pass the ugly no-pre-clean option).

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
16 months agobuildsys: derive upload dist automatically
Thomas Lamprecht [Sun, 21 May 2023 09:19:16 +0000 (11:19 +0200)]
buildsys: derive upload dist automatically

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
16 months agobuildsys: don't pass arch for an arch: all package
Thomas Lamprecht [Sun, 21 May 2023 09:18:36 +0000 (11:18 +0200)]
buildsys: don't pass arch for an arch: all package

it was wrong too anyway, if, one would need to use the
$(DEB_HOST_ARCH), as that's the one package is built for.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
16 months agouse combined dpkg packaging variable makefile fragment
Thomas Lamprecht [Sun, 21 May 2023 08:53:20 +0000 (10:53 +0200)]
use combined dpkg packaging variable makefile fragment

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
16 months agomakefile: convert to use simple parenthesis
Thomas Lamprecht [Sun, 21 May 2023 08:52:58 +0000 (10:52 +0200)]
makefile: convert to use simple parenthesis

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
16 months agobump version to 7.4-3
Wolfgang Bumiller [Tue, 16 May 2023 11:33:54 +0000 (13:33 +0200)]
bump version to 7.4-3

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
16 months agouse TFA authentication api v2
Wolfgang Bumiller [Mon, 15 May 2023 07:06:28 +0000 (09:06 +0200)]
use  TFA authentication api v2

Previously `authentication_verify` just `die`d on error and
would only return a boolean whether `priv/tfa.cfg` needs
updating as a positive result.

Since we want to support locking TOTP as well as a general
TFA lock-out via the config, we also want to be able to tell
when this occurs. Most of it is handled by the TFA rust
crate already, but notifying users needs to be done on this
end instead.

In pve-rs we now have a different API for this:
`authentication_verify2`, which, instead of die()ing on
errors, always returns a hash containing the result as well
as the flags 'tfa-limit-reached' and 'totp-limit-reached'
which, if set, tell us to notify the user.

However, doing so will introduce new fields in the
`priv/tfa.cfg` in a struct marked as `deny_unknown_fields`,
so in a cluster, the limits & notification handling should
only be done once we can be sure that all nodes are up to
date.

These fields are only introduced on login errors, so for
now, handle a failed result early without saving
`priv/tfa.cfg`.
The only case where saving the file was previously required
was when *successfully* logging in with a recovery key, by
which we cannot be reaching a limit, so this should still be
safe.

Once we can validate that all cluster nodes are up to date,
we can implement the notification system.
A commented-out code structure for this is included in this
patch.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
17 months agofix various perlcritic lints
Thomas Lamprecht [Tue, 11 Apr 2023 13:45:38 +0000 (15:45 +0200)]
fix various perlcritic lints

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
17 months agooathkeygen: code style fixes
Thomas Lamprecht [Tue, 11 Apr 2023 13:13:43 +0000 (15:13 +0200)]
oathkeygen: code style fixes

we probably should just deprecate this altogether as it could be
worked around by doing a simple

 dd if=/dev/urandom bs=1 count=10 status=none | base32

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
18 months agobump version to 7.4-2
Thomas Lamprecht [Thu, 23 Mar 2023 14:44:29 +0000 (15:44 +0100)]
bump version to 7.4-2

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
18 months agofix #4609: allow valid DN in ldap/ad realm config
Dominik Csapak [Thu, 23 Mar 2023 13:14:29 +0000 (14:14 +0100)]
fix #4609: allow valid DN in ldap/ad realm config

We previously added support for ',' in the DNS attribute through
allowing a quoted format, but the regex used was made too
restrictive.

In the new quoted attribute we'd only allow \w (alphanumeric and _)
and the restricted characters. This patch now changes that to allow
everything except the quotation mark " itself, which is again closer
to the original regex which did not care for quotation and allowed
everything aside from ','.

The unquoted attributes did not allow spaces anymore, but the RFC [0]
actually makes it clear that spaces are only forbidden at the
beginning and the end (same for #). So, fix the regex to accommodate
for that and allow space and # characters again if not at the end or
beginning.

0: https://www.ietf.org/rfc/rfc2253.txt

Fixes: 1aa2355 ("ldap: Allow quoted values for DN attribute values")
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
Tested-by: Friedrich Weber <f.weber@proxmox.com>
 [ T: make fixes a trailer and rework commit message ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
18 months agobump version to 7.4-1
Thomas Lamprecht [Mon, 20 Mar 2023 16:16:15 +0000 (17:16 +0100)]
bump version to 7.4-1

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
18 months agoldap: Allow quoted values for DN attribute values
Christoph Heiss [Tue, 31 Jan 2023 12:50:42 +0000 (13:50 +0100)]
ldap: Allow quoted values for DN attribute values

This fixes #3748 by allowing reserved characters in `bind_dn` (and
other properties of the same format) if they are properly quoted and
adds some corresponding documentation regarding that.

This was tested by setting up a slapd server and creating a user with
the CN `Test, User` much like in the bug report, then using this user
as `bind_dn` in the sync options. I also tested some variants of that
CN, including just `TestUser`.)

One thing that still won't work is syncing of LDAP users with colons
or slashes in their CNs. In such cases, the message
> value 'Test, User@ldap' does not look like a valid user name
will pop up.

This is due to spaces and colons being explicitly disallowed in
usernames by PVE access-control's username schema. This probably
means that such names can never be allowed, which is being documented
too as separate pve-docs patch.

Note that while this is now a bit more strict for some cases too,
they should not matter in practice. For context; see RFC 2253 [0],
section 4. Interestingly, this document was obsoleted by RFC 4514 [1]
in 2006, which only mentions this in section 2.4 ("Converting an
AttributeValue from ASN.1 to a String") and appendix A ("Presentation
Issues").

But the first one seems to be the "authoritive" document on this
matter, at least looking at some other docs about LDAP DNs (RedHat,
Microsoft, ..).

[0] https://www.ietf.org/rfc/rfc2253.txt
[1] https://docs.ldap.com/specs/rfc4514.txt

Reviewed-by: Dominik Csapak <d.csapak@proxmox.com>
Tested-by: Dominik Csapak <d.csapak@proxmox.com>
Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
 [ T: added commit message ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
18 months agorealm sync: refactor scope/remove-vanished into a standard option
Dominik Csapak [Tue, 17 Jan 2023 11:46:53 +0000 (12:46 +0100)]
realm sync: refactor scope/remove-vanished into a standard option

so that we can reuse it easily

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
18 months agobump version to 7.3-2
Thomas Lamprecht [Mon, 6 Mar 2023 10:40:15 +0000 (11:40 +0100)]
bump version to 7.3-2

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
18 months agouserid format: clarify that this is the full name@realm in description
Thomas Lamprecht [Mon, 6 Mar 2023 09:41:37 +0000 (10:41 +0100)]
userid format: clarify that this is the full name@realm in description

as it recently confused a user in the forum.

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
18 months agofix #4518: improve ACL computation performance
Fabian Grünbichler [Wed, 15 Feb 2023 09:44:13 +0000 (10:44 +0100)]
fix #4518: improve ACL computation performance

by switching to a tree-based in-memory structure, like we do in PBS.

instead of parsing ACL entries into a hash using the full ACL path as key for
each entry, parse them into a tree-like nested hash. when evaluating ACLs,
iterating over all path prefixes starting at '/' is needed anyway, so this is a
more natural way to store and access the parsed configuration.

some performance data, timing `pveum user permissions $user > /dev/null` for
various amounts of ACL entries in user.cfg

entries | stock  | patched  | speedup
-------------------------------------
     1k | 1.234s |   0.241s |    5.12
     2k | 4.480s |   0.262s |   17.09
    20k |  7m25s |   0.987s |  450.86

similarly, an /access/ticket request such as the one happening on login goes
down from 4.27s to 109ms with 2k entries (testing with 20k entries fails
because the request times out after 30s, but with the patch it takes 336ms).

the underlying issue is that these two code paths not only iterate over *all
defined ACL paths* to get a complete picture of a user's/token's privileges,
but the fact that that ACL computation for each checked path itself did another
such loop in PVE::AccessControl::roles().

it is enough to iterate over the to-be-checked ACL path in a component-wise
fashion in order to handle role propagation, e.g., when looking at /a/b/c/d,
iterate over

/
/a
/a/b
/a/b/c
/a/b/c/d

in turn instead of all defined ACL paths.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
20 months agod/control: wrap-and-sort
Fabian Grünbichler [Tue, 10 Jan 2023 13:49:35 +0000 (14:49 +0100)]
d/control: wrap-and-sort

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
20 months agobuild: add missing build-dependency
Fabian Grünbichler [Tue, 10 Jan 2023 13:48:50 +0000 (14:48 +0100)]
build: add missing build-dependency

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
21 months agobump version to 7.3-1
Thomas Lamprecht [Fri, 16 Dec 2022 12:11:08 +0000 (13:11 +0100)]
bump version to 7.3-1

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
21 months agorealm: sync: allow explicit 'none' for 'remove-vanished' option
Dominik Csapak [Tue, 6 Dec 2022 11:06:30 +0000 (12:06 +0100)]
realm: sync: allow explicit 'none' for 'remove-vanished' option

with that, the api call can now override the default option
that is set on the realm (if any) by providing 'none'

it was not possible previously to override the realm default
when one wanted no properties to delete

no other code changes are necessary since we only extract the
known values 'acl' etc. and 'none' has no meaning there

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
22 months agobump version to 7.2-5
Thomas Lamprecht [Thu, 17 Nov 2022 12:09:21 +0000 (13:09 +0100)]
bump version to 7.2-5

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
22 months agoprivs: add Sys.Incoming
Fabian Grünbichler [Wed, 28 Sep 2022 12:50:47 +0000 (14:50 +0200)]
privs: add Sys.Incoming

for guarding cross-cluster data streams like guest migrations and
storage migrations.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
23 months agoauthenticate_user: pass undef instead of empty $tfa_challenge to authenticate_2nd_new
Dominik Csapak [Fri, 21 Oct 2022 08:31:17 +0000 (10:31 +0200)]
authenticate_user: pass undef instead of empty $tfa_challenge to authenticate_2nd_new

just above, we check & return if $tfa_challenge is set, so there is no
way that it would be set here. To make it clearer that it must be undef
here pass it as such.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
23 months agoauthenticate_2nd_new: rename $otp to $tfa_response
Dominik Csapak [Fri, 21 Oct 2022 08:31:16 +0000 (10:31 +0200)]
authenticate_2nd_new: rename $otp to $tfa_response

since that is what it really is, not only a otp

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
23 months agoauthenticate_2nd_new: only lock tfa config for recovery keys
Dominik Csapak [Fri, 21 Oct 2022 08:31:15 +0000 (10:31 +0200)]
authenticate_2nd_new: only lock tfa config for recovery keys

we currently only need to lock the tfa config when we got a recovery key
as a tfa challenge response, since that's the only thing that can
actually change the tfa config (every other method only reads from
there).

so to do that, factor out the code that was inside the lock, and call it
with/without lock depending on the tfa challenge response

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
2 years agoauth ldap/ad: compare group member dn case-insensitively
Stoiko Ivanov [Mon, 29 Aug 2022 16:07:55 +0000 (18:07 +0200)]
auth ldap/ad: compare group member dn case-insensitively

currently we add a user to a group if it's DN is listed in the
member-attributes of a group. The comparison for this is done via
existence check of a hash key, which is case-sensitive.

The equality for DNs is defined in a not straight forward way [0]:
(roughly translating to you need to honor the equality rules for each
'component' (RDN) of the DN) and is implementation-specific (Microsoft
AD is case-insensitive).

While this patch does not address the complete complexity of comparing
DNs it should work fine in practice.

issue with case-sensitive mismatches was reported in our community
forum:
https://forum.proxmox.com/threads/.113387

tested against a local test-vm used for reproducing the issue.

[0] https://ldapwiki.com/wiki/Distinguished%20Name%20Case%20Sensitivity

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
2 years agotfa: pass whole webauthn config to 'set_webauthn_config'
Wolfgang Bumiller [Mon, 25 Jul 2022 11:52:56 +0000 (13:52 +0200)]
tfa: pass whole webauthn config to 'set_webauthn_config'

the field names are being kept compatible

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2 years agoapi: realm sync: avoid separate log line for "remove-vanished" opt
Thomas Lamprecht [Tue, 19 Jul 2022 10:07:58 +0000 (12:07 +0200)]
api: realm sync: avoid separate log line for "remove-vanished" opt

can be a bit confusing and not really necessary, just inline it with
the "syncing user/group" message

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 years agobump version to 7.2-4
Thomas Lamprecht [Thu, 14 Jul 2022 06:36:58 +0000 (08:36 +0200)]
bump version to 7.2-4

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 years agoauth key: fix double rotation in clusters
Fabian Grünbichler [Wed, 13 Jul 2022 13:13:59 +0000 (15:13 +0200)]
auth key: fix double rotation in clusters

there is a (hard to trigger) race that can cause a double rotation of
the auth key, with potentially confusing fallout (various processes on
different nodes having an inconsistent view of the current and previous
auth keys, resulting in "random" invalid ticket errors until the next
proper key rotation 24h later).

the underlying cause is that `stat()` calls are excempt from our
otherwise non-cached/direct_io handling of pmxcfs I/O, which allows the
following sequence of events to take place:

LAST: mtime of current auth key

- current epoch advances to LAST + 24h

the following can be arbitrarly interleaved between node A and B:
- LAST+24h node A: pvedaemon/pvestatd on node A calls check_authkey(1)
- LAST+24h node A: it returns 0 (rotation required)
- LAST+24h node A: rotate_key() is called
- LAST+24h node A: cfs_lock_authkey is called
- LAST+24h node B: pvedaemon/pvestatd calls check_authkey(1)
- LAST+24h node B: key is not yet cached in-memory by current process
- LAST+24h node B: key file is opened, stat-ed, read, parsed, and content+mtime
  is cached (the kernel will now cache this stat result for 1s unless
  the path is opened)
- LAST+24h node B: it returns 0 (rotation required)
- LAST+24h node B: rotate_key() is called
- LAST+24h node B: cfs_lock_authkey is called

the following is mutex-ed via a cfs_lock:
- LAST+24h node A: lock is obtained
- LAST+24h node A: check_authkey() is called
- LAST+24h node A: key is stat-ed, mtime is still (correctly) LAST,
  cached mtime and content are returned
- LAST+24h node A: it returns 0 (rotation still required)
- LAST+24h node A: get_pubkey() is called and returns current auth key
- LAST+24h node A: new keypair is generated and persisted
- LAST+24h node A: cfs_lock is released
- LAST+24h node B: changes by node A are processed by pmxcfs
- LAST+24h node B: lock is obtained
- LAST+24h node B: check_authkey() is called
- LAST+24h node B: key is stat-ed, mtime is (incorrectly!) still LAST
  since the stat call is handled by the kernel/page cache, not by
  pmxcfs, cached mtime and content are returned
- LAST+24h node B: it returns 0 (rotation still required)
- LAST+24h node B: get_pubkey() is called and returns either previous or
  key written by node A (depending on whether page cache or pmxcfs
  answers stat call)
- LAST+24h node B: new keypair is generated, key returned by last
  get_pubkey call is written as old key

the end result is that some nodes and process will treat the key
generated by node A as "current", while others will treat the one
generated by nodoe B as "current". both have the same mtime, so the
in-memory cache hash won't be updated unless the service is restarted or
another rotation happens. depending on who generated the ticket and who
attempts validating it, a ticket might be rejected as invalid even
though the generating party would treat it as valid, and time on all
nodes is properly synced.

there seems to be now way for pmxcfs to pro-actively invalidate the page
cache entry safely (since we'd need to do so while writes to the same
path can happen concurrently), so work around by forcing an open/close
at the (stat) call site which does the work for us. regular reads are
not affected since those already bypass the page cache entirely anyway.

thankfully in almost all cases, the following sequence has enough
synchronization overhead baked in to avoid triggering the issue almost
entirely:

- cfs_lock
- generate key
- create tmp file for old key
- write tmp file
- rename tmp file into proper place
- create tmp file for new pub key
- write tmp file
- rename tmp file into proper place
- create tmp file for new priv key
- write tmp file
- rename tmp file into proper place
- release lock

that being said, there has been at least one report where this was
triggered in the wild from time to time.

it is easy to reproduce by increasing the attr_timeout and entry_timeout
fuse settings inside pmxcfs to increase the time stat results are
treated as valid/retained in the page cache:

-----8<-----
 diff --git a/data/src/pmxcfs.c b/data/src/pmxcfs.c
 index d78a248..e3e807b 100644
 --- a/data/src/pmxcfs.c
 +++ b/data/src/pmxcfs.c
 @@ -935,7 +935,7 @@ int main(int argc, char *argv[])

   mkdir(CFSDIR, 0755);

 - char *fa[] = { "-f", "-odefault_permissions", "-oallow_other", NULL};
 + char *fa[] = { "-f", "-odefault_permissions", "-oallow_other", "-oentry_timeout=5", "-oattr_timeout=5", NULL};

   struct fuse_args fuse_args = FUSE_ARGS_INIT(sizeof (fa)/sizeof(gpointer) - 1, fa);

----->8-----

in which case it's even easy to trigger more than double rotation in a
bigger test cluster (stopping all PVE services except for pve-cluster
helps avoiding interference):

on a single node:
$ touch --date yesterday /etc/pve/authkey.pub

in parallel (i.e., via tmux synchronized panes):
-----8<-----
use strict;
use warnings;
use PVE::Cluster;
use PVE::AccessControl;
PVE::Cluster::cfs_update();

# ensure page cache entry is there
PVE::AccessControl::check_authkey(1);
PVE::AccessControl::check_authkey(1);
# now attempt rotation
PVE::AccessControl::rotate_authkey();
----->8-----

Thanks to Wolfgang Bumiller for assistance in triaging and exploring
various avenues of fixing.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2 years agofix #4074: increase API OpenID code size limit to 2048
Mira Limbeck [Wed, 15 Jun 2022 14:09:50 +0000 (16:09 +0200)]
fix #4074: increase API OpenID code size limit to 2048

Azure AD seems to have a variable authorization code size, depending on
the browser state according to one report in bug #4074 [0].

Sometimes the size is greater than our current limit of 1024, so
increase it to 2048.

The RFC [1] mentions that there is no limit to the code size, but based on
current experience, a size limit of 2048 might be enough for every
current OpenID Connect provider.

[0] https://bugzilla.proxmox.com/show_bug.cgi?id=4074
[1] https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2

Signed-off-by: Mira Limbeck <m.limbeck@proxmox.com>
[w.bumiller@proxmox.com: bump to 4096]
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2 years agobump version to 7.2-3
Thomas Lamprecht [Mon, 20 Jun 2022 13:51:19 +0000 (15:51 +0200)]
bump version to 7.2-3

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 years agoperm check: forbid undefined/empty ACL path
Fabian Grünbichler [Mon, 20 Jun 2022 11:05:12 +0000 (13:05 +0200)]
perm check: forbid undefined/empty ACL path

to detect similar issues to that fixed in the previous commit early on
and without the potential for dangerous side-effects.

root@pam is intentionally still allowed before the check in case such
situations can be triggered by misconfiguration - root@pam can then
still clean up the affected configs via the GUI/API, and not just via
manual editing.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2 years agoapi2: token: use userid-group as API perm check
Fabian Grünbichler [Mon, 20 Jun 2022 11:05:11 +0000 (13:05 +0200)]
api2: token: use userid-group as API perm check

the previous version using an ACL path of '/access/users/{userid}' was
broken for non-root users, since the '@' character always contained in a
userid is not allowed in ACL paths.

this effectively meant that creating API tokens only worked for:
- root@pam (ACL checks skipped altogether)
- users with User.Modify on '/' with propagation (the roles/privs for
  '/' are propagated to the undefined path in this case)
- users creating their own tokens (first branch of 'or')

the userid-group check is used for all other modifications of user
entities, so it can also be used for creating/modifying/removing API
tokens.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2 years agobump version to 7.2-2
Thomas Lamprecht [Fri, 3 Jun 2022 12:02:35 +0000 (14:02 +0200)]
bump version to 7.2-2

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 years agoREADME: break long lines
Thomas Lamprecht [Fri, 3 Jun 2022 11:58:46 +0000 (13:58 +0200)]
README: break long lines

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 years agotree wide: typo fixes
Thomas Lamprecht [Fri, 3 Jun 2022 11:58:07 +0000 (13:58 +0200)]
tree wide: typo fixes

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 years agopermissions: add some more comments
Fabian Grünbichler [Fri, 3 Jun 2022 11:50:49 +0000 (13:50 +0200)]
permissions: add some more comments

for future reference/changes.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2 years agopermissions: fix token/user priv intersection
Fabian Grünbichler [Fri, 3 Jun 2022 11:50:48 +0000 (13:50 +0200)]
permissions: fix token/user priv intersection

the token/user priv intersection could only honored user privs that had
the propagation flag set, reducing the scope of the token more than
intended.

the pre-existing test case actually triggered the broken behaviour, but
the expected value matched it so it was not noticed.

Fixes: e8a0cee47bb477162f291e67144ea0c0df47f2ee "rpcenv: improve user/token intersection"
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2 years agopermissions: properly merge propagation flag
Fabian Grünbichler [Fri, 3 Jun 2022 11:50:47 +0000 (13:50 +0200)]
permissions: properly merge propagation flag

when multiple roles are defined on a path that share a privilege, this
randomly took the propagation flag for the priv from the last role
encountered. since perl hashes are iterated randomly, this means the
propagation flag was sometimes set correctly, and sometimes not.

note that this propagation flag is only used for display/dumping
purposes, and for intersection with token privs (see next commit).
actual handling of propagation happens on the role level in
PVE::AccessControl::roles().

modified test case (spuriously) fails without the fix.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
2 years agobump version to 7.2-1
Thomas Lamprecht [Tue, 31 May 2022 11:43:47 +0000 (13:43 +0200)]
bump version to 7.2-1

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 years agoaccess check: include user/token id in expired exception
Thomas Lamprecht [Tue, 31 May 2022 11:32:36 +0000 (13:32 +0200)]
access check: include user/token id in expired exception

not that relevant for the user as the daemon auth log already
contains that info, but for token it can be nice.

The API response is always just a plain "401 auth failure" in any
case (expired or wrong creds)

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 years agocheck user: re-order enable check first again and adhere noerr flag
Thomas Lamprecht [Tue, 31 May 2022 11:31:23 +0000 (13:31 +0200)]
check user: re-order enable check first again and adhere noerr flag

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 years agouser check: fix expiration/enable order
Oguz Bektas [Tue, 31 May 2022 10:58:52 +0000 (12:58 +0200)]
user check: fix expiration/enable order

Signed-off-by: Oguz Bektas <o.bektas@proxmox.com>
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
2 years agobump version to 7.1-8
Thomas Lamprecht [Thu, 28 Apr 2022 15:02:54 +0000 (17:02 +0200)]
bump version to 7.1-8

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>