void PDB_printProfile(FILE *out, PDB_profile *r) { char tmp[1024]; if (r == NULL) { fprintf(out, "# You tried to print a NULL pointer\n"); return; } if (r->id == 0){ fprintf(out, "The record is empty\n"); return; } /* print header and name */ if(PDB_ISGROUP(r->id)) fprintf(out, "GROUP %s OWNED BY %s\n", r->name, r->owner_name); else fprintf(out, "USER %s\n", r->name); fprintf(out, " * id: %d\n", r->id); if (PDB_ISGROUP(r->id)) fprintf(out, " * owner id: %d\n", r->owner_id); if (r->member_of.size > 0) { pdb_array_snprintf(tmp, &(r->member_of), 1024); fprintf(out, " * belongs to groups: [ %s]\n",tmp); } else fprintf(out, " * belongs to no groups\n"); if (r->cps.size > 0) { pdb_array_snprintf(tmp, &(r->cps), 1024); fprintf(out, " * cps: [ %s]\n",tmp); } else fprintf(out, " * has no cps\n"); if (r->groups_or_members.size > 0) { pdb_array_snprintf(tmp, &(r->groups_or_members), 1024); if (PDB_ISGROUP(r->id)) fprintf(out, " * has members: [ %s]\n",tmp); else fprintf(out, " * owns groups: [ %s]\n",tmp); } else { if (PDB_ISGROUP(r->id)) fprintf(out, " * has no members\n"); else fprintf(out, " * owns no groups\n"); } }
void PDB_removeFromGroup(int32_t id, int32_t groupId) { PDB_HANDLE h; PDB_profile r; /* sanity check arguments (groupId must be < 0) */ CODA_ASSERT(PDB_ISGROUP(groupId) && (id != 0)); h = PDB_db_open(O_RDWR); /* remove id from the group's member list */ PDB_readProfile(h, groupId, &r); CODA_ASSERT(r.id != 0); pdb_array_del(&(r.groups_or_members), id); PDB_writeProfile(h, &r); PDB_freeProfile(&r); /* remove groupId from user's member_of list */ PDB_readProfile(h, id, &r); CODA_ASSERT(r.id != 0); pdb_array_del(&(r.member_of), groupId); PDB_updateCps(h, &r); PDB_freeProfile(&r); PDB_db_close(h); }
/* ADD SOMEONE (USER OR GROUP) TO A GROUP */ void tool_addtoGroup(int argc, char *argv[]) { char *s; long arg1, arg2; if (check_args_num(argc, 3)) { printf( "Usage: ag group user\ngroup\t\t" "id or name of group to add to\nuser\t\t" "id or name of user to add\n"); return; } arg1 = get_id(argv[1]); PDB_lookupById((int32_t)arg1, &s); if (!PDB_ISGROUP(arg1) || s == NULL) { printf("No group %s found!\n", argv[1]); if (s) free(s); return; } free(s); arg2 = get_id(argv[2]); PDB_lookupById((int32_t)arg2, &s); if (s == NULL) { printf("No user or group %s found!\n", argv[2]); if (s) free(s); return; } free(s); PDB_addToGroup(arg2, arg1); }
/* Updates the CPS entries of the given id and the CPS entries of its children*/ void PDB_updateCps(PDB_HANDLE h, PDB_profile *r) { PDB_profile p, c; int32_t nextid; pdb_array_off off; CODA_ASSERT(r != NULL); /* Update the CPS entry of the given id */ pdb_array_free(&(r->cps)); /* Add the CPS of parents into list */ nextid = pdb_array_head(&(r->member_of), &off); while(nextid != 0){ PDB_readProfile(h, nextid, &p); if(p.id != 0) { pdb_array_merge(&(r->cps), &(p.cps)); PDB_freeProfile(&p); } nextid = pdb_array_next(&(r->member_of), &off); } /* Add self to list */ pdb_array_add(&(r->cps), r->id); /* write the updated CPS */ PDB_writeProfile(h, r); /* Update the CPS entries of the given id's children's CPS entries */ if (!PDB_ISGROUP(r->id)) return; /* Add the CPS of parents into list */ nextid = pdb_array_head(&(r->groups_or_members), &off); while(nextid != 0){ PDB_readProfile(h, nextid, &c); if (c.id != 0) { /* Recurse through all children */ PDB_updateCps(h, &c); PDB_freeProfile(&c); } nextid = pdb_array_next(&(r->groups_or_members), &off); } }
void PDB_changeName(int32_t id, char *name) { PDB_HANDLE h; PDB_profile r,p; pdb_array_off off; int32_t nextid; /* sanity check arguments */ CODA_ASSERT(name); h = PDB_db_open(O_RDWR); /* add id to the group's member list */ PDB_readProfile(h, id, &r); CODA_ASSERT(r.id != 0); PDB_db_delete_xfer(h, r.name); free(r.name); r.name = strdup(name); PDB_writeProfile(h, &r); /* Update everything is an owner of */ if(PDB_ISUSER(id)){ nextid = pdb_array_head(&(r.groups_or_members), &off); while(nextid != 0){ PDB_readProfile(h, nextid, &p); CODA_ASSERT(r.id != 0); if(PDB_ISGROUP(p.id)){ free(p.owner_name); p.owner_name = strdup(name); PDB_writeProfile(h, &p); } PDB_freeProfile(&p); nextid = pdb_array_next(&(r.groups_or_members), &off); } } PDB_freeProfile(&r); PDB_db_close(h); }
/* DELETE USER OR GROUP */ void tool_delete(int argc, char *argv[]) { char *s; long arg1; if (check_args_num(argc, 2)) { printf( "Usage: d id/name\n" "id/name\t\tid or name of user/group\n"); return; } arg1 = get_id(argv[1]); PDB_lookupById((int32_t)arg1, &s); if (s == NULL) { printf("%s not found!\n", argv[1]); return; } free(s); if (PDB_ISGROUP(arg1)) PDB_deleteGroup(arg1); else PDB_deleteUser(arg1); }
/* REMOVE SOMEONE (USER OR GROUP) TO A GROUP */ void tool_removefromGroup(int argc, char *argv[]) { int32_t arg1, arg2; if (check_args_num(argc, 3)) { printf( "Usage: rg group user\ngroup\t\t" "id or name of group to remove from\nuser\t\t" "id or name of user to remove\n"); return; } arg1 = get_id(argv[1]); if (!PDB_ISGROUP(arg1)) { printf("No group %s found!\n", argv[1]); return; } arg2 = get_id(argv[2]); if (arg2 == 0) { printf("No user or group %s found!\n", argv[2]); return; } PDB_removeFromGroup(arg2, arg1); }
void PDB_addToGroup(int32_t id, int32_t groupId) { PDB_HANDLE h; PDB_profile r; int n; /* sanity check arguments */ CODA_ASSERT(PDB_ISGROUP(groupId) && (id != 0)); h = PDB_db_open(O_RDWR); /* add id to the group's member list */ PDB_readProfile(h, groupId, &r); CODA_ASSERT(r.id != 0); /* make sure we don't introduce an infinite loop */ n = pdb_array_search(&(r.cps), id); if (n != -1) { fprintf(stderr, "Cannot add %d, it is already a parent of %d\n", id, groupId); PDB_freeProfile(&r); return; } pdb_array_add(&(r.groups_or_members), id); PDB_writeProfile(h, &r); PDB_freeProfile(&r); /* add groupId to user's member_of list */ PDB_readProfile(h, id, &r); CODA_ASSERT(r.id != 0); pdb_array_add(&(r.member_of), groupId); PDB_updateCps(h, &r); PDB_freeProfile(&r); PDB_db_close(h); }
void PDB_changeId(int32_t oldId, int32_t newId) { PDB_HANDLE h; PDB_profile r,p; void *tmp; size_t size; int32_t nextid; pdb_array_off off; if (oldId == newId) return; h = PDB_db_open(O_RDWR); PDB_db_read(h, newId, NULL, &tmp, &size); pdb_unpack(&r, tmp, size); CODA_ASSERT(r.id == 0); PDB_readProfile(h, oldId, &r); CODA_ASSERT(r.id != 0); /* Delete the old id */ PDB_deleteProfile(h, &r); /* Change the id */ r.id = newId; PDB_updateCps(h, &r); if(PDB_ISGROUP(oldId)){ /* Need to change owner info */ PDB_readProfile(h, r.owner_id, &p); CODA_ASSERT(p.id != 0); pdb_array_del(&(p.groups_or_members), oldId); pdb_array_add(&(p.groups_or_members), newId); PDB_writeProfile(h, &p); PDB_db_update_maxids(h, 0, newId, PDB_MAXID_SET); PDB_freeProfile(&p); } else PDB_db_update_maxids(h, newId, 0, PDB_MAXID_SET); /* update groups we are a member of */ nextid = pdb_array_head(&(r.member_of), &off); while(nextid != 0){ PDB_readProfile(h, nextid, &p); CODA_ASSERT(p.id != 0); pdb_array_del(&(p.groups_or_members), oldId); pdb_array_add(&(p.groups_or_members), newId); /* Don't need CPS updates */ PDB_writeProfile(h, &p); PDB_freeProfile(&p); nextid = pdb_array_next(&(r.member_of), &off); } /* update members or ownership */ nextid = pdb_array_head(&(r.groups_or_members), &off); while(nextid != 0) { PDB_readProfile(h, nextid, &p); CODA_ASSERT(p.id != 0); if (PDB_ISGROUP(oldId)) { pdb_array_del(&(p.member_of), oldId); pdb_array_add(&(p.member_of), newId); } else { if (PDB_ISGROUP(p.id)) { if(p.owner_id == oldId) p.owner_id = newId; } } PDB_updateCps(h, &p); PDB_freeProfile(&p); nextid = pdb_array_next(&(r.groups_or_members), &off); } PDB_db_close(h); PDB_freeProfile(&r); }
void PDB_bugfixes(void) { PDB_HANDLE h; /* fixups for old bugs */ int32_t id; pdb_array_off off; int rc, n; PDB_profile p, r; h = PDB_db_open(O_RDWR); while ( (rc = PDB_db_nextkey(h, &id)) ) { if ( rc == -1 ) continue; PDB_readProfile(h, id, &p); CODA_ASSERT(p.id != 0); if (PDB_ISGROUP(p.id)) { /* BUG: forgot to update owner_id when changing a user's uid */ PDB_lookupByName(p.owner_name, &id); if (p.owner_id != id) { fprintf(stderr, "Group %d owner name %s didn't match owner id %d, FIXED\n", p.id, p.owner_name, p.owner_id); p.owner_id = id; PDB_writeProfile(h, &p); } /* BUG: we added userid's to a group's member_of list */ again: id = pdb_array_head(&p.member_of, &off); while(id != 0) { if (PDB_ISUSER(id)) { pdb_array_del(&p.member_of, id); PDB_updateCps(h, &p); fprintf(stderr, "Group %d was listed as a member of userid %d, FIXED\n", p.id, id); goto again; } id = pdb_array_next(&p.member_of, &off); } /* BUG: we forgot to change userid's in a group's groups_or_members * list (fix part 1, removes non-existing or non-member * userids) */ again2: id = pdb_array_head(&p.groups_or_members, &off); while(id != 0) { if (PDB_ISUSER(id)) { PDB_readProfile(h, id, &r); CODA_ASSERT(r.id != 0); n = pdb_array_search(&r.member_of, p.id); if (n == -1) { pdb_array_del(&p.groups_or_members, id); PDB_updateCps(h, &p); PDB_freeProfile(&r); fprintf(stderr, "Group %d had nonexisting member %d, FIXED\n", p.id, id); goto again2; } PDB_freeProfile(&r); } id = pdb_array_next(&p.groups_or_members, &off); } } else /* PDB_ISUSER(p.id) */ { /* BUG: we forgot to change userid's in a group's groups_or_members * list (fix part 2, adds missing members to groups)*/ id = pdb_array_head(&p.member_of, &off); while (id != 0) { if (PDB_ISGROUP(id)) { PDB_readProfile(h, id, &r); CODA_ASSERT(r.id != 0); n = pdb_array_search(&r.groups_or_members, p.id); if (n == -1) { pdb_array_add(&r.groups_or_members, p.id); PDB_updateCps(h, &r); fprintf(stderr, "Group %d was missing member %d, FIXED\n", id, p.id); } PDB_freeProfile(&r); } id = pdb_array_next(&p.member_of, &off); } } PDB_freeProfile(&p); } PDB_db_close(h); /* iterate through the whole database again and this time make sure that * all the CPS arrays are consistent. */ h = PDB_db_open(O_RDWR); while ( (rc = PDB_db_nextkey(h, &id)) ) { if ( rc == -1 ) continue; PDB_readProfile(h, id, &p); if (p.id == 0) continue; PDB_updateCps(h, &p); PDB_freeProfile(&p); } PDB_db_close(h); }