root/source4/heimdal/lib/gssapi/mech/context.c

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

DEFINITIONS

This source file includes following definitions.
  1. destroy_context
  2. _gss_mechglue_thread
  3. _gss_mg_get_error
  4. _gss_mg_error
  5. gss_mg_collect_error

   1 #include "mech/mech_locl.h"
   2 #include "heim_threads.h"
   3 
   4 RCSID("$Id$");
   5 
   6 struct mg_thread_ctx {
   7     gss_OID mech;
   8     OM_uint32 maj_stat;
   9     OM_uint32 min_stat;
  10     gss_buffer_desc maj_error;
  11     gss_buffer_desc min_error;
  12 };
  13 
  14 static HEIMDAL_MUTEX context_mutex = HEIMDAL_MUTEX_INITIALIZER;
  15 static int created_key;
  16 static HEIMDAL_thread_key context_key;
  17 
  18 
  19 static void
  20 destroy_context(void *ptr)
     /* [<][>][^][v][top][bottom][index][help] */
  21 {
  22     struct mg_thread_ctx *mg = ptr;
  23     OM_uint32 junk;
  24 
  25     if (mg == NULL)
  26         return;
  27 
  28     gss_release_buffer(&junk, &mg->maj_error);
  29     gss_release_buffer(&junk, &mg->min_error);
  30     free(mg);
  31 }
  32 
  33 
  34 static struct mg_thread_ctx *
  35 _gss_mechglue_thread(void)
     /* [<][>][^][v][top][bottom][index][help] */
  36 {
  37     struct mg_thread_ctx *ctx;
  38     int ret = 0;
  39 
  40     HEIMDAL_MUTEX_lock(&context_mutex);
  41 
  42     if (!created_key) {
  43         HEIMDAL_key_create(&context_key, destroy_context, ret);
  44         if (ret) {
  45             HEIMDAL_MUTEX_unlock(&context_mutex);
  46             return NULL;
  47         }
  48         created_key = 1;
  49     }
  50     HEIMDAL_MUTEX_unlock(&context_mutex);
  51 
  52     ctx = HEIMDAL_getspecific(context_key);
  53     if (ctx == NULL) {
  54 
  55         ctx = calloc(1, sizeof(*ctx));
  56         if (ctx == NULL)
  57             return NULL;
  58         HEIMDAL_setspecific(context_key, ctx, ret);
  59         if (ret) {
  60             free(ctx);
  61             return NULL;
  62         }
  63     }
  64     return ctx;
  65 }
  66 
  67 OM_uint32
  68 _gss_mg_get_error(const gss_OID mech, OM_uint32 type,
     /* [<][>][^][v][top][bottom][index][help] */
  69                   OM_uint32 value, gss_buffer_t string)
  70 {
  71     struct mg_thread_ctx *mg;
  72 
  73     mg = _gss_mechglue_thread();
  74     if (mg == NULL)
  75         return GSS_S_BAD_STATUS;
  76 
  77 #if 0
  78     /*
  79      * We cant check the mech here since a pseudo-mech might have
  80      * called an lower layer and then the mech info is all broken
  81      */
  82     if (mech != NULL && gss_oid_equal(mg->mech, mech) == 0)
  83         return GSS_S_BAD_STATUS;
  84 #endif
  85 
  86     switch (type) {
  87     case GSS_C_GSS_CODE: {
  88         if (value != mg->maj_stat || mg->maj_error.length == 0)
  89             break;
  90         string->value = malloc(mg->maj_error.length);
  91         string->length = mg->maj_error.length;
  92         memcpy(string->value, mg->maj_error.value, mg->maj_error.length);
  93         return GSS_S_COMPLETE;
  94     }
  95     case GSS_C_MECH_CODE: {
  96         if (value != mg->min_stat || mg->min_error.length == 0)
  97             break;
  98         string->value = malloc(mg->min_error.length);
  99         string->length = mg->min_error.length;
 100         memcpy(string->value, mg->min_error.value, mg->min_error.length);
 101         return GSS_S_COMPLETE;
 102     }
 103     }
 104     string->value = NULL;
 105     string->length = 0;
 106     return GSS_S_BAD_STATUS;
 107 }
 108 
 109 void
 110 _gss_mg_error(gssapi_mech_interface m, OM_uint32 maj, OM_uint32 min)
     /* [<][>][^][v][top][bottom][index][help] */
 111 {
 112     OM_uint32 major_status, minor_status;
 113     OM_uint32 message_content;
 114     struct mg_thread_ctx *mg;
 115 
 116     /*
 117      * Mechs without gss_display_status() does
 118      * gss_mg_collect_error() by themself.
 119      */
 120     if (m->gm_display_status == NULL)
 121         return ;
 122 
 123     mg = _gss_mechglue_thread();
 124     if (mg == NULL)
 125         return;
 126 
 127     gss_release_buffer(&minor_status, &mg->maj_error);
 128     gss_release_buffer(&minor_status, &mg->min_error);
 129 
 130     mg->mech = &m->gm_mech_oid;
 131     mg->maj_stat = maj;
 132     mg->min_stat = min;
 133 
 134     major_status = m->gm_display_status(&minor_status,
 135                                         maj,
 136                                         GSS_C_GSS_CODE,
 137                                         &m->gm_mech_oid,
 138                                         &message_content,
 139                                         &mg->maj_error);
 140     if (GSS_ERROR(major_status)) {
 141         mg->maj_error.value = NULL;
 142         mg->maj_error.length = 0;
 143     }
 144     major_status = m->gm_display_status(&minor_status,
 145                                         min,
 146                                         GSS_C_MECH_CODE,
 147                                         &m->gm_mech_oid,
 148                                         &message_content,
 149                                         &mg->min_error);
 150     if (GSS_ERROR(major_status)) {
 151         mg->min_error.value = NULL;
 152         mg->min_error.length = 0;
 153     }
 154 }
 155 
 156 void
 157 gss_mg_collect_error(gss_OID mech, OM_uint32 maj, OM_uint32 min)
     /* [<][>][^][v][top][bottom][index][help] */
 158 {
 159     gssapi_mech_interface m = __gss_get_mechanism(mech);
 160     if (m == NULL)
 161         return;
 162     _gss_mg_error(m, maj, min);
 163 }

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