1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-29 21:47:30 +03:00

Merge branch 'v3-2-test' of ssh://git.samba.org/data/git/samba into v3-2-simo

(This used to be commit 05c22a55a4c052c682a2f2afdb0696504195d18c)
This commit is contained in:
Simo Sorce 2008-01-16 12:06:34 -05:00
commit 04b2a9e80a
50 changed files with 4114 additions and 515 deletions

View File

@ -308,7 +308,7 @@ LIB_WITH_PROTO_OBJ = $(VERSION_OBJ) lib/charcnv.o lib/debug.o lib/fault.o \
lib/util_str.o lib/clobber.o lib/util_sid.o lib/util_uuid.o \
lib/util_unistr.o lib/util_file.o lib/data_blob.o \
lib/util.o lib/util_sock.o lib/sock_exec.o lib/util_sec.o \
lib/substitute.o lib/fsusage.o \
lib/substitute.o lib/fsusage.o lib/dbwrap_util.o \
lib/ms_fnmatch.o lib/select.o lib/errmap_unix.o \
lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \
lib/md5.o lib/hmacmd5.o lib/arc4.o lib/iconv.o \
@ -503,6 +503,7 @@ VFS_READONLY_OBJ = modules/vfs_readonly.o modules/getdate.o
VFS_CAP_OBJ = modules/vfs_cap.o
VFS_EXPAND_MSDFS_OBJ = modules/vfs_expand_msdfs.o
VFS_SHADOW_COPY_OBJ = modules/vfs_shadow_copy.o
VFS_SHADOW_COPY2_OBJ = modules/vfs_shadow_copy2.o
VFS_AFSACL_OBJ = modules/vfs_afsacl.o
VFS_XATTR_TDB_OBJ = modules/vfs_xattr_tdb.o librpc/gen_ndr/ndr_xattr.o
VFS_POSIXACL_OBJ = modules/vfs_posixacl.o
@ -520,6 +521,7 @@ VFS_COMMIT_OBJ = modules/vfs_commit.o
VFS_GPFS_OBJ = modules/vfs_gpfs.o modules/gpfs.o modules/nfs4_acls.o
VFS_NOTIFY_FAM_OBJ = modules/vfs_notify_fam.o
VFS_READAHEAD_OBJ = modules/vfs_readahead.o
VFS_TSMSM_OBJ = modules/vfs_tsmsm.o
VFS_FILEID_OBJ = modules/vfs_fileid.o
VFS_SYNCOPS_OBJ = modules/vfs_syncops.o
@ -1611,6 +1613,10 @@ bin/ad.@SHLIBEXT@: $(BINARY_PREREQS) winbindd/idmap_ad.o
@echo "Building plugin $@"
@$(SHLD_MODULE) winbindd/idmap_ad.o
bin/tdb2.@SHLIBEXT@: $(BINARY_PREREQS) winbindd/idmap_tdb2.o
@echo "Building plugin $@"
@$(SHLD_MODULE) winbindd/idmap_tdb2.o
bin/ldap.@SHLIBEXT@: $(BINARY_PREREQS) winbindd/idmap_ldap.o
@echo "Building plugin $@"
@$(SHLD_MODULE) winbindd/idmap_ldap.o
@ -1670,6 +1676,10 @@ bin/shadow_copy.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_SHADOW_COPY_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_SHADOW_COPY_OBJ)
bin/shadow_copy2.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_SHADOW_COPY2_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_SHADOW_COPY2_OBJ)
bin/syncops.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_SYNCOPS_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_SYNCOPS_OBJ)
@ -1750,6 +1760,10 @@ bin/readahead.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_READAHEAD_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_READAHEAD_OBJ)
bin/tsmsm.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_TSMSM_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_TSMSM_OBJ)
bin/fileid.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_FILEID_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_FILEID_OBJ)

View File

@ -707,7 +707,7 @@ dnl These have to be built static:
default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsa rpc_samr rpc_winreg rpc_initshutdown rpc_lsa_ds rpc_wkssvc rpc_svcctl2 rpc_ntsvcs rpc_net rpc_netdfs rpc_srvsvc2 rpc_spoolss rpc_eventlog2 auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin vfs_default nss_info_template"
dnl These are preferably build shared, and static if dlopen() is not available
default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy charset_CP850 charset_CP437 auth_script vfs_readahead vfs_syncops vfs_xattr_tdb"
default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_syncops vfs_xattr_tdb"
if test "x$developer" = xyes; then
default_static_modules="$default_static_modules rpc_rpcecho"
@ -2751,6 +2751,12 @@ AC_SUBST(SMB_FAM_LIBS)
SMB_CHECK_DMAPI([], AC_MSG_NOTICE(DMAPI support not present) )
# Add TSM SM VFS module only if there are both GPFS and DMAPI support
# Theoretically it should work with AIX JFS2 too but this needs testing
if test x"$samba_cv_HAVE_GPFS" = x"yes" && test x"$samba_dmapi_libs" != x"" ; then
default_shared_modules="$default_shared_modules vfs_tsmsm"
fi
AC_CACHE_CHECK([for kernel share modes],samba_cv_HAVE_KERNEL_SHARE_MODES,[
AC_TRY_RUN([
#include <sys/types.h>
@ -6452,6 +6458,7 @@ SMB_SUBSYSTEM(RPC,smbd/server.o)
SMB_MODULE(idmap_ldap, winbindd/idmap_ldap.o, "bin/ldap.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_tdb, winbindd/idmap_tdb.o, "bin/tdb.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_tdb2, winbindd/idmap_tdb2.o, "bin/tdb2.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_passdb, winbindd/idmap_passdb.o, "bin/passdb.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_nss, winbindd/idmap_nss.o, "bin/nss.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_rid, winbindd/idmap_rid.o, "bin/rid.$SHLIBEXT", IDMAP)
@ -6488,6 +6495,7 @@ SMB_MODULE(vfs_readonly, \$(VFS_READONLY_OBJ), "bin/readonly.$SHLIBEXT", VFS)
SMB_MODULE(vfs_cap, \$(VFS_CAP_OBJ), "bin/cap.$SHLIBEXT", VFS)
SMB_MODULE(vfs_expand_msdfs, \$(VFS_EXPAND_MSDFS_OBJ), "bin/expand_msdfs.$SHLIBEXT", VFS)
SMB_MODULE(vfs_shadow_copy, \$(VFS_SHADOW_COPY_OBJ), "bin/shadow_copy.$SHLIBEXT", VFS)
SMB_MODULE(vfs_shadow_copy2, \$(VFS_SHADOW_COPY2_OBJ), "bin/shadow_copy2.$SHLIBEXT", VFS)
SMB_MODULE(vfs_afsacl, \$(VFS_AFSACL_OBJ), "bin/afsacl.$SHLIBEXT", VFS)
SMB_MODULE(vfs_xattr_tdb, \$(VFS_XATTR_TDB_OBJ), "bin/xattr_tdb.$SHLIBEXT", VFS)
SMB_MODULE(vfs_posixacl, \$(VFS_POSIXACL_OBJ), "bin/posixacl.$SHLIBEXT", VFS)
@ -6503,6 +6511,7 @@ SMB_MODULE(vfs_prealloc, \$(VFS_PREALLOC_OBJ), "bin/prealloc.$SHLIBEXT", VFS)
SMB_MODULE(vfs_commit, \$(VFS_COMMIT_OBJ), "bin/commit.$SHLIBEXT", VFS)
SMB_MODULE(vfs_gpfs, \$(VFS_GPFS_OBJ), "bin/gpfs.$SHLIBEXT", VFS)
SMB_MODULE(vfs_readahead, \$(VFS_READAHEAD_OBJ), "bin/readahead.$SHLIBEXT", VFS)
SMB_MODULE(vfs_tsmsm, \$(VFS_TSMSM_OBJ), "bin/tsmsm.$SHLIBEXT", VFS)
SMB_MODULE(vfs_fileid, \$(VFS_FILEID_OBJ), "bin/fileid.$SHLIBEXT", VFS)
SMB_MODULE(vfs_syncops, \$(VFS_SYNCOPS_OBJ), "bin/syncops.$SHLIBEXT", VFS)
SMB_MODULE(vfs_zfsacl, \$(VFS_ZFSACL_OBJ), "bin/zfsacl.$SHLIBEXT", VFS)

View File

@ -17,6 +17,9 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CTDBD_CONN_H
#define _CTDBD_CONN_H
struct ctdbd_connection;
NTSTATUS ctdbd_init_connection(TALLOC_CTX *mem_ctx,
@ -62,3 +65,6 @@ NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn,
NTSTATUS ctdbd_register_reconfigure(struct ctdbd_connection *conn);
NTSTATUS ctdbd_persistent_store(struct ctdbd_connection *conn, uint32_t db_id, TDB_DATA key, TDB_DATA data);
#endif /* _CTDBD_CONN_H */

View File

@ -43,6 +43,7 @@ struct db_context {
void *private_data);
int (*get_seqnum)(struct db_context *db);
void *private_data;
bool persistent;
};
struct db_context *db_open(TALLOC_CTX *mem_ctx,

View File

@ -87,27 +87,8 @@
#define LSA_AUDIT_NUM_CATEGORIES_NT4 7
#define LSA_AUDIT_NUM_CATEGORIES_WIN2K 9
#define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
#define LSA_AUDIT_POLICY_NONE 0x00
#define LSA_AUDIT_POLICY_SUCCESS 0x01
#define LSA_AUDIT_POLICY_FAILURE 0x02
#define LSA_AUDIT_POLICY_ALL (LSA_AUDIT_POLICY_SUCCESS|LSA_AUDIT_POLICY_FAILURE)
#define LSA_AUDIT_POLICY_CLEAR 0x04
enum lsa_audit_categories {
LSA_AUDIT_CATEGORY_SYSTEM = 0,
LSA_AUDIT_CATEGORY_LOGON = 1,
LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS,
LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS,
LSA_AUDIT_CATEGORY_PROCCESS_TRACKING,
LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES,
LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT,
LSA_AUDIT_CATEGORY_DIRECTORY_SERVICE_ACCESS, /* only in win2k/2k3 */
LSA_AUDIT_CATEGORY_ACCOUNT_LOGON /* only in win2k/2k3 */
};
/* level 1 is auditing settings */
typedef struct dom_query_1
{

View File

@ -70,6 +70,7 @@
* timestamp resolition. JRA. */
/* Changed to version21 to add chflags operation -- jpeach */
/* Changed to version22 to add lchown operation -- jra */
/* Additional change: add operations for offline files and remote storage volume abstraction -- ab*/
/* Leave at 22 - not yet released. But change set_nt_acl to return an NTSTATUS. jra. */
/* Leave at 22 - not yet released. Add file_id_create operation. --metze */
/* Leave at 22 - not yet released. Change all BOOL parameters (int) to bool. jra. */
@ -257,6 +258,12 @@ typedef enum _vfs_op_type {
SMB_VFS_OP_AIO_ERROR,
SMB_VFS_OP_AIO_FSYNC,
SMB_VFS_OP_AIO_SUSPEND,
SMB_VFS_OP_AIO_FORCE,
/* offline operations */
SMB_VFS_OP_IS_OFFLINE,
SMB_VFS_OP_SET_OFFLINE,
SMB_VFS_OP_IS_REMOTESTORAGE,
/* This should always be last enum value */
@ -405,6 +412,12 @@ struct vfs_ops {
int (*aio_error_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb);
int (*aio_fsync)(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb);
int (*aio_suspend)(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *timeout);
bool (*aio_force)(struct vfs_handle_struct *handle, struct files_struct *fsp);
/* offline operations */
int (*is_offline)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf, bool *offline);
int (*set_offline)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
bool (*is_remotestorage)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
} ops;
@ -526,6 +539,12 @@ struct vfs_ops {
struct vfs_handle_struct *aio_error;
struct vfs_handle_struct *aio_fsync;
struct vfs_handle_struct *aio_suspend;
struct vfs_handle_struct *aio_force;
/* offline operations */
struct vfs_handle_struct *is_offline;
struct vfs_handle_struct *set_offline;
struct vfs_handle_struct *is_remotestorage;
} handles;
};

View File

@ -138,6 +138,12 @@
#define SMB_VFS_AIO_ERROR(fsp,aiocb) ((fsp)->conn->vfs.ops.aio_error_fn((fsp)->conn->vfs.handles.aio_error,(fsp),(aiocb)))
#define SMB_VFS_AIO_FSYNC(fsp,op,aiocb) ((fsp)->conn->vfs.ops.aio_fsync((fsp)->conn->vfs.handles.aio_fsync,(fsp),(op),(aiocb)))
#define SMB_VFS_AIO_SUSPEND(fsp,aiocb,n,ts) ((fsp)->conn->vfs.ops.aio_suspend((fsp)->conn->vfs.handles.aio_suspend,(fsp),(aiocb),(n),(ts)))
#define SMB_VFS_AIO_FORCE(fsp) ((fsp)->conn->vfs.ops.aio_force((fsp)->conn->vfs.handles.aio_force,(fsp)))
/* Offline operations */
#define SMB_VFS_IS_OFFLINE(conn,path,sbuf,offline) ((conn)->vfs.ops.is_offline((conn)->vfs.handles.is_offline,(conn),(path),(sbuf),(offline)))
#define SMB_VFS_SET_OFFLINE(conn,path) ((conn)->vfs.ops.set_offline((conn)->vfs.handles.set_offline,(conn),(path)))
#define SMB_VFS_IS_REMOTESTORAGE(conn,path) ((conn)->vfs.ops.is_remotestorage((conn)->vfs.handles.is_remotestorage,(conn),(path)))
/*******************************************************************
Don't access conn->vfs_opaque.ops directly!!!
@ -257,6 +263,12 @@
#define SMB_VFS_OPAQUE_AIO_ERROR(fsp,aiocb) ((fsp)->conn->vfs_opaque.ops.aio_error_fn((fsp)->conn->vfs_opaque.handles.aio_error,(fsp),(aiocb)))
#define SMB_VFS_OPAQUE_AIO_FSYNC(fsp,op,aiocb) ((fsp)->conn->vfs_opaque.ops.aio_fsync((fsp)->conn->vfs_opaque.handles.aio_fsync,(fsp),(op),(aiocb)))
#define SMB_VFS_OPAQUE_AIO_SUSPEND(fsp,aiocb,n,ts) ((fsp)->conn->vfs_opaque.ops.aio_suspend((fsp)->conn->vfs_opaque.handles.aio_suspend,(fsp),(aiocb),(n),(ts)))
#define SMB_VFS_OPAQUE_AIO_FORCE(fsp) ((fsp)->conn->vfs_opaque.ops.aio_force((fsp)->conn->vfs_opaque.handles.aio_force,(fsp)))
/* Offline operations */
#define SMB_VFS_OPAQUE_IS_OFFLINE(conn,path,sbuf,offline) ((conn)->vfs_opaque.ops.is_offline((conn)->vfs_opaque.handles.is_offline,(conn),(path),(sbuf),(offline)))
#define SMB_VFS_OPAQUE_SET_OFFLINE(conn,path) ((conn)->vfs_opaque.ops.set_offline((conn)->vfs_opaque.handles.set_offline,(conn),(path)))
#define SMB_VFS_OPAQUE_IS_REMOTESTORAGE(conn,path) ((conn)->vfs_opaque.ops.is_remotestorage((conn)->vfs_opaque.handles.is_remotestorage,(conn),(path)))
/*******************************************************************
Don't access handle->vfs_next.ops.* directly!!!
@ -377,5 +389,11 @@
#define SMB_VFS_NEXT_AIO_ERROR(handle,fsp,aiocb) ((handle)->vfs_next.ops.aio_error_fn((handle)->vfs_next.handles.aio_error,(fsp),(aiocb)))
#define SMB_VFS_NEXT_AIO_FSYNC(handle,fsp,op,aiocb) ((handle)->vfs_next.ops.aio_fsync((handle)->vfs_next.handles.aio_fsync,(fsp),(op),(aiocb)))
#define SMB_VFS_NEXT_AIO_SUSPEND(handle,fsp,aiocb,n,ts) ((handle)->vfs_next.ops.aio_suspend((handle)->vfs_next.handles.aio_suspend,(fsp),(aiocb),(n),(ts)))
#define SMB_VFS_NEXT_AIO_FORCE(handle,fsp) ((handle)->vfs_next.ops.aio_force((handle)->vfs_next.handles.aio_force,(fsp)))
/* Offline operations */
#define SMB_VFS_NEXT_IS_OFFLINE(conn,path,sbuf,offline) ((conn)->vfs_next.ops.is_offline((conn)->vfs_next.handles.is_offline,(conn),(path),(sbuf),(offline)))
#define SMB_VFS_NEXT_SET_OFFLINE(conn,path) ((conn)->vfs_next.ops.set_offline((conn)->vfs_next.handles.set_offline,(conn),(path)))
#define SMB_VFS_NEXT_IS_REMOTESTORAGE(conn,path) ((conn)->vfs_next.ops.is_remotestorage((conn)->vfs_next.handles.is_remotestorage,(conn),(path)))
#endif /* _VFS_MACROS_H */

View File

@ -34,7 +34,7 @@ static struct db_context *connections_db_ctx(bool rw)
}
else {
db_ctx = db_open(NULL, lock_path("connections.tdb"), 0,
TDB_DEFAULT, O_RDONLY, 0);
TDB_CLEAR_IF_FIRST|TDB_DEFAULT, O_RDONLY, 0);
}
return db_ctx;

View File

@ -1203,6 +1203,42 @@ NTSTATUS ctdbd_register_reconfigure(struct ctdbd_connection *conn)
return register_with_ctdbd(conn, CTDB_SRVID_RECONFIGURE);
}
/*
persstent store. Used when we update a record in a persistent database
*/
NTSTATUS ctdbd_persistent_store(struct ctdbd_connection *conn, uint32_t db_id, TDB_DATA key, TDB_DATA data)
{
int cstatus=0;
struct ctdb_rec_data *rec;
TDB_DATA recdata;
size_t length;
NTSTATUS status;
length = offsetof(struct ctdb_rec_data, data) + key.dsize + data.dsize;
rec = (struct ctdb_rec_data *)talloc_size(conn, length);
NT_STATUS_HAVE_NO_MEMORY(rec);
rec->length = length;
rec->reqid = db_id;
rec->keylen = key.dsize;
rec->datalen= data.dsize;
memcpy(&rec->data[0], key.dptr, key.dsize);
memcpy(&rec->data[key.dsize], data.dptr, data.dsize);
recdata.dptr = (uint8_t *)rec;
recdata.dsize = length;
status = ctdbd_control(conn, CTDB_CURRENT_NODE,
CTDB_CONTROL_PERSISTENT_STORE,
0, recdata, NULL, NULL, &cstatus);
if (cstatus != 0) {
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
return status;
}
#else
NTSTATUS ctdbd_init_connection(TALLOC_CTX *mem_ctx,

View File

@ -20,7 +20,9 @@
*/
#include "includes.h"
#ifdef CLUSTER_SUPPORT
#include "ctdb_private.h"
#endif
/*
* Fall back using fetch_locked if no genuine fetch operation is provided
*/
@ -46,10 +48,16 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
int open_flags, mode_t mode)
{
struct db_context *result = NULL;
#ifdef CLUSTER_SUPPORT
const char *sockname = lp_ctdbd_socket();
#endif
#ifdef CLUSTER_SUPPORT
if(!sockname || !*sockname) {
sockname = CTDB_PATH;
}
if (lp_clustering()) {
if (lp_clustering() && socket_exist(sockname)) {
const char *partname;
/* ctdb only wants the file part of the name */
partname = strrchr(name, '/');

View File

@ -18,16 +18,14 @@
*/
#include "includes.h"
#ifdef CLUSTER_SUPPORT
#include "ctdb.h"
#include "ctdb_private.h"
#include "ctdbd_conn.h"
struct db_ctdb_ctx {
struct tdb_wrap *wtdb;
uint32 db_id;
struct ctdbd_connection *conn;
};
struct db_ctdb_rec {
@ -35,8 +33,6 @@ struct db_ctdb_rec {
struct ctdb_ltdb_header header;
};
static struct ctdbd_connection *db_ctdbd_conn(struct db_ctdb_ctx *ctx);
static NTSTATUS db_ctdb_store(struct db_record *rec, TDB_DATA data, int flag)
{
struct db_ctdb_rec *crec = talloc_get_type_abort(
@ -60,6 +56,42 @@ static NTSTATUS db_ctdb_store(struct db_record *rec, TDB_DATA data, int flag)
return (ret == 0) ? NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION;
}
/* for persistent databases the store is a bit different. We have to
ask the ctdb daemon to push the record to all nodes after the
store */
static NTSTATUS db_ctdb_store_persistent(struct db_record *rec, TDB_DATA data, int flag)
{
struct db_ctdb_rec *crec = talloc_get_type_abort(
rec->private_data, struct db_ctdb_rec);
TDB_DATA cdata;
int ret;
NTSTATUS status;
cdata.dsize = sizeof(crec->header) + data.dsize;
if (!(cdata.dptr = SMB_MALLOC_ARRAY(uint8, cdata.dsize))) {
return NT_STATUS_NO_MEMORY;
}
crec->header.rsn++;
memcpy(cdata.dptr, &crec->header, sizeof(crec->header));
memcpy(cdata.dptr + sizeof(crec->header), data.dptr, data.dsize);
ret = tdb_store(crec->ctdb_ctx->wtdb->tdb, rec->key, cdata, TDB_REPLACE);
status = (ret == 0) ? NT_STATUS_OK : NT_STATUS_INTERNAL_DB_CORRUPTION;
/* now tell ctdbd to update this record on all other nodes */
if (NT_STATUS_IS_OK(status)) {
status = ctdbd_persistent_store(messaging_ctdbd_connection(), crec->ctdb_ctx->db_id, rec->key, cdata);
}
SAFE_FREE(cdata.dptr);
return status;
}
static NTSTATUS db_ctdb_delete(struct db_record *rec)
{
struct db_ctdb_rec *crec = talloc_get_type_abort(
@ -110,6 +142,7 @@ static struct db_record *db_ctdb_fetch_locked(struct db_context *db,
struct db_ctdb_rec *crec;
NTSTATUS status;
TDB_DATA ctdb_data;
int migrate_attempts = 0;
if (!(result = talloc(mem_ctx, struct db_record))) {
DEBUG(0, ("talloc failed\n"));
@ -153,7 +186,11 @@ again:
return NULL;
}
result->store = db_ctdb_store;
if (db->persistent) {
result->store = db_ctdb_store_persistent;
} else {
result->store = db_ctdb_store;
}
result->delete_rec = db_ctdb_delete;
talloc_set_destructor(result, db_ctdb_record_destr);
@ -175,12 +212,14 @@ again:
tdb_chainunlock(ctx->wtdb->tdb, key);
talloc_set_destructor(result, NULL);
migrate_attempts += 1;
DEBUG(10, ("ctdb_data.dptr = %p, dmaster = %u (%u)\n",
ctdb_data.dptr, ctdb_data.dptr ?
((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster : -1,
get_my_vnn()));
status = ctdbd_migrate(db_ctdbd_conn(ctx), ctx->db_id, key);
status = ctdbd_migrate(messaging_ctdbd_connection(),ctx->db_id, key);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("ctdb_migrate failed: %s\n",
nt_errstr(status)));
@ -191,6 +230,11 @@ again:
goto again;
}
if (migrate_attempts > 10) {
DEBUG(0, ("db_ctdb_fetch_locked needed %d attempts\n",
migrate_attempts));
}
memcpy(&crec->header, ctdb_data.dptr, sizeof(crec->header));
result->value.dsize = ctdb_data.dsize - sizeof(crec->header);
@ -226,10 +270,12 @@ static int db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
/*
* See if we have a valid record and we are the dmaster. If so, we can
* take the shortcut and just return it.
* we bypass the dmaster check for persistent databases
*/
if ((ctdb_data.dptr != NULL) &&
(ctdb_data.dsize >= sizeof(struct ctdb_ltdb_header)) &&
((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster == get_my_vnn()) {
(db->persistent ||
((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster == get_my_vnn())) {
/* we are the dmaster - avoid the ctdb protocol op */
data->dsize = ctdb_data.dsize - sizeof(struct ctdb_ltdb_header);
@ -254,8 +300,7 @@ static int db_ctdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
SAFE_FREE(ctdb_data.dptr);
/* we weren't able to get it locally - ask ctdb to fetch it for us */
status = ctdbd_fetch(db_ctdbd_conn(ctx), ctx->db_id, key, mem_ctx,
data);
status = ctdbd_fetch(messaging_ctdbd_connection(),ctx->db_id, key, mem_ctx, data);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("ctdbd_fetch failed: %s\n", nt_errstr(status)));
return -1;
@ -283,6 +328,22 @@ static void traverse_callback(TDB_DATA key, TDB_DATA data, void *private_data)
talloc_free(tmp_ctx);
}
static int traverse_persistent_callback(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
void *private_data)
{
struct traverse_state *state = (struct traverse_state *)private_data;
struct db_record *rec;
TALLOC_CTX *tmp_ctx = talloc_new(state->db);
int ret = 0;
/* we have to give them a locked record to prevent races */
rec = db_ctdb_fetch_locked(state->db, tmp_ctx, kbuf);
if (rec && rec->value.dsize > 0) {
ret = state->fn(rec, state->private_data);
}
talloc_free(tmp_ctx);
return ret;
}
static int db_ctdb_traverse(struct db_context *db,
int (*fn)(struct db_record *rec,
void *private_data),
@ -296,6 +357,13 @@ static int db_ctdb_traverse(struct db_context *db,
state.fn = fn;
state.private_data = private_data;
if (db->persistent) {
/* for persistent databases we don't need to do a ctdb traverse,
we can do a faster local traverse */
return tdb_traverse(ctx->wtdb->tdb, traverse_persistent_callback, &state);
}
ctdbd_traverse(ctx->db_id, traverse_callback, &state);
return 0;
}
@ -322,6 +390,27 @@ static void traverse_read_callback(TDB_DATA key, TDB_DATA data, void *private_da
state->fn(&rec, state->private_data);
}
static int traverse_persistent_callback_read(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
void *private_data)
{
struct traverse_state *state = (struct traverse_state *)private_data;
struct db_record rec;
rec.key = kbuf;
rec.value = dbuf;
rec.store = db_ctdb_store_deny;
rec.delete_rec = db_ctdb_delete_deny;
rec.private_data = state->db;
if (rec.value.dsize <= sizeof(struct ctdb_ltdb_header)) {
/* a deleted record */
return 0;
}
rec.value.dsize -= sizeof(struct ctdb_ltdb_header);
rec.value.dptr += sizeof(struct ctdb_ltdb_header);
return state->fn(&rec, state->private_data);
}
static int db_ctdb_traverse_read(struct db_context *db,
int (*fn)(struct db_record *rec,
void *private_data),
@ -335,6 +424,12 @@ static int db_ctdb_traverse_read(struct db_context *db,
state.fn = fn;
state.private_data = private_data;
if (db->persistent) {
/* for persistent databases we don't need to do a ctdb traverse,
we can do a faster local traverse */
return tdb_traverse_read(ctx->wtdb->tdb, traverse_persistent_callback_read, &state);
}
ctdbd_traverse(ctx->db_id, traverse_read_callback, &state);
return 0;
}
@ -346,41 +441,6 @@ static int db_ctdb_get_seqnum(struct db_context *db)
return tdb_get_seqnum(ctx->wtdb->tdb);
}
/*
* Get the ctdbd connection for a database. If possible, re-use the messaging
* ctdbd connection
*/
static struct ctdbd_connection *db_ctdbd_conn(struct db_ctdb_ctx *ctx)
{
struct ctdbd_connection *result;
result = messaging_ctdbd_connection();
if (result != NULL) {
if (ctx->conn == NULL) {
/*
* Someone has initialized messaging since we
* initialized our own connection, we don't need it
* anymore.
*/
TALLOC_FREE(ctx->conn);
}
return result;
}
if (ctx->conn == NULL) {
NTSTATUS status;
status = ctdbd_init_connection(ctx, &ctx->conn);
if (!NT_STATUS_IS_OK(status)) {
return NULL;
}
set_my_vnn(ctdbd_vnn(ctx->conn));
}
return ctx->conn;
}
struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
const char *name,
@ -390,7 +450,6 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
struct db_context *result;
struct db_ctdb_ctx *db_ctdb;
char *db_path;
NTSTATUS status;
if (!lp_clustering()) {
DEBUG(10, ("Clustering disabled -- no ctdb\n"));
@ -409,20 +468,15 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
return NULL;
}
db_ctdb->conn = NULL;
status = ctdbd_db_attach(db_ctdbd_conn(db_ctdb), name,
&db_ctdb->db_id, tdb_flags);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("ctdbd_db_attach failed for %s: %s\n", name,
nt_errstr(status)));
if (!NT_STATUS_IS_OK(ctdbd_db_attach(messaging_ctdbd_connection(),name, &db_ctdb->db_id, tdb_flags))) {
DEBUG(0, ("ctdbd_db_attach failed for %s\n", name));
TALLOC_FREE(result);
return NULL;
}
db_path = ctdbd_dbpath(db_ctdbd_conn(db_ctdb), db_ctdb,
db_ctdb->db_id);
db_path = ctdbd_dbpath(messaging_ctdbd_connection(), db_ctdb, db_ctdb->db_id);
result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
/* only pass through specific flags */
tdb_flags &= TDB_SEQNUM;
@ -447,16 +501,4 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
return result;
}
#else
struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
const char *name,
int hash_size, int tdb_flags,
int open_flags, mode_t mode)
{
DEBUG(0, ("no clustering compiled in\n"));
return NULL;
}
#endif

View File

@ -17,10 +17,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Be aware that this is just sample code that has not seen too much testing
*/
#include "includes.h"
struct db_file_ctx {
@ -367,6 +363,7 @@ struct db_context *db_open_file(TALLOC_CTX *mem_ctx,
result->fetch_locked = db_file_fetch_locked;
result->traverse = db_file_traverse;
result->traverse_read = db_file_traverse;
result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
ctx->locked_record = NULL;
if (!(ctx->dirname = talloc_strdup(ctx, name))) {

View File

@ -31,6 +31,11 @@ static int db_tdb_record_destr(struct db_record* data)
struct db_tdb_ctx *ctx =
talloc_get_type_abort(data->private_data, struct db_tdb_ctx);
/* This hex_encode() call allocates memory on data context. By way how current
__talloc_free() code works, it is OK to allocate in the destructor as
the children of data will be freed after call to the destructor and this
new 'child' will be caught and freed correctly.
*/
DEBUG(10, (DEBUGLEVEL > 10
? "Unlocking key %s\n" : "Unlocking key %.20s\n",
hex_encode(data, (unsigned char *)data->key.dptr,
@ -88,8 +93,9 @@ static struct db_record *db_tdb_fetch_locked(struct db_context *db,
struct tdb_fetch_locked_state state;
int res;
if (DEBUGLEVEL >= 10) {
char *keystr = hex_encode(NULL, key.dptr, key.dsize);
/* Do not accidently allocate/deallocate w/o need when debug level is lower than needed */
if(DEBUGLEVEL >= 10) {
char *keystr = hex_encode(NULL, (unsigned char*)key.dptr, key.dsize);
DEBUG(10, (DEBUGLEVEL > 10
? "Locking key %s\n" : "Locking key %.20s\n",
keystr));
@ -191,15 +197,9 @@ static NTSTATUS db_tdb_delete(struct db_record *rec)
{
struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data,
struct db_tdb_ctx);
int res;
res = tdb_delete(ctx->wtdb->tdb, rec->key);
if (res == 0) {
return NT_STATUS_OK;
}
return map_nt_error_from_tdb(tdb_error(ctx->wtdb->tdb));
return (tdb_delete(ctx->wtdb->tdb, rec->key) == 0) ?
NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
}
struct db_tdb_traverse_ctx {
@ -318,6 +318,7 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
result->traverse = db_tdb_traverse;
result->traverse_read = db_tdb_traverse_read;
result->get_seqnum = db_tdb_get_seqnum;
result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
return result;
fail:

90
source3/lib/dbwrap_util.c Normal file
View File

@ -0,0 +1,90 @@
/*
Unix SMB/CIFS implementation.
Utility functions for the dbwrap API
Copyright (C) Volker Lendecke 2007
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
int32_t dbwrap_fetch_int32(struct db_context *db, const char *keystr)
{
TDB_DATA dbuf;
int32 ret;
if (db->fetch(db, NULL, string_term_tdb_data(keystr), &dbuf) != 0) {
return -1;
}
if ((dbuf.dptr == NULL) || (dbuf.dsize != sizeof(int32_t))) {
TALLOC_FREE(dbuf.dptr);
return -1;
}
ret = IVAL(dbuf.dptr, 0);
TALLOC_FREE(dbuf.dptr);
return ret;
}
int dbwrap_store_int32(struct db_context *db, const char *keystr, int32_t v)
{
struct db_record *rec;
int32 v_store;
NTSTATUS status;
rec = db->fetch_locked(db, NULL, string_term_tdb_data(keystr));
if (rec == NULL) {
return -1;
}
SIVAL(&v_store, 0, v);
status = rec->store(rec, make_tdb_data((const uint8 *)&v_store,
sizeof(v_store)),
TDB_REPLACE);
TALLOC_FREE(rec);
return NT_STATUS_IS_OK(status) ? 0 : -1;
}
uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr,
uint32_t *oldval, uint32_t change_val)
{
struct db_record *rec;
uint32 val = -1;
TDB_DATA data;
if (!(rec = db->fetch_locked(db, NULL,
string_term_tdb_data(keystr)))) {
return -1;
}
if ((rec->value.dptr != NULL)
&& (rec->value.dsize == sizeof(val))) {
val = IVAL(rec->value.dptr, 0);
}
val += change_val;
data.dsize = sizeof(val);
data.dptr = (uint8 *)&val;
rec->store(rec, data, TDB_REPLACE);
TALLOC_FREE(rec);
return 0;
}

View File

@ -22,6 +22,10 @@
#ifdef CLUSTER_SUPPORT
#include "librpc/gen_ndr/messaging.h"
#include "ctdb.h"
#include "ctdb_private.h"
#include "ctdbd_conn.h"
struct messaging_ctdbd_context {
struct ctdbd_connection *conn;

View File

@ -167,7 +167,7 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx,
return WERR_INVALID_PARAM;
}
if (!lp_include_registry_globals()) {
if (!lp_config_backend_is_registry()) {
return WERR_NOT_SUPPORTED;
}

View File

@ -505,6 +505,19 @@ bool file_exist(const char *fname,SMB_STRUCT_STAT *sbuf)
return((S_ISREG(sbuf->st_mode)) || (S_ISFIFO(sbuf->st_mode)));
}
/*******************************************************************
Check if a unix domain socket exists - call vfs_file_exist for samba files.
********************************************************************/
bool socket_exist(const char *fname)
{
SMB_STRUCT_STAT st;
if (sys_stat(fname,&st) != 0)
return(False);
return S_ISSOCK(st.st_mode);
}
/*******************************************************************
Check a files mod time.
********************************************************************/

View File

@ -130,6 +130,7 @@ bool registry_smbconf_valname_forbidden(const char *valname)
"include",
"lock directory",
"lock dir",
"config backend",
NULL
};
const char **forbidden = NULL;

View File

@ -32,18 +32,23 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int
r = SMB_STRDUP(realm);
if (!r || !*r)
if (!r || !*r) {
return r;
}
for (p=r; *p; p++)
if (strchr(sep, *p))
for (p=r; *p; p++) {
if (strchr(sep, *p)) {
numbits++;
}
}
len = (numbits+1)*(strlen(field)+1) + strlen(r) + 1;
ret = (char *)SMB_MALLOC(len);
if (!ret)
if (!ret) {
free(r);
return NULL;
}
strlcpy(ret,field, len);
p=strtok(r,sep);
@ -57,7 +62,8 @@ char *ads_build_path(const char *realm, const char *sep, const char *field, int
else
asprintf(&s, "%s,%s%s", ret, field, p);
free(ret);
ret = s;
ret = SMB_STRDUP(s);
free(s);
}
}

View File

@ -1041,7 +1041,7 @@ static WERROR libnet_join_pre_processing(TALLOC_CTX *mem_ctx,
return WERR_INVALID_PARAM;
}
if (r->in.modify_config && !lp_include_registry_globals()) {
if (r->in.modify_config && !lp_config_backend_is_registry()) {
return WERR_NOT_SUPPORTED;
}
@ -1350,7 +1350,7 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx,
static WERROR libnet_unjoin_pre_processing(TALLOC_CTX *mem_ctx,
struct libnet_UnjoinCtx *r)
{
if (r->in.modify_config && !lp_include_registry_globals()) {
if (r->in.modify_config && !lp_config_backend_is_registry()) {
return WERR_NOT_SUPPORTED;
}

View File

@ -609,7 +609,7 @@ NTSTATUS rpccli_lsa_LookupNames(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray *sids,
uint16_t level,
enum lsa_LookupNamesLevel level,
uint32_t *count)
{
struct lsa_LookupNames r;
@ -2528,7 +2528,7 @@ NTSTATUS rpccli_lsa_LookupNames2(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray2 *sids,
uint16_t level,
enum lsa_LookupNamesLevel level,
uint32_t *count,
uint32_t unknown1,
uint32_t unknown2)
@ -2920,7 +2920,7 @@ NTSTATUS rpccli_lsa_LookupNames3(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray3 *sids,
uint16_t level,
enum lsa_LookupNamesLevel level,
uint32_t *count,
uint32_t unknown1,
uint32_t unknown2)
@ -3120,16 +3120,23 @@ NTSTATUS rpccli_lsa_LSARUNREGISTERAUDITEVENT(struct rpc_pipe_client *cli,
return r.out.result;
}
NTSTATUS rpccli_lsa_LSARQUERYFORESTTRUSTINFORMATION(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx)
NTSTATUS rpccli_lsa_lsaRQueryForestTrustInformation(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle,
struct lsa_String *trusted_domain_name,
uint16_t unknown,
struct lsa_ForestTrustInformation **forest_trust_info)
{
struct lsa_LSARQUERYFORESTTRUSTINFORMATION r;
struct lsa_lsaRQueryForestTrustInformation r;
NTSTATUS status;
/* In parameters */
r.in.handle = handle;
r.in.trusted_domain_name = trusted_domain_name;
r.in.unknown = unknown;
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(lsa_LSARQUERYFORESTTRUSTINFORMATION, &r);
NDR_PRINT_IN_DEBUG(lsa_lsaRQueryForestTrustInformation, &r);
}
status = cli_do_rpc_ndr(cli,
@ -3144,7 +3151,7 @@ NTSTATUS rpccli_lsa_LSARQUERYFORESTTRUSTINFORMATION(struct rpc_pipe_client *cli,
}
if (DEBUGLEVEL >= 10) {
NDR_PRINT_OUT_DEBUG(lsa_LSARQUERYFORESTTRUSTINFORMATION, &r);
NDR_PRINT_OUT_DEBUG(lsa_lsaRQueryForestTrustInformation, &r);
}
if (NT_STATUS_IS_ERR(status)) {
@ -3152,6 +3159,7 @@ NTSTATUS rpccli_lsa_LSARQUERYFORESTTRUSTINFORMATION(struct rpc_pipe_client *cli,
}
/* Return variables */
*forest_trust_info = *r.out.forest_trust_info;
/* Return result */
return r.out.result;
@ -3292,7 +3300,7 @@ NTSTATUS rpccli_lsa_LookupNames4(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray3 *sids,
uint16_t level,
enum lsa_LookupNamesLevel level,
uint32_t *count,
uint32_t unknown1,
uint32_t unknown2)

View File

@ -71,7 +71,7 @@ NTSTATUS rpccli_lsa_LookupNames(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray *sids,
uint16_t level,
enum lsa_LookupNamesLevel level,
uint32_t *count);
NTSTATUS rpccli_lsa_LookupSids(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
@ -280,7 +280,7 @@ NTSTATUS rpccli_lsa_LookupNames2(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray2 *sids,
uint16_t level,
enum lsa_LookupNamesLevel level,
uint32_t *count,
uint32_t unknown1,
uint32_t unknown2);
@ -309,7 +309,7 @@ NTSTATUS rpccli_lsa_LookupNames3(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray3 *sids,
uint16_t level,
enum lsa_LookupNamesLevel level,
uint32_t *count,
uint32_t unknown1,
uint32_t unknown2);
@ -321,8 +321,12 @@ NTSTATUS rpccli_lsa_LSARGENAUDITEVENT(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx);
NTSTATUS rpccli_lsa_LSARUNREGISTERAUDITEVENT(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx);
NTSTATUS rpccli_lsa_LSARQUERYFORESTTRUSTINFORMATION(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx);
NTSTATUS rpccli_lsa_lsaRQueryForestTrustInformation(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
struct policy_handle *handle,
struct lsa_String *trusted_domain_name,
uint16_t unknown,
struct lsa_ForestTrustInformation **forest_trust_info);
NTSTATUS rpccli_lsa_LSARSETFORESTTRUSTINFORMATION(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx);
NTSTATUS rpccli_lsa_CREDRRENAME(struct rpc_pipe_client *cli,
@ -342,7 +346,7 @@ NTSTATUS rpccli_lsa_LookupNames4(struct rpc_pipe_client *cli,
struct lsa_String *names,
struct lsa_RefDomainList *domains,
struct lsa_TransSidArray3 *sids,
uint16_t level,
enum lsa_LookupNamesLevel level,
uint32_t *count,
uint32_t unknown1,
uint32_t unknown2);

View File

@ -75,9 +75,55 @@ struct lsa_AuditLogInfo {
uint32_t unknown;
};
enum lsa_PolicyAuditPolicy
#ifndef USE_UINT_ENUMS
{
LSA_AUDIT_POLICY_NONE=0,
LSA_AUDIT_POLICY_SUCCESS=1,
LSA_AUDIT_POLICY_FAILURE=2,
LSA_AUDIT_POLICY_ALL=(LSA_AUDIT_POLICY_SUCCESS|LSA_AUDIT_POLICY_FAILURE),
LSA_AUDIT_POLICY_CLEAR=4
}
#else
{ __donnot_use_enum_lsa_PolicyAuditPolicy=0x7FFFFFFF}
#define LSA_AUDIT_POLICY_NONE ( 0 )
#define LSA_AUDIT_POLICY_SUCCESS ( 1 )
#define LSA_AUDIT_POLICY_FAILURE ( 2 )
#define LSA_AUDIT_POLICY_ALL ( (LSA_AUDIT_POLICY_SUCCESS|LSA_AUDIT_POLICY_FAILURE) )
#define LSA_AUDIT_POLICY_CLEAR ( 4 )
#endif
;
enum lsa_PolicyAuditEventType
#ifndef USE_UINT_ENUMS
{
LSA_AUDIT_CATEGORY_SYSTEM=0,
LSA_AUDIT_CATEGORY_LOGON=1,
LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS=2,
LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS=3,
LSA_AUDIT_CATEGORY_PROCCESS_TRACKING=4,
LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES=5,
LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT=6,
LSA_AUDIT_CATEGORY_DIRECTORY_SERVICE_ACCESS=7,
LSA_AUDIT_CATEGORY_ACCOUNT_LOGON=8
}
#else
{ __donnot_use_enum_lsa_PolicyAuditEventType=0x7FFFFFFF}
#define LSA_AUDIT_CATEGORY_SYSTEM ( 0 )
#define LSA_AUDIT_CATEGORY_LOGON ( 1 )
#define LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS ( 2 )
#define LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS ( 3 )
#define LSA_AUDIT_CATEGORY_PROCCESS_TRACKING ( 4 )
#define LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES ( 5 )
#define LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT ( 6 )
#define LSA_AUDIT_CATEGORY_DIRECTORY_SERVICE_ACCESS ( 7 )
#define LSA_AUDIT_CATEGORY_ACCOUNT_LOGON ( 8 )
#endif
;
struct lsa_AuditEventsInfo {
uint32_t auditing_mode;
uint32_t *settings;/* [unique,size_is(count)] */
enum lsa_PolicyAuditPolicy *settings;/* [unique,size_is(count)] */
uint32_t count;
};
@ -240,6 +286,27 @@ struct lsa_RefDomainList {
uint32_t max_size;
};
enum lsa_LookupNamesLevel
#ifndef USE_UINT_ENUMS
{
LSA_LOOKUP_NAMES_ALL=1,
LSA_LOOKUP_NAMES_DOMAINS_ONLY=2,
LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY=3,
LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY=4,
LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY=5,
LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2=6
}
#else
{ __donnot_use_enum_lsa_LookupNamesLevel=0x7FFFFFFF}
#define LSA_LOOKUP_NAMES_ALL ( 1 )
#define LSA_LOOKUP_NAMES_DOMAINS_ONLY ( 2 )
#define LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY ( 3 )
#define LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY ( 4 )
#define LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY ( 5 )
#define LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 ( 6 )
#endif
;
struct lsa_TranslatedName {
enum lsa_SidType sid_type;
struct lsa_String name;
@ -464,6 +531,53 @@ struct lsa_TransSidArray3 {
struct lsa_TranslatedSid3 *sids;/* [unique,size_is(count)] */
};
struct lsa_ForestTrustBinaryData {
uint32_t length;/* [range(0 131072)] */
uint8_t *data;/* [unique,size_is(length)] */
};
struct lsa_ForestTrustDomainInfo {
struct dom_sid2 *domain_sid;/* [unique] */
struct lsa_StringLarge dns_domain_name;
struct lsa_StringLarge netbios_domain_name;
};
union lsa_ForestTrustData {
struct lsa_String top_level_name;/* [case(LSA_FOREST_TRUST_TOP_LEVEL_NAME)] */
struct lsa_StringLarge top_level_name_ex;/* [case(LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX)] */
struct lsa_ForestTrustDomainInfo domain_info;/* [case(LSA_FOREST_TRUST_DOMAIN_INFO)] */
struct lsa_ForestTrustBinaryData data;/* [default] */
}/* [switch_type(uint32)] */;
enum lsa_ForestTrustRecordType
#ifndef USE_UINT_ENUMS
{
LSA_FOREST_TRUST_TOP_LEVEL_NAME=0,
LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX=1,
LSA_FOREST_TRUST_DOMAIN_INFO=2,
LSA_FOREST_TRUST_RECORD_TYPE_LAST=3
}
#else
{ __donnot_use_enum_lsa_ForestTrustRecordType=0x7FFFFFFF}
#define LSA_FOREST_TRUST_TOP_LEVEL_NAME ( 0 )
#define LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX ( 1 )
#define LSA_FOREST_TRUST_DOMAIN_INFO ( 2 )
#define LSA_FOREST_TRUST_RECORD_TYPE_LAST ( 3 )
#endif
;
struct lsa_ForestTrustRecord {
uint32_t flags;
enum lsa_ForestTrustRecordType level;
uint64_t unknown;
union lsa_ForestTrustData forest_trust_data;/* [switch_is(level)] */
};
struct lsa_ForestTrustInformation {
uint32_t count;/* [range(0 4000)] */
struct lsa_ForestTrustRecord **entries;/* [unique,size_is(count)] */
}/* [public] */;
struct lsa_Close {
struct {
@ -636,7 +750,7 @@ struct lsa_CreateTrustedDomain {
struct lsa_EnumTrustDom {
struct {
struct policy_handle *handle;/* [ref] */
uint32_t max_size;/* [range(0 1000)] */
uint32_t max_size;
uint32_t *resume_handle;/* [ref] */
} in;
@ -654,7 +768,7 @@ struct lsa_LookupNames {
struct policy_handle *handle;/* [ref] */
uint32_t num_names;/* [range(0 1000)] */
struct lsa_String *names;/* [size_is(num_names)] */
uint16_t level;
enum lsa_LookupNamesLevel level;
struct lsa_TransSidArray *sids;/* [ref] */
uint32_t *count;/* [ref] */
} in;
@ -1241,7 +1355,7 @@ struct lsa_LookupNames2 {
struct policy_handle *handle;/* [ref] */
uint32_t num_names;/* [range(0 1000)] */
struct lsa_String *names;/* [size_is(num_names)] */
uint16_t level;
enum lsa_LookupNamesLevel level;
uint32_t unknown1;
uint32_t unknown2;
struct lsa_TransSidArray2 *sids;/* [ref] */
@ -1335,7 +1449,7 @@ struct lsa_LookupNames3 {
struct policy_handle *handle;/* [ref] */
uint32_t num_names;/* [range(0 1000)] */
struct lsa_String *names;/* [size_is(num_names)] */
uint16_t level;
enum lsa_LookupNamesLevel level;
uint32_t unknown1;
uint32_t unknown2;
struct lsa_TransSidArray3 *sids;/* [ref] */
@ -1384,8 +1498,15 @@ struct lsa_LSARUNREGISTERAUDITEVENT {
};
struct lsa_LSARQUERYFORESTTRUSTINFORMATION {
struct lsa_lsaRQueryForestTrustInformation {
struct {
struct policy_handle *handle;/* [ref] */
struct lsa_String *trusted_domain_name;/* [ref] */
uint16_t unknown;
} in;
struct {
struct lsa_ForestTrustInformation **forest_trust_info;/* [ref] */
NTSTATUS result;
} out;
@ -1432,7 +1553,7 @@ struct lsa_LookupNames4 {
struct {
uint32_t num_names;/* [range(0 1000)] */
struct lsa_String *names;/* [size_is(num_names)] */
uint16_t level;
enum lsa_LookupNamesLevel level;
uint32_t unknown1;
uint32_t unknown2;
struct lsa_TransSidArray3 *sids;/* [ref] */

File diff suppressed because it is too large Load Diff

View File

@ -194,6 +194,7 @@ void ndr_print_lsa_PrivArray(struct ndr_print *ndr, const char *name, const stru
void ndr_print_lsa_QosInfo(struct ndr_print *ndr, const char *name, const struct lsa_QosInfo *r);
void ndr_print_lsa_ObjectAttribute(struct ndr_print *ndr, const char *name, const struct lsa_ObjectAttribute *r);
void ndr_print_lsa_AuditLogInfo(struct ndr_print *ndr, const char *name, const struct lsa_AuditLogInfo *r);
void ndr_print_lsa_PolicyAuditPolicy(struct ndr_print *ndr, const char *name, enum lsa_PolicyAuditPolicy r);
void ndr_print_lsa_AuditEventsInfo(struct ndr_print *ndr, const char *name, const struct lsa_AuditEventsInfo *r);
void ndr_print_lsa_DomainInfo(struct ndr_print *ndr, const char *name, const struct lsa_DomainInfo *r);
void ndr_print_lsa_PDAccountInfo(struct ndr_print *ndr, const char *name, const struct lsa_PDAccountInfo *r);
@ -215,6 +216,7 @@ void ndr_print_lsa_SidType(struct ndr_print *ndr, const char *name, enum lsa_Sid
void ndr_print_lsa_TranslatedSid(struct ndr_print *ndr, const char *name, const struct lsa_TranslatedSid *r);
void ndr_print_lsa_TransSidArray(struct ndr_print *ndr, const char *name, const struct lsa_TransSidArray *r);
void ndr_print_lsa_RefDomainList(struct ndr_print *ndr, const char *name, const struct lsa_RefDomainList *r);
void ndr_print_lsa_LookupNamesLevel(struct ndr_print *ndr, const char *name, enum lsa_LookupNamesLevel r);
void ndr_print_lsa_TranslatedName(struct ndr_print *ndr, const char *name, const struct lsa_TranslatedName *r);
void ndr_print_lsa_TransNameArray(struct ndr_print *ndr, const char *name, const struct lsa_TransNameArray *r);
void ndr_print_lsa_LUIDAttribute(struct ndr_print *ndr, const char *name, const struct lsa_LUIDAttribute *r);
@ -246,22 +248,48 @@ void ndr_print_lsa_TranslatedSid2(struct ndr_print *ndr, const char *name, const
void ndr_print_lsa_TransSidArray2(struct ndr_print *ndr, const char *name, const struct lsa_TransSidArray2 *r);
void ndr_print_lsa_TranslatedSid3(struct ndr_print *ndr, const char *name, const struct lsa_TranslatedSid3 *r);
void ndr_print_lsa_TransSidArray3(struct ndr_print *ndr, const char *name, const struct lsa_TransSidArray3 *r);
void ndr_print_lsa_ForestTrustBinaryData(struct ndr_print *ndr, const char *name, const struct lsa_ForestTrustBinaryData *r);
void ndr_print_lsa_ForestTrustDomainInfo(struct ndr_print *ndr, const char *name, const struct lsa_ForestTrustDomainInfo *r);
void ndr_print_lsa_ForestTrustData(struct ndr_print *ndr, const char *name, const union lsa_ForestTrustData *r);
void ndr_print_lsa_ForestTrustRecordType(struct ndr_print *ndr, const char *name, enum lsa_ForestTrustRecordType r);
void ndr_print_lsa_ForestTrustRecord(struct ndr_print *ndr, const char *name, const struct lsa_ForestTrustRecord *r);
enum ndr_err_code ndr_push_lsa_ForestTrustInformation(struct ndr_push *ndr, int ndr_flags, const struct lsa_ForestTrustInformation *r);
enum ndr_err_code ndr_pull_lsa_ForestTrustInformation(struct ndr_pull *ndr, int ndr_flags, struct lsa_ForestTrustInformation *r);
void ndr_print_lsa_ForestTrustInformation(struct ndr_print *ndr, const char *name, const struct lsa_ForestTrustInformation *r);
void ndr_print_lsa_Close(struct ndr_print *ndr, const char *name, int flags, const struct lsa_Close *r);
enum ndr_err_code ndr_push_lsa_Delete(struct ndr_push *ndr, int flags, const struct lsa_Delete *r);
enum ndr_err_code ndr_pull_lsa_Delete(struct ndr_pull *ndr, int flags, struct lsa_Delete *r);
void ndr_print_lsa_Delete(struct ndr_print *ndr, const char *name, int flags, const struct lsa_Delete *r);
enum ndr_err_code ndr_push_lsa_EnumPrivs(struct ndr_push *ndr, int flags, const struct lsa_EnumPrivs *r);
enum ndr_err_code ndr_pull_lsa_EnumPrivs(struct ndr_pull *ndr, int flags, struct lsa_EnumPrivs *r);
void ndr_print_lsa_EnumPrivs(struct ndr_print *ndr, const char *name, int flags, const struct lsa_EnumPrivs *r);
void ndr_print_lsa_QuerySecurity(struct ndr_print *ndr, const char *name, int flags, const struct lsa_QuerySecurity *r);
void ndr_print_lsa_SetSecObj(struct ndr_print *ndr, const char *name, int flags, const struct lsa_SetSecObj *r);
void ndr_print_lsa_ChangePassword(struct ndr_print *ndr, const char *name, int flags, const struct lsa_ChangePassword *r);
enum ndr_err_code ndr_push_lsa_OpenPolicy(struct ndr_push *ndr, int flags, const struct lsa_OpenPolicy *r);
enum ndr_err_code ndr_pull_lsa_OpenPolicy(struct ndr_pull *ndr, int flags, struct lsa_OpenPolicy *r);
void ndr_print_lsa_OpenPolicy(struct ndr_print *ndr, const char *name, int flags, const struct lsa_OpenPolicy *r);
void ndr_print_lsa_QueryInfoPolicy(struct ndr_print *ndr, const char *name, int flags, const struct lsa_QueryInfoPolicy *r);
void ndr_print_lsa_SetInfoPolicy(struct ndr_print *ndr, const char *name, int flags, const struct lsa_SetInfoPolicy *r);
void ndr_print_lsa_ClearAuditLog(struct ndr_print *ndr, const char *name, int flags, const struct lsa_ClearAuditLog *r);
enum ndr_err_code ndr_push_lsa_CreateAccount(struct ndr_push *ndr, int flags, const struct lsa_CreateAccount *r);
enum ndr_err_code ndr_pull_lsa_CreateAccount(struct ndr_pull *ndr, int flags, struct lsa_CreateAccount *r);
void ndr_print_lsa_CreateAccount(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CreateAccount *r);
enum ndr_err_code ndr_push_lsa_EnumAccounts(struct ndr_push *ndr, int flags, const struct lsa_EnumAccounts *r);
enum ndr_err_code ndr_pull_lsa_EnumAccounts(struct ndr_pull *ndr, int flags, struct lsa_EnumAccounts *r);
void ndr_print_lsa_EnumAccounts(struct ndr_print *ndr, const char *name, int flags, const struct lsa_EnumAccounts *r);
enum ndr_err_code ndr_push_lsa_CreateTrustedDomain(struct ndr_push *ndr, int flags, const struct lsa_CreateTrustedDomain *r);
enum ndr_err_code ndr_pull_lsa_CreateTrustedDomain(struct ndr_pull *ndr, int flags, struct lsa_CreateTrustedDomain *r);
void ndr_print_lsa_CreateTrustedDomain(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CreateTrustedDomain *r);
void ndr_print_lsa_EnumTrustDom(struct ndr_print *ndr, const char *name, int flags, const struct lsa_EnumTrustDom *r);
enum ndr_err_code ndr_push_lsa_LookupNames(struct ndr_push *ndr, int flags, const struct lsa_LookupNames *r);
enum ndr_err_code ndr_pull_lsa_LookupNames(struct ndr_pull *ndr, int flags, struct lsa_LookupNames *r);
void ndr_print_lsa_LookupNames(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupNames *r);
enum ndr_err_code ndr_push_lsa_LookupSids(struct ndr_push *ndr, int flags, const struct lsa_LookupSids *r);
enum ndr_err_code ndr_pull_lsa_LookupSids(struct ndr_pull *ndr, int flags, struct lsa_LookupSids *r);
void ndr_print_lsa_LookupSids(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupSids *r);
enum ndr_err_code ndr_push_lsa_CreateSecret(struct ndr_push *ndr, int flags, const struct lsa_CreateSecret *r);
enum ndr_err_code ndr_pull_lsa_CreateSecret(struct ndr_pull *ndr, int flags, struct lsa_CreateSecret *r);
void ndr_print_lsa_CreateSecret(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CreateSecret *r);
void ndr_print_lsa_OpenAccount(struct ndr_print *ndr, const char *name, int flags, const struct lsa_OpenAccount *r);
void ndr_print_lsa_EnumPrivsAccount(struct ndr_print *ndr, const char *name, int flags, const struct lsa_EnumPrivsAccount *r);
@ -274,8 +302,14 @@ void ndr_print_lsa_SetSystemAccessAccount(struct ndr_print *ndr, const char *nam
void ndr_print_lsa_OpenTrustedDomain(struct ndr_print *ndr, const char *name, int flags, const struct lsa_OpenTrustedDomain *r);
void ndr_print_lsa_QueryTrustedDomainInfo(struct ndr_print *ndr, const char *name, int flags, const struct lsa_QueryTrustedDomainInfo *r);
void ndr_print_lsa_SetInformationTrustedDomain(struct ndr_print *ndr, const char *name, int flags, const struct lsa_SetInformationTrustedDomain *r);
enum ndr_err_code ndr_push_lsa_OpenSecret(struct ndr_push *ndr, int flags, const struct lsa_OpenSecret *r);
enum ndr_err_code ndr_pull_lsa_OpenSecret(struct ndr_pull *ndr, int flags, struct lsa_OpenSecret *r);
void ndr_print_lsa_OpenSecret(struct ndr_print *ndr, const char *name, int flags, const struct lsa_OpenSecret *r);
enum ndr_err_code ndr_push_lsa_SetSecret(struct ndr_push *ndr, int flags, const struct lsa_SetSecret *r);
enum ndr_err_code ndr_pull_lsa_SetSecret(struct ndr_pull *ndr, int flags, struct lsa_SetSecret *r);
void ndr_print_lsa_SetSecret(struct ndr_print *ndr, const char *name, int flags, const struct lsa_SetSecret *r);
enum ndr_err_code ndr_push_lsa_QuerySecret(struct ndr_push *ndr, int flags, const struct lsa_QuerySecret *r);
enum ndr_err_code ndr_pull_lsa_QuerySecret(struct ndr_pull *ndr, int flags, struct lsa_QuerySecret *r);
void ndr_print_lsa_QuerySecret(struct ndr_print *ndr, const char *name, int flags, const struct lsa_QuerySecret *r);
void ndr_print_lsa_LookupPrivValue(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupPrivValue *r);
void ndr_print_lsa_LookupPrivName(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupPrivName *r);
@ -290,6 +324,8 @@ void ndr_print_lsa_SetTrustedDomainInfo(struct ndr_print *ndr, const char *name,
void ndr_print_lsa_DeleteTrustedDomain(struct ndr_print *ndr, const char *name, int flags, const struct lsa_DeleteTrustedDomain *r);
void ndr_print_lsa_StorePrivateData(struct ndr_print *ndr, const char *name, int flags, const struct lsa_StorePrivateData *r);
void ndr_print_lsa_RetrievePrivateData(struct ndr_print *ndr, const char *name, int flags, const struct lsa_RetrievePrivateData *r);
enum ndr_err_code ndr_push_lsa_OpenPolicy2(struct ndr_push *ndr, int flags, const struct lsa_OpenPolicy2 *r);
enum ndr_err_code ndr_pull_lsa_OpenPolicy2(struct ndr_pull *ndr, int flags, struct lsa_OpenPolicy2 *r);
void ndr_print_lsa_OpenPolicy2(struct ndr_print *ndr, const char *name, int flags, const struct lsa_OpenPolicy2 *r);
void ndr_print_lsa_GetUserName(struct ndr_print *ndr, const char *name, int flags, const struct lsa_GetUserName *r);
void ndr_print_lsa_QueryInfoPolicy2(struct ndr_print *ndr, const char *name, int flags, const struct lsa_QueryInfoPolicy2 *r);
@ -303,7 +339,11 @@ void ndr_print_lsa_QueryDomainInformationPolicy(struct ndr_print *ndr, const cha
void ndr_print_lsa_SetDomainInformationPolicy(struct ndr_print *ndr, const char *name, int flags, const struct lsa_SetDomainInformationPolicy *r);
void ndr_print_lsa_OpenTrustedDomainByName(struct ndr_print *ndr, const char *name, int flags, const struct lsa_OpenTrustedDomainByName *r);
void ndr_print_lsa_TestCall(struct ndr_print *ndr, const char *name, int flags, const struct lsa_TestCall *r);
enum ndr_err_code ndr_push_lsa_LookupSids2(struct ndr_push *ndr, int flags, const struct lsa_LookupSids2 *r);
enum ndr_err_code ndr_pull_lsa_LookupSids2(struct ndr_pull *ndr, int flags, struct lsa_LookupSids2 *r);
void ndr_print_lsa_LookupSids2(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupSids2 *r);
enum ndr_err_code ndr_push_lsa_LookupNames2(struct ndr_push *ndr, int flags, const struct lsa_LookupNames2 *r);
enum ndr_err_code ndr_pull_lsa_LookupNames2(struct ndr_pull *ndr, int flags, struct lsa_LookupNames2 *r);
void ndr_print_lsa_LookupNames2(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupNames2 *r);
void ndr_print_lsa_CreateTrustedDomainEx2(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CreateTrustedDomainEx2 *r);
void ndr_print_lsa_CREDRWRITE(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CREDRWRITE *r);
@ -314,14 +354,18 @@ void ndr_print_lsa_CREDRREADDOMAINCREDENTIALS(struct ndr_print *ndr, const char
void ndr_print_lsa_CREDRDELETE(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CREDRDELETE *r);
void ndr_print_lsa_CREDRGETTARGETINFO(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CREDRGETTARGETINFO *r);
void ndr_print_lsa_CREDRPROFILELOADED(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CREDRPROFILELOADED *r);
enum ndr_err_code ndr_push_lsa_LookupNames3(struct ndr_push *ndr, int flags, const struct lsa_LookupNames3 *r);
enum ndr_err_code ndr_pull_lsa_LookupNames3(struct ndr_pull *ndr, int flags, struct lsa_LookupNames3 *r);
void ndr_print_lsa_LookupNames3(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupNames3 *r);
void ndr_print_lsa_CREDRGETSESSIONTYPES(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CREDRGETSESSIONTYPES *r);
void ndr_print_lsa_LSARREGISTERAUDITEVENT(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LSARREGISTERAUDITEVENT *r);
void ndr_print_lsa_LSARGENAUDITEVENT(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LSARGENAUDITEVENT *r);
void ndr_print_lsa_LSARUNREGISTERAUDITEVENT(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LSARUNREGISTERAUDITEVENT *r);
void ndr_print_lsa_LSARQUERYFORESTTRUSTINFORMATION(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r);
void ndr_print_lsa_lsaRQueryForestTrustInformation(struct ndr_print *ndr, const char *name, int flags, const struct lsa_lsaRQueryForestTrustInformation *r);
void ndr_print_lsa_LSARSETFORESTTRUSTINFORMATION(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LSARSETFORESTTRUSTINFORMATION *r);
void ndr_print_lsa_CREDRRENAME(struct ndr_print *ndr, const char *name, int flags, const struct lsa_CREDRRENAME *r);
enum ndr_err_code ndr_push_lsa_LookupSids3(struct ndr_push *ndr, int flags, const struct lsa_LookupSids3 *r);
enum ndr_err_code ndr_pull_lsa_LookupSids3(struct ndr_pull *ndr, int flags, struct lsa_LookupSids3 *r);
void ndr_print_lsa_LookupSids3(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupSids3 *r);
void ndr_print_lsa_LookupNames4(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LookupNames4 *r);
void ndr_print_lsa_LSAROPENPOLICYSCE(struct ndr_print *ndr, const char *name, int flags, const struct lsa_LSAROPENPOLICYSCE *r);

View File

@ -5579,18 +5579,18 @@ static bool api_lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p)
return true;
}
static bool api_lsa_LSARQUERYFORESTTRUSTINFORMATION(pipes_struct *p)
static bool api_lsa_lsaRQueryForestTrustInformation(pipes_struct *p)
{
const struct ndr_interface_call *call;
struct ndr_pull *pull;
struct ndr_push *push;
enum ndr_err_code ndr_err;
DATA_BLOB blob;
struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r;
struct lsa_lsaRQueryForestTrustInformation *r;
call = &ndr_table_lsarpc.calls[NDR_LSA_LSARQUERYFORESTTRUSTINFORMATION];
r = talloc(NULL, struct lsa_LSARQUERYFORESTTRUSTINFORMATION);
r = talloc(NULL, struct lsa_lsaRQueryForestTrustInformation);
if (r == NULL) {
return false;
}
@ -5614,10 +5614,17 @@ static bool api_lsa_LSARQUERYFORESTTRUSTINFORMATION(pipes_struct *p)
}
if (DEBUGLEVEL >= 10) {
NDR_PRINT_IN_DEBUG(lsa_LSARQUERYFORESTTRUSTINFORMATION, r);
NDR_PRINT_IN_DEBUG(lsa_lsaRQueryForestTrustInformation, r);
}
r->out.result = _lsa_LSARQUERYFORESTTRUSTINFORMATION(p, r);
ZERO_STRUCT(r->out);
r->out.forest_trust_info = talloc_zero(r, struct lsa_ForestTrustInformation *);
if (r->out.forest_trust_info == NULL) {
talloc_free(r);
return false;
}
r->out.result = _lsa_lsaRQueryForestTrustInformation(p, r);
if (p->rng_fault_state) {
talloc_free(r);
@ -5626,7 +5633,7 @@ static bool api_lsa_LSARQUERYFORESTTRUSTINFORMATION(pipes_struct *p)
}
if (DEBUGLEVEL >= 10) {
NDR_PRINT_OUT_DEBUG(lsa_LSARQUERYFORESTTRUSTINFORMATION, r);
NDR_PRINT_OUT_DEBUG(lsa_lsaRQueryForestTrustInformation, r);
}
push = ndr_push_init_ctx(r);
@ -6331,7 +6338,7 @@ static struct api_struct api_lsarpc_cmds[] =
{"LSA_LSARREGISTERAUDITEVENT", NDR_LSA_LSARREGISTERAUDITEVENT, api_lsa_LSARREGISTERAUDITEVENT},
{"LSA_LSARGENAUDITEVENT", NDR_LSA_LSARGENAUDITEVENT, api_lsa_LSARGENAUDITEVENT},
{"LSA_LSARUNREGISTERAUDITEVENT", NDR_LSA_LSARUNREGISTERAUDITEVENT, api_lsa_LSARUNREGISTERAUDITEVENT},
{"LSA_LSARQUERYFORESTTRUSTINFORMATION", NDR_LSA_LSARQUERYFORESTTRUSTINFORMATION, api_lsa_LSARQUERYFORESTTRUSTINFORMATION},
{"LSA_LSARQUERYFORESTTRUSTINFORMATION", NDR_LSA_LSARQUERYFORESTTRUSTINFORMATION, api_lsa_lsaRQueryForestTrustInformation},
{"LSA_LSARSETFORESTTRUSTINFORMATION", NDR_LSA_LSARSETFORESTTRUSTINFORMATION, api_lsa_LSARSETFORESTTRUSTINFORMATION},
{"LSA_CREDRRENAME", NDR_LSA_CREDRRENAME, api_lsa_CREDRRENAME},
{"LSA_LOOKUPSIDS3", NDR_LSA_LOOKUPSIDS3, api_lsa_LookupSids3},

View File

@ -74,7 +74,7 @@ NTSTATUS _lsa_CREDRGETSESSIONTYPES(pipes_struct *p, struct lsa_CREDRGETSESSIONTY
NTSTATUS _lsa_LSARREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARREGISTERAUDITEVENT *r);
NTSTATUS _lsa_LSARGENAUDITEVENT(pipes_struct *p, struct lsa_LSARGENAUDITEVENT *r);
NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARUNREGISTERAUDITEVENT *r);
NTSTATUS _lsa_LSARQUERYFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r);
NTSTATUS _lsa_lsaRQueryForestTrustInformation(pipes_struct *p, struct lsa_lsaRQueryForestTrustInformation *r);
NTSTATUS _lsa_LSARSETFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARSETFORESTTRUSTINFORMATION *r);
NTSTATUS _lsa_CREDRRENAME(pipes_struct *p, struct lsa_CREDRRENAME *r);
NTSTATUS _lsa_LookupSids3(pipes_struct *p, struct lsa_LookupSids3 *r);

View File

@ -47,7 +47,7 @@ import "security.idl";
/******************/
/* Function: 0x01 */
NTSTATUS lsa_Delete (
[public] NTSTATUS lsa_Delete (
[in] policy_handle *handle
);
@ -69,7 +69,7 @@ import "security.idl";
[size_is(count)] lsa_PrivEntry *privs;
} lsa_PrivArray;
NTSTATUS lsa_EnumPrivs (
[public] NTSTATUS lsa_EnumPrivs (
[in] policy_handle *handle,
[in,out] uint32 *resume_handle,
[in] uint32 max_count,
@ -116,7 +116,7 @@ import "security.idl";
/* notice the screwup with the system_name - thats why MS created
OpenPolicy2 */
NTSTATUS lsa_OpenPolicy (
[public] NTSTATUS lsa_OpenPolicy (
[in,unique] uint16 *system_name,
[in] lsa_ObjectAttribute *attr,
[in] uint32 access_mask,
@ -138,9 +138,29 @@ import "security.idl";
uint32 unknown;
} lsa_AuditLogInfo;
typedef [v1_enum] enum {
LSA_AUDIT_POLICY_NONE=0,
LSA_AUDIT_POLICY_SUCCESS=1,
LSA_AUDIT_POLICY_FAILURE=2,
LSA_AUDIT_POLICY_ALL=(LSA_AUDIT_POLICY_SUCCESS|LSA_AUDIT_POLICY_FAILURE),
LSA_AUDIT_POLICY_CLEAR=4
} lsa_PolicyAuditPolicy;
typedef enum {
LSA_AUDIT_CATEGORY_SYSTEM = 0,
LSA_AUDIT_CATEGORY_LOGON = 1,
LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS = 2,
LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS = 3,
LSA_AUDIT_CATEGORY_PROCCESS_TRACKING = 4,
LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES = 5,
LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT = 6,
LSA_AUDIT_CATEGORY_DIRECTORY_SERVICE_ACCESS = 7, /* only in win2k/2k3 */
LSA_AUDIT_CATEGORY_ACCOUNT_LOGON = 8 /* only in win2k/2k3 */
} lsa_PolicyAuditEventType;
typedef struct {
uint32 auditing_mode;
[size_is(count)] uint32 *settings;
[size_is(count)] lsa_PolicyAuditPolicy *settings;
uint32 count;
} lsa_AuditEventsInfo;
@ -251,7 +271,7 @@ import "security.idl";
/******************/
/* Function: 0x0a */
NTSTATUS lsa_CreateAccount (
[public] NTSTATUS lsa_CreateAccount (
[in] policy_handle *handle,
[in] dom_sid2 *sid,
[in] uint32 access_mask,
@ -272,7 +292,7 @@ import "security.idl";
[size_is(num_sids)] lsa_SidPtr *sids;
} lsa_SidArray;
NTSTATUS lsa_EnumAccounts (
[public] NTSTATUS lsa_EnumAccounts (
[in] policy_handle *handle,
[in,out] uint32 *resume_handle,
[in,range(0,8192)] uint32 num_entries,
@ -283,7 +303,7 @@ import "security.idl";
/*************************************************/
/* Function: 0x0c */
NTSTATUS lsa_CreateTrustedDomain(
[public] NTSTATUS lsa_CreateTrustedDomain(
[in] policy_handle *handle,
[in] lsa_DomainInfo *info,
[in] uint32 access_mask,
@ -305,7 +325,7 @@ import "security.idl";
NTSTATUS lsa_EnumTrustDom (
[in] policy_handle *handle,
[in,out] uint32 *resume_handle,
[in,range(0,1000)] uint32 max_size,
[in] uint32 max_size,
[out] lsa_DomainList *domains
);
@ -343,13 +363,30 @@ import "security.idl";
uint32 max_size;
} lsa_RefDomainList;
NTSTATUS lsa_LookupNames (
/* Level 1: Ask everywhere
* Level 2: Ask domain and trusted domains, no builtin and wkn
* Level 3: Only ask domain
* Level 4: W2k3ad: Only ask AD trusts
* Level 5: Only ask transitive forest trusts
* Level 6: Like 4
*/
typedef enum {
LSA_LOOKUP_NAMES_ALL = 1,
LSA_LOOKUP_NAMES_DOMAINS_ONLY = 2,
LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY = 3,
LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY = 4,
LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY = 5,
LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 = 6
} lsa_LookupNamesLevel;
[public] NTSTATUS lsa_LookupNames (
[in] policy_handle *handle,
[in,range(0,1000)] uint32 num_names,
[in,size_is(num_names)] lsa_String names[],
[out,unique] lsa_RefDomainList *domains,
[in,out] lsa_TransSidArray *sids,
[in] uint16 level,
[in] lsa_LookupNamesLevel level,
[in,out] uint32 *count
);
@ -368,7 +405,7 @@ import "security.idl";
[size_is(count)] lsa_TranslatedName *names;
} lsa_TransNameArray;
NTSTATUS lsa_LookupSids (
[public] NTSTATUS lsa_LookupSids (
[in] policy_handle *handle,
[in] lsa_SidArray *sids,
[out,unique] lsa_RefDomainList *domains,
@ -379,7 +416,7 @@ import "security.idl";
/* Function: 0x10 */
NTSTATUS lsa_CreateSecret(
[public] NTSTATUS lsa_CreateSecret(
[in] policy_handle *handle,
[in] lsa_String name,
[in] uint32 access_mask,
@ -559,7 +596,7 @@ import "security.idl";
NTSTATUS lsa_SetInformationTrustedDomain();
/* Function: 0x1c */
NTSTATUS lsa_OpenSecret(
[public] NTSTATUS lsa_OpenSecret(
[in] policy_handle *handle,
[in] lsa_String name,
[in] uint32 access_mask,
@ -568,7 +605,7 @@ import "security.idl";
/* Function: 0x1d */
NTSTATUS lsa_SetSecret(
[public] NTSTATUS lsa_SetSecret(
[in] policy_handle *sec_handle,
[in,unique] lsa_DATA_BUF *new_val,
[in,unique] lsa_DATA_BUF *old_val
@ -579,7 +616,7 @@ import "security.idl";
} lsa_DATA_BUF_PTR;
/* Function: 0x1e */
NTSTATUS lsa_QuerySecret (
[public] NTSTATUS lsa_QuerySecret (
[in] policy_handle *sec_handle,
[in,out,unique] lsa_DATA_BUF_PTR *new_val,
[in,out,unique] NTTIME_hyper *new_mtime,
@ -685,7 +722,7 @@ import "security.idl";
/**********************/
/* Function: 0x2c */
NTSTATUS lsa_OpenPolicy2 (
[public] NTSTATUS lsa_OpenPolicy2 (
[in,unique] [string,charset(UTF16)] uint16 *system_name,
[in] lsa_ObjectAttribute *attr,
[in] uint32 access_mask,
@ -832,7 +869,7 @@ import "security.idl";
[size_is(count)] lsa_TranslatedName2 *names;
} lsa_TransNameArray2;
NTSTATUS lsa_LookupSids2(
[public] NTSTATUS lsa_LookupSids2(
[in] policy_handle *handle,
[in] lsa_SidArray *sids,
[out,unique] lsa_RefDomainList *domains,
@ -858,13 +895,13 @@ import "security.idl";
[size_is(count)] lsa_TranslatedSid2 *sids;
} lsa_TransSidArray2;
NTSTATUS lsa_LookupNames2 (
[public] NTSTATUS lsa_LookupNames2 (
[in] policy_handle *handle,
[in,range(0,1000)] uint32 num_names,
[in,size_is(num_names)] lsa_String names[],
[out,unique] lsa_RefDomainList *domains,
[in,out] lsa_TransSidArray2 *sids,
[in] uint16 level,
[in] lsa_LookupNamesLevel level,
[in,out] uint32 *count,
[in] uint32 unknown1,
[in] uint32 unknown2
@ -911,13 +948,13 @@ import "security.idl";
[size_is(count)] lsa_TranslatedSid3 *sids;
} lsa_TransSidArray3;
NTSTATUS lsa_LookupNames3 (
[public] NTSTATUS lsa_LookupNames3 (
[in] policy_handle *handle,
[in,range(0,1000)] uint32 num_names,
[in,size_is(num_names)] lsa_String names[],
[out,unique] lsa_RefDomainList *domains,
[in,out] lsa_TransSidArray3 *sids,
[in] uint16 level,
[in] lsa_LookupNamesLevel level,
[in,out] uint32 *count,
[in] uint32 unknown1,
[in] uint32 unknown2
@ -936,7 +973,49 @@ import "security.idl";
NTSTATUS lsa_LSARUNREGISTERAUDITEVENT();
/* Function 0x49 */
NTSTATUS lsa_LSARQUERYFORESTTRUSTINFORMATION();
typedef struct {
[range(0,131072)] uint32 length;
[size_is(length)] uint8 *data;
} lsa_ForestTrustBinaryData;
typedef struct {
dom_sid2 *domain_sid;
lsa_StringLarge dns_domain_name;
lsa_StringLarge netbios_domain_name;
} lsa_ForestTrustDomainInfo;
typedef [switch_type(uint32)] union {
[case(LSA_FOREST_TRUST_TOP_LEVEL_NAME)] lsa_String top_level_name;
[case(LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX)] lsa_StringLarge top_level_name_ex;
[case(LSA_FOREST_TRUST_DOMAIN_INFO)] lsa_ForestTrustDomainInfo domain_info;
[default] lsa_ForestTrustBinaryData data;
} lsa_ForestTrustData;
typedef [v1_enum] enum {
LSA_FOREST_TRUST_TOP_LEVEL_NAME = 0,
LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX = 1,
LSA_FOREST_TRUST_DOMAIN_INFO = 2,
LSA_FOREST_TRUST_RECORD_TYPE_LAST = 3
} lsa_ForestTrustRecordType;
typedef struct {
uint32 flags;
lsa_ForestTrustRecordType level;
hyper unknown;
[switch_is(level)] lsa_ForestTrustData forest_trust_data;
} lsa_ForestTrustRecord;
typedef [public] struct {
[range(0,4000)] uint32 count;
[size_is(count)] lsa_ForestTrustRecord **entries;
} lsa_ForestTrustInformation;
NTSTATUS lsa_lsaRQueryForestTrustInformation(
[in] policy_handle *handle,
[in,ref] lsa_String *trusted_domain_name,
[in] uint16 unknown, /* level ? */
[out,ref] lsa_ForestTrustInformation **forest_trust_info
);
/* Function 0x4a */
NTSTATUS lsa_LSARSETFORESTTRUSTINFORMATION();
@ -947,7 +1026,7 @@ import "security.idl";
/*****************/
/* Function 0x4c */
NTSTATUS lsa_LookupSids3(
[public] NTSTATUS lsa_LookupSids3(
[in] lsa_SidArray *sids,
[out,unique] lsa_RefDomainList *domains,
[in,out] lsa_TransNameArray2 *names,
@ -963,7 +1042,7 @@ import "security.idl";
[in,size_is(num_names)] lsa_String names[],
[out,unique] lsa_RefDomainList *domains,
[in,out] lsa_TransSidArray3 *sids,
[in] uint16 level,
[in] lsa_LookupNamesLevel level,
[in,out] uint32 *count,
[in] uint32 unknown1,
[in] uint32 unknown2

View File

@ -1299,11 +1299,11 @@ static NTSTATUS resolve_hosts(const char *name, int name_type,
Resolve via "ADS" method.
*********************************************************/
NTSTATUS resolve_ads(const char *name,
int name_type,
const char *sitename,
struct ip_service **return_iplist,
int *return_count)
static NTSTATUS resolve_ads(const char *name,
int name_type,
const char *sitename,
struct ip_service **return_iplist,
int *return_count)
{
int i, j;
NTSTATUS status;

View File

@ -41,11 +41,11 @@ static struct db_context *brlock_db;
static void print_lock_struct(unsigned int i, struct lock_struct *pls)
{
DEBUG(10,("[%u]: smbpid = %u, tid = %u, pid = %s, ",
DEBUG(10,("[%u]: smbpid = %u, tid = %u, pid = %u, ",
i,
(unsigned int)pls->context.smbpid,
(unsigned int)pls->context.tid,
procid_str_static(&pls->context.pid) ));
(unsigned int)procid_to_pid(&pls->context.pid) ));
DEBUG(10,("start = %.0f, size = %.0f, fnum = %d, %s %s\n",
(double)pls->start,
@ -263,10 +263,9 @@ void brl_init(bool read_only)
if (brlock_db) {
return;
}
brlock_db = db_open(NULL, lock_path("brlock.tdb"), 0,
TDB_DEFAULT
|TDB_VOLATILE
|(read_only?0x0:TDB_CLEAR_IF_FIRST),
brlock_db = db_open(NULL, lock_path("brlock.tdb"),
lp_open_files_db_hash_size(),
TDB_DEFAULT | TDB_CLEAR_IF_FIRST,
read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644 );
if (!brlock_db) {
DEBUG(0,("Failed to open byte range locking database %s\n",
@ -1495,14 +1494,16 @@ static int traverse_fn(struct db_record *rec, void *state)
}
}
for ( i=0; i<num_locks; i++) {
cb->fn(*key,
locks[i].context.pid,
locks[i].lock_type,
locks[i].lock_flav,
locks[i].start,
locks[i].size,
cb->private_data);
if (cb->fn) {
for ( i=0; i<num_locks; i++) {
cb->fn(*key,
locks[i].context.pid,
locks[i].lock_type,
locks[i].lock_flav,
locks[i].start,
locks[i].size,
cb->private_data);
}
}
SAFE_FREE(locks);

View File

@ -22,9 +22,11 @@
#ifdef HAVE_GPFS
#include "gpfs_gpl.h"
#include "vfs_gpfs.h"
static void *libgpfs_handle = NULL;
static bool gpfs_share_modes;
static bool gpfs_leases;
static int (*gpfs_set_share_fn)(int fd, unsigned int allow, unsigned int deny);
static int (*gpfs_set_lease_fn)(int fd, unsigned int leaseType);
@ -42,7 +44,7 @@ bool set_gpfs_sharemode(files_struct *fsp, uint32 access_mask,
if (!gpfs_share_modes) {
return True;
}
if (gpfs_set_share_fn == NULL) {
return False;
}
@ -88,7 +90,7 @@ int set_gpfs_lease(int fd, int leasetype)
{
int gpfs_type = GPFS_LEASE_NONE;
if (!gpfs_share_modes) {
if (!gpfs_leases) {
return True;
}
@ -103,6 +105,13 @@ int set_gpfs_lease(int fd, int leasetype)
if (leasetype == F_WRLCK) {
gpfs_type = GPFS_LEASE_WRITE;
}
/* we unconditionally set CAP_LEASE, rather than looking for
-1/EACCES as there is a bug in some versions of
libgpfs_gpl.so which results in a leaked fd on /dev/ss0
each time we try this with the wrong capabilities set
*/
linux_set_lease_capability();
return gpfs_set_lease_fn(fd, gpfs_type);
}
@ -172,11 +181,8 @@ void init_gpfs(void)
goto failed;
}
if (lp_parm_bool(-1, "gpfs", "sharemodes", True)) {
gpfs_share_modes = True;
} else {
gpfs_share_modes = False;
}
gpfs_share_modes = lp_parm_bool(-1, "gpfs", "sharemodes", True);
gpfs_leases = lp_parm_bool(-1, "gpfs", "leases", True);
return;

View File

@ -20,6 +20,9 @@
#include "includes.h"
#include "nfs4_acls.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_ACLS
#define SMBACL4_PARAM_TYPE_NAME "nfs4"
#define SMB_ACE4_INT_MAGIC 0x76F8A967
@ -352,6 +355,7 @@ typedef struct _smbacl4_vfs_params {
enum smbacl4_mode_enum mode;
bool do_chown;
enum smbacl4_acedup_enum acedup;
struct db_context *sid_mapping_table;
} smbacl4_vfs_params;
/*
@ -451,8 +455,65 @@ static SMB_ACE4PROP_T *smbacl4_find_equal_special(
return NULL;
}
static int smbacl4_fill_ace4(
static bool nfs4_map_sid(smbacl4_vfs_params *params, const DOM_SID *src,
DOM_SID *dst)
{
static struct db_context *mapping_db = NULL;
TDB_DATA data;
if (mapping_db == NULL) {
const char *dbname = lp_parm_const_string(
-1, SMBACL4_PARAM_TYPE_NAME, "sidmap", NULL);
if (dbname == NULL) {
DEBUG(10, ("%s:sidmap not defined\n",
SMBACL4_PARAM_TYPE_NAME));
return False;
}
become_root();
mapping_db = db_open(NULL, dbname, 0, TDB_DEFAULT,
O_RDONLY, 0600);
unbecome_root();
if (mapping_db == NULL) {
DEBUG(1, ("could not open sidmap: %s\n",
strerror(errno)));
return False;
}
}
if (mapping_db->fetch(mapping_db, NULL,
string_term_tdb_data(sid_string_tos(src)),
&data) == -1) {
DEBUG(10, ("could not find mapping for SID %s\n",
sid_string_dbg(src)));
return False;
}
if ((data.dptr == NULL) || (data.dsize <= 0)
|| (data.dptr[data.dsize-1] != '\0')) {
DEBUG(5, ("invalid mapping for SID %s\n",
sid_string_dbg(src)));
TALLOC_FREE(data.dptr);
return False;
}
if (!string_to_sid(dst, (char *)data.dptr)) {
DEBUG(1, ("invalid mapping %s for SID %s\n",
(char *)data.dptr, sid_string_dbg(src)));
TALLOC_FREE(data.dptr);
return False;
}
TALLOC_FREE(data.dptr);
return True;
}
static bool smbacl4_fill_ace4(
TALLOC_CTX *mem_ctx,
const char *filename,
smbacl4_vfs_params *params,
uid_t ownerUID,
gid_t ownerGID,
@ -460,11 +521,6 @@ static int smbacl4_fill_ace4(
SMB_ACE4PROP_T *ace_v4 /* output */
)
{
const char *dom, *name;
enum lsa_SidType type;
uid_t uid;
gid_t gid;
DEBUG(10, ("got ace for %s\n", sid_string_dbg(&ace_nt->trustee)));
memset(ace_v4, 0, sizeof(SMB_ACE4PROP_T));
@ -485,18 +541,46 @@ static int smbacl4_fill_ace4(
ace_v4->who.special_id = SMB_ACE4_WHO_EVERYONE;
ace_v4->flags |= SMB_ACE4_ID_SPECIAL;
} else {
if (!lookup_sid(mem_ctx, &ace_nt->trustee, &dom, &name, &type)) {
DEBUG(8, ("Could not find %s' type\n",
sid_string_dbg(&ace_nt->trustee)));
errno = EINVAL;
return -1;
const char *dom, *name;
enum lsa_SidType type;
uid_t uid;
gid_t gid;
DOM_SID sid;
sid_copy(&sid, &ace_nt->trustee);
if (!lookup_sid(mem_ctx, &sid, &dom, &name, &type)) {
DOM_SID mapped;
if (!nfs4_map_sid(params, &sid, &mapped)) {
DEBUG(1, ("nfs4_acls.c: file [%s]: SID %s "
"unknown\n", filename, sid_string_dbg(&sid)));
errno = EINVAL;
return False;
}
DEBUG(2, ("nfs4_acls.c: file [%s]: mapped SID %s "
"to %s\n", filename, sid_string_dbg(&sid), sid_string_dbg(&mapped)));
if (!lookup_sid(mem_ctx, &mapped, &dom,
&name, &type)) {
DEBUG(1, ("nfs4_acls.c: file [%s]: SID %s "
"mapped from %s is unknown\n",
filename, sid_string_dbg(&mapped), sid_string_dbg(&sid)));
errno = EINVAL;
return False;
}
sid_copy(&sid, &mapped);
}
if (type == SID_NAME_USER) {
if (!sid_to_uid(&ace_nt->trustee, &uid)) {
DEBUG(2, ("Could not convert %s to uid\n",
sid_string_dbg(&ace_nt->trustee)));
return -1;
if (!sid_to_uid(&sid, &uid)) {
DEBUG(1, ("nfs4_acls.c: file [%s]: could not "
"convert %s to uid\n", filename,
sid_string_dbg(&sid)));
return False;
}
if (params->mode==e_special && uid==ownerUID) {
@ -506,11 +590,13 @@ static int smbacl4_fill_ace4(
ace_v4->who.uid = uid;
}
} else { /* else group? - TODO check it... */
if (!sid_to_gid(&ace_nt->trustee, &gid)) {
DEBUG(2, ("Could not convert %s to gid\n",
sid_string_dbg(&ace_nt->trustee)));
return -1;
if (!sid_to_gid(&sid, &gid)) {
DEBUG(1, ("nfs4_acls.c: file [%s]: could not "
"convert %s to gid\n", filename,
sid_string_dbg(&sid)));
return False;
}
ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP;
if (params->mode==e_special && gid==ownerGID) {
@ -522,7 +608,7 @@ static int smbacl4_fill_ace4(
}
}
return 0; /* OK */
return True; /* OK */
}
static int smbacl4_MergeIgnoreReject(
@ -560,6 +646,7 @@ static int smbacl4_MergeIgnoreReject(
}
static SMB4ACL_T *smbacl4_win2nfs4(
const char *filename,
SEC_ACL *dacl,
smbacl4_vfs_params *pparams,
uid_t ownerUID,
@ -580,9 +667,14 @@ static SMB4ACL_T *smbacl4_win2nfs4(
SMB_ACE4PROP_T ace_v4;
bool addNewACE = True;
if (smbacl4_fill_ace4(mem_ctx, pparams, ownerUID, ownerGID,
dacl->aces + i, &ace_v4))
return NULL;
if (!smbacl4_fill_ace4(mem_ctx, filename, pparams,
ownerUID, ownerGID,
dacl->aces + i, &ace_v4)) {
DEBUG(3, ("Could not fill ace for file %s, SID %s\n",
filename,
sid_string_dbg(&((dacl->aces+i)->trustee))));
continue;
}
if (pparams->acedup!=e_dontcare) {
if (smbacl4_MergeIgnoreReject(pparams->acedup, acl,
@ -607,6 +699,7 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
bool result;
SMB_STRUCT_STAT sbuf;
bool need_chown = False;
uid_t newUID = (uid_t)-1;
gid_t newGID = (gid_t)-1;
@ -635,25 +728,33 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
return status;
}
if (((newUID != (uid_t)-1) && (sbuf.st_uid != newUID)) ||
((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) {
if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n",
fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, strerror(errno) ));
if (errno == EPERM) {
return NT_STATUS_INVALID_OWNER;
((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) {
need_chown = True;
}
if (need_chown) {
if ((newUID == (uid_t)-1 || newUID == current_user.ut.uid)) {
if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n",
fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID,
strerror(errno)));
return map_nt_error_from_unix(errno);
}
return map_nt_error_from_unix(errno);
DEBUG(10,("chown %s, %u, %u succeeded.\n",
fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
if (smbacl4_GetFileOwner(fsp->conn, fsp->fsp_name, &sbuf))
return map_nt_error_from_unix(errno);
need_chown = False;
} else { /* chown is needed, but _after_ changing acl */
sbuf.st_uid = newUID; /* OWNER@ in case of e_special */
sbuf.st_gid = newGID; /* GROUP@ in case of e_special */
}
DEBUG(10,("chown %s, %u, %u succeeded.\n",
fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
if (smbacl4_fGetFileOwner(fsp, &sbuf))
return map_nt_error_from_unix(errno);
}
}
if ((security_info_sent & DACL_SECURITY_INFORMATION)!=0 && psd->dacl!=NULL)
{
acl = smbacl4_win2nfs4(psd->dacl, &params, sbuf.st_uid, sbuf.st_gid);
acl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, &params, sbuf.st_uid, sbuf.st_gid);
if (!acl)
return map_nt_error_from_unix(errno);
@ -668,6 +769,20 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
} else
DEBUG(10, ("no dacl found; security_info_sent = 0x%x\n", security_info_sent));
/* Any chown pending? */
if (need_chown) {
DEBUG(3,("chown#2 %s. uid = %u, gid = %u.\n",
fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
if (try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) {
DEBUG(2,("chown#2 %s, %u, %u failed. Error = %s.\n",
fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID,
strerror(errno)));
return map_nt_error_from_unix(errno);
}
DEBUG(10,("chown#2 %s, %u, %u succeeded.\n",
fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
}
DEBUG(10, ("smb_set_nt_acl_nfs4 succeeded\n"));
return NT_STATUS_OK;
}

View File

@ -1225,6 +1225,38 @@ static int vfswrap_aio_suspend(struct vfs_handle_struct *handle, struct files_st
return sys_aio_suspend(aiocb, n, timeout);
}
static int vfswrap_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
{
return False;
}
static int vfswrap_is_offline(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf, bool *offline)
{
if (ISDOT(path) || ISDOTDOT(path)) {
return 1;
}
if (!lp_dmapi_support(SNUM(conn)) || !dmapi_have_session()) {
return -1;
}
*offline = (dmapi_file_flags(path) & FILE_ATTRIBUTE_OFFLINE) != 0;
return 0;
}
static int vfswrap_set_offline(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path)
{
/* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
return -1;
}
static bool vfswrap_is_remotestorage(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path)
{
/* We don't know how to detect that volume is remote storage. VFS modules should redefine it. */
return False;
}
static vfs_op_tuple vfs_default_ops[] = {
/* Disk operations */
@ -1442,6 +1474,16 @@ static vfs_op_tuple vfs_default_ops[] = {
{SMB_VFS_OP(vfswrap_aio_suspend),SMB_VFS_OP_AIO_SUSPEND,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(vfswrap_aio_force), SMB_VFS_OP_AIO_FORCE,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(vfswrap_is_offline),SMB_VFS_OP_IS_OFFLINE,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(vfswrap_set_offline),SMB_VFS_OP_SET_OFFLINE,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(vfswrap_is_remotestorage),SMB_VFS_OP_IS_REMOTESTORAGE,
SMB_VFS_LAYER_OPAQUE},
/* Finish VFS operations definition */
{SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP,

View File

@ -30,7 +30,7 @@
#include <gpfs_gpl.h>
#include "nfs4_acls.h"
#include "vfs_gpfs.h"
static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
uint32 share_mode)
@ -153,7 +153,7 @@ static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl)
DEBUG(10, ("gpfs_get_nfs4_acl invoked for %s\n", fname));
/* First get the real acl length */
gacl = gpfs_getacl_alloc(fname, GPFS_ACL_TYPE_NFS4);
gacl = gpfs_getacl_alloc(fname, 0);
if (gacl == NULL) {
DEBUG(9, ("gpfs_getacl failed for %s with %s\n",
fname, strerror(errno)));
@ -208,10 +208,10 @@ static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl)
if (i > 0 && gace->aceType == SMB_ACE4_ACCESS_DENIED_ACE_TYPE) {
struct gpfs_ace_v4 *prev = &gacl->ace_v4[i-1];
if (prev->aceType == SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE &&
prev->aceFlags == gace->aceFlags &&
prev->aceIFlags == gace->aceIFlags &&
(gace->aceMask & prev->aceMask) == 0 &&
gace->aceWho == prev->aceWho) {
prev->aceFlags == gace->aceFlags &&
prev->aceIFlags == gace->aceIFlags &&
(gace->aceMask & prev->aceMask) == 0 &&
gace->aceWho == prev->aceWho) {
/* its redundent - skip it */
continue;
}
@ -256,7 +256,7 @@ static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle,
int result;
*ppdesc = NULL;
result = gpfs_get_nfs4_acl(fsp->fsp_name, &pacl);
result = gpfs_get_nfs4_acl(name, &pacl);
if (result == 0)
return smb_get_nt_acl_nfs4(handle->conn, name, security_info, ppdesc, pacl);
@ -301,8 +301,31 @@ static bool gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
gace->aceType = aceprop->aceType;
gace->aceFlags = aceprop->aceFlags;
gace->aceMask = aceprop->aceMask;
/*
* GPFS can't distinguish between WRITE and APPEND on
* files, so one being set without the other is an
* error. Sorry for the many ()'s :-)
*/
if (!fsp->is_directory
&&
((((gace->aceMask & ACE4_MASK_WRITE) == 0)
&& ((gace->aceMask & ACE4_MASK_APPEND) != 0))
||
(((gace->aceMask & ACE4_MASK_WRITE) != 0)
&& ((gace->aceMask & ACE4_MASK_APPEND) == 0)))
&&
lp_parm_bool(fsp->conn->params->service, "gpfs",
"merge_writeappend", True)) {
DEBUG(2, ("vfs_gpfs.c: file [%s]: ACE contains "
"WRITE^APPEND, setting WRITE|APPEND\n",
fsp->fsp_name));
gace->aceMask |= ACE4_MASK_WRITE|ACE4_MASK_APPEND;
}
gace->aceIFlags = (aceprop->flags&SMB_ACE4_ID_SPECIAL) ? ACE4_IFLAG_SPECIAL_ID : 0;
if (aceprop->flags&SMB_ACE4_ID_SPECIAL)
{
switch(aceprop->who.special_id)
@ -347,7 +370,7 @@ static NTSTATUS gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_i
struct gpfs_acl *acl;
NTSTATUS result = NT_STATUS_ACCESS_DENIED;
acl = gpfs_getacl_alloc(fsp->fsp_name, GPFS_ACL_TYPE_ACCESS);
acl = gpfs_getacl_alloc(fsp->fsp_name, 0);
if (acl == NULL)
return result;
@ -628,75 +651,225 @@ int gpfsacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
return -1;
}
/*
* Assumed: mode bits are shiftable and standard
* Output: the new aceMask field for an smb nfs4 ace
*/
static uint32 gpfsacl_mask_filter(uint32 aceType, uint32 aceMask, uint32 rwx)
{
const uint32 posix_nfs4map[3] = {
SMB_ACE4_EXECUTE, /* execute */
SMB_ACE4_WRITE_DATA | SMB_ACE4_APPEND_DATA, /* write; GPFS specific */
SMB_ACE4_READ_DATA /* read */
};
int i;
uint32_t posix_mask = 0x01;
uint32_t posix_bit;
uint32_t nfs4_bits;
for(i=0; i<3; i++) {
nfs4_bits = posix_nfs4map[i];
posix_bit = rwx & posix_mask;
if (aceType==SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE) {
if (posix_bit)
aceMask |= nfs4_bits;
else
aceMask &= ~nfs4_bits;
} else {
/* add deny bits when suitable */
if (!posix_bit)
aceMask |= nfs4_bits;
else
aceMask &= ~nfs4_bits;
} /* other ace types are unexpected */
posix_mask <<= 1;
}
return aceMask;
}
static int gpfsacl_emu_chmod(const char *path, mode_t mode)
{
SMB4ACL_T *pacl = NULL;
int result;
bool haveAllowEntry[SMB_ACE4_WHO_EVERYONE + 1] = {False, False, False, False};
int i;
files_struct fake_fsp; /* TODO: rationalize parametrization */
SMB4ACE_T *smbace;
DEBUG(10, ("gpfsacl_emu_chmod invoked for %s mode %o\n", path, mode));
result = gpfs_get_nfs4_acl(path, &pacl);
if (result)
return result;
if (mode & ~(S_IRWXU | S_IRWXG | S_IRWXO)) {
DEBUG(2, ("WARNING: cutting extra mode bits %o on %s\n", mode, path));
}
for (smbace=smb_first_ace4(pacl); smbace!=NULL; smbace = smb_next_ace4(smbace)) {
SMB_ACE4PROP_T *ace = smb_get_ace4(smbace);
uint32_t specid = ace->who.special_id;
if (ace->flags&SMB_ACE4_ID_SPECIAL &&
ace->aceType<=SMB_ACE4_ACCESS_DENIED_ACE_TYPE &&
specid <= SMB_ACE4_WHO_EVERYONE) {
uint32_t newMask;
if (ace->aceType==SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE)
haveAllowEntry[specid] = True;
/* mode >> 6 for @owner, mode >> 3 for @group,
* mode >> 0 for @everyone */
newMask = gpfsacl_mask_filter(ace->aceType, ace->aceMask,
mode >> ((SMB_ACE4_WHO_EVERYONE - specid) * 3));
if (ace->aceMask!=newMask) {
DEBUG(10, ("ace changed for %s (%o -> %o) id=%d\n",
path, ace->aceMask, newMask, specid));
}
ace->aceMask = newMask;
}
}
/* make sure we have at least ALLOW entries
* for all the 3 special ids (@EVERYONE, @OWNER, @GROUP)
* - if necessary
*/
for(i = SMB_ACE4_WHO_OWNER; i<=SMB_ACE4_WHO_EVERYONE; i++) {
SMB_ACE4PROP_T ace;
if (haveAllowEntry[i]==True)
continue;
memset(&ace, 0, sizeof(SMB_ACE4PROP_T));
ace.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE;
ace.flags |= SMB_ACE4_ID_SPECIAL;
ace.who.special_id = i;
if (i==SMB_ACE4_WHO_GROUP) /* not sure it's necessary... */
ace.aceFlags |= SMB_ACE4_IDENTIFIER_GROUP;
ace.aceMask = gpfsacl_mask_filter(ace.aceType, ace.aceMask,
mode >> ((SMB_ACE4_WHO_EVERYONE - i) * 3));
/* don't add unnecessary aces */
if (!ace.aceMask)
continue;
/* we add it to the END - as windows expects allow aces */
smb_add_ace4(pacl, &ace);
DEBUG(10, ("Added ALLOW ace for %s, mode=%o, id=%d, aceMask=%x\n",
path, mode, i, ace.aceMask));
}
/* don't add complementary DENY ACEs here */
memset(&fake_fsp, 0, sizeof(struct files_struct));
fake_fsp.fsp_name = (char *)path; /* no file_new is needed here */
/* put the acl */
if (gpfsacl_process_smbacl(&fake_fsp, pacl) == False)
return -1;
return 0; /* ok for [f]chmod */
}
static int vfs_gpfs_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
{
SMB_STRUCT_STAT st;
int rc;
if (SMB_VFS_NEXT_STAT(handle, path, &st) != 0) {
return -1;
return -1;
}
/* avoid chmod() if possible, to preserve acls */
if ((st.st_mode & ~S_IFMT) == mode) {
return 0;
return 0;
}
return SMB_VFS_NEXT_CHMOD(handle, path, mode);
rc = gpfsacl_emu_chmod(path, mode);
if (rc == 1)
return SMB_VFS_NEXT_CHMOD(handle, path, mode);
return rc;
}
static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
{
SMB_STRUCT_STAT st;
int rc;
if (SMB_VFS_NEXT_FSTAT(handle, fsp, &st) != 0) {
return -1;
return -1;
}
/* avoid chmod() if possible, to preserve acls */
if ((st.st_mode & ~S_IFMT) == mode) {
return 0;
return 0;
}
return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
rc = gpfsacl_emu_chmod(fsp->fsp_name, mode);
if (rc == 1)
return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
return rc;
}
/* VFS operations structure */
static vfs_op_tuple gpfs_op_tuples[] = {
{ SMB_VFS_OP(vfs_gpfs_kernel_flock), SMB_VFS_OP_KERNEL_FLOCK,
SMB_VFS_LAYER_OPAQUE },
{ SMB_VFS_OP(vfs_gpfs_setlease), SMB_VFS_OP_LINUX_SETLEASE,
SMB_VFS_LAYER_OPAQUE },
{ SMB_VFS_OP(gpfsacl_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_get_nt_acl), SMB_VFS_OP_GET_NT_ACL,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_fset_nt_acl), SMB_VFS_OP_FSET_NT_ACL,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_set_nt_acl), SMB_VFS_OP_SET_NT_ACL,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_sys_acl_get_fd), SMB_VFS_OP_SYS_ACL_GET_FD,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_sys_acl_set_file), SMB_VFS_OP_SYS_ACL_SET_FILE,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_sys_acl_set_fd), SMB_VFS_OP_SYS_ACL_SET_FD,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(vfs_gpfs_kernel_flock),
SMB_VFS_OP_KERNEL_FLOCK,
SMB_VFS_LAYER_OPAQUE },
{ SMB_VFS_OP(vfs_gpfs_setlease),
SMB_VFS_OP_LINUX_SETLEASE,
SMB_VFS_LAYER_OPAQUE },
{ SMB_VFS_OP(gpfsacl_fget_nt_acl),
SMB_VFS_OP_FGET_NT_ACL,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_get_nt_acl),
SMB_VFS_OP_GET_NT_ACL,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_fset_nt_acl),
SMB_VFS_OP_FSET_NT_ACL,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_set_nt_acl),
SMB_VFS_OP_SET_NT_ACL,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_sys_acl_get_file),
SMB_VFS_OP_SYS_ACL_GET_FILE,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_sys_acl_get_fd),
SMB_VFS_OP_SYS_ACL_GET_FD,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_sys_acl_set_file),
SMB_VFS_OP_SYS_ACL_SET_FILE,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_sys_acl_set_fd),
SMB_VFS_OP_SYS_ACL_SET_FD,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(gpfsacl_sys_acl_delete_def_file),
SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(vfs_gpfs_chmod), SMB_VFS_OP_CHMOD,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(vfs_gpfs_fchmod), SMB_VFS_OP_FCHMOD,
SMB_VFS_LAYER_TRANSPARENT },
SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(vfs_gpfs_chmod),
SMB_VFS_OP_CHMOD,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(vfs_gpfs_fchmod),
SMB_VFS_OP_FCHMOD,
SMB_VFS_LAYER_TRANSPARENT },
{ SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP }

View File

@ -0,0 +1,32 @@
/*
Unix SMB/CIFS implementation.
Wrap gpfs calls in vfs functions.
Copyright (C) Christian Ambach <cambach1@de.ibm.com> 2006
Major code contributions by Chetan Shringarpure <chetan.sh@in.ibm.com>
and Gomati Mohanan <gomati.mohanan@in.ibm.com>
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
bool set_gpfs_sharemode(files_struct *fsp, uint32 access_mask,
uint32 share_access);
int set_gpfs_lease(int fd, int leasetype);
int smbd_gpfs_getacl(char *pathname, int flags, void *acl);
int smbd_gpfs_putacl(char *pathname, int flags, void *acl);
void init_gpfs(void);

View File

@ -47,11 +47,16 @@
#define lock_type struct flock64
#endif
#ifdef HAVE_GPFS
#include "gpfs_gpl.h"
#endif
#define MODULE "prealloc"
static int module_debug;
static int preallocate_space(int fd, SMB_OFF_T size)
{
#ifndef HAVE_GPFS
lock_type fl = {0};
int err;
@ -78,6 +83,9 @@ static int preallocate_space(int fd, SMB_OFF_T size)
err = -1;
errno = ENOSYS;
#endif
#else /* GPFS uses completely different interface */
err = gpfs_prealloc(fd, (gpfs_off64_t)0, (gpfs_off64_t)size);
#endif
if (err) {
DEBUG(module_debug,

View File

@ -0,0 +1,637 @@
/*
* implementation of an Shadow Copy module - version 2
*
* Copyright (C) Andrew Tridgell 2007
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
/*
This is a 2nd implemetation of a shadow copy module for exposing
snapshots to windows clients as shadow copies. This version has the
following features:
1) you don't need to populate your shares with symlinks to the
snapshots. This can be very important when you have thousands of
shares, or use [homes]
2) the inode number of the files is altered so it is different
from the original. This allows the 'restore' button to work
without a sharing violation
Module options:
shadow:snapdir = <directory where snapshots are kept>
This is the directory containing the @GMT-* snapshot directories. If it is an absolute
path it is used as-is. If it is a relative path, then it is taken relative to the mount
point of the filesystem that the root of this share is on
shadow:basedir = <base directory that snapshots are from>
This is an optional parameter that specifies the directory that
the snapshots are relative to. It defaults to the filesystem
mount point
shadow:fixinodes = yes/no
If you enable shadow:fixinodes then this module will modify the
apparent inode number of files in the snapshot directories using
a hash of the files path. This is needed for snapshot systems
where the snapshots have the same device:inode number as the
original files (such as happens with GPFS snapshots). If you
don't set this option then the 'restore' button in the shadow
copy UI will fail with a sharing violation.
Note that the directory names in the snapshot directory must take the form
@GMT-YYYY.MM.DD-HH.MM.SS
The following command would generate a correctly formatted directory name:
date -u +@GMT-%Y.%m.%d-%H.%M.%S
*/
static int vfs_shadow_copy2_debug_level = DBGC_VFS;
#undef DBGC_CLASS
#define DBGC_CLASS vfs_shadow_copy2_debug_level
#define GMT_NAME_LEN 24 /* length of a @GMT- name */
/*
make very sure it is one of our special names
*/
static inline bool shadow_copy2_match_name(const char *name)
{
unsigned year, month, day, hr, min, sec;
if (name[0] != '@') return False;
if (strncmp(name, "@GMT-", 5) != 0) return False;
if (sscanf(name, "@GMT-%04u.%02u.%02u-%02u.%02u.%02u", &year, &month,
&day, &hr, &min, &sec) != 6) {
return False;
}
if (name[24] != 0 && name[24] != '/') {
return False;
}
return True;
}
/*
convert a name to the shadow directory
*/
#define _SHADOW2_NEXT(op, args, rtype, eret, extra) do { \
const char *name = fname; \
if (shadow_copy2_match_name(fname)) { \
char *name2; \
rtype ret; \
name2 = convert_shadow2_name(handle, fname); \
if (name2 == NULL) { \
errno = EINVAL; \
return eret; \
} \
name = name2; \
ret = SMB_VFS_NEXT_ ## op args; \
talloc_free(name2); \
if (ret != eret) extra; \
return ret; \
} else { \
return SMB_VFS_NEXT_ ## op args; \
} \
} while (0)
/*
convert a name to the shadow directory: NTSTATUS-specific handling
*/
#define _SHADOW2_NTSTATUS_NEXT(op, args, eret, extra) do { \
const char *name = fname; \
if (shadow_copy2_match_name(fname)) { \
char *name2; \
NTSTATUS ret; \
name2 = convert_shadow2_name(handle, fname); \
if (name2 == NULL) { \
errno = EINVAL; \
return eret; \
} \
name = name2; \
ret = SMB_VFS_NEXT_ ## op args; \
talloc_free(name2); \
if (!NT_STATUS_EQUAL(ret, eret)) extra; \
return ret; \
} else { \
return SMB_VFS_NEXT_ ## op args; \
} \
} while (0)
#define SHADOW2_NTSTATUS_NEXT(op, args, eret) _SHADOW2_NTSTATUS_NEXT(op, args, eret, )
#define SHADOW2_NEXT(op, args, rtype, eret) _SHADOW2_NEXT(op, args, rtype, eret, )
#define SHADOW2_NEXT2(op, args) do { \
if (shadow_copy2_match_name(oldname) || shadow_copy2_match_name(newname)) { \
errno = EROFS; \
return -1; \
} else { \
return SMB_VFS_NEXT_ ## op args; \
} \
} while (0)
/*
find the mount point of a filesystem
*/
static char *find_mount_point(TALLOC_CTX *mem_ctx, vfs_handle_struct *handle)
{
char *path = talloc_strdup(mem_ctx, handle->conn->connectpath);
dev_t dev;
struct stat st;
char *p;
if (stat(path, &st) != 0) {
talloc_free(path);
return NULL;
}
dev = st.st_dev;
while ((p = strrchr(path, '/')) && p > path) {
*p = 0;
if (stat(path, &st) != 0) {
talloc_free(path);
return NULL;
}
if (st.st_dev != dev) {
*p = '/';
break;
}
}
return path;
}
/*
work out the location of the snapshot for this share
*/
static const char *shadow_copy2_find_snapdir(TALLOC_CTX *mem_ctx, vfs_handle_struct *handle)
{
const char *snapdir;
char *mount_point;
const char *ret;
snapdir = lp_parm_const_string(SNUM(handle->conn), "shadow", "snapdir", NULL);
if (snapdir == NULL) {
return NULL;
}
/* if its an absolute path, we're done */
if (*snapdir == '/') {
return snapdir;
}
/* other its relative to the filesystem mount point */
mount_point = find_mount_point(mem_ctx, handle);
if (mount_point == NULL) {
return NULL;
}
ret = talloc_asprintf(mem_ctx, "%s/%s", mount_point, snapdir);
talloc_free(mount_point);
return ret;
}
/*
work out the location of the base directory for snapshots of this share
*/
static const char *shadow_copy2_find_basedir(TALLOC_CTX *mem_ctx, vfs_handle_struct *handle)
{
const char *basedir = lp_parm_const_string(SNUM(handle->conn), "shadow", "basedir", NULL);
/* other its the filesystem mount point */
if (basedir == NULL) {
basedir = find_mount_point(mem_ctx, handle);
}
return basedir;
}
/*
convert a filename from a share relative path, to a path in the
snapshot directory
*/
static char *convert_shadow2_name(vfs_handle_struct *handle, const char *fname)
{
TALLOC_CTX *tmp_ctx = talloc_new(handle->data);
const char *snapdir, *relpath, *baseoffset, *basedir;
size_t baselen;
char *ret;
snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle);
if (snapdir == NULL) {
DEBUG(2,("no snapdir found for share at %s\n", handle->conn->connectpath));
talloc_free(tmp_ctx);
return NULL;
}
basedir = shadow_copy2_find_basedir(tmp_ctx, handle);
if (basedir == NULL) {
DEBUG(2,("no basedir found for share at %s\n", handle->conn->connectpath));
talloc_free(tmp_ctx);
return NULL;
}
relpath = fname + GMT_NAME_LEN;
baselen = strlen(basedir);
baseoffset = handle->conn->connectpath + baselen;
/* some sanity checks */
if (strncmp(basedir, handle->conn->connectpath, baselen) != 0 ||
(handle->conn->connectpath[baselen] != 0 && handle->conn->connectpath[baselen] != '/')) {
DEBUG(0,("convert_shadow2_name: basedir %s is not a parent of %s\n",
basedir, handle->conn->connectpath));
talloc_free(tmp_ctx);
return NULL;
}
if (*relpath == '/') relpath++;
if (*baseoffset == '/') baseoffset++;
ret = talloc_asprintf(handle->data, "%s/%.*s/%s/%s",
snapdir,
GMT_NAME_LEN, fname,
baseoffset,
relpath);
DEBUG(6,("convert_shadow2_name: '%s' -> '%s'\n", fname, ret));
talloc_free(tmp_ctx);
return ret;
}
/*
simple string hash
*/
static uint32 string_hash(const char *s)
{
uint32 n = 0;
while (*s) {
n = ((n << 5) + n) ^ (uint32)(*s++);
}
return n;
}
/*
modify a sbuf return to ensure that inodes in the shadow directory
are different from those in the main directory
*/
static void convert_sbuf(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf)
{
if (lp_parm_bool(SNUM(handle->conn), "shadow", "fixinodes", False)) {
/* some snapshot systems, like GPFS, return the name
device:inode for the snapshot files as the current
files. That breaks the 'restore' button in the shadow copy
GUI, as the client gets a sharing violation.
This is a crude way of allowing both files to be
open at once. It has a slight chance of inode
number collision, but I can't see a better approach
without significant VFS changes
*/
uint32_t shash = string_hash(fname) & 0xFF000000;
if (shash == 0) {
shash = 1;
}
sbuf->st_ino ^= shash;
}
}
static int shadow_copy2_rename(vfs_handle_struct *handle,
const char *oldname, const char *newname)
{
SHADOW2_NEXT2(RENAME, (handle, oldname, newname));
}
static int shadow_copy2_symlink(vfs_handle_struct *handle,
const char *oldname, const char *newname)
{
SHADOW2_NEXT2(SYMLINK, (handle, oldname, newname));
}
static int shadow_copy2_link(vfs_handle_struct *handle,
const char *oldname, const char *newname)
{
SHADOW2_NEXT2(LINK, (handle, oldname, newname));
}
static int shadow_copy2_open(vfs_handle_struct *handle,
const char *fname, files_struct *fsp, int flags, mode_t mode)
{
SHADOW2_NEXT(OPEN, (handle, name, fsp, flags, mode), int, -1);
}
static SMB_STRUCT_DIR *shadow_copy2_opendir(vfs_handle_struct *handle,
const char *fname, const char *mask, uint32 attr)
{
SHADOW2_NEXT(OPENDIR, (handle, name, mask, attr), void*, NULL);
}
static int shadow_copy2_stat(vfs_handle_struct *handle,
const char *fname, SMB_STRUCT_STAT *sbuf)
{
_SHADOW2_NEXT(STAT, (handle, name, sbuf), int, -1, convert_sbuf(handle, fname, sbuf));
}
static int shadow_copy2_lstat(vfs_handle_struct *handle,
const char *fname, SMB_STRUCT_STAT *sbuf)
{
_SHADOW2_NEXT(LSTAT, (handle, name, sbuf), int, -1, convert_sbuf(handle, fname, sbuf));
}
static int shadow_copy2_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
{
int ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
if (ret == 0 && shadow_copy2_match_name(fsp->fsp_name)) {
convert_sbuf(handle, fsp->fsp_name, sbuf);
}
return ret;
}
static int shadow_copy2_unlink(vfs_handle_struct *handle, const char *fname)
{
SHADOW2_NEXT(UNLINK, (handle, name), int, -1);
}
static int shadow_copy2_chmod(vfs_handle_struct *handle,
const char *fname, mode_t mode)
{
SHADOW2_NEXT(CHMOD, (handle, name, mode), int, -1);
}
static int shadow_copy2_chown(vfs_handle_struct *handle,
const char *fname, uid_t uid, gid_t gid)
{
SHADOW2_NEXT(CHOWN, (handle, name, uid, gid), int, -1);
}
static int shadow_copy2_chdir(vfs_handle_struct *handle,
const char *fname)
{
SHADOW2_NEXT(CHDIR, (handle, name), int, -1);
}
static int shadow_copy2_ntimes(vfs_handle_struct *handle,
const char *fname, const struct timespec ts[2])
{
SHADOW2_NEXT(NTIMES, (handle, name, ts), int, -1);
}
static int shadow_copy2_readlink(vfs_handle_struct *handle,
const char *fname, char *buf, size_t bufsiz)
{
SHADOW2_NEXT(READLINK, (handle, name, buf, bufsiz), int, -1);
}
static int shadow_copy2_mknod(vfs_handle_struct *handle,
const char *fname, mode_t mode, SMB_DEV_T dev)
{
SHADOW2_NEXT(MKNOD, (handle, name, mode, dev), int, -1);
}
static char *shadow_copy2_realpath(vfs_handle_struct *handle,
const char *fname, char *resolved_path)
{
SHADOW2_NEXT(REALPATH, (handle, name, resolved_path), void*, NULL);
}
static NTSTATUS shadow_copy2_get_nt_acl(vfs_handle_struct *handle,
const char *fname, uint32 security_info,
struct security_descriptor **ppdesc)
{
SHADOW2_NTSTATUS_NEXT(GET_NT_ACL, (handle, name, security_info, ppdesc), NT_STATUS_ACCESS_DENIED);
}
static NTSTATUS shadow_copy2_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
const char *fname, uint32 security_info_sent,
struct security_descriptor *psd)
{
SHADOW2_NTSTATUS_NEXT(SET_NT_ACL, (handle, fsp, name, security_info_sent, psd), NT_STATUS_ACCESS_DENIED);
}
static int shadow_copy2_mkdir(vfs_handle_struct *handle, const char *fname, mode_t mode)
{
SHADOW2_NEXT(MKDIR, (handle, name, mode), int, -1);
}
static int shadow_copy2_rmdir(vfs_handle_struct *handle, const char *fname)
{
SHADOW2_NEXT(RMDIR, (handle, name), int, -1);
}
static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname, int flags)
{
SHADOW2_NEXT(CHFLAGS, (handle, name, flags), int, -1);
}
static ssize_t shadow_copy2_getxattr(vfs_handle_struct *handle,
const char *fname, const char *aname, void *value, size_t size)
{
SHADOW2_NEXT(GETXATTR, (handle, name, aname, value, size), ssize_t, -1);
}
static ssize_t shadow_copy2_lgetxattr(vfs_handle_struct *handle,
const char *fname, const char *aname, void *value, size_t size)
{
SHADOW2_NEXT(LGETXATTR, (handle, name, aname, value, size), ssize_t, -1);
}
static ssize_t shadow_copy2_listxattr(struct vfs_handle_struct *handle, const char *fname,
char *list, size_t size)
{
SHADOW2_NEXT(LISTXATTR, (handle, name, list, size), ssize_t, -1);
}
static int shadow_copy2_removexattr(struct vfs_handle_struct *handle, const char *fname,
const char *aname)
{
SHADOW2_NEXT(REMOVEXATTR, (handle, name, aname), int, -1);
}
static int shadow_copy2_lremovexattr(struct vfs_handle_struct *handle, const char *fname,
const char *aname)
{
SHADOW2_NEXT(LREMOVEXATTR, (handle, name, aname), int, -1);
}
static int shadow_copy2_setxattr(struct vfs_handle_struct *handle, const char *fname,
const char *aname, const void *value, size_t size, int flags)
{
SHADOW2_NEXT(SETXATTR, (handle, name, aname, value, size, flags), int, -1);
}
static int shadow_copy2_lsetxattr(struct vfs_handle_struct *handle, const char *fname,
const char *aname, const void *value, size_t size, int flags)
{
SHADOW2_NEXT(LSETXATTR, (handle, name, aname, value, size, flags), int, -1);
}
static int shadow_copy2_chmod_acl(vfs_handle_struct *handle,
const char *fname, mode_t mode)
{
/* If the underlying VFS doesn't have ACL support... */
if (!handle->vfs_next.ops.chmod_acl) {
errno = ENOSYS;
return -1;
}
SHADOW2_NEXT(CHMOD_ACL, (handle, name, mode), int, -1);
}
static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle,
files_struct *fsp,
SHADOW_COPY_DATA *shadow_copy2_data,
bool labels)
{
SMB_STRUCT_DIR *p;
const char *snapdir;
SMB_STRUCT_DIRENT *d;
TALLOC_CTX *tmp_ctx = talloc_new(handle->data);
snapdir = shadow_copy2_find_snapdir(tmp_ctx, handle);
if (snapdir == NULL) {
DEBUG(0,("shadow:snapdir not found for %s in get_shadow_copy_data\n",
handle->conn->connectpath));
errno = EINVAL;
talloc_free(tmp_ctx);
return -1;
}
p = SMB_VFS_NEXT_OPENDIR(handle, snapdir, NULL, 0);
if (!p) {
DEBUG(0,("shadow_copy2: SMB_VFS_NEXT_OPENDIR() failed for '%s' - %s\n",
snapdir, strerror(errno)));
talloc_free(tmp_ctx);
return -1;
}
talloc_free(tmp_ctx);
shadow_copy2_data->num_volumes = 0;
shadow_copy2_data->labels = NULL;
while ((d = SMB_VFS_NEXT_READDIR(handle, p))) {
SHADOW_COPY_LABEL *tlabels;
/* ignore names not of the right form in the snapshot directory */
if (!shadow_copy2_match_name(d->d_name)) {
continue;
}
if (!labels) {
/* the caller doesn't want the labels */
shadow_copy2_data->num_volumes++;
continue;
}
tlabels = talloc_realloc(shadow_copy2_data->mem_ctx,
shadow_copy2_data->labels,
SHADOW_COPY_LABEL, shadow_copy2_data->num_volumes+1);
if (tlabels == NULL) {
DEBUG(0,("shadow_copy2: out of memory\n"));
SMB_VFS_NEXT_CLOSEDIR(handle, p);
return -1;
}
strlcpy(tlabels[shadow_copy2_data->num_volumes], d->d_name, sizeof(*tlabels));
shadow_copy2_data->num_volumes++;
shadow_copy2_data->labels = tlabels;
}
SMB_VFS_NEXT_CLOSEDIR(handle,p);
return 0;
}
/* VFS operations structure */
static vfs_op_tuple shadow_copy2_ops[] = {
{SMB_VFS_OP(shadow_copy2_opendir), SMB_VFS_OP_OPENDIR, SMB_VFS_LAYER_TRANSPARENT},
/* directory operations */
{SMB_VFS_OP(shadow_copy2_mkdir), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_rmdir), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT},
/* xattr and flags operations */
{SMB_VFS_OP(shadow_copy2_chflags), SMB_VFS_OP_CHFLAGS, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_getxattr), SMB_VFS_OP_GETXATTR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_lgetxattr), SMB_VFS_OP_LGETXATTR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_listxattr), SMB_VFS_OP_LISTXATTR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_removexattr), SMB_VFS_OP_REMOVEXATTR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_lremovexattr),SMB_VFS_OP_LREMOVEXATTR,SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_setxattr), SMB_VFS_OP_SETXATTR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_lsetxattr), SMB_VFS_OP_LSETXATTR, SMB_VFS_LAYER_TRANSPARENT},
/* File operations */
{SMB_VFS_OP(shadow_copy2_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_lstat), SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_fstat), SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_unlink), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_chmod), SMB_VFS_OP_CHMOD, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_chown), SMB_VFS_OP_CHOWN, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_chdir), SMB_VFS_OP_CHDIR, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_ntimes), SMB_VFS_OP_NTIMES, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_symlink), SMB_VFS_OP_SYMLINK, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_readlink), SMB_VFS_OP_READLINK, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_link), SMB_VFS_OP_LINK, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_mknod), SMB_VFS_OP_MKNOD, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_realpath), SMB_VFS_OP_REALPATH, SMB_VFS_LAYER_TRANSPARENT},
/* NT File ACL operations */
{SMB_VFS_OP(shadow_copy2_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(shadow_copy2_set_nt_acl), SMB_VFS_OP_SET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT},
/* POSIX ACL operations */
{SMB_VFS_OP(shadow_copy2_chmod_acl), SMB_VFS_OP_CHMOD_ACL, SMB_VFS_LAYER_TRANSPARENT},
/* special shadown copy op */
{SMB_VFS_OP(shadow_copy2_get_shadow_copy2_data),
SMB_VFS_OP_GET_SHADOW_COPY_DATA,SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
};
NTSTATUS vfs_shadow_copy2_init(void);
NTSTATUS vfs_shadow_copy2_init(void)
{
NTSTATUS ret;
ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "shadow_copy2", shadow_copy2_ops);
if (!NT_STATUS_IS_OK(ret))
return ret;
vfs_shadow_copy2_debug_level = debug_add_class("shadow_copy2");
if (vfs_shadow_copy2_debug_level == -1) {
vfs_shadow_copy2_debug_level = DBGC_VFS;
DEBUG(0, ("%s: Couldn't register custom debugging class!\n",
"vfs_shadow_copy2_init"));
} else {
DEBUG(10, ("%s: Debug class number of '%s': %d\n",
"vfs_shadow_copy2_init","shadow_copy2",vfs_shadow_copy2_debug_level));
}
return ret;
}

338
source3/modules/vfs_tsmsm.c Normal file
View File

@ -0,0 +1,338 @@
/*
Unix SMB/CIFS implementation.
Samba VFS module for handling offline files
with Tivoli Storage Manager Space Management
(c) Alexander Bokovoy, 2007
(c) Andrew Tridgell, 2007
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/>.
*/
/*
This VFS module accepts following options:
tsmsm: hsm script = <path to hsm script> (/bin/true by default, i.e. does nothing)
hsm script should point to a shell script which accepts two arguments:
<operation> <filepath>
where <operation> is currently 'offline' to set offline status of the <filepath>
tsmsm: online ratio = ratio to check reported size against actual file size (0.5 by default)
The TSMSM VFS module tries to avoid calling expensive DMAPI calls with some heuristics
based on the fact that number of blocks reported of a file multiplied by 512 will be
bigger than 'online ratio' of actual size for online (non-migrated) files.
If checks fail, we call DMAPI and ask for specific IBM attribute which present for
offline (migrated) files. If this attribute presents, we consider file offline.
*/
#include "includes.h"
#ifndef USE_DMAPI
#error "This module requires DMAPI support!"
#endif
#ifdef HAVE_XFS_DMAPI_H
#include <xfs/dmapi.h>
#elif defined(HAVE_SYS_DMI_H)
#include <sys/dmi.h>
#elif defined(HAVE_SYS_JFSDMAPI_H)
#include <sys/jfsdmapi.h>
#elif defined(HAVE_SYS_DMAPI_H)
#include <sys/dmapi.h>
#elif defined(HAVE_DMAPI_H)
#include <dmapi.h>
#endif
#ifndef _ISOC99_SOURCE
#define _ISOC99_SOURCE
#endif
#include <math.h>
/* optimisation tunables - used to avoid the DMAPI slow path */
#define FILE_IS_ONLINE_RATIO 0.5
#define DM_ATTRIB_OBJECT "IBMObj"
#define DM_ATTRIB_MIGRATED "IBMMig"
struct tsmsm_struct {
dm_sessid_t sid;
float online_ratio;
char *hsmscript;
};
#define TSM_STRINGIFY(a) #a
#define TSM_TOSTRING(a) TSM_STRINGIFY(a)
static void tsmsm_free_data(void **pptr) {
struct tsmsm_struct **tsmd = (struct tsmsm_struct **)pptr;
if(!tsmd) return;
TALLOC_FREE(*tsmd);
}
static int tsmsm_connect(struct vfs_handle_struct *handle,
const char *service,
const char *user) {
struct tsmsm_struct *tsmd = TALLOC_ZERO_P(handle, struct tsmsm_struct);
const char *hsmscript, *tsmname;
const char *fres;
if (!tsmd) {
DEBUG(0,("tsmsm_connect: out of memory!\n"));
return -1;
}
tsmd->sid = *(dm_sessid_t*) dmapi_get_current_session();
if (tsmd->sid == DM_NO_SESSION) {
DEBUG(0,("tsmsm_connect: no DMAPI session for Samba is available!\n"));
TALLOC_FREE(tsmd);
return -1;
}
tsmname = (handle->param ? handle->param : "tsmsm");
hsmscript = lp_parm_const_string(SNUM(handle->conn), tsmname,
"hsm script", NULL);
if (hsmscript) {
tsmd->hsmscript = talloc_strdup(tsmd, hsmscript);
if(!tsmd->hsmscript) {
DEBUG(1, ("tsmsm_connect: can't allocate memory for hsm script path"));
TALLOC_FREE(tsmd);
return -1;
}
} else {
DEBUG(1, ("tsmsm_connect: can't call hsm script because it "
"is not set to anything in the smb.conf\n"
"Use %s: 'hsm script = path' to set it\n",
tsmname));
TALLOC_FREE(tsmd);
return -1;
}
fres = lp_parm_const_string(SNUM(handle->conn), tsmname,
"online ratio", TSM_TOSTRING(FILE_IS_ONLINE_RATIO));
tsmd->online_ratio = strtof(fres, NULL);
if((tsmd->online_ratio == (float)0) || ((errno == ERANGE) &&
((tsmd->online_ratio == HUGE_VALF) ||
(tsmd->online_ratio == HUGE_VALL)))) {
DEBUG(1, ("tsmsm_connect: error while getting online ratio from smb.conf."
"Default to %s.\n", TSM_TOSTRING(FILE_IS_ONLINE_RATIO)));
tsmd->online_ratio = FILE_IS_ONLINE_RATIO;
}
/* Store the private data. */
SMB_VFS_HANDLE_SET_DATA(handle, tsmd, tsmsm_free_data,
struct tsmsm_struct, return -1);
return SMB_VFS_NEXT_CONNECT(handle, service, user);
}
static int tsmsm_is_offline(struct vfs_handle_struct *handle,
struct connection_struct *conn,
const char *path,
SMB_STRUCT_STAT *stbuf,
bool *offline) {
struct tsmsm_struct *tsmd = (struct tsmsm_struct *) handle->data;
void *dmhandle = NULL;
size_t dmhandle_len = 0;
size_t rlen;
dm_attrname_t dmname;
int ret;
/* if the file has more than FILE_IS_ONLINE_RATIO of blocks available,
then assume it is not offline (it may not be 100%, as it could be sparse) */
if (512 * (off_t)stbuf->st_blocks >= stbuf->st_size * tsmd->online_ratio) {
*offline = false;
DEBUG(10,("%s not offline: st_blocks=%ld st_size=%ld online_ratio=%.2f\n",
path, stbuf->st_blocks, stbuf->st_size, tsmd->online_ratio));
return 0;
}
/* using POSIX capabilities does not work here. It's a slow path, so
* become_root() is just as good anyway (tridge)
*/
/* Also, AIX has DMAPI but no POSIX capablities support. In this case,
* we need to be root to do DMAPI manipulations.
*/
become_root();
/* go the slow DMAPI route */
if (dm_path_to_handle((char*)path, &dmhandle, &dmhandle_len) != 0) {
ret = -1;
DEBUG(2,("dm_path_to_handle failed - assuming offline (%s) - %s\n",
path, strerror(errno)));
*offline = True;
goto done;
}
memset(&dmname, 0, sizeof(dmname));
strlcpy((char *)&dmname.an_chars[0], DM_ATTRIB_OBJECT, sizeof(dmname.an_chars));
ret = dm_get_dmattr(tsmd->sid, dmhandle, dmhandle_len,
DM_NO_TOKEN, &dmname, 0, NULL, &rlen);
/* its offline if the IBMObj attribute exists */
*offline = (ret == 0 || (ret == -1 && errno == E2BIG));
DEBUG(10,("dm_get_dmattr %s ret=%d (%s)\n", path, ret, strerror(errno)));
ret = 0;
dm_handle_free(dmhandle, dmhandle_len);
done:
unbecome_root();
return ret;
}
static bool tsmsm_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
{
SMB_STRUCT_STAT sbuf;
struct tsmsm_struct *tsmd = (struct tsmsm_struct *) handle->data;
/* see if the file might be offline. This is called before each IO
to ensure we use AIO if the file is offline. We don't do the full dmapi
call as that would be too slow, instead we err on the side of using AIO
if the file might be offline
*/
if(SMB_VFS_FSTAT(fsp, &sbuf) == 0) {
DEBUG(10,("tsmsm_aio_force st_blocks=%ld st_size=%ld online_ratio=%.2f\n",
sbuf.st_blocks, sbuf.st_size, tsmd->online_ratio));
return !(512 * (off_t)sbuf.st_blocks >= sbuf.st_size * tsmd->online_ratio);
}
return False;
}
static ssize_t tsmsm_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp,
SMB_STRUCT_AIOCB *aiocb)
{
ssize_t result;
result = SMB_VFS_NEXT_AIO_RETURN(handle, fsp, aiocb);
if(result >= 0) {
notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES,
fsp->fsp_name);
}
return result;
}
static ssize_t tsmsm_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, const DATA_BLOB *hdr,
SMB_OFF_T offset, size_t n)
{
bool file_online = tsmsm_aio_force(handle, fsp);
if(!file_online)
return ENOSYS;
return SMB_VFS_NEXT_SENDFILE(handle, tofd, fsp, hdr, offset, n);
}
/* We do overload pread to allow notification when file becomes online after offline status */
/* We don't intercept SMB_VFS_READ here because all file I/O now goes through SMB_VFS_PREAD instead */
static ssize_t tsmsm_pread(struct vfs_handle_struct *handle, struct files_struct *fsp,
void *data, size_t n, SMB_OFF_T offset) {
ssize_t result;
bool notify_online = tsmsm_aio_force(handle, fsp);
result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
if((result != -1) && notify_online) {
/* We can't actually force AIO at this point (came here not from reply_read_and_X)
what we can do is to send notification that file became online
*/
notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES,
fsp->fsp_name);
}
return result;
}
static ssize_t tsmsm_pwrite(struct vfs_handle_struct *handle, struct files_struct *fsp,
void *data, size_t n, SMB_OFF_T offset) {
ssize_t result;
bool notify_online = tsmsm_aio_force(handle, fsp);
result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
if((result != -1) && notify_online) {
/* We can't actually force AIO at this point (came here not from reply_read_and_X)
what we can do is to send notification that file became online
*/
notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES,
fsp->fsp_name);
}
return result;
}
static int tsmsm_set_offline(struct vfs_handle_struct *handle, struct connection_struct *conn,
const char *path) {
struct tsmsm_struct *tsmd = (struct tsmsm_struct *) handle->data;
int result = 0;
char *command;
/* Now, call the script */
command = talloc_asprintf(tsmd, "%s offline \"%s\"", tsmd->hsmscript, path);
if(!command) {
DEBUG(1, ("tsmsm_set_offline: can't allocate memory to run hsm script"));
return -1;
}
DEBUG(10, ("tsmsm_set_offline: Running [%s]\n", command));
if((result = smbrun(command, NULL)) != 0) {
DEBUG(1,("tsmsm_set_offline: Running [%s] returned %d\n", command, result));
}
TALLOC_FREE(command);
return result;
}
static bool tsmsm_is_remotestorage(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path) {
return True;
}
static vfs_op_tuple vfs_tsmsm_ops[] = {
/* Disk operations */
{SMB_VFS_OP(tsmsm_connect), SMB_VFS_OP_CONNECT,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(tsmsm_aio_force), SMB_VFS_OP_AIO_FORCE,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(tsmsm_aio_return), SMB_VFS_OP_AIO_RETURN,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(tsmsm_pread), SMB_VFS_OP_PREAD,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(tsmsm_pwrite), SMB_VFS_OP_PWRITE,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(tsmsm_sendfile), SMB_VFS_OP_SENDFILE,
SMB_VFS_LAYER_TRANSPARENT},
{SMB_VFS_OP(tsmsm_is_offline),SMB_VFS_OP_IS_OFFLINE,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(tsmsm_set_offline),SMB_VFS_OP_SET_OFFLINE,
SMB_VFS_LAYER_OPAQUE},
{SMB_VFS_OP(tsmsm_is_remotestorage),SMB_VFS_OP_IS_REMOTESTORAGE,
SMB_VFS_LAYER_OPAQUE},
/* Finish VFS operations definition */
{SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP,
SMB_VFS_LAYER_NOOP}
};
NTSTATUS vfs_tsmsm_init(void);
NTSTATUS vfs_tsmsm_init(void)
{
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
"tsmsm", vfs_tsmsm_ops);
}

View File

@ -9,6 +9,7 @@
Copyright (C) Alexander Bokovoy 2002
Copyright (C) Stefan (metze) Metzmacher 2002
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
Copyright (C) Michael Adam 2008
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
@ -70,16 +71,12 @@ extern userdom_struct current_user_info;
#define HOMES_NAME "homes"
#endif
/* the special value for the include parameter
* to be interpreted not as a file name but to
* trigger loading of the global smb.conf options
* from registry. */
#ifndef INCLUDE_REGISTRY_NAME
#define INCLUDE_REGISTRY_NAME "registry"
#endif
static int regdb_last_seqnum = 0;
static bool include_registry_globals = False;
#define CONFIG_BACKEND_FILE 0
#define CONFIG_BACKEND_REGISTRY 1
static int config_backend = CONFIG_BACKEND_FILE;
/* some helpful bits */
#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
@ -104,6 +101,7 @@ struct _param_opt_struct {
* This structure describes global (ie., server-wide) parameters.
*/
typedef struct {
int ConfigBackend;
char *smb_ports;
char *dos_charset;
char *unix_charset;
@ -842,6 +840,14 @@ static const struct enum_list enum_map_to_guest[] = {
{-1, NULL}
};
/* Config backend options */
static const struct enum_list enum_config_backend[] = {
{CONFIG_BACKEND_FILE, "file"},
{CONFIG_BACKEND_REGISTRY, "registry"},
{-1, NULL}
};
/* Note: We do not initialise the defaults union - it is not allowed in ANSI C
*
* The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
@ -880,6 +886,8 @@ static struct parm_struct parm_table[] = {
{"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
{"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
{"config backend", P_ENUM, P_GLOBAL, &Globals.ConfigBackend, NULL, enum_config_backend, FLAG_ADVANCED},
{N_("Security Options"), P_SEP, P_SEPARATOR},
{"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
@ -1215,14 +1223,14 @@ static struct parm_struct parm_table[] = {
{"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
{"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
{N_("EventLog Options"), P_SEP, P_SEPARATOR},
{"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
{N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
{"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
{"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
{"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
{N_("EventLog Options"), P_SEP, P_SEPARATOR},
{"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
{"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
{"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
{"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
@ -1294,6 +1302,8 @@ static struct parm_struct parm_table[] = {
{"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE},
{N_("MSDFS options"), P_SEP, P_SEPARATOR},
{"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED},
@ -1527,6 +1537,8 @@ static void init_globals(bool first_time_only)
Globals.bLoadPrinters = True;
Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
Globals.ConfigBackend = config_backend;
/* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
/* Discovered by 2 days of pain by Don McCall @ HP :-). */
Globals.max_xmit = 0x4104;
@ -2046,6 +2058,7 @@ FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend);
FN_LOCAL_STRING(lp_preexec, szPreExec)
FN_LOCAL_STRING(lp_postexec, szPostExec)
@ -3422,8 +3435,6 @@ static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
char * valstr;
struct registry_value *value = NULL;
include_registry_globals = True;
ZERO_STRUCT(data);
reg_tdb = lp_regdb_open();
@ -3536,8 +3547,6 @@ static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
smb_panic("Failed to create talloc context!");
}
include_registry_globals = True;
if (!registry_init_regdb()) {
DEBUG(1, ("Error initializing the registry.\n"));
goto done;
@ -3637,9 +3646,12 @@ static void add_to_file_list(const char *fname, const char *subfname)
}
}
bool lp_include_registry_globals(void)
/**
* Utility function for outsiders to check if we're running on registry.
*/
bool lp_config_backend_is_registry(void)
{
return include_registry_globals;
return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
}
/*******************************************************************
@ -3653,7 +3665,7 @@ bool lp_file_list_changed(void)
DEBUG(6, ("lp_file_list_changed()\n"));
if (include_registry_globals) {
if (lp_config_backend() == CONFIG_BACKEND_REGISTRY) {
reg_tdb = lp_regdb_open();
if (reg_tdb && (regdb_last_seqnum != tdb_get_seqnum(reg_tdb->tdb)))
{
@ -3661,6 +3673,15 @@ bool lp_file_list_changed(void)
regdb_last_seqnum, tdb_get_seqnum(reg_tdb->tdb)));
TALLOC_FREE(reg_tdb);
return true;
} else {
/*
* Don't check files when config_backend is registry.
* Remove this to obtain checking of files even with
* registry config backend. That would enable switching
* off registry configuration by changing smb.conf even
* without restarting smbd.
*/
return false;
}
}
@ -3696,6 +3717,7 @@ bool lp_file_list_changed(void)
return (False);
}
/***************************************************************************
Run standard_sub_basic on netbios name... needed because global_myname
is not accessed through any lp_ macro.
@ -3765,17 +3787,6 @@ static bool handle_include(int snum, const char *pszParmValue, char **ptr)
{
char *fname;
if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
if (bInGlobalSection) {
return process_registry_globals(do_parameter);
}
else {
DEBUG(1, ("\"include = registry\" only effective "
"in %s section\n", GLOBAL_NAME));
return false;
}
}
fname = alloc_sub_basic(get_current_username(),
current_user_info.domain,
pszParmValue);
@ -5654,15 +5665,6 @@ bool lp_load(const char *pszFname,
bool bRetval;
param_opt_struct *data, *pdata;
n2 = alloc_sub_basic(get_current_username(),
current_user_info.domain,
pszFname);
if (!n2) {
smb_panic("lp_load: out of memory");
}
add_to_file_list(pszFname, n2);
bRetval = False;
DEBUG(3, ("lp_load: refreshing parameters\n"));
@ -5691,17 +5693,47 @@ bool lp_load(const char *pszFname,
Globals.param_opt = NULL;
}
/* We get sections first, so have to start 'behind' to make up */
iServiceIndex = -1;
bRetval = pm_process(n2, do_section, do_parameter);
SAFE_FREE(n2);
/* finish up the last section */
DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
if (bRetval) {
if (iServiceIndex >= 0) {
bRetval = service_ok(iServiceIndex);
if (lp_config_backend() == CONFIG_BACKEND_FILE) {
n2 = alloc_sub_basic(get_current_username(),
current_user_info.domain,
pszFname);
if (!n2) {
smb_panic("lp_load: out of memory");
}
add_to_file_list(pszFname, n2);
/* We get sections first, so have to start 'behind' to make up */
iServiceIndex = -1;
bRetval = pm_process(n2, do_section, do_parameter);
SAFE_FREE(n2);
/* finish up the last section */
DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
if (bRetval) {
if (iServiceIndex >= 0) {
bRetval = service_ok(iServiceIndex);
}
}
if (lp_config_backend() == CONFIG_BACKEND_REGISTRY) {
/*
* We need to use this extra global variable here to
* survive restart: init_globals usese this as a default
* for ConfigBackend. Otherwise, init_globals would
* send us into an endless loop here.
*/
config_backend = CONFIG_BACKEND_REGISTRY;
/* start over */
return lp_load(pszFname, global_only, save_defaults,
add_ipc, initialize_globals);
}
} else if (lp_config_backend() == CONFIG_BACKEND_REGISTRY) {
bRetval = process_registry_globals(do_parameter);
} else {
DEBUG(0, ("Illegal config backend given: %d\n",
lp_config_backend()));
bRetval = false;
}
lp_add_auto_services(lp_auto_services());

View File

@ -2583,7 +2583,7 @@ NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(pipes_struct *p, struct lsa_LSARUNREGISTE
return NT_STATUS_NOT_IMPLEMENTED;
}
NTSTATUS _lsa_LSARQUERYFORESTTRUSTINFORMATION(pipes_struct *p, struct lsa_LSARQUERYFORESTTRUSTINFORMATION *r)
NTSTATUS _lsa_lsaRQueryForestTrustInformation(pipes_struct *p, struct lsa_lsaRQueryForestTrustInformation *r)
{
p->rng_fault_state = True;
return NT_STATUS_NOT_IMPLEMENTED;

View File

@ -117,6 +117,15 @@ int count_current_connections( const char *sharename, bool clear )
return cs.curr_connections;
}
/****************************************************************************
Count the number of connections open across all shares.
****************************************************************************/
int count_all_current_connections(void)
{
return count_current_connections(NULL, True /* clear stale entries */);
}
/****************************************************************************
Claim an entry in the connections database.
****************************************************************************/

View File

@ -46,7 +46,7 @@ bool dmapi_have_session(void) { return False; }
#define DMAPI_SESSION_NAME "samba"
#define DMAPI_TRACE 10
static dm_sessid_t dmapi_session = DM_NO_SESSION;
static dm_sessid_t samba_dmapi_session = DM_NO_SESSION;
/* Initialise the DMAPI interface. Make sure that we only end up initialising
* once per process to avoid resource leaks across different DMAPI
@ -75,7 +75,7 @@ static int init_dmapi_service(void)
bool dmapi_have_session(void)
{
return dmapi_session != DM_NO_SESSION;
return samba_dmapi_session != DM_NO_SESSION;
}
static dm_sessid_t *realloc_session_list(dm_sessid_t * sessions, int count)
@ -110,7 +110,7 @@ int dmapi_init_session(void)
*/
SMB_WARN(getuid() == 0, "dmapi_init_session must be called as root");
dmapi_session = DM_NO_SESSION;
samba_dmapi_session = DM_NO_SESSION;
if (init_dmapi_service() < 0) {
return -1;
}
@ -139,7 +139,7 @@ retry:
err = dm_query_session(sessions[i], sizeof(buf), buf, &buflen);
buf[sizeof(buf) - 1] = '\0';
if (err == 0 && strcmp(DMAPI_SESSION_NAME, buf) == 0) {
dmapi_session = sessions[i];
samba_dmapi_session = sessions[i];
DEBUGADD(DMAPI_TRACE,
("attached to existing DMAPI session "
"named '%s'\n", buf));
@ -150,16 +150,15 @@ retry:
TALLOC_FREE(sessions);
/* No session already defined. */
if (dmapi_session == DM_NO_SESSION) {
err = dm_create_session(DM_NO_SESSION,
CONST_DISCARD(char *,
DMAPI_SESSION_NAME),
&dmapi_session);
if (samba_dmapi_session == DM_NO_SESSION) {
err = dm_create_session(DM_NO_SESSION,
CONST_DISCARD(char *, DMAPI_SESSION_NAME),
&samba_dmapi_session);
if (err < 0) {
DEBUGADD(DMAPI_TRACE,
("failed to create new DMAPI session: %s\n",
strerror(errno)));
dmapi_session = DM_NO_SESSION;
samba_dmapi_session = DM_NO_SESSION;
return -1;
}
@ -185,22 +184,22 @@ static int reattach_dmapi_session(void)
char buf[DM_SESSION_INFO_LEN];
size_t buflen;
if (dmapi_session != DM_NO_SESSION ) {
if (samba_dmapi_session != DM_NO_SESSION ) {
become_root();
/* NOTE: On Linux, this call opens /dev/dmapi, costing us a
* file descriptor. Ideally, we would close this when we fork.
*/
if (init_dmapi_service() < 0) {
dmapi_session = DM_NO_SESSION;
samba_dmapi_session = DM_NO_SESSION;
unbecome_root();
return -1;
}
if (dm_query_session(dmapi_session, sizeof(buf),
if (dm_query_session(samba_dmapi_session, sizeof(buf),
buf, &buflen) < 0) {
/* Session is stale. Disable DMAPI. */
dmapi_session = DM_NO_SESSION;
samba_dmapi_session = DM_NO_SESSION;
unbecome_root();
return -1;
}
@ -214,33 +213,42 @@ static int reattach_dmapi_session(void)
return 0;
}
uint32 dmapi_file_flags(const char * const path)
/* If a DMAPI session has been initialised, then we need to make sure
* we are attached to it and have the correct privileges. This is
* necessary to be able to do DMAPI operations across a fork(2). If
* it fails, there is no likelihood of that failure being transient.
*
* Note that this use of the static attached flag relies on the fact
* that dmapi_file_flags() is never called prior to forking the
* per-client server process.
*/
const void * dmapi_get_current_session(void)
{
static int attached = 0;
if (dmapi_have_session() && !attached) {
attached++;
if (reattach_dmapi_session() < 0) {
return DM_NO_SESSION;
}
}
return &samba_dmapi_session;
}
uint32 dmapi_file_flags(const char * const path)
{
dm_sessid_t dmapi_session;
int err;
dm_eventset_t events = {0};
uint nevents;
void *dm_handle;
size_t dm_handle_len;
void *dm_handle = NULL;
size_t dm_handle_len = 0;
uint32 flags = 0;
/* If a DMAPI session has been initialised, then we need to make sure
* we are attached to it and have the correct privileges. This is
* necessary to be able to do DMAPI operations across a fork(2). If
* it fails, there is no liklihood of that failure being transient.
*
* Note that this use of the static attached flag relies on the fact
* that dmapi_file_flags() is never called prior to forking the
* per-client server process.
*/
if (dmapi_have_session() && !attached) {
attached++;
if (reattach_dmapi_session() < 0) {
return 0;
}
dmapi_session = *(dm_sessid_t*) dmapi_get_current_session();
if (dmapi_session == DM_NO_SESSION) {
return 0;
}
/* AIX has DMAPI but no POSIX capablities support. In this case,
@ -313,4 +321,5 @@ done:
return flags;
}
#endif /* USE_DMAPI */

View File

@ -30,23 +30,6 @@ static int set_sparse_flag(const SMB_STRUCT_STAT * const sbuf)
return 0;
}
/****************************************************************************
Work out whether this file is offline
****************************************************************************/
static uint32 set_offline_flag(connection_struct *conn, const char *const path)
{
if (ISDOT(path) || ISDOTDOT(path)) {
return 0;
}
if (!lp_dmapi_support(SNUM(conn)) || !dmapi_have_session()) {
return 0;
}
return dmapi_file_flags(path);
}
/****************************************************************************
Change a dos mode to a unix mode.
Base permission for files:
@ -366,6 +349,8 @@ uint32 dos_mode_msdfs(connection_struct *conn, const char *path,SMB_STRUCT_STAT
uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
{
uint32 result = 0;
bool offline;
int ret;
DEBUG(8,("dos_mode: %s\n", path));
@ -395,8 +380,10 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf)
result |= dos_mode_from_sbuf(conn, path, sbuf);
}
if (S_ISREG(sbuf->st_mode)) {
result |= set_offline_flag(conn, path);
ret = SMB_VFS_IS_OFFLINE(conn, path, sbuf, &offline);
if (S_ISREG(sbuf->st_mode) && (ret == 0) && offline) {
result |= FILE_ATTRIBUTE_OFFLINE;
}
/* Optimization : Only call is_hidden_path if it's not already
@ -432,7 +419,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
int mask=0;
mode_t tmp;
mode_t unixmode;
int ret = -1;
int ret = -1, lret = -1;
/* We only allow READONLY|HIDDEN|SYSTEM|DIRECTORY|ARCHIVE here. */
dosmode &= SAMBA_ATTRIBUTES_MASK;
@ -505,10 +492,21 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
}
if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) {
if (!newfile) {
if (dosmode & FILE_ATTRIBUTE_OFFLINE) {
lret = SMB_VFS_SET_OFFLINE(conn, fname);
if (lret == -1) {
DEBUG(0, ("set_dos_mode: client has asked to set "
"FILE_ATTRIBUTE_OFFLINE to %s/%s but there was "
"an error while setting it or it is not supported.\n",
parent_dir, fname));
}
}
ret = SMB_VFS_CHMOD(conn, fname, unixmode);
if (ret == 0) {
if(!newfile || (lret != -1)) {
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
}
st->st_mode = unixmode;
return 0;

View File

@ -93,17 +93,27 @@ static void set_capability(unsigned capability)
return;
}
data.effective |= (1<<capability);
if (0 == (data.effective & (1<<capability))) {
data.effective |= (1<<capability);
if (capset(&header, &data) == -1) {
DEBUG(3,("Unable to set %d capability (%s)\n",
capability, strerror(errno)));
if (capset(&header, &data) == -1) {
DEBUG(3,("Unable to set %d capability (%s)\n",
capability, strerror(errno)));
}
}
}
/*
Call to set the kernel lease signal handler
*/
* public function to get linux lease capability. Needed by some VFS modules (eg. gpfs.c)
*/
void linux_set_lease_capability(void)
{
set_capability(CAP_LEASE);
}
/*
* Call to set the kernel lease signal handler
*/
int linux_set_lease_sighandler(int fd)
{
if (fcntl(fd, F_SETSIG, RT_SIGNAL_LEASE) == -1) {

View File

@ -3413,6 +3413,9 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
bool acl_perms = False;
mode_t orig_mode = (mode_t)0;
NTSTATUS status;
uid_t orig_uid;
gid_t orig_gid;
bool need_chown = False;
DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name ));
@ -3435,6 +3438,8 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
/* Save the original elements we check against. */
orig_mode = sbuf.st_mode;
orig_uid = sbuf.st_uid;
orig_gid = sbuf.st_gid;
/*
* Unpack the user/group/world id's.
@ -3449,7 +3454,11 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
* Do we need to chown ?
*/
if (((user != (uid_t)-1) && (sbuf.st_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_gid != grp))) {
if (((user != (uid_t)-1) && (orig_uid != user)) || (( grp != (gid_t)-1) && (orig_gid != grp))) {
need_chown = True;
}
if (need_chown && (user == (uid_t)-1 || user == current_user.ut.uid)) {
DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
@ -3487,6 +3496,11 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
/* Save the original elements we check against. */
orig_mode = sbuf.st_mode;
orig_uid = sbuf.st_uid;
orig_gid = sbuf.st_gid;
/* We did chown already, drop the flag */
need_chown = False;
}
create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid);
@ -3630,6 +3644,21 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
free_canon_ace_list(dir_ace_list);
}
/* Any chown pending? */
if (need_chown) {
DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
if(try_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) {
DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error = %s.\n",
fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) ));
if (errno == EPERM) {
return NT_STATUS_INVALID_OWNER;
}
return map_nt_error_from_unix(errno);
}
}
return NT_STATUS_OK;
}

View File

@ -3329,8 +3329,12 @@ void reply_read_and_X(struct smb_request *req)
return;
}
if (!big_readX
&& schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
/* It is possible for VFS modules to selectively decide whether Async I/O should be used
for the file or not.
*/
if ((SMB_VFS_AIO_FORCE(fsp)) &&
!big_readX &&
schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
END_PROFILE(SMBreadX);
return;
}
@ -4001,13 +4005,16 @@ void reply_write_and_X(struct smb_request *req)
nwritten = 0;
} else {
if (req->unread_bytes == 0 &&
schedule_aio_write_and_X(conn, req, fsp, data,
startpos, numtowrite)) {
/* It is possible for VFS modules to selectively decide whether Async I/O
should be used for the file or not.
*/
if ((SMB_VFS_AIO_FORCE(fsp)) && (req->unread_bytes == 0) &&
schedule_aio_write_and_X(conn, req, fsp, data, startpos,
numtowrite)) {
END_PROFILE(SMBwriteX);
return;
}
nwritten = write_file(req,fsp,data,startpos,numtowrite);
}

View File

@ -268,10 +268,20 @@ static void add_child_pid(pid_t pid)
num_children += 1;
}
static void remove_child_pid(pid_t pid)
static void remove_child_pid(pid_t pid, bool unclean_shutdown)
{
struct child_pid *child;
if (unclean_shutdown) {
/* a child terminated uncleanly so tickle all processes to see
if they can grab any of the pending locks
*/
messaging_send_buf(smbd_messaging_context(), procid_self(),
MSG_SMB_BRL_VALIDATE, NULL, 0);
message_send_all(smbd_messaging_context(),
MSG_SMB_UNLOCK, NULL, 0, NULL);
}
if (lp_max_smbd_processes() == 0) {
/* Don't bother with the child list if we don't care anyway */
return;
@ -560,10 +570,27 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
if (got_sig_cld) {
pid_t pid;
int status;
got_sig_cld = False;
while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) {
remove_child_pid(pid);
while ((pid = sys_waitpid(-1, &status, WNOHANG)) > 0) {
bool unclean_shutdown = False;
/* If the child terminated normally, assume
it was an unclean shutdown unless the
status is 0
*/
if (WIFEXITED(status)) {
unclean_shutdown = WEXITSTATUS(status);
}
/* If the child terminated due to a signal
we always assume it was unclean.
*/
if (WIFSIGNALED(status)) {
unclean_shutdown = True;
}
remove_child_pid(pid, unclean_shutdown);
}
}
@ -603,6 +630,15 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_
continue;
}
/* If the idle timeout fired and we don't have any connected
* users, exit gracefully. We should be running under a process
* controller that will restart us if necessry.
*/
if (num == 0 && count_all_current_connections() == 0) {
exit_server_cleanly("idle timeout");
}
/* process pending nDNS responses */
if (dns_register_smbd_reply(dns_reg, &r_fds, &idle_timeout)) {
@ -906,6 +942,29 @@ void exit_server_fault(void)
exit_server("critical server fault");
}
/****************************************************************************
received when we should release a specific IP
****************************************************************************/
static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
{
const char *ip = (const char *)data->data;
char addr[INET6_ADDRSTRLEN];
if (strcmp(client_socket_addr(get_client_fd(),addr,sizeof(addr)), ip) == 0) {
/* we can't afford to do a clean exit - that involves
database writes, which would potentially mean we
are still running after the failover has finished -
we have to get rid of this process ID straight
away */
DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
ip));
_exit(0);
}
}
/****************************************************************************
Initialise connect, service and file structs.
****************************************************************************/
@ -1305,6 +1364,8 @@ extern void build_options(bool screen);
/* register our message handlers */
messaging_register(smbd_messaging_context(), NULL,
MSG_SMB_FORCE_TDIS, msg_force_tdis);
messaging_register(smbd_messaging_context(), NULL,
MSG_SMB_RELEASE_IP, msg_release_ip);
if ((lp_keepalive() != 0)
&& !(event_add_idle(smbd_event_context(), NULL,

View File

@ -219,44 +219,6 @@ bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir)
return(True);
}
/****************************************************************************
Add a home service. Returns the new service number or -1 if fail.
****************************************************************************/
int add_home_service(const char *service, const char *username, const char *homedir)
{
int iHomeService;
if (!service || !homedir)
return -1;
if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0)
return -1;
/*
* If this is a winbindd provided username, remove
* the domain component before adding the service.
* Log a warning if the "path=" parameter does not
* include any macros.
*/
{
const char *p = strchr(service,*lp_winbind_separator());
/* We only want the 'user' part of the string */
if (p) {
service = p + 1;
}
}
if (!lp_add_home(service, iHomeService, username, homedir)) {
return -1;
}
return lp_servicenumber(service);
}
static int load_registry_service(const char *servicename)
{
struct registry_key *key;
@ -348,6 +310,47 @@ void load_registry_shares(void)
return;
}
/****************************************************************************
Add a home service. Returns the new service number or -1 if fail.
****************************************************************************/
int add_home_service(const char *service, const char *username, const char *homedir)
{
int iHomeService;
if (!service || !homedir)
return -1;
if ((iHomeService = lp_servicenumber(HOMES_NAME)) < 0) {
if ((iHomeService = load_registry_service(HOMES_NAME)) < 0) {
return -1;
}
}
/*
* If this is a winbindd provided username, remove
* the domain component before adding the service.
* Log a warning if the "path=" parameter does not
* include any macros.
*/
{
const char *p = strchr(service,*lp_winbind_separator());
/* We only want the 'user' part of the string */
if (p) {
service = p + 1;
}
}
if (!lp_add_home(service, iHomeService, username, homedir)) {
return -1;
}
return lp_servicenumber(service);
}
/**
* Find a service entry.
*
@ -386,7 +389,10 @@ int find_service(fstring service)
if (iService < 0) {
int iPrinterService;
if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) < 0) {
iPrinterService = load_registry_service(PRINTERS_NAME);
}
if (iPrinterService) {
DEBUG(3,("checking whether %s is a valid printer name...\n", service));
if (pcap_printername_ok(service)) {
DEBUG(3,("%s is a valid printer name\n", service));

View File

@ -2373,8 +2373,8 @@ static void call_trans2qfsinfo(connection_struct *conn,
const char *vname = volume_label(SNUM(conn));
int snum = SNUM(conn);
char *fstype = lp_fstype(SNUM(conn));
int quota_flag = 0;
uint32 additional_flags = 0;
if (total_params < 2) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
@ -2487,16 +2487,23 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsi
case SMB_QUERY_FS_ATTRIBUTE_INFO:
case SMB_FS_ATTRIBUTE_INFORMATION:
additional_flags = 0;
#if defined(HAVE_SYS_QUOTAS)
quota_flag = FILE_VOLUME_QUOTAS;
additional_flags |= FILE_VOLUME_QUOTAS;
#endif
if(lp_nt_acl_support(SNUM(conn))) {
additional_flags |= FILE_PERSISTENT_ACLS;
}
if(SMB_VFS_IS_REMOTESTORAGE(conn, lp_pathname(SNUM(conn)))) {
additional_flags |= FILE_SUPPORTS_REMOTE_STORAGE;
additional_flags |= FILE_SUPPORTS_REPARSE_POINTS;
}
SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
(lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
FILE_SUPPORTS_OBJECT_IDS|
FILE_UNICODE_ON_DISK|
quota_flag); /* FS ATTRIBUTES */
FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
additional_flags); /* FS ATTRIBUTES */
SIVAL(pdata,4,255); /* Max filename component length */
/* NOTE! the fstype must *not* be null terminated or win98 won't recognise it

File diff suppressed because it is too large Load Diff