16a76a347fccd4214000e3c428862fc4108dabb6
[samba.git] / lib / tdb / common / open.c
1  /*
2    Unix SMB/CIFS implementation.
3
4    trivial database library
5
6    Copyright (C) Andrew Tridgell              1999-2005
7    Copyright (C) Paul `Rusty' Russell              2000
8    Copyright (C) Jeremy Allison                    2000-2003
9
10      ** NOTE! The following LGPL license applies to the tdb
11      ** library. This does NOT imply that all of Samba is released
12      ** under the LGPL
13
14    This library is free software; you can redistribute it and/or
15    modify it under the terms of the GNU Lesser General Public
16    License as published by the Free Software Foundation; either
17    version 3 of the License, or (at your option) any later version.
18
19    This library is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22    Lesser General Public License for more details.
23
24    You should have received a copy of the GNU Lesser General Public
25    License along with this library; if not, see <http://www.gnu.org/licenses/>.
26 */
27
28 #include "tdb_private.h"
29
30 /* all contexts, to ensure no double-opens (fcntl locks don't nest!) */
31 static struct tdb_context *tdbs = NULL;
32
33 /* We use two hashes to double-check they're using the right hash function. */
34 void tdb_header_hash(struct tdb_context *tdb,
35                      uint32_t *magic1_hash, uint32_t *magic2_hash)
36 {
37         TDB_DATA hash_key;
38         uint32_t tdb_magic = TDB_MAGIC;
39
40         hash_key.dptr = discard_const_p(unsigned char, TDB_MAGIC_FOOD);
41         hash_key.dsize = sizeof(TDB_MAGIC_FOOD);
42         *magic1_hash = tdb->hash_fn(&hash_key);
43
44         hash_key.dptr = (unsigned char *)CONVERT(tdb_magic);
45         hash_key.dsize = sizeof(tdb_magic);
46         *magic2_hash = tdb->hash_fn(&hash_key);
47
48         /* Make sure at least one hash is non-zero! */
49         if (*magic1_hash == 0 && *magic2_hash == 0)
50                 *magic1_hash = 1;
51 }
52
53 /* initialise a new database with a specified hash size */
54 static int tdb_new_database(struct tdb_context *tdb, struct tdb_header *header,
55                             int hash_size)
56 {
57         struct tdb_header *newdb;
58         size_t size;
59         int ret = -1;
60
61         /* We make it up in memory, then write it out if not internal */
62         size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off_t);
63         if (!(newdb = (struct tdb_header *)calloc(size, 1))) {
64                 tdb->ecode = TDB_ERR_OOM;
65                 return -1;
66         }
67
68         /* Fill in the header */
69         newdb->version = TDB_VERSION;
70         newdb->hash_size = hash_size;
71
72         tdb_header_hash(tdb, &newdb->magic1_hash, &newdb->magic2_hash);
73
74         /* Make sure older tdbs (which don't check the magic hash fields)
75          * will refuse to open this TDB. */
76         if (tdb->flags & TDB_INCOMPATIBLE_HASH)
77                 newdb->rwlocks = TDB_HASH_RWLOCK_MAGIC;
78
79         /*
80          * We create a tdb with TDB_FEATURE_FLAG_MUTEX support,
81          * the flag combination and runtime feature checks
82          * are done by the caller already.
83          */
84         if (tdb->flags & TDB_MUTEX_LOCKING) {
85                 newdb->feature_flags |= TDB_FEATURE_FLAG_MUTEX;
86         }
87
88         /*
89          * If we have any features we add the FEATURE_FLAG_MAGIC, overwriting the
90          * TDB_HASH_RWLOCK_MAGIC above.
91          */
92         if (newdb->feature_flags != 0) {
93                 newdb->rwlocks = TDB_FEATURE_FLAG_MAGIC;
94         }
95
96         /*
97          * It's required for some following code pathes
98          * to have the fields on 'tdb' up-to-date.
99          *
100          * E.g. tdb_mutex_size() requires it
101          */
102         tdb->feature_flags = newdb->feature_flags;
103         tdb->hash_size = newdb->hash_size;
104
105         if (tdb->flags & TDB_INTERNAL) {
106                 tdb->map_size = size;
107                 tdb->map_ptr = (char *)newdb;
108                 memcpy(header, newdb, sizeof(*header));
109                 /* Convert the `ondisk' version if asked. */
110                 CONVERT(*newdb);
111                 return 0;
112         }
113         if (lseek(tdb->fd, 0, SEEK_SET) == -1)
114                 goto fail;
115
116         if (ftruncate(tdb->fd, 0) == -1)
117                 goto fail;
118
119         if (newdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) {
120                 newdb->mutex_size = tdb_mutex_size(tdb);
121                 tdb->hdr_ofs = newdb->mutex_size;
122         }
123
124         /* This creates an endian-converted header, as if read from disk */
125         CONVERT(*newdb);
126         memcpy(header, newdb, sizeof(*header));
127         /* Don't endian-convert the magic food! */
128         memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
129
130         if (!tdb_write_all(tdb->fd, newdb, size))
131                 goto fail;
132
133         if (newdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) {
134
135                 /*
136                  * Now we init the mutex area
137                  * followed by a second header.
138                  */
139
140                 ret = ftruncate(
141                         tdb->fd,
142                         newdb->mutex_size + sizeof(struct tdb_header));
143                 if (ret == -1) {
144                         goto fail;
145                 }
146                 ret = tdb_mutex_init(tdb);
147                 if (ret == -1) {
148                         goto fail;
149                 }
150
151                 /*
152                  * Write a second header behind the mutexes. That's the area
153                  * that will be mmapp'ed.
154                  */
155                 ret = lseek(tdb->fd, newdb->mutex_size, SEEK_SET);
156                 if (ret == -1) {
157                         goto fail;
158                 }
159                 if (!tdb_write_all(tdb->fd, newdb, size)) {
160                         goto fail;
161                 }
162         }
163
164         ret = 0;
165   fail:
166         SAFE_FREE(newdb);
167         return ret;
168 }
169
170
171
172 static int tdb_already_open(dev_t device,
173                             ino_t ino)
174 {
175         struct tdb_context *i;
176
177         for (i = tdbs; i; i = i->next) {
178                 if (i->device == device && i->inode == ino) {
179                         return 1;
180                 }
181         }
182
183         return 0;
184 }
185
186 /* open the database, creating it if necessary
187
188    The open_flags and mode are passed straight to the open call on the
189    database file. A flags value of O_WRONLY is invalid. The hash size
190    is advisory, use zero for a default value.
191
192    Return is NULL on error, in which case errno is also set.  Don't
193    try to call tdb_error or tdb_errname, just do strerror(errno).
194
195    @param name may be NULL for internal databases. */
196 _PUBLIC_ struct tdb_context *tdb_open(const char *name, int hash_size, int tdb_flags,
197                       int open_flags, mode_t mode)
198 {
199         return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL, NULL);
200 }
201
202 /* a default logging function */
203 static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);
204 static void null_log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...)
205 {
206 }
207
208 static bool check_header_hash(struct tdb_context *tdb,
209                               struct tdb_header *header,
210                               bool default_hash, uint32_t *m1, uint32_t *m2)
211 {
212         tdb_header_hash(tdb, m1, m2);
213         if (header->magic1_hash == *m1 &&
214             header->magic2_hash == *m2) {
215                 return true;
216         }
217
218         /* If they explicitly set a hash, always respect it. */
219         if (!default_hash)
220                 return false;
221
222         /* Otherwise, try the other inbuilt hash. */
223         if (tdb->hash_fn == tdb_old_hash)
224                 tdb->hash_fn = tdb_jenkins_hash;
225         else
226                 tdb->hash_fn = tdb_old_hash;
227         return check_header_hash(tdb, header, false, m1, m2);
228 }
229
230 static bool tdb_mutex_open_ok(struct tdb_context *tdb,
231                               const struct tdb_header *header)
232 {
233         int locked;
234
235         locked = tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK,
236                                TDB_LOCK_NOWAIT|TDB_LOCK_PROBE);
237
238         if ((locked == -1) && (tdb->ecode == TDB_ERR_LOCK)) {
239                 /*
240                  * CLEAR_IF_FIRST still active. The tdb was created on this
241                  * host, so we can assume the mutex implementation is
242                  * compatible. Important for tools like tdbdump on a still
243                  * open locking.tdb.
244                  */
245                 goto check_local_settings;
246         }
247
248         /*
249          * We got the CLEAR_IF_FIRST lock. That means the database was
250          * potentially copied from somewhere else. The mutex implementation
251          * might be incompatible.
252          */
253
254         if (tdb_nest_unlock(tdb, ACTIVE_LOCK, F_WRLCK, false) == -1) {
255                 /*
256                  * Should not happen
257                  */
258                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok: "
259                          "failed to release ACTIVE_LOCK on %s: %s\n",
260                          tdb->name, strerror(errno)));
261                 return false;
262         }
263
264         if (tdb->flags & TDB_NOLOCK) {
265                 /*
266                  * We don't look at locks, so it does not matter to have a
267                  * compatible mutex implementation. Allow the open.
268                  */
269                 return true;
270         }
271
272 check_local_settings:
273
274         if (!(tdb->flags & TDB_MUTEX_LOCKING)) {
275                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok[%s]: "
276                          "Can use mutexes only with "
277                          "MUTEX_LOCKING or NOLOCK\n",
278                          tdb->name));
279                 return false;
280         }
281
282         if (tdb_mutex_size(tdb) != header->mutex_size) {
283                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_mutex_open_ok[%s]: "
284                          "Mutex size changed from %u to %u\n.",
285                          tdb->name,
286                          (unsigned int)header->mutex_size,
287                          (unsigned int)tdb_mutex_size(tdb)));
288                 return false;
289         }
290
291         return true;
292 }
293
294 _PUBLIC_ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
295                                 int open_flags, mode_t mode,
296                                 const struct tdb_logging_context *log_ctx,
297                                 tdb_hash_func hash_fn)
298 {
299         int orig_errno = errno;
300         struct tdb_header header;
301         struct tdb_context *tdb;
302         struct stat st;
303         int rev = 0, locked = 0;
304         unsigned char *vp;
305         uint32_t vertest;
306         unsigned v;
307         const char *hash_alg;
308         uint32_t magic1, magic2;
309         int ret;
310
311         ZERO_STRUCT(header);
312
313         if (!(tdb = (struct tdb_context *)calloc(1, sizeof *tdb))) {
314                 /* Can't log this */
315                 errno = ENOMEM;
316                 goto fail;
317         }
318         tdb_io_init(tdb);
319
320         if (tdb_flags & TDB_INTERNAL) {
321                 tdb_flags |= TDB_INCOMPATIBLE_HASH;
322         }
323         if (tdb_flags & TDB_MUTEX_LOCKING) {
324                 tdb_flags |= TDB_INCOMPATIBLE_HASH;
325         }
326
327         tdb->fd = -1;
328 #ifdef TDB_TRACE
329         tdb->tracefd = -1;
330 #endif
331         tdb->name = NULL;
332         tdb->map_ptr = NULL;
333         tdb->flags = tdb_flags;
334         tdb->open_flags = open_flags;
335         if (log_ctx) {
336                 tdb->log = *log_ctx;
337         } else {
338                 tdb->log.log_fn = null_log_fn;
339                 tdb->log.log_private = NULL;
340         }
341
342         if (name == NULL && (tdb_flags & TDB_INTERNAL)) {
343                 name = "__TDB_INTERNAL__";
344         }
345
346         if (name == NULL) {
347                 tdb->name = discard_const_p(char, "__NULL__");
348                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: called with name == NULL\n"));
349                 tdb->name = NULL;
350                 errno = EINVAL;
351                 goto fail;
352         }
353
354         /* now make a copy of the name, as the caller memory might go away */
355         if (!(tdb->name = (char *)strdup(name))) {
356                 /*
357                  * set the name as the given string, so that tdb_name() will
358                  * work in case of an error.
359                  */
360                 tdb->name = discard_const_p(char, name);
361                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't strdup(%s)\n",
362                          name));
363                 tdb->name = NULL;
364                 errno = ENOMEM;
365                 goto fail;
366         }
367
368         if (hash_fn) {
369                 tdb->hash_fn = hash_fn;
370                 hash_alg = "the user defined";
371         } else {
372                 /* This controls what we use when creating a tdb. */
373                 if (tdb->flags & TDB_INCOMPATIBLE_HASH) {
374                         tdb->hash_fn = tdb_jenkins_hash;
375                 } else {
376                         tdb->hash_fn = tdb_old_hash;
377                 }
378                 hash_alg = "either default";
379         }
380
381         /* cache the page size */
382         tdb->page_size = getpagesize();
383         if (tdb->page_size <= 0) {
384                 tdb->page_size = 0x2000;
385         }
386
387         tdb->max_dead_records = (tdb_flags & TDB_VOLATILE) ? 5 : 0;
388
389         if ((open_flags & O_ACCMODE) == O_WRONLY) {
390                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: can't open tdb %s write-only\n",
391                          name));
392                 errno = EINVAL;
393                 goto fail;
394         }
395
396         if (hash_size == 0)
397                 hash_size = DEFAULT_HASH_SIZE;
398         if ((open_flags & O_ACCMODE) == O_RDONLY) {
399                 tdb->read_only = 1;
400                 /* read only databases don't do locking or clear if first */
401                 tdb->flags |= TDB_NOLOCK;
402                 tdb->flags &= ~TDB_CLEAR_IF_FIRST;
403         }
404
405         if ((tdb->flags & TDB_ALLOW_NESTING) &&
406             (tdb->flags & TDB_DISALLOW_NESTING)) {
407                 tdb->ecode = TDB_ERR_NESTING;
408                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
409                         "allow_nesting and disallow_nesting are not allowed together!"));
410                 errno = EINVAL;
411                 goto fail;
412         }
413
414         if (tdb->flags & TDB_MUTEX_LOCKING) {
415                 /*
416                  * Here we catch bugs in the callers,
417                  * the runtime check for existing tdb's comes later.
418                  */
419
420                 if (!(tdb->flags & TDB_CLEAR_IF_FIRST)) {
421                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
422                                 "invalid flags for %s - TDB_MUTEX_LOCKING "
423                                 "requires TDB_CLEAR_IF_FIRST\n", name));
424                         errno = EINVAL;
425                         goto fail;
426                 }
427
428                 if (tdb->flags & TDB_INTERNAL) {
429                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
430                                 "invalid flags for %s - TDB_MUTEX_LOCKING and "
431                                 "TDB_INTERNAL are not allowed together\n", name));
432                         errno = EINVAL;
433                         goto fail;
434                 }
435
436                 if (tdb->flags & TDB_NOMMAP) {
437                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
438                                 "invalid flags for %s - TDB_MUTEX_LOCKING and "
439                                 "TDB_NOMMAP are not allowed together\n", name));
440                         errno = EINVAL;
441                         goto fail;
442                 }
443
444                 if (tdb->read_only) {
445                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
446                                 "invalid flags for %s - TDB_MUTEX_LOCKING "
447                                 "not allowed read only\n", name));
448                         errno = EINVAL;
449                         goto fail;
450                 }
451
452                 /*
453                  * The callers should have called
454                  * tdb_runtime_check_for_robust_mutexes()
455                  * before using TDB_MUTEX_LOCKING!
456                  *
457                  * This makes sure the caller understands
458                  * that the locking may behave a bit differently
459                  * than with pure fcntl locking. E.g. multiple
460                  * read locks are not supported.
461                  */
462                 if (!tdb_runtime_check_for_robust_mutexes()) {
463                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
464                                 "invalid flags for %s - TDB_MUTEX_LOCKING "
465                                 "requires support for robust_mutexes\n",
466                                 name));
467                         errno = ENOSYS;
468                         goto fail;
469                 }
470         }
471
472         if (getenv("TDB_NO_FSYNC")) {
473                 tdb->flags |= TDB_NOSYNC;
474         }
475
476         /*
477          * TDB_ALLOW_NESTING is the default behavior.
478          * Note: this may change in future versions!
479          */
480         if (!(tdb->flags & TDB_DISALLOW_NESTING)) {
481                 tdb->flags |= TDB_ALLOW_NESTING;
482         }
483
484         /* internal databases don't mmap or lock, and start off cleared */
485         if (tdb->flags & TDB_INTERNAL) {
486                 tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP);
487                 tdb->flags &= ~TDB_CLEAR_IF_FIRST;
488                 if (tdb_new_database(tdb, &header, hash_size) != 0) {
489                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: tdb_new_database failed!"));
490                         goto fail;
491                 }
492                 tdb->hash_size = hash_size;
493                 goto internal;
494         }
495
496         if ((tdb->fd = open(name, open_flags, mode)) == -1) {
497                 TDB_LOG((tdb, TDB_DEBUG_WARNING, "tdb_open_ex: could not open file %s: %s\n",
498                          name, strerror(errno)));
499                 goto fail;      /* errno set by open(2) */
500         }
501
502         /* on exec, don't inherit the fd */
503         v = fcntl(tdb->fd, F_GETFD, 0);
504         fcntl(tdb->fd, F_SETFD, v | FD_CLOEXEC);
505
506         /* ensure there is only one process initialising at once */
507         if (tdb_nest_lock(tdb, OPEN_LOCK, F_WRLCK, TDB_LOCK_WAIT) == -1) {
508                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to get open lock on %s: %s\n",
509                          name, strerror(errno)));
510                 goto fail;      /* errno set by tdb_brlock */
511         }
512
513         /* we need to zero database if we are the only one with it open */
514         if ((tdb_flags & TDB_CLEAR_IF_FIRST) &&
515             (!tdb->read_only) &&
516             (locked = (tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE) == 0))) {
517                 ret = tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0,
518                                  TDB_LOCK_WAIT);
519                 if (ret == -1) {
520                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
521                                  "tdb_brlock failed for %s: %s\n",
522                                  name, strerror(errno)));
523                         goto fail;
524                 }
525                 ret = tdb_new_database(tdb, &header, hash_size);
526                 if (ret == -1) {
527                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
528                                  "tdb_new_database failed for %s: %s\n",
529                                  name, strerror(errno)));
530                         tdb_unlockall(tdb);
531                         goto fail;
532                 }
533                 ret = tdb_brunlock(tdb, F_WRLCK, FREELIST_TOP, 0);
534                 if (ret == -1) {
535                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
536                                  "tdb_unlockall failed for %s: %s\n",
537                                  name, strerror(errno)));
538                         goto fail;
539                 }
540                 ret = lseek(tdb->fd, 0, SEEK_SET);
541                 if (ret == -1) {
542                         TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
543                                  "lseek failed for %s: %s\n",
544                                  name, strerror(errno)));
545                         goto fail;
546                 }
547         }
548
549         errno = 0;
550         if (read(tdb->fd, &header, sizeof(header)) != sizeof(header)
551             || strcmp(header.magic_food, TDB_MAGIC_FOOD) != 0) {
552                 if (!(open_flags & O_CREAT) ||
553                     tdb_new_database(tdb, &header, hash_size) == -1) {
554                         if (errno == 0) {
555                                 errno = EIO; /* ie bad format or something */
556                         }
557                         goto fail;
558                 }
559                 rev = (tdb->flags & TDB_CONVERT);
560         } else if (header.version != TDB_VERSION
561                    && !(rev = (header.version==TDB_BYTEREV(TDB_VERSION)))) {
562                 /* wrong version */
563                 errno = EIO;
564                 goto fail;
565         }
566         vp = (unsigned char *)&header.version;
567         vertest = (((uint32_t)vp[0]) << 24) | (((uint32_t)vp[1]) << 16) |
568                   (((uint32_t)vp[2]) << 8) | (uint32_t)vp[3];
569         tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0;
570         if (!rev)
571                 tdb->flags &= ~TDB_CONVERT;
572         else {
573                 tdb->flags |= TDB_CONVERT;
574                 tdb_convert(&header, sizeof(header));
575         }
576
577         /*
578          * We only use st.st_dev and st.st_ino from the raw fstat()
579          * call, everything else needs to use tdb_fstat() in order
580          * to skip tdb->hdr_ofs!
581          */
582         if (fstat(tdb->fd, &st) == -1) {
583                 goto fail;
584         }
585         tdb->device = st.st_dev;
586         tdb->inode = st.st_ino;
587         ZERO_STRUCT(st);
588
589         if (header.rwlocks != 0 &&
590             header.rwlocks != TDB_FEATURE_FLAG_MAGIC &&
591             header.rwlocks != TDB_HASH_RWLOCK_MAGIC) {
592                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: spinlocks no longer supported\n"));
593                 errno = ENOSYS;
594                 goto fail;
595         }
596         tdb->hash_size = header.hash_size;
597
598         if (header.rwlocks == TDB_FEATURE_FLAG_MAGIC) {
599                 tdb->feature_flags = header.feature_flags;
600         }
601
602         if (tdb->feature_flags & ~TDB_SUPPORTED_FEATURE_FLAGS) {
603                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: unsupported "
604                          "features in tdb %s: 0x%08x (supported: 0x%08x)\n",
605                          name, (unsigned)tdb->feature_flags,
606                          (unsigned)TDB_SUPPORTED_FEATURE_FLAGS));
607                 errno = ENOSYS;
608                 goto fail;
609         }
610
611         if (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) {
612                 if (!tdb_mutex_open_ok(tdb, &header)) {
613                         errno = EINVAL;
614                         goto fail;
615                 }
616
617                 /*
618                  * We need to remember the hdr_ofs
619                  * also for the TDB_NOLOCK case
620                  * if the current library doesn't support
621                  * mutex locking.
622                  */
623                 tdb->hdr_ofs = header.mutex_size;
624         }
625
626         if ((header.magic1_hash == 0) && (header.magic2_hash == 0)) {
627                 /* older TDB without magic hash references */
628                 tdb->hash_fn = tdb_old_hash;
629         } else if (!check_header_hash(tdb, &header, !hash_fn,
630                                       &magic1, &magic2)) {
631                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: "
632                          "%s was not created with %s hash function we are using\n"
633                          "magic1_hash[0x%08X %s 0x%08X] "
634                          "magic2_hash[0x%08X %s 0x%08X]\n",
635                          name, hash_alg,
636                          header.magic1_hash,
637                          (header.magic1_hash == magic1) ? "==" : "!=",
638                          magic1,
639                          header.magic2_hash,
640                          (header.magic2_hash == magic2) ? "==" : "!=",
641                          magic2));
642                 errno = EINVAL;
643                 goto fail;
644         }
645
646         /* Is it already in the open list?  If so, fail. */
647         if (tdb_already_open(tdb->device, tdb->inode)) {
648                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
649                          "%s (%d,%d) is already open in this process\n",
650                          name, (int)tdb->device, (int)tdb->inode));
651                 errno = EBUSY;
652                 goto fail;
653         }
654
655         /*
656          * We had tdb_mmap(tdb) here before,
657          * but we need to use tdb_fstat(),
658          * which is triggered from tdb_oob() before calling tdb_mmap().
659          * As this skips tdb->hdr_ofs.
660          */
661         tdb->map_size = 0;
662         ret = tdb->methods->tdb_oob(tdb, 0, 1, 0);
663         if (ret == -1) {
664                 errno = EIO;
665                 goto fail;
666         }
667
668         if (tdb->feature_flags & TDB_FEATURE_FLAG_MUTEX) {
669                 if (!(tdb->flags & TDB_NOLOCK)) {
670                         ret = tdb_mutex_mmap(tdb);
671                         if (ret != 0) {
672                                 goto fail;
673                         }
674                 }
675         }
676
677         if (locked) {
678                 if (tdb_nest_unlock(tdb, ACTIVE_LOCK, F_WRLCK, false) == -1) {
679                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
680                                  "failed to release ACTIVE_LOCK on %s: %s\n",
681                                  name, strerror(errno)));
682                         goto fail;
683                 }
684
685         }
686
687         /* We always need to do this if the CLEAR_IF_FIRST flag is set, even if
688            we didn't get the initial exclusive lock as we need to let all other
689            users know we're using it. */
690
691         if (tdb_flags & TDB_CLEAR_IF_FIRST) {
692                 /* leave this lock in place to indicate it's in use */
693                 if (tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT) == -1) {
694                         goto fail;
695                 }
696         }
697
698         /* if needed, run recovery */
699         if (tdb_transaction_recover(tdb) == -1) {
700                 goto fail;
701         }
702
703 #ifdef TDB_TRACE
704         {
705                 char tracefile[strlen(name) + 32];
706
707                 snprintf(tracefile, sizeof(tracefile),
708                          "%s.trace.%li", name, (long)getpid());
709                 tdb->tracefd = open(tracefile, O_WRONLY|O_CREAT|O_EXCL, 0600);
710                 if (tdb->tracefd >= 0) {
711                         tdb_enable_seqnum(tdb);
712                         tdb_trace_open(tdb, "tdb_open", hash_size, tdb_flags,
713                                        open_flags);
714                 } else
715                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to open trace file %s!\n", tracefile));
716         }
717 #endif
718
719  internal:
720         /* Internal (memory-only) databases skip all the code above to
721          * do with disk files, and resume here by releasing their
722          * open lock and hooking into the active list. */
723         if (tdb_nest_unlock(tdb, OPEN_LOCK, F_WRLCK, false) == -1) {
724                 goto fail;
725         }
726         tdb->next = tdbs;
727         tdbs = tdb;
728         errno = orig_errno;
729         return tdb;
730
731  fail:
732         { int save_errno = errno;
733
734         if (!tdb)
735                 return NULL;
736
737 #ifdef TDB_TRACE
738         close(tdb->tracefd);
739 #endif
740         if (tdb->map_ptr) {
741                 if (tdb->flags & TDB_INTERNAL)
742                         SAFE_FREE(tdb->map_ptr);
743                 else
744                         tdb_munmap(tdb);
745         }
746         if (tdb->fd != -1)
747                 if (close(tdb->fd) != 0)
748                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n"));
749         SAFE_FREE(tdb->lockrecs);
750         SAFE_FREE(tdb->name);
751         SAFE_FREE(tdb);
752         errno = save_errno;
753         return NULL;
754         }
755 }
756
757 /*
758  * Set the maximum number of dead records per hash chain
759  */
760
761 _PUBLIC_ void tdb_set_max_dead(struct tdb_context *tdb, int max_dead)
762 {
763         tdb->max_dead_records = max_dead;
764 }
765
766 /**
767  * Close a database.
768  *
769  * @returns -1 for error; 0 for success.
770  **/
771 _PUBLIC_ int tdb_close(struct tdb_context *tdb)
772 {
773         struct tdb_context **i;
774         int ret = 0;
775
776         if (tdb->transaction) {
777                 tdb_transaction_cancel(tdb);
778         }
779         tdb_trace(tdb, "tdb_close");
780
781         if (tdb->map_ptr) {
782                 if (tdb->flags & TDB_INTERNAL)
783                         SAFE_FREE(tdb->map_ptr);
784                 else
785                         tdb_munmap(tdb);
786         }
787
788         tdb_mutex_munmap(tdb);
789
790         SAFE_FREE(tdb->name);
791         if (tdb->fd != -1) {
792                 ret = close(tdb->fd);
793                 tdb->fd = -1;
794         }
795         SAFE_FREE(tdb->lockrecs);
796
797         /* Remove from contexts list */
798         for (i = &tdbs; *i; i = &(*i)->next) {
799                 if (*i == tdb) {
800                         *i = tdb->next;
801                         break;
802                 }
803         }
804
805 #ifdef TDB_TRACE
806         close(tdb->tracefd);
807 #endif
808         memset(tdb, 0, sizeof(*tdb));
809         SAFE_FREE(tdb);
810
811         return ret;
812 }
813
814 /* register a loging function */
815 _PUBLIC_ void tdb_set_logging_function(struct tdb_context *tdb,
816                                        const struct tdb_logging_context *log_ctx)
817 {
818         tdb->log = *log_ctx;
819 }
820
821 _PUBLIC_ void *tdb_get_logging_private(struct tdb_context *tdb)
822 {
823         return tdb->log.log_private;
824 }
825
826 static int tdb_reopen_internal(struct tdb_context *tdb, bool active_lock)
827 {
828 #if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \
829         !defined(LIBREPLACE_PWRITE_NOT_REPLACED)
830         struct stat st;
831 #endif
832
833         if (tdb->flags & TDB_INTERNAL) {
834                 return 0; /* Nothing to do. */
835         }
836
837         if (tdb_have_extra_locks(tdb)) {
838                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed with locks held\n"));
839                 goto fail;
840         }
841
842         if (tdb->transaction != 0) {
843                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_reopen: reopen not allowed inside a transaction\n"));
844                 goto fail;
845         }
846
847 /* If we have real pread & pwrite, we can skip reopen. */
848 #if !defined(LIBREPLACE_PREAD_NOT_REPLACED) || \
849         !defined(LIBREPLACE_PWRITE_NOT_REPLACED)
850         if (tdb_munmap(tdb) != 0) {
851                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: munmap failed (%s)\n", strerror(errno)));
852                 goto fail;
853         }
854         if (close(tdb->fd) != 0)
855                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: WARNING closing tdb->fd failed!\n"));
856         tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0);
857         if (tdb->fd == -1) {
858                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: open failed (%s)\n", strerror(errno)));
859                 goto fail;
860         }
861         /*
862          * We only use st.st_dev and st.st_ino from the raw fstat()
863          * call, everything else needs to use tdb_fstat() in order
864          * to skip tdb->hdr_ofs!
865          */
866         if (fstat(tdb->fd, &st) != 0) {
867                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: fstat failed (%s)\n", strerror(errno)));
868                 goto fail;
869         }
870         if (st.st_ino != tdb->inode || st.st_dev != tdb->device) {
871                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: file dev/inode has changed!\n"));
872                 goto fail;
873         }
874         ZERO_STRUCT(st);
875
876         /*
877          * We had tdb_mmap(tdb) here before,
878          * but we need to use tdb_fstat(),
879          * which is triggered from tdb_oob() before calling tdb_mmap().
880          * As this skips tdb->hdr_ofs.
881          */
882         tdb->map_size = 0;
883         if (tdb->methods->tdb_oob(tdb, 0, 1, 0) != 0) {
884                 goto fail;
885         }
886 #endif /* fake pread or pwrite */
887
888         /* We may still think we hold the active lock. */
889         tdb->num_lockrecs = 0;
890         SAFE_FREE(tdb->lockrecs);
891         tdb->lockrecs_array_length = 0;
892
893         if (active_lock && tdb_nest_lock(tdb, ACTIVE_LOCK, F_RDLCK, TDB_LOCK_WAIT) == -1) {
894                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_reopen: failed to obtain active lock\n"));
895                 goto fail;
896         }
897
898         return 0;
899
900 fail:
901         tdb_close(tdb);
902         return -1;
903 }
904
905 /* reopen a tdb - this can be used after a fork to ensure that we have an independent
906    seek pointer from our parent and to re-establish locks */
907 _PUBLIC_ int tdb_reopen(struct tdb_context *tdb)
908 {
909         return tdb_reopen_internal(tdb, tdb->flags & TDB_CLEAR_IF_FIRST);
910 }
911
912 /* reopen all tdb's */
913 _PUBLIC_ int tdb_reopen_all(int parent_longlived)
914 {
915         struct tdb_context *tdb;
916
917         for (tdb=tdbs; tdb; tdb = tdb->next) {
918                 bool active_lock = (tdb->flags & TDB_CLEAR_IF_FIRST);
919
920                 /*
921                  * If the parent is longlived (ie. a
922                  * parent daemon architecture), we know
923                  * it will keep it's active lock on a
924                  * tdb opened with CLEAR_IF_FIRST. Thus
925                  * for child processes we don't have to
926                  * add an active lock. This is essential
927                  * to improve performance on systems that
928                  * keep POSIX locks as a non-scalable data
929                  * structure in the kernel.
930                  */
931                 if (parent_longlived) {
932                         /* Ensure no clear-if-first. */
933                         active_lock = false;
934                 }
935
936                 if (tdb_reopen_internal(tdb, active_lock) != 0)
937                         return -1;
938         }
939
940         return 0;
941 }