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