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