| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
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 |
| @@ -58,33 +58,34 @@ pwkrb5_usage(const char *prefix) | | | @@ -58,33 +58,34 @@ pwkrb5_usage(const char *prefix) |
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 | /* |
| @@ -115,89 +116,112 @@ pwkrb5_process(const char *username, int | | | @@ -115,89 +116,112 @@ pwkrb5_process(const char *username, int |
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); |
| @@ -261,45 +285,56 @@ krb5_end(void) | | | @@ -261,45 +285,56 @@ krb5_end(void) |
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", |
| @@ -307,28 +342,33 @@ krb5_chpw(const char *username) | | | @@ -307,28 +342,33 @@ krb5_chpw(const char *username) |
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); |