Line data Source code
1 : /*
2 : samba3sid module
3 :
4 : Copyright (C) Andrew Bartlett 2010
5 : Copyright (C) Andrew Tridgell 2010
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : /*
22 : add objectSid to users and groups using samba3 nextRid method
23 : */
24 :
25 : #include "includes.h"
26 : #include "libcli/ldap/ldap_ndr.h"
27 : #include "ldb_module.h"
28 : #include "dsdb/samdb/samdb.h"
29 : #include "dsdb/samdb/ldb_modules/util.h"
30 : #include "libcli/security/security.h"
31 : #include "librpc/gen_ndr/ndr_security.h"
32 : #include "ldb_wrap.h"
33 : #include "param/param.h"
34 :
35 : /*
36 : RID algorithm from pdb_ldap.c in source3/passdb/
37 : (loosely based on Volkers code)
38 : */
39 1 : static int samba3sid_next_sid(struct ldb_module *module,
40 : TALLOC_CTX *mem_ctx, char **sid,
41 : struct ldb_request *parent)
42 : {
43 1 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
44 1 : struct ldb_result *res;
45 1 : const char *attrs[] = { "sambaNextRid", "sambaNextUserRid",
46 : "sambaNextGroupRid", "sambaSID", NULL };
47 1 : int ret;
48 1 : struct ldb_context *ldb = ldb_module_get_ctx(module);
49 1 : struct ldb_message *msg;
50 1 : uint32_t sambaNextRid, sambaNextGroupRid, sambaNextUserRid, rid;
51 1 : const char *sambaSID;
52 :
53 1 : ret = dsdb_module_search(module, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE,
54 : attrs,
55 : DSDB_FLAG_NEXT_MODULE |
56 : DSDB_SEARCH_SEARCH_ALL_PARTITIONS,
57 : parent,
58 : "(&(objectClass=sambaDomain)(sambaDomainName=%s))",
59 1 : lpcfg_sam_name(ldb_get_opaque(ldb, "loadparm")));
60 1 : if (ret != LDB_SUCCESS) {
61 0 : ldb_asprintf_errstring(ldb,
62 : __location__
63 : ": Failed to find domain object - %s",
64 : ldb_errstring(ldb));
65 0 : talloc_free(tmp_ctx);
66 0 : return ret;
67 : }
68 1 : if (res->count != 1) {
69 0 : ldb_asprintf_errstring(ldb,
70 : __location__
71 : ": Expected exactly 1 domain object - got %u",
72 0 : res->count);
73 0 : talloc_free(tmp_ctx);
74 0 : return LDB_ERR_OPERATIONS_ERROR;
75 : }
76 1 : msg = res->msgs[0];
77 :
78 1 : sambaNextRid = ldb_msg_find_attr_as_uint(msg, "sambaNextRid",
79 : (uint32_t) -1);
80 1 : sambaNextUserRid = ldb_msg_find_attr_as_uint(msg, "sambaNextUserRid",
81 : (uint32_t) -1);
82 1 : sambaNextGroupRid = ldb_msg_find_attr_as_uint(msg, "sambaNextGroupRid",
83 : (uint32_t) -1);
84 1 : sambaSID = ldb_msg_find_attr_as_string(msg, "sambaSID", NULL);
85 :
86 1 : if (sambaSID == NULL) {
87 0 : ldb_asprintf_errstring(ldb,
88 : __location__
89 : ": No sambaSID in %s",
90 : ldb_dn_get_linearized(msg->dn));
91 0 : talloc_free(tmp_ctx);
92 0 : return LDB_ERR_OPERATIONS_ERROR;
93 : }
94 :
95 : /* choose the highest of the 3 - see pdb_ldap.c for an
96 : * explanation */
97 1 : rid = sambaNextRid;
98 1 : if ((sambaNextUserRid != (uint32_t) -1) && (sambaNextUserRid > rid)) {
99 0 : rid = sambaNextUserRid;
100 : }
101 1 : if ((sambaNextGroupRid != (uint32_t) -1) && (sambaNextGroupRid > rid)) {
102 0 : rid = sambaNextGroupRid;
103 : }
104 1 : if (rid == (uint32_t) -1) {
105 0 : ldb_asprintf_errstring(ldb,
106 : __location__
107 : ": No sambaNextRid in %s",
108 : ldb_dn_get_linearized(msg->dn));
109 0 : talloc_free(tmp_ctx);
110 0 : return LDB_ERR_OPERATIONS_ERROR;
111 : }
112 :
113 : /* sambaNextRid is actually the previous RID .... */
114 1 : rid += 1;
115 :
116 1 : (*sid) = talloc_asprintf(tmp_ctx, "%s-%u", sambaSID, rid);
117 1 : if (!*sid) {
118 0 : talloc_free(tmp_ctx);
119 0 : return ldb_module_oom(module);
120 : }
121 :
122 1 : ret = dsdb_module_constrainted_update_uint32(module, msg->dn,
123 : "sambaNextRid",
124 : &sambaNextRid, &rid, parent);
125 1 : if (ret != LDB_SUCCESS) {
126 0 : ldb_asprintf_errstring(ldb,
127 : __location__
128 : ": Failed to update sambaNextRid - %s",
129 : ldb_errstring(ldb));
130 0 : talloc_free(tmp_ctx);
131 0 : return ret;
132 : }
133 :
134 1 : talloc_steal(mem_ctx, *sid);
135 1 : talloc_free(tmp_ctx);
136 1 : return LDB_SUCCESS;
137 : }
138 :
139 :
140 :
141 : /* add */
142 16 : static int samba3sid_add(struct ldb_module *module, struct ldb_request *req)
143 : {
144 16 : struct ldb_context *ldb;
145 16 : int ret;
146 16 : const struct ldb_message *msg = req->op.add.message;
147 16 : struct ldb_message *new_msg;
148 16 : char *sid;
149 16 : struct ldb_request *new_req;
150 :
151 16 : ldb = ldb_module_get_ctx(module);
152 :
153 : /* do not manipulate our control entries */
154 16 : if (ldb_dn_is_special(req->op.add.message->dn)) {
155 0 : return ldb_next_request(module, req);
156 : }
157 :
158 30 : if (!samdb_find_attribute(ldb, msg, "objectclass", "posixAccount") &&
159 14 : !samdb_find_attribute(ldb, msg, "objectclass", "posixGroup")) {
160 : /* its not a user or a group */
161 13 : return ldb_next_request(module, req);
162 : }
163 :
164 3 : if (ldb_msg_find_element(msg, "sambaSID")) {
165 : /* a SID was supplied */
166 2 : return ldb_next_request(module, req);
167 : }
168 :
169 1 : new_msg = ldb_msg_copy_shallow(req, req->op.add.message);
170 1 : if (!new_msg) {
171 0 : return ldb_module_oom(module);
172 : }
173 :
174 1 : ret = samba3sid_next_sid(module, new_msg, &sid, req);
175 1 : if (ret != LDB_SUCCESS) {
176 0 : return ret;
177 : }
178 :
179 1 : ret = ldb_msg_add_steal_string(new_msg, "sambaSID", sid);
180 1 : if (ret != LDB_SUCCESS) {
181 0 : return ret;
182 : }
183 :
184 1 : ret = ldb_build_add_req(&new_req, ldb, req,
185 : new_msg,
186 : req->controls,
187 : req, dsdb_next_callback,
188 : req);
189 1 : LDB_REQ_SET_LOCATION(new_req);
190 1 : if (ret != LDB_SUCCESS) {
191 0 : return ret;
192 : }
193 :
194 1 : return ldb_next_request(module, new_req);
195 : }
196 :
197 : static const struct ldb_module_ops ldb_samba3sid_module_ops = {
198 : .name = "samba3sid",
199 : .add = samba3sid_add,
200 : };
201 :
202 :
203 6040 : int ldb_samba3sid_module_init(const char *version)
204 : {
205 6040 : LDB_MODULE_CHECK_VERSION(version);
206 6040 : return ldb_register_module(&ldb_samba3sid_module_ops);
207 : }
|