diff options
author | Bostjan Skufca <bostjan@a2o.si> | 2014-09-06 18:47:55 +0000 |
---|---|---|
committer | Serge Hallyn <serge.hallyn@ubuntu.com> | 2014-09-17 15:48:24 -0500 |
commit | 1d049b6aedb7f94a97369215787e111b4b1dc584 (patch) | |
tree | dc35303495fc4ba4e1b7afea978fceb36efdd988 | |
parent | 37e2a687e3a67a3ea14f8ed01a52ec6a76149990 (diff) |
sub[ug]id: compare range before comparing username/UID, to avoid unnecessary syscallssubuigid-numeric
Change suggested by Nicolas François as performance optimization.
Performance penalty would be really noticeable when usernames are
stored in remote databases (ldap).
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
-rw-r--r-- | lib/subordinateio.c | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/lib/subordinateio.c b/lib/subordinateio.c index 25353368..88cc5817 100644 --- a/lib/subordinateio.c +++ b/lib/subordinateio.c @@ -245,36 +245,38 @@ static const struct subordinate_range *find_range(struct commonio_db *db, unsigned long first = range->start; unsigned long last = first + range->count - 1; + /* For performance reasons check range before using getpwnam() */ + if ((val < first) || (val > last)) { + continue; + } + + /* + * Range matches. Check if range owner is specified + * as numeric UID and if it matches. + */ + if (0 == strcmp(range->owner, owner_uid_string)) { + return range; + } + /* - * First check if range owner is specified as numeric UID - * and if it matches. + * Ok, this range owner is not specified as numeric UID + * we are looking for. It may be specified as another + * UID or as a literal username. + * + * If specified as another UID, the call to getpwnam() + * will return NULL. + * + * If specified as literal username, we will get its + * UID and compare that to UID we are looking for. */ - if (0 != strcmp(range->owner, owner_uid_string)) { - /* - * Ok, this range owner is not specified as numeric UID - * we are looking for. It may be specified as another - * UID or as a literal username. - * - * If specified as another UID, the call to getpwnam() - * will return NULL. - * - * If specified as literal username, we will get its - * UID and compare that to UID we are looking for. - */ - const struct passwd *range_owner_pwd; - - range_owner_pwd = getpwnam(range->owner); - if (NULL == range_owner_pwd) { - continue; - } - - if (owner_uid != range_owner_pwd->pw_uid) { - continue; - } + const struct passwd *range_owner_pwd; + + range_owner_pwd = getpwnam(range->owner); + if (NULL == range_owner_pwd) { + continue; } - /* Owner matches, now let us check this UID/GID range */ - if ((val >= first) && (val <= last)) { + if (owner_uid == range_owner_pwd->pw_uid) { return range; } } |