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