1 /* 2 * Copyright (c) 1997 - 2002 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.17 2002/08/26 13:28:36 assar 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 const 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, 135 &top_binding, 136 krb5_config_list, 137 "kdc", 138 "database", 139 NULL))) { 140 const char *p; 141 p = krb5_config_get_string(context, db_binding, "realm", NULL); 142 if(p == NULL) { 143 if(default_binding) { 144 krb5_warnx(context, "WARNING: more than one realm-less " 145 "database specification"); 146 krb5_warnx(context, "WARNING: using the first encountered"); 147 } else 148 default_binding = db_binding; 149 continue; 150 } 151 if(strcmp(ctx->config.realm, p) != 0) 152 continue; 153 154 set_config(ctx, db_binding); 155 return 0; 156 } 157 if(default_binding) 158 set_config(ctx, default_binding); 159 else { 160 ctx->config.dbname = strdup(HDB_DEFAULT_DB); 161 ctx->config.acl_file = strdup(HDB_DB_DIR "/kadmind.acl"); 162 ctx->config.stash_file = strdup(HDB_DB_DIR "/m-key"); 163 ctx->log_context.log_file = strdup(HDB_DB_DIR "/log"); 164 memset(&ctx->log_context.socket_name, 0, 165 sizeof(ctx->log_context.socket_name)); 166 ctx->log_context.socket_name.sun_family = AF_UNIX; 167 strlcpy(ctx->log_context.socket_name.sun_path, 168 KADM5_LOG_SIGNAL, 169 sizeof(ctx->log_context.socket_name.sun_path)); 170 } 171 return 0; 172 } 173 174 kadm5_ret_t 175 _kadm5_s_init_context(kadm5_server_context **ctx, 176 kadm5_config_params *params, 177 krb5_context context) 178 { 179 *ctx = malloc(sizeof(**ctx)); 180 if(*ctx == NULL) 181 return ENOMEM; 182 memset(*ctx, 0, sizeof(**ctx)); 183 set_funcs(*ctx); 184 (*ctx)->context = context; 185 krb5_add_et_list (context, initialize_kadm5_error_table_r); 186 #define is_set(M) (params && params->mask & KADM5_CONFIG_ ## M) 187 if(is_set(REALM)) 188 (*ctx)->config.realm = strdup(params->realm); 189 else 190 krb5_get_default_realm(context, &(*ctx)->config.realm); 191 if(is_set(DBNAME)) 192 (*ctx)->config.dbname = strdup(params->dbname); 193 if(is_set(ACL_FILE)) 194 (*ctx)->config.acl_file = strdup(params->acl_file); 195 if(is_set(STASH_FILE)) 196 (*ctx)->config.stash_file = strdup(params->stash_file); 197 198 find_db_spec(*ctx); 199 200 /* PROFILE can't be specified for now */ 201 /* KADMIND_PORT is supposed to be used on the server also, 202 but this doesn't make sense */ 203 /* ADMIN_SERVER is client only */ 204 /* ADNAME is not used at all (as far as I can tell) */ 205 /* ADB_LOCKFILE ditto */ 206 /* DICT_FILE */ 207 /* ADMIN_KEYTAB */ 208 /* MKEY_FROM_KEYBOARD is not supported */ 209 /* MKEY_NAME neither */ 210 /* ENCTYPE */ 211 /* MAX_LIFE */ 212 /* MAX_RLIFE */ 213 /* EXPIRATION */ 214 /* FLAGS */ 215 /* ENCTYPES */ 216 217 return 0; 218 } 219 220 HDB * 221 _kadm5_s_get_db(void *server_handle) 222 { 223 kadm5_server_context *context = server_handle; 224 return context->db; 225 } 226