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_dn *partitions_basedn;
30 struct ldb_result *dom_res;
31 const char *dom_attrs[] = {
38 struct ldb_result *ref_res;
39 struct ldb_result *forest_ref_res;
40 const char *ref_attrs[] = {
47 state = talloc(mem_ctx, struct lsa_policy_state);
49 return NT_STATUS_NO_MEMORY;
52 /* make sure the sam database is accessible */
53 state->sam_ldb = samdb_connect(state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
54 if (state->sam_ldb == NULL) {
55 return NT_STATUS_INVALID_SYSTEM_SERVICE;
58 partitions_basedn = samdb_partitions_dn(state->sam_ldb, mem_ctx);
60 /* work out the domain_dn - useful for so many calls its worth
62 state->domain_dn = samdb_base_dn(state->sam_ldb);
63 if (!state->domain_dn) {
64 return NT_STATUS_NO_MEMORY;
67 /* work out the forest root_dn - useful for so many calls its worth
69 state->forest_dn = samdb_root_dn(state->sam_ldb);
70 if (!state->forest_dn) {
71 return NT_STATUS_NO_MEMORY;
74 ret = ldb_search(state->sam_ldb, state->domain_dn, LDB_SCOPE_BASE, NULL, dom_attrs, &dom_res);
76 if (ret != LDB_SUCCESS) {
77 return NT_STATUS_INVALID_SYSTEM_SERVICE;
79 talloc_steal(mem_ctx, dom_res);
80 if (dom_res->count != 1) {
81 return NT_STATUS_NO_SUCH_DOMAIN;
84 state->domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
85 if (!state->domain_sid) {
86 return NT_STATUS_NO_SUCH_DOMAIN;
89 state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
90 if (!state->domain_sid) {
91 return NT_STATUS_NO_SUCH_DOMAIN;
94 state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
98 ret = ldb_search_exp_fmt(state->sam_ldb, state, &ref_res,
99 partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
100 "(&(objectclass=crossRef)(ncName=%s))",
101 ldb_dn_get_linearized(state->domain_dn));
103 if (ret != LDB_SUCCESS) {
104 talloc_free(ref_res);
105 return NT_STATUS_INVALID_SYSTEM_SERVICE;
107 if (ref_res->count != 1) {
108 talloc_free(ref_res);
109 return NT_STATUS_NO_SUCH_DOMAIN;
112 state->domain_name = ldb_msg_find_attr_as_string(ref_res->msgs[0], "nETBIOSName", NULL);
113 if (!state->domain_name) {
114 talloc_free(ref_res);
115 return NT_STATUS_NO_SUCH_DOMAIN;
117 talloc_steal(state, state->domain_name);
119 state->domain_dns = ldb_msg_find_attr_as_string(ref_res->msgs[0], "dnsRoot", NULL);
120 if (!state->domain_dns) {
121 talloc_free(ref_res);
122 return NT_STATUS_NO_SUCH_DOMAIN;
124 talloc_steal(state, state->domain_dns);
126 talloc_free(ref_res);
128 ret = ldb_search_exp_fmt(state->sam_ldb, state, &forest_ref_res,
129 partitions_basedn, LDB_SCOPE_SUBTREE, ref_attrs,
130 "(&(objectclass=crossRef)(ncName=%s))",
131 ldb_dn_get_linearized(state->forest_dn));
133 if (ret != LDB_SUCCESS) {
134 talloc_free(forest_ref_res);
135 return NT_STATUS_INVALID_SYSTEM_SERVICE;
137 if (forest_ref_res->count != 1) {
138 talloc_free(forest_ref_res);
139 return NT_STATUS_NO_SUCH_DOMAIN;
142 state->forest_dns = ldb_msg_find_attr_as_string(forest_ref_res->msgs[0], "dnsRoot", NULL);
143 if (!state->forest_dns) {
144 talloc_free(forest_ref_res);
145 return NT_STATUS_NO_SUCH_DOMAIN;
147 talloc_steal(state, state->forest_dns);
149 talloc_free(forest_ref_res);
151 /* work out the builtin_dn - useful for so many calls its worth
153 state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
154 if (!state->builtin_dn) {
155 return NT_STATUS_NO_SUCH_DOMAIN;
158 /* work out the system_dn - useful for so many calls its worth
160 state->system_dn = samdb_search_dn(state->sam_ldb, state,
161 state->domain_dn, "(&(objectClass=container)(cn=System))");
162 if (!state->system_dn) {
163 return NT_STATUS_NO_SUCH_DOMAIN;
166 state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
167 if (!state->builtin_sid) {
168 return NT_STATUS_NO_SUCH_DOMAIN;
171 state->nt_authority_sid = dom_sid_parse_talloc(state, SID_NT_AUTHORITY);
172 if (!state->nt_authority_sid) {
173 return NT_STATUS_NO_SUCH_DOMAIN;
176 state->creator_owner_domain_sid = dom_sid_parse_talloc(state, SID_CREATOR_OWNER_DOMAIN);
177 if (!state->creator_owner_domain_sid) {
178 return NT_STATUS_NO_SUCH_DOMAIN;
181 state->world_domain_sid = dom_sid_parse_talloc(state, SID_WORLD_DOMAIN);
182 if (!state->world_domain_sid) {
183 return NT_STATUS_NO_SUCH_DOMAIN;
194 NTSTATUS dcesrv_lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
195 struct lsa_OpenPolicy2 *r)
198 struct lsa_policy_state *state;
199 struct dcesrv_handle *handle;
201 ZERO_STRUCTP(r->out.handle);
203 status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
204 if (!NT_STATUS_IS_OK(status)) {
208 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
210 return NT_STATUS_NO_MEMORY;
213 handle->data = talloc_steal(handle, state);
215 state->access_mask = r->in.access_mask;
216 state->handle = handle;
217 *r->out.handle = handle->wire_handle;
219 /* note that we have completely ignored the attr element of
220 the OpenPolicy. As far as I can tell, this is what w2k3
228 a wrapper around lsa_OpenPolicy2
230 NTSTATUS dcesrv_lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
231 struct lsa_OpenPolicy *r)
233 struct lsa_OpenPolicy2 r2;
235 r2.in.system_name = NULL;
236 r2.in.attr = r->in.attr;
237 r2.in.access_mask = r->in.access_mask;
238 r2.out.handle = r->out.handle;
240 return dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &r2);