Fix one more warning introduced by changing the size of UNIX_USER_TOKEN->ngroups...
[Samba.git] / source3 / smbd / signing.c
blob8945cd3ec1cfb98de415f46d420ffd5f2d5240e9
1 /*
2 Unix SMB/CIFS implementation.
3 SMB Signing Code
4 Copyright (C) Jeremy Allison 2003.
5 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
6 Copyright (C) Stefan Metzmacher 2009
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "smbd/globals.h"
24 #include "smb_signing.h"
26 /***********************************************************
27 Called to validate an incoming packet from the client.
28 ************************************************************/
30 bool srv_check_sign_mac(struct smbd_server_connection *conn,
31 const char *inbuf, uint32_t *seqnum,
32 bool trusted_channel)
34 /* Check if it's a non-session message. */
35 if(CVAL(inbuf,0)) {
36 return true;
39 if (trusted_channel) {
40 NTSTATUS status;
42 if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) {
43 DEBUG(1,("smb_signing_check_pdu: Can't check signature "
44 "on short packet! smb_len = %u\n",
45 smb_len(inbuf)));
46 return false;
49 status = NT_STATUS(IVAL(inbuf, smb_ss_field + 4));
50 if (!NT_STATUS_IS_OK(status)) {
51 DEBUG(1,("smb_signing_check_pdu: trusted channel passed %s\n",
52 nt_errstr(status)));
53 return false;
56 *seqnum = IVAL(inbuf, smb_ss_field);
57 return true;
60 *seqnum = smb_signing_next_seqnum(conn->smb1.signing_state, false);
61 return smb_signing_check_pdu(conn->smb1.signing_state,
62 (const uint8_t *)inbuf,
63 *seqnum);
66 /***********************************************************
67 Called to sign an outgoing packet to the client.
68 ************************************************************/
70 void srv_calculate_sign_mac(struct smbd_server_connection *conn,
71 char *outbuf, uint32_t seqnum)
73 /* Check if it's a non-session message. */
74 if(CVAL(outbuf,0)) {
75 return;
78 smb_signing_sign_pdu(conn->smb1.signing_state, (uint8_t *)outbuf, seqnum);
82 /***********************************************************
83 Called to indicate a oneway request
84 ************************************************************/
85 void srv_cancel_sign_response(struct smbd_server_connection *conn)
87 smb_signing_cancel_reply(conn->smb1.signing_state, true);
90 struct smbd_shm_signing {
91 size_t shm_size;
92 uint8_t *shm_pointer;
94 /* we know the signing engine will only allocate 2 chunks */
95 uint8_t *ptr1;
96 size_t len1;
97 uint8_t *ptr2;
98 size_t len2;
101 static int smbd_shm_signing_destructor(struct smbd_shm_signing *s)
103 anonymous_shared_free(s->shm_pointer);
104 return 0;
107 static void *smbd_shm_signing_alloc(TALLOC_CTX *mem_ctx, size_t len)
109 struct smbd_shm_signing *s = talloc_get_type_abort(mem_ctx,
110 struct smbd_shm_signing);
112 if (s->ptr1 == NULL) {
113 s->len1 = len;
114 if (len % 8) {
115 s->len1 += (8 - (len % 8));
117 if (s->len1 > s->shm_size) {
118 s->len1 = 0;
119 errno = ENOMEM;
120 return NULL;
122 s->ptr1 = s->shm_pointer;
123 return s->ptr1;
126 if (s->ptr2 == NULL) {
127 s->len2 = len;
128 if (s->len2 > (s->shm_size - s->len1)) {
129 s->len2 = 0;
130 errno = ENOMEM;
131 return NULL;
133 s->ptr2 = s->shm_pointer + s->len1;
134 return s->ptr2;
137 errno = ENOMEM;
138 return NULL;
141 static void smbd_shm_signing_free(TALLOC_CTX *mem_ctx, void *ptr)
143 struct smbd_shm_signing *s = talloc_get_type_abort(mem_ctx,
144 struct smbd_shm_signing);
146 if (s->ptr2 == ptr) {
147 s->ptr2 = NULL;
148 s->len2 = 0;
152 /***********************************************************
153 Called by server negprot when signing has been negotiated.
154 ************************************************************/
156 bool srv_init_signing(struct smbd_server_connection *conn)
158 bool allowed = true;
159 bool mandatory = false;
161 switch (lp_server_signing()) {
162 case Required:
163 mandatory = true;
164 break;
165 case Auto:
166 break;
167 case True:
168 break;
169 case False:
170 allowed = false;
171 break;
174 if (lp_async_smb_echo_handler()) {
175 struct smbd_shm_signing *s;
177 /* setup the signing state in shared memory */
178 s = talloc_zero(smbd_event_context(), struct smbd_shm_signing);
179 if (s == NULL) {
180 return false;
182 s->shm_size = 4096;
183 s->shm_pointer =
184 (uint8_t *)anonymous_shared_allocate(s->shm_size);
185 if (s->shm_pointer == NULL) {
186 talloc_free(s);
187 return false;
189 talloc_set_destructor(s, smbd_shm_signing_destructor);
190 conn->smb1.signing_state = smb_signing_init_ex(s,
191 allowed, mandatory,
192 smbd_shm_signing_alloc,
193 smbd_shm_signing_free);
194 if (!conn->smb1.signing_state) {
195 return false;
197 return true;
200 conn->smb1.signing_state = smb_signing_init(smbd_event_context(),
201 allowed, mandatory);
202 if (!conn->smb1.signing_state) {
203 return false;
206 return true;
209 void srv_set_signing_negotiated(struct smbd_server_connection *conn)
211 smb_signing_set_negotiated(conn->smb1.signing_state);
214 /***********************************************************
215 Returns whether signing is active. We can't use sendfile or raw
216 reads/writes if it is.
217 ************************************************************/
219 bool srv_is_signing_active(struct smbd_server_connection *conn)
221 return smb_signing_is_active(conn->smb1.signing_state);
225 /***********************************************************
226 Returns whether signing is negotiated. We can't use it unless it was
227 in the negprot.
228 ************************************************************/
230 bool srv_is_signing_negotiated(struct smbd_server_connection *conn)
232 return smb_signing_is_negotiated(conn->smb1.signing_state);
235 /***********************************************************
236 Turn on signing from this packet onwards.
237 ************************************************************/
239 void srv_set_signing(struct smbd_server_connection *conn,
240 const DATA_BLOB user_session_key,
241 const DATA_BLOB response)
243 bool negotiated;
244 bool mandatory;
246 if (!user_session_key.length)
247 return;
249 negotiated = smb_signing_is_negotiated(conn->smb1.signing_state);
250 mandatory = smb_signing_is_mandatory(conn->smb1.signing_state);
252 if (!negotiated && !mandatory) {
253 DEBUG(5,("srv_set_signing: signing negotiated = %u, "
254 "mandatory_signing = %u. Not allowing smb signing.\n",
255 negotiated, mandatory));
256 return;
259 if (!smb_signing_activate(conn->smb1.signing_state,
260 user_session_key, response)) {
261 return;
264 DEBUG(3,("srv_set_signing: turning on SMB signing: "
265 "signing negotiated = %u, mandatory_signing = %u.\n",
266 negotiated, mandatory));