1/* 2 * Copyright (c) 1997 - 1999 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 36RCSID("$Id$"); 37 38kadm5_ret_t 39kadm5_store_key_data(krb5_storage *sp, 40 krb5_key_data *key) 41{ 42 krb5_data c; 43 krb5_store_int32(sp, key->key_data_ver); 44 krb5_store_int32(sp, key->key_data_kvno); 45 krb5_store_int32(sp, key->key_data_type[0]); 46 c.length = key->key_data_length[0]; 47 c.data = key->key_data_contents[0]; 48 krb5_store_data(sp, c); 49 krb5_store_int32(sp, key->key_data_type[1]); 50 c.length = key->key_data_length[1]; 51 c.data = key->key_data_contents[1]; 52 krb5_store_data(sp, c); 53 return 0; 54} 55 56kadm5_ret_t 57kadm5_store_fake_key_data(krb5_storage *sp, 58 krb5_key_data *key) 59{ 60 char buf[4] = {0}; 61 krb5_data c; 62 63 krb5_store_int32(sp, key->key_data_ver); 64 krb5_store_int32(sp, key->key_data_kvno); 65 krb5_store_int32(sp, key->key_data_type[0]); 66 67 /* 68 * This is the key contents. We want it to be obvious to the client 69 * (if it really did want the keys) that the key won't work. 70 * 32-bit keys are no good for any enctype, so that should do. 71 * Clients that didn't need keys will ignore this, and clients that 72 * did want keys will either fail or they'll, say, create bogus 73 * keytab entries that will subsequently fail to be useful. 74 */ 75 c.length = sizeof (buf); 76 c.data = buf; 77 memset(buf, 0xdeadcee5, sizeof (buf)); /* bad bad hexspeak for deadkeys */ 78 krb5_store_data(sp, c); 79 80 /* This is the salt -- no need to send garbage */ 81 krb5_store_int32(sp, key->key_data_type[1]); 82 c.length = key->key_data_length[1]; 83 c.data = key->key_data_contents[1]; 84 krb5_store_data(sp, c); 85 return 0; 86} 87 88kadm5_ret_t 89kadm5_ret_key_data(krb5_storage *sp, 90 krb5_key_data *key) 91{ 92 krb5_data c; 93 int32_t tmp; 94 krb5_ret_int32(sp, &tmp); 95 key->key_data_ver = tmp; 96 krb5_ret_int32(sp, &tmp); 97 key->key_data_kvno = tmp; 98 krb5_ret_int32(sp, &tmp); 99 key->key_data_type[0] = tmp; 100 krb5_ret_data(sp, &c); 101 key->key_data_length[0] = c.length; 102 key->key_data_contents[0] = c.data; 103 krb5_ret_int32(sp, &tmp); 104 key->key_data_type[1] = tmp; 105 krb5_ret_data(sp, &c); 106 key->key_data_length[1] = c.length; 107 key->key_data_contents[1] = c.data; 108 return 0; 109} 110 111kadm5_ret_t 112kadm5_store_tl_data(krb5_storage *sp, 113 krb5_tl_data *tl) 114{ 115 krb5_data c; 116 krb5_store_int32(sp, tl->tl_data_type); 117 c.length = tl->tl_data_length; 118 c.data = tl->tl_data_contents; 119 krb5_store_data(sp, c); 120 return 0; 121} 122 123kadm5_ret_t 124kadm5_ret_tl_data(krb5_storage *sp, 125 krb5_tl_data *tl) 126{ 127 krb5_data c; 128 int32_t tmp; 129 krb5_ret_int32(sp, &tmp); 130 tl->tl_data_type = tmp; 131 krb5_ret_data(sp, &c); 132 tl->tl_data_length = c.length; 133 tl->tl_data_contents = c.data; 134 return 0; 135} 136 137static kadm5_ret_t 138store_principal_ent(krb5_storage *sp, 139 kadm5_principal_ent_t princ, 140 uint32_t mask, int wkeys) 141{ 142 int i; 143 144 if (mask & KADM5_PRINCIPAL) 145 krb5_store_principal(sp, princ->principal); 146 if (mask & KADM5_PRINC_EXPIRE_TIME) 147 krb5_store_int32(sp, (int32_t)princ->princ_expire_time); 148 if (mask & KADM5_PW_EXPIRATION) 149 krb5_store_int32(sp, (int32_t)princ->pw_expiration); 150 if (mask & KADM5_LAST_PWD_CHANGE) 151 krb5_store_int32(sp, (int32_t)princ->last_pwd_change); 152 if (mask & KADM5_MAX_LIFE) 153 krb5_store_int32(sp, (int32_t)princ->max_life); 154 if (mask & KADM5_MOD_NAME) { 155 krb5_store_int32(sp, princ->mod_name != NULL); 156 if(princ->mod_name) 157 krb5_store_principal(sp, princ->mod_name); 158 } 159 if (mask & KADM5_MOD_TIME) 160 krb5_store_int32(sp, (int32_t)princ->mod_date); 161 if (mask & KADM5_ATTRIBUTES) 162 krb5_store_int32(sp, princ->attributes); 163 if (mask & KADM5_KVNO) 164 krb5_store_int32(sp, princ->kvno); 165 if (mask & KADM5_MKVNO) 166 krb5_store_int32(sp, princ->mkvno); 167 if (mask & KADM5_POLICY) { 168 krb5_store_int32(sp, princ->policy != NULL); 169 if(princ->policy) 170 krb5_store_string(sp, princ->policy); 171 } 172 if (mask & KADM5_AUX_ATTRIBUTES) 173 krb5_store_int32(sp, princ->aux_attributes); 174 if (mask & KADM5_MAX_RLIFE) 175 krb5_store_int32(sp, (int32_t)princ->max_renewable_life); 176 if (mask & KADM5_LAST_SUCCESS) 177 krb5_store_int32(sp, (int32_t)princ->last_success); 178 if (mask & KADM5_LAST_FAILED) 179 krb5_store_int32(sp, (int32_t)princ->last_failed); 180 if (mask & KADM5_FAIL_AUTH_COUNT) 181 krb5_store_int32(sp, princ->fail_auth_count); 182 if (mask & KADM5_KEY_DATA) { 183 krb5_store_int32(sp, princ->n_key_data); 184 for(i = 0; i < princ->n_key_data; i++) { 185 if (wkeys) 186 kadm5_store_key_data(sp, &princ->key_data[i]); 187 else 188 kadm5_store_fake_key_data(sp, &princ->key_data[i]); 189 } 190 } 191 if (mask & KADM5_TL_DATA) { 192 krb5_tl_data *tp; 193 194 krb5_store_int32(sp, princ->n_tl_data); 195 for(tp = princ->tl_data; tp; tp = tp->tl_data_next) 196 kadm5_store_tl_data(sp, tp); 197 } 198 return 0; 199} 200 201 202kadm5_ret_t 203kadm5_store_principal_ent(krb5_storage *sp, 204 kadm5_principal_ent_t princ) 205{ 206 return store_principal_ent (sp, princ, ~0, 1); 207} 208 209kadm5_ret_t 210kadm5_store_principal_ent_nokeys(krb5_storage *sp, 211 kadm5_principal_ent_t princ) 212{ 213 return store_principal_ent (sp, princ, ~0, 0); 214} 215 216kadm5_ret_t 217kadm5_store_principal_ent_mask(krb5_storage *sp, 218 kadm5_principal_ent_t princ, 219 uint32_t mask) 220{ 221 krb5_store_int32(sp, mask); 222 return store_principal_ent (sp, princ, mask, 1); 223} 224 225static kadm5_ret_t 226ret_principal_ent(krb5_storage *sp, 227 kadm5_principal_ent_t princ, 228 uint32_t mask) 229{ 230 int i; 231 int32_t tmp; 232 233 if (mask & KADM5_PRINCIPAL) 234 krb5_ret_principal(sp, &princ->principal); 235 236 if (mask & KADM5_PRINC_EXPIRE_TIME) { 237 krb5_ret_int32(sp, &tmp); 238 princ->princ_expire_time = tmp; 239 } 240 if (mask & KADM5_PW_EXPIRATION) { 241 krb5_ret_int32(sp, &tmp); 242 princ->pw_expiration = tmp; 243 } 244 if (mask & KADM5_LAST_PWD_CHANGE) { 245 krb5_ret_int32(sp, &tmp); 246 princ->last_pwd_change = tmp; 247 } 248 if (mask & KADM5_MAX_LIFE) { 249 krb5_ret_int32(sp, &tmp); 250 princ->max_life = tmp; 251 } 252 if (mask & KADM5_MOD_NAME) { 253 krb5_ret_int32(sp, &tmp); 254 if(tmp) 255 krb5_ret_principal(sp, &princ->mod_name); 256 else 257 princ->mod_name = NULL; 258 } 259 if (mask & KADM5_MOD_TIME) { 260 krb5_ret_int32(sp, &tmp); 261 princ->mod_date = tmp; 262 } 263 if (mask & KADM5_ATTRIBUTES) { 264 krb5_ret_int32(sp, &tmp); 265 princ->attributes = tmp; 266 } 267 if (mask & KADM5_KVNO) { 268 krb5_ret_int32(sp, &tmp); 269 princ->kvno = tmp; 270 } 271 if (mask & KADM5_MKVNO) { 272 krb5_ret_int32(sp, &tmp); 273 princ->mkvno = tmp; 274 } 275 if (mask & KADM5_POLICY) { 276 krb5_ret_int32(sp, &tmp); 277 if(tmp) 278 krb5_ret_string(sp, &princ->policy); 279 else 280 princ->policy = NULL; 281 } 282 if (mask & KADM5_AUX_ATTRIBUTES) { 283 krb5_ret_int32(sp, &tmp); 284 princ->aux_attributes = tmp; 285 } 286 if (mask & KADM5_MAX_RLIFE) { 287 krb5_ret_int32(sp, &tmp); 288 princ->max_renewable_life = tmp; 289 } 290 if (mask & KADM5_LAST_SUCCESS) { 291 krb5_ret_int32(sp, &tmp); 292 princ->last_success = tmp; 293 } 294 if (mask & KADM5_LAST_FAILED) { 295 krb5_ret_int32(sp, &tmp); 296 princ->last_failed = tmp; 297 } 298 if (mask & KADM5_FAIL_AUTH_COUNT) { 299 krb5_ret_int32(sp, &tmp); 300 princ->fail_auth_count = tmp; 301 } 302 if (mask & KADM5_KEY_DATA) { 303 krb5_ret_int32(sp, &tmp); 304 princ->n_key_data = tmp; 305 princ->key_data = malloc(princ->n_key_data * sizeof(*princ->key_data)); 306 if (princ->key_data == NULL && princ->n_key_data != 0) 307 return ENOMEM; 308 for(i = 0; i < princ->n_key_data; i++) 309 kadm5_ret_key_data(sp, &princ->key_data[i]); 310 } 311 if (mask & KADM5_TL_DATA) { 312 krb5_ret_int32(sp, &tmp); 313 princ->n_tl_data = tmp; 314 princ->tl_data = NULL; 315 for(i = 0; i < princ->n_tl_data; i++){ 316 krb5_tl_data *tp = malloc(sizeof(*tp)); 317 if (tp == NULL) 318 return ENOMEM; 319 kadm5_ret_tl_data(sp, tp); 320 tp->tl_data_next = princ->tl_data; 321 princ->tl_data = tp; 322 } 323 } 324 return 0; 325} 326 327kadm5_ret_t 328kadm5_ret_principal_ent(krb5_storage *sp, 329 kadm5_principal_ent_t princ) 330{ 331 return ret_principal_ent (sp, princ, ~0); 332} 333 334kadm5_ret_t 335kadm5_ret_principal_ent_mask(krb5_storage *sp, 336 kadm5_principal_ent_t princ, 337 uint32_t *mask) 338{ 339 int32_t tmp; 340 341 krb5_ret_int32 (sp, &tmp); 342 *mask = tmp; 343 return ret_principal_ent (sp, princ, *mask); 344} 345 346kadm5_ret_t 347_kadm5_marshal_params(krb5_context context, 348 kadm5_config_params *params, 349 krb5_data *out) 350{ 351 krb5_storage *sp = krb5_storage_emem(); 352 353 krb5_store_int32(sp, params->mask & (KADM5_CONFIG_REALM)); 354 355 if(params->mask & KADM5_CONFIG_REALM) 356 krb5_store_string(sp, params->realm); 357 krb5_storage_to_data(sp, out); 358 krb5_storage_free(sp); 359 360 return 0; 361} 362 363kadm5_ret_t 364_kadm5_unmarshal_params(krb5_context context, 365 krb5_data *in, 366 kadm5_config_params *params) 367{ 368 krb5_error_code ret; 369 krb5_storage *sp; 370 int32_t mask; 371 372 sp = krb5_storage_from_data(in); 373 if (sp == NULL) 374 return ENOMEM; 375 376 ret = krb5_ret_int32(sp, &mask); 377 if (ret) 378 goto out; 379 params->mask = mask; 380 381 if(params->mask & KADM5_CONFIG_REALM) 382 ret = krb5_ret_string(sp, ¶ms->realm); 383 out: 384 krb5_storage_free(sp); 385 386 return ret; 387} 388