root/source4/heimdal/lib/krb5/keytab_any.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. free_list
  2. any_resolve
  3. any_get_name
  4. any_close
  5. any_start_seq_get
  6. any_next_entry
  7. any_end_seq_get
  8. any_add_entry
  9. any_remove_entry

   1 /*
   2  * Copyright (c) 2001-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 "krb5_locl.h"
  35 
  36 RCSID("$Id$");
  37 
  38 struct any_data {
  39     krb5_keytab kt;
  40     char *name;
  41     struct any_data *next;
  42 };
  43 
  44 static void
  45 free_list (krb5_context context, struct any_data *a)
     /* [<][>][^][v][top][bottom][index][help] */
  46 {
  47     struct any_data *next;
  48 
  49     for (; a != NULL; a = next) {
  50         next = a->next;
  51         free (a->name);
  52         if(a->kt)
  53             krb5_kt_close(context, a->kt);
  54         free (a);
  55     }
  56 }
  57 
  58 static krb5_error_code
  59 any_resolve(krb5_context context, const char *name, krb5_keytab id)
     /* [<][>][^][v][top][bottom][index][help] */
  60 {
  61     struct any_data *a, *a0 = NULL, *prev = NULL;
  62     krb5_error_code ret;
  63     char buf[256];
  64 
  65     while (strsep_copy(&name, ",", buf, sizeof(buf)) != -1) {
  66         a = malloc(sizeof(*a));
  67         if (a == NULL) {
  68             ret = ENOMEM;
  69             goto fail;
  70         }
  71         if (a0 == NULL) {
  72             a0 = a;
  73             a->name = strdup(buf);
  74             if (a->name == NULL) {
  75                 ret = ENOMEM;
  76                 krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
  77                 goto fail;
  78             }
  79         } else
  80             a->name = NULL;
  81         if (prev != NULL)
  82             prev->next = a;
  83         a->next = NULL;
  84         ret = krb5_kt_resolve (context, buf, &a->kt);
  85         if (ret)
  86             goto fail;
  87         prev = a;
  88     }
  89     if (a0 == NULL) {
  90         krb5_set_error_message(context, ENOENT, N_("empty ANY: keytab", ""));
  91         return ENOENT;
  92     }
  93     id->data = a0;
  94     return 0;
  95  fail:
  96     free_list (context, a0);
  97     return ret;
  98 }
  99 
 100 static krb5_error_code
 101 any_get_name (krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 102               krb5_keytab id,
 103               char *name,
 104               size_t namesize)
 105 {
 106     struct any_data *a = id->data;
 107     strlcpy(name, a->name, namesize);
 108     return 0;
 109 }
 110 
 111 static krb5_error_code
 112 any_close (krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 113            krb5_keytab id)
 114 {
 115     struct any_data *a = id->data;
 116 
 117     free_list (context, a);
 118     return 0;
 119 }
 120 
 121 struct any_cursor_extra_data {
 122     struct any_data *a;
 123     krb5_kt_cursor cursor;
 124 };
 125 
 126 static krb5_error_code
 127 any_start_seq_get(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 128                   krb5_keytab id,
 129                   krb5_kt_cursor *c)
 130 {
 131     struct any_data *a = id->data;
 132     struct any_cursor_extra_data *ed;
 133     krb5_error_code ret;
 134 
 135     c->data = malloc (sizeof(struct any_cursor_extra_data));
 136     if(c->data == NULL){
 137         krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
 138         return ENOMEM;
 139     }
 140     ed = (struct any_cursor_extra_data *)c->data;
 141     for (ed->a = a; ed->a != NULL; ed->a = ed->a->next) {
 142         ret = krb5_kt_start_seq_get(context, ed->a->kt, &ed->cursor);
 143         if (ret == 0)
 144             break;
 145     }
 146     if (ed->a == NULL) {
 147         free (c->data);
 148         c->data = NULL;
 149         krb5_clear_error_message (context);
 150         return KRB5_KT_END;
 151     }
 152     return 0;
 153 }
 154 
 155 static krb5_error_code
 156 any_next_entry (krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 157                 krb5_keytab id,
 158                 krb5_keytab_entry *entry,
 159                 krb5_kt_cursor *cursor)
 160 {
 161     krb5_error_code ret, ret2;
 162     struct any_cursor_extra_data *ed;
 163 
 164     ed = (struct any_cursor_extra_data *)cursor->data;
 165     do {
 166         ret = krb5_kt_next_entry(context, ed->a->kt, entry, &ed->cursor);
 167         if (ret == 0)
 168             return 0;
 169         else if (ret != KRB5_KT_END)
 170             return ret;
 171 
 172         ret2 = krb5_kt_end_seq_get (context, ed->a->kt, &ed->cursor);
 173         if (ret2)
 174             return ret2;
 175         while ((ed->a = ed->a->next) != NULL) {
 176             ret2 = krb5_kt_start_seq_get(context, ed->a->kt, &ed->cursor);
 177             if (ret2 == 0)
 178                 break;
 179         }
 180         if (ed->a == NULL) {
 181             krb5_clear_error_message (context);
 182             return KRB5_KT_END;
 183         }
 184     } while (1);
 185 }
 186 
 187 static krb5_error_code
 188 any_end_seq_get(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 189                 krb5_keytab id,
 190                 krb5_kt_cursor *cursor)
 191 {
 192     krb5_error_code ret = 0;
 193     struct any_cursor_extra_data *ed;
 194 
 195     ed = (struct any_cursor_extra_data *)cursor->data;
 196     if (ed->a != NULL)
 197         ret = krb5_kt_end_seq_get(context, ed->a->kt, &ed->cursor);
 198     free (ed);
 199     cursor->data = NULL;
 200     return ret;
 201 }
 202 
 203 static krb5_error_code
 204 any_add_entry(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 205               krb5_keytab id,
 206               krb5_keytab_entry *entry)
 207 {
 208     struct any_data *a = id->data;
 209     krb5_error_code ret;
 210     while(a != NULL) {
 211         ret = krb5_kt_add_entry(context, a->kt, entry);
 212         if(ret != 0 && ret != KRB5_KT_NOWRITE) {
 213             krb5_set_error_message(context, ret,
 214                                    N_("failed to add entry to %s", ""),
 215                                    a->name);
 216             return ret;
 217         }
 218         a = a->next;
 219     }
 220     return 0;
 221 }
 222 
 223 static krb5_error_code
 224 any_remove_entry(krb5_context context,
     /* [<][>][^][v][top][bottom][index][help] */
 225                  krb5_keytab id,
 226                  krb5_keytab_entry *entry)
 227 {
 228     struct any_data *a = id->data;
 229     krb5_error_code ret;
 230     int found = 0;
 231     while(a != NULL) {
 232         ret = krb5_kt_remove_entry(context, a->kt, entry);
 233         if(ret == 0)
 234             found++;
 235         else {
 236             if(ret != KRB5_KT_NOWRITE && ret != KRB5_KT_NOTFOUND) {
 237                 krb5_set_error_message(context, ret,
 238                                        N_("Failed to remove keytab "
 239                                           "entry from %s", "keytab name"),
 240                                        a->name);
 241                 return ret;
 242             }
 243         }
 244         a = a->next;
 245     }
 246     if(!found)
 247         return KRB5_KT_NOTFOUND;
 248     return 0;
 249 }
 250 
 251 const krb5_kt_ops krb5_any_ops = {
 252     "ANY",
 253     any_resolve,
 254     any_get_name,
 255     any_close,
 256     NULL, /* get */
 257     any_start_seq_get,
 258     any_next_entry,
 259     any_end_seq_get,
 260     any_add_entry,
 261     any_remove_entry
 262 };

/* [<][>][^][v][top][bottom][index][help] */