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.