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