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