I like this (note, I've added some 'f's to function names): int pam_logf(pam_handle_t *pamh, int priority, const char *fmt, ...); int pam_vlogf(pam_handle_t *pamh, int priority, const char *fmt, va_list args); (Want to clarify this?): > Oh, again forgot this. locale() + LC_CTIME handling for syslog here, > example is in `Shadow Utilities'. Ugly but necessary. I'm in agreement with Nikolay on this way to go (since it can be detected with either a source code #ifdef, or a dynamic pam_get_item() call): Nikolay Pelov wrote: > PAM already supports setting two user-defined callback functions: > conversation function and fail-delay function. And there is a > standard convention how to set and retreive them: > > pam_(set|get)_item(pamh, PAM_CONV, conv_func); > pam_(set|get)_item(pamh, PAM_FAIL_DELAY, fail_delay_func); > > So, I think we should stick with this principle and use > pam_set_item(pamh, PAM_LOG_CALLBACK, new_pam_callback_vlogf); pam_get_item(pamh, PAM_LOG_CALLBACK, ¤t_pam_callback_vlogf); If no one has installed a callback, the pam_get_item call will indicate that NULL is the current value. Despite this, libpam will use its installed default: static int _pam_vlogf(); function, when a module or application calls pam_*logf(). I'm confused by Michael's proposed definition for the prototype of the "pam_callback_vlogf" (my name) function. What is wrong with this?: int pam_callback_vlogf(pam_handle_t pamh, int priority, const char *fmt, va_list args); What is not at all clear to me is whether we should have some PAM_LOG_* definitions for the 'priority' argument. Some systems may not support syslog so using the priorities defined for syslog may not be sufficiently portable. Should we define: PAM_LOG_URGENT, PAM_LOG_NOTICE, PAM_LOG_WARNING etc., and leave it up to libpam or the application to map them to some system specific stuff? Cheers Andrew