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