1 /*
2  * Copyright 2005 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  * admin/stash/kdb5_stash.c
28  *
29  * Copyright 1990 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  *
52  * Store the master database key in a file.
53  */
54 
55 #define KDB5_DISPATCH
56 #define KRB5_KDB5_DBM__
57 #include <k5-int.h>
58 /* #define these to avoid an indirection function; for future implementations,
59    these may be redirected from a dispatch table/routine */
60 #define krb5_dbm_db_set_name krb5_db_set_name
61 #define krb5_dbm_db_set_nonblocking krb5_db_set_nonblocking
62 #define krb5_dbm_db_init krb5_db_init
63 #define krb5_dbm_db_get_age krb5_db_get_age
64 #define krb5_dbm_db_create krb5_db_create
65 #define krb5_dbm_db_rename krb5_db_rename
66 #define krb5_dbm_db_get_principal krb5_db_get_principal
67 #define krb5_dbm_db_free_principal krb5_db_free_principal
68 #define krb5_dbm_db_put_principal krb5_db_put_principal
69 #define krb5_dbm_db_delete_principal krb5_db_delete_principal
70 #define krb5_dbm_db_lock krb5_db_lock
71 #define krb5_dbm_db_unlock krb5_db_unlock
72 #define krb5_dbm_db_set_lockmode krb5_db_set_lockmode
73 #define krb5_dbm_db_close_database krb5_db_close_database
74 #define krb5_dbm_db_open_database krb5_db_open_database
75 
76 #include <kadm5/admin.h>
77 #include "com_err.h"
78 #include <kadm5/admin.h>
79 #include <stdio.h>
80 #include <libintl.h>
81 
82 extern int errno;
83 
84 extern krb5_principal master_princ;
85 extern kadm5_config_params global_params;
86 
87 extern int exit_status;
88 extern int close_policy_db;
89 
90 void
91 kdb5_stash(argc, argv)
92 int argc;
93 char *argv[];
94 {
95     extern char *optarg;
96     extern int optind;
97     int optchar;
98     krb5_error_code retval;
99     char *dbname = (char *) NULL;
100     char *realm = 0;
101     char *mkey_name = 0;
102     char *mkey_fullname;
103     char *keyfile = 0;
104     krb5_context context;
105     krb5_keyblock mkey;
106 
107     int enctypedone = 0;
108 
109     if (strrchr(argv[0], '/'))
110 	argv[0] = strrchr(argv[0], '/')+1;
111 
112     /* Tell upwards to close the policy db cause we don't */
113     close_policy_db = 1;
114 
115     krb5_init_context(&context);
116 
117     dbname = global_params.dbname;
118     realm = global_params.realm;
119     mkey_name = global_params.mkey_name;
120     keyfile = global_params.stash_file;
121 
122     optind = 1;
123     while ((optchar = getopt(argc, argv, "f:")) != -1) {
124 	switch(optchar) {
125 	case 'f':
126 	    keyfile = optarg;
127 	    break;
128 	case '?':
129 	default:
130 	    usage();
131 	    return;
132 	}
133     }
134 
135     if (!krb5_c_valid_enctype(global_params.enctype)) {
136 	char tmp[32];
137 
138 	if (krb5_enctype_to_string(global_params.enctype,
139 					    tmp, sizeof (tmp)))
140 	    com_err(argv[0], KRB5_PROG_KEYTYPE_NOSUPP,
141 		gettext("while setting up enctype %d"),
142 		global_params.enctype);
143 	else
144 	    com_err(argv[0], KRB5_PROG_KEYTYPE_NOSUPP, tmp);
145 	exit_status++;
146 	return;
147     }
148 
149     if (retval = krb5_db_set_name(context, dbname)) {
150 	com_err(argv[0], retval,
151 	    gettext("while setting active database to '%s'"),
152 	dbname);
153 	exit_status++;
154 	return;
155     }
156 
157     /* assemble & parse the master key name */
158     if (retval = krb5_db_setup_mkey_name(context, mkey_name, realm,
159 					 &mkey_fullname, &master_princ)) {
160 	com_err(argv[0], retval,
161 		gettext("while setting up master key name"));
162 	exit_status++;
163 	return;
164     }
165     if (retval = krb5_db_init(context)) {
166 	com_err(argv[0], retval,
167 		gettext("while initializing the database '%s'"),
168 	dbname);
169 	exit_status++;
170 	return;
171     }
172 
173     /* TRUE here means read the keyboard, but only once */
174     if (retval = krb5_db_fetch_mkey(context, master_princ,
175 				    global_params.enctype,
176 				    TRUE, FALSE, (char *) NULL,
177 				    0, &mkey)) {
178 	com_err(argv[0], retval, gettext("while reading master key"));
179 	(void) krb5_db_fini(context);
180 	exit_status++;
181 	return;
182     }
183     if (retval = krb5_db_verify_master_key(context, master_princ, &mkey)) {
184 	com_err(argv[0], retval, gettext("while verifying master key"));
185 	krb5_free_keyblock_contents(context, &mkey);
186 	(void) krb5_db_fini(context);
187 	exit_status++;
188 	return;
189     }
190     if (retval = krb5_db_store_mkey(context, keyfile, master_princ,
191 				    &mkey)) {
192 	com_err(argv[0], errno, gettext("while storing key"));
193 	krb5_free_keyblock_contents(context, &mkey);
194 	(void) krb5_db_fini(context);
195 	exit_status++;
196 	return;
197     }
198     krb5_free_keyblock_contents(context, &mkey);
199     if (retval = krb5_db_fini(context)) {
200 	com_err(argv[0], retval,
201 		gettext("closing database '%s'"), dbname);
202 	exit_status++;
203 	return;
204     }
205 
206     krb5_free_context(context);
207     exit_status = 0;
208 }
209