1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
|
From 5beb93d42efb807838c09c5fab898876876f8d09 Mon Sep 17 00:00:00 2001
From: Noriko Hosoi <nhosoi@totoro.usersys.redhat.com>
Date: Fri, 21 Sep 2012 19:35:18 +0000
Subject: Trac Ticket #340 - Change on SLAPI_MODRDN_NEWSUPERIOR is not
evaluated in acl
https://fedorahosted.org/389/ticket/340
Bug Description: When modrdn operation was executed, only newrdn
change was passed to the acl plugin. Also, the change was used
only for the acl search, but not for the acl target in the items
in the acl cache.
Fix Description: This patch also passes the newsuperior update
to the acl plugin. And the modrdn updates are applied to the
acl target in the acl cache.
---
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
index 15e474e..3389404 100644
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -170,9 +170,9 @@ acl_access_allowed_modrdn(
* Test if have access to make the first rdn of dn in entry e.
*/
-static int check_rdn_access( Slapi_PBlock *pb, Slapi_Entry *e, const char *dn,
- int access) {
-
+static int
+check_rdn_access( Slapi_PBlock *pb, Slapi_Entry *e, const char *dn, int access)
+{
char **dns;
char **rdns;
int retCode = LDAP_INSUFFICIENT_ACCESS;
@@ -655,7 +655,8 @@ cleanup_and_ret:
}
-static void print_access_control_summary( char *source, int ret_val, char *clientDn,
+static void
+print_access_control_summary( char *source, int ret_val, char *clientDn,
struct acl_pblock *aclpb,
char *right,
char *attr,
@@ -1524,11 +1525,12 @@ acl_check_mods(
*
**************************************************************************/
extern void
-acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
+acl_modified (Slapi_PBlock *pb, int optype, Slapi_DN *e_sdn, void *change)
{
struct berval **bvalue;
char **value;
int rv=0; /* returned value */
+ const char* n_dn;
char* new_RDN;
char* parent_DN;
char* new_DN;
@@ -1537,10 +1539,12 @@ acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
int j;
Slapi_Attr *attr = NULL;
Slapi_Entry *e = NULL;
- Slapi_DN *e_sdn;
aclUserGroup *ugroup = NULL;
- e_sdn = slapi_sdn_new_normdn_byval ( n_dn );
+ if (NULL == e_sdn) {
+ return;
+ }
+ n_dn = slapi_sdn_get_dn(e_sdn);
/* Before we proceed, Let's first check if we are changing any groups.
** If we are, then we need to change the signature
*/
@@ -1768,45 +1772,64 @@ acl_modified (Slapi_PBlock *pb, int optype, char *n_dn, void *change)
}
break;
- }/* case op is modify*/
+ }/* case op is modify*/
- case SLAPI_OPERATION_MODRDN:
-
- new_RDN = (char*) change;
- slapi_log_error (SLAPI_LOG_ACL, plugin_name,
- "acl_modified (MODRDN %s => \"%s\"\n",
- n_dn, new_RDN);
+ case SLAPI_OPERATION_MODRDN:
+ {
+ char **rdn_parent;
+ rdn_parent = (char **)change;
+ new_RDN = rdn_parent[0];
+ parent_DN = rdn_parent[1];
/* compute new_DN: */
- parent_DN = slapi_dn_parent (n_dn);
- if (parent_DN == NULL) {
- new_DN = new_RDN;
+ if (NULL == parent_DN) {
+ parent_DN = slapi_dn_parent(n_dn);
+ }
+ if (NULL == parent_DN) {
+ if (NULL == new_RDN) {
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acl_modified (MODRDN %s => \"no change\"\n",
+ n_dn);
+ break;
+ } else {
+ new_DN = new_RDN;
+ }
} else {
- new_DN = slapi_create_dn_string("%s,%s", new_RDN, parent_DN);
+ if (NULL == new_RDN) {
+ Slapi_RDN *rdn= slapi_rdn_new();
+ slapi_sdn_get_rdn(e_sdn, rdn);
+ new_DN = slapi_create_dn_string("%s,%s", slapi_rdn_get_rdn(rdn),
+ parent_DN);
+ slapi_rdn_free(&rdn);
+ } else {
+ new_DN = slapi_create_dn_string("%s,%s", new_RDN, parent_DN);
+ }
}
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "acl_modified (MODRDN %s => \"%s\"\n", n_dn, new_RDN);
/* Change the acls */
- acllist_acicache_WRITE_LOCK();
+ acllist_acicache_WRITE_LOCK();
/* acllist_moddn_aci_needsLock expects normalized new_DN,
* which is no need to be case-ignored */
acllist_moddn_aci_needsLock ( e_sdn, new_DN );
acllist_acicache_WRITE_UNLOCK();
/* deallocat the parent_DN */
- if (parent_DN != NULL) {
- slapi_ch_free ( (void **) &new_DN );
- slapi_ch_free ( (void **) &parent_DN );
+ if (parent_DN != NULL) {
+ slapi_ch_free_string(&new_DN);
+ if (parent_DN != rdn_parent[1]) {
+ slapi_ch_free_string(&parent_DN);
+ }
}
break;
-
- default:
+ } /* case op is modrdn */
+ default:
/* print ERROR */
break;
} /*optype switch */
-
- slapi_sdn_free ( &e_sdn );
-
}
+
/***************************************************************************
*
* acl__scan_for_acis
diff --git a/ldap/servers/plugins/acl/acl.h b/ldap/servers/plugins/acl/acl.h
index 4fa3e3f..28c38e7 100644
--- a/ldap/servers/plugins/acl/acl.h
+++ b/ldap/servers/plugins/acl/acl.h
@@ -796,7 +796,8 @@ int acl_read_access_allowed_on_attr ( Slapi_PBlock *pb, Slapi_Entry *e, char
struct berval *val, int access);
void acl_set_acllist (Slapi_PBlock *pb, int scope, char *base);
void acl_gen_err_msg(int access, char *edn, char *attr, char **errbuf);
-void acl_modified ( Slapi_PBlock *pb, int optype, char *dn, void *change);
+void acl_modified (Slapi_PBlock *pb, int optype, Slapi_DN *e_sdn, void *change);
+
int acl_access_allowed_disjoint_resource( Slapi_PBlock *pb, Slapi_Entry *e,
char *attr, struct berval *val, int access );
int acl_access_allowed_main ( Slapi_PBlock *pb, Slapi_Entry *e, char **attrs,
@@ -866,7 +867,7 @@ void acllist_print_tree ( Avlnode *root, int *depth, char *start, char *side);
AciContainer *acllist_get_aciContainer_new ( );
void acllist_done_aciContainer ( AciContainer *);
-aclUserGroup* aclg_find_userGroup (char *n_dn);
+aclUserGroup* aclg_find_userGroup (const char *n_dn);
void aclg_regen_ugroup_signature( aclUserGroup *ugroup);
void aclg_markUgroupForRemoval ( aclUserGroup *u_group );
void aclg_reader_incr_ugroup_refcnt(aclUserGroup* u_group);
diff --git a/ldap/servers/plugins/acl/aclgroup.c b/ldap/servers/plugins/acl/aclgroup.c
index c694293..2231304 100644
--- a/ldap/servers/plugins/acl/aclgroup.c
+++ b/ldap/servers/plugins/acl/aclgroup.c
@@ -213,7 +213,7 @@ aclg_reset_userGroup ( struct acl_pblock *aclpb )
*/
aclUserGroup*
-aclg_find_userGroup(char *n_dn)
+aclg_find_userGroup(const char *n_dn)
{
aclUserGroup *u_group = NULL;
int i;
diff --git a/ldap/servers/plugins/acl/acllist.c b/ldap/servers/plugins/acl/acllist.c
index 9b5363a..e8198af 100644
--- a/ldap/servers/plugins/acl/acllist.c
+++ b/ldap/servers/plugins/acl/acllist.c
@@ -600,7 +600,6 @@ void
acllist_init_scan (Slapi_PBlock *pb, int scope, const char *base)
{
Acl_PBlock *aclpb;
- int i;
AciContainer *root;
char *basedn = NULL;
int index;
@@ -671,11 +670,6 @@ acllist_init_scan (Slapi_PBlock *pb, int scope, const char *base)
aclpb->aclpb_state &= ~ACLPB_SEARCH_BASED_ON_LIST ;
acllist_acicache_READ_UNLOCK();
-
- i = 0;
- while ( i < aclpb_max_selected_acls && aclpb->aclpb_base_handles_index[i] != -1 ) {
- i++;
- }
}
/*
@@ -893,34 +887,50 @@ acllist_acicache_WRITE_LOCK( )
int
acllist_moddn_aci_needsLock ( Slapi_DN *oldsdn, char *newdn )
{
-
-
AciContainer *aciListHead;
AciContainer *head;
+ aci_t *acip;
+ const char *oldndn;
/* first get the container */
aciListHead = acllist_get_aciContainer_new ( );
slapi_sdn_free(&aciListHead->acic_sdn);
- aciListHead->acic_sdn = oldsdn;
-
+ aciListHead->acic_sdn = oldsdn;
if ( NULL == (head = (AciContainer *) avl_find( acllistRoot, aciListHead,
- (IFP) __acllist_aciContainer_node_cmp ) ) ) {
+ (IFP) __acllist_aciContainer_node_cmp ) ) ) {
slapi_log_error ( SLAPI_PLUGIN_ACL, plugin_name,
- "Can't find the acl in the tree for moddn operation:olddn%s\n",
- slapi_sdn_get_ndn ( oldsdn ));
+ "Can't find the acl in the tree for moddn operation:olddn%s\n",
+ slapi_sdn_get_ndn ( oldsdn ));
aciListHead->acic_sdn = NULL;
__acllist_free_aciContainer ( &aciListHead );
- return 1;
+ return 1;
}
-
- /* Now set the new DN */
- slapi_sdn_done ( head->acic_sdn );
- slapi_sdn_set_normdn_byval ( head->acic_sdn, newdn );
-
+ /* Now set the new DN */
+ slapi_sdn_set_normdn_byval(head->acic_sdn, newdn);
+
+ /* If necessary, reset the target DNs, as well. */
+ oldndn = slapi_sdn_get_ndn(oldsdn);
+ for (acip = head->acic_list; acip; acip = acip->aci_next) {
+ const char *ndn = slapi_sdn_get_ndn(acip->aci_sdn);
+ char *p = PL_strstr(ndn, oldndn);
+ if (p) {
+ if (p == ndn) {
+ /* target dn is identical, replace it with new DN*/
+ slapi_sdn_set_normdn_byval(acip->aci_sdn, newdn);
+ } else {
+ /* target dn is a descendent of olddn, merge it with new DN*/
+ char *mynewdn;
+ *p = '\0';
+ mynewdn = slapi_ch_smprintf("%s%s", ndn, newdn);
+ slapi_sdn_set_normdn_passin(acip->aci_sdn, mynewdn);
+ }
+ }
+ }
+
aciListHead->acic_sdn = NULL;
__acllist_free_aciContainer ( &aciListHead );
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
index 11e56a9..b79d0f2 100644
--- a/ldap/servers/slapd/dn.c
+++ b/ldap/servers/slapd/dn.c
@@ -2097,7 +2097,7 @@ slapi_sdn_set_normdn_byval(Slapi_DN *sdn, const char *normdn)
slapi_sdn_done(sdn);
sdn->flag = slapi_setbit_uchar(sdn->flag, FLAG_DN);
if(normdn == NULL) {
- sdn->dn = slapi_ch_strdup(normdn);
+ sdn->dn = NULL;
sdn->ndn_len = 0;
} else {
sdn->dn = slapi_ch_strdup(normdn);
diff --git a/ldap/servers/slapd/plugin_acl.c b/ldap/servers/slapd/plugin_acl.c
index b878156..3bc3f21 100644
--- a/ldap/servers/slapd/plugin_acl.c
+++ b/ldap/servers/slapd/plugin_acl.c
@@ -134,11 +134,10 @@ int
plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
{
struct slapdplugin *p;
- char *dn;
int rc = 0;
- void *change = NULL;
- Slapi_Entry *te = NULL;
- Slapi_DN *sdn = NULL;
+ void *change = NULL;
+ Slapi_Entry *te = NULL;
+ Slapi_DN *sdn = NULL;
Operation *operation;
slapi_pblock_get (pb, SLAPI_OPERATION, &operation);
@@ -146,7 +145,7 @@ plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
(void)slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
switch ( optype ) {
- case SLAPI_OPERATION_MODIFY:
+ case SLAPI_OPERATION_MODIFY:
(void)slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &change );
break;
case SLAPI_OPERATION_ADD:
@@ -158,11 +157,27 @@ plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
}
break;
case SLAPI_OPERATION_MODRDN:
+ {
+ void *mychange[2];
+ char *newrdn = NULL;
+ Slapi_DN *psdn = NULL;
+ char *pdn = NULL;
+
/* newrdn: "change" is normalized but not case-ignored */
/* The acl plugin expects normalized newrdn, but no need to be case-
* ignored. */
- (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &change );
+ (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &newrdn );
+ (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &psdn );
+ if (psdn) {
+ pdn = (char *)slapi_sdn_get_dn(psdn);
+ } else {
+ (void)slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR, &pdn );
+ }
+ mychange[0] = newrdn;
+ mychange[1] = pdn;
+ change = mychange;
break;
+ }
}
if (NULL == sdn) {
@@ -172,10 +187,9 @@ plugin_call_acl_mods_update ( Slapi_PBlock *pb, int optype )
}
/* call the global plugins first and then the backend specific */
- dn = (char*)slapi_sdn_get_ndn(sdn); /* jcm - Had to cast away const */
for ( p = get_plugin_list(PLUGIN_LIST_ACL); p != NULL; p = p->plg_next ) {
if (plugin_invoke_plugin_sdn(p, SLAPI_PLUGIN_ACL_MODS_UPDATE, pb, sdn)){
- rc = (*p->plg_acl_mods_update)(pb, optype, dn, change );
+ rc = (*p->plg_acl_mods_update)(pb, optype, sdn, change );
if ( rc != LDAP_SUCCESS ) break;
}
}
--
cgit v0.9.0.2
|