dCache / dcache

dCache - a system for storing and retrieving huge amounts of data, distributed among a large number of heterogenous server nodes, under a single virtual filesystem tree with a variety of standard access methods
https://dcache.org
291 stars 136 forks source link

gPlazma/multimap: request: when multiple UIDs match, pick first or last #7174

Open onnozweers opened 1 year ago

onnozweers commented 1 year ago

Dear dCache devs,

Recently we discussed multiple UID matches in the multimap auth plugin on the dCache user mailinglist. When multimap finds two or more UIDs, authentication fails.

Example, with a double group membership, each leading to a specific UID:

 |   +--multimap OPTIONAL:OK => OK
 |   |      added: GidPrincipal[47014,primary]
 |   |             GroupNamePrincipal[ska]
 |   |             GroupNamePrincipal[escape]
 |   |             GidPrincipal[49839]
 |   |
 |   +--multimap OPTIONAL:FAIL (no mappable principals) => OK
 |   |
 |   +--multimap SUFFICIENT:FAIL (no mappable principals) => OK
 |   |
 |   +--multimap SUFFICIENT:OK => OK (ends the phase)
 |          added: UidPrincipal[50209]
 |                 UserNamePrincipal[ska]
 |                 UidPrincipal[47307]
 |                 UserNamePrincipal[escape]

Result:

 +--VALIDATION FAIL (multiple UIDs)

Now, it is possible to work around this by adding more multimap plugins to gPlazma. Adrien Georget suggested this workaround:

map sufficient multimap gplazma.multimap.file=/etc/dcache/multimap-id-to-group+gid.conf map optional multimap gplazma.multimap.file=/etc/dcache/multimap-id-to-group+gid2.conf

The first multimap file should contains :

oidcgrp:escape/ska group:ska gid:47014,true oidcgrp:/escape/ska group:ska gid:47014,true

and the 2nd one :

oidcgrp:escape group:escape gid:49839,true oidcgrp:/escape group:escape gid:49839,true

If gPlazma succeeds to map the user with the first multimap file, it will not try the other one.

The downside of this is that you may have to repeat this trick for different cases, ending up with a possibly long list of multimap plugins that make it increasingly difficult (for colleagues and my later self) to understand how and why the mapping is done.

I can't think of any use case where selecting more than one UID would be useful, even if it were possible. So I'd like to request that multimap is modified, to pick only the first UID or the last UID it finds. In the worst case, a user would be mapped onto a different UID than he/she wants, but I suppose it should still be a UID that he/she is entitled to. Then changing the order of multimap rules should be sufficient to switch the mapping to the desired UID.

My understanding of multimap is still limited (documentation is sparse), so if I'm overlooking something I'd be very interested to learn.

Cheers, Onno

odevroed commented 1 year ago

+1

paulmillar commented 1 year ago

Hi Onno,

Yes, you have touched upon a genuine limitation of multimap.

The original idea of multimap was quite simple: just to add extra information. The intended semantics are something like: if I know this (about the individual) then I also know that.

As you noted, there is a requirement in gPlazma (and dCache, generally) that each logged in user has exactly one username, exactly one uid and exactly one primary gid. In effect, this is just saying that the logged-in user must have a single, concrete identity.

However, a user might (in general) have multiple identities that they could use. Using your example, an individual could be a member of the ESCAPE/SKA group, which means that they are also a member of the ESCAPE VO. Both of these statements would imply an identity (a group account), but they are two different accounts.

dCache/gPlazma enforces that only one identity is selected, but multimap doesn't provide a way of resolving that ambiguity.

There are some related problems.

Some individuals are known to dCache (e.g., their sub claims can be mapped to a specific username). When that person authenticates with membership of a supported VO: which identity should dCache use? Should the uid/username match their individual/personal identity, or match a group account from their VO membership?

Similarly, group membership, if derived from X509/VOMS, has the concept of a primary group (a primary FQAN); however, OIDC has (in general) no such concept of a primary group. So, how can multimap decide which group is the primary group in the OIDC case? Whatever solution is used, that should also honour the primary group from VOMS?

At the time when multimap was written, it wasn't clear how to handle these situations. What procedure/algorithm should be used to resolve this ambiguity?

For the most part, the decision was to go with something simple, with the hope that time and some experience would provide a reasonable answer. The result is the kind of work-around you described. The gPlazma configuration has multiple multimap plugins, which act as a kind of cascading selection process. Try the first multimap, if that doesn't work move onto the next one.

As you point out, this isn't very satisfactory.

I have some ideas on how this could be solved, but (to be honest) it's still not 100% clear to me what is the best solution, as the result should be (in some sense) intuitive and not something people find impossible to configure (i.e., no programming!). I fear that adding support for conditional statements (if-then) would quickly result in unmanageable files and/or impossible to understand why the mapping isn't working as intended.

In summary, this is actually quite a difficult problem to solve (at least, while keeping the configuration manageable). The work-around you describe is what I'm using (and others, too), and is unfortunate the best we can offer right now.

onnozweers commented 1 year ago

Hi Paul, thanks for your extensive reply. I agree that any solution should be intuitive and should avoid if-then constructions. The beauty of multimap is in its simplicity and flexibility.

Just a wild idea: how about an optional new keyword quit or exit or action:exit or sufficient on a line, like this:

oidcgrp:/escape/ska      username:ska     uid:47307    gid:47014,true    quit

If multimap encounters this keyword on a matching line, it would skip the rest of the file. A next invocation of multimap could then still add properties from other multimap files if desired. To me, this would seem intuitive.

You could even think of other actions, like action:block as a simple way to keep some unwanted users out.

And because it's optional, it would not break any existing configs.

paulmillar commented 1 year ago

I was thinking along somewhat similar lines.

However, I would trying to avoid adding support for such processing-instruction like arguments (like quit or exit). I'm trying to keep multimap "declarative" rather than "imperative".

So, I was thinking that the multimap would resolve multiple identities by choosing the identity that's appears first in the multimap file.

For example, let's say that gPlazma has already identified principals for a user that means that the multimap plugin selects two uid principals: one from the sub claim and the other from ESCAPE VO membership.

In this example, let's say that the sub-based uid principal is the result of line 20 (in the multimap file) and the ESCAPE VO membership uid principal comes from line 54 (of the multimap file). The multimap plugin would choose sub-claim based uid from line 20 (as 20 < 54) and discard the VO-membership-derived uid from line 54.

Someone from the ESCAPE VO for whom there is no sub-base uid principal (they personally are not known to dCache) would have only the uid principal from line 54. There is no conflict, so that uid is used.

If there is already a uid (from some other module, perhaps an earlier multimap with different configuration) then both uids would be discarded.

The same approach could be done for username principals: the earliest (in document order) is used if there is a conflict. As with the uid case, if the user already has a username principal (from earlier in the gPlazma login process) then multimap wouldn't add any username principals.

Broadly the same approach could be used to primary gid. We get rid of this ,true business. Instead, the earliest (in document order) selected gid is promoted to being the primary gid. If the user already has a primary gid then no gids are promoted to being the primary gid.

The admin can choose which identity is "more important" by putting it earlier in the file.