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.13 2000/01/06 21:40:08 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); 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 p = krb5_config_get_string(context, binding, name, NULL); 70 if(p) 71 *variable = strdup(p); 72 else { 73 p = strrchr(dbname, '.'); 74 if(p == NULL) 75 asprintf(variable, "%s.%s", dbname, ext); 76 else 77 asprintf(variable, "%.*s.%s", (int)(p - dbname), dbname, ext); 78 } 79 } 80 81 static void 82 set_socket_name(const char *dbname, struct sockaddr_un *un) 83 { 84 const char *p; 85 memset(un, 0, sizeof(*un)); 86 un->sun_family = AF_UNIX; 87 p = strrchr(dbname, '.'); 88 if(p == NULL) 89 snprintf(un->sun_path, sizeof(un->sun_path), "%s.signal", 90 dbname); 91 else 92 snprintf(un->sun_path, sizeof(un->sun_path), "%.*s.signal", 93 (int)(p - dbname), dbname); 94 } 95 96 static void 97 set_config(kadm5_server_context *ctx, 98 krb5_config_binding *binding) 99 { 100 const char *p; 101 if(ctx->config.dbname == NULL) { 102 p = krb5_config_get_string(ctx->context, binding, "dbname", NULL); 103 if(p) 104 ctx->config.dbname = strdup(p); 105 else 106 ctx->config.dbname = strdup(HDB_DEFAULT_DB); 107 } 108 if(ctx->log_context.log_file == NULL) 109 set_field(ctx->context, binding, ctx->config.dbname, 110 "log_file", "log", &ctx->log_context.log_file); 111 set_socket_name(ctx->config.dbname, &ctx->log_context.socket_name); 112 if(ctx->config.acl_file == NULL) 113 set_field(ctx->context, binding, ctx->config.dbname, 114 "acl_file", "acl", &ctx->config.acl_file); 115 /* XXX calling a file a `stash file' isn't very clever */ 116 if(ctx->config.stash_file == NULL) 117 set_field(ctx->context, binding, ctx->config.dbname, 118 "mkey_file", "mkey", &ctx->config.stash_file); 119 } 120 121 static kadm5_ret_t 122 find_db_spec(kadm5_server_context *ctx) 123 { 124 krb5_config_binding *top_binding = NULL; 125 krb5_config_binding *db_binding; 126 krb5_config_binding *default_binding = NULL; 127 krb5_context context = ctx->context; 128 129 while((db_binding = (krb5_config_binding *) 130 krb5_config_get_next(context, 131 NULL, &top_binding, 132 krb5_config_list, 133 "kdc", 134 "database", 135 NULL))) { 136 const char *p; 137 p = krb5_config_get_string(context, db_binding, "realm", NULL); 138 if(p == NULL) { 139 if(default_binding) { 140 krb5_warnx(context, "WARNING: more than one realm-less " 141 "database specification"); 142 krb5_warnx(context, "WARNING: using the first encountered"); 143 } else 144 default_binding = db_binding; 145 continue; 146 } 147 if(strcmp(ctx->config.realm, p) != 0) 148 continue; 149 150 set_config(ctx, db_binding); 151 return 0; 152 } 153 if(default_binding) 154 set_config(ctx, default_binding); 155 else { 156 ctx->config.dbname = strdup(HDB_DEFAULT_DB); 157 ctx->config.acl_file = HDB_DB_DIR "/kadmind.acl"; 158 ctx->config.stash_file = HDB_DB_DIR "/m-key"; 159 ctx->log_context.log_file = HDB_DB_DIR "/log"; 160 memset(&ctx->log_context.socket_name, 0, 161 sizeof(ctx->log_context.socket_name)); 162 ctx->log_context.socket_name.sun_family = AF_UNIX; 163 strlcpy(ctx->log_context.socket_name.sun_path, 164 KADM5_LOG_SIGNAL, 165 sizeof(ctx->log_context.socket_name.sun_path)); 166 } 167 return 0; 168 } 169 170 kadm5_ret_t 171 _kadm5_s_init_context(kadm5_server_context **ctx, 172 kadm5_config_params *params, 173 krb5_context context) 174 { 175 *ctx = malloc(sizeof(**ctx)); 176 if(*ctx == NULL) 177 return ENOMEM; 178 memset(*ctx, 0, sizeof(**ctx)); 179 set_funcs(*ctx); 180 (*ctx)->context = context; 181 krb5_add_et_list (context, initialize_kadm5_error_table_r); 182 #define is_set(M) (params && params->mask & KADM5_CONFIG_ ## M) 183 if(is_set(REALM)) 184 (*ctx)->config.realm = strdup(params->realm); 185 else 186 krb5_get_default_realm(context, &(*ctx)->config.realm); 187 if(is_set(DBNAME)) 188 (*ctx)->config.dbname = strdup(params->dbname); 189 if(is_set(ACL_FILE)) 190 (*ctx)->config.acl_file = strdup(params->acl_file); 191 if(is_set(STASH_FILE)) 192 (*ctx)->config.stash_file = strdup(params->stash_file); 193 194 find_db_spec(*ctx); 195 196 /* PROFILE can't be specified for now */ 197 /* KADMIND_PORT is supposed to be used on the server also, 198 but this doesn't make sense */ 199 /* ADMIN_SERVER is client only */ 200 /* ADNAME is not used at all (as far as I can tell) */ 201 /* ADB_LOCKFILE ditto */ 202 /* DICT_FILE */ 203 /* ADMIN_KEYTAB */ 204 /* MKEY_FROM_KEYBOARD is not supported */ 205 /* MKEY_NAME neither */ 206 /* ENCTYPE */ 207 /* MAX_LIFE */ 208 /* MAX_RLIFE */ 209 /* EXPIRATION */ 210 /* FLAGS */ 211 /* ENCTYPES */ 212 213 return 0; 214 } 215 216 HDB * 217 _kadm5_s_get_db(void *server_handle) 218 { 219 kadm5_server_context *context = server_handle; 220 return context->db; 221 } 222