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