X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/blobdiff_plain/9d08cc9804c96ab96d9f6885e615deef750891c7..refs/heads/LOCKING:/afssync/ptutils.c diff --git a/afssync/ptutils.c b/afssync/ptutils.c index cc413a8f..4cad2a79 100644 --- a/afssync/ptutils.c +++ b/afssync/ptutils.c @@ -83,7 +83,7 @@ static long CorrectGroupName (ut, aname, cid, oid, cname) struct prentry tentry; if (strlen (aname) >= PR_MAXNAMELEN) return PRBADNAM; - admin = pr_noAuth || IsAMemberOf (ut, cid, SYSADMINID); + admin = pr_noAuth || (cid==SYSADMINID) || IsAMemberOf(ut, cid, SYSADMINID); if (oid == 0) oid = cid; @@ -1045,6 +1045,79 @@ long Initdb() return PRSUCCESS; } +/* + * FUNCTION + * fixOwnerChain + * + * DESCRIPTION + * This function follows the "owned" and "nextOwned" chains and verifies + * that the data is consistent. The chain is only traversed as far as is + * necessary for efficiency reasons: + * o Follow the "nextOwned" chain only if we had to adjust ourself + * (either renaming ourself or adjusting the owner id) + * o Follow the "owned" chain if we had to adjust ourself (see above), or + * we are the parent that started this mess (tentry->id == oldid/newid) + */ + +long fixOwnerChain(at,loc,tentry,oldid,newid) + struct ubik_trans *at; + struct prentry *tentry; + long loc, oldid, newid; +{ + char name[PR_MAXNAMELEN]; + struct prentry nentry; + long pos; + register long code; + int nextOwn = 0; + + if (newid && oldid != newid) { + if (tentry->owner == oldid) tentry->owner = newid; + if (tentry->creator == oldid) tentry->creator = newid; + + /* If our owner has changed, continue along the nextOwned chain */ + if (tentry->owner == newid) nextOwn=1; + } + + strcpy(name, tentry->name); + code=CorrectGroupName(at,name,tentry->creator,tentry->owner,tentry->name); + if (code) return code; + if (strcmp(name, tentry->name)) { + + /* If we had to rename ourself, there are probably others + * along the nextOwned chain that have to do the same. */ + nextOwn = 1; + + pos = FindByName(at,tentry->name); + if (pos) return PREXIST; + + code = RemoveFromNameHash (at, name, &loc); + if (code) return code; + code = AddToNameHash(at,tentry->name,loc); + if (code) return code; + } + + code = pr_WriteEntry(at, 0, loc, tentry); + if (code) return code; + + if ((loc = tentry->owned) && + (nextOwn || (newid && tentry->id == newid) || (tentry->id == oldid))) { + + code = pr_ReadEntry(at,0,loc,&nentry); + if (code) return code; + code = fixOwnerChain(at, loc, &nentry, oldid, newid); + if (code) return code; + } + + if (nextOwn && (loc = tentry->nextOwned)) { + + code = pr_ReadEntry(at,0,loc,&nentry); + if (code) return code; + code = fixOwnerChain(at, loc, &nentry, oldid, newid); + if (code) return code; + } + return PRSUCCESS; +} + long ChangeEntry (at, aid, cid, name, oid, newid) struct ubik_trans *at; long aid; @@ -1053,9 +1126,10 @@ long ChangeEntry (at, aid, cid, name, oid, newid) long oid; long newid; { - register long code; + register long code, nptr, i; long pos; - struct prentry tentry; + struct prentry tentry, gentry; + struct contentry centry; long loc; long oldowner; char holder[PR_MAXNAMELEN]; @@ -1096,6 +1170,43 @@ long ChangeEntry (at, aid, cid, name, oid, newid) /* get current data */ code = pr_ReadEntry(at,0,loc,&tentry); if (code) return PRDBFAIL; + + for (i=0;i