OpenDNSSEC-enforcer  1.4.7
ksm_policy.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008-2009 Nominet UK. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
27 /*
28  * ksm_policy.c - Manipulation of Policy Information
29  */
30 
31 #include "config.h"
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, 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  /* Resolve ambiguity in comparing names for these two parameters. With the old code if
275  ttlds came out the DB second, it would overwrite the value for ttl! */
276  if (strncmp(data.name, "ttlds", 5) == 0) {
277  policy->parent->ds_ttl=data.value;
278  }
279  else if (strncmp(data.name, "ttl", 3) == 0) {
280  policy->parent->soa_ttl=data.value;
281  }
282  }
283  if (strncmp(data.category, "signature", 9) == 0) {
284  if (strncmp(data.name, "jitter", 6) == 0) policy->signer->jitter=data.value;
285  if (strncmp(data.name, "refresh", 7) == 0) policy->signer->refresh=data.value;
286  if (strncmp(data.name, "clockskew", 9) == 0) policy->signature->clockskew=data.value;
287  if (strncmp(data.name, "resign", 6) == 0) policy->signature->resign=data.value;
288  if (strncmp(data.name, "valdefault", 10) == 0) policy->signature->valdefault=data.value;
289  if (strncmp(data.name, "valdenial", 9) == 0) policy->signature->valdenial=data.value;
290  }
291  if (strncmp(data.category, "denial", 6) == 0) {
292  if (strncmp(data.name, "version", 7) == 0) policy->denial->version=data.value;
293  if (strncmp(data.name, "resalt", 6) == 0) policy->denial->resalt=data.value;
294  if (strncmp(data.name, "alg", 3) == 0) policy->denial->algorithm=data.value;
295  if (strncmp(data.name, "iteration", 9) == 0) policy->denial->iteration=data.value;
296  if (strncmp(data.name, "optout", 6) == 0) policy->denial->optout=data.value;
297  if (strncmp(data.name, "ttl",3) == 0) policy->denial->ttl=data.value;
298  if (strncmp(data.name, "saltlength",10) == 0) policy->denial->saltlength=data.value;
299  }
300  if (strncmp(data.category, "zsk", 3) == 0) {
301  if (strncmp(data.name, "alg",3) == 0) policy->zsk->algorithm=data.value;
302  if (strncmp(data.name, "lifetime",8) == 0) policy->zsk->lifetime=data.value;
303  if (strncmp(data.name, "repository",10) == 0) policy->zsk->sm=data.value;
304  if (strncmp(data.name, "overlap",7) == 0) policy->zsk->overlap=data.value;
305  if (strncmp(data.name, "bits",4) == 0) policy->zsk->bits=data.value;
306  if (strncmp(data.name, "standby",7) == 0) policy->zsk->standby_keys=data.value;
307  if (strncmp(data.name, "manual_rollover",15) == 0) policy->zsk->manual_rollover=data.value;
308  }
309  if (strncmp(data.category, "ksk", 3) == 0) {
310  if (strncmp(data.name, "alg",3) == 0) policy->ksk->algorithm=data.value;
311  if (strncmp(data.name, "lifetime",8) == 0) policy->ksk->lifetime=data.value;
312  if (strncmp(data.name, "repository",10) == 0) policy->ksk->sm=data.value;
313  if (strncmp(data.name, "overlap",7) == 0) policy->ksk->overlap=data.value;
314  if (strncmp(data.name, "rfc5011",7) == 0) policy->ksk->rfc5011=data.value;
315  if (strncmp(data.name, "bits",4) == 0) policy->ksk->bits=data.value;
316  if (strncmp(data.name, "standby",7) == 0) policy->ksk->standby_keys=data.value;
317  if (strncmp(data.name, "manual_rollover",15) == 0) policy->ksk->manual_rollover=data.value;
318  if (strncmp(data.name, "rollover_scheme",15) == 0) policy->ksk->rollover_scheme=data.value;
319  }
320  if (strncmp(data.category, "keys", 4) == 0) {
321  if (strncmp(data.name, "ttl",3) == 0) policy->ksk->ttl=data.value;
322  if (strncmp(data.name, "ttl",3) == 0) policy->zsk->ttl=data.value;
323  if (strncmp(data.name, "zones_share_keys",16) == 0) policy->shared_keys=data.value;
324  if (strncmp(data.name, "ttl",3) == 0) policy->keys->ttl=data.value;
325  if (strncmp(data.name, "zones_share_keys",16) == 0) policy->keys->share_keys=data.value;
326  if (strncmp(data.name, "retiresafety",12) == 0) policy->keys->retire_safety=data.value;
327  if (strncmp(data.name, "publishsafety",13) == 0) policy->keys->publish_safety=data.value;
328  if (strncmp(data.name, "purge",5) == 0) policy->keys->purge=data.value;
329  }
330  /* Ignore any unknown parameters */
331 
332  status = KsmPolicyParameter(result, &data);
333  }
334 
335  /* All done, so tidy up */
336 
337  KsmParameterEnd(result);
338  }
339  } else {
340  return status;
341  }
342 
343  /* convert security module ids into names, capacities and requirebackup flags */
344  status = KsmPolicyPopulateSMFromIds(policy);
345 
346  return status;
347 }
348 
349 /*+
350  * KsmPolicyParameter - Return PolicyParameter Information
351  *
352  * Description:
353  * Returns information about the next key in the result set.
354  *
355  * Arguments:
356  * DB_RESULT result
357  * Handle from KsmParameterInit
358  *
359  * KSM_PARAMETER* data
360  * Data is returned in here.
361  *
362  * Returns:
363  * int
364  * Status return:
365  * 0 success
366  * -1 end of record set reached
367  * non-zero some error occurred and a message has been output.
368  *
369  * If the status is non-zero, the returned data is meaningless.
370 -*/
371 
373 {
374  int status = 0; /* Return status */
375  DB_ROW row = NULL; /* Row data */
376 
377  /* check the argument */
378  if (data == NULL) {
379  return MsgLog(KSM_INVARG, "NULL data");
380  }
381 
382  /* Get the next row from the data */
383  status = DbFetchRow(result, &row);
384 
385  if (status == 0) {
386 
387  /* Now copy the results into the output data */
388 
389  memset(data, 0, sizeof(KSM_POLICY_PARAMETER));
391  sizeof(data->name));
393  sizeof(data->category));
394  status = DbInt(row, DB_POLICY_PARAMETER_VALUE, &(data->value));
395  }
396  else if (status == -1) {}
397  /* No rows to return (but no error) */
398  else {
399  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
400  }
401 
402  if (row != NULL) {
403  DbFreeRow(row);
404  }
405 
406  return status;
407 }
408 
409 /*+
410  * KsmPolicyReadFromId - Read Policy given just the id
411  *
412  * Description:
413  * Read policy from database in to a struct.
414  *
415  * Arguments:
416  * struct policy_t policy
417  * struct to hold policy information should have id populated
418 -*/
419 
421 {
422  int status = KsmPolicyNameFromId(policy);
423 
424  if (status != 0)
425  {
426  return status;
427  }
428 
429  return KsmPolicyRead(policy);
430 
431 }
432 
434 {
435  int where = 0; /* WHERE clause value */
436  char* sql = NULL; /* SQL query */
437  DB_RESULT result; /* Handle converted to a result object */
438  DB_ROW row = NULL; /* Row data */
439  int status = 0; /* Status return */
440 
441  /* check the argument */
442  if (policy == NULL) {
443  return MsgLog(KSM_INVARG, "NULL policy");
444  }
445 
446  /* Construct the query */
447 
448  sql = DqsSpecifyInit("policies","id, name");
449  DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, policy->id, where++);
450  DqsOrderBy(&sql, "id");
451 
452  /* Execute query and free up the query string */
453  status = DbExecuteSql(DbHandle(), sql, &result);
454  DqsFree(sql);
455 
456  if (status != 0)
457  {
458  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
459  DbFreeResult(result);
460  return status;
461  }
462 
463  /* Get the next row from the data */
464  status = DbFetchRow(result, &row);
465  if (status == 0) {
466  DbStringBuffer(row, DB_POLICY_NAME, policy->name, KSM_NAME_LENGTH*sizeof(char));
467  }
468  else if (status == -1) {}
469  /* No rows to return (but no error) */
470  else {
471  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
472  }
473 
474  DbFreeRow(row);
475  DbFreeResult(result);
476  return status;
477 }
478 
479 /*+
480  * KsmPolicyUpdateSalt
481  *
482  * Description:
483  * Given a policy see if the salt needs updating (based on denial->resalt).
484  * If it is out of date then generate a new salt and write it to the struct.
485  * Also update the database with the new value and timestamp.
486  *
487  * Arguments:
488  * struct policy_t policy
489  * struct which holds the current policy information should have been populated
490  *
491  * Returns:
492  * int
493  * Status return:
494  * 0 success
495  * non-zero some error occurred and a message has been output.
496  * -1 no policy found
497  * -2 an error working out time difference between stamp and now
498  *
499 -*/
500 
502 {
503  /* First work out what the current salt is and when it was created */
504  int where = 0; /* WHERE clause value */
505  char* sql = NULL; /* SQL query */
506  DB_RESULT result; /* Handle converted to a result object */
507  DB_ROW row = NULL; /* Row data */
508  int status = 0; /* Status return */
509  char* datetime_now = DtParseDateTimeString("now"); /* where are we in time */
510  int time_diff; /* how many second have elapsed */
511  char* salt; /* This will be the salt that we create */
512  char buffer[KSM_SQL_SIZE]; /* update statement for salt_stamp */
513  unsigned int nchar; /* Number of characters converted */
514  int i = 0; /* a counter */
515  char* hex_chars = "0123456789abcdef"; /* for "manual" random string */
516 
517  /* check the argument */
518  if (policy == NULL) {
519  MsgLog(KSM_INVARG, "NULL policy");
520  StrFree(datetime_now);
521  return -1;
522  }
523 
524  /* Check datetime in case it came back NULL */
525  if (datetime_now == NULL) {
526  printf("Couldn't turn \"now\" into a date, quitting...\n");
527  exit(1);
528  }
529 
530  /* Construct the query */
531 
532  sql = DqsSpecifyInit("policies","id, salt, salt_stamp");
533  DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, policy->id, where++);
534  DqsOrderBy(&sql, "id");
535 
536  /* Execute query and free up the query string */
537  status = DbExecuteSql(DbHandle(), sql, &result);
538  DqsFree(sql);
539 
540  if (status != 0)
541  {
542  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
543  StrFree(datetime_now);
544  return status;
545  }
546 
547  /* Get the next row from the data */
548  status = DbFetchRow(result, &row);
549  if (status == 0) {
550  status = DbStringBuffer(row, DB_POLICY_SALT, policy->denial->salt, KSM_SALT_LENGTH*sizeof(char));
551  if (status == 0) {
552  status = DbStringBuffer(row, DB_POLICY_SALT_STAMP, policy->denial->salt_stamp, KSM_TIME_LENGTH*sizeof(char));
553  }
554 
555  if (status != 0) {
556  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
557  DbFreeResult(result);
558  DbFreeRow(row);
559  StrFree(datetime_now);
560  return status;
561  }
562  }
563  else if (status == -1) {
564  /* No rows to return (but no error), policy_id doesn't exist? */
565  DbFreeResult(result);
566  DbFreeRow(row);
567  StrFree(datetime_now);
568  return -1;
569  }
570  else {
571  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
572 
573  DbFreeResult(result);
574  DbFreeRow(row);
575  StrFree(datetime_now);
576  return status;
577  }
578 
579  DbFreeResult(result);
580  DbFreeRow(row);
581 
582  /* Now see if this needs to be updated; if the stamp is null then assume it does */
583  if (policy->denial->salt_stamp[0] == '\0') {
584  time_diff = -1;
585  } else {
586  status = DtDateDiff(datetime_now, policy->denial->salt_stamp, &time_diff);
587  }
588 
589  if (status == 0) {
590  if (policy->denial->resalt > time_diff && time_diff != -1 && policy->denial->salt[0] != '\0') {
591  /* current salt is fine */
592  StrFree(datetime_now);
593  return status;
594  } else {
595  /* salt needs updating, or is null */
596  salt = (char *)calloc(KSM_SALT_LENGTH, sizeof(char));
597  if (salt == NULL) {
598  MsgLog(KSM_INVARG, "Could not allocate memory for salt");
599  StrFree(datetime_now);
600  exit(1);
601  }
602 
603 #ifdef HAVE_ARC4RANDOM_UNIFORM
604  for (i = 0; i < 2*(policy->denial->saltlength); i++) {
605  salt[i] = hex_chars[arc4random_uniform(strlen(hex_chars))];
606  }
607 #elif HAVE_ARC4RANDOM
608  for (i = 0; i < 2*(policy->denial->saltlength); i++) {
609  salt[i] = hex_chars[arc4random()%strlen(hex_chars)];
610  }
611 #else
612  srand( time(NULL) );
613  for (i = 0; i < 2*(policy->denial->saltlength); i++) {
614  salt[i] = hex_chars[rand()%strlen(hex_chars)];
615  }
616 #endif
617 
618  if (status != 0) {
619  StrFree(datetime_now);
620  StrFree(salt);
621  return status;
622  }
623  StrStrncpy(policy->denial->salt, salt, KSM_SALT_LENGTH);
624  StrStrncpy(policy->denial->salt_stamp, datetime_now, KSM_TIME_LENGTH);
625 
626  StrFree(salt);
627 
628  /* write these back to the database */
629 #ifdef USE_MYSQL
630  nchar = snprintf(buffer, sizeof(buffer),
631  "UPDATE policies SET salt = '%s', salt_stamp = '%s' WHERE ID = %lu",
632  policy->denial->salt, policy->denial->salt_stamp, (unsigned long) policy->id);
633 #else
634  nchar = snprintf(buffer, sizeof(buffer),
635  "UPDATE policies SET salt = '%s', salt_stamp = DATETIME('%s') WHERE ID = %lu",
636  policy->denial->salt, policy->denial->salt_stamp, (unsigned long) policy->id);
637 #endif /* USE_MYSQL */
638  if (nchar < sizeof(buffer)) {
639  /* All OK, execute the statement */
640 
641  status = DbExecuteSqlNoResult(DbHandle(), buffer);
642  }
643  else {
644  /* Unable to create update statement */
645 
646  status = MsgLog(KME_BUFFEROVF, "KsmPolicy");
647  }
648 
649  StrFree(datetime_now);
650  return status;
651  }
652  } else {
653  MsgLog(KSM_INVARG, "Could not calculate DateDiff");
654  StrFree(datetime_now);
655  return -2;
656  }
657 
658  StrFree(datetime_now);
659  return status;
660 }
661 
662 /*+
663  * KsmPolicyNullSaltStamp
664  *
665  * Description:
666  * Given a policy id set its saltstamp to NULL, this will force a resalt on
667  * the next enforcer run, suitable for when salt length has changed for
668  * instance.
669  *
670  * Arguments:
671  * int policy_id
672  * policy to work on
673  *
674  * Returns:
675  * int
676  * Status return:
677  * 0 success
678  * non-zero some error occurred and a message has been output.
679  * -1 no policy found
680  *
681 -*/
682 
683 int KsmPolicyNullSaltStamp(int policy_id)
684 {
685  char buffer[KSM_SQL_SIZE]; /* update statement for salt_stamp */
686  unsigned int nchar; /* Number of characters converted */
687  int status = 0;
688 
689  /* check the argument */
690  if (policy_id < 1) {
691  MsgLog(KSM_INVARG, "Negative or zero policy_id");
692  return -1;
693  }
694 
695  nchar = snprintf(buffer, sizeof(buffer),
696  "UPDATE policies SET salt_stamp = NULL WHERE ID = %lu",
697  (unsigned long) policy_id);
698 
699  if (nchar < sizeof(buffer)) {
700  /* All OK, execute the statement */
701 
702  status = DbExecuteSqlNoResult(DbHandle(), buffer);
703  }
704  else {
705  /* Unable to create update statement */
706 
707  status = MsgLog(KME_BUFFEROVF, "KsmPolicy");
708  }
709 
710  return status;
711 }
712 
713 
714 /* Populate security module information for a structure that has the sm_id fields filled in */
715 
717 {
718  int where = 0; /* WHERE clause value */
719  char* sql = NULL; /* SQL query */
720  DB_RESULT result; /* Handle converted to a result object */
721  DB_ROW row = NULL; /* Row data */
722  DB_RESULT result2; /* Handle converted to a result object */
723  DB_ROW row2 = NULL; /* Row data */
724  int status = 0; /* Status return */
725 
726  /* check the argument */
727  if (policy == NULL) {
728  return MsgLog(KSM_INVARG, "NULL policy");
729  }
730 
731  /* Construct the query for ksk */
732 
734  DqsConditionInt(&sql, "id", DQS_COMPARE_EQ, policy->ksk->sm, where++);
735 
736  /* Execute query and free up the query string */
737  status = DbExecuteSql(DbHandle(), sql, &result);
738  DqsFree(sql);
739 
740  if (status != 0)
741  {
742  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
743  DbFreeResult(result);
744  return status;
745  }
746 
747  /* Get the next row from the data */
748  status = DbFetchRow(result, &row);
749  if (status == 0) {
750  DbStringBuffer(row, DB_SECURITY_MODULE_NAME, policy->ksk->sm_name, KSM_NAME_LENGTH*sizeof(char));
753  }
754  else if (status == -1) {}
755  /* No rows to return (but no error) */
756  else {
757  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
758  DbFreeResult(result);
759  DbFreeRow(row);
760  return status;
761  }
762 
763  DbFreeResult(result);
764  DbFreeRow(row);
765 
766 
767  /* Construct the query for zsk */
768  where = 0;
769 
771  DqsConditionInt(&sql, "id", DQS_COMPARE_EQ, policy->zsk->sm, where++);
772 
773  /* Execute query and free up the query string */
774  status = DbExecuteSql(DbHandle(), sql, &result2);
775  DqsFree(sql);
776 
777  if (status != 0)
778  {
779  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
780  DbFreeResult(result2);
781  return status;
782  }
783 
784  /* Get the next row from the data */
785  status = DbFetchRow(result2, &row2);
786  if (status == 0) {
787  DbStringBuffer(row2, DB_SECURITY_MODULE_NAME, policy->zsk->sm_name, KSM_NAME_LENGTH*sizeof(char));
790  }
791  else if (status == -1) {}
792  /* No rows to return (but no error) */
793  else {
794  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
795  }
796 
797  DbFreeRow(row2);
798  DbFreeResult(result2);
799  return status;
800 }
801 
802 /*+
803  * KsmPolicySetIdFromName - Given a policy with the name set, fill in the ID
804  *
805  *
806  * Arguments:
807  *
808  * Name of the parameter.
809  *
810  *
811  * Returns:
812  * int
813  * 0 Success, value found
814  * Other Error
815 -*/
816 
818 {
819  int status; /* Status return */
820  DB_RESULT result; /* Handle converted to a result object */
821  DB_ROW row = NULL; /* Row data */
822 
823  if (policy == NULL || policy->name[0] == '\0') {
824  return MsgLog(KSM_INVARG, "NULL policy or name");
825  }
826 
827  status = KsmPolicyInit(&result, policy->name);
828  if (status == 0) {
829  /* Get the next row from the data */
830  status = DbFetchRow(result, &row);
831  if (status == 0) {
832  DbInt(row, DB_POLICY_ID, &policy->id);
834  DbStringBuffer(row, 3, policy->denial->salt, KSM_SALT_LENGTH*sizeof(char));
835  }
836  else if (status == -1) {
837  /* No rows to return (but no error) */
838  }
839  else {
840  /* Error */
841  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
842  }
843 
844  }
845  DbFreeRow(row);
846  DbFreeResult(result);
847  return status;
848 }
849 
850 /*+
851  * KsmPolicyIdFromZoneId
852  *
853  * Arguments:
854  * int zone_id zone id
855  * int* policy_id returned id
856  *
857  * Returns:
858  * int
859  * Status return:
860  * 0 success
861  * -1 no record found
862  * non-zero some error occurred and a message has been output.
863  *
864  * If the status is non-zero, the returned data is meaningless.
865 -*/
866 int KsmPolicyIdFromZoneId(int zone_id, int* policy_id)
867 {
868  int where = 0; /* WHERE clause value */
869  char* sql = NULL; /* SQL query */
870  DB_RESULT result; /* Handle converted to a result object */
871  DB_ROW row = NULL; /* Row data */
872  int status = 0; /* Status return */
873 
874  /* check the argument */
875  if (zone_id == -1) {
876  return MsgLog(KSM_INVARG, "NULL zone name");
877  }
878 
879  /* Construct the query */
880 
881  sql = DqsSpecifyInit("zones","id, policy_id");
882  DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, zone_id, where++);
883  DqsOrderBy(&sql, "id");
884 
885  /* Execute query and free up the query string */
886  status = DbExecuteSql(DbHandle(), sql, &result);
887  DqsFree(sql);
888 
889  if (status != 0)
890  {
891  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
892  DbFreeResult(result);
893  return status;
894  }
895 
896  /* Get the next row from the data */
897  status = DbFetchRow(result, &row);
898  if (status == 0) {
899  DbInt(row, 1, policy_id);
900  }
901  else if (status == -1) {}
902  /* No rows to return (but no DB error) */
903  else {
904  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
905  }
906 
907  DbFreeRow(row);
908  DbFreeResult(result);
909  return status;
910 }
911 
912 /*+
913  * KsmPolicyUpdateDesc - Update a policy description
914  *
915  * Arguments:
916  *
917  * int policy_id
918  * id of the policy
919  *
920  * const char* policy_description
921  * Description for that policy
922  *
923  * Returns:
924  * int
925  * Status return. 0 on success.
926  * -1 if an unexpected count value was returned
927 -*/
928 
929 int KsmPolicyUpdateDesc(int policy_id, const char* policy_description)
930 {
931  char* sql = NULL; /* SQL query */
932  int status = 0; /* Status return */
933 
934  char quoted_desc[KSM_POLICY_DESC_LENGTH]; /* with bad chars quoted */
935  /* check the main argument (description may be NULL) */
936  if (policy_id <= 0) {
937  return MsgLog(KSM_INVARG, "NULL policy id");
938  }
939 
940  /* Quote description */
941  status = DbQuoteString(DbHandle(), policy_description, quoted_desc, KSM_POLICY_DESC_LENGTH);
942 
943  if (status != 0) {
944  return status;
945  }
946 
947  /* Update policy */
948  sql = DusInit("policies");
949  DusSetString(&sql, "description", quoted_desc, 0);
950  DusConditionInt(&sql, "id", DQS_COMPARE_EQ, policy_id, 0);
951  DusEnd(&sql);
952 
953  status = DbExecuteSqlNoResult(DbHandle(), sql);
954  DisFree(sql);
955 
956  return status;
957 }
958 
960 {
961  KSM_POLICY *policy;
962 
963  policy = (KSM_POLICY *)malloc(sizeof(KSM_POLICY));
964  if (policy == NULL) {
965  return NULL;
966  }
967 
968  policy->description = (char *)calloc(KSM_POLICY_DESC_LENGTH, sizeof(char));
969  policy->signer = (KSM_SIGNER_POLICY *)malloc(sizeof(KSM_SIGNER_POLICY));
970  policy->signature = (KSM_SIGNATURE_POLICY *)malloc(sizeof(KSM_SIGNATURE_POLICY));
971  policy->denial = (KSM_DENIAL_POLICY *)malloc(sizeof(KSM_DENIAL_POLICY));
972  policy->keys = (KSM_COMMON_KEY_POLICY *)malloc(sizeof(KSM_COMMON_KEY_POLICY));
973  policy->ksk = (KSM_KEY_POLICY *)malloc(sizeof(KSM_KEY_POLICY));
974  policy->zsk = (KSM_KEY_POLICY *)malloc(sizeof(KSM_KEY_POLICY));
975  policy->enforcer = (KSM_ENFORCER_POLICY *)malloc(sizeof(KSM_ENFORCER_POLICY));
976  policy->zone = (KSM_ZONE_POLICY *)malloc(sizeof(KSM_ZONE_POLICY));
977  policy->parent = (KSM_PARENT_POLICY *)malloc(sizeof(KSM_PARENT_POLICY));
978 
979  /* if allocation fails, return NULL*/
980  if (policy->description == NULL ||
981  policy->signer == NULL ||
982  policy->signature == NULL ||
983  policy->denial == NULL ||
984  policy->keys == NULL ||
985  policy->ksk == NULL ||
986  policy->zsk == NULL ||
987  policy->enforcer == NULL ||
988  policy->zone == NULL ||
989  policy->parent == NULL) {
990  KsmPolicyFree(policy);
991  return NULL;
992  }
993 
994  return policy;
995 }
996 
998 {
999  free(policy->description);
1000  free(policy->signer);
1001  free(policy->signature);
1002  free(policy->denial);
1003  free(policy->keys);
1004  free(policy->ksk);
1005  free(policy->zsk);
1006  free(policy->enforcer);
1007  free(policy->zone);
1008  free(policy->parent);
1009  free(policy);
1010 }
void DbFreeResult(DB_RESULT result)
int KsmPolicy(DB_RESULT result, KSM_POLICY *data)
Definition: ksm_policy.c:191
char name[KSM_NAME_LENGTH]
Definition: ksm.h:242
int KsmPolicyNameFromId(KSM_POLICY *policy)
Definition: ksm_policy.c:433
int KsmPolicySetIdFromName(KSM_POLICY *policy)
Definition: ksm_policy.c:817
unsigned long sm_capacity
Definition: ksm.h:209
KSM_POLICY * KsmPolicyAlloc()
Definition: ksm_policy.c:959
#define StrFree(x)
Definition: string_util.h:66
int overlap
Definition: ksm.h:211
#define KSM_INVARG
Definition: ksmdef.h:66
int rfc5011
Definition: ksm.h:213
int DbFetchRow(DB_RESULT result, DB_ROW *row)
#define KSM_SQLFAIL
Definition: ksmdef.h:67
#define DB_SECURITY_MODULE_NAME
Definition: db_fields.h:93
char category[KSM_NAME_LENGTH]
Definition: ksm.h:258
int serial
Definition: ksm.h:230
char * DqsSpecifyInit(const char *table, const char *fields)
Definition: dq_string.c:117
#define DB_SECURITY_MODULE_FIELDS
Definition: db_fields.h:91
#define DB_SECURITY_MODULE_TABLE
Definition: db_fields.h:90
void KsmPolicyFree(KSM_POLICY *policy)
Definition: ksm_policy.c:997
int KsmPolicyUpdateDesc(int policy_id, const char *policy_description)
Definition: ksm_policy.c:929
int soa_min
Definition: ksm.h:229
KSM_COMMON_KEY_POLICY * keys
Definition: ksm.h:247
int soa_ttl
Definition: ksm.h:228
#define KSM_TIME_LENGTH
Definition: ksm.h:61
KSM_KEY_POLICY * zsk
Definition: ksm.h:249
int bits
Definition: ksm.h:205
void DqsConditionKeyword(char **query, const char *field, DQS_COMPARISON compare, const char *value, int index)
Definition: dq_string.c:251
int KsmPolicyReadFromId(KSM_POLICY *policy)
Definition: ksm_policy.c:420
int manual_rollover
Definition: ksm.h:216
void DqsOrderBy(char **query, const char *field)
Definition: dq_string.c:277
char sm_name[KSM_NAME_LENGTH]
Definition: ksm.h:208
int MsgLog(int status,...)
Definition: message.c:335
int shared_keys
Definition: ksm.h:253
#define DB_SECURITY_MODULE_REQUIREBACKUP
Definition: db_fields.h:95
void DqsFree(char *query)
Definition: dq_string.c:320
int KsmPolicyUpdateSalt(KSM_POLICY *policy)
Definition: ksm_policy.c:501
#define DB_POLICY_PARAMETER_CATEGORY
Definition: db_fields.h:87
int algorithm
Definition: ksm.h:204
void DusConditionInt(char **query, const char *field, DQS_COMPARISON compare, int value, int clause)
Definition: du_string.c:170
#define KSM_NAME_LENGTH
Definition: ksm.h:57
int KsmPolicyRead(KSM_POLICY *policy)
Definition: ksm_policy.c:232
DB_HANDLE DbHandle(void)
char salt_stamp[KSM_TIME_LENGTH]
Definition: ksm.h:192
int KsmPolicyParametersInit(DB_RESULT *result, const char *name)
Definition: ksm_policy.c:110
void DqsConditionInt(char **query, const char *field, DQS_COMPARISON compare, int value, int index)
Definition: dq_string.c:224
int keygeninterval
Definition: ksm.h:223
char salt[KSM_SALT_LENGTH]
Definition: ksm.h:191
int saltlength
Definition: ksm.h:190
int DbQuoteString(DB_HANDLE handle, const char *in, char *buffer, size_t buflen)
char * DtParseDateTimeString(const char *string)
Definition: datetime.c:614
KSM_PARENT_POLICY * parent
Definition: ksm.h:252
KSM_DENIAL_POLICY * denial
Definition: ksm.h:246
void StrStrncpy(char *dest, const char *src, size_t destlen)
Definition: string_util.c:176
KSM_KEY_POLICY * ksk
Definition: ksm.h:248
int KsmPolicyParameter(DB_RESULT result, KSM_POLICY_PARAMETER *data)
Definition: ksm_policy.c:372
KSM_ZONE_POLICY * zone
Definition: ksm.h:251
int propdelay
Definition: ksm.h:227
const char * DbErrmsg(DB_HANDLE handle)
void DbFreeRow(DB_ROW row)
KSM_SIGNER_POLICY * signer
Definition: ksm.h:244
int standby_keys
Definition: ksm.h:215
#define DB_POLICY_ID
Definition: db_fields.h:109
#define KSM_SALT_LENGTH
Definition: ksm.h:65
#define DB_POLICY_SALT
Definition: db_fields.h:112
int DbExecuteSql(DB_HANDLE handle, const char *stmt_str, DB_RESULT *result)
#define KSM_SQL_SIZE
Definition: ksm.h:63
#define KSM_POLICY_DESC_LENGTH
Definition: ksm.h:60
int DbStringBuffer(DB_ROW row, int field_index, char *buffer, size_t buflen)
int propdelay
Definition: ksm.h:234
char * description
Definition: ksm.h:243
void DusEnd(char **sql)
Definition: du_string.c:202
int propdelay
Definition: ksm.h:170
#define DB_POLICY_PARAMETER_VALUE
Definition: db_fields.h:88
int KsmPolicyInit(DB_RESULT *result, const char *name)
Definition: ksm_policy.c:69
int DbUnsignedLong(DB_ROW row, int field_index, unsigned long *value)
char * DusInit(const char *table)
Definition: du_string.c:60
#define DB_SECURITY_MODULE_CAPACITY
Definition: db_fields.h:94
void KsmParameterEnd(DB_RESULT result)
void DisFree(char *sql)
Definition: di_string.c:191
int sm
Definition: ksm.h:207
char name[KSM_NAME_LENGTH]
Definition: ksm.h:257
#define DB_POLICY_SALT_STAMP
Definition: db_fields.h:113
int KsmPolicyIdFromZoneId(int zone_id, int *policy_id)
Definition: ksm_policy.c:866
#define DB_POLICY_DESCRIPTION
Definition: db_fields.h:111
#define KME_BUFFEROVF
Definition: kmedef.h:48
int id
Definition: ksm.h:241
int ttl
Definition: ksm.h:212
int require_backup
Definition: ksm.h:210
KSM_ENFORCER_POLICY * enforcer
Definition: ksm.h:250
int DbInt(DB_ROW row, int field_index, int *value)
int KsmPolicyNullSaltStamp(int policy_id)
Definition: ksm_policy.c:683
int KsmPolicyExists(const char *name)
Definition: ksm_policy.c:151
int algorithm
Definition: ksm.h:186
int rollover_scheme
Definition: ksm.h:217
int lifetime
Definition: ksm.h:206
int iteration
Definition: ksm.h:187
void DusSetString(char **sql, const char *field, const char *data, int clause)
Definition: du_string.c:113
int DtDateDiff(const char *date1, const char *date2, int *result)
Definition: datetime.c:825
int DbExecuteSqlNoResult(DB_HANDLE handle, const char *stmt_str)
int KsmPolicyPopulateSMFromIds(KSM_POLICY *policy)
Definition: ksm_policy.c:716
void DqsConditionString(char **query, const char *field, DQS_COMPARISON compare, const char *value, int index)
Definition: dq_string.c:238
#define DB_POLICY_PARAMETER_NAME
Definition: db_fields.h:86
#define DB_POLICY_NAME
Definition: db_fields.h:110
KSM_SIGNATURE_POLICY * signature
Definition: ksm.h:245