1 /*
2  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 #pragma ident	"%Z%%M%	%I%	%E% SMI"
7 
8 /*
9  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
10  *
11  *	Openvision retains the copyright to derivative works of
12  *	this source code.  Do *NOT* create a derivative of this
13  *	source code before consulting with your legal department.
14  *	Do *NOT* integrate *ANY* of this source code into another
15  *	product before consulting with your legal department.
16  *
17  *	For further information, read the top-level Openvision
18  *	copyright which is contained in the top-level MIT Kerberos
19  *	copyright.
20  *
21  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
22  *
23  */
24 
25 
26 /*
27  * kadmin/ktutil/ktutil.c
28  *
29  * Copyright 1995, 1996 by the Massachusetts Institute of Technology.
30  * All Rights Reserved.
31  *
32  * Export of this software from the United States of America may
33  *   require a specific license from the United States Government.
34  *   It is the responsibility of any person or organization contemplating
35  *   export to obtain such a license before exporting.
36  *
37  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
38  * distribute this software and its documentation for any purpose and
39  * without fee is hereby granted, provided that the above copyright
40  * notice appear in all copies and that both that copyright notice and
41  * this permission notice appear in supporting documentation, and that
42  * the name of M.I.T. not be used in advertising or publicity pertaining
43  * to distribution of the software without specific, written prior
44  * permission.  Furthermore if you modify this software you must label
45  * your software as modified software and not distribute it in such a
46  * fashion that it might be confused with the original M.I.T. software.
47  * M.I.T. makes no representations about the suitability of
48  * this software for any purpose.  It is provided "as is" without express
49  * or implied warranty.
50  *
51  * SS user interface for ktutil.
52  */
53 
54 #include "k5-int.h"
55 #include "ktutil.h"
56 #include <com_err.h>
57 #include <ss/ss.h>
58 #include <stdio.h>
59 #ifdef HAVE_STDLIB_H
60 #include <stdlib.h>
61 #endif
62 #include <libintl.h>
63 #include <locale.h>
64 
65 extern ss_request_table ktutil_cmds;
66 krb5_context kcontext;
67 krb5_kt_list ktlist = NULL;
68 
69 int
70 main(argc, argv)
71 int argc;
72 char *argv[];
73 {
74 	krb5_error_code retval;
75 	extern krb5_kt_ops krb5_ktf_writable_ops;
76 	int sci_idx;
77 
78 	(void) setlocale(LC_ALL, "");
79 
80 #if !defined(TEXT_DOMAIN)  /* Should be defined by cc -D */
81 #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it weren't */
82 #endif
83 
84 	(void) textdomain(TEXT_DOMAIN);
85 
86 	retval = krb5_init_context(&kcontext);
87 	if (retval) {
88 		com_err(argv[0], retval, gettext("while initializing krb5"));
89 		exit(1);
90 	}
91 	retval = krb5_kt_register(kcontext, &krb5_ktf_writable_ops);
92 	if (retval) {
93 		com_err(argv[0], retval,
94 		    gettext("while registering writable key table functions"));
95 		exit(1);
96 	}
97 	retval = ktutil_initialize_cmds_table (&ktutil_cmds);
98 	if (retval) {
99 		com_err(argv[0], retval,
100 		    gettext("while localizing command description messages"));
101 		exit(1);
102 	}
103 	sci_idx = ss_create_invocation("ktutil", "5.0", (char *) NULL,
104 	    &ktutil_cmds, &retval);
105 	if (retval) {
106 		ss_perror(sci_idx, retval, gettext("creating invocation"));
107 		exit(1);
108 	}
109 	ss_listen(sci_idx, &retval);
110 	ktutil_free_kt_list(kcontext, ktlist);
111 	exit(0);
112 }
113 
114 void
115 ktutil_clear_list(argc, argv)
116 int argc;
117 char *argv[];
118 {
119 	krb5_error_code retval;
120 
121 	if (argc != 1) {
122 		fprintf(stderr, gettext("%s: invalid arguments\n"), argv[0]);
123 		return;
124 	}
125 	retval = ktutil_free_kt_list(kcontext, ktlist);
126 	if (retval)
127 		com_err(argv[0], retval, gettext("while freeing ktlist"));
128 	ktlist = NULL;
129 }
130 
131 void
132 ktutil_read_v5(argc, argv)
133 int argc;
134 char *argv[];
135 {
136 	krb5_error_code retval;
137 
138 	if (argc != 2) {
139 		fprintf(stderr,
140 			gettext("%s: must specify keytab to read\n"), argv[0]);
141 		return;
142 	}
143 	retval = ktutil_read_keytab(kcontext, argv[1], &ktlist);
144 	if (retval)
145 		com_err(argv[0], retval,
146 		    gettext("while reading keytab \"%s\""), argv[1]);
147 }
148 
149 void
150 ktutil_read_v4(argc, argv)
151 int argc;
152 char *argv[];
153 {
154 #ifdef KRB5_KRB4_COMPAT
155 	krb5_error_code retval;
156 
157 	if (argc != 2) {
158 		fprintf(stderr,
159 		    gettext("%s: must specify the srvtab to read\n"), argv[0]);
160 		return;
161 	}
162 	retval = ktutil_read_srvtab(kcontext, argv[1], &ktlist);
163 	if (retval)
164 		com_err(argv[0], retval,
165 		    gettext("while reading srvtab \"%s\""), argv[1]);
166 #else
167 	fprintf(stderr, gettext("%s: krb4 support not configured\n"), argv[0]);
168 #endif
169 }
170 
171 void
172 ktutil_write_v5(argc, argv)
173 int argc;
174 char *argv[];
175 {
176 	krb5_error_code retval;
177 
178 	if (argc != 2) {
179 		fprintf(stderr,
180 		    gettext("%s: must specify keytab to write\n"), argv[0]);
181 		return;
182 	}
183 	retval = ktutil_write_keytab(kcontext, ktlist, argv[1]);
184 	if (retval)
185 		com_err(argv[0], retval,
186 		    gettext("while writing keytab \"%s\""), argv[1]);
187 }
188 
189 void
190 ktutil_write_v4(argc, argv)
191 int argc;
192 char *argv[];
193 {
194 #ifdef KRB5_KRB4_COMPAT
195 	krb5_error_code retval;
196 
197 	if (argc != 2) {
198 		fprintf(stderr,
199 		    gettext("%s: must specify srvtab to write\n"), argv[0]);
200 		return;
201 	}
202 	retval = ktutil_write_srvtab(kcontext, ktlist, argv[1]);
203 	if (retval)
204 		com_err(argv[0], retval,
205 		    gettext("while writing srvtab \"%s\""), argv[1]);
206 #else
207 	fprintf(stderr, gettext("%s: krb4 support not configured\n"), argv[0]);
208 #endif
209 }
210 
211 void ktutil_add_entry(argc, argv)
212     int argc;
213     char *argv[];
214 {
215     krb5_error_code retval;
216     char *princ = NULL;
217     char *enctype = NULL;
218     krb5_kvno kvno = 0;
219     int use_pass = 0, use_key = 0, i;
220 
221     for (i = 1; i < argc; i++) {
222 	if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-p", 2)) {
223 	    princ = argv[++i];
224 	    continue;
225 	}
226 	if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) {
227 	    kvno = (krb5_kvno) atoi(argv[++i]);
228 	    continue;
229 	}
230 	if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) {
231 	    enctype = argv[++i];
232 	    continue;
233 	}
234 	if ((strlen(argv[i]) == 9) && !strncmp(argv[i], "-password", 9)) {
235 	    use_pass++;
236 	    continue;
237 	}
238 	if ((strlen(argv[i]) == 4) && !strncmp(argv[i], "-key", 4)) {
239 	    use_key++;
240 	    continue;
241 	}
242     }
243 
244     if (argc != 8 || !(princ && kvno && enctype) || (use_pass+use_key != 1)) {
245         fprintf(stderr, "%s: %s (-key | -password) -p principal "
246 		"-k kvno -e enctype\n", gettext("usage"), argv[0]);
247 	return;
248     }
249 
250     retval = ktutil_add(kcontext, &ktlist, princ, kvno, enctype, use_pass);
251     if (retval)
252         com_err(argv[0], retval, gettext("while adding new entry"));
253 }
254 
255 void
256 ktutil_delete_entry(argc, argv)
257 int argc;
258 char *argv[];
259 {
260 	krb5_error_code retval;
261 
262 	if (argc != 2) {
263 		fprintf(stderr,
264 		    gettext("%s: must specify entry to delete\n"), argv[0]);
265 		return;
266 	}
267 	retval = ktutil_delete(kcontext, &ktlist, atoi(argv[1]));
268 	if (retval)
269 		com_err(argv[0], retval,
270 		    gettext("while deleting entry %d"), atoi(argv[1]));
271 }
272 
273 void
274 ktutil_list(argc, argv)
275 int argc;
276 char *argv[];
277 {
278 	krb5_error_code retval;
279 	krb5_kt_list lp;
280 	struct tm *stime;
281 	int show_time = 0, show_keys = 0, show_enctype = 0;
282 	int i, j;
283 	char *pname;
284 
285 	for (i = 1; i < argc; i++) {
286 		if ((strlen(argv[i]) == 2) && strncmp(argv[i], "-t", 2) == 0) {
287 			show_time++;
288 			continue;
289 		}
290 		if ((strlen(argv[i]) == 2) && strncmp(argv[i], "-k", 2) == 0) {
291 			show_keys++;
292 			continue;
293 		}
294 		if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) {
295 			show_enctype++;
296 			continue;
297 		}
298 		if ((strlen(argv[i]) == 2) &&
299 		    (strncmp(argv[i], "-e", 2) == 0)) {
300 			show_enctype = 1;
301 			continue;
302 		}
303 		fprintf(stderr, gettext("%s: illegal arguments\n"), argv[0]);
304 		return;
305 	}
306 	if (show_time) {
307 		printf(gettext("slot KVNO Timestamp         Principal\n"));
308 		printf("---- ---- ----------------- ---------------------------------------------------\n");
309 	} else {
310 		printf(gettext("slot KVNO Principal\n"));
311 		printf("---- ---- ---------------------------------------------------------------------\n");
312 	}
313 	for (i = 1, lp = ktlist; lp; i++, lp = lp->next) {
314 		retval = krb5_unparse_name(kcontext,
315 					    lp->entry->principal, &pname);
316 		if (retval) {
317 			com_err(argv[0], retval,
318 				gettext("while unparsing principal name"));
319 			return;
320 		}
321 		printf("%4d %4d ", i, lp->entry->vno);
322 		if (show_time) {
323 			char fmtbuf[18];
324 			char fill;
325 
326 			stime = localtime((time_t *) & lp->entry->timestamp);
327 			fill = ' ';
328 			if (!krb5_timestamp_to_sfstring(
329 				(krb5_timestamp) lp->entry->timestamp,
330 				fmtbuf,
331 				sizeof (fmtbuf),
332 				&fill))
333 			    printf("%s ", fmtbuf);
334 		}
335 		printf("%40s", pname);
336 		if (show_enctype) {
337 			static char buf[256];
338 
339 			if ((retval = krb5_enctype_to_string(
340 				    lp->entry->key.enctype, buf, 256))) {
341 				com_err(argv[0], retval,
342 					gettext("While converting "
343 						"enctype to string"));
344 				return;
345 			}
346 			printf(" (%s) ", buf);
347 		}
348 		if (show_keys) {
349 			printf(" (0x");
350 			for (j = 0; j < lp->entry->key.length; j++)
351 				printf("%02x", lp->entry->key.contents[j]);
352 			printf(")");
353 		}
354 		printf("\n");
355 		krb5_xfree(pname);
356 	}
357 }
358 
359 
360 
361 
362 
363 
364 
365 
366 
367 
368