heimdal: update to lorikeet-heimdal rev 801
[kai/samba-autobuild/.git] / source4 / heimdal / lib / gssapi / krb5 / set_sec_context_option.c
index 67f5e8e722f6252237140bb37dcb6bd864f19497..fd76838af514688bf8d61dcd8eb1e74f96501128 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "krb5/gsskrb5_locl.h"
 
-RCSID("$Id: set_sec_context_option.c,v 1.6 2006/10/20 18:58:22 lha Exp $");
+RCSID("$Id: set_sec_context_option.c 23420 2008-07-26 18:37:48Z lha $");
 
 static OM_uint32
 get_bool(OM_uint32 *minor_status,
@@ -51,6 +51,55 @@ get_bool(OM_uint32 *minor_status,
     return GSS_S_COMPLETE;
 }
 
+static OM_uint32
+get_string(OM_uint32 *minor_status,
+          const gss_buffer_t value,
+          char **str)
+{
+    if (value == NULL || value->length == 0) {
+       *str = NULL;
+    } else {
+       *str = malloc(value->length + 1);
+       if (*str == NULL) {
+           *minor_status = 0;
+           return GSS_S_UNAVAILABLE;
+       }
+       memcpy(*str, value->value, value->length);
+       (*str)[value->length] = '\0';
+    }
+    return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+get_int32(OM_uint32 *minor_status,
+         const gss_buffer_t value,
+         OM_uint32 *ret)
+{
+    *minor_status = 0;
+    if (value == NULL || value->length == 0)
+       *ret = 0;
+    else if (value->length == sizeof(*ret))
+       memcpy(ret, value->value, sizeof(*ret));
+    else
+       return GSS_S_UNAVAILABLE;
+
+    return GSS_S_COMPLETE;
+}
+
+static OM_uint32
+set_int32(OM_uint32 *minor_status,
+         const gss_buffer_t value,
+         OM_uint32 set)
+{
+    *minor_status = 0;
+    if (value->length == sizeof(set))
+       memcpy(value->value, &set, sizeof(set));
+    else
+       return GSS_S_UNAVAILABLE;
+
+    return GSS_S_COMPLETE;
+}
+
 OM_uint32
 _gsskrb5_set_sec_context_option
            (OM_uint32 *minor_status,
@@ -58,9 +107,10 @@ _gsskrb5_set_sec_context_option
             const gss_OID desired_object,
             const gss_buffer_t value)
 {
+    krb5_context context;
     OM_uint32 maj_stat;
 
-    GSSAPI_KRB5_INIT ();
+    GSSAPI_KRB5_INIT (&context);
 
     if (value == GSS_C_NO_BUFFER) {
        *minor_status = EINVAL;
@@ -96,23 +146,15 @@ _gsskrb5_set_sec_context_option
        if (maj_stat != GSS_S_COMPLETE)
            return maj_stat;
 
-       krb5_set_dns_canonicalize_hostname(_gsskrb5_context, flag);
+       krb5_set_dns_canonicalize_hostname(context, flag);
        return GSS_S_COMPLETE;
 
     } else if (gss_oid_equal(desired_object, GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X)) {
        char *str;
 
-       if (value == NULL || value->length == 0) {
-           str = NULL;
-       } else {
-           str = malloc(value->length + 1);
-           if (str) {
-               *minor_status = 0;
-               return GSS_S_UNAVAILABLE;
-           }
-           memcpy(str, value->value, value->length);
-           str[value->length] = '\0';
-       }
+       maj_stat = get_string(minor_status, value, &str);
+       if (maj_stat != GSS_S_COMPLETE)
+           return maj_stat;
 
        _gsskrb5_register_acceptor_identity(str);
        free(str);
@@ -120,10 +162,27 @@ _gsskrb5_set_sec_context_option
        *minor_status = 0;
        return GSS_S_COMPLETE;
 
+    } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DEFAULT_REALM_X)) {
+       char *str;
+
+       maj_stat = get_string(minor_status, value, &str);
+       if (maj_stat != GSS_S_COMPLETE)
+           return maj_stat;
+       if (str == NULL) {
+           *minor_status = 0;
+           return GSS_S_CALL_INACCESSIBLE_READ;
+       }
+
+       krb5_set_default_realm(context, str);
+       free(str);
+
+       *minor_status = 0;
+       return GSS_S_COMPLETE;
+
     } else if (gss_oid_equal(desired_object, GSS_KRB5_SEND_TO_KDC_X)) {
 
        if (value == NULL || value->length == 0) {
-           krb5_set_send_to_kdc_func(_gsskrb5_context, NULL, NULL);
+           krb5_set_send_to_kdc_func(context, NULL, NULL);
        } else {
            struct gsskrb5_send_to_kdc c;
 
@@ -132,15 +191,60 @@ _gsskrb5_set_sec_context_option
                return GSS_S_FAILURE;
            }
            memcpy(&c, value->value, sizeof(c));
-           krb5_set_send_to_kdc_func(_gsskrb5_context,
+           krb5_set_send_to_kdc_func(context,
                                      (krb5_send_to_kdc_func)c.func, 
                                      c.ptr);
        }
 
        *minor_status = 0;
        return GSS_S_COMPLETE;
-    }
+    } else if (gss_oid_equal(desired_object, GSS_KRB5_CCACHE_NAME_X)) {
+       char *str;
+
+       maj_stat = get_string(minor_status, value, &str);
+       if (maj_stat != GSS_S_COMPLETE)
+           return maj_stat;
+       if (str == NULL) {
+           *minor_status = 0;
+           return GSS_S_CALL_INACCESSIBLE_READ;
+       }
+
+       *minor_status = krb5_cc_set_default_name(context, str);
+       free(str);
+       if (*minor_status)
+           return GSS_S_FAILURE;
+
+       return GSS_S_COMPLETE;
+    } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_TIME_OFFSET_X)) {
+       OM_uint32 offset;
+       time_t t;
 
+       maj_stat = get_int32(minor_status, value, &offset);
+       if (maj_stat != GSS_S_COMPLETE)
+           return maj_stat;
+
+       t = time(NULL) + offset;
+       
+       krb5_set_real_time(context, t, 0);
+
+       *minor_status = 0;
+       return GSS_S_COMPLETE;
+    } else if (gss_oid_equal(desired_object, GSS_KRB5_GET_TIME_OFFSET_X)) {
+       krb5_timestamp sec;
+       int32_t usec;
+       time_t t;
+
+       t = time(NULL);
+
+       krb5_us_timeofday (context, &sec, &usec);
+
+       maj_stat = set_int32(minor_status, value, sec - t);
+       if (maj_stat != GSS_S_COMPLETE)
+           return maj_stat;
+
+       *minor_status = 0;
+       return GSS_S_COMPLETE;
+    }
 
     *minor_status = EINVAL;
     return GSS_S_FAILURE;