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