Re: [OT] getpwnam() interface (was Re: PAM and the pwd.h interface)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I speak of traditional old-school authentication (pam_unix).
Things like kerberos have differant needs, but we must keep /etc/passwd
style authentication in mind.  This is why I am pushing for a read-write
API.


On Tue, 12 Jun 2001, Nicolas Williams wrote:
> The biggest problem is this: whereas a read-only API can be generic
> enough to apply different name services and data models with rather
> little pain, the same is NOT true of write APIs.

Like I have said in other emails, some PAM modules "require" the ability
to write certain user attributes.  I'll relate this to what is probably
the most widely used module: pam_unix. Pam_unix needs to be able to write
a hashed password to wherever user-attributes are stored (traditionally
/etc/passwd). It is an apsolute neccesity. As of now, "/etc/passwd"
and "/etc/shadow" are hard-coded into the functions used to store this
information in pam_unix.  This is bad if you want to use some alternative
place (or method, like a database) to store authentication information.

Another issue is that pam_unix currently handles the rewrite of
/etc/passwd.  This should not be handled by the password module. If there
are two differant password modules being used by differant services and
they both need to update these files at the same time, they "must" use the
same locking scheme.  This may be an unlikely scenario, but it is a real
concern for administrators who might wish to use differant password
modules in differant services that both rely on the same file.

In a read-write API, these things could all be handled by the "user
attribute" module.


> PAM is not an administration interface. Neither is NSS. I want to
> replace NSS with a more generic interface, but still read-only.

In some ways it is. See above. PAM still manages password changing. In
this way, PAM "is" an administration interface. NSS is not. PAM modules
don't use NSS when changing a users password.  They do it in their own
way (because they have to).  It would be much better if the new API took
this job out of the hand's of the modules.


> It's a much easier way to start than would be designing a read-write
> replacement API.

I'm of the crowd "If you're going to do it, go all out."  If we are going
to make a replacement API, it will need to be read-write.  At first we
can certainly start with read-only and then implement the write
functions, but in the end the API should be read-write.


> Also, I only want to integrate a getpwnam() replacement
> API with PAM, not necessarily all of NSS.

Yeah.. of course. We are only dealing with user authentication, not ethers
or protocols.  All I would want to implement is a replacement that can
handle everything that might be done with the passwd, shadow, and group
entries in nsswitch.conf.

One of your main reasons for wanting to replace nss is the lack of
flexibility from getpwnam(). One of my main reasons is the non-existance
of putpwnam().

In a previous e-mail you said there was no putpwnam().  Well, there
"should" be a putpwnam().  If we are going to replace getpwnam(), we
should create something along the lines of putpwnam().  Just because it
hasn't existed in the past doesn't mean it shouldn't exist in the future.

> 
> Finally, look at XFN and what a crummy API that was. That's what you get
> when you try to address the write-side of things generically.
> 

XFN is not what we are trying to do.  All we want is a flexible
[and modular] way to access user attributes.


> > Well, I think the second prototype would fit into PAM better (going mainly
> > by pam_get_item()).  This way, the application can request the attribute
> > it needs directly.  Multiple values probably aren't required, but I'm not
> > sure.
> 
> Really? What about the groups that a user belongs to?

I knew I was forgetting something :).  However, this could still be
handled by a single multi-dimensional array.  You would signal the end of
the array with a reserved value (probably -1).  So I'll stick with my
original statement that multiple values "probably" aren't required. This
isn't a big issue. At the moment I'm more concerned with convincing you we
need a read-write API :).


> 
> > Yes, we would need to decide on a standard set of attributes.  Everything
> > getpwnam() provides should be sufficient; I can't think of anything else
> > that would be needed by the application, but additional attributes could
> > be transparently added if we used the second prototype above.
> 
> It is precisely because getpwnam() does not provide enough attributes
> that I want to replace it.
> 

heh. That's the reason we would make it flexible enough so that additional
attributes could be added as the need arrises.  This is a big weakness of
getpwnam, and is one of the reasons I would go with your second prototype
of being able to request attributes in an item-by-item case.  This way new
attributes could be transparently added.


> There's lots of things that an app, and more importantly, PAM *modules*,
> might need. E.g., login enabled/disabled status, hours during which the
> user can login, groups the user belongs to, _netgroups_ the user belongs
> to, and other authorization data. Don't tell me to stuff that into the
> GECOS field of passwd entries. I wouldn't bother if that were enough.
> And don't tell me that replacing the crypted password or shell fields is
> enough to mark a user as disabled (think of Samba, which checks neither
> in some setups).
> 

Ok. These are very good points you bring up.  I suppose I'm just not
thinking of these things because I personally have no need for them. You
are correct though, these things would definately be nice to have.

> > Now, here is another hypothetical problem that is identical to the problem
> > I was facing with pam_crypt. How do authentication modules obtain these
> > attributes?
> 
> Using this very API.

My point exactly. But do you use the same API for the application as you
do for the modules? (see below)

> 
> > The main attributes that authentication modules would need are the hashed
> > token (password) and account expiration information. Coincidentally, these
> > are the things in /etc/shadow.
> 
> Stop thinking crypt() for a minute. There's other authentication
> mechanisms.

heh. Yeah, sorry.


> > The authentication modules would rely on PAM to obtain these attributes.
> > We can probably do this (for the module) in one of two ways. Either add a
> > pam_get_item() feature, or create a new call solely for dealing with these
> > authentication attributes.  It would probably be much simpler and much
> > better to add things to pam_get_item().
> 
> But that would not be extensible.

In refering to your statements above about things like the hours a user
can login, you are correct in saying that using pam_get_item isn't
extensible enough.  We should probably use the same API for modules that
we use for applications.  An example would be for when an authentication
module checks a user's shell.  I suppose this could be a useful module, so
we might as well use the same API.


> > Another issue that would arrise is the fact that in order to authenticate
> > a user, not only must the authentication stack succeed, but the "user
> > attribute" stack must also succeed if the authentication stack needs
> > information from the "user attribute" stack.
> 
> Why? If the modules use this API then they'll know when a missing
> attribute should lead to module failure.

To answer "Why?", if we used the first prototype where all of the user
attributes were returned at once, then the module wouldn't know which
attribute was missing.  It will definately be much better to have an
item-by-item API (your second prototype).

So I guess this is a non-issue.

> > - Adam Slattery
> 
> Nico

- Adam Slattery







[Index of Archives]     [Fedora Users]     [Kernel]     [Red Hat Install]     [Linux for the blind]     [Gimp]

  Powered by Linux