dd7d46b41daad66082982713e0e6fce45cc3d169
[ira/wip.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 #include "dsdb/samdb/samdb_proto.h"
25
26 NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
27                                      struct lsa_policy_state **_state)
28 {
29         struct lsa_policy_state *state;
30         struct ldb_result *dom_res;
31         const char *dom_attrs[] = {
32                 "objectSid", 
33                 "objectGUID", 
34                 "nTMixedDomain",
35                 "fSMORoleOwner",
36                 NULL
37         };
38         char *p;
39         int ret;
40
41         state = talloc(mem_ctx, struct lsa_policy_state);
42         if (!state) {
43                 return NT_STATUS_NO_MEMORY;
44         }
45
46         /* make sure the sam database is accessible */
47         state->sam_ldb = samdb_connect(state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info); 
48         if (state->sam_ldb == NULL) {
49                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
50         }
51
52         /* and the privilege database */
53         state->pdb = privilege_connect(state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
54         if (state->pdb == NULL) {
55                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
56         }
57
58         /* work out the domain_dn - useful for so many calls its worth
59            fetching here */
60         state->domain_dn = ldb_get_default_basedn(state->sam_ldb);
61         if (!state->domain_dn) {
62                 return NT_STATUS_NO_MEMORY;             
63         }
64
65         /* work out the forest root_dn - useful for so many calls its worth
66            fetching here */
67         state->forest_dn = samdb_root_dn(state->sam_ldb);
68         if (!state->forest_dn) {
69                 return NT_STATUS_NO_MEMORY;             
70         }
71
72         ret = ldb_search(state->sam_ldb, mem_ctx, &dom_res,
73                          state->domain_dn, LDB_SCOPE_BASE, dom_attrs, NULL);
74         if (ret != LDB_SUCCESS) {
75                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
76         }
77         if (dom_res->count != 1) {
78                 return NT_STATUS_NO_SUCH_DOMAIN;                
79         }
80
81         state->domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
82         if (!state->domain_sid) {
83                 return NT_STATUS_NO_SUCH_DOMAIN;                
84         }
85
86         state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
87
88         state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
89         
90         talloc_free(dom_res);
91
92         state->domain_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
93
94         state->domain_dns = ldb_dn_canonical_string(state, state->domain_dn);
95         if (!state->domain_dns) {
96                 return NT_STATUS_NO_SUCH_DOMAIN;                
97         }
98         p = strchr(state->domain_dns, '/');
99         if (p) {
100                 *p = '\0';
101         }
102
103         state->forest_dns = ldb_dn_canonical_string(state, state->forest_dn);
104         if (!state->forest_dns) {
105                 return NT_STATUS_NO_SUCH_DOMAIN;                
106         }
107         p = strchr(state->forest_dns, '/');
108         if (p) {
109                 *p = '\0';
110         }
111
112         /* work out the builtin_dn - useful for so many calls its worth
113            fetching here */
114         state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
115         if (!state->builtin_dn) {
116                 return NT_STATUS_NO_SUCH_DOMAIN;                
117         }
118
119         /* work out the system_dn - useful for so many calls its worth
120            fetching here */
121         state->system_dn = samdb_search_dn(state->sam_ldb, state,
122                                            state->domain_dn, "(&(objectClass=container)(cn=System))");
123         if (!state->system_dn) {
124                 return NT_STATUS_NO_SUCH_DOMAIN;                
125         }
126
127         state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
128         if (!state->builtin_sid) {
129                 return NT_STATUS_NO_SUCH_DOMAIN;                
130         }
131
132         state->nt_authority_sid = dom_sid_parse_talloc(state, SID_NT_AUTHORITY);
133         if (!state->nt_authority_sid) {
134                 return NT_STATUS_NO_SUCH_DOMAIN;                
135         }
136
137         state->creator_owner_domain_sid = dom_sid_parse_talloc(state, SID_CREATOR_OWNER_DOMAIN);
138         if (!state->creator_owner_domain_sid) {
139                 return NT_STATUS_NO_SUCH_DOMAIN;                
140         }
141
142         state->world_domain_sid = dom_sid_parse_talloc(state, SID_WORLD_DOMAIN);
143         if (!state->world_domain_sid) {
144                 return NT_STATUS_NO_SUCH_DOMAIN;                
145         }
146
147         *_state = state;
148
149         return NT_STATUS_OK;
150 }
151
152 /* 
153   lsa_OpenPolicy2
154 */
155 NTSTATUS dcesrv_lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
156                                 struct lsa_OpenPolicy2 *r)
157 {
158         NTSTATUS status;
159         struct lsa_policy_state *state;
160         struct dcesrv_handle *handle;
161
162         ZERO_STRUCTP(r->out.handle);
163
164         if (r->in.attr != NULL &&
165             r->in.attr->root_dir != NULL) {
166                 /* MS-LSAD 3.1.4.4.1 */
167                 return NT_STATUS_INVALID_PARAMETER;
168         }
169
170         status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
171         if (!NT_STATUS_IS_OK(status)) {
172                 return status;
173         }
174
175         handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_POLICY);
176         if (!handle) {
177                 return NT_STATUS_NO_MEMORY;
178         }
179
180         handle->data = talloc_steal(handle, state);
181
182         /* need to check the access mask against - need ACLs - fails
183            WSPP test */
184         state->access_mask = r->in.access_mask;
185         state->handle = handle;
186         *r->out.handle = handle->wire_handle;
187
188         /* note that we have completely ignored the attr element of
189            the OpenPolicy. As far as I can tell, this is what w2k3
190            does */
191
192         return NT_STATUS_OK;
193 }
194
195 /* 
196   lsa_OpenPolicy
197   a wrapper around lsa_OpenPolicy2
198 */
199 NTSTATUS dcesrv_lsa_OpenPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
200                                 struct lsa_OpenPolicy *r)
201 {
202         struct lsa_OpenPolicy2 r2;
203
204         r2.in.system_name = NULL;
205         r2.in.attr = r->in.attr;
206         r2.in.access_mask = r->in.access_mask;
207         r2.out.handle = r->out.handle;
208
209         return dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &r2);
210 }
211
212