Import upstream 2.3 release.
Russ Allbery
17 years ago
0 | 85 Russ Allbery 2006-09-03 | |
1 | Release 2.3. | |
2 | ||
3 | 84 Russ Allbery 2006-09-03 | |
4 | Fix the interface between the Kerberos prompting function and the | |
5 | PAM conversation function on Linux. Prior to this fix, the PAM module | |
6 | would only work on Solaris if Kerberos passed multiple prompts, which | |
7 | happens when an account requires a password change. Solaris and Linux | |
8 | PAM implementations expect a different structure of pam_message | |
9 | structs in the conversation function; use a workaround to cater to | |
10 | both of them. Based on a patch by Joachim Keltsch. | |
11 | ||
12 | 83 Russ Allbery 2006-08-29 | |
13 | Minor comment fixes. | |
14 | ||
15 | 82 Russ Allbery 2006-08-29 | |
16 | Implement retain_after_close, which specifies that the PAM module | |
17 | should never destroy the user's ticket cache, even on session end. | |
18 | ||
19 | 81 Russ Allbery 2006-08-29 | |
20 | Adjust for the differences in Solaris's PAM libraries: Include | |
21 | pam_appl.h everywhere for structure and type definitions, and add | |
22 | portability workarounds for the return statuses missing from the | |
23 | Solaris implementation. | |
24 | ||
0 | 25 | 80 Russ Allbery 2006-08-28 |
1 | 26 | Release 2.2. |
2 | 27 |
0 | 0 | User-Visible pam-krb5 Changes |
1 | ||
2 | pam-krb5 2.3 (2006-09-03) | |
3 | ||
4 | Fix the interface between the Kerberos prompting function and the | |
5 | PAM conversation function on Linux. Prior to this fix, the PAM module | |
6 | would only work on Solaris if Kerberos passed multiple prompts, which | |
7 | happens when an account requires a password change. Solaris and Linux | |
8 | PAM implementations expect a different structure of pam_message | |
9 | structs in the conversation function; use a workaround to cater to | |
10 | both of them. Based on a patch by Joachim Keltsch. | |
11 | ||
12 | Implement retain_after_close, which specifies that the PAM module | |
13 | should never destroy the user's ticket cache, even on session end. | |
14 | ||
15 | Adjust for the differences in Solaris's PAM libraries: Include | |
16 | pam_appl.h everywhere for structure and type definitions, and add | |
17 | portability workarounds for the return statuses missing from the | |
18 | Solaris implementation. | |
1 | 19 | |
2 | 20 | pam-krb5 2.2 (2006-08-28) |
3 | 21 |
0 | pam-krb5 2.2 | |
0 | pam-krb5 2.3 | |
1 | 1 | (PAM module for Kerberos v5 authentication) |
2 | 2 | |
3 | 3 | Originally written by Frank Cusack |
11 | 11 | the user is authenticating to. |
12 | 12 | |
13 | 13 | * Diagnose unknown options to the PAM module. Currently, they're ignored. |
14 | ||
15 | * Try to support Solaris as well. I don't know how close the module is | |
16 | to just working and how much the Solaris PAM setup differs from Linux. | |
17 | (HP-UX is probably not worth the effort.) |
0 | 0 | #! /bin/sh |
1 | 1 | # Guess values for system-dependent variables and create Makefiles. |
2 | # Generated by GNU Autoconf 2.60 for pam-krb5 2.2. | |
2 | # Generated by GNU Autoconf 2.60 for pam-krb5 2.3. | |
3 | 3 | # |
4 | 4 | # Report bugs to <rra@stanford.edu>. |
5 | 5 | # |
558 | 558 | # Identity of this package. |
559 | 559 | PACKAGE_NAME='pam-krb5' |
560 | 560 | PACKAGE_TARNAME='pam-krb5' |
561 | PACKAGE_VERSION='2.2' | |
562 | PACKAGE_STRING='pam-krb5 2.2' | |
561 | PACKAGE_VERSION='2.3' | |
562 | PACKAGE_STRING='pam-krb5 2.3' | |
563 | 563 | PACKAGE_BUGREPORT='rra@stanford.edu' |
564 | 564 | |
565 | 565 | # Factoring default headers for most tests. |
1172 | 1172 | # Omit some internal or obsolete options to make the list less imposing. |
1173 | 1173 | # This message is too long to be a string in the A/UX 3.1 sh. |
1174 | 1174 | cat <<_ACEOF |
1175 | \`configure' configures pam-krb5 2.2 to adapt to many kinds of systems. | |
1175 | \`configure' configures pam-krb5 2.3 to adapt to many kinds of systems. | |
1176 | 1176 | |
1177 | 1177 | Usage: $0 [OPTION]... [VAR=VALUE]... |
1178 | 1178 | |
1237 | 1237 | |
1238 | 1238 | if test -n "$ac_init_help"; then |
1239 | 1239 | case $ac_init_help in |
1240 | short | recursive ) echo "Configuration of pam-krb5 2.2:";; | |
1240 | short | recursive ) echo "Configuration of pam-krb5 2.3:";; | |
1241 | 1241 | esac |
1242 | 1242 | cat <<\_ACEOF |
1243 | 1243 | |
1326 | 1326 | test -n "$ac_init_help" && exit $ac_status |
1327 | 1327 | if $ac_init_version; then |
1328 | 1328 | cat <<\_ACEOF |
1329 | pam-krb5 configure 2.2 | |
1329 | pam-krb5 configure 2.3 | |
1330 | 1330 | generated by GNU Autoconf 2.60 |
1331 | 1331 | |
1332 | 1332 | Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, |
1340 | 1340 | This file contains any messages produced by compilers while |
1341 | 1341 | running configure, to aid debugging if configure makes a mistake. |
1342 | 1342 | |
1343 | It was created by pam-krb5 $as_me 2.2, which was | |
1343 | It was created by pam-krb5 $as_me 2.3, which was | |
1344 | 1344 | generated by GNU Autoconf 2.60. Invocation command line was |
1345 | 1345 | |
1346 | 1346 | $ $0 $@ |
5731 | 5731 | # report actual input values of CONFIG_FILES etc. instead of their |
5732 | 5732 | # values after options handling. |
5733 | 5733 | ac_log=" |
5734 | This file was extended by pam-krb5 $as_me 2.2, which was | |
5734 | This file was extended by pam-krb5 $as_me 2.3, which was | |
5735 | 5735 | generated by GNU Autoconf 2.60. Invocation command line was |
5736 | 5736 | |
5737 | 5737 | CONFIG_FILES = $CONFIG_FILES |
5780 | 5780 | _ACEOF |
5781 | 5781 | cat >>$CONFIG_STATUS <<_ACEOF |
5782 | 5782 | ac_cs_version="\\ |
5783 | pam-krb5 config.status 2.2 | |
5783 | pam-krb5 config.status 2.3 | |
5784 | 5784 | configured by $0, generated by GNU Autoconf 2.60, |
5785 | 5785 | with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" |
5786 | 5786 |
0 | 0 | dnl Process this file with Autoconf to produce a configure script. |
1 | 1 | |
2 | 2 | AC_PREREQ(2.57) |
3 | AC_INIT([pam-krb5], [2.2], [rra@stanford.edu]) | |
3 | AC_INIT([pam-krb5], [2.3], [rra@stanford.edu]) | |
4 | 4 | |
5 | 5 | m4_include([m4/krb5.m4]) |
6 | 6 |
8 | 8 | |
9 | 9 | #include "config.h" |
10 | 10 | |
11 | #include <security/pam_appl.h> | |
11 | 12 | #include <security/pam_modules.h> |
12 | 13 | #include <stdlib.h> |
13 | 14 | #include <string.h> |
14 | 15 | |
15 | 16 | #include "pam_krb5.h" |
17 | ||
18 | /* Solaris doesn't have these. */ | |
19 | #ifndef PAM_CONV_AGAIN | |
20 | # define PAM_CONV_AGAIN 0 | |
21 | # define PAM_INCOMPLETE PAM_SERVICE_ERR | |
22 | #endif | |
16 | 23 | |
17 | 24 | /* |
18 | 25 | * Create a new context and populate it with the user and service from PAM and |
99 | 99 | free(args->renew_lifetime); |
100 | 100 | args->renew_lifetime = NULL; |
101 | 101 | } |
102 | krb5_appdefault_boolean(c, "pam", args->realm_data, | |
103 | "retain_after_close", 0, &args->retain); | |
102 | 104 | krb5_appdefault_boolean(c, "pam", args->realm_data, "search_k5login", |
103 | 105 | 0, &args->search_k5login); |
104 | 106 | if (local_context) |
141 | 143 | free(args->renew_lifetime); |
142 | 144 | args->renew_lifetime = strdup(&argv[i][strlen("renew_lifetime=")]); |
143 | 145 | } |
146 | else if (strcmp(argv[i], "retain_after_close") == 0) | |
147 | args->retain = 1; | |
144 | 148 | else if (strcmp(argv[i], "search_k5login") == 0) |
145 | 149 | args->search_k5login = 1; |
146 | 150 | else if (strcmp(argv[i], "try_first_pass") == 0) |
128 | 128 | .\" ======================================================================== |
129 | 129 | .\" |
130 | 130 | .IX Title "PAM_KRB5 5" |
131 | .TH PAM_KRB5 5 "2006-08-28" "2.2" "PAM Modules" | |
131 | .TH PAM_KRB5 5 "2006-09-03" "2.3" "PAM Modules" | |
132 | 132 | .SH "NAME" |
133 | 133 | pam_krb5 \- Kerberos v5 PAM module |
134 | 134 | .SH "SYNOPSIS" |
395 | 395 | .Sp |
396 | 396 | This option can be set in \fIkrb5.conf\fR and is only applicable to the auth |
397 | 397 | group. |
398 | .IP "retain_after_close" 4 | |
399 | .IX Item "retain_after_close" | |
400 | Normally, the user's ticket cache is destroyed when either \fIpam_end()\fR or | |
401 | \&\fIpam_close_session()\fR is called by the authenticating application so that | |
402 | ticket caches aren't left behind after the user logs out. In some cases, | |
403 | however, this isn't desireable. (On Solaris 8, for instance, the default | |
404 | behavior means login will destroy the ticket cache before running the | |
405 | user's shell.) If this option is set, the \s-1PAM\s0 module will never destroy | |
406 | the user's ticket cache. If you set this, you may want to call | |
407 | \&\fBkdestroy\fR in the shell's logout configuration or run a temporary file | |
408 | removal program to avoid accumulating hundreds of ticket caches in | |
409 | \&\fI/tmp\fR. | |
410 | .Sp | |
411 | This option can be set in \fIkrb5.conf\fR and is only applicable to the auth | |
412 | and session groups. | |
398 | 413 | .IP "search_k5login" 4 |
399 | 414 | .IX Item "search_k5login" |
400 | 415 | Normally, the Kerberos implementation of pam_authenticate attempts to |
9 | 9 | #include "config.h" |
10 | 10 | |
11 | 11 | #include <krb5.h> |
12 | #include <security/pam_appl.h> | |
12 | 13 | #include <security/pam_modules.h> |
13 | 14 | #include <stdarg.h> |
14 | 15 | |
27 | 28 | int no_ccache; /* Don't create a ticket cache. */ |
28 | 29 | char *realm; /* Default realm. */ |
29 | 30 | char *renew_lifetime; /* Renewable lifetime of credentials. */ |
31 | int retain; /* Don't destroy the cache on session end. */ | |
30 | 32 | int search_k5login; /* Try password with each line of .k5login. */ |
31 | 33 | int try_first_pass; /* Try the previously entered password. */ |
32 | 34 | int use_authtok; /* Require a previous password be used. */ |
283 | 283 | |
284 | 284 | This option can be set in F<krb5.conf> and is only applicable to the auth |
285 | 285 | group. |
286 | ||
287 | =item retain_after_close | |
288 | ||
289 | Normally, the user's ticket cache is destroyed when either pam_end() or | |
290 | pam_close_session() is called by the authenticating application so that | |
291 | ticket caches aren't left behind after the user logs out. In some cases, | |
292 | however, this isn't desireable. (On Solaris 8, for instance, the default | |
293 | behavior means login will destroy the ticket cache before running the | |
294 | user's shell.) If this option is set, the PAM module will never destroy | |
295 | the user's ticket cache. If you set this, you may want to call | |
296 | B<kdestroy> in the shell's logout configuration or run a temporary file | |
297 | removal program to avoid accumulating hundreds of ticket caches in | |
298 | F</tmp>. | |
299 | ||
300 | This option can be set in F<krb5.conf> and is only applicable to the auth | |
301 | and session groups. | |
286 | 302 | |
287 | 303 | =item search_k5login |
288 | 304 |
9 | 9 | |
10 | 10 | #include "config.h" |
11 | 11 | |
12 | #include <security/pam_appl.h> | |
12 | 13 | #include <security/pam_modules.h> |
13 | 14 | |
14 | 15 | #include "pam_krb5.h" |
119 | 119 | if (pamret != PAM_SUCCESS) |
120 | 120 | goto done; |
121 | 121 | |
122 | /* | |
123 | * Check .k5login, and if everything is fine, tell pam_sm_setcred where | |
124 | * the ticket cache is. | |
125 | */ | |
122 | /* Check .k5login. */ | |
126 | 123 | pamret = pamk5_validate_auth(ctx, args); |
127 | 124 | if (pamret != PAM_SUCCESS) |
128 | 125 | goto done; |
230 | 227 | |
231 | 228 | /* |
232 | 229 | * Create a new context for a session if we've lost the context created during |
233 | * authentication (such as when running under OpenSSH. | |
230 | * authentication (such as when running under OpenSSH). | |
234 | 231 | */ |
235 | 232 | static int |
236 | 233 | create_session_context(struct pam_args *args, pam_handle_t *pamh, |
507 | 504 | ctx->cache = cache; |
508 | 505 | cache = NULL; |
509 | 506 | ctx->initialized = 1; |
507 | if (args->retain) | |
508 | ctx->dont_destroy_cache = 1; | |
510 | 509 | |
511 | 510 | done: |
512 | 511 | if (cache != NULL) |
26 | 26 | #include <string.h> |
27 | 27 | |
28 | 28 | #include "pam_krb5.h" |
29 | ||
30 | #ifndef PAM_AUTHTOK_RECOVER_ERR | |
31 | # define PAM_AUTHTOK_RECOVER_ERR PAM_AUTHTOK_ERR | |
32 | #endif | |
29 | 33 | |
30 | 34 | |
31 | 35 | /* |
17 | 17 | |
18 | 18 | #include "config.h" |
19 | 19 | |
20 | #include <security/pam_appl.h> | |
20 | 21 | #include <security/pam_modules.h> |
21 | 22 | |
22 | 23 | #include "pam_krb5.h" |
7 | 7 | |
8 | 8 | #include <errno.h> |
9 | 9 | #include <krb5.h> |
10 | #include <security/pam_appl.h> | |
10 | 11 | #include <security/pam_modules.h> |
11 | 12 | #include <stdio.h> |
12 | 13 | #include <stdlib.h> |
50 | 51 | int pam_prompts = num_prompts; |
51 | 52 | int pamret, i; |
52 | 53 | int retval = KRB5KRB_ERR_GENERIC; |
53 | struct pam_message *msg; | |
54 | struct pam_message **msg; | |
54 | 55 | struct pam_response *resp = NULL; |
55 | 56 | struct pam_conv *conv; |
56 | 57 | pam_handle_t *pamh = (pam_handle_t *) data; |
66 | 67 | if (banner != NULL) |
67 | 68 | pam_prompts++; |
68 | 69 | |
69 | /* Allocate memory to copy all of the prompts into a pam_message. */ | |
70 | msg = calloc(sizeof(struct pam_message) * pam_prompts, 1); | |
70 | /* | |
71 | * Allocate memory to copy all of the prompts into a pam_message. | |
72 | * | |
73 | * Linux PAM and Solaris PAM expect different things here. Solaris PAM | |
74 | * expects to receive a pointer to a pointer to an array of pam_message | |
75 | * structs. Linux PAM expects to receive a pointer to an array of | |
76 | * pointers to pam_message structs. In order for the module to work with | |
77 | * either PAM implementation, we need to set up a structure that is valid | |
78 | * either way you look at it. | |
79 | * | |
80 | * We do this by making msg point to the array of struct pam_message | |
81 | * pointers (what Linux PAM expects), and then make the first one of those | |
82 | * pointers point to the array of pam_message structs. Solaris will then | |
83 | * be happy, looking at only the first element of the outer array and | |
84 | * finding it pointing to the inner array. Then, for Linux, we point the | |
85 | * other elements of the outer array to the storage allocated in the inner | |
86 | * array. | |
87 | * | |
88 | * All this also means we have to be careful how we free the resulting | |
89 | * structure since it's double-linked in a subtle way. Thankfully, we get | |
90 | * to free it ourselves. | |
91 | */ | |
92 | msg = calloc(pam_prompts, sizeof(struct pam_message *)); | |
71 | 93 | if (msg == NULL) |
72 | 94 | return ENOMEM; |
95 | *msg = calloc(pam_prompts, sizeof(struct pam_message)); | |
96 | if (*msg == NULL) { | |
97 | free(msg); | |
98 | return ENOMEM; | |
99 | } | |
100 | for (i = 1; i < pam_prompts; i++) | |
101 | msg[i] = msg[0] + i; | |
73 | 102 | |
74 | 103 | /* From this point on, pam_prompts is an index into msg. */ |
75 | 104 | pam_prompts = 0; |
76 | 105 | if (name != NULL) { |
77 | msg[pam_prompts].msg = malloc(strlen(name) + 1); | |
78 | if (msg[pam_prompts].msg == NULL) | |
106 | msg[pam_prompts]->msg = malloc(strlen(name) + 1); | |
107 | if (msg[pam_prompts]->msg == NULL) | |
79 | 108 | goto cleanup; |
80 | strcpy((char *) msg[pam_prompts].msg, name); | |
81 | msg[pam_prompts].msg_style = PAM_TEXT_INFO; | |
109 | strcpy((char *) msg[pam_prompts]->msg, name); | |
110 | msg[pam_prompts]->msg_style = PAM_TEXT_INFO; | |
82 | 111 | pam_prompts++; |
83 | 112 | } |
84 | 113 | if (banner != NULL) { |
85 | msg[pam_prompts].msg = malloc(strlen(banner) + 1); | |
86 | if (msg[pam_prompts].msg == NULL) | |
114 | msg[pam_prompts]->msg = malloc(strlen(banner) + 1); | |
115 | if (msg[pam_prompts]->msg == NULL) | |
87 | 116 | goto cleanup; |
88 | strcpy((char *) msg[pam_prompts].msg, banner); | |
89 | msg[pam_prompts].msg_style = PAM_TEXT_INFO; | |
117 | strcpy((char *) msg[pam_prompts]->msg, banner); | |
118 | msg[pam_prompts]->msg_style = PAM_TEXT_INFO; | |
90 | 119 | pam_prompts++; |
91 | 120 | } |
92 | 121 | for (i = 0; i < num_prompts; i++) { |
93 | msg[pam_prompts].msg = malloc(strlen(prompts[i].prompt) + 3); | |
94 | if (msg[pam_prompts].msg == NULL) | |
122 | msg[pam_prompts]->msg = malloc(strlen(prompts[i].prompt) + 3); | |
123 | if (msg[pam_prompts]->msg == NULL) | |
95 | 124 | goto cleanup; |
96 | sprintf((char *) msg[pam_prompts].msg, "%s: ", prompts[i].prompt); | |
97 | msg[pam_prompts].msg_style = prompts[i].hidden ? PAM_PROMPT_ECHO_OFF | |
98 | : PAM_PROMPT_ECHO_ON; | |
125 | sprintf((char *) msg[pam_prompts]->msg, "%s: ", prompts[i].prompt); | |
126 | msg[pam_prompts]->msg_style = prompts[i].hidden ? PAM_PROMPT_ECHO_OFF | |
127 | : PAM_PROMPT_ECHO_ON; | |
99 | 128 | pam_prompts++; |
100 | 129 | } |
101 | 130 | |
102 | 131 | /* Call into the application conversation function. */ |
103 | pamret = conv->conv(pam_prompts, (const struct pam_message **) &msg, | |
132 | pamret = conv->conv(pam_prompts, (const struct pam_message **) msg, | |
104 | 133 | &resp, conv->appdata_ptr); |
105 | 134 | if (pamret != 0) |
106 | 135 | goto cleanup; |
138 | 167 | |
139 | 168 | cleanup: |
140 | 169 | for (i = 0; i < pam_prompts; i++) { |
141 | if (msg[i].msg != NULL) | |
142 | free((char *) msg[i].msg); | |
170 | if (msg[i]->msg != NULL) | |
171 | free((char *) msg[i]->msg); | |
143 | 172 | } |
173 | free(*msg); | |
144 | 174 | free(msg); |
145 | 175 | |
146 | 176 | /* |
148 | 178 | * It's not clear if I should free it, or if the application has to. |
149 | 179 | * Therefore most (all?) apps won't free it, and I can't either, as I am |
150 | 180 | * not sure it was malloced. All PAM implementations I've seen leak |
151 | * memory here. Not so bad, IFF you fork/exec for each PAM authentication | |
181 | * memory here. Not so bad iff you fork/exec for each PAM authentication | |
152 | 182 | * (as is typical). |
153 | 183 | */ |
154 | 184 | if (resp != NULL) |