Andrew Morgan wrote: > > Solar Designer wrote: > > I also agree that the callback pointer should be inside pamh. > > So what does the final proposal look like? :) Ok, prototype summary: int pam_log(pam_handle_t *pamh, int priority, const char *fmt, ...); int pam_vlog(pam_handle_t *pamh, int priority, const char *fmt, va_list args); That are two public routines used by modules. Another one: typedef int pam_log_callback_t (pam_handle_t *pamh, const char *module, const char *service, int priority, const char *message); /* used only to simplify next declaration */ pam_log_callback_t *pam_set_log_callback(pam_handle_t *pamh, pam_log_callback_t *newcb); This routine should be used by application if desirable. It returns previuos callback used. If newcb == NULL, default callback will be set. [Maybe: if pamh == NULL, just return default callback and ignore newcb.] Inside libpam (log_callback is a member of pam_handle_t structure): pam_vlog(pamh, pri, fmt, args) { char *buff; /* format message in buff using fmt and args */ retval = (*pamh->log_callback)(pamh, pamh->module, pamh->stack, pri, buff); /* free/clean buff etc */ return retval; } default callback (that initialized by pam_start): static int pam_default_log_callback(pamh, module, stack, pri, msg) { openlog(module, LOG_AUTH|...); syslog(pri, "%s: %s", stack, msg); closelog(); return PAM_SUCCESS; } Ok, 3 questions. 1. Can we omit openlog/closelog? Manpage sais that them are both optional. Also consider: syslog(pri|LOG_AUTH, "%s: %s", stack, msg); ^^^^^^^^^^ 2. Final format for last syslog line? 3. Maybe routines should be void? Should I implement this all? It is almost trivial... Regards, Michael.