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"
30 #include "rpc_server/samr/proto.h"
32 struct server_pipe_state {
33 struct netr_Credential client_challenge;
34 struct netr_Credential server_challenge;
38 static NTSTATUS netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
39 struct netr_ServerReqChallenge *r)
41 struct server_pipe_state *pipe_state = dce_call->context->private;
43 ZERO_STRUCTP(r->out.credentials);
45 /* destroyed on pipe shutdown */
48 talloc_free(pipe_state);
49 dce_call->context->private = NULL;
52 pipe_state = talloc(dce_call->context, struct server_pipe_state);
54 return NT_STATUS_NO_MEMORY;
57 pipe_state->client_challenge = *r->in.credentials;
59 generate_random_buffer(pipe_state->server_challenge.data,
60 sizeof(pipe_state->server_challenge.data));
62 *r->out.credentials = pipe_state->server_challenge;
64 dce_call->context->private = pipe_state;
69 static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
70 struct netr_ServerAuthenticate3 *r)
72 struct server_pipe_state *pipe_state = dce_call->context->private;
73 struct creds_CredentialState *creds;
75 struct samr_Password *mach_pwd;
78 struct ldb_message **msgs;
80 const char *attrs[] = {"ntPwdHash", "userAccountControl",
83 ZERO_STRUCTP(r->out.credentials);
85 *r->out.negotiate_flags = *r->in.negotiate_flags;
88 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
89 return NT_STATUS_ACCESS_DENIED;
92 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
93 if (sam_ctx == NULL) {
94 return NT_STATUS_INVALID_SYSTEM_SERVICE;
96 /* pull the user attributes */
97 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
98 "(&(sAMAccountName=%s)(objectclass=user))",
101 if (num_records == 0) {
102 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
103 r->in.account_name));
104 return NT_STATUS_ACCESS_DENIED;
107 if (num_records > 1) {
108 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
109 return NT_STATUS_INTERNAL_DB_CORRUPTION;
112 acct_flags = samdb_result_acct_flags(msgs[0],
113 "userAccountControl");
115 if (acct_flags & ACB_DISABLED) {
116 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
117 return NT_STATUS_ACCESS_DENIED;
120 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
121 if (!(acct_flags & ACB_WSTRUST)) {
122 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", acct_flags));
123 return NT_STATUS_ACCESS_DENIED;
125 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
126 if (!(acct_flags & ACB_DOMTRUST)) {
127 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", acct_flags));
128 return NT_STATUS_ACCESS_DENIED;
130 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
131 if (!(acct_flags & ACB_SVRTRUST)) {
132 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", acct_flags));
133 return NT_STATUS_ACCESS_DENIED;
136 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
137 r->in.secure_channel_type));
138 return NT_STATUS_ACCESS_DENIED;
141 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
144 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "ntPwdHash");
145 if (mach_pwd == NULL) {
146 return NT_STATUS_ACCESS_DENIED;
149 creds = talloc(mem_ctx, struct creds_CredentialState);
151 return NT_STATUS_NO_MEMORY;
154 creds_server_init(creds, &pipe_state->client_challenge,
155 &pipe_state->server_challenge, mach_pwd,
157 *r->in.negotiate_flags);
159 if (!creds_server_check(creds, r->in.credentials)) {
161 return NT_STATUS_ACCESS_DENIED;
164 creds->account_name = talloc_steal(creds, r->in.account_name);
166 creds->computer_name = talloc_steal(creds, r->in.computer_name);
167 creds->domain = talloc_strdup(creds, lp_workgroup());
169 creds->secure_channel_type = r->in.secure_channel_type;
171 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
174 /* remember this session key state */
175 nt_status = schannel_store_session_key(mem_ctx, creds);
180 static NTSTATUS netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
181 struct netr_ServerAuthenticate *r)
183 struct netr_ServerAuthenticate3 r3;
186 * negotiate_flags is used as an [in] parameter
187 * so it need to be initialised.
189 * (I think ... = 0; seems wrong here --metze)
191 uint32_t negotiate_flags = 0;
193 r3.in.server_name = r->in.server_name;
194 r3.in.account_name = r->in.account_name;
195 r3.in.secure_channel_type = r->in.secure_channel_type;
196 r3.in.computer_name = r->in.computer_name;
197 r3.in.credentials = r->in.credentials;
198 r3.out.credentials = r->out.credentials;
199 r3.in.negotiate_flags = &negotiate_flags;
200 r3.out.negotiate_flags = &negotiate_flags;
203 return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
206 static NTSTATUS netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
207 struct netr_ServerAuthenticate2 *r)
209 struct netr_ServerAuthenticate3 r3;
212 r3.in.server_name = r->in.server_name;
213 r3.in.account_name = r->in.account_name;
214 r3.in.secure_channel_type = r->in.secure_channel_type;
215 r3.in.computer_name = r->in.computer_name;
216 r3.in.credentials = r->in.credentials;
217 r3.out.credentials = r->out.credentials;
218 r3.in.negotiate_flags = r->in.negotiate_flags;
219 r3.out.negotiate_flags = r->out.negotiate_flags;
222 return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
226 Validate an incoming authenticator against the credentials for the remote machine.
228 The credentials are (re)read and from the schannel database, and
229 written back after the caclulations are performed.
231 The creds_out parameter (if not NULL) returns the credentials, if
232 the caller needs some of that information.
235 static NTSTATUS netr_creds_server_step_check(const char *computer_name,
237 struct netr_Authenticator *received_authenticator,
238 struct netr_Authenticator *return_authenticator,
239 struct creds_CredentialState **creds_out)
241 struct creds_CredentialState *creds;
243 struct ldb_context *ldb;
246 ldb = schannel_db_connect(mem_ctx);
248 return NT_STATUS_ACCESS_DENIED;
251 ret = ldb_transaction_start(ldb);
254 return NT_STATUS_INTERNAL_DB_CORRUPTION;
257 /* Because this is a shared structure (even across
258 * disconnects) we must update the database every time we
259 * update the structure */
261 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name, lp_workgroup(),
263 if (NT_STATUS_IS_OK(nt_status)) {
264 nt_status = creds_server_step_check(creds,
265 received_authenticator,
266 return_authenticator);
268 if (NT_STATUS_IS_OK(nt_status)) {
269 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
272 if (NT_STATUS_IS_OK(nt_status)) {
273 ldb_transaction_commit(ldb);
276 talloc_steal(mem_ctx, creds);
279 ldb_transaction_cancel(ldb);
286 Change the machine account password for the currently connected
287 client. Supplies only the NT#.
290 static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
291 struct netr_ServerPasswordSet *r)
293 struct creds_CredentialState *creds;
294 struct ldb_context *sam_ctx;
297 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
298 &r->in.credential, &r->out.return_authenticator,
300 NT_STATUS_NOT_OK_RETURN(nt_status);
302 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
303 if (sam_ctx == NULL) {
304 return NT_STATUS_INVALID_SYSTEM_SERVICE;
307 creds_des_decrypt(creds, &r->in.new_password);
309 /* Using the sid for the account as the key, set the password */
310 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
312 NULL, /* Don't have plaintext */
313 NULL, &r->in.new_password,
314 False, /* This is not considered a password change */
315 False, /* don't restrict this password change (match w2k3) */
321 Change the machine account password for the currently connected
322 client. Supplies new plaintext.
324 static NTSTATUS netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
325 struct netr_ServerPasswordSet2 *r)
327 struct creds_CredentialState *creds;
328 struct ldb_context *sam_ctx;
331 uint32_t new_pass_len;
334 struct samr_CryptPassword password_buf;
336 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
337 &r->in.credential, &r->out.return_authenticator,
339 NT_STATUS_NOT_OK_RETURN(nt_status);
341 sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
342 if (sam_ctx == NULL) {
343 return NT_STATUS_INVALID_SYSTEM_SERVICE;
346 memcpy(password_buf.data, r->in.new_password.data, 512);
347 SIVAL(password_buf.data,512,r->in.new_password.length);
348 creds_arcfour_crypt(creds, password_buf.data, 516);
350 ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
351 &new_pass_len, STR_UNICODE);
353 DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
354 return NT_STATUS_ACCESS_DENIED;
357 /* Using the sid for the account as the key, set the password */
358 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
360 new_pass, /* we have plaintext */
362 False, /* This is not considered a password change */
363 False, /* don't restrict this password change (match w2k3) */
372 static WERROR netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
373 struct netr_LogonUasLogon *r)
375 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
382 static WERROR netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
383 struct netr_LogonUasLogoff *r)
385 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
390 netr_LogonSamLogon_base
392 This version of the function allows other wrappers to say 'do not check the credentials'
394 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
396 static NTSTATUS netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
397 struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
399 struct auth_context *auth_context;
400 struct auth_usersupplied_info *user_info;
401 struct auth_serversupplied_info *server_info;
403 static const char zeros[16];
404 struct netr_SamBaseInfo *sam;
405 struct netr_SamInfo2 *sam2;
406 struct netr_SamInfo3 *sam3;
407 struct netr_SamInfo6 *sam6;
409 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
411 return NT_STATUS_NO_MEMORY;
414 user_info->flags = 0;
415 user_info->mapped_state = False;
416 user_info->remote_host = NULL;
418 switch (r->in.logon_level) {
422 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
423 creds_arcfour_crypt(creds,
424 r->in.logon.password->lmpassword.hash,
425 sizeof(r->in.logon.password->lmpassword.hash));
426 creds_arcfour_crypt(creds,
427 r->in.logon.password->ntpassword.hash,
428 sizeof(r->in.logon.password->ntpassword.hash));
430 creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
431 creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
434 /* TODO: we need to deny anonymous access here */
435 nt_status = auth_context_create(mem_ctx, lp_auth_methods(), &auth_context,
436 dce_call->event_ctx);
437 NT_STATUS_NOT_OK_RETURN(nt_status);
439 user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
440 user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
441 user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
442 user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
444 user_info->password_state = AUTH_PASSWORD_HASH;
445 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
446 if (!user_info->password.hash.lanman) {
447 return NT_STATUS_NO_MEMORY;
449 *user_info->password.hash.lanman = r->in.logon.password->lmpassword;
451 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
452 if (!user_info->password.hash.nt) {
453 return NT_STATUS_NO_MEMORY;
455 *user_info->password.hash.nt = r->in.logon.password->ntpassword;
457 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
463 /* TODO: we need to deny anonymous access here */
464 nt_status = auth_context_create(mem_ctx, lp_auth_methods(), &auth_context,
465 dce_call->event_ctx);
466 NT_STATUS_NOT_OK_RETURN(nt_status);
468 nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
469 NT_STATUS_NOT_OK_RETURN(nt_status);
471 user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
472 user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
473 user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
474 user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
476 user_info->password_state = AUTH_PASSWORD_RESPONSE;
477 user_info->password.response.lanman = data_blob(r->in.logon.network->lm.data, r->in.logon.network->lm.length);
478 user_info->password.response.nt = data_blob(r->in.logon.network->nt.data, r->in.logon.network->nt.length);
482 return NT_STATUS_INVALID_PARAMETER;
485 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
486 NT_STATUS_NOT_OK_RETURN(nt_status);
488 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
490 NT_STATUS_NOT_OK_RETURN(nt_status);
492 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
493 /* It appears that level 6 is not individually encrypted */
494 if ((r->in.validation_level != 6)
495 && memcmp(sam->key.key, zeros,
496 sizeof(sam->key.key)) != 0) {
498 /* This key is sent unencrypted without the ARCFOUR flag set */
499 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
500 creds_arcfour_crypt(creds,
502 sizeof(sam->key.key));
506 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
507 /* It appears that level 6 is not individually encrypted */
508 if ((r->in.validation_level != 6)
509 && memcmp(sam->LMSessKey.key, zeros,
510 sizeof(sam->LMSessKey.key)) != 0) {
511 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
512 creds_arcfour_crypt(creds,
514 sizeof(sam->LMSessKey.key));
516 creds_des_encrypt_LMKey(creds,
521 switch (r->in.validation_level) {
523 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
524 NT_STATUS_HAVE_NO_MEMORY(sam2);
526 r->out.validation.sam2 = sam2;
530 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
531 NT_STATUS_HAVE_NO_MEMORY(sam3);
533 r->out.validation.sam3 = sam3;
537 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
538 NT_STATUS_HAVE_NO_MEMORY(sam6);
540 sam6->forest.string = lp_realm();
541 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
542 sam->account_name.string, sam6->forest.string);
543 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
544 r->out.validation.sam6 = sam6;
551 r->out.authoritative = 1;
553 /* TODO: Describe and deal with these flags */
559 static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
560 struct netr_LogonSamLogonEx *r)
563 struct creds_CredentialState *creds;
564 nt_status = schannel_fetch_session_key(mem_ctx, r->in.computer_name, lp_workgroup(), &creds);
565 if (!NT_STATUS_IS_OK(nt_status)) {
569 if (!dce_call->conn->auth_state.auth_info
570 || dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
571 return NT_STATUS_INTERNAL_ERROR;
573 return netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
577 netr_LogonSamLogonWithFlags
580 static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
581 struct netr_LogonSamLogonWithFlags *r)
584 struct creds_CredentialState *creds;
585 struct netr_LogonSamLogonEx r2;
587 struct netr_Authenticator *return_authenticator;
589 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
590 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
592 nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
593 r->in.credential, return_authenticator,
595 NT_STATUS_NOT_OK_RETURN(nt_status);
599 r2.in.server_name = r->in.server_name;
600 r2.in.computer_name = r->in.computer_name;
601 r2.in.logon_level = r->in.logon_level;
602 r2.in.logon = r->in.logon;
603 r2.in.validation_level = r->in.validation_level;
604 r2.in.flags = r->in.flags;
606 nt_status = netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
608 r->out.return_authenticator = return_authenticator;
609 r->out.validation = r2.out.validation;
610 r->out.authoritative = r2.out.authoritative;
611 r->out.flags = r2.out.flags;
619 static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
620 struct netr_LogonSamLogon *r)
622 struct netr_LogonSamLogonWithFlags r2;
627 r2.in.server_name = r->in.server_name;
628 r2.in.computer_name = r->in.computer_name;
629 r2.in.credential = r->in.credential;
630 r2.in.return_authenticator = r->in.return_authenticator;
631 r2.in.logon_level = r->in.logon_level;
632 r2.in.logon = r->in.logon;
633 r2.in.validation_level = r->in.validation_level;
636 status = netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
638 r->out.return_authenticator = r2.out.return_authenticator;
639 r->out.validation = r2.out.validation;
640 r->out.authoritative = r2.out.authoritative;
649 static NTSTATUS netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
650 struct netr_LogonSamLogoff *r)
652 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
660 static NTSTATUS netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
661 struct netr_DatabaseDeltas *r)
663 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
670 static NTSTATUS netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
671 struct netr_DatabaseSync *r)
673 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
680 static NTSTATUS netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
681 struct netr_AccountDeltas *r)
683 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
690 static NTSTATUS netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
691 struct netr_AccountSync *r)
693 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
700 static NTSTATUS netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
701 struct netr_GetDcName *r)
703 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
710 static WERROR netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
711 struct netr_LogonControl *r)
713 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
720 static WERROR netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
721 struct netr_GetAnyDCName *r)
723 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
730 static WERROR netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
731 struct netr_LogonControl2 *r)
733 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
740 static NTSTATUS netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
741 struct netr_DatabaseSync2 *r)
743 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
750 static NTSTATUS netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
751 struct netr_DatabaseRedo *r)
753 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
760 static WERROR netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
761 struct netr_LogonControl2Ex *r)
763 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
768 netr_NETRENUMERATETRUSTEDDOMAINS
770 static WERROR netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
771 struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
773 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
778 netr_NETRLOGONDUMMYROUTINE1
780 static WERROR netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
781 struct netr_NETRLOGONDUMMYROUTINE1 *r)
783 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
788 netr_NETRLOGONSETSERVICEBITS
790 static WERROR netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
791 struct netr_NETRLOGONSETSERVICEBITS *r)
793 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
798 netr_NETRLOGONGETTRUSTRID
800 static WERROR netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
801 struct netr_NETRLOGONGETTRUSTRID *r)
803 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
808 netr_NETRLOGONCOMPUTESERVERDIGEST
810 static WERROR netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
811 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
813 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
818 netr_NETRLOGONCOMPUTECLIENTDIGEST
820 static WERROR netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
821 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
823 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
831 static WERROR netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
832 struct netr_DsRGetSiteName *r)
834 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
839 fill in a netr_DomainTrustInfo from a ldb search result
841 static NTSTATUS fill_domain_primary_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
842 struct netr_DomainTrustInfo *info,
843 const char *local_domain)
847 info->domainname.string = local_domain;
848 info->fulldomainname.string = talloc_asprintf(info, "%s.", samdb_result_string(res, "dnsDomain", NULL));
849 /* TODO: we need proper forest support */
850 info->forest.string = info->fulldomainname.string;
851 info->guid = samdb_result_guid(res, "objectGUID");
852 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
858 fill in a netr_DomainTrustInfo from a ldb search result
860 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx, struct ldb_message *res,
861 struct netr_DomainTrustInfo *info,
862 const char *local_domain, BOOL is_local)
867 info->domainname.string = local_domain;
868 info->fulldomainname.string = samdb_result_string(res, "dnsDomain", NULL);
869 info->forest.string = NULL;
870 info->guid = samdb_result_guid(res, "objectGUID");
871 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
873 info->domainname.string = samdb_result_string(res, "flatName", NULL);
874 info->fulldomainname.string = samdb_result_string(res, "name", NULL);
875 info->forest.string = NULL;
876 info->guid = samdb_result_guid(res, "objectGUID");
877 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
884 netr_LogonGetDomainInfo
885 this is called as part of the ADS domain logon procedure.
887 static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
888 struct netr_LogonGetDomainInfo *r)
890 const char * const attrs[] = { "dnsDomain", "objectSid",
891 "objectGUID", "flatName", "securityIdentifier",
893 const char * const ref_attrs[] = { "nETBIOSName", NULL };
894 struct ldb_context *sam_ctx;
895 struct ldb_message **res1, **res2, **ref_res;
896 struct netr_DomainInfo1 *info1;
897 int ret, ret1, ret2, i;
900 const char *local_domain;
902 status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
904 r->out.return_authenticator,
906 if (!NT_STATUS_IS_OK(status)) {
910 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
911 if (sam_ctx == NULL) {
912 return NT_STATUS_INVALID_SYSTEM_SERVICE;
915 /* we need to do two searches. The first will pull our primary
916 domain and the second will pull any trusted domains. Our
917 primary domain is also a "trusted" domain, so we need to
918 put the primary domain into the lists of returned trusts as
920 ret1 = gendb_search(sam_ctx, mem_ctx, NULL, &res1, attrs, "(objectClass=domainDNS)");
922 return NT_STATUS_INTERNAL_DB_CORRUPTION;
925 /* try and find the domain */
926 ret = gendb_search(sam_ctx, mem_ctx, NULL,
928 "(&(objectClass=crossRef)(ncName=%s))",
929 ldb_dn_linearize(mem_ctx, res1[0]->dn));
931 return NT_STATUS_INTERNAL_DB_CORRUPTION;
934 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
936 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
938 return NT_STATUS_INTERNAL_DB_CORRUPTION;
941 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
943 return NT_STATUS_NO_MEMORY;
948 info1->num_trusts = ret2 + 1;
949 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
951 if (info1->trusts == NULL) {
952 return NT_STATUS_NO_MEMORY;
955 status = fill_domain_primary_info(mem_ctx, res1[0], &info1->domaininfo, local_domain);
956 if (!NT_STATUS_IS_OK(status)) {
960 for (i=0;i<ret2;i++) {
961 status = fill_domain_trust_info(mem_ctx, res2[i], &info1->trusts[i], NULL, False);
962 if (!NT_STATUS_IS_OK(status)) {
967 status = fill_domain_trust_info(mem_ctx, res1[0], &info1->trusts[i], local_domain, True);
968 if (!NT_STATUS_IS_OK(status)) {
972 r->out.info.info1 = info1;
980 netr_NETRSERVERPASSWORDGET
982 static WERROR netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
983 struct netr_NETRSERVERPASSWORDGET *r)
985 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
990 netr_NETRLOGONSENDTOSAM
992 static WERROR netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
993 struct netr_NETRLOGONSENDTOSAM *r)
995 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1000 netr_DSRADDRESSTOSITENAMESW
1002 static WERROR netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1003 struct netr_DSRADDRESSTOSITENAMESW *r)
1005 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1010 netr_DsRGetDCNameEx2
1012 static WERROR netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1013 struct netr_DsRGetDCNameEx2 *r)
1015 const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
1017 struct ldb_message **res;
1020 ZERO_STRUCT(r->out);
1022 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1023 if (sam_ctx == NULL) {
1024 return WERR_DS_SERVICE_UNAVAILABLE;
1027 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
1028 "(&(objectClass=domainDNS)(dnsDomain=%s))",
1031 return WERR_NO_SUCH_DOMAIN;
1034 r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1039 /* TODO: - return real IP address
1040 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1042 r->out.info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s", lp_netbios_name(),lp_realm());
1043 r->out.info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1044 r->out.info->dc_address_type = 1;
1045 r->out.info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1046 r->out.info->domain_name = samdb_result_string(res[0], "dnsDomain", NULL);
1047 r->out.info->forest_name = samdb_result_string(res[0], "dnsDomain", NULL);
1048 r->out.info->dc_flags = 0xE00001FD;
1049 r->out.info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1050 r->out.info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1058 static WERROR netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1059 struct netr_DsRGetDCNameEx *r)
1061 struct netr_DsRGetDCNameEx2 r2;
1066 r2.in.server_unc = r->in.server_unc;
1067 r2.in.client_account = NULL;
1069 r2.in.domain_guid = r->in.domain_guid;
1070 r2.in.domain_name = r->in.domain_name;
1071 r2.in.site_name = r->in.site_name;
1072 r2.in.flags = r->in.flags;
1075 werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1077 r->out.info = r2.out.info;
1085 static WERROR netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1086 struct netr_DsRGetDCName *r)
1088 struct netr_DsRGetDCNameEx2 r2;
1093 r2.in.server_unc = r->in.server_unc;
1094 r2.in.client_account = NULL;
1096 r2.in.domain_name = r->in.domain_name;
1097 r2.in.domain_guid = r->in.domain_guid;
1099 r2.in.site_name = NULL; /* should fill in from site GUID */
1100 r2.in.flags = r->in.flags;
1103 werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1105 r->out.info = r2.out.info;
1111 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1113 static WERROR netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1114 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1116 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1121 netr_NETRENUMERATETRUSTEDDOMAINSEX
1123 static WERROR netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1124 struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
1126 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1131 netr_DSRADDRESSTOSITENAMESEXW
1133 static WERROR netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1134 struct netr_DSRADDRESSTOSITENAMESEXW *r)
1136 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1141 netr_DSRGETDCSITECOVERAGEW
1143 static WERROR netr_DSRGETDCSITECOVERAGEW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1144 struct netr_DSRGETDCSITECOVERAGEW *r)
1146 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1151 netr_DsrEnumerateDomainTrusts
1153 static WERROR netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1154 struct netr_DsrEnumerateDomainTrusts *r)
1156 struct netr_DomainTrust *trusts;
1159 struct ldb_message **dom_res, **ref_res;
1160 const char * const dom_attrs[] = { "dnsDomain", "objectSid", "objectGUID", NULL };
1161 const char * const ref_attrs[] = { "nETBIOSName", NULL };
1163 ZERO_STRUCT(r->out);
1165 sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1166 if (sam_ctx == NULL) {
1167 return WERR_GENERAL_FAILURE;
1170 ret = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(mem_ctx), &dom_res, dom_attrs);
1172 return WERR_GENERAL_FAILURE;
1176 return WERR_GENERAL_FAILURE;
1179 ret = gendb_search(sam_ctx, mem_ctx, NULL, &ref_res, ref_attrs,
1180 "(&(objectClass=crossRef)(ncName=%s))",
1181 ldb_dn_linearize(mem_ctx, dom_res[0]->dn));
1183 return WERR_GENERAL_FAILURE;
1187 return WERR_GENERAL_FAILURE;
1192 trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1193 if (trusts == NULL) {
1198 r->out.trusts = trusts;
1200 /* TODO: add filtering by trust_flags, and correct trust_type
1202 trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1203 trusts[0].dns_name = samdb_result_string(dom_res[0], "dnsDomain", NULL);
1204 trusts[0].trust_flags =
1205 NETR_TRUST_FLAG_TREEROOT |
1206 NETR_TRUST_FLAG_IN_FOREST |
1207 NETR_TRUST_FLAG_PRIMARY;
1208 trusts[0].parent_index = 0;
1209 trusts[0].trust_type = 2;
1210 trusts[0].trust_attributes = 0;
1211 trusts[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1212 trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1219 netr_DSRDEREGISTERDNSHOSTRECORDS
1221 static WERROR netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1222 struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1224 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1229 netr_NETRSERVERTRUSTPASSWORDSGET
1231 static WERROR netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1232 struct netr_NETRSERVERTRUSTPASSWORDSGET *r)
1234 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1239 netr_DSRGETFORESTTRUSTINFORMATION
1241 static WERROR netr_DSRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1242 struct netr_DSRGETFORESTTRUSTINFORMATION *r)
1244 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1249 netr_NETRGETFORESTTRUSTINFORMATION
1251 static WERROR netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1252 struct netr_NETRGETFORESTTRUSTINFORMATION *r)
1254 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1259 netr_NETRSERVERGETTRUSTINFO
1261 static WERROR netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1262 struct netr_NETRSERVERGETTRUSTINFO *r)
1264 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1268 /* include the generated boilerplate */
1269 #include "librpc/gen_ndr/ndr_netlogon_s.c"