Annotation of 43BSDReno/kerberosIV/kdb/krb_dbm.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * $Source: /usr/src/kerberosIV/kdb/RCS/krb_dbm.c,v $
                      3:  * $Author: kfall $ 
                      4:  *
                      5:  * Copyright 1988 by the Massachusetts Institute of Technology. 
                      6:  *
                      7:  * For copying and distribution information, please see the file
                      8:  * <mit-copyright.h>. 
                      9:  */
                     10: 
                     11: #ifndef        lint
                     12: static char rcsid_krb_dbm_c[] =
                     13: "$Header: /usr/src/kerberosIV/kdb/RCS/krb_dbm.c,v 4.10 90/06/25 20:52:39 kfall Exp $";
                     14: #endif lint
                     15: 
                     16: #include <sys/types.h>
                     17: #include <sys/uio.h>
                     18: #include <sys/time.h>
                     19: #include <sys/stat.h>
                     20: #include <sys/resource.h>
                     21: #include <sys/errno.h>
                     22: #include <sys/file.h>
                     23: #include <netinet/in.h>
                     24: #include <mit-copyright.h>
                     25: #include <stdio.h>
                     26: #include <string.h>
                     27: #include <des.h>
                     28: #include <krb.h>
                     29: #include <krb_db.h>
                     30: #include <ndbm.h>
                     31: 
                     32: #define KERB_DB_MAX_RETRY 5
                     33: 
                     34: #ifdef DEBUG
                     35: extern int debug;
                     36: extern long kerb_debug;
                     37: extern char *progname;
                     38: #endif
                     39: extern char *malloc();
                     40: extern int errno;
                     41: 
                     42: static  init = 0;
                     43: static char default_db_name[] = DBM_FILE;
                     44: static char *current_db_name = default_db_name;
                     45: static void encode_princ_key(), decode_princ_key();
                     46: static void encode_princ_contents(), decode_princ_contents();
                     47: static void kerb_dbl_fini();
                     48: static int kerb_dbl_lock();
                     49: static void kerb_dbl_unlock();
                     50: 
                     51: static struct timeval timestamp;/* current time of request */
                     52: static int non_blocking = 0;
                     53: 
                     54: /*
                     55:  * This module contains all of the code which directly interfaces to
                     56:  * the underlying representation of the Kerberos database; this
                     57:  * implementation uses a DBM or NDBM indexed "file" (actually
                     58:  * implemented as two separate files) to store the relations, plus a
                     59:  * third file as a semaphore to allow the database to be replaced out
                     60:  * from underneath the KDC server.
                     61:  */
                     62: 
                     63: /*
                     64:  * Locking:
                     65:  * 
                     66:  * There are two distinct locking protocols used.  One is designed to
                     67:  * lock against processes (the admin_server, for one) which make
                     68:  * incremental changes to the database; the other is designed to lock
                     69:  * against utilities (kdb_util, kpropd) which replace the entire
                     70:  * database in one fell swoop.
                     71:  *
                     72:  * The first locking protocol is implemented using flock() in the 
                     73:  * krb_dbl_lock() and krb_dbl_unlock routines.
                     74:  *
                     75:  * The second locking protocol is necessary because DBM "files" are
                     76:  * actually implemented as two separate files, and it is impossible to
                     77:  * atomically rename two files simultaneously.  It assumes that the
                     78:  * database is replaced only very infrequently in comparison to the time
                     79:  * needed to do a database read operation.
                     80:  *
                     81:  * A third file is used as a "version" semaphore; the modification
                     82:  * time of this file is the "version number" of the database.
                     83:  * At the start of a read operation, the reader checks the version
                     84:  * number; at the end of the read operation, it checks again.  If the
                     85:  * version number changed, or if the semaphore was nonexistant at
                     86:  * either time, the reader sleeps for a second to let things
                     87:  * stabilize, and then tries again; if it does not succeed after
                     88:  * KERB_DB_MAX_RETRY attempts, it gives up.
                     89:  * 
                     90:  * On update, the semaphore file is deleted (if it exists) before any
                     91:  * update takes place; at the end of the update, it is replaced, with
                     92:  * a version number strictly greater than the version number which
                     93:  * existed at the start of the update.
                     94:  * 
                     95:  * If the system crashes in the middle of an update, the semaphore
                     96:  * file is not automatically created on reboot; this is a feature, not
                     97:  * a bug, since the database may be inconsistant.  Note that the
                     98:  * absence of a semaphore file does not prevent another _update_ from
                     99:  * taking place later.  Database replacements take place automatically
                    100:  * only on slave servers; a crash in the middle of an update will be
                    101:  * fixed by the next slave propagation.  A crash in the middle of an
                    102:  * update on the master would be somewhat more serious, but this would
                    103:  * likely be noticed by an administrator, who could fix the problem and
                    104:  * retry the operation.
                    105:  */
                    106: 
                    107: /* Macros to convert ndbm names to dbm names.
                    108:  * Note that dbm_nextkey() cannot be simply converted using a macro, since
                    109:  * it is invoked giving the database, and nextkey() needs the previous key.
                    110:  *
                    111:  * Instead, all routines call "dbm_next" instead.
                    112:  */
                    113: 
                    114: #define dbm_next(db,key) dbm_nextkey(db)
                    115: 
                    116: /*
                    117:  * Utility routine: generate name of database file.
                    118:  */
                    119: 
                    120: static char *gen_dbsuffix(db_name, sfx)
                    121:     char *db_name;
                    122:     char *sfx;
                    123: {
                    124:     char *dbsuffix;
                    125:     
                    126:     if (sfx == NULL)
                    127:        sfx = ".ok";
                    128: 
                    129:     dbsuffix = malloc (strlen(db_name) + strlen(sfx) + 1);
                    130:     strcpy(dbsuffix, db_name);
                    131:     strcat(dbsuffix, sfx);
                    132:     return dbsuffix;
                    133: }
                    134: 
                    135: /*
                    136:  * initialization for data base routines.
                    137:  */
                    138: 
                    139: kerb_db_init()
                    140: {
                    141:     init = 1;
                    142:     return (0);
                    143: }
                    144: 
                    145: /*
                    146:  * gracefully shut down database--must be called by ANY program that does
                    147:  * a kerb_db_init 
                    148:  */
                    149: 
                    150: kerb_db_fini()
                    151: {
                    152: }
                    153: 
                    154: /*
                    155:  * Set the "name" of the current database to some alternate value.
                    156:  *
                    157:  * Passing a null pointer as "name" will set back to the default.
                    158:  * If the alternate database doesn't exist, nothing is changed.
                    159:  */
                    160: 
                    161: kerb_db_set_name(name)
                    162:        char *name;
                    163: {
                    164:     DBM *db;
                    165: 
                    166:     if (name == NULL)
                    167:        name = default_db_name;
                    168:     db = dbm_open(name, 0, 0);
                    169:     if (db == NULL)
                    170:        return errno;
                    171:     dbm_close(db);
                    172:     kerb_dbl_fini();
                    173:     current_db_name = name;
                    174:     return 0;
                    175: }
                    176: 
                    177: /*
                    178:  * Return the last modification time of the database.
                    179:  */
                    180: 
                    181: long kerb_get_db_age()
                    182: {
                    183:     struct stat st;
                    184:     char *okname;
                    185:     long age;
                    186:     
                    187:     okname = gen_dbsuffix(current_db_name, ".ok");
                    188: 
                    189:     if (stat (okname, &st) < 0)
                    190:        age = 0;
                    191:     else
                    192:        age = st.st_mtime;
                    193: 
                    194:     free (okname);
                    195:     return age;
                    196: }
                    197: 
                    198: /*
                    199:  * Remove the semaphore file; indicates that database is currently
                    200:  * under renovation.
                    201:  *
                    202:  * This is only for use when moving the database out from underneath
                    203:  * the server (for example, during slave updates).
                    204:  */
                    205: 
                    206: static long kerb_start_update(db_name)
                    207:     char *db_name;
                    208: {
                    209:     char *okname = gen_dbsuffix(db_name, ".ok");
                    210:     long age = kerb_get_db_age();
                    211:     
                    212:     if (unlink(okname) < 0
                    213:        && errno != ENOENT) {
                    214:            age = -1;
                    215:     }
                    216:     free (okname);
                    217:     return age;
                    218: }
                    219: 
                    220: static long kerb_end_update(db_name, age)
                    221:     char *db_name;
                    222:     long age;
                    223: {
                    224:     int fd;
                    225:     int retval = 0;
                    226:     char *new_okname = gen_dbsuffix(db_name, ".ok#");
                    227:     char *okname = gen_dbsuffix(db_name, ".ok");
                    228:     
                    229:     fd = open (new_okname, O_CREAT|O_RDWR|O_TRUNC, 0600);
                    230:     if (fd < 0)
                    231:        retval = errno;
                    232:     else {
                    233:        struct stat st;
                    234:        struct timeval tv[2];
                    235:        /* make sure that semaphore is "after" previous value. */
                    236:        if (fstat (fd, &st) == 0
                    237:            && st.st_mtime <= age) {
                    238:            tv[0].tv_sec = st.st_atime;
                    239:            tv[0].tv_usec = 0;
                    240:            tv[1].tv_sec = age;
                    241:            tv[1].tv_usec = 0;
                    242:            /* set times.. */
                    243:            utimes (new_okname, tv);
                    244:            fsync(fd);
                    245:        }
                    246:        close(fd);
                    247:        if (rename (new_okname, okname) < 0)
                    248:            retval = errno;
                    249:     }
                    250: 
                    251:     free (new_okname);
                    252:     free (okname);
                    253: 
                    254:     return retval;
                    255: }
                    256: 
                    257: static long kerb_start_read()
                    258: {
                    259:     return kerb_get_db_age();
                    260: }
                    261: 
                    262: static long kerb_end_read(age)
                    263:     u_long age;
                    264: {
                    265:     if (kerb_get_db_age() != age || age == -1) {
                    266:        return -1;
                    267:     }
                    268:     return 0;
                    269: }
                    270: 
                    271: /*
                    272:  * Create the database, assuming it's not there.
                    273:  */
                    274: 
                    275: kerb_db_create(db_name)
                    276:     char *db_name;
                    277: {
                    278:     char *okname = gen_dbsuffix(db_name, ".ok");
                    279:     int fd;
                    280:     register int ret = 0;
                    281:     DBM *db;
                    282: 
                    283:     db = dbm_open(db_name, O_RDWR|O_CREAT|O_EXCL, 0600);
                    284:     if (db == NULL)
                    285:        ret = errno;
                    286:     else
                    287:        dbm_close(db);
                    288: 
                    289:     if (ret == 0) {
                    290:        fd = open (okname, O_CREAT|O_RDWR|O_TRUNC, 0600);
                    291:        if (fd < 0)
                    292:            ret = errno;
                    293:        close(fd);
                    294:     }
                    295:     return ret;
                    296: }
                    297: 
                    298: /*
                    299:  * "Atomically" rename the database in a way that locks out read
                    300:  * access in the middle of the rename.
                    301:  *
                    302:  * Not perfect; if we crash in the middle of an update, we don't
                    303:  * necessarily know to complete the transaction the rename, but...
                    304:  */
                    305: 
                    306: kerb_db_rename(from, to)
                    307:     char *from;
                    308:     char *to;
                    309: {
                    310:     char *fromdir = gen_dbsuffix (from, ".dir");
                    311:     char *todir = gen_dbsuffix (to, ".dir");
                    312:     char *frompag = gen_dbsuffix (from , ".pag");
                    313:     char *topag = gen_dbsuffix (to, ".pag");
                    314:     char *fromok = gen_dbsuffix(from, ".ok");
                    315:     long trans = kerb_start_update(to);
                    316:     int ok;
                    317:     
                    318:     if ((rename (fromdir, todir) == 0)
                    319:        && (rename (frompag, topag) == 0)) {
                    320:        (void) unlink (fromok);
                    321:        ok = 1;
                    322:     }
                    323: 
                    324:     free (fromok);
                    325:     free (fromdir);
                    326:     free (todir);
                    327:     free (frompag);
                    328:     free (topag);
                    329:     if (ok)
                    330:        return kerb_end_update(to, trans);
                    331:     else
                    332:        return -1;
                    333: }
                    334: 
                    335: /*
                    336:  * look up a principal in the data base returns number of principals
                    337:  * found , and whether there were more than requested. 
                    338:  */
                    339: 
                    340: kerb_db_get_principal(name, inst, principal, max, more)
                    341:     char   *name;              /* could have wild card */
                    342:     char   *inst;              /* could have wild card */
                    343:     Principal *principal;
                    344:     unsigned int max;          /* max number of name structs to return */
                    345:     int    *more;              /* where there more than 'max' tuples? */
                    346: 
                    347: {
                    348:     int     found = 0, code;
                    349:     extern int errorproc();
                    350:     int     wildp, wildi;
                    351:     datum   key, contents;
                    352:     char    testname[ANAME_SZ], testinst[INST_SZ];
                    353:     u_long trans;
                    354:     int try;
                    355:     DBM    *db;
                    356: 
                    357:     if (!init)
                    358:        kerb_db_init();         /* initialize database routines */
                    359: 
                    360:     for (try = 0; try < KERB_DB_MAX_RETRY; try++) {
                    361:        trans = kerb_start_read();
                    362: 
                    363:        if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0)
                    364:            return -1;
                    365: 
                    366:        db = dbm_open(current_db_name, O_RDONLY, 0600);
                    367: 
                    368:        *more = 0;
                    369: 
                    370: #ifdef DEBUG
                    371:        if (kerb_debug & 2)
                    372:            fprintf(stderr,
                    373:                    "%s: db_get_principal for %s %s max = %d",
                    374:                    progname, name, inst, max);
                    375: #endif
                    376: 
                    377:        wildp = !strcmp(name, "*");
                    378:        wildi = !strcmp(inst, "*");
                    379: 
                    380:        if (!wildi && !wildp) { /* nothing's wild */
                    381:            encode_princ_key(&key, name, inst);
                    382:            contents = dbm_fetch(db, key);
                    383:            if (contents.dptr == NULL) {
                    384:                found = 0;
                    385:                goto done;
                    386:            }
                    387:            decode_princ_contents(&contents, principal);
                    388: #ifdef DEBUG
                    389:            if (kerb_debug & 1) {
                    390:                fprintf(stderr, "\t found %s %s p_n length %d t_n length %d\n",
                    391:                        principal->name, principal->instance,
                    392:                        strlen(principal->name),
                    393:                        strlen(principal->instance));
                    394:            }
                    395: #endif
                    396:            found = 1;
                    397:            goto done;
                    398:        }
                    399:        /* process wild cards by looping through entire database */
                    400: 
                    401:        for (key = dbm_firstkey(db); key.dptr != NULL;
                    402:             key = dbm_next(db, key)) {
                    403:            decode_princ_key(&key, testname, testinst);
                    404:            if ((wildp || !strcmp(testname, name)) &&
                    405:                (wildi || !strcmp(testinst, inst))) { /* have a match */
                    406:                if (found >= max) {
                    407:                    *more = 1;
                    408:                    goto done;
                    409:                } else {
                    410:                    found++;
                    411:                    contents = dbm_fetch(db, key);
                    412:                    decode_princ_contents(&contents, principal);
                    413: #ifdef DEBUG
                    414:                    if (kerb_debug & 1) {
                    415:                        fprintf(stderr,
                    416:                                "\tfound %s %s p_n length %d t_n length %d\n",
                    417:                                principal->name, principal->instance,
                    418:                                strlen(principal->name),
                    419:                                strlen(principal->instance));
                    420:                    }
                    421: #endif
                    422:                    principal++; /* point to next */
                    423:                }
                    424:            }
                    425:        }
                    426: 
                    427:     done:
                    428:        kerb_dbl_unlock();      /* unlock read lock */
                    429:        dbm_close(db);
                    430:        if (kerb_end_read(trans) == 0)
                    431:            break;
                    432:        found = -1;
                    433:        if (!non_blocking)
                    434:            sleep(1);
                    435:     }
                    436:     return (found);
                    437: }
                    438: 
                    439: /*
                    440:  * Update a name in the data base.  Returns number of names
                    441:  * successfully updated.
                    442:  */
                    443: 
                    444: kerb_db_put_principal(principal, max)
                    445:     Principal *principal;
                    446:     unsigned int max;          /* number of principal structs to
                    447:                                 * update */
                    448: 
                    449: {
                    450:     int     found = 0, code;
                    451:     u_long  i;
                    452:     extern int errorproc();
                    453:     datum   key, contents;
                    454:     DBM    *db;
                    455: 
                    456:     gettimeofday(&timestamp, NULL);
                    457: 
                    458:     if (!init)
                    459:        kerb_db_init();
                    460: 
                    461:     if ((code = kerb_dbl_lock(KERB_DBL_EXCLUSIVE)) != 0)
                    462:        return -1;
                    463: 
                    464:     db = dbm_open(current_db_name, O_RDWR, 0600);
                    465: 
                    466: #ifdef DEBUG
                    467:     if (kerb_debug & 2)
                    468:        fprintf(stderr, "%s: kerb_db_put_principal  max = %d",
                    469:            progname, max);
                    470: #endif
                    471: 
                    472:     /* for each one, stuff temps, and do replace/append */
                    473:     for (i = 0; i < max; i++) {
                    474:        encode_princ_contents(&contents, principal);
                    475:        encode_princ_key(&key, principal->name, principal->instance);
                    476:        dbm_store(db, key, contents, DBM_REPLACE);
                    477: #ifdef DEBUG
                    478:        if (kerb_debug & 1) {
                    479:            fprintf(stderr, "\n put %s %s\n",
                    480:                principal->name, principal->instance);
                    481:        }
                    482: #endif
                    483:        found++;
                    484:        principal++;            /* bump to next struct                     */
                    485:     }
                    486: 
                    487:     dbm_close(db);
                    488:     kerb_dbl_unlock();         /* unlock database */
                    489:     return (found);
                    490: }
                    491: 
                    492: static void
                    493: encode_princ_key(key, name, instance)
                    494:     datum  *key;
                    495:     char   *name, *instance;
                    496: {
                    497:     static char keystring[ANAME_SZ + INST_SZ];
                    498: 
                    499:     bzero(keystring, ANAME_SZ + INST_SZ);
                    500:     strncpy(keystring, name, ANAME_SZ);
                    501:     strncpy(&keystring[ANAME_SZ], instance, INST_SZ);
                    502:     key->dptr = keystring;
                    503:     key->dsize = ANAME_SZ + INST_SZ;
                    504: }
                    505: 
                    506: static void
                    507: decode_princ_key(key, name, instance)
                    508:     datum  *key;
                    509:     char   *name, *instance;
                    510: {
                    511:     strncpy(name, key->dptr, ANAME_SZ);
                    512:     strncpy(instance, key->dptr + ANAME_SZ, INST_SZ);
                    513:     name[ANAME_SZ - 1] = '\0';
                    514:     instance[INST_SZ - 1] = '\0';
                    515: }
                    516: 
                    517: static void
                    518: encode_princ_contents(contents, principal)
                    519:     datum  *contents;
                    520:     Principal *principal;
                    521: {
                    522:     contents->dsize = sizeof(*principal);
                    523:     contents->dptr = (char *) principal;
                    524: }
                    525: 
                    526: static void
                    527: decode_princ_contents(contents, principal)
                    528:     datum  *contents;
                    529:     Principal *principal;
                    530: {
                    531:     bcopy(contents->dptr, (char *) principal, sizeof(*principal));
                    532: }
                    533: 
                    534: kerb_db_get_stat(s)
                    535:     DB_stat *s;
                    536: {
                    537:     gettimeofday(&timestamp, NULL);
                    538: 
                    539: 
                    540:     s->cpu = 0;
                    541:     s->elapsed = 0;
                    542:     s->dio = 0;
                    543:     s->pfault = 0;
                    544:     s->t_stamp = timestamp.tv_sec;
                    545:     s->n_retrieve = 0;
                    546:     s->n_replace = 0;
                    547:     s->n_append = 0;
                    548:     s->n_get_stat = 0;
                    549:     s->n_put_stat = 0;
                    550:     /* update local copy too */
                    551: }
                    552: 
                    553: kerb_db_put_stat(s)
                    554:     DB_stat *s;
                    555: {
                    556: }
                    557: 
                    558: delta_stat(a, b, c)
                    559:     DB_stat *a, *b, *c;
                    560: {
                    561:     /* c = a - b then b = a for the next time */
                    562: 
                    563:     c->cpu = a->cpu - b->cpu;
                    564:     c->elapsed = a->elapsed - b->elapsed;
                    565:     c->dio = a->dio - b->dio;
                    566:     c->pfault = a->pfault - b->pfault;
                    567:     c->t_stamp = a->t_stamp - b->t_stamp;
                    568:     c->n_retrieve = a->n_retrieve - b->n_retrieve;
                    569:     c->n_replace = a->n_replace - b->n_replace;
                    570:     c->n_append = a->n_append - b->n_append;
                    571:     c->n_get_stat = a->n_get_stat - b->n_get_stat;
                    572:     c->n_put_stat = a->n_put_stat - b->n_put_stat;
                    573: 
                    574:     bcopy(a, b, sizeof(DB_stat));
                    575:     return;
                    576: }
                    577: 
                    578: /*
                    579:  * look up a dba in the data base returns number of dbas found , and
                    580:  * whether there were more than requested. 
                    581:  */
                    582: 
                    583: kerb_db_get_dba(dba_name, dba_inst, dba, max, more)
                    584:     char   *dba_name;          /* could have wild card */
                    585:     char   *dba_inst;          /* could have wild card */
                    586:     Dba    *dba;
                    587:     unsigned int max;          /* max number of name structs to return */
                    588:     int    *more;              /* where there more than 'max' tuples? */
                    589: 
                    590: {
                    591:     *more = 0;
                    592:     return (0);
                    593: }
                    594: 
                    595: kerb_db_iterate (func, arg)
                    596:     int (*func)();
                    597:     char *arg;                 /* void *, really */
                    598: {
                    599:     datum key, contents;
                    600:     Principal *principal;
                    601:     int code;
                    602:     DBM *db;
                    603:     
                    604:     kerb_db_init();            /* initialize and open the database */
                    605:     if ((code = kerb_dbl_lock(KERB_DBL_SHARED)) != 0)
                    606:        return code;
                    607: 
                    608:     db = dbm_open(current_db_name, O_RDONLY, 0600);
                    609: 
                    610:     for (key = dbm_firstkey (db); key.dptr != NULL; key = dbm_next(db, key)) {
                    611:        contents = dbm_fetch (db, key);
                    612:        /* XXX may not be properly aligned */
                    613:        principal = (Principal *) contents.dptr;
                    614:        if ((code = (*func)(arg, principal)) != 0)
                    615:            return code;
                    616:     }
                    617:     dbm_close(db);
                    618:     kerb_dbl_unlock();
                    619:     return 0;
                    620: }
                    621: 
                    622: static int dblfd = -1;
                    623: static int mylock = 0;
                    624: static int inited = 0;
                    625: 
                    626: static kerb_dbl_init()
                    627: {
                    628:     if (!inited) {
                    629:        char *filename = gen_dbsuffix (current_db_name, ".ok");
                    630:        if ((dblfd = open(filename, 0)) < 0) {
                    631:            fprintf(stderr, "kerb_dbl_init: couldn't open %s\n", filename);
                    632:            fflush(stderr);
                    633:            perror("open");
                    634:            exit(1);
                    635:        }
                    636:        free(filename);
                    637:        inited++;
                    638:     }
                    639:     return (0);
                    640: }
                    641: 
                    642: static void kerb_dbl_fini()
                    643: {
                    644:     close(dblfd);
                    645:     dblfd = -1;
                    646:     inited = 0;
                    647:     mylock = 0;
                    648: }
                    649: 
                    650: static int kerb_dbl_lock(mode)
                    651:     int     mode;
                    652: {
                    653:     int flock_mode;
                    654:     
                    655:     if (!inited)
                    656:        kerb_dbl_init();
                    657:     if (mylock) {              /* Detect lock call when lock already
                    658:                                 * locked */
                    659:        fprintf(stderr, "Kerberos locking error (mylock)\n");
                    660:        fflush(stderr);
                    661:        exit(1);
                    662:     }
                    663:     switch (mode) {
                    664:     case KERB_DBL_EXCLUSIVE:
                    665:        flock_mode = LOCK_EX;
                    666:        break;
                    667:     case KERB_DBL_SHARED:
                    668:        flock_mode = LOCK_SH;
                    669:        break;
                    670:     default:
                    671:        fprintf(stderr, "invalid lock mode %d\n", mode);
                    672:        abort();
                    673:     }
                    674:     if (non_blocking)
                    675:        flock_mode |= LOCK_NB;
                    676:     
                    677:     if (flock(dblfd, flock_mode) < 0) 
                    678:        return errno;
                    679:     mylock++;
                    680:     return 0;
                    681: }
                    682: 
                    683: static void kerb_dbl_unlock()
                    684: {
                    685:     if (!mylock) {             /* lock already unlocked */
                    686:        fprintf(stderr, "Kerberos database lock not locked when unlocking.\n");
                    687:        fflush(stderr);
                    688:        exit(1);
                    689:     }
                    690:     if (flock(dblfd, LOCK_UN) < 0) {
                    691:        fprintf(stderr, "Kerberos database lock error. (unlocking)\n");
                    692:        fflush(stderr);
                    693:        perror("flock");
                    694:        exit(1);
                    695:     }
                    696:     mylock = 0;
                    697: }
                    698: 
                    699: int kerb_db_set_lockmode(mode)
                    700:     int mode;
                    701: {
                    702:     int old = non_blocking;
                    703:     non_blocking = mode;
                    704:     return old;
                    705: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.