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