4cf79a2346022f5d6c6ff7c8ab09bd12cd3910e5
[kai/samba-autobuild/.git] / source4 / rpc_server / lsa / lsa_init.c
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
25 NTSTATUS 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, 0);
47         if (state->sam_ldb == NULL) {
48                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
49         }
50
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;
55         }
56
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;             
62         }
63
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;             
69         }
70
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;
75         }
76         if (dom_res->count != 1) {
77                 return NT_STATUS_NO_SUCH_DOMAIN;                
78         }
79
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;                
83         }
84
85         state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
86
87         state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
88         
89         talloc_free(dom_res);
90
91         state->domain_name = lpcfg_sam_name(dce_call->conn->dce_ctx->lp_ctx);
92
93         state->domain_dns = ldb_dn_canonical_string(state, state->domain_dn);
94         if (!state->domain_dns) {
95                 return NT_STATUS_NO_SUCH_DOMAIN;                
96         }
97         p = strchr(state->domain_dns, '/');
98         if (p) {
99                 *p = '\0';
100         }
101
102         state->forest_dns = ldb_dn_canonical_string(state, state->forest_dn);
103         if (!state->forest_dns) {
104                 return NT_STATUS_NO_SUCH_DOMAIN;                
105         }
106         p = strchr(state->forest_dns, '/');
107         if (p) {
108                 *p = '\0';
109         }
110
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;                
116         }
117
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;                
124         }
125
126         state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
127         if (!state->builtin_sid) {
128                 return NT_STATUS_NO_SUCH_DOMAIN;                
129         }
130
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;                
134         }
135
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;                
139         }
140
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;                
144         }
145
146         *_state = state;
147
148         return NT_STATUS_OK;
149 }
150
151 /* 
152   lsa_OpenPolicy2
153 */
154 NTSTATUS dcesrv_lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
155                                 struct lsa_OpenPolicy2 *r)
156 {
157         enum dcerpc_transport_t transport =
158                 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
159         NTSTATUS status;
160         struct lsa_policy_state *state;
161         struct dcesrv_handle *handle;
162
163         if (transport != NCACN_NP && transport != NCALRPC) {
164                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
165         }
166
167         ZERO_STRUCTP(r->out.handle);
168
169         if (r->in.attr != NULL &&
170             r->in.attr->root_dir != NULL) {
171                 /* MS-LSAD 3.1.4.4.1 */
172                 return NT_STATUS_INVALID_PARAMETER;
173         }
174
175         status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
176         if (!NT_STATUS_IS_OK(status)) {
177                 return status;
178         }
179
180         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
181         if (!handle) {
182                 return NT_STATUS_NO_MEMORY;
183         }
184
185         handle->data = talloc_steal(handle, state);
186
187         /* need to check the access mask against - need ACLs - fails
188            WSPP test */
189         state->access_mask = r->in.access_mask;
190         state->handle = handle;
191         *r->out.handle = handle->wire_handle;
192
193         /* note that we have completely ignored the attr element of
194            the OpenPolicy. As far as I can tell, this is what w2k3
195            does */
196
197         return NT_STATUS_OK;
198 }
199
200 /* 
201   lsa_OpenPolicy
202   a wrapper around lsa_OpenPolicy2
203 */
204 NTSTATUS dcesrv_lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
205                                 struct lsa_OpenPolicy *r)
206 {
207         enum dcerpc_transport_t transport =
208                 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
209         struct lsa_OpenPolicy2 r2;
210
211         if (transport != NCACN_NP && transport != NCALRPC) {
212                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
213         }
214
215         r2.in.system_name = NULL;
216         r2.in.attr = r->in.attr;
217         r2.in.access_mask = r->in.access_mask;
218         r2.out.handle = r->out.handle;
219
220         return dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
221 }
222
223