Line data Source code
1 : /*
2 : * Copyright (c) 1997-2004 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : *
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : *
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * 3. Neither the name of the Institute nor the names of its contributors
18 : * may be used to endorse or promote products derived from this software
19 : * without specific prior written permission.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 : * SUCH DAMAGE.
32 : */
33 :
34 : #include "kpasswd_locl.h"
35 : RCSID("$Id$");
36 :
37 : static int version_flag;
38 : static int help_flag;
39 : static char *admin_principal_str;
40 : static char *cred_cache_str;
41 :
42 : static struct getargs args[] = {
43 : { "admin-principal", 0, arg_string, &admin_principal_str, NULL,
44 : NULL },
45 : { "cache", 'c', arg_string, &cred_cache_str, NULL, NULL },
46 : { "version", 0, arg_flag, &version_flag, NULL, NULL },
47 : { "help", 0, arg_flag, &help_flag, NULL, NULL }
48 : };
49 :
50 : static void
51 0 : usage (int ret, struct getargs *a, int num_args)
52 : {
53 0 : arg_printusage (a, num_args, NULL, "[principal ...]");
54 0 : exit (ret);
55 : }
56 :
57 : static int
58 6 : change_password(krb5_context context,
59 : krb5_principal principal,
60 : krb5_ccache id)
61 : {
62 : krb5_data result_code_string, result_string;
63 : int result_code;
64 : krb5_error_code ret;
65 : char pwbuf[BUFSIZ];
66 : char *msg, *name;
67 : int aret;
68 :
69 6 : krb5_data_zero (&result_code_string);
70 6 : krb5_data_zero (&result_string);
71 :
72 6 : name = msg = NULL;
73 6 : if (principal == NULL)
74 0 : aret = asprintf(&msg, "New password: ");
75 : else {
76 6 : ret = krb5_unparse_name(context, principal, &name);
77 6 : if (ret)
78 0 : krb5_err(context, 1, ret, "krb5_unparse_name");
79 :
80 6 : aret = asprintf(&msg, "New password for %s: ", name);
81 : }
82 :
83 6 : if (aret == -1 || msg == NULL)
84 0 : krb5_errx (context, 1, "out of memory");
85 :
86 6 : ret = UI_UTIL_read_pw_string (pwbuf, sizeof(pwbuf), msg,
87 : UI_UTIL_FLAG_VERIFY);
88 6 : free(msg);
89 6 : if (name)
90 6 : free(name);
91 6 : if (ret != 0) {
92 0 : return 1;
93 : }
94 :
95 6 : ret = krb5_set_password_using_ccache (context, id, pwbuf,
96 : principal,
97 : &result_code,
98 : &result_code_string,
99 : &result_string);
100 6 : if (ret) {
101 0 : krb5_warn (context, ret, "krb5_set_password_using_ccache");
102 0 : return 1;
103 : }
104 :
105 12 : printf ("%s%s%.*s\n", krb5_passwd_result_to_string(context, result_code),
106 6 : result_string.length > 0 ? " : " : "",
107 6 : (int)result_string.length,
108 6 : result_string.length > 0 ? (char *)result_string.data : "");
109 :
110 6 : krb5_data_free (&result_code_string);
111 6 : krb5_data_free (&result_string);
112 :
113 6 : return ret != 0;
114 : }
115 :
116 :
117 : int
118 6 : main (int argc, char **argv)
119 : {
120 : krb5_error_code ret;
121 : krb5_context context;
122 : krb5_principal principal;
123 : krb5_get_init_creds_opt *opt;
124 6 : krb5_ccache id = NULL;
125 : int exit_value;
126 6 : int optidx = 0;
127 :
128 6 : setprogname(argv[0]);
129 :
130 6 : if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
131 0 : usage(1, args, sizeof(args) / sizeof(args[0]));
132 6 : if (help_flag)
133 0 : usage(0, args, sizeof(args) / sizeof(args[0]));
134 6 : if (version_flag) {
135 0 : print_version(NULL);
136 0 : return 0;
137 : }
138 6 : argc -= optidx;
139 6 : argv += optidx;
140 :
141 6 : ret = krb5_init_context (&context);
142 6 : if (ret)
143 0 : errx (1, "krb5_init_context failed: %d", ret);
144 :
145 6 : ret = krb5_get_init_creds_opt_alloc (context, &opt);
146 6 : if (ret)
147 0 : krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");
148 :
149 6 : krb5_get_init_creds_opt_set_tkt_life (opt, 300);
150 6 : krb5_get_init_creds_opt_set_forwardable (opt, FALSE);
151 6 : krb5_get_init_creds_opt_set_proxiable (opt, FALSE);
152 :
153 6 : if (cred_cache_str) {
154 0 : ret = krb5_cc_resolve(context, cred_cache_str, &id);
155 0 : if (ret)
156 0 : krb5_err (context, 1, ret, "krb5_cc_resolve");
157 : } else {
158 6 : ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id);
159 6 : if (ret)
160 0 : krb5_err (context, 1, ret, "krb5_cc_new_unique");
161 : }
162 :
163 6 : if (cred_cache_str == NULL) {
164 6 : krb5_principal admin_principal = NULL;
165 : krb5_creds cred;
166 :
167 6 : if (admin_principal_str) {
168 0 : ret = krb5_parse_name (context, admin_principal_str,
169 : &admin_principal);
170 0 : if (ret)
171 0 : krb5_err (context, 1, ret, "krb5_parse_name");
172 6 : } else if (argc == 1) {
173 6 : ret = krb5_parse_name (context, argv[0], &admin_principal);
174 6 : if (ret)
175 0 : krb5_err (context, 1, ret, "krb5_parse_name");
176 : } else {
177 0 : ret = krb5_get_default_principal (context, &admin_principal);
178 0 : if (ret)
179 0 : krb5_err (context, 1, ret, "krb5_get_default_principal");
180 : }
181 :
182 6 : ret = krb5_get_init_creds_password (context,
183 : &cred,
184 : admin_principal,
185 : NULL,
186 : krb5_prompter_posix,
187 : NULL,
188 : 0,
189 : "kadmin/changepw",
190 : opt);
191 6 : switch (ret) {
192 6 : case 0:
193 6 : break;
194 0 : case KRB5_LIBOS_PWDINTR :
195 0 : return 1;
196 0 : case KRB5KRB_AP_ERR_BAD_INTEGRITY :
197 : case KRB5KRB_AP_ERR_MODIFIED :
198 0 : krb5_errx(context, 1, "Password incorrect");
199 : break;
200 0 : default:
201 0 : krb5_err(context, 1, ret, "krb5_get_init_creds");
202 : }
203 :
204 6 : krb5_get_init_creds_opt_free(context, opt);
205 :
206 6 : ret = krb5_cc_initialize(context, id, admin_principal);
207 6 : krb5_free_principal(context, admin_principal);
208 6 : if (ret)
209 0 : krb5_err(context, 1, ret, "krb5_cc_initialize");
210 :
211 6 : ret = krb5_cc_store_cred(context, id, &cred);
212 6 : if (ret)
213 0 : krb5_err(context, 1, ret, "krb5_cc_store_cred");
214 :
215 6 : krb5_free_cred_contents (context, &cred);
216 : }
217 :
218 6 : if (argc == 0) {
219 0 : exit_value = change_password(context, NULL, id);
220 : } else {
221 6 : exit_value = 0;
222 :
223 12 : while (argc-- > 0) {
224 :
225 6 : ret = krb5_parse_name (context, argv[0], &principal);
226 6 : if (ret)
227 0 : krb5_err (context, 1, ret, "krb5_parse_name");
228 :
229 6 : ret = change_password(context, principal, id);
230 6 : if (ret)
231 0 : exit_value = 1;
232 6 : krb5_free_principal(context, principal);
233 6 : argv++;
234 : }
235 : }
236 :
237 6 : if (cred_cache_str == NULL) {
238 6 : ret = krb5_cc_destroy(context, id);
239 6 : if (ret)
240 0 : krb5_err (context, 1, ret, "krb5_cc_destroy");
241 : } else {
242 0 : ret = krb5_cc_close(context, id);
243 0 : if (ret)
244 0 : krb5_err (context, 1, ret, "krb5_cc_close");
245 : }
246 :
247 6 : krb5_free_context (context);
248 6 : return exit_value;
249 : }
|