]> andersk Git - moira.git/commitdiff
Initial revision
authormar <mar>
Sat, 23 Sep 1989 18:44:04 +0000 (18:44 +0000)
committermar <mar>
Sat, 23 Sep 1989 18:44:04 +0000 (18:44 +0000)
afssync/ptutils.c [new file with mode: 0644]
afssync/ubik.c [new file with mode: 0644]
afssync/utils.c [new file with mode: 0644]

diff --git a/afssync/ptutils.c b/afssync/ptutils.c
new file mode 100644 (file)
index 0000000..b52af94
--- /dev/null
@@ -0,0 +1,771 @@
+/* $Header$ */
+/* $Source$ */
+
+
+/*
+ * P_R_P_Q_# (C) COPYRIGHT IBM CORPORATION 1988
+ * LICENSED MATERIALS - PROPERTY OF IBM
+ * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
+ */
+
+/*     
+             Sherri Nichols
+             Information Technology Center
+       November, 1988
+
+       Modified May, 1989 by Jeff Schiller to keep disk file in
+       network byte order
+
+*/
+
+#include <stdio.h>
+#include <strings.h>
+#include <lock.h>
+#include <ubik.h>
+#include <rx/xdr.h>
+#include "print.h"
+#include "prserver.h"
+#include "prerror.h"
+#include <netinet/in.h>
+
+extern struct prheader cheader;
+extern struct ubik_dbase *dbase;
+extern struct afsconf_dir *prdir;
+
+long CreateEntry(at, aname, aid, idflag,flag,oid,creator)  
+register struct ubik_trans *at;
+char aname[PR_MAXNAMELEN];
+long *aid;
+long idflag;
+long flag;
+long oid;
+long creator;
+{
+    /* get and init a new entry */
+    register long code;
+    long newEntry;
+    long temp;
+    struct prentry tentry;
+    
+    bzero(&tentry, sizeof(tentry));
+    newEntry = AllocBlock(at);
+    if (!newEntry) return PRDBFAIL;
+    if (flag & PRGRP) {
+       tentry.flags |= PRGRP;
+       tentry.owner = oid;
+    }
+    else if (flag & PRFOREIGN) {
+       tentry.flags |= PRFOREIGN;
+       tentry.owner = oid;
+    }
+    else tentry.owner = SYSADMINID;
+    if (idflag) 
+       tentry.id = *aid;
+    else {
+       code= AllocID(at,flag,&tentry.id);
+       if (code != PRSUCCESS) return code;
+    }
+    if (flag & PRGRP) {
+       if (tentry.id < ntohl(cheader.maxGroup)) {
+           cheader.maxGroup = htonl(tentry.id);
+           code = pr_Write(at,0,16,(char *) &cheader.maxGroup,sizeof(cheader.maxGroup));
+           if (code) return PRDBFAIL;
+       }
+    }
+    else if (flag & PRFOREIGN) {
+       if (tentry.id > ntohl(cheader.maxForeign)) {
+           cheader.maxForeign = htonl(tentry.id);
+           code = pr_Write(at,0,24,(char *) &cheader.maxForeign,sizeof(cheader.maxForeign));
+           if (code) return PRDBFAIL;
+       }
+    }
+    else {
+       if (tentry.id > ntohl(cheader.maxID)) {
+           cheader.maxID = htonl(tentry.id);
+           code = pr_Write(at,0,20,(char *) &cheader.maxID,sizeof(cheader.maxID));
+           if (code) return PRDBFAIL;
+       }
+    }
+    tentry.creator = creator;
+    *aid = tentry.id;
+    strncpy(tentry.name, aname, PR_MAXNAMELEN);
+    code = pr_WriteEntry(at, 0, newEntry, &tentry);
+    if (code) return PRDBFAIL;
+    code = AddToIDHash(at,*aid,newEntry);
+    if (code != PRSUCCESS) return code;
+    code = AddToNameHash(at,aname,newEntry);
+    if (code != PRSUCCESS) return code;
+    if (tentry.flags & PRGRP) {
+       code = AddToOwnerChain(at,tentry.id,oid);
+       if (code) return code;
+    }
+    if (tentry.flags & PRGRP) {
+        temp = ntohl(cheader.groupcount) + 1;
+       cheader.groupcount = htonl(temp);
+       code = pr_Write(at,0,40,(char *)&cheader.groupcount,sizeof(cheader.groupcount));
+       if (code) return PRDBFAIL;
+    }
+    else if (tentry.flags & PRFOREIGN) {
+        temp = ntohl(cheader.foreigncount) + 1;
+       cheader.foreigncount = htonl(temp);
+       code = pr_Write(at,0,44,(char *)&cheader.foreigncount,sizeof(cheader.foreigncount));
+       if (code) return PRDBFAIL;
+    }
+    else if (tentry.flags & PRINST) {
+        temp = ntohl(cheader.instcount) + 1;
+       cheader.instcount = htonl(temp);
+       code = pr_Write(at,0,48,(char *)&cheader.instcount,sizeof(cheader.instcount));
+       if (code) return PRDBFAIL;
+    }
+    else {
+        temp = ntohl(cheader.usercount) + 1;
+       cheader.usercount = htonl(temp);
+       code = pr_Write(at,0,36,(char *)&cheader.usercount,sizeof(cheader.usercount));
+       if (code) return PRDBFAIL;
+    }
+    return PRSUCCESS;
+}
+    
+
+
+long RemoveFromEntry(at,aid,bid)
+register struct ubik_trans *at;
+register long aid;
+register long bid;
+{
+    /* remove aid from bid's entries list, freeing a continuation entry if appropriate */
+
+    register long code;
+    struct prentry tentry;
+    struct contentry centry;
+    struct contentry hentry;
+    long temp;
+    long first;
+    long i,j;
+    long nptr;
+    long hloc = 0;
+    
+    bzero(&hentry,sizeof(hentry));
+    temp = FindByID(at,bid);
+    code = pr_ReadEntry(at, 0, temp, &tentry);
+    if (code != 0) return code;
+    for (i=0;i<PRSIZE;i++) {
+       if (tentry.entries[i] == aid) {  
+           tentry.entries[i] = PRBADID;
+           tentry.count--;
+           code = pr_WriteEntry(at,0,temp,&tentry);
+            if (code != 0) return code;
+           return PRSUCCESS;
+       }
+       if (tentry.entries[i] == 0)   /* found end of list */
+           return PRNOENT;
+    }
+    if (tentry.next != NULL) {
+       nptr = tentry.next;
+       first = 1;
+       while (nptr != NULL) {
+           code = pr_ReadCoEntry(at,0,nptr,&centry);
+           if (code != 0) return code;
+           for (i=0;i<COSIZE;i++) {
+               if (centry.entries[i] == aid) {
+                   centry.entries[i] = PRBADID;
+                   tentry.count--;
+                   code = pr_WriteEntry(at,0,temp,&tentry);
+                   if (code) return PRDBFAIL;
+                   for (j=0;j<COSIZE;j++)
+                       if (centry.entries[j] != PRBADID && centry.entries[j] != 0) break;
+                   if (j == COSIZE) {   /* can free this block */
+                       if (first) {
+                           tentry.next = centry.next;
+                           code = pr_WriteEntry(at,0,temp,&tentry);
+                           if (code != 0) return code;
+                       }
+                       else {
+                           hentry.next = centry.next;
+                           code = pr_WriteCoEntry(at,0,hloc,(char *) &hentry);
+                           if (code != 0) return code;
+                       }
+                       code = FreeBlock(at,nptr);
+                       return code;
+                   }
+                   else { /* can't free it yet */
+                       code = pr_WriteCoEntry(at,0,nptr,&centry);
+                       if (code != 0) return code;
+                       return PRSUCCESS;
+                   }
+               }
+               if (centry.entries[i] == 0) return PRNOENT;
+           }
+           hloc = nptr;
+           nptr = centry.next;
+           bcopy(&centry,&hentry,sizeof(centry));
+       }
+    }
+    else return PRNOENT;
+    return PRSUCCESS;
+}
+
+long DeleteEntry(at,aid,cid)
+register struct ubik_trans *at;
+long aid;
+long cid;
+{
+    /* delete the entry aid, removing it from all groups, putting groups owned by it on orphan chain, and freeing the space */
+    register long code;
+    long temp;
+    long temp1;
+    struct prentry tentry;
+    struct contentry centry;
+    struct prentry nentry;
+    register long  i;
+    long nptr;
+    long noAuth;
+
+    noAuth = afsconf_GetNoAuthFlag(prdir);
+    bzero(&tentry,sizeof(tentry));
+    temp = FindByID(at,aid);
+    if (!temp) return PRNOENT;
+    code = pr_ReadEntry(at,0,temp,&tentry);
+    if (code != 0) return PRDBFAIL;
+    if (tentry.owner != cid && !IsAMemberOf(at,cid,SYSADMINID) && !IsAMemberOf(at,cid,tentry.owner) && !noAuth) return PRPERM;
+    for (i=0;i<PRSIZE;i++) {
+       if (tentry.entries[i] == 0) break;
+       RemoveFromEntry(at,aid,tentry.entries[i]);
+    }
+    nptr = tentry.next;
+    while (nptr != NULL) {
+       code = pr_ReadCoEntry(at,0,nptr,&centry);
+       if (code != 0) return PRDBFAIL;
+       for (i=0;i<COSIZE;i++) {
+           if (centry.entries[i] == 0) break;
+           RemoveFromEntry(at,aid,centry.entries[i]);
+       }
+       nptr = centry.next;
+    }
+    if (tentry.flags & PRGRP) {
+       if (FindByID(at,tentry.owner)) {
+           code = RemoveFromOwnerChain(at,aid,tentry.owner);
+           if (code) return code;
+       }
+       else {
+           code = RemoveFromOrphan(at,aid);
+           if (code) return code;
+       }
+    }
+    if (tentry.owned) {
+       nptr = tentry.owned;
+       while (nptr != NULL) {
+           code = pr_ReadEntry(at,0,nptr,&nentry);
+           if (code != 0) return PRDBFAIL;
+           if (nentry.id != aid)  /* don't add this entry to orphan chain! */
+               code = AddToOrphan(at,nentry.id);
+           nptr = nentry.nextOwned;
+       }
+    }
+    code = RemoveFromIDHash(at,tentry.id,&temp);
+    if (code != PRSUCCESS) return code;
+    code = RemoveFromNameHash(at,tentry.name,&temp);
+    if (code != PRSUCCESS) return code;
+   if (tentry.flags & PRGRP) {
+       temp1 = ntohl(cheader.groupcount) + 1;
+       cheader.groupcount = htonl(temp1);
+       code = pr_Write(at,0,40,(char *)&cheader.groupcount,sizeof(cheader.groupcount));
+       if (code) return PRDBFAIL;
+    }
+    else if (tentry.flags & PRFOREIGN) {
+       temp1 = ntohl(cheader.foreigncount) + 1;
+       cheader.foreigncount = htonl(temp1);
+       code = pr_Write(at,0,44,(char *)&cheader.foreigncount,sizeof(cheader.foreigncount));
+       if (code) return PRDBFAIL;
+    }
+    else if (tentry.flags & PRINST) {
+       temp1 = ntohl(cheader.instcount) + 1;
+       cheader.instcount = htonl(temp1);
+       code = pr_Write(at,0,48,(char *)&cheader.instcount,sizeof(cheader.instcount));
+       if (code) return PRDBFAIL;
+    }
+    else {
+       temp1 = ntohl(cheader.usercount) + 1;
+       cheader.usercount = htonl(temp1);
+       code = pr_Write(at,0,36,(char *)&cheader.usercount,sizeof(cheader.usercount));
+       if (code) return PRDBFAIL;
+    }
+    FreeBlock(at,temp);
+    return PRSUCCESS;
+}
+
+
+
+
+long AddToEntry(tt,entry,loc,aid)
+struct ubik_trans *tt;
+struct prentry entry;
+long loc;
+long aid;
+{
+    /* add aid to entry's entries list, alloc'ing a continuation block if needed */
+    register long code;
+    long i;
+    struct contentry nentry;
+    struct contentry aentry;
+    long nptr;
+    long last = 0;
+    long first = 0;
+    long cloc;
+    long slot = -1;
+
+    bzero(&nentry,sizeof(nentry));
+    bzero(&aentry,sizeof(aentry));
+    for (i=0;i<PRSIZE;i++) {
+       if (entry.entries[i] == aid)
+           return PRIDEXIST;
+       if (entry.entries[i] == PRBADID) { /* remember this spot */
+           first = 1;
+           slot = i;
+       }
+       if (entry.entries[i] == 0) { /* end of the line */
+           if (slot == -1) {
+               first = 1;
+               slot = i;
+           }
+           break;
+       }
+    }
+    nptr = entry.next;
+    while (nptr != NULL) {
+       code = pr_ReadCoEntry(tt,0,nptr,&nentry);
+       if (code != 0) return code;
+       if (!(nentry.flags & PRCONT)) return PRDBFAIL;
+       for (i=0;i<COSIZE;i++) {
+           if (nentry.entries[i] == aid)
+               return PRIDEXIST;
+           if (nentry.entries[i] == PRBADID) {
+               if (slot == -1) {
+                   slot = i;
+                   cloc = nptr;
+               }
+           }
+           if (nentry.entries[i] == 0) {
+               if (slot == -1) {
+                   slot = i;
+                   cloc = nptr;
+               }
+               break;
+           }
+       }
+       last = nptr;
+       nptr = nentry.next;
+    }
+    if (slot != -1) {  /* we found a place */
+       entry.count++;
+       if (first) {  /* place is in first block */
+           entry.entries[slot] = aid;
+           code = pr_WriteEntry(tt,0,loc,&entry);
+           if (code != 0) return code;
+           return PRSUCCESS;
+       }
+       code = pr_WriteEntry(tt,0,loc,&entry);
+       code = pr_ReadCoEntry(tt,0,cloc,&aentry);
+       if (code != 0) return code;
+       aentry.entries[slot] = aid;
+       code = pr_WriteCoEntry(tt,0,cloc,&aentry);
+       if (code != 0) return code;
+       return PRSUCCESS;
+    }
+    /* have to allocate a continuation block if we got here */
+    nptr = AllocBlock(tt);
+    if (nentry.flags & PRCONT) {
+       /* then we should tack new block here */
+       nentry.next = nptr;
+       code = pr_WriteCoEntry(tt,0,last,&nentry);
+       if (code != 0) return code;
+    }
+    else {
+       entry.next = nptr;
+       code = pr_WriteEntry(tt,0,loc,&entry);
+       if (code != 0) return code;
+    }
+    aentry.flags |= PRCONT;
+    aentry.id = entry.id;
+    aentry.next = NULL;
+    aentry.entries[0] = aid;
+    code = pr_WriteCoEntry(tt,0,nptr,&aentry);
+    if (code != 0) return code;
+    /* don't forget to update count, here! */
+    entry.count++;
+    code = pr_WriteEntry(tt,0,loc,&entry);
+    return PRSUCCESS;
+       
+}
+
+long GetList(at,aid,alist,add)
+struct ubik_trans *at;
+long aid;
+prlist *alist;
+long add;
+{
+    register long code;
+    long temp;
+    long i;
+    long count;
+    struct prentry tentry;
+    struct contentry centry;
+    long nptr;
+    long size;
+    extern long IDCmp();
+
+    temp = FindByID(at,aid);
+    if (!temp) return PRNOENT;
+    code = pr_ReadEntry(at,0,temp,&tentry);
+    if (code != 0) return code;
+    alist->prlist_val = (long *)malloc(100*sizeof(long));
+    size = 100;
+    alist->prlist_len = 0;
+    count = 0;
+    for (i=0;i<PRSIZE;i++) {
+       if (tentry.entries[i] == PRBADID) continue;
+       if (tentry.entries[i] == 0) break;
+       alist->prlist_val[count]= tentry.entries[i];
+       count++;
+       alist->prlist_len++;
+    }
+    nptr = tentry.next;
+    while (nptr != NULL) {
+       /* look through cont entries */
+       code = pr_ReadCoEntry(at,0,nptr,&centry);
+       if (code != 0) return code;
+       for (i=0;i<COSIZE;i++) {
+           if (centry.entries[i] == PRBADID) continue;
+           if (centry.entries[i] == 0) break;
+           if (alist->prlist_len >= size) {
+               alist->prlist_val = (long *)realloc(alist->prlist_val,(size+100)*sizeof(long));
+               size += 100;
+           }
+           alist->prlist_val[count] = centry.entries[i];
+           count++;
+           alist->prlist_len++;
+       }
+       nptr = centry.next;
+    }
+    if (add) { /* this is for a CPS, so tack on appropriate stuff */
+       if (aid != ANONYMOUSID && aid != ANYUSERID) {
+           if (alist->prlist_len >= size)
+               alist->prlist_val = (long *)realloc(alist->prlist_val,(size + 3)*sizeof(long));
+           alist->prlist_val[count] = ANYUSERID;
+           count++;
+           alist->prlist_val[count] = AUTHUSERID;
+           count++;
+           alist->prlist_val[count] = aid;
+           count++;
+           alist->prlist_len += 3;
+       }
+       else {
+           if (alist->prlist_len >= size)
+               alist->prlist_val = (long *)realloc(alist->prlist_val,(size + 2)*sizeof(long));
+           alist->prlist_val[count] = ANYUSERID;
+           count++;
+           alist->prlist_val[count] = aid;
+           count++;
+           alist->prlist_len += 2;
+       }
+    }
+    qsort(alist->prlist_val,alist->prlist_len,sizeof(long),IDCmp);
+    return PRSUCCESS;
+}
+
+long GetMax(at,uid,gid)
+register struct ubik_trans *at;
+long *uid;
+long *gid;
+{
+    *uid = ntohl(cheader.maxID);
+    *gid = ntohl(cheader.maxGroup);
+    return PRSUCCESS;
+}
+
+long SetMax(at,id,flag)
+register struct ubik_trans *at;
+long id;
+long flag;
+{
+    register long code;
+    if (flag & PRGRP) {
+       cheader.maxGroup = htonl(id);
+       code = pr_Write(at,0,16,(char *)&cheader.maxGroup,sizeof(cheader.maxGroup));
+       if (code != 0) return code;
+    }
+    else {
+       cheader.maxID = htonl(id);
+       code = pr_Write(at,0,20,(char *)&cheader.maxID,sizeof(cheader.maxID));
+       if (code != 0) return code;
+    }
+    return PRSUCCESS;
+}
+
+Initdb()
+{
+    long code;
+    struct ubik_trans *tt;
+    long len;
+    long temp;
+    long flag = 0;
+    static long initd=0;
+    static struct ubik_version curver;
+    struct ubik_version newver;
+
+    /* init the database.  We'll try reading it, but if we're starting from scratch, we'll have to do a write transaction. */
+
+    code = ubik_BeginTrans(dbase,UBIK_READTRANS, &tt);
+    if (code) return code;
+    code = ubik_SetLock(tt,1,1,LOCKREAD);
+    if (code) {
+       ubik_AbortTrans(tt);
+       return code;
+    }
+    if (!initd) {
+       initd = 1;
+       bzero(&curver,sizeof(curver));
+    }
+    code = ubik_GetVersion(tt,&newver);
+    if (vcmp(curver,newver) == 0) {
+       /* same version */
+       code = ubik_EndTrans(tt);
+       if (code) return code;
+       return PRSUCCESS;
+    }
+    bcopy(&newver,&curver,sizeof(struct ubik_version));
+    len = sizeof(cheader);
+    code = pr_Read(tt, 0, 0, (char *) &cheader, len);
+    if (code != 0) {
+       printf("prserver: couldn't read header -code is %d\n",code);
+       ubik_AbortTrans(tt);
+       return code;
+    }
+    if (ntohl(cheader.headerSize) == sizeof(cheader) && ntohl(cheader.eofPtr) != NULL && FindByID(tt,ANONYMOUSID) != 0){
+       /* database exists, so we don't have to build it */
+       code = ubik_EndTrans(tt);
+       if (code) return code;
+       return PRSUCCESS;
+    }
+    /* else we need to build a database */
+    code = ubik_EndTrans(tt);
+    if (code) return code;
+    code = ubik_BeginTrans(dbase,UBIK_WRITETRANS, &tt);
+    if (code) return code;
+    code = ubik_SetLock(tt,1,1,LOCKWRITE);
+    if (code) {
+       ubik_AbortTrans(tt);
+       return code;
+    }
+    cheader.headerSize = htonl(sizeof(cheader));
+    code = pr_Write(tt,0,4,(char *)&cheader.headerSize,sizeof(cheader.headerSize));
+    if (code != 0) {
+       printf("prserver:  couldn't write header size - code is %d.\n",code);
+       ubik_AbortTrans(tt);
+       return code;
+    }
+    cheader.eofPtr = cheader.headerSize; /* already in network order! */
+    code = pr_Write(tt,0,12,(char *)&cheader.eofPtr,sizeof(cheader.eofPtr));
+    if (code != 0) {
+       printf("prserver:  couldn't write eof Ptr - code is %d.\n",code);
+       ubik_AbortTrans(tt);
+       return code;
+    }
+    temp = SYSADMINID;
+    if (FindByID(tt,SYSADMINID) == 0) {
+       /* init sysadmin */
+       flag |= PRGRP;
+       code = CreateEntry(tt,"system:administrators",&temp,1,flag,SYSADMINID,SYSADMINID);
+       if (code != PRSUCCESS) {
+           printf("prserver: couldn't create system:administrators.\n");
+           ubik_AbortTrans(tt);
+           return code;
+       }
+       flag = 0;
+    }
+    temp = ANYUSERID;
+    if ( FindByID(tt,temp) == 0) { /* init sysadmin */
+       flag |= PRGRP;
+       code = CreateEntry(tt,"system:anyuser",&temp,1,flag,SYSADMINID,SYSADMINID);
+       if (code != PRSUCCESS) {
+           printf("prserver:  couldn't create system:anyuser.\n");
+           ubik_AbortTrans(tt);
+           return code;
+       }
+       flag = 0;
+    }
+    temp = AUTHUSERID;
+    if (FindByID(tt,temp) == 0) { /* init sysadmin */
+       flag |= PRGRP;
+       code = CreateEntry(tt,"system:authuser",&temp,1,flag,SYSADMINID,SYSADMINID);
+       if (code != PRSUCCESS) {
+           printf("prserver:  couldn't create system:authuser.\n");
+           ubik_AbortTrans(tt);
+           return code;
+       }
+       flag = 0;
+    }
+    temp = ANONYMOUSID;
+    if (FindByID(tt,temp) == 0) { /* init sysadmin */
+       code = CreateEntry(tt,"anonymous",&temp,1,flag,SYSADMINID,SYSADMINID);
+       if (code != PRSUCCESS) {
+           printf("prserver:  couldn't create anonymous.\n");
+           ubik_AbortTrans(tt);
+           return code;
+       }
+       /* well, we don't really want the max id set to anonymousid, so we'll set it back to 0 */
+       cheader.maxID = 0; /* Zero is in correct byte order no matter what! */
+       code = pr_Write(tt,0,20,(char *)&cheader.maxID,sizeof(cheader.maxID));
+       if (code) {
+           printf("prserver: couldn't set max id - code is %d.\n");
+           ubik_AbortTrans(tt);
+           return code;
+       }
+    }
+    code = ubik_EndTrans(tt);
+    if (code) return code;
+    return PRSUCCESS;
+}
+
+long NameToID(at, aname, aid)
+register struct ubik_trans *at;
+char aname[PR_MAXNAMELEN];
+long *aid;
+{
+    register long code;
+    long temp;
+    struct prentry tentry;
+
+    temp = FindByName(at,aname);
+    if (!temp) return PRNOENT;
+    code = pr_ReadEntry(at, 0, temp, &tentry);
+    if (code != 0) return code;
+    *aid = tentry.id;
+    return PRSUCCESS;
+}
+
+long IDToName(at, aid, aname)
+register struct ubik_trans *at;
+long aid;
+char aname[PR_MAXNAMELEN];
+{
+    long temp;
+    struct prentry tentry;
+    register long code;
+
+    temp = FindByID(at,aid);
+    if (!temp) return PRNOENT;
+    code = pr_ReadEntry(at,0,temp,&tentry);
+    if (code != 0) return code;
+    strncpy(aname,tentry.name,PR_MAXNAMELEN);
+    return PRSUCCESS;
+}
+
+long ChangeEntry(at, aid,cid,name,oid,newid)
+struct ubik_trans *at;
+long aid;
+long cid;
+char *name;
+long oid;
+long newid;
+{
+    register long code;
+    long pos;
+    struct prentry tentry;
+    long loc;
+    long noAuth;
+    char *check;
+    long tid;
+    char holder[PR_MAXNAMELEN];
+    char temp[PR_MAXNAMELEN];
+
+    noAuth = afsconf_GetNoAuthFlag(prdir);
+    bzero(holder,PR_MAXNAMELEN);
+    bzero(temp,PR_MAXNAMELEN);
+    loc = FindByID(at,aid);
+    if (!loc) return PRNOENT;
+    code = pr_ReadEntry(at,0,loc,&tentry);
+    if (code) return PRDBFAIL;
+    if (tentry.owner != cid && !IsAMemberOf(at,cid,SYSADMINID) && !IsAMemberOf(at,cid,tentry.owner) && !noAuth)
+       return PRPERM;
+    if (aid != newid && newid != 0) { /* then we're actually trying to change the id */
+       pos = FindByID(at,newid);
+       if (pos) return PRIDEXIST;  /* new id already in use! */
+       if ((aid < 0 && newid) > 0 || (aid > 0 && newid < 0)) return PRPERM;
+       /* if new id is not in use, rehash things */
+       code = RemoveFromIDHash(at,aid,&loc);
+       if (code != PRSUCCESS) return code;
+       tentry.id = newid;
+       code = pr_WriteEntry(at,0,loc,&tentry);
+       code = AddToIDHash(at,tentry.id,loc);
+       if (code) return code;
+    }
+    if (tentry.owner != oid && oid) {
+       if (tentry.flags & PRGRP) {
+           /* switch owner chains before we lose old owner */
+           if (FindByID(at,tentry.owner)) /* if it has an owner */
+               code = RemoveFromOwnerChain(at,tentry.id,tentry.owner);
+           else  /* must be an orphan */
+               code = RemoveFromOrphan(at,tentry.id);
+           if (code) return code;
+           code = AddToOwnerChain(at,tentry.id,oid);
+           if (code) return code;
+       }
+       tentry.owner = oid;
+       if ((tentry.flags & PRGRP) && (strlen(name) == 0)) {
+           /* if we change the owner of a group, it's name will change as well */
+           if (tentry.owner < 0) {
+               code = IDToName(at,tentry.owner,temp);
+               if (code) return code;
+               check = index(temp,':');
+               strncpy(holder,temp,check - temp);
+           }
+           else {
+               code = IDToName(at,tentry.owner,holder);
+               if (code) return code;
+           }
+           strncat(holder,":",PR_MAXNAMELEN);
+           /* now the rest of the name */
+           check = index(tentry.name,':');
+           strncat(holder,++check,PR_MAXNAMELEN);
+           if (strcmp(holder,tentry.name)) {
+               /* then the name really did change */
+               pos = FindByName(at,holder);
+               if (pos) return PREXIST;
+               code = RemoveFromNameHash(at,tentry.name,&loc);
+               if (code != PRSUCCESS) return code;
+               strncpy(tentry.name,holder,PR_MAXNAMELEN);
+               code = AddToNameHash(at,tentry.name,loc);
+               if (code != PRSUCCESS) return code;
+           }
+       }
+       code = pr_WriteEntry(at,0,loc,&tentry);
+       if (code) return PRDBFAIL;
+    }
+    if ((strcmp(tentry.name,name)) && (strlen(name)!= 0)) {
+       if (tentry.flags & PRGRP) {
+           if ((check = index(name,':')) == NULL) return PRBADNAM;
+           strncpy(temp,name,check-name);
+           code = NameToID(at,temp,&tid);
+           if (tid != tentry.owner) return PRPERM;
+       }
+       else
+           /* if it's not a group, shouldn't have a : in it */
+           if ((check = index(name,':')) != NULL) 
+               return PRBADNAM;
+       pos = FindByName(at,name);
+       if (pos) return PREXIST;
+       code = RemoveFromNameHash(at,tentry.name,&loc);
+       if (code != PRSUCCESS) return code;
+       strncpy(tentry.name,name,PR_MAXNAMELEN);
+       code = pr_WriteEntry(at,0,loc,&tentry);
+       if (code) return PRDBFAIL;
+       code = AddToNameHash(at,tentry.name,loc);
+       if (code != PRSUCCESS) return code;
+    }
+    return PRSUCCESS;
+}
+
+       
+
+    
diff --git a/afssync/ubik.c b/afssync/ubik.c
new file mode 100644 (file)
index 0000000..07fa2d3
--- /dev/null
@@ -0,0 +1,98 @@
+/* $Header$ */
+
+#include <sys/types.h>
+#include <lock.h>
+#define UBIK_INTERNALS
+#include <ubik.h>
+#include <rx/xdr.h>
+#include "print.h"
+#include "prserver.h"
+
+
+struct ubik_dbase *dbase;
+
+long ubik_BeginTrans()
+{
+    return(0);
+}
+
+long ubik_SetLock()
+{
+    return(0);
+}
+
+long ubik_AbortTrans()
+{
+    return(0);
+}
+
+long ubik_GetVersion(dummy, ver)
+int dummy;
+struct ubik_version *ver;
+{
+    bzero(ver, sizeof(struct ubik_version));
+    return(0);
+}
+
+long ubik_EndTrans()
+{
+    return(0);
+}
+
+
+extern int dbase_fd;
+
+long ubik_Seek(tt, afd, pos)
+struct ubik_trans *tt;
+long afd;
+long pos;
+{
+    if (lseek(dbase_fd, pos+HDRSIZE, 0) < 0) {
+       perror("ubik_Seek");
+       return(-1);
+    }
+    return(0);
+}
+
+long ubik_Write(tt, buf, len)
+struct ubik_trans *tt;
+char *buf;
+long len;
+{
+    int status;
+
+    status = write(dbase_fd, buf, len);
+    if (status < len) {
+       perror("ubik_Write");
+       return(1);
+    }
+    return(0);
+}
+
+long ubik_Read(tt, buf, len)
+struct ubik_trans *tt;
+char *buf;
+long len;
+{
+    int status;
+    
+    status = read(dbase_fd, buf, len);
+    if (status < 0) {
+       perror("ubik_Read");
+       return(1);
+    }
+    if (status < len)
+      bzero(&buf[status], len - status);
+    return(0);
+}
+
+
+char *prdir = "/dev/null";
+
+afsconf_GetNoAuthFlag()
+{
+    return(1);
+}
+
+
+struct prheader cheader;
diff --git a/afssync/utils.c b/afssync/utils.c
new file mode 100644 (file)
index 0000000..7f7a9db
--- /dev/null
@@ -0,0 +1,780 @@
+/* $Header$ */
+/* $Source$ */
+
+
+/*
+ * P_R_P_Q_# (C) COPYRIGHT IBM CORPORATION 1988
+ * LICENSED MATERIALS - PROPERTY OF IBM
+ * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
+ */
+
+/*     
+       Sherri Nichols
+       Information Technology Center
+       November, 1988
+
+       Modified May, 1989 by Jeff Schiller to keep disk file in
+       network byte order
+
+*/
+
+
+#include <sys/types.h>
+#include <lock.h>
+#include <ubik.h>
+#include <stdio.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <rx/xdr.h>
+#include <rx/rx.h>
+#include <rx/rx_vab.h>
+#include <rx/rxkad.h>
+#include "print.h"
+#include "prserver.h"
+#include "prerror.h"
+
+extern struct prheader cheader;
+extern struct ubik_dbase *dbase;
+
+long IDHash(x)
+long x;
+{
+    /* returns hash bucket for x */
+    return ((abs(x)) % HASHSIZE);
+}
+
+long NameHash(aname)
+register unsigned char *aname;
+{
+    /* returns hash bucket for aname */
+    register unsigned int hash=0;
+    register int i;
+/* stolen directly from the HashString function in the vol package */
+    for (i=strlen(aname),aname += i-1;i--;aname--)
+       hash = (hash*31) + (*aname-31);
+    return(hash % HASHSIZE);
+}
+
+
+long pr_Write(tt,afd,pos,buff,len)
+struct ubik_trans *tt;
+long afd;
+long pos;
+char *buff;
+long len;
+{
+    /* package up seek and write into one procedure for ease of use */
+    long code;
+    code = ubik_Seek(tt,afd,pos);
+    if (code) return code;
+    code = ubik_Write(tt,buff,len);
+    return code;
+}
+
+long pr_Read(tt,afd,pos,buff,len)
+struct ubik_trans *tt;
+long afd;
+long pos;
+char *buff;
+long len;
+{
+    /* same thing for read */
+    long code;
+    code = ubik_Seek(tt,afd,pos);
+    if (code) return code;
+    code = ubik_Read(tt,buff,len);
+    return code;
+}
+
+pr_WriteEntry(tt, afd, pos, tentry)
+struct ubik_trans *tt;
+long afd;
+long pos;
+struct prentry *tentry;
+{
+    long code;
+    register long i;
+    struct prentry nentry;
+    if (ntohl(1) != 1) {       /* Need to swap bytes. */
+      nentry.flags = htonl(tentry->flags);
+      nentry.id = htonl(tentry->id);
+      nentry.cellid = htonl(tentry->cellid);
+      nentry.next = htonl(tentry->next);
+      nentry.nextID = htonl(tentry->nextID);
+      nentry.nextName = htonl(tentry->nextName);
+      nentry.owner = htonl(tentry->owner);
+      nentry.creator = htonl(tentry->creator);
+      nentry.ngroups = htonl(tentry->ngroups);
+      nentry.nusers = htonl(tentry->nusers);
+      nentry.count = htonl(tentry->count);
+      nentry.instance = htonl(tentry->instance);
+      nentry.owned = htonl(tentry->owned);
+      nentry.nextOwned = htonl(tentry->nextOwned);
+      nentry.parent = htonl(tentry->parent);
+      nentry.sibling = htonl(tentry->sibling);
+      nentry.child = htonl(tentry->child);
+      strncpy(nentry.name, tentry->name, PR_MAXNAMELEN);
+      for (i = 0; i < PRSIZE; i++)
+       nentry.entries[i] = htonl(tentry->entries[i]);
+      code = ubik_Seek(tt, afd, pos);
+      if (code) return (code);
+      code = ubik_Write(tt, (char *) &nentry, sizeof(struct prentry));
+      return(code);
+    } else {
+      code = ubik_Seek(tt, afd, pos);
+      if (code) return (code);
+      code = ubik_Write(tt, (char *) tentry, sizeof(struct prentry));
+      return(code);
+    }
+}
+
+pr_ReadEntry(tt, afd, pos, tentry)
+struct ubik_trans *tt;
+long afd;
+long pos;
+struct prentry *tentry;
+{
+    long code;
+    register long i;
+    struct prentry nentry;
+    code = ubik_Seek(tt, afd, pos);
+    if (code) return (code);
+    if (ntohl(1) == 1) {       /* no swapping needed */
+      code = ubik_Read(tt, (char *) tentry, sizeof(struct prentry));
+      return(code);
+    }
+    code = ubik_Read(tt, (char *) &nentry, sizeof(struct prentry));
+    if (code) return (code);
+    tentry->flags = ntohl(nentry.flags);
+    tentry->id = ntohl(nentry.id);
+    tentry->cellid = ntohl(nentry.cellid);
+    tentry->next = ntohl(nentry.next);
+    tentry->nextID = ntohl(nentry.nextID);
+    tentry->nextName = ntohl(nentry.nextName);
+    tentry->owner = ntohl(nentry.owner);
+    tentry->creator = ntohl(nentry.creator);
+    tentry->ngroups = ntohl(nentry.ngroups);
+    tentry->nusers = ntohl(nentry.nusers);
+    tentry->count = ntohl(nentry.count);
+    tentry->instance = ntohl(nentry.instance);
+    tentry->owned = ntohl(nentry.owned);
+    tentry->nextOwned = ntohl(nentry.nextOwned);
+    tentry->parent = ntohl(nentry.parent);
+    tentry->sibling = ntohl(nentry.sibling);
+    tentry->child = ntohl(nentry.child);
+    strncpy(tentry->name, nentry.name, PR_MAXNAMELEN);
+    for (i = 0; i < PRSIZE; i++)
+      tentry->entries[i] = ntohl(nentry.entries[i]);
+    return(code);
+}
+
+pr_WriteCoEntry(tt, afd, pos, tentry)
+struct ubik_trans *tt;
+long afd;
+long pos;
+struct contentry *tentry;
+{
+    long code;
+    register long i;
+    struct contentry nentry;
+    if (ntohl(1) == 1) {       /* No need to swap */
+      code = ubik_Seek(tt, afd, pos);
+      if (code) return(code);
+      code = ubik_Write(tt, (char *) tentry, sizeof(struct contentry));
+      return(code);
+    }
+    nentry.flags = htonl(tentry->flags);
+    nentry.id = htonl(tentry->id);
+    nentry.cellid = htonl(tentry->cellid);
+    nentry.next = htonl(tentry->next);
+    for (i = 0; i < COSIZE; i++)
+      nentry.entries[i] = htonl(tentry->entries[i]);
+    code = ubik_Seek(tt, afd, pos);
+    if (code) return (code);
+    code = ubik_Write(tt, (char *) &nentry, sizeof(struct contentry));
+    return(code);
+}
+
+pr_ReadCoEntry(tt, afd, pos, tentry)
+struct ubik_trans *tt;
+long afd;
+long pos;
+struct contentry *tentry;
+{
+    long code;
+    register long i;
+    struct contentry nentry;
+    code = ubik_Seek(tt, afd, pos);
+    if (code) return (code);
+    if (ntohl(1) == 1) {       /* No swapping needed. */
+      code = ubik_Read(tt, (char *) tentry, sizeof(struct contentry));
+      return(code);
+    }
+    code = ubik_Read(tt, (char *) &nentry, sizeof(struct contentry));
+    if (code) return (code);
+    tentry->flags = ntohl(nentry.flags);
+    tentry->id = ntohl(nentry.id);
+    tentry->cellid = ntohl(nentry.cellid);
+    tentry->next = ntohl(nentry.next);
+    for (i = 0; i < COSIZE; i++)
+      tentry->entries[i] = ntohl(nentry.entries[i]);
+    return(code);
+}
+
+long AllocBlock(at)
+register struct ubik_trans *at;
+{
+    /* allocate a free block of storage for entry, returning address of new entry  */
+    register long code;
+    long temp;
+    struct prentry tentry;
+
+    if (cheader.freePtr) {
+       /* allocate this dude */
+       temp = ntohl(cheader.freePtr);      
+       code = pr_ReadEntry(at, 0, temp, &tentry);
+       if (code) return 0;
+       cheader.freePtr = htonl(tentry.next);
+       code = pr_Write(at, 0, 8, (char *)&cheader.freePtr, sizeof(cheader.freePtr));
+       if (code != 0) return 0;
+       return temp;
+    }
+    else {
+       /* hosed, nothing on free list, grow file */
+       temp = ntohl(cheader.eofPtr);   /* remember this guy */
+       cheader.eofPtr = htonl(temp + ENTRYSIZE);
+       code = pr_Write(at, 0, 12,(char *) &cheader.eofPtr, sizeof(cheader.eofPtr));
+       if (code != 0) return 0;
+       return temp;
+    }
+}
+
+long FreeBlock(at, pos)
+register struct ubik_trans *at;
+long pos;
+{
+    /* add a block of storage to the free list */
+    register long code;
+    struct prentry tentry;
+
+    bzero(&tentry,sizeof(tentry));
+    tentry.next = ntohl(cheader.freePtr);
+    tentry.flags |= PRFREE;
+    cheader.freePtr = htonl(pos);
+    code = pr_Write(at,0,8, (char *) &cheader.freePtr,sizeof(cheader.freePtr));
+    if (code != 0) return code;
+    code = pr_WriteEntry(at,0,pos,&tentry);
+    if (code != 0) return code;
+    return PRSUCCESS;
+}
+
+long FindByID(at,aid)
+register struct ubik_trans *at;
+long aid;
+{
+    /* returns address of entry if found, 0 otherwise */
+    register long code;
+    long i;
+    struct prentry tentry;
+    long entry;
+
+    i = IDHash(aid);
+    entry = ntohl(cheader.idHash[i]);
+    if (entry == 0) return entry;
+    bzero(&tentry,sizeof(tentry));
+    code = pr_ReadEntry(at, 0, entry, &tentry);
+    if (code != 0) return 0;
+    if (aid == tentry.id) return entry;
+    entry = tentry.nextID;
+    while (entry != NULL) {
+       bzero(&tentry,sizeof(tentry));
+       code = pr_ReadEntry(at,0,entry,&tentry);
+       if (code != 0) return 0;
+       if (aid == tentry.id) return entry;
+       entry = tentry.nextID;
+    }
+    return 0;
+}
+
+
+long FindByName(at,aname)    
+register struct ubik_trans *at;
+char aname[PR_MAXNAMELEN];
+{
+    /* ditto */
+    register long code;
+    long i;
+    struct prentry tentry;
+    long entry;
+
+    i = NameHash(aname);
+    entry = ntohl(cheader.nameHash[i]);
+    if (entry == 0) return entry;
+    bzero(&tentry,sizeof(tentry));
+    code = pr_ReadEntry(at, 0, entry,&tentry);
+    if (code != 0) return 0;
+    if ((strncmp(aname,tentry.name,PR_MAXNAMELEN)) == 0) return entry;
+    entry = tentry.nextName;
+    while (entry != NULL) {
+       bzero(&tentry,sizeof(tentry));
+       code = pr_ReadEntry(at,0,entry,&tentry);
+       if (code != 0) return 0;
+       if ((strncmp(aname,tentry.name,PR_MAXNAMELEN)) == 0) return entry;
+       entry = tentry.nextName;
+    }
+    return 0;
+}
+
+long AllocID(at,flag,aid)
+register struct ubik_trans *at;
+long flag;
+long *aid;
+{
+    /* allocs an id from the proper area of address space, based on flag */
+    register long code = 1;
+    register long i = 0;
+    register maxcount = 50;  /* to prevent infinite loops */
+    
+    if (flag & PRGRP) {
+       *aid = ntohl(cheader.maxGroup);
+       while (code && i<maxcount) {
+           --(*aid);
+           code = FindByID(at,*aid);
+           i++;
+       }
+       if (code) return PRNOIDS;
+       cheader.maxGroup = htonl(*aid);
+       code = pr_Write(at,0,16,(char *)&cheader.maxGroup,sizeof(cheader.maxGroup));
+       if (code) return PRDBFAIL;
+       return PRSUCCESS;
+    }
+    else if (flag & PRFOREIGN) {
+       *aid = ntohl(cheader.maxForeign);
+       while (code && i<maxcount) {
+           ++(*aid);
+           code = FindByID(at,*aid);
+           i++;
+       }
+       if (code) return PRNOIDS;
+       cheader.maxForeign = htonl(*aid);
+       code = pr_Write(at,0,24,(char *)&cheader.maxForeign,sizeof(cheader.maxForeign));
+       if (code) return PRDBFAIL;
+       return PRSUCCESS;
+    }
+    else {
+       *aid = ntohl(cheader.maxID);
+       while (code && i<maxcount) {
+           ++(*aid);
+           code = FindByID(at,*aid);
+           i++;
+       }
+       if (code) return PRNOIDS;
+       cheader.maxID = htonl(*aid);
+       code = pr_Write(at,0,20,(char *)&cheader.maxID,sizeof(cheader.maxID));
+       if (code) return PRDBFAIL;
+       return PRSUCCESS;
+    }
+}
+
+long IDCmp(a,b)
+long *a;
+long *b;
+{
+    /* used to sort CPS's so that comparison with acl's is easier */
+    if (*a > *b) return 1;
+    if (*a == *b) return 0;
+    if (*a < *b) return -1;
+}
+
+long RemoveFromIDHash(tt,aid,loc)
+struct ubik_trans *tt;
+long aid;
+long *loc;
+{
+    /* remove entry designated by aid from id hash table */
+    register long code;
+    long current, trail, i;
+    struct prentry tentry;
+    struct prentry bentry;
+
+    i = IDHash(aid);
+    current = ntohl(cheader.idHash[i]);
+    bzero(&tentry,sizeof(tentry));
+    bzero(&bentry,sizeof(bentry));
+    trail = 0;
+    if (current == NULL) return PRNOENT;
+    code = pr_ReadEntry(tt,0,current,&tentry);
+    if (code) return PRDBFAIL;
+    while (aid != tentry.id) {
+       trail = current;
+       current = tentry.nextID;
+       if (current == NULL) break;
+       code = pr_ReadEntry(tt,0,current,&tentry);
+       if (code) return PRDBFAIL;
+    }
+    if (current == NULL) return PRNOENT;  /* we didn't find him */
+    if (trail == NULL) {
+       /* it's the first entry! */
+       cheader.idHash[i] = htonl(tentry.nextID);
+       code = pr_Write(tt,0,72+HASHSIZE*4+i*4,(char *)&cheader.idHash[i],sizeof(cheader.idHash[i]));
+       if (code) return PRDBFAIL;
+    }
+    else {
+       code = pr_ReadEntry(tt,0,trail, &bentry);
+       if (code) return PRDBFAIL;
+       bentry.nextID = tentry.nextID;
+       code = pr_WriteEntry(tt,0,trail,&bentry);
+    }
+    *loc = current;
+    return PRSUCCESS;
+}
+
+long AddToIDHash(tt, aid, loc)
+struct ubik_trans *tt;
+long aid;
+long loc;
+{
+    /* add entry at loc designated by aid to id hash table */
+    register long code;
+    long i;
+    struct prentry tentry;
+
+    i = IDHash(aid);
+    bzero(&tentry,sizeof(tentry));
+    code = pr_ReadEntry(tt,0,loc,&tentry);
+    if (code) return PRDBFAIL;
+    tentry.nextID = ntohl(cheader.idHash[i]);
+    cheader.idHash[i] = htonl(loc);
+    code = pr_WriteEntry(tt,0,loc,&tentry);
+    if (code) return PRDBFAIL;
+    code = pr_Write(tt,0,72+HASHSIZE*4+i*4,(char *)&cheader.idHash[i],sizeof(cheader.idHash[i]));
+    if (code) return PRDBFAIL;
+    return PRSUCCESS;
+}
+
+long RemoveFromNameHash(tt,aname,loc)
+struct ubik_trans *tt;
+char *aname;
+long *loc;
+{
+    /* remove from name hash */
+    register long code;
+    long current, trail, i;
+    struct prentry tentry;
+    struct prentry bentry;
+
+    i = NameHash(aname);
+    current = ntohl(cheader.nameHash[i]);
+    bzero(&tentry,sizeof(tentry));
+    bzero(&bentry,sizeof(bentry));
+    trail = 0;
+    if (current == NULL) return PRNOENT;
+    code = pr_ReadEntry(tt,0,current,&tentry);
+    if (code) return PRDBFAIL;
+    while (strcmp(aname,tentry.name)) {
+       trail = current;
+       current = tentry.nextName;
+       if (current == NULL) break;
+       code = pr_ReadEntry(tt,0,current,&tentry);
+       if (code) return PRDBFAIL;
+    }
+    if (current == NULL) return PRNOENT;  /* we dnamen't find him */
+    if (trail == NULL) {
+       /* it's the first entry! */
+       cheader.nameHash[i] = htonl(tentry.nextName);
+       code = pr_Write(tt,0,72+i*4,(char *)&cheader.nameHash[i],sizeof(cheader.nameHash[i]));
+       if (code) return PRDBFAIL;
+    }
+    else {
+       code = pr_ReadEntry(tt,0,trail, &bentry);
+       if (code) return PRDBFAIL;
+       bentry.nextName = tentry.nextName;
+       code = pr_WriteEntry(tt,0,trail,&bentry);
+    }
+    *loc = current;
+    return PRSUCCESS;
+}
+
+long AddToNameHash(tt, aname, loc)
+struct ubik_trans *tt;
+char *aname;
+long loc;
+{
+    /* add to name hash */
+    register long code;
+    long i;
+    struct prentry tentry;
+
+    i = NameHash(aname);
+    bzero(&tentry,sizeof(tentry));
+    code = pr_ReadEntry(tt,0,loc,&tentry);
+    if (code) return PRDBFAIL;
+    tentry.nextName = ntohl(cheader.nameHash[i]);
+    cheader.nameHash[i] = htonl(loc);
+    code = pr_WriteEntry(tt,0,loc,&tentry);
+    if (code) return PRDBFAIL;
+    code = pr_Write(tt,0,72+i*4,(char *)&cheader.nameHash[i],sizeof(cheader.nameHash[i]));
+    if (code) return PRDBFAIL;
+    return PRSUCCESS;
+}
+
+long AddToOwnerChain(at,gid,oid)
+struct ubik_trans *at;
+long gid;
+long oid;
+{
+    /* add entry designated by gid to owner chain of entry designated by oid */
+    register long code;
+    long loc;
+    long gloc;
+    struct prentry tentry;
+    struct prentry gentry;
+
+    loc = FindByID(at,oid);
+    if (!loc) return PRNOENT;
+    code = pr_ReadEntry(at,0,loc,&tentry);
+    if (code != 0) return PRDBFAIL;
+    gloc = FindByID(at,gid);
+    code = pr_ReadEntry(at,0,gloc,&gentry);
+    if (code != 0) return PRDBFAIL;
+    gentry.nextOwned = tentry.owned;
+    tentry.owned = gloc;
+    code = pr_WriteEntry(at,0,loc,&tentry);
+    if (code != 0) return PRDBFAIL;
+    code = pr_WriteEntry(at,0,gloc,&gentry);
+    if (code != 0) return PRDBFAIL;
+    return PRSUCCESS;
+}
+
+long RemoveFromOwnerChain(at,gid,oid)
+struct ubik_trans *at;
+long gid;
+long oid;
+{
+    /* remove gid from owner chain for oid */
+    register long code;
+    long nptr;
+    struct prentry tentry;
+    struct prentry bentry;
+    long loc;
+
+    loc = FindByID(at,oid);
+    if (!loc) return PRNOENT;
+    code = pr_ReadEntry(at,0,loc,&tentry);
+    if (code != 0) return PRDBFAIL;
+    if (!tentry.owned) return PRNOENT;
+    nptr = tentry.owned;
+    bcopy(&tentry,&bentry,sizeof(tentry));
+    while (nptr != NULL) {
+       code = pr_ReadEntry(at,0,nptr,&tentry);
+       if (code != 0) return PRDBFAIL;
+       if (tentry.id == gid) {
+           /* found it */
+           if (nptr == bentry.owned) /* modifying first of chain */
+               bentry.owned = tentry.nextOwned;
+           else bentry.nextOwned = tentry.nextOwned;
+           tentry.nextOwned = 0;
+           code = pr_WriteEntry(at,0,loc,&bentry);
+           if (code != 0) return PRDBFAIL;
+           code = pr_WriteEntry(at,0,nptr,&tentry);
+           if (code != 0) return PRDBFAIL;
+           return PRSUCCESS;
+       }
+       loc = nptr;
+       nptr = tentry.nextOwned;
+       bcopy(&tentry,&bentry,sizeof(tentry));
+    }
+    return PRNOENT;
+}
+
+long AddToOrphan(at,gid)
+struct ubik_trans *at;
+long gid;
+{
+    /* add gid to orphan list, as it's owner has died */
+    register long code;
+    long loc;
+    struct prentry tentry;
+
+    loc = FindByID(at,gid);
+    if (!loc) return PRNOENT;
+    code = pr_ReadEntry(at,0,loc,&tentry);
+    if (code != 0) return PRDBFAIL;
+    tentry.nextOwned = ntohl(cheader.orphan);
+    cheader.orphan = htonl(loc);
+    code = pr_WriteEntry(at,0,loc,&tentry);
+    if (code != 0) return PRDBFAIL;
+    code = pr_Write(at,0,32,(char *)&cheader.orphan,sizeof(cheader.orphan));
+    if (code != 0) return PRDBFAIL;
+    return PRSUCCESS;
+}
+
+long RemoveFromOrphan(at,gid)
+struct ubik_trans *at;
+long gid;
+{
+    /* remove gid from the orphan list */
+    register long code;
+    long loc;
+    long nptr;
+    struct prentry tentry;
+    struct prentry bentry;
+
+    loc = FindByID(at,gid);
+    if (!loc) return PRNOENT;
+    code = pr_ReadEntry(at,0,loc,&tentry);
+    if (code != 0) return PRDBFAIL;
+    if (cheader.orphan == htonl(loc)) {
+       cheader.orphan = htonl(tentry.nextOwned);
+       tentry.nextOwned = 0;
+       code = pr_Write(at,0,32,(char *)&cheader.orphan,sizeof(cheader.orphan));
+       if (code != 0) return PRDBFAIL;
+       code = pr_WriteEntry(at,0,loc,&tentry);
+       if (code != 0) return PRDBFAIL;
+       return PRSUCCESS;
+    }
+    nptr = ntohl(cheader.orphan);
+    bzero(&bentry,sizeof(bentry));
+    loc = 0;
+    while (nptr != NULL) {
+       code = pr_ReadEntry(at,0,nptr,&tentry);
+       if (code != 0) return PRDBFAIL;
+       if (gid == tentry.id) {
+           /* found it */
+           bentry.nextOwned = tentry.nextOwned;
+           tentry.nextOwned = 0;
+           code = pr_WriteEntry(at,0,loc,&bentry);
+           if (code != 0) return PRDBFAIL;
+           code = pr_WriteEntry(at,0,nptr,&tentry);
+           if (code != 0) return PRDBFAIL;
+           return PRSUCCESS;
+       }
+       loc = nptr;
+       nptr = tentry.nextOwned;
+       bcopy(&tentry,&bentry,sizeof(tentry));
+    }
+    return PRNOENT;
+}
+
+long IsOwnerOf(at,aid,gid)
+struct ubik_trans *at;
+long aid;
+long gid;
+{
+    /* returns 1 if aid is the owner of gid, 0 otherwise */
+    register long code;
+    struct prentry tentry;
+    long loc;
+
+    loc = FindByID(at,gid);
+    if (!loc) return 0;
+    code = pr_ReadEntry(at,0,loc,&tentry);
+    if (code != 0) return 0;
+    if (tentry.owner == aid) return 1;
+    return 0;
+}
+
+long OwnerOf(at,gid)
+struct ubik_trans *at;
+long gid;
+{
+    /* returns the owner of gid */
+    register long code;
+    long loc;
+    struct prentry tentry;
+
+    loc = FindByID(at,gid);
+    if (!loc) return 0;
+    code = pr_ReadEntry(at,0,loc,&tentry);
+    if (code != 0) return 0;
+    return tentry.owner;
+}
+    
+
+long WhoIsThis(acall, at, aid)
+struct rx_call *acall;
+struct ubik_trans *at;
+long *aid;
+{
+    /* aid is set to the identity of the caller, if known, ANONYMOUSID otherwise */
+    /* returns -1 and sets aid to ANONYMOUSID on any failure */
+    register struct rx_connection *tconn;
+    struct rxvab_conn *tc;
+    register long code;
+    char tcell[64];
+    long exp;
+    char vname[256];
+
+    tconn = rx_ConnectionOf(acall);
+    code = rx_SecurityClassOf(tconn);
+    if (code == 0) 
+       *aid = ANONYMOUSID;
+    else if (code == 1) {
+       /* vab class */
+       tc = (struct rxvab_conn *) tconn->securityData;
+       if (!tc) {
+           *aid = ANONYMOUSID; /* set it to something harmless */
+           return -1;
+       }
+       *aid = ntohl(tc->viceID);
+    }
+    else if (code == 2) {
+       /* kad class */
+       code = rxkad_GetServerInfo(acall->conn,(long *) 0, &exp, vname, (char *) 0, tcell, (long *) 0);
+       if (code) {
+           *aid = ANONYMOUSID;
+           return -1;
+       }
+       if (exp < FT_ApproxTime()) return -1;
+       code = NameToID(at,vname,aid);
+       if (code) {
+           *aid = ANONYMOUSID;
+           return -1;
+       }
+       return 0;
+    }
+    else {
+       *aid = ANONYMOUSID;
+       return -1;
+    }
+    return 0;
+}
+
+long IsAMemberOf(at,aid,gid)
+struct ubik_trans *at;
+long aid;
+long gid;
+{
+    /* returns true if aid is a member of gid */
+    struct prentry tentry;
+    struct contentry centry;
+    register long code;
+    long i;
+    long loc;
+
+    loc = FindByID(at,gid);
+    if (!loc) return 0;
+    bzero(&tentry,sizeof(tentry));
+    code = pr_ReadEntry(at, 0, loc,&tentry);
+    if (code) return 0;
+    if (!(tentry.flags & PRGRP)) return 0;
+    for (i= 0;i<PRSIZE;i++) {
+       if (tentry.entries[i] == aid) return 1;
+       if (tentry.entries[i] == 0) return 0;
+    }
+    if (tentry.next) {
+       loc = tentry.next;
+       while (loc) {
+           bzero(&centry,sizeof(centry));
+           code = pr_ReadCoEntry(at,0,loc,&centry);
+           if (code) return 0;
+           for (i=0;i<COSIZE;i++) {
+               if (centry.entries[i] == aid) return 1;
+               if (centry.entries[i] == 0) return 0;
+           }
+           loc = centry.next;
+       }
+    }
+    return 0;  /* actually, should never get here */
+}
This page took 0.094439 seconds and 5 git commands to generate.