summaryrefslogtreecommitdiff
path: root/lib/tdb2/tdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tdb2/tdb.c')
-rw-r--r--lib/tdb2/tdb.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/tdb2/tdb.c b/lib/tdb2/tdb.c
index 6f334a264b..25ce9b4662 100644
--- a/lib/tdb2/tdb.c
+++ b/lib/tdb2/tdb.c
@@ -326,6 +326,29 @@ unsigned int tdb_get_flags(struct tdb_context *tdb)
return tdb->flags;
}
+static bool readonly_changable(struct tdb_context *tdb, const char *caller)
+{
+ if (tdb->transaction) {
+ tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL,
+ TDB_LOG_USE_ERROR,
+ "%s: can't change"
+ " TDB_RDONLY inside transaction",
+ caller);
+ return false;
+ }
+
+ if (tdb->file->allrecord_lock.count != 0
+ || tdb->file->num_lockrecs != 0) {
+ tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL,
+ TDB_LOG_USE_ERROR,
+ "%s: can't change"
+ " TDB_RDONLY holding locks",
+ caller);
+ return false;
+ }
+ return true;
+}
+
void tdb_add_flag(struct tdb_context *tdb, unsigned flag)
{
if (tdb->flags & TDB_INTERNAL) {
@@ -351,6 +374,10 @@ void tdb_add_flag(struct tdb_context *tdb, unsigned flag)
case TDB_ALLOW_NESTING:
tdb->flags |= TDB_ALLOW_NESTING;
break;
+ case TDB_RDONLY:
+ if (readonly_changable(tdb, "tdb_add_flag"))
+ tdb->flags |= TDB_RDONLY;
+ break;
default:
tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL,
TDB_LOG_USE_ERROR,
@@ -384,6 +411,18 @@ void tdb_remove_flag(struct tdb_context *tdb, unsigned flag)
case TDB_ALLOW_NESTING:
tdb->flags &= ~TDB_ALLOW_NESTING;
break;
+ case TDB_RDONLY:
+ if ((tdb->open_flags & O_ACCMODE) == O_RDONLY) {
+ tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL,
+ TDB_LOG_USE_ERROR,
+ "tdb_remove_flag: can't"
+ " remove TDB_RDONLY on tdb"
+ " opened with O_RDONLY");
+ break;
+ }
+ if (readonly_changable(tdb, "tdb_remove_flag"))
+ tdb->flags &= ~TDB_RDONLY;
+ break;
default:
tdb->last_error = tdb_logerr(tdb, TDB_ERR_EINVAL,
TDB_LOG_USE_ERROR,