Line data Source code
1 : /*
2 : ldb database library
3 :
4 : Copyright (C) Simo Sorce 2004-2008
5 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
6 : Copyright (C) Andrew Tridgell 2005
7 : Copyright (C) Stefan Metzmacher <metze@samba.org> 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 : /*
24 : * Name: ldb
25 : *
26 : * Component: ldb instancetype module
27 : *
28 : * Description: add an instanceType onto every new record
29 : *
30 : * Author: Andrew Bartlett
31 : */
32 :
33 : #include "includes.h"
34 : #include "ldb.h"
35 : #include "ldb_module.h"
36 : #include "librpc/gen_ndr/ndr_misc.h"
37 : #include "dsdb/samdb/samdb.h"
38 : #include "../libds/common/flags.h"
39 : #include "dsdb/samdb/ldb_modules/util.h"
40 :
41 : /* add_record: add instancetype attribute */
42 543049 : static int instancetype_add(struct ldb_module *module, struct ldb_request *req)
43 : {
44 543049 : struct ldb_context *ldb = ldb_module_get_ctx(module);
45 83679 : struct ldb_request *down_req;
46 83679 : struct ldb_message *msg;
47 83679 : struct ldb_message_element *el;
48 83679 : uint32_t instanceType;
49 83679 : int ret;
50 :
51 : /* do not manipulate our control entries */
52 543049 : if (ldb_dn_is_special(req->op.add.message->dn)) {
53 538 : return ldb_next_request(module, req);
54 : }
55 :
56 542511 : ldb_debug(ldb, LDB_DEBUG_TRACE, "instancetype_add\n");
57 :
58 542511 : el = ldb_msg_find_element(req->op.add.message, "instanceType");
59 542511 : if (el != NULL) {
60 1714 : if (el->num_values != 1) {
61 0 : ldb_set_errstring(ldb, "instancetype: the 'instanceType' attribute is single-valued!");
62 0 : return LDB_ERR_UNWILLING_TO_PERFORM;
63 : }
64 :
65 1714 : instanceType = ldb_msg_find_attr_as_uint(req->op.add.message,
66 : "instanceType", 0);
67 1714 : if (!(instanceType & INSTANCE_TYPE_IS_NC_HEAD)) {
68 : /*
69 : * If we have no NC add operation (no TYPE_IS_NC_HEAD)
70 : * then "instanceType" can only be "0" or "TYPE_WRITE".
71 : */
72 1103 : if ((instanceType != 0) &&
73 1103 : ((instanceType & INSTANCE_TYPE_WRITE) == 0)) {
74 1 : ldb_set_errstring(ldb, "instancetype: if TYPE_IS_NC_HEAD wasn't set, then only TYPE_WRITE or 0 are allowed!");
75 1 : return LDB_ERR_UNWILLING_TO_PERFORM;
76 : }
77 : } else {
78 : /*
79 : * If we have a NC add operation then we need also the
80 : * "TYPE_WRITE" flag in order to succeed,
81 : * unless this NC is not instantiated
82 : */
83 611 : if (ldb_request_get_control(req, DSDB_CONTROL_PARTIAL_REPLICA)) {
84 0 : if (!(instanceType & INSTANCE_TYPE_UNINSTANT)) {
85 0 : ldb_set_errstring(ldb, "instancetype: if TYPE_IS_NC_HEAD "
86 : "was set, and we are creating a new NC "
87 : "over DsAddEntry then also TYPE_UNINSTANT is requested!");
88 0 : return LDB_ERR_UNWILLING_TO_PERFORM;
89 : }
90 : } else {
91 611 : if (!(instanceType & INSTANCE_TYPE_WRITE)) {
92 2 : ldb_set_errstring(ldb, "instancetype: if TYPE_IS_NC_HEAD "
93 : "was set, then also TYPE_WRITE is requested!");
94 2 : return LDB_ERR_UNWILLING_TO_PERFORM;
95 : }
96 : }
97 :
98 : /*
99 : * TODO: Confirm we are naming master or start
100 : * a remote call to the naming master to
101 : * create the crossRef object
102 : */
103 : }
104 :
105 : /* we did only tests, so proceed with the original request */
106 1711 : return ldb_next_request(module, req);
107 : }
108 :
109 : /* we have to copy the message as the caller might have it as a const */
110 540797 : msg = ldb_msg_copy_shallow(req, req->op.add.message);
111 540797 : if (msg == NULL) {
112 0 : return ldb_oom(ldb);
113 : }
114 :
115 : /*
116 : * TODO: calculate correct instance type
117 : */
118 540797 : instanceType = INSTANCE_TYPE_WRITE;
119 :
120 540797 : ret = samdb_msg_add_uint(ldb, msg, msg, "instanceType", instanceType);
121 540797 : if (ret != LDB_SUCCESS) {
122 0 : return ret;
123 : }
124 :
125 540797 : ret = ldb_build_add_req(&down_req, ldb, req,
126 : msg,
127 : req->controls,
128 : req, dsdb_next_callback,
129 : req);
130 540797 : LDB_REQ_SET_LOCATION(down_req);
131 540797 : if (ret != LDB_SUCCESS) {
132 0 : return ret;
133 : }
134 :
135 : /* go on with the call chain */
136 540797 : return ldb_next_request(module, down_req);
137 : }
138 :
139 : /* deny instancetype modification */
140 642719 : static int instancetype_mod(struct ldb_module *module, struct ldb_request *req)
141 : {
142 642719 : struct ldb_context *ldb = ldb_module_get_ctx(module);
143 27627 : struct ldb_message_element *el;
144 :
145 : /* do not manipulate our control entries */
146 642719 : if (ldb_dn_is_special(req->op.mod.message->dn)) {
147 715 : return ldb_next_request(module, req);
148 : }
149 :
150 642004 : ldb_debug(ldb, LDB_DEBUG_TRACE, "instancetype_mod\n");
151 :
152 642004 : el = ldb_msg_find_element(req->op.mod.message, "instanceType");
153 642004 : if (el != NULL) {
154 : /* Except to allow dbcheck to fix things, this must never be modified */
155 3 : if (!ldb_request_get_control(req, DSDB_CONTROL_DBCHECK)) {
156 3 : ldb_set_errstring(ldb, "instancetype: the 'instanceType' attribute can never be changed!");
157 3 : return LDB_ERR_CONSTRAINT_VIOLATION;
158 : }
159 : }
160 642001 : return ldb_next_request(module, req);
161 : }
162 :
163 : static const struct ldb_module_ops ldb_instancetype_module_ops = {
164 : .name = "instancetype",
165 : .add = instancetype_add,
166 : .modify = instancetype_mod
167 : };
168 :
169 6040 : int ldb_instancetype_module_init(const char *version)
170 : {
171 6040 : LDB_MODULE_CHECK_VERSION(version);
172 6040 : return ldb_register_module(&ldb_instancetype_module_ops);
173 : }
|