60761b8b3ee0e4ed540bb96f85db73f4694e4cb5
[samba.git] / source4 / rpc_server / netlogon / dcerpc_netlogon.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    endpoint server for the netlogon pipe
5
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
7    Copyright (C) Stefan Metzmacher <metze@samba.org>  2005
8    Copyright (C) Matthias Dieter Wallnöfer            2009-2010
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "rpc_server/dcerpc_server.h"
26 #include "auth/auth.h"
27 #include "auth/auth_sam_reply.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "../lib/util/util_ldb.h"
30 #include "../libcli/auth/schannel.h"
31 #include "libcli/security/security.h"
32 #include "param/param.h"
33 #include "lib/messaging/irpc.h"
34 #include "librpc/gen_ndr/ndr_irpc_c.h"
35 #include "../libcli/ldap/ldap_ndr.h"
36 #include "dsdb/samdb/ldb_modules/util.h"
37 #include "lib/tsocket/tsocket.h"
38 #include "librpc/gen_ndr/ndr_netlogon.h"
39 #include "librpc/gen_ndr/ndr_lsa.h"
40 #include "librpc/gen_ndr/ndr_samr.h"
41 #include "librpc/gen_ndr/ndr_irpc.h"
42 #include "librpc/gen_ndr/ndr_winbind.h"
43 #include "librpc/gen_ndr/ndr_winbind_c.h"
44 #include "lib/socket/netif.h"
45 #include "rpc_server/common/sid_helper.h"
46 #include "lib/util/util_str_escape.h"
47
48 #define DCESRV_INTERFACE_NETLOGON_BIND(call, iface) \
49        dcesrv_interface_netlogon_bind(call, iface)
50
51 /*
52  * This #define allows the netlogon interface to accept invalid
53  * association groups, because association groups are to coordinate
54  * handles, and handles are not used in NETLOGON. This in turn avoids
55  * the need to coordinate these across multiple possible NETLOGON
56  * processes
57  */
58 #define DCESRV_INTERFACE_NETLOGON_FLAGS DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED
59
60 static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_call_state *dce_call,
61                                                const struct dcesrv_interface *iface)
62 {
63         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
2753 /*
2754   netr_DsRGetDCNameEx2
2755 */
2756 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call,
2757                                           TALLOC_CTX *mem_ctx,
2758                                           struct netr_DsRGetDCNameEx2 *r)
2759 {
2760         struct ldb_context *sam_ctx;
2761         struct netr_DsRGetDCNameInfo *info;
2762         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
2763         const struct tsocket_address *local_address;
2764         char *local_addr = NULL;
2765         const struct tsocket_address *remote_address;
2766         char *remote_addr = NULL;
2767         const char *server_site_name;
2768         char *guid_str;
2769         struct netlogon_samlogon_response response;
2770         NTSTATUS status;
2771         const char *dc_name = NULL;
2772         const char *domain_name = NULL;
2773         const char *pdc_ip;
2774
2775         ZERO_STRUCTP(r->out.info);
2776
2777         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
2778                                 dce_call->conn->auth_state.session_info, 0);
2779         if (sam_ctx == NULL) {
2780                 return WERR_DS_UNAVAILABLE;
2781         }
2782
2783         local_address = dcesrv_connection_get_local_address(dce_call->conn);
2784         if (tsocket_address_is_inet(local_address, "ip")) {
2785                 local_addr = tsocket_address_inet_addr_string(local_address, mem_ctx);
2786                 W_ERROR_HAVE_NO_MEMORY(local_addr);
2787         }
2788
2789         remote_address = dcesrv_connection_get_remote_address(dce_call->conn);
2790         if (tsocket_address_is_inet(remote_address, "ip")) {
2791                 remote_addr = tsocket_address_inet_addr_string(remote_address, mem_ctx);
2792                 W_ERROR_HAVE_NO_MEMORY(remote_addr);
2793         }
2794
2795         /* "server_unc" is ignored by w2k3 */
2796
2797         if (r->in.flags & ~(DSGETDC_VALID_FLAGS)) {
2798                 return WERR_INVALID_FLAGS;
2799         }
2800
2801         if (r->in.flags & DS_GC_SERVER_REQUIRED &&
2802             r->in.flags & DS_PDC_REQUIRED &&
2803             r->in.flags & DS_KDC_REQUIRED) {
2804                 return WERR_INVALID_FLAGS;
2805         }
2806         if (r->in.flags & DS_IS_FLAT_NAME &&
2807             r->in.flags & DS_IS_DNS_NAME) {
2808                 return WERR_INVALID_FLAGS;
2809         }
2810         if (r->in.flags & DS_RETURN_DNS_NAME &&
2811             r->in.flags & DS_RETURN_FLAT_NAME) {
2812                 return WERR_INVALID_FLAGS;
2813         }
2814         if (r->in.flags & DS_DIRECTORY_SERVICE_REQUIRED &&
2815             r->in.flags & DS_DIRECTORY_SERVICE_6_REQUIRED) {
2816                 return WERR_INVALID_FLAGS;
2817         }
2818
2819         if (r->in.flags & DS_GOOD_TIMESERV_PREFERRED &&
2820             r->in.flags &
2821             (DS_DIRECTORY_SERVICE_REQUIRED |
2822              DS_DIRECTORY_SERVICE_PREFERRED |
2823              DS_GC_SERVER_REQUIRED |
2824              DS_PDC_REQUIRED |
2825              DS_KDC_REQUIRED)) {
2826                 return WERR_INVALID_FLAGS;
2827         }
2828
2829         if (r->in.flags & DS_TRY_NEXTCLOSEST_SITE &&
2830             r->in.site_name) {
2831                 return WERR_INVALID_FLAGS;
2832         }
2833
2834         /* Proof server site parameter "site_name" if it was specified */
2835         server_site_name = samdb_server_site_name(sam_ctx, mem_ctx);
2836         W_ERROR_HAVE_NO_MEMORY(server_site_name);
2837         if ((r->in.site_name != NULL) && (strcasecmp(r->in.site_name,
2838                                                      server_site_name) != 0)) {
2839                 return WERR_NO_SUCH_DOMAIN;
2840         }
2841
2842         guid_str = r->in.domain_guid != NULL ?
2843                  GUID_string(mem_ctx, r->in.domain_guid) : NULL;
2844
2845         status = fill_netlogon_samlogon_response(sam_ctx, mem_ctx,
2846                                                  r->in.domain_name,
2847                                                  r->in.domain_name,
2848                                                  NULL, guid_str,
2849                                                  r->in.client_account,
2850                                                  r->in.mask, remote_addr,
2851                                                  NETLOGON_NT_VERSION_5EX_WITH_IP,
2852                                                  lp_ctx, &response, true);
2853         if (!NT_STATUS_IS_OK(status)) {
2854                 return ntstatus_to_werror(status);
2855         }
2856
2857         /*
2858          * According to MS-NRPC 2.2.1.2.1 we should set the "DS_DNS_FOREST_ROOT"
2859          * (O) flag when the returned forest name is in DNS format. This is here
2860          * always the case (see below).
2861          */
2862         response.data.nt5_ex.server_type |= DS_DNS_FOREST_ROOT;
2863
2864         if (r->in.flags & DS_RETURN_DNS_NAME) {
2865                 dc_name = response.data.nt5_ex.pdc_dns_name;
2866                 domain_name = response.data.nt5_ex.dns_domain;
2867                 /*
2868                  * According to MS-NRPC 2.2.1.2.1 we should set the
2869                  * "DS_DNS_CONTROLLER" (M) and "DS_DNS_DOMAIN" (N) flags when
2870                  * the returned information is in DNS form.
2871                  */
2872                 response.data.nt5_ex.server_type |=
2873                         DS_DNS_CONTROLLER | DS_DNS_DOMAIN;
2874         } else if (r->in.flags & DS_RETURN_FLAT_NAME) {
2875                 dc_name = response.data.nt5_ex.pdc_name;
2876                 domain_name = response.data.nt5_ex.domain_name;
2877         } else {
2878
2879                 /*
2880                  * TODO: autodetect what we need to return
2881                  * based on the given arguments
2882                  */
2883                 dc_name = response.data.nt5_ex.pdc_name;
2884                 domain_name = response.data.nt5_ex.domain_name;
2885         }
2886
2887         if (!dc_name || !dc_name[0]) {
2888                 return WERR_NO_SUCH_DOMAIN;
2889         }
2890
2891         if (!domain_name || !domain_name[0]) {
2892                 return WERR_NO_SUCH_DOMAIN;
2893         }
2894
2895         info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
2896         W_ERROR_HAVE_NO_MEMORY(info);
2897         info->dc_unc = talloc_asprintf(mem_ctx, "%s%s",
2898                         dc_name[0] != '\\'? "\\\\":"",
2899                         talloc_strdup(mem_ctx, dc_name));
2900         W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
2901
2902         pdc_ip = local_addr;
2903         if (pdc_ip == NULL) {
2904                 pdc_ip = "127.0.0.1";
2905         }
2906         info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", pdc_ip);
2907         W_ERROR_HAVE_NO_MEMORY(info->dc_address);
2908         info->dc_address_type  = DS_ADDRESS_TYPE_INET;
2909         info->domain_guid      = response.data.nt5_ex.domain_uuid;
2910         info->domain_name      = domain_name;
2911         info->forest_name      = response.data.nt5_ex.forest;
2912         info->dc_flags         = response.data.nt5_ex.server_type;
2913         if (r->in.flags & DS_RETURN_DNS_NAME) {
2914                 /* As MS-NRPC.pdf in 2.2.1.2.1 the DS_DNS_CONTROLLER flag should be
2915                  * returned if we are returning info->dc_unc containing a FQDN.
2916                  * This attribute is called DomainControllerName in the specs,
2917                  * it seems that we decide to return FQDN or netbios depending on
2918                  * DS_RETURN_DNS_NAME.
2919                  */
2920                 info->dc_flags |= DS_DNS_CONTROLLER;
2921         }
2922         info->dc_site_name     = response.data.nt5_ex.server_site;
2923         info->client_site_name = response.data.nt5_ex.client_site;
2924
2925         *r->out.info = info;
2926
2927         return WERR_OK;
2928 }
2929
2930 /*
2931   netr_DsRGetDCNameEx
2932 */
2933 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2934                                   struct netr_DsRGetDCNameEx *r)
2935 {
2936         struct netr_DsRGetDCNameEx2 r2;
2937         WERROR werr;
2938
2939         ZERO_STRUCT(r2);
2940
2941         r2.in.server_unc = r->in.server_unc;
2942         r2.in.client_account = NULL;
2943         r2.in.mask = 0;
2944         r2.in.domain_guid = r->in.domain_guid;
2945         r2.in.domain_name = r->in.domain_name;
2946         r2.in.site_name = r->in.site_name;
2947         r2.in.flags = r->in.flags;
2948         r2.out.info = r->out.info;
2949
2950         werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
2951
2952         return werr;
2953 }
2954
2955 /*
2956   netr_DsRGetDCName
2957 */
2958 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2959                                 struct netr_DsRGetDCName *r)
2960 {
2961         struct netr_DsRGetDCNameEx2 r2;
2962         WERROR werr;
2963
2964         ZERO_STRUCT(r2);
2965
2966         r2.in.server_unc = r->in.server_unc;
2967         r2.in.client_account = NULL;
2968         r2.in.mask = 0;
2969         r2.in.domain_name = r->in.domain_name;
2970         r2.in.domain_guid = r->in.domain_guid;
2971
2972         r2.in.site_name = NULL; /* this is correct, we should ignore site GUID */
2973         r2.in.flags = r->in.flags;
2974         r2.out.info = r->out.info;
2975
2976         werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
2977
2978         return werr;
2979 }
2980 /*
2981   netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
2982 */
2983 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2984                        struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
2985 {
2986         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2987 }
2988
2989
2990 /*
2991   netr_NetrEnumerateTrustedDomainsEx
2992 */
2993 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2994                        struct netr_NetrEnumerateTrustedDomainsEx *r)
2995 {
2996         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2997 }
2998
2999
3000 /*
3001   netr_DsRAddressToSitenamesExW
3002 */
3003 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3004                                                    struct netr_DsRAddressToSitenamesExW *r)
3005 {
3006         struct ldb_context *sam_ctx;
3007         struct netr_DsRAddressToSitenamesExWCtr *ctr;
3008         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
3009         sa_family_t sin_family;
3010         struct sockaddr_in *addr;
3011 #ifdef HAVE_IPV6
3012         struct sockaddr_in6 *addr6;
3013         char addr_str[INET6_ADDRSTRLEN];
3014 #else
3015         char addr_str[INET_ADDRSTRLEN];
3016 #endif
3017         char *subnet_name;
3018         const char *res;
3019         uint32_t i;
3020
3021         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
3022                                 dce_call->conn->auth_state.session_info, 0);
3023         if (sam_ctx == NULL) {
3024                 return WERR_DS_UNAVAILABLE;
3025         }
3026
3027         ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr);
3028         W_ERROR_HAVE_NO_MEMORY(ctr);
3029
3030         *r->out.ctr = ctr;
3031
3032         ctr->count = r->in.count;
3033         ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count);
3034         W_ERROR_HAVE_NO_MEMORY(ctr->sitename);
3035         ctr->subnetname = talloc_array(ctr, struct lsa_String, ctr->count);
3036         W_ERROR_HAVE_NO_MEMORY(ctr->subnetname);
3037
3038         for (i=0; i<ctr->count; i++) {
3039                 ctr->sitename[i].string = NULL;
3040                 ctr->subnetname[i].string = NULL;
3041
3042                 if (r->in.addresses[i].size < sizeof(sa_family_t)) {
3043                         continue;
3044                 }
3045                 /* The first two byte of the buffer are reserved for the
3046                  * "sin_family" but for now only the first one is used. */
3047                 sin_family = r->in.addresses[i].buffer[0];
3048
3049                 switch (sin_family) {
3050                 case AF_INET:
3051                         if (r->in.addresses[i].size < sizeof(struct sockaddr_in)) {
3052                                 continue;
3053                         }
3054                         addr = (struct sockaddr_in *) r->in.addresses[i].buffer;
3055                         res = inet_ntop(AF_INET, &addr->sin_addr,
3056                                         addr_str, sizeof(addr_str));
3057                         break;
3058 #ifdef HAVE_IPV6
3059                 case AF_INET6:
3060                         if (r->in.addresses[i].size < sizeof(struct sockaddr_in6)) {
3061                                 continue;
3062                         }
3063                         addr6 = (struct sockaddr_in6 *) r->in.addresses[i].buffer;
3064                         res = inet_ntop(AF_INET6, &addr6->sin6_addr,
3065                                         addr_str, sizeof(addr_str));
3066                         break;
3067 #endif
3068                 default:
3069                         continue;
3070                 }
3071
3072                 if (res == NULL) {
3073                         continue;
3074                 }
3075
3076                 ctr->sitename[i].string   = samdb_client_site_name(sam_ctx,
3077                                                                    mem_ctx,
3078                                                                    addr_str,
3079                                                                    &subnet_name);
3080                 W_ERROR_HAVE_NO_MEMORY(ctr->sitename[i].string);
3081                 ctr->subnetname[i].string = subnet_name;
3082         }
3083
3084         return WERR_OK;
3085 }
3086
3087
3088 /*
3089   netr_DsRAddressToSitenamesW
3090 */
3091 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3092                        struct netr_DsRAddressToSitenamesW *r)
3093 {
3094         struct netr_DsRAddressToSitenamesExW r2;
3095         struct netr_DsRAddressToSitenamesWCtr *ctr;
3096         uint32_t i;
3097         WERROR werr;
3098
3099         ZERO_STRUCT(r2);
3100
3101         r2.in.server_name = r->in.server_name;
3102         r2.in.count = r->in.count;
3103         r2.in.addresses = r->in.addresses;
3104
3105         r2.out.ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr *);
3106         W_ERROR_HAVE_NO_MEMORY(r2.out.ctr);
3107
3108         ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesWCtr);
3109         W_ERROR_HAVE_NO_MEMORY(ctr);
3110
3111         *r->out.ctr = ctr;
3112
3113         ctr->count = r->in.count;
3114         ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count);
3115         W_ERROR_HAVE_NO_MEMORY(ctr->sitename);
3116
3117         werr = dcesrv_netr_DsRAddressToSitenamesExW(dce_call, mem_ctx, &r2);
3118
3119         for (i=0; i<ctr->count; i++) {
3120                 ctr->sitename[i].string   = (*r2.out.ctr)->sitename[i].string;
3121         }
3122
3123         return werr;
3124 }
3125
3126
3127 /*
3128   netr_DsrGetDcSiteCoverageW
3129 */
3130 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3131                        struct netr_DsrGetDcSiteCoverageW *r)
3132 {
3133         struct ldb_context *sam_ctx;
3134         struct DcSitesCtr *ctr;
3135         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
3136
3137         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
3138                                 dce_call->conn->auth_state.session_info, 0);
3139         if (sam_ctx == NULL) {
3140                 return WERR_DS_UNAVAILABLE;
3141         }
3142
3143         ctr = talloc(mem_ctx, struct DcSitesCtr);
3144         W_ERROR_HAVE_NO_MEMORY(ctr);
3145
3146         *r->out.ctr = ctr;
3147
3148         /* For now only return our default site */
3149         ctr->num_sites = 1;
3150         ctr->sites = talloc_array(ctr, struct lsa_String, ctr->num_sites);
3151         W_ERROR_HAVE_NO_MEMORY(ctr->sites);
3152         ctr->sites[0].string = samdb_server_site_name(sam_ctx, mem_ctx);
3153         W_ERROR_HAVE_NO_MEMORY(ctr->sites[0].string);
3154
3155         return WERR_OK;
3156 }
3157
3158
3159 static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
3160                                          struct ldb_context *sam_ctx,
3161                                          struct netr_DomainTrustList *trusts,
3162                                          uint32_t trust_flags)
3163 {
3164         struct ldb_dn *system_dn;
3165         struct ldb_message **dom_res = NULL;
3166         const char *trust_attrs[] = { "flatname", "trustPartner",
3167                                       "securityIdentifier", "trustDirection",
3168                                       "trustType", "trustAttributes", NULL };
3169         uint32_t n;
3170         int i;
3171         int ret;
3172
3173         if (!(trust_flags & (NETR_TRUST_FLAG_INBOUND |
3174                              NETR_TRUST_FLAG_OUTBOUND))) {
3175                 return WERR_INVALID_FLAGS;
3176         }
3177
3178         system_dn = samdb_search_dn(sam_ctx, mem_ctx,
3179                                     ldb_get_default_basedn(sam_ctx),
3180                                     "(&(objectClass=container)(cn=System))");
3181         if (!system_dn) {
3182                 return WERR_GEN_FAILURE;
3183         }
3184
3185         ret = gendb_search(sam_ctx, mem_ctx, system_dn,
3186                            &dom_res, trust_attrs,
3187                            "(objectclass=trustedDomain)");
3188
3189         for (i = 0; i < ret; i++) {
3190                 unsigned int trust_dir;
3191                 uint32_t flags = 0;
3192
3193                 trust_dir = ldb_msg_find_attr_as_uint(dom_res[i],
3194                                                       "trustDirection", 0);
3195
3196                 if (trust_dir & LSA_TRUST_DIRECTION_INBOUND) {
3197                         flags |= NETR_TRUST_FLAG_INBOUND;
3198                 }
3199                 if (trust_dir & LSA_TRUST_DIRECTION_OUTBOUND) {
3200                         flags |= NETR_TRUST_FLAG_OUTBOUND;
3201                 }
3202
3203                 if (!(flags & trust_flags)) {
3204                         /* this trust direction was not requested */
3205                         continue;
3206                 }
3207
3208                 n = trusts->count;
3209                 trusts->array = talloc_realloc(trusts, trusts->array,
3210                                                struct netr_DomainTrust,
3211                                                n + 1);
3212                 W_ERROR_HAVE_NO_MEMORY(trusts->array);
3213
3214                 trusts->array[n].netbios_name = talloc_steal(trusts->array, ldb_msg_find_attr_as_string(dom_res[i], "flatname", NULL));
3215                 if (!trusts->array[n].netbios_name) {
3216                         DEBUG(0, ("DB Error, TrustedDomain entry (%s) "
3217                                   "without flatname\n", 
3218                                   ldb_dn_get_linearized(dom_res[i]->dn)));
3219                 }
3220
3221                 trusts->array[n].dns_name = talloc_steal(trusts->array, ldb_msg_find_attr_as_string(dom_res[i], "trustPartner", NULL));
3222
3223                 trusts->array[n].trust_flags = flags;
3224                 if ((trust_flags & NETR_TRUST_FLAG_IN_FOREST) &&
3225                     !(flags & NETR_TRUST_FLAG_TREEROOT)) {
3226                         /* TODO: find if we have parent in the list */
3227                         trusts->array[n].parent_index = 0;
3228                 }
3229
3230                 trusts->array[n].trust_type =
3231                                 ldb_msg_find_attr_as_uint(dom_res[i],
3232                                                   "trustType", 0);
3233                 trusts->array[n].trust_attributes =
3234                                 ldb_msg_find_attr_as_uint(dom_res[i],
3235                                                   "trustAttributes", 0);
3236
3237                 if ((trusts->array[n].trust_type == LSA_TRUST_TYPE_MIT) ||
3238                     (trusts->array[n].trust_type == LSA_TRUST_TYPE_DCE)) {
3239                         struct dom_sid zero_sid;
3240                         ZERO_STRUCT(zero_sid);
3241                         trusts->array[n].sid =
3242                                 dom_sid_dup(trusts, &zero_sid);
3243                 } else {
3244                         trusts->array[n].sid =
3245                                 samdb_result_dom_sid(trusts, dom_res[i],
3246                                                      "securityIdentifier");
3247                 }
3248                 trusts->array[n].guid = GUID_zero();
3249
3250                 trusts->count = n + 1;
3251         }
3252
3253         talloc_free(dom_res);
3254         return WERR_OK;
3255 }
3256
3257 /*
3258   netr_DsrEnumerateDomainTrusts
3259 */
3260 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call,
3261                                                    TALLOC_CTX *mem_ctx,
3262                                                    struct netr_DsrEnumerateDomainTrusts *r)
3263 {
3264         struct netr_DomainTrustList *trusts;
3265         struct ldb_context *sam_ctx;
3266         int ret;
3267         struct ldb_message **dom_res;
3268         const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
3269         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
3270         const char *dnsdomain = lpcfg_dnsdomain(lp_ctx);
3271         const char *p;
3272         WERROR werr;
3273
3274         if (r->in.trust_flags & 0xFFFFFE00) {
3275                 return WERR_INVALID_FLAGS;
3276         }
3277
3278         /* TODO: turn to hard check once we are sure this is 100% correct */
3279         if (!r->in.server_name) {
3280                 DEBUG(3, ("Invalid domain! Expected name in domain [%s]. "
3281                           "But received NULL!\n", dnsdomain));
3282         } else {
3283                 p = strchr(r->in.server_name, '.');
3284                 if (!p) {
3285                         DEBUG(3, ("Invalid domain! Expected name in domain "
3286                                   "[%s]. But received [%s]!\n",
3287                                   dnsdomain, r->in.server_name));
3288                         p = r->in.server_name;
3289                 } else {
3290                         p++;
3291                 }
3292                 if (strcasecmp(p, dnsdomain)) {
3293                         DEBUG(3, ("Invalid domain! Expected name in domain "
3294                                   "[%s]. But received [%s]!\n",
3295                                   dnsdomain, r->in.server_name));
3296                 }
3297         }
3298
3299         trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList);
3300         W_ERROR_HAVE_NO_MEMORY(trusts);
3301
3302         trusts->count = 0;
3303         r->out.trusts = trusts;
3304
3305         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
3306                                 dce_call->conn->auth_state.session_info, 0);
3307         if (sam_ctx == NULL) {
3308                 return WERR_GEN_FAILURE;
3309         }
3310
3311         if ((r->in.trust_flags & NETR_TRUST_FLAG_INBOUND) ||
3312             (r->in.trust_flags & NETR_TRUST_FLAG_OUTBOUND)) {
3313
3314                 werr = fill_trusted_domains_array(mem_ctx, sam_ctx,
3315                                                   trusts, r->in.trust_flags);
3316                 W_ERROR_NOT_OK_RETURN(werr);
3317         }
3318
3319         /* NOTE: we currently are always the root of the forest */
3320         if (r->in.trust_flags & NETR_TRUST_FLAG_IN_FOREST) {
3321                 uint32_t n = trusts->count;
3322
3323                 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
3324                                       &dom_res, dom_attrs);
3325                 if (ret != 1) {
3326                         return WERR_GEN_FAILURE;
3327                 }
3328
3329                 trusts->count = n + 1;
3330                 trusts->array = talloc_realloc(trusts, trusts->array,
3331                                                struct netr_DomainTrust,
3332                                                trusts->count);
3333                 W_ERROR_HAVE_NO_MEMORY(trusts->array);
3334
3335                 trusts->array[n].netbios_name = lpcfg_workgroup(lp_ctx);
3336                 trusts->array[n].dns_name = lpcfg_dnsdomain(lp_ctx);
3337                 trusts->array[n].trust_flags =
3338                         NETR_TRUST_FLAG_NATIVE |
3339                         NETR_TRUST_FLAG_TREEROOT |
3340                         NETR_TRUST_FLAG_IN_FOREST |
3341                         NETR_TRUST_FLAG_PRIMARY;
3342                 /* we are always the root domain for now */
3343                 trusts->array[n].parent_index = 0;
3344                 trusts->array[n].trust_type = LSA_TRUST_TYPE_UPLEVEL;
3345                 trusts->array[n].trust_attributes = 0;
3346                 trusts->array[n].sid = samdb_result_dom_sid(mem_ctx,
3347                                                             dom_res[0],
3348                                                             "objectSid");
3349                 trusts->array[n].guid = samdb_result_guid(dom_res[0],
3350                                                           "objectGUID");
3351                 talloc_free(dom_res);
3352         }
3353
3354         return WERR_OK;
3355 }
3356
3357
3358 /*
3359   netr_DsrDeregisterDNSHostRecords
3360 */
3361 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3362                        struct netr_DsrDeregisterDNSHostRecords *r)
3363 {
3364         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3365 }
3366
3367
3368 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3369                        struct netr_ServerGetTrustInfo *r);
3370
3371 /*
3372   netr_ServerTrustPasswordsGet
3373 */
3374 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3375                        struct netr_ServerTrustPasswordsGet *r)
3376 {
3377         struct netr_ServerGetTrustInfo r2 = {};
3378         struct netr_TrustInfo *_ti = NULL;
3379         NTSTATUS status;
3380
3381         r2.in.server_name = r->in.server_name;
3382         r2.in.account_name = r->in.account_name;
3383         r2.in.secure_channel_type = r->in.secure_channel_type;
3384         r2.in.computer_name = r->in.computer_name;
3385         r2.in.credential = r->in.credential;
3386
3387         r2.out.return_authenticator = r->out.return_authenticator;
3388         r2.out.new_owf_password = r->out.new_owf_password;
3389         r2.out.old_owf_password = r->out.old_owf_password;
3390         r2.out.trust_info = &_ti;
3391
3392         status = dcesrv_netr_ServerGetTrustInfo(dce_call, mem_ctx, &r2);
3393
3394         r->out.return_authenticator = r2.out.return_authenticator;
3395         r->out.new_owf_password = r2.out.new_owf_password;
3396         r->out.old_owf_password = r2.out.old_owf_password;
3397
3398         return status;
3399 }
3400
3401 /*
3402   netr_DsRGetForestTrustInformation
3403 */
3404 struct dcesrv_netr_DsRGetForestTrustInformation_state {
3405         struct dcesrv_call_state *dce_call;
3406         TALLOC_CTX *mem_ctx;
3407         struct netr_DsRGetForestTrustInformation *r;
3408 };
3409
3410 static void dcesrv_netr_DsRGetForestTrustInformation_done(struct tevent_req *subreq);
3411
3412 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call,
3413                                                        TALLOC_CTX *mem_ctx,
3414                                                        struct netr_DsRGetForestTrustInformation *r)
3415 {
3416         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
3417         struct dcesrv_connection *conn = dce_call->conn;
3418         struct auth_session_info *session_info = conn->auth_state.session_info;
3419         enum security_user_level security_level;
3420         struct ldb_context *sam_ctx = NULL;
3421         struct dcesrv_netr_DsRGetForestTrustInformation_state *state = NULL;
3422         struct dcerpc_binding_handle *irpc_handle = NULL;
3423         struct tevent_req *subreq = NULL;
3424         struct ldb_dn *domain_dn = NULL;
3425         struct ldb_dn *forest_dn = NULL;
3426         int cmp;
3427         int forest_level;
3428
3429         security_level = security_session_user_level(session_info, NULL);
3430         if (security_level < SECURITY_USER) {
3431                 return WERR_ACCESS_DENIED;
3432         }
3433
3434         if (r->in.flags & 0xFFFFFFFE) {
3435                 return WERR_INVALID_FLAGS;
3436         }
3437
3438         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
3439                                 dce_call->conn->auth_state.session_info, 0);
3440         if (sam_ctx == NULL) {
3441                 return WERR_GEN_FAILURE;
3442         }
3443
3444         domain_dn = ldb_get_default_basedn(sam_ctx);
3445         if (domain_dn == NULL) {
3446                 return WERR_GEN_FAILURE;
3447         }
3448
3449         forest_dn = ldb_get_root_basedn(sam_ctx);
3450         if (forest_dn == NULL) {
3451                 return WERR_GEN_FAILURE;
3452         }
3453
3454         cmp = ldb_dn_compare(domain_dn, forest_dn);
3455         if (cmp != 0) {
3456                 return WERR_NERR_ACFNOTLOADED;
3457         }
3458
3459         forest_level = dsdb_forest_functional_level(sam_ctx);
3460         if (forest_level < DS_DOMAIN_FUNCTION_2003) {
3461                 return WERR_INVALID_FUNCTION;
3462         }
3463
3464         if (r->in.flags & DS_GFTI_UPDATE_TDO) {
3465                 if (!samdb_is_pdc(sam_ctx)) {
3466                         return WERR_NERR_NOTPRIMARY;
3467                 }
3468
3469                 if (r->in.trusted_domain_name == NULL) {
3470                         return WERR_INVALID_FLAGS;
3471                 }
3472         }
3473
3474         if (r->in.trusted_domain_name == NULL) {
3475                 NTSTATUS status;
3476
3477                 /*
3478                  * information about our own domain
3479                  */
3480                 status = dsdb_trust_xref_forest_info(mem_ctx, sam_ctx,
3481                                                 r->out.forest_trust_info);
3482                 if (!NT_STATUS_IS_OK(status)) {
3483                         return ntstatus_to_werror(status);
3484                 }
3485
3486                 return WERR_OK;
3487         }
3488
3489         /*
3490          * Forward the request to winbindd
3491          */
3492
3493         state = talloc_zero(mem_ctx,
3494                         struct dcesrv_netr_DsRGetForestTrustInformation_state);
3495         if (state == NULL) {
3496                 return WERR_NOT_ENOUGH_MEMORY;
3497         }
3498         state->dce_call = dce_call;
3499         state->mem_ctx = mem_ctx;
3500         state->r = r;
3501
3502         irpc_handle = irpc_binding_handle_by_name(state,