/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- dcesrv_netr_ServerReqChallenge
- dcesrv_netr_ServerAuthenticate3
- dcesrv_netr_ServerAuthenticate
- dcesrv_netr_ServerAuthenticate2
- dcesrv_netr_creds_server_step_check
- dcesrv_netr_ServerPasswordSet
- dcesrv_netr_ServerPasswordSet2
- dcesrv_netr_LogonUasLogon
- dcesrv_netr_LogonUasLogoff
- dcesrv_netr_LogonSamLogon_base
- dcesrv_netr_LogonSamLogonEx
- dcesrv_netr_LogonSamLogonWithFlags
- dcesrv_netr_LogonSamLogon
- dcesrv_netr_LogonSamLogoff
- dcesrv_netr_DatabaseDeltas
- dcesrv_netr_DatabaseSync
- dcesrv_netr_AccountDeltas
- dcesrv_netr_AccountSync
- dcesrv_netr_GetDcName
- dcesrv_netr_LogonControl
- dcesrv_netr_GetAnyDCName
- dcesrv_netr_LogonControl2
- dcesrv_netr_DatabaseSync2
- dcesrv_netr_DatabaseRedo
- dcesrv_netr_LogonControl2Ex
- dcesrv_netr_NetrEnumerateTrustedDomains
- dcesrv_netr_LogonGetCapabilities
- dcesrv_netr_NETRLOGONSETSERVICEBITS
- dcesrv_netr_LogonGetTrustRid
- dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST
- dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST
- dcesrv_netr_DsRGetSiteName
- fill_domain_trust_info
- dcesrv_netr_LogonGetDomainInfo
- dcesrv_netr_ServerPasswordGet
- dcesrv_netr_NETRLOGONSENDTOSAM
- dcesrv_netr_DsRAddressToSitenamesW
- dcesrv_netr_DsRGetDCNameEx2
- dcesrv_netr_DsRGetDCNameEx
- dcesrv_netr_DsRGetDCName
- dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
- dcesrv_netr_NetrEnumerateTrustedDomainsEx
- dcesrv_netr_DsRAddressToSitenamesExW
- dcesrv_netr_DsrGetDcSiteCoverageW
- dcesrv_netr_DsrEnumerateDomainTrusts
- dcesrv_netr_DsrDeregisterDNSHostRecords
- dcesrv_netr_ServerTrustPasswordsGet
- dcesrv_netr_DsRGetForestTrustInformation
- dcesrv_netr_GetForestTrustInformation
- dcesrv_netr_ServerGetTrustInfo
1 /*
2 Unix SMB/CIFS implementation.
3
4 endpoint server for the netlogon pipe
5
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
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 3 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, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "includes.h"
24 #include "rpc_server/dcerpc_server.h"
25 #include "rpc_server/common/common.h"
26 #include "lib/ldb/include/ldb.h"
27 #include "auth/auth.h"
28 #include "auth/auth_sam_reply.h"
29 #include "dsdb/samdb/samdb.h"
30 #include "dsdb/common/flags.h"
31 #include "rpc_server/samr/proto.h"
32 #include "../lib/util/util_ldb.h"
33 #include "libcli/auth/libcli_auth.h"
34 #include "auth/gensec/schannel_state.h"
35 #include "libcli/security/security.h"
36 #include "param/param.h"
37 #include "lib/messaging/irpc.h"
38 #include "librpc/gen_ndr/ndr_irpc.h"
39 #include "librpc/gen_ndr/ndr_netlogon.h"
40
41 struct server_pipe_state {
42 struct netr_Credential client_challenge;
43 struct netr_Credential server_challenge;
44 };
45
46
47 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
48 struct netr_ServerReqChallenge *r)
49 {
50 struct server_pipe_state *pipe_state =
51 (struct server_pipe_state *)dce_call->context->private_data;
52
53 ZERO_STRUCTP(r->out.return_credentials);
54
55 /* destroyed on pipe shutdown */
56
57 if (pipe_state) {
58 talloc_free(pipe_state);
59 dce_call->context->private_data = NULL;
60 }
61
62 pipe_state = talloc(dce_call->context, struct server_pipe_state);
63 NT_STATUS_HAVE_NO_MEMORY(pipe_state);
64
65 pipe_state->client_challenge = *r->in.credentials;
66
67 generate_random_buffer(pipe_state->server_challenge.data,
68 sizeof(pipe_state->server_challenge.data));
69
70 *r->out.return_credentials = pipe_state->server_challenge;
71
72 dce_call->context->private_data = pipe_state;
73
74 return NT_STATUS_OK;
75 }
76
77 static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
78 struct netr_ServerAuthenticate3 *r)
79 {
80 struct server_pipe_state *pipe_state =
81 (struct server_pipe_state *)dce_call->context->private_data;
82 struct creds_CredentialState *creds;
83 void *sam_ctx;
84 struct samr_Password *mach_pwd;
85 uint32_t user_account_control;
86 int num_records;
87 struct ldb_message **msgs;
88 NTSTATUS nt_status;
89 const char *attrs[] = {"unicodePwd", "userAccountControl",
90 "objectSid", NULL};
91
92 const char *trust_dom_attrs[] = {"flatname", NULL};
93 const char *account_name;
94
95 ZERO_STRUCTP(r->out.return_credentials);
96 *r->out.rid = 0;
97
98 /*
99 * According to Microsoft (see bugid #6099)
100 * Windows 7 looks at the negotiate_flags
101 * returned in this structure *even if the
102 * call fails with access denied!
103 */
104 *r->out.negotiate_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT |
105 NETLOGON_NEG_PERSISTENT_SAMREPL |
106 NETLOGON_NEG_ARCFOUR |
107 NETLOGON_NEG_PROMOTION_COUNT |
108 NETLOGON_NEG_CHANGELOG_BDC |
109 NETLOGON_NEG_FULL_SYNC_REPL |
110 NETLOGON_NEG_MULTIPLE_SIDS |
111 NETLOGON_NEG_REDO |
112 NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
113 NETLOGON_NEG_SEND_PASSWORD_INFO_PDC |
114 NETLOGON_NEG_GENERIC_PASSTHROUGH |
115 NETLOGON_NEG_CONCURRENT_RPC |
116 NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL |
117 NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL |
118 NETLOGON_NEG_STRONG_KEYS |
119 NETLOGON_NEG_TRANSITIVE_TRUSTS |
120 NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
121 NETLOGON_NEG_PASSWORD_SET2 |
122 NETLOGON_NEG_GETDOMAININFO |
123 NETLOGON_NEG_CROSS_FOREST_TRUSTS |
124 NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION |
125 NETLOGON_NEG_RODC_PASSTHROUGH |
126 NETLOGON_NEG_AUTHENTICATED_RPC_LSASS |
127 NETLOGON_NEG_AUTHENTICATED_RPC;
128
129 if (!pipe_state) {
130 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
131 return NT_STATUS_ACCESS_DENIED;
132 }
133
134 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
135 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
136 if (sam_ctx == NULL) {
137 return NT_STATUS_INVALID_SYSTEM_SERVICE;
138 }
139
140 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
141 char *encoded_account = ldb_binary_encode_string(mem_ctx, r->in.account_name);
142 const char *flatname;
143 if (!encoded_account) {
144 return NT_STATUS_NO_MEMORY;
145 }
146
147 /* Kill the trailing dot */
148 if (encoded_account[strlen(encoded_account)-1] == '.') {
149 encoded_account[strlen(encoded_account)-1] = '\0';
150 }
151
152 /* pull the user attributes */
153 num_records = gendb_search((struct ldb_context *)sam_ctx,
154 mem_ctx, NULL, &msgs,
155 trust_dom_attrs,
156 "(&(trustPartner=%s)(objectclass=trustedDomain))",
157 encoded_account);
158
159 if (num_records == 0) {
160 DEBUG(3,("Couldn't find trust [%s] in samdb.\n",
161 encoded_account));
162 return NT_STATUS_ACCESS_DENIED;
163 }
164
165 if (num_records > 1) {
166 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
167 return NT_STATUS_INTERNAL_DB_CORRUPTION;
168 }
169
170 flatname = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL);
171 if (!flatname) {
172 /* No flatname for this trust - we can't proceed */
173 return NT_STATUS_ACCESS_DENIED;
174 }
175 account_name = talloc_asprintf(mem_ctx, "%s$", flatname);
176
177 if (!account_name) {
178 return NT_STATUS_NO_MEMORY;
179 }
180
181 } else {
182 account_name = r->in.account_name;
183 }
184
185 /* pull the user attributes */
186 num_records = gendb_search((struct ldb_context *)sam_ctx, mem_ctx,
187 NULL, &msgs, attrs,
188 "(&(sAMAccountName=%s)(objectclass=user))",
189 ldb_binary_encode_string(mem_ctx, account_name));
190
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;
195 }
196
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;
200 }
201
202
203 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
204
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;
208 }
209
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;
214 }
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));
219
220 return NT_STATUS_ACCESS_DENIED;
221 }
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;
226 }
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;
231 }
232
233 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
234 "objectSid", 0);
235
236 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd");
237 if (mach_pwd == NULL) {
238 return NT_STATUS_ACCESS_DENIED;
239 }
240
241 creds = talloc(mem_ctx, struct creds_CredentialState);
242 NT_STATUS_HAVE_NO_MEMORY(creds);
243
244 creds_server_init(creds, &pipe_state->client_challenge,
245 &pipe_state->server_challenge, mach_pwd,
246 r->out.return_credentials,
247 *r->in.negotiate_flags);
248
249 if (!creds_server_check(creds, r->in.credentials)) {
250 talloc_free(creds);
251 return NT_STATUS_ACCESS_DENIED;
252 }
253
254 creds->account_name = talloc_steal(creds, r->in.account_name);
255
256 creds->computer_name = talloc_steal(creds, r->in.computer_name);
257 creds->domain = talloc_strdup(creds, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx));
258
259 creds->secure_channel_type = r->in.secure_channel_type;
260
261 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
262
263
264 /* remember this session key state */
265 nt_status = schannel_store_session_key(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, creds);
266
267 return nt_status;
268 }
269
270 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
271 struct netr_ServerAuthenticate *r)
272 {
273 struct netr_ServerAuthenticate3 r3;
274 uint32_t rid = 0;
275 /* TODO:
276 * negotiate_flags is used as an [in] parameter
277 * so it need to be initialised.
278 *
279 * (I think ... = 0; seems wrong here --metze)
280 */
281 uint32_t negotiate_flags_in = 0;
282 uint32_t negotiate_flags_out = 0;
283
284 r3.in.server_name = r->in.server_name;
285 r3.in.account_name = r->in.account_name;
286 r3.in.secure_channel_type = r->in.secure_channel_type;
287 r3.in.computer_name = r->in.computer_name;
288 r3.in.credentials = r->in.credentials;
289 r3.out.return_credentials = r->out.return_credentials;
290 r3.in.negotiate_flags = &negotiate_flags_in;
291 r3.out.negotiate_flags = &negotiate_flags_out;
292 r3.out.rid = &rid;
293
294 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
295 }
296
297 static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
298 struct netr_ServerAuthenticate2 *r)
299 {
300 struct netr_ServerAuthenticate3 r3;
301 uint32_t rid = 0;
302
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;
312
313 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
314 }
315
316 /*
317 Validate an incoming authenticator against the credentials for the remote machine.
318
319 The credentials are (re)read and from the schannel database, and
320 written back after the caclulations are performed.
321
322 The creds_out parameter (if not NULL) returns the credentials, if
323 the caller needs some of that information.
324
325 */
326 static NTSTATUS dcesrv_netr_creds_server_step_check(struct tevent_context *event_ctx,
/* [<][>][^][v][top][bottom][index][help] */
327 struct loadparm_context *lp_ctx,
328 const char *computer_name,
329 TALLOC_CTX *mem_ctx,
330 struct netr_Authenticator *received_authenticator,
331 struct netr_Authenticator *return_authenticator,
332 struct creds_CredentialState **creds_out)
333 {
334 struct creds_CredentialState *creds;
335 NTSTATUS nt_status;
336 struct ldb_context *ldb;
337 int ret;
338
339 ldb = schannel_db_connect(mem_ctx, event_ctx, lp_ctx);
340 if (!ldb) {
341 return NT_STATUS_ACCESS_DENIED;
342 }
343
344 ret = ldb_transaction_start(ldb);
345 if (ret != 0) {
346 talloc_free(ldb);
347 return NT_STATUS_INTERNAL_DB_CORRUPTION;
348 }
349
350 /* Because this is a shared structure (even across
351 * disconnects) we must update the database every time we
352 * update the structure */
353
354 nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name,
355 lp_workgroup(lp_ctx),
356 &creds);
357 if (NT_STATUS_IS_OK(nt_status)) {
358 nt_status = creds_server_step_check(creds,
359 received_authenticator,
360 return_authenticator);
361 }
362 if (NT_STATUS_IS_OK(nt_status)) {
363 nt_status = schannel_store_session_key_ldb(ldb, ldb, creds);
364 }
365
366 if (NT_STATUS_IS_OK(nt_status)) {
367 ldb_transaction_commit(ldb);
368 if (creds_out) {
369 *creds_out = creds;
370 talloc_steal(mem_ctx, creds);
371 }
372 } else {
373 ldb_transaction_cancel(ldb);
374 }
375 talloc_free(ldb);
376 return nt_status;
377 }
378
379 /*
380 Change the machine account password for the currently connected
381 client. Supplies only the NT#.
382 */
383
384 static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
385 struct netr_ServerPasswordSet *r)
386 {
387 struct creds_CredentialState *creds;
388 struct ldb_context *sam_ctx;
389 NTSTATUS nt_status;
390
391 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
392 r->in.computer_name, mem_ctx,
393 r->in.credential, r->out.return_authenticator,
394 &creds);
395 NT_STATUS_NOT_OK_RETURN(nt_status);
396
397 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));
398 if (sam_ctx == NULL) {
399 return NT_STATUS_INVALID_SYSTEM_SERVICE;
400 }
401
402 creds_des_decrypt(creds, r->in.new_password);
403
404 /* Using the sid for the account as the key, set the password */
405 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
406 creds->sid,
407 NULL, /* Don't have plaintext */
408 NULL, r->in.new_password,
409 true, /* Password change */
410 NULL, NULL);
411 return nt_status;
412 }
413
414 /*
415 Change the machine account password for the currently connected
416 client. Supplies new plaintext.
417 */
418 static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
419 struct netr_ServerPasswordSet2 *r)
420 {
421 struct creds_CredentialState *creds;
422 struct ldb_context *sam_ctx;
423 NTSTATUS nt_status;
424 DATA_BLOB new_password;
425
426 struct samr_CryptPassword password_buf;
427
428 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
429 r->in.computer_name, mem_ctx,
430 r->in.credential, r->out.return_authenticator,
431 &creds);
432 NT_STATUS_NOT_OK_RETURN(nt_status);
433
434 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));
435 if (sam_ctx == NULL) {
436 return NT_STATUS_INVALID_SYSTEM_SERVICE;
437 }
438
439 memcpy(password_buf.data, r->in.new_password->data, 512);
440 SIVAL(password_buf.data, 512, r->in.new_password->length);
441 creds_arcfour_crypt(creds, password_buf.data, 516);
442
443 if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
444 DEBUG(3,("samr: failed to decode password buffer\n"));
445 return NT_STATUS_WRONG_PASSWORD;
446 }
447
448 /* Using the sid for the account as the key, set the password */
449 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
450 creds->sid,
451 &new_password, /* we have plaintext */
452 NULL, NULL,
453 true, /* Password change */
454 NULL, NULL);
455 return nt_status;
456 }
457
458
459 /*
460 netr_LogonUasLogon
461 */
462 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
463 struct netr_LogonUasLogon *r)
464 {
465 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
466 }
467
468
469 /*
470 netr_LogonUasLogoff
471 */
472 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
473 struct netr_LogonUasLogoff *r)
474 {
475 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
476 }
477
478
479 /*
480 netr_LogonSamLogon_base
481
482 This version of the function allows other wrappers to say 'do not check the credentials'
483
484 We can't do the traditional 'wrapping' format completly, as this function must only run under schannel
485 */
486 static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
487 struct netr_LogonSamLogonEx *r, struct creds_CredentialState *creds)
488 {
489 struct auth_context *auth_context;
490 struct auth_usersupplied_info *user_info;
491 struct auth_serversupplied_info *server_info;
492 NTSTATUS nt_status;
493 static const char zeros[16];
494 struct netr_SamBaseInfo *sam;
495 struct netr_SamInfo2 *sam2;
496 struct netr_SamInfo3 *sam3;
497 struct netr_SamInfo6 *sam6;
498
499 user_info = talloc(mem_ctx, struct auth_usersupplied_info);
500 NT_STATUS_HAVE_NO_MEMORY(user_info);
501
502 user_info->flags = 0;
503 user_info->mapped_state = false;
504 user_info->remote_host = NULL;
505
506 switch (r->in.logon_level) {
507 case NetlogonInteractiveInformation:
508 case NetlogonServiceInformation:
509 case NetlogonInteractiveTransitiveInformation:
510 case NetlogonServiceTransitiveInformation:
511 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
512 creds_arcfour_crypt(creds,
513 r->in.logon->password->lmpassword.hash,
514 sizeof(r->in.logon->password->lmpassword.hash));
515 creds_arcfour_crypt(creds,
516 r->in.logon->password->ntpassword.hash,
517 sizeof(r->in.logon->password->ntpassword.hash));
518 } else {
519 creds_des_decrypt(creds, &r->in.logon->password->lmpassword);
520 creds_des_decrypt(creds, &r->in.logon->password->ntpassword);
521 }
522
523 /* TODO: we need to deny anonymous access here */
524 nt_status = auth_context_create(mem_ctx,
525 dce_call->event_ctx, dce_call->msg_ctx,
526 dce_call->conn->dce_ctx->lp_ctx,
527 &auth_context);
528 NT_STATUS_NOT_OK_RETURN(nt_status);
529
530 user_info->logon_parameters = r->in.logon->password->identity_info.parameter_control;
531 user_info->client.account_name = r->in.logon->password->identity_info.account_name.string;
532 user_info->client.domain_name = r->in.logon->password->identity_info.domain_name.string;
533 user_info->workstation_name = r->in.logon->password->identity_info.workstation.string;
534
535 user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
536 user_info->password_state = AUTH_PASSWORD_HASH;
537
538 user_info->password.hash.lanman = talloc(user_info, struct samr_Password);
539 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.lanman);
540 *user_info->password.hash.lanman = r->in.logon->password->lmpassword;
541
542 user_info->password.hash.nt = talloc(user_info, struct samr_Password);
543 NT_STATUS_HAVE_NO_MEMORY(user_info->password.hash.nt);
544 *user_info->password.hash.nt = r->in.logon->password->ntpassword;
545
546 break;
547 case NetlogonNetworkInformation:
548 case NetlogonNetworkTransitiveInformation:
549
550 /* TODO: we need to deny anonymous access here */
551 nt_status = auth_context_create(mem_ctx,
552 dce_call->event_ctx, dce_call->msg_ctx,
553 dce_call->conn->dce_ctx->lp_ctx,
554 &auth_context);
555 NT_STATUS_NOT_OK_RETURN(nt_status);
556
557 nt_status = auth_context_set_challenge(auth_context, r->in.logon->network->challenge, "netr_LogonSamLogonWithFlags");
558 NT_STATUS_NOT_OK_RETURN(nt_status);
559
560 user_info->logon_parameters = r->in.logon->network->identity_info.parameter_control;
561 user_info->client.account_name = r->in.logon->network->identity_info.account_name.string;
562 user_info->client.domain_name = r->in.logon->network->identity_info.domain_name.string;
563 user_info->workstation_name = r->in.logon->network->identity_info.workstation.string;
564
565 user_info->password_state = AUTH_PASSWORD_RESPONSE;
566 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length);
567 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length);
568
569 break;
570
571
572 case NetlogonGenericInformation:
573 {
574 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
575 creds_arcfour_crypt(creds,
576 r->in.logon->generic->data, r->in.logon->generic->length);
577 } else {
578 /* Using DES to verify kerberos tickets makes no sense */
579 return NT_STATUS_INVALID_PARAMETER;
580 }
581
582 if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) {
583 NTSTATUS status;
584 struct server_id *kdc;
585 struct kdc_check_generic_kerberos check;
586 struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
587 NT_STATUS_HAVE_NO_MEMORY(generic);
588 *r->out.authoritative = 1;
589
590 /* TODO: Describe and deal with these flags */
591 *r->out.flags = 0;
592
593 r->out.validation->generic = generic;
594
595 kdc = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "kdc_server");
596 if ((kdc == NULL) || (kdc[0].id == 0)) {
597 return NT_STATUS_NO_LOGON_SERVERS;
598 }
599
600 check.in.generic_request =
601 data_blob_const(r->in.logon->generic->data,
602 r->in.logon->generic->length);
603
604 status = irpc_call(dce_call->msg_ctx, kdc[0],
605 &ndr_table_irpc, NDR_KDC_CHECK_GENERIC_KERBEROS,
606 &check, mem_ctx);
607 if (!NT_STATUS_IS_OK(status)) {
608 return status;
609 }
610 generic->length = check.out.generic_reply.length;
611 generic->data = check.out.generic_reply.data;
612 return NT_STATUS_OK;
613 }
614
615 /* Until we get an implemetnation of these other packages */
616 return NT_STATUS_INVALID_PARAMETER;
617 }
618 default:
619 return NT_STATUS_INVALID_PARAMETER;
620 }
621
622 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
623 NT_STATUS_NOT_OK_RETURN(nt_status);
624
625 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
626 NT_STATUS_NOT_OK_RETURN(nt_status);
627
628 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
629 /* It appears that level 6 is not individually encrypted */
630 if ((r->in.validation_level != 6) &&
631 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) {
632 /* This key is sent unencrypted without the ARCFOUR flag set */
633 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
634 creds_arcfour_crypt(creds,
635 sam->key.key,
636 sizeof(sam->key.key));
637 }
638 }
639
640 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
641 /* It appears that level 6 is not individually encrypted */
642 if ((r->in.validation_level != 6) &&
643 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
644 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
645 creds_arcfour_crypt(creds,
646 sam->LMSessKey.key,
647 sizeof(sam->LMSessKey.key));
648 } else {
649 creds_des_encrypt_LMKey(creds,
650 &sam->LMSessKey);
651 }
652 }
653
654 switch (r->in.validation_level) {
655 case 2:
656 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
657 NT_STATUS_HAVE_NO_MEMORY(sam2);
658 sam2->base = *sam;
659 r->out.validation->sam2 = sam2;
660 break;
661
662 case 3:
663 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
664 NT_STATUS_HAVE_NO_MEMORY(sam3);
665 sam3->base = *sam;
666 r->out.validation->sam3 = sam3;
667 break;
668
669 case 6:
670 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
671 NT_STATUS_HAVE_NO_MEMORY(sam6);
672 sam6->base = *sam;
673 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
674 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
675 sam->account_name.string, sam6->forest.string);
676 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
677 r->out.validation->sam6 = sam6;
678 break;
679
680 default:
681 break;
682 }
683
684 *r->out.authoritative = 1;
685
686 /* TODO: Describe and deal with these flags */
687 *r->out.flags = 0;
688
689 return NT_STATUS_OK;
690 }
691
692 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
693 struct netr_LogonSamLogonEx *r)
694 {
695 NTSTATUS nt_status;
696 struct creds_CredentialState *creds;
697 nt_status = schannel_fetch_session_key(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, r->in.computer_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx), &creds);
698 if (!NT_STATUS_IS_OK(nt_status)) {
699 return nt_status;
700 }
701
702 if (!dce_call->conn->auth_state.auth_info ||
703 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
704 return NT_STATUS_INTERNAL_ERROR;
705 }
706 return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
707 }
708
709 /*
710 netr_LogonSamLogonWithFlags
711
712 */
713 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
714 struct netr_LogonSamLogonWithFlags *r)
715 {
716 NTSTATUS nt_status;
717 struct creds_CredentialState *creds;
718 struct netr_LogonSamLogonEx r2;
719
720 struct netr_Authenticator *return_authenticator;
721
722 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
723 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
724
725 nt_status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
726 r->in.computer_name, mem_ctx,
727 r->in.credential, return_authenticator,
728 &creds);
729 NT_STATUS_NOT_OK_RETURN(nt_status);
730
731 ZERO_STRUCT(r2);
732
733 r2.in.server_name = r->in.server_name;
734 r2.in.computer_name = r->in.computer_name;
735 r2.in.logon_level = r->in.logon_level;
736 r2.in.logon = r->in.logon;
737 r2.in.validation_level = r->in.validation_level;
738 r2.in.flags = r->in.flags;
739 r2.out.validation = r->out.validation;
740 r2.out.authoritative = r->out.authoritative;
741 r2.out.flags = r->out.flags;
742
743 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
744
745 r->out.return_authenticator = return_authenticator;
746
747 return nt_status;
748 }
749
750 /*
751 netr_LogonSamLogon
752 */
753 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
754 struct netr_LogonSamLogon *r)
755 {
756 struct netr_LogonSamLogonWithFlags r2;
757 uint32_t flags = 0;
758 NTSTATUS status;
759
760 ZERO_STRUCT(r2);
761
762 r2.in.server_name = r->in.server_name;
763 r2.in.computer_name = r->in.computer_name;
764 r2.in.credential = r->in.credential;
765 r2.in.return_authenticator = r->in.return_authenticator;
766 r2.in.logon_level = r->in.logon_level;
767 r2.in.logon = r->in.logon;
768 r2.in.validation_level = r->in.validation_level;
769 r2.in.flags = &flags;
770 r2.out.validation = r->out.validation;
771 r2.out.authoritative = r->out.authoritative;
772 r2.out.flags = &flags;
773
774 status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
775
776 r->out.return_authenticator = r2.out.return_authenticator;
777
778 return status;
779 }
780
781
782 /*
783 netr_LogonSamLogoff
784 */
785 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
786 struct netr_LogonSamLogoff *r)
787 {
788 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
789 }
790
791
792
793 /*
794 netr_DatabaseDeltas
795 */
796 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
797 struct netr_DatabaseDeltas *r)
798 {
799 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
800 }
801
802
803 /*
804 netr_DatabaseSync
805 */
806 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
807 struct netr_DatabaseSync *r)
808 {
809 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
810 return NT_STATUS_NOT_IMPLEMENTED;
811 }
812
813
814 /*
815 netr_AccountDeltas
816 */
817 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
818 struct netr_AccountDeltas *r)
819 {
820 /* w2k3 returns "NOT IMPLEMENTED" for this call */
821 return NT_STATUS_NOT_IMPLEMENTED;
822 }
823
824
825 /*
826 netr_AccountSync
827 */
828 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
829 struct netr_AccountSync *r)
830 {
831 /* w2k3 returns "NOT IMPLEMENTED" for this call */
832 return NT_STATUS_NOT_IMPLEMENTED;
833 }
834
835
836 /*
837 netr_GetDcName
838 */
839 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
840 struct netr_GetDcName *r)
841 {
842 const char * const attrs[] = { NULL };
843 void *sam_ctx;
844 struct ldb_message **res;
845 struct ldb_dn *domain_dn;
846 int ret;
847 const char *dcname;
848
849 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
850 dce_call->conn->dce_ctx->lp_ctx,
851 dce_call->conn->auth_state.session_info);
852 if (sam_ctx == NULL) {
853 return WERR_DS_SERVICE_UNAVAILABLE;
854 }
855
856 domain_dn = samdb_domain_to_dn((struct ldb_context *)sam_ctx, mem_ctx,
857 r->in.domainname);
858 if (domain_dn == NULL) {
859 return WERR_DS_SERVICE_UNAVAILABLE;
860 }
861
862 ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx,
863 domain_dn, &res, attrs);
864 if (ret != 1) {
865 return WERR_NO_SUCH_DOMAIN;
866 }
867
868 /* TODO: - return real IP address
869 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
870 */
871 dcname = talloc_asprintf(mem_ctx, "\\\\%s",
872 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
873 W_ERROR_HAVE_NO_MEMORY(dcname);
874
875 *r->out.dcname = dcname;
876 return WERR_OK;
877 }
878
879
880 /*
881 netr_LogonControl
882 */
883 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
884 struct netr_LogonControl *r)
885 {
886 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
887 }
888
889
890 /*
891 netr_GetAnyDCName
892 */
893 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
894 struct netr_GetAnyDCName *r)
895 {
896 struct netr_GetDcName r2;
897 WERROR werr;
898
899 ZERO_STRUCT(r2);
900
901 r2.in.logon_server = r->in.logon_server;
902 r2.in.domainname = r->in.domainname;
903 r2.out.dcname = r->out.dcname;
904
905 werr = dcesrv_netr_GetDcName(dce_call, mem_ctx, &r2);
906
907 return werr;
908 }
909
910
911 /*
912 netr_LogonControl2
913 */
914 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
915 struct netr_LogonControl2 *r)
916 {
917 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
918 }
919
920
921 /*
922 netr_DatabaseSync2
923 */
924 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
925 struct netr_DatabaseSync2 *r)
926 {
927 /* win2k3 native mode returns "NOT IMPLEMENTED" for this call */
928 return NT_STATUS_NOT_IMPLEMENTED;
929 }
930
931
932 /*
933 netr_DatabaseRedo
934 */
935 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
936 struct netr_DatabaseRedo *r)
937 {
938 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
939 }
940
941
942 /*
943 netr_LogonControl2Ex
944 */
945 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
946 struct netr_LogonControl2Ex *r)
947 {
948 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
949 }
950
951
952 /*
953 netr_NetrEnumerateTurstedDomains
954 */
955 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
956 struct netr_NetrEnumerateTrustedDomains *r)
957 {
958 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
959 }
960
961
962 /*
963 netr_LogonGetCapabilities
964 */
965 static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
966 struct netr_LogonGetCapabilities *r)
967 {
968 /* we don't support AES yet */
969 return NT_STATUS_NOT_IMPLEMENTED;
970 }
971
972
973 /*
974 netr_NETRLOGONSETSERVICEBITS
975 */
976 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
977 struct netr_NETRLOGONSETSERVICEBITS *r)
978 {
979 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
980 }
981
982
983 /*
984 netr_LogonGetTrustRid
985 */
986 static WERROR dcesrv_netr_LogonGetTrustRid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
987 struct netr_LogonGetTrustRid *r)
988 {
989 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
990 }
991
992
993 /*
994 netr_NETRLOGONCOMPUTESERVERDIGEST
995 */
996 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
997 struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
998 {
999 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1000 }
1001
1002
1003 /*
1004 netr_NETRLOGONCOMPUTECLIENTDIGEST
1005 */
1006 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1007 struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
1008 {
1009 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1010 }
1011
1012
1013
1014 /*
1015 netr_DsRGetSiteName
1016 */
1017 static WERROR dcesrv_netr_DsRGetSiteName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1018 struct netr_DsRGetSiteName *r)
1019 {
1020 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1021 }
1022
1023
1024 /*
1025 fill in a netr_DomainTrustInfo from a ldb search result
1026 */
1027 static NTSTATUS fill_domain_trust_info(TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1028 struct ldb_message *res,
1029 struct ldb_message *ref_res,
1030 struct netr_DomainTrustInfo *info,
1031 bool is_local, bool is_trust_list)
1032 {
1033 ZERO_STRUCTP(info);
1034
1035 info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension);
1036 info->trust_extension.length = 16;
1037 info->trust_extension.info->flags =
1038 NETR_TRUST_FLAG_TREEROOT |
1039 NETR_TRUST_FLAG_IN_FOREST |
1040 NETR_TRUST_FLAG_PRIMARY;
1041 info->trust_extension.info->parent_index = 0; /* should be index into array
1042 of parent */
1043 info->trust_extension.info->trust_type = LSA_TRUST_TYPE_UPLEVEL; /* should be based on ldb search for trusts */
1044 info->trust_extension.info->trust_attributes = LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE; /* needs to be based on ldb search */
1045
1046 if (is_trust_list) {
1047 /* MS-NRPC 3.5.4.3.9 - must be set to NULL for trust list */
1048 info->forest.string = NULL;
1049 } else {
1050 /* TODO: we need a common function for pulling the forest */
1051 info->forest.string = samdb_result_string(ref_res, "dnsRoot", NULL);
1052 }
1053
1054 if (is_local) {
1055 info->domainname.string = samdb_result_string(ref_res, "nETBIOSName", NULL);
1056 info->fulldomainname.string = samdb_result_string(ref_res, "dnsRoot", NULL);
1057 info->guid = samdb_result_guid(res, "objectGUID");
1058 info->sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
1059 } else {
1060 info->domainname.string = samdb_result_string(res, "flatName", NULL);
1061 info->fulldomainname.string = samdb_result_string(res, "trustPartner", NULL);
1062 info->guid = samdb_result_guid(res, "objectGUID");
1063 info->sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
1064 }
1065
1066 return NT_STATUS_OK;
1067 }
1068
1069 /*
1070 netr_LogonGetDomainInfo
1071 this is called as part of the ADS domain logon procedure.
1072
1073 It has an important role in convaying details about the client, such
1074 as Operating System, Version, Service Pack etc.
1075 */
1076 static NTSTATUS dcesrv_netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1077 struct netr_LogonGetDomainInfo *r)
1078 {
1079 const char * const attrs[] = { "objectSid",
1080 "objectGUID", "flatName", "securityIdentifier",
1081 "trustPartner", NULL };
1082 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1083 struct ldb_context *sam_ctx;
1084 struct ldb_message **res1, **res2, **ref_res;
1085 struct netr_DomainInfo1 *info1;
1086 int ret, ret1, ret2, i;
1087 NTSTATUS status;
1088 struct ldb_dn *partitions_basedn;
1089
1090 const char *local_domain;
1091
1092 status = dcesrv_netr_creds_server_step_check(dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
1093 r->in.computer_name, mem_ctx,
1094 r->in.credential,
1095 r->out.return_authenticator,
1096 NULL);
1097 if (!NT_STATUS_IS_OK(status)) {
1098 DEBUG(0,(__location__ " Bad credentials - error\n"));
1099 }
1100 NT_STATUS_NOT_OK_RETURN(status);
1101
1102 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1103 if (sam_ctx == NULL) {
1104 return NT_STATUS_INVALID_SYSTEM_SERVICE;
1105 }
1106
1107 partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx);
1108
1109 /* we need to do two searches. The first will pull our primary
1110 domain and the second will pull any trusted domains. Our
1111 primary domain is also a "trusted" domain, so we need to
1112 put the primary domain into the lists of returned trusts as
1113 well */
1114 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx), &res1, attrs);
1115 if (ret1 != 1) {
1116 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1117 }
1118
1119 /* try and find the domain */
1120 ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn,
1121 &ref_res, ref_attrs,
1122 "(&(objectClass=crossRef)(ncName=%s))",
1123 ldb_dn_get_linearized(res1[0]->dn));
1124 if (ret != 1) {
1125 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1126 }
1127
1128 local_domain = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1129
1130 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs, "(objectClass=trustedDomain)");
1131 if (ret2 == -1) {
1132 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1133 }
1134
1135 info1 = talloc(mem_ctx, struct netr_DomainInfo1);
1136 NT_STATUS_HAVE_NO_MEMORY(info1);
1137
1138 ZERO_STRUCTP(info1);
1139
1140 info1->num_trusts = ret2 + 1;
1141 info1->trusts = talloc_array(mem_ctx, struct netr_DomainTrustInfo,
1142 info1->num_trusts);
1143 NT_STATUS_HAVE_NO_MEMORY(info1->trusts);
1144
1145 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->domaininfo,
1146 true, false);
1147 NT_STATUS_NOT_OK_RETURN(status);
1148
1149 for (i=0;i<ret2;i++) {
1150 status = fill_domain_trust_info(mem_ctx, res2[i], NULL, &info1->trusts[i],
1151 false, true);
1152 NT_STATUS_NOT_OK_RETURN(status);
1153 }
1154
1155 status = fill_domain_trust_info(mem_ctx, res1[0], ref_res[0], &info1->trusts[i],
1156 true, true);
1157 NT_STATUS_NOT_OK_RETURN(status);
1158
1159 info1->dns_hostname.string = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1160 info1->workstation_flags =
1161 NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS | NETR_WS_FLAG_HANDLES_SPN_UPDATE;
1162 info1->supported_enc_types = 0; /* w2008 gives this 0 */
1163
1164 r->out.info->info1 = info1;
1165
1166 return NT_STATUS_OK;
1167 }
1168
1169
1170
1171 /*
1172 netr_ServerPasswordGet
1173 */
1174 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1175 struct netr_ServerPasswordGet *r)
1176 {
1177 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1178 }
1179
1180
1181 /*
1182 netr_NETRLOGONSENDTOSAM
1183 */
1184 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1185 struct netr_NETRLOGONSENDTOSAM *r)
1186 {
1187 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1188 }
1189
1190
1191 /*
1192 netr_DsRAddressToSitenamesW
1193 */
1194 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1195 struct netr_DsRAddressToSitenamesW *r)
1196 {
1197 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1198 }
1199
1200
1201 /*
1202 netr_DsRGetDCNameEx2
1203 */
1204 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1205 struct netr_DsRGetDCNameEx2 *r)
1206 {
1207 const char * const attrs[] = { "objectGUID", NULL };
1208 void *sam_ctx;
1209 struct ldb_message **res;
1210 struct ldb_dn *domain_dn;
1211 int ret;
1212 struct netr_DsRGetDCNameInfo *info;
1213
1214 ZERO_STRUCTP(r->out.info);
1215
1216 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1217 if (sam_ctx == NULL) {
1218 return WERR_DS_SERVICE_UNAVAILABLE;
1219 }
1220
1221 /* Win7-beta will send the domain name in the form the user typed, so we have to cope
1222 with both the short and long form here */
1223 if (r->in.domain_name == NULL || strcasecmp(r->in.domain_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx)) == 0) {
1224 r->in.domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1225 }
1226
1227 domain_dn = samdb_dns_domain_to_dn((struct ldb_context *)sam_ctx,
1228 mem_ctx,
1229 r->in.domain_name);
1230 if (domain_dn == NULL) {
1231 return WERR_DS_SERVICE_UNAVAILABLE;
1232 }
1233
1234 ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx,
1235 domain_dn, &res, attrs);
1236 if (ret != 1) {
1237 return WERR_NO_SUCH_DOMAIN;
1238 }
1239
1240 info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
1241 W_ERROR_HAVE_NO_MEMORY(info);
1242
1243 /* TODO: - return real IP address
1244 * - check all r->in.* parameters (server_unc is ignored by w2k3!)
1245 */
1246 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s",
1247 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
1248 lp_realm(dce_call->conn->dce_ctx->lp_ctx));
1249 W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
1250 info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
1251 W_ERROR_HAVE_NO_MEMORY(info->dc_address);
1252 info->dc_address_type = DS_ADDRESS_TYPE_INET;
1253 info->domain_guid = samdb_result_guid(res[0], "objectGUID");
1254 info->domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1255 info->forest_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
1256 info->dc_flags = DS_DNS_FOREST |
1257 DS_DNS_DOMAIN |
1258 DS_DNS_CONTROLLER |
1259 DS_SERVER_WRITABLE |
1260 DS_SERVER_CLOSEST |
1261 DS_SERVER_TIMESERV |
1262 DS_SERVER_KDC |
1263 DS_SERVER_DS |
1264 DS_SERVER_LDAP |
1265 DS_SERVER_GC |
1266 DS_SERVER_PDC;
1267 info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1268 W_ERROR_HAVE_NO_MEMORY(info->dc_site_name);
1269 info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name");
1270 W_ERROR_HAVE_NO_MEMORY(info->client_site_name);
1271
1272 *r->out.info = info;
1273
1274 return WERR_OK;
1275 }
1276
1277 /*
1278 netr_DsRGetDCNameEx
1279 */
1280 static WERROR dcesrv_netr_DsRGetDCNameEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1281 struct netr_DsRGetDCNameEx *r)
1282 {
1283 struct netr_DsRGetDCNameEx2 r2;
1284 WERROR werr;
1285
1286 ZERO_STRUCT(r2);
1287
1288 r2.in.server_unc = r->in.server_unc;
1289 r2.in.client_account = NULL;
1290 r2.in.mask = 0;
1291 r2.in.domain_guid = r->in.domain_guid;
1292 r2.in.domain_name = r->in.domain_name;
1293 r2.in.site_name = r->in.site_name;
1294 r2.in.flags = r->in.flags;
1295 r2.out.info = r->out.info;
1296
1297 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1298
1299 return werr;
1300 }
1301
1302 /*
1303 netr_DsRGetDCName
1304 */
1305 static WERROR dcesrv_netr_DsRGetDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1306 struct netr_DsRGetDCName *r)
1307 {
1308 struct netr_DsRGetDCNameEx2 r2;
1309 WERROR werr;
1310
1311 ZERO_STRUCT(r2);
1312
1313 r2.in.server_unc = r->in.server_unc;
1314 r2.in.client_account = NULL;
1315 r2.in.mask = 0;
1316 r2.in.domain_name = r->in.domain_name;
1317 r2.in.domain_guid = r->in.domain_guid;
1318
1319 r2.in.site_name = NULL; /* should fill in from site GUID */
1320 r2.in.flags = r->in.flags;
1321 r2.out.info = r->out.info;
1322
1323 werr = dcesrv_netr_DsRGetDCNameEx2(dce_call, mem_ctx, &r2);
1324
1325 return werr;
1326 }
1327 /*
1328 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
1329 */
1330 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1331 struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
1332 {
1333 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1334 }
1335
1336
1337 /*
1338 netr_NetrEnumerateTrustedDomainsEx
1339 */
1340 static WERROR dcesrv_netr_NetrEnumerateTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1341 struct netr_NetrEnumerateTrustedDomainsEx *r)
1342 {
1343 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1344 }
1345
1346
1347 /*
1348 netr_DsRAddressToSitenamesExW
1349 */
1350 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1351 struct netr_DsRAddressToSitenamesExW *r)
1352 {
1353 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1354 }
1355
1356
1357 /*
1358 netr_DsrGetDcSiteCoverageW
1359 */
1360 static WERROR dcesrv_netr_DsrGetDcSiteCoverageW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1361 struct netr_DsrGetDcSiteCoverageW *r)
1362 {
1363 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1364 }
1365
1366
1367 /*
1368 netr_DsrEnumerateDomainTrusts
1369 */
1370 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1371 struct netr_DsrEnumerateDomainTrusts *r)
1372 {
1373 struct netr_DomainTrustList *trusts;
1374 void *sam_ctx;
1375 int ret;
1376 struct ldb_message **dom_res, **ref_res;
1377 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
1378 const char * const ref_attrs[] = { "nETBIOSName", "dnsRoot", NULL };
1379 struct ldb_dn *partitions_basedn;
1380
1381 ZERO_STRUCT(r->out);
1382
1383 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
1384 if (sam_ctx == NULL) {
1385 return WERR_GENERAL_FAILURE;
1386 }
1387
1388 partitions_basedn = samdb_partitions_dn((struct ldb_context *)sam_ctx,
1389 mem_ctx);
1390
1391 ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, NULL,
1392 &dom_res, dom_attrs);
1393 if (ret == -1) {
1394 return WERR_GENERAL_FAILURE;
1395 }
1396 if (ret != 1) {
1397 return WERR_GENERAL_FAILURE;
1398 }
1399
1400 ret = gendb_search((struct ldb_context *)sam_ctx, mem_ctx,
1401 partitions_basedn, &ref_res, ref_attrs,
1402 "(&(objectClass=crossRef)(ncName=%s))",
1403 ldb_dn_get_linearized(dom_res[0]->dn));
1404 if (ret == -1) {
1405 return WERR_GENERAL_FAILURE;
1406 }
1407 if (ret != 1) {
1408 return WERR_GENERAL_FAILURE;
1409 }
1410
1411 trusts = talloc(mem_ctx, struct netr_DomainTrustList);
1412 W_ERROR_HAVE_NO_MEMORY(trusts);
1413
1414 trusts->array = talloc_array(trusts, struct netr_DomainTrust, ret);
1415 W_ERROR_HAVE_NO_MEMORY(trusts->array);
1416
1417 trusts->count = 1; /* ?? */
1418
1419 r->out.trusts = trusts;
1420
1421 /* TODO: add filtering by trust_flags, and correct trust_type
1422 and attributes */
1423 trusts->array[0].netbios_name = samdb_result_string(ref_res[0], "nETBIOSName", NULL);
1424 trusts->array[0].dns_name = samdb_result_string(ref_res[0], "dnsRoot", NULL);
1425 trusts->array[0].trust_flags =
1426 NETR_TRUST_FLAG_TREEROOT |
1427 NETR_TRUST_FLAG_IN_FOREST |
1428 NETR_TRUST_FLAG_PRIMARY;
1429 trusts->array[0].parent_index = 0;
1430 trusts->array[0].trust_type = 2;
1431 trusts->array[0].trust_attributes = 0;
1432 trusts->array[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
1433 trusts->array[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
1434
1435 return WERR_OK;
1436 }
1437
1438
1439 /*
1440 netr_DsrDeregisterDNSHostRecords
1441 */
1442 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1443 struct netr_DsrDeregisterDNSHostRecords *r)
1444 {
1445 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1446 }
1447
1448
1449 /*
1450 netr_ServerTrustPasswordsGet
1451 */
1452 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1453 struct netr_ServerTrustPasswordsGet *r)
1454 {
1455 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1456 }
1457
1458
1459 /*
1460 netr_DsRGetForestTrustInformation
1461 */
1462 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1463 struct netr_DsRGetForestTrustInformation *r)
1464 {
1465 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1466 }
1467
1468
1469 /*
1470 netr_GetForestTrustInformation
1471 */
1472 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1473 struct netr_GetForestTrustInformation *r)
1474 {
1475 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1476 }
1477
1478
1479 /*
1480 netr_ServerGetTrustInfo
1481 */
1482 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
/* [<][>][^][v][top][bottom][index][help] */
1483 struct netr_ServerGetTrustInfo *r)
1484 {
1485 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1486 }
1487
1488
1489 /* include the generated boilerplate */
1490 #include "librpc/gen_ndr/ndr_netlogon_s.c"