]> git.sur5r.net Git - openldap/commitdiff
Support DB encryption
authorHoward Chu <hyc@openldap.org>
Sat, 15 Dec 2007 19:07:41 +0000 (19:07 +0000)
committerHoward Chu <hyc@openldap.org>
Sat, 15 Dec 2007 19:07:41 +0000 (19:07 +0000)
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-bdb/config.c
servers/slapd/back-bdb/dbcache.c
servers/slapd/back-bdb/init.c

index e3a9a2caad95bbbf36dc8a9b31d529ad9226050b..90c119c3e48c8914dfe1f416162bacfd0abc5882 100644 (file)
@@ -235,6 +235,8 @@ struct bdb_info {
        alock_info_t    bi_alock_info;
        char            *bi_db_config_path;
        BerVarray       bi_db_config;
+       char            *bi_db_crypt_file;
+       struct berval   bi_db_crypt_key;
        bdb_monitor_t   bi_monitor;
 
 #ifdef BDB_MONITOR_IDX
index 32291d7d054e773848e191cc913088d1a1fc9886..eda23ebd4edae98e5cdc45caf94c562a4b31e9dd 100644 (file)
@@ -42,6 +42,8 @@ static ConfigDriver bdb_cf_gen;
 enum {
        BDB_CHKPT = 1,
        BDB_CONFIG,
+       BDB_CRYPTFILE,
+       BDB_CRYPTKEY,
        BDB_DIRECTORY,
        BDB_NOSYNC,
        BDB_DIRTYR,
@@ -70,6 +72,14 @@ static ConfigTable bdbcfg[] = {
                bdb_cf_gen, "( OLcfgDbAt:1.2 NAME 'olcDbCheckpoint' "
                        "DESC 'Database checkpoint interval in kbytes and minutes' "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )",NULL, NULL },
+       { "cryptfile", "file", 2, 2, 0, ARG_STRING|ARG_MAGIC|BDB_CRYPTFILE,
+               bdb_cf_gen, "( OLcfgDbAt:1.13 NAME 'olcDbCryptFile' "
+                       "DESC 'Pathname of file containing the DB encryption key' "
+                       "SYNTAX OMsDirectoryString SINGLE-VALUE )",NULL, NULL },
+       { "cryptkey", "key", 2, 2, 0, ARG_BERVAL|ARG_MAGIC|BDB_CRYPTKEY,
+               bdb_cf_gen, "( OLcfgDbAt:1.14 NAME 'olcDbCryptKey' "
+                       "DESC 'DB encryption key' "
+                       "SYNTAX OMsOctetString SINGLE-VALUE )",NULL, NULL },
        { "dbconfig", "DB_CONFIG setting", 1, 0, 0, ARG_MAGIC|BDB_CONFIG,
                bdb_cf_gen, "( OLcfgDbAt:1.3 NAME 'olcDbConfig' "
                        "DESC 'BerkeleyDB DB_CONFIG configuration directives' "
@@ -143,6 +153,7 @@ static ConfigOCs bdbocs[] = {
                "SUP olcDatabaseConfig "
                "MUST olcDbDirectory "
                "MAY ( olcDbCacheSize $ olcDbCheckpoint $ olcDbConfig $ "
+               "olcDbCryptFile $ olcDbCryptKey $ "
                "olcDbNoSync $ olcDbDirtyRead $ olcDbIDLcacheSize $ "
                "olcDbIndex $ olcDbLinearIndex $ olcDbLockDetect $ "
                "olcDbMode $ olcDbSearchStack $ olcDbShmKey $ "
@@ -364,6 +375,25 @@ bdb_cf_gen( ConfigArgs *c )
                        }
                        break;
 
+               case BDB_CRYPTFILE:
+                       if ( bdb->bi_db_crypt_file ) {
+                               c->value_string = ch_strdup( bdb->bi_db_crypt_file );
+                       } else {
+                               rc = 1;
+                       }
+                       break;
+
+               /* If a crypt file has been set, its contents are copied here.
+                * But we don't want the key to be incorporated here.
+                */
+               case BDB_CRYPTKEY:
+                       if ( !bdb->bi_db_crypt_file && !BER_BVISNULL( &bdb->bi_db_crypt_key )) {
+                               value_add_one( &c->rvalue_vals, &bdb->bi_db_crypt_key );
+                       } else {
+                               rc = 1;
+                       }
+                       break;
+
                case BDB_DIRECTORY:
                        if ( bdb->bi_dbenv_home ) {
                                c->value_string = ch_strdup( bdb->bi_dbenv_home );
@@ -472,6 +502,21 @@ bdb_cf_gen( ConfigArgs *c )
                        bdb->bi_flags |= BDB_UPD_CONFIG;
                        c->cleanup = bdb_cf_cleanup;
                        break;
+               /* Doesn't really make sense to change these on the fly;
+                * the entire DB must be dumped and reloaded
+                */
+               case BDB_CRYPTFILE:
+                       if ( bdb->bi_db_crypt_file ) {
+                               ch_free( bdb->bi_db_crypt_file );
+                               bdb->bi_db_crypt_file = NULL;
+                       }
+                       /* FALLTHRU */
+               case BDB_CRYPTKEY:
+                       if ( !BER_BVISNULL( &bdb->bi_db_crypt_key )) {
+                               ch_free( bdb->bi_db_crypt_key.bv_val );
+                               BER_BVZERO( &bdb->bi_db_crypt_key );
+                       }
+                       break;
                case BDB_DIRECTORY:
                        bdb->bi_flags |= BDB_RE_OPEN;
                        bdb->bi_flags ^= BDB_HAS_CONFIG;
@@ -616,6 +661,22 @@ bdb_cf_gen( ConfigArgs *c )
                }
                break;
 
+       case BDB_CRYPTFILE:
+               rc = lutil_get_filed_password( c->value_string, &bdb->bi_db_crypt_key );
+               if ( rc == 0 ) {
+                       bdb->bi_db_crypt_file = c->value_string;
+               }
+               break;
+
+       /* Cannot set key if file was already set */
+       case BDB_CRYPTKEY:
+               if ( bdb->bi_db_crypt_file ) {
+                       rc = 1;
+               } else {
+                       bdb->bi_db_crypt_key = c->value_bv;
+               }
+               break;
+
        case BDB_DIRECTORY: {
                FILE *f;
                char *ptr, *testpath;
index ba005476f2e6953b4f7242019eac883c911bc9dd..ec24666c654d72799617f60a69d55a4f1d31ddce 100644 (file)
@@ -104,9 +104,23 @@ bdb_db_cache(
                        "bdb_db_cache: db_create(%s) failed: %s (%d)\n",
                        bdb->bi_dbenv_home, db_strerror(rc), rc );
                ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex );
+               ch_free( db );
                return rc;
        }
 
+       if( !BER_BVISNULL( &bdb->bi_db_crypt_key )) {
+               rc = db->bdi_db->set_flags( db->bdi_db, DB_ENCRYPT );
+               if ( rc ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "bdb_db_cache: db set_flags(DB_ENCRYPT)(%s) failed: %s (%d)\n",
+                               bdb->bi_dbenv_home, db_strerror(rc), rc );
+                       ldap_pvt_thread_mutex_unlock( &bdb->bi_database_mutex );
+                       db->bdi_db->close( db->bdi_db, 0 );
+                       ch_free( db );
+                       return rc;
+               }
+       }
+
        rc = db->bdi_db->set_pagesize( db->bdi_db, BDB_PAGESIZE );
 #ifdef BDB_INDEX_USE_HASH
        rc = db->bdi_db->set_h_hash( db->bdi_db, bdb_db_hash );
index 552540112fbb2459444becfc78e24d9c2e41d352..3b4d42672c0ef45369690c50b593d1f67b482669 100644 (file)
@@ -279,6 +279,18 @@ shm_retry:
 
        bdb->bi_dbenv->set_lk_detect( bdb->bi_dbenv, bdb->bi_lock_detect );
 
+       if ( !BER_BVISNULL( &bdb->bi_db_crypt_key )) {
+               rc = bdb->bi_dbenv->set_encrypt( bdb->bi_dbenv, bdb->bi_db_crypt_key.bv_val,
+                       DB_ENCRYPT_AES );
+               if ( rc ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               LDAP_XSTRING(bdb_db_open) ": database \"%s\": "
+                               "dbenv set_encrypt failed: %s (%d).\n",
+                               be->be_suffix[0].bv_val, db_strerror(rc), rc );
+                       goto fail;
+               }
+       }
+
        /* One long-lived TXN per thread, two TXNs per write op */
        bdb->bi_dbenv->set_tx_max( bdb->bi_dbenv, connection_pool_max * 3 );
 
@@ -390,6 +402,20 @@ shm_retry:
                        goto fail;
                }
 
+               if( !BER_BVISNULL( &bdb->bi_db_crypt_key )) {
+                       rc = db->bdi_db->set_flags( db->bdi_db, DB_ENCRYPT );
+                       if ( rc ) {
+                               snprintf(cr->msg, sizeof(cr->msg),
+                                       "database \"%s\": db set_flags(DB_ENCRYPT)(%s) failed: %s (%d).",
+                                       be->be_suffix[0].bv_val, 
+                                       bdb->bi_dbenv_home, db_strerror(rc), rc );
+                               Debug( LDAP_DEBUG_ANY,
+                                       LDAP_XSTRING(bdb_db_open) ": %s\n",
+                                       cr->msg, 0, 0 );
+                               goto fail;
+                       }
+               }
+
                if( i == BDB_ID2ENTRY ) {
                        if ( slapMode & SLAP_TOOL_MODE )
                                db->bdi_db->mpf->set_priority( db->bdi_db->mpf,