s4:rpc_server: only use context within op_bind() hooks and dcesrv_interface_bind_...
[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 "auth/auth.h"
27 #include "auth/auth_sam_reply.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "../lib/util/util_ldb.h"
30 #include "../libcli/auth/schannel.h"
31 #include "libcli/security/security.h"
32 #include "param/param.h"
33 #include "lib/messaging/irpc.h"
34 #include "librpc/gen_ndr/ndr_irpc_c.h"
35 #include "../libcli/ldap/ldap_ndr.h"
36 #include "dsdb/samdb/ldb_modules/util.h"
37 #include "lib/tsocket/tsocket.h"
38 #include "librpc/gen_ndr/ndr_netlogon.h"
39 #include "librpc/gen_ndr/ndr_lsa.h"
40 #include "librpc/gen_ndr/ndr_samr.h"
41 #include "librpc/gen_ndr/ndr_irpc.h"
42 #include "librpc/gen_ndr/ndr_winbind.h"
43 #include "librpc/gen_ndr/ndr_winbind_c.h"
44 #include "lib/socket/netif.h"
45 #include "rpc_server/common/sid_helper.h"
46 #include "lib/util/util_str_escape.h"
47
48 #define DCESRV_INTERFACE_NETLOGON_BIND(call, iface) \
49        dcesrv_interface_netlogon_bind(call, iface)
50
51 /*
52  * This #define allows the netlogon interface to accept invalid
53  * association groups, because association groups are to coordinate
54  * handles, and handles are not used in NETLOGON. This in turn avoids
55  * the need to coordinate these across multiple possible NETLOGON
56  * processes
57  */
58 #define DCESRV_INTERFACE_NETLOGON_FLAGS DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED
59
60 static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_call_state *dce_call,
61                                                const struct dcesrv_interface *iface)
62 {
63         struct dcesrv_connection_context *context = dce_call->context;
64         return dcesrv_interface_bind_reject_connect(context, iface);
65 }
66
67 #define NETLOGON_SERVER_PIPE_STATE_MAGIC 0x4f555358
68 struct netlogon_server_pipe_state {
69         struct netr_Credential client_challenge;
70         struct netr_Credential server_challenge;
71 };
72
73 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
74                                         struct netr_ServerReqChallenge *r)
75 {
76         struct netlogon_server_pipe_state *pipe_state = NULL;
77         NTSTATUS ntstatus;
78
79         ZERO_STRUCTP(r->out.return_credentials);
80
81         pipe_state = dcesrv_iface_state_find_conn(dce_call,
82                         NETLOGON_SERVER_PIPE_STATE_MAGIC,
83                         struct netlogon_server_pipe_state);
84         TALLOC_FREE(pipe_state);
85
86         pipe_state = talloc_zero(dce_call,
87                                  struct netlogon_server_pipe_state);
88         if (pipe_state == NULL) {
89                 return NT_STATUS_NO_MEMORY;
90         }
91
92         pipe_state->client_challenge = *r->in.credentials;
93
94         generate_random_buffer(pipe_state->server_challenge.data,
95                                sizeof(pipe_state->server_challenge.data));
96
97         *r->out.return_credentials = pipe_state->server_challenge;
98
99         ntstatus = dcesrv_iface_state_store_conn(dce_call,
100                         NETLOGON_SERVER_PIPE_STATE_MAGIC,
101                         pipe_state);
102         if (!NT_STATUS_IS_OK(ntstatus)) {
103                 return ntstatus;
104         }
105
106         ntstatus = schannel_save_challenge(dce_call->conn->dce_ctx->lp_ctx,
107                                            &pipe_state->client_challenge,
108                                            &pipe_state->server_challenge,
109                                            r->in.computer_name);
110         if (!NT_STATUS_IS_OK(ntstatus)) {
111                 TALLOC_FREE(pipe_state);
112                 return ntstatus;
113         }
114
115         return NT_STATUS_OK;
116 }
117
118 /*
119  * Do the actual processing of a netr_ServerAuthenticate3 message.
120  * called from dcesrv_netr_ServerAuthenticate3, which handles the logging.
121  */
122 static NTSTATUS dcesrv_netr_ServerAuthenticate3_helper(
123         struct dcesrv_call_state *dce_call,
124         TALLOC_CTX *mem_ctx,
125         struct netr_ServerAuthenticate3 *r,
126         const char **trust_account_for_search,
127         const char **trust_account_in_db,
128         struct dom_sid **sid)
129 {
130         struct netlogon_server_pipe_state *pipe_state = NULL;
131         bool challenge_valid = false;
132         struct netlogon_server_pipe_state challenge;
133         struct netlogon_creds_CredentialState *creds;
134         struct ldb_context *sam_ctx;
135         struct samr_Password *curNtHash = NULL;
136         struct samr_Password *prevNtHash = NULL;
137         uint32_t user_account_control;
138         int num_records;
139         struct ldb_message **msgs;
140         NTSTATUS nt_status;
141         const char *attrs[] = {"unicodePwd", "userAccountControl",
142                                "objectSid", "samAccountName", NULL};
143         uint32_t server_flags = 0;
144         uint32_t negotiate_flags = 0;
145         bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(dce_call->conn->dce_ctx->lp_ctx);
146         bool reject_des_client = !allow_nt4_crypto;
147         bool reject_md5_client = lpcfg_reject_md5_clients(dce_call->conn->dce_ctx->lp_ctx);
148         int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx);
149         bool reject_none_rpc = (schannel == true);
150
151         ZERO_STRUCTP(r->out.return_credentials);
152         *r->out.rid = 0;
153
154         pipe_state = dcesrv_iface_state_find_conn(dce_call,
155                         NETLOGON_SERVER_PIPE_STATE_MAGIC,
156                         struct netlogon_server_pipe_state);
157         if (pipe_state != NULL) {
158                 /*
159                  * If we had a challenge remembered on the connection
160                  * consider this for usage. This can't be cleanup
161                  * by other clients.
162                  *
163                  * This is the default code path for typical clients
164                  * which call netr_ServerReqChallenge() and
165                  * netr_ServerAuthenticate3() on the same dcerpc connection.
166                  */
167                 challenge = *pipe_state;
168
169                 challenge_valid = true;
170
171         } else {
172                 NTSTATUS ntstatus;
173
174                 /*
175                  * Fallback and try to get the challenge from
176                  * the global cache.
177                  *
178                  * If too many clients are using this code path,
179                  * they may destroy their cache entries as the
180                  * TDB has a fixed size limited via a lossy hash
181                  *
182                  * The TDB used is the schannel store, which is
183                  * initialised at startup.
184                  *
185                  * NOTE: The challenge is deleted from the DB as soon as it is
186                  * fetched, to prevent reuse.
187                  *
188                  */
189
190                 ntstatus = schannel_get_challenge(dce_call->conn->dce_ctx->lp_ctx,
191                                                   &challenge.client_challenge,
192                                                   &challenge.server_challenge,
193                                                   r->in.computer_name);
194
195                 if (!NT_STATUS_IS_OK(ntstatus)) {
196                         ZERO_STRUCT(challenge);
197                 } else {
198                         challenge_valid = true;
199                 }
200         }
201
202         server_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT |
203                        NETLOGON_NEG_PERSISTENT_SAMREPL |
204                        NETLOGON_NEG_ARCFOUR |
205                        NETLOGON_NEG_PROMOTION_COUNT |
206                        NETLOGON_NEG_CHANGELOG_BDC |
207                        NETLOGON_NEG_FULL_SYNC_REPL |
208                        NETLOGON_NEG_MULTIPLE_SIDS |
209                        NETLOGON_NEG_REDO |
210                        NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
211                        NETLOGON_NEG_SEND_PASSWORD_INFO_PDC |
212                        NETLOGON_NEG_GENERIC_PASSTHROUGH |
213                        NETLOGON_NEG_CONCURRENT_RPC |
214                        NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL |
215                        NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL |
216                        NETLOGON_NEG_STRONG_KEYS |
217                        NETLOGON_NEG_TRANSITIVE_TRUSTS |
218                        NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
219                        NETLOGON_NEG_PASSWORD_SET2 |
220                        NETLOGON_NEG_GETDOMAININFO |
221                        NETLOGON_NEG_CROSS_FOREST_TRUSTS |
222                        NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION |
223                        NETLOGON_NEG_RODC_PASSTHROUGH |
224                        NETLOGON_NEG_SUPPORTS_AES |
225                        NETLOGON_NEG_AUTHENTICATED_RPC_LSASS |
226                        NETLOGON_NEG_AUTHENTICATED_RPC;
227
228         negotiate_flags = *r->in.negotiate_flags & server_flags;
229
230         if (negotiate_flags & NETLOGON_NEG_AUTHENTICATED_RPC) {
231                 reject_none_rpc = false;
232         }
233
234         if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
235                 reject_des_client = false;
236         }
237
238         if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
239                 reject_des_client = false;
240                 reject_md5_client = false;
241         }
242
243         if (reject_des_client || reject_md5_client) {
244                 /*
245                  * Here we match Windows 2012 and return no flags.
246                  */
247                 *r->out.negotiate_flags = 0;
248                 return NT_STATUS_DOWNGRADE_DETECTED;
249         }
250
251         /*
252          * This talloc_free is important to prevent re-use of the
253          * challenge.  We have to delay it this far due to NETApp
254          * servers per:
255          * https://bugzilla.samba.org/show_bug.cgi?id=11291
256          */
257         TALLOC_FREE(pipe_state);
258
259         /*
260          * At this point we must also cleanup the TDB cache
261          * entry, if we fail the client needs to call
262          * netr_ServerReqChallenge again.
263          *
264          * Note: this handles a non existing record just fine,
265          * the r->in.computer_name might not be the one used
266          * in netr_ServerReqChallenge(), but we are trying to
267          * just tidy up the normal case to prevent re-use.
268          */
269         schannel_delete_challenge(dce_call->conn->dce_ctx->lp_ctx,
270                                   r->in.computer_name);
271
272         /*
273          * According to Microsoft (see bugid #6099)
274          * Windows 7 looks at the negotiate_flags
275          * returned in this structure *even if the
276          * call fails with access denied!
277          */
278         *r->out.negotiate_flags = negotiate_flags;
279
280         if (reject_none_rpc) {
281                 /* schannel must be used, but client did not offer it. */
282                 DEBUG(0,("%s: schannel required but client failed "
283                         "to offer it. Client was %s\n",
284                          __func__,
285                          log_escape(mem_ctx, r->in.account_name)));
286                 return NT_STATUS_ACCESS_DENIED;
287         }
288
289         switch (r->in.secure_channel_type) {
290         case SEC_CHAN_WKSTA:
291         case SEC_CHAN_DNS_DOMAIN:
292         case SEC_CHAN_DOMAIN:
293         case SEC_CHAN_BDC:
294         case SEC_CHAN_RODC:
295                 break;
296         case SEC_CHAN_NULL:
297                 return NT_STATUS_INVALID_PARAMETER;
298         default:
299                 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
300                           r->in.secure_channel_type));
301                 return NT_STATUS_INVALID_PARAMETER;
302         }
303
304         sam_ctx = samdb_connect(mem_ctx,
305                                 dce_call->event_ctx,
306                                 dce_call->conn->dce_ctx->lp_ctx,
307                                 system_session(dce_call->conn->dce_ctx->lp_ctx),
308                                 dce_call->conn->remote_address,
309                                 0);
310         if (sam_ctx == NULL) {
311                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
312         }
313
314         if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
315             r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN)
316         {
317                 struct ldb_message *tdo_msg = NULL;
318                 const char * const tdo_attrs[] = {
319                         "trustAuthIncoming",
320                         "trustAttributes",
321                         "flatName",
322                         NULL
323                 };
324                 char *encoded_name = NULL;
325                 size_t len;
326                 const char *flatname = NULL;
327                 char trailer = '$';
328                 bool require_trailer = true;
329                 const char *netbios = NULL;
330                 const char *dns = NULL;
331
332                 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
333                         trailer = '.';
334                         require_trailer = false;
335                 }
336
337                 encoded_name = ldb_binary_encode_string(mem_ctx,
338                                                         r->in.account_name);
339                 if (encoded_name == NULL) {
340                         return NT_STATUS_NO_MEMORY;
341                 }
342
343                 len = strlen(encoded_name);
344                 if (len < 2) {
345                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
346                 }
347
348                 if (require_trailer && encoded_name[len - 1] != trailer) {
349                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
350                 }
351                 encoded_name[len - 1] = '\0';
352
353                 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
354                         dns = encoded_name;
355                 } else {
356                         netbios = encoded_name;
357                 }
358
359                 nt_status = dsdb_trust_search_tdo(sam_ctx,
360                                                   netbios, dns,
361                                                   tdo_attrs, mem_ctx, &tdo_msg);
362                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
363                         DEBUG(2, ("Client asked for a trusted domain secure channel, "
364                                   "but there's no tdo for [%s] => [%s] \n",
365                                   log_escape(mem_ctx, r->in.account_name),
366                                   encoded_name));
367                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
368                 }
369                 if (!NT_STATUS_IS_OK(nt_status)) {
370                         return nt_status;
371                 }
372
373                 nt_status = dsdb_trust_get_incoming_passwords(tdo_msg, mem_ctx,
374                                                               &curNtHash,
375                                                               &prevNtHash);
376                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_DISABLED)) {
377                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
378                 }
379                 if (!NT_STATUS_IS_OK(nt_status)) {
380                         return nt_status;
381                 }
382
383                 flatname = ldb_msg_find_attr_as_string(tdo_msg, "flatName", NULL);
384                 if (flatname == NULL) {
385                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
386                 }
387
388                 *trust_account_for_search = talloc_asprintf(mem_ctx, "%s$", flatname);
389                 if (*trust_account_for_search == NULL) {
390                         return NT_STATUS_NO_MEMORY;
391                 }
392         } else {
393                 *trust_account_for_search = r->in.account_name;
394         }
395
396         /* pull the user attributes */
397         num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
398                                    "(&(sAMAccountName=%s)(objectclass=user))",
399                                    ldb_binary_encode_string(mem_ctx,
400                                                             *trust_account_for_search));
401
402         if (num_records == 0) {
403                 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
404                          log_escape(mem_ctx, r->in.account_name)));
405                 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
406         }
407
408         if (num_records > 1) {
409                 DEBUG(0,("Found %d records matching user [%s]\n",
410                          num_records,
411                          log_escape(mem_ctx, r->in.account_name)));
412                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
413         }
414
415         *trust_account_in_db = ldb_msg_find_attr_as_string(msgs[0],
416                                                            "samAccountName",
417                                                            NULL);
418         if (*trust_account_in_db == NULL) {
419                 DEBUG(0,("No samAccountName returned in record matching user [%s]\n",
420                          r->in.account_name));
421                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
422         }
423         
424         user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
425
426         if (user_account_control & UF_ACCOUNTDISABLE) {
427                 DEBUG(1, ("Account [%s] is disabled\n",
428                           log_escape(mem_ctx, r->in.account_name)));
429                 return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
430         }
431
432         if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
433                 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
434                         DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
435                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
436                 }
437         } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
438                    r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
439                 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
440                         DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
441
442                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
443                 }
444         } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
445                 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
446                         DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
447                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
448                 }
449         } else if (r->in.secure_channel_type == SEC_CHAN_RODC) {
450                 if (!(user_account_control & UF_PARTIAL_SECRETS_ACCOUNT)) {
451                         DEBUG(1, ("Client asked for a RODC secure channel, but is not a RODC: acb flags: 0x%x\n", user_account_control));
452                         return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
453                 }
454         } else {
455                 /* we should never reach this */
456                 return NT_STATUS_INTERNAL_ERROR;
457         }
458
459         if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
460                 nt_status = samdb_result_passwords_no_lockout(mem_ctx,
461                                         dce_call->conn->dce_ctx->lp_ctx,
462                                         msgs[0], NULL, &curNtHash);
463                 if (!NT_STATUS_IS_OK(nt_status)) {
464                         return NT_STATUS_ACCESS_DENIED;
465                 }
466         }
467
468         if (curNtHash == NULL) {
469                 return NT_STATUS_ACCESS_DENIED;
470         }
471
472         if (!challenge_valid) {
473                 DEBUG(1, ("No challenge requested by client [%s/%s], "
474                           "cannot authenticate\n",
475                           log_escape(mem_ctx, r->in.computer_name),
476                           log_escape(mem_ctx, r->in.account_name)));
477                 return NT_STATUS_ACCESS_DENIED;
478         }
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                                            curNtHash,
487                                            r->in.credentials,
488                                            r->out.return_credentials,
489                                            negotiate_flags);
490         if (creds == NULL && prevNtHash != NULL) {
491                 /*
492                  * We fallback to the previous password for domain trusts.
493                  *
494                  * Note that lpcfg_old_password_allowed_period() doesn't
495                  * apply here.
496                  */
497                 creds = netlogon_creds_server_init(mem_ctx,
498                                                    r->in.account_name,
499                                                    r->in.computer_name,
500                                                    r->in.secure_channel_type,
501                                                    &challenge.client_challenge,
502                                                    &challenge.server_challenge,
503                                                    prevNtHash,
504                                                    r->in.credentials,
505                                                    r->out.return_credentials,
506                                                    negotiate_flags);
507         }
508
509         if (creds == NULL) {
510                 return NT_STATUS_ACCESS_DENIED;
511         }
512         creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
513         *sid = talloc_memdup(mem_ctx, creds->sid, sizeof(struct dom_sid));
514
515         nt_status = schannel_save_creds_state(mem_ctx,
516                                               dce_call->conn->dce_ctx->lp_ctx,
517                                               creds);
518         if (!NT_STATUS_IS_OK(nt_status)) {
519                 ZERO_STRUCTP(r->out.return_credentials);
520                 return nt_status;
521         }
522
523         *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
524                                                 "objectSid", 0);
525
526         return NT_STATUS_OK;
527 }
528
529 /*
530  * Log a netr_ServerAuthenticate3 request, and then invoke
531  * dcesrv_netr_ServerAuthenticate3_helper to perform the actual processing
532  */
533 static NTSTATUS dcesrv_netr_ServerAuthenticate3(
534         struct dcesrv_call_state *dce_call,
535         TALLOC_CTX *mem_ctx,
536         struct netr_ServerAuthenticate3 *r)
537 {
538         NTSTATUS status;
539         struct dom_sid *sid = NULL;
540         const char *trust_account_for_search = NULL;
541         const char *trust_account_in_db = NULL;
542         struct auth_usersupplied_info ui = {
543                 .local_host = dce_call->conn->local_address,
544                 .remote_host = dce_call->conn->remote_address,
545                 .client = {
546                         .account_name = r->in.account_name,
547                         .domain_name = lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx),
548                 },
549                 .service_description = "NETLOGON",
550                 .auth_description = "ServerAuthenticate",
551                 .netlogon_trust_account = {
552                         .computer_name = r->in.computer_name,
553                         .negotiate_flags = *r->in.negotiate_flags,
554                         .secure_channel_type = r->in.secure_channel_type,
555                 },
556         };
557
558         status = dcesrv_netr_ServerAuthenticate3_helper(dce_call,
559                                                         mem_ctx,
560                                                         r,
561                                                         &trust_account_for_search,
562                                                         &trust_account_in_db,
563                                                         &sid);
564         ui.netlogon_trust_account.sid = sid;
565         ui.netlogon_trust_account.account_name = trust_account_in_db;
566         ui.mapped.account_name = trust_account_for_search;
567         log_authentication_event(
568                 dce_call->conn->msg_ctx,
569                 dce_call->conn->dce_ctx->lp_ctx,
570                 NULL,
571                 &ui,
572                 status,
573                 lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx),
574                 trust_account_in_db,
575                 NULL,
576                 sid);
577
578         return status;
579 }
580 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
581                                         struct netr_ServerAuthenticate *r)
582 {
583         struct netr_ServerAuthenticate3 a;
584         uint32_t rid;
585         /* TODO:
586          * negotiate_flags is used as an [in] parameter
587          * so it need to be initialised.
588          *
589          * (I think ... = 0; seems wrong here --metze)
590          */
591         uint32_t negotiate_flags_in = 0;
592         uint32_t negotiate_flags_out = 0;
593
594         a.in.server_name                = r->in.server_name;
595         a.in.account_name               = r->in.account_name;
596         a.in.secure_channel_type        = r->in.secure_channel_type;
597         a.in.computer_name              = r->in.computer_name;
598         a.in.credentials                = r->in.credentials;
599         a.in.negotiate_flags            = &negotiate_flags_in;
600
601         a.out.return_credentials        = r->out.return_credentials;
602         a.out.rid                       = &rid;
603         a.out.negotiate_flags           = &negotiate_flags_out;
604
605         return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &a);
606 }
607
608 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
609                                          struct netr_ServerAuthenticate2 *r)
610 {
611         struct netr_ServerAuthenticate3 r3;
612         uint32_t rid = 0;
613
614         r3.in.server_name = r->in.server_name;
615         r3.in.account_name = r->in.account_name;
616         r3.in.secure_channel_type = r->in.secure_channel_type;
617         r3.in.computer_name = r->in.computer_name;
618         r3.in.credentials = r->in.credentials;
619         r3.out.return_credentials = r->out.return_credentials;
620         r3.in.negotiate_flags = r->in.negotiate_flags;
621         r3.out.negotiate_flags = r->out.negotiate_flags;
622         r3.out.rid = &rid;
623
624         return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
625 }
626
627 /*
628  * NOTE: The following functions are nearly identical to the ones available in
629  * source3/rpc_server/srv_nelog_nt.c
630  * The reason we keep 2 copies is that they use different structures to
631  * represent the auth_info and the decrpc pipes.
632  */
633 static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
634                                                     TALLOC_CTX *mem_ctx,
635                                                     const char *computer_name,
636                                                     struct netr_Authenticator *received_authenticator,
637                                                     struct netr_Authenticator *return_authenticator,
638                                                     struct netlogon_creds_CredentialState **creds_out)
639 {
640         NTSTATUS nt_status;
641         int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx);
642         bool schannel_global_required = (schannel == true);
643
644         if (schannel_global_required) {
645                 enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
646
647                 dcesrv_call_auth_info(dce_call, &auth_type, NULL);
648
649                 if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
650                         DBG_ERR("[%s] is not using schannel\n",
651                                 computer_name);
652                         return NT_STATUS_ACCESS_DENIED;
653                 }
654         }
655
656         nt_status = schannel_check_creds_state(mem_ctx,
657                                                dce_call->conn->dce_ctx->lp_ctx,
658                                                computer_name,
659                                                received_authenticator,
660                                                return_authenticator,
661                                                creds_out);
662         return nt_status;
663 }
664
665 /*
666   Change the machine account password for the currently connected
667   client.  Supplies only the NT#.
668 */
669
670 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
671                                        struct netr_ServerPasswordSet *r)
672 {
673         struct netlogon_creds_CredentialState *creds;
674         struct ldb_context *sam_ctx;
675         const char * const attrs[] = { "unicodePwd", NULL };
676         struct ldb_message **res;
677         struct samr_Password *oldNtHash;
678         NTSTATUS nt_status;
679         int ret;
680
681         nt_status = dcesrv_netr_creds_server_step_check(dce_call,
682                                                         mem_ctx,
683                                                         r->in.computer_name,
684                                                         r->in.credential, r->out.return_authenticator,
685                                                         &creds);
686         NT_STATUS_NOT_OK_RETURN(nt_status);
687
688         sam_ctx = samdb_connect(mem_ctx,
689                                 dce_call->event_ctx,
690                                 dce_call->conn->dce_ctx->lp_ctx,
691                                 system_session(dce_call->conn->dce_ctx->lp_ctx),
692                                 dce_call->conn->remote_address,
693                                 0);
694         if (sam_ctx == NULL) {
695                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
696         }
697
698         netlogon_creds_des_decrypt(creds, r->in.new_password);
699
700         /* fetch the old password hashes (the NT hash has to exist) */
701
702         ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
703                            "(&(objectClass=user)(objectSid=%s))",
704                            ldap_encode_ndr_dom_sid(mem_ctx, creds->sid));
705         if (ret != 1) {
706                 return NT_STATUS_WRONG_PASSWORD;
707         }
708
709         nt_status = samdb_result_passwords_no_lockout(mem_ctx,
710                                                       dce_call->conn->dce_ctx->lp_ctx,
711                                                       res[0], NULL, &oldNtHash);
712         if (!NT_STATUS_IS_OK(nt_status) || !oldNtHash) {
713                 return NT_STATUS_WRONG_PASSWORD;
714         }
715
716         /* Using the sid for the account as the key, set the password */
717         nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
718                                            creds->sid,
719                                            NULL, /* Don't have version */
720                                            NULL, /* Don't have plaintext */
721                                            NULL, r->in.new_password,
722                                            NULL, oldNtHash, /* Password change */
723                                            NULL, NULL);
724         return nt_status;
725 }
726
727 /*
728   Change the machine account password for the currently connected
729   client.  Supplies new plaintext.
730 */
731 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
732                                        struct netr_ServerPasswordSet2 *r)
733 {
734         struct netlogon_creds_CredentialState *creds;
735         struct ldb_context *sam_ctx;
736         const char * const attrs[] = { "dBCSPwd", "unicodePwd", NULL };
737         struct ldb_message **res;
738         struct samr_Password *oldLmHash, *oldNtHash;
739         struct NL_PASSWORD_VERSION version = {};
740         const uint32_t *new_version = NULL;
741         NTSTATUS nt_status;
742         DATA_BLOB new_password;
743         int ret;
744         struct samr_CryptPassword password_buf;
745
746         nt_status = dcesrv_netr_creds_server_step_check(dce_call,
747                                                         mem_ctx,
748                                                         r->in.computer_name,
749                                                         r->in.credential, r->out.return_authenticator,
750                                                         &creds);
751         NT_STATUS_NOT_OK_RETURN(nt_status);
752
753         sam_ctx = samdb_connect(mem_ctx,
754                                 dce_call->event_ctx,
755                                 dce_call->conn->dce_ctx->lp_ctx,
756                                 system_session(dce_call->conn->dce_ctx->lp_ctx),
757                                 dce_call->conn->remote_address,
758                                 0);
759         if (sam_ctx == NULL) {
760                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
761         }
762
763         memcpy(password_buf.data, r->in.new_password->data, 512);
764         SIVAL(password_buf.data, 512, r->in.new_password->length);
765
766         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
767                 netlogon_creds_aes_decrypt(creds, password_buf.data, 516);
768         } else {
769                 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
770         }
771
772         switch (creds->secure_channel_type) {
773         case SEC_CHAN_DOMAIN:
774         case SEC_CHAN_DNS_DOMAIN: {
775                 uint32_t len = IVAL(password_buf.data, 512);
776                 if (len <= 500) {
777                         uint32_t ofs = 500 - len;
778                         uint8_t *p;
779
780                         p = password_buf.data + ofs;
781
782                         version.ReservedField = IVAL(p, 0);
783                         version.PasswordVersionNumber = IVAL(p, 4);
784                         version.PasswordVersionPresent = IVAL(p, 8);
785
786                         if (version.PasswordVersionPresent == NETLOGON_PASSWORD_VERSION_NUMBER_PRESENT) {
787                                 new_version = &version.PasswordVersionNumber;
788                         }
789                 }}
790                 break;
791         default:
792                 break;
793         }
794
795         if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
796                 DEBUG(3,("samr: failed to decode password buffer\n"));
797                 return NT_STATUS_WRONG_PASSWORD;
798         }
799
800         /* fetch the old password hashes (at least one of both has to exist) */
801
802         ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
803                            "(&(objectClass=user)(objectSid=%s))",
804                            ldap_encode_ndr_dom_sid(mem_ctx, creds->sid));
805         if (ret != 1) {
806                 return NT_STATUS_WRONG_PASSWORD;
807         }
808
809         nt_status = samdb_result_passwords_no_lockout(mem_ctx,
810                                                       dce_call->conn->dce_ctx->lp_ctx,
811                                                       res[0], &oldLmHash, &oldNtHash);
812         if (!NT_STATUS_IS_OK(nt_status) || (!oldLmHash && !oldNtHash)) {
813                 return NT_STATUS_WRONG_PASSWORD;
814         }
815
816         /* Using the sid for the account as the key, set the password */
817         nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
818                                            creds->sid,
819                                            new_version,
820                                            &new_password, /* we have plaintext */
821                                            NULL, NULL,
822                                            oldLmHash, oldNtHash, /* Password change */
823                                            NULL, NULL);
824         return nt_status;
825 }
826
827
828 /*
829   netr_LogonUasLogon
830 */
831 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
832                                  struct netr_LogonUasLogon *r)
833 {
834         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
835 }
836
837
838 /*
839   netr_LogonUasLogoff
840 */
841 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
842                        struct netr_LogonUasLogoff *r)
843 {
844         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
845 }
846
847
848 static NTSTATUS dcesrv_netr_LogonSamLogon_check(struct dcesrv_call_state *dce_call,
849                                                 const struct netr_LogonSamLogonEx *r)
850 {
851         enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
852
853         switch (r->in.logon_level) {
854         case NetlogonInteractiveInformation:
855         case NetlogonServiceInformation:
856         case NetlogonInteractiveTransitiveInformation:
857         case NetlogonServiceTransitiveInformation:
858                 if (r->in.logon->password == NULL) {
859                         return NT_STATUS_INVALID_PARAMETER;
860                 }
861
862                 switch (r->in.validation_level) {
863                 case NetlogonValidationSamInfo:  /* 2 */
864                 case NetlogonValidationSamInfo2: /* 3 */
865                 case NetlogonValidationSamInfo4: /* 6 */
866                         break;
867                 default:
868                         return NT_STATUS_INVALID_INFO_CLASS;
869                 }
870
871                 break;
872         case NetlogonNetworkInformation:
873         case NetlogonNetworkTransitiveInformation:
874                 if (r->in.logon->network == NULL) {
875                         return NT_STATUS_INVALID_PARAMETER;
876                 }
877
878                 switch (r->in.validation_level) {
879                 case NetlogonValidationSamInfo:  /* 2 */
880                 case NetlogonValidationSamInfo2: /* 3 */
881                 case NetlogonValidationSamInfo4: /* 6 */
882                         break;
883                 default:
884                         return NT_STATUS_INVALID_INFO_CLASS;
885                 }
886
887                 break;
888
889         case NetlogonGenericInformation:
890                 if (r->in.logon->generic == NULL) {
891                         return NT_STATUS_INVALID_PARAMETER;
892                 }
893
894                 switch (r->in.validation_level) {
895                 /* TODO: case NetlogonValidationGenericInfo: 4 */
896                 case NetlogonValidationGenericInfo2: /* 5 */
897                         break;
898                 default:
899                         return NT_STATUS_INVALID_INFO_CLASS;
900                 }
901
902                 break;
903         default:
904                 return NT_STATUS_INVALID_PARAMETER;
905         }
906
907         dcesrv_call_auth_info(dce_call, NULL, &auth_level);
908
909         switch (r->in.validation_level) {
910         case NetlogonValidationSamInfo4: /* 6 */
911                 if (auth_level < DCERPC_AUTH_LEVEL_PRIVACY) {
912                         return NT_STATUS_INVALID_PARAMETER;
913                 }
914                 break;
915
916         default:
917                 break;
918         }
919
920         return NT_STATUS_OK;
921 }
922
923 struct dcesrv_netr_LogonSamLogon_base_state {
924         struct dcesrv_call_state *dce_call;
925
926         TALLOC_CTX *mem_ctx;
927
928         struct netlogon_creds_CredentialState *creds;
929
930         struct netr_LogonSamLogonEx r;
931
932         uint32_t _ignored_flags;
933
934         struct {
935                 struct netr_LogonSamLogon *lsl;
936                 struct netr_LogonSamLogonWithFlags *lslwf;
937                 struct netr_LogonSamLogonEx *lslex;
938         } _r;
939
940         struct kdc_check_generic_kerberos kr;
941 };
942
943 static void dcesrv_netr_LogonSamLogon_base_auth_done(struct tevent_req *subreq);
944 static void dcesrv_netr_LogonSamLogon_base_krb5_done(struct tevent_req *subreq);
945 static void dcesrv_netr_LogonSamLogon_base_reply(
946         struct dcesrv_netr_LogonSamLogon_base_state *state);
947
948 /*
949   netr_LogonSamLogon_base
950
951   This version of the function allows other wrappers to say 'do not check the credentials'
952
953   We can't do the traditional 'wrapping' format completely, as this
954   function must only run under schannel
955 */
956 static NTSTATUS dcesrv_netr_LogonSamLogon_base_call(struct dcesrv_netr_LogonSamLogon_base_state *state)
957 {
958         struct dcesrv_call_state *dce_call = state->dce_call;
959         TALLOC_CTX *mem_ctx = state->mem_ctx;
960         struct netr_LogonSamLogonEx *r = &state->r;
961         struct netlogon_creds_CredentialState *creds = state->creds;
962         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
963         const char *workgroup = lpcfg_workgroup(lp_ctx);
964         struct auth4_context *auth_context = NULL;
965         struct auth_usersupplied_info *user_info = NULL;
966         NTSTATUS nt_status;
967         struct tevent_req *subreq = NULL;
968
969         *r->out.authoritative = 1;
970
971         if (*r->in.flags & NETLOGON_SAMLOGON_FLAG_PASS_TO_FOREST_ROOT) {
972                 /*
973                  * Currently we're always the forest root ourself.
974                  */
975                 return NT_STATUS_NO_SUCH_USER;
976         }
977
978         if (*r->in.flags & NETLOGON_SAMLOGON_FLAG_PASS_CROSS_FOREST_HOP) {
979                 /*
980                  * Currently we don't support trusts correctly yet.
981                  */
982                 return NT_STATUS_NO_SUCH_USER;
983         }
984
985         user_info = talloc_zero(mem_ctx, struct auth_usersupplied_info);
986         NT_STATUS_HAVE_NO_MEMORY(user_info);
987
988         user_info->service_description = "SamLogon";
989
990         netlogon_creds_decrypt_samlogon_logon(creds,
991                                               r->in.logon_level,
992                                               r->in.logon);
993
994         switch (r->in.logon_level) {
995         case NetlogonInteractiveInformation:
996         case NetlogonServiceInformation:
997         case NetlogonInteractiveTransitiveInformation:
998         case NetlogonServiceTransitiveInformation:
999         case NetlogonNetworkInformation:
1000         case NetlogonNetworkTransitiveInformation:
1001
1002                 nt_status = auth_context_create_for_netlogon(mem_ctx,
1003                                         dce_call->event_ctx, dce_call->msg_ctx,
1004                                         dce_call->conn->dce_ctx->lp_ctx,
1005                                         &auth_context);
1006                 NT_STATUS_NOT_OK_RETURN(nt_status);
1007
1008                 user_info->remote_host = dce_call->conn->remote_address;
1009                 user_info->local_host = dce_call->conn->local_address;
1010
1011                 user_info->netlogon_trust_account.secure_channel_type
1012                         = creds->secure_channel_type;
1013                 user_info->netlogon_trust_account.negotiate_flags
1014                         = creds->negotiate_flags;
1015
1016                 /*
1017                  * These two can be unrelated when the account is
1018                  * actually that of a trusted domain, so we want to
1019                  * know which DC in that trusted domain contacted
1020                  * us
1021                  */
1022                 user_info->netlogon_trust_account.computer_name
1023                         = creds->computer_name;
1024                 user_info->netlogon_trust_account.account_name
1025                         = creds->account_name;
1026                 user_info->netlogon_trust_account.sid
1027                         = creds->sid;
1028
1029         default:
1030                 /* We do not need to set up the user_info in this case */
1031                 break;
1032         }
1033
1034         switch (r->in.logon_level) {
1035         case NetlogonInteractiveInformation:
1036         case NetlogonServiceInformation:
1037         case NetlogonInteractiveTransitiveInformation:
1038         case NetlogonServiceTransitiveInformation:
1039                 user_info->auth_description = "interactive";
1040
1041                 user_info->logon_parameters
1042                         = r->in.logon->password->identity_info.parameter_control;
1043                 user_info->client.account_name
1044                         = r->in.logon->password->identity_info.account_name.string;
1045                 user_info->client.domain_name
1046                         = r->in.logon->password->identity_info.domain_name.string;
1047                 user_info->workstation_name
1048                         = r->in.logon->password->identity_info.workstation.string;
1049                 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
1050                 user_info->password_state = AUTH_PASSWORD_HASH;
1051
1052                 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
1053                 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
1054                 *user_info->password.hash.lanman = r->in.logon->password->lmpassword;
1055
1056                 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
1057                 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
1058                 *user_info->password.hash.nt = r->in.logon->password->ntpassword;
1059
1060                 break;
1061         case NetlogonNetworkInformation:
1062         case NetlogonNetworkTransitiveInformation:
1063                 user_info->auth_description = "network";
1064
1065                 nt_status = auth_context_set_challenge(
1066                         auth_context,
1067                         r->in.logon->network->challenge,
1068                         "netr_LogonSamLogonWithFlags");
1069                 NT_STATUS_NOT_OK_RETURN(nt_status);
1070
1071                 user_info->logon_parameters
1072                         = r->in.logon->network->identity_info.parameter_control;
1073                 user_info->client.account_name
1074                         = r->in.logon->network->identity_info.account_name.string;
1075                 user_info->client.domain_name
1076                         = r->in.logon->network->identity_info.domain_name.string;
1077                 user_info->workstation_name
1078                         = r->in.logon->network->identity_info.workstation.string;
1079
1080                 user_info->password_state = AUTH_PASSWORD_RESPONSE;
1081                 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length);
1082                 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length);
1083
1084                 nt_status = NTLMv2_RESPONSE_verify_netlogon_creds(
1085                                         user_info->client.account_name,
1086                                         user_info->client.domain_name,
1087                                         user_info->password.response.nt,
1088                                         creds, workgroup);
1089                 NT_STATUS_NOT_OK_RETURN(nt_status);
1090
1091                 break;
1092
1093
1094         case NetlogonGenericInformation:
1095         {
1096                 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
1097                         /* OK */
1098                 } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
1099                         /* OK */
1100                 } else {
1101                         /* Using DES to verify kerberos tickets makes no sense */
1102                         return NT_STATUS_INVALID_PARAMETER;
1103                 }
1104
1105                 if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) {
1106                         struct dcerpc_binding_handle *irpc_handle;
1107                         struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
1108                         NT_STATUS_HAVE_NO_MEMORY(generic);
1109
1110                         r->out.validation->generic = generic;
1111
1112                         irpc_handle = irpc_binding_handle_by_name(mem_ctx,
1113                                                                   dce_call->msg_ctx,
1114                                                                   "kdc_server",
1115                                                                   &ndr_table_irpc);
1116                         if (irpc_handle == NULL) {
1117                                 return NT_STATUS_NO_LOGON_SERVERS;
1118                         }
1119
1120                         state->kr.in.generic_request =
1121                                 data_blob_const(r->in.logon->generic->data,
1122                                                 r->in.logon->generic->length);
1123
1124                         /*
1125                          * 60 seconds should be enough
1126                          */
1127                         dcerpc_binding_handle_set_timeout(irpc_handle, 60);
1128                         subreq = dcerpc_kdc_check_generic_kerberos_r_send(state,
1129                                                 state->dce_call->event_ctx,
1130                                                 irpc_handle, &state->kr);
1131                         if (subreq == NULL) {
1132                                 return NT_STATUS_NO_MEMORY;
1133                         }
1134                         state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
1135                         tevent_req_set_callback(subreq,
1136                                         dcesrv_netr_LogonSamLogon_base_krb5_done,
1137                                         state);
1138                         return NT_STATUS_OK;
1139                 }
1140
1141                 /* Until we get an implemetnation of these other packages */
1142                 return NT_STATUS_INVALID_PARAMETER;
1143         }
1144         default:
1145                 return NT_STATUS_INVALID_PARAMETER;
1146         }
1147
1148         subreq = auth_check_password_send(state, state->dce_call->event_ctx,
1149                                           auth_context, user_info);
1150         state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
1151         tevent_req_set_callback(subreq,
1152                                 dcesrv_netr_LogonSamLogon_base_auth_done,
1153                                 state);
1154         return NT_STATUS_OK;
1155 }
1156
1157 static void dcesrv_netr_LogonSamLogon_base_auth_done(struct tevent_req *subreq)
1158 {
1159         struct dcesrv_netr_LogonSamLogon_base_state *state =
1160                 tevent_req_callback_data(subreq,
1161                 struct dcesrv_netr_LogonSamLogon_base_state);
1162         TALLOC_CTX *mem_ctx = state->mem_ctx;
1163         struct netr_LogonSamLogonEx *r = &state->r;
1164         struct auth_user_info_dc *user_info_dc = NULL;
1165         struct netr_SamInfo2 *sam2 = NULL;
1166         struct netr_SamInfo3 *sam3 = NULL;
1167         struct netr_SamInfo6 *sam6 = NULL;
1168         NTSTATUS nt_status;
1169
1170         nt_status = auth_check_password_recv(subreq, mem_ctx,
1171                                              &user_info_dc,
1172                                              r->out.authoritative);
1173         TALLOC_FREE(subreq);
1174         if (!NT_STATUS_IS_OK(nt_status)) {
1175                 r->out.result = nt_status;
1176                 dcesrv_netr_LogonSamLogon_base_reply(state);
1177                 return;
1178         }
1179
1180         switch (r->in.validation_level) {
1181         case 2:
1182                 nt_status = auth_convert_user_info_dc_saminfo2(mem_ctx,
1183                                                                user_info_dc,
1184                                                                &sam2);
1185                 if (!NT_STATUS_IS_OK(nt_status)) {
1186                         r->out.result = nt_status;
1187                         dcesrv_netr_LogonSamLogon_base_reply(state);
1188                         return;
1189                 }
1190
1191                 r->out.validation->sam2 = sam2;
1192                 break;
1193
1194         case 3:
1195                 nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx,
1196                                                                user_info_dc,
1197                                                                &sam3);
1198                 if (!NT_STATUS_IS_OK(nt_status)) {
1199                         r->out.result = nt_status;
1200                         dcesrv_netr_LogonSamLogon_base_reply(state);
1201                         return;
1202                 }
1203
1204                 r->out.validation->sam3 = sam3;
1205                 break;
1206
1207         case 6:
1208                 nt_status = auth_convert_user_info_dc_saminfo6(mem_ctx,
1209                                                                user_info_dc,
1210                                                                &sam6);
1211                 if (!NT_STATUS_IS_OK(nt_status)) {
1212                         r->out.result = nt_status;
1213                         dcesrv_netr_LogonSamLogon_base_reply(state);
1214                         return;
1215                 }
1216
1217                 r->out.validation->sam6 = sam6;
1218                 break;
1219
1220         default:
1221                 if (!NT_STATUS_IS_OK(nt_status)) {
1222                         r->out.result = NT_STATUS_INVALID_INFO_CLASS;
1223                         dcesrv_netr_LogonSamLogon_base_reply(state);
1224                         return;
1225                 }
1226         }
1227
1228         /* TODO: Describe and deal with these flags */
1229         *r->out.flags = 0;
1230
1231         r->out.result = NT_STATUS_OK;
1232
1233         dcesrv_netr_LogonSamLogon_base_reply(state);
1234 }
1235
1236 static void dcesrv_netr_LogonSamLogon_base_krb5_done(struct tevent_req *subreq)
1237 {
1238         struct dcesrv_netr_LogonSamLogon_base_state *state =
1239                 tevent_req_callback_data(subreq,
1240                 struct dcesrv_netr_LogonSamLogon_base_state);
1241         TALLOC_CTX *mem_ctx = state->mem_ctx;
1242         struct netr_LogonSamLogonEx *r = &state->r;
1243         struct netr_GenericInfo2 *generic = NULL;
1244         NTSTATUS status;
1245
1246         status = dcerpc_kdc_check_generic_kerberos_r_recv(subreq, mem_ctx);
1247         TALLOC_FREE(subreq);
1248         if (!NT_STATUS_IS_OK(status)) {
1249                 r->out.result = status;
1250                 dcesrv_netr_LogonSamLogon_base_reply(state);
1251                 return;
1252         }
1253
1254         generic = r->out.validation->generic;
1255         generic->length = state->kr.out.generic_reply.length;
1256         generic->data = state->kr.out.generic_reply.data;
1257
1258         /* TODO: Describe and deal with these flags */
1259         *r->out.flags = 0;
1260
1261         r->out.result = NT_STATUS_OK;
1262
1263         dcesrv_netr_LogonSamLogon_base_reply(state);
1264 }
1265
1266 static void dcesrv_netr_LogonSamLogon_base_reply(
1267         struct dcesrv_netr_LogonSamLogon_base_state *state)
1268 {
1269         struct netr_LogonSamLogonEx *r = &state->r;
1270         NTSTATUS status;
1271
1272         if (NT_STATUS_IS_OK(r->out.result)) {
1273                 netlogon_creds_encrypt_samlogon_validation(state->creds,
1274                                                            r->in.validation_level,
1275                                                            r->out.validation);
1276         }
1277
1278         if (state->_r.lslex != NULL) {
1279                 struct netr_LogonSamLogonEx *_r = state->_r.lslex;
1280                 _r->out.result = r->out.result;
1281         } else if (state->_r.lslwf != NULL) {
1282                 struct netr_LogonSamLogonWithFlags *_r = state->_r.lslwf;
1283                 _r->out.result = r->out.result;
1284         } else if (state->_r.lsl != NULL) {
1285                 struct netr_LogonSamLogon *_r = state->_r.lsl;
1286                 _r->out.result = r->out.result;
1287         }
1288
1289         status = dcesrv_reply(state->dce_call);
1290         if (!NT_STATUS_IS_OK(status)) {
1291                 DBG_ERR("dcesrv_reply() failed - %s\n",
1292                         nt_errstr(status));
1293         }
1294 }
1295
1296 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1297                                      struct netr_LogonSamLogonEx *r)
1298 {
1299         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
1300         struct dcesrv_netr_LogonSamLogon_base_state *state;
1301         NTSTATUS nt_status;
1302
1303         *r->out.authoritative = 1;
1304
1305         state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonSamLogon_base_state);
1306         if (state == NULL) {
1307                 return NT_STATUS_NO_MEMORY;
1308         }
1309
1310         state->dce_call = dce_call;
1311         state->mem_ctx = mem_ctx;
1312
1313         state->r.in.server_name      = r->in.server_name;
1314         state->r.in.computer_name    = r->in.computer_name;
1315         state->r.in.logon_level      = r->in.logon_level;
1316         state->r.in.logon            = r->in.logon;
1317         state->r.in.validation_level = r->in.validation_level;
1318         state->r.in.flags            = r->in.flags;
1319         state->r.out.validation      = r->out.validation;
1320         state->r.out.authoritative   = r->out.authoritative;
1321         state->r.out.flags           = r->out.flags;
1322
1323         state->_r.lslex = r;
1324
1325         nt_status = dcesrv_netr_LogonSamLogon_check(dce_call, &state->r);
1326         if (!NT_STATUS_IS_OK(nt_status)) {
1327                 return nt_status;
1328         }
1329
1330         nt_status = schannel_get_creds_state(mem_ctx,
1331                                              dce_call->conn->dce_ctx->lp_ctx,
1332                                              r->in.computer_name, &state->creds);
1333         if (!NT_STATUS_IS_OK(nt_status)) {
1334                 return nt_status;
1335         }
1336
1337         dcesrv_call_auth_info(dce_call, &auth_type, NULL);
1338
1339         if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
1340                 return NT_STATUS_ACCESS_DENIED;
1341         }
1342
1343         nt_status = dcesrv_netr_LogonSamLogon_base_call(state);
1344
1345         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1346                 return nt_status;
1347         }
1348
1349         return nt_status;
1350 }
1351
1352 /*
1353   netr_LogonSamLogonWithFlags
1354
1355 */
1356 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1357                                             struct netr_LogonSamLogonWithFlags *r)
1358 {
1359         struct dcesrv_netr_LogonSamLogon_base_state *state;
1360         NTSTATUS nt_status;
1361
1362         *r->out.authoritative = 1;
1363
1364         state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonSamLogon_base_state);
1365         if (state == NULL) {
1366                 return NT_STATUS_NO_MEMORY;
1367         }
1368
1369         state->dce_call = dce_call;
1370         state->mem_ctx = mem_ctx;
1371
1372         state->r.in.server_name      = r->in.server_name;
1373         state->r.in.computer_name    = r->in.computer_name;
1374         state->r.in.logon_level      = r->in.logon_level;
1375         state->r.in.logon            = r->in.logon;
1376         state->r.in.validation_level = r->in.validation_level;
1377         state->r.in.flags            = r->in.flags;
1378         state->r.out.validation      = r->out.validation;
1379         state->r.out.authoritative   = r->out.authoritative;
1380         state->r.out.flags           = r->out.flags;
1381
1382         state->_r.lslwf = r;
1383
1384         nt_status = dcesrv_netr_LogonSamLogon_check(dce_call, &state->r);
1385         if (!NT_STATUS_IS_OK(nt_status)) {
1386                 return nt_status;
1387         }
1388
1389         r->out.return_authenticator = talloc_zero(mem_ctx,
1390                                                   struct netr_Authenticator);
1391         if (r->out.return_authenticator == NULL) {
1392                 return NT_STATUS_NO_MEMORY;
1393         }
1394
1395         nt_status = dcesrv_netr_creds_server_step_check(dce_call,
1396                                                         mem_ctx,
1397                                                         r->in.computer_name,
1398                                                         r->in.credential,
1399                                                         r->out.return_authenticator,
1400                                                         &state->creds);
1401         if (!NT_STATUS_IS_OK(nt_status)) {
1402                 return nt_status;
1403         }
1404
1405         nt_status = dcesrv_netr_LogonSamLogon_base_call(state);
1406
1407         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1408                 return nt_status;
1409         }
1410
1411         return nt_status;
1412 }
1413
1414 /*
1415   netr_LogonSamLogon
1416 */
1417 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1418                                    struct netr_LogonSamLogon *r)
1419 {
1420         struct dcesrv_netr_LogonSamLogon_base_state *state;
1421         NTSTATUS nt_status;
1422
1423         *r->out.authoritative = 1;
1424
1425         state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonSamLogon_base_state);
1426         if (state == NULL) {
1427                 return NT_STATUS_NO_MEMORY;
1428         }
1429
1430         state->dce_call = dce_call;
1431         state->mem_ctx = mem_ctx;
1432
1433         state->r.in.server_name      = r->in.server_name;
1434         state->r.in.computer_name    = r->in.computer_name;
1435         state->r.in.logon_level      = r->in.logon_level;
1436         state->r.in.logon            = r->in.logon;
1437         state->r.in.validation_level = r->in.validation_level;
1438         state->r.in.flags            = &state->_ignored_flags;
1439         state->r.out.validation      = r->out.validation;
1440         state->r.out.authoritative   = r->out.authoritative;
1441         state->r.out.flags           = &state->_ignored_flags;
1442
1443         state->_r.lsl = r;
1444
1445         nt_status = dcesrv_netr_LogonSamLogon_check(dce_call, &state->r);
1446         if (!NT_STATUS_IS_OK(nt_status)) {
1447                 return nt_status;
1448         }
1449
1450         r->out.return_authenticator = talloc_zero(mem_ctx,
1451                                                   struct netr_Authenticator);
1452         if (r->out.return_authenticator == NULL) {
1453                 return NT_STATUS_NO_MEMORY;
1454         }
1455
1456         nt_status = dcesrv_netr_creds_server_step_check(dce_call,
1457                                                         mem_ctx,
1458                                                         r->in.computer_name,
1459                                                         r->in.credential,
1460                                                         r->out.return_authenticator,
1461                                                         &state->creds);
1462         if (!NT_STATUS_IS_OK(nt_status)) {
1463                 return nt_status;
1464         }
1465
1466         nt_status = dcesrv_netr_LogonSamLogon_base_call(state);
1467
1468         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1469                 return nt_status;
1470         }
1471
1472         return nt_status;
1473 }
1474
1475
1476 /*
1477   netr_LogonSamLogoff
1478 */
1479 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1480                        struct netr_LogonSamLogoff *r)
1481 {
1482         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1483 }
1484
1485
1486
1487 /*
1488   netr_DatabaseDeltas
1489 */
1490 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1491                        struct netr_DatabaseDeltas *r)
1492 {
1493         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1494 }
1495
1496
1497 /*
1498   netr_DatabaseSync2
1499 */
1500 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1501                        struct netr_DatabaseSync2 *r)
1502 {
1503         /* win2k3 native mode returns  "NOT IMPLEMENTED" for this call */
1504         return NT_STATUS_NOT_IMPLEMENTED;
1505 }
1506
1507
1508 /*
1509   netr_DatabaseSync
1510 */
1511 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1512                        struct netr_DatabaseSync *r)
1513 {
1514         struct netr_DatabaseSync2 r2;
1515         NTSTATUS status;
1516
1517         ZERO_STRUCT(r2);
1518
1519         r2.in.logon_server = r->in.logon_server;
1520         r2.in.computername = r->in.computername;
1521         r2.in.credential = r->in.credential;
1522         r2.in.database_id = r->in.database_id;
1523         r2.in.restart_state = SYNCSTATE_NORMAL_STATE;
1524         r2.in.sync_context = r->in.sync_context;
1525         r2.out.sync_context = r->out.sync_context;
1526         r2.out.delta_enum_array = r->out.delta_enum_array;
1527         r2.in.preferredmaximumlength = r->in.preferredmaximumlength;
1528
1529         status = dcesrv_netr_DatabaseSync2(dce_call, mem_ctx, &r2);
1530
1531         return status;
1532 }
1533
1534
1535 /*
1536   netr_AccountDeltas
1537 */
1538 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1539                        struct netr_AccountDeltas *r)
1540 {
1541         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1542         return NT_STATUS_NOT_IMPLEMENTED;
1543 }
1544
1545
1546 /*
1547   netr_AccountSync
1548 */
1549 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1550                        struct netr_AccountSync *r)
1551 {
1552         /* w2k3 returns "NOT IMPLEMENTED" for this call */
1553         return NT_STATUS_NOT_IMPLEMENTED;
1554 }
1555
1556
1557 /*
1558   netr_GetDcName
1559 */
1560 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1561                        struct netr_GetDcName *r)
1562 {
1563         struct auth_session_info *session_info =
1564                 dcesrv_call_session_info(dce_call);
1565         const char * const attrs[] = { NULL };
1566         struct ldb_context *sam_ctx;
1567         struct ldb_message **res;
1568         struct ldb_dn *domain_dn;
1569         int ret;
1570         const char *dcname;
1571
1572         /*
1573          * [MS-NRPC] 3.5.5.3.4 NetrGetDCName says
1574          * that the domainname needs to be a valid netbios domain
1575          * name, if it is not NULL.
1576          */
1577         if (r->in.domainname) {
1578                 const char *dot = strchr(r->in.domainname, '.');
1579                 size_t len = strlen(r->in.domainname);
1580
1581                 if (dot || len > 15) {
1582                         return WERR_NERR_DCNOTFOUND;
1583                 }
1584
1585                 /*
1586                  * TODO: Should we also varify that only valid
1587                  *       netbios name characters are used?
1588                  */
1589         }
1590
1591         sam_ctx = samdb_connect(mem_ctx,
1592                                 dce_call->event_ctx,
1593                                 dce_call->conn->dce_ctx->lp_ctx,
1594                                 session_info,
1595                                 dce_call->conn->remote_address,
1596                                 0);
1597         if (sam_ctx == NULL) {
1598                 return WERR_DS_UNAVAILABLE;
1599         }
1600
1601         domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx,
1602                                        r->in.domainname);
1603         if (domain_dn == NULL) {
1604                 return WERR_NO_SUCH_DOMAIN;
1605         }
1606
1607         ret = gendb_search_dn(sam_ctx, mem_ctx,
1608                               domain_dn, &res, attrs);
1609         if (ret != 1) {
1610                 return WERR_NO_SUCH_DOMAIN;
1611         }
1612
1613         /* TODO: - return real IP address
1614          *       - check all r->in.* parameters (server_unc is ignored by w2k3!)
1615          */
1616         dcname = talloc_asprintf(mem_ctx, "\\\\%s",
1617                                  lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
1618         W_ERROR_HAVE_NO_MEMORY(dcname);
1619
1620         *r->out.dcname = dcname;
1621         return WERR_OK;
1622 }
1623
1624 struct dcesrv_netr_LogonControl_base_state {
1625         struct dcesrv_call_state *dce_call;
1626
1627         TALLOC_CTX *mem_ctx;
1628
1629         struct netr_LogonControl2Ex r;
1630
1631         struct {
1632                 struct netr_LogonControl *l;
1633                 struct netr_LogonControl2 *l2;
1634                 struct netr_LogonControl2Ex *l2ex;
1635         } _r;
1636 };
1637
1638 static void dcesrv_netr_LogonControl_base_done(struct tevent_req *subreq);
1639
1640 static WERROR dcesrv_netr_LogonControl_base_call(struct dcesrv_netr_LogonControl_base_state *state)
1641 {
1642         struct loadparm_context *lp_ctx = state->dce_call->conn->dce_ctx->lp_ctx;
1643         struct auth_session_info *session_info =
1644                 dcesrv_call_session_info(state->dce_call);
1645         enum security_user_level security_level;
1646         struct dcerpc_binding_handle *irpc_handle;
1647         struct tevent_req *subreq;
1648         bool ok;
1649
1650         /* TODO: check for WERR_INVALID_COMPUTERNAME ? */
1651
1652         if (state->_r.l != NULL) {
1653                 /*
1654                  * netr_LogonControl
1655                  */
1656                 if (state->r.in.level == 0x00000002) {
1657                         return WERR_NOT_SUPPORTED;
1658                 } else if (state->r.in.level != 0x00000001) {
1659                         return WERR_INVALID_LEVEL;
1660                 }
1661
1662                 switch (state->r.in.function_code) {
1663                 case NETLOGON_CONTROL_QUERY:
1664                 case NETLOGON_CONTROL_REPLICATE:
1665                 case NETLOGON_CONTROL_SYNCHRONIZE:
1666                 case NETLOGON_CONTROL_PDC_REPLICATE:
1667                 case NETLOGON_CONTROL_BREAKPOINT:
1668                 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
1669                 case NETLOGON_CONTROL_TRUNCATE_LOG:
1670                         break;
1671                 default:
1672                         return WERR_NOT_SUPPORTED;
1673                 }
1674         }
1675
1676         if (state->r.in.level < 0x00000001) {
1677                 return WERR_INVALID_LEVEL;
1678         }
1679
1680         if (state->r.in.level > 0x00000004) {
1681                 return WERR_INVALID_LEVEL;
1682         }
1683
1684         if (state->r.in.function_code == NETLOGON_CONTROL_QUERY) {
1685                 struct netr_NETLOGON_INFO_1 *info1 = NULL;
1686                 struct netr_NETLOGON_INFO_3 *info3 = NULL;
1687
1688                 switch (state->r.in.level) {
1689                 case 0x00000001:
1690                         info1 = talloc_zero(state->mem_ctx,
1691                                             struct netr_NETLOGON_INFO_1);
1692                         if (info1 == NULL) {
1693                                 return WERR_NOT_ENOUGH_MEMORY;
1694                         }
1695                         state->r.out.query->info1 = info1;
1696                         return WERR_OK;
1697
1698                 case 0x00000003:
1699                         info3 = talloc_zero(state->mem_ctx,
1700                                             struct netr_NETLOGON_INFO_3);
1701                         if (info3 == NULL) {
1702                                 return WERR_NOT_ENOUGH_MEMORY;
1703                         }
1704                         state->r.out.query->info3 = info3;
1705                         return WERR_OK;
1706
1707                 default:
1708                         return WERR_INVALID_PARAMETER;
1709                 }
1710         }
1711
1712         /*
1713          * Some validations are done before the access check
1714          * and some after the access check
1715          */
1716         security_level = security_session_user_level(session_info, NULL);
1717         if (security_level < SECURITY_ADMINISTRATOR) {
1718                 return WERR_ACCESS_DENIED;
1719         }
1720
1721         if (state->_r.l2 != NULL) {
1722                 /*
1723                  * netr_LogonControl2
1724                  */
1725                 if (state->r.in.level == 0x00000004) {
1726                         return WERR_INVALID_LEVEL;
1727                 }
1728         }
1729
1730         switch (state->r.in.level) {
1731         case 0x00000001:
1732                 break;
1733
1734         case 0x00000002:
1735                 switch (state->r.in.function_code) {
1736                 case NETLOGON_CONTROL_REDISCOVER:
1737                 case NETLOGON_CONTROL_TC_QUERY:
1738                 case NETLOGON_CONTROL_TC_VERIFY:
1739                         break;
1740                 default:
1741                         return WERR_INVALID_PARAMETER;
1742                 }
1743
1744                 break;
1745
1746         case 0x00000003:
1747                 break;
1748
1749         case 0x00000004:
1750                 if (state->r.in.function_code != NETLOGON_CONTROL_FIND_USER) {
1751                         return WERR_INVALID_PARAMETER;
1752                 }
1753
1754                 break;
1755
1756         default:
1757                 return WERR_INVALID_LEVEL;
1758         }
1759
1760         switch (state->r.in.function_code) {
1761         case NETLOGON_CONTROL_REDISCOVER:
1762         case NETLOGON_CONTROL_TC_QUERY:
1763         case NETLOGON_CONTROL_TC_VERIFY:
1764                 if (state->r.in.level != 2) {
1765                         return WERR_INVALID_PARAMETER;
1766                 }
1767
1768                 if (state->r.in.data == NULL) {
1769                         return WERR_INVALID_PARAMETER;
1770                 }
1771
1772                 if (state->r.in.data->domain == NULL) {
1773                         return WERR_INVALID_PARAMETER;
1774                 }
1775
1776                 break;
1777
1778         case NETLOGON_CONTROL_CHANGE_PASSWORD:
1779                 if (state->r.in.level != 1) {
1780                         return WERR_INVALID_PARAMETER;
1781                 }
1782
1783                 if (state->r.in.data == NULL) {
1784                         return WERR_INVALID_PARAMETER;
1785                 }
1786
1787                 if (state->r.in.data->domain == NULL) {
1788                         return WERR_INVALID_PARAMETER;
1789                 }
1790
1791                 ok = lpcfg_is_my_domain_or_realm(lp_ctx,
1792                                                  state->r.in.data->domain);
1793                 if (!ok) {
1794                         struct ldb_context *sam_ctx;
1795
1796                         sam_ctx = samdb_connect(
1797                                 state,
1798                                 state->dce_call->event_ctx,
1799                                 lp_ctx,
1800                                 system_session(lp_ctx),
1801                                 state->dce_call->conn->remote_address,
1802                                 0);
1803                         if (sam_ctx == NULL) {
1804                                 return WERR_DS_UNAVAILABLE;
1805                         }
1806
1807                         /*
1808                          * Secrets for trusted domains can only be triggered on
1809                          * the PDC.
1810                          */
1811                         ok = samdb_is_pdc(sam_ctx);
1812                         TALLOC_FREE(sam_ctx);
1813                         if (!ok) {
1814                                 return WERR_INVALID_DOMAIN_ROLE;
1815                         }
1816                 }
1817
1818                 break;
1819         default:
1820                 return WERR_NOT_SUPPORTED;
1821         }
1822
1823         irpc_handle = irpc_binding_handle_by_name(state,
1824                                                   state->dce_call->msg_ctx,
1825                                                   "winbind_server",
1826                                                   &ndr_table_winbind);
1827         if (irpc_handle == NULL) {
1828                 DEBUG(0,("Failed to get binding_handle for winbind_server task\n"));
1829                 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
1830                 return WERR_SERVICE_NOT_FOUND;
1831         }
1832
1833         /*
1834          * 60 seconds timeout should be enough
1835          */
1836         dcerpc_binding_handle_set_timeout(irpc_handle, 60);
1837
1838         subreq = dcerpc_winbind_LogonControl_send(state,
1839                                                   state->dce_call->event_ctx,
1840                                                   irpc_handle,
1841                                                   state->r.in.function_code,
1842                                                   state->r.in.level,
1843                                                   state->r.in.data,
1844                                                   state->r.out.query);
1845         if (subreq == NULL) {
1846                 return WERR_NOT_ENOUGH_MEMORY;
1847         }
1848         state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
1849         tevent_req_set_callback(subreq,
1850                                 dcesrv_netr_LogonControl_base_done,
1851                                 state);
1852
1853         return WERR_OK;
1854 }
1855
1856 static void dcesrv_netr_LogonControl_base_done(struct tevent_req *subreq)
1857 {
1858         struct dcesrv_netr_LogonControl_base_state *state =
1859                 tevent_req_callback_data(subreq,
1860                 struct dcesrv_netr_LogonControl_base_state);
1861         NTSTATUS status;
1862
1863         status = dcerpc_winbind_LogonControl_recv(subreq, state->mem_ctx,
1864                                                   &state->r.out.result);
1865         TALLOC_FREE(subreq);
1866         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
1867                 state->r.out.result = WERR_TIMEOUT;
1868         } else if (!NT_STATUS_IS_OK(status)) {
1869                 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
1870                 DEBUG(0,(__location__ ": IRPC callback failed %s\n",
1871                          nt_errstr(status)));
1872         }
1873
1874         if (state->_r.l2ex != NULL) {
1875                 struct netr_LogonControl2Ex *r = state->_r.l2ex;
1876                 r->out.result = state->r.out.result;
1877         } else if (state->_r.l2 != NULL) {
1878                 struct netr_LogonControl2 *r = state->_r.l2;
1879                 r->out.result = state->r.out.result;
1880         } else if (state->_r.l != NULL) {
1881                 struct netr_LogonControl *r = state->_r.l;
1882                 r->out.result = state->r.out.result;
1883         }
1884
1885         status = dcesrv_reply(state->dce_call);
1886         if (!NT_STATUS_IS_OK(status)) {
1887                 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status)));
1888         }
1889 }
1890
1891 /*
1892   netr_LogonControl
1893 */
1894 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1895                        struct netr_LogonControl *r)
1896 {
1897         struct dcesrv_netr_LogonControl_base_state *state;
1898         WERROR werr;
1899
1900         state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonControl_base_state);
1901         if (state == NULL) {
1902                 return WERR_NOT_ENOUGH_MEMORY;
1903         }
1904
1905         state->dce_call = dce_call;
1906         state->mem_ctx = mem_ctx;
1907
1908         state->r.in.logon_server = r->in.logon_server;
1909         state->r.in.function_code = r->in.function_code;
1910         state->r.in.level = r->in.level;
1911         state->r.in.data = NULL;
1912         state->r.out.query = r->out.query;
1913
1914         state->_r.l = r;
1915
1916         werr = dcesrv_netr_LogonControl_base_call(state);
1917
1918         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1919                 return werr;
1920         }
1921
1922         return werr;
1923 }
1924
1925 /*
1926   netr_LogonControl2
1927 */
1928 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1929                        struct netr_LogonControl2 *r)
1930 {
1931         struct dcesrv_netr_LogonControl_base_state *state;
1932         WERROR werr;
1933
1934         state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonControl_base_state);
1935         if (state == NULL) {
1936                 return WERR_NOT_ENOUGH_MEMORY;
1937         }
1938
1939         state->dce_call = dce_call;
1940         state->mem_ctx = mem_ctx;
1941
1942         state->r.in.logon_server = r->in.logon_server;
1943         state->r.in.function_code = r->in.function_code;
1944         state->r.in.level = r->in.level;
1945         state->r.in.data = r->in.data;
1946         state->r.out.query = r->out.query;
1947
1948         state->_r.l2 = r;
1949
1950         werr = dcesrv_netr_LogonControl_base_call(state);
1951
1952         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1953                 return werr;
1954         }
1955
1956         return werr;
1957 }
1958
1959 /*
1960   netr_LogonControl2Ex
1961 */
1962 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1963                        struct netr_LogonControl2Ex *r)
1964 {
1965         struct dcesrv_netr_LogonControl_base_state *state;
1966         WERROR werr;
1967
1968         state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonControl_base_state);
1969         if (state == NULL) {
1970                 return WERR_NOT_ENOUGH_MEMORY;
1971         }
1972
1973         state->dce_call = dce_call;
1974         state->mem_ctx = mem_ctx;
1975
1976         state->r = *r;
1977         state->_r.l2ex = r;
1978
1979         werr = dcesrv_netr_LogonControl_base_call(state);
1980
1981         if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1982                 return werr;
1983         }
1984
1985         return werr;
1986 }
1987
1988 static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
1989                                          struct ldb_context *sam_ctx,
1990                                          struct netr_DomainTrustList *trusts,
1991                                          uint32_t trust_flags);
1992
1993 /*
1994   netr_GetAnyDCName
1995 */
1996 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1997                        struct netr_GetAnyDCName *r)
1998 {
1999         struct auth_session_info *session_info =
2000                 dcesrv_call_session_info(dce_call);
2001         struct netr_DomainTrustList *trusts;
2002         struct ldb_context *sam_ctx;
2003         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
2004         uint32_t i;
2005         WERROR werr;
2006
2007         *r->out.dcname = NULL;
2008
2009         if ((r->in.domainname == NULL) || (r->in.domainname[0] == '\0')) {
2010                 /* if the domainname parameter wasn't set assume our domain */
2011                 r->in.domainname = lpcfg_workgroup(lp_ctx);
2012         }
2013
2014         sam_ctx = samdb_connect(mem_ctx,
2015                                 dce_call->event_ctx,
2016                                 lp_ctx,
2017                                 session_info,
2018                                 dce_call->conn->remote_address,
2019                                 0);
2020         if (sam_ctx == NULL) {
2021                 return WERR_DS_UNAVAILABLE;
2022         }
2023
2024         if (strcasecmp(r->in.domainname, lpcfg_workgroup(lp_ctx)) == 0) {
2025                 /* well we asked for a DC of our own domain */
2026                 if (samdb_is_pdc(sam_ctx)) {
2027                         /* we are the PDC of the specified domain */
2028                         return WERR_NO_SUCH_DOMAIN;
2029                 }
2030
2031                 *r->out.dcname = talloc_asprintf(mem_ctx, "\\%s",
2032                                                 lpcfg_netbios_name(lp_ctx));
2033                 W_ERROR_HAVE_NO_MEMORY(*r->out.dcname);
2034
2035                 return WERR_OK;
2036         }
2037
2038         /* Okay, now we have to consider the trusted domains */
2039
2040         trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList);
2041         W_ERROR_HAVE_NO_MEMORY(trusts);
2042
2043         trusts->count = 0;
2044
2045         werr = fill_trusted_domains_array(mem_ctx, sam_ctx, trusts,
2046                                           NETR_TRUST_FLAG_INBOUND
2047                                           | NETR_TRUST_FLAG_OUTBOUND);
2048         W_ERROR_NOT_OK_RETURN(werr);
2049
2050         for (i = 0; i < trusts->count; i++) {
2051                 if (strcasecmp(r->in.domainname, trusts->array[i].netbios_name) == 0) {
2052                         /* FIXME: Here we need to find a DC for the specified
2053                          * trusted domain. */
2054
2055                         /* return WERR_OK; */
2056                         return WERR_NO_SUCH_DOMAIN;
2057                 }
2058         }
2059
2060         return WERR_NO_SUCH_DOMAIN;
2061 }
2062
2063
2064 /*
2065   netr_DatabaseRedo
2066 */
2067 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2068                        struct netr_DatabaseRedo *r)
2069 {
2070         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2071 }
2072
2073
2074 /*
2075   netr_NetrEnumerateTrustedDomains
2076 */
2077 static NTSTATUS dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2078                        struct netr_NetrEnumerateTrustedDomains *r)
2079 {
2080         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2081 }
2082
2083
2084 /*
2085   netr_LogonGetCapabilities
2086 */
2087 static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2088                        struct netr_LogonGetCapabilities *r)
2089 {
2090         struct netlogon_creds_CredentialState *creds;
2091         NTSTATUS status;
2092
2093         status = dcesrv_netr_creds_server_step_check(dce_call,
2094                                                      mem_ctx,
2095                                                      r->in.computer_name,
2096                                                      r->in.credential,
2097                                                      r->out.return_authenticator,
2098                                                      &creds);
2099         if (!NT_STATUS_IS_OK(status)) {
2100                 DEBUG(0,(__location__ " Bad credentials - error\n"));
2101         }
2102         NT_STATUS_NOT_OK_RETURN(status);
2103
2104         if (r->in.query_level != 1) {
2105                 return NT_STATUS_NOT_SUPPORTED;
2106         }
2107
2108         r->out.capabilities->server_capabilities = creds->negotiate_flags;
2109
2110         return NT_STATUS_OK;
2111 }
2112
2113
2114 /*
2115   netr_NETRLOGONSETSERVICEBITS
2116 */
2117 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2118                        struct netr_NETRLOGONSETSERVICEBITS *r)
2119 {
2120         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2121 }
2122
2123
2124 /*
2125   netr_LogonGetTrustRid
2126 */
2127 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2128                        struct netr_LogonGetTrustRid *r)
2129 {
2130         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2131 }
2132
2133
2134 /*
2135   netr_NETRLOGONCOMPUTESERVERDIGEST
2136 */
2137 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2138                        struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
2139 {
2140         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2141 }
2142
2143
2144 /*
2145   netr_NETRLOGONCOMPUTECLIENTDIGEST
2146 */
2147 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2148                        struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
2149 {
2150         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2151 }
2152
2153
2154
2155 /*
2156   netr_DsRGetSiteName
2157 */
2158 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2159                                   struct netr_DsRGetSiteName *r)
2160 {
2161         struct auth_session_info *session_info =
2162                 dcesrv_call_session_info(dce_call);
2163         struct ldb_context *sam_ctx;
2164         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
2165
2166         sam_ctx = samdb_connect(mem_ctx,
2167                                 dce_call->event_ctx,
2168                                 lp_ctx,
2169                                 session_info,
2170                                 dce_call->conn->remote_address,
2171                                 0);
2172         if (sam_ctx == NULL) {
2173                 return WERR_DS_UNAVAILABLE;
2174         }
2175
2176         /*
2177          * We assume to be a DC when we get called over NETLOGON. Hence we
2178          * get our site name always by using "samdb_server_site_name()"
2179          * and not "samdb_client_site_name()".
2180          */
2181         *r->out.site = samdb_server_site_name(sam_ctx, mem_ctx);
2182         W_ERROR_HAVE_NO_MEMORY(*r->out.site);
2183
2184         return WERR_OK;
2185 }
2186
2187
2188 /*
2189   fill in a netr_OneDomainInfo from our own domain/forest
2190 */
2191 static NTSTATUS fill_our_one_domain_info(TALLOC_CTX *mem_ctx,
2192                                 const struct lsa_TrustDomainInfoInfoEx *our_tdo,
2193                                 struct GUID domain_guid,
2194                                 struct netr_OneDomainInfo *info,
2195                                 bool is_trust_list)
2196 {
2197         ZERO_STRUCTP(info);
2198
2199         if (is_trust_list) {
2200                 struct netr_trust_extension *tei = NULL;
2201
2202                 /* w2k8 only fills this on trusted domains */
2203                 tei = talloc_zero(mem_ctx, struct netr_trust_extension);
2204                 if (tei == NULL) {
2205                         return NT_STATUS_NO_MEMORY;
2206                 }
2207                 tei->flags |= NETR_TRUST_FLAG_PRIMARY;
2208
2209                 /*
2210                  * We're always within a native forest
2211                  */
2212                 tei->flags |= NETR_TRUST_FLAG_IN_FOREST;
2213                 tei->flags |= NETR_TRUST_FLAG_NATIVE;
2214
2215                 /* For now we assume we're always the tree root */
2216                 tei->flags |= NETR_TRUST_FLAG_TREEROOT;
2217                 tei->parent_index = 0;
2218
2219                 tei->trust_type = our_tdo->trust_type;
2220                 /*
2221                  * This needs to be 0 instead of our_tdo->trust_attributes
2222                  * It means LSA_TRUST_ATTRIBUTE_WITHIN_FOREST won't
2223                  * be set, while NETR_TRUST_FLAG_IN_FOREST is set above.
2224                  */
2225                 tei->trust_attributes = 0;
2226
2227                 info->trust_extension.info = tei;
2228                 info->trust_extension.length = 16;
2229         }
2230
2231         if (is_trust_list) {
2232                 info->dns_domainname.string = our_tdo->domain_name.string;
2233
2234                 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
2235                 info->dns_forestname.string = NULL;
2236         } else {
2237                 info->dns_domainname.string = talloc_asprintf(mem_ctx, "%s.",
2238                                                 our_tdo->domain_name.string);
2239                 if (info->dns_domainname.string == NULL) {
2240                         return NT_STATUS_NO_MEMORY;
2241                 }
2242
2243                 info->dns_forestname.string = info->dns_domainname.string;
2244         }
2245
2246         info->domainname.string = our_tdo->netbios_name.string;
2247         info->domain_sid = our_tdo->sid;
2248         info->domain_guid = domain_guid;
2249
2250         return NT_STATUS_OK;
2251 }
2252
2253 /*
2254   fill in a netr_OneDomainInfo from a trust tdo
2255 */
2256 static NTSTATUS fill_trust_one_domain_info(TALLOC_CTX *mem_ctx,
2257                                 struct GUID domain_guid,
2258                                 const struct lsa_TrustDomainInfoInfoEx *tdo,
2259                                 struct netr_OneDomainInfo *info)
2260 {
2261         struct netr_trust_extension *tei = NULL;
2262
2263         ZERO_STRUCTP(info);
2264
2265         /* w2k8 only fills this on trusted domains */
2266         tei = talloc_zero(mem_ctx, struct netr_trust_extension);
2267         if (tei == NULL) {
2268                 return NT_STATUS_NO_MEMORY;
2269         }
2270
2271         if (tdo->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
2272                 tei->flags |= NETR_TRUST_FLAG_INBOUND;
2273         }
2274         if (tdo->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) {
2275                 tei->flags |= NETR_TRUST_FLAG_OUTBOUND;
2276         }
2277         if (tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
2278                 tei->flags |= NETR_TRUST_FLAG_IN_FOREST;
2279         }
2280
2281         /*
2282          * TODO: once we support multiple domains within our forest,
2283          * we need to fill this correct (or let the caller do it
2284          * for all domains marked with NETR_TRUST_FLAG_IN_FOREST).
2285          */
2286         tei->parent_index = 0;
2287
2288         tei->trust_type = tdo->trust_type;
2289         tei->trust_attributes = tdo->trust_attributes;
2290
2291         info->trust_extension.info = tei;
2292         info->trust_extension.length = 16;
2293
2294         info->domainname.string = tdo->netbios_name.string;
2295         if (tdo->trust_type != LSA_TRUST_TYPE_DOWNLEVEL) {
2296                 info->dns_domainname.string = tdo->domain_name.string;
2297         } else {
2298                 info->dns_domainname.string = NULL;
2299         }
2300         info->domain_sid = tdo->sid;
2301         info->domain_guid = domain_guid;
2302
2303         /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
2304         info->dns_forestname.string = NULL;
2305
2306         return NT_STATUS_OK;
2307 }
2308
2309 /*
2310   netr_LogonGetDomainInfo
2311   this is called as part of the ADS domain logon procedure.
2312
2313   It has an important role in convaying details about the client, such
2314   as Operating System, Version, Service Pack etc.
2315 */
2316 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call,
2317         TALLOC_CTX *mem_ctx, struct netr_LogonGetDomainInfo *r)
2318 {
2319         struct netlogon_creds_CredentialState *creds;
2320         const char * const trusts_attrs[] = {
2321                 "securityIdentifier",
2322                 "flatName",
2323                 "trustPartner",
2324                 "trustAttributes",
2325                 "trustDirection",
2326                 "trustType",
2327                 NULL
2328         };
2329         const char * const attrs2[] = { "sAMAccountName", "dNSHostName",
2330                 "msDS-SupportedEncryptionTypes", NULL };
2331         const char *sam_account_name, *old_dns_hostname, *prefix1, *prefix2;
2332         struct ldb_context *sam_ctx;
2333         const struct GUID *our_domain_guid = NULL;
2334         struct lsa_TrustDomainInfoInfoEx *our_tdo = NULL;
2335         struct ldb_message **res1, *new_msg;
2336         struct ldb_result *trusts_res = NULL;
2337         struct ldb_dn *workstation_dn;
2338         struct netr_DomainInformation *domain_info;
2339         struct netr_LsaPolicyInformation *lsa_policy_info;
2340         uint32_t default_supported_enc_types = 0xFFFFFFFF;
2341         bool update_dns_hostname = true;
2342         int ret, i;
2343         NTSTATUS status;
2344
2345         status = dcesrv_netr_creds_server_step_check(dce_call,
2346                                                      mem_ctx,
2347                                                      r->in.computer_name,
2348                                                      r->in.credential,
2349                                                      r->out.return_authenticator,
2350                                                      &creds);
2351         if (!NT_STATUS_IS_OK(status)) {
2352                 char* local  = NULL;
2353                 char* remote = NULL;
2354                 TALLOC_CTX *frame = talloc_stackframe();
2355                 remote = tsocket_address_string(dce_call->conn->remote_address,
2356                                                 frame);
2357                 local  = tsocket_address_string(dce_call->conn->local_address,
2358                                                 frame);
2359                 DBG_ERR(("Bad credentials - "
2360                          "computer[%s] remote[%s] local[%s]\n"),
2361                         log_escape(frame, r->in.computer_name),
2362                         remote,
2363                         local);
2364                 talloc_free(frame);
2365         }
2366         NT_STATUS_NOT_OK_RETURN(status);
2367
2368         sam_ctx = samdb_connect(mem_ctx,
2369                                 dce_call->event_ctx,
2370                                 dce_call->conn->dce_ctx->lp_ctx,
2371                                 system_session(dce_call->conn->dce_ctx->lp_ctx),
2372                                 dce_call->conn->remote_address,
2373                                 0);
2374         if (sam_ctx == NULL) {
2375                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
2376         }
2377
2378         switch (r->in.level) {
2379         case 1: /* Domain information */
2380
2381                 if (r->in.query->workstation_info == NULL) {
2382                         return NT_STATUS_INVALID_PARAMETER;
2383                 }
2384
2385                 /* Prepares the workstation DN */
2386                 workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
2387                                                 dom_sid_string(mem_ctx, creds->sid));
2388                 NT_STATUS_HAVE_NO_MEMORY(workstation_dn);
2389
2390                 /* Lookup for attributes in workstation object */
2391                 ret = gendb_search_dn(sam_ctx, mem_ctx, workstation_dn, &res1,
2392                                       attrs2);
2393                 if (ret != 1) {
2394                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2395                 }
2396
2397                 /* Gets the sam account name which is checked against the DNS
2398                  * hostname parameter. */
2399                 sam_account_name = ldb_msg_find_attr_as_string(res1[0],
2400                                                                "sAMAccountName",
2401                                                                NULL);
2402                 if (sam_account_name == NULL) {
2403                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2404                 }
2405
2406                 /*
2407                  * Checks that the sam account name without a possible "$"
2408                  * matches as prefix with the DNS hostname in the workstation
2409                  * info structure.
2410                  */
2411                 prefix1 = talloc_strndup(mem_ctx, sam_account_name,
2412                                          strcspn(sam_account_name, "$"));
2413                 NT_STATUS_HAVE_NO_MEMORY(prefix1);
2414                 if (r->in.query->workstation_info->dns_hostname != NULL) {
2415                         prefix2 = talloc_strndup(mem_ctx,
2416                                                  r->in.query->workstation_info->dns_hostname,
2417                                                  strcspn(r->in.query->workstation_info->dns_hostname, "."));
2418                         NT_STATUS_HAVE_NO_MEMORY(prefix2);
2419
2420                         if (strcasecmp(prefix1, prefix2) != 0) {
2421                                 update_dns_hostname = false;
2422                         }
2423                 } else {
2424                         update_dns_hostname = false;
2425                 }
2426
2427                 /* Gets the old DNS hostname */
2428                 old_dns_hostname = ldb_msg_find_attr_as_string(res1[0],
2429                                                                "dNSHostName",
2430                                                                NULL);
2431
2432                 /*
2433                  * Updates the DNS hostname when the client wishes that the
2434                  * server should handle this for him
2435                  * ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set). And this is
2436                  * obviously only checked when we do already have a
2437                  * "dNSHostName".
2438                  * See MS-NRPC section 3.5.4.3.9
2439                  */
2440                 if ((old_dns_hostname != NULL) &&
2441                     (r->in.query->workstation_info->workstation_flags
2442                     & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) {
2443                         update_dns_hostname = false;
2444                 }
2445
2446                 /* Gets host information and put them into our directory */
2447
2448                 new_msg = ldb_msg_new(mem_ctx);
2449                 NT_STATUS_HAVE_NO_MEMORY(new_msg);
2450
2451                 new_msg->dn = workstation_dn;
2452
2453                 /* Sets the OS name */
2454
2455                 if (r->in.query->workstation_info->os_name.string == NULL) {
2456                         return NT_STATUS_INVALID_PARAMETER;
2457                 }
2458
2459                 ret = ldb_msg_add_string(new_msg, "operatingSystem",
2460                                          r->in.query->workstation_info->os_name.string);
2461                 if (ret != LDB_SUCCESS) {
2462                         return NT_STATUS_NO_MEMORY;
2463                 }
2464
2465                 /*
2466                  * Sets information from "os_version". On an empty structure
2467                  * the values are cleared.
2468                  */
2469                 if (r->in.query->workstation_info->os_version.os != NULL) {
2470                         struct netr_OsVersionInfoEx *os_version;
2471                         const char *os_version_str;
2472
2473                         os_version = &r->in.query->workstation_info->os_version.os->os;
2474
2475                         if (os_version->CSDVersion == NULL) {
2476                                 return NT_STATUS_INVALID_PARAMETER;
2477                         }
2478
2479                         os_version_str = talloc_asprintf(new_msg, "%u.%u (%u)",
2480                                                          os_version->MajorVersion,
2481                                                          os_version->MinorVersion,
2482                                                          os_version->BuildNumber);
2483                         NT_STATUS_HAVE_NO_MEMORY(os_version_str);
2484
2485                         ret = ldb_msg_add_string(new_msg,
2486                                                  "operatingSystemServicePack",
2487                                                  os_version->CSDVersion);
2488                         if (ret != LDB_SUCCESS) {
2489                                 return NT_STATUS_NO_MEMORY;
2490                         }
2491
2492                         ret = ldb_msg_add_string(new_msg,
2493                                                  "operatingSystemVersion",
2494                                                  os_version_str);
2495                         if (ret != LDB_SUCCESS) {
2496                                 return NT_STATUS_NO_MEMORY;
2497                         }
2498                 } else {
2499                         ret = samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
2500                                                    "operatingSystemServicePack");
2501                         if (ret != LDB_SUCCESS) {
2502                                 return NT_STATUS_NO_MEMORY;
2503                         }
2504
2505                         ret = samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
2506                                                    "operatingSystemVersion");
2507                         if (ret != LDB_SUCCESS) {
2508                                 return NT_STATUS_NO_MEMORY;
2509                         }
2510                 }
2511
2512                 /*
2513                  * If the boolean "update_dns_hostname" remained true, then we
2514                  * are fine to start the update.
2515                  */
2516                 if (update_dns_hostname) {
2517                         ret = ldb_msg_add_string(new_msg,
2518                                                  "dNSHostname",
2519                                                  r->in.query->workstation_info->dns_hostname);
2520                         if (ret != LDB_SUCCESS) {
2521                                 return NT_STATUS_NO_MEMORY;
2522                         }
2523
2524                         /* This manual "servicePrincipalName" generation is
2525                          * still needed! Since the update in the samldb LDB
2526                          * module does only work if the entries already exist
2527                          * which isn't always the case. */
2528                         ret = ldb_msg_add_string(new_msg,
2529                                                  "servicePrincipalName",
2530                                                  talloc_asprintf(new_msg, "HOST/%s",
2531                                                  r->in.computer_name));
2532                         if (ret != LDB_SUCCESS) {
2533                                 return NT_STATUS_NO_MEMORY;
2534                         }
2535
2536                         ret = ldb_msg_add_string(new_msg,
2537                                                  "servicePrincipalName",
2538                                                  talloc_asprintf(new_msg, "HOST/%s",
2539                                                  r->in.query->workstation_info->dns_hostname));
2540                         if (ret != LDB_SUCCESS) {
2541                                 return NT_STATUS_NO_MEMORY;
2542                         }
2543                 }
2544
2545                 if (dsdb_replace(sam_ctx, new_msg, 0) != LDB_SUCCESS) {
2546                         DEBUG(3,("Impossible to update samdb: %s\n",
2547                                 ldb_errstring(sam_ctx)));
2548                 }
2549
2550                 talloc_free(new_msg);
2551
2552                 /* Writes back the domain information */
2553
2554                 our_domain_guid = samdb_domain_guid(sam_ctx);
2555                 if (our_domain_guid == NULL) {
2556                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
2557                 }
2558
2559                 status = dsdb_trust_local_tdo_info(mem_ctx, sam_ctx, &our_tdo);
2560                 if (!NT_STATUS_IS_OK(status)) {
2561                         return status;
2562                 }
2563
2564                 status = dsdb_trust_search_tdos(sam_ctx,
2565                                                 NULL, /* exclude */
2566                                                 trusts_attrs,
2567                                                 mem_ctx,
2568                                                 &trusts_res);
2569                 if (!NT_STATUS_IS_OK(status)) {
2570                         return status;
2571                 }
2572
2573                 domain_info = talloc(mem_ctx, struct netr_DomainInformation);
2574                 NT_STATUS_HAVE_NO_MEMORY(domain_info);
2575
2576                 ZERO_STRUCTP(domain_info);
2577
2578                 /* Informations about the local and trusted domains */
2579
2580                 status = fill_our_one_domain_info(mem_ctx,
2581                                                   our_tdo,
2582                                                   *our_domain_guid,
2583                                                   &domain_info->primary_domain,
2584                                                   false);
2585                 if (!NT_STATUS_IS_OK(status)) {
2586                         return status;
2587                 }
2588
2589                 domain_info->trusted_domain_count = trusts_res->count + 1;
2590                 domain_info->trusted_domains = talloc_zero_array(mem_ctx,
2591                         struct netr_OneDomainInfo,
2592                         domain_info->trusted_domain_count);
2593                 NT_STATUS_HAVE_NO_MEMORY(domain_info->trusted_domains);
2594
2595                 for (i=0; i < trusts_res->count; i++) {
2596                         struct netr_OneDomainInfo *o =
2597                                 &domain_info->trusted_domains[i];
2598                         /* we can't know the guid of trusts outside our forest */
2599                         struct GUID trust_domain_guid = GUID_zero();
2600                         struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
2601
2602                         status = dsdb_trust_parse_tdo_info(mem_ctx,
2603                                                            trusts_res->msgs[i],
2604                                                            &tdo);
2605                         if (!NT_STATUS_IS_OK(status)) {
2606                                 return status;
2607                         }
2608
2609                         status = fill_trust_one_domain_info(mem_ctx,
2610                                                             trust_domain_guid,
2611                                                             tdo,
2612                                                             o);
2613                         if (!NT_STATUS_IS_OK(status)) {
2614                                 return status;
2615                         }
2616                 }
2617
2618                 status = fill_our_one_domain_info(mem_ctx,
2619                                                   our_tdo,
2620                                                   *our_domain_guid,
2621                                                   &domain_info->trusted_domains[i],
2622                                                   true);
2623                 if (!NT_STATUS_IS_OK(status)) {
2624                         return status;
2625                 }
2626
2627                 /* Sets the supported encryption types */
2628                 domain_info->supported_enc_types = ldb_msg_find_attr_as_uint(res1[0],
2629                         "msDS-SupportedEncryptionTypes",
2630                         default_supported_enc_types);
2631
2632                 /* Other host domain information */
2633
2634                 lsa_policy_info = talloc(mem_ctx,
2635                         struct netr_LsaPolicyInformation);
2636                 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
2637                 ZERO_STRUCTP(lsa_policy_info);
2638
2639                 domain_info->lsa_policy = *lsa_policy_info;
2640
2641                 /* The DNS hostname is only returned back when there is a chance
2642                  * for a change. */
2643                 if ((r->in.query->workstation_info->workstation_flags
2644                     & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) {
2645                         domain_info->dns_hostname.string = old_dns_hostname;
2646                 } else {
2647                         domain_info->dns_hostname.string = NULL;
2648                 }
2649
2650                 domain_info->workstation_flags =
2651                         r->in.query->workstation_info->workstation_flags & (
2652                         NETR_WS_FLAG_HANDLES_SPN_UPDATE | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS);
2653
2654                 r->out.info->domain_info = domain_info;
2655         break;
2656         case 2: /* LSA policy information - not used at the moment */
2657                 lsa_policy_info = talloc(mem_ctx,
2658                         struct netr_LsaPolicyInformation);
2659                 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
2660                 ZERO_STRUCTP(lsa_policy_info);
2661
2662                 r->out.info->lsa_policy_info = lsa_policy_info;
2663         break;
2664         default:
2665                 return NT_STATUS_INVALID_LEVEL;
2666         break;
2667         }
2668
2669         return NT_STATUS_OK;
2670 }
2671
2672
2673 /*
2674   netr_ServerPasswordGet
2675 */
2676 static NTSTATUS dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2677                        struct netr_ServerPasswordGet *r)
2678 {
2679         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2680 }
2681
2682 static bool sam_rodc_access_check(struct ldb_context *sam_ctx,
2683                                   TALLOC_CTX *mem_ctx,
2684                                   struct dom_sid *user_sid,
2685                                   struct ldb_dn *obj_dn)
2686 {
2687         const char *rodc_attrs[] = { "msDS-KrbTgtLink", "msDS-NeverRevealGroup", "msDS-RevealOnDemandGroup", "objectGUID", NULL };
2688         const char *obj_attrs[] = { "tokenGroups", "objectSid", "UserAccountControl", "msDS-KrbTgtLinkBL", NULL };
2689         struct ldb_dn *rodc_dn;
2690         int ret;
2691         struct ldb_result *rodc_res = NULL, *obj_res = NULL;
2692         const struct dom_sid *additional_sids[] = { NULL, NULL };
2693         WERROR werr;
2694         struct dom_sid *object_sid;
2695         const struct dom_sid **never_reveal_sids, **reveal_sids, **token_sids;
2696
2697         rodc_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
2698                                  dom_sid_string(mem_ctx, user_sid));
2699         if (!ldb_dn_validate(rodc_dn)) goto denied;
2700
2701         /* do the two searches we need */
2702         ret = dsdb_search_dn(sam_ctx, mem_ctx, &rodc_res, rodc_dn, rodc_attrs,
2703                              DSDB_SEARCH_SHOW_EXTENDED_DN);
2704         if (ret != LDB_SUCCESS || rodc_res->count != 1) goto denied;
2705
2706         ret = dsdb_search_dn(sam_ctx, mem_ctx, &obj_res, obj_dn, obj_attrs, 0);
2707         if (ret != LDB_SUCCESS || obj_res->count != 1) goto denied;
2708
2709         object_sid = samdb_result_dom_sid(mem_ctx, obj_res->msgs[0], "objectSid");
2710
2711         additional_sids[0] = object_sid;
2712
2713         werr = samdb_result_sid_array_dn(sam_ctx, rodc_res->msgs[0],
2714                                          mem_ctx, "msDS-NeverRevealGroup", &never_reveal_sids);
2715         if (!W_ERROR_IS_OK(werr)) {
2716                 goto denied;
2717         }
2718
2719         werr = samdb_result_sid_array_dn(sam_ctx, rodc_res->msgs[0],
2720                                          mem_ctx, "msDS-RevealOnDemandGroup", &reveal_sids);
2721         if (!W_ERROR_IS_OK(werr)) {
2722                 goto denied;
2723         }
2724
2725         /*
2726          * The SID list needs to include itself as well as the tokenGroups.
2727          *
2728          * TODO determine if sIDHistory is required for this check
2729          */
2730         werr = samdb_result_sid_array_ndr(sam_ctx, obj_res->msgs[0],
2731                                           mem_ctx, "tokenGroups", &token_sids,
2732                                           additional_sids, 1);
2733         if (!W_ERROR_IS_OK(werr) || token_sids==NULL) {
2734                 goto denied;
2735         }
2736
2737         if (never_reveal_sids &&
2738             sid_list_match(token_sids, never_reveal_sids)) {
2739                 goto denied;
2740         }
2741
2742         if (reveal_sids &&
2743             sid_list_match(token_sids, reveal_sids)) {
2744                 goto allowed;
2745         }
2746
2747 denied:
2748         return false;
2749 allowed:
2750         return true;
2751
2752 }
2753
2754 /*
2755   netr_NetrLogonSendToSam
2756 */
2757 static NTSTATUS dcesrv_netr_NetrLogonSendToSam(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2758                                                struct netr_NetrLogonSendToSam *r)
2759 {
2760         struct netlogon_creds_CredentialState *creds;
2761         struct ldb_context *sam_ctx;
2762         NTSTATUS nt_status;
2763         DATA_BLOB decrypted_blob;
2764         enum ndr_err_code ndr_err;
2765         struct netr_SendToSamBase base_msg = { 0 };
2766
2767         nt_status = dcesrv_netr_creds_server_step_check(dce_call,
2768                                                         mem_ctx,
2769                                                         r->in.computer_name,
2770                                                         r->in.credential,
2771                                                         r->out.return_authenticator,
2772                                                         &creds);
2773
2774         NT_STATUS_NOT_OK_RETURN(nt_status);
2775
2776         switch (creds->secure_channel_type) {
2777         case SEC_CHAN_BDC:
2778         case SEC_CHAN_RODC:
2779                 break;
2780         case SEC_CHAN_WKSTA:
2781         case SEC_CHAN_DNS_DOMAIN:
2782         case SEC_CHAN_DOMAIN:
2783         case SEC_CHAN_NULL:
2784                 return NT_STATUS_INVALID_PARAMETER;
2785         default:
2786                 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
2787                           creds->secure_channel_type));
2788                 return NT_STATUS_INVALID_PARAMETER;
2789         }
2790
2791         sam_ctx = samdb_connect(mem_ctx,
2792                                 dce_call->event_ctx,
2793                                 dce_call->conn->dce_ctx->lp_ctx,
2794                                 system_session(dce_call->conn->dce_ctx->lp_ctx),
2795                                 dce_call->conn->remote_address,
2796                                 0);
2797         if (sam_ctx == NULL) {
2798                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
2799         }
2800
2801         /* Buffer is meant to be 16-bit aligned */
2802         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
2803                 netlogon_creds_aes_decrypt(creds, r->in.opaque_buffer, r->in.buffer_len);
2804         } else {
2805                 netlogon_creds_arcfour_crypt(creds, r->in.opaque_buffer, r->in.buffer_len);
2806         }
2807
2808         decrypted_blob.data = r->in.opaque_buffer;
2809         decrypted_blob.length = r->in.buffer_len;
2810
2811         ndr_err = ndr_pull_struct_blob(&decrypted_blob, mem_ctx, &base_msg,
2812                                        (ndr_pull_flags_fn_t)ndr_pull_netr_SendToSamBase);
2813
2814         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2815                 /* We only partially implement SendToSam */
2816                 return NT_STATUS_NOT_IMPLEMENTED;
2817         }
2818
2819         /* Now 'send' to SAM */
2820         switch (base_msg.message_type) {
2821         case SendToSamResetBadPasswordCount:
2822         {
2823                 struct ldb_message *msg = ldb_msg_new(mem_ctx);
2824                 struct ldb_dn *dn = NULL;
2825                 int ret = 0;
2826
2827
2828                 ret = ldb_transaction_start(sam_ctx);
2829                 if (ret != LDB_SUCCESS) {
2830                         return NT_STATUS_INTERNAL_ERROR;
2831                 }
2832
2833                 ret = dsdb_find_dn_by_guid(sam_ctx,
2834                                            mem_ctx,
2835                                            &base_msg.message.reset_bad_password.guid,
2836                                            0,
2837                                            &dn);
2838                 if (ret != LDB_SUCCESS) {
2839                         ldb_transaction_cancel(sam_ctx);
2840                         return NT_STATUS_INVALID_PARAMETER;
2841                 }
2842
2843                 if (creds->secure_channel_type == SEC_CHAN_RODC &&
2844                     !sam_rodc_access_check(sam_ctx, mem_ctx, creds->sid, dn)) {
2845                         DEBUG(1, ("Client asked to reset bad password on "
2846                                   "an arbitrary user: %s\n",
2847                                   ldb_dn_get_linearized(dn)));
2848                         ldb_transaction_cancel(sam_ctx);
2849                         return NT_STATUS_INVALID_PARAMETER;
2850                 }
2851
2852                 msg->dn = dn;
2853
2854                 ret = samdb_msg_add_int(sam_ctx, mem_ctx, msg, "badPwdCount", 0);
2855                 if (ret != LDB_SUCCESS) {
2856                         ldb_transaction_cancel(sam_ctx);
2857                         return NT_STATUS_INVALID_PARAMETER;
2858                 }
2859
2860                 ret = dsdb_replace(sam_ctx, msg, 0);
2861                 if (ret != LDB_SUCCESS) {
2862                         ldb_transaction_cancel(sam_ctx);
2863                         return NT_STATUS_INVALID_PARAMETER;
2864                 }
2865
2866                 ret = ldb_transaction_commit(sam_ctx);
2867                 if (ret != LDB_SUCCESS) {
2868                         ldb_transaction_cancel(sam_ctx);
2869                         return NT_STATUS_INTERNAL_ERROR;
2870                 }
2871
2872                 break;
2873         }
2874         default:
2875                 return NT_STATUS_NOT_IMPLEMENTED;
2876         }
2877
2878         return NT_STATUS_OK;
2879 }
2880
2881 struct dcesrv_netr_DsRGetDCName_base_state {
2882         struct dcesrv_call_state *dce_call;
2883         TALLOC_CTX *mem_ctx;
2884
2885         struct netr_DsRGetDCNameEx2 r;
2886         const char *client_site;
2887
2888         struct {
2889                 struct netr_DsRGetDCName *dc;
2890                 struct netr_DsRGetDCNameEx *dcex;
2891                 struct netr_DsRGetDCNameEx2 *dcex2;
2892         } _r;
2893 };
2894
2895 static void dcesrv_netr_DsRGetDCName_base_done(struct tevent_req *subreq);
2896
2897 static WERROR dcesrv_netr_DsRGetDCName_base_call(struct dcesrv_netr_DsRGetDCName_base_state *state)
2898 {
2899         struct dcesrv_call_state *dce_call = state->dce_call;
2900         struct auth_session_info *session_info =
2901                 dcesrv_call_session_info(dce_call);
2902         TALLOC_CTX *mem_ctx = state->mem_ctx;
2903         struct netr_DsRGetDCNameEx2 *r = &state->r;
2904         struct ldb_context *sam_ctx;
2905         struct netr_DsRGetDCNameInfo *info;
2906         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
2907         const struct tsocket_address *local_address;
2908         char *local_addr = NULL;
2909         const struct tsocket_address *remote_address;
2910         char *remote_addr = NULL;
2911         const char *server_site_name;
2912         char *guid_str;
2913         struct netlogon_samlogon_response response;
2914         NTSTATUS status;
2915         const char *dc_name = NULL;
2916         const char *domain_name = NULL;
2917         const char *pdc_ip;
2918         bool different_domain = true;
2919
2920         ZERO_STRUCTP(r->out.info);
2921
2922         sam_ctx = samdb_connect(state,
2923                                 dce_call->event_ctx,
2924                                 lp_ctx,
2925                                 session_info,
2926                                 dce_call->conn->remote_address,
2927                                 0);
2928         if (sam_ctx == NULL) {
2929                 return WERR_DS_UNAVAILABLE;
2930         }
2931
2932         local_address = dcesrv_connection_get_local_address(dce_call->conn);
2933         if (tsocket_address_is_inet(local_address, "ip")) {
2934                 local_addr = tsocket_address_inet_addr_string(local_address, state);
2935                 W_ERROR_HAVE_NO_MEMORY(local_addr);
2936         }
2937
2938         remote_address = dcesrv_connection_get_remote_address(dce_call->conn);
2939         if (tsocket_address_is_inet(remote_address, "ip")) {
2940                 remote_addr = tsocket_address_inet_addr_string(remote_address, state);
2941                 W_ERROR_HAVE_NO_MEMORY(remote_addr);
2942         }
2943
2944         /* "server_unc" is ignored by w2k3 */
2945
2946         if (r->in.flags & ~(DSGETDC_VALID_FLAGS)) {
2947                 return WERR_INVALID_FLAGS;
2948         }
2949
2950         if (r->in.flags & DS_GC_SERVER_REQUIRED &&
2951             r->in.flags & DS_PDC_REQUIRED &&
2952             r->in.flags & DS_KDC_REQUIRED) {
2953                 return WERR_INVALID_FLAGS;
2954         }
2955         if (r->in.flags & DS_IS_FLAT_NAME &&
2956             r->in.flags & DS_IS_DNS_NAME) {
2957                 return WERR_INVALID_FLAGS;
2958         }
2959         if (r->in.flags & DS_RETURN_DNS_NAME &&
2960             r->in.flags & DS_RETURN_FLAT_NAME) {
2961                 return WERR_INVALID_FLAGS;
2962         }
2963         if (r->in.flags & DS_DIRECTORY_SERVICE_REQUIRED &&
2964             r->in.flags & DS_DIRECTORY_SERVICE_6_REQUIRED) {
2965                 return WERR_INVALID_FLAGS;
2966         }
2967
2968         if (r->in.flags & DS_GOOD_TIMESERV_PREFERRED &&
2969             r->in.flags &
2970             (DS_DIRECTORY_SERVICE_REQUIRED |
2971              DS_DIRECTORY_SERVICE_PREFERRED |
2972              DS_GC_SERVER_REQUIRED |
2973              DS_PDC_REQUIRED |
2974              DS_KDC_REQUIRED)) {
2975                 return WERR_INVALID_FLAGS;
2976         }
2977
2978         if (r->in.flags & DS_TRY_NEXTCLOSEST_SITE &&
2979             r->in.site_name) {
2980                 return WERR_INVALID_FLAGS;
2981         }
2982
2983         /*
2984          * If we send an all-zero GUID, we should ignore it as winbind actually
2985          * checks it with a DNS query. Windows also appears to ignore it.
2986          */
2987         if (r->in.domain_guid != NULL && GUID_all_zero(r->in.domain_guid)) {
2988                 r->in.domain_guid = NULL;
2989         }
2990
2991         /* Attempt winbind search only if we suspect the domain is incorrect */
2992         if (r->in.domain_name != NULL && strcmp("", r->in.domain_name) != 0) {
2993                 if (r->in.flags & DS_IS_FLAT_NAME) {
2994                         if (strcasecmp_m(r->in.domain_name,
2995                                          lpcfg_sam_name(lp_ctx)) == 0) {
2996                                 different_domain = false;
2997                         }
2998                 } else if (r->in.flags & DS_IS_DNS_NAME) {
2999                         if (strcasecmp_m(r->in.domain_name,
3000                                          lpcfg_dnsdomain(lp_ctx)) == 0) {
3001                                 different_domain = false;
3002                         }
3003                 } else {
3004                         if (strcasecmp_m(r->in.domain_name,
3005                                          lpcfg_sam_name(lp_ctx)) == 0 ||
3006                             strcasecmp_m(r->in.domain_name,
3007                                          lpcfg_dnsdomain(lp_ctx)) == 0) {
3008                                 different_domain = false;
3009                         }
3010                 }
3011         } else {
3012                 /*
3013                  * We need to be able to handle empty domain names, where we
3014                  * revert to our domain by default.
3015                  */
3016                 different_domain = false;
3017         }
3018
3019         /* Proof server site parameter "site_name" if it was specified */
3020         server_site_name = samdb_server_site_name(sam_ctx, state);
3021         W_ERROR_HAVE_NO_MEMORY(server_site_name);
3022         if (different_domain || (r->in.site_name != NULL &&
3023                                  (strcasecmp_m(r->in.site_name,
3024