mode_run -> policy_check -> sudoers_policy_main -> sudoers_policy_init:
- init_vars (fills global variable sudo_user)
- sudo_user->pwd (from global struct passwd) will be used in "user_in_group" as "struct passwd" of executing user
- it will check whether the executing user is in a certain group (pre-reqs for sudo execution)
/*
* Get a local copy of the user's struct passwd if we don't already
* have one.
*/
if (sudo_user.pw == NULL) {
if ((sudo_user.pw = sudo_getpwnam(user_name)) == NULL) {
/*
* It is not unusual for users to place "sudo -k" in a .logout
* file which can cause sudo to be run during reboot after the
* YP/NIS/NIS+/LDAP/etc daemon has died.
*/
if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) { sudo_warnx(U_("unknown uid: %u"), (unsigned int) user_uid); debug_return_bool(false);
}
/* Need to make a fake struct passwd for the call to log_warningx(). */ sudo_user.pw = sudo_mkpwent(user_name, user_uid, user_gid, NULL, NULL); unknown_user = true;
}
}
so sudo_user->pwd comes from sudo_mkpwent(user_name).
At this time, impossible that sudo_mkpwent has cached values so we have:
...
item = sudo_make_pwitem((uid_t)-1, name);
if (item == NULL) {
const size_t len = strlen(name) + 1;
if (errno != ENOENT || (item = calloc(1, sizeof(*item) + len)) == NULL) { sudo_warnx(U_("unable to cache user %s, out of memory"), name); debug_return_ptr(NULL);
}
item->refcnt = 1;
item->k.name = (char *) item + sizeof(*item);
memcpy(item->k.name, name, len);
/* item->d.pw = NULL; */
}
strlcpy(item->registry, key.registry, sizeof(item->registry));
switch (rbinsert(pwcache_byname, item, NULL)) {
...
Since sudo_make_pwitem relies on local authentication, and user is coming from ldap... item = NULL.
With item being NULL, cache item item->d (union) will be filled of zeroes.
With that, item->d>pw will be a NULL pointer.
PROBLEM:
In the future, when this cache item is recovered from redblack tree, any reference to item->d>pw will fail.
Following execution path I get:
====
(1)
mode_run -> policy_check -> sudoers_policy_main -> sudoers_ policy_ init:
- init_vars (fills global variable sudo_user)
- sudo_user->pwd (from global struct passwd) will be used in "user_in_group" as "struct passwd" of executing user
- it will check whether the executing user is in a certain group (pre-reqs for sudo execution)
/* user_name) ) == NULL) { NIS+/LDAP/ etc daemon has died.
sudo_ warnx(U_ ("unknown uid: %u"), (unsigned int) user_uid);
debug_ return_ bool(false) ;
* Get a local copy of the user's struct passwd if we don't already
* have one.
*/
if (sudo_user.pw == NULL) {
if ((sudo_user.pw = sudo_getpwnam(
/*
* It is not unusual for users to place "sudo -k" in a .logout
* file which can cause sudo to be run during reboot after the
* YP/NIS/
*/
if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) {
}
/* Need to make a fake struct passwd for the call to log_warningx(). */
sudo_user. pw = sudo_mkpwent( user_name, user_uid, user_gid, NULL, NULL);
unknown_ user = true;
}
}
so sudo_user->pwd comes from sudo_mkpwent( user_name) .
At this time, impossible that sudo_mkpwent has cached values so we have:
... pwitem( (uid_t) -1, name);
item = sudo_make_
if (item == NULL) {
sudo_warnx( U_("unable to cache user %s, out of memory"), name);
debug_ return_ ptr(NULL) ; item->k. name, name, len); item->registry, key.registry, sizeof( item->registry) ); pwcache_ byname, item, NULL)) {
const size_t len = strlen(name) + 1;
if (errno != ENOENT || (item = calloc(1, sizeof(*item) + len)) == NULL) {
}
item->refcnt = 1;
item->k.name = (char *) item + sizeof(*item);
memcpy(
/* item->d.pw = NULL; */
}
strlcpy(
switch (rbinsert(
...
Since sudo_make_pwitem relies on local authentication, and user is coming from ldap... item = NULL.
With item being NULL, cache item item->d (union) will be filled of zeroes.
With that, item->d>pw will be a NULL pointer.
PROBLEM:
In the future, when this cache item is recovered from redblack tree, any reference to item->d>pw will fail.