ni_status ni2_copydirtoparentdir(void *srcdomain, ni_id *srcdir, void*dstdomain, ni_id *dstdir , bool recursive) { ni_status ret; ni_idlist children; int i, len; ni_proplist p; ni_id dir, newdstdir; NI_INIT(&p); /* get proplist from src dir */ ret = ni_read(srcdomain, srcdir, &p); if (ret != NI_OK) { return ret; } /* create the destination dir */ ret = ni_create(dstdomain, dstdir, p, &newdstdir, NI_INDEX_NULL); if (ret != NI_OK) { ni_proplist_free(&p); return ret; } ni_proplist_free(&p); if (recursive) { NI_INIT(&children); /* get list of children */ ret = ni_children(srcdomain, srcdir, &children); if (ret != NI_OK) { return ret; } len = children.ni_idlist_len; for (i = 0; i < len; i++) { dir.nii_object = children.ni_idlist_val[i]; ret = ni_self(srcdomain, &dir); if (ret != NI_OK) { ni_idlist_free(&children); return ret; } ret = ni2_copydirtoparentdir(srcdomain,&dir,dstdomain, &newdstdir,recursive); } ni_idlist_free(&children); } return NI_OK; }
ni_status ni2_destroydir(void *domain, ni_id *dir, ni_id *parent) { /* destroy a directory and all it's subdirectories */ /* this is the recursive workhorse */ ni_status ret; int i; ni_idlist children; ni_id child; /* need to be talking to the master */ ni_needwrite(domain, 1); /* get a list of all my children */ NI_INIT(&children); ret = ni_children(domain, dir, &children); if (ret != NI_OK) return ret; /* destroy each child */ for (i = 0; i < children.ni_idlist_len; i++) { child.nii_object = children.ni_idlist_val[i]; ret = ni_self(domain, &child); if (ret != NI_OK) return ret; ret = ni2_destroydir(domain, &child, dir); if (ret != NI_OK) return ret; } /* free list of child ids */ ni_idlist_free(&children); /* destroy myself */ return ni_destroy(domain, parent, *dir); }
static ni_status ni_idlist2binding(void *ni, ni_idlist *idlist, krb5_config_section **ret) { int i; ni_status nis; krb5_config_section **next; for (i = 0; i < idlist->ni_idlist_len; i++) { ni_proplist pl; ni_id nid; ni_idlist children; krb5_config_binding *b; ni_index index; nid.nii_instance = 0; nid.nii_object = idlist->ni_idlist_val[i]; nis = ni_read(ni, &nid, &pl); if (nis != NI_OK) { return nis; } index = ni_proplist_match(pl, "name", NULL); b = malloc(sizeof(*b)); if (b == NULL) return NI_FAILED; if (i == 0) { *ret = b; } else { *next = b; } b->type = krb5_config_list; b->name = ni_name_dup(pl.nipl_val[index].nip_val.ninl_val[0]); b->next = NULL; b->u.list = NULL; /* get the child directories */ nis = ni_children(ni, &nid, &children); if (nis == NI_OK) { nis = ni_idlist2binding(ni, &children, &b->u.list); if (nis != NI_OK) { return nis; } } nis = ni_proplist2binding(&pl, b->u.list == NULL ? &b->u.list : &b->u.list->next); ni_proplist_free(&pl); if (nis != NI_OK) { return nis; } next = &b->next; } ni_idlist_free(idlist); return NI_OK; }
/* * Use ni_lookup to match key=value, * Fetch matching subdirectories and append those that match the pattern to the list. */ static u_int32_t NI_query_lookup(agent_private *ap, char *path, int single_item, u_int32_t where, dsrecord *pattern, dsrecord **list) { ni_idlist idl; ni_proplist pl; ni_id dir; int dx, i, try_realname; ni_status status; dsrecord *r, *lastrec; char *key, *val; dsattribute *a; lastrec = NULL; a = dsattribute_retain(pattern->attribute[where]); key = dsdata_to_cstring(a->key); val = dsdata_to_cstring(a->value[0]); dsrecord_remove_attribute(pattern, a, SELECT_ATTRIBUTE); /* * SPECIAL CASE For category user, key "name": * if no matches for "name", try "realname". */ try_realname = 0; if ((!strcmp(path, "/users")) && (!strcmp(key, "name"))) try_realname = 1; for (dx = 0; dx < ap->domain_count; dx++) { NI_INIT(&dir); syslock_lock(rpcLock); status = sa_pathsearch(ap->domain[dx].handle, &dir, path); syslock_unlock(rpcLock); if (status != NI_OK) continue; NI_INIT(&idl); syslock_lock(rpcLock); status = sa_lookup(ap->domain[dx].handle, &dir, key, val, &idl); if ((idl.ni_idlist_len == 0) && (try_realname == 1)) { status = sa_lookup(ap->domain[dx].handle, &dir, "realname", val, &idl); } syslock_unlock(rpcLock); if (status != NI_OK) continue; for (i = 0; i < idl.ni_idlist_len; i++) { dir.nii_object = idl.ni_idlist_val[i]; dir.nii_instance = 0; NI_INIT(&pl); syslock_lock(rpcLock); status = sa_read(ap->domain[dx].handle, &dir, &pl); syslock_unlock(rpcLock); if (status != NI_OK) continue; r = nitods(&pl); NI_add_validation(ap, r, dx); ni_proplist_free(&pl); if (r == NULL) continue; if (dsrecord_match(r, pattern)) { if (*list == NULL) *list = r; else lastrec->next = r; lastrec = r; if (single_item == 1) { ni_idlist_free(&idl); dsattribute_release(a); return 0; } } else { dsrecord_release(r); } } ni_idlist_free(&idl); } dsattribute_release(a); return 0; }
/* * Fetch all subdirectories and append those that match the pattern to the list. */ static u_int32_t NI_query_all(agent_private *ap, char *path, int single_item, int stamp, dsrecord *pattern, dsrecord **list) { ni_idlist idl; ni_proplist pl; ni_id dir; int dx, i; ni_status status; dsrecord *r, *lastrec; lastrec = NULL; for (dx = 0; dx < ap->domain_count; dx++) { if (stamp == 1) { r = dsrecord_new(); NI_add_validation(ap, r, dx); if (*list == NULL) *list = r; else lastrec->next = r; lastrec = r; continue; } NI_INIT(&dir); syslock_lock(rpcLock); status = sa_pathsearch(ap->domain[dx].handle, &dir, path); syslock_unlock(rpcLock); if (status != NI_OK) continue; NI_INIT(&idl); syslock_lock(rpcLock); status = sa_children(ap->domain[dx].handle, &dir, &idl); syslock_unlock(rpcLock); if (status != NI_OK) continue; for (i = 0; i < idl.ni_idlist_len; i++) { dir.nii_object = idl.ni_idlist_val[i]; dir.nii_instance = 0; NI_INIT(&pl); syslock_lock(rpcLock); status = sa_read(ap->domain[dx].handle, &dir, &pl); syslock_unlock(rpcLock); if (status != NI_OK) continue; r = nitods(&pl); NI_add_validation(ap, r, dx); ni_proplist_free(&pl); if (r == NULL) continue; if (dsrecord_match(r, pattern)) { if (*list == NULL) *list = r; else lastrec->next = r; lastrec = r; if (single_item == 1) { ni_idlist_free(&idl); return 0; } } else { dsrecord_release(r); } } ni_idlist_free(&idl); } return 0; }