s4:torture/smb2: fix compound.invalid2 against windows
[Samba/gebeck_regimport.git] / source4 / rpc_server / lsa / lsa_init.c
blob9b95374c0570b9cf163847ff89909b8351af1938
1 /*
2 Unix SMB/CIFS implementation.
4 endpoint server for the lsarpc pipe
6 Copyright (C) Andrew Tridgell 2004
7 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "rpc_server/lsa/lsa.h"
25 NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
26 struct lsa_policy_state **_state)
28 struct lsa_policy_state *state;
29 struct ldb_result *dom_res;
30 const char *dom_attrs[] = {
31 "objectSid",
32 "objectGUID",
33 "nTMixedDomain",
34 "fSMORoleOwner",
35 NULL
37 char *p;
38 int ret;
40 state = talloc(mem_ctx, struct lsa_policy_state);
41 if (!state) {
42 return NT_STATUS_NO_MEMORY;
45 /* make sure the sam database is accessible */
46 state->sam_ldb = samdb_connect(state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info, 0);
47 if (state->sam_ldb == NULL) {
48 return NT_STATUS_INVALID_SYSTEM_SERVICE;
51 /* and the privilege database */
52 state->pdb = privilege_connect(state, dce_call->conn->dce_ctx->lp_ctx);
53 if (state->pdb == NULL) {
54 return NT_STATUS_INVALID_SYSTEM_SERVICE;
57 /* work out the domain_dn - useful for so many calls its worth
58 fetching here */
59 state->domain_dn = ldb_get_default_basedn(state->sam_ldb);
60 if (!state->domain_dn) {
61 return NT_STATUS_NO_MEMORY;
64 /* work out the forest root_dn - useful for so many calls its worth
65 fetching here */
66 state->forest_dn = ldb_get_root_basedn(state->sam_ldb);
67 if (!state->forest_dn) {
68 return NT_STATUS_NO_MEMORY;
71 ret = ldb_search(state->sam_ldb, mem_ctx, &dom_res,
72 state->domain_dn, LDB_SCOPE_BASE, dom_attrs, NULL);
73 if (ret != LDB_SUCCESS) {
74 return NT_STATUS_INVALID_SYSTEM_SERVICE;
76 if (dom_res->count != 1) {
77 return NT_STATUS_NO_SUCH_DOMAIN;
80 state->domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
81 if (!state->domain_sid) {
82 return NT_STATUS_NO_SUCH_DOMAIN;
85 state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
87 state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
89 talloc_free(dom_res);
91 state->domain_name = lpcfg_sam_name(dce_call->conn->dce_ctx->lp_ctx);
93 state->domain_dns = ldb_dn_canonical_string(state, state->domain_dn);
94 if (!state->domain_dns) {
95 return NT_STATUS_NO_SUCH_DOMAIN;
97 p = strchr(state->domain_dns, '/');
98 if (p) {
99 *p = '\0';
102 state->forest_dns = ldb_dn_canonical_string(state, state->forest_dn);
103 if (!state->forest_dns) {
104 return NT_STATUS_NO_SUCH_DOMAIN;
106 p = strchr(state->forest_dns, '/');
107 if (p) {
108 *p = '\0';
111 /* work out the builtin_dn - useful for so many calls its worth
112 fetching here */
113 state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
114 if (!state->builtin_dn) {
115 return NT_STATUS_NO_SUCH_DOMAIN;
118 /* work out the system_dn - useful for so many calls its worth
119 fetching here */
120 state->system_dn = samdb_search_dn(state->sam_ldb, state,
121 state->domain_dn, "(&(objectClass=container)(cn=System))");
122 if (!state->system_dn) {
123 return NT_STATUS_NO_SUCH_DOMAIN;
126 state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
127 if (!state->builtin_sid) {
128 return NT_STATUS_NO_SUCH_DOMAIN;
131 state->nt_authority_sid = dom_sid_parse_talloc(state, SID_NT_AUTHORITY);
132 if (!state->nt_authority_sid) {
133 return NT_STATUS_NO_SUCH_DOMAIN;
136 state->creator_owner_domain_sid = dom_sid_parse_talloc(state, SID_CREATOR_OWNER_DOMAIN);
137 if (!state->creator_owner_domain_sid) {
138 return NT_STATUS_NO_SUCH_DOMAIN;
141 state->world_domain_sid = dom_sid_parse_talloc(state, SID_WORLD_DOMAIN);
142 if (!state->world_domain_sid) {
143 return NT_STATUS_NO_SUCH_DOMAIN;
146 *_state = state;
148 return NT_STATUS_OK;
152 lsa_OpenPolicy2
154 NTSTATUS dcesrv_lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
155 struct lsa_OpenPolicy2 *r)
157 NTSTATUS status;
158 struct lsa_policy_state *state;
159 struct dcesrv_handle *handle;
161 ZERO_STRUCTP(r->out.handle);
163 if (r->in.attr != NULL &&
164 r->in.attr->root_dir != NULL) {
165 /* MS-LSAD 3.1.4.4.1 */
166 return NT_STATUS_INVALID_PARAMETER;
169 status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
170 if (!NT_STATUS_IS_OK(status)) {
171 return status;
174 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
175 if (!handle) {
176 return NT_STATUS_NO_MEMORY;
179 handle->data = talloc_steal(handle, state);
181 /* need to check the access mask against - need ACLs - fails
182 WSPP test */
183 state->access_mask = r->in.access_mask;
184 state->handle = handle;
185 *r->out.handle = handle->wire_handle;
187 /* note that we have completely ignored the attr element of
188 the OpenPolicy. As far as I can tell, this is what w2k3
189 does */
191 return NT_STATUS_OK;
195 lsa_OpenPolicy
196 a wrapper around lsa_OpenPolicy2
198 NTSTATUS dcesrv_lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
199 struct lsa_OpenPolicy *r)
201 struct lsa_OpenPolicy2 r2;
203 r2.in.system_name = NULL;
204 r2.in.attr = r->in.attr;
205 r2.in.access_mask = r->in.access_mask;
206 r2.out.handle = r->out.handle;
208 return dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &r2);