s4-dsdb: Added a function to check access on a particular object by its guid
[Samba/gebeck_regimport.git] / source4 / dsdb / samdb / ldb_modules / acl_util.c
blob6873e56abda45226cdd73fe52f471e682c9fefc5
1 /*
2 ACL utility functions
4 Copyright (C) Nadezhda Ivanova 2010
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * Name: acl_util
23 * Component: ldb ACL modules
25 * Description: Some auxiliary functions used for access checking
27 * Author: Nadezhda Ivanova
29 #include "includes.h"
30 #include "ldb_module.h"
31 #include "auth/auth.h"
32 #include "libcli/security/security.h"
33 #include "dsdb/samdb/samdb.h"
34 #include "librpc/gen_ndr/ndr_security.h"
35 #include "param/param.h"
36 #include "dsdb/samdb/ldb_modules/util.h"
38 struct security_token *acl_user_token(struct ldb_module *module)
40 struct ldb_context *ldb = ldb_module_get_ctx(module);
41 struct auth_session_info *session_info
42 = (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo");
43 if(!session_info) {
44 return NULL;
46 return session_info->security_token;
49 /* performs an access check from inside the module stack
50 * given the dn of the object to be checked, the required access
51 * guid is either the guid of the extended right, or NULL
54 int dsdb_module_check_access_on_dn(struct ldb_module *module,
55 TALLOC_CTX *mem_ctx,
56 struct ldb_dn *dn,
57 uint32_t access,
58 const struct GUID *guid)
60 int ret;
61 struct ldb_result *acl_res;
62 static const char *acl_attrs[] = {
63 "nTSecurityDescriptor",
64 "objectSid",
65 NULL
67 struct ldb_context *ldb = ldb_module_get_ctx(module);
68 struct auth_session_info *session_info
69 = (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo");
70 if(!session_info) {
71 return ldb_operr(ldb);
73 ret = dsdb_module_search_dn(module, mem_ctx, &acl_res, dn,
74 acl_attrs,
75 DSDB_FLAG_NEXT_MODULE |
76 DSDB_SEARCH_SHOW_DELETED);
77 if (ret != LDB_SUCCESS) {
78 DEBUG(0,("access_check: failed to find object %s\n", ldb_dn_get_linearized(dn)));
79 return ret;
81 return dsdb_check_access_on_dn_internal(ldb, acl_res,
82 mem_ctx,
83 session_info->security_token,
84 dn,
85 access,
86 guid);
89 int dsdb_module_check_access_on_guid(struct ldb_module *module,
90 TALLOC_CTX *mem_ctx,
91 struct GUID *guid,
92 uint32_t access,
93 const struct GUID *oc_guid)
95 int ret;
96 struct ldb_result *acl_res;
97 static const char *acl_attrs[] = {
98 "nTSecurityDescriptor",
99 "objectSid",
100 NULL
102 struct ldb_context *ldb = ldb_module_get_ctx(module);
103 struct auth_session_info *session_info
104 = (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo");
105 if(!session_info) {
106 return ldb_operr(ldb);
108 ret = dsdb_module_search(module, mem_ctx, &acl_res, NULL, LDB_SCOPE_SUBTREE,
109 acl_attrs,
110 DSDB_FLAG_NEXT_MODULE |
111 DSDB_SEARCH_SHOW_DELETED,
112 "objectGUID=%s", GUID_string(mem_ctx, guid));
114 if (ret != LDB_SUCCESS || acl_res->count == 0) {
115 DEBUG(0,("access_check: failed to find object %s\n", GUID_string(mem_ctx, guid)));
116 return ret;
118 return dsdb_check_access_on_dn_internal(ldb, acl_res,
119 mem_ctx,
120 session_info->security_token,
121 acl_res->msgs[0]->dn,
122 access,
123 oc_guid);
126 int acl_check_access_on_attribute(struct ldb_module *module,
127 TALLOC_CTX *mem_ctx,
128 struct security_descriptor *sd,
129 struct dom_sid *rp_sid,
130 uint32_t access,
131 const struct dsdb_attribute *attr)
133 int ret;
134 NTSTATUS status;
135 uint32_t access_granted;
136 struct object_tree *root = NULL;
137 struct object_tree *new_node = NULL;
138 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
139 struct security_token *token = acl_user_token(module);
140 if (attr) {
141 if (!GUID_all_zero(&attr->attributeSecurityGUID)) {
142 if (!insert_in_object_tree(tmp_ctx,
143 &attr->attributeSecurityGUID, access,
144 &root, &new_node)) {
145 DEBUG(10, ("acl_search: cannot add to object tree securityGUID\n"));
146 goto fail;
149 if (!insert_in_object_tree(tmp_ctx,
150 &attr->schemaIDGUID, access, &new_node, &new_node)) {
151 DEBUG(10, ("acl_search: cannot add to object tree attributeGUID\n"));
152 goto fail;
155 else {
156 if (!insert_in_object_tree(tmp_ctx,
157 &attr->schemaIDGUID, access, &root, &new_node)) {
158 DEBUG(10, ("acl_search: cannot add to object tree attributeGUID\n"));
159 goto fail;
163 status = sec_access_check_ds(sd, token,
164 access,
165 &access_granted,
166 root,
167 rp_sid);
168 if (!NT_STATUS_IS_OK(status)) {
169 ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
171 else {
172 ret = LDB_SUCCESS;
174 talloc_free(tmp_ctx);
175 return ret;
176 fail:
177 talloc_free(tmp_ctx);
178 return ldb_operr(ldb_module_get_ctx(module));
181 int acl_check_access_on_class(struct ldb_module *module,
182 const struct dsdb_schema *schema,
183 TALLOC_CTX *mem_ctx,
184 struct security_descriptor *sd,
185 struct dom_sid *rp_sid,
186 uint32_t access,
187 const char *class_name)
189 int ret;
190 NTSTATUS status;
191 uint32_t access_granted;
192 struct object_tree *root = NULL;
193 struct object_tree *new_node = NULL;
194 const struct GUID *guid;
195 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
196 struct security_token *token = acl_user_token(module);
197 if (class_name) {
198 guid = class_schemaid_guid_by_lDAPDisplayName(schema, class_name);
199 if (!guid) {
200 DEBUG(10, ("acl_search: cannot find class %s\n",
201 class_name));
202 goto fail;
204 if (!insert_in_object_tree(tmp_ctx,
205 guid, access,
206 &root, &new_node)) {
207 DEBUG(10, ("acl_search: cannot add to object tree guid\n"));
208 goto fail;
211 status = sec_access_check_ds(sd, token,
212 access,
213 &access_granted,
214 root,
215 rp_sid);
216 if (!NT_STATUS_IS_OK(status)) {
217 ret = LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
219 else {
220 ret = LDB_SUCCESS;
222 return ret;
223 fail:
224 return ldb_operr(ldb_module_get_ctx(module));
227 const struct GUID *get_oc_guid_from_message(struct ldb_module *module,
228 const struct dsdb_schema *schema,
229 struct ldb_message *msg)
231 struct ldb_message_element *oc_el;
233 oc_el = ldb_msg_find_element(msg, "objectClass");
234 if (!oc_el) {
235 return NULL;
238 return class_schemaid_guid_by_lDAPDisplayName(schema,
239 (char *)oc_el->values[oc_el->num_values-1].data);
243 /* checks for validated writes */
244 int acl_check_extended_right(TALLOC_CTX *mem_ctx,
245 struct security_descriptor *sd,
246 struct security_token *token,
247 const char *ext_right,
248 uint32_t right_type,
249 struct dom_sid *sid)
251 struct GUID right;
252 NTSTATUS status;
253 uint32_t access_granted;
254 struct object_tree *root = NULL;
255 struct object_tree *new_node = NULL;
256 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
258 GUID_from_string(ext_right, &right);
260 if (!insert_in_object_tree(tmp_ctx, &right, right_type,
261 &root, &new_node)) {
262 DEBUG(10, ("acl_ext_right: cannot add to object tree\n"));
263 talloc_free(tmp_ctx);
264 return LDB_ERR_OPERATIONS_ERROR;
266 status = sec_access_check_ds(sd, token,
267 right_type,
268 &access_granted,
269 root,
270 sid);
272 if (!NT_STATUS_IS_OK(status)) {
273 talloc_free(tmp_ctx);
274 return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
276 talloc_free(tmp_ctx);
277 return LDB_SUCCESS;
280 const char *acl_user_name(TALLOC_CTX *mem_ctx, struct ldb_module *module)
282 struct ldb_context *ldb = ldb_module_get_ctx(module);
283 struct auth_session_info *session_info
284 = (struct auth_session_info *)ldb_get_opaque(ldb, "sessionInfo");
285 if (!session_info) {
286 return "UNKNOWN (NULL)";
289 return talloc_asprintf(mem_ctx, "%s\\%s",
290 session_info->server_info->domain_name,
291 session_info->server_info->account_name);