s4:netlogon: implement netr_LogonGetCapabilities with NT_STATUS_NOT_IMPLEMENTED
[Samba/gbeck.git] / source4 / rpc_server / netlogon / dcerpc_netlogon.c
blobac7ce73f2aacd78cbe7b015886aa32a1b5f63c20
1 /*
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/>.
23 #include "includes.h"
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 */
56 if (pipe_state) {
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;
73 return NT_STATUS_OK;
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;
81 void *sam_ctx;
82 struct samr_Password *mach_pwd;
83 uint32_t user_account_control;
84 int num_records;
85 struct ldb_message **msgs;
86 NTSTATUS nt_status;
87 const char *attrs[] = {"unicodePwd", "userAccountControl",
88 "objectSid", NULL};
90 const char *trust_dom_attrs[] = {"flatname", NULL};
91 const char *account_name;
93 ZERO_STRUCTP(r->out.return_credentials);
94 *r->out.rid = 0;
97 * According to Microsoft (see bugid #6099)
98 * Windows 7 looks at the negotiate_flags
99 * returned in this structure *even if the
100 * call fails with access denied!
102 *r->out.negotiate_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT |
103 NETLOGON_NEG_PERSISTENT_SAMREPL |
104 NETLOGON_NEG_ARCFOUR |
105 NETLOGON_NEG_PROMOTION_COUNT |
106 NETLOGON_NEG_CHANGELOG_BDC |
107 NETLOGON_NEG_FULL_SYNC_REPL |
108 NETLOGON_NEG_MULTIPLE_SIDS |
109 NETLOGON_NEG_REDO |
110 NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
111 NETLOGON_NEG_SEND_PASSWORD_INFO_PDC |
112 NETLOGON_NEG_GENERIC_PASSTHROUGH |
113 NETLOGON_NEG_CONCURRENT_RPC |
114 NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL |
115 NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL |
116 NETLOGON_NEG_STRONG_KEYS |
117 NETLOGON_NEG_TRANSITIVE_TRUSTS |
118 NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
119 NETLOGON_NEG_PASSWORD_SET2 |
120 NETLOGON_NEG_GETDOMAININFO |
121 NETLOGON_NEG_CROSS_FOREST_TRUSTS |
122 NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION |
123 NETLOGON_NEG_RODC_PASSTHROUGH |
124 NETLOGON_NEG_AUTHENTICATED_RPC_LSASS |
125 NETLOGON_NEG_AUTHENTICATED_RPC;
127 if (!pipe_state) {
128 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
129 return NT_STATUS_ACCESS_DENIED;
132 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
133 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
134 if (sam_ctx == NULL) {
135 return NT_STATUS_INVALID_SYSTEM_SERVICE;
138 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
139 char *encoded_account = ldb_binary_encode_string(mem_ctx, r->in.account_name);
140 const char *flatname;
141 if (!encoded_account) {
142 return NT_STATUS_NO_MEMORY;
145 /* Kill the trailing dot */
146 if (encoded_account[strlen(encoded_account)-1] == '.') {
147 encoded_account[strlen(encoded_account)-1] = '\0';
150 /* pull the user attributes */
151 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, trust_dom_attrs,
152 "(&(trustPartner=%s)(objectclass=trustedDomain))",
153 encoded_account);
155 if (num_records == 0) {
156 DEBUG(3,("Couldn't find trust [%s] in samdb.\n",
157 encoded_account));
158 return NT_STATUS_ACCESS_DENIED;
161 if (num_records > 1) {
162 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
163 return NT_STATUS_INTERNAL_DB_CORRUPTION;
166 flatname = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL);
167 if (!flatname) {
168 /* No flatname for this trust - we can't proceed */
169 return NT_STATUS_ACCESS_DENIED;
171 account_name = talloc_asprintf(mem_ctx, "%s$", flatname);
173 if (!account_name) {
174 return NT_STATUS_NO_MEMORY;
177 } else {
178 account_name = r->in.account_name;
181 /* pull the user attributes */
182 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
183 "(&(sAMAccountName=%s)(objectclass=user))",
184 ldb_binary_encode_string(mem_ctx, account_name));
186 if (num_records == 0) {
187 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
188 r->in.account_name));
189 return NT_STATUS_ACCESS_DENIED;
192 if (num_records > 1) {
193 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
194 return NT_STATUS_INTERNAL_DB_CORRUPTION;
198 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
200 if (user_account_control & UF_ACCOUNTDISABLE) {
201 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
202 return NT_STATUS_ACCESS_DENIED;
205 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
206 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
207 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
208 return NT_STATUS_ACCESS_DENIED;
210 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
211 r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
212 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
213 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
215 return NT_STATUS_ACCESS_DENIED;
217 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
218 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
219 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
220 return NT_STATUS_ACCESS_DENIED;
222 } else {
223 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
224 r->in.secure_channel_type));
225 return NT_STATUS_ACCESS_DENIED;
228 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
229 "objectSid", 0);
231 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd");
232 if (mach_pwd == NULL) {
233 return NT_STATUS_ACCESS_DENIED;
236 creds = talloc(mem_ctx, struct creds_CredentialState);
237 NT_STATUS_HAVE_NO_MEMORY(creds);
239 creds_server_init(creds, &pipe_state->client_challenge,
240 &pipe_state->server_challenge, mach_pwd,
241 r->out.return_credentials,
242 *r->in.negotiate_flags);
244 if (!creds_server_check(creds, r->in.credentials)) {
245 talloc_free(creds);
246 return NT_STATUS_ACCESS_DENIED;
249 creds->account_name = talloc_steal(creds, r->in.account_name);
251 creds->computer_name = talloc_steal(creds, r->in.computer_name);
252 creds->domain = talloc_strdup(creds, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
254 creds->secure_channel_type = r->in.secure_channel_type;
256 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
259 /* remember this session key state */
260 nt_status = schannel_store_session_key(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, creds);
262 return nt_status;
265 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
266 struct netr_ServerAuthenticate *r)
268 struct netr_ServerAuthenticate3 r3;
269 uint32_t rid = 0;
270 /* TODO:
271 * negotiate_flags is used as an [in] parameter
272 * so it need to be initialised.
274 * (I think ... = 0; seems wrong here --metze)
276 uint32_t negotiate_flags = 0;
278 r3.in.server_name = r->in.server_name;
279 r3.in.account_name = r->in.account_name;
280 r3.in.secure_channel_type = r->in.secure_channel_type;
281 r3.in.computer_name = r->in.computer_name;
282 r3.in.credentials = r->in.credentials;
283 r3.out.return_credentials = r->out.return_credentials;
284 r3.in.negotiate_flags = &negotiate_flags;
285 r3.out.negotiate_flags = &negotiate_flags;
286 r3.out.rid = &rid;
288 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
291 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
292 struct netr_ServerAuthenticate2 *r)
294 struct netr_ServerAuthenticate3 r3;
295 uint32_t rid = 0;
297 r3.in.server_name = r->in.server_name;
298 r3.in.account_name = r->in.account_name;
299 r3.in.secure_channel_type = r->in.secure_channel_type;
300 r3.in.computer_name = r->in.computer_name;
301 r3.in.credentials = r->in.credentials;
302 r3.out.return_credentials = r->out.return_credentials;
303 r3.in.negotiate_flags = r->in.negotiate_flags;
304 r3.out.negotiate_flags = r->out.negotiate_flags;
305 r3.out.rid = &rid;
307 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
311 Validate an incoming authenticator against the credentials for the remote machine.
313 The credentials are (re)read and from the schannel database, and
314 written back after the caclulations are performed.
316 The creds_out parameter (if not NULL) returns the credentials, if
317 the caller needs some of that information.
320 static NTSTATUS dcesrv_netr_creds_server_step_check(struct tevent_context *event_ctx,
321 struct loadparm_context *lp_ctx,
322 const char *computer_name,
323 TALLOC_CTX *mem_ctx,
324 struct netr_Authenticator *received_authenticator,
325 struct netr_Authenticator *return_authenticator,
326 struct creds_CredentialState **creds_out)
328 struct creds_CredentialState *creds;
329 NTSTATUS nt_status;
330 struct ldb_context *ldb;
331 int ret;
333 ldb = schannel_db_connect(mem_ctx, event_ctx, lp_ctx);
334 if (!ldb) {
335 return NT_STATUS_ACCESS_DENIED;
338 ret = ldb_transaction_start(ldb);
339 if (ret != 0) {
340 talloc_free(ldb);
341 return NT_STATUS_INTERNAL_DB_CORRUPTION;
344 /* Because this is a shared structure (even across
345 * disconnects) we must update the database every time we
346 * update the structure */
348 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name,
349 lp_workgroup(lp_ctx),
350 &creds);
351 if (NT_STATUS_IS_OK(nt_status)) {
352 nt_status = creds_server_step_check(creds,
353 received_authenticator,
354 return_authenticator);
356 if (NT_STATUS_IS_OK(nt_status)) {
357 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
360 if (NT_STATUS_IS_OK(nt_status)) {
361 ldb_transaction_commit(ldb);
362 if (creds_out) {
363 *creds_out = creds;
364 talloc_steal(mem_ctx, creds);
366 } else {
367 ldb_transaction_cancel(ldb);
369 talloc_free(ldb);
370 return nt_status;
374 Change the machine account password for the currently connected
375 client. Supplies only the NT#.
378 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
379 struct netr_ServerPasswordSet *r)
381 struct creds_CredentialState *creds;
382 struct ldb_context *sam_ctx;
383 NTSTATUS nt_status;
385 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
386 r->in.computer_name, mem_ctx,
387 r->in.credential, r->out.return_authenticator,
388 &creds);
389 NT_STATUS_NOT_OK_RETURN(nt_status);
391 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));
392 if (sam_ctx == NULL) {
393 return NT_STATUS_INVALID_SYSTEM_SERVICE;
396 creds_des_decrypt(creds, r->in.new_password);
398 /* Using the sid for the account as the key, set the password */
399 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
400 creds->sid,
401 NULL, /* Don't have plaintext */
402 NULL, r->in.new_password,
403 true, /* Password change */
404 NULL, NULL);
405 return nt_status;
409 Change the machine account password for the currently connected
410 client. Supplies new plaintext.
412 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
413 struct netr_ServerPasswordSet2 *r)
415 struct creds_CredentialState *creds;
416 struct ldb_context *sam_ctx;
417 NTSTATUS nt_status;
418 DATA_BLOB new_password;
420 struct samr_CryptPassword password_buf;
422 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
423 r->in.computer_name, mem_ctx,
424 r->in.credential, r->out.return_authenticator,
425 &creds);
426 NT_STATUS_NOT_OK_RETURN(nt_status);
428 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));
429 if (sam_ctx == NULL) {
430 return NT_STATUS_INVALID_SYSTEM_SERVICE;
433 memcpy(password_buf.data, r->in.new_password->data, 512);
434 SIVAL(password_buf.data, 512, r->in.new_password->length);
435 creds_arcfour_crypt(creds, password_buf.data, 516);
437 if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
438 DEBUG(3,("samr: failed to decode password buffer\n"));
439 return NT_STATUS_WRONG_PASSWORD;
442 /* Using the sid for the account as the key, set the password */
443 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
444 creds->sid,
445 &new_password, /* we have plaintext */
446 NULL, NULL,
447 true, /* Password change */
448 NULL, NULL);
449 return nt_status;
454 netr_LogonUasLogon
456 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
457 struct netr_LogonUasLogon *r)
459 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
464 netr_LogonUasLogoff
466 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
467 struct netr_LogonUasLogoff *r)
469 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
474 netr_LogonSamLogon_base
476 This version of the function allows other wrappers to say 'do not check the credentials'
478 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
480 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
481 struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
483 struct auth_context *auth_context;
484 struct auth_usersupplied_info *user_info;
485 struct auth_serversupplied_info *server_info;
486 NTSTATUS nt_status;
487 static const char zeros[16];
488 struct netr_SamBaseInfo *sam;
489 struct netr_SamInfo2 *sam2;
490 struct netr_SamInfo3 *sam3;
491 struct netr_SamInfo6 *sam6;
493 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
494 NT_STATUS_HAVE_NO_MEMORY(user_info);
496 user_info->flags = 0;
497 user_info->mapped_state = false;
498 user_info->remote_host = NULL;
500 switch (r->in.logon_level) {
501 case NetlogonInteractiveInformation:
502 case NetlogonServiceInformation:
503 case NetlogonInteractiveTransitiveInformation:
504 case NetlogonServiceTransitiveInformation:
505 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
506 creds_arcfour_crypt(creds,
507 r->in.logon->password->lmpassword.hash,
508 sizeof(r->in.logon->password->lmpassword.hash));
509 creds_arcfour_crypt(creds,
510 r->in.logon->password->ntpassword.hash,
511 sizeof(r->in.logon->password->ntpassword.hash));
512 } else {
513 creds_des_decrypt(creds, &r->in.logon->password->lmpassword);
514 creds_des_decrypt(creds, &r->in.logon->password->ntpassword);
517 /* TODO: we need to deny anonymous access here */
518 nt_status = auth_context_create(mem_ctx,
519 dce_call->event_ctx, dce_call->msg_ctx,
520 dce_call->conn->dce_ctx->lp_ctx,
521 &auth_context);
522 NT_STATUS_NOT_OK_RETURN(nt_status);
524 user_info->logon_parameters = r->in.logon->password->identity_info.parameter_control;
525 user_info->client.account_name = r->in.logon->password->identity_info.account_name.string;
526 user_info->client.domain_name = r->in.logon->password->identity_info.domain_name.string;
527 user_info->workstation_name = r->in.logon->password->identity_info.workstation.string;
529 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
530 user_info->password_state = AUTH_PASSWORD_HASH;
532 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
533 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
534 *user_info->password.hash.lanman = r->in.logon->password->lmpassword;
536 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
537 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
538 *user_info->password.hash.nt = r->in.logon->password->ntpassword;
540 break;
541 case NetlogonNetworkInformation:
542 case NetlogonNetworkTransitiveInformation:
544 /* TODO: we need to deny anonymous access here */
545 nt_status = auth_context_create(mem_ctx,
546 dce_call->event_ctx, dce_call->msg_ctx,
547 dce_call->conn->dce_ctx->lp_ctx,
548 &auth_context);
549 NT_STATUS_NOT_OK_RETURN(nt_status);
551 nt_status = auth_context_set_challenge(auth_context, r->in.logon->network->challenge, "netr_LogonSamLogonWithFlags");
552 NT_STATUS_NOT_OK_RETURN(nt_status);
554 user_info->logon_parameters = r->in.logon->network->identity_info.parameter_control;
555 user_info->client.account_name = r->in.logon->network->identity_info.account_name.string;
556 user_info->client.domain_name = r->in.logon->network->identity_info.domain_name.string;
557 user_info->workstation_name = r->in.logon->network->identity_info.workstation.string;
559 user_info->password_state = AUTH_PASSWORD_RESPONSE;
560 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length);
561 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length);
563 break;
566 case NetlogonGenericInformation:
568 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
569 creds_arcfour_crypt(creds,
570 r->in.logon->generic->data, r->in.logon->generic->length);
571 } else {
572 /* Using DES to verify kerberos tickets makes no sense */
573 return NT_STATUS_INVALID_PARAMETER;
576 if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) {
577 NTSTATUS status;
578 struct server_id *kdc;
579 struct kdc_check_generic_kerberos check;
580 struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
581 NT_STATUS_HAVE_NO_MEMORY(generic);
582 *r->out.authoritative = 1;
584 /* TODO: Describe and deal with these flags */
585 *r->out.flags = 0;
587 r->out.validation->generic = generic;
589 kdc = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "kdc_server");
590 if ((kdc == NULL) || (kdc[0].id == 0)) {
591 return NT_STATUS_NO_LOGON_SERVERS;
594 check.in.generic_request =
595 data_blob_const(r->in.logon->generic->data,
596 r->in.logon->generic->length);
598 status = irpc_call(dce_call->msg_ctx, kdc[0],
599 &ndr_table_irpc, NDR_KDC_CHECK_GENERIC_KERBEROS,
600 &check, mem_ctx);
601 if (!NT_STATUS_IS_OK(status)) {
602 return status;
604 generic->length = check.out.generic_reply.length;
605 generic->data = check.out.generic_reply.data;
606 return NT_STATUS_OK;
609 /* Until we get an implemetnation of these other packages */
610 return NT_STATUS_INVALID_PARAMETER;
612 default:
613 return NT_STATUS_INVALID_PARAMETER;
616 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
617 NT_STATUS_NOT_OK_RETURN(nt_status);
619 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
620 NT_STATUS_NOT_OK_RETURN(nt_status);
622 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
623 /* It appears that level 6 is not individually encrypted */
624 if ((r->in.validation_level != 6) &&
625 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
626 /* This key is sent unencrypted without the ARCFOUR flag set */
627 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
628 creds_arcfour_crypt(creds,
629 sam->key.key,
630 sizeof(sam->key.key));
634 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
635 /* It appears that level 6 is not individually encrypted */
636 if ((r->in.validation_level != 6) &&
637 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
638 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
639 creds_arcfour_crypt(creds,
640 sam->LMSessKey.key,
641 sizeof(sam->LMSessKey.key));
642 } else {
643 creds_des_encrypt_LMKey(creds,
644 &sam->LMSessKey);
648 switch (r->in.validation_level) {
649 case 2:
650 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
651 NT_STATUS_HAVE_NO_MEMORY(sam2);
652 sam2->base = *sam;
653 r->out.validation->sam2 = sam2;
654 break;
656 case 3:
657 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
658 NT_STATUS_HAVE_NO_MEMORY(sam3);
659 sam3->base = *sam;
660 r->out.validation->sam3 = sam3;
661 break;
663 case 6:
664 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
665 NT_STATUS_HAVE_NO_MEMORY(sam6);
666 sam6->base = *sam;
667 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
668 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
669 sam->account_name.string, sam6->forest.string);
670 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
671 r->out.validation->sam6 = sam6;
672 break;
674 default:
675 break;
678 *r->out.authoritative = 1;
680 /* TODO: Describe and deal with these flags */
681 *r->out.flags = 0;
683 return NT_STATUS_OK;
686 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
687 struct netr_LogonSamLogonEx *r)
689 NTSTATUS nt_status;
690 struct creds_CredentialState *creds;
691 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);
692 if (!NT_STATUS_IS_OK(nt_status)) {
693 return nt_status;
696 if (!dce_call->conn->auth_state.auth_info ||
697 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
698 return NT_STATUS_INTERNAL_ERROR;
700 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
704 netr_LogonSamLogonWithFlags
707 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
708 struct netr_LogonSamLogonWithFlags *r)
710 NTSTATUS nt_status;
711 struct creds_CredentialState *creds;
712 struct netr_LogonSamLogonEx r2;
714 struct netr_Authenticator *return_authenticator;
716 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
717 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
719 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
720 r->in.computer_name, mem_ctx,
721 r->in.credential, return_authenticator,
722 &creds);
723 NT_STATUS_NOT_OK_RETURN(nt_status);
725 ZERO_STRUCT(r2);
727 r2.in.server_name = r->in.server_name;
728 r2.in.computer_name = r->in.computer_name;
729 r2.in.logon_level = r->in.logon_level;
730 r2.in.logon = r->in.logon;
731 r2.in.validation_level = r->in.validation_level;
732 r2.in.flags = r->in.flags;
733 r2.out.validation = r->out.validation;
734 r2.out.authoritative = r->out.authoritative;
735 r2.out.flags = r->out.flags;
737 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
739 r->out.return_authenticator = return_authenticator;
741 return nt_status;
745 netr_LogonSamLogon
747 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
748 struct netr_LogonSamLogon *r)
750 struct netr_LogonSamLogonWithFlags r2;
751 uint32_t flags = 0;
752 NTSTATUS status;
754 ZERO_STRUCT(r2);
756 r2.in.server_name = r->in.server_name;
757 r2.in.computer_name = r->in.computer_name;
758 r2.in.credential = r->in.credential;
759 r2.in.return_authenticator = r->in.return_authenticator;
760 r2.in.logon_level = r->in.logon_level;
761 r2.in.logon = r->in.logon;
762 r2.in.validation_level = r->in.validation_level;
763 r2.in.flags = &flags;
764 r2.out.validation = r->out.validation;
765 r2.out.authoritative = r->out.authoritative;
766 r2.out.flags = &flags;
768 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
770 r->out.return_authenticator = r2.out.return_authenticator;
772 return status;
777 netr_LogonSamLogoff
779 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
780 struct netr_LogonSamLogoff *r)
782 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
788 netr_DatabaseDeltas
790 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
791 struct netr_DatabaseDeltas *r)
793 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
798 netr_DatabaseSync
800 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
801 struct netr_DatabaseSync *r)
803 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
804 return NT_STATUS_NOT_IMPLEMENTED;
809 netr_AccountDeltas
811 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
812 struct netr_AccountDeltas *r)
814 /* w2k3 returns "NOT IMPLEMENTED" for this call */
815 return NT_STATUS_NOT_IMPLEMENTED;
820 netr_AccountSync
822 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
823 struct netr_AccountSync *r)
825 /* w2k3 returns "NOT IMPLEMENTED" for this call */
826 return NT_STATUS_NOT_IMPLEMENTED;
831 netr_GetDcName
833 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
834 struct netr_GetDcName *r)
836 const char * const attrs[] = { NULL };
837 void *sam_ctx;
838 struct ldb_message **res;
839 struct ldb_dn *domain_dn;
840 int ret;
841 const char *dcname;
843 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
844 dce_call->conn->dce_ctx->lp_ctx,
845 dce_call->conn->auth_state.session_info);
846 if (sam_ctx == NULL) {
847 return WERR_DS_SERVICE_UNAVAILABLE;
850 domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx,
851 r->in.domainname);
852 if (domain_dn == NULL) {
853 return WERR_DS_SERVICE_UNAVAILABLE;
856 ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs);
857 if (ret != 1) {
858 return WERR_NO_SUCH_DOMAIN;
861 /* TODO: - return real IP address
862 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
864 dcname = talloc_asprintf(mem_ctx, "\\\\%s",
865 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
866 W_ERROR_HAVE_NO_MEMORY(dcname);
868 *r->out.dcname = dcname;
869 return WERR_OK;
874 netr_LogonControl
876 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
877 struct netr_LogonControl *r)
879 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
884 netr_GetAnyDCName
886 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
887 struct netr_GetAnyDCName *r)
889 struct netr_GetDcName r2;
890 WERROR werr;
892 ZERO_STRUCT(r2);
894 r2.in.logon_server = r->in.logon_server;
895 r2.in.domainname = r->in.domainname;
896 r2.out.dcname = r->out.dcname;
898 werr = dcesrv_netr_GetDcName(dce_call, mem_ctx, &r2);
900 return werr;
905 netr_LogonControl2
907 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
908 struct netr_LogonControl2 *r)
910 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
915 netr_DatabaseSync2
917 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
918 struct netr_DatabaseSync2 *r)
920 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
921 return NT_STATUS_NOT_IMPLEMENTED;
926 netr_DatabaseRedo
928 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
929 struct netr_DatabaseRedo *r)
931 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
936 netr_LogonControl2Ex
938 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
939 struct netr_LogonControl2Ex *r)
941 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
946 netr_NetrEnumerateTurstedDomains
948 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
949 struct netr_NetrEnumerateTrustedDomains *r)
951 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
956 netr_LogonGetCapabilities
958 static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
959 struct netr_LogonGetCapabilities *r)
961 /* we don't support AES yet */
962 return NT_STATUS_NOT_IMPLEMENTED;
967 netr_NETRLOGONSETSERVICEBITS
969 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
970 struct netr_NETRLOGONSETSERVICEBITS *r)
972 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
977 netr_LogonGetTrustRid
979 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
980 struct netr_LogonGetTrustRid *r)
982 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
987 netr_NETRLOGONCOMPUTESERVERDIGEST
989 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
990 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
992 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
997 netr_NETRLOGONCOMPUTECLIENTDIGEST
999 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1000 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
1002 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1008 netr_DsRGetSiteName
1010 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1011 struct netr_DsRGetSiteName *r)
1013 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1018 fill in a netr_DomainTrustInfo from a ldb search result
1020 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
1021 struct ldb_message *res,
1022 struct ldb_message *ref_res,
1023 struct netr_DomainTrustInfo *info,
1024 bool is_local, bool is_trust_list)
1026 ZERO_STRUCTP(info);
1028 info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension);
1029 info->trust_extension.length = 16;
1030 info->trust_extension.info->flags =
1031 NETR_TRUST_FLAG_TREEROOT |
1032 NETR_TRUST_FLAG_IN_FOREST |
1033 NETR_TRUST_FLAG_PRIMARY;
1034 info->trust_extension.info->parent_index = 0; /* should be index into array
1035 of parent */
1036 info->trust_extension.info->trust_type = LSA_TRUST_TYPE_UPLEVEL; /* should be based on ldb search for trusts */
1037 info->trust_extension.info->trust_attributes = LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE; /* needs to be based on ldb search */
1039 if (is_trust_list) {
1040 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
1041 info->forest.string = NULL;
1042 } else {
1043 /* TODO: we need a common function for pulling the forest */
1044 info->forest.string = samdb_result_string(ref_res, "dnsRoot", NULL);
1047 if (is_local) {
1048 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
1049 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
1050 info->guid = samdb_result_guid(res, "objectGUID");
1051 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
1052 } else {
1053 info->domainname.string = samdb_result_string(res, "flatName", NULL);
1054 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
1055 info->guid = samdb_result_guid(res, "objectGUID");
1056 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
1059 return NT_STATUS_OK;
1063 netr_LogonGetDomainInfo
1064 this is called as part of the ADS domain logon procedure.
1066 It has an important role in convaying details about the client, such
1067 as Operating System, Version, Service Pack etc.
1069 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1070 struct netr_LogonGetDomainInfo *r)
1072 const char * const attrs[] = { "objectSid",
1073 "objectGUID", "flatName", "securityIdentifier",
1074 "trustPartner", NULL };
1075 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1076 struct ldb_context *sam_ctx;
1077 struct ldb_message **res1, **res2, **ref_res;
1078 struct netr_DomainInfo1 *info1;
1079 int ret, ret1, ret2, i;
1080 NTSTATUS status;
1081 struct ldb_dn *partitions_basedn;
1083 const char *local_domain;
1085 status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
1086 r->in.computer_name, mem_ctx,
1087 r->in.credential,
1088 r->out.return_authenticator,
1089 NULL);
1090 if (!NT_STATUS_IS_OK(status)) {
1091 DEBUG(0,(__location__ " Bad credentials - error\n"));
1093 NT_STATUS_NOT_OK_RETURN(status);
1095 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1096 if (sam_ctx == NULL) {
1097 return NT_STATUS_INVALID_SYSTEM_SERVICE;
1100 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1102 /* we need to do two searches. The first will pull our primary
1103 domain and the second will pull any trusted domains. Our
1104 primary domain is also a "trusted" domain, so we need to
1105 put the primary domain into the lists of returned trusts as
1106 well */
1107 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
1108 if (ret1 != 1) {
1109 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1112 /* try and find the domain */
1113 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
1114 &ref_res, ref_attrs,
1115 "(&(objectClass=crossRef)(ncName=%s))",
1116 ldb_dn_get_linearized(res1[0]->dn));
1117 if (ret != 1) {
1118 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1121 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1123 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
1124 if (ret2 == -1) {
1125 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1128 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
1129 NT_STATUS_HAVE_NO_MEMORY(info1);
1131 ZERO_STRUCTP(info1);
1133 info1->num_trusts = ret2 + 1;
1134 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
1135 info1->num_trusts);
1136 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
1138 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo,
1139 true, false);
1140 NT_STATUS_NOT_OK_RETURN(status);
1142 for (i=0;i<ret2;i++) {
1143 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i],
1144 false, true);
1145 NT_STATUS_NOT_OK_RETURN(status);
1148 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i],
1149 true, true);
1150 NT_STATUS_NOT_OK_RETURN(status);
1152 info1->dns_hostname.string = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1153 info1->workstation_flags =
1154 NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | NETR_WS_FLAG_HANDLES_SPN_UPDATE;
1155 info1->supported_enc_types = 0; /* w2008 gives this 0 */
1157 r->out.info->info1 = info1;
1159 return NT_STATUS_OK;
1165 netr_ServerPasswordGet
1167 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1168 struct netr_ServerPasswordGet *r)
1170 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1175 netr_NETRLOGONSENDTOSAM
1177 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1178 struct netr_NETRLOGONSENDTOSAM *r)
1180 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1185 netr_DsRAddressToSitenamesW
1187 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1188 struct netr_DsRAddressToSitenamesW *r)
1190 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1195 netr_DsRGetDCNameEx2
1197 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1198 struct netr_DsRGetDCNameEx2 *r)
1200 const char * const attrs[] = { "objectGUID", NULL };
1201 void *sam_ctx;
1202 struct ldb_message **res;
1203 struct ldb_dn *domain_dn;
1204 int ret;
1205 struct netr_DsRGetDCNameInfo *info;
1207 ZERO_STRUCTP(r->out.info);
1209 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1210 if (sam_ctx == NULL) {
1211 return WERR_DS_SERVICE_UNAVAILABLE;
1214 /* Win7-beta will send the domain name in the form the user typed, so we have to cope
1215 with both the short and long form here */
1216 if (strcasecmp(r->in.domain_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx)) == 0) {
1217 r->in.domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1220 domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx,
1221 r->in.domain_name);
1222 if (domain_dn == NULL) {
1223 return WERR_DS_SERVICE_UNAVAILABLE;
1226 ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs);
1227 if (ret != 1) {
1228 return WERR_NO_SUCH_DOMAIN;
1231 info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1232 W_ERROR_HAVE_NO_MEMORY(info);
1234 /* TODO: - return real IP address
1235 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1237 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1238 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1239 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1240 W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
1241 info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1242 W_ERROR_HAVE_NO_MEMORY(info->dc_address);
1243 info->dc_address_type = DS_ADDRESS_TYPE_INET;
1244 info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1245 info->domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1246 info->forest_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1247 info->dc_flags = DS_DNS_FOREST |
1248 DS_DNS_DOMAIN |
1249 DS_DNS_CONTROLLER |
1250 DS_SERVER_WRITABLE |
1251 DS_SERVER_CLOSEST |
1252 DS_SERVER_TIMESERV |
1253 DS_SERVER_KDC |
1254 DS_SERVER_DS |
1255 DS_SERVER_LDAP |
1256 DS_SERVER_GC |
1257 DS_SERVER_PDC;
1258 info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1259 W_ERROR_HAVE_NO_MEMORY(info->dc_site_name);
1260 info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1261 W_ERROR_HAVE_NO_MEMORY(info->client_site_name);
1263 *r->out.info = info;
1265 return WERR_OK;
1269 netr_DsRGetDCNameEx
1271 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1272 struct netr_DsRGetDCNameEx *r)
1274 struct netr_DsRGetDCNameEx2 r2;
1275 WERROR werr;
1277 ZERO_STRUCT(r2);
1279 r2.in.server_unc = r->in.server_unc;
1280 r2.in.client_account = NULL;
1281 r2.in.mask = 0;
1282 r2.in.domain_guid = r->in.domain_guid;
1283 r2.in.domain_name = r->in.domain_name;
1284 r2.in.site_name = r->in.site_name;
1285 r2.in.flags = r->in.flags;
1286 r2.out.info = r->out.info;
1288 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1290 return werr;
1294 netr_DsRGetDCName
1296 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1297 struct netr_DsRGetDCName *r)
1299 struct netr_DsRGetDCNameEx2 r2;
1300 WERROR werr;
1302 ZERO_STRUCT(r2);
1304 r2.in.server_unc = r->in.server_unc;
1305 r2.in.client_account = NULL;
1306 r2.in.mask = 0;
1307 r2.in.domain_name = r->in.domain_name;
1308 r2.in.domain_guid = r->in.domain_guid;
1310 r2.in.site_name = NULL; /* should fill in from site GUID */
1311 r2.in.flags = r->in.flags;
1312 r2.out.info = r->out.info;
1314 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1316 return werr;
1319 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1321 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1322 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1324 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1329 netr_NetrEnumerateTrustedDomainsEx
1331 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1332 struct netr_NetrEnumerateTrustedDomainsEx *r)
1334 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1339 netr_DsRAddressToSitenamesExW
1341 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1342 struct netr_DsRAddressToSitenamesExW *r)
1344 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1349 netr_DsrGetDcSiteCoverageW
1351 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1352 struct netr_DsrGetDcSiteCoverageW *r)
1354 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1359 netr_DsrEnumerateDomainTrusts
1361 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1362 struct netr_DsrEnumerateDomainTrusts *r)
1364 struct netr_DomainTrustList *trusts;
1365 void *sam_ctx;
1366 int ret;
1367 struct ldb_message **dom_res, **ref_res;
1368 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1369 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1370 struct ldb_dn *partitions_basedn;
1372 ZERO_STRUCT(r->out);
1374 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1375 if (sam_ctx == NULL) {
1376 return WERR_GENERAL_FAILURE;
1379 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1381 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1382 if (ret == -1) {
1383 return WERR_GENERAL_FAILURE;
1385 if (ret != 1) {
1386 return WERR_GENERAL_FAILURE;
1389 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1390 "(&(objectClass=crossRef)(ncName=%s))",
1391 ldb_dn_get_linearized(dom_res[0]->dn));
1392 if (ret == -1) {
1393 return WERR_GENERAL_FAILURE;
1395 if (ret != 1) {
1396 return WERR_GENERAL_FAILURE;
1399 trusts = talloc(mem_ctx, struct netr_DomainTrustList);
1400 W_ERROR_HAVE_NO_MEMORY(trusts);
1402 trusts->array = talloc_array(trusts, struct netr_DomainTrust, ret);
1403 W_ERROR_HAVE_NO_MEMORY(trusts->array);
1405 trusts->count = 1; /* ?? */
1407 r->out.trusts = trusts;
1409 /* TODO: add filtering by trust_flags, and correct trust_type
1410 and attributes */
1411 trusts->array[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1412 trusts->array[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1413 trusts->array[0].trust_flags =
1414 NETR_TRUST_FLAG_TREEROOT |
1415 NETR_TRUST_FLAG_IN_FOREST |
1416 NETR_TRUST_FLAG_PRIMARY;
1417 trusts->array[0].parent_index = 0;
1418 trusts->array[0].trust_type = 2;
1419 trusts->array[0].trust_attributes = 0;
1420 trusts->array[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1421 trusts->array[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1423 return WERR_OK;
1428 netr_DsrDeregisterDNSHostRecords
1430 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1431 struct netr_DsrDeregisterDNSHostRecords *r)
1433 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1438 netr_ServerTrustPasswordsGet
1440 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1441 struct netr_ServerTrustPasswordsGet *r)
1443 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1448 netr_DsRGetForestTrustInformation
1450 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1451 struct netr_DsRGetForestTrustInformation *r)
1453 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1458 netr_GetForestTrustInformation
1460 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1461 struct netr_GetForestTrustInformation *r)
1463 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1468 netr_ServerGetTrustInfo
1470 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1471 struct netr_ServerGetTrustInfo *r)
1473 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1477 /* include the generated boilerplate */
1478 #include "librpc/gen_ndr/ndr_netlogon_s.c"