OpenDNSSEC-enforcer  1.3.16
ksm_policy.c
Go to the documentation of this file.
1 /*
2  * $Id: ksm_policy.c 7421 2013-11-21 16:11:40Z sara $
3  *
4  * Copyright (c) 2008-2009 Nominet UK. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  */
28 
29 /*
30  * ksm_policy.c - Manipulation of Policy Information
31  */
32 
33 #include <assert.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <time.h>
38 
39 #include "ksm/database.h"
40 #include "ksm/database_statement.h"
41 #include "ksm/datetime.h"
42 #include "ksm/db_fields.h"
43 #include "ksm/debug.h"
44 #include "ksm/ksmdef.h"
45 #include "ksm/kmedef.h"
46 #include "ksm/ksm.h"
47 #include "ksm/ksm_internal.h"
48 #include "ksm/message.h"
49 #include "ksm/string_util.h"
50 
51 /*+
52  * KsmPolicyInit - Query for Policy Information
53  *
54  *
55  * Arguments:
56  * DB_RESULT* result
57  * Pointer to a handle to be used for information retrieval. Will
58  * be NULL on error.
59  *
60  * const char* name
61  * Name of the parameter to retrieve information on. If NULL, information
62  * on all parameters is retrieved.
63  *
64  * Returns:
65  * int
66  * Status return. 0 on success.
67 -*/
68 
69 int KsmPolicyInit(DB_RESULT* result, const char* name)
70 {
71  int where = 0; /* WHERE clause value */
72  char* sql = NULL; /* SQL query */
73  int status = 0; /* Status return */
74 
75  /* Construct the query */
76 
77  sql = DqsSpecifyInit("policies","id, name, description, audit, salt");
78  if (name) {
79  DqsConditionString(&sql, "NAME", DQS_COMPARE_EQ, name, where++);
80  }
81  DqsOrderBy(&sql, "id");
82 
83  /* Execute query and free up the query string */
84 
85  status = DbExecuteSql(DbHandle(), sql, result);
86 
87  DqsFree(sql);
88 
89  return status;
90 }
91 
92 /*+
93  * KsmPolicyParametersInit - Query for Policy Information
94  *
95  *
96  * Arguments:
97  * DB_RESULT* result
98  * Pointer to a handle to be used for information retrieval. Will
99  * be NULL on error.
100  *
101  * const char* name
102  * Name of the parameter to retrieve information on. If NULL, information
103  * on all parameters is retrieved.
104  *
105  * Returns:
106  * int
107  * Status return. 0 on success.
108 -*/
109 
110 int KsmPolicyParametersInit(DB_RESULT* result, const char* name)
111 {
112  int where = 0; /* WHERE clause value */
113  char* sql = NULL; /* SQL query */
114  int status = 0; /* Status return */
115 
116  /* Construct the query */
117 
118  sql = DqsSpecifyInit("policies p, parameters_policies x, parameters y, categories c ","y.name, c.name, x.value");
119  DqsConditionKeyword(&sql, "p.id", DQS_COMPARE_EQ, "x.policy_id", where++);
120  DqsConditionKeyword(&sql, "y.id", DQS_COMPARE_EQ, "x.parameter_id", where++);
121  DqsConditionKeyword(&sql, "c.id", DQS_COMPARE_EQ, "y.category_id", where++);
122  if (name) {
123  DqsConditionString(&sql, "p.NAME", DQS_COMPARE_EQ, name, where++);
124  }
125  DqsOrderBy(&sql, "p.NAME");
126 
127  /* Execute query and free up the query string */
128 
129  status = DbExecuteSql(DbHandle(), sql, result);
130 
131  DqsFree(sql);
132 
133  return status;
134 }
135 
136 /*+
137  * KsmPolicyExists - Check Policy Exists
138  *
139  *
140  * Arguments:
141  * const char* name
142  * Name of the parameter.
143  *
144  *
145  * Returns:
146  * int
147  * 0 Success, value found
148  * Other Error, message has been output
149 -*/
150 
151 int KsmPolicyExists(const char* name)
152 {
153  int status; /* Status return */
154  DB_RESULT result; /* Handle converted to a result object */
155  DB_ROW row = NULL; /* Row data */
156 
157  status = KsmPolicyInit(&result, name);
158  if (status == 0) {
159  /* Get the next row from the data */
160  status = DbFetchRow(result, &row);
161  if (status > 0) {
162  /* Error */
163  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
164  }
165  }
166  DbFreeRow(row);
167  DbFreeResult(result);
168  return status;
169 }
170 
171 /*+
172  * KsmPolicy - Return Policy Information
173  *
174  * Arguments:
175  * DB_RESULT result
176  * Handle from KsmParameterInit
177  *
178  * KSM_PARAMETER* data
179  * Data is returned in here.
180  *
181  * Returns:
182  * int
183  * Status return:
184  * 0 success
185  * -1 end of record set reached
186  * non-zero some error occurred and a message has been output.
187  *
188  * If the status is non-zero, the returned data is meaningless.
189 -*/
190 
191 int KsmPolicy(DB_RESULT result, KSM_POLICY* data)
192 {
193  int status = 0; /* Return status */
194  DB_ROW row = NULL; /* Row data */
195 
196  /* check the argument */
197  if (data == NULL) {
198  return MsgLog(KSM_INVARG, "NULL data");
199  }
200 
201  /* Get the next row from the data */
202  status = DbFetchRow(result, &row);
203  if (status == 0) {
204 
205  status = DbInt(row, DB_POLICY_ID, &(data->id));
206  DbStringBuffer(row, DB_POLICY_NAME, data->name, KSM_NAME_LENGTH*sizeof(char));
207  }
208  else if (status == -1) {}
209  /* No rows to return (but no error) */
210  else {
211  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
212  }
213 
214  if (row != NULL) {
215  DbFreeRow(row);
216  }
217 
218  return status;
219 }
220 
221 /*+
222  * KsmPolicyRead - Read Policy
223  *
224  * Description:
225  * Read policy from database in to a struct.
226  *
227  * Arguments:
228  * struct policy_t policy
229  * struct to hold policy information, it needs to have the policy name set
230 -*/
231 
233 {
234  KSM_POLICY_PARAMETER data; /* Parameter information */
235  DB_RESULT result; /* Handle to parameter */
236  int status = 0; /* Status return */
237 
238  /* check the argument */
239  if (policy == NULL) {
240  return MsgLog(KSM_INVARG, "NULL policy");
241  }
242 
243  /* status = KsmPolicyExists(policy->name); */
244  status = KsmPolicySetIdFromName(policy);
245 
246  /* NSEC3PARAM TTL might be null in the database if the policy was imported before the fix
247  * so default to zero */
248  policy->denial->ttl=0;
249 
250  if (status == 0) {
251 
252  status = KsmPolicyParametersInit(&result, policy->name);
253  if (status == 0) {
254  status = KsmPolicyParameter(result, &data);
255  while (status == 0) {
256  if (strncmp(data.category, "enforcer", 8) == 0) {
257 /* if (strncmp(data.name, "keycreate", 9) == 0) policy->enforcer->keycreate=data.value;
258  if (strncmp(data.name, "backup_interval", 15) == 0) policy->enforcer->backup_interval=data.value; */
259  if (strncmp(data.name, "keygeninterval", 14) == 0) policy->enforcer->keygeninterval=data.value;
260  }
261  if (strncmp(data.category, "zone", 4) == 0) {
262  if (strncmp(data.name, "propagationdelay", 16) == 0) policy->signer->propdelay=data.value;
263  if (strncmp(data.name, "min", 3) == 0) policy->signer->soamin=data.value;
264  if (strncmp(data.name, "ttl", 2) == 0) policy->signer->soattl=data.value;
265  if (strncmp(data.name, "serial", 6) == 0) policy->signer->serial=data.value;
266  if (strncmp(data.name, "propagationdelay", 16) == 0) policy->zone->propdelay=data.value;
267  if (strncmp(data.name, "min", 3) == 0) policy->zone->soa_min=data.value;
268  if (strncmp(data.name, "ttl", 3) == 0) policy->zone->soa_ttl=data.value;
269  if (strncmp(data.name, "serial", 6) == 0) policy->zone->serial=data.value;
270  }
271  if (strncmp(data.category, "parent", 6) == 0) {
272  if (strncmp(data.name, "propagationdelay", 16) == 0) policy->parent->propdelay=data.value;
273  if (strncmp(data.name, "min", 3) == 0) policy->parent->soa_min=data.value;
274  if (strncmp(data.name, "ttl", 3) == 0) policy->parent->soa_ttl=data.value;
275  if (strncmp(data.name, "ttlds", 5) == 0) policy->parent->ds_ttl=data.value;
276  }
277  if (strncmp(data.category, "signature", 9) == 0) {
278  if (strncmp(data.name, "jitter", 6) == 0) policy->signer->jitter=data.value;
279  if (strncmp(data.name, "refresh", 7) == 0) policy->signer->refresh=data.value;
280  if (strncmp(data.name, "clockskew", 9) == 0) policy->signature->clockskew=data.value;
281  if (strncmp(data.name, "resign", 6) == 0) policy->signature->resign=data.value;
282  if (strncmp(data.name, "valdefault", 10) == 0) policy->signature->valdefault=data.value;
283  if (strncmp(data.name, "valdenial", 9) == 0) policy->signature->valdenial=data.value;
284  }
285  if (strncmp(data.category, "denial", 6) == 0) {
286  if (strncmp(data.name, "version", 7) == 0) policy->denial->version=data.value;
287  if (strncmp(data.name, "resalt", 6) == 0) policy->denial->resalt=data.value;
288  if (strncmp(data.name, "alg", 3) == 0) policy->denial->algorithm=data.value;
289  if (strncmp(data.name, "iteration", 9) == 0) policy->denial->iteration=data.value;
290  if (strncmp(data.name, "optout", 6) == 0) policy->denial->optout=data.value;
291  if (strncmp(data.name, "ttl",3) == 0) policy->denial->ttl=data.value;
292  if (strncmp(data.name, "saltlength",10) == 0) policy->denial->saltlength=data.value;
293  }
294  if (strncmp(data.category, "zsk", 3) == 0) {
295  if (strncmp(data.name, "alg",3) == 0) policy->zsk->algorithm=data.value;
296  if (strncmp(data.name, "lifetime",8) == 0) policy->zsk->lifetime=data.value;
297  if (strncmp(data.name, "repository",10) == 0) policy->zsk->sm=data.value;
298  if (strncmp(data.name, "overlap",7) == 0) policy->zsk->overlap=data.value;
299  if (strncmp(data.name, "bits",4) == 0) policy->zsk->bits=data.value;
300  if (strncmp(data.name, "standby",7) == 0) policy->zsk->standby_keys=data.value;
301  if (strncmp(data.name, "manual_rollover",15) == 0) policy->zsk->manual_rollover=data.value;
302  }
303  if (strncmp(data.category, "ksk", 3) == 0) {
304  if (strncmp(data.name, "alg",3) == 0) policy->ksk->algorithm=data.value;
305  if (strncmp(data.name, "lifetime",8) == 0) policy->ksk->lifetime=data.value;
306  if (strncmp(data.name, "repository",10) == 0) policy->ksk->sm=data.value;
307  if (strncmp(data.name, "overlap",7) == 0) policy->ksk->overlap=data.value;
308  if (strncmp(data.name, "rfc5011",7) == 0) policy->ksk->rfc5011=data.value;
309  if (strncmp(data.name, "bits",4) == 0) policy->ksk->bits=data.value;
310  if (strncmp(data.name, "standby",7) == 0) policy->ksk->standby_keys=data.value;
311  if (strncmp(data.name, "manual_rollover",15) == 0) policy->ksk->manual_rollover=data.value;
312  if (strncmp(data.name, "rollover_scheme",15) == 0) policy->ksk->rollover_scheme=data.value;
313  }
314  if (strncmp(data.category, "keys", 4) == 0) {
315  if (strncmp(data.name, "ttl",3) == 0) policy->ksk->ttl=data.value;
316  if (strncmp(data.name, "ttl",3) == 0) policy->zsk->ttl=data.value;
317  if (strncmp(data.name, "zones_share_keys",16) == 0) policy->shared_keys=data.value;
318  if (strncmp(data.name, "ttl",3) == 0) policy->keys->ttl=data.value;
319  if (strncmp(data.name, "zones_share_keys",16) == 0) policy->keys->share_keys=data.value;
320  if (strncmp(data.name, "retiresafety",12) == 0) policy->keys->retire_safety=data.value;
321  if (strncmp(data.name, "publishsafety",13) == 0) policy->keys->publish_safety=data.value;
322  if (strncmp(data.name, "purge",5) == 0) policy->keys->purge=data.value;
323  }
324  /* if (strncmp(data.category, "audit", 5) == 0) {
325  if (strncmp(data.name, "audit",5) == 0) policy->audit->audit=data.value;
326  }*/
327  /* Ignore any unknown parameters */
328 
329  status = KsmPolicyParameter(result, &data);
330  }
331 
332  /* All done, so tidy up */
333 
334  KsmParameterEnd(result);
335  }
336  } else {
337  return status;
338  }
339 
340  /* convert security module ids into names, capacities and requirebackup flags */
341  status = KsmPolicyPopulateSMFromIds(policy);
342 
343  return status;
344 }
345 
346 /*+
347  * KsmPolicyParameter - Return PolicyParameter Information
348  *
349  * Description:
350  * Returns information about the next key in the result set.
351  *
352  * Arguments:
353  * DB_RESULT result
354  * Handle from KsmParameterInit
355  *
356  * KSM_PARAMETER* data
357  * Data is returned in here.
358  *
359  * Returns:
360  * int
361  * Status return:
362  * 0 success
363  * -1 end of record set reached
364  * non-zero some error occurred and a message has been output.
365  *
366  * If the status is non-zero, the returned data is meaningless.
367 -*/
368 
370 {
371  int status = 0; /* Return status */
372  DB_ROW row = NULL; /* Row data */
373 
374  /* check the argument */
375  if (data == NULL) {
376  return MsgLog(KSM_INVARG, "NULL data");
377  }
378 
379  /* Get the next row from the data */
380  status = DbFetchRow(result, &row);
381 
382  if (status == 0) {
383 
384  /* Now copy the results into the output data */
385 
386  memset(data, 0, sizeof(KSM_POLICY_PARAMETER));
388  sizeof(data->name));
390  sizeof(data->category));
391  status = DbInt(row, DB_POLICY_PARAMETER_VALUE, &(data->value));
392  }
393  else if (status == -1) {}
394  /* No rows to return (but no error) */
395  else {
396  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
397  }
398 
399  if (row != NULL) {
400  DbFreeRow(row);
401  }
402 
403  return status;
404 }
405 
406 /*+
407  * KsmPolicyReadFromId - Read Policy given just the id
408  *
409  * Description:
410  * Read policy from database in to a struct.
411  *
412  * Arguments:
413  * struct policy_t policy
414  * struct to hold policy information should have id populated
415 -*/
416 
418 {
419  int status = KsmPolicyNameFromId(policy);
420 
421  if (status != 0)
422  {
423  return status;
424  }
425 
426  return KsmPolicyRead(policy);
427 
428 }
429 
431 {
432  int where = 0; /* WHERE clause value */
433  char* sql = NULL; /* SQL query */
434  DB_RESULT result; /* Handle converted to a result object */
435  DB_ROW row = NULL; /* Row data */
436  int status = 0; /* Status return */
437 
438  /* check the argument */
439  if (policy == NULL) {
440  return MsgLog(KSM_INVARG, "NULL policy");
441  }
442 
443  /* Construct the query */
444 
445  sql = DqsSpecifyInit("policies","id, name");
446  DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, policy->id, where++);
447  DqsOrderBy(&sql, "id");
448 
449  /* Execute query and free up the query string */
450  status = DbExecuteSql(DbHandle(), sql, &result);
451  DqsFree(sql);
452 
453  if (status != 0)
454  {
455  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
456  DbFreeResult(result);
457  return status;
458  }
459 
460  /* Get the next row from the data */
461  status = DbFetchRow(result, &row);
462  if (status == 0) {
463  DbStringBuffer(row, DB_POLICY_NAME, policy->name, KSM_NAME_LENGTH*sizeof(char));
464  }
465  else if (status == -1) {}
466  /* No rows to return (but no error) */
467  else {
468  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
469  }
470 
471  DbFreeRow(row);
472  DbFreeResult(result);
473  return status;
474 }
475 
476 /*+
477  * KsmPolicyUpdateSalt
478  *
479  * Description:
480  * Given a policy see if the salt needs updating (based on denial->resalt).
481  * If it is out of date then generate a new salt and write it to the struct.
482  * Also update the database with the new value and timestamp.
483  *
484  * Arguments:
485  * struct policy_t policy
486  * struct which holds the current policy information should have been populated
487  *
488  * Returns:
489  * int
490  * Status return:
491  * 0 success
492  * non-zero some error occurred and a message has been output.
493  * -1 no policy found
494  * -2 an error working out time difference between stamp and now
495  *
496 -*/
497 
499 {
500  /* First work out what the current salt is and when it was created */
501  int where = 0; /* WHERE clause value */
502  char* sql = NULL; /* SQL query */
503  DB_RESULT result; /* Handle converted to a result object */
504  DB_ROW row = NULL; /* Row data */
505  int status = 0; /* Status return */
506  char* datetime_now = DtParseDateTimeString("now"); /* where are we in time */
507  int time_diff; /* how many second have elapsed */
508  char* salt; /* This will be the salt that we create */
509  char buffer[KSM_SQL_SIZE]; /* update statement for salt_stamp */
510  unsigned int nchar; /* Number of characters converted */
511  int i = 0; /* a counter */
512  char* hex_chars = "0123456789abcdef"; /* for "manual" random string */
513 
514  /* check the argument */
515  if (policy == NULL) {
516  MsgLog(KSM_INVARG, "NULL policy");
517  StrFree(datetime_now);
518  return -1;
519  }
520 
521  /* Check datetime in case it came back NULL */
522  if (datetime_now == NULL) {
523  printf("Couldn't turn \"now\" into a date, quitting...\n");
524  exit(1);
525  }
526 
527  /* Construct the query */
528 
529  sql = DqsSpecifyInit("policies","id, salt, salt_stamp");
530  DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, policy->id, where++);
531  DqsOrderBy(&sql, "id");
532 
533  /* Execute query and free up the query string */
534  status = DbExecuteSql(DbHandle(), sql, &result);
535  DqsFree(sql);
536 
537  if (status != 0)
538  {
539  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
540  StrFree(datetime_now);
541  return status;
542  }
543 
544  /* Get the next row from the data */
545  status = DbFetchRow(result, &row);
546  if (status == 0) {
547  status = DbStringBuffer(row, DB_POLICY_SALT, policy->denial->salt, KSM_SALT_LENGTH*sizeof(char));
548  if (status == 0) {
549  status = DbStringBuffer(row, DB_POLICY_SALT_STAMP, policy->denial->salt_stamp, KSM_TIME_LENGTH*sizeof(char));
550  }
551 
552  if (status != 0) {
553  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
554  DbFreeResult(result);
555  DbFreeRow(row);
556  StrFree(datetime_now);
557  return status;
558  }
559  }
560  else if (status == -1) {
561  /* No rows to return (but no error), policy_id doesn't exist? */
562  DbFreeResult(result);
563  DbFreeRow(row);
564  StrFree(datetime_now);
565  return -1;
566  }
567  else {
568  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
569 
570  DbFreeResult(result);
571  DbFreeRow(row);
572  StrFree(datetime_now);
573  return status;
574  }
575 
576  DbFreeResult(result);
577  DbFreeRow(row);
578 
579  /* Now see if this needs to be updated; if the stamp is null then assume it does */
580  if (policy->denial->salt_stamp[0] == '\0') {
581  time_diff = -1;
582  } else {
583  status = DtDateDiff(datetime_now, policy->denial->salt_stamp, &time_diff);
584  }
585 
586  if (status == 0) {
587  if (policy->denial->resalt > time_diff && time_diff != -1 && policy->denial->salt[0] != '\0') {
588  /* current salt is fine */
589  StrFree(datetime_now);
590  return status;
591  } else {
592  /* salt needs updating, or is null */
593  salt = (char *)calloc(KSM_SALT_LENGTH, sizeof(char));
594  if (salt == NULL) {
595  MsgLog(KSM_INVARG, "Could not allocate memory for salt");
596  StrFree(datetime_now);
597  exit(1);
598  }
599 
600 #ifdef HAVE_ARC4RANDOM
601  for (i = 0; i < 2*(policy->denial->saltlength); i++) {
602  salt[i] = hex_chars[arc4random()%strlen(hex_chars)];
603  }
604 #else
605  srand( time(NULL) );
606  for (i = 0; i < 2*(policy->denial->saltlength); i++) {
607  salt[i] = hex_chars[rand()%strlen(hex_chars)];
608  }
609 #endif
610 
611  if (status != 0) {
612  StrFree(datetime_now);
613  StrFree(salt);
614  return status;
615  }
616  StrStrncpy(policy->denial->salt, salt, KSM_SALT_LENGTH);
617  StrStrncpy(policy->denial->salt_stamp, datetime_now, KSM_TIME_LENGTH);
618 
619  StrFree(salt);
620 
621  /* write these back to the database */
622 #ifdef USE_MYSQL
623  nchar = snprintf(buffer, sizeof(buffer),
624  "UPDATE policies SET salt = '%s', salt_stamp = \"%s\" WHERE ID = %lu",
625  policy->denial->salt, policy->denial->salt_stamp, (unsigned long) policy->id);
626 #else
627  nchar = snprintf(buffer, sizeof(buffer),
628  "UPDATE policies SET salt = '%s', salt_stamp = DATETIME('%s') WHERE ID = %lu",
629  policy->denial->salt, policy->denial->salt_stamp, (unsigned long) policy->id);
630 #endif /* USE_MYSQL */
631  if (nchar < sizeof(buffer)) {
632  /* All OK, execute the statement */
633 
634  status = DbExecuteSqlNoResult(DbHandle(), buffer);
635  }
636  else {
637  /* Unable to create update statement */
638 
639  status = MsgLog(KME_BUFFEROVF, "KsmPolicy");
640  }
641 
642  StrFree(datetime_now);
643  return status;
644  }
645  } else {
646  MsgLog(KSM_INVARG, "Could not calculate DateDiff");
647  StrFree(datetime_now);
648  return -2;
649  }
650 
651  StrFree(datetime_now);
652  return status;
653 }
654 
655 /*+
656  * KsmPolicyNullSaltStamp
657  *
658  * Description:
659  * Given a policy id set its saltstamp to NULL, this will force a resalt on
660  * the next enforcer run, suitable for when salt length has changed for
661  * instance.
662  *
663  * Arguments:
664  * int policy_id
665  * policy to work on
666  *
667  * Returns:
668  * int
669  * Status return:
670  * 0 success
671  * non-zero some error occurred and a message has been output.
672  * -1 no policy found
673  *
674 -*/
675 
676 int KsmPolicyNullSaltStamp(int policy_id)
677 {
678  char buffer[KSM_SQL_SIZE]; /* update statement for salt_stamp */
679  unsigned int nchar; /* Number of characters converted */
680  int status = 0;
681 
682  /* check the argument */
683  if (policy_id < 1) {
684  MsgLog(KSM_INVARG, "Negative or zero policy_id");
685  return -1;
686  }
687 
688  nchar = snprintf(buffer, sizeof(buffer),
689  "UPDATE policies SET salt_stamp = NULL WHERE ID = %lu",
690  (unsigned long) policy_id);
691 
692  if (nchar < sizeof(buffer)) {
693  /* All OK, execute the statement */
694 
695  status = DbExecuteSqlNoResult(DbHandle(), buffer);
696  }
697  else {
698  /* Unable to create update statement */
699 
700  status = MsgLog(KME_BUFFEROVF, "KsmPolicy");
701  }
702 
703  return status;
704 }
705 
706 
707 /* Populate security module information for a structure that has the sm_id fields filled in */
708 
710 {
711  int where = 0; /* WHERE clause value */
712  char* sql = NULL; /* SQL query */
713  DB_RESULT result; /* Handle converted to a result object */
714  DB_ROW row = NULL; /* Row data */
715  DB_RESULT result2; /* Handle converted to a result object */
716  DB_ROW row2 = NULL; /* Row data */
717  int status = 0; /* Status return */
718 
719  /* check the argument */
720  if (policy == NULL) {
721  return MsgLog(KSM_INVARG, "NULL policy");
722  }
723 
724  /* Construct the query for ksk */
725 
727  DqsConditionInt(&sql, "id", DQS_COMPARE_EQ, policy->ksk->sm, where++);
728 
729  /* Execute query and free up the query string */
730  status = DbExecuteSql(DbHandle(), sql, &result);
731  DqsFree(sql);
732 
733  if (status != 0)
734  {
735  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
736  DbFreeResult(result);
737  return status;
738  }
739 
740  /* Get the next row from the data */
741  status = DbFetchRow(result, &row);
742  if (status == 0) {
743  DbStringBuffer(row, DB_SECURITY_MODULE_NAME, policy->ksk->sm_name, KSM_NAME_LENGTH*sizeof(char));
746  }
747  else if (status == -1) {}
748  /* No rows to return (but no error) */
749  else {
750  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
751  DbFreeResult(result);
752  DbFreeRow(row);
753  return status;
754  }
755 
756  DbFreeResult(result);
757  DbFreeRow(row);
758 
759 
760  /* Construct the query for zsk */
761  where = 0;
762 
764  DqsConditionInt(&sql, "id", DQS_COMPARE_EQ, policy->zsk->sm, where++);
765 
766  /* Execute query and free up the query string */
767  status = DbExecuteSql(DbHandle(), sql, &result2);
768  DqsFree(sql);
769 
770  if (status != 0)
771  {
772  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
773  DbFreeResult(result2);
774  return status;
775  }
776 
777  /* Get the next row from the data */
778  status = DbFetchRow(result2, &row2);
779  if (status == 0) {
780  DbStringBuffer(row2, DB_SECURITY_MODULE_NAME, policy->zsk->sm_name, KSM_NAME_LENGTH*sizeof(char));
783  }
784  else if (status == -1) {}
785  /* No rows to return (but no error) */
786  else {
787  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
788  }
789 
790  DbFreeRow(row2);
791  DbFreeResult(result2);
792  return status;
793 }
794 
795 /*+
796  * KsmPolicySetIdFromName - Given a policy with the name set, fill in the ID
797  *
798  *
799  * Arguments:
800  *
801  * Name of the parameter.
802  *
803  *
804  * Returns:
805  * int
806  * 0 Success, value found
807  * Other Error
808 -*/
809 
811 {
812  int status; /* Status return */
813  DB_RESULT result; /* Handle converted to a result object */
814  DB_ROW row = NULL; /* Row data */
815 
816  if (policy == NULL || policy->name[0] == '\0') {
817  return MsgLog(KSM_INVARG, "NULL policy or name");
818  }
819 
820  status = KsmPolicyInit(&result, policy->name);
821  if (status == 0) {
822  /* Get the next row from the data */
823  status = DbFetchRow(result, &row);
824  if (status == 0) {
825  DbInt(row, DB_POLICY_ID, &policy->id);
827  DbStringBuffer(row, DB_POLICY_AUDIT, policy->audit, KSM_POLICY_AUDIT_LENGTH*sizeof(char));
828  DbStringBuffer(row, 4, policy->denial->salt, KSM_SALT_LENGTH*sizeof(char));
829  }
830  else if (status == -1) {
831  /* No rows to return (but no error) */
832  }
833  else {
834  /* Error */
835  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
836  }
837 
838  }
839  DbFreeRow(row);
840  DbFreeResult(result);
841  return status;
842 }
843 
844 /*+
845  * KsmPolicyIdFromZoneId
846  *
847  * Arguments:
848  * int zone_id zone id
849  * int* policy_id returned id
850  *
851  * Returns:
852  * int
853  * Status return:
854  * 0 success
855  * -1 no record found
856  * non-zero some error occurred and a message has been output.
857  *
858  * If the status is non-zero, the returned data is meaningless.
859 -*/
860 int KsmPolicyIdFromZoneId(int zone_id, int* policy_id)
861 {
862  int where = 0; /* WHERE clause value */
863  char* sql = NULL; /* SQL query */
864  DB_RESULT result; /* Handle converted to a result object */
865  DB_ROW row = NULL; /* Row data */
866  int status = 0; /* Status return */
867 
868  /* check the argument */
869  if (zone_id == -1) {
870  return MsgLog(KSM_INVARG, "NULL zone name");
871  }
872 
873  /* Construct the query */
874 
875  sql = DqsSpecifyInit("zones","id, policy_id");
876  DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, zone_id, where++);
877  DqsOrderBy(&sql, "id");
878 
879  /* Execute query and free up the query string */
880  status = DbExecuteSql(DbHandle(), sql, &result);
881  DqsFree(sql);
882 
883  if (status != 0)
884  {
885  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
886  DbFreeResult(result);
887  return status;
888  }
889 
890  /* Get the next row from the data */
891  status = DbFetchRow(result, &row);
892  if (status == 0) {
893  DbInt(row, 1, policy_id);
894  }
895  else if (status == -1) {}
896  /* No rows to return (but no DB error) */
897  else {
898  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
899  }
900 
901  DbFreeRow(row);
902  DbFreeResult(result);
903  return status;
904 }
905 
907 {
908  KSM_POLICY *policy;
909 
910  policy = (KSM_POLICY *)malloc(sizeof(KSM_POLICY));
911  policy->description = (char *)calloc(KSM_POLICY_DESC_LENGTH, sizeof(char));
912  policy->signer = (KSM_SIGNER_POLICY *)malloc(sizeof(KSM_SIGNER_POLICY));
913  policy->signature = (KSM_SIGNATURE_POLICY *)malloc(sizeof(KSM_SIGNATURE_POLICY));
914  policy->denial = (KSM_DENIAL_POLICY *)malloc(sizeof(KSM_DENIAL_POLICY));
915  policy->keys = (KSM_COMMON_KEY_POLICY *)malloc(sizeof(KSM_COMMON_KEY_POLICY));
916  policy->ksk = (KSM_KEY_POLICY *)malloc(sizeof(KSM_KEY_POLICY));
917  policy->zsk = (KSM_KEY_POLICY *)malloc(sizeof(KSM_KEY_POLICY));
918  policy->enforcer = (KSM_ENFORCER_POLICY *)malloc(sizeof(KSM_ENFORCER_POLICY));
919  policy->zone = (KSM_ZONE_POLICY *)malloc(sizeof(KSM_ZONE_POLICY));
920  policy->parent = (KSM_PARENT_POLICY *)malloc(sizeof(KSM_PARENT_POLICY));
921  /* policy->audit = (KSM_AUDIT_POLICY *)malloc(sizeof(KSM_AUDIT_POLICY)); */
922  policy->audit = (char *)calloc(KSM_POLICY_AUDIT_LENGTH, sizeof(char));
923 
924  /* if allocation fails, return NULL*/
925  if (policy->description == NULL ||
926  policy->signer == NULL ||
927  policy->signature == NULL ||
928  policy->denial == NULL ||
929  policy->keys == NULL ||
930  policy->ksk == NULL ||
931  policy->zsk == NULL ||
932  policy->enforcer == NULL ||
933  policy->zone == NULL ||
934  policy->parent == NULL ||
935  policy->audit == NULL) {
936  KsmPolicyFree(policy);
937  return NULL;
938  }
939 
940  return policy;
941 }
942 
944 {
945  free(policy->description);
946  free(policy->signer);
947  free(policy->signature);
948  free(policy->denial);
949  free(policy->keys);
950  free(policy->ksk);
951  free(policy->zsk);
952  free(policy->enforcer);
953  free(policy->zone);
954  free(policy->parent);
955  free(policy->audit);
956  free(policy);
957 }
void DbFreeResult(DB_RESULT result)
int KsmPolicyInit(DB_RESULT *handle, const char *name)
Definition: ksm_policy.c:69
char name[KSM_NAME_LENGTH]
Definition: ksm.h:249
unsigned long sm_capacity
Definition: ksm.h:212
char * audit
Definition: ksm.h:261
#define StrFree(x)
Definition: string_util.h:68
int overlap
Definition: ksm.h:214
#define KSM_INVARG
Definition: ksmdef.h:68
int rfc5011
Definition: ksm.h:216
int DbFetchRow(DB_RESULT result, DB_ROW *row)
#define KSM_SQLFAIL
Definition: ksmdef.h:69
int KsmPolicy(DB_RESULT handle, KSM_POLICY *data)
Definition: ksm_policy.c:191
#define DB_SECURITY_MODULE_NAME
Definition: db_fields.h:95
char category[KSM_NAME_LENGTH]
Definition: ksm.h:267
int serial
Definition: ksm.h:233
char * DqsSpecifyInit(const char *table, const char *fields)
Definition: dq_string.c:119
#define DB_SECURITY_MODULE_FIELDS
Definition: db_fields.h:93
#define DB_SECURITY_MODULE_TABLE
Definition: db_fields.h:92
int soa_min
Definition: ksm.h:232
KSM_POLICY * KsmPolicyAlloc()
Definition: ksm_policy.c:906
KSM_COMMON_KEY_POLICY * keys
Definition: ksm.h:254
int soa_ttl
Definition: ksm.h:231
#define KSM_TIME_LENGTH
Definition: ksm.h:64
KSM_KEY_POLICY * zsk
Definition: ksm.h:256
int bits
Definition: ksm.h:208
int KsmPolicySetIdFromName(KSM_POLICY *policy)
Definition: ksm_policy.c:810
void DqsConditionKeyword(char **query, const char *field, DQS_COMPARISON compare, const char *value, int index)
Definition: dq_string.c:253
int manual_rollover
Definition: ksm.h:219
void DqsOrderBy(char **query, const char *field)
Definition: dq_string.c:279
char sm_name[KSM_NAME_LENGTH]
Definition: ksm.h:211
int MsgLog(int status,...)
Definition: message.c:338
int KsmPolicyUpdateSalt(KSM_POLICY *policy)
Definition: ksm_policy.c:498
int shared_keys
Definition: ksm.h:262
int KsmPolicyRead(KSM_POLICY *policy)
Definition: ksm_policy.c:232
#define DB_SECURITY_MODULE_REQUIREBACKUP
Definition: db_fields.h:97
void DqsFree(char *query)
Definition: dq_string.c:322
#define DB_POLICY_PARAMETER_CATEGORY
Definition: db_fields.h:89
int algorithm
Definition: ksm.h:207
#define KSM_NAME_LENGTH
Definition: ksm.h:59
DB_HANDLE DbHandle(void)
int KsmPolicyParameter(DB_RESULT handle, KSM_POLICY_PARAMETER *data)
Definition: ksm_policy.c:369
char salt_stamp[KSM_TIME_LENGTH]
Definition: ksm.h:195
void DqsConditionInt(char **query, const char *field, DQS_COMPARISON compare, int value, int index)
Definition: dq_string.c:226
int keygeninterval
Definition: ksm.h:226
int KsmPolicyReadFromId(KSM_POLICY *policy)
Definition: ksm_policy.c:417
char salt[KSM_SALT_LENGTH]
Definition: ksm.h:194
int saltlength
Definition: ksm.h:193
int KsmPolicyIdFromZoneId(int zone_id, int *policy_id)
Definition: ksm_policy.c:860
char * DtParseDateTimeString(const char *string)
Definition: datetime.c:617
int KsmPolicyParametersInit(DB_RESULT *handle, const char *name)
Definition: ksm_policy.c:110
KSM_PARENT_POLICY * parent
Definition: ksm.h:259
KSM_DENIAL_POLICY * denial
Definition: ksm.h:253
void StrStrncpy(char *dest, const char *src, size_t destlen)
Definition: string_util.c:178
KSM_KEY_POLICY * ksk
Definition: ksm.h:255
KSM_ZONE_POLICY * zone
Definition: ksm.h:258
int propdelay
Definition: ksm.h:230
const char * DbErrmsg(DB_HANDLE handle)
void KsmPolicyFree(KSM_POLICY *policy)
Definition: ksm_policy.c:943
void DbFreeRow(DB_ROW row)
KSM_SIGNER_POLICY * signer
Definition: ksm.h:251
int standby_keys
Definition: ksm.h:218
#define DB_POLICY_ID
Definition: db_fields.h:109
#define KSM_SALT_LENGTH
Definition: ksm.h:68
#define KSM_POLICY_AUDIT_LENGTH
Definition: ksm.h:63
int KsmPolicyNullSaltStamp(int policy_id)
Definition: ksm_policy.c:676
#define DB_POLICY_SALT
Definition: db_fields.h:113
int DbExecuteSql(DB_HANDLE handle, const char *stmt_str, DB_RESULT *result)
#define KSM_SQL_SIZE
Definition: ksm.h:66
#define KSM_POLICY_DESC_LENGTH
Definition: ksm.h:62
int DbStringBuffer(DB_ROW row, int field_index, char *buffer, size_t buflen)
int propdelay
Definition: ksm.h:237
char * description
Definition: ksm.h:250
int propdelay
Definition: ksm.h:173
#define DB_POLICY_PARAMETER_VALUE
Definition: db_fields.h:90
int DbUnsignedLong(DB_ROW row, int field_index, unsigned long *value)
int KsmPolicyPopulateSMFromIds(KSM_POLICY *policy)
Definition: ksm_policy.c:709
#define DB_SECURITY_MODULE_CAPACITY
Definition: db_fields.h:96
void KsmParameterEnd(DB_RESULT result)
int sm
Definition: ksm.h:210
char name[KSM_NAME_LENGTH]
Definition: ksm.h:266
#define DB_POLICY_SALT_STAMP
Definition: db_fields.h:114
#define DB_POLICY_DESCRIPTION
Definition: db_fields.h:111
int KsmPolicyExists(const char *name)
Definition: ksm_policy.c:151
#define KME_BUFFEROVF
Definition: kmedef.h:50
int id
Definition: ksm.h:248
int ttl
Definition: ksm.h:215
int require_backup
Definition: ksm.h:213
KSM_ENFORCER_POLICY * enforcer
Definition: ksm.h:257
int DbInt(DB_ROW row, int field_index, int *value)
#define DB_POLICY_AUDIT
Definition: db_fields.h:112
int algorithm
Definition: ksm.h:189
int rollover_scheme
Definition: ksm.h:220
int KsmPolicyNameFromId(KSM_POLICY *policy)
Definition: ksm_policy.c:430
int lifetime
Definition: ksm.h:209
int iteration
Definition: ksm.h:190
int DtDateDiff(const char *date1, const char *date2, int *result)
Definition: datetime.c:828
int DbExecuteSqlNoResult(DB_HANDLE handle, const char *stmt_str)
void DqsConditionString(char **query, const char *field, DQS_COMPARISON compare, const char *value, int index)
Definition: dq_string.c:240
#define DB_POLICY_PARAMETER_NAME
Definition: db_fields.h:88
#define DB_POLICY_NAME
Definition: db_fields.h:110
KSM_SIGNATURE_POLICY * signature
Definition: ksm.h:252