10Sstevel@tonic-gate /* 21508Smp153739 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 30Sstevel@tonic-gate * Use is subject to license terms. 40Sstevel@tonic-gate */ 50Sstevel@tonic-gate 60Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 70Sstevel@tonic-gate /* 80Sstevel@tonic-gate * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved. 90Sstevel@tonic-gate * 100Sstevel@tonic-gate * $Id: kadm5_create.c,v 1.6 1998/10/30 02:52:37 marc Exp $ 110Sstevel@tonic-gate * $Source: /cvs/krbdev/krb5/src/kadmin/dbutil/kadm5_create.c,v $ 120Sstevel@tonic-gate */ 130Sstevel@tonic-gate 140Sstevel@tonic-gate /* 150Sstevel@tonic-gate * Copyright (C) 1998 by the FundsXpress, INC. 160Sstevel@tonic-gate * 170Sstevel@tonic-gate * All rights reserved. 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * Export of this software from the United States of America may require 200Sstevel@tonic-gate * a specific license from the United States Government. It is the 210Sstevel@tonic-gate * responsibility of any person or organization contemplating export to 220Sstevel@tonic-gate * obtain such a license before exporting. 230Sstevel@tonic-gate * 240Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 250Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 260Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 270Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 280Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 290Sstevel@tonic-gate * the name of FundsXpress. not be used in advertising or publicity pertaining 300Sstevel@tonic-gate * to distribution of the software without specific, written prior 310Sstevel@tonic-gate * permission. FundsXpress makes no representations about the suitability of 320Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 330Sstevel@tonic-gate * or implied warranty. 340Sstevel@tonic-gate * 350Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 360Sstevel@tonic-gate * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 370Sstevel@tonic-gate * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 380Sstevel@tonic-gate */ 390Sstevel@tonic-gate 400Sstevel@tonic-gate #include "string_table.h" 410Sstevel@tonic-gate 420Sstevel@tonic-gate #include <stdio.h> 430Sstevel@tonic-gate #include <stdlib.h> 440Sstevel@tonic-gate #include <string.h> 450Sstevel@tonic-gate #include <kadm5/adb.h> 460Sstevel@tonic-gate #include <kadm5/admin.h> 47*2881Smp153739 #include <krb5/adm_proto.h> 48*2881Smp153739 490Sstevel@tonic-gate 500Sstevel@tonic-gate #include <krb5.h> 510Sstevel@tonic-gate #include <krb5/kdb.h> 520Sstevel@tonic-gate #include <libintl.h> 530Sstevel@tonic-gate 540Sstevel@tonic-gate int 550Sstevel@tonic-gate add_admin_old_princ(void *handle, krb5_context context, 560Sstevel@tonic-gate char *name, char *realm, int attrs, int lifetime); 570Sstevel@tonic-gate int 580Sstevel@tonic-gate add_admin_sname_princ(void *handle, krb5_context context, 590Sstevel@tonic-gate char *sname, int attrs, int lifetime); 600Sstevel@tonic-gate int 610Sstevel@tonic-gate add_admin_princ(void *handle, krb5_context context, 620Sstevel@tonic-gate krb5_principal principal, int attrs, int lifetime); 630Sstevel@tonic-gate 64*2881Smp153739 static int add_admin_princs(void *handle, krb5_context context, char *realm); 65*2881Smp153739 66*2881Smp153739 #define ERR 1 67*2881Smp153739 #define OK 0 680Sstevel@tonic-gate 690Sstevel@tonic-gate #define ADMIN_LIFETIME 60*60*3 /* 3 hours */ 700Sstevel@tonic-gate #define CHANGEPW_LIFETIME 60*5 /* 5 minutes */ 710Sstevel@tonic-gate 720Sstevel@tonic-gate extern char *progname; 730Sstevel@tonic-gate 740Sstevel@tonic-gate /* 750Sstevel@tonic-gate * Function: kadm5_create 760Sstevel@tonic-gate * 770Sstevel@tonic-gate * Purpose: create admin principals in KDC database 780Sstevel@tonic-gate * 790Sstevel@tonic-gate * Arguments: params (r) configuration parameters to use 800Sstevel@tonic-gate * 810Sstevel@tonic-gate * Effects: Creates KADM5_ADMIN_SERVICE and KADM5_CHANGEPW_SERVICE 820Sstevel@tonic-gate * principals in the KDC database and sets their attributes 830Sstevel@tonic-gate * appropriately. 840Sstevel@tonic-gate */ 85*2881Smp153739 int kadm5_create(kadm5_config_params *params) 860Sstevel@tonic-gate { 870Sstevel@tonic-gate int retval; 880Sstevel@tonic-gate krb5_context context; 890Sstevel@tonic-gate 900Sstevel@tonic-gate kadm5_config_params lparams; 910Sstevel@tonic-gate 92*2881Smp153739 if ((retval = krb5_init_context(&context))) 93*2881Smp153739 exit(ERR); 940Sstevel@tonic-gate 950Sstevel@tonic-gate (void) memset(&lparams, 0, sizeof (kadm5_config_params)); 960Sstevel@tonic-gate 970Sstevel@tonic-gate /* 980Sstevel@tonic-gate * The lock file has to exist before calling kadm5_init, but 990Sstevel@tonic-gate * params->admin_lockfile may not be set yet... 1000Sstevel@tonic-gate */ 101*2881Smp153739 if ((retval = kadm5_get_config_params(context, NULL, NULL, 102*2881Smp153739 params, &lparams))) { 103*2881Smp153739 com_err(progname, retval, gettext("while looking up the Kerberos configuration")); 104*2881Smp153739 return 1; 1050Sstevel@tonic-gate } 106*2881Smp153739 107*2881Smp153739 if ((retval = osa_adb_create_policy_db(&lparams))) { 1080Sstevel@tonic-gate com_err(progname, retval, gettext(str_CREATING_POLICY_DB)); 109*2881Smp153739 return 1; 1100Sstevel@tonic-gate } 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate retval = kadm5_create_magic_princs(&lparams, context); 1130Sstevel@tonic-gate 1140Sstevel@tonic-gate kadm5_free_config_params(context, &lparams); 1150Sstevel@tonic-gate krb5_free_context(context); 1160Sstevel@tonic-gate 117*2881Smp153739 return retval; 1180Sstevel@tonic-gate } 1190Sstevel@tonic-gate 120*2881Smp153739 int kadm5_create_magic_princs(kadm5_config_params *params, 121*2881Smp153739 krb5_context context) 1220Sstevel@tonic-gate { 1230Sstevel@tonic-gate int retval; 1240Sstevel@tonic-gate void *handle; 1250Sstevel@tonic-gate 126*2881Smp153739 retval = krb5_klog_init(context, "admin_server", progname, 0); 127*2881Smp153739 if (retval) 128*2881Smp153739 return retval; 1290Sstevel@tonic-gate if ((retval = kadm5_init(progname, NULL, NULL, params, 1300Sstevel@tonic-gate KADM5_STRUCT_VERSION, 1310Sstevel@tonic-gate KADM5_API_VERSION_2, 1320Sstevel@tonic-gate &handle))) { 133*2881Smp153739 com_err(progname, retval, gettext("while initializing the Kerberos admin interface")); 134*2881Smp153739 return retval; 1350Sstevel@tonic-gate } 136*2881Smp153739 1370Sstevel@tonic-gate retval = add_admin_princs(handle, context, params->realm); 1380Sstevel@tonic-gate 1390Sstevel@tonic-gate kadm5_destroy(handle); 1400Sstevel@tonic-gate 141*2881Smp153739 krb5_klog_close(context); 142*2881Smp153739 143*2881Smp153739 return retval; 1440Sstevel@tonic-gate } 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate /* 1470Sstevel@tonic-gate * Function: build_name_with_realm 1480Sstevel@tonic-gate * 1490Sstevel@tonic-gate * Purpose: concatenate a name and a realm to form a krb5 name 1500Sstevel@tonic-gate * 1510Sstevel@tonic-gate * Arguments: 1520Sstevel@tonic-gate * 1530Sstevel@tonic-gate * name (input) the name 1540Sstevel@tonic-gate * realm (input) the realm 1550Sstevel@tonic-gate * 1560Sstevel@tonic-gate * Returns: 1570Sstevel@tonic-gate * 1580Sstevel@tonic-gate * pointer to name@realm, in allocated memory, or NULL if it 1590Sstevel@tonic-gate * cannot be allocated 1600Sstevel@tonic-gate * 1610Sstevel@tonic-gate * Requires: both strings are null-terminated 1620Sstevel@tonic-gate */ 163*2881Smp153739 static char *build_name_with_realm(char *name, char *realm) 1640Sstevel@tonic-gate { 1650Sstevel@tonic-gate char *n; 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate n = (char *) malloc(strlen(name) + strlen(realm) + 2); 1680Sstevel@tonic-gate sprintf(n, "%s@%s", name, realm); 169*2881Smp153739 return n; 1700Sstevel@tonic-gate } 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate /* 1730Sstevel@tonic-gate * Function: add_admin_princs 1740Sstevel@tonic-gate * 1750Sstevel@tonic-gate * Purpose: create admin principals 1760Sstevel@tonic-gate * 1770Sstevel@tonic-gate * Arguments: 1780Sstevel@tonic-gate * 1790Sstevel@tonic-gate * rseed (input) random seed 1800Sstevel@tonic-gate * realm (input) realm, or NULL for default realm 1810Sstevel@tonic-gate * <return value> (output) status, 0 for success, 1 for serious error 1820Sstevel@tonic-gate * 1830Sstevel@tonic-gate * Requires: 1840Sstevel@tonic-gate * 1850Sstevel@tonic-gate * Effects: 1860Sstevel@tonic-gate * 1870Sstevel@tonic-gate * add_admin_princs creates KADM5_ADMIN_SERVICE, 1880Sstevel@tonic-gate * KADM5_CHANGEPW_SERVICE. If any of these exist a message is 1890Sstevel@tonic-gate * printed. If any of these existing principal do not have the proper 1900Sstevel@tonic-gate * attributes, a warning message is printed. 1910Sstevel@tonic-gate */ 192*2881Smp153739 static int add_admin_princs(void *handle, krb5_context context, char *realm) 1930Sstevel@tonic-gate { 1940Sstevel@tonic-gate krb5_error_code ret = 0; 1951508Smp153739 1961508Smp153739 /* 1971508Smp153739 * Solaris Kerberos: 1981508Smp153739 * The kadmin/admin principal is unused on Solaris. This principal is used 1991508Smp153739 * in AUTH_GSSAPI but Solaris doesn't support AUTH_GSSAPI. RPCSEC_GSS can only 2001508Smp153739 * be used with host-based principals. 2011508Smp153739 * 2021508Smp153739 */ 2031508Smp153739 2041508Smp153739 #if 0 2051508Smp153739 if ((ret = add_admin_old_princ(handle, context, 2061508Smp153739 KADM5_ADMIN_SERVICE, realm, 2071508Smp153739 KRB5_KDB_DISALLOW_TGT_BASED, 2081508Smp153739 ADMIN_LIFETIME))) 2091508Smp153739 goto clean_and_exit; 2101508Smp153739 #endif 2110Sstevel@tonic-gate 2120Sstevel@tonic-gate if ((ret = add_admin_old_princ(handle, context, 2130Sstevel@tonic-gate KADM5_CHANGEPW_SERVICE, realm, 2140Sstevel@tonic-gate KRB5_KDB_DISALLOW_TGT_BASED | 2150Sstevel@tonic-gate KRB5_KDB_PWCHANGE_SERVICE, 2160Sstevel@tonic-gate CHANGEPW_LIFETIME))) 2170Sstevel@tonic-gate goto clean_and_exit; 2180Sstevel@tonic-gate 2190Sstevel@tonic-gate if ((ret = add_admin_sname_princ(handle, context, 2200Sstevel@tonic-gate KADM5_ADMIN_HOST_SERVICE, 2210Sstevel@tonic-gate KRB5_KDB_DISALLOW_TGT_BASED, 2220Sstevel@tonic-gate ADMIN_LIFETIME))) 2230Sstevel@tonic-gate goto clean_and_exit; 2240Sstevel@tonic-gate 2250Sstevel@tonic-gate if ((ret = add_admin_sname_princ(handle, context, 2260Sstevel@tonic-gate KADM5_CHANGEPW_HOST_SERVICE, 2270Sstevel@tonic-gate KRB5_KDB_DISALLOW_TGT_BASED | 2280Sstevel@tonic-gate KRB5_KDB_PWCHANGE_SERVICE, 2290Sstevel@tonic-gate ADMIN_LIFETIME))) 2300Sstevel@tonic-gate goto clean_and_exit; 2310Sstevel@tonic-gate 2321508Smp153739 if ((ret = add_admin_sname_princ(handle, context, 2331508Smp153739 KADM5_KIPROP_HOST_SERVICE, 2341508Smp153739 KRB5_KDB_DISALLOW_TGT_BASED, 2351508Smp153739 ADMIN_LIFETIME))) 2361508Smp153739 goto clean_and_exit; 2371508Smp153739 2380Sstevel@tonic-gate clean_and_exit: 2390Sstevel@tonic-gate 240*2881Smp153739 return ret; 2410Sstevel@tonic-gate } 2420Sstevel@tonic-gate 2430Sstevel@tonic-gate /* 2440Sstevel@tonic-gate * Function: add_admin_princ 2450Sstevel@tonic-gate * 2460Sstevel@tonic-gate * Arguments: 2470Sstevel@tonic-gate * 2480Sstevel@tonic-gate * creator (r) principal to use as "mod_by" 2490Sstevel@tonic-gate * rseed (r) seed for random key generator 2500Sstevel@tonic-gate * principal (r) kerberos principal to add 2510Sstevel@tonic-gate * attrs (r) principal's attributes 2520Sstevel@tonic-gate * lifetime (r) principal's max life, or 0 2530Sstevel@tonic-gate * not_unique (r) error message for multiple entries, never used 2540Sstevel@tonic-gate * exists (r) warning message for principal exists 2550Sstevel@tonic-gate * wrong_attrs (r) warning message for wrong attributes 2560Sstevel@tonic-gate * 2570Sstevel@tonic-gate * Returns: 2580Sstevel@tonic-gate * 259*2881Smp153739 * OK on success 260*2881Smp153739 * ERR on serious errors 2610Sstevel@tonic-gate * 2620Sstevel@tonic-gate * Effects: 2630Sstevel@tonic-gate * 2640Sstevel@tonic-gate * If the principal is not unique, not_unique is printed (but this 2650Sstevel@tonic-gate * never happens). If the principal exists, then exists is printed 2660Sstevel@tonic-gate * and if the principals attributes != attrs, wrong_attrs is printed. 2670Sstevel@tonic-gate * Otherwise, the principal is created with mod_by creator and 2680Sstevel@tonic-gate * attributes attrs and max life of lifetime (if not zero). 2690Sstevel@tonic-gate */ 2700Sstevel@tonic-gate 271*2881Smp153739 int add_admin_princ(void *handle, krb5_context context, 2720Sstevel@tonic-gate krb5_principal principal, int attrs, int lifetime) 2730Sstevel@tonic-gate { 2740Sstevel@tonic-gate char *fullname; 2750Sstevel@tonic-gate krb5_error_code ret; 2760Sstevel@tonic-gate kadm5_principal_ent_rec ent; 2770Sstevel@tonic-gate 2780Sstevel@tonic-gate memset(&ent, 0, sizeof(ent)); 2790Sstevel@tonic-gate 2800Sstevel@tonic-gate if (krb5_unparse_name(context, principal, &fullname)) 281*2881Smp153739 return ERR; 2820Sstevel@tonic-gate 2830Sstevel@tonic-gate ent.principal = principal; 2840Sstevel@tonic-gate ent.max_life = lifetime; 2850Sstevel@tonic-gate ent.attributes = attrs | KRB5_KDB_DISALLOW_ALL_TIX; 2860Sstevel@tonic-gate 287*2881Smp153739 ret = kadm5_create_principal(handle, &ent, 288*2881Smp153739 (KADM5_PRINCIPAL | KADM5_MAX_LIFE | 289*2881Smp153739 KADM5_ATTRIBUTES), 290*2881Smp153739 "to-be-random"); 291*2881Smp153739 if (ret) { 2920Sstevel@tonic-gate if (ret != KADM5_DUP) { 2930Sstevel@tonic-gate com_err(progname, ret, 2940Sstevel@tonic-gate gettext(str_PUT_PRINC), fullname); 2950Sstevel@tonic-gate krb5_free_principal(context, ent.principal); 2960Sstevel@tonic-gate free(fullname); 297*2881Smp153739 return ERR; 2980Sstevel@tonic-gate } 2990Sstevel@tonic-gate } else { 3000Sstevel@tonic-gate /* only randomize key if we created the principal */ 3010Sstevel@tonic-gate ret = kadm5_randkey_principal(handle, ent.principal, NULL, NULL); 3020Sstevel@tonic-gate if (ret) { 3030Sstevel@tonic-gate com_err(progname, ret, 3040Sstevel@tonic-gate gettext(str_RANDOM_KEY), fullname); 305*2881Smp153739 krb5_free_principal(context, ent.principal); 306*2881Smp153739 free(fullname); 307*2881Smp153739 return ERR; 308*2881Smp153739 } 309*2881Smp153739 310*2881Smp153739 ent.attributes = attrs; 311*2881Smp153739 ret = kadm5_modify_principal(handle, &ent, KADM5_ATTRIBUTES); 312*2881Smp153739 if (ret) { 313*2881Smp153739 com_err(progname, ret, 314*2881Smp153739 gettext(str_PUT_PRINC), fullname); 315*2881Smp153739 krb5_free_principal(context, ent.principal); 316*2881Smp153739 free(fullname); 317*2881Smp153739 return ERR; 318*2881Smp153739 } 319*2881Smp153739 } 3200Sstevel@tonic-gate 321*2881Smp153739 krb5_free_principal(context, ent.principal); 322*2881Smp153739 free(fullname); 3230Sstevel@tonic-gate 324*2881Smp153739 return OK; 3250Sstevel@tonic-gate } 3260Sstevel@tonic-gate 3270Sstevel@tonic-gate int 3280Sstevel@tonic-gate add_admin_old_princ(void *handle, krb5_context context, 3290Sstevel@tonic-gate char *name, char *realm, int attrs, int lifetime) 3300Sstevel@tonic-gate { 3310Sstevel@tonic-gate char *fullname; 3320Sstevel@tonic-gate krb5_error_code ret; 3330Sstevel@tonic-gate krb5_principal principal; 3340Sstevel@tonic-gate 3350Sstevel@tonic-gate fullname = build_name_with_realm(name, realm); 3360Sstevel@tonic-gate if (ret = krb5_parse_name(context, fullname, &principal)) { 3370Sstevel@tonic-gate com_err(progname, ret, gettext(str_PARSE_NAME)); 338*2881Smp153739 return (ERR); 3390Sstevel@tonic-gate } 3400Sstevel@tonic-gate 3410Sstevel@tonic-gate return (add_admin_princ(handle, context, principal, attrs, lifetime)); 3420Sstevel@tonic-gate } 3430Sstevel@tonic-gate 3440Sstevel@tonic-gate int 3450Sstevel@tonic-gate add_admin_sname_princ(void *handle, krb5_context context, 3460Sstevel@tonic-gate char *sname, int attrs, int lifetime) 3470Sstevel@tonic-gate { 3480Sstevel@tonic-gate krb5_error_code ret; 3490Sstevel@tonic-gate krb5_principal principal; 3500Sstevel@tonic-gate 3510Sstevel@tonic-gate if (ret = krb5_sname_to_principal(context, NULL, sname, 3520Sstevel@tonic-gate KRB5_NT_SRV_HST, &principal)) { 3530Sstevel@tonic-gate com_err(progname, ret, 3540Sstevel@tonic-gate gettext("Could not get host based " 3550Sstevel@tonic-gate "service name for %s principal\n"), sname); 356*2881Smp153739 return (ERR); 3570Sstevel@tonic-gate } 3580Sstevel@tonic-gate return (add_admin_princ(handle, context, principal, attrs, lifetime)); 3590Sstevel@tonic-gate } 3600Sstevel@tonic-gate 3610Sstevel@tonic-gate 3620Sstevel@tonic-gate 363