#if 0 Compile with: cc -O -D_REENTRANT -Kpic -G -z text -xstrconst -o lpq_letitgo.so lpq_letitgo.c Usage is a bit challenging as you can't LD_PRELOAD modules to set-uid apps. Following set-root-uid perl script covers up for it. #!/usr/bin/perl -T foreach $i (keys %ENV) { if ($i !~ /^(TZ|USER|LOGNAME|HOME|TMPDIR|PRINTER|LPDEST)$/) { delete $ENV{$i}; } } $ENV{LD_PRELOAD}="/usr/local/lib/lpq_letitgo.so"; $ENV{_DROP_TO_RUID}="$<"; $<=$>; exec ("/usr/ucb/lpq",@ARGV); #endif #include #include #include #include #include #include #include #include #include #include #include #include #include static int (*__lib_rresvport_af)(int *,int); int _setsockopt(int socket, int level, int option_name, const void *option_value, unsigned int option_len); int rresvport_af (int *alport, int af) { int ret; struct linger l={1,0}; ret=(*__lib_rresvport_af)(alport,af); if (ret>=0) _setsockopt (ret,SOL_SOCKET,SO_LINGER,(void *)&l,sizeof(l)); return ret; } #pragma init(setmeup) static void setmeup() { int fd; char *env; uid_t uid; void *libh; if (getuid()==0 && (env=getenv("_DROP_TO_RUID"))) { if (uid = strtoul (env,NULL,10)) setreuid (uid,-1); } if (!(libh = dlopen ("libsocket.so.1",RTLD_LAZY))) { fprintf (stderr,"can't dlopen(\"%s\").","libsocket.so.1"); exit(1); } if (!(__lib_rresvport_af = (int (*)(int *,int))dlsym (libh,"rresvport_af"))) { fprintf (stderr, "can't link to \"%s\" from %s", "rresvport_af","libsocket.so.1"); exit (1); } } #if 0 int setsockopt (int socket, int level, int option_name, const void *option_value, unsigned int option_len) { struct linger l={1,0}; if (level==SOL_SOCKET && option_name==SO_LINGER) return _setsockopt (socket,level,option_name,(void *)&l,sizeof(l)); else _setsockopt (socket,SOL_SOCKET,SO_LINGER,(void *)&l,sizeof(l)); return _setsockopt (socket,level,option_name,option_value,option_len); } #endif