12ad78036d00f6802896966374ef56d71292796e
[samba.git] / source4 / rpc_server / netlogon / dcerpc_netlogon.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    endpoint server for the netlogon pipe
5
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
7    Copyright (C) Stefan Metzmacher <metze@samba.org>  2005
8    Copyright (C) Matthias Dieter Wallnöfer            2009-2010
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "rpc_server/dcerpc_server.h"
26 #include "rpc_server/common/common.h"
27 #include "auth/auth.h"
28 #include "auth/auth_sam_reply.h"
29 #include "dsdb/samdb/samdb.h"
30 #include "../lib/util/util_ldb.h"
31 #include "../libcli/auth/schannel.h"
32 #include "libcli/security/security.h"
33 #include "param/param.h"
34 #include "lib/messaging/irpc.h"
35 #include "librpc/gen_ndr/ndr_irpc_c.h"
36 #include "../libcli/ldap/ldap_ndr.h"
37 #include "dsdb/samdb/ldb_modules/util.h"
38 #include "lib/tsocket/tsocket.h"
39 #include "librpc/gen_ndr/ndr_netlogon.h"
40 #include "librpc/gen_ndr/ndr_lsa.h"
41 #include "librpc/gen_ndr/ndr_samr.h"
42 #include "librpc/gen_ndr/ndr_irpc.h"
43 #include "librpc/gen_ndr/ndr_winbind.h"
44 #include "librpc/gen_ndr/ndr_winbind_c.h"
45 #include "lib/socket/netif.h"
46 #include "lib/util/util_str_escape.h"
47 #include "lib/param/loadparm.h"
48
49 #define DCESRV_INTERFACE_NETLOGON_BIND(context, iface) \
50        dcesrv_interface_netlogon_bind(context, iface)
51
52 #undef strcasecmp
53
54 /*
55  * This #define allows the netlogon interface to accept invalid
56  * association groups, because association groups are to coordinate
57  * handles, and handles are not used in NETLOGON. This in turn avoids
58  * the need to coordinate these across multiple possible NETLOGON
59  * processes
60  */
61 #define DCESRV_INTERFACE_NETLOGON_FLAGS DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED
62
63 static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_connection_context *context,
64                                                const struct dcesrv_interface *iface)
65 {
66         return dcesrv_interface_bind_reject_connect(context, iface);
67 }
68
69 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
70                                         struct netr_ServerReqChallenge *r)
71 {
72         struct netlogon_server_pipe_state *pipe_state = NULL;
73         NTSTATUS ntstatus;
74
75         ZERO_STRUCTP(r->out.return_credentials);
76
77         pipe_state = dcesrv_iface_state_find_conn(dce_call,
78                         NETLOGON_SERVER_PIPE_STATE_MAGIC,
79                         struct netlogon_server_pipe_state);
80         TALLOC_FREE(pipe_state);
81
82         pipe_state = talloc_zero(dce_call,
83                                  struct netlogon_server_pipe_state);
84         if (pipe_state == NULL) {
85                 return NT_STATUS_NO_MEMORY;
86         }
87
88         pipe_state->client_challenge = *r->in.credentials;
89
90         netlogon_creds_random_challenge(&pipe_state->server_challenge);
91
92         *r->out.return_credentials = pipe_state->server_challenge;
93
94         ntstatus = dcesrv_iface_state_store_conn(dce_call,
95                         NETLOGON_SERVER_PIPE_STATE_MAGIC,
96                         pipe_state);
97         if (!NT_STATUS_IS_OK(ntstatus)) {
98                 return ntstatus;
99         }
100
101         ntstatus = schannel_save_challenge(dce_call->conn->dce_ctx->lp_ctx,
102                                            &pipe_state->client_challenge,
103                                            &pipe_state->server_challenge,
104                                            r->in.computer_name);
105         if (!NT_STATUS_IS_OK(ntstatus)) {
106                 TALLOC_FREE(pipe_state);
107                 return ntstatus;
108         }
109
110         return NT_STATUS_OK;
111 }
112
113 /*
114  * Do the actual processing of a netr_ServerAuthenticate3 message.
115  * called from dcesrv_netr_ServerAuthenticate3, which handles the logging.
116  */
117 static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
118         struct dcesrv_call_state *dce_call,
119         TALLOC_CTX *mem_ctx,
120         struct netr_ServerAuthenticate3 *r,
121         const char **trust_account_for_search,
122         const char **trust_account_in_db,
123         struct dom_sid **sid)
124 {
125         struct netlogon_server_pipe_state *pipe_state = NULL;
126         bool challenge_valid = false;
127         struct netlogon_server_pipe_state challenge;
128         struct netlogon_creds_CredentialState *creds;
129         struct ldb_context *sam_ctx;
130         struct samr_Password *curNtHash = NULL;
131         struct samr_Password *prevNtHash = NULL;
132         uint32_t user_account_control;
133         int num_records;
134         struct ldb_message **msgs;
135         NTSTATUS nt_status;
136         const char *attrs[] = {"unicodePwd", "userAccountControl",
137                                "objectSid", "samAccountName", NULL};
138         uint32_t server_flags = 0;
139         uint32_t negotiate_flags = 0;
140         bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(dce_call->conn->dce_ctx->lp_ctx);
141         bool reject_des_client = !allow_nt4_crypto;
142         bool reject_md5_client = lpcfg_reject_md5_clients(dce_call->conn->dce_ctx->lp_ctx);
143
144         ZERO_STRUCTP(r->out.return_credentials);
145         *r->out.rid = 0;
146
147         pipe_state = dcesrv_iface_state_find_conn(dce_call,
148                         NETLOGON_SERVER_PIPE_STATE_MAGIC,
149                         struct netlogon_server_pipe_state);
150         if (pipe_state != NULL) {
151                 /*
152                  * If we had a challenge remembered on the connection
153                  * consider this for usage. This can't be cleanup
154                  * by other clients.
155                  *
156                  * This is the default code path for typical clients
157                  * which call netr_ServerReqChallenge() and
158                  * netr_ServerAuthenticate3() on the same dcerpc connection.
159                  */
160                 challenge = *pipe_state;
161
162                 challenge_valid = true;
163
164         } else {
165                 NTSTATUS ntstatus;
166
167                 /*
168                  * Fallback and try to get the challenge from
169                  * the global cache.
170                  *
171                  * If too many clients are using this code path,
172                  * they may destroy their cache entries as the
173                  * TDB has a fixed size limited via a lossy hash
174                  *
175                  * The TDB used is the schannel store, which is
176                  * initialised at startup.
177                  *
178                  * NOTE: The challenge is deleted from the DB as soon as it is
179                  * fetched, to prevent reuse.
180                  *
181                  */
182
183                 ntstatus = schannel_get_challenge(dce_call->conn->dce_ctx->lp_ctx,
184                                                   &challenge.client_challenge,
185                                                   &challenge.server_challenge,
186                                                   r->in.computer_name);
187
188                 if (!NT_STATUS_IS_OK(ntstatus)) {
189                         ZERO_STRUCT(challenge);
190                 } else {
191                         challenge_valid = true;
192                 }
193         }
194
195         server_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT |
196                        NETLOGON_NEG_PERSISTENT_SAMREPL |
197                        NETLOGON_NEG_ARCFOUR |
198                        NETLOGON_NEG_PROMOTION_COUNT |
199                        NETLOGON_NEG_CHANGELOG_BDC |
200                        NETLOGON_NEG_FULL_SYNC_REPL |
201                        NETLOGON_NEG_MULTIPLE_SIDS |
202                        NETLOGON_NEG_REDO |
203                        NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
204                        NETLOGON_NEG_SEND_PASSWORD_INFO_PDC |
205                        NETLOGON_NEG_GENERIC_PASSTHROUGH |
206                        NETLOGON_NEG_CONCURRENT_RPC |
207                        NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL |
208                        NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL |
209                        NETLOGON_NEG_STRONG_KEYS |
210                        NETLOGON_NEG_TRANSITIVE_TRUSTS |
211                        NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
212                        NETLOGON_NEG_PASSWORD_SET2 |
213                        NETLOGON_NEG_GETDOMAININFO |
214                        NETLOGON_NEG_CROSS_FOREST_TRUSTS |
215                        NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION |
216                        NETLOGON_NEG_RODC_PASSTHROUGH |
217                        NETLOGON_NEG_SUPPORTS_AES |
218                        NETLOGON_NEG_AUTHENTICATED_RPC_LSASS |
219                        NETLOGON_NEG_AUTHENTICATED_RPC;
220
221         /*
222          * If weak cryto is disabled, do not announce that we support RC4.
223          */
224         if (lpcfg_weak_crypto(dce_call->conn->dce_ctx->lp_ctx) ==
225             SAMBA_WEAK_CRYPTO_DISALLOWED) {
226                 server_flags &= ~NETLOGON_NEG_ARCFOUR;
227         }
228
229         negotiate_flags = *r->in.negotiate_flags & server_flags;
230
231         if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
232                 reject_des_client = false;
233         }
234
235         if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
236                 reject_des_client = false;
237                 reject_md5_client = false;
238         }
239
240         if (reject_des_client || reject_md5_client) {
241                 /*
242                  * Here we match Windows 2012 and return no flags.
243                  */
244                 *r->out.negotiate_flags = 0;
245                 return NT_STATUS_DOWNGRADE_DETECTED;
246         }
247
248         /*
249          * This talloc_free is important to prevent re-use of the
250          * challenge.  We have to delay it this far due to NETApp
251          * servers per:
252          * https://bugzilla.samba.org/show_bug.cgi?id=11291
253          */
254         TALLOC_FREE(pipe_state);
255
256         /*
257          * At this point we must also cleanup the TDB cache
258          * entry, if we fail the client needs to call
259          * netr_ServerReqChallenge again.
260          *
261          * Note: this handles a non existing record just fine,
262          * the r->in.computer_name might not be the one used
263          * in netr_ServerReqChallenge(), but we are trying to
264          * just tidy up the normal case to prevent re-use.
265          */
266         schannel_delete_challenge(dce_call->conn->dce_ctx->lp_ctx,
267                                   r->in.computer_name);
268
269         /*
270          * According to Microsoft (see bugid #6099)
271          * Windows 7 looks at the negotiate_flags
272          * returned in this structure *even if the
273          * call fails with access denied!
274          */
275         *r->out.negotiate_flags = negotiate_flags;
276
277         switch (r->in.secure_channel_type) {
278         case SEC_CHAN_WKSTA:
279         case SEC_CHAN_DNS_DOMAIN:
280         case SEC_CHAN_DOMAIN:
281         case SEC_CHAN_BDC:
282         case SEC_CHAN_RODC:
283                 break;
284         case SEC_CHAN_NULL:
285                 return NT_STATUS_INVALID_PARAMETER;
286         default:
287                 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
288                           r->in.secure_channel_type));
289                 return NT_STATUS_INVALID_PARAMETER;
290         }
291
292         sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
293         if (sam_ctx == NULL) {
294                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
295         }
296
297         if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
298             r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN)
299         {
300                 struct ldb_message *tdo_msg = NULL;
301                 const char * const tdo_attrs[] = {
302                         "trustAuthIncoming",
303                         "trustAttributes",
304                         "flatName",
305                         NULL
306                 };
307                 char *encoded_name = NULL;
308                 size_t len;
309                 const char *flatname = NULL;
310                 char trailer = '$';
311                 bool require_trailer = true;
312                 const char *netbios = NULL;
313                 const char *dns = NULL;
314
315                 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
316                         trailer = '.';
317                         require_trailer = false;
318                 }
319
320                 encoded_name = ldb_binary_encode_string(mem_ctx,
321                                                         r->in.account_name);
322                 if (encoded_name == NULL) {
323                         return NT_STATUS_NO_MEMORY;
324                 }
325
326                 len = strlen(encoded_name);
327                 if (len < 2) {
328                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
329                 }
330
331                 if (require_trailer && encoded_name[len - 1] != trailer) {
332                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
333                 }
334                 encoded_name[len - 1] = '\0';
335
336                 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
337                         dns = encoded_name;
338                 } else {
339                         netbios = encoded_name;
340                 }
341
342                 nt_status = dsdb_trust_search_tdo(sam_ctx,
343                                                   netbios, dns,
344                                                   tdo_attrs, mem_ctx, &tdo_msg);
345                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
346                         DEBUG(2, ("Client asked for a trusted domain secure channel, "
347                                   "but there's no tdo for [%s] => [%s] \n",
348                                   log_escape(mem_ctx, r->in.account_name),
349                                   encoded_name));
350                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
351                 }
352                 if (!NT_STATUS_IS_OK(nt_status)) {
353                         return nt_status;
354                 }
355
356                 nt_status = dsdb_trust_get_incoming_passwords(tdo_msg, mem_ctx,
357                                                               &curNtHash,
358                                                               &prevNtHash);
359                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_DISABLED)) {
360                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
361                 }
362                 if (!NT_STATUS_IS_OK(nt_status)) {
363                         return nt_status;
364                 }
365
366                 flatname = ldb_msg_find_attr_as_string(tdo_msg, "flatName", NULL);
367                 if (flatname == NULL) {
368                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
369                 }
370
371                 *trust_account_for_search = talloc_asprintf(mem_ctx, "%s$", flatname);
372                 if (*trust_account_for_search == NULL) {
373                         return NT_STATUS_NO_MEMORY;
374                 }
375         } else {
376                 *trust_account_for_search = r->in.account_name;
377         }
378
379         /* pull the user attributes */
380         num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
381                                    "(&(sAMAccountName=%s)(objectclass=user))",
382                                    ldb_binary_encode_string(mem_ctx,
383                                                             *trust_account_for_search));
384
385         if (num_records == 0) {
386                 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
387                          log_escape(mem_ctx, r->in.account_name)));
388                 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
389         }
390
391         if (num_records > 1) {
392                 DEBUG(0,("Found %d records matching user [%s]\n",
393                          num_records,
394                          log_escape(mem_ctx, r->in.account_name)));
395                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
396         }
397
398         *trust_account_in_db = ldb_msg_find_attr_as_string(msgs[0],
399                                                            "samAccountName",
400                                                            NULL);
401         if (*trust_account_in_db == NULL) {
402                 DEBUG(0,("No samAccountName returned in record matching user [%s]\n",
403                          r->in.account_name));
404                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
405         }
406         
407         user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
408
409         if (user_account_control & UF_ACCOUNTDISABLE) {
410                 DEBUG(1, ("Account [%s] is disabled\n",
411                           log_escape(mem_ctx, r->in.account_name)));
412                 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
413         }
414
415         if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
416                 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
417                         DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
418                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
419                 }
420         } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
421                    r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
422                 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
423                         DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
424
425                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
426                 }
427         } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
428                 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
429                         DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
430                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
431                 }
432         } else if (r->in.secure_channel_type == SEC_CHAN_RODC) {
433                 if (!(user_account_control & UF_PARTIAL_SECRETS_ACCOUNT)) {
434                         DEBUG(1, ("Client asked for a RODC secure channel, but is not a RODC: acb flags: 0x%x\n", user_account_control));
435                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
436                 }
437         } else {
438                 /* we should never reach this */
439                 return NT_STATUS_INTERNAL_ERROR;
440         }
441
442         if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
443                 nt_status = samdb_result_passwords_no_lockout(mem_ctx,
444                                         dce_call->conn->dce_ctx->lp_ctx,
445                                         msgs[0], &curNtHash);
446                 if (!NT_STATUS_IS_OK(nt_status)) {
447                         return NT_STATUS_ACCESS_DENIED;
448                 }
449         }
450
451         if (curNtHash == NULL) {
452                 return NT_STATUS_ACCESS_DENIED;
453         }
454
455         if (!challenge_valid) {
456                 DEBUG(1, ("No challenge requested by client [%s/%s], "
457                           "cannot authenticate\n",
458                           log_escape(mem_ctx, r->in.computer_name),
459                           log_escape(mem_ctx, r->in.account_name)));
460                 return NT_STATUS_ACCESS_DENIED;
461         }
462
463         creds = netlogon_creds_server_init(mem_ctx,
464                                            r->in.account_name,
465                                            r->in.computer_name,
466                                            r->in.secure_channel_type,
467                                            &challenge.client_challenge,
468                                            &challenge.server_challenge,
469                                            curNtHash,
470                                            r->in.credentials,
471                                            r->out.return_credentials,
472                                            negotiate_flags);
473         if (creds == NULL && prevNtHash != NULL) {
474                 /*
475                  * We fallback to the previous password for domain trusts.
476                  *
477                  * Note that lpcfg_old_password_allowed_period() doesn't
478                  * apply here.
479                  */
480                 creds = netlogon_creds_server_init(mem_ctx,
481                                                    r->in.account_name,
482                                                    r->in.computer_name,
483                                                    r->in.secure_channel_type,
484                                                    &challenge.client_challenge,
485                                                    &challenge.server_challenge,
486                                                    prevNtHash,
487                                                    r->in.credentials,
488                                                    r->out.return_credentials,
489                                                    negotiate_flags);
490         }
491
492         if (creds == NULL) {
493                 return NT_STATUS_ACCESS_DENIED;
494         }
495         creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
496         *sid = talloc_memdup(mem_ctx, creds->sid, sizeof(struct dom_sid));
497
498         nt_status = schannel_save_creds_state(mem_ctx,
499                                               dce_call->conn->dce_ctx->lp_ctx,
500                                               creds);
501         if (!NT_STATUS_IS_OK(nt_status)) {
502                 ZERO_STRUCTP(r->out.return_credentials);
503                 return nt_status;
504         }
505
506         *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
507                                                 "objectSid", 0);
508
509         return NT_STATUS_OK;
510 }
511
512 /*
513  * Log a netr_ServerAuthenticate3 request, and then invoke
514  * dcesrv_netr_ServerAuthenticate3_helper to perform the actual processing
515  */
516 static NTSTATUS dcesrv_netr_ServerAuthenticate3(
517         struct dcesrv_call_state *dce_call,
518         TALLOC_CTX *mem_ctx,
519         struct netr_ServerAuthenticate3 *r)
520 {
521         NTSTATUS status;
522         struct dom_sid *sid = NULL;
523         const char *trust_account_for_search = NULL;
524         const char *trust_account_in_db = NULL;
525         struct imessaging_context *imsg_ctx =
526                 dcesrv_imessaging_context(dce_call->conn);
527         struct auth_usersupplied_info ui = {
528                 .local_host = dce_call->conn->local_address,
529                 .remote_host = dce_call->conn->remote_address,
530                 .client = {
531                         .account_name = r->in.account_name,
532                         .domain_name = lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx),
533                 },
534                 .service_description = "NETLOGON",
535                 .auth_description = "ServerAuthenticate",
536                 .netlogon_trust_account = {
537                         .computer_name = r->in.computer_name,
538                         .negotiate_flags = *r->in.negotiate_flags,
539                         .secure_channel_type = r->in.secure_channel_type,
540                 },
541         };
542
543         status = dcesrv_netr_ServerAuthenticate3_helper(dce_call,
544                                                         mem_ctx,
545                                                         r,
546                                                         &trust_account_for_search,
547                                                         &trust_account_in_db,
548                                                         &sid);
549         ui.netlogon_trust_account.sid = sid;
550         ui.netlogon_trust_account.account_name = trust_account_in_db;
551         ui.mapped.account_name = trust_account_for_search;
552         log_authentication_event(
553                 imsg_ctx,
554                 dce_call->conn->dce_ctx->lp_ctx,
555                 NULL,
556                 &ui,
557                 status,
558                 lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx),
559                 trust_account_in_db,
560                 sid);
561
562         return status;
563 }
564 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
565                                         struct netr_ServerAuthenticate *r)
566 {
567         struct netr_ServerAuthenticate3 a;
568         uint32_t rid;
569         /* TODO:
570          * negotiate_flags is used as an [in] parameter
571          * so it need to be initialised.
572          *
573          * (I think ... = 0; seems wrong here --metze)
574          */
575         uint32_t negotiate_flags_in = 0;
576         uint32_t negotiate_flags_out = 0;
577
578         a.in.server_name                = r->in.server_name;
579         a.in.account_name               = r->in.account_name;
580         a.in.secure_channel_type        = r->in.secure_channel_type;
581         a.in.computer_name              = r->in.computer_name;
582         a.in.credentials                = r->in.credentials;
583         a.in.negotiate_flags            = &negotiate_flags_in;
584
585         a.out.return_credentials        = r->out.return_credentials;
586         a.out.rid                       = &rid;
587         a.out.negotiate_flags           = &negotiate_flags_out;
588
589         return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &a);
590 }
591
592 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
593                                          struct netr_ServerAuthenticate2 *r)
594 {
595         struct netr_ServerAuthenticate3 r3;
596         uint32_t rid = 0;
597
598         r3.in.server_name = r->in.server_name;
599         r3.in.account_name = r->in.account_name;
600         r3.in.secure_channel_type = r->in.secure_channel_type;
601         r3.in.computer_name = r->in.computer_name;
602         r3.in.credentials = r->in.credentials;
603         r3.out.return_credentials = r->out.return_credentials;
604         r3.in.negotiate_flags = r->in.negotiate_flags;
605         r3.out.negotiate_flags = r->out.negotiate_flags;
606         r3.out.rid = &rid;
607
608         return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
609 }
610
611 /*
612  * NOTE: The following functions are nearly identical to the ones available in
613  * source3/rpc_server/srv_nelog_nt.c
614  * The reason we keep 2 copies is that they use different structures to
615  * represent the auth_info and the decrpc pipes.
616  */
617 static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
618                                                     TALLOC_CTX *mem_ctx,
619                                                     const char *computer_name,
620                                                     struct netr_Authenticator *received_authenticator,
621                                                     struct netr_Authenticator *return_authenticator,
622                                                     struct netlogon_creds_CredentialState **creds_out)
623 {
624         NTSTATUS nt_status;
625         int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx);
626         bool schannel_global_required = (schannel == true);
627         bool schannel_required = schannel_global_required;
628         const char *explicit_opt = NULL;
629         struct netlogon_creds_CredentialState *creds = NULL;
630         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
631         uint16_t opnum = dce_call->pkt.u.request.opnum;
632         const char *opname = "<unknown>";
633         static bool warned_global_once = false;
634
635         if (opnum < ndr_table_netlogon.num_calls) {
636                 opname = ndr_table_netlogon.calls[opnum].name;
637         }
638
639         dcesrv_call_auth_info(dce_call, &auth_type, NULL);
640
641         nt_status = schannel_check_creds_state(mem_ctx,
642                                                dce_call->conn->dce_ctx->lp_ctx,
643                                                computer_name,
644                                                received_authenticator,
645                                                return_authenticator,
646                                                &creds);
647         if (!NT_STATUS_IS_OK(nt_status)) {
648                 ZERO_STRUCTP(return_authenticator);
649                 return nt_status;
650         }
651
652         /*
653          * We don't use lpcfg_parm_bool(), as we
654          * need the explicit_opt pointer in order to
655          * adjust the debug messages.
656          */
657         explicit_opt = lpcfg_get_parametric(dce_call->conn->dce_ctx->lp_ctx,
658                                             NULL,
659                                             "server require schannel",
660                                             creds->account_name);
661         if (explicit_opt != NULL) {
662                 schannel_required = lp_bool(explicit_opt);
663         }
664
665         if (schannel_required) {
666                 if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
667                         *creds_out = creds;
668                         return NT_STATUS_OK;
669                 }
670
671                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
672                         "%s request (opnum[%u]) without schannel from "
673                         "client_account[%s] client_computer_name[%s]\n",
674                         opname, opnum,
675                         log_escape(mem_ctx, creds->account_name),
676                         log_escape(mem_ctx, creds->computer_name));
677                 DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
678                         "'server require schannel:%s = no' is needed! \n",
679                         log_escape(mem_ctx, creds->account_name));
680                 TALLOC_FREE(creds);
681                 ZERO_STRUCTP(return_authenticator);
682                 return NT_STATUS_ACCESS_DENIED;
683         }
684
685         if (!schannel_global_required && !warned_global_once) {
686                 /*
687                  * We want admins to notice their misconfiguration!
688                  */
689                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
690                         "Please configure 'server schannel = yes', "
691                         "See https://bugzilla.samba.org/show_bug.cgi?id=14497\n");
692                 warned_global_once = true;
693         }
694
695         if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
696                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
697                         "%s request (opnum[%u]) WITH schannel from "
698                         "client_account[%s] client_computer_name[%s]\n",
699                         opname, opnum,
700                         log_escape(mem_ctx, creds->account_name),
701                         log_escape(mem_ctx, creds->computer_name));
702                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
703                         "Option 'server require schannel:%s = no' not needed!?\n",
704                         log_escape(mem_ctx, creds->account_name));
705
706                 *creds_out = creds;
707                 return NT_STATUS_OK;
708         }
709
710
711         if (explicit_opt != NULL) {
712                 DBG_INFO("CVE-2020-1472(ZeroLogon): "
713                          "%s request (opnum[%u]) without schannel from "
714                          "client_account[%s] client_computer_name[%s]\n",
715                          opname, opnum,
716                          log_escape(mem_ctx, creds->account_name),
717                          log_escape(mem_ctx, creds->computer_name));
718                 DBG_INFO("CVE-2020-1472(ZeroLogon): "
719                          "Option 'server require schannel:%s = no' still needed!\n",
720                          log_escape(mem_ctx, creds->account_name));
721         } else {
722                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
723                         "%s request (opnum[%u]) without schannel from "
724                         "client_account[%s] client_computer_name[%s]\n",
725                         opname, opnum,
726                         log_escape(mem_ctx, creds->account_name),
727                         log_escape(mem_ctx, creds->computer_name));
728                 DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
729                         "'server require schannel:%s = no' might be needed!\n",
730                         log_escape(mem_ctx, creds->account_name));
731         }
732
733         *creds_out = creds;
734         return NT_STATUS_OK;
735 }
736
737 /*
738   Change the machine account password for the currently connected
739   client.  Supplies only the NT#.
740 */
741
742 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
743                                        struct netr_ServerPasswordSet *r)
744 {
745         struct netlogon_creds_CredentialState *creds;
746         struct ldb_context *sam_ctx;
747         NTSTATUS nt_status;
748
749         nt_status = dcesrv_netr_creds_server_step_check(dce_call,
750                                                         mem_ctx,
751                                                         r->in.computer_name,
752                                                         r->in.credential, r->out.return_authenticator,
753                                                         &creds);
754         NT_STATUS_NOT_OK_RETURN(nt_status);
755
756         sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
757         if (sam_ctx == NULL) {
758                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
759         }
760
761         nt_status = netlogon_creds_des_decrypt(creds, r->in.new_password);
762         NT_STATUS_NOT_OK_RETURN(nt_status);
763
764         /* Using the sid for the account as the key, set the password */
765         nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
766                                            creds->sid,
767                                            NULL, /* Don't have version */
768                                            NULL, /* Don't have plaintext */
769                                            r->in.new_password,
770                                            DSDB_PASSWORD_CHECKED_AND_CORRECT, /* Password change */
771                                            NULL, NULL);
772         return nt_status;
773 }
774
775 /*
776   Change the machine account password for the currently connected
777   client.  Supplies new plaintext.
778 */
779 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
780                                        struct netr_ServerPasswordSet2 *r)
781 {
782         struct netlogon_creds_CredentialState *creds;
783         struct ldb_context *sam_ctx;
784         struct NL_PASSWORD_VERSION version = {};
785         const uint32_t *new_version = NULL;
786         NTSTATUS nt_status;
787         DATA_BLOB new_password = data_blob_null;
788         size_t confounder_len;
789         DATA_BLOB dec_blob = data_blob_null;
790         DATA_BLOB enc_blob = data_blob_null;
791         struct samr_CryptPassword password_buf;
792
793         nt_status = dcesrv_netr_creds_server_step_check(dce_call,
794                                                         mem_ctx,
795                                                         r->in.computer_name,
796                                                         r->in.credential, r->out.return_authenticator,
797                                                         &creds);
798         NT_STATUS_NOT_OK_RETURN(nt_status);
799
800         sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
801         if (sam_ctx == NULL) {
802                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
803         }
804
805         memcpy(password_buf.data, r->in.new_password->data, 512);
806         SIVAL(password_buf.data, 512, r->in.new_password->length);
807
808         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
809                 nt_status = netlogon_creds_aes_decrypt(creds,
810                                                        password_buf.data,
811                                                        516);
812         } else {
813                 nt_status = netlogon_creds_arcfour_crypt(creds,
814                                                          password_buf.data,
815                                                          516);
816         }
817
818         if (!NT_STATUS_IS_OK(nt_status)) {
819                 return nt_status;
820         }
821
822         switch (creds->secure_channel_type) {
823         case SEC_CHAN_DOMAIN:
824         case SEC_CHAN_DNS_DOMAIN: {
825                 uint32_t len = IVAL(password_buf.data, 512);
826                 if (len <= 500) {
827                         uint32_t ofs = 500 - len;
828                         uint8_t *p;
829
830                         p = password_buf.data + ofs;
831
832                         version.ReservedField = IVAL(p, 0);
833                         version.PasswordVersionNumber = IVAL(p, 4);
834                         version.PasswordVersionPresent = IVAL(p, 8);
835
836                         if (version.PasswordVersionPresent == NETLOGON_PASSWORD_VERSION_NUMBER_PRESENT) {
837                                 new_version = &version.PasswordVersionNumber;
838                         }
839                 }}
840                 break;
841         default:
842                 break;
843         }
844
845         if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
846                 DEBUG(3,("samr: failed to decode password buffer\n"));
847                 return NT_STATUS_WRONG_PASSWORD;
848         }
849
850         /*
851          * Make sure the length field was encrypted,
852          * otherwise we are under attack.
853          */
854         if (new_password.length == r->in.new_password->length) {
855                 DBG_WARNING("Length[%zu] field not encrypted\n",
856                             new_password.length);
857                 return NT_STATUS_WRONG_PASSWORD;
858         }
859
860         /*
861          * We don't allow empty passwords for machine accounts.
862          */
863         if (new_password.length < 2) {
864                 DBG_WARNING("Empty password Length[%zu]\n",
865                             new_password.length);
866                 return NT_STATUS_WRONG_PASSWORD;
867         }
868
869         /*
870          * Make sure the confounder part of CryptPassword
871          * buffer was encrypted, otherwise we are under attack.
872          */
873         confounder_len = 512 - new_password.length;
874         enc_blob = data_blob_const(r->in.new_password->data, confounder_len);
875         dec_blob = data_blob_const(password_buf.data, confounder_len);
876         if (confounder_len > 0 && data_blob_equal_const_time(&dec_blob, &enc_blob)) {
877                 DBG_WARNING("Confounder buffer not encrypted Length[%zu]\n",
878                             confounder_len);
879                 return NT_STATUS_WRONG_PASSWORD;
880         }
881
882         /*
883          * Check that the password part was actually encrypted,
884          * otherwise we are under attack.
885          */
886         enc_blob = data_blob_const(r->in.new_password->data + confounder_len,
887                                    new_password.length);
888         dec_blob = data_blob_const(password_buf.data + confounder_len,
889                                    new_password.length);
890         if (data_blob_equal_const_time(&dec_blob, &enc_blob)) {
891                 DBG_WARNING("Password buffer not encrypted Length[%zu]\n",
892                             new_password.length);
893                 return NT_STATUS_WRONG_PASSWORD;
894         }
895
896         /*
897          * don't allow zero buffers
898          */
899         if (all_zero(new_password.data, new_password.length)) {
900                 DBG_WARNING("Password zero buffer Length[%zu]\n",
901                             new_password.length);
902                 return NT_STATUS_WRONG_PASSWORD;
903         }
904
905         /* Using the sid for the account as the key, set the password */
906         nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
907                                            creds->sid,
908                                            new_version,
909                                            &new_password, /* we have plaintext */
910                                            NULL,
911                                            DSDB_PASSWORD_CHECKED_AND_CORRECT, /* Password change */
912                                            NULL, NULL);
913         return nt_status;
914 }
915
916
917 /*
918   netr_LogonUasLogon
919 */
920 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
921                                  struct netr_LogonUasLogon *r)
922 {
923         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
924 }
925
926
927 /*
928   netr_LogonUasLogoff
929 */
930 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
931                        struct netr_LogonUasLogoff *r)
932 {
933         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
934 }
935
936
937 static NTSTATUS dcesrv_netr_LogonSamLogon_check(struct dcesrv_call_state *dce_call,
938                                                 const struct netr_LogonSamLogonEx *r)
939 {
940         enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
941
942         switch (r->in.logon_level) {
943         case NetlogonInteractiveInformation:
944         case NetlogonServiceInformation:
945         case NetlogonInteractiveTransitiveInformation:
946         case NetlogonServiceTransitiveInformation:
947                 if (r->in.logon->password == NULL) {
948                         return NT_STATUS_INVALID_PARAMETER;
949                 }
950
951                 switch (r->in.validation_level) {
952                 case NetlogonValidationSamInfo:  /* 2 */
953                 case NetlogonValidationSamInfo2: /* 3 */
954                 case NetlogonValidationSamInfo4: /* 6 */
955                         break;
956                 default:
957                         return NT_STATUS_INVALID_INFO_CLASS;
958                 }
959
960                 break;
961         case NetlogonNetworkInformation:
962         case NetlogonNetworkTransitiveInformation:
963                 if (r->in.logon->network == NULL) {
964                         return NT_STATUS_INVALID_PARAMETER;
965                 }
966
967                 switch (r->in.validation_level) {
968                 case NetlogonValidationSamInfo:  /* 2 */
969                 case NetlogonValidationSamInfo2: /* 3 */
970                 case NetlogonValidationSamInfo4: /* 6 */
971                         break;
972                 default:
973                         return NT_STATUS_INVALID_INFO_CLASS;
974                 }
975
976                 break;
977
978         case NetlogonGenericInformation:
979                 if (r->in.logon->generic == NULL) {
980                         return NT_STATUS_INVALID_PARAMETER;
981                 }
982
983                 switch (r->in.validation_level) {
984                 /* TODO: case NetlogonValidationGenericInfo: 4 */
985                 case NetlogonValidationGenericInfo2: /* 5 */
986                         break;
987                 default:
988                         return NT_STATUS_INVALID_INFO_CLASS;
989                 }
990
991                 break;
992         default:
993                 return NT_STATUS_INVALID_PARAMETER;
994         }
995
996         dcesrv_call_auth_info(dce_call, NULL, &auth_level);
997
998         switch (r->in.validation_level) {
999         case NetlogonValidationSamInfo4: /* 6 */
1000                 if (auth_level < DCERPC_AUTH_LEVEL_PRIVACY) {
1001                         return NT_STATUS_INVALID_PARAMETER;
1002                 }
1003                 break;
1004
1005         default:
1006                 break;
1007         }
1008
1009         return NT_STATUS_OK;
1010 }
1011
1012 struct dcesrv_netr_LogonSamLogon_base_state {
1013         struct dcesrv_call_state *dce_call;
1014
1015         TALLOC_CTX *mem_ctx;
1016
1017         struct netlogon_creds_CredentialState *creds;
1018
1019         struct netr_LogonSamLogonEx r;
1020
1021         uint32_t _ignored_flags;
1022
1023         struct {
1024                 struct netr_LogonSamLogon *lsl;
1025                 struct netr_LogonSamLogonWithFlags *lslwf;
1026                 struct netr_LogonSamLogonEx *lslex;
1027         } _r;
1028
1029         struct kdc_check_generic_kerberos kr;
1030 };
1031
1032 static void dcesrv_netr_LogonSamLogon_base_auth_done(struct tevent_req *subreq);
1033 static void dcesrv_netr_LogonSamLogon_base_krb5_done(struct tevent_req *subreq);
1034 static void dcesrv_netr_LogonSamLogon_base_reply(
1035         struct dcesrv_netr_LogonSamLogon_base_state *state);
1036
1037 /*
1038   netr_LogonSamLogon_base
1039
1040   This version of the function allows other wrappers to say 'do not check the credentials'
1041
1042   We can't do the traditional 'wrapping' format completely, as this
1043   function must only run under schannel
1044 */
1045 static NTSTATUS dcesrv_netr_LogonSamLogon_base_call(struct dcesrv_netr_LogonSamLogon_base_state *state)
1046 {
1047         struct dcesrv_call_state *dce_call = state->dce_call;
1048         struct imessaging_context *imsg_ctx =
1049                 dcesrv_imessaging_context(dce_call->conn);
1050         TALLOC_CTX *mem_ctx = state->mem_ctx;
1051         struct netr_LogonSamLogonEx *r = &state->r;
1052         struct netlogon_creds_CredentialState *creds = state->creds;
1053         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
1054         const char *workgroup = lpcfg_workgroup(lp_ctx);
1055         struct auth4_context *auth_context = NULL;
1056         struct auth_usersupplied_info *user_info = NULL;
1057         NTSTATUS nt_status;
1058         struct tevent_req *subreq = NULL;
1059
1060         *r->out.authoritative = 1;
1061
1062         if (*r->in.flags & NETLOGON_SAMLOGON_FLAG_PASS_TO_FOREST_ROOT) {
1063                 /*
1064                  * Currently we're always the forest root ourself.
1065                  */
1066                 return NT_STATUS_NO_SUCH_USER;
1067         }
1068
1069         if (*r->in.flags & NETLOGON_SAMLOGON_FLAG_PASS_CROSS_FOREST_HOP) {
1070                 /*
1071                  * Currently we don't support trusts correctly yet.
1072                  */
1073                 return NT_STATUS_NO_SUCH_USER;
1074         }
1075
1076         user_info = talloc_zero(mem_ctx, struct auth_usersupplied_info);
1077         NT_STATUS_HAVE_NO_MEMORY(user_info);
1078
1079         user_info->service_description = "SamLogon";
1080
1081         nt_status = netlogon_creds_decrypt_samlogon_logon(creds,
1082                                                           r->in.logon_level,
1083                                                           r->in.logon);
1084         NT_STATUS_NOT_OK_RETURN(nt_status);
1085
1086         switch (r->in.logon_level) {
1087         case NetlogonInteractiveInformation:
1088         case NetlogonServiceInformation:
1089         case NetlogonInteractiveTransitiveInformation:
1090         case NetlogonServiceTransitiveInformation:
1091         case NetlogonNetworkInformation:
1092         case NetlogonNetworkTransitiveInformation:
1093
1094                 nt_status = auth_context_create_for_netlogon(mem_ctx,
1095                                         dce_call->event_ctx,
1096                                         imsg_ctx,
1097                                         dce_call->conn->dce_ctx->lp_ctx,
1098                                         &auth_context);
1099                 NT_STATUS_NOT_OK_RETURN(nt_status);
1100
1101                 user_info->remote_host = dce_call->conn->remote_address;
1102                 user_info->local_host = dce_call->conn->local_address;
1103
1104                 user_info->netlogon_trust_account.secure_channel_type
1105                         = creds->secure_channel_type;
1106                 user_info->netlogon_trust_account.negotiate_flags
1107                         = creds->negotiate_flags;
1108
1109                 /*
1110                  * These two can be unrelated when the account is
1111                  * actually that of a trusted domain, so we want to
1112                  * know which DC in that trusted domain contacted
1113                  * us
1114                  */
1115                 user_info->netlogon_trust_account.computer_name
1116                         = creds->computer_name;
1117                 user_info->netlogon_trust_account.account_name
1118                         = creds->account_name;
1119                 user_info->netlogon_trust_account.sid
1120                         = creds->sid;
1121
1122                 break;
1123         default:
1124                 /* We do not need to set up the user_info in this case */
1125                 break;
1126         }
1127
1128         switch (r->in.logon_level) {
1129         case NetlogonInteractiveInformation:
1130         case NetlogonServiceInformation:
1131         case NetlogonInteractiveTransitiveInformation:
1132         case NetlogonServiceTransitiveInformation:
1133                 user_info->auth_description = "interactive";
1134
1135                 user_info->logon_parameters
1136                         = r->in.logon->password->identity_info.parameter_control;
1137                 user_info->client.account_name
1138                         = r->in.logon->password->identity_info.account_name.string;
1139                 user_info->client.domain_name
1140                         = r->in.logon->password->identity_info.domain_name.string;
1141                 user_info->workstation_name
1142                         = r->in.logon->password->identity_info.workstation.string;
1143                 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
1144                 user_info->password_state = AUTH_PASSWORD_HASH;
1145
1146                 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
1147                 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
1148                 *user_info->password.hash.lanman = r->in.logon->password->lmpassword;
1149
1150                 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
1151                 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
1152                 *user_info->password.hash.nt = r->in.logon->password->ntpassword;
1153
1154                 user_info->logon_id
1155                     = r->in.logon->password->identity_info.logon_id;
1156
1157                 break;
1158         case NetlogonNetworkInformation:
1159         case NetlogonNetworkTransitiveInformation:
1160                 user_info->auth_description = "network";
1161
1162                 nt_status = auth_context_set_challenge(
1163                         auth_context,
1164                         r->in.logon->network->challenge,
1165                         "netr_LogonSamLogonWithFlags");
1166                 NT_STATUS_NOT_OK_RETURN(nt_status);
1167
1168                 user_info->logon_parameters
1169                         = r->in.logon->network->identity_info.parameter_control;
1170                 user_info->client.account_name
1171                         = r->in.logon->network->identity_info.account_name.string;
1172                 user_info->client.domain_name
1173                         = r->in.logon->network->identity_info.domain_name.string;
1174                 user_info->workstation_name
1175                         = r->in.logon->network->identity_info.workstation.string;
1176
1177                 user_info->password_state = AUTH_PASSWORD_RESPONSE;
1178                 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length);
1179                 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length);
1180
1181                 user_info->logon_id
1182                     = r->in.logon->network->identity_info.logon_id;
1183
1184                 nt_status = NTLMv2_RESPONSE_verify_netlogon_creds(
1185                                         user_info->client.account_name,
1186                                         user_info->client.domain_name,
1187                                         user_info->password.response.nt,
1188                                         creds, workgroup);
1189                 NT_STATUS_NOT_OK_RETURN(nt_status);
1190
1191                 break;
1192
1193
1194         case NetlogonGenericInformation:
1195         {
1196                 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1197                         /* OK */
1198                 } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
1199                         /* OK */
1200                 } else {
1201                         /* Using DES to verify kerberos tickets makes no sense */
1202                         return NT_STATUS_INVALID_PARAMETER;
1203                 }
1204
1205                 if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) {
1206                         struct dcerpc_binding_handle *irpc_handle;
1207                         struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
1208                         NT_STATUS_HAVE_NO_MEMORY(generic);
1209
1210                         r->out.validation->generic = generic;
1211
1212                         user_info->logon_id
1213                             = r->in.logon->generic->identity_info.logon_id;
1214
1215                         irpc_handle = irpc_binding_handle_by_name(mem_ctx,
1216                                                                   imsg_ctx,
1217                                                                   "kdc_server",
1218                                                                   &ndr_table_irpc);
1219                         if (irpc_handle == NULL) {
1220                                 return NT_STATUS_NO_LOGON_SERVERS;
1221                         }
1222
1223                         state->kr.in.generic_request =
1224                                 data_blob_const(r->in.logon->generic->data,
1225                                                 r->in.logon->generic->length);
1226
1227                         /*
1228                          * 60 seconds should be enough
1229                          */
1230                         dcerpc_binding_handle_set_timeout(irpc_handle, 60);
1231                         subreq = dcerpc_kdc_check_generic_kerberos_r_send(state,
1232                                                 state->dce_call->event_ctx,
1233                                                 irpc_handle, &state->kr);
1234                         if (subreq == NULL) {
1235                                 return NT_STATUS_NO_MEMORY;
1236                         }
1237                         state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
1238                         tevent_req_set_callback(subreq,
1239                                         dcesrv_netr_LogonSamLogon_base_krb5_done,
1240                                         state);
1241                         return NT_STATUS_OK;
1242                 }
1243
1244                 /* Until we get an implemetnation of these other packages */
1245                 return NT_STATUS_INVALID_PARAMETER;
1246         }
1247         default:
1248                 return NT_STATUS_INVALID_PARAMETER;
1249         }
1250
1251         subreq = auth_check_password_send(state, state->dce_call->event_ctx,
1252                                           auth_context, user_info);
1253         state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
1254         tevent_req_set_callback(subreq,
1255                                 dcesrv_netr_LogonSamLogon_base_auth_done,
1256                                 state);
1257         return NT_STATUS_OK;
1258 }
1259
1260 static void dcesrv_netr_LogonSamLogon_base_auth_done(struct tevent_req *subreq)
1261 {
1262         struct dcesrv_netr_LogonSamLogon_base_state *state =
1263                 tevent_req_callback_data(subreq,
1264                 struct dcesrv_netr_LogonSamLogon_base_state);
1265         TALLOC_CTX *mem_ctx = state->mem_ctx;
1266         struct netr_LogonSamLogonEx *r = &state->r;
1267         struct auth_user_info_dc *user_info_dc = NULL;
1268         struct netr_SamInfo2 *sam2 = NULL;
1269         struct netr_SamInfo3 *sam3 = NULL;
1270         struct netr_SamInfo6 *sam6 = NULL;
1271         NTSTATUS nt_status;
1272
1273         nt_status = auth_check_password_recv(subreq, mem_ctx,
1274                                              &user_info_dc,
1275                                              r->out.authoritative);
1276         TALLOC_FREE(subreq);
1277         if (!NT_STATUS_IS_OK(nt_status)) {
1278                 r->out.result = nt_status;
1279                 dcesrv_netr_LogonSamLogon_base_reply(state);
1280                 return;
1281         }
1282
1283         switch (r->in.validation_level) {
1284         case 2:
1285                 nt_status = auth_convert_user_info_dc_saminfo2(mem_ctx,
1286                                                                user_info_dc,
1287                                                                &sam2);
1288                 if (!NT_STATUS_IS_OK(nt_status)) {
1289                         r->out.result = nt_status;
1290                         dcesrv_netr_LogonSamLogon_base_reply(state);
1291                         return;
1292                 }
1293
1294                 r->out.validation->sam2 = sam2;
1295                 break;
1296
1297         case 3:
1298                 nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx,
1299                                                                user_info_dc,
1300                                                                &sam3);
1301                 if (!NT_STATUS_IS_OK(nt_status)) {
1302                         r->out.result = nt_status;
1303                         dcesrv_netr_LogonSamLogon_base_reply(state);
1304                         return;
1305                 }
1306
1307                 r->out.validation->sam3 = sam3;
1308                 break;
1309
1310         case 6:
1311                 nt_status = auth_convert_user_info_dc_saminfo6(mem_ctx,
1312                                                                user_info_dc,
1313                                                                &sam6);
1314                 if (!NT_STATUS_IS_OK(nt_status)) {
1315                         r->out.result = nt_status;
1316                         dcesrv_netr_LogonSamLogon_base_reply(state);
1317                         return;
1318                 }
1319
1320                 r->out.validation->sam6 = sam6;
1321                 break;
1322
1323         default:
1324                 if (!NT_STATUS_IS_OK(nt_status)) {
1325                         r->out.result = NT_STATUS_INVALID_INFO_CLASS;
1326                         dcesrv_netr_LogonSamLogon_base_reply(state);
1327                         return;
1328                 }
1329         }
1330
1331         /* TODO: Describe and deal with these flags */
1332         *r->out.flags = 0;
1333
1334         r->out.result = NT_STATUS_OK;
1335
1336         dcesrv_netr_LogonSamLogon_base_reply(state);
1337 }
1338
1339 static void dcesrv_netr_LogonSamLogon_base_krb5_done(struct tevent_req *subreq)
1340 {
1341         struct dcesrv_netr_LogonSamLogon_base_state *state =
1342                 tevent_req_callback_data(subreq,
1343                 struct dcesrv_netr_LogonSamLogon_base_state);
1344         TALLOC_CTX *mem_ctx = state->mem_ctx;
1345         struct netr_LogonSamLogonEx *r = &state->r;
1346         struct netr_GenericInfo2 *generic = NULL;
1347         NTSTATUS status;
1348
1349         status = dcerpc_kdc_check_generic_kerberos_r_recv(subreq, mem_ctx);
1350         TALLOC_FREE(subreq);
1351         if (!NT_STATUS_IS_OK(status)) {
1352                 r->out.result = status;
1353                 dcesrv_netr_LogonSamLogon_base_reply(state);
1354                 return;
1355         }
1356
1357         generic = r->out.validation->generic;
1358         generic->length = state->kr.out.generic_reply.length;
1359         generic->data = state->kr.out.generic_reply.data;
1360
1361         /* TODO: Describe and deal with these flags */
1362         *r->out.flags = 0;
1363
1364         r->out.result = NT_STATUS_OK;
1365
1366         dcesrv_netr_LogonSamLogon_base_reply(state);
1367 }
1368
1369 static void dcesrv_netr_LogonSamLogon_base_reply(
1370         struct dcesrv_netr_LogonSamLogon_base_state *state)
1371 {
1372         struct netr_LogonSamLogonEx *r = &state->r;
1373         NTSTATUS status;
1374
1375         if (NT_STATUS_IS_OK(r->out.result)) {
1376                 status = netlogon_creds_encrypt_samlogon_validation(state->creds,
1377                                                                     r->in.validation_level,
1378                                                                     r->out.validation);
1379                 if (!NT_STATUS_IS_OK(status)) {
1380                         DBG_ERR("netlogon_creds_encrypt_samlogon_validation() "
1381                                 "failed - %s\n",
1382                                 nt_errstr(status));
1383                 }
1384         }
1385
1386         if (state->_r.lslex != NULL) {
1387                 struct netr_LogonSamLogonEx *_r = state->_r.lslex;
1388                 _r->out.result = r->out.result;
1389         } else if (state->_r.lslwf != NULL) {
1390                 struct netr_LogonSamLogonWithFlags *_r = state->_r.lslwf;
1391                 _r->out.result = r->out.result;
1392         } else if (state->_r.lsl != NULL) {
1393                 struct netr_LogonSamLogon *_r = state->_r.lsl;
1394                 _r->out.result = r->out.result;
1395         }
1396
1397         status = dcesrv_reply(state->dce_call);
1398         if (!NT_STATUS_IS_OK(status)) {
1399                 DBG_ERR("dcesrv_reply() failed - %s\n",
1400                         nt_errstr(status));
1401         }
1402 }
1403
1404 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1405                                      struct netr_LogonSamLogonEx *r)
1406 {
1407         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1408         struct dcesrv_netr_LogonSamLogon_base_state *state;
1409         NTSTATUS nt_status;
1410
1411         *r->out.authoritative = 1;
1412
1413         state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonSamLogon_base_state);
1414         if (state == NULL) {
1415                 return NT_STATUS_NO_MEMORY;
1416         }
1417
1418         state->dce_call = dce_call;
1419         state->mem_ctx = mem_ctx;
1420
1421         state->r.in.server_name      = r->in.server_name;
1422         state->r.in.computer_name    = r->in.computer_name;
1423         state->r.in.logon_level      = r->in.logon_level;
1424         state->r.in.logon            = r->in.logon;
1425         state->r.in.validation_level = r->in.validation_level;
1426         state->r.in.flags            = r->in.flags;
1427         state->r.out.validation      = r->out.validation;
1428         state->r.out.authoritative   = r->out.authoritative;
1429         state->r.out.flags           = r->out.flags;
1430
1431         state->_r.lslex = r;
1432
1433         nt_status = dcesrv_netr_LogonSamLogon_check(dce_call, &state->r);
1434         if (!NT_STATUS_IS_OK(nt_status)) {
1435                 return nt_status;
1436         }
1437
1438         nt_status = schannel_get_creds_state(mem_ctx,
1439                                              dce_call->conn->dce_ctx->lp_ctx,
1440                                              r->in.computer_name, &state->creds);
1441         if (!NT_STATUS_IS_OK(nt_status)) {
1442                 return nt_status;
1443         }
1444
1445         dcesrv_call_auth_info(dce_call, &auth_type, NULL);
1446
1447         if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1448                 return NT_STATUS_ACCESS_DENIED;
1449         }
1450
1451         nt_status = dcesrv_netr_LogonSamLogon_base_call(state);
1452
1453         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1454                 return nt_status;
1455         }
1456
1457         return nt_status;
1458 }
1459
1460 /*
1461   netr_LogonSamLogonWithFlags
1462
1463 */
1464 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1465                                             struct netr_LogonSamLogonWithFlags *r)
1466 {
1467         struct dcesrv_netr_LogonSamLogon_base_state *state;
1468         NTSTATUS nt_status;
1469
1470         *r->out.authoritative = 1;
1471
1472         state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonSamLogon_base_state);
1473         if (state == NULL) {
1474                 return NT_STATUS_NO_MEMORY;
1475         }
1476
1477         state->dce_call = dce_call;
1478         state->mem_ctx = mem_ctx;
1479
1480         state->r.in.server_name      = r->in.server_name;
1481         state->r.in.computer_name    = r->in.computer_name;
1482         state->r.in.logon_level      = r->in.logon_level;
1483         state->r.in.logon            = r->in.logon;
1484         state->r.in.validation_level = r->in.validation_level;
1485         state->r.in.flags            = r->in.flags;
1486         state->r.out.validation      = r->out.validation;
1487         state->r.out.authoritative   = r->out.authoritative;
1488         state->r.out.flags           = r->out.flags;
1489
1490         state->_r.lslwf = r;
1491
1492         nt_status = dcesrv_netr_LogonSamLogon_check(dce_call, &state->r);
1493         if (!NT_STATUS_IS_OK(nt_status)) {
1494                 return nt_status;
1495         }
1496
1497         r->out.return_authenticator = talloc_zero(mem_ctx,
1498                                                   struct netr_Authenticator);
1499         if (r->out.return_authenticator == NULL) {
1500                 return NT_STATUS_NO_MEMORY;
1501         }
1502
1503         nt_status = dcesrv_netr_creds_server_step_check(dce_call,
1504                                                         mem_ctx,
1505                                                         r->in.computer_name,
1506                                                         r->in.credential,
1507                                                         r->out.return_authenticator,
1508                                                         &state->creds);
1509         if (!NT_STATUS_IS_OK(nt_status)) {
1510                 return nt_status;
1511         }
1512
1513         nt_status = dcesrv_netr_LogonSamLogon_base_call(state);
1514
1515         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1516                 return nt_status;
1517         }
1518
1519         return nt_status;
1520 }
1521
1522 /*
1523   netr_LogonSamLogon
1524 */
1525 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1526                                    struct netr_LogonSamLogon *r)
1527 {
1528         struct dcesrv_netr_LogonSamLogon_base_state *state;
1529         NTSTATUS nt_status;
1530
1531         *r->out.authoritative = 1;
1532
1533         state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonSamLogon_base_state);
1534         if (state == NULL) {
1535                 return NT_STATUS_NO_MEMORY;
1536         }
1537
1538         state->dce_call = dce_call;
1539         state->mem_ctx = mem_ctx;
1540
1541         state->r.in.server_name      = r->in.server_name;
1542         state->r.in.computer_name    = r->in.computer_name;
1543         state->r.in.logon_level      = r->in.logon_level;
1544         state->r.in.logon            = r->in.logon;
1545         state->r.in.validation_level = r->in.validation_level;
1546         state->r.in.flags            = &state->_ignored_flags;
1547         state->r.out.validation      = r->out.validation;
1548         state->r.out.authoritative   = r->out.authoritative;
1549         state->r.out.flags           = &state->_ignored_flags;
1550
1551         state->_r.lsl = r;
1552
1553         nt_status = dcesrv_netr_LogonSamLogon_check(dce_call, &state->r);
1554         if (!NT_STATUS_IS_OK(nt_status)) {
1555                 return nt_status;
1556         }
1557
1558         r->out.return_authenticator = talloc_zero(mem_ctx,
1559                                                   struct netr_Authenticator);
1560         if (r->out.return_authenticator == NULL) {
1561                 return NT_STATUS_NO_MEMORY;
1562         }
1563
1564         nt_status = dcesrv_netr_creds_server_step_check(dce_call,
1565                                                         mem_ctx,
1566                                                         r->in.computer_name,
1567                                                         r->in.credential,
1568                                                         r->out.return_authenticator,
1569                                                         &state->creds);
1570         if (!NT_STATUS_IS_OK(nt_status)) {
1571                 return nt_status;
1572         }
1573
1574         nt_status = dcesrv_netr_LogonSamLogon_base_call(state);
1575
1576         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1577                 return nt_status;
1578         }
1579
1580         return nt_status;
1581 }
1582
1583
1584 /*
1585   netr_LogonSamLogoff
1586 */
1587 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1588                        struct netr_LogonSamLogoff *r)
1589 {
1590         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1591 }
1592
1593
1594
1595 /*
1596   netr_DatabaseDeltas
1597 */
1598 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1599                        struct netr_DatabaseDeltas *r)
1600 {
1601         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1602 }
1603
1604
1605 /*
1606   netr_DatabaseSync2
1607 */
1608 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1609                        struct netr_DatabaseSync2 *r)
1610 {
1611         /* win2k3 native mode returns  "NOT IMPLEMENTED" for this call */
1612         return NT_STATUS_NOT_IMPLEMENTED;
1613 }
1614
1615
1616 /*
1617   netr_DatabaseSync
1618 */
1619 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1620                        struct netr_DatabaseSync *r)
1621 {
1622         struct netr_DatabaseSync2 r2;
1623         NTSTATUS status;
1624
1625         ZERO_STRUCT(r2);
1626
1627         r2.in.logon_server = r->in.logon_server;
1628         r2.in.computername = r->in.computername;
1629         r2.in.credential = r->in.credential;
1630         r2.in.database_id = r->in.database_id;
1631         r2.in.restart_state = SYNCSTATE_NORMAL_STATE;
1632         r2.in.sync_context = r->in.sync_context;
1633         r2.out.sync_context = r->out.sync_context;
1634         r2.out.delta_enum_array = r->out.delta_enum_array;
1635         r2.in.preferredmaximumlength = r->in.preferredmaximumlength;
1636
1637         status = dcesrv_netr_DatabaseSync2(dce_call, mem_ctx, &r2);
1638
1639         return status;
1640 }
1641
1642
1643 /*
1644   netr_AccountDeltas
1645 */
1646 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1647                        struct netr_AccountDeltas *r)
1648 {
1649         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1650         return NT_STATUS_NOT_IMPLEMENTED;
1651 }
1652
1653
1654 /*
1655   netr_AccountSync
1656 */
1657 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1658                        struct netr_AccountSync *r)
1659 {
1660         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1661         return NT_STATUS_NOT_IMPLEMENTED;
1662 }
1663
1664
1665 /*
1666   netr_GetDcName
1667 */
1668 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1669                        struct netr_GetDcName *r)
1670 {
1671         const char * const attrs[] = { NULL };
1672         struct ldb_context *sam_ctx;
1673         struct ldb_message **res;
1674         struct ldb_dn *domain_dn;
1675         int ret;
1676         const char *dcname;
1677
1678         /*
1679          * [MS-NRPC] 3.5.5.3.4 NetrGetDCName says
1680          * that the domainname needs to be a valid netbios domain
1681          * name, if it is not NULL.
1682          */
1683         if (r->in.domainname) {
1684                 const char *dot = strchr(r->in.domainname, '.');
1685                 size_t len = strlen(r->in.domainname);
1686
1687                 if (dot || len > 15) {
1688                         return WERR_NERR_DCNOTFOUND;
1689                 }
1690
1691                 /*
1692                  * TODO: Should we also varify that only valid
1693                  *       netbios name characters are used?
1694                  */
1695         }
1696
1697         sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
1698         if (sam_ctx == NULL) {
1699                 return WERR_DS_UNAVAILABLE;
1700         }
1701
1702         domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx,
1703                                        r->in.domainname);
1704         if (domain_dn == NULL) {
1705                 return WERR_NO_SUCH_DOMAIN;
1706         }
1707
1708         ret = gendb_search_dn(sam_ctx, mem_ctx,
1709                               domain_dn, &res, attrs);
1710         if (ret != 1) {
1711                 return WERR_NO_SUCH_DOMAIN;
1712         }
1713
1714         /* TODO: - return real IP address
1715          *       - check all r->in.* parameters (server_unc is ignored by w2k3!)
1716          */
1717         dcname = talloc_asprintf(mem_ctx, "\\\\%s",
1718                                  lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
1719         W_ERROR_HAVE_NO_MEMORY(dcname);
1720
1721         *r->out.dcname = dcname;
1722         return WERR_OK;
1723 }
1724
1725 struct dcesrv_netr_LogonControl_base_state {
1726         struct dcesrv_call_state *dce_call;
1727
1728         TALLOC_CTX *mem_ctx;
1729
1730         struct netr_LogonControl2Ex r;
1731
1732         struct {
1733                 struct netr_LogonControl *l;
1734                 struct netr_LogonControl2 *l2;
1735                 struct netr_LogonControl2Ex *l2ex;
1736         } _r;
1737 };
1738
1739 static void dcesrv_netr_LogonControl_base_done(struct tevent_req *subreq);
1740
1741 static WERROR dcesrv_netr_LogonControl_base_call(struct dcesrv_netr_LogonControl_base_state *state)
1742 {
1743         struct loadparm_context *lp_ctx = state->dce_call->conn->dce_ctx->lp_ctx;
1744         struct auth_session_info *session_info =
1745                 dcesrv_call_session_info(state->dce_call);
1746         struct imessaging_context *imsg_ctx =
1747                 dcesrv_imessaging_context(state->dce_call->conn);
1748         enum security_user_level security_level;
1749         struct dcerpc_binding_handle *irpc_handle;
1750         struct tevent_req *subreq;
1751         bool ok;
1752
1753         /* TODO: check for WERR_INVALID_COMPUTERNAME ? */
1754
1755         if (state->_r.l != NULL) {
1756                 /*
1757                  * netr_LogonControl
1758                  */
1759                 if (state->r.in.level == 0x00000002) {
1760                         return WERR_NOT_SUPPORTED;
1761                 } else if (state->r.in.level != 0x00000001) {
1762                         return WERR_INVALID_LEVEL;
1763                 }
1764
1765                 switch (state->r.in.function_code) {
1766                 case NETLOGON_CONTROL_QUERY:
1767                 case NETLOGON_CONTROL_REPLICATE:
1768                 case NETLOGON_CONTROL_SYNCHRONIZE:
1769                 case NETLOGON_CONTROL_PDC_REPLICATE:
1770                 case NETLOGON_CONTROL_BREAKPOINT:
1771                 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1772                 case NETLOGON_CONTROL_TRUNCATE_LOG:
1773                         break;
1774                 default:
1775                         return WERR_NOT_SUPPORTED;
1776                 }
1777         }
1778
1779         if (state->r.in.level < 0x00000001) {
1780                 return WERR_INVALID_LEVEL;
1781         }
1782
1783         if (state->r.in.level > 0x00000004) {
1784                 return WERR_INVALID_LEVEL;
1785         }
1786
1787         if (state->r.in.function_code == NETLOGON_CONTROL_QUERY) {
1788                 struct netr_NETLOGON_INFO_1 *info1 = NULL;
1789                 struct netr_NETLOGON_INFO_3 *info3 = NULL;
1790
1791                 switch (state->r.in.level) {
1792                 case 0x00000001:
1793                         info1 = talloc_zero(state->mem_ctx,
1794                                             struct netr_NETLOGON_INFO_1);
1795                         if (info1 == NULL) {
1796                                 return WERR_NOT_ENOUGH_MEMORY;
1797                         }
1798                         state->r.out.query->info1 = info1;
1799                         return WERR_OK;
1800
1801                 case 0x00000003:
1802                         info3 = talloc_zero(state->mem_ctx,
1803                                             struct netr_NETLOGON_INFO_3);
1804                         if (info3 == NULL) {
1805                                 return WERR_NOT_ENOUGH_MEMORY;
1806                         }
1807                         state->r.out.query->info3 = info3;
1808                         return WERR_OK;
1809
1810                 default:
1811                         return WERR_INVALID_PARAMETER;
1812                 }
1813         }
1814
1815         /*
1816          * Some validations are done before the access check
1817          * and some after the access check
1818          */
1819         security_level = security_session_user_level(session_info, NULL);
1820         if (security_level < SECURITY_ADMINISTRATOR) {
1821                 return WERR_ACCESS_DENIED;
1822         }
1823
1824         if (state->_r.l2 != NULL) {
1825                 /*
1826                  * netr_LogonControl2
1827                  */
1828                 if (state->r.in.level == 0x00000004) {
1829                         return WERR_INVALID_LEVEL;
1830                 }
1831         }
1832
1833         switch (state->r.in.level) {
1834         case 0x00000001:
1835                 break;
1836
1837         case 0x00000002:
1838                 switch (state->r.in.function_code) {
1839                 case NETLOGON_CONTROL_REDISCOVER:
1840                 case NETLOGON_CONTROL_TC_QUERY:
1841                 case NETLOGON_CONTROL_TC_VERIFY:
1842                         break;
1843                 default:
1844                         return WERR_INVALID_PARAMETER;
1845                 }
1846
1847                 break;
1848
1849         case 0x00000003:
1850                 break;
1851
1852         case 0x00000004:
1853                 if (state->r.in.function_code != NETLOGON_CONTROL_FIND_USER) {
1854                         return WERR_INVALID_PARAMETER;
1855                 }
1856
1857                 break;
1858
1859         default:
1860                 return WERR_INVALID_LEVEL;
1861         }
1862
1863         switch (state->r.in.function_code) {
1864         case NETLOGON_CONTROL_REDISCOVER:
1865         case NETLOGON_CONTROL_TC_QUERY:
1866         case NETLOGON_CONTROL_TC_VERIFY:
1867                 if (state->r.in.level != 2) {
1868                         return WERR_INVALID_PARAMETER;
1869                 }
1870
1871                 if (state->r.in.data == NULL) {
1872                         return WERR_INVALID_PARAMETER;
1873                 }
1874
1875                 if (state->r.in.data->domain == NULL) {
1876                         return WERR_INVALID_PARAMETER;
1877                 }
1878
1879                 break;
1880
1881         case NETLOGON_CONTROL_CHANGE_PASSWORD:
1882                 if (state->r.in.level != 1) {
1883                         return WERR_INVALID_PARAMETER;
1884                 }
1885
1886                 if (state->r.in.data == NULL) {
1887                         return WERR_INVALID_PARAMETER;
1888                 }
1889
1890                 if (state->r.in.data->domain == NULL) {
1891                         return WERR_INVALID_PARAMETER;
1892                 }
1893
1894                 ok = lpcfg_is_my_domain_or_realm(lp_ctx,
1895                                                  state->r.in.data->domain);
1896                 if (!ok) {
1897                         struct ldb_context *sam_ctx;
1898
1899                         sam_ctx = dcesrv_samdb_connect_as_system(state,
1900                                                                  state->dce_call);
1901                         if (sam_ctx == NULL) {
1902                                 return WERR_DS_UNAVAILABLE;
1903                         }
1904
1905                         /*
1906                          * Secrets for trusted domains can only be triggered on
1907                          * the PDC.
1908                          */
1909                         ok = samdb_is_pdc(sam_ctx);
1910                         TALLOC_FREE(sam_ctx);
1911                         if (!ok) {
1912                                 return WERR_INVALID_DOMAIN_ROLE;
1913                         }
1914                 }
1915
1916                 break;
1917         default:
1918                 return WERR_NOT_SUPPORTED;
1919         }
1920
1921         irpc_handle = irpc_binding_handle_by_name(state,
1922                                                   imsg_ctx,
1923                                                   "winbind_server",
1924                                                   &ndr_table_winbind);
1925         if (irpc_handle == NULL) {
1926                 DEBUG(0,("Failed to get binding_handle for winbind_server task\n"));
1927                 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
1928                 return WERR_SERVICE_NOT_FOUND;
1929         }
1930
1931         /*
1932          * 60 seconds timeout should be enough
1933          */
1934         dcerpc_binding_handle_set_timeout(irpc_handle, 60);
1935
1936         subreq = dcerpc_winbind_LogonControl_send(state,
1937                                                   state->dce_call->event_ctx,
1938                                                   irpc_handle,
1939                                                   state->r.in.function_code,
1940                                                   state->r.in.level,
1941                                                   state->r.in.data,
1942                                                   state->r.out.query);
1943         if (subreq == NULL) {
1944                 return WERR_NOT_ENOUGH_MEMORY;
1945         }
1946         state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
1947         tevent_req_set_callback(subreq,
1948                                 dcesrv_netr_LogonControl_base_done,
1949                                 state);
1950
1951         return WERR_OK;
1952 }
1953
1954 static void dcesrv_netr_LogonControl_base_done(struct tevent_req *subreq)
1955 {
1956         struct dcesrv_netr_LogonControl_base_state *state =
1957                 tevent_req_callback_data(subreq,
1958                 struct dcesrv_netr_LogonControl_base_state);
1959         NTSTATUS status;
1960
1961         status = dcerpc_winbind_LogonControl_recv(subreq, state->mem_ctx,
1962                                                   &state->r.out.result);
1963         TALLOC_FREE(subreq);
1964         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1965                 state->r.out.result = WERR_TIMEOUT;
1966         } else if (!NT_STATUS_IS_OK(status)) {
1967                 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
1968                 DEBUG(0,(__location__ ": IRPC callback failed %s\n",
1969                          nt_errstr(status)));
1970         }
1971
1972         if (state->_r.l2ex != NULL) {
1973                 struct netr_LogonControl2Ex *r = state->_r.l2ex;
1974                 r->out.result = state->r.out.result;
1975         } else if (state->_r.l2 != NULL) {
1976                 struct netr_LogonControl2 *r = state->_r.l2;
1977                 r->out.result = state->r.out.result;
1978         } else if (state->_r.l != NULL) {
1979                 struct netr_LogonControl *r = state->_r.l;
1980                 r->out.result = state->r.out.result;
1981         }
1982
1983         status = dcesrv_reply(state->dce_call);
1984         if (!NT_STATUS_IS_OK(status)) {
1985                 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status)));
1986         }
1987 }
1988
1989 /*
1990   netr_LogonControl
1991 */
1992 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1993                        struct netr_LogonControl *r)
1994 {
1995         struct dcesrv_netr_LogonControl_base_state *state;
1996         WERROR werr;
1997
1998         state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonControl_base_state);
1999         if (state == NULL) {
2000                 return WERR_NOT_ENOUGH_MEMORY;
2001         }
2002
2003         state->dce_call = dce_call;
2004         state->mem_ctx = mem_ctx;
2005
2006         state->r.in.logon_server = r->in.logon_server;
2007         state->r.in.function_code = r->in.function_code;
2008         state->r.in.level = r->in.level;
2009         state->r.in.data = NULL;
2010         state->r.out.query = r->out.query;
2011
2012         state->_r.l = r;
2013
2014         werr = dcesrv_netr_LogonControl_base_call(state);
2015
2016         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
2017                 return werr;
2018         }
2019
2020         return werr;
2021 }
2022
2023 /*
2024   netr_LogonControl2
2025 */
2026 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2027                        struct netr_LogonControl2 *r)
2028 {
2029         struct dcesrv_netr_LogonControl_base_state *state;
2030         WERROR werr;
2031
2032         state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonControl_base_state);
2033         if (state == NULL) {
2034                 return WERR_NOT_ENOUGH_MEMORY;
2035         }
2036
2037         state->dce_call = dce_call;
2038         state->mem_ctx = mem_ctx;
2039
2040         state->r.in.logon_server = r->in.logon_server;
2041         state->r.in.function_code = r->in.function_code;
2042         state->r.in.level = r->in.level;
2043         state->r.in.data = r->in.data;
2044         state->r.out.query = r->out.query;
2045
2046         state->_r.l2 = r;
2047
2048         werr = dcesrv_netr_LogonControl_base_call(state);
2049
2050         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
2051                 return werr;
2052         }
2053
2054         return werr;
2055 }
2056
2057 /*
2058   netr_LogonControl2Ex
2059 */
2060 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2061                        struct netr_LogonControl2Ex *r)
2062 {
2063         struct dcesrv_netr_LogonControl_base_state *state;
2064         WERROR werr;
2065
2066         state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonControl_base_state);
2067         if (state == NULL) {
2068                 return WERR_NOT_ENOUGH_MEMORY;
2069         }
2070
2071         state->dce_call = dce_call;
2072         state->mem_ctx = mem_ctx;
2073
2074         state->r = *r;
2075         state->_r.l2ex = r;
2076
2077         werr = dcesrv_netr_LogonControl_base_call(state);
2078
2079         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
2080                 return werr;
2081         }
2082
2083         return werr;
2084 }
2085
2086 static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
2087                                          struct ldb_context *sam_ctx,
2088                                          struct netr_DomainTrustList *trusts,
2089                                          uint32_t trust_flags);
2090
2091 /*
2092   netr_GetAnyDCName
2093 */
2094 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2095                        struct netr_GetAnyDCName *r)
2096 {
2097         struct netr_DomainTrustList *trusts;
2098         struct ldb_context *sam_ctx;
2099         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
2100         uint32_t i;
2101         WERROR werr;
2102
2103         *r->out.dcname = NULL;
2104
2105         if ((r->in.domainname == NULL) || (r->in.domainname[0] == '\0')) {
2106                 /* if the domainname parameter wasn't set assume our domain */
2107                 r->in.domainname = lpcfg_workgroup(lp_ctx);
2108         }
2109
2110         sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
2111         if (sam_ctx == NULL) {
2112                 return WERR_DS_UNAVAILABLE;
2113         }
2114
2115         if (strcasecmp(r->in.domainname, lpcfg_workgroup(lp_ctx)) == 0) {
2116                 /* well we asked for a DC of our own domain */
2117                 if (samdb_is_pdc(sam_ctx)) {
2118                         /* we are the PDC of the specified domain */
2119                         return WERR_NO_SUCH_DOMAIN;
2120                 }
2121
2122                 *r->out.dcname = talloc_asprintf(mem_ctx, "\\%s",
2123                                                 lpcfg_netbios_name(lp_ctx));
2124                 W_ERROR_HAVE_NO_MEMORY(*r->out.dcname);
2125
2126                 return WERR_OK;
2127         }
2128
2129         /* Okay, now we have to consider the trusted domains */
2130
2131         trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList);
2132         W_ERROR_HAVE_NO_MEMORY(trusts);
2133
2134         trusts->count = 0;
2135
2136         werr = fill_trusted_domains_array(mem_ctx, sam_ctx, trusts,
2137                                           NETR_TRUST_FLAG_INBOUND
2138                                           | NETR_TRUST_FLAG_OUTBOUND);
2139         W_ERROR_NOT_OK_RETURN(werr);
2140
2141         for (i = 0; i < trusts->count; i++) {
2142                 if (strcasecmp(r->in.domainname, trusts->array[i].netbios_name) == 0) {
2143                         /* FIXME: Here we need to find a DC for the specified
2144                          * trusted domain. */
2145
2146                         /* return WERR_OK; */
2147                         return WERR_NO_SUCH_DOMAIN;
2148                 }
2149         }
2150
2151         return WERR_NO_SUCH_DOMAIN;
2152 }
2153
2154
2155 /*
2156   netr_DatabaseRedo
2157 */
2158 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2159                        struct netr_DatabaseRedo *r)
2160 {
2161         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2162 }
2163
2164
2165 /*
2166   netr_NetrEnumerateTrustedDomains
2167 */
2168 static NTSTATUS dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2169                        struct netr_NetrEnumerateTrustedDomains *r)
2170 {
2171         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2172 }
2173
2174
2175 /*
2176   netr_LogonGetCapabilities
2177 */
2178 static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2179                        struct netr_LogonGetCapabilities *r)
2180 {
2181         struct netlogon_creds_CredentialState *creds;
2182         NTSTATUS status;
2183
2184         status = dcesrv_netr_creds_server_step_check(dce_call,
2185                                                      mem_ctx,
2186                                                      r->in.computer_name,
2187                                                      r->in.credential,
2188                                                      r->out.return_authenticator,
2189                                                      &creds);
2190         if (!NT_STATUS_IS_OK(status)) {
2191                 DEBUG(0,(__location__ " Bad credentials - error\n"));
2192         }
2193         NT_STATUS_NOT_OK_RETURN(status);
2194
2195         if (r->in.query_level != 1) {
2196                 return NT_STATUS_NOT_SUPPORTED;
2197         }
2198
2199         r->out.capabilities->server_capabilities = creds->negotiate_flags;
2200
2201         return NT_STATUS_OK;
2202 }
2203
2204
2205 /*
2206   netr_NETRLOGONSETSERVICEBITS
2207 */
2208 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2209                        struct netr_NETRLOGONSETSERVICEBITS *r)
2210 {
2211         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2212 }
2213
2214
2215 /*
2216   netr_LogonGetTrustRid
2217 */
2218 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2219                        struct netr_LogonGetTrustRid *r)
2220 {
2221         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2222 }
2223
2224
2225 /*
2226   netr_NETRLOGONCOMPUTESERVERDIGEST
2227 */
2228 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2229                        struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
2230 {
2231         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2232 }
2233
2234
2235 /*
2236   netr_NETRLOGONCOMPUTECLIENTDIGEST
2237 */
2238 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2239                        struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
2240 {
2241         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2242 }
2243
2244
2245
2246 /*
2247   netr_DsRGetSiteName
2248 */
2249 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2250                                   struct netr_DsRGetSiteName *r)
2251 {
2252         struct ldb_context *sam_ctx;
2253
2254         sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
2255         if (sam_ctx == NULL) {
2256                 return WERR_DS_UNAVAILABLE;
2257         }
2258
2259         /*
2260          * We assume to be a DC when we get called over NETLOGON. Hence we
2261          * get our site name always by using "samdb_server_site_name()"
2262          * and not "samdb_client_site_name()".
2263          */
2264         *r->out.site = samdb_server_site_name(sam_ctx, mem_ctx);
2265         W_ERROR_HAVE_NO_MEMORY(*r->out.site);
2266
2267         return WERR_OK;
2268 }
2269
2270
2271 /*
2272   fill in a netr_OneDomainInfo from our own domain/forest
2273 */
2274 static NTSTATUS fill_our_one_domain_info(TALLOC_CTX *mem_ctx,
2275                                 const struct lsa_TrustDomainInfoInfoEx *our_tdo,
2276                                 struct GUID domain_guid,
2277                                 struct netr_OneDomainInfo *info,
2278                                 bool is_trust_list)
2279 {
2280         ZERO_STRUCTP(info);
2281
2282         if (is_trust_list) {
2283                 struct netr_trust_extension *te = NULL;
2284                 struct netr_trust_extension_info *tei = NULL;
2285
2286                 /* w2k8 only fills this on trusted domains */
2287                 te = talloc_zero(mem_ctx, struct netr_trust_extension);
2288                 if (te == NULL) {
2289                         return NT_STATUS_NO_MEMORY;
2290                 }
2291                 tei = &te->info;
2292                 tei->flags |= NETR_TRUST_FLAG_PRIMARY;
2293
2294                 /*
2295                  * We're always within a native forest
2296                  */
2297                 tei->flags |= NETR_TRUST_FLAG_IN_FOREST;
2298                 tei->flags |= NETR_TRUST_FLAG_NATIVE;
2299
2300                 /* For now we assume we're always the tree root */
2301                 tei->flags |= NETR_TRUST_FLAG_TREEROOT;
2302                 tei->parent_index = 0;
2303
2304                 tei->trust_type = our_tdo->trust_type;
2305                 /*
2306                  * This needs to be 0 instead of our_tdo->trust_attributes
2307                  * It means LSA_TRUST_ATTRIBUTE_WITHIN_FOREST won't
2308                  * be set, while NETR_TRUST_FLAG_IN_FOREST is set above.
2309                  */
2310                 tei->trust_attributes = 0;
2311
2312                 info->trust_extension.info = te;
2313         }
2314
2315         if (is_trust_list) {
2316                 info->dns_domainname.string = our_tdo->domain_name.string;
2317
2318                 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
2319                 info->dns_forestname.string = NULL;
2320         } else {
2321                 info->dns_domainname.string = talloc_asprintf(mem_ctx, "%s.",
2322                                                 our_tdo->domain_name.string);
2323                 if (info->dns_domainname.string == NULL) {
2324                         return NT_STATUS_NO_MEMORY;
2325                 }
2326
2327                 info->dns_forestname.string = info->dns_domainname.string;
2328         }
2329
2330         info->domainname.string = our_tdo->netbios_name.string;
2331         info->domain_sid = our_tdo->sid;
2332         info->domain_guid = domain_guid;
2333
2334         return NT_STATUS_OK;
2335 }
2336
2337 /*
2338   fill in a netr_OneDomainInfo from a trust tdo
2339 */
2340 static NTSTATUS fill_trust_one_domain_info(TALLOC_CTX *mem_ctx,
2341                                 struct GUID domain_guid,
2342                                 const struct lsa_TrustDomainInfoInfoEx *tdo,
2343                                 struct netr_OneDomainInfo *info)
2344 {
2345         struct netr_trust_extension *te = NULL;
2346         struct netr_trust_extension_info *tei = NULL;
2347
2348         ZERO_STRUCTP(info);
2349
2350         /* w2k8 only fills this on trusted domains */
2351         te = talloc_zero(mem_ctx, struct netr_trust_extension);
2352         if (te == NULL) {
2353                 return NT_STATUS_NO_MEMORY;
2354         }
2355         tei = &te->info;
2356
2357         if (tdo->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
2358                 tei->flags |= NETR_TRUST_FLAG_INBOUND;
2359         }
2360         if (tdo->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) {
2361                 tei->flags |= NETR_TRUST_FLAG_OUTBOUND;
2362         }
2363         if (tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
2364                 tei->flags |= NETR_TRUST_FLAG_IN_FOREST;
2365         }
2366
2367         /*
2368          * TODO: once we support multiple domains within our forest,
2369          * we need to fill this correct (or let the caller do it
2370          * for all domains marked with NETR_TRUST_FLAG_IN_FOREST).
2371          */
2372         tei->parent_index = 0;
2373
2374         tei->trust_type = tdo->trust_type;
2375         tei->trust_attributes = tdo->trust_attributes;
2376
2377         info->trust_extension.info = te;
2378
2379         info->domainname.string = tdo->netbios_name.string;
2380         if (tdo->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
2381                 info->dns_domainname.string = tdo->domain_name.string;
2382         } else {
2383                 info->dns_domainname.string = NULL;
2384         }
2385         info->domain_sid = tdo->sid;
2386         info->domain_guid = domain_guid;
2387
2388         /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
2389         info->dns_forestname.string = NULL;
2390
2391         return NT_STATUS_OK;
2392 }
2393
2394 /*
2395   netr_LogonGetDomainInfo
2396   this is called as part of the ADS domain logon procedure.
2397
2398   It has an important role in convaying details about the client, such
2399   as Operating System, Version, Service Pack etc.
2400 */
2401 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call,
2402         TALLOC_CTX *mem_ctx, struct netr_LogonGetDomainInfo *r)
2403 {
2404         struct netlogon_creds_CredentialState *creds;
2405         const char * const trusts_attrs[] = {
2406                 "securityIdentifier",
2407                 "flatName",
2408                 "trustPartner",
2409                 "trustAttributes",
2410                 "trustDirection",
2411                 "trustType",
2412                 NULL
2413         };
2414         const char * const attrs2[] = { "sAMAccountName", "dNSHostName",
2415                 "msDS-SupportedEncryptionTypes", NULL };
2416         const char *sam_account_name, *old_dns_hostname;
2417         struct ldb_context *sam_ctx;
2418         const struct GUID *our_domain_guid = NULL;
2419         struct lsa_TrustDomainInfoInfoEx *our_tdo = NULL;
2420         struct ldb_message **res1, *new_msg;
2421         struct ldb_result *trusts_res = NULL;
2422         struct ldb_dn *workstation_dn;
2423         struct netr_DomainInformation *domain_info;
2424         struct netr_LsaPolicyInformation *lsa_policy_info;
2425         struct auth_session_info *workstation_session_info = NULL;
2426         uint32_t default_supported_enc_types = 0xFFFFFFFF;
2427         bool update_dns_hostname = true;
2428         int ret, i;
2429         NTSTATUS status;
2430
2431         status = dcesrv_netr_creds_server_step_check(dce_call,
2432                                                      mem_ctx,
2433                                                      r->in.computer_name,
2434                                                      r->in.credential,
2435                                                      r->out.return_authenticator,
2436                                                      &creds);
2437         if (!NT_STATUS_IS_OK(status)) {
2438                 char* local  = NULL;
2439                 char* remote = NULL;
2440                 TALLOC_CTX *frame = talloc_stackframe();
2441                 remote = tsocket_address_string(dce_call->conn->remote_address,
2442                                                 frame);
2443                 local  = tsocket_address_string(dce_call->conn->local_address,
2444                                                 frame);
2445                 DBG_ERR(("Bad credentials - "
2446                          "computer[%s] remote[%s] local[%s]\n"),
2447                         log_escape(frame, r->in.computer_name),
2448                         remote,
2449                         local);
2450                 talloc_free(frame);
2451         }
2452         NT_STATUS_NOT_OK_RETURN(status);
2453
2454         /* We want to avoid connecting as system. */
2455         sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
2456         if (sam_ctx == NULL) {
2457                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
2458         }
2459
2460         switch (r->in.level) {
2461         case 1: /* Domain information */
2462
2463                 if (r->in.query->workstation_info == NULL) {
2464                         return NT_STATUS_INVALID_PARAMETER;
2465                 }
2466
2467                 /* Prepares the workstation DN */
2468                 workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
2469                                                 dom_sid_string(mem_ctx, creds->sid));
2470                 NT_STATUS_HAVE_NO_MEMORY(workstation_dn);
2471
2472                 /* Get the workstation's session info from the database. */
2473                 status = authsam_get_session_info_principal(mem_ctx,
2474                                                             dce_call->conn->dce_ctx->lp_ctx,
2475                                                             sam_ctx,
2476                                                             NULL, /* principal */
2477                                                             workstation_dn,
2478                                                             0, /* session_info_flags */
2479                                                             &workstation_session_info);
2480                 if (!NT_STATUS_IS_OK(status)) {
2481                         return status;
2482                 }
2483
2484                 /*
2485                  * Reconnect to samdb as the workstation, now that we have its
2486                  * session info. We do this so the database update can be
2487                  * attributed to the workstation account in the audit logs --
2488                  * otherwise it might be incorrectly attributed to
2489                  * SID_NT_ANONYMOUS.
2490                  */
2491                 sam_ctx = dcesrv_samdb_connect_session_info(mem_ctx,
2492                                                             dce_call,
2493                                                             workstation_session_info,
2494                                                             workstation_session_info);
2495                 if (sam_ctx == NULL) {
2496                         return NT_STATUS_INVALID_SYSTEM_SERVICE;
2497                 }
2498
2499                 /* Lookup for attributes in workstation object */
2500                 ret = gendb_search_dn(sam_ctx, mem_ctx, workstation_dn, &res1,
2501                                       attrs2);
2502                 if (ret != 1) {
2503                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2504                 }
2505
2506                 /* Gets the sam account name which is checked against the DNS
2507                  * hostname parameter. */
2508                 sam_account_name = ldb_msg_find_attr_as_string(res1[0],
2509                                                                "sAMAccountName",
2510                                                                NULL);
2511                 if (sam_account_name == NULL) {
2512                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2513                 }
2514
2515                 if (r->in.query->workstation_info->dns_hostname == NULL) {
2516                         update_dns_hostname = false;
2517                 }
2518
2519                 /* Gets the old DNS hostname */
2520                 old_dns_hostname = ldb_msg_find_attr_as_string(res1[0],
2521                                                                "dNSHostName",
2522                                                                NULL);
2523
2524                 /*
2525                  * Updates the DNS hostname when the client wishes that the
2526                  * server should handle this for him
2527                  * ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set).
2528                  * See MS-NRPC section 3.5.4.3.9
2529                  */
2530                 if ((r->in.query->workstation_info->workstation_flags
2531                     & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) {
2532                         update_dns_hostname = false;
2533                 }
2534
2535                 /* Gets host information and put them into our directory */
2536
2537                 new_msg = ldb_msg_new(mem_ctx);
2538                 NT_STATUS_HAVE_NO_MEMORY(new_msg);
2539
2540                 new_msg->dn = workstation_dn;
2541
2542                 /* Sets the OS name */
2543
2544                 if (r->in.query->workstation_info->os_name.string == NULL) {
2545                         return NT_STATUS_INVALID_PARAMETER;
2546                 }
2547
2548                 ret = ldb_msg_add_string(new_msg, "operatingSystem",
2549                                          r->in.query->workstation_info->os_name.string);
2550                 if (ret != LDB_SUCCESS) {
2551                         return NT_STATUS_NO_MEMORY;
2552                 }
2553
2554                 /*
2555                  * Sets information from "os_version". On an empty structure
2556                  * the values are cleared.
2557                  */
2558                 if (r->in.query->workstation_info->os_version.os != NULL) {
2559                         struct netr_OsVersionInfoEx *os_version;
2560                         const char *os_version_str;
2561
2562                         os_version = &r->in.query->workstation_info->os_version.os->os;
2563
2564                         if (os_version->CSDVersion == NULL) {
2565                                 return NT_STATUS_INVALID_PARAMETER;
2566                         }
2567
2568                         os_version_str = talloc_asprintf(new_msg, "%u.%u (%u)",
2569                                                          os_version->MajorVersion,
2570                                                          os_version->MinorVersion,
2571                                                          os_version->BuildNumber);
2572                         NT_STATUS_HAVE_NO_MEMORY(os_version_str);
2573
2574                         if (strlen(os_version->CSDVersion) != 0) {
2575                                 ret = ldb_msg_add_string(new_msg,
2576                                                          "operatingSystemServicePack",
2577                                                          os_version->CSDVersion);
2578                         } else {
2579                                 ret = samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
2580                                                            "operatingSystemServicePack");
2581                         }
2582                         if (ret != LDB_SUCCESS) {
2583                                 return NT_STATUS_NO_MEMORY;
2584                         }
2585
2586                         ret = ldb_msg_add_string(new_msg,
2587                                                  "operatingSystemVersion",
2588                                                  os_version_str);
2589                         if (ret != LDB_SUCCESS) {
2590                                 return NT_STATUS_NO_MEMORY;
2591                         }
2592                 } else {
2593                         ret = samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
2594                                                    "operatingSystemServicePack");
2595                         if (ret != LDB_SUCCESS) {
2596                                 return NT_STATUS_NO_MEMORY;
2597                         }
2598
2599                         ret = samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
2600                                                    "operatingSystemVersion");
2601                         if (ret != LDB_SUCCESS) {
2602                                 return NT_STATUS_NO_MEMORY;
2603                         }
2604                 }
2605
2606                 /*
2607                  * If the boolean "update_dns_hostname" remained true, then we
2608                  * are fine to start the update.
2609                  */
2610                 if (update_dns_hostname) {
2611                         ret = ldb_msg_add_string(new_msg,
2612                                                  "dNSHostname",
2613                                                  r->in.query->workstation_info->dns_hostname);
2614                         if (ret != LDB_SUCCESS) {
2615                                 return NT_STATUS_NO_MEMORY;
2616                         }
2617
2618                         /* This manual "servicePrincipalName" generation is
2619                          * still needed! Since the update in the samldb LDB
2620                          * module does only work if the entries already exist
2621                          * which isn't always the case. */
2622                         ret = ldb_msg_add_string(new_msg,
2623                                                  "servicePrincipalName",
2624                                                  talloc_asprintf(new_msg, "HOST/%s",
2625                                                  r->in.computer_name));
2626                         if (ret != LDB_SUCCESS) {
2627                                 return NT_STATUS_NO_MEMORY;
2628                         }
2629
2630                         ret = ldb_msg_add_string(new_msg,
2631                                                  "servicePrincipalName",
2632                                                  talloc_asprintf(new_msg, "HOST/%s",
2633                                                  r->in.query->workstation_info->dns_hostname));
2634                         if (ret != LDB_SUCCESS) {
2635                                 return NT_STATUS_NO_MEMORY;
2636                         }
2637                 }
2638
2639                 if (dsdb_replace(sam_ctx, new_msg, DSDB_FLAG_FORCE_ALLOW_VALIDATED_DNS_HOSTNAME_SPN_WRITE) != LDB_SUCCESS) {
2640                         DEBUG(3,("Impossible to update samdb: %s\n",
2641                                 ldb_errstring(sam_ctx)));
2642                 }
2643
2644                 talloc_free(new_msg);
2645
2646                 /* Writes back the domain information */
2647
2648                 our_domain_guid = samdb_domain_guid(sam_ctx);
2649                 if (our_domain_guid == NULL) {
2650                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2651                 }
2652
2653                 status = dsdb_trust_local_tdo_info(mem_ctx, sam_ctx, &our_tdo);
2654                 if (!NT_STATUS_IS_OK(status)) {
2655                         return status;
2656                 }
2657
2658                 status = dsdb_trust_search_tdos(sam_ctx,
2659                                                 NULL, /* exclude */
2660                                                 trusts_attrs,
2661                                                 mem_ctx,
2662                                                 &trusts_res);
2663                 if (!NT_STATUS_IS_OK(status)) {
2664                         return status;
2665                 }
2666
2667                 domain_info = talloc(mem_ctx, struct netr_DomainInformation);
2668                 NT_STATUS_HAVE_NO_MEMORY(domain_info);
2669
2670                 ZERO_STRUCTP(domain_info);
2671
2672                 /* Informations about the local and trusted domains */
2673
2674                 status = fill_our_one_domain_info(mem_ctx,
2675                                                   our_tdo,
2676                                                   *our_domain_guid,
2677                                                   &domain_info->primary_domain,
2678                                                   false);
2679                 if (!NT_STATUS_IS_OK(status)) {
2680                         return status;
2681                 }
2682
2683                 domain_info->trusted_domain_count = trusts_res->count + 1;
2684                 domain_info->trusted_domains = talloc_zero_array(mem_ctx,
2685                         struct netr_OneDomainInfo,
2686                         domain_info->trusted_domain_count);
2687                 NT_STATUS_HAVE_NO_MEMORY(domain_info->trusted_domains);
2688
2689                 for (i=0; i < trusts_res->count; i++) {
2690                         struct netr_OneDomainInfo *o =
2691                                 &domain_info->trusted_domains[i];
2692                         /* we can't know the guid of trusts outside our forest */
2693                         struct GUID trust_domain_guid = GUID_zero();
2694                         struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
2695
2696                         status = dsdb_trust_parse_tdo_info(mem_ctx,
2697                                                            trusts_res->msgs[i],
2698                                                            &tdo);
2699                         if (!NT_STATUS_IS_OK(status)) {
2700                                 return status;
2701                         }
2702
2703                         status = fill_trust_one_domain_info(mem_ctx,
2704                                                             trust_domain_guid,
2705                                                             tdo,
2706                                                             o);
2707                         if (!NT_STATUS_IS_OK(status)) {
2708                                 return status;
2709                         }
2710                 }
2711
2712                 status = fill_our_one_domain_info(mem_ctx,
2713                                                   our_tdo,
2714                                                   *our_domain_guid,
2715                                                   &domain_info->trusted_domains[i],
2716                                                   true);
2717                 if (!NT_STATUS_IS_OK(status)) {
2718                         return status;
2719                 }
2720
2721                 /* Sets the supported encryption types */
2722                 domain_info->supported_enc_types = ldb_msg_find_attr_as_uint(res1[0],
2723                         "msDS-SupportedEncryptionTypes",
2724                         default_supported_enc_types);
2725
2726                 /* Other host domain information */
2727
2728                 lsa_policy_info = talloc(mem_ctx,
2729                         struct netr_LsaPolicyInformation);
2730                 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
2731                 ZERO_STRUCTP(lsa_policy_info);
2732
2733                 domain_info->lsa_policy = *lsa_policy_info;
2734
2735                 /* The DNS hostname is only returned back when there is a chance
2736                  * for a change. */
2737                 if ((r->in.query->workstation_info->workstation_flags
2738                     & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) {
2739                         domain_info->dns_hostname.string = old_dns_hostname;
2740                 } else {
2741                         domain_info->dns_hostname.string = NULL;
2742                 }
2743
2744                 domain_info->workstation_flags =
2745                         r->in.query->workstation_info->workstation_flags & (
2746                         NETR_WS_FLAG_HANDLES_SPN_UPDATE | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS);
2747
2748                 r->out.info->domain_info = domain_info;
2749         break;
2750         case 2: /* LSA policy information - not used at the moment */
2751                 lsa_policy_info = talloc(mem_ctx,
2752                         struct netr_LsaPolicyInformation);
2753                 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
2754                 ZERO_STRUCTP(lsa_policy_info);
2755
2756                 r->out.info->lsa_policy_info = lsa_policy_info;
2757         break;
2758         default:
2759                 return NT_STATUS_INVALID_LEVEL;
2760         break;
2761         }
2762
2763         return NT_STATUS_OK;
2764 }
2765
2766
2767 /*
2768   netr_ServerPasswordGet
2769 */
2770 static NTSTATUS dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2771                        struct netr_ServerPasswordGet *r)
2772 {
2773         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2774 }
2775
2776 static bool sam_rodc_access_check(struct ldb_context *sam_ctx,
2777                                   TALLOC_CTX *mem_ctx,
2778                                   struct dom_sid *user_sid,
2779                                   struct ldb_dn *obj_dn)
2780 {
2781         const char *rodc_attrs[] = { "msDS-NeverRevealGroup",
2782                                      "msDS-RevealOnDemandGroup",
2783                                      "userAccountControl",
2784                                      NULL };
2785         const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL };
2786         struct ldb_dn *rodc_dn;
2787         int ret;
2788         struct ldb_result *rodc_res = NULL, *obj_res = NULL;
2789         WERROR werr;
2790
2791         rodc_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
2792                                  dom_sid_string(mem_ctx, user_sid));
2793         if (!ldb_dn_validate(rodc_dn)) goto denied;
2794
2795         /*
2796          * do the two searches we need
2797          * We need DSDB_SEARCH_SHOW_EXTENDED_DN as we get a SID list
2798          * out of the extended DNs
2799          */
2800         ret = dsdb_search_dn(sam_ctx, mem_ctx, &rodc_res, rodc_dn, rodc_attrs,
2801                              DSDB_SEARCH_SHOW_EXTENDED_DN);
2802         if (ret != LDB_SUCCESS || rodc_res->count != 1) goto denied;
2803
2804         ret = dsdb_search_dn(sam_ctx, mem_ctx, &obj_res, obj_dn, obj_attrs, 0);
2805         if (ret != LDB_SUCCESS || obj_res->count != 1) goto denied;
2806
2807         werr = samdb_confirm_rodc_allowed_to_repl_to(sam_ctx,
2808                                                      user_sid,
2809                                                      rodc_res->msgs[0],
2810                                                      obj_res->msgs[0]);
2811
2812         if (W_ERROR_IS_OK(werr)) {
2813                 goto allowed;
2814         }
2815 denied:
2816         return false;
2817 allowed:
2818         return true;
2819
2820 }
2821
2822 /*
2823   netr_NetrLogonSendToSam
2824 */
2825 static NTSTATUS dcesrv_netr_NetrLogonSendToSam(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2826                                                struct netr_NetrLogonSendToSam *r)
2827 {
2828         struct netlogon_creds_CredentialState *creds;
2829         struct ldb_context *sam_ctx;
2830         NTSTATUS nt_status;
2831         DATA_BLOB decrypted_blob;
2832         enum ndr_err_code ndr_err;
2833         struct netr_SendToSamBase base_msg = { 0 };
2834
2835         nt_status = dcesrv_netr_creds_server_step_check(dce_call,
2836                                                         mem_ctx,
2837                                                         r->in.computer_name,
2838                                                         r->in.credential,
2839                                                         r->out.return_authenticator,
2840                                                         &creds);
2841
2842         NT_STATUS_NOT_OK_RETURN(nt_status);
2843
2844         switch (creds->secure_channel_type) {
2845         case SEC_CHAN_BDC:
2846         case SEC_CHAN_RODC:
2847                 break;
2848         case SEC_CHAN_WKSTA:
2849         case SEC_CHAN_DNS_DOMAIN:
2850         case SEC_CHAN_DOMAIN:
2851         case SEC_CHAN_NULL:
2852                 return NT_STATUS_INVALID_PARAMETER;
2853         default:
2854                 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
2855                           creds->secure_channel_type));
2856                 return NT_STATUS_INVALID_PARAMETER;
2857         }
2858
2859         sam_ctx = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
2860         if (sam_ctx == NULL) {
2861                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
2862         }
2863
2864         /* Buffer is meant to be 16-bit aligned */
2865         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
2866                 nt_status = netlogon_creds_aes_decrypt(creds,
2867                                                        r->in.opaque_buffer,
2868                                                        r->in.buffer_len);
2869         } else {
2870                 nt_status = netlogon_creds_arcfour_crypt(creds,
2871                                                          r->in.opaque_buffer,
2872                                                          r->in.buffer_len);
2873         }
2874         if (!NT_STATUS_IS_OK(nt_status)) {
2875                 return nt_status;
2876         }
2877
2878         decrypted_blob.data = r->in.opaque_buffer;
2879         decrypted_blob.length = r->in.buffer_len;
2880
2881         ndr_err = ndr_pull_struct_blob(&decrypted_blob, mem_ctx, &base_msg,
2882                                        (ndr_pull_flags_fn_t)ndr_pull_netr_SendToSamBase);
2883
2884         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2885                 /* We only partially implement SendToSam */
2886                 return NT_STATUS_NOT_IMPLEMENTED;
2887         }
2888
2889         /* Now 'send' to SAM */
2890         switch (base_msg.message_type) {
2891         case SendToSamResetBadPasswordCount:
2892         {
2893                 struct ldb_message *msg = ldb_msg_new(mem_ctx);
2894                 struct ldb_dn *dn = NULL;
2895                 int ret = 0;
2896
2897
2898                 ret = ldb_transaction_start(sam_ctx);
2899                 if (ret != LDB_SUCCESS) {
2900                         return NT_STATUS_INTERNAL_ERROR;
2901                 }
2902
2903                 ret = dsdb_find_dn_by_guid(sam_ctx,
2904                                            mem_ctx,
2905                                            &base_msg.message.reset_bad_password.guid,
2906                                            0,
2907                                            &dn);
2908                 if (ret != LDB_SUCCESS) {
2909                         ldb_transaction_cancel(sam_ctx);
2910                         return NT_STATUS_INVALID_PARAMETER;
2911                 }
2912
2913                 if (creds->secure_channel_type == SEC_CHAN_RODC &&
2914                     !sam_rodc_access_check(sam_ctx, mem_ctx, creds->sid, dn)) {
2915                         DEBUG(1, ("Client asked to reset bad password on "
2916                                   "an arbitrary user: %s\n",
2917                                   ldb_dn_get_linearized(dn)));
2918                         ldb_transaction_cancel(sam_ctx);
2919                         return NT_STATUS_INVALID_PARAMETER;
2920                 }
2921
2922                 msg->dn = dn;
2923
2924                 ret = samdb_msg_add_int(sam_ctx, mem_ctx, msg, "badPwdCount", 0);
2925                 if (ret != LDB_SUCCESS) {
2926                         ldb_transaction_cancel(sam_ctx);
2927                         return NT_STATUS_INVALID_PARAMETER;
2928                 }
2929
2930                 ret = dsdb_replace(sam_ctx, msg, 0);
2931                 if (ret != LDB_SUCCESS) {
2932                         ldb_transaction_cancel(sam_ctx);
2933                         return NT_STATUS_INVALID_PARAMETER;
2934                 }
2935
2936                 ret = ldb_transaction_commit(sam_ctx);
2937                 if (ret != LDB_SUCCESS) {
2938                         ldb_transaction_cancel(sam_ctx);
2939                         return NT_STATUS_INTERNAL_ERROR;
2940                 }
2941
2942                 break;
2943         }
2944         default:
2945                 return NT_STATUS_NOT_IMPLEMENTED;
2946         }
2947
2948         return NT_STATUS_OK;
2949 }
2950
2951 struct dcesrv_netr_DsRGetDCName_base_state {
2952         struct dcesrv_call_state *dce_call;
2953         TALLOC_CTX *mem_ctx;
2954
2955         struct netr_DsRGetDCNameEx2 r;
2956         const char *client_site;
2957
2958         struct {
2959                 struct netr_DsRGetDCName *dc;
2960                 struct netr_DsRGetDCNameEx *dcex;
2961                 struct netr_DsRGetDCNameEx2 *dcex2;
2962         } _r;
2963 };
2964
2965 static void dcesrv_netr_DsRGetDCName_base_done(struct tevent_req *subreq);
2966
2967 /* Returns a nonzero value if multiple bits in 'val' are set. */
2968 static bool multiple_bits_set(uint32_t val)
2969 {
2970         /*
2971          * Subtracting one from an integer has the effect of flipping all the
2972          * bits from the least significant bit up to and including the least
2973          * significant '1' bit. For example,
2974          *
2975          *   0b101000 - 1
2976          * = 0b100111
2977          *       ====
2978          *
2979          * If 'val' is zero, all the bits will be flipped and thus the bitwise
2980          * AND of 'val' with 'val - 1' will be zero.
2981          *
2982          * If the integer is nonzero, the least significant '1' bit will be
2983          * ANDed with a '0' bit and so will be reset in the final result, but
2984          * all other '1' bits will remain set. In other words, the effect of
2985          * this expression is to mask off the least significant bit that is
2986          * set. Therefore iff the result of 'val & (val - 1)' is non-zero, 'val'
2987          * must contain multiple set bits.
2988          */
2989         return val & (val - 1);
2990 }
2991
2992 static WERROR dcesrv_netr_DsRGetDCName_base_call(struct dcesrv_netr_DsRGetDCName_base_state *state)
2993 {
2994         struct dcesrv_call_state *dce_call = state->dce_call;
2995         struct imessaging_context *imsg_ctx =
2996                 dcesrv_imessaging_context(dce_call->conn);
2997         TALLOC_CTX *mem_ctx = state->mem_ctx;
2998         struct netr_DsRGetDCNameEx2 *r = &state->r;
2999         struct ldb_context *sam_ctx;
3000         struct netr_DsRGetDCNameInfo *info;
3001         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
3002         const struct tsocket_address *local_address;
3003         char *local_addr = NULL;
3004         const struct tsocket_address *remote_address;
3005         char *remote_addr = NULL;
3006         const char *server_site_name;
3007         char *guid_str;
3008         struct netlogon_samlogon_response response;
3009         NTSTATUS status;
3010         const char *dc_name = NULL;
3011         const char *domain_name = NULL;
3012         const char *pdc_ip;
3013         bool different_domain = true;
3014         uint32_t valid_flags;
3015         int dc_level;
3016
3017         ZERO_STRUCTP(r->out.info);
3018
3019         sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
3020         if (sam_ctx == NULL) {
3021                 return WERR_DS_UNAVAILABLE;
3022         }
3023
3024         local_address = dcesrv_connection_get_local_address(dce_call->conn);
3025         if (tsocket_address_is_inet(local_address, "ip")) {
3026                 local_addr = tsocket_address_inet_addr_string(local_address, state);
3027                 W_ERROR_HAVE_NO_MEMORY(local_addr);
3028         }
3029
3030         remote_address = dcesrv_connection_get_remote_address(dce_call->conn);
3031         if (tsocket_address_is_inet(remote_address, "ip")) {
3032                 remote_addr = tsocket_address_inet_addr_string(remote_address, state);
3033                 W_ERROR_HAVE_NO_MEMORY(remote_addr);
3034         }
3035
3036         /* "server_unc" is ignored by w2k3 */
3037
3038         /*
3039          * With the following flags:
3040          * DS_FORCE_REDISCOVERY (Flag A)
3041          * DS_DIRECTORY_SERVICE_REQUIRED (Flag B)
3042          * DS_DIRECTORY_SERVICE_PREFERRED (Flag C)
3043          * DS_GC_SERVER_REQUIRED (Flag D)
3044          * DS_PDC_REQUIRED (Flag E)
3045          * DS_BACKGROUND_ONLY (Flag F)
3046          * DS_IP_REQUIRED (Flag G)
3047          * DS_KDC_REQUIRED (Flag H)
3048          * DS_TIMESERV_REQUIRED (Flag I)
3049          * DS_WRITABLE_REQUIRED (Flag J)
3050          * DS_GOOD_TIMESERV_PREFERRED (Flag K)
3051          * DS_AVOID_SELF (Flag L)
3052          * DS_ONLY_LDAP_NEEDED (Flag M)
3053          * DS_IS_FLAT_NAME (Flag N)
3054          * DS_IS_DNS_NAME (Flag O)
3055          * DS_TRY_NEXTCLOSEST_SITE (Flag P)
3056          * DS_DIRECTORY_SERVICE_6_REQUIRED  (Flag Q)
3057          * DS_WEB_SERVICE_REQUIRED (Flag T)
3058          * DS_DIRECTORY_SERVICE_8_REQUIRED  (Flag U)
3059          * DS_DIRECTORY_SERVICE_9_REQUIRED  (Flag V)
3060          * DS_DIRECTORY_SERVICE_10_REQUIRED (Flag W)
3061          * DS_RETURN_DNS_NAME (Flag R)
3062          * DS_RETURN_FLAT_NAME (Flag S)
3063          *
3064          * MS-NRPC 3.5.4.3.1 says:
3065          * ...
3066          * On receiving this call, the server MUST perform the following Flags
3067          * parameter validations:
3068          * - Flags D, E, and H MUST NOT be combined with each other.
3069          * - Flag N MUST NOT be combined with the O flag.
3070          * - Flag R MUST NOT be combined with the S flag.
3071          * - Flags B, Q, U, V, and W MUST NOT be combined with each other.
3072          * - Flag K MUST NOT be combined with any of the flags: B, C, D, E, or H.
3073          * - Flag P MUST NOT be set when the SiteName parameter is provided.
3074          * The server MUST return ERROR_INVALID_FLAGS for any of the previously
3075          * mentioned conflicting combinations.
3076          * ...
3077          */
3078
3079         dc_level = dsdb_dc_functional_level(sam_ctx);
3080         valid_flags = DSGETDC_VALID_FLAGS;
3081         if (dc_level >= DS_DOMAIN_FUNCTION_2012) {
3082                 valid_flags |= DS_DIRECTORY_SERVICE_8_REQUIRED;
3083         }
3084         if (dc_level >= DS_DOMAIN_FUNCTION_2012_R2) {
3085                 valid_flags |= DS_DIRECTORY_SERVICE_9_REQUIRED;
3086         }
3087         if (dc_level >= DS_DOMAIN_FUNCTION_2016) {
3088                 valid_flags |= DS_DIRECTORY_SERVICE_10_REQUIRED;
3089         }
3090         if (r->in.flags & ~valid_flags) {
3091                 /*
3092                  * TODO: add tests to prove this (maybe based on the
3093                  * msDS-Behavior-Version levels of dc, domain and/or forest
3094                  */
3095                 return WERR_INVALID_FLAGS;
3096         }
3097
3098         /* Flags D, E, and H MUST NOT be combined with each other. */
3099 #define _DEH (DS_GC_SERVER_REQUIRED|DS_PDC_REQUIRED|DS_KDC_REQUIRED)
3100         if (multiple_bits_set(r->in.flags & _DEH)) {
3101                 return WERR_INVALID_FLAGS;
3102         }
3103
3104         /* Flag N MUST NOT be combined with the O flag. */
3105         if (r->in.flags & DS_IS_FLAT_NAME &&
3106             r->in.flags & DS_IS_DNS_NAME) {
3107                 return WERR_INVALID_FLAGS;
3108         }
3109
3110         /* Flag R MUST NOT be combined with the S flag. */
3111         if (r->in.flags & DS_RETURN_DNS_NAME &&
3112             r->in.flags & DS_RETURN_FLAT_NAME) {
3113                 return WERR_INVALID_FLAGS;
3114         }
3115
3116         /* Flags B, Q, U, V, and W MUST NOT be combined with each other */
3117 #define _BQUVW ( \
3118         DS_DIRECTORY_SERVICE_REQUIRED | \
3119         DS_DIRECTORY_SERVICE_6_REQUIRED | \
3120         DS_DIRECTORY_SERVICE_8_REQUIRED | \
3121         DS_DIRECTORY_SERVICE_9_REQUIRED | \
3122         DS_DIRECTORY_SERVICE_10_REQUIRED | \
3123 0)
3124         if (multiple_bits_set(r->in.flags & _BQUVW)) {
3125                 return WERR_INVALID_FLAGS;
3126         }
3127
3128         /*
3129          * Flag K MUST NOT be combined with any of the flags:
3130          * B, C, D, E, or H.
3131          */
3132         if (r->in.flags & DS_GOOD_TIMESERV_PREFERRED &&
3133             r->in.flags &
3134             (DS_DIRECTORY_SERVICE_REQUIRED |
3135              DS_DIRECTORY_SERVICE_PREFERRED |
3136              DS_GC_SERVER_REQUIRED |
3137              DS_PDC_REQUIRED |
3138              DS_KDC_REQUIRED)) {
3139                 return WERR_INVALID_FLAGS;
3140         }
3141
3142         /* Flag P MUST NOT be set when the SiteName parameter is provided. */
3143         if (r->in.flags & DS_TRY_NEXTCLOSEST_SITE &&
3144             r->in.site_name) {
3145                 return WERR_INVALID_FLAGS;
3146         }
3147
3148         /*
3149          * If we send an all-zero GUID, we should ignore it as winbind actually
3150          * checks it with a DNS query. Windows also appears to ignore it.
3151          */
3152         if (r->in.domain_guid != NULL && GUID_all_zero(r->in.domain_guid)) {
3153                 r->in.domain_guid = NULL;
3154         }
3155
3156         /* Attempt winbind search only if we suspect the domain is incorrect */
3157         if (r->in.domain_name != NULL && strcmp("", r->in.domain_name) != 0) {
3158                 if (r->in.flags & DS_IS_FLAT_NAME) {
3159                         if (strcasecmp_m(r->in.domain_name,
3160                                          lpcfg_sam_name(lp_ctx)) == 0) {
3161                                 different_domain = false;
3162                         }
3163                 } else if (r->in.flags & DS_IS_DNS_NAME) {
3164                         if (strcasecmp_m(r->in.domain_name,
3165                                          lpcfg_dnsdomain(lp_ctx)) == 0) {
3166                                 different_domain = false;
3167                         }
3168                 } else {
3169                         if (strcasecmp_m(r->in.domain_name,
3170                                          lpcfg_sam_name(lp_ctx)) == 0 ||
3171                             strcasecmp_m(r->in.domain_name,
3172                                          lpcfg_dnsdomain(lp_ctx)) == 0) {
3173                                 different_domain = false;
3174                         }
3175                 }
3176         } else {
3177                 /*
3178                  * We need to be able to handle empty domain names, where we
3179                  * revert to our domain by default.
3180                  */
3181                 different_domain = false;
3182         }
3183
3184         /* Proof server site parameter "site_name" if it was specified */
3185         server_site_name = samdb_server_site_name(sam_ctx, state);
3186         W_ERROR_HAVE_NO_MEMORY(server_site_name);
3187         if (different_domain || (r->in.site_name != NULL &&
3188                                  (strcasecmp_m(r->in.site_name,
3189                                              server_site_name) != 0))) {
3190
3191                 struct dcerpc_binding_handle *irpc_handle = NULL;
3192                 struct tevent_req *subreq = NULL;
3193
3194                 /*
3195                  * Retrieve the client site to override the winbind response.
3196                  *
3197                  * DO NOT use Windows fallback for client site.
3198                  * In the case of multiple domains, this is plainly wrong.
3199                  *
3200                  * Note: It's possible that the client may belong to multiple
3201                  * subnets across domains. It's not clear what this would mean,
3202                  * but here we only return what this domain knows.
3203                  */
3204                 state->client_site = samdb_client_site_name(sam_ctx,
3205                                                             state,
3206                                                             remote_addr,
3207                                                             NULL,
3208                                                             false);
3209
3210                 irpc_handle = irpc_binding_handle_by_name(state,
3211                                                           imsg_ctx,
3212                                                           "winbind_server",
3213                                                           &ndr_table_winbind);
3214                 if (irpc_handle == NULL) {
3215                         DEBUG(0,("Failed to get binding_handle for "
3216                                  "winbind_server task\n"));
3217                         dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
3218                         return WERR_SERVICE_NOT_FOUND;
3219                 }
3220
3221                 dcerpc_binding_handle_set_timeout(irpc_handle, 60);
3222
3223                 dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
3224
3225                 subreq = dcerpc_wbint_DsGetDcName_send(state,
3226                                                        dce_call->event_ctx,
3227                                                        irpc_handle,
3228                                                        r->in.domain_name,
3229                                                        r->in.domain_guid,
3230                                                        r->in.site_name,
3231                                                        r->in.flags,
3232                                                        r->out.info);
3233                 if (subreq == NULL) {
3234                         return WERR_NOT_ENOUGH_MEMORY;
3235                 }
3236
3237                 tevent_req_set_callback(subreq,
3238                                         dcesrv_netr_DsRGetDCName_base_done,
3239                                         state);
3240
3241                 return WERR_OK;
3242         }
3243
3244         guid_str = r->in.domain_guid != NULL ?
3245                  GUID_string(state, r->in.domain_guid) : NULL;
3246
3247         status = fill_netlogon_samlogon_response(sam_ctx, mem_ctx,
3248                                                  r->in.domain_name,
3249                                                  r->in.domain_name,
3250                                                  NULL, guid_str,
3251                                                  r->in.client_account,
3252                                                  r->in.mask, remote_addr,
3253                                                  NETLOGON_NT_VERSION_5EX_WITH_IP,
3254                                                  lp_ctx, &response, true);
3255         if (!NT_STATUS_IS_OK(status)) {
3256                 return ntstatus_to_werror(status);
3257         }
3258
3259         /*
3260          * According to MS-NRPC 2.2.1.2.1 we should set the "DS_DNS_FOREST_ROOT"
3261          * (O) flag when the returned forest name is in DNS format. This is here
3262          * always the case (see below).
3263          */
3264         response.data.nt5_ex.server_type |= DS_DNS_FOREST_ROOT;
3265
3266         if (r->in.flags & DS_RETURN_DNS_NAME) {
3267                 dc_name = response.data.nt5_ex.pdc_dns_name;
3268                 domain_name = response.data.nt5_ex.dns_domain;
3269                 /*
3270                  * According to MS-NRPC 2.2.1.2.1 we should set the
3271                  * "DS_DNS_CONTROLLER" (M) and "DS_DNS_DOMAIN" (N) flags when
3272                  * the returned information is in DNS form.
3273                  */
3274                 response.data.nt5_ex.server_type |=
3275                         DS_DNS_CONTROLLER | DS_DNS_DOMAIN;
3276         } else if (r->in.flags & DS_RETURN_FLAT_NAME) {
3277                 dc_name = response.data.nt5_ex.pdc_name;
3278                 domain_name = response.data.nt5_ex.domain_name;
3279         } else {
3280
3281                 /*
3282                  * TODO: autodetect what we need to return
3283                  * based on the given arguments
3284                  */
3285                 dc_name = response.data.nt5_ex.pdc_name;
3286                 domain_name = response.data.nt5_ex.domain_name;
3287         }
3288
3289         if (!dc_name || !dc_name[0]) {
3290                 return WERR_NO_SUCH_DOMAIN;
3291         }
3292
3293         if (!domain_name || !domain_name[0]) {
3294                 return WERR_NO_SUCH_DOMAIN;
3295         }
3296
3297         info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
3298         W_ERROR_HAVE_NO_MEMORY(info);
3299         info->dc_unc = talloc_asprintf(mem_ctx, "%s%s",
3300                         dc_name[0] != '\\'? "\\\\":"",
3301                         talloc_strdup(mem_ctx, dc_name));
3302         W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
3303
3304         pdc_ip = local_addr;
3305         if (pdc_ip == NULL) {
3306                 pdc_ip = "127.0.0.1";
3307         }
3308         info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", pdc_ip);
3309         W_ERROR_HAVE_NO_MEMORY(info->dc_address);
3310         info->dc_address_type  = DS_ADDRESS_TYPE_INET;
3311         info->domain_guid      = response.data.nt5_ex.domain_uuid;
3312         info->domain_name      = domain_name;
3313         info->forest_name      = response.data.nt5_ex.forest;
3314         info->dc_flags         = response.data.nt5_ex.server_type;
3315         if (r->in.flags & DS_RETURN_DNS_NAME) {
3316                 /* As MS-NRPC.pdf in 2.2.1.2.1 the DS_DNS_CONTROLLER flag should be
3317                  * returned if we are returning info->dc_unc containing a FQDN.
3318                  * This attribute is called DomainControllerName in the specs,
3319                  * it seems that we decide to return FQDN or netbios depending on
3320                  * DS_RETURN_DNS_NAME.
3321                  */
3322                 info->dc_flags |= DS_DNS_CONTROLLER;
3323         }
3324         info->dc_site_name     = response.data.nt5_ex.server_site;
3325         info->client_site_name = response.data.nt5_ex.client_site;
3326
3327         *r->out.info = info;
3328
3329         return WERR_OK;
3330 }
3331
3332 static void dcesrv_netr_DsRGetDCName_base_done(struct tevent_req *subreq)
3333 {
3334         struct dcesrv_netr_DsRGetDCName_base_state *state =
3335                 tevent_req_callback_data(subreq,
3336                 struct dcesrv_netr_DsRGetDCName_base_state);
3337         struct dcesrv_call_state *dce_call = state->dce_call;
3338         NTSTATUS result, status;
3339
3340         status = dcerpc_wbint_DsGetDcName_recv(subreq,
3341                                                state->mem_ctx,
3342                                                &result);
3343         TALLOC_FREE(subreq);
3344
3345         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
3346                 state->r.out.result = WERR_TIMEOUT;
3347                 goto finished;
3348         }
3349
3350         if (!NT_STATUS_IS_OK(status)) {
3351                 DBG_ERR(__location__ ": IRPC callback failed %s\n",
3352                         nt_errstr(status));
3353                 state->r.out.result = WERR_GEN_FAILURE;
3354                 goto finished;
3355         }
3356
3357         if (!NT_STATUS_IS_OK(result)) {
3358                 DBG_NOTICE("DC location via winbind failed - %s\n",
3359                            nt_errstr(result));
3360                 state->r.out.result = WERR_NO_SUCH_DOMAIN;
3361                 goto finished;
3362         }
3363
3364         if (state->r.out.info == NULL || state->r.out.info[0] == NULL) {
3365                 DBG_ERR("DC location via winbind returned no results\n");
3366                 state->r.out.result = WERR_GEN_FAILURE;
3367                 goto finished;
3368         }
3369
3370         if (state->r.out.info[0]->dc_unc == NULL) {
3371                 DBG_ERR("DC location via winbind returned no DC unc\n");
3372                 state->r.out.result = WERR_GEN_FAILURE;
3373                 goto finished;
3374         }
3375
3376         /*
3377          * Either the supplied site name is NULL (possibly via
3378          * TRY_NEXT_CLOSEST_SITE) or the resulting site name matches
3379          * the input match name.
3380          *
3381          * TODO: Currently this means that requests with NETBIOS domain
3382          * names can fail because they do not return the site name.
3383          */
3384         if (state->r.in.site_name == NULL ||
3385             strcasecmp_m("", state->r.in.site_name) == 0 ||
3386             (state->r.out.info[0]->dc_site_name != NULL &&
3387              strcasecmp_m(state->r.out.info[0]->dc_site_name,
3388                           state->r.in.site_name) == 0)) {
3389
3390                 state->r.out.info[0]->client_site_name =
3391                         talloc_move(state->mem_ctx, &state->client_site);
3392
3393                 /*
3394                  * Make sure to return our DC UNC with // prefix.
3395                  * Winbind currently doesn't send the leading slashes
3396                  * for some reason.
3397                  */
3398                 if (strlen(state->r.out.info[0]->dc_unc) > 2 &&
3399                     strncmp("\\\\", state->r.out.info[0]->dc_unc, 2) != 0) {
3400                         const char *dc_unc = NULL;
3401
3402                         dc_unc = talloc_asprintf(state->mem_ctx,
3403                                                  "\\\\%s",
3404                                                  state->r.out.info[0]->dc_unc);
3405                         state->r.out.info[0]->dc_unc = dc_unc;
3406                 }
3407
3408                 state->r.out.result = WERR_OK;
3409         } else {
3410                 state->r.out.info = NULL;
3411                 state->r.out.result = WERR_NO_SUCH_DOMAIN;
3412         }
3413
3414 finished:
3415         if (state->_r.dcex2 != NULL) {
3416                 struct netr_DsRGetDCNameEx2 *r = state->_r.dcex2;
3417                 r->out.result = state->r.out.result;
3418         } else if (state->_r.dcex != NULL) {
3419                 struct netr_DsRGetDCNameEx *r = state->_r.dcex;
3420                 r->out.result = state->r.out.result;
3421         } else if (state->_r.dc != NULL) {
3422                 struct netr_DsRGetDCName *r = state->_r.dc;
3423                 r->out.result = state->r.out.result;
3424         }
3425
3426         TALLOC_FREE(state);
3427         status = dcesrv_reply(dce_call);
3428         if (!NT_STATUS_IS_OK(status)) {
3429                 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n",
3430                          nt_errstr(status)));
3431         }
3432 }
3433
3434 /*
3435   netr_DsRGetDCNameEx2
3436 */
3437 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call,
3438                                           TALLOC_CTX *mem_ctx,
3439                                           struct netr_DsRGetDCNameEx2 *r)
3440 {
3441         struct dcesrv_netr_DsRGetDCName_base_state *state;
3442
3443         state = talloc_zero(mem_ctx, struct dcesrv_netr_DsRGetDCName_base_state);
3444         if (state == NULL) {
3445                 return WERR_NOT_ENOUGH_MEMORY;
3446         }
3447
3448         state->dce_call = dce_call;
3449         state->mem_ctx = mem_ctx;
3450
3451         state->r = *r;
3452         state->_r.dcex2 = r;
3453
3454         return dcesrv_netr_DsRGetDCName_base_call(state);
3455 }
3456
3457 /*
3458   netr_DsRGetDCNameEx
3459 */
3460 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3461                                   struct netr_DsRGetDCNameEx *r)
3462 {
3463         struct dcesrv_netr_DsRGetDCName_base_state *state;
3464
3465         state = talloc_zero(mem_ctx, struct dcesrv_netr_DsRGetDCName_base_state);
3466         if (state == NULL) {
3467                 return WERR_NOT_ENOUGH_MEMORY;
3468         }
3469
3470         state->dce_call = dce_call;
3471         state->mem_ctx = mem_ctx;
3472
3473         state->r.in.server_unc = r->in.server_unc;
3474         state->r.in.client_account = NULL;
3475         state->r.in.mask = 0;
3476         state->r.in.domain_guid = r->in.domain_guid;
3477         state->r.in.domain_name = r->in.domain_name;
3478         state->r.in.site_name = r->in.site_name;
3479         state->r.in.flags = r->in.flags;
3480         state->r.out.info = r->out.info;
3481
3482         state->_r.dcex = r;
3483
3484         return dcesrv_netr_DsRGetDCName_base_call(state);
3485 }
3486
3487 /*
3488  * netr_DsRGetDCName
3489  *
3490  * This function is a predecessor to DsrGetDcNameEx2 according to [MS-NRPC].
3491  * Although it has a site-guid parameter, the documentation 3.5.4.3.3 DsrGetDcName
3492  * insists that it be ignored.
3493  */
3494 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3495                                        struct netr_DsRGetDCName *r)
3496 {
3497         struct dcesrv_netr_DsRGetDCName_base_state *state;
3498
3499         state = talloc_zero(mem_ctx, struct dcesrv_netr_DsRGetDCName_base_state);
3500         if (state == NULL) {
3501                 return WERR_NOT_ENOUGH_MEMORY;
3502         }
3503
3504         state->dce_call = dce_call;
3505         state->mem_ctx = mem_ctx;
3506
3507         state->r.in.server_unc = r->in.server_unc;
3508         state->r.in.client_account = NULL;
3509         state->r.in.mask = 0;
3510         state->r.in.domain_name = r->in.domain_name;
3511         state->r.in.domain_guid = r->in.domain_guid;
3512
3513         state->r.in.site_name = NULL; /* this is correct, we should ignore site GUID */
3514         state->r.in.flags = r->in.flags;
3515         state->r.out.info = r->out.info;
3516
3517         state->_r.dc = r;
3518
3519         return dcesrv_netr_DsRGetDCName_base_call(state);
3520 }
3521 /*
3522   netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
3523 */
3524 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3525                        struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
3526 {
3527         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3528 }
3529
3530
3531 /*
3532   netr_NetrEnumerateTrustedDomainsEx
3533 */
3534 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3535                        struct netr_NetrEnumerateTrustedDomainsEx *r)
3536 {
3537         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3538 }
3539
3540
3541 /*
3542   netr_DsRAddressToSitenamesExW
3543 */
3544 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3545                                                    struct netr_DsRAddressToSitenamesExW *r)
3546 {
3547         struct ldb_context *sam_ctx;
3548         struct netr_DsRAddressToSitenamesExWCtr *ctr;
3549         sa_family_t sin_family;
3550         struct sockaddr_in *addr;
3551 #ifdef HAVE_IPV6
3552         struct sockaddr_in6 *addr6;
3553         char addr_str[INET6_ADDRSTRLEN];
3554 #else
3555         char addr_str[INET_ADDRSTRLEN];
3556 #endif
3557         char *subnet_name;
3558         const char *res;
3559         uint32_t i;
3560
3561         sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
3562         if (sam_ctx == NULL) {
3563                 return WERR_DS_UNAVAILABLE;
3564         }
3565
3566         ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr);
3567         W_ERROR_HAVE_NO_MEMORY(ctr);
3568
3569         *r->out.ctr = ctr;
3570
3571         ctr->count = r->in.count;
3572         ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count);
3573         W_ERROR_HAVE_NO_MEMORY(ctr->sitename);
3574         ctr->subnetname = talloc_array(ctr, struct lsa_String, ctr->count);
3575         W_ERROR_HAVE_NO_MEMORY(ctr->subnetname);
3576
3577         for (i=0; i<ctr->count; i++) {
3578                 ctr->sitename[i].string = NULL;
3579                 ctr->subnetname[i].string = NULL;
3580
3581                 if (r->in.addresses[i].size < sizeof(sa_family_t)) {
3582                         continue;
3583                 }
3584                 /* The first two byte of the buffer are reserved for the
3585                  * "sin_family" but for now only the first one is used. */
3586                 sin_family = r->in.addresses[i].buffer[0];
3587
3588                 switch (sin_family) {
3589                 case AF_INET:
3590                         if (r->in.addresses[i].size < sizeof(struct sockaddr_in)) {
3591                                 continue;
3592                         }
3593                         addr = (struct sockaddr_in *) r->in.addresses[i].buffer;
3594                         res = inet_ntop(AF_INET, &addr->sin_addr,
3595                                         addr_str, sizeof(addr_str));
3596                         break;
3597 #ifdef HAVE_IPV6
3598                 case AF_INET6:
3599                         if (r->in.addresses[i].size < sizeof(struct sockaddr_in6)) {
3600                                 continue;
3601                         }
3602                         addr6 = (struct sockaddr_in6 *) r->in.addresses[i].buffer;
3603                         res = inet_ntop(AF_INET6, &addr6->sin6_addr,
3604                                         addr_str, sizeof(addr_str));
3605                         break;
3606 #endif
3607                 default:
3608                         continue;
3609                 }
3610
3611                 if (res == NULL) {
3612                         continue;
3613                 }
3614
3615                 ctr->sitename[i].string   = samdb_client_site_name(sam_ctx,
3616                                                                    mem_ctx,
3617                                                                    addr_str,
3618                                                                    &subnet_name,
3619                                                                    true);
3620                 W_ERROR_HAVE_NO_MEMORY(ctr->sitename[i].string);
3621                 ctr->subnetname[i].string = subnet_name;
3622         }
3623
3624         return WERR_OK;
3625 }
3626
3627
3628 /*
3629   netr_DsRAddressToSitenamesW
3630 */
3631 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3632                        struct netr_DsRAddressToSitenamesW *r)
3633 {
3634         struct netr_DsRAddressToSitenamesExW r2;
3635         struct netr_DsRAddressToSitenamesWCtr *ctr;
3636         uint32_t i;
3637         WERROR werr;
3638
3639         ZERO_STRUCT(r2);
3640
3641         r2.in.server_name = r->in.server_name;
3642         r2.in.count = r->in.count;
3643         r2.in.addresses = r->in.addresses;
3644
3645         r2.out.ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr *);
3646         W_ERROR_HAVE_NO_MEMORY(r2.out.ctr);
3647
3648         ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesWCtr);
3649         W_ERROR_HAVE_NO_MEMORY(ctr);
3650
3651         *r->out.ctr = ctr;
3652
3653         ctr->count = r->in.count;
3654         ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count);
3655         W_ERROR_HAVE_NO_MEMORY(ctr->sitename);
3656
3657         werr = dcesrv_netr_DsRAddressToSitenamesExW(dce_call, mem_ctx, &r2);
3658
3659         for (i=0; i<ctr->count; i++) {
3660                 ctr->sitename[i].string   = (*r2.out.ctr)->sitename[i].string;
3661         }
3662
3663         return werr;
3664 }
3665
3666
3667 /*
3668   netr_DsrGetDcSiteCoverageW
3669 */
3670 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3671                        struct netr_DsrGetDcSiteCoverageW *r)
3672 {
3673         struct ldb_context *sam_ctx;
3674         struct DcSitesCtr *ctr;
3675
3676         sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
3677         if (sam_ctx == NULL) {
3678                 return WERR_DS_UNAVAILABLE;
3679         }
3680
3681         ctr = talloc(mem_ctx, struct DcSitesCtr);
3682         W_ERROR_HAVE_NO_MEMORY(ctr);
3683
3684         *r->out.ctr = ctr;
3685
3686         /* For now only return our default site */
3687         ctr->num_sites = 1;
3688         ctr->sites = talloc_array(ctr, struct lsa_String, ctr->num_sites);
3689         W_ERROR_HAVE_NO_MEMORY(ctr->sites);
3690         ctr->sites[0].string = samdb_server_site_name(sam_ctx, mem_ctx);
3691         W_ERROR_HAVE_NO_MEMORY(ctr->sites[0].string);
3692
3693         return WERR_OK;
3694 }
3695
3696
3697 static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
3698                                          struct ldb_context *sam_ctx,
3699                                          struct netr_DomainTrustList *trusts,
3700                                          uint32_t trust_flags)
3701 {
3702         struct ldb_dn *system_dn;
3703         struct ldb_message **dom_res = NULL;
3704         const char *trust_attrs[] = { "flatname", "trustPartner",
3705                                       "securityIdentifier", "trustDirection",
3706                                       "trustType", "trustAttributes", NULL };
3707         uint32_t n;
3708         int i;
3709         int ret;
3710
3711         if (!(trust_flags & (NETR_TRUST_FLAG_INBOUND |
3712                              NETR_TRUST_FLAG_OUTBOUND))) {
3713                 return WERR_INVALID_FLAGS;
3714         }
3715
3716         system_dn = samdb_search_dn(sam_ctx, mem_ctx,
3717                                     ldb_get_default_basedn(sam_ctx),
3718                                     "(&(objectClass=container)(cn=System))");
3719         if (!system_dn) {
3720                 return WERR_GEN_FAILURE;
3721         }
3722
3723         ret = gendb_search(sam_ctx, mem_ctx, system_dn,
3724                            &dom_res, trust_attrs,
3725                            "(objectclass=trustedDomain)");
3726
3727         for (i = 0; i < ret; i++) {
3728                 unsigned int trust_dir;
3729                 uint32_t flags = 0;
3730
3731                 trust_dir = ldb_msg_find_attr_as_uint(dom_res[i],
3732                                                       "trustDirection", 0);
3733
3734                 if (trust_dir & LSA_TRUST_DIRECTION_INBOUND) {
3735                         flags |= NETR_TRUST_FLAG_INBOUND;
3736                 }
3737                 if (trust_dir & LSA_TRUST_DIRECTION_OUTBOUND) {
3738                         flags |= NETR_TRUST_FLAG_OUTBOUND;
3739                 }
3740
3741                 if (!(flags & trust_flags)) {
3742                         /* this trust direction was not requested */
3743                         continue;
3744                 }
3745
3746                 n = trusts->count;
3747                 trusts->array = talloc_realloc(trusts, trusts->array,
3748                                                struct netr_DomainTrust,
3749                                                n + 1);
3750                 W_ERROR_HAVE_NO_MEMORY(trusts->array);
3751
3752                 trusts->array[n].netbios_name = talloc_steal(trusts->array, ldb_msg_find_attr_as_string(dom_res[i], "flatname", NULL));
3753                 if (!trusts->array[n].netbios_name) {
3754                         DEBUG(0, ("DB Error, TrustedDomain entry (%s) "
3755                                   "without flatname\n", 
3756                                   ldb_dn_get_linearized(dom_res[i]->dn)));
3757                 }
3758
3759                 trusts->array[n].dns_name = talloc_steal(trusts->array, ldb_msg_find_attr_as_string(dom_res[i], "trustPartner", NULL));
3760
3761                 trusts->array[n].trust_flags = flags;
3762                 if ((trust_flags & NETR_TRUST_FLAG_IN_FOREST) &&
3763                     !(flags & NETR_TRUST_FLAG_TREEROOT)) {
3764                         /* TODO: find if we have parent in the list */
3765                         trusts->array[n].parent_index = 0;
3766                 }
3767
3768                 trusts->array[n].trust_type =
3769                                 ldb_msg_find_attr_as_uint(dom_res[i],
3770                                                   "trustType", 0);
3771                 trusts->array[n].trust_attributes =
3772                                 ldb_msg_find_attr_as_uint(dom_res[i],
3773                                                   "trustAttributes", 0);
3774
3775                 if ((trusts->array[n].trust_type == LSA_TRUST_TYPE_MIT) ||
3776                     (trusts->array[n].trust_type == LSA_TRUST_TYPE_DCE)) {
3777                         struct dom_sid zero_sid;
3778                         ZERO_STRUCT(zero_sid);
3779                         trusts->array[n].sid =
3780                                 dom_sid_dup(trusts, &zero_sid);
3781                 } else {
3782                         trusts->array[n].sid =
3783                                 samdb_result_dom_sid(trusts, dom_res[i],
3784                                                      "securityIdentifier");
3785                 }
3786                 trusts->array[n].guid = GUID_zero();
3787
3788                 trusts->count = n + 1;
3789         }
3790
3791         talloc_free(dom_res);
3792         return WERR_OK;
3793 }
3794
3795 /*
3796   netr_DsrEnumerateDomainTrusts
3797 */
3798 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call,
3799                                                    TALLOC_CTX *mem_ctx,
3800                                                    struct netr_DsrEnumerateDomainTrusts *r)
3801 {
3802         struct netr_DomainTrustList *trusts;
3803         struct ldb_context *sam_ctx;
3804         int ret;
3805         struct ldb_message **dom_res;
3806         const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
3807         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
3808         const char *dnsdomain = lpcfg_dnsdomain(lp_ctx);
3809         const char *p;
3810         WERROR werr;
3811
3812         if (r->in.trust_flags & 0xFFFFFE00) {
3813                 return WERR_INVALID_FLAGS;
3814         }
3815
3816         /* TODO: turn to hard check once we are sure this is 100% correct */
3817         if (!r->in.server_name) {
3818                 DEBUG(3, ("Invalid domain! Expected name in domain [%s]. "
3819                           "But received NULL!\n", dnsdomain));
3820         } else {
3821                 p = strchr(r->in.server_name, '.');
3822                 if (!p) {
3823                         DEBUG(3, ("Invalid domain! Expected name in domain "
3824                                   "[%s]. But received [%s]!\n",
3825                                   dnsdomain, r->in.server_name));
3826                         p = r->in.server_name;
3827                 } else {
3828                         p++;
3829                 }
3830                 if (strcasecmp(p, dnsdomain)) {
3831                         DEBUG(3, ("Invalid domain! Expected name in domain "
3832                                   "[%s]. But received [%s]!\n",
3833                                   dnsdomain, r->in.server_name));
3834                 }
3835         }
3836
3837         trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList);
3838         W_ERROR_HAVE_NO_MEMORY(trusts);
3839
3840         trusts->count = 0;
3841         r->out.trusts = trusts;
3842
3843         sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
3844         if (sam_ctx == NULL) {
3845                 return WERR_GEN_FAILURE;
3846         }
3847
3848         if ((r->in.trust_flags & NETR_TRUST_FLAG_INBOUND) ||
3849             (r->in.trust_flags & NETR_TRUST_FLAG_OUTBOUND)) {
3850
3851                 werr = fill_trusted_domains_array(mem_ctx, sam_ctx,
3852                                                   trusts, r->in.trust_flags);
3853                 W_ERROR_NOT_OK_RETURN(werr);
3854         }
3855
3856         /* NOTE: we currently are always the root of the forest */
3857         if (r->in.trust_flags & NETR_TRUST_FLAG_IN_FOREST) {
3858                 uint32_t n = trusts->count;
3859
3860                 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
3861                                       &dom_res, dom_attrs);
3862                 if (ret != 1) {
3863                         return WERR_GEN_FAILURE;
3864                 }
3865
3866                 trusts->count = n + 1;
3867                 trusts->array = talloc_realloc(trusts, trusts->array,
3868                                                struct netr_DomainTrust,
3869                                                trusts->count);
3870                 W_ERROR_HAVE_NO_MEMORY(trusts->array);
3871
3872                 trusts->array[n].netbios_name = lpcfg_workgroup(lp_ctx);
3873                 trusts->array[n].dns_name = lpcfg_dnsdomain(lp_ctx);
3874                 trusts->array[n].trust_flags =
3875                         NETR_TRUST_FLAG_NATIVE |
3876                         NETR_TRUST_FLAG_TREEROOT |
3877                         NETR_TRUST_FLAG_IN_FOREST |
3878                         NETR_TRUST_FLAG_PRIMARY;
3879                 /* we are always the root domain for now */
3880                 trusts->array[n].parent_index = 0;
3881                 trusts->array[n].trust_type = LSA_TRUST_TYPE_UPLEVEL;
3882                 trusts->array[n].trust_attributes = 0;
3883                 trusts->array[n].sid = samdb_result_dom_sid(mem_ctx,
3884                                                             dom_res[0],
3885                                                             "objectSid");
3886                 trusts->array[n].guid = samdb_result_guid(dom_res[0],
3887                                                           "objectGUID");
3888                 talloc_free(dom_res);
3889         }
3890
3891         return WERR_OK;
3892 }
3893
3894
3895 /*
3896   netr_DsrDeregisterDNSHostRecords
3897 */
3898 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3899                        struct netr_DsrDeregisterDNSHostRecords *r)
3900 {
3901         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3902 }
3903
3904
3905 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3906                        struct netr_ServerGetTrustInfo *r);
3907
3908 /*
3909   netr_ServerTrustPasswordsGet
3910 */
3911 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3912                        struct netr_ServerTrustPasswordsGet *r)
3913 {
3914         struct netr_ServerGetTrustInfo r2 = {};
3915         struct netr_TrustInfo *_ti = NULL;
3916         NTSTATUS status;
3917
3918         r2.in.server_name = r->in.server_name;
3919         r2.in.account_name = r->in.account_name;
3920         r2.in.secure_channel_type = r->in.secure_channel_type;
3921         r2.in.computer_name = r->in.computer_name;
3922         r2.in.credential = r->in.credential;
3923
3924         r2.out.return_authenticator = r->out.return_authenticator;
3925         r2.out.new_owf_password = r->out.new_owf_password;
3926         r2.out.old_owf_password = r->out.old_owf_password;
3927         r2.out.trust_info = &_ti;
3928
3929         status = dcesrv_netr_ServerGetTrustInfo(dce_call, mem_ctx, &r2);
3930
3931         r->out.return_authenticator = r2.out.return_authenticator;
3932         r->out.new_owf_password = r2.out.new_owf_password;
3933         r->out.old_owf_password = r2.out.old_owf_password;
3934
3935         return status;
3936 }
3937
3938 /*
3939   netr_DsRGetForestTrustInformation
3940 */
3941 struct dcesrv_netr_DsRGetForestTrustInformation_state {
3942         struct dcesrv_call_state *dce_call;
3943         TALLOC_CTX *mem_ctx;
3944         struct netr_DsRGetForestTrustInformation *r;
3945 };
3946
3947 static void dcesrv_netr_DsRGetForestTrustInformation_done(struct tevent_req *subreq);
3948
3949 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call,
3950                                                        TALLOC_CTX *mem_ctx,
3951                                                        struct netr_DsRGetForestTrustInformation *r)
3952 {
3953         struct auth_session_info *session_info =
3954                 dcesrv_call_session_info(dce_call);
3955         struct imessaging_context *imsg_ctx =
3956                 dcesrv_imessaging_context(dce_call->conn);
3957         enum security_user_level security_level;
3958         struct ldb_context *sam_ctx = NULL;
3959         struct dcesrv_netr_DsRGetForestTrustInformation_state *state = NULL;
3960         struct dcerpc_binding_handle *irpc_handle = NULL;
3961         struct tevent_req *subreq = NULL;
3962         struct ldb_dn *domain_dn = NULL;
3963         struct ldb_dn *forest_dn = NULL;
3964         int cmp;
3965         int forest_level;
3966
3967         security_level = security_session_user_level(session_info, NULL);
3968         if (security_level < SECURITY_USER) {
3969                 return WERR_ACCESS_DENIED;
3970         }
3971
3972         if (r->in.flags & 0xFFFFFFFE) {
3973                 return WERR_INVALID_FLAGS;
3974         }
3975
3976         sam_ctx = dcesrv_samdb_connect_as_user(mem_ctx, dce_call);
3977         if (sam_ctx == NULL) {
3978                 return WERR_GEN_FAILURE;
3979         }
3980
3981         domain_dn = ldb_get_default_basedn(sam_ctx);
3982         if (domain_dn == NULL) {
3983                 return WERR_GEN_FAILURE;
3984         }
3985
3986         forest_dn = ldb_get_root_basedn(sam_ctx);
3987         if (forest_dn == NULL) {
3988                 return WERR_GEN_FAILURE;
3989         }
3990
3991         cmp = ldb_dn_compare(domain_dn, forest_dn);
3992         if (cmp != 0) {
3993                 return WERR_NERR_ACFNOTLOADED;
3994         }
3995
3996         forest_level = dsdb_forest_functional_level(sam_ctx);
3997         if (forest_level < DS_DOMAIN_FUNCTION_2003) {
3998                 return WERR_INVALID_FUNCTION;
3999         }
4000
4001         if (r->in.flags & DS_GFTI_UPDATE_TDO) {
4002                 if (!samdb_is_pdc(sam_ctx)) {
4003                         return WERR_NERR_NOTPRIMARY;
4004                 }
4005
4006                 if (r->in.trusted_domain_name == NULL) {
4007                         return WERR_INVALID_FLAGS;
4008                 }
4009         }
4010
4011         if (r->in.trusted_domain_name == NULL) {
4012                 NTSTATUS status;
4013
4014                 /*
4015                  * information about our own domain
4016                  */
4017                 status = dsdb_trust_xref_forest_info(mem_ctx, sam_ctx,
4018                                                 r->out.forest_trust_info);
4019                 if (!NT_STATUS_IS_OK(status)) {
4020                         return ntstatus_to_werror(status);
4021                 }
4022
4023                 return WERR_OK;
4024         }
4025
4026         /*
4027          * Forward the request to winbindd
4028          */
4029
4030         state = talloc_zero(mem_ctx,
4031                         struct dcesrv_netr_DsRGetForestTrustInformation_state);
4032         if (state == NULL) {
4033                 return WERR_NOT_ENOUGH_MEMORY;
4034         }
4035         state->dce_call = dce_call;
4036         state->mem_ctx = mem_ctx;
4037         state->r = r;
4038
4039         irpc_handle = irpc_binding_handle_by_name(state,
4040                                                   imsg_ctx,
4041                                                   "winbind_server",
4042                                                   &ndr_table_winbind);
4043         if (irpc_handle == NULL) {
4044                 DEBUG(0,("Failed to get binding_handle for winbind_server task\n"));
4045                 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
4046                 return WERR_SERVICE_NOT_FOUND;
4047         }
4048
4049         /*
4050          * 60 seconds timeout should be enough
4051          */
4052         dcerpc_binding_handle_set_timeout(irpc_handle, 60);
4053
4054         subreq = dcerpc_winbind_GetForestTrustInformation_send(state,
4055                                                 state->dce_call->event_ctx,
4056                           &nb