ntlmssp: Make the ntlmssp.h from source3/ a common header
[rusty/samba.git] / source3 / auth / auth_ntlmssp.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    handle NLTMSSP, server side
5
6    Copyright (C) Andrew Tridgell      2001
7    Copyright (C) Andrew Bartlett 2001-2003
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 "../libcli/auth/ntlmssp.h"
25
26 struct auth_ntlmssp_state {
27         TALLOC_CTX *mem_ctx;
28         struct auth_context *auth_context;
29         struct auth_serversupplied_info *server_info;
30         struct ntlmssp_state *ntlmssp_state;
31 };
32
33 NTSTATUS auth_ntlmssp_sign_packet(struct auth_ntlmssp_state *auth_ntlmssp_state,
34                                   const uint8_t *data, size_t length,
35                                   const uint8_t *whole_pdu, size_t pdu_length,
36                                   DATA_BLOB *sig)
37 {
38         return ntlmssp_sign_packet(auth_ntlmssp_state->ntlmssp_state, data, length, whole_pdu, pdu_length, sig);
39 }
40
41 NTSTATUS auth_ntlmssp_check_packet(struct auth_ntlmssp_state *auth_ntlmssp_state,
42                                    const uint8_t *data, size_t length,
43                                    const uint8_t *whole_pdu, size_t pdu_length,
44                                    const DATA_BLOB *sig)
45 {
46         return ntlmssp_check_packet(auth_ntlmssp_state->ntlmssp_state, data, length, whole_pdu, pdu_length, sig);
47 }
48
49 NTSTATUS auth_ntlmssp_seal_packet(struct auth_ntlmssp_state *auth_ntlmssp_state,
50                                   uint8_t *data, size_t length,
51                                   const uint8_t *whole_pdu, size_t pdu_length,
52                                   DATA_BLOB *sig)
53 {
54         return ntlmssp_seal_packet(auth_ntlmssp_state->ntlmssp_state, data, length, whole_pdu, pdu_length, sig);
55 }
56
57 NTSTATUS auth_ntlmssp_unseal_packet(struct auth_ntlmssp_state *auth_ntlmssp_state,
58                                     uint8_t *data, size_t length,
59                                     const uint8_t *whole_pdu, size_t pdu_length,
60                                     const DATA_BLOB *sig)
61 {
62         return ntlmssp_unseal_packet(auth_ntlmssp_state->ntlmssp_state, data, length, whole_pdu, pdu_length, sig);
63 }
64
65 bool auth_ntlmssp_negotiated_sign(struct auth_ntlmssp_state *auth_ntlmssp_state)
66 {
67         return auth_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN;
68 }
69
70 bool auth_ntlmssp_negotiated_seal(struct auth_ntlmssp_state *auth_ntlmssp_state)
71 {
72         return auth_ntlmssp_state->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL;
73 }
74
75 struct auth_serversupplied_info *auth_ntlmssp_server_info(TALLOC_CTX *mem_ctx,
76                                                           struct auth_ntlmssp_state *auth_ntlmssp_state)
77 {
78         struct auth_serversupplied_info *server_info = auth_ntlmssp_state->server_info;
79         data_blob_free(&server_info->user_session_key);
80         server_info->user_session_key =
81                 data_blob_talloc(
82                         server_info,
83                         auth_ntlmssp_state->ntlmssp_state->session_key.data,
84                         auth_ntlmssp_state->ntlmssp_state->session_key.length);
85         if (auth_ntlmssp_state->ntlmssp_state->session_key.length && !server_info->user_session_key.data) {
86                 return NULL;
87         }
88         auth_ntlmssp_state->server_info = NULL;
89         return talloc_steal(mem_ctx, server_info);
90 }
91
92 struct ntlmssp_state *auth_ntlmssp_get_ntlmssp_state(struct auth_ntlmssp_state *auth_ntlmssp_state)
93 {
94         return auth_ntlmssp_state->ntlmssp_state;
95 }
96
97 /* Needed for 'map to guest' and 'smb username' processing */
98 const char *auth_ntlmssp_get_username(struct auth_ntlmssp_state *auth_ntlmssp_state)
99 {
100         return auth_ntlmssp_state->ntlmssp_state->user;
101 }
102
103 const char *auth_ntlmssp_get_domain(struct auth_ntlmssp_state *auth_ntlmssp_state)
104 {
105         return auth_ntlmssp_state->ntlmssp_state->domain;
106 }
107
108 const char *auth_ntlmssp_get_client(struct auth_ntlmssp_state *auth_ntlmssp_state)
109 {
110         return auth_ntlmssp_state->ntlmssp_state->client.netbios_name;
111 }
112
113 /**
114  * Return the challenge as determined by the authentication subsystem 
115  * @return an 8 byte random challenge
116  */
117
118 static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state,
119                                            uint8_t chal[8])
120 {
121         struct auth_ntlmssp_state *auth_ntlmssp_state =
122                 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
123         auth_ntlmssp_state->auth_context->get_ntlm_challenge(
124                 auth_ntlmssp_state->auth_context, chal);
125         return NT_STATUS_OK;
126 }
127
128 /**
129  * Some authentication methods 'fix' the challenge, so we may not be able to set it
130  *
131  * @return If the effective challenge used by the auth subsystem may be modified
132  */
133 static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
134 {
135         struct auth_ntlmssp_state *auth_ntlmssp_state =
136                 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
137         struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
138
139         return auth_context->challenge_may_be_modified;
140 }
141
142 /**
143  * NTLM2 authentication modifies the effective challenge, 
144  * @param challenge The new challenge value
145  */
146 static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
147 {
148         struct auth_ntlmssp_state *auth_ntlmssp_state =
149                 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
150         struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
151
152         SMB_ASSERT(challenge->length == 8);
153
154         auth_context->challenge = data_blob_talloc(auth_context,
155                                                    challenge->data, challenge->length);
156
157         auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)";
158
159         DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by));
160         DEBUG(5, ("challenge is: \n"));
161         dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
162         return NT_STATUS_OK;
163 }
164
165 /**
166  * Check the password on an NTLMSSP login.  
167  *
168  * Return the session keys used on the connection.
169  */
170
171 static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) 
172 {
173         struct auth_ntlmssp_state *auth_ntlmssp_state =
174                 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
175         struct auth_usersupplied_info *user_info = NULL;
176         NTSTATUS nt_status;
177         bool username_was_mapped;
178
179         /* the client has given us its machine name (which we otherwise would not get on port 445).
180            we need to possibly reload smb.conf if smb.conf includes depend on the machine name */
181
182         set_remote_machine_name(auth_ntlmssp_state->ntlmssp_state->client.netbios_name, True);
183
184         /* setup the string used by %U */
185         /* sub_set_smb_name checks for weird internally */
186         sub_set_smb_name(auth_ntlmssp_state->ntlmssp_state->user);
187
188         reload_services(True);
189
190         nt_status = make_user_info_map(&user_info, 
191                                        auth_ntlmssp_state->ntlmssp_state->user, 
192                                        auth_ntlmssp_state->ntlmssp_state->domain, 
193                                        auth_ntlmssp_state->ntlmssp_state->client.netbios_name,
194                                        auth_ntlmssp_state->ntlmssp_state->lm_resp.data ? &auth_ntlmssp_state->ntlmssp_state->lm_resp : NULL, 
195                                        auth_ntlmssp_state->ntlmssp_state->nt_resp.data ? &auth_ntlmssp_state->ntlmssp_state->nt_resp : NULL, 
196                                        NULL, NULL, NULL,
197                                        True);
198
199         user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
200
201         if (!NT_STATUS_IS_OK(nt_status)) {
202                 return nt_status;
203         }
204
205         nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context, 
206                                                                           user_info, &auth_ntlmssp_state->server_info); 
207
208         username_was_mapped = user_info->was_mapped;
209
210         free_user_info(&user_info);
211
212         if (!NT_STATUS_IS_OK(nt_status)) {
213                 return nt_status;
214         }
215
216         auth_ntlmssp_state->server_info->nss_token |= username_was_mapped;
217
218         nt_status = create_local_token(auth_ntlmssp_state->server_info);
219
220         if (!NT_STATUS_IS_OK(nt_status)) {
221                 DEBUG(10, ("create_local_token failed: %s\n",
222                         nt_errstr(nt_status)));
223                 return nt_status;
224         }
225
226         if (auth_ntlmssp_state->server_info->user_session_key.length) {
227                 DEBUG(10, ("Got NT session key of length %u\n",
228                         (unsigned int)auth_ntlmssp_state->server_info->user_session_key.length));
229                 *user_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, 
230                                                    auth_ntlmssp_state->server_info->user_session_key.data,
231                                                    auth_ntlmssp_state->server_info->user_session_key.length);
232         }
233         if (auth_ntlmssp_state->server_info->lm_session_key.length) {
234                 DEBUG(10, ("Got LM session key of length %u\n",
235                         (unsigned int)auth_ntlmssp_state->server_info->lm_session_key.length));
236                 *lm_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, 
237                                                    auth_ntlmssp_state->server_info->lm_session_key.data,
238                                                    auth_ntlmssp_state->server_info->lm_session_key.length);
239         }
240         return nt_status;
241 }
242
243 NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state **auth_ntlmssp_state)
244 {
245         NTSTATUS nt_status;
246         TALLOC_CTX *mem_ctx;
247         bool is_standalone;
248         const char *netbios_name;
249         const char *netbios_domain;
250         const char *dns_name;
251         char *dns_domain;
252
253         if ((enum server_types)lp_server_role() == ROLE_STANDALONE) {
254                 is_standalone = true;
255         } else {
256                 is_standalone = false;
257         }
258
259         netbios_name = global_myname();
260         netbios_domain = lp_workgroup();
261         /* This should be a 'netbios domain -> DNS domain' mapping */
262         dns_domain = get_mydnsdomname(talloc_tos());
263         if (dns_domain) {
264                 strlower_m(dns_domain);
265         }
266         dns_name = get_mydnsfullname();
267
268         mem_ctx = talloc_init("AUTH NTLMSSP context");
269         
270         *auth_ntlmssp_state = TALLOC_ZERO_P(mem_ctx, struct auth_ntlmssp_state);
271         if (!*auth_ntlmssp_state) {
272                 DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
273                 talloc_destroy(mem_ctx);
274                 return NT_STATUS_NO_MEMORY;
275         }
276
277         ZERO_STRUCTP(*auth_ntlmssp_state);
278
279         (*auth_ntlmssp_state)->mem_ctx = mem_ctx;
280
281         nt_status = ntlmssp_server_start(NULL,
282                                          is_standalone,
283                                          netbios_name,
284                                          netbios_domain,
285                                          dns_name,
286                                          dns_domain,
287                                          &(*auth_ntlmssp_state)->ntlmssp_state);
288         if (!NT_STATUS_IS_OK(nt_status)) {
289                 return nt_status;
290         }
291
292         if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&(*auth_ntlmssp_state)->auth_context))) {
293                 return nt_status;
294         }
295
296         (*auth_ntlmssp_state)->ntlmssp_state->callback_private = (*auth_ntlmssp_state);
297         (*auth_ntlmssp_state)->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
298         (*auth_ntlmssp_state)->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
299         (*auth_ntlmssp_state)->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
300         (*auth_ntlmssp_state)->ntlmssp_state->check_password = auth_ntlmssp_check_password;
301
302         return NT_STATUS_OK;
303 }
304
305 void auth_ntlmssp_end(struct auth_ntlmssp_state **auth_ntlmssp_state)
306 {
307         TALLOC_CTX *mem_ctx;
308
309         if (*auth_ntlmssp_state == NULL) {
310                 return;
311         }
312
313         mem_ctx = (*auth_ntlmssp_state)->mem_ctx;
314         if ((*auth_ntlmssp_state)->ntlmssp_state) {
315                 ntlmssp_end(&(*auth_ntlmssp_state)->ntlmssp_state);
316         }
317         if ((*auth_ntlmssp_state)->auth_context) {
318                 ((*auth_ntlmssp_state)->auth_context->free)(&(*auth_ntlmssp_state)->auth_context);
319         }
320         if ((*auth_ntlmssp_state)->server_info) {
321                 TALLOC_FREE((*auth_ntlmssp_state)->server_info);
322         }
323         talloc_destroy(mem_ctx);
324         *auth_ntlmssp_state = NULL;
325 }
326
327 NTSTATUS auth_ntlmssp_update(struct auth_ntlmssp_state *auth_ntlmssp_state,
328                              const DATA_BLOB request, DATA_BLOB *reply) 
329 {
330         return ntlmssp_update(auth_ntlmssp_state->ntlmssp_state, request, reply);
331 }