Previously, check_user_runcwd() would return true if the runcwd
matched the user's cwd, even if sudoers specified a different one.
The user-specified runcwd was ignored but it is better to error out
in this case. It is now also possible to use "sudo -D" with the
directory specified in sudoers.
The lack of setting to NULL is a holdover from when command_info was a local variable and not a global one. However, we given how other global variables are set to NULL, it is best that we do the same here to avoid potential issues should sudoers_policy_store_result be called again after the first time failed, otherwise we could get a double-free.
Variable length arrays are supported by C99, but having it denoted as "1" confused the compiler and is not defined.
Note that because we don't get the inferred NULL terminator, we have to increase the malloc size by one.
This makes it possible to call the appropriate runas user or group
list match function when resolving aliases instead of calling
runaslist_matches() itself. Fixes a bug that prevented the group
specified via "sudo -g" from matching when a Runas_Alias was used
in the user or group portion of a Runas_Spec.
If a sudoers rule has no runas list, a user-specified runas group
should only be allowed if it matches a group that the default runas
user belongs to. Instead, a missing group check allowed the user
run commands as the default runas user with an arbitrary group.
This means that a rule like "somebody host = ALL", which should be
equivalent to "somebody host = (root) ALL", had the same effect as
"somebody host = (root:ALL) ALL".
Now that we are guaranteed to have a runas user list for all sudoers
rules that contain a runas list, we can remove support for the
special case where user_matched is set in the runas group matching
conditional. This fixes a bug where "sudo -u myuser -g mygroup"
was permitted by a rule like "myuser ALL = (root) ALL".
When a sudoers rule permits the user to run commands as a group,
not a user, we should set the runasusers to single member with the
special MYSELF token. This guarantees that the only time runasusers
will be NULL is when no runaslist is present.
This can be used to support netgroup queries on systems that lack
the innetgr() function and where the LDAP server cannot query the
nisNetgroup by nisNetgroupTriple.
This allows us to use the LDAP-specific version of innetgr() when
possible. Also enable "use_netgroups" by default even on systems
without innetgr() since we can now query netgroups directly via
LDAP.
The command is now always run in its own process group. If visudo
is run in the foreground, the command is run in the foreground too.
Otherwise, run the command in the background. There is a race
between the tcsetpgrp() call in the parent and the execve() in the
child. If we lose the race and the command needs the controlling
terminal, it will be stopped with SIGTTOU or SIGTTIN, which the
waitpid() loop will handle.
Since visudo doesn't alter the terminal settings it is possible for
the terminal to have the ONLCR bit set in the output control flags.
In that case, we will get a CR, not a NL when the user presses
enter/return. One way this can happen is if visudo is run in the
background from a shell that supports line editing and the editor
restores the (cbreak-style) terminal mode when it finishes.
We just need a way for the policy (and visudo) to override the
default sudoers path. This adds a getter to be used in file.c when
sudoers is first opened.
When adminconfdir is enabled, the destination pathh may be different
from the path we opened. We always store an edited file in the
adminconfdir (if enabled). This makes it possible to use visudo
when /etc/sudoers is located on a read-only file system.
Configuration paths in sudo are now a colon-separated list of files
with the adminconfdir instance first (if enabled), followed by a
sysconfdir instance.