summaryrefslogtreecommitdiffstats
path: root/krb5-1.11-gss-client-keytab.patch
blob: 3c1e964d6df26eb22e3733337c83422b48a7fa36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
Originally http://fedorapeople.org/cgit/simo/public_git/krb5.git/commit/?h=gss_cs&id=a3b9bf20df1d976775ed929d8cb5f4844e03b1bf

commit a3b9bf20df1d976775ed929d8cb5f4844e03b1bf
Author: Simo Sorce <simo@redhat.com>
Date:   Thu Mar 28 12:53:01 2013 -0400

    Add support for client keytab from cred store
    
    The new credential store extensions added support for specifying a
    specific ccache name and also a specific keytab to be used for accepting
    security contexts, but did not add a way to specify a client keytab
    to be used in conjunction with the Keytab initiation support added also
    in 1.11
    
    This patch introduces a new URN named client_keytab through which a
    specific client_keytab can be set when calling gss_acquire_cred_from()
    and Keytab Initiation will use that keytab to initialize credentials.

diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
index 4d499e4..8540bf3 100644
--- a/src/lib/gssapi/krb5/acquire_cred.c
+++ b/src/lib/gssapi/krb5/acquire_cred.c
@@ -636,6 +636,7 @@ acquire_init_cred(krb5_context context,
                   OM_uint32 *minor_status,
                   krb5_ccache req_ccache,
                   gss_buffer_t password,
+                  krb5_keytab client_keytab,
                   krb5_gss_cred_id_rec *cred)
 {
     krb5_error_code code;
@@ -659,9 +660,13 @@ acquire_init_cred(krb5_context context,
             goto error;
     }
 
-    code = krb5_kt_client_default(context, &cred->client_keytab);
-    if (code)
-        goto error;
+    if (client_keytab != NULL)
+        cred->client_keytab = client_keytab;
+    else {
+        code = krb5_kt_client_default(context, &cred->client_keytab);
+        if (code)
+            goto error;
+    }
 
     if (password != GSS_C_NO_BUFFER) {
         pwdata = make_data(password->value, password->length);
@@ -719,8 +724,9 @@ static OM_uint32
 acquire_cred_context(krb5_context context, OM_uint32 *minor_status,
                      gss_name_t desired_name, gss_buffer_t password,
                      OM_uint32 time_req, gss_cred_usage_t cred_usage,
-                     krb5_ccache ccache, krb5_keytab keytab,
-                     krb5_boolean iakerb, gss_cred_id_t *output_cred_handle,
+                     krb5_ccache ccache, krb5_keytab client_keytab,
+                     krb5_keytab keytab, krb5_boolean iakerb,
+                     gss_cred_id_t *output_cred_handle,
                      OM_uint32 *time_rec)
 {
     krb5_gss_cred_id_t cred = NULL;
@@ -787,7 +793,8 @@ acquire_cred_context(krb5_context context, OM_uint32 *minor_status,
      * in cred->name if it wasn't set above.
      */
     if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) {
-        ret = acquire_init_cred(context, minor_status, ccache, password, cred);
+        ret = acquire_init_cred(context, minor_status, ccache, password,
+                                client_keytab, cred);
         if (ret != GSS_S_COMPLETE)
             goto error_out;
     }
@@ -864,8 +871,8 @@ acquire_cred(OM_uint32 *minor_status, gss_name_t desired_name,
     }
 
     ret = acquire_cred_context(context, minor_status, desired_name, password,
-                               time_req, cred_usage, ccache, keytab, iakerb,
-                               output_cred_handle, time_rec);
+                               time_req, cred_usage, ccache, NULL, keytab,
+                               iakerb, output_cred_handle, time_rec);
 
 out:
     krb5_free_context(context);
@@ -1130,6 +1137,7 @@ krb5_gss_acquire_cred_from(OM_uint32 *minor_status,
 {
     krb5_context context = NULL;
     krb5_error_code code = 0;
+    krb5_keytab client_keytab = NULL;
     krb5_keytab keytab = NULL;
     krb5_ccache ccache = NULL;
     const char *value;
@@ -1162,6 +1170,19 @@ krb5_gss_acquire_cred_from(OM_uint32 *minor_status,
         }
     }
 
+    ret = kg_value_from_cred_store(cred_store, KRB5_CS_CLI_KEYTAB_URN, &value);
+    if (GSS_ERROR(ret))
+        goto out;
+
+    if (value) {
+        code = krb5_kt_resolve(context, value, &client_keytab);
+        if (code != 0) {
+            *minor_status = code;
+            ret = GSS_S_CRED_UNAVAIL;
+            goto out;
+        }
+    }
+
     ret = kg_value_from_cred_store(cred_store, KRB5_CS_KEYTAB_URN, &value);
     if (GSS_ERROR(ret))
         goto out;
@@ -1176,8 +1197,8 @@ krb5_gss_acquire_cred_from(OM_uint32 *minor_status,
     }
 
     ret = acquire_cred_context(context, minor_status, desired_name, NULL,
-                               time_req, cred_usage, ccache, keytab, 0,
-                               output_cred_handle, time_rec);
+                               time_req, cred_usage, ccache, client_keytab,
+                               keytab, 0, output_cred_handle, time_rec);
 
 out:
     if (ccache != NULL)
diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
index 8215b10..310ff58 100644
--- a/src/lib/gssapi/krb5/gssapiP_krb5.h
+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
@@ -1227,6 +1227,7 @@ data_to_gss(krb5_data *input_k5data, gss_buffer_t output_buffer)
 
 /* Credential store extensions */
 
+#define KRB5_CS_CLI_KEYTAB_URN "client_keytab"
 #define KRB5_CS_KEYTAB_URN "keytab"
 #define KRB5_CS_CCACHE_URN "ccache"