Line data Source code
1 : /* need access mask/acl implementation */
2 :
3 : /*
4 : Unix SMB/CIFS implementation.
5 :
6 : endpoint server for the lsarpc pipe
7 :
8 : Copyright (C) Andrew Tridgell 2004
9 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
10 :
11 : This program is free software; you can redistribute it and/or modify
12 : it under the terms of the GNU General Public License as published by
13 : the Free Software Foundation; either version 3 of the License, or
14 : (at your option) any later version.
15 :
16 : This program is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : GNU General Public License for more details.
20 :
21 : You should have received a copy of the GNU General Public License
22 : along with this program. If not, see <http://www.gnu.org/licenses/>.
23 : */
24 :
25 : #include "rpc_server/lsa/lsa.h"
26 : #include "system/kerberos.h"
27 : #include "auth/kerberos/kerberos.h"
28 : #include "librpc/gen_ndr/ndr_drsblobs.h"
29 : #include "librpc/gen_ndr/ndr_lsa.h"
30 : #include "lib/util/tsort.h"
31 : #include "dsdb/common/util.h"
32 : #include "libcli/security/session.h"
33 : #include "libcli/lsarpc/util_lsarpc.h"
34 : #include "lib/messaging/irpc.h"
35 : #include "libds/common/roles.h"
36 : #include "lib/util/smb_strtox.h"
37 : #include "lib/param/loadparm.h"
38 : #include "librpc/rpc/dcerpc_helper.h"
39 :
40 : #include "lib/crypto/gnutls_helpers.h"
41 : #include <gnutls/gnutls.h>
42 : #include <gnutls/crypto.h>
43 :
44 : #undef strcasecmp
45 :
46 : #define DCESRV_INTERFACE_LSARPC_BIND(context, iface) \
47 : dcesrv_interface_lsarpc_bind(context, iface)
48 4044 : static NTSTATUS dcesrv_interface_lsarpc_bind(struct dcesrv_connection_context *context,
49 : const struct dcesrv_interface *iface)
50 : {
51 4044 : return dcesrv_interface_bind_reject_connect(context, iface);
52 : }
53 :
54 : static NTSTATUS lsarpc__op_init_server(struct dcesrv_context *dce_ctx,
55 : const struct dcesrv_endpoint_server *ep_server);
56 : static const struct dcesrv_interface dcesrv_lsarpc_interface;
57 :
58 : #define NCACN_NP_PIPE_NETLOGON "ncacn_np:[\\pipe\\netlogon]"
59 : #define NCACN_NP_PIPE_LSASS "ncacn_np:[\\pipe\\lsass]"
60 : #define DCESRV_INTERFACE_LSARPC_NCACN_NP_SECONDARY_ENDPOINT NCACN_NP_PIPE_LSASS
61 :
62 : #define DCESRV_INTERFACE_LSARPC_INIT_SERVER \
63 : dcesrv_interface_lsarpc_init_server
64 64 : static NTSTATUS dcesrv_interface_lsarpc_init_server(struct dcesrv_context *dce_ctx,
65 : const struct dcesrv_endpoint_server *ep_server)
66 : {
67 64 : if (lpcfg_lsa_over_netlogon(dce_ctx->lp_ctx)) {
68 9 : NTSTATUS ret = dcesrv_interface_register(dce_ctx,
69 : NCACN_NP_PIPE_NETLOGON,
70 : NCACN_NP_PIPE_LSASS,
71 : &dcesrv_lsarpc_interface, NULL);
72 9 : if (!NT_STATUS_IS_OK(ret)) {
73 0 : DEBUG(1,("lsarpc_op_init_server: failed to register endpoint '\\pipe\\netlogon'\n"));
74 0 : return ret;
75 : }
76 : }
77 64 : return lsarpc__op_init_server(dce_ctx, ep_server);
78 : }
79 :
80 : /*
81 : this type allows us to distinguish handle types
82 : */
83 :
84 : /*
85 : state associated with a lsa_OpenAccount() operation
86 : */
87 : struct lsa_account_state {
88 : struct lsa_policy_state *policy;
89 : uint32_t access_mask;
90 : struct dom_sid *account_sid;
91 : };
92 :
93 :
94 : /*
95 : state associated with a lsa_OpenSecret() operation
96 : */
97 : struct lsa_secret_state {
98 : struct lsa_policy_state *policy;
99 : uint32_t access_mask;
100 : struct ldb_dn *secret_dn;
101 : struct ldb_context *sam_ldb;
102 : bool global;
103 : };
104 :
105 : /*
106 : state associated with a lsa_OpenTrustedDomain() operation
107 : */
108 : struct lsa_trusted_domain_state {
109 : struct lsa_policy_state *policy;
110 : uint32_t access_mask;
111 : struct ldb_dn *trusted_domain_dn;
112 : struct ldb_dn *trusted_domain_user_dn;
113 : };
114 :
115 123 : static bool dcesrc_lsa_valid_AccountRight(const char *right)
116 : {
117 0 : enum sec_privilege priv_id;
118 0 : uint32_t right_bit;
119 :
120 123 : priv_id = sec_privilege_id(right);
121 123 : if (priv_id != SEC_PRIV_INVALID) {
122 115 : return true;
123 : }
124 :
125 8 : right_bit = sec_right_bit(right);
126 8 : if (right_bit != 0) {
127 8 : return true;
128 : }
129 :
130 0 : return false;
131 : }
132 :
133 : /*
134 : this is based on the samba3 function make_lsa_object_sd()
135 : It uses the same logic, but with samba4 helper functions
136 : */
137 0 : static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
138 : struct security_descriptor **sd,
139 : struct dom_sid *sid,
140 : uint32_t sid_access)
141 : {
142 0 : NTSTATUS status;
143 0 : uint32_t rid;
144 0 : struct dom_sid *domain_sid, *domain_admins_sid;
145 0 : const char *domain_admins_sid_str, *sidstr;
146 0 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
147 :
148 0 : status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
149 0 : if (!NT_STATUS_IS_OK(status)) {
150 0 : TALLOC_FREE(tmp_ctx);
151 0 : return status;
152 : }
153 :
154 0 : domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
155 0 : if (domain_admins_sid == NULL) {
156 0 : TALLOC_FREE(tmp_ctx);
157 0 : return NT_STATUS_NO_MEMORY;
158 : }
159 :
160 0 : domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
161 0 : if (domain_admins_sid_str == NULL) {
162 0 : TALLOC_FREE(tmp_ctx);
163 0 : return NT_STATUS_NO_MEMORY;
164 : }
165 :
166 0 : sidstr = dom_sid_string(tmp_ctx, sid);
167 0 : if (sidstr == NULL) {
168 0 : TALLOC_FREE(tmp_ctx);
169 0 : return NT_STATUS_NO_MEMORY;
170 : }
171 :
172 0 : *sd = security_descriptor_dacl_create(mem_ctx,
173 : 0, sidstr, NULL,
174 :
175 : SID_WORLD,
176 : SEC_ACE_TYPE_ACCESS_ALLOWED,
177 : SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
178 :
179 : SID_BUILTIN_ADMINISTRATORS,
180 : SEC_ACE_TYPE_ACCESS_ALLOWED,
181 : SEC_GENERIC_ALL, 0,
182 :
183 : SID_BUILTIN_ACCOUNT_OPERATORS,
184 : SEC_ACE_TYPE_ACCESS_ALLOWED,
185 : SEC_GENERIC_ALL, 0,
186 :
187 : domain_admins_sid_str,
188 : SEC_ACE_TYPE_ACCESS_ALLOWED,
189 : SEC_GENERIC_ALL, 0,
190 :
191 : sidstr,
192 : SEC_ACE_TYPE_ACCESS_ALLOWED,
193 : sid_access, 0,
194 :
195 : NULL);
196 0 : talloc_free(tmp_ctx);
197 :
198 0 : NT_STATUS_HAVE_NO_MEMORY(*sd);
199 :
200 0 : return NT_STATUS_OK;
201 : }
202 :
203 :
204 : static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
205 : TALLOC_CTX *mem_ctx,
206 : struct lsa_EnumAccountRights *r);
207 :
208 : static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
209 : TALLOC_CTX *mem_ctx,
210 : struct lsa_policy_state *state,
211 : int ldb_flag,
212 : struct dom_sid *sid,
213 : const struct lsa_RightSet *rights);
214 :
215 : /*
216 : lsa_Close
217 : */
218 952 : static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
219 : struct lsa_Close *r)
220 : {
221 36 : enum dcerpc_transport_t transport =
222 952 : dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
223 36 : struct dcesrv_handle *h;
224 :
225 952 : if (transport != NCACN_NP && transport != NCALRPC) {
226 0 : DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
227 : }
228 :
229 952 : *r->out.handle = *r->in.handle;
230 :
231 952 : DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
232 :
233 783 : talloc_free(h);
234 :
235 783 : ZERO_STRUCTP(r->out.handle);
236 :
237 783 : return NT_STATUS_OK;
238 : }
239 :
240 :
241 : /*
242 : lsa_Delete
243 : */
244 33 : static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
245 : struct lsa_Delete *r)
246 : {
247 33 : return NT_STATUS_NOT_SUPPORTED;
248 : }
249 :
250 :
251 : /*
252 : lsa_DeleteObject
253 : */
254 1788 : static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
255 : struct lsa_DeleteObject *r)
256 : {
257 0 : struct auth_session_info *session_info =
258 1788 : dcesrv_call_session_info(dce_call);
259 0 : struct dcesrv_handle *h;
260 0 : int ret;
261 :
262 1788 : DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
263 :
264 1788 : if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
265 1669 : struct lsa_secret_state *secret_state = h->data;
266 :
267 : /* Ensure user is permitted to delete this... */
268 1669 : switch (security_session_user_level(session_info, NULL))
269 : {
270 1669 : case SECURITY_SYSTEM:
271 : case SECURITY_ADMINISTRATOR:
272 1669 : break;
273 0 : default:
274 : /* Users and anonymous are not allowed to delete things */
275 0 : return NT_STATUS_ACCESS_DENIED;
276 : }
277 :
278 1669 : ret = ldb_delete(secret_state->sam_ldb,
279 : secret_state->secret_dn);
280 1669 : if (ret != LDB_SUCCESS) {
281 18 : return NT_STATUS_INVALID_HANDLE;
282 : }
283 :
284 1651 : ZERO_STRUCTP(r->out.handle);
285 :
286 1651 : return NT_STATUS_OK;
287 :
288 119 : } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
289 0 : struct lsa_trusted_domain_state *trusted_domain_state =
290 112 : talloc_get_type(h->data, struct lsa_trusted_domain_state);
291 112 : ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
292 112 : if (ret != LDB_SUCCESS) {
293 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
294 : }
295 :
296 112 : ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
297 : trusted_domain_state->trusted_domain_dn);
298 112 : if (ret != LDB_SUCCESS) {
299 0 : ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
300 0 : return NT_STATUS_INVALID_HANDLE;
301 : }
302 :
303 112 : if (trusted_domain_state->trusted_domain_user_dn) {
304 52 : ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
305 : trusted_domain_state->trusted_domain_user_dn);
306 52 : if (ret != LDB_SUCCESS) {
307 0 : ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
308 0 : return NT_STATUS_INVALID_HANDLE;
309 : }
310 : }
311 :
312 112 : ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
313 112 : if (ret != LDB_SUCCESS) {
314 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
315 : }
316 :
317 112 : ZERO_STRUCTP(r->out.handle);
318 :
319 112 : return NT_STATUS_OK;
320 :
321 7 : } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
322 0 : struct lsa_RightSet *rights;
323 0 : struct lsa_account_state *astate;
324 0 : struct lsa_EnumAccountRights r2;
325 0 : NTSTATUS status;
326 :
327 7 : rights = talloc(mem_ctx, struct lsa_RightSet);
328 :
329 7 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
330 :
331 7 : astate = h->data;
332 :
333 7 : r2.in.handle = &astate->policy->handle->wire_handle;
334 7 : r2.in.sid = astate->account_sid;
335 7 : r2.out.rights = rights;
336 :
337 : /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
338 : but we have a LSA_HANDLE_ACCOUNT here, so this call
339 : will always fail */
340 7 : status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
341 7 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
342 3 : return NT_STATUS_OK;
343 : }
344 :
345 4 : if (!NT_STATUS_IS_OK(status)) {
346 0 : return status;
347 : }
348 :
349 4 : status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
350 : LDB_FLAG_MOD_DELETE, astate->account_sid,
351 4 : r2.out.rights);
352 4 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
353 0 : return NT_STATUS_OK;
354 : }
355 :
356 4 : if (!NT_STATUS_IS_OK(status)) {
357 0 : return status;
358 : }
359 :
360 4 : ZERO_STRUCTP(r->out.handle);
361 :
362 4 : return NT_STATUS_OK;
363 : }
364 :
365 0 : return NT_STATUS_INVALID_HANDLE;
366 : }
367 :
368 :
369 : /*
370 : lsa_EnumPrivs
371 : */
372 3 : static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
373 : struct lsa_EnumPrivs *r)
374 : {
375 0 : struct dcesrv_handle *h;
376 0 : uint32_t i;
377 0 : enum sec_privilege priv;
378 0 : const char *privname;
379 :
380 3 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
381 :
382 3 : i = *r->in.resume_handle;
383 :
384 78 : while (((priv = sec_privilege_from_index(i)) != SEC_PRIV_INVALID) &&
385 75 : r->out.privs->count < r->in.max_count) {
386 0 : struct lsa_PrivEntry *e;
387 75 : privname = sec_privilege_name(priv);
388 75 : r->out.privs->privs = talloc_realloc(r->out.privs,
389 : r->out.privs->privs,
390 : struct lsa_PrivEntry,
391 : r->out.privs->count+1);
392 75 : if (r->out.privs->privs == NULL) {
393 0 : return NT_STATUS_NO_MEMORY;
394 : }
395 75 : e = &r->out.privs->privs[r->out.privs->count];
396 75 : e->luid.low = priv;
397 75 : e->luid.high = 0;
398 75 : e->name.string = privname;
399 75 : r->out.privs->count++;
400 75 : i++;
401 : }
402 :
403 3 : *r->out.resume_handle = i;
404 :
405 3 : return NT_STATUS_OK;
406 : }
407 :
408 :
409 : /*
410 : lsa_QuerySecObj
411 : */
412 48 : static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
413 : struct lsa_QuerySecurity *r)
414 : {
415 12 : struct auth_session_info *session_info =
416 48 : dcesrv_call_session_info(dce_call);
417 12 : struct dcesrv_handle *h;
418 48 : const struct security_descriptor *sd = NULL;
419 48 : uint32_t access_granted = 0;
420 48 : struct sec_desc_buf *sdbuf = NULL;
421 12 : NTSTATUS status;
422 12 : struct dom_sid *sid;
423 :
424 48 : DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
425 :
426 48 : sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
427 :
428 48 : if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
429 48 : struct lsa_policy_state *pstate = h->data;
430 :
431 48 : sd = pstate->sd;
432 48 : access_granted = pstate->access_mask;
433 :
434 0 : } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
435 0 : struct lsa_account_state *astate = h->data;
436 0 : struct security_descriptor *_sd = NULL;
437 :
438 0 : status = dcesrv_build_lsa_sd(mem_ctx, &_sd, sid,
439 : LSA_ACCOUNT_ALL_ACCESS);
440 0 : if (!NT_STATUS_IS_OK(status)) {
441 0 : return status;
442 : }
443 0 : sd = _sd;
444 0 : access_granted = astate->access_mask;
445 : } else {
446 0 : return NT_STATUS_INVALID_HANDLE;
447 : }
448 :
449 48 : sdbuf = talloc_zero(mem_ctx, struct sec_desc_buf);
450 48 : if (sdbuf == NULL) {
451 0 : return NT_STATUS_NO_MEMORY;
452 : }
453 :
454 48 : status = security_descriptor_for_client(sdbuf, sd, r->in.sec_info,
455 : access_granted, &sdbuf->sd);
456 48 : if (!NT_STATUS_IS_OK(status)) {
457 0 : return status;
458 : }
459 :
460 48 : *r->out.sdbuf = sdbuf;
461 :
462 48 : return NT_STATUS_OK;
463 : }
464 :
465 :
466 : /*
467 : lsa_SetSecObj
468 : */
469 0 : static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
470 : struct lsa_SetSecObj *r)
471 : {
472 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
473 : }
474 :
475 :
476 : /*
477 : lsa_ChangePassword
478 : */
479 0 : static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
480 : struct lsa_ChangePassword *r)
481 : {
482 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
483 : }
484 :
485 : /*
486 : dssetup_DsRoleGetPrimaryDomainInformation
487 :
488 : This is not an LSA call, but is the only call left on the DSSETUP
489 : pipe (after the pipe was truncated), and needs lsa_get_policy_state
490 : */
491 123 : static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
492 : TALLOC_CTX *mem_ctx,
493 : struct dssetup_DsRoleGetPrimaryDomainInformation *r)
494 : {
495 9 : union dssetup_DsRoleInfo *info;
496 :
497 123 : info = talloc_zero(mem_ctx, union dssetup_DsRoleInfo);
498 123 : W_ERROR_HAVE_NO_MEMORY(info);
499 :
500 123 : switch (r->in.level) {
501 63 : case DS_ROLE_BASIC_INFORMATION:
502 : {
503 63 : enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
504 63 : uint32_t flags = 0;
505 63 : const char *domain = NULL;
506 63 : const char *dns_domain = NULL;
507 63 : const char *forest = NULL;
508 3 : struct GUID domain_guid;
509 3 : struct lsa_policy_state *state;
510 :
511 63 : NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx,
512 : 0, /* we skip access checks */
513 : &state);
514 63 : if (!NT_STATUS_IS_OK(status)) {
515 0 : return ntstatus_to_werror(status);
516 : }
517 :
518 63 : ZERO_STRUCT(domain_guid);
519 :
520 63 : switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
521 0 : case ROLE_STANDALONE:
522 0 : role = DS_ROLE_STANDALONE_SERVER;
523 0 : break;
524 4 : case ROLE_DOMAIN_MEMBER:
525 4 : role = DS_ROLE_MEMBER_SERVER;
526 4 : break;
527 59 : case ROLE_ACTIVE_DIRECTORY_DC:
528 59 : if (samdb_is_pdc(state->sam_ldb)) {
529 56 : role = DS_ROLE_PRIMARY_DC;
530 : } else {
531 0 : role = DS_ROLE_BACKUP_DC;
532 : }
533 56 : break;
534 : }
535 :
536 63 : switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
537 0 : case ROLE_STANDALONE:
538 0 : domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
539 0 : W_ERROR_HAVE_NO_MEMORY(domain);
540 0 : break;
541 4 : case ROLE_DOMAIN_MEMBER:
542 4 : domain = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
543 4 : W_ERROR_HAVE_NO_MEMORY(domain);
544 : /* TODO: what is with dns_domain and forest and guid? */
545 4 : break;
546 59 : case ROLE_ACTIVE_DIRECTORY_DC:
547 59 : flags = DS_ROLE_PRIMARY_DS_RUNNING;
548 :
549 59 : if (state->mixed_domain == 1) {
550 0 : flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
551 : }
552 :
553 59 : domain = state->domain_name;
554 59 : dns_domain = state->domain_dns;
555 59 : forest = state->forest_dns;
556 :
557 59 : domain_guid = state->domain_guid;
558 59 : flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
559 59 : break;
560 : }
561 :
562 63 : info->basic.role = role;
563 63 : info->basic.flags = flags;
564 63 : info->basic.domain = domain;
565 63 : info->basic.dns_domain = dns_domain;
566 63 : info->basic.forest = forest;
567 63 : info->basic.domain_guid = domain_guid;
568 :
569 63 : r->out.info = info;
570 63 : return WERR_OK;
571 : }
572 30 : case DS_ROLE_UPGRADE_STATUS:
573 : {
574 30 : info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
575 30 : info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
576 :
577 30 : r->out.info = info;
578 30 : return WERR_OK;
579 : }
580 30 : case DS_ROLE_OP_STATUS:
581 : {
582 30 : info->opstatus.status = DS_ROLE_OP_IDLE;
583 :
584 30 : r->out.info = info;
585 30 : return WERR_OK;
586 : }
587 0 : default:
588 0 : return WERR_INVALID_PARAMETER;
589 : }
590 : }
591 :
592 : /*
593 : fill in the AccountDomain info
594 : */
595 751 : static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
596 : struct lsa_DomainInfo *info)
597 : {
598 751 : info->name.string = state->domain_name;
599 751 : info->sid = state->domain_sid;
600 :
601 751 : return NT_STATUS_OK;
602 : }
603 :
604 : /*
605 : fill in the DNS domain info
606 : */
607 880 : static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
608 : struct lsa_DnsDomainInfo *info)
609 : {
610 880 : info->name.string = state->domain_name;
611 880 : info->sid = state->domain_sid;
612 880 : info->dns_domain.string = state->domain_dns;
613 880 : info->dns_forest.string = state->forest_dns;
614 880 : info->domain_guid = state->domain_guid;
615 :
616 880 : return NT_STATUS_OK;
617 : }
618 :
619 : /*
620 : lsa_QueryInfoPolicy2
621 : */
622 1847 : static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
623 : struct lsa_QueryInfoPolicy2 *r)
624 : {
625 146 : struct lsa_policy_state *state;
626 146 : struct dcesrv_handle *h;
627 146 : union lsa_PolicyInformation *info;
628 :
629 1847 : *r->out.info = NULL;
630 :
631 1847 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
632 :
633 1847 : state = h->data;
634 :
635 1847 : info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
636 1847 : if (!info) {
637 0 : return NT_STATUS_NO_MEMORY;
638 : }
639 1847 : *r->out.info = info;
640 :
641 1847 : switch (r->in.level) {
642 24 : case LSA_POLICY_INFO_AUDIT_LOG:
643 : /* we don't need to fill in any of this */
644 24 : ZERO_STRUCT(info->audit_log);
645 24 : return NT_STATUS_OK;
646 24 : case LSA_POLICY_INFO_AUDIT_EVENTS:
647 : /* we don't need to fill in any of this */
648 24 : ZERO_STRUCT(info->audit_events);
649 24 : return NT_STATUS_OK;
650 24 : case LSA_POLICY_INFO_PD:
651 : /* we don't need to fill in any of this */
652 24 : ZERO_STRUCT(info->pd);
653 24 : return NT_STATUS_OK;
654 :
655 563 : case LSA_POLICY_INFO_DOMAIN:
656 563 : return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
657 164 : case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
658 164 : return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
659 24 : case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
660 24 : return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
661 :
662 24 : case LSA_POLICY_INFO_ROLE:
663 24 : info->role.role = LSA_ROLE_PRIMARY;
664 24 : return NT_STATUS_OK;
665 :
666 856 : case LSA_POLICY_INFO_DNS:
667 856 : return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
668 24 : case LSA_POLICY_INFO_DNS_INT:
669 24 : return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns_int);
670 :
671 24 : case LSA_POLICY_INFO_REPLICA:
672 24 : ZERO_STRUCT(info->replica);
673 24 : return NT_STATUS_OK;
674 :
675 24 : case LSA_POLICY_INFO_QUOTA:
676 24 : ZERO_STRUCT(info->quota);
677 24 : return NT_STATUS_OK;
678 :
679 72 : case LSA_POLICY_INFO_MOD:
680 : case LSA_POLICY_INFO_AUDIT_FULL_SET:
681 : case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
682 : /* windows gives INVALID_PARAMETER */
683 72 : *r->out.info = NULL;
684 72 : return NT_STATUS_INVALID_PARAMETER;
685 : }
686 :
687 0 : *r->out.info = NULL;
688 0 : return NT_STATUS_INVALID_INFO_CLASS;
689 : }
690 :
691 : /*
692 : lsa_QueryInfoPolicy
693 : */
694 847 : static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
695 : struct lsa_QueryInfoPolicy *r)
696 : {
697 72 : struct lsa_QueryInfoPolicy2 r2;
698 72 : NTSTATUS status;
699 :
700 847 : ZERO_STRUCT(r2);
701 :
702 847 : r2.in.handle = r->in.handle;
703 847 : r2.in.level = r->in.level;
704 847 : r2.out.info = r->out.info;
705 :
706 847 : status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
707 :
708 847 : return status;
709 : }
710 :
711 : /*
712 : lsa_SetInfoPolicy
713 : */
714 0 : static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
715 : struct lsa_SetInfoPolicy *r)
716 : {
717 : /* need to support this */
718 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
719 : }
720 :
721 :
722 : /*
723 : lsa_ClearAuditLog
724 : */
725 0 : static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
726 : struct lsa_ClearAuditLog *r)
727 : {
728 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
729 : }
730 :
731 :
732 : static const struct generic_mapping dcesrv_lsa_account_mapping = {
733 : LSA_ACCOUNT_READ,
734 : LSA_ACCOUNT_WRITE,
735 : LSA_ACCOUNT_EXECUTE,
736 : LSA_ACCOUNT_ALL_ACCESS
737 : };
738 :
739 : /*
740 : lsa_CreateAccount
741 :
742 : This call does not seem to have any long-term effects, hence no database operations
743 :
744 : we need to talk to the MS product group to find out what this account database means!
745 :
746 : answer is that the lsa database is totally separate from the SAM and
747 : ldap databases. We are going to need a separate ldb to store these
748 : accounts. The SIDs on this account bear no relation to the SIDs in
749 : AD
750 : */
751 3 : static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
752 : struct lsa_CreateAccount *r)
753 : {
754 0 : struct lsa_account_state *astate;
755 :
756 0 : struct lsa_policy_state *state;
757 0 : struct dcesrv_handle *h, *ah;
758 :
759 3 : ZERO_STRUCTP(r->out.acct_handle);
760 :
761 3 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
762 :
763 3 : state = h->data;
764 :
765 3 : astate = talloc(dce_call->conn, struct lsa_account_state);
766 3 : if (astate == NULL) {
767 0 : return NT_STATUS_NO_MEMORY;
768 : }
769 :
770 3 : astate->account_sid = dom_sid_dup(astate, r->in.sid);
771 3 : if (astate->account_sid == NULL) {
772 0 : talloc_free(astate);
773 0 : return NT_STATUS_NO_MEMORY;
774 : }
775 :
776 3 : astate->policy = talloc_reference(astate, state);
777 3 : astate->access_mask = r->in.access_mask;
778 :
779 : /*
780 : * For now we grant all requested access.
781 : *
782 : * We will fail at the ldb layer later.
783 : */
784 3 : if (astate->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
785 3 : astate->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
786 3 : astate->access_mask |= LSA_ACCOUNT_ALL_ACCESS;
787 : }
788 3 : se_map_generic(&astate->access_mask, &dcesrv_lsa_account_mapping);
789 :
790 3 : DEBUG(10,("%s: %s access desired[0x%08X] granted[0x%08X].\n",
791 : __func__, dom_sid_string(mem_ctx, astate->account_sid),
792 : (unsigned)r->in.access_mask,
793 : (unsigned)astate->access_mask));
794 :
795 3 : ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT);
796 3 : if (!ah) {
797 0 : talloc_free(astate);
798 0 : return NT_STATUS_NO_MEMORY;
799 : }
800 :
801 3 : ah->data = talloc_steal(ah, astate);
802 :
803 3 : *r->out.acct_handle = ah->wire_handle;
804 :
805 3 : return NT_STATUS_OK;
806 : }
807 :
808 :
809 : /*
810 : lsa_EnumAccounts
811 : */
812 18 : static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
813 : struct lsa_EnumAccounts *r)
814 : {
815 0 : struct dcesrv_handle *h;
816 0 : struct lsa_policy_state *state;
817 0 : int ret;
818 0 : struct ldb_message **res;
819 18 : const char * const attrs[] = { "objectSid", NULL};
820 0 : uint32_t count, i;
821 :
822 18 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
823 :
824 18 : state = h->data;
825 :
826 : /* NOTE: This call must only return accounts that have at least
827 : one privilege set
828 : */
829 18 : ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
830 : "(&(objectSid=*)(privilege=*))");
831 18 : if (ret < 0) {
832 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
833 : }
834 :
835 18 : if (*r->in.resume_handle >= ret) {
836 3 : return NT_STATUS_NO_MORE_ENTRIES;
837 : }
838 :
839 15 : count = ret - *r->in.resume_handle;
840 15 : if (count > r->in.num_entries) {
841 0 : count = r->in.num_entries;
842 : }
843 :
844 15 : if (count == 0) {
845 0 : return NT_STATUS_NO_MORE_ENTRIES;
846 : }
847 :
848 15 : r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
849 15 : if (r->out.sids->sids == NULL) {
850 0 : return NT_STATUS_NO_MEMORY;
851 : }
852 :
853 113 : for (i=0;i<count;i++) {
854 196 : r->out.sids->sids[i].sid =
855 98 : samdb_result_dom_sid(r->out.sids->sids,
856 98 : res[i + *r->in.resume_handle],
857 : "objectSid");
858 98 : NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
859 : }
860 :
861 15 : r->out.sids->num_sids = count;
862 15 : *r->out.resume_handle = count + *r->in.resume_handle;
863 :
864 15 : return NT_STATUS_OK;
865 : }
866 :
867 : /* This decrypts and returns Trusted Domain Auth Information Internal data */
868 62 : static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
869 : TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
870 : struct trustDomainPasswords *auth_struct)
871 : {
872 62 : DATA_BLOB session_key = data_blob(NULL, 0);
873 0 : enum ndr_err_code ndr_err;
874 0 : NTSTATUS nt_status;
875 62 : gnutls_cipher_hd_t cipher_hnd = NULL;
876 0 : gnutls_datum_t _session_key;
877 0 : int rc;
878 0 : struct auth_session_info *session_info =
879 62 : dcesrv_call_session_info(dce_call);
880 62 : struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
881 0 : bool encrypted;
882 :
883 0 : encrypted =
884 62 : dcerpc_is_transport_encrypted(session_info);
885 62 : if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED &&
886 0 : !encrypted) {
887 0 : DBG_ERR("Transport isn't encrypted and weak crypto disallowed!\n");
888 0 : return NT_STATUS_ACCESS_DENIED;
889 : }
890 :
891 :
892 62 : nt_status = dcesrv_transport_session_key(dce_call, &session_key);
893 62 : if (!NT_STATUS_IS_OK(nt_status)) {
894 0 : return nt_status;
895 : }
896 :
897 62 : _session_key = (gnutls_datum_t) {
898 62 : .data = session_key.data,
899 62 : .size = session_key.length,
900 : };
901 :
902 62 : GNUTLS_FIPS140_SET_LAX_MODE();
903 62 : rc = gnutls_cipher_init(&cipher_hnd,
904 : GNUTLS_CIPHER_ARCFOUR_128,
905 : &_session_key,
906 : NULL);
907 62 : if (rc < 0) {
908 0 : GNUTLS_FIPS140_SET_STRICT_MODE();
909 0 : nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
910 0 : goto out;
911 : }
912 :
913 62 : rc = gnutls_cipher_decrypt(cipher_hnd,
914 62 : auth_blob->data,
915 : auth_blob->length);
916 62 : gnutls_cipher_deinit(cipher_hnd);
917 62 : GNUTLS_FIPS140_SET_STRICT_MODE();
918 62 : if (rc < 0) {
919 0 : nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
920 0 : goto out;
921 : }
922 :
923 62 : ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
924 : auth_struct,
925 : (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
926 62 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
927 0 : return NT_STATUS_INVALID_PARAMETER;
928 : }
929 :
930 62 : nt_status = NT_STATUS_OK;
931 62 : out:
932 62 : return nt_status;
933 : }
934 :
935 118 : static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call,
936 : TALLOC_CTX *mem_ctx,
937 : struct trustAuthInOutBlob *iopw,
938 : DATA_BLOB *trustauth_blob)
939 : {
940 0 : enum ndr_err_code ndr_err;
941 :
942 118 : if (iopw->current.count != iopw->count) {
943 0 : return NT_STATUS_INVALID_PARAMETER;
944 : }
945 :
946 118 : if (iopw->previous.count > iopw->current.count) {
947 0 : return NT_STATUS_INVALID_PARAMETER;
948 : }
949 :
950 118 : if (iopw->previous.count == 0) {
951 : /*
952 : * If the previous credentials are not present
953 : * we need to make a copy.
954 : */
955 46 : iopw->previous = iopw->current;
956 : }
957 :
958 118 : if (iopw->previous.count < iopw->current.count) {
959 0 : struct AuthenticationInformationArray *c = &iopw->current;
960 0 : struct AuthenticationInformationArray *p = &iopw->previous;
961 :
962 : /*
963 : * The previous array needs to have the same size
964 : * as the current one.
965 : *
966 : * We may have to fill with TRUST_AUTH_TYPE_NONE
967 : * elements.
968 : */
969 0 : p->array = talloc_realloc(mem_ctx, p->array,
970 : struct AuthenticationInformation,
971 : c->count);
972 0 : if (p->array == NULL) {
973 0 : return NT_STATUS_NO_MEMORY;
974 : }
975 :
976 0 : while (p->count < c->count) {
977 0 : struct AuthenticationInformation *a =
978 0 : &p->array[p->count++];
979 :
980 0 : *a = (struct AuthenticationInformation) {
981 0 : .LastUpdateTime = p->array[0].LastUpdateTime,
982 : .AuthType = TRUST_AUTH_TYPE_NONE,
983 : };
984 : }
985 : }
986 :
987 118 : ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
988 : iopw,
989 : (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
990 118 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
991 0 : return NT_STATUS_INVALID_PARAMETER;
992 : }
993 :
994 118 : return NT_STATUS_OK;
995 : }
996 :
997 71 : static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx,
998 : struct ldb_context *sam_ldb,
999 : struct ldb_dn *base_dn,
1000 : const char *netbios_name,
1001 : struct trustAuthInOutBlob *in,
1002 : struct ldb_dn **user_dn)
1003 : {
1004 0 : struct ldb_request *req;
1005 0 : struct ldb_message *msg;
1006 0 : struct ldb_dn *dn;
1007 0 : uint32_t i;
1008 0 : int ret;
1009 :
1010 71 : dn = ldb_dn_copy(mem_ctx, base_dn);
1011 71 : if (!dn) {
1012 0 : return NT_STATUS_NO_MEMORY;
1013 : }
1014 71 : if (!ldb_dn_add_child_fmt(dn, "cn=%s$,cn=users", netbios_name)) {
1015 0 : return NT_STATUS_NO_MEMORY;
1016 : }
1017 :
1018 71 : msg = ldb_msg_new(mem_ctx);
1019 71 : if (!msg) {
1020 0 : return NT_STATUS_NO_MEMORY;
1021 : }
1022 71 : msg->dn = dn;
1023 :
1024 71 : ret = ldb_msg_add_string(msg, "objectClass", "user");
1025 71 : if (ret != LDB_SUCCESS) {
1026 0 : return NT_STATUS_NO_MEMORY;
1027 : }
1028 :
1029 71 : ret = ldb_msg_add_fmt(msg, "samAccountName", "%s$", netbios_name);
1030 71 : if (ret != LDB_SUCCESS) {
1031 0 : return NT_STATUS_NO_MEMORY;
1032 : }
1033 :
1034 71 : ret = samdb_msg_add_uint(sam_ldb, msg, msg, "userAccountControl",
1035 : UF_INTERDOMAIN_TRUST_ACCOUNT);
1036 71 : if (ret != LDB_SUCCESS) {
1037 0 : return NT_STATUS_NO_MEMORY;
1038 : }
1039 :
1040 118 : for (i = 0; i < in->count; i++) {
1041 0 : const char *attribute;
1042 0 : struct ldb_val v;
1043 47 : switch (in->current.array[i].AuthType) {
1044 0 : case TRUST_AUTH_TYPE_NT4OWF:
1045 0 : attribute = "unicodePwd";
1046 0 : v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
1047 0 : v.length = 16;
1048 0 : break;
1049 47 : case TRUST_AUTH_TYPE_CLEAR:
1050 47 : attribute = "clearTextPassword";
1051 47 : v.data = in->current.array[i].AuthInfo.clear.password;
1052 47 : v.length = in->current.array[i].AuthInfo.clear.size;
1053 47 : break;
1054 0 : default:
1055 0 : continue;
1056 : }
1057 :
1058 47 : ret = ldb_msg_add_value(msg, attribute, &v, NULL);
1059 47 : if (ret != LDB_SUCCESS) {
1060 0 : return NT_STATUS_NO_MEMORY;
1061 : }
1062 : }
1063 :
1064 : /* create the trusted_domain user account */
1065 71 : ret = ldb_build_add_req(&req, sam_ldb, mem_ctx, msg, NULL, NULL,
1066 : ldb_op_default_callback, NULL);
1067 71 : if (ret != LDB_SUCCESS) {
1068 0 : return NT_STATUS_NO_MEMORY;
1069 : }
1070 :
1071 71 : ret = ldb_request_add_control(req, DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID,
1072 : false, NULL);
1073 71 : if (ret != LDB_SUCCESS) {
1074 0 : return NT_STATUS_NO_MEMORY;
1075 : }
1076 :
1077 71 : ret = dsdb_autotransaction_request(sam_ldb, req);
1078 71 : if (ret != LDB_SUCCESS) {
1079 0 : DEBUG(0,("Failed to create user record %s: %s\n",
1080 : ldb_dn_get_linearized(msg->dn),
1081 : ldb_errstring(sam_ldb)));
1082 :
1083 0 : switch (ret) {
1084 0 : case LDB_ERR_ENTRY_ALREADY_EXISTS:
1085 0 : return NT_STATUS_DOMAIN_EXISTS;
1086 0 : case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1087 0 : return NT_STATUS_ACCESS_DENIED;
1088 0 : default:
1089 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
1090 : }
1091 : }
1092 :
1093 71 : if (user_dn) {
1094 71 : *user_dn = dn;
1095 : }
1096 71 : return NT_STATUS_OK;
1097 : }
1098 :
1099 : /*
1100 : lsa_CreateTrustedDomainEx2
1101 : */
1102 134 : static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dce_call,
1103 : TALLOC_CTX *mem_ctx,
1104 : struct lsa_CreateTrustedDomainEx2 *r,
1105 : int op,
1106 : struct lsa_TrustDomainInfoAuthInfo *unencrypted_auth_info)
1107 : {
1108 0 : struct dcesrv_handle *policy_handle;
1109 0 : struct lsa_policy_state *policy_state;
1110 0 : struct lsa_trusted_domain_state *trusted_domain_state;
1111 0 : struct dcesrv_handle *handle;
1112 0 : struct ldb_message **msgs, *msg;
1113 134 : const char *attrs[] = {
1114 : NULL
1115 : };
1116 0 : const char *netbios_name;
1117 0 : const char *dns_name;
1118 0 : DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
1119 0 : struct trustDomainPasswords auth_struct;
1120 0 : int ret;
1121 0 : NTSTATUS nt_status;
1122 0 : struct ldb_context *sam_ldb;
1123 134 : struct server_id *server_ids = NULL;
1124 134 : uint32_t num_server_ids = 0;
1125 0 : NTSTATUS status;
1126 0 : bool ok;
1127 134 : char *dns_encoded = NULL;
1128 134 : char *netbios_encoded = NULL;
1129 134 : char *sid_encoded = NULL;
1130 0 : struct imessaging_context *imsg_ctx =
1131 134 : dcesrv_imessaging_context(dce_call->conn);
1132 :
1133 134 : DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
1134 134 : ZERO_STRUCTP(r->out.trustdom_handle);
1135 :
1136 134 : policy_state = policy_handle->data;
1137 134 : sam_ldb = policy_state->sam_ldb;
1138 :
1139 134 : netbios_name = r->in.info->netbios_name.string;
1140 134 : if (!netbios_name) {
1141 0 : return NT_STATUS_INVALID_PARAMETER;
1142 : }
1143 :
1144 134 : dns_name = r->in.info->domain_name.string;
1145 134 : if (dns_name == NULL) {
1146 0 : return NT_STATUS_INVALID_PARAMETER;
1147 : }
1148 :
1149 134 : if (r->in.info->sid == NULL) {
1150 0 : return NT_STATUS_INVALID_SID;
1151 : }
1152 :
1153 : /*
1154 : * We expect S-1-5-21-A-B-C, but we don't
1155 : * allow S-1-5-21-0-0-0 as this is used
1156 : * for claims and compound identities.
1157 : */
1158 134 : ok = dom_sid_is_valid_account_domain(r->in.info->sid);
1159 134 : if (!ok) {
1160 0 : return NT_STATUS_INVALID_PARAMETER;
1161 : }
1162 :
1163 134 : dns_encoded = ldb_binary_encode_string(mem_ctx, dns_name);
1164 134 : if (dns_encoded == NULL) {
1165 0 : return NT_STATUS_NO_MEMORY;
1166 : }
1167 134 : netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
1168 134 : if (netbios_encoded == NULL) {
1169 0 : return NT_STATUS_NO_MEMORY;
1170 : }
1171 134 : sid_encoded = ldap_encode_ndr_dom_sid(mem_ctx, r->in.info->sid);
1172 134 : if (sid_encoded == NULL) {
1173 0 : return NT_STATUS_NO_MEMORY;
1174 : }
1175 :
1176 134 : trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
1177 134 : if (!trusted_domain_state) {
1178 0 : return NT_STATUS_NO_MEMORY;
1179 : }
1180 134 : trusted_domain_state->policy = policy_state;
1181 :
1182 134 : if (strcasecmp(netbios_name, "BUILTIN") == 0
1183 134 : || (strcasecmp(dns_name, "BUILTIN") == 0)
1184 134 : || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
1185 0 : return NT_STATUS_INVALID_PARAMETER;
1186 : }
1187 :
1188 134 : if (strcasecmp(netbios_name, policy_state->domain_name) == 0
1189 134 : || strcasecmp(netbios_name, policy_state->domain_dns) == 0
1190 134 : || strcasecmp(dns_name, policy_state->domain_dns) == 0
1191 134 : || strcasecmp(dns_name, policy_state->domain_name) == 0
1192 134 : || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
1193 0 : return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
1194 : }
1195 :
1196 : /* While this is a REF pointer, some of the functions that wrap this don't provide this */
1197 134 : if (op == NDR_LSA_CREATETRUSTEDDOMAIN) {
1198 : /* No secrets are created at this time, for this function */
1199 36 : auth_struct.outgoing.count = 0;
1200 36 : auth_struct.incoming.count = 0;
1201 98 : } else if (op == NDR_LSA_CREATETRUSTEDDOMAINEX2) {
1202 62 : auth_blob = data_blob_const(r->in.auth_info_internal->auth_blob.data,
1203 62 : r->in.auth_info_internal->auth_blob.size);
1204 62 : nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
1205 : &auth_blob, &auth_struct);
1206 62 : if (!NT_STATUS_IS_OK(nt_status)) {
1207 0 : return nt_status;
1208 : }
1209 36 : } else if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) {
1210 :
1211 36 : if (unencrypted_auth_info->incoming_count > 1) {
1212 0 : return NT_STATUS_INVALID_PARAMETER;
1213 : }
1214 :
1215 : /* more investigation required here, do not create secrets for
1216 : * now */
1217 36 : auth_struct.outgoing.count = 0;
1218 36 : auth_struct.incoming.count = 0;
1219 : } else {
1220 0 : return NT_STATUS_INVALID_PARAMETER;
1221 : }
1222 :
1223 134 : if (auth_struct.incoming.count) {
1224 59 : nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1225 : &auth_struct.incoming,
1226 : &trustAuthIncoming);
1227 59 : if (!NT_STATUS_IS_OK(nt_status)) {
1228 0 : return nt_status;
1229 : }
1230 : } else {
1231 75 : trustAuthIncoming = data_blob(NULL, 0);
1232 : }
1233 :
1234 134 : if (auth_struct.outgoing.count) {
1235 59 : nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
1236 : &auth_struct.outgoing,
1237 : &trustAuthOutgoing);
1238 59 : if (!NT_STATUS_IS_OK(nt_status)) {
1239 0 : return nt_status;
1240 : }
1241 : } else {
1242 75 : trustAuthOutgoing = data_blob(NULL, 0);
1243 : }
1244 :
1245 134 : ret = ldb_transaction_start(sam_ldb);
1246 134 : if (ret != LDB_SUCCESS) {
1247 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
1248 : }
1249 :
1250 : /* search for the trusted_domain record */
1251 134 : ret = gendb_search(sam_ldb,
1252 : mem_ctx, policy_state->system_dn, &msgs, attrs,
1253 : "(&(objectClass=trustedDomain)(|"
1254 : "(flatname=%s)(trustPartner=%s)"
1255 : "(flatname=%s)(trustPartner=%s)"
1256 : "(securityIdentifier=%s)))",
1257 : dns_encoded, dns_encoded,
1258 : netbios_encoded, netbios_encoded,
1259 : sid_encoded);
1260 134 : if (ret > 0) {
1261 0 : ldb_transaction_cancel(sam_ldb);
1262 0 : return NT_STATUS_OBJECT_NAME_COLLISION;
1263 : }
1264 134 : if (ret < 0) {
1265 0 : ldb_transaction_cancel(sam_ldb);
1266 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
1267 : }
1268 :
1269 134 : msg = ldb_msg_new(mem_ctx);
1270 134 : if (msg == NULL) {
1271 0 : return NT_STATUS_NO_MEMORY;
1272 : }
1273 :
1274 134 : msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
1275 134 : if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", dns_name)) {
1276 0 : ldb_transaction_cancel(sam_ldb);
1277 0 : return NT_STATUS_NO_MEMORY;
1278 : }
1279 :
1280 134 : ret = ldb_msg_add_string(msg, "objectClass", "trustedDomain");
1281 134 : if (ret != LDB_SUCCESS) {
1282 0 : ldb_transaction_cancel(sam_ldb);
1283 0 : return NT_STATUS_NO_MEMORY;;
1284 : }
1285 :
1286 134 : ret = ldb_msg_add_string(msg, "flatname", netbios_name);
1287 134 : if (ret != LDB_SUCCESS) {
1288 0 : ldb_transaction_cancel(sam_ldb);
1289 0 : return NT_STATUS_NO_MEMORY;
1290 : }
1291 :
1292 134 : ret = ldb_msg_add_string(msg, "trustPartner", dns_name);
1293 134 : if (ret != LDB_SUCCESS) {
1294 0 : ldb_transaction_cancel(sam_ldb);
1295 0 : return NT_STATUS_NO_MEMORY;;
1296 : }
1297 :
1298 134 : ret = samdb_msg_add_dom_sid(sam_ldb, mem_ctx, msg, "securityIdentifier",
1299 134 : r->in.info->sid);
1300 134 : if (ret != LDB_SUCCESS) {
1301 0 : ldb_transaction_cancel(sam_ldb);
1302 0 : return NT_STATUS_NO_MEMORY;;
1303 : }
1304 :
1305 134 : ret = samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type);
1306 134 : if (ret != LDB_SUCCESS) {
1307 0 : ldb_transaction_cancel(sam_ldb);
1308 0 : return NT_STATUS_NO_MEMORY;;
1309 : }
1310 :
1311 134 : ret = samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes);
1312 134 : if (ret != LDB_SUCCESS) {
1313 0 : ldb_transaction_cancel(sam_ldb);
1314 0 : return NT_STATUS_NO_MEMORY;;
1315 : }
1316 :
1317 134 : ret = samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction);
1318 134 : if (ret != LDB_SUCCESS) {
1319 0 : ldb_transaction_cancel(sam_ldb);
1320 0 : return NT_STATUS_NO_MEMORY;;
1321 : }
1322 :
1323 134 : if (trustAuthIncoming.data) {
1324 59 : ret = ldb_msg_add_value(msg, "trustAuthIncoming", &trustAuthIncoming, NULL);
1325 59 : if (ret != LDB_SUCCESS) {
1326 0 : ldb_transaction_cancel(sam_ldb);
1327 0 : return NT_STATUS_NO_MEMORY;
1328 : }
1329 : }
1330 134 : if (trustAuthOutgoing.data) {
1331 59 : ret = ldb_msg_add_value(msg, "trustAuthOutgoing", &trustAuthOutgoing, NULL);
1332 59 : if (ret != LDB_SUCCESS) {
1333 0 : ldb_transaction_cancel(sam_ldb);
1334 0 : return NT_STATUS_NO_MEMORY;
1335 : }
1336 : }
1337 :
1338 134 : trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
1339 :
1340 : /* create the trusted_domain */
1341 134 : ret = ldb_add(sam_ldb, msg);
1342 134 : switch (ret) {
1343 134 : case LDB_SUCCESS:
1344 134 : break;
1345 0 : case LDB_ERR_ENTRY_ALREADY_EXISTS:
1346 0 : ldb_transaction_cancel(sam_ldb);
1347 0 : DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1348 : ldb_dn_get_linearized(msg->dn),
1349 : ldb_errstring(sam_ldb)));
1350 0 : return NT_STATUS_DOMAIN_EXISTS;
1351 0 : case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1352 0 : ldb_transaction_cancel(sam_ldb);
1353 0 : DEBUG(0,("Failed to create trusted domain record %s: %s\n",
1354 : ldb_dn_get_linearized(msg->dn),
1355 : ldb_errstring(sam_ldb)));
1356 0 : return NT_STATUS_ACCESS_DENIED;
1357 0 : default:
1358 0 : ldb_transaction_cancel(sam_ldb);
1359 0 : DEBUG(0,("Failed to create user record %s: %s\n",
1360 : ldb_dn_get_linearized(msg->dn),
1361 : ldb_errstring(sam_ldb)));
1362 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
1363 : }
1364 :
1365 134 : if (r->in.info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
1366 0 : struct ldb_dn *user_dn;
1367 : /* Inbound trusts must also create a cn=users object to match */
1368 71 : nt_status = add_trust_user(mem_ctx, sam_ldb,
1369 : policy_state->domain_dn,
1370 : netbios_name,
1371 : &auth_struct.incoming,
1372 : &user_dn);
1373 71 : if (!NT_STATUS_IS_OK(nt_status)) {
1374 0 : ldb_transaction_cancel(sam_ldb);
1375 0 : return nt_status;
1376 : }
1377 :
1378 : /* save the trust user dn */
1379 0 : trusted_domain_state->trusted_domain_user_dn
1380 71 : = talloc_steal(trusted_domain_state, user_dn);
1381 : }
1382 :
1383 134 : ret = ldb_transaction_commit(sam_ldb);
1384 134 : if (ret != LDB_SUCCESS) {
1385 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
1386 : }
1387 :
1388 : /*
1389 : * Notify winbindd that we have a new trust
1390 : */
1391 134 : status = irpc_servers_byname(imsg_ctx,
1392 : mem_ctx,
1393 : "winbind_server",
1394 : &num_server_ids,
1395 : &server_ids);
1396 134 : if (NT_STATUS_IS_OK(status) && num_server_ids >= 1) {
1397 134 : imessaging_send(imsg_ctx,
1398 : server_ids[0],
1399 : MSG_WINBIND_RELOAD_TRUSTED_DOMAINS,
1400 : NULL);
1401 : }
1402 134 : TALLOC_FREE(server_ids);
1403 :
1404 134 : handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN);
1405 134 : if (!handle) {
1406 0 : return NT_STATUS_NO_MEMORY;
1407 : }
1408 :
1409 134 : handle->data = talloc_steal(handle, trusted_domain_state);
1410 :
1411 134 : trusted_domain_state->access_mask = r->in.access_mask;
1412 134 : trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1413 :
1414 134 : *r->out.trustdom_handle = handle->wire_handle;
1415 :
1416 134 : return NT_STATUS_OK;
1417 : }
1418 :
1419 : /*
1420 : lsa_CreateTrustedDomainEx2
1421 : */
1422 62 : static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
1423 : TALLOC_CTX *mem_ctx,
1424 : struct lsa_CreateTrustedDomainEx2 *r)
1425 : {
1426 62 : return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2, NULL);
1427 : }
1428 : /*
1429 : lsa_CreateTrustedDomainEx
1430 : */
1431 36 : static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
1432 : TALLOC_CTX *mem_ctx,
1433 : struct lsa_CreateTrustedDomainEx *r)
1434 : {
1435 36 : struct lsa_CreateTrustedDomainEx2 r2 = {};
1436 :
1437 36 : r2.in.policy_handle = r->in.policy_handle;
1438 36 : r2.in.info = r->in.info;
1439 36 : r2.out.trustdom_handle = r->out.trustdom_handle;
1440 36 : return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX, r->in.auth_info);
1441 : }
1442 :
1443 : /*
1444 : lsa_CreateTrustedDomain
1445 : */
1446 36 : static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1447 : struct lsa_CreateTrustedDomain *r)
1448 : {
1449 36 : struct lsa_CreateTrustedDomainEx2 r2 = {};
1450 :
1451 36 : r2.in.policy_handle = r->in.policy_handle;
1452 36 : r2.in.info = talloc(mem_ctx, struct lsa_TrustDomainInfoInfoEx);
1453 36 : if (!r2.in.info) {
1454 0 : return NT_STATUS_NO_MEMORY;
1455 : }
1456 :
1457 36 : r2.in.info->domain_name = r->in.info->name;
1458 36 : r2.in.info->netbios_name = r->in.info->name;
1459 36 : r2.in.info->sid = r->in.info->sid;
1460 36 : r2.in.info->trust_direction = LSA_TRUST_DIRECTION_OUTBOUND;
1461 36 : r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
1462 36 : r2.in.info->trust_attributes = 0;
1463 :
1464 36 : r2.in.access_mask = r->in.access_mask;
1465 36 : r2.out.trustdom_handle = r->out.trustdom_handle;
1466 :
1467 36 : return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN, NULL);
1468 : }
1469 :
1470 3424 : static NTSTATUS dcesrv_lsa_OpenTrustedDomain_common(
1471 : struct dcesrv_call_state *dce_call,
1472 : TALLOC_CTX *tmp_mem,
1473 : struct lsa_policy_state *policy_state,
1474 : const char *filter,
1475 : uint32_t access_mask,
1476 : struct dcesrv_handle **_handle)
1477 : {
1478 0 : struct lsa_trusted_domain_state *trusted_domain_state;
1479 0 : struct dcesrv_handle *handle;
1480 0 : struct ldb_message **msgs;
1481 3424 : const char *attrs[] = {
1482 : "trustDirection",
1483 : "flatname",
1484 : NULL
1485 : };
1486 0 : uint32_t direction;
1487 0 : int ret;
1488 :
1489 : /* TODO: perform access checks */
1490 :
1491 : /* search for the trusted_domain record */
1492 3424 : ret = gendb_search(policy_state->sam_ldb, tmp_mem,
1493 : policy_state->system_dn,
1494 : &msgs, attrs, "%s", filter);
1495 3424 : if (ret == 0) {
1496 53 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1497 : }
1498 :
1499 3371 : if (ret != 1) {
1500 0 : DEBUG(0,("Found %d records matching %s under %s\n", ret,
1501 : filter,
1502 : ldb_dn_get_linearized(policy_state->system_dn)));
1503 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
1504 : }
1505 :
1506 3371 : trusted_domain_state = talloc_zero(tmp_mem,
1507 : struct lsa_trusted_domain_state);
1508 3371 : if (!trusted_domain_state) {
1509 0 : return NT_STATUS_NO_MEMORY;
1510 : }
1511 3371 : trusted_domain_state->policy = policy_state;
1512 :
1513 3371 : trusted_domain_state->trusted_domain_dn =
1514 3371 : talloc_steal(trusted_domain_state, msgs[0]->dn);
1515 :
1516 3371 : direction = ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0);
1517 3371 : if (direction & LSA_TRUST_DIRECTION_INBOUND) {
1518 1612 : const char *flatname = ldb_msg_find_attr_as_string(msgs[0],
1519 : "flatname", NULL);
1520 :
1521 : /* search for the trusted_domain account */
1522 1612 : ret = gendb_search(policy_state->sam_ldb, tmp_mem,
1523 : policy_state->domain_dn,
1524 : &msgs, attrs,
1525 : "(&(samaccountname=%s$)(objectclass=user)"
1526 : "(userAccountControl:%s:=%u))",
1527 : flatname,
1528 : LDB_OID_COMPARATOR_AND,
1529 : UF_INTERDOMAIN_TRUST_ACCOUNT);
1530 1612 : if (ret == 1) {
1531 1612 : trusted_domain_state->trusted_domain_user_dn =
1532 1612 : talloc_steal(trusted_domain_state, msgs[0]->dn);
1533 : }
1534 : }
1535 :
1536 3371 : handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN);
1537 3371 : if (!handle) {
1538 0 : return NT_STATUS_NO_MEMORY;
1539 : }
1540 :
1541 3371 : handle->data = talloc_steal(handle, trusted_domain_state);
1542 :
1543 3371 : trusted_domain_state->access_mask = access_mask;
1544 3371 : trusted_domain_state->policy = talloc_reference(trusted_domain_state,
1545 : policy_state);
1546 :
1547 3371 : *_handle = handle;
1548 :
1549 3371 : return NT_STATUS_OK;
1550 : }
1551 :
1552 : /*
1553 : lsa_OpenTrustedDomain
1554 : */
1555 1625 : static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1556 : struct lsa_OpenTrustedDomain *r)
1557 : {
1558 0 : struct dcesrv_handle *policy_handle;
1559 0 : struct lsa_policy_state *policy_state;
1560 0 : struct dcesrv_handle *handle;
1561 0 : const char *sid_string;
1562 0 : char *filter;
1563 0 : NTSTATUS status;
1564 :
1565 1625 : DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1566 1625 : ZERO_STRUCTP(r->out.trustdom_handle);
1567 1625 : policy_state = policy_handle->data;
1568 :
1569 1625 : sid_string = dom_sid_string(mem_ctx, r->in.sid);
1570 1625 : if (!sid_string) {
1571 0 : return NT_STATUS_NO_MEMORY;
1572 : }
1573 :
1574 1625 : filter = talloc_asprintf(mem_ctx,
1575 : "(&(securityIdentifier=%s)"
1576 : "(objectclass=trustedDomain))",
1577 : sid_string);
1578 1625 : if (filter == NULL) {
1579 0 : return NT_STATUS_NO_MEMORY;
1580 : }
1581 :
1582 1625 : status = dcesrv_lsa_OpenTrustedDomain_common(dce_call, mem_ctx,
1583 : policy_state,
1584 : filter,
1585 : r->in.access_mask,
1586 : &handle);
1587 1625 : if (!NT_STATUS_IS_OK(status)) {
1588 1 : return status;
1589 : }
1590 :
1591 1624 : *r->out.trustdom_handle = handle->wire_handle;
1592 :
1593 1624 : return NT_STATUS_OK;
1594 : }
1595 :
1596 :
1597 : /*
1598 : lsa_OpenTrustedDomainByName
1599 : */
1600 1799 : static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
1601 : TALLOC_CTX *mem_ctx,
1602 : struct lsa_OpenTrustedDomainByName *r)
1603 : {
1604 0 : struct dcesrv_handle *policy_handle;
1605 0 : struct lsa_policy_state *policy_state;
1606 0 : struct dcesrv_handle *handle;
1607 0 : char *td_name;
1608 0 : char *filter;
1609 0 : NTSTATUS status;
1610 :
1611 1799 : DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1612 1799 : ZERO_STRUCTP(r->out.trustdom_handle);
1613 1799 : policy_state = policy_handle->data;
1614 :
1615 1799 : if (!r->in.name.string) {
1616 0 : return NT_STATUS_INVALID_PARAMETER;
1617 : }
1618 :
1619 : /* search for the trusted_domain record */
1620 1799 : td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
1621 1799 : if (td_name == NULL) {
1622 0 : return NT_STATUS_NO_MEMORY;
1623 : }
1624 :
1625 1799 : filter = talloc_asprintf(mem_ctx,
1626 : "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
1627 : "(objectclass=trustedDomain))",
1628 : td_name, td_name, td_name);
1629 1799 : if (filter == NULL) {
1630 0 : return NT_STATUS_NO_MEMORY;
1631 : }
1632 :
1633 1799 : status = dcesrv_lsa_OpenTrustedDomain_common(dce_call, mem_ctx,
1634 : policy_state,
1635 : filter,
1636 : r->in.access_mask,
1637 : &handle);
1638 1799 : if (!NT_STATUS_IS_OK(status)) {
1639 52 : return status;
1640 : }
1641 :
1642 1747 : *r->out.trustdom_handle = handle->wire_handle;
1643 :
1644 1747 : return NT_STATUS_OK;
1645 : }
1646 :
1647 :
1648 :
1649 : /*
1650 : lsa_SetTrustedDomainInfo
1651 : */
1652 0 : static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1653 : struct lsa_SetTrustedDomainInfo *r)
1654 : {
1655 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1656 : }
1657 :
1658 :
1659 :
1660 : /* parameters 4 to 6 are optional if the dn is a dn of a TDO object,
1661 : * otherwise at least one must be provided */
1662 46 : static NTSTATUS get_tdo(struct ldb_context *sam, TALLOC_CTX *mem_ctx,
1663 : struct ldb_dn *basedn, const char *dns_domain,
1664 : const char *netbios, struct dom_sid2 *sid,
1665 : struct ldb_message ***msgs)
1666 : {
1667 46 : const char *attrs[] = { "flatname", "trustPartner",
1668 : "securityIdentifier", "trustDirection",
1669 : "trustType", "trustAttributes",
1670 : "trustPosixOffset",
1671 : "msDs-supportedEncryptionTypes",
1672 : "msDS-TrustForestTrustInfo",
1673 : NULL
1674 : };
1675 46 : char *dns = NULL;
1676 46 : char *nbn = NULL;
1677 0 : char *filter;
1678 0 : int ret;
1679 :
1680 :
1681 46 : if (dns_domain || netbios || sid) {
1682 24 : filter = talloc_strdup(mem_ctx,
1683 : "(&(objectclass=trustedDomain)(|");
1684 : } else {
1685 22 : filter = talloc_strdup(mem_ctx,
1686 : "(objectclass=trustedDomain)");
1687 : }
1688 :
1689 46 : if (dns_domain) {
1690 24 : dns = ldb_binary_encode_string(mem_ctx, dns_domain);
1691 24 : if (!dns) {
1692 0 : return NT_STATUS_NO_MEMORY;
1693 : }
1694 24 : talloc_asprintf_addbuf(&filter, "(trustPartner=%s)", dns);
1695 : }
1696 46 : if (netbios) {
1697 24 : nbn = ldb_binary_encode_string(mem_ctx, netbios);
1698 24 : if (!nbn) {
1699 0 : return NT_STATUS_NO_MEMORY;
1700 : }
1701 24 : talloc_asprintf_addbuf(&filter, "(flatname=%s)", nbn);
1702 : }
1703 46 : if (sid) {
1704 0 : struct dom_sid_buf buf;
1705 6 : char *sidstr = dom_sid_str_buf(sid, &buf);
1706 6 : talloc_asprintf_addbuf(
1707 : &filter, "(securityIdentifier=%s)", sidstr);
1708 : }
1709 46 : if (dns_domain || netbios || sid) {
1710 24 : talloc_asprintf_addbuf(&filter, "))");
1711 : }
1712 46 : if (filter == NULL) {
1713 0 : return NT_STATUS_NO_MEMORY;
1714 : }
1715 :
1716 46 : ret = gendb_search(sam, mem_ctx, basedn, msgs, attrs, "%s", filter);
1717 46 : if (ret == 0) {
1718 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1719 : }
1720 :
1721 46 : if (ret != 1) {
1722 0 : return NT_STATUS_OBJECT_NAME_COLLISION;
1723 : }
1724 :
1725 46 : return NT_STATUS_OK;
1726 : }
1727 :
1728 43 : static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx,
1729 : struct ldb_context *sam_ldb,
1730 : struct ldb_message *orig,
1731 : struct ldb_message *dest,
1732 : const char *attribute,
1733 : uint32_t value,
1734 : uint32_t *orig_value)
1735 : {
1736 0 : const struct ldb_val *orig_val;
1737 43 : uint32_t orig_uint = 0;
1738 43 : unsigned int flags = 0;
1739 0 : int ret;
1740 43 : int error = 0;
1741 :
1742 43 : orig_val = ldb_msg_find_ldb_val(orig, attribute);
1743 43 : if (!orig_val || !orig_val->data) {
1744 : /* add new attribute */
1745 28 : flags = LDB_FLAG_MOD_ADD;
1746 :
1747 : } else {
1748 15 : orig_uint = smb_strtoul((const char *)orig_val->data,
1749 : NULL,
1750 : 0,
1751 : &error,
1752 : SMB_STR_STANDARD);
1753 15 : if (error != 0 || orig_uint != value) {
1754 : /* replace also if can't get value */
1755 0 : flags = LDB_FLAG_MOD_REPLACE;
1756 : }
1757 : }
1758 :
1759 43 : if (flags == 0) {
1760 : /* stored value is identical, nothing to change */
1761 15 : goto done;
1762 : }
1763 :
1764 28 : ret = samdb_msg_append_uint(sam_ldb, dest, dest, attribute, value, flags);
1765 28 : if (ret != LDB_SUCCESS) {
1766 0 : return NT_STATUS_NO_MEMORY;
1767 : }
1768 :
1769 28 : done:
1770 43 : if (orig_value) {
1771 12 : *orig_value = orig_uint;
1772 : }
1773 43 : return NT_STATUS_OK;
1774 : }
1775 :
1776 0 : static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx,
1777 : struct ldb_context *sam_ldb,
1778 : struct ldb_dn *base_dn,
1779 : bool delete_user,
1780 : const char *netbios_name,
1781 : struct trustAuthInOutBlob *in)
1782 : {
1783 0 : const char *attrs[] = { "userAccountControl", NULL };
1784 0 : struct ldb_message **msgs;
1785 0 : struct ldb_message *msg;
1786 0 : uint32_t uac;
1787 0 : uint32_t i;
1788 0 : int ret;
1789 :
1790 0 : ret = gendb_search(sam_ldb, mem_ctx,
1791 : base_dn, &msgs, attrs,
1792 : "samAccountName=%s$", netbios_name);
1793 0 : if (ret > 1) {
1794 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
1795 : }
1796 :
1797 0 : if (ret == 0) {
1798 0 : if (delete_user) {
1799 0 : return NT_STATUS_OK;
1800 : }
1801 :
1802 : /* ok no existing user, add it from scratch */
1803 0 : return add_trust_user(mem_ctx, sam_ldb, base_dn,
1804 : netbios_name, in, NULL);
1805 : }
1806 :
1807 : /* check user is what we are looking for */
1808 0 : uac = ldb_msg_find_attr_as_uint(msgs[0],
1809 : "userAccountControl", 0);
1810 0 : if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
1811 0 : return NT_STATUS_OBJECT_NAME_COLLISION;
1812 : }
1813 :
1814 0 : if (delete_user) {
1815 0 : ret = ldb_delete(sam_ldb, msgs[0]->dn);
1816 0 : switch (ret) {
1817 0 : case LDB_SUCCESS:
1818 0 : return NT_STATUS_OK;
1819 0 : case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1820 0 : return NT_STATUS_ACCESS_DENIED;
1821 0 : default:
1822 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
1823 : }
1824 : }
1825 :
1826 : /* entry exists, just modify secret if any */
1827 0 : if (in == NULL || in->count == 0) {
1828 0 : return NT_STATUS_OK;
1829 : }
1830 :
1831 0 : msg = ldb_msg_new(mem_ctx);
1832 0 : if (!msg) {
1833 0 : return NT_STATUS_NO_MEMORY;
1834 : }
1835 0 : msg->dn = msgs[0]->dn;
1836 :
1837 0 : for (i = 0; i < in->count; i++) {
1838 0 : const char *attribute;
1839 0 : struct ldb_val v;
1840 0 : switch (in->current.array[i].AuthType) {
1841 0 : case TRUST_AUTH_TYPE_NT4OWF:
1842 0 : attribute = "unicodePwd";
1843 0 : v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
1844 0 : v.length = 16;
1845 0 : break;
1846 0 : case TRUST_AUTH_TYPE_CLEAR:
1847 0 : attribute = "clearTextPassword";
1848 0 : v.data = in->current.array[i].AuthInfo.clear.password;
1849 0 : v.length = in->current.array[i].AuthInfo.clear.size;
1850 0 : break;
1851 0 : default:
1852 0 : continue;
1853 : }
1854 :
1855 0 : ret = ldb_msg_append_value(msg, attribute, &v, LDB_FLAG_MOD_REPLACE);
1856 0 : if (ret != LDB_SUCCESS) {
1857 0 : return NT_STATUS_NO_MEMORY;
1858 : }
1859 : }
1860 :
1861 : /* create the trusted_domain user account */
1862 0 : ret = ldb_modify(sam_ldb, msg);
1863 0 : if (ret != LDB_SUCCESS) {
1864 0 : DEBUG(0,("Failed to create user record %s: %s\n",
1865 : ldb_dn_get_linearized(msg->dn),
1866 : ldb_errstring(sam_ldb)));
1867 :
1868 0 : switch (ret) {
1869 0 : case LDB_ERR_ENTRY_ALREADY_EXISTS:
1870 0 : return NT_STATUS_DOMAIN_EXISTS;
1871 0 : case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
1872 0 : return NT_STATUS_ACCESS_DENIED;
1873 0 : default:
1874 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
1875 : }
1876 : }
1877 :
1878 0 : return NT_STATUS_OK;
1879 : }
1880 :
1881 :
1882 40 : static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call,
1883 : struct lsa_policy_state *p_state,
1884 : TALLOC_CTX *mem_ctx,
1885 : struct ldb_message *dom_msg,
1886 : enum lsa_TrustDomInfoEnum level,
1887 : union lsa_TrustedDomainInfo *info)
1888 : {
1889 40 : uint32_t *posix_offset = NULL;
1890 40 : struct lsa_TrustDomainInfoInfoEx *info_ex = NULL;
1891 40 : struct lsa_TrustDomainInfoAuthInfo *auth_info = NULL;
1892 40 : struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
1893 40 : uint32_t *enc_types = NULL;
1894 0 : DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
1895 0 : struct trustDomainPasswords auth_struct;
1896 40 : struct trustAuthInOutBlob *current_passwords = NULL;
1897 0 : NTSTATUS nt_status;
1898 0 : struct ldb_message **msgs;
1899 0 : struct ldb_message *msg;
1900 40 : bool add_outgoing = false;
1901 40 : bool add_incoming = false;
1902 40 : bool del_outgoing = false;
1903 40 : bool del_incoming = false;
1904 40 : bool del_forest_info = false;
1905 40 : bool in_transaction = false;
1906 0 : int ret;
1907 0 : bool am_rodc;
1908 :
1909 40 : switch (level) {
1910 3 : case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1911 3 : posix_offset = &info->posix_offset.posix_offset;
1912 3 : break;
1913 3 : case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1914 3 : info_ex = &info->info_ex;
1915 3 : break;
1916 0 : case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
1917 0 : auth_info = &info->auth_info;
1918 0 : break;
1919 3 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1920 3 : posix_offset = &info->full_info.posix_offset.posix_offset;
1921 3 : info_ex = &info->full_info.info_ex;
1922 3 : auth_info = &info->full_info.auth_info;
1923 3 : break;
1924 0 : case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
1925 0 : auth_info_int = &info->auth_info_internal;
1926 0 : break;
1927 0 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
1928 0 : posix_offset = &info->full_info_internal.posix_offset.posix_offset;
1929 0 : info_ex = &info->full_info_internal.info_ex;
1930 0 : auth_info_int = &info->full_info_internal.auth_info;
1931 0 : break;
1932 25 : case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
1933 25 : enc_types = &info->enc_types.enc_types;
1934 25 : break;
1935 6 : default:
1936 6 : return NT_STATUS_INVALID_PARAMETER;
1937 : }
1938 :
1939 34 : if (auth_info) {
1940 3 : nt_status = auth_info_2_auth_blob(mem_ctx, auth_info,
1941 : &trustAuthIncoming,
1942 : &trustAuthOutgoing);
1943 3 : if (!NT_STATUS_IS_OK(nt_status)) {
1944 0 : return nt_status;
1945 : }
1946 3 : if (trustAuthIncoming.data) {
1947 : /* This does the decode of some of this twice, but it is easier that way */
1948 0 : nt_status = auth_info_2_trustauth_inout(mem_ctx,
1949 : auth_info->incoming_count,
1950 : auth_info->incoming_current_auth_info,
1951 : NULL,
1952 : ¤t_passwords);
1953 0 : if (!NT_STATUS_IS_OK(nt_status)) {
1954 0 : return nt_status;
1955 : }
1956 : }
1957 : }
1958 :
1959 : /* decode auth_info_int if set */
1960 34 : if (auth_info_int) {
1961 :
1962 : /* now decrypt blob */
1963 0 : auth_blob = data_blob_const(auth_info_int->auth_blob.data,
1964 0 : auth_info_int->auth_blob.size);
1965 :
1966 0 : nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
1967 : &auth_blob, &auth_struct);
1968 0 : if (!NT_STATUS_IS_OK(nt_status)) {
1969 0 : return nt_status;
1970 : }
1971 : }
1972 :
1973 34 : if (info_ex) {
1974 : /* verify data matches */
1975 6 : if (info_ex->trust_attributes &
1976 : LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
1977 : /* TODO: check what behavior level we have */
1978 6 : if (strcasecmp_m(p_state->domain_dns,
1979 : p_state->forest_dns) != 0) {
1980 0 : return NT_STATUS_INVALID_DOMAIN_STATE;
1981 : }
1982 : }
1983 :
1984 6 : ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
1985 6 : if (ret == LDB_SUCCESS && am_rodc) {
1986 0 : return NT_STATUS_NO_SUCH_DOMAIN;
1987 : }
1988 :
1989 : /* verify only one object matches the dns/netbios/sid
1990 : * triplet and that this is the one we already have */
1991 6 : nt_status = get_tdo(p_state->sam_ldb, mem_ctx,
1992 : p_state->system_dn,
1993 : info_ex->domain_name.string,
1994 : info_ex->netbios_name.string,
1995 : info_ex->sid, &msgs);
1996 6 : if (!NT_STATUS_IS_OK(nt_status)) {
1997 0 : return nt_status;
1998 : }
1999 6 : if (ldb_dn_compare(dom_msg->dn, msgs[0]->dn) != 0) {
2000 0 : return NT_STATUS_OBJECT_NAME_COLLISION;
2001 : }
2002 6 : talloc_free(msgs);
2003 : }
2004 :
2005 : /* TODO: should we fetch previous values from the existing entry
2006 : * and append them ? */
2007 34 : if (auth_info_int && auth_struct.incoming.count) {
2008 0 : nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
2009 : &auth_struct.incoming,
2010 : &trustAuthIncoming);
2011 0 : if (!NT_STATUS_IS_OK(nt_status)) {
2012 0 : return nt_status;
2013 : }
2014 :
2015 0 : current_passwords = &auth_struct.incoming;
2016 :
2017 : } else {
2018 34 : trustAuthIncoming = data_blob(NULL, 0);
2019 : }
2020 :
2021 34 : if (auth_info_int && auth_struct.outgoing.count) {
2022 0 : nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
2023 : &auth_struct.outgoing,
2024 : &trustAuthOutgoing);
2025 0 : if (!NT_STATUS_IS_OK(nt_status)) {
2026 0 : return nt_status;
2027 : }
2028 : } else {
2029 34 : trustAuthOutgoing = data_blob(NULL, 0);
2030 : }
2031 :
2032 34 : msg = ldb_msg_new(mem_ctx);
2033 34 : if (msg == NULL) {
2034 0 : return NT_STATUS_NO_MEMORY;
2035 : }
2036 34 : msg->dn = dom_msg->dn;
2037 :
2038 34 : if (posix_offset) {
2039 6 : nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2040 : dom_msg, msg,
2041 : "trustPosixOffset",
2042 : *posix_offset, NULL);
2043 6 : if (!NT_STATUS_IS_OK(nt_status)) {
2044 0 : return nt_status;
2045 : }
2046 : }
2047 :
2048 34 : if (info_ex) {
2049 0 : uint32_t origattrs;
2050 0 : uint32_t changed_attrs;
2051 0 : uint32_t origdir;
2052 0 : int origtype;
2053 :
2054 6 : nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2055 : dom_msg, msg,
2056 : "trustDirection",
2057 : info_ex->trust_direction,
2058 : &origdir);
2059 6 : if (!NT_STATUS_IS_OK(nt_status)) {
2060 0 : return nt_status;
2061 : }
2062 :
2063 6 : if (info_ex->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
2064 6 : if (auth_info != NULL && trustAuthIncoming.length > 0) {
2065 0 : add_incoming = true;
2066 : }
2067 : }
2068 6 : if (info_ex->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) {
2069 6 : if (auth_info != NULL && trustAuthOutgoing.length > 0) {
2070 0 : add_outgoing = true;
2071 : }
2072 : }
2073 :
2074 6 : if ((origdir & LSA_TRUST_DIRECTION_INBOUND) &&
2075 6 : !(info_ex->trust_direction & LSA_TRUST_DIRECTION_INBOUND)) {
2076 0 : del_incoming = true;
2077 : }
2078 6 : if ((origdir & LSA_TRUST_DIRECTION_OUTBOUND) &&
2079 6 : !(info_ex->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND)) {
2080 0 : del_outgoing = true;
2081 : }
2082 :
2083 6 : origtype = ldb_msg_find_attr_as_int(dom_msg, "trustType", -1);
2084 6 : if (origtype == -1 || origtype != info_ex->trust_type) {
2085 0 : DEBUG(1, ("Attempted to change trust type! "
2086 : "Operation not handled\n"));
2087 0 : return NT_STATUS_INVALID_PARAMETER;
2088 : }
2089 :
2090 6 : nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2091 : dom_msg, msg,
2092 : "trustAttributes",
2093 : info_ex->trust_attributes,
2094 : &origattrs);
2095 6 : if (!NT_STATUS_IS_OK(nt_status)) {
2096 0 : return nt_status;
2097 : }
2098 : /* TODO: check forestFunctionality from ldb opaque */
2099 : /* TODO: check what is set makes sense */
2100 :
2101 6 : changed_attrs = origattrs ^ info_ex->trust_attributes;
2102 6 : if (changed_attrs & ~LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
2103 : /*
2104 : * For now we only allow
2105 : * LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE to be changed.
2106 : *
2107 : * TODO: we may need to support more attribute changes
2108 : */
2109 0 : DEBUG(1, ("Attempted to change trust attributes "
2110 : "(0x%08x != 0x%08x)! "
2111 : "Operation not handled yet...\n",
2112 : (unsigned)origattrs,
2113 : (unsigned)info_ex->trust_attributes));
2114 0 : return NT_STATUS_INVALID_PARAMETER;
2115 : }
2116 :
2117 6 : if (!(info_ex->trust_attributes &
2118 : LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE))
2119 : {
2120 0 : struct ldb_message_element *orig_forest_el = NULL;
2121 :
2122 0 : orig_forest_el = ldb_msg_find_element(dom_msg,
2123 : "msDS-TrustForestTrustInfo");
2124 0 : if (orig_forest_el != NULL) {
2125 0 : del_forest_info = true;
2126 : }
2127 : }
2128 : }
2129 :
2130 34 : if (enc_types) {
2131 25 : nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
2132 : dom_msg, msg,
2133 : "msDS-SupportedEncryptionTypes",
2134 : *enc_types, NULL);
2135 25 : if (!NT_STATUS_IS_OK(nt_status)) {
2136 0 : return nt_status;
2137 : }
2138 : }
2139 :
2140 34 : if (add_incoming || del_incoming) {
2141 0 : if (add_incoming) {
2142 0 : ret = ldb_msg_append_value(msg, "trustAuthIncoming",
2143 : &trustAuthIncoming, LDB_FLAG_MOD_REPLACE);
2144 0 : if (ret != LDB_SUCCESS) {
2145 0 : return NT_STATUS_NO_MEMORY;
2146 : }
2147 : } else {
2148 0 : ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
2149 : LDB_FLAG_MOD_REPLACE, NULL);
2150 0 : if (ret != LDB_SUCCESS) {
2151 0 : return NT_STATUS_NO_MEMORY;
2152 : }
2153 : }
2154 : }
2155 34 : if (add_outgoing || del_outgoing) {
2156 0 : if (add_outgoing) {
2157 0 : ret = ldb_msg_append_value(msg, "trustAuthOutgoing",
2158 : &trustAuthOutgoing, LDB_FLAG_MOD_REPLACE);
2159 0 : if (ret != LDB_SUCCESS) {
2160 0 : return NT_STATUS_NO_MEMORY;
2161 : }
2162 : } else {
2163 0 : ret = ldb_msg_add_empty(msg, "trustAuthOutgoing",
2164 : LDB_FLAG_MOD_REPLACE, NULL);
2165 0 : if (ret != LDB_SUCCESS) {
2166 0 : return NT_STATUS_NO_MEMORY;
2167 : }
2168 : }
2169 : }
2170 34 : if (del_forest_info) {
2171 0 : ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo",
2172 : LDB_FLAG_MOD_REPLACE, NULL);
2173 0 : if (ret != LDB_SUCCESS) {
2174 0 : return NT_STATUS_NO_MEMORY;
2175 : }
2176 : }
2177 :
2178 : /* start transaction */
2179 34 : ret = ldb_transaction_start(p_state->sam_ldb);
2180 34 : if (ret != LDB_SUCCESS) {
2181 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
2182 : }
2183 34 : in_transaction = true;
2184 :
2185 34 : if (msg->num_elements) {
2186 28 : ret = ldb_modify(p_state->sam_ldb, msg);
2187 28 : if (ret != LDB_SUCCESS) {
2188 0 : DEBUG(1,("Failed to modify trusted domain record %s: %s\n",
2189 : ldb_dn_get_linearized(msg->dn),
2190 : ldb_errstring(p_state->sam_ldb)));
2191 0 : nt_status = dsdb_ldb_err_to_ntstatus(ret);
2192 0 : goto done;
2193 : }
2194 : }
2195 :
2196 34 : if (add_incoming || del_incoming) {
2197 0 : const char *netbios_name;
2198 :
2199 0 : netbios_name = ldb_msg_find_attr_as_string(dom_msg,
2200 : "flatname", NULL);
2201 0 : if (!netbios_name) {
2202 0 : nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
2203 0 : goto done;
2204 : }
2205 :
2206 : /* We use trustAuthIncoming.data to indicate that auth_struct.incoming is valid */
2207 0 : nt_status = update_trust_user(mem_ctx,
2208 : p_state->sam_ldb,
2209 : p_state->domain_dn,
2210 : del_incoming,
2211 : netbios_name,
2212 : current_passwords);
2213 0 : if (!NT_STATUS_IS_OK(nt_status)) {
2214 0 : goto done;
2215 : }
2216 : }
2217 :
2218 : /* ok, all fine, commit transaction and return */
2219 34 : ret = ldb_transaction_commit(p_state->sam_ldb);
2220 34 : if (ret != LDB_SUCCESS) {
2221 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
2222 : }
2223 34 : in_transaction = false;
2224 :
2225 34 : nt_status = NT_STATUS_OK;
2226 :
2227 34 : done:
2228 34 : if (in_transaction) {
2229 0 : ldb_transaction_cancel(p_state->sam_ldb);
2230 : }
2231 34 : return nt_status;
2232 : }
2233 :
2234 : /*
2235 : lsa_SetInformationTrustedDomain
2236 : */
2237 22 : static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(
2238 : struct dcesrv_call_state *dce_call,
2239 : TALLOC_CTX *mem_ctx,
2240 : struct lsa_SetInformationTrustedDomain *r)
2241 : {
2242 0 : struct dcesrv_handle *h;
2243 0 : struct lsa_trusted_domain_state *td_state;
2244 0 : struct ldb_message **msgs;
2245 0 : NTSTATUS nt_status;
2246 :
2247 22 : DCESRV_PULL_HANDLE(h, r->in.trustdom_handle,
2248 : LSA_HANDLE_TRUSTED_DOMAIN);
2249 :
2250 22 : td_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
2251 :
2252 : /* get the trusted domain object */
2253 22 : nt_status = get_tdo(td_state->policy->sam_ldb, mem_ctx,
2254 : td_state->trusted_domain_dn,
2255 : NULL, NULL, NULL, &msgs);
2256 22 : if (!NT_STATUS_IS_OK(nt_status)) {
2257 0 : if (NT_STATUS_EQUAL(nt_status,
2258 : NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2259 0 : return nt_status;
2260 : }
2261 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
2262 : }
2263 :
2264 22 : return setInfoTrustedDomain_base(dce_call, td_state->policy, mem_ctx,
2265 : msgs[0], r->in.level, r->in.info);
2266 : }
2267 :
2268 :
2269 : /*
2270 : lsa_DeleteTrustedDomain
2271 : */
2272 112 : static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2273 : struct lsa_DeleteTrustedDomain *r)
2274 : {
2275 0 : NTSTATUS status;
2276 112 : struct lsa_OpenTrustedDomain opn = {{0},{0}};
2277 0 : struct lsa_DeleteObject del;
2278 0 : struct dcesrv_handle *h;
2279 :
2280 112 : opn.in.handle = r->in.handle;
2281 112 : opn.in.sid = r->in.dom_sid;
2282 112 : opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2283 112 : opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2284 112 : if (!opn.out.trustdom_handle) {
2285 0 : return NT_STATUS_NO_MEMORY;
2286 : }
2287 112 : status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2288 112 : if (!NT_STATUS_IS_OK(status)) {
2289 0 : return status;
2290 : }
2291 :
2292 112 : DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2293 112 : talloc_steal(mem_ctx, h);
2294 :
2295 112 : del.in.handle = opn.out.trustdom_handle;
2296 112 : del.out.handle = opn.out.trustdom_handle;
2297 112 : status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
2298 112 : if (!NT_STATUS_IS_OK(status)) {
2299 0 : return status;
2300 : }
2301 112 : return NT_STATUS_OK;
2302 : }
2303 :
2304 2041 : static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
2305 : struct ldb_message *msg,
2306 : struct lsa_TrustDomainInfoInfoEx *info_ex)
2307 : {
2308 0 : info_ex->domain_name.string
2309 2041 : = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
2310 0 : info_ex->netbios_name.string
2311 2041 : = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2312 0 : info_ex->sid
2313 2041 : = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2314 0 : info_ex->trust_direction
2315 2041 : = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
2316 0 : info_ex->trust_type
2317 2041 : = ldb_msg_find_attr_as_int(msg, "trustType", 0);
2318 0 : info_ex->trust_attributes
2319 2041 : = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
2320 2041 : return NT_STATUS_OK;
2321 : }
2322 :
2323 : /*
2324 : lsa_QueryTrustedDomainInfo
2325 : */
2326 5962 : static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2327 : struct lsa_QueryTrustedDomainInfo *r)
2328 : {
2329 5962 : union lsa_TrustedDomainInfo *info = NULL;
2330 0 : struct dcesrv_handle *h;
2331 0 : struct lsa_trusted_domain_state *trusted_domain_state;
2332 0 : struct ldb_message *msg;
2333 0 : int ret;
2334 0 : struct ldb_message **res;
2335 5962 : const char *attrs[] = {
2336 : "flatname",
2337 : "trustPartner",
2338 : "securityIdentifier",
2339 : "trustDirection",
2340 : "trustType",
2341 : "trustAttributes",
2342 : "msDs-supportedEncryptionTypes",
2343 : NULL
2344 : };
2345 :
2346 5962 : DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
2347 :
2348 5962 : trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
2349 :
2350 : /* pull all the user attributes */
2351 5962 : ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
2352 : trusted_domain_state->trusted_domain_dn, &res, attrs);
2353 5962 : if (ret != 1) {
2354 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
2355 : }
2356 5962 : msg = res[0];
2357 :
2358 5962 : info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
2359 5962 : if (!info) {
2360 0 : return NT_STATUS_NO_MEMORY;
2361 : }
2362 5962 : *r->out.info = info;
2363 :
2364 5962 : switch (r->in.level) {
2365 435 : case LSA_TRUSTED_DOMAIN_INFO_NAME:
2366 0 : info->name.netbios_name.string
2367 435 : = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2368 435 : break;
2369 435 : case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
2370 0 : info->posix_offset.posix_offset
2371 435 : = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
2372 435 : break;
2373 : #if 0 /* Win2k3 doesn't implement this */
2374 : case LSA_TRUSTED_DOMAIN_INFO_BASIC:
2375 : r->out.info->info_basic.netbios_name.string
2376 : = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
2377 : r->out.info->info_basic.sid
2378 : = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
2379 : break;
2380 : #endif
2381 715 : case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
2382 4633 : return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
2383 :
2384 459 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
2385 459 : ZERO_STRUCT(info->full_info);
2386 459 : return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
2387 435 : case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
2388 435 : ZERO_STRUCT(info->full_info2_internal);
2389 0 : info->full_info2_internal.posix_offset.posix_offset
2390 435 : = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
2391 435 : return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
2392 :
2393 459 : case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
2394 0 : info->enc_types.enc_types
2395 459 : = ldb_msg_find_attr_as_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
2396 459 : break;
2397 :
2398 864 : case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
2399 : case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
2400 : /* oops, we don't want to return the info after all */
2401 864 : talloc_free(info);
2402 864 : *r->out.info = NULL;
2403 864 : return NT_STATUS_INVALID_PARAMETER;
2404 2160 : default:
2405 : /* oops, we don't want to return the info after all */
2406 2160 : talloc_free(info);
2407 2160 : *r->out.info = NULL;
2408 2160 : return NT_STATUS_INVALID_INFO_CLASS;
2409 : }
2410 :
2411 1329 : return NT_STATUS_OK;
2412 : }
2413 :
2414 :
2415 : /*
2416 : lsa_QueryTrustedDomainInfoBySid
2417 : */
2418 1405 : static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2419 : struct lsa_QueryTrustedDomainInfoBySid *r)
2420 : {
2421 0 : NTSTATUS status;
2422 1405 : struct lsa_OpenTrustedDomain opn = {{0},{0}};
2423 0 : struct lsa_QueryTrustedDomainInfo query;
2424 0 : struct dcesrv_handle *h;
2425 :
2426 1405 : opn.in.handle = r->in.handle;
2427 1405 : opn.in.sid = r->in.dom_sid;
2428 1405 : opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2429 1405 : opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2430 1405 : if (!opn.out.trustdom_handle) {
2431 0 : return NT_STATUS_NO_MEMORY;
2432 : }
2433 1405 : status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
2434 1405 : if (!NT_STATUS_IS_OK(status)) {
2435 1 : return status;
2436 : }
2437 :
2438 : /* Ensure this handle goes away at the end of this call */
2439 1404 : DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2440 1404 : talloc_steal(mem_ctx, h);
2441 :
2442 1404 : query.in.trustdom_handle = opn.out.trustdom_handle;
2443 1404 : query.in.level = r->in.level;
2444 1404 : query.out.info = r->out.info;
2445 1404 : status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2446 1404 : if (!NT_STATUS_IS_OK(status)) {
2447 756 : return status;
2448 : }
2449 :
2450 648 : return NT_STATUS_OK;
2451 : }
2452 :
2453 : /*
2454 : lsa_SetTrustedDomainInfoByName
2455 : */
2456 18 : static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2457 : TALLOC_CTX *mem_ctx,
2458 : struct lsa_SetTrustedDomainInfoByName *r)
2459 : {
2460 0 : struct dcesrv_handle *policy_handle;
2461 0 : struct lsa_policy_state *policy_state;
2462 0 : struct ldb_message **msgs;
2463 0 : NTSTATUS nt_status;
2464 :
2465 18 : DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2466 18 : policy_state = policy_handle->data;
2467 :
2468 : /* get the trusted domain object */
2469 18 : nt_status = get_tdo(policy_state->sam_ldb, mem_ctx,
2470 : policy_state->domain_dn,
2471 18 : r->in.trusted_domain->string,
2472 18 : r->in.trusted_domain->string,
2473 : NULL, &msgs);
2474 18 : if (!NT_STATUS_IS_OK(nt_status)) {
2475 0 : if (NT_STATUS_EQUAL(nt_status,
2476 : NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2477 0 : return nt_status;
2478 : }
2479 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
2480 : }
2481 :
2482 18 : return setInfoTrustedDomain_base(dce_call, policy_state, mem_ctx,
2483 : msgs[0], r->in.level, r->in.info);
2484 : }
2485 :
2486 : /*
2487 : lsa_QueryTrustedDomainInfoByName
2488 : */
2489 1691 : static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
2490 : TALLOC_CTX *mem_ctx,
2491 : struct lsa_QueryTrustedDomainInfoByName *r)
2492 : {
2493 0 : NTSTATUS status;
2494 1691 : struct lsa_OpenTrustedDomainByName opn = {{0},{0}};
2495 0 : struct lsa_QueryTrustedDomainInfo query;
2496 0 : struct dcesrv_handle *h;
2497 :
2498 1691 : opn.in.handle = r->in.handle;
2499 1691 : opn.in.name = *r->in.trusted_domain;
2500 1691 : opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
2501 1691 : opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
2502 1691 : if (!opn.out.trustdom_handle) {
2503 0 : return NT_STATUS_NO_MEMORY;
2504 : }
2505 1691 : status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
2506 1691 : if (!NT_STATUS_IS_OK(status)) {
2507 52 : return status;
2508 : }
2509 :
2510 : /* Ensure this handle goes away at the end of this call */
2511 1639 : DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
2512 1639 : talloc_steal(mem_ctx, h);
2513 :
2514 1639 : query.in.trustdom_handle = opn.out.trustdom_handle;
2515 1639 : query.in.level = r->in.level;
2516 1639 : query.out.info = r->out.info;
2517 1639 : status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
2518 1639 : if (!NT_STATUS_IS_OK(status)) {
2519 756 : return status;
2520 : }
2521 :
2522 883 : return NT_STATUS_OK;
2523 : }
2524 :
2525 : /*
2526 : lsa_CloseTrustedDomainEx
2527 : */
2528 108 : static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
2529 : TALLOC_CTX *mem_ctx,
2530 : struct lsa_CloseTrustedDomainEx *r)
2531 : {
2532 : /* The result of a bad hair day from an IDL programmer? Not
2533 : * implemented in Win2k3. You should always just lsa_Close
2534 : * anyway. */
2535 108 : return NT_STATUS_NOT_IMPLEMENTED;
2536 : }
2537 :
2538 :
2539 : /*
2540 : comparison function for sorting lsa_DomainInformation array
2541 : */
2542 1104 : static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
2543 : {
2544 1104 : return strcasecmp_m(e1->name.string, e2->name.string);
2545 : }
2546 :
2547 : /*
2548 : lsa_EnumTrustDom
2549 : */
2550 66 : static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2551 : struct lsa_EnumTrustDom *r)
2552 : {
2553 3 : struct dcesrv_handle *policy_handle;
2554 3 : struct lsa_DomainInfo *entries;
2555 3 : struct lsa_policy_state *policy_state;
2556 3 : struct ldb_message **domains;
2557 66 : const char *attrs[] = {
2558 : "flatname",
2559 : "securityIdentifier",
2560 : NULL
2561 : };
2562 :
2563 :
2564 3 : int count, i;
2565 :
2566 66 : *r->out.resume_handle = 0;
2567 :
2568 66 : r->out.domains->domains = NULL;
2569 66 : r->out.domains->count = 0;
2570 :
2571 66 : DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2572 :
2573 66 : policy_state = policy_handle->data;
2574 :
2575 : /* search for all users in this domain. This could possibly be cached and
2576 : resumed based on resume_key */
2577 66 : count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2578 : "objectclass=trustedDomain");
2579 66 : if (count < 0) {
2580 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
2581 : }
2582 :
2583 : /* convert to lsa_TrustInformation format */
2584 66 : entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
2585 66 : if (!entries) {
2586 0 : return NT_STATUS_NO_MEMORY;
2587 : }
2588 498 : for (i=0;i<count;i++) {
2589 432 : entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
2590 432 : entries[i].name.string = ldb_msg_find_attr_as_string(domains[i], "flatname", NULL);
2591 : }
2592 :
2593 : /* sort the results by name */
2594 66 : TYPESAFE_QSORT(entries, count, compare_DomainInfo);
2595 :
2596 66 : if (*r->in.resume_handle >= count) {
2597 30 : *r->out.resume_handle = -1;
2598 :
2599 30 : return NT_STATUS_NO_MORE_ENTRIES;
2600 : }
2601 :
2602 : /* return the rest, limit by max_size. Note that we
2603 : use the w2k3 element size value of 60 */
2604 36 : r->out.domains->count = count - *r->in.resume_handle;
2605 36 : r->out.domains->count = MIN(r->out.domains->count,
2606 : 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
2607 :
2608 36 : r->out.domains->domains = entries + *r->in.resume_handle;
2609 :
2610 36 : if (r->out.domains->count < count - *r->in.resume_handle) {
2611 27 : *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2612 27 : return STATUS_MORE_ENTRIES;
2613 : }
2614 :
2615 : /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
2616 : * always be larger than the previous input resume handle, in
2617 : * particular when hitting the last query it is vital to set the
2618 : * resume handle correctly to avoid infinite client loops, as
2619 : * seen e.g. with Windows XP SP3 when resume handle is 0 and
2620 : * status is NT_STATUS_OK - gd */
2621 :
2622 9 : *r->out.resume_handle = (uint32_t)-1;
2623 :
2624 9 : return NT_STATUS_OK;
2625 : }
2626 :
2627 : /*
2628 : comparison function for sorting lsa_DomainInformation array
2629 : */
2630 1104 : static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
2631 : {
2632 1104 : return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
2633 : }
2634 :
2635 : /*
2636 : lsa_EnumTrustedDomainsEx
2637 : */
2638 42 : static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2639 : struct lsa_EnumTrustedDomainsEx *r)
2640 : {
2641 0 : struct dcesrv_handle *policy_handle;
2642 0 : struct lsa_TrustDomainInfoInfoEx *entries;
2643 0 : struct lsa_policy_state *policy_state;
2644 0 : struct ldb_message **domains;
2645 42 : const char *attrs[] = {
2646 : "flatname",
2647 : "trustPartner",
2648 : "securityIdentifier",
2649 : "trustDirection",
2650 : "trustType",
2651 : "trustAttributes",
2652 : NULL
2653 : };
2654 0 : NTSTATUS nt_status;
2655 :
2656 0 : int count, i;
2657 :
2658 42 : *r->out.resume_handle = 0;
2659 :
2660 42 : r->out.domains->domains = NULL;
2661 42 : r->out.domains->count = 0;
2662 :
2663 42 : DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2664 :
2665 42 : policy_state = policy_handle->data;
2666 :
2667 : /* search for all users in this domain. This could possibly be cached and
2668 : resumed based on resume_key */
2669 42 : count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
2670 : "objectclass=trustedDomain");
2671 42 : if (count < 0) {
2672 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
2673 : }
2674 :
2675 : /* convert to lsa_DomainInformation format */
2676 42 : entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
2677 42 : if (!entries) {
2678 0 : return NT_STATUS_NO_MEMORY;
2679 : }
2680 474 : for (i=0;i<count;i++) {
2681 432 : nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
2682 432 : if (!NT_STATUS_IS_OK(nt_status)) {
2683 0 : return nt_status;
2684 : }
2685 : }
2686 :
2687 : /* sort the results by name */
2688 42 : TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
2689 :
2690 42 : if (*r->in.resume_handle >= count) {
2691 6 : *r->out.resume_handle = -1;
2692 :
2693 6 : return NT_STATUS_NO_MORE_ENTRIES;
2694 : }
2695 :
2696 : /* return the rest, limit by max_size. Note that we
2697 : use the w2k3 element size value of 60 */
2698 36 : r->out.domains->count = count - *r->in.resume_handle;
2699 36 : r->out.domains->count = MIN(r->out.domains->count,
2700 : 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
2701 :
2702 36 : r->out.domains->domains = entries + *r->in.resume_handle;
2703 :
2704 36 : if (r->out.domains->count < count - *r->in.resume_handle) {
2705 27 : *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2706 27 : return STATUS_MORE_ENTRIES;
2707 : }
2708 :
2709 9 : *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
2710 :
2711 9 : return NT_STATUS_OK;
2712 : }
2713 :
2714 :
2715 : /*
2716 : lsa_OpenAccount
2717 : */
2718 26 : static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2719 : struct lsa_OpenAccount *r)
2720 : {
2721 0 : struct dcesrv_handle *h, *ah;
2722 0 : struct lsa_policy_state *state;
2723 0 : struct lsa_account_state *astate;
2724 :
2725 26 : ZERO_STRUCTP(r->out.acct_handle);
2726 :
2727 26 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2728 :
2729 26 : state = h->data;
2730 :
2731 26 : astate = talloc(dce_call->conn, struct lsa_account_state);
2732 26 : if (astate == NULL) {
2733 0 : return NT_STATUS_NO_MEMORY;
2734 : }
2735 :
2736 26 : astate->account_sid = dom_sid_dup(astate, r->in.sid);
2737 26 : if (astate->account_sid == NULL) {
2738 0 : talloc_free(astate);
2739 0 : return NT_STATUS_NO_MEMORY;
2740 : }
2741 :
2742 26 : astate->policy = talloc_reference(astate, state);
2743 26 : astate->access_mask = r->in.access_mask;
2744 :
2745 : /*
2746 : * For now we grant all requested access.
2747 : *
2748 : * We will fail at the ldb layer later.
2749 : */
2750 26 : if (astate->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
2751 26 : astate->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
2752 26 : astate->access_mask |= LSA_ACCOUNT_ALL_ACCESS;
2753 : }
2754 26 : se_map_generic(&astate->access_mask, &dcesrv_lsa_account_mapping);
2755 :
2756 26 : DEBUG(10,("%s: %s access desired[0x%08X] granted[0x%08X] - success.\n",
2757 : __func__, dom_sid_string(mem_ctx, astate->account_sid),
2758 : (unsigned)r->in.access_mask,
2759 : (unsigned)astate->access_mask));
2760 :
2761 26 : ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT);
2762 26 : if (!ah) {
2763 0 : talloc_free(astate);
2764 0 : return NT_STATUS_NO_MEMORY;
2765 : }
2766 :
2767 26 : ah->data = talloc_steal(ah, astate);
2768 :
2769 26 : *r->out.acct_handle = ah->wire_handle;
2770 :
2771 26 : return NT_STATUS_OK;
2772 : }
2773 :
2774 :
2775 : /*
2776 : lsa_EnumPrivsAccount
2777 : */
2778 18 : static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
2779 : TALLOC_CTX *mem_ctx,
2780 : struct lsa_EnumPrivsAccount *r)
2781 : {
2782 0 : struct dcesrv_handle *h;
2783 0 : struct lsa_account_state *astate;
2784 0 : int ret;
2785 0 : unsigned int i, j;
2786 0 : struct ldb_message **res;
2787 18 : const char * const attrs[] = { "privilege", NULL};
2788 0 : struct ldb_message_element *el;
2789 0 : const char *sidstr;
2790 0 : struct lsa_PrivilegeSet *privs;
2791 :
2792 18 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2793 :
2794 18 : astate = h->data;
2795 :
2796 18 : privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
2797 18 : if (privs == NULL) {
2798 0 : return NT_STATUS_NO_MEMORY;
2799 : }
2800 18 : privs->count = 0;
2801 18 : privs->unknown = 0;
2802 18 : privs->set = NULL;
2803 :
2804 18 : *r->out.privs = privs;
2805 :
2806 18 : sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
2807 18 : if (sidstr == NULL) {
2808 0 : return NT_STATUS_NO_MEMORY;
2809 : }
2810 :
2811 18 : ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
2812 : "objectSid=%s", sidstr);
2813 18 : if (ret < 0) {
2814 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
2815 : }
2816 18 : if (ret != 1) {
2817 0 : return NT_STATUS_OK;
2818 : }
2819 :
2820 18 : el = ldb_msg_find_element(res[0], "privilege");
2821 18 : if (el == NULL || el->num_values == 0) {
2822 0 : return NT_STATUS_OK;
2823 : }
2824 :
2825 18 : privs->set = talloc_array(privs,
2826 : struct lsa_LUIDAttribute, el->num_values);
2827 18 : if (privs->set == NULL) {
2828 0 : return NT_STATUS_NO_MEMORY;
2829 : }
2830 :
2831 18 : j = 0;
2832 138 : for (i=0;i<el->num_values;i++) {
2833 120 : int id = sec_privilege_id((const char *)el->values[i].data);
2834 120 : if (id == SEC_PRIV_INVALID) {
2835 : /* Perhaps an account right, not a privilege */
2836 24 : continue;
2837 : }
2838 96 : privs->set[j].attribute = 0;
2839 96 : privs->set[j].luid.low = id;
2840 96 : privs->set[j].luid.high = 0;
2841 96 : j++;
2842 : }
2843 :
2844 18 : privs->count = j;
2845 :
2846 18 : return NT_STATUS_OK;
2847 : }
2848 :
2849 : /*
2850 : lsa_EnumAccountRights
2851 : */
2852 78 : static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
2853 : TALLOC_CTX *mem_ctx,
2854 : struct lsa_EnumAccountRights *r)
2855 : {
2856 0 : struct dcesrv_handle *h;
2857 0 : struct lsa_policy_state *state;
2858 0 : int ret;
2859 0 : unsigned int i;
2860 0 : struct ldb_message **res;
2861 78 : const char * const attrs[] = { "privilege", NULL};
2862 0 : const char *sidstr;
2863 0 : struct ldb_message_element *el;
2864 :
2865 78 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2866 :
2867 78 : state = h->data;
2868 :
2869 78 : sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
2870 78 : if (sidstr == NULL) {
2871 0 : return NT_STATUS_NO_MEMORY;
2872 : }
2873 :
2874 78 : ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
2875 : "(&(objectSid=%s)(privilege=*))", sidstr);
2876 78 : if (ret == 0) {
2877 17 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2878 : }
2879 61 : if (ret != 1) {
2880 0 : DEBUG(3, ("searching for account rights for SID: %s failed: %s\n",
2881 : dom_sid_string(mem_ctx, r->in.sid),
2882 : ldb_errstring(state->pdb)));
2883 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
2884 : }
2885 :
2886 61 : el = ldb_msg_find_element(res[0], "privilege");
2887 61 : if (el == NULL || el->num_values == 0) {
2888 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2889 : }
2890 :
2891 61 : r->out.rights->count = el->num_values;
2892 61 : r->out.rights->names = talloc_array(r->out.rights,
2893 : struct lsa_StringLarge, r->out.rights->count);
2894 61 : if (r->out.rights->names == NULL) {
2895 0 : return NT_STATUS_NO_MEMORY;
2896 : }
2897 :
2898 599 : for (i=0;i<el->num_values;i++) {
2899 538 : r->out.rights->names[i].string = (const char *)el->values[i].data;
2900 : }
2901 :
2902 61 : return NT_STATUS_OK;
2903 : }
2904 :
2905 :
2906 :
2907 : /*
2908 : helper for lsa_AddAccountRights and lsa_RemoveAccountRights
2909 : */
2910 44 : static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
2911 : TALLOC_CTX *mem_ctx,
2912 : struct lsa_policy_state *state,
2913 : int ldb_flag,
2914 : struct dom_sid *sid,
2915 : const struct lsa_RightSet *rights)
2916 : {
2917 0 : struct auth_session_info *session_info =
2918 44 : dcesrv_call_session_info(dce_call);
2919 0 : const char *sidstr, *sidndrstr;
2920 0 : struct ldb_message *msg;
2921 0 : struct ldb_message_element *el;
2922 0 : int ret;
2923 0 : uint32_t i;
2924 0 : struct lsa_EnumAccountRights r2;
2925 0 : char *dnstr;
2926 :
2927 44 : if (security_session_user_level(session_info, NULL) <
2928 : SECURITY_ADMINISTRATOR) {
2929 0 : DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
2930 0 : return NT_STATUS_ACCESS_DENIED;
2931 : }
2932 :
2933 44 : msg = ldb_msg_new(mem_ctx);
2934 44 : if (msg == NULL) {
2935 0 : return NT_STATUS_NO_MEMORY;
2936 : }
2937 :
2938 44 : sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
2939 44 : if (sidndrstr == NULL) {
2940 0 : TALLOC_FREE(msg);
2941 0 : return NT_STATUS_NO_MEMORY;
2942 : }
2943 :
2944 44 : sidstr = dom_sid_string(msg, sid);
2945 44 : if (sidstr == NULL) {
2946 0 : TALLOC_FREE(msg);
2947 0 : return NT_STATUS_NO_MEMORY;
2948 : }
2949 :
2950 44 : dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
2951 44 : if (dnstr == NULL) {
2952 0 : TALLOC_FREE(msg);
2953 0 : return NT_STATUS_NO_MEMORY;
2954 : }
2955 :
2956 44 : msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
2957 44 : if (msg->dn == NULL) {
2958 0 : TALLOC_FREE(msg);
2959 0 : return NT_STATUS_NO_MEMORY;
2960 : }
2961 :
2962 44 : if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
2963 0 : NTSTATUS status;
2964 :
2965 25 : r2.in.handle = &state->handle->wire_handle;
2966 25 : r2.in.sid = sid;
2967 25 : r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
2968 :
2969 25 : status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2970 25 : if (!NT_STATUS_IS_OK(status)) {
2971 6 : ZERO_STRUCTP(r2.out.rights);
2972 : }
2973 : }
2974 :
2975 92 : for (i=0;i<rights->count;i++) {
2976 0 : bool ok;
2977 :
2978 48 : ok = dcesrc_lsa_valid_AccountRight(rights->names[i].string);
2979 48 : if (!ok) {
2980 0 : talloc_free(msg);
2981 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
2982 : }
2983 :
2984 48 : if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
2985 : uint32_t j;
2986 131 : for (j=0;j<r2.out.rights->count;j++) {
2987 106 : if (strcasecmp_m(r2.out.rights->names[j].string,
2988 106 : rights->names[i].string) == 0) {
2989 0 : break;
2990 : }
2991 : }
2992 25 : if (j != r2.out.rights->count) continue;
2993 : }
2994 :
2995 48 : ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
2996 48 : if (ret != LDB_SUCCESS) {
2997 0 : talloc_free(msg);
2998 0 : return NT_STATUS_NO_MEMORY;
2999 : }
3000 : }
3001 :
3002 44 : el = ldb_msg_find_element(msg, "privilege");
3003 44 : if (!el) {
3004 0 : talloc_free(msg);
3005 0 : return NT_STATUS_OK;
3006 : }
3007 :
3008 44 : el->flags = ldb_flag;
3009 :
3010 44 : ret = ldb_modify(state->pdb, msg);
3011 44 : if (ret == LDB_ERR_NO_SUCH_OBJECT) {
3012 6 : if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
3013 0 : talloc_free(msg);
3014 0 : return NT_STATUS_NO_MEMORY;
3015 : }
3016 6 : ldb_msg_add_string(msg, "comment", "added via LSA");
3017 6 : ret = ldb_add(state->pdb, msg);
3018 : }
3019 44 : if (ret != LDB_SUCCESS) {
3020 0 : if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
3021 0 : talloc_free(msg);
3022 0 : return NT_STATUS_OK;
3023 : }
3024 0 : DEBUG(3, ("Could not %s attributes from %s: %s\n",
3025 : LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE ? "delete" : "add",
3026 : ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
3027 0 : talloc_free(msg);
3028 0 : return NT_STATUS_UNEXPECTED_IO_ERROR;
3029 : }
3030 :
3031 44 : talloc_free(msg);
3032 44 : return NT_STATUS_OK;
3033 : }
3034 :
3035 : /*
3036 : lsa_AddPrivilegesToAccount
3037 : */
3038 15 : static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3039 : struct lsa_AddPrivilegesToAccount *r)
3040 : {
3041 0 : struct lsa_RightSet rights;
3042 0 : struct dcesrv_handle *h;
3043 0 : struct lsa_account_state *astate;
3044 0 : uint32_t i;
3045 :
3046 15 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3047 :
3048 15 : astate = h->data;
3049 :
3050 15 : rights.count = r->in.privs->count;
3051 15 : rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
3052 15 : if (rights.names == NULL) {
3053 0 : return NT_STATUS_NO_MEMORY;
3054 : }
3055 30 : for (i=0;i<rights.count;i++) {
3056 15 : int id = r->in.privs->set[i].luid.low;
3057 15 : if (r->in.privs->set[i].luid.high) {
3058 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3059 : }
3060 15 : rights.names[i].string = sec_privilege_name(id);
3061 15 : if (rights.names[i].string == NULL) {
3062 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3063 : }
3064 : }
3065 :
3066 15 : return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3067 : LDB_FLAG_MOD_ADD, astate->account_sid,
3068 : &rights);
3069 : }
3070 :
3071 :
3072 : /*
3073 : lsa_RemovePrivilegesFromAccount
3074 : */
3075 15 : static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3076 : struct lsa_RemovePrivilegesFromAccount *r)
3077 : {
3078 0 : struct lsa_RightSet *rights;
3079 0 : struct dcesrv_handle *h;
3080 0 : struct lsa_account_state *astate;
3081 0 : uint32_t i;
3082 :
3083 15 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3084 :
3085 15 : astate = h->data;
3086 :
3087 15 : rights = talloc(mem_ctx, struct lsa_RightSet);
3088 :
3089 15 : if (r->in.remove_all == 1 &&
3090 0 : r->in.privs == NULL) {
3091 0 : struct lsa_EnumAccountRights r2;
3092 0 : NTSTATUS status;
3093 :
3094 0 : r2.in.handle = &astate->policy->handle->wire_handle;
3095 0 : r2.in.sid = astate->account_sid;
3096 0 : r2.out.rights = rights;
3097 :
3098 0 : status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
3099 0 : if (!NT_STATUS_IS_OK(status)) {
3100 0 : return status;
3101 : }
3102 :
3103 0 : return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3104 : LDB_FLAG_MOD_DELETE, astate->account_sid,
3105 0 : r2.out.rights);
3106 : }
3107 :
3108 15 : if (r->in.remove_all != 0) {
3109 0 : return NT_STATUS_INVALID_PARAMETER;
3110 : }
3111 :
3112 15 : rights->count = r->in.privs->count;
3113 15 : rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
3114 15 : if (rights->names == NULL) {
3115 0 : return NT_STATUS_NO_MEMORY;
3116 : }
3117 30 : for (i=0;i<rights->count;i++) {
3118 15 : int id = r->in.privs->set[i].luid.low;
3119 15 : if (r->in.privs->set[i].luid.high) {
3120 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3121 : }
3122 15 : rights->names[i].string = sec_privilege_name(id);
3123 15 : if (rights->names[i].string == NULL) {
3124 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3125 : }
3126 : }
3127 :
3128 15 : return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
3129 : LDB_FLAG_MOD_DELETE, astate->account_sid,
3130 : rights);
3131 : }
3132 :
3133 :
3134 : /*
3135 : lsa_GetQuotasForAccount
3136 : */
3137 0 : static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3138 : struct lsa_GetQuotasForAccount *r)
3139 : {
3140 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3141 : }
3142 :
3143 :
3144 : /*
3145 : lsa_SetQuotasForAccount
3146 : */
3147 0 : static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3148 : struct lsa_SetQuotasForAccount *r)
3149 : {
3150 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3151 : }
3152 :
3153 :
3154 : /*
3155 : lsa_GetSystemAccessAccount
3156 : */
3157 26 : static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3158 : struct lsa_GetSystemAccessAccount *r)
3159 : {
3160 0 : struct dcesrv_handle *h;
3161 0 : struct lsa_account_state *astate;
3162 0 : int ret;
3163 0 : unsigned int i;
3164 0 : struct ldb_message **res;
3165 26 : const char * const attrs[] = { "privilege", NULL};
3166 0 : struct ldb_message_element *el;
3167 0 : const char *sidstr;
3168 :
3169 26 : *(r->out.access_mask) = 0x00000000;
3170 :
3171 26 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
3172 :
3173 26 : astate = h->data;
3174 :
3175 26 : sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
3176 26 : if (sidstr == NULL) {
3177 0 : return NT_STATUS_NO_MEMORY;
3178 : }
3179 :
3180 26 : ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
3181 : "objectSid=%s", sidstr);
3182 26 : if (ret < 0) {
3183 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
3184 : }
3185 26 : if (ret != 1) {
3186 0 : return NT_STATUS_OK;
3187 : }
3188 :
3189 26 : el = ldb_msg_find_element(res[0], "privilege");
3190 26 : if (el == NULL || el->num_values == 0) {
3191 0 : return NT_STATUS_OK;
3192 : }
3193 :
3194 162 : for (i=0;i<el->num_values;i++) {
3195 136 : uint32_t right_bit = sec_right_bit((const char *)el->values[i].data);
3196 136 : if (right_bit == 0) {
3197 : /* Perhaps an privilege, not a right */
3198 104 : continue;
3199 : }
3200 32 : *(r->out.access_mask) |= right_bit;
3201 : }
3202 :
3203 26 : return NT_STATUS_OK;
3204 : }
3205 :
3206 :
3207 : /*
3208 : lsa_SetSystemAccessAccount
3209 : */
3210 0 : static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3211 : struct lsa_SetSystemAccessAccount *r)
3212 : {
3213 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3214 : }
3215 : /*
3216 : lsa_CreateSecret
3217 : */
3218 1676 : static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3219 : struct lsa_CreateSecret *r)
3220 : {
3221 0 : struct auth_session_info *session_info =
3222 1676 : dcesrv_call_session_info(dce_call);
3223 0 : struct dcesrv_handle *policy_handle;
3224 0 : struct lsa_policy_state *policy_state;
3225 0 : struct lsa_secret_state *secret_state;
3226 0 : struct dcesrv_handle *handle;
3227 0 : struct ldb_message **msgs, *msg;
3228 1676 : const char *attrs[] = {
3229 : NULL
3230 : };
3231 :
3232 0 : const char *name;
3233 :
3234 0 : int ret;
3235 :
3236 1676 : DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3237 1676 : ZERO_STRUCTP(r->out.sec_handle);
3238 :
3239 1676 : switch (security_session_user_level(session_info, NULL))
3240 : {
3241 1676 : case SECURITY_SYSTEM:
3242 : case SECURITY_ADMINISTRATOR:
3243 1676 : break;
3244 0 : default:
3245 : /* Users and anonymous are not allowed create secrets */
3246 0 : return NT_STATUS_ACCESS_DENIED;
3247 : }
3248 :
3249 1676 : policy_state = policy_handle->data;
3250 :
3251 1676 : if (!r->in.name.string) {
3252 0 : return NT_STATUS_INVALID_PARAMETER;
3253 : }
3254 :
3255 1676 : secret_state = talloc(mem_ctx, struct lsa_secret_state);
3256 1676 : NT_STATUS_HAVE_NO_MEMORY(secret_state);
3257 1676 : secret_state->policy = policy_state;
3258 :
3259 1676 : msg = ldb_msg_new(mem_ctx);
3260 1676 : if (msg == NULL) {
3261 0 : return NT_STATUS_NO_MEMORY;
3262 : }
3263 :
3264 1676 : if (strncmp("G$", r->in.name.string, 2) == 0) {
3265 0 : const char *name2;
3266 :
3267 20 : secret_state->global = true;
3268 :
3269 20 : name = &r->in.name.string[2];
3270 20 : if (strlen(name) == 0) {
3271 0 : return NT_STATUS_INVALID_PARAMETER;
3272 : }
3273 :
3274 20 : name2 = talloc_asprintf(mem_ctx, "%s Secret",
3275 : ldb_binary_encode_string(mem_ctx, name));
3276 20 : NT_STATUS_HAVE_NO_MEMORY(name2);
3277 :
3278 : /*
3279 : * We need to connect to the database as system, as this is
3280 : * one of the rare RPC calls that must read the secrets
3281 : * (and this is denied otherwise)
3282 : *
3283 : * We also save the current remote session details so they can
3284 : * used by the audit logging module. This allows the audit
3285 : * logging to report the remote users details, rather than the
3286 : * system users details.
3287 : */
3288 20 : secret_state->sam_ldb =
3289 20 : dcesrv_samdb_connect_as_system(secret_state, dce_call);
3290 20 : NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
3291 :
3292 : /* search for the secret record */
3293 20 : ret = gendb_search(secret_state->sam_ldb,
3294 : mem_ctx, policy_state->system_dn, &msgs, attrs,
3295 : "(&(cn=%s)(objectclass=secret))",
3296 : name2);
3297 20 : if (ret > 0) {
3298 9 : return NT_STATUS_OBJECT_NAME_COLLISION;
3299 : }
3300 :
3301 11 : if (ret < 0) {
3302 0 : DEBUG(0,("Failure searching for CN=%s: %s\n",
3303 : name2, ldb_errstring(secret_state->sam_ldb)));
3304 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
3305 : }
3306 :
3307 11 : msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
3308 11 : NT_STATUS_HAVE_NO_MEMORY(msg->dn);
3309 11 : if (!ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
3310 0 : return NT_STATUS_NO_MEMORY;
3311 : }
3312 :
3313 11 : ret = ldb_msg_add_string(msg, "cn", name2);
3314 11 : if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3315 : } else {
3316 1656 : secret_state->global = false;
3317 :
3318 1656 : name = r->in.name.string;
3319 1656 : if (strlen(name) == 0) {
3320 0 : return NT_STATUS_INVALID_PARAMETER;
3321 : }
3322 :
3323 3312 : secret_state->sam_ldb = secrets_db_connect(secret_state,
3324 1656 : dce_call->conn->dce_ctx->lp_ctx);
3325 1656 : NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
3326 :
3327 : /* search for the secret record */
3328 1656 : ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3329 : ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3330 : &msgs, attrs,
3331 : "(&(cn=%s)(objectclass=secret))",
3332 : ldb_binary_encode_string(mem_ctx, name));
3333 1656 : if (ret > 0) {
3334 12 : return NT_STATUS_OBJECT_NAME_COLLISION;
3335 : }
3336 :
3337 1644 : if (ret < 0) {
3338 0 : DEBUG(0,("Failure searching for CN=%s: %s\n",
3339 : name, ldb_errstring(secret_state->sam_ldb)));
3340 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
3341 : }
3342 :
3343 1644 : msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb,
3344 : "cn=%s,cn=LSA Secrets", name);
3345 1644 : NT_STATUS_HAVE_NO_MEMORY(msg->dn);
3346 1644 : ret = ldb_msg_add_string(msg, "cn", name);
3347 1644 : if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3348 : }
3349 :
3350 1655 : ret = ldb_msg_add_string(msg, "objectClass", "secret");
3351 1655 : if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
3352 :
3353 1655 : secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
3354 1655 : NT_STATUS_HAVE_NO_MEMORY(secret_state->secret_dn);
3355 :
3356 : /* create the secret */
3357 1655 : ret = ldb_add(secret_state->sam_ldb, msg);
3358 1655 : if (ret != LDB_SUCCESS) {
3359 0 : DEBUG(0,("Failed to create secret record %s: %s\n",
3360 : ldb_dn_get_linearized(msg->dn),
3361 : ldb_errstring(secret_state->sam_ldb)));
3362 0 : return NT_STATUS_ACCESS_DENIED;
3363 : }
3364 :
3365 1655 : handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
3366 1655 : NT_STATUS_HAVE_NO_MEMORY(handle);
3367 :
3368 1655 : handle->data = talloc_steal(handle, secret_state);
3369 :
3370 1655 : secret_state->access_mask = r->in.access_mask;
3371 1655 : secret_state->policy = talloc_reference(secret_state, policy_state);
3372 1655 : NT_STATUS_HAVE_NO_MEMORY(secret_state->policy);
3373 :
3374 1655 : *r->out.sec_handle = handle->wire_handle;
3375 :
3376 1655 : return NT_STATUS_OK;
3377 : }
3378 :
3379 :
3380 : /*
3381 : lsa_OpenSecret
3382 : */
3383 46 : static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3384 : struct lsa_OpenSecret *r)
3385 : {
3386 0 : struct auth_session_info *session_info =
3387 46 : dcesrv_call_session_info(dce_call);
3388 0 : struct dcesrv_handle *policy_handle;
3389 0 : struct lsa_policy_state *policy_state;
3390 0 : struct lsa_secret_state *secret_state;
3391 0 : struct dcesrv_handle *handle;
3392 0 : struct ldb_message **msgs;
3393 46 : const char *attrs[] = {
3394 : NULL
3395 : };
3396 0 : const char *name;
3397 0 : int ret;
3398 :
3399 46 : DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3400 46 : ZERO_STRUCTP(r->out.sec_handle);
3401 46 : policy_state = policy_handle->data;
3402 :
3403 46 : if (!r->in.name.string) {
3404 0 : return NT_STATUS_INVALID_PARAMETER;
3405 : }
3406 :
3407 46 : switch (security_session_user_level(session_info, NULL))
3408 : {
3409 46 : case SECURITY_SYSTEM:
3410 : case SECURITY_ADMINISTRATOR:
3411 46 : break;
3412 0 : default:
3413 : /* Users and anonymous are not allowed to access secrets */
3414 0 : return NT_STATUS_ACCESS_DENIED;
3415 : }
3416 :
3417 46 : secret_state = talloc(mem_ctx, struct lsa_secret_state);
3418 46 : if (!secret_state) {
3419 0 : return NT_STATUS_NO_MEMORY;
3420 : }
3421 46 : secret_state->policy = policy_state;
3422 :
3423 46 : if (strncmp("G$", r->in.name.string, 2) == 0) {
3424 25 : name = &r->in.name.string[2];
3425 : /*
3426 : * We need to connect to the database as system, as this is
3427 : * one of the rare RPC calls that must read the secrets
3428 : * (and this is denied otherwise)
3429 : *
3430 : * We also save the current remote session details so they can
3431 : * used by the audit logging module. This allows the audit
3432 : * logging to report the remote users details, rather than the
3433 : * system users details.
3434 : */
3435 25 : secret_state->sam_ldb =
3436 25 : dcesrv_samdb_connect_as_system(secret_state, dce_call);
3437 25 : NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
3438 25 : secret_state->global = true;
3439 :
3440 25 : if (strlen(name) < 1) {
3441 0 : return NT_STATUS_INVALID_PARAMETER;
3442 : }
3443 :
3444 : /* search for the secret record */
3445 25 : ret = gendb_search(secret_state->sam_ldb,
3446 : mem_ctx, policy_state->system_dn, &msgs, attrs,
3447 : "(&(cn=%s Secret)(objectclass=secret))",
3448 : ldb_binary_encode_string(mem_ctx, name));
3449 25 : if (ret == 0) {
3450 9 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3451 : }
3452 :
3453 16 : if (ret != 1) {
3454 0 : DEBUG(0,("Found %d records matching DN %s\n", ret,
3455 : ldb_dn_get_linearized(policy_state->system_dn)));
3456 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
3457 : }
3458 : } else {
3459 21 : secret_state->global = false;
3460 42 : secret_state->sam_ldb = secrets_db_connect(secret_state,
3461 21 : dce_call->conn->dce_ctx->lp_ctx);
3462 21 : NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
3463 :
3464 21 : name = r->in.name.string;
3465 21 : if (strlen(name) < 1) {
3466 0 : return NT_STATUS_INVALID_PARAMETER;
3467 : }
3468 :
3469 : /* search for the secret record */
3470 21 : ret = gendb_search(secret_state->sam_ldb, mem_ctx,
3471 : ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
3472 : &msgs, attrs,
3473 : "(&(cn=%s)(objectclass=secret))",
3474 : ldb_binary_encode_string(mem_ctx, name));
3475 21 : if (ret == 0) {
3476 9 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3477 : }
3478 :
3479 12 : if (ret != 1) {
3480 0 : DEBUG(0,("Found %d records matching CN=%s\n",
3481 : ret, ldb_binary_encode_string(mem_ctx, name)));
3482 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
3483 : }
3484 : }
3485 :
3486 28 : secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
3487 :
3488 28 : handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
3489 28 : if (!handle) {
3490 0 : return NT_STATUS_NO_MEMORY;
3491 : }
3492 :
3493 28 : handle->data = talloc_steal(handle, secret_state);
3494 :
3495 28 : secret_state->access_mask = r->in.access_mask;
3496 28 : secret_state->policy = talloc_reference(secret_state, policy_state);
3497 :
3498 28 : *r->out.sec_handle = handle->wire_handle;
3499 :
3500 28 : return NT_STATUS_OK;
3501 : }
3502 :
3503 :
3504 : /*
3505 : lsa_SetSecret
3506 : */
3507 2376 : static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3508 : struct lsa_SetSecret *r)
3509 : {
3510 :
3511 0 : struct dcesrv_handle *h;
3512 0 : struct lsa_secret_state *secret_state;
3513 0 : struct ldb_message *msg;
3514 0 : DATA_BLOB session_key;
3515 0 : DATA_BLOB crypt_secret, secret;
3516 0 : struct ldb_val val;
3517 0 : int ret;
3518 2376 : NTSTATUS status = NT_STATUS_OK;
3519 :
3520 2376 : struct timeval now = timeval_current();
3521 2376 : NTTIME nt_now = timeval_to_nttime(&now);
3522 :
3523 2376 : DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3524 :
3525 2376 : secret_state = h->data;
3526 :
3527 2376 : msg = ldb_msg_new(mem_ctx);
3528 2376 : if (msg == NULL) {
3529 0 : return NT_STATUS_NO_MEMORY;
3530 : }
3531 :
3532 2376 : msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
3533 2376 : if (!msg->dn) {
3534 0 : return NT_STATUS_NO_MEMORY;
3535 : }
3536 2376 : status = dcesrv_transport_session_key(dce_call, &session_key);
3537 2376 : if (!NT_STATUS_IS_OK(status)) {
3538 0 : return status;
3539 : }
3540 :
3541 2376 : if (r->in.old_val) {
3542 : /* Decrypt */
3543 18 : crypt_secret.data = r->in.old_val->data;
3544 18 : crypt_secret.length = r->in.old_val->size;
3545 :
3546 18 : status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3547 18 : if (!NT_STATUS_IS_OK(status)) {
3548 0 : return status;
3549 : }
3550 :
3551 18 : val.data = secret.data;
3552 18 : val.length = secret.length;
3553 :
3554 : /* set value */
3555 18 : if (ldb_msg_add_value(msg, "priorValue", &val, NULL) != LDB_SUCCESS) {
3556 0 : return NT_STATUS_NO_MEMORY;
3557 : }
3558 :
3559 : /* set old value mtime */
3560 18 : if (samdb_msg_add_uint64(secret_state->sam_ldb,
3561 : mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3562 0 : return NT_STATUS_NO_MEMORY;
3563 : }
3564 :
3565 : } else {
3566 : /* If the old value is not set, then migrate the
3567 : * current value to the old value */
3568 0 : const struct ldb_val *old_val;
3569 0 : NTTIME last_set_time;
3570 0 : struct ldb_message **res;
3571 2358 : const char *attrs[] = {
3572 : "currentValue",
3573 : "lastSetTime",
3574 : NULL
3575 : };
3576 :
3577 : /* search for the secret record */
3578 2358 : ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
3579 : secret_state->secret_dn, &res, attrs);
3580 2358 : if (ret == 0) {
3581 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3582 : }
3583 :
3584 2358 : if (ret != 1) {
3585 0 : DEBUG(0,("Found %d records matching dn=%s\n", ret,
3586 : ldb_dn_get_linearized(secret_state->secret_dn)));
3587 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
3588 : }
3589 :
3590 2358 : old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
3591 2358 : last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
3592 :
3593 2358 : if (old_val) {
3594 : /* set old value */
3595 1188 : if (ldb_msg_add_value(msg, "priorValue",
3596 : old_val, NULL) != LDB_SUCCESS) {
3597 0 : return NT_STATUS_NO_MEMORY;
3598 : }
3599 : } else {
3600 1170 : if (samdb_msg_add_delete(secret_state->sam_ldb,
3601 : mem_ctx, msg, "priorValue") != LDB_SUCCESS) {
3602 0 : return NT_STATUS_NO_MEMORY;
3603 : }
3604 : }
3605 :
3606 : /* set old value mtime */
3607 2358 : if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
3608 1188 : if (samdb_msg_add_uint64(secret_state->sam_ldb,
3609 : mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
3610 0 : return NT_STATUS_NO_MEMORY;
3611 : }
3612 : } else {
3613 1170 : if (samdb_msg_add_uint64(secret_state->sam_ldb,
3614 : mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
3615 0 : return NT_STATUS_NO_MEMORY;
3616 : }
3617 : }
3618 : }
3619 :
3620 2376 : if (r->in.new_val) {
3621 : /* Decrypt */
3622 2358 : crypt_secret.data = r->in.new_val->data;
3623 2358 : crypt_secret.length = r->in.new_val->size;
3624 :
3625 2358 : status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
3626 2358 : if (!NT_STATUS_IS_OK(status)) {
3627 1170 : return status;
3628 : }
3629 :
3630 1188 : val.data = secret.data;
3631 1188 : val.length = secret.length;
3632 :
3633 : /* set value */
3634 1188 : if (ldb_msg_add_value(msg, "currentValue", &val, NULL) != LDB_SUCCESS) {
3635 0 : return NT_STATUS_NO_MEMORY;
3636 : }
3637 :
3638 : /* set new value mtime */
3639 1188 : if (samdb_msg_add_uint64(secret_state->sam_ldb,
3640 : mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3641 0 : return NT_STATUS_NO_MEMORY;
3642 : }
3643 : } else {
3644 : /* NULL out the NEW value */
3645 18 : if (samdb_msg_add_uint64(secret_state->sam_ldb,
3646 : mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
3647 0 : return NT_STATUS_NO_MEMORY;
3648 : }
3649 18 : if (samdb_msg_add_delete(secret_state->sam_ldb,
3650 : mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
3651 0 : return NT_STATUS_NO_MEMORY;
3652 : }
3653 : }
3654 :
3655 : /* modify the samdb record */
3656 1206 : ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
3657 1206 : if (ret != LDB_SUCCESS) {
3658 0 : return dsdb_ldb_err_to_ntstatus(ret);
3659 : }
3660 :
3661 1206 : return NT_STATUS_OK;
3662 : }
3663 :
3664 :
3665 : /*
3666 : lsa_QuerySecret
3667 : */
3668 1212 : static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3669 : struct lsa_QuerySecret *r)
3670 : {
3671 0 : struct auth_session_info *session_info =
3672 1212 : dcesrv_call_session_info(dce_call);
3673 0 : struct dcesrv_handle *h;
3674 0 : struct lsa_secret_state *secret_state;
3675 0 : struct ldb_message *msg;
3676 0 : DATA_BLOB session_key;
3677 0 : DATA_BLOB crypt_secret, secret;
3678 0 : int ret;
3679 0 : struct ldb_message **res;
3680 1212 : const char *attrs[] = {
3681 : "currentValue",
3682 : "priorValue",
3683 : "lastSetTime",
3684 : "priorSetTime",
3685 : NULL
3686 : };
3687 :
3688 0 : NTSTATUS nt_status;
3689 :
3690 1212 : DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
3691 :
3692 : /* Ensure user is permitted to read this... */
3693 1212 : switch (security_session_user_level(session_info, NULL))
3694 : {
3695 1212 : case SECURITY_SYSTEM:
3696 : case SECURITY_ADMINISTRATOR:
3697 1212 : break;
3698 0 : default:
3699 : /* Users and anonymous are not allowed to read secrets */
3700 0 : return NT_STATUS_ACCESS_DENIED;
3701 : }
3702 :
3703 1212 : secret_state = h->data;
3704 :
3705 : /* pull all the user attributes */
3706 1212 : ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
3707 : secret_state->secret_dn, &res, attrs);
3708 1212 : if (ret != 1) {
3709 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
3710 : }
3711 1212 : msg = res[0];
3712 :
3713 1212 : nt_status = dcesrv_transport_session_key(dce_call, &session_key);
3714 1212 : if (!NT_STATUS_IS_OK(nt_status)) {
3715 0 : return nt_status;
3716 : }
3717 :
3718 1212 : if (r->in.old_val) {
3719 0 : const struct ldb_val *prior_val;
3720 36 : r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3721 36 : if (!r->out.old_val) {
3722 0 : return NT_STATUS_NO_MEMORY;
3723 : }
3724 36 : prior_val = ldb_msg_find_ldb_val(msg, "priorValue");
3725 :
3726 36 : if (prior_val && prior_val->length) {
3727 36 : secret.data = prior_val->data;
3728 36 : secret.length = prior_val->length;
3729 :
3730 : /* Encrypt */
3731 36 : crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3732 36 : if (!crypt_secret.length) {
3733 0 : return NT_STATUS_NO_MEMORY;
3734 : }
3735 36 : r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3736 36 : if (!r->out.old_val->buf) {
3737 0 : return NT_STATUS_NO_MEMORY;
3738 : }
3739 36 : r->out.old_val->buf->size = crypt_secret.length;
3740 36 : r->out.old_val->buf->length = crypt_secret.length;
3741 36 : r->out.old_val->buf->data = crypt_secret.data;
3742 : }
3743 : }
3744 :
3745 1212 : if (r->in.old_mtime) {
3746 36 : r->out.old_mtime = talloc(mem_ctx, NTTIME);
3747 36 : if (!r->out.old_mtime) {
3748 0 : return NT_STATUS_NO_MEMORY;
3749 : }
3750 36 : *r->out.old_mtime = ldb_msg_find_attr_as_uint64(msg, "priorSetTime", 0);
3751 : }
3752 :
3753 1212 : if (r->in.new_val) {
3754 0 : const struct ldb_val *new_val;
3755 1212 : r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
3756 1212 : if (!r->out.new_val) {
3757 0 : return NT_STATUS_NO_MEMORY;
3758 : }
3759 :
3760 1212 : new_val = ldb_msg_find_ldb_val(msg, "currentValue");
3761 :
3762 1212 : if (new_val && new_val->length) {
3763 1194 : secret.data = new_val->data;
3764 1194 : secret.length = new_val->length;
3765 :
3766 : /* Encrypt */
3767 1194 : crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
3768 1194 : if (!crypt_secret.length) {
3769 0 : return NT_STATUS_NO_MEMORY;
3770 : }
3771 1194 : r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
3772 1194 : if (!r->out.new_val->buf) {
3773 0 : return NT_STATUS_NO_MEMORY;
3774 : }
3775 1194 : r->out.new_val->buf->length = crypt_secret.length;
3776 1194 : r->out.new_val->buf->size = crypt_secret.length;
3777 1194 : r->out.new_val->buf->data = crypt_secret.data;
3778 : }
3779 : }
3780 :
3781 1212 : if (r->in.new_mtime) {
3782 1206 : r->out.new_mtime = talloc(mem_ctx, NTTIME);
3783 1206 : if (!r->out.new_mtime) {
3784 0 : return NT_STATUS_NO_MEMORY;
3785 : }
3786 1206 : *r->out.new_mtime = ldb_msg_find_attr_as_uint64(msg, "lastSetTime", 0);
3787 : }
3788 :
3789 1212 : return NT_STATUS_OK;
3790 : }
3791 :
3792 :
3793 : /*
3794 : lsa_LookupPrivValue
3795 : */
3796 77 : static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
3797 : TALLOC_CTX *mem_ctx,
3798 : struct lsa_LookupPrivValue *r)
3799 : {
3800 0 : struct dcesrv_handle *h;
3801 0 : int id;
3802 :
3803 77 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3804 :
3805 77 : id = sec_privilege_id(r->in.name->string);
3806 77 : if (id == SEC_PRIV_INVALID) {
3807 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3808 : }
3809 :
3810 77 : r->out.luid->low = id;
3811 77 : r->out.luid->high = 0;
3812 :
3813 77 : return NT_STATUS_OK;
3814 : }
3815 :
3816 :
3817 : /*
3818 : lsa_LookupPrivName
3819 : */
3820 96 : static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
3821 : TALLOC_CTX *mem_ctx,
3822 : struct lsa_LookupPrivName *r)
3823 : {
3824 0 : struct dcesrv_handle *h;
3825 0 : struct lsa_StringLarge *name;
3826 0 : const char *privname;
3827 :
3828 96 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3829 :
3830 96 : if (r->in.luid->high != 0) {
3831 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3832 : }
3833 :
3834 96 : privname = sec_privilege_name(r->in.luid->low);
3835 96 : if (privname == NULL) {
3836 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3837 : }
3838 :
3839 96 : name = talloc(mem_ctx, struct lsa_StringLarge);
3840 96 : if (name == NULL) {
3841 0 : return NT_STATUS_NO_MEMORY;
3842 : }
3843 :
3844 96 : name->string = privname;
3845 :
3846 96 : *r->out.name = name;
3847 :
3848 96 : return NT_STATUS_OK;
3849 : }
3850 :
3851 :
3852 : /*
3853 : lsa_LookupPrivDisplayName
3854 : */
3855 75 : static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
3856 : TALLOC_CTX *mem_ctx,
3857 : struct lsa_LookupPrivDisplayName *r)
3858 : {
3859 0 : struct dcesrv_handle *h;
3860 75 : struct lsa_StringLarge *disp_name = NULL;
3861 0 : enum sec_privilege id;
3862 :
3863 75 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3864 :
3865 75 : id = sec_privilege_id(r->in.name->string);
3866 75 : if (id == SEC_PRIV_INVALID) {
3867 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3868 : }
3869 :
3870 75 : disp_name = talloc(mem_ctx, struct lsa_StringLarge);
3871 75 : if (disp_name == NULL) {
3872 0 : return NT_STATUS_NO_MEMORY;
3873 : }
3874 :
3875 75 : disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
3876 75 : if (disp_name->string == NULL) {
3877 0 : return NT_STATUS_INTERNAL_ERROR;
3878 : }
3879 :
3880 75 : *r->out.disp_name = disp_name;
3881 75 : *r->out.returned_language_id = 0;
3882 :
3883 75 : return NT_STATUS_OK;
3884 : }
3885 :
3886 :
3887 : /*
3888 : lsa_EnumAccountsWithUserRight
3889 : */
3890 75 : static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
3891 : TALLOC_CTX *mem_ctx,
3892 : struct lsa_EnumAccountsWithUserRight *r)
3893 : {
3894 0 : struct dcesrv_handle *h;
3895 0 : struct lsa_policy_state *state;
3896 0 : int ret, i;
3897 0 : struct ldb_message **res;
3898 75 : const char * const attrs[] = { "objectSid", NULL};
3899 0 : const char *privname;
3900 0 : bool ok;
3901 :
3902 75 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3903 :
3904 75 : state = h->data;
3905 :
3906 75 : if (r->in.name == NULL) {
3907 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3908 : }
3909 :
3910 75 : privname = r->in.name->string;
3911 :
3912 75 : ok = dcesrc_lsa_valid_AccountRight(privname);
3913 75 : if (!ok) {
3914 0 : return NT_STATUS_NO_SUCH_PRIVILEGE;
3915 : }
3916 :
3917 75 : ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
3918 : "privilege=%s", privname);
3919 75 : if (ret < 0) {
3920 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
3921 : }
3922 75 : if (ret == 0) {
3923 12 : return NT_STATUS_NO_MORE_ENTRIES;
3924 : }
3925 :
3926 63 : r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
3927 63 : if (r->out.sids->sids == NULL) {
3928 0 : return NT_STATUS_NO_MEMORY;
3929 : }
3930 159 : for (i=0;i<ret;i++) {
3931 192 : r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
3932 96 : res[i], "objectSid");
3933 96 : NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
3934 : }
3935 63 : r->out.sids->num_sids = ret;
3936 :
3937 63 : return NT_STATUS_OK;
3938 : }
3939 :
3940 :
3941 : /*
3942 : lsa_AddAccountRights
3943 : */
3944 10 : static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
3945 : TALLOC_CTX *mem_ctx,
3946 : struct lsa_AddAccountRights *r)
3947 : {
3948 0 : struct dcesrv_handle *h;
3949 0 : struct lsa_policy_state *state;
3950 :
3951 10 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3952 :
3953 10 : state = h->data;
3954 :
3955 10 : return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3956 : LDB_FLAG_MOD_ADD,
3957 10 : r->in.sid, r->in.rights);
3958 : }
3959 :
3960 :
3961 : /*
3962 : lsa_RemoveAccountRights
3963 : */
3964 0 : static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
3965 : TALLOC_CTX *mem_ctx,
3966 : struct lsa_RemoveAccountRights *r)
3967 : {
3968 0 : struct dcesrv_handle *h;
3969 0 : struct lsa_policy_state *state;
3970 :
3971 0 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3972 :
3973 0 : state = h->data;
3974 :
3975 0 : return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
3976 : LDB_FLAG_MOD_DELETE,
3977 0 : r->in.sid, r->in.rights);
3978 : }
3979 :
3980 :
3981 : /*
3982 : lsa_StorePrivateData
3983 : */
3984 0 : static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3985 : struct lsa_StorePrivateData *r)
3986 : {
3987 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3988 : }
3989 :
3990 :
3991 : /*
3992 : lsa_RetrievePrivateData
3993 : */
3994 0 : static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3995 : struct lsa_RetrievePrivateData *r)
3996 : {
3997 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3998 : }
3999 :
4000 :
4001 : /*
4002 : lsa_GetUserName
4003 : */
4004 519 : static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4005 : struct lsa_GetUserName *r)
4006 : {
4007 48 : enum dcerpc_transport_t transport =
4008 519 : dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
4009 48 : struct auth_session_info *session_info =
4010 519 : dcesrv_call_session_info(dce_call);
4011 519 : NTSTATUS status = NT_STATUS_OK;
4012 48 : const char *account_name;
4013 48 : const char *authority_name;
4014 48 : struct lsa_String *_account_name;
4015 519 : struct lsa_String *_authority_name = NULL;
4016 :
4017 519 : if (transport != NCACN_NP && transport != NCALRPC) {
4018 3 : DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
4019 : }
4020 :
4021 : /* this is what w2k3 does */
4022 516 : r->out.account_name = r->in.account_name;
4023 516 : r->out.authority_name = r->in.authority_name;
4024 :
4025 516 : if (r->in.account_name
4026 516 : && *r->in.account_name
4027 : /* && *(*r->in.account_name)->string */
4028 : ) {
4029 0 : return NT_STATUS_INVALID_PARAMETER;
4030 : }
4031 :
4032 516 : if (r->in.authority_name
4033 468 : && *r->in.authority_name
4034 : /* && *(*r->in.authority_name)->string */
4035 : ) {
4036 0 : return NT_STATUS_INVALID_PARAMETER;
4037 : }
4038 :
4039 516 : account_name = talloc_reference(mem_ctx, session_info->info->account_name);
4040 516 : authority_name = talloc_reference(mem_ctx, session_info->info->domain_name);
4041 :
4042 516 : _account_name = talloc(mem_ctx, struct lsa_String);
4043 516 : NT_STATUS_HAVE_NO_MEMORY(_account_name);
4044 516 : _account_name->string = account_name;
4045 :
4046 516 : if (r->in.authority_name) {
4047 468 : _authority_name = talloc(mem_ctx, struct lsa_String);
4048 468 : NT_STATUS_HAVE_NO_MEMORY(_authority_name);
4049 468 : _authority_name->string = authority_name;
4050 : }
4051 :
4052 516 : *r->out.account_name = _account_name;
4053 516 : if (r->out.authority_name) {
4054 468 : *r->out.authority_name = _authority_name;
4055 : }
4056 :
4057 516 : return status;
4058 : }
4059 :
4060 : /*
4061 : lsa_SetInfoPolicy2
4062 : */
4063 0 : static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
4064 : TALLOC_CTX *mem_ctx,
4065 : struct lsa_SetInfoPolicy2 *r)
4066 : {
4067 : /* need to support these */
4068 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4069 : }
4070 :
4071 12 : static void kdc_get_policy(TALLOC_CTX *mem_ctx,
4072 : struct loadparm_context *lp_ctx,
4073 : struct smb_krb5_context *smb_krb5_context,
4074 : struct lsa_DomainInfoKerberos *k)
4075 : {
4076 0 : time_t svc_tkt_lifetime;
4077 0 : time_t usr_tkt_lifetime;
4078 0 : time_t renewal_lifetime;
4079 :
4080 : /* Our KDC always re-validates the client */
4081 12 : k->authentication_options = LSA_POLICY_KERBEROS_VALIDATE_CLIENT;
4082 :
4083 12 : lpcfg_default_kdc_policy(mem_ctx, lp_ctx, &svc_tkt_lifetime,
4084 : &usr_tkt_lifetime, &renewal_lifetime);
4085 :
4086 12 : unix_to_nt_time(&k->service_tkt_lifetime, svc_tkt_lifetime);
4087 12 : unix_to_nt_time(&k->user_tkt_lifetime, usr_tkt_lifetime);
4088 12 : unix_to_nt_time(&k->user_tkt_renewaltime, renewal_lifetime);
4089 : #ifdef SAMBA4_USES_HEIMDAL /* MIT lacks krb5_get_max_time_skew.
4090 : However in the parent function we basically just did a full
4091 : krb5_context init with the only purpose of getting a global
4092 : config option (the max skew), it would probably make more sense
4093 : to have a lp_ or ldb global option as the samba default */
4094 9 : if (smb_krb5_context) {
4095 9 : unix_to_nt_time(&k->clock_skew,
4096 : krb5_get_max_time_skew(smb_krb5_context->krb5_context));
4097 : }
4098 : #endif
4099 12 : k->reserved = 0;
4100 12 : }
4101 : /*
4102 : lsa_QueryDomainInformationPolicy
4103 : */
4104 24 : static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
4105 : TALLOC_CTX *mem_ctx,
4106 : struct lsa_QueryDomainInformationPolicy *r)
4107 : {
4108 0 : union lsa_DomainInformationPolicy *info;
4109 :
4110 24 : info = talloc_zero(r->out.info, union lsa_DomainInformationPolicy);
4111 24 : if (!info) {
4112 0 : return NT_STATUS_NO_MEMORY;
4113 : }
4114 :
4115 24 : switch (r->in.level) {
4116 12 : case LSA_DOMAIN_INFO_POLICY_EFS:
4117 12 : talloc_free(info);
4118 12 : *r->out.info = NULL;
4119 12 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4120 12 : case LSA_DOMAIN_INFO_POLICY_KERBEROS:
4121 : {
4122 12 : struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
4123 0 : struct smb_krb5_context *smb_krb5_context;
4124 12 : int ret = smb_krb5_init_context(mem_ctx,
4125 12 : dce_call->conn->dce_ctx->lp_ctx,
4126 : &smb_krb5_context);
4127 12 : if (ret != 0) {
4128 0 : talloc_free(info);
4129 0 : *r->out.info = NULL;
4130 0 : return NT_STATUS_INTERNAL_ERROR;
4131 : }
4132 12 : kdc_get_policy(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
4133 : smb_krb5_context,
4134 : k);
4135 12 : talloc_free(smb_krb5_context);
4136 12 : *r->out.info = info;
4137 12 : return NT_STATUS_OK;
4138 : }
4139 0 : default:
4140 0 : talloc_free(info);
4141 0 : *r->out.info = NULL;
4142 0 : return NT_STATUS_INVALID_INFO_CLASS;
4143 : }
4144 : }
4145 :
4146 : /*
4147 : lsa_SetDomInfoPolicy
4148 : */
4149 0 : static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
4150 : TALLOC_CTX *mem_ctx,
4151 : struct lsa_SetDomainInformationPolicy *r)
4152 : {
4153 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4154 : }
4155 :
4156 : /*
4157 : lsa_TestCall
4158 : */
4159 0 : static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
4160 : TALLOC_CTX *mem_ctx,
4161 : struct lsa_TestCall *r)
4162 : {
4163 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4164 : }
4165 :
4166 : /*
4167 : lsa_CREDRWRITE
4168 : */
4169 0 : static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4170 : struct lsa_CREDRWRITE *r)
4171 : {
4172 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4173 : }
4174 :
4175 :
4176 : /*
4177 : lsa_CREDRREAD
4178 : */
4179 0 : static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4180 : struct lsa_CREDRREAD *r)
4181 : {
4182 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4183 : }
4184 :
4185 :
4186 : /*
4187 : lsa_CREDRENUMERATE
4188 : */
4189 0 : static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4190 : struct lsa_CREDRENUMERATE *r)
4191 : {
4192 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4193 : }
4194 :
4195 :
4196 : /*
4197 : lsa_CREDRWRITEDOMAINCREDENTIALS
4198 : */
4199 0 : static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4200 : struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
4201 : {
4202 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4203 : }
4204 :
4205 :
4206 : /*
4207 : lsa_CREDRREADDOMAINCREDENTIALS
4208 : */
4209 0 : static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4210 : struct lsa_CREDRREADDOMAINCREDENTIALS *r)
4211 : {
4212 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4213 : }
4214 :
4215 :
4216 : /*
4217 : lsa_CREDRDELETE
4218 : */
4219 0 : static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4220 : struct lsa_CREDRDELETE *r)
4221 : {
4222 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4223 : }
4224 :
4225 :
4226 : /*
4227 : lsa_CREDRGETTARGETINFO
4228 : */
4229 0 : static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4230 : struct lsa_CREDRGETTARGETINFO *r)
4231 : {
4232 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4233 : }
4234 :
4235 :
4236 : /*
4237 : lsa_CREDRPROFILELOADED
4238 : */
4239 0 : static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4240 : struct lsa_CREDRPROFILELOADED *r)
4241 : {
4242 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4243 : }
4244 :
4245 :
4246 : /*
4247 : lsa_CREDRGETSESSIONTYPES
4248 : */
4249 0 : static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4250 : struct lsa_CREDRGETSESSIONTYPES *r)
4251 : {
4252 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4253 : }
4254 :
4255 :
4256 : /*
4257 : lsa_LSARREGISTERAUDITEVENT
4258 : */
4259 0 : static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4260 : struct lsa_LSARREGISTERAUDITEVENT *r)
4261 : {
4262 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4263 : }
4264 :
4265 :
4266 : /*
4267 : lsa_LSARGENAUDITEVENT
4268 : */
4269 0 : static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4270 : struct lsa_LSARGENAUDITEVENT *r)
4271 : {
4272 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4273 : }
4274 :
4275 :
4276 : /*
4277 : lsa_LSARUNREGISTERAUDITEVENT
4278 : */
4279 0 : static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4280 : struct lsa_LSARUNREGISTERAUDITEVENT *r)
4281 : {
4282 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4283 : }
4284 :
4285 :
4286 : /*
4287 : lsa_lsaRQueryForestTrustInformation
4288 : */
4289 164 : static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4290 : struct lsa_lsaRQueryForestTrustInformation *r)
4291 : {
4292 164 : struct dcesrv_handle *h = NULL;
4293 164 : struct lsa_policy_state *p_state = NULL;
4294 164 : int forest_level = DS_DOMAIN_FUNCTION_2000;
4295 164 : const char * const trust_attrs[] = {
4296 : "securityIdentifier",
4297 : "flatName",
4298 : "trustPartner",
4299 : "trustAttributes",
4300 : "trustDirection",
4301 : "trustType",
4302 : "msDS-TrustForestTrustInfo",
4303 : NULL
4304 : };
4305 164 : struct ldb_message *trust_tdo_msg = NULL;
4306 164 : struct lsa_TrustDomainInfoInfoEx *trust_tdo = NULL;
4307 164 : struct ForestTrustInfo *trust_fti = NULL;
4308 164 : struct lsa_ForestTrustInformation *trust_lfti = NULL;
4309 0 : NTSTATUS status;
4310 :
4311 164 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4312 :
4313 164 : p_state = h->data;
4314 :
4315 164 : if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4316 0 : return NT_STATUS_INVALID_DOMAIN_STATE;
4317 : }
4318 :
4319 164 : forest_level = dsdb_forest_functional_level(p_state->sam_ldb);
4320 164 : if (forest_level < DS_DOMAIN_FUNCTION_2003) {
4321 0 : return NT_STATUS_INVALID_DOMAIN_STATE;
4322 : }
4323 :
4324 164 : if (r->in.trusted_domain_name->string == NULL) {
4325 0 : return NT_STATUS_NO_SUCH_DOMAIN;
4326 : }
4327 :
4328 164 : status = dsdb_trust_search_tdo(p_state->sam_ldb,
4329 164 : r->in.trusted_domain_name->string,
4330 164 : r->in.trusted_domain_name->string,
4331 : trust_attrs, mem_ctx, &trust_tdo_msg);
4332 164 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4333 0 : return NT_STATUS_NO_SUCH_DOMAIN;
4334 : }
4335 164 : if (!NT_STATUS_IS_OK(status)) {
4336 0 : return status;
4337 : }
4338 :
4339 164 : status = dsdb_trust_parse_tdo_info(mem_ctx, trust_tdo_msg, &trust_tdo);
4340 164 : if (!NT_STATUS_IS_OK(status)) {
4341 0 : return status;
4342 : }
4343 :
4344 164 : if (!(trust_tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4345 0 : return NT_STATUS_INVALID_PARAMETER;
4346 : }
4347 :
4348 164 : if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4349 0 : return NT_STATUS_INVALID_PARAMETER;
4350 : }
4351 :
4352 164 : status = dsdb_trust_parse_forest_info(mem_ctx,
4353 : trust_tdo_msg,
4354 : &trust_fti);
4355 164 : if (!NT_STATUS_IS_OK(status)) {
4356 8 : return status;
4357 : }
4358 :
4359 156 : status = dsdb_trust_forest_info_to_lsa(mem_ctx, trust_fti,
4360 : &trust_lfti);
4361 156 : if (!NT_STATUS_IS_OK(status)) {
4362 0 : return status;
4363 : }
4364 :
4365 156 : *r->out.forest_trust_info = trust_lfti;
4366 156 : return NT_STATUS_OK;
4367 : }
4368 :
4369 : /*
4370 : lsa_lsaRSetForestTrustInformation
4371 : */
4372 87 : static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_state *dce_call,
4373 : TALLOC_CTX *mem_ctx,
4374 : struct lsa_lsaRSetForestTrustInformation *r)
4375 : {
4376 0 : struct dcesrv_handle *h;
4377 0 : struct lsa_policy_state *p_state;
4378 87 : const char * const trust_attrs[] = {
4379 : "securityIdentifier",
4380 : "flatName",
4381 : "trustPartner",
4382 : "trustAttributes",
4383 : "trustDirection",
4384 : "trustType",
4385 : "msDS-TrustForestTrustInfo",
4386 : NULL
4387 : };
4388 87 : struct ldb_message *trust_tdo_msg = NULL;
4389 87 : struct lsa_TrustDomainInfoInfoEx *trust_tdo = NULL;
4390 87 : struct lsa_ForestTrustInformation *step1_lfti = NULL;
4391 87 : struct lsa_ForestTrustInformation *step2_lfti = NULL;
4392 87 : struct ForestTrustInfo *trust_fti = NULL;
4393 87 : struct ldb_result *trusts_res = NULL;
4394 0 : unsigned int i;
4395 87 : struct lsa_TrustDomainInfoInfoEx *xref_tdo = NULL;
4396 87 : struct lsa_ForestTrustInformation *xref_lfti = NULL;
4397 87 : struct lsa_ForestTrustCollisionInfo *c_info = NULL;
4398 87 : DATA_BLOB ft_blob = {};
4399 87 : struct ldb_message *msg = NULL;
4400 87 : struct server_id *server_ids = NULL;
4401 87 : uint32_t num_server_ids = 0;
4402 0 : NTSTATUS status;
4403 0 : enum ndr_err_code ndr_err;
4404 0 : int ret;
4405 87 : bool in_transaction = false;
4406 0 : struct imessaging_context *imsg_ctx =
4407 87 : dcesrv_imessaging_context(dce_call->conn);
4408 :
4409 87 : DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
4410 :
4411 87 : p_state = h->data;
4412 :
4413 87 : if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
4414 0 : return NT_STATUS_INVALID_DOMAIN_STATE;
4415 : }
4416 :
4417 87 : if (r->in.check_only == 0) {
4418 79 : ret = ldb_transaction_start(p_state->sam_ldb);
4419 79 : if (ret != LDB_SUCCESS) {
4420 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
4421 : }
4422 79 : in_transaction = true;
4423 : }
4424 :
4425 : /*
4426 : * abort if we are not a PDC
4427 : *
4428 : * In future we should use a function like IsEffectiveRoleOwner()
4429 : */
4430 87 : if (!samdb_is_pdc(p_state->sam_ldb)) {
4431 0 : status = NT_STATUS_INVALID_DOMAIN_ROLE;
4432 0 : goto done;
4433 : }
4434 :
4435 87 : if (r->in.trusted_domain_name->string == NULL) {
4436 0 : status = NT_STATUS_NO_SUCH_DOMAIN;
4437 0 : goto done;
4438 : }
4439 :
4440 87 : status = dsdb_trust_search_tdo(p_state->sam_ldb,
4441 87 : r->in.trusted_domain_name->string,
4442 87 : r->in.trusted_domain_name->string,
4443 : trust_attrs, mem_ctx, &trust_tdo_msg);
4444 87 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4445 0 : status = NT_STATUS_NO_SUCH_DOMAIN;
4446 0 : goto done;
4447 : }
4448 87 : if (!NT_STATUS_IS_OK(status)) {
4449 0 : goto done;
4450 : }
4451 :
4452 87 : status = dsdb_trust_parse_tdo_info(mem_ctx, trust_tdo_msg, &trust_tdo);
4453 87 : if (!NT_STATUS_IS_OK(status)) {
4454 0 : goto done;
4455 : }
4456 :
4457 87 : if (!(trust_tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
4458 0 : status = NT_STATUS_INVALID_PARAMETER;
4459 0 : goto done;
4460 : }
4461 :
4462 87 : if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
4463 0 : status = NT_STATUS_INVALID_PARAMETER;
4464 0 : goto done;
4465 : }
4466 :
4467 : /*
4468 : * verify and normalize the given forest trust info.
4469 : *
4470 : * Step1: doesn't reorder yet, so step1_lfti might contain
4471 : * NULL entries. This means dsdb_trust_verify_forest_info()
4472 : * can generate collision entries with the callers index.
4473 : */
4474 87 : status = dsdb_trust_normalize_forest_info_step1(mem_ctx,
4475 87 : r->in.forest_trust_info,
4476 : &step1_lfti);
4477 87 : if (!NT_STATUS_IS_OK(status)) {
4478 0 : goto done;
4479 : }
4480 :
4481 87 : c_info = talloc_zero(r->out.collision_info,
4482 : struct lsa_ForestTrustCollisionInfo);
4483 87 : if (c_info == NULL) {
4484 0 : status = NT_STATUS_NO_MEMORY;
4485 0 : goto done;
4486 : }
4487 :
4488 : /*
4489 : * First check our own forest, then other domains/forests
4490 : */
4491 :
4492 87 : status = dsdb_trust_xref_tdo_info(mem_ctx, p_state->sam_ldb,
4493 : &xref_tdo);
4494 87 : if (!NT_STATUS_IS_OK(status)) {
4495 0 : goto done;
4496 : }
4497 87 : status = dsdb_trust_xref_forest_info(mem_ctx, p_state->sam_ldb,
4498 : &xref_lfti);
4499 87 : if (!NT_STATUS_IS_OK(status)) {
4500 0 : goto done;
4501 : }
4502 :
4503 : /*
4504 : * The documentation proposed to generate
4505 : * LSA_FOREST_TRUST_COLLISION_XREF collisions.
4506 : * But Windows always uses LSA_FOREST_TRUST_COLLISION_TDO.
4507 : */
4508 87 : status = dsdb_trust_verify_forest_info(xref_tdo, xref_lfti,
4509 : LSA_FOREST_TRUST_COLLISION_TDO,
4510 : c_info, step1_lfti);
4511 87 : if (!NT_STATUS_IS_OK(status)) {
4512 0 : goto done;
4513 : }
4514 :
4515 : /* fetch all other trusted domain objects */
4516 87 : status = dsdb_trust_search_tdos(p_state->sam_ldb,
4517 87 : trust_tdo->domain_name.string,
4518 : trust_attrs,
4519 : mem_ctx, &trusts_res);
4520 87 : if (!NT_STATUS_IS_OK(status)) {
4521 0 : goto done;
4522 : }
4523 :
4524 : /*
4525 : * now check against the other domains.
4526 : * and generate LSA_FOREST_TRUST_COLLISION_TDO collisions.
4527 : */
4528 87 : for (i = 0; i < trusts_res->count; i++) {
4529 0 : struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
4530 0 : struct ForestTrustInfo *fti = NULL;
4531 0 : struct lsa_ForestTrustInformation *lfti = NULL;
4532 :
4533 0 : status = dsdb_trust_parse_tdo_info(mem_ctx,
4534 0 : trusts_res->msgs[i],
4535 : &tdo);
4536 0 : if (!NT_STATUS_IS_OK(status)) {
4537 0 : goto done;
4538 : }
4539 :
4540 0 : status = dsdb_trust_parse_forest_info(tdo,
4541 0 : trusts_res->msgs[i],
4542 : &fti);
4543 0 : if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
4544 0 : continue;
4545 : }
4546 0 : if (!NT_STATUS_IS_OK(status)) {
4547 0 : goto done;
4548 : }
4549 :
4550 0 : status = dsdb_trust_forest_info_to_lsa(tdo, fti, &lfti);
4551 0 : if (!NT_STATUS_IS_OK(status)) {
4552 0 : goto done;
4553 : }
4554 :
4555 0 : status = dsdb_trust_verify_forest_info(tdo, lfti,
4556 : LSA_FOREST_TRUST_COLLISION_TDO,
4557 : c_info, step1_lfti);
4558 0 : if (!NT_STATUS_IS_OK(status)) {
4559 0 : goto done;
4560 : }
4561 :
4562 0 : TALLOC_FREE(tdo);
4563 : }
4564 :
4565 87 : if (r->in.check_only != 0) {
4566 8 : status = NT_STATUS_OK;
4567 8 : goto done;
4568 : }
4569 :
4570 : /*
4571 : * not just a check, write info back
4572 : */
4573 :
4574 : /*
4575 : * normalize the given forest trust info.
4576 : *
4577 : * Step2: adds TOP_LEVEL_NAME[_EX] in reverse order,
4578 : * followed by DOMAIN_INFO in reverse order. It also removes
4579 : * possible NULL entries from Step1.
4580 : */
4581 79 : status = dsdb_trust_normalize_forest_info_step2(mem_ctx, step1_lfti,
4582 : &step2_lfti);
4583 79 : if (!NT_STATUS_IS_OK(status)) {
4584 0 : goto done;
4585 : }
4586 :
4587 79 : status = dsdb_trust_forest_info_from_lsa(mem_ctx, step2_lfti,
4588 : &trust_fti);
4589 79 : if (!NT_STATUS_IS_OK(status)) {
4590 0 : goto done;
4591 : }
4592 :
4593 79 : ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, trust_fti,
4594 : (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
4595 79 : if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4596 0 : status = NT_STATUS_INVALID_PARAMETER;
4597 0 : goto done;
4598 : }
4599 :
4600 79 : msg = ldb_msg_new(mem_ctx);
4601 79 : if (msg == NULL) {
4602 0 : status = NT_STATUS_NO_MEMORY;
4603 0 : goto done;
4604 : }
4605 :
4606 79 : msg->dn = ldb_dn_copy(mem_ctx, trust_tdo_msg->dn);
4607 79 : if (!msg->dn) {
4608 0 : status = NT_STATUS_NO_MEMORY;
4609 0 : goto done;
4610 : }
4611 :
4612 79 : ret = ldb_msg_append_value(msg, "msDS-TrustForestTrustInfo",
4613 : &ft_blob, LDB_FLAG_MOD_REPLACE);
4614 79 : if (ret != LDB_SUCCESS) {
4615 0 : status = NT_STATUS_NO_MEMORY;
4616 0 : goto done;
4617 : }
4618 :
4619 79 : ret = ldb_modify(p_state->sam_ldb, msg);
4620 79 : if (ret != LDB_SUCCESS) {
4621 0 : status = dsdb_ldb_err_to_ntstatus(ret);
4622 :
4623 0 : DEBUG(0, ("Failed to store Forest Trust Info: %s\n",
4624 : ldb_errstring(p_state->sam_ldb)));
4625 :
4626 0 : goto done;
4627 : }
4628 :
4629 : /* ok, all fine, commit transaction and return */
4630 79 : in_transaction = false;
4631 79 : ret = ldb_transaction_commit(p_state->sam_ldb);
4632 79 : if (ret != LDB_SUCCESS) {
4633 0 : status = NT_STATUS_INTERNAL_DB_CORRUPTION;
4634 0 : goto done;
4635 : }
4636 :
4637 : /*
4638 : * Notify winbindd that we have a acquired forest trust info
4639 : */
4640 79 : status = irpc_servers_byname(imsg_ctx,
4641 : mem_ctx,
4642 : "winbind_server",
4643 : &num_server_ids,
4644 : &server_ids);
4645 79 : if (!NT_STATUS_IS_OK(status)) {
4646 0 : DBG_ERR("irpc_servers_byname failed\n");
4647 0 : goto done;
4648 : }
4649 :
4650 79 : imessaging_send(imsg_ctx,
4651 : server_ids[0],
4652 : MSG_WINBIND_RELOAD_TRUSTED_DOMAINS,
4653 : NULL);
4654 :
4655 79 : status = NT_STATUS_OK;
4656 :
4657 87 : done:
4658 87 : if (NT_STATUS_IS_OK(status) && c_info->count != 0) {
4659 20 : *r->out.collision_info = c_info;
4660 : }
4661 :
4662 87 : if (in_transaction) {
4663 0 : ldb_transaction_cancel(p_state->sam_ldb);
4664 : }
4665 :
4666 87 : return status;
4667 : }
4668 :
4669 : /*
4670 : lsa_CREDRRENAME
4671 : */
4672 0 : static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4673 : struct lsa_CREDRRENAME *r)
4674 : {
4675 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4676 : }
4677 :
4678 :
4679 :
4680 : /*
4681 : lsa_LSAROPENPOLICYSCE
4682 : */
4683 0 : static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4684 : struct lsa_LSAROPENPOLICYSCE *r)
4685 : {
4686 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4687 : }
4688 :
4689 :
4690 : /*
4691 : lsa_LSARADTREGISTERSECURITYEVENTSOURCE
4692 : */
4693 0 : static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4694 : struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
4695 : {
4696 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4697 : }
4698 :
4699 :
4700 : /*
4701 : lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
4702 : */
4703 0 : static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4704 : struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
4705 : {
4706 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4707 : }
4708 :
4709 :
4710 : /*
4711 : lsa_LSARADTREPORTSECURITYEVENT
4712 : */
4713 0 : static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
4714 : struct lsa_LSARADTREPORTSECURITYEVENT *r)
4715 : {
4716 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
4717 : }
4718 :
4719 : /*
4720 : lsa_Opnum82NotUsedOnWire
4721 : */
4722 0 : static void dcesrv_lsa_Opnum82NotUsedOnWire(struct dcesrv_call_state *dce_call,
4723 : TALLOC_CTX *mem_ctx,
4724 : struct lsa_Opnum82NotUsedOnWire *r)
4725 : {
4726 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4727 : }
4728 :
4729 : /*
4730 : lsa_Opnum83NotUsedOnWire
4731 : */
4732 0 : static void dcesrv_lsa_Opnum83NotUsedOnWire(struct dcesrv_call_state *dce_call,
4733 : TALLOC_CTX *mem_ctx,
4734 : struct lsa_Opnum83NotUsedOnWire *r)
4735 : {
4736 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4737 : }
4738 :
4739 : /*
4740 : lsa_Opnum84NotUsedOnWire
4741 : */
4742 0 : static void dcesrv_lsa_Opnum84NotUsedOnWire(struct dcesrv_call_state *dce_call,
4743 : TALLOC_CTX *mem_ctx,
4744 : struct lsa_Opnum84NotUsedOnWire *r)
4745 : {
4746 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4747 : }
4748 :
4749 : /*
4750 : lsa_Opnum85NotUsedOnWire
4751 : */
4752 0 : static void dcesrv_lsa_Opnum85NotUsedOnWire(struct dcesrv_call_state *dce_call,
4753 : TALLOC_CTX *mem_ctx,
4754 : struct lsa_Opnum85NotUsedOnWire *r)
4755 : {
4756 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4757 : }
4758 :
4759 : /*
4760 : lsa_Opnum86NotUsedOnWire
4761 : */
4762 0 : static void dcesrv_lsa_Opnum86NotUsedOnWire(struct dcesrv_call_state *dce_call,
4763 : TALLOC_CTX *mem_ctx,
4764 : struct lsa_Opnum86NotUsedOnWire *r)
4765 : {
4766 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4767 : }
4768 :
4769 : /*
4770 : lsa_Opnum87NotUsedOnWire
4771 : */
4772 0 : static void dcesrv_lsa_Opnum87NotUsedOnWire(struct dcesrv_call_state *dce_call,
4773 : TALLOC_CTX *mem_ctx,
4774 : struct lsa_Opnum87NotUsedOnWire *r)
4775 : {
4776 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4777 : }
4778 :
4779 : /*
4780 : lsa_Opnum88NotUsedOnWire
4781 : */
4782 0 : static void dcesrv_lsa_Opnum88NotUsedOnWire(struct dcesrv_call_state *dce_call,
4783 : TALLOC_CTX *mem_ctx,
4784 : struct lsa_Opnum88NotUsedOnWire *r)
4785 : {
4786 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4787 : }
4788 :
4789 : /*
4790 : lsa_Opnum89NotUsedOnWire
4791 : */
4792 0 : static void dcesrv_lsa_Opnum89NotUsedOnWire(struct dcesrv_call_state *dce_call,
4793 : TALLOC_CTX *mem_ctx,
4794 : struct lsa_Opnum89NotUsedOnWire *r)
4795 : {
4796 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4797 : }
4798 :
4799 : /*
4800 : lsa_Opnum90NotUsedOnWire
4801 : */
4802 0 : static void dcesrv_lsa_Opnum90NotUsedOnWire(struct dcesrv_call_state *dce_call,
4803 : TALLOC_CTX *mem_ctx,
4804 : struct lsa_Opnum90NotUsedOnWire *r)
4805 : {
4806 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4807 : }
4808 :
4809 : /*
4810 : lsa_Opnum91NotUsedOnWire
4811 : */
4812 0 : static void dcesrv_lsa_Opnum91NotUsedOnWire(struct dcesrv_call_state *dce_call,
4813 : TALLOC_CTX *mem_ctx,
4814 : struct lsa_Opnum91NotUsedOnWire *r)
4815 : {
4816 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4817 : }
4818 :
4819 : /*
4820 : lsa_Opnum92NotUsedOnWire
4821 : */
4822 0 : static void dcesrv_lsa_Opnum92NotUsedOnWire(struct dcesrv_call_state *dce_call,
4823 : TALLOC_CTX *mem_ctx,
4824 : struct lsa_Opnum92NotUsedOnWire *r)
4825 : {
4826 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4827 : }
4828 :
4829 : /*
4830 : lsa_Opnum93NotUsedOnWire
4831 : */
4832 0 : static void dcesrv_lsa_Opnum93NotUsedOnWire(struct dcesrv_call_state *dce_call,
4833 : TALLOC_CTX *mem_ctx,
4834 : struct lsa_Opnum93NotUsedOnWire *r)
4835 : {
4836 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4837 : }
4838 :
4839 : /*
4840 : lsa_Opnum94NotUsedOnWire
4841 : */
4842 0 : static void dcesrv_lsa_Opnum94NotUsedOnWire(struct dcesrv_call_state *dce_call,
4843 : TALLOC_CTX *mem_ctx,
4844 : struct lsa_Opnum94NotUsedOnWire *r)
4845 : {
4846 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4847 : }
4848 :
4849 : /*
4850 : lsa_Opnum95NotUsedOnWire
4851 : */
4852 0 : static void dcesrv_lsa_Opnum95NotUsedOnWire(struct dcesrv_call_state *dce_call,
4853 : TALLOC_CTX *mem_ctx,
4854 : struct lsa_Opnum95NotUsedOnWire *r)
4855 : {
4856 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4857 : }
4858 :
4859 : /*
4860 : lsa_Opnum96NotUsedOnWire
4861 : */
4862 0 : static void dcesrv_lsa_Opnum96NotUsedOnWire(struct dcesrv_call_state *dce_call,
4863 : TALLOC_CTX *mem_ctx,
4864 : struct lsa_Opnum96NotUsedOnWire *r)
4865 : {
4866 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4867 : }
4868 :
4869 : /*
4870 : lsa_Opnum97NotUsedOnWire
4871 : */
4872 0 : static void dcesrv_lsa_Opnum97NotUsedOnWire(struct dcesrv_call_state *dce_call,
4873 : TALLOC_CTX *mem_ctx,
4874 : struct lsa_Opnum97NotUsedOnWire *r)
4875 : {
4876 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4877 : }
4878 :
4879 : /*
4880 : lsa_Opnum98NotUsedOnWire
4881 : */
4882 0 : static void dcesrv_lsa_Opnum98NotUsedOnWire(struct dcesrv_call_state *dce_call,
4883 : TALLOC_CTX *mem_ctx,
4884 : struct lsa_Opnum98NotUsedOnWire *r)
4885 : {
4886 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4887 : }
4888 :
4889 : /*
4890 : lsa_Opnum99NotUsedOnWire
4891 : */
4892 0 : static void dcesrv_lsa_Opnum99NotUsedOnWire(struct dcesrv_call_state *dce_call,
4893 : TALLOC_CTX *mem_ctx,
4894 : struct lsa_Opnum99NotUsedOnWire *r)
4895 : {
4896 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4897 : }
4898 :
4899 : /*
4900 : lsa_Opnum100NotUsedOnWire
4901 : */
4902 0 : static void dcesrv_lsa_Opnum100NotUsedOnWire(struct dcesrv_call_state *dce_call,
4903 : TALLOC_CTX *mem_ctx,
4904 : struct lsa_Opnum100NotUsedOnWire *r)
4905 : {
4906 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4907 : }
4908 :
4909 : /*
4910 : lsa_Opnum101NotUsedOnWire
4911 : */
4912 0 : static void dcesrv_lsa_Opnum101NotUsedOnWire(struct dcesrv_call_state *dce_call,
4913 : TALLOC_CTX *mem_ctx,
4914 : struct lsa_Opnum101NotUsedOnWire *r)
4915 : {
4916 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4917 : }
4918 :
4919 : /*
4920 : lsa_Opnum102NotUsedOnWire
4921 : */
4922 0 : static void dcesrv_lsa_Opnum102NotUsedOnWire(struct dcesrv_call_state *dce_call,
4923 : TALLOC_CTX *mem_ctx,
4924 : struct lsa_Opnum102NotUsedOnWire *r)
4925 : {
4926 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4927 : }
4928 :
4929 : /*
4930 : lsa_Opnum103NotUsedOnWire
4931 : */
4932 0 : static void dcesrv_lsa_Opnum103NotUsedOnWire(struct dcesrv_call_state *dce_call,
4933 : TALLOC_CTX *mem_ctx,
4934 : struct lsa_Opnum103NotUsedOnWire *r)
4935 : {
4936 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4937 : }
4938 :
4939 : /*
4940 : lsa_Opnum104NotUsedOnWire
4941 : */
4942 0 : static void dcesrv_lsa_Opnum104NotUsedOnWire(struct dcesrv_call_state *dce_call,
4943 : TALLOC_CTX *mem_ctx,
4944 : struct lsa_Opnum104NotUsedOnWire *r)
4945 : {
4946 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4947 : }
4948 :
4949 : /*
4950 : lsa_Opnum105NotUsedOnWire
4951 : */
4952 0 : static void dcesrv_lsa_Opnum105NotUsedOnWire(struct dcesrv_call_state *dce_call,
4953 : TALLOC_CTX *mem_ctx,
4954 : struct lsa_Opnum105NotUsedOnWire *r)
4955 : {
4956 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4957 : }
4958 :
4959 : /*
4960 : lsa_Opnum106NotUsedOnWire
4961 : */
4962 0 : static void dcesrv_lsa_Opnum106NotUsedOnWire(struct dcesrv_call_state *dce_call,
4963 : TALLOC_CTX *mem_ctx,
4964 : struct lsa_Opnum106NotUsedOnWire *r)
4965 : {
4966 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4967 : }
4968 :
4969 : /*
4970 : lsa_Opnum107NotUsedOnWire
4971 : */
4972 0 : static void dcesrv_lsa_Opnum107NotUsedOnWire(struct dcesrv_call_state *dce_call,
4973 : TALLOC_CTX *mem_ctx,
4974 : struct lsa_Opnum107NotUsedOnWire *r)
4975 : {
4976 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4977 : }
4978 :
4979 : /*
4980 : lsa_Opnum108NotUsedOnWire
4981 : */
4982 0 : static void dcesrv_lsa_Opnum108NotUsedOnWire(struct dcesrv_call_state *dce_call,
4983 : TALLOC_CTX *mem_ctx,
4984 : struct lsa_Opnum108NotUsedOnWire *r)
4985 : {
4986 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4987 : }
4988 :
4989 : /*
4990 : lsa_Opnum109NotUsedOnWire
4991 : */
4992 0 : static void dcesrv_lsa_Opnum109NotUsedOnWire(struct dcesrv_call_state *dce_call,
4993 : TALLOC_CTX *mem_ctx,
4994 : struct lsa_Opnum109NotUsedOnWire *r)
4995 : {
4996 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
4997 : }
4998 :
4999 : /*
5000 : lsa_Opnum110NotUsedOnWire
5001 : */
5002 0 : static void dcesrv_lsa_Opnum110NotUsedOnWire(struct dcesrv_call_state *dce_call,
5003 : TALLOC_CTX *mem_ctx,
5004 : struct lsa_Opnum110NotUsedOnWire *r)
5005 : {
5006 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5007 : }
5008 :
5009 : /*
5010 : lsa_Opnum111NotUsedOnWire
5011 : */
5012 0 : static void dcesrv_lsa_Opnum111NotUsedOnWire(struct dcesrv_call_state *dce_call,
5013 : TALLOC_CTX *mem_ctx,
5014 : struct lsa_Opnum111NotUsedOnWire *r)
5015 : {
5016 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5017 : }
5018 :
5019 : /*
5020 : lsa_Opnum112NotUsedOnWire
5021 : */
5022 0 : static void dcesrv_lsa_Opnum112NotUsedOnWire(struct dcesrv_call_state *dce_call,
5023 : TALLOC_CTX *mem_ctx,
5024 : struct lsa_Opnum112NotUsedOnWire *r)
5025 : {
5026 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5027 : }
5028 :
5029 : /*
5030 : lsa_Opnum113NotUsedOnWire
5031 : */
5032 0 : static void dcesrv_lsa_Opnum113NotUsedOnWire(struct dcesrv_call_state *dce_call,
5033 : TALLOC_CTX *mem_ctx,
5034 : struct lsa_Opnum113NotUsedOnWire *r)
5035 : {
5036 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5037 : }
5038 :
5039 : /*
5040 : lsa_Opnum114NotUsedOnWire
5041 : */
5042 0 : static void dcesrv_lsa_Opnum114NotUsedOnWire(struct dcesrv_call_state *dce_call,
5043 : TALLOC_CTX *mem_ctx,
5044 : struct lsa_Opnum114NotUsedOnWire *r)
5045 : {
5046 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5047 : }
5048 :
5049 : /*
5050 : lsa_Opnum115NotUsedOnWire
5051 : */
5052 0 : static void dcesrv_lsa_Opnum115NotUsedOnWire(struct dcesrv_call_state *dce_call,
5053 : TALLOC_CTX *mem_ctx,
5054 : struct lsa_Opnum115NotUsedOnWire *r)
5055 : {
5056 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5057 : }
5058 :
5059 : /*
5060 : lsa_Opnum116NotUsedOnWire
5061 : */
5062 0 : static void dcesrv_lsa_Opnum116NotUsedOnWire(struct dcesrv_call_state *dce_call,
5063 : TALLOC_CTX *mem_ctx,
5064 : struct lsa_Opnum116NotUsedOnWire *r)
5065 : {
5066 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5067 : }
5068 :
5069 : /*
5070 : lsa_Opnum117NotUsedOnWire
5071 : */
5072 0 : static void dcesrv_lsa_Opnum117NotUsedOnWire(struct dcesrv_call_state *dce_call,
5073 : TALLOC_CTX *mem_ctx,
5074 : struct lsa_Opnum117NotUsedOnWire *r)
5075 : {
5076 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5077 : }
5078 :
5079 : /*
5080 : lsa_Opnum118NotUsedOnWire
5081 : */
5082 0 : static void dcesrv_lsa_Opnum118NotUsedOnWire(struct dcesrv_call_state *dce_call,
5083 : TALLOC_CTX *mem_ctx,
5084 : struct lsa_Opnum118NotUsedOnWire *r)
5085 : {
5086 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5087 : }
5088 :
5089 : /*
5090 : lsa_Opnum119NotUsedOnWire
5091 : */
5092 0 : static void dcesrv_lsa_Opnum119NotUsedOnWire(struct dcesrv_call_state *dce_call,
5093 : TALLOC_CTX *mem_ctx,
5094 : struct lsa_Opnum119NotUsedOnWire *r)
5095 : {
5096 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5097 : }
5098 :
5099 : /*
5100 : lsa_Opnum120NotUsedOnWire
5101 : */
5102 0 : static void dcesrv_lsa_Opnum120NotUsedOnWire(struct dcesrv_call_state *dce_call,
5103 : TALLOC_CTX *mem_ctx,
5104 : struct lsa_Opnum120NotUsedOnWire *r)
5105 : {
5106 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5107 : }
5108 :
5109 : /*
5110 : lsa_Opnum121NotUsedOnWire
5111 : */
5112 0 : static void dcesrv_lsa_Opnum121NotUsedOnWire(struct dcesrv_call_state *dce_call,
5113 : TALLOC_CTX *mem_ctx,
5114 : struct lsa_Opnum121NotUsedOnWire *r)
5115 : {
5116 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5117 : }
5118 :
5119 : /*
5120 : lsa_Opnum122NotUsedOnWire
5121 : */
5122 0 : static void dcesrv_lsa_Opnum122NotUsedOnWire(struct dcesrv_call_state *dce_call,
5123 : TALLOC_CTX *mem_ctx,
5124 : struct lsa_Opnum122NotUsedOnWire *r)
5125 : {
5126 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5127 : }
5128 :
5129 : /*
5130 : lsa_Opnum123NotUsedOnWire
5131 : */
5132 0 : static void dcesrv_lsa_Opnum123NotUsedOnWire(struct dcesrv_call_state *dce_call,
5133 : TALLOC_CTX *mem_ctx,
5134 : struct lsa_Opnum123NotUsedOnWire *r)
5135 : {
5136 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5137 : }
5138 :
5139 : /*
5140 : lsa_Opnum124NotUsedOnWire
5141 : */
5142 0 : static void dcesrv_lsa_Opnum124NotUsedOnWire(struct dcesrv_call_state *dce_call,
5143 : TALLOC_CTX *mem_ctx,
5144 : struct lsa_Opnum124NotUsedOnWire *r)
5145 : {
5146 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5147 : }
5148 :
5149 : /*
5150 : lsa_Opnum125NotUsedOnWire
5151 : */
5152 0 : static void dcesrv_lsa_Opnum125NotUsedOnWire(struct dcesrv_call_state *dce_call,
5153 : TALLOC_CTX *mem_ctx,
5154 : struct lsa_Opnum125NotUsedOnWire *r)
5155 : {
5156 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5157 : }
5158 :
5159 : /*
5160 : lsa_Opnum126NotUsedOnWire
5161 : */
5162 0 : static void dcesrv_lsa_Opnum126NotUsedOnWire(struct dcesrv_call_state *dce_call,
5163 : TALLOC_CTX *mem_ctx,
5164 : struct lsa_Opnum126NotUsedOnWire *r)
5165 : {
5166 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5167 : }
5168 :
5169 : /*
5170 : lsa_Opnum127NotUsedOnWire
5171 : */
5172 0 : static void dcesrv_lsa_Opnum127NotUsedOnWire(struct dcesrv_call_state *dce_call,
5173 : TALLOC_CTX *mem_ctx,
5174 : struct lsa_Opnum127NotUsedOnWire *r)
5175 : {
5176 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5177 : }
5178 :
5179 : /*
5180 : lsa_Opnum128NotUsedOnWire
5181 : */
5182 0 : static void dcesrv_lsa_Opnum128NotUsedOnWire(struct dcesrv_call_state *dce_call,
5183 : TALLOC_CTX *mem_ctx,
5184 : struct lsa_Opnum128NotUsedOnWire *r)
5185 : {
5186 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5187 : }
5188 :
5189 : /*
5190 : lsa_CreateTrustedDomainEx3
5191 : */
5192 0 : static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx3(struct dcesrv_call_state *dce_call,
5193 : TALLOC_CTX *mem_ctx,
5194 : struct lsa_CreateTrustedDomainEx3 *r)
5195 : {
5196 : /* TODO */
5197 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5198 : }
5199 :
5200 : /*
5201 : lsa_Opnum131NotUsedOnWire
5202 : */
5203 0 : static void dcesrv_lsa_Opnum131NotUsedOnWire(struct dcesrv_call_state *dce_call,
5204 : TALLOC_CTX *mem_ctx,
5205 : struct lsa_Opnum131NotUsedOnWire *r)
5206 : {
5207 0 : DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
5208 : }
5209 :
5210 : /*
5211 : lsa_lsaRQueryForestTrustInformation2
5212 : */
5213 0 : static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation2(
5214 : struct dcesrv_call_state *dce_call,
5215 : TALLOC_CTX *mem_ctx,
5216 : struct lsa_lsaRQueryForestTrustInformation2 *r)
5217 : {
5218 : /* TODO */
5219 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5220 : }
5221 :
5222 : /*
5223 : lsa_lsaRSetForestTrustInformation2
5224 : */
5225 0 : static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation2(struct dcesrv_call_state *dce_call,
5226 : TALLOC_CTX *mem_ctx,
5227 : struct lsa_lsaRSetForestTrustInformation2 *r)
5228 : {
5229 : /* TODO */
5230 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5231 : }
5232 :
5233 : /* include the generated boilerplate */
5234 : #include "librpc/gen_ndr/ndr_lsa_s.c"
5235 :
5236 :
5237 :
5238 : /*****************************************
5239 : NOTE! The remaining calls below were
5240 : removed in w2k3, so the DCESRV_FAULT()
5241 : replies are the correct implementation. Do
5242 : not try and fill these in with anything else
5243 : ******************************************/
5244 :
5245 : /*
5246 : dssetup_DsRoleDnsNameToFlatName
5247 : */
5248 0 : static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5249 : struct dssetup_DsRoleDnsNameToFlatName *r)
5250 : {
5251 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5252 : }
5253 :
5254 :
5255 : /*
5256 : dssetup_DsRoleDcAsDc
5257 : */
5258 0 : static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5259 : struct dssetup_DsRoleDcAsDc *r)
5260 : {
5261 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5262 : }
5263 :
5264 :
5265 : /*
5266 : dssetup_DsRoleDcAsReplica
5267 : */
5268 0 : static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5269 : struct dssetup_DsRoleDcAsReplica *r)
5270 : {
5271 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5272 : }
5273 :
5274 :
5275 : /*
5276 : dssetup_DsRoleDemoteDc
5277 : */
5278 0 : static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5279 : struct dssetup_DsRoleDemoteDc *r)
5280 : {
5281 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5282 : }
5283 :
5284 :
5285 : /*
5286 : dssetup_DsRoleGetDcOperationProgress
5287 : */
5288 0 : static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5289 : struct dssetup_DsRoleGetDcOperationProgress *r)
5290 : {
5291 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5292 : }
5293 :
5294 :
5295 : /*
5296 : dssetup_DsRoleGetDcOperationResults
5297 : */
5298 0 : static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5299 : struct dssetup_DsRoleGetDcOperationResults *r)
5300 : {
5301 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5302 : }
5303 :
5304 :
5305 : /*
5306 : dssetup_DsRoleCancel
5307 : */
5308 0 : static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5309 : struct dssetup_DsRoleCancel *r)
5310 : {
5311 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5312 : }
5313 :
5314 :
5315 : /*
5316 : dssetup_DsRoleServerSaveStateForUpgrade
5317 : */
5318 0 : static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5319 : struct dssetup_DsRoleServerSaveStateForUpgrade *r)
5320 : {
5321 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5322 : }
5323 :
5324 :
5325 : /*
5326 : dssetup_DsRoleUpgradeDownlevelServer
5327 : */
5328 0 : static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5329 : struct dssetup_DsRoleUpgradeDownlevelServer *r)
5330 : {
5331 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5332 : }
5333 :
5334 :
5335 : /*
5336 : dssetup_DsRoleAbortDownlevelServerUpgrade
5337 : */
5338 0 : static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
5339 : struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
5340 : {
5341 0 : DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
5342 : }
5343 :
5344 :
5345 : /* include the generated boilerplate */
5346 : #include "librpc/gen_ndr/ndr_dssetup_s.c"
5347 :
5348 66 : NTSTATUS dcerpc_server_lsa_init(TALLOC_CTX *ctx)
5349 : {
5350 2 : NTSTATUS ret;
5351 :
5352 66 : ret = dcerpc_server_dssetup_init(ctx);
5353 66 : if (!NT_STATUS_IS_OK(ret)) {
5354 0 : return ret;
5355 : }
5356 66 : ret = dcerpc_server_lsarpc_init(ctx);
5357 66 : if (!NT_STATUS_IS_OK(ret)) {
5358 0 : return ret;
5359 : }
5360 66 : return ret;
5361 : }
|