1b528cefcSMark Murray /* 2bbd80c28SJacques Vidrine * Copyright (c) 1997 - 2003 Kungliga Tekniska H�gskolan 3b528cefcSMark Murray * (Royal Institute of Technology, Stockholm, Sweden). 4b528cefcSMark Murray * All rights reserved. 5b528cefcSMark Murray * 6b528cefcSMark Murray * Redistribution and use in source and binary forms, with or without 7b528cefcSMark Murray * modification, are permitted provided that the following conditions 8b528cefcSMark Murray * are met: 9b528cefcSMark Murray * 10b528cefcSMark Murray * 1. Redistributions of source code must retain the above copyright 11b528cefcSMark Murray * notice, this list of conditions and the following disclaimer. 12b528cefcSMark Murray * 13b528cefcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright 14b528cefcSMark Murray * notice, this list of conditions and the following disclaimer in the 15b528cefcSMark Murray * documentation and/or other materials provided with the distribution. 16b528cefcSMark Murray * 17b528cefcSMark Murray * 3. Neither the name of the Institute nor the names of its contributors 18b528cefcSMark Murray * may be used to endorse or promote products derived from this software 19b528cefcSMark Murray * without specific prior written permission. 20b528cefcSMark Murray * 21b528cefcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22b528cefcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23b528cefcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24b528cefcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25b528cefcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26b528cefcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27b528cefcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28b528cefcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29b528cefcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30b528cefcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31b528cefcSMark Murray * SUCH DAMAGE. 32b528cefcSMark Murray */ 33b528cefcSMark Murray 34b528cefcSMark Murray #include "krb5_locl.h" 35b528cefcSMark Murray 36bbd80c28SJacques Vidrine RCSID("$Id: keytab.c,v 1.55 2003/03/27 03:45:01 lha Exp $"); 37b528cefcSMark Murray 38b528cefcSMark Murray /* 39b528cefcSMark Murray * Register a new keytab in `ops' 40b528cefcSMark Murray * Return 0 or an error. 41b528cefcSMark Murray */ 42b528cefcSMark Murray 43b528cefcSMark Murray krb5_error_code 44b528cefcSMark Murray krb5_kt_register(krb5_context context, 45b528cefcSMark Murray const krb5_kt_ops *ops) 46b528cefcSMark Murray { 47b528cefcSMark Murray struct krb5_keytab_data *tmp; 48b528cefcSMark Murray 49bbd80c28SJacques Vidrine if (strlen(ops->prefix) > KRB5_KT_PREFIX_MAX_LEN - 1) { 50bbd80c28SJacques Vidrine krb5_set_error_string(context, "krb5_kt_register; prefix too long"); 51bbd80c28SJacques Vidrine return KRB5_KT_NAME_TOOLONG; 52bbd80c28SJacques Vidrine } 53bbd80c28SJacques Vidrine 54b528cefcSMark Murray tmp = realloc(context->kt_types, 55b528cefcSMark Murray (context->num_kt_types + 1) * sizeof(*context->kt_types)); 56adb0ddaeSAssar Westerlund if(tmp == NULL) { 57adb0ddaeSAssar Westerlund krb5_set_error_string(context, "malloc: out of memory"); 58b528cefcSMark Murray return ENOMEM; 59adb0ddaeSAssar Westerlund } 60b528cefcSMark Murray memcpy(&tmp[context->num_kt_types], ops, 61b528cefcSMark Murray sizeof(tmp[context->num_kt_types])); 62b528cefcSMark Murray context->kt_types = tmp; 63b528cefcSMark Murray context->num_kt_types++; 64b528cefcSMark Murray return 0; 65b528cefcSMark Murray } 66b528cefcSMark Murray 67b528cefcSMark Murray /* 68b528cefcSMark Murray * Resolve the keytab name (of the form `type:residual') in `name' 69b528cefcSMark Murray * into a keytab in `id'. 70b528cefcSMark Murray * Return 0 or an error 71b528cefcSMark Murray */ 72b528cefcSMark Murray 73b528cefcSMark Murray krb5_error_code 74b528cefcSMark Murray krb5_kt_resolve(krb5_context context, 75b528cefcSMark Murray const char *name, 76b528cefcSMark Murray krb5_keytab *id) 77b528cefcSMark Murray { 78b528cefcSMark Murray krb5_keytab k; 79b528cefcSMark Murray int i; 80b528cefcSMark Murray const char *type, *residual; 81b528cefcSMark Murray size_t type_len; 82b528cefcSMark Murray krb5_error_code ret; 83b528cefcSMark Murray 84b528cefcSMark Murray residual = strchr(name, ':'); 85b528cefcSMark Murray if(residual == NULL) { 86b528cefcSMark Murray type = "FILE"; 87b528cefcSMark Murray type_len = strlen(type); 88b528cefcSMark Murray residual = name; 89b528cefcSMark Murray } else { 90b528cefcSMark Murray type = name; 91b528cefcSMark Murray type_len = residual - name; 92b528cefcSMark Murray residual++; 93b528cefcSMark Murray } 94b528cefcSMark Murray 95b528cefcSMark Murray for(i = 0; i < context->num_kt_types; i++) { 964137ff4cSJacques Vidrine if(strncasecmp(type, context->kt_types[i].prefix, type_len) == 0) 97b528cefcSMark Murray break; 98b528cefcSMark Murray } 99adb0ddaeSAssar Westerlund if(i == context->num_kt_types) { 100adb0ddaeSAssar Westerlund krb5_set_error_string(context, "unknown keytab type %.*s", 101adb0ddaeSAssar Westerlund (int)type_len, type); 102b528cefcSMark Murray return KRB5_KT_UNKNOWN_TYPE; 103adb0ddaeSAssar Westerlund } 104b528cefcSMark Murray 105b528cefcSMark Murray k = malloc (sizeof(*k)); 106adb0ddaeSAssar Westerlund if (k == NULL) { 107adb0ddaeSAssar Westerlund krb5_set_error_string(context, "malloc: out of memory"); 108b528cefcSMark Murray return ENOMEM; 109adb0ddaeSAssar Westerlund } 110b528cefcSMark Murray memcpy(k, &context->kt_types[i], sizeof(*k)); 111b528cefcSMark Murray k->data = NULL; 112b528cefcSMark Murray ret = (*k->resolve)(context, residual, k); 113b528cefcSMark Murray if(ret) { 114b528cefcSMark Murray free(k); 115b528cefcSMark Murray k = NULL; 116b528cefcSMark Murray } 117b528cefcSMark Murray *id = k; 118b528cefcSMark Murray return ret; 119b528cefcSMark Murray } 120b528cefcSMark Murray 121b528cefcSMark Murray /* 122b528cefcSMark Murray * copy the name of the default keytab into `name'. 123b528cefcSMark Murray * Return 0 or KRB5_CONFIG_NOTENUFSPACE if `namesize' is too short. 124b528cefcSMark Murray */ 125b528cefcSMark Murray 126b528cefcSMark Murray krb5_error_code 127b528cefcSMark Murray krb5_kt_default_name(krb5_context context, char *name, size_t namesize) 128b528cefcSMark Murray { 129adb0ddaeSAssar Westerlund if (strlcpy (name, context->default_keytab, namesize) >= namesize) { 130adb0ddaeSAssar Westerlund krb5_clear_error_string (context); 131b528cefcSMark Murray return KRB5_CONFIG_NOTENUFSPACE; 132adb0ddaeSAssar Westerlund } 133adb0ddaeSAssar Westerlund return 0; 134adb0ddaeSAssar Westerlund } 135adb0ddaeSAssar Westerlund 136adb0ddaeSAssar Westerlund /* 137adb0ddaeSAssar Westerlund * copy the name of the default modify keytab into `name'. 138adb0ddaeSAssar Westerlund * Return 0 or KRB5_CONFIG_NOTENUFSPACE if `namesize' is too short. 139adb0ddaeSAssar Westerlund */ 140adb0ddaeSAssar Westerlund 141adb0ddaeSAssar Westerlund krb5_error_code 142adb0ddaeSAssar Westerlund krb5_kt_default_modify_name(krb5_context context, char *name, size_t namesize) 143adb0ddaeSAssar Westerlund { 1444137ff4cSJacques Vidrine const char *kt = NULL; 1454137ff4cSJacques Vidrine if(context->default_keytab_modify == NULL) { 1464137ff4cSJacques Vidrine if(strncasecmp(context->default_keytab, "ANY:", 4) != 0) 1474137ff4cSJacques Vidrine kt = context->default_keytab; 1484137ff4cSJacques Vidrine else { 1494137ff4cSJacques Vidrine size_t len = strcspn(context->default_keytab + 4, ","); 1504137ff4cSJacques Vidrine if(len >= namesize) { 1514137ff4cSJacques Vidrine krb5_clear_error_string(context); 1524137ff4cSJacques Vidrine return KRB5_CONFIG_NOTENUFSPACE; 1534137ff4cSJacques Vidrine } 1544137ff4cSJacques Vidrine strlcpy(name, context->default_keytab + 4, namesize); 1554137ff4cSJacques Vidrine name[len] = '\0'; 1564137ff4cSJacques Vidrine return 0; 1574137ff4cSJacques Vidrine } 1584137ff4cSJacques Vidrine } else 1594137ff4cSJacques Vidrine kt = context->default_keytab_modify; 1604137ff4cSJacques Vidrine if (strlcpy (name, kt, namesize) >= namesize) { 161adb0ddaeSAssar Westerlund krb5_clear_error_string (context); 162adb0ddaeSAssar Westerlund return KRB5_CONFIG_NOTENUFSPACE; 163adb0ddaeSAssar Westerlund } 164b528cefcSMark Murray return 0; 165b528cefcSMark Murray } 166b528cefcSMark Murray 167b528cefcSMark Murray /* 168b528cefcSMark Murray * Set `id' to the default keytab. 169b528cefcSMark Murray * Return 0 or an error. 170b528cefcSMark Murray */ 171b528cefcSMark Murray 172b528cefcSMark Murray krb5_error_code 173b528cefcSMark Murray krb5_kt_default(krb5_context context, krb5_keytab *id) 174b528cefcSMark Murray { 175b528cefcSMark Murray return krb5_kt_resolve (context, context->default_keytab, id); 176b528cefcSMark Murray } 177b528cefcSMark Murray 178b528cefcSMark Murray /* 179b528cefcSMark Murray * Read the key identified by `(principal, vno, enctype)' from the 180b528cefcSMark Murray * keytab in `keyprocarg' (the default if == NULL) into `*key'. 181b528cefcSMark Murray * Return 0 or an error. 182b528cefcSMark Murray */ 183b528cefcSMark Murray 184b528cefcSMark Murray krb5_error_code 185b528cefcSMark Murray krb5_kt_read_service_key(krb5_context context, 186b528cefcSMark Murray krb5_pointer keyprocarg, 187b528cefcSMark Murray krb5_principal principal, 188b528cefcSMark Murray krb5_kvno vno, 189b528cefcSMark Murray krb5_enctype enctype, 190b528cefcSMark Murray krb5_keyblock **key) 191b528cefcSMark Murray { 192b528cefcSMark Murray krb5_keytab keytab; 193b528cefcSMark Murray krb5_keytab_entry entry; 194b528cefcSMark Murray krb5_error_code ret; 195b528cefcSMark Murray 196b528cefcSMark Murray if (keyprocarg) 197b528cefcSMark Murray ret = krb5_kt_resolve (context, keyprocarg, &keytab); 198b528cefcSMark Murray else 199b528cefcSMark Murray ret = krb5_kt_default (context, &keytab); 200b528cefcSMark Murray 201b528cefcSMark Murray if (ret) 202b528cefcSMark Murray return ret; 203b528cefcSMark Murray 204b528cefcSMark Murray ret = krb5_kt_get_entry (context, keytab, principal, vno, enctype, &entry); 205b528cefcSMark Murray krb5_kt_close (context, keytab); 206b528cefcSMark Murray if (ret) 207b528cefcSMark Murray return ret; 208b528cefcSMark Murray ret = krb5_copy_keyblock (context, &entry.keyblock, key); 209b528cefcSMark Murray krb5_kt_free_entry(context, &entry); 210b528cefcSMark Murray return ret; 211b528cefcSMark Murray } 212b528cefcSMark Murray 213b528cefcSMark Murray /* 214bbd80c28SJacques Vidrine * Return the type of the `keytab' in the string `prefix of length 215bbd80c28SJacques Vidrine * `prefixsize'. 216bbd80c28SJacques Vidrine */ 217bbd80c28SJacques Vidrine 218bbd80c28SJacques Vidrine krb5_error_code 219bbd80c28SJacques Vidrine krb5_kt_get_type(krb5_context context, 220bbd80c28SJacques Vidrine krb5_keytab keytab, 221bbd80c28SJacques Vidrine char *prefix, 222bbd80c28SJacques Vidrine size_t prefixsize) 223bbd80c28SJacques Vidrine { 224bbd80c28SJacques Vidrine strlcpy(prefix, keytab->prefix, prefixsize); 225bbd80c28SJacques Vidrine return 0; 226bbd80c28SJacques Vidrine } 227bbd80c28SJacques Vidrine 228bbd80c28SJacques Vidrine /* 229b528cefcSMark Murray * Retrieve the name of the keytab `keytab' into `name', `namesize' 230b528cefcSMark Murray * Return 0 or an error. 231b528cefcSMark Murray */ 232b528cefcSMark Murray 233b528cefcSMark Murray krb5_error_code 234b528cefcSMark Murray krb5_kt_get_name(krb5_context context, 235b528cefcSMark Murray krb5_keytab keytab, 236b528cefcSMark Murray char *name, 237b528cefcSMark Murray size_t namesize) 238b528cefcSMark Murray { 239b528cefcSMark Murray return (*keytab->get_name)(context, keytab, name, namesize); 240b528cefcSMark Murray } 241b528cefcSMark Murray 242b528cefcSMark Murray /* 243b528cefcSMark Murray * Finish using the keytab in `id'. All resources will be released. 244b528cefcSMark Murray * Return 0 or an error. 245b528cefcSMark Murray */ 246b528cefcSMark Murray 247b528cefcSMark Murray krb5_error_code 248b528cefcSMark Murray krb5_kt_close(krb5_context context, 249b528cefcSMark Murray krb5_keytab id) 250b528cefcSMark Murray { 251b528cefcSMark Murray krb5_error_code ret; 252b528cefcSMark Murray 253b528cefcSMark Murray ret = (*id->close)(context, id); 254b528cefcSMark Murray if(ret == 0) 255b528cefcSMark Murray free(id); 256b528cefcSMark Murray return ret; 257b528cefcSMark Murray } 258b528cefcSMark Murray 259b528cefcSMark Murray /* 260b528cefcSMark Murray * Compare `entry' against `principal, vno, enctype'. 261b528cefcSMark Murray * Any of `principal, vno, enctype' might be 0 which acts as a wildcard. 262b528cefcSMark Murray * Return TRUE if they compare the same, FALSE otherwise. 263b528cefcSMark Murray */ 264b528cefcSMark Murray 265b528cefcSMark Murray krb5_boolean 266b528cefcSMark Murray krb5_kt_compare(krb5_context context, 267b528cefcSMark Murray krb5_keytab_entry *entry, 268b528cefcSMark Murray krb5_const_principal principal, 269b528cefcSMark Murray krb5_kvno vno, 270b528cefcSMark Murray krb5_enctype enctype) 271b528cefcSMark Murray { 272b528cefcSMark Murray if(principal != NULL && 273b528cefcSMark Murray !krb5_principal_compare(context, entry->principal, principal)) 274b528cefcSMark Murray return FALSE; 275b528cefcSMark Murray if(vno && vno != entry->vno) 276b528cefcSMark Murray return FALSE; 277b528cefcSMark Murray if(enctype && enctype != entry->keyblock.keytype) 278b528cefcSMark Murray return FALSE; 279b528cefcSMark Murray return TRUE; 280b528cefcSMark Murray } 281b528cefcSMark Murray 282b528cefcSMark Murray /* 283b528cefcSMark Murray * Retrieve the keytab entry for `principal, kvno, enctype' into `entry' 284b528cefcSMark Murray * from the keytab `id'. 2858373020dSJacques Vidrine * kvno == 0 is a wildcard and gives the keytab with the highest vno. 286b528cefcSMark Murray * Return 0 or an error. 287b528cefcSMark Murray */ 288b528cefcSMark Murray 289b528cefcSMark Murray krb5_error_code 290b528cefcSMark Murray krb5_kt_get_entry(krb5_context context, 291b528cefcSMark Murray krb5_keytab id, 292b528cefcSMark Murray krb5_const_principal principal, 293b528cefcSMark Murray krb5_kvno kvno, 294b528cefcSMark Murray krb5_enctype enctype, 295b528cefcSMark Murray krb5_keytab_entry *entry) 296b528cefcSMark Murray { 297b528cefcSMark Murray krb5_keytab_entry tmp; 298b528cefcSMark Murray krb5_error_code ret; 299b528cefcSMark Murray krb5_kt_cursor cursor; 300b528cefcSMark Murray 301b528cefcSMark Murray if(id->get) 302b528cefcSMark Murray return (*id->get)(context, id, principal, kvno, enctype, entry); 303b528cefcSMark Murray 304b528cefcSMark Murray ret = krb5_kt_start_seq_get (context, id, &cursor); 305b528cefcSMark Murray if (ret) 306b528cefcSMark Murray return KRB5_KT_NOTFOUND; /* XXX i.e. file not found */ 307b528cefcSMark Murray 308b528cefcSMark Murray entry->vno = 0; 309b528cefcSMark Murray while (krb5_kt_next_entry(context, id, &tmp, &cursor) == 0) { 310b528cefcSMark Murray if (krb5_kt_compare(context, &tmp, principal, 0, enctype)) { 3118373020dSJacques Vidrine /* the file keytab might only store the lower 8 bits of 3128373020dSJacques Vidrine the kvno, so only compare those bits */ 3138373020dSJacques Vidrine if (kvno == tmp.vno 3148373020dSJacques Vidrine || (tmp.vno < 256 && kvno % 256 == tmp.vno)) { 315b528cefcSMark Murray krb5_kt_copy_entry_contents (context, &tmp, entry); 316b528cefcSMark Murray krb5_kt_free_entry (context, &tmp); 317b528cefcSMark Murray krb5_kt_end_seq_get(context, id, &cursor); 318b528cefcSMark Murray return 0; 319b528cefcSMark Murray } else if (kvno == 0 && tmp.vno > entry->vno) { 320b528cefcSMark Murray if (entry->vno) 321b528cefcSMark Murray krb5_kt_free_entry (context, entry); 322b528cefcSMark Murray krb5_kt_copy_entry_contents (context, &tmp, entry); 323b528cefcSMark Murray } 324b528cefcSMark Murray } 325b528cefcSMark Murray krb5_kt_free_entry(context, &tmp); 326b528cefcSMark Murray } 327b528cefcSMark Murray krb5_kt_end_seq_get (context, id, &cursor); 328adb0ddaeSAssar Westerlund if (entry->vno) { 329b528cefcSMark Murray return 0; 330adb0ddaeSAssar Westerlund } else { 331bbd80c28SJacques Vidrine char princ[256], kt_name[256], kvno_str[25]; 332adb0ddaeSAssar Westerlund 333adb0ddaeSAssar Westerlund krb5_unparse_name_fixed (context, principal, princ, sizeof(princ)); 334adb0ddaeSAssar Westerlund krb5_kt_get_name (context, id, kt_name, sizeof(kt_name)); 335adb0ddaeSAssar Westerlund 336bbd80c28SJacques Vidrine if (kvno) 337bbd80c28SJacques Vidrine snprintf(kvno_str, sizeof(kvno_str), "(kvno %d)", kvno); 338bbd80c28SJacques Vidrine else 339bbd80c28SJacques Vidrine kvno_str[0] = '\0'; 340bbd80c28SJacques Vidrine 341adb0ddaeSAssar Westerlund krb5_set_error_string (context, 342bbd80c28SJacques Vidrine "failed to find %s%s in keytab %s", 3438373020dSJacques Vidrine princ, 344bbd80c28SJacques Vidrine kvno_str, 3458373020dSJacques Vidrine kt_name); 346b528cefcSMark Murray return KRB5_KT_NOTFOUND; 347b528cefcSMark Murray } 348adb0ddaeSAssar Westerlund } 349b528cefcSMark Murray 350b528cefcSMark Murray /* 351b528cefcSMark Murray * Copy the contents of `in' into `out'. 3528373020dSJacques Vidrine * Return 0 or an error. */ 353b528cefcSMark Murray 354b528cefcSMark Murray krb5_error_code 355b528cefcSMark Murray krb5_kt_copy_entry_contents(krb5_context context, 356b528cefcSMark Murray const krb5_keytab_entry *in, 357b528cefcSMark Murray krb5_keytab_entry *out) 358b528cefcSMark Murray { 359b528cefcSMark Murray krb5_error_code ret; 360b528cefcSMark Murray 361b528cefcSMark Murray memset(out, 0, sizeof(*out)); 362b528cefcSMark Murray out->vno = in->vno; 363b528cefcSMark Murray 364b528cefcSMark Murray ret = krb5_copy_principal (context, in->principal, &out->principal); 365b528cefcSMark Murray if (ret) 366b528cefcSMark Murray goto fail; 367b528cefcSMark Murray ret = krb5_copy_keyblock_contents (context, 368b528cefcSMark Murray &in->keyblock, 369b528cefcSMark Murray &out->keyblock); 370b528cefcSMark Murray if (ret) 371b528cefcSMark Murray goto fail; 372b528cefcSMark Murray out->timestamp = in->timestamp; 373b528cefcSMark Murray return 0; 374b528cefcSMark Murray fail: 375b528cefcSMark Murray krb5_kt_free_entry (context, out); 376b528cefcSMark Murray return ret; 377b528cefcSMark Murray } 378b528cefcSMark Murray 379b528cefcSMark Murray /* 380b528cefcSMark Murray * Free the contents of `entry'. 381b528cefcSMark Murray */ 382b528cefcSMark Murray 383b528cefcSMark Murray krb5_error_code 384b528cefcSMark Murray krb5_kt_free_entry(krb5_context context, 385b528cefcSMark Murray krb5_keytab_entry *entry) 386b528cefcSMark Murray { 387b528cefcSMark Murray krb5_free_principal (context, entry->principal); 388b528cefcSMark Murray krb5_free_keyblock_contents (context, &entry->keyblock); 389b528cefcSMark Murray return 0; 390b528cefcSMark Murray } 391b528cefcSMark Murray 392b528cefcSMark Murray #if 0 393b528cefcSMark Murray static int 394b528cefcSMark Murray xxxlock(int fd, int write) 395b528cefcSMark Murray { 396b528cefcSMark Murray if(flock(fd, (write ? LOCK_EX : LOCK_SH) | LOCK_NB) < 0) { 397b528cefcSMark Murray sleep(1); 398b528cefcSMark Murray if(flock(fd, (write ? LOCK_EX : LOCK_SH) | LOCK_NB) < 0) 399b528cefcSMark Murray return -1; 400b528cefcSMark Murray } 401b528cefcSMark Murray return 0; 402b528cefcSMark Murray } 403b528cefcSMark Murray 404b528cefcSMark Murray static void 405b528cefcSMark Murray xxxunlock(int fd) 406b528cefcSMark Murray { 407b528cefcSMark Murray flock(fd, LOCK_UN); 408b528cefcSMark Murray } 409b528cefcSMark Murray #endif 410b528cefcSMark Murray 411b528cefcSMark Murray /* 412b528cefcSMark Murray * Set `cursor' to point at the beginning of `id'. 413b528cefcSMark Murray * Return 0 or an error. 414b528cefcSMark Murray */ 415b528cefcSMark Murray 416b528cefcSMark Murray krb5_error_code 417b528cefcSMark Murray krb5_kt_start_seq_get(krb5_context context, 418b528cefcSMark Murray krb5_keytab id, 419b528cefcSMark Murray krb5_kt_cursor *cursor) 420b528cefcSMark Murray { 421adb0ddaeSAssar Westerlund if(id->start_seq_get == NULL) { 422adb0ddaeSAssar Westerlund krb5_set_error_string(context, 423adb0ddaeSAssar Westerlund "start_seq_get is not supported in the %s " 424adb0ddaeSAssar Westerlund " keytab", id->prefix); 425b528cefcSMark Murray return HEIM_ERR_OPNOTSUPP; 426adb0ddaeSAssar Westerlund } 427b528cefcSMark Murray return (*id->start_seq_get)(context, id, cursor); 428b528cefcSMark Murray } 429b528cefcSMark Murray 430b528cefcSMark Murray /* 431b528cefcSMark Murray * Get the next entry from `id' pointed to by `cursor' and advance the 432b528cefcSMark Murray * `cursor'. 433b528cefcSMark Murray * Return 0 or an error. 434b528cefcSMark Murray */ 435b528cefcSMark Murray 436b528cefcSMark Murray krb5_error_code 437b528cefcSMark Murray krb5_kt_next_entry(krb5_context context, 438b528cefcSMark Murray krb5_keytab id, 439b528cefcSMark Murray krb5_keytab_entry *entry, 440b528cefcSMark Murray krb5_kt_cursor *cursor) 441b528cefcSMark Murray { 442adb0ddaeSAssar Westerlund if(id->next_entry == NULL) { 443adb0ddaeSAssar Westerlund krb5_set_error_string(context, 444adb0ddaeSAssar Westerlund "next_entry is not supported in the %s " 445adb0ddaeSAssar Westerlund " keytab", id->prefix); 446b528cefcSMark Murray return HEIM_ERR_OPNOTSUPP; 447adb0ddaeSAssar Westerlund } 448b528cefcSMark Murray return (*id->next_entry)(context, id, entry, cursor); 449b528cefcSMark Murray } 450b528cefcSMark Murray 451b528cefcSMark Murray /* 452b528cefcSMark Murray * Release all resources associated with `cursor'. 453b528cefcSMark Murray */ 454b528cefcSMark Murray 455b528cefcSMark Murray krb5_error_code 456b528cefcSMark Murray krb5_kt_end_seq_get(krb5_context context, 457b528cefcSMark Murray krb5_keytab id, 458b528cefcSMark Murray krb5_kt_cursor *cursor) 459b528cefcSMark Murray { 460adb0ddaeSAssar Westerlund if(id->end_seq_get == NULL) { 461adb0ddaeSAssar Westerlund krb5_set_error_string(context, 462adb0ddaeSAssar Westerlund "end_seq_get is not supported in the %s " 463adb0ddaeSAssar Westerlund " keytab", id->prefix); 464b528cefcSMark Murray return HEIM_ERR_OPNOTSUPP; 465adb0ddaeSAssar Westerlund } 466b528cefcSMark Murray return (*id->end_seq_get)(context, id, cursor); 467b528cefcSMark Murray } 468b528cefcSMark Murray 469b528cefcSMark Murray /* 470b528cefcSMark Murray * Add the entry in `entry' to the keytab `id'. 471b528cefcSMark Murray * Return 0 or an error. 472b528cefcSMark Murray */ 473b528cefcSMark Murray 474b528cefcSMark Murray krb5_error_code 475b528cefcSMark Murray krb5_kt_add_entry(krb5_context context, 476b528cefcSMark Murray krb5_keytab id, 477b528cefcSMark Murray krb5_keytab_entry *entry) 478b528cefcSMark Murray { 479adb0ddaeSAssar Westerlund if(id->add == NULL) { 480adb0ddaeSAssar Westerlund krb5_set_error_string(context, "Add is not supported in the %s keytab", 481adb0ddaeSAssar Westerlund id->prefix); 482b528cefcSMark Murray return KRB5_KT_NOWRITE; 483adb0ddaeSAssar Westerlund } 48413e3f4d6SMark Murray entry->timestamp = time(NULL); 485b528cefcSMark Murray return (*id->add)(context, id,entry); 486b528cefcSMark Murray } 487b528cefcSMark Murray 488b528cefcSMark Murray /* 489b528cefcSMark Murray * Remove the entry `entry' from the keytab `id'. 490b528cefcSMark Murray * Return 0 or an error. 491b528cefcSMark Murray */ 492b528cefcSMark Murray 493b528cefcSMark Murray krb5_error_code 494b528cefcSMark Murray krb5_kt_remove_entry(krb5_context context, 495b528cefcSMark Murray krb5_keytab id, 496b528cefcSMark Murray krb5_keytab_entry *entry) 497b528cefcSMark Murray { 498adb0ddaeSAssar Westerlund if(id->remove == NULL) { 499adb0ddaeSAssar Westerlund krb5_set_error_string(context, 500adb0ddaeSAssar Westerlund "Remove is not supported in the %s keytab", 501adb0ddaeSAssar Westerlund id->prefix); 502b528cefcSMark Murray return KRB5_KT_NOWRITE; 503adb0ddaeSAssar Westerlund } 504b528cefcSMark Murray return (*id->remove)(context, id, entry); 505b528cefcSMark Murray } 506