OpenDNSSEC-enforcer  1.3.4
/build/buildd/opendnssec-1.3.4/enforcer/ksm/ksm_policy.c
Go to the documentation of this file.
00001 /*
00002  * $Id: ksm_policy.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_policy.c - Manipulation of Policy Information
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/kmedef.h"
00046 #include "ksm/ksm.h"
00047 #include "ksm/ksm_internal.h"
00048 #include "ksm/message.h"
00049 #include "ksm/string_util.h"
00050 
00051 /*+
00052  * KsmPolicyInit - Query for Policy Information
00053  *
00054  *
00055  * Arguments:
00056  *      DB_RESULT* result
00057  *          Pointer to a handle to be used for information retrieval.  Will
00058  *          be NULL on error.
00059  *
00060  *      const char* name
00061  *          Name of the parameter to retrieve information on.  If NULL, information
00062  *          on all parameters is retrieved.
00063  *
00064  * Returns:
00065  *      int
00066  *          Status return.  0 on success.
00067 -*/
00068 
00069 int KsmPolicyInit(DB_RESULT* result, const char* name)
00070 {
00071     int     where = 0;          /* WHERE clause value */
00072     char*   sql = NULL;         /* SQL query */
00073     int     status = 0;         /* Status return */
00074 
00075     /* Construct the query */
00076 
00077     sql = DqsSpecifyInit("policies","id, name, description, audit, salt");
00078     if (name) {
00079         DqsConditionString(&sql, "NAME", DQS_COMPARE_EQ, name, where++);
00080     }
00081     DqsOrderBy(&sql, "id");
00082 
00083     /* Execute query and free up the query string */
00084 
00085     status = DbExecuteSql(DbHandle(), sql, result);
00086 
00087     DqsFree(sql);
00088 
00089     return status;
00090 }
00091 
00092 /*+
00093  * KsmPolicyParametersInit - Query for Policy Information
00094  *
00095  *
00096  * Arguments:
00097  *      DB_RESULT* result
00098  *          Pointer to a handle to be used for information retrieval.  Will
00099  *          be NULL on error.
00100  *
00101  *      const char* name
00102  *          Name of the parameter to retrieve information on.  If NULL, information
00103  *          on all parameters is retrieved.
00104  *
00105  * Returns:
00106  *      int
00107  *          Status return.  0 on success.
00108 -*/
00109 
00110 int KsmPolicyParametersInit(DB_RESULT* result, const char* name)
00111 {
00112     int     where = 0;          /* WHERE clause value */
00113     char*   sql = NULL;         /* SQL query */
00114     int     status = 0;         /* Status return */
00115 
00116     /* Construct the query */
00117 
00118     sql = DqsSpecifyInit("policies p, parameters_policies x, parameters y, categories c ","y.name, c.name, x.value");
00119     DqsConditionKeyword(&sql, "p.id", DQS_COMPARE_EQ, "x.policy_id", where++);
00120     DqsConditionKeyword(&sql, "y.id", DQS_COMPARE_EQ, "x.parameter_id", where++);
00121     DqsConditionKeyword(&sql, "c.id", DQS_COMPARE_EQ, "y.category_id", where++);
00122     if (name) {
00123         DqsConditionString(&sql, "p.NAME", DQS_COMPARE_EQ, name, where++);
00124     }
00125     DqsOrderBy(&sql, "p.NAME");
00126 
00127     /* Execute query and free up the query string */
00128 
00129     status = DbExecuteSql(DbHandle(), sql, result);
00130 
00131     DqsFree(sql);
00132 
00133     return status;
00134 }
00135 
00136 /*+
00137  * KsmPolicyExists - Check Policy Exists
00138  *
00139  *
00140  * Arguments:
00141  *      const char* name
00142  *          Name of the parameter.
00143  *
00144  *
00145  * Returns:
00146  *      int
00147  *          0       Success, value found
00148  *          Other   Error, message has been output
00149 -*/
00150 
00151 int KsmPolicyExists(const char* name)
00152 {
00153     int             status;     /* Status return */
00154     DB_RESULT       result;     /* Handle converted to a result object */
00155     DB_ROW          row = NULL; /* Row data */
00156 
00157     status = KsmPolicyInit(&result, name);
00158     if (status == 0) {
00159         /* Get the next row from the data */
00160         status = DbFetchRow(result, &row);
00161         if (status > 0) {
00162             /* Error */
00163             status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00164         }
00165     }
00166     DbFreeRow(row);
00167     DbFreeResult(result);
00168     return status;
00169 }
00170 
00171 /*+
00172  * KsmPolicy - Return Policy Information
00173  *
00174  * Arguments:
00175  *      DB_RESULT result
00176  *          Handle from KsmParameterInit
00177  *
00178  *      KSM_PARAMETER* data
00179  *          Data is returned in here.
00180  *
00181  * Returns:
00182  *      int
00183  *          Status return:
00184  *              0           success
00185  *              -1          end of record set reached
00186  *              non-zero    some error occurred and a message has been output.
00187  *
00188  *          If the status is non-zero, the returned data is meaningless.
00189 -*/
00190 
00191 int KsmPolicy(DB_RESULT result, KSM_POLICY* data)
00192 {
00193     int         status = 0;     /* Return status */
00194     DB_ROW      row = NULL;     /* Row data */
00195 
00196     /* check the argument */
00197     if (data == NULL) {
00198         return MsgLog(KSM_INVARG, "NULL data");
00199     }
00200 
00201     /* Get the next row from the data */
00202     status = DbFetchRow(result, &row);
00203     if (status == 0) {
00204 
00205         status = DbInt(row, DB_POLICY_ID, &(data->id));
00206         DbStringBuffer(row, DB_POLICY_NAME, data->name, KSM_NAME_LENGTH*sizeof(char));
00207     }
00208     else if (status == -1) {}
00209         /* No rows to return (but no error) */
00210         else {
00211         status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00212         }
00213 
00214     if (row != NULL) {
00215         DbFreeRow(row);
00216     }
00217 
00218     return status;
00219 }
00220 
00221 /*+
00222  * KsmPolicyRead - Read Policy
00223  *
00224  * Description:
00225  *      Read policy from database in to a struct.
00226  *
00227  * Arguments:
00228  *      struct policy_t policy
00229  *              struct to hold policy information, it needs to have the policy name set
00230 -*/
00231 
00232 int KsmPolicyRead(KSM_POLICY* policy)
00233 {
00234     KSM_POLICY_PARAMETER data;           /* Parameter information */
00235     DB_RESULT            result;         /* Handle to parameter */
00236     int                  status = 0;     /* Status return */
00237 
00238     /* check the argument */
00239     if (policy == NULL) {
00240         return MsgLog(KSM_INVARG, "NULL policy");
00241     }
00242 
00243     /* status = KsmPolicyExists(policy->name); */
00244     status = KsmPolicySetIdFromName(policy);
00245 
00246     if (status == 0) {
00247 
00248         status = KsmPolicyParametersInit(&result, policy->name);
00249         if (status == 0) {
00250             status = KsmPolicyParameter(result, &data);
00251             while (status == 0) {
00252                 if (strncmp(data.category, "enforcer", 8) == 0) {
00253 /*                      if (strncmp(data.name, "keycreate", 9) == 0) policy->enforcer->keycreate=data.value;
00254                         if (strncmp(data.name, "backup_interval", 15) == 0) policy->enforcer->backup_interval=data.value; */
00255                         if (strncmp(data.name, "keygeninterval", 14) == 0) policy->enforcer->keygeninterval=data.value;
00256                 }
00257                 if (strncmp(data.category, "zone", 4) == 0) {
00258                         if (strncmp(data.name, "propagationdelay", 16) == 0) policy->signer->propdelay=data.value;
00259                         if (strncmp(data.name, "min", 3) == 0) policy->signer->soamin=data.value;
00260                         if (strncmp(data.name, "ttl", 2) == 0) policy->signer->soattl=data.value;
00261                         if (strncmp(data.name, "serial", 6) == 0) policy->signer->serial=data.value;
00262                         if (strncmp(data.name, "propagationdelay", 16) == 0) policy->zone->propdelay=data.value;
00263                         if (strncmp(data.name, "min", 3) == 0) policy->zone->soa_min=data.value;
00264                         if (strncmp(data.name, "ttl", 3) == 0) policy->zone->soa_ttl=data.value;
00265                         if (strncmp(data.name, "serial", 6) == 0) policy->zone->serial=data.value;
00266                 }
00267                 if (strncmp(data.category, "parent", 6) == 0) {
00268                         if (strncmp(data.name, "propagationdelay", 16) == 0) policy->parent->propdelay=data.value;
00269                         if (strncmp(data.name, "min", 3) == 0) policy->parent->soa_min=data.value;
00270                         if (strncmp(data.name, "ttl", 3) == 0) policy->parent->soa_ttl=data.value;
00271                         if (strncmp(data.name, "ttlds", 5) == 0) policy->parent->ds_ttl=data.value;
00272                 }
00273                 if (strncmp(data.category, "signature", 9) == 0) {
00274                         if (strncmp(data.name, "jitter", 6) == 0) policy->signer->jitter=data.value;
00275                         if (strncmp(data.name, "refresh", 7) == 0) policy->signer->refresh=data.value;
00276                         if (strncmp(data.name, "clockskew", 9) == 0) policy->signature->clockskew=data.value;
00277                         if (strncmp(data.name, "resign", 6) == 0) policy->signature->resign=data.value;
00278                         if (strncmp(data.name, "valdefault", 10) == 0) policy->signature->valdefault=data.value;
00279                         if (strncmp(data.name, "valdenial", 9) == 0) policy->signature->valdenial=data.value;
00280                 }
00281                 if (strncmp(data.category, "denial", 6) == 0) {
00282                         if (strncmp(data.name, "version", 7) == 0) policy->denial->version=data.value;
00283                         if (strncmp(data.name, "resalt", 6) == 0) policy->denial->resalt=data.value;
00284                         if (strncmp(data.name, "alg", 3) == 0) policy->denial->algorithm=data.value;
00285                         if (strncmp(data.name, "iteration", 9) == 0) policy->denial->iteration=data.value;
00286                         if (strncmp(data.name, "optout", 6) == 0) policy->denial->optout=data.value;
00287                         if (strncmp(data.name, "ttl",3) == 0) policy->denial->ttl=data.value;
00288                         if (strncmp(data.name, "saltlength",10) == 0) policy->denial->saltlength=data.value;
00289                 }
00290                 if (strncmp(data.category, "zsk", 3) == 0) {
00291                         if (strncmp(data.name, "alg",3) == 0) policy->zsk->algorithm=data.value;
00292                         if (strncmp(data.name, "lifetime",8) == 0) policy->zsk->lifetime=data.value;
00293                         if (strncmp(data.name, "repository",10) == 0) policy->zsk->sm=data.value;
00294                         if (strncmp(data.name, "overlap",7) == 0) policy->zsk->overlap=data.value;
00295                         if (strncmp(data.name, "bits",4) == 0) policy->zsk->bits=data.value;
00296                     if (strncmp(data.name, "standby",7) == 0) policy->zsk->standby_keys=data.value;
00297                     if (strncmp(data.name, "manual_rollover",15) == 0) policy->zsk->manual_rollover=data.value;
00298                 }
00299                 if (strncmp(data.category, "ksk", 3) == 0) {
00300                         if (strncmp(data.name, "alg",3) == 0) policy->ksk->algorithm=data.value;
00301                         if (strncmp(data.name, "lifetime",8) == 0) policy->ksk->lifetime=data.value;
00302                         if (strncmp(data.name, "repository",10) == 0) policy->ksk->sm=data.value;
00303                         if (strncmp(data.name, "overlap",7) == 0) policy->ksk->overlap=data.value;
00304                         if (strncmp(data.name, "rfc5011",7) == 0) policy->ksk->rfc5011=data.value;
00305                         if (strncmp(data.name, "bits",4) == 0) policy->ksk->bits=data.value;
00306                     if (strncmp(data.name, "standby",7) == 0) policy->ksk->standby_keys=data.value;
00307                     if (strncmp(data.name, "manual_rollover",15) == 0) policy->ksk->manual_rollover=data.value;
00308                     if (strncmp(data.name, "rollover_scheme",15) == 0) policy->ksk->rollover_scheme=data.value;
00309                 }
00310                 if (strncmp(data.category, "keys", 4) == 0) {
00311                         if (strncmp(data.name, "ttl",3) == 0) policy->ksk->ttl=data.value;
00312                         if (strncmp(data.name, "ttl",3) == 0) policy->zsk->ttl=data.value;
00313                         if (strncmp(data.name, "zones_share_keys",16) == 0) policy->shared_keys=data.value;
00314                         if (strncmp(data.name, "ttl",3) == 0) policy->keys->ttl=data.value;
00315                         if (strncmp(data.name, "zones_share_keys",16) == 0) policy->keys->share_keys=data.value;
00316                         if (strncmp(data.name, "retiresafety",12) == 0) policy->keys->retire_safety=data.value;
00317                         if (strncmp(data.name, "publishsafety",13) == 0) policy->keys->publish_safety=data.value;
00318                         if (strncmp(data.name, "purge",5) == 0) policy->keys->purge=data.value;
00319                 }
00320             /*  if (strncmp(data.category, "audit", 5) == 0) {
00321                         if (strncmp(data.name, "audit",5) == 0) policy->audit->audit=data.value;
00322                 }*/
00323                         /* Ignore any unknown parameters */
00324 
00325                 status = KsmPolicyParameter(result, &data);
00326             }
00327 
00328             /* All done, so tidy up */
00329 
00330             KsmParameterEnd(result);
00331         }
00332     } else {
00333         return status;
00334     }
00335 
00336     /* convert security module ids into names, capacities and requirebackup flags */
00337     status = KsmPolicyPopulateSMFromIds(policy);
00338 
00339     return status;
00340 }
00341 
00342 /*+
00343  * KsmPolicyParameter - Return PolicyParameter Information
00344  *
00345  * Description:
00346  *      Returns information about the next key in the result set.
00347  *
00348  * Arguments:
00349  *      DB_RESULT result
00350  *          Handle from KsmParameterInit
00351  *
00352  *      KSM_PARAMETER* data
00353  *          Data is returned in here.
00354  *
00355  * Returns:
00356  *      int
00357  *          Status return:
00358  *              0           success
00359  *              -1          end of record set reached
00360  *              non-zero    some error occurred and a message has been output.
00361  *
00362  *          If the status is non-zero, the returned data is meaningless.
00363 -*/
00364 
00365 int KsmPolicyParameter(DB_RESULT result, KSM_POLICY_PARAMETER* data)
00366 {
00367     int         status = 0;     /* Return status */
00368     DB_ROW      row = NULL;     /* Row data */
00369 
00370     /* check the argument */
00371     if (data == NULL) {
00372         return MsgLog(KSM_INVARG, "NULL data");
00373     }
00374 
00375     /* Get the next row from the data */
00376     status = DbFetchRow(result, &row);
00377 
00378     if (status == 0) {
00379 
00380         /* Now copy the results into the output data */
00381 
00382         memset(data, 0, sizeof(KSM_POLICY_PARAMETER));
00383         DbStringBuffer(row, DB_POLICY_PARAMETER_NAME, data->name,
00384             sizeof(data->name));
00385         DbStringBuffer(row, DB_POLICY_PARAMETER_CATEGORY, data->category,
00386                     sizeof(data->category));
00387         status = DbInt(row, DB_POLICY_PARAMETER_VALUE, &(data->value));
00388     }
00389     else if (status == -1) {}
00390         /* No rows to return (but no error) */
00391         else {
00392         status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00393         }
00394 
00395     if (row != NULL) {
00396         DbFreeRow(row);
00397     }
00398 
00399     return status;
00400 }
00401 
00402 /*+
00403  * KsmPolicyReadFromId - Read Policy given just the id
00404  *
00405  * Description:
00406  *      Read policy from database in to a struct.
00407  *
00408  * Arguments:
00409  *      struct policy_t policy
00410  *              struct to hold policy information should have id populated
00411 -*/
00412 
00413 int KsmPolicyReadFromId(KSM_POLICY* policy)
00414 {
00415     int status = KsmPolicyNameFromId(policy);
00416 
00417     if (status != 0)
00418     {
00419         return status;
00420     }
00421 
00422     return KsmPolicyRead(policy);
00423 
00424 }
00425 
00426 int KsmPolicyNameFromId(KSM_POLICY* policy)
00427 {
00428     int     where = 0;          /* WHERE clause value */
00429     char*   sql = NULL;         /* SQL query */
00430     DB_RESULT       result;     /* Handle converted to a result object */
00431     DB_ROW      row = NULL;            /* Row data */
00432     int     status = 0;         /* Status return */
00433 
00434     /* check the argument */
00435     if (policy == NULL) {
00436         return MsgLog(KSM_INVARG, "NULL policy");
00437     }
00438 
00439     /* Construct the query */
00440 
00441     sql = DqsSpecifyInit("policies","id, name");
00442     DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, policy->id, where++);
00443     DqsOrderBy(&sql, "id");
00444 
00445     /* Execute query and free up the query string */
00446     status = DbExecuteSql(DbHandle(), sql, &result);
00447     DqsFree(sql);
00448     
00449     if (status != 0)
00450     {
00451         status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00452         DbFreeResult(result);
00453         return status;
00454         }
00455 
00456     /* Get the next row from the data */
00457     status = DbFetchRow(result, &row);
00458     if (status == 0) {
00459         DbStringBuffer(row, DB_POLICY_NAME, policy->name, KSM_NAME_LENGTH*sizeof(char));
00460     }
00461     else if (status == -1) {}
00462         /* No rows to return (but no error) */
00463         else {
00464         status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00465         }
00466 
00467     DbFreeRow(row);
00468     DbFreeResult(result);
00469     return status;
00470 }
00471 
00472 /*+
00473  * KsmPolicyUpdateSalt
00474  *
00475  * Description:
00476  *      Given a policy see if the salt needs updating (based on denial->resalt).
00477  *      If it is out of date then generate a new salt and write it to the struct.
00478  *      Also update the database with the new value and timestamp.
00479  *
00480  * Arguments:
00481  *      struct policy_t policy
00482  *              struct which holds the current policy information should have been populated
00483  *
00484  * Returns:
00485  *      int
00486  *          Status return:
00487  *              0           success
00488  *              non-zero    some error occurred and a message has been output.
00489  *              -1          no policy found
00490  *              -2          an error working out time difference between stamp and now
00491  *
00492 -*/
00493 
00494 int KsmPolicyUpdateSalt(KSM_POLICY* policy)
00495 {
00496     /* First work out what the current salt is and when it was created */
00497     int     where = 0;          /* WHERE clause value */
00498     char*   sql = NULL;         /* SQL query */
00499     DB_RESULT       result;     /* Handle converted to a result object */
00500     DB_ROW      row = NULL;            /* Row data */
00501     int     status = 0;         /* Status return */
00502     char*   datetime_now = DtParseDateTimeString("now");    /* where are we in time */
00503     int     time_diff;          /* how many second have elapsed */
00504     char*   salt;               /* This will be the salt that we create */
00505     char    buffer[KSM_SQL_SIZE];   /* update statement for salt_stamp */
00506     unsigned int    nchar;          /* Number of characters converted */
00507     int     i = 0;              /* a counter */
00508     char*   hex_chars = "0123456789abcdef"; /* for "manual" random string */
00509 
00510     /* check the argument */
00511     if (policy == NULL) {
00512         MsgLog(KSM_INVARG, "NULL policy");
00513         StrFree(datetime_now);
00514         return -1;
00515     }
00516 
00517     /* Check datetime in case it came back NULL */
00518     if (datetime_now == NULL) {
00519         printf("Couldn't turn \"now\" into a date, quitting...\n");
00520         exit(1);
00521     }
00522 
00523     /* Construct the query */
00524 
00525     sql = DqsSpecifyInit("policies","id, salt, salt_stamp");
00526     DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, policy->id, where++);
00527     DqsOrderBy(&sql, "id");
00528 
00529     /* Execute query and free up the query string */
00530     status = DbExecuteSql(DbHandle(), sql, &result);
00531     DqsFree(sql);
00532     
00533     if (status != 0)
00534     {
00535         status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00536         StrFree(datetime_now);
00537         return status;
00538         }
00539 
00540     /* Get the next row from the data */
00541     status = DbFetchRow(result, &row);
00542     if (status == 0) {
00543         status = DbStringBuffer(row, DB_POLICY_SALT, policy->denial->salt, KSM_SALT_LENGTH*sizeof(char));
00544         if (status == 0) {
00545             status = DbStringBuffer(row, DB_POLICY_SALT_STAMP, policy->denial->salt_stamp, KSM_TIME_LENGTH*sizeof(char));
00546         }
00547 
00548         if (status != 0) {
00549             status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00550             DbFreeResult(result);
00551             DbFreeRow(row);
00552             StrFree(datetime_now);
00553             return status;
00554         }
00555     }
00556     else if (status == -1) {
00557         /* No rows to return (but no error), policy_id doesn't exist? */
00558         DbFreeResult(result);
00559         DbFreeRow(row);
00560         StrFree(datetime_now);
00561         return -1;
00562     }
00563         else {
00564         status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00565 
00566         DbFreeResult(result);
00567         DbFreeRow(row);
00568         StrFree(datetime_now);
00569         return status;
00570         }
00571 
00572     DbFreeResult(result);
00573     DbFreeRow(row);
00574 
00575     /* Now see if this needs to be updated; if the stamp is null then assume it does */
00576     if (policy->denial->salt_stamp[0] == '\0') {
00577         time_diff = -1;
00578     } else {
00579         status = DtDateDiff(datetime_now, policy->denial->salt_stamp, &time_diff);
00580     }
00581 
00582     if (status == 0) {
00583         if (policy->denial->resalt > time_diff && time_diff != -1 && policy->denial->salt[0] != '\0') {
00584             /* current salt is fine */
00585             StrFree(datetime_now);
00586             return status;
00587         } else {
00588             /* salt needs updating, or is null */
00589             salt = (char *)calloc(KSM_SALT_LENGTH, sizeof(char));
00590             if (salt == NULL) {
00591                 MsgLog(KSM_INVARG, "Could not allocate memory for salt");
00592                 StrFree(datetime_now);
00593                 exit(1);
00594             }
00595 
00596 #ifdef HAVE_ARC4RANDOM
00597             for (i = 0; i < 2*(policy->denial->saltlength); i++) {
00598                 salt[i] = hex_chars[arc4random()%strlen(hex_chars)];
00599             }
00600 #else
00601             srand( time(NULL) );
00602             for (i = 0; i < 2*(policy->denial->saltlength); i++) {
00603                 salt[i] = hex_chars[rand()%strlen(hex_chars)];
00604             }
00605 #endif
00606 
00607             if (status != 0) {
00608                 StrFree(datetime_now);
00609                 StrFree(salt);
00610                 return status;
00611             }
00612             StrStrncpy(policy->denial->salt, salt, KSM_SALT_LENGTH);
00613             StrStrncpy(policy->denial->salt_stamp, datetime_now, KSM_TIME_LENGTH);
00614             
00615             StrFree(salt);
00616 
00617             /* write these back to the database */
00618 #ifdef USE_MYSQL
00619             nchar = snprintf(buffer, sizeof(buffer),
00620                     "UPDATE policies SET salt = '%s', salt_stamp = \"%s\" WHERE ID = %lu",
00621                     policy->denial->salt, policy->denial->salt_stamp, (unsigned long) policy->id);
00622 #else
00623             nchar = snprintf(buffer, sizeof(buffer),
00624                     "UPDATE policies SET salt = '%s', salt_stamp = DATETIME('%s') WHERE ID = %lu",
00625                     policy->denial->salt, policy->denial->salt_stamp, (unsigned long) policy->id);
00626 #endif /* USE_MYSQL */
00627             if (nchar < sizeof(buffer)) {
00628                 /* All OK, execute the statement */
00629 
00630                 status = DbExecuteSqlNoResult(DbHandle(), buffer);
00631             }
00632             else {
00633                 /* Unable to create update statement */
00634 
00635                 status = MsgLog(KME_BUFFEROVF, "KsmPolicy");
00636             }
00637 
00638             StrFree(datetime_now);
00639             return status;
00640         }
00641     } else {
00642                 MsgLog(KSM_INVARG, "Could not calculate DateDiff");
00643         StrFree(datetime_now);
00644         return -2;
00645     }
00646 
00647     StrFree(datetime_now);
00648     return status;
00649 }
00650 
00651 /*+
00652  * KsmPolicyNullSaltStamp
00653  *
00654  * Description:
00655  *      Given a policy id set its saltstamp to NULL, this will force a resalt on
00656  *      the next enforcer run, suitable for when salt length has changed for 
00657  *      instance.
00658  *
00659  * Arguments:
00660  *      int policy_id
00661  *              policy to work on
00662  *
00663  * Returns:
00664  *      int
00665  *          Status return:
00666  *              0           success
00667  *              non-zero    some error occurred and a message has been output.
00668  *              -1          no policy found
00669  *
00670 -*/
00671 
00672 int KsmPolicyNullSaltStamp(int policy_id)
00673 {
00674     char    buffer[KSM_SQL_SIZE];   /* update statement for salt_stamp */
00675     unsigned int    nchar;          /* Number of characters converted */
00676     int status = 0;
00677    
00678     /* check the argument */
00679     if (policy_id < 1) {
00680         MsgLog(KSM_INVARG, "Negative or zero policy_id");
00681         return -1;
00682     }
00683 
00684      nchar = snprintf(buffer, sizeof(buffer),
00685              "UPDATE policies SET salt_stamp = NULL WHERE ID = %lu",
00686              (unsigned long) policy_id);
00687 
00688      if (nchar < sizeof(buffer)) {
00689          /* All OK, execute the statement */
00690 
00691          status = DbExecuteSqlNoResult(DbHandle(), buffer);
00692      }
00693      else {
00694          /* Unable to create update statement */
00695 
00696          status = MsgLog(KME_BUFFEROVF, "KsmPolicy");
00697      }
00698 
00699      return status;
00700 }
00701 
00702 
00703 /* Populate security module information for a structure that has the sm_id fields filled in */
00704 
00705 int KsmPolicyPopulateSMFromIds(KSM_POLICY* policy)
00706 {
00707     int     where = 0;          /* WHERE clause value */
00708     char*   sql = NULL;         /* SQL query */
00709     DB_RESULT       result;     /* Handle converted to a result object */
00710     DB_ROW      row = NULL;            /* Row data */
00711     DB_RESULT       result2;     /* Handle converted to a result object */
00712     DB_ROW      row2 = NULL;            /* Row data */
00713     int     status = 0;         /* Status return */
00714 
00715     /* check the argument */
00716     if (policy == NULL) {
00717         return MsgLog(KSM_INVARG, "NULL policy");
00718     }
00719 
00720     /* Construct the query for ksk */
00721 
00722     sql = DqsSpecifyInit(DB_SECURITY_MODULE_TABLE, DB_SECURITY_MODULE_FIELDS);
00723     DqsConditionInt(&sql, "id", DQS_COMPARE_EQ, policy->ksk->sm, where++);
00724 
00725     /* Execute query and free up the query string */
00726     status = DbExecuteSql(DbHandle(), sql, &result);
00727     DqsFree(sql);
00728     
00729     if (status != 0)
00730     {
00731         status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00732         DbFreeResult(result);
00733         return status;
00734         }
00735 
00736     /* Get the next row from the data */
00737     status = DbFetchRow(result, &row);
00738     if (status == 0) {
00739         DbStringBuffer(row, DB_SECURITY_MODULE_NAME, policy->ksk->sm_name, KSM_NAME_LENGTH*sizeof(char));
00740         DbUnsignedLong(row, DB_SECURITY_MODULE_CAPACITY, &(policy->ksk->sm_capacity));
00741         DbInt(row, DB_SECURITY_MODULE_REQUIREBACKUP, &(policy->ksk->require_backup));
00742     }
00743     else if (status == -1) {}
00744         /* No rows to return (but no error) */
00745         else {
00746         status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00747         DbFreeResult(result);
00748         DbFreeRow(row);
00749         return status;
00750         }
00751 
00752     DbFreeResult(result);
00753     DbFreeRow(row);
00754 
00755 
00756     /* Construct the query for zsk */
00757     where = 0;
00758 
00759     sql = DqsSpecifyInit(DB_SECURITY_MODULE_TABLE, DB_SECURITY_MODULE_FIELDS);
00760     DqsConditionInt(&sql, "id", DQS_COMPARE_EQ, policy->zsk->sm, where++);
00761 
00762     /* Execute query and free up the query string */
00763     status = DbExecuteSql(DbHandle(), sql, &result2);
00764     DqsFree(sql);
00765     
00766     if (status != 0)
00767     {
00768         status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00769         DbFreeResult(result2);
00770         return status;
00771         }
00772 
00773     /* Get the next row from the data */
00774     status = DbFetchRow(result2, &row2);
00775     if (status == 0) {
00776         DbStringBuffer(row2, DB_SECURITY_MODULE_NAME, policy->zsk->sm_name, KSM_NAME_LENGTH*sizeof(char));
00777         DbUnsignedLong(row2, DB_SECURITY_MODULE_CAPACITY, &(policy->zsk->sm_capacity));
00778         DbInt(row2, DB_SECURITY_MODULE_REQUIREBACKUP, &(policy->zsk->require_backup));
00779     }
00780     else if (status == -1) {}
00781         /* No rows to return (but no error) */
00782         else {
00783         status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00784         }
00785 
00786     DbFreeRow(row2);
00787     DbFreeResult(result2);
00788     return status;
00789 }
00790 
00791 /*+
00792  * KsmPolicySetIdFromName - Given a policy with the name set, fill in the ID
00793  *
00794  *
00795  * Arguments:
00796  *      
00797  *          Name of the parameter.
00798  *
00799  *
00800  * Returns:
00801  *      int
00802  *          0       Success, value found
00803  *          Other   Error
00804 -*/
00805 
00806 int KsmPolicySetIdFromName(KSM_POLICY *policy)
00807 {
00808     int             status;     /* Status return */
00809     DB_RESULT       result;     /* Handle converted to a result object */
00810     DB_ROW          row = NULL; /* Row data */
00811 
00812     if (policy == NULL || policy->name[0] == '\0') {
00813         return MsgLog(KSM_INVARG, "NULL policy or name");
00814     }
00815 
00816     status = KsmPolicyInit(&result, policy->name);
00817     if (status == 0) {
00818         /* Get the next row from the data */
00819         status = DbFetchRow(result, &row);
00820         if (status == 0) {
00821             DbInt(row, DB_POLICY_ID, &policy->id);
00822             DbStringBuffer(row, DB_POLICY_DESCRIPTION, policy->description, KSM_POLICY_DESC_LENGTH*sizeof(char));
00823             DbStringBuffer(row, DB_POLICY_AUDIT, policy->audit, KSM_POLICY_AUDIT_LENGTH*sizeof(char));
00824             DbStringBuffer(row, 4, policy->denial->salt, KSM_SALT_LENGTH*sizeof(char));
00825         }
00826         else if (status == -1) {
00827         /* No rows to return (but no error) */
00828         }
00829         else {
00830             /* Error */
00831             status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00832         }
00833 
00834     }
00835     DbFreeRow(row);
00836     DbFreeResult(result);
00837     return status;
00838 }
00839 
00840 /*+
00841  * KsmPolicyIdFromZoneId
00842  *
00843  * Arguments:
00844  *          int         zone_id     zone id
00845  *          int*        policy_id   returned id
00846  *
00847  * Returns:
00848  *      int
00849  *          Status return:
00850  *              0           success
00851  *              -1          no record found
00852  *              non-zero    some error occurred and a message has been output.
00853  *
00854  *          If the status is non-zero, the returned data is meaningless.
00855 -*/
00856 int KsmPolicyIdFromZoneId(int zone_id, int* policy_id)
00857 {
00858     int     where = 0;          /* WHERE clause value */
00859     char*   sql = NULL;         /* SQL query */
00860     DB_RESULT       result;     /* Handle converted to a result object */
00861     DB_ROW      row = NULL;            /* Row data */
00862     int     status = 0;         /* Status return */
00863 
00864     /* check the argument */
00865     if (zone_id == -1) {
00866         return MsgLog(KSM_INVARG, "NULL zone name");
00867     }
00868 
00869     /* Construct the query */
00870 
00871     sql = DqsSpecifyInit("zones","id, policy_id");
00872     DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, zone_id, where++);
00873     DqsOrderBy(&sql, "id");
00874 
00875     /* Execute query and free up the query string */
00876     status = DbExecuteSql(DbHandle(), sql, &result);
00877     DqsFree(sql);
00878     
00879     if (status != 0)
00880     {
00881         status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00882         DbFreeResult(result);
00883         return status;
00884         }
00885 
00886     /* Get the next row from the data */
00887     status = DbFetchRow(result, &row);
00888     if (status == 0) {
00889         DbInt(row, 1, policy_id);
00890     }
00891     else if (status == -1) {}
00892         /* No rows to return (but no DB error) */
00893         else {
00894         status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
00895         }
00896 
00897     DbFreeRow(row);
00898     DbFreeResult(result);
00899     return status;
00900 }
00901 
00902 KSM_POLICY *KsmPolicyAlloc()
00903 {
00904         KSM_POLICY *policy;
00905     
00906         policy = (KSM_POLICY *)malloc(sizeof(KSM_POLICY));
00907         policy->description = (char *)calloc(KSM_POLICY_DESC_LENGTH, sizeof(char));
00908         policy->signer = (KSM_SIGNER_POLICY *)malloc(sizeof(KSM_SIGNER_POLICY));
00909         policy->signature = (KSM_SIGNATURE_POLICY *)malloc(sizeof(KSM_SIGNATURE_POLICY));
00910         policy->denial = (KSM_DENIAL_POLICY *)malloc(sizeof(KSM_DENIAL_POLICY));
00911         policy->keys = (KSM_COMMON_KEY_POLICY *)malloc(sizeof(KSM_COMMON_KEY_POLICY));
00912         policy->ksk = (KSM_KEY_POLICY *)malloc(sizeof(KSM_KEY_POLICY));
00913         policy->zsk = (KSM_KEY_POLICY *)malloc(sizeof(KSM_KEY_POLICY));
00914         policy->enforcer = (KSM_ENFORCER_POLICY *)malloc(sizeof(KSM_ENFORCER_POLICY));
00915         policy->zone = (KSM_ZONE_POLICY *)malloc(sizeof(KSM_ZONE_POLICY));
00916         policy->parent = (KSM_PARENT_POLICY *)malloc(sizeof(KSM_PARENT_POLICY));
00917         /*  policy->audit = (KSM_AUDIT_POLICY *)malloc(sizeof(KSM_AUDIT_POLICY)); */
00918         policy->audit = (char *)calloc(KSM_POLICY_AUDIT_LENGTH, sizeof(char));
00919         
00920         /*  if allocation fails, return NULL*/
00921         if (policy->description == NULL ||
00922             policy->signer == NULL ||
00923             policy->signature == NULL ||
00924             policy->denial == NULL ||
00925             policy->keys == NULL ||
00926             policy->ksk == NULL ||
00927             policy->zsk == NULL || 
00928             policy->enforcer == NULL ||
00929             policy->zone == NULL ||
00930             policy->parent == NULL || 
00931             policy->audit == NULL) {
00932                 KsmPolicyFree(policy);
00933                 return NULL;
00934         }
00935         
00936         return policy;
00937 }
00938 
00939 void KsmPolicyFree(KSM_POLICY *policy)
00940 {       
00941     free(policy->description);
00942     free(policy->signer);
00943     free(policy->signature);
00944     free(policy->denial);
00945     free(policy->keys);
00946     free(policy->ksk);
00947     free(policy->zsk);
00948     free(policy->enforcer);
00949     free(policy->zone);
00950     free(policy->parent);
00951     free(policy->audit);
00952     free(policy);
00953 }