2 Unix SMB/CIFS implementation.
4 endpoint server for the netlogon pipe
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004
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 2 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, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "rpc_server/dcerpc_server.h"
26 #include "rpc_server/common/common.h"
27 #include "lib/ldb/include/ldb.h"
28 #include "auth/auth.h"
29 #include "dsdb/samdb/samdb.h"
31 struct server_pipe_state {
32 struct netr_Credential client_challenge;
33 struct netr_Credential server_challenge;
35 /* This is a bit (dangeroursly?) tricky:
36 - The session key, computer name and domain elements are
38 - However the credentials chaining (seed, client, server etc)
39 should be obtained from the database at runtime */
40 struct creds_CredentialState *creds;
45 a client has connected to the netlogon server using schannel, so we need
46 to re-establish the credentials state
48 static NTSTATUS netlogon_schannel_setup(struct dcesrv_call_state *dce_call)
50 struct server_pipe_state *state;
53 /* We want the client and server challenge zero */
54 state = talloc_zero(dce_call->conn, struct server_pipe_state);
56 return NT_STATUS_NO_MEMORY;
59 status = dcerpc_schannel_creds(dce_call->conn->auth_state.gensec_security,
63 if (!NT_STATUS_IS_OK(status)) {
64 DEBUG(3, ("getting schannel credentials failed with %s\n", nt_errstr(status)));
69 dce_call->context->private = state;
75 a hook for bind on the netlogon pipe
77 static NTSTATUS netlogon_bind(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *di)
79 dce_call->context->private = NULL;
81 /* if this is a schannel bind then we need to reconstruct the pipe state */
82 if (dce_call->conn->auth_state.auth_info &&
83 dce_call->conn->auth_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
86 DEBUG(5, ("schannel bind on netlogon\n"));
88 status = netlogon_schannel_setup(dce_call);
89 if (!NT_STATUS_IS_OK(status)) {
90 DEBUG(3, ("schannel bind on netlogon failed with %s\n", nt_errstr(status)));
98 #define DCESRV_INTERFACE_NETLOGON_BIND netlogon_bind
100 static NTSTATUS netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
101 struct netr_ServerReqChallenge *r)
103 struct server_pipe_state *pipe_state = dce_call->context->private;
105 ZERO_STRUCTP(r->out.credentials);
107 /* destroyed on pipe shutdown */
110 talloc_free(pipe_state);
111 dce_call->context->private = NULL;
114 pipe_state = talloc(dce_call->context, struct server_pipe_state);
116 return NT_STATUS_NO_MEMORY;
119 pipe_state->creds = NULL;
121 pipe_state->client_challenge = *r->in.credentials;
123 generate_random_buffer(pipe_state->server_challenge.data,
124 sizeof(pipe_state->server_challenge.data));
126 *r->out.credentials = pipe_state->server_challenge;
128 dce_call->context->private = pipe_state;
133 static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
134 struct netr_ServerAuthenticate3 *r)
136 struct server_pipe_state *pipe_state = dce_call->context->private;
137 struct creds_CredentialState *creds;
139 struct samr_Password *mach_pwd;
142 struct ldb_message **msgs;
144 const char *attrs[] = {"ntPwdHash", "userAccountControl",
147 ZERO_STRUCTP(r->out.credentials);
149 *r->out.negotiate_flags = *r->in.negotiate_flags;
152 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
153 return NT_STATUS_ACCESS_DENIED;
156 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
157 if (sam_ctx == NULL) {
158 return NT_STATUS_INVALID_SYSTEM_SERVICE;
160 /* pull the user attributes */
161 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
162 "(&(sAMAccountName=%s)(objectclass=user))",
165 if (num_records == 0) {
166 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
167 r->in.account_name));
168 return NT_STATUS_ACCESS_DENIED;
171 if (num_records > 1) {
172 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
173 return NT_STATUS_INTERNAL_DB_CORRUPTION;
176 acct_flags = samdb_result_acct_flags(msgs[0],
177 "userAccountControl");
179 if (acct_flags & ACB_DISABLED) {
180 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
181 return NT_STATUS_ACCESS_DENIED;
184 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
185 if (!(acct_flags & ACB_WSTRUST)) {
186 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", acct_flags));
187 return NT_STATUS_ACCESS_DENIED;
189 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
190 if (!(acct_flags & ACB_DOMTRUST)) {
191 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", acct_flags));
192 return NT_STATUS_ACCESS_DENIED;
194 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
195 if (!(acct_flags & ACB_SVRTRUST)) {
196 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", acct_flags));
197 return NT_STATUS_ACCESS_DENIED;
200 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
201 r->in.secure_channel_type));
202 return NT_STATUS_ACCESS_DENIED;
205 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
208 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "ntPwdHash");
209 if (mach_pwd == NULL) {
210 return NT_STATUS_ACCESS_DENIED;
213 creds = talloc(mem_ctx, struct creds_CredentialState);
215 return NT_STATUS_NO_MEMORY;
218 creds_server_init(creds, &pipe_state->client_challenge,
219 &pipe_state->server_challenge, mach_pwd,
221 *r->in.negotiate_flags);
223 if (!creds_server_check(creds, r->in.credentials)) {
225 return NT_STATUS_ACCESS_DENIED;
228 creds->account_name = talloc_steal(creds, r->in.account_name);
230 creds->computer_name = talloc_steal(creds, r->in.computer_name);
231 creds->domain = talloc_strdup(creds, lp_workgroup());
233 creds->secure_channel_type = r->in.secure_channel_type;
235 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
238 /* remember this session key state */
239 nt_status = schannel_store_session_key(mem_ctx, creds);
241 if (pipe_state->creds) {
242 talloc_free(pipe_state->creds);
244 talloc_steal(pipe_state, creds);
245 pipe_state->creds = creds;
250 static NTSTATUS netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
251 struct netr_ServerAuthenticate *r)
253 struct netr_ServerAuthenticate3 r3;
256 * negotiate_flags is used as an [in] parameter
257 * so it need to be initialised.
259 * (I think ... = 0; seems wrong here --metze)
261 uint32_t negotiate_flags = 0;
263 r3.in.server_name = r->in.server_name;
264 r3.in.account_name = r->in.account_name;
265 r3.in.secure_channel_type = r->in.secure_channel_type;
266 r3.in.computer_name = r->in.computer_name;
267 r3.in.credentials = r->in.credentials;
268 r3.out.credentials = r->out.credentials;
269 r3.in.negotiate_flags = &negotiate_flags;
270 r3.out.negotiate_flags = &negotiate_flags;
273 return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
276 static NTSTATUS netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
277 struct netr_ServerAuthenticate2 *r)
279 struct netr_ServerAuthenticate3 r3;
282 r3.in.server_name = r->in.server_name;
283 r3.in.account_name = r->in.account_name;
284 r3.in.secure_channel_type = r->in.secure_channel_type;
285 r3.in.computer_name = r->in.computer_name;
286 r3.in.credentials = r->in.credentials;
287 r3.out.credentials = r->out.credentials;
288 r3.in.negotiate_flags = r->in.negotiate_flags;
289 r3.out.negotiate_flags = r->out.negotiate_flags;
292 return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
296 Validate an incoming authenticator against the credentials for the remote machine.
298 The credentials are (re)read and from the schannel database, and
299 written back after the caclulations are performed.
301 The creds_out parameter (if not NULL) returns the credentials, if
302 the caller needs some of that information.
305 static NTSTATUS netr_creds_server_step_check(struct server_pipe_state *pipe_state,
307 struct netr_Authenticator *received_authenticator,
308 struct netr_Authenticator *return_authenticator,
309 struct creds_CredentialState **creds_out)
311 struct creds_CredentialState *creds;
313 struct ldb_context *ldb;
317 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
318 return NT_STATUS_ACCESS_DENIED;
321 ldb = schannel_db_connect(mem_ctx);
323 return NT_STATUS_ACCESS_DENIED;
326 ret = ldb_transaction_start(ldb);
329 return NT_STATUS_INTERNAL_DB_CORRUPTION;
332 /* Because this is a shared structure (even across
333 * disconnects) we must update the database every time we
334 * update the structure */
336 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, pipe_state->creds->computer_name,
337 pipe_state->creds->domain, &creds);
338 if (NT_STATUS_IS_OK(nt_status)) {
339 nt_status = creds_server_step_check(creds,
340 received_authenticator,
341 return_authenticator);
343 if (NT_STATUS_IS_OK(nt_status)) {
344 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
347 if (NT_STATUS_IS_OK(nt_status)) {
348 ldb_transaction_commit(ldb);
351 talloc_steal(mem_ctx, creds);
354 ldb_transaction_cancel(ldb);
361 Change the machine account password for the currently connected
362 client. Supplies only the NT#.
365 static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
366 struct netr_ServerPasswordSet *r)
368 struct server_pipe_state *pipe_state = dce_call->context->private;
369 struct creds_CredentialState *creds;
370 struct ldb_context *sam_ctx;
373 nt_status = netr_creds_server_step_check(pipe_state, mem_ctx,
374 &r->in.credential, &r->out.return_authenticator,
376 NT_STATUS_NOT_OK_RETURN(nt_status);
378 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
379 if (sam_ctx == NULL) {
380 return NT_STATUS_INVALID_SYSTEM_SERVICE;
383 creds_des_decrypt(creds, &r->in.new_password);
385 /* Using the sid for the account as the key, set the password */
386 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
388 NULL, /* Don't have plaintext */
389 NULL, &r->in.new_password,
390 False, /* This is not considered a password change */
391 False, /* don't restrict this password change (match w2k3) */
397 Change the machine account password for the currently connected
398 client. Supplies new plaintext.
400 static NTSTATUS netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
401 struct netr_ServerPasswordSet2 *r)
403 struct server_pipe_state *pipe_state = dce_call->context->private;
404 struct creds_CredentialState *creds;
405 struct ldb_context *sam_ctx;
408 uint32_t new_pass_len;
411 struct samr_CryptPassword password_buf;
413 nt_status = netr_creds_server_step_check(pipe_state, mem_ctx,
414 &r->in.credential, &r->out.return_authenticator,
416 NT_STATUS_NOT_OK_RETURN(nt_status);
418 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
419 if (sam_ctx == NULL) {
420 return NT_STATUS_INVALID_SYSTEM_SERVICE;
423 memcpy(password_buf.data, r->in.new_password.data, 512);
424 SIVAL(password_buf.data,512,r->in.new_password.length);
425 creds_arcfour_crypt(creds, password_buf.data, 516);
427 ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
428 &new_pass_len, STR_UNICODE);
430 DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
431 return NT_STATUS_ACCESS_DENIED;
434 /* Using the sid for the account as the key, set the password */
435 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
437 new_pass, /* we have plaintext */
439 False, /* This is not considered a password change */
440 False, /* don't restrict this password change (match w2k3) */
449 static WERROR netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
450 struct netr_LogonUasLogon *r)
452 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
459 static WERROR netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
460 struct netr_LogonUasLogoff *r)
462 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
469 This version of the function allows other wrappers to say 'do not check the credentials'
471 static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
472 struct netr_LogonSamLogonEx *r)
474 struct server_pipe_state *pipe_state = dce_call->context->private;
475 struct creds_CredentialState *creds = pipe_state->creds;
476 struct auth_context *auth_context;
477 struct auth_usersupplied_info *user_info;
478 struct auth_serversupplied_info *server_info;
480 static const char zeros[16];
481 struct netr_SamBaseInfo *sam;
482 struct netr_SamInfo2 *sam2;
483 struct netr_SamInfo3 *sam3;
484 struct netr_SamInfo6 *sam6;
486 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
488 return NT_STATUS_NO_MEMORY;
491 user_info->flags = 0;
492 user_info->mapped_state = False;
493 user_info->remote_host = NULL;
495 switch (r->in.logon_level) {
499 if (pipe_state->creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
500 creds_arcfour_crypt(creds,
501 r->in.logon.password->lmpassword.hash,
502 sizeof(r->in.logon.password->lmpassword.hash));
503 creds_arcfour_crypt(creds,
504 r->in.logon.password->ntpassword.hash,
505 sizeof(r->in.logon.password->ntpassword.hash));
507 creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
508 creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
511 /* TODO: we need to deny anonymous access here */
512 nt_status = auth_context_create(mem_ctx, lp_auth_methods(), &auth_context,
513 dce_call->event_ctx);
514 NT_STATUS_NOT_OK_RETURN(nt_status);
516 user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
517 user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
518 user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
519 user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
521 user_info->password_state = AUTH_PASSWORD_HASH;
522 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
523 if (!user_info->password.hash.lanman) {
524 return NT_STATUS_NO_MEMORY;
526 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
528 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
529 if (!user_info->password.hash.nt) {
530 return NT_STATUS_NO_MEMORY;
532 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
534 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
540 /* TODO: we need to deny anonymous access here */
541 nt_status = auth_context_create(mem_ctx, lp_auth_methods(), &auth_context,
542 dce_call->event_ctx);
543 NT_STATUS_NOT_OK_RETURN(nt_status);
545 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
546 NT_STATUS_NOT_OK_RETURN(nt_status);
548 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
549 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
550 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
551 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
553 user_info->password_state = AUTH_PASSWORD_RESPONSE;
554 user_info->password.response.lanman = data_blob(r->in.logon.network->lm.data, r->in.logon.network->lm.length);
555 user_info->password.response.nt = data_blob(r->in.logon.network->nt.data, r->in.logon.network->nt.length);
559 return NT_STATUS_INVALID_PARAMETER;
562 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
563 NT_STATUS_NOT_OK_RETURN(nt_status);
565 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
567 NT_STATUS_NOT_OK_RETURN(nt_status);
569 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
570 /* It appears that level 6 is not individually encrypted */
571 if ((r->in.validation_level != 6)
572 && memcmp(sam->key.key, zeros,
573 sizeof(sam->key.key)) != 0) {
575 /* This key is sent unencrypted without the ARCFOUR flag set */
576 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
577 creds_arcfour_crypt(creds,
579 sizeof(sam->key.key));
583 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
584 /* It appears that level 6 is not individually encrypted */
585 if ((r->in.validation_level != 6)
586 && memcmp(sam->LMSessKey.key, zeros,
587 sizeof(sam->LMSessKey.key)) != 0) {
588 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
589 creds_arcfour_crypt(creds,
591 sizeof(sam->LMSessKey.key));
593 creds_des_encrypt_LMKey(creds,
598 switch (r->in.validation_level) {
600 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
601 NT_STATUS_HAVE_NO_MEMORY(sam2);
603 r->out.validation.sam2 = sam2;
607 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
608 NT_STATUS_HAVE_NO_MEMORY(sam3);
610 r->out.validation.sam3 = sam3;
614 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
615 NT_STATUS_HAVE_NO_MEMORY(sam6);
617 sam6->forest.string = lp_realm();
618 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
619 sam->account_name.string, sam6->forest.string);
620 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
621 r->out.validation.sam6 = sam6;
628 r->out.authoritative = 1;
630 /* TODO: Describe and deal with these flags */
637 netr_LogonSamLogonWithFlags
640 static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
641 struct netr_LogonSamLogonWithFlags *r)
643 struct server_pipe_state *pipe_state = dce_call->context->private;
645 struct netr_LogonSamLogonEx r2;
647 struct netr_Authenticator *return_authenticator;
649 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
650 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
652 nt_status = netr_creds_server_step_check(pipe_state, mem_ctx,
653 r->in.credential, return_authenticator,
655 NT_STATUS_NOT_OK_RETURN(nt_status);
659 r2.in.server_name = r->in.server_name;
660 r2.in.workstation = r->in.workstation;
661 r2.in.logon_level = r->in.logon_level;
662 r2.in.logon = r->in.logon;
663 r2.in.validation_level = r->in.validation_level;
664 r2.in.flags = r->in.flags;
666 nt_status = netr_LogonSamLogonEx(dce_call, mem_ctx, &r2);
668 r->out.return_authenticator = return_authenticator;
669 r->out.validation = r2.out.validation;
670 r->out.authoritative = r2.out.authoritative;
671 r->out.flags = r2.out.flags;
679 static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
680 struct netr_LogonSamLogon *r)
682 struct netr_LogonSamLogonWithFlags r2;
687 r2.in.server_name = r->in.server_name;
688 r2.in.workstation = r->in.workstation;
689 r2.in.credential = r->in.credential;
690 r2.in.return_authenticator = r->in.return_authenticator;
691 r2.in.logon_level = r->in.logon_level;
692 r2.in.logon = r->in.logon;
693 r2.in.validation_level = r->in.validation_level;
696 status = netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
698 r->out.return_authenticator = r2.out.return_authenticator;
699 r->out.validation = r2.out.validation;
700 r->out.authoritative = r2.out.authoritative;
709 static NTSTATUS netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
710 struct netr_LogonSamLogoff *r)
712 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
720 static NTSTATUS netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
721 struct netr_DatabaseDeltas *r)
723 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
730 static NTSTATUS netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
731 struct netr_DatabaseSync *r)
733 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
740 static NTSTATUS netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
741 struct netr_AccountDeltas *r)
743 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
750 static NTSTATUS netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
751 struct netr_AccountSync *r)
753 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
760 static NTSTATUS netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
761 struct netr_GetDcName *r)
763 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
770 static WERROR netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
771 struct netr_LogonControl *r)
773 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
780 static WERROR netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
781 struct netr_GetAnyDCName *r)
783 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
790 static WERROR netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
791 struct netr_LogonControl2 *r)
793 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
800 static NTSTATUS netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
801 struct netr_DatabaseSync2 *r)
803 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
810 static NTSTATUS netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
811 struct netr_DatabaseRedo *r)
813 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
820 static WERROR netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
821 struct netr_LogonControl2Ex *r)
823 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
828 netr_NETRENUMERATETRUSTEDDOMAINS
830 static WERROR netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
831 struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
833 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
838 netr_NETRLOGONDUMMYROUTINE1
840 static WERROR netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
841 struct netr_NETRLOGONDUMMYROUTINE1 *r)
843 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
848 netr_NETRLOGONSETSERVICEBITS
850 static WERROR netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
851 struct netr_NETRLOGONSETSERVICEBITS *r)
853 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
858 netr_NETRLOGONGETTRUSTRID
860 static WERROR netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
861 struct netr_NETRLOGONGETTRUSTRID *r)
863 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
868 netr_NETRLOGONCOMPUTESERVERDIGEST
870 static WERROR netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
871 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
873 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
878 netr_NETRLOGONCOMPUTECLIENTDIGEST
880 static WERROR netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
881 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
883 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
891 static WERROR netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
892 struct netr_DsRGetSiteName *r)
894 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
899 fill in a netr_DomainTrustInfo from a ldb search result
901 static NTSTATUS fill_domain_primary_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
902 struct netr_DomainTrustInfo *info,
903 const char *local_domain)
907 info->domainname.string = local_domain;
908 info->fulldomainname.string = talloc_asprintf(info, "%s.", samdb_result_string(res, "dnsDomain", NULL));
909 /* TODO: we need proper forest support */
910 info->forest.string = info->fulldomainname.string;
911 info->guid = samdb_result_guid(res, "objectGUID");
912 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
918 fill in a netr_DomainTrustInfo from a ldb search result
920 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
921 struct netr_DomainTrustInfo *info,
922 const char *local_domain, BOOL is_local)
927 info->domainname.string = local_domain;
928 info->fulldomainname.string = samdb_result_string(res, "dnsDomain", NULL);
929 info->forest.string = NULL;
930 info->guid = samdb_result_guid(res, "objectGUID");
931 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
933 info->domainname.string = samdb_result_string(res, "flatName", NULL);
934 info->fulldomainname.string = samdb_result_string(res, "name", NULL);
935 info->forest.string = NULL;
936 info->guid = samdb_result_guid(res, "objectGUID");
937 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
944 netr_LogonGetDomainInfo
945 this is called as part of the ADS domain logon procedure.
947 static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
948 struct netr_LogonGetDomainInfo *r)
950 struct server_pipe_state *pipe_state = dce_call->context->private;
951 const char * const attrs[] = { "dnsDomain", "objectSid",
952 "objectGUID", "flatName", "securityIdentifier",
954 const char * const ref_attrs[] = { "nETBIOSName", NULL };
955 struct ldb_context *sam_ctx;
956 struct ldb_message **res1, **res2, **ref_res;
957 struct netr_DomainInfo1 *info1;
958 int ret, ret1, ret2, i;
961 const char *local_domain;
963 status = netr_creds_server_step_check(pipe_state, mem_ctx,
965 r->out.return_authenticator,
967 if (!NT_STATUS_IS_OK(status)) {
971 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
972 if (sam_ctx == NULL) {
973 return NT_STATUS_INVALID_SYSTEM_SERVICE;
976 /* we need to do two searches. The first will pull our primary
977 domain and the second will pull any trusted domains. Our
978 primary domain is also a "trusted" domain, so we need to
979 put the primary domain into the lists of returned trusts as
981 ret1 = gendb_search(sam_ctx, mem_ctx, NULL, &res1, attrs, "(objectClass=domainDNS)");
983 return NT_STATUS_INTERNAL_DB_CORRUPTION;
986 /* try and find the domain */
987 ret = gendb_search(sam_ctx, mem_ctx, NULL,
989 "(&(objectClass=crossRef)(ncName=%s))",
990 ldb_dn_linearize(mem_ctx, res1[0]->dn));
992 return NT_STATUS_INTERNAL_DB_CORRUPTION;
995 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
997 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
999 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1002 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
1003 if (info1 == NULL) {
1004 return NT_STATUS_NO_MEMORY;
1007 ZERO_STRUCTP(info1);
1009 info1->num_trusts = ret2 + 1;
1010 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
1012 if (info1->trusts == NULL) {
1013 return NT_STATUS_NO_MEMORY;
1016 status = fill_domain_primary_info(mem_ctx, res1[0], &info1->domaininfo, local_domain);
1017 if (!NT_STATUS_IS_OK(status)) {
1021 for (i=0;i<ret2;i++) {
1022 status = fill_domain_trust_info(mem_ctx, res2[i], &info1->trusts[i], NULL, False);
1023 if (!NT_STATUS_IS_OK(status)) {
1028 status = fill_domain_trust_info(mem_ctx, res1[0], &info1->trusts[i], local_domain, True);
1029 if (!NT_STATUS_IS_OK(status)) {
1033 r->out.info.info1 = info1;
1035 return NT_STATUS_OK;
1041 netr_NETRSERVERPASSWORDGET
1043 static WERROR netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1044 struct netr_NETRSERVERPASSWORDGET *r)
1046 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1051 netr_NETRLOGONSENDTOSAM
1053 static WERROR netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1054 struct netr_NETRLOGONSENDTOSAM *r)
1056 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1061 netr_DSRADDRESSTOSITENAMESW
1063 static WERROR netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1064 struct netr_DSRADDRESSTOSITENAMESW *r)
1066 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1071 netr_DsRGetDCNameEx2
1073 static WERROR netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1074 struct netr_DsRGetDCNameEx2 *r)
1076 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
1078 struct ldb_message **res;
1081 ZERO_STRUCT(r->out);
1083 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1084 if (sam_ctx == NULL) {
1085 return WERR_DS_SERVICE_UNAVAILABLE;
1088 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
1089 "(&(objectClass=domainDNS)(dnsDomain=%s))",
1092 return WERR_NO_SUCH_DOMAIN;
1095 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1100 /* TODO: - return real IP address
1101 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1103 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s", lp_netbios_name(),lp_realm());
1104 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1105 r->out.info->dc_address_type = 1;
1106 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1107 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1108 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1109 r->out.info->dc_flags = 0xE00001FD;
1110 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1111 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1119 static WERROR netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1120 struct netr_DsRGetDCNameEx *r)
1122 struct netr_DsRGetDCNameEx2 r2;
1127 r2.in.server_unc = r->in.server_unc;
1128 r2.in.client_account = NULL;
1130 r2.in.domain_guid = r->in.domain_guid;
1131 r2.in.domain_name = r->in.domain_name;
1132 r2.in.site_name = r->in.site_name;
1133 r2.in.flags = r->in.flags;
1136 werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1138 r->out.info = r2.out.info;
1146 static WERROR netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1147 struct netr_DsRGetDCName *r)
1149 struct netr_DsRGetDCNameEx2 r2;
1154 r2.in.server_unc = r->in.server_unc;
1155 r2.in.client_account = NULL;
1157 r2.in.domain_name = r->in.domain_name;
1158 r2.in.domain_guid = r->in.domain_guid;
1160 r2.in.site_name = NULL; /* should fill in from site GUID */
1161 r2.in.flags = r->in.flags;
1164 werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1166 r->out.info = r2.out.info;
1172 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1174 static WERROR netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1175 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1177 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1182 netr_NETRENUMERATETRUSTEDDOMAINSEX
1184 static WERROR netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1185 struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
1187 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1192 netr_DSRADDRESSTOSITENAMESEXW
1194 static WERROR netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1195 struct netr_DSRADDRESSTOSITENAMESEXW *r)
1197 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1202 netr_DSRGETDCSITECOVERAGEW
1204 static WERROR netr_DSRGETDCSITECOVERAGEW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1205 struct netr_DSRGETDCSITECOVERAGEW *r)
1207 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1212 netr_DsrEnumerateDomainTrusts
1214 static WERROR netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1215 struct netr_DsrEnumerateDomainTrusts *r)
1217 struct netr_DomainTrust *trusts;
1220 struct ldb_message **dom_res, **ref_res;
1221 const char * const dom_attrs[] = { "dnsDomain", "objectSid", "objectGUID", NULL };
1222 const char * const ref_attrs[] = { "nETBIOSName", NULL };
1224 ZERO_STRUCT(r->out);
1226 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1227 if (sam_ctx == NULL) {
1228 return WERR_GENERAL_FAILURE;
1231 ret = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(mem_ctx), &dom_res, dom_attrs);
1233 return WERR_GENERAL_FAILURE;
1237 return WERR_GENERAL_FAILURE;
1240 ret = gendb_search(sam_ctx, mem_ctx, NULL, &ref_res, ref_attrs,
1241 "(&(objectClass=crossRef)(ncName=%s))",
1242 ldb_dn_linearize(mem_ctx, dom_res[0]->dn));
1244 return WERR_GENERAL_FAILURE;
1248 return WERR_GENERAL_FAILURE;
1253 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1254 if (trusts == NULL) {
1259 r->out.trusts = trusts;
1261 /* TODO: add filtering by trust_flags, and correct trust_type
1263 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1264 trusts[0].dns_name = samdb_result_string(dom_res[0], "dnsDomain", NULL);
1265 trusts[0].trust_flags =
1266 NETR_TRUST_FLAG_TREEROOT |
1267 NETR_TRUST_FLAG_IN_FOREST |
1268 NETR_TRUST_FLAG_PRIMARY;
1269 trusts[0].parent_index = 0;
1270 trusts[0].trust_type = 2;
1271 trusts[0].trust_attributes = 0;
1272 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1273 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1280 netr_DSRDEREGISTERDNSHOSTRECORDS
1282 static WERROR netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1283 struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1285 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1290 netr_NETRSERVERTRUSTPASSWORDSGET
1292 static WERROR netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1293 struct netr_NETRSERVERTRUSTPASSWORDSGET *r)
1295 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1300 netr_DSRGETFORESTTRUSTINFORMATION
1302 static WERROR netr_DSRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1303 struct netr_DSRGETFORESTTRUSTINFORMATION *r)
1305 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1310 netr_NETRGETFORESTTRUSTINFORMATION
1312 static WERROR netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1313 struct netr_NETRGETFORESTTRUSTINFORMATION *r)
1315 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1320 netr_NETRSERVERGETTRUSTINFO
1322 static WERROR netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1323 struct netr_NETRSERVERGETTRUSTINFO *r)
1325 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1329 /* include the generated boilerplate */
1330 #include "librpc/gen_ndr/ndr_netlogon_s.c"