Re: Incompatibility between Linux-PAM and other PAM?

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

 



Gary Winiger wrote:
> > I think the Sun guys didn't think when they implemented this. I actually
> > asked the Sun guys about it when I was writing this part of libpam_misc
> > (5 years ago?) and they never gave any response. The first I heard that
> > they had implemented it wrongly was actually about a year ago, when a
> > commercial module developer emailed me to say that they'd run into this
> > problem with their module and had opted to support both meanings of
> > 'pam_message **' in what they passed to the conversation function.
> > Slightly sick, but quite doable.
> 
>         I'm probably being dense, I read the documentation as:
> 
>         "int conv(int num_msg, const struct pam_message **msg,
>             struct pam_response **resp, void *appdata_ptr);
> 
> 
>         The num_msg  parameter is the number of messages  associated with the
>         call. The parameter msg is a pointer to an array of length num_msg of
>         the pam_message structure."
> 
>         Not an array of pam_message structure pointers.
> 
>         The code implements it as:
>                 msg = (struct pam_message *)calloc(num_msg,
>                     sizeof (struct pam_message));
>                 retcode = (pam_convp->conv)(num_msg, &msg, ret_respp,
>                     conv_apdp);
> 
>         That seems the same to me as const struct pam_message *msg[]. Though

No, (..., const struct pam_message *msg[], ...) implies [like the
main(..., argv) case] that you are passing an array of pointers. In
point of fact, K&Rv2 is quite careful to use the following prototype for
their main(...) functions:

  main(int argc, char *argv[])

which, given the current topic, is less ambiguous than main(int argc,
char **argv). Common usage of the latter (which I believe was what K&R
used in their first C book - but that's my memory as opposed to actually
based on having the book in front of me - refers to the same data
structure).

>         I agree *msg[] might be clearer.  I believe whomever did the prototype
>         at X/Open followed the main(int argc, char **argv, char **envp)
>         prototype that was popular at one time.  IMO, the X/Open spec has a
>         number of typos that should be corrected some day.  This could be one
>         of them.

The prototype is also present in the original RFC from SunSoft. There is
a cached copy of that here:

 http://www.kernel.org/pub/linux/libs/pam/pre/doc/rfc86.0.txt.gz

Now that I read it again, its actually curious that the example
login_conv() function that this document contains doesn't work as
written(! No definition of 'm'), but its spirit seems a great deal more
in line with the Linux implementation than the Solaris one.

If the prototype had been written differently then it could have been:

    int conv(int num_msg, const struct pam_message *msg,
             struct pam_response **resp, void *appdata_ptr);

which is not ambiguous, and quite sufficient for the way the
conversation function is used. Unfortunately, we've all implemented an
interpretation of **msg - which is incompatible with this more clear
definition.

History and backward compatibility - its a real pain.

Cheers

Andrew





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

  Powered by Linux