On Tue, Jun 12, 2001 at 02:18:39PM -0400, Adam Slattery wrote: > > 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. I suppose I would be willing to settle for this: - a user profile attribute/value based API for reading - a user profile attribute/value based API for writing - a statement that the ability to change user profile attributes will depend on the modules in the stack, and that coders should not expect writes to work in all circumstances Now, I'd like to follow a comment I made just before, that this API should not be a part of PAM after all, but external to it, with a function for apps to pass in the credentials they have available, including PAM handles. Let me use 'nss_' as a prefix, or perhaps, 'nnss_' (new nss). nnss_handle_t nnss_start(...); int nnss_set_creds(nss_handle_t nnssh, nss_cred_type_t cred_type, void *creds); int nnss_get_user_prof_attr(nss_handle_t nnssh, /* optional */ char *nnss_service, /* optional -- use * configured stack if * not specified */ char *user, nnss_attr_type_t type, char *attr, void **val /* another function should * handle multi-value attributes? */ ); and so on, including a similar set attr function. Cred types would include: GSS-API creds, Kerberos creds, PAM handles, etc... Attribute types would include int(8, 16, 32, 64), uid_t/gid_t, string (char *), and so on. Calls to nnss_get_user_prof_attr could be made with a null nnss handle, meaning "use whatever creds you can find in my environment, if you need any." Then only one thing need be added to PAM: a new PAM item to store an nnss handle. > > 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. Clearly, changing passwords is exceptional. And that's the only user item that PAM can change. You can't use PAM, as it is, to change a user's shell, and I now believe PAM should not be extended so you could. > 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. Hey, the modules get called in order, so there's no locking issues there. > In a read-write API, these things could all be handled by the "user > attribute" module. See sketch API above. > > 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. See above. PAM can only change passwords now. > > 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. It has to be simple a simple API, but with no fixed profile structure like getpwnam(). > > 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. I was thinking of gethostby*() and friends, which are also part of NSS, and which I don't want to mess with now (though they too need extensibility). > 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(). Ok. I can see that, but, as I said, you can't expect a write API to work with all name services -- you care about the 'files' name service, and so a simple API will probably do for you (but even here, I don't care to cover user creation, and if you have no transactional interface, then it may be an inefficient interface). > 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. I still disagree, but I think that some user attributes are easy enough to handle that we can probably deal with them in a read-write API. > > 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. And the difference is...? :) > > 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 :). Well, see above. > > > > > 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. Both of the prototypes I suggested were of the one-attr-at-a-time type. > > > 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) I think so. I don't see why not. Hey, the apps and the modules use getpwnam() now... > > > 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. I still wouldn't make that kind of thing a PAM item -- the app should call pam_acct_mgmt() and abide by the result. The modules in the stack should be responsible for evaluating login-hours and all that. Making this new API external to PAM should make that clear since that means not changing PAM. ... > - Adam Slattery Cheers, Nico --