| Summary: | libc problem with getpw* functions using NIS | ||
|---|---|---|---|
| Product: | Base System | Reporter: | david <david> |
| Component: | misc | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 3.2-RELEASE | ||
| Hardware: | Any | ||
| OS: | Any | ||
This appears to be identical to the problem noted in bin/10821 This email has been virus scanned by intY using Sophos Anti-Virus State Changed From-To: open->closed Duplicate of bin/10821. Workaround committed to -STABLE 1999/07/09 in revision 1.48.2.2 of src/lib/libc/gen/getpwent.c. |
I'm seeing many errors in the logs of the form: Jul 9 14:27:53 server ypserv[1268]: access to master.passwd.byuid denied -- client 127.0.0.1:2597 not privileged This is caused by the following sequence of events: 1) program runs as root 2) calls getpwuid 3) closes all file descriptors 4) setuid(something other than root) 5) calls getpwuid The first call to getpwuid sets the _gotmaster variable in getpwent.c This makes all subsequent calls use the 'master.passwd' map instead of 'passwd'. When the second call to getpwuid is made, _yp_dobind determines that its socket has been closed and that it needs to rebind, however it can no longer get a privileged port due to no longer running as root. However, it still tries to access the master.passwd map because the _gotmaster variable has not been updated, resulting in the error message shown above. Fix: I've commented out the check in ypserv which checks for a secure port for the moment - not a terribly good solution. Either that or somehow, _getyppass must realise if the map lookup for 'master.passwd' has failed, it should reset _gotmaster and retry with the 'passwd' map. How-To-Repeat: Run Apache with SuEXEC enabled (this is how I noticed it originally). Either that, or run the following on box using NIS: #include <pwd.h> int main(int argc, char **argv) { int i; struct passwd *pw; pw = getpwuid(9998); setuid(99); for (i = 2; i < 200; i++) close(i); pw = getpwuid(9999); } Ensure that UIDs (9998 and 9999) don't exist in your local password file