Deleted Added
full compact
pam_get_authtok.c (95908) pam_get_authtok.c (96364)
1/*-
2 * Copyright (c) 2002 Networks Associates Technology, Inc.
3 * All rights reserved.
4 *
5 * This software was developed for the FreeBSD Project by ThinkSec AS and
6 * NAI Labs, the Security Research Division of Network Associates, Inc.
7 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
8 * DARPA CHATS research program.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * $P4: //depot/projects/openpam/lib/pam_get_authtok.c#17 $
35 */
36
37#include <sys/param.h>
38
39#include <stdlib.h>
1/*-
2 * Copyright (c) 2002 Networks Associates Technology, Inc.
3 * All rights reserved.
4 *
5 * This software was developed for the FreeBSD Project by ThinkSec AS and
6 * NAI Labs, the Security Research Division of Network Associates, Inc.
7 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
8 * DARPA CHATS research program.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of the author may not be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * $P4: //depot/projects/openpam/lib/pam_get_authtok.c#17 $
35 */
36
37#include <sys/param.h>
38
39#include <stdlib.h>
40#include <string.h>
40
41#include <security/pam_appl.h>
42#include <security/openpam.h>
43
44#include "openpam_impl.h"
45
46const char authtok_prompt[] = "Password:";
47const char oldauthtok_prompt[] = "Old Password:";
48const char newauthtok_prompt[] = "New Password:";
49
50/*
51 * OpenPAM extension
52 *
53 * Retrieve authentication token
54 */
55
56int
57pam_get_authtok(pam_handle_t *pamh,
58 int item,
59 const char **authtok,
60 const char *prompt)
61{
62 const void *oldauthtok;
63 const char *default_prompt;
64 char *resp, *resp2;
65 int pitem, r, style, twice;
66
67 if (pamh == NULL || authtok == NULL)
68 return (PAM_SYSTEM_ERR);
69
70 *authtok = NULL;
71 twice = 0;
72 switch (item) {
73 case PAM_AUTHTOK:
74 pitem = PAM_AUTHTOK_PROMPT;
75 default_prompt = authtok_prompt;
76 r = pam_get_item(pamh, PAM_OLDAUTHTOK, &oldauthtok);
77 if (r == PAM_SUCCESS && oldauthtok != NULL) {
78 default_prompt = newauthtok_prompt;
79 twice = 1;
80 }
81 break;
82 case PAM_OLDAUTHTOK:
83 pitem = PAM_OLDAUTHTOK_PROMPT;
84 default_prompt = oldauthtok_prompt;
85 twice = 0;
86 break;
87 default:
88 return (PAM_SYMBOL_ERR);
89 }
90
91 if (openpam_get_option(pamh, "try_first_pass") ||
92 openpam_get_option(pamh, "use_first_pass")) {
93 r = pam_get_item(pamh, item, (const void **)authtok);
94 if (r == PAM_SUCCESS && *authtok != NULL)
95 return (PAM_SUCCESS);
96 else if (openpam_get_option(pamh, "use_first_pass"))
97 return (r == PAM_SUCCESS ? PAM_AUTH_ERR : r);
98 }
99 if (prompt == NULL) {
100 r = pam_get_item(pamh, pitem, (const void **)&prompt);
101 if (r != PAM_SUCCESS || prompt == NULL)
102 prompt = default_prompt;
103 }
104 style = openpam_get_option(pamh, "echo_pass") ?
105 PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF;
106 r = pam_prompt(pamh, style, &resp, "%s", prompt);
107 if (r != PAM_SUCCESS)
108 return (r);
109 if (twice) {
110 r = pam_prompt(pamh, style, &resp2, "Retype %s", prompt);
111 if (r != PAM_SUCCESS) {
112 free(resp);
113 return (r);
114 }
115 if (strcmp(resp, resp2) != 0) {
116 free(resp);
117 resp = NULL;
118 }
119 free(resp2);
120 }
121 if (resp == NULL)
122 return (PAM_TRY_AGAIN);
123 r = pam_set_item(pamh, item, resp);
124 free(resp);
125 if (r != PAM_SUCCESS)
126 return (r);
127 return (pam_get_item(pamh, item, (const void **)authtok));
128}
129
130/*
131 * Error codes:
132 *
133 * =pam_get_item
134 * =pam_prompt
135 * =pam_set_item
136 * !PAM_SYMBOL_ERR
137 * PAM_TRY_AGAIN
138 */
139
140/**
141 * The =pam_get_authtok function returns the cached authentication token,
142 * or prompts the user if no token is currently cached. Either way, a
143 * pointer to the authentication token is stored in the location pointed
144 * to by the =authtok argument.
145 *
146 * The =item argument must have one of the following values:
147 *
148 * =PAM_AUTHTOK:
149 * Returns the current authentication token, or the new token
150 * when changing authentication tokens.
151 * =PAM_OLDAUTHTOK:
152 * Returns the previous authentication token when changing
153 * authentication tokens.
154 *
155 * The =prompt argument specifies a prompt to use if no token is cached.
156 * If it is =NULL, the =PAM_AUTHTOK_PROMPT or =PAM_OLDAUTHTOK_PROMPT item,
157 * as appropriate, will be used. If that item is also =NULL, a hardcoded
158 * default prompt will be used.
159 *
160 * If =item is set to =PAM_AUTHTOK and there is a non-null =PAM_OLDAUTHTOK
161 * item, =pam_get_authtok will ask the user to confirm the new token by
162 * retyping it. If there is a mismatch, =pam_get_authtok will return
163 * =PAM_TRY_AGAIN.
164 *
165 * >pam_get_item
166 * >pam_get_user
167 */
41
42#include <security/pam_appl.h>
43#include <security/openpam.h>
44
45#include "openpam_impl.h"
46
47const char authtok_prompt[] = "Password:";
48const char oldauthtok_prompt[] = "Old Password:";
49const char newauthtok_prompt[] = "New Password:";
50
51/*
52 * OpenPAM extension
53 *
54 * Retrieve authentication token
55 */
56
57int
58pam_get_authtok(pam_handle_t *pamh,
59 int item,
60 const char **authtok,
61 const char *prompt)
62{
63 const void *oldauthtok;
64 const char *default_prompt;
65 char *resp, *resp2;
66 int pitem, r, style, twice;
67
68 if (pamh == NULL || authtok == NULL)
69 return (PAM_SYSTEM_ERR);
70
71 *authtok = NULL;
72 twice = 0;
73 switch (item) {
74 case PAM_AUTHTOK:
75 pitem = PAM_AUTHTOK_PROMPT;
76 default_prompt = authtok_prompt;
77 r = pam_get_item(pamh, PAM_OLDAUTHTOK, &oldauthtok);
78 if (r == PAM_SUCCESS && oldauthtok != NULL) {
79 default_prompt = newauthtok_prompt;
80 twice = 1;
81 }
82 break;
83 case PAM_OLDAUTHTOK:
84 pitem = PAM_OLDAUTHTOK_PROMPT;
85 default_prompt = oldauthtok_prompt;
86 twice = 0;
87 break;
88 default:
89 return (PAM_SYMBOL_ERR);
90 }
91
92 if (openpam_get_option(pamh, "try_first_pass") ||
93 openpam_get_option(pamh, "use_first_pass")) {
94 r = pam_get_item(pamh, item, (const void **)authtok);
95 if (r == PAM_SUCCESS && *authtok != NULL)
96 return (PAM_SUCCESS);
97 else if (openpam_get_option(pamh, "use_first_pass"))
98 return (r == PAM_SUCCESS ? PAM_AUTH_ERR : r);
99 }
100 if (prompt == NULL) {
101 r = pam_get_item(pamh, pitem, (const void **)&prompt);
102 if (r != PAM_SUCCESS || prompt == NULL)
103 prompt = default_prompt;
104 }
105 style = openpam_get_option(pamh, "echo_pass") ?
106 PAM_PROMPT_ECHO_ON : PAM_PROMPT_ECHO_OFF;
107 r = pam_prompt(pamh, style, &resp, "%s", prompt);
108 if (r != PAM_SUCCESS)
109 return (r);
110 if (twice) {
111 r = pam_prompt(pamh, style, &resp2, "Retype %s", prompt);
112 if (r != PAM_SUCCESS) {
113 free(resp);
114 return (r);
115 }
116 if (strcmp(resp, resp2) != 0) {
117 free(resp);
118 resp = NULL;
119 }
120 free(resp2);
121 }
122 if (resp == NULL)
123 return (PAM_TRY_AGAIN);
124 r = pam_set_item(pamh, item, resp);
125 free(resp);
126 if (r != PAM_SUCCESS)
127 return (r);
128 return (pam_get_item(pamh, item, (const void **)authtok));
129}
130
131/*
132 * Error codes:
133 *
134 * =pam_get_item
135 * =pam_prompt
136 * =pam_set_item
137 * !PAM_SYMBOL_ERR
138 * PAM_TRY_AGAIN
139 */
140
141/**
142 * The =pam_get_authtok function returns the cached authentication token,
143 * or prompts the user if no token is currently cached. Either way, a
144 * pointer to the authentication token is stored in the location pointed
145 * to by the =authtok argument.
146 *
147 * The =item argument must have one of the following values:
148 *
149 * =PAM_AUTHTOK:
150 * Returns the current authentication token, or the new token
151 * when changing authentication tokens.
152 * =PAM_OLDAUTHTOK:
153 * Returns the previous authentication token when changing
154 * authentication tokens.
155 *
156 * The =prompt argument specifies a prompt to use if no token is cached.
157 * If it is =NULL, the =PAM_AUTHTOK_PROMPT or =PAM_OLDAUTHTOK_PROMPT item,
158 * as appropriate, will be used. If that item is also =NULL, a hardcoded
159 * default prompt will be used.
160 *
161 * If =item is set to =PAM_AUTHTOK and there is a non-null =PAM_OLDAUTHTOK
162 * item, =pam_get_authtok will ask the user to confirm the new token by
163 * retyping it. If there is a mismatch, =pam_get_authtok will return
164 * =PAM_TRY_AGAIN.
165 *
166 * >pam_get_item
167 * >pam_get_user
168 */