mailing list archives
NIS+ and signed directory objects
From: secure () SUNSC ENG SUN COM (Sun Security Coordination)
Date: Tue, 15 Apr 1997 18:43:56 -0700
On Thu Mar 27 11:17:20 1997,
Bill Paul (wpaul () CTR COLUMBIA EDU) wrote:
NIS+ clients run a daemon called nis_cachemgr which is designed to
cache directory 'objects' returned from NIS+ servers. The object is
really an XDR encoded directory_obj structure (as defined in
<rpcsvc/nis_object.x>). The tricky part about nis_cachemgr is that
any local process on the system is allowed to send it requests to
cache objects; nis_cachemgr is basically just an RPC server, with
a protocol defined in <rpcsvc/nis_cache.x>. Since NIS+ directory
lookups are performed by library code in libnsl, they might be made
by anyone on the system; hence nis_cachemgr must be prepared to
accept updates from privileged and unprivileged users alike.
The cache (/var/nis/NIS_SHARED_DIRCACHE) is later accessed by other
processes: if, say, user 'foo' does an 'niscat passwd.org_dir,' this
will cause the org_dir object to be saved in /var/nis/NIS_SHARED_DIRCACHE.
Subsequently, user 'bar' may issue the same command, but rather than
asking the remote server to do a directory lookup all over again,
the client NIS+ library reads the org_dir object from the cache.
An obvious question is: what happens if a malicious user decides to
write his own client program to talk to nis_cachemgr and instructs it
to load the cache with bogus objects? How can nis_cachemgr tell if
the request is legitimate or if the user is just trying to be a wiseass?
The answer is supposed to be the 'signature' contained in the fd_result
structure returned by the NIS+ server (rpc.nisd). The server is supposed
to compute an MD5 digest of the encoded directory object and encrypt it
(with ecb_crypt()) using a Secure RPC conversation key. This conversation
key consists of the server's secret key and the requester's public key.
(You can get it from the keyserv daemon with the key_get_conv() function.)
Since nis_cachemgr runs as root, its principal name is the same as
the 'requester' listed in the finddirectory request, hence it will be
able to compute its own signature and compare it to the one generated
by the server (using its secret key and the server's public key).
Since only the server knows its RPC secret key, it should be impossible
for a user to forge a directory object because it can't create a proper
But here's the problem: from what I can tell, rpc.nisd never signs its
directory objects and nis_cachemgr never checks for them. I've run
several tests with Solaris 2.5.1 on a couple of different machines.
I've set up a dummy root server and a single dummy client, with all
the right credentials. Authentication of the client works correctly
and the service seems to function properly. However, when I use a
test program to call the NIS_FINDDIRECTORY procedure on rpc.nisd,
the server sends back an object without a signature. I tried several
different variations (using AUTH_DES authentication, using AUTH_SYS
authentication, using no authentication, running the program on the
server host itself) but I could never get rpc.nisd to supply a signed
At first I was convinced that I was omitting some magic in my test
program since I could tell that nis_cachemgr was adding directory objects
to the client's cache. The nis_cachemgr man page states that it will
always attempt to authenticate the signature unless you start it with
the -i flag (to activate insecure mode). I did not start nis_cachemgr
with the -i flag, so it should have been checking for signatures and
if rpc.nisd wasn't sending them, it would never have updated the cache.
Finally, after simplifying the test program as much as I could and
still not getting any results, I started to think that maybe the problem
was with rpc.nisd after all. Thanks go gdb, I finally learned what was
going on: the insecureMode flag in nis_cachemgr starts off initialized to
0 but is forced to 1 later in the program even though nis_cachemgr was
_NOT_ started with -i. In other words, nis_cachemgr doesn't really check
for signatures at all, which bore out my hunch that rpc.nisd was never
sending them. As a further test, I even toggled the insecureMode flag
back off with gdb and let nis_cachemgr continue running; now, as I
expected, it would no longer add any directory objects to the cache since
it couldn't verify the signatures.
Bill's analysis is correct. nis_cachemgr does not check for signatures
resulting in the possibility of loading bogus directory objects in the
cache managed by nis_cachemgr. This is a bug that is fixed in Solaris 2.6
which is expected to be released later this year. The only workaround is
to disable nis_cachemgr on the client machines. Sun is investigating
patching this bug for Solaris 2.3, 2.4, 2.5, and 2.5.1 and will announce the
availability of the patches later through a Sun bulletin.