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