NSS_IMPLEMENT CK_RV nss_dbm_db_delete_object ( nss_dbm_dbt_t *dbt ) { CK_RV rv; int dbrv; /* Locked region */ { rv = NSSCKFWMutex_Lock(dbt->my_db->crustylock); if( CKR_OK != rv ) { return rv; } dbrv = dbt->my_db->db->del(dbt->my_db->db, &dbt->dbt, 0); if( 0 != dbrv ) { rv = CKR_DEVICE_ERROR; goto done; } dbrv = dbt->my_db->db->sync(dbt->my_db->db, 0); if( 0 != dbrv ) { rv = CKR_DEVICE_ERROR; goto done; } done: (void)NSSCKFWMutex_Unlock(dbt->my_db->crustylock); } return rv; }
static void nss_dbm_mdSession_Close ( NSSCKMDSession *mdSession, NSSCKFWSession *fwSession, NSSCKMDToken *mdToken, NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance ) { nss_dbm_session_t *session = (nss_dbm_session_t *)mdSession->etc; struct nss_dbm_dbt_node *w; /* Lock */ { if( CKR_OK != NSSCKFWMutex_Lock(session->list_lock) ) { return; } w = session->session_objects; session->session_objects = (struct nss_dbm_dbt_node *)NULL; /* sanity */ (void)NSSCKFWMutex_Unlock(session->list_lock); } for( ; (struct nss_dbm_dbt_node *)NULL != w; w = w->next ) { (void)nss_dbm_db_delete_object(w->dbt); } }
NSS_IMPLEMENT CK_VERSION nss_dbm_db_get_format_version ( nss_dbm_db_t *db ) { CK_VERSION rv; DBT k, v; int dbrv; char buffer[64]; rv.major = rv.minor = 0; k.data = PREFIX_METADATA "FormatVersion"; k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL); (void)memset(&v, 0, sizeof(v)); /* Locked region */ { if( CKR_OK != NSSCKFWMutex_Lock(db->crustylock) ) { return rv; } dbrv = db->db->get(db->db, &k, &v, 0); if( dbrv == 0 ) { CK_ULONG major = 0, minor = 0; (void)PR_sscanf(v.data, "%ld.%ld", &major, &minor); rv.major = major; rv.minor = minor; } else if( dbrv > 0 ) { (void)PR_snprintf(buffer, sizeof(buffer), "%ld.%ld", nss_dbm_db_format_version.major, nss_dbm_db_format_version.minor); v.data = buffer; v.size = nssUTF8_Size((NSSUTF8 *)v.data, (PRStatus *)NULL); dbrv = db->db->put(db->db, &k, &v, 0); (void)db->db->sync(db->db, 0); rv = nss_dbm_db_format_version; } else { /* No error return.. */ ; } (void)NSSCKFWMutex_Unlock(db->crustylock); } return rv; }
NSS_IMPLEMENT NSSUTF8 * nss_dbm_db_get_label ( nss_dbm_db_t *db, NSSArena *arena, CK_RV *pError ) { NSSUTF8 *rv = (NSSUTF8 *)NULL; DBT k, v; int dbrv; k.data = PREFIX_METADATA "Label"; k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL); /* Locked region */ { if( CKR_OK != NSSCKFWMutex_Lock(db->crustylock) ) { return rv; } dbrv = db->db->get(db->db, &k, &v, 0); if( 0 == dbrv ) { rv = nssUTF8_Duplicate((NSSUTF8 *)v.data, arena); if( (NSSUTF8 *)NULL == rv ) { *pError = CKR_HOST_MEMORY; } } else if( dbrv > 0 ) { /* Just return null */ ; } else { *pError = CKR_DEVICE_ERROR; ; } (void)NSSCKFWMutex_Unlock(db->crustylock); } return rv; }
NSS_IMPLEMENT CK_RV nss_dbm_db_set_label ( nss_dbm_db_t *db, NSSUTF8 *label ) { CK_RV rv; DBT k, v; int dbrv; k.data = PREFIX_METADATA "Label"; k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL); v.data = label; v.size = nssUTF8_Size((NSSUTF8 *)v.data, (PRStatus *)NULL); /* Locked region */ { rv = NSSCKFWMutex_Lock(db->crustylock); if( CKR_OK != rv ) { return rv; } dbrv = db->db->put(db->db, &k, &v, 0); if( 0 != dbrv ) { rv = CKR_DEVICE_ERROR; } dbrv = db->db->sync(db->db, 0); if( 0 != dbrv ) { rv = CKR_DEVICE_ERROR; } (void)NSSCKFWMutex_Unlock(db->crustylock); } return rv; }
static NSSCKMDObject * nss_dbm_mdFindObjects_Next ( NSSCKMDFindObjects *mdFindObjects, NSSCKFWFindObjects *fwFindObjects, NSSCKMDSession *mdSession, NSSCKFWSession *fwSession, NSSCKMDToken *mdToken, NSSCKFWToken *fwToken, NSSCKMDInstance *mdInstance, NSSCKFWInstance *fwInstance, NSSArena *arena, CK_RV *pError ) { nss_dbm_find_t *find = (nss_dbm_find_t *)mdFindObjects->etc; struct nss_dbm_dbt_node *node; nss_dbm_object_t *object; NSSCKMDObject *rv; while(1) { /* Lock */ { *pError = NSSCKFWMutex_Lock(find->list_lock); if( CKR_OK != *pError ) { return (NSSCKMDObject *)NULL; } node = find->found; if( (struct nss_dbm_dbt_node *)NULL != node ) { find->found = node->next; } *pError = NSSCKFWMutex_Unlock(find->list_lock); if( CKR_OK != *pError ) { /* screwed now */ return (NSSCKMDObject *)NULL; } } if( (struct nss_dbm_dbt_node *)NULL == node ) { break; } if( nss_dbm_db_object_still_exists(node->dbt) ) { break; } } if( (struct nss_dbm_dbt_node *)NULL == node ) { *pError = CKR_OK; return (NSSCKMDObject *)NULL; } object = nss_ZNEW(arena, nss_dbm_object_t); if( (nss_dbm_object_t *)NULL == object ) { *pError = CKR_HOST_MEMORY; return (NSSCKMDObject *)NULL; } object->arena = arena; object->handle = nss_ZNEW(arena, nss_dbm_dbt_t); if( (nss_dbm_dbt_t *)NULL == object->handle ) { *pError = CKR_HOST_MEMORY; return (NSSCKMDObject *)NULL; } object->handle->my_db = node->dbt->my_db; object->handle->dbt.size = node->dbt->dbt.size; object->handle->dbt.data = nss_ZAlloc(arena, node->dbt->dbt.size); if( (void *)NULL == object->handle->dbt.data ) { *pError = CKR_HOST_MEMORY; return (NSSCKMDObject *)NULL; } (void)memcpy(object->handle->dbt.data, node->dbt->dbt.data, node->dbt->dbt.size); rv = nss_dbm_mdObject_factory(object, pError); if( (NSSCKMDObject *)NULL == rv ) { return (NSSCKMDObject *)NULL; } return rv; }
NSS_IMPLEMENT CK_RV nss_dbm_db_find_objects ( nss_dbm_find_t *find, nss_dbm_db_t *db, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_ULONG *pdbrv ) { CK_RV rv = CKR_OK; if( (nss_dbm_db_t *)NULL != db ) { DBT k, v; rv = NSSCKFWMutex_Lock(db->crustylock); if( CKR_OK != rv ) { return rv; } *pdbrv = db->db->seq(db->db, &k, &v, R_FIRST); while( 0 == *pdbrv ) { CK_ULONG i, j; NSSArena *tmparena = (NSSArena *)NULL; CK_ULONG ulac; CK_ATTRIBUTE_PTR pt; if( (k.size < 4) || (0 != memcmp(k.data, PREFIX_OBJECT, 4)) ) { goto nomatch; } tmparena = NSSArena_Create(); rv = nss_dbm_db_unwrap_object(tmparena, &v, &pt, &ulac); if( CKR_OK != rv ) { goto loser; } for( i = 0; i < ulAttributeCount; i++ ) { for( j = 0; j < ulac; j++ ) { if( pTemplate[i].type == pt[j].type ) { if( pTemplate[i].ulValueLen != pt[j].ulValueLen ) { goto nomatch; } if( 0 != memcmp(pTemplate[i].pValue, pt[j].pValue, pt[j].ulValueLen) ) { goto nomatch; } break; } } if( j == ulac ) { goto nomatch; } } /* entire template matches */ { struct nss_dbm_dbt_node *node; node = nss_ZNEW(find->arena, struct nss_dbm_dbt_node); if( (struct nss_dbm_dbt_node *)NULL == node ) { rv = CKR_HOST_MEMORY; goto loser; } node->dbt = nss_ZNEW(find->arena, nss_dbm_dbt_t); if( (nss_dbm_dbt_t *)NULL == node->dbt ) { rv = CKR_HOST_MEMORY; goto loser; } node->dbt->dbt.size = k.size; node->dbt->dbt.data = nss_ZAlloc(find->arena, k.size); if( (void *)NULL == node->dbt->dbt.data ) { rv = CKR_HOST_MEMORY; goto loser; } (void)memcpy(node->dbt->dbt.data, k.data, k.size); node->dbt->my_db = db; node->next = find->found; find->found = node; } nomatch: if( (NSSArena *)NULL != tmparena ) { (void)NSSArena_Destroy(tmparena); } *pdbrv = db->db->seq(db->db, &k, &v, R_NEXT); } if( *pdbrv < 0 ) { rv = CKR_DEVICE_ERROR; goto loser; } rv = CKR_OK; loser: (void)NSSCKFWMutex_Unlock(db->crustylock); }
NSS_IMPLEMENT nss_dbm_dbt_t * nss_dbm_db_create_object ( NSSArena *arena, nss_dbm_db_t *db, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_RV *pError, CK_ULONG *pdbrv ) { NSSArena *tmparena = (NSSArena *)NULL; nss_dbm_dbt_t *rv = (nss_dbm_dbt_t *)NULL; DBT object; rv = nss_ZNEW(arena, nss_dbm_dbt_t); if( (nss_dbm_dbt_t *)NULL == rv ) { *pError = CKR_HOST_MEMORY; return (nss_dbm_dbt_t *)NULL; } rv->my_db = db; rv->dbt.size = sizeof(struct handle); rv->dbt.data = nss_ZAlloc(arena, rv->dbt.size); if( (void *)NULL == rv->dbt.data ) { *pError = CKR_HOST_MEMORY; return (nss_dbm_dbt_t *)NULL; } *pdbrv = nss_dbm_db_new_handle(db, &rv->dbt, pError); if( 0 != *pdbrv ) { return (nss_dbm_dbt_t *)NULL; } tmparena = NSSArena_Create(); if( (NSSArena *)NULL == tmparena ) { *pError = CKR_HOST_MEMORY; return (nss_dbm_dbt_t *)NULL; } *pError = nss_dbm_db_wrap_object(tmparena, pTemplate, ulAttributeCount, &object); if( CKR_OK != *pError ) { return (nss_dbm_dbt_t *)NULL; } /* Locked region */ { *pError = NSSCKFWMutex_Lock(db->crustylock); if( CKR_OK != *pError ) { goto loser; } *pdbrv = db->db->put(db->db, &rv->dbt, &object, 0); if( 0 != *pdbrv ) { *pError = CKR_DEVICE_ERROR; } (void)db->db->sync(db->db, 0); (void)NSSCKFWMutex_Unlock(db->crustylock); } loser: if( (NSSArena *)NULL != tmparena ) { (void)NSSArena_Destroy(tmparena); } return rv; }
static CK_ULONG nss_dbm_db_new_handle ( nss_dbm_db_t *db, DBT *dbt, /* pre-allocated */ CK_RV *pError ) { CK_ULONG rv; DBT k, v; CK_ULONG align = 0, id, myid; struct handle *hp; if( sizeof(struct handle) != dbt->size ) { return EINVAL; } /* Locked region */ { *pError = NSSCKFWMutex_Lock(db->crustylock); if( CKR_OK != *pError ) { return EINVAL; } k.data = PREFIX_METADATA "LastID"; k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL); (void)memset(&v, 0, sizeof(v)); rv = db->db->get(db->db, &k, &v, 0); if( 0 == rv ) { (void)memcpy(&align, v.data, sizeof(CK_ULONG)); id = ntohl(align); } else if( rv > 0 ) { id = 0; } else { goto done; } myid = id; id++; align = htonl(id); v.data = &align; v.size = sizeof(CK_ULONG); rv = db->db->put(db->db, &k, &v, 0); if( 0 != rv ) { goto done; } rv = db->db->sync(db->db, 0); if( 0 != rv ) { goto done; } done: (void)NSSCKFWMutex_Unlock(db->crustylock); } if( 0 != rv ) { return rv; } hp = (struct handle *)dbt->data; (void)memcpy(&hp->prefix[0], PREFIX_OBJECT, 4); hp->id = myid; return 0; }