1   /*
   2 |  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
   2 |  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
   3    * Use is subject to license terms.
   4    */
   5   
   6 | #pragma ident        "@(#)dump.c        1.9        04/09/08 SMI"
   6 | #pragma ident        "@(#)dump.c        1.8        04/05/04 SMI"
   7   
   8   /*
   9    * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
  10    *
  11    *        Openvision retains the copyright to derivative works of
  12    *        this source code.  Do *NOT* create a derivative of this
  13    *        source code before consulting with your legal department.
  14    *        Do *NOT* integrate *ANY* of this source code into another
  15    *        product before consulting with your legal department.
  16    *
  17    *        For further information, read the top-level Openvision
  18    *        copyright which is contained in the top-level MIT Kerberos
  19    *        copyright.
  20    *
  21    * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
  22    *
  23    */
  24   
  25   
  26   /*
  27    * admin/edit/dump.c
  28    *
  29    * Copyright 1990,1991 by the Massachusetts Institute of Technology.
  30    * All Rights Reserved.
  31    *
  32    * Export of this software from the United States of America may
  33    *   require a specific license from the United States Government.
  34    *   It is the responsibility of any person or organization contemplating
  35    *   export to obtain such a license before exporting.
  36    * 
  37    * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
  38    * distribute this software and its documentation for any purpose and
  39    * without fee is hereby granted, provided that the above copyright
  40    * notice appear in all copies and that both that copyright notice and
  41    * this permission notice appear in supporting documentation, and that
  42    * the name of M.I.T. not be used in advertising or publicity pertaining
  43    * to distribution of the software without specific, written prior
  44    * permission.  Furthermore if you modify this software you must label
  45    * your software as modified software and not distribute it in such a
  46    * fashion that it might be confused with the original M.I.T. software.
  47    * M.I.T. makes no representations about the suitability of
  48    * this software for any purpose.  It is provided "as is" without express
  49    * or implied warranty.
  50    * 
  51    *
  52    * Dump a KDC database
  53    */
  54   
  55   #define KDB5_DISPATCH
  56   #define KRB5_KDB5_DBM__
  57   #include <k5-int.h>
  58   /* #define these to avoid an indirection function; for future implementations,
  59      these may be redirected from a dispatch table/routine */
  60   /* SUNWresync121 - this appears to be an orig SEAM thang */
  61   #define krb5_dbm_db_set_name krb5_db_set_name
  62   #define krb5_dbm_db_set_nonblocking krb5_db_set_nonblocking
  63   #define krb5_dbm_db_init krb5_db_init
  64   #define krb5_dbm_db_get_age krb5_db_get_age
  65   #define krb5_dbm_db_create krb5_db_create
  66   #define krb5_dbm_db_rename krb5_db_rename
  67   #define krb5_dbm_db_get_principal krb5_db_get_principal
  68   #define krb5_dbm_db_free_principal krb5_db_free_principal
  69   #define krb5_dbm_db_put_principal krb5_db_put_principal
  70   #define krb5_dbm_db_delete_principal krb5_db_delete_principal
  71   #define krb5_dbm_db_lock krb5_db_lock
  72   #define krb5_dbm_db_unlock krb5_db_unlock
  73   #define krb5_dbm_db_set_lockmode krb5_db_set_lockmode
  74   #define krb5_dbm_db_close_database krb5_db_close_database
  75   #define krb5_dbm_db_open_database krb5_db_open_database
  76   #define krb5_dbm_db_iterate krb5_db_iterate
  77   
  78   #include <stdio.h>
  79   #include <com_err.h>
  80   #include <kadm5/admin.h>
  81   #include <kadm5/adb.h>
  82   #include <libintl.h>
  83   
  84   #include "kdb5_util.h"
  85   
  86   #if        HAVE_REGEX_H
  87   #include <regex.h>
  88   #endif        /* HAVE_REGEX_H */
  89   
  90   /*
  91    * Needed for master key conversion.
  92    */
  93   extern krb5_keyblock master_key;
  94   extern krb5_principal master_princ;
  95   extern int valid_master_key;
  96   extern void usage();
  97   static int                        mkey_convert;
  98   static krb5_keyblock                new_master_key;
  99   
 100   /*
 101    * Use compile(3) if no regcomp present.
 102    */
 103   #if        !defined(HAVE_REGCOMP) && defined(HAVE_REGEXP_H)
 104   #define        INIT                char *sp = instring;
 105   #define        GETC()                (*sp++)
 106   #define        PEEKC()                (*sp)
 107   #define        UNGETC(c)        (--sp)
 108   #define        RETURN(c)        return(c)
 109   #define        ERROR(c)        
 110   #define        RE_BUF_SIZE        1024
 111   #include <regexp.h>
 112   #endif        /* !HAVE_REGCOMP && HAVE_REGEXP_H */
 113   
 114   struct dump_args {
 115       char                *programname;
 116       FILE                *ofile;
 117       krb5_context        kcontext;
 118       char                **names;
 119       int                        nnames;
 120       int                        verbose;
 121   };
 122   
 123   static krb5_error_code dump_k5beta_iterator
 124   PROTOTYPE((krb5_pointer,
 125                                                          krb5_db_entry *));
 126   static krb5_error_code dump_k5beta6_iterator
 127   PROTOTYPE((krb5_pointer,
 128                                                           krb5_db_entry *));
 129 + static krb5_error_code dump_iprop_iterator
 130 + PROTOTYPE((krb5_pointer,
 131 +                                                         krb5_db_entry *));
 132   static krb5_error_code dump_k5beta7_princ
 133   PROTOTYPE((krb5_pointer,
 134                                                        krb5_db_entry *));
 135 + static krb5_error_code dump_iprop_princ
 136 + PROTOTYPE((krb5_pointer,
 137 +                                                      krb5_db_entry *));
 138   static krb5_error_code dump_ov_princ
 139   PROTOTYPE((krb5_pointer,
 140                                                   krb5_db_entry *));
 141   static void dump_k5beta7_policy PROTOTYPE((void *, osa_policy_ent_t));
 142   
 143   typedef
 144   krb5_error_code(*dump_func) PROTOTYPE((krb5_pointer,
 145                                                  krb5_db_entry *));
 146   
 147   static int process_k5beta_record
 148   PROTOTYPE((char *, krb5_context,
 149                                               FILE *, int, int *, void *));
 150   static int process_k5beta6_record
 151   PROTOTYPE((char *, krb5_context,
 152                                                FILE *, int, int *, void *));
 153   static int process_k5beta7_record
 154   PROTOTYPE((char *, krb5_context,
 155                                                FILE *, int, int *, void *));
 156   static int process_ov_record
 157   PROTOTYPE((char *, krb5_context,
 158                                           FILE *, int, int *, void *));
 159   typedef
 160   krb5_error_code(*load_func) PROTOTYPE((char *, krb5_context,
 161                                                  FILE *, int, int *, void *));
 162   
 163   typedef struct _dump_version {
 164        char *name;
 165        char *header;
 166        int updateonly;
 167        int create_kadm5;
 168        dump_func dump_princ;
 169        osa_adb_iter_policy_func dump_policy;
 170        load_func load_record;
 171   } dump_version;
 200 + dump_version iprop_version = {
 201 +      "Kerberos iprop version",
 202 +      "iprop",
 203 +      0,
 204 +      0,
 205 +      dump_iprop_princ,
 206 +      dump_k5beta7_policy,
 207 +      process_k5beta7_record,
 208 + };
 209   dump_version ov_version = {
 210        "OpenV*Secure V1.0",
 211        "OpenV*Secure V1.0\t",
 212        1,
 213        1,
 214        dump_ov_princ,
 215        dump_k5beta7_policy,
 216        process_ov_record,
 217   };
 218   
 219   /* External data */
 220   extern char                *current_dbname;
 221   extern krb5_boolean        dbactive;
 222   extern int                exit_status;
 223   extern krb5_context        util_context;
 224   extern kadm5_config_params global_params;
 225   
 226   /* Strings */
 227   
 228   static const char k5beta_dump_header[] = "kdb5_edit load_dump version 2.0\n";
 229   static const char k5beta6_dump_header[] = "kdb5_edit load_dump version 3.0\n";
 230   static const char k5beta7_dump_header[] = "kdb5_edit load_dump version 4\n";
 231   
 232   static const char null_mprinc_name[] = "kdb5_dump@MISSING";
 233   
 234   /*
 235    * We define gettext(s) to be s here, so that xgettext will extract the
 236    * strings to the .po file. At the end of the message section we will
 237    * undef gettext so that we can use it as a funtion.
 238    */
 239   
 240   #define        gettext(s) s
 241   
 242   /* Message strings */
 243   static const char regex_err[] =
 244           gettext("%s: regular expression error - %s\n");
 245   static const char regex_merr[] =
 246           gettext("%s: regular expression match error - %s\n");
 247   static const char pname_unp_err[] =
 248           gettext("%s: cannot unparse principal name (%s)\n");
 249   static const char mname_unp_err[] =
 250           gettext("%s: cannot unparse modifier name (%s)\n");
 251   static const char nokeys_err[] =
 252           gettext("%s: cannot find any standard key for %s\n");
 253   static const char sdump_tl_inc_err[] =
 254           gettext("%s: tagged data list inconsistency for %s "
 255                   "(counted %d, stored %d)\n");
 256   static const char stand_fmt_name[] =
 257           gettext("Kerberos version 5");
 258   static const char old_fmt_name[] =
 259           gettext("Kerberos version 5 old format");
 260   static const char b6_fmt_name[] =
 261           gettext("Kerberos version 5 beta 6 format");
 262   static const char ofopen_error[] =
 263           gettext("%s: cannot open %s for writing (%s)\n");
 264   static const char oflock_error[] =
 265           gettext("%s: cannot lock %s (%s)\n");
 266   static const char dumprec_err[] =
 267           gettext("%s: error performing %s dump (%s)\n");
 268   static const char dumphdr_err[] =
 269           gettext("%s: error dumping %s header (%s)\n");
 270   static const char trash_end_fmt[] =
 271           gettext("%s(%d): ignoring trash at end of line: ");
 272   static const char read_name_string[] =
 273           gettext("name string");
 274   static const char read_key_type[] =
 275           gettext("key type");
 276   static const char read_key_data[] =
 277           gettext("key data");
 278   static const char read_pr_data1[] =
 279           gettext("first set of principal attributes");
 280   static const char read_mod_name[] =
 281           gettext("modifier name");
 282   static const char read_pr_data2[] =
 283           gettext("second set of principal attributes");
 284   static const char read_salt_data[] =
 285           gettext("salt data");
 286   static const char read_akey_type[] =
 287           gettext("alternate key type");
 288   static const char read_akey_data[] =
 289           gettext("alternate key data");
 290   static const char read_asalt_type[] =
 291           gettext("alternate salt type");
 292   static const char read_asalt_data[] =
 293           gettext("alternate salt data");
 294   static const char read_exp_data[] =
 295           gettext("expansion data");
 296   static const char store_err_fmt[] =
 297           gettext("%s(%d): cannot store %s(%s)\n");
 298   static const char add_princ_fmt[] =
 299           gettext("%s\n");
 300   static const char parse_err_fmt[] =
 301           gettext("%s(%d): cannot parse %s (%s)\n");
 302   static const char read_err_fmt[] =
 303           gettext("%s(%d): cannot read %s\n");
 304   static const char no_mem_fmt[] =
 305           gettext("%s(%d): no memory for buffers\n");
 306   static const char rhead_err_fmt[] =
 307           gettext("%s(%d): cannot match size tokens\n");
 308   static const char err_line_fmt[] =
 309           gettext("%s: error processing line %d of %s\n");
 310   static const char head_bad_fmt[] =
 311           gettext("%s: dump header bad in %s\n");
 312   static const char read_bytecnt[] =
 313           gettext("record byte count");
 314   static const char read_encdata[] =
 315           gettext("encoded data");
 316   static const char n_name_unp_fmt[] =
 317           gettext("%s(%s): cannot unparse name\n");
 318   static const char n_dec_cont_fmt[] =
 319           gettext("%s(%s): cannot decode contents\n");
 320   static const char read_nint_data[] =
 321           gettext("principal static attributes");
 322   static const char read_tcontents[] =
 323           gettext("tagged data contents");
 324   static const char read_ttypelen[] =
 325           gettext("tagged data type and length");
 326   static const char read_kcontents[] =
 327           gettext("key data contents");
 328   static const char read_ktypelen[] =
 329           gettext("key data type and length");
 330   static const char read_econtents[] =
 331           gettext("extra data contents");
 332   static const char k5beta_fmt_name[] =
 333           gettext("Kerberos version 5 old format");
 334   static const char standard_fmt_name[] =
 335           gettext("Kerberos version 5 format");
 336   static const char no_name_mem_fmt[] =
 337           gettext("%s: cannot get memory for temporary name\n");
 338   static const char ctx_err_fmt[] =
 339           gettext("%s: cannot initialize Kerberos context\n");
 340   static const char stdin_name[] =
 341           gettext("standard input");
 342   static const char remaster_err_fmt[] = 
 343           gettext("while re-encoding keys for principal %s with new master key");
 344   static const char restfail_fmt[] =
 345           gettext("%s: %s restore failed\n");
 346   static const char close_err_fmt[] =
 347           gettext("%s: cannot close database (%s)\n");
 348   static const char dbinit_err_fmt[] =
 349           gettext("%s: cannot initialize database (%s)\n");
 350   static const char dblock_err_fmt[] =
 351           gettext("%s: cannot initialize database lock (%s)\n");
 352   static const char dbname_err_fmt[] =
 353           gettext("%s: cannot set database name to %s (%s)\n");
 354   static const char dbdelerr_fmt[] =
 355           gettext("%s: cannot delete bad database %s (%s)\n");
 356   static const char dbunlockerr_fmt[] =
 357           gettext("%s: cannot unlock database %s (%s)\n");
 358   static const char dbrenerr_fmt[] =
 359           gettext("%s: cannot rename database %s to %s (%s)\n");
 360   static const char dbcreaterr_fmt[] =
 361           gettext("%s: cannot create database %s (%s)\n");
 362   static const char dfile_err_fmt[] =
 363           gettext("%s: cannot open %s (%s)\n");
 364   
 365   /*
 366    * We now return you to your regularly scheduled program.
 367    */
 368   #undef gettext
 369   
 370   static const char oldoption[] = "-old";
 371   static const char b6option[] = "-b6";
 372 + static const char ipropoption[] = "-i";
 373   static const char verboseoption[] = "-verbose";
 374   static const char updateoption[] = "-update";
 375   static const char hashoption[] = "-hash";
 376   static const char ovoption[] = "-ov";
 377   static const char dump_tmptrail[] = "~";
 378   
 379   /*
 380    * Re-encrypt the key_data with the new master key...
 381    */
 382   krb5_error_code master_key_convert(context, db_entry)
 383       krb5_context          context;
 384       krb5_db_entry        * db_entry;
 385   {
 386       krb5_error_code        retval;
 387       krb5_keyblock         v5plainkey, *key_ptr;
 388       krb5_keysalt         keysalt;
 389       int              i;
 390       krb5_key_data        new_key_data, *key_data;
 391       krb5_boolean        is_mkey;
 392   
 393       is_mkey = krb5_principal_compare(context, master_princ, db_entry->princ);
 394   
 395       if (is_mkey && db_entry->n_key_data != 1)
 396               fprintf(stderr,
 397                       gettext(
 398                         "Master key db entry has %d keys, expecting only 1!\n"),
 399                       db_entry->n_key_data);
 400       for (i=0; i < db_entry->n_key_data; i++) {
 401           key_data = &db_entry->key_data[i];
 402           if (key_data->key_data_length == 0)
 403               continue;
 404           retval = krb5_dbekd_decrypt_key_data(context, &master_key,
 405                                                key_data, &v5plainkey,
 406                                                &keysalt);
 407           if (retval)
 408                   return retval;
 409   
 410           memset(&new_key_data, 0, sizeof(new_key_data));
 411           key_ptr = is_mkey ? &new_master_key : &v5plainkey;
 412           retval = krb5_dbekd_encrypt_key_data(context, &new_master_key,
 413                                                key_ptr, &keysalt,
 414                                                key_data->key_data_kvno,
 415                                                &new_key_data);
 416           if (retval)
 417                   return retval;
 418           krb5_free_keyblock_contents(context, &v5plainkey);
 419           free(key_data->key_data_contents);
 420           *key_data = new_key_data;
 421       }
 422       return 0;
 423   }
 974 + /*
 975 +  * dump_iprop_iterator()        - Output a dump record in iprop format.
 976 +  */
 977 + static krb5_error_code
 978 + dump_iprop_iterator(ptr, entry)
 979 +     krb5_pointer        ptr;
 980 +     krb5_db_entry        *entry;
 981 + {
 982 +     krb5_error_code        retval;
 983 +     struct dump_args        *arg;
 984 +     char                *name;
 985 +     krb5_tl_data        *tlp;
 986 +     krb5_key_data        *kdata;
 987 +     int                        counter, i, j;
 988   
 989 +     /* Initialize */
 990 +     arg = (struct dump_args *) ptr;
 991 +     name = (char *) NULL;
 992 + 
 993       /*
 994 +      * Flatten the principal name.
 995 +      */
 996 +     if ((retval = krb5_unparse_name(arg->kcontext,
 997 +                                     entry->princ,
 998 +                                     &name))) {
 999 +                 fprintf(stderr, gettext(pname_unp_err),
1000 +                 arg->programname, error_message(retval));
1001 +         return(retval);
1002 +     }
1003 + 
1004 +     /*
1005 +      * Re-encode the keys in the new master key, if necessary.
1006 +      */
1007 +     if (mkey_convert) {
1008 +         retval = master_key_convert(arg->kcontext, entry);
1009 +         if (retval) {
1010 +             com_err(arg->programname, retval, remaster_err_fmt, name);
1011 +             return retval;
1012 +         }
1013 +     }
1014 +     
1015 +     /*
1016 +      * If we don't have any match strings, or if our name matches, then
1017 +      * proceed with the dump, otherwise, just forget about it.
1018 +      */
1019 +     if (!arg->nnames || name_matches(name, arg)) {
1020 +         /*
1021 +          * We'd like to just blast out the contents as they would
1022 +          * appear in the database so that we can just suck it back
1023 +          * in, but it doesn't lend itself to easy editing.
1024 +          */
1025 + 
1026 +         /*
1027 +          * The dump format is as follows: len strlen(name)
1028 +          * n_tl_data n_key_data e_length name attributes max_life
1029 +          * max_renewable_life expiration pw_expiration last_success
1030 +          * last_failed fail_auth_count n_tl_data*[type length
1031 +          * <contents>] n_key_data*[ver kvno ver*(type length
1032 +          * <contents>)] <e_data> Fields which are not encapsulated
1033 +          * by angle-brackets are to appear verbatim.  Bracketed
1034 +          * fields absence is indicated by a -1 in its place
1035 +          */
1036 + 
1037 +         /*
1038 +          * Make sure that the tagged list is reasonably correct.
1039 +          */
1040 +         counter = 0;
1041 +         for (tlp = entry->tl_data; tlp; tlp = tlp->tl_data_next)
1042 +                   counter++;
1043 +         
1044 +         if (counter == entry->n_tl_data) {
1045 +             /* Pound out header */
1046 +             fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%s\t",
1047 +                     (int) entry->len,
1048 +                     strlen(name),
1049 +                     (int) entry->n_tl_data,
1050 +                     (int) entry->n_key_data,
1051 +                     (int) entry->e_length,
1052 +                     name);
1053 +             fprintf(arg->ofile, "%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t",
1054 +                     entry->attributes,
1055 +                     entry->max_life,
1056 +                     entry->max_renewable_life,
1057 +                     entry->expiration,
1058 +                     entry->pw_expiration,
1059 +                     entry->last_success,
1060 +                     entry->last_failed,
1061 +                     entry->fail_auth_count);
1062 +             /* Pound out tagged data. */
1063 +                         for (tlp = entry->tl_data; tlp;
1064 +                             tlp = tlp->tl_data_next) {
1065 +                 fprintf(arg->ofile, "%d\t%d\t",
1066 +                         (int) tlp->tl_data_type,
1067 +                         (int) tlp->tl_data_length);
1068 +                 if (tlp->tl_data_length)
1069 +                                         for (i = 0;
1070 +                                             i < tlp->tl_data_length;
1071 +                                             i++)
1072 +                                                 fprintf(arg->ofile, "%02x",
1073 +                                                         tlp->
1074 +                                                         tl_data_contents[i]);
1075 +                 else
1076 +                     fprintf(arg->ofile, "%d", -1);
1077 +                 fprintf(arg->ofile, "\t");
1078 +             }
1079 + 
1080 +             /* Pound out key data */
1081 +                         for (counter = 0;
1082 +                             counter < entry->n_key_data; counter++) {
1083 +                 kdata = &entry->key_data[counter];
1084 +                 fprintf(arg->ofile, "%d\t%d\t",
1085 +                         (int) kdata->key_data_ver,
1086 +                         (int) kdata->key_data_kvno);
1087 +                 for (i=0; i<kdata->key_data_ver; i++) {
1088 +                     fprintf(arg->ofile, "%d\t%d\t",
1089 +                             kdata->key_data_type[i],
1090 +                             kdata->key_data_length[i]);
1091 +                     if (kdata->key_data_length[i])
1092 +                                                 for (j = 0;
1093 +                                                     j < kdata->
1094 +                                                         key_data_length[i];
1095 +                                                     j++)
1096 +                                                         fprintf(arg->ofile,
1097 +                                                             "%02x",
1098 +                                                             kdata->
1099 +                                                             key_data_contents
1100 +                                                                 [i][j]);
1101 +                     else
1102 +                         fprintf(arg->ofile, "%d", -1);
1103 +                     fprintf(arg->ofile, "\t");
1104 +                 }
1105 +             }
1106 + 
1107 +             /* Pound out extra data */
1108 +             if (entry->e_length)
1109 +                 for (i=0; i<entry->e_length; i++)
1110 +                                         fprintf(arg->ofile, "%02x",
1111 +                                                 entry->e_data[i]);
1112 +             else
1113 +                 fprintf(arg->ofile, "%d", -1);
1114 + 
1115 +             /* Print trailer */
1116 +             fprintf(arg->ofile, ";\n");
1117 + 
1118 +             if (arg->verbose)
1119 +                 fprintf(stderr, "%s\n", name);
1120 +                 } else {
1121 +                         fprintf(stderr, gettext(sdump_tl_inc_err),
1122 +                     arg->programname, name, counter,
1123 +                     (int) entry->n_tl_data); 
1124 +             retval = EINVAL;
1125 +         }
1126 +     }
1127 +     krb5_xfree(name);
1128 +     return(retval);
1129 + }
1130 + 
1131 + /*
1132    * dump_k5beta7_iterator()        - Output a dump record in krb5b7 format.
1133    */
1134   static krb5_error_code
1135   dump_k5beta7_princ(ptr, entry)
1136       krb5_pointer        ptr;
1137       krb5_db_entry        *entry;
1138   {
1139        krb5_error_code retval;
1140        struct dump_args *arg;
1141        char *name;
1142        int tmp_nnames;
1143   
1144        /* Initialize */
1145        arg = (struct dump_args *) ptr;
1146        name = (char *) NULL;
1147   
1148        /*
1149         * Flatten the principal name.
1150         */
1151        if ((retval = krb5_unparse_name(arg->kcontext,
1152                                        entry->princ,
1153                                        &name))) {
1154                   fprintf(stderr, gettext(pname_unp_err),
1155                     arg->programname, error_message(retval));
1156             return(retval);
1157        }
1158        /*
1159         * If we don't have any match strings, or if our name matches, then
1160         * proceed with the dump, otherwise, just forget about it.
1161         */
1162        if (!arg->nnames || name_matches(name, arg)) {
1163             fprintf(arg->ofile, "princ\t");
1164             
1165             /* save the callee from matching the name again */
1166             tmp_nnames = arg->nnames;
1167             arg->nnames = 0;
1168             retval = dump_k5beta6_iterator(ptr, entry);
1169             arg->nnames = tmp_nnames;
1170        }
1171        free(name);
1172           return (retval);
1173   }
1174   
1175 + /*
1176 +  * dump_iprop_princ()        - Output a dump record in iprop format.
1177 +  * This was created in order to dump more data, such as kadm5 tl
1178 +  */
1179 + static krb5_error_code
1180 + dump_iprop_princ(ptr, entry)
1181 +     krb5_pointer        ptr;
1182 +     krb5_db_entry        *entry;
1183 + {
1184 +      krb5_error_code retval;
1185 +      struct dump_args *arg;
1186 +      char *name;
1187 +      int tmp_nnames;
1188 + 
1189 +      /* Initialize */
1190 +      arg = (struct dump_args *) ptr;
1191 +      name = (char *) NULL;
1192 + 
1193 +      /*
1194 +       * Flatten the principal name.
1195 +       */
1196 +      if ((retval = krb5_unparse_name(arg->kcontext,
1197 +                                      entry->princ,
1198 +                                      &name))) {
1199 +                 fprintf(stderr, gettext(pname_unp_err),
1200 +                   arg->programname, error_message(retval));
1201 +           return(retval);
1202 +      }
1203 +      /*
1204 +       * If we don't have any match strings, or if our name matches, then
1205 +       * proceed with the dump, otherwise, just forget about it.
1206 +       */
1207 +      if (!arg->nnames || name_matches(name, arg)) {
1208 +           fprintf(arg->ofile, "princ\t");
1209 +           
1210 +           /* save the callee from matching the name again */
1211 +           tmp_nnames = arg->nnames;
1212 +           arg->nnames = 0;
1213 +           retval = dump_iprop_iterator(ptr, entry);
1214 +           arg->nnames = tmp_nnames;
1215 +      }
1216 +      free(name);
1217 +         return (retval);
1218 + }
1219   void
1220   dump_k5beta7_policy(void *data, osa_policy_ent_t entry)
1221   {
1222        struct dump_args *arg;
1223   
1224        arg = (struct dump_args *) data;
1225        fprintf(arg->ofile, "policy\t%s\t%d\t%d\t%d\t%d\t%d\t%d\n", entry->name,
1226                entry->pw_min_life, entry->pw_max_life, entry->pw_min_length,
1227                entry->pw_min_classes, entry->pw_history_num,
1228                entry->policy_refcnt);
1229   }

 ----Unchanged portion omitted----

1342   
1343   /*
1344    * usage is:
1345    *        dump_db [-i] [-old] [-b6] [-ov] [-verbose] [filename [principals...]]
1346    */
1347   void
1348   dump_db(argc, argv)
1349       int                argc;
1350       char        **argv;
1351   {
1352       FILE                *f;
1353       struct dump_args        arglist;
1354       int                        error;
1355       char                *programname;
1356       char                *ofile;
1357       krb5_error_code        kret, retval;
1358       dump_version        *dump;
1359       int                        aindex;
1360       krb5_boolean        locked;
1361       extern osa_adb_policy_t policy_db;
1362       char                *new_mkey_file = 0;
1363 +     bool_t                dump_sno = FALSE;
1364 +     kdb_log_context        *log_ctx;
1365           
1366       /*
1367        * Parse the arguments.
1368        */
1369       programname = argv[0];
1370       if (strrchr(programname, (int) '/'))
1371           programname = strrchr(argv[0], (int) '/') + 1;
1372       ofile = (char *) NULL;
1373       error = 0;
1374       dump = &beta7_version;
1375       arglist.verbose = 0;
1376       new_mkey_file = 0;
1377       mkey_convert = 0;
1378 +     log_ctx = util_context->kdblog_context;
1379   
1380       /*
1381        * Parse the qualifiers.
1382        */
1383       for (aindex = 1; aindex < argc; aindex++) {
1384                   if (strcmp(argv[aindex], oldoption) == 0)
1385                dump = &old_version;
1386                   else if (strcmp(argv[aindex], b6option) == 0)
1387                dump = &beta6_version;
1388                   else if (strcmp(argv[aindex], ovoption) == 0)
1389                dump = &ov_version;
1390 +                 else if (!strcmp(argv[aindex], ipropoption)) {
1391 +                         if (log_ctx && log_ctx->iproprole) {
1392 +                                 dump = &iprop_version;
1393 +                                 /*
1394 +                                  * dump_sno is used to indicate if the serial
1395 +                                  * # should be populated in the output
1396 +                                  * file to be used later by iprop for updating
1397 +                                  * the slave's update log when loading
1398 +                                  */
1399 +                                 dump_sno = TRUE;
1400 +                         } else {
1401 +                                 fprintf(stderr, gettext("Iprop not enabled\n"));
1402 +                                 exit_status++;
1403 +                                 return;
1404 +                         }
1405 +                 }
1406                   else if (strcmp(argv[aindex], verboseoption) == 0)
1407               arglist.verbose++;
1408           else if (!strcmp(argv[aindex], "-mkey_convert"))
1409               mkey_convert = 1;
1410           else if (!strcmp(argv[aindex], "-new_mkey_file")) {
1411               new_mkey_file = argv[++aindex];
1412               mkey_convert = 1;
1413           } else
1414               break;
1415       }
1416   
1417       arglist.names = (char **) NULL;
1418       arglist.nnames = 0;
1419       if (aindex < argc) {
1420           ofile = argv[aindex];
1421           aindex++;
1422           if (aindex < argc) {
1423               arglist.names = &argv[aindex];
1424               arglist.nnames = argc - aindex;
1425           }
1426       }
1427   
1428       /*
1429        * Make sure the database is open.  The policy database only has
1430        * to be opened if we try a dump that uses it.
1431        */
1432       if (!dbactive || (dump->dump_policy != NULL && policy_db == NULL)) {
1433           com_err(argv[0], 0, Err_no_database);
1434           exit_status++;
1435           return;
1436       }
1437   
1438       /*
1439        * If we're doing a master key conversion, set up for it.
1440        */
1441       if (mkey_convert) {
1442               if (!valid_master_key) {
1443                       /* TRUE here means read the keyboard, but only once */
1444                       retval = krb5_db_fetch_mkey(util_context,
1445                                                   master_princ,
1446                                                   global_params.enctype,
1447                                                   TRUE, FALSE,
1448                                                   (char *) NULL, 0,
1449                                                   &master_key);
1450                       if (retval) {
1451                               com_err(argv[0], retval,
1452                                       gettext("while reading master key"));
1453                               exit(1);
1454                       }
1455                       retval = krb5_db_verify_master_key(util_context,
1456                                                          master_princ,
1457                                                          &master_key);
1458                       if (retval) {
1459                               com_err(argv[0], retval,
1460                                       gettext("while verifying master key"));
1461                               exit(1);
1462                       }
1463               }
1464               if (!new_mkey_file)
1465                       printf(gettext("Please enter new master key....\n"));
1466   
1467               if ((retval = krb5_db_fetch_mkey(util_context, master_princ, 
1468                                                global_params.enctype,
1469                                                !new_mkey_file, TRUE, 
1470                                                new_mkey_file, 0,
1471                                                &new_master_key))) { 
1472                       com_err(argv[0], retval,
1473                               gettext("while reading new master key"));
1474                       exit(1);
1475               }
1476       }
1477   
1478       kret = 0;
1479       locked = 0;
1480       if (ofile && strcmp(ofile, "-")) {
1481           /*
1482            * Make sure that we don't open and truncate on the fopen,
1483            * since that may hose an on-going kprop process.
1484            * 
1485            * We could also control this by opening for read and write,
1486            * doing an flock with LOCK_EX, and then truncating the
1487            * file once we have gotten the lock, but that would
1488            * involve more OS dependencies than I want to get into.
1489            */
1490           unlink(ofile);
1491           if (!(f = fopen(ofile, "w"))) {
1492                           fprintf(stderr, gettext(ofopen_error),
1493                       programname, ofile, error_message(errno));
1494               exit_status++;
1495               return;
1496          }
1497           if ((kret = krb5_lock_file(util_context,
1498                                      fileno(f),
1499                                      KRB5_LOCKMODE_EXCLUSIVE))) {
1500                           fprintf(stderr, gettext(oflock_error),
1501                       programname, ofile, error_message(kret));
1502               exit_status++;
1503                   } else
1504               locked = 1;
1505       } else {
1506           f = stdout;
1507       }
1508       if (f && !(kret)) {
1509           arglist.programname = programname;
1510           arglist.ofile = f;
1511           arglist.kcontext = util_context;
1512           fprintf(arglist.ofile, "%s", dump->header);
1513   
1514 +         if (dump_sno) {
1515 +                 if (ulog_map(util_context, &global_params, FKCOMMAND)) {
1516 +                         fprintf(stderr,
1517 +                             gettext("%s: Could not map log\n"), programname);
1518 +                         exit_status++;
1519 +                         goto error;
1520 +                 }
1521 + 
1522 +                 /*
1523 +                  * We grab the lock twice (once again in the iterator call),
1524 +                  * but that's ok since the lock func handles incr locks held.
1525 +                  */
1526 +                 if (krb5_db_lock(util_context, KRB5_LOCKMODE_SHARED)) {
1527 +                         fprintf(stderr,
1528 +                             gettext("%s: Couldn't grab lock\n"), programname);
1529 +                         exit_status++;
1530 +                         goto error;
1531 +                 }
1532 + 
1533 +                 fprintf(f, " %u", log_ctx->ulog->kdb_last_sno);
1534 +                 fprintf(f, " %u", log_ctx->ulog->kdb_last_time.seconds);
1535 +                 fprintf(f, " %u", log_ctx->ulog->kdb_last_time.useconds);
1536 +         }
1537 + 
1538           if (dump->header[strlen(dump->header)-1] != '\n')
1539                fputc('\n', arglist.ofile);
1540           
1541                   if ((kret = krb5_dbm_db_iterate(util_context,
1542                                       dump->dump_princ,
1543                                       (krb5_pointer) &arglist))) {
1544                           fprintf(stderr, gettext(dumprec_err),
1545                        programname, dump->name, error_message(kret));
1546                exit_status++;
1547 +                 if (dump_sno)
1548 +                         (void) krb5_db_unlock(util_context);
1549           }
1550           if (dump->dump_policy &&
1551               (kret = osa_adb_iter_policy(policy_db, dump->dump_policy,
1552                                           &arglist))) { 
1553                           fprintf(stderr, gettext(dumprec_err),
1554                               programname, dump->name,
1555                        error_message(kret));
1556                exit_status++;
1557           }
1558   
1559   error:
1560           if (ofile && f != stdout && !exit_status) {
1561                fclose(f);
1562                update_ok_file(ofile);
1563           }
1564       }
1565       if (locked)
1566                   (void) krb5_lock_file(util_context,
1567                                       fileno(f), KRB5_LOCKMODE_UNLOCK);
1568   }

 ----Unchanged portion omitted----

2558   
2559   /*
2560    * Usage: load_db [-i] [-old] [-ov] [-b6] [-verbose] [-update] [-hash] filename
2561    */
2562   void
2563   load_db(argc, argv)
2564       int                argc;
2565       char        **argv;
2566   {
2567       kadm5_config_params newparams;
2568       osa_adb_policy_t        tmppol_db;
2569       krb5_error_code        kret;
2570       krb5_context        kcontext;
2571       FILE                *f;
2572       extern char                *optarg;
2573       extern int                optind;
2574       char                *programname;
2575       char                *dumpfile;
2576       char                *dbname;
2577       char                *dbname_tmp;
2578       char                buf[BUFSIZ];
2579       dump_version        *load;
2580       int                        update, verbose;
2581       krb5_int32                crflags;
2582       int                        aindex;
2583       bool_t                add_update = TRUE;
2584 +     char                iheader[MAX_HEADER];
2585       uint32_t                caller, last_sno, last_seconds, last_useconds;
2586 +     kdb_log_context        *log_ctx;
2587   
2588       /*
2589        * Parse the arguments.
2590        */
2591       programname = argv[0];
2592       if (strrchr(programname, (int) '/'))
2593           programname = strrchr(argv[0], (int) '/') + 1;
2594       dumpfile = (char *) NULL;
2595       dbname = global_params.dbname;
2596       load = NULL;
2597       update = 0;
2598       verbose = 0;
2599       crflags = KRB5_KDB_CREATE_BTREE;
2600       exit_status = 0;
2601       dbname_tmp = (char *) NULL;
2602       tmppol_db = NULL;
2603 +     log_ctx = util_context->kdblog_context;
2604 + 
2605       for (aindex = 1; aindex < argc; aindex++) {
2606                   if (strcmp(argv[aindex], oldoption) == 0)
2607                load = &old_version;
2608                   else if (strcmp(argv[aindex], b6option) == 0)
2609                load = &beta6_version;
2610                   else if (strcmp(argv[aindex], ovoption) == 0)
2611                load = &ov_version;
2612 +                 else if (!strcmp(argv[aindex], ipropoption)) {
2613 +                         if (log_ctx && log_ctx->iproprole) {
2614 +                                 load = &iprop_version;
2615 +                                 add_update = FALSE;
2616 +                         } else {
2617 +                                 fprintf(stderr, gettext("Iprop not enabled\n"));
2618 +                                 exit_status++;
2619 +                                 return;
2620 +                         }
2621                   } else if (strcmp(argv[aindex], verboseoption) == 0)
2622               verbose = 1;
2623                   else if (strcmp(argv[aindex], updateoption) == 0)
2624               update = 1;
2625           else if (!strcmp(argv[aindex], hashoption))
2626               crflags = KRB5_KDB_CREATE_HASH;
2627           else
2628               break;
2629       }
2630       if ((argc - aindex) != 1) {
2631           usage();
2632           return;
2633       }
2634       dumpfile = argv[aindex];
2635   
2636       if (!(dbname_tmp = (char *) malloc(strlen(dbname)+
2637                                          strlen(dump_tmptrail)+1))) {
2638                   fprintf(stderr, gettext(no_name_mem_fmt), argv[0]);
2639           exit_status++;
2640           return;
2641       }
2642       strcpy(dbname_tmp, dbname);
2643       strcat(dbname_tmp, dump_tmptrail);
2644   
2645       /*
2646        * Initialize the Kerberos context and error tables.
2647        */
2648       if ((kret = krb5_init_context(&kcontext))) {
2649                   fprintf(stderr, gettext(ctx_err_fmt), programname);
2650           free(dbname_tmp);
2651           exit_status++;
2652           return;
2653       }
2654 + 
2655 +     if (log_ctx && log_ctx->iproprole)
2656 +         kcontext->kdblog_context = (void *)log_ctx;
2657 + 
2658       /*
2659        * Open the dumpfile
2660        */
2661       if (dumpfile) {
2662           if ((f = fopen(dumpfile, "r+")) == NULL) {
2663                           fprintf(stderr, gettext(dfile_err_fmt),
2664                               programname, dumpfile,
2665                        error_message(errno)); 
2666                exit_status++;
2667                return;
2668           }
2669           if ((kret = krb5_lock_file(kcontext, fileno(f),
2670                                      KRB5_LOCKMODE_SHARED))) {
2671                fprintf(stderr, gettext("%s: Cannot lock %s: %s\n"), programname,
2672                        dumpfile, error_message(errno));
2673                exit_status++;
2674                return;
2675           }
2676       } else
2677           f = stdin;
2678   
2679       /*
2680            * Auto-detect dump version if we weren't told, verify if we were
2681            * told.
2682        */
2683       fgets(buf, sizeof(buf), f);
2684       if (load) {
2685                   /*
2686                    * only check what we know; some headers only contain a
2687                    * prefix
2688                    */
2689            if (strncmp(buf, load->header, strlen(load->header)) != 0) {
2690                           fprintf(stderr, gettext(head_bad_fmt),
2691                               programname, dumpfile);
2692                 exit_status++;
2693                           if (dumpfile)
2694                                   fclose(f);
2695                 return;
2696            }
2697       } else {
2698            /* perhaps this should be in an array, but so what? */
2699            if (strcmp(buf, old_version.header) == 0)
2700                 load = &old_version;
2701            else if (strcmp(buf, beta6_version.header) == 0)
2702                 load = &beta6_version;
2703            else if (strcmp(buf, beta7_version.header) == 0)
2704                 load = &beta7_version;
2705            else if (strncmp(buf, ov_version.header,
2706                             strlen(ov_version.header)) == 0)
2707                 load = &ov_version;
2708           else {
2709                           fprintf(stderr, gettext(head_bad_fmt),
2710                                   programname, dumpfile);
2711                 exit_status++;
2712                           if (dumpfile)
2713                                   fclose(f);
2714                 return;
2715            }
2716       }
2717       if (load->updateonly && !update) {
2718                   fprintf(stderr,
2719                       gettext("%s: dump version %s can only "
2720                           "be loaded with the -update flag\n"),
2721                       programname, load->name);
2722            exit_status++;
2723            return;
2724       }
2725       /*
2726        * Cons up params for the new databases.  If we are not in update
2727        * mode use a temp name that we'll rename later.
2728        */
2729       newparams = global_params;
2730       if (! update) {
2731            newparams.mask |= KADM5_CONFIG_DBNAME;
2732            newparams.dbname = dbname_tmp;
2733   
2734            if ((kret = kadm5_get_config_params(kcontext, NULL, NULL,
2735                                                &newparams, &newparams))) {
2736                 com_err(argv[0], kret,
2737                               gettext("while retreiving new "
2738                                   "configuration parameters"));
2739                 exit_status++;
2740                 return;
2741            }
2742       }
2743       /*
2744        * If not an update restoration, create the temp database.  Always
2745        * create a temp policy db, even if we are not loading a dump file
2746        * with policy info, because they may be loading an old dump
2747        * intending to use it with the new kadm5 system.
2748        */
2749       if (!update && ((kret = krb5_db_create(kcontext, dbname_tmp, crflags)))) {
2750            fprintf(stderr, gettext(dbcreaterr_fmt),
2751                    programname, dbname_tmp, error_message(kret));
2752            exit_status++;
2753            kadm5_free_config_params(kcontext, &newparams);
2754            if (dumpfile) fclose(f);
2755            return;
2756       }
2757       if (!update && (kret = osa_adb_create_policy_db(&newparams))) {
2758                   fprintf(stderr,
2759                           gettext("%s: %s while creating policy database\n"),
2760                    programname, error_message(kret));
2761            exit_status++;
2762            kadm5_free_config_params(kcontext, &newparams);
2763                   if (dumpfile)
2764                           fclose(f);
2765            return;
2766       }
2767       /*
2768        * Point ourselves at the new databases.
2769        */
2770           if ((kret = krb5_db_set_name(kcontext,
2771                   (update) ? dbname : dbname_tmp))) {
2772                   fprintf(stderr, gettext(dbname_err_fmt),
2773                    programname, 
2774                    (update) ? dbname : dbname_tmp, error_message(kret));
2775            exit_status++;
2776            goto error;
2777       }
2778           if ((kret = osa_adb_open_policy(&tmppol_db, &newparams))) {
2779                   fprintf(stderr,
2780                           gettext("%s: %s while opening policy database\n"),
2781                    programname, error_message(kret));
2782            exit_status++;
2783            goto error;
2784       }
2785       /*
2786        * If an update restoration, make sure the db is left unusable if
2787        * the update fails.
2788        */
2789       if (update) {
2790                   if ((kret = osa_adb_get_lock(tmppol_db, OSA_ADB_PERMANENT))) {
2791                           fprintf(stderr,
2792                               gettext("%s: %s while "
2793                                       "permanently locking database\n"),
2794                         programname, error_message(kret));
2795                 exit_status++;
2796                 goto error;
2797            }
2798       }
2799                         
2800       /*
2801        * Initialize the database.
2802        */
2803           if ((kret = krb5_db_init(kcontext))) {
2804                   fprintf(stderr, gettext(dbinit_err_fmt),
2805                    programname, error_message(kret));
2806            exit_status++;
2807            goto error;
2808       }
2809       /* 
2810        * grab an extra lock, since there are no other users
2811        */
2812       if (!update) {
2813            kret = krb5_db_lock(kcontext, KRB5_LOCKMODE_EXCLUSIVE);
2814            if (kret) {
2815                           fprintf(stderr, gettext(dblock_err_fmt),
2816                            programname, error_message(kret));
2817                    exit_status++;
2818                    goto error;
2819            }
2820       }
2821 + 
2822 +         if (log_ctx && log_ctx->iproprole) {
2823 +                 if (add_update)
2824 +                         caller = FKCOMMAND;
2825 +                 else
2826 +                         caller = FKPROPD;
2827 + 
2828 +                 if (ulog_map(kcontext, &global_params, caller)) {
2829 +                         fprintf(stderr,
2830 +                                 gettext("%s: Could not map log\n"),
2831 +                                 programname);
2832 +                         exit_status++;
2833 +                         goto error;
2834 +                 }
2835 + 
2836 +                 /*
2837 +                  * We don't want to take out the ulog out from underneath
2838 +                  * kadmind so we reinit the header log.
2839 +                  *
2840 +                  * We also don't want to add to the update log since we
2841 +                  * are doing a whole sale replace of the db, because:
2842 +                  *         we could easily exceed # of update entries
2843 +                  *         we could implicity delete db entries during a replace
2844 +                  *        no advantage in incr updates when entire db is replaced
2845 +                  */
2846 +                 if (!update) {
2847 +                         memset(log_ctx->ulog, 0, sizeof (kdb_hlog_t));
2848 +  
2849 +                         log_ctx->ulog->kdb_hmagic = KDB_HMAGIC;
2850 +                         log_ctx->ulog->db_version_num = KDB_VERSION;
2851 +                         log_ctx->ulog->kdb_state = KDB_STABLE;
2852 +                         log_ctx->ulog->kdb_block = ULOG_BLOCK;
2853 + 
2854 +                         log_ctx->iproprole = IPROP_NULL;
2855 + 
2856 +                         if (!add_update) {
2857 +                                 sscanf(buf, "%s %u %u %u", iheader, &last_sno,
2858 +                                         &last_seconds, &last_useconds);
2859 + 
2860 +                                 log_ctx->ulog->kdb_last_sno = last_sno;
2861 +                                 log_ctx->ulog->kdb_last_time.seconds =
2862 +                                     last_seconds;
2863 +                                 log_ctx->ulog->kdb_last_time.useconds =
2864 +                                     last_useconds;
2865 +                         }
2866 +                 }
2867 +         }
2868   
2869           if (restore_dump(programname, kcontext,
2870                           (dumpfile) ? dumpfile : stdin_name,
2871                        f, verbose, load, tmppol_db)) {
2872                   fprintf(stderr, gettext(restfail_fmt),
2873                    programname, load->name);
2874            exit_status++;
2875       }
2876       if (!update && (kret = krb5_db_unlock(kcontext))) {
2877            /* change this error? */
2878                   fprintf(stderr, gettext(dbunlockerr_fmt),
2879                    programname, dbname_tmp, error_message(kret));
2880            exit_status++;
2881       }
2882           if ((kret = krb5_db_fini(kcontext))) {
2883                   fprintf(stderr, gettext(close_err_fmt),
2884                    programname, error_message(kret));
2885            exit_status++;
2886       }
2887   
2888       if (!update && load->create_kadm5 &&
2889               ((kret = kadm5_create_magic_princs(&newparams, kcontext)))) {
2890            /* error message printed by create_magic_princs */
2891            exit_status++;
2892       }
2893       
2894       /* close policy db below */
2895   
2896   error:
2897       /*
2898            * If not an update: if there was an error, destroy the temp
2899            * database, otherwise rename it into place.
2900        *
2901        * If an update: if there was no error, unlock the database.
2902        */
2903       if (!update) {
2904            if (exit_status) {
2905                           if ((kret =
2906                                   krb5_db_destroy(kcontext, dbname_tmp))) {
2907                                   fprintf(stderr, gettext(dbdelerr_fmt),
2908                                           programname, dbname_tmp,
2909                                           error_message(kret));
2910                      exit_status++;
2911                 }
2912                           if ((kret = osa_adb_destroy_policy_db(&newparams))) {
2913                                   fprintf(stderr,
2914                                           gettext("%s: %s while destroying "
2915                                                   "policy database\n"),
2916                              programname, error_message(kret));
2917                      exit_status++;
2918                 }
2919                   } else {
2920                 if ((kret = krb5_db_rename(kcontext,
2921                                            dbname_tmp,
2922                                            dbname))) {
2923                                   fprintf(stderr, gettext(dbrenerr_fmt),
2924                              programname, dbname_tmp, dbname,
2925                              error_message(kret));
2926                      exit_status++;
2927                 } 
2928                           if ((kret = osa_adb_close_policy(tmppol_db))) {
2929                                   fprintf(stderr, gettext(close_err_fmt),
2930                              programname, error_message(kret));
2931                      exit_status++;
2932                 }
2933                           if ((kret = osa_adb_rename_policy_db(&newparams,
2934                                   &global_params))) {
2935                      fprintf(stderr,
2936                                       gettext("%s: %s while renaming "
2937                                           "policy db %s to %s\n"),
2938                              programname, error_message(kret),
2939                              newparams.admin_dbname,
2940                              global_params.admin_dbname);
2941                      exit_status++;
2942                 }
2943            }
2944           } else {           /* update */
2945                   if (!exit_status && ((kret = osa_adb_release_lock(tmppol_db)))) {
2946                           fprintf(stderr,
2947                               gettext("%s: %s while releasing permanent lock\n"),
2948                         programname, error_message(kret));
2949                 exit_status++;
2950            }
2951                   if (tmppol_db && ((kret = osa_adb_close_policy(tmppol_db)))) {
2952                           fprintf(stderr, gettext(close_err_fmt),
2953                         programname, error_message(kret));
2954                 exit_status++;
2955            }
2956       }
2957   
2958       if (dumpfile) {
2959                   (void) krb5_lock_file(kcontext,
2960                                       fileno(f), KRB5_LOCKMODE_UNLOCK);
2961            fclose(f);
2962       }
2963       if (dbname_tmp)
2964            free(dbname_tmp);
2965       krb5_free_context(kcontext);
2966   }

 ----Unchanged portion omitted----