4 * Heimdal compatability layer.
6 * $FreeBSD: src/lib/libpam/modules/pam_krb5/compat_heimdal.c,v 1.1.2.2 2001/07/29 18:57:30 markm Exp $
15 #include <security/pam_appl.h>
16 #include <security/pam_modules.h>
20 compat_princ_component(krb5_context context, krb5_principal princ, int n)
22 return princ->name.name_string.val[n];
26 compat_free_data_contents(krb5_context context, krb5_data *data)
28 krb5_xfree(data->data);
31 static krb5_error_code
32 heimdal_pam_prompter(krb5_context context, void *data, const char *name,
33 const char *banner, int num_prompts, krb5_prompt prompts[])
35 int pam_prompts = num_prompts;
38 struct pam_message *msg;
39 struct pam_response *resp = NULL;
40 struct pam_conv *conv;
41 pam_handle_t *pamh = (pam_handle_t *) data;
43 if ((pamret = pam_get_item(pamh, PAM_CONV, (const void **) &conv)) != 0)
44 return KRB5KRB_ERR_GENERIC;
49 msg = calloc(sizeof(struct pam_message) * pam_prompts, 1);
53 /* Now use pam_prompts as an index */
57 msg[pam_prompts].msg = malloc(strlen(banner) + 1);
58 if (!msg[pam_prompts].msg)
60 strcpy((char *) msg[pam_prompts].msg, banner);
61 msg[pam_prompts].msg_style = PAM_TEXT_INFO;
65 for (i = 0; i < num_prompts; i++) {
66 msg[pam_prompts].msg = malloc(strlen(prompts[i].prompt) + 3);
67 if (!msg[pam_prompts].msg)
69 sprintf((char *) msg[pam_prompts].msg, "%s: ", prompts[i].prompt);
70 msg[pam_prompts].msg_style = prompts[i].hidden ? PAM_PROMPT_ECHO_OFF
75 if ((pamret = conv->conv(pam_prompts, (const struct pam_message **) &msg,
76 &resp, conv->appdata_ptr)) != 0)
82 /* Reuse pam_prompts as a starting index */
87 for (i = 0; i < num_prompts; i++, pam_prompts++) {
89 if (!resp[pam_prompts].resp) {
90 pamret = PAM_AUTH_ERR;
93 len = strlen(resp[pam_prompts].resp); /* Help out the compiler */
94 if (len > prompts[i].reply->length) {
95 pamret = PAM_AUTH_ERR;
98 memcpy(prompts[i].reply->data, resp[pam_prompts].resp, len);
99 prompts[i].reply->length = len;
103 /* pam_prompts is correct at this point */
105 for (i = 0; i < pam_prompts; i++) {
107 free((char *) msg[i].msg);
112 for (i = 0; i < pam_prompts; i++) {
114 * Note that PAM is underspecified wrt free()'ing resp[i].resp.
115 * It's not clear if I should free it, or if the application
116 * has to. Therefore most (all?) apps won't free() it, and I
117 * can't either, as I am not sure it was malloc()'d. All PAM
118 * implementations I've seen leak memory here. Not so bad, IFF
119 * you fork/exec for each PAM authentication (as is typical).
126 /* This does not lose resp[i].resp if the application saved a copy. */
130 return (pamret ? KRB5KRB_ERR_GENERIC : 0);
133 krb5_prompter_fct pam_prompter = heimdal_pam_prompter;