auth: Fix code spelling
[gd/samba-autobuild/.git] / auth / gensec / gensec_util.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Generic Authentication Interface
5
6    Copyright (C) Andrew Tridgell 2003
7    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2006
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "auth/gensec/gensec.h"
25 #include "auth/gensec/gensec_internal.h"
26 #include "auth/common_auth.h"
27 #include "../lib/util/asn1.h"
28 #include "param/param.h"
29 #include "libds/common/roles.h"
30
31 #undef DBGC_CLASS
32 #define DBGC_CLASS DBGC_AUTH
33
34 NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx,
35                                           struct gensec_security *gensec_security,
36                                           struct smb_krb5_context *smb_krb5_context,
37                                           DATA_BLOB *pac_blob,
38                                           const char *principal_string,
39                                           const struct tsocket_address *remote_address,
40                                           struct auth_session_info **session_info)
41 {
42         uint32_t session_info_flags = 0;
43         struct auth4_context *auth_context = NULL;
44         NTSTATUS status;
45
46         if (gensec_security->want_features & GENSEC_FEATURE_UNIX_TOKEN) {
47                 session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
48         }
49
50         session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
51
52         if (!pac_blob) {
53                 enum server_role server_role =
54                         lpcfg_server_role(gensec_security->settings->lp_ctx);
55
56                 /*
57                  * For any domain setup (DC or member) we require having
58                  * a PAC, as the service ticket comes from an AD DC,
59                  * which will always provide a PAC, unless
60                  * UF_NO_AUTH_DATA_REQUIRED is configured for our
61                  * account, but that's just an invalid configuration,
62                  * the admin configured for us!
63                  *
64                  * As a legacy case, we still allow kerberos tickets from an MIT
65                  * realm, but only in standalone mode. In that mode we'll only
66                  * ever accept a kerberos authentication with a keytab file
67                  * being explicitly configured via the 'keytab method' option.
68                  */
69                 if (server_role != ROLE_STANDALONE) {
70                         DBG_WARNING("Unable to find PAC in ticket from %s, "
71                                     "failing to allow access\n",
72                                     principal_string);
73                         return NT_STATUS_NO_IMPERSONATION_TOKEN;
74                 }
75                 DBG_NOTICE("Unable to find PAC for %s, resorting to local "
76                            "user lookup\n", principal_string);
77         }
78
79         auth_context = gensec_security->auth_context;
80
81         if ((auth_context == NULL) ||
82             (auth_context->generate_session_info_pac == NULL)) {
83                 DBG_ERR("Cannot generate a session_info without "
84                         "the auth_context\n");
85                 return NT_STATUS_INTERNAL_ERROR;
86         }
87
88         status = auth_context->generate_session_info_pac(
89                 auth_context,
90                 mem_ctx,
91                 smb_krb5_context,
92                 pac_blob,
93                 principal_string,
94                 remote_address,
95                 session_info_flags,
96                 session_info);
97         return status;
98 }
99
100 /*
101   magic check a GSS-API wrapper packet for an Kerberos OID
102 */
103 static bool gensec_gssapi_check_oid(const DATA_BLOB *blob, const char *oid)
104 {
105         bool ret = false;
106         struct asn1_data *data = asn1_init(NULL, ASN1_MAX_TREE_DEPTH);
107
108         if (!data) return false;
109
110         if (!asn1_load(data, *blob)) goto err;
111         if (!asn1_start_tag(data, ASN1_APPLICATION(0))) goto err;
112         if (!asn1_check_OID(data, oid)) goto err;
113
114         ret = !asn1_has_error(data);
115
116   err:
117
118         asn1_free(data);
119         return ret;
120 }
121
122 /**
123  * Check if the packet is one for the KRB5 mechanism
124  *
125  * NOTE: This is a helper that can be employed by multiple mechanisms, do
126  * not make assumptions about the private_data
127  *
128  * @param gensec_security GENSEC state, unused
129  * @param in The request, as a DATA_BLOB
130  * @return Error, INVALID_PARAMETER if it's not a packet for us
131  *                or NT_STATUS_OK if the packet is ok.
132  */
133
134 NTSTATUS gensec_magic_check_krb5_oid(struct gensec_security *unused,
135                                         const DATA_BLOB *blob)
136 {
137         if (gensec_gssapi_check_oid(blob, GENSEC_OID_KERBEROS5)) {
138                 return NT_STATUS_OK;
139         } else {
140                 return NT_STATUS_INVALID_PARAMETER;
141         }
142 }
143
144 void gensec_child_want_feature(struct gensec_security *gensec_security,
145                                uint32_t feature)
146 {
147         struct gensec_security *child_security = gensec_security->child_security;
148
149         gensec_security->want_features |= feature;
150         if (child_security == NULL) {
151                 return;
152         }
153         gensec_want_feature(child_security, feature);
154 }
155
156 bool gensec_child_have_feature(struct gensec_security *gensec_security,
157                                uint32_t feature)
158 {
159         struct gensec_security *child_security = gensec_security->child_security;
160
161         if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) {
162                 /*
163                  * All mechs with sub (child) mechs need to provide DCERPC
164                  * header signing! This is required because the negotiation
165                  * of header signing is done before the authentication
166                  * is completed.
167                  */
168                 return true;
169         }
170
171         if (child_security == NULL) {
172                 return false;
173         }
174
175         return gensec_have_feature(child_security, feature);
176 }
177
178 NTSTATUS gensec_child_unseal_packet(struct gensec_security *gensec_security,
179                                     uint8_t *data, size_t length,
180                                     const uint8_t *whole_pdu, size_t pdu_length,
181                                     const DATA_BLOB *sig)
182 {
183         if (gensec_security->child_security == NULL) {
184                 return NT_STATUS_INVALID_PARAMETER;
185         }
186
187         return gensec_unseal_packet(gensec_security->child_security,
188                                     data, length,
189                                     whole_pdu, pdu_length,
190                                     sig);
191 }
192
193 NTSTATUS gensec_child_check_packet(struct gensec_security *gensec_security,
194                                    const uint8_t *data, size_t length,
195                                    const uint8_t *whole_pdu, size_t pdu_length,
196                                    const DATA_BLOB *sig)
197 {
198         if (gensec_security->child_security == NULL) {
199                 return NT_STATUS_INVALID_PARAMETER;
200         }
201
202         return gensec_check_packet(gensec_security->child_security,
203                                    data, length,
204                                    whole_pdu, pdu_length,
205                                    sig);
206 }
207
208 NTSTATUS gensec_child_seal_packet(struct gensec_security *gensec_security,
209                                   TALLOC_CTX *mem_ctx,
210                                   uint8_t *data, size_t length,
211                                   const uint8_t *whole_pdu, size_t pdu_length,
212                                   DATA_BLOB *sig)
213 {
214         if (gensec_security->child_security == NULL) {
215                 return NT_STATUS_INVALID_PARAMETER;
216         }
217
218         return gensec_seal_packet(gensec_security->child_security,
219                                   mem_ctx,
220                                   data, length,
221                                   whole_pdu, pdu_length,
222                                   sig);
223 }
224
225 NTSTATUS gensec_child_sign_packet(struct gensec_security *gensec_security,
226                                   TALLOC_CTX *mem_ctx,
227                                   const uint8_t *data, size_t length,
228                                   const uint8_t *whole_pdu, size_t pdu_length,
229                                   DATA_BLOB *sig)
230 {
231         if (gensec_security->child_security == NULL) {
232                 return NT_STATUS_INVALID_PARAMETER;
233         }
234
235         return gensec_sign_packet(gensec_security->child_security,
236                                   mem_ctx,
237                                   data, length,
238                                   whole_pdu, pdu_length,
239                                   sig);
240 }
241
242 NTSTATUS gensec_child_wrap(struct gensec_security *gensec_security,
243                            TALLOC_CTX *mem_ctx,
244                            const DATA_BLOB *in,
245                            DATA_BLOB *out)
246 {
247         if (gensec_security->child_security == NULL) {
248                 return NT_STATUS_INVALID_PARAMETER;
249         }
250
251         return gensec_wrap(gensec_security->child_security,
252                            mem_ctx, in, out);
253 }
254
255 NTSTATUS gensec_child_unwrap(struct gensec_security *gensec_security,
256                              TALLOC_CTX *mem_ctx,
257                              const DATA_BLOB *in,
258                              DATA_BLOB *out)
259 {
260         if (gensec_security->child_security == NULL) {
261                 return NT_STATUS_INVALID_PARAMETER;
262         }
263
264         return gensec_unwrap(gensec_security->child_security,
265                              mem_ctx, in, out);
266 }
267
268 size_t gensec_child_sig_size(struct gensec_security *gensec_security,
269                              size_t data_size)
270 {
271         if (gensec_security->child_security == NULL) {
272                 return 0;
273         }
274
275         return gensec_sig_size(gensec_security->child_security, data_size);
276 }
277
278 size_t gensec_child_max_input_size(struct gensec_security *gensec_security)
279 {
280         if (gensec_security->child_security == NULL) {
281                 return 0;
282         }
283
284         return gensec_max_input_size(gensec_security->child_security);
285 }
286
287 size_t gensec_child_max_wrapped_size(struct gensec_security *gensec_security)
288 {
289         if (gensec_security->child_security == NULL) {
290                 return 0;
291         }
292
293         return gensec_max_wrapped_size(gensec_security->child_security);
294 }
295
296 NTSTATUS gensec_child_session_key(struct gensec_security *gensec_security,
297                                   TALLOC_CTX *mem_ctx,
298                                   DATA_BLOB *session_key)
299 {
300         if (gensec_security->child_security == NULL) {
301                 return NT_STATUS_INVALID_PARAMETER;
302         }
303
304         return gensec_session_key(gensec_security->child_security,
305                                   mem_ctx,
306                                   session_key);
307 }
308
309 NTSTATUS gensec_child_session_info(struct gensec_security *gensec_security,
310                                    TALLOC_CTX *mem_ctx,
311                                    struct auth_session_info **session_info)
312 {
313         if (gensec_security->child_security == NULL) {
314                 return NT_STATUS_INVALID_PARAMETER;
315         }
316
317         return gensec_session_info(gensec_security->child_security,
318                                    mem_ctx,
319                                    session_info);
320 }
321
322 NTTIME gensec_child_expire_time(struct gensec_security *gensec_security)
323 {
324         if (gensec_security->child_security == NULL) {
325                 return GENSEC_EXPIRE_TIME_INFINITY;
326         }
327
328         return gensec_expire_time(gensec_security->child_security);
329 }
330
331 const char *gensec_child_final_auth_type(struct gensec_security *gensec_security)
332 {
333         if (gensec_security->child_security == NULL) {
334                 return "NONE";
335         }
336
337         return gensec_final_auth_type(gensec_security->child_security);
338 }