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