7e10a554d8c93ada4aded6c54d4af7751ffeac87
[sfrench/samba-autobuild/.git] / source4 / auth / ntlm / auth.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Password and authentication handling
4    Copyright (C) Andrew Bartlett         2001-2002
5    Copyright (C) Stefan Metzmacher       2005
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include <tevent.h>
23 #include "../lib/util/tevent_ntstatus.h"
24 #include "../lib/util/dlinklist.h"
25 #include "auth/auth.h"
26 #include "auth/ntlm/auth_proto.h"
27 #include "param/param.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "libcli/wbclient/wbclient.h"
30 #include "lib/util/samba_modules.h"
31 #include "auth/credentials/credentials.h"
32 #include "system/kerberos.h"
33 #include "auth/kerberos/kerberos.h"
34 #include "auth/kerberos/kerberos_util.h"
35 #include "libds/common/roles.h"
36
37 static NTSTATUS auth_generate_session_info_wrapper(struct auth4_context *auth_context,
38                                                    TALLOC_CTX *mem_ctx,
39                                                   void *server_returned_info,
40                                                    const char *original_user_name,
41                                                    uint32_t session_info_flags,
42                                                    struct auth_session_info **session_info);
43
44 /***************************************************************************
45  Set a fixed challenge
46 ***************************************************************************/
47 _PUBLIC_ NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by) 
48 {
49         auth_ctx->challenge.set_by = talloc_strdup(auth_ctx, set_by);
50         NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.set_by);
51
52         auth_ctx->challenge.data = data_blob_talloc(auth_ctx, chal, 8);
53         NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.data.data);
54
55         return NT_STATUS_OK;
56 }
57
58 /****************************************************************************
59  Try to get a challenge out of the various authentication modules.
60  Returns a const char of length 8 bytes.
61 ****************************************************************************/
62 _PUBLIC_ NTSTATUS auth_get_challenge(struct auth4_context *auth_ctx, uint8_t chal[8])
63 {
64
65         if (auth_ctx->challenge.data.length == 8) {
66                 DEBUG(5, ("auth_get_challenge: returning previous challenge by module %s (normal)\n", 
67                           auth_ctx->challenge.set_by));
68                 memcpy(chal, auth_ctx->challenge.data.data, 8);
69                 return NT_STATUS_OK;
70         }
71
72         if (!auth_ctx->challenge.set_by) {
73                 generate_random_buffer(chal, 8);
74
75                 auth_ctx->challenge.data                = data_blob_talloc(auth_ctx, chal, 8);
76                 NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.data.data);
77                 auth_ctx->challenge.set_by              = "random";
78         }
79
80         DEBUG(10,("auth_get_challenge: challenge set by %s\n",
81                  auth_ctx->challenge.set_by));
82
83         return NT_STATUS_OK;
84 }
85
86 /****************************************************************************
87 Used in the gensec_gssapi and gensec_krb5 server-side code, where the
88 PAC isn't available, and for tokenGroups in the DSDB stack.
89
90  Supply either a principal or a DN
91 ****************************************************************************/
92 static NTSTATUS auth_generate_session_info_principal(struct auth4_context *auth_ctx,
93                                                   TALLOC_CTX *mem_ctx,
94                                                   const char *principal,
95                                                   struct ldb_dn *user_dn,
96                                                   uint32_t session_info_flags,
97                                                   struct auth_session_info **session_info)
98 {
99         NTSTATUS nt_status;
100         struct auth_method_context *method;
101         struct auth_user_info_dc *user_info_dc;
102
103         for (method = auth_ctx->methods; method; method = method->next) {
104                 if (!method->ops->get_user_info_dc_principal) {
105                         continue;
106                 }
107
108                 nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, &user_info_dc);
109                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {
110                         continue;
111                 }
112                 if (!NT_STATUS_IS_OK(nt_status)) {
113                         return nt_status;
114                 }
115
116                 nt_status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx, 
117                                                                user_info_dc,
118                                                                user_info_dc->info->account_name,
119                                                                session_info_flags, session_info);
120                 talloc_free(user_info_dc);
121
122                 return nt_status;
123         }
124
125         return NT_STATUS_NOT_IMPLEMENTED;
126 }
127
128 /**
129  * Check a user's Plaintext, LM or NTLM password.
130  * (sync version)
131  *
132  * Check a user's password, as given in the user_info struct and return various
133  * interesting details in the user_info_dc struct.
134  *
135  * The return value takes precedence over the contents of the user_info_dc
136  * struct.  When the return is other than NT_STATUS_OK the contents 
137  * of that structure is undefined.
138  *
139  * @param auth_ctx Supplies the challenges and some other data. 
140  *                  Must be created with auth_context_create(), and the challenges should be 
141  *                  filled in, either at creation or by calling the challenge geneation 
142  *                  function auth_get_challenge().  
143  *
144  * @param user_info Contains the user supplied components, including the passwords.
145  *
146  * @param mem_ctx The parent memory context for the user_info_dc structure
147  *
148  * @param user_info_dc If successful, contains information about the authentication,
149  *                    including a SAM_ACCOUNT struct describing the user.
150  *
151  * @return An NTSTATUS with NT_STATUS_OK or an appropriate error.
152  *
153  **/
154
155 _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
156                              TALLOC_CTX *mem_ctx,
157                              const struct auth_usersupplied_info *user_info, 
158                              struct auth_user_info_dc **user_info_dc,
159                              uint8_t *pauthoritative)
160 {
161         struct tevent_req *subreq;
162         struct tevent_context *ev;
163         bool ok;
164         NTSTATUS status;
165
166         /*TODO: create a new event context here! */
167         ev = auth_ctx->event_ctx;
168
169         subreq = auth_check_password_send(mem_ctx,
170                                           ev,
171                                           auth_ctx,
172                                           user_info);
173         if (subreq == NULL) {
174                 return NT_STATUS_NO_MEMORY;
175         }
176
177         ok = tevent_req_poll(subreq, ev);
178         if (!ok) {
179                 return NT_STATUS_INTERNAL_ERROR;
180         }
181
182         status = auth_check_password_recv(subreq, mem_ctx,
183                                           user_info_dc, pauthoritative);
184         TALLOC_FREE(subreq);
185
186         return status;
187 }
188
189 struct auth_check_password_state {
190         struct tevent_context *ev;
191         struct auth4_context *auth_ctx;
192         const struct auth_usersupplied_info *user_info;
193         struct auth_user_info_dc *user_info_dc;
194         struct auth_method_context *method;
195         uint8_t authoritative;
196 };
197
198 static void auth_check_password_next(struct tevent_req *req);
199
200 /**
201  * Check a user's Plaintext, LM or NTLM password.
202  * async send hook
203  *
204  * Check a user's password, as given in the user_info struct and return various
205  * interesting details in the user_info_dc struct.
206  *
207  * The return value takes precedence over the contents of the user_info_dc
208  * struct.  When the return is other than NT_STATUS_OK the contents 
209  * of that structure is undefined.
210  *
211  * @param mem_ctx The memory context the request should operate on
212  *
213  * @param ev The tevent context the request should operate on
214  *
215  * @param auth_ctx Supplies the challenges and some other data. 
216  *                  Must be created with make_auth_context(), and the challenges should be 
217  *                  filled in, either at creation or by calling the challenge geneation 
218  *                  function auth_get_challenge().  
219  *
220  * @param user_info Contains the user supplied components, including the passwords.
221  *
222  * @return The request handle or NULL on no memory error.
223  *
224  **/
225
226 _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx,
227                                 struct tevent_context *ev,
228                                 struct auth4_context *auth_ctx,
229                                 const struct auth_usersupplied_info *user_info)
230 {
231         struct tevent_req *req;
232         struct auth_check_password_state *state;
233         /* if all the modules say 'not for me' this is reasonable */
234         NTSTATUS nt_status;
235         uint8_t chal[8];
236
237         DEBUG(3,("auth_check_password_send: "
238                  "Checking password for unmapped user [%s]\\[%s]@[%s]\n",
239                  user_info->client.domain_name, user_info->client.account_name,
240                  user_info->workstation_name));
241
242         req = tevent_req_create(mem_ctx, &state,
243                                 struct auth_check_password_state);
244         if (req == NULL) {
245                 return NULL;
246         }
247
248         /*
249          * We are authoritative by default.
250          */
251         state->ev               = ev;
252         state->auth_ctx         = auth_ctx;
253         state->user_info        = user_info;
254         state->authoritative    = 1;
255
256         if (!user_info->mapped_state) {
257                 struct auth_usersupplied_info *user_info_tmp;
258
259                 /*
260                  * We don't really do any mapping here.
261                  *
262                  * So we don't set user_info->mapped_state,
263                  * but we set mapped.domain_name and
264                  * mapped.account_name to the client
265                  * provided values.
266                  *
267                  * It's up to the backends to do mappings
268                  * for their authentication.
269                  */
270                 user_info_tmp = talloc_zero(state, struct auth_usersupplied_info);
271                 if (tevent_req_nomem(user_info_tmp, req)) {
272                         return tevent_req_post(req, ev);;
273                 }
274
275                 /*
276                  * The lifetime of user_info is longer than
277                  * user_info_tmp, so we don't need to copy the
278                  * strings.
279                  */
280                 *user_info_tmp = *user_info;
281                 user_info_tmp->mapped.domain_name = user_info->client.domain_name;
282                 user_info_tmp->mapped.account_name = user_info->client.account_name;
283
284                 user_info = user_info_tmp;
285                 state->user_info = user_info_tmp;
286         }
287
288         DEBUGADD(3,("auth_check_password_send: "
289                     "user is: [%s]\\[%s]@[%s]\n",
290                     user_info->mapped.domain_name,
291                     user_info->mapped.account_name,
292                     user_info->workstation_name));
293
294         nt_status = auth_get_challenge(auth_ctx, chal);
295         if (tevent_req_nterror(req, nt_status)) {
296                 DEBUG(0,("auth_check_password_send: "
297                          "Invalid challenge (length %u) stored for "
298                          "this auth context set_by %s - cannot continue: %s\n",
299                         (unsigned)auth_ctx->challenge.data.length,
300                         auth_ctx->challenge.set_by,
301                         nt_errstr(nt_status)));
302                 return tevent_req_post(req, ev);
303         }
304
305         if (auth_ctx->challenge.set_by) {
306                 DEBUG(10,("auth_check_password_send: "
307                           "auth_context challenge created by %s\n",
308                           auth_ctx->challenge.set_by));
309         }
310
311         DEBUG(10, ("auth_check_password_send: challenge is: \n"));
312         dump_data(5, auth_ctx->challenge.data.data,
313                   auth_ctx->challenge.data.length);
314
315         state->method = state->auth_ctx->methods;
316         auth_check_password_next(req);
317         if (!tevent_req_is_in_progress(req)) {
318                 return tevent_req_post(req, ev);
319         }
320
321         return req;
322 }
323
324 static void auth_check_password_done(struct tevent_req *subreq);
325
326 static void auth_check_password_next(struct tevent_req *req)
327 {
328         struct auth_check_password_state *state =
329                 tevent_req_data(req, struct auth_check_password_state);
330         struct tevent_req *subreq = NULL;
331         bool authoritative = true;
332         NTSTATUS status;
333
334         if (state->method == NULL) {
335                 state->authoritative = 0;
336                 tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);
337                 return;
338         }
339
340         /* check if the module wants to check the password */
341         status = state->method->ops->want_check(state->method, state,
342                                                 state->user_info);
343         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
344                 DEBUG(11,("auth_check_password_send: "
345                           "%s doesn't want to check\n",
346                           state->method->ops->name));
347                 state->method = state->method->next;
348                 auth_check_password_next(req);
349                 return;
350         }
351
352         if (tevent_req_nterror(req, status)) {
353                 return;
354         }
355
356         if (state->method->ops->check_password_send != NULL) {
357                 subreq = state->method->ops->check_password_send(state,
358                                                                  state->ev,
359                                                                  state->method,
360                                                                  state->user_info);
361                 if (tevent_req_nomem(subreq, req)) {
362                         return;
363                 }
364                 tevent_req_set_callback(subreq,
365                                         auth_check_password_done,
366                                         req);
367                 return;
368         }
369
370         if (state->method->ops->check_password == NULL) {
371                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
372                 return;
373         }
374
375         status = state->method->ops->check_password(state->method,
376                                                     state,
377                                                     state->user_info,
378                                                     &state->user_info_dc,
379                                                     &authoritative);
380         if (!authoritative ||
381             NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
382                 DEBUG(11,("auth_check_password_send: "
383                           "%s passes to the next method\n",
384                           state->method->ops->name));
385                 state->method = state->method->next;
386                 auth_check_password_next(req);
387                 return;
388         }
389
390         /* the backend has handled the request */
391
392         if (tevent_req_nterror(req, status)) {
393                 return;
394         }
395
396         tevent_req_done(req);
397 }
398
399 static void auth_check_password_done(struct tevent_req *subreq)
400 {
401         struct tevent_req *req =
402                 tevent_req_callback_data(subreq,
403                 struct tevent_req);
404         struct auth_check_password_state *state =
405                 tevent_req_data(req,
406                 struct auth_check_password_state);
407         bool authoritative = true;
408         NTSTATUS status;
409
410         status = state->method->ops->check_password_recv(subreq, state,
411                                                          &state->user_info_dc,
412                                                          &authoritative);
413         TALLOC_FREE(subreq);
414         if (!authoritative ||
415             NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
416                 DEBUG(11,("auth_check_password_send: "
417                           "%s passes to the next method\n",
418                           state->method->ops->name));
419                 state->method = state->method->next;
420                 auth_check_password_next(req);
421                 return;
422         }
423
424         /* the backend has handled the request */
425
426         if (tevent_req_nterror(req, status)) {
427                 return;
428         }
429
430         tevent_req_done(req);
431 }
432
433 /**
434  * Check a user's Plaintext, LM or NTLM password.
435  * async receive function
436  *
437  * The return value takes precedence over the contents of the user_info_dc
438  * struct.  When the return is other than NT_STATUS_OK the contents 
439  * of that structure is undefined.
440  *
441  *
442  * @param req The async request state
443  *
444  * @param mem_ctx The parent memory context for the user_info_dc structure
445  *
446  * @param user_info_dc If successful, contains information about the authentication,
447  *                    including a SAM_ACCOUNT struct describing the user.
448  *
449  * @return An NTSTATUS with NT_STATUS_OK or an appropriate error.
450  *
451  **/
452
453 _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req,
454                                   TALLOC_CTX *mem_ctx,
455                                   struct auth_user_info_dc **user_info_dc,
456                                   uint8_t *pauthoritative)
457 {
458         struct auth_check_password_state *state =
459                 tevent_req_data(req, struct auth_check_password_state);
460         NTSTATUS status = NT_STATUS_OK;
461
462         *pauthoritative = state->authoritative;
463
464         if (tevent_req_is_nterror(req, &status)) {
465                 /*
466                  * Please try not to change this string, it is probably in use
467                  * in audit logging tools
468                  */
469                 DEBUG(2,("auth_check_password_recv: "
470                          "%s authentication for user [%s\\%s] "
471                          "FAILED with error %s, authoritative=%u\n",
472                          (state->method ? state->method->ops->name : "NO_METHOD"),
473                          state->user_info->mapped.domain_name,
474                          state->user_info->mapped.account_name,
475                          nt_errstr(status), state->authoritative));
476
477                 log_authentication_event(state->auth_ctx->msg_ctx,
478                                          state->auth_ctx->lp_ctx,
479                                          state->user_info, status,
480                                          NULL, NULL, NULL, NULL);
481                 tevent_req_received(req);
482                 return status;
483         }
484
485         DEBUG(5,("auth_check_password_recv: "
486                  "%s authentication for user [%s\\%s] succeeded\n",
487                  state->method->ops->name,
488                  state->user_info_dc->info->domain_name,
489                  state->user_info_dc->info->account_name));
490
491         log_authentication_event(state->auth_ctx->msg_ctx,
492                                  state->auth_ctx->lp_ctx,
493                                  state->user_info, status,
494                                  state->user_info_dc->info->domain_name,
495                                  state->user_info_dc->info->account_name,
496                                  NULL,
497                                  &state->user_info_dc->sids[0]);
498
499         *user_info_dc = talloc_move(mem_ctx, &state->user_info_dc);
500
501         tevent_req_received(req);
502         return NT_STATUS_OK;
503 }
504
505 struct auth_check_password_wrapper_state {
506         uint8_t authoritative;
507         struct auth_user_info_dc *user_info_dc;
508 };
509
510 static void auth_check_password_wrapper_done(struct tevent_req *subreq);
511
512 static struct tevent_req *auth_check_password_wrapper_send(TALLOC_CTX *mem_ctx,
513                                         struct tevent_context *ev,
514                                         struct auth4_context *auth_ctx,
515                                         const struct auth_usersupplied_info *user_info)
516 {
517         struct tevent_req *req = NULL;
518         struct auth_check_password_wrapper *state = NULL;
519         struct tevent_req *subreq = NULL;
520
521         req = tevent_req_create(mem_ctx, &state,
522                                 struct auth_check_password_wrapper_state);
523         if (req == NULL) {
524                 return NULL;
525         }
526
527         subreq = auth_check_password_send(state, ev, auth_ctx, user_info);
528         if (tevent_req_nomem(subreq, req)) {
529                 return tevent_req_post(req, ev);
530         }
531         tevent_req_set_callback(subreq,
532                                 auth_check_password_wrapper_done,
533                                 req);
534
535         return req;
536 }
537
538 static void auth_check_password_wrapper_done(struct tevent_req *subreq)
539 {
540         struct tevent_req *req =
541                 tevent_req_callback_data(subreq,
542                 struct tevent_req);
543         struct auth_check_password_wrapper_state *state =
544                 tevent_req_data(req,
545                 struct auth_check_password_wrapper_state);
546         NTSTATUS status;
547
548         status = auth_check_password_recv(subreq, state,
549                                           &state->user_info_dc,
550                                           &state->authoritative);
551         TALLOC_FREE(subreq);
552         if (tevent_req_nterror(req, status)) {
553                 return;
554         }
555
556         tevent_req_done(req);
557 }
558
559 static NTSTATUS auth_check_password_wrapper_recv(struct tevent_req *req,
560                                         TALLOC_CTX *mem_ctx,
561                                         uint8_t *pauthoritative,
562                                         void **server_returned_info,
563                                         DATA_BLOB *user_session_key,
564                                         DATA_BLOB *lm_session_key)
565 {
566         struct auth_check_password_wrapper_state *state =
567                 tevent_req_data(req,
568                 struct auth_check_password_wrapper_state);
569         struct auth_user_info_dc *user_info_dc = state->user_info_dc;
570         NTSTATUS status = NT_STATUS_OK;
571
572         *pauthoritative = state->authoritative;
573
574         if (tevent_req_is_nterror(req, &status)) {
575                 tevent_req_received(req);
576                 return status;
577         }
578
579         talloc_steal(mem_ctx, user_info_dc);
580         *server_returned_info = user_info_dc;
581
582         if (user_session_key) {
583                 DEBUG(10, ("Got NT session key of length %u\n",
584                            (unsigned)user_info_dc->user_session_key.length));
585                 *user_session_key = user_info_dc->user_session_key;
586                 talloc_steal(mem_ctx, user_session_key->data);
587                 user_info_dc->user_session_key = data_blob_null;
588         }
589
590         if (lm_session_key) {
591                 DEBUG(10, ("Got LM session key of length %u\n",
592                            (unsigned)user_info_dc->lm_session_key.length));
593                 *lm_session_key = user_info_dc->lm_session_key;
594                 talloc_steal(mem_ctx, lm_session_key->data);
595                 user_info_dc->lm_session_key = data_blob_null;
596         }
597
598         tevent_req_received(req);
599         return NT_STATUS_OK;
600 }
601
602  /* Wrapper because we don't want to expose all callers to needing to
603   * know that session_info is generated from the main ldb, and because
604   * we need to break a depenency loop between the DCE/RPC layer and the
605   * generation of unix tokens via IRPC */
606 static NTSTATUS auth_generate_session_info_wrapper(struct auth4_context *auth_context,
607                                                    TALLOC_CTX *mem_ctx,
608                                                    void *server_returned_info,
609                                                    const char *original_user_name,
610                                                   uint32_t session_info_flags,
611                                                   struct auth_session_info **session_info)
612 {
613         NTSTATUS status;
614         struct auth_user_info_dc *user_info_dc = talloc_get_type_abort(server_returned_info, struct auth_user_info_dc);
615
616         if (user_info_dc->info->authenticated) {
617                 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
618         }
619
620         status = auth_generate_session_info(mem_ctx, auth_context->lp_ctx,
621                                             auth_context->sam_ctx, user_info_dc,
622                                             session_info_flags, session_info);
623         if (!NT_STATUS_IS_OK(status)) {
624                 return status;
625         }
626
627         if ((session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN)
628             && NT_STATUS_IS_OK(status)) {
629                 status = auth_session_info_fill_unix(auth_context->lp_ctx,
630                                                      original_user_name,
631                                                      *session_info);
632                 if (!NT_STATUS_IS_OK(status)) {
633                         TALLOC_FREE(*session_info);
634                 }
635         }
636         return status;
637 }
638
639 /* Wrapper because we don't want to expose all callers to needing to
640  * know anything about the PAC or auth subsystem internal structures
641  * before we output a struct auth session_info */
642 static NTSTATUS auth_generate_session_info_pac(struct auth4_context *auth_ctx,
643                                                TALLOC_CTX *mem_ctx,
644                                                struct smb_krb5_context *smb_krb5_context,
645                                                DATA_BLOB *pac_blob,
646                                                const char *principal_name,
647                                                const struct tsocket_address *remote_address,
648                                                uint32_t session_info_flags,
649                                                struct auth_session_info **session_info)
650 {
651         NTSTATUS status;
652         struct auth_user_info_dc *user_info_dc;
653         TALLOC_CTX *tmp_ctx;
654
655         if (!pac_blob) {
656                 return auth_generate_session_info_principal(auth_ctx, mem_ctx, principal_name,
657                                                        NULL, session_info_flags, session_info);
658         }
659
660         tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context");
661         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
662
663         status = kerberos_pac_blob_to_user_info_dc(tmp_ctx,
664                                                    *pac_blob,
665                                                    smb_krb5_context->krb5_context,
666                                                    &user_info_dc, NULL, NULL);
667         if (!NT_STATUS_IS_OK(status)) {
668                 talloc_free(tmp_ctx);
669                 return status;
670         }
671
672         if (user_info_dc->info->authenticated) {
673                 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
674         }
675
676         status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx, 
677                                                     user_info_dc,
678                                                     user_info_dc->info->account_name,
679                                                     session_info_flags, session_info);
680         talloc_free(tmp_ctx);
681         return status;
682 }
683
684 /***************************************************************************
685  Make a auth_info struct for the auth subsystem
686  - Allow the caller to specify the methods to use, including optionally the SAM to use
687 ***************************************************************************/
688 _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char * const *methods, 
689                                               struct tevent_context *ev,
690                                               struct imessaging_context *msg,
691                                               struct loadparm_context *lp_ctx,
692                                               struct ldb_context *sam_ctx,
693                                               struct auth4_context **auth_ctx)
694 {
695         int i;
696         struct auth4_context *ctx;
697
698         auth4_init();
699
700         if (!ev) {
701                 DEBUG(0,("auth_context_create: called with out event context\n"));
702                 return NT_STATUS_INTERNAL_ERROR;
703         }
704
705         ctx = talloc_zero(mem_ctx, struct auth4_context);
706         NT_STATUS_HAVE_NO_MEMORY(ctx);
707         ctx->challenge.data             = data_blob(NULL, 0);
708         ctx->methods                    = NULL;
709         ctx->event_ctx                  = ev;
710         ctx->msg_ctx                    = msg;
711         ctx->lp_ctx                     = lp_ctx;
712
713         if (sam_ctx) {
714                 ctx->sam_ctx = sam_ctx;
715         } else {
716                 ctx->sam_ctx = samdb_connect(ctx, ctx->event_ctx, ctx->lp_ctx, system_session(ctx->lp_ctx), 0);
717         }
718
719         for (i=0; methods && methods[i] ; i++) {
720                 struct auth_method_context *method;
721
722                 method = talloc(ctx, struct auth_method_context);
723                 NT_STATUS_HAVE_NO_MEMORY(method);
724
725                 method->ops = auth_backend_byname(methods[i]);
726                 if (!method->ops) {
727                         DEBUG(1,("auth_context_create: failed to find method=%s\n",
728                                 methods[i]));
729                         return NT_STATUS_INTERNAL_ERROR;
730                 }
731                 method->auth_ctx        = ctx;
732                 method->depth           = i;
733                 DLIST_ADD_END(ctx->methods, method);
734         }
735
736         ctx->check_ntlm_password_send = auth_check_password_wrapper_send;
737         ctx->check_ntlm_password_recv = auth_check_password_wrapper_recv;
738         ctx->get_ntlm_challenge = auth_get_challenge;
739         ctx->set_ntlm_challenge = auth_context_set_challenge;
740         ctx->generate_session_info = auth_generate_session_info_wrapper;
741         ctx->generate_session_info_pac = auth_generate_session_info_pac;
742
743         *auth_ctx = ctx;
744
745         return NT_STATUS_OK;
746 }
747
748 const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
749 {
750         char **auth_methods = NULL;
751
752         switch (lpcfg_server_role(lp_ctx)) {
753         case ROLE_STANDALONE:
754                 auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain", NULL);
755                 break;
756         case ROLE_DOMAIN_MEMBER:
757         case ROLE_DOMAIN_BDC:
758         case ROLE_DOMAIN_PDC:
759         case ROLE_ACTIVE_DIRECTORY_DC:
760                 auth_methods = str_list_make(mem_ctx, "anonymous sam winbind sam_ignoredomain", NULL);
761                 break;
762         }
763         return discard_const_p(const char *, auth_methods);
764 }
765
766 /***************************************************************************
767  Make a auth_info struct for the auth subsystem
768  - Uses default auth_methods, depending on server role and smb.conf settings
769 ***************************************************************************/
770 _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx,
771                              struct tevent_context *ev,
772                              struct imessaging_context *msg,
773                              struct loadparm_context *lp_ctx,
774                              struct auth4_context **auth_ctx)
775 {
776         NTSTATUS status;
777         const char **auth_methods;
778         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
779         if (!tmp_ctx) {
780                 return NT_STATUS_NO_MEMORY;
781         }
782
783         auth_methods = auth_methods_from_lp(tmp_ctx, lp_ctx);
784         if (!auth_methods) {
785                 return NT_STATUS_INVALID_PARAMETER;
786         }
787         status = auth_context_create_methods(mem_ctx, auth_methods, ev, msg, lp_ctx, NULL, auth_ctx);
788         talloc_free(tmp_ctx);
789         return status;
790 }
791
792 _PUBLIC_ NTSTATUS auth_context_create_for_netlogon(TALLOC_CTX *mem_ctx,
793                                                    struct tevent_context *ev,
794                                                    struct imessaging_context *msg,
795                                                    struct loadparm_context *lp_ctx,
796                                                    struct auth4_context **auth_ctx)
797 {
798         NTSTATUS status;
799         char **_auth_methods = NULL;
800         const char **auth_methods = NULL;
801
802         /*
803          * Here we only allow 'sam winbind' instead of
804          * the 'anonymous sam winbind sam_ignoredomain'
805          * we typically use for authentication from clients.
806          */
807         _auth_methods = str_list_make(mem_ctx, "sam winbind", NULL);
808         if (_auth_methods == NULL) {
809                 return NT_STATUS_NO_MEMORY;
810         }
811         auth_methods = discard_const_p(const char *, _auth_methods);
812
813         status = auth_context_create_methods(mem_ctx, auth_methods, ev, msg,
814                                              lp_ctx, NULL, auth_ctx);
815         talloc_free(_auth_methods);
816         return status;
817 }
818
819 /* the list of currently registered AUTH backends */
820 static struct auth_backend {
821         const struct auth_operations *ops;
822 } *backends = NULL;
823 static int num_backends;
824
825 /*
826   register a AUTH backend. 
827
828   The 'name' can be later used by other backends to find the operations
829   structure for this backend.
830 */
831 _PUBLIC_ NTSTATUS auth_register(TALLOC_CTX *mem_ctx,
832                         const struct auth_operations *ops)
833 {
834         struct auth_operations *new_ops;
835         
836         if (auth_backend_byname(ops->name) != NULL) {
837                 /* its already registered! */
838                 DEBUG(0,("AUTH backend '%s' already registered\n", 
839                          ops->name));
840                 return NT_STATUS_OBJECT_NAME_COLLISION;
841         }
842
843         backends = talloc_realloc(mem_ctx, backends,
844                                   struct auth_backend, num_backends+1);
845         NT_STATUS_HAVE_NO_MEMORY(backends);
846
847         new_ops = (struct auth_operations *)talloc_memdup(backends, ops, sizeof(*ops));
848         NT_STATUS_HAVE_NO_MEMORY(new_ops);
849         new_ops->name = talloc_strdup(new_ops, ops->name);
850         NT_STATUS_HAVE_NO_MEMORY(new_ops->name);
851
852         backends[num_backends].ops = new_ops;
853
854         num_backends++;
855
856         DEBUG(3,("AUTH backend '%s' registered\n", 
857                  ops->name));
858
859         return NT_STATUS_OK;
860 }
861
862 /*
863   return the operations structure for a named backend of the specified type
864 */
865 const struct auth_operations *auth_backend_byname(const char *name)
866 {
867         int i;
868
869         for (i=0;i<num_backends;i++) {
870                 if (strcmp(backends[i].ops->name, name) == 0) {
871                         return backends[i].ops;
872                 }
873         }
874
875         return NULL;
876 }
877
878 /*
879   return the AUTH interface version, and the size of some critical types
880   This can be used by backends to either detect compilation errors, or provide
881   multiple implementations for different smbd compilation options in one module
882 */
883 const struct auth_critical_sizes *auth_interface_version(void)
884 {
885         static const struct auth_critical_sizes critical_sizes = {
886                 AUTH4_INTERFACE_VERSION,
887                 sizeof(struct auth_operations),
888                 sizeof(struct auth_method_context),
889                 sizeof(struct auth4_context),
890                 sizeof(struct auth_usersupplied_info),
891                 sizeof(struct auth_user_info_dc)
892         };
893
894         return &critical_sizes;
895 }
896
897 _PUBLIC_ NTSTATUS auth4_init(void)
898 {
899         static bool initialized = false;
900 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
901         STATIC_auth4_MODULES_PROTO;
902         init_module_fn static_init[] = { STATIC_auth4_MODULES };
903         
904         if (initialized) return NT_STATUS_OK;
905         initialized = true;
906         
907         run_init_functions(NULL, static_init);
908         
909         return NT_STATUS_OK;    
910 }