Print this page
*** NO COMMENTS ***


  47 #include <unistd.h>
  48 #include <stropts.h>
  49 #include <libdevinfo.h>
  50 #include <libgen.h>
  51 #include <ctype.h>
  52 #include <dlfcn.h>
  53 #include <limits.h>
  54 #include <security/cryptoki.h>
  55 #include <cryptoutil.h>
  56 #include <sys/crypto/ioctl.h>
  57 #include <sys/crypto/ioctladmin.h>
  58 #include "utils.h"
  59 #include <LzmaEnc.h>
  60 
  61 /* Only need the IV len #defines out of these files, nothing else. */
  62 #include <aes/aes_impl.h>
  63 #include <des/des_impl.h>
  64 #include <blowfish/blowfish_impl.h>
  65 
  66 static const char USAGE[] =
  67         "Usage: %s -a file [ device ] "
  68         " [-c aes-128-cbc|aes-192-cbc|aes-256-cbc|des3-cbc|blowfish-cbc]"
  69         " [-e] [-k keyfile] [-T [token]:[manuf]:[serial]:key]\n"
  70         "       %s -d file | device\n"
  71         "       %s -C [gzip|gzip-6|gzip-9|lzma] [-s segment_size] file\n"
  72         "       %s -U file\n"
  73         "       %s [ file | device ]\n";
  74 
  75 typedef struct token_spec {
  76         char    *name;
  77         char    *mfr;
  78         char    *serno;
  79         char    *key;
  80 } token_spec_t;
  81 
  82 typedef struct mech_alias {
  83         char    *alias;
  84         CK_MECHANISM_TYPE type;
  85         char    *name;          /* for ioctl */
  86         char    *iv_name;       /* for ioctl */
  87         size_t  iv_len;         /* for ioctl */


 347 
 348         li.li_minor = 0;
 349         (void) strlcpy(li.li_filename, filename, sizeof (li.li_filename));
 350         minor = ioctl(lfd, LOFI_MAP_FILE, &li);
 351         if (minor == -1) {
 352                 if (errno == ENOTSUP)
 353                         warn(gettext("encrypting compressed files is "
 354                             "unsupported"));
 355                 die(gettext("could not map file %s"), filename);
 356         }
 357         wait_until_dev_complete(minor);
 358         return (minor);
 359 }
 360 
 361 /*
 362  * Add a device association. If devicename is NULL, let the driver
 363  * pick a device.
 364  */
 365 static void
 366 add_mapping(int lfd, const char *devicename, const char *filename,
 367     mech_alias_t *cipher, const char *rkey, size_t rksz)
 368 {
 369         struct lofi_ioctl li;
 370 


 371         li.li_crypto_enabled = B_FALSE;
 372         if (cipher != NULL) {
 373                 /* set up encryption for mapped file */
 374                 li.li_crypto_enabled = B_TRUE;
 375                 (void) strlcpy(li.li_cipher, cipher->name,
 376                     sizeof (li.li_cipher));
 377                 if (rksz > sizeof (li.li_key)) {
 378                         die(gettext("key too large"));
 379                 }
 380                 bcopy(rkey, li.li_key, rksz);
 381                 li.li_key_len = rksz << 3;        /* convert to bits */
 382 
 383                 li.li_iv_type = cipher->iv_type;
 384                 li.li_iv_len = cipher->iv_len;       /* 0 when no iv needed */
 385                 switch (cipher->iv_type) {
 386                 case IVM_ENC_BLKNO:
 387                         (void) strlcpy(li.li_iv_cipher, cipher->iv_name,
 388                             sizeof (li.li_iv_cipher));
 389                         break;
 390                 case IVM_NONE:


 480         li.li_minor = name_to_minor(devicename);
 481         if (li.li_minor == 0) {
 482                 die(gettext("malformed device name %s\n"), devicename);
 483         }
 484         if (ioctl(lfd, LOFI_GET_FILENAME, &li) == -1) {
 485                 die(gettext("could not find filename for %s"), devicename);
 486         }
 487         (void) printf("%s\n", li.li_filename);
 488 }
 489 
 490 /*
 491  * Print the list of all the mappings, including a header.
 492  */
 493 static void
 494 print_mappings(int fd)
 495 {
 496         struct lofi_ioctl li;
 497         int     minor;
 498         int     maxminor;
 499         char    path[MAXPATHLEN];
 500         char    options[MAXPATHLEN];
 501 
 502         li.li_minor = 0;
 503         if (ioctl(fd, LOFI_GET_MAXMINOR, &li) == -1) {
 504                 die("ioctl");
 505         }
 506         maxminor = li.li_minor;
 507 
 508         (void) printf(FORMAT, gettext("Block Device"), gettext("File"),
 509             gettext("Options"));
 510         for (minor = 1; minor <= maxminor; minor++) {
 511                 li.li_minor = minor;
 512                 if (ioctl(fd, LOFI_GET_FILENAME, &li) == -1) {
 513                         if (errno == ENXIO)
 514                                 continue;
 515                         warn("ioctl");
 516                         break;
 517                 }
 518                 (void) snprintf(path, sizeof (path), "/dev/%s/%d",
 519                     LOFI_BLOCK_NAME, minor);



 520                 /*
 521                  * Encrypted lofi and compressed lofi are mutually exclusive.
 522                  */
 523                 if (li.li_crypto_enabled)
 524                         (void) snprintf(options, sizeof (options),
 525                             gettext("Encrypted"));
 526                 else if (li.li_algorithm[0] != '\0')
 527                         (void) snprintf(options, sizeof (options),
 528                             gettext("Compressed(%s)"), li.li_algorithm);
 529                 else










 530                         (void) snprintf(options, sizeof (options), "-");
 531 
 532                 (void) printf(FORMAT, path, li.li_filename, options);
 533         }
 534 }
 535 
 536 /*
 537  * Verify the cipher selected by user.
 538  */
 539 static mech_alias_t *
 540 ciph2mech(const char *alias)
 541 {
 542         int     i;
 543 
 544         for (i = 0; i < mech_aliases_count; i++) {
 545                 if (strcasecmp(alias, mech_aliases[i].alias) == 0)
 546                         return (&mech_aliases[i]);
 547         }
 548         return (NULL);
 549 }


1772         return (segsize);
1773 }
1774 
1775 int
1776 main(int argc, char *argv[])
1777 {
1778         int     lfd;
1779         int     c;
1780         const char *devicename = NULL;
1781         const char *filename = NULL;
1782         const char *algname = COMPRESS_ALGORITHM;
1783         int     openflag;
1784         int     minor;
1785         int     compress_index;
1786         uint32_t segsize = SEGSIZE;
1787         static char *lofictl = "/dev/" LOFI_CTL_NAME;
1788         boolean_t force = B_FALSE;
1789         const char *pname;
1790         boolean_t errflag = B_FALSE;
1791         boolean_t addflag = B_FALSE;

1792         boolean_t deleteflag = B_FALSE;
1793         boolean_t ephflag = B_FALSE;
1794         boolean_t compressflag = B_FALSE;
1795         boolean_t uncompressflag = B_FALSE;
1796         /* the next two work together for -c, -k, -T, -e options only */
1797         boolean_t need_crypto = B_FALSE;        /* if any -c, -k, -T, -e */
1798         boolean_t cipher_only = B_TRUE;         /* if -c only */
1799         const char *keyfile = NULL;
1800         mech_alias_t *cipher = NULL;
1801         token_spec_t *token = NULL;
1802         char    *rkey = NULL;
1803         size_t  rksz = 0;
1804         char realfilename[MAXPATHLEN];
1805 
1806         pname = getpname(argv[0]);
1807 
1808         (void) setlocale(LC_ALL, "");
1809         (void) textdomain(TEXT_DOMAIN);
1810 
1811         while ((c = getopt(argc, argv, "a:c:Cd:efk:o:s:T:U")) != EOF) {
1812                 switch (c) {
1813                 case 'a':
1814                         addflag = B_TRUE;
1815                         if ((filename = realpath(optarg, realfilename)) == NULL)
1816                                 die("%s", optarg);
1817                         if (((argc - optind) > 0) && (*argv[optind] != '-')) {
1818                                 /* optional device */
1819                                 devicename = argv[optind];
1820                                 optind++;
1821                         }
1822                         break;
1823                 case 'C':
1824                         compressflag = B_TRUE;
1825                         if (((argc - optind) > 1) && (*argv[optind] != '-')) {
1826                                 /* optional algorithm */
1827                                 algname = argv[optind];
1828                                 optind++;
1829                         }
1830                         check_algorithm_validity(algname, &compress_index);
1831                         break;


1846                                 devicename = optarg;
1847                         else {
1848                                 if ((filename = realpath(optarg,
1849                                     realfilename)) == NULL)
1850                                         die("%s", optarg);
1851                         }
1852                         break;
1853                 case 'e':
1854                         ephflag = B_TRUE;
1855                         need_crypto = B_TRUE;
1856                         cipher_only = B_FALSE;  /* need to unset cipher_only */
1857                         break;
1858                 case 'f':
1859                         force = B_TRUE;
1860                         break;
1861                 case 'k':
1862                         keyfile = optarg;
1863                         need_crypto = B_TRUE;
1864                         cipher_only = B_FALSE;  /* need to unset cipher_only */
1865                         break;



1866                 case 's':
1867                         segsize = convert_to_num(optarg);
1868                         if (segsize < DEV_BSIZE || !ISP2(segsize))
1869                                 die(gettext("segment size %s is invalid "
1870                                     "or not a multiple of minimum block "
1871                                     "size %ld\n"), optarg, DEV_BSIZE);
1872                         break;
1873                 case 'T':
1874                         if ((token = parsetoken(optarg)) == NULL) {
1875                                 errflag = B_TRUE;
1876                                 warn(
1877                                     gettext("invalid token key specifier %s\n"),
1878                                     optarg);
1879                         }
1880                         need_crypto = B_TRUE;
1881                         cipher_only = B_FALSE;  /* need to unset cipher_only */
1882                         break;
1883                 case 'U':
1884                         uncompressflag = B_TRUE;
1885                         break;
1886                 case '?':
1887                 default:
1888                         errflag = B_TRUE;
1889                         break;
1890                 }
1891         }
1892 
1893         /* Check for mutually exclusive combinations of options */
1894         if (errflag ||
1895             (addflag && deleteflag) ||

1896             (!addflag && need_crypto) ||
1897             ((compressflag || uncompressflag) && (addflag || deleteflag)))
1898                 usage(pname);
1899 
1900         /* ephemeral key, and key from either file or token are incompatible */
1901         if (ephflag && (keyfile != NULL || token != NULL)) {
1902                 die(gettext("ephemeral key cannot be used with keyfile"
1903                     " or token key\n"));
1904         }
1905 
1906         /*
1907          * "-c" but no "-k", "-T", "-e", or "-T -k" means derive key from
1908          * command line passphrase
1909          */
1910 
1911         switch (argc - optind) {
1912         case 0: /* no more args */
1913                 if (compressflag || uncompressflag)     /* needs filename */
1914                         usage(pname);
1915                 break;


1992 
1993                 init_crypto(token, cipher, &sess);
1994 
1995                 if (cipher_only) {
1996                         getkeyfromuser(cipher, &rkey, &rksz);
1997                 } else if (token != NULL) {
1998                         getkeyfromtoken(sess, token, keyfile, cipher,
1999                             &rkey, &rksz);
2000                 } else {
2001                         /* this also handles ephemeral keys */
2002                         getkeyfromfile(keyfile, cipher, &rkey, &rksz);
2003                 }
2004 
2005                 end_crypto(sess);
2006         }
2007 
2008         /*
2009          * Now to the real work.
2010          */
2011         if (addflag)
2012                 add_mapping(lfd, devicename, filename, cipher, rkey, rksz);

2013         else if (compressflag)
2014                 lofi_compress(&lfd, filename, compress_index, segsize);
2015         else if (uncompressflag)
2016                 lofi_uncompress(lfd, filename);
2017         else if (deleteflag)
2018                 delete_mapping(lfd, devicename, filename, force);
2019         else if (filename || devicename)
2020                 print_one_mapping(lfd, devicename, filename);
2021         else
2022                 print_mappings(lfd);
2023 
2024         if (lfd != -1)
2025                 (void) close(lfd);
2026         closelib();
2027         return (E_SUCCESS);
2028 }


  47 #include <unistd.h>
  48 #include <stropts.h>
  49 #include <libdevinfo.h>
  50 #include <libgen.h>
  51 #include <ctype.h>
  52 #include <dlfcn.h>
  53 #include <limits.h>
  54 #include <security/cryptoki.h>
  55 #include <cryptoutil.h>
  56 #include <sys/crypto/ioctl.h>
  57 #include <sys/crypto/ioctladmin.h>
  58 #include "utils.h"
  59 #include <LzmaEnc.h>
  60 
  61 /* Only need the IV len #defines out of these files, nothing else. */
  62 #include <aes/aes_impl.h>
  63 #include <des/des_impl.h>
  64 #include <blowfish/blowfish_impl.h>
  65 
  66 static const char USAGE[] =
  67         "Usage: %s [-r] -a file [ device ] "
  68         " [-c aes-128-cbc|aes-192-cbc|aes-256-cbc|des3-cbc|blowfish-cbc]"
  69         " [-e] [-k keyfile] [-T [token]:[manuf]:[serial]:key]\n"
  70         "       %s -d file | device\n"
  71         "       %s -C [gzip|gzip-6|gzip-9|lzma] [-s segment_size] file\n"
  72         "       %s -U file\n"
  73         "       %s [ file | device ]\n";
  74 
  75 typedef struct token_spec {
  76         char    *name;
  77         char    *mfr;
  78         char    *serno;
  79         char    *key;
  80 } token_spec_t;
  81 
  82 typedef struct mech_alias {
  83         char    *alias;
  84         CK_MECHANISM_TYPE type;
  85         char    *name;          /* for ioctl */
  86         char    *iv_name;       /* for ioctl */
  87         size_t  iv_len;         /* for ioctl */


 347 
 348         li.li_minor = 0;
 349         (void) strlcpy(li.li_filename, filename, sizeof (li.li_filename));
 350         minor = ioctl(lfd, LOFI_MAP_FILE, &li);
 351         if (minor == -1) {
 352                 if (errno == ENOTSUP)
 353                         warn(gettext("encrypting compressed files is "
 354                             "unsupported"));
 355                 die(gettext("could not map file %s"), filename);
 356         }
 357         wait_until_dev_complete(minor);
 358         return (minor);
 359 }
 360 
 361 /*
 362  * Add a device association. If devicename is NULL, let the driver
 363  * pick a device.
 364  */
 365 static void
 366 add_mapping(int lfd, const char *devicename, const char *filename,
 367     mech_alias_t *cipher, const char *rkey, size_t rksz, boolean_t rdonly)
 368 {
 369         struct lofi_ioctl li;
 370 
 371         li.li_readonly = rdonly;
 372 
 373         li.li_crypto_enabled = B_FALSE;
 374         if (cipher != NULL) {
 375                 /* set up encryption for mapped file */
 376                 li.li_crypto_enabled = B_TRUE;
 377                 (void) strlcpy(li.li_cipher, cipher->name,
 378                     sizeof (li.li_cipher));
 379                 if (rksz > sizeof (li.li_key)) {
 380                         die(gettext("key too large"));
 381                 }
 382                 bcopy(rkey, li.li_key, rksz);
 383                 li.li_key_len = rksz << 3;        /* convert to bits */
 384 
 385                 li.li_iv_type = cipher->iv_type;
 386                 li.li_iv_len = cipher->iv_len;       /* 0 when no iv needed */
 387                 switch (cipher->iv_type) {
 388                 case IVM_ENC_BLKNO:
 389                         (void) strlcpy(li.li_iv_cipher, cipher->iv_name,
 390                             sizeof (li.li_iv_cipher));
 391                         break;
 392                 case IVM_NONE:


 482         li.li_minor = name_to_minor(devicename);
 483         if (li.li_minor == 0) {
 484                 die(gettext("malformed device name %s\n"), devicename);
 485         }
 486         if (ioctl(lfd, LOFI_GET_FILENAME, &li) == -1) {
 487                 die(gettext("could not find filename for %s"), devicename);
 488         }
 489         (void) printf("%s\n", li.li_filename);
 490 }
 491 
 492 /*
 493  * Print the list of all the mappings, including a header.
 494  */
 495 static void
 496 print_mappings(int fd)
 497 {
 498         struct lofi_ioctl li;
 499         int     minor;
 500         int     maxminor;
 501         char    path[MAXPATHLEN];
 502         char    options[MAXPATHLEN] = { 0 };
 503 
 504         li.li_minor = 0;
 505         if (ioctl(fd, LOFI_GET_MAXMINOR, &li) == -1) {
 506                 die("ioctl");
 507         }
 508         maxminor = li.li_minor;
 509 
 510         (void) printf(FORMAT, gettext("Block Device"), gettext("File"),
 511             gettext("Options"));
 512         for (minor = 1; minor <= maxminor; minor++) {
 513                 li.li_minor = minor;
 514                 if (ioctl(fd, LOFI_GET_FILENAME, &li) == -1) {
 515                         if (errno == ENXIO)
 516                                 continue;
 517                         warn("ioctl");
 518                         break;
 519                 }
 520                 (void) snprintf(path, sizeof (path), "/dev/%s/%d",
 521                     LOFI_BLOCK_NAME, minor);
 522 
 523                 options[0] = '\0';
 524 
 525                 /*
 526                  * Encrypted lofi and compressed lofi are mutually exclusive.
 527                  */
 528                 if (li.li_crypto_enabled)
 529                         (void) snprintf(options, sizeof (options),
 530                             gettext("Encrypted"));
 531                 else if (li.li_algorithm[0] != '\0')
 532                         (void) snprintf(options, sizeof (options),
 533                             gettext("Compressed(%s)"), li.li_algorithm);
 534                 if (li.li_readonly) {
 535                         if (strlen(options) != 0) {
 536                                 (void) strlcat(options, ",", sizeof (options));
 537                                 (void) strlcat(options, "Readonly",
 538                                     sizeof (options));
 539                         } else {
 540                                 (void) snprintf(options, sizeof (options),
 541                                     gettext("Readonly"));
 542                         }
 543                 }
 544                 if (strlen(options) == 0)
 545                         (void) snprintf(options, sizeof (options), "-");
 546 
 547                 (void) printf(FORMAT, path, li.li_filename, options);
 548         }
 549 }
 550 
 551 /*
 552  * Verify the cipher selected by user.
 553  */
 554 static mech_alias_t *
 555 ciph2mech(const char *alias)
 556 {
 557         int     i;
 558 
 559         for (i = 0; i < mech_aliases_count; i++) {
 560                 if (strcasecmp(alias, mech_aliases[i].alias) == 0)
 561                         return (&mech_aliases[i]);
 562         }
 563         return (NULL);
 564 }


1787         return (segsize);
1788 }
1789 
1790 int
1791 main(int argc, char *argv[])
1792 {
1793         int     lfd;
1794         int     c;
1795         const char *devicename = NULL;
1796         const char *filename = NULL;
1797         const char *algname = COMPRESS_ALGORITHM;
1798         int     openflag;
1799         int     minor;
1800         int     compress_index;
1801         uint32_t segsize = SEGSIZE;
1802         static char *lofictl = "/dev/" LOFI_CTL_NAME;
1803         boolean_t force = B_FALSE;
1804         const char *pname;
1805         boolean_t errflag = B_FALSE;
1806         boolean_t addflag = B_FALSE;
1807         boolean_t rdflag = B_FALSE;
1808         boolean_t deleteflag = B_FALSE;
1809         boolean_t ephflag = B_FALSE;
1810         boolean_t compressflag = B_FALSE;
1811         boolean_t uncompressflag = B_FALSE;
1812         /* the next two work together for -c, -k, -T, -e options only */
1813         boolean_t need_crypto = B_FALSE;        /* if any -c, -k, -T, -e */
1814         boolean_t cipher_only = B_TRUE;         /* if -c only */
1815         const char *keyfile = NULL;
1816         mech_alias_t *cipher = NULL;
1817         token_spec_t *token = NULL;
1818         char    *rkey = NULL;
1819         size_t  rksz = 0;
1820         char realfilename[MAXPATHLEN];
1821 
1822         pname = getpname(argv[0]);
1823 
1824         (void) setlocale(LC_ALL, "");
1825         (void) textdomain(TEXT_DOMAIN);
1826 
1827         while ((c = getopt(argc, argv, "a:c:Cd:efk:o:rs:T:U")) != EOF) {
1828                 switch (c) {
1829                 case 'a':
1830                         addflag = B_TRUE;
1831                         if ((filename = realpath(optarg, realfilename)) == NULL)
1832                                 die("%s", optarg);
1833                         if (((argc - optind) > 0) && (*argv[optind] != '-')) {
1834                                 /* optional device */
1835                                 devicename = argv[optind];
1836                                 optind++;
1837                         }
1838                         break;
1839                 case 'C':
1840                         compressflag = B_TRUE;
1841                         if (((argc - optind) > 1) && (*argv[optind] != '-')) {
1842                                 /* optional algorithm */
1843                                 algname = argv[optind];
1844                                 optind++;
1845                         }
1846                         check_algorithm_validity(algname, &compress_index);
1847                         break;


1862                                 devicename = optarg;
1863                         else {
1864                                 if ((filename = realpath(optarg,
1865                                     realfilename)) == NULL)
1866                                         die("%s", optarg);
1867                         }
1868                         break;
1869                 case 'e':
1870                         ephflag = B_TRUE;
1871                         need_crypto = B_TRUE;
1872                         cipher_only = B_FALSE;  /* need to unset cipher_only */
1873                         break;
1874                 case 'f':
1875                         force = B_TRUE;
1876                         break;
1877                 case 'k':
1878                         keyfile = optarg;
1879                         need_crypto = B_TRUE;
1880                         cipher_only = B_FALSE;  /* need to unset cipher_only */
1881                         break;
1882                 case 'r':
1883                         rdflag = B_TRUE;
1884                         break;
1885                 case 's':
1886                         segsize = convert_to_num(optarg);
1887                         if (segsize < DEV_BSIZE || !ISP2(segsize))
1888                                 die(gettext("segment size %s is invalid "
1889                                     "or not a multiple of minimum block "
1890                                     "size %ld\n"), optarg, DEV_BSIZE);
1891                         break;
1892                 case 'T':
1893                         if ((token = parsetoken(optarg)) == NULL) {
1894                                 errflag = B_TRUE;
1895                                 warn(
1896                                     gettext("invalid token key specifier %s\n"),
1897                                     optarg);
1898                         }
1899                         need_crypto = B_TRUE;
1900                         cipher_only = B_FALSE;  /* need to unset cipher_only */
1901                         break;
1902                 case 'U':
1903                         uncompressflag = B_TRUE;
1904                         break;
1905                 case '?':
1906                 default:
1907                         errflag = B_TRUE;
1908                         break;
1909                 }
1910         }
1911 
1912         /* Check for mutually exclusive combinations of options */
1913         if (errflag ||
1914             (addflag && deleteflag) ||
1915             (rdflag && !addflag) ||
1916             (!addflag && need_crypto) ||
1917             ((compressflag || uncompressflag) && (addflag || deleteflag)))
1918                 usage(pname);
1919 
1920         /* ephemeral key, and key from either file or token are incompatible */
1921         if (ephflag && (keyfile != NULL || token != NULL)) {
1922                 die(gettext("ephemeral key cannot be used with keyfile"
1923                     " or token key\n"));
1924         }
1925 
1926         /*
1927          * "-c" but no "-k", "-T", "-e", or "-T -k" means derive key from
1928          * command line passphrase
1929          */
1930 
1931         switch (argc - optind) {
1932         case 0: /* no more args */
1933                 if (compressflag || uncompressflag)     /* needs filename */
1934                         usage(pname);
1935                 break;


2012 
2013                 init_crypto(token, cipher, &sess);
2014 
2015                 if (cipher_only) {
2016                         getkeyfromuser(cipher, &rkey, &rksz);
2017                 } else if (token != NULL) {
2018                         getkeyfromtoken(sess, token, keyfile, cipher,
2019                             &rkey, &rksz);
2020                 } else {
2021                         /* this also handles ephemeral keys */
2022                         getkeyfromfile(keyfile, cipher, &rkey, &rksz);
2023                 }
2024 
2025                 end_crypto(sess);
2026         }
2027 
2028         /*
2029          * Now to the real work.
2030          */
2031         if (addflag)
2032                 add_mapping(lfd, devicename, filename, cipher, rkey, rksz,
2033                     rdflag);
2034         else if (compressflag)
2035                 lofi_compress(&lfd, filename, compress_index, segsize);
2036         else if (uncompressflag)
2037                 lofi_uncompress(lfd, filename);
2038         else if (deleteflag)
2039                 delete_mapping(lfd, devicename, filename, force);
2040         else if (filename || devicename)
2041                 print_one_mapping(lfd, devicename, filename);
2042         else
2043                 print_mappings(lfd);
2044 
2045         if (lfd != -1)
2046                 (void) close(lfd);
2047         closelib();
2048         return (E_SUCCESS);
2049 }