| @@ -1,351 +1,391 @@ | | | @@ -1,351 +1,391 @@ |
1 | /* $NetBSD: krb5_passwd.c,v 1.18 2009/04/18 09:04:34 mlelstv Exp $ */ | | 1 | /* $NetBSD: krb5_passwd.c,v 1.19 2011/04/24 21:16:43 elric Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2000, 2005 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2000, 2005 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Johan Danielsson; and by Jason R. Thorpe. | | 8 | * by Johan Danielsson; and by Jason R. Thorpe. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * | | 13 | * |
14 | * 1. Redistributions of source code must retain the above copyright | | 14 | * 1. Redistributions of source code must retain the above copyright |
15 | * notice, this list of conditions and the following disclaimer. | | 15 | * notice, this list of conditions and the following disclaimer. |
16 | * 2. Redistributions in binary form must reproduce the above copyright | | 16 | * 2. Redistributions in binary form must reproduce the above copyright |
17 | * notice, this list of conditions and the following disclaimer in the | | 17 | * notice, this list of conditions and the following disclaimer in the |
18 | * documentation and/or other materials provided with the distribution. | | 18 | * documentation and/or other materials provided with the distribution. |
19 | * | | 19 | * |
20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 20 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
30 | * POSSIBILITY OF SUCH DAMAGE. | | 30 | * POSSIBILITY OF SUCH DAMAGE. |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | /* uses the `Kerberos Change Password Protocol' */ | | 33 | /* uses the `Kerberos Change Password Protocol' */ |
34 | | | 34 | |
35 | #include <stdio.h> | | 35 | #include <stdio.h> |
36 | #include <stdlib.h> | | 36 | #include <stdlib.h> |
37 | #include <string.h> | | 37 | #include <string.h> |
38 | #include <err.h> | | 38 | #include <err.h> |
39 | #include <errno.h> | | 39 | #include <errno.h> |
40 | #include <pwd.h> | | 40 | #include <pwd.h> |
41 | #include <unistd.h> | | 41 | #include <unistd.h> |
42 | | | 42 | |
43 | #include <openssl/ui.h> | | 43 | #include <openssl/ui.h> |
44 | #include <krb5.h> | | 44 | #include <krb5.h> |
45 | | | 45 | |
46 | #include "extern.h" | | 46 | #include "extern.h" |
47 | | | 47 | |
48 | #ifdef USE_PAM | | 48 | #ifdef USE_PAM |
49 | | | 49 | |
50 | void | | 50 | void |
51 | pwkrb5_usage(const char *prefix) | | 51 | pwkrb5_usage(const char *prefix) |
52 | { | | 52 | { |
53 | | | 53 | |
54 | (void) fprintf(stderr, "%s %s [-d krb5 | -k] [principal]\n", | | 54 | (void) fprintf(stderr, "%s %s [-d krb5 | -k] [principal]\n", |
55 | prefix, getprogname()); | | 55 | prefix, getprogname()); |
56 | } | | 56 | } |
57 | | | 57 | |
58 | void | | 58 | void |
59 | pwkrb5_argv0_usage(const char *prefix) | | 59 | pwkrb5_argv0_usage(const char *prefix) |
60 | { | | 60 | { |
61 | | | 61 | |
62 | (void) fprintf(stderr, "%s %s [principal]\n", | | 62 | (void) fprintf(stderr, "%s %s [principal]\n", |
63 | prefix, getprogname()); | | 63 | prefix, getprogname()); |
64 | } | | 64 | } |
65 | | | 65 | |
66 | void | | 66 | void |
67 | pwkrb5_process(const char *username, int argc, char **argv) | | 67 | pwkrb5_process(const char *username, int argc, char **argv) |
68 | { | | 68 | { |
69 | krb5_context context; | | 69 | krb5_context context; |
70 | krb5_error_code ret; | | 70 | krb5_error_code ret; |
71 | krb5_get_init_creds_opt opt; | | 71 | krb5_get_init_creds_opt *opt; |
72 | krb5_principal principal; | | 72 | krb5_principal principal; |
73 | krb5_creds cred; | | 73 | krb5_creds cred; |
74 | int result_code; | | 74 | int result_code; |
75 | krb5_data result_code_string, result_string; | | 75 | krb5_data result_code_string, result_string; |
76 | char pwbuf[BUFSIZ]; | | 76 | char pwbuf[BUFSIZ]; |
77 | int ch; | | 77 | int ch; |
| | | 78 | const char *errtxt; |
78 | | | 79 | |
79 | while ((ch = getopt(argc, argv, "5ku:")) != -1) { | | 80 | while ((ch = getopt(argc, argv, "5ku:")) != -1) { |
80 | switch (ch) { | | 81 | switch (ch) { |
81 | case '5': | | 82 | case '5': |
82 | /* | | 83 | /* |
83 | * Compatibility option that historically | | 84 | * Compatibility option that historically |
84 | * specified to use Kerberos 5. Silently | | 85 | * specified to use Kerberos 5. Silently |
85 | * ignore it. | | 86 | * ignore it. |
86 | */ | | 87 | */ |
87 | break; | | 88 | break; |
88 | | | 89 | |
89 | case 'k': | | 90 | case 'k': |
90 | /* | | 91 | /* |
91 | * Absorb the -k that may have gotten us here. | | 92 | * Absorb the -k that may have gotten us here. |
92 | */ | | 93 | */ |
93 | break; | | 94 | break; |
94 | | | 95 | |
95 | case 'u': | | 96 | case 'u': |
96 | /* | | 97 | /* |
97 | * Historical option to specify principal. | | 98 | * Historical option to specify principal. |
98 | */ | | 99 | */ |
99 | username = optarg; | | 100 | username = optarg; |
100 | break; | | 101 | break; |
101 | | | 102 | |
102 | default: | | 103 | default: |
103 | usage(); | | 104 | usage(); |
104 | /* NOTREACHED */ | | 105 | /* NOTREACHED */ |
105 | } | | 106 | } |
106 | } | | 107 | } |
107 | | | 108 | |
108 | argc -= optind; | | 109 | argc -= optind; |
109 | argv += optind; | | 110 | argv += optind; |
110 | | | 111 | |
111 | switch (argc) { | | 112 | switch (argc) { |
112 | case 0: | | 113 | case 0: |
113 | /* username already provided */ | | 114 | /* username already provided */ |
114 | break; | | 115 | break; |
115 | case 1: | | 116 | case 1: |
116 | /* overrides -u <principal> */ | | 117 | /* overrides -u <principal> */ |
117 | username = argv[0]; | | 118 | username = argv[0]; |
118 | break; | | 119 | break; |
119 | default: | | 120 | default: |
120 | usage(); | | 121 | usage(); |
121 | /* NOTREACHED */ | | 122 | /* NOTREACHED */ |
122 | } | | 123 | } |
123 | | | 124 | |
124 | ret = krb5_init_context(&context); | | 125 | ret = krb5_init_context(&context); |
125 | if (ret != 0) { | | 126 | if (ret != 0) { |
126 | if (ret == ENXIO) | | 127 | if (ret == ENXIO) |
127 | errx(1, "Kerberos 5 not in use."); | | 128 | errx(1, "Kerberos 5 not in use."); |
128 | warnx("Unable to initialize Kerberos 5: %s", | | 129 | errx(1, "Unable to initialize Kerberos 5: %s", strerror(ret)); |
129 | krb5_get_err_text(context, ret)); | | | |
130 | goto bad; | | | |
131 | } | | 130 | } |
132 | | | 131 | |
133 | krb5_get_init_creds_opt_init(&opt); | | 132 | ret = krb5_get_init_creds_opt_alloc(context, &opt); |
| | | 133 | if (ret) { |
| | | 134 | errtxt = krb5_get_error_message(context, ret); |
| | | 135 | if (errtxt != NULL) { |
| | | 136 | warnx("failed to allocate opts: %s", errtxt); |
| | | 137 | krb5_free_error_message(context, errtxt); |
| | | 138 | } else { |
| | | 139 | warnx("failed to allocate opts: %d", ret); |
| | | 140 | } |
| | | 141 | goto bad; |
| | | 142 | } |
134 | | | 143 | |
135 | krb5_get_init_creds_opt_set_tkt_life(&opt, 300L); | | 144 | krb5_get_init_creds_opt_set_tkt_life(opt, 300L); |
136 | krb5_get_init_creds_opt_set_forwardable(&opt, FALSE); | | 145 | krb5_get_init_creds_opt_set_forwardable(opt, FALSE); |
137 | krb5_get_init_creds_opt_set_proxiable(&opt, FALSE); | | 146 | krb5_get_init_creds_opt_set_proxiable(opt, FALSE); |
138 | | | 147 | |
139 | ret = krb5_parse_name(context, username, &principal); | | 148 | ret = krb5_parse_name(context, username, &principal); |
140 | if (ret) { | | 149 | if (ret) { |
141 | warnx("failed to parse principal: %s", | | 150 | errtxt = krb5_get_error_message(context, ret); |
142 | krb5_get_err_text(context, ret)); | | 151 | if (errtxt != NULL) { |
| | | 152 | warnx("failed to parse principal: %s", errtxt); |
| | | 153 | krb5_free_error_message(context, errtxt); |
| | | 154 | } else { |
| | | 155 | warnx("failed to parse principal: %d", ret); |
| | | 156 | } |
143 | goto bad; | | 157 | goto bad; |
144 | } | | 158 | } |
145 | | | 159 | |
146 | ret = krb5_get_init_creds_password(context, | | 160 | ret = krb5_get_init_creds_password(context, |
147 | &cred, | | 161 | &cred, |
148 | principal, | | 162 | principal, |
149 | NULL, | | 163 | NULL, |
150 | krb5_prompter_posix, | | 164 | krb5_prompter_posix, |
151 | NULL, | | 165 | NULL, |
152 | 0L, | | 166 | 0L, |
153 | "kadmin/changepw", | | 167 | "kadmin/changepw", |
154 | &opt); | | 168 | opt); |
155 | | | 169 | |
156 | | | 170 | |
157 | switch (ret) { | | 171 | switch (ret) { |
158 | case 0: | | 172 | case 0: |
159 | break; | | 173 | break; |
160 | | | 174 | |
161 | case KRB5_LIBOS_PWDINTR : | | 175 | case KRB5_LIBOS_PWDINTR : |
162 | /* XXX */ | | 176 | /* XXX */ |
163 | goto bad; | | 177 | goto bad; |
164 | | | 178 | |
165 | case KRB5KRB_AP_ERR_BAD_INTEGRITY : | | 179 | case KRB5KRB_AP_ERR_BAD_INTEGRITY : |
166 | case KRB5KRB_AP_ERR_MODIFIED : | | 180 | case KRB5KRB_AP_ERR_MODIFIED : |
167 | fprintf(stderr, "Password incorrect\n"); | | 181 | fprintf(stderr, "Password incorrect\n"); |
168 | goto bad; | | 182 | goto bad; |
169 | | | 183 | |
170 | default: | | 184 | default: |
171 | warnx("failed to get credentials: %s", | | 185 | errtxt = krb5_get_error_message(context, ret); |
172 | krb5_get_err_text(context, ret)); | | 186 | if (errtxt != NULL) { |
| | | 187 | warnx("failed to get credentials: %s", errtxt); |
| | | 188 | krb5_free_error_message(context, errtxt); |
| | | 189 | } else { |
| | | 190 | warnx("failed to get credentials: %d", ret); |
| | | 191 | } |
173 | goto bad; | | 192 | goto bad; |
174 | } | | 193 | } |
175 | | | 194 | |
176 | krb5_data_zero(&result_code_string); | | 195 | krb5_data_zero(&result_code_string); |
177 | krb5_data_zero(&result_string); | | 196 | krb5_data_zero(&result_string); |
178 | | | 197 | |
179 | /* XXX use getpass? It has a broken interface. */ | | 198 | /* XXX use getpass? It has a broken interface. */ |
180 | if (UI_UTIL_read_pw_string(pwbuf, sizeof(pwbuf), | | 199 | if (UI_UTIL_read_pw_string(pwbuf, sizeof(pwbuf), |
181 | "New password: ", 1) != 0) | | 200 | "New password: ", 1) != 0) |
182 | goto bad; | | 201 | goto bad; |
183 | | | 202 | |
184 | ret = krb5_set_password(context, &cred, pwbuf, NULL, | | 203 | ret = krb5_set_password(context, &cred, pwbuf, NULL, |
185 | &result_code, | | 204 | &result_code, |
186 | &result_code_string, | | 205 | &result_code_string, |
187 | &result_string); | | 206 | &result_string); |
188 | if (ret) { | | 207 | if (ret) { |
189 | warnx("unable to set password: %s", | | 208 | errtxt = krb5_get_error_message(context, ret); |
190 | krb5_get_err_text(context, ret)); | | 209 | if (errtxt != NULL) { |
| | | 210 | warnx("unable to set password: %s", errtxt); |
| | | 211 | krb5_free_error_message(context, errtxt); |
| | | 212 | } else { |
| | | 213 | warnx("unable to set password: %d", ret); |
| | | 214 | } |
191 | goto bad; | | 215 | goto bad; |
192 | } | | 216 | } |
193 | | | 217 | |
194 | printf("%s%s%.*s\n", | | 218 | printf("%s%s%.*s\n", |
195 | krb5_passwd_result_to_string(context, result_code), | | 219 | krb5_passwd_result_to_string(context, result_code), |
196 | result_string.length > 0 ? " : " : "", | | 220 | result_string.length > 0 ? " : " : "", |
197 | (int)result_string.length, | | 221 | (int)result_string.length, |
198 | result_string.length > 0 ? (char *)result_string.data : ""); | | 222 | result_string.length > 0 ? (char *)result_string.data : ""); |
199 | | | 223 | |
200 | krb5_data_free(&result_code_string); | | 224 | krb5_data_free(&result_code_string); |
201 | krb5_data_free(&result_string); | | 225 | krb5_data_free(&result_string); |
202 | | | 226 | |
203 | krb5_free_cred_contents(context, &cred); | | 227 | krb5_free_cred_contents(context, &cred); |
204 | krb5_free_context(context); | | 228 | krb5_free_context(context); |
205 | if (result_code) | | 229 | if (result_code) |
206 | exit(1); | | 230 | exit(1); |
207 | return; | | 231 | return; |
208 | | | 232 | |
209 | bad: | | 233 | bad: |
210 | krb5_free_context(context); | | 234 | krb5_free_context(context); |
211 | exit(1); | | 235 | exit(1); |
212 | } | | 236 | } |
213 | | | 237 | |
214 | #else /* ! USE_PAM */ | | 238 | #else /* ! USE_PAM */ |
215 | | | 239 | |
216 | static krb5_context defcontext; | | 240 | static krb5_context defcontext; |
217 | static krb5_principal defprinc; | | 241 | static krb5_principal defprinc; |
218 | static int kusage = PW_USE; | | 242 | static int kusage = PW_USE; |
219 | | | 243 | |
220 | int | | 244 | int |
221 | krb5_init(const char *progname) | | 245 | krb5_init(const char *progname) |
222 | { | | 246 | { |
223 | return krb5_init_context(&defcontext); | | 247 | return krb5_init_context(&defcontext); |
224 | } | | 248 | } |
225 | | | 249 | |
226 | int | | 250 | int |
227 | krb5_arg (char ch, const char *opt) | | 251 | krb5_arg (char ch, const char *opt) |
228 | { | | 252 | { |
229 | krb5_error_code ret; | | 253 | krb5_error_code ret; |
230 | switch(ch) { | | 254 | switch(ch) { |
231 | case '5': | | 255 | case '5': |
232 | case 'k': | | 256 | case 'k': |
233 | kusage = PW_USE_FORCE; | | 257 | kusage = PW_USE_FORCE; |
234 | return 1; | | 258 | return 1; |
235 | case 'u': | | 259 | case 'u': |
236 | ret = krb5_parse_name(defcontext, opt, &defprinc); | | 260 | ret = krb5_parse_name(defcontext, opt, &defprinc); |
237 | if(ret) { | | 261 | if(ret) { |
238 | krb5_warn(defcontext, ret, "%s", opt); | | 262 | krb5_warn(defcontext, ret, "%s", opt); |
239 | return 0; | | 263 | return 0; |
240 | } | | 264 | } |
241 | return 1; | | 265 | return 1; |
242 | } | | 266 | } |
243 | return 0; | | 267 | return 0; |
244 | } | | 268 | } |
245 | | | 269 | |
246 | int | | 270 | int |
247 | krb5_arg_end(void) | | 271 | krb5_arg_end(void) |
248 | { | | 272 | { |
249 | return kusage; | | 273 | return kusage; |
250 | } | | 274 | } |
251 | | | 275 | |
252 | void | | 276 | void |
253 | krb5_end(void) | | 277 | krb5_end(void) |
254 | { | | 278 | { |
255 | if (defcontext == NULL) | | 279 | if (defcontext == NULL) |
256 | return; | | 280 | return; |
257 | if(defprinc) | | 281 | if(defprinc) |
258 | krb5_free_principal(defcontext, defprinc); | | 282 | krb5_free_principal(defcontext, defprinc); |
259 | krb5_free_context(defcontext); | | 283 | krb5_free_context(defcontext); |
260 | } | | 284 | } |
261 | | | 285 | |
262 | | | 286 | |
263 | int | | 287 | int |
264 | krb5_chpw(const char *username) | | 288 | krb5_chpw(const char *username) |
265 | { | | 289 | { |
266 | krb5_error_code ret; | | 290 | krb5_error_code ret; |
267 | krb5_context context; | | 291 | krb5_context context; |
268 | krb5_principal principal; | | 292 | krb5_principal principal; |
269 | krb5_get_init_creds_opt opt; | | 293 | krb5_get_init_creds_opt opt; |
270 | krb5_creds cred; | | 294 | krb5_creds cred; |
271 | int result_code; | | 295 | int result_code; |
272 | krb5_data result_code_string, result_string; | | 296 | krb5_data result_code_string, result_string; |
273 | char pwbuf[BUFSIZ]; | | 297 | char pwbuf[BUFSIZ]; |
| | | 298 | const char *errtxt; |
274 | | | 299 | |
275 | ret = krb5_init_context (&context); | | 300 | ret = krb5_init_context (&context); |
276 | if (ret) { | | 301 | if (ret) { |
277 | warnx("failed kerberos initialisation: %s", | | 302 | errtxt = krb5_get_error_message(context, ret); |
278 | krb5_get_err_text(context, ret)); | | 303 | if (errtxt != NULL) { |
| | | 304 | warnx("failed kerberos initialisation: %s", errtxt); |
| | | 305 | krb5_free_error_message(context, errtxt); |
| | | 306 | } else { |
| | | 307 | warnx("failed kerberos initialisation: %d", ret); |
| | | 308 | } |
279 | return 1; | | 309 | return 1; |
280 | } | | 310 | } |
281 | | | 311 | |
282 | krb5_get_init_creds_opt_init (&opt); | | 312 | krb5_get_init_creds_opt_init (&opt); |
283 | | | 313 | |
284 | krb5_get_init_creds_opt_set_tkt_life (&opt, 300); | | 314 | krb5_get_init_creds_opt_set_tkt_life (&opt, 300); |
285 | krb5_get_init_creds_opt_set_forwardable (&opt, FALSE); | | 315 | krb5_get_init_creds_opt_set_forwardable (&opt, FALSE); |
286 | krb5_get_init_creds_opt_set_proxiable (&opt, FALSE); | | 316 | krb5_get_init_creds_opt_set_proxiable (&opt, FALSE); |
287 | | | 317 | |
288 | if(username != NULL) { | | 318 | if(username != NULL) { |
289 | ret = krb5_parse_name (context, username, &principal); | | 319 | ret = krb5_parse_name (context, username, &principal); |
290 | if (ret) { | | 320 | if (ret) { |
291 | warnx("failed to parse principal: %s", | | 321 | errtxt = krb5_get_error_message(context, ret); |
292 | krb5_get_err_text(context, ret)); | | 322 | if (errtxt != NULL) { |
| | | 323 | warnx("failed to parse principal: %s", errtxt); |
| | | 324 | krb5_free_error_message(context, errtxt); |
| | | 325 | } else { |
| | | 326 | warnx("failed to parse principal: %d", ret); |
| | | 327 | } |
293 | return 1; | | 328 | return 1; |
294 | } | | 329 | } |
295 | } else | | 330 | } else |
296 | principal = defprinc; | | 331 | principal = defprinc; |
297 | | | 332 | |
298 | ret = krb5_get_init_creds_password (context, | | 333 | ret = krb5_get_init_creds_password (context, |
299 | &cred, | | 334 | &cred, |
300 | principal, | | 335 | principal, |
301 | NULL, | | 336 | NULL, |
302 | krb5_prompter_posix, | | 337 | krb5_prompter_posix, |
303 | NULL, | | 338 | NULL, |
304 | 0, | | 339 | 0, |
305 | "kadmin/changepw", | | 340 | "kadmin/changepw", |
306 | &opt); | | 341 | &opt); |
307 | | | 342 | |
308 | switch (ret) { | | 343 | switch (ret) { |
309 | case 0: | | 344 | case 0: |
310 | break; | | 345 | break; |
311 | case KRB5_LIBOS_PWDINTR : | | 346 | case KRB5_LIBOS_PWDINTR : |
312 | /* XXX */ | | 347 | /* XXX */ |
313 | return 1; | | 348 | return 1; |
314 | case KRB5KRB_AP_ERR_BAD_INTEGRITY : | | 349 | case KRB5KRB_AP_ERR_BAD_INTEGRITY : |
315 | case KRB5KRB_AP_ERR_MODIFIED : | | 350 | case KRB5KRB_AP_ERR_MODIFIED : |
316 | fprintf(stderr, "Password incorrect\n"); | | 351 | fprintf(stderr, "Password incorrect\n"); |
317 | return 1; | | 352 | return 1; |
318 | break; | | 353 | break; |
319 | default: | | 354 | default: |
320 | warnx("failed to get credentials: %s", | | 355 | errtxt = krb5_get_error_message(context, ret); |
321 | krb5_get_err_text(context, ret)); | | 356 | if (errtxt != NULL) { |
| | | 357 | warnx("failed to get credentials: %s", errtxt); |
| | | 358 | krb5_free_error_message(context, errtxt); |
| | | 359 | } else { |
| | | 360 | warnx("failed to get credentials: %d", ret); |
| | | 361 | } |
322 | return 1; | | 362 | return 1; |
323 | } | | 363 | } |
324 | krb5_data_zero (&result_code_string); | | 364 | krb5_data_zero (&result_code_string); |
325 | krb5_data_zero (&result_string); | | 365 | krb5_data_zero (&result_string); |
326 | | | 366 | |
327 | /* XXX use getpass? It has a broken interface. */ | | 367 | /* XXX use getpass? It has a broken interface. */ |
328 | if(UI_UTIL_read_pw_string(pwbuf, sizeof(pwbuf), "New password: ", 1) != 0) | | 368 | if(UI_UTIL_read_pw_string(pwbuf, sizeof(pwbuf), "New password: ", 1) != 0) |
329 | return 1; | | 369 | return 1; |
330 | | | 370 | |
331 | ret = krb5_set_password (context, &cred, pwbuf, NULL, | | 371 | ret = krb5_set_password (context, &cred, pwbuf, NULL, |
332 | &result_code, | | 372 | &result_code, |
333 | &result_code_string, | | 373 | &result_code_string, |
334 | &result_string); | | 374 | &result_string); |
335 | if (ret) | | 375 | if (ret) |
336 | krb5_err (context, 1, ret, "krb5_set_password"); | | 376 | krb5_err (context, 1, ret, "krb5_set_password"); |
337 | | | 377 | |
338 | printf ("%s%s%.*s\n", krb5_passwd_result_to_string(context, result_code), | | 378 | printf ("%s%s%.*s\n", krb5_passwd_result_to_string(context, result_code), |
339 | result_string.length > 0 ? " : " : "", | | 379 | result_string.length > 0 ? " : " : "", |
340 | (int)result_string.length, | | 380 | (int)result_string.length, |
341 | result_string.length > 0 ? (char *)result_string.data : ""); | | 381 | result_string.length > 0 ? (char *)result_string.data : ""); |
342 | | | 382 | |
343 | krb5_data_free (&result_code_string); | | 383 | krb5_data_free (&result_code_string); |
344 | krb5_data_free (&result_string); | | 384 | krb5_data_free (&result_string); |
345 | | | 385 | |
346 | krb5_free_cred_contents (context, &cred); | | 386 | krb5_free_cred_contents (context, &cred); |
347 | krb5_free_context (context); | | 387 | krb5_free_context (context); |
348 | return result_code; | | 388 | return result_code; |
349 | } | | 389 | } |
350 | | | 390 | |
351 | #endif /* USE_PAM */ | | 391 | #endif /* USE_PAM */ |