in reply to How to use setuid with modules?
Setuid is a property of a process, not a module. It's an OS level thing, not a perl level thing. If an executable is marked as setuid, the process' effective uid will be that of the owner of the file (not necessarily root, just whomever owns it). It's an all or nothing proposition that you can't really enable for just some code.
If you can't use something like syslog, you could write your own logging process which listens on a UNIX domain socket (or a TCP socket if you want to work from multiple hosts) and let your module send messages to that (of course then you have to worry about authentication et al yourself).
Another posibility would be to use a wrapper which opens a write only filehandle to the logfile in question as a priveledged user, changes uid to the target user's, and then execs the end script. Set something in the environment to the filedescriptor they should use and then dup it into a handle in your module.
# in wrapper . . . use Fcntl qw( F_GETFD F_SETFD FD_CLOEXEC ); open( LOG, "/path/to/log" ) or die "open log: $!\n"; $ENV{LOG_FD} = fileno( LOG ); my $flags = fcntl( LOG, F_GETFD ) or warn "getfd: $!\n"; fcntl( LOG, F_SETFD, $flags & ~FD_CLOEXEC ) or warn "setfd: $!\n"; $< = $> = uid_to_run_as( ... ); exec "/path/to/real/program", @prog_args or die "Can't exec real program: $!\n"; # in your module sub log_it { local( *LOG ); open( LOG, "<&=" . $ENV{LOG_FD} ) or die "Can't dup log fd: $!\n"; print LOG, "Ack: ", @_, "\n"; }
Update: Added in code to clear close-on-exec flag so that the descriptor will survive the exec.
|
|---|