Annotation of 43BSDReno/kerberosIV/kdb/krb_dbm.c, revision 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.