OpenDNSSEC-enforcer  1.3.8
/build/buildd/opendnssec-1.3.8/enforcer/ksm/ksm_parameter.c
Go to the documentation of this file.
00001 /*
00002  * $Id: ksm_parameter.c 3059 2010-03-16 11:52:08Z 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_parameter.c - Manipulation of Parameter Information
00031  *
00032  * Description:
00033  *      Holds the functions needed to manipulate the PARAMETER table.
00034  *
00035  *      N.B.  The table is the KEYDATA table - rather than the KEY table - as
00036  *      KEY is a reserved word in SQL.
00037 
00038 -*/
00039 
00040 #include <assert.h>
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <string.h>
00044 #include <time.h>
00045 
00046 #include "ksm/database.h"
00047 #include "ksm/database_statement.h"
00048 #include "ksm/datetime.h"
00049 #include "ksm/db_fields.h"
00050 #include "ksm/debug.h"
00051 #include "ksm/kmedef.h"
00052 #include "ksm/ksmdef.h"
00053 #include "ksm/ksm.h"
00054 #include "ksm/ksm_internal.h"
00055 #include "ksm/message.h"
00056 #include "ksm/string_util.h"
00057 
00058 
00059 
00060 
00061 /*+
00062  * KsmParameterInit - Query for Key Information
00063  *
00064  * Description:
00065  *      Performs a query for parameters in the parameter table that match the
00066  *      given conditions.
00067  *
00068  * Arguments:
00069  *      DB_RESULT* result
00070  *          Pointer to a result set to be used for information retrieval.  Will
00071  *          be undefined on error.
00072  *
00073  *      const char* name
00074  *          Name of the parameter to retrieve information on.  If NULL,
00075  *          information on all parameters is retrieved.
00076  *
00077  * Returns:
00078  *      int
00079  *          Status return.
00080  *
00081  *              0               Success
00082  *              Other   Error.  A message will have been output.
00083 -*/
00084 
00085 int KsmParameterInit(DB_RESULT* result, const char* name, const char* category, int policy_id)
00086 {
00087     int     where = 0;          /* WHERE clause value */
00088     char*   sql = NULL;         /* SQL query */
00089     int     status = 0;         /* Status return */
00090 
00091     /* Construct the query */
00092 
00093     sql = DqsSpecifyInit("PARAMETER_VIEW", DB_PARAMETER_VIEW_FIELDS);
00094     if (name) {
00095         DqsConditionString(&sql, "NAME", DQS_COMPARE_EQ, name, where++);
00096         DqsConditionString(&sql, "CATEGORY", DQS_COMPARE_EQ, category, where++);
00097     }
00098     DqsConditionInt(&sql, "policy_id", DQS_COMPARE_EQ, policy_id, where++);
00099 
00100     DqsOrderBy(&sql, "NAME");
00101 
00102     /* Execute query and free up the query string */
00103 
00104     status = DbExecuteSql(DbHandle(), sql, result);
00105 
00106     DqsFree(sql);
00107 
00108     return status;
00109 }
00110 
00111 /*+
00112  * KsmParameterExist - Does the parameter exist at all?
00113  *
00114  * Description:
00115  *      Performs a query for parameters in the parameter table that match the
00116  *      given conditions.
00117  *
00118  * Arguments:
00119  *      DB_RESULT* result
00120  *          Pointer to a result set to be used for information retrieval.  Will
00121  *          be undefined on error.
00122  *
00123  *      const char* name
00124  *          Name of the parameter to retrieve information on.  If NULL,
00125  *          information on all parameters is retrieved.
00126  *
00127  * Returns:
00128  *      int
00129  *          Status return.
00130  *
00131  *              0               Success
00132  *              Other   Error.  A message will have been output.
00133 -*/
00134 
00135 int KsmParameterExist(DB_RESULT* result, const char* name, const char* category, int* parameter_id)
00136 {
00137     int     where = 0;          /* WHERE clause value */
00138     char*   sql = NULL;         /* SQL query */
00139     DB_ROW              row = NULL;            /* Row data */
00140     int     status = 0;         /* Status return */
00141 
00142     /* Construct the query */
00143 
00144     sql = DqsSpecifyInit("PARAMETER_LIST", DB_PARAMETER_LIST_FIELDS);
00145     DqsConditionString(&sql, "NAME", DQS_COMPARE_EQ, name, where++);
00146     DqsConditionString(&sql, "CATEGORY", DQS_COMPARE_EQ, category, where++);
00147 
00148     DqsOrderBy(&sql, "NAME");
00149 
00150     /* Execute query and free up the query string */
00151 
00152     status = DbExecuteSql(DbHandle(), sql, result);
00153 
00154     if (status == 0) {
00155         status = DbFetchRow(*result, &row);
00156     }
00157     if (status == 0) {
00158         status = DbInt(row, DB_PARAMETER_ID, parameter_id);
00159     }
00160 
00161     DqsFree(sql);
00162     DbFreeRow(row);
00163 
00164     return status;
00165 }
00166 
00167 /*+
00168  * KsmParameter - Return Parameter Information
00169  *
00170  * Description:
00171  *      Returns information about the next key in the result set.
00172  *
00173  * Arguments:
00174  *      DB_RESULT result
00175  *          Result set from KsmParameterInit.
00176  *
00177  *      KSM_PARAMETER* data
00178  *          Data is returned in here.
00179  *
00180  * Returns:
00181  *      int
00182  *          Status return:
00183  *              0           success
00184  *              -1          end of record set reached
00185  *              non-zero    some error occurred and a message has been output.
00186  *
00187  *          If the status is non-zero, the returned data is meaningless.
00188 -*/
00189 
00190 int KsmParameter(DB_RESULT result, KSM_PARAMETER* data)
00191 {
00192     int         status = 0;     /* Return status */
00193     DB_ROW              row = NULL;     /* Row data */
00194 
00195     if (data == NULL) {
00196         return MsgLog(KSM_INVARG, "NULL data");
00197     }
00198 
00199         /* Initialize */
00200 
00201         memset(data, 0, sizeof(KSM_PARAMETER));
00202 
00203     /* Get the next row from the data */
00204 
00205         status = DbFetchRow(result, &row);
00206 
00207         if (status == 0) {
00208         status = DbStringBuffer(row, DB_PARAMETER_NAME, data->name,
00209             sizeof(data->name));
00210     }
00211         if (status == 0) {
00212         status = DbStringBuffer(row, DB_PARAMETER_CATEGORY, data->category,
00213             sizeof(data->category));
00214     }
00215     if (status == 0) {
00216         status = DbInt(row, DB_PARAMETER_ID, &(data->parameter_id));
00217     }
00218         if (status == 0) {
00219         status = DbInt(row, DB_PARAMETER_VALUE, &(data->value));
00220     }
00221 
00222     if (row != NULL) {
00223         DbFreeRow(row);
00224     }
00225 
00226     return status;
00227 }
00228 
00229 
00230 /*+
00231  * KsmParameterEnd - End Parameter Information
00232  *
00233  * Description:
00234  *      Called at the end of a KsmParameter cycle, frees up a result set.
00235  *
00236  * Arguments:
00237  *      DB_RESULT result
00238  *          Handle from KsmParameterInit
00239 -*/
00240 
00241 void KsmParameterEnd(DB_RESULT result)
00242 {
00243     DbFreeResult(result);
00244 }
00245 
00246 
00247 
00248 /*+
00249  * KsmParameterValue - Get Parameter Value
00250  *
00251  * Description:
00252  *      Gets the data for the named parameter.  If the parameter does not
00253  *      exist, a warning is output and an error returned.
00254  *
00255  * Arguments:
00256  *      const char* name
00257  *          Name of the parameter.
00258  *
00259  *      const char* category
00260  *          Category of the parameter.
00261  *
00262  *      int* value
00263  *          Location into which the value of the parameter is put.
00264  *
00265  *      int policy_id
00266  *          ID of the policy we are interested in
00267  *
00268  *      int* parameter_id
00269  *          Location into which the ID of the parameter is put.
00270  *
00271  * Returns:
00272  *      int
00273  *          0       Success, value found
00274  *          -2      Success, value not set
00275  *          Other   Error, message has been output
00276 -*/
00277 
00278 int KsmParameterValue(const char* name, const char* category, int* value, int policy_id, int* parameter_id)
00279 {
00280     DB_RESULT       handle;     /* Handle to the parameter information */
00281     DB_RESULT       handle2;     /* Handle to the parameter information */
00282     KSM_PARAMETER   data;       /* Parameter data */
00283     int             status;     /* Status return */
00284 
00285     /* check the arguments */
00286     if (value == NULL || parameter_id == NULL) {
00287         return MsgLog(KSM_INVARG, "NULL arg");
00288     }
00289     status = KsmParameterInit(&handle, name, category, policy_id);
00290     if (status == 0) {
00291 
00292         /* Initialized OK, get the value */
00293 
00294         status = KsmParameter(handle, &data);
00295         if (status == 0) {
00296             *value = data.value;
00297             *parameter_id = data.parameter_id;
00298         }
00299         else if (status == -1) {
00300             status = KsmParameterExist(&handle2, name, category, parameter_id);
00301             if (status == 0) {
00302                 /* parameter by that name exists, but is not set */
00303                 status = -2;
00304             } 
00305             else {
00306                 status = MsgLog(KME_NOSUCHPAR, name);
00307             }
00308             DbFreeResult(handle2);
00309         }
00310 
00311         /* ... and tidy up */
00312 
00313     }
00314     DbFreeResult(handle);
00315 
00316     return status;
00317 }
00318 
00319 
00320 
00321 /*+
00322  * KsmCollectionInit - Fill In Parameter Collection with defaults
00323  *
00324  * Description:
00325  *      Fills in the parameter collection object with the values of the
00326  *      parameters given in ksm.h.
00327  *
00328  * Arguments:
00329  *      KSM_PARCOLL* data
00330  *          Pointer to the parameter collection object.  This will be filled in
00331  *          by this function.
00332  *
00333  * Returns:
00334  *      int
00335  *          0       Success
00336  *          Other   One or more errors,  in which case a message will have been
00337  *                  output.
00338 -*/
00339 
00340 int KsmCollectionInit(KSM_PARCOLL* data)
00341 {
00342     if (data == NULL) {
00343         return MsgLog(KSM_INVARG, "NULL data");
00344     }
00345 
00346     data->clockskew = KSM_PAR_CLOCKSKEW;
00347     data->ksklife = KSM_PAR_KSKLIFE;
00348     data->standbyksks = KSM_PAR_STANDBYKSKS;
00349     data->standbyzsks = KSM_PAR_STANDBYZSKS;
00350     data->propdelay = KSM_PAR_PROPDELAY;
00351     data->signint = KSM_PAR_SIGNINT;
00352     data->soamin = KSM_PAR_SOAMIN;
00353     data->soattl = KSM_PAR_SOATTL;
00354     data->zsksiglife = KSM_PAR_ZSKSIGLIFE;
00355     data->zsklife = KSM_PAR_ZSKLIFE;
00356     data->zskttl = KSM_PAR_ZSKTTL;
00357     data->kskttl = KSM_PAR_KSKTTL;
00358     data->kskpropdelay = KSM_PAR_KSKPROPDELAY;
00359     data->regdelay = KSM_PAR_REGDELAY;
00360     data->pub_safety = KSM_PAR_PUBSAFETY;
00361     data->ret_safety = KSM_PAR_RETSAFETY;
00362 
00363     return(0);
00364 }
00365 
00366 /*+
00367  * KsmParameterCollection - Fill In Parameter Collection Given Name
00368  *
00369  * Description:
00370  *      Fills in the parameter collection object with the values of the
00371  *      parameters.
00372  *
00373  * Arguments:
00374  *      KSM_PARCOLL* data
00375  *          Pointer to the parameter collection object.  This will be filled in
00376  *          by this function.
00377  *
00378  * Returns:
00379  *      int
00380  *          0       Success
00381  *          Other   One or more errors,  in which case a message will have been
00382  *                  output.
00383 -*/
00384 
00385 int KsmParameterCollection(KSM_PARCOLL* data, int policy_id)
00386 {
00387     int status = 0;
00388     int param_id;
00389 
00390     /* check the arguments */
00391     if (data == NULL) {
00392         return MsgLog(KSM_INVARG, "NULL data");
00393     }
00394 
00395     status = KsmParameterValue(KSM_PAR_CLOCKSKEW_STRING, KSM_PAR_CLOCKSKEW_CAT, &(data->clockskew), policy_id, &param_id);
00396     if (status > 0) return status;
00397 
00398     status = KsmParameterValue(KSM_PAR_KSKLIFE_STRING, KSM_PAR_KSKLIFE_CAT, &(data->ksklife), policy_id, &param_id);
00399     if (status > 0) return status;
00400 
00401     status = KsmParameterValue(KSM_PAR_STANDBYKSKS_STRING, KSM_PAR_STANDBYKSKS_CAT, &(data->standbyksks), policy_id, &param_id);
00402     if (status > 0) return status;
00403 
00404     status = KsmParameterValue(KSM_PAR_STANDBYZSKS_STRING, KSM_PAR_STANDBYZSKS_CAT, &(data->standbyzsks), policy_id, &param_id);
00405     if (status > 0) return status;
00406 
00407     status = KsmParameterValue(KSM_PAR_PROPDELAY_STRING, KSM_PAR_PROPDELAY_CAT, &(data->propdelay), policy_id, &param_id);
00408     if (status > 0) return status;
00409 
00410     status = KsmParameterValue(KSM_PAR_SIGNINT_STRING, KSM_PAR_SIGNINT_CAT, &(data->signint), policy_id, &param_id);
00411     if (status > 0) return status;
00412 
00413     status = KsmParameterValue(KSM_PAR_SOAMIN_STRING, KSM_PAR_SOAMIN_CAT, &(data->soamin), policy_id, &param_id);
00414     if (status > 0) return status;
00415 
00416     status = KsmParameterValue(KSM_PAR_SOATTL_STRING, KSM_PAR_SOATTL_CAT, &(data->soattl), policy_id, &param_id);
00417     if (status > 0) return status;
00418 
00419     status = KsmParameterValue(KSM_PAR_ZSKSIGLIFE_STRING, KSM_PAR_ZSKSIGLIFE_CAT, &(data->zsksiglife), policy_id, &param_id);
00420     if (status > 0) return status;
00421 
00422     status = KsmParameterValue(KSM_PAR_ZSKLIFE_STRING, KSM_PAR_ZSKLIFE_CAT, &(data->zsklife), policy_id, &param_id);
00423     if (status > 0) return status;
00424 
00425     status = KsmParameterValue(KSM_PAR_ZSKTTL_STRING, KSM_PAR_ZSKTTL_CAT, &(data->zskttl), policy_id, &param_id);
00426     if (status > 0) return status;
00427 
00428     status = KsmParameterValue(KSM_PAR_KSKTTL_STRING, KSM_PAR_KSKTTL_CAT, &(data->kskttl), policy_id, &param_id);
00429     if (status > 0) return status;
00430 
00431     status = KsmParameterValue(KSM_PAR_KSKPROPDELAY_STRING, KSM_PAR_KSKPROPDELAY_CAT, &(data->kskpropdelay), policy_id, &param_id);
00432     if (status > 0) return status;
00433 
00434     status = KsmParameterValue(KSM_PAR_REGDELAY_STRING, KSM_PAR_REGDELAY_CAT, &(data->regdelay), policy_id, &param_id);
00435     if (status > 0) return status;
00436 
00437     status = KsmParameterValue(KSM_PAR_PUBSAFETY_STRING, KSM_PAR_PUBSAFETY_CAT, &(data->pub_safety), policy_id, &param_id);
00438     if (status > 0) return status;
00439 
00440     status = KsmParameterValue(KSM_PAR_RETSAFETY_STRING, KSM_PAR_RETSAFETY_CAT, &(data->ret_safety), policy_id, &param_id);
00441     if (status > 0) return status;
00442 
00443     status = KsmParameterValue(KSM_PAR_KSK_MAN_ROLL_STRING, KSM_PAR_KSK_MAN_ROLL_CAT, &(data->kskmanroll), policy_id, &param_id);
00444     if (status > 0) return status;
00445 
00446     status = KsmParameterValue(KSM_PAR_ZSK_MAN_ROLL_STRING, KSM_PAR_ZSK_MAN_ROLL_CAT, &(data->zskmanroll), policy_id, &param_id);
00447     if (status > 0) return status;
00448 
00449     status = KsmParameterValue(KSM_PAR_DSTTL_STRING, KSM_PAR_DSTTL_CAT, &(data->dsttl), policy_id, &param_id);
00450     if (status > 0) return status;
00451 
00452 /* For now we only set our default KSK rollover scheme */
00453 /*    status = KsmParameterValue(KSM_PAR_KSK_ROLL_STRING, KSM_PAR_KSK_ROLL_CAT, &(data->kskroll), policy_id, &param_id);
00454     if (status > 0) return status;
00455     else if (status == -2) 
00456     { */
00457         /* Not set, use our default */
00458         data->kskroll = KSM_ROLL_DEFAULT;
00459     /*}*/
00460 
00461     return 0;
00462 }
00463 
00464 
00465 
00466 
00467 /*+
00468  * KsmParameterSet - Set Parameter Entry
00469  *
00470  * Description:
00471  *      Sets the value of a parameter in the database.
00472  *
00473  * Arguments:
00474  *      const char* name
00475  *          Name of parameter to set.  This must exist, else the setting
00476  *          will fail.
00477  *
00478  *      int value
00479  *          Value of the parameter.  For intervals, this is the value in
00480  *          seconds.
00481  *
00482  * Returns:
00483  *      int
00484  *          Status return.  0 => Success, non-zero => error.DisInt
00485 -*/
00486 
00487 int KsmParameterSet(const char* name, const char* category, int value, int policy_id)
00488 {
00489     int             curvalue;               /* Current value */
00490     int             param_id;               /* Unique ID of this param */
00491     int             status = 0;             /* Status return */
00492     int             set = 0;                /* SET clause value */
00493     char*           sql = NULL;             /* SQL for the insert */
00494     int             where = 0;              /* WHERE clause value */
00495 
00496     /* Check to see if the parameter exists */
00497 
00498     status = KsmParameterValue(name, category, &curvalue, policy_id, &param_id);
00499     if (status == 0) {
00500 
00501         /* It does.  Update the value */
00502 
00503         sql = DusInit("parameters_policies");
00504         DusSetInt(&sql, "value", value, set++);
00505         DusConditionInt(&sql, "parameter_id", DQS_COMPARE_EQ, param_id, where++);
00506         DusConditionInt(&sql, "policy_id", DQS_COMPARE_EQ, policy_id, where++);
00507         DusEnd(&sql);
00508 
00509         status = DbExecuteSqlNoResult(DbHandle(), sql);
00510         DusFree(sql);
00511     }
00512     else if (status == -2) {
00513         /* param name is legal, but is not set for this policy */
00514         sql = DisInit("parameters_policies");
00515         DisAppendInt(&sql, param_id);
00516         DisAppendInt(&sql, policy_id);
00517         DisAppendInt(&sql, value);
00518         DisEnd(&sql);
00519 
00520         status = DbExecuteSqlNoResult(DbHandle(), sql);
00521         DisFree(sql);
00522     }
00523     /*
00524      * else {
00525      *      Error.  A message will have been output.
00526      * }
00527      */
00528 
00529     return status;
00530 }
00531 
00532 /*+
00533  * KsmParameterShow - Show Parameter
00534  *
00535  * Description:
00536  *      Prints to stdout the values of the parameter (or parameters).
00537  *
00538  * Arguments:
00539  *      const char* name
00540  *          Name of parameter to output, or NULL for all parameters.
00541 -*/
00542 
00543 int KsmParameterShow(const char* name, const char* category, int policy_id)
00544 {
00545     KSM_PARAMETER data;         /* Parameter information */
00546     DB_RESULT   result;         /* Result of parameter query */
00547     int         param_id;       /* Unique ID of param */
00548     int         status = 0;     /* Status return */
00549     char        text[32];       /* For translated string */
00550     int         value;          /* Value of the parameter */
00551 
00552     /*
00553      * If a parameter was given, does it exist?  An error will be output if not
00554      * and the status return will be non-zero.
00555      */
00556 
00557     if (name) {
00558         status = KsmParameterValue(name, category, &value, policy_id, &param_id);
00559     }
00560 
00561     if (status == 0) {
00562 
00563         /* No problem to perform ther listing */
00564 
00565         status = KsmParameterInit(&result, name, category, policy_id);
00566         if (status == 0) {
00567             status = KsmParameter(result, &data);
00568             while (status == 0) {
00569 
00570                 /* Get a text form of the value */
00571 
00572                 DtSecondsInterval(data.value, text, sizeof(text));
00573 
00574                 /* ... and print */
00575 
00576                 StrTrimR(data.name);
00577                 printf("%-12s %-12s %9d (%s)\n", data.name, data.category, data.value, text);
00578                 
00579                 /* Get the next parameter */
00580 
00581                 status = KsmParameter(result, &data);
00582             }
00583 
00584             /* All done, so tidy up */
00585 
00586             KsmParameterEnd(result);
00587         }
00588     }
00589 
00590     return 0;
00591 }