1 /* 2 * Copyright (c) 1997 - 2000 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "kadm5_locl.h" 35 36 RCSID("$Id: context_s.c,v 1.16 2001/08/13 14:42:13 joda Exp $"); 37 38 static void 39 set_funcs(kadm5_server_context *c) 40 { 41 #define SET(C, F) (C)->funcs.F = kadm5_s_ ## F 42 SET(c, chpass_principal); 43 SET(c, chpass_principal_with_key); 44 SET(c, create_principal); 45 SET(c, delete_principal); 46 SET(c, destroy); 47 SET(c, flush); 48 SET(c, get_principal); 49 SET(c, get_principals); 50 SET(c, get_privs); 51 SET(c, modify_principal); 52 SET(c, randkey_principal); 53 SET(c, rename_principal); 54 } 55 56 struct database_spec { 57 char *dbpath; 58 char *logfile; 59 char *mkeyfile; 60 char *aclfile; 61 }; 62 63 static void 64 set_field(krb5_context context, krb5_config_binding *binding, 65 const char *dbname, const char *name, const char *ext, 66 char **variable) 67 { 68 const char *p; 69 70 if (*variable != NULL) 71 free (*variable); 72 73 p = krb5_config_get_string(context, binding, name, NULL); 74 if(p) 75 *variable = strdup(p); 76 else { 77 p = strrchr(dbname, '.'); 78 if(p == NULL) 79 asprintf(variable, "%s.%s", dbname, ext); 80 else 81 asprintf(variable, "%.*s.%s", (int)(p - dbname), dbname, ext); 82 } 83 } 84 85 static void 86 set_socket_name(const char *dbname, struct sockaddr_un *un) 87 { 88 const char *p; 89 memset(un, 0, sizeof(*un)); 90 un->sun_family = AF_UNIX; 91 p = strrchr(dbname, '.'); 92 if(p == NULL) 93 snprintf(un->sun_path, sizeof(un->sun_path), "%s.signal", 94 dbname); 95 else 96 snprintf(un->sun_path, sizeof(un->sun_path), "%.*s.signal", 97 (int)(p - dbname), dbname); 98 } 99 100 static void 101 set_config(kadm5_server_context *ctx, 102 krb5_config_binding *binding) 103 { 104 const char *p; 105 if(ctx->config.dbname == NULL) { 106 p = krb5_config_get_string(ctx->context, binding, "dbname", NULL); 107 if(p) 108 ctx->config.dbname = strdup(p); 109 else 110 ctx->config.dbname = strdup(HDB_DEFAULT_DB); 111 } 112 if(ctx->log_context.log_file == NULL) 113 set_field(ctx->context, binding, ctx->config.dbname, 114 "log_file", "log", &ctx->log_context.log_file); 115 set_socket_name(ctx->config.dbname, &ctx->log_context.socket_name); 116 if(ctx->config.acl_file == NULL) 117 set_field(ctx->context, binding, ctx->config.dbname, 118 "acl_file", "acl", &ctx->config.acl_file); 119 if(ctx->config.stash_file == NULL) 120 set_field(ctx->context, binding, ctx->config.dbname, 121 "mkey_file", "mkey", &ctx->config.stash_file); 122 } 123 124 static kadm5_ret_t 125 find_db_spec(kadm5_server_context *ctx) 126 { 127 krb5_config_binding *top_binding = NULL; 128 krb5_config_binding *db_binding; 129 krb5_config_binding *default_binding = NULL; 130 krb5_context context = ctx->context; 131 132 while((db_binding = (krb5_config_binding *) 133 krb5_config_get_next(context, 134 NULL, &top_binding, 135 krb5_config_list, 136 "kdc", 137 "database", 138 NULL))) { 139 const char *p; 140 p = krb5_config_get_string(context, db_binding, "realm", NULL); 141 if(p == NULL) { 142 if(default_binding) { 143 krb5_warnx(context, "WARNING: more than one realm-less " 144 "database specification"); 145 krb5_warnx(context, "WARNING: using the first encountered"); 146 } else 147 default_binding = db_binding; 148 continue; 149 } 150 if(strcmp(ctx->config.realm, p) != 0) 151 continue; 152 153 set_config(ctx, db_binding); 154 return 0; 155 } 156 if(default_binding) 157 set_config(ctx, default_binding); 158 else { 159 ctx->config.dbname = strdup(HDB_DEFAULT_DB); 160 ctx->config.acl_file = strdup(HDB_DB_DIR "/kadmind.acl"); 161 ctx->config.stash_file = strdup(HDB_DB_DIR "/m-key"); 162 ctx->log_context.log_file = strdup(HDB_DB_DIR "/log"); 163 memset(&ctx->log_context.socket_name, 0, 164 sizeof(ctx->log_context.socket_name)); 165 ctx->log_context.socket_name.sun_family = AF_UNIX; 166 strlcpy(ctx->log_context.socket_name.sun_path, 167 KADM5_LOG_SIGNAL, 168 sizeof(ctx->log_context.socket_name.sun_path)); 169 } 170 return 0; 171 } 172 173 kadm5_ret_t 174 _kadm5_s_init_context(kadm5_server_context **ctx, 175 kadm5_config_params *params, 176 krb5_context context) 177 { 178 *ctx = malloc(sizeof(**ctx)); 179 if(*ctx == NULL) 180 return ENOMEM; 181 memset(*ctx, 0, sizeof(**ctx)); 182 set_funcs(*ctx); 183 (*ctx)->context = context; 184 krb5_add_et_list (context, initialize_kadm5_error_table_r); 185 #define is_set(M) (params && params->mask & KADM5_CONFIG_ ## M) 186 if(is_set(REALM)) 187 (*ctx)->config.realm = strdup(params->realm); 188 else 189 krb5_get_default_realm(context, &(*ctx)->config.realm); 190 if(is_set(DBNAME)) 191 (*ctx)->config.dbname = strdup(params->dbname); 192 if(is_set(ACL_FILE)) 193 (*ctx)->config.acl_file = strdup(params->acl_file); 194 if(is_set(STASH_FILE)) 195 (*ctx)->config.stash_file = strdup(params->stash_file); 196 197 find_db_spec(*ctx); 198 199 /* PROFILE can't be specified for now */ 200 /* KADMIND_PORT is supposed to be used on the server also, 201 but this doesn't make sense */ 202 /* ADMIN_SERVER is client only */ 203 /* ADNAME is not used at all (as far as I can tell) */ 204 /* ADB_LOCKFILE ditto */ 205 /* DICT_FILE */ 206 /* ADMIN_KEYTAB */ 207 /* MKEY_FROM_KEYBOARD is not supported */ 208 /* MKEY_NAME neither */ 209 /* ENCTYPE */ 210 /* MAX_LIFE */ 211 /* MAX_RLIFE */ 212 /* EXPIRATION */ 213 /* FLAGS */ 214 /* ENCTYPES */ 215 216 return 0; 217 } 218 219 HDB * 220 _kadm5_s_get_db(void *server_handle) 221 { 222 kadm5_server_context *context = server_handle; 223 return context->db; 224 } 225