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