First of all I have never thought of the in-memory cache as a
performance issue (we are only sorting them), but as a nice way to
handle rules expiration.
I will try to explain why the sysdb is not enough in this case.
Because it is a security issue, when user runs SUDO, we want to always
go to an LDAP server and download current rules - not all of them, just
the ones that apply to him to minimize the traffic.
But running SUDO multiple times in a short period of time is not an
exception, therefore we cannot afford this approach because it would be
too. It would make SUDO unusable.
Therefore we need to implement expiration mechanism so we can reuse the
rules in a short period (currently set to 180 seconds). The question is
*how*?
1. *Download every time all rules instead of per user*
This would be probably too costly to do, similar to users and groups
enumeration. There is already implemented an option that enables
periodical update of all rules.
I admit I have never seen an enterprise sudoers. I assume that it
can get very big with hundreds of rules. If this is not a valid
assumption, just tell me that I am stupid and we can do it this
way :-)
2. *Store the rules in sysdb per user*
There would be many data duplication and the database may get very
huge.
3. Store the expiration time with each rule
*update only those rules that are expired*
We wouldn't be able to decide whether a new rule was created without
downloading all rules that apply for the user.
(And we might be delivering to SUDO half of the updated rules and
half of the old rules.)
4. Store the expiration time with each rule
*if one rule has different timestamp than others, perform an update*
Here we may end up in a not complete set of rules and a race
condition when the cache will not be used at all. Details are below
(*).
5. *Storing set of rules per user in in-memory cache* (current approach)
Once the rules that apply for the user are downloaded, they are
stored in the sysdb for the offline times but they are also stored
in a hash table. We set a tevent timer that will remove them from
the hash table after the expiration time exceeds.
We will refresh the rules in case of in-memory cache miss.
There is a possible duplication of the rules in the memory, but only
for a short time and for a small amount of users (I don't expect
many administrators to be using sudo at one moment).
6. If there is some approach I have not thought of, please tell me.
=======================================================================
(*)
**Rules in LDAP**
cn=rule1
sudoUser: A
cn=rule2
sudoUser: B
cn=rule3
sudoUser: A
sudoUser: B
**Timeline**
*Timestamp: 0*
user A does: sudo ls
Downloaded rules: rule1 and rule3
Sysdb contains:
cn=rule1
expire: 180
cn=rule3
expire: 180
*Timestamp: 10*
user B does: sudo ls
rule1 and rule3 are found in sysdb
expiration time equals
return them
!!! rule2 is missing !!!
*Timestamp: 190*
user B does: sudo ls
rule3 in sysdb is expired
perform an LDAP search for user B
sysdb contains:
cn=rule1
expire: 180
cn=rule2
expire: 370
cn=rule3
expire: 370
*Timestamp: 200*
user A does: sudo ls
rule1 and rule3 have different expiration time
perform an LDAP search for user A
sysdb contains:
cn=rule1
expire: 380
cn=rule2
expire: 370
cn=rule3
expire: 380
*Timestamp: 210*
user B does: sudo ls
rule2 and rule3 have different expiration time
perform an LDAP search for user B
sysdb contains:
cn=rule1
expire: 380
cn=rule2
expire: 390
cn=rule3
expire: 390
!!! always performing an LDAP search !!!
Regards,
Pavel.