r25598: Add missing become_root/unbecome_root around calls of add_aliases.
[samba.git] / source3 / smbd / seal.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB Transport encryption (sealing) code - server code.
4    Copyright (C) Jeremy Allison 2007.
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21
22 /******************************************************************************
23  Server side encryption.
24 ******************************************************************************/
25
26 /******************************************************************************
27  Global server state.
28 ******************************************************************************/
29
30 struct smb_srv_trans_enc_ctx {
31         struct smb_trans_enc_state *es;
32         AUTH_NTLMSSP_STATE *auth_ntlmssp_state; /* Must be kept in sync with pointer in ec->ntlmssp_state. */
33 };
34
35 static struct smb_srv_trans_enc_ctx *partial_srv_trans_enc_ctx;
36 static struct smb_srv_trans_enc_ctx *srv_trans_enc_ctx;
37
38 /******************************************************************************
39  Is server encryption on ?
40 ******************************************************************************/
41
42 BOOL srv_encryption_on(void)
43 {
44         if (srv_trans_enc_ctx) {
45                 return common_encryption_on(srv_trans_enc_ctx->es);
46         }
47         return False;
48 }
49
50 /******************************************************************************
51  Create an auth_ntlmssp_state and ensure pointer copy is correct.
52 ******************************************************************************/
53
54 static NTSTATUS make_auth_ntlmssp(struct smb_srv_trans_enc_ctx *ec)
55 {
56         NTSTATUS status = auth_ntlmssp_start(&ec->auth_ntlmssp_state);
57         if (!NT_STATUS_IS_OK(status)) {
58                 return nt_status_squash(status);
59         }
60
61         /*
62          * We must remember to update the pointer copy for the common
63          * functions after any auth_ntlmssp_start/auth_ntlmssp_end.
64          */
65         ec->es->s.ntlmssp_state = ec->auth_ntlmssp_state->ntlmssp_state;
66         return status;
67 }
68
69 /******************************************************************************
70  Destroy an auth_ntlmssp_state and ensure pointer copy is correct.
71 ******************************************************************************/
72
73 static void destroy_auth_ntlmssp(struct smb_srv_trans_enc_ctx *ec)
74 {
75         /*
76          * We must remember to update the pointer copy for the common
77          * functions after any auth_ntlmssp_start/auth_ntlmssp_end.
78          */
79
80         if (ec->auth_ntlmssp_state) {
81                 auth_ntlmssp_end(&ec->auth_ntlmssp_state);
82                 /* The auth_ntlmssp_end killed this already. */
83                 ec->es->s.ntlmssp_state = NULL;
84         }
85 }
86
87 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
88
89 /******************************************************************************
90  Import a name.
91 ******************************************************************************/
92
93 static NTSTATUS get_srv_gss_creds(const char *service,
94                                 const char *name,
95                                 gss_cred_usage_t cred_type,
96                                 gss_cred_id_t *p_srv_cred)
97 {
98         OM_uint32 ret;
99         OM_uint32 min;
100         gss_name_t srv_name;
101         gss_buffer_desc input_name;
102         char *host_princ_s = NULL;
103         NTSTATUS status = NT_STATUS_OK;
104
105         gss_OID_desc nt_hostbased_service =
106         {10, CONST_DISCARD(char *,"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")};
107
108         asprintf(&host_princ_s, "%s@%s", service, name);
109         if (host_princ_s == NULL) {
110                 return NT_STATUS_NO_MEMORY;
111         }
112
113         input_name.value = host_princ_s;
114         input_name.length = strlen(host_princ_s) + 1;
115
116         ret = gss_import_name(&min,
117                                 &input_name,
118                                 &nt_hostbased_service,
119                                 &srv_name);
120
121         DEBUG(10,("get_srv_gss_creds: imported name %s\n",
122                 host_princ_s ));
123
124         if (ret != GSS_S_COMPLETE) {
125                 SAFE_FREE(host_princ_s);
126                 return map_nt_error_from_gss(ret, min);
127         }
128
129         /*
130          * We're accessing the krb5.keytab file here.
131          * ensure we have permissions to do so.
132          */
133         become_root();
134
135         ret = gss_acquire_cred(&min,
136                                 srv_name,
137                                 GSS_C_INDEFINITE,
138                                 GSS_C_NULL_OID_SET,
139                                 cred_type,
140                                 p_srv_cred,
141                                 NULL,
142                                 NULL);
143         unbecome_root();
144
145         if (ret != GSS_S_COMPLETE) {
146                 ADS_STATUS adss = ADS_ERROR_GSS(ret, min);
147                 DEBUG(10,("get_srv_gss_creds: gss_acquire_cred failed with %s\n",
148                         ads_errstr(adss)));
149                 status = map_nt_error_from_gss(ret, min);
150         }
151
152         SAFE_FREE(host_princ_s);
153         gss_release_name(&min, &srv_name);
154         return status;
155 }
156
157 /******************************************************************************
158  Create a gss state.
159  Try and get the cifs/server@realm principal first, then fall back to
160  host/server@realm.
161 ******************************************************************************/
162
163 static NTSTATUS make_auth_gss(struct smb_srv_trans_enc_ctx *ec)
164 {
165         NTSTATUS status;
166         gss_cred_id_t srv_cred;
167         fstring fqdn;
168
169         name_to_fqdn(fqdn, global_myname());
170         strlower_m(fqdn);
171
172         status = get_srv_gss_creds("cifs", fqdn, GSS_C_ACCEPT, &srv_cred);
173         if (!NT_STATUS_IS_OK(status)) {
174                 status = get_srv_gss_creds("host", fqdn, GSS_C_ACCEPT, &srv_cred);
175                 if (!NT_STATUS_IS_OK(status)) {
176                         return nt_status_squash(status);
177                 }
178         }
179
180         ec->es->s.gss_state = SMB_MALLOC_P(struct smb_tran_enc_state_gss);
181         if (!ec->es->s.gss_state) {
182                 OM_uint32 min;
183                 gss_release_cred(&min, &srv_cred);
184                 return NT_STATUS_NO_MEMORY;
185         }
186         ZERO_STRUCTP(ec->es->s.gss_state);
187         ec->es->s.gss_state->creds = srv_cred;
188
189         /* No context yet. */
190         ec->es->s.gss_state->gss_ctx = GSS_C_NO_CONTEXT;
191
192         return NT_STATUS_OK;
193 }
194 #endif
195
196 /******************************************************************************
197  Shutdown a server encryption context.
198 ******************************************************************************/
199
200 static void srv_free_encryption_context(struct smb_srv_trans_enc_ctx **pp_ec)
201 {
202         struct smb_srv_trans_enc_ctx *ec = *pp_ec;
203
204         if (!ec) {
205                 return;
206         }
207
208         if (ec->es) {
209                 switch (ec->es->smb_enc_type) {
210                         case SMB_TRANS_ENC_NTLM:
211                                 destroy_auth_ntlmssp(ec);
212                                 break;
213 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
214                         case SMB_TRANS_ENC_GSS:
215                                 break;
216 #endif
217                 }
218                 common_free_encryption_state(&ec->es);
219         }
220
221         SAFE_FREE(ec);
222         *pp_ec = NULL;
223 }
224
225 /******************************************************************************
226  Create a server encryption context.
227 ******************************************************************************/
228
229 static NTSTATUS make_srv_encryption_context(enum smb_trans_enc_type smb_enc_type, struct smb_srv_trans_enc_ctx **pp_ec)
230 {
231         struct smb_srv_trans_enc_ctx *ec;
232
233         *pp_ec = NULL;
234
235         ec = SMB_MALLOC_P(struct smb_srv_trans_enc_ctx);
236         if (!ec) {
237                 return NT_STATUS_NO_MEMORY;
238         }
239         ZERO_STRUCTP(partial_srv_trans_enc_ctx);
240         ec->es = SMB_MALLOC_P(struct smb_trans_enc_state);
241         if (!ec->es) {
242                 SAFE_FREE(ec);
243                 return NT_STATUS_NO_MEMORY;
244         }
245         ZERO_STRUCTP(ec->es);
246         ec->es->smb_enc_type = smb_enc_type;
247         switch (smb_enc_type) {
248                 case SMB_TRANS_ENC_NTLM:
249                         {
250                                 NTSTATUS status = make_auth_ntlmssp(ec);
251                                 if (!NT_STATUS_IS_OK(status)) {
252                                         srv_free_encryption_context(&ec);
253                                         return status;
254                                 }
255                         }
256                         break;
257
258 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
259                 case SMB_TRANS_ENC_GSS:
260                         /* Acquire our credentials by calling gss_acquire_cred here. */
261                         {
262                                 NTSTATUS status = make_auth_gss(ec);
263                                 if (!NT_STATUS_IS_OK(status)) {
264                                         srv_free_encryption_context(&ec);
265                                         return status;
266                                 }
267                         }
268                         break;
269 #endif
270                 default:
271                         srv_free_encryption_context(&ec);
272                         return NT_STATUS_INVALID_PARAMETER;
273         }
274         *pp_ec = ec;
275         return NT_STATUS_OK;
276 }
277
278 /******************************************************************************
279  Free an encryption-allocated buffer.
280 ******************************************************************************/
281
282 void srv_free_enc_buffer(char *buf)
283 {
284         /* We know this is an smb buffer, and we
285          * didn't malloc, only copy, for a keepalive,
286          * so ignore session keepalives. */
287
288         if(CVAL(buf,0) == SMBkeepalive) {
289                 return;
290         }
291
292         if (srv_trans_enc_ctx) {
293                 common_free_enc_buffer(srv_trans_enc_ctx->es, buf);
294         }
295 }
296
297 /******************************************************************************
298  Decrypt an incoming buffer.
299 ******************************************************************************/
300
301 NTSTATUS srv_decrypt_buffer(char *buf)
302 {
303         /* Ignore session keepalives. */
304         if(CVAL(buf,0) == SMBkeepalive) {
305                 return NT_STATUS_OK;
306         }
307
308         if (srv_trans_enc_ctx) {
309                 return common_decrypt_buffer(srv_trans_enc_ctx->es, buf);
310         }
311
312         return NT_STATUS_OK;
313 }
314
315 /******************************************************************************
316  Encrypt an outgoing buffer. Return the encrypted pointer in buf_out.
317 ******************************************************************************/
318
319 NTSTATUS srv_encrypt_buffer(char *buf, char **buf_out)
320 {
321         *buf_out = buf;
322
323         /* Ignore session keepalives. */
324         if(CVAL(buf,0) == SMBkeepalive) {
325                 return NT_STATUS_OK;
326         }
327
328         if (srv_trans_enc_ctx) {
329                 return common_encrypt_buffer(srv_trans_enc_ctx->es, buf, buf_out);
330         }
331         /* Not encrypting. */
332         return NT_STATUS_OK;
333 }
334
335 /******************************************************************************
336  Do the gss encryption negotiation. Parameters are in/out.
337  Until success we do everything on the partial enc ctx.
338 ******************************************************************************/
339
340 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
341 static NTSTATUS srv_enc_spnego_gss_negotiate(unsigned char **ppdata, size_t *p_data_size, DATA_BLOB secblob)
342 {
343         OM_uint32 ret;
344         OM_uint32 min;
345         OM_uint32 flags = 0;
346         gss_buffer_desc in_buf, out_buf;
347         struct smb_tran_enc_state_gss *gss_state;
348         DATA_BLOB auth_reply = data_blob_null;
349         DATA_BLOB response = data_blob_null;
350         NTSTATUS status;
351
352         if (!partial_srv_trans_enc_ctx) {
353                 status = make_srv_encryption_context(SMB_TRANS_ENC_GSS, &partial_srv_trans_enc_ctx);
354                 if (!NT_STATUS_IS_OK(status)) {
355                         return status;
356                 }
357         }
358
359         gss_state = partial_srv_trans_enc_ctx->es->s.gss_state;
360
361         in_buf.value = secblob.data;
362         in_buf.length = secblob.length;
363
364         out_buf.value = NULL;
365         out_buf.length = 0;
366
367         become_root();
368
369         ret = gss_accept_sec_context(&min,
370                                 &gss_state->gss_ctx,
371                                 gss_state->creds,
372                                 &in_buf,
373                                 GSS_C_NO_CHANNEL_BINDINGS,
374                                 NULL,
375                                 NULL,           /* Ignore oids. */
376                                 &out_buf,       /* To return. */
377                                 &flags,
378                                 NULL,           /* Ingore time. */
379                                 NULL);          /* Ignore delegated creds. */
380         unbecome_root();
381
382         status = gss_err_to_ntstatus(ret, min);
383         if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) {
384                 return status;
385         }
386
387         /* Ensure we've got sign+seal available. */
388         if (ret == GSS_S_COMPLETE) {
389                 if ((flags & (GSS_C_INTEG_FLAG|GSS_C_CONF_FLAG|GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG)) !=
390                                 (GSS_C_INTEG_FLAG|GSS_C_CONF_FLAG|GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG)) {
391                         DEBUG(0,("srv_enc_spnego_gss_negotiate: quality of service not good enough "
392                                 "for SMB sealing.\n"));
393                         gss_release_buffer(&min, &out_buf);
394                         return NT_STATUS_ACCESS_DENIED;
395                 }
396         }
397
398         auth_reply = data_blob(out_buf.value, out_buf.length);
399         gss_release_buffer(&min, &out_buf);
400
401         /* Wrap in SPNEGO. */
402         response = spnego_gen_auth_response(&auth_reply, status, OID_KERBEROS5);
403         data_blob_free(&auth_reply);
404
405         SAFE_FREE(*ppdata);
406         *ppdata = response.data;
407         *p_data_size = response.length;
408
409         return status;
410 }
411 #endif
412
413 /******************************************************************************
414  Do the NTLM SPNEGO (or raw) encryption negotiation. Parameters are in/out.
415  Until success we do everything on the partial enc ctx.
416 ******************************************************************************/
417
418 static NTSTATUS srv_enc_ntlm_negotiate(unsigned char **ppdata, size_t *p_data_size, DATA_BLOB secblob, BOOL spnego_wrap)
419 {
420         NTSTATUS status;
421         DATA_BLOB chal = data_blob_null;
422         DATA_BLOB response = data_blob_null;
423
424         status = make_srv_encryption_context(SMB_TRANS_ENC_NTLM, &partial_srv_trans_enc_ctx);
425         if (!NT_STATUS_IS_OK(status)) {
426                 return status;
427         }
428
429         status = auth_ntlmssp_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state, secblob, &chal);
430
431         /* status here should be NT_STATUS_MORE_PROCESSING_REQUIRED
432          * for success ... */
433
434         if (spnego_wrap) {
435                 response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP);
436                 data_blob_free(&chal);
437         } else {
438                 /* Return the raw blob. */
439                 response = chal;
440         }
441
442         SAFE_FREE(*ppdata);
443         *ppdata = response.data;
444         *p_data_size = response.length;
445         return status;
446 }
447
448 /******************************************************************************
449  Do the SPNEGO encryption negotiation. Parameters are in/out.
450  Based off code in smbd/sesssionsetup.c
451  Until success we do everything on the partial enc ctx.
452 ******************************************************************************/
453
454 static NTSTATUS srv_enc_spnego_negotiate(connection_struct *conn,
455                                         unsigned char **ppdata,
456                                         size_t *p_data_size,
457                                         unsigned char **pparam,
458                                         size_t *p_param_size)
459 {
460         NTSTATUS status;
461         DATA_BLOB blob = data_blob_null;
462         DATA_BLOB secblob = data_blob_null;
463         BOOL got_kerberos_mechanism = False;
464
465         blob = data_blob_const(*ppdata, *p_data_size);
466
467         status = parse_spnego_mechanisms(blob, &secblob, &got_kerberos_mechanism);
468         if (!NT_STATUS_IS_OK(status)) {
469                 return nt_status_squash(status);
470         }
471
472         /* We should have no partial context at this point. */
473
474         srv_free_encryption_context(&partial_srv_trans_enc_ctx);
475
476 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
477         if (got_kerberos_mechanism && lp_use_kerberos_keytab() ) {
478                 status = srv_enc_spnego_gss_negotiate(ppdata, p_data_size, secblob);
479         } else 
480 #endif
481         {
482                 status = srv_enc_ntlm_negotiate(ppdata, p_data_size, secblob, True);
483         }
484
485         data_blob_free(&secblob);
486
487         if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) {
488                 srv_free_encryption_context(&partial_srv_trans_enc_ctx);
489                 return nt_status_squash(status);
490         }
491
492         if (NT_STATUS_IS_OK(status)) {
493                 /* Return the context we're using for this encryption state. */
494                 if (!(*pparam = SMB_MALLOC_ARRAY(unsigned char, 2))) {
495                         return NT_STATUS_NO_MEMORY;
496                 }
497                 SSVAL(*pparam,0,partial_srv_trans_enc_ctx->es->enc_ctx_num);
498                 *p_param_size = 2;
499         }
500
501         return status;
502 }
503
504 /******************************************************************************
505  Complete a SPNEGO encryption negotiation. Parameters are in/out.
506  We only get this for a NTLM auth second stage.
507 ******************************************************************************/
508
509 static NTSTATUS srv_enc_spnego_ntlm_auth(connection_struct *conn,
510                                         unsigned char **ppdata,
511                                         size_t *p_data_size,
512                                         unsigned char **pparam,
513                                         size_t *p_param_size)
514 {
515         NTSTATUS status;
516         DATA_BLOB blob = data_blob_null;
517         DATA_BLOB auth = data_blob_null;
518         DATA_BLOB auth_reply = data_blob_null;
519         DATA_BLOB response = data_blob_null;
520         struct smb_srv_trans_enc_ctx *ec = partial_srv_trans_enc_ctx;
521
522         /* We must have a partial context here. */
523
524         if (!ec || !ec->es || ec->auth_ntlmssp_state == NULL || ec->es->smb_enc_type != SMB_TRANS_ENC_NTLM) {
525                 srv_free_encryption_context(&partial_srv_trans_enc_ctx);
526                 return NT_STATUS_INVALID_PARAMETER;
527         }
528
529         blob = data_blob_const(*ppdata, *p_data_size);
530         if (!spnego_parse_auth(blob, &auth)) {
531                 srv_free_encryption_context(&partial_srv_trans_enc_ctx);
532                 return NT_STATUS_INVALID_PARAMETER;
533         }
534
535         status = auth_ntlmssp_update(ec->auth_ntlmssp_state, auth, &auth_reply);
536         data_blob_free(&auth);
537
538         response = spnego_gen_auth_response(&auth_reply, status, OID_NTLMSSP);
539         data_blob_free(&auth_reply);
540
541         if (NT_STATUS_IS_OK(status)) {
542                 /* Return the context we're using for this encryption state. */
543                 if (!(*pparam = SMB_MALLOC_ARRAY(unsigned char, 2))) {
544                         return NT_STATUS_NO_MEMORY;
545                 }
546                 SSVAL(*pparam,0,ec->es->enc_ctx_num);
547                 *p_param_size = 2;
548         }
549
550         SAFE_FREE(*ppdata);
551         *ppdata = response.data;
552         *p_data_size = response.length;
553         return status;
554 }
555
556 /******************************************************************************
557  Raw NTLM encryption negotiation. Parameters are in/out.
558  This function does both steps.
559 ******************************************************************************/
560
561 static NTSTATUS srv_enc_raw_ntlm_auth(connection_struct *conn,
562                                         unsigned char **ppdata,
563                                         size_t *p_data_size,
564                                         unsigned char **pparam,
565                                         size_t *p_param_size)
566 {
567         NTSTATUS status;
568         DATA_BLOB blob = data_blob_const(*ppdata, *p_data_size);
569         DATA_BLOB response = data_blob_null;
570         struct smb_srv_trans_enc_ctx *ec;
571
572         if (!partial_srv_trans_enc_ctx) {
573                 /* This is the initial step. */
574                 status = srv_enc_ntlm_negotiate(ppdata, p_data_size, blob, False);
575                 if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) {
576                         srv_free_encryption_context(&partial_srv_trans_enc_ctx);
577                         return nt_status_squash(status);
578                 }
579                 return status;
580         }
581
582         ec = partial_srv_trans_enc_ctx;
583         if (!ec || !ec->es || ec->auth_ntlmssp_state == NULL || ec->es->smb_enc_type != SMB_TRANS_ENC_NTLM) {
584                 srv_free_encryption_context(&partial_srv_trans_enc_ctx);
585                 return NT_STATUS_INVALID_PARAMETER;
586         }
587
588         /* Second step. */
589         status = auth_ntlmssp_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state, blob, &response);
590
591         if (NT_STATUS_IS_OK(status)) {
592                 /* Return the context we're using for this encryption state. */
593                 if (!(*pparam = SMB_MALLOC_ARRAY(unsigned char, 2))) {
594                         return NT_STATUS_NO_MEMORY;
595                 }
596                 SSVAL(*pparam,0,ec->es->enc_ctx_num);
597                 *p_param_size = 2;
598         }
599
600         /* Return the raw blob. */
601         SAFE_FREE(*ppdata);
602         *ppdata = response.data;
603         *p_data_size = response.length;
604         return status;
605 }
606
607 /******************************************************************************
608  Do the SPNEGO encryption negotiation. Parameters are in/out.
609 ******************************************************************************/
610
611 NTSTATUS srv_request_encryption_setup(connection_struct *conn,
612                                         unsigned char **ppdata,
613                                         size_t *p_data_size,
614                                         unsigned char **pparam,
615                                         size_t *p_param_size)
616 {
617         unsigned char *pdata = *ppdata;
618
619         SAFE_FREE(*pparam);
620         *p_param_size = 0;
621
622         if (*p_data_size < 1) {
623                 return NT_STATUS_INVALID_PARAMETER;
624         }
625
626         if (pdata[0] == ASN1_APPLICATION(0)) {
627                 /* its a negTokenTarg packet */
628                 return srv_enc_spnego_negotiate(conn, ppdata, p_data_size, pparam, p_param_size);
629         }
630
631         if (pdata[0] == ASN1_CONTEXT(1)) {
632                 /* It's an auth packet */
633                 return srv_enc_spnego_ntlm_auth(conn, ppdata, p_data_size, pparam, p_param_size);
634         }
635
636         /* Maybe it's a raw unwrapped auth ? */
637         if (*p_data_size < 7) {
638                 return NT_STATUS_INVALID_PARAMETER;
639         }
640
641         if (strncmp((char *)pdata, "NTLMSSP", 7) == 0) {
642                 return srv_enc_raw_ntlm_auth(conn, ppdata, p_data_size, pparam, p_param_size);
643         }
644
645         DEBUG(1,("srv_request_encryption_setup: Unknown packet\n"));
646
647         return NT_STATUS_LOGON_FAILURE;
648 }
649
650 /******************************************************************************
651  Negotiation was successful - turn on server-side encryption.
652 ******************************************************************************/
653
654 static NTSTATUS check_enc_good(struct smb_srv_trans_enc_ctx *ec)
655 {
656         if (!ec || !ec->es) {
657                 return NT_STATUS_LOGON_FAILURE;
658         }
659
660         if (ec->es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
661                 if ((ec->es->s.ntlmssp_state->neg_flags & (NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL)) !=
662                                 (NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL)) {
663                         return NT_STATUS_INVALID_PARAMETER;
664                 }
665         }
666         /* Todo - check gssapi case. */
667
668         return NT_STATUS_OK;
669 }
670
671 /******************************************************************************
672  Negotiation was successful - turn on server-side encryption.
673 ******************************************************************************/
674
675 NTSTATUS srv_encryption_start(connection_struct *conn)
676 {
677         NTSTATUS status;
678
679         /* Check that we are really doing sign+seal. */
680         status = check_enc_good(partial_srv_trans_enc_ctx);
681         if (!NT_STATUS_IS_OK(status)) {
682                 return status;
683         }
684         /* Throw away the context we're using currently (if any). */
685         srv_free_encryption_context(&srv_trans_enc_ctx);
686
687         /* Steal the partial pointer. Deliberate shallow copy. */
688         srv_trans_enc_ctx = partial_srv_trans_enc_ctx;
689         srv_trans_enc_ctx->es->enc_on = True;
690
691         partial_srv_trans_enc_ctx = NULL;
692         return NT_STATUS_OK;
693 }
694
695 /******************************************************************************
696  Shutdown all server contexts.
697 ******************************************************************************/
698
699 void server_encryption_shutdown(void)
700 {
701         srv_free_encryption_context(&partial_srv_trans_enc_ctx);
702         srv_free_encryption_context(&srv_trans_enc_ctx);
703 }