• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.5.8/source4/rpc_server/lsa/
1/*
2   Unix SMB/CIFS implementation.
3
4   endpoint server for the lsarpc pipe
5
6   Copyright (C) Andrew Tridgell 2004
7   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2007
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 3 of the License, or
12   (at your option) any later version.
13
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with this program.  If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#include "rpc_server/lsa/lsa.h"
24
25NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
26				     struct lsa_policy_state **_state)
27{
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
36	};
37	char *p;
38	int ret;
39
40	state = talloc(mem_ctx, struct lsa_policy_state);
41	if (!state) {
42		return NT_STATUS_NO_MEMORY;
43	}
44
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);
47	if (state->sam_ldb == NULL) {
48		return NT_STATUS_INVALID_SYSTEM_SERVICE;
49	}
50
51	/* work out the domain_dn - useful for so many calls its worth
52	   fetching here */
53	state->domain_dn = ldb_get_default_basedn(state->sam_ldb);
54	if (!state->domain_dn) {
55		return NT_STATUS_NO_MEMORY;
56	}
57
58	/* work out the forest root_dn - useful for so many calls its worth
59	   fetching here */
60	state->forest_dn = samdb_root_dn(state->sam_ldb);
61	if (!state->forest_dn) {
62		return NT_STATUS_NO_MEMORY;
63	}
64
65	ret = ldb_search(state->sam_ldb, mem_ctx, &dom_res,
66			 state->domain_dn, LDB_SCOPE_BASE, dom_attrs, NULL);
67	if (ret != LDB_SUCCESS) {
68		return NT_STATUS_INVALID_SYSTEM_SERVICE;
69	}
70	if (dom_res->count != 1) {
71		return NT_STATUS_NO_SUCH_DOMAIN;
72	}
73
74	state->domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
75	if (!state->domain_sid) {
76		return NT_STATUS_NO_SUCH_DOMAIN;
77	}
78
79	state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
80
81	state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
82
83	talloc_free(dom_res);
84
85	state->domain_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
86
87	state->domain_dns = ldb_dn_canonical_string(state, state->domain_dn);
88	if (!state->domain_dns) {
89		return NT_STATUS_NO_SUCH_DOMAIN;
90	}
91	p = strchr(state->domain_dns, '/');
92	if (p) {
93		*p = '\0';
94	}
95
96	state->forest_dns = ldb_dn_canonical_string(state, state->forest_dn);
97	if (!state->forest_dns) {
98		return NT_STATUS_NO_SUCH_DOMAIN;
99	}
100	p = strchr(state->forest_dns, '/');
101	if (p) {
102		*p = '\0';
103	}
104
105	/* work out the builtin_dn - useful for so many calls its worth
106	   fetching here */
107	state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
108	if (!state->builtin_dn) {
109		return NT_STATUS_NO_SUCH_DOMAIN;
110	}
111
112	/* work out the system_dn - useful for so many calls its worth
113	   fetching here */
114	state->system_dn = samdb_search_dn(state->sam_ldb, state,
115					   state->domain_dn, "(&(objectClass=container)(cn=System))");
116	if (!state->system_dn) {
117		return NT_STATUS_NO_SUCH_DOMAIN;
118	}
119
120	state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
121	if (!state->builtin_sid) {
122		return NT_STATUS_NO_SUCH_DOMAIN;
123	}
124
125	state->nt_authority_sid = dom_sid_parse_talloc(state, SID_NT_AUTHORITY);
126	if (!state->nt_authority_sid) {
127		return NT_STATUS_NO_SUCH_DOMAIN;
128	}
129
130	state->creator_owner_domain_sid = dom_sid_parse_talloc(state, SID_CREATOR_OWNER_DOMAIN);
131	if (!state->creator_owner_domain_sid) {
132		return NT_STATUS_NO_SUCH_DOMAIN;
133	}
134
135	state->world_domain_sid = dom_sid_parse_talloc(state, SID_WORLD_DOMAIN);
136	if (!state->world_domain_sid) {
137		return NT_STATUS_NO_SUCH_DOMAIN;
138	}
139
140	*_state = state;
141
142	return NT_STATUS_OK;
143}
144
145/*
146  lsa_OpenPolicy2
147*/
148NTSTATUS dcesrv_lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
149				struct lsa_OpenPolicy2 *r)
150{
151	NTSTATUS status;
152	struct lsa_policy_state *state;
153	struct dcesrv_handle *handle;
154
155	ZERO_STRUCTP(r->out.handle);
156
157	if (r->in.attr != NULL &&
158	    r->in.attr->root_dir != NULL) {
159		/* MS-LSAD 3.1.4.4.1 */
160		return NT_STATUS_INVALID_PARAMETER;
161	}
162
163	status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
164	if (!NT_STATUS_IS_OK(status)) {
165		return status;
166	}
167
168	handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
169	if (!handle) {
170		return NT_STATUS_NO_MEMORY;
171	}
172
173	handle->data = talloc_steal(handle, state);
174
175	/* need to check the access mask against - need ACLs - fails
176	   WSPP test */
177	state->access_mask = r->in.access_mask;
178	state->handle = handle;
179	*r->out.handle = handle->wire_handle;
180
181	/* note that we have completely ignored the attr element of
182	   the OpenPolicy. As far as I can tell, this is what w2k3
183	   does */
184
185	return NT_STATUS_OK;
186}
187
188/*
189  lsa_OpenPolicy
190  a wrapper around lsa_OpenPolicy2
191*/
192NTSTATUS dcesrv_lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
193				struct lsa_OpenPolicy *r)
194{
195	struct lsa_OpenPolicy2 r2;
196
197	r2.in.system_name = NULL;
198	r2.in.attr = r->in.attr;
199	r2.in.access_mask = r->in.access_mask;
200	r2.out.handle = r->out.handle;
201
202	return dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
203}
204
205
206