1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-03 04:22:09 +03:00

s3: Move the share_mode_lock handling to its own file

Signed-off-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Volker Lendecke
2012-01-10 14:13:49 +01:00
committed by Jeremy Allison
parent cfebba96bd
commit 6f9442a705
4 changed files with 465 additions and 417 deletions

View File

@ -793,7 +793,7 @@ RPC_SERVER_OBJ = $(RPC_LSARPC_OBJ) $(RPC_WINREG_OBJ) $(RPC_INITSHUTDOWN_OBJ) \
RPC_CLIENT_SCHANNEL_OBJ = rpc_client/cli_pipe_schannel.o RPC_CLIENT_SCHANNEL_OBJ = rpc_client/cli_pipe_schannel.o
LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o \ LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o \
librpc/gen_ndr/ndr_open_files.o librpc/gen_ndr/ndr_open_files.o locking/share_mode_lock.o
PRIVILEGES_BASIC_OBJ = ../libcli/security/privileges.o PRIVILEGES_BASIC_OBJ = ../libcli/security/privileges.o

View File

@ -52,9 +52,6 @@
#define NO_LOCKING_COUNT (-1) #define NO_LOCKING_COUNT (-1)
/* the locking database handle */
static struct db_context *lock_db;
/**************************************************************************** /****************************************************************************
Debugging aids :-). Debugging aids :-).
****************************************************************************/ ****************************************************************************/
@ -431,64 +428,6 @@ void locking_close_file(struct messaging_context *msg_ctx,
} }
} }
/****************************************************************************
Initialise the locking functions.
****************************************************************************/
static bool locking_init_internal(bool read_only)
{
brl_init(read_only);
if (lock_db)
return True;
lock_db = db_open(NULL, lock_path("locking.tdb"),
lp_open_files_db_hash_size(),
TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
read_only?O_RDONLY:O_RDWR|O_CREAT, 0644);
if (!lock_db) {
DEBUG(0,("ERROR: Failed to initialise locking database\n"));
return False;
}
if (!posix_locking_init(read_only))
return False;
return True;
}
bool locking_init(void)
{
return locking_init_internal(false);
}
bool locking_init_readonly(void)
{
return locking_init_internal(true);
}
/*******************************************************************
Deinitialize the share_mode management.
******************************************************************/
bool locking_end(void)
{
brl_shutdown();
TALLOC_FREE(lock_db);
return true;
}
/*******************************************************************
Form a static locking key for a dev/inode pair.
******************************************************************/
static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp)
{
*tmp = *id;
return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp));
}
/******************************************************************* /*******************************************************************
Print out a share mode. Print out a share mode.
********************************************************************/ ********************************************************************/
@ -509,287 +448,12 @@ char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
(unsigned int)e->name_hash); (unsigned int)e->name_hash);
} }
/*******************************************************************
Get all share mode entries for a dev/inode pair.
********************************************************************/
static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx,
const TDB_DATA dbuf)
{
struct share_mode_data *d;
int i;
struct server_id *pids;
bool *pid_exists;
enum ndr_err_code ndr_err;
DATA_BLOB blob;
d = talloc_zero(mem_ctx, struct share_mode_data);
if (d == NULL) {
DEBUG(0, ("talloc failed\n"));
goto fail;
}
blob.data = dbuf.dptr;
blob.length = dbuf.dsize;
ndr_err = ndr_pull_struct_blob(
&blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
goto fail;
}
d->modified = false;
d->fresh = false;
if (DEBUGLEVEL >= 10) {
DEBUG(10, ("parse_share_modes:\n"));
NDR_PRINT_DEBUG(share_mode_data, d);
}
/*
* Ensure that each entry has a real process attached.
*/
pids = talloc_array(talloc_tos(), struct server_id,
d->num_share_modes);
if (pids == NULL) {
DEBUG(0, ("talloc failed\n"));
goto fail;
}
pid_exists = talloc_array(talloc_tos(), bool, d->num_share_modes);
if (pid_exists == NULL) {
DEBUG(0, ("talloc failed\n"));
goto fail;
}
for (i=0; i<d->num_share_modes; i++) {
pids[i] = d->share_modes[i].pid;
}
if (!serverids_exist(pids, d->num_share_modes, pid_exists)) {
DEBUG(0, ("serverid_exists failed\n"));
goto fail;
}
i = 0;
while (i < d->num_share_modes) {
struct share_mode_entry *e = &d->share_modes[i];
if (!pid_exists[i]) {
*e = d->share_modes[d->num_share_modes-1];
d->num_share_modes -= 1;
d->modified = True;
continue;
}
i += 1;
}
TALLOC_FREE(pid_exists);
TALLOC_FREE(pids);
return d;
fail:
TALLOC_FREE(d);
return NULL;
}
static TDB_DATA unparse_share_modes(struct share_mode_data *d)
{
DATA_BLOB blob;
enum ndr_err_code ndr_err;
if (DEBUGLEVEL >= 10) {
DEBUG(10, ("unparse_share_modes:\n"));
NDR_PRINT_DEBUG(share_mode_data, d);
}
if (d->num_share_modes == 0) {
DEBUG(10, ("No used share mode found\n"));
return make_tdb_data(NULL, 0);
}
ndr_err = ndr_push_struct_blob(
&blob, d, d, (ndr_push_flags_fn_t)ndr_push_share_mode_data);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
smb_panic("ndr_push_share_mode_lock failed");
}
return make_tdb_data(blob.data, blob.length);
}
static int share_mode_data_destructor(struct share_mode_data *d)
{
NTSTATUS status;
TDB_DATA data;
if (!d->modified) {
return 0;
}
data = unparse_share_modes(d);
if (data.dptr == NULL) {
if (!d->fresh) {
/* There has been an entry before, delete it */
status = dbwrap_record_delete(d->record);
if (!NT_STATUS_IS_OK(status)) {
char *errmsg;
DEBUG(0, ("delete_rec returned %s\n",
nt_errstr(status)));
if (asprintf(&errmsg, "could not delete share "
"entry: %s\n",
nt_errstr(status)) == -1) {
smb_panic("could not delete share"
"entry");
}
smb_panic(errmsg);
}
}
goto done;
}
status = dbwrap_record_store(d->record, data, TDB_REPLACE);
if (!NT_STATUS_IS_OK(status)) {
char *errmsg;
DEBUG(0, ("store returned %s\n", nt_errstr(status)));
if (asprintf(&errmsg, "could not store share mode entry: %s",
nt_errstr(status)) == -1) {
smb_panic("could not store share mode entry");
}
smb_panic(errmsg);
}
done:
return 0;
}
static struct share_mode_data *fresh_share_mode_lock(
TALLOC_CTX *mem_ctx, const char *servicepath,
const struct smb_filename *smb_fname,
const struct timespec *old_write_time)
{
struct share_mode_data *d;
if ((servicepath == NULL) || (smb_fname == NULL) ||
(old_write_time == NULL)) {
return NULL;
}
d = talloc_zero(mem_ctx, struct share_mode_data);
if (d == NULL) {
goto fail;
}
d->base_name = talloc_strdup(d, smb_fname->base_name);
if (d->base_name == NULL) {
goto fail;
}
if (smb_fname->stream_name != NULL) {
d->stream_name = talloc_strdup(d, smb_fname->stream_name);
if (d->stream_name == NULL) {
goto fail;
}
}
d->servicepath = talloc_strdup(d, servicepath);
if (d->servicepath == NULL) {
goto fail;
}
d->old_write_time = *old_write_time;
d->modified = false;
d->fresh = true;
return d;
fail:
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(d);
return NULL;
}
struct share_mode_lock *get_share_mode_lock_fresh(TALLOC_CTX *mem_ctx,
const struct file_id id,
const char *servicepath,
const struct smb_filename *smb_fname,
const struct timespec *old_write_time)
{
struct share_mode_lock *lck;
struct share_mode_data *d;
struct file_id tmp;
struct db_record *rec;
TDB_DATA key = locking_key(&id, &tmp);
TDB_DATA value;
rec = dbwrap_fetch_locked(lock_db, mem_ctx, key);
if (rec == NULL) {
DEBUG(3, ("Could not lock share entry\n"));
return NULL;
}
value = dbwrap_record_get_value(rec);
if (value.dptr == NULL) {
d = fresh_share_mode_lock(mem_ctx, servicepath, smb_fname,
old_write_time);
} else {
d = parse_share_modes(mem_ctx, value);
}
if (d == NULL) {
DEBUG(1, ("Could not get share mode lock\n"));
TALLOC_FREE(rec);
return NULL;
}
d->id = id;
d->record = talloc_move(d, &rec);
talloc_set_destructor(d, share_mode_data_destructor);
lck = talloc(mem_ctx, struct share_mode_lock);
if (lck == NULL) {
DEBUG(1, ("talloc failed\n"));
TALLOC_FREE(d);
return NULL;
}
lck->data = talloc_move(lck, &d);
return lck;
}
struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx, struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
const struct file_id id) const struct file_id id)
{ {
return get_share_mode_lock_fresh(mem_ctx, id, NULL, NULL, NULL); return get_share_mode_lock_fresh(mem_ctx, id, NULL, NULL, NULL);
} }
struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
const struct file_id id)
{
struct share_mode_lock *lck;
struct file_id tmp;
TDB_DATA key = locking_key(&id, &tmp);
TDB_DATA data;
NTSTATUS status;
status = dbwrap_fetch(lock_db, talloc_tos(), key, &data);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("Could not fetch share entry\n"));
return NULL;
}
if (data.dptr == NULL) {
return NULL;
}
lck = talloc(mem_ctx, struct share_mode_lock);
if (lck == NULL) {
TALLOC_FREE(data.dptr);
return NULL;
}
lck->data = parse_share_modes(mem_ctx, data);
TALLOC_FREE(data.dptr);
if (lck->data == NULL) {
TALLOC_FREE(lck);
return NULL;
}
return lck;
}
/******************************************************************* /*******************************************************************
Sets the service name and filename for rename. Sets the service name and filename for rename.
At this point we emit "file renamed" messages to all At this point we emit "file renamed" messages to all
@ -1373,82 +1037,3 @@ bool set_write_time(struct file_id fileid, struct timespec write_time)
TALLOC_FREE(lck); TALLOC_FREE(lck);
return True; return True;
} }
struct forall_state {
void (*fn)(const struct share_mode_entry *entry,
const char *sharepath,
const char *fname,
void *private_data);
void *private_data;
};
static int traverse_fn(struct db_record *rec, void *_state)
{
struct forall_state *state = (struct forall_state *)_state;
uint32_t i;
TDB_DATA key;
TDB_DATA value;
DATA_BLOB blob;
enum ndr_err_code ndr_err;
struct share_mode_data *d;
key = dbwrap_record_get_key(rec);
value = dbwrap_record_get_value(rec);
/* Ensure this is a locking_key record. */
if (key.dsize != sizeof(struct file_id))
return 0;
d = talloc(talloc_tos(), struct share_mode_data);
if (d == NULL) {
return 0;
}
blob.data = value.dptr;
blob.length = value.dsize;
ndr_err = ndr_pull_struct_blob(
&blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
return 0;
}
for (i=0; i<d->num_share_modes; i++) {
state->fn(&d->share_modes[i],
d->servicepath, d->base_name,
state->private_data);
}
TALLOC_FREE(d);
return 0;
}
/*******************************************************************
Call the specified function on each entry under management by the
share mode system.
********************************************************************/
int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
const char *, void *),
void *private_data)
{
struct forall_state state;
NTSTATUS status;
int count;
if (lock_db == NULL)
return 0;
state.fn = fn;
state.private_data = private_data;
status = dbwrap_traverse_read(lock_db, traverse_fn, (void *)&state,
&count);
if (!NT_STATUS_IS_OK(status)) {
return -1;
} else {
return count;
}
}

View File

@ -0,0 +1,463 @@
/*
Unix SMB/CIFS implementation.
Locking functions
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) Jeremy Allison 1992-2006
Copyright (C) Volker Lendecke 2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Revision History:
12 aug 96: Erik.Devriendt@te6.siemens.be
added support for shared memory implementation of share mode locking
May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
locking to deal with multiple share modes per open file.
September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
support.
rewritten completely to use new tdb code. Tridge, Dec '99
Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
Added Unix Extensions POSIX locking support. Jeremy Allison Mar 2006.
*/
#include "includes.h"
#include "system/filesys.h"
#include "locking/proto.h"
#include "smbd/globals.h"
#include "dbwrap/dbwrap.h"
#include "dbwrap/dbwrap_open.h"
#include "../libcli/security/security.h"
#include "serverid.h"
#include "messages.h"
#include "util_tdb.h"
#include "../librpc/gen_ndr/ndr_open_files.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_LOCKING
#define NO_LOCKING_COUNT (-1)
/* the locking database handle */
static struct db_context *lock_db;
static bool locking_init_internal(bool read_only)
{
brl_init(read_only);
if (lock_db)
return True;
lock_db = db_open(NULL, lock_path("locking.tdb"),
lp_open_files_db_hash_size(),
TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
read_only?O_RDONLY:O_RDWR|O_CREAT, 0644);
if (!lock_db) {
DEBUG(0,("ERROR: Failed to initialise locking database\n"));
return False;
}
if (!posix_locking_init(read_only))
return False;
return True;
}
bool locking_init(void)
{
return locking_init_internal(false);
}
bool locking_init_readonly(void)
{
return locking_init_internal(true);
}
/*******************************************************************
Deinitialize the share_mode management.
******************************************************************/
bool locking_end(void)
{
brl_shutdown();
TALLOC_FREE(lock_db);
return true;
}
/*******************************************************************
Form a static locking key for a dev/inode pair.
******************************************************************/
static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp)
{
*tmp = *id;
return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp));
}
/*******************************************************************
Get all share mode entries for a dev/inode pair.
********************************************************************/
static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx,
const TDB_DATA dbuf)
{
struct share_mode_data *d;
int i;
struct server_id *pids;
bool *pid_exists;
enum ndr_err_code ndr_err;
DATA_BLOB blob;
d = talloc_zero(mem_ctx, struct share_mode_data);
if (d == NULL) {
DEBUG(0, ("talloc failed\n"));
goto fail;
}
blob.data = dbuf.dptr;
blob.length = dbuf.dsize;
ndr_err = ndr_pull_struct_blob(
&blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
goto fail;
}
d->modified = false;
d->fresh = false;
if (DEBUGLEVEL >= 10) {
DEBUG(10, ("parse_share_modes:\n"));
NDR_PRINT_DEBUG(share_mode_data, d);
}
/*
* Ensure that each entry has a real process attached.
*/
pids = talloc_array(talloc_tos(), struct server_id,
d->num_share_modes);
if (pids == NULL) {
DEBUG(0, ("talloc failed\n"));
goto fail;
}
pid_exists = talloc_array(talloc_tos(), bool, d->num_share_modes);
if (pid_exists == NULL) {
DEBUG(0, ("talloc failed\n"));
goto fail;
}
for (i=0; i<d->num_share_modes; i++) {
pids[i] = d->share_modes[i].pid;
}
if (!serverids_exist(pids, d->num_share_modes, pid_exists)) {
DEBUG(0, ("serverid_exists failed\n"));
goto fail;
}
i = 0;
while (i < d->num_share_modes) {
struct share_mode_entry *e = &d->share_modes[i];
if (!pid_exists[i]) {
*e = d->share_modes[d->num_share_modes-1];
d->num_share_modes -= 1;
d->modified = True;
continue;
}
i += 1;
}
TALLOC_FREE(pid_exists);
TALLOC_FREE(pids);
return d;
fail:
TALLOC_FREE(d);
return NULL;
}
static TDB_DATA unparse_share_modes(struct share_mode_data *d)
{
DATA_BLOB blob;
enum ndr_err_code ndr_err;
if (DEBUGLEVEL >= 10) {
DEBUG(10, ("unparse_share_modes:\n"));
NDR_PRINT_DEBUG(share_mode_data, d);
}
if (d->num_share_modes == 0) {
DEBUG(10, ("No used share mode found\n"));
return make_tdb_data(NULL, 0);
}
ndr_err = ndr_push_struct_blob(
&blob, d, d, (ndr_push_flags_fn_t)ndr_push_share_mode_data);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
smb_panic("ndr_push_share_mode_lock failed");
}
return make_tdb_data(blob.data, blob.length);
}
static int share_mode_data_destructor(struct share_mode_data *d)
{
NTSTATUS status;
TDB_DATA data;
if (!d->modified) {
return 0;
}
data = unparse_share_modes(d);
if (data.dptr == NULL) {
if (!d->fresh) {
/* There has been an entry before, delete it */
status = dbwrap_record_delete(d->record);
if (!NT_STATUS_IS_OK(status)) {
char *errmsg;
DEBUG(0, ("delete_rec returned %s\n",
nt_errstr(status)));
if (asprintf(&errmsg, "could not delete share "
"entry: %s\n",
nt_errstr(status)) == -1) {
smb_panic("could not delete share"
"entry");
}
smb_panic(errmsg);
}
}
goto done;
}
status = dbwrap_record_store(d->record, data, TDB_REPLACE);
if (!NT_STATUS_IS_OK(status)) {
char *errmsg;
DEBUG(0, ("store returned %s\n", nt_errstr(status)));
if (asprintf(&errmsg, "could not store share mode entry: %s",
nt_errstr(status)) == -1) {
smb_panic("could not store share mode entry");
}
smb_panic(errmsg);
}
done:
return 0;
}
static struct share_mode_data *fresh_share_mode_lock(
TALLOC_CTX *mem_ctx, const char *servicepath,
const struct smb_filename *smb_fname,
const struct timespec *old_write_time)
{
struct share_mode_data *d;
if ((servicepath == NULL) || (smb_fname == NULL) ||
(old_write_time == NULL)) {
return NULL;
}
d = talloc_zero(mem_ctx, struct share_mode_data);
if (d == NULL) {
goto fail;
}
d->base_name = talloc_strdup(d, smb_fname->base_name);
if (d->base_name == NULL) {
goto fail;
}
if (smb_fname->stream_name != NULL) {
d->stream_name = talloc_strdup(d, smb_fname->stream_name);
if (d->stream_name == NULL) {
goto fail;
}
}
d->servicepath = talloc_strdup(d, servicepath);
if (d->servicepath == NULL) {
goto fail;
}
d->old_write_time = *old_write_time;
d->modified = false;
d->fresh = true;
return d;
fail:
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(d);
return NULL;
}
struct share_mode_lock *get_share_mode_lock_fresh(TALLOC_CTX *mem_ctx,
const struct file_id id,
const char *servicepath,
const struct smb_filename *smb_fname,
const struct timespec *old_write_time)
{
struct share_mode_lock *lck;
struct share_mode_data *d;
struct file_id tmp;
struct db_record *rec;
TDB_DATA key = locking_key(&id, &tmp);
TDB_DATA value;
rec = dbwrap_fetch_locked(lock_db, mem_ctx, key);
if (rec == NULL) {
DEBUG(3, ("Could not lock share entry\n"));
return NULL;
}
value = dbwrap_record_get_value(rec);
if (value.dptr == NULL) {
d = fresh_share_mode_lock(mem_ctx, servicepath, smb_fname,
old_write_time);
} else {
d = parse_share_modes(mem_ctx, value);
}
if (d == NULL) {
DEBUG(1, ("Could not get share mode lock\n"));
TALLOC_FREE(rec);
return NULL;
}
d->id = id;
d->record = talloc_move(d, &rec);
talloc_set_destructor(d, share_mode_data_destructor);
lck = talloc(mem_ctx, struct share_mode_lock);
if (lck == NULL) {
DEBUG(1, ("talloc failed\n"));
TALLOC_FREE(d);
return NULL;
}
lck->data = talloc_move(lck, &d);
return lck;
}
struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
const struct file_id id)
{
struct share_mode_lock *lck;
struct file_id tmp;
TDB_DATA key = locking_key(&id, &tmp);
TDB_DATA data;
NTSTATUS status;
status = dbwrap_fetch(lock_db, talloc_tos(), key, &data);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("Could not fetch share entry\n"));
return NULL;
}
if (data.dptr == NULL) {
return NULL;
}
lck = talloc(mem_ctx, struct share_mode_lock);
if (lck == NULL) {
TALLOC_FREE(data.dptr);
return NULL;
}
lck->data = parse_share_modes(mem_ctx, data);
TALLOC_FREE(data.dptr);
if (lck->data == NULL) {
TALLOC_FREE(lck);
return NULL;
}
return lck;
}
struct forall_state {
void (*fn)(const struct share_mode_entry *entry,
const char *sharepath,
const char *fname,
void *private_data);
void *private_data;
};
static int traverse_fn(struct db_record *rec, void *_state)
{
struct forall_state *state = (struct forall_state *)_state;
uint32_t i;
TDB_DATA key;
TDB_DATA value;
DATA_BLOB blob;
enum ndr_err_code ndr_err;
struct share_mode_data *d;
key = dbwrap_record_get_key(rec);
value = dbwrap_record_get_value(rec);
/* Ensure this is a locking_key record. */
if (key.dsize != sizeof(struct file_id))
return 0;
d = talloc(talloc_tos(), struct share_mode_data);
if (d == NULL) {
return 0;
}
blob.data = value.dptr;
blob.length = value.dsize;
ndr_err = ndr_pull_struct_blob(
&blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
return 0;
}
for (i=0; i<d->num_share_modes; i++) {
state->fn(&d->share_modes[i],
d->servicepath, d->base_name,
state->private_data);
}
TALLOC_FREE(d);
return 0;
}
/*******************************************************************
Call the specified function on each entry under management by the
share mode system.
********************************************************************/
int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
const char *, void *),
void *private_data)
{
struct forall_state state;
NTSTATUS status;
int count;
if (lock_db == NULL)
return 0;
state.fn = fn;
state.private_data = private_data;
status = dbwrap_traverse_read(lock_db, traverse_fn, (void *)&state,
&count);
if (!NT_STATUS_IS_OK(status)) {
return -1;
} else {
return count;
}
}

View File

@ -218,7 +218,7 @@ LIB_EVENTLOG_SRC = '''lib/eventlog/eventlog.c'''
RPC_CLIENT_SCHANNEL_SRC = '''rpc_client/cli_pipe_schannel.c''' RPC_CLIENT_SCHANNEL_SRC = '''rpc_client/cli_pipe_schannel.c'''
LOCKING_SRC = '''locking/locking.c locking/brlock.c locking/posix.c''' LOCKING_SRC = '''locking/locking.c locking/brlock.c locking/posix.c locking/share_mode_lock.c'''
PRIVILEGES_SRC = '''lib/privileges.c''' PRIVILEGES_SRC = '''lib/privileges.c'''