OpenDNSSEC-enforcer  1.4.3
ksm_policy.c
Go to the documentation of this file.
1 /*
2  * $Id: ksm_policy.c 7401 2013-11-14 15:46:25Z sion $
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, 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  /* Ignore any unknown parameters */
325 
326  status = KsmPolicyParameter(result, &data);
327  }
328 
329  /* All done, so tidy up */
330 
331  KsmParameterEnd(result);
332  }
333  } else {
334  return status;
335  }
336 
337  /* convert security module ids into names, capacities and requirebackup flags */
338  status = KsmPolicyPopulateSMFromIds(policy);
339 
340  return status;
341 }
342 
343 /*+
344  * KsmPolicyParameter - Return PolicyParameter Information
345  *
346  * Description:
347  * Returns information about the next key in the result set.
348  *
349  * Arguments:
350  * DB_RESULT result
351  * Handle from KsmParameterInit
352  *
353  * KSM_PARAMETER* data
354  * Data is returned in here.
355  *
356  * Returns:
357  * int
358  * Status return:
359  * 0 success
360  * -1 end of record set reached
361  * non-zero some error occurred and a message has been output.
362  *
363  * If the status is non-zero, the returned data is meaningless.
364 -*/
365 
367 {
368  int status = 0; /* Return status */
369  DB_ROW row = NULL; /* Row data */
370 
371  /* check the argument */
372  if (data == NULL) {
373  return MsgLog(KSM_INVARG, "NULL data");
374  }
375 
376  /* Get the next row from the data */
377  status = DbFetchRow(result, &row);
378 
379  if (status == 0) {
380 
381  /* Now copy the results into the output data */
382 
383  memset(data, 0, sizeof(KSM_POLICY_PARAMETER));
385  sizeof(data->name));
387  sizeof(data->category));
388  status = DbInt(row, DB_POLICY_PARAMETER_VALUE, &(data->value));
389  }
390  else if (status == -1) {}
391  /* No rows to return (but no error) */
392  else {
393  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
394  }
395 
396  if (row != NULL) {
397  DbFreeRow(row);
398  }
399 
400  return status;
401 }
402 
403 /*+
404  * KsmPolicyReadFromId - Read Policy given just the id
405  *
406  * Description:
407  * Read policy from database in to a struct.
408  *
409  * Arguments:
410  * struct policy_t policy
411  * struct to hold policy information should have id populated
412 -*/
413 
415 {
416  int status = KsmPolicyNameFromId(policy);
417 
418  if (status != 0)
419  {
420  return status;
421  }
422 
423  return KsmPolicyRead(policy);
424 
425 }
426 
428 {
429  int where = 0; /* WHERE clause value */
430  char* sql = NULL; /* SQL query */
431  DB_RESULT result; /* Handle converted to a result object */
432  DB_ROW row = NULL; /* Row data */
433  int status = 0; /* Status return */
434 
435  /* check the argument */
436  if (policy == NULL) {
437  return MsgLog(KSM_INVARG, "NULL policy");
438  }
439 
440  /* Construct the query */
441 
442  sql = DqsSpecifyInit("policies","id, name");
443  DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, policy->id, where++);
444  DqsOrderBy(&sql, "id");
445 
446  /* Execute query and free up the query string */
447  status = DbExecuteSql(DbHandle(), sql, &result);
448  DqsFree(sql);
449 
450  if (status != 0)
451  {
452  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
453  DbFreeResult(result);
454  return status;
455  }
456 
457  /* Get the next row from the data */
458  status = DbFetchRow(result, &row);
459  if (status == 0) {
460  DbStringBuffer(row, DB_POLICY_NAME, policy->name, KSM_NAME_LENGTH*sizeof(char));
461  }
462  else if (status == -1) {}
463  /* No rows to return (but no error) */
464  else {
465  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
466  }
467 
468  DbFreeRow(row);
469  DbFreeResult(result);
470  return status;
471 }
472 
473 /*+
474  * KsmPolicyUpdateSalt
475  *
476  * Description:
477  * Given a policy see if the salt needs updating (based on denial->resalt).
478  * If it is out of date then generate a new salt and write it to the struct.
479  * Also update the database with the new value and timestamp.
480  *
481  * Arguments:
482  * struct policy_t policy
483  * struct which holds the current policy information should have been populated
484  *
485  * Returns:
486  * int
487  * Status return:
488  * 0 success
489  * non-zero some error occurred and a message has been output.
490  * -1 no policy found
491  * -2 an error working out time difference between stamp and now
492  *
493 -*/
494 
496 {
497  /* First work out what the current salt is and when it was created */
498  int where = 0; /* WHERE clause value */
499  char* sql = NULL; /* SQL query */
500  DB_RESULT result; /* Handle converted to a result object */
501  DB_ROW row = NULL; /* Row data */
502  int status = 0; /* Status return */
503  char* datetime_now = DtParseDateTimeString("now"); /* where are we in time */
504  int time_diff; /* how many second have elapsed */
505  char* salt; /* This will be the salt that we create */
506  char buffer[KSM_SQL_SIZE]; /* update statement for salt_stamp */
507  unsigned int nchar; /* Number of characters converted */
508  int i = 0; /* a counter */
509  char* hex_chars = "0123456789abcdef"; /* for "manual" random string */
510 
511  /* check the argument */
512  if (policy == NULL) {
513  MsgLog(KSM_INVARG, "NULL policy");
514  StrFree(datetime_now);
515  return -1;
516  }
517 
518  /* Check datetime in case it came back NULL */
519  if (datetime_now == NULL) {
520  printf("Couldn't turn \"now\" into a date, quitting...\n");
521  exit(1);
522  }
523 
524  /* Construct the query */
525 
526  sql = DqsSpecifyInit("policies","id, salt, salt_stamp");
527  DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, policy->id, where++);
528  DqsOrderBy(&sql, "id");
529 
530  /* Execute query and free up the query string */
531  status = DbExecuteSql(DbHandle(), sql, &result);
532  DqsFree(sql);
533 
534  if (status != 0)
535  {
536  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
537  StrFree(datetime_now);
538  return status;
539  }
540 
541  /* Get the next row from the data */
542  status = DbFetchRow(result, &row);
543  if (status == 0) {
544  status = DbStringBuffer(row, DB_POLICY_SALT, policy->denial->salt, KSM_SALT_LENGTH*sizeof(char));
545  if (status == 0) {
546  status = DbStringBuffer(row, DB_POLICY_SALT_STAMP, policy->denial->salt_stamp, KSM_TIME_LENGTH*sizeof(char));
547  }
548 
549  if (status != 0) {
550  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
551  DbFreeResult(result);
552  DbFreeRow(row);
553  StrFree(datetime_now);
554  return status;
555  }
556  }
557  else if (status == -1) {
558  /* No rows to return (but no error), policy_id doesn't exist? */
559  DbFreeResult(result);
560  DbFreeRow(row);
561  StrFree(datetime_now);
562  return -1;
563  }
564  else {
565  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
566 
567  DbFreeResult(result);
568  DbFreeRow(row);
569  StrFree(datetime_now);
570  return status;
571  }
572 
573  DbFreeResult(result);
574  DbFreeRow(row);
575 
576  /* Now see if this needs to be updated; if the stamp is null then assume it does */
577  if (policy->denial->salt_stamp[0] == '\0') {
578  time_diff = -1;
579  } else {
580  status = DtDateDiff(datetime_now, policy->denial->salt_stamp, &time_diff);
581  }
582 
583  if (status == 0) {
584  if (policy->denial->resalt > time_diff && time_diff != -1 && policy->denial->salt[0] != '\0') {
585  /* current salt is fine */
586  StrFree(datetime_now);
587  return status;
588  } else {
589  /* salt needs updating, or is null */
590  salt = (char *)calloc(KSM_SALT_LENGTH, sizeof(char));
591  if (salt == NULL) {
592  MsgLog(KSM_INVARG, "Could not allocate memory for salt");
593  StrFree(datetime_now);
594  exit(1);
595  }
596 
597 #ifdef HAVE_ARC4RANDOM
598  for (i = 0; i < 2*(policy->denial->saltlength); i++) {
599  salt[i] = hex_chars[arc4random()%strlen(hex_chars)];
600  }
601 #else
602  srand( time(NULL) );
603  for (i = 0; i < 2*(policy->denial->saltlength); i++) {
604  salt[i] = hex_chars[rand()%strlen(hex_chars)];
605  }
606 #endif
607 
608  if (status != 0) {
609  StrFree(datetime_now);
610  StrFree(salt);
611  return status;
612  }
613  StrStrncpy(policy->denial->salt, salt, KSM_SALT_LENGTH);
614  StrStrncpy(policy->denial->salt_stamp, datetime_now, KSM_TIME_LENGTH);
615 
616  StrFree(salt);
617 
618  /* write these back to the database */
619 #ifdef USE_MYSQL
620  nchar = snprintf(buffer, sizeof(buffer),
621  "UPDATE policies SET salt = '%s', salt_stamp = '%s' WHERE ID = %lu",
622  policy->denial->salt, policy->denial->salt_stamp, (unsigned long) policy->id);
623 #else
624  nchar = snprintf(buffer, sizeof(buffer),
625  "UPDATE policies SET salt = '%s', salt_stamp = DATETIME('%s') WHERE ID = %lu",
626  policy->denial->salt, policy->denial->salt_stamp, (unsigned long) policy->id);
627 #endif /* USE_MYSQL */
628  if (nchar < sizeof(buffer)) {
629  /* All OK, execute the statement */
630 
631  status = DbExecuteSqlNoResult(DbHandle(), buffer);
632  }
633  else {
634  /* Unable to create update statement */
635 
636  status = MsgLog(KME_BUFFEROVF, "KsmPolicy");
637  }
638 
639  StrFree(datetime_now);
640  return status;
641  }
642  } else {
643  MsgLog(KSM_INVARG, "Could not calculate DateDiff");
644  StrFree(datetime_now);
645  return -2;
646  }
647 
648  StrFree(datetime_now);
649  return status;
650 }
651 
652 /*+
653  * KsmPolicyNullSaltStamp
654  *
655  * Description:
656  * Given a policy id set its saltstamp to NULL, this will force a resalt on
657  * the next enforcer run, suitable for when salt length has changed for
658  * instance.
659  *
660  * Arguments:
661  * int policy_id
662  * policy to work on
663  *
664  * Returns:
665  * int
666  * Status return:
667  * 0 success
668  * non-zero some error occurred and a message has been output.
669  * -1 no policy found
670  *
671 -*/
672 
673 int KsmPolicyNullSaltStamp(int policy_id)
674 {
675  char buffer[KSM_SQL_SIZE]; /* update statement for salt_stamp */
676  unsigned int nchar; /* Number of characters converted */
677  int status = 0;
678 
679  /* check the argument */
680  if (policy_id < 1) {
681  MsgLog(KSM_INVARG, "Negative or zero policy_id");
682  return -1;
683  }
684 
685  nchar = snprintf(buffer, sizeof(buffer),
686  "UPDATE policies SET salt_stamp = NULL WHERE ID = %lu",
687  (unsigned long) policy_id);
688 
689  if (nchar < sizeof(buffer)) {
690  /* All OK, execute the statement */
691 
692  status = DbExecuteSqlNoResult(DbHandle(), buffer);
693  }
694  else {
695  /* Unable to create update statement */
696 
697  status = MsgLog(KME_BUFFEROVF, "KsmPolicy");
698  }
699 
700  return status;
701 }
702 
703 
704 /* Populate security module information for a structure that has the sm_id fields filled in */
705 
707 {
708  int where = 0; /* WHERE clause value */
709  char* sql = NULL; /* SQL query */
710  DB_RESULT result; /* Handle converted to a result object */
711  DB_ROW row = NULL; /* Row data */
712  DB_RESULT result2; /* Handle converted to a result object */
713  DB_ROW row2 = NULL; /* Row data */
714  int status = 0; /* Status return */
715 
716  /* check the argument */
717  if (policy == NULL) {
718  return MsgLog(KSM_INVARG, "NULL policy");
719  }
720 
721  /* Construct the query for ksk */
722 
724  DqsConditionInt(&sql, "id", DQS_COMPARE_EQ, policy->ksk->sm, where++);
725 
726  /* Execute query and free up the query string */
727  status = DbExecuteSql(DbHandle(), sql, &result);
728  DqsFree(sql);
729 
730  if (status != 0)
731  {
732  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
733  DbFreeResult(result);
734  return status;
735  }
736 
737  /* Get the next row from the data */
738  status = DbFetchRow(result, &row);
739  if (status == 0) {
740  DbStringBuffer(row, DB_SECURITY_MODULE_NAME, policy->ksk->sm_name, KSM_NAME_LENGTH*sizeof(char));
743  }
744  else if (status == -1) {}
745  /* No rows to return (but no error) */
746  else {
747  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
748  DbFreeResult(result);
749  DbFreeRow(row);
750  return status;
751  }
752 
753  DbFreeResult(result);
754  DbFreeRow(row);
755 
756 
757  /* Construct the query for zsk */
758  where = 0;
759 
761  DqsConditionInt(&sql, "id", DQS_COMPARE_EQ, policy->zsk->sm, where++);
762 
763  /* Execute query and free up the query string */
764  status = DbExecuteSql(DbHandle(), sql, &result2);
765  DqsFree(sql);
766 
767  if (status != 0)
768  {
769  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
770  DbFreeResult(result2);
771  return status;
772  }
773 
774  /* Get the next row from the data */
775  status = DbFetchRow(result2, &row2);
776  if (status == 0) {
777  DbStringBuffer(row2, DB_SECURITY_MODULE_NAME, policy->zsk->sm_name, KSM_NAME_LENGTH*sizeof(char));
780  }
781  else if (status == -1) {}
782  /* No rows to return (but no error) */
783  else {
784  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
785  }
786 
787  DbFreeRow(row2);
788  DbFreeResult(result2);
789  return status;
790 }
791 
792 /*+
793  * KsmPolicySetIdFromName - Given a policy with the name set, fill in the ID
794  *
795  *
796  * Arguments:
797  *
798  * Name of the parameter.
799  *
800  *
801  * Returns:
802  * int
803  * 0 Success, value found
804  * Other Error
805 -*/
806 
808 {
809  int status; /* Status return */
810  DB_RESULT result; /* Handle converted to a result object */
811  DB_ROW row = NULL; /* Row data */
812 
813  if (policy == NULL || policy->name[0] == '\0') {
814  return MsgLog(KSM_INVARG, "NULL policy or name");
815  }
816 
817  status = KsmPolicyInit(&result, policy->name);
818  if (status == 0) {
819  /* Get the next row from the data */
820  status = DbFetchRow(result, &row);
821  if (status == 0) {
822  DbInt(row, DB_POLICY_ID, &policy->id);
824  DbStringBuffer(row, 3, policy->denial->salt, KSM_SALT_LENGTH*sizeof(char));
825  }
826  else if (status == -1) {
827  /* No rows to return (but no error) */
828  }
829  else {
830  /* Error */
831  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
832  }
833 
834  }
835  DbFreeRow(row);
836  DbFreeResult(result);
837  return status;
838 }
839 
840 /*+
841  * KsmPolicyIdFromZoneId
842  *
843  * Arguments:
844  * int zone_id zone id
845  * int* policy_id returned id
846  *
847  * Returns:
848  * int
849  * Status return:
850  * 0 success
851  * -1 no record found
852  * non-zero some error occurred and a message has been output.
853  *
854  * If the status is non-zero, the returned data is meaningless.
855 -*/
856 int KsmPolicyIdFromZoneId(int zone_id, int* policy_id)
857 {
858  int where = 0; /* WHERE clause value */
859  char* sql = NULL; /* SQL query */
860  DB_RESULT result; /* Handle converted to a result object */
861  DB_ROW row = NULL; /* Row data */
862  int status = 0; /* Status return */
863 
864  /* check the argument */
865  if (zone_id == -1) {
866  return MsgLog(KSM_INVARG, "NULL zone name");
867  }
868 
869  /* Construct the query */
870 
871  sql = DqsSpecifyInit("zones","id, policy_id");
872  DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, zone_id, where++);
873  DqsOrderBy(&sql, "id");
874 
875  /* Execute query and free up the query string */
876  status = DbExecuteSql(DbHandle(), sql, &result);
877  DqsFree(sql);
878 
879  if (status != 0)
880  {
881  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
882  DbFreeResult(result);
883  return status;
884  }
885 
886  /* Get the next row from the data */
887  status = DbFetchRow(result, &row);
888  if (status == 0) {
889  DbInt(row, 1, policy_id);
890  }
891  else if (status == -1) {}
892  /* No rows to return (but no DB error) */
893  else {
894  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
895  }
896 
897  DbFreeRow(row);
898  DbFreeResult(result);
899  return status;
900 }
901 
902 /*+
903  * KsmPolicyUpdateDesc - Update a policy description
904  *
905  * Arguments:
906  *
907  * int policy_id
908  * id of the policy
909  *
910  * const char* policy_description
911  * Description for that policy
912  *
913  * Returns:
914  * int
915  * Status return. 0 on success.
916  * -1 if an unexpected count value was returned
917 -*/
918 
919 int KsmPolicyUpdateDesc(int policy_id, const char* policy_description)
920 {
921  char* sql = NULL; /* SQL query */
922  int status = 0; /* Status return */
923 
924  char quoted_desc[KSM_POLICY_DESC_LENGTH]; /* with bad chars quoted */
925  /* check the main argument (description may be NULL) */
926  if (policy_id <= 0) {
927  return MsgLog(KSM_INVARG, "NULL policy id");
928  }
929 
930  /* Quote description */
931  status = DbQuoteString(DbHandle(), policy_description, quoted_desc, KSM_POLICY_DESC_LENGTH);
932 
933  if (status != 0) {
934  return status;
935  }
936 
937  /* Update policy */
938  sql = DusInit("policies");
939  DusSetString(&sql, "description", quoted_desc, 0);
940  DusConditionInt(&sql, "id", DQS_COMPARE_EQ, policy_id, 0);
941  DusEnd(&sql);
942 
943  status = DbExecuteSqlNoResult(DbHandle(), sql);
944  DisFree(sql);
945 
946  return status;
947 }
948 
950 {
951  KSM_POLICY *policy;
952 
953  policy = (KSM_POLICY *)malloc(sizeof(KSM_POLICY));
954  if (policy == NULL) {
955  return NULL;
956  }
957 
958  policy->description = (char *)calloc(KSM_POLICY_DESC_LENGTH, sizeof(char));
959  policy->signer = (KSM_SIGNER_POLICY *)malloc(sizeof(KSM_SIGNER_POLICY));
960  policy->signature = (KSM_SIGNATURE_POLICY *)malloc(sizeof(KSM_SIGNATURE_POLICY));
961  policy->denial = (KSM_DENIAL_POLICY *)malloc(sizeof(KSM_DENIAL_POLICY));
962  policy->keys = (KSM_COMMON_KEY_POLICY *)malloc(sizeof(KSM_COMMON_KEY_POLICY));
963  policy->ksk = (KSM_KEY_POLICY *)malloc(sizeof(KSM_KEY_POLICY));
964  policy->zsk = (KSM_KEY_POLICY *)malloc(sizeof(KSM_KEY_POLICY));
965  policy->enforcer = (KSM_ENFORCER_POLICY *)malloc(sizeof(KSM_ENFORCER_POLICY));
966  policy->zone = (KSM_ZONE_POLICY *)malloc(sizeof(KSM_ZONE_POLICY));
967  policy->parent = (KSM_PARENT_POLICY *)malloc(sizeof(KSM_PARENT_POLICY));
968 
969  /* if allocation fails, return NULL*/
970  if (policy->description == NULL ||
971  policy->signer == NULL ||
972  policy->signature == NULL ||
973  policy->denial == NULL ||
974  policy->keys == NULL ||
975  policy->ksk == NULL ||
976  policy->zsk == NULL ||
977  policy->enforcer == NULL ||
978  policy->zone == NULL ||
979  policy->parent == NULL) {
980  KsmPolicyFree(policy);
981  return NULL;
982  }
983 
984  return policy;
985 }
986 
988 {
989  free(policy->description);
990  free(policy->signer);
991  free(policy->signature);
992  free(policy->denial);
993  free(policy->keys);
994  free(policy->ksk);
995  free(policy->zsk);
996  free(policy->enforcer);
997  free(policy->zone);
998  free(policy->parent);
999  free(policy);
1000 }
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:244
int KsmPolicyNameFromId(KSM_POLICY *policy)
Definition: ksm_policy.c:427
int KsmPolicySetIdFromName(KSM_POLICY *policy)
Definition: ksm_policy.c:807
unsigned long sm_capacity
Definition: ksm.h:211
KSM_POLICY * KsmPolicyAlloc()
Definition: ksm_policy.c:949
#define StrFree(x)
Definition: string_util.h:68
int overlap
Definition: ksm.h:213
#define KSM_INVARG
Definition: ksmdef.h:68
int rfc5011
Definition: ksm.h:215
int DbFetchRow(DB_RESULT result, DB_ROW *row)
#define KSM_SQLFAIL
Definition: ksmdef.h:69
#define DB_SECURITY_MODULE_NAME
Definition: db_fields.h:95
char category[KSM_NAME_LENGTH]
Definition: ksm.h:260
int serial
Definition: ksm.h:232
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
void KsmPolicyFree(KSM_POLICY *policy)
Definition: ksm_policy.c:987
int KsmPolicyUpdateDesc(int policy_id, const char *policy_description)
Definition: ksm_policy.c:919
int soa_min
Definition: ksm.h:231
KSM_COMMON_KEY_POLICY * keys
Definition: ksm.h:249
int soa_ttl
Definition: ksm.h:230
#define KSM_TIME_LENGTH
Definition: ksm.h:63
KSM_KEY_POLICY * zsk
Definition: ksm.h:251
int bits
Definition: ksm.h:207
void DqsConditionKeyword(char **query, const char *field, DQS_COMPARISON compare, const char *value, int index)
Definition: dq_string.c:253
int KsmPolicyReadFromId(KSM_POLICY *policy)
Definition: ksm_policy.c:414
int manual_rollover
Definition: ksm.h:218
void DqsOrderBy(char **query, const char *field)
Definition: dq_string.c:279
char sm_name[KSM_NAME_LENGTH]
Definition: ksm.h:210
int MsgLog(int status,...)
Definition: message.c:337
int shared_keys
Definition: ksm.h:255
#define DB_SECURITY_MODULE_REQUIREBACKUP
Definition: db_fields.h:97
void DqsFree(char *query)
Definition: dq_string.c:322
int KsmPolicyUpdateSalt(KSM_POLICY *policy)
Definition: ksm_policy.c:495
#define DB_POLICY_PARAMETER_CATEGORY
Definition: db_fields.h:89
int algorithm
Definition: ksm.h:206
void DusConditionInt(char **query, const char *field, DQS_COMPARISON compare, int value, int clause)
Definition: du_string.c:172
#define KSM_NAME_LENGTH
Definition: ksm.h:59
int KsmPolicyRead(KSM_POLICY *policy)
Definition: ksm_policy.c:232
DB_HANDLE DbHandle(void)
char salt_stamp[KSM_TIME_LENGTH]
Definition: ksm.h:194
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:226
int keygeninterval
Definition: ksm.h:225
char salt[KSM_SALT_LENGTH]
Definition: ksm.h:193
int saltlength
Definition: ksm.h:192
int DbQuoteString(DB_HANDLE handle, const char *in, char *buffer, size_t buflen)
char * DtParseDateTimeString(const char *string)
Definition: datetime.c:617
KSM_PARENT_POLICY * parent
Definition: ksm.h:254
KSM_DENIAL_POLICY * denial
Definition: ksm.h:248
void StrStrncpy(char *dest, const char *src, size_t destlen)
Definition: string_util.c:178
KSM_KEY_POLICY * ksk
Definition: ksm.h:250
int KsmPolicyParameter(DB_RESULT result, KSM_POLICY_PARAMETER *data)
Definition: ksm_policy.c:366
KSM_ZONE_POLICY * zone
Definition: ksm.h:253
int propdelay
Definition: ksm.h:229
const char * DbErrmsg(DB_HANDLE handle)
void DbFreeRow(DB_ROW row)
KSM_SIGNER_POLICY * signer
Definition: ksm.h:246
int standby_keys
Definition: ksm.h:217
#define DB_POLICY_ID
Definition: db_fields.h:111
#define KSM_SALT_LENGTH
Definition: ksm.h:67
#define DB_POLICY_SALT
Definition: db_fields.h:114
int DbExecuteSql(DB_HANDLE handle, const char *stmt_str, DB_RESULT *result)
#define KSM_SQL_SIZE
Definition: ksm.h:65
#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:236
char * description
Definition: ksm.h:245
void DusEnd(char **sql)
Definition: du_string.c:204
int propdelay
Definition: ksm.h:172
#define DB_POLICY_PARAMETER_VALUE
Definition: db_fields.h:90
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:62
#define DB_SECURITY_MODULE_CAPACITY
Definition: db_fields.h:96
void KsmParameterEnd(DB_RESULT result)
void DisFree(char *sql)
Definition: di_string.c:193
int sm
Definition: ksm.h:209
char name[KSM_NAME_LENGTH]
Definition: ksm.h:259
#define DB_POLICY_SALT_STAMP
Definition: db_fields.h:115
int KsmPolicyIdFromZoneId(int zone_id, int *policy_id)
Definition: ksm_policy.c:856
#define DB_POLICY_DESCRIPTION
Definition: db_fields.h:113
#define KME_BUFFEROVF
Definition: kmedef.h:50
int id
Definition: ksm.h:243
int ttl
Definition: ksm.h:214
int require_backup
Definition: ksm.h:212
KSM_ENFORCER_POLICY * enforcer
Definition: ksm.h:252
int DbInt(DB_ROW row, int field_index, int *value)
int KsmPolicyNullSaltStamp(int policy_id)
Definition: ksm_policy.c:673
int KsmPolicyExists(const char *name)
Definition: ksm_policy.c:151
int algorithm
Definition: ksm.h:188
int rollover_scheme
Definition: ksm.h:219
int lifetime
Definition: ksm.h:208
int iteration
Definition: ksm.h:189
void DusSetString(char **sql, const char *field, const char *data, int clause)
Definition: du_string.c:115
int DtDateDiff(const char *date1, const char *date2, int *result)
Definition: datetime.c:828
int DbExecuteSqlNoResult(DB_HANDLE handle, const char *stmt_str)
int KsmPolicyPopulateSMFromIds(KSM_POLICY *policy)
Definition: ksm_policy.c:706
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:112
KSM_SIGNATURE_POLICY * signature
Definition: ksm.h:247