2f2cdc1a4ff72208818bb5f31c2e23ef0c667801
[garming/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 static NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx,
190                                             TALLOC_CTX *mem_ctx,
191                                             const struct auth_usersupplied_info *user_info,
192                                             uint8_t *pauthoritative,
193                                             void **server_returned_info,
194                                             DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
195 {
196         struct auth_user_info_dc *user_info_dc;
197         NTSTATUS status;
198
199         status = auth_check_password(auth_ctx, mem_ctx, user_info,
200                                      &user_info_dc, pauthoritative);
201         if (!NT_STATUS_IS_OK(status)) {
202                 return status;
203         }
204
205         *server_returned_info = user_info_dc;
206
207         if (user_session_key) {
208                 DEBUG(10, ("Got NT session key of length %u\n",
209                            (unsigned)user_info_dc->user_session_key.length));
210                 *user_session_key = user_info_dc->user_session_key;
211                 talloc_steal(mem_ctx, user_session_key->data);
212                 user_info_dc->user_session_key = data_blob_null;
213         }
214
215         if (lm_session_key) {
216                 DEBUG(10, ("Got LM session key of length %u\n",
217                            (unsigned)user_info_dc->lm_session_key.length));
218                 *lm_session_key = user_info_dc->lm_session_key;
219                 talloc_steal(mem_ctx, lm_session_key->data);
220                 user_info_dc->lm_session_key = data_blob_null;
221         }
222
223         return NT_STATUS_OK;
224 }
225
226 struct auth_check_password_state {
227         struct auth4_context *auth_ctx;
228         const struct auth_usersupplied_info *user_info;
229         struct auth_user_info_dc *user_info_dc;
230         struct auth_method_context *method;
231         uint8_t authoritative;
232 };
233
234 static void auth_check_password_async_trigger(struct tevent_context *ev,
235                                               struct tevent_immediate *im,
236                                               void *private_data);
237 /**
238  * Check a user's Plaintext, LM or NTLM password.
239  * async send hook
240  *
241  * Check a user's password, as given in the user_info struct and return various
242  * interesting details in the user_info_dc struct.
243  *
244  * The return value takes precedence over the contents of the user_info_dc
245  * struct.  When the return is other than NT_STATUS_OK the contents 
246  * of that structure is undefined.
247  *
248  * @param mem_ctx The memory context the request should operate on
249  *
250  * @param ev The tevent context the request should operate on
251  *
252  * @param auth_ctx Supplies the challenges and some other data. 
253  *                  Must be created with make_auth_context(), and the challenges should be 
254  *                  filled in, either at creation or by calling the challenge geneation 
255  *                  function auth_get_challenge().  
256  *
257  * @param user_info Contains the user supplied components, including the passwords.
258  *
259  * @return The request handle or NULL on no memory error.
260  *
261  **/
262
263 _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx,
264                                 struct tevent_context *ev,
265                                 struct auth4_context *auth_ctx,
266                                 const struct auth_usersupplied_info *user_info)
267 {
268         struct tevent_req *req;
269         struct auth_check_password_state *state;
270         /* if all the modules say 'not for me' this is reasonable */
271         NTSTATUS nt_status;
272         uint8_t chal[8];
273         struct tevent_immediate *im;
274
275         DEBUG(3,("auth_check_password_send: "
276                  "Checking password for unmapped user [%s]\\[%s]@[%s]\n",
277                  user_info->client.domain_name, user_info->client.account_name,
278                  user_info->workstation_name));
279
280         req = tevent_req_create(mem_ctx, &state,
281                                 struct auth_check_password_state);
282         if (req == NULL) {
283                 return NULL;
284         }
285
286         /*
287          * We are authoritative by default.
288          */
289         state->authoritative    = 1;
290         state->auth_ctx         = auth_ctx;
291         state->user_info        = user_info;
292
293         if (!user_info->mapped_state) {
294                 struct auth_usersupplied_info *user_info_tmp;
295
296                 /*
297                  * We don't really do any mapping here.
298                  *
299                  * So we don't set user_info->mapped_state,
300                  * but we set mapped.domain_name and
301                  * mapped.account_name to the client
302                  * provided values.
303                  *
304                  * It's up to the backends to do mappings
305                  * for their authentication.
306                  */
307                 user_info_tmp = talloc_zero(state, struct auth_usersupplied_info);
308                 if (tevent_req_nomem(user_info_tmp, req)) {
309                         return tevent_req_post(req, ev);;
310                 }
311
312                 /*
313                  * The lifetime of user_info is longer than
314                  * user_info_tmp, so we don't need to copy the
315                  * strings.
316                  */
317                 *user_info_tmp = *user_info;
318                 user_info_tmp->mapped.domain_name = user_info->client.domain_name;
319                 user_info_tmp->mapped.account_name = user_info->client.account_name;
320
321                 user_info = user_info_tmp;
322                 state->user_info = user_info_tmp;
323         }
324
325         DEBUGADD(3,("auth_check_password_send: "
326                     "user is: [%s]\\[%s]@[%s]\n",
327                     user_info->mapped.domain_name,
328                     user_info->mapped.account_name,
329                     user_info->workstation_name));
330
331         nt_status = auth_get_challenge(auth_ctx, chal);
332         if (tevent_req_nterror(req, nt_status)) {
333                 DEBUG(0,("auth_check_password_send: "
334                          "Invalid challenge (length %u) stored for "
335                          "this auth context set_by %s - cannot continue: %s\n",
336                         (unsigned)auth_ctx->challenge.data.length,
337                         auth_ctx->challenge.set_by,
338                         nt_errstr(nt_status)));
339                 return tevent_req_post(req, ev);
340         }
341
342         if (auth_ctx->challenge.set_by) {
343                 DEBUG(10,("auth_check_password_send: "
344                           "auth_context challenge created by %s\n",
345                           auth_ctx->challenge.set_by));
346         }
347
348         DEBUG(10, ("auth_check_password_send: challenge is: \n"));
349         dump_data(5, auth_ctx->challenge.data.data,
350                   auth_ctx->challenge.data.length);
351
352         im = tevent_create_immediate(state);
353         if (tevent_req_nomem(im, req)) {
354                 return tevent_req_post(req, ev);
355         }
356
357         tevent_schedule_immediate(im,
358                                   auth_ctx->event_ctx,
359                                   auth_check_password_async_trigger,
360                                   req);
361         return req;
362 }
363
364 static void auth_check_password_async_trigger(struct tevent_context *ev,
365                                               struct tevent_immediate *im,
366                                               void *private_data)
367 {
368         struct tevent_req *req =
369                 talloc_get_type_abort(private_data, struct tevent_req);
370         struct auth_check_password_state *state =
371                 tevent_req_data(req, struct auth_check_password_state);
372         NTSTATUS status;
373         struct auth_method_context *method;
374
375         status = NT_STATUS_OK;
376
377         for (method=state->auth_ctx->methods; method; method = method->next) {
378
379                 /* we fill in state->method here so debug messages in
380                    the callers know which method failed */
381                 state->method = method;
382
383                 /* check if the module wants to check the password */
384                 status = method->ops->want_check(method, req, state->user_info);
385                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
386                         DEBUG(11,("auth_check_password_send: "
387                                   "%s doesn't want to check\n",
388                                   method->ops->name));
389                         continue;
390                 }
391
392                 if (tevent_req_nterror(req, status)) {
393                         return;
394                 }
395
396                 status = method->ops->check_password(method,
397                                                      state,
398                                                      state->user_info,
399                                                      &state->user_info_dc);
400                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
401                         DEBUG(11,("auth_check_password_send: "
402                                   "%s passes to the next method\n",
403                                   method->ops->name));
404                         continue;
405                 }
406
407                 /* the backend has handled the request */
408                 break;
409         }
410
411         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
412                 state->authoritative = 0;
413                 status = NT_STATUS_NO_SUCH_USER;
414         }
415
416         if (tevent_req_nterror(req, status)) {
417                 return;
418         }
419
420         tevent_req_done(req);
421 }
422
423 /**
424  * Check a user's Plaintext, LM or NTLM password.
425  * async receive function
426  *
427  * The return value takes precedence over the contents of the user_info_dc
428  * struct.  When the return is other than NT_STATUS_OK the contents 
429  * of that structure is undefined.
430  *
431  *
432  * @param req The async request state
433  *
434  * @param mem_ctx The parent memory context for the user_info_dc structure
435  *
436  * @param user_info_dc If successful, contains information about the authentication,
437  *                    including a SAM_ACCOUNT struct describing the user.
438  *
439  * @return An NTSTATUS with NT_STATUS_OK or an appropriate error.
440  *
441  **/
442
443 _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req,
444                                   TALLOC_CTX *mem_ctx,
445                                   struct auth_user_info_dc **user_info_dc,
446                                   uint8_t *pauthoritative)
447 {
448         struct auth_check_password_state *state =
449                 tevent_req_data(req, struct auth_check_password_state);
450         NTSTATUS status = NT_STATUS_OK;
451
452         *pauthoritative = state->authoritative;
453
454         if (tevent_req_is_nterror(req, &status)) {
455                 /*
456                  * Please try not to change this string, it is probably in use
457                  * in audit logging tools
458                  */
459                 DEBUG(2,("auth_check_password_recv: "
460                          "%s authentication for user [%s\\%s] "
461                          "FAILED with error %s, authoritative=%u\n",
462                          (state->method ? state->method->ops->name : "NO_METHOD"),
463                          state->user_info->mapped.domain_name,
464                          state->user_info->mapped.account_name,
465                          nt_errstr(status), state->authoritative));
466
467                 log_authentication_event(state->auth_ctx->msg_ctx,
468                                          state->auth_ctx->lp_ctx,
469                                          state->user_info, status,
470                                          NULL, NULL, NULL, NULL);
471                 tevent_req_received(req);
472                 return status;
473         }
474
475         DEBUG(5,("auth_check_password_recv: "
476                  "%s authentication for user [%s\\%s] succeeded\n",
477                  state->method->ops->name,
478                  state->user_info_dc->info->domain_name,
479                  state->user_info_dc->info->account_name));
480
481         log_authentication_event(state->auth_ctx->msg_ctx,
482                                  state->auth_ctx->lp_ctx,
483                                  state->user_info, status,
484                                  state->user_info_dc->info->domain_name,
485                                  state->user_info_dc->info->account_name,
486                                  NULL,
487                                  &state->user_info_dc->sids[0]);
488
489         *user_info_dc = talloc_move(mem_ctx, &state->user_info_dc);
490
491         tevent_req_received(req);
492         return NT_STATUS_OK;
493 }
494
495  /* Wrapper because we don't want to expose all callers to needing to
496   * know that session_info is generated from the main ldb, and because
497   * we need to break a depenency loop between the DCE/RPC layer and the
498   * generation of unix tokens via IRPC */
499 static NTSTATUS auth_generate_session_info_wrapper(struct auth4_context *auth_context,
500                                                    TALLOC_CTX *mem_ctx,
501                                                    void *server_returned_info,
502                                                    const char *original_user_name,
503                                                   uint32_t session_info_flags,
504                                                   struct auth_session_info **session_info)
505 {
506         NTSTATUS status;
507         struct auth_user_info_dc *user_info_dc = talloc_get_type_abort(server_returned_info, struct auth_user_info_dc);
508
509         if (user_info_dc->info->authenticated) {
510                 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
511         }
512
513         status = auth_generate_session_info(mem_ctx, auth_context->lp_ctx,
514                                             auth_context->sam_ctx, user_info_dc,
515                                             session_info_flags, session_info);
516         if (!NT_STATUS_IS_OK(status)) {
517                 return status;
518         }
519
520         if ((session_info_flags & AUTH_SESSION_INFO_UNIX_TOKEN)
521             && NT_STATUS_IS_OK(status)) {
522                 status = auth_session_info_fill_unix(auth_context->event_ctx,
523                                                      auth_context->lp_ctx,
524                                                      original_user_name, *session_info);
525                 if (!NT_STATUS_IS_OK(status)) {
526                         TALLOC_FREE(*session_info);
527                 }
528         }
529         return status;
530 }
531
532 /* Wrapper because we don't want to expose all callers to needing to
533  * know anything about the PAC or auth subsystem internal structures
534  * before we output a struct auth session_info */
535 static NTSTATUS auth_generate_session_info_pac(struct auth4_context *auth_ctx,
536                                                TALLOC_CTX *mem_ctx,
537                                                struct smb_krb5_context *smb_krb5_context,
538                                                DATA_BLOB *pac_blob,
539                                                const char *principal_name,
540                                                const struct tsocket_address *remote_address,
541                                                uint32_t session_info_flags,
542                                                struct auth_session_info **session_info)
543 {
544         NTSTATUS status;
545         struct auth_user_info_dc *user_info_dc;
546         TALLOC_CTX *tmp_ctx;
547
548         if (!pac_blob) {
549                 return auth_generate_session_info_principal(auth_ctx, mem_ctx, principal_name,
550                                                        NULL, session_info_flags, session_info);
551         }
552
553         tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context");
554         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
555
556         status = kerberos_pac_blob_to_user_info_dc(tmp_ctx,
557                                                    *pac_blob,
558                                                    smb_krb5_context->krb5_context,
559                                                    &user_info_dc, NULL, NULL);
560         if (!NT_STATUS_IS_OK(status)) {
561                 talloc_free(tmp_ctx);
562                 return status;
563         }
564
565         if (user_info_dc->info->authenticated) {
566                 session_info_flags |= AUTH_SESSION_INFO_AUTHENTICATED;
567         }
568
569         status = auth_generate_session_info_wrapper(auth_ctx, mem_ctx, 
570                                                     user_info_dc,
571                                                     user_info_dc->info->account_name,
572                                                     session_info_flags, session_info);
573         talloc_free(tmp_ctx);
574         return status;
575 }
576
577 /***************************************************************************
578  Make a auth_info struct for the auth subsystem
579  - Allow the caller to specify the methods to use, including optionally the SAM to use
580 ***************************************************************************/
581 _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char * const *methods, 
582                                               struct tevent_context *ev,
583                                               struct imessaging_context *msg,
584                                               struct loadparm_context *lp_ctx,
585                                               struct ldb_context *sam_ctx,
586                                               struct auth4_context **auth_ctx)
587 {
588         int i;
589         struct auth4_context *ctx;
590
591         auth4_init();
592
593         if (!ev) {
594                 DEBUG(0,("auth_context_create: called with out event context\n"));
595                 return NT_STATUS_INTERNAL_ERROR;
596         }
597
598         ctx = talloc_zero(mem_ctx, struct auth4_context);
599         NT_STATUS_HAVE_NO_MEMORY(ctx);
600         ctx->challenge.data             = data_blob(NULL, 0);
601         ctx->methods                    = NULL;
602         ctx->event_ctx                  = ev;
603         ctx->msg_ctx                    = msg;
604         ctx->lp_ctx                     = lp_ctx;
605
606         if (sam_ctx) {
607                 ctx->sam_ctx = sam_ctx;
608         } else {
609                 ctx->sam_ctx = samdb_connect(ctx, ctx->event_ctx, ctx->lp_ctx, system_session(ctx->lp_ctx), 0);
610         }
611
612         for (i=0; methods && methods[i] ; i++) {
613                 struct auth_method_context *method;
614
615                 method = talloc(ctx, struct auth_method_context);
616                 NT_STATUS_HAVE_NO_MEMORY(method);
617
618                 method->ops = auth_backend_byname(methods[i]);
619                 if (!method->ops) {
620                         DEBUG(1,("auth_context_create: failed to find method=%s\n",
621                                 methods[i]));
622                         return NT_STATUS_INTERNAL_ERROR;
623                 }
624                 method->auth_ctx        = ctx;
625                 method->depth           = i;
626                 DLIST_ADD_END(ctx->methods, method);
627         }
628
629         ctx->check_ntlm_password = auth_check_password_wrapper;
630         ctx->get_ntlm_challenge = auth_get_challenge;
631         ctx->set_ntlm_challenge = auth_context_set_challenge;
632         ctx->generate_session_info = auth_generate_session_info_wrapper;
633         ctx->generate_session_info_pac = auth_generate_session_info_pac;
634
635         *auth_ctx = ctx;
636
637         return NT_STATUS_OK;
638 }
639
640 const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
641 {
642         char **auth_methods = NULL;
643         const char **const_auth_methods = NULL;
644
645         /*
646          * As 'auth methods' is deprecated it will be removed
647          * in future releases again, but for now give
648          * admins the flexibility to configure, the behavior
649          * from Samba 4.6: "auth methods = anonymous sam_ignoredomain",
650          * for a while.
651          */
652         const_auth_methods = lpcfg_auth_methods(lp_ctx);
653         if (const_auth_methods != NULL) {
654                 DBG_NOTICE("using deprecated 'auth methods' values.\n");
655                 return const_auth_methods;
656         }
657
658         switch (lpcfg_server_role(lp_ctx)) {
659         case ROLE_STANDALONE:
660                 auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain", NULL);
661                 break;
662         case ROLE_DOMAIN_MEMBER:
663                 auth_methods = str_list_make(mem_ctx, "anonymous sam winbind sam_ignoredomain", NULL);
664                 break;
665         case ROLE_DOMAIN_BDC:
666         case ROLE_DOMAIN_PDC:
667         case ROLE_ACTIVE_DIRECTORY_DC:
668                 /*
669                  * TODO: we should replace "winbind_rodc sam_failtrusts" with "winbind"
670                  * if everything (gensec/auth4) is fully async without nested
671                  * event loops!
672                  *
673                  * But for now we'll fail authentications for trusted
674                  * domain consistently with NT_STATUS_NO_TRUST_LSA_SECRET,
675                  * instead of silently mapping to local users.
676                  */
677                 auth_methods = str_list_make(mem_ctx,
678                                              "anonymous sam "
679                                              "winbind_rodc sam_failtrusts "
680                                              "sam_ignoredomain",
681                                              NULL);
682                 break;
683         }
684         return discard_const_p(const char *, auth_methods);
685 }
686
687 /***************************************************************************
688  Make a auth_info struct for the auth subsystem
689  - Uses default auth_methods, depending on server role and smb.conf settings
690 ***************************************************************************/
691 _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx,
692                              struct tevent_context *ev,
693                              struct imessaging_context *msg,
694                              struct loadparm_context *lp_ctx,
695                              struct auth4_context **auth_ctx)
696 {
697         NTSTATUS status;
698         const char **auth_methods;
699         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
700         if (!tmp_ctx) {
701                 return NT_STATUS_NO_MEMORY;
702         }
703
704         auth_methods = auth_methods_from_lp(tmp_ctx, lp_ctx);
705         if (!auth_methods) {
706                 return NT_STATUS_INVALID_PARAMETER;
707         }
708         status = auth_context_create_methods(mem_ctx, auth_methods, ev, msg, lp_ctx, NULL, auth_ctx);
709         talloc_free(tmp_ctx);
710         return status;
711 }
712
713 _PUBLIC_ NTSTATUS auth_context_create_for_netlogon(TALLOC_CTX *mem_ctx,
714                                                    struct tevent_context *ev,
715                                                    struct imessaging_context *msg,
716                                                    struct loadparm_context *lp_ctx,
717                                                    struct auth4_context **auth_ctx)
718 {
719         NTSTATUS status;
720         char **_auth_methods = NULL;
721         const char **auth_methods = NULL;
722
723         /*
724          * As 'auth methods' is deprecated it will be removed
725          * in future releases again, but for now give
726          * admins the flexibility to configure, the behavior
727          * from Samba 4.6: "auth methods = anonymous sam_ignoredomain",
728          * for a while.
729          */
730         auth_methods = lpcfg_auth_methods(lp_ctx);
731         if (auth_methods != NULL) {
732                 DBG_NOTICE("using deprecated 'auth methods' values.\n");
733         } else {
734                 /*
735                  * We can remove "winbind_rodc sam_failtrusts",
736                  * when we made the netlogon retries to
737                  * to contact winbind via irpc.
738                  */
739                 _auth_methods = str_list_make(mem_ctx,
740                                 "sam "
741                                 "winbind_rodc sam_failtrusts",
742                                 NULL);
743                 if (_auth_methods == NULL) {
744                         return NT_STATUS_NO_MEMORY;
745                 }
746                 auth_methods = discard_const_p(const char *, _auth_methods);
747         }
748
749         status = auth_context_create_methods(mem_ctx, auth_methods, ev, msg,
750                                              lp_ctx, NULL, auth_ctx);
751         talloc_free(_auth_methods);
752         return status;
753 }
754
755 /* the list of currently registered AUTH backends */
756 static struct auth_backend {
757         const struct auth_operations *ops;
758 } *backends = NULL;
759 static int num_backends;
760
761 /*
762   register a AUTH backend. 
763
764   The 'name' can be later used by other backends to find the operations
765   structure for this backend.
766 */
767 _PUBLIC_ NTSTATUS auth_register(const struct auth_operations *ops)
768 {
769         struct auth_operations *new_ops;
770         
771         if (auth_backend_byname(ops->name) != NULL) {
772                 /* its already registered! */
773                 DEBUG(0,("AUTH backend '%s' already registered\n", 
774                          ops->name));
775                 return NT_STATUS_OBJECT_NAME_COLLISION;
776         }
777
778         backends = talloc_realloc(talloc_autofree_context(), backends, 
779                                   struct auth_backend, num_backends+1);
780         NT_STATUS_HAVE_NO_MEMORY(backends);
781
782         new_ops = (struct auth_operations *)talloc_memdup(backends, ops, sizeof(*ops));
783         NT_STATUS_HAVE_NO_MEMORY(new_ops);
784         new_ops->name = talloc_strdup(new_ops, ops->name);
785         NT_STATUS_HAVE_NO_MEMORY(new_ops->name);
786
787         backends[num_backends].ops = new_ops;
788
789         num_backends++;
790
791         DEBUG(3,("AUTH backend '%s' registered\n", 
792                  ops->name));
793
794         return NT_STATUS_OK;
795 }
796
797 /*
798   return the operations structure for a named backend of the specified type
799 */
800 const struct auth_operations *auth_backend_byname(const char *name)
801 {
802         int i;
803
804         for (i=0;i<num_backends;i++) {
805                 if (strcmp(backends[i].ops->name, name) == 0) {
806                         return backends[i].ops;
807                 }
808         }
809
810         return NULL;
811 }
812
813 /*
814   return the AUTH interface version, and the size of some critical types
815   This can be used by backends to either detect compilation errors, or provide
816   multiple implementations for different smbd compilation options in one module
817 */
818 const struct auth_critical_sizes *auth_interface_version(void)
819 {
820         static const struct auth_critical_sizes critical_sizes = {
821                 AUTH4_INTERFACE_VERSION,
822                 sizeof(struct auth_operations),
823                 sizeof(struct auth_method_context),
824                 sizeof(struct auth4_context),
825                 sizeof(struct auth_usersupplied_info),
826                 sizeof(struct auth_user_info_dc)
827         };
828
829         return &critical_sizes;
830 }
831
832 _PUBLIC_ NTSTATUS auth4_init(void)
833 {
834         static bool initialized = false;
835 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
836         STATIC_auth4_MODULES_PROTO;
837         init_module_fn static_init[] = { STATIC_auth4_MODULES };
838         
839         if (initialized) return NT_STATUS_OK;
840         initialized = true;
841         
842         run_init_functions(NULL, static_init);
843         
844         return NT_STATUS_OK;    
845 }