2 Unix SMB/CIFS implementation.
4 endpoint server for the netlogon pipe
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
7 Copyright (C) Stefan Metzmacher <metze@samba.org> 2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "rpc_server/dcerpc_server.h"
25 #include "rpc_server/common/common.h"
26 #include "lib/ldb/include/ldb.h"
27 #include "auth/auth.h"
28 #include "auth/auth_sam_reply.h"
29 #include "dsdb/samdb/samdb.h"
30 #include "dsdb/common/flags.h"
31 #include "rpc_server/samr/proto.h"
32 #include "../lib/util/util_ldb.h"
33 #include "libcli/auth/libcli_auth.h"
34 #include "auth/gensec/schannel_state.h"
35 #include "libcli/security/security.h"
36 #include "param/param.h"
37 #include "lib/messaging/irpc.h"
38 #include "librpc/gen_ndr/ndr_irpc.h"
39 #include "librpc/gen_ndr/ndr_netlogon.h"
41 struct server_pipe_state {
42 struct netr_Credential client_challenge;
43 struct netr_Credential server_challenge;
47 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
48 struct netr_ServerReqChallenge *r)
50 struct server_pipe_state *pipe_state = dce_call->context->private_data;
52 ZERO_STRUCTP(r->out.return_credentials);
54 /* destroyed on pipe shutdown */
57 talloc_free(pipe_state);
58 dce_call->context->private_data = NULL;
61 pipe_state = talloc(dce_call->context, struct server_pipe_state);
62 NT_STATUS_HAVE_NO_MEMORY(pipe_state);
64 pipe_state->client_challenge = *r->in.credentials;
66 generate_random_buffer(pipe_state->server_challenge.data,
67 sizeof(pipe_state->server_challenge.data));
69 *r->out.return_credentials = pipe_state->server_challenge;
71 dce_call->context->private_data = pipe_state;
76 static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
77 struct netr_ServerAuthenticate3 *r)
79 struct server_pipe_state *pipe_state = dce_call->context->private_data;
80 struct creds_CredentialState *creds;
82 struct samr_Password *mach_pwd;
83 uint32_t user_account_control;
85 struct ldb_message **msgs;
87 const char *attrs[] = {"unicodePwd", "userAccountControl",
90 const char *trust_dom_attrs[] = {"flatname", NULL};
91 const char *account_name;
93 ZERO_STRUCTP(r->out.return_credentials);
95 *r->out.negotiate_flags = *r->in.negotiate_flags;
98 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
99 return NT_STATUS_ACCESS_DENIED;
102 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
103 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
104 if (sam_ctx == NULL) {
105 return NT_STATUS_INVALID_SYSTEM_SERVICE;
108 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
109 char *encoded_account = ldb_binary_encode_string(mem_ctx, r->in.account_name);
110 const char *flatname;
111 if (!encoded_account) {
112 return NT_STATUS_NO_MEMORY;
115 /* Kill the trailing dot */
116 if (encoded_account[strlen(encoded_account)-1] == '.') {
117 encoded_account[strlen(encoded_account)-1] = '\0';
120 /* pull the user attributes */
121 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, trust_dom_attrs,
122 "(&(trustPartner=%s)(objectclass=trustedDomain))",
125 if (num_records == 0) {
126 DEBUG(3,("Couldn't find trust [%s] in samdb.\n",
128 return NT_STATUS_ACCESS_DENIED;
131 if (num_records > 1) {
132 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
133 return NT_STATUS_INTERNAL_DB_CORRUPTION;
136 flatname = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL);
138 /* No flatname for this trust - we can't proceed */
139 return NT_STATUS_ACCESS_DENIED;
141 account_name = talloc_asprintf(mem_ctx, "%s$", flatname);
144 return NT_STATUS_NO_MEMORY;
148 account_name = r->in.account_name;
151 /* pull the user attributes */
152 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
153 "(&(sAMAccountName=%s)(objectclass=user))",
154 ldb_binary_encode_string(mem_ctx, account_name));
156 if (num_records == 0) {
157 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
158 r->in.account_name));
159 return NT_STATUS_ACCESS_DENIED;
162 if (num_records > 1) {
163 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
164 return NT_STATUS_INTERNAL_DB_CORRUPTION;
168 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
170 if (user_account_control & UF_ACCOUNTDISABLE) {
171 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
172 return NT_STATUS_ACCESS_DENIED;
175 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
176 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
177 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
178 return NT_STATUS_ACCESS_DENIED;
180 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
181 r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
182 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
183 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
185 return NT_STATUS_ACCESS_DENIED;
187 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
188 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
189 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
190 return NT_STATUS_ACCESS_DENIED;
193 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
194 r->in.secure_channel_type));
195 return NT_STATUS_ACCESS_DENIED;
198 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
201 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd");
202 if (mach_pwd == NULL) {
203 return NT_STATUS_ACCESS_DENIED;
206 creds = talloc(mem_ctx, struct creds_CredentialState);
207 NT_STATUS_HAVE_NO_MEMORY(creds);
209 creds_server_init(creds, &pipe_state->client_challenge,
210 &pipe_state->server_challenge, mach_pwd,
211 r->out.return_credentials,
212 *r->in.negotiate_flags);
214 if (!creds_server_check(creds, r->in.credentials)) {
216 return NT_STATUS_ACCESS_DENIED;
219 creds->account_name = talloc_steal(creds, r->in.account_name);
221 creds->computer_name = talloc_steal(creds, r->in.computer_name);
222 creds->domain = talloc_strdup(creds, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
224 creds->secure_channel_type = r->in.secure_channel_type;
226 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
229 /* remember this session key state */
230 nt_status = schannel_store_session_key(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, creds);
235 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
236 struct netr_ServerAuthenticate *r)
238 struct netr_ServerAuthenticate3 r3;
241 * negotiate_flags is used as an [in] parameter
242 * so it need to be initialised.
244 * (I think ... = 0; seems wrong here --metze)
246 uint32_t negotiate_flags = 0;
248 r3.in.server_name = r->in.server_name;
249 r3.in.account_name = r->in.account_name;
250 r3.in.secure_channel_type = r->in.secure_channel_type;
251 r3.in.computer_name = r->in.computer_name;
252 r3.in.credentials = r->in.credentials;
253 r3.out.return_credentials = r->out.return_credentials;
254 r3.in.negotiate_flags = &negotiate_flags;
255 r3.out.negotiate_flags = &negotiate_flags;
258 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
261 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
262 struct netr_ServerAuthenticate2 *r)
264 struct netr_ServerAuthenticate3 r3;
267 r3.in.server_name = r->in.server_name;
268 r3.in.account_name = r->in.account_name;
269 r3.in.secure_channel_type = r->in.secure_channel_type;
270 r3.in.computer_name = r->in.computer_name;
271 r3.in.credentials = r->in.credentials;
272 r3.out.return_credentials = r->out.return_credentials;
273 r3.in.negotiate_flags = r->in.negotiate_flags;
274 r3.out.negotiate_flags = r->out.negotiate_flags;
277 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
281 Validate an incoming authenticator against the credentials for the remote machine.
283 The credentials are (re)read and from the schannel database, and
284 written back after the caclulations are performed.
286 The creds_out parameter (if not NULL) returns the credentials, if
287 the caller needs some of that information.
290 static NTSTATUS dcesrv_netr_creds_server_step_check(struct tevent_context *event_ctx,
291 struct loadparm_context *lp_ctx,
292 const char *computer_name,
294 struct netr_Authenticator *received_authenticator,
295 struct netr_Authenticator *return_authenticator,
296 struct creds_CredentialState **creds_out)
298 struct creds_CredentialState *creds;
300 struct ldb_context *ldb;
303 ldb = schannel_db_connect(mem_ctx, event_ctx, lp_ctx);
305 return NT_STATUS_ACCESS_DENIED;
308 ret = ldb_transaction_start(ldb);
311 return NT_STATUS_INTERNAL_DB_CORRUPTION;
314 /* Because this is a shared structure (even across
315 * disconnects) we must update the database every time we
316 * update the structure */
318 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name,
319 lp_workgroup(lp_ctx),
321 if (NT_STATUS_IS_OK(nt_status)) {
322 nt_status = creds_server_step_check(creds,
323 received_authenticator,
324 return_authenticator);
326 if (NT_STATUS_IS_OK(nt_status)) {
327 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
330 if (NT_STATUS_IS_OK(nt_status)) {
331 ldb_transaction_commit(ldb);
334 talloc_steal(mem_ctx, creds);
337 ldb_transaction_cancel(ldb);
344 Change the machine account password for the currently connected
345 client. Supplies only the NT#.
348 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
349 struct netr_ServerPasswordSet *r)
351 struct creds_CredentialState *creds;
352 struct ldb_context *sam_ctx;
355 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
356 r->in.computer_name, mem_ctx,
357 r->in.credential, r->out.return_authenticator,
359 NT_STATUS_NOT_OK_RETURN(nt_status);
361 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
362 if (sam_ctx == NULL) {
363 return NT_STATUS_INVALID_SYSTEM_SERVICE;
366 creds_des_decrypt(creds, r->in.new_password);
368 /* Using the sid for the account as the key, set the password */
369 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
371 NULL, /* Don't have plaintext */
372 NULL, r->in.new_password,
373 true, /* Password change */
379 Change the machine account password for the currently connected
380 client. Supplies new plaintext.
382 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
383 struct netr_ServerPasswordSet2 *r)
385 struct creds_CredentialState *creds;
386 struct ldb_context *sam_ctx;
388 DATA_BLOB new_password;
390 struct samr_CryptPassword password_buf;
392 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
393 r->in.computer_name, mem_ctx,
394 r->in.credential, r->out.return_authenticator,
396 NT_STATUS_NOT_OK_RETURN(nt_status);
398 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
399 if (sam_ctx == NULL) {
400 return NT_STATUS_INVALID_SYSTEM_SERVICE;
403 memcpy(password_buf.data, r->in.new_password->data, 512);
404 SIVAL(password_buf.data, 512, r->in.new_password->length);
405 creds_arcfour_crypt(creds, password_buf.data, 516);
407 if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
408 DEBUG(3,("samr: failed to decode password buffer\n"));
409 return NT_STATUS_WRONG_PASSWORD;
412 /* Using the sid for the account as the key, set the password */
413 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
415 &new_password, /* we have plaintext */
417 true, /* Password change */
426 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
427 struct netr_LogonUasLogon *r)
429 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
436 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
437 struct netr_LogonUasLogoff *r)
439 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
444 netr_LogonSamLogon_base
446 This version of the function allows other wrappers to say 'do not check the credentials'
448 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
450 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
451 struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
453 struct auth_context *auth_context;
454 struct auth_usersupplied_info *user_info;
455 struct auth_serversupplied_info *server_info;
457 static const char zeros[16];
458 struct netr_SamBaseInfo *sam;
459 struct netr_SamInfo2 *sam2;
460 struct netr_SamInfo3 *sam3;
461 struct netr_SamInfo6 *sam6;
463 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
464 NT_STATUS_HAVE_NO_MEMORY(user_info);
466 user_info->flags = 0;
467 user_info->mapped_state = false;
468 user_info->remote_host = NULL;
470 switch (r->in.logon_level) {
471 case NetlogonInteractiveInformation:
472 case NetlogonServiceInformation:
473 case NetlogonInteractiveTransitiveInformation:
474 case NetlogonServiceTransitiveInformation:
475 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
476 creds_arcfour_crypt(creds,
477 r->in.logon->password->lmpassword.hash,
478 sizeof(r->in.logon->password->lmpassword.hash));
479 creds_arcfour_crypt(creds,
480 r->in.logon->password->ntpassword.hash,
481 sizeof(r->in.logon->password->ntpassword.hash));
483 creds_des_decrypt(creds, &r->in.logon->password->lmpassword);
484 creds_des_decrypt(creds, &r->in.logon->password->ntpassword);
487 /* TODO: we need to deny anonymous access here */
488 nt_status = auth_context_create(mem_ctx,
489 dce_call->event_ctx, dce_call->msg_ctx,
490 dce_call->conn->dce_ctx->lp_ctx,
492 NT_STATUS_NOT_OK_RETURN(nt_status);
494 user_info->logon_parameters = r->in.logon->password->identity_info.parameter_control;
495 user_info->client.account_name = r->in.logon->password->identity_info.account_name.string;
496 user_info->client.domain_name = r->in.logon->password->identity_info.domain_name.string;
497 user_info->workstation_name = r->in.logon->password->identity_info.workstation.string;
499 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
500 user_info->password_state = AUTH_PASSWORD_HASH;
502 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
503 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
504 *user_info->password.hash.lanman = r->in.logon->password->lmpassword;
506 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
507 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
508 *user_info->password.hash.nt = r->in.logon->password->ntpassword;
511 case NetlogonNetworkInformation:
512 case NetlogonNetworkTransitiveInformation:
514 /* TODO: we need to deny anonymous access here */
515 nt_status = auth_context_create(mem_ctx,
516 dce_call->event_ctx, dce_call->msg_ctx,
517 dce_call->conn->dce_ctx->lp_ctx,
519 NT_STATUS_NOT_OK_RETURN(nt_status);
521 nt_status = auth_context_set_challenge(auth_context, r->in.logon->network->challenge, "netr_LogonSamLogonWithFlags");
522 NT_STATUS_NOT_OK_RETURN(nt_status);
524 user_info->logon_parameters = r->in.logon->network->identity_info.parameter_control;
525 user_info->client.account_name = r->in.logon->network->identity_info.account_name.string;
526 user_info->client.domain_name = r->in.logon->network->identity_info.domain_name.string;
527 user_info->workstation_name = r->in.logon->network->identity_info.workstation.string;
529 user_info->password_state = AUTH_PASSWORD_RESPONSE;
530 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length);
531 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length);
536 case NetlogonGenericInformation:
538 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
539 creds_arcfour_crypt(creds,
540 r->in.logon->generic->data, r->in.logon->generic->length);
542 /* Using DES to verify kerberos tickets makes no sense */
543 return NT_STATUS_INVALID_PARAMETER;
546 if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) {
548 struct server_id *kdc;
549 struct kdc_check_generic_kerberos check;
550 struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
551 NT_STATUS_HAVE_NO_MEMORY(generic);
552 *r->out.authoritative = 1;
554 /* TODO: Describe and deal with these flags */
557 r->out.validation->generic = generic;
559 kdc = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "kdc_server");
560 if ((kdc == NULL) || (kdc[0].id == 0)) {
561 return NT_STATUS_NO_LOGON_SERVERS;
564 check.in.generic_request =
565 data_blob_const(r->in.logon->generic->data,
566 r->in.logon->generic->length);
568 status = irpc_call(dce_call->msg_ctx, kdc[0],
569 &ndr_table_irpc, NDR_KDC_CHECK_GENERIC_KERBEROS,
571 if (!NT_STATUS_IS_OK(status)) {
574 generic->length = check.out.generic_reply.length;
575 generic->data = check.out.generic_reply.data;
579 /* Until we get an implemetnation of these other packages */
580 return NT_STATUS_INVALID_PARAMETER;
583 return NT_STATUS_INVALID_PARAMETER;
586 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
587 NT_STATUS_NOT_OK_RETURN(nt_status);
589 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
590 NT_STATUS_NOT_OK_RETURN(nt_status);
592 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
593 /* It appears that level 6 is not individually encrypted */
594 if ((r->in.validation_level != 6) &&
595 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
596 /* This key is sent unencrypted without the ARCFOUR flag set */
597 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
598 creds_arcfour_crypt(creds,
600 sizeof(sam->key.key));
604 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
605 /* It appears that level 6 is not individually encrypted */
606 if ((r->in.validation_level != 6) &&
607 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
608 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
609 creds_arcfour_crypt(creds,
611 sizeof(sam->LMSessKey.key));
613 creds_des_encrypt_LMKey(creds,
618 switch (r->in.validation_level) {
620 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
621 NT_STATUS_HAVE_NO_MEMORY(sam2);
623 r->out.validation->sam2 = sam2;
627 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
628 NT_STATUS_HAVE_NO_MEMORY(sam3);
630 r->out.validation->sam3 = sam3;
634 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
635 NT_STATUS_HAVE_NO_MEMORY(sam6);
637 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
638 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
639 sam->account_name.string, sam6->forest.string);
640 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
641 r->out.validation->sam6 = sam6;
648 *r->out.authoritative = 1;
650 /* TODO: Describe and deal with these flags */
656 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
657 struct netr_LogonSamLogonEx *r)
660 struct creds_CredentialState *creds;
661 nt_status = schannel_fetch_session_key(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, r->in.computer_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx), &creds);
662 if (!NT_STATUS_IS_OK(nt_status)) {
666 if (!dce_call->conn->auth_state.auth_info ||
667 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
668 return NT_STATUS_INTERNAL_ERROR;
670 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
674 netr_LogonSamLogonWithFlags
677 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
678 struct netr_LogonSamLogonWithFlags *r)
681 struct creds_CredentialState *creds;
682 struct netr_LogonSamLogonEx r2;
684 struct netr_Authenticator *return_authenticator;
686 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
687 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
689 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
690 r->in.computer_name, mem_ctx,
691 r->in.credential, return_authenticator,
693 NT_STATUS_NOT_OK_RETURN(nt_status);
697 r2.in.server_name = r->in.server_name;
698 r2.in.computer_name = r->in.computer_name;
699 r2.in.logon_level = r->in.logon_level;
700 r2.in.logon = r->in.logon;
701 r2.in.validation_level = r->in.validation_level;
702 r2.in.flags = r->in.flags;
703 r2.out.validation = r->out.validation;
704 r2.out.authoritative = r->out.authoritative;
705 r2.out.flags = r->out.flags;
707 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
709 r->out.return_authenticator = return_authenticator;
717 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
718 struct netr_LogonSamLogon *r)
720 struct netr_LogonSamLogonWithFlags r2;
726 r2.in.server_name = r->in.server_name;
727 r2.in.computer_name = r->in.computer_name;
728 r2.in.credential = r->in.credential;
729 r2.in.return_authenticator = r->in.return_authenticator;
730 r2.in.logon_level = r->in.logon_level;
731 r2.in.logon = r->in.logon;
732 r2.in.validation_level = r->in.validation_level;
733 r2.in.flags = &flags;
734 r2.out.validation = r->out.validation;
735 r2.out.authoritative = r->out.authoritative;
736 r2.out.flags = &flags;
738 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
740 r->out.return_authenticator = r2.out.return_authenticator;
749 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
750 struct netr_LogonSamLogoff *r)
752 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
760 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
761 struct netr_DatabaseDeltas *r)
763 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
770 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
771 struct netr_DatabaseSync *r)
773 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
774 return NT_STATUS_NOT_IMPLEMENTED;
781 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
782 struct netr_AccountDeltas *r)
784 /* w2k3 returns "NOT IMPLEMENTED" for this call */
785 return NT_STATUS_NOT_IMPLEMENTED;
792 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
793 struct netr_AccountSync *r)
795 /* w2k3 returns "NOT IMPLEMENTED" for this call */
796 return NT_STATUS_NOT_IMPLEMENTED;
803 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
804 struct netr_GetDcName *r)
806 const char * const attrs[] = { NULL };
808 struct ldb_message **res;
809 struct ldb_dn *domain_dn;
813 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
814 dce_call->conn->dce_ctx->lp_ctx,
815 dce_call->conn->auth_state.session_info);
816 if (sam_ctx == NULL) {
817 return WERR_DS_SERVICE_UNAVAILABLE;
820 domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx,
822 if (domain_dn == NULL) {
823 return WERR_DS_SERVICE_UNAVAILABLE;
826 ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs);
828 return WERR_NO_SUCH_DOMAIN;
831 /* TODO: - return real IP address
832 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
834 dcname = talloc_asprintf(mem_ctx, "\\\\%s",
835 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
836 W_ERROR_HAVE_NO_MEMORY(dcname);
838 *r->out.dcname = dcname;
846 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
847 struct netr_LogonControl *r)
849 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
856 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
857 struct netr_GetAnyDCName *r)
859 struct netr_GetDcName r2;
864 r2.in.logon_server = r->in.logon_server;
865 r2.in.domainname = r->in.domainname;
866 r2.out.dcname = r->out.dcname;
868 werr = dcesrv_netr_GetDcName(dce_call, mem_ctx, &r2);
877 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
878 struct netr_LogonControl2 *r)
880 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
887 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
888 struct netr_DatabaseSync2 *r)
890 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
891 return NT_STATUS_NOT_IMPLEMENTED;
898 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
899 struct netr_DatabaseRedo *r)
901 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
908 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
909 struct netr_LogonControl2Ex *r)
911 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
916 netr_NetrEnumerateTurstedDomains
918 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
919 struct netr_NetrEnumerateTrustedDomains *r)
921 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
926 netr_NETRLOGONDUMMYROUTINE1
928 static WERROR dcesrv_netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
929 struct netr_NETRLOGONDUMMYROUTINE1 *r)
931 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
936 netr_NETRLOGONSETSERVICEBITS
938 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
939 struct netr_NETRLOGONSETSERVICEBITS *r)
941 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
946 netr_LogonGetTrustRid
948 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
949 struct netr_LogonGetTrustRid *r)
951 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
956 netr_NETRLOGONCOMPUTESERVERDIGEST
958 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
959 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
961 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
966 netr_NETRLOGONCOMPUTECLIENTDIGEST
968 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
969 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
971 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
979 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
980 struct netr_DsRGetSiteName *r)
982 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
987 fill in a netr_DomainTrustInfo from a ldb search result
989 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
990 struct ldb_message *res,
991 struct ldb_message *ref_res,
992 struct netr_DomainTrustInfo *info,
993 bool is_local, bool is_trust_list)
997 info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension);
998 info->trust_extension.length = 16;
999 info->trust_extension.info->flags =
1000 NETR_TRUST_FLAG_TREEROOT |
1001 NETR_TRUST_FLAG_IN_FOREST |
1002 NETR_TRUST_FLAG_PRIMARY;
1003 info->trust_extension.info->parent_index = 0; /* should be index into array
1005 info->trust_extension.info->trust_type = LSA_TRUST_TYPE_UPLEVEL; /* should be based on ldb search for trusts */
1006 info->trust_extension.info->trust_attributes = LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE; /* needs to be based on ldb search */
1008 if (is_trust_list) {
1009 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
1010 info->forest.string = NULL;
1012 /* TODO: we need a common function for pulling the forest */
1013 info->forest.string = samdb_result_string(ref_res, "dnsRoot", NULL);
1017 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
1018 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
1019 info->guid = samdb_result_guid(res, "objectGUID");
1020 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
1022 info->domainname.string = samdb_result_string(res, "flatName", NULL);
1023 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
1024 info->guid = samdb_result_guid(res, "objectGUID");
1025 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
1028 return NT_STATUS_OK;
1032 netr_LogonGetDomainInfo
1033 this is called as part of the ADS domain logon procedure.
1035 It has an important role in convaying details about the client, such
1036 as Operating System, Version, Service Pack etc.
1038 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1039 struct netr_LogonGetDomainInfo *r)
1041 const char * const attrs[] = { "objectSid",
1042 "objectGUID", "flatName", "securityIdentifier",
1043 "trustPartner", NULL };
1044 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1045 struct ldb_context *sam_ctx;
1046 struct ldb_message **res1, **res2, **ref_res;
1047 struct netr_DomainInfo1 *info1;
1048 int ret, ret1, ret2, i;
1050 struct ldb_dn *partitions_basedn;
1052 const char *local_domain;
1054 status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
1055 r->in.computer_name, mem_ctx,
1057 r->out.return_authenticator,
1059 if (!NT_STATUS_IS_OK(status)) {
1060 DEBUG(0,(__location__ " Bad credentials - error\n"));
1062 NT_STATUS_NOT_OK_RETURN(status);
1064 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1065 if (sam_ctx == NULL) {
1066 return NT_STATUS_INVALID_SYSTEM_SERVICE;
1069 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1071 /* we need to do two searches. The first will pull our primary
1072 domain and the second will pull any trusted domains. Our
1073 primary domain is also a "trusted" domain, so we need to
1074 put the primary domain into the lists of returned trusts as
1076 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
1078 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1081 /* try and find the domain */
1082 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
1083 &ref_res, ref_attrs,
1084 "(&(objectClass=crossRef)(ncName=%s))",
1085 ldb_dn_get_linearized(res1[0]->dn));
1087 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1090 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1092 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
1094 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1097 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
1098 NT_STATUS_HAVE_NO_MEMORY(info1);
1100 ZERO_STRUCTP(info1);
1102 info1->num_trusts = ret2 + 1;
1103 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
1105 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
1107 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo,
1109 NT_STATUS_NOT_OK_RETURN(status);
1111 for (i=0;i<ret2;i++) {
1112 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i],
1114 NT_STATUS_NOT_OK_RETURN(status);
1117 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i],
1119 NT_STATUS_NOT_OK_RETURN(status);
1121 info1->dns_hostname.string = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1122 info1->workstation_flags =
1123 NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | NETR_WS_FLAG_HANDLES_SPN_UPDATE;
1124 info1->supported_enc_types = 0; /* w2008 gives this 0 */
1126 r->out.info->info1 = info1;
1128 return NT_STATUS_OK;
1134 netr_ServerPasswordGet
1136 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1137 struct netr_ServerPasswordGet *r)
1139 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1144 netr_NETRLOGONSENDTOSAM
1146 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1147 struct netr_NETRLOGONSENDTOSAM *r)
1149 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1154 netr_DsRAddressToSitenamesW
1156 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1157 struct netr_DsRAddressToSitenamesW *r)
1159 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1164 netr_DsRGetDCNameEx2
1166 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1167 struct netr_DsRGetDCNameEx2 *r)
1169 const char * const attrs[] = { "objectGUID", NULL };
1171 struct ldb_message **res;
1172 struct ldb_dn *domain_dn;
1174 struct netr_DsRGetDCNameInfo *info;
1176 ZERO_STRUCTP(r->out.info);
1178 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1179 if (sam_ctx == NULL) {
1180 return WERR_DS_SERVICE_UNAVAILABLE;
1183 /* Win7-beta will send the domain name in the form the user typed, so we have to cope
1184 with both the short and long form here */
1185 if (strcasecmp(r->in.domain_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx)) == 0) {
1186 r->in.domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1189 domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx,
1191 if (domain_dn == NULL) {
1192 return WERR_DS_SERVICE_UNAVAILABLE;
1195 ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs);
1197 return WERR_NO_SUCH_DOMAIN;
1200 info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1201 W_ERROR_HAVE_NO_MEMORY(info);
1203 /* TODO: - return real IP address
1204 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1206 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1207 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1208 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1209 W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
1210 info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1211 W_ERROR_HAVE_NO_MEMORY(info->dc_address);
1212 info->dc_address_type = DS_ADDRESS_TYPE_INET;
1213 info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1214 info->domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1215 info->forest_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1216 info->dc_flags = DS_DNS_FOREST |
1219 DS_SERVER_WRITABLE |
1221 DS_SERVER_TIMESERV |
1227 info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1228 W_ERROR_HAVE_NO_MEMORY(info->dc_site_name);
1229 info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1230 W_ERROR_HAVE_NO_MEMORY(info->client_site_name);
1232 *r->out.info = info;
1240 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1241 struct netr_DsRGetDCNameEx *r)
1243 struct netr_DsRGetDCNameEx2 r2;
1248 r2.in.server_unc = r->in.server_unc;
1249 r2.in.client_account = NULL;
1251 r2.in.domain_guid = r->in.domain_guid;
1252 r2.in.domain_name = r->in.domain_name;
1253 r2.in.site_name = r->in.site_name;
1254 r2.in.flags = r->in.flags;
1255 r2.out.info = r->out.info;
1257 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1265 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1266 struct netr_DsRGetDCName *r)
1268 struct netr_DsRGetDCNameEx2 r2;
1273 r2.in.server_unc = r->in.server_unc;
1274 r2.in.client_account = NULL;
1276 r2.in.domain_name = r->in.domain_name;
1277 r2.in.domain_guid = r->in.domain_guid;
1279 r2.in.site_name = NULL; /* should fill in from site GUID */
1280 r2.in.flags = r->in.flags;
1281 r2.out.info = r->out.info;
1283 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1288 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1290 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1291 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1293 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1298 netr_NetrEnumerateTrustedDomainsEx
1300 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1301 struct netr_NetrEnumerateTrustedDomainsEx *r)
1303 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1308 netr_DsRAddressToSitenamesExW
1310 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1311 struct netr_DsRAddressToSitenamesExW *r)
1313 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1318 netr_DsrGetDcSiteCoverageW
1320 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1321 struct netr_DsrGetDcSiteCoverageW *r)
1323 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1328 netr_DsrEnumerateDomainTrusts
1330 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1331 struct netr_DsrEnumerateDomainTrusts *r)
1333 struct netr_DomainTrustList *trusts;
1336 struct ldb_message **dom_res, **ref_res;
1337 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1338 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1339 struct ldb_dn *partitions_basedn;
1341 ZERO_STRUCT(r->out);
1343 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1344 if (sam_ctx == NULL) {
1345 return WERR_GENERAL_FAILURE;
1348 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1350 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1352 return WERR_GENERAL_FAILURE;
1355 return WERR_GENERAL_FAILURE;
1358 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1359 "(&(objectClass=crossRef)(ncName=%s))",
1360 ldb_dn_get_linearized(dom_res[0]->dn));
1362 return WERR_GENERAL_FAILURE;
1365 return WERR_GENERAL_FAILURE;
1368 trusts = talloc(mem_ctx, struct netr_DomainTrustList);
1369 W_ERROR_HAVE_NO_MEMORY(trusts);
1371 trusts->array = talloc_array(trusts, struct netr_DomainTrust, ret);
1372 W_ERROR_HAVE_NO_MEMORY(trusts->array);
1374 trusts->count = 1; /* ?? */
1376 r->out.trusts = trusts;
1378 /* TODO: add filtering by trust_flags, and correct trust_type
1380 trusts->array[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1381 trusts->array[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1382 trusts->array[0].trust_flags =
1383 NETR_TRUST_FLAG_TREEROOT |
1384 NETR_TRUST_FLAG_IN_FOREST |
1385 NETR_TRUST_FLAG_PRIMARY;
1386 trusts->array[0].parent_index = 0;
1387 trusts->array[0].trust_type = 2;
1388 trusts->array[0].trust_attributes = 0;
1389 trusts->array[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1390 trusts->array[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1397 netr_DsrDeregisterDNSHostRecords
1399 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1400 struct netr_DsrDeregisterDNSHostRecords *r)
1402 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1407 netr_ServerTrustPasswordsGet
1409 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1410 struct netr_ServerTrustPasswordsGet *r)
1412 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1417 netr_DsRGetForestTrustInformation
1419 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1420 struct netr_DsRGetForestTrustInformation *r)
1422 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1427 netr_GetForestTrustInformation
1429 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1430 struct netr_GetForestTrustInformation *r)
1432 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1437 netr_ServerGetTrustInfo
1439 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1440 struct netr_ServerGetTrustInfo *r)
1442 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1446 /* include the generated boilerplate */
1447 #include "librpc/gen_ndr/ndr_netlogon_s.c"