- Fix buffer overflow problem once and for all: do away with the buffer
copies to 'user' prior to calling _scancaches() and just pass a pointer
to the buffer returned by yp_match()/yp_first()/yp_next()/whatever.
(We turn the first ':' to a NUL first so strcmp() works, then change it
back later. Submitted by Bill Fenner <fenner@parc.xerox.com> and
tweaked slightly by me.
- Give _pw_breakout_yp() the 'more elegant solution' I promised way back when.
Eliminate several copies to static buffers and replace them with just
one copy. (The buffer returned by the NIS functions is at most
YPMAXRECORD bytes long, so we should only need one static buffer of
the same length (plus 2 for paranoia's sake).)
- Also in _pw_breakout_yp(): always set pw.pw_passwd to the username
obtained via NIS regardless of what pw_fields says: usernames cannot
be overridden so we have no choice but to use the name returned by
NIS.
- _Again_ in _pw_breakout_yp(): before doing anything else, check that
the first character of the NIS-returned buffer is not a '+' or '-'.
If it is, drop the entry. (#define EXTRA_PARANOIA 1 :)
- Probe for the master.passwd.* maps once during __initdb() instead
of doing it each time _getyppass() or _nextyppass() is called.
- Don't copy the NIS data buffers to static memory in _getyppass()
and _nextyppass(): this is done in _pw_breakout_yp() now.
- Test against phkmalloc and phkmalloc/2 (TNG!) to make sure we're
free()ing the yp buffers sanely.
- Put _havemaster(), _getyppass() and nextyppass() prototypes under
#ifdef YP. (Somehow they ended up on the wrong side of the #endif.)
- Remove unused variable ___yp_only.
- In some cases, we don't properly resolve _all_ possible group memberships.
If a user is a member of both local and NIS groups, we sometimes lose some
of the membership info from NIS. (Reported by: Thorsten Kukuk
<kukuk@uni-paderborn.de>)
- Make NIS +groupname overrides actually work the way the SunOS group(5)
man page says they should (make them work for all cases: getgrent(),
getgrnam() and getgrgid()).
- When not compiled with -DYP, grscan() should ignore entries that
begin with a '+'. When compiled _with_ -DYP, grscan() should ignore
+groupname entries that don't refer to real NIS groups.
- Remove redundant redeclaration of fgets(), strsep() and index() inside
grscan(). We already #include all the right header files for these.
Note: -groupname exclusion as specified in the Sun documentation still
isn't supported. This'll be a 2.2 addition. Right now I just want this
stuff to work.
What was happening, is if syslogd was not running, syslog() would do
a strcat("\r\n") on a non-null-terminated buffer, and write it to the console.
This meant that sometimes extra characters could be written to the console
during boot, depending on the stack contents.
This totally avoids the potential problem by using writev() like the rest
of the does, and avoid modifying the buffer after the trouble we've gone to
to carefully protect it.
This is actually a trivial fix, in spite of the long commit message.. :-)
It only appeared during boot and shutdown with syslogd stopped.
running on a tty. (Same as isatty()) The old-style TIOCGETP ioctl
wouldn't fly if the kernel didn't have COMPAT_43.
Submitted by: Carl Fongheiser <cmf@netins.net>
Performance is comparable to gnumalloc if you have sufficient RAM, and
it screams around it if you don't.
Compiled with "EXTRA_SANITY" until further notice.
see malloc.3 for more details.
control hooks.
It is similar to an unrolled multi-part snprintf(), in that a "FILE *" is
attached to a string buffer. There is also an optimisation for the case
where the syslog format string does not contain %m, which should improve
performance of "informational" logging, like from ftpd.
the group map after encountering a badly formatted entry.
getpwent.c: same as above for _nextyppass(), and also turn a couple of
sprintf()s into snprintf()s to avoid potential buffer overruns. (The
other day I nearly went mad because of a username in my NIS database
that's actually 9 characters long instead of 8. Stuffing a 9-character
username into an 8-character buffer can do some strange things.)
(This reminds me: I hope somebody's planning to fix the buffer overrun
security hole in syslog(3) before 2.1 ships.)
on, which is fine, except that _yp_dobind() is called before we check
the cache. The means we can return from the cache check (if we have
a hit) without calling _yp_unbind().
We should do the cache check first and _then_ drop into the section
that binds the server and does the yp_match query.
seperate function to avoid duplication. Also fix getpwent() a
small bit to properly handle the case where the magic NIS '+'
entry appears before the end of the password file.
getgrent.c: be a little more SunOS-ish. Make it look like the NIS
group map is 'inserted' at the the point(s) where the magic NIS '+'
entry/entries appear.
getgrent: fix a file descriptor leak: remember to close the netgroup
file after we determine that we're using NIS-only innetgr() lookups.
Since Bruce changed the #include <res_config.h> to #include "res_config.h"
this is no longer needed, and only makes the 'make' more verbose for
no real reason.
Note that this was done by selective patching from diffs, to not conflict
with the 4.4bsd base code.. This was *not* a trivial task.. I have been
testing this code (apart from cosmetic changes) in my libc for a while now.
Obtained from: Paul Vixie <paul@vix.com>
/usr/include/ufs/ufs/quota (#include <ufs/ufs/quota.h>) that seems to work
ok though.
Closes PR # docs/670: quotactl man page incorr...
Submitted by: evans@scnc.k12.mi.us (Jeffrey Evans)
Fix for PR #510. The original problem was that __ivaliduser() was
failing to grant access to a machine listed in a +@netgroup specified
in /etc/hosts.equiv, even though the host being checked was most
certainly in the +@netgroup.
The /etc/hosts.equiv file in question looked like this:
localhost
+@netgroup
The reason for the failure was had to do with gethostbyaddr(). Inside
the __ivaliduser() routine, we need to do a gethostbyaddr() in order
to get back the actual name of the host we're trying to validate since
we're only passed its IP address. The hostname returned by gethostbyaddr()
is later passed as an argument to innetgr(). The problem is that
__icheckhost() later does a gethostbyname() of its own, which clobbers
the buffer returned by gethostbyaddr().
The fix is just to copy the hostname into a private buffer and use
_that_ as the 'host' argument that gets passed to innetgr().
And here I was crawling all over the innetgr() code thinking the
problem was there. *sigh*
bump it again if something else is added before 2.2.
The xdr_* functions are enabled only in the 2.2 (-current) branch
so far. If that modification is moved to the 2.1 (-stable) branch,
this one should, too.
Reviewed by: the mailing lists
- getnetgrent.c: address some NIS compatibility problems. We really need
to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr()
when using NIS. Also, change the NIS interaction in the following way:
If /etc/netgroup does not exist or is empty (or contains only the
NIS '+' token), we now use NIS exclusively. This lets us use the
'reverse netgroup' maps and is more or less the behavior of other
platforms.
If /etc/netgroup exists and contains local netgroup data (but no '+').
we use only lthe local stuff and ignore NIS.
If /etc/netgroup exists and contains both local data and the '+',
we use the local data nd the netgroup map as a single combined
database (which, unfortunately, can be slow when the netgroup
database is large). This is what we have been doing up until now.
Head off a potential NULL pointer dereference in the old innetgr()
matching code.
Also fix the way the NIS netgroup map is incorporated into things:
adding the '+' is supposed to make it seem as though the netgroup
database is 'inserted' wherever the '+' is placed. We didn't quite
do it that way before.
(The NetBSD people apparently use a real, honest-to-gosh, netgroup.db
database that works just like the password database. This is
actually a neat idea since netgroups is the sort of thing that
can really benefit from having multi-key search capability,
particularly since reverse lookups require more than a trivial
amount of processing. Should we do something like this too?)
- netgroup.5: document all this stuff.
- rcmd.c: some sleuthing with some test programs linked with my own
version of innetgr() has revealed that SunOS always passes the NIS
domain name to innetgr() in the 'domain' argument. We might as well
do the same (if YP is defined).
- ether_addr.c: also fix the NIS interaction so that placing the
'+' token in the /etc/ethers file makes it seem like the NIS
ethers data is 'inserted' at that point. (Chances are nobody will
notice the effect of this change, which is just te way I like it. :)
specified in the top level Makefiles.
Previously I missed dozens of Makefiles that skip the install after
using `cmp -s' to decide that the install isn't necessary.
changeover, so we have to extend the format of timezone files (in a backward-
compatible way, of course). This probably means that libc needs a minor
version number bump before 2.2 is released (or maybe not).
by me). This probably loses for multibyte characters, but I have no
way of telling. I'll let ache decide whether to add this support to
startup_setlocale. Note that for this to make any sense at all, the
symlinks in /usr/share/locale must go. (For the moment, this doesn't
make any difference since there are no locales supplied.)
Obtained from: Arthur David Olson <ado@elsie.nci.nih.gov>
Back out the 'help NIS rebind faster' hack. This change used a
connect()/send() pair rather than the original sendto() to allow
RPC to pass ICMP host unreachable and similar errors up to RPC
programs that use UDP. This is not a terrible thing by itself, but it can
cause trouble in environments with multi-homed hosts: if the portmapper
on the multi-homed machine sends a reply with a source address
that's different than the one associated with the connection by
connect(), the kernel will send a port unreachable message and
drop the reply. For the sake of compatibility with everybody else
on the planet, it's best to revert to the old behavior.
*long, heavy sigh*
like 38400<any 8bit char, isalpha> it not detect this stuff and
produce very big number instead. Fixed by operating with unsigned char
and checking for isascii. (secure/telnetd hits by it f.e.)
the comment before checking for long lines, so there was a possibility
that the wrap-around might be used as an exploitable hostname.
Reviewed by:
Submitted by:
Obtained from:
Strange as it sounds, it should map to YPERR_DOMAIN instead.
The YP_NODOM protocol error code is generally returned by ypserv when you
ask it for data from a domain that it doesn't support. By contrast,
the YPERR_NODOM error code means 'local domain name not set.'
Consequently, this incorrect mapping leads to yperr_string() generating
a very confusing error message. YPERR_DOMAIN says 'couldn't
bind to a server which serves this domain' which is much closer
to the truth.
_gr_breakout_yp(): if we encounter a NULL pointer generated as the
result of a badly formatted NIS passwd entry (e.g. missing fields),
we punt and return an error code, thereby silently skipping the
bad entry.
last night:
_gr_breakout_yp() doesn't check for badly formatted NIS group entries.
For example, a bogus entry like this:
bootp::user1,user2,user3
will lead to a null pointer dereference and a SEGV (note that the GID
field is missing -- this results in one of the strsep(&result, ":")
returning NULL). The symtpom of this problem is programs dumping
core left and right the moment you add a + entry to /etc/group.
Note that while this is similar to an earlier bug, it's caused by a
different set of circumstances.
The fix is to check for the NULL pointers and have _gr_breakout_yp()
punt and return a failure code if it catches one. This is more or
less the behavior of SunOS: if a bad NIS group entry is encountered,
it's silently ignored. I don't think our standard (non-NIS) group
parsing code behaves the same way. It doesn't crash though, so I'm
citing the 'it ain't broken, don't fix it' rule and leaving it alone.
I'll probably have to add similar checks to _pw_breakout_yp() in
getpwent.c to ward off the same problems. It's rare that bad NIS
map entries like this occur, but we should handle them gracefully
when they do.
'cycle in netgroup check too greedy').
PR #508 is apparently due to an inconsistency in the way the 4.4BSD
netgroup code deals with bad netgroups. When 4.4BSD code encounters
a badly formed netgroup entry (e.g. (somehost,-somedomain), which,
because of the missing comma between the '-' and 'somedomain,' has
only 2 fields instead of 3), it generates an error message and
then bails out without doing any more processing on the netgroup
containing the bad entry. Conversely, every other *NIX in the world
that usees netgroups just tries to parse the entry as best it can
and then silently continues on its way.
The result is that two bad things happen: 1) we ignore other valid entries
within the netgroup containing the bogus entry, which prevents
us from interoperating with other systems that don't behave this way,
and 2) by printing an error to stderr from inside libc, we hose certain
programs, in this case rlogind. In the problem report, Bill Fenner
noted that the 'B' from 'Bad' was missing, and that rlogind exited
immediately after generating the error. The missing 'B' is apparently
not caused by any problem in getnetgrent.c; more likely it's getting
swallowed up by rlogind somehow, and the error message itself causes
rlogind to become confused. I was able to duplicate this problem and
discovered that running a simple test program on my FreeBSD system
resulted in a properly formatted (if confusing) error, whereas triggering
the error by trying to rlogin to the machine yielded the missing 'B'
problem.
Anyway, the fixes for this are as follows:
- The error message has been reformatted so that it prints out more useful
information (e.g. Bad entry (somehost,-somedomain) in netgroup "foo").
We check for NULL entries so that we don't print '(null)' anymore too. :)
- Rearranged things in parse_netgrp() so that we make a best guess at
what bad entries are supposed to look like and then continue processing
instead of bailing out.
- Even though the error message has been cleaned up, it's wrapped inside
a #ifdef DEBUG. This way we match the behavior of other systems. Since we
now handle the error condition better anyway, this error message becomes
less important.
PR #507 is another case of inconsistency. The code that handles
duplicate/circular netgroup entries isn't really 'too greedy; -- it's
just too noisy. If you have a netgroup containing duplicate entries,
the code actually does the right thing, but it also generates an error
message. As with the 'Bad netgroup' message, spewing this out from
inside libc can also hose certain programs (like rlogind). Again, no
other system generates an error message in this case.
The only change here is to hide the error message inside an #ifdef DEBUG.
Like the other message, it's largely superfluous since the code handles
the condition correctly.
Note that PR #510 (+@netgroup host matching in /etc/hosts.equiv) is still
being investigated. I haven't been able to duplicate it myself, and I
strongly suspect it to be a configuration problem of some kind. However,
I'm leaving all three PRs open until I get 510 resolved just for the
sake of paranoia.
ypbind.c:
Make fewer assumtions about the state of the dom_alive and dom_broadcasting
flags in roc_received().
If select() fails, use syslog() to report the error rather than perror().
Check that all our malloc()s succeed. Report malloc() failure in
ypbindproc_setdom_2() to callers.
yplib.c:
Use #defined constants in ypbinderr_string() rather than hard-coded values.
- If you take the wheel entry out of /etc/group and turn on NIS,
the '+:*::' line is incorrectly flagged as the entry for wheel (the
empty gid section is translated to 0), hence getgrgid() returns '+'
as the name of the group instead of 'wheel.'
- Using just '+:' as the 'turn on NIS' switch in /etc/group makes
getgrgid() dump core because of a null pointer dereference. (Last
time I was in here, I foolishly assumed that fixing the core dump
problems with getgrnam() and getgrent() would fix getgrgid() too.
Silly me.)
- Moved to a more client-driven model. We aggressively attempt to keep
the default domain bound (as before) but we give up on non-default
domains if we lose contact with a server and fail to get a response
after one round of broadcasting. This helps drastically reduce the
amount of network bandwitdh that ypbind consumes: if a client references
the secondary domain at some later point, this will prod ypbind into
establishing a new binding anyway, so continuously broadcasting without
need is pointless.
Note that we still actively seek out a binding for our default domain
even if no client program has queried us yet. I'm not exactly sure if
this matches SunOS's behavior or not, but I decided to do it this way
since we can get into all sorts of trouble if our default domain comes
unbound. Even so, we're still much quieter than we used to be.
- Removed a bunch of no-longer pertinent comments and a couple of
chunks of #ifdef 0'ed code that no longer fit in to the new layout.
- Theo deRaadt must have become frustrated with the callback mechanism
in clnt_broadcast(), because he shamelessly stole the clnt_broadcast()
code right out of the RPC library and hacked it up to suit his needs.
(Comments and all! :)
I can understand why: clnt_broadcast() blocks while awaiting replies.
Changing this behavior requires surgery. However, you can work around
this: fork the broadcast into a child process and relay the results
back to the parent via a pipe. (Careful obervation has shown that the
SunOS ypbind forks children for broadcasting too, though I can only
guess what sort of interprocess communication it uses. pipe() seems to
do the job well enough.)
This may seem like the long way around, but it's not really that
hard to implement, and I'd prefer to use documented RPC library functions
wherever possible. We're careful to limit the number of simultaneous
broadcasters to avoid swamping the system (the current limit is 5).
Each clnt_broadcast() call only sends out a small number of packets
at increasing intervals. We're also careful not to spawn more than one
bradcaster for a given domain.
- Used clntudp_bufcreate() and clnt_call() to implement a ping()
function for directly querying a particular server so that we can
check if it's still alive. This lets me completely remove the old
bradcasting code and use actual RPC library calls instead, at the
cost of more than a few handfulls of torn-out hair. (Make no mistake
folks: I *HATE* RPC.) Currently, the ping interval is one minute.
- Fixed another potential 'nfds too big for select()' bug: use
_rpc_dtablesize() instead of getdtablesize().
- Quieted gcc -Wall a bit.
- Probably a bunch of other stuff that I've forgotten.
ypbind.8:
- Updated man page to reflect modifications.
ypwhich.c:
- Small mind-o fix from last time: decode error results from
ypbind correctly (*groan*)
yplib.c:
- same as above
- Change behavior of _yp_dobind() a little: if we get back a 'Domain
not bound' error for a given domain, retry a few times before giving
up and passing the error back to the caller. We have to sleep for a
few seconds between tries since the 'Domain not bound' error comes
back immediately (by repeatedly looping, we end up pounding on ypbind).
We retry at most 20 times at 5 second intervals. This gives us a full
minute to get a response. This seems to deviate a bit from SunOS
behavior -- it appears to wait forever -- but I don't like the idea
of perpetually hanging inside a library call.
Note that this should fix the problems some people have with bindings
not being established fast enough at boot time; sometimes amd is started
in /etc/rc after ypbind has run but before it gets a binding set up. The
automounter gets annoyed at this and tends to exit. By pausing ther YP
calls until a binding is ready, we avoid this situation.
- Another _yp_dobind() change: if we determine that our binding files
are unlocked or nonexistent, jump directly to code that pokes ypbind
into restablishing the binding. Again, if it fails, we'll time out
eventually and return.
ypbind.c: if a client program asks ypbind for the name of the server
for a particular domain, and there isn't a binding for that domain
available yet, ypbind needs to supply a status value along with its
failure message. Set yprespbody.ypbind_error before returning from
a ypbindproc_domain request.
yplib.c: properly handle the error status messages ypbind now has the
ability to send us. Add a ypbinderr_string() function to decode the
error values.
ypwhich.c: handle ypbind errors correctly: yperr_string() can't handle
ypbind_status messages -- use ypbinderr_string instead.
- it succeeded on non-directories (see POSIX 5.1.2.4).
- it hung on (non-open) named pipes.
- it leaked memory if the second malloc() failed.
- it didn't preserve errno across errors in close().
of the plus or minus lists at all, reject him. This lets you create
a +@netgroup list of users that you want to admit and reject everybody
else. If you end your +@netgroup list with the wildcard line
(+:::::::::) then you'll have a +@netgroup list that remaps the
specified people but leaves people not in any netgroup unaffected.
where one or more of the non-default domains are not yet bound.
If we make a YP request for a domain other than the default domain,
and there is no binding for the new domain yet, _yp_dobind() sees
that the /var/yp/binding/DOMAIN.VERS file for the unbound domain is
not locked (by ypbind) and from this it concludes that the NIS system
is dead, so it gives up.
This behavior has been changed: before giving up in this case, we now
make a second check to see if the binding file for the *default* domain
is also not locked. Only if the default domain binding file is also
unlocked to we now assume that ypbind has bought the farm and bail out.
(Note: this assumes that the user hasn't changed the default domain
while ypbind is running.)
With this change, _do_ypbind() is allowed to proceed into the next
section of code wherein it prods ypbind into establishing a binding
for the new domain. This first call times out after ten seconds,
after which it should retry and succeed. From then on, the binding
for the second domain should be handled normally.
isctype.c:
o The tolower() and toupper() functions duplicated too much code
and were out of date (surprise). This didn't matter because
it was difficult to call them.
o Change formatting to be more like that in <ctype.h> (with
extra parentheses as in the macros). Perhaps this file should
be machine generated or everything should be handled like
__tolower() so that no code is repeated.
nomacros.c:
o Instead of looking at _USE_CTYPE_INLINE_ to see what <ctype.h>
has done, set _EXTERNALIZE_CTYPE_INLINES_ to tell <ctype.h>
what to do, so that we don't have anything left to do. Note
that code is now generated even if inlines are used by default.
This allows users to switch to non-inline versions.
select() returns EINVAL if you try to feed it a value of FD_SETSIZE greater
that 256. You can apparently adjust this by specifying a larger value of
FD_SETSIZE when configuring your kernel. However, if you set the maximum
number of open file descriptors per process to some value greater than
the FD_SETSIZE value that select() expects, many selects() within the RPC
library code will be botched because _rpc_dtablesize() will return
invalid numbers. This is to say that it will return the upper descriptor
table size limit which can be much higher than 256. Unless select() is
prepared to expect this 'unusually' high value, it will fail. (A good
example of this can be seen with NIS enabled: if you type 'unlimit' at
the shell prompt and then run any command that does NIS calls, you'll
be bombarded with errors from clnttcp_create().)
A temporary fix for this is to clamp the value returned by _rpc_dtablesize()
at FD_SETSIZE (as defined in <sys/types.h> (256)). I suppose the Right
Thing would be to provide some mechanism for select() to dynamically
adjust itself to handle FD_SETSIZE values larger than 256, but it's a
bit late in the game for that. Hopefully 256 file descriptors will be enough
to keep RPC happy for now.
add #includes for YP headers when compiling with -DYP to avoid some implicit
declarations.
getgrent.c & getnetgrent.c: add some #includes to avoid implicit declarations
of YP functions.
Obtained from: Casper H. Dik (by vay of Usenet)
Small patch to help improve NIS rebinding times (among other things):
>From: casper@fwi.uva.nl (Casper H.S. Dik)
>Newsgroups: comp.sys.sun.misc,comp.sys.sun.admin
>Subject: FIX for slow rebinding of NIS.
>Summary: a small change in libc makes life with NIS a lot easier.
>Message-ID: <1992Jan17.173905.11727@fwi.uva.nl>
>Date: 17 Jan 92 17:39:05 GMT
>Sender: news@fwi.uva.nl
>Organization: FWI, University of Amsterdam
>Lines: 138
>Nntp-Posting-Host: halo.fwi.uva.nl
Have you been plagued by long waits when your NIS server is rebooted?
READ ON!
Sun has a patch, but the README says:
********************* WARNING ******************************
This is a new version of ypbind that never uses the NIS
binding file to cache the servers binding. This will have
the effect of fixing the current symptom. However, it might
degrade the overall performance of the system when the
server is available. This is most likely to happen on an
overloaded server, which will cause the network to produce
a broadcast storm.
*************************************************************
Therefor, I have produced another fix.
o What goes wrong.
When the NIS server is rebooted, ypserv will obtain different ports
to listen for RPC requests. All clients will continue to use the old
binding they obtained earlier. The NIS server will send ICMP dst unreachable
messages for the RPC requests that arrive at the old port. These ICMPs
are dropped on the floor and the client code will continue sending the
requests until the timer has expired. The small fix at the end of this
message will pick up these ICMP messages and deliver them to the RPC layer.
o Before and after.
I've tested this on some machines and this is the result:
(kill and restart ypserv on the server)
original% time ypmatch user passwd
user:....
0.040u 0.090s 2:35.64 0.0% 0+126k 0+0io 0pf+0w (155 seconds elapsed time)
fixedhost% time ypmatch user passwd
user:....
0.050u 0.050s 0:10.20 0.9% 0+136k 0+0io 0pf+0w (10 seconds elapsed time)
Rebinding is almost instantaneous.
o Other benefits.
RPC calls that use UDP as transport will no longer time out but
will abort much sooner. (E.g., the remote host is unreachable or
111/udp is filtered by an intermediate router)
Grrr. If the dbhash routines weren't grossly overengineered I wouldn't
even need to do this! :-(
Also now export the hash_stats routine. Manpage coming RSN - I promise.
Make sure all arguments to the yp_*() functions are valid before sending
them off to the server. This is somewhat distressing: once again my
FreeBSD box brought down my entire network because of NIS bogosities.
I *think* the poor argument checking in this module is the cause, but
I still haven't been able to reproduce the exact series of events that
lead to the ypserv crashes. For now I've resorted to sticking my FreeBSD
box in a seprate domain. Hopefully a weekend of heavy testing will
uncover the problem.
Change strtok() to strsep(), cause memory corruption for all
programs which use strtok() too in the same time.
Fix potential NULL reference, depends of /etc/hosts.conf format
Fix the bug when service name fetched always from beginning of the line,
not from parsed token.
programs which use strtok() too in the same time.
Fix potential NULL reference, depends of /etc/hosts.conf format
Fix the bug when service name fetched always from beginning of the line,
not from parsed token.
remapping mechanism in the following manner: if given an entry +@foo
and there is no netgroup named 'foo,' try searching for a regular
user group called 'foo' and build the cache using the members of
group 'foo' instead. If both a netgroup 'foo' and a user group 'foo'
exist, the 'foo' netgroup takes precedence, since we're primarily
interested in netgroup matching anyway.
This allows access control schemes based on ordinary user groups
(which are also available via NIS) rather than netgroups, since
netgroups on some systems are limited in really brain-damaged ways.
ypserv to do a yp_match() with an a null or empty key causes much havok.
(Note that this could be construed as a denial of service attack if used
maliciously.)
my network because setnetgrent() was trying to do a lookup on group "".
It seems that an attempt to do a yp_match() (and possible yp_next())
on a null or empty key causes Sun's ypserv in SunOS 4.1.3 to exit
suddenly (and without warning). Our ypserv behaves badly in this
situation too, thoush it doesn't appear to crash. In any event, getpwent,
getnetgrent and yp_match() and yp_next() are now extra careful not to
accidentally pass on null or empty arguments.
Also made a small change to getpwent.c to allow +::::::::: wildcarding,
which I had disabled previously.
- Have the +@netgroup/-@netgroup caches handle the +user/-user cases too.
- Clean up getpwent() to take advantage of the improved +user/-user handling.
Submitted by: Sebastian Strollo <seb@erix.ericsson.se>
- In /usr/src/lib/libc/yp/yplib.c, function yp_first when clnt_call
fails with (r != RPC_SUCCESS) ysd->dom_vers should be set to 0! This
ensures that /var/yp/bindings/dom.vers will be read again on retry.
What happens now is that when our server is down and someone tries to
use yp they will continue to try until kingdom come. So:
if(r != RPC_SUCCESS) {
clnt_perror(ysd->dom_client, "yp_first: clnt_call");
ysd->dom_vers = -1;
^^^^ change to 0
goto again;
}
that everyone else does: you can now use +host/-host, +user,-user and
+@netgroup/-@netgroup in /etc/hosts.equiv, /.rhosts, /etc/hosts.lpd and
~/.rhosts. Previously, __ivaliduser would only do host/user matches,
which was lame. This affects all the r-commands, lpd, and any other
program/service that uses ruserok().
An example of the usefullness of this feature would be a hosts.equiv
file that looks like this:
+@equiv-hosts
Since the netgroup database can now be accessed via NIS, this lets you
set up client machines once and then never have to worry about them
again: all hosts.equiv changes can now be done through NIS. Once I
finish with getpwent.c, we'll be able to do similar wacky things
with login authentication too. (Our password field substitution
will finally be on par with everyone else's, and I'll finally be
able to fully integrate my FreeBSD machine into my network without
having to worry about the grad students sneaking into it when I'm
not looking. :)
Danger Will Robinson! I tested this thing every which way I could, but
Murphy's Law applies! If anybody spots a potential security problem with
the way my matching algorithm works, tell me immediately! I don't want
crackers snickering and calling me names behind my back. :)
work because parse_netgrp() doesn't recurse properly. Fixed by
changing
if (parse_netgrp(spos))
return(1);
to
if (parse_netgrp(spos))
continue;
inside parse_netgrp(). (Lucky for me I happen to have a fairly complex
'live' netgroup database to test this stuff with.)
- Added support for reading netgroups from NIS/YP in addition to the
local /etc/netgroups file. (Note that SunOS and many other systems only
support reading netgroups via NIS, which is a bit odd.)
- Fix Evil Null Pointer Dereferences From Hell (tm) that caused
parse_netgrp() to SEGV when expanding netgroups that include
references to other netgroups. Funny how nobody else noticed this.
This is the first step in implimenting +@netgroup substitution in
getpwent.c and any other places that could use it and don't already
support it (which is probably everywhere).
by heading off possible null pointer dereferences in grscan(). Also
change getgrnam() slightly to properly handle the change: if grscan()
returns an rval of 1 and leaves a '+' in the gr_name field and YP is
enabled, poll the YP group.byname map before giving up. This should
insure that we make every effort to find a match in the local and
YP group databases before bailing out.
commit by bde.
Fix bugs in floating point formatting. The 4.4lite version is similar
to revision 1.3 in old-cvs and is missing all of jtc's fixes in revision
1.4 in old-cvs. Revision 1.2 in ncvs fixed one of the old bugs but
introduced at least one new one (for %.0e).
old-cvs log:
revision 1.4
date: 1993/11/04 19:38:22; author: jtc; state: Exp; lines: +33 -20
My work from NetBSD to make printf() & friends ANSI C compliant.
Fixes several bugs in floating point formatting:
1. Trailing zeros were being stripped with %e format.
2. %g/%G formats incorrect.
3. Lots of other nits.
the copy built from here was overwritten by the other copy and the other
copy was put in library-building command lines twice. ld now objects to
duplicated modules.
from the code in strftime.c . This affects both the library code
and all the commands using it (e.g. date +%s).
Note that %s is not required by ANSI, but we've already got it in 1.1.5.1.
Suggested by: luigi@labinfo.iet.unipi.it (Luigi Rizzo)
in an (unlikely) border case (maxgroups==1 and the user is on
an /etc/group line for the same group and that group only ...).
Now this case is dealt with as before ...
Add a missing apostrophe that suggests inverting the frequency to get
tick size. It read better before because `CLK_TCK' suggests a tick
size although it is actually a frequency.
as an NIS client. The pw_breakout_yp routines that are used to populate the
_pw_passwd structire only do anything if the bits in the pw_fields member
_pw_passwd are cleared. Unfortunately, we can get into a state where
pw_fields has garbage in it right before the YP lookup functions are
called, which causes the breakout functions to screw up in a big way.
Here's how to duplicate the problem:
- Configure FreeBSD as an NIS client
- Log in as a user who's password database records reside only in
the NIS passwd maps.
- Type ps -aux
Result: your processes appear to be owned by 'root' or 'deamon.'
/bin/ls can exhibit the same problem.
The reason this happens:
- When ps(1) needs to match a username to a UID, it calls getpwuid().
- root is in the local password file, so getpwuid() calls __hashpw()
and __hashpw() populates the _pw_passwd struct, including the pw_fields
member. This happens before NIS lookups take place because, by coincidence,
ps(1) tends to display processes owned by root before it happens upon
a proccess owned by you.
- When your UID comes up, __hashpw() fails to find your entry in the
local password database, so it bails out, BUT THE BITS IN THE pw_fields
STRUCTURE OF _pw_passwd ARE NEVER CLEARED AND STILL CONTAIN INFORMATION
FROM THE PREVIOUS CALL TO __hash_pw()!!
- If we have NIS enabled, the NIS lookup functions are called.
- The pw_breakout_yp routines see that the pw_fields bits are set and
decline to place the data retrieved from the NIS passwd maps into the
_pw_passwd structure.
- getpwuid() returns the results of the last __hashpw() lookup instead
of the valid NIS data.
- Hijinxs ensue when user_from_uid() caches this bogus information and
starts handing out the wrong usernames.
AAAARRRRRRRRRGGGGGGHHHHHHHHHH!!!
*Please* don't tell me I'm the only person to have noticed this.
Fixed by having __hashpw() check the state of pw_fields just before
bailing out on a failed lookup and clearing away any leftover garbage.
What a fun way to spend an afternoon.
- FreeBSD's NIS server can supply a master.passwd map, which has
more fields in it than a standard passwd map, so we need a
_master_pw_breakout() fuction.
- When doing passwd map lookups, look for master.passwd.* by attempting
a _yp_first() on master.passwd.byname. If it exists, we're being served
by a FreeBSD NIS server and we should use this map.
- If we aren't the superuser, retrieve only the standard passwd maps.
If we're being served by a FreeBSD system, then the passwd map has
no passwords in it, and it won't serve us the master.passwd map unless
we're superuser anyway.
There's a small speed hit for the superuser inherent in the check for
the master.passwd map, but this lets us dynamically decide what to do
rather than rely on a non-standard config file somewhere. Since all
of this is bypassed for normal users, they shouldn't notice the
difference.
1) Changed LIB_SCCS and SYSLIB_SCCS to LIB_RCS and SYSLIB_RCS.
2) Changed sccsid[] variables to rcsid[]
3) Moved all RCSID strings into .text
4) Converted all SCCSID's to RCS $Id$'s
5) Added missing $Id$'s after copyright.
YP by disallowing `+' entries as logins in all cases. (This handles the
case of a `+' entry in the password file but YP not running, which should
never happen but is easy enough to check for so we'll apply some
prophylaxis.)
Embalm. Rewrite to do things much the same as gcc-2: use fistpq for speed
and elegance, and mishandle overflow consistently. __fixunsdfsi() is no
longer called by gcc.
getcwd() has two off-by-one bugs in FreeBSD-2.0:
1. getcwd(buf, size) fails when the size is just large enough.
2. getcwd(buf + 1, 1) incorrectly succeeds when the current directory
is "/". buf[0] and buf[2] are clobbered.
(I modified Bruce's original patch to return the proper error code
[ERANGE] in the case of #2, but otherwise... -DG)
This program demonstrates the bug:
---
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
char buf[5];
int errors;
errors = 0;
if (chdir("/tmp") != 0) {
perror("chdir");
abort();
}
if (getcwd(buf, 5) == NULL) {
perror("oops, getcwd failed for buffer size = size required");
++errors;
}
if (chdir("/") != 0) {
perror("chdir");
abort();
}
buf[0] = 0;
buf[2] = 1;
if (getcwd(buf + 1, 1) != NULL) {
fprintf(stderr,
"oops, getcwd succeeded for buffer size = one too small\n");
++errors;
}
if (buf[0] != 0) {
fprintf(stderr,
"oops, getcwd scribbled on memory before start of buffer\n");
++errors;
}
if (buf[2] != 1) {
fprintf(stderr,
"oops, getcwd scribbled on memory after end of buffer\n");
++errors;
}
exit(errors == 0 ? 0 : 1);
}
pointer returned by realloc(). All callers free the pointer if the
execve fails. Nuke the caching. This essentially restores buildargv()
to the 1.1.5 version. Also fix a memory leak if realloc() fails. Also
nuke similar but non-broken caching in execvp(). malloc() should be
efficient enough.
command available yet.
Changed an entry in getprcent.3 from rpcinfo(8C) to rpcinfo(8).
Changed an entry in getrpcport.3 from 3R to 3.
Changed two entries in rpc.3 from 3N to 3.
incredibly obnoxious, but also makes inverse mappings work when the local
resolver is in a cache-only configuration. (Maybe this is actually
a bug in BIND?)
pointer if len is 0. I should have looked at the revision history - I would
have found that Bruce already fixed the bug with len=0 over a month ago.
Whoever said that the bug was in 2.0 was wrong.
for Wine support. The current snapshot of wine works fine with this.
This should go into the beta as the code which it calls in the kernel is
already there, and works fine.
later be applied to a number of programs (inetd for instance) to clean
out the bogus code doing the same thing, modulus all the bugs.
If you need to read a '#'-is-a-comment-file, please use these routines.
I realize that the shlib# should be bumped (for the non-US world:
increased by something), but will defer this until something significant
happens.
From: Chris Torek <torek@bsdi.com>
Here is a semi-official patch (apply to /usr/src/lib/libc/stdio/fseek.c,
rebuild libc, install). The current code fails when the seek:
- is optimized, and
- is to just past the end of the block currently in the buffer, and
- is followed by another seek with no intervening read operation, and
- the destination of subsequent seek is within the block left in the
buffer (seeking to the beginning of a block does not force a read,
so the buffer still contains the previous block)
so it is indeed rather obscure.
I may have a different `final' fix, as this one `loses' the buffer
contents on a seek that goes just past the end of the current block.
[Footnote: seeks are optimized only on read-only opens of regular
files that are buffered by the file's optimal I/O size. This is
what you get with fopen(path, "r") and no call to setvbuf().]
Obtained from: [ BSDI mailing list ]
While trying to figure out why rlogind wasn't working right for root,
I noticed that man wouldn't come back with a man page for iruserok, but
it would for ruserok. Checking the lib/net directory's Makefile.inc
file shows that the link to the rcmd man page just isn't getting
created.
>How-To-Repeat:
Do a 'man iruserok' and notihing will come back, where a 'man ruserok'
will.
Submitted by: Brian Moore <ziff@houdini.eecs.umich.edu>
Obtained from: NetBSD-bugs mailing list
getnet* configuration. (It's highly unlikely that you'd want to do
something different, and network lookups aren't common enough to justify
their own configuration file.)
!!!!!!!!
NB
!!!!!!!!
You MUST pwd_mkdb /etc/master.passwd before attempting to use the new
libc, or things may go wrong. (I doubt anything actually /will/ go
wrong, but the actual behavior is undefined. YOU HAVE BEEN WARNED.)
The database format is, however, backwards-compatible, so old executables
will still work.
>From: jtk@atria.com (John T. Kohl)
in rcmd:
It calls select() with a hardcoded "number of file descriptors" argument
of 32, rather than computing it based on the sockets about which it
cares.
- Now we work out the nfds arg, and do some error checking
Submitted by: Geoff.
Don't add to POBJS or SOBJS. bsd.lib.mk does it. Some objects were
duplicated.
Don't add to CLEANFILES. bsd.lib.mk does it. Some objects were
quadruplicated.
Define variables that are only used once close to where they are
used.
The ifdefs for avoiding building of profiled/shared objects when
NOPROFILE/NOPIC are set were not actually committed. The ifdefs
belong in bsd.lib.mk anyway.
long long. Done by plugging both eax and edx with -1. This will clobber
edx unnecessarily when the return value is only 32bit...though probably
always an okay thing to do, it could stand a better fix.
This was the cause of gawk being broken (boy was THAT ever a subtle
bug!!!).
are running under. Here's how to bootstrap (order is important):
1) Re-compile gcc (just the driver is all you need).
2) Re-compile libc.
3) Re-compile your kernel. Reboot.
4) cd /usr/src/include; make install
You can now detect the compilation environment with the following code:
#if !defined(__FreeBSD__)
#define __FreeBSD_version 199401
#elif __FreeBSD__ == 1
#define __FreeBSD_version 199405
#else
#include <osreldate.h>
#endif
You can determine the run-time environment by calling the new C library
function getosreldate(), or by examining the MIB variable kern.osreldate.
For the time being, the release date is defined as 199409, which we have
already established as our target.