1 /* 2 * Copyright 2006 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 #include "string_table.h" 41 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <kadm5/adb.h> 46 #include <kadm5/admin.h> 47 #include <krb5/adm_proto.h> 48 49 50 #include <krb5.h> 51 #include <krb5/kdb.h> 52 #include <libintl.h> 53 54 int 55 add_admin_old_princ(void *handle, krb5_context context, 56 char *name, char *realm, int attrs, int lifetime); 57 int 58 add_admin_sname_princ(void *handle, krb5_context context, 59 char *sname, int attrs, int lifetime); 60 int 61 add_admin_princ(void *handle, krb5_context context, 62 krb5_principal principal, int attrs, int lifetime); 63 64 static int add_admin_princs(void *handle, krb5_context context, char *realm); 65 66 #define ERR 1 67 #define 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 kadm5_create(kadm5_config_params *params) 86 { 87 int retval; 88 krb5_context context; 89 90 kadm5_config_params lparams; 91 92 if ((retval = krb5_init_context(&context))) 93 exit(ERR); 94 95 (void) memset(&lparams, 0, sizeof (kadm5_config_params)); 96 97 /* 98 * The lock file has to exist before calling kadm5_init, but 99 * params->admin_lockfile may not be set yet... 100 */ 101 if ((retval = kadm5_get_config_params(context, NULL, NULL, 102 params, &lparams))) { 103 com_err(progname, retval, gettext("while looking up the Kerberos configuration")); 104 return 1; 105 } 106 107 if ((retval = osa_adb_create_policy_db(&lparams))) { 108 com_err(progname, retval, gettext(str_CREATING_POLICY_DB)); 109 return 1; 110 } 111 112 retval = kadm5_create_magic_princs(&lparams, context); 113 114 kadm5_free_config_params(context, &lparams); 115 krb5_free_context(context); 116 117 return retval; 118 } 119 120 int kadm5_create_magic_princs(kadm5_config_params *params, 121 krb5_context context) 122 { 123 int retval; 124 void *handle; 125 126 retval = krb5_klog_init(context, "admin_server", progname, 0); 127 if (retval) 128 return retval; 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("while initializing the Kerberos admin interface")); 134 return retval; 135 } 136 137 retval = add_admin_princs(handle, context, params->realm); 138 139 kadm5_destroy(handle); 140 141 krb5_klog_close(context); 142 143 return retval; 144 } 145 146 /* 147 * Function: build_name_with_realm 148 * 149 * Purpose: concatenate a name and a realm to form a krb5 name 150 * 151 * Arguments: 152 * 153 * name (input) the name 154 * realm (input) the realm 155 * 156 * Returns: 157 * 158 * pointer to name@realm, in allocated memory, or NULL if it 159 * cannot be allocated 160 * 161 * Requires: both strings are null-terminated 162 */ 163 static char *build_name_with_realm(char *name, char *realm) 164 { 165 char *n; 166 167 n = (char *) malloc(strlen(name) + strlen(realm) + 2); 168 sprintf(n, "%s@%s", name, realm); 169 return n; 170 } 171 172 /* 173 * Function: add_admin_princs 174 * 175 * Purpose: create admin principals 176 * 177 * Arguments: 178 * 179 * rseed (input) random seed 180 * realm (input) realm, or NULL for default realm 181 * <return value> (output) status, 0 for success, 1 for serious error 182 * 183 * Requires: 184 * 185 * Effects: 186 * 187 * add_admin_princs creates KADM5_ADMIN_SERVICE, 188 * KADM5_CHANGEPW_SERVICE. If any of these exist a message is 189 * printed. If any of these existing principal do not have the proper 190 * attributes, a warning message is printed. 191 */ 192 static int add_admin_princs(void *handle, krb5_context context, char *realm) 193 { 194 krb5_error_code ret = 0; 195 196 /* 197 * Solaris Kerberos: 198 * The kadmin/admin principal is unused on Solaris. This principal is used 199 * in AUTH_GSSAPI but Solaris doesn't support AUTH_GSSAPI. RPCSEC_GSS can only 200 * be used with host-based principals. 201 * 202 */ 203 204 #if 0 205 if ((ret = add_admin_old_princ(handle, context, 206 KADM5_ADMIN_SERVICE, realm, 207 KRB5_KDB_DISALLOW_TGT_BASED, 208 ADMIN_LIFETIME))) 209 goto clean_and_exit; 210 #endif 211 212 if ((ret = add_admin_old_princ(handle, context, 213 KADM5_CHANGEPW_SERVICE, realm, 214 KRB5_KDB_DISALLOW_TGT_BASED | 215 KRB5_KDB_PWCHANGE_SERVICE, 216 CHANGEPW_LIFETIME))) 217 goto clean_and_exit; 218 219 if ((ret = add_admin_sname_princ(handle, context, 220 KADM5_ADMIN_HOST_SERVICE, 221 KRB5_KDB_DISALLOW_TGT_BASED, 222 ADMIN_LIFETIME))) 223 goto clean_and_exit; 224 225 if ((ret = add_admin_sname_princ(handle, context, 226 KADM5_CHANGEPW_HOST_SERVICE, 227 KRB5_KDB_DISALLOW_TGT_BASED | 228 KRB5_KDB_PWCHANGE_SERVICE, 229 ADMIN_LIFETIME))) 230 goto clean_and_exit; 231 232 if ((ret = add_admin_sname_princ(handle, context, 233 KADM5_KIPROP_HOST_SERVICE, 234 KRB5_KDB_DISALLOW_TGT_BASED, 235 ADMIN_LIFETIME))) 236 goto clean_and_exit; 237 238 clean_and_exit: 239 240 return ret; 241 } 242 243 /* 244 * Function: add_admin_princ 245 * 246 * Arguments: 247 * 248 * creator (r) principal to use as "mod_by" 249 * rseed (r) seed for random key generator 250 * principal (r) kerberos principal to add 251 * attrs (r) principal's attributes 252 * lifetime (r) principal's max life, or 0 253 * not_unique (r) error message for multiple entries, never used 254 * exists (r) warning message for principal exists 255 * wrong_attrs (r) warning message for wrong attributes 256 * 257 * Returns: 258 * 259 * OK on success 260 * ERR on serious errors 261 * 262 * Effects: 263 * 264 * If the principal is not unique, not_unique is printed (but this 265 * never happens). If the principal exists, then exists is printed 266 * and if the principals attributes != attrs, wrong_attrs is printed. 267 * Otherwise, the principal is created with mod_by creator and 268 * attributes attrs and max life of lifetime (if not zero). 269 */ 270 271 int add_admin_princ(void *handle, krb5_context context, 272 krb5_principal principal, int attrs, int lifetime) 273 { 274 char *fullname; 275 krb5_error_code ret; 276 kadm5_principal_ent_rec ent; 277 278 memset(&ent, 0, sizeof(ent)); 279 280 if (krb5_unparse_name(context, principal, &fullname)) 281 return ERR; 282 283 ent.principal = principal; 284 ent.max_life = lifetime; 285 ent.attributes = attrs | KRB5_KDB_DISALLOW_ALL_TIX; 286 287 ret = kadm5_create_principal(handle, &ent, 288 (KADM5_PRINCIPAL | KADM5_MAX_LIFE | 289 KADM5_ATTRIBUTES), 290 "to-be-random"); 291 if (ret) { 292 if (ret != KADM5_DUP) { 293 com_err(progname, ret, 294 gettext(str_PUT_PRINC), fullname); 295 krb5_free_principal(context, ent.principal); 296 free(fullname); 297 return ERR; 298 } 299 } else { 300 /* only randomize key if we created the principal */ 301 ret = kadm5_randkey_principal(handle, ent.principal, NULL, NULL); 302 if (ret) { 303 com_err(progname, ret, 304 gettext(str_RANDOM_KEY), fullname); 305 krb5_free_principal(context, ent.principal); 306 free(fullname); 307 return ERR; 308 } 309 310 ent.attributes = attrs; 311 ret = kadm5_modify_principal(handle, &ent, KADM5_ATTRIBUTES); 312 if (ret) { 313 com_err(progname, ret, 314 gettext(str_PUT_PRINC), fullname); 315 krb5_free_principal(context, ent.principal); 316 free(fullname); 317 return ERR; 318 } 319 } 320 321 krb5_free_principal(context, ent.principal); 322 free(fullname); 323 324 return OK; 325 } 326 327 int 328 add_admin_old_princ(void *handle, krb5_context context, 329 char *name, char *realm, int attrs, int lifetime) 330 { 331 char *fullname; 332 krb5_error_code ret; 333 krb5_principal principal; 334 335 fullname = build_name_with_realm(name, realm); 336 if (ret = krb5_parse_name(context, fullname, &principal)) { 337 com_err(progname, ret, gettext(str_PARSE_NAME)); 338 return (ERR); 339 } 340 341 return (add_admin_princ(handle, context, principal, attrs, lifetime)); 342 } 343 344 int 345 add_admin_sname_princ(void *handle, krb5_context context, 346 char *sname, int attrs, int lifetime) 347 { 348 krb5_error_code ret; 349 krb5_principal principal; 350 351 if (ret = krb5_sname_to_principal(context, NULL, sname, 352 KRB5_NT_SRV_HST, &principal)) { 353 com_err(progname, ret, 354 gettext("Could not get host based " 355 "service name for %s principal\n"), sname); 356 return (ERR); 357 } 358 return (add_admin_princ(handle, context, principal, attrs, lifetime)); 359 } 360 361 362 363