s3-auth: Remove unimplemented functions
[mat/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 #include "ntlmssp_wrap.h"
26
27 NTSTATUS auth_ntlmssp_steal_server_info(TALLOC_CTX *mem_ctx,
28                                 struct auth_ntlmssp_state *auth_ntlmssp_state,
29                                 struct auth_serversupplied_info **server_info)
30 {
31         /* Free the current server_info user_session_key and reset it from the
32          * current ntlmssp_state session_key */
33         data_blob_free(&auth_ntlmssp_state->server_info->user_session_key);
34         auth_ntlmssp_state->server_info->user_session_key =
35                 data_blob_talloc(
36                         auth_ntlmssp_state->server_info,
37                         auth_ntlmssp_state->ntlmssp_state->session_key.data,
38                         auth_ntlmssp_state->ntlmssp_state->session_key.length);
39         if (auth_ntlmssp_state->ntlmssp_state->session_key.length &&
40             !auth_ntlmssp_state->server_info->user_session_key.data) {
41                 *server_info = NULL;
42                 return NT_STATUS_NO_MEMORY;
43         }
44         /* Steal server_info away from auth_ntlmssp_state */
45         *server_info = talloc_move(mem_ctx, &auth_ntlmssp_state->server_info);
46         return NT_STATUS_OK;
47 }
48
49 /**
50  * Return the challenge as determined by the authentication subsystem 
51  * @return an 8 byte random challenge
52  */
53
54 static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state,
55                                            uint8_t chal[8])
56 {
57         struct auth_ntlmssp_state *auth_ntlmssp_state =
58                 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
59         auth_ntlmssp_state->auth_context->get_ntlm_challenge(
60                 auth_ntlmssp_state->auth_context, chal);
61         return NT_STATUS_OK;
62 }
63
64 /**
65  * Some authentication methods 'fix' the challenge, so we may not be able to set it
66  *
67  * @return If the effective challenge used by the auth subsystem may be modified
68  */
69 static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
70 {
71         struct auth_ntlmssp_state *auth_ntlmssp_state =
72                 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
73         struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
74
75         return auth_context->challenge_may_be_modified;
76 }
77
78 /**
79  * NTLM2 authentication modifies the effective challenge, 
80  * @param challenge The new challenge value
81  */
82 static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
83 {
84         struct auth_ntlmssp_state *auth_ntlmssp_state =
85                 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
86         struct auth_context *auth_context = auth_ntlmssp_state->auth_context;
87
88         SMB_ASSERT(challenge->length == 8);
89
90         auth_context->challenge = data_blob_talloc(auth_context,
91                                                    challenge->data, challenge->length);
92
93         auth_context->challenge_set_by = "NTLMSSP callback (NTLM2)";
94
95         DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by));
96         DEBUG(5, ("challenge is: \n"));
97         dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
98         return NT_STATUS_OK;
99 }
100
101 /**
102  * Check the password on an NTLMSSP login.  
103  *
104  * Return the session keys used on the connection.
105  */
106
107 static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) 
108 {
109         struct auth_ntlmssp_state *auth_ntlmssp_state =
110                 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private;
111         struct auth_usersupplied_info *user_info = NULL;
112         NTSTATUS nt_status;
113         bool username_was_mapped;
114
115         /* the client has given us its machine name (which we otherwise would not get on port 445).
116            we need to possibly reload smb.conf if smb.conf includes depend on the machine name */
117
118         set_remote_machine_name(auth_ntlmssp_state->ntlmssp_state->client.netbios_name, True);
119
120         /* setup the string used by %U */
121         /* sub_set_smb_name checks for weird internally */
122         sub_set_smb_name(auth_ntlmssp_state->ntlmssp_state->user);
123
124         reload_services(True);
125
126         nt_status = make_user_info_map(&user_info, 
127                                        auth_ntlmssp_state->ntlmssp_state->user, 
128                                        auth_ntlmssp_state->ntlmssp_state->domain, 
129                                        auth_ntlmssp_state->ntlmssp_state->client.netbios_name,
130                                        auth_ntlmssp_state->ntlmssp_state->lm_resp.data ? &auth_ntlmssp_state->ntlmssp_state->lm_resp : NULL, 
131                                        auth_ntlmssp_state->ntlmssp_state->nt_resp.data ? &auth_ntlmssp_state->ntlmssp_state->nt_resp : NULL, 
132                                        NULL, NULL, NULL,
133                                        True);
134
135         user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
136
137         if (!NT_STATUS_IS_OK(nt_status)) {
138                 return nt_status;
139         }
140
141         nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context, 
142                                                                           user_info, &auth_ntlmssp_state->server_info); 
143
144         username_was_mapped = user_info->was_mapped;
145
146         free_user_info(&user_info);
147
148         if (!NT_STATUS_IS_OK(nt_status)) {
149                 return nt_status;
150         }
151
152         auth_ntlmssp_state->server_info->nss_token |= username_was_mapped;
153
154         nt_status = create_local_token(auth_ntlmssp_state->server_info);
155
156         if (!NT_STATUS_IS_OK(nt_status)) {
157                 DEBUG(10, ("create_local_token failed: %s\n",
158                         nt_errstr(nt_status)));
159                 return nt_status;
160         }
161
162         if (auth_ntlmssp_state->server_info->user_session_key.length) {
163                 DEBUG(10, ("Got NT session key of length %u\n",
164                         (unsigned int)auth_ntlmssp_state->server_info->user_session_key.length));
165                 *user_session_key = data_blob_talloc(auth_ntlmssp_state,
166                                                    auth_ntlmssp_state->server_info->user_session_key.data,
167                                                    auth_ntlmssp_state->server_info->user_session_key.length);
168         }
169         if (auth_ntlmssp_state->server_info->lm_session_key.length) {
170                 DEBUG(10, ("Got LM session key of length %u\n",
171                         (unsigned int)auth_ntlmssp_state->server_info->lm_session_key.length));
172                 *lm_session_key = data_blob_talloc(auth_ntlmssp_state,
173                                                    auth_ntlmssp_state->server_info->lm_session_key.data,
174                                                    auth_ntlmssp_state->server_info->lm_session_key.length);
175         }
176         return nt_status;
177 }
178
179 static int auth_ntlmssp_state_destructor(void *ptr);
180
181 NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state **auth_ntlmssp_state)
182 {
183         NTSTATUS nt_status;
184         bool is_standalone;
185         const char *netbios_name;
186         const char *netbios_domain;
187         const char *dns_name;
188         char *dns_domain;
189         struct auth_ntlmssp_state *ans;
190         struct auth_context *auth_context;
191
192         if ((enum server_types)lp_server_role() == ROLE_STANDALONE) {
193                 is_standalone = true;
194         } else {
195                 is_standalone = false;
196         }
197
198         netbios_name = global_myname();
199         netbios_domain = lp_workgroup();
200         /* This should be a 'netbios domain -> DNS domain' mapping */
201         dns_domain = get_mydnsdomname(talloc_tos());
202         if (dns_domain) {
203                 strlower_m(dns_domain);
204         }
205         dns_name = get_mydnsfullname();
206
207         ans = talloc_zero(NULL, struct auth_ntlmssp_state);
208         if (!ans) {
209                 DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
210                 return NT_STATUS_NO_MEMORY;
211         }
212
213         nt_status = ntlmssp_server_start(ans,
214                                          is_standalone,
215                                          netbios_name,
216                                          netbios_domain,
217                                          dns_name,
218                                          dns_domain,
219                                          &ans->ntlmssp_state);
220         if (!NT_STATUS_IS_OK(nt_status)) {
221                 return nt_status;
222         }
223
224         nt_status = make_auth_context_subsystem(&auth_context);
225         if (!NT_STATUS_IS_OK(nt_status)) {
226                 return nt_status;
227         }
228         ans->auth_context = talloc_steal(ans, auth_context);
229
230         ans->ntlmssp_state->callback_private = ans;
231         ans->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
232         ans->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
233         ans->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
234         ans->ntlmssp_state->check_password = auth_ntlmssp_check_password;
235
236         talloc_set_destructor((TALLOC_CTX *)ans, auth_ntlmssp_state_destructor);
237
238         *auth_ntlmssp_state = ans;
239         return NT_STATUS_OK;
240 }
241
242 static int auth_ntlmssp_state_destructor(void *ptr)
243 {
244         struct auth_ntlmssp_state *ans;
245
246         ans = talloc_get_type(ptr, struct auth_ntlmssp_state);
247
248         TALLOC_FREE(ans->server_info);
249         TALLOC_FREE(ans->ntlmssp_state);
250         return 0;
251 }