~ubuntu-branches/ubuntu/raring/389-ds-base/raring

« back to all changes in this revision

Viewing changes to ldap/servers/plugins/posix-winsync/posix-group-func.c

  • Committer: Package Import Robot
  • Author(s): Timo Aaltonen
  • Date: 2013-02-06 18:06:31 UTC
  • mfrom: (11.1.1 raring-proposed)
  • Revision ID: package-import@ubuntu.com-20130206180631-h6ldv3k506hmm46e
Tags: 1.3.0.2-0ubuntu2
debian/*: Fix time stamps due to clock skew (FTBFS).

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 $Id: posix-group-func.c 28 2011-05-13 14:35:29Z grzemba $
19
19
 */
20
20
#include "slapi-plugin.h"
 
21
#include "slapi-private.h"
21
22
 
22
23
#include <string.h>
23
24
#include <nspr.h>
24
25
#include "posix-wsp-ident.h"
25
26
 
 
27
#define MAX_RECURSION_DEPTH (5)
 
28
 
26
29
Slapi_Value **
27
30
valueset_get_valuearray(const Slapi_ValueSet *vs); /* stolen from proto-slap.h */
 
31
static int hasObjectClass(Slapi_Entry *entry, const char *objectClass);
 
32
 
28
33
static PRMonitor *memberuid_operation_lock = 0;
29
34
 
30
35
void
45
50
    return (memberuid_operation_lock = PR_NewMonitor()) != NULL;
46
51
}
47
52
 
 
53
void
 
54
addDynamicGroupIfNecessary(Slapi_Entry *entry, Slapi_Mods *smods) {
 
55
    Slapi_Attr *oc_attr = NULL;
 
56
    Slapi_Value *voc = slapi_value_new();
 
57
 
 
58
    slapi_value_init_string(voc, "dynamicGroup");
 
59
    slapi_entry_attr_find(entry, "objectClass", &oc_attr);
 
60
 
 
61
    if (slapi_attr_value_find(oc_attr, slapi_value_get_berval(voc)) != 0) {
 
62
        if (smods) {
 
63
            slapi_mods_add_string(smods, LDAP_MOD_ADD, "objectClass", "dynamicGroup");
 
64
        }
 
65
        else {
 
66
            smods = slapi_mods_new();
 
67
            slapi_mods_add_string(smods, LDAP_MOD_ADD, "objectClass", "dynamicGroup");
 
68
 
 
69
            Slapi_PBlock *mod_pb = slapi_pblock_new();
 
70
            slapi_modify_internal_set_pb_ext(mod_pb, slapi_entry_get_sdn(entry), slapi_mods_get_ldapmods_passout(smods), 0, 0,
 
71
                                             posix_winsync_get_plugin_identity(), 0);
 
72
            slapi_modify_internal_pb(mod_pb);
 
73
            slapi_pblock_destroy(mod_pb);
 
74
 
 
75
            slapi_mods_free(&smods);
 
76
        }
 
77
    }
 
78
 
 
79
    slapi_value_free(&voc);
 
80
}
 
81
 
 
82
Slapi_Entry *
 
83
getEntry(const char *udn, char **attrs)
 
84
{
 
85
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "getEntry: search %s\n", udn);
 
86
 
 
87
    Slapi_DN *udn_sdn = slapi_sdn_new_dn_byval(udn);
 
88
    Slapi_Entry *result = NULL;
 
89
    int rc = slapi_search_internal_get_entry(udn_sdn, attrs, &result, posix_winsync_get_plugin_identity());
 
90
    slapi_sdn_free(&udn_sdn);
 
91
 
 
92
    if (rc == 0) {
 
93
        if (result != NULL) {
 
94
            return result; /* Must be freed */
 
95
        }
 
96
        else {
 
97
            slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
98
                            "getEntry: %s not found\n", udn);
 
99
        }
 
100
    }
 
101
    else {
 
102
        slapi_log_error(SLAPI_LOG_FATAL, POSIX_WINSYNC_PLUGIN_NAME,
 
103
                        "getEntry: error searching for uid: %d", rc);
 
104
    }
 
105
 
 
106
    return NULL;
 
107
}
 
108
 
48
109
/* search the user with DN udn and returns uid*/
49
110
char *
50
111
searchUid(const char *udn)
51
112
{
52
 
    Slapi_PBlock *int_search_pb = slapi_pblock_new();
53
 
    Slapi_Entry **entries = NULL;
54
 
    char *attrs[] = { "uid", NULL };
 
113
    char *attrs[] = { "uid", "objectclass", NULL };
 
114
    Slapi_Entry *entry = getEntry(udn,
 
115
                                  /* "(|(objectclass=posixAccount)(objectclass=ldapsubentry))", */
 
116
                                  attrs);
55
117
    char *uid = NULL;
56
118
 
57
 
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "search Uid: search %s\n", udn);
58
 
 
59
 
    slapi_search_internal_set_pb(int_search_pb, udn, LDAP_SCOPE_BASE,
60
 
                                 "(|(objectclass=posixAccount)(objectclass=ldapsubentry))", attrs,
61
 
                                 0 /* attrsonly */, NULL /* controls */, NULL /* uniqueid */,
62
 
                                 posix_winsync_get_plugin_identity(), 0 /* actions */);
63
 
    if (slapi_search_internal_pb(int_search_pb)) {
64
 
        /* get result and log an error */
65
 
        int res = 0;
66
 
        slapi_pblock_get(int_search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res);
67
 
        slapi_log_error(SLAPI_LOG_FATAL, POSIX_WINSYNC_PLUGIN_NAME,
68
 
                        "searchUid: error searching for uid: %d", res);
69
 
    } else {
70
 
        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "searchUid: searched %s\n",
71
 
                        udn);
72
 
        slapi_pblock_get(int_search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
73
 
        if (NULL != entries && NULL != entries[0]) {
74
 
            Slapi_Attr *attr = NULL;
75
 
            Slapi_Value *v = NULL;
76
 
 
77
 
            if (slapi_entry_attr_find(entries[0], "uid", &attr) == 0) {
78
 
                slapi_attr_first_value(attr, &v);
79
 
                uid = slapi_ch_strdup(slapi_value_get_string(v));
80
 
                slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
81
 
                                "searchUid: return uid %s\n", uid);
82
 
                /* slapi_value_free(&v); */
83
 
            } else {
84
 
                slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
85
 
                                "searchUid: uid in %s not found\n", udn);
86
 
            }
87
 
            slapi_free_search_results_internal(int_search_pb);
88
 
            slapi_pblock_destroy(int_search_pb);
89
 
            if (uid && posix_winsync_config_get_lowercase()) {
90
 
                return slapi_dn_ignore_case(uid);
91
 
            }
92
 
            return uid;
93
 
        }
 
119
    if (entry) {
 
120
        Slapi_Attr *attr = NULL;
 
121
        Slapi_Value *v = NULL;
 
122
 
 
123
        if (slapi_entry_attr_find(entry, "uid", &attr) == 0 && hasObjectClass(entry, "posixAccount")) {
 
124
            slapi_attr_first_value(attr, &v);
 
125
            uid = slapi_ch_strdup(slapi_value_get_string(v));
 
126
            slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
127
                            "searchUid: return uid %s\n", uid);
 
128
        } else {
 
129
            slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
130
                            "searchUid: uid in %s not found\n", udn);
 
131
        }
 
132
 
 
133
        if (uid && posix_winsync_config_get_lowercase()) {
 
134
            uid = slapi_dn_ignore_case(uid);
 
135
        }
 
136
 
 
137
        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
138
                        "searchUid: About to free entry (%s)\n", udn);
 
139
        
 
140
        slapi_entry_free(entry);
94
141
    }
95
 
    slapi_free_search_results_internal(int_search_pb);
96
 
    slapi_pblock_destroy(int_search_pb);
 
142
 
97
143
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
98
 
                    "searchUid: posix user %s not found\n", udn);
99
 
    return NULL;
 
144
                    "searchUid(%s): <==\n", udn);
 
145
        
 
146
    return uid;
100
147
}
101
148
 
102
149
int
152
199
    return false;
153
200
}
154
201
 
 
202
int
 
203
uid_in_valueset(const char* uid, Slapi_ValueSet *uids)
 
204
{
 
205
    int i;
 
206
    Slapi_Value *v = NULL;
 
207
 
 
208
    if (uid == NULL)
 
209
        return false;
 
210
    for (i = slapi_valueset_first_value(uids, &v); i != -1;
 
211
         i = slapi_valueset_next_value(uids, i, &v)) {
 
212
        Slapi_RDN *i_rdn = NULL;
 
213
        char *i_uid = NULL;
 
214
        char *t = NULL;
 
215
 
 
216
        const char *uid_i = slapi_value_get_string(v);
 
217
 
 
218
        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "uid_in_valueset: comp %s %s \n",
 
219
                        uid, uid_i);
 
220
        i_rdn = slapi_rdn_new_dn(uid_i);
 
221
        if (slapi_rdn_get_first(i_rdn, &t, &i_uid) == 1) {
 
222
            if (strncasecmp(uid, i_uid, 256) == 0) {
 
223
                slapi_rdn_free(&i_rdn);
 
224
                return true;
 
225
            }
 
226
        }
 
227
        slapi_rdn_free(&i_rdn);
 
228
    }
 
229
    return false;
 
230
}
 
231
 
155
232
/* return 1 if smods already has the given mod - 0 otherwise */
156
233
static int
157
234
smods_has_mod(Slapi_Mods *smods, int modtype, const char *type, const char *val)
185
262
    return rc;
186
263
}
187
264
 
188
 
int
189
 
isPosixGroup(Slapi_Entry *entry)
 
265
static int
 
266
hasObjectClass(Slapi_Entry *entry, const char *objectClass)
190
267
{
191
268
    int rc = 0;
192
269
    int i;
200
277
    }
201
278
 
202
279
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
203
 
                    "add/mod-GroupMembership scan objectclasses\n");
 
280
                    "Scanning objectclasses\n");
204
281
 
205
282
    for (
206
283
        i = slapi_attr_first_value(obj_attr, &value);
209
286
    ) {
210
287
        const char *oc = NULL;
211
288
        oc = slapi_value_get_string(value);
212
 
        if (strncasecmp(oc, "posixGroup", 11) == 0) {
213
 
            return 1; /* Entry has objectclass posixGroup */
214
 
        }
215
 
    }
216
 
 
217
 
    return 0; /* Doesn't have objectclass "posixGroup" */
 
289
        if (strcasecmp(oc, objectClass) == 0) {
 
290
            return 1; /* Entry has the desired objectclass */
 
291
        }
 
292
    }
 
293
    
 
294
    return 0; /* Doesn't have desired objectclass */
 
295
}
 
296
 
 
297
void
 
298
posix_winsync_foreach_parent(Slapi_Entry *entry, char **attrs, plugin_search_entry_callback callback, void *callback_data)
 
299
{
 
300
    char *cookie = NULL;
 
301
    Slapi_Backend *be = NULL;
 
302
 
 
303
    char *value = slapi_entry_get_ndn(entry);
 
304
    size_t vallen = value ? strlen(value) : 0;
 
305
    char *filter_escaped_value = slapi_escape_filter_value(value, vallen);
 
306
    char *filter = slapi_ch_smprintf("(uniqueMember=%s)", filter_escaped_value);
 
307
    slapi_ch_free_string(&filter_escaped_value);
 
308
 
 
309
    Slapi_PBlock *search_pb = slapi_pblock_new();
 
310
 
 
311
    for (be = slapi_get_first_backend(&cookie); be;
 
312
         be = slapi_get_next_backend(cookie)) {
 
313
        const Slapi_DN *base_sdn = slapi_be_getsuffix(be, 0);
 
314
        if (base_sdn == NULL) {
 
315
            continue;
 
316
        }
 
317
        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
318
                        "posix_winsync_foreach_parent: Searching subtree %s for %s\n",
 
319
                        slapi_sdn_get_dn(base_sdn),
 
320
                        filter);
 
321
        
 
322
        slapi_search_internal_set_pb(search_pb,
 
323
                                     slapi_sdn_get_dn(base_sdn),
 
324
                                     LDAP_SCOPE_SUBTREE,
 
325
                                     filter,
 
326
                                     attrs, 0, NULL, NULL,
 
327
                                     posix_winsync_get_plugin_identity(), 0);
 
328
        slapi_search_internal_callback_pb(search_pb, callback_data, 0, callback, 0);        
 
329
        
 
330
        slapi_pblock_init(search_pb);
 
331
    }
 
332
 
 
333
    slapi_pblock_destroy(search_pb);
 
334
    slapi_ch_free((void**)&cookie);
 
335
    slapi_ch_free_string(&filter);
 
336
}
 
337
 
 
338
/* Retrieve nested membership from chains of groups.
 
339
 * Muid_vs  in => any preexisting membership list
 
340
 *         out => the union of the input list and the total membership
 
341
 * Muid_nested_vs out => the members of muid_vs "out" that weren't in muid_vs "in"
 
342
 * deletions in => Any elements to NOT consider if members of base_sdn
 
343
 */
 
344
void
 
345
getMembershipFromDownward(Slapi_Entry *entry, Slapi_ValueSet *muid_vs, Slapi_ValueSet *muid_nested_vs, Slapi_ValueSet *deletions, const Slapi_DN *base_sdn, int depth)
 
346
{
 
347
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
348
                    "getMembershipFromDownward: ==>\n");
 
349
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
350
                    "getMembershipFromDownward: entry name: %s\n",
 
351
                    slapi_entry_get_dn_const(entry));
 
352
 
 
353
    int rc = 0;
 
354
    Slapi_Attr *um_attr = NULL; /* Entry attributes uniqueMember */
 
355
    Slapi_Value *uid_value = NULL; /* uniqueMember attribute values */
 
356
 
 
357
    if (depth >= MAX_RECURSION_DEPTH) {
 
358
        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
359
                        "getMembershipFromDownward: recursion limit reached: %d\n", depth);
 
360
        return;
 
361
    }
 
362
 
 
363
    rc = slapi_entry_attr_find(entry, "uniquemember", &um_attr);
 
364
    if (rc != 0 || um_attr == NULL) {
 
365
        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
366
                        "getMembershipFromDownward end: attribute uniquemember not found\n");
 
367
        return;
 
368
    }
 
369
 
 
370
    int i;
 
371
    for (i = slapi_attr_first_value(um_attr, &uid_value); i != -1;
 
372
         i = slapi_attr_next_value(um_attr, i, &uid_value)) {
 
373
 
 
374
        char *attrs[] = { "uniqueMember", "memberUid", "uid", "objectClass", NULL };
 
375
        const char *uid_dn = slapi_value_get_string(uid_value);
 
376
        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
377
                        "getMembershipFromDownward: iterating uniqueMember: %s\n",
 
378
                        uid_dn);
 
379
        
 
380
        if (deletions && !slapi_sdn_compare(slapi_entry_get_sdn_const(entry), base_sdn)) {
 
381
            if (slapi_valueset_find(um_attr, deletions, uid_value)) {
 
382
                slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
383
                                "getMembershipFromDownward: Skipping iteration because of deletion\n");
 
384
 
 
385
                continue;
 
386
            }
 
387
        }
 
388
 
 
389
        Slapi_Entry *child = getEntry(uid_dn, attrs);
 
390
 
 
391
        if (!child) {
 
392
            slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
393
                            "getMembershipFromDownward end: child not found: %s\n", uid_dn);
 
394
        }
 
395
        else {
 
396
            /* PosixGroups except for the top one are already fully mapped out */
 
397
            if ((!hasObjectClass(entry, "posixGroup") || depth == 0) &&
 
398
                (hasObjectClass(child, "ntGroup") || hasObjectClass(child, "posixGroup"))) {
 
399
 
 
400
                /* Recurse downward */
 
401
                getMembershipFromDownward(child, muid_vs, muid_nested_vs, deletions, base_sdn, depth + 1);
 
402
            }
 
403
 
 
404
            if (hasObjectClass(child, "posixAccount")) {
 
405
                Slapi_Attr *uid_attr = NULL;
 
406
                Slapi_Value *v = NULL;
 
407
                if (slapi_entry_attr_find(child, "uid", &uid_attr) == 0) {
 
408
                    slapi_attr_first_value(uid_attr, &v);
 
409
 
 
410
                    if (v && !slapi_valueset_find(uid_attr, muid_vs, v)) {                        
 
411
                        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
412
                                        "getMembershipFromDownward: adding member: %s\n",
 
413
                                        slapi_value_get_string(v));
 
414
                        slapi_valueset_add_value(muid_vs, v);
 
415
                        slapi_valueset_add_value(muid_nested_vs, v);
 
416
                    }
 
417
                }
 
418
            }
 
419
            slapi_entry_free(child);
 
420
        }
 
421
    }
 
422
 
 
423
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
424
                    "getMembershipFromDownward: <==\n");
 
425
}
 
426
 
 
427
struct propogateMembershipUpwardArgs {
 
428
    Slapi_ValueSet *muid_vs;
 
429
    int depth;
 
430
};
 
431
 
 
432
/* Forward declaration for next function */
 
433
void propogateMembershipUpward(Slapi_Entry *, Slapi_ValueSet *, int);
 
434
 
 
435
int
 
436
propogateMembershipUpwardCallback(Slapi_Entry *child, void *callback_data)
 
437
{
 
438
    struct propogateMembershipUpwardArgs *args = (struct propogateMembershipUpwardArgs *)(callback_data);
 
439
    propogateMembershipUpward(child, args->muid_vs, args->depth);
 
440
    return 0;
 
441
}
 
442
 
 
443
void
 
444
propogateMembershipUpward(Slapi_Entry *entry, Slapi_ValueSet *muid_vs, int depth)
 
445
{
 
446
    if (depth >= MAX_RECURSION_DEPTH) {
 
447
        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
448
                        "propogateMembershipUpward: recursion limit reached: %d\n", depth);
 
449
        return;
 
450
    }
 
451
 
 
452
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
453
                    "propogateMembershipUpward: ==>\n");
 
454
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
455
                    "propogateMembershipUpward: entry name: %s\n",
 
456
                    slapi_entry_get_dn_const(entry));
 
457
 
 
458
    Slapi_ValueSet *muid_here_vs   = NULL;
 
459
    Slapi_ValueSet *muid_upward_vs = NULL;
 
460
 
 
461
    /* Get the memberUids at this location, and figure out local changes to memberUid (if any)
 
462
     *  and changes to send upward.
 
463
     */
 
464
    if (depth > 0 && hasObjectClass(entry, "posixGroup")) {
 
465
        int addDynamicGroup = 0;
 
466
        Slapi_Attr *muid_old_attr = NULL;
 
467
        Slapi_ValueSet *muid_old_vs = NULL;
 
468
        int rc = slapi_entry_attr_find(entry, "memberUid", &muid_old_attr);
 
469
        if (rc != 0 || muid_old_attr == NULL) { /* Found no memberUid list, so create  */
 
470
            slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
471
                            "propogateMembershipUpward: no attribute memberUid\n");
 
472
            
 
473
            /* There's no values from this entry to add */
 
474
            muid_upward_vs = muid_vs;
 
475
            muid_here_vs = muid_vs;
 
476
        }
 
477
        else {
 
478
            int i = 0;
 
479
            Slapi_Value *v = NULL;
 
480
            /* Eliminate duplicates */
 
481
            muid_upward_vs = slapi_valueset_new();
 
482
            muid_here_vs = slapi_valueset_new();
 
483
 
 
484
            slapi_attr_get_valueset(muid_old_attr, &muid_old_vs);
 
485
            slapi_valueset_set_valueset(muid_upward_vs, muid_old_vs);
 
486
 
 
487
            for (i = slapi_valueset_first_value(muid_vs, &v); i != -1;
 
488
                 i = slapi_valueset_next_value(muid_vs, i, &v)) {
 
489
                
 
490
                if (!slapi_valueset_find(muid_old_attr, muid_old_vs, v)) {
 
491
                    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
492
                                    "propogateMembershipUpward: adding %s to set\n",
 
493
                                    slapi_value_get_string(v));
 
494
 
 
495
                    addDynamicGroup = 1;
 
496
                    slapi_valueset_add_value(muid_here_vs, v);
 
497
                    slapi_valueset_add_value(muid_upward_vs, v);
 
498
                }
 
499
            }
 
500
            slapi_valueset_free(muid_old_vs);
 
501
        }
 
502
 
 
503
        /* Update this group's membership */
 
504
        slapi_entry_add_valueset(entry, "memberUid", muid_here_vs);
 
505
        if (addDynamicGroup) {
 
506
            addDynamicGroupIfNecessary(entry, NULL);
 
507
            slapi_entry_add_valueset(entry, "dsOnlyMemberUid", muid_here_vs);
 
508
        }
 
509
    }
 
510
    else {
 
511
        muid_upward_vs = muid_vs;
 
512
    }
 
513
 
 
514
    /* Find groups containing this one, recurse
 
515
     */
 
516
    char *attrs[] = {"memberUid", "objectClass", NULL};
 
517
    struct propogateMembershipUpwardArgs data = {muid_upward_vs, depth + 1};
 
518
 
 
519
    posix_winsync_foreach_parent(entry, attrs, propogateMembershipUpwardCallback, &data);
 
520
 
 
521
/* Cleanup */
 
522
    if (muid_here_vs && muid_here_vs != muid_vs) {
 
523
        slapi_valueset_free(muid_here_vs); muid_here_vs = NULL;
 
524
    }
 
525
    if (muid_upward_vs && muid_upward_vs != muid_vs) {
 
526
        slapi_valueset_free(muid_upward_vs); muid_upward_vs = NULL;
 
527
    }
 
528
 
 
529
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
530
                    "propogateMembershipUpward: <==\n");
 
531
}
 
532
 
 
533
struct propogateDeletionsUpwardArgs {
 
534
    const Slapi_DN *base_sdn;
 
535
    Slapi_ValueSet *smod_deluids;
 
536
    Slapi_ValueSet *del_nested_vs;
 
537
    int depth;
 
538
};
 
539
 
 
540
/* Forward declaration for next function */
 
541
void propogateDeletionsUpward(Slapi_Entry *, const Slapi_DN *, Slapi_ValueSet*, Slapi_ValueSet *, int);
 
542
 
 
543
int
 
544
propogateDeletionsUpwardCallback(Slapi_Entry *entry, void *callback_data)
 
545
{
 
546
    struct propogateDeletionsUpwardArgs *args = (struct propogateDeletionsUpwardArgs *)(callback_data);
 
547
    propogateDeletionsUpward(entry, args->base_sdn, args->smod_deluids, args->del_nested_vs, args->depth);
 
548
    return 0;
 
549
}
 
550
 
 
551
void
 
552
propogateDeletionsUpward(Slapi_Entry *entry, const Slapi_DN *base_sdn, Slapi_ValueSet *smod_deluids, Slapi_ValueSet *del_nested_vs, int depth)
 
553
{
 
554
    if (smod_deluids == NULL) return;
 
555
 
 
556
    if (depth >= MAX_RECURSION_DEPTH) {
 
557
        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
558
                        "propogateDeletionsUpward: recursion limit reached: %d\n", depth);
 
559
        return;
 
560
    }
 
561
 
 
562
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
563
                    "propogateDeletionsUpward: ==>\n");
 
564
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
565
                    "propogateDeletionsUpward: entry name: %s\n",
 
566
                    slapi_entry_get_dn_const(entry));
 
567
 
 
568
    char *attrs[] = { "uniqueMember", "memberUid", "objectClass", NULL };
 
569
    struct propogateDeletionsUpwardArgs data = {base_sdn, smod_deluids, del_nested_vs, depth + 1};
 
570
    posix_winsync_foreach_parent(entry, attrs, propogateDeletionsUpwardCallback, &data);
 
571
 
 
572
    Slapi_Attr *muid_attr = NULL;
 
573
    int rc = slapi_entry_attr_find(entry, "dsOnlyMemberUid", &muid_attr);
 
574
    
 
575
    if (rc == 0 && muid_attr != NULL) {
 
576
 
 
577
        Slapi_ValueSet *muid_vs = slapi_valueset_new();
 
578
        Slapi_ValueSet *muid_nested_vs = slapi_valueset_new();
 
579
        Slapi_ValueSet *muid_deletions_vs = slapi_valueset_new();
 
580
 
 
581
        getMembershipFromDownward(entry, muid_vs, muid_nested_vs, smod_deluids, base_sdn, 0);
 
582
 
 
583
        int i;
 
584
        Slapi_Value *v;
 
585
        for (i = slapi_attr_first_value(muid_attr, &v); i != -1;
 
586
             i = slapi_attr_next_value(muid_attr, i, &v)) {
 
587
            if (!slapi_valueset_find(muid_attr, muid_vs, v)) {
 
588
                const char *uid = slapi_value_get_string(v);
 
589
                if (depth == 0 && !uid_in_valueset(uid, smod_deluids)) {
 
590
                    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
591
                                    "propogateDeletionsUpward: Adding deletion to modlist: %s\n",
 
592
                                    slapi_value_get_string(v));
 
593
                    slapi_valueset_add_value(del_nested_vs, v);                    
 
594
                }
 
595
                else if (depth > 0) {
 
596
                    slapi_valueset_add_value(muid_deletions_vs, v);                
 
597
                    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
598
                                    "propogateDeletionsUpward: Adding deletion to deletion list: %s\n",
 
599
                                    slapi_value_get_string(v));
 
600
                }
 
601
            }
 
602
        }
 
603
 
 
604
        if (depth > 0) {
 
605
            slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
606
                            "propogateDeletionsUpward: executing deletion list\n");
 
607
 
 
608
            Slapi_Mods *smods = slapi_mods_new();
 
609
            slapi_mods_add_mod_values(smods, LDAP_MOD_DELETE, "memberuid", valueset_get_valuearray(muid_deletions_vs));
 
610
            slapi_mods_add_mod_values(smods, LDAP_MOD_DELETE, "dsonlymemberuid", valueset_get_valuearray(muid_deletions_vs));
 
611
 
 
612
            Slapi_PBlock *mod_pb = slapi_pblock_new();
 
613
            slapi_modify_internal_set_pb_ext(mod_pb, slapi_entry_get_sdn(entry), slapi_mods_get_ldapmods_passout(smods), 0, 0,
 
614
                                             posix_winsync_get_plugin_identity(), 0);
 
615
            slapi_modify_internal_pb(mod_pb);
 
616
            slapi_pblock_destroy(mod_pb);
 
617
 
 
618
            slapi_mods_free(&smods);
 
619
        }
 
620
 
 
621
        slapi_valueset_free(muid_vs); muid_vs = NULL;
 
622
        slapi_valueset_free(muid_nested_vs); muid_nested_vs = NULL;
 
623
        slapi_valueset_free(muid_deletions_vs); muid_deletions_vs = NULL;
 
624
    }
 
625
 
 
626
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
627
                    "propogateDeletionsUpward: <==\n");
218
628
}
219
629
 
220
630
int
221
631
modGroupMembership(Slapi_Entry *entry, Slapi_Mods *smods, int *do_modify)
222
632
{
223
 
    int rc = 0;
224
 
 
225
633
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "modGroupMembership: ==>\n");
226
 
 
227
 
    if (!isPosixGroup(entry)) {
 
634
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "modGroupMembership: Modding %s\n",
 
635
                    slapi_entry_get_dn_const(entry));
 
636
 
 
637
    int posixGroup = hasObjectClass(entry, "posixGroup");
 
638
 
 
639
    if (!(posixGroup || hasObjectClass(entry, "ntGroup"))) {
 
640
        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
641
                        "modGroupMembership end: Not a posixGroup or ntGroup\n");
228
642
        return 0;
229
643
    }
230
644
 
232
646
    Slapi_Mod *nextMod = slapi_mod_new();
233
647
    int del_mod = 0; /* Bool: was there a delete mod? */
234
648
    char **smod_adduids = NULL;
235
 
    char **smod_deluids = NULL;
 
649
    Slapi_ValueSet *smod_deluids = NULL;
236
650
 
237
651
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
238
652
                    "modGroupMembership: posixGroup -> look for uniquemember\n");
243
657
        if (slapi_attr_types_equivalent(slapi_mod_get_type(smod), "uniqueMember")) {
244
658
            struct berval *bv;
245
659
 
 
660
            int current_del_mod = SLAPI_IS_MOD_DELETE(slapi_mod_get_operation(smod));
 
661
            if (current_del_mod) {
 
662
                del_mod = 1;
 
663
            }
 
664
            
246
665
            for (bv = slapi_mod_get_first_value(smod); bv;
247
666
                 bv = slapi_mod_get_next_value(smod)) {
248
667
                Slapi_Value *sv = slapi_value_new();
249
668
 
250
669
                slapi_value_init_berval(sv, bv); /* copies bv_val */
251
 
                if (SLAPI_IS_MOD_DELETE(slapi_mod_get_operation(smod))) {
252
 
                    del_mod = 1;
253
 
                    slapi_ch_array_add(&smod_deluids,
254
 
                                       slapi_ch_strdup(slapi_value_get_string(sv)));
 
670
                if (current_del_mod) {
 
671
                    if (!smod_deluids) smod_deluids = slapi_valueset_new();
 
672
 
 
673
                    slapi_valueset_add_value(smod_deluids, sv);
255
674
                    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
256
675
                                    "modGroupMembership: add to deluids %s\n",
257
676
                                    bv->bv_val);
268
687
    }
269
688
    slapi_mod_free(&nextMod);
270
689
 
271
 
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
272
 
                    "modGroupMembership: entry is posixGroup\n");
273
 
 
274
 
    Slapi_Attr * muid_attr = NULL; /* Entry attributes        */
 
690
    int muid_rc = 0;
 
691
    Slapi_Attr * muid_attr  = NULL; /* Entry attributes        */
 
692
    Slapi_ValueSet *muid_vs = NULL;
275
693
    Slapi_Value * uid_value = NULL; /* Attribute values        */
276
694
 
277
 
    char **adduids = NULL;
278
 
    char **moduids = NULL;
279
 
    char **deluids = NULL;
280
 
    int doModify = false;
 
695
    Slapi_ValueSet *adduids = slapi_valueset_new();
 
696
    Slapi_ValueSet *add_nested_vs = slapi_valueset_new();
 
697
    Slapi_ValueSet *deluids = slapi_valueset_new();
 
698
    Slapi_ValueSet *del_nested_vs = slapi_valueset_new();
 
699
 
 
700
    const Slapi_DN *base_sdn = slapi_entry_get_sdn_const(entry);
 
701
 
281
702
    int j = 0;
282
703
 
283
704
    if (del_mod || smod_deluids != NULL) {
284
705
        do { /* Create a context to "break" from */
285
 
            Slapi_Attr * mu_attr = NULL; /* Entry attributes        */
286
 
            rc = slapi_entry_attr_find(entry, "memberUid", &mu_attr);
287
 
            if (rc != 0 || mu_attr == NULL) {
288
 
                slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
289
 
                                "modGroupMembership end: attribute memberUid not found\n");
290
 
                break;
291
 
            }
292
 
            /* found attribute uniquemember */
 
706
            muid_rc = slapi_entry_attr_find(entry, "memberUid", &muid_attr);
 
707
 
293
708
            if (smod_deluids == NULL) { /* deletion of the last value, deletes the Attribut from entry complete, this operation has no value, so we must look by self */
294
709
                Slapi_Attr * um_attr = NULL; /* Entry attributes        */
295
 
                Slapi_Value * uid_dn_value = NULL; /* Attribute values        */
296
710
                int rc = slapi_entry_attr_find(entry, "uniquemember", &um_attr);
 
711
                
297
712
                if (rc != 0 || um_attr == NULL) {
298
713
                    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
299
714
                                    "modGroupMembership end: attribute uniquemember not found\n");
300
715
                    break;
301
716
                }
302
 
                /* found attribute uniquemember */
 
717
 
 
718
                slapi_attr_get_valueset(um_attr, &smod_deluids);
 
719
            }
 
720
            if (muid_rc != 0 || muid_attr == NULL) {
 
721
                slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
722
                                "modGroupMembership end: attribute memberUid not found\n");
 
723
            }
 
724
            else if (posix_winsync_config_get_mapMemberUid()) {
303
725
                /* ...loop for value...    */
304
 
                for (j = slapi_attr_first_value(um_attr, &uid_dn_value); j != -1;
305
 
                     j = slapi_attr_next_value(um_attr, j, &uid_dn_value)) {
306
 
                    slapi_ch_array_add(&smod_deluids,
307
 
                                       slapi_ch_strdup(slapi_value_get_string(uid_dn_value)));
 
726
                for (j = slapi_attr_first_value(muid_attr, &uid_value); j != -1;
 
727
                     j = slapi_attr_next_value(muid_attr, j, &uid_value)) {
 
728
                    /* remove from uniquemember: remove from memberUid also */
 
729
                    const char *uid = NULL;
 
730
                    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
731
                                    "modGroupMembership: test dellist \n");
 
732
                    uid = slapi_value_get_string(uid_value);
 
733
                    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
734
                                    "modGroupMembership: test dellist %s\n", uid);
 
735
                    if (uid_in_valueset(uid, smod_deluids)) {
 
736
                        slapi_valueset_add_value(deluids, uid_value);
 
737
                        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
738
                                        "modGroupMembership: add to dellist %s\n", uid);
 
739
                    }
308
740
                }
309
741
            }
310
 
            /* ...loop for value...    */
311
 
            for (j = slapi_attr_first_value(mu_attr, &uid_value); j != -1;
312
 
                 j = slapi_attr_next_value(mu_attr, j, &uid_value)) {
313
 
                /* remove from uniquemember: remove from memberUid also */
314
 
                const char *uid = NULL;
315
 
                slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
316
 
                                "modGroupMembership: test dellist \n");
317
 
                uid = slapi_value_get_string(uid_value);
318
 
                slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
319
 
                                "modGroupMembership: test dellist %s\n", uid);
320
 
                if (uid_in_set(uid, smod_deluids)) {
321
 
                    slapi_ch_array_add(&deluids, slapi_ch_strdup(uid));
322
 
                    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
323
 
                                    "modGroupMembership: add to dellist %s\n", uid);
324
 
                    doModify = true;
 
742
            
 
743
            if (posix_winsync_config_get_mapNestedGrouping()) {
 
744
                propogateDeletionsUpward(entry, base_sdn, smod_deluids, del_nested_vs, 0);
 
745
                int i;
 
746
                Slapi_Value *v;
 
747
                for (i = slapi_valueset_first_value(del_nested_vs, &v); i != -1;
 
748
                     i = slapi_valueset_next_value(del_nested_vs, i, &v)) {
 
749
                    slapi_valueset_add_value(deluids, v);
325
750
                }
326
751
            }
327
752
        } while (false);
331
756
 
332
757
        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
333
758
                        "modGroupMembership: posixGroup -> look for uniquemember\n");
334
 
        /* found attribute uniquemember */
335
 
        for (j = 0; smod_adduids[j]; j++) {
336
 
            static char *uid = NULL;
337
 
 
338
 
            uid_dn = smod_adduids[j];
339
 
            slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
340
 
                            "modGroupMembership: perform user %s\n", uid_dn);
341
 
 
342
 
            uid = searchUid(uid_dn);
343
 
 
344
 
            if (uid == NULL) {
 
759
 
 
760
        if (muid_rc == 0 && muid_attr == NULL) {
 
761
            muid_rc = slapi_entry_attr_find(entry, "memberUid", &muid_attr);
 
762
        }
 
763
        if (muid_rc == 0 && muid_attr != NULL) {
 
764
            slapi_attr_get_valueset(muid_attr, &muid_vs);
 
765
        }
 
766
        else {
 
767
            muid_vs = slapi_valueset_new();
 
768
        }
 
769
 
 
770
        if (posix_winsync_config_get_mapMemberUid()) {
 
771
            for (j = 0; smod_adduids[j]; j++) {
 
772
                static char *uid = NULL;
 
773
 
 
774
                uid_dn = smod_adduids[j];
345
775
                slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
346
 
                                "modGroupMembership: uid not found for %s, cannot do anything\n",
347
 
                                uid_dn); /* member on longer on server, do nothing */
348
 
            } else {
349
 
                rc |= slapi_entry_attr_find(entry, "memberUid", &muid_attr);
350
 
                if (rc != 0 || muid_attr == NULL) { /* Found no memberUid list, so create  */
 
776
                                "modGroupMembership: perform user %s\n", uid_dn);
 
777
 
 
778
                uid = searchUid(uid_dn);
 
779
 
 
780
                if (uid == NULL) {
351
781
                    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
352
 
                                    "modGroupMembership: no attribute memberUid, add with %s \n",
353
 
                                    uid_dn);
354
 
                    slapi_ch_array_add(&adduids, uid);
355
 
                    uid = NULL; /* adduids now owns uid */
356
 
                    doModify = true;
357
 
                } else { /* Found a memberUid list, so modify */
358
 
                    Slapi_ValueSet *vs = NULL;
 
782
                                    "modGroupMembership: uid not found for %s, cannot do anything\n",
 
783
                                    uid_dn); /* member on longer on server, do nothing */
 
784
                } else {
359
785
                    Slapi_Value *v = slapi_value_new();
360
 
 
361
786
                    slapi_value_init_string_passin(v, uid);
362
 
                    slapi_attr_get_valueset(muid_attr, &vs);
363
 
                    if (slapi_valueset_find(muid_attr, vs, v) != NULL) { /* already exist, all ok */
 
787
 
 
788
                    if (muid_rc == 0 && muid_attr != NULL &&
 
789
                        slapi_valueset_find(muid_attr, muid_vs, v) != NULL) {
 
790
 
364
791
                        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
365
792
                                        "modGroupMembership: uid found in memberuid list %s nothing to do\n",
366
793
                                        uid);
367
 
                    } else {
368
 
                        slapi_ch_array_add(&moduids, uid);
 
794
                    }
 
795
                    else {
 
796
                        slapi_valueset_add_value(adduids, v);
 
797
                        slapi_valueset_add_value(muid_vs, v);
369
798
                        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
370
799
                                        "modGroupMembership: add to modlist %s\n", uid);
371
 
                        uid = NULL; /* adduids now owns uid */
372
 
                        /* have to clear out v otherwise slapi_value_free will also free uid */
373
 
                        slapi_value_init_berval(v, NULL);
374
 
                        doModify = true;
375
800
                    }
 
801
 
376
802
                    slapi_value_free(&v); /* also frees uid since it was a passin */
377
 
                    slapi_valueset_free(vs); vs = NULL;
378
 
                }
379
 
            }
 
803
                }
 
804
            }
 
805
        }
 
806
 
 
807
        if (posix_winsync_config_get_mapNestedGrouping()) {
 
808
 
 
809
            for (j = 0; smod_adduids[j]; ++j) {
 
810
                char *attrs[] = { "uniqueMember", "memberUid", "uid", "objectClass", NULL };
 
811
                Slapi_Entry *child = getEntry(smod_adduids[j], attrs);
 
812
 
 
813
                if (child) {
 
814
                    if (hasObjectClass(child, "ntGroup") || hasObjectClass(child, "posixGroup")) {
 
815
                        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
816
                                        "modGroupMembership: Found mod to add group, adding membership: %s\n",
 
817
                                        smod_adduids[j]);
 
818
                        Slapi_ValueSet *muid_tempnested = slapi_valueset_new();
 
819
                        getMembershipFromDownward(child, muid_vs, add_nested_vs, smod_deluids, base_sdn, 0);
 
820
 
 
821
                        slapi_valueset_free(muid_tempnested); muid_tempnested = NULL;
 
822
                    }
 
823
                }
 
824
                else {
 
825
                    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
826
                                    "modGroupMembership: entry not found for dn: %s\n",
 
827
                                    smod_adduids[j]);
 
828
                }
 
829
            }
 
830
 
 
831
            getMembershipFromDownward(entry, muid_vs, add_nested_vs, smod_deluids, base_sdn, 0);
 
832
            int i = 0;
 
833
            Slapi_Value *v = NULL;
 
834
            for (i = slapi_valueset_first_value(add_nested_vs, &v); i != -1;
 
835
                 i = slapi_valueset_next_value(add_nested_vs, i, &v)) {
 
836
                slapi_valueset_add_value(adduids, v);
 
837
            }
 
838
 
 
839
            propogateMembershipUpward(entry, adduids, 0);
380
840
        }
381
841
    }
382
 
    if (doModify) {
 
842
    if (posixGroup) {
 
843
        int addDynamicGroup = 0;
383
844
        int i;
384
 
        for (i = 0; adduids && adduids[i]; i++) {
385
 
            if (!smods_has_mod(smods, LDAP_MOD_ADD, "memberUid", adduids[i])) {
386
 
                slapi_mods_add_string(smods, LDAP_MOD_ADD, "memberUid", adduids[i]);
387
 
            }
388
 
        }
389
 
        for (i = 0; moduids && moduids[i]; i++) {
390
 
            if (!smods_has_mod(smods, LDAP_MOD_ADD, "memberUid", moduids[i])) {
391
 
                slapi_mods_add_string(smods, LDAP_MOD_ADD, "memberUid", moduids[i]);
392
 
            }
393
 
        }
394
 
        for (i = 0; deluids && deluids[i]; i++) {
395
 
            if (!smods_has_mod(smods, LDAP_MOD_DELETE, "memberUid", deluids[i])) {
396
 
                slapi_mods_add_string(smods, LDAP_MOD_DELETE, "memberUid", deluids[i]);
397
 
            }
 
845
        Slapi_Value *v;
 
846
        for (i = slapi_valueset_first_value(adduids, &v); i != -1;
 
847
             i = slapi_valueset_next_value(adduids, i, &v)){
 
848
            const char *muid = slapi_value_get_string(v);
 
849
            if (!smods_has_mod(smods, LDAP_MOD_ADD, "memberUid", muid)) {
 
850
                *do_modify = 1;
 
851
                slapi_mods_add_string(smods, LDAP_MOD_ADD, "memberUid", muid);
 
852
            }
 
853
        }
 
854
        for (i = slapi_valueset_first_value(add_nested_vs, &v); i != -1;
 
855
             i = slapi_valueset_next_value(add_nested_vs, i, &v)) {
 
856
            const char *muid = slapi_value_get_string(v);
 
857
            if (!smods_has_mod(smods, LDAP_MOD_ADD, "dsOnlyMemberUid", muid)) {
 
858
                addDynamicGroup = 1;
 
859
                *do_modify = 1;
 
860
                slapi_mods_add_string(smods, LDAP_MOD_ADD, "dsOnlyMemberUid", muid);
 
861
            }
 
862
        }
 
863
        for (i = slapi_valueset_first_value(deluids, &v); i != -1;
 
864
             i = slapi_valueset_next_value(deluids, i, &v)){
 
865
            const char *muid = slapi_value_get_string(v);
 
866
            if (!smods_has_mod(smods, LDAP_MOD_DELETE, "memberUid", muid)) {
 
867
                *do_modify = 1;
 
868
                slapi_mods_add_string(smods, LDAP_MOD_DELETE, "memberUid", muid);
 
869
            }
 
870
        }
 
871
        for (i = slapi_valueset_first_value(del_nested_vs, &v); i != -1;
 
872
             i = slapi_valueset_next_value(del_nested_vs, i, &v)){
 
873
            const char *muid = slapi_value_get_string(v);
 
874
            if (!smods_has_mod(smods, LDAP_MOD_DELETE, "dsOnlyMemberUid", muid)) {
 
875
                *do_modify = 1;
 
876
                slapi_mods_add_string(smods, LDAP_MOD_DELETE, "dsOnlyMemberUid", muid);
 
877
            }
 
878
        }
 
879
        if (addDynamicGroup) {
 
880
            addDynamicGroupIfNecessary(entry, smods);
398
881
        }
399
882
 
400
883
        if (slapi_is_loglevel_set(SLAPI_LOG_PLUGIN))
401
884
            slapi_mods_dump(smods, "memberUid - mods dump");
402
 
        *do_modify = 1;
403
885
        posix_winsync_config_set_MOFTaskCreated();
404
886
    }
405
887
    slapi_ch_array_free(smod_adduids);
406
888
    smod_adduids = NULL;
407
 
    slapi_ch_array_free(adduids);
 
889
    if (smod_deluids) slapi_valueset_free(smod_deluids);
 
890
    smod_deluids = NULL;
 
891
 
 
892
    slapi_valueset_free(adduids);
408
893
    adduids = NULL;
409
 
    slapi_ch_array_free(smod_deluids);
410
 
    smod_deluids = NULL;
411
 
    slapi_ch_array_free(deluids);
 
894
    slapi_valueset_free(deluids);
412
895
    deluids = NULL;
413
 
    slapi_ch_array_free(moduids);
414
 
    moduids = NULL;
 
896
 
 
897
    slapi_valueset_free(add_nested_vs); add_nested_vs = NULL;
 
898
    slapi_valueset_free(del_nested_vs); del_nested_vs = NULL;
 
899
 
 
900
    if (muid_vs) {
 
901
        slapi_valueset_free(muid_vs); muid_vs = NULL;
 
902
    }
415
903
 
416
904
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "modGroupMembership: <==\n");
417
905
    return 0;
418
906
}
419
907
 
420
908
int
 
909
addUserToGroupMembership(Slapi_Entry *entry)
 
910
{
 
911
    Slapi_Attr *uid_attr = NULL;
 
912
    Slapi_Value *v = NULL;
 
913
    Slapi_ValueSet *muid_vs = slapi_valueset_new();
 
914
 
 
915
    if (slapi_entry_attr_find(entry, "uid", &uid_attr) == 0) {
 
916
        slapi_attr_first_value(uid_attr, &v);
 
917
 
 
918
        if (v) {
 
919
            slapi_valueset_add_value(muid_vs, v);
 
920
        }
 
921
    }
 
922
 
 
923
    propogateMembershipUpward(entry, muid_vs, 0);
 
924
 
 
925
    slapi_valueset_free(muid_vs); muid_vs = NULL;
 
926
    return 0;
 
927
}
 
928
 
 
929
int
421
930
addGroupMembership(Slapi_Entry *entry, Slapi_Entry *ad_entry)
422
931
{
423
932
    int rc = 0;
425
934
 
426
935
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "addGroupMembership: ==>\n");
427
936
 
428
 
    if(!isPosixGroup(entry)) {
 
937
    int posixGroup = hasObjectClass(entry, "posixGroup");
 
938
 
 
939
    if(!(posixGroup || hasObjectClass(entry, "ntGroup"))) {
 
940
        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
941
                        "addGroupMembership: didn't find posixGroup or ntGroup objectclass\n");
429
942
        return 0;
430
943
    }
431
944
 
448
961
    if (rc != 0 || muid_attr == NULL) { /* Found no memberUid list, so create  */
449
962
        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
450
963
                        "addGroupMembership: no attribute memberUid\n");
 
964
        muid_attr = NULL;
451
965
    }
452
966
    newvs = slapi_valueset_new();
453
967
    /* ...loop for value...    */
454
 
    for (i = slapi_attr_first_value(um_attr, &uid_value); i != -1;
455
 
         i = slapi_attr_next_value(um_attr, i, &uid_value)) {
456
 
        const char *uid_dn = NULL;
457
 
        static char *uid = NULL;
458
 
        Slapi_Value *v = NULL;
 
968
    if (posix_winsync_config_get_mapMemberUid()) {
 
969
        for (i = slapi_attr_first_value(um_attr, &uid_value); i != -1;
 
970
             i = slapi_attr_next_value(um_attr, i, &uid_value)) {
 
971
            const char *uid_dn = NULL;
 
972
            static char *uid = NULL;
 
973
            Slapi_Value *v = NULL;
459
974
 
460
 
        uid_dn = slapi_value_get_string(uid_value);
461
 
        slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
462
 
                        "addGroupMembership: perform member %s\n", uid_dn);
463
 
        uid = searchUid(uid_dn);
464
 
        if (uid == NULL) {
 
975
            uid_dn = slapi_value_get_string(uid_value);
465
976
            slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
466
 
                            "addGroupMembership: uid not found for %s, cannot do anything\n",
467
 
                            uid_dn); /* member on longer on server, do nothing */
468
 
        } else {
469
 
            v = slapi_value_new_string(uid);
470
 
            slapi_ch_free_string(&uid);
471
 
            if (slapi_attr_value_find(muid_attr, slapi_value_get_berval(v)) != 0) {
472
 
                slapi_valueset_add_value(newvs, v);
 
977
                            "addGroupMembership: perform member %s\n", uid_dn);
 
978
            uid = searchUid(uid_dn);
 
979
            if (uid == NULL) {
 
980
                slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME,
 
981
                                "addGroupMembership: uid not found for %s, cannot do anything\n",
 
982
                                uid_dn); /* member on longer on server, do nothing */
 
983
            } else {
 
984
                v = slapi_value_new_string(uid);
 
985
                slapi_ch_free_string(&uid);
 
986
                if (slapi_attr_value_find(muid_attr, slapi_value_get_berval(v)) != 0) {
 
987
                    slapi_valueset_add_value(newvs, v);
 
988
                }
 
989
                slapi_value_free(&v);
473
990
            }
474
 
            slapi_value_free(&v);
475
 
        }
476
 
    }
477
 
    slapi_entry_add_valueset(entry, "memberUid", newvs);
478
 
    slapi_valueset_free(newvs);
 
991
        }
 
992
    }
 
993
 
 
994
    if (posix_winsync_config_get_mapNestedGrouping()) {
 
995
        Slapi_ValueSet *muid_nested_vs = slapi_valueset_new();
 
996
 
 
997
        getMembershipFromDownward(entry, newvs, muid_nested_vs, NULL, NULL, 0);
 
998
        propogateMembershipUpward(entry, newvs, 0);
 
999
 
 
1000
        if (posixGroup) {
 
1001
            addDynamicGroupIfNecessary(entry, NULL);
 
1002
            slapi_entry_add_valueset(entry, "dsOnlyMemberUid", muid_nested_vs);
 
1003
        }
 
1004
 
 
1005
        slapi_valueset_free(muid_nested_vs); muid_nested_vs = NULL;   
 
1006
    }
 
1007
 
 
1008
    if (posixGroup) {
 
1009
        slapi_entry_add_valueset(entry, "memberUid", newvs);
 
1010
    }
 
1011
 
 
1012
    slapi_valueset_free(newvs); newvs = NULL;
479
1013
    posix_winsync_config_get_MOFTaskCreated();
480
1014
 
481
1015
    slapi_log_error(SLAPI_LOG_PLUGIN, POSIX_WINSYNC_PLUGIN_NAME, "addGroupMembership: <==\n");