1 /*
2 Unix SMB/CIFS implementation.
3
4 endpoint server for the lsarpc pipe
5
6 Copyright (C) Andrew Tridgell 2004
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25 #include "rpc_server/dcerpc_server.h"
26 #include "rpc_server/common/common.h"
27 #include "auth/auth.h"
28 #include "dsdb/samdb/samdb.h"
29 #include "libcli/ldap/ldap.h"
30 #include "lib/ldb/include/ldb_errors.h"
31 #include "libcli/security/security.h"
32 #include "libcli/auth/libcli_auth.h"
33 #include "param/secrets.h"
34 #include "db_wrap.h"
35 #include "librpc/gen_ndr/ndr_dssetup.h"
36
37 /*
38 this type allows us to distinguish handle types
39 */
40 enum lsa_handle {
41 LSA_HANDLE_POLICY,
42 LSA_HANDLE_ACCOUNT,
43 LSA_HANDLE_SECRET,
44 LSA_HANDLE_TRUSTED_DOMAIN
45 };
46
47 /*
48 state associated with a lsa_OpenPolicy() operation
49 */
50 struct lsa_policy_state {
51 struct dcesrv_handle *handle;
52 struct ldb_context *sam_ldb;
53 struct sidmap_context *sidmap;
54 uint32_t access_mask;
55 struct ldb_dn *domain_dn;
56 struct ldb_dn *builtin_dn;
57 struct ldb_dn *system_dn;
58 const char *domain_name;
59 const char *domain_dns;
60 struct dom_sid *domain_sid;
61 struct GUID domain_guid;
62 struct dom_sid *builtin_sid;
63 int mixed_domain;
64 };
65
66
67 /*
68 state associated with a lsa_OpenAccount() operation
69 */
70 struct lsa_account_state {
71 struct lsa_policy_state *policy;
72 uint32_t access_mask;
73 struct dom_sid *account_sid;
74 };
75
76
77 /*
78 state associated with a lsa_OpenSecret() operation
79 */
80 struct lsa_secret_state {
81 struct lsa_policy_state *policy;
82 uint32_t access_mask;
83 struct ldb_dn *secret_dn;
84 struct ldb_context *sam_ldb;
85 BOOL global;
86 };
87
88 /*
89 state associated with a lsa_OpenTrustedDomain() operation
90 */
91 struct lsa_trusted_domain_state {
92 struct lsa_policy_state *policy;
93 uint32_t access_mask;
94 struct ldb_dn *trusted_domain_dn;
95 };
96
97 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
98 TALLOC_CTX *mem_ctx,
99 struct lsa_EnumAccountRights *r);
100
101 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
102 TALLOC_CTX *mem_ctx,
103 struct lsa_policy_state *state,
104 int ldb_flag,
105 struct dom_sid *sid,
106 const struct lsa_RightSet *rights);
107
108 /*
109 lsa_Close
110 */
lsa_Close(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_Close * r)111 static NTSTATUS lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
112 struct lsa_Close *r)
113 {
114 struct dcesrv_handle *h;
115
116 *r->out.handle = *r->in.handle;
117
118 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
119
120 talloc_free(h);
121
122 ZERO_STRUCTP(r->out.handle);
123
124 return NT_STATUS_OK;
125 }
126
127
128 /*
129 lsa_Delete
130 */
lsa_Delete(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_Delete * r)131 static NTSTATUS lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
132 struct lsa_Delete *r)
133 {
134 struct dcesrv_handle *h;
135 int ret;
136
137 DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
138 if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
139 struct lsa_secret_state *secret_state = h->data;
140 ret = samdb_delete(secret_state->sam_ldb, mem_ctx, secret_state->secret_dn);
141 talloc_free(h);
142 if (ret != 0) {
143 return NT_STATUS_INVALID_HANDLE;
144 }
145
146 return NT_STATUS_OK;
147 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
148 struct lsa_trusted_domain_state *trusted_domain_state = h->data;
149 ret = samdb_delete(trusted_domain_state->policy->sam_ldb, mem_ctx,
150 trusted_domain_state->trusted_domain_dn);
151 talloc_free(h);
152 if (ret != 0) {
153 return NT_STATUS_INVALID_HANDLE;
154 }
155
156 return NT_STATUS_OK;
157 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
158 struct lsa_RightSet *rights;
159 struct lsa_account_state *astate;
160 struct lsa_EnumAccountRights r2;
161 NTSTATUS status;
162
163 rights = talloc(mem_ctx, struct lsa_RightSet);
164
165 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
166
167 astate = h->data;
168
169 r2.in.handle = &astate->policy->handle->wire_handle;
170 r2.in.sid = astate->account_sid;
171 r2.out.rights = rights;
172
173 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
174 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
175 return NT_STATUS_OK;
176 }
177
178 if (!NT_STATUS_IS_OK(status)) {
179 return status;
180 }
181
182 status = lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
183 LDB_FLAG_MOD_DELETE, astate->account_sid,
184 r2.out.rights);
185 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
186 return NT_STATUS_OK;
187 }
188
189 if (!NT_STATUS_IS_OK(status)) {
190 return status;
191 }
192 }
193
194 return NT_STATUS_INVALID_HANDLE;
195 }
196
197
198 /*
199 lsa_EnumPrivs
200 */
lsa_EnumPrivs(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_EnumPrivs * r)201 static NTSTATUS lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
202 struct lsa_EnumPrivs *r)
203 {
204 struct dcesrv_handle *h;
205 struct lsa_policy_state *state;
206 int i;
207 const char *privname;
208
209 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
210
211 state = h->data;
212
213 i = *r->in.resume_handle;
214 if (i == 0) i = 1;
215
216 while ((privname = sec_privilege_name(i)) &&
217 r->out.privs->count < r->in.max_count) {
218 struct lsa_PrivEntry *e;
219
220 r->out.privs->privs = talloc_realloc(r->out.privs,
221 r->out.privs->privs,
222 struct lsa_PrivEntry,
223 r->out.privs->count+1);
224 if (r->out.privs->privs == NULL) {
225 return NT_STATUS_NO_MEMORY;
226 }
227 e = &r->out.privs->privs[r->out.privs->count];
228 e->luid.low = i;
229 e->luid.high = 0;
230 e->name.string = privname;
231 r->out.privs->count++;
232 i++;
233 }
234
235 *r->out.resume_handle = i;
236
237 return NT_STATUS_OK;
238 }
239
240
241 /*
242 lsa_QuerySecObj
243 */
lsa_QuerySecurity(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_QuerySecurity * r)244 static NTSTATUS lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
245 struct lsa_QuerySecurity *r)
246 {
247 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
248 }
249
250
251 /*
252 lsa_SetSecObj
253 */
lsa_SetSecObj(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_SetSecObj * r)254 static NTSTATUS lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
255 struct lsa_SetSecObj *r)
256 {
257 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
258 }
259
260
261 /*
262 lsa_ChangePassword
263 */
lsa_ChangePassword(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_ChangePassword * r)264 static NTSTATUS lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
265 struct lsa_ChangePassword *r)
266 {
267 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
268 }
269
lsa_get_policy_state(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_policy_state ** _state)270 static NTSTATUS lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
271 struct lsa_policy_state **_state)
272 {
273 struct lsa_policy_state *state;
274 struct ldb_dn *partitions_basedn;
275 struct ldb_result *dom_res;
276 const char *dom_attrs[] = {
277 "objectSid",
278 "objectGUID",
279 "nTMixedDomain",
280 NULL
281 };
282 struct ldb_result *ref_res;
283 const char *ref_attrs[] = {
284 "nETBIOSName",
285 "dnsRoot",
286 NULL
287 };
288 int ret;
289
290 state = talloc(mem_ctx, struct lsa_policy_state);
291 if (!state) {
292 return NT_STATUS_NO_MEMORY;
293 }
294
295 /* make sure the sam database is accessible */
296 state->sam_ldb = samdb_connect(state, dce_call->conn->auth_state.session_info);
297 if (state->sam_ldb == NULL) {
298 return NT_STATUS_INVALID_SYSTEM_SERVICE;
299 }
300
301 partitions_basedn = samdb_partitions_dn(state->sam_ldb, mem_ctx);
302
303 state->sidmap = sidmap_open(state);
304 if (state->sidmap == NULL) {
305 return NT_STATUS_INVALID_SYSTEM_SERVICE;
306 }
307
308 /* work out the domain_dn - useful for so many calls its worth
309 fetching here */
310 state->domain_dn = samdb_base_dn(state->sam_ldb);
311 if (!state->domain_dn) {
312 return NT_STATUS_NO_MEMORY;
313 }
314
315 ret = ldb_search(state->sam_ldb, state->domain_dn, LDB_SCOPE_BASE, NULL, dom_attrs, &dom_res);
316
317 if (ret != LDB_SUCCESS) {
318 return NT_STATUS_INVALID_SYSTEM_SERVICE;
319 }
320 talloc_steal(state, dom_res);
321 if (dom_res->count != 1) {
322 return NT_STATUS_NO_SUCH_DOMAIN;
323 }
324
325 state->domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
326 if (!state->domain_sid) {
327 return NT_STATUS_NO_SUCH_DOMAIN;
328 }
329
330 state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
331 if (!state->domain_sid) {
332 return NT_STATUS_NO_SUCH_DOMAIN;
333 }
334
335 state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
336
337 talloc_free(dom_res);
338
339 ret = ldb_search_exp_fmt(state->sam_ldb, state, &ref_res,
340 partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
341 "(&(objectclass=crossRef)(ncName=%s))",
342 ldb_dn_get_linearized(state->domain_dn));
343
344 if (ret != LDB_SUCCESS) {
345 talloc_free(ref_res);
346 return NT_STATUS_INVALID_SYSTEM_SERVICE;
347 }
348 if (ref_res->count != 1) {
349 talloc_free(ref_res);
350 return NT_STATUS_NO_SUCH_DOMAIN;
351 }
352
353 state->domain_name = ldb_msg_find_attr_as_string(ref_res->msgs[0], "nETBIOSName", NULL);
354 if (!state->domain_name) {
355 talloc_free(ref_res);
356 return NT_STATUS_NO_SUCH_DOMAIN;
357 }
358 talloc_steal(state, state->domain_name);
359
360 state->domain_dns = ldb_msg_find_attr_as_string(ref_res->msgs[0], "dnsRoot", NULL);
361 if (!state->domain_dns) {
362 talloc_free(ref_res);
363 return NT_STATUS_NO_SUCH_DOMAIN;
364 }
365 talloc_steal(state, state->domain_dns);
366
367 talloc_free(ref_res);
368
369 /* work out the builtin_dn - useful for so many calls its worth
370 fetching here */
371 state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
372 if (!state->builtin_dn) {
373 return NT_STATUS_NO_SUCH_DOMAIN;
374 }
375
376 /* work out the system_dn - useful for so many calls its worth
377 fetching here */
378 state->system_dn = samdb_search_dn(state->sam_ldb, state,
379 state->domain_dn, "(&(objectClass=container)(cn=System))");
380 if (!state->system_dn) {
381 return NT_STATUS_NO_SUCH_DOMAIN;
382 }
383
384 state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
385 if (!state->builtin_sid) {
386 return NT_STATUS_NO_SUCH_DOMAIN;
387 }
388
389 *_state = state;
390
391 return NT_STATUS_OK;
392 }
393
394 /*
395 dssetup_DsRoleGetPrimaryDomainInformation
396
397 This is not an LSA call, but is the only call left on the DSSETUP
398 pipe (after the pipe was truncated), and needs lsa_get_policy_state
399 */
dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct dssetup_DsRoleGetPrimaryDomainInformation * r)400 static WERROR dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
401 TALLOC_CTX *mem_ctx,
402 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
403 {
404 union dssetup_DsRoleInfo *info;
405
406 info = talloc(mem_ctx, union dssetup_DsRoleInfo);
407 W_ERROR_HAVE_NO_MEMORY(info);
408
409 switch (r->in.level) {
410 case DS_ROLE_BASIC_INFORMATION:
411 {
412 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
413 uint32_t flags = 0;
414 const char *domain = NULL;
415 const char *dns_domain = NULL;
416 const char *forest = NULL;
417 struct GUID domain_guid;
418 struct lsa_policy_state *state;
419
420 NTSTATUS status = lsa_get_policy_state(dce_call, mem_ctx, &state);
421 if (!NT_STATUS_IS_OK(status)) {
422 return ntstatus_to_werror(status);
423 }
424
425 ZERO_STRUCT(domain_guid);
426
427 switch (lp_server_role()) {
428 case ROLE_STANDALONE:
429 role = DS_ROLE_STANDALONE_SERVER;
430 break;
431 case ROLE_DOMAIN_MEMBER:
432 role = DS_ROLE_MEMBER_SERVER;
433 break;
434 case ROLE_DOMAIN_BDC:
435 role = DS_ROLE_BACKUP_DC;
436 break;
437 case ROLE_DOMAIN_PDC:
438 role = DS_ROLE_PRIMARY_DC;
439 break;
440 }
441
442 switch (lp_server_role()) {
443 case ROLE_STANDALONE:
444 domain = talloc_strdup(mem_ctx, lp_workgroup());
445 W_ERROR_HAVE_NO_MEMORY(domain);
446 break;
447 case ROLE_DOMAIN_MEMBER:
448 domain = talloc_strdup(mem_ctx, lp_workgroup());
449 W_ERROR_HAVE_NO_MEMORY(domain);
450 /* TODO: what is with dns_domain and forest and guid? */
451 break;
452 case ROLE_DOMAIN_BDC:
453 case ROLE_DOMAIN_PDC:
454 flags = DS_ROLE_PRIMARY_DS_RUNNING;
455
456 if (state->mixed_domain == 1) {
457 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
458 }
459
460 domain = state->domain_name;
461 dns_domain = state->domain_dns;
462 forest = state->domain_dns;
463
464 domain_guid = state->domain_guid;
465 flags |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
466 break;
467 }
468
469 info->basic.role = role;
470 info->basic.flags = flags;
471 info->basic.domain = domain;
472 info->basic.dns_domain = dns_domain;
473 info->basic.forest = forest;
474 info->basic.domain_guid = domain_guid;
475
476 r->out.info = info;
477 return WERR_OK;
478 }
479 case DS_ROLE_UPGRADE_STATUS:
480 {
481 info->upgrade.upgrading = DS_ROLE_NOT_UPGRADING;
482 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
483
484 r->out.info = info;
485 return WERR_OK;
486 }
487 case DS_ROLE_OP_STATUS:
488 {
489 info->opstatus.status = DS_ROLE_OP_IDLE;
490
491 r->out.info = info;
492 return WERR_OK;
493 }
494 default:
495 return WERR_INVALID_PARAM;
496 }
497
498 return WERR_INVALID_PARAM;
499 }
500
501 /*
502 lsa_OpenPolicy2
503 */
lsa_OpenPolicy2(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_OpenPolicy2 * r)504 static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
505 struct lsa_OpenPolicy2 *r)
506 {
507 NTSTATUS status;
508 struct lsa_policy_state *state;
509 struct dcesrv_handle *handle;
510
511 ZERO_STRUCTP(r->out.handle);
512
513 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
514 if (!NT_STATUS_IS_OK(status)) {
515 return status;
516 }
517
518 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
519 if (!handle) {
520 return NT_STATUS_NO_MEMORY;
521 }
522
523 handle->data = talloc_steal(handle, state);
524
525 state->access_mask = r->in.access_mask;
526 state->handle = handle;
527 *r->out.handle = handle->wire_handle;
528
529 /* note that we have completely ignored the attr element of
530 the OpenPolicy. As far as I can tell, this is what w2k3
531 does */
532
533 return NT_STATUS_OK;
534 }
535
536 /*
537 lsa_OpenPolicy
538 a wrapper around lsa_OpenPolicy2
539 */
lsa_OpenPolicy(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_OpenPolicy * r)540 static NTSTATUS lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
541 struct lsa_OpenPolicy *r)
542 {
543 struct lsa_OpenPolicy2 r2;
544
545 r2.in.system_name = NULL;
546 r2.in.attr = r->in.attr;
547 r2.in.access_mask = r->in.access_mask;
548 r2.out.handle = r->out.handle;
549
550 return lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
551 }
552
553
554
555
556 /*
557 fill in the AccountDomain info
558 */
lsa_info_AccountDomain(struct lsa_policy_state * state,TALLOC_CTX * mem_ctx,struct lsa_DomainInfo * info)559 static NTSTATUS lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
560 struct lsa_DomainInfo *info)
561 {
562 info->name.string = state->domain_name;
563 info->sid = state->domain_sid;
564
565 return NT_STATUS_OK;
566 }
567
568 /*
569 fill in the DNS domain info
570 */
lsa_info_DNS(struct lsa_policy_state * state,TALLOC_CTX * mem_ctx,struct lsa_DnsDomainInfo * info)571 static NTSTATUS lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
572 struct lsa_DnsDomainInfo *info)
573 {
574 info->name.string = state->domain_name;
575 info->sid = state->domain_sid;
576 info->dns_domain.string = state->domain_dns;
577 info->dns_forest.string = state->domain_dns;
578 info->domain_guid = state->domain_guid;
579
580 return NT_STATUS_OK;
581 }
582
583 /*
584 lsa_QueryInfoPolicy2
585 */
lsa_QueryInfoPolicy2(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_QueryInfoPolicy2 * r)586 static NTSTATUS lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
587 struct lsa_QueryInfoPolicy2 *r)
588 {
589 struct lsa_policy_state *state;
590 struct dcesrv_handle *h;
591
592 r->out.info = NULL;
593
594 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
595
596 state = h->data;
597
598 r->out.info = talloc(mem_ctx, union lsa_PolicyInformation);
599 if (!r->out.info) {
600 return NT_STATUS_NO_MEMORY;
601 }
602
603 ZERO_STRUCTP(r->out.info);
604
605 switch (r->in.level) {
606 case LSA_POLICY_INFO_DOMAIN:
607 case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
608 return lsa_info_AccountDomain(state, mem_ctx, &r->out.info->account_domain);
609
610 case LSA_POLICY_INFO_DNS:
611 return lsa_info_DNS(state, mem_ctx, &r->out.info->dns);
612 }
613
614 return NT_STATUS_INVALID_INFO_CLASS;
615 }
616
617 /*
618 lsa_QueryInfoPolicy
619 */
lsa_QueryInfoPolicy(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_QueryInfoPolicy * r)620 static NTSTATUS lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
621 struct lsa_QueryInfoPolicy *r)
622 {
623 struct lsa_QueryInfoPolicy2 r2;
624 NTSTATUS status;
625
626 r2.in.handle = r->in.handle;
627 r2.in.level = r->in.level;
628
629 status = lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
630
631 r->out.info = r2.out.info;
632
633 return status;
634 }
635
636 /*
637 lsa_SetInfoPolicy
638 */
lsa_SetInfoPolicy(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_SetInfoPolicy * r)639 static NTSTATUS lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
640 struct lsa_SetInfoPolicy *r)
641 {
642 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
643 }
644
645
646 /*
647 lsa_ClearAuditLog
648 */
lsa_ClearAuditLog(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_ClearAuditLog * r)649 static NTSTATUS lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
650 struct lsa_ClearAuditLog *r)
651 {
652 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
653 }
654
655
656 /*
657 lsa_CreateAccount
658 */
lsa_CreateAccount(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CreateAccount * r)659 static NTSTATUS lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
660 struct lsa_CreateAccount *r)
661 {
662 struct lsa_account_state *astate;
663
664 struct lsa_policy_state *state;
665 struct dcesrv_handle *h, *ah;
666
667 ZERO_STRUCTP(r->out.acct_handle);
668
669 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
670
671 state = h->data;
672
673 astate = talloc(dce_call->conn, struct lsa_account_state);
674 if (astate == NULL) {
675 return NT_STATUS_NO_MEMORY;
676 }
677
678 astate->account_sid = dom_sid_dup(astate, r->in.sid);
679 if (astate->account_sid == NULL) {
680 talloc_free(astate);
681 return NT_STATUS_NO_MEMORY;
682 }
683
684 astate->policy = talloc_reference(astate, state);
685 astate->access_mask = r->in.access_mask;
686
687 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
688 if (!ah) {
689 talloc_free(astate);
690 return NT_STATUS_NO_MEMORY;
691 }
692
693 ah->data = talloc_steal(ah, astate);
694
695 *r->out.acct_handle = ah->wire_handle;
696
697 return NT_STATUS_OK;
698 }
699
700
701 /*
702 lsa_EnumAccounts
703 */
lsa_EnumAccounts(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_EnumAccounts * r)704 static NTSTATUS lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
705 struct lsa_EnumAccounts *r)
706 {
707 struct dcesrv_handle *h;
708 struct lsa_policy_state *state;
709 int ret, i;
710 struct ldb_message **res;
711 const char * const attrs[] = { "objectSid", NULL};
712 uint32_t count;
713
714 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
715
716 state = h->data;
717
718 /* NOTE: This call must only return accounts that have at least
719 one privilege set
720 */
721 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
722 "(&(objectSid=*)(privilege=*))");
723 if (ret < 0) {
724 return NT_STATUS_NO_SUCH_USER;
725 }
726
727 if (*r->in.resume_handle >= ret) {
728 return NT_STATUS_NO_MORE_ENTRIES;
729 }
730
731 count = ret - *r->in.resume_handle;
732 if (count > r->in.num_entries) {
733 count = r->in.num_entries;
734 }
735
736 if (count == 0) {
737 return NT_STATUS_NO_MORE_ENTRIES;
738 }
739
740 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
741 if (r->out.sids->sids == NULL) {
742 return NT_STATUS_NO_MEMORY;
743 }
744
745 for (i=0;i<count;i++) {
746 r->out.sids->sids[i].sid =
747 samdb_result_dom_sid(r->out.sids->sids,
748 res[i + *r->in.resume_handle],
749 "objectSid");
750 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
751 }
752
753 r->out.sids->num_sids = count;
754 *r->out.resume_handle = count + *r->in.resume_handle;
755
756 return NT_STATUS_OK;
757
758 }
759
760
761 /*
762 lsa_CreateTrustedDomainEx2
763 */
lsa_CreateTrustedDomainEx2(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CreateTrustedDomainEx2 * r)764 static NTSTATUS lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
765 TALLOC_CTX *mem_ctx,
766 struct lsa_CreateTrustedDomainEx2 *r)
767 {
768 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
769 }
770
771 /*
772 lsa_CreateTrustedDomainEx
773 */
lsa_CreateTrustedDomainEx(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CreateTrustedDomainEx * r)774 static NTSTATUS lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
775 TALLOC_CTX *mem_ctx,
776 struct lsa_CreateTrustedDomainEx *r)
777 {
778 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
779 }
780
781 /*
782 lsa_CreateTrustedDomain
783 */
lsa_CreateTrustedDomain(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CreateTrustedDomain * r)784 static NTSTATUS lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
785 struct lsa_CreateTrustedDomain *r)
786 {
787 struct dcesrv_handle *policy_handle;
788 struct lsa_policy_state *policy_state;
789 struct lsa_trusted_domain_state *trusted_domain_state;
790 struct dcesrv_handle *handle;
791 struct ldb_message **msgs, *msg;
792 const char *attrs[] = {
793 NULL
794 };
795 const char *name;
796 int ret;
797
798 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
799 ZERO_STRUCTP(r->out.trustdom_handle);
800
801 policy_state = policy_handle->data;
802
803 if (!r->in.info->name.string) {
804 return NT_STATUS_INVALID_PARAMETER;
805 }
806 name = r->in.info->name.string;
807
808 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
809 if (!trusted_domain_state) {
810 return NT_STATUS_NO_MEMORY;
811 }
812 trusted_domain_state->policy = policy_state;
813
814 msg = ldb_msg_new(mem_ctx);
815 if (msg == NULL) {
816 return NT_STATUS_NO_MEMORY;
817 }
818
819 /* search for the trusted_domain record */
820 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
821 mem_ctx, policy_state->system_dn, &msgs, attrs,
822 "(&(cn=%s)(objectclass=trustedDomain))",
823 ldb_binary_encode_string(mem_ctx, r->in.info->name.string));
824 if (ret > 0) {
825 return NT_STATUS_OBJECT_NAME_COLLISION;
826 }
827
828 if (ret < 0 || ret > 1) {
829 DEBUG(0,("Found %d records matching DN %s\n", ret,
830 ldb_dn_get_linearized(policy_state->system_dn)));
831 return NT_STATUS_INTERNAL_DB_CORRUPTION;
832 }
833
834 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
835 if ( ! ldb_dn_add_child_fmt(msg->dn, "sn=%s", r->in.info->name.string)) {
836 return NT_STATUS_NO_MEMORY;
837 }
838
839 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "cn", name);
840 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "flatname", name);
841
842 if (r->in.info->sid) {
843 const char *sid_string = dom_sid_string(mem_ctx, r->in.info->sid);
844 if (!sid_string) {
845 return NT_STATUS_NO_MEMORY;
846 }
847
848 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "securityIdentifier", sid_string);
849 }
850
851 samdb_msg_add_string(trusted_domain_state->policy->sam_ldb, mem_ctx, msg, "objectClass", "trustedDomain");
852
853 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msg->dn);
854
855 /* create the trusted_domain */
856 ret = ldb_add(trusted_domain_state->policy->sam_ldb, msg);
857 if (ret != LDB_SUCCESS) {
858 DEBUG(0,("Failed to create trusted_domain record %s: %s\n",
859 ldb_dn_get_linearized(msg->dn), ldb_errstring(trusted_domain_state->policy->sam_ldb)));
860 return NT_STATUS_INTERNAL_DB_CORRUPTION;
861 }
862
863 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
864 if (!handle) {
865 return NT_STATUS_NO_MEMORY;
866 }
867
868 handle->data = talloc_steal(handle, trusted_domain_state);
869
870 trusted_domain_state->access_mask = r->in.access_mask;
871 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
872
873 *r->out.trustdom_handle = handle->wire_handle;
874
875 return NT_STATUS_OK;
876 }
877
878 /*
879 lsa_OpenTrustedDomain
880 */
lsa_OpenTrustedDomain(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_OpenTrustedDomain * r)881 static NTSTATUS lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
882 struct lsa_OpenTrustedDomain *r)
883 {
884 struct dcesrv_handle *policy_handle;
885
886 struct lsa_policy_state *policy_state;
887 struct lsa_trusted_domain_state *trusted_domain_state;
888 struct dcesrv_handle *handle;
889 struct ldb_message **msgs;
890 const char *attrs[] = {
891 NULL
892 };
893
894 const char *sid_string;
895 int ret;
896
897 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
898 ZERO_STRUCTP(r->out.trustdom_handle);
899 policy_state = policy_handle->data;
900
901 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
902 if (!trusted_domain_state) {
903 return NT_STATUS_NO_MEMORY;
904 }
905 trusted_domain_state->policy = policy_state;
906
907 sid_string = dom_sid_string(mem_ctx, r->in.sid);
908 if (!sid_string) {
909 return NT_STATUS_NO_MEMORY;
910 }
911
912 /* search for the trusted_domain record */
913 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
914 mem_ctx, policy_state->system_dn, &msgs, attrs,
915 "(&(securityIdentifier=%s)(objectclass=trustedDomain))",
916 sid_string);
917 if (ret == 0) {
918 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
919 }
920
921 if (ret != 1) {
922 DEBUG(0,("Found %d records matching DN %s\n", ret,
923 ldb_dn_get_linearized(policy_state->system_dn)));
924 return NT_STATUS_INTERNAL_DB_CORRUPTION;
925 }
926
927 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
928
929 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
930 if (!handle) {
931 return NT_STATUS_NO_MEMORY;
932 }
933
934 handle->data = talloc_steal(handle, trusted_domain_state);
935
936 trusted_domain_state->access_mask = r->in.access_mask;
937 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
938
939 *r->out.trustdom_handle = handle->wire_handle;
940
941 return NT_STATUS_OK;
942 }
943
944
945 /*
946 lsa_OpenTrustedDomainByName
947 */
lsa_OpenTrustedDomainByName(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_OpenTrustedDomainByName * r)948 static NTSTATUS lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
949 TALLOC_CTX *mem_ctx,
950 struct lsa_OpenTrustedDomainByName *r)
951 {
952 struct dcesrv_handle *policy_handle;
953
954 struct lsa_policy_state *policy_state;
955 struct lsa_trusted_domain_state *trusted_domain_state;
956 struct dcesrv_handle *handle;
957 struct ldb_message **msgs;
958 const char *attrs[] = {
959 NULL
960 };
961
962 int ret;
963
964 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
965 ZERO_STRUCTP(r->out.trustdom_handle);
966 policy_state = policy_handle->data;
967
968 if (!r->in.name.string) {
969 return NT_STATUS_INVALID_PARAMETER;
970 }
971
972 trusted_domain_state = talloc(mem_ctx, struct lsa_trusted_domain_state);
973 if (!trusted_domain_state) {
974 return NT_STATUS_NO_MEMORY;
975 }
976 trusted_domain_state->policy = policy_state;
977
978 /* search for the trusted_domain record */
979 ret = gendb_search(trusted_domain_state->policy->sam_ldb,
980 mem_ctx, policy_state->system_dn, &msgs, attrs,
981 "(&(flatname=%s)(objectclass=trustedDomain))",
982 ldb_binary_encode_string(mem_ctx, r->in.name.string));
983 if (ret == 0) {
984 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
985 }
986
987 if (ret != 1) {
988 DEBUG(0,("Found %d records matching DN %s\n", ret,
989 ldb_dn_get_linearized(policy_state->system_dn)));
990 return NT_STATUS_INTERNAL_DB_CORRUPTION;
991 }
992
993 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn);
994
995 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
996 if (!handle) {
997 return NT_STATUS_NO_MEMORY;
998 }
999
1000 handle->data = talloc_steal(handle, trusted_domain_state);
1001
1002 trusted_domain_state->access_mask = r->in.access_mask;
1003 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state);
1004
1005 *r->out.trustdom_handle = handle->wire_handle;
1006
1007 return NT_STATUS_OK;
1008 }
1009
1010
1011
1012 /*
1013 lsa_SetTrustedDomainInfo
1014 */
lsa_SetTrustedDomainInfo(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_SetTrustedDomainInfo * r)1015 static NTSTATUS lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1016 struct lsa_SetTrustedDomainInfo *r)
1017 {
1018 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1019 }
1020
1021
1022
1023 /*
1024 lsa_SetInfomrationTrustedDomain
1025 */
lsa_SetInformationTrustedDomain(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_SetInformationTrustedDomain * r)1026 static NTSTATUS lsa_SetInformationTrustedDomain(struct dcesrv_call_state *dce_call,
1027 TALLOC_CTX *mem_ctx,
1028 struct lsa_SetInformationTrustedDomain *r)
1029 {
1030 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1031 }
1032
1033
1034 /*
1035 lsa_DeleteTrustedDomain
1036 */
lsa_DeleteTrustedDomain(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_DeleteTrustedDomain * r)1037 static NTSTATUS lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1038 struct lsa_DeleteTrustedDomain *r)
1039 {
1040 NTSTATUS status;
1041 struct lsa_OpenTrustedDomain open;
1042 struct lsa_Delete delete;
1043 struct dcesrv_handle *h;
1044
1045 open.in.handle = r->in.handle;
1046 open.in.sid = r->in.dom_sid;
1047 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1048 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1049 if (!open.out.trustdom_handle) {
1050 return NT_STATUS_NO_MEMORY;
1051 }
1052 status = lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1053 if (!NT_STATUS_IS_OK(status)) {
1054 return status;
1055 }
1056
1057 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1058 talloc_steal(mem_ctx, h);
1059
1060 delete.in.handle = open.out.trustdom_handle;
1061 status = lsa_Delete(dce_call, mem_ctx, &delete);
1062 if (!NT_STATUS_IS_OK(status)) {
1063 return status;
1064 }
1065 return NT_STATUS_OK;
1066 }
1067
fill_trust_domain_ex(TALLOC_CTX * mem_ctx,struct ldb_message * msg,struct lsa_TrustDomainInfoInfoEx * info_ex)1068 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
1069 struct ldb_message *msg,
1070 struct lsa_TrustDomainInfoInfoEx *info_ex)
1071 {
1072 info_ex->domain_name.string
1073 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
1074 info_ex->netbios_name.string
1075 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1076 info_ex->sid
1077 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1078 info_ex->trust_direction
1079 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
1080 info_ex->trust_type
1081 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
1082 info_ex->trust_attributes
1083 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
1084 return NT_STATUS_OK;
1085 }
1086
1087 /*
1088 lsa_QueryTrustedDomainInfo
1089 */
lsa_QueryTrustedDomainInfo(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_QueryTrustedDomainInfo * r)1090 static NTSTATUS lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1091 struct lsa_QueryTrustedDomainInfo *r)
1092 {
1093 struct dcesrv_handle *h;
1094 struct lsa_trusted_domain_state *trusted_domain_state;
1095 struct ldb_message *msg;
1096 int ret;
1097 struct ldb_message **res;
1098 const char *attrs[] = {
1099 "flatname",
1100 "trustPartner",
1101 "securityIdentifier",
1102 "trustDirection",
1103 "trustType",
1104 "trustAttributes",
1105 NULL
1106 };
1107
1108 DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
1109
1110 trusted_domain_state = h->data;
1111
1112 /* pull all the user attributes */
1113 ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
1114 trusted_domain_state->trusted_domain_dn, &res, attrs);
1115 if (ret != 1) {
1116 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1117 }
1118 msg = res[0];
1119
1120 r->out.info = talloc(mem_ctx, union lsa_TrustedDomainInfo);
1121 if (!r->out.info) {
1122 return NT_STATUS_NO_MEMORY;
1123 }
1124 switch (r->in.level) {
1125 case LSA_TRUSTED_DOMAIN_INFO_NAME:
1126 r->out.info->name.netbios_name.string
1127 = samdb_result_string(msg, "flatname", NULL);
1128 break;
1129 case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
1130 r->out.info->posix_offset.posix_offset
1131 = samdb_result_uint(msg, "posixOffset", 0);
1132 break;
1133 #if 0 /* Win2k3 doesn't implement this */
1134 case LSA_TRUSTED_DOMAIN_INFO_BASIC:
1135 r->out.info->info_basic.netbios_name.string
1136 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
1137 r->out.info->info_basic.sid
1138 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
1139 break;
1140 #endif
1141 case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
1142 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_ex);
1143
1144 case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
1145 ZERO_STRUCT(r->out.info->full_info);
1146 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->full_info.info_ex);
1147
1148 case LSA_TRUSTED_DOMAIN_INFO_INFO_ALL:
1149 ZERO_STRUCT(r->out.info->info_all);
1150 return fill_trust_domain_ex(mem_ctx, msg, &r->out.info->info_all.info_ex);
1151
1152 case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO:
1153 case LSA_TRUSTED_DOMAIN_INFO_11:
1154 /* oops, we don't want to return the info after all */
1155 talloc_free(r->out.info);
1156 r->out.info = NULL;
1157 return NT_STATUS_INVALID_PARAMETER;
1158 default:
1159 /* oops, we don't want to return the info after all */
1160 talloc_free(r->out.info);
1161 r->out.info = NULL;
1162 return NT_STATUS_INVALID_INFO_CLASS;
1163 }
1164
1165 return NT_STATUS_OK;
1166 }
1167
1168
1169 /*
1170 lsa_QueryTrustedDomainInfoBySid
1171 */
lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_QueryTrustedDomainInfoBySid * r)1172 static NTSTATUS lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1173 struct lsa_QueryTrustedDomainInfoBySid *r)
1174 {
1175 NTSTATUS status;
1176 struct lsa_OpenTrustedDomain open;
1177 struct lsa_QueryTrustedDomainInfo query;
1178 struct dcesrv_handle *h;
1179 open.in.handle = r->in.handle;
1180 open.in.sid = r->in.dom_sid;
1181 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1182 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1183 if (!open.out.trustdom_handle) {
1184 return NT_STATUS_NO_MEMORY;
1185 }
1186 status = lsa_OpenTrustedDomain(dce_call, mem_ctx, &open);
1187 if (!NT_STATUS_IS_OK(status)) {
1188 return status;
1189 }
1190
1191 /* Ensure this handle goes away at the end of this call */
1192 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1193 talloc_steal(mem_ctx, h);
1194
1195 query.in.trustdom_handle = open.out.trustdom_handle;
1196 query.in.level = r->in.level;
1197 status = lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1198 if (!NT_STATUS_IS_OK(status)) {
1199 return status;
1200 }
1201
1202 r->out.info = query.out.info;
1203 return NT_STATUS_OK;
1204 }
1205
1206 /*
1207 lsa_SetTrustedDomainInfoByName
1208 */
lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_SetTrustedDomainInfoByName * r)1209 static NTSTATUS lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1210 TALLOC_CTX *mem_ctx,
1211 struct lsa_SetTrustedDomainInfoByName *r)
1212 {
1213 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
1214 }
1215
1216 /*
1217 lsa_QueryTrustedDomainInfoByName
1218 */
lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_QueryTrustedDomainInfoByName * r)1219 static NTSTATUS lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
1220 TALLOC_CTX *mem_ctx,
1221 struct lsa_QueryTrustedDomainInfoByName *r)
1222 {
1223 NTSTATUS status;
1224 struct lsa_OpenTrustedDomainByName open;
1225 struct lsa_QueryTrustedDomainInfo query;
1226 struct dcesrv_handle *h;
1227 open.in.handle = r->in.handle;
1228 open.in.name = r->in.trusted_domain;
1229 open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1230 open.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
1231 if (!open.out.trustdom_handle) {
1232 return NT_STATUS_NO_MEMORY;
1233 }
1234 status = lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &open);
1235 if (!NT_STATUS_IS_OK(status)) {
1236 return status;
1237 }
1238
1239 /* Ensure this handle goes away at the end of this call */
1240 DCESRV_PULL_HANDLE(h, open.out.trustdom_handle, DCESRV_HANDLE_ANY);
1241 talloc_steal(mem_ctx, h);
1242
1243 query.in.trustdom_handle = open.out.trustdom_handle;
1244 query.in.level = r->in.level;
1245 status = lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 return status;
1248 }
1249
1250 r->out.info = query.out.info;
1251 return NT_STATUS_OK;
1252 }
1253
1254 /*
1255 lsa_CloseTrustedDomainEx
1256 */
lsa_CloseTrustedDomainEx(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CloseTrustedDomainEx * r)1257 static NTSTATUS lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
1258 TALLOC_CTX *mem_ctx,
1259 struct lsa_CloseTrustedDomainEx *r)
1260 {
1261 /* The result of a bad hair day from an IDL programmer? Not
1262 * implmented in Win2k3. You should always just lsa_Close
1263 * anyway. */
1264 return NT_STATUS_NOT_IMPLEMENTED;
1265 }
1266
1267
1268 /*
1269 comparison function for sorting lsa_DomainInformation array
1270 */
compare_DomainInfo(struct lsa_DomainInfo * e1,struct lsa_DomainInfo * e2)1271 static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
1272 {
1273 return strcasecmp_m(e1->name.string, e2->name.string);
1274 }
1275
1276 /*
1277 lsa_EnumTrustDom
1278 */
lsa_EnumTrustDom(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_EnumTrustDom * r)1279 static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1280 struct lsa_EnumTrustDom *r)
1281 {
1282 struct dcesrv_handle *policy_handle;
1283 struct lsa_DomainInfo *entries;
1284 struct lsa_policy_state *policy_state;
1285 struct ldb_message **domains;
1286 const char *attrs[] = {
1287 "flatname",
1288 "securityIdentifier",
1289 NULL
1290 };
1291
1292
1293 int count, i;
1294
1295 *r->out.resume_handle = 0;
1296
1297 r->out.domains->domains = NULL;
1298 r->out.domains->count = 0;
1299
1300 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1301
1302 policy_state = policy_handle->data;
1303
1304 /* search for all users in this domain. This could possibly be cached and
1305 resumed based on resume_key */
1306 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1307 "objectclass=trustedDomain");
1308 if (count == -1) {
1309 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1310 }
1311 if (count == 0 || r->in.max_size == 0) {
1312 return NT_STATUS_OK;
1313 }
1314
1315 /* convert to lsa_TrustInformation format */
1316 entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
1317 if (!entries) {
1318 return NT_STATUS_NO_MEMORY;
1319 }
1320 for (i=0;i<count;i++) {
1321 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
1322 entries[i].name.string = samdb_result_string(domains[i], "flatname", NULL);
1323 }
1324
1325 /* sort the results by name */
1326 qsort(entries, count, sizeof(*entries),
1327 (comparison_fn_t)compare_DomainInfo);
1328
1329 if (*r->in.resume_handle >= count) {
1330 *r->out.resume_handle = -1;
1331
1332 return NT_STATUS_NO_MORE_ENTRIES;
1333 }
1334
1335 /* return the rest, limit by max_size. Note that we
1336 use the w2k3 element size value of 60 */
1337 r->out.domains->count = count - *r->in.resume_handle;
1338 r->out.domains->count = MIN(r->out.domains->count,
1339 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
1340
1341 r->out.domains->domains = entries + *r->in.resume_handle;
1342 r->out.domains->count = r->out.domains->count;
1343
1344 if (r->out.domains->count < count - *r->in.resume_handle) {
1345 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1346 return STATUS_MORE_ENTRIES;
1347 }
1348
1349 return NT_STATUS_OK;
1350 }
1351
1352 /*
1353 comparison function for sorting lsa_DomainInformation array
1354 */
compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx * e1,struct lsa_TrustDomainInfoInfoEx * e2)1355 static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
1356 {
1357 return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
1358 }
1359
1360 /*
1361 lsa_EnumTrustedDomainsEx
1362 */
lsa_EnumTrustedDomainsEx(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_EnumTrustedDomainsEx * r)1363 static NTSTATUS lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1364 struct lsa_EnumTrustedDomainsEx *r)
1365 {
1366 struct dcesrv_handle *policy_handle;
1367 struct lsa_TrustDomainInfoInfoEx *entries;
1368 struct lsa_policy_state *policy_state;
1369 struct ldb_message **domains;
1370 const char *attrs[] = {
1371 "flatname",
1372 "trustPartner",
1373 "securityIdentifier",
1374 "trustDirection",
1375 "trustType",
1376 "trustAttributes",
1377 NULL
1378 };
1379 NTSTATUS nt_status;
1380
1381 int count, i;
1382
1383 *r->out.resume_handle = 0;
1384
1385 r->out.domains->domains = NULL;
1386 r->out.domains->count = 0;
1387
1388 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
1389
1390 policy_state = policy_handle->data;
1391
1392 /* search for all users in this domain. This could possibly be cached and
1393 resumed based on resume_key */
1394 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
1395 "objectclass=trustedDomain");
1396 if (count == -1) {
1397 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1398 }
1399 if (count == 0 || r->in.max_size == 0) {
1400 return NT_STATUS_OK;
1401 }
1402
1403 /* convert to lsa_DomainInformation format */
1404 entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
1405 if (!entries) {
1406 return NT_STATUS_NO_MEMORY;
1407 }
1408 for (i=0;i<count;i++) {
1409 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
1410 if (!NT_STATUS_IS_OK(nt_status)) {
1411 return nt_status;
1412 }
1413 }
1414
1415 /* sort the results by name */
1416 qsort(entries, count, sizeof(*entries),
1417 (comparison_fn_t)compare_TrustDomainInfoInfoEx);
1418
1419 if (*r->in.resume_handle >= count) {
1420 *r->out.resume_handle = -1;
1421
1422 return NT_STATUS_NO_MORE_ENTRIES;
1423 }
1424
1425 /* return the rest, limit by max_size. Note that we
1426 use the w2k3 element size value of 60 */
1427 r->out.domains->count = count - *r->in.resume_handle;
1428 r->out.domains->count = MIN(r->out.domains->count,
1429 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
1430
1431 r->out.domains->domains = entries + *r->in.resume_handle;
1432 r->out.domains->count = r->out.domains->count;
1433
1434 if (r->out.domains->count < count - *r->in.resume_handle) {
1435 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
1436 return STATUS_MORE_ENTRIES;
1437 }
1438
1439 return NT_STATUS_OK;
1440 }
1441
1442
1443 /*
1444 return the authority name and authority sid, given a sid
1445 */
lsa_authority_name(struct lsa_policy_state * state,TALLOC_CTX * mem_ctx,struct dom_sid * sid,const char ** authority_name,struct dom_sid ** authority_sid)1446 static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
1447 TALLOC_CTX *mem_ctx, struct dom_sid *sid,
1448 const char **authority_name,
1449 struct dom_sid **authority_sid)
1450 {
1451 if (dom_sid_in_domain(state->domain_sid, sid)) {
1452 *authority_name = state->domain_name;
1453 *authority_sid = state->domain_sid;
1454 return NT_STATUS_OK;
1455 }
1456
1457 if (dom_sid_in_domain(state->builtin_sid, sid)) {
1458 *authority_name = "BUILTIN";
1459 *authority_sid = state->builtin_sid;
1460 return NT_STATUS_OK;
1461 }
1462
1463 *authority_sid = dom_sid_dup(mem_ctx, sid);
1464 if (*authority_sid == NULL) {
1465 return NT_STATUS_NO_MEMORY;
1466 }
1467 (*authority_sid)->num_auths = 0;
1468 *authority_name = dom_sid_string(mem_ctx, *authority_sid);
1469 if (*authority_name == NULL) {
1470 return NT_STATUS_NO_MEMORY;
1471 }
1472
1473 return NT_STATUS_OK;
1474 }
1475
1476 /*
1477 add to the lsa_RefDomainList for LookupSids and LookupNames
1478 */
lsa_authority_list(struct lsa_policy_state * state,TALLOC_CTX * mem_ctx,struct dom_sid * sid,struct lsa_RefDomainList * domains,uint32_t * sid_index)1479 static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1480 struct dom_sid *sid,
1481 struct lsa_RefDomainList *domains,
1482 uint32_t *sid_index)
1483 {
1484 NTSTATUS status;
1485 const char *authority_name;
1486 struct dom_sid *authority_sid;
1487 int i;
1488
1489 /* work out the authority name */
1490 status = lsa_authority_name(state, mem_ctx, sid,
1491 &authority_name, &authority_sid);
1492 if (!NT_STATUS_IS_OK(status)) {
1493 return status;
1494 }
1495
1496 /* see if we've already done this authority name */
1497 for (i=0;i<domains->count;i++) {
1498 if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
1499 *sid_index = i;
1500 return NT_STATUS_OK;
1501 }
1502 }
1503
1504 domains->domains = talloc_realloc(domains,
1505 domains->domains,
1506 struct lsa_DomainInfo,
1507 domains->count+1);
1508 if (domains->domains == NULL) {
1509 return NT_STATUS_NO_MEMORY;
1510 }
1511 domains->domains[i].name.string = authority_name;
1512 domains->domains[i].sid = authority_sid;
1513 domains->count++;
1514 domains->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER * domains->count;
1515 *sid_index = i;
1516
1517 return NT_STATUS_OK;
1518 }
1519
1520 /*
1521 lookup a name for 1 SID
1522 */
lsa_lookup_sid(struct lsa_policy_state * state,TALLOC_CTX * mem_ctx,struct dom_sid * sid,const char * sid_str,const char ** name,uint32_t * atype)1523 static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
1524 struct dom_sid *sid, const char *sid_str,
1525 const char **name, uint32_t *atype)
1526 {
1527 int ret;
1528 struct ldb_message **res;
1529 const char * const attrs[] = { "sAMAccountName", "sAMAccountType", "name", NULL};
1530 NTSTATUS status;
1531
1532 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1533 "objectSid=%s", ldap_encode_ndr_dom_sid(mem_ctx, sid));
1534 if (ret == 1) {
1535 *name = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL);
1536 if (!*name) {
1537 *name = ldb_msg_find_attr_as_string(res[0], "name", NULL);
1538 if (!*name) {
1539 *name = talloc_strdup(mem_ctx, sid_str);
1540 NT_STATUS_HAVE_NO_MEMORY(*name);
1541 }
1542 }
1543
1544 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
1545
1546 return NT_STATUS_OK;
1547 }
1548
1549 status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
1550
1551 return status;
1552 }
1553
1554
1555 /*
1556 lsa_LookupSids2
1557 */
lsa_LookupSids2(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LookupSids2 * r)1558 static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
1559 TALLOC_CTX *mem_ctx,
1560 struct lsa_LookupSids2 *r)
1561 {
1562 struct lsa_policy_state *state;
1563 int i;
1564 NTSTATUS status = NT_STATUS_OK;
1565
1566 r->out.domains = NULL;
1567
1568 status = lsa_get_policy_state(dce_call, mem_ctx, &state);
1569 if (!NT_STATUS_IS_OK(status)) {
1570 return status;
1571 }
1572
1573 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
1574 if (r->out.domains == NULL) {
1575 return NT_STATUS_NO_MEMORY;
1576 }
1577
1578 r->out.names = talloc_zero(mem_ctx, struct lsa_TransNameArray2);
1579 if (r->out.names == NULL) {
1580 return NT_STATUS_NO_MEMORY;
1581 }
1582
1583 *r->out.count = 0;
1584
1585 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName2,
1586 r->in.sids->num_sids);
1587 if (r->out.names->names == NULL) {
1588 return NT_STATUS_NO_MEMORY;
1589 }
1590
1591 for (i=0;i<r->in.sids->num_sids;i++) {
1592 struct dom_sid *sid = r->in.sids->sids[i].sid;
1593 char *sid_str = dom_sid_string(mem_ctx, sid);
1594 const char *name;
1595 uint32_t atype, rtype, sid_index;
1596 NTSTATUS status2;
1597
1598 r->out.names->count++;
1599 (*r->out.count)++;
1600
1601 r->out.names->names[i].sid_type = SID_NAME_UNKNOWN;
1602 r->out.names->names[i].name.string = sid_str;
1603 r->out.names->names[i].sid_index = 0xFFFFFFFF;
1604 r->out.names->names[i].unknown = 0;
1605
1606 if (sid_str == NULL) {
1607 r->out.names->names[i].name.string = "(SIDERROR)";
1608 status = STATUS_SOME_UNMAPPED;
1609 continue;
1610 }
1611
1612 /* work out the authority name */
1613 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
1614 if (!NT_STATUS_IS_OK(status2)) {
1615 return status2;
1616 }
1617
1618 status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str,
1619 &name, &atype);
1620 if (!NT_STATUS_IS_OK(status2)) {
1621 status = STATUS_SOME_UNMAPPED;
1622 continue;
1623 }
1624
1625 rtype = samdb_atype_map(atype);
1626 if (rtype == SID_NAME_UNKNOWN) {
1627 status = STATUS_SOME_UNMAPPED;
1628 continue;
1629 }
1630
1631 r->out.names->names[i].sid_type = rtype;
1632 r->out.names->names[i].name.string = name;
1633 r->out.names->names[i].sid_index = sid_index;
1634 r->out.names->names[i].unknown = 0;
1635 }
1636
1637 return status;
1638 }
1639
1640
1641 /*
1642 lsa_LookupSids3
1643
1644 Identical to LookupSids2, but doesn't take a policy handle
1645
1646 */
lsa_LookupSids3(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LookupSids3 * r)1647 static NTSTATUS lsa_LookupSids3(struct dcesrv_call_state *dce_call,
1648 TALLOC_CTX *mem_ctx,
1649 struct lsa_LookupSids3 *r)
1650 {
1651 struct lsa_LookupSids2 r2;
1652 struct lsa_OpenPolicy2 pol;
1653 NTSTATUS status;
1654 struct dcesrv_handle *h;
1655
1656 /* No policy handle on the wire, so make one up here */
1657 r2.in.handle = talloc(mem_ctx, struct policy_handle);
1658 if (!r2.in.handle) {
1659 return NT_STATUS_NO_MEMORY;
1660 }
1661
1662 pol.out.handle = r2.in.handle;
1663 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
1664 pol.in.attr = NULL;
1665 pol.in.system_name = NULL;
1666 status = lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
1667 if (!NT_STATUS_IS_OK(status)) {
1668 return status;
1669 }
1670
1671 /* ensure this handle goes away at the end of this call */
1672 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
1673 talloc_steal(mem_ctx, h);
1674
1675 r2.in.sids = r->in.sids;
1676 r2.in.names = r->in.names;
1677 r2.in.level = r->in.level;
1678 r2.in.count = r->in.count;
1679 r2.in.unknown1 = r->in.unknown1;
1680 r2.in.unknown2 = r->in.unknown2;
1681 r2.out.count = r->out.count;
1682 r2.out.names = r->out.names;
1683
1684 status = lsa_LookupSids2(dce_call, mem_ctx, &r2);
1685 if (dce_call->fault_code != 0) {
1686 return status;
1687 }
1688
1689 r->out.domains = r2.out.domains;
1690 r->out.names = r2.out.names;
1691 r->out.count = r2.out.count;
1692
1693 return status;
1694 }
1695
1696
1697 /*
1698 lsa_LookupSids
1699 */
lsa_LookupSids(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LookupSids * r)1700 static NTSTATUS lsa_LookupSids(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1701 struct lsa_LookupSids *r)
1702 {
1703 struct lsa_LookupSids2 r2;
1704 NTSTATUS status;
1705 int i;
1706
1707 r2.in.handle = r->in.handle;
1708 r2.in.sids = r->in.sids;
1709 r2.in.names = NULL;
1710 r2.in.level = r->in.level;
1711 r2.in.count = r->in.count;
1712 r2.in.unknown1 = 0;
1713 r2.in.unknown2 = 0;
1714 r2.out.count = r->out.count;
1715 r2.out.names = NULL;
1716
1717 status = lsa_LookupSids2(dce_call, mem_ctx, &r2);
1718 if (dce_call->fault_code != 0) {
1719 return status;
1720 }
1721
1722 r->out.domains = r2.out.domains;
1723 if (!r2.out.names) {
1724 r->out.names = NULL;
1725 return status;
1726 }
1727
1728 r->out.names = talloc(mem_ctx, struct lsa_TransNameArray);
1729 if (r->out.names == NULL) {
1730 return NT_STATUS_NO_MEMORY;
1731 }
1732 r->out.names->count = r2.out.names->count;
1733 r->out.names->names = talloc_array(r->out.names, struct lsa_TranslatedName,
1734 r->out.names->count);
1735 if (r->out.names->names == NULL) {
1736 return NT_STATUS_NO_MEMORY;
1737 }
1738 for (i=0;i<r->out.names->count;i++) {
1739 r->out.names->names[i].sid_type = r2.out.names->names[i].sid_type;
1740 r->out.names->names[i].name.string = r2.out.names->names[i].name.string;
1741 r->out.names->names[i].sid_index = r2.out.names->names[i].sid_index;
1742 }
1743
1744 return status;
1745 }
1746
1747
1748 /*
1749 lsa_OpenAccount
1750 */
lsa_OpenAccount(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_OpenAccount * r)1751 static NTSTATUS lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
1752 struct lsa_OpenAccount *r)
1753 {
1754 struct dcesrv_handle *h, *ah;
1755 struct lsa_policy_state *state;
1756 struct lsa_account_state *astate;
1757
1758 ZERO_STRUCTP(r->out.acct_handle);
1759
1760 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1761
1762 state = h->data;
1763
1764 astate = talloc(dce_call->conn, struct lsa_account_state);
1765 if (astate == NULL) {
1766 return NT_STATUS_NO_MEMORY;
1767 }
1768
1769 astate->account_sid = dom_sid_dup(astate, r->in.sid);
1770 if (astate->account_sid == NULL) {
1771 talloc_free(astate);
1772 return NT_STATUS_NO_MEMORY;
1773 }
1774
1775 astate->policy = talloc_reference(astate, state);
1776 astate->access_mask = r->in.access_mask;
1777
1778 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
1779 if (!ah) {
1780 talloc_free(astate);
1781 return NT_STATUS_NO_MEMORY;
1782 }
1783
1784 ah->data = talloc_steal(ah, astate);
1785
1786 *r->out.acct_handle = ah->wire_handle;
1787
1788 return NT_STATUS_OK;
1789 }
1790
1791
1792 /*
1793 lsa_EnumPrivsAccount
1794 */
lsa_EnumPrivsAccount(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_EnumPrivsAccount * r)1795 static NTSTATUS lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
1796 TALLOC_CTX *mem_ctx,
1797 struct lsa_EnumPrivsAccount *r)
1798 {
1799 struct dcesrv_handle *h;
1800 struct lsa_account_state *astate;
1801 int ret, i;
1802 struct ldb_message **res;
1803 const char * const attrs[] = { "privilege", NULL};
1804 struct ldb_message_element *el;
1805 const char *sidstr;
1806
1807 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
1808
1809 astate = h->data;
1810
1811 r->out.privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
1812 r->out.privs->count = 0;
1813 r->out.privs->unknown = 0;
1814 r->out.privs->set = NULL;
1815
1816 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
1817 if (sidstr == NULL) {
1818 return NT_STATUS_NO_MEMORY;
1819 }
1820
1821 ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs,
1822 "objectSid=%s", sidstr);
1823 if (ret != 1) {
1824 return NT_STATUS_OK;
1825 }
1826
1827 el = ldb_msg_find_element(res[0], "privilege");
1828 if (el == NULL || el->num_values == 0) {
1829 return NT_STATUS_OK;
1830 }
1831
1832 r->out.privs->set = talloc_array(r->out.privs,
1833 struct lsa_LUIDAttribute, el->num_values);
1834 if (r->out.privs->set == NULL) {
1835 return NT_STATUS_NO_MEMORY;
1836 }
1837
1838 for (i=0;i<el->num_values;i++) {
1839 int id = sec_privilege_id((const char *)el->values[i].data);
1840 if (id == -1) {
1841 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1842 }
1843 r->out.privs->set[i].attribute = 0;
1844 r->out.privs->set[i].luid.low = id;
1845 r->out.privs->set[i].luid.high = 0;
1846 }
1847
1848 r->out.privs->count = el->num_values;
1849
1850 return NT_STATUS_OK;
1851 }
1852
1853 /*
1854 lsa_EnumAccountRights
1855 */
lsa_EnumAccountRights(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_EnumAccountRights * r)1856 static NTSTATUS lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
1857 TALLOC_CTX *mem_ctx,
1858 struct lsa_EnumAccountRights *r)
1859 {
1860 struct dcesrv_handle *h;
1861 struct lsa_policy_state *state;
1862 int ret, i;
1863 struct ldb_message **res;
1864 const char * const attrs[] = { "privilege", NULL};
1865 const char *sidstr;
1866 struct ldb_message_element *el;
1867
1868 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
1869
1870 state = h->data;
1871
1872 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
1873 if (sidstr == NULL) {
1874 return NT_STATUS_NO_MEMORY;
1875 }
1876
1877 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
1878 "(&(objectSid=%s)(privilege=*))", sidstr);
1879 if (ret == 0) {
1880 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1881 }
1882 if (ret > 1) {
1883 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1884 }
1885 if (ret == -1) {
1886 DEBUG(3, ("searching for account rights for SID: %s failed: %s",
1887 dom_sid_string(mem_ctx, r->in.sid),
1888 ldb_errstring(state->sam_ldb)));
1889 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1890 }
1891
1892 el = ldb_msg_find_element(res[0], "privilege");
1893 if (el == NULL || el->num_values == 0) {
1894 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1895 }
1896
1897 r->out.rights->count = el->num_values;
1898 r->out.rights->names = talloc_array(r->out.rights,
1899 struct lsa_StringLarge, r->out.rights->count);
1900 if (r->out.rights->names == NULL) {
1901 return NT_STATUS_NO_MEMORY;
1902 }
1903
1904 for (i=0;i<el->num_values;i++) {
1905 r->out.rights->names[i].string = (const char *)el->values[i].data;
1906 }
1907
1908 return NT_STATUS_OK;
1909 }
1910
1911
1912
1913 /*
1914 helper for lsa_AddAccountRights and lsa_RemoveAccountRights
1915 */
lsa_AddRemoveAccountRights(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_policy_state * state,int ldb_flag,struct dom_sid * sid,const struct lsa_RightSet * rights)1916 static NTSTATUS lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
1917 TALLOC_CTX *mem_ctx,
1918 struct lsa_policy_state *state,
1919 int ldb_flag,
1920 struct dom_sid *sid,
1921 const struct lsa_RightSet *rights)
1922 {
1923 const char *sidstr;
1924 struct ldb_message *msg;
1925 struct ldb_message_element *el;
1926 int i, ret;
1927 struct lsa_EnumAccountRights r2;
1928
1929 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid);
1930 if (sidstr == NULL) {
1931 return NT_STATUS_NO_MEMORY;
1932 }
1933
1934 msg = ldb_msg_new(mem_ctx);
1935 if (msg == NULL) {
1936 return NT_STATUS_NO_MEMORY;
1937 }
1938
1939 msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx,
1940 NULL, "objectSid=%s", sidstr);
1941 if (msg->dn == NULL) {
1942 NTSTATUS status;
1943 if (ldb_flag == LDB_FLAG_MOD_DELETE) {
1944 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1945 }
1946 status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx,
1947 sid, &msg->dn);
1948 if (!NT_STATUS_IS_OK(status)) {
1949 return status;
1950 }
1951 return NT_STATUS_NO_SUCH_USER;
1952 }
1953
1954 if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) {
1955 return NT_STATUS_NO_MEMORY;
1956 }
1957
1958 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1959 NTSTATUS status;
1960
1961 r2.in.handle = &state->handle->wire_handle;
1962 r2.in.sid = sid;
1963 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
1964
1965 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
1966 if (!NT_STATUS_IS_OK(status)) {
1967 ZERO_STRUCTP(r2.out.rights);
1968 }
1969 }
1970
1971 for (i=0;i<rights->count;i++) {
1972 if (sec_privilege_id(rights->names[i].string) == -1) {
1973 return NT_STATUS_NO_SUCH_PRIVILEGE;
1974 }
1975
1976 if (ldb_flag == LDB_FLAG_MOD_ADD) {
1977 int j;
1978 for (j=0;j<r2.out.rights->count;j++) {
1979 if (strcasecmp_m(r2.out.rights->names[j].string,
1980 rights->names[i].string) == 0) {
1981 break;
1982 }
1983 }
1984 if (j != r2.out.rights->count) continue;
1985 }
1986
1987 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
1988 if (ret != LDB_SUCCESS) {
1989 return NT_STATUS_NO_MEMORY;
1990 }
1991 }
1992
1993 el = ldb_msg_find_element(msg, "privilege");
1994 if (!el) {
1995 return NT_STATUS_OK;
1996 }
1997
1998 ret = samdb_modify(state->sam_ldb, mem_ctx, msg);
1999 if (ret != 0) {
2000 if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
2001 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2002 }
2003 DEBUG(3, ("Could not %s attributes from %s: %s",
2004 ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add",
2005 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb)));
2006 return NT_STATUS_UNEXPECTED_IO_ERROR;
2007 }
2008
2009 return NT_STATUS_OK;
2010 }
2011
2012 /*
2013 lsa_AddPrivilegesToAccount
2014 */
lsa_AddPrivilegesToAccount(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_AddPrivilegesToAccount * r)2015 static NTSTATUS lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2016 struct lsa_AddPrivilegesToAccount *r)
2017 {
2018 struct lsa_RightSet rights;
2019 struct dcesrv_handle *h;
2020 struct lsa_account_state *astate;
2021 int i;
2022
2023 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2024
2025 astate = h->data;
2026
2027 rights.count = r->in.privs->count;
2028 rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
2029 if (rights.names == NULL) {
2030 return NT_STATUS_NO_MEMORY;
2031 }
2032 for (i=0;i<rights.count;i++) {
2033 int id = r->in.privs->set[i].luid.low;
2034 if (r->in.privs->set[i].luid.high) {
2035 return NT_STATUS_NO_SUCH_PRIVILEGE;
2036 }
2037 rights.names[i].string = sec_privilege_name(id);
2038 if (rights.names[i].string == NULL) {
2039 return NT_STATUS_NO_SUCH_PRIVILEGE;
2040 }
2041 }
2042
2043 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2044 LDB_FLAG_MOD_ADD, astate->account_sid,
2045 &rights);
2046 }
2047
2048
2049 /*
2050 lsa_RemovePrivilegesFromAccount
2051 */
lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_RemovePrivilegesFromAccount * r)2052 static NTSTATUS lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2053 struct lsa_RemovePrivilegesFromAccount *r)
2054 {
2055 struct lsa_RightSet *rights;
2056 struct dcesrv_handle *h;
2057 struct lsa_account_state *astate;
2058 int i;
2059
2060 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
2061
2062 astate = h->data;
2063
2064 rights = talloc(mem_ctx, struct lsa_RightSet);
2065
2066 if (r->in.remove_all == 1 &&
2067 r->in.privs == NULL) {
2068 struct lsa_EnumAccountRights r2;
2069 NTSTATUS status;
2070
2071 r2.in.handle = &astate->policy->handle->wire_handle;
2072 r2.in.sid = astate->account_sid;
2073 r2.out.rights = rights;
2074
2075 status = lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
2076 if (!NT_STATUS_IS_OK(status)) {
2077 return status;
2078 }
2079
2080 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2081 LDB_FLAG_MOD_DELETE, astate->account_sid,
2082 r2.out.rights);
2083 }
2084
2085 if (r->in.remove_all != 0) {
2086 return NT_STATUS_INVALID_PARAMETER;
2087 }
2088
2089 rights->count = r->in.privs->count;
2090 rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
2091 if (rights->names == NULL) {
2092 return NT_STATUS_NO_MEMORY;
2093 }
2094 for (i=0;i<rights->count;i++) {
2095 int id = r->in.privs->set[i].luid.low;
2096 if (r->in.privs->set[i].luid.high) {
2097 return NT_STATUS_NO_SUCH_PRIVILEGE;
2098 }
2099 rights->names[i].string = sec_privilege_name(id);
2100 if (rights->names[i].string == NULL) {
2101 return NT_STATUS_NO_SUCH_PRIVILEGE;
2102 }
2103 }
2104
2105 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
2106 LDB_FLAG_MOD_DELETE, astate->account_sid,
2107 rights);
2108 }
2109
2110
2111 /*
2112 lsa_GetQuotasForAccount
2113 */
lsa_GetQuotasForAccount(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_GetQuotasForAccount * r)2114 static NTSTATUS lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2115 struct lsa_GetQuotasForAccount *r)
2116 {
2117 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2118 }
2119
2120
2121 /*
2122 lsa_SetQuotasForAccount
2123 */
lsa_SetQuotasForAccount(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_SetQuotasForAccount * r)2124 static NTSTATUS lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2125 struct lsa_SetQuotasForAccount *r)
2126 {
2127 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2128 }
2129
2130
2131 /*
2132 lsa_GetSystemAccessAccount
2133 */
lsa_GetSystemAccessAccount(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_GetSystemAccessAccount * r)2134 static NTSTATUS lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2135 struct lsa_GetSystemAccessAccount *r)
2136 {
2137 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2138 }
2139
2140
2141 /*
2142 lsa_SetSystemAccessAccount
2143 */
lsa_SetSystemAccessAccount(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_SetSystemAccessAccount * r)2144 static NTSTATUS lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2145 struct lsa_SetSystemAccessAccount *r)
2146 {
2147 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2148 }
2149
2150
2151 /*
2152 lsa_CreateSecret
2153 */
lsa_CreateSecret(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CreateSecret * r)2154 static NTSTATUS lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2155 struct lsa_CreateSecret *r)
2156 {
2157 struct dcesrv_handle *policy_handle;
2158 struct lsa_policy_state *policy_state;
2159 struct lsa_secret_state *secret_state;
2160 struct dcesrv_handle *handle;
2161 struct ldb_message **msgs, *msg;
2162 const char *errstr;
2163 const char *attrs[] = {
2164 NULL
2165 };
2166
2167 const char *name;
2168
2169 int ret;
2170
2171 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2172 ZERO_STRUCTP(r->out.sec_handle);
2173
2174 policy_state = policy_handle->data;
2175
2176 if (!r->in.name.string) {
2177 return NT_STATUS_INVALID_PARAMETER;
2178 }
2179
2180 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2181 if (!secret_state) {
2182 return NT_STATUS_NO_MEMORY;
2183 }
2184 secret_state->policy = policy_state;
2185
2186 msg = ldb_msg_new(mem_ctx);
2187 if (msg == NULL) {
2188 return NT_STATUS_NO_MEMORY;
2189 }
2190
2191 if (strncmp("G$", r->in.name.string, 2) == 0) {
2192 const char *name2;
2193 name = &r->in.name.string[2];
2194 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2195 secret_state->global = True;
2196
2197 if (strlen(name) < 1) {
2198 return NT_STATUS_INVALID_PARAMETER;
2199 }
2200
2201 name2 = talloc_asprintf(mem_ctx, "%s Secret", ldb_binary_encode_string(mem_ctx, name));
2202 /* search for the secret record */
2203 ret = gendb_search(secret_state->sam_ldb,
2204 mem_ctx, policy_state->system_dn, &msgs, attrs,
2205 "(&(cn=%s)(objectclass=secret))",
2206 name2);
2207 if (ret > 0) {
2208 return NT_STATUS_OBJECT_NAME_COLLISION;
2209 }
2210
2211 if (ret == -1) {
2212 DEBUG(0,("Failure searching for CN=%s: %s\n",
2213 name2, ldb_errstring(secret_state->sam_ldb)));
2214 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2215 }
2216
2217 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
2218 if (!name2 || ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
2219 return NT_STATUS_NO_MEMORY;
2220 }
2221
2222 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name2);
2223
2224 } else {
2225 secret_state->global = False;
2226
2227 name = r->in.name.string;
2228 if (strlen(name) < 1) {
2229 return NT_STATUS_INVALID_PARAMETER;
2230 }
2231
2232 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2233 /* search for the secret record */
2234 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2235 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2236 &msgs, attrs,
2237 "(&(cn=%s)(objectclass=secret))",
2238 ldb_binary_encode_string(mem_ctx, name));
2239 if (ret > 0) {
2240 return NT_STATUS_OBJECT_NAME_COLLISION;
2241 }
2242
2243 if (ret == -1) {
2244 DEBUG(0,("Failure searching for CN=%s: %s\n",
2245 name, ldb_errstring(secret_state->sam_ldb)));
2246 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2247 }
2248
2249 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb, "cn=%s,cn=LSA Secrets", name);
2250 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "cn", name);
2251 }
2252
2253 /* pull in all the template attributes. Note this is always from the global samdb */
2254 ret = samdb_copy_template(secret_state->policy->sam_ldb, msg,
2255 "(&(cn=TemplateSecret)(objectclass=secretTemplate))", &errstr);
2256 if (ret != 0) {
2257 DEBUG(0,("Failed to load TemplateSecret from samdb: %s\n",
2258 errstr));
2259 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2260 }
2261
2262 samdb_msg_add_string(secret_state->sam_ldb, mem_ctx, msg, "objectClass", "secret");
2263
2264 secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
2265
2266 /* create the secret */
2267 ret = samdb_add(secret_state->sam_ldb, mem_ctx, msg);
2268 if (ret != 0) {
2269 DEBUG(0,("Failed to create secret record %s: %s\n",
2270 ldb_dn_get_linearized(msg->dn),
2271 ldb_errstring(secret_state->sam_ldb)));
2272 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2273 }
2274
2275 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2276 if (!handle) {
2277 return NT_STATUS_NO_MEMORY;
2278 }
2279
2280 handle->data = talloc_steal(handle, secret_state);
2281
2282 secret_state->access_mask = r->in.access_mask;
2283 secret_state->policy = talloc_reference(secret_state, policy_state);
2284
2285 *r->out.sec_handle = handle->wire_handle;
2286
2287 return NT_STATUS_OK;
2288 }
2289
2290
2291 /*
2292 lsa_OpenSecret
2293 */
lsa_OpenSecret(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_OpenSecret * r)2294 static NTSTATUS lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2295 struct lsa_OpenSecret *r)
2296 {
2297 struct dcesrv_handle *policy_handle;
2298
2299 struct lsa_policy_state *policy_state;
2300 struct lsa_secret_state *secret_state;
2301 struct dcesrv_handle *handle;
2302 struct ldb_message **msgs;
2303 const char *attrs[] = {
2304 NULL
2305 };
2306
2307 const char *name;
2308
2309 int ret;
2310
2311 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
2312 ZERO_STRUCTP(r->out.sec_handle);
2313 policy_state = policy_handle->data;
2314
2315 if (!r->in.name.string) {
2316 return NT_STATUS_INVALID_PARAMETER;
2317 }
2318
2319 secret_state = talloc(mem_ctx, struct lsa_secret_state);
2320 if (!secret_state) {
2321 return NT_STATUS_NO_MEMORY;
2322 }
2323 secret_state->policy = policy_state;
2324
2325 if (strncmp("G$", r->in.name.string, 2) == 0) {
2326 name = &r->in.name.string[2];
2327 secret_state->sam_ldb = talloc_reference(secret_state, policy_state->sam_ldb);
2328 secret_state->global = True;
2329
2330 if (strlen(name) < 1) {
2331 return NT_STATUS_INVALID_PARAMETER;
2332 }
2333
2334 /* search for the secret record */
2335 ret = gendb_search(secret_state->sam_ldb,
2336 mem_ctx, policy_state->system_dn, &msgs, attrs,
2337 "(&(cn=%s Secret)(objectclass=secret))",
2338 ldb_binary_encode_string(mem_ctx, name));
2339 if (ret == 0) {
2340 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2341 }
2342
2343 if (ret != 1) {
2344 DEBUG(0,("Found %d records matching DN %s\n", ret,
2345 ldb_dn_get_linearized(policy_state->system_dn)));
2346 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2347 }
2348
2349 } else {
2350 secret_state->sam_ldb = talloc_reference(secret_state, secrets_db_connect(mem_ctx));
2351
2352 secret_state->global = False;
2353 name = r->in.name.string;
2354 if (strlen(name) < 1) {
2355 return NT_STATUS_INVALID_PARAMETER;
2356 }
2357
2358 /* search for the secret record */
2359 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
2360 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
2361 &msgs, attrs,
2362 "(&(cn=%s)(objectclass=secret))",
2363 ldb_binary_encode_string(mem_ctx, name));
2364 if (ret == 0) {
2365 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2366 }
2367
2368 if (ret != 1) {
2369 DEBUG(0,("Found %d records matching DN %s\n", ret,
2370 ldb_dn_get_linearized(policy_state->system_dn)));
2371 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2372 }
2373 }
2374
2375 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
2376
2377 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
2378 if (!handle) {
2379 return NT_STATUS_NO_MEMORY;
2380 }
2381
2382 handle->data = talloc_steal(handle, secret_state);
2383
2384 secret_state->access_mask = r->in.access_mask;
2385 secret_state->policy = talloc_reference(secret_state, policy_state);
2386
2387 *r->out.sec_handle = handle->wire_handle;
2388
2389 return NT_STATUS_OK;
2390 }
2391
2392
2393 /*
2394 lsa_SetSecret
2395 */
lsa_SetSecret(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_SetSecret * r)2396 static NTSTATUS lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2397 struct lsa_SetSecret *r)
2398 {
2399
2400 struct dcesrv_handle *h;
2401 struct lsa_secret_state *secret_state;
2402 struct ldb_message *msg;
2403 DATA_BLOB session_key;
2404 DATA_BLOB crypt_secret, secret;
2405 struct ldb_val val;
2406 int ret;
2407 NTSTATUS status = NT_STATUS_OK;
2408
2409 struct timeval now = timeval_current();
2410 NTTIME nt_now = timeval_to_nttime(&now);
2411
2412 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2413
2414 secret_state = h->data;
2415
2416 msg = ldb_msg_new(mem_ctx);
2417 if (msg == NULL) {
2418 return NT_STATUS_NO_MEMORY;
2419 }
2420
2421 msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
2422 if (!msg->dn) {
2423 return NT_STATUS_NO_MEMORY;
2424 }
2425 status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2426 if (!NT_STATUS_IS_OK(status)) {
2427 return status;
2428 }
2429
2430 if (r->in.old_val) {
2431 /* Decrypt */
2432 crypt_secret.data = r->in.old_val->data;
2433 crypt_secret.length = r->in.old_val->size;
2434
2435 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2436 if (!NT_STATUS_IS_OK(status)) {
2437 return status;
2438 }
2439
2440 val.data = secret.data;
2441 val.length = secret.length;
2442
2443 /* set value */
2444 if (samdb_msg_add_value(secret_state->sam_ldb,
2445 mem_ctx, msg, "priorValue", &val) != 0) {
2446 return NT_STATUS_NO_MEMORY;
2447 }
2448
2449 /* set old value mtime */
2450 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2451 mem_ctx, msg, "priorSetTime", nt_now) != 0) {
2452 return NT_STATUS_NO_MEMORY;
2453 }
2454
2455 if (!r->in.new_val) {
2456 /* This behaviour varies depending of if this is a local, or a global secret... */
2457 if (secret_state->global) {
2458 /* set old value mtime */
2459 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2460 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2461 return NT_STATUS_NO_MEMORY;
2462 }
2463 } else {
2464 if (samdb_msg_add_delete(secret_state->sam_ldb,
2465 mem_ctx, msg, "currentValue")) {
2466 return NT_STATUS_NO_MEMORY;
2467 }
2468 if (samdb_msg_add_delete(secret_state->sam_ldb,
2469 mem_ctx, msg, "lastSetTime")) {
2470 return NT_STATUS_NO_MEMORY;
2471 }
2472 }
2473 }
2474 }
2475
2476 if (r->in.new_val) {
2477 /* Decrypt */
2478 crypt_secret.data = r->in.new_val->data;
2479 crypt_secret.length = r->in.new_val->size;
2480
2481 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
2482 if (!NT_STATUS_IS_OK(status)) {
2483 return status;
2484 }
2485
2486 val.data = secret.data;
2487 val.length = secret.length;
2488
2489 /* set value */
2490 if (samdb_msg_add_value(secret_state->sam_ldb,
2491 mem_ctx, msg, "currentValue", &val) != 0) {
2492 return NT_STATUS_NO_MEMORY;
2493 }
2494
2495 /* set new value mtime */
2496 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2497 mem_ctx, msg, "lastSetTime", nt_now) != 0) {
2498 return NT_STATUS_NO_MEMORY;
2499 }
2500
2501 /* If the old value is not set, then migrate the
2502 * current value to the old value */
2503 if (!r->in.old_val) {
2504 const struct ldb_val *new_val;
2505 NTTIME last_set_time;
2506 struct ldb_message **res;
2507 const char *attrs[] = {
2508 "currentValue",
2509 "lastSetTime",
2510 NULL
2511 };
2512
2513 /* search for the secret record */
2514 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
2515 secret_state->secret_dn, &res, attrs);
2516 if (ret == 0) {
2517 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2518 }
2519
2520 if (ret != 1) {
2521 DEBUG(0,("Found %d records matching dn=%s\n", ret,
2522 ldb_dn_get_linearized(secret_state->secret_dn)));
2523 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2524 }
2525
2526 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2527 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2528
2529 if (new_val) {
2530 /* set value */
2531 if (samdb_msg_add_value(secret_state->sam_ldb,
2532 mem_ctx, msg, "priorValue",
2533 new_val) != 0) {
2534 return NT_STATUS_NO_MEMORY;
2535 }
2536 }
2537
2538 /* set new value mtime */
2539 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
2540 if (samdb_msg_add_uint64(secret_state->sam_ldb,
2541 mem_ctx, msg, "priorSetTime", last_set_time) != 0) {
2542 return NT_STATUS_NO_MEMORY;
2543 }
2544 }
2545 }
2546 }
2547
2548 /* modify the samdb record */
2549 ret = samdb_replace(secret_state->sam_ldb, mem_ctx, msg);
2550 if (ret != 0) {
2551 /* we really need samdb.c to return NTSTATUS */
2552 return NT_STATUS_UNSUCCESSFUL;
2553 }
2554
2555 return NT_STATUS_OK;
2556 }
2557
2558
2559 /*
2560 lsa_QuerySecret
2561 */
lsa_QuerySecret(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_QuerySecret * r)2562 static NTSTATUS lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2563 struct lsa_QuerySecret *r)
2564 {
2565 struct dcesrv_handle *h;
2566 struct lsa_secret_state *secret_state;
2567 struct ldb_message *msg;
2568 DATA_BLOB session_key;
2569 DATA_BLOB crypt_secret, secret;
2570 int ret;
2571 struct ldb_message **res;
2572 const char *attrs[] = {
2573 "currentValue",
2574 "priorValue",
2575 "lastSetTime",
2576 "priorSetTime",
2577 NULL
2578 };
2579
2580 NTSTATUS nt_status;
2581
2582 DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
2583
2584 secret_state = h->data;
2585
2586 /* pull all the user attributes */
2587 ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
2588 secret_state->secret_dn, &res, attrs);
2589 if (ret != 1) {
2590 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2591 }
2592 msg = res[0];
2593
2594 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
2595 if (!NT_STATUS_IS_OK(nt_status)) {
2596 return nt_status;
2597 }
2598
2599 if (r->in.old_val) {
2600 const struct ldb_val *prior_val;
2601 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2602 if (!r->out.old_val) {
2603 return NT_STATUS_NO_MEMORY;
2604 }
2605 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
2606
2607 if (prior_val && prior_val->length) {
2608 secret.data = prior_val->data;
2609 secret.length = prior_val->length;
2610
2611 /* Encrypt */
2612 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2613 if (!crypt_secret.length) {
2614 return NT_STATUS_NO_MEMORY;
2615 }
2616 r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2617 if (!r->out.old_val->buf) {
2618 return NT_STATUS_NO_MEMORY;
2619 }
2620 r->out.old_val->buf->size = crypt_secret.length;
2621 r->out.old_val->buf->length = crypt_secret.length;
2622 r->out.old_val->buf->data = crypt_secret.data;
2623 }
2624 }
2625
2626 if (r->in.old_mtime) {
2627 r->out.old_mtime = talloc(mem_ctx, NTTIME);
2628 if (!r->out.old_mtime) {
2629 return NT_STATUS_NO_MEMORY;
2630 }
2631 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(res[0], "priorSetTime", 0);
2632 }
2633
2634 if (r->in.new_val) {
2635 const struct ldb_val *new_val;
2636 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
2637 if (!r->out.new_val) {
2638 return NT_STATUS_NO_MEMORY;
2639 }
2640
2641 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
2642
2643 if (new_val && new_val->length) {
2644 secret.data = new_val->data;
2645 secret.length = new_val->length;
2646
2647 /* Encrypt */
2648 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
2649 if (!crypt_secret.length) {
2650 return NT_STATUS_NO_MEMORY;
2651 }
2652 r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
2653 if (!r->out.new_val->buf) {
2654 return NT_STATUS_NO_MEMORY;
2655 }
2656 r->out.new_val->buf->length = crypt_secret.length;
2657 r->out.new_val->buf->size = crypt_secret.length;
2658 r->out.new_val->buf->data = crypt_secret.data;
2659 }
2660 }
2661
2662 if (r->in.new_mtime) {
2663 r->out.new_mtime = talloc(mem_ctx, NTTIME);
2664 if (!r->out.new_mtime) {
2665 return NT_STATUS_NO_MEMORY;
2666 }
2667 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
2668 }
2669
2670 return NT_STATUS_OK;
2671 }
2672
2673
2674 /*
2675 lsa_LookupPrivValue
2676 */
lsa_LookupPrivValue(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LookupPrivValue * r)2677 static NTSTATUS lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
2678 TALLOC_CTX *mem_ctx,
2679 struct lsa_LookupPrivValue *r)
2680 {
2681 struct dcesrv_handle *h;
2682 struct lsa_policy_state *state;
2683 int id;
2684
2685 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2686
2687 state = h->data;
2688
2689 id = sec_privilege_id(r->in.name->string);
2690 if (id == -1) {
2691 return NT_STATUS_NO_SUCH_PRIVILEGE;
2692 }
2693
2694 r->out.luid->low = id;
2695 r->out.luid->high = 0;
2696
2697 return NT_STATUS_OK;
2698 }
2699
2700
2701 /*
2702 lsa_LookupPrivName
2703 */
lsa_LookupPrivName(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LookupPrivName * r)2704 static NTSTATUS lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
2705 TALLOC_CTX *mem_ctx,
2706 struct lsa_LookupPrivName *r)
2707 {
2708 struct dcesrv_handle *h;
2709 struct lsa_policy_state *state;
2710 const char *privname;
2711
2712 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2713
2714 state = h->data;
2715
2716 if (r->in.luid->high != 0) {
2717 return NT_STATUS_NO_SUCH_PRIVILEGE;
2718 }
2719
2720 privname = sec_privilege_name(r->in.luid->low);
2721 if (privname == NULL) {
2722 return NT_STATUS_NO_SUCH_PRIVILEGE;
2723 }
2724
2725 r->out.name = talloc(mem_ctx, struct lsa_StringLarge);
2726 if (r->out.name == NULL) {
2727 return NT_STATUS_NO_MEMORY;
2728 }
2729 r->out.name->string = privname;
2730
2731 return NT_STATUS_OK;
2732 }
2733
2734
2735 /*
2736 lsa_LookupPrivDisplayName
2737 */
lsa_LookupPrivDisplayName(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LookupPrivDisplayName * r)2738 static NTSTATUS lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
2739 TALLOC_CTX *mem_ctx,
2740 struct lsa_LookupPrivDisplayName *r)
2741 {
2742 struct dcesrv_handle *h;
2743 struct lsa_policy_state *state;
2744 int id;
2745
2746 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2747
2748 state = h->data;
2749
2750 id = sec_privilege_id(r->in.name->string);
2751 if (id == -1) {
2752 return NT_STATUS_NO_SUCH_PRIVILEGE;
2753 }
2754
2755 r->out.disp_name = talloc(mem_ctx, struct lsa_StringLarge);
2756 if (r->out.disp_name == NULL) {
2757 return NT_STATUS_NO_MEMORY;
2758 }
2759
2760 r->out.disp_name->string = sec_privilege_display_name(id, r->in.language_id);
2761 if (r->out.disp_name->string == NULL) {
2762 return NT_STATUS_INTERNAL_ERROR;
2763 }
2764
2765 return NT_STATUS_OK;
2766 }
2767
2768
2769 /*
2770 lsa_DeleteObject
2771 */
lsa_DeleteObject(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_DeleteObject * r)2772 static NTSTATUS lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2773 struct lsa_DeleteObject *r)
2774 {
2775 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2776 }
2777
2778
2779 /*
2780 lsa_EnumAccountsWithUserRight
2781 */
lsa_EnumAccountsWithUserRight(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_EnumAccountsWithUserRight * r)2782 static NTSTATUS lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
2783 TALLOC_CTX *mem_ctx,
2784 struct lsa_EnumAccountsWithUserRight *r)
2785 {
2786 struct dcesrv_handle *h;
2787 struct lsa_policy_state *state;
2788 int ret, i;
2789 struct ldb_message **res;
2790 const char * const attrs[] = { "objectSid", NULL};
2791 const char *privname;
2792
2793 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2794
2795 state = h->data;
2796
2797 if (r->in.name == NULL) {
2798 return NT_STATUS_NO_SUCH_PRIVILEGE;
2799 }
2800
2801 privname = r->in.name->string;
2802 if (sec_privilege_id(privname) == -1) {
2803 return NT_STATUS_NO_SUCH_PRIVILEGE;
2804 }
2805
2806 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs,
2807 "privilege=%s", privname);
2808 if (ret == -1) {
2809 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2810 }
2811 if (ret == 0) {
2812 return NT_STATUS_NO_MORE_ENTRIES;
2813 }
2814
2815 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
2816 if (r->out.sids->sids == NULL) {
2817 return NT_STATUS_NO_MEMORY;
2818 }
2819 for (i=0;i<ret;i++) {
2820 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
2821 res[i], "objectSid");
2822 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
2823 }
2824 r->out.sids->num_sids = ret;
2825
2826 return NT_STATUS_OK;
2827 }
2828
2829
2830 /*
2831 lsa_AddAccountRights
2832 */
lsa_AddAccountRights(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_AddAccountRights * r)2833 static NTSTATUS lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
2834 TALLOC_CTX *mem_ctx,
2835 struct lsa_AddAccountRights *r)
2836 {
2837 struct dcesrv_handle *h;
2838 struct lsa_policy_state *state;
2839
2840 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2841
2842 state = h->data;
2843
2844 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2845 LDB_FLAG_MOD_ADD,
2846 r->in.sid, r->in.rights);
2847 }
2848
2849
2850 /*
2851 lsa_RemoveAccountRights
2852 */
lsa_RemoveAccountRights(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_RemoveAccountRights * r)2853 static NTSTATUS lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
2854 TALLOC_CTX *mem_ctx,
2855 struct lsa_RemoveAccountRights *r)
2856 {
2857 struct dcesrv_handle *h;
2858 struct lsa_policy_state *state;
2859
2860 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
2861
2862 state = h->data;
2863
2864 return lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
2865 LDB_FLAG_MOD_DELETE,
2866 r->in.sid, r->in.rights);
2867 }
2868
2869
2870 /*
2871 lsa_StorePrivateData
2872 */
lsa_StorePrivateData(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_StorePrivateData * r)2873 static NTSTATUS lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2874 struct lsa_StorePrivateData *r)
2875 {
2876 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2877 }
2878
2879
2880 /*
2881 lsa_RetrievePrivateData
2882 */
lsa_RetrievePrivateData(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_RetrievePrivateData * r)2883 static NTSTATUS lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2884 struct lsa_RetrievePrivateData *r)
2885 {
2886 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2887 }
2888
2889
2890 /*
2891 lsa_GetUserName
2892 */
lsa_GetUserName(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_GetUserName * r)2893 static NTSTATUS lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
2894 struct lsa_GetUserName *r)
2895 {
2896 NTSTATUS status = NT_STATUS_OK;
2897 const char *account_name;
2898 const char *authority_name;
2899 struct lsa_String *_account_name;
2900 struct lsa_StringPointer *_authority_name = NULL;
2901
2902 /* this is what w2k3 does */
2903 r->out.account_name = r->in.account_name;
2904 r->out.authority_name = r->in.authority_name;
2905
2906 if (r->in.account_name && r->in.account_name->string) {
2907 return NT_STATUS_INVALID_PARAMETER;
2908 }
2909
2910 if (r->in.authority_name &&
2911 r->in.authority_name->string &&
2912 r->in.authority_name->string->string) {
2913 return NT_STATUS_INVALID_PARAMETER;
2914 }
2915
2916 account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->account_name);
2917 authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->server_info->domain_name);
2918
2919 _account_name = talloc(mem_ctx, struct lsa_String);
2920 NT_STATUS_HAVE_NO_MEMORY(_account_name);
2921 _account_name->string = account_name;
2922
2923 if (r->in.authority_name) {
2924 _authority_name = talloc(mem_ctx, struct lsa_StringPointer);
2925 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
2926 _authority_name->string = talloc(mem_ctx, struct lsa_String);
2927 NT_STATUS_HAVE_NO_MEMORY(_authority_name->string);
2928 _authority_name->string->string = authority_name;
2929 }
2930
2931 r->out.account_name = _account_name;
2932 r->out.authority_name = _authority_name;
2933
2934 return status;
2935 }
2936
2937 /*
2938 lsa_SetInfoPolicy2
2939 */
lsa_SetInfoPolicy2(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_SetInfoPolicy2 * r)2940 static NTSTATUS lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
2941 TALLOC_CTX *mem_ctx,
2942 struct lsa_SetInfoPolicy2 *r)
2943 {
2944 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2945 }
2946
2947 /*
2948 lsa_QueryDomainInformationPolicy
2949 */
lsa_QueryDomainInformationPolicy(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_QueryDomainInformationPolicy * r)2950 static NTSTATUS lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2951 TALLOC_CTX *mem_ctx,
2952 struct lsa_QueryDomainInformationPolicy *r)
2953 {
2954 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2955 }
2956
2957 /*
2958 lsa_SetDomInfoPolicy
2959 */
lsa_SetDomainInformationPolicy(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_SetDomainInformationPolicy * r)2960 static NTSTATUS lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
2961 TALLOC_CTX *mem_ctx,
2962 struct lsa_SetDomainInformationPolicy *r)
2963 {
2964 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2965 }
2966
2967 /*
2968 lsa_TestCall
2969 */
lsa_TestCall(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_TestCall * r)2970 static NTSTATUS lsa_TestCall(struct dcesrv_call_state *dce_call,
2971 TALLOC_CTX *mem_ctx,
2972 struct lsa_TestCall *r)
2973 {
2974 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
2975 }
2976
2977 /*
2978 lookup a SID for 1 name
2979 */
lsa_lookup_name(struct lsa_policy_state * state,TALLOC_CTX * mem_ctx,const char * name,struct dom_sid ** sid,uint32_t * atype)2980 static NTSTATUS lsa_lookup_name(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
2981 const char *name, struct dom_sid **sid, uint32_t *atype)
2982 {
2983 int ret;
2984 struct ldb_message **res;
2985 const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
2986 const char *p;
2987
2988 p = strchr_m(name, '\\');
2989 if (p != NULL) {
2990 /* TODO: properly parse the domain prefix here, and use it to
2991 limit the search */
2992 name = p + 1;
2993 }
2994
2995 ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", ldb_binary_encode_string(mem_ctx, name));
2996 if (ret == 1) {
2997 *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid");
2998 if (*sid == NULL) {
2999 return NT_STATUS_INVALID_SID;
3000 }
3001
3002 *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
3003
3004 return NT_STATUS_OK;
3005 }
3006
3007 /* need to add a call into sidmap to check for a allocated sid */
3008
3009 return NT_STATUS_INVALID_SID;
3010 }
3011
3012
3013 /*
3014 lsa_LookupNames3
3015 */
lsa_LookupNames3(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LookupNames3 * r)3016 static NTSTATUS lsa_LookupNames3(struct dcesrv_call_state *dce_call,
3017 TALLOC_CTX *mem_ctx,
3018 struct lsa_LookupNames3 *r)
3019 {
3020 struct lsa_policy_state *policy_state;
3021 struct dcesrv_handle *policy_handle;
3022 int i;
3023 NTSTATUS status = NT_STATUS_OK;
3024
3025 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
3026
3027 policy_state = policy_handle->data;
3028
3029 r->out.domains = NULL;
3030
3031 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3032 if (r->out.domains == NULL) {
3033 return NT_STATUS_NO_MEMORY;
3034 }
3035
3036 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray3);
3037 if (r->out.sids == NULL) {
3038 return NT_STATUS_NO_MEMORY;
3039 }
3040
3041 *r->out.count = 0;
3042
3043 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid3,
3044 r->in.num_names);
3045 if (r->out.sids->sids == NULL) {
3046 return NT_STATUS_NO_MEMORY;
3047 }
3048
3049 for (i=0;i<r->in.num_names;i++) {
3050 const char *name = r->in.names[i].string;
3051 struct dom_sid *sid;
3052 uint32_t atype, rtype, sid_index;
3053 NTSTATUS status2;
3054
3055 r->out.sids->count++;
3056 (*r->out.count)++;
3057
3058 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3059 r->out.sids->sids[i].sid = NULL;
3060 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3061 r->out.sids->sids[i].unknown = 0;
3062
3063 status2 = lsa_lookup_name(policy_state, mem_ctx, name, &sid, &atype);
3064 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3065 status = STATUS_SOME_UNMAPPED;
3066 continue;
3067 }
3068
3069 rtype = samdb_atype_map(atype);
3070 if (rtype == SID_NAME_UNKNOWN) {
3071 status = STATUS_SOME_UNMAPPED;
3072 continue;
3073 }
3074
3075 status2 = lsa_authority_list(policy_state, mem_ctx, sid, r->out.domains, &sid_index);
3076 if (!NT_STATUS_IS_OK(status2)) {
3077 return status2;
3078 }
3079
3080 r->out.sids->sids[i].sid_type = rtype;
3081 r->out.sids->sids[i].sid = sid;
3082 r->out.sids->sids[i].sid_index = sid_index;
3083 r->out.sids->sids[i].unknown = 0;
3084 }
3085
3086 return status;
3087 }
3088
3089 /*
3090 lsa_LookupNames4
3091
3092 Identical to LookupNames3, but doesn't take a policy handle
3093
3094 */
lsa_LookupNames4(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LookupNames4 * r)3095 static NTSTATUS lsa_LookupNames4(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3096 struct lsa_LookupNames4 *r)
3097 {
3098 struct lsa_LookupNames3 r2;
3099 struct lsa_OpenPolicy2 pol;
3100 NTSTATUS status;
3101 struct dcesrv_handle *h;
3102
3103 /* No policy handle on the wire, so make one up here */
3104 r2.in.handle = talloc(mem_ctx, struct policy_handle);
3105 if (!r2.in.handle) {
3106 return NT_STATUS_NO_MEMORY;
3107 }
3108
3109 pol.out.handle = r2.in.handle;
3110 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
3111 pol.in.attr = NULL;
3112 pol.in.system_name = NULL;
3113 status = lsa_OpenPolicy2(dce_call, mem_ctx, &pol);
3114 if (!NT_STATUS_IS_OK(status)) {
3115 return status;
3116 }
3117
3118 /* ensure this handle goes away at the end of this call */
3119 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY);
3120 talloc_steal(mem_ctx, h);
3121
3122 r2.in.num_names = r->in.num_names;
3123 r2.in.names = r->in.names;
3124 r2.in.sids = r->in.sids;
3125 r2.in.count = r->in.count;
3126 r2.in.unknown1 = r->in.unknown1;
3127 r2.in.unknown2 = r->in.unknown2;
3128 r2.out.domains = r->out.domains;
3129 r2.out.sids = r->out.sids;
3130 r2.out.count = r->out.count;
3131
3132 status = lsa_LookupNames3(dce_call, mem_ctx, &r2);
3133 if (dce_call->fault_code != 0) {
3134 return status;
3135 }
3136
3137 r->out.domains = r2.out.domains;
3138 r->out.sids = r2.out.sids;
3139 r->out.count = r2.out.count;
3140 return status;
3141 }
3142
3143 /*
3144 lsa_LookupNames2
3145 */
lsa_LookupNames2(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LookupNames2 * r)3146 static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
3147 TALLOC_CTX *mem_ctx,
3148 struct lsa_LookupNames2 *r)
3149 {
3150 struct lsa_policy_state *state;
3151 struct dcesrv_handle *h;
3152 int i;
3153 NTSTATUS status = NT_STATUS_OK;
3154
3155 r->out.domains = NULL;
3156
3157 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
3158
3159 state = h->data;
3160
3161 r->out.domains = talloc_zero(mem_ctx, struct lsa_RefDomainList);
3162 if (r->out.domains == NULL) {
3163 return NT_STATUS_NO_MEMORY;
3164 }
3165
3166 r->out.sids = talloc_zero(mem_ctx, struct lsa_TransSidArray2);
3167 if (r->out.sids == NULL) {
3168 return NT_STATUS_NO_MEMORY;
3169 }
3170
3171 *r->out.count = 0;
3172
3173 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid2,
3174 r->in.num_names);
3175 if (r->out.sids->sids == NULL) {
3176 return NT_STATUS_NO_MEMORY;
3177 }
3178
3179 for (i=0;i<r->in.num_names;i++) {
3180 const char *name = r->in.names[i].string;
3181 struct dom_sid *sid;
3182 uint32_t atype, rtype, sid_index;
3183 NTSTATUS status2;
3184
3185 r->out.sids->count++;
3186 (*r->out.count)++;
3187
3188 r->out.sids->sids[i].sid_type = SID_NAME_UNKNOWN;
3189 r->out.sids->sids[i].rid = 0xFFFFFFFF;
3190 r->out.sids->sids[i].sid_index = 0xFFFFFFFF;
3191 r->out.sids->sids[i].unknown = 0;
3192
3193 status2 = lsa_lookup_name(state, mem_ctx, name, &sid, &atype);
3194 if (!NT_STATUS_IS_OK(status2) || sid->num_auths == 0) {
3195 status = STATUS_SOME_UNMAPPED;
3196 continue;
3197 }
3198
3199 rtype = samdb_atype_map(atype);
3200 if (rtype == SID_NAME_UNKNOWN) {
3201 status = STATUS_SOME_UNMAPPED;
3202 continue;
3203 }
3204
3205 status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains, &sid_index);
3206 if (!NT_STATUS_IS_OK(status2)) {
3207 return status2;
3208 }
3209
3210 r->out.sids->sids[i].sid_type = rtype;
3211 r->out.sids->sids[i].rid = sid->sub_auths[sid->num_auths-1];
3212 r->out.sids->sids[i].sid_index = sid_index;
3213 r->out.sids->sids[i].unknown = 0;
3214 }
3215
3216 return status;
3217 }
3218
3219 /*
3220 lsa_LookupNames
3221 */
lsa_LookupNames(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LookupNames * r)3222 static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3223 struct lsa_LookupNames *r)
3224 {
3225 struct lsa_LookupNames2 r2;
3226 NTSTATUS status;
3227 int i;
3228
3229 r2.in.handle = r->in.handle;
3230 r2.in.num_names = r->in.num_names;
3231 r2.in.names = r->in.names;
3232 r2.in.sids = NULL;
3233 r2.in.level = r->in.level;
3234 r2.in.count = r->in.count;
3235 r2.in.unknown1 = 0;
3236 r2.in.unknown2 = 0;
3237 r2.out.count = r->out.count;
3238
3239 status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
3240 if (dce_call->fault_code != 0) {
3241 return status;
3242 }
3243
3244 r->out.domains = r2.out.domains;
3245 r->out.sids = talloc(mem_ctx, struct lsa_TransSidArray);
3246 if (r->out.sids == NULL) {
3247 return NT_STATUS_NO_MEMORY;
3248 }
3249 r->out.sids->count = r2.out.sids->count;
3250 r->out.sids->sids = talloc_array(r->out.sids, struct lsa_TranslatedSid,
3251 r->out.sids->count);
3252 if (r->out.sids->sids == NULL) {
3253 return NT_STATUS_NO_MEMORY;
3254 }
3255 for (i=0;i<r->out.sids->count;i++) {
3256 r->out.sids->sids[i].sid_type = r2.out.sids->sids[i].sid_type;
3257 r->out.sids->sids[i].rid = r2.out.sids->sids[i].rid;
3258 r->out.sids->sids[i].sid_index = r2.out.sids->sids[i].sid_index;
3259 }
3260
3261 return status;
3262 }
3263
3264 /*
3265 lsa_CREDRWRITE
3266 */
lsa_CREDRWRITE(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CREDRWRITE * r)3267 static NTSTATUS lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3268 struct lsa_CREDRWRITE *r)
3269 {
3270 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3271 }
3272
3273
3274 /*
3275 lsa_CREDRREAD
3276 */
lsa_CREDRREAD(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CREDRREAD * r)3277 static NTSTATUS lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3278 struct lsa_CREDRREAD *r)
3279 {
3280 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3281 }
3282
3283
3284 /*
3285 lsa_CREDRENUMERATE
3286 */
lsa_CREDRENUMERATE(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CREDRENUMERATE * r)3287 static NTSTATUS lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3288 struct lsa_CREDRENUMERATE *r)
3289 {
3290 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3291 }
3292
3293
3294 /*
3295 lsa_CREDRWRITEDOMAINCREDENTIALS
3296 */
lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CREDRWRITEDOMAINCREDENTIALS * r)3297 static NTSTATUS lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3298 struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
3299 {
3300 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3301 }
3302
3303
3304 /*
3305 lsa_CREDRREADDOMAINCREDENTIALS
3306 */
lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CREDRREADDOMAINCREDENTIALS * r)3307 static NTSTATUS lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3308 struct lsa_CREDRREADDOMAINCREDENTIALS *r)
3309 {
3310 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3311 }
3312
3313
3314 /*
3315 lsa_CREDRDELETE
3316 */
lsa_CREDRDELETE(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CREDRDELETE * r)3317 static NTSTATUS lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3318 struct lsa_CREDRDELETE *r)
3319 {
3320 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3321 }
3322
3323
3324 /*
3325 lsa_CREDRGETTARGETINFO
3326 */
lsa_CREDRGETTARGETINFO(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CREDRGETTARGETINFO * r)3327 static NTSTATUS lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3328 struct lsa_CREDRGETTARGETINFO *r)
3329 {
3330 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3331 }
3332
3333
3334 /*
3335 lsa_CREDRPROFILELOADED
3336 */
lsa_CREDRPROFILELOADED(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CREDRPROFILELOADED * r)3337 static NTSTATUS lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3338 struct lsa_CREDRPROFILELOADED *r)
3339 {
3340 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3341 }
3342
3343
3344 /*
3345 lsa_CREDRGETSESSIONTYPES
3346 */
lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CREDRGETSESSIONTYPES * r)3347 static NTSTATUS lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3348 struct lsa_CREDRGETSESSIONTYPES *r)
3349 {
3350 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3351 }
3352
3353
3354 /*
3355 lsa_LSARREGISTERAUDITEVENT
3356 */
lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LSARREGISTERAUDITEVENT * r)3357 static NTSTATUS lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3358 struct lsa_LSARREGISTERAUDITEVENT *r)
3359 {
3360 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3361 }
3362
3363
3364 /*
3365 lsa_LSARGENAUDITEVENT
3366 */
lsa_LSARGENAUDITEVENT(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LSARGENAUDITEVENT * r)3367 static NTSTATUS lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3368 struct lsa_LSARGENAUDITEVENT *r)
3369 {
3370 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3371 }
3372
3373
3374 /*
3375 lsa_LSARUNREGISTERAUDITEVENT
3376 */
lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LSARUNREGISTERAUDITEVENT * r)3377 static NTSTATUS lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3378 struct lsa_LSARUNREGISTERAUDITEVENT *r)
3379 {
3380 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3381 }
3382
3383
3384 /*
3385 lsa_LSARQUERYFORESTTRUSTINFORMATION
3386 */
lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LSARQUERYFORESTTRUSTINFORMATION * r)3387 static NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3388 struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
3389 {
3390 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3391 }
3392
3393
3394 /*
3395 lsa_LSARSETFORESTTRUSTINFORMATION
3396 */
lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LSARSETFORESTTRUSTINFORMATION * r)3397 static NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3398 struct lsa_LSARSETFORESTTRUSTINFORMATION *r)
3399 {
3400 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3401 }
3402
3403
3404 /*
3405 lsa_CREDRRENAME
3406 */
lsa_CREDRRENAME(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_CREDRRENAME * r)3407 static NTSTATUS lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3408 struct lsa_CREDRRENAME *r)
3409 {
3410 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3411 }
3412
3413
3414
3415 /*
3416 lsa_LSAROPENPOLICYSCE
3417 */
lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LSAROPENPOLICYSCE * r)3418 static NTSTATUS lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3419 struct lsa_LSAROPENPOLICYSCE *r)
3420 {
3421 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3422 }
3423
3424
3425 /*
3426 lsa_LSARADTREGISTERSECURITYEVENTSOURCE
3427 */
lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE * r)3428 static NTSTATUS lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3429 struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
3430 {
3431 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3432 }
3433
3434
3435 /*
3436 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
3437 */
lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE * r)3438 static NTSTATUS lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3439 struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
3440 {
3441 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3442 }
3443
3444
3445 /*
3446 lsa_LSARADTREPORTSECURITYEVENT
3447 */
lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct lsa_LSARADTREPORTSECURITYEVENT * r)3448 static NTSTATUS lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3449 struct lsa_LSARADTREPORTSECURITYEVENT *r)
3450 {
3451 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3452 }
3453
3454
3455 /* include the generated boilerplate */
3456 #include "librpc/gen_ndr/ndr_lsa_s.c"
3457
3458
3459
3460 /*****************************************
3461 NOTE! The remaining calls below were
3462 removed in w2k3, so the DCESRV_FAULT()
3463 replies are the correct implementation. Do
3464 not try and fill these in with anything else
3465 ******************************************/
3466
3467 /*
3468 dssetup_DsRoleDnsNameToFlatName
3469 */
dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct dssetup_DsRoleDnsNameToFlatName * r)3470 static WERROR dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3471 struct dssetup_DsRoleDnsNameToFlatName *r)
3472 {
3473 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3474 }
3475
3476
3477 /*
3478 dssetup_DsRoleDcAsDc
3479 */
dssetup_DsRoleDcAsDc(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct dssetup_DsRoleDcAsDc * r)3480 static WERROR dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3481 struct dssetup_DsRoleDcAsDc *r)
3482 {
3483 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3484 }
3485
3486
3487 /*
3488 dssetup_DsRoleDcAsReplica
3489 */
dssetup_DsRoleDcAsReplica(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct dssetup_DsRoleDcAsReplica * r)3490 static WERROR dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3491 struct dssetup_DsRoleDcAsReplica *r)
3492 {
3493 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3494 }
3495
3496
3497 /*
3498 dssetup_DsRoleDemoteDc
3499 */
dssetup_DsRoleDemoteDc(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct dssetup_DsRoleDemoteDc * r)3500 static WERROR dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3501 struct dssetup_DsRoleDemoteDc *r)
3502 {
3503 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3504 }
3505
3506
3507 /*
3508 dssetup_DsRoleGetDcOperationProgress
3509 */
dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct dssetup_DsRoleGetDcOperationProgress * r)3510 static WERROR dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3511 struct dssetup_DsRoleGetDcOperationProgress *r)
3512 {
3513 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3514 }
3515
3516
3517 /*
3518 dssetup_DsRoleGetDcOperationResults
3519 */
dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct dssetup_DsRoleGetDcOperationResults * r)3520 static WERROR dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3521 struct dssetup_DsRoleGetDcOperationResults *r)
3522 {
3523 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3524 }
3525
3526
3527 /*
3528 dssetup_DsRoleCancel
3529 */
dssetup_DsRoleCancel(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct dssetup_DsRoleCancel * r)3530 static WERROR dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3531 struct dssetup_DsRoleCancel *r)
3532 {
3533 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3534 }
3535
3536
3537 /*
3538 dssetup_DsRoleServerSaveStateForUpgrade
3539 */
dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct dssetup_DsRoleServerSaveStateForUpgrade * r)3540 static WERROR dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3541 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
3542 {
3543 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3544 }
3545
3546
3547 /*
3548 dssetup_DsRoleUpgradeDownlevelServer
3549 */
dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct dssetup_DsRoleUpgradeDownlevelServer * r)3550 static WERROR dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3551 struct dssetup_DsRoleUpgradeDownlevelServer *r)
3552 {
3553 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3554 }
3555
3556
3557 /*
3558 dssetup_DsRoleAbortDownlevelServerUpgrade
3559 */
dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state * dce_call,TALLOC_CTX * mem_ctx,struct dssetup_DsRoleAbortDownlevelServerUpgrade * r)3560 static WERROR dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
3561 struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
3562 {
3563 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
3564 }
3565
3566
3567 /* include the generated boilerplate */
3568 #include "librpc/gen_ndr/ndr_dssetup_s.c"
3569
dcerpc_server_lsa_init(void)3570 NTSTATUS dcerpc_server_lsa_init(void)
3571 {
3572 NTSTATUS ret;
3573
3574 ret = dcerpc_server_dssetup_init();
3575 if (!NT_STATUS_IS_OK(ret)) {
3576 return ret;
3577 }
3578 ret = dcerpc_server_lsarpc_init();
3579 if (!NT_STATUS_IS_OK(ret)) {
3580 return ret;
3581 }
3582 return ret;
3583 }
3584