xref: /titanic_50/usr/src/cmd/krb5/kadmin/dbutil/kadm5_create.c (revision fa9e4066f08beec538e775443c5be79dd423fcab)
1 /*
2  * Copyright 2004 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  * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
9  *
10  * $Id: kadm5_create.c,v 1.6 1998/10/30 02:52:37 marc Exp $
11  * $Source: /cvs/krbdev/krb5/src/kadmin/dbutil/kadm5_create.c,v $
12  */
13 
14 /*
15  * Copyright (C) 1998 by the FundsXpress, INC.
16  *
17  * All rights reserved.
18  *
19  * Export of this software from the United States of America may require
20  * a specific license from the United States Government.  It is the
21  * responsibility of any person or organization contemplating export to
22  * obtain such a license before exporting.
23  *
24  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
25  * distribute this software and its documentation for any purpose and
26  * without fee is hereby granted, provided that the above copyright
27  * notice appear in all copies and that both that copyright notice and
28  * this permission notice appear in supporting documentation, and that
29  * the name of FundsXpress. not be used in advertising or publicity pertaining
30  * to distribution of the software without specific, written prior
31  * permission.  FundsXpress makes no representations about the suitability of
32  * this software for any purpose.  It is provided "as is" without express
33  * or implied warranty.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
36  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
37  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
38  */
39 
40 #if !defined(lint) && !defined(__CODECENTER__)
41 static char *rcsid = "$Header: /cvs/krbdev/krb5/src/kadmin/dbutil/kadm5_create.c,v 1.6 1998/10/30 02:52:37 marc Exp $";
42 #endif
43 
44 #include "string_table.h"
45 
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <kadm5/adb.h>
50 #include <kadm5/admin.h>
51 
52 #include <krb5.h>
53 #include <krb5/kdb.h>
54 #include <libintl.h>
55 
56 int
57 add_admin_old_princ(void *handle, krb5_context context,
58 		    char *name, char *realm, int attrs, int lifetime);
59 int
60 add_admin_sname_princ(void *handle, krb5_context context,
61     char *sname, int attrs, int lifetime);
62 int
63 add_admin_princ(void *handle, krb5_context context,
64     krb5_principal principal, int attrs, int lifetime);
65 
66 #define	KADM5_ERR 1
67 #define	KADM5_OK 0
68 
69 #define ADMIN_LIFETIME 60*60*3 /* 3 hours */
70 #define CHANGEPW_LIFETIME 60*5 /* 5 minutes */
71 
72 extern char *progname;
73 
74 /*
75  * Function: kadm5_create
76  *
77  * Purpose: create admin principals in KDC database
78  *
79  * Arguments:	params	(r) configuration parameters to use
80  *
81  * Effects:  Creates KADM5_ADMIN_SERVICE and KADM5_CHANGEPW_SERVICE
82  * principals in the KDC database and sets their attributes
83  * appropriately.
84  */
85 int
86 kadm5_create(kadm5_config_params * params)
87 {
88      int retval;
89      void *handle;
90      krb5_context context;
91      FILE *f;
92 
93      kadm5_config_params lparams;
94 
95      if (retval = krb5_init_context(&context))
96 	exit(KADM5_ERR);
97 
98      (void) memset(&lparams, 0, sizeof (kadm5_config_params));
99 
100      /*
101       * The lock file has to exist before calling kadm5_init, but
102       * params->admin_lockfile may not be set yet...
103       */
104      if (retval = kadm5_get_config_params(context, NULL, NULL,
105 		params, &lparams)) {
106 	com_err(progname, retval, gettext(str_INITING_KCONTEXT));
107 	return (1);
108      }
109      if (retval = osa_adb_create_policy_db(&lparams)) {
110 	com_err(progname, retval, gettext(str_CREATING_POLICY_DB));
111 	return (1);
112      }
113 
114      retval = kadm5_create_magic_princs(&lparams, context);
115 
116      kadm5_free_config_params(context, &lparams);
117      krb5_free_context(context);
118 
119      return (retval);
120 }
121 
122 int
123 kadm5_create_magic_princs(kadm5_config_params * params,
124 			      krb5_context *context)
125 {
126      int retval;
127      void *handle;
128 
129      if ((retval = kadm5_init(progname, NULL, NULL, params,
130 			      KADM5_STRUCT_VERSION,
131 			      KADM5_API_VERSION_2,
132 			      &handle))) {
133 	com_err(progname, retval, gettext(str_INITING_KCONTEXT));
134 	return (retval);
135      }
136      retval = add_admin_princs(handle, context, params->realm);
137 
138      kadm5_destroy(handle);
139 
140      return (retval);
141 }
142 
143 /*
144  * Function: build_name_with_realm
145  *
146  * Purpose: concatenate a name and a realm to form a krb5 name
147  *
148  * Arguments:
149  *
150  * 	name	(input) the name
151  * 	realm	(input) the realm
152  *
153  * Returns:
154  *
155  * 	pointer to name@realm, in allocated memory, or NULL if it
156  * 	cannot be allocated
157  *
158  * Requires: both strings are null-terminated
159  */
160 char *
161 build_name_with_realm(char *name, char *realm)
162 {
163      char *n;
164 
165      n = (char *) malloc(strlen(name) + strlen(realm) + 2);
166      sprintf(n, "%s@%s", name, realm);
167      return (n);
168 }
169 
170 /*
171  * Function: add_admin_princs
172  *
173  * Purpose: create admin principals
174  *
175  * Arguments:
176  *
177  * 	rseed		(input) random seed
178  * 	realm		(input) realm, or NULL for default realm
179  *      <return value>  (output) status, 0 for success, 1 for serious error
180  *
181  * Requires:
182  *
183  * Effects:
184  *
185  * add_admin_princs creates KADM5_ADMIN_SERVICE,
186  * KADM5_CHANGEPW_SERVICE.  If any of these exist a message is
187  * printed.  If any of these existing principal do not have the proper
188  * attributes, a warning message is printed.
189  */
190 int
191 add_admin_princs(void *handle, krb5_context context, char *realm)
192 {
193   krb5_error_code ret = 0;
194 
195 	if ((ret = add_admin_old_princ(handle, context,
196 			     KADM5_ADMIN_SERVICE, realm,
197 			     KRB5_KDB_DISALLOW_TGT_BASED,
198 			     ADMIN_LIFETIME)))
199        goto clean_and_exit;
200 
201 	if ((ret = add_admin_old_princ(handle, context,
202 			     KADM5_CHANGEPW_SERVICE, realm,
203 			     KRB5_KDB_DISALLOW_TGT_BASED |
204 			     KRB5_KDB_PWCHANGE_SERVICE,
205 			     CHANGEPW_LIFETIME)))
206        goto clean_and_exit;
207 
208 	if ((ret = add_admin_sname_princ(handle, context,
209 		    KADM5_ADMIN_HOST_SERVICE,
210 		    KRB5_KDB_DISALLOW_TGT_BASED,
211 		    ADMIN_LIFETIME)))
212 		goto clean_and_exit;
213 
214 	if ((ret = add_admin_sname_princ(handle, context,
215 		    KADM5_CHANGEPW_HOST_SERVICE,
216 		    KRB5_KDB_DISALLOW_TGT_BASED |
217 		    KRB5_KDB_PWCHANGE_SERVICE,
218 		    ADMIN_LIFETIME)))
219 		goto clean_and_exit;
220 
221 clean_and_exit:
222 
223 	return (ret);
224 }
225 
226 /*
227  * Function: add_admin_princ
228  *
229  * Arguments:
230  *
231  * 	creator		(r) principal to use as "mod_by"
232  * 	rseed		(r) seed for random key generator
233  *	principal	(r) kerberos principal to add
234  * 	attrs		(r) principal's attributes
235  * 	lifetime	(r) principal's max life, or 0
236  * 	not_unique	(r) error message for multiple entries, never used
237  * 	exists		(r) warning message for principal exists
238  * 	wrong_attrs	(r) warning message for wrong attributes
239  *
240  * Returns:
241  *
242  * 	KADM5_OK on success
243  * 	KADM5_ERR on serious errors
244  *
245  * Effects:
246  *
247  * If the principal is not unique, not_unique is printed (but this
248  * never happens).  If the principal exists, then exists is printed
249  * and if the principals attributes != attrs, wrong_attrs is printed.
250  * Otherwise, the principal is created with mod_by creator and
251  * attributes attrs and max life of lifetime (if not zero).
252  */
253 
254 int
255 add_admin_princ(void *handle, krb5_context context,
256     krb5_principal principal, int attrs, int lifetime)
257 {
258      char *fullname;
259      krb5_error_code ret;
260      kadm5_principal_ent_rec ent;
261 
262      memset(&ent, 0, sizeof(ent));
263 
264 	if (krb5_unparse_name(context, principal, &fullname))
265 		return (KADM5_ERR);
266 
267      ent.principal = principal;
268      ent.max_life = lifetime;
269      ent.attributes = attrs | KRB5_KDB_DISALLOW_ALL_TIX;
270 
271      if (ret = kadm5_create_principal(handle, &ent,
272 					   (KADM5_PRINCIPAL |
273 					    KADM5_MAX_LIFE |
274 					    KADM5_ATTRIBUTES),
275 					   "to-be-random")) {
276 	  if (ret != KADM5_DUP) {
277 		com_err(progname, ret,
278 			gettext(str_PUT_PRINC), fullname);
279 	       krb5_free_principal(context, ent.principal);
280 	       free(fullname);
281 		return (KADM5_ERR);
282 	  }
283      } else {
284 	  /* only randomize key if we created the principal */
285 	ret = kadm5_randkey_principal(handle, ent.principal, NULL, NULL);
286 	if (ret) {
287 		com_err(progname, ret,
288 			gettext(str_RANDOM_KEY), fullname);
289 		krb5_free_principal(context, ent.principal);
290 		free(fullname);
291 		return (KADM5_ERR);
292 	}
293 	ent.attributes = attrs;
294 	ret = kadm5_modify_principal(handle, &ent, KADM5_ATTRIBUTES);
295 	if (ret) {
296 		com_err(progname, ret,
297 			gettext(str_PUT_PRINC), fullname);
298 		krb5_free_principal(context, ent.principal);
299 		free(fullname);
300 		return (KADM5_ERR);
301 	}
302     }
303 
304     krb5_free_principal(context, ent.principal);
305     free(fullname);
306 
307     return (KADM5_OK);
308 }
309 
310 int
311 add_admin_old_princ(void *handle, krb5_context context,
312     char *name, char *realm, int attrs, int lifetime)
313 {
314 	char *fullname;
315 	krb5_error_code ret;
316 	krb5_principal principal;
317 
318 	fullname = build_name_with_realm(name, realm);
319 	if (ret = krb5_parse_name(context, fullname, &principal)) {
320 		com_err(progname, ret, gettext(str_PARSE_NAME));
321 		return (KADM5_ERR);
322 	}
323 
324 	return (add_admin_princ(handle, context, principal, attrs, lifetime));
325 }
326 
327 int
328 add_admin_sname_princ(void *handle, krb5_context context,
329 	     char *sname, int attrs, int lifetime)
330 {
331 	krb5_error_code ret;
332 	krb5_principal principal;
333 
334 	if (ret = krb5_sname_to_principal(context, NULL, sname,
335 					  KRB5_NT_SRV_HST, &principal)) {
336 		com_err(progname, ret,
337 			gettext("Could not get host based "
338 				"service name for %s principal\n"), sname);
339 		return (KADM5_ERR);
340 	}
341 	return (add_admin_princ(handle, context, principal, attrs, lifetime));
342 }
343 
344 
345 
346