Check "auth event notification" param in log_json
[nivanova/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
29 #undef DBGC_CLASS
30 #define DBGC_CLASS DBGC_AUTH
31
32 NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx,
33                                           struct gensec_security *gensec_security,
34                                           struct smb_krb5_context *smb_krb5_context,
35                                           DATA_BLOB *pac_blob,
36                                           const char *principal_string,
37                                           const struct tsocket_address *remote_address,
38                                           struct auth_session_info **session_info)
39 {
40         uint32_t session_info_flags = 0;
41
42         if (gensec_security->want_features & GENSEC_FEATURE_UNIX_TOKEN) {
43                 session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
44         }
45
46         session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
47
48         if (!pac_blob) {
49                 if (gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) {
50                         DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n",
51                                   principal_string));
52                         return NT_STATUS_ACCESS_DENIED;
53                 }
54                 DBG_NOTICE("Unable to find PAC for %s, resorting to local "
55                            "user lookup\n", principal_string);
56         }
57
58         if (gensec_security->auth_context && gensec_security->auth_context->generate_session_info_pac) {
59                 return gensec_security->auth_context->generate_session_info_pac(gensec_security->auth_context,
60                                                                                 mem_ctx,
61                                                                                 smb_krb5_context,
62                                                                                 pac_blob,
63                                                                                 principal_string,
64                                                                                 remote_address,
65                                                                                 session_info_flags,
66                                                                                 session_info);
67         } else {
68                 DEBUG(0, ("Cannot generate a session_info without the auth_context\n"));
69                 return NT_STATUS_INTERNAL_ERROR;
70         }
71 }
72
73 /*
74   magic check a GSS-API wrapper packet for an Kerberos OID
75 */
76 static bool gensec_gssapi_check_oid(const DATA_BLOB *blob, const char *oid)
77 {
78         bool ret = false;
79         struct asn1_data *data = asn1_init(NULL);
80
81         if (!data) return false;
82
83         if (!asn1_load(data, *blob)) goto err;
84         if (!asn1_start_tag(data, ASN1_APPLICATION(0))) goto err;
85         if (!asn1_check_OID(data, oid)) goto err;
86
87         ret = !asn1_has_error(data);
88
89   err:
90
91         asn1_free(data);
92         return ret;
93 }
94
95 /**
96  * Check if the packet is one for the KRB5 mechansim
97  *
98  * NOTE: This is a helper that can be employed by multiple mechanisms, do
99  * not make assumptions about the private_data
100  *
101  * @param gensec_security GENSEC state, unused
102  * @param in The request, as a DATA_BLOB
103  * @return Error, INVALID_PARAMETER if it's not a packet for us
104  *                or NT_STATUS_OK if the packet is ok.
105  */
106
107 NTSTATUS gensec_magic_check_krb5_oid(struct gensec_security *unused,
108                                         const DATA_BLOB *blob)
109 {
110         if (gensec_gssapi_check_oid(blob, GENSEC_OID_KERBEROS5)) {
111                 return NT_STATUS_OK;
112         } else {
113                 return NT_STATUS_INVALID_PARAMETER;
114         }
115 }
116
117 void gensec_child_want_feature(struct gensec_security *gensec_security,
118                                uint32_t feature)
119 {
120         struct gensec_security *child_security = gensec_security->child_security;
121
122         gensec_security->want_features |= feature;
123         if (child_security == NULL) {
124                 return;
125         }
126         gensec_want_feature(child_security, feature);
127 }
128
129 bool gensec_child_have_feature(struct gensec_security *gensec_security,
130                                uint32_t feature)
131 {
132         struct gensec_security *child_security = gensec_security->child_security;
133
134         if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) {
135                 /*
136                  * All mechs with sub (child) mechs need to provide DCERPC
137                  * header signing! This is required because the negotiation
138                  * of header signing is done before the authentication
139                  * is completed.
140                  */
141                 return true;
142         }
143
144         if (child_security == NULL) {
145                 return false;
146         }
147
148         return gensec_have_feature(child_security, feature);
149 }
150
151 NTSTATUS gensec_child_unseal_packet(struct gensec_security *gensec_security,
152                                     uint8_t *data, size_t length,
153                                     const uint8_t *whole_pdu, size_t pdu_length,
154                                     const DATA_BLOB *sig)
155 {
156         if (gensec_security->child_security == NULL) {
157                 return NT_STATUS_INVALID_PARAMETER;
158         }
159
160         return gensec_unseal_packet(gensec_security->child_security,
161                                     data, length,
162                                     whole_pdu, pdu_length,
163                                     sig);
164 }
165
166 NTSTATUS gensec_child_check_packet(struct gensec_security *gensec_security,
167                                    const uint8_t *data, size_t length,
168                                    const uint8_t *whole_pdu, size_t pdu_length,
169                                    const DATA_BLOB *sig)
170 {
171         if (gensec_security->child_security == NULL) {
172                 return NT_STATUS_INVALID_PARAMETER;
173         }
174
175         return gensec_check_packet(gensec_security->child_security,
176                                    data, length,
177                                    whole_pdu, pdu_length,
178                                    sig);
179 }
180
181 NTSTATUS gensec_child_seal_packet(struct gensec_security *gensec_security,
182                                   TALLOC_CTX *mem_ctx,
183                                   uint8_t *data, size_t length,
184                                   const uint8_t *whole_pdu, size_t pdu_length,
185                                   DATA_BLOB *sig)
186 {
187         if (gensec_security->child_security == NULL) {
188                 return NT_STATUS_INVALID_PARAMETER;
189         }
190
191         return gensec_seal_packet(gensec_security->child_security,
192                                   mem_ctx,
193                                   data, length,
194                                   whole_pdu, pdu_length,
195                                   sig);
196 }
197
198 NTSTATUS gensec_child_sign_packet(struct gensec_security *gensec_security,
199                                   TALLOC_CTX *mem_ctx,
200                                   const uint8_t *data, size_t length,
201                                   const uint8_t *whole_pdu, size_t pdu_length,
202                                   DATA_BLOB *sig)
203 {
204         if (gensec_security->child_security == NULL) {
205                 return NT_STATUS_INVALID_PARAMETER;
206         }
207
208         return gensec_sign_packet(gensec_security->child_security,
209                                   mem_ctx,
210                                   data, length,
211                                   whole_pdu, pdu_length,
212                                   sig);
213 }
214
215 NTSTATUS gensec_child_wrap(struct gensec_security *gensec_security,
216                            TALLOC_CTX *mem_ctx,
217                            const DATA_BLOB *in,
218                            DATA_BLOB *out)
219 {
220         if (gensec_security->child_security == NULL) {
221                 return NT_STATUS_INVALID_PARAMETER;
222         }
223
224         return gensec_wrap(gensec_security->child_security,
225                            mem_ctx, in, out);
226 }
227
228 NTSTATUS gensec_child_unwrap(struct gensec_security *gensec_security,
229                              TALLOC_CTX *mem_ctx,
230                              const DATA_BLOB *in,
231                              DATA_BLOB *out)
232 {
233         if (gensec_security->child_security == NULL) {
234                 return NT_STATUS_INVALID_PARAMETER;
235         }
236
237         return gensec_unwrap(gensec_security->child_security,
238                              mem_ctx, in, out);
239 }
240
241 size_t gensec_child_sig_size(struct gensec_security *gensec_security,
242                              size_t data_size)
243 {
244         if (gensec_security->child_security == NULL) {
245                 return 0;
246         }
247
248         return gensec_sig_size(gensec_security->child_security, data_size);
249 }
250
251 size_t gensec_child_max_input_size(struct gensec_security *gensec_security)
252 {
253         if (gensec_security->child_security == NULL) {
254                 return 0;
255         }
256
257         return gensec_max_input_size(gensec_security->child_security);
258 }
259
260 size_t gensec_child_max_wrapped_size(struct gensec_security *gensec_security)
261 {
262         if (gensec_security->child_security == NULL) {
263                 return 0;
264         }
265
266         return gensec_max_wrapped_size(gensec_security->child_security);
267 }
268
269 NTSTATUS gensec_child_session_key(struct gensec_security *gensec_security,
270                                   TALLOC_CTX *mem_ctx,
271                                   DATA_BLOB *session_key)
272 {
273         if (gensec_security->child_security == NULL) {
274                 return NT_STATUS_INVALID_PARAMETER;
275         }
276
277         return gensec_session_key(gensec_security->child_security,
278                                   mem_ctx,
279                                   session_key);
280 }
281
282 NTSTATUS gensec_child_session_info(struct gensec_security *gensec_security,
283                                    TALLOC_CTX *mem_ctx,
284                                    struct auth_session_info **session_info)
285 {
286         if (gensec_security->child_security == NULL) {
287                 return NT_STATUS_INVALID_PARAMETER;
288         }
289
290         return gensec_session_info(gensec_security->child_security,
291                                    mem_ctx,
292                                    session_info);
293 }
294
295 NTTIME gensec_child_expire_time(struct gensec_security *gensec_security)
296 {
297         if (gensec_security->child_security == NULL) {
298                 return GENSEC_EXPIRE_TIME_INFINITY;
299         }
300
301         return gensec_expire_time(gensec_security->child_security);
302 }
303
304 const char *gensec_child_final_auth_type(struct gensec_security *gensec_security)
305 {
306         if (gensec_security->child_security == NULL) {
307                 return "NONE";
308         }
309
310         return gensec_final_auth_type(gensec_security->child_security);
311 }