Print this page
6414175 kcf.conf's supportedlist not providing much usefulness

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef_util.c
          +++ new/usr/src/cmd/cmd-crypto/cryptoadm/adm_kef_util.c
↓ open down ↓ 24 lines elided ↑ open up ↑
  25   25  
  26   26  #include <errno.h>
  27   27  #include <fcntl.h>
  28   28  #include <stdio.h>
  29   29  #include <stdlib.h>
  30   30  #include <strings.h>
  31   31  #include <time.h>
  32   32  #include <unistd.h>
  33   33  #include <locale.h>
  34   34  #include <sys/types.h>
       35 +#include <zone.h>
  35   36  #include <sys/stat.h>
  36   37  #include "cryptoadm.h"
  37   38  
  38   39  static int err; /* To store errno which may be overwritten by gettext() */
  39   40  static int build_entrylist(entry_t *, entrylist_t **);
  40   41  static entry_t *dup_entry(entry_t *);
  41   42  static mechlist_t *dup_mechlist(mechlist_t *);
  42   43  static entry_t *getent(char *, entrylist_t *);
  43   44  static int interpret(char *, entry_t **);
  44      -static int parse_dislist(char *, entry_t *);
       45 +static int parse_sup_dis_list(char *, entry_t *);
  45   46  
  46   47  
  47   48  /*
  48   49   * Duplicate the mechanism list.  A null pointer is returned if the storage
  49   50   * space available is insufficient or the input argument is NULL.
  50   51   */
  51   52  static mechlist_t *
  52   53  dup_mechlist(mechlist_t *plist)
  53   54  {
  54      -        mechlist_t *pres = NULL;
  55      -        mechlist_t *pcur;
  56      -        mechlist_t *ptmp;
  57      -        int rc = SUCCESS;
       55 +        mechlist_t      *pres = NULL;
       56 +        mechlist_t      *pcur;
       57 +        mechlist_t      *ptmp;
       58 +        int             rc = SUCCESS;
  58   59  
  59   60          while (plist != NULL) {
  60   61                  if (!(ptmp = create_mech(plist->name))) {
  61   62                          rc = FAILURE;
  62   63                          break;
  63   64                  }
  64   65  
  65   66                  if (pres == NULL) {
  66   67                          pres = pcur = ptmp;
  67   68                  } else {
↓ open down ↓ 20 lines elided ↑ open up ↑
  88   89  {
  89   90          int count = 0;
  90   91  
  91   92          while (plist != NULL) {
  92   93                  count++;
  93   94                  plist = plist->next;
  94   95          }
  95   96          return (count);
  96   97  }
  97   98  
       99 +/*
      100 + * Create one item of type entry_t with the provider name.
      101 + * Return NULL if there's not enough memory or provname is NULL.
      102 + */
      103 +entry_t *
      104 +create_entry(char *provname)
      105 +{
      106 +        entry_t         *pent = NULL;
  98  107  
      108 +        if (provname == NULL) {
      109 +                return (NULL);
      110 +        }
      111 +
      112 +        pent = calloc(1, sizeof (entry_t));
      113 +        if (pent == NULL) {
      114 +                cryptodebug("out of memory.");
      115 +                return (NULL);
      116 +        }
      117 +
      118 +        (void) strlcpy(pent->name, provname, MAXNAMELEN);
      119 +        pent->suplist = NULL;
      120 +        pent->sup_count = 0;
      121 +        pent->dislist = NULL;
      122 +        pent->dis_count = 0;
      123 +        pent->load = B_TRUE;
      124 +
      125 +        return (pent);
      126 +}
      127 +
  99  128  /*
 100      - * Duplicate an entry.  A null pointer is returned if the storage space
 101      - * available is insufficient or the input argument is NULL.
      129 + * Duplicate an entry for a provider from kcf.conf.
      130 + * Return NULL if memory is insufficient or the input argument is NULL.
      131 + * Called by getent().
 102  132   */
 103  133  static entry_t *
 104  134  dup_entry(entry_t *pent1)
 105  135  {
 106  136          entry_t *pent2 = NULL;
 107  137  
 108  138          if (pent1 == NULL) {
 109  139                  return (NULL);
 110  140          }
 111  141  
 112      -        if ((pent2 = malloc(sizeof (entry_t))) == NULL) {
      142 +        if ((pent2 = create_entry(pent1->name)) == NULL) {
 113  143                  cryptodebug("out of memory.");
 114  144                  return (NULL);
 115  145          }
 116  146  
 117      -        (void) strlcpy(pent2->name, pent1->name, sizeof (pent2->name));
 118  147          pent2->sup_count = pent1->sup_count;
 119  148          pent2->dis_count = pent1->dis_count;
 120      -        pent2->suplist = NULL;
 121      -        pent2->dislist = NULL;
      149 +        pent2->load = pent1->load;
 122  150          if (pent1->suplist != NULL) {
 123  151                  pent2->suplist = dup_mechlist(pent1->suplist);
 124  152                  if (pent2->suplist == NULL) {
 125  153                          free_entry(pent2);
 126  154                          return (NULL);
 127  155                  }
 128  156          }
 129  157          if (pent1->dislist != NULL) {
 130  158                  pent2->dislist = dup_mechlist(pent1->dislist);
 131  159                  if (pent2->dislist == NULL) {
↓ open down ↓ 4 lines elided ↑ open up ↑
 136  164  
 137  165          return (pent2);
 138  166  }
 139  167  
 140  168  
 141  169  /*
 142  170   * This routine parses the disabledlist or the supportedlist of an entry
 143  171   * in the kcf.conf configuration file.
 144  172   *
 145  173   * Arguments:
 146      - *      buf: an input argument which is a char string with the format of
      174 + *      buf: an input argument which is a char string with the format of
 147  175   *           "disabledlist=m1,m2,..." or "supportedlist=m1,m2,..."
 148  176   *      pent: the entry for the disabledlist.  This is an IN/OUT argument.
 149  177   *
 150  178   * Return value: SUCCESS or FAILURE.
 151  179   */
 152  180  static int
 153      -parse_dislist(char *buf, entry_t *pent)
      181 +parse_sup_dis_list(char *buf, entry_t *pent)
 154  182  {
 155      -        mechlist_t *pmech;
 156      -        mechlist_t *phead;
 157      -        char *next_token;
 158      -        char *value;
 159      -        int count;
 160      -        int supflag = B_FALSE;
 161      -        int disflag = B_FALSE;
 162      -        int rc = SUCCESS;
      183 +        mechlist_t      *pmech = NULL;
      184 +        mechlist_t      *phead = NULL;
      185 +        char            *next_token;
      186 +        char            *value;
      187 +        int             count;
      188 +        int             supflag = B_FALSE;
      189 +        int             disflag = B_FALSE;
      190 +        int             rc = SUCCESS;
 163  191  
 164  192          if (strncmp(buf, EF_SUPPORTED, strlen(EF_SUPPORTED)) == 0) {
 165  193                  supflag = B_TRUE;
 166  194          } else if (strncmp(buf, EF_DISABLED, strlen(EF_DISABLED)) == 0) {
 167  195                  disflag = B_TRUE;
 168  196          } else {
 169  197                  /* should not come here */
 170  198                  return (FAILURE);
 171  199          }
 172  200  
↓ open down ↓ 39 lines elided ↑ open up ↑
 212  240                          pent->dis_count = count;
 213  241                  }
 214  242          } else {
 215  243                  free_mechlist(phead);
 216  244          }
 217  245  
 218  246          return (rc);
 219  247  }
 220  248  
 221  249  
 222      -
 223  250  /*
 224      - * This routine converts a char string into an entry_t structure
      251 + * Convert a char string containing a line about a provider
      252 + * from kcf.conf into an entry_t structure.
      253 + *
      254 + * See ent2str(), the reverse of this function, for the format of
      255 + * kcf.conf lines.
 225  256   */
 226  257  static int
 227  258  interpret(char *buf, entry_t **ppent)
 228  259  {
 229      -        entry_t *pent;
 230      -        char *token1;
 231      -        char *token2;
 232      -        char *token3;
 233      -        int rc;
      260 +        entry_t *pent = NULL;
      261 +        char    *token1;
      262 +        char    *token2;
      263 +        char    *token3;
      264 +        int     rc;
 234  265  
      266 +        /* Get provider name */
 235  267          if ((token1 = strtok(buf, SEP_COLON)) == NULL) { /* buf is NULL */
 236  268                  return (FAILURE);
 237  269          };
 238  270  
 239      -        pent = malloc(sizeof (entry_t));
      271 +        pent = create_entry(token1);
 240  272          if (pent == NULL) {
 241  273                  cryptodebug("out of memory.");
 242  274                  return (FAILURE);
 243  275          }
 244      -        (void) strlcpy(pent->name, token1, sizeof (pent->name));
 245      -        pent->suplist = NULL;
 246      -        pent->dislist = NULL;
 247      -        pent->sup_count = 0;
 248      -        pent->dis_count = 0;
 249  276  
 250  277          if ((token2 = strtok(NULL, SEP_SEMICOLON)) == NULL) {
 251  278                  /* The entry contains a provider name only */
 252  279                  free_entry(pent);
 253  280                  return (FAILURE);
 254  281          }
 255  282  
      283 +        if (strncmp(token2, EF_UNLOAD, strlen(EF_UNLOAD)) == 0) {
      284 +                pent->load = B_FALSE; /* cryptoadm unload */
      285 +                if ((token2 = strtok(NULL, SEP_SEMICOLON)) == NULL) {
      286 +                        /* The entry contains a provider name:unload only */
      287 +                        free_entry(pent);
      288 +                        return (FAILURE);
      289 +                }
      290 +        }
      291 +
 256  292          /* need to get token3 first to satisfy nested strtok invocations */
 257      -        token3 = strtok(NULL, SEP_SEMICOLON);
      293 +        token3 = strtok(NULL, SEP_SEMICOLON); /* optional */
 258  294  
 259      -        if (token2 && ((rc = parse_dislist(token2, pent)) != SUCCESS)) {
      295 +        /* parse supportedlist (or disabledlist if no supportedlist) */
      296 +        if ((token2 != NULL) && ((rc = parse_sup_dis_list(token2, pent)) !=
      297 +            SUCCESS)) {
 260  298                  free_entry(pent);
 261  299                  return (rc);
 262  300          }
 263  301  
 264      -        if (token3 && ((rc = parse_dislist(token3, pent)) != SUCCESS)) {
      302 +        /* parse disabledlist (if there's a supportedlist) */
      303 +        if ((token3 != NULL) && ((rc = parse_sup_dis_list(token3, pent)) !=
      304 +            SUCCESS)) {
 265  305                  free_entry(pent);
 266  306                  return (rc);
 267  307          }
 268  308  
 269  309          *ppent = pent;
 270  310          return (SUCCESS);
 271  311  }
 272  312  
 273  313  
 274  314  /*
 275      - * Add an entry to the end of an entry list. If the entry list is NULL, will
 276      - * create an entry list with the pent.
      315 + * Add an entry about a provider from kcf.conf to the end of an entry list.
      316 + * If the entry list pplist is NULL, create the linked list with pent as the
      317 + * first element.
 277  318   */
 278  319  static int
 279  320  build_entrylist(entry_t *pent, entrylist_t **pplist)
 280  321  {
 281      -        entrylist_t *pentlist;
 282      -        entrylist_t *pcur;
      322 +        entrylist_t     *pentlist;
      323 +        entrylist_t     *pcur = NULL;
 283  324  
 284  325          pentlist = malloc(sizeof (entrylist_t));
 285  326          if (pentlist == NULL) {
 286  327                  cryptodebug("out of memory.");
 287  328                  return (FAILURE);
 288  329          }
 289  330          pentlist->pent = pent;
 290  331          pentlist->next = NULL;
 291  332  
 292  333          if (*pplist) {
↓ open down ↓ 5 lines elided ↑ open up ↑
 298  339                  *pplist = pentlist;
 299  340          }
 300  341  
 301  342          return (SUCCESS);
 302  343  }
 303  344  
 304  345  
 305  346  
 306  347  /*
 307  348   * Find the entry with the "provname" name from the entry list and duplicate
 308      - * it.
      349 + * it.  Called by getent_kef().
 309  350   */
 310  351  static entry_t *
 311  352  getent(char *provname, entrylist_t *entrylist)
 312  353  {
 313  354          boolean_t       found = B_FALSE;
 314  355          entry_t         *pent1 = NULL;
 315  356  
 316  357          if ((provname == NULL) || (entrylist == NULL)) {
 317  358                  return (NULL);
 318  359          }
↓ open down ↓ 9 lines elided ↑ open up ↑
 328  369  
 329  370          if (!found) {
 330  371                  return (NULL);
 331  372          }
 332  373  
 333  374          /* duplicate the entry to be returned */
 334  375          return (dup_entry(pent1));
 335  376  }
 336  377  
 337  378  
 338      -
      379 +/*
      380 + * Free memory in entry_t.
      381 + * That is, the supported and disabled lists for a provider
      382 + * from kcf.conf.
      383 + */
 339  384  void
 340  385  free_entry(entry_t  *pent)
 341  386  {
 342  387          if (pent == NULL) {
 343  388                  return;
 344  389          } else {
 345  390                  free_mechlist(pent->suplist);
 346  391                  free_mechlist(pent->dislist);
 347  392                  free(pent);
 348  393          }
 349  394  }
 350  395  
 351  396  
      397 +/*
      398 + * Free elements in a entrylist_t linked list,
      399 + * which lists providers in kcf.conf.
      400 + */
 352  401  void
 353  402  free_entrylist(entrylist_t *entrylist)
 354  403  {
 355  404          entrylist_t *pnext;
 356  405  
 357  406          while (entrylist != NULL) {
 358  407                  pnext = entrylist->next;
 359  408                  free_entry(entrylist->pent);
 360  409                  entrylist = pnext;
 361  410          }
 362  411  }
 363  412  
 364  413  
 365  414  /*
 366  415   * Convert an entry to a string.  This routine builds a string for the entry
 367      - * to be inserted in the config file.  Based on the content of each entry,
 368      - * the result string can be one of the 4 forms:
 369      - *  - name
      416 + * to be inserted in the kcf.conf file.  Based on the content of each entry,
      417 + * the result string can be one of these 6 forms:
 370  418   *  - name:supportedlist=m1,m2,...,mj
 371  419   *  - name:disabledlist=m1,m2,...,mj
 372  420   *  - name:supportedlist=m1,...,mj;disabledlist=m1,m2,...,mk
 373  421   *
 374      - * Note that the caller is responsible for freeing the returned string.
      422 + *  - name:unload;supportedlist=m1,m2,...,mj
      423 + *  - name:unload;disabledlist=m1,m2,...,mj
      424 + *  - name:unload;supportedlist=m1,...,mj;disabledlist=m1,m2,...,mk
      425 + *
      426 + * Note that the caller is responsible for freeing the returned string
      427 + * (with free_entry()).
      428 + * See interpret() for the reverse of this function: converting a string
      429 + * to an entry_t.
 375  430   */
 376  431  char *
 377  432  ent2str(entry_t *pent)
 378  433  {
 379      -        char    *buf;
 380      -        mechlist_t  *phead;
 381      -        boolean_t supflag = B_FALSE;
      434 +        char            *buf;
      435 +        mechlist_t      *pcur = NULL;
      436 +        boolean_t       semicolon_separator = B_FALSE;
 382  437  
 383  438  
 384  439          if (pent == NULL) {
 385  440                  return (NULL);
 386  441          }
 387  442  
 388  443          if ((buf = malloc(BUFSIZ)) == NULL) {
 389  444                  return (NULL);
 390  445          }
 391  446  
 392  447          /* convert the provider name */
 393  448          if (strlcpy(buf, pent->name, BUFSIZ) >= BUFSIZ) {
 394  449                  free(buf);
 395  450                  return (NULL);
 396  451          }
 397  452  
 398      -        /* convert the supported list if any */
 399      -        phead = pent->suplist;
 400      -        if (phead != NULL) {
 401      -                supflag = B_TRUE;
 402      -
      453 +        if (!pent->load) { /* add "unload" keyword */
 403  454                  if (strlcat(buf, SEP_COLON, BUFSIZ) >= BUFSIZ) {
 404  455                          free(buf);
 405  456                          return (NULL);
 406  457                  }
 407  458  
      459 +                if (strlcat(buf, EF_UNLOAD, BUFSIZ) >= BUFSIZ) {
      460 +                        free(buf);
      461 +                        return (NULL);
      462 +                }
      463 +
      464 +                semicolon_separator = B_TRUE;
      465 +        }
      466 +
      467 +        /* convert the supported list if any */
      468 +        pcur = pent->suplist;
      469 +        if (pcur != NULL) {
      470 +                if (strlcat(buf,
      471 +                    semicolon_separator ? SEP_SEMICOLON : SEP_COLON,
      472 +                    BUFSIZ) >= BUFSIZ) {
      473 +                        free(buf);
      474 +                        return (NULL);
      475 +                }
      476 +
 408  477                  if (strlcat(buf, EF_SUPPORTED, BUFSIZ) >= BUFSIZ) {
 409  478                          free(buf);
 410  479                          return (NULL);
 411  480                  }
 412  481  
 413      -                while (phead != NULL) {
 414      -                        if (strlcat(buf, phead->name, BUFSIZ) >= BUFSIZ) {
      482 +                while (pcur != NULL) {
      483 +                        if (strlcat(buf, pcur->name, BUFSIZ) >= BUFSIZ) {
 415  484                                  free(buf);
 416  485                                  return (NULL);
 417  486                          }
 418  487  
 419      -                        phead = phead->next;
 420      -                        if (phead != NULL) {
      488 +                        pcur = pcur->next;
      489 +                        if (pcur != NULL) {
 421  490                                  if (strlcat(buf, SEP_COMMA, BUFSIZ)
 422  491                                      >= BUFSIZ) {
 423  492                                          free(buf);
 424  493                                          return (NULL);
 425  494                                  }
 426  495                          }
 427  496                  }
      497 +                semicolon_separator = B_TRUE;
 428  498          }
 429  499  
 430  500          /* convert the disabled list if any */
 431      -        phead = pent->dislist;
 432      -        if (phead != NULL) {
 433      -                if (supflag) {
 434      -                        if (strlcat(buf, ";disabledlist=", BUFSIZ) >= BUFSIZ) {
 435      -                                free(buf);
 436      -                                return (NULL);
 437      -                        }
 438      -                } else {
 439      -                        if (strlcat(buf, ":disabledlist=", BUFSIZ) >= BUFSIZ) {
 440      -                                free(buf);
 441      -                                return (NULL);
 442      -                        }
      501 +        pcur = pent->dislist;
      502 +        if (pcur != NULL) {
      503 +                if (strlcat(buf,
      504 +                    semicolon_separator ? SEP_SEMICOLON : SEP_COLON,
      505 +                    BUFSIZ) >= BUFSIZ) {
      506 +                        free(buf);
      507 +                        return (NULL);
 443  508                  }
 444  509  
 445      -                while (phead != NULL) {
 446      -                        if (strlcat(buf, phead->name, BUFSIZ) >= BUFSIZ) {
      510 +                if (strlcat(buf, EF_DISABLED, BUFSIZ) >= BUFSIZ) {
      511 +                        free(buf);
      512 +                        return (NULL);
      513 +                }
      514 +
      515 +                while (pcur != NULL) {
      516 +                        if (strlcat(buf, pcur->name, BUFSIZ) >= BUFSIZ) {
 447  517                                  free(buf);
 448  518                                  return (NULL);
 449  519                          }
 450  520  
 451      -                        phead = phead->next;
 452      -                        if (phead != NULL) {
      521 +                        pcur = pcur->next;
      522 +                        if (pcur != NULL) {
 453  523                                  if (strlcat(buf, SEP_COMMA, BUFSIZ)
 454  524                                      >= BUFSIZ) {
 455  525                                          free(buf);
 456  526                                          return (NULL);
 457  527                                  }
 458  528                          }
 459  529                  }
      530 +                semicolon_separator = B_TRUE;
 460  531          }
 461  532  
 462  533          if (strlcat(buf, "\n", BUFSIZ) >= BUFSIZ) {
 463  534                  free(buf);
 464  535                  return (NULL);
 465  536          }
 466  537  
 467  538          return (buf);
 468  539  }
 469  540  
 470  541  
 471  542  /*
 472  543   * Enable the mechanisms for the provider pointed by *ppent.  If allflag is
 473  544   * TRUE, enable all.  Otherwise, enable the mechanisms specified in the 3rd
 474  545   * argument "mlist".  The result will be stored in ppent also.
 475  546   */
 476  547  int
 477  548  enable_mechs(entry_t **ppent, boolean_t allflag, mechlist_t *mlist)
 478  549  {
 479      -        entry_t *pent;
 480      -        mechlist_t *phead; /* the current and resulting disabled list */
 481      -        mechlist_t *ptr;
 482      -        mechlist_t *pcur;
 483      -        boolean_t found;
      550 +        entry_t         *pent;
      551 +        mechlist_t      *phead; /* the current and resulting disabled list */
      552 +        mechlist_t      *ptr = NULL;
      553 +        mechlist_t      *pcur = NULL;
      554 +        boolean_t       found;
 484  555  
 485  556          pent = *ppent;
 486  557          if (pent == NULL) {
 487  558                  return (FAILURE);
 488  559          }
 489  560  
 490  561          if (allflag) {
 491  562                  free_mechlist(pent->dislist);
 492  563                  pent->dis_count = 0;
 493  564                  pent->dislist = NULL;
 494  565                  return (SUCCESS);
 495  566          }
 496  567  
 497  568          /*
 498  569           * for each mechanism in the to-be-enabled mechanism list,
 499  570           * -    check if it is in the current disabled list
 500  571           * -    if found, delete it from the disabled list
 501      -         *      otherwise, give a warning.
      572 +         *      otherwise, give a warning.
 502  573           */
 503  574          ptr = mlist;
 504  575          while (ptr != NULL) {
 505  576                  found = B_FALSE;
 506  577                  phead = pcur =  pent->dislist;
 507  578                  while (!found && pcur) {
 508  579                          if (strcmp(pcur->name, ptr->name) == 0) {
 509  580                                  found = B_TRUE;
 510  581                          } else {
 511  582                                  phead = pcur;
↓ open down ↓ 21 lines elided ↑ open up ↑
 533  604  
 534  605          if (pent->dis_count == 0) {
 535  606                  pent->dislist = NULL;
 536  607          }
 537  608  
 538  609          return (SUCCESS);
 539  610  
 540  611  }
 541  612  
 542  613  
      614 +/*
      615 + * Determine if the kernel provider name, path, is a device
      616 + * (that is, it contains a slash character (e.g., "mca/0").
      617 + * If so, it is a hardware provider; otherwise it is a software provider.
      618 + */
 543  619  boolean_t
 544  620  is_device(char *path)
 545  621  {
 546  622          if (strchr(path, SEP_SLASH) != NULL) {
 547  623                  return (B_TRUE);
 548  624          } else {
 549  625                  return (B_FALSE);
 550  626          }
 551  627  }
 552  628  
 553  629  /*
 554  630   * Split a hardware provider name with the "name/inst_num" format into
 555      - * a name and a number.
      631 + * a name and a number (e.g., split "mca/0" into "mca" instance 0).
 556  632   */
 557  633  int
 558  634  split_hw_provname(char *provname, char *pname, int *inst_num)
 559  635  {
 560  636          char    name[MAXNAMELEN];
 561  637          char    *inst_str;
 562  638  
 563  639          if (provname == NULL) {
 564  640                  return (FAILURE);
 565  641          }
↓ open down ↓ 8 lines elided ↑ open up ↑
 574  650          }
 575  651  
 576  652          (void) strlcpy(pname, name, MAXNAMELEN);
 577  653          *inst_num = atoi(inst_str);
 578  654  
 579  655          return (SUCCESS);
 580  656  }
 581  657  
 582  658  
 583  659  /*
 584      - * Retrieve information from kcf.conf and build a device entry list and
 585      - * a software entry list
      660 + * Retrieve information from kcf.conf and build a hardware device entry list
      661 + * and a software entry list of kernel crypto providers.
      662 + *
      663 + * This list is usually incomplete, as kernel crypto providers only have to
      664 + * be listed in kcf.conf if a mechanism is disabled (by cryptoadm) or
      665 + * if the kernel provider module is not one of the default kernel providers.
      666 + *
      667 + * The kcf.conf file is available only in the global zone.
 586  668   */
 587  669  int
 588  670  get_kcfconf_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist)
 589  671  {
 590      -        FILE *pfile;
 591      -        char buffer[BUFSIZ];
 592      -        int len;
 593      -        entry_t *pent = NULL;
 594      -        int rc = SUCCESS;
      672 +        FILE    *pfile = NULL;
      673 +        char    buffer[BUFSIZ];
      674 +        int     len;
      675 +        entry_t *pent = NULL;
      676 +        int     rc = SUCCESS;
 595  677  
 596  678          if ((pfile = fopen(_PATH_KCF_CONF, "r")) == NULL) {
 597  679                  cryptodebug("failed to open the kcf.conf file for read only");
 598  680                  return (FAILURE);
 599  681          }
 600  682  
 601  683          *ppdevlist = NULL;
 602  684          *ppsoftlist = NULL;
 603  685          while (fgets(buffer, BUFSIZ, pfile) != NULL) {
 604  686                  if (buffer[0] == '#' || buffer[0] == ' ' ||
 605  687                      buffer[0] == '\n'|| buffer[0] == '\t') {
 606  688                          continue;   /* ignore comment lines */
 607  689                  }
 608  690  
 609  691                  len = strlen(buffer);
 610      -                if (buffer[len-1] == '\n') { /* get rid of trailing '\n' */
      692 +                if (buffer[len - 1] == '\n') { /* get rid of trailing '\n' */
 611  693                          len--;
 612  694                  }
 613  695                  buffer[len] = '\0';
 614  696  
 615  697                  if ((rc = interpret(buffer,  &pent)) == SUCCESS) {
 616  698                          if (is_device(pent->name)) {
 617  699                                  rc = build_entrylist(pent, ppdevlist);
 618  700                          } else {
 619  701                                  rc = build_entrylist(pent, ppsoftlist);
 620  702                          }
↓ open down ↓ 9 lines elided ↑ open up ↑
 630  712                          break;
 631  713                  }
 632  714          }
 633  715  
 634  716          (void) fclose(pfile);
 635  717          return (rc);
 636  718  }
 637  719  
 638  720  /*
 639  721   * Retrieve information from admin device and build a device entry list and
 640      - * a software entry list.  This is used where there is no kcf.conf, e.g.
      722 + * a software entry list.  This is used where there is no kcf.conf, e.g., the
 641  723   * non-global zone.
 642  724   */
 643  725  int
 644  726  get_admindev_info(entrylist_t **ppdevlist, entrylist_t **ppsoftlist)
 645  727  {
 646      -        crypto_get_dev_list_t *pdevlist_kernel = NULL;
 647      -        crypto_get_soft_list_t *psoftlist_kernel = NULL;
 648      -        char *devname;
 649      -        int inst_num;
 650      -        int mcount;
 651      -        mechlist_t *pmech;
 652      -        entry_t *pent = NULL;
 653      -        int i;
 654      -        char *psoftname;
 655      -        entrylist_t *tmp_pdev = NULL;
 656      -        entrylist_t *tmp_psoft = NULL;
      728 +        crypto_get_dev_list_t   *pdevlist_kernel = NULL;
      729 +        crypto_get_soft_list_t  *psoftlist_kernel = NULL;
      730 +        char                    *devname;
      731 +        int                     inst_num;
      732 +        int                     mcount;
      733 +        mechlist_t              *pmech = NULL;
      734 +        entry_t                 *pent_dev = NULL, *pent_soft = NULL;
      735 +        int                     i;
      736 +        char                    *psoftname;
      737 +        entrylist_t             *tmp_pdev = NULL;
      738 +        entrylist_t             *tmp_psoft = NULL;
      739 +        entrylist_t             *phardlist = NULL, *psoftlist = NULL;
 657  740  
      741 +        /*
      742 +         * Get hardware providers
      743 +         */
 658  744          if (get_dev_list(&pdevlist_kernel) != SUCCESS) {
 659  745                  cryptodebug("failed to get hardware provider list from kernel");
 660  746                  return (FAILURE);
 661  747          }
 662  748  
 663  749          for (i = 0; i < pdevlist_kernel->dl_dev_count; i++) {
 664  750                  devname = pdevlist_kernel->dl_devs[i].le_dev_name;
 665  751                  inst_num = pdevlist_kernel->dl_devs[i].le_dev_instance;
 666  752                  mcount = pdevlist_kernel->dl_devs[i].le_mechanism_count;
 667  753  
 668  754                  pmech = NULL;
 669  755                  if (get_dev_info(devname, inst_num, mcount, &pmech) !=
 670  756                      SUCCESS) {
 671  757                          cryptodebug(
 672  758                              "failed to retrieve the mechanism list for %s/%d.",
 673  759                              devname, inst_num);
 674  760                          goto fail_out;
 675  761                  }
 676  762  
 677      -                if ((pent = malloc(sizeof (entry_t))) == NULL) {
      763 +                if ((pent_dev = create_entry(devname)) == NULL) {
 678  764                          cryptodebug("out of memory.");
 679  765                          free_mechlist(pmech);
 680  766                          goto fail_out;
 681  767                  }
      768 +                pent_dev->suplist = pmech;
      769 +                pent_dev->sup_count = mcount;
 682  770  
 683      -                (void) strlcpy(pent->name, devname, MAXNAMELEN);
 684      -                pent->suplist = pmech;
 685      -                pent->sup_count = mcount;
 686      -                pent->dislist = NULL;
 687      -                pent->dis_count = 0;
 688      -
 689      -                if (build_entrylist(pent, &tmp_pdev) != SUCCESS) {
      771 +                if (build_entrylist(pent_dev, &tmp_pdev) != SUCCESS) {
 690  772                          goto fail_out;
 691  773                  }
 692      -
 693      -                /* because incorporated in tmp_pdev */
 694      -                pent = NULL;
 695  774          }
 696  775  
 697  776          free(pdevlist_kernel);
 698  777          pdevlist_kernel = NULL;
 699  778  
      779 +        /*
      780 +         * Get software providers
      781 +         */
      782 +        if (getzoneid() == GLOBAL_ZONEID) {
      783 +                if (get_kcfconf_info(&phardlist, &psoftlist) != SUCCESS) {
      784 +                        goto fail_out;
      785 +                }
      786 +        }
      787 +
 700  788          if (get_soft_list(&psoftlist_kernel) != SUCCESS) {
 701  789                  cryptodebug("failed to get software provider list from kernel");
 702  790                  goto fail_out;
 703  791          }
 704  792  
 705  793          for (i = 0, psoftname = psoftlist_kernel->sl_soft_names;
 706  794              i < psoftlist_kernel->sl_soft_count;
 707  795              i++, psoftname = psoftname + strlen(psoftname) + 1) {
 708  796                  pmech = NULL;
 709      -                if (get_soft_info(psoftname, &pmech) != SUCCESS) {
      797 +                if (get_soft_info(psoftname, &pmech, phardlist, psoftlist) !=
      798 +                    SUCCESS) {
 710  799                          cryptodebug(
 711  800                              "failed to retrieve the mechanism list for %s.",
 712  801                              psoftname);
 713  802                          goto fail_out;
 714  803                  }
 715  804  
 716      -                if ((pent = malloc(sizeof (entry_t))) == NULL) {
      805 +                if ((pent_soft = create_entry(psoftname)) == NULL) {
 717  806                          cryptodebug("out of memory.");
 718  807                          free_mechlist(pmech);
 719  808                          goto fail_out;
 720  809                  }
      810 +                pent_soft->suplist = pmech;
      811 +                pent_soft->sup_count = get_mech_count(pmech);
 721  812  
 722      -                (void) strlcpy(pent->name, psoftname, MAXNAMELEN);
 723      -                pent->suplist = pmech;
 724      -                pent->sup_count = get_mech_count(pmech);
 725      -                pent->dislist = NULL;
 726      -                pent->dis_count = 0;
 727      -
 728      -                if (build_entrylist(pent, &tmp_psoft) != SUCCESS) {
      813 +                if (build_entrylist(pent_soft, &tmp_psoft) != SUCCESS) {
 729  814                          goto fail_out;
 730  815                  }
 731  816          }
 732  817  
 733  818          free(psoftlist_kernel);
 734  819          psoftlist_kernel = NULL;
 735  820  
 736  821          *ppdevlist = tmp_pdev;
 737  822          *ppsoftlist = tmp_psoft;
 738  823  
 739  824          return (SUCCESS);
 740  825  
 741  826  fail_out:
 742      -        if (pent != NULL)
 743      -                free_entry(pent);
      827 +        if (pent_dev != NULL)
      828 +                free_entry(pent_dev);
      829 +        if (pent_soft != NULL)
      830 +                free_entry(pent_soft);
 744  831  
 745  832          free_entrylist(tmp_pdev);
 746  833          free_entrylist(tmp_psoft);
 747  834  
 748  835          if (pdevlist_kernel != NULL)
 749  836                  free(pdevlist_kernel);
 750  837          if (psoftlist_kernel != NULL)
 751  838                  free(psoftlist_kernel);
 752  839  
 753  840          return (FAILURE);
 754  841  }
 755  842  
 756  843  /*
 757      - * Find the entry in the "kcf.conf" file with "provname" as the provider name.
 758      - * Return the entry if found, otherwise return NULL.
      844 + * Return configuration information for a kernel provider from kcf.conf.
      845 + * For kernel software providers return a enabled list and disabled list.
      846 + * For kernel hardware providers return just a disabled list.
      847 + *
      848 + * Parameters phardlist and psoftlist are supplied by get_kcfconf_info().
      849 + * If NULL, this function calls get_kcfconf_info() internally.
 759  850   */
 760  851  entry_t *
 761      -getent_kef(char *provname)
      852 +getent_kef(char *provname, entrylist_t *phardlist, entrylist_t *psoftlist)
 762  853  {
 763      -        entrylist_t *pdevlist = NULL;
 764      -        entrylist_t *psoftlist = NULL;
 765      -        entry_t *pent = NULL;
      854 +        entry_t         *pent = NULL;
      855 +        boolean_t       memory_allocated = B_FALSE;
 766  856  
 767      -        if (get_kcfconf_info(&pdevlist, &psoftlist) != SUCCESS) {
 768      -                return (NULL);
      857 +        if ((phardlist == NULL) || (psoftlist == NULL)) {
      858 +                if (get_kcfconf_info(&phardlist, &psoftlist) != SUCCESS) {
      859 +                        return (NULL);
      860 +                }
      861 +                memory_allocated = B_TRUE;
 769  862          }
 770  863  
 771  864          if (is_device(provname)) {
 772      -                pent = getent(provname, pdevlist);
      865 +                pent = getent(provname, phardlist);
 773  866          } else {
 774  867                  pent = getent(provname, psoftlist);
 775  868          }
 776  869  
 777      -        free_entrylist(pdevlist);
 778      -        free_entrylist(psoftlist);
      870 +        if (memory_allocated) {
      871 +                free_entrylist(phardlist);
      872 +                free_entrylist(psoftlist);
      873 +        }
 779  874  
 780  875          return (pent);
 781  876  }
 782  877  
 783  878  /*
 784  879   * Print out the provider name and the mechanism list.
 785  880   */
 786  881  void
 787  882  print_mechlist(char *provname, mechlist_t *pmechlist)
 788  883  {
 789      -        mechlist_t *ptr;
      884 +        mechlist_t *ptr = NULL;
 790  885  
 791  886          if (provname == NULL) {
 792  887                  return;
 793  888          }
 794  889  
 795  890          (void) printf("%s: ", provname);
 796  891          if (pmechlist == NULL) {
 797  892                  (void) printf(gettext("No mechanisms presented.\n"));
 798  893                  return;
 799  894          }
↓ open down ↓ 5 lines elided ↑ open up ↑
 805  900                  if (ptr == NULL) {
 806  901                          (void) printf("\n");
 807  902                  } else {
 808  903                          (void) printf(",");
 809  904                  }
 810  905          }
 811  906  }
 812  907  
 813  908  
 814  909  /*
 815      - * Update the kcf.conf file based on the specified entry and the update mode.
 816      - * - If update_mode is MODIFY_MODE or DELETE_MODE, the entry with the same
 817      - *   provider name will be modified or deleted.
 818      - * - If update_mode is ADD_MODE, this must be a hardware provider without
 819      - *   an entry in the kcf.conf file yet.  Need to locate its driver package
 820      - *   bracket and insert an entry into the bracket.
      910 + * Update the kcf.conf file based on the update mode:
      911 + * - If update_mode is MODIFY_MODE, modify the entry with the same name.
      912 + *   If not found, append a new entry to the kcf.conf file.
      913 + * - If update_mode is DELETE_MODE, delete the entry with the same name.
      914 + * - If update_mode is ADD_MODE, append a new entry to the kcf.conf file.
 821  915   */
 822  916  int
 823  917  update_kcfconf(entry_t *pent, int update_mode)
 824  918  {
 825  919          boolean_t       add_it = B_FALSE;
 826  920          boolean_t       delete_it = B_FALSE;
 827      -        boolean_t       found_package = B_FALSE;
 828  921          boolean_t       found_entry = B_FALSE;
 829      -        FILE    *pfile;
 830      -        FILE    *pfile_tmp;
 831      -        char    buffer[BUFSIZ];
 832      -        char    buffer2[BUFSIZ];
 833      -        char    devname[MAXNAMELEN];
 834      -        char    tmpfile_name[MAXPATHLEN];
 835      -        char    *name;
 836      -        char    *str;
 837      -        char    *new_str = NULL;
 838      -        int     inst_num;
 839      -        int rc = SUCCESS;
      922 +        FILE            *pfile = NULL;
      923 +        FILE            *pfile_tmp = NULL;
      924 +        char            buffer[BUFSIZ];
      925 +        char            buffer2[BUFSIZ];
      926 +        char            tmpfile_name[MAXPATHLEN];
      927 +        char            *name;
      928 +        char            *new_str = NULL;
      929 +        int             rc = SUCCESS;
 840  930  
 841      -
 842  931          if (pent == NULL) {
 843  932                  cryptoerror(LOG_STDERR, gettext("internal error."));
 844  933                  return (FAILURE);
 845  934          }
 846  935  
 847  936          /* Check the update_mode */
 848      -        if (update_mode == ADD_MODE) {
      937 +        switch (update_mode) {
      938 +        case ADD_MODE:
 849  939                  add_it = B_TRUE;
 850      -                /* Get the hardware provider name first */
 851      -                if (split_hw_provname(pent->name, devname, &inst_num) ==
 852      -                    FAILURE) {
 853      -                        return (FAILURE);
 854      -                }
 855      -
 856      -                /* Convert the entry to be a string  */
      940 +                /* FALLTHROUGH */
      941 +        case MODIFY_MODE:
      942 +                /* Convert the entry a string to add to kcf.conf  */
 857  943                  if ((new_str = ent2str(pent)) == NULL) {
 858  944                          return (FAILURE);
 859  945                  }
 860      -        } else if (update_mode == DELETE_MODE) {
      946 +                break;
      947 +        case DELETE_MODE:
 861  948                  delete_it = B_TRUE;
 862      -        } else if (update_mode != MODIFY_MODE) {
      949 +                break;
      950 +        default:
 863  951                  cryptoerror(LOG_STDERR, gettext("internal error."));
 864  952                  return (FAILURE);
 865  953          }
 866  954  
 867      -
 868  955          /* Open the kcf.conf file */
 869  956          if ((pfile = fopen(_PATH_KCF_CONF, "r+")) == NULL) {
 870  957                  err = errno;
 871  958                  cryptoerror(LOG_STDERR,
 872  959                      gettext("failed to update the configuration - %s"),
 873  960                      strerror(err));
 874  961                  cryptodebug("failed to open %s for write.", _PATH_KCF_CONF);
 875  962                  return (FAILURE);
 876  963          }
 877  964  
 878  965          /* Lock the kcf.conf file */
 879  966          if (lockf(fileno(pfile), F_TLOCK, 0) == -1) {
 880  967                  err = errno;
 881  968                  cryptoerror(LOG_STDERR,
 882  969                      gettext("failed to update the configuration - %s"),
 883      -                        strerror(err));
      970 +                    strerror(err));
 884  971                  (void) fclose(pfile);
 885  972                  return (FAILURE);
 886  973          }
 887  974  
 888  975          /*
 889  976           * Create a temporary file in the /etc/crypto directory to save
 890  977           * updated configuration file first.
 891  978           */
 892  979          (void) strlcpy(tmpfile_name, TMPFILE_TEMPLATE, sizeof (tmpfile_name));
 893  980          if (mkstemp(tmpfile_name) == -1) {
↓ open down ↓ 12 lines elided ↑ open up ↑
 906  993                  (void) fclose(pfile);
 907  994                  return (FAILURE);
 908  995          }
 909  996  
 910  997          /*
 911  998           * Loop thru the entire kcf.conf file, insert, modify or delete
 912  999           * an entry.
 913 1000           */
 914 1001          while (fgets(buffer, BUFSIZ, pfile) != NULL) {
 915 1002                  if (add_it) {
 916      -                        /* always keep the current line */
 917 1003                          if (fputs(buffer, pfile_tmp) == EOF) {
 918 1004                                  err = errno;
 919 1005                                  cryptoerror(LOG_STDERR, gettext(
 920 1006                                      "failed to write to a temp file: %s."),
 921 1007                                      strerror(err));
 922 1008                                  rc = FAILURE;
 923 1009                                  break;
 924 1010                          }
 925 1011  
 926      -                        /*
 927      -                         * If the current position is the beginning of a driver
 928      -                         * package and if the driver name matches the hardware
 929      -                         * provider name, then we want to insert the entry
 930      -                         * here.
 931      -                         */
 932      -                        if ((strstr(buffer, HW_DRIVER_STRING) != NULL) &&
 933      -                            (strstr(buffer, devname) != NULL)) {
 934      -                                found_package = B_TRUE;
 935      -                                if (fputs(new_str, pfile_tmp) == EOF) {
 936      -                                        err = errno;
 937      -                                        cryptoerror(LOG_STDERR, gettext(
 938      -                                            "failed to write to a temp file: "
 939      -                                            "%s."), strerror(err));
 940      -                                        rc = FAILURE;
 941      -                                        break;
 942      -                                }
 943      -                        }
 944 1012                  } else { /* modify or delete */
 945 1013                          found_entry = B_FALSE;
     1014 +
 946 1015                          if (!(buffer[0] == '#' || buffer[0] == ' ' ||
 947 1016                              buffer[0] == '\n'|| buffer[0] == '\t')) {
 948 1017                                  /*
 949 1018                                   * Get the provider name from this line and
 950 1019                                   * check if this is the entry to be updated
 951 1020                                   * or deleted. Note: can not use "buffer"
 952 1021                                   * directly because strtok will change its
 953 1022                                   * value.
 954 1023                                   */
 955 1024                                  (void) strlcpy(buffer2, buffer, BUFSIZ);
↓ open down ↓ 6 lines elided ↑ open up ↑
 962 1031                                  if (strcmp(pent->name, name) == 0) {
 963 1032                                          found_entry = B_TRUE;
 964 1033                                  }
 965 1034                          }
 966 1035  
 967 1036                          if (found_entry && !delete_it) {
 968 1037                                  /*
 969 1038                                   * This is the entry to be updated; get the
 970 1039                                   * updated string and place into buffer.
 971 1040                                   */
 972      -                                if ((str = ent2str(pent)) == NULL) {
 973      -                                        rc = FAILURE;
 974      -                                        break;
 975      -                                } else {
 976      -                                        (void) strlcpy(buffer, str, BUFSIZ);
 977      -                                        free(str);
 978      -                                }
     1041 +                                (void) strlcpy(buffer, new_str, BUFSIZ);
     1042 +                                free(new_str);
 979 1043                          }
 980 1044  
 981 1045                          if (!(found_entry && delete_it)) {
 982 1046                                  /* This is the entry to be updated/reserved */
 983 1047                                  if (fputs(buffer, pfile_tmp) == EOF) {
 984 1048                                          err = errno;
 985 1049                                          cryptoerror(LOG_STDERR, gettext(
 986 1050                                              "failed to write to a temp file: "
 987 1051                                              "%s."), strerror(err));
 988 1052                                          rc = FAILURE;
 989 1053                                          break;
 990 1054                                  }
 991 1055                          }
 992 1056                  }
 993 1057          }
 994 1058  
 995      -        if (add_it) {
 996      -                free(new_str);
 997      -        }
 998      -
 999      -        if ((add_it && !found_package) || (rc == FAILURE)) {
1000      -                if (add_it && !found_package) {
1001      -                        cryptoerror(LOG_STDERR,
1002      -                            gettext("failed to update configuration - no "
1003      -                            "driver package information."));
     1059 +        if ((!delete_it) && (rc != FAILURE)) {
     1060 +                if (add_it || !found_entry) {
     1061 +                        /* append new entry to end of file */
     1062 +                        if (fputs(new_str, pfile_tmp) == EOF) {
     1063 +                                err = errno;
     1064 +                                cryptoerror(LOG_STDERR, gettext(
     1065 +                                    "failed to write to a temp file: %s."),
     1066 +                                    strerror(err));
     1067 +                                rc = FAILURE;
     1068 +                        }
     1069 +                        free(new_str);
1004 1070                  }
1005      -
1006      -                (void) fclose(pfile);
1007      -                (void) fclose(pfile_tmp);
1008      -                if (unlink(tmpfile_name) != 0) {
1009      -                        err = errno;
1010      -                        cryptoerror(LOG_STDERR, gettext(
1011      -                            "(Warning) failed to remove %s: %s"),
1012      -                            tmpfile_name, strerror(err));
1013      -                }
1014      -                return (FAILURE);
1015 1071          }
1016 1072  
1017 1073          (void) fclose(pfile);
1018 1074          if (fclose(pfile_tmp) != 0) {
1019 1075                  err = errno;
1020 1076                  cryptoerror(LOG_STDERR,
1021 1077                      gettext("failed to close %s: %s"), tmpfile_name,
1022 1078                      strerror(err));
1023 1079                  return (FAILURE);
1024 1080          }
↓ open down ↓ 34 lines elided ↑ open up ↑
1059 1115  /*
1060 1116   * Disable the mechanisms for the provider pointed by *ppent.  If allflag is
1061 1117   * TRUE, disable all.  Otherwise, disable the mechanisms specified in the
1062 1118   * dislist argument.  The "infolist" argument contains the mechanism list
1063 1119   * supported by this provider.
1064 1120   */
1065 1121  int
1066 1122  disable_mechs(entry_t **ppent, mechlist_t *infolist, boolean_t allflag,
1067 1123  mechlist_t *dislist)
1068 1124  {
1069      -        entry_t *pent;
1070      -        mechlist_t *plist;
1071      -        mechlist_t *phead;
1072      -        mechlist_t *pmech;
1073      -        int rc = SUCCESS;
     1125 +        entry_t         *pent;
     1126 +        mechlist_t      *plist = NULL;
     1127 +        mechlist_t      *phead = NULL;
     1128 +        mechlist_t      *pmech = NULL;
     1129 +        int             rc = SUCCESS;
1074 1130  
1075 1131          pent = *ppent;
1076 1132          if (pent == NULL) {
1077 1133                  return (FAILURE);
1078 1134          }
1079 1135  
1080 1136          if (allflag) {
1081 1137                  free_mechlist(pent->dislist);
1082 1138                  pent->dis_count = get_mech_count(infolist);
1083 1139                  if (!(pent->dislist = dup_mechlist(infolist))) {
↓ open down ↓ 40 lines elided ↑ open up ↑
1124 1180  
1125 1181  /*
1126 1182   * Remove the mechanism passed, specified by mech, from the list of
1127 1183   * mechanisms, if present in the list. Else, do nothing.
1128 1184   *
1129 1185   * Returns B_TRUE if mechanism is present in the list.
1130 1186   */
1131 1187  boolean_t
1132 1188  filter_mechlist(mechlist_t **pmechlist, const char *mech)
1133 1189  {
1134      -        int cnt = 0;
1135      -        mechlist_t *ptr, *pptr;
1136      -        boolean_t mech_present = B_FALSE;
     1190 +        int             cnt = 0;
     1191 +        mechlist_t      *ptr, *pptr;
     1192 +        boolean_t       mech_present = B_FALSE;
1137 1193  
1138 1194          ptr = pptr = *pmechlist;
1139 1195  
1140 1196          while (ptr != NULL) {
1141 1197                  if (strncmp(ptr->name, mech, sizeof (mech_name_t)) == 0) {
1142 1198                          mech_present = B_TRUE;
1143 1199                          if (ptr == *pmechlist) {
1144 1200                                  pptr = *pmechlist = ptr->next;
1145 1201                                  free(ptr);
1146 1202                                  ptr = pptr;
↓ open down ↓ 18 lines elided ↑ open up ↑
1165 1221  
1166 1222  
1167 1223  
1168 1224  /*
1169 1225   * Print out the mechanism policy for a kernel provider that has an entry
1170 1226   * in the kcf.conf file.
1171 1227   *
1172 1228   * The flag has_random is set to B_TRUE if the provider does random
1173 1229   * numbers. The flag has_mechs is set by the caller to B_TRUE if the provider
1174 1230   * has some mechanisms.
     1231 + *
     1232 + * If pent is NULL, the provider doesn't have a kcf.conf entry.
1175 1233   */
1176 1234  void
1177      -print_kef_policy(entry_t *pent, boolean_t has_random, boolean_t has_mechs)
     1235 +print_kef_policy(char *provname, entry_t *pent, boolean_t has_random,
     1236 +    boolean_t has_mechs)
1178 1237  {
1179      -        mechlist_t *ptr;
1180      -        boolean_t rnd_disabled = B_FALSE;
     1238 +        mechlist_t      *ptr = NULL;
     1239 +        boolean_t       rnd_disabled = B_FALSE;
1181 1240  
1182      -        if (pent == NULL) {
1183      -                return;
     1241 +        if (pent != NULL) {
     1242 +                rnd_disabled = filter_mechlist(&pent->dislist, RANDOM);
     1243 +                ptr = pent->dislist;
1184 1244          }
1185 1245  
1186      -        rnd_disabled = filter_mechlist(&pent->dislist, RANDOM);
1187      -        ptr = pent->dislist;
     1246 +        (void) printf("%s:", provname);
1188 1247  
1189      -        (void) printf("%s:", pent->name);
1190      -
1191 1248          if (has_mechs == B_TRUE) {
1192 1249                  /*
1193 1250                   * TRANSLATION_NOTE
1194 1251                   * This code block may need to be modified a bit to avoid
1195 1252                   * constructing the text message on the fly.
1196 1253                   */
1197 1254                  (void) printf(gettext(" all mechanisms are enabled"));
1198 1255                  if (ptr != NULL)
1199 1256                          (void) printf(gettext(", except "));
1200 1257                  while (ptr != NULL) {
↓ open down ↓ 10 lines elided ↑ open up ↑
1211 1268           * TRANSLATION_NOTE
1212 1269           * "random" is a keyword and not to be translated.
1213 1270           */
1214 1271          if (rnd_disabled)
1215 1272                  (void) printf(gettext(" %s is disabled."), "random");
1216 1273          else if (has_random)
1217 1274                  (void) printf(gettext(" %s is enabled."), "random");
1218 1275          (void) printf("\n");
1219 1276  }
1220 1277  
     1278 +
1221 1279  /*
1222 1280   * Check if a kernel software provider is in the kernel.
     1281 + *
     1282 + * Parameters:
     1283 + * provname             Provider name
     1284 + * psoftlist_kernel     Optional software provider list.  If NULL, it will be
     1285 + *                      obtained from get_soft_list().
     1286 + * in_kernel            Set to B_TRUE if device is in the kernel, else B_FALSE
1223 1287   */
1224 1288  int
1225      -check_active_for_soft(char *provname, boolean_t *is_active)
     1289 +check_kernel_for_soft(char *provname, crypto_get_soft_list_t *psoftlist_kernel,
     1290 +    boolean_t *in_kernel)
1226 1291  {
1227      -        crypto_get_soft_list_t  *psoftlist_kernel = NULL;
1228      -        char    *ptr;
1229      -        int     i;
     1292 +        char            *ptr;
     1293 +        int             i;
     1294 +        boolean_t       psoftlist_allocated = B_FALSE;
1230 1295  
1231 1296          if (provname == NULL) {
1232 1297                  cryptoerror(LOG_STDERR, gettext("internal error."));
1233 1298                  return (FAILURE);
1234 1299          }
1235 1300  
1236      -        if (get_soft_list(&psoftlist_kernel) == FAILURE) {
1237      -                cryptodebug("failed to get the software provider list from"
1238      -                    "kernel.");
1239      -                return (FAILURE);
     1301 +        if (psoftlist_kernel == NULL) {
     1302 +                if (get_soft_list(&psoftlist_kernel) == FAILURE) {
     1303 +                        cryptodebug("failed to get the software provider list"
     1304 +                        " from kernel.");
     1305 +                        return (FAILURE);
     1306 +                }
     1307 +                psoftlist_allocated = B_TRUE;
1240 1308          }
1241 1309  
1242      -        *is_active = B_FALSE;
     1310 +        *in_kernel = B_FALSE;
1243 1311          ptr = psoftlist_kernel->sl_soft_names;
1244 1312          for (i = 0; i < psoftlist_kernel->sl_soft_count; i++) {
1245 1313                  if (strcmp(provname, ptr) == 0) {
1246      -                        *is_active = B_TRUE;
     1314 +                        *in_kernel = B_TRUE;
1247 1315                          break;
1248 1316                  }
1249 1317                  ptr = ptr + strlen(ptr) + 1;
1250 1318          }
1251      -        free(psoftlist_kernel);
1252 1319  
     1320 +        if (psoftlist_allocated)
     1321 +                free(psoftlist_kernel);
     1322 +
1253 1323          return (SUCCESS);
1254 1324  }
1255 1325  
1256 1326  
1257 1327  /*
1258 1328   * Check if a kernel hardware provider is in the kernel.
     1329 + *
     1330 + * Parameters:
     1331 + * provname     Provider name
     1332 + * pdevlist     Optional Hardware Crypto Device List.  If NULL, it will be
     1333 + *              obtained from get_dev_list().
     1334 + * in_kernel    Set to B_TRUE if device is in the kernel, otherwise B_FALSE
1259 1335   */
1260 1336  int
1261      -check_active_for_hard(char *provname, boolean_t *is_active)
     1337 +check_kernel_for_hard(char *provname,
     1338 +    crypto_get_dev_list_t *pdevlist, boolean_t *in_kernel)
1262 1339  {
1263      -        crypto_get_dev_list_t   *pdevlist = NULL;
1264      -        char    devname[MAXNAMELEN];
1265      -        int     inst_num;
1266      -        int     i;
     1340 +        char            devname[MAXNAMELEN];
     1341 +        int             inst_num;
     1342 +        int             i;
     1343 +        boolean_t       dev_list_allocated = B_FALSE;
1267 1344  
1268 1345          if (provname == NULL) {
1269 1346                  cryptoerror(LOG_STDERR, gettext("internal error."));
1270 1347                  return (FAILURE);
1271 1348          }
1272 1349  
1273 1350          if (split_hw_provname(provname, devname, &inst_num) == FAILURE) {
1274 1351                  return (FAILURE);
1275 1352          }
1276 1353  
1277      -        if (get_dev_list(&pdevlist) == FAILURE) {
1278      -                cryptoerror(LOG_STDERR, gettext("internal error."));
1279      -                return (FAILURE);
     1354 +        if (pdevlist == NULL) {
     1355 +                if (get_dev_list(&pdevlist) == FAILURE) {
     1356 +                        cryptoerror(LOG_STDERR, gettext("internal error."));
     1357 +                        return (FAILURE);
     1358 +                }
     1359 +                dev_list_allocated = B_TRUE;
1280 1360          }
1281 1361  
1282      -        *is_active = B_FALSE;
     1362 +        *in_kernel = B_FALSE;
1283 1363          for (i = 0; i < pdevlist->dl_dev_count; i++) {
1284 1364                  if ((strcmp(pdevlist->dl_devs[i].le_dev_name, devname) == 0) &&
1285 1365                      (pdevlist->dl_devs[i].le_dev_instance == inst_num)) {
1286      -                        *is_active = B_TRUE;
     1366 +                        *in_kernel = B_TRUE;
1287 1367                          break;
1288 1368                  }
1289 1369          }
1290      -        free(pdevlist);
1291 1370  
     1371 +        if (dev_list_allocated)
     1372 +                free(pdevlist);
     1373 +
1292 1374          return (SUCCESS);
1293 1375  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX