OpenDNSSEC-enforcer  1.3.15
ksm_policy.c
Go to the documentation of this file.
1 /*
2  * $Id: ksm_policy.c 4169 2010-11-04 14:24:23Z 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, audit, salt");
78  if (name) {
79  DqsConditionString(&sql, "NAME", DQS_COMPARE_EQ, name, where++);
80  }
81  DqsOrderBy(&sql, "id");
82 
83  /* Execute query and free up the query string */
84 
85  status = DbExecuteSql(DbHandle(), sql, result);
86 
87  DqsFree(sql);
88 
89  return status;
90 }
91 
92 /*+
93  * KsmPolicyParametersInit - Query for Policy Information
94  *
95  *
96  * Arguments:
97  * DB_RESULT* result
98  * Pointer to a handle to be used for information retrieval. Will
99  * be NULL on error.
100  *
101  * const char* name
102  * Name of the parameter to retrieve information on. If NULL, information
103  * on all parameters is retrieved.
104  *
105  * Returns:
106  * int
107  * Status return. 0 on success.
108 -*/
109 
110 int KsmPolicyParametersInit(DB_RESULT* result, const char* name)
111 {
112  int where = 0; /* WHERE clause value */
113  char* sql = NULL; /* SQL query */
114  int status = 0; /* Status return */
115 
116  /* Construct the query */
117 
118  sql = DqsSpecifyInit("policies p, parameters_policies x, parameters y, categories c ","y.name, c.name, x.value");
119  DqsConditionKeyword(&sql, "p.id", DQS_COMPARE_EQ, "x.policy_id", where++);
120  DqsConditionKeyword(&sql, "y.id", DQS_COMPARE_EQ, "x.parameter_id", where++);
121  DqsConditionKeyword(&sql, "c.id", DQS_COMPARE_EQ, "y.category_id", where++);
122  if (name) {
123  DqsConditionString(&sql, "p.NAME", DQS_COMPARE_EQ, name, where++);
124  }
125  DqsOrderBy(&sql, "p.NAME");
126 
127  /* Execute query and free up the query string */
128 
129  status = DbExecuteSql(DbHandle(), sql, result);
130 
131  DqsFree(sql);
132 
133  return status;
134 }
135 
136 /*+
137  * KsmPolicyExists - Check Policy Exists
138  *
139  *
140  * Arguments:
141  * const char* name
142  * Name of the parameter.
143  *
144  *
145  * Returns:
146  * int
147  * 0 Success, value found
148  * Other Error, message has been output
149 -*/
150 
151 int KsmPolicyExists(const char* name)
152 {
153  int status; /* Status return */
154  DB_RESULT result; /* Handle converted to a result object */
155  DB_ROW row = NULL; /* Row data */
156 
157  status = KsmPolicyInit(&result, name);
158  if (status == 0) {
159  /* Get the next row from the data */
160  status = DbFetchRow(result, &row);
161  if (status > 0) {
162  /* Error */
163  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
164  }
165  }
166  DbFreeRow(row);
167  DbFreeResult(result);
168  return status;
169 }
170 
171 /*+
172  * KsmPolicy - Return Policy Information
173  *
174  * Arguments:
175  * DB_RESULT result
176  * Handle from KsmParameterInit
177  *
178  * KSM_PARAMETER* data
179  * Data is returned in here.
180  *
181  * Returns:
182  * int
183  * Status return:
184  * 0 success
185  * -1 end of record set reached
186  * non-zero some error occurred and a message has been output.
187  *
188  * If the status is non-zero, the returned data is meaningless.
189 -*/
190 
191 int KsmPolicy(DB_RESULT result, KSM_POLICY* data)
192 {
193  int status = 0; /* Return status */
194  DB_ROW row = NULL; /* Row data */
195 
196  /* check the argument */
197  if (data == NULL) {
198  return MsgLog(KSM_INVARG, "NULL data");
199  }
200 
201  /* Get the next row from the data */
202  status = DbFetchRow(result, &row);
203  if (status == 0) {
204 
205  status = DbInt(row, DB_POLICY_ID, &(data->id));
206  DbStringBuffer(row, DB_POLICY_NAME, data->name, KSM_NAME_LENGTH*sizeof(char));
207  }
208  else if (status == -1) {}
209  /* No rows to return (but no error) */
210  else {
211  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
212  }
213 
214  if (row != NULL) {
215  DbFreeRow(row);
216  }
217 
218  return status;
219 }
220 
221 /*+
222  * KsmPolicyRead - Read Policy
223  *
224  * Description:
225  * Read policy from database in to a struct.
226  *
227  * Arguments:
228  * struct policy_t policy
229  * struct to hold policy information, it needs to have the policy name set
230 -*/
231 
233 {
234  KSM_POLICY_PARAMETER data; /* Parameter information */
235  DB_RESULT result; /* Handle to parameter */
236  int status = 0; /* Status return */
237 
238  /* check the argument */
239  if (policy == NULL) {
240  return MsgLog(KSM_INVARG, "NULL policy");
241  }
242 
243  /* status = KsmPolicyExists(policy->name); */
244  status = KsmPolicySetIdFromName(policy);
245 
246  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  /* if (strncmp(data.category, "audit", 5) == 0) {
321  if (strncmp(data.name, "audit",5) == 0) policy->audit->audit=data.value;
322  }*/
323  /* Ignore any unknown parameters */
324 
325  status = KsmPolicyParameter(result, &data);
326  }
327 
328  /* All done, so tidy up */
329 
330  KsmParameterEnd(result);
331  }
332  } else {
333  return status;
334  }
335 
336  /* convert security module ids into names, capacities and requirebackup flags */
337  status = KsmPolicyPopulateSMFromIds(policy);
338 
339  return status;
340 }
341 
342 /*+
343  * KsmPolicyParameter - Return PolicyParameter Information
344  *
345  * Description:
346  * Returns information about the next key in the result set.
347  *
348  * Arguments:
349  * DB_RESULT result
350  * Handle from KsmParameterInit
351  *
352  * KSM_PARAMETER* data
353  * Data is returned in here.
354  *
355  * Returns:
356  * int
357  * Status return:
358  * 0 success
359  * -1 end of record set reached
360  * non-zero some error occurred and a message has been output.
361  *
362  * If the status is non-zero, the returned data is meaningless.
363 -*/
364 
366 {
367  int status = 0; /* Return status */
368  DB_ROW row = NULL; /* Row data */
369 
370  /* check the argument */
371  if (data == NULL) {
372  return MsgLog(KSM_INVARG, "NULL data");
373  }
374 
375  /* Get the next row from the data */
376  status = DbFetchRow(result, &row);
377 
378  if (status == 0) {
379 
380  /* Now copy the results into the output data */
381 
382  memset(data, 0, sizeof(KSM_POLICY_PARAMETER));
384  sizeof(data->name));
386  sizeof(data->category));
387  status = DbInt(row, DB_POLICY_PARAMETER_VALUE, &(data->value));
388  }
389  else if (status == -1) {}
390  /* No rows to return (but no error) */
391  else {
392  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
393  }
394 
395  if (row != NULL) {
396  DbFreeRow(row);
397  }
398 
399  return status;
400 }
401 
402 /*+
403  * KsmPolicyReadFromId - Read Policy given just the id
404  *
405  * Description:
406  * Read policy from database in to a struct.
407  *
408  * Arguments:
409  * struct policy_t policy
410  * struct to hold policy information should have id populated
411 -*/
412 
414 {
415  int status = KsmPolicyNameFromId(policy);
416 
417  if (status != 0)
418  {
419  return status;
420  }
421 
422  return KsmPolicyRead(policy);
423 
424 }
425 
427 {
428  int where = 0; /* WHERE clause value */
429  char* sql = NULL; /* SQL query */
430  DB_RESULT result; /* Handle converted to a result object */
431  DB_ROW row = NULL; /* Row data */
432  int status = 0; /* Status return */
433 
434  /* check the argument */
435  if (policy == NULL) {
436  return MsgLog(KSM_INVARG, "NULL policy");
437  }
438 
439  /* Construct the query */
440 
441  sql = DqsSpecifyInit("policies","id, name");
442  DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, policy->id, where++);
443  DqsOrderBy(&sql, "id");
444 
445  /* Execute query and free up the query string */
446  status = DbExecuteSql(DbHandle(), sql, &result);
447  DqsFree(sql);
448 
449  if (status != 0)
450  {
451  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
452  DbFreeResult(result);
453  return status;
454  }
455 
456  /* Get the next row from the data */
457  status = DbFetchRow(result, &row);
458  if (status == 0) {
459  DbStringBuffer(row, DB_POLICY_NAME, policy->name, KSM_NAME_LENGTH*sizeof(char));
460  }
461  else if (status == -1) {}
462  /* No rows to return (but no error) */
463  else {
464  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
465  }
466 
467  DbFreeRow(row);
468  DbFreeResult(result);
469  return status;
470 }
471 
472 /*+
473  * KsmPolicyUpdateSalt
474  *
475  * Description:
476  * Given a policy see if the salt needs updating (based on denial->resalt).
477  * If it is out of date then generate a new salt and write it to the struct.
478  * Also update the database with the new value and timestamp.
479  *
480  * Arguments:
481  * struct policy_t policy
482  * struct which holds the current policy information should have been populated
483  *
484  * Returns:
485  * int
486  * Status return:
487  * 0 success
488  * non-zero some error occurred and a message has been output.
489  * -1 no policy found
490  * -2 an error working out time difference between stamp and now
491  *
492 -*/
493 
495 {
496  /* First work out what the current salt is and when it was created */
497  int where = 0; /* WHERE clause value */
498  char* sql = NULL; /* SQL query */
499  DB_RESULT result; /* Handle converted to a result object */
500  DB_ROW row = NULL; /* Row data */
501  int status = 0; /* Status return */
502  char* datetime_now = DtParseDateTimeString("now"); /* where are we in time */
503  int time_diff; /* how many second have elapsed */
504  char* salt; /* This will be the salt that we create */
505  char buffer[KSM_SQL_SIZE]; /* update statement for salt_stamp */
506  unsigned int nchar; /* Number of characters converted */
507  int i = 0; /* a counter */
508  char* hex_chars = "0123456789abcdef"; /* for "manual" random string */
509 
510  /* check the argument */
511  if (policy == NULL) {
512  MsgLog(KSM_INVARG, "NULL policy");
513  StrFree(datetime_now);
514  return -1;
515  }
516 
517  /* Check datetime in case it came back NULL */
518  if (datetime_now == NULL) {
519  printf("Couldn't turn \"now\" into a date, quitting...\n");
520  exit(1);
521  }
522 
523  /* Construct the query */
524 
525  sql = DqsSpecifyInit("policies","id, salt, salt_stamp");
526  DqsConditionInt(&sql, "ID", DQS_COMPARE_EQ, policy->id, where++);
527  DqsOrderBy(&sql, "id");
528 
529  /* Execute query and free up the query string */
530  status = DbExecuteSql(DbHandle(), sql, &result);
531  DqsFree(sql);
532 
533  if (status != 0)
534  {
535  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
536  StrFree(datetime_now);
537  return status;
538  }
539 
540  /* Get the next row from the data */
541  status = DbFetchRow(result, &row);
542  if (status == 0) {
543  status = DbStringBuffer(row, DB_POLICY_SALT, policy->denial->salt, KSM_SALT_LENGTH*sizeof(char));
544  if (status == 0) {
545  status = DbStringBuffer(row, DB_POLICY_SALT_STAMP, policy->denial->salt_stamp, KSM_TIME_LENGTH*sizeof(char));
546  }
547 
548  if (status != 0) {
549  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
550  DbFreeResult(result);
551  DbFreeRow(row);
552  StrFree(datetime_now);
553  return status;
554  }
555  }
556  else if (status == -1) {
557  /* No rows to return (but no error), policy_id doesn't exist? */
558  DbFreeResult(result);
559  DbFreeRow(row);
560  StrFree(datetime_now);
561  return -1;
562  }
563  else {
564  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
565 
566  DbFreeResult(result);
567  DbFreeRow(row);
568  StrFree(datetime_now);
569  return status;
570  }
571 
572  DbFreeResult(result);
573  DbFreeRow(row);
574 
575  /* Now see if this needs to be updated; if the stamp is null then assume it does */
576  if (policy->denial->salt_stamp[0] == '\0') {
577  time_diff = -1;
578  } else {
579  status = DtDateDiff(datetime_now, policy->denial->salt_stamp, &time_diff);
580  }
581 
582  if (status == 0) {
583  if (policy->denial->resalt > time_diff && time_diff != -1 && policy->denial->salt[0] != '\0') {
584  /* current salt is fine */
585  StrFree(datetime_now);
586  return status;
587  } else {
588  /* salt needs updating, or is null */
589  salt = (char *)calloc(KSM_SALT_LENGTH, sizeof(char));
590  if (salt == NULL) {
591  MsgLog(KSM_INVARG, "Could not allocate memory for salt");
592  StrFree(datetime_now);
593  exit(1);
594  }
595 
596 #ifdef HAVE_ARC4RANDOM
597  for (i = 0; i < 2*(policy->denial->saltlength); i++) {
598  salt[i] = hex_chars[arc4random()%strlen(hex_chars)];
599  }
600 #else
601  srand( time(NULL) );
602  for (i = 0; i < 2*(policy->denial->saltlength); i++) {
603  salt[i] = hex_chars[rand()%strlen(hex_chars)];
604  }
605 #endif
606 
607  if (status != 0) {
608  StrFree(datetime_now);
609  StrFree(salt);
610  return status;
611  }
612  StrStrncpy(policy->denial->salt, salt, KSM_SALT_LENGTH);
613  StrStrncpy(policy->denial->salt_stamp, datetime_now, KSM_TIME_LENGTH);
614 
615  StrFree(salt);
616 
617  /* write these back to the database */
618 #ifdef USE_MYSQL
619  nchar = snprintf(buffer, sizeof(buffer),
620  "UPDATE policies SET salt = '%s', salt_stamp = \"%s\" WHERE ID = %lu",
621  policy->denial->salt, policy->denial->salt_stamp, (unsigned long) policy->id);
622 #else
623  nchar = snprintf(buffer, sizeof(buffer),
624  "UPDATE policies SET salt = '%s', salt_stamp = DATETIME('%s') WHERE ID = %lu",
625  policy->denial->salt, policy->denial->salt_stamp, (unsigned long) policy->id);
626 #endif /* USE_MYSQL */
627  if (nchar < sizeof(buffer)) {
628  /* All OK, execute the statement */
629 
630  status = DbExecuteSqlNoResult(DbHandle(), buffer);
631  }
632  else {
633  /* Unable to create update statement */
634 
635  status = MsgLog(KME_BUFFEROVF, "KsmPolicy");
636  }
637 
638  StrFree(datetime_now);
639  return status;
640  }
641  } else {
642  MsgLog(KSM_INVARG, "Could not calculate DateDiff");
643  StrFree(datetime_now);
644  return -2;
645  }
646 
647  StrFree(datetime_now);
648  return status;
649 }
650 
651 /*+
652  * KsmPolicyNullSaltStamp
653  *
654  * Description:
655  * Given a policy id set its saltstamp to NULL, this will force a resalt on
656  * the next enforcer run, suitable for when salt length has changed for
657  * instance.
658  *
659  * Arguments:
660  * int policy_id
661  * policy to work on
662  *
663  * Returns:
664  * int
665  * Status return:
666  * 0 success
667  * non-zero some error occurred and a message has been output.
668  * -1 no policy found
669  *
670 -*/
671 
672 int KsmPolicyNullSaltStamp(int policy_id)
673 {
674  char buffer[KSM_SQL_SIZE]; /* update statement for salt_stamp */
675  unsigned int nchar; /* Number of characters converted */
676  int status = 0;
677 
678  /* check the argument */
679  if (policy_id < 1) {
680  MsgLog(KSM_INVARG, "Negative or zero policy_id");
681  return -1;
682  }
683 
684  nchar = snprintf(buffer, sizeof(buffer),
685  "UPDATE policies SET salt_stamp = NULL WHERE ID = %lu",
686  (unsigned long) policy_id);
687 
688  if (nchar < sizeof(buffer)) {
689  /* All OK, execute the statement */
690 
691  status = DbExecuteSqlNoResult(DbHandle(), buffer);
692  }
693  else {
694  /* Unable to create update statement */
695 
696  status = MsgLog(KME_BUFFEROVF, "KsmPolicy");
697  }
698 
699  return status;
700 }
701 
702 
703 /* Populate security module information for a structure that has the sm_id fields filled in */
704 
706 {
707  int where = 0; /* WHERE clause value */
708  char* sql = NULL; /* SQL query */
709  DB_RESULT result; /* Handle converted to a result object */
710  DB_ROW row = NULL; /* Row data */
711  DB_RESULT result2; /* Handle converted to a result object */
712  DB_ROW row2 = NULL; /* Row data */
713  int status = 0; /* Status return */
714 
715  /* check the argument */
716  if (policy == NULL) {
717  return MsgLog(KSM_INVARG, "NULL policy");
718  }
719 
720  /* Construct the query for ksk */
721 
723  DqsConditionInt(&sql, "id", DQS_COMPARE_EQ, policy->ksk->sm, where++);
724 
725  /* Execute query and free up the query string */
726  status = DbExecuteSql(DbHandle(), sql, &result);
727  DqsFree(sql);
728 
729  if (status != 0)
730  {
731  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
732  DbFreeResult(result);
733  return status;
734  }
735 
736  /* Get the next row from the data */
737  status = DbFetchRow(result, &row);
738  if (status == 0) {
739  DbStringBuffer(row, DB_SECURITY_MODULE_NAME, policy->ksk->sm_name, KSM_NAME_LENGTH*sizeof(char));
742  }
743  else if (status == -1) {}
744  /* No rows to return (but no error) */
745  else {
746  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
747  DbFreeResult(result);
748  DbFreeRow(row);
749  return status;
750  }
751 
752  DbFreeResult(result);
753  DbFreeRow(row);
754 
755 
756  /* Construct the query for zsk */
757  where = 0;
758 
760  DqsConditionInt(&sql, "id", DQS_COMPARE_EQ, policy->zsk->sm, where++);
761 
762  /* Execute query and free up the query string */
763  status = DbExecuteSql(DbHandle(), sql, &result2);
764  DqsFree(sql);
765 
766  if (status != 0)
767  {
768  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
769  DbFreeResult(result2);
770  return status;
771  }
772 
773  /* Get the next row from the data */
774  status = DbFetchRow(result2, &row2);
775  if (status == 0) {
776  DbStringBuffer(row2, DB_SECURITY_MODULE_NAME, policy->zsk->sm_name, KSM_NAME_LENGTH*sizeof(char));
779  }
780  else if (status == -1) {}
781  /* No rows to return (but no error) */
782  else {
783  status = MsgLog(KSM_SQLFAIL, DbErrmsg(DbHandle()));
784  }
785 
786  DbFreeRow(row2);
787  DbFreeResult(result2);
788  return status;
789 }
790 
791 /*+
792  * KsmPolicySetIdFromName - Given a policy with the name set, fill in the ID
793  *
794  *
795  * Arguments:
796  *
797  * Name of the parameter.
798  *
799  *
800  * Returns:
801  * int
802  * 0 Success, value found
803  * Other Error
804 -*/
805 
807 {
808  int status; /* Status return */
809  DB_RESULT result; /* Handle converted to a result object */
810  DB_ROW row = NULL; /* Row data */
811 
812  if (policy == NULL || policy->name[0] == '\0') {
813  return MsgLog(KSM_INVARG, "NULL policy or name");
814  }
815 
816  status = KsmPolicyInit(&result, policy->name);
817  if (status == 0) {
818  /* Get the next row from the data */
819  status = DbFetchRow(result, &row);
820  if (status == 0) {
821  DbInt(row, DB_POLICY_ID, &policy->id);
823  DbStringBuffer(row, DB_POLICY_AUDIT, policy->audit, KSM_POLICY_AUDIT_LENGTH*sizeof(char));
824  DbStringBuffer(row, 4, 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 
903 {
904  KSM_POLICY *policy;
905 
906  policy = (KSM_POLICY *)malloc(sizeof(KSM_POLICY));
907  policy->description = (char *)calloc(KSM_POLICY_DESC_LENGTH, sizeof(char));
908  policy->signer = (KSM_SIGNER_POLICY *)malloc(sizeof(KSM_SIGNER_POLICY));
909  policy->signature = (KSM_SIGNATURE_POLICY *)malloc(sizeof(KSM_SIGNATURE_POLICY));
910  policy->denial = (KSM_DENIAL_POLICY *)malloc(sizeof(KSM_DENIAL_POLICY));
911  policy->keys = (KSM_COMMON_KEY_POLICY *)malloc(sizeof(KSM_COMMON_KEY_POLICY));
912  policy->ksk = (KSM_KEY_POLICY *)malloc(sizeof(KSM_KEY_POLICY));
913  policy->zsk = (KSM_KEY_POLICY *)malloc(sizeof(KSM_KEY_POLICY));
914  policy->enforcer = (KSM_ENFORCER_POLICY *)malloc(sizeof(KSM_ENFORCER_POLICY));
915  policy->zone = (KSM_ZONE_POLICY *)malloc(sizeof(KSM_ZONE_POLICY));
916  policy->parent = (KSM_PARENT_POLICY *)malloc(sizeof(KSM_PARENT_POLICY));
917  /* policy->audit = (KSM_AUDIT_POLICY *)malloc(sizeof(KSM_AUDIT_POLICY)); */
918  policy->audit = (char *)calloc(KSM_POLICY_AUDIT_LENGTH, sizeof(char));
919 
920  /* if allocation fails, return NULL*/
921  if (policy->description == NULL ||
922  policy->signer == NULL ||
923  policy->signature == NULL ||
924  policy->denial == NULL ||
925  policy->keys == NULL ||
926  policy->ksk == NULL ||
927  policy->zsk == NULL ||
928  policy->enforcer == NULL ||
929  policy->zone == NULL ||
930  policy->parent == NULL ||
931  policy->audit == NULL) {
932  KsmPolicyFree(policy);
933  return NULL;
934  }
935 
936  return policy;
937 }
938 
940 {
941  free(policy->description);
942  free(policy->signer);
943  free(policy->signature);
944  free(policy->denial);
945  free(policy->keys);
946  free(policy->ksk);
947  free(policy->zsk);
948  free(policy->enforcer);
949  free(policy->zone);
950  free(policy->parent);
951  free(policy->audit);
952  free(policy);
953 }