1 /*
2  * Copyright 2006 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 main(argc, argv)
70     int argc;
71     char *argv[];
72 {
73     krb5_error_code retval;
74     int sci_idx;
75 
76 	(void) setlocale(LC_ALL, "");
77 
78 #if !defined(TEXT_DOMAIN)  /* Should be defined by cc -D */
79 #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it weren't */
80 #endif
81 
82 	(void) textdomain(TEXT_DOMAIN);
83 
84     retval = krb5_init_context(&kcontext);
85     if (retval) {
86 		com_err(argv[0], retval, gettext("while initializing krb5"));
87 	exit(1);
88     }
89 	retval = ktutil_initialize_cmds_table (&ktutil_cmds);
90 	if (retval) {
91 		com_err(argv[0], retval,
92 		    gettext("while localizing command description messages"));
93 		exit(1);
94 	}
95     sci_idx = ss_create_invocation("ktutil", "5.0", (char *) NULL,
96 				   &ktutil_cmds, &retval);
97     if (retval) {
98 	ss_perror(sci_idx, retval, gettext("creating invocation"));
99 	exit(1);
100     }
101     retval = ss_listen(sci_idx);
102     ktutil_free_kt_list(kcontext, ktlist);
103     exit(0);
104 }
105 
106 void ktutil_clear_list(argc, argv)
107     int argc;
108     char *argv[];
109 {
110     krb5_error_code retval;
111 
112     if (argc != 1) {
113 		fprintf(stderr, gettext("%s: invalid arguments\n"), argv[0]);
114 	return;
115     }
116     retval = ktutil_free_kt_list(kcontext, ktlist);
117     if (retval)
118 		com_err(argv[0], retval, gettext("while freeing ktlist"));
119     ktlist = NULL;
120 }
121 
122 void ktutil_read_v5(argc, argv)
123     int argc;
124     char *argv[];
125 {
126     krb5_error_code retval;
127 
128     if (argc != 2) {
129 		fprintf(stderr,
130 			gettext("%s: must specify keytab to read\n"), argv[0]);
131 	return;
132     }
133     retval = ktutil_read_keytab(kcontext, argv[1], &ktlist);
134     if (retval)
135 		com_err(argv[0], retval,
136 		    gettext("while reading keytab \"%s\""), argv[1]);
137 }
138 
139 void ktutil_read_v4(argc, argv)
140     int argc;
141     char *argv[];
142 {
143 #ifdef KRB5_KRB4_COMPAT
144     krb5_error_code retval;
145 
146     if (argc != 2) {
147 		fprintf(stderr,
148 		    gettext("%s: must specify the srvtab to read\n"), argv[0]);
149 	return;
150     }
151     retval = ktutil_read_srvtab(kcontext, argv[1], &ktlist);
152     if (retval)
153 		com_err(argv[0], retval,
154 		    gettext("while reading srvtab \"%s\""), argv[1]);
155 #else
156 	fprintf(stderr, gettext("%s: krb4 support not configured\n"), argv[0]);
157 #endif
158 }
159 
160 void ktutil_write_v5(argc, argv)
161     int argc;
162     char *argv[];
163 {
164     krb5_error_code retval;
165 
166     if (argc != 2) {
167 		fprintf(stderr,
168 		    gettext("%s: must specify keytab to write\n"), argv[0]);
169 	return;
170     }
171     retval = ktutil_write_keytab(kcontext, ktlist, argv[1]);
172     if (retval)
173 		com_err(argv[0], retval,
174 		    gettext("while writing keytab \"%s\""), argv[1]);
175 }
176 
177 void ktutil_write_v4(argc, argv)
178     int argc;
179     char *argv[];
180 {
181 #ifdef KRB5_KRB4_COMPAT
182     krb5_error_code retval;
183 
184     if (argc != 2) {
185 		fprintf(stderr,
186 		    gettext("%s: must specify srvtab to write\n"), argv[0]);
187 	return;
188     }
189     retval = ktutil_write_srvtab(kcontext, ktlist, argv[1]);
190     if (retval)
191 		com_err(argv[0], retval,
192 		    gettext("while writing srvtab \"%s\""), argv[1]);
193 #else
194 	fprintf(stderr, gettext("%s: krb4 support not configured\n"), argv[0]);
195 #endif
196 }
197 
198 void ktutil_add_entry(argc, argv)
199     int argc;
200     char *argv[];
201 {
202     krb5_error_code retval;
203     char *princ = NULL;
204     char *enctype = NULL;
205     krb5_kvno kvno = 0;
206     int use_pass = 0, use_key = 0, i;
207 
208     for (i = 1; i < argc; i++) {
209 	if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-p", 2)) {
210 	    princ = argv[++i];
211 	    continue;
212 	}
213 	if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) {
214 	    kvno = (krb5_kvno) atoi(argv[++i]);
215 	    continue;
216 	}
217 	if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) {
218 	    enctype = argv[++i];
219 	    continue;
220 	}
221 	if ((strlen(argv[i]) == 9) && !strncmp(argv[i], "-password", 9)) {
222 	    use_pass++;
223 	    continue;
224 	}
225 	if ((strlen(argv[i]) == 4) && !strncmp(argv[i], "-key", 4)) {
226 	    use_key++;
227 	    continue;
228 	}
229     }
230 
231     if (argc != 8 || !(princ && kvno && enctype) || (use_pass+use_key != 1)) {
232         fprintf(stderr, "%s: %s (-key | -password) -p principal "
233 		"-k kvno -e enctype\n", gettext("usage"), argv[0]);
234 	return;
235     }
236 
237     retval = ktutil_add(kcontext, &ktlist, princ, kvno, enctype, use_pass);
238     if (retval)
239         com_err(argv[0], retval, gettext("while adding new entry"));
240 }
241 
242 void ktutil_delete_entry(argc, argv)
243     int argc;
244     char *argv[];
245 {
246     krb5_error_code retval;
247 
248     if (argc != 2) {
249 	fprintf(stderr,
250 	    gettext("%s: must specify entry to delete\n"), argv[0]);
251 	return;
252     }
253     retval = ktutil_delete(kcontext, &ktlist, atoi(argv[1]));
254     if (retval)
255 	com_err(argv[0], retval,
256 		    gettext("while deleting entry %d"), atoi(argv[1]));
257 }
258 
259 void ktutil_list(argc, argv)
260     int argc;
261     char *argv[];
262 {
263     krb5_error_code retval;
264     krb5_kt_list lp;
265     int show_time = 0, show_keys = 0, show_enctype = 0;
266     int i, j;
267     char *pname;
268 
269     for (i = 1; i < argc; i++) {
270 	if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-t", 2)) {
271 	    show_time++;
272 	    continue;
273 	}
274 	if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) {
275 	    show_keys++;
276 	    continue;
277 	}
278 	if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) {
279 	    show_enctype++;
280 	    continue;
281 	}
282 
283 	fprintf(stderr, "%s: %s [-t] [-k] [-e]\n", gettext("usage"), argv[0]);
284 	return;
285     }
286     if (show_time) {
287 	printf(gettext("slot KVNO Timestamp         Principal\n"));
288 	printf("---- ---- ----------------- ---------------------------------------------------\n");
289     } else {
290 	printf(gettext("slot KVNO Principal\n"));
291 	printf("---- ---- ---------------------------------------------------------------------\n");
292     }
293     for (i = 1, lp = ktlist; lp; i++, lp = lp->next) {
294 	retval = krb5_unparse_name(kcontext, lp->entry->principal, &pname);
295 	if (retval) {
296 	    com_err(argv[0], retval,
297 	    gettext("while unparsing principal name"));
298 	    return;
299 	}
300 	printf("%4d %4d ", i, lp->entry->vno);
301 	if (show_time) {
302 	    char fmtbuf[18];
303 	    char fill;
304 	    time_t tstamp;
305 
306 	    (void) localtime(&tstamp);
307 	    lp->entry->timestamp = tstamp;
308 	    fill = ' ';
309 	    if (!krb5_timestamp_to_sfstring((krb5_timestamp)lp->entry->
310 					    	timestamp,
311 					    fmtbuf,
312 					    sizeof(fmtbuf),
313 					    &fill))
314 		printf("%s ", fmtbuf);
315 	}
316 	printf("%40s", pname);
317 	if (show_enctype) {
318 	    static char buf[256];
319 		if ((retval = krb5_enctype_to_string(
320 		    lp->entry->key.enctype, buf, 256))) {
321 		    com_err(argv[0], retval,
322 		    gettext("While converting "
323 		    "enctype to string"));
324 		    return;
325 		}
326 	    printf(" (%s) ", buf);
327 	}
328 
329 	if (show_keys) {
330 	    printf(" (0x");
331 	    for (j = 0; j < lp->entry->key.length; j++)
332 		printf("%02x", lp->entry->key.contents[j]);
333 	    printf(")");
334 	}
335 	printf("\n");
336 	krb5_xfree(pname);
337     }
338 }
339 
340 
341 
342 
343 
344 
345 
346 
347 
348 
349