Hello Paul, Please accept some nitpicking: - The code uses the Solaris 10 APIs. How about also using the Linux API for "capabilities" - capget() - that was added in Linux 2.2 and glibc-2.1.x? - If priv_allocset fails, the function returns false without considering geteuid (). And if priv_allocset succeeds, it will not cache the result, but instead redo the same system calls next time. Is this intentional? - If getppriv fails, the function also returns false without considering geteuid ().
Here's a tentative patch to address the last two problems. *** lib/write-any-file.c 23 Mar 2007 17:33:07 -0000 1.1 --- lib/write-any-file.c 23 Mar 2007 23:32:51 -0000 *************** *** 42,53 **** priv_set_t *pset = priv_allocset (); if (pset) { ! can = ! (getppriv (PRIV_EFFECTIVE, pset) == 0 ! && priv_ismember (pset, PRIV_FILE_DAC_WRITE)); priv_freeset (pset); } else #else /* In traditional Unix, only root can unlink directories. */ can = (geteuid () == 0); --- 42,55 ---- priv_set_t *pset = priv_allocset (); if (pset) { ! if (getppriv (PRIV_EFFECTIVE, pset) == 0) ! can = priv_ismember (pset, PRIV_FILE_DAC_WRITE); ! else ! can = (geteuid () == 0); priv_freeset (pset); } else + can = (geteuid () == 0); #else /* In traditional Unix, only root can unlink directories. */ can = (geteuid () == 0);