1 /*
2    Unix SMB/CIFS implementation.
3 
4    endpoint server for the netlogon pipe
5 
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004
7    Copyright (C) Stefan Metzmacher <metze@samba.org>  2005
8 
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13 
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.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23 
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.h"
30 #include "dsdb/samdb/samdb.h"
31 #include "rpc_server/samr/proto.h"
32 #include "db_wrap.h"
33 #include "libcli/auth/libcli_auth.h"
34 #include "auth/gensec/schannel_state.h"
35 #include "libcli/security/security.h"
36 
37 struct server_pipe_state {
38 	struct netr_Credential client_challenge;
39 	struct netr_Credential server_challenge;
40 };
41 
42 
netr_ServerReqChallenge(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_ServerReqChallenge * r)43 static NTSTATUS netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
44 					struct netr_ServerReqChallenge *r)
45 {
46 	struct server_pipe_state *pipe_state = dce_call->context->private;
47 
48 	ZERO_STRUCTP(r->out.credentials);
49 
50 	/* destroyed on pipe shutdown */
51 
52 	if (pipe_state) {
53 		talloc_free(pipe_state);
54 		dce_call->context->private = NULL;
55 	}
56 
57 	pipe_state = talloc(dce_call->context, struct server_pipe_state);
58 	NT_STATUS_HAVE_NO_MEMORY(pipe_state);
59 
60 	pipe_state->client_challenge = *r->in.credentials;
61 
62 	generate_random_buffer(pipe_state->server_challenge.data,
63 			       sizeof(pipe_state->server_challenge.data));
64 
65 	*r->out.credentials = pipe_state->server_challenge;
66 
67 	dce_call->context->private = pipe_state;
68 
69 	return NT_STATUS_OK;
70 }
71 
netr_ServerAuthenticate3(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_ServerAuthenticate3 * r)72 static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
73 					 struct netr_ServerAuthenticate3 *r)
74 {
75 	struct server_pipe_state *pipe_state = dce_call->context->private;
76 	struct creds_CredentialState *creds;
77 	void *sam_ctx;
78 	struct samr_Password *mach_pwd;
79 	uint16_t acct_flags;
80 	int num_records;
81 	struct ldb_message **msgs;
82 	NTSTATUS nt_status;
83 	const char *attrs[] = {"ntPwdHash", "userAccountControl",
84 			       "objectSid", NULL};
85 
86 	ZERO_STRUCTP(r->out.credentials);
87 	*r->out.rid = 0;
88 	*r->out.negotiate_flags = *r->in.negotiate_flags;
89 
90 	if (!pipe_state) {
91 		DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
92 		return NT_STATUS_ACCESS_DENIED;
93 	}
94 
95 	sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
96 	if (sam_ctx == NULL) {
97 		return NT_STATUS_INVALID_SYSTEM_SERVICE;
98 	}
99 	/* pull the user attributes */
100 	num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
101 				   "(&(sAMAccountName=%s)(objectclass=user))",
102 				   r->in.account_name);
103 
104 	if (num_records == 0) {
105 		DEBUG(3,("Couldn't find user [%s] in samdb.\n",
106 			 r->in.account_name));
107 		return NT_STATUS_ACCESS_DENIED;
108 	}
109 
110 	if (num_records > 1) {
111 		DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
112 		return NT_STATUS_INTERNAL_DB_CORRUPTION;
113 	}
114 
115 	acct_flags = samdb_result_acct_flags(msgs[0],
116 					     "userAccountControl");
117 
118 	if (acct_flags & ACB_DISABLED) {
119 		DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
120 		return NT_STATUS_ACCESS_DENIED;
121 	}
122 
123 	if (r->in.secure_channel_type == SEC_CHAN_WKSTA) {
124 		if (!(acct_flags & ACB_WSTRUST)) {
125 			DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", acct_flags));
126 			return NT_STATUS_ACCESS_DENIED;
127 		}
128 	} else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN) {
129 		if (!(acct_flags & ACB_DOMTRUST)) {
130 			DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", acct_flags));
131 			return NT_STATUS_ACCESS_DENIED;
132 		}
133 	} else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
134 		if (!(acct_flags & ACB_SVRTRUST)) {
135 			DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", acct_flags));
136 			return NT_STATUS_ACCESS_DENIED;
137 		}
138 	} else {
139 		DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
140 			  r->in.secure_channel_type));
141 		return NT_STATUS_ACCESS_DENIED;
142 	}
143 
144 	*r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
145 						"objectSid", 0);
146 
147 	mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "ntPwdHash");
148 	if (mach_pwd == NULL) {
149 		return NT_STATUS_ACCESS_DENIED;
150 	}
151 
152 	creds = talloc(mem_ctx, struct creds_CredentialState);
153 	NT_STATUS_HAVE_NO_MEMORY(creds);
154 
155 	creds_server_init(creds, &pipe_state->client_challenge,
156 			  &pipe_state->server_challenge, mach_pwd,
157 			  r->out.credentials,
158 			  *r->in.negotiate_flags);
159 
160 	if (!creds_server_check(creds, r->in.credentials)) {
161 		talloc_free(creds);
162 		return NT_STATUS_ACCESS_DENIED;
163 	}
164 
165 	creds->account_name = talloc_steal(creds, r->in.account_name);
166 
167 	creds->computer_name = talloc_steal(creds, r->in.computer_name);
168 	creds->domain = talloc_strdup(creds, lp_workgroup());
169 
170 	creds->secure_channel_type = r->in.secure_channel_type;
171 
172 	creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
173 
174 
175 	/* remember this session key state */
176 	nt_status = schannel_store_session_key(mem_ctx, creds);
177 
178 	return nt_status;
179 }
180 
netr_ServerAuthenticate(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_ServerAuthenticate * r)181 static NTSTATUS netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
182 					struct netr_ServerAuthenticate *r)
183 {
184 	struct netr_ServerAuthenticate3 r3;
185 	uint32_t rid = 0;
186 	/* TODO:
187 	 * negotiate_flags is used as an [in] parameter
188 	 * so it need to be initialised.
189 	 *
190 	 * (I think ... = 0; seems wrong here --metze)
191 	 */
192 	uint32_t negotiate_flags = 0;
193 
194 	r3.in.server_name = r->in.server_name;
195 	r3.in.account_name = r->in.account_name;
196 	r3.in.secure_channel_type = r->in.secure_channel_type;
197 	r3.in.computer_name = r->in.computer_name;
198 	r3.in.credentials = r->in.credentials;
199 	r3.out.credentials = r->out.credentials;
200 	r3.in.negotiate_flags = &negotiate_flags;
201 	r3.out.negotiate_flags = &negotiate_flags;
202 	r3.out.rid = &rid;
203 
204 	return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
205 }
206 
netr_ServerAuthenticate2(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_ServerAuthenticate2 * r)207 static NTSTATUS netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
208 					 struct netr_ServerAuthenticate2 *r)
209 {
210 	struct netr_ServerAuthenticate3 r3;
211 	uint32_t rid = 0;
212 
213 	r3.in.server_name = r->in.server_name;
214 	r3.in.account_name = r->in.account_name;
215 	r3.in.secure_channel_type = r->in.secure_channel_type;
216 	r3.in.computer_name = r->in.computer_name;
217 	r3.in.credentials = r->in.credentials;
218 	r3.out.credentials = r->out.credentials;
219 	r3.in.negotiate_flags = r->in.negotiate_flags;
220 	r3.out.negotiate_flags = r->out.negotiate_flags;
221 	r3.out.rid = &rid;
222 
223 	return netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
224 }
225 
226 /*
227   Validate an incoming authenticator against the credentials for the remote machine.
228 
229   The credentials are (re)read and from the schannel database, and
230   written back after the caclulations are performed.
231 
232   The creds_out parameter (if not NULL) returns the credentials, if
233   the caller needs some of that information.
234 
235 */
netr_creds_server_step_check(const char * computer_name,TALLOC_CTX * mem_ctx,struct netr_Authenticator * received_authenticator,struct netr_Authenticator * return_authenticator,struct creds_CredentialState ** creds_out)236 static NTSTATUS netr_creds_server_step_check(const char *computer_name,
237 					     TALLOC_CTX *mem_ctx,
238 					     struct netr_Authenticator *received_authenticator,
239 					     struct netr_Authenticator *return_authenticator,
240 					     struct creds_CredentialState **creds_out)
241 {
242 	struct creds_CredentialState *creds;
243 	NTSTATUS nt_status;
244 	struct ldb_context *ldb;
245 	int ret;
246 
247 	ldb = schannel_db_connect(mem_ctx);
248 	if (!ldb) {
249 		return NT_STATUS_ACCESS_DENIED;
250 	}
251 
252 	ret = ldb_transaction_start(ldb);
253 	if (ret != 0) {
254 		talloc_free(ldb);
255 		return NT_STATUS_INTERNAL_DB_CORRUPTION;
256 	}
257 
258 	/* Because this is a shared structure (even across
259 	 * disconnects) we must update the database every time we
260 	 * update the structure */
261 
262 	nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name, lp_workgroup(),
263 						   &creds);
264 	if (NT_STATUS_IS_OK(nt_status)) {
265 		nt_status = creds_server_step_check(creds,
266 						    received_authenticator,
267 						    return_authenticator);
268 	}
269 	if (NT_STATUS_IS_OK(nt_status)) {
270 		nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
271 	}
272 
273 	if (NT_STATUS_IS_OK(nt_status)) {
274 		ldb_transaction_commit(ldb);
275 		if (creds_out) {
276 			*creds_out = creds;
277 			talloc_steal(mem_ctx, creds);
278 		}
279 	} else {
280 		ldb_transaction_cancel(ldb);
281 	}
282 	talloc_free(ldb);
283 	return nt_status;
284 }
285 
286 /*
287   Change the machine account password for the currently connected
288   client.  Supplies only the NT#.
289 */
290 
netr_ServerPasswordSet(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_ServerPasswordSet * r)291 static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
292 				       struct netr_ServerPasswordSet *r)
293 {
294 	struct creds_CredentialState *creds;
295 	struct ldb_context *sam_ctx;
296 	NTSTATUS nt_status;
297 
298 	nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
299 						 &r->in.credential, &r->out.return_authenticator,
300 						 &creds);
301 	NT_STATUS_NOT_OK_RETURN(nt_status);
302 
303 	sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
304 	if (sam_ctx == NULL) {
305 		return NT_STATUS_INVALID_SYSTEM_SERVICE;
306 	}
307 
308 	creds_des_decrypt(creds, &r->in.new_password);
309 
310 	/* Using the sid for the account as the key, set the password */
311 	nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
312 					   creds->sid,
313 					   NULL, /* Don't have plaintext */
314 					   NULL, &r->in.new_password,
315 					   False, /* This is not considered a password change */
316 					   False, /* don't restrict this password change (match w2k3) */
317 					   NULL, NULL);
318 	return nt_status;
319 }
320 
321 /*
322   Change the machine account password for the currently connected
323   client.  Supplies new plaintext.
324 */
netr_ServerPasswordSet2(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_ServerPasswordSet2 * r)325 static NTSTATUS netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
326 				       struct netr_ServerPasswordSet2 *r)
327 {
328 	struct creds_CredentialState *creds;
329 	struct ldb_context *sam_ctx;
330 	NTSTATUS nt_status;
331 	char new_pass[512];
332 	uint32_t new_pass_len;
333 	BOOL ret;
334 
335 	struct samr_CryptPassword password_buf;
336 
337 	nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
338 						 &r->in.credential, &r->out.return_authenticator,
339 						 &creds);
340 	NT_STATUS_NOT_OK_RETURN(nt_status);
341 
342 	sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
343 	if (sam_ctx == NULL) {
344 		return NT_STATUS_INVALID_SYSTEM_SERVICE;
345 	}
346 
347 	memcpy(password_buf.data, r->in.new_password.data, 512);
348 	SIVAL(password_buf.data,512,r->in.new_password.length);
349 	creds_arcfour_crypt(creds, password_buf.data, 516);
350 
351 	ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass),
352 			       &new_pass_len, STR_UNICODE);
353 	if (!ret) {
354 		DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n"));
355 		return NT_STATUS_ACCESS_DENIED;
356 	}
357 
358 	/* Using the sid for the account as the key, set the password */
359 	nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
360 					   creds->sid,
361 					   new_pass, /* we have plaintext */
362 					   NULL, NULL,
363 					   False, /* This is not considered a password change */
364 					   False, /* don't restrict this password change (match w2k3) */
365 					   NULL, NULL);
366 	return nt_status;
367 }
368 
369 
370 /*
371   netr_LogonUasLogon
372 */
netr_LogonUasLogon(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_LogonUasLogon * r)373 static WERROR netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
374 				 struct netr_LogonUasLogon *r)
375 {
376 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
377 }
378 
379 
380 /*
381   netr_LogonUasLogoff
382 */
netr_LogonUasLogoff(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_LogonUasLogoff * r)383 static WERROR netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
384 		       struct netr_LogonUasLogoff *r)
385 {
386 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
387 }
388 
389 
390 /*
391   netr_LogonSamLogon_base
392 
393   This version of the function allows other wrappers to say 'do not check the credentials'
394 
395   We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
396 */
netr_LogonSamLogon_base(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_LogonSamLogonEx * r,struct creds_CredentialState * creds)397 static NTSTATUS netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
398 					struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
399 {
400 	struct auth_context *auth_context;
401 	struct auth_usersupplied_info *user_info;
402 	struct auth_serversupplied_info *server_info;
403 	NTSTATUS nt_status;
404 	static const char zeros[16];
405 	struct netr_SamBaseInfo *sam;
406 	struct netr_SamInfo2 *sam2;
407 	struct netr_SamInfo3 *sam3;
408 	struct netr_SamInfo6 *sam6;
409 
410 	user_info = talloc(mem_ctx, struct auth_usersupplied_info);
411 	NT_STATUS_HAVE_NO_MEMORY(user_info);
412 
413 	user_info->flags = 0;
414 	user_info->mapped_state = False;
415 	user_info->remote_host = NULL;
416 
417 	switch (r->in.logon_level) {
418 	case 1:
419 	case 3:
420 	case 5:
421 		if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
422 			creds_arcfour_crypt(creds,
423 					    r->in.logon.password->lmpassword.hash,
424 					    sizeof(r->in.logon.password->lmpassword.hash));
425 			creds_arcfour_crypt(creds,
426 					    r->in.logon.password->ntpassword.hash,
427 					    sizeof(r->in.logon.password->ntpassword.hash));
428 		} else {
429 			creds_des_decrypt(creds, &r->in.logon.password->lmpassword);
430 			creds_des_decrypt(creds, &r->in.logon.password->ntpassword);
431 		}
432 
433 		/* TODO: we need to deny anonymous access here */
434 		nt_status = auth_context_create(mem_ctx, lp_auth_methods(),
435 						dce_call->event_ctx, dce_call->msg_ctx,
436 						&auth_context);
437 		NT_STATUS_NOT_OK_RETURN(nt_status);
438 
439 		user_info->logon_parameters = r->in.logon.password->identity_info.parameter_control;
440 		user_info->client.account_name = r->in.logon.password->identity_info.account_name.string;
441 		user_info->client.domain_name = r->in.logon.password->identity_info.domain_name.string;
442 		user_info->workstation_name = r->in.logon.password->identity_info.workstation.string;
443 
444 		user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
445 		user_info->password_state = AUTH_PASSWORD_HASH;
446 
447 		user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
448 		NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
449 		*user_info->password.hash.lanman = r->in.logon.password->lmpassword;
450 
451 		user_info->password.hash.nt = talloc(user_info, struct samr_Password);
452 		NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
453 		*user_info->password.hash.nt = r->in.logon.password->ntpassword;
454 
455 		break;
456 	case 2:
457 	case 6:
458 
459 		/* TODO: we need to deny anonymous access here */
460 		nt_status = auth_context_create(mem_ctx, lp_auth_methods(),
461 						dce_call->event_ctx, dce_call->msg_ctx,
462 						&auth_context);
463 		NT_STATUS_NOT_OK_RETURN(nt_status);
464 
465 		nt_status = auth_context_set_challenge(auth_context, r->in.logon.network->challenge, "netr_LogonSamLogonWithFlags");
466 		NT_STATUS_NOT_OK_RETURN(nt_status);
467 
468 		user_info->logon_parameters = r->in.logon.network->identity_info.parameter_control;
469 		user_info->client.account_name = r->in.logon.network->identity_info.account_name.string;
470 		user_info->client.domain_name = r->in.logon.network->identity_info.domain_name.string;
471 		user_info->workstation_name = r->in.logon.network->identity_info.workstation.string;
472 
473 		user_info->password_state = AUTH_PASSWORD_RESPONSE;
474 		user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length);
475 		user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length);
476 
477 		break;
478 	default:
479 		return NT_STATUS_INVALID_PARAMETER;
480 	}
481 
482 	nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
483 	NT_STATUS_NOT_OK_RETURN(nt_status);
484 
485 	nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
486 	NT_STATUS_NOT_OK_RETURN(nt_status);
487 
488 	/* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
489 	/* It appears that level 6 is not individually encrypted */
490 	if ((r->in.validation_level != 6) &&
491 	    memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
492 		/* This key is sent unencrypted without the ARCFOUR flag set */
493 		if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
494 			creds_arcfour_crypt(creds,
495 					    sam->key.key,
496 					    sizeof(sam->key.key));
497 		}
498 	}
499 
500 	/* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
501 	/* It appears that level 6 is not individually encrypted */
502 	if ((r->in.validation_level != 6) &&
503 	    memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
504 		if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
505 			creds_arcfour_crypt(creds,
506 					    sam->LMSessKey.key,
507 					    sizeof(sam->LMSessKey.key));
508 		} else {
509 			creds_des_encrypt_LMKey(creds,
510 						&sam->LMSessKey);
511 		}
512 	}
513 
514 	switch (r->in.validation_level) {
515 	case 2:
516 		sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
517 		NT_STATUS_HAVE_NO_MEMORY(sam2);
518 		sam2->base = *sam;
519 		r->out.validation.sam2 = sam2;
520 		break;
521 
522 	case 3:
523 		sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
524 		NT_STATUS_HAVE_NO_MEMORY(sam3);
525 		sam3->base = *sam;
526 		r->out.validation.sam3 = sam3;
527 		break;
528 
529 	case 6:
530 		sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
531 		NT_STATUS_HAVE_NO_MEMORY(sam6);
532 		sam6->base = *sam;
533 		sam6->forest.string = lp_realm();
534 		sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
535 							 sam->account_name.string, sam6->forest.string);
536 		NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
537 		r->out.validation.sam6 = sam6;
538 		break;
539 
540 	default:
541 		break;
542 	}
543 
544 	r->out.authoritative = 1;
545 
546 	/* TODO: Describe and deal with these flags */
547 	r->out.flags = 0;
548 
549 	return NT_STATUS_OK;
550 }
551 
netr_LogonSamLogonEx(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_LogonSamLogonEx * r)552 static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
553 				     struct netr_LogonSamLogonEx *r)
554 {
555 	NTSTATUS nt_status;
556 	struct creds_CredentialState *creds;
557 	nt_status = schannel_fetch_session_key(mem_ctx, r->in.computer_name, lp_workgroup(), &creds);
558 	if (!NT_STATUS_IS_OK(nt_status)) {
559 		return nt_status;
560 	}
561 
562 	if (!dce_call->conn->auth_state.auth_info ||
563 	    dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
564 		return NT_STATUS_INTERNAL_ERROR;
565 	}
566 	return netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
567 }
568 
569 /*
570   netr_LogonSamLogonWithFlags
571 
572 */
netr_LogonSamLogonWithFlags(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_LogonSamLogonWithFlags * r)573 static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
574 					    struct netr_LogonSamLogonWithFlags *r)
575 {
576 	NTSTATUS nt_status;
577 	struct creds_CredentialState *creds;
578 	struct netr_LogonSamLogonEx r2;
579 
580 	struct netr_Authenticator *return_authenticator;
581 
582 	return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
583 	NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
584 
585 	nt_status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
586 						 r->in.credential, return_authenticator,
587 						 &creds);
588 	NT_STATUS_NOT_OK_RETURN(nt_status);
589 
590 	ZERO_STRUCT(r2);
591 
592 	r2.in.server_name	= r->in.server_name;
593 	r2.in.computer_name	= r->in.computer_name;
594 	r2.in.logon_level	= r->in.logon_level;
595 	r2.in.logon		= r->in.logon;
596 	r2.in.validation_level	= r->in.validation_level;
597 	r2.in.flags		= r->in.flags;
598 
599 	nt_status = netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
600 
601 	r->out.return_authenticator	= return_authenticator;
602 	r->out.validation		= r2.out.validation;
603 	r->out.authoritative		= r2.out.authoritative;
604 	r->out.flags			= r2.out.flags;
605 
606 	return nt_status;
607 }
608 
609 /*
610   netr_LogonSamLogon
611 */
netr_LogonSamLogon(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_LogonSamLogon * r)612 static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
613 				   struct netr_LogonSamLogon *r)
614 {
615 	struct netr_LogonSamLogonWithFlags r2;
616 	NTSTATUS status;
617 
618 	ZERO_STRUCT(r2);
619 
620 	r2.in.server_name = r->in.server_name;
621 	r2.in.computer_name = r->in.computer_name;
622 	r2.in.credential  = r->in.credential;
623 	r2.in.return_authenticator = r->in.return_authenticator;
624 	r2.in.logon_level = r->in.logon_level;
625 	r2.in.logon = r->in.logon;
626 	r2.in.validation_level = r->in.validation_level;
627 	r2.in.flags = 0;
628 
629 	status = netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
630 
631 	r->out.return_authenticator = r2.out.return_authenticator;
632 	r->out.validation = r2.out.validation;
633 	r->out.authoritative = r2.out.authoritative;
634 
635 	return status;
636 }
637 
638 
639 /*
640   netr_LogonSamLogoff
641 */
netr_LogonSamLogoff(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_LogonSamLogoff * r)642 static NTSTATUS netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
643 		       struct netr_LogonSamLogoff *r)
644 {
645 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
646 }
647 
648 
649 
650 /*
651   netr_DatabaseDeltas
652 */
netr_DatabaseDeltas(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_DatabaseDeltas * r)653 static NTSTATUS netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
654 		       struct netr_DatabaseDeltas *r)
655 {
656 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
657 }
658 
659 
660 /*
661   netr_DatabaseSync
662 */
netr_DatabaseSync(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_DatabaseSync * r)663 static NTSTATUS netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
664 		       struct netr_DatabaseSync *r)
665 {
666 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
667 }
668 
669 
670 /*
671   netr_AccountDeltas
672 */
netr_AccountDeltas(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_AccountDeltas * r)673 static NTSTATUS netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
674 		       struct netr_AccountDeltas *r)
675 {
676 	/* w2k3 returns "NOT IMPLEMENTED" for this call */
677 	return NT_STATUS_NOT_IMPLEMENTED;
678 }
679 
680 
681 /*
682   netr_AccountSync
683 */
netr_AccountSync(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_AccountSync * r)684 static NTSTATUS netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
685 		       struct netr_AccountSync *r)
686 {
687 	/* w2k3 returns "NOT IMPLEMENTED" for this call */
688 	return NT_STATUS_NOT_IMPLEMENTED;
689 }
690 
691 
692 /*
693   netr_GetDcName
694 */
netr_GetDcName(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_GetDcName * r)695 static NTSTATUS netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
696 		       struct netr_GetDcName *r)
697 {
698 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
699 }
700 
701 
702 /*
703   netr_LogonControl
704 */
netr_LogonControl(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_LogonControl * r)705 static WERROR netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
706 		       struct netr_LogonControl *r)
707 {
708 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
709 }
710 
711 
712 /*
713   netr_GetAnyDCName
714 */
netr_GetAnyDCName(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_GetAnyDCName * r)715 static WERROR netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
716 		       struct netr_GetAnyDCName *r)
717 {
718 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
719 }
720 
721 
722 /*
723   netr_LogonControl2
724 */
netr_LogonControl2(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_LogonControl2 * r)725 static WERROR netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
726 		       struct netr_LogonControl2 *r)
727 {
728 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
729 }
730 
731 
732 /*
733   netr_DatabaseSync2
734 */
netr_DatabaseSync2(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_DatabaseSync2 * r)735 static NTSTATUS netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
736 		       struct netr_DatabaseSync2 *r)
737 {
738 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
739 }
740 
741 
742 /*
743   netr_DatabaseRedo
744 */
netr_DatabaseRedo(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_DatabaseRedo * r)745 static NTSTATUS netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
746 		       struct netr_DatabaseRedo *r)
747 {
748 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
749 }
750 
751 
752 /*
753   netr_LogonControl2Ex
754 */
netr_LogonControl2Ex(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_LogonControl2Ex * r)755 static WERROR netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
756 		       struct netr_LogonControl2Ex *r)
757 {
758 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
759 }
760 
761 
762 /*
763   netr_NETRENUMERATETRUSTEDDOMAINS
764 */
netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_NETRENUMERATETRUSTEDDOMAINS * r)765 static WERROR netr_NETRENUMERATETRUSTEDDOMAINS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
766 		       struct netr_NETRENUMERATETRUSTEDDOMAINS *r)
767 {
768 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
769 }
770 
771 
772 /*
773   netr_NETRLOGONDUMMYROUTINE1
774 */
netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_NETRLOGONDUMMYROUTINE1 * r)775 static WERROR netr_NETRLOGONDUMMYROUTINE1(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
776 		       struct netr_NETRLOGONDUMMYROUTINE1 *r)
777 {
778 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
779 }
780 
781 
782 /*
783   netr_NETRLOGONSETSERVICEBITS
784 */
netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_NETRLOGONSETSERVICEBITS * r)785 static WERROR netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
786 		       struct netr_NETRLOGONSETSERVICEBITS *r)
787 {
788 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
789 }
790 
791 
792 /*
793   netr_NETRLOGONGETTRUSTRID
794 */
netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_NETRLOGONGETTRUSTRID * r)795 static WERROR netr_NETRLOGONGETTRUSTRID(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
796 		       struct netr_NETRLOGONGETTRUSTRID *r)
797 {
798 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
799 }
800 
801 
802 /*
803   netr_NETRLOGONCOMPUTESERVERDIGEST
804 */
netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_NETRLOGONCOMPUTESERVERDIGEST * r)805 static WERROR netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
806 		       struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
807 {
808 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
809 }
810 
811 
812 /*
813   netr_NETRLOGONCOMPUTECLIENTDIGEST
814 */
netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_NETRLOGONCOMPUTECLIENTDIGEST * r)815 static WERROR netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
816 		       struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
817 {
818 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
819 }
820 
821 
822 
823 /*
824   netr_DsRGetSiteName
825 */
netr_DsRGetSiteName(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_DsRGetSiteName * r)826 static WERROR netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
827 				  struct netr_DsRGetSiteName *r)
828 {
829 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
830 }
831 
832 
833 /*
834   fill in a netr_DomainTrustInfo from a ldb search result
835 */
fill_domain_trust_info(TALLOC_CTX * mem_ctx,struct ldb_message * res,struct ldb_message * ref_res,struct netr_DomainTrustInfo * info,BOOL is_local)836 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
837 				       struct ldb_message *res,
838 				       struct ldb_message *ref_res,
839 				       struct netr_DomainTrustInfo *info,
840 				       BOOL is_local)
841 {
842 	ZERO_STRUCTP(info);
843 
844 	if (is_local) {
845 		info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
846 		info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
847 		info->forest.string = NULL;
848 		info->guid = samdb_result_guid(res, "objectGUID");
849 		info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
850 	} else {
851 		info->domainname.string = samdb_result_string(res, "flatName", NULL);
852 		info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
853 		info->forest.string = NULL;
854 		info->guid = samdb_result_guid(res, "objectGUID");
855 		info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
856 	}
857 
858 	return NT_STATUS_OK;
859 }
860 
861 /*
862   netr_LogonGetDomainInfo
863   this is called as part of the ADS domain logon procedure.
864 */
netr_LogonGetDomainInfo(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_LogonGetDomainInfo * r)865 static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
866 					struct netr_LogonGetDomainInfo *r)
867 {
868 	const char * const attrs[] = { "objectSid",
869 				       "objectGUID", "flatName", "securityIdentifier",
870 				       "trustPartner", NULL };
871 	const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
872 	struct ldb_context *sam_ctx;
873 	struct ldb_message **res1, **res2, **ref_res;
874 	struct netr_DomainInfo1 *info1;
875 	int ret, ret1, ret2, i;
876 	NTSTATUS status;
877 	struct ldb_dn *partitions_basedn;
878 
879 	const char *local_domain;
880 
881 	status = netr_creds_server_step_check(r->in.computer_name, mem_ctx,
882 					      r->in.credential,
883 					      r->out.return_authenticator,
884 					      NULL);
885 	NT_STATUS_NOT_OK_RETURN(status);
886 
887 	sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
888 	if (sam_ctx == NULL) {
889 		return NT_STATUS_INVALID_SYSTEM_SERVICE;
890 	}
891 
892 	partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
893 
894 	/* we need to do two searches. The first will pull our primary
895 	   domain and the second will pull any trusted domains. Our
896 	   primary domain is also a "trusted" domain, so we need to
897 	   put the primary domain into the lists of returned trusts as
898 	   well */
899 	ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
900 	if (ret1 != 1) {
901 		return NT_STATUS_INTERNAL_DB_CORRUPTION;
902 	}
903 
904 	/* try and find the domain */
905 	ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
906 			   &ref_res, ref_attrs,
907 			   "(&(objectClass=crossRef)(ncName=%s))",
908 			   ldb_dn_get_linearized(res1[0]->dn));
909 	if (ret != 1) {
910 		return NT_STATUS_INTERNAL_DB_CORRUPTION;
911 	}
912 
913 	local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
914 
915 	ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
916 	if (ret2 == -1) {
917 		return NT_STATUS_INTERNAL_DB_CORRUPTION;
918 	}
919 
920 	info1 = talloc(mem_ctx, struct netr_DomainInfo1);
921 	NT_STATUS_HAVE_NO_MEMORY(info1);
922 
923 	ZERO_STRUCTP(info1);
924 
925 	info1->num_trusts = ret2 + 1;
926 	info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
927 				       info1->num_trusts);
928 	NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
929 
930 	status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo, True);
931 	NT_STATUS_NOT_OK_RETURN(status);
932 
933 	for (i=0;i<ret2;i++) {
934 		status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i], False);
935 		NT_STATUS_NOT_OK_RETURN(status);
936 	}
937 
938 	status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i], True);
939 	NT_STATUS_NOT_OK_RETURN(status);
940 
941 	r->out.info.info1 = info1;
942 
943 	return NT_STATUS_OK;
944 }
945 
946 
947 
948 /*
949   netr_NETRSERVERPASSWORDGET
950 */
netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_NETRSERVERPASSWORDGET * r)951 static WERROR netr_NETRSERVERPASSWORDGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
952 		       struct netr_NETRSERVERPASSWORDGET *r)
953 {
954 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
955 }
956 
957 
958 /*
959   netr_NETRLOGONSENDTOSAM
960 */
netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_NETRLOGONSENDTOSAM * r)961 static WERROR netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
962 		       struct netr_NETRLOGONSENDTOSAM *r)
963 {
964 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
965 }
966 
967 
968 /*
969   netr_DSRADDRESSTOSITENAMESW
970 */
netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_DSRADDRESSTOSITENAMESW * r)971 static WERROR netr_DSRADDRESSTOSITENAMESW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
972 		       struct netr_DSRADDRESSTOSITENAMESW *r)
973 {
974 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
975 }
976 
977 
978 /*
979   netr_DsRGetDCNameEx2
980 */
netr_DsRGetDCNameEx2(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_DsRGetDCNameEx2 * r)981 static WERROR netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
982 				   struct netr_DsRGetDCNameEx2 *r)
983 {
984 	const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
985 	void *sam_ctx;
986 	struct ldb_message **res;
987 	int ret;
988 
989 	ZERO_STRUCT(r->out);
990 
991 	sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
992 	if (sam_ctx == NULL) {
993 		return WERR_DS_SERVICE_UNAVAILABLE;
994 	}
995 
996 	ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
997 				"(&(objectClass=domainDNS)(dnsDomain=%s))",
998 				r->in.domain_name);
999 	if (ret != 1) {
1000 		return WERR_NO_SUCH_DOMAIN;
1001 	}
1002 
1003 	r->out.info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1004 	W_ERROR_HAVE_NO_MEMORY(r->out.info);
1005 
1006 	/* TODO: - return real IP address
1007 	 *       - check all r->in.* parameters (server_unc is ignored by w2k3!)
1008 	 */
1009 	r->out.info->dc_unc		= talloc_asprintf(mem_ctx, "\\\\%s.%s", lp_netbios_name(),lp_realm());
1010 	W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_unc);
1011 	r->out.info->dc_address		= talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1012 	W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_address);
1013 	r->out.info->dc_address_type	= 1;
1014 	r->out.info->domain_guid	= samdb_result_guid(res[0], "objectGUID");
1015 	r->out.info->domain_name	= samdb_result_string(res[0], "dnsDomain", NULL);
1016 	r->out.info->forest_name	= samdb_result_string(res[0], "dnsDomain", NULL);
1017 	r->out.info->dc_flags		= 0xE00001FD;
1018 	r->out.info->dc_site_name	= talloc_strdup(mem_ctx, "Default-First-Site-Name");
1019 	W_ERROR_HAVE_NO_MEMORY(r->out.info->dc_site_name);
1020 	r->out.info->client_site_name	= talloc_strdup(mem_ctx, "Default-First-Site-Name");
1021 	W_ERROR_HAVE_NO_MEMORY(r->out.info->client_site_name);
1022 
1023 	return WERR_OK;
1024 }
1025 
1026 /*
1027   netr_DsRGetDCNameEx
1028 */
netr_DsRGetDCNameEx(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_DsRGetDCNameEx * r)1029 static WERROR netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1030 				  struct netr_DsRGetDCNameEx *r)
1031 {
1032 	struct netr_DsRGetDCNameEx2 r2;
1033 	WERROR werr;
1034 
1035 	ZERO_STRUCT(r2);
1036 
1037 	r2.in.server_unc = r->in.server_unc;
1038 	r2.in.client_account = NULL;
1039 	r2.in.mask = 0;
1040 	r2.in.domain_guid = r->in.domain_guid;
1041 	r2.in.domain_name = r->in.domain_name;
1042 	r2.in.site_name = r->in.site_name;
1043 	r2.in.flags = r->in.flags;
1044 	r2.out.info = NULL;
1045 
1046 	werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1047 
1048 	r->out.info = r2.out.info;
1049 
1050 	return werr;
1051 }
1052 
1053 /*
1054   netr_DsRGetDCName
1055 */
netr_DsRGetDCName(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_DsRGetDCName * r)1056 static WERROR netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1057 				struct netr_DsRGetDCName *r)
1058 {
1059 	struct netr_DsRGetDCNameEx2 r2;
1060 	WERROR werr;
1061 
1062 	ZERO_STRUCT(r2);
1063 
1064 	r2.in.server_unc = r->in.server_unc;
1065 	r2.in.client_account = NULL;
1066 	r2.in.mask = 0;
1067 	r2.in.domain_name = r->in.domain_name;
1068 	r2.in.domain_guid = r->in.domain_guid;
1069 
1070 	r2.in.site_name = NULL; /* should fill in from site GUID */
1071 	r2.in.flags = r->in.flags;
1072 	r2.out.info = NULL;
1073 
1074 	werr = netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1075 
1076 	r->out.info = r2.out.info;
1077 
1078 	return werr;
1079 }
1080 
1081 /*
1082   netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1083 */
netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN * r)1084 static WERROR netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1085 		       struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1086 {
1087 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1088 }
1089 
1090 
1091 /*
1092   netr_NETRENUMERATETRUSTEDDOMAINSEX
1093 */
netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_NETRENUMERATETRUSTEDDOMAINSEX * r)1094 static WERROR netr_NETRENUMERATETRUSTEDDOMAINSEX(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1095 		       struct netr_NETRENUMERATETRUSTEDDOMAINSEX *r)
1096 {
1097 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1098 }
1099 
1100 
1101 /*
1102   netr_DSRADDRESSTOSITENAMESEXW
1103 */
netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_DSRADDRESSTOSITENAMESEXW * r)1104 static WERROR netr_DSRADDRESSTOSITENAMESEXW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1105 		       struct netr_DSRADDRESSTOSITENAMESEXW *r)
1106 {
1107 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1108 }
1109 
1110 
1111 /*
1112   netr_DSRGETDCSITECOVERAGEW
1113 */
netr_DSRGETDCSITECOVERAGEW(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_DSRGETDCSITECOVERAGEW * r)1114 static WERROR netr_DSRGETDCSITECOVERAGEW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1115 		       struct netr_DSRGETDCSITECOVERAGEW *r)
1116 {
1117 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1118 }
1119 
1120 
1121 /*
1122   netr_DsrEnumerateDomainTrusts
1123 */
netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_DsrEnumerateDomainTrusts * r)1124 static WERROR netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1125 					      struct netr_DsrEnumerateDomainTrusts *r)
1126 {
1127 	struct netr_DomainTrust *trusts;
1128 	void *sam_ctx;
1129 	int ret;
1130 	struct ldb_message **dom_res, **ref_res;
1131 	const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1132 	const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1133 	struct ldb_dn *partitions_basedn;
1134 
1135 	ZERO_STRUCT(r->out);
1136 
1137 	sam_ctx = samdb_connect(mem_ctx, dce_call->conn->auth_state.session_info);
1138 	if (sam_ctx == NULL) {
1139 		return WERR_GENERAL_FAILURE;
1140 	}
1141 
1142 	partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1143 
1144 	ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs);
1145 	if (ret == -1) {
1146 		return WERR_GENERAL_FAILURE;
1147 	}
1148 	if (ret != 1) {
1149 		return WERR_GENERAL_FAILURE;
1150 	}
1151 
1152 	ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs,
1153 			   "(&(objectClass=crossRef)(ncName=%s))",
1154 			   ldb_dn_get_linearized(dom_res[0]->dn));
1155 	if (ret == -1) {
1156 		return WERR_GENERAL_FAILURE;
1157 	}
1158 	if (ret != 1) {
1159 		return WERR_GENERAL_FAILURE;
1160 	}
1161 
1162 	trusts = talloc_array(mem_ctx, struct netr_DomainTrust, ret);
1163 	W_ERROR_HAVE_NO_MEMORY(trusts);
1164 
1165 	r->out.count = 1;
1166 	r->out.trusts = trusts;
1167 
1168 	/* TODO: add filtering by trust_flags, and correct trust_type
1169 	   and attributes */
1170 	trusts[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1171 	trusts[0].dns_name     = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1172 	trusts[0].trust_flags =
1173 		NETR_TRUST_FLAG_TREEROOT |
1174 		NETR_TRUST_FLAG_IN_FOREST |
1175 		NETR_TRUST_FLAG_PRIMARY;
1176 	trusts[0].parent_index = 0;
1177 	trusts[0].trust_type = 2;
1178 	trusts[0].trust_attributes = 0;
1179 	trusts[0].sid  = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1180 	trusts[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1181 
1182 	return WERR_OK;
1183 }
1184 
1185 
1186 /*
1187   netr_DSRDEREGISTERDNSHOSTRECORDS
1188 */
netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_DSRDEREGISTERDNSHOSTRECORDS * r)1189 static WERROR netr_DSRDEREGISTERDNSHOSTRECORDS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1190 		       struct netr_DSRDEREGISTERDNSHOSTRECORDS *r)
1191 {
1192 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1193 }
1194 
1195 
1196 /*
1197   netr_NETRSERVERTRUSTPASSWORDSGET
1198 */
netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_NETRSERVERTRUSTPASSWORDSGET * r)1199 static WERROR netr_NETRSERVERTRUSTPASSWORDSGET(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1200 		       struct netr_NETRSERVERTRUSTPASSWORDSGET *r)
1201 {
1202 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1203 }
1204 
1205 
1206 /*
1207   netr_DSRGETFORESTTRUSTINFORMATION
1208 */
netr_DSRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_DSRGETFORESTTRUSTINFORMATION * r)1209 static WERROR netr_DSRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1210 		       struct netr_DSRGETFORESTTRUSTINFORMATION *r)
1211 {
1212 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1213 }
1214 
1215 
1216 /*
1217   netr_NETRGETFORESTTRUSTINFORMATION
1218 */
netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_NETRGETFORESTTRUSTINFORMATION * r)1219 static WERROR netr_NETRGETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1220 		       struct netr_NETRGETFORESTTRUSTINFORMATION *r)
1221 {
1222 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1223 }
1224 
1225 
1226 /*
1227   netr_NETRSERVERGETTRUSTINFO
1228 */
netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct netr_NETRSERVERGETTRUSTINFO * r)1229 static WERROR netr_NETRSERVERGETTRUSTINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1230 		       struct netr_NETRSERVERGETTRUSTINFO *r)
1231 {
1232 	DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1233 }
1234 
1235 
1236 /* include the generated boilerplate */
1237 #include "librpc/gen_ndr/ndr_netlogon_s.c"
1238