Example #1
0
afs_int32
AllocBlock(struct ubik_trans *at, struct kaentry *tentry)
{
    afs_int32 code;
    afs_int32 temp;

    if (cheader.freePtr) {
	/* allocate this dude */
	temp = ntohl(cheader.freePtr);
	code = karead(at, temp, (char *)tentry, sizeof(kaentry));
	if (code)
	    return 0;		/* can't read block */
	code = set_header_word(at, freePtr, tentry->next);
    } else {
	/* hosed, nothing on free list, grow file */
	temp = ntohl(cheader.eofPtr);	/* remember this guy */
	code = set_header_word(at, eofPtr, htonl(temp + sizeof(kaentry)));
    }
    if (code)
	return 0;

    code = inc_header_word(at, stats.allocs);
    if (code)
	return 0;
    memset(tentry, 0, sizeof(kaentry));	/* zero new entry */
    return temp;
}
Example #2
0
afs_int32
FreeBlock(struct ubik_trans *at, afs_int32 index)
{
    struct kaentry tentry;
    int code;

    /* check index just to be on the safe side */
    if (!index_OK(index))
	return KABADINDEX;

    memset(&tentry, 0, sizeof(kaentry));
    tentry.next = cheader.freePtr;
    tentry.flags = htonl(KAFFREE);
    code = set_header_word(at, freePtr, htonl(index));
    if (code)
	return KAIO;
    code = kawrite(at, index, (char *)&tentry, sizeof(kaentry));
    if (code)
	return KAIO;

    code = inc_header_word(at, stats.frees);
    if (code)
	return KAIO;
    return 0;
}
Example #3
0
afs_int32
GetInstanceId(struct rx_call *call, afs_uint32 *instanceId)
{
    struct ubik_trans *ut;
    afs_int32 code;
    afs_int32 instanceValue;

    LogDebug(4, "GetInstanceId:\n");

    /* *** Allow anyone to get the instance id ***
     * if ( callPermitted(call) == 0 )
     *    return(BUDB_NOTPERMITTED);
     */

    code = InitRPC(&ut, LOCKWRITE, 1);
    if (code)
	return (code);

    instanceValue = ntohl(db.h.lastInstanceId) + 1;

    set_header_word(ut, lastInstanceId, htonl(instanceValue));

    code = ubik_EndTrans(ut);
    return (code);
}
Example #4
0
afs_int32
ka_DelKey(struct ubik_trans *tt, afs_int32 tentryaddr,
	  struct kaentry *tentry)
{
    int code;
    struct kaOldKeys okeys;	/* old keys block */
    afs_int32 okeysaddr, nextaddr;	/* offset of old keys block */
    afs_int32 prevptr = 0;

    es_Report("DelKey for %s.%s\n", tentry->userID.name,
	      tentry->userID.instance);

    /* An entry may have more than one oldkeys blocks. The entry
     * points to the most current, but all the oldkeys blocks for an
     * entry are not linked together. All oldkeys blocks for all
     * entries are linked together off of the header. So we follow
     * this link.
     */
    for (okeysaddr = ntohl(cheader.kvnoPtr); okeysaddr; okeysaddr = nextaddr) {
	/* foreacholdkeysblock */
	/* Read the oldKeys block */
	code = karead(tt, okeysaddr, (char *)&okeys, sizeof(okeys));
	if (code)
	    return code;
	nextaddr = ntohl(okeys.next);

	/* We only want oldkey blocks that belong to this entry */
	if (ntohl(okeys.entry) != tentryaddr) {
	    prevptr = DOFFSET(okeysaddr, &okeys, &okeys.next);
	    continue;
	}

	/* Delete the oldkeys block */
	if (prevptr) {
	    code =
		kawrite(tt, prevptr, (char *)&okeys.next, sizeof(afs_int32));
	} else {
	    code = set_header_word(tt, kvnoPtr, okeys.next);
	}
	if (code)
	    return code;
	code = FreeBlock(tt, okeysaddr);
	if (code)
	    return code;
    }				/* foreacholdkeysblock */

    /* Update the tentry. We rely on caller to write it out */
    tentry->misc.asServer.oldKeys = 0;
    tentry->misc.asServer.nOldKeys = 0;

    /* invalidate key caches everywhere */
    code = inc_header_word(tt, specialKeysVersion);
    if (code)
	return code;

    return 0;
}
Example #5
0
afs_int32
ThreadBlock(struct ubik_trans *at, afs_int32 index,
	    struct kaentry *tentry)
{
    int code;
    int hi;			/* hash index */

    if (!index_OK(index))
	return KABADINDEX;
    hi = NameHash(tentry->userID.name, tentry->userID.instance);
    tentry->next = cheader.nameHash[hi];
    code = set_header_word(at, nameHash[hi], htonl(index));
    if (code)
	return KAIO;
    code = kawrite(at, index, (char *)tentry, sizeof(kaentry));
    if (code)
	return KAIO;
    return 0;
}
Example #6
0
afs_int32
AddToOrphan(struct ubik_trans *at, afs_int32 gid)
{
    afs_int32 code;
    afs_int32 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);
    code = set_header_word(at, orphan, htonl(loc));
    if (code != 0)
	return PRDBFAIL;
    tentry.owner = 0;		/* so there's no confusion later */
    code = pr_WriteEntry(at, 0, loc, &tentry);
    if (code != 0)
	return PRDBFAIL;
    return PRSUCCESS;
}
Example #7
0
afs_int32
UnthreadBlock(struct ubik_trans *at, struct kaentry *aentry)
{
    afs_int32 i, code;
    afs_int32 to;
    afs_int32 lo;
    struct kaentry tentry;

    i = NameHash(aentry->userID.name, aentry->userID.instance);
    lo = 0;
    for (to = ntohl(cheader.nameHash[i]); to != NULLO;
	 to = ntohl(tentry.next)) {
	code = karead(at, to, (char *)&tentry, sizeof(kaentry));
	if (code)
	    return KAIO;
	/* see if the name matches */
	if (!strcmp(aentry->userID.name, tentry.userID.name)
	    && !strcmp(aentry->userID.instance, tentry.userID.instance)) {
	    /* found it */
	    if (lo) {		/* unthread from last block */
		code =
		    kawrite(at, lo, (char *)&tentry.next, sizeof(afs_int32));
		if (code)
		    return KAIO;
	    } else {		/* unthread from hash table */
		code = set_header_word(at, nameHash[i], tentry.next);
		if (code)
		    return KAIO;
	    }
	    aentry->next = 0;	/* just to be sure */
	    return 0;
	}
	lo = DOFFSET(to, &tentry, &tentry.next);
    }
    return KANOENT;
}
Example #8
0
afs_int32
ka_NewKey(struct ubik_trans *tt, afs_int32 tentryaddr,
	  struct kaentry *tentry, struct ktc_encryptionKey *key)
{
    struct kaOldKeys okeys;	/* old keys block */
    afs_int32 okeysaddr, nextaddr;	/* offset of old keys block */
    afs_int32 prevptr, nextprevptr;
    int code, i;
    Date now = time(0);
    afs_int32 newkeyver;	/* new key version number */
    afs_int32 newtotalkeyentries = 0, oldtotalkeyentries = 0, keyentries;
    int addednewkey = 0, modified;
#ifdef AUTH_DBM_LOG
    int foundcurrentkey = 0;
#endif

    es_Report("Newkey for %s.%s\n", tentry->userID.name,
	      tentry->userID.instance);

    newkeyver = ntohl(tentry->key_version) + 1;
    if ((newkeyver < 1) || (newkeyver >= MAXKAKVNO))
	newkeyver = 1;

    /* An entry may have more than one oldkeys blocks. The entry
     * points to the most current, but all the oldkeys blocks for an
     * entry are not linked together. All oldkeys blocks for all
     * entries are linked together off of the header. So we follow
     * this link.
     */
    for (prevptr = 0, okeysaddr = ntohl(cheader.kvnoPtr); okeysaddr;
	 prevptr = nextprevptr, okeysaddr = nextaddr) {
	/* foreacholdkeysblock */
	/* Read the oldKeys block */
	code = karead(tt, okeysaddr, (char *)&okeys, sizeof(okeys));
	if (code)
	    return code;

	nextaddr = ntohl(okeys.next);
	nextprevptr = DOFFSET(okeysaddr, &okeys, &okeys.next);

	/* We only want oldkey blocks that belong to this entry */
	if (ntohl(okeys.entry) != tentryaddr)
	    continue;

	modified = 0;		/* This oldkeys block has not been modified */
	keyentries = 0;		/* Number of valid key entries in the block */
	for (i = 0; i < NOLDKEYS; i++) {
	    /* foreachkey */
	    /* Keep count of number of entries found */
	    if (okeys.keys[i].superseded != 0) {
		oldtotalkeyentries++;
	    }

	    /* If we find the entry that is not superseded, then supersede it */
	    if (ntohl(okeys.keys[i].superseded) == NEVERDATE) {
		okeys.keys[i].superseded = htonl(now);
		modified = 1;
#ifdef AUTH_DBM_LOG
		if (foundcurrentkey) {
		    ViceLog(0,
			    ("Warning: Entry %s.%s contains more than one valid key: fixing\n",
			     tentry->userID.name, tentry->userID.instance));
		}
		foundcurrentkey = 1;
#endif
	    }

	    /* If we find an oldkey of the same version or
	     * an old key that has expired, then delete it.
	     */
	    if ((ntohl(okeys.keys[i].version) == newkeyver)
		|| ((now - ntohl(okeys.keys[i].superseded) > maxKeyLifetime))) {
		okeys.keys[i].superseded = 0;
		okeys.keys[i].version = htonl(-1);
		memset(&okeys.keys[i].key, 0,
		       sizeof(struct ktc_encryptionKey));
		modified = 1;

		es_Report("Dropped oldkey %d seconds old with kvno %d\n",
			  now - ntohl(okeys.keys[i].superseded),
			  ntohl(okeys.keys[i].version));
	    }

	    /* Add our key here if its free */
	    if (!addednewkey && (okeys.keys[i].superseded == 0)) {
		okeys.keys[i].version = htonl(newkeyver);
		okeys.keys[i].superseded = htonl(NEVERDATE);
		memcpy(&okeys.keys[i].key, key,
		       sizeof(struct ktc_encryptionKey));
		modified = 1;
		addednewkey = okeysaddr;
	    }

	    /* Keep count of number of entries found */
	    if (okeys.keys[i].superseded != 0) {
		keyentries++;
		newtotalkeyentries++;
	    }
	}			/* foreachkey */

	/* If we modified the block, write it out */
	if (modified && keyentries) {
	    code = kawrite(tt, okeysaddr, (char *)&okeys, sizeof(okeys));
	    if (code)
		return code;
	}

	/* If there are no more entries in this oldkeys block, delete it */
	if (keyentries == 0) {
	    if (!prevptr) {
		code = set_header_word(tt, kvnoPtr, okeys.next);
	    } else {
		code =
		    kawrite(tt, prevptr, (char *)&okeys.next,
			    sizeof(afs_int32));
	    }
	    if (code)
		return code;
	    code = FreeBlock(tt, okeysaddr);
	    if (code)
		return code;

	    nextprevptr = prevptr;	/* won't bump prevptr */
	}
    }				/* foreacholdkeysblock */

    /* If we could not add the key, create a new oldkeys block */
    if (!addednewkey) {
	/* Allocate and fill in an oldkeys block */
	addednewkey = AllocBlock(tt, (struct kaentry *)&okeys);
	if (!addednewkey)
	    return KACREATEFAIL;
	okeys.flags = htonl(KAFOLDKEYS);
	okeys.entry = htonl(tentryaddr);
	okeys.keys[0].version = htonl(newkeyver);
	okeys.keys[0].superseded = htonl(NEVERDATE);
	memcpy(&okeys.keys[0].key, key, sizeof(struct ktc_encryptionKey));
	newtotalkeyentries++;

	/* Thread onto the header's chain of oldkeys */
	okeys.next = cheader.kvnoPtr;
	code = set_header_word(tt, kvnoPtr, htonl(addednewkey));
	if (code)
	    return code;

	/* Write the oldkeys block out */
	code = kawrite(tt, addednewkey, (char *)&okeys, sizeof(okeys));
	if (code)
	    return code;

	es_Report("New oldkey block allocated at %d\n", addednewkey);
    }
#ifdef AUTH_DBM_LOG
    if (oldtotalkeyentries != ntohl(tentry->misc.asServer.nOldKeys)) {
	ViceLog(0,
		("Warning: Entry %s.%s reports %d oldkeys, found %d: fixing\n",
		 tentry->userID.name, tentry->userID.instance,
		 ntohl(tentry->misc.asServer.nOldKeys), oldtotalkeyentries));
    }
#endif

    /* Update the tentry. We rely on caller to write it out */
    tentry->misc.asServer.oldKeys = htonl(addednewkey);
    tentry->misc.asServer.nOldKeys = htonl(newtotalkeyentries);
    tentry->key_version = htonl(newkeyver);
    memcpy(&tentry->key, key, sizeof(tentry->key));

    /* invalidate key caches everywhere */
    code = inc_header_word(tt, specialKeysVersion);
    if (code)
	return code;

    es_Report("New kvno is %d, now are %d oldkeys\n", newkeyver,
	      newtotalkeyentries);
    return 0;
}