OpenDNSSEC-enforcer 1.3.0
|
00001 /* 00002 * $Id: ksm_policy.c 5320 2011-07-12 10:42:26Z jakob $ 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 }