summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/locking/locking.c151
1 files changed, 67 insertions, 84 deletions
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index db4f45fea8..95710cdd75 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -513,14 +513,22 @@ char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
Get all share mode entries for a dev/inode pair.
********************************************************************/
-static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
+static struct share_mode_lock *parse_share_modes(TALLOC_CTX *mem_ctx,
+ const TDB_DATA dbuf)
{
+ struct share_mode_lock *lck;
int i;
struct server_id *pids;
bool *pid_exists;
enum ndr_err_code ndr_err;
DATA_BLOB blob;
+ lck = talloc_zero(mem_ctx, struct share_mode_lock);
+ if (lck == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ goto fail;
+ }
+
blob.data = dbuf.dptr;
blob.length = dbuf.dsize;
@@ -529,10 +537,11 @@ static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
(ndr_pull_flags_fn_t)ndr_pull_share_mode_lock);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
- return false;
+ goto fail;
}
lck->modified = false;
+ lck->fresh = false;
if (DEBUGLEVEL >= 10) {
DEBUG(10, ("parse_share_modes:\n"));
@@ -546,19 +555,21 @@ static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
pids = talloc_array(talloc_tos(), struct server_id,
lck->num_share_modes);
if (pids == NULL) {
- smb_panic("parse_share_modes: talloc_array failed");
+ DEBUG(0, ("talloc failed\n"));
+ goto fail;
}
pid_exists = talloc_array(talloc_tos(), bool, lck->num_share_modes);
if (pid_exists == NULL) {
- smb_panic("parse_share_modes: talloc_array failed");
+ DEBUG(0, ("talloc failed\n"));
+ goto fail;
}
for (i=0; i<lck->num_share_modes; i++) {
pids[i] = lck->share_modes[i].pid;
}
-
if (!serverids_exist(pids, lck->num_share_modes, pid_exists)) {
- smb_panic("parse_share_modes: serverids_exist failed");
+ DEBUG(0, ("serverid_exists failed\n"));
+ goto fail;
}
i = 0;
@@ -574,8 +585,10 @@ static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
}
TALLOC_FREE(pid_exists);
TALLOC_FREE(pids);
-
- return True;
+ return lck;
+fail:
+ TALLOC_FREE(lck);
+ return NULL;
}
static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
@@ -655,60 +668,39 @@ static int share_mode_lock_destructor(struct share_mode_lock *lck)
return 0;
}
-static bool fill_share_mode_lock(struct share_mode_lock *lck,
- struct file_id id,
- const char *servicepath,
- const struct smb_filename *smb_fname,
- TDB_DATA share_mode_data,
- const struct timespec *old_write_time)
+static struct share_mode_lock *fresh_share_mode_lock(
+ TALLOC_CTX *mem_ctx, const char *servicepath,
+ const struct smb_filename *smb_fname,
+ const struct timespec *old_write_time)
{
- bool fresh;
-
- /* Ensure we set every field here as the destructor must be
- valid even if parse_share_modes fails. */
-
- lck->servicepath = NULL;
- lck->base_name = NULL;
- lck->stream_name = NULL;
- lck->id = id;
- lck->num_share_modes = 0;
- lck->share_modes = NULL;
- lck->num_delete_tokens = 0;
- lck->delete_tokens = NULL;
- ZERO_STRUCT(lck->old_write_time);
- ZERO_STRUCT(lck->changed_write_time);
-
- fresh = (share_mode_data.dptr == NULL);
-
- if (fresh) {
- bool has_stream;
- if (smb_fname == NULL || servicepath == NULL
- || old_write_time == NULL) {
- return False;
- }
-
- has_stream = smb_fname->stream_name != NULL;
+ struct share_mode_lock *lck;
- lck->base_name = talloc_strdup(lck, smb_fname->base_name);
+ lck = talloc_zero(mem_ctx, struct share_mode_lock);
+ if (lck == NULL) {
+ goto fail;
+ }
+ lck->base_name = talloc_strdup(lck, smb_fname->base_name);
+ if (lck->base_name == NULL) {
+ goto fail;
+ }
+ if (smb_fname->stream_name != NULL) {
lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
- lck->servicepath = talloc_strdup(lck, servicepath);
- if (lck->base_name == NULL ||
- (has_stream && lck->stream_name == NULL) ||
- lck->servicepath == NULL) {
- DEBUG(0, ("talloc failed\n"));
- return False;
- }
- lck->old_write_time = *old_write_time;
- lck->modified = false;
- } else {
- if (!parse_share_modes(share_mode_data, lck)) {
- DEBUG(0, ("Could not parse share modes\n"));
- return False;
+ if (lck->stream_name == NULL) {
+ goto fail;
}
}
- lck->fresh = fresh;
-
- return True;
+ lck->servicepath = talloc_strdup(lck, servicepath);
+ if (lck->servicepath == NULL) {
+ goto fail;
+ }
+ lck->old_write_time = *old_write_time;
+ lck->modified = false;
+ lck->fresh = true;
+ return lck;
+fail:
+ DEBUG(0, ("talloc failed\n"));
+ TALLOC_FREE(lck);
+ return NULL;
}
struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
@@ -723,28 +715,29 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
TDB_DATA key = locking_key(&id, &tmp);
TDB_DATA value;
- if (!(lck = talloc(mem_ctx, struct share_mode_lock))) {
- DEBUG(0, ("talloc failed\n"));
- return NULL;
- }
-
- rec = dbwrap_fetch_locked(lock_db, lck, key);
+ rec = dbwrap_fetch_locked(lock_db, mem_ctx, key);
if (rec == NULL) {
DEBUG(3, ("Could not lock share entry\n"));
- TALLOC_FREE(lck);
return NULL;
}
value = dbwrap_record_get_value(rec);
- if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
- value, old_write_time)) {
- DEBUG(3, ("fill_share_mode_lock failed\n"));
- TALLOC_FREE(lck);
+ if (value.dptr == NULL) {
+ lck = fresh_share_mode_lock(mem_ctx, servicepath, smb_fname,
+ old_write_time);
+ } else {
+ lck = parse_share_modes(mem_ctx, value);
+ }
+
+ if (lck == NULL) {
+ DEBUG(1, ("Could not get share mode lock\n"));
+ TALLOC_FREE(rec);
return NULL;
}
- lck->record = rec;
+ lck->id = id;
+ lck->record = talloc_move(lck, &rec);
talloc_set_destructor(lck, share_mode_lock_destructor);
return lck;
@@ -759,29 +752,19 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
TDB_DATA data;
NTSTATUS status;
- if (!(lck = talloc(mem_ctx, struct share_mode_lock))) {
- DEBUG(0, ("talloc failed\n"));
- return NULL;
- }
-
- status = dbwrap_fetch(lock_db, lck, key, &data);
+ status = dbwrap_fetch(lock_db, talloc_tos(), key, &data);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("Could not fetch share entry\n"));
- TALLOC_FREE(lck);
return NULL;
}
if (data.dptr == NULL) {
- TALLOC_FREE(lck);
return NULL;
}
-
- if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
- DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
- "around (file not open)\n"));
- TALLOC_FREE(lck);
- return NULL;
+ lck = parse_share_modes(mem_ctx, data);
+ if (lck != NULL) {
+ lck->id = id;
}
-
+ TALLOC_FREE(data.dptr);
return lck;
}