Sorry for the delay in reply. Had a few busy days.


On Tue, Jul 15, 2014 at 7:15 PM, Jakub Hrozek <jhrozek@redhat.com> wrote:
On Mon, Jul 14, 2014 at 09:58:11PM +0300, Noam Meltzer wrote:
> On Mon, Jul 14, 2014 at 7:21 PM, Jakub Hrozek <jhrozek@redhat.com> wrote:
>
> > On Fri, Jun 27, 2014 at 09:44:34AM +0300, Noam Meltzer wrote:
> > > Follow patches are the code implementing design document:
> > > https://fedorahosted.org/sssd/wiki/DesignDocs/rpc.idmapd%20plugin
> > >
> > > Changes compared to v2 of this patch:
> > >  * rebase over rev. 8ca18752 (current master)
> > >  * remove man pages from the patch (will be sent separately)
> > >  * add new contact details for plugin author
> > >  * code style
> > >  * remove sss_nfs_make_request() wrapper
> > >  * fix typo in reply_to_name(): REPLY_ID_OFFSET -> REPLY_NAME_OFFSET
> >
> > Thanks for these changes! The patches look good with one nitpick, which
> > I can fix locally before pushing and one packaging question. I'll ask
> > those inline when replying to the patches themselves.
> >
> > But more importantly, I have a question on testing the patches. I admit
> > my NFS internals knowledge is quite lacking, so maybe these are basic
> > questions..how exactly do I make sure the plugin mapping functions are
> > called? I tried attaching gdb to rpc.idmapd and doing various operations
> > to the file (ls, echo "foo" >> file) etc but still no luck. Disabling
> > the sss nsswitch plugin just yields UIDs and GIDs on the client (which
> > is
> >
> > For my test, I configured a server and a client. I can mount the shares
> > just fine, I see I'm using NFSv4 in the mount(8) output. I can see the
> > sss plugin was loaded, because journalctl -u nfs-idmap.service says:
> > Jul 14 12:01:21 master.ipa.example.com rpc.idmapd[24320]: rpc.idmapd:
> > sss_nfs_init: use memcache: 1
> > Jul 14 12:01:21 master.ipa.example.com rpc.idmapd[24320]: rpc.idmapd:
> > libnfsidmap: loaded plugin /lib64/libnfsidmap/sss_nfs.so for method
> > sss_nfs
> >
> > My idmapd.conf file looks quite simple:
> > --------------------
> > [General]
> > Verbosity = 2
> > Domain = ipa.example.com
> >
> > [Mapping]
> > Nobody-User = nfsnobody
> > Nobody-Group = nfsnobody
> >
> > [Translation]
> > Method = sss_nfs
> >
> > [Static]
> >
> > [UMICH_SCHEMA]
> > nk --------------------
> )>
> > I guess I could also ask -- where does the rpc.idmapd daemon hook into
> > the system? When exactly are the translation functions called?
> >
>
> The idmapd.conf looks good (assuming that your LDAP domain really is
> ipa.example.com).
>
> Regarding how rpc.idmapd operation:
> 1. There's the feature wiki:
> https://fedorahosted.org/sssd/wiki/DesignDocs/rpc.idmapd%20plugin
> I'm not sure that it answers your question though. (so I'll make sure to
> update it following this email thread)

I'm aware of the design document, but I was more interested in some
user-facing documentation. Something we could give to the admins to tell
them what are the benefits and how to leverage them.

Oh, sorry. Gotcha now. Here goes: (I think it should also go to the manpage & wiki page, what do you think?)

  The sss_nfs plugin is useful on systems designated as dedicated NFS servers.
Background: With NFSv4 it is required to be able to translate between usernames/groupnames sent on the wire to uid/gids and vice versa. The traditional way of achieving this is by having the OS aware of the various NFS users/groups and then retrieve the user<->uid / group<->gid information from the OS.
However, that methodology poses a security concern which requires special attention. The sss_nfs plugin overcomes this issue by providing direct communication path between rpc.idmapd (+ libnfsidmap) and sssd.

 
>
> 2. rpc.idmapd listens for events (queries) from the kernel over a named
> pipe. once such an event arrives, rpc.idmapd will start the mapping process
> using libnfsidmap.

OK, thanks, that's very helpful, but how/when does the kernel receive
the event ? How can I trigger that even as admin or a user using NFS
client+server ? For instance, if you run "ls -l", is there anything more
than the id->name conversion using getpwuid() ? I realize these might be
basic questions, so feel free to point me to docs..
These are good questions. Unfortunately (for me) the answer is not well (or maybe not at all) documented. I'll try to provide a good explanation without going too much into details.

Assume a NFSv4 setup:
Server = Fedora20, kernel NFS server.
Client(s) = Various linuxes, other UNIXes.

On the very basic level:
When a client send a GETATTR request on the wire (in a sense, similar to stat(2)), the server will perform the following operations to retrieve the info:
* Read the uid/gid from the file on disk
* Send a request on a well defined named-pipe requesting uid/gid to username/groupname mapping.
* rpc.idmapd will receive the request and perform the mapping using libnfsidmap (and here comes the sss_nfs plugin...)
* respond will be sent on a well defined named-pipe to the kernel.
* kernel nfs server will send the information (the username/groupname) over the wire as strings.

Once the client receives the information over the wire it will need to translate the username/groupname back to uid/gid. The actual mechanism is out of scope for this email, but if the client is Fedora20, the NFS client will run an upcall to "/usr/sbin/request-key" to perform the translation.

Sounds simple? Now lets make it complicated:
* Caching might be available both on client side and server side.
* On recent linux kernels (not sure which versions), if sec=sys is used on the NFS export, there will be a short-circuit sending the uid/gid as a string over the wire (check manpage exports(5), section about sec= for more info) thus translation is not performed.
* There are different NFS clients & servers: linux vs. UNIX vs. commercial NFS products (NetApp, for example). Each one implementing the NFS protocol a bit differently.

So... How to test a full system with Fedora20 client & server?
Having a kerberised NFS setup is one option. However, this might be a pain in the neck to setup (if you don't have one already).
A more simpler solution is to use the "sec=sys" and disable the short-circuit described above:
echo N > /sys/module/nfsd/parameters/nfs4_disable_idmapping
echo N > /sys/module/nfs/parameters/nfs4_disable_idmapping
 
If when doing "ls -l" on a directory with files, you see the permissions you expected to see, then test was successful.


> libnfsidmap on its turn will dlopen(3) the relevant plugin (sss_nfs in our
> case) and call the relevant functions from 'struct trans_func'.
>
>
> How to test:
> libnfsidmap.git comes with a small C code named "libtest.c" which allows
> you to directly test the various function from 'struct trans_func'.
> I modified this code a bit to match our needs (and attached to this email).
> compile/link with:
> gcc -o libtest libtest.c  -lnfsidmap
>
> run like this:
> $ ./libtest noam@localdomain 0 users@localdomain 101
>
> expected output:
> input: user=noam@localdomain uid=0 group=users@localdomain gid=101
> nfs4_name_to_uid: username noam@localdomain has uid 1000
> nfs4_name_to_gid: username users@localdomain has gid 100
> nfs4_uid_to_name: uid 0 has name root@localdomain
> nfs4_gid_to_name: gid 101 has name libuuid@localdomain

Thank you, I will test using the program so far.

>
>
> Unfortunately, I don't have an LDAP environment at the moment to test it
> myself. So what you see here is the result of the default idmapd.conf
> running with the "nss" plugin (going to /etc/passwd ...)

np, I can test with your program. Thanks again.