OpenDNSSEC-enforcer  1.3.4
/build/buildd/opendnssec-1.3.4/enforcer/ksm/ksm_list.c
Go to the documentation of this file.
00001 /*
00002  * $Id: ksm_list.c 4169 2010-11-04 14:24:23Z sion $
00003  *
00004  * Copyright (c) 2008-2009 Nominet UK. All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00016  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00017  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00019  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00020  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00021  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00023  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00024  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00025  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  */
00028 
00029 /*
00030  * ksm_list.c - List various aspects of the current configuration
00031  */
00032 
00033 #include <assert.h>
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <string.h>
00037 #include <time.h>
00038 
00039 #include "ksm/database.h"
00040 #include "ksm/database_statement.h"
00041 #include "ksm/datetime.h"
00042 #include "ksm/db_fields.h"
00043 #include "ksm/debug.h"
00044 #include "ksm/ksmdef.h"
00045 #include "ksm/ksm.h"
00046 #include "ksm/ksm_internal.h"
00047 #include "ksm/message.h"
00048 #include "ksm/string_util.h"
00049 #include "ksm/string_util2.h"
00050 
00051 /*+
00052  * KsmListBackups - Output a list of all backups perfomed
00053  *
00054  *
00055  * Arguments:
00056  *
00057  *      int repo_id
00058  *          ID of the repository (-1 for all)
00059  *
00060  * Returns:
00061  *      int
00062  *          Status return.  0 on success.
00063  *                          other on fail
00064  */
00065 
00066 int KsmListBackups(int repo_id, int verbose_flag)
00067 {
00068     char*       sql = NULL;     /* SQL query */
00069     char*       sql2 = NULL;     /* SQL query */
00070     char*       sql3 = NULL;     /* SQL query */
00071     int         status = 0;     /* Status return */
00072     char        stringval[KSM_INT_STR_SIZE];  /* For Integer to String conversion */
00073     DB_RESULT   result;         /* Result of the query */
00074     DB_ROW      row = NULL;     /* Row data */
00075     DB_RESULT   result2;         /* Result of the query */
00076     DB_ROW      row2 = NULL;     /* Row data */
00077     DB_RESULT   result3;         /* Result of the query */
00078     DB_ROW      row3 = NULL;     /* Row data */
00079 
00080     char*       temp_date = NULL; /* place to store date returned */
00081     char*       temp_pre_date = NULL; /* place to store pre-backup date returned */
00082     char*       temp_repo = NULL; /* place to store repository returned */
00083     int         temp_backup_req = 0; /* place to store backuprequired returned */
00084 
00085     /* Select rows */
00086     StrAppend(&sql, "select distinct k.backup, s.name, k.pre_backup from keypairs k, securitymodules s ");
00087     StrAppend(&sql, "where s.id = k.securitymodule_id ");
00088     if (repo_id != -1) {
00089         StrAppend(&sql, "and s.id = ");
00090         snprintf(stringval, KSM_INT_STR_SIZE, "%d", repo_id);
00091         StrAppend(&sql, stringval);
00092     }
00093     StrAppend(&sql, " order by backup");
00094 
00095     DusEnd(&sql);
00096 
00097     status = DbExecuteSql(DbHandle(), sql, &result);
00098 
00099     if (status == 0) {
00100         status = DbFetchRow(result, &row);
00101         if (verbose_flag == 1) {
00102             printf("Pre Backup Date:         Backup Date:             Repository:\n");
00103         } else {
00104             printf("Date:                    Repository:\n");
00105         }
00106         while (status == 0) {
00107             /* Got a row, print it */
00108             DbString(row, 0, &temp_date);
00109             DbString(row, 1, &temp_repo);
00110             DbString(row, 2, &temp_pre_date);
00111 
00112             if (verbose_flag == 1) {
00113                 if (temp_date != NULL || temp_pre_date != NULL) { /* Ignore non-backup */
00114                     printf("%-24s %-24s %s\n", temp_pre_date, temp_date, temp_repo);
00115                 }
00116             } else {
00117                 if (temp_date != NULL) { /* Ignore non-backup */
00118                     printf("%-24s %s\n", temp_date, temp_repo);
00119                 }
00120             }
00121             
00122             status = DbFetchRow(result, &row);
00123         }
00124 
00125         /* Convert EOF status to success */
00126 
00127         if (status == -1) {
00128             status = 0;
00129         }
00130 
00131         DbFreeResult(result);
00132     }
00133 
00134     DusFree(sql);
00135     DbFreeRow(row);
00136     DbStringFree(temp_date);
00137     DbStringFree(temp_pre_date);
00138     sql = NULL;
00139     row = NULL;
00140     temp_date = NULL;
00141 
00142     /* List repos which need a backup */
00143     StrAppend(&sql2, "select s.name, s.requirebackup from keypairs k, securitymodules s ");
00144     StrAppend(&sql2, "where s.id = k.securitymodule_id ");
00145     if (repo_id != -1) {
00146         StrAppend(&sql2, "and s.id = ");
00147         snprintf(stringval, KSM_INT_STR_SIZE, "%d", repo_id);
00148         StrAppend(&sql2, stringval);
00149     }
00150     StrAppend(&sql2, " and k.backup is null");
00151     StrAppend(&sql2, " group by s.name order by s.name");
00152 
00153     DusEnd(&sql2);
00154 
00155     status = DbExecuteSql(DbHandle(), sql2, &result2);
00156 
00157     if (status == 0) {
00158         status = DbFetchRow(result2, &row2);
00159         while (status == 0) {
00160             /* Got a row, print it */
00161             DbString(row2, 0, &temp_repo);
00162             DbInt(row2, 1, &temp_backup_req);
00163 
00164             if (temp_backup_req == 0) {
00165                 printf("Repository %s has unbacked up keys (that can be used)\n", temp_repo);
00166             } else {
00167                 printf("Repository %s has unbacked up keys (that will not be used)\n", temp_repo);
00168             }
00169             
00170             status = DbFetchRow(result2, &row2);
00171         }
00172 
00173         /* Convert EOF status to success */
00174 
00175         if (status == -1) {
00176             status = 0;
00177         }
00178 
00179         DbFreeResult(result2);
00180     }
00181 
00182     DusFree(sql2);
00183     DbFreeRow(row2);
00184     DbStringFree(temp_repo);
00185 
00186     /* List repos which need a backup commit */
00187     temp_repo = NULL;
00188     StrAppend(&sql3, "select s.name from keypairs k, securitymodules s ");
00189     StrAppend(&sql3, "where s.id = k.securitymodule_id ");
00190     if (repo_id != -1) {
00191         StrAppend(&sql3, "and s.id = ");
00192         snprintf(stringval, KSM_INT_STR_SIZE, "%d", repo_id);
00193         StrAppend(&sql3, stringval);
00194     }
00195     StrAppend(&sql3, " and k.backup is null");
00196     StrAppend(&sql3, " and k.pre_backup is not null");
00197     StrAppend(&sql3, " group by s.name order by s.name");
00198 
00199     DusEnd(&sql3);
00200 
00201     status = DbExecuteSql(DbHandle(), sql3, &result3);
00202 
00203     if (status == 0) {
00204         status = DbFetchRow(result3, &row3);
00205         while (status == 0) {
00206             /* Got a row, print it */
00207             DbString(row3, 0, &temp_repo);
00208 
00209             printf("Repository %s has keys prepared for back up which have not been committed\n", temp_repo);
00210             
00211             status = DbFetchRow(result3, &row3);
00212         }
00213 
00214         /* Convert EOF status to success */
00215 
00216         if (status == -1) {
00217             status = 0;
00218         }
00219 
00220         DbFreeResult(result3);
00221     }
00222 
00223     DusFree(sql3);
00224     DbFreeRow(row3);
00225     DbStringFree(temp_repo);
00226 
00227     return status;
00228 }
00229 
00230 /*+
00231  * KsmListRepos - Output a list of all repositories available
00232  *
00233  *
00234  * Arguments:
00235  *
00236  *      none
00237  *
00238  * Returns:
00239  *      int
00240  *          Status return.  0 on success.
00241  *                          other on fail
00242  */
00243 
00244 int KsmListRepos()
00245 {
00246     char*       sql = NULL;     /* SQL query */
00247     int         status = 0;     /* Status return */
00248     DB_RESULT   result;         /* Result of the query */
00249     DB_ROW      row = NULL;     /* Row data */
00250 
00251     char*       temp_name = NULL;   /* place to store name returned */
00252     char*       temp_cap = NULL;    /* place to store capacity returned */
00253     int         temp_back = 0;      /* place to store backup flag returned */
00254 
00255     /* Select rows */
00256     StrAppend(&sql, "select name, capacity, requirebackup from securitymodules ");
00257     StrAppend(&sql, "order by name");
00258 
00259     DusEnd(&sql);
00260 
00261     status = DbExecuteSql(DbHandle(), sql, &result);
00262 
00263     if (status == 0) {
00264         status = DbFetchRow(result, &row);
00265         printf("Name:                            Capacity:    RequireBackup:\n");
00266         while (status == 0) {
00267             /* Got a row, print it */
00268             DbString(row, 0, &temp_name);
00269             DbString(row, 1, &temp_cap);
00270             DbInt(row, 2, &temp_back);
00271 
00272             printf("%-32s %-12s %s\n", temp_name, (strlen(temp_cap) == 0) ? "unset" : temp_cap, (temp_back == 0) ? "No" : "Yes");
00273             
00274             status = DbFetchRow(result, &row);
00275         }
00276 
00277         /* Convert EOF status to success */
00278 
00279         if (status == -1) {
00280             status = 0;
00281         }
00282 
00283         DbFreeResult(result);
00284     }
00285 
00286     DusFree(sql);
00287     DbFreeRow(row);
00288     DbStringFree(temp_name);
00289     DbStringFree(temp_cap);
00290 
00291     return status;
00292 }
00293 
00294 /*+
00295  * KsmListPolicies - Output a list of all policies available
00296  *
00297  *
00298  * Arguments:
00299  *
00300  *      none
00301  *
00302  * Returns:
00303  *      int
00304  *          Status return.  0 on success.
00305  *                          other on fail
00306  */
00307 
00308 int KsmListPolicies()
00309 {
00310     char*       sql = NULL;     /* SQL query */
00311     int         status = 0;     /* Status return */
00312     DB_RESULT   result;         /* Result of the query */
00313     DB_ROW      row = NULL;     /* Row data */
00314 
00315     char*       temp_name = NULL;   /* place to store name returned */
00316     char*       temp_desc = NULL;   /* place to store description returned */
00317 
00318     /* Select rows */
00319     StrAppend(&sql, "select name, description from policies ");
00320     StrAppend(&sql, "order by name");
00321 
00322     DusEnd(&sql);
00323 
00324     status = DbExecuteSql(DbHandle(), sql, &result);
00325 
00326     if (status == 0) {
00327         status = DbFetchRow(result, &row);
00328         printf("Name:                            Description:\n");
00329         while (status == 0) {
00330             /* Got a row, print it */
00331             DbString(row, 0, &temp_name);
00332             DbString(row, 1, &temp_desc);
00333 
00334             printf("%-32s %s\n", temp_name, (strlen(temp_desc) == 0) ? "unset" : temp_desc);
00335             
00336             status = DbFetchRow(result, &row);
00337         }
00338 
00339         /* Convert EOF status to success */
00340 
00341         if (status == -1) {
00342             status = 0;
00343         }
00344 
00345         DbFreeResult(result);
00346     }
00347 
00348     DusFree(sql);
00349     DbFreeRow(row);
00350     DbStringFree(temp_name);
00351     DbStringFree(temp_desc);
00352 
00353     return status;
00354 }
00355 
00356 /*+
00357  * KsmListRollovers - Output a list of expected rollovers
00358  *
00359  *
00360  * Arguments:
00361  *
00362  *      int zone_id
00363  *          ID of the zone (-1 for all)
00364  *
00365  * Returns:
00366  *      int
00367  *          Status return.  0 on success.
00368  *                          other on fail
00369  */
00370 
00371 int KsmListRollovers(int zone_id)
00372 {
00373     char*       sql = NULL;     /* SQL query */
00374     int         status = 0;     /* Status return */
00375     char        stringval[KSM_INT_STR_SIZE];  /* For Integer to String conversion */
00376     DB_RESULT   result;         /* Result of the query */
00377     DB_ROW      row = NULL;     /* Row data */
00378 
00379     char*       temp_zone = NULL;   /* place to store zone name returned */
00380     int         temp_type = 0;      /* place to store key type returned */
00381     char*       temp_date = NULL;   /* place to store date returned */
00382 
00383     /* Select rows */
00384     StrAppend(&sql, "select z.name, k.keytype, k.retire from zones z, KEYDATA_VIEW k where z.id = k.zone_id and k.state = 4 ");
00385     if (zone_id != -1) {
00386         StrAppend(&sql, "and zone_id = ");
00387         snprintf(stringval, KSM_INT_STR_SIZE, "%d", zone_id);
00388         StrAppend(&sql, stringval);
00389     }
00390     StrAppend(&sql, " order by zone_id");
00391 
00392     DusEnd(&sql);
00393 
00394     status = DbExecuteSql(DbHandle(), sql, &result);
00395 
00396     if (status == 0) {
00397         status = DbFetchRow(result, &row);
00398         printf("Zone:                           Keytype:      Rollover expected:\n");
00399         while (status == 0) {
00400             /* Got a row, print it */
00401             DbString(row, 0, &temp_zone);
00402             DbInt(row, 1, &temp_type);
00403             DbString(row, 2, &temp_date);
00404 
00405             printf("%-31s %-13s %s\n", temp_zone, (temp_type == KSM_TYPE_KSK) ? "KSK" : "ZSK", (temp_date == NULL) ? "(not scheduled)" : temp_date);
00406             
00407             status = DbFetchRow(result, &row);
00408         }
00409 
00410         /* Convert EOF status to success */
00411 
00412         if (status == -1) {
00413             status = 0;
00414         }
00415 
00416         DbFreeResult(result);
00417     }
00418 
00419     DusFree(sql);
00420     DbFreeRow(row);
00421     DbStringFree(temp_zone);
00422     DbStringFree(temp_date);
00423 
00424     return status;
00425 }
00426 
00427 /*+
00428  * KsmCheckNextRollover - Find next expected rollover
00429  *
00430  *
00431  * Arguments:
00432  *
00433  *      int keytype
00434  *          KSK or ZSK
00435  *
00436  *      int zone_id
00437  *          ID of the zone
00438  *
00439  *      char** datetime
00440  *          (returned) date that a rollover is expected
00441  *
00442  * Returns:
00443  *      int
00444  *          Status return.  0 on success.
00445  *                          other on fail
00446  */
00447 
00448 int KsmCheckNextRollover(int keytype, int zone_id, char** datetime)
00449 {
00450     char*       sql = NULL;     /* SQL query */
00451     int         status = 0;     /* Status return */
00452     DB_RESULT   result;         /* Result of the query */
00453     DB_ROW      row = NULL;     /* Row data */
00454 
00455     /* Select rows */
00456     sql = DqsSpecifyInit("KEYDATA_VIEW", "retire");
00457     DqsConditionInt(&sql, "KEYTYPE", DQS_COMPARE_EQ, keytype, 0);
00458     DqsConditionInt(&sql, "STATE", DQS_COMPARE_EQ, KSM_STATE_ACTIVE, 1);
00459     DqsConditionInt(&sql, "ZONE_ID", DQS_COMPARE_EQ, zone_id, 2);
00460     StrAppend(&sql, " order by retire asc");
00461 
00462     DqsEnd(&sql);
00463 
00464     status = DbExecuteSql(DbHandle(), sql, &result);
00465 
00466     if (status == 0) {
00467         status = DbFetchRow(result, &row);
00468 
00469         /* First row should be the closest rollover if there are multiple active keys */
00470         if (status == 0) {
00471             DbString(row, 0, datetime);
00472         }
00473 
00474         DbFreeResult(result);
00475         DbFreeRow(row);
00476     }
00477 
00478     DusFree(sql);
00479 
00480     return status;
00481 }