Coda File System

Re: UIDs/GIDs

From: Jan Harkes <jaharkes_at_cs.cmu.edu>
Date: Fri, 9 Apr 2004 05:49:13 -0400
On Thu, Apr 08, 2004 at 10:45:12AM +0200, Michael Tautschnig wrote:
> Jan, thanks for your extensive answer - but still a few questions remain:

I'm sorry, this one got a bit out of hand as well.

> On Thursday, 08. April 2004 06:32, Jan Harkes wrote:
> > On Thu, Apr 08, 2004 at 02:37:58AM +0200, Michael Tautschnig wrote:
> > > Since I intend to use Coda in a production environment, I need to know a
> > > lot more about the mapping of uids/fileowner between getent()-results
> > > (e.g. /etc/ passwd) and coda's own database.
> > >
> > > - What was the idea when creating an independent database (obviously
> > > administrative work increases...)?
> >
> > Clients are untrusted. Local userid's are irrelevant. Large
> > installations typically already have some sort of an independent
> > database (ldap, nis, mysql, pts) and the idea was that the interface we
> > use to access the pdb database would be abstract enough to allow Coda to
> > hook into any existing systems.
> 
> This is really fine, since I am using ldap for all of this, but using nss 
> there is no difference between that and /etc/passwd. So  - how much work is 
> to be done to move the coda-database to ldap?

Ah, there has been one attempt a year or two ago, there were some
problems with using LDAP,

 The OpenLDAP library was using pthreads, which didn't mix well with
 Coda's userspace LWP thread package. Maybe pthreads/LWP are a bit more
 compatible by now, and the liblwp_pt did mature a bit since then as
 well I had to run venus linked with pthreads to hunt down some memory
 problem with valgrind.

 The library did have failover to LDAP replica servers when setting up
 the initial connection to the LDAP servers, but didn't handle failover
 when the server failed with an already established connection. I guess
 most LDAP clients simply set up a new connection for every query, but
 for performance reasons we were using persistent connections. The
 failover/reconnect handling during query processing was pretty messy.
 Again, 2 years can make a lot of difference.

 LDAP is slower, so we tried to use some built-in query cache which
 was a bit funny. I can't really remember the details, but I believe
 there was no way to invalidate cached queries/responses, so when a
 user was added to a group the servers had to be restarted to clear the
 stale cache. But I'm not sure whether this was really the problem.

Any case, we decided at the time that is was probably better to wait
until things stabilized a bit further instead of trying to shoehorn
something in.

> > > - How can I change a file's owner/group according to coda-numbers
> > > (e.g. change group to -3 ?)
> >
> > The Unix userid and groupid is totally unused, we don't even send the
> > groupid information in the SetAttr/GetAttr rpc calls. When a file is
> > created the userid is set according to the Coda userid of the RPC2
> > connection, although the locally cached copy initially will have the
> > local userid. i.e. my local userid is 1000, my Coda userid is 7768. So
> > when I create a file it will initially have uid 1000 on only my client,
> > everyone else sees 7768, as will my client if it ever replaces the
> > cached copy.
>
> How does coda get to know this mapping? On which basis does it map? I thought 
> it was the uid, but that doesn't make sense anyway...

I guess it isn't mapped explicitly.

The client has a mapping of local uid -> (codatoken, realm), which is
then used to create an authenticated connection with a server based on
the identity stored in the Coda token. The client knows the local uid
and the Coda token that it should use to talk to servers in a specific
realm, but has no way to reliably tell what the Coda user identity is.

The server knows the Coda user identity from the token, but not what the
original local uid on the client was. At the moment Coda identities are
stored in the encrypted part of the token as a Coda userid (i.e. 7768)
and auth2 is responsible for mapping the username given by clog to this
userid. But we really want to store the username/identity-string in the
token and have the Coda server perform the mapping.

This way auth2 only has a minimal dependency on the pdb database, the
only place we need to perform a lookup is when changing passwords as we
need to check if we are a member of the System:Administrators group.
Ideally if auth2 is only used for authentication purposes and not user
administration it never even needs to touch the user/group databases.

> > So a Coda client doesn't try to interpret the token we give it, and
> > doesn't interpret ACLs as it really has no (reliable) clue what our Coda
> > userid is or which Coda groups we are a member of.
>
> But what happens if you get disconnected? In what way is access control done 
> on cached objects or for creating new objects?

As others mentioned, rights are cached. When a new object is created it
inherits the rights of the parent.

> BTW - where will I get in trouble when using large caches (e.g. > 1GB
> on 
> laptops)?

I tend to use ~200MB, but my 'working set' is only about 155MB. VM usage
of the Coda client is indirectly tied to the size of the cache. There is
a whole formula of 'estimates',

Given a 1GB cache size, we assume an average file size, which gives an
estimated number of objects in the cache. Space for all these objects is
reserved. Then we assume that some percentage will be directories.
Additional space is reserved. Then we assume N directories per volume,
and M volumes per realm and finally it is all rounded up to some almost
arbitrary number of MB we need for the RVM data segment. Which seems to
be fairly close to 10% of the cache size with the default numbers.

So with my 200MB cache, my client allocated just over 20MB of RVM and
ends up allocating another 10MB of 'normal' memory giving a total
process size of 30MB. With a 1GB cache I would expect a client to have
~100MB RVM and somewhere between 20 and 50MB of additional allocations
using up close to 150MB of total VM.

However if your objects are relatively larger, it is possible to set
both the 'cachesize' as well as the 'cachefiles' options in venus.conf.
The number of files is really what is using RVM. The limiting factor
simply used to be disk space, but as disks have exponentially grown the
real limitation now is more often memory.

> > Maybe Coda should always return a fixed userid in a file's attributes
> > similar to the fixed groupid (65535 or something) we already have. But
> > sadly a lot of installers (rpm/dpkg/install.sh) tend to fail when we
> > don't appear to listen at least a little to chmod/chown syscalls.
>
> My users will like to be able to change access rights on their files (e.g. 
> what about making files executable) and e.g. give a virtual group access to a 

Executable is a funny little bit. Would you believe that pretty much
nothing in the kernel (or at least the filesystems) really cares about
it. Executing an object is nothing more than mmapping or reading the
file into a memory region. I guess it must be the shell that interprets
this bit. 

> project - how could they do that? Furthermore they probably prefer to do it 
> using chmod/chown ...

Users can modify the modebits of any object in a directory as long as
the ACL gives them write permission. And chmod works just fine
(setuid/setgid are of course disabled).

However I think you need to have at least admin permission from the ACL
before you can use chown, and the generic VFS layers in the kernel like
to enforce some policy here as well so you might have to be logged in as
root or have a matching uid on the file or something. But the userid set
by an explicit chown will be stored on the server.

As far as group access is concerned, only an administrator with access
to the pdb database can create and manage Coda groups. The datastructure
does already have a 'group owner' defined, but there is no RPC call in
auth2 that actually allows the group owner to perform management
functions. Once the group is there a user simply does, 'cfs setacl <dir>
groupname rlidw' to allow read/lookup/insert/delete/write rights.
Read and write are for files in the directory. Lookup, insert and delete
control operations on the directory.

Jan
Received on 2004-04-09 05:54:19