s4:heimdal: import lorikeet-heimdal-200906080040 (commit 904d0124b46eed7a8ad6e5b73e89...
[amitay/samba.git] / source4 / heimdal / lib / gssapi / krb5 / set_cred_option.c
index 5807ef016618bab6ac68d127d76b73c1e451e13d..2a2390f8d1f3a86870c4d4a69ea2ac44a1eb2e53 100644 (file)
  * SUCH DAMAGE.
  */
 
-#include "krb5/gsskrb5_locl.h"
+#include "gsskrb5_locl.h"
 
-RCSID("$Id: set_cred_option.c,v 1.4 2006/10/24 20:14:13 lha Exp $");
+RCSID("$Id$");
 
+/* 1.2.752.43.13.17 */
+static gss_OID_desc gss_krb5_cred_no_ci_flags_x_oid_desc =
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x11")};
+
+gss_OID GSS_KRB5_CRED_NO_CI_FLAGS_X = &gss_krb5_cred_no_ci_flags_x_oid_desc;
+
+/* 1.2.752.43.13.18 */
 static gss_OID_desc gss_krb5_import_cred_x_oid_desc =
-{9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x04"}; /* XXX */
+{6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x12")};
 
 gss_OID GSS_KRB5_IMPORT_CRED_X = &gss_krb5_import_cred_x_oid_desc;
 
+
+
 static OM_uint32
 import_cred(OM_uint32 *minor_status,
+           krb5_context context,
             gss_cred_id_t *cred_handle,
             const gss_buffer_t value)
 {
@@ -71,7 +81,7 @@ import_cred(OM_uint32 *minor_status,
        goto out;
     }
     if (str[0]) {
-       ret = krb5_cc_resolve(_gsskrb5_context, str, &id);
+       ret = krb5_cc_resolve(context, str, &id);
        if (ret) {
            *minor_status = ret;
            major_stat =  GSS_S_FAILURE;
@@ -84,7 +94,7 @@ import_cred(OM_uint32 *minor_status,
     /* keytab principal name */
     ret = krb5_ret_string(sp, &str);
     if (ret == 0 && str[0])
-       ret = krb5_parse_name(_gsskrb5_context, str, &keytab_principal);
+       ret = krb5_parse_name(context, str, &keytab_principal);
     if (ret) {
        *minor_status = ret;
        major_stat = GSS_S_FAILURE;
@@ -101,7 +111,7 @@ import_cred(OM_uint32 *minor_status,
        goto out;
     }
     if (str[0]) {
-       ret = krb5_kt_resolve(_gsskrb5_context, str, &keytab);
+       ret = krb5_kt_resolve(context, str, &keytab);
        if (ret) {
            *minor_status = ret;
            major_stat =  GSS_S_FAILURE;
@@ -115,11 +125,11 @@ import_cred(OM_uint32 *minor_status,
                                      keytab, cred_handle);
 out:
     if (id)
-       krb5_cc_close(_gsskrb5_context, id);
+       krb5_cc_close(context, id);
     if (keytab_principal)
-       krb5_free_principal(_gsskrb5_context, keytab_principal);
+       krb5_free_principal(context, keytab_principal);
     if (keytab)
-       krb5_kt_close(_gsskrb5_context, keytab);
+       krb5_kt_close(context, keytab);
     if (str)
        free(str);
     if (sp)
@@ -129,6 +139,99 @@ out:
 }
 
 
+static OM_uint32
+allowed_enctypes(OM_uint32 *minor_status,
+                krb5_context context,
+                gss_cred_id_t *cred_handle,
+                const gss_buffer_t value)
+{
+    OM_uint32 major_stat;
+    krb5_error_code ret;
+    size_t len, i;
+    krb5_enctype *enctypes = NULL;
+    krb5_storage *sp = NULL;
+    gsskrb5_cred cred;
+
+    if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) {
+       *minor_status = 0;
+       return GSS_S_FAILURE;
+    }
+
+    cred = (gsskrb5_cred)*cred_handle;
+
+    if ((value->length % 4) != 0) {
+       *minor_status = 0;
+       major_stat = GSS_S_FAILURE;
+       goto out;
+    }
+
+    len = value->length / 4;
+    enctypes = malloc((len + 1) * 4);
+    if (enctypes == NULL) {
+       *minor_status = ENOMEM;
+       major_stat = GSS_S_FAILURE;
+       goto out;
+    }
+
+    sp = krb5_storage_from_mem(value->value, value->length);
+    if (sp == NULL) {
+       *minor_status = ENOMEM;
+       major_stat = GSS_S_FAILURE;
+       goto out;
+    }
+
+    for (i = 0; i < len; i++) {
+       uint32_t e;
+
+       ret = krb5_ret_uint32(sp, &e);
+       if (ret) {
+           *minor_status = ret;
+           major_stat =  GSS_S_FAILURE;
+           goto out;
+       }
+       enctypes[i] = e;
+    }
+    enctypes[i] = 0;
+
+    if (cred->enctypes)
+       free(cred->enctypes);
+    cred->enctypes = enctypes;
+
+    krb5_storage_free(sp);
+
+    return GSS_S_COMPLETE;
+
+out:
+    if (sp)
+       krb5_storage_free(sp);
+    if (enctypes)
+       free(enctypes);
+
+    return major_stat;
+}
+
+static OM_uint32
+no_ci_flags(OM_uint32 *minor_status,
+           krb5_context context,
+           gss_cred_id_t *cred_handle,
+           const gss_buffer_t value)
+{
+    gsskrb5_cred cred;
+
+    if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) {
+       *minor_status = 0;
+       return GSS_S_FAILURE;
+    }
+
+    cred = (gsskrb5_cred)*cred_handle;
+    cred->cred_flags |= GSS_CF_NO_CI_FLAGS;
+       
+    *minor_status = 0;
+    return GSS_S_COMPLETE;
+
+}
+
+
 OM_uint32
 _gsskrb5_set_cred_option
            (OM_uint32 *minor_status,
@@ -136,16 +239,25 @@ _gsskrb5_set_cred_option
             const gss_OID desired_object,
             const gss_buffer_t value)
 {
-    GSSAPI_KRB5_INIT ();
+    krb5_context context;
+
+    GSSAPI_KRB5_INIT (&context);
 
     if (value == GSS_C_NO_BUFFER) {
        *minor_status = EINVAL;
        return GSS_S_FAILURE;
     }
 
-    if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_CRED_X)) {
-       return import_cred(minor_status, cred_handle, value);
+    if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_CRED_X))
+       return import_cred(minor_status, context, cred_handle, value);
+
+    if (gss_oid_equal(desired_object, GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X))
+       return allowed_enctypes(minor_status, context, cred_handle, value);
+
+    if (gss_oid_equal(desired_object, GSS_KRB5_CRED_NO_CI_FLAGS_X)) {
+       return no_ci_flags(minor_status, context, cred_handle, value);
     }
+       
 
     *minor_status = EINVAL;
     return GSS_S_FAILURE;