s4:netlogon - Put the "supported encryption types" more back in the "LogonGetDomainIn...
[Samba/ekacnet.git] / source4 / rpc_server / netlogon / dcerpc_netlogon.c
blob4ec6b74020b577a34561c53f22c8e639b5d0e7d7
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
8 Copyright (C) Matthias Dieter Wallnöfer 2009
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
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 "auth/auth_sam_reply.h"
30 #include "dsdb/samdb/samdb.h"
31 #include "../libds/common/flags.h"
32 #include "rpc_server/samr/proto.h"
33 #include "../lib/util/util_ldb.h"
34 #include "libcli/auth/libcli_auth.h"
35 #include "auth/gensec/schannel.h"
36 #include "libcli/security/security.h"
37 #include "param/param.h"
38 #include "lib/messaging/irpc.h"
39 #include "librpc/gen_ndr/ndr_irpc.h"
40 #include "librpc/gen_ndr/ndr_netlogon.h"
42 struct netlogon_server_pipe_state {
43 struct netr_Credential client_challenge;
44 struct netr_Credential server_challenge;
48 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
49 struct netr_ServerReqChallenge *r)
51 struct netlogon_server_pipe_state *pipe_state =
52 talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state);
54 ZERO_STRUCTP(r->out.return_credentials);
56 /* destroyed on pipe shutdown */
58 if (pipe_state) {
59 talloc_free(pipe_state);
60 dce_call->context->private_data = NULL;
63 pipe_state = talloc(dce_call->context, struct netlogon_server_pipe_state);
64 NT_STATUS_HAVE_NO_MEMORY(pipe_state);
66 pipe_state->client_challenge = *r->in.credentials;
68 generate_random_buffer(pipe_state->server_challenge.data,
69 sizeof(pipe_state->server_challenge.data));
71 *r->out.return_credentials = pipe_state->server_challenge;
73 dce_call->context->private_data = pipe_state;
75 return NT_STATUS_OK;
78 static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
79 struct netr_ServerAuthenticate3 *r)
81 struct netlogon_server_pipe_state *pipe_state =
82 talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state);
83 struct netlogon_creds_CredentialState *creds;
84 struct ldb_context *schannel_ldb;
85 struct ldb_context *sam_ctx;
86 struct samr_Password *mach_pwd;
87 uint32_t user_account_control;
88 int num_records;
89 struct ldb_message **msgs;
90 NTSTATUS nt_status;
91 const char *attrs[] = {"unicodePwd", "userAccountControl",
92 "objectSid", NULL};
94 const char *trust_dom_attrs[] = {"flatname", NULL};
95 const char *account_name;
97 ZERO_STRUCTP(r->out.return_credentials);
98 *r->out.rid = 0;
101 * According to Microsoft (see bugid #6099)
102 * Windows 7 looks at the negotiate_flags
103 * returned in this structure *even if the
104 * call fails with access denied!
106 *r->out.negotiate_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT |
107 NETLOGON_NEG_PERSISTENT_SAMREPL |
108 NETLOGON_NEG_ARCFOUR |
109 NETLOGON_NEG_PROMOTION_COUNT |
110 NETLOGON_NEG_CHANGELOG_BDC |
111 NETLOGON_NEG_FULL_SYNC_REPL |
112 NETLOGON_NEG_MULTIPLE_SIDS |
113 NETLOGON_NEG_REDO |
114 NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
115 NETLOGON_NEG_SEND_PASSWORD_INFO_PDC |
116 NETLOGON_NEG_GENERIC_PASSTHROUGH |
117 NETLOGON_NEG_CONCURRENT_RPC |
118 NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL |
119 NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL |
120 NETLOGON_NEG_STRONG_KEYS |
121 NETLOGON_NEG_TRANSITIVE_TRUSTS |
122 NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
123 NETLOGON_NEG_PASSWORD_SET2 |
124 NETLOGON_NEG_GETDOMAININFO |
125 NETLOGON_NEG_CROSS_FOREST_TRUSTS |
126 NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION |
127 NETLOGON_NEG_RODC_PASSTHROUGH |
128 NETLOGON_NEG_AUTHENTICATED_RPC_LSASS |
129 NETLOGON_NEG_AUTHENTICATED_RPC;
131 if (!pipe_state) {
132 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
133 return NT_STATUS_ACCESS_DENIED;
136 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
137 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
138 if (sam_ctx == NULL) {
139 return NT_STATUS_INVALID_SYSTEM_SERVICE;
142 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
143 char *encoded_account = ldb_binary_encode_string(mem_ctx, r->in.account_name);
144 const char *flatname;
145 if (!encoded_account) {
146 return NT_STATUS_NO_MEMORY;
149 /* Kill the trailing dot */
150 if (encoded_account[strlen(encoded_account)-1] == '.') {
151 encoded_account[strlen(encoded_account)-1] = '\0';
154 /* pull the user attributes */
155 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs,
156 trust_dom_attrs,
157 "(&(trustPartner=%s)(objectclass=trustedDomain))",
158 encoded_account);
160 if (num_records == 0) {
161 DEBUG(3,("Couldn't find trust [%s] in samdb.\n",
162 encoded_account));
163 return NT_STATUS_ACCESS_DENIED;
166 if (num_records > 1) {
167 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
168 return NT_STATUS_INTERNAL_DB_CORRUPTION;
171 flatname = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL);
172 if (!flatname) {
173 /* No flatname for this trust - we can't proceed */
174 return NT_STATUS_ACCESS_DENIED;
176 account_name = talloc_asprintf(mem_ctx, "%s$", flatname);
178 if (!account_name) {
179 return NT_STATUS_NO_MEMORY;
182 } else {
183 account_name = r->in.account_name;
186 /* pull the user attributes */
187 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
188 "(&(sAMAccountName=%s)(objectclass=user))",
189 ldb_binary_encode_string(mem_ctx, account_name));
191 if (num_records == 0) {
192 DEBUG(3,("Couldn't find user [%s] in samdb.\n",
193 r->in.account_name));
194 return NT_STATUS_ACCESS_DENIED;
197 if (num_records > 1) {
198 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
199 return NT_STATUS_INTERNAL_DB_CORRUPTION;
203 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
205 if (user_account_control & UF_ACCOUNTDISABLE) {
206 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
207 return NT_STATUS_ACCESS_DENIED;
210 if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
211 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
212 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
213 return NT_STATUS_ACCESS_DENIED;
215 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
216 r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
217 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
218 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
220 return NT_STATUS_ACCESS_DENIED;
222 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
223 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
224 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
225 return NT_STATUS_ACCESS_DENIED;
227 } else {
228 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
229 r->in.secure_channel_type));
230 return NT_STATUS_ACCESS_DENIED;
233 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
234 "objectSid", 0);
236 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd");
237 if (mach_pwd == NULL) {
238 return NT_STATUS_ACCESS_DENIED;
241 creds = netlogon_creds_server_init(mem_ctx,
242 r->in.account_name,
243 r->in.computer_name,
244 r->in.secure_channel_type,
245 &pipe_state->client_challenge,
246 &pipe_state->server_challenge,
247 mach_pwd,
248 r->in.credentials,
249 r->out.return_credentials,
250 *r->in.negotiate_flags);
252 if (!creds) {
253 return NT_STATUS_ACCESS_DENIED;
256 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
258 schannel_ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
259 if (!schannel_ldb) {
260 return NT_STATUS_ACCESS_DENIED;
263 nt_status = schannel_store_session_key_ldb(schannel_ldb, mem_ctx, creds);
264 talloc_free(schannel_ldb);
266 return nt_status;
269 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
270 struct netr_ServerAuthenticate *r)
272 struct netr_ServerAuthenticate3 a;
273 uint32_t rid;
274 /* TODO:
275 * negotiate_flags is used as an [in] parameter
276 * so it need to be initialised.
278 * (I think ... = 0; seems wrong here --metze)
280 uint32_t negotiate_flags_in = 0;
281 uint32_t negotiate_flags_out = 0;
283 a.in.server_name = r->in.server_name;
284 a.in.account_name = r->in.account_name;
285 a.in.secure_channel_type = r->in.secure_channel_type;
286 a.in.computer_name = r->in.computer_name;
287 a.in.credentials = r->in.credentials;
288 a.in.negotiate_flags = &negotiate_flags_in;
290 a.out.return_credentials = r->out.return_credentials;
291 a.out.rid = &rid;
292 a.out.negotiate_flags = &negotiate_flags_out;
294 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &a);
297 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
298 struct netr_ServerAuthenticate2 *r)
300 struct netr_ServerAuthenticate3 r3;
301 uint32_t rid = 0;
303 r3.in.server_name = r->in.server_name;
304 r3.in.account_name = r->in.account_name;
305 r3.in.secure_channel_type = r->in.secure_channel_type;
306 r3.in.computer_name = r->in.computer_name;
307 r3.in.credentials = r->in.credentials;
308 r3.out.return_credentials = r->out.return_credentials;
309 r3.in.negotiate_flags = r->in.negotiate_flags;
310 r3.out.negotiate_flags = r->out.negotiate_flags;
311 r3.out.rid = &rid;
313 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
317 Validate an incoming authenticator against the credentials for the remote machine.
319 The credentials are (re)read and from the schannel database, and
320 written back after the caclulations are performed.
322 The creds_out parameter (if not NULL) returns the credentials, if
323 the caller needs some of that information.
326 static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
327 TALLOC_CTX *mem_ctx,
328 const char *computer_name,
329 struct netr_Authenticator *received_authenticator,
330 struct netr_Authenticator *return_authenticator,
331 struct netlogon_creds_CredentialState **creds_out)
333 NTSTATUS nt_status;
334 struct ldb_context *ldb;
335 bool schannel_global_required = false; /* Should be lp_schannel_server() == true */
336 bool schannel_in_use = dce_call->conn->auth_state.auth_info
337 && dce_call->conn->auth_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL
338 && (dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY
339 || dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY);
341 ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
342 if (!ldb) {
343 return NT_STATUS_ACCESS_DENIED;
345 nt_status = schannel_creds_server_step_check_ldb(ldb, mem_ctx,
346 computer_name,
347 schannel_global_required,
348 schannel_in_use,
349 received_authenticator,
350 return_authenticator, creds_out);
351 talloc_free(ldb);
352 return nt_status;
356 Change the machine account password for the currently connected
357 client. Supplies only the NT#.
360 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
361 struct netr_ServerPasswordSet *r)
363 struct netlogon_creds_CredentialState *creds;
364 struct ldb_context *sam_ctx;
365 NTSTATUS nt_status;
367 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
368 mem_ctx,
369 r->in.computer_name,
370 r->in.credential, r->out.return_authenticator,
371 &creds);
372 NT_STATUS_NOT_OK_RETURN(nt_status);
374 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));
375 if (sam_ctx == NULL) {
376 return NT_STATUS_INVALID_SYSTEM_SERVICE;
379 netlogon_creds_des_decrypt(creds, r->in.new_password);
381 /* Using the sid for the account as the key, set the password */
382 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
383 creds->sid,
384 NULL, /* Don't have plaintext */
385 NULL, r->in.new_password,
386 true, /* Password change */
387 NULL, NULL);
388 return nt_status;
392 Change the machine account password for the currently connected
393 client. Supplies new plaintext.
395 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
396 struct netr_ServerPasswordSet2 *r)
398 struct netlogon_creds_CredentialState *creds;
399 struct ldb_context *sam_ctx;
400 NTSTATUS nt_status;
401 DATA_BLOB new_password;
403 struct samr_CryptPassword password_buf;
405 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
406 mem_ctx,
407 r->in.computer_name,
408 r->in.credential, r->out.return_authenticator,
409 &creds);
410 NT_STATUS_NOT_OK_RETURN(nt_status);
412 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));
413 if (sam_ctx == NULL) {
414 return NT_STATUS_INVALID_SYSTEM_SERVICE;
417 memcpy(password_buf.data, r->in.new_password->data, 512);
418 SIVAL(password_buf.data, 512, r->in.new_password->length);
419 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
421 if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
422 DEBUG(3,("samr: failed to decode password buffer\n"));
423 return NT_STATUS_WRONG_PASSWORD;
426 /* Using the sid for the account as the key, set the password */
427 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
428 creds->sid,
429 &new_password, /* we have plaintext */
430 NULL, NULL,
431 true, /* Password change */
432 NULL, NULL);
433 return nt_status;
438 netr_LogonUasLogon
440 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
441 struct netr_LogonUasLogon *r)
443 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
448 netr_LogonUasLogoff
450 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
451 struct netr_LogonUasLogoff *r)
453 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
458 netr_LogonSamLogon_base
460 This version of the function allows other wrappers to say 'do not check the credentials'
462 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
464 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
465 struct netr_LogonSamLogonEx *r, struct netlogon_creds_CredentialState *creds)
467 struct auth_context *auth_context;
468 struct auth_usersupplied_info *user_info;
469 struct auth_serversupplied_info *server_info;
470 NTSTATUS nt_status;
471 static const char zeros[16];
472 struct netr_SamBaseInfo *sam;
473 struct netr_SamInfo2 *sam2;
474 struct netr_SamInfo3 *sam3;
475 struct netr_SamInfo6 *sam6;
477 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
478 NT_STATUS_HAVE_NO_MEMORY(user_info);
480 user_info->flags = 0;
481 user_info->mapped_state = false;
482 user_info->remote_host = NULL;
484 switch (r->in.logon_level) {
485 case NetlogonInteractiveInformation:
486 case NetlogonServiceInformation:
487 case NetlogonInteractiveTransitiveInformation:
488 case NetlogonServiceTransitiveInformation:
489 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
490 netlogon_creds_arcfour_crypt(creds,
491 r->in.logon->password->lmpassword.hash,
492 sizeof(r->in.logon->password->lmpassword.hash));
493 netlogon_creds_arcfour_crypt(creds,
494 r->in.logon->password->ntpassword.hash,
495 sizeof(r->in.logon->password->ntpassword.hash));
496 } else {
497 netlogon_creds_des_decrypt(creds, &r->in.logon->password->lmpassword);
498 netlogon_creds_des_decrypt(creds, &r->in.logon->password->ntpassword);
501 /* TODO: we need to deny anonymous access here */
502 nt_status = auth_context_create(mem_ctx,
503 dce_call->event_ctx, dce_call->msg_ctx,
504 dce_call->conn->dce_ctx->lp_ctx,
505 &auth_context);
506 NT_STATUS_NOT_OK_RETURN(nt_status);
508 user_info->logon_parameters = r->in.logon->password->identity_info.parameter_control;
509 user_info->client.account_name = r->in.logon->password->identity_info.account_name.string;
510 user_info->client.domain_name = r->in.logon->password->identity_info.domain_name.string;
511 user_info->workstation_name = r->in.logon->password->identity_info.workstation.string;
513 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
514 user_info->password_state = AUTH_PASSWORD_HASH;
516 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
517 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
518 *user_info->password.hash.lanman = r->in.logon->password->lmpassword;
520 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
521 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
522 *user_info->password.hash.nt = r->in.logon->password->ntpassword;
524 break;
525 case NetlogonNetworkInformation:
526 case NetlogonNetworkTransitiveInformation:
528 /* TODO: we need to deny anonymous access here */
529 nt_status = auth_context_create(mem_ctx,
530 dce_call->event_ctx, dce_call->msg_ctx,
531 dce_call->conn->dce_ctx->lp_ctx,
532 &auth_context);
533 NT_STATUS_NOT_OK_RETURN(nt_status);
535 nt_status = auth_context_set_challenge(auth_context, r->in.logon->network->challenge, "netr_LogonSamLogonWithFlags");
536 NT_STATUS_NOT_OK_RETURN(nt_status);
538 user_info->logon_parameters = r->in.logon->network->identity_info.parameter_control;
539 user_info->client.account_name = r->in.logon->network->identity_info.account_name.string;
540 user_info->client.domain_name = r->in.logon->network->identity_info.domain_name.string;
541 user_info->workstation_name = r->in.logon->network->identity_info.workstation.string;
543 user_info->password_state = AUTH_PASSWORD_RESPONSE;
544 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length);
545 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length);
547 break;
550 case NetlogonGenericInformation:
552 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
553 netlogon_creds_arcfour_crypt(creds,
554 r->in.logon->generic->data, r->in.logon->generic->length);
555 } else {
556 /* Using DES to verify kerberos tickets makes no sense */
557 return NT_STATUS_INVALID_PARAMETER;
560 if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) {
561 NTSTATUS status;
562 struct server_id *kdc;
563 struct kdc_check_generic_kerberos check;
564 struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
565 NT_STATUS_HAVE_NO_MEMORY(generic);
566 *r->out.authoritative = 1;
568 /* TODO: Describe and deal with these flags */
569 *r->out.flags = 0;
571 r->out.validation->generic = generic;
573 kdc = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "kdc_server");
574 if ((kdc == NULL) || (kdc[0].id == 0)) {
575 return NT_STATUS_NO_LOGON_SERVERS;
578 check.in.generic_request =
579 data_blob_const(r->in.logon->generic->data,
580 r->in.logon->generic->length);
582 status = irpc_call(dce_call->msg_ctx, kdc[0],
583 &ndr_table_irpc, NDR_KDC_CHECK_GENERIC_KERBEROS,
584 &check, mem_ctx);
585 if (!NT_STATUS_IS_OK(status)) {
586 return status;
588 generic->length = check.out.generic_reply.length;
589 generic->data = check.out.generic_reply.data;
590 return NT_STATUS_OK;
593 /* Until we get an implemetnation of these other packages */
594 return NT_STATUS_INVALID_PARAMETER;
596 default:
597 return NT_STATUS_INVALID_PARAMETER;
600 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
601 NT_STATUS_NOT_OK_RETURN(nt_status);
603 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
604 NT_STATUS_NOT_OK_RETURN(nt_status);
606 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
607 /* It appears that level 6 is not individually encrypted */
608 if ((r->in.validation_level != 6) &&
609 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
610 /* This key is sent unencrypted without the ARCFOUR flag set */
611 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
612 netlogon_creds_arcfour_crypt(creds,
613 sam->key.key,
614 sizeof(sam->key.key));
618 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
619 /* It appears that level 6 is not individually encrypted */
620 if ((r->in.validation_level != 6) &&
621 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
622 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
623 netlogon_creds_arcfour_crypt(creds,
624 sam->LMSessKey.key,
625 sizeof(sam->LMSessKey.key));
626 } else {
627 netlogon_creds_des_encrypt_LMKey(creds,
628 &sam->LMSessKey);
632 switch (r->in.validation_level) {
633 case 2:
634 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
635 NT_STATUS_HAVE_NO_MEMORY(sam2);
636 sam2->base = *sam;
637 r->out.validation->sam2 = sam2;
638 break;
640 case 3:
641 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
642 NT_STATUS_HAVE_NO_MEMORY(sam3);
643 sam3->base = *sam;
644 r->out.validation->sam3 = sam3;
645 break;
647 case 6:
648 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
649 NT_STATUS_HAVE_NO_MEMORY(sam6);
650 sam6->base = *sam;
651 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
652 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
653 sam->account_name.string, sam6->forest.string);
654 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
655 r->out.validation->sam6 = sam6;
656 break;
658 default:
659 break;
662 *r->out.authoritative = 1;
664 /* TODO: Describe and deal with these flags */
665 *r->out.flags = 0;
667 return NT_STATUS_OK;
670 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
671 struct netr_LogonSamLogonEx *r)
673 NTSTATUS nt_status;
674 struct netlogon_creds_CredentialState *creds;
675 struct ldb_context *ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
676 if (!ldb) {
677 return NT_STATUS_ACCESS_DENIED;
680 nt_status = schannel_fetch_session_key_ldb(ldb, mem_ctx, r->in.computer_name, &creds);
681 if (!NT_STATUS_IS_OK(nt_status)) {
682 return nt_status;
685 if (!dce_call->conn->auth_state.auth_info ||
686 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
687 return NT_STATUS_ACCESS_DENIED;
689 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
693 netr_LogonSamLogonWithFlags
696 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
697 struct netr_LogonSamLogonWithFlags *r)
699 NTSTATUS nt_status;
700 struct netlogon_creds_CredentialState *creds;
701 struct netr_LogonSamLogonEx r2;
703 struct netr_Authenticator *return_authenticator;
705 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
706 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
708 nt_status = dcesrv_netr_creds_server_step_check(dce_call,
709 mem_ctx,
710 r->in.computer_name,
711 r->in.credential, return_authenticator,
712 &creds);
713 NT_STATUS_NOT_OK_RETURN(nt_status);
715 ZERO_STRUCT(r2);
717 r2.in.server_name = r->in.server_name;
718 r2.in.computer_name = r->in.computer_name;
719 r2.in.logon_level = r->in.logon_level;
720 r2.in.logon = r->in.logon;
721 r2.in.validation_level = r->in.validation_level;
722 r2.in.flags = r->in.flags;
723 r2.out.validation = r->out.validation;
724 r2.out.authoritative = r->out.authoritative;
725 r2.out.flags = r->out.flags;
727 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
729 r->out.return_authenticator = return_authenticator;
731 return nt_status;
735 netr_LogonSamLogon
737 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
738 struct netr_LogonSamLogon *r)
740 struct netr_LogonSamLogonWithFlags r2;
741 uint32_t flags = 0;
742 NTSTATUS status;
744 ZERO_STRUCT(r2);
746 r2.in.server_name = r->in.server_name;
747 r2.in.computer_name = r->in.computer_name;
748 r2.in.credential = r->in.credential;
749 r2.in.return_authenticator = r->in.return_authenticator;
750 r2.in.logon_level = r->in.logon_level;
751 r2.in.logon = r->in.logon;
752 r2.in.validation_level = r->in.validation_level;
753 r2.in.flags = &flags;
754 r2.out.validation = r->out.validation;
755 r2.out.authoritative = r->out.authoritative;
756 r2.out.flags = &flags;
758 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
760 r->out.return_authenticator = r2.out.return_authenticator;
762 return status;
767 netr_LogonSamLogoff
769 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
770 struct netr_LogonSamLogoff *r)
772 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
778 netr_DatabaseDeltas
780 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
781 struct netr_DatabaseDeltas *r)
783 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
788 netr_DatabaseSync2
790 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
791 struct netr_DatabaseSync2 *r)
793 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
794 return NT_STATUS_NOT_IMPLEMENTED;
799 netr_DatabaseSync
801 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
802 struct netr_DatabaseSync *r)
804 struct netr_DatabaseSync2 r2;
805 NTSTATUS status;
807 ZERO_STRUCT(r2);
809 r2.in.logon_server = r->in.logon_server;
810 r2.in.computername = r->in.computername;
811 r2.in.credential = r->in.credential;
812 r2.in.database_id = r->in.database_id;
813 r2.in.restart_state = SYNCSTATE_NORMAL_STATE;
814 r2.in.sync_context = r->in.sync_context;
815 r2.out.sync_context = r->out.sync_context;
816 r2.out.delta_enum_array = r->out.delta_enum_array;
817 r2.in.preferredmaximumlength = r->in.preferredmaximumlength;
819 status = dcesrv_netr_DatabaseSync2(dce_call, mem_ctx, &r2);
821 return status;
826 netr_AccountDeltas
828 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
829 struct netr_AccountDeltas *r)
831 /* w2k3 returns "NOT IMPLEMENTED" for this call */
832 return NT_STATUS_NOT_IMPLEMENTED;
837 netr_AccountSync
839 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
840 struct netr_AccountSync *r)
842 /* w2k3 returns "NOT IMPLEMENTED" for this call */
843 return NT_STATUS_NOT_IMPLEMENTED;
848 netr_GetDcName
850 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
851 struct netr_GetDcName *r)
853 const char * const attrs[] = { NULL };
854 struct ldb_context *sam_ctx;
855 struct ldb_message **res;
856 struct ldb_dn *domain_dn;
857 int ret;
858 const char *dcname;
860 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
861 dce_call->conn->dce_ctx->lp_ctx,
862 dce_call->conn->auth_state.session_info);
863 if (sam_ctx == NULL) {
864 return WERR_DS_UNAVAILABLE;
867 domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx,
868 r->in.domainname);
869 if (domain_dn == NULL) {
870 return WERR_DS_UNAVAILABLE;
873 ret = gendb_search_dn(sam_ctx, mem_ctx,
874 domain_dn, &res, attrs);
875 if (ret != 1) {
876 return WERR_NO_SUCH_DOMAIN;
879 /* TODO: - return real IP address
880 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
882 dcname = talloc_asprintf(mem_ctx, "\\\\%s",
883 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
884 W_ERROR_HAVE_NO_MEMORY(dcname);
886 *r->out.dcname = dcname;
887 return WERR_OK;
892 netr_LogonControl2Ex
894 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
895 struct netr_LogonControl2Ex *r)
897 return WERR_NOT_SUPPORTED;
902 netr_LogonControl
904 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
905 struct netr_LogonControl *r)
907 struct netr_LogonControl2Ex r2;
908 WERROR werr;
910 if (r->in.level == 0x00000001) {
911 ZERO_STRUCT(r2);
913 r2.in.logon_server = r->in.logon_server;
914 r2.in.function_code = r->in.function_code;
915 r2.in.level = r->in.level;
916 r2.in.data = NULL;
917 r2.out.query = r->out.query;
919 werr = dcesrv_netr_LogonControl2Ex(dce_call, mem_ctx, &r2);
920 } else if (r->in.level == 0x00000002) {
921 werr = WERR_NOT_SUPPORTED;
922 } else {
923 werr = WERR_UNKNOWN_LEVEL;
926 return werr;
931 netr_LogonControl2
933 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
934 struct netr_LogonControl2 *r)
936 struct netr_LogonControl2Ex r2;
937 WERROR werr;
939 ZERO_STRUCT(r2);
941 r2.in.logon_server = r->in.logon_server;
942 r2.in.function_code = r->in.function_code;
943 r2.in.level = r->in.level;
944 r2.in.data = r->in.data;
945 r2.out.query = r->out.query;
947 werr = dcesrv_netr_LogonControl2Ex(dce_call, mem_ctx, &r2);
949 return werr;
954 netr_GetAnyDCName
956 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
957 struct netr_GetAnyDCName *r)
959 struct netr_GetDcName r2;
960 WERROR werr;
962 ZERO_STRUCT(r2);
964 r2.in.logon_server = r->in.logon_server;
965 r2.in.domainname = r->in.domainname;
966 r2.out.dcname = r->out.dcname;
968 werr = dcesrv_netr_GetDcName(dce_call, mem_ctx, &r2);
970 return werr;
975 netr_DatabaseRedo
977 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
978 struct netr_DatabaseRedo *r)
980 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
985 netr_NetrEnumerateTurstedDomains
987 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
988 struct netr_NetrEnumerateTrustedDomains *r)
990 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
995 netr_LogonGetCapabilities
997 static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
998 struct netr_LogonGetCapabilities *r)
1000 /* we don't support AES yet */
1001 return NT_STATUS_NOT_IMPLEMENTED;
1006 netr_NETRLOGONSETSERVICEBITS
1008 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1009 struct netr_NETRLOGONSETSERVICEBITS *r)
1011 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1016 netr_LogonGetTrustRid
1018 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1019 struct netr_LogonGetTrustRid *r)
1021 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1026 netr_NETRLOGONCOMPUTESERVERDIGEST
1028 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1029 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
1031 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1036 netr_NETRLOGONCOMPUTECLIENTDIGEST
1038 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1039 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
1041 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1047 netr_DsRGetSiteName
1049 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1050 struct netr_DsRGetSiteName *r)
1052 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1057 fill in a netr_OneDomainInfo from a ldb search result
1059 static NTSTATUS fill_one_domain_info(TALLOC_CTX *mem_ctx,
1060 struct loadparm_context *lp_ctx,
1061 struct ldb_context *sam_ctx,
1062 struct ldb_message *res,
1063 struct netr_OneDomainInfo *info,
1064 bool is_local, bool is_trust_list)
1066 ZERO_STRUCTP(info);
1068 info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension);
1069 info->trust_extension.length = 16;
1070 info->trust_extension.info->flags =
1071 NETR_TRUST_FLAG_TREEROOT |
1072 NETR_TRUST_FLAG_IN_FOREST |
1073 NETR_TRUST_FLAG_PRIMARY;
1075 info->trust_extension.info->parent_index = 0; /* should be index into array
1076 of parent */
1077 info->trust_extension.info->trust_type = LSA_TRUST_TYPE_UPLEVEL; /* should be based on ldb search for trusts */
1078 info->trust_extension.info->trust_attributes = LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE; /* needs to be based on ldb search */
1080 if (is_trust_list) {
1081 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
1082 info->dns_forestname.string = NULL;
1083 } else {
1084 char *p;
1085 /* TODO: we need a common function for pulling the forest */
1086 info->dns_forestname.string = ldb_dn_canonical_string(info, ldb_get_root_basedn(sam_ctx));
1087 if (!info->dns_forestname.string) {
1088 return NT_STATUS_NO_SUCH_DOMAIN;
1090 p = strchr(info->dns_forestname.string, '/');
1091 if (p) {
1092 *p = '\0';
1096 if (is_local) {
1097 info->domainname.string = lp_sam_name(lp_ctx);
1098 info->dns_domainname.string = lp_realm(lp_ctx);
1099 info->domain_guid = samdb_result_guid(res, "objectGUID");
1100 info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
1101 } else {
1102 info->domainname.string = samdb_result_string(res, "flatName", NULL);
1103 info->dns_domainname.string = samdb_result_string(res, "trustPartner", NULL);
1104 info->domain_guid = samdb_result_guid(res, "objectGUID");
1105 info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
1108 return NT_STATUS_OK;
1112 netr_LogonGetDomainInfo
1113 this is called as part of the ADS domain logon procedure.
1115 It has an important role in convaying details about the client, such
1116 as Operating System, Version, Service Pack etc.
1118 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call,
1119 TALLOC_CTX *mem_ctx, struct netr_LogonGetDomainInfo *r)
1121 struct netlogon_creds_CredentialState *creds;
1122 const char * const attrs[] = { "objectSid", "objectGUID", "flatName",
1123 "securityIdentifier", "trustPartner", NULL };
1124 const char *temp_str;
1125 const char *old_dns_hostname;
1126 struct ldb_context *sam_ctx;
1127 struct ldb_message **res1, **res2, *new_msg;
1128 struct ldb_dn *workstation_dn;
1129 struct netr_DomainInformation *domain_info;
1130 struct netr_LsaPolicyInformation *lsa_policy_info;
1131 struct netr_OsVersionInfoEx *os_version;
1132 uint32_t default_supported_enc_types =
1133 ENC_CRC32|ENC_RSA_MD5|ENC_RC4_HMAC_MD5;
1134 int ret1, ret2, i;
1135 NTSTATUS status;
1137 status = dcesrv_netr_creds_server_step_check(dce_call,
1138 mem_ctx,
1139 r->in.computer_name,
1140 r->in.credential,
1141 r->out.return_authenticator,
1142 &creds);
1143 if (!NT_STATUS_IS_OK(status)) {
1144 DEBUG(0,(__location__ " Bad credentials - error\n"));
1146 NT_STATUS_NOT_OK_RETURN(status);
1148 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
1149 dce_call->conn->dce_ctx->lp_ctx,
1150 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
1151 if (sam_ctx == NULL) {
1152 return NT_STATUS_INVALID_SYSTEM_SERVICE;
1155 switch (r->in.level) {
1156 case 1: /* Domain information */
1158 /* TODO: check NTSTATUS results - and fail also on SAMDB
1159 * errors (needs some testing against Windows Server 2008) */
1162 * Check that the computer name parameter matches as prefix with
1163 * the DNS hostname in the workstation info structure.
1165 temp_str = strndup(r->in.query->workstation_info->dns_hostname,
1166 strcspn(r->in.query->workstation_info->dns_hostname,
1167 "."));
1168 if (strcasecmp(r->in.computer_name, temp_str) != 0)
1169 return NT_STATUS_INVALID_PARAMETER;
1171 workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
1172 dom_sid_string(mem_ctx, creds->sid));
1173 NT_STATUS_HAVE_NO_MEMORY(workstation_dn);
1175 /* Gets the old DNS hostname */
1176 old_dns_hostname = samdb_search_string(sam_ctx, mem_ctx,
1177 workstation_dn,
1178 "dNSHostName",
1179 NULL);
1181 /* Gets host informations and put them in our directory */
1182 new_msg = ldb_msg_new(mem_ctx);
1183 NT_STATUS_HAVE_NO_MEMORY(new_msg);
1185 new_msg->dn = workstation_dn;
1187 /* Deletes old OS version values */
1188 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
1189 "operatingSystemServicePack");
1190 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
1191 "operatingSystemVersion");
1193 if (samdb_replace(sam_ctx, mem_ctx, new_msg) != LDB_SUCCESS) {
1194 DEBUG(3,("Impossible to update samdb: %s\n",
1195 ldb_errstring(sam_ctx)));
1198 talloc_free(new_msg);
1200 new_msg = ldb_msg_new(mem_ctx);
1201 NT_STATUS_HAVE_NO_MEMORY(new_msg);
1203 new_msg->dn = workstation_dn;
1205 /* Sets the OS name */
1206 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1207 "operatingSystem",
1208 r->in.query->workstation_info->os_name.string);
1211 * Sets informations from "os_version". On a empty structure
1212 * the values are cleared.
1214 if (r->in.query->workstation_info->os_version.os != NULL) {
1215 os_version = &r->in.query->workstation_info->os_version.os->os;
1217 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1218 "operatingSystemServicePack",
1219 os_version->CSDVersion);
1221 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
1222 "operatingSystemVersion",
1223 talloc_asprintf(mem_ctx, "%d.%d (%d)",
1224 os_version->MajorVersion,
1225 os_version->MinorVersion,
1226 os_version->BuildNumber
1232 * Updates the "dNSHostname" and the "servicePrincipalName"s
1233 * since the client wishes that the server should handle this
1234 * for him ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set).
1235 * See MS-NRPC section 3.5.4.3.9
1237 if ((r->in.query->workstation_info->workstation_flags
1238 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) == 0) {
1240 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1241 "dNSHostname",
1242 r->in.query->workstation_info->dns_hostname);
1243 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1244 "servicePrincipalName",
1245 talloc_asprintf(mem_ctx, "HOST/%s",
1246 r->in.computer_name)
1248 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
1249 "servicePrincipalName",
1250 talloc_asprintf(mem_ctx, "HOST/%s",
1251 r->in.query->workstation_info->dns_hostname)
1255 if (samdb_replace(sam_ctx, mem_ctx, new_msg) != LDB_SUCCESS) {
1256 DEBUG(3,("Impossible to update samdb: %s\n",
1257 ldb_errstring(sam_ctx)));
1260 talloc_free(new_msg);
1262 /* Writes back the domain information */
1264 /* We need to do two searches. The first will pull our primary
1265 domain and the second will pull any trusted domains. Our
1266 primary domain is also a "trusted" domain, so we need to
1267 put the primary domain into the lists of returned trusts as
1268 well. */
1269 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx),
1270 &res1, attrs);
1271 if (ret1 != 1) {
1272 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1275 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs,
1276 "(objectClass=trustedDomain)");
1277 if (ret2 == -1) {
1278 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1281 domain_info = talloc(mem_ctx, struct netr_DomainInformation);
1282 NT_STATUS_HAVE_NO_MEMORY(domain_info);
1284 ZERO_STRUCTP(domain_info);
1286 /* Informations about the local and trusted domains */
1288 status = fill_one_domain_info(mem_ctx,
1289 dce_call->conn->dce_ctx->lp_ctx,
1290 sam_ctx, res1[0], &domain_info->primary_domain,
1291 true, false);
1292 NT_STATUS_NOT_OK_RETURN(status);
1294 domain_info->trusted_domain_count = ret2 + 1;
1295 domain_info->trusted_domains = talloc_array(mem_ctx,
1296 struct netr_OneDomainInfo,
1297 domain_info->trusted_domain_count);
1298 NT_STATUS_HAVE_NO_MEMORY(domain_info->trusted_domains);
1300 for (i=0;i<ret2;i++) {
1301 status = fill_one_domain_info(mem_ctx,
1302 dce_call->conn->dce_ctx->lp_ctx,
1303 sam_ctx, res2[i],
1304 &domain_info->trusted_domains[i],
1305 false, true);
1306 NT_STATUS_NOT_OK_RETURN(status);
1309 status = fill_one_domain_info(mem_ctx,
1310 dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res1[0],
1311 &domain_info->trusted_domains[i], true, true);
1312 NT_STATUS_NOT_OK_RETURN(status);
1314 /* Sets the supported encryption types */
1315 domain_info->supported_enc_types = samdb_search_uint(
1316 sam_ctx, mem_ctx,
1317 default_supported_enc_types, workstation_dn,
1318 "msDS-SupportedEncryptionTypes", NULL);
1320 /* Other host domain informations */
1322 lsa_policy_info = talloc(mem_ctx,
1323 struct netr_LsaPolicyInformation);
1324 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
1325 ZERO_STRUCTP(lsa_policy_info);
1327 domain_info->lsa_policy = *lsa_policy_info;
1329 domain_info->dns_hostname.string = old_dns_hostname;
1330 domain_info->workstation_flags =
1331 r->in.query->workstation_info->workstation_flags;
1333 r->out.info->domain_info = domain_info;
1334 break;
1335 case 2: /* LSA policy information - not used at the moment */
1336 lsa_policy_info = talloc(mem_ctx,
1337 struct netr_LsaPolicyInformation);
1338 NT_STATUS_HAVE_NO_MEMORY(lsa_policy_info);
1339 ZERO_STRUCTP(lsa_policy_info);
1341 r->out.info->lsa_policy_info = lsa_policy_info;
1342 break;
1343 default:
1344 return NT_STATUS_INVALID_LEVEL;
1345 break;
1348 return NT_STATUS_OK;
1354 netr_ServerPasswordGet
1356 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1357 struct netr_ServerPasswordGet *r)
1359 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1364 netr_NETRLOGONSENDTOSAM
1366 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1367 struct netr_NETRLOGONSENDTOSAM *r)
1369 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1374 netr_DsRAddressToSitenamesW
1376 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1377 struct netr_DsRAddressToSitenamesW *r)
1379 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1384 netr_DsRGetDCNameEx2
1386 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1387 struct netr_DsRGetDCNameEx2 *r)
1389 const char * const attrs[] = { "objectGUID", NULL };
1390 struct ldb_context *sam_ctx;
1391 struct ldb_message **res;
1392 struct ldb_dn *domain_dn;
1393 int ret;
1394 struct netr_DsRGetDCNameInfo *info;
1396 ZERO_STRUCTP(r->out.info);
1398 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1399 if (sam_ctx == NULL) {
1400 return WERR_DS_UNAVAILABLE;
1403 /* Win7-beta will send the domain name in the form the user typed, so we have to cope
1404 with both the short and long form here */
1405 if (r->in.domain_name != NULL && !lp_is_my_domain_or_realm(dce_call->conn->dce_ctx->lp_ctx,
1406 r->in.domain_name)) {
1407 return WERR_NO_SUCH_DOMAIN;
1410 domain_dn = ldb_get_default_basedn(sam_ctx);
1411 if (domain_dn == NULL) {
1412 return WERR_DS_UNAVAILABLE;
1415 ret = gendb_search_dn(sam_ctx, mem_ctx,
1416 domain_dn, &res, attrs);
1417 if (ret != 1) {
1420 info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1421 W_ERROR_HAVE_NO_MEMORY(info);
1423 /* TODO: - return real IP address
1424 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1426 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1427 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1428 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1429 W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
1430 info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1431 W_ERROR_HAVE_NO_MEMORY(info->dc_address);
1432 info->dc_address_type = DS_ADDRESS_TYPE_INET;
1433 info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1434 info->domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1435 info->forest_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1436 info->dc_flags = DS_DNS_FOREST |
1437 DS_DNS_DOMAIN |
1438 DS_DNS_CONTROLLER |
1439 DS_SERVER_WRITABLE |
1440 DS_SERVER_CLOSEST |
1441 DS_SERVER_TIMESERV |
1442 DS_SERVER_KDC |
1443 DS_SERVER_DS |
1444 DS_SERVER_LDAP |
1445 DS_SERVER_GC |
1446 DS_SERVER_PDC;
1447 info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1448 W_ERROR_HAVE_NO_MEMORY(info->dc_site_name);
1449 info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1450 W_ERROR_HAVE_NO_MEMORY(info->client_site_name);
1452 *r->out.info = info;
1454 return WERR_OK;
1458 netr_DsRGetDCNameEx
1460 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1461 struct netr_DsRGetDCNameEx *r)
1463 struct netr_DsRGetDCNameEx2 r2;
1464 WERROR werr;
1466 ZERO_STRUCT(r2);
1468 r2.in.server_unc = r->in.server_unc;
1469 r2.in.client_account = NULL;
1470 r2.in.mask = 0;
1471 r2.in.domain_guid = r->in.domain_guid;
1472 r2.in.domain_name = r->in.domain_name;
1473 r2.in.site_name = r->in.site_name;
1474 r2.in.flags = r->in.flags;
1475 r2.out.info = r->out.info;
1477 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1479 return werr;
1483 netr_DsRGetDCName
1485 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1486 struct netr_DsRGetDCName *r)
1488 struct netr_DsRGetDCNameEx2 r2;
1489 WERROR werr;
1491 ZERO_STRUCT(r2);
1493 r2.in.server_unc = r->in.server_unc;
1494 r2.in.client_account = NULL;
1495 r2.in.mask = 0;
1496 r2.in.domain_name = r->in.domain_name;
1497 r2.in.domain_guid = r->in.domain_guid;
1499 r2.in.site_name = NULL; /* should fill in from site GUID */
1500 r2.in.flags = r->in.flags;
1501 r2.out.info = r->out.info;
1503 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1505 return werr;
1508 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1510 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1511 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1513 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1518 netr_NetrEnumerateTrustedDomainsEx
1520 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1521 struct netr_NetrEnumerateTrustedDomainsEx *r)
1523 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1528 netr_DsRAddressToSitenamesExW
1530 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1531 struct netr_DsRAddressToSitenamesExW *r)
1533 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1538 netr_DsrGetDcSiteCoverageW
1540 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1541 struct netr_DsrGetDcSiteCoverageW *r)
1543 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1548 netr_DsrEnumerateDomainTrusts
1550 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1551 struct netr_DsrEnumerateDomainTrusts *r)
1553 struct netr_DomainTrustList *trusts;
1554 struct ldb_context *sam_ctx;
1555 int ret;
1556 struct ldb_message **dom_res;
1557 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1559 ZERO_STRUCT(r->out);
1561 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1562 if (sam_ctx == NULL) {
1563 return WERR_GENERAL_FAILURE;
1566 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
1567 &dom_res, dom_attrs);
1568 if (ret == -1) {
1569 return WERR_GENERAL_FAILURE;
1571 if (ret != 1) {
1572 return WERR_GENERAL_FAILURE;
1575 trusts = talloc(mem_ctx, struct netr_DomainTrustList);
1576 W_ERROR_HAVE_NO_MEMORY(trusts);
1578 trusts->array = talloc_array(trusts, struct netr_DomainTrust, ret);
1579 W_ERROR_HAVE_NO_MEMORY(trusts->array);
1581 trusts->count = 1; /* ?? */
1583 r->out.trusts = trusts;
1585 /* TODO: add filtering by trust_flags, and correct trust_type
1586 and attributes */
1587 trusts->array[0].netbios_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
1588 trusts->array[0].dns_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1589 trusts->array[0].trust_flags =
1590 NETR_TRUST_FLAG_TREEROOT |
1591 NETR_TRUST_FLAG_IN_FOREST |
1592 NETR_TRUST_FLAG_PRIMARY;
1593 trusts->array[0].parent_index = 0;
1594 trusts->array[0].trust_type = 2;
1595 trusts->array[0].trust_attributes = 0;
1596 trusts->array[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1597 trusts->array[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1599 return WERR_OK;
1604 netr_DsrDeregisterDNSHostRecords
1606 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1607 struct netr_DsrDeregisterDNSHostRecords *r)
1609 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1614 netr_ServerTrustPasswordsGet
1616 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1617 struct netr_ServerTrustPasswordsGet *r)
1619 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1624 netr_DsRGetForestTrustInformation
1626 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1627 struct netr_DsRGetForestTrustInformation *r)
1629 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1634 netr_GetForestTrustInformation
1636 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1637 struct netr_GetForestTrustInformation *r)
1639 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1644 netr_ServerGetTrustInfo
1646 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1647 struct netr_ServerGetTrustInfo *r)
1649 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1653 /* include the generated boilerplate */
1654 #include "librpc/gen_ndr/ndr_netlogon_s.c"