summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/Makefile.in8
-rw-r--r--source/auth/auth_server.c64
-rw-r--r--source/auth/auth_util.c133
-rw-r--r--source/client/client.c351
-rw-r--r--source/client/smbctool.c2
-rw-r--r--source/client/smbmount.c12
-rw-r--r--source/client/smbspool.c7
-rw-r--r--source/include/includes.h1
-rw-r--r--source/include/libsmb_internal.h2
-rw-r--r--source/include/locking.h89
-rw-r--r--source/include/nt_status.h1
-rw-r--r--source/include/nterr.h4
-rw-r--r--source/include/printing.h4
-rw-r--r--source/include/reg_objects.h5
-rw-r--r--source/include/rpc_misc.h5
-rw-r--r--source/include/smb.h59
-rw-r--r--source/include/smb_macros.h23
-rw-r--r--source/include/vfs.h133
-rw-r--r--source/include/vfs_macros.h350
-rw-r--r--source/lib/afs.c7
-rw-r--r--source/lib/data_blob.c2
-rw-r--r--source/lib/sharesec.c50
-rw-r--r--source/lib/substitute.c189
-rw-r--r--source/lib/util.c4
-rw-r--r--source/lib/util_str.c11
-rw-r--r--source/libmsrpc/cac_lsarpc.c2092
-rw-r--r--source/libmsrpc/cac_samr.c4047
-rw-r--r--source/libmsrpc/cac_svcctl.c850
-rw-r--r--source/libmsrpc/libmsrpc_internal.c8
-rw-r--r--source/libsmb/cliconnect.c177
-rw-r--r--source/libsmb/clidfs.c16
-rw-r--r--source/libsmb/clientgen.c42
-rw-r--r--source/libsmb/clikrb5.c21
-rw-r--r--source/libsmb/clirap.c3
-rw-r--r--source/libsmb/libsmb_cache.c8
-rw-r--r--source/libsmb/libsmbclient.c393
-rw-r--r--source/libsmb/passchange.c143
-rw-r--r--source/locking/brlock.c524
-rw-r--r--source/locking/locking.c249
-rw-r--r--source/locking/posix.c1305
-rw-r--r--source/modules/vfs_audit.c60
-rw-r--r--source/modules/vfs_cacheprime.c200
-rw-r--r--source/modules/vfs_cap.c126
-rw-r--r--source/modules/vfs_catia.c84
-rw-r--r--source/modules/vfs_commit.c189
-rw-r--r--source/modules/vfs_default.c1338
-rw-r--r--source/modules/vfs_default_quota.c16
-rw-r--r--source/modules/vfs_expand_msdfs.c12
-rw-r--r--source/modules/vfs_extd_audit.c60
-rw-r--r--source/modules/vfs_fake_perms.c4
-rw-r--r--source/modules/vfs_full_audit.c335
-rw-r--r--source/modules/vfs_netatalk.c62
-rw-r--r--source/modules/vfs_prealloc.c214
-rw-r--r--source/modules/vfs_readonly.c5
-rw-r--r--source/modules/vfs_recycle.c66
-rw-r--r--source/modules/vfs_shadow_copy.c28
-rw-r--r--source/nmbd/nmbd_synclists.c34
-rw-r--r--source/nsswitch/winbindd_cm.c10
-rw-r--r--source/param/loadparm.c150
-rw-r--r--source/passdb/passdb.c14
-rw-r--r--source/passdb/pdb_ldap.c17
-rw-r--r--source/passdb/pdb_tdb.c39
-rw-r--r--source/printing/nt_printing.c32
-rw-r--r--source/printing/print_generic.c11
-rw-r--r--source/printing/print_test.c81
-rw-r--r--source/printing/printfsp.c20
-rw-r--r--source/printing/printing.c59
-rw-r--r--source/python/py_smb.c6
-rw-r--r--source/rpc_server/srv_srvsvc_nt.c37
-rw-r--r--source/smbd/blocking.c457
-rw-r--r--source/smbd/close.c4
-rw-r--r--source/smbd/conn.c16
-rw-r--r--source/smbd/dir.c14
-rw-r--r--source/smbd/dosmode.c7
-rw-r--r--source/smbd/error.c62
-rw-r--r--source/smbd/fake_file.c23
-rw-r--r--source/smbd/fileio.c2
-rw-r--r--source/smbd/files.c70
-rw-r--r--source/smbd/lanman.c49
-rw-r--r--source/smbd/message.c3
-rw-r--r--source/smbd/msdfs.c34
-rw-r--r--source/smbd/negprot.c46
-rw-r--r--source/smbd/ntquotas.c2
-rw-r--r--source/smbd/nttrans.c172
-rw-r--r--source/smbd/open.c417
-rw-r--r--source/smbd/oplock_linux.c31
-rw-r--r--source/smbd/password.c19
-rw-r--r--source/smbd/pipes.c17
-rw-r--r--source/smbd/posix_acls.c39
-rw-r--r--source/smbd/process.c85
-rw-r--r--source/smbd/reply.c356
-rw-r--r--source/smbd/server.c119
-rw-r--r--source/smbd/service.c68
-rw-r--r--source/smbd/share_access.c5
-rw-r--r--source/smbd/trans2.c325
-rw-r--r--source/smbd/uid.c6
-rw-r--r--source/smbd/vfs-wrap.c1113
-rw-r--r--source/smbd/vfs.c220
-rw-r--r--source/torture/cmd_vfs.c22
-rw-r--r--source/torture/denytest.c12
-rw-r--r--source/torture/locktest.c22
-rw-r--r--source/torture/locktest2.c1
-rw-r--r--source/torture/mangle_test.c2
-rw-r--r--source/torture/masktest.c10
-rw-r--r--source/torture/nbio.c4
-rw-r--r--source/torture/nsstest.c52
-rw-r--r--source/torture/rpctorture.c2
-rw-r--r--source/torture/scanner.c16
-rw-r--r--source/torture/torture.c442
-rw-r--r--source/torture/utable.c4
-rw-r--r--source/torture/vfstest.c2
-rw-r--r--source/utils/net_sam.c132
-rw-r--r--source/utils/net_time.c10
-rw-r--r--source/utils/status.c397
-rw-r--r--source/web/diagnose.c10
-rw-r--r--source/web/neg_lang.c4
-rw-r--r--source/web/statuspage.c7
117 files changed, 10806 insertions, 8829 deletions
diff --git a/source/Makefile.in b/source/Makefile.in
index eb5cea522fa..5abb7ebbf48 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -386,6 +386,7 @@ OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o
NOTIFY_OBJ = smbd/notify.o smbd/notify_hash.o smbd/notify_kernel.o smbd/notify_fam.o
+VFS_DEFAULT_OBJ = modules/vfs_default.o
VFS_AUDIT_OBJ = modules/vfs_audit.o
VFS_EXTD_AUDIT_OBJ = modules/vfs_extd_audit.o
VFS_FULL_AUDIT_OBJ = modules/vfs_full_audit.o
@@ -406,6 +407,9 @@ VFS_HPUXACL_OBJ = modules/vfs_hpuxacl.o
VFS_IRIXACL_OBJ = modules/vfs_irixacl.o
VFS_TRU64ACL_OBJ = modules/vfs_tru64acl.o
VFS_CATIA_OBJ = modules/vfs_catia.o
+VFS_CACHEPRIME_OBJ = modules/vfs_cacheprime.o
+VFS_PREALLOC_OBJ = modules/vfs_prealloc.o
+VFS_COMMIT_OBJ = modules/vfs_commit.o
VFS_GPFS_OBJ = modules/vfs_gpfs.o modules/gpfs.o
PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
@@ -441,7 +445,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/reply.o smbd/sesssetup.o smbd/trans2.o smbd/uid.o \
smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o \
smbd/blocking.o smbd/sec_ctx.o smbd/srvstr.o \
- smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \
+ smbd/vfs.o smbd/statcache.o \
smbd/posix_acls.o lib/sysacls.o $(SERVER_MUTEX_OBJ) \
smbd/process.o smbd/service.o smbd/error.o \
printing/printfsp.o lib/sysquotas.o lib/sysquotas_linux.o \
@@ -464,7 +468,7 @@ SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/print_aix.o \
printing/print_cups.o printing/print_generic.o \
printing/lpq_parse.o printing/load.o \
- printing/print_iprint.o
+ printing/print_iprint.o printing/print_test.o
PRINTBASE_OBJ = printing/notify.o printing/printing_db.o
PRINTBACKEND_OBJ = printing/printing.o printing/nt_printing.o $(PRINTBASE_OBJ)
diff --git a/source/auth/auth_server.c b/source/auth/auth_server.c
index 7bec1b4128d..7ffea1ca11b 100644
--- a/source/auth/auth_server.c
+++ b/source/auth/auth_server.c
@@ -39,7 +39,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
char *pserver;
BOOL connected_ok = False;
- if (!(cli = cli_initialise(cli)))
+ if (!(cli = cli_initialise()))
return NULL;
/* security = server just can't function with spnego */
@@ -49,7 +49,8 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
p = pserver;
while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) {
- standard_sub_basic(current_user_info.smb_name, desthost, sizeof(desthost));
+ standard_sub_basic(current_user_info.smb_name, current_user_info.domain,
+ desthost, sizeof(desthost));
strupper_m(desthost);
if(!resolve_name( desthost, &dest_ip, 0x20)) {
@@ -85,7 +86,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
return NULL;
}
- if (!attempt_netbios_session_request(cli, global_myname(),
+ if (!attempt_netbios_session_request(&cli, global_myname(),
desthost, &dest_ip)) {
release_server_mutex();
DEBUG(1,("password server fails session request\n"));
@@ -119,8 +120,8 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
this one...
*/
- if (!cli_session_setup(cli, "", "", 0, "", 0,
- "")) {
+ if (!NT_STATUS_IS_OK(cli_session_setup(cli, "", "", 0, "", 0,
+ ""))) {
DEBUG(0,("%s rejected the initial session setup (%s)\n",
desthost, cli_errstr(cli)));
release_server_mutex();
@@ -129,7 +130,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
}
release_server_mutex();
-
+
DEBUG(3,("password server OK\n"));
return cli;
@@ -240,7 +241,7 @@ static NTSTATUS check_smbserver_security(const struct auth_context *auth_context
return nt_status;
}
- cli = my_private_data;
+ cli = (struct cli_state *)my_private_data;
if (cli) {
} else {
@@ -295,8 +296,12 @@ static NTSTATUS check_smbserver_security(const struct auth_context *auth_context
*/
if ((!tested_password_server) && (lp_paranoid_server_security())) {
- if (cli_session_setup(cli, baduser, (char *)badpass, sizeof(badpass),
- (char *)badpass, sizeof(badpass), user_info->domain)) {
+ if (NT_STATUS_IS_OK(cli_session_setup(cli, baduser,
+ (char *)badpass,
+ sizeof(badpass),
+ (char *)badpass,
+ sizeof(badpass),
+ user_info->domain))) {
/*
* We connected to the password server so we
@@ -342,30 +347,25 @@ use this machine as the password server.\n"));
if (!user_info->encrypted) {
/* Plaintext available */
- if (!cli_session_setup(cli, user_info->smb_name,
- (char *)user_info->plaintext_password.data,
- user_info->plaintext_password.length,
- NULL, 0,
- user_info->domain)) {
- DEBUG(1,("password server %s rejected the password\n", cli->desthost));
- /* Make this cli_nt_error() when the conversion is in */
- nt_status = cli_nt_error(cli);
- } else {
- nt_status = NT_STATUS_OK;
- }
+ nt_status = cli_session_setup(
+ cli, user_info->smb_name,
+ (char *)user_info->plaintext_password.data,
+ user_info->plaintext_password.length,
+ NULL, 0, user_info->domain);
+
} else {
- if (!cli_session_setup(cli, user_info->smb_name,
- (char *)user_info->lm_resp.data,
- user_info->lm_resp.length,
- (char *)user_info->nt_resp.data,
- user_info->nt_resp.length,
- user_info->domain)) {
- DEBUG(1,("password server %s rejected the password\n", cli->desthost));
- /* Make this cli_nt_error() when the conversion is in */
- nt_status = cli_nt_error(cli);
- } else {
- nt_status = NT_STATUS_OK;
- }
+ nt_status = cli_session_setup(
+ cli, user_info->smb_name,
+ (char *)user_info->lm_resp.data,
+ user_info->lm_resp.length,
+ (char *)user_info->nt_resp.data,
+ user_info->nt_resp.length,
+ user_info->domain);
+ }
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(1,("password server %s rejected the password: %s\n",
+ cli->desthost, nt_errstr(nt_status)));
}
/* if logged in as guest then reject */
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
index 0fbf672026f..82a13fd9e78 100644
--- a/source/auth/auth_util.c
+++ b/source/auth/auth_util.c
@@ -513,15 +513,9 @@ NT_USER_TOKEN *get_root_nt_token( void )
return token;
}
-static int server_info_dtor(void *p)
+static int server_info_dtor(auth_serversupplied_info *server_info)
{
- auth_serversupplied_info *server_info =
- talloc_get_type_abort(p, auth_serversupplied_info);
-
- if (server_info->sam_account != NULL) {
- TALLOC_FREE(server_info->sam_account);
- }
-
+ TALLOC_FREE(server_info->sam_account);
ZERO_STRUCTP(server_info);
return 0;
}
@@ -633,12 +627,17 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
* Add alias SIDs from memberships within the partially created token SID list
*/
-static NTSTATUS add_aliases(TALLOC_CTX *tmp_ctx, const DOM_SID *domain_sid,
+static NTSTATUS add_aliases(const DOM_SID *domain_sid,
struct nt_user_token *token)
{
uint32 *aliases;
size_t i, num_aliases;
NTSTATUS status;
+ TALLOC_CTX *tmp_ctx;
+
+ if (!(tmp_ctx = talloc_init("add_aliases"))) {
+ return NT_STATUS_NO_MEMORY;
+ }
aliases = NULL;
num_aliases = 0;
@@ -651,6 +650,7 @@ static NTSTATUS add_aliases(TALLOC_CTX *tmp_ctx, const DOM_SID *domain_sid,
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("pdb_enum_alias_memberships failed: %s\n",
nt_errstr(status)));
+ TALLOC_FREE(tmp_ctx);
return status;
}
@@ -662,10 +662,12 @@ static NTSTATUS add_aliases(TALLOC_CTX *tmp_ctx, const DOM_SID *domain_sid,
&token->num_sids);
if (token->user_sids == NULL) {
DEBUG(0, ("add_sid_to_array failed\n"));
+ TALLOC_FREE(tmp_ctx);
return NT_STATUS_NO_MEMORY;
}
}
+ TALLOC_FREE(tmp_ctx);
return NT_STATUS_OK;
}
@@ -708,7 +710,7 @@ static NTSTATUS log_nt_token(TALLOC_CTX *tmp_ctx, NT_USER_TOKEN *token)
/*******************************************************************
*******************************************************************/
-static NTSTATUS add_builtin_administrators( TALLOC_CTX *ctx, struct nt_user_token *token )
+static NTSTATUS add_builtin_administrators( struct nt_user_token *token )
{
DOM_SID domadm;
@@ -829,22 +831,14 @@ static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
int num_groupsids,
const DOM_SID *groupsids)
{
- TALLOC_CTX *tmp_ctx;
struct nt_user_token *result = NULL;
int i;
NTSTATUS status;
gid_t gid;
- tmp_ctx = talloc_new(mem_ctx);
- if (tmp_ctx == NULL) {
- DEBUG(0, ("talloc_new failed\n"));
- return NULL;
- }
-
- result = TALLOC_ZERO_P(tmp_ctx, NT_USER_TOKEN);
- if (result == NULL) {
+ if (!(result = TALLOC_ZERO_P(mem_ctx, NT_USER_TOKEN))) {
DEBUG(0, ("talloc failed\n"));
- goto done;
+ return NULL;
}
/* Add the user and primary group sid */
@@ -902,7 +896,7 @@ static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
unbecome_root();
}
else {
- status = add_builtin_administrators( tmp_ctx, result );
+ status = add_builtin_administrators( result );
if ( !NT_STATUS_IS_OK(status) ) {
/* just log a complaint but do not fail */
DEBUG(3,("create_local_nt_token: failed to check for local Administrators"
@@ -936,31 +930,26 @@ static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
/* Now add the aliases. First the one from our local SAM */
- status = add_aliases(tmp_ctx, get_global_sam_sid(), result);
+ status = add_aliases(get_global_sam_sid(), result);
if (!NT_STATUS_IS_OK(status)) {
- result = NULL;
- goto done;
+ TALLOC_FREE(result);
+ return NULL;
}
/* Finally the builtin ones */
- status = add_aliases(tmp_ctx, &global_sid_Builtin, result);
+ status = add_aliases(&global_sid_Builtin, result);
if (!NT_STATUS_IS_OK(status)) {
- result = NULL;
- goto done;
+ TALLOC_FREE(result);
+ return NULL;
}
}
get_privileges_for_sids(&result->privileges, result->user_sids,
result->num_sids);
-
- talloc_steal(mem_ctx, result);
-
- done:
- TALLOC_FREE(tmp_ctx);
return result;
}
@@ -982,6 +971,12 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info)
return NT_STATUS_NO_MEMORY;
}
+ /*
+ * If winbind is not around, we can not make much use of the SIDs the
+ * domain controller provided us with. Likewise if the user name was
+ * mapped to some local unix user.
+ */
+
if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
(server_info->was_mapped)) {
status = create_token_from_username(server_info,
@@ -1377,7 +1372,7 @@ static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_inf
struct samu *sampass = NULL;
DOM_SID guest_sid;
BOOL ret;
- static const char zeros[16];
+ static const char zeros[16] = { 0, };
if ( !(sampass = samu_new( NULL )) ) {
return NT_STATUS_NO_MEMORY;
@@ -1432,8 +1427,8 @@ static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
dst->gid = src->gid;
dst->n_groups = src->n_groups;
if (src->n_groups != 0) {
- dst->groups = talloc_memdup(dst, src->groups,
- sizeof(gid_t)*dst->n_groups);
+ dst->groups = (gid_t *)talloc_memdup(
+ dst, src->groups, sizeof(gid_t)*dst->n_groups);
} else {
dst->groups = NULL;
}
@@ -1489,6 +1484,66 @@ NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
}
+BOOL copy_current_user(struct current_user *dst, struct current_user *src)
+{
+ gid_t *groups;
+ NT_USER_TOKEN *nt_token;
+
+ groups = (gid_t *)memdup(src->ut.groups,
+ sizeof(gid_t) * src->ut.ngroups);
+ if ((src->ut.ngroups != 0) && (groups == NULL)) {
+ return False;
+ }
+
+ nt_token = dup_nt_token(NULL, src->nt_user_token);
+ if (nt_token == NULL) {
+ SAFE_FREE(groups);
+ return False;
+ }
+
+ dst->conn = src->conn;
+ dst->vuid = src->vuid;
+ dst->ut.uid = src->ut.uid;
+ dst->ut.gid = src->ut.gid;
+ dst->ut.ngroups = src->ut.ngroups;
+ dst->ut.groups = groups;
+ dst->nt_user_token = nt_token;
+ return True;
+}
+
+BOOL set_current_user_guest(struct current_user *dst)
+{
+ gid_t *groups;
+ NT_USER_TOKEN *nt_token;
+
+ groups = (gid_t *)memdup(guest_info->groups,
+ sizeof(gid_t) * guest_info->n_groups);
+ if (groups == NULL) {
+ return False;
+ }
+
+ nt_token = dup_nt_token(NULL, guest_info->ptok);
+ if (nt_token == NULL) {
+ SAFE_FREE(groups);
+ return False;
+ }
+
+ TALLOC_FREE(dst->nt_user_token);
+ SAFE_FREE(dst->ut.groups);
+
+ /* dst->conn is never really dereferenced, it's only tested for
+ * equality in uid.c */
+ dst->conn = NULL;
+
+ dst->vuid = UID_FIELD_INVALID;
+ dst->ut.uid = guest_info->uid;
+ dst->ut.gid = guest_info->gid;
+ dst->ut.ngroups = guest_info->n_groups;
+ dst->ut.groups = groups;
+ dst->nt_user_token = nt_token;
+ return True;
+}
+
/***************************************************************************
Purely internal function for make_server_info_info3
Fill the sam account from getpwnam
@@ -1634,7 +1689,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
auth_serversupplied_info **server_info,
NET_USER_INFO_3 *info3)
{
- static const char zeros[16];
+ static const char zeros[16] = { 0, };
NTSTATUS nt_status = NT_STATUS_OK;
char *found_username;
@@ -1931,8 +1986,8 @@ NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, NT_USER_TOKEN *ptoken)
ZERO_STRUCTP(token);
if (ptoken->user_sids && ptoken->num_sids) {
- token->user_sids = talloc_memdup(token, ptoken->user_sids,
- sizeof(DOM_SID) * ptoken->num_sids );
+ token->user_sids = (DOM_SID *)talloc_memdup(
+ token, ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids );
if (token->user_sids == NULL) {
DEBUG(0, ("talloc_memdup failed\n"));
@@ -1941,7 +1996,7 @@ NT_USER_TOKEN *dup_nt_token(TALLOC_CTX *mem_ctx, NT_USER_TOKEN *ptoken)
}
token->num_sids = ptoken->num_sids;
}
-
+
/* copy the privileges; don't consider failure to be critical here */
if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {
diff --git a/source/client/client.c b/source/client/client.c
index a578608bfff..3b153a7e04c 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -23,6 +23,7 @@
#include "includes.h"
#include "client/client_proto.h"
+#include "include/rpc_client.h"
#ifndef REGISTER
#define REGISTER 0
#endif
@@ -102,7 +103,8 @@ static double dir_total;
struct cli_state *cli;
-
+static char CLI_DIRSEP_CHAR = '\\';
+static char CLI_DIRSEP_STR[] = { '\\', '\0' };
/****************************************************************************
Write to a local file with CR/LF->LF translation if appropriate. Return the
@@ -269,18 +271,18 @@ static int do_cd(char *newdir)
pstrcpy(saved_dir, cur_dir);
- if (*p == '\\')
+ if (*p == CLI_DIRSEP_CHAR)
pstrcpy(cur_dir,p);
else
pstrcat(cur_dir,p);
- if ((cur_dir[0] != '\0') && (*(cur_dir+strlen(cur_dir)-1) != '\\')) {
- pstrcat(cur_dir, "\\");
+ if ((cur_dir[0] != '\0') && (*(cur_dir+strlen(cur_dir)-1) != CLI_DIRSEP_CHAR)) {
+ pstrcat(cur_dir, CLI_DIRSEP_STR);
}
dos_clean_name(cur_dir);
pstrcpy( dname, cur_dir );
- pstrcat(cur_dir,"\\");
+ pstrcat(cur_dir,CLI_DIRSEP_STR);
dos_clean_name(cur_dir);
if ( !cli_resolve_path( "", cli, dname, &targetcli, targetpath ) ) {
@@ -290,7 +292,7 @@ static int do_cd(char *newdir)
}
- if ( strequal(targetpath,"\\" ) )
+ if ( strequal(targetpath,CLI_DIRSEP_STR ) )
return 0;
/* Use a trans2_qpathinfo to test directories for modern servers.
@@ -309,7 +311,7 @@ static int do_cd(char *newdir)
goto out;
}
} else {
- pstrcat( targetpath, "\\" );
+ pstrcat( targetpath, CLI_DIRSEP_STR );
dos_clean_name( targetpath );
if ( !cli_chkpath(targetcli, targetpath) ) {
@@ -384,11 +386,11 @@ static void display_finfo(file_info *finfo)
d_printf(" %-30s%7.7s %8.0f %s",
finfo->name,
attrib_string(finfo->mode),
- (double)finfo->size,
- time_to_asc(&t));
+ (double)finfo->size,
+ time_to_asc(&t));
dir_total += finfo->size;
- } else { /* showacls */
- static pstring afname;
+ } else {
+ pstring afname;
int fnum;
/* skip if this is . or .. */
@@ -406,8 +408,8 @@ static void display_finfo(file_info *finfo)
fnum = cli_nt_create(cli, afname, CREATE_ACCESS_READ);
if (fnum == -1) {
DEBUG( 0, ("display_finfo() Failed to open %s: %s\n",
- afname,
- cli_errstr( cli)));
+ afname,
+ cli_errstr( cli)));
} else {
SEC_DESC *sd = NULL;
sd = cli_query_secdesc(cli, fnum, ctx);
@@ -470,7 +472,7 @@ static void init_do_list_queue(void)
{
reset_do_list_queue();
do_list_queue_size = 1024;
- do_list_queue = SMB_MALLOC(do_list_queue_size);
+ do_list_queue = (char *)SMB_MALLOC(do_list_queue_size);
if (do_list_queue == 0) {
d_printf("malloc fail for size %d\n",
(int)do_list_queue_size);
@@ -514,7 +516,7 @@ static void add_to_do_list_queue(const char* entry)
do_list_queue_size *= 2;
DEBUG(4,("enlarging do_list_queue to %d\n",
(int)do_list_queue_size));
- do_list_queue = SMB_REALLOC(do_list_queue, do_list_queue_size);
+ do_list_queue = (char *)SMB_REALLOC(do_list_queue, do_list_queue_size);
if (! do_list_queue) {
d_printf("failure enlarging do_list_queue to %d bytes\n",
(int)do_list_queue_size);
@@ -563,7 +565,7 @@ static void do_list_helper(const char *mntpoint, file_info *f, const char *mask,
/* save the directory */
pstrcpy( f->dir, mask );
- if ( (dir_end = strrchr( f->dir, '\\' )) != NULL ) {
+ if ( (dir_end = strrchr( f->dir, CLI_DIRSEP_CHAR )) != NULL ) {
*dir_end = '\0';
}
@@ -584,7 +586,7 @@ static void do_list_helper(const char *mntpoint, file_info *f, const char *mask,
pstrcpy(mask2, mntpoint);
pstrcat(mask2, mask);
- p = strrchr_m(mask2,'\\');
+ p = strrchr_m(mask2,CLI_DIRSEP_CHAR);
if (!p)
return;
p[1] = 0;
@@ -651,7 +653,7 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec,
char* save_ch = 0;
if ((strlen(next_file) >= 2) &&
(next_file[strlen(next_file) - 1] == '*') &&
- (next_file[strlen(next_file) - 2] == '\\')) {
+ (next_file[strlen(next_file) - 2] == CLI_DIRSEP_CHAR)) {
save_ch = next_file +
strlen(next_file) - 2;
*save_ch = '\0';
@@ -661,7 +663,7 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec,
if (!showacls) /* don't disturbe the showacls output */
d_printf("\n%s\n",next_file);
if (save_ch) {
- *save_ch = '\\';
+ *save_ch = CLI_DIRSEP_CHAR;
}
}
}
@@ -694,17 +696,17 @@ static int cmd_dir(void)
int rc;
dir_total = 0;
- if (strcmp(cur_dir, "\\") != 0) {
+ if (strcmp(cur_dir, CLI_DIRSEP_STR) != 0) {
pstrcpy(mask,cur_dir);
- if ((mask[0] != '\0') && (mask[strlen(mask)-1]!='\\'))
- pstrcat(mask,"\\");
+ if ((mask[0] != '\0') && (mask[strlen(mask)-1]!=CLI_DIRSEP_CHAR))
+ pstrcat(mask,CLI_DIRSEP_STR);
} else {
- pstrcpy(mask, "\\");
+ pstrcpy(mask, CLI_DIRSEP_STR);
}
if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
dos_format(p);
- if (*p == '\\')
+ if (*p == CLI_DIRSEP_CHAR)
pstrcpy(mask,p + 1);
else
pstrcat(mask,p);
@@ -735,12 +737,12 @@ static int cmd_du(void)
dir_total = 0;
pstrcpy(mask,cur_dir);
- if ((mask[0] != '\0') && (mask[strlen(mask)-1]!='\\'))
- pstrcat(mask,"\\");
+ if ((mask[0] != '\0') && (mask[strlen(mask)-1]!=CLI_DIRSEP_CHAR))
+ pstrcat(mask,CLI_DIRSEP_STR);
if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
dos_format(p);
- if (*p == '\\')
+ if (*p == CLI_DIRSEP_CHAR)
pstrcpy(mask,p);
else
pstrcat(mask,p);
@@ -913,7 +915,7 @@ static int cmd_get(void)
char *p;
pstrcpy(rname,cur_dir);
- pstrcat(rname,"\\");
+ pstrcat(rname,CLI_DIRSEP_STR);
p = rname + strlen(rname);
@@ -969,7 +971,7 @@ static void do_mget(file_info *finfo)
pstrcpy(saved_curdir,cur_dir);
pstrcat(cur_dir,finfo->name);
- pstrcat(cur_dir,"\\");
+ pstrcat(cur_dir,CLI_DIRSEP_STR);
unix_format(finfo->name);
if (lowercase)
@@ -1008,7 +1010,7 @@ static int cmd_more(void)
int rc = 0;
pstrcpy(rname,cur_dir);
- pstrcat(rname,"\\");
+ pstrcat(rname,CLI_DIRSEP_STR);
slprintf(lname,sizeof(lname)-1, "%s/smbmore.XXXXXX",tmpdir());
fd = smb_mkstemp(lname);
@@ -1057,10 +1059,10 @@ static int cmd_mget(void)
while (next_token_nr(NULL,p,NULL,sizeof(buf))) {
pstrcpy(mget_mask,cur_dir);
- if ((mget_mask[0] != '\0') && (mget_mask[strlen(mget_mask)-1]!='\\'))
- pstrcat(mget_mask,"\\");
+ if ((mget_mask[0] != '\0') && (mget_mask[strlen(mget_mask)-1]!=CLI_DIRSEP_CHAR))
+ pstrcat(mget_mask,CLI_DIRSEP_STR);
- if (*p == '\\')
+ if (*p == CLI_DIRSEP_CHAR)
pstrcpy(mget_mask,p);
else
pstrcat(mget_mask,p);
@@ -1069,8 +1071,8 @@ static int cmd_mget(void)
if (!*mget_mask) {
pstrcpy(mget_mask,cur_dir);
- if(mget_mask[strlen(mget_mask)-1]!='\\')
- pstrcat(mget_mask,"\\");
+ if(mget_mask[strlen(mget_mask)-1]!=CLI_DIRSEP_CHAR)
+ pstrcat(mget_mask,CLI_DIRSEP_STR);
pstrcat(mget_mask,"*");
do_list(mget_mask, attribute,do_mget,False,True);
}
@@ -1163,7 +1165,7 @@ static int cmd_mkdir(void)
if (!cli_chkpath(cli, ddir2)) {
do_mkdir(ddir2);
}
- pstrcat(ddir2,"\\");
+ pstrcat(ddir2,CLI_DIRSEP_STR);
p = strtok(NULL,"/\\");
}
} else {
@@ -1343,7 +1345,7 @@ static int cmd_put(void)
char *p=buf;
pstrcpy(rname,cur_dir);
- pstrcat(rname,"\\");
+ pstrcat(rname,CLI_DIRSEP_STR);
if (!next_token_nr(NULL,p,NULL,sizeof(buf))) {
d_printf("put <filename>\n");
@@ -1715,7 +1717,8 @@ static int cmd_open(void)
pstring buf;
struct cli_state *targetcli;
pstring targetname;
-
+ int fnum;
+
pstrcpy(mask,cur_dir);
if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
@@ -1729,7 +1732,169 @@ static int cmd_open(void)
return 1;
}
- cli_nt_create(targetcli, targetname, FILE_READ_DATA);
+ fnum = cli_nt_create(targetcli, targetname, FILE_READ_DATA|FILE_WRITE_DATA);
+ if (fnum == -1) {
+ fnum = cli_nt_create(targetcli, targetname, FILE_READ_DATA);
+ if (fnum != -1) {
+ d_printf("open file %s: for read/write fnum %d\n", targetname, fnum);
+ } else {
+ d_printf("Failed to open file %s. %s\n", targetname, cli_errstr(cli));
+ }
+ } else {
+ d_printf("open file %s: for read/write fnum %d\n", targetname, fnum);
+ }
+
+ return 0;
+}
+
+static int cmd_close(void)
+{
+ fstring buf;
+ int fnum;
+
+ if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ d_printf("close <fnum>\n");
+ return 1;
+ }
+
+ fnum = atoi(buf);
+ /* We really should use the targetcli here.... */
+ if (!cli_close(cli, fnum)) {
+ d_printf("close %d: %s\n", fnum, cli_errstr(cli));
+ return 1;
+ }
+ return 0;
+}
+
+static int cmd_posix(void)
+{
+ uint16 major, minor;
+ uint32 caplow, caphigh;
+ pstring caps;
+
+ if (!SERVER_HAS_UNIX_CIFS(cli)) {
+ d_printf("Server doesn't support UNIX CIFS extensions.\n");
+ return 1;
+ }
+
+ if (!cli_unix_extensions_version(cli, &major, &minor, &caplow, &caphigh)) {
+ d_printf("Can't get UNIX CIFS extensions version from server.\n");
+ return 1;
+ }
+
+ d_printf("Server supports CIFS extensions %u.%u\n", (unsigned int)major, (unsigned int)minor);
+
+ *caps = '\0';
+ if (caplow & CIFS_UNIX_FCNTL_LOCKS_CAP) {
+ pstrcat(caps, "locks ");
+ }
+ if (caplow & CIFS_UNIX_POSIX_ACLS_CAP) {
+ pstrcat(caps, "acls ");
+ }
+ if (caplow & CIFS_UNIX_XATTTR_CAP) {
+ pstrcat(caps, "eas ");
+ }
+ if (caplow & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
+ pstrcat(caps, "pathnames ");
+ }
+
+ if (strlen(caps) > 0 && caps[strlen(caps)-1] == ' ') {
+ caps[strlen(caps)-1] = '\0';
+ }
+
+ if (!cli_set_unix_extensions_capabilities(cli, major, minor, caplow, caphigh)) {
+ d_printf("Can't set UNIX CIFS extensions capabilities. %s.\n", cli_errstr(cli));
+ return 1;
+ }
+
+ d_printf("Selecting server supported CIFS capabilities %s\n", caps);
+
+ if (caplow & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
+ CLI_DIRSEP_CHAR = '/';
+ *CLI_DIRSEP_STR = '/';
+ pstrcpy(cur_dir, CLI_DIRSEP_STR);
+ }
+
+ return 0;
+}
+
+static int cmd_lock(void)
+{
+ fstring buf;
+ SMB_BIG_UINT start, len;
+ enum brl_type lock_type;
+ int fnum;
+
+ if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n");
+ return 1;
+ }
+ fnum = atoi(buf);
+
+ if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n");
+ return 1;
+ }
+
+ if (*buf == 'r' || *buf == 'R') {
+ lock_type = READ_LOCK;
+ } else if (*buf == 'w' || *buf == 'W') {
+ lock_type = WRITE_LOCK;
+ } else {
+ d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n");
+ return 1;
+ }
+
+ if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n");
+ return 1;
+ }
+
+ start = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16);
+
+ if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ d_printf("lock <fnum> [r|w] <hex-start> <hex-len>\n");
+ return 1;
+ }
+
+ len = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16);
+
+ if (!cli_posix_lock(cli, fnum, start, len, True, lock_type)) {
+ d_printf("lock failed %d: %s\n", fnum, cli_errstr(cli));
+ }
+
+ return 0;
+}
+
+static int cmd_unlock(void)
+{
+ fstring buf;
+ SMB_BIG_UINT start, len;
+ int fnum;
+
+ if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ d_printf("unlock <fnum> <hex-start> <hex-len>\n");
+ return 1;
+ }
+ fnum = atoi(buf);
+
+ if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ d_printf("unlock <fnum> <hex-start> <hex-len>\n");
+ return 1;
+ }
+
+ start = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16);
+
+ if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+ d_printf("unlock <fnum> <hex-start> <hex-len>\n");
+ return 1;
+ }
+
+ len = (SMB_BIG_UINT)strtol(buf, (char **)NULL, 16);
+
+ if (!cli_posix_unlock(cli, fnum, start, len)) {
+ d_printf("unlock failed %d: %s\n", fnum, cli_errstr(cli));
+ }
return 0;
}
@@ -2532,7 +2697,7 @@ static int cmd_reget(void)
char *p;
pstrcpy(remote_name, cur_dir);
- pstrcat(remote_name, "\\");
+ pstrcat(remote_name, CLI_DIRSEP_STR);
p = remote_name + strlen(remote_name);
@@ -2561,7 +2726,7 @@ static int cmd_reput(void)
SMB_STRUCT_STAT st;
pstrcpy(remote_name, cur_dir);
- pstrcat(remote_name, "\\");
+ pstrcat(remote_name, CLI_DIRSEP_STR);
if (!next_token_nr(NULL, p, NULL, sizeof(buf))) {
d_printf("reput <filename>\n");
@@ -2622,10 +2787,13 @@ static BOOL browse_host_rpc(BOOL sort)
NTSTATUS status;
struct rpc_pipe_client *pipe_hnd;
TALLOC_CTX *mem_ctx;
- ENUM_HND enum_hnd;
- WERROR werr;
- SRV_SHARE_INFO_CTR ctr;
+ uint32 enum_hnd = 0;
+ uint32 *penum_hnd = &enum_hnd;
+ struct srvsvc_NetShareCtr1 ctr1;
+ union srvsvc_NetShareCtr ctr;
int i;
+ uint32 level;
+ uint32 numentries;
mem_ctx = talloc_new(NULL);
if (mem_ctx == NULL) {
@@ -2633,8 +2801,6 @@ static BOOL browse_host_rpc(BOOL sort)
return False;
}
- init_enum_hnd(&enum_hnd, 0);
-
pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &status);
if (pipe_hnd == NULL) {
@@ -2644,23 +2810,23 @@ static BOOL browse_host_rpc(BOOL sort)
return False;
}
- werr = rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, 1, &ctr,
- 0xffffffff, &enum_hnd);
+ ZERO_STRUCT(ctr1);
+ level = 1;
+ ctr.ctr1 = &ctr1;
+
+ status = rpccli_srvsvc_NetShareEnum(pipe_hnd, mem_ctx, "", &level,
+ &ctr, 0xffffffff, &numentries,
+ &penum_hnd);
- if (!W_ERROR_IS_OK(werr)) {
+ if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(mem_ctx);
cli_rpc_pipe_close(pipe_hnd);
return False;
}
- for (i=0; i<ctr.num_entries; i++) {
- SRV_SHARE_INFO_1 *info = &ctr.share.info1[i];
- char *name, *comment;
- name = rpcstr_pull_unistr2_talloc(
- mem_ctx, &info->info_1_str.uni_netname);
- comment = rpcstr_pull_unistr2_talloc(
- mem_ctx, &info->info_1_str.uni_remark);
- browse_fn(name, info->info_1.type, comment, NULL);
+ for (i=0; i<numentries; i++) {
+ struct srvsvc_NetShareInfo1 *info = &ctr.ctr1->array[i];
+ browse_fn(info->name, info->type, info->comment, NULL);
}
TALLOC_FREE(mem_ctx);
@@ -2777,10 +2943,10 @@ static int cmd_logon(void)
else
pstrcpy(l_password, buf2);
- if (!cli_session_setup(cli, l_username,
- l_password, strlen(l_password),
- l_password, strlen(l_password),
- lp_workgroup())) {
+ if (!NT_STATUS_IS_OK(cli_session_setup(cli, l_username,
+ l_password, strlen(l_password),
+ l_password, strlen(l_password),
+ lp_workgroup()))) {
d_printf("session setup failed: %s\n", cli_errstr(cli));
return -1;
}
@@ -2846,6 +3012,7 @@ static struct
{"cd",cmd_cd,"[directory] change/report the remote directory",{COMPL_REMOTE,COMPL_NONE}},
{"chmod",cmd_chmod,"<src> <mode> chmod a file using UNIX permission",{COMPL_REMOTE,COMPL_REMOTE}},
{"chown",cmd_chown,"<src> <uid> <gid> chown a file using UNIX uids and gids",{COMPL_REMOTE,COMPL_REMOTE}},
+ {"close",cmd_close,"<fid> close a file given a fid",{COMPL_REMOTE,COMPL_REMOTE}},
{"del",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
{"dir",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}},
{"du",cmd_du,"<mask> computes the total size of the current directory",{COMPL_REMOTE,COMPL_NONE}},
@@ -2857,6 +3024,7 @@ static struct
{"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}},
{"lcd",cmd_lcd,"[directory] change/report the local current working directory",{COMPL_LOCAL,COMPL_NONE}},
{"link",cmd_link,"<oldname> <newname> create a UNIX hard link",{COMPL_REMOTE,COMPL_REMOTE}},
+ {"lock",cmd_lock,"lock <fnum> [r|w] <hex-start> <hex-len> : set a POSIX lock",{COMPL_REMOTE,COMPL_REMOTE}},
{"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get",{COMPL_NONE,COMPL_NONE}},
{"ls",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}},
{"mask",cmd_select,"<mask> mask all filenames against this",{COMPL_REMOTE,COMPL_NONE}},
@@ -2867,6 +3035,7 @@ static struct
{"mput",cmd_mput,"<mask> put all matching files",{COMPL_REMOTE,COMPL_NONE}},
{"newer",cmd_newer,"<file> only mget files newer than the specified local file",{COMPL_LOCAL,COMPL_NONE}},
{"open",cmd_open,"<mask> open a file",{COMPL_REMOTE,COMPL_NONE}},
+ {"posix", cmd_posix, "turn on all POSIX capabilities", {COMPL_REMOTE,COMPL_NONE}},
{"print",cmd_print,"<file name> print a file",{COMPL_NONE,COMPL_NONE}},
{"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput",{COMPL_NONE,COMPL_NONE}},
{"put",cmd_put,"<local name> [remote name] put a file",{COMPL_LOCAL,COMPL_REMOTE}},
@@ -2888,6 +3057,7 @@ static struct
{"tar",cmd_tar,"tar <c|x>[IXFqbgNan] current directory to/from <file name>",{COMPL_NONE,COMPL_NONE}},
{"tarmode",cmd_tarmode,"<full|inc|reset|noreset> tar's behaviour towards archive bits",{COMPL_NONE,COMPL_NONE}},
{"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}},
+ {"unlock",cmd_unlock,"unlock <fnum> <hex-start> <hex-len> : remove a POSIX lock",{COMPL_REMOTE,COMPL_REMOTE}},
{"volume",cmd_volume,"print the volume name",{COMPL_NONE,COMPL_NONE}},
{"vuid",cmd_vuid,"change current vuid",{COMPL_NONE,COMPL_NONE}},
{"logon",cmd_logon,"establish new logon",{COMPL_NONE,COMPL_NONE}},
@@ -3068,10 +3238,17 @@ static char **remote_completion(const char *text, int len)
if (!info.matches) {
return NULL;
}
+
+ /*
+ * We're leaving matches[0] free to fill it later with the text to
+ * display: Either the one single match or the longest common subset
+ * of the matches.
+ */
info.matches[0] = NULL;
+ info.count = 1;
for (i = len-1; i >= 0; i--) {
- if ((text[i] == '/') || (text[i] == '\\')) {
+ if ((text[i] == '/') || (text[i] == CLI_DIRSEP_CHAR)) {
break;
}
}
@@ -3090,15 +3267,36 @@ static char **remote_completion(const char *text, int len)
if (cli_list(cli, dirmask, aDIR | aSYSTEM | aHIDDEN, completion_remote_filter, &info) < 0)
goto cleanup;
- if (info.count == 2)
- info.matches[0] = SMB_STRDUP(info.matches[1]);
- else {
- info.matches[0] = SMB_MALLOC(info.samelen+1);
- if (!info.matches[0])
- goto cleanup;
- strncpy(info.matches[0], info.matches[1], info.samelen);
- info.matches[0][info.samelen] = 0;
+ if (info.count == 1) {
+
+ /*
+ * No matches at all, NULL indicates there is nothing
+ */
+
+ SAFE_FREE(info.matches[0]);
+ SAFE_FREE(info.matches);
+ return NULL;
+ }
+
+ if (info.count == 2) {
+
+ /*
+ * Exactly one match in matches[1], indicate this is the one
+ * in matches[0].
+ */
+
+ info.matches[0] = info.matches[1];
+ info.matches[1] = NULL;
+ info.count -= 1;
+ return info.matches;
}
+
+ /*
+ * We got more than one possible match, set the result to the maximum
+ * common subset
+ */
+
+ info.matches[0] = SMB_STRNDUP(info.matches[1], info.samelen);
info.matches[info.count] = NULL;
return info.matches;
@@ -3125,10 +3323,13 @@ static char **completion_fn(const char *text, int start, int end)
sp = strchr(buf, ' ');
if (sp == NULL)
return NULL;
-
- for (i = 0; commands[i].name; i++)
- if ((strncmp(commands[i].name, text, sp - buf) == 0) && (commands[i].name[sp - buf] == 0))
+
+ for (i = 0; commands[i].name; i++) {
+ if ((strncmp(commands[i].name, buf, sp - buf) == 0) &&
+ (commands[i].name[sp - buf] == 0)) {
break;
+ }
+ }
if (commands[i].name == NULL)
return NULL;
@@ -3177,7 +3378,7 @@ static char **completion_fn(const char *text, int start, int end)
matches[0] = SMB_STRDUP(matches[1]);
break;
default:
- matches[0] = SMB_MALLOC(samelen+1);
+ matches[0] = (char *)SMB_MALLOC(samelen+1);
if (!matches[0])
goto cleanup;
strncpy(matches[0], matches[1], samelen);
@@ -3415,7 +3616,7 @@ static int do_message_op(void)
msg_port = port ? port : 139;
- if (!(cli=cli_initialise(NULL)) || (cli_set_port(cli, msg_port) != msg_port) ||
+ if (!(cli=cli_initialise()) || (cli_set_port(cli, msg_port) != msg_port) ||
!cli_connect(cli, server_name, &ip)) {
d_printf("Connection to %s failed\n", desthost);
return 1;
diff --git a/source/client/smbctool.c b/source/client/smbctool.c
index fd385ee6817..b7042f99cb2 100644
--- a/source/client/smbctool.c
+++ b/source/client/smbctool.c
@@ -3494,7 +3494,7 @@ static int do_message_op(void)
msg_port = port ? port : 139;
- if (!(cli=cli_initialise(NULL)) || (cli_set_port(cli, msg_port) != msg_port) ||
+ if (!(cli=cli_initialise()) || (cli_set_port(cli, msg_port) != msg_port) ||
!cli_connect(cli, server_name, &ip)) {
d_printf("Connection to %s failed\n", desthost);
return 1;
diff --git a/source/client/smbmount.c b/source/client/smbmount.c
index 7a3ccb7630d..56b7e9e6234 100644
--- a/source/client/smbmount.c
+++ b/source/client/smbmount.c
@@ -149,7 +149,7 @@ static struct cli_state *do_connection(char *the_service)
if (have_ip) ip = dest_ip;
/* have to open a new connection */
- if (!(c=cli_initialise(NULL)) || (cli_set_port(c, smb_port) != smb_port) ||
+ if (!(c=cli_initialise()) || (cli_set_port(c, smb_port) != smb_port) ||
!cli_connect(c, server_n, &ip)) {
DEBUG(0,("%d: Connection to %s failed\n", sys_getpid(), server_n));
if (c) {
@@ -211,14 +211,14 @@ static struct cli_state *do_connection(char *the_service)
c->force_dos_errors = True;
}
- if (!cli_session_setup(c, username,
- password, strlen(password),
- password, strlen(password),
- workgroup)) {
+ if (!NT_STATUS_IS_OK(cli_session_setup(c, username,
+ password, strlen(password),
+ password, strlen(password),
+ workgroup))) {
/* if a password was not supplied then try again with a
null username */
if (password[0] || !username[0] ||
- !cli_session_setup(c, "", "", 0, "", 0, workgroup)) {
+ !NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0, "", 0, workgroup))) {
DEBUG(0,("%d: session setup failed: %s\n",
sys_getpid(), cli_errstr(c)));
cli_shutdown(c);
diff --git a/source/client/smbspool.c b/source/client/smbspool.c
index c9a7fbe10ef..5783cbe1381 100644
--- a/source/client/smbspool.c
+++ b/source/client/smbspool.c
@@ -429,9 +429,10 @@ static struct cli_state
}
- if (!cli_session_setup(cli, username, password, strlen(password)+1,
- password, strlen(password)+1,
- workgroup))
+ if (!NT_STATUS_IS_OK(cli_session_setup(cli, username,
+ password, strlen(password)+1,
+ password, strlen(password)+1,
+ workgroup)))
{
fprintf(stderr,"ERROR: Session setup failed: %s\n", cli_errstr(cli));
if (NT_STATUS_V(cli_nt_error(cli)) ==
diff --git a/source/include/includes.h b/source/include/includes.h
index ea639d28a9b..1591b1b7d14 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -640,6 +640,7 @@ typedef int BOOL;
#include "debugparse.h"
#include "version.h"
#include "privileges.h"
+#include "locking.h"
#include "smb.h"
#include "ads_cldap.h"
#include "nameserv.h"
diff --git a/source/include/libsmb_internal.h b/source/include/libsmb_internal.h
index 86e98617558..41f72d5fb3d 100644
--- a/source/include/libsmb_internal.h
+++ b/source/include/libsmb_internal.h
@@ -10,7 +10,7 @@
struct _SMBCSRV {
- struct cli_state cli;
+ struct cli_state *cli;
dev_t dev;
BOOL no_pathinfo;
BOOL no_pathinfo2;
diff --git a/source/include/locking.h b/source/include/locking.h
new file mode 100644
index 00000000000..4b3b10d7367
--- /dev/null
+++ b/source/include/locking.h
@@ -0,0 +1,89 @@
+/*
+ Unix SMB/CIFS implementation.
+ SMB parameters and setup, plus a whole lot more.
+
+ Copyright (C) Jeremy Allison 2006
+
+ 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.
+*/
+
+#ifndef _LOCKING_H
+#define _LOCKING_H
+
+/* passed to br lock code - the UNLOCK_LOCK should never be stored into the tdb
+ and is used in calculating POSIX unlock ranges only. We differentiate between
+ PENDING read and write locks to allow posix lock downgrades to trigger a lock
+ re-evaluation. */
+
+enum brl_type {READ_LOCK, WRITE_LOCK, PENDING_READ_LOCK, PENDING_WRITE_LOCK, UNLOCK_LOCK};
+enum brl_flavour {WINDOWS_LOCK = 0, POSIX_LOCK = 1};
+
+#define IS_PENDING_LOCK(type) ((type) == PENDING_READ_LOCK || (type) == PENDING_WRITE_LOCK)
+
+/* This contains elements that differentiate locks. The smbpid is a
+ client supplied pid, and is essentially the locking context for
+ this client */
+
+struct lock_context {
+ uint32 smbpid;
+ uint16 tid;
+ struct process_id pid;
+};
+
+/* The key used in the brlock database. */
+
+struct lock_key {
+ SMB_DEV_T device;
+ SMB_INO_T inode;
+};
+
+struct files_struct;
+
+struct byte_range_lock {
+ struct files_struct *fsp;
+ unsigned int num_locks;
+ BOOL modified;
+ BOOL read_only;
+ struct lock_key key;
+ void *lock_data;
+};
+
+#define BRLOCK_FN_CAST() \
+ void (*)(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, \
+ enum brl_type lock_type, \
+ enum brl_flavour lock_flav, \
+ br_off start, br_off size)
+
+#define BRLOCK_FN(fn) \
+ void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, \
+ enum brl_type lock_type, \
+ enum brl_flavour lock_flav, \
+ br_off start, br_off size)
+
+/* Internal structure in brlock.tdb.
+ The data in brlock records is an unsorted linear array of these
+ records. It is unnecessary to store the count as tdb provides the
+ size of the record */
+
+struct lock_struct {
+ struct lock_context context;
+ br_off start;
+ br_off size;
+ uint16 fnum;
+ enum brl_type lock_type;
+ enum brl_flavour lock_flav;
+};
+
+#endif /* _LOCKING_H_ */
diff --git a/source/include/nt_status.h b/source/include/nt_status.h
index f57ddf6b3dc..968657ca44f 100644
--- a/source/include/nt_status.h
+++ b/source/include/nt_status.h
@@ -56,7 +56,6 @@ typedef uint32 WERROR;
#define NT_STATUS_IS_OK(x) (NT_STATUS_V(x) == 0)
#define NT_STATUS_IS_ERR(x) ((NT_STATUS_V(x) & 0xc0000000) == 0xc0000000)
-#define NT_STATUS_IS_INVALID(x) (NT_STATUS_V(x) == 0xFFFFFFFF)
#define NT_STATUS_EQUAL(x,y) (NT_STATUS_V(x) == NT_STATUS_V(y))
#define W_ERROR_IS_OK(x) (W_ERROR_V(x) == 0)
#define W_ERROR_EQUAL(x,y) (W_ERROR_V(x) == W_ERROR_V(y))
diff --git a/source/include/nterr.h b/source/include/nterr.h
index 417719625e7..b6db14817d4 100644
--- a/source/include/nterr.h
+++ b/source/include/nterr.h
@@ -37,9 +37,6 @@
#define STATUS_NOTIFY_ENUM_DIR NT_STATUS(0x010c)
#define ERROR_INVALID_DATATYPE NT_STATUS(0x070c)
-/* Special "invalid" NT status code. */
-#define NT_STATUS_INVALID NT_STATUS(0xFFFFFFFF)
-
/* Win32 Error codes extracted using a loop in smbclient then printing a
netmon sniff to a file. */
@@ -564,5 +561,6 @@
#define NT_STATUS_FILE_IS_OFFLINE NT_STATUS(0xC0000000 | 0x0267)
#define NT_STATUS_NOT_A_REPARSE_POINT NT_STATUS(0xC0000000 | 0x0275)
#define NT_STATUS_NO_SUCH_JOB NT_STATUS(0xC0000000 | 0xEDE) /* scheduler */
+#define NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x20004)
#endif /* _NTERR_H */
diff --git a/source/include/printing.h b/source/include/printing.h
index 54f32d5954c..21caff0a832 100644
--- a/source/include/printing.h
+++ b/source/include/printing.h
@@ -73,6 +73,10 @@ extern struct printif cups_printif;
extern struct printif iprint_printif;
#endif /* HAVE_IPRINT */
+#if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
+extern struct printif test_printif;
+#endif /* DEVELOPER||ENABLE_BUILD_FARM_HACKS */
+
/* PRINT_MAX_JOBID is now defined in local.h */
#define UNIX_JOB_START PRINT_MAX_JOBID
#define NEXT_JOBID(j) ((j+1) % PRINT_MAX_JOBID > 0 ? (j+1) % PRINT_MAX_JOBID : 1)
diff --git a/source/include/reg_objects.h b/source/include/reg_objects.h
index fff6fa16f79..1f819df999b 100644
--- a/source/include/reg_objects.h
+++ b/source/include/reg_objects.h
@@ -1,7 +1,8 @@
/*
- Unix SMB/CIFS implementation.
+ Samba's Internal Registry objects
+
SMB parameters and setup
- Copyright (C) Gerald Carter 2002-2005.
+ Copyright (C) Gerald Carter 2002-2006.
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
diff --git a/source/include/rpc_misc.h b/source/include/rpc_misc.h
index 0ee63ae7e18..7404f5669d2 100644
--- a/source/include/rpc_misc.h
+++ b/source/include/rpc_misc.h
@@ -339,10 +339,5 @@ typedef struct owf_info {
uint8 data[16];
} OWF_INFO;
-typedef struct uint64_s
-{
- uint32 low;
- uint32 high;
-} UINT64_S;
#endif /* _RPC_MISC_H */
diff --git a/source/include/smb.h b/source/include/smb.h
index 4dd6028509c..15006c239f3 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -406,6 +406,15 @@ struct fd_handle {
struct timed_event;
struct idle_event;
struct share_mode_entry;
+struct uuid;
+
+struct vfs_fsp_data {
+ struct vfs_fsp_data *next;
+ struct vfs_handle_struct *owner;
+ /* NOTE: This structure contains two pointers so that we can guarantee
+ * that the end of the structure is always both 4-byte and 8-byte aligned.
+ */
+};
typedef struct files_struct {
struct files_struct *next, *prev;
@@ -431,6 +440,7 @@ typedef struct files_struct {
int oplock_type;
int sent_oplock_break;
struct timed_event *oplock_timeout;
+ struct lock_struct last_lock_failure;
struct share_mode_entry *pending_break_messages;
int num_pending_break_messages;
@@ -445,6 +455,8 @@ typedef struct files_struct {
BOOL aio_write_behind;
BOOL lockdb_clean;
char *fsp_name;
+
+ struct vfs_fsp_data *vfs_extension;
FAKE_FILE_HANDLE *fake_file_handle;
} files_struct;
@@ -516,6 +528,8 @@ struct trans_state {
/* Include VFS stuff */
+struct security_descriptor_info;
+
#include "smb_acls.h"
#include "vfs.h"
@@ -850,54 +864,11 @@ struct parm_struct {
#define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */
#define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */
-/* passed to br lock code - the UNLOCK_LOCK should never be stored into the tdb
- and is used in calculating POSIX unlock ranges only. */
-
-enum brl_type {READ_LOCK, WRITE_LOCK, PENDING_LOCK, UNLOCK_LOCK};
-enum brl_flavour {WINDOWS_LOCK = 0, POSIX_LOCK = 1};
-
-/* The key used in the brlock database. */
-
-struct lock_key {
- SMB_DEV_T device;
- SMB_INO_T inode;
-};
-
-struct byte_range_lock {
- files_struct *fsp;
- unsigned int num_locks;
- BOOL modified;
- struct lock_key key;
- void *lock_data;
-};
-
-#define BRLOCK_FN_CAST() \
- void (*)(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, \
- enum brl_type lock_type, \
- enum brl_flavour lock_flav, \
- br_off start, br_off size)
-
-#define BRLOCK_FN(fn) \
- void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid, \
- enum brl_type lock_type, \
- enum brl_flavour lock_flav, \
- br_off start, br_off size)
-
-#define LOCKING_FN_CAST() \
- void (*)(struct share_mode_entry *, const char *, const char *)
-
-#define LOCKING_FN(fn) \
- void (*fn)(struct share_mode_entry *, const char *, const char *)
-
struct bitmap {
uint32 *b;
unsigned int n;
};
-#ifndef LOCKING_VERSION
-#define LOCKING_VERSION 4
-#endif /* LOCKING_VERSION */
-
/* the basic packet size, assuming no words or bytes */
#define smb_size 39
@@ -1497,7 +1468,7 @@ enum server_types {
enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX,
PRINT_QNX,PRINT_PLP,PRINT_LPRNG,PRINT_SOFTQ,
PRINT_CUPS,PRINT_LPRNT,PRINT_LPROS2,PRINT_IPRINT
-#ifdef DEVELOPER
+#if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
,PRINT_TEST,PRINT_VLP
#endif /* DEVELOPER */
};
diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h
index b9c51002fa5..44f15734d9a 100644
--- a/source/include/smb_macros.h
+++ b/source/include/smb_macros.h
@@ -83,8 +83,6 @@
#define SMB_ASSERT_ARRAY(a,n) SMB_ASSERT((sizeof(a)/sizeof((a)[0])) >= (n))
/* these are useful macros for checking validity of handles */
-#define OPEN_FSP(fsp) ((fsp) && !(fsp)->is_directory)
-#define OPEN_CONN(conn) ((conn) && (conn)->open)
#define IS_IPC(conn) ((conn) && (conn)->ipc)
#define IS_PRINT(conn) ((conn) && (conn)->printer)
/* you must add the following extern declaration to files using this macro
@@ -93,20 +91,24 @@
#define FSP_BELONGS_CONN(fsp,conn) do {\
extern struct current_user current_user;\
if (!((fsp) && (conn) && ((conn)==(fsp)->conn) && (current_user.vuid==(fsp)->vuid))) \
- return(ERROR_DOS(ERRDOS,ERRbadfid));\
+ return ERROR_NT(NT_STATUS_INVALID_HANDLE); \
} while(0)
-#define FNUM_OK(fsp,c) (OPEN_FSP(fsp) && (c)==(fsp)->conn && current_user.vuid==(fsp)->vuid)
+#define FNUM_OK(fsp,c) ((fsp) && !(fsp)->is_directory && (c)==(fsp)->conn && current_user.vuid==(fsp)->vuid)
/* you must add the following extern declaration to files using this macro
* extern struct current_user current_user;
*/
#define CHECK_FSP(fsp,conn) do {\
extern struct current_user current_user;\
- if (!FNUM_OK(fsp,conn)) \
- return(ERROR_DOS(ERRDOS,ERRbadfid)); \
- else if((fsp)->fh->fd == -1) \
- return(ERROR_DOS(ERRDOS,ERRbadaccess));\
+ if (!(fsp) || !(conn)) \
+ return ERROR_NT(NT_STATUS_INVALID_HANDLE); \
+ else if (((conn) != (fsp)->conn) || current_user.vuid != (fsp)->vuid) \
+ return ERROR_NT(NT_STATUS_INVALID_HANDLE); \
+ else if ((fsp)->is_directory) \
+ return ERROR_NT(NT_STATUS_INVALID_DEVICE_REQUEST); \
+ else if ((fsp)->fh->fd == -1) \
+ return ERROR_NT(NT_STATUS_ACCESS_DENIED); \
(fsp)->num_smb_operations++;\
} while(0)
@@ -182,7 +184,6 @@
#define CACHED_ERROR(fsp) cached_error_packet(outbuf,fsp,__LINE__,__FILE__)
#define ERROR_DOS(class,code) error_packet(outbuf,class,code,NT_STATUS_OK,__LINE__,__FILE__)
-#define ERROR_FORCE_DOS(class,code) error_packet(outbuf,class,code,NT_STATUS_INVALID,__LINE__,__FILE__)
#define ERROR_NT(status) error_packet(outbuf,0,0,status,__LINE__,__FILE__)
#define ERROR_FORCE_NT(status) error_packet(outbuf,-1,-1,status,__LINE__,__FILE__)
#define ERROR_BOTH(status,class,code) error_packet(outbuf,class,code,status,__LINE__,__FILE__)
@@ -284,7 +285,7 @@ copy an IP address from one buffer to another
#define SMB_XMALLOC_ARRAY(type,count) (type *)smb_xmalloc_array(sizeof(type),(count))
/* limiting size of ipc replies */
-#define SMB_REALLOC_LIMIT(ptr,size) SMB_REALLOC(ptr,MAX((size),4*1024))
+#define SMB_REALLOC_LIMIT(ptr,size) (char *)SMB_REALLOC(ptr,MAX((size),4*1024))
/* The new talloc is paranoid malloc checker safe. */
@@ -377,6 +378,6 @@ do { \
} while (0)
#define ADD_TO_LARGE_ARRAY(mem_ctx, type, elem, array, num, size) \
- add_to_large_array((mem_ctx), sizeof(type), &(elem), (void **)(array), (num), (size));
+ add_to_large_array((mem_ctx), sizeof(type), &(elem), (void *)(array), (num), (size));
#endif /* _SMB_MACROS_H */
diff --git a/source/include/vfs.h b/source/include/vfs.h
index 16d1428779d..fe4886567ff 100644
--- a/source/include/vfs.h
+++ b/source/include/vfs.h
@@ -62,8 +62,10 @@
/* Changed to version 14 as we had to change DIR to SMB_STRUCT_DIR. JRA */
/* Changed to version 15 as we added the statvfs call. JRA */
/* Changed to version 16 as we added the getlock call. JRA */
-/* Changed to version 17 to add kernel_flock call. Note in 3.0 dev branch it's different - jmcd */
-#define SMB_VFS_INTERFACE_VERSION 17
+/* Changed to version 17 as we removed redundant connection_struct parameters. --jpeach */
+/* Changed to version 18 to add fsp parameter to the open call -- jpeach
+ Also include kernel_flock call - jmcd */
+#define SMB_VFS_INTERFACE_VERSION 18
/* to bug old modules which are trying to compile with the old functions */
@@ -84,7 +86,7 @@
struct vfs_handle_struct;
struct connection_struct;
struct files_struct;
-struct security_descriptor_info;
+struct security_descriptor;
struct vfs_statvfs_struct;
/*
@@ -221,29 +223,29 @@ struct vfs_ops {
struct vfs_fn_pointers {
/* Disk operations */
- int (*connect_fn)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *service, const char *user);
- void (*disconnect)(struct vfs_handle_struct *handle, struct connection_struct *conn);
- SMB_BIG_UINT (*disk_free)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize,
+ int (*connect_fn)(struct vfs_handle_struct *handle, const char *service, const char *user);
+ void (*disconnect)(struct vfs_handle_struct *handle);
+ SMB_BIG_UINT (*disk_free)(struct vfs_handle_struct *handle, const char *path, BOOL small_query, SMB_BIG_UINT *bsize,
SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
- int (*get_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
- int (*set_quota)(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
+ int (*get_quota)(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
+ int (*set_quota)(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt);
int (*get_shadow_copy_data)(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels);
- int (*statvfs)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, struct vfs_statvfs_struct *statbuf);
+ int (*statvfs)(struct vfs_handle_struct *handle, const char *path, struct vfs_statvfs_struct *statbuf);
/* Directory operations */
- SMB_STRUCT_DIR *(*opendir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, const char *mask, uint32 attributes);
- SMB_STRUCT_DIRENT *(*readdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *dirp);
- void (*seekdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *dirp, long offset);
- long (*telldir)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *dirp);
- void (*rewind_dir)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *dirp);
- int (*mkdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode);
- int (*rmdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
- int (*closedir)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *dir);
+ SMB_STRUCT_DIR *(*opendir)(struct vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attributes);
+ SMB_STRUCT_DIRENT *(*readdir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp);
+ void (*seekdir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, long offset);
+ long (*telldir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp);
+ void (*rewind_dir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp);
+ int (*mkdir)(struct vfs_handle_struct *handle, const char *path, mode_t mode);
+ int (*rmdir)(struct vfs_handle_struct *handle, const char *path);
+ int (*closedir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dir);
/* File operations */
- int (*open)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, int flags, mode_t mode);
+ int (*open)(struct vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode);
int (*close_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd);
ssize_t (*read)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n);
ssize_t (*pread)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, void *data, size_t n, SMB_OFF_T offset);
@@ -251,28 +253,28 @@ struct vfs_ops {
ssize_t (*pwrite)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, const void *data, size_t n, SMB_OFF_T offset);
SMB_OFF_T (*lseek)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset, int whence);
ssize_t (*sendfile)(struct vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *header, SMB_OFF_T offset, size_t count);
- int (*rename)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldname, const char *newname);
+ int (*rename)(struct vfs_handle_struct *handle, const char *oldname, const char *newname);
int (*fsync)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd);
- int (*stat)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf);
+ int (*stat)(struct vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf);
int (*fstat)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf);
- int (*lstat)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf);
- int (*unlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
- int (*chmod)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode);
+ int (*lstat)(struct vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf);
+ int (*unlink)(struct vfs_handle_struct *handle, const char *path);
+ int (*chmod)(struct vfs_handle_struct *handle, const char *path, mode_t mode);
int (*fchmod)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, mode_t mode);
- int (*chown)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, uid_t uid, gid_t gid);
+ int (*chown)(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid);
int (*fchown)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uid_t uid, gid_t gid);
- int (*chdir)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
- char *(*getwd)(struct vfs_handle_struct *handle, struct connection_struct *conn, char *buf);
- int (*utime)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, struct utimbuf *times);
+ int (*chdir)(struct vfs_handle_struct *handle, const char *path);
+ char *(*getwd)(struct vfs_handle_struct *handle, char *buf);
+ int (*utime)(struct vfs_handle_struct *handle, const char *path, struct utimbuf *times);
int (*ftruncate)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T offset);
BOOL (*lock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
int (*kernel_flock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 share_mode);
BOOL (*getlock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid);
- int (*symlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldpath, const char *newpath);
- int (*readlink)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, char *buf, size_t bufsiz);
- int (*link)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldpath, const char *newpath);
- int (*mknod)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev);
- char *(*realpath)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, char *resolved_path);
+ int (*symlink)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath);
+ int (*readlink)(struct vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz);
+ int (*link)(struct vfs_handle_struct *handle, const char *oldpath, const char *newpath);
+ int (*mknod)(struct vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev);
+ char *(*realpath)(struct vfs_handle_struct *handle, const char *path, char *resolved_path);
/* NT ACL operations. */
@@ -283,44 +285,44 @@ struct vfs_ops {
/* POSIX ACL operations. */
- int (*chmod_acl)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *name, mode_t mode);
+ int (*chmod_acl)(struct vfs_handle_struct *handle, const char *name, mode_t mode);
int (*fchmod_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, mode_t mode);
- int (*sys_acl_get_entry)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
- int (*sys_acl_get_tag_type)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
- int (*sys_acl_get_permset)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
- void * (*sys_acl_get_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d);
- SMB_ACL_T (*sys_acl_get_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type);
+ int (*sys_acl_get_entry)(struct vfs_handle_struct *handle, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
+ int (*sys_acl_get_tag_type)(struct vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
+ int (*sys_acl_get_permset)(struct vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p);
+ void * (*sys_acl_get_qualifier)(struct vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d);
+ SMB_ACL_T (*sys_acl_get_file)(struct vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type);
SMB_ACL_T (*sys_acl_get_fd)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd);
- int (*sys_acl_clear_perms)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset);
- int (*sys_acl_add_perm)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
- char * (*sys_acl_to_text)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen);
- SMB_ACL_T (*sys_acl_init)(struct vfs_handle_struct *handle, struct connection_struct *conn, int count);
- int (*sys_acl_create_entry)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry);
- int (*sys_acl_set_tag_type)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype);
- int (*sys_acl_set_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual);
- int (*sys_acl_set_permset)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset);
- int (*sys_acl_valid)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T theacl );
- int (*sys_acl_set_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
+ int (*sys_acl_clear_perms)(struct vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset);
+ int (*sys_acl_add_perm)(struct vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+ char * (*sys_acl_to_text)(struct vfs_handle_struct *handle, SMB_ACL_T theacl, ssize_t *plen);
+ SMB_ACL_T (*sys_acl_init)(struct vfs_handle_struct *handle, int count);
+ int (*sys_acl_create_entry)(struct vfs_handle_struct *handle, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry);
+ int (*sys_acl_set_tag_type)(struct vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype);
+ int (*sys_acl_set_qualifier)(struct vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, void *qual);
+ int (*sys_acl_set_permset)(struct vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset);
+ int (*sys_acl_valid)(struct vfs_handle_struct *handle, SMB_ACL_T theacl );
+ int (*sys_acl_set_file)(struct vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
int (*sys_acl_set_fd)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_ACL_T theacl);
- int (*sys_acl_delete_def_file)(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path);
- int (*sys_acl_get_perm)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
- int (*sys_acl_free_text)(struct vfs_handle_struct *handle, struct connection_struct *conn, char *text);
- int (*sys_acl_free_acl)(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_ACL_T posix_acl);
- int (*sys_acl_free_qualifier)(struct vfs_handle_struct *handle, struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype);
+ int (*sys_acl_delete_def_file)(struct vfs_handle_struct *handle, const char *path);
+ int (*sys_acl_get_perm)(struct vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm);
+ int (*sys_acl_free_text)(struct vfs_handle_struct *handle, char *text);
+ int (*sys_acl_free_acl)(struct vfs_handle_struct *handle, SMB_ACL_T posix_acl);
+ int (*sys_acl_free_qualifier)(struct vfs_handle_struct *handle, void *qualifier, SMB_ACL_TAG_T tagtype);
/* EA operations. */
- ssize_t (*getxattr)(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size);
- ssize_t (*lgetxattr)(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size);
+ ssize_t (*getxattr)(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size);
+ ssize_t (*lgetxattr)(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size);
ssize_t (*fgetxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size);
- ssize_t (*listxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size);
- ssize_t (*llistxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size);
+ ssize_t (*listxattr)(struct vfs_handle_struct *handle, const char *path, char *list, size_t size);
+ ssize_t (*llistxattr)(struct vfs_handle_struct *handle, const char *path, char *list, size_t size);
ssize_t (*flistxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size);
- int (*removexattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name);
- int (*lremovexattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name);
+ int (*removexattr)(struct vfs_handle_struct *handle, const char *path, const char *name);
+ int (*lremovexattr)(struct vfs_handle_struct *handle, const char *path, const char *name);
int (*fremovexattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int filedes, const char *name);
- int (*setxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags);
- int (*lsetxattr)(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags);
+ int (*setxattr)(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags);
+ int (*lsetxattr)(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags);
int (*fsetxattr)(struct vfs_handle_struct *handle, struct files_struct *fsp,int filedes, const char *name, const void *value, size_t size, int flags);
/* aio operations */
@@ -534,6 +536,14 @@ typedef struct vfs_statvfs_struct {
/* NB flags can come from FILE_SYSTEM_DEVICE_INFO call */
} vfs_statvfs_struct;
+#define VFS_ADD_FSP_EXTENSION(handle, fsp, type) \
+ vfs_add_fsp_extension_notype(handle, (fsp), sizeof(type))
+
+#define VFS_FETCH_FSP_EXTENSION(handle, fsp) \
+ vfs_fetch_fsp_extension(handle, (fsp))
+
+#define VFS_REMOVE_FSP_EXTENSION(handle, fsp) \
+ vfs_remove_fsp_extension((handle), (fsp))
#define SMB_VFS_HANDLE_GET_DATA(handle, datap, type, ret) { \
if (!(handle)||((datap=(type *)(handle)->data)==NULL)) { \
@@ -566,6 +576,7 @@ typedef struct vfs_statvfs_struct {
#define SMB_VFS_OP(x) ((void *) x)
+#define DEFAULT_VFS_MODULE_NAME "/[Default VFS]/"
#include "vfs_macros.h"
diff --git a/source/include/vfs_macros.h b/source/include/vfs_macros.h
index 843dd89ce7a..119b616e72e 100644
--- a/source/include/vfs_macros.h
+++ b/source/include/vfs_macros.h
@@ -28,26 +28,26 @@
********************************************************************/
/* Disk operations */
-#define SMB_VFS_CONNECT(conn, service, user) ((conn)->vfs.ops.connect_fn((conn)->vfs.handles.connect_hnd, (conn), (service), (user)))
-#define SMB_VFS_DISCONNECT(conn) ((conn)->vfs.ops.disconnect((conn)->vfs.handles.disconnect, (conn)))
-#define SMB_VFS_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs.ops.disk_free((conn)->vfs.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize)))
-#define SMB_VFS_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.get_quota((conn)->vfs.handles.get_quota, (conn), (qtype), (id), (qt)))
-#define SMB_VFS_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.set_quota((conn)->vfs.handles.set_quota, (conn), (qtype), (id), (qt)))
+#define SMB_VFS_CONNECT(conn, service, user) ((conn)->vfs.ops.connect_fn((conn)->vfs.handles.connect_hnd, (service), (user)))
+#define SMB_VFS_DISCONNECT(conn) ((conn)->vfs.ops.disconnect((conn)->vfs.handles.disconnect))
+#define SMB_VFS_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs.ops.disk_free((conn)->vfs.handles.disk_free, (path), (small_query), (bsize), (dfree), (dsize)))
+#define SMB_VFS_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.get_quota((conn)->vfs.handles.get_quota, (qtype), (id), (qt)))
+#define SMB_VFS_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs.ops.set_quota((conn)->vfs.handles.set_quota, (qtype), (id), (qt)))
#define SMB_VFS_GET_SHADOW_COPY_DATA(fsp,shadow_copy_data,labels) ((fsp)->conn->vfs.ops.get_shadow_copy_data((fsp)->conn->vfs.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
-#define SMB_VFS_STATVFS(conn, path, statbuf) ((conn)->vfs.ops.statvfs((conn)->vfs.handles.statvfs, (conn), (path), (statbuf)))
+#define SMB_VFS_STATVFS(conn, path, statbuf) ((conn)->vfs.ops.statvfs((conn)->vfs.handles.statvfs, (path), (statbuf)))
/* Directory operations */
-#define SMB_VFS_OPENDIR(conn, fname, mask, attr) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (conn), (fname), (mask), (attr)))
-#define SMB_VFS_READDIR(conn, dirp) ((conn)->vfs.ops.readdir((conn)->vfs.handles.readdir, (conn), (dirp)))
-#define SMB_VFS_SEEKDIR(conn, dirp, offset) ((conn)->vfs.ops.seekdir((conn)->vfs.handles.seekdir, (conn), (dirp), (offset)))
-#define SMB_VFS_TELLDIR(conn, dirp) ((conn)->vfs.ops.telldir((conn)->vfs.handles.telldir, (conn), (dirp)))
-#define SMB_VFS_REWINDDIR(conn, dirp) ((conn)->vfs.ops.rewind_dir((conn)->vfs.handles.rewind_dir, (conn), (dirp)))
-#define SMB_VFS_MKDIR(conn, path, mode) ((conn)->vfs.ops.mkdir((conn)->vfs.handles.mkdir,(conn), (path), (mode)))
-#define SMB_VFS_RMDIR(conn, path) ((conn)->vfs.ops.rmdir((conn)->vfs.handles.rmdir, (conn), (path)))
-#define SMB_VFS_CLOSEDIR(conn, dir) ((conn)->vfs.ops.closedir((conn)->vfs.handles.closedir, (conn), dir))
+#define SMB_VFS_OPENDIR(conn, fname, mask, attr) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (fname), (mask), (attr)))
+#define SMB_VFS_READDIR(conn, dirp) ((conn)->vfs.ops.readdir((conn)->vfs.handles.readdir, (dirp)))
+#define SMB_VFS_SEEKDIR(conn, dirp, offset) ((conn)->vfs.ops.seekdir((conn)->vfs.handles.seekdir, (dirp), (offset)))
+#define SMB_VFS_TELLDIR(conn, dirp) ((conn)->vfs.ops.telldir((conn)->vfs.handles.telldir, (dirp)))
+#define SMB_VFS_REWINDDIR(conn, dirp) ((conn)->vfs.ops.rewind_dir((conn)->vfs.handles.rewind_dir, (dirp)))
+#define SMB_VFS_MKDIR(conn, path, mode) ((conn)->vfs.ops.mkdir((conn)->vfs.handles.mkdir,(path), (mode)))
+#define SMB_VFS_RMDIR(conn, path) ((conn)->vfs.ops.rmdir((conn)->vfs.handles.rmdir, (path)))
+#define SMB_VFS_CLOSEDIR(conn, dir) ((conn)->vfs.ops.closedir((conn)->vfs.handles.closedir, dir))
/* File operations */
-#define SMB_VFS_OPEN(conn, fname, flags, mode) ((conn)->vfs.ops.open((conn)->vfs.handles.open, (conn), (fname), (flags), (mode)))
+#define SMB_VFS_OPEN(conn, fname, fsp, flags, mode) ((conn)->vfs.ops.open((conn)->vfs.handles.open, (fname), (fsp), (flags), (mode)))
#define SMB_VFS_CLOSE(fsp, fd) ((fsp)->conn->vfs.ops.close_fn((fsp)->conn->vfs.handles.close_hnd, (fsp), (fd)))
#define SMB_VFS_READ(fsp, fd, data, n) ((fsp)->conn->vfs.ops.read((fsp)->conn->vfs.handles.read, (fsp), (fd), (data), (n)))
#define SMB_VFS_PREAD(fsp, fd, data, n, off) ((fsp)->conn->vfs.ops.pread((fsp)->conn->vfs.handles.pread, (fsp), (fd), (data), (n), (off)))
@@ -55,28 +55,28 @@
#define SMB_VFS_PWRITE(fsp, fd, data, n, off) ((fsp)->conn->vfs.ops.pwrite((fsp)->conn->vfs.handles.pwrite, (fsp), (fd), (data), (n), (off)))
#define SMB_VFS_LSEEK(fsp, fd, offset, whence) ((fsp)->conn->vfs.ops.lseek((fsp)->conn->vfs.handles.lseek, (fsp), (fd), (offset), (whence)))
#define SMB_VFS_SENDFILE(tofd, fsp, fromfd, header, offset, count) ((fsp)->conn->vfs.ops.sendfile((fsp)->conn->vfs.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count)))
-#define SMB_VFS_RENAME(conn, old, new) ((conn)->vfs.ops.rename((conn)->vfs.handles.rename, (conn), (old), (new)))
+#define SMB_VFS_RENAME(conn, old, new) ((conn)->vfs.ops.rename((conn)->vfs.handles.rename, (old), (new)))
#define SMB_VFS_FSYNC(fsp, fd) ((fsp)->conn->vfs.ops.fsync((fsp)->conn->vfs.handles.fsync, (fsp), (fd)))
-#define SMB_VFS_STAT(conn, fname, sbuf) ((conn)->vfs.ops.stat((conn)->vfs.handles.stat, (conn), (fname), (sbuf)))
+#define SMB_VFS_STAT(conn, fname, sbuf) ((conn)->vfs.ops.stat((conn)->vfs.handles.stat, (fname), (sbuf)))
#define SMB_VFS_FSTAT(fsp, fd, sbuf) ((fsp)->conn->vfs.ops.fstat((fsp)->conn->vfs.handles.fstat, (fsp) ,(fd) ,(sbuf)))
-#define SMB_VFS_LSTAT(conn, path, sbuf) ((conn)->vfs.ops.lstat((conn)->vfs.handles.lstat, (conn), (path), (sbuf)))
-#define SMB_VFS_UNLINK(conn, path) ((conn)->vfs.ops.unlink((conn)->vfs.handles.unlink, (conn), (path)))
-#define SMB_VFS_CHMOD(conn, path, mode) ((conn)->vfs.ops.chmod((conn)->vfs.handles.chmod, (conn), (path), (mode)))
+#define SMB_VFS_LSTAT(conn, path, sbuf) ((conn)->vfs.ops.lstat((conn)->vfs.handles.lstat, (path), (sbuf)))
+#define SMB_VFS_UNLINK(conn, path) ((conn)->vfs.ops.unlink((conn)->vfs.handles.unlink, (path)))
+#define SMB_VFS_CHMOD(conn, path, mode) ((conn)->vfs.ops.chmod((conn)->vfs.handles.chmod, (path), (mode)))
#define SMB_VFS_FCHMOD(fsp, fd, mode) ((fsp)->conn->vfs.ops.fchmod((fsp)->conn->vfs.handles.fchmod, (fsp), (fd), (mode)))
-#define SMB_VFS_CHOWN(conn, path, uid, gid) ((conn)->vfs.ops.chown((conn)->vfs.handles.chown, (conn), (path), (uid), (gid)))
+#define SMB_VFS_CHOWN(conn, path, uid, gid) ((conn)->vfs.ops.chown((conn)->vfs.handles.chown, (path), (uid), (gid)))
#define SMB_VFS_FCHOWN(fsp, fd, uid, gid) ((fsp)->conn->vfs.ops.fchown((fsp)->conn->vfs.handles.fchown, (fsp), (fd), (uid), (gid)))
-#define SMB_VFS_CHDIR(conn, path) ((conn)->vfs.ops.chdir((conn)->vfs.handles.chdir, (conn), (path)))
-#define SMB_VFS_GETWD(conn, buf) ((conn)->vfs.ops.getwd((conn)->vfs.handles.getwd, (conn), (buf)))
-#define SMB_VFS_UTIME(conn, path, times) ((conn)->vfs.ops.utime((conn)->vfs.handles.utime, (conn), (path), (times)))
+#define SMB_VFS_CHDIR(conn, path) ((conn)->vfs.ops.chdir((conn)->vfs.handles.chdir, (path)))
+#define SMB_VFS_GETWD(conn, buf) ((conn)->vfs.ops.getwd((conn)->vfs.handles.getwd, (buf)))
+#define SMB_VFS_UTIME(conn, path, times) ((conn)->vfs.ops.utime((conn)->vfs.handles.utime, (path), (times)))
#define SMB_VFS_FTRUNCATE(fsp, fd, offset) ((fsp)->conn->vfs.ops.ftruncate((fsp)->conn->vfs.handles.ftruncate, (fsp), (fd), (offset)))
#define SMB_VFS_LOCK(fsp, fd, op, offset, count, type) ((fsp)->conn->vfs.ops.lock((fsp)->conn->vfs.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
#define SMB_VFS_KERNEL_FLOCK(fsp, fd, share_mode) ((fsp)->conn->vfs.ops.kernel_flock((fsp)->conn->vfs.handles.kernel_flock, (fsp), (fd), (share_mode)))
#define SMB_VFS_GETLOCK(fsp, fd, poffset, pcount, ptype, ppid) ((fsp)->conn->vfs.ops.getlock((fsp)->conn->vfs.handles.getlock, (fsp), (fd) ,(poffset), (pcount), (ptype), (ppid)))
-#define SMB_VFS_SYMLINK(conn, oldpath, newpath) ((conn)->vfs.ops.symlink((conn)->vfs.handles.symlink, (conn), (oldpath), (newpath)))
-#define SMB_VFS_READLINK(conn, path, buf, bufsiz) ((conn)->vfs.ops.readlink((conn)->vfs.handles.readlink, (conn), (path), (buf), (bufsiz)))
-#define SMB_VFS_LINK(conn, oldpath, newpath) ((conn)->vfs.ops.link((conn)->vfs.handles.link, (conn), (oldpath), (newpath)))
-#define SMB_VFS_MKNOD(conn, path, mode, dev) ((conn)->vfs.ops.mknod((conn)->vfs.handles.mknod, (conn), (path), (mode), (dev)))
-#define SMB_VFS_REALPATH(conn, path, resolved_path) ((conn)->vfs.ops.realpath((conn)->vfs.handles.realpath, (conn), (path), (resolved_path)))
+#define SMB_VFS_SYMLINK(conn, oldpath, newpath) ((conn)->vfs.ops.symlink((conn)->vfs.handles.symlink, (oldpath), (newpath)))
+#define SMB_VFS_READLINK(conn, path, buf, bufsiz) ((conn)->vfs.ops.readlink((conn)->vfs.handles.readlink, (path), (buf), (bufsiz)))
+#define SMB_VFS_LINK(conn, oldpath, newpath) ((conn)->vfs.ops.link((conn)->vfs.handles.link, (oldpath), (newpath)))
+#define SMB_VFS_MKNOD(conn, path, mode, dev) ((conn)->vfs.ops.mknod((conn)->vfs.handles.mknod, (path), (mode), (dev)))
+#define SMB_VFS_REALPATH(conn, path, resolved_path) ((conn)->vfs.ops.realpath((conn)->vfs.handles.realpath, (path), (resolved_path)))
/* NT ACL operations. */
#define SMB_VFS_FGET_NT_ACL(fsp, fd, security_info, ppdesc) ((fsp)->conn->vfs.ops.fget_nt_acl((fsp)->conn->vfs.handles.fget_nt_acl, (fsp), (fd), (security_info), (ppdesc)))
@@ -85,44 +85,44 @@
#define SMB_VFS_SET_NT_ACL(fsp, name, security_info_sent, psd) ((fsp)->conn->vfs.ops.set_nt_acl((fsp)->conn->vfs.handles.set_nt_acl, (fsp), (name), (security_info_sent), (psd)))
/* POSIX ACL operations. */
-#define SMB_VFS_CHMOD_ACL(conn, name, mode) ((conn)->vfs.ops.chmod_acl((conn)->vfs.handles.chmod_acl, (conn), (name), (mode)))
+#define SMB_VFS_CHMOD_ACL(conn, name, mode) ((conn)->vfs.ops.chmod_acl((conn)->vfs.handles.chmod_acl, (name), (mode)))
#define SMB_VFS_FCHMOD_ACL(fsp, fd, mode) ((fsp)->conn->vfs.ops.fchmod_acl((fsp)->conn->vfs.handles.chmod_acl, (fsp), (fd), (mode)))
-#define SMB_VFS_SYS_ACL_GET_ENTRY(conn, theacl, entry_id, entry_p) ((conn)->vfs.ops.sys_acl_get_entry((conn)->vfs.handles.sys_acl_get_entry, (conn), (theacl), (entry_id), (entry_p)))
-#define SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry_d, tag_type_p) ((conn)->vfs.ops.sys_acl_get_tag_type((conn)->vfs.handles.sys_acl_get_tag_type, (conn), (entry_d), (tag_type_p)))
-#define SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry_d, permset_p) ((conn)->vfs.ops.sys_acl_get_permset((conn)->vfs.handles.sys_acl_get_permset, (conn), (entry_d), (permset_p)))
-#define SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry_d) ((conn)->vfs.ops.sys_acl_get_qualifier((conn)->vfs.handles.sys_acl_get_qualifier, (conn), (entry_d)))
-#define SMB_VFS_SYS_ACL_GET_FILE(conn, path_p, type) ((conn)->vfs.ops.sys_acl_get_file((conn)->vfs.handles.sys_acl_get_file, (conn), (path_p), (type)))
+#define SMB_VFS_SYS_ACL_GET_ENTRY(conn, theacl, entry_id, entry_p) ((conn)->vfs.ops.sys_acl_get_entry((conn)->vfs.handles.sys_acl_get_entry, (theacl), (entry_id), (entry_p)))
+#define SMB_VFS_SYS_ACL_GET_TAG_TYPE(conn, entry_d, tag_type_p) ((conn)->vfs.ops.sys_acl_get_tag_type((conn)->vfs.handles.sys_acl_get_tag_type, (entry_d), (tag_type_p)))
+#define SMB_VFS_SYS_ACL_GET_PERMSET(conn, entry_d, permset_p) ((conn)->vfs.ops.sys_acl_get_permset((conn)->vfs.handles.sys_acl_get_permset, (entry_d), (permset_p)))
+#define SMB_VFS_SYS_ACL_GET_QUALIFIER(conn, entry_d) ((conn)->vfs.ops.sys_acl_get_qualifier((conn)->vfs.handles.sys_acl_get_qualifier, (entry_d)))
+#define SMB_VFS_SYS_ACL_GET_FILE(conn, path_p, type) ((conn)->vfs.ops.sys_acl_get_file((conn)->vfs.handles.sys_acl_get_file, (path_p), (type)))
#define SMB_VFS_SYS_ACL_GET_FD(fsp, fd) ((fsp)->conn->vfs.ops.sys_acl_get_fd((fsp)->conn->vfs.handles.sys_acl_get_fd, (fsp), (fd)))
-#define SMB_VFS_SYS_ACL_CLEAR_PERMS(conn, permset) ((conn)->vfs.ops.sys_acl_clear_perms((conn)->vfs.handles.sys_acl_clear_perms, (conn), (permset)))
-#define SMB_VFS_SYS_ACL_ADD_PERM(conn, permset, perm) ((conn)->vfs.ops.sys_acl_add_perm((conn)->vfs.handles.sys_acl_add_perm, (conn), (permset), (perm)))
-#define SMB_VFS_SYS_ACL_TO_TEXT(conn, theacl, plen) ((conn)->vfs.ops.sys_acl_to_text((conn)->vfs.handles.sys_acl_to_text, (conn), (theacl), (plen)))
-#define SMB_VFS_SYS_ACL_INIT(conn, count) ((conn)->vfs.ops.sys_acl_init((conn)->vfs.handles.sys_acl_init, (conn), (count)))
-#define SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, pacl, pentry) ((conn)->vfs.ops.sys_acl_create_entry((conn)->vfs.handles.sys_acl_create_entry, (conn), (pacl), (pentry)))
-#define SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, entry, tagtype) ((conn)->vfs.ops.sys_acl_set_tag_type((conn)->vfs.handles.sys_acl_set_tag_type, (conn), (entry), (tagtype)))
-#define SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, entry, qual) ((conn)->vfs.ops.sys_acl_set_qualifier((conn)->vfs.handles.sys_acl_set_qualifier, (conn), (entry), (qual)))
-#define SMB_VFS_SYS_ACL_SET_PERMSET(conn, entry, permset) ((conn)->vfs.ops.sys_acl_set_permset((conn)->vfs.handles.sys_acl_set_permset, (conn), (entry), (permset)))
-#define SMB_VFS_SYS_ACL_VALID(conn, theacl) ((conn)->vfs.ops.sys_acl_valid((conn)->vfs.handles.sys_acl_valid, (conn), (theacl)))
-#define SMB_VFS_SYS_ACL_SET_FILE(conn, name, acltype, theacl) ((conn)->vfs.ops.sys_acl_set_file((conn)->vfs.handles.sys_acl_set_file, (conn), (name), (acltype), (theacl)))
+#define SMB_VFS_SYS_ACL_CLEAR_PERMS(conn, permset) ((conn)->vfs.ops.sys_acl_clear_perms((conn)->vfs.handles.sys_acl_clear_perms, (permset)))
+#define SMB_VFS_SYS_ACL_ADD_PERM(conn, permset, perm) ((conn)->vfs.ops.sys_acl_add_perm((conn)->vfs.handles.sys_acl_add_perm, (permset), (perm)))
+#define SMB_VFS_SYS_ACL_TO_TEXT(conn, theacl, plen) ((conn)->vfs.ops.sys_acl_to_text((conn)->vfs.handles.sys_acl_to_text, (theacl), (plen)))
+#define SMB_VFS_SYS_ACL_INIT(conn, count) ((conn)->vfs.ops.sys_acl_init((conn)->vfs.handles.sys_acl_init, (count)))
+#define SMB_VFS_SYS_ACL_CREATE_ENTRY(conn, pacl, pentry) ((conn)->vfs.ops.sys_acl_create_entry((conn)->vfs.handles.sys_acl_create_entry, (pacl), (pentry)))
+#define SMB_VFS_SYS_ACL_SET_TAG_TYPE(conn, entry, tagtype) ((conn)->vfs.ops.sys_acl_set_tag_type((conn)->vfs.handles.sys_acl_set_tag_type, (entry), (tagtype)))
+#define SMB_VFS_SYS_ACL_SET_QUALIFIER(conn, entry, qual) ((conn)->vfs.ops.sys_acl_set_qualifier((conn)->vfs.handles.sys_acl_set_qualifier, (entry), (qual)))
+#define SMB_VFS_SYS_ACL_SET_PERMSET(conn, entry, permset) ((conn)->vfs.ops.sys_acl_set_permset((conn)->vfs.handles.sys_acl_set_permset, (entry), (permset)))
+#define SMB_VFS_SYS_ACL_VALID(conn, theacl) ((conn)->vfs.ops.sys_acl_valid((conn)->vfs.handles.sys_acl_valid, (theacl)))
+#define SMB_VFS_SYS_ACL_SET_FILE(conn, name, acltype, theacl) ((conn)->vfs.ops.sys_acl_set_file((conn)->vfs.handles.sys_acl_set_file, (name), (acltype), (theacl)))
#define SMB_VFS_SYS_ACL_SET_FD(fsp, fd, theacl) ((fsp)->conn->vfs.ops.sys_acl_set_fd((fsp)->conn->vfs.handles.sys_acl_set_fd, (fsp), (fd), (theacl)))
-#define SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, path) ((conn)->vfs.ops.sys_acl_delete_def_file((conn)->vfs.handles.sys_acl_delete_def_file, (conn), (path)))
-#define SMB_VFS_SYS_ACL_GET_PERM(conn, permset, perm) ((conn)->vfs.ops.sys_acl_get_perm((conn)->vfs.handles.sys_acl_get_perm, (conn), (permset), (perm)))
-#define SMB_VFS_SYS_ACL_FREE_TEXT(conn, text) ((conn)->vfs.ops.sys_acl_free_text((conn)->vfs.handles.sys_acl_free_text, (conn), (text)))
-#define SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl) ((conn)->vfs.ops.sys_acl_free_acl((conn)->vfs.handles.sys_acl_free_acl, (conn), (posix_acl)))
-#define SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, qualifier, tagtype) ((conn)->vfs.ops.sys_acl_free_qualifier((conn)->vfs.handles.sys_acl_free_qualifier, (conn), (qualifier), (tagtype)))
+#define SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, path) ((conn)->vfs.ops.sys_acl_delete_def_file((conn)->vfs.handles.sys_acl_delete_def_file, (path)))
+#define SMB_VFS_SYS_ACL_GET_PERM(conn, permset, perm) ((conn)->vfs.ops.sys_acl_get_perm((conn)->vfs.handles.sys_acl_get_perm, (permset), (perm)))
+#define SMB_VFS_SYS_ACL_FREE_TEXT(conn, text) ((conn)->vfs.ops.sys_acl_free_text((conn)->vfs.handles.sys_acl_free_text, (text)))
+#define SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl) ((conn)->vfs.ops.sys_acl_free_acl((conn)->vfs.handles.sys_acl_free_acl, (posix_acl)))
+#define SMB_VFS_SYS_ACL_FREE_QUALIFIER(conn, qualifier, tagtype) ((conn)->vfs.ops.sys_acl_free_qualifier((conn)->vfs.handles.sys_acl_free_qualifier, (qualifier), (tagtype)))
/* EA operations. */
-#define SMB_VFS_GETXATTR(conn,path,name,value,size) ((conn)->vfs.ops.getxattr((conn)->vfs.handles.getxattr,(conn),(path),(name),(value),(size)))
-#define SMB_VFS_LGETXATTR(conn,path,name,value,size) ((conn)->vfs.ops.lgetxattr((conn)->vfs.handles.lgetxattr,(conn),(path),(name),(value),(size)))
+#define SMB_VFS_GETXATTR(conn,path,name,value,size) ((conn)->vfs.ops.getxattr((conn)->vfs.handles.getxattr,(path),(name),(value),(size)))
+#define SMB_VFS_LGETXATTR(conn,path,name,value,size) ((conn)->vfs.ops.lgetxattr((conn)->vfs.handles.lgetxattr,(path),(name),(value),(size)))
#define SMB_VFS_FGETXATTR(fsp,fd,name,value,size) ((fsp)->conn->vfs.ops.fgetxattr((fsp)->conn->vfs.handles.fgetxattr,(fsp),(fd),(name),(value),(size)))
-#define SMB_VFS_LISTXATTR(conn,path,list,size) ((conn)->vfs.ops.listxattr((conn)->vfs.handles.listxattr,(conn),(path),(list),(size)))
-#define SMB_VFS_LLISTXATTR(conn,path,list,size) ((conn)->vfs.ops.llistxattr((conn)->vfs.handles.llistxattr,(conn),(path),(list),(size)))
+#define SMB_VFS_LISTXATTR(conn,path,list,size) ((conn)->vfs.ops.listxattr((conn)->vfs.handles.listxattr,(path),(list),(size)))
+#define SMB_VFS_LLISTXATTR(conn,path,list,size) ((conn)->vfs.ops.llistxattr((conn)->vfs.handles.llistxattr,(path),(list),(size)))
#define SMB_VFS_FLISTXATTR(fsp,fd,list,size) ((fsp)->conn->vfs.ops.flistxattr((fsp)->conn->vfs.handles.flistxattr,(fsp),(fd),(list),(size)))
-#define SMB_VFS_REMOVEXATTR(conn,path,name) ((conn)->vfs.ops.removexattr((conn)->vfs.handles.removexattr,(conn),(path),(name)))
-#define SMB_VFS_LREMOVEXATTR(conn,path,name) ((conn)->vfs.ops.lremovexattr((conn)->vfs.handles.lremovexattr,(conn),(path),(name)))
+#define SMB_VFS_REMOVEXATTR(conn,path,name) ((conn)->vfs.ops.removexattr((conn)->vfs.handles.removexattr,(path),(name)))
+#define SMB_VFS_LREMOVEXATTR(conn,path,name) ((conn)->vfs.ops.lremovexattr((conn)->vfs.handles.lremovexattr,(path),(name)))
#define SMB_VFS_FREMOVEXATTR(fsp,fd,name) ((fsp)->conn->vfs.ops.fremovexattr((fsp)->conn->vfs.handles.fremovexattr,(fsp),(fd),(name)))
-#define SMB_VFS_SETXATTR(conn,path,name,value,size,flags) ((conn)->vfs.ops.setxattr((conn)->vfs.handles.setxattr,(conn),(path),(name),(value),(size),(flags)))
-#define SMB_VFS_LSETXATTR(conn,path,name,value,size,flags) ((conn)->vfs.ops.lsetxattr((conn)->vfs.handles.lsetxattr,(conn),(path),(name),(value),(size),(flags)))
+#define SMB_VFS_SETXATTR(conn,path,name,value,size,flags) ((conn)->vfs.ops.setxattr((conn)->vfs.handles.setxattr,(path),(name),(value),(size),(flags)))
+#define SMB_VFS_LSETXATTR(conn,path,name,value,size,flags) ((conn)->vfs.ops.lsetxattr((conn)->vfs.handles.lsetxattr,(path),(name),(value),(size),(flags)))
#define SMB_VFS_FSETXATTR(fsp,fd,name,value,size,flags) ((fsp)->conn->vfs.ops.fsetxattr((fsp)->conn->vfs.handles.fsetxattr,(fsp),(fd),(name),(value),(size),(flags)))
/* AIO operations. */
@@ -141,26 +141,26 @@
********************************************************************/
/* Disk operations */
-#define SMB_VFS_OPAQUE_CONNECT(conn, service, user) ((conn)->vfs_opaque.ops.connect_fn((conn)->vfs_opaque.handles.connect_hnd, (conn), (service), (user)))
-#define SMB_VFS_OPAQUE_DISCONNECT(conn) ((conn)->vfs_opaque.ops.disconnect((conn)->vfs_opaque.handles.disconnect, (conn)))
-#define SMB_VFS_OPAQUE_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs_opaque.ops.disk_free((conn)->vfs_opaque.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize)))
-#define SMB_VFS_OPAQUE_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.get_quota((conn)->vfs_opaque.handles.get_quota, (conn), (qtype), (id), (qt)))
-#define SMB_VFS_OPAQUE_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.set_quota((conn)->vfs_opaque.handles.set_quota, (conn), (qtype), (id), (qt)))
+#define SMB_VFS_OPAQUE_CONNECT(conn, service, user) ((conn)->vfs_opaque.ops.connect_fn((conn)->vfs_opaque.handles.connect_hnd, (service), (user)))
+#define SMB_VFS_OPAQUE_DISCONNECT(conn) ((conn)->vfs_opaque.ops.disconnect((conn)->vfs_opaque.handles.disconnect))
+#define SMB_VFS_OPAQUE_DISK_FREE(conn, path, small_query, bsize, dfree ,dsize) ((conn)->vfs_opaque.ops.disk_free((conn)->vfs_opaque.handles.disk_free, (path), (small_query), (bsize), (dfree), (dsize)))
+#define SMB_VFS_OPAQUE_GET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.get_quota((conn)->vfs_opaque.handles.get_quota, (qtype), (id), (qt)))
+#define SMB_VFS_OPAQUE_SET_QUOTA(conn, qtype, id, qt) ((conn)->vfs_opaque.ops.set_quota((conn)->vfs_opaque.handles.set_quota, (qtype), (id), (qt)))
#define SMB_VFS_OPAQUE_GET_SHADOW_COPY_DATA(fsp,shadow_copy_data,labels) ((fsp)->conn->vfs_opaque.ops.get_shadow_copy_data((fsp)->conn->vfs_opaque.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
-#define SMB_VFS_OPAQUE_STATVFS(conn, path, statbuf) ((conn)->vfs_opaque.ops.statvfs((conn)->vfs_opaque.handles.statvfs, (conn), (path), (statbuf)))
+#define SMB_VFS_OPAQUE_STATVFS(conn, path, statbuf) ((conn)->vfs_opaque.ops.statvfs((conn)->vfs_opaque.handles.statvfs, (path), (statbuf)))
/* Directory operations */
-#define SMB_VFS_OPAQUE_OPENDIR(conn, fname, mask, attr) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (conn), (fname), (mask), (attr)))
-#define SMB_VFS_OPAQUE_READDIR(conn, dirp) ((conn)->vfs_opaque.ops.readdir((conn)->vfs_opaque.handles.readdir, (conn), (dirp)))
-#define SMB_VFS_OPAQUE_SEEKDIR(conn, dirp, offset) ((conn)->vfs_opaque.ops.seekdir((conn)->vfs_opaque.handles.seekdir, (conn), (dirp), (offset)))
-#define SMB_VFS_OPAQUE_TELLDIR(conn, dirp) ((conn)->vfs_opaque.ops.telldir((conn)->vfs_opaque.handles.telldir, (conn), (dirp)))
-#define SMB_VFS_OPAQUE_REWINDDIR(conn, dirp) ((conn)->vfs_opaque.ops.rewind_dir((conn)->vfs_opaque.handles.rewind_dir, (conn), (dirp)))
-#define SMB_VFS_OPAQUE_MKDIR(conn, path, mode) ((conn)->vfs_opaque.ops.mkdir((conn)->vfs_opaque.handles.mkdir,(conn), (path), (mode)))
-#define SMB_VFS_OPAQUE_RMDIR(conn, path) ((conn)->vfs_opaque.ops.rmdir((conn)->vfs_opaque.handles.rmdir, (conn), (path)))
-#define SMB_VFS_OPAQUE_CLOSEDIR(conn, dir) ((conn)->vfs_opaque.ops.closedir((conn)->vfs_opaque.handles.closedir, (conn), dir))
+#define SMB_VFS_OPAQUE_OPENDIR(conn, fname, mask, attr) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (fname), (mask), (attr)))
+#define SMB_VFS_OPAQUE_READDIR(conn, dirp) ((conn)->vfs_opaque.ops.readdir((conn)->vfs_opaque.handles.readdir, (dirp)))
+#define SMB_VFS_OPAQUE_SEEKDIR(conn, dirp, offset) ((conn)->vfs_opaque.ops.seekdir((conn)->vfs_opaque.handles.seekdir, (dirp), (offset)))
+#define SMB_VFS_OPAQUE_TELLDIR(conn, dirp) ((conn)->vfs_opaque.ops.telldir((conn)->vfs_opaque.handles.telldir, (dirp)))
+#define SMB_VFS_OPAQUE_REWINDDIR(conn, dirp) ((conn)->vfs_opaque.ops.rewind_dir((conn)->vfs_opaque.handles.rewind_dir, (dirp)))
+#define SMB_VFS_OPAQUE_MKDIR(conn, path, mode) ((conn)->vfs_opaque.ops.mkdir((conn)->vfs_opaque.handles.mkdir,(path), (mode)))
+#define SMB_VFS_OPAQUE_RMDIR(conn, path) ((conn)->vfs_opaque.ops.rmdir((conn)->vfs_opaque.handles.rmdir, (path)))
+#define SMB_VFS_OPAQUE_CLOSEDIR(conn, dir) ((conn)->vfs_opaque.ops.closedir((conn)->vfs_opaque.handles.closedir, dir))
/* File operations */
-#define SMB_VFS_OPAQUE_OPEN(conn, fname, flags, mode) ((conn)->vfs_opaque.ops.open((conn)->vfs_opaque.handles.open, (conn), (fname), (flags), (mode)))
+#define SMB_VFS_OPAQUE_OPEN(conn, fname, fsp, flags, mode) ((conn)->vfs_opaque.ops.open((conn)->vfs_opaque.handles.open, (fname), (fsp), (flags), (mode)))
#define SMB_VFS_OPAQUE_CLOSE(fsp, fd) ((fsp)->conn->vfs_opaque.ops.close_fn((fsp)->conn->vfs_opaque.handles.close_hnd, (fsp), (fd)))
#define SMB_VFS_OPAQUE_READ(fsp, fd, data, n) ((fsp)->conn->vfs_opaque.ops.read((fsp)->conn->vfs_opaque.handles.read, (fsp), (fd), (data), (n)))
#define SMB_VFS_OPAQUE_PREAD(fsp, fd, data, n, off) ((fsp)->conn->vfs_opaque.ops.pread((fsp)->conn->vfs_opaque.handles.pread, (fsp), (fd), (data), (n), (off)))
@@ -168,28 +168,28 @@
#define SMB_VFS_OPAQUE_PWRITE(fsp, fd, data, n, off) ((fsp)->conn->vfs_opaque.ops.pwrite((fsp)->conn->vfs_opaque.handles.pwrite, (fsp), (fd), (data), (n), (off)))
#define SMB_VFS_OPAQUE_LSEEK(fsp, fd, offset, whence) ((fsp)->conn->vfs_opaque.ops.lseek((fsp)->conn->vfs_opaque.handles.lseek, (fsp), (fd), (offset), (whence)))
#define SMB_VFS_OPAQUE_SENDFILE(tofd, fsp, fromfd, header, offset, count) ((fsp)->conn->vfs_opaque.ops.sendfile((fsp)->conn->vfs_opaque.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count)))
-#define SMB_VFS_OPAQUE_RENAME(conn, old, new) ((conn)->vfs_opaque.ops.rename((conn)->vfs_opaque.handles.rename, (conn), (old), (new)))
+#define SMB_VFS_OPAQUE_RENAME(conn, old, new) ((conn)->vfs_opaque.ops.rename((conn)->vfs_opaque.handles.rename, (old), (new)))
#define SMB_VFS_OPAQUE_FSYNC(fsp, fd) ((fsp)->conn->vfs_opaque.ops.fsync((fsp)->conn->vfs_opaque.handles.fsync, (fsp), (fd)))
-#define SMB_VFS_OPAQUE_STAT(conn, fname, sbuf) ((conn)->vfs_opaque.ops.stat((conn)->vfs_opaque.handles.stat, (conn), (fname), (sbuf)))
+#define SMB_VFS_OPAQUE_STAT(conn, fname, sbuf) ((conn)->vfs_opaque.ops.stat((conn)->vfs_opaque.handles.stat, (fname), (sbuf)))
#define SMB_VFS_OPAQUE_FSTAT(fsp, fd, sbuf) ((fsp)->conn->vfs_opaque.ops.fstat((fsp)->conn->vfs_opaque.handles.fstat, (fsp) ,(fd) ,(sbuf)))
-#define SMB_VFS_OPAQUE_LSTAT(conn, path, sbuf) ((conn)->vfs_opaque.ops.lstat((conn)->vfs_opaque.handles.lstat, (conn), (path), (sbuf)))
-#define SMB_VFS_OPAQUE_UNLINK(conn, path) ((conn)->vfs_opaque.ops.unlink((conn)->vfs_opaque.handles.unlink, (conn), (path)))
-#define SMB_VFS_OPAQUE_CHMOD(conn, path, mode) ((conn)->vfs_opaque.ops.chmod((conn)->vfs_opaque.handles.chmod, (conn), (path), (mode)))
+#define SMB_VFS_OPAQUE_LSTAT(conn, path, sbuf) ((conn)->vfs_opaque.ops.lstat((conn)->vfs_opaque.handles.lstat, (path), (sbuf)))
+#define SMB_VFS_OPAQUE_UNLINK(conn, path) ((conn)->vfs_opaque.ops.unlink((conn)->vfs_opaque.handles.unlink, (path)))
+#define SMB_VFS_OPAQUE_CHMOD(conn, path, mode) ((conn)->vfs_opaque.ops.chmod((conn)->vfs_opaque.handles.chmod, (path), (mode)))
#define SMB_VFS_OPAQUE_FCHMOD(fsp, fd, mode) ((fsp)->conn->vfs_opaque.ops.fchmod((fsp)->conn->vfs_opaque.handles.fchmod, (fsp), (fd), (mode)))
-#define SMB_VFS_OPAQUE_CHOWN(conn, path, uid, gid) ((conn)->vfs_opaque.ops.chown((conn)->vfs_opaque.handles.chown, (conn), (path), (uid), (gid)))
+#define SMB_VFS_OPAQUE_CHOWN(conn, path, uid, gid) ((conn)->vfs_opaque.ops.chown((conn)->vfs_opaque.handles.chown, (path), (uid), (gid)))
#define SMB_VFS_OPAQUE_FCHOWN(fsp, fd, uid, gid) ((fsp)->conn->vfs_opaque.ops.fchown((fsp)->conn->vfs_opaque.handles.fchown, (fsp), (fd), (uid), (gid)))
-#define SMB_VFS_OPAQUE_CHDIR(conn, path) ((conn)->vfs_opaque.ops.chdir((conn)->vfs_opaque.handles.chdir, (conn), (path)))
-#define SMB_VFS_OPAQUE_GETWD(conn, buf) ((conn)->vfs_opaque.ops.getwd((conn)->vfs_opaque.handles.getwd, (conn), (buf)))
-#define SMB_VFS_OPAQUE_UTIME(conn, path, times) ((conn)->vfs_opaque.ops.utime((conn)->vfs_opaque.handles.utime, (conn), (path), (times)))
+#define SMB_VFS_OPAQUE_CHDIR(conn, path) ((conn)->vfs_opaque.ops.chdir((conn)->vfs_opaque.handles.chdir, (path)))
+#define SMB_VFS_OPAQUE_GETWD(conn, buf) ((conn)->vfs_opaque.ops.getwd((conn)->vfs_opaque.handles.getwd, (buf)))
+#define SMB_VFS_OPAQUE_UTIME(conn, path, times) ((conn)->vfs_opaque.ops.utime((conn)->vfs_opaque.handles.utime, (path), (times)))
#define SMB_VFS_OPAQUE_FTRUNCATE(fsp, fd, offset) ((fsp)->conn->vfs_opaque.ops.ftruncate((fsp)->conn->vfs_opaque.handles.ftruncate, (fsp), (fd), (offset)))
#define SMB_VFS_OPAQUE_LOCK(fsp, fd, op, offset, count, type) ((fsp)->conn->vfs_opaque.ops.lock((fsp)->conn->vfs_opaque.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
#define SMB_VFS_OPAQUE_FLOCK(fsp, fd, share_mode) ((fsp)->conn->vfs_opaque.ops.lock((fsp)->conn->vfs_opaque.handles.kernel_flock, (fsp), (fd), (share_mode)))
#define SMB_VFS_OPAQUE_GETLOCK(fsp, fd, poffset, pcount, ptype, ppid) ((fsp)->conn->vfs_opaque.ops.getlock((fsp)->conn->vfs_opaque.handles.getlock, (fsp), (fd), (poffset), (pcount), (ptype), (ppid)))
-#define SMB_VFS_OPAQUE_SYMLINK(conn, oldpath, newpath) ((conn)->vfs_opaque.ops.symlink((conn)->vfs_opaque.handles.symlink, (conn), (oldpath), (newpath)))
-#define SMB_VFS_OPAQUE_READLINK(conn, path, buf, bufsiz) ((conn)->vfs_opaque.ops.readlink((conn)->vfs_opaque.handles.readlink, (conn), (path), (buf), (bufsiz)))
-#define SMB_VFS_OPAQUE_LINK(conn, oldpath, newpath) ((conn)->vfs_opaque.ops.link((conn)->vfs_opaque.handles.link, (conn), (oldpath), (newpath)))
-#define SMB_VFS_OPAQUE_MKNOD(conn, path, mode, dev) ((conn)->vfs_opaque.ops.mknod((conn)->vfs_opaque.handles.mknod, (conn), (path), (mode), (dev)))
-#define SMB_VFS_OPAQUE_REALPATH(conn, path, resolved_path) ((conn)->vfs_opaque.ops.realpath((conn)->vfs_opaque.handles.realpath, (conn), (path), (resolved_path)))
+#define SMB_VFS_OPAQUE_SYMLINK(conn, oldpath, newpath) ((conn)->vfs_opaque.ops.symlink((conn)->vfs_opaque.handles.symlink, (oldpath), (newpath)))
+#define SMB_VFS_OPAQUE_READLINK(conn, path, buf, bufsiz) ((conn)->vfs_opaque.ops.readlink((conn)->vfs_opaque.handles.readlink, (path), (buf), (bufsiz)))
+#define SMB_VFS_OPAQUE_LINK(conn, oldpath, newpath) ((conn)->vfs_opaque.ops.link((conn)->vfs_opaque.handles.link, (oldpath), (newpath)))
+#define SMB_VFS_OPAQUE_MKNOD(conn, path, mode, dev) ((conn)->vfs_opaque.ops.mknod((conn)->vfs_opaque.handles.mknod, (path), (mode), (dev)))
+#define SMB_VFS_OPAQUE_REALPATH(conn, path, resolved_path) ((conn)->vfs_opaque.ops.realpath((conn)->vfs_opaque.handles.realpath, (path), (resolved_path)))
/* NT ACL operations. */
#define SMB_VFS_OPAQUE_FGET_NT_ACL(fsp, fd, security_info, ppdesc) ((fsp)->conn->vfs_opaque.ops.fget_nt_acl((fsp)->conn->vfs_opaque.handles.fget_nt_acl, (fsp), (fd), (security_info), (ppdesc)))
@@ -198,44 +198,44 @@
#define SMB_VFS_OPAQUE_SET_NT_ACL(fsp, name, security_info_sent, psd) ((fsp)->conn->vfs_opaque.ops.set_nt_acl((fsp)->conn->vfs_opaque.handles.set_nt_acl, (fsp), (name), (security_info_sent), (psd)))
/* POSIX ACL operations. */
-#define SMB_VFS_OPAQUE_CHMOD_ACL(conn, name, mode) ((conn)->vfs_opaque.ops.chmod_acl((conn)->vfs_opaque.handles.chmod_acl, (conn), (name), (mode)))
+#define SMB_VFS_OPAQUE_CHMOD_ACL(conn, name, mode) ((conn)->vfs_opaque.ops.chmod_acl((conn)->vfs_opaque.handles.chmod_acl, (name), (mode)))
#define SMB_VFS_OPAQUE_FCHMOD_ACL(fsp, fd, mode) ((fsp)->conn->vfs_opaque.ops.fchmod_acl((fsp)->conn->vfs_opaque.handles.chmod_acl, (fsp), (fd), (mode)))
-#define SMB_VFS_OPAQUE_SYS_ACL_GET_ENTRY(conn, theacl, entry_id, entry_p) ((conn)->vfs_opaque.ops.sys_acl_get_entry((conn)->vfs_opaque.handles.sys_acl_get_entry, (conn), (theacl), (entry_id), (entry_p)))
-#define SMB_VFS_OPAQUE_SYS_ACL_GET_TAG_TYPE(conn, entry_d, tag_type_p) ((conn)->vfs_opaque.ops.sys_acl_get_tag_type((conn)->vfs_opaque.handles.sys_acl_get_tag_type, (conn), (entry_d), (tag_type_p)))
-#define SMB_VFS_OPAQUE_SYS_ACL_GET_PERMSET(conn, entry_d, permset_p) ((conn)->vfs_opaque.ops.sys_acl_get_permset((conn)->vfs_opaque.handles.sys_acl_get_permset, (conn), (entry_d), (permset_p)))
-#define SMB_VFS_OPAQUE_SYS_ACL_GET_QUALIFIER(conn, entry_d) ((conn)->vfs_opaque.ops.sys_acl_get_qualifier((conn)->vfs_opaque.handles.sys_acl_get_qualifier, (conn), (entry_d)))
-#define SMB_VFS_OPAQUE_SYS_ACL_GET_FILE(conn, path_p, type) ((conn)->vfs_opaque.ops.sys_acl_get_file((conn)->vfs_opaque.handles.sys_acl_get_file, (conn), (path_p), (type)))
+#define SMB_VFS_OPAQUE_SYS_ACL_GET_ENTRY(conn, theacl, entry_id, entry_p) ((conn)->vfs_opaque.ops.sys_acl_get_entry((conn)->vfs_opaque.handles.sys_acl_get_entry, (theacl), (entry_id), (entry_p)))
+#define SMB_VFS_OPAQUE_SYS_ACL_GET_TAG_TYPE(conn, entry_d, tag_type_p) ((conn)->vfs_opaque.ops.sys_acl_get_tag_type((conn)->vfs_opaque.handles.sys_acl_get_tag_type, (entry_d), (tag_type_p)))
+#define SMB_VFS_OPAQUE_SYS_ACL_GET_PERMSET(conn, entry_d, permset_p) ((conn)->vfs_opaque.ops.sys_acl_get_permset((conn)->vfs_opaque.handles.sys_acl_get_permset, (entry_d), (permset_p)))
+#define SMB_VFS_OPAQUE_SYS_ACL_GET_QUALIFIER(conn, entry_d) ((conn)->vfs_opaque.ops.sys_acl_get_qualifier((conn)->vfs_opaque.handles.sys_acl_get_qualifier, (entry_d)))
+#define SMB_VFS_OPAQUE_SYS_ACL_GET_FILE(conn, path_p, type) ((conn)->vfs_opaque.ops.sys_acl_get_file((conn)->vfs_opaque.handles.sys_acl_get_file, (path_p), (type)))
#define SMB_VFS_OPAQUE_SYS_ACL_GET_FD(fsp, fd) ((fsp)->conn->vfs_opaque.ops.sys_acl_get_fd((fsp)->conn->vfs_opaque.handles.sys_acl_get_fd, (fsp), (fd)))
-#define SMB_VFS_OPAQUE_SYS_ACL_CLEAR_PERMS(conn, permset) ((conn)->vfs_opaque.ops.sys_acl_clear_perms((conn)->vfs_opaque.handles.sys_acl_clear_perms, (conn), (permset)))
-#define SMB_VFS_OPAQUE_SYS_ACL_ADD_PERM(conn, permset, perm) ((conn)->vfs_opaque.ops.sys_acl_add_perm((conn)->vfs_opaque.handles.sys_acl_add_perm, (conn), (permset), (perm)))
-#define SMB_VFS_OPAQUE_SYS_ACL_TO_TEXT(conn, theacl, plen) ((conn)->vfs_opaque.ops.sys_acl_to_text((conn)->vfs_opaque.handles.sys_acl_to_text, (conn), (theacl), (plen)))
-#define SMB_VFS_OPAQUE_SYS_ACL_INIT(conn, count) ((conn)->vfs_opaque.ops.sys_acl_init((conn)->vfs_opaque.handles.sys_acl_init, (conn), (count)))
-#define SMB_VFS_OPAQUE_SYS_ACL_CREATE_ENTRY(conn, pacl, pentry) ((conn)->vfs_opaque.ops.sys_acl_create_entry((conn)->vfs_opaque.handles.sys_acl_create_entry, (conn), (pacl), (pentry)))
-#define SMB_VFS_OPAQUE_SYS_ACL_SET_TAG_TYPE(conn, entry, tagtype) ((conn)->vfs_opaque.ops.sys_acl_set_tag_type((conn)->vfs_opaque.handles.sys_acl_set_tag_type, (conn), (entry), (tagtype)))
-#define SMB_VFS_OPAQUE_SYS_ACL_SET_QUALIFIER(conn, entry, qual) ((conn)->vfs_opaque.ops.sys_acl_set_qualifier((conn)->vfs_opaque.handles.sys_acl_set_qualifier, (conn), (entry), (qual)))
-#define SMB_VFS_OPAQUE_SYS_ACL_SET_PERMSET(conn, entry, permset) ((conn)->vfs_opaque.ops.sys_acl_set_permset((conn)->vfs_opaque.handles.sys_acl_set_permset, (conn), (entry), (permset)))
-#define SMB_VFS_OPAQUE_SYS_ACL_VALID(conn, theacl) ((conn)->vfs_opaque.ops.sys_acl_valid((conn)->vfs_opaque.handles.sys_acl_valid, (conn), (theacl)))
-#define SMB_VFS_OPAQUE_SYS_ACL_SET_FILE(conn, name, acltype, theacl) ((conn)->vfs_opaque.ops.sys_acl_set_file((conn)->vfs_opaque.handles.sys_acl_set_file, (conn), (name), (acltype), (theacl)))
+#define SMB_VFS_OPAQUE_SYS_ACL_CLEAR_PERMS(conn, permset) ((conn)->vfs_opaque.ops.sys_acl_clear_perms((conn)->vfs_opaque.handles.sys_acl_clear_perms, (permset)))
+#define SMB_VFS_OPAQUE_SYS_ACL_ADD_PERM(conn, permset, perm) ((conn)->vfs_opaque.ops.sys_acl_add_perm((conn)->vfs_opaque.handles.sys_acl_add_perm, (permset), (perm)))
+#define SMB_VFS_OPAQUE_SYS_ACL_TO_TEXT(conn, theacl, plen) ((conn)->vfs_opaque.ops.sys_acl_to_text((conn)->vfs_opaque.handles.sys_acl_to_text, (theacl), (plen)))
+#define SMB_VFS_OPAQUE_SYS_ACL_INIT(conn, count) ((conn)->vfs_opaque.ops.sys_acl_init((conn)->vfs_opaque.handles.sys_acl_init, (count)))
+#define SMB_VFS_OPAQUE_SYS_ACL_CREATE_ENTRY(conn, pacl, pentry) ((conn)->vfs_opaque.ops.sys_acl_create_entry((conn)->vfs_opaque.handles.sys_acl_create_entry, (pacl), (pentry)))
+#define SMB_VFS_OPAQUE_SYS_ACL_SET_TAG_TYPE(conn, entry, tagtype) ((conn)->vfs_opaque.ops.sys_acl_set_tag_type((conn)->vfs_opaque.handles.sys_acl_set_tag_type, (entry), (tagtype)))
+#define SMB_VFS_OPAQUE_SYS_ACL_SET_QUALIFIER(conn, entry, qual) ((conn)->vfs_opaque.ops.sys_acl_set_qualifier((conn)->vfs_opaque.handles.sys_acl_set_qualifier, (entry), (qual)))
+#define SMB_VFS_OPAQUE_SYS_ACL_SET_PERMSET(conn, entry, permset) ((conn)->vfs_opaque.ops.sys_acl_set_permset((conn)->vfs_opaque.handles.sys_acl_set_permset, (entry), (permset)))
+#define SMB_VFS_OPAQUE_SYS_ACL_VALID(conn, theacl) ((conn)->vfs_opaque.ops.sys_acl_valid((conn)->vfs_opaque.handles.sys_acl_valid, (theacl)))
+#define SMB_VFS_OPAQUE_SYS_ACL_SET_FILE(conn, name, acltype, theacl) ((conn)->vfs_opaque.ops.sys_acl_set_file((conn)->vfs_opaque.handles.sys_acl_set_file, (name), (acltype), (theacl)))
#define SMB_VFS_OPAQUE_SYS_ACL_SET_FD(fsp, fd, theacl) ((fsp)->conn->vfs_opaque.ops.sys_acl_set_fd((fsp)->conn->vfs_opaque.handles.sys_acl_set_fd, (fsp), (fd), (theacl)))
-#define SMB_VFS_OPAQUE_SYS_ACL_DELETE_DEF_FILE(conn, path) ((conn)->vfs_opaque.ops.sys_acl_delete_def_file((conn)->vfs_opaque.handles.sys_acl_delete_def_file, (conn), (path)))
-#define SMB_VFS_OPAQUE_SYS_ACL_GET_PERM(conn, permset, perm) ((conn)->vfs_opaque.ops.sys_acl_get_perm((conn)->vfs_opaque.handles.sys_acl_get_perm, (conn), (permset), (perm)))
-#define SMB_VFS_OPAQUE_SYS_ACL_FREE_TEXT(conn, text) ((conn)->vfs_opaque.ops.sys_acl_free_text((conn)->vfs_opaque.handles.sys_acl_free_text, (conn), (text)))
-#define SMB_VFS_OPAQUE_SYS_ACL_FREE_ACL(conn, posix_acl) ((conn)->vfs_opaque.ops.sys_acl_free_acl((conn)->vfs_opaque.handles.sys_acl_free_acl, (conn), (posix_acl)))
-#define SMB_VFS_OPAQUE_SYS_ACL_FREE_QUALIFIER(conn, qualifier, tagtype) ((conn)->vfs_opaque.ops.sys_acl_free_qualifier((conn)->vfs_opaque.handles.sys_acl_free_qualifier, (conn), (qualifier), (tagtype)))
+#define SMB_VFS_OPAQUE_SYS_ACL_DELETE_DEF_FILE(conn, path) ((conn)->vfs_opaque.ops.sys_acl_delete_def_file((conn)->vfs_opaque.handles.sys_acl_delete_def_file, (path)))
+#define SMB_VFS_OPAQUE_SYS_ACL_GET_PERM(conn, permset, perm) ((conn)->vfs_opaque.ops.sys_acl_get_perm((conn)->vfs_opaque.handles.sys_acl_get_perm, (permset), (perm)))
+#define SMB_VFS_OPAQUE_SYS_ACL_FREE_TEXT(conn, text) ((conn)->vfs_opaque.ops.sys_acl_free_text((conn)->vfs_opaque.handles.sys_acl_free_text, (text)))
+#define SMB_VFS_OPAQUE_SYS_ACL_FREE_ACL(conn, posix_acl) ((conn)->vfs_opaque.ops.sys_acl_free_acl((conn)->vfs_opaque.handles.sys_acl_free_acl, (posix_acl)))
+#define SMB_VFS_OPAQUE_SYS_ACL_FREE_QUALIFIER(conn, qualifier, tagtype) ((conn)->vfs_opaque.ops.sys_acl_free_qualifier((conn)->vfs_opaque.handles.sys_acl_free_qualifier, (qualifier), (tagtype)))
/* EA operations. */
-#define SMB_VFS_OPAQUE_GETXATTR(conn,path,name,value,size) ((conn)->vfs_opaque.ops.getxattr((conn)->vfs_opaque.handles.getxattr,(conn),(path),(name),(value),(size)))
-#define SMB_VFS_OPAQUE_LGETXATTR(conn,path,name,value,size) ((conn)->vfs_opaque.ops.lgetxattr((conn)->vfs_opaque.handles.lgetxattr,(conn),(path),(name),(value),(size)))
+#define SMB_VFS_OPAQUE_GETXATTR(conn,path,name,value,size) ((conn)->vfs_opaque.ops.getxattr((conn)->vfs_opaque.handles.getxattr,(path),(name),(value),(size)))
+#define SMB_VFS_OPAQUE_LGETXATTR(conn,path,name,value,size) ((conn)->vfs_opaque.ops.lgetxattr((conn)->vfs_opaque.handles.lgetxattr,(path),(name),(value),(size)))
#define SMB_VFS_OPAQUE_FGETXATTR(fsp,fd,name,value,size) ((fsp)->conn->vfs_opaque.ops.fgetxattr((fsp)->conn->vfs_opaque.handles.fgetxattr,(fsp),(fd),(name),(value),(size)))
-#define SMB_VFS_OPAQUE_LISTXATTR(conn,path,list,size) ((conn)->vfs_opaque.ops.listxattr((conn)->vfs_opaque.handles.listxattr,(conn),(path),(list),(size)))
-#define SMB_VFS_OPAQUE_LLISTXATTR(conn,path,list,size) ((conn)->vfs_opaque.ops.llistxattr((conn)->vfs_opaque.handles.llistxattr,(conn),(path),(list),(size)))
+#define SMB_VFS_OPAQUE_LISTXATTR(conn,path,list,size) ((conn)->vfs_opaque.ops.listxattr((conn)->vfs_opaque.handles.listxattr,(path),(list),(size)))
+#define SMB_VFS_OPAQUE_LLISTXATTR(conn,path,list,size) ((conn)->vfs_opaque.ops.llistxattr((conn)->vfs_opaque.handles.llistxattr,(path),(list),(size)))
#define SMB_VFS_OPAQUE_FLISTXATTR(fsp,fd,list,size) ((fsp)->conn->vfs_opaque.ops.flistxattr((fsp)->conn->vfs_opaque.handles.flistxattr,(fsp),(fd),(list),(size)))
-#define SMB_VFS_OPAQUE_REMOVEXATTR(conn,path,name) ((conn)->vfs_opaque.ops.removexattr((conn)->vfs_opaque.handles.removexattr,(conn),(path),(name)))
-#define SMB_VFS_OPAQUE_LREMOVEXATTR(conn,path,name) ((conn)->vfs_opaque.ops.lremovexattr((conn)->vfs_opaque.handles.lremovexattr,(conn),(path),(name)))
+#define SMB_VFS_OPAQUE_REMOVEXATTR(conn,path,name) ((conn)->vfs_opaque.ops.removexattr((conn)->vfs_opaque.handles.removexattr,(path),(name)))
+#define SMB_VFS_OPAQUE_LREMOVEXATTR(conn,path,name) ((conn)->vfs_opaque.ops.lremovexattr((conn)->vfs_opaque.handles.lremovexattr,(path),(name)))
#define SMB_VFS_OPAQUE_FREMOVEXATTR(fsp,fd,name) ((fsp)->conn->vfs_opaque.ops.fremovexattr((fsp)->conn->vfs_opaque.handles.fremovexattr,(fsp),(fd),(name)))
-#define SMB_VFS_OPAQUE_SETXATTR(conn,path,name,value,size,flags) ((conn)->vfs_opaque.ops.setxattr((conn)->vfs_opaque.handles.setxattr,(conn),(path),(name),(value),(size),(flags)))
-#define SMB_VFS_OPAQUE_LSETXATTR(conn,path,name,value,size,flags) ((conn)->vfs_opaque.ops.lsetxattr((conn)->vfs_opaque.handles.lsetxattr,(conn),(path),(name),(value),(size),(flags)))
+#define SMB_VFS_OPAQUE_SETXATTR(conn,path,name,value,size,flags) ((conn)->vfs_opaque.ops.setxattr((conn)->vfs_opaque.handles.setxattr,(path),(name),(value),(size),(flags)))
+#define SMB_VFS_OPAQUE_LSETXATTR(conn,path,name,value,size,flags) ((conn)->vfs_opaque.ops.lsetxattr((conn)->vfs_opaque.handles.lsetxattr,(path),(name),(value),(size),(flags)))
#define SMB_VFS_OPAQUE_FSETXATTR(fsp,fd,name,value,size,flags) ((fsp)->conn->vfs_opaque.ops.fsetxattr((fsp)->conn->vfs_opaque.handles.fsetxattr,(fsp),(fd),(name),(value),(size),(flags)))
/* AIO operations. */
@@ -254,27 +254,27 @@
********************************************************************/
/* Disk operations */
-#define SMB_VFS_NEXT_CONNECT(handle, conn, service, user) ((handle)->vfs_next.ops.connect_fn((handle)->vfs_next.handles.connect_hnd, (conn), (service), (user)))
-#define SMB_VFS_NEXT_DISCONNECT(handle, conn) ((handle)->vfs_next.ops.disconnect((handle)->vfs_next.handles.disconnect, (conn)))
-#define SMB_VFS_NEXT_DISK_FREE(handle, conn, path, small_query, bsize, dfree ,dsize) ((handle)->vfs_next.ops.disk_free((handle)->vfs_next.handles.disk_free, (conn), (path), (small_query), (bsize), (dfree), (dsize)))
-#define SMB_VFS_NEXT_GET_QUOTA(handle, conn, qtype, id, qt) ((handle)->vfs_next.ops.get_quota((handle)->vfs_next.handles.get_quota, (conn), (qtype), (id), (qt)))
-#define SMB_VFS_NEXT_SET_QUOTA(handle, conn, qtype, id, qt) ((handle)->vfs_next.ops.set_quota((handle)->vfs_next.handles.set_quota, (conn), (qtype), (id), (qt)))
+#define SMB_VFS_NEXT_CONNECT(handle, service, user) ((handle)->vfs_next.ops.connect_fn((handle)->vfs_next.handles.connect_hnd, (service), (user)))
+#define SMB_VFS_NEXT_DISCONNECT(handle) ((handle)->vfs_next.ops.disconnect((handle)->vfs_next.handles.disconnect))
+#define SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, bsize, dfree ,dsize) ((handle)->vfs_next.ops.disk_free((handle)->vfs_next.handles.disk_free, (path), (small_query), (bsize), (dfree), (dsize)))
+#define SMB_VFS_NEXT_GET_QUOTA(handle, qtype, id, qt) ((handle)->vfs_next.ops.get_quota((handle)->vfs_next.handles.get_quota, (qtype), (id), (qt)))
+#define SMB_VFS_NEXT_SET_QUOTA(handle, qtype, id, qt) ((handle)->vfs_next.ops.set_quota((handle)->vfs_next.handles.set_quota, (qtype), (id), (qt)))
#define SMB_VFS_NEXT_GET_SHADOW_COPY_DATA(handle, fsp, shadow_copy_data ,labels) ((handle)->vfs_next.ops.get_shadow_copy_data((handle)->vfs_next.handles.get_shadow_copy_data,(fsp),(shadow_copy_data),(labels)))
-#define SMB_VFS_NEXT_STATVFS(handle, conn, path, statbuf) ((handle)->vfs_next.ops.statvfs((handle)->vfs_next.handles.statvfs, (conn), (path), (statbuf)))
+#define SMB_VFS_NEXT_STATVFS(handle, path, statbuf) ((handle)->vfs_next.ops.statvfs((handle)->vfs_next.handles.statvfs, (path), (statbuf)))
/* Directory operations */
-#define SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (conn), (fname), (mask), (attr)))
-#define SMB_VFS_NEXT_READDIR(handle, conn, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (conn), (dirp)))
-#define SMB_VFS_NEXT_SEEKDIR(handle, conn, dirp, offset) ((handle)->vfs_next.ops.seekdir((handle)->vfs_next.handles.seekdir, (conn), (dirp), (offset)))
-#define SMB_VFS_NEXT_TELLDIR(handle, conn, dirp) ((handle)->vfs_next.ops.telldir((handle)->vfs_next.handles.telldir, (conn), (dirp)))
-#define SMB_VFS_NEXT_REWINDDIR(handle, conn, dirp) ((handle)->vfs_next.ops.rewind_dir((handle)->vfs_next.handles.rewind_dir, (conn), (dirp)))
-#define SMB_VFS_NEXT_DIR(handle, conn, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (conn), (dirp)))
-#define SMB_VFS_NEXT_MKDIR(handle, conn, path, mode) ((handle)->vfs_next.ops.mkdir((handle)->vfs_next.handles.mkdir,(conn), (path), (mode)))
-#define SMB_VFS_NEXT_RMDIR(handle, conn, path) ((handle)->vfs_next.ops.rmdir((handle)->vfs_next.handles.rmdir, (conn), (path)))
-#define SMB_VFS_NEXT_CLOSEDIR(handle, conn, dir) ((handle)->vfs_next.ops.closedir((handle)->vfs_next.handles.closedir, (conn), dir))
+#define SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (fname), (mask), (attr)))
+#define SMB_VFS_NEXT_READDIR(handle, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (dirp)))
+#define SMB_VFS_NEXT_SEEKDIR(handle, dirp, offset) ((handle)->vfs_next.ops.seekdir((handle)->vfs_next.handles.seekdir, (dirp), (offset)))
+#define SMB_VFS_NEXT_TELLDIR(handle, dirp) ((handle)->vfs_next.ops.telldir((handle)->vfs_next.handles.telldir, (dirp)))
+#define SMB_VFS_NEXT_REWINDDIR(handle, dirp) ((handle)->vfs_next.ops.rewind_dir((handle)->vfs_next.handles.rewind_dir, (dirp)))
+#define SMB_VFS_NEXT_DIR(handle, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (dirp)))
+#define SMB_VFS_NEXT_MKDIR(handle, path, mode) ((handle)->vfs_next.ops.mkdir((handle)->vfs_next.handles.mkdir,(path), (mode)))
+#define SMB_VFS_NEXT_RMDIR(handle, path) ((handle)->vfs_next.ops.rmdir((handle)->vfs_next.handles.rmdir, (path)))
+#define SMB_VFS_NEXT_CLOSEDIR(handle, dir) ((handle)->vfs_next.ops.closedir((handle)->vfs_next.handles.closedir, dir))
/* File operations */
-#define SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode) ((handle)->vfs_next.ops.open((handle)->vfs_next.handles.open, (conn), (fname), (flags), (mode)))
+#define SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode) ((handle)->vfs_next.ops.open((handle)->vfs_next.handles.open, (fname), (fsp), (flags), (mode)))
#define SMB_VFS_NEXT_CLOSE(handle, fsp, fd) ((handle)->vfs_next.ops.close_fn((handle)->vfs_next.handles.close_hnd, (fsp), (fd)))
#define SMB_VFS_NEXT_READ(handle, fsp, fd, data, n) ((handle)->vfs_next.ops.read((handle)->vfs_next.handles.read, (fsp), (fd), (data), (n)))
#define SMB_VFS_NEXT_PREAD(handle, fsp, fd, data, n, off) ((handle)->vfs_next.ops.pread((handle)->vfs_next.handles.pread, (fsp), (fd), (data), (n), (off)))
@@ -282,28 +282,28 @@
#define SMB_VFS_NEXT_PWRITE(handle, fsp, fd, data, n, off) ((handle)->vfs_next.ops.pwrite((handle)->vfs_next.handles.pwrite, (fsp), (fd), (data), (n), (off)))
#define SMB_VFS_NEXT_LSEEK(handle, fsp, fd, offset, whence) ((handle)->vfs_next.ops.lseek((handle)->vfs_next.handles.lseek, (fsp), (fd), (offset), (whence)))
#define SMB_VFS_NEXT_SENDFILE(handle, tofd, fsp, fromfd, header, offset, count) ((handle)->vfs_next.ops.sendfile((handle)->vfs_next.handles.sendfile, (tofd), (fsp), (fromfd), (header), (offset), (count)))
-#define SMB_VFS_NEXT_RENAME(handle, conn, old, new) ((handle)->vfs_next.ops.rename((handle)->vfs_next.handles.rename, (conn), (old), (new)))
+#define SMB_VFS_NEXT_RENAME(handle, old, new) ((handle)->vfs_next.ops.rename((handle)->vfs_next.handles.rename, (old), (new)))
#define SMB_VFS_NEXT_FSYNC(handle, fsp, fd) ((handle)->vfs_next.ops.fsync((handle)->vfs_next.handles.fsync, (fsp), (fd)))
-#define SMB_VFS_NEXT_STAT(handle, conn, fname, sbuf) ((handle)->vfs_next.ops.stat((handle)->vfs_next.handles.stat, (conn), (fname), (sbuf)))
+#define SMB_VFS_NEXT_STAT(handle, fname, sbuf) ((handle)->vfs_next.ops.stat((handle)->vfs_next.handles.stat, (fname), (sbuf)))
#define SMB_VFS_NEXT_FSTAT(handle, fsp, fd, sbuf) ((handle)->vfs_next.ops.fstat((handle)->vfs_next.handles.fstat, (fsp) ,(fd) ,(sbuf)))
-#define SMB_VFS_NEXT_LSTAT(handle, conn, path, sbuf) ((handle)->vfs_next.ops.lstat((handle)->vfs_next.handles.lstat, (conn), (path), (sbuf)))
-#define SMB_VFS_NEXT_UNLINK(handle, conn, path) ((handle)->vfs_next.ops.unlink((handle)->vfs_next.handles.unlink, (conn), (path)))
-#define SMB_VFS_NEXT_CHMOD(handle, conn, path, mode) ((handle)->vfs_next.ops.chmod((handle)->vfs_next.handles.chmod, (conn), (path), (mode)))
+#define SMB_VFS_NEXT_LSTAT(handle, path, sbuf) ((handle)->vfs_next.ops.lstat((handle)->vfs_next.handles.lstat, (path), (sbuf)))
+#define SMB_VFS_NEXT_UNLINK(handle, path) ((handle)->vfs_next.ops.unlink((handle)->vfs_next.handles.unlink, (path)))
+#define SMB_VFS_NEXT_CHMOD(handle, path, mode) ((handle)->vfs_next.ops.chmod((handle)->vfs_next.handles.chmod, (path), (mode)))
#define SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode) ((handle)->vfs_next.ops.fchmod((handle)->vfs_next.handles.fchmod, (fsp), (fd), (mode)))
-#define SMB_VFS_NEXT_CHOWN(handle, conn, path, uid, gid) ((handle)->vfs_next.ops.chown((handle)->vfs_next.handles.chown, (conn), (path), (uid), (gid)))
+#define SMB_VFS_NEXT_CHOWN(handle, path, uid, gid) ((handle)->vfs_next.ops.chown((handle)->vfs_next.handles.chown, (path), (uid), (gid)))
#define SMB_VFS_NEXT_FCHOWN(handle, fsp, fd, uid, gid) ((handle)->vfs_next.ops.fchown((handle)->vfs_next.handles.fchown, (fsp), (fd), (uid), (gid)))
-#define SMB_VFS_NEXT_CHDIR(handle, conn, path) ((handle)->vfs_next.ops.chdir((handle)->vfs_next.handles.chdir, (conn), (path)))
-#define SMB_VFS_NEXT_GETWD(handle, conn, buf) ((handle)->vfs_next.ops.getwd((handle)->vfs_next.handles.getwd, (conn), (buf)))
-#define SMB_VFS_NEXT_UTIME(handle, conn, path, times) ((handle)->vfs_next.ops.utime((handle)->vfs_next.handles.utime, (conn), (path), (times)))
+#define SMB_VFS_NEXT_CHDIR(handle, path) ((handle)->vfs_next.ops.chdir((handle)->vfs_next.handles.chdir, (path)))
+#define SMB_VFS_NEXT_GETWD(handle, buf) ((handle)->vfs_next.ops.getwd((handle)->vfs_next.handles.getwd, (buf)))
+#define SMB_VFS_NEXT_UTIME(handle, path, times) ((handle)->vfs_next.ops.utime((handle)->vfs_next.handles.utime, (path), (times)))
#define SMB_VFS_NEXT_FTRUNCATE(handle, fsp, fd, offset) ((handle)->vfs_next.ops.ftruncate((handle)->vfs_next.handles.ftruncate, (fsp), (fd), (offset)))
#define SMB_VFS_NEXT_LOCK(handle, fsp, fd, op, offset, count, type) ((handle)->vfs_next.ops.lock((handle)->vfs_next.handles.lock, (fsp), (fd) ,(op), (offset), (count), (type)))
#define SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, fd, share_mode)((handle)->vfs_next.ops.lock((handle)->vfs_next.handles.kernel_flock, (fsp), (fd), (share_mode)))
#define SMB_VFS_NEXT_GETLOCK(handle, fsp, fd, poffset, pcount, ptype, ppid) ((handle)->vfs_next.ops.getlock((handle)->vfs_next.handles.getlock, (fsp), (fd), (poffset), (pcount), (ptype), (ppid)))
-#define SMB_VFS_NEXT_SYMLINK(handle, conn, oldpath, newpath) ((handle)->vfs_next.ops.symlink((handle)->vfs_next.handles.symlink, (conn), (oldpath), (newpath)))
-#define SMB_VFS_NEXT_READLINK(handle, conn, path, buf, bufsiz) ((handle)->vfs_next.ops.readlink((handle)->vfs_next.handles.readlink, (conn), (path), (buf), (bufsiz)))
-#define SMB_VFS_NEXT_LINK(handle, conn, oldpath, newpath) ((handle)->vfs_next.ops.link((handle)->vfs_next.handles.link, (conn), (oldpath), (newpath)))
-#define SMB_VFS_NEXT_MKNOD(handle, conn, path, mode, dev) ((handle)->vfs_next.ops.mknod((handle)->vfs_next.handles.mknod, (conn), (path), (mode), (dev)))
-#define SMB_VFS_NEXT_REALPATH(handle, conn, path, resolved_path) ((handle)->vfs_next.ops.realpath((handle)->vfs_next.handles.realpath, (conn), (path), (resolved_path)))
+#define SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath) ((handle)->vfs_next.ops.symlink((handle)->vfs_next.handles.symlink, (oldpath), (newpath)))
+#define SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz) ((handle)->vfs_next.ops.readlink((handle)->vfs_next.handles.readlink, (path), (buf), (bufsiz)))
+#define SMB_VFS_NEXT_LINK(handle, oldpath, newpath) ((handle)->vfs_next.ops.link((handle)->vfs_next.handles.link, (oldpath), (newpath)))
+#define SMB_VFS_NEXT_MKNOD(handle, path, mode, dev) ((handle)->vfs_next.ops.mknod((handle)->vfs_next.handles.mknod, (path), (mode), (dev)))
+#define SMB_VFS_NEXT_REALPATH(handle, path, resolved_path) ((handle)->vfs_next.ops.realpath((handle)->vfs_next.handles.realpath, (path), (resolved_path)))
/* NT ACL operations. */
#define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, fd, security_info, ppdesc) ((handle)->vfs_next.ops.fget_nt_acl((handle)->vfs_next.handles.fget_nt_acl, (fsp), (fd), (security_info), (ppdesc)))
@@ -312,44 +312,44 @@
#define SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, name, security_info_sent, psd) ((handle)->vfs_next.ops.set_nt_acl((handle)->vfs_next.handles.set_nt_acl, (fsp), (name), (security_info_sent), (psd)))
/* POSIX ACL operations. */
-#define SMB_VFS_NEXT_CHMOD_ACL(handle, conn, name, mode) ((handle)->vfs_next.ops.chmod_acl((handle)->vfs_next.handles.chmod_acl, (conn), (name), (mode)))
+#define SMB_VFS_NEXT_CHMOD_ACL(handle, name, mode) ((handle)->vfs_next.ops.chmod_acl((handle)->vfs_next.handles.chmod_acl, (name), (mode)))
#define SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, fd, mode) ((handle)->vfs_next.ops.fchmod_acl((handle)->vfs_next.handles.chmod_acl, (fsp), (fd), (mode)))
-#define SMB_VFS_NEXT_SYS_ACL_GET_ENTRY(handle, conn, theacl, entry_id, entry_p) ((handle)->vfs_next.ops.sys_acl_get_entry((handle)->vfs_next.handles.sys_acl_get_entry, (conn), (theacl), (entry_id), (entry_p)))
-#define SMB_VFS_NEXT_SYS_ACL_GET_TAG_TYPE(handle, conn, entry_d, tag_type_p) ((handle)->vfs_next.ops.sys_acl_get_tag_type((handle)->vfs_next.handles.sys_acl_get_tag_type, (conn), (entry_d), (tag_type_p)))
-#define SMB_VFS_NEXT_SYS_ACL_GET_PERMSET(handle, conn, entry_d, permset_p) ((handle)->vfs_next.ops.sys_acl_get_permset((handle)->vfs_next.handles.sys_acl_get_permset, (conn), (entry_d), (permset_p)))
-#define SMB_VFS_NEXT_SYS_ACL_GET_QUALIFIER(handle, conn, entry_d) ((handle)->vfs_next.ops.sys_acl_get_qualifier((handle)->vfs_next.handles.sys_acl_get_qualifier, (conn), (entry_d)))
-#define SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, conn, path_p, type) ((handle)->vfs_next.ops.sys_acl_get_file((handle)->vfs_next.handles.sys_acl_get_file, (conn), (path_p), (type)))
+#define SMB_VFS_NEXT_SYS_ACL_GET_ENTRY(handle, theacl, entry_id, entry_p) ((handle)->vfs_next.ops.sys_acl_get_entry((handle)->vfs_next.handles.sys_acl_get_entry, (theacl), (entry_id), (entry_p)))
+#define SMB_VFS_NEXT_SYS_ACL_GET_TAG_TYPE(handle, entry_d, tag_type_p) ((handle)->vfs_next.ops.sys_acl_get_tag_type((handle)->vfs_next.handles.sys_acl_get_tag_type, (entry_d), (tag_type_p)))
+#define SMB_VFS_NEXT_SYS_ACL_GET_PERMSET(handle, entry_d, permset_p) ((handle)->vfs_next.ops.sys_acl_get_permset((handle)->vfs_next.handles.sys_acl_get_permset, (entry_d), (permset_p)))
+#define SMB_VFS_NEXT_SYS_ACL_GET_QUALIFIER(handle, entry_d) ((handle)->vfs_next.ops.sys_acl_get_qualifier((handle)->vfs_next.handles.sys_acl_get_qualifier, (entry_d)))
+#define SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type) ((handle)->vfs_next.ops.sys_acl_get_file((handle)->vfs_next.handles.sys_acl_get_file, (path_p), (type)))
#define SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, fd) ((handle)->vfs_next.ops.sys_acl_get_fd((handle)->vfs_next.handles.sys_acl_get_fd, (fsp), (fd)))
-#define SMB_VFS_NEXT_SYS_ACL_CLEAR_PERMS(handle, conn, permset) ((handle)->vfs_next.ops.sys_acl_clear_perms((handle)->vfs_next.handles.sys_acl_clear_perms, (conn), (permset)))
-#define SMB_VFS_NEXT_SYS_ACL_ADD_PERM(handle, conn, permset, perm) ((handle)->vfs_next.ops.sys_acl_add_perm((handle)->vfs_next.handles.sys_acl_add_perm, (conn), (permset), (perm)))
-#define SMB_VFS_NEXT_SYS_ACL_TO_TEXT(handle, conn, theacl, plen) ((handle)->vfs_next.ops.sys_acl_to_text((handle)->vfs_next.handles.sys_acl_to_text, (conn), (theacl), (plen)))
-#define SMB_VFS_NEXT_SYS_ACL_INIT(handle, conn, count) ((handle)->vfs_next.ops.sys_acl_init((handle)->vfs_next.handles.sys_acl_init, (conn), (count)))
-#define SMB_VFS_NEXT_SYS_ACL_CREATE_ENTRY(handle, conn, pacl, pentry) ((handle)->vfs_next.ops.sys_acl_create_entry((handle)->vfs_next.handles.sys_acl_create_entry, (conn), (pacl), (pentry)))
-#define SMB_VFS_NEXT_SYS_ACL_SET_TAG_TYPE(handle, conn, entry, tagtype) ((handle)->vfs_next.ops.sys_acl_set_tag_type((handle)->vfs_next.handles.sys_acl_set_tag_type, (conn), (entry), (tagtype)))
-#define SMB_VFS_NEXT_SYS_ACL_SET_QUALIFIER(handle, conn, entry, qual) ((handle)->vfs_next.ops.sys_acl_set_qualifier((handle)->vfs_next.handles.sys_acl_set_qualifier, (conn), (entry), (qual)))
-#define SMB_VFS_NEXT_SYS_ACL_SET_PERMSET(handle, conn, entry, permset) ((handle)->vfs_next.ops.sys_acl_set_permset((handle)->vfs_next.handles.sys_acl_set_permset, (conn), (entry), (permset)))
-#define SMB_VFS_NEXT_SYS_ACL_VALID(handle, conn, theacl) ((handle)->vfs_next.ops.sys_acl_valid((handle)->vfs_next.handles.sys_acl_valid, (conn), (theacl)))
-#define SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, conn, name, acltype, theacl) ((handle)->vfs_next.ops.sys_acl_set_file((handle)->vfs_next.handles.sys_acl_set_file, (conn), (name), (acltype), (theacl)))
+#define SMB_VFS_NEXT_SYS_ACL_CLEAR_PERMS(handle, permset) ((handle)->vfs_next.ops.sys_acl_clear_perms((handle)->vfs_next.handles.sys_acl_clear_perms, (permset)))
+#define SMB_VFS_NEXT_SYS_ACL_ADD_PERM(handle, permset, perm) ((handle)->vfs_next.ops.sys_acl_add_perm((handle)->vfs_next.handles.sys_acl_add_perm, (permset), (perm)))
+#define SMB_VFS_NEXT_SYS_ACL_TO_TEXT(handle, theacl, plen) ((handle)->vfs_next.ops.sys_acl_to_text((handle)->vfs_next.handles.sys_acl_to_text, (theacl), (plen)))
+#define SMB_VFS_NEXT_SYS_ACL_INIT(handle, count) ((handle)->vfs_next.ops.sys_acl_init((handle)->vfs_next.handles.sys_acl_init, (count)))
+#define SMB_VFS_NEXT_SYS_ACL_CREATE_ENTRY(handle, pacl, pentry) ((handle)->vfs_next.ops.sys_acl_create_entry((handle)->vfs_next.handles.sys_acl_create_entry, (pacl), (pentry)))
+#define SMB_VFS_NEXT_SYS_ACL_SET_TAG_TYPE(handle, entry, tagtype) ((handle)->vfs_next.ops.sys_acl_set_tag_type((handle)->vfs_next.handles.sys_acl_set_tag_type, (entry), (tagtype)))
+#define SMB_VFS_NEXT_SYS_ACL_SET_QUALIFIER(handle, entry, qual) ((handle)->vfs_next.ops.sys_acl_set_qualifier((handle)->vfs_next.handles.sys_acl_set_qualifier, (entry), (qual)))
+#define SMB_VFS_NEXT_SYS_ACL_SET_PERMSET(handle, entry, permset) ((handle)->vfs_next.ops.sys_acl_set_permset((handle)->vfs_next.handles.sys_acl_set_permset, (entry), (permset)))
+#define SMB_VFS_NEXT_SYS_ACL_VALID(handle, theacl) ((handle)->vfs_next.ops.sys_acl_valid((handle)->vfs_next.handles.sys_acl_valid, (theacl)))
+#define SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, acltype, theacl) ((handle)->vfs_next.ops.sys_acl_set_file((handle)->vfs_next.handles.sys_acl_set_file, (name), (acltype), (theacl)))
#define SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, fd, theacl) ((handle)->vfs_next.ops.sys_acl_set_fd((handle)->vfs_next.handles.sys_acl_set_fd, (fsp), (fd), (theacl)))
-#define SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, conn, path) ((handle)->vfs_next.ops.sys_acl_delete_def_file((handle)->vfs_next.handles.sys_acl_delete_def_file, (conn), (path)))
-#define SMB_VFS_NEXT_SYS_ACL_GET_PERM(handle, conn, permset, perm) ((handle)->vfs_next.ops.sys_acl_get_perm((handle)->vfs_next.handles.sys_acl_get_perm, (conn), (permset), (perm)))
-#define SMB_VFS_NEXT_SYS_ACL_FREE_TEXT(handle, conn, text) ((handle)->vfs_next.ops.sys_acl_free_text((handle)->vfs_next.handles.sys_acl_free_text, (conn), (text)))
-#define SMB_VFS_NEXT_SYS_ACL_FREE_ACL(handle, conn, posix_acl) ((handle)->vfs_next.ops.sys_acl_free_acl((handle)->vfs_next.handles.sys_acl_free_acl, (conn), (posix_acl)))
-#define SMB_VFS_NEXT_SYS_ACL_FREE_QUALIFIER(handle, conn, qualifier, tagtype) ((handle)->vfs_next.ops.sys_acl_free_qualifier((handle)->vfs_next.handles.sys_acl_free_qualifier, (conn), (qualifier), (tagtype)))
+#define SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, path) ((handle)->vfs_next.ops.sys_acl_delete_def_file((handle)->vfs_next.handles.sys_acl_delete_def_file, (path)))
+#define SMB_VFS_NEXT_SYS_ACL_GET_PERM(handle, permset, perm) ((handle)->vfs_next.ops.sys_acl_get_perm((handle)->vfs_next.handles.sys_acl_get_perm, (permset), (perm)))
+#define SMB_VFS_NEXT_SYS_ACL_FREE_TEXT(handle, text) ((handle)->vfs_next.ops.sys_acl_free_text((handle)->vfs_next.handles.sys_acl_free_text, (text)))
+#define SMB_VFS_NEXT_SYS_ACL_FREE_ACL(handle, posix_acl) ((handle)->vfs_next.ops.sys_acl_free_acl((handle)->vfs_next.handles.sys_acl_free_acl, (posix_acl)))
+#define SMB_VFS_NEXT_SYS_ACL_FREE_QUALIFIER(handle, qualifier, tagtype) ((handle)->vfs_next.ops.sys_acl_free_qualifier((handle)->vfs_next.handles.sys_acl_free_qualifier, (qualifier), (tagtype)))
/* EA operations. */
-#define SMB_VFS_NEXT_GETXATTR(handle,conn,path,name,value,size) ((handle)->vfs_next.ops.getxattr((handle)->vfs_next.handles.getxattr,(conn),(path),(name),(value),(size)))
-#define SMB_VFS_NEXT_LGETXATTR(handle,conn,path,name,value,size) ((handle)->vfs_next.ops.lgetxattr((handle)->vfs_next.handles.lgetxattr,(conn),(path),(name),(value),(size)))
+#define SMB_VFS_NEXT_GETXATTR(handle,path,name,value,size) ((handle)->vfs_next.ops.getxattr((handle)->vfs_next.handles.getxattr,(path),(name),(value),(size)))
+#define SMB_VFS_NEXT_LGETXATTR(handle,path,name,value,size) ((handle)->vfs_next.ops.lgetxattr((handle)->vfs_next.handles.lgetxattr,(path),(name),(value),(size)))
#define SMB_VFS_NEXT_FGETXATTR(handle,fsp,fd,name,value,size) ((handle)->vfs_next.ops.fgetxattr((handle)->vfs_next.handles.fgetxattr,(fsp),(fd),(name),(value),(size)))
-#define SMB_VFS_NEXT_LISTXATTR(handle,conn,path,list,size) ((handle)->vfs_next.ops.listxattr((handle)->vfs_next.handles.listxattr,(conn),(path),(list),(size)))
-#define SMB_VFS_NEXT_LLISTXATTR(handle,conn,path,list,size) ((handle)->vfs_next.ops.llistxattr((handle)->vfs_next.handles.llistxattr,(conn),(path),(list),(size)))
+#define SMB_VFS_NEXT_LISTXATTR(handle,path,list,size) ((handle)->vfs_next.ops.listxattr((handle)->vfs_next.handles.listxattr,(path),(list),(size)))
+#define SMB_VFS_NEXT_LLISTXATTR(handle,path,list,size) ((handle)->vfs_next.ops.llistxattr((handle)->vfs_next.handles.llistxattr,(path),(list),(size)))
#define SMB_VFS_NEXT_FLISTXATTR(handle,fsp,fd,list,size) ((handle)->vfs_next.ops.flistxattr((handle)->vfs_next.handles.flistxattr,(fsp),(fd),(list),(size)))
-#define SMB_VFS_NEXT_REMOVEXATTR(handle,conn,path,name) ((handle)->vfs_next.ops.removexattr((handle)->vfs_next.handles.removexattr,(conn),(path),(name)))
-#define SMB_VFS_NEXT_LREMOVEXATTR(handle,conn,path,name) ((handle)->vfs_next.ops.lremovexattr((handle)->vfs_next.handles.lremovexattr,(conn),(path),(name)))
+#define SMB_VFS_NEXT_REMOVEXATTR(handle,path,name) ((handle)->vfs_next.ops.removexattr((handle)->vfs_next.handles.removexattr,(path),(name)))
+#define SMB_VFS_NEXT_LREMOVEXATTR(handle,path,name) ((handle)->vfs_next.ops.lremovexattr((handle)->vfs_next.handles.lremovexattr,(path),(name)))
#define SMB_VFS_NEXT_FREMOVEXATTR(handle,fsp,fd,name) ((handle)->vfs_next.ops.fremovexattr((handle)->vfs_next.handles.fremovexattr,(fsp),(fd),(name)))
-#define SMB_VFS_NEXT_SETXATTR(handle,conn,path,name,value,size,flags) ((handle)->vfs_next.ops.setxattr((handle)->vfs_next.handles.setxattr,(conn),(path),(name),(value),(size),(flags)))
-#define SMB_VFS_NEXT_LSETXATTR(handle,conn,path,name,value,size,flags) ((handle)->vfs_next.ops.lsetxattr((handle)->vfs_next.handles.lsetxattr,(conn),(path),(name),(value),(size),(flags)))
+#define SMB_VFS_NEXT_SETXATTR(handle,path,name,value,size,flags) ((handle)->vfs_next.ops.setxattr((handle)->vfs_next.handles.setxattr,(path),(name),(value),(size),(flags)))
+#define SMB_VFS_NEXT_LSETXATTR(handle,path,name,value,size,flags) ((handle)->vfs_next.ops.lsetxattr((handle)->vfs_next.handles.lsetxattr,(path),(name),(value),(size),(flags)))
#define SMB_VFS_NEXT_FSETXATTR(handle,fsp,fd,name,value,size,flags) ((handle)->vfs_next.ops.fsetxattr((handle)->vfs_next.handles.fsetxattr,(fsp),(fd),(name),(value),(size),(flags)))
/* AIO operations. */
diff --git a/source/lib/afs.c b/source/lib/afs.c
index 8a304adcf0c..ea83fdebc25 100644
--- a/source/lib/afs.c
+++ b/source/lib/afs.c
@@ -211,6 +211,7 @@ char *afs_createtoken_str(const char *username, const char *cell)
BOOL afs_login(connection_struct *conn)
{
+ extern userdom_struct current_user_info;
extern struct current_user current_user;
DATA_BLOB ticket;
pstring afs_username;
@@ -222,7 +223,11 @@ BOOL afs_login(connection_struct *conn)
struct ClearToken ct;
pstrcpy(afs_username, lp_afs_username_map());
- standard_sub_conn(conn, afs_username, sizeof(afs_username));
+ standard_sub_advanced(SNUM(conn), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ afs_username, sizeof(afs_username));
user_sid = &current_user.nt_user_token->user_sids[0];
pstring_sub(afs_username, "%s", sid_string_static(user_sid));
diff --git a/source/lib/data_blob.c b/source/lib/data_blob.c
index 73e5357df86..c7eadc1acfb 100644
--- a/source/lib/data_blob.c
+++ b/source/lib/data_blob.c
@@ -102,7 +102,7 @@ void data_blob_free(DATA_BLOB *d)
Clear a DATA_BLOB's contents
*******************************************************************/
-static void data_blob_clear(DATA_BLOB *d)
+void data_blob_clear(DATA_BLOB *d)
{
if (d->data) {
memset(d->data, 0, d->length);
diff --git a/source/lib/sharesec.c b/source/lib/sharesec.c
index 8105d5c37a6..e3216aa4594 100644
--- a/source/lib/sharesec.c
+++ b/source/lib/sharesec.c
@@ -108,7 +108,8 @@ SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, size_t *psize, uint32 def
Pull a security descriptor from the share tdb.
********************************************************************/
-SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
+SEC_DESC *get_share_security( TALLOC_CTX *ctx, const char *servicename,
+ size_t *psize)
{
prs_struct ps;
fstring key;
@@ -122,12 +123,13 @@ SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
/* Fetch security descriptor from tdb */
- slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
+ slprintf(key, sizeof(key)-1, "SECDESC/%s", servicename);
if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 ||
!sec_io_desc("get_share_security", &psd, &ps, 1)) {
- DEBUG(4,("get_share_security: using default secdesc for %s\n", lp_servicename(snum) ));
+ DEBUG(4, ("get_share_security: using default secdesc for %s\n",
+ servicename));
return get_share_security_default(ctx, psize, GENERIC_ALL_ACCESS);
}
@@ -143,7 +145,7 @@ SEC_DESC *get_share_security( TALLOC_CTX *ctx, int snum, size_t *psize)
Store a security descriptor in the share db.
********************************************************************/
-BOOL set_share_security(TALLOC_CTX *ctx, const char *share_name, SEC_DESC *psd)
+BOOL set_share_security(const char *share_name, SEC_DESC *psd)
{
prs_struct ps;
TALLOC_CTX *mem_ctx = NULL;
@@ -186,24 +188,56 @@ out:
Delete a security descriptor.
********************************************************************/
-BOOL delete_share_security(int snum)
+BOOL delete_share_security(const struct share_params *params)
{
TDB_DATA kbuf;
fstring key;
- slprintf(key, sizeof(key)-1, "SECDESC/%s", lp_servicename(snum));
+ slprintf(key, sizeof(key)-1, "SECDESC/%s",
+ lp_servicename(params->service));
kbuf.dptr = key;
kbuf.dsize = strlen(key)+1;
- if (tdb_delete(share_tdb, kbuf) != 0) {
+ if (tdb_trans_delete(share_tdb, kbuf) != 0) {
DEBUG(0,("delete_share_security: Failed to delete entry for share %s\n",
- lp_servicename(snum) ));
+ lp_servicename(params->service) ));
return False;
}
return True;
}
+/*******************************************************************
+ Can this user access with share with the required permissions ?
+********************************************************************/
+
+BOOL share_access_check(const NT_USER_TOKEN *token, const char *sharename,
+ uint32 desired_access)
+{
+ uint32 granted;
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx = NULL;
+ SEC_DESC *psd = NULL;
+ size_t sd_size;
+ BOOL ret = True;
+
+ if (!(mem_ctx = talloc_init("share_access_check"))) {
+ return False;
+ }
+
+ psd = get_share_security(mem_ctx, sharename, &sd_size);
+
+ if (!psd) {
+ TALLOC_FREE(mem_ctx);
+ return True;
+ }
+
+ ret = se_access_check(psd, token, desired_access, &granted, &status);
+
+ talloc_destroy(mem_ctx);
+ return ret;
+}
+
/***************************************************************************
Parse the contents of an acl string from a usershare file.
***************************************************************************/
diff --git a/source/lib/substitute.c b/source/lib/substitute.c
index 3e556cebd1e..25a6a2c4c82 100644
--- a/source/lib/substitute.c
+++ b/source/lib/substitute.c
@@ -415,11 +415,12 @@ static const char *automount_server(const char *user_name)
don't allow expansions.
****************************************************************************/
-void standard_sub_basic(const char *smb_name, char *str, size_t len)
+void standard_sub_basic(const char *smb_name, const char *domain_name,
+ char *str, size_t len)
{
char *s;
- if ( (s = alloc_sub_basic( smb_name, str )) != NULL ) {
+ if ( (s = alloc_sub_basic( smb_name, domain_name, str )) != NULL ) {
strncpy( str, s, len );
}
@@ -432,11 +433,12 @@ void standard_sub_basic(const char *smb_name, char *str, size_t len)
This function will return an allocated string that have to be freed.
****************************************************************************/
-char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, const char *str)
+char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name,
+ const char *domain_name, const char *str)
{
char *a, *t;
- if ( (a = alloc_sub_basic(smb_name, str)) == NULL ) {
+ if ( (a = alloc_sub_basic(smb_name, domain_name, str)) == NULL ) {
return NULL;
}
t = talloc_strdup(mem_ctx, a);
@@ -447,7 +449,8 @@ char *talloc_sub_basic(TALLOC_CTX *mem_ctx, const char *smb_name, const char *st
/****************************************************************************
****************************************************************************/
-char *alloc_sub_basic(const char *smb_name, const char *str)
+char *alloc_sub_basic(const char *smb_name, const char *domain_name,
+ const char *str)
{
char *b, *p, *s, *r, *a_string;
fstring pidstr;
@@ -463,7 +466,7 @@ char *alloc_sub_basic(const char *smb_name, const char *str)
a_string = SMB_STRDUP(str);
if (a_string == NULL) {
- DEBUG(0, ("alloc_sub_specified: Out of memory!\n"));
+ DEBUG(0, ("alloc_sub_basic: Out of memory!\n"));
return NULL;
}
@@ -490,7 +493,7 @@ char *alloc_sub_basic(const char *smb_name, const char *str)
}
break;
case 'D' :
- r = strdup_upper(current_user_info.domain);
+ r = strdup_upper(domain_name);
if (r == NULL) {
goto error;
}
@@ -580,32 +583,20 @@ char *talloc_sub_specified(TALLOC_CTX *mem_ctx,
uid_t uid,
gid_t gid)
{
- char *a, *t;
- a = alloc_sub_specified(input_string, username, domain, uid, gid);
- if (!a) {
+ char *a_string;
+ char *ret_string = NULL;
+ char *b, *p, *s;
+ TALLOC_CTX *tmp_ctx;
+
+ if (!(tmp_ctx = talloc_new(mem_ctx))) {
+ DEBUG(0, ("talloc_new failed\n"));
return NULL;
}
- t = talloc_strdup(mem_ctx, a);
- SAFE_FREE(a);
- return t;
-}
-/****************************************************************************
-****************************************************************************/
-
-char *alloc_sub_specified(const char *input_string,
- const char *username,
- const char *domain,
- uid_t uid,
- gid_t gid)
-{
- char *a_string, *ret_string;
- char *b, *p, *s;
-
- a_string = SMB_STRDUP(input_string);
+ a_string = talloc_strdup(tmp_ctx, input_string);
if (a_string == NULL) {
- DEBUG(0, ("alloc_sub_specified: Out of memory!\n"));
- return NULL;
+ DEBUG(0, ("talloc_sub_specified: Out of memory!\n"));
+ goto done;
}
for (b = s = a_string; (p = strchr_m(s, '%')); s = a_string + (p - b)) {
@@ -614,30 +605,42 @@ char *alloc_sub_specified(const char *input_string,
switch (*(p+1)) {
case 'U' :
- a_string = realloc_string_sub(a_string, "%U", username);
+ a_string = talloc_string_sub(
+ tmp_ctx, a_string, "%U", username);
break;
case 'u' :
- a_string = realloc_string_sub(a_string, "%u", username);
+ a_string = talloc_string_sub(
+ tmp_ctx, a_string, "%u", username);
break;
case 'G' :
if (gid != -1) {
- a_string = realloc_string_sub(a_string, "%G", gidtoname(gid));
+ a_string = talloc_string_sub(
+ tmp_ctx, a_string, "%G",
+ gidtoname(gid));
} else {
- a_string = realloc_string_sub(a_string, "%G", "NO_GROUP");
+ a_string = talloc_string_sub(
+ tmp_ctx, a_string,
+ "%G", "NO_GROUP");
}
break;
case 'g' :
if (gid != -1) {
- a_string = realloc_string_sub(a_string, "%g", gidtoname(gid));
+ a_string = talloc_string_sub(
+ tmp_ctx, a_string, "%g",
+ gidtoname(gid));
} else {
- a_string = realloc_string_sub(a_string, "%g", "NO_GROUP");
+ a_string = talloc_string_sub(
+ tmp_ctx, a_string, "%g", "NO_GROUP");
}
break;
case 'D' :
- a_string = realloc_string_sub(a_string, "%D", domain);
+ a_string = talloc_string_sub(tmp_ctx, a_string,
+ "%D", domain);
break;
case 'N' :
- a_string = realloc_string_sub(a_string, "%N", automount_server(username));
+ a_string = talloc_string_sub(
+ tmp_ctx, a_string, "%N",
+ automount_server(username));
break;
default:
break;
@@ -645,42 +648,27 @@ char *alloc_sub_specified(const char *input_string,
p++;
if (a_string == NULL) {
- return NULL;
+ goto done;
}
}
- ret_string = alloc_sub_basic(username, a_string);
- SAFE_FREE(a_string);
- return ret_string;
-}
+ /* Watch out, using "mem_ctx" here, so all intermediate stuff goes
+ * away with the TALLOC_FREE(tmp_ctx) further down. */
-/****************************************************************************
-****************************************************************************/
+ ret_string = talloc_sub_basic(mem_ctx, username, domain, a_string);
-char *talloc_sub_advanced(TALLOC_CTX *mem_ctx,
- int snum,
- const char *user,
- const char *connectpath,
- gid_t gid,
- const char *smb_name,
- const char *str)
-{
- char *a, *t;
- a = alloc_sub_advanced(snum, user, connectpath, gid, smb_name, str);
- if (!a) {
- return NULL;
- }
- t = talloc_strdup(mem_ctx, a);
- SAFE_FREE(a);
- return t;
+ done:
+ TALLOC_FREE(tmp_ctx);
+ return ret_string;
}
/****************************************************************************
****************************************************************************/
-char *alloc_sub_advanced(int snum, const char *user,
- const char *connectpath, gid_t gid,
- const char *smb_name, const char *str)
+static char *alloc_sub_advanced(const char *servicename, const char *user,
+ const char *connectpath, gid_t gid,
+ const char *smb_name, const char *domain_name,
+ const char *str)
{
char *a_string, *ret_string;
char *b, *p, *s, *h;
@@ -707,7 +695,7 @@ char *alloc_sub_advanced(int snum, const char *user,
a_string = realloc_string_sub(a_string, "%P", connectpath);
break;
case 'S':
- a_string = realloc_string_sub(a_string, "%S", lp_servicename(snum));
+ a_string = realloc_string_sub(a_string, "%S", servicename);
break;
case 'g':
a_string = realloc_string_sub(a_string, "%g", gidtoname(gid));
@@ -724,7 +712,8 @@ char *alloc_sub_advanced(int snum, const char *user,
* "path =" string in [homes] and so needs the
* service name, not the username. */
case 'p':
- a_string = realloc_string_sub(a_string, "%p", automount_path(lp_servicename(snum)));
+ a_string = realloc_string_sub(a_string, "%p",
+ automount_path(servicename));
break;
default:
@@ -737,67 +726,43 @@ char *alloc_sub_advanced(int snum, const char *user,
}
}
- ret_string = alloc_sub_basic(smb_name, a_string);
+ ret_string = alloc_sub_basic(smb_name, domain_name, a_string);
SAFE_FREE(a_string);
return ret_string;
}
-/****************************************************************************
- Do some standard substitutions in a string.
-****************************************************************************/
+/*
+ * This obviously is inefficient and needs to be merged into
+ * alloc_sub_advanced...
+ */
-void standard_sub_conn(connection_struct *conn, char *str, size_t len)
+char *talloc_sub_advanced(TALLOC_CTX *mem_ctx,
+ const char *servicename, const char *user,
+ const char *connectpath, gid_t gid,
+ const char *smb_name, const char *domain_name,
+ const char *str)
{
- char *s;
-
- s = alloc_sub_advanced(SNUM(conn), conn->user, conn->connectpath,
- conn->gid, smb_user_name, str);
+ char *a, *t;
- if ( s ) {
- strncpy( str, s, len );
- SAFE_FREE( s );
+ if (!(a = alloc_sub_advanced(servicename, user, connectpath, gid,
+ smb_name, domain_name, str))) {
+ return NULL;
}
+ t = talloc_strdup(mem_ctx, a);
+ SAFE_FREE(a);
+ return t;
}
-/****************************************************************************
-****************************************************************************/
-
-char *talloc_sub_conn(TALLOC_CTX *mem_ctx, connection_struct *conn, const char *str)
-{
- return talloc_sub_advanced(mem_ctx, SNUM(conn), conn->user,
- conn->connectpath, conn->gid,
- smb_user_name, str);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-char *alloc_sub_conn(connection_struct *conn, const char *str)
-{
- return alloc_sub_advanced(SNUM(conn), conn->user, conn->connectpath,
- conn->gid, smb_user_name, str);
-}
-
-/****************************************************************************
- Like standard_sub but by snum.
-****************************************************************************/
-void standard_sub_snum(int snum, char *str, size_t len)
+void standard_sub_advanced(const char *servicename, const char *user,
+ const char *connectpath, gid_t gid,
+ const char *smb_name, const char *domain_name,
+ char *str, size_t len)
{
- static uid_t cached_uid = -1;
- static fstring cached_user;
char *s;
- /* calling uidtoname() on every substitute would be too expensive, so
- we cache the result here as nearly every call is for the same uid */
-
- if (cached_uid != current_user.ut.uid) {
- fstrcpy(cached_user, uidtoname(current_user.ut.uid));
- cached_uid = current_user.ut.uid;
- }
-
- s = alloc_sub_advanced(snum, cached_user, "", current_user.ut.gid,
- smb_user_name, str);
+ s = alloc_sub_advanced(servicename, user, connectpath,
+ gid, smb_name, domain_name, str);
if ( s ) {
strncpy( str, s, len );
diff --git a/source/lib/util.c b/source/lib/util.c
index dde637cf703..19c6cab5b28 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -1059,9 +1059,11 @@ void *realloc_array(void *p, size_t el_size, unsigned int count, BOOL free_old_o
****************************************************************************/
void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
- void *element, void **array, uint32 *num_elements,
+ void *element, void *_array, uint32 *num_elements,
ssize_t *array_size)
{
+ void **array = (void **)_array;
+
if (*array_size < 0) {
return;
}
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index 08be2cd2a11..fc13b75cc57 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -33,7 +33,7 @@
* Internal function to get the next token from a string, return False if none
* found. Handles double-quotes. This is the work horse function called by
* next_token() and next_token_no_ltrim().
- *
+ *
* Based on a routine by GJC@VILLAGE.COM.
* Extensively modified by Andrew.Tridgell@anu.edu.au
*/
@@ -59,8 +59,8 @@ static BOOL next_token_internal(const char **ptr,
/* find the first non sep char, if left-trimming is requested */
if (ltrim) {
- while (*s && strchr_m(sep,*s))
- s++;
+ while (*s && strchr_m(sep,*s))
+ s++;
}
/* nothing left? */
@@ -1943,13 +1943,14 @@ int str_list_count( const char **list )
for the work
*****************************************************************************/
-BOOL str_list_sub_basic( char **list, const char *smb_name )
+BOOL str_list_sub_basic( char **list, const char *smb_name,
+ const char *domain_name )
{
char *s, *tmpstr;
while ( *list ) {
s = *list;
- tmpstr = alloc_sub_basic(smb_name, s);
+ tmpstr = alloc_sub_basic(smb_name, domain_name, s);
if ( !tmpstr ) {
DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
return False;
diff --git a/source/libmsrpc/cac_lsarpc.c b/source/libmsrpc/cac_lsarpc.c
index eb1a9613734..2e3eb276d5a 100644
--- a/source/libmsrpc/cac_lsarpc.c
+++ b/source/libmsrpc/cac_lsarpc.c
@@ -1,3 +1,4 @@
+
/*
* Unix SMB/CIFS implementation.
* MS-RPC client library implementation (LSA pipe)
@@ -21,1061 +22,1212 @@
#include "libmsrpc.h"
#include "libsmb_internal.h"
-int cac_LsaOpenPolicy(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaOpenPolicy *op) {
- SMBCSRV *srv = NULL;
- POLICY_HND *policy = NULL;
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!mem_ctx || !op) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- op->out.pol = NULL;
-
- srv = cac_GetServer(hnd);
- if(!srv) {
- hnd->status = NT_STATUS_INVALID_CONNECTION;
- return CAC_FAILURE;
- }
-
- /*see if there is already an active session on this pipe, if not then open one*/
- if(!hnd->_internal.pipes[PI_LSARPC]) {
- pipe_hnd = cli_rpc_pipe_open_noauth(&(srv->cli), PI_LSARPC, &(hnd->status));
-
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_UNSUCCESSFUL;
- return CAC_FAILURE;
- }
-
- hnd->_internal.pipes[PI_LSARPC] = True;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- policy = TALLOC_P(mem_ctx, POLICY_HND);
- if(!policy) {
- errno = ENOMEM;
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- /*need to make sure that our nt status is good otherwise check might fail below*/
- hnd->status = NT_STATUS_OK;
-
- if(hnd->_internal.srv_level >= SRV_WIN_2K) {
-
- /*try using open_policy2, if this fails try again in next block using open_policy, if that works then adjust hnd->_internal.srv_level*/
-
- /*we shouldn't need to modify the access mask to make it work here*/
- hnd->status = rpccli_lsa_open_policy2(pipe_hnd, mem_ctx, op->in.security_qos, op->in.access, policy);
-
- }
-
- if(hnd->_internal.srv_level < SRV_WIN_2K || !NT_STATUS_IS_OK(hnd->status)) {
- hnd->status = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, op->in.security_qos, op->in.access, policy);
-
- if(hnd->_internal.srv_level > SRV_WIN_NT4 && NT_STATUS_IS_OK(hnd->status)) {
- /*change the server level to 1*/
- hnd->_internal.srv_level = SRV_WIN_NT4;
- }
-
- }
-
- if(!NT_STATUS_IS_OK(hnd->status)) {
- return CAC_FAILURE;
- }
-
- op->out.pol = policy;
-
- return CAC_SUCCESS;
+int cac_LsaOpenPolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaOpenPolicy *op )
+{
+ SMBCSRV *srv = NULL;
+ POLICY_HND *policy = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !mem_ctx || !op ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ op->out.pol = NULL;
+
+ srv = cac_GetServer( hnd );
+ if ( !srv ) {
+ hnd->status = NT_STATUS_INVALID_CONNECTION;
+ return CAC_FAILURE;
+ }
+
+ /*see if there is already an active session on this pipe, if not then open one */
+ if ( !hnd->_internal.pipes[PI_LSARPC] ) {
+ pipe_hnd =
+ cli_rpc_pipe_open_noauth( srv->cli, PI_LSARPC,
+ &hnd->status );
+
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_UNSUCCESSFUL;
+ return CAC_FAILURE;
+ }
+
+ hnd->_internal.pipes[PI_LSARPC] = True;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ policy = TALLOC_P( mem_ctx, POLICY_HND );
+ if ( !policy ) {
+ errno = ENOMEM;
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ /*need to make sure that our nt status is good otherwise check might fail below */
+ hnd->status = NT_STATUS_OK;
+
+ if ( hnd->_internal.srv_level >= SRV_WIN_2K ) {
+
+ /*try using open_policy2, if this fails try again in next block using open_policy, if that works then adjust hnd->_internal.srv_level */
+
+ /*we shouldn't need to modify the access mask to make it work here */
+ hnd->status =
+ rpccli_lsa_open_policy2( pipe_hnd, mem_ctx,
+ op->in.security_qos,
+ op->in.access, policy );
+
+ }
+
+ if ( hnd->_internal.srv_level < SRV_WIN_2K
+ || !NT_STATUS_IS_OK( hnd->status ) ) {
+ hnd->status =
+ rpccli_lsa_open_policy( pipe_hnd, mem_ctx,
+ op->in.security_qos,
+ op->in.access, policy );
+
+ if ( hnd->_internal.srv_level > SRV_WIN_NT4
+ && NT_STATUS_IS_OK( hnd->status ) ) {
+ /*change the server level to 1 */
+ hnd->_internal.srv_level = SRV_WIN_NT4;
+ }
+
+ }
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ return CAC_FAILURE;
+ }
+
+ op->out.pol = policy;
+
+ return CAC_SUCCESS;
}
-int cac_LsaClosePolicy(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *pol) {
+int cac_LsaClosePolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ POLICY_HND * pol )
+{
+
+ struct rpc_pipe_client *pipe_hnd = NULL;
- struct rpc_pipe_client *pipe_hnd = NULL;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd)
- return CAC_FAILURE;
-
- if(!pol)
- return CAC_SUCCESS; /*if the policy handle doesnt exist then it's already closed*/
+ if ( !pol )
+ return CAC_SUCCESS; /*if the policy handle doesnt exist then it's already closed */
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_lsa_close(pipe_hnd, mem_ctx, pol);
+ hnd->status = rpccli_lsa_Close( pipe_hnd, mem_ctx, pol );
- TALLOC_FREE(pol);
+ TALLOC_FREE( pol );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_LsaGetNamesFromSids(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaGetNamesFromSids *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- int result = -1;
-
- int i;
-
- /*buffers for outputs*/
- char **domains = NULL;
- char **names = NULL;
- uint32 *types = NULL;
-
- CacSidInfo *sids_out = NULL;
- DOM_SID *unknown_out = NULL;
- int num_unknown = 0;
-
- int num_sids;
-
- int found_idx;
- int unknown_idx;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!mem_ctx || !op || !op->in.pol || !op->in.sids) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- num_sids = op->in.num_sids;
-
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
-
-
- /*now actually lookup the names*/
- hnd->status = rpccli_lsa_lookup_sids(pipe_hnd, mem_ctx, op->in.pol, op->in.num_sids,
- op->in.sids, &domains, &names, &types);
-
- if(NT_STATUS_IS_OK(hnd->status)) {
- /*this is the easy part, just make the out.sids array*/
- sids_out = TALLOC_ARRAY(mem_ctx, CacSidInfo, num_sids);
- if(!sids_out) {
- errno = ENOMEM;
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- for(i = 0; i < num_sids; i++) {
- sids_out[i].sid = op->in.sids[i];
- sids_out[i].name = names[i];
- sids_out[i].domain = domains[i];
- }
-
- result = CAC_SUCCESS;
- }
- else if(NT_STATUS_V(hnd->status) == NT_STATUS_V(STATUS_SOME_UNMAPPED)) {
- /*first find out how many couldn't be looked up*/
-
- for(i = 0; i < num_sids; i++) {
- if(names[i] == NULL) {
- num_unknown++;
- }
- }
-
- if( num_unknown >= num_sids) {
- hnd->status = NT_STATUS_UNSUCCESSFUL;
- return CAC_FAILURE;
- }
-
- sids_out = TALLOC_ARRAY(mem_ctx, CacSidInfo, (num_sids - num_unknown));
- if(!sids_out) {
- errno = ENOMEM;
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- unknown_out = TALLOC_ARRAY(mem_ctx, DOM_SID, num_unknown);
- if(!unknown_out) {
- errno = ENOMEM;
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- found_idx = unknown_idx = 0;
-
- /*now we can actually do the real work*/
- for(i = 0; i < num_sids; i++) {
- if(names[i] != NULL) {
- sids_out[found_idx].sid = op->in.sids[i];
- sids_out[found_idx].name = names[i];
- sids_out[found_idx].domain = domains[i];
-
- found_idx++;
- }
- else { /*then this one didnt work out*/
- unknown_out[unknown_idx] = op->in.sids[i];
-
- unknown_idx++;
- }
- }
-
- result = CAC_PARTIAL_SUCCESS;
- }
- else { /*then it failed for some reason*/
- return CAC_FAILURE;
- }
-
- op->out.num_found = num_sids - num_unknown;
- op->out.sids = sids_out;
- op->out.unknown = unknown_out;
-
- return result;
-
+int cac_LsaGetNamesFromSids( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaGetNamesFromSids *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ int result = -1;
+
+ int i;
+
+ /*buffers for outputs */
+ char **domains = NULL;
+ char **names = NULL;
+ enum lsa_SidType *types = NULL;
+
+ CacSidInfo *sids_out = NULL;
+ DOM_SID *unknown_out = NULL;
+ int num_unknown = 0;
+
+ int num_sids;
+
+ int found_idx;
+ int unknown_idx;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !mem_ctx || !op || !op->in.pol || !op->in.sids ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ num_sids = op->in.num_sids;
+
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+
+
+ /*now actually lookup the names */
+ hnd->status =
+ rpccli_lsa_lookup_sids( pipe_hnd, mem_ctx, op->in.pol,
+ op->in.num_sids, op->in.sids,
+ &domains, &names, &types );
+
+ if ( NT_STATUS_IS_OK( hnd->status ) ) {
+ /*this is the easy part, just make the out.sids array */
+ sids_out = TALLOC_ARRAY( mem_ctx, CacSidInfo, num_sids );
+ if ( !sids_out ) {
+ errno = ENOMEM;
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ for ( i = 0; i < num_sids; i++ ) {
+ sids_out[i].sid = op->in.sids[i];
+ sids_out[i].name = names[i];
+ sids_out[i].domain = domains[i];
+ }
+
+ result = CAC_SUCCESS;
+ } else if ( NT_STATUS_V( hnd->status ) ==
+ NT_STATUS_V( STATUS_SOME_UNMAPPED ) ) {
+ /*first find out how many couldn't be looked up */
+
+ for ( i = 0; i < num_sids; i++ ) {
+ if ( names[i] == NULL ) {
+ num_unknown++;
+ }
+ }
+
+ if ( num_unknown >= num_sids ) {
+ hnd->status = NT_STATUS_UNSUCCESSFUL;
+ return CAC_FAILURE;
+ }
+
+ sids_out =
+ TALLOC_ARRAY( mem_ctx, CacSidInfo,
+ ( num_sids - num_unknown ) );
+ if ( !sids_out ) {
+ errno = ENOMEM;
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ unknown_out = TALLOC_ARRAY( mem_ctx, DOM_SID, num_unknown );
+ if ( !unknown_out ) {
+ errno = ENOMEM;
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ found_idx = unknown_idx = 0;
+
+ /*now we can actually do the real work */
+ for ( i = 0; i < num_sids; i++ ) {
+ if ( names[i] != NULL ) {
+ sids_out[found_idx].sid = op->in.sids[i];
+ sids_out[found_idx].name = names[i];
+ sids_out[found_idx].domain = domains[i];
+
+ found_idx++;
+ } else { /*then this one didnt work out */
+ unknown_out[unknown_idx] = op->in.sids[i];
+
+ unknown_idx++;
+ }
+ }
+
+ result = CAC_PARTIAL_SUCCESS;
+ } else { /*then it failed for some reason */
+ return CAC_FAILURE;
+ }
+
+ op->out.num_found = num_sids - num_unknown;
+ op->out.sids = sids_out;
+ op->out.unknown = unknown_out;
+
+ return result;
+
}
-int cac_LsaGetSidsFromNames(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaGetSidsFromNames *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
- int result = -1;
-
- int i;
-
- /*buffers for outputs*/
- DOM_SID *sids = NULL;
- uint32 *types = NULL;
-
- CacSidInfo *sids_out = NULL;
- char **unknown_out = NULL;
- int num_unknown = 0;
-
- int num_names;
-
- int found_idx = 0;
- int unknown_idx = 0;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!mem_ctx || !op || !op->in.pol || !op->in.names) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- num_names = op->in.num_names;
-
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
-
- /*now actually lookup the names*/
- hnd->status = rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, num_names,
- (const char **)op->in.names, NULL, &sids, &types);
-
- if(NT_STATUS_IS_OK(hnd->status)) {
- /*this is the easy part, just make the out.sids array*/
- sids_out = TALLOC_ARRAY(mem_ctx, CacSidInfo, num_names);
- if(!sids_out) {
- errno = ENOMEM;
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- for(i = 0; i < num_names; i++) {
- sids_out[i].sid = sids[i];
- sids_out[i].name = talloc_strdup(mem_ctx, op->in.names[i]);
- sids_out[i].domain = NULL;
- }
-
- result = CAC_SUCCESS;
- }
- else if(NT_STATUS_V(hnd->status) == NT_STATUS_V(STATUS_SOME_UNMAPPED)) {
- /*first find out how many couldn't be looked up*/
-
- for(i = 0; i < num_names; i++) {
- if(types[i] == SID_NAME_UNKNOWN) {
- num_unknown++;
- }
- }
-
- if( num_unknown >= num_names) {
- hnd->status = NT_STATUS_UNSUCCESSFUL;
- return CAC_FAILURE;
- }
-
- sids_out = TALLOC_ARRAY(mem_ctx, CacSidInfo, (num_names - num_unknown));
- if(!sids_out) {
- errno = ENOMEM;
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- unknown_out = TALLOC_ARRAY(mem_ctx, char *, num_unknown);
- if(!unknown_out) {
- errno = ENOMEM;
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- unknown_idx = found_idx = 0;
-
- /*now we can actually do the real work*/
- for(i = 0; i < num_names; i++) {
- if(types[i] != SID_NAME_UNKNOWN) {
- sids_out[found_idx].sid = sids[i];
- sids_out[found_idx].name = talloc_strdup(mem_ctx, op->in.names[i]);
- sids_out[found_idx].domain = NULL;
-
- found_idx++;
- }
- else { /*then this one didnt work out*/
- unknown_out[unknown_idx] = talloc_strdup(mem_ctx, op->in.names[i]);
-
- unknown_idx++;
- }
- }
-
- result = CAC_PARTIAL_SUCCESS;
- }
- else { /*then it failed for some reason*/
- return CAC_FAILURE;
- }
-
- op->out.num_found = num_names - num_unknown;
- op->out.sids = sids_out;
- op->out.unknown = unknown_out;
-
- return result;
-
+int cac_LsaGetSidsFromNames( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaGetSidsFromNames *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ int result = -1;
+
+ int i;
+
+ /*buffers for outputs */
+ DOM_SID *sids = NULL;
+ enum lsa_SidType *types = NULL;
+
+ CacSidInfo *sids_out = NULL;
+ char **unknown_out = NULL;
+ int num_unknown = 0;
+
+ int num_names;
+
+ int found_idx = 0;
+ int unknown_idx = 0;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !mem_ctx || !op || !op->in.pol || !op->in.names ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ num_names = op->in.num_names;
+
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+
+ /*now actually lookup the names */
+ hnd->status =
+ rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol,
+ num_names,
+ ( const char ** ) op->in.names, NULL,
+ &sids, &types );
+
+ if ( NT_STATUS_IS_OK( hnd->status ) ) {
+ /*this is the easy part, just make the out.sids array */
+ sids_out = TALLOC_ARRAY( mem_ctx, CacSidInfo, num_names );
+ if ( !sids_out ) {
+ errno = ENOMEM;
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ for ( i = 0; i < num_names; i++ ) {
+ sids_out[i].sid = sids[i];
+ sids_out[i].name =
+ talloc_strdup( mem_ctx, op->in.names[i] );
+ sids_out[i].domain = NULL;
+ }
+
+ result = CAC_SUCCESS;
+ } else if ( NT_STATUS_V( hnd->status ) ==
+ NT_STATUS_V( STATUS_SOME_UNMAPPED ) ) {
+ /*first find out how many couldn't be looked up */
+
+ for ( i = 0; i < num_names; i++ ) {
+ if ( types[i] == SID_NAME_UNKNOWN ) {
+ num_unknown++;
+ }
+ }
+
+ if ( num_unknown >= num_names ) {
+ hnd->status = NT_STATUS_UNSUCCESSFUL;
+ return CAC_FAILURE;
+ }
+
+ sids_out =
+ TALLOC_ARRAY( mem_ctx, CacSidInfo,
+ ( num_names - num_unknown ) );
+ if ( !sids_out ) {
+ errno = ENOMEM;
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ unknown_out = TALLOC_ARRAY( mem_ctx, char *, num_unknown );
+ if ( !unknown_out ) {
+ errno = ENOMEM;
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ unknown_idx = found_idx = 0;
+
+ /*now we can actually do the real work */
+ for ( i = 0; i < num_names; i++ ) {
+ if ( types[i] != SID_NAME_UNKNOWN ) {
+ sids_out[found_idx].sid = sids[i];
+ sids_out[found_idx].name =
+ talloc_strdup( mem_ctx,
+ op->in.names[i] );
+ sids_out[found_idx].domain = NULL;
+
+ found_idx++;
+ } else { /*then this one didnt work out */
+ unknown_out[unknown_idx] =
+ talloc_strdup( mem_ctx,
+ op->in.names[i] );
+
+ unknown_idx++;
+ }
+ }
+
+ result = CAC_PARTIAL_SUCCESS;
+ } else { /*then it failed for some reason */
+ return CAC_FAILURE;
+ }
+
+ op->out.num_found = num_names - num_unknown;
+ op->out.sids = sids_out;
+ op->out.unknown = unknown_out;
+
+ return result;
+
}
-int cac_LsaFetchSid(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaFetchSid *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
- int result = -1;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!mem_ctx || !op || !op->in.pol) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- op->out.local_sid = NULL;
- op->out.domain_sid = NULL;
-
- if( (op->in.info_class & CAC_LOCAL_INFO) == CAC_LOCAL_INFO) {
- DOM_SID *local_sid = NULL;
- char *dom_name = NULL;
-
- hnd->status = rpccli_lsa_query_info_policy( pipe_hnd, mem_ctx, op->in.pol, CAC_LOCAL_INFO, &dom_name, &local_sid);
-
- if(!NT_STATUS_IS_OK(hnd->status)) {
- result = CAC_FAILURE;
- goto domain;
- }
-
- op->out.local_sid = talloc(mem_ctx, CacSidInfo);
- if(!op->out.local_sid) {
- hnd->status = NT_STATUS_NO_MEMORY;
- result = CAC_FAILURE;
- goto domain;
- }
-
- op->out.local_sid->domain = dom_name;
-
- sid_copy(&op->out.local_sid->sid, local_sid);
- TALLOC_FREE(local_sid);
- }
-
-domain:
-
- if( (op->in.info_class & CAC_DOMAIN_INFO) == CAC_DOMAIN_INFO) {
- DOM_SID *domain_sid;
- char *dom_name;
-
- hnd->status = rpccli_lsa_query_info_policy( pipe_hnd, mem_ctx, op->in.pol, CAC_DOMAIN_INFO, &dom_name, &domain_sid);
- if(!NT_STATUS_IS_OK(hnd->status)) {
- /*if we succeeded above, report partial success*/
- result = CAC_FAILURE;
- goto done;
- }
- else if(result == CAC_FAILURE) {
- /*if we failed above but succeded here then report partial success*/
- result = CAC_PARTIAL_SUCCESS;
- }
-
- op->out.domain_sid = talloc(mem_ctx, CacSidInfo);
- if(!op->out.domain_sid) {
- hnd->status = NT_STATUS_NO_MEMORY;
- result = CAC_FAILURE;
- goto done;
- }
-
- op->out.domain_sid->domain = dom_name;
- sid_copy(&op->out.domain_sid->sid, domain_sid);
- TALLOC_FREE(domain_sid);
- }
-
-done:
- return result;
+int cac_LsaFetchSid( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaFetchSid *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ int result = -1;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !mem_ctx || !op || !op->in.pol ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ op->out.local_sid = NULL;
+ op->out.domain_sid = NULL;
+
+ if ( ( op->in.info_class & CAC_LOCAL_INFO ) == CAC_LOCAL_INFO ) {
+ DOM_SID *local_sid = NULL;
+ char *dom_name = NULL;
+
+ hnd->status =
+ rpccli_lsa_query_info_policy( pipe_hnd, mem_ctx,
+ op->in.pol,
+ CAC_LOCAL_INFO,
+ &dom_name, &local_sid );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ result = CAC_FAILURE;
+ goto domain;
+ }
+
+ op->out.local_sid = talloc( mem_ctx, CacSidInfo );
+ if ( !op->out.local_sid ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ result = CAC_FAILURE;
+ goto domain;
+ }
+
+ op->out.local_sid->domain = dom_name;
+
+ sid_copy( &op->out.local_sid->sid, local_sid );
+ TALLOC_FREE( local_sid );
+ }
+
+ domain:
+
+ if ( ( op->in.info_class & CAC_DOMAIN_INFO ) == CAC_DOMAIN_INFO ) {
+ DOM_SID *domain_sid;
+ char *dom_name;
+
+ hnd->status =
+ rpccli_lsa_query_info_policy( pipe_hnd, mem_ctx,
+ op->in.pol,
+ CAC_DOMAIN_INFO,
+ &dom_name,
+ &domain_sid );
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ /*if we succeeded above, report partial success */
+ result = CAC_FAILURE;
+ goto done;
+ } else if ( result == CAC_FAILURE ) {
+ /*if we failed above but succeded here then report partial success */
+ result = CAC_PARTIAL_SUCCESS;
+ }
+
+ op->out.domain_sid = talloc( mem_ctx, CacSidInfo );
+ if ( !op->out.domain_sid ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ result = CAC_FAILURE;
+ goto done;
+ }
+
+ op->out.domain_sid->domain = dom_name;
+ sid_copy( &op->out.domain_sid->sid, domain_sid );
+ TALLOC_FREE( domain_sid );
+ }
+
+ done:
+ return result;
}
-int cac_LsaQueryInfoPolicy(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaQueryInfoPolicy *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- char *domain_name = NULL;
- char *dns_name = NULL;
- char *forest_name = NULL;
- struct GUID *domain_guid = NULL;
- DOM_SID *domain_sid = NULL;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || !op->in.pol) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- /*only works if info_class parm is 12*/
- hnd->status = rpccli_lsa_query_info_policy2(pipe_hnd, mem_ctx, op->in.pol, 12,
- &domain_name, &dns_name, &forest_name, &domain_guid, &domain_sid);
-
- if(!NT_STATUS_IS_OK(hnd->status)) {
- return CAC_FAILURE;
- }
-
- op->out.domain_name = domain_name;
- op->out.dns_name = dns_name;
- op->out.forest_name = forest_name;
- op->out.domain_guid = domain_guid;
- op->out.domain_sid = domain_sid;
-
- return CAC_SUCCESS;
+int cac_LsaQueryInfoPolicy( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaQueryInfoPolicy *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ char *domain_name = NULL;
+ char *dns_name = NULL;
+ char *forest_name = NULL;
+ struct GUID *domain_guid = NULL;
+ DOM_SID *domain_sid = NULL;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || !op->in.pol ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ /*only works if info_class parm is 12 */
+ hnd->status =
+ rpccli_lsa_query_info_policy2( pipe_hnd, mem_ctx, op->in.pol,
+ 12, &domain_name, &dns_name,
+ &forest_name, &domain_guid,
+ &domain_sid );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ return CAC_FAILURE;
+ }
+
+ op->out.domain_name = domain_name;
+ op->out.dns_name = dns_name;
+ op->out.forest_name = forest_name;
+ op->out.domain_guid = domain_guid;
+ op->out.domain_sid = domain_sid;
+
+ return CAC_SUCCESS;
}
-int cac_LsaEnumSids(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumSids *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_LsaEnumSids( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaEnumSids *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- uint32 num_sids;
- DOM_SID *sids;
+ uint32 num_sids;
+ DOM_SID *sids;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.pol) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.pol ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_lsa_enum_sids(pipe_hnd, mem_ctx, op->in.pol, &(op->out.resume_idx), op->in.pref_max_sids, &num_sids, &sids);
+ hnd->status =
+ rpccli_lsa_enum_sids( pipe_hnd, mem_ctx, op->in.pol,
+ &( op->out.resume_idx ),
+ op->in.pref_max_sids, &num_sids,
+ &sids );
- if(!NT_STATUS_IS_OK(hnd->status)) {
- return CAC_FAILURE;
- }
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ return CAC_FAILURE;
+ }
- op->out.num_sids = num_sids;
- op->out.sids = sids;
+ op->out.num_sids = num_sids;
+ op->out.sids = sids;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_LsaEnumAccountRights(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumAccountRights *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_LsaEnumAccountRights( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaEnumAccountRights *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- uint32 count = 0;
- char **privs = NULL;
+ uint32 count = 0;
+ char **privs = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op->in.pol) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op->in.pol ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- if(!op->in.name && !op->in.sid) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op->in.name && !op->in.sid ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(op->in.name && !op->in.sid) {
- DOM_SID *user_sid = NULL;
- uint32 *type;
+ if ( op->in.name && !op->in.sid ) {
+ DOM_SID *user_sid = NULL;
+ enum lsa_SidType *type;
- /*lookup the SID*/
- hnd->status = rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, 1, (const char **)&(op->in.name), NULL, &user_sid, &type);
+ /*lookup the SID */
+ hnd->status =
+ rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
+ op->in.pol, 1,
+ ( const char ** ) &( op->in.
+ name ),
+ NULL, &user_sid, &type );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->in.sid = user_sid;
- }
-
- hnd->status = rpccli_lsa_enum_account_rights( pipe_hnd, mem_ctx, op->in.pol, op->in.sid,
- &count, &privs);
+ op->in.sid = user_sid;
+ }
- if(!NT_STATUS_IS_OK(hnd->status)) {
- return CAC_FAILURE;
- }
+ hnd->status =
+ rpccli_lsa_enum_account_rights( pipe_hnd, mem_ctx, op->in.pol,
+ op->in.sid, &count, &privs );
- op->out.num_privs = count;
- op->out.priv_names = privs;
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ return CAC_FAILURE;
+ }
- return CAC_SUCCESS;
-}
+ op->out.num_privs = count;
+ op->out.priv_names = privs;
-int cac_LsaEnumTrustedDomains(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumTrustedDomains *op) {
- struct rpc_pipe_client *pipe_hnd;
-
- uint32 num_domains;
- char **domain_names;
- DOM_SID *domain_sids;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op->in.pol) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- hnd->status = rpccli_lsa_enum_trust_dom( pipe_hnd, mem_ctx, op->in.pol, &(op->out.resume_idx), &num_domains, &domain_names, &domain_sids);
-
- if(!NT_STATUS_IS_OK(hnd->status)) {
- return CAC_FAILURE;
- }
-
- op->out.num_domains = num_domains;
- op->out.domain_names = domain_names;
- op->out.domain_sids = domain_sids;
-
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_LsaOpenTrustedDomain(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaOpenTrustedDomain *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- POLICY_HND *dom_pol = NULL;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op->in.pol || !op->in.access || !op->in.domain_sid) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- dom_pol = talloc(mem_ctx, POLICY_HND);
- if(!dom_pol) {
- hnd->status = NT_STATUS_NO_MEMORY;
- errno = ENOMEM;
- return CAC_FAILURE;
- }
-
- hnd->status = rpccli_lsa_open_trusted_domain( pipe_hnd, mem_ctx, op->in.pol, op->in.domain_sid, op->in.access, dom_pol);
-
- if(!NT_STATUS_IS_OK(hnd->status)) {
- return CAC_FAILURE;
- }
-
- op->out.domain_pol = dom_pol;
-
- return CAC_SUCCESS;
+int cac_LsaEnumTrustedDomains( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaEnumTrustedDomains *op )
+{
+ struct rpc_pipe_client *pipe_hnd;
+
+ uint32 num_domains;
+ char **domain_names;
+ DOM_SID *domain_sids;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op->in.pol ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ hnd->status =
+ rpccli_lsa_enum_trust_dom( pipe_hnd, mem_ctx, op->in.pol,
+ &( op->out.resume_idx ),
+ &num_domains, &domain_names,
+ &domain_sids );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ return CAC_FAILURE;
+ }
+
+ op->out.num_domains = num_domains;
+ op->out.domain_names = domain_names;
+ op->out.domain_sids = domain_sids;
+
+ return CAC_SUCCESS;
}
-int cac_LsaQueryTrustedDomainInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaQueryTrustedDomainInfo *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_LsaOpenTrustedDomain( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaOpenTrustedDomain *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- LSA_TRUSTED_DOMAIN_INFO *dom_info;
+ POLICY_HND *dom_pol = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op->in.pol || !op->in.info_class) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op->in.pol || !op->in.access || !op->in.domain_sid ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- if(!op->in.domain_sid && !op->in.domain_name) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ dom_pol = talloc( mem_ctx, POLICY_HND );
+ if ( !dom_pol ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ errno = ENOMEM;
+ return CAC_FAILURE;
+ }
- if(op->in.domain_sid) {
- hnd->status = rpccli_lsa_query_trusted_domain_info_by_sid( pipe_hnd, mem_ctx, op->in.pol, op->in.info_class, op->in.domain_sid, &dom_info);
- }
- else if(op->in.domain_name) {
- hnd->status = rpccli_lsa_query_trusted_domain_info_by_name( pipe_hnd, mem_ctx, op->in.pol, op->in.info_class, op->in.domain_name, &dom_info);
- }
+ hnd->status =
+ rpccli_lsa_open_trusted_domain( pipe_hnd, mem_ctx, op->in.pol,
+ op->in.domain_sid,
+ op->in.access, dom_pol );
- if(!NT_STATUS_IS_OK(hnd->status)) {
- return CAC_FAILURE;
- }
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ return CAC_FAILURE;
+ }
- op->out.info = dom_info;
-
- return CAC_SUCCESS;
+ op->out.domain_pol = dom_pol;
+ return CAC_SUCCESS;
}
-int cac_LsaEnumPrivileges(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaEnumPrivileges *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- uint32 num_privs;
- char **priv_names;
- uint32 *high_bits;
- uint32 *low_bits;
-
- if(!hnd) {
- return CAC_FAILURE;
- }
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || !op->in.pol) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- hnd->status = rpccli_lsa_enum_privilege(pipe_hnd, mem_ctx, op->in.pol, &(op->out.resume_idx), op->in.pref_max_privs,
- &num_privs, &priv_names, &high_bits, &low_bits);
-
- if(!NT_STATUS_IS_OK(hnd->status)) {
- return CAC_FAILURE;
- }
+int cac_LsaQueryTrustedDomainInfo( CacServerHandle * hnd,
+ TALLOC_CTX * mem_ctx,
+ struct LsaQueryTrustedDomainInfo *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ LSA_TRUSTED_DOMAIN_INFO *dom_info;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op->in.pol || !op->in.info_class ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ if ( !op->in.domain_sid && !op->in.domain_name ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( op->in.domain_sid ) {
+ hnd->status =
+ rpccli_lsa_query_trusted_domain_info_by_sid( pipe_hnd,
+ mem_ctx,
+ op->in.
+ pol,
+ op->in.
+ info_class,
+ op->in.
+ domain_sid,
+ &dom_info );
+ } else if ( op->in.domain_name ) {
+ hnd->status =
+ rpccli_lsa_query_trusted_domain_info_by_name
+ ( pipe_hnd, mem_ctx, op->in.pol, op->in.info_class,
+ op->in.domain_name, &dom_info );
+ }
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ return CAC_FAILURE;
+ }
+
+ op->out.info = dom_info;
+
+ return CAC_SUCCESS;
- op->out.num_privs = num_privs;
- op->out.priv_names = priv_names;
- op->out.high_bits = high_bits;
- op->out.low_bits = low_bits;
-
- return CAC_SUCCESS;
}
-int cac_LsaOpenAccount(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaOpenAccount *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- POLICY_HND *user_pol = NULL;
-
- if(!hnd) {
- return CAC_FAILURE;
- }
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || !op->in.pol) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- if(!op->in.sid && !op->in.name) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- /*look up the user's SID if we have to*/
- if(op->in.name && !op->in.sid) {
- DOM_SID *user_sid = NULL;
- uint32 *type;
-
- /*lookup the SID*/
- hnd->status = rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, 1, (const char **)&(op->in.name), NULL, &user_sid, &type);
-
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
-
- op->in.sid = user_sid;
- }
-
- user_pol = talloc(mem_ctx, POLICY_HND);
- if(!user_pol) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- hnd->status = rpccli_lsa_open_account(pipe_hnd, mem_ctx, op->in.pol, op->in.sid, op->in.access, user_pol);
-
- if(!NT_STATUS_IS_OK(hnd->status)) {
- TALLOC_FREE(user_pol);
- return CAC_FAILURE;
- }
-
- op->out.user = user_pol;
-
- return CAC_SUCCESS;
+int cac_LsaEnumPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaEnumPrivileges *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ uint32 num_privs;
+ char **priv_names;
+ uint32 *high_bits;
+ uint32 *low_bits;
+
+ if ( !hnd ) {
+ return CAC_FAILURE;
+ }
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || !op->in.pol ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ hnd->status =
+ rpccli_lsa_enum_privilege( pipe_hnd, mem_ctx, op->in.pol,
+ &( op->out.resume_idx ),
+ op->in.pref_max_privs, &num_privs,
+ &priv_names, &high_bits,
+ &low_bits );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ return CAC_FAILURE;
+ }
+
+ op->out.num_privs = num_privs;
+ op->out.priv_names = priv_names;
+ op->out.high_bits = high_bits;
+ op->out.low_bits = low_bits;
+
+ return CAC_SUCCESS;
}
-
-int cac_LsaAddPrivileges(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaAddPrivileges *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- DOM_SID *user_sid = NULL;
- uint32 *type = NULL;
-
- if(!hnd) {
- return CAC_FAILURE;
- }
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || !op->in.pol || !op->in.priv_names) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- if(!op->in.sid && !op->in.name) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(op->in.name && !op->in.sid) {
- /*lookup the SID*/
- hnd->status = rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, 1, (const char **)&(op->in.name), NULL, &user_sid, &type);
-
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
-
- op->in.sid = user_sid;
- }
-
- hnd->status = rpccli_lsa_add_account_rights( pipe_hnd, mem_ctx, op->in.pol, *(op->in.sid), op->in.num_privs, (const char **)op->in.priv_names);
-
- if(!NT_STATUS_IS_OK(hnd->status)) {
- return CAC_FAILURE;
- }
-
- return CAC_SUCCESS;
+int cac_LsaOpenAccount( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaOpenAccount *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ POLICY_HND *user_pol = NULL;
+
+ if ( !hnd ) {
+ return CAC_FAILURE;
+ }
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || !op->in.pol ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ if ( !op->in.sid && !op->in.name ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ /*look up the user's SID if we have to */
+ if ( op->in.name && !op->in.sid ) {
+ DOM_SID *user_sid = NULL;
+ enum lsa_SidType *type;
+
+ /*lookup the SID */
+ hnd->status =
+ rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
+ op->in.pol, 1,
+ ( const char ** ) &( op->in.
+ name ),
+ NULL, &user_sid, &type );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
+
+ op->in.sid = user_sid;
+ }
+
+ user_pol = talloc( mem_ctx, POLICY_HND );
+ if ( !user_pol ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ hnd->status =
+ rpccli_lsa_open_account( pipe_hnd, mem_ctx, op->in.pol,
+ op->in.sid, op->in.access,
+ user_pol );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ TALLOC_FREE( user_pol );
+ return CAC_FAILURE;
+ }
+
+ op->out.user = user_pol;
+
+ return CAC_SUCCESS;
}
-int cac_LsaRemovePrivileges(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaRemovePrivileges *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- DOM_SID *user_sid = NULL;
- uint32 *type = NULL;
-
- if(!hnd) {
- return CAC_FAILURE;
- }
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || !op->in.pol || !op->in.priv_names) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
- if(!op->in.sid && !op->in.name) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(op->in.name && !op->in.sid) {
- /*lookup the SID*/
- hnd->status = rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, 1, (const char **)&(op->in.name), NULL, &user_sid, &type);
-
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
-
- op->in.sid = user_sid;
- }
-
- hnd->status = rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx, op->in.pol, *(op->in.sid), False, op->in.num_privs, (const char **)op->in.priv_names);
-
- if(!NT_STATUS_IS_OK(hnd->status)) {
- return CAC_FAILURE;
- }
-
- return CAC_SUCCESS;
+int cac_LsaAddPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaAddPrivileges *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ DOM_SID *user_sid = NULL;
+ enum lsa_SidType *type = NULL;
+
+ if ( !hnd ) {
+ return CAC_FAILURE;
+ }
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || !op->in.pol || !op->in.priv_names ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ if ( !op->in.sid && !op->in.name ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( op->in.name && !op->in.sid ) {
+ /*lookup the SID */
+ hnd->status =
+ rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
+ op->in.pol, 1,
+ ( const char ** ) &( op->in.
+ name ),
+ NULL, &user_sid, &type );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
+
+ op->in.sid = user_sid;
+ }
+
+ hnd->status =
+ rpccli_lsa_add_account_rights( pipe_hnd, mem_ctx, op->in.pol,
+ *( op->in.sid ),
+ op->in.num_privs,
+ ( const char ** ) op->in.
+ priv_names );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ return CAC_FAILURE;
+ }
+
+ return CAC_SUCCESS;
}
-int cac_LsaClearPrivileges(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaClearPrivileges *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- DOM_SID *user_sid = NULL;
- uint32 *type = NULL;
-
- if(!hnd) {
- return CAC_FAILURE;
- }
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || !op->in.pol) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- if(!op->in.sid && !op->in.name) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(op->in.name && !op->in.sid) {
- /*lookup the SID*/
- hnd->status = rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, 1, (const char **)&(op->in.name), NULL, &user_sid, &type);
-
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
-
- op->in.sid = user_sid;
- }
-
- hnd->status = rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx, op->in.pol, *(op->in.sid), True, 0, NULL);
-
- if(!NT_STATUS_IS_OK(hnd->status)) {
- return CAC_FAILURE;
- }
-
- return CAC_SUCCESS;
+int cac_LsaRemovePrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaRemovePrivileges *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ DOM_SID *user_sid = NULL;
+ enum lsa_SidType *type = NULL;
+
+ if ( !hnd ) {
+ return CAC_FAILURE;
+ }
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || !op->in.pol || !op->in.priv_names ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ if ( !op->in.sid && !op->in.name ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( op->in.name && !op->in.sid ) {
+ /*lookup the SID */
+ hnd->status =
+ rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
+ op->in.pol, 1,
+ ( const char ** ) &( op->in.
+ name ),
+ NULL, &user_sid, &type );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
+
+ op->in.sid = user_sid;
+ }
+
+ hnd->status =
+ rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx,
+ op->in.pol, *( op->in.sid ),
+ False, op->in.num_privs,
+ ( const char ** ) op->in.
+ priv_names );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ return CAC_FAILURE;
+ }
+
+ return CAC_SUCCESS;
}
-int cac_LsaSetPrivileges(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaAddPrivileges *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- DOM_SID *user_sid = NULL;
- uint32 *type = NULL;
-
- if(!hnd) {
- return CAC_FAILURE;
- }
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || !op->in.pol || !op->in.priv_names) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- if(!op->in.sid && !op->in.name) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- return CAC_FAILURE;
- }
-
- if(op->in.name && !op->in.sid) {
- /*lookup the SID*/
- hnd->status = rpccli_lsa_lookup_names( pipe_hnd, mem_ctx, op->in.pol, 1, (const char **)&(op->in.name), NULL, &user_sid, &type);
-
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
-
- op->in.sid = user_sid;
- }
-
- /*first remove all privileges*/
- hnd->status = rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx, op->in.pol, *(op->in.sid), True, 0, NULL);
-
- if(!NT_STATUS_IS_OK(hnd->status)) {
- return CAC_FAILURE;
- }
-
- hnd->status = rpccli_lsa_add_account_rights( pipe_hnd, mem_ctx, op->in.pol, *(op->in.sid), op->in.num_privs, (const char **)op->in.priv_names);
-
- if(!NT_STATUS_IS_OK(hnd->status)) {
- return CAC_FAILURE;
- }
+int cac_LsaClearPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaClearPrivileges *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ DOM_SID *user_sid = NULL;
+ enum lsa_SidType *type = NULL;
+
+ if ( !hnd ) {
+ return CAC_FAILURE;
+ }
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || !op->in.pol ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ if ( !op->in.sid && !op->in.name ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( op->in.name && !op->in.sid ) {
+ /*lookup the SID */
+ hnd->status =
+ rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
+ op->in.pol, 1,
+ ( const char ** ) &( op->in.
+ name ),
+ NULL, &user_sid, &type );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
+
+ op->in.sid = user_sid;
+ }
+
+ hnd->status =
+ rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx,
+ op->in.pol, *( op->in.sid ),
+ True, 0, NULL );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ return CAC_FAILURE;
+ }
+
+ return CAC_SUCCESS;
+}
- return CAC_SUCCESS;
+int cac_LsaSetPrivileges( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaAddPrivileges *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ DOM_SID *user_sid = NULL;
+ enum lsa_SidType *type = NULL;
+
+ if ( !hnd ) {
+ return CAC_FAILURE;
+ }
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || !op->in.pol || !op->in.priv_names ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ if ( !op->in.sid && !op->in.name ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ return CAC_FAILURE;
+ }
+
+ if ( op->in.name && !op->in.sid ) {
+ /*lookup the SID */
+ hnd->status =
+ rpccli_lsa_lookup_names( pipe_hnd, mem_ctx,
+ op->in.pol, 1,
+ ( const char ** ) &( op->in.
+ name ),
+ NULL, &user_sid, &type );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
+
+ op->in.sid = user_sid;
+ }
+
+ /*first remove all privileges */
+ hnd->status =
+ rpccli_lsa_remove_account_rights( pipe_hnd, mem_ctx,
+ op->in.pol, *( op->in.sid ),
+ True, 0, NULL );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ return CAC_FAILURE;
+ }
+
+ hnd->status =
+ rpccli_lsa_add_account_rights( pipe_hnd, mem_ctx, op->in.pol,
+ *( op->in.sid ),
+ op->in.num_privs,
+ ( const char ** ) op->in.
+ priv_names );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ return CAC_FAILURE;
+ }
+
+ return CAC_SUCCESS;
}
-int cac_LsaGetSecurityObject(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct LsaGetSecurityObject *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_LsaGetSecurityObject( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct LsaGetSecurityObject *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- /*this is taken from rpcclient/cmd_lsarpc.c*/
- uint16 info_level = 4;
+ /*this is taken from rpcclient/cmd_lsarpc.c */
+ uint16 info_level = 4;
- SEC_DESC_BUF *sec_out = NULL;
+ SEC_DESC_BUF *sec_out = NULL;
- if(!hnd) {
- return CAC_FAILURE;
- }
+ if ( !hnd ) {
+ return CAC_FAILURE;
+ }
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_LSARPC] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.pol) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.pol ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_LSARPC);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_LSARPC );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_lsa_query_secobj( pipe_hnd, mem_ctx, op->in.pol, info_level, &sec_out);
+ hnd->status =
+ rpccli_lsa_query_secobj( pipe_hnd, mem_ctx, op->in.pol,
+ info_level, &sec_out );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.sec = sec_out;
+ op->out.sec = sec_out;
- return CAC_FAILURE;
+ return CAC_FAILURE;
}
diff --git a/source/libmsrpc/cac_samr.c b/source/libmsrpc/cac_samr.c
index 60c6562988e..aee60804372 100644
--- a/source/libmsrpc/cac_samr.c
+++ b/source/libmsrpc/cac_samr.c
@@ -1,3 +1,4 @@
+
/*
* Unix SMB/CIFS implementation.
* MS-RPC client library implementation (SAMR pipe)
@@ -29,2383 +30,2651 @@
/*not sure what this is.. taken from rpcclient/cmd_samr.c*/
#define SAMR_LOOKUP_FLAGS 0x000003e8
-int cac_SamConnect(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamConnect *op) {
- SMBCSRV *srv = NULL;
- struct rpc_pipe_client *pipe_hnd = NULL;
- POLICY_HND *sam_out = NULL;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || op->in.access == 0 || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- srv = cac_GetServer(hnd);
- if(!srv) {
- hnd->status = NT_STATUS_INVALID_CONNECTION;
- return CAC_FAILURE;
- }
-
- /*initialize for samr pipe if we have to*/
- if(!hnd->_internal.pipes[PI_SAMR]) {
- if(!(pipe_hnd = cli_rpc_pipe_open_noauth(&srv->cli, PI_SAMR, &(hnd->status)))) {
- return CAC_FAILURE;
- }
-
- hnd->_internal.pipes[PI_SAMR] = True;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- sam_out = talloc(mem_ctx, POLICY_HND);
- if(!sam_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+int cac_SamConnect( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamConnect *op )
+{
+ SMBCSRV *srv = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ POLICY_HND *sam_out = NULL;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || op->in.access == 0 || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ srv = cac_GetServer( hnd );
+ if ( !srv ) {
+ hnd->status = NT_STATUS_INVALID_CONNECTION;
+ return CAC_FAILURE;
+ }
+
+ /*initialize for samr pipe if we have to */
+ if ( !hnd->_internal.pipes[PI_SAMR] ) {
+ if ( !
+ ( pipe_hnd =
+ cli_rpc_pipe_open_noauth( srv->cli, PI_SAMR,
+ &hnd->status ) ) ) {
+ return CAC_FAILURE;
+ }
+
+ hnd->_internal.pipes[PI_SAMR] = True;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ sam_out = talloc( mem_ctx, POLICY_HND );
+ if ( !sam_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ if ( hnd->_internal.srv_level >= SRV_WIN_2K_SP3 ) {
+ hnd->status =
+ rpccli_samr_connect4( pipe_hnd, mem_ctx,
+ op->in.access, sam_out );
+ }
+
+ if ( hnd->_internal.srv_level < SRV_WIN_2K_SP3
+ || !NT_STATUS_IS_OK( hnd->status ) ) {
+ /*if sam_connect4 failed, the use sam_connect and lower srv_level */
+
+ hnd->status =
+ rpccli_samr_connect( pipe_hnd, mem_ctx, op->in.access,
+ sam_out );
+
+ if ( NT_STATUS_IS_OK( hnd->status )
+ && hnd->_internal.srv_level > SRV_WIN_2K ) {
+ hnd->_internal.srv_level = SRV_WIN_2K;
+ }
+ }
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
+
+ op->out.sam = sam_out;
+
+ return CAC_SUCCESS;
+}
- if(hnd->_internal.srv_level >= SRV_WIN_2K_SP3) {
- hnd->status = rpccli_samr_connect4( pipe_hnd, mem_ctx, op->in.access, sam_out);
- }
+int cac_SamClose( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ POLICY_HND * sam )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- if(hnd->_internal.srv_level < SRV_WIN_2K_SP3 || !NT_STATUS_IS_OK(hnd->status)) {
- /*if sam_connect4 failed, the use sam_connect and lower srv_level*/
+ if ( !hnd )
+ return CAC_FAILURE;
- hnd->status = rpccli_samr_connect( pipe_hnd, mem_ctx, op->in.access, sam_out);
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(NT_STATUS_IS_OK(hnd->status) && hnd->_internal.srv_level > SRV_WIN_2K) {
- hnd->_internal.srv_level = SRV_WIN_2K;
- }
- }
+ if ( !sam || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- op->out.sam = sam_out;
+ hnd->status = rpccli_samr_close( pipe_hnd, mem_ctx, sam );
- return CAC_SUCCESS;
-}
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
-int cac_SamClose(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *sam) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!sam || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- hnd->status = rpccli_samr_close( pipe_hnd, mem_ctx, sam);
-
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
-
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
/*this is an internal function. Due to a circular dependency, it must be prototyped in libmsrpc.h (which I don't want to do)
* cac_SamOpenDomain() is the only function that calls it, so I just put the definition here
*/
+
/*attempts to find the sid of the domain we are connected to*/
-DOM_SID *cac_get_domain_sid(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, uint32 des_access) {
- struct LsaOpenPolicy lop;
- struct LsaFetchSid fs;
+DOM_SID *cac_get_domain_sid( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ uint32 des_access )
+{
+ struct LsaOpenPolicy lop;
+ struct LsaFetchSid fs;
+
+ DOM_SID *sid;
+
+ ZERO_STRUCT( lop );
+ ZERO_STRUCT( fs );
- DOM_SID *sid;
-
- ZERO_STRUCT(lop);
- ZERO_STRUCT(fs);
+ lop.in.access = des_access;
+ lop.in.security_qos = True;
- lop.in.access = des_access;
- lop.in.security_qos = True;
+ if ( !cac_LsaOpenPolicy( hnd, mem_ctx, &lop ) )
+ return NULL;
- if(!cac_LsaOpenPolicy(hnd, mem_ctx, &lop))
- return NULL;
+ fs.in.pol = lop.out.pol;
+ fs.in.info_class = CAC_DOMAIN_INFO;
- fs.in.pol = lop.out.pol;
- fs.in.info_class = CAC_DOMAIN_INFO;
+ if ( !cac_LsaFetchSid( hnd, mem_ctx, &fs ) )
+ return NULL;
- if(!cac_LsaFetchSid(hnd, mem_ctx, &fs))
- return NULL;
-
- cac_LsaClosePolicy(hnd, mem_ctx, lop.out.pol);
+ cac_LsaClosePolicy( hnd, mem_ctx, lop.out.pol );
- if(!fs.out.domain_sid)
- return NULL;
+ if ( !fs.out.domain_sid )
+ return NULL;
- sid = talloc_memdup(mem_ctx, &(fs.out.domain_sid->sid), sizeof(DOM_SID));
+ sid = ( DOM_SID * ) talloc_memdup( mem_ctx,
+ &( fs.out.domain_sid->sid ),
+ sizeof( DOM_SID ) );
- if(!sid) {
- hnd->status = NT_STATUS_NO_MEMORY;
- }
+ if ( !sid ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ }
- return sid;
+ return sid;
}
-int cac_SamOpenDomain(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamOpenDomain *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- DOM_SID *sid_buf;
- POLICY_HND *sam_out;
- POLICY_HND *pol_out;
-
- struct SamLookupDomain sld;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || op->in.access == 0 || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- if(!op->in.sam) {
- /*use cac_SamConnect() since it does the session setup*/
- struct SamConnect sc;
- ZERO_STRUCT(sc);
-
- sc.in.access = op->in.access;
-
- if(!cac_SamConnect(hnd, mem_ctx, &sc)) {
- return CAC_FAILURE;
- }
-
- sam_out = sc.out.sam;
- }
- else {
- sam_out = op->in.sam;
- }
-
- if(!op->in.sid) {
- /*find the sid for the SAM's domain*/
-
- /*try using cac_SamLookupDomain() first*/
- ZERO_STRUCT(sld);
-
- sld.in.sam = sam_out;
- sld.in.name = hnd->domain;
-
- if(cac_SamLookupDomain(hnd, mem_ctx, &sld)) {
- /*then we got the sid*/
- sid_buf = sld.out.sid;
- }
- else {
- /*try to get it from the LSA*/
- sid_buf = cac_get_domain_sid(hnd, mem_ctx, op->in.access);
- }
- }
- else {
- /*we already have the sid for the domain we want*/
- sid_buf = op->in.sid;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- pol_out = talloc(mem_ctx, POLICY_HND);
- if(!pol_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- /*now open the domain*/
- hnd->status = rpccli_samr_open_domain( pipe_hnd, mem_ctx, sam_out, op->in.access, sid_buf, pol_out);
-
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
-
- op->out.sam = sam_out;
- op->out.dom_hnd = pol_out;
-
- return CAC_SUCCESS;
+int cac_SamOpenDomain( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamOpenDomain *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ DOM_SID *sid_buf;
+ POLICY_HND *sam_out;
+ POLICY_HND *pol_out;
+
+ struct SamLookupDomain sld;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || op->in.access == 0 || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ if ( !op->in.sam ) {
+ /*use cac_SamConnect() since it does the session setup */
+ struct SamConnect sc;
+
+ ZERO_STRUCT( sc );
+
+ sc.in.access = op->in.access;
+
+ if ( !cac_SamConnect( hnd, mem_ctx, &sc ) ) {
+ return CAC_FAILURE;
+ }
+
+ sam_out = sc.out.sam;
+ } else {
+ sam_out = op->in.sam;
+ }
+
+ if ( !op->in.sid ) {
+ /*find the sid for the SAM's domain */
+
+ /*try using cac_SamLookupDomain() first */
+ ZERO_STRUCT( sld );
+
+ sld.in.sam = sam_out;
+ sld.in.name = hnd->domain;
+
+ if ( cac_SamLookupDomain( hnd, mem_ctx, &sld ) ) {
+ /*then we got the sid */
+ sid_buf = sld.out.sid;
+ } else {
+ /*try to get it from the LSA */
+ sid_buf =
+ cac_get_domain_sid( hnd, mem_ctx,
+ op->in.access );
+ }
+ } else {
+ /*we already have the sid for the domain we want */
+ sid_buf = op->in.sid;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ pol_out = talloc( mem_ctx, POLICY_HND );
+ if ( !pol_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ /*now open the domain */
+ hnd->status =
+ rpccli_samr_open_domain( pipe_hnd, mem_ctx, sam_out,
+ op->in.access, sid_buf, pol_out );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
+
+ op->out.sam = sam_out;
+ op->out.dom_hnd = pol_out;
+
+ return CAC_SUCCESS;
}
-int cac_SamOpenUser(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamOpenUser *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamOpenUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamOpenUser *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- uint32 *rid_buf = NULL;
+ uint32 *rid_buf = NULL;
- uint32 num_rids = 0;
- uint32 *rid_types = NULL;
+ uint32 num_rids = 0;
+ uint32 *rid_types = NULL;
- POLICY_HND *user_out = NULL;
+ POLICY_HND *user_out = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.dom_hnd || op->in.access == 0 || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.dom_hnd || op->in.access == 0 || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- if(op->in.rid == 0 && op->in.name == NULL) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( op->in.rid == 0 && op->in.name == NULL ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(op->in.rid == 0 && op->in.name) {
- /*lookup the name and then set rid_buf*/
+ if ( op->in.rid == 0 && op->in.name ) {
+ /*lookup the name and then set rid_buf */
- hnd->status = rpccli_samr_lookup_names( pipe_hnd, mem_ctx, op->in.dom_hnd, SAMR_LOOKUP_FLAGS, 1, (const char **)&op->in.name,
- &num_rids, &rid_buf, &rid_types);
+ hnd->status =
+ rpccli_samr_lookup_names( pipe_hnd, mem_ctx,
+ op->in.dom_hnd,
+ SAMR_LOOKUP_FLAGS, 1,
+ ( const char ** ) &op->in.
+ name, &num_rids, &rid_buf,
+ &rid_types );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- if(num_rids == 0 || rid_buf == NULL || rid_types[0] == SAMR_RID_UNKNOWN) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( num_rids == 0 || rid_buf == NULL
+ || rid_types[0] == SAMR_RID_UNKNOWN ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- TALLOC_FREE(rid_types);
+ TALLOC_FREE( rid_types );
- }
- else {
- rid_buf = &op->in.rid;
- }
+ } else {
+ rid_buf = &op->in.rid;
+ }
- user_out = talloc(mem_ctx, POLICY_HND);
- if(!user_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ user_out = talloc( mem_ctx, POLICY_HND );
+ if ( !user_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_open_user(pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.access, *rid_buf, user_out);
-
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ hnd->status =
+ rpccli_samr_open_user( pipe_hnd, mem_ctx, op->in.dom_hnd,
+ op->in.access, *rid_buf, user_out );
- op->out.user_hnd = user_out;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ op->out.user_hnd = user_out;
+
+ return CAC_SUCCESS;
}
-int cac_SamCreateUser(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamCreateUser *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamCreateUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamCreateUser *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- POLICY_HND *user_out = NULL;
- uint32 rid_out;
+ POLICY_HND *user_out = NULL;
+ uint32 rid_out;
/**found in rpcclient/cmd_samr.c*/
- uint32 unknown = 0xe005000b;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || !op->in.dom_hnd || !op->in.name || op->in.acb_mask == 0 || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- user_out = talloc(mem_ctx, POLICY_HND);
- if(!user_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- hnd->status = rpccli_samr_create_dom_user( pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.name, op->in.acb_mask, unknown, user_out, &rid_out);
-
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
-
- op->out.user_hnd = user_out;
- op->out.rid = rid_out;
-
- return CAC_SUCCESS;
+ uint32 unknown = 0xe005000b;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || !op->in.dom_hnd || !op->in.name || op->in.acb_mask == 0
+ || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ user_out = talloc( mem_ctx, POLICY_HND );
+ if ( !user_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ hnd->status =
+ rpccli_samr_create_dom_user( pipe_hnd, mem_ctx,
+ op->in.dom_hnd, op->in.name,
+ op->in.acb_mask, unknown,
+ user_out, &rid_out );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
+
+ op->out.user_hnd = user_out;
+ op->out.rid = rid_out;
+
+ return CAC_SUCCESS;
}
-int cac_SamDeleteUser(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *user_hnd) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamDeleteUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ POLICY_HND * user_hnd )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!user_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !user_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_delete_dom_user( pipe_hnd, mem_ctx, user_hnd);
+ hnd->status =
+ rpccli_samr_delete_dom_user( pipe_hnd, mem_ctx, user_hnd );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamEnumUsers(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamEnumUsers *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamEnumUsers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamEnumUsers *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- uint32 resume_idx_out = 0;
- char **names_out = NULL;
- uint32 *rids_out = NULL;
- uint32 num_users_out = 0;
+ uint32 resume_idx_out = 0;
+ char **names_out = NULL;
+ uint32 *rids_out = NULL;
+ uint32 num_users_out = 0;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.dom_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.dom_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- /*this is a hack.. but is the only reliable way to know if everything has been enumerated*/
- if(op->out.done == True)
- return CAC_FAILURE;
+ /*this is a hack.. but is the only reliable way to know if everything has been enumerated */
+ if ( op->out.done == True )
+ return CAC_FAILURE;
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- resume_idx_out = op->out.resume_idx;
+ resume_idx_out = op->out.resume_idx;
- hnd->status = rpccli_samr_enum_dom_users( pipe_hnd, mem_ctx, op->in.dom_hnd, &resume_idx_out, op->in.acb_mask, SAMR_ENUM_MAX_SIZE,
- &names_out, &rids_out, &num_users_out);
+ hnd->status =
+ rpccli_samr_enum_dom_users( pipe_hnd, mem_ctx, op->in.dom_hnd,
+ &resume_idx_out, op->in.acb_mask,
+ SAMR_ENUM_MAX_SIZE, &names_out,
+ &rids_out, &num_users_out );
- if(NT_STATUS_IS_OK(hnd->status))
- op->out.done = True;
+ if ( NT_STATUS_IS_OK( hnd->status ) )
+ op->out.done = True;
- /*if there are no more entries, the operation will return NT_STATUS_OK.
- * We want to return failure if no results were returned*/
- if(!NT_STATUS_IS_OK(hnd->status) && NT_STATUS_V(hnd->status) != NT_STATUS_V(STATUS_MORE_ENTRIES))
- return CAC_FAILURE;
+ /*if there are no more entries, the operation will return NT_STATUS_OK.
+ * We want to return failure if no results were returned*/
+ if ( !NT_STATUS_IS_OK( hnd->status )
+ && NT_STATUS_V( hnd->status ) !=
+ NT_STATUS_V( STATUS_MORE_ENTRIES ) )
+ return CAC_FAILURE;
- op->out.resume_idx= resume_idx_out;
- op->out.num_users = num_users_out;
- op->out.rids = rids_out;
- op->out.names = names_out;
+ op->out.resume_idx = resume_idx_out;
+ op->out.num_users = num_users_out;
+ op->out.rids = rids_out;
+ op->out.names = names_out;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamGetNamesFromRids(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetNamesFromRids *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- uint32 num_names_out;
- char **names_out;
- uint32 *name_types_out;
-
-
- uint32 i = 0;
-
- CacLookupRidsRecord *map_out;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || !op->in.dom_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- if(!op->in.rids && op->in.num_rids != 0) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- if(op->in.num_rids == 0) {
- /*nothing to do*/
- op->out.num_names = 0;
- return CAC_SUCCESS;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- hnd->status = rpccli_samr_lookup_rids( pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.num_rids, op->in.rids, &num_names_out, &names_out, &name_types_out);
-
- if(!NT_STATUS_IS_OK(hnd->status) && !NT_STATUS_EQUAL(hnd->status, STATUS_SOME_UNMAPPED))
- return CAC_FAILURE;
-
- map_out = TALLOC_ARRAY(mem_ctx, CacLookupRidsRecord, num_names_out);
- if(!map_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- for(i = 0; i < num_names_out; i++) {
- if(name_types_out[i] == SAMR_RID_UNKNOWN) {
- map_out[i].found = False;
- map_out[i].name = NULL;
- map_out[i].type = 0;
- }
- else {
- map_out[i].found = True;
- map_out[i].name = talloc_strdup(mem_ctx, names_out[i]);
- map_out[i].type = name_types_out[i];
- }
- map_out[i].rid = op->in.rids[i];
- }
-
- TALLOC_FREE(names_out);
- TALLOC_FREE(name_types_out);
-
- op->out.num_names = num_names_out;
- op->out.map = map_out;
-
- if(NT_STATUS_EQUAL(hnd->status, STATUS_SOME_UNMAPPED))
- return CAC_PARTIAL_SUCCESS;
-
- return CAC_SUCCESS;
+int cac_SamGetNamesFromRids( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamGetNamesFromRids *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ uint32 num_names_out;
+ char **names_out;
+ uint32 *name_types_out;
+
+
+ uint32 i = 0;
+
+ CacLookupRidsRecord *map_out;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || !op->in.dom_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ if ( !op->in.rids && op->in.num_rids != 0 ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ if ( op->in.num_rids == 0 ) {
+ /*nothing to do */
+ op->out.num_names = 0;
+ return CAC_SUCCESS;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ hnd->status =
+ rpccli_samr_lookup_rids( pipe_hnd, mem_ctx, op->in.dom_hnd,
+ op->in.num_rids, op->in.rids,
+ &num_names_out, &names_out,
+ &name_types_out );
+
+ if ( !NT_STATUS_IS_OK( hnd->status )
+ && !NT_STATUS_EQUAL( hnd->status, STATUS_SOME_UNMAPPED ) )
+ return CAC_FAILURE;
+
+ map_out = TALLOC_ARRAY( mem_ctx, CacLookupRidsRecord, num_names_out );
+ if ( !map_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ for ( i = 0; i < num_names_out; i++ ) {
+ if ( name_types_out[i] == SAMR_RID_UNKNOWN ) {
+ map_out[i].found = False;
+ map_out[i].name = NULL;
+ map_out[i].type = 0;
+ } else {
+ map_out[i].found = True;
+ map_out[i].name =
+ talloc_strdup( mem_ctx, names_out[i] );
+ map_out[i].type = name_types_out[i];
+ }
+ map_out[i].rid = op->in.rids[i];
+ }
+
+ TALLOC_FREE( names_out );
+ TALLOC_FREE( name_types_out );
+
+ op->out.num_names = num_names_out;
+ op->out.map = map_out;
+
+ if ( NT_STATUS_EQUAL( hnd->status, STATUS_SOME_UNMAPPED ) )
+ return CAC_PARTIAL_SUCCESS;
+
+ return CAC_SUCCESS;
}
-int cac_SamGetRidsFromNames(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetRidsFromNames *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- uint32 num_rids_out;
- uint32 *rids_out;
- uint32 *rid_types_out;
-
- uint32 i = 0;
-
- CacLookupRidsRecord *map_out;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || !op->in.dom_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- if(!op->in.names && op->in.num_names != 0) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- if(op->in.num_names == 0) {
- /*then we don't have to do anything*/
- op->out.num_rids = 0;
- return CAC_SUCCESS;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- hnd->status = rpccli_samr_lookup_names( pipe_hnd, mem_ctx, op->in.dom_hnd, SAMR_LOOKUP_FLAGS, op->in.num_names, (const char **)op->in.names,
- &num_rids_out, &rids_out, &rid_types_out);
-
- if(!NT_STATUS_IS_OK(hnd->status) && !NT_STATUS_EQUAL(hnd->status, STATUS_SOME_UNMAPPED))
- return CAC_FAILURE;
-
- map_out = TALLOC_ARRAY(mem_ctx, CacLookupRidsRecord, num_rids_out);
- if(!map_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- for(i = 0; i < num_rids_out; i++) {
-
- if(rid_types_out[i] == SAMR_RID_UNKNOWN) {
- map_out[i].found = False;
- map_out[i].rid = 0;
- map_out[i].type = 0;
- }
- else {
- map_out[i].found = True;
- map_out[i].rid = rids_out[i];
- map_out[i].type = rid_types_out[i];
- }
-
- map_out[i].name = talloc_strdup(mem_ctx, op->in.names[i]);
- }
-
- op->out.num_rids = num_rids_out;
- op->out.map = map_out;
-
- TALLOC_FREE(rids_out);
- TALLOC_FREE(rid_types_out);
-
- if(NT_STATUS_EQUAL(hnd->status, STATUS_SOME_UNMAPPED))
- return CAC_PARTIAL_SUCCESS;
-
- return CAC_SUCCESS;
+int cac_SamGetRidsFromNames( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamGetRidsFromNames *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ uint32 num_rids_out;
+ uint32 *rids_out;
+ uint32 *rid_types_out;
+
+ uint32 i = 0;
+
+ CacLookupRidsRecord *map_out;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || !op->in.dom_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ if ( !op->in.names && op->in.num_names != 0 ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ if ( op->in.num_names == 0 ) {
+ /*then we don't have to do anything */
+ op->out.num_rids = 0;
+ return CAC_SUCCESS;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ hnd->status =
+ rpccli_samr_lookup_names( pipe_hnd, mem_ctx, op->in.dom_hnd,
+ SAMR_LOOKUP_FLAGS, op->in.num_names,
+ ( const char ** ) op->in.names,
+ &num_rids_out, &rids_out,
+ &rid_types_out );
+
+ if ( !NT_STATUS_IS_OK( hnd->status )
+ && !NT_STATUS_EQUAL( hnd->status, STATUS_SOME_UNMAPPED ) )
+ return CAC_FAILURE;
+
+ map_out = TALLOC_ARRAY( mem_ctx, CacLookupRidsRecord, num_rids_out );
+ if ( !map_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ for ( i = 0; i < num_rids_out; i++ ) {
+
+ if ( rid_types_out[i] == SAMR_RID_UNKNOWN ) {
+ map_out[i].found = False;
+ map_out[i].rid = 0;
+ map_out[i].type = 0;
+ } else {
+ map_out[i].found = True;
+ map_out[i].rid = rids_out[i];
+ map_out[i].type = rid_types_out[i];
+ }
+
+ map_out[i].name = talloc_strdup( mem_ctx, op->in.names[i] );
+ }
+
+ op->out.num_rids = num_rids_out;
+ op->out.map = map_out;
+
+ TALLOC_FREE( rids_out );
+ TALLOC_FREE( rid_types_out );
+
+ if ( NT_STATUS_EQUAL( hnd->status, STATUS_SOME_UNMAPPED ) )
+ return CAC_PARTIAL_SUCCESS;
+
+ return CAC_SUCCESS;
}
-int cac_SamGetGroupsForUser(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetGroupsForUser *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamGetGroupsForUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamGetGroupsForUser *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ DOM_GID *groups = NULL;
+ uint32 num_groups_out = 0;
- DOM_GID *groups = NULL;
- uint32 num_groups_out = 0;
+ uint32 *rids_out = NULL;
+ uint32 *attr_out = NULL;
- uint32 *rids_out = NULL;
- uint32 *attr_out = NULL;
+ uint32 i;
- uint32 i;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.user_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.user_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ hnd->status =
+ rpccli_samr_query_usergroups( pipe_hnd, mem_ctx,
+ op->in.user_hnd,
+ &num_groups_out, &groups );
- hnd->status = rpccli_samr_query_usergroups(pipe_hnd, mem_ctx, op->in.user_hnd, &num_groups_out, &groups);
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ rids_out = talloc_array( mem_ctx, uint32, num_groups_out );
+ if ( !rids_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- rids_out = talloc_array(mem_ctx, uint32, num_groups_out);
- if(!rids_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ attr_out = talloc_array( mem_ctx, uint32, num_groups_out );
+ if ( !attr_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- attr_out = talloc_array(mem_ctx, uint32, num_groups_out);
- if(!attr_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- for(i = 0; i < num_groups_out; i++) {
- rids_out[i] = groups[i].g_rid;
- attr_out[i] = groups[i].attr;
- }
+ for ( i = 0; i < num_groups_out; i++ ) {
+ rids_out[i] = groups[i].g_rid;
+ attr_out[i] = groups[i].attr;
+ }
- TALLOC_FREE(groups);
+ TALLOC_FREE( groups );
- op->out.num_groups = num_groups_out;
- op->out.rids = rids_out;
- op->out.attributes = attr_out;
+ op->out.num_groups = num_groups_out;
+ op->out.rids = rids_out;
+ op->out.attributes = attr_out;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamOpenGroup(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamOpenGroup *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamOpenGroup( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamOpenGroup *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- POLICY_HND *group_hnd_out = NULL;
+ POLICY_HND *group_hnd_out = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || op->in.access == 0 || op->in.rid == 0 || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || op->in.access == 0 || op->in.rid == 0 || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- group_hnd_out = talloc(mem_ctx, POLICY_HND);
- if(!group_hnd_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ group_hnd_out = talloc( mem_ctx, POLICY_HND );
+ if ( !group_hnd_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_open_group( pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.access, op->in.rid, group_hnd_out);
+ hnd->status =
+ rpccli_samr_open_group( pipe_hnd, mem_ctx, op->in.dom_hnd,
+ op->in.access, op->in.rid,
+ group_hnd_out );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.group_hnd = group_hnd_out;
+ op->out.group_hnd = group_hnd_out;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamCreateGroup(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamCreateGroup *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamCreateGroup( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamCreateGroup *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- POLICY_HND *group_hnd_out = NULL;
+ POLICY_HND *group_hnd_out = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.name || op->in.name[0] == '\0' || op->in.access == 0 || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.name || op->in.name[0] == '\0'
+ || op->in.access == 0 || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- group_hnd_out = talloc(mem_ctx, POLICY_HND);
- if(!group_hnd_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ group_hnd_out = talloc( mem_ctx, POLICY_HND );
+ if ( !group_hnd_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_create_dom_group( pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.name, op->in.access, group_hnd_out);
+ hnd->status =
+ rpccli_samr_create_dom_group( pipe_hnd, mem_ctx,
+ op->in.dom_hnd, op->in.name,
+ op->in.access, group_hnd_out );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.group_hnd = group_hnd_out;
+ op->out.group_hnd = group_hnd_out;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamDeleteGroup(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *group_hnd) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamDeleteGroup( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ POLICY_HND * group_hnd )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!group_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !group_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_delete_dom_group( pipe_hnd, mem_ctx, group_hnd);
+ hnd->status =
+ rpccli_samr_delete_dom_group( pipe_hnd, mem_ctx, group_hnd );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamGetGroupMembers(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetGroupMembers *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamGetGroupMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamGetGroupMembers *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- uint32 num_mem_out;
- uint32 *rids_out;
- uint32 *attr_out;
+ uint32 num_mem_out;
+ uint32 *rids_out;
+ uint32 *attr_out;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.group_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.group_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_query_groupmem( pipe_hnd, mem_ctx, op->in.group_hnd, &num_mem_out, &rids_out, &attr_out);
+ hnd->status =
+ rpccli_samr_query_groupmem( pipe_hnd, mem_ctx,
+ op->in.group_hnd, &num_mem_out,
+ &rids_out, &attr_out );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.num_members = num_mem_out;
- op->out.rids = rids_out;
- op->out.attributes = attr_out;
+ op->out.num_members = num_mem_out;
+ op->out.rids = rids_out;
+ op->out.attributes = attr_out;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamAddGroupMember(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamAddGroupMember *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamAddGroupMember( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamAddGroupMember *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.group_hnd || op->in.rid == 0 || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.group_hnd || op->in.rid == 0 || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_add_groupmem( pipe_hnd, mem_ctx, op->in.group_hnd, op->in.rid);
+ hnd->status =
+ rpccli_samr_add_groupmem( pipe_hnd, mem_ctx, op->in.group_hnd,
+ op->in.rid );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamRemoveGroupMember(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamRemoveGroupMember *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamRemoveGroupMember( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamRemoveGroupMember *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.group_hnd || op->in.rid == 0 || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.group_hnd || op->in.rid == 0 || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_del_groupmem( pipe_hnd, mem_ctx, op->in.group_hnd, op->in.rid);
+ hnd->status =
+ rpccli_samr_del_groupmem( pipe_hnd, mem_ctx, op->in.group_hnd,
+ op->in.rid );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamClearGroupMembers(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *group_hnd) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamClearGroupMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ POLICY_HND * group_hnd )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- int result = CAC_SUCCESS;
+ int result = CAC_SUCCESS;
- int i = 0;
+ int i = 0;
- uint32 num_mem = 0;
- uint32 *rid = NULL;
- uint32 *attr = NULL;
+ uint32 num_mem = 0;
+ uint32 *rid = NULL;
+ uint32 *attr = NULL;
- NTSTATUS status;
+ NTSTATUS status;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!group_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !group_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_query_groupmem(pipe_hnd, mem_ctx, group_hnd, &num_mem, &rid, &attr);
-
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ hnd->status =
+ rpccli_samr_query_groupmem( pipe_hnd, mem_ctx, group_hnd,
+ &num_mem, &rid, &attr );
- /*try to delete the users one by one*/
- for(i = 0; i < num_mem && NT_STATUS_IS_OK(hnd->status); i++) {
- hnd->status = rpccli_samr_del_groupmem(pipe_hnd, mem_ctx, group_hnd, rid[i]);
- }
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- /*if not all members could be removed, then try to re-add the members that were already deleted*/
- if(!NT_STATUS_IS_OK(hnd->status)) {
- status = NT_STATUS_OK;
+ /*try to delete the users one by one */
+ for ( i = 0; i < num_mem && NT_STATUS_IS_OK( hnd->status ); i++ ) {
+ hnd->status =
+ rpccli_samr_del_groupmem( pipe_hnd, mem_ctx,
+ group_hnd, rid[i] );
+ }
- for(i -= 1; i >= 0 && NT_STATUS_IS_OK(status); i--) {
- status = rpccli_samr_add_groupmem( pipe_hnd, mem_ctx, group_hnd, rid[i]);
- }
+ /*if not all members could be removed, then try to re-add the members that were already deleted */
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ status = NT_STATUS_OK;
- /*we return with the NTSTATUS error that we got when trying to delete users*/
- if(!NT_STATUS_IS_OK(status))
- result = CAC_FAILURE;
- }
+ for ( i -= 1; i >= 0 && NT_STATUS_IS_OK( status ); i-- ) {
+ status = rpccli_samr_add_groupmem( pipe_hnd, mem_ctx,
+ group_hnd,
+ rid[i] );
+ }
- TALLOC_FREE(attr);
+ /*we return with the NTSTATUS error that we got when trying to delete users */
+ if ( !NT_STATUS_IS_OK( status ) )
+ result = CAC_FAILURE;
+ }
- return result;
+ TALLOC_FREE( attr );
+
+ return result;
}
-int cac_SamSetGroupMembers(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamSetGroupMembers *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamSetGroupMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamSetGroupMembers *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ uint32 i = 0;
- uint32 i = 0;
-
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.group_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.group_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- /*use cac_SamClearGroupMembers() to clear them*/
- if(!cac_SamClearGroupMembers(hnd, mem_ctx, op->in.group_hnd))
- return CAC_FAILURE; /*hnd->status is already set*/
+ /*use cac_SamClearGroupMembers() to clear them */
+ if ( !cac_SamClearGroupMembers( hnd, mem_ctx, op->in.group_hnd ) )
+ return CAC_FAILURE; /*hnd->status is already set */
- for(i = 0; i < op->in.num_members && NT_STATUS_IS_OK(hnd->status); i++) {
- hnd->status = rpccli_samr_add_groupmem( pipe_hnd, mem_ctx, op->in.group_hnd, op->in.rids[i]);
- }
+ for ( i = 0; i < op->in.num_members && NT_STATUS_IS_OK( hnd->status );
+ i++ ) {
+ hnd->status =
+ rpccli_samr_add_groupmem( pipe_hnd, mem_ctx,
+ op->in.group_hnd,
+ op->in.rids[i] );
+ }
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamEnumGroups(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamEnumGroups *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- uint32 i = 0;
-
- uint32 resume_idx_out = 0;
- char **names_out = NULL;
- char **desc_out = NULL;
- uint32 *rids_out = NULL;
- uint32 num_groups_out = 0;
-
- struct acct_info *acct_buf = NULL;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || !op->in.dom_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- /*using this BOOL is the only reliable way to know that we are done*/
- if(op->out.done == True) /*we return failure so the call will break out of a loop*/
- return CAC_FAILURE;
-
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- resume_idx_out = op->out.resume_idx;
-
- hnd->status = rpccli_samr_enum_dom_groups( pipe_hnd, mem_ctx, op->in.dom_hnd, &resume_idx_out, SAMR_ENUM_MAX_SIZE,
- &acct_buf, &num_groups_out);
-
-
- if(NT_STATUS_IS_OK(hnd->status)) {
- op->out.done = True;
- }
- else if(NT_STATUS_V(hnd->status) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
- /*if there are no more entries, the operation will return NT_STATUS_OK.
- * We want to return failure if no results were returned*/
- return CAC_FAILURE;
- }
-
- names_out = talloc_array(mem_ctx, char *, num_groups_out);
- if(!names_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- TALLOC_FREE(acct_buf);
- return CAC_FAILURE;
- }
-
- desc_out = talloc_array(mem_ctx, char *, num_groups_out);
- if(!desc_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- TALLOC_FREE(acct_buf);
- TALLOC_FREE(names_out);
- return CAC_FAILURE;
- }
-
- rids_out = talloc_array(mem_ctx, uint32, num_groups_out);
- if(!rids_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- TALLOC_FREE(acct_buf);
- TALLOC_FREE(names_out);
- TALLOC_FREE(desc_out);
- return CAC_FAILURE;
- }
-
- for(i = 0; i < num_groups_out; i++) {
- names_out[i] = talloc_strdup(mem_ctx, acct_buf[i].acct_name);
- desc_out[i] = talloc_strdup(mem_ctx, acct_buf[i].acct_desc);
- rids_out[i] = acct_buf[i].rid;
-
- if(!names_out[i] || !desc_out[i]) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
- }
-
- op->out.resume_idx = resume_idx_out;
- op->out.num_groups = num_groups_out;
- op->out.rids = rids_out;
- op->out.names = names_out;
- op->out.descriptions = desc_out;
-
- return CAC_SUCCESS;
+int cac_SamEnumGroups( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamEnumGroups *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ uint32 i = 0;
+
+ uint32 resume_idx_out = 0;
+ char **names_out = NULL;
+ char **desc_out = NULL;
+ uint32 *rids_out = NULL;
+ uint32 num_groups_out = 0;
+
+ struct acct_info *acct_buf = NULL;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || !op->in.dom_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ /*using this BOOL is the only reliable way to know that we are done */
+ if ( op->out.done == True ) /*we return failure so the call will break out of a loop */
+ return CAC_FAILURE;
+
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ resume_idx_out = op->out.resume_idx;
+
+ hnd->status =
+ rpccli_samr_enum_dom_groups( pipe_hnd, mem_ctx,
+ op->in.dom_hnd, &resume_idx_out,
+ SAMR_ENUM_MAX_SIZE, &acct_buf,
+ &num_groups_out );
+
+
+ if ( NT_STATUS_IS_OK( hnd->status ) ) {
+ op->out.done = True;
+ } else if ( NT_STATUS_V( hnd->status ) !=
+ NT_STATUS_V( STATUS_MORE_ENTRIES ) ) {
+ /*if there are no more entries, the operation will return NT_STATUS_OK.
+ * We want to return failure if no results were returned*/
+ return CAC_FAILURE;
+ }
+
+ names_out = talloc_array( mem_ctx, char *, num_groups_out );
+ if ( !names_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ TALLOC_FREE( acct_buf );
+ return CAC_FAILURE;
+ }
+
+ desc_out = talloc_array( mem_ctx, char *, num_groups_out );
+ if ( !desc_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ TALLOC_FREE( acct_buf );
+ TALLOC_FREE( names_out );
+ return CAC_FAILURE;
+ }
+
+ rids_out = talloc_array( mem_ctx, uint32, num_groups_out );
+ if ( !rids_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ TALLOC_FREE( acct_buf );
+ TALLOC_FREE( names_out );
+ TALLOC_FREE( desc_out );
+ return CAC_FAILURE;
+ }
+
+ for ( i = 0; i < num_groups_out; i++ ) {
+ names_out[i] =
+ talloc_strdup( mem_ctx, acct_buf[i].acct_name );
+ desc_out[i] = talloc_strdup( mem_ctx, acct_buf[i].acct_desc );
+ rids_out[i] = acct_buf[i].rid;
+
+ if ( !names_out[i] || !desc_out[i] ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+ }
+
+ op->out.resume_idx = resume_idx_out;
+ op->out.num_groups = num_groups_out;
+ op->out.rids = rids_out;
+ op->out.names = names_out;
+ op->out.descriptions = desc_out;
+
+ return CAC_SUCCESS;
}
-int cac_SamEnumAliases(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamEnumAliases *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- uint32 i = 0;
-
- uint32 resume_idx_out = 0;
- char **names_out = NULL;
- char **desc_out = NULL;
- uint32 *rids_out = NULL;
- uint32 num_als_out = 0;
-
- struct acct_info *acct_buf = NULL;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || !op->in.dom_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- /*this is a hack.. but is the only reliable way to know if everything has been enumerated*/
- if(op->out.done == True) {
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- resume_idx_out = op->out.resume_idx;
-
- hnd->status = rpccli_samr_enum_als_groups( pipe_hnd, mem_ctx, op->in.dom_hnd, &resume_idx_out, SAMR_ENUM_MAX_SIZE,
- &acct_buf, &num_als_out);
-
-
- if(NT_STATUS_IS_OK(hnd->status))
- op->out.done = True;
-
- /*if there are no more entries, the operation will return NT_STATUS_OK.
- * We want to return failure if no results were returned*/
- if(!NT_STATUS_IS_OK(hnd->status) && NT_STATUS_V(hnd->status) != NT_STATUS_V(STATUS_MORE_ENTRIES))
- return CAC_FAILURE;
-
- names_out = talloc_array(mem_ctx, char *, num_als_out);
- if(!names_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- TALLOC_FREE(acct_buf);
- return CAC_FAILURE;
- }
-
- desc_out = talloc_array(mem_ctx, char *, num_als_out);
- if(!desc_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- TALLOC_FREE(acct_buf);
- TALLOC_FREE(names_out);
- return CAC_FAILURE;
- }
-
- rids_out = talloc_array(mem_ctx, uint32, num_als_out);
- if(!rids_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- TALLOC_FREE(acct_buf);
- TALLOC_FREE(names_out);
- TALLOC_FREE(desc_out);
- return CAC_FAILURE;
- }
-
- for(i = 0; i < num_als_out; i++) {
- names_out[i] = talloc_strdup(mem_ctx, acct_buf[i].acct_name);
- desc_out[i] = talloc_strdup(mem_ctx, acct_buf[i].acct_desc);
- rids_out[i] = acct_buf[i].rid;
-
- if(!names_out[i] || !desc_out[i]) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
- }
-
- op->out.resume_idx = resume_idx_out;
- op->out.num_aliases = num_als_out;
- op->out.rids = rids_out;
- op->out.names = names_out;
- op->out.descriptions = desc_out;
-
- return CAC_SUCCESS;
+int cac_SamEnumAliases( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamEnumAliases *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ uint32 i = 0;
+
+ uint32 resume_idx_out = 0;
+ char **names_out = NULL;
+ char **desc_out = NULL;
+ uint32 *rids_out = NULL;
+ uint32 num_als_out = 0;
+
+ struct acct_info *acct_buf = NULL;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || !op->in.dom_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ /*this is a hack.. but is the only reliable way to know if everything has been enumerated */
+ if ( op->out.done == True ) {
+ return CAC_FAILURE;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ resume_idx_out = op->out.resume_idx;
+
+ hnd->status =
+ rpccli_samr_enum_als_groups( pipe_hnd, mem_ctx,
+ op->in.dom_hnd, &resume_idx_out,
+ SAMR_ENUM_MAX_SIZE, &acct_buf,
+ &num_als_out );
+
+
+ if ( NT_STATUS_IS_OK( hnd->status ) )
+ op->out.done = True;
+
+ /*if there are no more entries, the operation will return NT_STATUS_OK.
+ * We want to return failure if no results were returned*/
+ if ( !NT_STATUS_IS_OK( hnd->status )
+ && NT_STATUS_V( hnd->status ) !=
+ NT_STATUS_V( STATUS_MORE_ENTRIES ) )
+ return CAC_FAILURE;
+
+ names_out = talloc_array( mem_ctx, char *, num_als_out );
+ if ( !names_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ TALLOC_FREE( acct_buf );
+ return CAC_FAILURE;
+ }
+
+ desc_out = talloc_array( mem_ctx, char *, num_als_out );
+ if ( !desc_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ TALLOC_FREE( acct_buf );
+ TALLOC_FREE( names_out );
+ return CAC_FAILURE;
+ }
+
+ rids_out = talloc_array( mem_ctx, uint32, num_als_out );
+ if ( !rids_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ TALLOC_FREE( acct_buf );
+ TALLOC_FREE( names_out );
+ TALLOC_FREE( desc_out );
+ return CAC_FAILURE;
+ }
+
+ for ( i = 0; i < num_als_out; i++ ) {
+ names_out[i] =
+ talloc_strdup( mem_ctx, acct_buf[i].acct_name );
+ desc_out[i] = talloc_strdup( mem_ctx, acct_buf[i].acct_desc );
+ rids_out[i] = acct_buf[i].rid;
+
+ if ( !names_out[i] || !desc_out[i] ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+ }
+
+ op->out.resume_idx = resume_idx_out;
+ op->out.num_aliases = num_als_out;
+ op->out.rids = rids_out;
+ op->out.names = names_out;
+ op->out.descriptions = desc_out;
+
+ return CAC_SUCCESS;
}
-int cac_SamCreateAlias(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamCreateAlias *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamCreateAlias( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamCreateAlias *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- POLICY_HND *als_hnd_out = NULL;
+ POLICY_HND *als_hnd_out = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.name || op->in.name[0] == '\0' || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.name || op->in.name[0] == '\0' || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- als_hnd_out = talloc(mem_ctx, POLICY_HND);
- if(!als_hnd_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ als_hnd_out = talloc( mem_ctx, POLICY_HND );
+ if ( !als_hnd_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_create_dom_alias( pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.name, als_hnd_out);
+ hnd->status =
+ rpccli_samr_create_dom_alias( pipe_hnd, mem_ctx,
+ op->in.dom_hnd, op->in.name,
+ als_hnd_out );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.alias_hnd = als_hnd_out;
+ op->out.alias_hnd = als_hnd_out;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamOpenAlias(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamOpenAlias *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamOpenAlias( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamOpenAlias *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- POLICY_HND *als_hnd_out = NULL;
+ POLICY_HND *als_hnd_out = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || op->in.access == 0 || op->in.rid == 0 || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || op->in.access == 0 || op->in.rid == 0 || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- als_hnd_out = talloc(mem_ctx, POLICY_HND);
- if(!als_hnd_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ als_hnd_out = talloc( mem_ctx, POLICY_HND );
+ if ( !als_hnd_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_open_alias( pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.access, op->in.rid, als_hnd_out);
+ hnd->status =
+ rpccli_samr_open_alias( pipe_hnd, mem_ctx, op->in.dom_hnd,
+ op->in.access, op->in.rid,
+ als_hnd_out );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.alias_hnd = als_hnd_out;
+ op->out.alias_hnd = als_hnd_out;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamDeleteAlias(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *alias_hnd) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamDeleteAlias( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ POLICY_HND * alias_hnd )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!alias_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !alias_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_delete_dom_alias( pipe_hnd, mem_ctx, alias_hnd);
+ hnd->status =
+ rpccli_samr_delete_dom_alias( pipe_hnd, mem_ctx, alias_hnd );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamAddAliasMember(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamAddAliasMember *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamAddAliasMember( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamAddAliasMember *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.alias_hnd || !op->in.sid || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.alias_hnd || !op->in.sid || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx, op->in.alias_hnd, op->in.sid);
+ hnd->status =
+ rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx, op->in.alias_hnd,
+ op->in.sid );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamRemoveAliasMember(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamRemoveAliasMember *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamRemoveAliasMember( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamRemoveAliasMember *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.alias_hnd || !op->in.sid || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.alias_hnd || !op->in.sid || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_del_aliasmem( pipe_hnd, mem_ctx, op->in.alias_hnd, op->in.sid);
+ hnd->status =
+ rpccli_samr_del_aliasmem( pipe_hnd, mem_ctx, op->in.alias_hnd,
+ op->in.sid );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamGetAliasMembers(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetAliasMembers *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamGetAliasMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamGetAliasMembers *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- uint32 num_mem_out;
- DOM_SID *sids_out;
+ uint32 num_mem_out;
+ DOM_SID *sids_out;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.alias_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.alias_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_query_aliasmem( pipe_hnd, mem_ctx, op->in.alias_hnd, &num_mem_out, &sids_out);
+ hnd->status =
+ rpccli_samr_query_aliasmem( pipe_hnd, mem_ctx,
+ op->in.alias_hnd, &num_mem_out,
+ &sids_out );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.num_members = num_mem_out;
- op->out.sids = sids_out;
+ op->out.num_members = num_mem_out;
+ op->out.sids = sids_out;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamClearAliasMembers(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *alias_hnd) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- int result = CAC_SUCCESS;
-
- int i = 0;
-
- uint32 num_mem = 0;
- DOM_SID *sid = NULL;
-
- NTSTATUS status;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!alias_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+int cac_SamClearAliasMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ POLICY_HND * alias_hnd )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- hnd->status = rpccli_samr_query_aliasmem(pipe_hnd, mem_ctx, alias_hnd, &num_mem, &sid);
-
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ int result = CAC_SUCCESS;
- /*try to delete the users one by one*/
- for(i = 0; i < num_mem && NT_STATUS_IS_OK(hnd->status); i++) {
- hnd->status = rpccli_samr_del_aliasmem(pipe_hnd, mem_ctx, alias_hnd, &sid[i]);
- }
+ int i = 0;
- /*if not all members could be removed, then try to re-add the members that were already deleted*/
- if(!NT_STATUS_IS_OK(hnd->status)) {
- status = NT_STATUS_OK;
+ uint32 num_mem = 0;
+ DOM_SID *sid = NULL;
- for(i -= 1; i >= 0 && NT_STATUS_IS_OK(status); i--) {
- status = rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx, alias_hnd, &sid[i]);
- }
+ NTSTATUS status;
- /*we return with the NTSTATUS error that we got when trying to delete users*/
- if(!NT_STATUS_IS_OK(status))
- result = CAC_FAILURE;
- }
+ if ( !hnd )
+ return CAC_FAILURE;
- TALLOC_FREE(sid);
- return result;
-}
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
-int cac_SamSetAliasMembers(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamSetAliasMembers *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+ if ( !alias_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- uint32 i = 0;
-
- if(!hnd)
- return CAC_FAILURE;
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ hnd->status =
+ rpccli_samr_query_aliasmem( pipe_hnd, mem_ctx, alias_hnd,
+ &num_mem, &sid );
- if(!op || !op->in.alias_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ /*try to delete the users one by one */
+ for ( i = 0; i < num_mem && NT_STATUS_IS_OK( hnd->status ); i++ ) {
+ hnd->status =
+ rpccli_samr_del_aliasmem( pipe_hnd, mem_ctx,
+ alias_hnd, &sid[i] );
+ }
- /*use cac_SamClearAliasMembers() to clear them*/
- if(!cac_SamClearAliasMembers(hnd, mem_ctx, op->in.alias_hnd))
- return CAC_FAILURE; /*hnd->status is already set*/
+ /*if not all members could be removed, then try to re-add the members that were already deleted */
+ if ( !NT_STATUS_IS_OK( hnd->status ) ) {
+ status = NT_STATUS_OK;
+ for ( i -= 1; i >= 0 && NT_STATUS_IS_OK( status ); i-- ) {
+ status = rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx,
+ alias_hnd,
+ &sid[i] );
+ }
- for(i = 0; i < op->in.num_members && NT_STATUS_IS_OK(hnd->status); i++) {
- hnd->status = rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx, op->in.alias_hnd, &(op->in.sids[i]));
- }
+ /*we return with the NTSTATUS error that we got when trying to delete users */
+ if ( !NT_STATUS_IS_OK( status ) )
+ result = CAC_FAILURE;
+ }
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ TALLOC_FREE( sid );
+ return result;
+}
- return CAC_SUCCESS;
+int cac_SamSetAliasMembers( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamSetAliasMembers *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
-}
+ uint32 i = 0;
-int cac_SamUserChangePasswd(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamUserChangePasswd *op) {
- SMBCSRV *srv = NULL;
- struct rpc_pipe_client *pipe_hnd = NULL;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.alias_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.username || !op->in.password || !op->in.new_password || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- srv = cac_GetServer(hnd);
- if(!srv) {
- hnd->status = NT_STATUS_INVALID_CONNECTION;
- return CAC_FAILURE;
- }
+ /*use cac_SamClearAliasMembers() to clear them */
+ if ( !cac_SamClearAliasMembers( hnd, mem_ctx, op->in.alias_hnd ) )
+ return CAC_FAILURE; /*hnd->status is already set */
- /*open a session on SAMR if we don't have one*/
- if(!hnd->_internal.pipes[PI_SAMR]) {
- if(!(pipe_hnd = cli_rpc_pipe_open_noauth(&srv->cli, PI_SAMR, &(hnd->status)))) {
- return CAC_FAILURE;
- }
- hnd->_internal.pipes[PI_SAMR] = True;
- }
+ for ( i = 0; i < op->in.num_members && NT_STATUS_IS_OK( hnd->status );
+ i++ ) {
+ hnd->status =
+ rpccli_samr_add_aliasmem( pipe_hnd, mem_ctx,
+ op->in.alias_hnd,
+ &( op->in.sids[i] ) );
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- hnd->status = rpccli_samr_chgpasswd_user(pipe_hnd, mem_ctx, op->in.username, op->in.new_password, op->in.password);
+ return CAC_SUCCESS;
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+}
- return CAC_SUCCESS;
+int cac_SamUserChangePasswd( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamUserChangePasswd *op )
+{
+ SMBCSRV *srv = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || !op->in.username || !op->in.password
+ || !op->in.new_password || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ srv = cac_GetServer( hnd );
+ if ( !srv ) {
+ hnd->status = NT_STATUS_INVALID_CONNECTION;
+ return CAC_FAILURE;
+ }
+
+ /*open a session on SAMR if we don't have one */
+ if ( !hnd->_internal.pipes[PI_SAMR] ) {
+ if ( !
+ ( pipe_hnd =
+ cli_rpc_pipe_open_noauth( srv->cli, PI_SAMR,
+ &hnd->status ) ) ) {
+ return CAC_FAILURE;
+ }
+
+ hnd->_internal.pipes[PI_SAMR] = True;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ hnd->status =
+ rpccli_samr_chgpasswd_user( pipe_hnd, mem_ctx,
+ op->in.username,
+ op->in.new_password,
+ op->in.password );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
+
+ return CAC_SUCCESS;
}
-int cac_SamEnableUser(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *user_hnd) {
- SMBCSRV *srv = NULL;
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamEnableUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ POLICY_HND * user_hnd )
+{
+ SMBCSRV *srv = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
- SAM_USERINFO_CTR *ctr;
+ SAM_USERINFO_CTR *ctr;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!user_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !user_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- srv = cac_GetServer(hnd);
- if(!srv) {
- hnd->status = NT_STATUS_INVALID_CONNECTION;
- return CAC_FAILURE;
- }
+ srv = cac_GetServer( hnd );
+ if ( !srv ) {
+ hnd->status = NT_STATUS_INVALID_CONNECTION;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- /*info_level = 21 is the only level that I have found to work reliably. It would be nice if user_level = 10 worked.*/
- hnd->status = rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, user_hnd, 0x10, &ctr);
+ /*info_level = 21 is the only level that I have found to work reliably. It would be nice if user_level = 10 worked. */
+ hnd->status =
+ rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, user_hnd, 0x10,
+ &ctr );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
/**check the ACB mask*/
- if((ctr->info.id16->acb_info & ACB_DISABLED) == ACB_DISABLED) {
- /*toggle the disabled bit*/
- ctr->info.id16->acb_info ^= ACB_DISABLED;
- }
- else {
- /*the user is already enabled so just return success*/
- return CAC_SUCCESS;
- }
-
- /*now set the userinfo*/
- hnd->status = rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx, user_hnd, 0x10, &(srv->cli.user_session_key), ctr);
-
- /*this will only work properly if we use set_userinfo2 - fail if it is not supported*/
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
-
- return CAC_SUCCESS;
+ if ( ( ctr->info.id16->acb_info & ACB_DISABLED ) == ACB_DISABLED ) {
+ /*toggle the disabled bit */
+ ctr->info.id16->acb_info ^= ACB_DISABLED;
+ } else {
+ /*the user is already enabled so just return success */
+ return CAC_SUCCESS;
+ }
+
+ /*now set the userinfo */
+ hnd->status =
+ rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx, user_hnd, 0x10,
+ &srv->cli->user_session_key, ctr );
+
+ /*this will only work properly if we use set_userinfo2 - fail if it is not supported */
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
+
+ return CAC_SUCCESS;
}
-int cac_SamDisableUser(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *user_hnd) {
- SMBCSRV *srv = NULL;
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamDisableUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ POLICY_HND * user_hnd )
+{
+ SMBCSRV *srv = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
- SAM_USERINFO_CTR *ctr;
+ SAM_USERINFO_CTR *ctr;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!user_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !user_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- srv = cac_GetServer(hnd);
- if(!srv) {
- hnd->status = NT_STATUS_INVALID_CONNECTION;
- return CAC_FAILURE;
- }
+ srv = cac_GetServer( hnd );
+ if ( !srv ) {
+ hnd->status = NT_STATUS_INVALID_CONNECTION;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, user_hnd, 0x10, &ctr);
+ hnd->status =
+ rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, user_hnd, 0x10,
+ &ctr );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- if((ctr->info.id16->acb_info & ACB_DISABLED) == ACB_DISABLED) {
- /*then the user is already disabled*/
- return CAC_SUCCESS;
- }
+ if ( ( ctr->info.id16->acb_info & ACB_DISABLED ) == ACB_DISABLED ) {
+ /*then the user is already disabled */
+ return CAC_SUCCESS;
+ }
- /*toggle the disabled bit*/
- ctr->info.id16->acb_info ^= ACB_DISABLED;
+ /*toggle the disabled bit */
+ ctr->info.id16->acb_info ^= ACB_DISABLED;
- /*this will only work properly if we use set_userinfo2*/
- hnd->status = rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx, user_hnd, 0x10, &(srv->cli.user_session_key), ctr);
+ /*this will only work properly if we use set_userinfo2 */
+ hnd->status =
+ rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx, user_hnd, 0x10,
+ &srv->cli->user_session_key, ctr );
- /*this will only work properly if we use set_userinfo2 fail if it is not supported*/
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ /*this will only work properly if we use set_userinfo2 fail if it is not supported */
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamSetPassword(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamSetPassword *op) {
- SMBCSRV *srv = NULL;
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamSetPassword( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamSetPassword *op )
+{
+ SMBCSRV *srv = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
- SAM_USERINFO_CTR ctr;
- SAM_USER_INFO_24 info24;
- uint8 pw[516];
+ SAM_USERINFO_CTR ctr;
+ SAM_USER_INFO_24 info24;
+ uint8 pw[516];
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op->in.user_hnd || !op->in.password || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op->in.user_hnd || !op->in.password || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- srv = cac_GetServer(hnd);
- if(!srv) {
- hnd->status = NT_STATUS_INVALID_CONNECTION;
- return CAC_FAILURE;
- }
+ srv = cac_GetServer( hnd );
+ if ( !srv ) {
+ hnd->status = NT_STATUS_INVALID_CONNECTION;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- ZERO_STRUCT(ctr);
- ZERO_STRUCT(info24);
+ ZERO_STRUCT( ctr );
+ ZERO_STRUCT( info24 );
- encode_pw_buffer(pw, op->in.password, STR_UNICODE);
+ encode_pw_buffer( pw, op->in.password, STR_UNICODE );
- init_sam_user_info24(&info24, (char *)pw, 24);
+ init_sam_user_info24( &info24, ( char * ) pw, 24 );
- ctr.switch_value = 24;
- ctr.info.id24 = &info24;
+ ctr.switch_value = 24;
+ ctr.info.id24 = &info24;
- hnd->status = rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, 24, &(srv->cli.user_session_key), &ctr);
+ hnd->status =
+ rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd,
+ 24, &srv->cli->user_session_key,
+ &ctr );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamGetUserInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetUserInfo *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamGetUserInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamGetUserInfo *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- SAM_USERINFO_CTR *ctr;
+ SAM_USERINFO_CTR *ctr;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op->in.user_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op->in.user_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, 21, &ctr);
+ hnd->status =
+ rpccli_samr_query_userinfo( pipe_hnd, mem_ctx,
+ op->in.user_hnd, 21, &ctr );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.info = cac_MakeUserInfo(mem_ctx, ctr);
+ op->out.info = cac_MakeUserInfo( mem_ctx, ctr );
- if(!op->out.info) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ if ( !op->out.info ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamSetUserInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamSetUserInfo *op) {
- SMBCSRV *srv = NULL;
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- SAM_USERINFO_CTR *ctr;
-
- if(!hnd)
- return CAC_FAILURE;
+int cac_SamSetUserInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamSetUserInfo *op )
+{
+ SMBCSRV *srv = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ SAM_USERINFO_CTR *ctr;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op->in.user_hnd || !op->in.info || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ ctr = cac_MakeUserInfoCtr( mem_ctx, op->in.info );
+ if ( !ctr ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ srv = cac_GetServer( hnd );
+ if ( !srv ) {
+ hnd->status = NT_STATUS_INVALID_CONNECTION;
+ return CAC_FAILURE;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( hnd->_internal.srv_level >= SRV_WIN_NT4 ) {
+ hnd->status =
+ rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx,
+ op->in.user_hnd, 21,
+ &srv->cli->
+ user_session_key, ctr );
+ }
+
+ if ( hnd->_internal.srv_level < SRV_WIN_NT4
+ || !NT_STATUS_IS_OK( hnd->status ) ) {
+ hnd->status =
+ rpccli_samr_set_userinfo( pipe_hnd, mem_ctx,
+ op->in.user_hnd, 21,
+ &srv->cli->user_session_key,
+ ctr );
+
+ if ( NT_STATUS_IS_OK( hnd->status )
+ && hnd->_internal.srv_level > SRV_WIN_NT4 ) {
+ hnd->_internal.srv_level = SRV_WIN_NT4;
+ }
+ }
+
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
+
+ return CAC_SUCCESS;
+}
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
- if(!op->in.user_hnd || !op->in.info || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+int cac_SamGetUserInfoCtr( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamGetUserInfoCtr *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- ctr = cac_MakeUserInfoCtr(mem_ctx, op->in.info);
- if(!ctr) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ SAM_USERINFO_CTR *ctr_out;
- srv = cac_GetServer(hnd);
- if(!srv) {
- hnd->status = NT_STATUS_INVALID_CONNECTION;
- return CAC_FAILURE;
- }
+ if ( !hnd )
+ return CAC_FAILURE;
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(hnd->_internal.srv_level >= SRV_WIN_NT4) {
- hnd->status = rpccli_samr_set_userinfo2( pipe_hnd, mem_ctx, op->in.user_hnd, 21, &(srv->cli.user_session_key), ctr);
- }
+ if ( !op->in.user_hnd || op->in.info_class == 0 || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- if(hnd->_internal.srv_level < SRV_WIN_NT4 || !NT_STATUS_IS_OK(hnd->status)) {
- hnd->status = rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, 21, &(srv->cli.user_session_key), ctr);
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(NT_STATUS_IS_OK(hnd->status) && hnd->_internal.srv_level > SRV_WIN_NT4) {
- hnd->_internal.srv_level = SRV_WIN_NT4;
- }
- }
+ hnd->status =
+ rpccli_samr_query_userinfo( pipe_hnd, mem_ctx,
+ op->in.user_hnd,
+ op->in.info_class, &ctr_out );
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ op->out.ctr = ctr_out;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
+int cac_SamSetUserInfoCtr( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamSetUserInfoCtr *op )
+{
+ SMBCSRV *srv = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
-int cac_SamGetUserInfoCtr(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetUserInfoCtr *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+ if ( !hnd )
+ return CAC_FAILURE;
- SAM_USERINFO_CTR *ctr_out;
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!hnd)
- return CAC_FAILURE;
+ if ( !op->in.user_hnd || !op->in.ctr || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ srv = cac_GetServer( hnd );
+ if ( !srv ) {
+ hnd->status = NT_STATUS_INVALID_CONNECTION;
+ return CAC_FAILURE;
+ }
- if(!op->in.user_hnd || op->in.info_class == 0 || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
- hnd->status = rpccli_samr_query_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, op->in.info_class, &ctr_out);
+ hnd->status =
+ rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd,
+ op->in.ctr->switch_value,
+ &srv->cli->user_session_key,
+ op->in.ctr );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.ctr = ctr_out;
+ return CAC_SUCCESS;
- return CAC_SUCCESS;
}
-int cac_SamSetUserInfoCtr(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamSetUserInfoCtr *op) {
- SMBCSRV *srv = NULL;
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+int cac_SamRenameUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamRenameUser *op )
+{
+ SMBCSRV *srv = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
- if(!op->in.user_hnd || !op->in.ctr || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ SAM_USERINFO_CTR ctr;
+ SAM_USER_INFO_7 info7;
- srv = cac_GetServer(hnd);
- if(!srv) {
- hnd->status = NT_STATUS_INVALID_CONNECTION;
- return CAC_FAILURE;
- }
+ if ( !hnd )
+ return CAC_FAILURE;
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+ if ( !op->in.user_hnd || !op->in.new_name
+ || op->in.new_name[0] == '\0' || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, op->in.ctr->switch_value, &(srv->cli.user_session_key), op->in.ctr);
+ srv = cac_GetServer( hnd );
+ if ( !srv ) {
+ hnd->status = NT_STATUS_INVALID_CONNECTION;
+ return CAC_FAILURE;
+ }
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- return CAC_SUCCESS;
+ ZERO_STRUCT( ctr );
+ ZERO_STRUCT( info7 );
-}
-
-int cac_SamRenameUser(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamRenameUser *op) {
- SMBCSRV *srv = NULL;
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- SAM_USERINFO_CTR ctr;
- SAM_USER_INFO_7 info7;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ init_sam_user_info7( &info7, op->in.new_name );
- if(!op->in.user_hnd || !op->in.new_name || op->in.new_name[0] == '\0' || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ ctr.switch_value = 7;
+ ctr.info.id7 = &info7;
- srv = cac_GetServer(hnd);
- if(!srv) {
- hnd->status = NT_STATUS_INVALID_CONNECTION;
- return CAC_FAILURE;
- }
+ hnd->status =
+ rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd,
+ 7, &srv->cli->user_session_key,
+ &ctr );
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- ZERO_STRUCT(ctr);
- ZERO_STRUCT(info7);
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- init_sam_user_info7(&info7, op->in.new_name);
-
- ctr.switch_value = 7;
- ctr.info.id7 = &info7;
-
- hnd->status = rpccli_samr_set_userinfo( pipe_hnd, mem_ctx, op->in.user_hnd, 7, &(srv->cli.user_session_key), &ctr);
-
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
-
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamGetGroupInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetGroupInfo *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamGetGroupInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamGetGroupInfo *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- GROUP_INFO_CTR *ctr;
+ GROUP_INFO_CTR *ctr;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op->in.group_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op->in.group_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- /*get a GROUP_INFO_1 structure*/
- hnd->status = rpccli_samr_query_groupinfo( pipe_hnd, mem_ctx, op->in.group_hnd, 1, &ctr);
+ /*get a GROUP_INFO_1 structure */
+ hnd->status =
+ rpccli_samr_query_groupinfo( pipe_hnd, mem_ctx,
+ op->in.group_hnd, 1, &ctr );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.info = cac_MakeGroupInfo(mem_ctx, ctr);
- if(!op->out.info) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ op->out.info = cac_MakeGroupInfo( mem_ctx, ctr );
+ if ( !op->out.info ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamSetGroupInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamSetGroupInfo *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamSetGroupInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamSetGroupInfo *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- GROUP_INFO_CTR *ctr = NULL;
+ GROUP_INFO_CTR *ctr = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op->in.group_hnd || !op->in.info || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op->in.group_hnd || !op->in.info || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- ctr = cac_MakeGroupInfoCtr(mem_ctx, op->in.info);
- if(!ctr) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ ctr = cac_MakeGroupInfoCtr( mem_ctx, op->in.info );
+ if ( !ctr ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_set_groupinfo(pipe_hnd, mem_ctx, op->in.group_hnd, ctr);
+ hnd->status =
+ rpccli_samr_set_groupinfo( pipe_hnd, mem_ctx,
+ op->in.group_hnd, ctr );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamRenameGroup(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamRenameGroup *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamRenameGroup( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamRenameGroup *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- GROUP_INFO_CTR ctr;
+ GROUP_INFO_CTR ctr;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op->in.group_hnd || !op->in.new_name || op->in.new_name[0] == '\0' || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op->in.group_hnd || !op->in.new_name
+ || op->in.new_name[0] == '\0' || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- ZERO_STRUCT(ctr);
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- init_samr_group_info2(&ctr.group.info2, op->in.new_name);
- ctr.switch_value1 = 2;
-
- hnd->status = rpccli_samr_set_groupinfo( pipe_hnd, mem_ctx, op->in.group_hnd, &ctr);
+ ZERO_STRUCT( ctr );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ init_samr_group_info2( &ctr.group.info2, op->in.new_name );
+ ctr.switch_value1 = 2;
- return CAC_SUCCESS;
-}
+ hnd->status =
+ rpccli_samr_set_groupinfo( pipe_hnd, mem_ctx,
+ op->in.group_hnd, &ctr );
-int cac_SamGetAliasInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetAliasInfo *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- ALIAS_INFO_CTR ctr;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op->in.alias_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- /*get a GROUP_INFO_1 structure*/
- hnd->status = rpccli_samr_query_alias_info( pipe_hnd, mem_ctx, op->in.alias_hnd, 1, &ctr);
-
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
-
- op->out.info = cac_MakeAliasInfo(mem_ctx, ctr);
- if(!op->out.info) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- return CAC_SUCCESS;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
+ return CAC_SUCCESS;
}
-int cac_SamSetAliasInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamSetAliasInfo *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamGetAliasInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamGetAliasInfo *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- ALIAS_INFO_CTR *ctr = NULL;
+ ALIAS_INFO_CTR ctr;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op->in.alias_hnd || !op->in.info || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op->in.alias_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- ctr = cac_MakeAliasInfoCtr(mem_ctx, op->in.info);
- if(!ctr) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ /*get a GROUP_INFO_1 structure */
+ hnd->status =
+ rpccli_samr_query_alias_info( pipe_hnd, mem_ctx,
+ op->in.alias_hnd, 1, &ctr );
- hnd->status = rpccli_samr_set_aliasinfo(pipe_hnd, mem_ctx, op->in.alias_hnd, ctr);
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ op->out.info = cac_MakeAliasInfo( mem_ctx, ctr );
+ if ( !op->out.info ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- return CAC_SUCCESS;
-}
+ return CAC_SUCCESS;
-int cac_SamGetDomainInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetDomainInfo *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- SAM_UNK_CTR ctr;
- SAM_UNK_INFO_1 info1;
- SAM_UNK_INFO_2 info2;
- SAM_UNK_INFO_12 info12;
-
- /*use this to keep track of a failed call*/
- NTSTATUS status_buf = NT_STATUS_OK;
-
- uint16 fail_count = 0;
-
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op->in.dom_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- /*first try with info 1*/
- hnd->status = rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd, 1, &ctr);
-
- if(NT_STATUS_IS_OK(hnd->status)) {
- /*then we buffer the SAM_UNK_INFO_1 structure*/
- info1 = ctr.info.inf1;
- }
- else {
- /*then the call failed, store the status and ZERO out the info structure*/
- ZERO_STRUCT(info1);
- status_buf = hnd->status;
- fail_count++;
- }
-
- /*try again for the next one*/
- hnd->status = rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd, 2, &ctr);
-
- if(NT_STATUS_IS_OK(hnd->status)) {
- /*store the info*/
- info2 = ctr.info.inf2;
- }
- else {
- /*ZERO out the structure and store the bad status*/
- ZERO_STRUCT(info2);
- status_buf = hnd->status;
- fail_count++;
- }
-
- /*once more*/
- hnd->status = rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd, 12, &ctr);
-
- if(NT_STATUS_IS_OK(hnd->status)) {
- info12 = ctr.info.inf12;
- }
- else {
- ZERO_STRUCT(info12);
- status_buf = hnd->status;
- fail_count++;
- }
-
- /*return failure if all 3 calls failed*/
- if(fail_count == 3)
- return CAC_FAILURE;
-
- op->out.info = cac_MakeDomainInfo(mem_ctx, &info1, &info2, &info12);
-
- if(!op->out.info) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- if(fail_count > 0) {
- hnd->status = status_buf;
- return CAC_PARTIAL_SUCCESS;
- }
-
- return CAC_SUCCESS;
}
-int cac_SamGetDomainInfoCtr(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetDomainInfoCtr *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- SAM_UNK_CTR *ctr_out;
+int cac_SamSetAliasInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamSetAliasInfo *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ ALIAS_INFO_CTR *ctr = NULL;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!op->in.dom_hnd || op->in.info_class == 0 || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !op->in.alias_hnd || !op->in.info || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- ctr_out = talloc(mem_ctx, SAM_UNK_CTR);
- if(!ctr_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ ctr = cac_MakeAliasInfoCtr( mem_ctx, op->in.info );
+ if ( !ctr ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd, op->in.info_class, ctr_out);
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ hnd->status =
+ rpccli_samr_set_aliasinfo( pipe_hnd, mem_ctx,
+ op->in.alias_hnd, ctr );
- op->out.info = ctr_out;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamGetDisplayInfo(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetDisplayInfo *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
-
- SAM_DISPINFO_CTR ctr_out;
-
- uint32 max_entries_buf = 0;
- uint32 max_size_buf = 0;
-
- uint32 resume_idx_out;
- uint32 num_entries_out;
+int cac_SamGetDomainInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamGetDomainInfo *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ SAM_UNK_CTR ctr;
+ SAM_UNK_INFO_1 info1;
+ SAM_UNK_INFO_2 info2;
+ SAM_UNK_INFO_12 info12;
+
+ /*use this to keep track of a failed call */
+ NTSTATUS status_buf = NT_STATUS_OK;
+
+ uint16 fail_count = 0;
+
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op->in.dom_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ /*first try with info 1 */
+ hnd->status =
+ rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd,
+ 1, &ctr );
+
+ if ( NT_STATUS_IS_OK( hnd->status ) ) {
+ /*then we buffer the SAM_UNK_INFO_1 structure */
+ info1 = ctr.info.inf1;
+ } else {
+ /*then the call failed, store the status and ZERO out the info structure */
+ ZERO_STRUCT( info1 );
+ status_buf = hnd->status;
+ fail_count++;
+ }
+
+ /*try again for the next one */
+ hnd->status =
+ rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd,
+ 2, &ctr );
+
+ if ( NT_STATUS_IS_OK( hnd->status ) ) {
+ /*store the info */
+ info2 = ctr.info.inf2;
+ } else {
+ /*ZERO out the structure and store the bad status */
+ ZERO_STRUCT( info2 );
+ status_buf = hnd->status;
+ fail_count++;
+ }
+
+ /*once more */
+ hnd->status =
+ rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd,
+ 12, &ctr );
+
+ if ( NT_STATUS_IS_OK( hnd->status ) ) {
+ info12 = ctr.info.inf12;
+ } else {
+ ZERO_STRUCT( info12 );
+ status_buf = hnd->status;
+ fail_count++;
+ }
+
+ /*return failure if all 3 calls failed */
+ if ( fail_count == 3 )
+ return CAC_FAILURE;
+
+ op->out.info = cac_MakeDomainInfo( mem_ctx, &info1, &info2, &info12 );
+
+ if ( !op->out.info ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ if ( fail_count > 0 ) {
+ hnd->status = status_buf;
+ return CAC_PARTIAL_SUCCESS;
+ }
+
+ return CAC_SUCCESS;
+}
- if(!hnd)
- return CAC_FAILURE;
+int cac_SamGetDomainInfoCtr( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamGetDomainInfoCtr *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ SAM_UNK_CTR *ctr_out;
- if(!op->in.dom_hnd || op->in.info_class == 0 || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !hnd )
+ return CAC_FAILURE;
- if(op->out.done == True) /*this is done so we can use the function as a loop condition*/
- return CAC_FAILURE;
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !op->in.dom_hnd || op->in.info_class == 0 || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- if(op->in.max_entries == 0 || op->in.max_size == 0) {
- get_query_dispinfo_params(op->out.loop_count, &max_entries_buf, &max_size_buf);
- }
- else {
- max_entries_buf = op->in.max_entries;
- max_size_buf = op->in.max_size;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- resume_idx_out = op->out.resume_idx;
+ ctr_out = talloc( mem_ctx, SAM_UNK_CTR );
+ if ( !ctr_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_query_dispinfo( pipe_hnd, mem_ctx, op->in.dom_hnd, &resume_idx_out, op->in.info_class,
- &num_entries_out, max_entries_buf, max_size_buf, &ctr_out);
+ hnd->status =
+ rpccli_samr_query_dom_info( pipe_hnd, mem_ctx, op->in.dom_hnd,
+ op->in.info_class, ctr_out );
- if(!NT_STATUS_IS_OK(hnd->status) && !NT_STATUS_EQUAL(hnd->status, STATUS_MORE_ENTRIES)) {
- /*be defensive, maybe they'll call again without zeroing the struct*/
- op->out.loop_count = 0;
- op->out.resume_idx = 0;
- return CAC_FAILURE;
- }
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- if(NT_STATUS_IS_OK(hnd->status)) {
- /*we want to quit once the function is called next. so it can be used in a loop*/
- op->out.done = True;
- }
+ op->out.info = ctr_out;
- op->out.resume_idx = resume_idx_out;
- op->out.num_entries = num_entries_out;
- op->out.ctr = ctr_out;
- op->out.loop_count++;
+ return CAC_SUCCESS;
+}
- return CAC_SUCCESS;
+int cac_SamGetDisplayInfo( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamGetDisplayInfo *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ SAM_DISPINFO_CTR ctr_out;
+
+ uint32 max_entries_buf = 0;
+ uint32 max_size_buf = 0;
+
+ uint32 resume_idx_out;
+ uint32 num_entries_out;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op->in.dom_hnd || op->in.info_class == 0 || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ if ( op->out.done == True ) /*this is done so we can use the function as a loop condition */
+ return CAC_FAILURE;
+
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( op->in.max_entries == 0 || op->in.max_size == 0 ) {
+ get_query_dispinfo_params( op->out.loop_count,
+ &max_entries_buf, &max_size_buf );
+ } else {
+ max_entries_buf = op->in.max_entries;
+ max_size_buf = op->in.max_size;
+ }
+
+ resume_idx_out = op->out.resume_idx;
+
+ hnd->status =
+ rpccli_samr_query_dispinfo( pipe_hnd, mem_ctx, op->in.dom_hnd,
+ &resume_idx_out,
+ op->in.info_class,
+ &num_entries_out, max_entries_buf,
+ max_size_buf, &ctr_out );
+
+ if ( !NT_STATUS_IS_OK( hnd->status )
+ && !NT_STATUS_EQUAL( hnd->status, STATUS_MORE_ENTRIES ) ) {
+ /*be defensive, maybe they'll call again without zeroing the struct */
+ op->out.loop_count = 0;
+ op->out.resume_idx = 0;
+ return CAC_FAILURE;
+ }
+
+ if ( NT_STATUS_IS_OK( hnd->status ) ) {
+ /*we want to quit once the function is called next. so it can be used in a loop */
+ op->out.done = True;
+ }
+
+ op->out.resume_idx = resume_idx_out;
+ op->out.num_entries = num_entries_out;
+ op->out.ctr = ctr_out;
+ op->out.loop_count++;
+
+ return CAC_SUCCESS;
}
-int cac_SamLookupDomain(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamLookupDomain *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamLookupDomain( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamLookupDomain *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ DOM_SID *sid_out = NULL;
- DOM_SID *sid_out = NULL;
-
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op->in.sam || !op->in.name || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op->in.sam || !op->in.name || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- sid_out = talloc(mem_ctx, DOM_SID);
- if(!sid_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ sid_out = talloc( mem_ctx, DOM_SID );
+ if ( !sid_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_lookup_domain( pipe_hnd, mem_ctx, op->in.sam, op->in.name, sid_out);
+ hnd->status =
+ rpccli_samr_lookup_domain( pipe_hnd, mem_ctx, op->in.sam,
+ op->in.name, sid_out );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.sid = sid_out;
+ op->out.sid = sid_out;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamGetSecurityObject(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamGetSecurityObject *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
+int cac_SamGetSecurityObject( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamGetSecurityObject *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
- /*this number taken from rpcclient/cmd_samr.c, I think it is the only supported level*/
- uint32 sec_info = DACL_SECURITY_INFORMATION;
+ /*this number taken from rpcclient/cmd_samr.c, I think it is the only supported level */
+ uint32 sec_info = DACL_SECURITY_INFORMATION;
- SEC_DESC_BUF *sec_out = NULL;
+ SEC_DESC_BUF *sec_out = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op->in.pol || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op->in.pol || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SAMR);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SAMR );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- hnd->status = rpccli_samr_query_sec_obj(pipe_hnd, mem_ctx, op->in.pol, sec_info, mem_ctx, &sec_out);
+ hnd->status =
+ rpccli_samr_query_sec_obj( pipe_hnd, mem_ctx, op->in.pol,
+ sec_info, mem_ctx, &sec_out );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.sec = sec_out;
+ op->out.sec = sec_out;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SamFlush(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SamFlush *op) {
- struct SamOpenDomain od;
+int cac_SamFlush( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SamFlush *op )
+{
+ struct SamOpenDomain od;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR]) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx || !hnd->_internal.pipes[PI_SAMR] ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.dom_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.dom_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- if(!cac_SamClose(hnd, mem_ctx, op->in.dom_hnd))
- return CAC_FAILURE;
+ if ( !cac_SamClose( hnd, mem_ctx, op->in.dom_hnd ) )
+ return CAC_FAILURE;
- ZERO_STRUCT(od);
- od.in.access = (op->in.access) ? op->in.access : MAXIMUM_ALLOWED_ACCESS;
- od.in.sid = op->in.sid;
+ ZERO_STRUCT( od );
+ od.in.access =
+ ( op->in.access ) ? op->in.access : MAXIMUM_ALLOWED_ACCESS;
+ od.in.sid = op->in.sid;
- if(!cac_SamOpenDomain(hnd, mem_ctx, &od))
- return CAC_FAILURE;
+ if ( !cac_SamOpenDomain( hnd, mem_ctx, &od ) )
+ return CAC_FAILURE;
- /*this function does not use an output parameter to make it as convenient as possible to use*/
- *op->in.dom_hnd = *od.out.dom_hnd;
+ /*this function does not use an output parameter to make it as convenient as possible to use */
+ *op->in.dom_hnd = *od.out.dom_hnd;
- TALLOC_FREE(od.out.dom_hnd);
+ TALLOC_FREE( od.out.dom_hnd );
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
diff --git a/source/libmsrpc/cac_svcctl.c b/source/libmsrpc/cac_svcctl.c
index 83dc0364930..9f61b421298 100644
--- a/source/libmsrpc/cac_svcctl.c
+++ b/source/libmsrpc/cac_svcctl.c
@@ -1,3 +1,4 @@
+
/*
* Unix SMB/CIFS implementation.
* MS-RPC client library implementation (SVCCTL pipe)
@@ -23,259 +24,288 @@
#define WAIT_SLEEP_TIME 300000
-int cac_SvcOpenScm(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcOpenScm *op) {
- SMBCSRV *srv = NULL;
- struct rpc_pipe_client *pipe_hnd = NULL;
- WERROR err;
-
- POLICY_HND *scm_out = NULL;
-
- if(!hnd)
- return CAC_FAILURE;
-
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- if(!op || op->in.access == 0 || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
-
- srv = cac_GetServer(hnd);
- if(!srv) {
- hnd->status = NT_STATUS_INVALID_CONNECTION;
- return CAC_FAILURE;
- }
-
- /*initialize for samr pipe if we have to*/
- if(!hnd->_internal.pipes[PI_SVCCTL]) {
- if(!(pipe_hnd = cli_rpc_pipe_open_noauth(&srv->cli, PI_SVCCTL, &(hnd->status)))) {
- hnd->status = NT_STATUS_UNSUCCESSFUL;
- return CAC_FAILURE;
- }
-
- hnd->_internal.pipes[PI_SVCCTL] = True;
- }
-
- scm_out = talloc(mem_ctx, POLICY_HND);
- if(!scm_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
-
- err = rpccli_svcctl_open_scm( pipe_hnd, mem_ctx, scm_out, op->in.access);
- hnd->status = werror_to_ntstatus(err);
-
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
-
- op->out.scm_hnd = scm_out;
-
- return CAC_SUCCESS;
+int cac_SvcOpenScm( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SvcOpenScm *op )
+{
+ SMBCSRV *srv = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ WERROR err;
+
+ POLICY_HND *scm_out = NULL;
+
+ if ( !hnd )
+ return CAC_FAILURE;
+
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ if ( !op || op->in.access == 0 || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
+
+ srv = cac_GetServer( hnd );
+ if ( !srv ) {
+ hnd->status = NT_STATUS_INVALID_CONNECTION;
+ return CAC_FAILURE;
+ }
+
+ /*initialize for samr pipe if we have to */
+ if ( !hnd->_internal.pipes[PI_SVCCTL] ) {
+ if ( !
+ ( pipe_hnd =
+ cli_rpc_pipe_open_noauth( srv->cli, PI_SVCCTL,
+ &( hnd->status ) ) ) ) {
+ hnd->status = NT_STATUS_UNSUCCESSFUL;
+ return CAC_FAILURE;
+ }
+
+ hnd->_internal.pipes[PI_SVCCTL] = True;
+ }
+
+ scm_out = talloc( mem_ctx, POLICY_HND );
+ if ( !scm_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
+
+ err = rpccli_svcctl_open_scm( pipe_hnd, mem_ctx, scm_out,
+ op->in.access );
+ hnd->status = werror_to_ntstatus( err );
+
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
+
+ op->out.scm_hnd = scm_out;
+
+ return CAC_SUCCESS;
}
-int cac_SvcClose(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *scm_hnd) {
- struct rpc_pipe_client *pipe_hnd = NULL;
- WERROR err;
+int cac_SvcClose( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ POLICY_HND * scm_hnd )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ WERROR err;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!scm_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !scm_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- err = rpccli_svcctl_close_service( pipe_hnd, mem_ctx, scm_hnd);
- hnd->status = werror_to_ntstatus(err);
+ err = rpccli_svcctl_close_service( pipe_hnd, mem_ctx, scm_hnd );
+ hnd->status = werror_to_ntstatus( err );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SvcEnumServices(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcEnumServices *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
- WERROR err;
+int cac_SvcEnumServices( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SvcEnumServices *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ WERROR err;
- uint32 type_buf = 0;
- uint32 state_buf = 0;
+ uint32 type_buf = 0;
+ uint32 state_buf = 0;
- uint32 num_svc_out = 0;
+ uint32 num_svc_out = 0;
- ENUM_SERVICES_STATUS *svc_buf = NULL;
+ ENUM_SERVICES_STATUS *svc_buf = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.scm_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.scm_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- type_buf = (op->in.type != 0) ? op->in.type : (SVCCTL_TYPE_DRIVER | SVCCTL_TYPE_WIN32);
- state_buf = (op->in.state != 0) ? op->in.state : SVCCTL_STATE_ALL;
+ type_buf =
+ ( op->in.type !=
+ 0 ) ? op->in.
+ type : ( SVCCTL_TYPE_DRIVER | SVCCTL_TYPE_WIN32 );
+ state_buf = ( op->in.state != 0 ) ? op->in.state : SVCCTL_STATE_ALL;
- err = rpccli_svcctl_enumerate_services( pipe_hnd, mem_ctx, op->in.scm_hnd, type_buf, state_buf, &num_svc_out, &svc_buf);
- hnd->status = werror_to_ntstatus(err);
+ err = rpccli_svcctl_enumerate_services( pipe_hnd, mem_ctx,
+ op->in.scm_hnd, type_buf,
+ state_buf, &num_svc_out,
+ &svc_buf );
+ hnd->status = werror_to_ntstatus( err );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.services = cac_MakeServiceArray(mem_ctx, svc_buf, num_svc_out);
+ op->out.services =
+ cac_MakeServiceArray( mem_ctx, svc_buf, num_svc_out );
- if(!op->out.services) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ if ( !op->out.services ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- TALLOC_FREE(svc_buf);
+ TALLOC_FREE( svc_buf );
- op->out.num_services = num_svc_out;
+ op->out.num_services = num_svc_out;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SvcOpenService(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcOpenService *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
- WERROR err;
+int cac_SvcOpenService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SvcOpenService *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ WERROR err;
- POLICY_HND *svc_hnd_out = NULL;
+ POLICY_HND *svc_hnd_out = NULL;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.scm_hnd || !op->in.name || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.scm_hnd || !op->in.name || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- svc_hnd_out = talloc(mem_ctx, POLICY_HND);
- if(!svc_hnd_out) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ svc_hnd_out = talloc( mem_ctx, POLICY_HND );
+ if ( !svc_hnd_out ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- err = rpccli_svcctl_open_service( pipe_hnd, mem_ctx, op->in.scm_hnd, svc_hnd_out, op->in.name, op->in.access);
- hnd->status = werror_to_ntstatus(err);
+ err = rpccli_svcctl_open_service( pipe_hnd, mem_ctx, op->in.scm_hnd,
+ svc_hnd_out, op->in.name,
+ op->in.access );
+ hnd->status = werror_to_ntstatus( err );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.svc_hnd = svc_hnd_out;
+ op->out.svc_hnd = svc_hnd_out;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SvcControlService(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcControlService *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
- WERROR err;
+int cac_SvcControlService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SvcControlService *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ WERROR err;
- SERVICE_STATUS status_out;
+ SERVICE_STATUS status_out;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.svc_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.svc_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- if(op->in.control < SVCCTL_CONTROL_STOP || op->in.control > SVCCTL_CONTROL_SHUTDOWN) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( op->in.control < SVCCTL_CONTROL_STOP
+ || op->in.control > SVCCTL_CONTROL_SHUTDOWN ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx, op->in.svc_hnd, op->in.control, &status_out);
- hnd->status = werror_to_ntstatus(err);
+ err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx,
+ op->in.svc_hnd, op->in.control,
+ &status_out );
+ hnd->status = werror_to_ntstatus( err );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SvcGetStatus(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcGetStatus *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
- WERROR err;
+int cac_SvcGetStatus( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SvcGetStatus *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ WERROR err;
- SERVICE_STATUS status_out;
+ SERVICE_STATUS status_out;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.svc_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.svc_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- err = rpccli_svcctl_query_status( pipe_hnd, mem_ctx, op->in.svc_hnd, &status_out);
- hnd->status = werror_to_ntstatus(err);
+ err = rpccli_svcctl_query_status( pipe_hnd, mem_ctx, op->in.svc_hnd,
+ &status_out );
+ hnd->status = werror_to_ntstatus( err );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.status = status_out;
+ op->out.status = status_out;
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
@@ -288,273 +318,313 @@ int cac_SvcGetStatus(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcGetSta
* returns CAC_FAILURE if the state is never reached
* or CAC_SUCCESS if the state is reached
*/
-int cac_WaitForService(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, POLICY_HND *svc_hnd, uint32 state, uint32 timeout, SERVICE_STATUS *status) {
- struct rpc_pipe_client *pipe_hnd = NULL;
- /*number of milliseconds we have spent*/
- uint32 time_spent = 0;
- WERROR err;
-
- if(!hnd || !mem_ctx || !svc_hnd || !status)
- return CAC_FAILURE;
-
- pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
-
- while(status->state != state && time_spent < (timeout * 1000000) && NT_STATUS_IS_OK(hnd->status)) {
- /*if this is the first call, then we _just_ got the status.. sleep now*/
- usleep(WAIT_SLEEP_TIME);
- time_spent += WAIT_SLEEP_TIME;
-
- err = rpccli_svcctl_query_status(pipe_hnd, mem_ctx, svc_hnd, status);
- hnd->status = werror_to_ntstatus(err);
- }
-
- if(status->state == state)
- return CAC_SUCCESS;
-
- return CAC_FAILURE;
+int cac_WaitForService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ POLICY_HND * svc_hnd, uint32 state, uint32 timeout,
+ SERVICE_STATUS * status )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+
+ /*number of milliseconds we have spent */
+ uint32 time_spent = 0;
+ WERROR err;
+
+ if ( !hnd || !mem_ctx || !svc_hnd || !status )
+ return CAC_FAILURE;
+
+ pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
+
+ while ( status->state != state && time_spent < ( timeout * 1000000 )
+ && NT_STATUS_IS_OK( hnd->status ) ) {
+ /*if this is the first call, then we _just_ got the status.. sleep now */
+ usleep( WAIT_SLEEP_TIME );
+ time_spent += WAIT_SLEEP_TIME;
+
+ err = rpccli_svcctl_query_status( pipe_hnd, mem_ctx, svc_hnd,
+ status );
+ hnd->status = werror_to_ntstatus( err );
+ }
+
+ if ( status->state == state )
+ return CAC_SUCCESS;
+
+ return CAC_FAILURE;
}
-int cac_SvcStartService(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcStartService *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
- WERROR err;
+int cac_SvcStartService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SvcStartService *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ WERROR err;
- SERVICE_STATUS status_buf;
+ SERVICE_STATUS status_buf;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.svc_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.svc_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- if(op->in.num_parms != 0 && op->in.parms == NULL) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( op->in.num_parms != 0 && op->in.parms == NULL ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- err = rpccli_svcctl_start_service(pipe_hnd, mem_ctx, op->in.svc_hnd, (const char **)op->in.parms, op->in.num_parms);
- hnd->status = werror_to_ntstatus(err);
+ err = rpccli_svcctl_start_service( pipe_hnd, mem_ctx, op->in.svc_hnd,
+ ( const char ** ) op->in.parms,
+ op->in.num_parms );
+ hnd->status = werror_to_ntstatus( err );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- if(op->in.timeout == 0)
- return CAC_SUCCESS;
+ if ( op->in.timeout == 0 )
+ return CAC_SUCCESS;
- return cac_WaitForService(hnd, mem_ctx, op->in.svc_hnd, SVCCTL_RUNNING, op->in.timeout, &status_buf);
+ return cac_WaitForService( hnd, mem_ctx, op->in.svc_hnd,
+ SVCCTL_RUNNING, op->in.timeout,
+ &status_buf );
}
-int cac_SvcStopService(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcStopService *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
- WERROR err;
+int cac_SvcStopService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SvcStopService *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ WERROR err;
- SERVICE_STATUS status_out;
+ SERVICE_STATUS status_out;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.svc_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.svc_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx, op->in.svc_hnd, SVCCTL_CONTROL_STOP, &status_out);
- hnd->status = werror_to_ntstatus(err);
+ err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx,
+ op->in.svc_hnd,
+ SVCCTL_CONTROL_STOP,
+ &status_out );
+ hnd->status = werror_to_ntstatus( err );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.status = status_out;
+ op->out.status = status_out;
- if(op->in.timeout == 0)
- return CAC_SUCCESS;
+ if ( op->in.timeout == 0 )
+ return CAC_SUCCESS;
- return cac_WaitForService(hnd, mem_ctx, op->in.svc_hnd, SVCCTL_STOPPED, op->in.timeout, &op->out.status);
+ return cac_WaitForService( hnd, mem_ctx, op->in.svc_hnd,
+ SVCCTL_STOPPED, op->in.timeout,
+ &op->out.status );
}
-int cac_SvcPauseService(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcPauseService *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
- WERROR err;
+int cac_SvcPauseService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SvcPauseService *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ WERROR err;
- SERVICE_STATUS status_out;
+ SERVICE_STATUS status_out;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.svc_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.svc_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx, op->in.svc_hnd, SVCCTL_CONTROL_PAUSE, &status_out);
- hnd->status = werror_to_ntstatus(err);
+ err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx,
+ op->in.svc_hnd,
+ SVCCTL_CONTROL_PAUSE,
+ &status_out );
+ hnd->status = werror_to_ntstatus( err );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.status = status_out;
+ op->out.status = status_out;
- if(op->in.timeout == 0)
- return CAC_SUCCESS;
+ if ( op->in.timeout == 0 )
+ return CAC_SUCCESS;
- return cac_WaitForService(hnd, mem_ctx, op->in.svc_hnd, SVCCTL_PAUSED, op->in.timeout, &op->out.status);
+ return cac_WaitForService( hnd, mem_ctx, op->in.svc_hnd,
+ SVCCTL_PAUSED, op->in.timeout,
+ &op->out.status );
}
-int cac_SvcContinueService(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcContinueService *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
- WERROR err;
+int cac_SvcContinueService( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SvcContinueService *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ WERROR err;
- SERVICE_STATUS status_out;
+ SERVICE_STATUS status_out;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.svc_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.svc_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx, op->in.svc_hnd, SVCCTL_CONTROL_CONTINUE, &status_out);
- hnd->status = werror_to_ntstatus(err);
+ err = rpccli_svcctl_control_service( pipe_hnd, mem_ctx,
+ op->in.svc_hnd,
+ SVCCTL_CONTROL_CONTINUE,
+ &status_out );
+ hnd->status = werror_to_ntstatus( err );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.status = status_out;
+ op->out.status = status_out;
- if(op->in.timeout == 0)
- return CAC_SUCCESS;
+ if ( op->in.timeout == 0 )
+ return CAC_SUCCESS;
- return cac_WaitForService(hnd, mem_ctx, op->in.svc_hnd, SVCCTL_RUNNING, op->in.timeout, &op->out.status);
+ return cac_WaitForService( hnd, mem_ctx, op->in.svc_hnd,
+ SVCCTL_RUNNING, op->in.timeout,
+ &op->out.status );
}
-int cac_SvcGetDisplayName(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcGetDisplayName *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
- WERROR err;
+int cac_SvcGetDisplayName( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SvcGetDisplayName *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ WERROR err;
- fstring disp_name_out;
+ fstring disp_name_out;
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.svc_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.svc_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- err = rpccli_svcctl_get_dispname( pipe_hnd, mem_ctx, op->in.svc_hnd, disp_name_out);
- hnd->status = werror_to_ntstatus(err);
+ err = rpccli_svcctl_get_dispname( pipe_hnd, mem_ctx, op->in.svc_hnd,
+ disp_name_out );
+ hnd->status = werror_to_ntstatus( err );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- op->out.display_name = talloc_strdup(mem_ctx, disp_name_out);
+ op->out.display_name = talloc_strdup( mem_ctx, disp_name_out );
- if(!op->out.display_name) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ if ( !op->out.display_name ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
-int cac_SvcGetServiceConfig(CacServerHandle *hnd, TALLOC_CTX *mem_ctx, struct SvcGetServiceConfig *op) {
- struct rpc_pipe_client *pipe_hnd = NULL;
- WERROR err;
+int cac_SvcGetServiceConfig( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
+ struct SvcGetServiceConfig *op )
+{
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ WERROR err;
+
+ SERVICE_CONFIG config_out;
- SERVICE_CONFIG config_out;
-
- if(!hnd)
- return CAC_FAILURE;
+ if ( !hnd )
+ return CAC_FAILURE;
- if(!hnd->_internal.ctx) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ if ( !hnd->_internal.ctx ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- if(!op || !op->in.svc_hnd || !mem_ctx) {
- hnd->status = NT_STATUS_INVALID_PARAMETER;
- return CAC_FAILURE;
- }
+ if ( !op || !op->in.svc_hnd || !mem_ctx ) {
+ hnd->status = NT_STATUS_INVALID_PARAMETER;
+ return CAC_FAILURE;
+ }
- pipe_hnd = cac_GetPipe(hnd, PI_SVCCTL);
- if(!pipe_hnd) {
- hnd->status = NT_STATUS_INVALID_HANDLE;
- return CAC_FAILURE;
- }
+ pipe_hnd = cac_GetPipe( hnd, PI_SVCCTL );
+ if ( !pipe_hnd ) {
+ hnd->status = NT_STATUS_INVALID_HANDLE;
+ return CAC_FAILURE;
+ }
- err = rpccli_svcctl_query_config( pipe_hnd, mem_ctx, op->in.svc_hnd, &config_out);
- hnd->status = werror_to_ntstatus(err);
+ err = rpccli_svcctl_query_config( pipe_hnd, mem_ctx, op->in.svc_hnd,
+ &config_out );
+ hnd->status = werror_to_ntstatus( err );
- if(!NT_STATUS_IS_OK(hnd->status))
- return CAC_FAILURE;
+ if ( !NT_STATUS_IS_OK( hnd->status ) )
+ return CAC_FAILURE;
- if(!cac_InitCacServiceConfig(mem_ctx, &config_out, &op->out.config)) {
- hnd->status = NT_STATUS_NO_MEMORY;
- return CAC_FAILURE;
- }
+ if ( !cac_InitCacServiceConfig
+ ( mem_ctx, &config_out, &op->out.config ) ) {
+ hnd->status = NT_STATUS_NO_MEMORY;
+ return CAC_FAILURE;
+ }
- return CAC_SUCCESS;
+ return CAC_SUCCESS;
}
diff --git a/source/libmsrpc/libmsrpc_internal.c b/source/libmsrpc/libmsrpc_internal.c
index 1295c510da3..36e604f90ff 100644
--- a/source/libmsrpc/libmsrpc_internal.c
+++ b/source/libmsrpc/libmsrpc_internal.c
@@ -44,7 +44,7 @@ struct rpc_pipe_client *cac_GetPipe( CacServerHandle * hnd, int pi_idx )
return NULL;
}
- pipe_hnd = srv->cli.pipe_list;
+ pipe_hnd = srv->cli->pipe_list;
while ( pipe_hnd != NULL && pipe_hnd->pipe_idx != pi_idx ) {
pipe_hnd = pipe_hnd->next;
@@ -129,7 +129,7 @@ RPC_DATA_BLOB *cac_MakeRpcDataBlob( TALLOC_CTX * mem_ctx, uint32 data_type,
init_rpc_blob_uint32( blob, data.reg_dword );
break;
- case REG_DWORD_BE:
+ case REG_DWORD_BIG_ENDIAN:
init_rpc_blob_uint32( blob, data.reg_dword_be );
break;
@@ -274,7 +274,7 @@ REG_VALUE_DATA *cac_MakeRegValueData( TALLOC_CTX * mem_ctx, uint32 data_type,
data->reg_dword = *( ( uint32 * ) buf.buffer );
break;
- case REG_DWORD_BE:
+ case REG_DWORD_BIG_ENDIAN:
data->reg_dword_be = *( ( uint32 * ) buf.buffer );
break;
@@ -511,7 +511,7 @@ CacUserInfo *cac_MakeUserInfo( TALLOC_CTX * mem_ctx, SAM_USERINFO_CTR * ctr )
info->logon_hours =
( LOGON_HRS * ) talloc_memdup( mem_ctx, &( id21->logon_hrs ),
- sizeof( LOGON_HRS ) );
+ sizeof( LOGON_HRS ) );
if ( !info->logon_hours )
return NULL;
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index 783cf0c1853..f29449cfb22 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -56,16 +56,19 @@ static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_
Do an old lanman2 style session setup.
****************************************************************************/
-static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user,
- const char *pass, size_t passlen, const char *workgroup)
+static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli,
+ const char *user,
+ const char *pass, size_t passlen,
+ const char *workgroup)
{
DATA_BLOB session_key = data_blob(NULL, 0);
DATA_BLOB lm_response = data_blob(NULL, 0);
fstring pword;
char *p;
- if (passlen > sizeof(pword)-1)
- return False;
+ if (passlen > sizeof(pword)-1) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
/* LANMAN servers predate NT status codes and Unicode and ignore those
smb flags so we must disable the corresponding default capabilities
@@ -83,7 +86,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user,
lm_response = data_blob(NULL, 24);
if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) {
DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n"));
- return False;
+ return NT_STATUS_ACCESS_DENIED;
}
} else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) {
/* Encrypted mode needed, and encrypted password supplied. */
@@ -116,14 +119,15 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user,
p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
cli_setup_bcc(cli, p);
- cli_send_smb(cli);
- if (!cli_receive_smb(cli))
- return False;
+ if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
+ return cli_nt_error(cli);
+ }
show_msg(cli->inbuf);
- if (cli_is_error(cli))
- return False;
+ if (cli_is_error(cli)) {
+ return cli_nt_error(cli);
+ }
/* use the returned vuid from now on */
cli->vuid = SVAL(cli->inbuf,smb_uid);
@@ -134,7 +138,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user,
cli_set_session_key(cli, session_key);
}
- return True;
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -159,7 +163,7 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli)
Do a NT1 guest session setup.
****************************************************************************/
-static BOOL cli_session_setup_guest(struct cli_state *cli)
+static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
{
char *p;
uint32 capabilities = cli_session_setup_capabilities(cli);
@@ -184,14 +188,15 @@ static BOOL cli_session_setup_guest(struct cli_state *cli)
p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
cli_setup_bcc(cli, p);
- cli_send_smb(cli);
- if (!cli_receive_smb(cli))
- return False;
+ if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
+ return cli_nt_error(cli);
+ }
show_msg(cli->inbuf);
- if (cli_is_error(cli))
- return False;
+ if (cli_is_error(cli)) {
+ return cli_nt_error(cli);
+ }
cli->vuid = SVAL(cli->inbuf,smb_uid);
@@ -206,15 +211,16 @@ static BOOL cli_session_setup_guest(struct cli_state *cli)
fstrcpy(cli->user_name, "");
- return True;
+ return NT_STATUS_OK;
}
/****************************************************************************
Do a NT1 plaintext session setup.
****************************************************************************/
-static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user,
- const char *pass, const char *workgroup)
+static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli,
+ const char *user, const char *pass,
+ const char *workgroup)
{
uint32 capabilities = cli_session_setup_capabilities(cli);
char *p;
@@ -253,14 +259,15 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user,
p += clistr_push(cli, p, lanman, -1, STR_TERMINATE);
cli_setup_bcc(cli, p);
- cli_send_smb(cli);
- if (!cli_receive_smb(cli))
- return False;
+ if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
+ return cli_nt_error(cli);
+ }
show_msg(cli->inbuf);
- if (cli_is_error(cli))
- return False;
+ if (cli_is_error(cli)) {
+ return cli_nt_error(cli);
+ }
cli->vuid = SVAL(cli->inbuf,smb_uid);
p = smb_buf(cli->inbuf);
@@ -273,7 +280,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user,
cli->is_samba = True;
}
- return True;
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -286,16 +293,16 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user,
@param workgroup The user's domain.
****************************************************************************/
-static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
- const char *pass, size_t passlen,
- const char *ntpass, size_t ntpasslen,
- const char *workgroup)
+static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
+ const char *pass, size_t passlen,
+ const char *ntpass, size_t ntpasslen,
+ const char *workgroup)
{
uint32 capabilities = cli_session_setup_capabilities(cli);
DATA_BLOB lm_response = data_blob(NULL, 0);
DATA_BLOB nt_response = data_blob(NULL, 0);
DATA_BLOB session_key = data_blob(NULL, 0);
- BOOL ret = False;
+ NTSTATUS result;
char *p;
if (passlen == 0) {
@@ -317,7 +324,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
&lm_response, &nt_response, &session_key)) {
data_blob_free(&names_blob);
data_blob_free(&server_chal);
- return False;
+ return NT_STATUS_ACCESS_DENIED;
}
data_blob_free(&names_blob);
data_blob_free(&server_chal);
@@ -399,14 +406,14 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
cli_setup_bcc(cli, p);
if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
- ret = False;
+ result = cli_nt_error(cli);
goto end;
}
/* show_msg(cli->inbuf); */
if (cli_is_error(cli)) {
- ret = False;
+ result = cli_nt_error(cli);
goto end;
}
@@ -429,12 +436,12 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user,
cli_set_session_key(cli, session_key);
}
- ret = True;
+ result = NT_STATUS_OK;
end:
data_blob_free(&lm_response);
data_blob_free(&nt_response);
data_blob_free(&session_key);
- return ret;
+ return result;
}
/****************************************************************************
@@ -600,6 +607,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) {
return nt_status;
}
+ ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
return nt_status;
@@ -762,7 +770,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
* sent. -- VL
*/
DEBUG(1, ("Kerberos mech was offered, but no principal was "
- "sent, disabling Kerberos\n"));
+ "sent, disabling Kerberos\n"));
cli->use_kerberos = False;
}
@@ -811,11 +819,11 @@ ntlmssp:
password is in plaintext, the same should be done.
****************************************************************************/
-BOOL cli_session_setup(struct cli_state *cli,
- const char *user,
- const char *pass, int passlen,
- const char *ntpass, int ntpasslen,
- const char *workgroup)
+NTSTATUS cli_session_setup(struct cli_state *cli,
+ const char *user,
+ const char *pass, int passlen,
+ const char *ntpass, int ntpasslen,
+ const char *workgroup)
{
char *p;
fstring user2;
@@ -829,8 +837,9 @@ BOOL cli_session_setup(struct cli_state *cli,
workgroup = user2;
}
- if (cli->protocol < PROTOCOL_LANMAN1)
- return True;
+ if (cli->protocol < PROTOCOL_LANMAN1) {
+ return NT_STATUS_OK;
+ }
/* now work out what sort of session setup we are going to
do. I have split this into separate functions to make the
@@ -842,17 +851,18 @@ BOOL cli_session_setup(struct cli_state *cli,
if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
DEBUG(1, ("Server requested LM password but 'client lanman auth'"
" is disabled\n"));
- return False;
+ return NT_STATUS_ACCESS_DENIED;
}
if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
!lp_client_plaintext_auth() && (*pass)) {
DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
" is disabled\n"));
- return False;
+ return NT_STATUS_ACCESS_DENIED;
}
- return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup);
+ return cli_session_setup_lanman2(cli, user, pass, passlen,
+ workgroup);
}
/* if no user is supplied then we have to do an anonymous connection.
@@ -875,7 +885,7 @@ BOOL cli_session_setup(struct cli_state *cli,
if (!lp_client_plaintext_auth() && (*pass)) {
DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'"
" is disabled\n"));
- return False;
+ return NT_STATUS_ACCESS_DENIED;
}
return cli_session_setup_plaintext(cli, user, pass, workgroup);
}
@@ -886,13 +896,18 @@ BOOL cli_session_setup(struct cli_state *cli,
ADS_STATUS status = cli_session_setup_spnego(cli, user, pass, workgroup);
if (!ADS_ERR_OK(status)) {
DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
- return False;
+ return ads_ntstatus(status);
}
} else {
+ NTSTATUS status;
+
/* otherwise do a NT1 style session setup */
- if ( !cli_session_setup_nt1(cli, user, pass, passlen, ntpass, ntpasslen, workgroup) ) {
- DEBUG(3,("cli_session_setup: NT1 session setup failed!\n"));
- return False;
+ status = cli_session_setup_nt1(cli, user, pass, passlen,
+ ntpass, ntpasslen, workgroup);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3,("cli_session_setup: NT1 session setup "
+ "failed: %s\n", nt_errstr(status)));
+ return status;
}
}
@@ -900,7 +915,7 @@ BOOL cli_session_setup(struct cli_state *cli,
cli->is_samba = True;
}
- return True;
+ return NT_STATUS_OK;
}
@@ -1406,8 +1421,9 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli,
if (!my_name)
my_name = global_myname();
- if (!(cli = cli_initialise(NULL)))
+ if (!(cli = cli_initialise())) {
return NT_STATUS_NO_MEMORY;
+ }
make_nmb_name(&calling, my_name, 0x0);
make_nmb_name(&called , dest_host, 0x20);
@@ -1507,6 +1523,8 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
struct cli_state *cli = NULL;
int pw_len = password ? strlen(password)+1 : 0;
+ *output_cli = NULL;
+
if (password == NULL) {
password = "";
}
@@ -1518,19 +1536,26 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
return nt_status;
}
- if (!cli_session_setup(cli, user, password, pw_len, password, pw_len, domain)) {
- if ((flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)
- && cli_session_setup(cli, "", "", 0, "", 0, domain)) {
- } else {
- nt_status = cli_nt_error(cli);
- DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status)));
+ nt_status = cli_session_setup(cli, user, password, pw_len, password,
+ pw_len, domain);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+
+ if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
+ DEBUG(1,("failed session setup with %s\n",
+ nt_errstr(nt_status)));
cli_shutdown(cli);
- if (NT_STATUS_IS_OK(nt_status))
- nt_status = NT_STATUS_UNSUCCESSFUL;
return nt_status;
}
- }
+ nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(1,("anonymous failed session setup with %s\n",
+ nt_errstr(nt_status)));
+ cli_shutdown(cli);
+ return nt_status;
+ }
+ }
+
if (service) {
if (!cli_send_tconX(cli, service, service_type, password, pw_len)) {
nt_status = cli_nt_error(cli);
@@ -1553,7 +1578,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli,
Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
****************************************************************************/
-BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, const char *desthost,
+BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
struct in_addr *pdest_ip)
{
struct nmb_name calling, called;
@@ -1571,7 +1596,7 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost,
make_nmb_name(&called, desthost, 0x20);
}
- if (!cli_session_request(cli, &calling, &called)) {
+ if (!cli_session_request(*ppcli, &calling, &called)) {
struct nmb_name smbservername;
make_nmb_name(&smbservername , "*SMBSERVER", 0x20);
@@ -1588,23 +1613,23 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost,
*/
DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
-with error %s.\n", desthost, cli_errstr(cli) ));
+with error %s.\n", desthost, cli_errstr(*ppcli) ));
return False;
}
- /*
- * We need to close the connection here but can't call cli_shutdown as
- * will free an allocated cli struct. cli_close_connection was invented
- * for this purpose. JRA. Based on work by "Kim R. Pedersen" <krp@filanet.dk>.
- */
+ /* Try again... */
+ cli_shutdown(*ppcli);
- cli_close_connection(cli);
+ *ppcli = cli_initialise();
+ if (!*ppcli) {
+ /* Out of memory... */
+ return False;
+ }
- if (!cli_initialise(cli) ||
- !cli_connect(cli, desthost, pdest_ip) ||
- !cli_session_request(cli, &calling, &smbservername)) {
+ if (!cli_connect(*ppcli, desthost, pdest_ip) ||
+ !cli_session_request(*ppcli, &calling, &smbservername)) {
DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
-name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) ));
+name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
return False;
}
}
diff --git a/source/libsmb/clidfs.c b/source/libsmb/clidfs.c
index e0c55057675..916e4cefc6e 100644
--- a/source/libsmb/clidfs.c
+++ b/source/libsmb/clidfs.c
@@ -51,7 +51,7 @@ static struct client_connection *connections;
static struct cli_state *do_connect( const char *server, const char *share,
BOOL show_sessetup )
{
- struct cli_state *c;
+ struct cli_state *c = NULL;
struct nmb_name called, calling;
const char *server_n;
struct in_addr ip;
@@ -83,7 +83,7 @@ static struct cli_state *do_connect( const char *server, const char *share,
ip = dest_ip;
/* have to open a new connection */
- if (!(c=cli_initialise(NULL)) || (cli_set_port(c, port) != port) ||
+ if (!(c=cli_initialise()) || (cli_set_port(c, port) != port) ||
!cli_connect(c, server_n, &ip)) {
d_printf("Connection to %s failed\n", server_n);
return NULL;
@@ -99,6 +99,7 @@ static struct cli_state *do_connect( const char *server, const char *share,
d_printf("session request to %s failed (%s)\n",
called.name, cli_errstr(c));
cli_shutdown(c);
+ c = NULL;
if ((p=strchr_m(called.name, '.'))) {
*p = 0;
goto again;
@@ -126,13 +127,14 @@ static struct cli_state *do_connect( const char *server, const char *share,
}
}
- if (!cli_session_setup(c, username,
- password, strlen(password),
- password, strlen(password),
- lp_workgroup())) {
+ if (!NT_STATUS_IS_OK(cli_session_setup(c, username,
+ password, strlen(password),
+ password, strlen(password),
+ lp_workgroup()))) {
/* if a password was not supplied then try again with a null username */
if (password[0] || !username[0] || use_kerberos ||
- !cli_session_setup(c, "", "", 0, "", 0, lp_workgroup())) {
+ !NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0, "", 0,
+ lp_workgroup()))) {
d_printf("session setup failed: %s\n", cli_errstr(c));
if (NT_STATUS_V(cli_nt_error(c)) ==
NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED))
diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c
index 8342df0f1d1..24851961d03 100644
--- a/source/libsmb/clientgen.c
+++ b/source/libsmb/clientgen.c
@@ -107,8 +107,8 @@ BOOL cli_receive_smb(struct cli_state *cli)
}
/* If the server is not responding, note that now */
-
if (!ret) {
+ DEBUG(0, ("Receiving SMB: Server stopped responding\n"));
cli->smb_rw_error = smb_read_error;
close(cli->fd);
cli->fd = -1;
@@ -255,12 +255,12 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state)
}
/****************************************************************************
- Initialise a client structure.
+ Initialise a client structure. Always returns a malloc'ed struct.
****************************************************************************/
-struct cli_state *cli_initialise(struct cli_state *cli)
+struct cli_state *cli_initialise(void)
{
- BOOL alloced_cli = False;
+ struct cli_state *cli = NULL;
/* Check the effective uid - make sure we are not setuid */
if (is_setuid_root()) {
@@ -268,17 +268,11 @@ struct cli_state *cli_initialise(struct cli_state *cli)
return NULL;
}
+ cli = SMB_MALLOC_P(struct cli_state);
if (!cli) {
- cli = SMB_MALLOC_P(struct cli_state);
- if (!cli)
- return NULL;
- ZERO_STRUCTP(cli);
- alloced_cli = True;
+ return NULL;
}
- if (cli->initialised)
- cli_close_connection(cli);
-
ZERO_STRUCTP(cli);
cli->port = 0;
@@ -333,7 +327,6 @@ struct cli_state *cli_initialise(struct cli_state *cli)
cli_null_set_signing(cli);
cli->initialised = 1;
- cli->allocated = alloced_cli;
return cli;
@@ -343,10 +336,7 @@ struct cli_state *cli_initialise(struct cli_state *cli)
SAFE_FREE(cli->inbuf);
SAFE_FREE(cli->outbuf);
-
- if (alloced_cli)
- SAFE_FREE(cli);
-
+ SAFE_FREE(cli);
return NULL;
}
@@ -403,10 +393,10 @@ void cli_nt_pipes_close(struct cli_state *cli)
}
/****************************************************************************
- Close a client connection and free the memory without destroying cli itself.
+ Shutdown a client structure.
****************************************************************************/
-void cli_close_connection(struct cli_state *cli)
+void cli_shutdown(struct cli_state *cli)
{
cli_nt_pipes_close(cli);
@@ -443,20 +433,8 @@ void cli_close_connection(struct cli_state *cli)
}
cli->fd = -1;
cli->smb_rw_error = 0;
-}
-/****************************************************************************
- Shutdown a client structure.
-****************************************************************************/
-
-void cli_shutdown(struct cli_state *cli)
-{
- BOOL allocated = cli->allocated;
- cli_close_connection(cli);
- ZERO_STRUCTP(cli);
- if (allocated) {
- free(cli);
- }
+ SAFE_FREE(cli);
}
/****************************************************************************
diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c
index 485f5abc0a8..14b5285e45a 100644
--- a/source/libsmb/clikrb5.c
+++ b/source/libsmb/clikrb5.c
@@ -852,6 +852,27 @@ failed:
#endif
}
+static int get_kvno_from_ap_req(krb5_ap_req *ap_req)
+{
+#ifdef HAVE_TICKET_POINTER_IN_KRB5_AP_REQ /* MIT */
+ if (ap_req->ticket->enc_part.kvno)
+ return ap_req->ticket->enc_part.kvno;
+#else /* Heimdal */
+ if (ap_req->ticket.enc_part.kvno)
+ return *ap_req->ticket.enc_part.kvno;
+#endif
+ return 0;
+}
+
+static krb5_enctype get_enctype_from_ap_req(krb5_ap_req *ap_req)
+{
+#ifdef HAVE_ETYPE_IN_ENCRYPTEDDATA /* Heimdal */
+ return ap_req->ticket.enc_part.etype;
+#else /* MIT */
+ return ap_req->ticket->enc_part.enctype;
+#endif
+}
+
static krb5_error_code
get_key_from_keytab(krb5_context context,
krb5_const_principal server,
diff --git a/source/libsmb/clirap.c b/source/libsmb/clirap.c
index caa23b59d9a..61cdd79f36b 100644
--- a/source/libsmb/clirap.c
+++ b/source/libsmb/clirap.c
@@ -244,7 +244,8 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
)) {
int res = rparam? SVAL(rparam,0) : -1;
- if (res == 0 || res == ERRmoredata) {
+ if (res == 0 || res == ERRmoredata ||
+ (res != -1 && cli_errno(cli) == 0)) {
int i;
int converter=SVAL(rparam,2);
diff --git a/source/libsmb/libsmb_cache.c b/source/libsmb/libsmb_cache.c
index 5d948ea5e25..8c4fd7c89f7 100644
--- a/source/libsmb/libsmb_cache.c
+++ b/source/libsmb/libsmb_cache.c
@@ -150,9 +150,10 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server,
* doesn't match the requested share, so
* disconnect from the current share.
*/
- if (! cli_tdis(&srv->server->cli)) {
+ if (! cli_tdis(srv->server->cli)) {
/* Sigh. Couldn't disconnect. */
- cli_shutdown(&srv->server->cli);
+ cli_shutdown(srv->server->cli);
+ srv->server->cli = NULL;
context->callbacks.remove_cached_srv_fn(context, srv->server);
continue;
}
@@ -166,7 +167,8 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server,
srv->share_name = SMB_STRDUP(share);
if (!srv->share_name) {
/* Out of memory. */
- cli_shutdown(&srv->server->cli);
+ cli_shutdown(srv->server->cli);
+ srv->server->cli = NULL;
context->callbacks.remove_cached_srv_fn(context, srv->server);
continue;
}
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index 8c6218c6431..c7f17d3d013 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -496,7 +496,7 @@ static int
smbc_check_server(SMBCCTX * context,
SMBCSRV * server)
{
- if ( send_keepalive(server->cli.fd) == False )
+ if ( send_keepalive(server->cli->fd) == False )
return 1;
/* connection is ok */
@@ -533,7 +533,8 @@ smbc_remove_unused_server(SMBCCTX * context,
DLIST_REMOVE(context->internal->_servers, srv);
- cli_shutdown(&srv->cli);
+ cli_shutdown(srv->cli);
+ srv->cli = NULL;
DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv));
@@ -639,7 +640,7 @@ smbc_server(SMBCCTX *context,
fstring password)
{
SMBCSRV *srv=NULL;
- struct cli_state c;
+ struct cli_state *c;
struct nmb_name called, calling;
const char *server_n = server;
pstring ipenv;
@@ -675,7 +676,7 @@ smbc_server(SMBCCTX *context,
* disconnect if the requested share is not the same as the
* one that was already connected.
*/
- if (srv->cli.cnum == (uint16) -1) {
+ if (srv->cli->cnum == (uint16) -1) {
/* Ensure we have accurate auth info */
if (context->internal->_auth_fn_with_context != NULL) {
context->internal->_auth_fn_with_context(
@@ -692,11 +693,12 @@ smbc_server(SMBCCTX *context,
password, sizeof(fstring));
}
- if (! cli_send_tconX(&srv->cli, share, "?????",
+ if (! cli_send_tconX(srv->cli, share, "?????",
password, strlen(password)+1)) {
- errno = smbc_errno(context, &srv->cli);
- cli_shutdown(&srv->cli);
+ errno = smbc_errno(context, srv->cli);
+ cli_shutdown(srv->cli);
+ srv->cli = NULL;
context->callbacks.remove_cached_srv_fn(context,
srv);
srv = NULL;
@@ -739,19 +741,19 @@ smbc_server(SMBCCTX *context,
zero_ip(&ip);
/* have to open a new connection */
- if (!cli_initialise(&c)) {
+ if ((c = cli_initialise()) == NULL) {
errno = ENOMEM;
return NULL;
}
if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) {
- c.use_kerberos = True;
+ c->use_kerberos = True;
}
if (context->flags & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) {
- c.fallback_after_kerberos = True;
+ c->fallback_after_kerberos = True;
}
- c.timeout = context->timeout;
+ c->timeout = context->timeout;
/*
* Force use of port 139 for first try if share is $IPC, empty, or
@@ -765,49 +767,47 @@ smbc_server(SMBCCTX *context,
port_try_next = 139;
}
- c.port = port_try_first;
+ c->port = port_try_first;
- if (!cli_connect(&c, server_n, &ip)) {
+ if (!cli_connect(c, server_n, &ip)) {
/* First connection attempt failed. Try alternate port. */
- c.port = port_try_next;
+ c->port = port_try_next;
- if (!cli_connect(&c, server_n, &ip)) {
- cli_shutdown(&c);
+ if (!cli_connect(c, server_n, &ip)) {
+ cli_shutdown(c);
errno = ETIMEDOUT;
return NULL;
}
}
- if (!cli_session_request(&c, &calling, &called)) {
- cli_shutdown(&c);
+ if (!cli_session_request(c, &calling, &called)) {
+ cli_shutdown(c);
if (strcmp(called.name, "*SMBSERVER")) {
make_nmb_name(&called , "*SMBSERVER", 0x20);
goto again;
} else { /* Try one more time, but ensure we don't loop */
- /* Only try this if server is an IP address ... */
+ /* Only try this if server is an IP address ... */
- if (is_ipaddress(server) && !tried_reverse) {
- fstring remote_name;
- struct in_addr rem_ip;
+ if (is_ipaddress(server) && !tried_reverse) {
+ fstring remote_name;
+ struct in_addr rem_ip;
- if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) {
+ if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) {
DEBUG(4, ("Could not convert IP address "
"%s to struct in_addr\n", server));
- errno = ETIMEDOUT;
- return NULL;
- }
-
- tried_reverse++; /* Yuck */
-
- if (name_status_find("*", 0, 0, rem_ip, remote_name)) {
- make_nmb_name(&called, remote_name, 0x20);
- goto again;
- }
+ errno = ETIMEDOUT;
+ return NULL;
+ }
+ tried_reverse++; /* Yuck */
- }
+ if (name_status_find("*", 0, 0, rem_ip, remote_name)) {
+ make_nmb_name(&called, remote_name, 0x20);
+ goto again;
+ }
+ }
}
errno = ETIMEDOUT;
return NULL;
@@ -815,29 +815,29 @@ smbc_server(SMBCCTX *context,
DEBUG(4,(" session request ok\n"));
- if (!cli_negprot(&c)) {
- cli_shutdown(&c);
+ if (!cli_negprot(c)) {
+ cli_shutdown(c);
errno = ETIMEDOUT;
return NULL;
}
username_used = username;
- if (!cli_session_setup(&c, username_used,
- password, strlen(password),
- password, strlen(password),
- workgroup)) {
+ if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used,
+ password, strlen(password),
+ password, strlen(password),
+ workgroup))) {
/* Failed. Try an anonymous login, if allowed by flags. */
username_used = "";
if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) ||
- !cli_session_setup(&c, username_used,
- password, 1,
- password, 0,
- workgroup)) {
+ !NT_STATUS_IS_OK(cli_session_setup(c, username_used,
+ password, 1,
+ password, 0,
+ workgroup))) {
- cli_shutdown(&c);
+ cli_shutdown(c);
errno = EPERM;
return NULL;
}
@@ -845,10 +845,10 @@ smbc_server(SMBCCTX *context,
DEBUG(4,(" session setup ok\n"));
- if (!cli_send_tconX(&c, share, "?????",
+ if (!cli_send_tconX(c, share, "?????",
password, strlen(password)+1)) {
- errno = smbc_errno(context, &c);
- cli_shutdown(&c);
+ errno = smbc_errno(context, c);
+ cli_shutdown(c);
return NULL;
}
@@ -867,7 +867,6 @@ smbc_server(SMBCCTX *context,
ZERO_STRUCTP(srv);
srv->cli = c;
- srv->cli.allocated = False;
srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
srv->no_pathinfo = False;
srv->no_pathinfo2 = False;
@@ -893,8 +892,10 @@ smbc_server(SMBCCTX *context,
return srv;
failed:
- cli_shutdown(&c);
- if (!srv) return NULL;
+ cli_shutdown(c);
+ if (!srv) {
+ return NULL;
+ }
SAFE_FREE(srv);
return NULL;
@@ -969,19 +970,16 @@ smbc_attr_server(SMBCCTX *context,
}
ZERO_STRUCTP(ipc_srv);
- ipc_srv->cli = *ipc_cli;
- ipc_srv->cli.allocated = False;
-
- free(ipc_cli);
+ ipc_srv->cli = ipc_cli;
if (pol) {
- pipe_hnd = cli_rpc_pipe_open_noauth(&ipc_srv->cli,
+ pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli,
PI_LSARPC,
&nt_status);
if (!pipe_hnd) {
DEBUG(1, ("cli_nt_session_open fail!\n"));
errno = ENOTSUP;
- cli_shutdown(&ipc_srv->cli);
+ cli_shutdown(ipc_srv->cli);
free(ipc_srv);
return NULL;
}
@@ -994,14 +992,14 @@ smbc_attr_server(SMBCCTX *context,
nt_status = rpccli_lsa_open_policy(
pipe_hnd,
- ipc_srv->cli.mem_ctx,
+ ipc_srv->cli->mem_ctx,
True,
GENERIC_EXECUTE_ACCESS,
pol);
if (!NT_STATUS_IS_OK(nt_status)) {
- errno = smbc_errno(context, &ipc_srv->cli);
- cli_shutdown(&ipc_srv->cli);
+ errno = smbc_errno(context, ipc_srv->cli);
+ cli_shutdown(ipc_srv->cli);
return NULL;
}
}
@@ -1018,7 +1016,7 @@ smbc_attr_server(SMBCCTX *context,
if (errno == 0) {
errno = ENOMEM;
}
- cli_shutdown(&ipc_srv->cli);
+ cli_shutdown(ipc_srv->cli);
free(ipc_srv);
return NULL;
}
@@ -1107,7 +1105,7 @@ smbc_open_ctx(SMBCCTX *context,
ZERO_STRUCTP(file);
/*d_printf(">>>open: resolving %s\n", path);*/
- if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath))
+ if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
SAFE_FREE(file);
@@ -1122,7 +1120,8 @@ smbc_open_ctx(SMBCCTX *context,
cli_dfs_make_full_path( targetpath, targetcli->desthost, targetcli->share, temppath);
}
- if ((fd = cli_open(targetcli, targetpath, flags, DENY_NONE)) < 0) {
+ if ((fd = cli_open(targetcli, targetpath, flags,
+ context->internal->_share_mode)) < 0) {
/* Handle the error ... */
@@ -1181,7 +1180,7 @@ smbc_open_ctx(SMBCCTX *context,
if (fd == -1) {
int eno = 0;
- eno = smbc_errno(context, &srv->cli);
+ eno = smbc_errno(context, srv->cli);
file = context->opendir(context, fname);
if (!file) errno = eno;
return file;
@@ -1284,7 +1283,7 @@ smbc_read_ctx(SMBCCTX *context,
}
/*d_printf(">>>read: resolving %s\n", path);*/
- if (!cli_resolve_path("", &file->srv->cli, path,
+ if (!cli_resolve_path("", file->srv->cli, path,
&targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
@@ -1292,7 +1291,7 @@ smbc_read_ctx(SMBCCTX *context,
}
/*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/
- ret = cli_read(targetcli, file->cli_fd, buf, offset, count);
+ ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count);
if (ret < 0) {
@@ -1367,7 +1366,7 @@ smbc_write_ctx(SMBCCTX *context,
}
/*d_printf(">>>write: resolving %s\n", path);*/
- if (!cli_resolve_path("", &file->srv->cli, path,
+ if (!cli_resolve_path("", file->srv->cli, path,
&targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
@@ -1376,7 +1375,7 @@ smbc_write_ctx(SMBCCTX *context,
/*d_printf(">>>write: resolved path as %s\n", targetpath);*/
- ret = cli_write(targetcli, file->cli_fd, 0, buf, offset, count);
+ ret = cli_write(targetcli, file->cli_fd, 0, (char *)buf, offset, count);
if (ret <= 0) {
@@ -1439,7 +1438,7 @@ smbc_close_ctx(SMBCCTX *context,
}
/*d_printf(">>>close: resolving %s\n", path);*/
- if (!cli_resolve_path("", &file->srv->cli, path,
+ if (!cli_resolve_path("", file->srv->cli, path,
&targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
@@ -1511,7 +1510,7 @@ smbc_getatr(SMBCCTX * context,
}
DEBUG(4,("smbc_getatr: sending qpathinfo\n"));
- if (!cli_resolve_path( "", &srv->cli, fixedpath, &targetcli, targetpath))
+ if (!cli_resolve_path( "", srv->cli, fixedpath, &targetcli, targetpath))
{
d_printf("Couldn't resolve %s\n", path);
return False;
@@ -1562,6 +1561,7 @@ smbc_getatr(SMBCCTX * context,
if (change_time_ts != NULL) {
*change_time_ts = w_time_ts;
}
+
srv->no_pathinfo2 = True;
return True;
}
@@ -1599,7 +1599,7 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
* attributes manipulated.
*/
if (srv->no_pathinfo ||
- ! cli_setpathinfo(&srv->cli, path,
+ ! cli_setpathinfo(srv->cli, path,
create_time,
access_time,
write_time,
@@ -1620,20 +1620,20 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
srv->no_pathinfo = True;
/* Open the file */
- if ((fd = cli_open(&srv->cli, path, O_RDWR, DENY_NONE)) < 0) {
+ if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) {
- errno = smbc_errno(context, &srv->cli);
+ errno = smbc_errno(context, srv->cli);
return -1;
}
- /* Set the new attributes */
- ret = cli_setattrE(&srv->cli, fd,
+ /* Set the new attributes */
+ ret = cli_setattrE(srv->cli, fd,
change_time,
access_time,
write_time);
/* Close the file */
- cli_close(&srv->cli, fd);
+ cli_close(srv->cli, fd);
/*
* Unfortunately, setattrE() doesn't have a provision for
@@ -1642,11 +1642,11 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
* seems to work on win98.
*/
if (ret && mode != (uint16) -1) {
- ret = cli_setatr(&srv->cli, path, mode, 0);
+ ret = cli_setatr(srv->cli, path, mode, 0);
}
if (! ret) {
- errno = smbc_errno(context, &srv->cli);
+ errno = smbc_errno(context, srv->cli);
return False;
}
}
@@ -1706,7 +1706,7 @@ smbc_unlink_ctx(SMBCCTX *context,
}
/*d_printf(">>>unlink: resolving %s\n", path);*/
- if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath))
+ if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
return -1;
@@ -1845,14 +1845,14 @@ smbc_rename_ctx(SMBCCTX *ocontext,
}
/*d_printf(">>>rename: resolving %s\n", path1);*/
- if (!cli_resolve_path( "", &srv->cli, path1, &targetcli1, targetpath1))
+ if (!cli_resolve_path( "", srv->cli, path1, &targetcli1, targetpath1))
{
d_printf("Could not resolve %s\n", path1);
return -1;
}
/*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/
/*d_printf(">>>rename: resolving %s\n", path2);*/
- if (!cli_resolve_path( "", &srv->cli, path2, &targetcli2, targetpath2))
+ if (!cli_resolve_path( "", srv->cli, path2, &targetcli2, targetpath2))
{
d_printf("Could not resolve %s\n", path2);
return -1;
@@ -1947,7 +1947,7 @@ smbc_lseek_ctx(SMBCCTX *context,
}
/*d_printf(">>>lseek: resolving %s\n", path);*/
- if (!cli_resolve_path("", &file->srv->cli, path,
+ if (!cli_resolve_path("", file->srv->cli, path,
&targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
@@ -2120,7 +2120,7 @@ smbc_stat_ctx(SMBCCTX *context,
&change_time_ts,
&ino)) {
- errno = smbc_errno(context, &srv->cli);
+ errno = smbc_errno(context, srv->cli);
return -1;
}
@@ -2196,7 +2196,7 @@ smbc_fstat_ctx(SMBCCTX *context,
}
/*d_printf(">>>fstat: resolving %s\n", path);*/
- if (!cli_resolve_path("", &file->srv->cli, path,
+ if (!cli_resolve_path("", file->srv->cli, path,
&targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
@@ -2213,12 +2213,12 @@ smbc_fstat_ctx(SMBCCTX *context,
time_t change_time, access_time, write_time;
- if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size,
+ if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size,
&change_time, &access_time, &write_time)) {
- errno = EINVAL;
- return -1;
- }
+ errno = EINVAL;
+ return -1;
+ }
change_time_ts = convert_time_t_to_timespec(change_time);
access_time_ts = convert_time_t_to_timespec(access_time);
@@ -2472,16 +2472,16 @@ net_share_enum_rpc(struct cli_state *cli,
void *state)
{
int i;
- WERROR result;
- ENUM_HND enum_hnd;
+ NTSTATUS result;
+ uint32 enum_hnd;
+ uint32 *penum_hnd = &enum_hnd;
uint32 info_level = 1;
uint32 preferred_len = 0xffffffff;
- uint32 type;
- SRV_SHARE_INFO_CTR ctr;
- fstring name = "";
- fstring comment = "";
+ struct srvsvc_NetShareCtr1 ctr1;
+ union srvsvc_NetShareCtr ctr;
void *mem_ctx;
struct rpc_pipe_client *pipe_hnd;
+ uint32 numentries;
NTSTATUS nt_status;
/* Open the server service pipe */
@@ -2499,37 +2499,28 @@ net_share_enum_rpc(struct cli_state *cli,
return -1;
}
+ ZERO_STRUCT(ctr1);
+ ctr.ctr1 = &ctr1;
+
/* Issue the NetShareEnum RPC call and retrieve the response */
- init_enum_hnd(&enum_hnd, 0);
- result = rpccli_srvsvc_net_share_enum(pipe_hnd,
- mem_ctx,
- info_level,
- &ctr,
- preferred_len,
- &enum_hnd);
+ enum_hnd = 0;
+ result = rpccli_srvsvc_NetShareEnum(pipe_hnd, mem_ctx, NULL,
+ &info_level, &ctr, preferred_len,
+ &numentries, &penum_hnd);
/* Was it successful? */
- if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) {
+ if (!NT_STATUS_IS_OK(result) || numentries == 0) {
/* Nope. Go clean up. */
goto done;
}
/* For each returned entry... */
- for (i = 0; i < ctr.num_entries; i++) {
-
- /* pull out the share name */
- rpcstr_pull_unistr2_fstring(
- name, &ctr.share.info1[i].info_1_str.uni_netname);
-
- /* pull out the share's comment */
- rpcstr_pull_unistr2_fstring(
- comment, &ctr.share.info1[i].info_1_str.uni_remark);
-
- /* Get the type value */
- type = ctr.share.info1[i].info_1.type;
+ for (i = 0; i < numentries; i++) {
/* Add this share to the list */
- (*fn)(name, type, comment, state);
+ (*fn)(ctr.ctr1->array[i].name,
+ ctr.ctr1->array[i].type,
+ ctr.ctr1->array[i].comment, state);
}
done:
@@ -2540,7 +2531,7 @@ done:
TALLOC_FREE(mem_ctx);
/* Tell 'em if it worked */
- return W_ERROR_IS_OK(result) ? 0 : -1;
+ return NT_STATUS_IS_OK(result) ? 0 : -1;
}
@@ -2549,6 +2540,7 @@ static SMBCFILE *
smbc_opendir_ctx(SMBCCTX *context,
const char *fname)
{
+ int saved_errno;
fstring server, share, user, password, options;
pstring workgroup;
pstring path;
@@ -2556,6 +2548,7 @@ smbc_opendir_ctx(SMBCCTX *context,
char *p;
SMBCSRV *srv = NULL;
SMBCFILE *dir = NULL;
+ struct _smbc_callbacks *cb;
struct in_addr rem_ip;
if (!context || !context->internal ||
@@ -2708,7 +2701,7 @@ smbc_opendir_ctx(SMBCCTX *context,
/* Now, list the stuff ... */
- if (!cli_NetServerEnum(&srv->cli,
+ if (!cli_NetServerEnum(srv->cli,
workgroup,
SV_TYPE_DOMAIN_ENUM,
list_unique_wg_fn,
@@ -2804,7 +2797,7 @@ smbc_opendir_ctx(SMBCCTX *context,
dir->srv = srv;
/* Now, list the servers ... */
- if (!cli_NetServerEnum(&srv->cli, server,
+ if (!cli_NetServerEnum(srv->cli, server,
0x0000FFFE, list_fn,
(void *)dir)) {
@@ -2840,15 +2833,15 @@ smbc_opendir_ctx(SMBCCTX *context,
/* List the shares ... */
if (net_share_enum_rpc(
- &srv->cli,
+ srv->cli,
list_fn,
(void *) dir) < 0 &&
cli_RNetShareEnum(
- &srv->cli,
+ srv->cli,
list_fn,
(void *)dir) < 0) {
- errno = cli_errno(&srv->cli);
+ errno = cli_errno(srv->cli);
if (dir) {
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
@@ -2898,7 +2891,7 @@ smbc_opendir_ctx(SMBCCTX *context,
p = path + strlen(path);
pstrcat(path, "\\*");
- if (!cli_resolve_path("", &srv->cli, path,
+ if (!cli_resolve_path("", srv->cli, path,
&targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
@@ -2917,9 +2910,9 @@ smbc_opendir_ctx(SMBCCTX *context,
SAFE_FREE(dir->fname);
SAFE_FREE(dir);
}
- errno = smbc_errno(context, targetcli);
+ saved_errno = smbc_errno(context, targetcli);
- if (errno == EINVAL) {
+ if (saved_errno == EINVAL) {
/*
* See if they asked to opendir something
* other than a directory. If so, the
@@ -2935,12 +2928,34 @@ smbc_opendir_ctx(SMBCCTX *context,
! IS_DOS_DIR(mode)) {
/* It is. Correct the error value */
- errno = ENOTDIR;
+ saved_errno = ENOTDIR;
}
}
- return NULL;
+ /*
+ * If there was an error and the server is no
+ * good any more...
+ */
+ cb = &context->callbacks;
+ if (cli_is_error(targetcli) &&
+ cb->check_server_fn(context, srv)) {
+
+ /* ... then remove it. */
+ if (cb->remove_unused_server_fn(context,
+ srv)) {
+ /*
+ * We could not remove the server
+ * completely, remove it from the
+ * cache so we will not get it
+ * again. It will be removed when the
+ * last file/dir is closed.
+ */
+ cb->remove_cached_srv_fn(context, srv);
+ }
+ }
+ errno = saved_errno;
+ return NULL;
}
}
@@ -3247,7 +3262,7 @@ smbc_mkdir_ctx(SMBCCTX *context,
}
/*d_printf(">>>mkdir: resolving %s\n", path);*/
- if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath))
+ if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
return -1;
@@ -3344,7 +3359,7 @@ smbc_rmdir_ctx(SMBCCTX *context,
}
/*d_printf(">>>rmdir: resolving %s\n", path);*/
- if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath))
+ if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
return -1;
@@ -3600,8 +3615,8 @@ smbc_chmod_ctx(SMBCCTX *context,
if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM;
if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN;
- if (!cli_setatr(&srv->cli, path, mode, 0)) {
- errno = smbc_errno(context, &srv->cli);
+ if (!cli_setatr(srv->cli, path, mode, 0)) {
+ errno = smbc_errno(context, srv->cli);
return -1;
}
@@ -3718,8 +3733,8 @@ ace_compare(SEC_ACE *ace1,
if (ace1->flags != ace2->flags)
return ace1->flags - ace2->flags;
- if (ace1->info.mask != ace2->info.mask)
- return ace1->info.mask - ace2->info.mask;
+ if (ace1->access_mask != ace2->access_mask)
+ return ace1->access_mask - ace2->access_mask;
if (ace1->size != ace2->size)
return ace1->size - ace2->size;
@@ -3734,14 +3749,14 @@ sort_acl(SEC_ACL *the_acl)
uint32 i;
if (!the_acl) return;
- qsort(the_acl->ace, the_acl->num_aces, sizeof(the_acl->ace[0]),
+ qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]),
QSORT_CAST ace_compare);
for (i=1;i<the_acl->num_aces;) {
- if (sec_ace_equal(&the_acl->ace[i-1], &the_acl->ace[i])) {
+ if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) {
int j;
for (j=i; j<the_acl->num_aces-1; j++) {
- the_acl->ace[j] = the_acl->ace[j+1];
+ the_acl->aces[j] = the_acl->aces[j+1];
}
the_acl->num_aces--;
} else {
@@ -3946,7 +3961,7 @@ parse_ace(struct cli_state *ipc_cli,
}
done:
- mask.mask = amask;
+ mask = amask;
init_sec_ace(ace, &sid, atype, mask, aflags);
return True;
}
@@ -3968,7 +3983,7 @@ add_ace(SEC_ACL **the_acl,
if ((aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces)) == NULL) {
return False;
}
- memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE));
+ memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(SEC_ACE));
memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE));
newacl = make_sec_acl(ctx, (*the_acl)->revision,
1+(*the_acl)->num_aces, aces);
@@ -4138,7 +4153,7 @@ dos_attr_query(SMBCCTX *context,
&change_time_ts,
&inode)) {
- errno = smbc_errno(context, &srv->cli);
+ errno = smbc_errno(context, srv->cli);
DEBUG(5, ("dos_attr_query Failed to query old attributes\n"));
return NULL;
@@ -4164,7 +4179,7 @@ dos_attr_parse(SMBCCTX *context,
char *str)
{
int n;
- const char *p = str;
+ const char *p = str;
fstring tok;
struct {
const char * create_time_attr;
@@ -4297,7 +4312,7 @@ cacl_get(SMBCCTX *context,
SMB_OFF_T size = 0;
uint16 mode = 0;
SMB_INO_T ino = 0;
- struct cli_state *cli = &srv->cli;
+ struct cli_state *cli = srv->cli;
struct {
const char * create_time_attr;
const char * access_time_attr;
@@ -4540,10 +4555,10 @@ cacl_get(SMBCCTX *context,
}
if (! exclude_nt_group) {
- if (sd->grp_sid) {
+ if (sd->group_sid) {
convert_sid_to_string(ipc_cli, pol,
sidstr, numeric,
- sd->grp_sid);
+ sd->group_sid);
} else {
fstrcpy(sidstr, "");
}
@@ -4588,7 +4603,7 @@ cacl_get(SMBCCTX *context,
/* Add aces to value buffer */
for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
- SEC_ACE *ace = &sd->dacl->ace[i];
+ SEC_ACE *ace = &sd->dacl->aces[i];
convert_sid_to_string(ipc_cli, pol,
sidstr, numeric,
&ace->trustee);
@@ -4602,7 +4617,7 @@ cacl_get(SMBCCTX *context,
sidstr,
ace->type,
ace->flags,
- ace->info.mask);
+ ace->access_mask);
if (!p) {
errno = ENOMEM;
return -1;
@@ -4615,7 +4630,7 @@ cacl_get(SMBCCTX *context,
sidstr,
ace->type,
ace->flags,
- ace->info.mask);
+ ace->access_mask);
}
} else if ((StrnCaseCmp(name, "acl", 3) == 0 &&
StrCaseCmp(name+3, sidstr) == 0) ||
@@ -4627,7 +4642,7 @@ cacl_get(SMBCCTX *context,
"%d/%d/0x%08x",
ace->type,
ace->flags,
- ace->info.mask);
+ ace->access_mask);
if (!p) {
errno = ENOMEM;
return -1;
@@ -4638,7 +4653,7 @@ cacl_get(SMBCCTX *context,
"%d/%d/0x%08x",
ace->type,
ace->flags,
- ace->info.mask);
+ ace->access_mask);
}
} else if (all_nt_acls) {
if (determine_size) {
@@ -4649,7 +4664,7 @@ cacl_get(SMBCCTX *context,
sidstr,
ace->type,
ace->flags,
- ace->info.mask);
+ ace->access_mask);
if (!p) {
errno = ENOMEM;
return -1;
@@ -4662,7 +4677,7 @@ cacl_get(SMBCCTX *context,
sidstr,
ace->type,
ace->flags,
- ace->info.mask);
+ ace->access_mask);
}
}
if (n > bufsize) {
@@ -4691,11 +4706,11 @@ cacl_get(SMBCCTX *context,
&change_time_ts,
&ino)) {
- errno = smbc_errno(context, &srv->cli);
+ errno = smbc_errno(context, srv->cli);
return -1;
}
-
+
create_time = convert_timespec_to_time_t(create_time_ts);
access_time = convert_timespec_to_time_t(access_time_ts);
write_time = convert_timespec_to_time_t(write_time_ts);
@@ -4811,7 +4826,7 @@ cacl_get(SMBCCTX *context,
attr_strings.create_time_attr,
create_time);
}
- } else if (StrCaseCmp(name, "c_time") == 0) {
+ } else if (StrCaseCmp(name, attr_strings.create_time_attr) == 0) {
if (determine_size) {
p = talloc_asprintf(ctx, "%lu", create_time);
if (!p) {
@@ -4852,7 +4867,7 @@ cacl_get(SMBCCTX *context,
attr_strings.access_time_attr,
access_time);
}
- } else if (StrCaseCmp(name, "a_time") == 0) {
+ } else if (StrCaseCmp(name, attr_strings.access_time_attr) == 0) {
if (determine_size) {
p = talloc_asprintf(ctx, "%lu", access_time);
if (!p) {
@@ -5093,9 +5108,9 @@ cacl_set(TALLOC_CTX *ctx,
switch (mode) {
case SMBC_XATTR_MODE_REMOVE_ALL:
old->dacl->num_aces = 0;
- SAFE_FREE(old->dacl->ace);
+ SAFE_FREE(old->dacl->aces);
SAFE_FREE(old->dacl);
- old->off_dacl = 0;
+ old->dacl = NULL;
dacl = old->dacl;
break;
@@ -5104,18 +5119,18 @@ cacl_set(TALLOC_CTX *ctx,
BOOL found = False;
for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
- if (sec_ace_equal(&sd->dacl->ace[i],
- &old->dacl->ace[j])) {
+ if (sec_ace_equal(&sd->dacl->aces[i],
+ &old->dacl->aces[j])) {
uint32 k;
for (k=j; k<old->dacl->num_aces-1;k++) {
- old->dacl->ace[k] =
- old->dacl->ace[k+1];
+ old->dacl->aces[k] =
+ old->dacl->aces[k+1];
}
old->dacl->num_aces--;
if (old->dacl->num_aces == 0) {
- SAFE_FREE(old->dacl->ace);
+ SAFE_FREE(old->dacl->aces);
SAFE_FREE(old->dacl);
- old->off_dacl = 0;
+ old->dacl = NULL;
}
found = True;
dacl = old->dacl;
@@ -5136,14 +5151,14 @@ cacl_set(TALLOC_CTX *ctx,
BOOL found = False;
for (j=0;old->dacl && j<old->dacl->num_aces;j++) {
- if (sid_equal(&sd->dacl->ace[i].trustee,
- &old->dacl->ace[j].trustee)) {
+ if (sid_equal(&sd->dacl->aces[i].trustee,
+ &old->dacl->aces[j].trustee)) {
if (!(flags & SMBC_XATTR_FLAG_CREATE)) {
err = EEXIST;
ret = -1;
goto failed;
}
- old->dacl->ace[j] = sd->dacl->ace[i];
+ old->dacl->aces[j] = sd->dacl->aces[i];
ret = -1;
found = True;
}
@@ -5156,7 +5171,7 @@ cacl_set(TALLOC_CTX *ctx,
}
for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
- add_ace(&old->dacl, &sd->dacl->ace[i], ctx);
+ add_ace(&old->dacl, &sd->dacl->aces[i], ctx);
}
}
dacl = old->dacl;
@@ -5165,7 +5180,7 @@ cacl_set(TALLOC_CTX *ctx,
case SMBC_XATTR_MODE_SET:
old = sd;
owner_sid = old->owner_sid;
- grp_sid = old->grp_sid;
+ grp_sid = old->group_sid;
dacl = old->dacl;
break;
@@ -5174,7 +5189,7 @@ cacl_set(TALLOC_CTX *ctx,
break;
case SMBC_XATTR_MODE_CHGRP:
- grp_sid = sd->grp_sid;
+ grp_sid = sd->group_sid;
break;
}
@@ -5310,8 +5325,8 @@ smbc_setxattr_ctx(SMBCCTX *context,
}
if (ipc_srv) {
- ret = cacl_set(ctx, &srv->cli,
- &ipc_srv->cli, &pol, path,
+ ret = cacl_set(ctx, srv->cli,
+ ipc_srv->cli, &pol, path,
namevalue,
(*namevalue == '*'
? SMBC_XATTR_MODE_SET
@@ -5374,8 +5389,8 @@ smbc_setxattr_ctx(SMBCCTX *context,
errno = ENOMEM;
ret = -1;
} else {
- ret = cacl_set(ctx, &srv->cli,
- &ipc_srv->cli, &pol, path,
+ ret = cacl_set(ctx, srv->cli,
+ ipc_srv->cli, &pol, path,
namevalue,
(*namevalue == '*'
? SMBC_XATTR_MODE_SET
@@ -5405,8 +5420,8 @@ smbc_setxattr_ctx(SMBCCTX *context,
errno = ENOMEM;
ret = -1;
} else {
- ret = cacl_set(ctx, &srv->cli,
- &ipc_srv->cli, &pol, path,
+ ret = cacl_set(ctx, srv->cli,
+ ipc_srv->cli, &pol, path,
namevalue, SMBC_XATTR_MODE_CHOWN, 0);
}
talloc_destroy(ctx);
@@ -5432,8 +5447,8 @@ smbc_setxattr_ctx(SMBCCTX *context,
errno = ENOMEM;
ret = -1;
} else {
- ret = cacl_set(ctx, &srv->cli,
- &ipc_srv->cli, &pol, path,
+ ret = cacl_set(ctx, srv->cli,
+ ipc_srv->cli, &pol, path,
namevalue, SMBC_XATTR_MODE_CHOWN, 0);
}
talloc_destroy(ctx);
@@ -5632,12 +5647,12 @@ smbc_getxattr_ctx(SMBCCTX *context,
/* Yup. */
ret = cacl_get(context, ctx, srv,
- ipc_srv == NULL ? NULL : &ipc_srv->cli,
+ ipc_srv == NULL ? NULL : ipc_srv->cli,
&pol, path,
CONST_DISCARD(char *, name),
CONST_DISCARD(char *, value), size);
if (ret < 0 && errno == 0) {
- errno = smbc_errno(context, &srv->cli);
+ errno = smbc_errno(context, srv->cli);
}
talloc_destroy(ctx);
return ret;
@@ -5728,8 +5743,8 @@ smbc_removexattr_ctx(SMBCCTX *context,
StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) {
/* Yup. */
- ret = cacl_set(ctx, &srv->cli,
- &ipc_srv->cli, &pol, path,
+ ret = cacl_set(ctx, srv->cli,
+ ipc_srv->cli, &pol, path,
NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0);
talloc_destroy(ctx);
return ret;
@@ -5748,8 +5763,8 @@ smbc_removexattr_ctx(SMBCCTX *context,
StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) {
/* Yup. */
- ret = cacl_set(ctx, &srv->cli,
- &ipc_srv->cli, &pol, path,
+ ret = cacl_set(ctx, srv->cli,
+ ipc_srv->cli, &pol, path,
name + 19, SMBC_XATTR_MODE_REMOVE, 0);
talloc_destroy(ctx);
return ret;
@@ -6026,10 +6041,10 @@ smbc_list_print_jobs_ctx(SMBCCTX *context,
}
- if (cli_print_queue(&srv->cli,
+ if (cli_print_queue(srv->cli,
(void (*)(struct print_job_info *))fn) < 0) {
- errno = smbc_errno(context, &srv->cli);
+ errno = smbc_errno(context, srv->cli);
return -1;
}
@@ -6096,10 +6111,10 @@ smbc_unlink_print_job_ctx(SMBCCTX *context,
}
- if ((err = cli_printjob_del(&srv->cli, id)) != 0) {
+ if ((err = cli_printjob_del(srv->cli, id)) != 0) {
if (err < 0)
- errno = smbc_errno(context, &srv->cli);
+ errno = smbc_errno(context, srv->cli);
else if (err == ERRnosuchprintjob)
errno = EINVAL;
return -1;
@@ -6220,8 +6235,8 @@ smbc_free_context(SMBCCTX *context,
s = context->internal->_servers;
while (s) {
DEBUG(1, ("Forced shutdown: %p (fd=%d)\n",
- s, s->cli.fd));
- cli_shutdown(&s->cli);
+ s, s->cli->fd));
+ cli_shutdown(s->cli);
context->callbacks.remove_cached_srv_fn(context,
s);
next = s->next;
@@ -6350,9 +6365,9 @@ smbc_option_get(SMBCCTX *context,
* Log to standard error instead of standard output.
*/
#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
- return (void *) (intptr_t) context->internal->_debug_stderr;
+ return (void *) (intptr_t) context->internal->_debug_stderr;
#else
- return (void *) context->internal->_debug_stderr;
+ return (void *) context->internal->_debug_stderr;
#endif
} else if (strcmp(option_name, "full_time_names") == 0) {
/*
diff --git a/source/libsmb/passchange.c b/source/libsmb/passchange.c
index 90eb67aceaa..5b4b0896c0f 100644
--- a/source/libsmb/passchange.c
+++ b/source/libsmb/passchange.c
@@ -29,7 +29,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
char *err_str, size_t err_str_len)
{
struct nmb_name calling, called;
- struct cli_state cli;
+ struct cli_state *cli;
struct rpc_pipe_client *pipe_hnd;
struct in_addr ip;
@@ -44,91 +44,96 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
return NT_STATUS_UNSUCCESSFUL;
}
- ZERO_STRUCT(cli);
-
- if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) {
+ cli = cli_initialise();
+ if (!cli) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!cli_connect(cli, remote_machine, &ip)) {
slprintf(err_str, err_str_len-1, "unable to connect to SMB server on machine %s. Error was : %s.\n",
- remote_machine, cli_errstr(&cli) );
- return NT_STATUS_UNSUCCESSFUL;
+ remote_machine, cli_errstr(cli) );
+ result = cli_nt_error(cli);
+ cli_shutdown(cli);
+ return result;
}
make_nmb_name(&calling, global_myname() , 0x0);
make_nmb_name(&called , remote_machine, 0x20);
- if (!cli_session_request(&cli, &calling, &called)) {
+ if (!cli_session_request(cli, &calling, &called)) {
slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n",
- remote_machine, cli_errstr(&cli) );
- cli_shutdown(&cli);
- return NT_STATUS_UNSUCCESSFUL;
+ remote_machine, cli_errstr(cli) );
+ result = cli_nt_error(cli);
+ cli_shutdown(cli);
+ return result;
}
- cli.protocol = PROTOCOL_NT1;
+ cli->protocol = PROTOCOL_NT1;
- if (!cli_negprot(&cli)) {
+ if (!cli_negprot(cli)) {
slprintf(err_str, err_str_len-1, "machine %s rejected the negotiate protocol. Error was : %s.\n",
- remote_machine, cli_errstr(&cli) );
- result = cli_nt_error(&cli);
- cli_shutdown(&cli);
+ remote_machine, cli_errstr(cli) );
+ result = cli_nt_error(cli);
+ cli_shutdown(cli);
return result;
}
/* Given things like SMB signing, restrict anonymous and the like,
try an authenticated connection first */
- if (!cli_session_setup(&cli, user_name, old_passwd, strlen(old_passwd)+1, old_passwd, strlen(old_passwd)+1, "")) {
-
- result = cli_nt_error(&cli);
-
- if (!NT_STATUS_IS_OK(result)) {
-
- /* Password must change or Password expired are the only valid
- * error conditions here from where we can proceed, the rest like
- * account locked out or logon failure will lead to errors later
- * anyway */
-
- if (!NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_MUST_CHANGE) &&
- !NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_EXPIRED)) {
-
- slprintf(err_str, err_str_len-1, "Could not "
- "connect to machine %s: %s\n",
- remote_machine, cli_errstr(&cli));
- cli_shutdown(&cli);
- return result;
- }
-
- pass_must_change = True;
+ result = cli_session_setup(cli, user_name,
+ old_passwd, strlen(old_passwd)+1,
+ old_passwd, strlen(old_passwd)+1, "");
+
+ if (!NT_STATUS_IS_OK(result)) {
+
+ /* Password must change or Password expired are the only valid
+ * error conditions here from where we can proceed, the rest like
+ * account locked out or logon failure will lead to errors later
+ * anyway */
+
+ if (!NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_MUST_CHANGE) &&
+ !NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_EXPIRED)) {
+ slprintf(err_str, err_str_len-1, "Could not "
+ "connect to machine %s: %s\n",
+ remote_machine, cli_errstr(cli));
+ cli_shutdown(cli);
+ return result;
}
+ pass_must_change = True;
+
/*
* We should connect as the anonymous user here, in case
* the server has "must change password" checked...
* Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix.
*/
- if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
+ result = cli_session_setup(cli, "", "", 0, "", 0, "");
+
+ if (!NT_STATUS_IS_OK(result)) {
slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n",
- remote_machine, cli_errstr(&cli) );
- result = cli_nt_error(&cli);
- cli_shutdown(&cli);
+ remote_machine, cli_errstr(cli) );
+ cli_shutdown(cli);
return result;
}
- cli_init_creds(&cli, "", "", NULL);
+ cli_init_creds(cli, "", "", NULL);
} else {
- cli_init_creds(&cli, user_name, "", old_passwd);
+ cli_init_creds(cli, user_name, "", old_passwd);
}
- if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
+ if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) {
slprintf(err_str, err_str_len-1, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n",
- remote_machine, cli_errstr(&cli) );
- result = cli_nt_error(&cli);
- cli_shutdown(&cli);
+ remote_machine, cli_errstr(cli) );
+ result = cli_nt_error(cli);
+ cli_shutdown(cli);
return result;
}
/* Try not to give the password away too easily */
if (!pass_must_change) {
- pipe_hnd = cli_rpc_pipe_open_ntlmssp(&cli,
+ pipe_hnd = cli_rpc_pipe_open_ntlmssp(cli,
PI_SAMR,
PIPE_AUTH_LEVEL_PRIVACY,
"", /* what domain... ? */
@@ -144,17 +149,17 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
* will just fail. So we do it anonymously, there's no other
* way.
*/
- pipe_hnd = cli_rpc_pipe_open_noauth(&cli, PI_SAMR, &result);
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result);
}
if (!pipe_hnd) {
if (lp_client_lanman_auth()) {
/* Use the old RAP method. */
- if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
+ if (!cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) {
slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n",
- remote_machine, cli_errstr(&cli) );
- result = cli_nt_error(&cli);
- cli_shutdown(&cli);
+ remote_machine, cli_errstr(cli) );
+ result = cli_nt_error(cli);
+ cli_shutdown(cli);
return result;
}
} else {
@@ -162,16 +167,16 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
"SAMR connection to machine %s failed. Error was %s, "
"but LANMAN password changed are disabled\n",
nt_errstr(result), remote_machine);
- result = cli_nt_error(&cli);
- cli_shutdown(&cli);
+ result = cli_nt_error(cli);
+ cli_shutdown(cli);
return result;
}
}
- if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, cli.mem_ctx, user_name,
+ if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, cli->mem_ctx, user_name,
new_passwd, old_passwd))) {
/* Great - it all worked! */
- cli_shutdown(&cli);
+ cli_shutdown(cli);
return NT_STATUS_OK;
} else if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)
@@ -180,7 +185,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n",
remote_machine, get_friendly_nt_error_msg(result));
- cli_shutdown(&cli);
+ cli_shutdown(cli);
return result;
}
@@ -188,21 +193,21 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
cli_rpc_pipe_close(pipe_hnd);
/* Try anonymous NTLMSSP... */
- cli_init_creds(&cli, "", "", NULL);
+ cli_init_creds(cli, "", "", NULL);
result = NT_STATUS_UNSUCCESSFUL;
/* OK, this is ugly, but... try an anonymous pipe. */
- pipe_hnd = cli_rpc_pipe_open_noauth(&cli, PI_SAMR, &result);
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result);
if ( pipe_hnd &&
(NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd,
- cli.mem_ctx,
+ cli->mem_ctx,
user_name,
new_passwd,
old_passwd)))) {
/* Great - it all worked! */
- cli_shutdown(&cli);
+ cli_shutdown(cli);
return NT_STATUS_OK;
} else {
if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)
@@ -212,7 +217,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
slprintf(err_str, err_str_len-1,
"machine %s rejected the (anonymous) password change: Error was : %s.\n",
remote_machine, get_friendly_nt_error_msg(result));
- cli_shutdown(&cli);
+ cli_shutdown(cli);
return result;
}
@@ -221,24 +226,24 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
if (lp_client_lanman_auth()) {
/* Use the old RAP method. */
- if (cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
+ if (cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) {
/* SAMR failed, but the old LanMan protocol worked! */
- cli_shutdown(&cli);
+ cli_shutdown(cli);
return NT_STATUS_OK;
}
slprintf(err_str, err_str_len-1,
"machine %s rejected the password change: Error was : %s.\n",
- remote_machine, cli_errstr(&cli) );
- result = cli_nt_error(&cli);
- cli_shutdown(&cli);
+ remote_machine, cli_errstr(cli) );
+ result = cli_nt_error(cli);
+ cli_shutdown(cli);
return result;
} else {
slprintf(err_str, err_str_len-1,
"SAMR connection to machine %s failed. Error was %s, "
"but LANMAN password changed are disabled\n",
nt_errstr(result), remote_machine);
- cli_shutdown(&cli);
+ cli_shutdown(cli);
return NT_STATUS_UNSUCCESSFUL;
}
}
diff --git a/source/locking/brlock.c b/source/locking/brlock.c
index 267a08d15fa..872ed2bbeaf 100644
--- a/source/locking/brlock.c
+++ b/source/locking/brlock.c
@@ -32,29 +32,6 @@
#define ZERO_ZERO 0
-/* This contains elements that differentiate locks. The smbpid is a
- client supplied pid, and is essentially the locking context for
- this client */
-
-struct lock_context {
- uint16 smbpid;
- uint16 tid;
- struct process_id pid;
-};
-
-/* The data in brlock records is an unsorted linear array of these
- records. It is unnecessary to store the count as tdb provides the
- size of the record */
-
-struct lock_struct {
- struct lock_context context;
- br_off start;
- br_off size;
- int fnum;
- enum brl_type lock_type;
- enum brl_flavour lock_flav;
-};
-
/* The open brlock.tdb database. */
static TDB_CONTEXT *tdb;
@@ -83,7 +60,7 @@ static void print_lock_struct(unsigned int i, struct lock_struct *pls)
See if two locking contexts are equal.
****************************************************************************/
-static BOOL brl_same_context(const struct lock_context *ctx1,
+BOOL brl_same_context(const struct lock_context *ctx1,
const struct lock_context *ctx2)
{
return (procid_equal(&ctx1->pid, &ctx2->pid) &&
@@ -121,7 +98,7 @@ static BOOL brl_conflict(const struct lock_struct *lck1,
const struct lock_struct *lck2)
{
/* Ignore PENDING locks. */
- if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK )
+ if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type))
return False;
/* Read locks never conflict. */
@@ -152,7 +129,7 @@ static BOOL brl_conflict_posix(const struct lock_struct *lck1,
#endif
/* Ignore PENDING locks. */
- if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK )
+ if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type))
return False;
/* Read locks never conflict. */
@@ -174,7 +151,7 @@ static BOOL brl_conflict_posix(const struct lock_struct *lck1,
static BOOL brl_conflict1(const struct lock_struct *lck1,
const struct lock_struct *lck2)
{
- if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK )
+ if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type))
return False;
if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) {
@@ -207,7 +184,7 @@ static BOOL brl_conflict1(const struct lock_struct *lck1,
static BOOL brl_conflict_other(const struct lock_struct *lck1, const struct lock_struct *lck2)
{
- if (lck1->lock_type == PENDING_LOCK || lck2->lock_type == PENDING_LOCK )
+ if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type))
return False;
if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK)
@@ -234,30 +211,47 @@ static BOOL brl_conflict_other(const struct lock_struct *lck1, const struct lock
}
/****************************************************************************
- Amazingly enough, w2k3 "remembers" whether the last lock failure
+ Check if an unlock overlaps a pending lock.
+****************************************************************************/
+
+static BOOL brl_pending_overlap(const struct lock_struct *lock, const struct lock_struct *pend_lock)
+{
+ if ((lock->start <= pend_lock->start) && (lock->start + lock->size > pend_lock->start))
+ return True;
+ if ((lock->start >= pend_lock->start) && (lock->start <= pend_lock->start + pend_lock->size))
+ return True;
+ return False;
+}
+
+/****************************************************************************
+ Amazingly enough, w2k3 "remembers" whether the last lock failure on a fnum
is the same as this one and changes its error code. I wonder if any
app depends on this ?
****************************************************************************/
-static NTSTATUS brl_lock_failed(const struct lock_struct *lock)
+static NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *lock, BOOL blocking_lock)
{
- static struct lock_struct last_lock_failure;
-
- if (brl_same_context(&lock->context, &last_lock_failure.context) &&
- lock->fnum == last_lock_failure.fnum &&
- lock->start == last_lock_failure.start &&
- lock->size == last_lock_failure.size) {
- return NT_STATUS_FILE_LOCK_CONFLICT;
- }
- last_lock_failure = *lock;
- if (lock->start >= 0xEF000000 &&
- (lock->start >> 63) == 0) {
+ if (lock->start >= 0xEF000000 && (lock->start >> 63) == 0) {
/* amazing the little things you learn with a test
suite. Locks beyond this offset (as a 64 bit
number!) always generate the conflict error code,
unless the top bit is set */
+ if (!blocking_lock) {
+ fsp->last_lock_failure = *lock;
+ }
return NT_STATUS_FILE_LOCK_CONFLICT;
}
+
+ if (procid_equal(&lock->context.pid, &fsp->last_lock_failure.context.pid) &&
+ lock->context.tid == fsp->last_lock_failure.context.tid &&
+ lock->fnum == fsp->last_lock_failure.fnum &&
+ lock->start == fsp->last_lock_failure.start) {
+ return NT_STATUS_FILE_LOCK_CONFLICT;
+ }
+
+ if (!blocking_lock) {
+ fsp->last_lock_failure = *lock;
+ }
return NT_STATUS_LOCK_NOT_GRANTED;
}
@@ -316,8 +310,7 @@ static int lock_compare(const struct lock_struct *lck1,
****************************************************************************/
static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
- const struct lock_struct *plock,
- BOOL *my_lock_ctx)
+ const struct lock_struct *plock, BOOL blocking_lock)
{
unsigned int i;
files_struct *fsp = br_lck->fsp;
@@ -326,12 +319,7 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
for (i=0; i < br_lck->num_locks; i++) {
/* Do any Windows or POSIX locks conflict ? */
if (brl_conflict(&locks[i], plock)) {
- NTSTATUS status = brl_lock_failed(plock);;
- /* Did we block ourselves ? */
- if (brl_same_context(&locks[i].context, &plock->context)) {
- *my_lock_ctx = True;
- }
- return status;
+ return brl_lock_failed(fsp,plock,blocking_lock);
}
#if ZERO_ZERO
if (plock->start == 0 && plock->size == 0 &&
@@ -343,13 +331,19 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
/* We can get the Windows lock, now see if it needs to
be mapped into a lower level POSIX one, and if so can
- we get it ? We tell the lower lock layer about the
- lock type so it can cope with the difference between
- Windows "stacking" locks and POSIX "flat" ones. */
-
- if ((plock->lock_type != PENDING_LOCK) && lp_posix_locking(SNUM(fsp->conn))) {
- if (!set_posix_lock(fsp, plock->start, plock->size, plock->lock_type, WINDOWS_LOCK)) {
- if (errno == EACCES || errno == EAGAIN) {
+ we get it ? */
+
+ if (!IS_PENDING_LOCK(plock->lock_type) && lp_posix_locking(fsp->conn->params)) {
+ int errno_ret;
+ if (!set_posix_lock_windows_flavour(fsp,
+ plock->start,
+ plock->size,
+ plock->lock_type,
+ &plock->context,
+ locks,
+ br_lck->num_locks,
+ &errno_ret)) {
+ if (errno_ret == EACCES || errno_ret == EAGAIN) {
return NT_STATUS_FILE_LOCK_CONFLICT;
} else {
return map_nt_error_from_unix(errno);
@@ -375,9 +369,9 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
Cope with POSIX range splits and merges.
****************************************************************************/
-static unsigned int brlock_posix_split_merge(struct lock_struct *lck_arr,
- const struct lock_struct *ex,
- const struct lock_struct *plock,
+static unsigned int brlock_posix_split_merge(struct lock_struct *lck_arr, /* Output array. */
+ const struct lock_struct *ex, /* existing lock. */
+ const struct lock_struct *plock, /* proposed lock. */
BOOL *lock_was_added)
{
BOOL lock_types_differ = (ex->lock_type != plock->lock_type);
@@ -398,26 +392,26 @@ static unsigned int brlock_posix_split_merge(struct lock_struct *lck_arr,
+---------+
| ex |
+---------+
- +-------+
- | plock |
- +-------+
+ +-------+
+ | plock |
+ +-------+
OR....
+---------+
| ex |
+---------+
**********************************************/
- if ( (ex->start >= (plock->start + plock->size)) ||
- (plock->start >= (ex->start + ex->size))) {
+ if ( (ex->start > (plock->start + plock->size)) ||
+ (plock->start > (ex->start + ex->size))) {
/* No overlap with this lock - copy existing. */
memcpy(&lck_arr[0], ex, sizeof(struct lock_struct));
return 1;
}
/*********************************************
- +---------+
- | ex |
- +---------+
+ +---------------------------+
+ | ex |
+ +---------------------------+
+---------------------------+
| plock | -> replace with plock.
+---------------------------+
@@ -431,24 +425,32 @@ OR....
}
/*********************************************
- +---------------+
- | ex |
- +---------------+
+ +-----------------------+
+ | ex |
+ +-----------------------+
+ +---------------+
+ | plock |
+ +---------------+
+OR....
+ +-------+
+ | ex |
+ +-------+
+---------------+
| plock |
+---------------+
+
BECOMES....
+---------------+-------+
| plock | ex | - different lock types.
+---------------+-------+
-OR....
+OR.... (merge)
+-----------------------+
| ex | - same lock type.
+-----------------------+
**********************************************/
if ( (ex->start >= plock->start) &&
- (ex->start < plock->start + plock->size) &&
+ (ex->start <= plock->start + plock->size) &&
(ex->start + ex->size > plock->start + plock->size) ) {
*lock_was_added = True;
@@ -475,9 +477,16 @@ OR....
}
/*********************************************
- +---------------+
- | ex |
- +---------------+
+ +-----------------------+
+ | ex |
+ +-----------------------+
+ +---------------+
+ | plock |
+ +---------------+
+OR....
+ +-------+
+ | ex |
+ +-------+
+---------------+
| plock |
+---------------+
@@ -486,7 +495,7 @@ BECOMES....
| ex | plock | - different lock types
+-------+---------------+
-OR
+OR.... (merge)
+-----------------------+
| ex | - same lock type.
+-----------------------+
@@ -494,7 +503,7 @@ OR
**********************************************/
if ( (ex->start < plock->start) &&
- (ex->start + ex->size > plock->start) &&
+ (ex->start + ex->size >= plock->start) &&
(ex->start + ex->size <= plock->start + plock->size) ) {
*lock_was_added = True;
@@ -573,13 +582,13 @@ OR
****************************************************************************/
static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck,
- const struct lock_struct *plock,
- BOOL *my_lock_ctx)
+ const struct lock_struct *plock)
{
unsigned int i, count;
struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data;
struct lock_struct *tp;
BOOL lock_was_added = False;
+ BOOL signal_pending_read = False;
/* No zero-zero locks for POSIX. */
if (plock->start == 0 && plock->size == 0) {
@@ -603,23 +612,28 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck,
count = 0;
for (i=0; i < br_lck->num_locks; i++) {
- if (locks[i].lock_flav == WINDOWS_LOCK) {
+ struct lock_struct *curr_lock = &locks[i];
+
+ /* If we have a pending read lock, a lock downgrade should
+ trigger a lock re-evaluation. */
+ if (curr_lock->lock_type == PENDING_READ_LOCK &&
+ brl_pending_overlap(plock, curr_lock)) {
+ signal_pending_read = True;
+ }
+
+ if (curr_lock->lock_flav == WINDOWS_LOCK) {
/* Do any Windows flavour locks conflict ? */
- if (brl_conflict(&locks[i], plock)) {
- /* Did we block ourselves ? */
- if (brl_same_context(&locks[i].context, &plock->context)) {
- *my_lock_ctx = True;
- }
+ if (brl_conflict(curr_lock, plock)) {
/* No games with error messages. */
SAFE_FREE(tp);
return NT_STATUS_FILE_LOCK_CONFLICT;
}
/* Just copy the Windows lock into the new array. */
- memcpy(&tp[count], &locks[i], sizeof(struct lock_struct));
+ memcpy(&tp[count], curr_lock, sizeof(struct lock_struct));
count++;
} else {
/* POSIX conflict semantics are different. */
- if (brl_conflict_posix(&locks[i], plock)) {
+ if (brl_conflict_posix(curr_lock, plock)) {
/* Can't block ourselves with POSIX locks. */
/* No games with error messages. */
SAFE_FREE(tp);
@@ -627,24 +641,32 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck,
}
/* Work out overlaps. */
- count += brlock_posix_split_merge(&tp[count], &locks[i], plock, &lock_was_added);
+ count += brlock_posix_split_merge(&tp[count], curr_lock, plock, &lock_was_added);
}
}
+ if (!lock_was_added) {
+ memcpy(&tp[count], plock, sizeof(struct lock_struct));
+ count++;
+ }
+
/* We can get the POSIX lock, now see if it needs to
be mapped into a lower level POSIX one, and if so can
- we get it ? We well the lower lock layer about the
- lock type so it can cope with the difference between
- Windows "stacking" locks and POSIX "flat" ones. */
+ we get it ? */
-#if 0
- /* FIXME - this call doesn't work correctly yet for POSIX locks... */
+ if (!IS_PENDING_LOCK(plock->lock_type) && lp_posix_locking(br_lck->fsp->conn->params)) {
+ int errno_ret;
- if ((plock->lock_type != PENDING_LOCK) && lp_posix_locking(SNUM(fsp->conn))) {
- files_struct *fsp = br_lck->fsp;
+ /* The lower layer just needs to attempt to
+ get the system POSIX lock. We've weeded out
+ any conflicts above. */
- if (!set_posix_lock(fsp, plock->start, plock->size, plock->lock_type, POSIX_LOCK)) {
- if (errno == EACCES || errno == EAGAIN) {
+ if (!set_posix_lock_posix_flavour(br_lck->fsp,
+ plock->start,
+ plock->size,
+ plock->lock_type,
+ &errno_ret)) {
+ if (errno_ret == EACCES || errno_ret == EAGAIN) {
SAFE_FREE(tp);
return NT_STATUS_FILE_LOCK_CONFLICT;
} else {
@@ -653,12 +675,6 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck,
}
}
}
-#endif
-
- if (!lock_was_added) {
- memcpy(&tp[count], plock, sizeof(struct lock_struct));
- count++;
- }
/* Realloc so we don't leak entries per lock call. */
tp = (struct lock_struct *)SMB_REALLOC(tp, count * sizeof(*locks));
@@ -668,7 +684,34 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck,
br_lck->num_locks = count;
SAFE_FREE(br_lck->lock_data);
br_lck->lock_data = (void *)tp;
+ locks = tp;
br_lck->modified = True;
+
+ /* A successful downgrade from write to read lock can trigger a lock
+ re-evalutation where waiting readers can now proceed. */
+
+ if (signal_pending_read) {
+ /* Send unlock messages to any pending read waiters that overlap. */
+ for (i=0; i < br_lck->num_locks; i++) {
+ struct lock_struct *pend_lock = &locks[i];
+
+ /* Ignore non-pending locks. */
+ if (!IS_PENDING_LOCK(pend_lock->lock_type)) {
+ continue;
+ }
+
+ if (pend_lock->lock_type == PENDING_READ_LOCK &&
+ brl_pending_overlap(plock, pend_lock)) {
+ DEBUG(10,("brl_lock_posix: sending unlock message to pid %s\n",
+ procid_str_static(&pend_lock->context.pid )));
+
+ message_send_pid(pend_lock->context.pid,
+ MSG_SMB_UNLOCK,
+ NULL, 0, True);
+ }
+ }
+ }
+
return NT_STATUS_OK;
}
@@ -677,19 +720,17 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck,
****************************************************************************/
NTSTATUS brl_lock(struct byte_range_lock *br_lck,
- uint16 smbpid,
+ uint32 smbpid,
struct process_id pid,
br_off start,
br_off size,
enum brl_type lock_type,
enum brl_flavour lock_flav,
- BOOL *my_lock_ctx)
+ BOOL blocking_lock)
{
NTSTATUS ret;
struct lock_struct lock;
- *my_lock_ctx = False;
-
#if !ZERO_ZERO
if (start == 0 && size == 0) {
DEBUG(0,("client sent 0/0 lock - please report this\n"));
@@ -706,9 +747,9 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck,
lock.lock_flav = lock_flav;
if (lock_flav == WINDOWS_LOCK) {
- ret = brl_lock_windows(br_lck, &lock, my_lock_ctx);
+ ret = brl_lock_windows(br_lck, &lock, blocking_lock);
} else {
- ret = brl_lock_posix(br_lck, &lock, my_lock_ctx);
+ ret = brl_lock_posix(br_lck, &lock);
}
#if ZERO_ZERO
@@ -720,19 +761,6 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck,
}
/****************************************************************************
- Check if an unlock overlaps a pending lock.
-****************************************************************************/
-
-static BOOL brl_pending_overlap(const struct lock_struct *lock, const struct lock_struct *pend_lock)
-{
- if ((lock->start <= pend_lock->start) && (lock->start + lock->size > pend_lock->start))
- return True;
- if ((lock->start >= pend_lock->start) && (lock->start <= pend_lock->start + pend_lock->size))
- return True;
- return False;
-}
-
-/****************************************************************************
Unlock a range of bytes - Windows semantics.
****************************************************************************/
@@ -740,8 +768,12 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock
{
unsigned int i, j;
struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data;
+ enum brl_type deleted_lock_type = READ_LOCK; /* shut the compiler up.... */
#if ZERO_ZERO
+ /* Delete write locks by preference... The lock list
+ is sorted in the zero zero case. */
+
for (i = 0; i < br_lck->num_locks; i++) {
struct lock_struct *lock = &locks[i];
@@ -753,16 +785,15 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock
lock->size == plock->size) {
/* found it - delete it */
- if (i < br_lck->num_locks - 1) {
- memmove(&locks[i], &locks[i+1],
- sizeof(*locks)*((br_lck->num_locks-1) - i));
- }
-
- br_lck->num_locks -= 1;
- br_lck->modified = True;
- return True;
+ deleted_lock_type = lock->lock_type;
+ break;
}
}
+
+ if (i != br_lck->num_locks) {
+ /* We found it - don't search again. */
+ goto unlock_continue;
+ }
#endif
for (i = 0; i < br_lck->num_locks; i++) {
@@ -774,6 +805,7 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock
lock->lock_flav == WINDOWS_LOCK &&
lock->start == plock->start &&
lock->size == plock->size ) {
+ deleted_lock_type = lock->lock_type;
break;
}
}
@@ -783,9 +815,28 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock
return False;
}
- /* Unlock any POSIX regions. */
- if(lp_posix_locking(br_lck->fsp->conn->cnum)) {
- release_posix_lock(br_lck->fsp, plock->start, plock->size);
+#if ZERO_ZERO
+ unlock_continue:
+#endif
+
+ /* Actually delete the lock. */
+ if (i < br_lck->num_locks - 1) {
+ memmove(&locks[i], &locks[i+1],
+ sizeof(*locks)*((br_lck->num_locks-1) - i));
+ }
+
+ br_lck->num_locks -= 1;
+ br_lck->modified = True;
+
+ /* Unlock the underlying POSIX regions. */
+ if(lp_posix_locking(br_lck->fsp->conn->params)) {
+ release_posix_lock_windows_flavour(br_lck->fsp,
+ plock->start,
+ plock->size,
+ deleted_lock_type,
+ &plock->context,
+ locks,
+ br_lck->num_locks);
}
/* Send unlock messages to any pending waiters that overlap. */
@@ -793,7 +844,7 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock
struct lock_struct *pend_lock = &locks[j];
/* Ignore non-pending locks. */
- if (pend_lock->lock_type != PENDING_LOCK) {
+ if (!IS_PENDING_LOCK(pend_lock->lock_type)) {
continue;
}
@@ -802,22 +853,12 @@ static BOOL brl_unlock_windows(struct byte_range_lock *br_lck, const struct lock
DEBUG(10,("brl_unlock: sending unlock message to pid %s\n",
procid_str_static(&pend_lock->context.pid )));
- become_root();
message_send_pid(pend_lock->context.pid,
MSG_SMB_UNLOCK,
NULL, 0, True);
- unbecome_root();
}
}
- /* Actually delete the lock. */
- if (i < br_lck->num_locks - 1) {
- memmove(&locks[i], &locks[i+1],
- sizeof(*locks)*((br_lck->num_locks-1) - i));
- }
-
- br_lck->num_locks -= 1;
- br_lck->modified = True;
return True;
}
@@ -861,9 +902,8 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s
BOOL lock_was_added = False;
unsigned int tmp_count;
-
/* Only remove our own locks - ignore fnum. */
- if (lock->lock_type == PENDING_LOCK ||
+ if (IS_PENDING_LOCK(lock->lock_type) ||
!brl_same_context(&lock->context, &plock->context)) {
memcpy(&tp[count], lock, sizeof(struct lock_struct));
count++;
@@ -894,13 +934,18 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s
SMB_ASSERT(tmp_lock[0].lock_type == locks[i].lock_type);
SMB_ASSERT(tmp_lock[1].lock_type == UNLOCK_LOCK);
memcpy(&tp[count], &tmp_lock[0], sizeof(struct lock_struct));
+ if (tmp_lock[0].size != locks[i].size) {
+ overlap_found = True;
+ }
} else {
SMB_ASSERT(tmp_lock[0].lock_type == UNLOCK_LOCK);
SMB_ASSERT(tmp_lock[1].lock_type == locks[i].lock_type);
memcpy(&tp[count], &tmp_lock[1], sizeof(struct lock_struct));
+ if (tmp_lock[1].start != locks[i].start) {
+ overlap_found = True;
+ }
}
count++;
- overlap_found = True;
continue;
} else {
/* tmp_count == 3 - (we split a lock range in two). */
@@ -932,14 +977,15 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s
return True;
}
-#if 0
- /* FIXME - this call doesn't work correctly yet for POSIX locks... */
-
/* Unlock any POSIX regions. */
- if(lp_posix_locking(br_lck->fsp->conn->cnum)) {
- release_posix_lock(br_lck->fsp, plock->start, plock->size);
+ if(lp_posix_locking(br_lck->fsp->conn->params)) {
+ release_posix_lock_posix_flavour(br_lck->fsp,
+ plock->start,
+ plock->size,
+ &plock->context,
+ tp,
+ count);
}
-#endif
/* Realloc so we don't leak entries per unlock call. */
if (count) {
@@ -956,7 +1002,8 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s
br_lck->num_locks = count;
SAFE_FREE(br_lck->lock_data);
- locks = br_lck->lock_data = (void *)tp;
+ locks = tp;
+ br_lck->lock_data = (void *)tp;
br_lck->modified = True;
/* Send unlock messages to any pending waiters that overlap. */
@@ -965,7 +1012,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s
struct lock_struct *pend_lock = &locks[j];
/* Ignore non-pending locks. */
- if (pend_lock->lock_type != PENDING_LOCK) {
+ if (!IS_PENDING_LOCK(pend_lock->lock_type)) {
continue;
}
@@ -974,11 +1021,9 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s
DEBUG(10,("brl_unlock: sending unlock message to pid %s\n",
procid_str_static(&pend_lock->context.pid )));
- become_root();
message_send_pid(pend_lock->context.pid,
MSG_SMB_UNLOCK,
NULL, 0, True);
- unbecome_root();
}
}
@@ -990,7 +1035,7 @@ static BOOL brl_unlock_posix(struct byte_range_lock *br_lck, const struct lock_s
****************************************************************************/
BOOL brl_unlock(struct byte_range_lock *br_lck,
- uint16 smbpid,
+ uint32 smbpid,
struct process_id pid,
br_off start,
br_off size,
@@ -1020,7 +1065,7 @@ BOOL brl_unlock(struct byte_range_lock *br_lck,
****************************************************************************/
BOOL brl_locktest(struct byte_range_lock *br_lck,
- uint16 smbpid,
+ uint32 smbpid,
struct process_id pid,
br_off start,
br_off size,
@@ -1030,7 +1075,7 @@ BOOL brl_locktest(struct byte_range_lock *br_lck,
BOOL ret = True;
unsigned int i;
struct lock_struct lock;
- struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data;
+ const struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data;
files_struct *fsp = br_lck->fsp;
lock.context.smbpid = smbpid;
@@ -1058,7 +1103,7 @@ BOOL brl_locktest(struct byte_range_lock *br_lck,
* This only conflicts with Windows locks, not POSIX locks.
*/
- if(lp_posix_locking(fsp->conn->cnum) && (lock_flav == WINDOWS_LOCK)) {
+ if(lp_posix_locking(fsp->conn->params) && (lock_flav == WINDOWS_LOCK)) {
ret = is_posix_locked(fsp, &start, &size, &lock_type, WINDOWS_LOCK);
DEBUG(10,("brl_locktest: posix start=%.0f len=%.0f %s for fnum %d file %s\n",
@@ -1078,7 +1123,7 @@ BOOL brl_locktest(struct byte_range_lock *br_lck,
****************************************************************************/
NTSTATUS brl_lockquery(struct byte_range_lock *br_lck,
- uint16 *psmbpid,
+ uint32 *psmbpid,
struct process_id pid,
br_off *pstart,
br_off *psize,
@@ -1087,7 +1132,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck,
{
unsigned int i;
struct lock_struct lock;
- struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data;
+ const struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data;
files_struct *fsp = br_lck->fsp;
lock.context.smbpid = *psmbpid;
@@ -1101,7 +1146,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck,
/* Make sure existing locks don't conflict */
for (i=0; i < br_lck->num_locks; i++) {
- struct lock_struct *exlock = &locks[i];
+ const struct lock_struct *exlock = &locks[i];
BOOL conflict = False;
if (exlock->lock_flav == WINDOWS_LOCK) {
@@ -1124,7 +1169,7 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck,
* see if there is a POSIX lock from a UNIX or NFS process.
*/
- if(lp_posix_locking(fsp->conn->cnum)) {
+ if(lp_posix_locking(fsp->conn->params)) {
BOOL ret = is_posix_locked(fsp, pstart, psize, plock_type, POSIX_LOCK);
DEBUG(10,("brl_lockquery: posix start=%.0f len=%.0f %s for fnum %d file %s\n",
@@ -1141,13 +1186,12 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck,
return NT_STATUS_OK;
}
-
/****************************************************************************
Remove a particular pending lock.
****************************************************************************/
-BOOL brl_remove_pending_lock(struct byte_range_lock *br_lck,
- uint16 smbpid,
+BOOL brl_lock_cancel(struct byte_range_lock *br_lck,
+ uint32 smbpid,
struct process_id pid,
br_off start,
br_off size,
@@ -1167,7 +1211,7 @@ BOOL brl_remove_pending_lock(struct byte_range_lock *br_lck,
/* For pending locks we *always* care about the fnum. */
if (brl_same_context(&lock->context, &context) &&
lock->fnum == br_lck->fsp->fnum &&
- lock->lock_type == PENDING_LOCK &&
+ IS_PENDING_LOCK(lock->lock_type) &&
lock->lock_flav == lock_flav &&
lock->start == start &&
lock->size == size) {
@@ -1191,18 +1235,75 @@ BOOL brl_remove_pending_lock(struct byte_range_lock *br_lck,
return True;
}
-
/****************************************************************************
Remove any locks associated with a open file.
+ We return True if this process owns any other Windows locks on this
+ fd and so we should not immediately close the fd.
****************************************************************************/
-void brl_close_fnum(struct byte_range_lock *br_lck, struct process_id pid)
+void brl_close_fnum(struct byte_range_lock *br_lck)
{
files_struct *fsp = br_lck->fsp;
uint16 tid = fsp->conn->cnum;
int fnum = fsp->fnum;
unsigned int i, j, dcount=0;
+ int num_deleted_windows_locks = 0;
struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data;
+ struct process_id pid = procid_self();
+ BOOL unlock_individually = False;
+
+ if(lp_posix_locking(fsp->conn->params)) {
+
+ /* Check if there are any Windows locks associated with this dev/ino
+ pair that are not this fnum. If so we need to call unlock on each
+ one in order to release the system POSIX locks correctly. */
+
+ for (i=0; i < br_lck->num_locks; i++) {
+ struct lock_struct *lock = &locks[i];
+
+ if (!procid_equal(&lock->context.pid, &pid)) {
+ continue;
+ }
+
+ if (lock->lock_type != READ_LOCK && lock->lock_type != WRITE_LOCK) {
+ continue; /* Ignore pending. */
+ }
+
+ if (lock->context.tid != tid || lock->fnum != fnum) {
+ unlock_individually = True;
+ break;
+ }
+ }
+
+ if (unlock_individually) {
+ struct lock_struct *locks_copy;
+ unsigned int num_locks_copy;
+
+ /* Copy the current lock array. */
+ locks_copy = (struct lock_struct *)TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct));
+ if (!locks_copy) {
+ smb_panic("brl_close_fnum: talloc fail.\n");
+ }
+ num_locks_copy = br_lck->num_locks;
+
+ for (i=0; i < num_locks_copy; i++) {
+ struct lock_struct *lock = &locks_copy[i];
+
+ if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid) &&
+ (lock->fnum == fnum)) {
+ brl_unlock(br_lck,
+ lock->context.smbpid,
+ pid,
+ lock->start,
+ lock->size,
+ lock->lock_flav);
+ }
+ }
+ return;
+ }
+ }
+
+ /* We can bulk delete - any POSIX locks will be removed when the fd closes. */
/* Remove any existing locks for this fnum (or any fnum if they're POSIX). */
@@ -1213,6 +1314,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck, struct process_id pid)
if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid)) {
if ((lock->lock_flav == WINDOWS_LOCK) && (lock->fnum == fnum)) {
del_this_lock = True;
+ num_deleted_windows_locks++;
} else if (lock->lock_flav == POSIX_LOCK) {
del_this_lock = True;
}
@@ -1224,7 +1326,7 @@ void brl_close_fnum(struct byte_range_lock *br_lck, struct process_id pid)
struct lock_struct *pend_lock = &locks[j];
/* Ignore our own or non-pending locks. */
- if (pend_lock->lock_type != PENDING_LOCK) {
+ if (!IS_PENDING_LOCK(pend_lock->lock_type)) {
continue;
}
@@ -1238,11 +1340,9 @@ void brl_close_fnum(struct byte_range_lock *br_lck, struct process_id pid)
/* We could send specific lock info here... */
if (brl_pending_overlap(lock, pend_lock)) {
- become_root();
message_send_pid(pend_lock->context.pid,
MSG_SMB_UNLOCK,
NULL, 0, True);
- unbecome_root();
}
}
@@ -1257,6 +1357,11 @@ void brl_close_fnum(struct byte_range_lock *br_lck, struct process_id pid)
dcount++;
}
}
+
+ if(lp_posix_locking(fsp->conn->params) && num_deleted_windows_locks) {
+ /* Reduce the Windows lock POSIX reference count on this dev/ino pair. */
+ reduce_windows_lock_ref_count(fsp, num_deleted_windows_locks);
+ }
}
/****************************************************************************
@@ -1345,7 +1450,7 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st
}
if (orig_num_locks != num_locks) {
- dbuf.dptr = (void *)locks;
+ dbuf.dptr = (char *)locks;
dbuf.dsize = num_locks * sizeof(*locks);
if (dbuf.dsize) {
@@ -1387,13 +1492,17 @@ int brl_forall(BRLOCK_FN(fn))
Unlock the record.
********************************************************************/
-int byte_range_lock_destructor(struct byte_range_lock *br_lck)
+static int byte_range_lock_destructor(struct byte_range_lock *br_lck)
{
TDB_DATA key;
key.dptr = (char *)&br_lck->key;
key.dsize = sizeof(struct lock_key);
+ if (br_lck->read_only) {
+ SMB_ASSERT(!br_lck->modified);
+ }
+
if (!br_lck->modified) {
goto done;
}
@@ -1405,7 +1514,7 @@ int byte_range_lock_destructor(struct byte_range_lock *br_lck)
}
} else {
TDB_DATA data;
- data.dptr = br_lck->lock_data;
+ data.dptr = (char *)br_lck->lock_data;
data.dsize = br_lck->num_locks * sizeof(struct lock_struct);
if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) {
@@ -1415,22 +1524,25 @@ int byte_range_lock_destructor(struct byte_range_lock *br_lck)
done:
- tdb_chainunlock(tdb, key);
+ if (!br_lck->read_only) {
+ tdb_chainunlock(tdb, key);
+ }
SAFE_FREE(br_lck->lock_data);
- SAFE_FREE(br_lck);
return 0;
}
/*******************************************************************
Fetch a set of byte range lock data from the database.
Leave the record locked.
+ TALLOC_FREE(brl) will release the lock in the destructor.
********************************************************************/
-struct byte_range_lock *brl_get_locks(files_struct *fsp)
+static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx,
+ files_struct *fsp, BOOL read_only)
{
TDB_DATA key;
TDB_DATA data;
- struct byte_range_lock *br_lck = SMB_MALLOC_P(struct byte_range_lock);
+ struct byte_range_lock *br_lck = TALLOC_P(mem_ctx, struct byte_range_lock);
if (br_lck == NULL) {
return NULL;
@@ -1446,12 +1558,25 @@ struct byte_range_lock *brl_get_locks(files_struct *fsp)
key.dptr = (char *)&br_lck->key;
key.dsize = sizeof(struct lock_key);
- if (tdb_chainlock(tdb, key) != 0) {
- DEBUG(3, ("Could not lock byte range lock entry\n"));
- SAFE_FREE(br_lck);
- return NULL;
+ if (!fsp->lockdb_clean) {
+ /* We must be read/write to clean
+ the dead entries. */
+ read_only = False;
}
+ if (read_only) {
+ br_lck->read_only = True;
+ } else {
+ if (tdb_chainlock(tdb, key) != 0) {
+ DEBUG(3, ("Could not lock byte range lock entry\n"));
+ TALLOC_FREE(br_lck);
+ return NULL;
+ }
+ br_lck->read_only = False;
+ }
+
+ talloc_set_destructor(br_lck, byte_range_lock_destructor);
+
data = tdb_fetch(tdb, key);
br_lck->lock_data = (void *)data.dptr;
br_lck->num_locks = data.dsize / sizeof(struct lock_struct);
@@ -1462,13 +1587,22 @@ struct byte_range_lock *brl_get_locks(files_struct *fsp)
/* Go through and ensure all entries exist - remove any that don't. */
/* Makes the lockdb self cleaning at low cost. */
- if (!validate_lock_entries(&br_lck->num_locks, (struct lock_struct **)&br_lck->lock_data)) {
- tdb_chainunlock(tdb, key);
+ struct lock_struct *locks =
+ (struct lock_struct *)br_lck->lock_data;
+
+ if (!validate_lock_entries(&br_lck->num_locks, &locks)) {
SAFE_FREE(br_lck->lock_data);
- SAFE_FREE(br_lck);
+ TALLOC_FREE(br_lck);
return NULL;
}
+ /*
+ * validate_lock_entries might have changed locks. We can't
+ * use a direct pointer here because otherwise gcc warnes
+ * about strict aliasing rules being violated.
+ */
+ br_lck->lock_data = locks;
+
/* Mark the lockdb as "clean" as seen from this open file. */
fsp->lockdb_clean = True;
}
@@ -1476,7 +1610,7 @@ struct byte_range_lock *brl_get_locks(files_struct *fsp)
if (DEBUGLEVEL >= 10) {
unsigned int i;
struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data;
- DEBUG(10,("brl_get_locks: %u current locks on dev=%.0f, inode=%.0f\n",
+ DEBUG(10,("brl_get_locks_internal: %u current locks on dev=%.0f, inode=%.0f\n",
br_lck->num_locks,
(double)fsp->dev, (double)fsp->inode ));
for( i = 0; i < br_lck->num_locks; i++) {
@@ -1485,3 +1619,15 @@ struct byte_range_lock *brl_get_locks(files_struct *fsp)
}
return br_lck;
}
+
+struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx,
+ files_struct *fsp)
+{
+ return brl_get_locks_internal(mem_ctx, fsp, False);
+}
+
+struct byte_range_lock *brl_get_locks_readonly(TALLOC_CTX *mem_ctx,
+ files_struct *fsp)
+{
+ return brl_get_locks_internal(mem_ctx, fsp, True);
+}
diff --git a/source/locking/locking.c b/source/locking/locking.c
index 9d3ca956014..13c7724656e 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -37,7 +37,6 @@
*/
#include "includes.h"
-uint16 global_smbpid;
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_LOCKING
@@ -56,8 +55,10 @@ const char *lock_type_name(enum brl_type lock_type)
return "READ";
case WRITE_LOCK:
return "WRITE";
- case PENDING_LOCK:
- return "PENDING";
+ case PENDING_READ_LOCK:
+ return "PENDING_READ";
+ case PENDING_WRITE_LOCK:
+ return "PENDING_WRITE";
default:
return "other";
}
@@ -74,12 +75,12 @@ const char *lock_flav_name(enum brl_flavour lock_flav)
****************************************************************************/
BOOL is_locked(files_struct *fsp,
+ uint32 smbpid,
SMB_BIG_UINT count,
SMB_BIG_UINT offset,
enum brl_type lock_type)
{
- int snum = SNUM(fsp->conn);
- int strict_locking = lp_strict_locking(snum);
+ int strict_locking = lp_strict_locking(fsp->conn->params);
enum brl_flavour lock_flav = lp_posix_cifsu_locktype();
BOOL ret = True;
@@ -87,7 +88,7 @@ BOOL is_locked(files_struct *fsp,
return False;
}
- if (!lp_locking(snum) || !strict_locking) {
+ if (!lp_locking(fsp->conn->params) || !strict_locking) {
return False;
}
@@ -100,32 +101,32 @@ BOOL is_locked(files_struct *fsp,
DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
ret = False;
} else {
- struct byte_range_lock *br_lck = brl_get_locks(fsp);
+ struct byte_range_lock *br_lck = brl_get_locks_readonly(NULL, fsp);
if (!br_lck) {
return False;
}
ret = !brl_locktest(br_lck,
- global_smbpid,
+ smbpid,
procid_self(),
offset,
count,
lock_type,
lock_flav);
- byte_range_lock_destructor(br_lck);
+ TALLOC_FREE(br_lck);
}
} else {
- struct byte_range_lock *br_lck = brl_get_locks(fsp);
+ struct byte_range_lock *br_lck = brl_get_locks_readonly(NULL, fsp);
if (!br_lck) {
return False;
}
ret = !brl_locktest(br_lck,
- global_smbpid,
+ smbpid,
procid_self(),
offset,
count,
lock_type,
lock_flav);
- byte_range_lock_destructor(br_lck);
+ TALLOC_FREE(br_lck);
}
DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n",
@@ -141,7 +142,7 @@ BOOL is_locked(files_struct *fsp,
****************************************************************************/
NTSTATUS query_lock(files_struct *fsp,
- uint16 *psmbpid,
+ uint32 *psmbpid,
SMB_BIG_UINT *pcount,
SMB_BIG_UINT *poffset,
enum brl_type *plock_type,
@@ -150,15 +151,15 @@ NTSTATUS query_lock(files_struct *fsp,
struct byte_range_lock *br_lck = NULL;
NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
- if (!OPEN_FSP(fsp) || !fsp->can_lock) {
- return NT_STATUS_INVALID_HANDLE;
+ if (!fsp->can_lock) {
+ return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
}
- if (!lp_locking(SNUM(fsp->conn))) {
+ if (!lp_locking(fsp->conn->params)) {
return NT_STATUS_OK;
}
- br_lck = brl_get_locks(fsp);
+ br_lck = brl_get_locks_readonly(NULL, fsp);
if (!br_lck) {
return NT_STATUS_NO_MEMORY;
}
@@ -171,7 +172,7 @@ NTSTATUS query_lock(files_struct *fsp,
plock_type,
lock_flav);
- byte_range_lock_destructor(br_lck);
+ TALLOC_FREE(br_lck);
return status;
}
@@ -179,23 +180,25 @@ NTSTATUS query_lock(files_struct *fsp,
Utility function called by locking requests.
****************************************************************************/
-NTSTATUS do_lock(files_struct *fsp,
- uint16 lock_pid,
+struct byte_range_lock *do_lock(files_struct *fsp,
+ uint32 lock_pid,
SMB_BIG_UINT count,
SMB_BIG_UINT offset,
enum brl_type lock_type,
enum brl_flavour lock_flav,
- BOOL *my_lock_ctx)
+ BOOL blocking_lock,
+ NTSTATUS *perr)
{
struct byte_range_lock *br_lck = NULL;
- NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
- if (!OPEN_FSP(fsp) || !fsp->can_lock) {
- return NT_STATUS_INVALID_HANDLE;
+ if (!fsp->can_lock) {
+ *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
+ return NULL;
}
- if (!lp_locking(SNUM(fsp->conn))) {
- return NT_STATUS_OK;
+ if (!lp_locking(fsp->conn->params)) {
+ *perr = NT_STATUS_OK;
+ return NULL;
}
/* NOTE! 0 byte long ranges ARE allowed and should be stored */
@@ -204,89 +207,76 @@ NTSTATUS do_lock(files_struct *fsp,
lock_flav_name(lock_flav), lock_type_name(lock_type),
(double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
- br_lck = brl_get_locks(fsp);
+ br_lck = brl_get_locks(NULL, fsp);
if (!br_lck) {
- return NT_STATUS_NO_MEMORY;
+ *perr = NT_STATUS_NO_MEMORY;
+ return NULL;
}
- status = brl_lock(br_lck,
+ *perr = brl_lock(br_lck,
lock_pid,
procid_self(),
offset,
count,
lock_type,
lock_flav,
- my_lock_ctx);
+ blocking_lock);
- byte_range_lock_destructor(br_lck);
- return status;
+ return br_lck;
}
/****************************************************************************
- Utility function called by locking requests. This is *DISGUSTING*. It also
- appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000
- is so slow on the locking tests...... ? This is the reason. Much though I hate
- it, we need this. JRA.
+ Utility function called by unlocking requests.
****************************************************************************/
-NTSTATUS do_lock_spin(files_struct *fsp,
- uint16 lock_pid,
+NTSTATUS do_unlock(files_struct *fsp,
+ uint32 lock_pid,
SMB_BIG_UINT count,
SMB_BIG_UINT offset,
- enum brl_type lock_type,
- enum brl_flavour lock_flav,
- BOOL *my_lock_ctx)
+ enum brl_flavour lock_flav)
{
- int j, maxj = lp_lock_spin_count();
- int sleeptime = lp_lock_sleep_time();
- NTSTATUS status, ret;
-
- if (maxj <= 0) {
- maxj = 1;
+ BOOL ok = False;
+ struct byte_range_lock *br_lck = NULL;
+
+ if (!fsp->can_lock) {
+ return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
}
+
+ if (!lp_locking(fsp->conn->params)) {
+ return NT_STATUS_OK;
+ }
+
+ DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
+ (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
- ret = NT_STATUS_OK; /* to keep dumb compilers happy */
-
- for (j = 0; j < maxj; j++) {
- status = do_lock(fsp,
- lock_pid,
- count,
- offset,
- lock_type,
- lock_flav,
- my_lock_ctx);
-
- if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) &&
- !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
- return status;
- }
- /* if we do fail then return the first error code we got */
- if (j == 0) {
- ret = status;
- /* Don't spin if we blocked ourselves. */
- if (*my_lock_ctx) {
- return ret;
- }
+ br_lck = brl_get_locks(NULL, fsp);
+ if (!br_lck) {
+ return NT_STATUS_NO_MEMORY;
+ }
- /* Only spin for Windows locks. */
- if (lock_flav == POSIX_LOCK) {
- return ret;
- }
- }
+ ok = brl_unlock(br_lck,
+ lock_pid,
+ procid_self(),
+ offset,
+ count,
+ lock_flav);
+
+ TALLOC_FREE(br_lck);
- if (sleeptime) {
- sys_usleep(sleeptime);
- }
+ if (!ok) {
+ DEBUG(10,("do_unlock: returning ERRlock.\n" ));
+ return NT_STATUS_RANGE_NOT_LOCKED;
}
- return ret;
+
+ return NT_STATUS_OK;
}
/****************************************************************************
- Utility function called by unlocking requests.
+ Cancel any pending blocked locks.
****************************************************************************/
-NTSTATUS do_unlock(files_struct *fsp,
- uint16 lock_pid,
+NTSTATUS do_lock_cancel(files_struct *fsp,
+ uint32 lock_pid,
SMB_BIG_UINT count,
SMB_BIG_UINT offset,
enum brl_flavour lock_flav)
@@ -294,34 +284,35 @@ NTSTATUS do_unlock(files_struct *fsp,
BOOL ok = False;
struct byte_range_lock *br_lck = NULL;
- if (!lp_locking(SNUM(fsp->conn))) {
- return NT_STATUS_OK;
+ if (!fsp->can_lock) {
+ return fsp->is_directory ?
+ NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
}
- if (!OPEN_FSP(fsp) || !fsp->can_lock) {
- return NT_STATUS_INVALID_HANDLE;
+ if (!lp_locking(fsp->conn->params)) {
+ return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
}
-
- DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
+
+ DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
(double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
- br_lck = brl_get_locks(fsp);
+ br_lck = brl_get_locks(NULL, fsp);
if (!br_lck) {
return NT_STATUS_NO_MEMORY;
}
- ok = brl_unlock(br_lck,
+ ok = brl_lock_cancel(br_lck,
lock_pid,
procid_self(),
offset,
count,
lock_flav);
- byte_range_lock_destructor(br_lck);
+ TALLOC_FREE(br_lck);
if (!ok) {
- DEBUG(10,("do_unlock: returning ERRlock.\n" ));
- return NT_STATUS_RANGE_NOT_LOCKED;
+ DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
+ return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
}
return NT_STATUS_OK;
@@ -334,25 +325,17 @@ NTSTATUS do_unlock(files_struct *fsp,
void locking_close_file(files_struct *fsp)
{
struct byte_range_lock *br_lck;
- struct process_id pid = procid_self();
- if (!lp_locking(SNUM(fsp->conn)))
+ if (!lp_locking(fsp->conn->params)) {
return;
-
- /*
- * Just release all the brl locks, no need to release individually.
- */
-
- br_lck = brl_get_locks(fsp);
- if (br_lck) {
- brl_close_fnum(br_lck, pid);
- byte_range_lock_destructor(br_lck);
}
- if(lp_posix_locking(SNUM(fsp->conn))) {
- /* Release all the POSIX locks.*/
- posix_locking_close_file(fsp);
+ br_lck = brl_get_locks(NULL,fsp);
+ if (br_lck) {
+ cancel_pending_lock_requests_by_fid(fsp, br_lck);
+ brl_close_fnum(br_lck);
+ TALLOC_FREE(br_lck);
}
}
@@ -516,9 +499,10 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
smb_panic("PANIC: parse_share_modes: buffer too short.\n");
}
- lck->share_modes = talloc_memdup(lck, dbuf.dptr+sizeof(*data),
- lck->num_share_modes *
- sizeof(struct share_mode_entry));
+ lck->share_modes = (struct share_mode_entry *)
+ talloc_memdup(lck, dbuf.dptr+sizeof(*data),
+ lck->num_share_modes *
+ sizeof(struct share_mode_entry));
if (lck->share_modes == NULL) {
smb_panic("talloc failed\n");
@@ -577,12 +561,18 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
(lck->num_share_modes *
sizeof(struct share_mode_entry)) +
data->u.s.delete_token_size );
+ if (lck->servicepath == NULL) {
+ smb_panic("talloc_strdup failed\n");
+ }
lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
(lck->num_share_modes *
sizeof(struct share_mode_entry)) +
data->u.s.delete_token_size +
strlen(lck->servicepath) + 1 );
+ if (lck->filename == NULL) {
+ smb_panic("talloc_strdup failed\n");
+ }
/*
* Ensure that each entry has a real process attached.
@@ -635,7 +625,7 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
delete_token_size +
sp_len + 1 +
strlen(lck->filename) + 1;
- result.dptr = talloc_size(lck, result.dsize);
+ result.dptr = TALLOC_ARRAY(lck, char, result.dsize);
if (result.dptr == NULL) {
smb_panic("talloc failed\n");
@@ -687,10 +677,8 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
return result;
}
-static int share_mode_lock_destructor(void *p)
+static int share_mode_lock_destructor(struct share_mode_lock *lck)
{
- struct share_mode_lock *lck =
- talloc_get_type_abort(p, struct share_mode_lock);
TDB_DATA key = locking_key(lck->dev, lck->ino);
TDB_DATA data;
@@ -838,7 +826,7 @@ BOOL rename_share_filename(struct share_mode_lock *lck,
msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + fn_len + 1;
/* Set up the name changed message. */
- frm = TALLOC(lck, msg_len);
+ frm = TALLOC_ARRAY(lck, char, msg_len);
if (!frm) {
return False;
}
@@ -862,16 +850,14 @@ BOOL rename_share_filename(struct share_mode_lock *lck,
continue;
}
- DEBUG(10,("rename_share_filename: sending rename message to pid %u "
+ DEBUG(10,("rename_share_filename: sending rename message to pid %s "
"dev %x, inode %.0f sharepath %s newname %s\n",
- (unsigned int)procid_to_pid(&se->pid),
+ procid_str_static(&se->pid),
(unsigned int)lck->dev, (double)lck->ino,
lck->servicepath, lck->filename ));
- become_root();
message_send_pid(se->pid, MSG_SMB_FILE_RENAME,
frm, msg_len, True);
- unbecome_root();
}
return True;
@@ -1266,15 +1252,23 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKE
return True;
}
+struct forall_state {
+ void (*fn)(const struct share_mode_entry *entry,
+ const char *sharepath,
+ const char *fname,
+ void *private_data);
+ void *private_data;
+};
+
static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
- void *state)
+ void *_state)
{
+ struct forall_state *state = (struct forall_state *)_state;
struct locking_data *data;
struct share_mode_entry *shares;
const char *sharepath;
const char *fname;
int i;
- LOCKING_FN(traverse_callback) = (LOCKING_FN_CAST())state;
/* Ensure this is a locking_key record. */
if (kbuf.dsize != sizeof(struct locking_key))
@@ -1291,7 +1285,8 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
strlen(sharepath) + 1;
for (i=0;i<data->u.s.num_share_mode_entries;i++) {
- traverse_callback(&shares[i], sharepath, fname);
+ state->fn(&shares[i], sharepath, fname,
+ state->private_data);
}
return 0;
}
@@ -1301,9 +1296,17 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
share mode system.
********************************************************************/
-int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, const char *))
+int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
+ const char *, void *),
+ void *private_data)
{
+ struct forall_state state;
+
if (tdb == NULL)
return 0;
- return tdb_traverse(tdb, traverse_fn, fn);
+
+ state.fn = fn;
+ state.private_data = private_data;
+
+ return tdb_traverse(tdb, traverse_fn, (void *)&state);
}
diff --git a/source/locking/posix.c b/source/locking/posix.c
index 4a5f59b622d..806018da816 100644
--- a/source/locking/posix.c
+++ b/source/locking/posix.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
Locking functions
- Copyright (C) Jeremy Allison 1992-2000
+ Copyright (C) Jeremy Allison 1992-2006
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
@@ -28,481 +28,17 @@
#define DBGC_CLASS DBGC_LOCKING
/*
- * The POSIX locking database handle.
- */
-
-static TDB_CONTEXT *posix_lock_tdb;
-
-/*
* The pending close database handle.
*/
static TDB_CONTEXT *posix_pending_close_tdb;
-/*
- * The data in POSIX lock records is an unsorted linear array of these
- * records. It is unnecessary to store the count as tdb provides the
- * size of the record.
- */
-
-struct posix_lock {
- int fd;
- SMB_OFF_T start;
- SMB_OFF_T size;
- int lock_type;
-};
-
-/*
- * The data in POSIX pending close records is an unsorted linear array of int
- * records. It is unnecessary to store the count as tdb provides the
- * size of the record.
- */
-
-/* The key used in both the POSIX databases. */
-
-struct posix_lock_key {
- SMB_DEV_T device;
- SMB_INO_T inode;
-};
-
-/*******************************************************************
- Form a static locking key for a dev/inode pair.
-******************************************************************/
-
-static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
-{
- static struct posix_lock_key key;
- TDB_DATA kbuf;
-
- memset(&key, '\0', sizeof(key));
- key.device = dev;
- key.inode = inode;
- kbuf.dptr = (char *)&key;
- kbuf.dsize = sizeof(key);
- return kbuf;
-}
-
-/*******************************************************************
- Convenience function to get a key from an fsp.
-******************************************************************/
-
-static TDB_DATA locking_key_fsp(files_struct *fsp)
-{
- return locking_key(fsp->dev, fsp->inode);
-}
-
-/****************************************************************************
- Add an fd to the pending close tdb.
-****************************************************************************/
-
-static BOOL add_fd_to_close_entry(files_struct *fsp)
-{
- TDB_DATA kbuf = locking_key_fsp(fsp);
- TDB_DATA dbuf;
-
- dbuf.dptr = NULL;
- dbuf.dsize = 0;
-
- dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
-
- dbuf.dptr = SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(int));
- if (!dbuf.dptr) {
- DEBUG(0,("add_fd_to_close_entry: Realloc fail !\n"));
- return False;
- }
-
- memcpy(dbuf.dptr + dbuf.dsize, &fsp->fh->fd, sizeof(int));
- dbuf.dsize += sizeof(int);
-
- if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
- DEBUG(0,("add_fd_to_close_entry: tdb_store fail !\n"));
- }
-
- SAFE_FREE(dbuf.dptr);
- return True;
-}
-
-/****************************************************************************
- Remove all fd entries for a specific dev/inode pair from the tdb.
-****************************************************************************/
-
-static void delete_close_entries(files_struct *fsp)
-{
- TDB_DATA kbuf = locking_key_fsp(fsp);
-
- if (tdb_delete(posix_pending_close_tdb, kbuf) == -1)
- DEBUG(0,("delete_close_entries: tdb_delete fail !\n"));
-}
-
-/****************************************************************************
- Get the array of POSIX pending close records for an open fsp. Caller must
- free. Returns number of entries.
-****************************************************************************/
-
-static size_t get_posix_pending_close_entries(files_struct *fsp, int **entries)
-{
- TDB_DATA kbuf = locking_key_fsp(fsp);
- TDB_DATA dbuf;
- size_t count = 0;
-
- *entries = NULL;
- dbuf.dptr = NULL;
-
- dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
-
- if (!dbuf.dptr) {
- return 0;
- }
-
- *entries = (int *)dbuf.dptr;
- count = (size_t)(dbuf.dsize / sizeof(int));
-
- return count;
-}
-
-/****************************************************************************
- Get the array of POSIX locks for an fsp. Caller must free. Returns
- number of entries.
-****************************************************************************/
-
-static size_t get_posix_lock_entries(files_struct *fsp, struct posix_lock **entries)
-{
- TDB_DATA kbuf = locking_key_fsp(fsp);
- TDB_DATA dbuf;
- size_t count = 0;
-
- *entries = NULL;
-
- dbuf.dptr = NULL;
-
- dbuf = tdb_fetch(posix_lock_tdb, kbuf);
-
- if (!dbuf.dptr) {
- return 0;
- }
-
- *entries = (struct posix_lock *)dbuf.dptr;
- count = (size_t)(dbuf.dsize / sizeof(struct posix_lock));
-
- return count;
-}
-
-/****************************************************************************
- Deal with pending closes needed by POSIX locking support.
- Note that posix_locking_close_file() is expected to have been called
- to delete all locks on this fsp before this function is called.
-****************************************************************************/
-
-int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
-{
- int saved_errno = 0;
- int ret;
- size_t count, i;
- struct posix_lock *entries = NULL;
- int *fd_array = NULL;
- BOOL locks_on_other_fds = False;
-
- if (!lp_posix_locking(SNUM(conn))) {
- /*
- * No POSIX to worry about, just close.
- */
- ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd);
- fsp->fh->fd = -1;
- return ret;
- }
-
- /*
- * Get the number of outstanding POSIX locks on this dev/inode pair.
- */
-
- count = get_posix_lock_entries(fsp, &entries);
-
- /*
- * Check if there are any outstanding locks belonging to
- * other fd's. This should never be the case if posix_locking_close_file()
- * has been called first, but it never hurts to be *sure*.
- */
-
- for (i = 0; i < count; i++) {
- if (entries[i].fd != fsp->fh->fd) {
- locks_on_other_fds = True;
- break;
- }
- }
-
- if (locks_on_other_fds) {
-
- /*
- * There are outstanding locks on this dev/inode pair on other fds.
- * Add our fd to the pending close tdb and set fsp->fh->fd to -1.
- */
-
- if (!add_fd_to_close_entry(fsp)) {
- SAFE_FREE(entries);
- return -1;
- }
-
- SAFE_FREE(entries);
- fsp->fh->fd = -1;
- return 0;
- }
-
- SAFE_FREE(entries);
-
- /*
- * No outstanding POSIX locks. Get the pending close fd's
- * from the tdb and close them all.
- */
-
- count = get_posix_pending_close_entries(fsp, &fd_array);
-
- if (count) {
- DEBUG(10,("fd_close_posix: doing close on %u fd's.\n", (unsigned int)count ));
-
- for(i = 0; i < count; i++) {
- if (SMB_VFS_CLOSE(fsp,fd_array[i]) == -1) {
- saved_errno = errno;
- }
- }
-
- /*
- * Delete all fd's stored in the tdb
- * for this dev/inode pair.
- */
-
- delete_close_entries(fsp);
- }
-
- SAFE_FREE(fd_array);
-
- /*
- * Finally close the fd associated with this fsp.
- */
-
- ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd);
-
- if (saved_errno != 0) {
- errno = saved_errno;
- ret = -1;
- }
-
- fsp->fh->fd = -1;
-
- return ret;
-}
-
-/****************************************************************************
- Debugging aid :-).
-****************************************************************************/
-
-static const char *posix_lock_type_name(int lock_type)
-{
- return (lock_type == F_RDLCK) ? "READ" : "WRITE";
-}
-
-/****************************************************************************
- Delete a POSIX lock entry by index number. Used if the tdb add succeeds, but
- then the POSIX fcntl lock fails.
-****************************************************************************/
-
-static BOOL delete_posix_lock_entry_by_index(files_struct *fsp, size_t entry)
-{
- TDB_DATA kbuf = locking_key_fsp(fsp);
- TDB_DATA dbuf;
- struct posix_lock *locks;
- size_t count;
-
- dbuf.dptr = NULL;
-
- dbuf = tdb_fetch(posix_lock_tdb, kbuf);
-
- if (!dbuf.dptr) {
- DEBUG(10,("delete_posix_lock_entry_by_index: tdb_fetch failed !\n"));
- goto fail;
- }
-
- count = (size_t)(dbuf.dsize / sizeof(struct posix_lock));
- locks = (struct posix_lock *)dbuf.dptr;
-
- if (count == 1) {
- tdb_delete(posix_lock_tdb, kbuf);
- } else {
- if (entry < count-1) {
- memmove(&locks[entry], &locks[entry+1], sizeof(struct posix_lock)*((count-1) - entry));
- }
- dbuf.dsize -= sizeof(struct posix_lock);
- tdb_store(posix_lock_tdb, kbuf, dbuf, TDB_REPLACE);
- }
-
- SAFE_FREE(dbuf.dptr);
-
- return True;
-
- fail:
-
- SAFE_FREE(dbuf.dptr);
- return False;
-}
-
-/****************************************************************************
- Add an entry into the POSIX locking tdb. We return the index number of the
- added lock (used in case we need to delete *exactly* this entry). Returns
- False on fail, True on success.
-****************************************************************************/
-
-static BOOL add_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T size, int lock_type, size_t *pentry_num)
-{
- TDB_DATA kbuf = locking_key_fsp(fsp);
- TDB_DATA dbuf;
- struct posix_lock pl;
-
- dbuf.dptr = NULL;
- dbuf.dsize = 0;
-
- dbuf = tdb_fetch(posix_lock_tdb, kbuf);
-
- *pentry_num = (size_t)(dbuf.dsize / sizeof(struct posix_lock));
-
- /*
- * Add new record.
- */
-
- pl.fd = fsp->fh->fd;
- pl.start = start;
- pl.size = size;
- pl.lock_type = lock_type;
-
- dbuf.dptr = SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(struct posix_lock));
- if (!dbuf.dptr) {
- DEBUG(0,("add_posix_lock_entry: Realloc fail !\n"));
- goto fail;
- }
-
- memcpy(dbuf.dptr + dbuf.dsize, &pl, sizeof(struct posix_lock));
- dbuf.dsize += sizeof(struct posix_lock);
-
- if (tdb_store(posix_lock_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
- DEBUG(0,("add_posix_lock: Failed to add lock entry on file %s\n", fsp->fsp_name));
- goto fail;
- }
-
- SAFE_FREE(dbuf.dptr);
-
- DEBUG(10,("add_posix_lock: File %s: type = %s: start=%.0f size=%.0f: dev=%.0f inode=%.0f\n",
- fsp->fsp_name, posix_lock_type_name(lock_type), (double)start, (double)size,
- (double)fsp->dev, (double)fsp->inode ));
-
- return True;
-
- fail:
-
- SAFE_FREE(dbuf.dptr);
- return False;
-}
-
/****************************************************************************
- Calculate if locks have any overlap at all.
+ First - the functions that deal with the underlying system locks - these
+ functions are used no matter if we're mapping CIFS Windows locks or CIFS
+ POSIX locks onto POSIX.
****************************************************************************/
-static BOOL does_lock_overlap(SMB_OFF_T start1, SMB_OFF_T size1, SMB_OFF_T start2, SMB_OFF_T size2)
-{
- if (start1 >= start2 && start1 <= start2 + size2)
- return True;
-
- if (start1 < start2 && start1 + size1 > start2)
- return True;
-
- return False;
-}
-
-/****************************************************************************
- Delete an entry from the POSIX locking tdb. Returns a copy of the entry being
- deleted and the number of records that are overlapped by this one, or -1 on error.
-****************************************************************************/
-
-static int delete_posix_lock_entry(files_struct *fsp, SMB_OFF_T start, SMB_OFF_T size, struct posix_lock *pl)
-{
- TDB_DATA kbuf = locking_key_fsp(fsp);
- TDB_DATA dbuf;
- struct posix_lock *locks;
- size_t i, count;
- BOOL found = False;
- int num_overlapping_records = 0;
-
- dbuf.dptr = NULL;
-
- dbuf = tdb_fetch(posix_lock_tdb, kbuf);
-
- if (!dbuf.dptr) {
- DEBUG(10,("delete_posix_lock_entry: tdb_fetch failed !\n"));
- goto fail;
- }
-
- /* There are existing locks - find a match. */
- locks = (struct posix_lock *)dbuf.dptr;
- count = (size_t)(dbuf.dsize / sizeof(struct posix_lock));
-
- /*
- * Search for and delete the first record that matches the
- * unlock criteria.
- */
-
- for (i=0; i<count; i++) {
- struct posix_lock *entry = &locks[i];
-
- if (entry->fd == fsp->fh->fd &&
- entry->start == start &&
- entry->size == size) {
-
- /* Make a copy */
- *pl = *entry;
-
- /* Found it - delete it. */
- if (count == 1) {
- tdb_delete(posix_lock_tdb, kbuf);
- } else {
- if (i < count-1) {
- memmove(&locks[i], &locks[i+1], sizeof(struct posix_lock)*((count-1) - i));
- }
- dbuf.dsize -= sizeof(struct posix_lock);
- tdb_store(posix_lock_tdb, kbuf, dbuf, TDB_REPLACE);
- }
- count--;
- found = True;
- break;
- }
- }
-
- if (!found)
- goto fail;
-
- /*
- * Count the number of entries that are
- * overlapped by this unlock request.
- */
-
- for (i = 0; i < count; i++) {
- struct posix_lock *entry = &locks[i];
-
- if (fsp->fh->fd == entry->fd &&
- does_lock_overlap( start, size, entry->start, entry->size))
- num_overlapping_records++;
- }
-
- DEBUG(10,("delete_posix_lock_entry: type = %s: start=%.0f size=%.0f, num_records = %d\n",
- posix_lock_type_name(pl->lock_type), (double)pl->start, (double)pl->size,
- (unsigned int)num_overlapping_records ));
-
- SAFE_FREE(dbuf.dptr);
-
- return num_overlapping_records;
-
- fail:
-
- SAFE_FREE(dbuf.dptr);
- return -1;
-}
-
/****************************************************************************
Utility function to map a lock type correctly depending on the open
mode of a file.
@@ -519,16 +55,6 @@ static int map_posix_lock_type( files_struct *fsp, enum brl_type lock_type)
DEBUG(10,("map_posix_lock_type: Downgrading write lock to read due to read-only file.\n"));
return F_RDLCK;
}
-#if 0
- /* We no longer open files write-only. */
- else if((lock_type == READ_LOCK) && !fsp->can_read) {
- /*
- * Ditto for read locks on write only files.
- */
- DEBUG(10,("map_posix_lock_type: Changing read lock to write due to write-only file.\n"));
- return F_WRLCK;
- }
-#endif
/*
* This return should be the most normal, as we attempt
@@ -539,6 +65,15 @@ static int map_posix_lock_type( files_struct *fsp, enum brl_type lock_type)
}
/****************************************************************************
+ Debugging aid :-).
+****************************************************************************/
+
+static const char *posix_lock_type_name(int lock_type)
+{
+ return (lock_type == F_RDLCK) ? "READ" : "WRITE";
+}
+
+/****************************************************************************
Check to see if the given unsigned lock range is within the possible POSIX
range. Modifies the given args to be in range if possible, just returns
False if not.
@@ -608,15 +143,17 @@ static BOOL posix_lock_in_range(SMB_OFF_T *offset_out, SMB_OFF_T *count_out,
* We must truncate the count to less than max_positive_lock_offset.
*/
- if (u_count & ~((SMB_BIG_UINT)max_positive_lock_offset))
+ if (u_count & ~((SMB_BIG_UINT)max_positive_lock_offset)) {
count = max_positive_lock_offset;
+ }
/*
* Truncate count to end at max lock offset.
*/
- if (offset + count < 0 || offset + count > max_positive_lock_offset)
+ if (offset + count < 0 || offset + count > max_positive_lock_offset) {
count = max_positive_lock_offset - offset;
+ }
/*
* If we ate all the count, ignore this lock.
@@ -729,7 +266,6 @@ static BOOL posix_fcntl_getlock(files_struct *fsp, SMB_OFF_T *poffset, SMB_OFF_T
return ret;
}
-
/****************************************************************************
POSIX function to see if a file region is locked. Returns True if the
region is locked, False otherwise.
@@ -774,6 +310,412 @@ BOOL is_posix_locked(files_struct *fsp,
return True;
}
+/****************************************************************************
+ Next - the functions that deal with in memory database storing representations
+ of either Windows CIFS locks or POSIX CIFS locks.
+****************************************************************************/
+
+/* The key used in the in-memory POSIX databases. */
+
+struct lock_ref_count_key {
+ SMB_DEV_T device;
+ SMB_INO_T inode;
+ char r;
+};
+
+struct fd_key {
+ SMB_DEV_T device;
+ SMB_INO_T inode;
+};
+
+/*******************************************************************
+ Form a static locking key for a dev/inode pair for the fd array.
+******************************************************************/
+
+static TDB_DATA fd_array_key(SMB_DEV_T dev, SMB_INO_T inode)
+{
+ static struct fd_key key;
+ TDB_DATA kbuf;
+
+ memset(&key, '\0', sizeof(key));
+ key.device = dev;
+ key.inode = inode;
+ kbuf.dptr = (char *)&key;
+ kbuf.dsize = sizeof(key);
+ return kbuf;
+}
+
+/*******************************************************************
+ Form a static locking key for a dev/inode pair for the lock ref count
+******************************************************************/
+
+static TDB_DATA locking_ref_count_key(SMB_DEV_T dev, SMB_INO_T inode)
+{
+ static struct lock_ref_count_key key;
+ TDB_DATA kbuf;
+
+ memset(&key, '\0', sizeof(key));
+ key.device = dev;
+ key.inode = inode;
+ key.r = 'r';
+ kbuf.dptr = (char *)&key;
+ kbuf.dsize = sizeof(key);
+ return kbuf;
+}
+
+/*******************************************************************
+ Convenience function to get an fd_array key from an fsp.
+******************************************************************/
+
+static TDB_DATA fd_array_key_fsp(files_struct *fsp)
+{
+ return fd_array_key(fsp->dev, fsp->inode);
+}
+
+/*******************************************************************
+ Convenience function to get a lock ref count key from an fsp.
+******************************************************************/
+
+static TDB_DATA locking_ref_count_key_fsp(files_struct *fsp)
+{
+ return locking_ref_count_key(fsp->dev, fsp->inode);
+}
+
+/*******************************************************************
+ Create the in-memory POSIX lock databases.
+********************************************************************/
+
+BOOL posix_locking_init(int read_only)
+{
+ if (posix_pending_close_tdb) {
+ return True;
+ }
+
+ if (!posix_pending_close_tdb) {
+ posix_pending_close_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL,
+ read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644);
+ }
+ if (!posix_pending_close_tdb) {
+ DEBUG(0,("Failed to open POSIX pending close database.\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ Delete the in-memory POSIX lock databases.
+********************************************************************/
+
+BOOL posix_locking_end(void)
+{
+ if (posix_pending_close_tdb && tdb_close(posix_pending_close_tdb) != 0) {
+ return False;
+ }
+ return True;
+}
+
+/****************************************************************************
+ Next - the functions that deal with storing fd's that have outstanding
+ POSIX locks when closed.
+****************************************************************************/
+
+/****************************************************************************
+ The records in posix_pending_close_tdb are composed of an array of ints
+ keyed by dev/ino pair.
+ The first int is a reference count of the number of outstanding locks on
+ all open fd's on this dev/ino pair. Any subsequent ints are the fd's that
+ were open on this dev/ino pair that should have been closed, but can't as
+ the lock ref count is non zero.
+****************************************************************************/
+
+/****************************************************************************
+ Keep a reference count of the number of Windows locks open on this dev/ino
+ pair. Creates entry if it doesn't exist.
+****************************************************************************/
+
+static void increment_windows_lock_ref_count(files_struct *fsp)
+{
+ TDB_DATA kbuf = locking_ref_count_key_fsp(fsp);
+ TDB_DATA dbuf;
+ int lock_ref_count;
+
+ dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
+ if (dbuf.dptr == NULL) {
+ dbuf.dptr = (char *)SMB_MALLOC_P(int);
+ if (!dbuf.dptr) {
+ smb_panic("increment_windows_lock_ref_count: malloc fail.\n");
+ }
+ memset(dbuf.dptr, '\0', sizeof(int));
+ dbuf.dsize = sizeof(int);
+ }
+
+ memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
+ lock_ref_count++;
+ memcpy(dbuf.dptr, &lock_ref_count, sizeof(int));
+
+ if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
+ smb_panic("increment_windows_lock_ref_count: tdb_store_fail.\n");
+ }
+ SAFE_FREE(dbuf.dptr);
+
+ DEBUG(10,("increment_windows_lock_ref_count for file now %s = %d\n",
+ fsp->fsp_name, lock_ref_count ));
+}
+
+static void decrement_windows_lock_ref_count(files_struct *fsp)
+{
+ TDB_DATA kbuf = locking_ref_count_key_fsp(fsp);
+ TDB_DATA dbuf;
+ int lock_ref_count;
+
+ dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
+ if (!dbuf.dptr) {
+ smb_panic("decrement_windows_lock_ref_count: logic error.\n");
+ }
+
+ memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
+ lock_ref_count--;
+ memcpy(dbuf.dptr, &lock_ref_count, sizeof(int));
+
+ if (lock_ref_count < 0) {
+ smb_panic("decrement_windows_lock_ref_count: lock_count logic error.\n");
+ }
+
+ if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
+ smb_panic("decrement_windows_lock_ref_count: tdb_store_fail.\n");
+ }
+ SAFE_FREE(dbuf.dptr);
+
+ DEBUG(10,("decrement_windows_lock_ref_count for file now %s = %d\n",
+ fsp->fsp_name, lock_ref_count ));
+}
+
+/****************************************************************************
+ Bulk delete - subtract as many locks as we've just deleted.
+****************************************************************************/
+
+void reduce_windows_lock_ref_count(files_struct *fsp, unsigned int dcount)
+{
+ TDB_DATA kbuf = locking_ref_count_key_fsp(fsp);
+ TDB_DATA dbuf;
+ int lock_ref_count;
+
+ dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
+ if (!dbuf.dptr) {
+ return;
+ }
+
+ memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
+ lock_ref_count -= dcount;
+
+ if (lock_ref_count < 0) {
+ smb_panic("reduce_windows_lock_ref_count: lock_count logic error.\n");
+ }
+ memcpy(dbuf.dptr, &lock_ref_count, sizeof(int));
+
+ if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
+ smb_panic("reduce_windows_lock_ref_count: tdb_store_fail.\n");
+ }
+ SAFE_FREE(dbuf.dptr);
+
+ DEBUG(10,("reduce_windows_lock_ref_count for file now %s = %d\n",
+ fsp->fsp_name, lock_ref_count ));
+}
+
+/****************************************************************************
+ Fetch the lock ref count.
+****************************************************************************/
+
+static int get_windows_lock_ref_count(files_struct *fsp)
+{
+ TDB_DATA kbuf = locking_ref_count_key_fsp(fsp);
+ TDB_DATA dbuf;
+ int lock_ref_count;
+
+ dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
+ if (!dbuf.dptr) {
+ lock_ref_count = 0;
+ } else {
+ memcpy(&lock_ref_count, dbuf.dptr, sizeof(int));
+ }
+ SAFE_FREE(dbuf.dptr);
+
+ DEBUG(10,("get_windows_lock_count for file %s = %d\n",
+ fsp->fsp_name, lock_ref_count ));
+ return lock_ref_count;
+}
+
+/****************************************************************************
+ Delete a lock_ref_count entry.
+****************************************************************************/
+
+static void delete_windows_lock_ref_count(files_struct *fsp)
+{
+ TDB_DATA kbuf = locking_ref_count_key_fsp(fsp);
+
+ /* Not a bug if it doesn't exist - no locks were ever granted. */
+ tdb_delete(posix_pending_close_tdb, kbuf);
+ DEBUG(10,("delete_windows_lock_ref_count for file %s\n", fsp->fsp_name));
+}
+
+/****************************************************************************
+ Add an fd to the pending close tdb.
+****************************************************************************/
+
+static void add_fd_to_close_entry(files_struct *fsp)
+{
+ TDB_DATA kbuf = fd_array_key_fsp(fsp);
+ TDB_DATA dbuf;
+
+ dbuf.dptr = NULL;
+ dbuf.dsize = 0;
+
+ dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
+
+ dbuf.dptr = (char *)SMB_REALLOC(dbuf.dptr, dbuf.dsize + sizeof(int));
+ if (!dbuf.dptr) {
+ smb_panic("add_fd_to_close_entry: Realloc fail !\n");
+ }
+
+ memcpy(dbuf.dptr + dbuf.dsize, &fsp->fh->fd, sizeof(int));
+ dbuf.dsize += sizeof(int);
+
+ if (tdb_store(posix_pending_close_tdb, kbuf, dbuf, TDB_REPLACE) == -1) {
+ smb_panic("add_fd_to_close_entry: tdb_store_fail.\n");
+ }
+
+ DEBUG(10,("add_fd_to_close_entry: added fd %d file %s\n",
+ fsp->fh->fd, fsp->fsp_name ));
+
+ SAFE_FREE(dbuf.dptr);
+}
+
+/****************************************************************************
+ Remove all fd entries for a specific dev/inode pair from the tdb.
+****************************************************************************/
+
+static void delete_close_entries(files_struct *fsp)
+{
+ TDB_DATA kbuf = fd_array_key_fsp(fsp);
+
+ if (tdb_delete(posix_pending_close_tdb, kbuf) == -1) {
+ smb_panic("delete_close_entries: tdb_delete fail !\n");
+ }
+}
+
+/****************************************************************************
+ Get the array of POSIX pending close records for an open fsp. Caller must
+ free. Returns number of entries.
+****************************************************************************/
+
+static size_t get_posix_pending_close_entries(files_struct *fsp, int **entries)
+{
+ TDB_DATA kbuf = fd_array_key_fsp(fsp);
+ TDB_DATA dbuf;
+ size_t count = 0;
+
+ *entries = NULL;
+ dbuf.dptr = NULL;
+
+ dbuf = tdb_fetch(posix_pending_close_tdb, kbuf);
+
+ if (!dbuf.dptr) {
+ return 0;
+ }
+
+ *entries = (int *)dbuf.dptr;
+ count = (size_t)(dbuf.dsize / sizeof(int));
+
+ return count;
+}
+
+/****************************************************************************
+ Deal with pending closes needed by POSIX locking support.
+ Note that posix_locking_close_file() is expected to have been called
+ to delete all locks on this fsp before this function is called.
+****************************************************************************/
+
+int fd_close_posix(struct connection_struct *conn, files_struct *fsp)
+{
+ int saved_errno = 0;
+ int ret;
+ int *fd_array = NULL;
+ size_t count, i;
+
+ if (!lp_locking(fsp->conn->params) || !lp_posix_locking(conn->params)) {
+ /*
+ * No locking or POSIX to worry about or we want POSIX semantics
+ * which will lose all locks on all fd's open on this dev/inode,
+ * just close.
+ */
+ ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd);
+ fsp->fh->fd = -1;
+ return ret;
+ }
+
+ if (get_windows_lock_ref_count(fsp)) {
+
+ /*
+ * There are outstanding locks on this dev/inode pair on other fds.
+ * Add our fd to the pending close tdb and set fsp->fh->fd to -1.
+ */
+
+ add_fd_to_close_entry(fsp);
+ fsp->fh->fd = -1;
+ return 0;
+ }
+
+ /*
+ * No outstanding locks. Get the pending close fd's
+ * from the tdb and close them all.
+ */
+
+ count = get_posix_pending_close_entries(fsp, &fd_array);
+
+ if (count) {
+ DEBUG(10,("fd_close_posix: doing close on %u fd's.\n", (unsigned int)count ));
+
+ for(i = 0; i < count; i++) {
+ if (SMB_VFS_CLOSE(fsp,fd_array[i]) == -1) {
+ saved_errno = errno;
+ }
+ }
+
+ /*
+ * Delete all fd's stored in the tdb
+ * for this dev/inode pair.
+ */
+
+ delete_close_entries(fsp);
+ }
+
+ SAFE_FREE(fd_array);
+
+ /* Don't need a lock ref count on this dev/ino anymore. */
+ delete_windows_lock_ref_count(fsp);
+
+ /*
+ * Finally close the fd associated with this fsp.
+ */
+
+ ret = SMB_VFS_CLOSE(fsp,fsp->fh->fd);
+
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ ret = -1;
+ }
+
+ fsp->fh->fd = -1;
+
+ return ret;
+}
+
+/****************************************************************************
+ Next - the functions that deal with the mapping CIFS Windows locks onto
+ the underlying system POSIX locks.
+****************************************************************************/
+
/*
* Structure used when splitting a lock range
* into a POSIX lock range. Doubly linked list.
@@ -792,22 +734,14 @@ struct lock_list {
understand it :-).
****************************************************************************/
-static struct lock_list *posix_lock_list(TALLOC_CTX *ctx, struct lock_list *lhead, files_struct *fsp)
+static struct lock_list *posix_lock_list(TALLOC_CTX *ctx,
+ struct lock_list *lhead,
+ const struct lock_context *lock_ctx, /* Lock context lhead belongs to. */
+ files_struct *fsp,
+ const struct lock_struct *plocks,
+ int num_locks)
{
- TDB_DATA kbuf = locking_key_fsp(fsp);
- TDB_DATA dbuf;
- struct posix_lock *locks;
- size_t num_locks, i;
-
- dbuf.dptr = NULL;
-
- dbuf = tdb_fetch(posix_lock_tdb, kbuf);
-
- if (!dbuf.dptr)
- return lhead;
-
- locks = (struct posix_lock *)dbuf.dptr;
- num_locks = (size_t)(dbuf.dsize / sizeof(struct posix_lock));
+ int i;
/*
* Check the current lock list on this dev/inode pair.
@@ -818,10 +752,19 @@ static struct lock_list *posix_lock_list(TALLOC_CTX *ctx, struct lock_list *lhea
(double)lhead->start, (double)lhead->size ));
for (i=0; i<num_locks && lhead; i++) {
-
- struct posix_lock *lock = &locks[i];
+ const struct lock_struct *lock = &plocks[i];
struct lock_list *l_curr;
+ /* Ignore all but read/write locks. */
+ if (lock->lock_type != READ_LOCK && lock->lock_type != WRITE_LOCK) {
+ continue;
+ }
+
+ /* Ignore locks not owned by this process. */
+ if (!procid_equal(&lock->context.pid, &lock_ctx->pid)) {
+ continue;
+ }
+
/*
* Walk the lock list, checking for overlaps. Note that
* the lock list can expand within this loop if the current
@@ -830,13 +773,13 @@ static struct lock_list *posix_lock_list(TALLOC_CTX *ctx, struct lock_list *lhea
for (l_curr = lhead; l_curr;) {
- DEBUG(10,("posix_lock_list: lock: fd=%d: start=%.0f,size=%.0f:type=%s", lock->fd,
+ DEBUG(10,("posix_lock_list: lock: fnum=%d: start=%.0f,size=%.0f:type=%s", lock->fnum,
(double)lock->start, (double)lock->size, posix_lock_type_name(lock->lock_type) ));
if ( (l_curr->start >= (lock->start + lock->size)) ||
(lock->start >= (l_curr->start + l_curr->size))) {
- /* No overlap with this lock - leave this range alone. */
+ /* No overlap with existing lock - leave this range alone. */
/*********************************************
+---------+
| l_curr |
@@ -850,7 +793,7 @@ OR....
+---------+
**********************************************/
- DEBUG(10,("no overlap case.\n" ));
+ DEBUG(10,(" no overlap case.\n" ));
l_curr = l_curr->next;
@@ -858,8 +801,8 @@ OR....
(l_curr->start + l_curr->size <= lock->start + lock->size) ) {
/*
- * This unlock is completely overlapped by this existing lock range
- * and thus should have no effect (not be unlocked). Delete it from the list.
+ * This range is completely overlapped by this existing lock range
+ * and thus should have no effect. Delete it from the list.
*/
/*********************************************
+---------+
@@ -872,11 +815,12 @@ OR....
/* Save the next pointer */
struct lock_list *ul_next = l_curr->next;
- DEBUG(10,("delete case.\n" ));
+ DEBUG(10,(" delete case.\n" ));
DLIST_REMOVE(lhead, l_curr);
- if(lhead == NULL)
+ if(lhead == NULL) {
break; /* No more list... */
+ }
l_curr = ul_next;
@@ -885,7 +829,7 @@ OR....
(l_curr->start + l_curr->size > lock->start + lock->size) ) {
/*
- * This unlock overlaps the existing lock range at the high end.
+ * This range overlaps the existing lock range at the high end.
* Truncate by moving start to existing range end and reducing size.
*/
/*********************************************
@@ -904,7 +848,7 @@ BECOMES....
l_curr->size = (l_curr->start + l_curr->size) - (lock->start + lock->size);
l_curr->start = lock->start + lock->size;
- DEBUG(10,("truncate high case: start=%.0f,size=%.0f\n",
+ DEBUG(10,(" truncate high case: start=%.0f,size=%.0f\n",
(double)l_curr->start, (double)l_curr->size ));
l_curr = l_curr->next;
@@ -914,7 +858,7 @@ BECOMES....
(l_curr->start + l_curr->size <= lock->start + lock->size) ) {
/*
- * This unlock overlaps the existing lock range at the low end.
+ * This range overlaps the existing lock range at the low end.
* Truncate by reducing size.
*/
/*********************************************
@@ -932,7 +876,7 @@ BECOMES....
l_curr->size = lock->start - l_curr->start;
- DEBUG(10,("truncate low case: start=%.0f,size=%.0f\n",
+ DEBUG(10,(" truncate low case: start=%.0f,size=%.0f\n",
(double)l_curr->start, (double)l_curr->size ));
l_curr = l_curr->next;
@@ -940,10 +884,10 @@ BECOMES....
} else if ( (l_curr->start < lock->start) &&
(l_curr->start + l_curr->size > lock->start + lock->size) ) {
/*
- * Worst case scenario. Unlock request completely overlaps an existing
+ * Worst case scenario. Range completely overlaps an existing
* lock range. Split the request into two, push the new (upper) request
- * into the dlink list, and continue with the entry after ul_new (as we
- * know that ul_new will not overlap with this lock).
+ * into the dlink list, and continue with the entry after l_new (as we
+ * know that l_new will not overlap with this lock).
*/
/*********************************************
+---------------------------+
@@ -971,7 +915,7 @@ BECOMES.....
/* Truncate the l_curr. */
l_curr->size = lock->start - l_curr->start;
- DEBUG(10,("split case: curr: start=%.0f,size=%.0f \
+ DEBUG(10,(" split case: curr: start=%.0f,size=%.0f \
new: start=%.0f,size=%.0f\n", (double)l_curr->start, (double)l_curr->size,
(double)l_new->start, (double)l_new->size ));
@@ -1003,34 +947,33 @@ lock: start = %.0f, size = %.0f\n", (double)l_curr->start, (double)l_curr->size,
} /* end for ( l_curr = lhead; l_curr;) */
} /* end for (i=0; i<num_locks && ul_head; i++) */
- SAFE_FREE(dbuf.dptr);
-
return lhead;
}
/****************************************************************************
POSIX function to acquire a lock. Returns True if the
lock could be granted, False if not.
- TODO -- Fix POSIX lock flavour semantics.
****************************************************************************/
-BOOL set_posix_lock(files_struct *fsp,
+BOOL set_posix_lock_windows_flavour(files_struct *fsp,
SMB_BIG_UINT u_offset,
SMB_BIG_UINT u_count,
enum brl_type lock_type,
- enum brl_flavour lock_flav)
+ const struct lock_context *lock_ctx,
+ const struct lock_struct *plocks,
+ int num_locks,
+ int *errno_ret)
{
SMB_OFF_T offset;
SMB_OFF_T count;
+ int posix_lock_type = map_posix_lock_type(fsp,lock_type);
BOOL ret = True;
- size_t entry_num = 0;
size_t lock_count;
TALLOC_CTX *l_ctx = NULL;
struct lock_list *llist = NULL;
struct lock_list *ll = NULL;
- int posix_lock_type = map_posix_lock_type(fsp,lock_type);
- DEBUG(5,("set_posix_lock: File %s, offset = %.0f, count = %.0f, type = %s\n",
+ DEBUG(5,("set_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n",
fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) ));
/*
@@ -1038,8 +981,10 @@ BOOL set_posix_lock(files_struct *fsp,
* pretend it was successful.
*/
- if(!posix_lock_in_range(&offset, &count, u_offset, u_count))
+ if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) {
+ increment_windows_lock_ref_count(fsp);
return True;
+ }
/*
* Windows is very strange. It allows read locks to be overlayed
@@ -1056,21 +1001,18 @@ BOOL set_posix_lock(files_struct *fsp,
* READ LOCK: start =0, len = 10 - OK
*
* Under POSIX, the same sequence in steps 1 and 2 would not be reference counted, but
- * would leave a single read lock over the 0-14 region. In order to
- * re-create Windows semantics mapped to POSIX locks, we create multiple TDB
- * entries, one for each overlayed lock request. We are guarenteed by the brlock
- * semantics that if a write lock is added, then it will be first in the array.
+ * would leave a single read lock over the 0-14 region.
*/
if ((l_ctx = talloc_init("set_posix_lock")) == NULL) {
- DEBUG(0,("set_posix_lock: unable to init talloc context.\n"));
- return True; /* Not a fatal error. */
+ DEBUG(0,("set_posix_lock_windows_flavour: unable to init talloc context.\n"));
+ return False;
}
if ((ll = TALLOC_P(l_ctx, struct lock_list)) == NULL) {
- DEBUG(0,("set_posix_lock: unable to talloc unlock list.\n"));
+ DEBUG(0,("set_posix_lock_windows_flavour: unable to talloc unlock list.\n"));
talloc_destroy(l_ctx);
- return True; /* Not a fatal error. */
+ return False;
}
/*
@@ -1092,19 +1034,12 @@ BOOL set_posix_lock(files_struct *fsp,
* POSIX locks.
*/
- llist = posix_lock_list(l_ctx, llist, fsp);
-
- /*
- * Now we have the list of ranges to lock it is safe to add the
- * entry into the POSIX lock tdb. We take note of the entry we
- * added here in case we have to remove it on POSIX lock fail.
- */
-
- if (!add_posix_lock_entry(fsp,offset,count,posix_lock_type,&entry_num)) {
- DEBUG(0,("set_posix_lock: Unable to create posix lock entry !\n"));
- talloc_destroy(l_ctx);
- return False;
- }
+ llist = posix_lock_list(l_ctx,
+ llist,
+ lock_ctx, /* Lock context llist belongs to. */
+ fsp,
+ plocks,
+ num_locks);
/*
* Add the POSIX locks on the list of ranges returned.
@@ -1116,11 +1051,12 @@ BOOL set_posix_lock(files_struct *fsp,
offset = ll->start;
count = ll->size;
- DEBUG(5,("set_posix_lock: Real lock: Type = %s: offset = %.0f, count = %.0f\n",
+ DEBUG(5,("set_posix_lock_windows_flavour: Real lock: Type = %s: offset = %.0f, count = %.0f\n",
posix_lock_type_name(posix_lock_type), (double)offset, (double)count ));
if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,posix_lock_type)) {
- DEBUG(5,("set_posix_lock: Lock fail !: Type = %s: offset = %.0f, count = %.0f. Errno = %s\n",
+ *errno_ret = errno;
+ DEBUG(5,("set_posix_lock_windows_flavour: Lock fail !: Type = %s: offset = %.0f, count = %.0f. Errno = %s\n",
posix_lock_type_name(posix_lock_type), (double)offset, (double)count, strerror(errno) ));
ret = False;
break;
@@ -1137,17 +1073,14 @@ BOOL set_posix_lock(files_struct *fsp,
offset = ll->start;
count = ll->size;
- DEBUG(5,("set_posix_lock: Backing out locks: Type = %s: offset = %.0f, count = %.0f\n",
+ DEBUG(5,("set_posix_lock_windows_flavour: Backing out locks: Type = %s: offset = %.0f, count = %.0f\n",
posix_lock_type_name(posix_lock_type), (double)offset, (double)count ));
posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_UNLCK);
}
-
- /*
- * Remove the tdb entry for this lock.
- */
-
- delete_posix_lock_entry_by_index(fsp,entry_num);
+ } else {
+ /* Remember the number of Windows locks we have on this dev/ino pair. */
+ increment_windows_lock_ref_count(fsp);
}
talloc_destroy(l_ctx);
@@ -1159,7 +1092,13 @@ BOOL set_posix_lock(files_struct *fsp,
lock could be released, False if not.
****************************************************************************/
-BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u_count)
+BOOL release_posix_lock_windows_flavour(files_struct *fsp,
+ SMB_BIG_UINT u_offset,
+ SMB_BIG_UINT u_count,
+ enum brl_type deleted_lock_type,
+ const struct lock_context *lock_ctx,
+ const struct lock_struct *plocks,
+ int num_locks)
{
SMB_OFF_T offset;
SMB_OFF_T count;
@@ -1167,56 +1106,31 @@ BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u
TALLOC_CTX *ul_ctx = NULL;
struct lock_list *ulist = NULL;
struct lock_list *ul = NULL;
- struct posix_lock deleted_lock;
- int num_overlapped_entries;
- DEBUG(5,("release_posix_lock: File %s, offset = %.0f, count = %.0f\n",
+ DEBUG(5,("release_posix_lock_windows_flavour: File %s, offset = %.0f, count = %.0f\n",
fsp->fsp_name, (double)u_offset, (double)u_count ));
+ /* Remember the number of Windows locks we have on this dev/ino pair. */
+ decrement_windows_lock_ref_count(fsp);
+
/*
* If the requested lock won't fit in the POSIX range, we will
* pretend it was successful.
*/
- if(!posix_lock_in_range(&offset, &count, u_offset, u_count))
+ if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) {
return True;
-
- /*
- * We treat this as one unlock request for POSIX accounting purposes even
- * if it may later be split into multiple smaller POSIX unlock ranges.
- * num_overlapped_entries is the number of existing locks that have any
- * overlap with this unlock request.
- */
-
- num_overlapped_entries = delete_posix_lock_entry(fsp, offset, count, &deleted_lock);
-
- if (num_overlapped_entries == -1) {
- smb_panic("release_posix_lock: unable find entry to delete !\n");
- }
-
- /*
- * If num_overlapped_entries is > 0, and the lock_type we just deleted from the tdb was
- * a POSIX write lock, then before doing the unlock we need to downgrade
- * the POSIX lock to a read lock. This allows any overlapping read locks
- * to be atomically maintained.
- */
-
- if (num_overlapped_entries > 0 && deleted_lock.lock_type == F_WRLCK) {
- if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_RDLCK)) {
- DEBUG(0,("release_posix_lock: downgrade of lock failed with error %s !\n", strerror(errno) ));
- return False;
- }
}
if ((ul_ctx = talloc_init("release_posix_lock")) == NULL) {
- DEBUG(0,("release_posix_lock: unable to init talloc context.\n"));
- return True; /* Not a fatal error. */
+ DEBUG(0,("release_posix_lock_windows_flavour: unable to init talloc context.\n"));
+ return False;
}
if ((ul = TALLOC_P(ul_ctx, struct lock_list)) == NULL) {
- DEBUG(0,("release_posix_lock: unable to talloc unlock list.\n"));
+ DEBUG(0,("release_posix_lock_windows_flavour: unable to talloc unlock list.\n"));
talloc_destroy(ul_ctx);
- return True; /* Not a fatal error. */
+ return False;
}
/*
@@ -1239,7 +1153,33 @@ BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u
* unlocks are performed.
*/
- ulist = posix_lock_list(ul_ctx, ulist, fsp);
+ ulist = posix_lock_list(ul_ctx,
+ ulist,
+ lock_ctx, /* Lock context ulist belongs to. */
+ fsp,
+ plocks,
+ num_locks);
+
+ /*
+ * If there were any overlapped entries (list is > 1 or size or start have changed),
+ * and the lock_type we just deleted from
+ * the upper layer tdb was a write lock, then before doing the unlock we need to downgrade
+ * the POSIX lock to a read lock. This allows any overlapping read locks
+ * to be atomically maintained.
+ */
+
+ if (deleted_lock_type == WRITE_LOCK &&
+ (!ulist || ulist->next != NULL || ulist->start != offset || ulist->size != count)) {
+
+ DEBUG(5,("release_posix_lock_windows_flavour: downgrading lock to READ: offset = %.0f, count = %.0f\n",
+ (double)offset, (double)count ));
+
+ if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_RDLCK)) {
+ DEBUG(0,("release_posix_lock_windows_flavour: downgrade of lock failed with error %s !\n", strerror(errno) ));
+ talloc_destroy(ul_ctx);
+ return False;
+ }
+ }
/*
* Release the POSIX locks on the list of ranges returned.
@@ -1249,129 +1189,148 @@ BOOL release_posix_lock(files_struct *fsp, SMB_BIG_UINT u_offset, SMB_BIG_UINT u
offset = ulist->start;
count = ulist->size;
- DEBUG(5,("release_posix_lock: Real unlock: offset = %.0f, count = %.0f\n",
+ DEBUG(5,("release_posix_lock_windows_flavour: Real unlock: offset = %.0f, count = %.0f\n",
(double)offset, (double)count ));
- if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_UNLCK))
+ if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_UNLCK)) {
ret = False;
+ }
}
talloc_destroy(ul_ctx);
-
return ret;
}
/****************************************************************************
- Remove all lock entries for a specific dev/inode pair from the tdb.
+ Next - the functions that deal with mapping CIFS POSIX locks onto
+ the underlying system POSIX locks.
****************************************************************************/
-static void delete_posix_lock_entries(files_struct *fsp)
-{
- TDB_DATA kbuf = locking_key_fsp(fsp);
-
- if (tdb_delete(posix_lock_tdb, kbuf) == -1)
- DEBUG(0,("delete_close_entries: tdb_delete fail !\n"));
-}
-
/****************************************************************************
- Debug function.
+ POSIX function to acquire a lock. Returns True if the
+ lock could be granted, False if not.
+ As POSIX locks don't stack or conflict (they just overwrite)
+ we can map the requested lock directly onto a system one. We
+ know it doesn't conflict with locks on other contexts as the
+ upper layer would have refused it.
****************************************************************************/
-static void dump_entry(struct posix_lock *pl)
+BOOL set_posix_lock_posix_flavour(files_struct *fsp,
+ SMB_BIG_UINT u_offset,
+ SMB_BIG_UINT u_count,
+ enum brl_type lock_type,
+ int *errno_ret)
{
- DEBUG(10,("entry: start=%.0f, size=%.0f, type=%d, fd=%i\n",
- (double)pl->start, (double)pl->size, (int)pl->lock_type, pl->fd ));
+ SMB_OFF_T offset;
+ SMB_OFF_T count;
+ int posix_lock_type = map_posix_lock_type(fsp,lock_type);
+
+ DEBUG(5,("set_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f, type = %s\n",
+ fsp->fsp_name, (double)u_offset, (double)u_count, posix_lock_type_name(lock_type) ));
+
+ /*
+ * If the requested lock won't fit in the POSIX range, we will
+ * pretend it was successful.
+ */
+
+ if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) {
+ return True;
+ }
+
+ if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,posix_lock_type)) {
+ *errno_ret = errno;
+ DEBUG(5,("set_posix_lock_posix_flavour: Lock fail !: Type = %s: offset = %.0f, count = %.0f. Errno = %s\n",
+ posix_lock_type_name(posix_lock_type), (double)offset, (double)count, strerror(errno) ));
+ return False;
+ }
+ return True;
}
/****************************************************************************
- Remove any locks on this fd. Called from file_close().
+ POSIX function to release a lock. Returns True if the
+ lock could be released, False if not.
+ We are given a complete lock state from the upper layer which is what the lock
+ state should be after the unlock has already been done, so what
+ we do is punch out holes in the unlock range where locks owned by this process
+ have a different lock context.
****************************************************************************/
-void posix_locking_close_file(files_struct *fsp)
+BOOL release_posix_lock_posix_flavour(files_struct *fsp,
+ SMB_BIG_UINT u_offset,
+ SMB_BIG_UINT u_count,
+ const struct lock_context *lock_ctx,
+ const struct lock_struct *plocks,
+ int num_locks)
{
- struct posix_lock *entries = NULL;
- size_t count, i;
+ BOOL ret = True;
+ SMB_OFF_T offset;
+ SMB_OFF_T count;
+ TALLOC_CTX *ul_ctx = NULL;
+ struct lock_list *ulist = NULL;
+ struct lock_list *ul = NULL;
+
+ DEBUG(5,("release_posix_lock_posix_flavour: File %s, offset = %.0f, count = %.0f\n",
+ fsp->fsp_name, (double)u_offset, (double)u_count ));
/*
- * Optimization for the common case where we are the only
- * opener of a file. If all fd entries are our own, we don't
- * need to explicitly release all the locks via the POSIX functions,
- * we can just remove all the entries in the tdb and allow the
- * close to remove the real locks.
+ * If the requested lock won't fit in the POSIX range, we will
+ * pretend it was successful.
*/
- count = get_posix_lock_entries(fsp, &entries);
-
- if (count == 0) {
- DEBUG(10,("posix_locking_close_file: file %s has no outstanding locks.\n", fsp->fsp_name ));
- return;
+ if(!posix_lock_in_range(&offset, &count, u_offset, u_count)) {
+ return True;
}
- for (i = 0; i < count; i++) {
- if (entries[i].fd != fsp->fh->fd )
- break;
-
- dump_entry(&entries[i]);
+ if ((ul_ctx = talloc_init("release_posix_lock")) == NULL) {
+ DEBUG(0,("release_posix_lock_windows_flavour: unable to init talloc context.\n"));
+ return False;
}
- if (i == count) {
- /* All locks are ours. */
- DEBUG(10,("posix_locking_close_file: file %s has %u outstanding locks, but all on one fd.\n",
- fsp->fsp_name, (unsigned int)count ));
- SAFE_FREE(entries);
- delete_posix_lock_entries(fsp);
- return;
+ if ((ul = TALLOC_P(ul_ctx, struct lock_list)) == NULL) {
+ DEBUG(0,("release_posix_lock_windows_flavour: unable to talloc unlock list.\n"));
+ talloc_destroy(ul_ctx);
+ return False;
}
/*
- * Difficult case. We need to delete all our locks, whilst leaving
- * all other POSIX locks in place.
+ * Create the initial list entry containing the
+ * lock we want to remove.
*/
- for (i = 0; i < count; i++) {
- struct posix_lock *pl = &entries[i];
- if (pl->fd == fsp->fh->fd)
- release_posix_lock(fsp, (SMB_BIG_UINT)pl->start, (SMB_BIG_UINT)pl->size );
- }
- SAFE_FREE(entries);
-}
+ ZERO_STRUCTP(ul);
+ ul->start = offset;
+ ul->size = count;
-/*******************************************************************
- Create the in-memory POSIX lock databases.
-********************************************************************/
+ DLIST_ADD(ulist, ul);
-BOOL posix_locking_init(int read_only)
-{
- if (posix_lock_tdb && posix_pending_close_tdb)
- return True;
-
- if (!posix_lock_tdb)
- posix_lock_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL,
- read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644);
- if (!posix_lock_tdb) {
- DEBUG(0,("Failed to open POSIX byte range locking database.\n"));
- return False;
- }
- if (!posix_pending_close_tdb)
- posix_pending_close_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL,
- read_only?O_RDONLY:(O_RDWR|O_CREAT), 0644);
- if (!posix_pending_close_tdb) {
- DEBUG(0,("Failed to open POSIX pending close database.\n"));
- return False;
- }
+ /*
+ * Walk the given array creating a linked list
+ * of unlock requests.
+ */
- return True;
-}
+ ulist = posix_lock_list(ul_ctx,
+ ulist,
+ lock_ctx, /* Lock context ulist belongs to. */
+ fsp,
+ plocks,
+ num_locks);
-/*******************************************************************
- Delete the in-memory POSIX lock databases.
-********************************************************************/
+ /*
+ * Release the POSIX locks on the list of ranges returned.
+ */
-BOOL posix_locking_end(void)
-{
- if (posix_lock_tdb && tdb_close(posix_lock_tdb) != 0)
- return False;
- if (posix_pending_close_tdb && tdb_close(posix_pending_close_tdb) != 0)
- return False;
- return True;
+ for(; ulist; ulist = ulist->next) {
+ offset = ulist->start;
+ count = ulist->size;
+
+ DEBUG(5,("release_posix_lock_posix_flavour: Real unlock: offset = %.0f, count = %.0f\n",
+ (double)offset, (double)count ));
+
+ if (!posix_fcntl_lock(fsp,SMB_F_SETLK,offset,count,F_UNLCK)) {
+ ret = False;
+ }
+ }
+
+ talloc_destroy(ul_ctx);
+ return ret;
}
diff --git a/source/modules/vfs_audit.c b/source/modules/vfs_audit.c
index 9f5179a47ce..b240cafd29f 100644
--- a/source/modules/vfs_audit.c
+++ b/source/modules/vfs_audit.c
@@ -29,17 +29,17 @@
/* Function prototypes */
-static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user);
-static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn);
-static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr);
-static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode);
-static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path);
-static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode);
+static int audit_connect(vfs_handle_struct *handle, const char *svc, const char *user);
+static void audit_disconnect(vfs_handle_struct *handle);
+static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr);
+static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode);
+static int audit_rmdir(vfs_handle_struct *handle, const char *path);
+static int audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode);
static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd);
-static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname);
-static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path);
-static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode);
-static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode);
+static int audit_rename(vfs_handle_struct *handle, const char *oldname, const char *newname);
+static int audit_unlink(vfs_handle_struct *handle, const char *path);
+static int audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode);
+static int audit_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode);
static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
@@ -120,7 +120,7 @@ static int audit_syslog_priority(vfs_handle_struct *handle)
/* Implementation of vfs_ops. Pass everything on to the default
operation but log event first. */
-static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user)
+static int audit_connect(vfs_handle_struct *handle, const char *svc, const char *user)
{
int result;
@@ -129,24 +129,24 @@ static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, con
syslog(audit_syslog_priority(handle), "connect to service %s by user %s\n",
svc, user);
- result = SMB_VFS_NEXT_CONNECT(handle, conn, svc, user);
+ result = SMB_VFS_NEXT_CONNECT(handle, svc, user);
return result;
}
-static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn)
+static void audit_disconnect(vfs_handle_struct *handle)
{
syslog(audit_syslog_priority(handle), "disconnected\n");
- SMB_VFS_NEXT_DISCONNECT(handle, conn);
+ SMB_VFS_NEXT_DISCONNECT(handle);
return;
}
-static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr)
+static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
{
SMB_STRUCT_DIR *result;
- result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr);
+ result = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
syslog(audit_syslog_priority(handle), "opendir %s %s%s\n",
fname,
@@ -156,11 +156,11 @@ static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, connection_struc
return result;
}
-static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
+static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_MKDIR(handle, conn, path, mode);
+ result = SMB_VFS_NEXT_MKDIR(handle, path, mode);
syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n",
path,
@@ -170,11 +170,11 @@ static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const
return result;
}
-static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
+static int audit_rmdir(vfs_handle_struct *handle, const char *path)
{
int result;
- result = SMB_VFS_NEXT_RMDIR(handle, conn, path);
+ result = SMB_VFS_NEXT_RMDIR(handle, path);
syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n",
path,
@@ -184,11 +184,11 @@ static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const
return result;
}
-static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
+static int audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode);
+ result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n",
fname, result,
@@ -213,11 +213,11 @@ static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
return result;
}
-static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname)
+static int audit_rename(vfs_handle_struct *handle, const char *oldname, const char *newname)
{
int result;
- result = SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname);
+ result = SMB_VFS_NEXT_RENAME(handle, oldname, newname);
syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n",
oldname, newname,
@@ -227,11 +227,11 @@ static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, cons
return result;
}
-static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
+static int audit_unlink(vfs_handle_struct *handle, const char *path)
{
int result;
- result = SMB_VFS_NEXT_UNLINK(handle, conn, path);
+ result = SMB_VFS_NEXT_UNLINK(handle, path);
syslog(audit_syslog_priority(handle), "unlink %s %s%s\n",
path,
@@ -241,11 +241,11 @@ static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, cons
return result;
}
-static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
+static int audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode);
+ result = SMB_VFS_NEXT_CHMOD(handle, path, mode);
syslog(audit_syslog_priority(handle), "chmod %s mode 0x%x %s%s\n",
path, mode,
@@ -255,11 +255,11 @@ static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const
return result;
}
-static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
+static int audit_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_CHMOD_ACL(handle, conn, path, mode);
+ result = SMB_VFS_NEXT_CHMOD_ACL(handle, path, mode);
syslog(audit_syslog_priority(handle), "chmod_acl %s mode 0x%x %s%s\n",
path, mode,
diff --git a/source/modules/vfs_cacheprime.c b/source/modules/vfs_cacheprime.c
new file mode 100644
index 00000000000..196441c4dda
--- /dev/null
+++ b/source/modules/vfs_cacheprime.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) James Peach 2005-2006
+ *
+ * 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"
+
+/* Cache priming module.
+ *
+ * The purpose of this module is to do RAID stripe width reads to prime the
+ * buffer cache to do zero-copy I/O for subsequent sendfile calls. The idea is
+ * to do a single large read at the start of the file to make sure that most or
+ * all of the file is pulled into the buffer cache. Subsequent I/Os have
+ * reduced latency.
+ *
+ * Tunables.
+ *
+ * cacheprime:rsize Amount of readahead in bytes. This should be a
+ * multiple of the RAID stripe width.
+ * cacheprime:debug Debug level at which to emit messages.
+ */
+
+#define READAHEAD_MIN (128 * 1024) /* min is 128 KiB */
+#define READAHEAD_MAX (100 * 1024 * 1024) /* max is 100 MiB */
+
+#define MODULE "cacheprime"
+
+static int module_debug;
+static ssize_t g_readsz = 0;
+static void * g_readbuf = NULL;
+
+/* Prime the kernel buffer cache with data from the specified file. We use
+ * per-fsp data to make sure we only ever do this once. If pread is being
+ * emulated by seek/read/seek, when this will suck quite a lot.
+ */
+static BOOL prime_cache(
+ struct vfs_handle_struct * handle,
+ files_struct * fsp,
+ int fd,
+ SMB_OFF_T offset,
+ size_t count)
+{
+ SMB_OFF_T * last;
+ ssize_t nread;
+
+ last = VFS_ADD_FSP_EXTENSION(handle, fsp, SMB_OFF_T);
+ if (!last) {
+ return False;
+ }
+
+ if (*last == -1) {
+ /* Readahead disabled. */
+ return False;
+ }
+
+ if ((*last + g_readsz) > (offset + count)) {
+ /* Skip readahead ... we've already been here. */
+ return False;
+ }
+
+ DEBUG(module_debug,
+ ("%s: doing readahead of %lld bytes at %lld for %s\n",
+ MODULE, (long long)g_readsz, (long long)*last,
+ fsp->fsp_name));
+
+ nread = sys_pread(fd, g_readbuf, g_readsz, *last);
+ if (nread < 0) {
+ *last = -1;
+ return False;
+ }
+
+ *last += nread;
+ return True;
+}
+
+static int cprime_connect(
+ struct vfs_handle_struct * handle,
+ const char * service,
+ const char * user)
+{
+ module_debug = lp_parm_int(SNUM(handle->conn), MODULE, "debug", 100);
+ if (g_readbuf) {
+ /* Only allocate g_readbuf once. If the config changes and
+ * another client multiplexes onto this smbd, we don't want
+ * to risk memory corruption.
+ */
+ return SMB_VFS_NEXT_CONNECT(handle, service, user);
+ }
+
+ g_readsz = conv_str_size(lp_parm_const_string(SNUM(handle->conn),
+ MODULE, "rsize", NULL));
+
+ if (g_readsz < READAHEAD_MIN) {
+ DEBUG(module_debug, ("%s: %ld bytes of readahead "
+ "requested, using minimum of %u\n",
+ MODULE, (long)g_readsz, READAHEAD_MIN));
+ g_readsz = READAHEAD_MIN;
+ } else if (g_readsz > READAHEAD_MAX) {
+ DEBUG(module_debug, ("%s: %ld bytes of readahead "
+ "requested, using maximum of %u\n",
+ MODULE, (long)g_readsz, READAHEAD_MAX));
+ g_readsz = READAHEAD_MAX;
+ }
+
+ if ((g_readbuf = SMB_MALLOC(g_readsz)) == NULL) {
+ /* Turn off readahead if we can't get a buffer. */
+ g_readsz = 0;
+ }
+
+ return SMB_VFS_NEXT_CONNECT(handle, service, user);
+}
+
+static ssize_t cprime_sendfile(
+ struct vfs_handle_struct * handle,
+ int tofd,
+ files_struct * fsp,
+ int fromfd,
+ const DATA_BLOB * header,
+ SMB_OFF_T offset,
+ size_t count)
+{
+ if (g_readbuf && offset == 0) {
+ prime_cache(handle, fsp, fromfd, offset, count);
+ }
+
+ return SMB_VFS_NEXT_SENDFILE(handle, tofd, fsp, fromfd,
+ header, offset, count);
+}
+
+static ssize_t cprime_read(
+ vfs_handle_struct * handle,
+ files_struct * fsp,
+ int fd,
+ void * data,
+ size_t count)
+{
+ SMB_OFF_T offset;
+
+ offset = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
+ if (offset >= 0 && g_readbuf) {
+ prime_cache(handle, fsp, fd, offset, count);
+ SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET);
+ }
+
+ return SMB_VFS_NEXT_READ(handle, fsp, fd, data, count);
+}
+
+static ssize_t cprime_pread(
+ vfs_handle_struct * handle,
+ files_struct * fsp,
+ int fd,
+ void * data,
+ size_t count,
+ SMB_OFF_T offset)
+{
+ if (g_readbuf) {
+ prime_cache(handle, fsp, fd, offset, count);
+ }
+
+ return SMB_VFS_NEXT_PREAD(handle, fsp, fd, data, count, offset);
+}
+
+static vfs_op_tuple cprime_ops [] =
+{
+ {SMB_VFS_OP(cprime_sendfile),
+ SMB_VFS_OP_SENDFILE, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(cprime_pread),
+ SMB_VFS_OP_PREAD, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(cprime_read),
+ SMB_VFS_OP_READ, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(cprime_connect),
+ SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
+
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+};
+
+/* -------------------------------------------------------------------------
+ * Samba module initialisation entry point.
+ * -------------------------------------------------------------------------
+ */
+
+NTSTATUS vfs_cacheprime_init(void)
+{
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, MODULE, cprime_ops);
+}
+
+/* vim: set sw=4 ts=4 tw=79 et: */
diff --git a/source/modules/vfs_cap.c b/source/modules/vfs_cap.c
index b1bfcd75f2f..c4539ca34a8 100644
--- a/source/modules/vfs_cap.c
+++ b/source/modules/vfs_cap.c
@@ -28,28 +28,28 @@
static char *capencode(char *to, const char *from);
static char *capdecode(char *to, const char *from);
-static SMB_BIG_UINT cap_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path,
+static SMB_BIG_UINT cap_disk_free(vfs_handle_struct *handle, const char *path,
BOOL small_query, SMB_BIG_UINT *bsize,
SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
pstring cappath;
capencode(cappath, path);
- return SMB_VFS_NEXT_DISK_FREE(handle, conn, cappath, small_query, bsize,
+ return SMB_VFS_NEXT_DISK_FREE(handle, cappath, small_query, bsize,
dfree, dsize);
}
-static SMB_STRUCT_DIR *cap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr)
+static SMB_STRUCT_DIR *cap_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
{
pstring capname;
capencode(capname, fname);
- return SMB_VFS_NEXT_OPENDIR(handle, conn, capname, mask, attr);
+ return SMB_VFS_NEXT_OPENDIR(handle, capname, mask, attr);
}
-static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp)
+static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
{
SMB_STRUCT_DIRENT *result;
DEBUG(3,("cap: cap_readdir\n"));
- result = SMB_VFS_NEXT_READDIR(handle, conn, dirp);
+ result = SMB_VFS_NEXT_READDIR(handle, dirp);
if (result) {
DEBUG(3,("cap: cap_readdir: %s\n", result->d_name));
capdecode(result->d_name, result->d_name);
@@ -57,134 +57,134 @@ static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, connection_stru
return result;
}
-static int cap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
+static int cap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode)
{
pstring cappath;
capencode(cappath, path);
- return SMB_VFS_NEXT_MKDIR(handle, conn, cappath, mode);
+ return SMB_VFS_NEXT_MKDIR(handle, cappath, mode);
}
-static int cap_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
+static int cap_rmdir(vfs_handle_struct *handle, const char *path)
{
pstring cappath;
capencode(cappath, path);
- return SMB_VFS_NEXT_RMDIR(handle, conn, cappath);
+ return SMB_VFS_NEXT_RMDIR(handle, cappath);
}
-static int cap_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
+static int cap_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode)
{
pstring capname;
DEBUG(3,("cap: cap_open for %s\n", fname));
capencode(capname, fname);
- return SMB_VFS_NEXT_OPEN(handle, conn, capname, flags, mode);
+ return SMB_VFS_NEXT_OPEN(handle, capname, fsp, flags, mode);
}
-static int cap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname)
+static int cap_rename(vfs_handle_struct *handle, const char *oldname, const char *newname)
{
pstring capold, capnew;
capencode(capold, oldname);
capencode(capnew, newname);
- return SMB_VFS_NEXT_RENAME(handle, conn, capold, capnew);
+ return SMB_VFS_NEXT_RENAME(handle, capold, capnew);
}
-static int cap_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
+static int cap_stat(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf)
{
pstring capname;
capencode(capname, fname);
- return SMB_VFS_NEXT_STAT(handle, conn, capname, sbuf);
+ return SMB_VFS_NEXT_STAT(handle, capname, sbuf);
}
-static int cap_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
+static int cap_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf)
{
pstring cappath;
capencode(cappath, path);
- return SMB_VFS_NEXT_LSTAT(handle, conn, cappath, sbuf);
+ return SMB_VFS_NEXT_LSTAT(handle, cappath, sbuf);
}
-static int cap_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
+static int cap_unlink(vfs_handle_struct *handle, const char *path)
{
pstring cappath;
capencode(cappath, path);
- return SMB_VFS_NEXT_UNLINK(handle, conn, cappath);
+ return SMB_VFS_NEXT_UNLINK(handle, cappath);
}
-static int cap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
+static int cap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
{
pstring cappath;
capencode(cappath, path);
- return SMB_VFS_NEXT_CHMOD(handle, conn, cappath, mode);
+ return SMB_VFS_NEXT_CHMOD(handle, cappath, mode);
}
-static int cap_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid)
+static int cap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
{
pstring cappath;
capencode(cappath, path);
- return SMB_VFS_NEXT_CHOWN(handle, conn, cappath, uid, gid);
+ return SMB_VFS_NEXT_CHOWN(handle, cappath, uid, gid);
}
-static int cap_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
+static int cap_chdir(vfs_handle_struct *handle, const char *path)
{
pstring cappath;
DEBUG(3,("cap: cap_chdir for %s\n", path));
capencode(cappath, path);
- return SMB_VFS_NEXT_CHDIR(handle, conn, cappath);
+ return SMB_VFS_NEXT_CHDIR(handle, cappath);
}
-static int cap_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times)
+static int cap_utime(vfs_handle_struct *handle, const char *path, struct utimbuf *times)
{
pstring cappath;
capencode(cappath, path);
- return SMB_VFS_NEXT_UTIME(handle, conn, cappath, times);
+ return SMB_VFS_NEXT_UTIME(handle, cappath, times);
}
-static BOOL cap_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
+static BOOL cap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
{
pstring capoldpath, capnewpath;
capencode(capoldpath, oldpath);
capencode(capnewpath, newpath);
- return SMB_VFS_NEXT_SYMLINK(handle, conn, capoldpath, capnewpath);
+ return SMB_VFS_NEXT_SYMLINK(handle, capoldpath, capnewpath);
}
-static BOOL cap_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz)
+static BOOL cap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
{
pstring cappath;
capencode(cappath, path);
- return SMB_VFS_NEXT_READLINK(handle, conn, cappath, buf, bufsiz);
+ return SMB_VFS_NEXT_READLINK(handle, cappath, buf, bufsiz);
}
-static int cap_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
+static int cap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
{
pstring capoldpath, capnewpath;
capencode(capoldpath, oldpath);
capencode(capnewpath, newpath);
- return SMB_VFS_NEXT_LINK(handle, conn, capoldpath, capnewpath);
+ return SMB_VFS_NEXT_LINK(handle, capoldpath, capnewpath);
}
-static int cap_mknod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode, SMB_DEV_T dev)
+static int cap_mknod(vfs_handle_struct *handle, const char *path, mode_t mode, SMB_DEV_T dev)
{
pstring cappath;
capencode(cappath, path);
- return SMB_VFS_NEXT_MKNOD(handle, conn, cappath, mode, dev);
+ return SMB_VFS_NEXT_MKNOD(handle, cappath, mode, dev);
}
-static char *cap_realpath(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *resolved_path)
+static char *cap_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path)
{
/* monyo need capencode'ed and capdecode'ed? */
pstring cappath;
capencode(cappath, path);
- return SMB_VFS_NEXT_REALPATH(handle, conn, path, resolved_path);
+ return SMB_VFS_NEXT_REALPATH(handle, path, resolved_path);
}
-static BOOL cap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd)
+static BOOL cap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor *psd)
{
pstring capname;
capencode(capname, name);
return SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, capname, security_info_sent, psd);
}
-static int cap_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode)
+static int cap_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode)
{
pstring capname;
capencode(capname, name);
@@ -194,45 +194,45 @@ static int cap_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, con
errno = ENOSYS;
return -1;
}
- return SMB_VFS_NEXT_CHMOD_ACL(handle, conn, capname, mode);
+ return SMB_VFS_NEXT_CHMOD_ACL(handle, capname, mode);
}
-static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle, connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type)
+static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type)
{
pstring cappath_p;
capencode(cappath_p, path_p);
- return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, conn, cappath_p, type);
+ return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, cappath_p, type);
}
-static int cap_sys_acl_set_file(vfs_handle_struct *handle, connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+static int cap_sys_acl_set_file(vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
{
pstring capname;
capencode(capname, name);
- return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, conn, capname, acltype, theacl);
+ return SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, capname, acltype, theacl);
}
-static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle, connection_struct *conn, const char *path)
+static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path)
{
pstring cappath;
capencode(cappath, path);
- return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, conn, cappath);
+ return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, cappath);
}
-static ssize_t cap_getxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, void *value, size_t size)
+static ssize_t cap_getxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t size)
{
pstring cappath, capname;
capencode(cappath, path);
capencode(capname, name);
- return SMB_VFS_NEXT_GETXATTR(handle, conn, cappath, capname, value, size);
+ return SMB_VFS_NEXT_GETXATTR(handle, cappath, capname, value, size);
}
-static ssize_t cap_lgetxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, void *value, size_t
+static ssize_t cap_lgetxattr(vfs_handle_struct *handle, const char *path, const char *name, void *value, size_t
size)
{
pstring cappath, capname;
capencode(cappath, path);
capencode(capname, name);
- return SMB_VFS_NEXT_LGETXATTR(handle, conn, cappath, capname, value, size);
+ return SMB_VFS_NEXT_LGETXATTR(handle, cappath, capname, value, size);
}
static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size)
@@ -242,34 +242,34 @@ static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp
return SMB_VFS_NEXT_FGETXATTR(handle, fsp, fd, capname, value, size);
}
-static ssize_t cap_listxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
+static ssize_t cap_listxattr(vfs_handle_struct *handle, const char *path, char *list, size_t size)
{
pstring cappath;
capencode(cappath, path);
- return SMB_VFS_NEXT_LISTXATTR(handle, conn, cappath, list, size);
+ return SMB_VFS_NEXT_LISTXATTR(handle, cappath, list, size);
}
-static ssize_t cap_llistxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
+static ssize_t cap_llistxattr(vfs_handle_struct *handle, const char *path, char *list, size_t size)
{
pstring cappath;
capencode(cappath, path);
- return SMB_VFS_NEXT_LLISTXATTR(handle, conn, cappath, list, size);
+ return SMB_VFS_NEXT_LLISTXATTR(handle, cappath, list, size);
}
-static int cap_removexattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
+static int cap_removexattr(vfs_handle_struct *handle, const char *path, const char *name)
{
pstring cappath, capname;
capencode(cappath, path);
capencode(capname, name);
- return SMB_VFS_NEXT_REMOVEXATTR(handle, conn, cappath, capname);
+ return SMB_VFS_NEXT_REMOVEXATTR(handle, cappath, capname);
}
-static int cap_lremovexattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
+static int cap_lremovexattr(vfs_handle_struct *handle, const char *path, const char *name)
{
pstring cappath, capname;
capencode(cappath, path);
capencode(capname, name);
- return SMB_VFS_NEXT_LREMOVEXATTR(handle, conn, cappath, capname);
+ return SMB_VFS_NEXT_LREMOVEXATTR(handle, cappath, capname);
}
static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name)
@@ -279,20 +279,20 @@ static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp,
return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, fd, capname);
}
-static int cap_setxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
+static int cap_setxattr(vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
{
pstring cappath, capname;
capencode(cappath, path);
capencode(capname, name);
- return SMB_VFS_NEXT_SETXATTR(handle, conn, cappath, capname, value, size, flags);
+ return SMB_VFS_NEXT_SETXATTR(handle, cappath, capname, value, size, flags);
}
-static int cap_lsetxattr(vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
+static int cap_lsetxattr(vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
{
pstring cappath, capname;
capencode(cappath, path);
capencode(capname, name);
- return SMB_VFS_NEXT_LSETXATTR(handle, conn, cappath, capname, value, size, flags);
+ return SMB_VFS_NEXT_LSETXATTR(handle, cappath, capname, value, size, flags);
}
static int cap_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags)
diff --git a/source/modules/vfs_catia.c b/source/modules/vfs_catia.c
index 69735de3f43..ccf637c3bcf 100644
--- a/source/modules/vfs_catia.c
+++ b/source/modules/vfs_catia.c
@@ -71,20 +71,20 @@ static void to_unix(char *s)
catia_string_replace(s, '\xb1', ' ');
}
-static SMB_STRUCT_DIR *catia_opendir(vfs_handle_struct *handle, connection_struct
- *conn, const char *fname, const char *mask, uint32 attr)
+static SMB_STRUCT_DIR *catia_opendir(vfs_handle_struct *handle,
+ const char *fname, const char *mask, uint32 attr)
{
pstring name;
pstrcpy(name, fname);
to_unix(name);
- return SMB_VFS_NEXT_OPENDIR(handle, conn, name, mask, attr);
+ return SMB_VFS_NEXT_OPENDIR(handle, name, mask, attr);
}
static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle,
- connection_struct *conn, SMB_STRUCT_DIR *dirp)
+ SMB_STRUCT_DIR *dirp)
{
- SMB_STRUCT_DIRENT *result = SMB_VFS_NEXT_READDIR(handle, conn, dirp);
+ SMB_STRUCT_DIRENT *result = SMB_VFS_NEXT_READDIR(handle, dirp);
if (result == NULL)
return result;
@@ -93,18 +93,18 @@ static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle,
return result;
}
-static int catia_open(vfs_handle_struct *handle, connection_struct *conn,
- const char *fname, int flags, mode_t mode)
+static int catia_open(vfs_handle_struct *handle,
+ const char *fname, files_struct *fsp, int flags, mode_t mode)
{
pstring name;
pstrcpy(name, fname);
to_unix(name);
- return SMB_VFS_NEXT_OPEN(handle, conn, name, flags, mode);
+ return SMB_VFS_NEXT_OPEN(handle, name, fsp, flags, mode);
}
-static int catia_rename(vfs_handle_struct *handle, connection_struct *conn,
+static int catia_rename(vfs_handle_struct *handle,
const char *oldname, const char *newname)
{
pstring oname, nname;
@@ -117,114 +117,112 @@ static int catia_rename(vfs_handle_struct *handle, connection_struct *conn,
DEBUG(10, ("converted old name: %s\n", oname));
DEBUG(10, ("converted new name: %s\n", nname));
- return SMB_VFS_NEXT_RENAME(handle, conn, oname, nname);
+ return SMB_VFS_NEXT_RENAME(handle, oname, nname);
}
-static int catia_stat(vfs_handle_struct *handle, connection_struct *conn,
+static int catia_stat(vfs_handle_struct *handle,
const char *fname, SMB_STRUCT_STAT *sbuf)
{
pstring name;
pstrcpy(name, fname);
to_unix(name);
- return SMB_VFS_NEXT_STAT(handle, conn, name, sbuf);
+ return SMB_VFS_NEXT_STAT(handle, name, sbuf);
}
-static int catia_lstat(vfs_handle_struct *handle, connection_struct *conn,
+static int catia_lstat(vfs_handle_struct *handle,
const char *path, SMB_STRUCT_STAT *sbuf)
{
pstring name;
pstrcpy(name, path);
to_unix(name);
- return SMB_VFS_NEXT_LSTAT(handle, conn, name, sbuf);
+ return SMB_VFS_NEXT_LSTAT(handle, name, sbuf);
}
-static int catia_unlink(vfs_handle_struct *handle, connection_struct *conn,
- const char *path)
+static int catia_unlink(vfs_handle_struct *handle, const char *path)
{
pstring name;
pstrcpy(name, path);
to_unix(name);
- return SMB_VFS_NEXT_UNLINK(handle, conn, name);
+ return SMB_VFS_NEXT_UNLINK(handle, name);
}
-static int catia_chmod(vfs_handle_struct *handle, connection_struct *conn,
+static int catia_chmod(vfs_handle_struct *handle,
const char *path, mode_t mode)
{
pstring name;
pstrcpy(name, path);
to_unix(name);
- return SMB_VFS_NEXT_CHMOD(handle, conn, name, mode);
+ return SMB_VFS_NEXT_CHMOD(handle, name, mode);
}
-static int catia_chown(vfs_handle_struct *handle, connection_struct *conn,
+static int catia_chown(vfs_handle_struct *handle,
const char *path, uid_t uid, gid_t gid)
{
pstring name;
pstrcpy(name, path);
to_unix(name);
- return SMB_VFS_NEXT_CHOWN(handle, conn, name, uid, gid);
+ return SMB_VFS_NEXT_CHOWN(handle, name, uid, gid);
}
-static int catia_chdir(vfs_handle_struct *handle, connection_struct *conn,
+static int catia_chdir(vfs_handle_struct *handle,
const char *path)
{
pstring name;
pstrcpy(name, path);
to_unix(name);
- return SMB_VFS_NEXT_CHDIR(handle, conn, name);
+ return SMB_VFS_NEXT_CHDIR(handle, name);
}
-static char *catia_getwd(vfs_handle_struct *handle, connection_struct *conn,
- char *buf)
+static char *catia_getwd(vfs_handle_struct *handle, char *buf)
{
- return SMB_VFS_NEXT_GETWD(handle, conn, buf);
+ return SMB_VFS_NEXT_GETWD(handle, buf);
}
-static int catia_utime(vfs_handle_struct *handle, connection_struct *conn,
+static int catia_utime(vfs_handle_struct *handle,
const char *path, struct utimbuf *times)
{
- return SMB_VFS_NEXT_UTIME(handle, conn, path, times);
+ return SMB_VFS_NEXT_UTIME(handle, path, times);
}
-static BOOL catia_symlink(vfs_handle_struct *handle, connection_struct *conn,
+static BOOL catia_symlink(vfs_handle_struct *handle,
const char *oldpath, const char *newpath)
{
- return SMB_VFS_NEXT_SYMLINK(handle, conn, oldpath, newpath);
+ return SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
}
-static BOOL catia_readlink(vfs_handle_struct *handle, connection_struct *conn,
+static BOOL catia_readlink(vfs_handle_struct *handle,
const char *path, char *buf, size_t bufsiz)
{
- return SMB_VFS_NEXT_READLINK(handle, conn, path, buf, bufsiz);
+ return SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz);
}
-static int catia_link(vfs_handle_struct *handle, connection_struct *conn,
+static int catia_link(vfs_handle_struct *handle,
const char *oldpath, const char *newpath)
{
- return SMB_VFS_NEXT_LINK(handle, conn, oldpath, newpath);
+ return SMB_VFS_NEXT_LINK(handle, oldpath, newpath);
}
-static int catia_mknod(vfs_handle_struct *handle, connection_struct *conn,
+static int catia_mknod(vfs_handle_struct *handle,
const char *path, mode_t mode, SMB_DEV_T dev)
{
- return SMB_VFS_NEXT_MKNOD(handle, conn, path, mode, dev);
+ return SMB_VFS_NEXT_MKNOD(handle, path, mode, dev);
}
-static char *catia_realpath(vfs_handle_struct *handle, connection_struct *conn,
+static char *catia_realpath(vfs_handle_struct *handle,
const char *path, char *resolved_path)
{
- return SMB_VFS_NEXT_REALPATH(handle, conn, path, resolved_path);
+ return SMB_VFS_NEXT_REALPATH(handle, path, resolved_path);
}
static size_t catia_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
const char *name, uint32 security_info,
- struct security_descriptor_info **ppdesc)
+ struct security_descriptor **ppdesc)
{
return SMB_VFS_NEXT_GET_NT_ACL(handle, fsp, name, security_info,
ppdesc);
@@ -232,13 +230,13 @@ static size_t catia_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
static BOOL catia_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
const char *name, uint32 security_info_sent,
- struct security_descriptor_info *psd)
+ struct security_descriptor *psd)
{
return SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, name, security_info_sent,
psd);
}
-static int catia_chmod_acl(vfs_handle_struct *handle, connection_struct *conn,
+static int catia_chmod_acl(vfs_handle_struct *handle,
const char *name, mode_t mode)
{
/* If the underlying VFS doesn't have ACL support... */
@@ -246,7 +244,7 @@ static int catia_chmod_acl(vfs_handle_struct *handle, connection_struct *conn,
errno = ENOSYS;
return -1;
}
- return SMB_VFS_NEXT_CHMOD_ACL(handle, conn, name, mode);
+ return SMB_VFS_NEXT_CHMOD_ACL(handle, name, mode);
}
/* VFS operations structure */
@@ -310,7 +308,7 @@ SMB_VFS_LAYER_TRANSPARENT},
SMB_VFS_LAYER_NOOP}
};
-NTSTATUS init_module(void)
+NTSTATUS vfs_catia_init(void)
{
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "catia",
catia_op_tuples);
diff --git a/source/modules/vfs_commit.c b/source/modules/vfs_commit.c
new file mode 100644
index 00000000000..9d817c017d2
--- /dev/null
+++ b/source/modules/vfs_commit.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) James Peach 2006
+ *
+ * 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"
+
+/* Commit data module.
+ *
+ * The purpose of this module is to flush data to disk at regular intervals,
+ * just like the NFS commit operation. There's two rationales for this. First,
+ * it minimises the data loss in case of a power outage without incurring
+ * the poor performance of synchronous I/O. Second, a steady flush rate
+ * can produce better throughput than suddenly dumping massive amounts of
+ * writes onto a disk.
+ *
+ * Tunables:
+ *
+ * commit: dthresh Amount of dirty data that can accumulate
+ * before we commit (sync) it.
+ *
+ * commit: debug Debug level at which to emit messages.
+ *
+ */
+
+#define MODULE "commit"
+
+static int module_debug;
+
+struct commit_info
+{
+ SMB_OFF_T dbytes; /* Dirty (uncommitted) bytes */
+ SMB_OFF_T dthresh; /* Dirty data threshold */
+};
+
+static void commit_all(
+ struct vfs_handle_struct * handle,
+ files_struct * fsp)
+{
+ struct commit_info *c;
+
+ if ((c = VFS_FETCH_FSP_EXTENSION(handle, fsp))) {
+ if (c->dbytes) {
+ DEBUG(module_debug,
+ ("%s: flushing %lu dirty bytes\n",
+ MODULE, (unsigned long)c->dbytes));
+
+ fdatasync(fsp->fh->fd);
+ c->dbytes = 0;
+ }
+ }
+}
+
+static void commit(
+ struct vfs_handle_struct * handle,
+ files_struct * fsp,
+ ssize_t last_write)
+{
+ struct commit_info *c;
+
+ if ((c = VFS_FETCH_FSP_EXTENSION(handle, fsp))) {
+
+ if (last_write > 0) {
+ c->dbytes += last_write;
+ }
+
+ if (c->dbytes > c->dthresh) {
+ DEBUG(module_debug,
+ ("%s: flushing %lu dirty bytes\n",
+ MODULE, (unsigned long)c->dbytes));
+
+ fdatasync(fsp->fh->fd);
+ c->dbytes = 0;
+ }
+ }
+}
+
+static int commit_connect(
+ struct vfs_handle_struct * handle,
+ const char * service,
+ const char * user)
+{
+ module_debug = lp_parm_int(SNUM(handle->conn), MODULE, "debug", 100);
+ return SMB_VFS_NEXT_CONNECT(handle, service, user);
+}
+
+static int commit_open(
+ vfs_handle_struct * handle,
+ const char * fname,
+ files_struct * fsp,
+ int flags,
+ mode_t mode)
+{
+ SMB_OFF_T dthresh;
+
+ /* Don't bother with read-only files. */
+ if ((flags & O_ACCMODE) == O_RDONLY) {
+ return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ }
+
+ dthresh = conv_str_size(lp_parm_const_string(SNUM(handle->conn),
+ MODULE, "dthresh", NULL));
+
+ if (dthresh > 0) {
+ struct commit_info * c;
+ c = VFS_ADD_FSP_EXTENSION(handle, fsp, struct commit_info);
+ if (c) {
+ c->dthresh = dthresh;
+ c->dbytes = 0;
+ }
+ }
+
+ return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+}
+
+static ssize_t commit_write(
+ vfs_handle_struct * handle,
+ files_struct * fsp,
+ int fd,
+ void * data,
+ size_t count)
+{
+ ssize_t ret;
+
+ ret = SMB_VFS_NEXT_WRITE(handle, fsp, fd, data, count);
+ commit(handle, fsp, ret);
+
+ return ret;
+}
+
+static ssize_t commit_pwrite(
+ vfs_handle_struct * handle,
+ files_struct * fsp,
+ int fd,
+ void * data,
+ size_t count,
+ SMB_OFF_T offset)
+{
+ ssize_t ret;
+
+ ret = SMB_VFS_NEXT_PWRITE(handle, fsp, fd, data, count, offset);
+ commit(handle, fsp, ret);
+
+ return ret;
+}
+
+static ssize_t commit_close(
+ vfs_handle_struct * handle,
+ files_struct * fsp,
+ int fd)
+{
+ commit_all(handle, fsp);
+ return SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
+}
+
+static vfs_op_tuple commit_ops [] =
+{
+ {SMB_VFS_OP(commit_open),
+ SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(commit_close),
+ SMB_VFS_OP_CLOSE, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(commit_write),
+ SMB_VFS_OP_WRITE, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(commit_pwrite),
+ SMB_VFS_OP_PWRITE, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(commit_connect),
+ SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
+
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS vfs_commit_init(void)
+{
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, MODULE, commit_ops);
+}
+
diff --git a/source/modules/vfs_default.c b/source/modules/vfs_default.c
new file mode 100644
index 00000000000..486a76ac88a
--- /dev/null
+++ b/source/modules/vfs_default.c
@@ -0,0 +1,1338 @@
+/*
+ Unix SMB/CIFS implementation.
+ Wrap disk only vfs functions to sidestep dodgy compilers.
+ Copyright (C) Tim Potter 1998
+
+ 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"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
+
+/* Check for NULL pointer parameters in vfswrap_* functions */
+
+/* We don't want to have NULL function pointers lying around. Someone
+ is sure to try and execute them. These stubs are used to prevent
+ this possibility. */
+
+static int vfswrap_connect(vfs_handle_struct *handle, const char *service, const char *user)
+{
+ return 0; /* Return >= 0 for success */
+}
+
+static void vfswrap_disconnect(vfs_handle_struct *handle)
+{
+}
+
+/* Disk operations */
+
+static SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, const char *path, BOOL small_query, SMB_BIG_UINT *bsize,
+ SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
+{
+ SMB_BIG_UINT result;
+
+ result = sys_disk_free(handle->conn, path, small_query, bsize, dfree, dsize);
+ return result;
+}
+
+static int vfswrap_get_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
+{
+#ifdef HAVE_SYS_QUOTAS
+ int result;
+
+ START_PROFILE(syscall_get_quota);
+ result = sys_get_quota(handle->conn->connectpath, qtype, id, qt);
+ END_PROFILE(syscall_get_quota);
+ return result;
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int vfswrap_set_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
+{
+#ifdef HAVE_SYS_QUOTAS
+ int result;
+
+ START_PROFILE(syscall_set_quota);
+ result = sys_set_quota(handle->conn->connectpath, qtype, id, qt);
+ END_PROFILE(syscall_set_quota);
+ return result;
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels)
+{
+ errno = ENOSYS;
+ return -1; /* Not implemented. */
+}
+
+static int vfswrap_statvfs(struct vfs_handle_struct *handle, const char *path, vfs_statvfs_struct *statbuf)
+{
+ return sys_statvfs(path, statbuf);
+}
+
+/* Directory operations */
+
+static SMB_STRUCT_DIR *vfswrap_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
+{
+ SMB_STRUCT_DIR *result;
+
+ START_PROFILE(syscall_opendir);
+ result = sys_opendir(fname);
+ END_PROFILE(syscall_opendir);
+ return result;
+}
+
+static SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
+{
+ SMB_STRUCT_DIRENT *result;
+
+ START_PROFILE(syscall_readdir);
+ result = sys_readdir(dirp);
+ END_PROFILE(syscall_readdir);
+ return result;
+}
+
+static void vfswrap_seekdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, long offset)
+{
+ START_PROFILE(syscall_seekdir);
+ sys_seekdir(dirp, offset);
+ END_PROFILE(syscall_seekdir);
+}
+
+static long vfswrap_telldir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
+{
+ long result;
+ START_PROFILE(syscall_telldir);
+ result = sys_telldir(dirp);
+ END_PROFILE(syscall_telldir);
+ return result;
+}
+
+static void vfswrap_rewinddir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
+{
+ START_PROFILE(syscall_rewinddir);
+ sys_rewinddir(dirp);
+ END_PROFILE(syscall_rewinddir);
+}
+
+static int vfswrap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode)
+{
+ int result;
+ BOOL has_dacl = False;
+
+ START_PROFILE(syscall_mkdir);
+
+ if (lp_inherit_acls(SNUM(handle->conn)) && (has_dacl = directory_has_default_acl(handle->conn, parent_dirname(path))))
+ mode = 0777;
+
+ result = mkdir(path, mode);
+
+ if (result == 0 && !has_dacl) {
+ /*
+ * We need to do this as the default behavior of POSIX ACLs
+ * is to set the mask to be the requested group permission
+ * bits, not the group permission bits to be the requested
+ * group permission bits. This is not what we want, as it will
+ * mess up any inherited ACL bits that were set. JRA.
+ */
+ int saved_errno = errno; /* We may get ENOSYS */
+ if ((SMB_VFS_CHMOD_ACL(handle->conn, path, mode) == -1) && (errno == ENOSYS))
+ errno = saved_errno;
+ }
+
+ END_PROFILE(syscall_mkdir);
+ return result;
+}
+
+static int vfswrap_rmdir(vfs_handle_struct *handle, const char *path)
+{
+ int result;
+
+ START_PROFILE(syscall_rmdir);
+ result = rmdir(path);
+ END_PROFILE(syscall_rmdir);
+ return result;
+}
+
+static int vfswrap_closedir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
+{
+ int result;
+
+ START_PROFILE(syscall_closedir);
+ result = sys_closedir(dirp);
+ END_PROFILE(syscall_closedir);
+ return result;
+}
+
+/* File operations */
+
+static int vfswrap_open(vfs_handle_struct *handle, const char *fname,
+ files_struct *fsp, int flags, mode_t mode)
+{
+ int result;
+
+ START_PROFILE(syscall_open);
+ result = sys_open(fname, flags, mode);
+ END_PROFILE(syscall_open);
+ return result;
+}
+
+static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
+{
+ int result;
+
+ START_PROFILE(syscall_close);
+
+ result = close(fd);
+ END_PROFILE(syscall_close);
+ return result;
+}
+
+static ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n)
+{
+ ssize_t result;
+
+ START_PROFILE_BYTES(syscall_read, n);
+ result = sys_read(fd, data, n);
+ END_PROFILE(syscall_read);
+ return result;
+}
+
+static ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data,
+ size_t n, SMB_OFF_T offset)
+{
+ ssize_t result;
+
+#if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
+ START_PROFILE_BYTES(syscall_pread, n);
+ result = sys_pread(fd, data, n, offset);
+ END_PROFILE(syscall_pread);
+
+ if (result == -1 && errno == ESPIPE) {
+ /* Maintain the fiction that pipes can be seeked (sought?) on. */
+ result = SMB_VFS_READ(fsp, fd, data, n);
+ fsp->fh->pos = 0;
+ }
+
+#else /* HAVE_PREAD */
+ SMB_OFF_T curr;
+ int lerrno;
+
+ curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
+ if (curr == -1 && errno == ESPIPE) {
+ /* Maintain the fiction that pipes can be seeked (sought?) on. */
+ result = SMB_VFS_READ(fsp, fd, data, n);
+ fsp->fh->pos = 0;
+ return result;
+ }
+
+ if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) {
+ return -1;
+ }
+
+ errno = 0;
+ result = SMB_VFS_READ(fsp, fd, data, n);
+ lerrno = errno;
+
+ SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET);
+ errno = lerrno;
+
+#endif /* HAVE_PREAD */
+
+ return result;
+}
+
+static ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n)
+{
+ ssize_t result;
+
+ START_PROFILE_BYTES(syscall_write, n);
+ result = sys_write(fd, data, n);
+ END_PROFILE(syscall_write);
+ return result;
+}
+
+static ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data,
+ size_t n, SMB_OFF_T offset)
+{
+ ssize_t result;
+
+#if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
+ START_PROFILE_BYTES(syscall_pwrite, n);
+ result = sys_pwrite(fd, data, n, offset);
+ END_PROFILE(syscall_pwrite);
+
+ if (result == -1 && errno == ESPIPE) {
+ /* Maintain the fiction that pipes can be sought on. */
+ result = SMB_VFS_WRITE(fsp, fd, data, n);
+ }
+
+#else /* HAVE_PWRITE */
+ SMB_OFF_T curr;
+ int lerrno;
+
+ curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
+ if (curr == -1) {
+ return -1;
+ }
+
+ if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) {
+ return -1;
+ }
+
+ result = SMB_VFS_WRITE(fsp, fd, data, n);
+ lerrno = errno;
+
+ SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET);
+ errno = lerrno;
+
+#endif /* HAVE_PWRITE */
+
+ return result;
+}
+
+static SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
+{
+ SMB_OFF_T result = 0;
+
+ START_PROFILE(syscall_lseek);
+
+ /* Cope with 'stat' file opens. */
+ if (filedes != -1)
+ result = sys_lseek(filedes, offset, whence);
+
+ /*
+ * We want to maintain the fiction that we can seek
+ * on a fifo for file system purposes. This allows
+ * people to set up UNIX fifo's that feed data to Windows
+ * applications. JRA.
+ */
+
+ if((result == -1) && (errno == ESPIPE)) {
+ result = 0;
+ errno = 0;
+ }
+
+ END_PROFILE(syscall_lseek);
+ return result;
+}
+
+static ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *hdr,
+ SMB_OFF_T offset, size_t n)
+{
+ ssize_t result;
+
+ START_PROFILE_BYTES(syscall_sendfile, n);
+ result = sys_sendfile(tofd, fromfd, hdr, offset, n);
+ END_PROFILE(syscall_sendfile);
+ return result;
+}
+
+/*********************************************************
+ For rename across filesystems Patch from Warren Birnbaum
+ <warrenb@hpcvscdp.cv.hp.com>
+**********************************************************/
+
+static int copy_reg(const char *source, const char *dest)
+{
+ SMB_STRUCT_STAT source_stats;
+ int saved_errno;
+ int ifd = -1;
+ int ofd = -1;
+
+ if (sys_lstat (source, &source_stats) == -1)
+ return -1;
+
+ if (!S_ISREG (source_stats.st_mode))
+ return -1;
+
+ if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
+ return -1;
+
+ if (unlink (dest) && errno != ENOENT)
+ return -1;
+
+#ifdef O_NOFOLLOW
+ if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 )
+#else
+ if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )
+#endif
+ goto err;
+
+ if (transfer_file(ifd, ofd, (size_t)-1) == -1)
+ goto err;
+
+ /*
+ * Try to preserve ownership. For non-root it might fail, but that's ok.
+ * But root probably wants to know, e.g. if NFS disallows it.
+ */
+
+#ifdef HAVE_FCHOWN
+ if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
+#else
+ if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
+#endif
+ goto err;
+
+ /*
+ * fchown turns off set[ug]id bits for non-root,
+ * so do the chmod last.
+ */
+
+#if defined(HAVE_FCHMOD)
+ if (fchmod (ofd, source_stats.st_mode & 07777))
+#else
+ if (chmod (dest, source_stats.st_mode & 07777))
+#endif
+ goto err;
+
+ if (close (ifd) == -1)
+ goto err;
+
+ if (close (ofd) == -1)
+ return -1;
+
+ /* Try to copy the old file's modtime and access time. */
+ {
+ struct utimbuf tv;
+
+ tv.actime = source_stats.st_atime;
+ tv.modtime = source_stats.st_mtime;
+ utime(dest, &tv);
+ }
+
+ if (unlink (source) == -1)
+ return -1;
+
+ return 0;
+
+ err:
+
+ saved_errno = errno;
+ if (ifd != -1)
+ close(ifd);
+ if (ofd != -1)
+ close(ofd);
+ errno = saved_errno;
+ return -1;
+}
+
+static int vfswrap_rename(vfs_handle_struct *handle, const char *oldname, const char *newname)
+{
+ int result;
+
+ START_PROFILE(syscall_rename);
+ result = rename(oldname, newname);
+ if (errno == EXDEV) {
+ /* Rename across filesystems needed. */
+ result = copy_reg(oldname, newname);
+ }
+
+ END_PROFILE(syscall_rename);
+ return result;
+}
+
+static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd)
+{
+#ifdef HAVE_FSYNC
+ int result;
+
+ START_PROFILE(syscall_fsync);
+ result = fsync(fd);
+ END_PROFILE(syscall_fsync);
+ return result;
+#else
+ return 0;
+#endif
+}
+
+static int vfswrap_stat(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf)
+{
+ int result;
+
+ START_PROFILE(syscall_stat);
+ result = sys_stat(fname, sbuf);
+ END_PROFILE(syscall_stat);
+ return result;
+}
+
+static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
+{
+ int result;
+
+ START_PROFILE(syscall_fstat);
+ result = sys_fstat(fd, sbuf);
+ END_PROFILE(syscall_fstat);
+ return result;
+}
+
+int vfswrap_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf)
+{
+ int result;
+
+ START_PROFILE(syscall_lstat);
+ result = sys_lstat(path, sbuf);
+ END_PROFILE(syscall_lstat);
+ return result;
+}
+
+static int vfswrap_unlink(vfs_handle_struct *handle, const char *path)
+{
+ int result;
+
+ START_PROFILE(syscall_unlink);
+ result = unlink(path);
+ END_PROFILE(syscall_unlink);
+ return result;
+}
+
+static int vfswrap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
+{
+ int result;
+
+ START_PROFILE(syscall_chmod);
+
+ /*
+ * We need to do this due to the fact that the default POSIX ACL
+ * chmod modifies the ACL *mask* for the group owner, not the
+ * group owner bits directly. JRA.
+ */
+
+
+ {
+ int saved_errno = errno; /* We might get ENOSYS */
+ if ((result = SMB_VFS_CHMOD_ACL(handle->conn, path, mode)) == 0) {
+ END_PROFILE(syscall_chmod);
+ return result;
+ }
+ /* Error - return the old errno. */
+ errno = saved_errno;
+ }
+
+ result = chmod(path, mode);
+ END_PROFILE(syscall_chmod);
+ return result;
+}
+
+static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
+{
+ int result;
+
+ START_PROFILE(syscall_fchmod);
+
+ /*
+ * We need to do this due to the fact that the default POSIX ACL
+ * chmod modifies the ACL *mask* for the group owner, not the
+ * group owner bits directly. JRA.
+ */
+
+ {
+ int saved_errno = errno; /* We might get ENOSYS */
+ if ((result = SMB_VFS_FCHMOD_ACL(fsp, fd, mode)) == 0) {
+ END_PROFILE(syscall_fchmod);
+ return result;
+ }
+ /* Error - return the old errno. */
+ errno = saved_errno;
+ }
+
+#if defined(HAVE_FCHMOD)
+ result = fchmod(fd, mode);
+#else
+ result = -1;
+ errno = ENOSYS;
+#endif
+
+ END_PROFILE(syscall_fchmod);
+ return result;
+}
+
+static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
+{
+ int result;
+
+ START_PROFILE(syscall_chown);
+ result = sys_chown(path, uid, gid);
+ END_PROFILE(syscall_chown);
+ return result;
+}
+
+static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid)
+{
+#ifdef HAVE_FCHOWN
+ int result;
+
+ START_PROFILE(syscall_fchown);
+ result = fchown(fd, uid, gid);
+ END_PROFILE(syscall_fchown);
+ return result;
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int vfswrap_chdir(vfs_handle_struct *handle, const char *path)
+{
+ int result;
+
+ START_PROFILE(syscall_chdir);
+ result = chdir(path);
+ END_PROFILE(syscall_chdir);
+ return result;
+}
+
+static char *vfswrap_getwd(vfs_handle_struct *handle, char *path)
+{
+ char *result;
+
+ START_PROFILE(syscall_getwd);
+ result = sys_getwd(path);
+ END_PROFILE(syscall_getwd);
+ return result;
+}
+
+static int vfswrap_utime(vfs_handle_struct *handle, const char *path, struct utimbuf *times)
+{
+ int result;
+
+ START_PROFILE(syscall_utime);
+ result = utime(path, times);
+ END_PROFILE(syscall_utime);
+ return result;
+}
+
+/*********************************************************************
+ A version of ftruncate that will write the space on disk if strict
+ allocate is set.
+**********************************************************************/
+
+static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
+{
+ SMB_STRUCT_STAT st;
+ SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
+ unsigned char zero_space[4096];
+ SMB_OFF_T space_to_write;
+
+ if (currpos == -1)
+ return -1;
+
+ if (SMB_VFS_FSTAT(fsp, fd, &st) == -1)
+ return -1;
+
+ space_to_write = len - st.st_size;
+
+#ifdef S_ISFIFO
+ if (S_ISFIFO(st.st_mode))
+ return 0;
+#endif
+
+ if (st.st_size == len)
+ return 0;
+
+ /* Shrink - just ftruncate. */
+ if (st.st_size > len)
+ return sys_ftruncate(fd, len);
+
+ /* Write out the real space on disk. */
+ if (SMB_VFS_LSEEK(fsp, fd, st.st_size, SEEK_SET) != st.st_size)
+ return -1;
+
+ space_to_write = len - st.st_size;
+
+ memset(zero_space, '\0', sizeof(zero_space));
+ while ( space_to_write > 0) {
+ SMB_OFF_T retlen;
+ SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write);
+
+ retlen = SMB_VFS_WRITE(fsp,fsp->fh->fd,(char *)zero_space,current_len_to_write);
+ if (retlen <= 0)
+ return -1;
+
+ space_to_write -= retlen;
+ }
+
+ /* Seek to where we were */
+ if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
+ return -1;
+
+ return 0;
+}
+
+static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
+{
+ int result = -1;
+ SMB_STRUCT_STAT st;
+ char c = 0;
+ SMB_OFF_T currpos;
+
+ START_PROFILE(syscall_ftruncate);
+
+ if (lp_strict_allocate(SNUM(fsp->conn))) {
+ result = strict_allocate_ftruncate(handle, fsp, fd, len);
+ END_PROFILE(syscall_ftruncate);
+ return result;
+ }
+
+ /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
+ sys_ftruncate if the system supports it. Then I discovered that
+ you can have some filesystems that support ftruncate
+ expansion and some that don't! On Linux fat can't do
+ ftruncate extend but ext2 can. */
+
+ result = sys_ftruncate(fd, len);
+ if (result == 0)
+ goto done;
+
+ /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
+ extend a file with ftruncate. Provide alternate implementation
+ for this */
+ currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
+ if (currpos == -1) {
+ goto done;
+ }
+
+ /* Do an fstat to see if the file is longer than the requested
+ size in which case the ftruncate above should have
+ succeeded or shorter, in which case seek to len - 1 and
+ write 1 byte of zero */
+ if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) {
+ goto done;
+ }
+
+#ifdef S_ISFIFO
+ if (S_ISFIFO(st.st_mode)) {
+ result = 0;
+ goto done;
+ }
+#endif
+
+ if (st.st_size == len) {
+ result = 0;
+ goto done;
+ }
+
+ if (st.st_size > len) {
+ /* the sys_ftruncate should have worked */
+ goto done;
+ }
+
+ if (SMB_VFS_LSEEK(fsp, fd, len-1, SEEK_SET) != len -1)
+ goto done;
+
+ if (SMB_VFS_WRITE(fsp, fd, &c, 1)!=1)
+ goto done;
+
+ /* Seek to where we were */
+ if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
+ goto done;
+ result = 0;
+
+ done:
+
+ END_PROFILE(syscall_ftruncate);
+ return result;
+}
+
+static BOOL vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
+{
+ BOOL result;
+
+ START_PROFILE(syscall_fcntl_lock);
+ result = fcntl_lock(fd, op, offset, count, type);
+ END_PROFILE(syscall_fcntl_lock);
+ return result;
+}
+
+static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, int fd,
+ uint32 share_mode)
+{
+ START_PROFILE(syscall_kernel_flock);
+ kernel_flock(fd, share_mode);
+ END_PROFILE(syscall_kernel_flock);
+ return 0;
+}
+
+static BOOL vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
+{
+ BOOL result;
+
+ START_PROFILE(syscall_fcntl_getlock);
+ result = fcntl_getlock(fd, poffset, pcount, ptype, ppid);
+ END_PROFILE(syscall_fcntl_getlock);
+ return result;
+}
+
+static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
+{
+ int result;
+
+ START_PROFILE(syscall_symlink);
+ result = sys_symlink(oldpath, newpath);
+ END_PROFILE(syscall_symlink);
+ return result;
+}
+
+static int vfswrap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
+{
+ int result;
+
+ START_PROFILE(syscall_readlink);
+ result = sys_readlink(path, buf, bufsiz);
+ END_PROFILE(syscall_readlink);
+ return result;
+}
+
+static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
+{
+ int result;
+
+ START_PROFILE(syscall_link);
+ result = sys_link(oldpath, newpath);
+ END_PROFILE(syscall_link);
+ return result;
+}
+
+static int vfswrap_mknod(vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev)
+{
+ int result;
+
+ START_PROFILE(syscall_mknod);
+ result = sys_mknod(pathname, mode, dev);
+ END_PROFILE(syscall_mknod);
+ return result;
+}
+
+static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path)
+{
+ char *result;
+
+ START_PROFILE(syscall_realpath);
+ result = sys_realpath(path, resolved_path);
+ END_PROFILE(syscall_realpath);
+ return result;
+}
+
+static size_t vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc)
+{
+ size_t result;
+
+ START_PROFILE(fget_nt_acl);
+ result = get_nt_acl(fsp, security_info, ppdesc);
+ END_PROFILE(fget_nt_acl);
+ return result;
+}
+
+static size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, SEC_DESC **ppdesc)
+{
+ size_t result;
+
+ START_PROFILE(get_nt_acl);
+ result = get_nt_acl(fsp, security_info, ppdesc);
+ END_PROFILE(get_nt_acl);
+ return result;
+}
+
+static BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
+{
+ BOOL result;
+
+ START_PROFILE(fset_nt_acl);
+ result = set_nt_acl(fsp, security_info_sent, psd);
+ END_PROFILE(fset_nt_acl);
+ return result;
+}
+
+static BOOL vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
+{
+ BOOL result;
+
+ START_PROFILE(set_nt_acl);
+ result = set_nt_acl(fsp, security_info_sent, psd);
+ END_PROFILE(set_nt_acl);
+ return result;
+}
+
+static int vfswrap_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode)
+{
+#ifdef HAVE_NO_ACL
+ errno = ENOSYS;
+ return -1;
+#else
+ int result;
+
+ START_PROFILE(chmod_acl);
+ result = chmod_acl(handle->conn, name, mode);
+ END_PROFILE(chmod_acl);
+ return result;
+#endif
+}
+
+static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
+{
+#ifdef HAVE_NO_ACL
+ errno = ENOSYS;
+ return -1;
+#else
+ int result;
+
+ START_PROFILE(fchmod_acl);
+ result = fchmod_acl(fsp, fd, mode);
+ END_PROFILE(fchmod_acl);
+ return result;
+#endif
+}
+
+static int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
+{
+ return sys_acl_get_entry(theacl, entry_id, entry_p);
+}
+
+static int vfswrap_sys_acl_get_tag_type(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
+{
+ return sys_acl_get_tag_type(entry_d, tag_type_p);
+}
+
+static int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
+{
+ return sys_acl_get_permset(entry_d, permset_p);
+}
+
+static void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d)
+{
+ return sys_acl_get_qualifier(entry_d);
+}
+
+static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type)
+{
+ return sys_acl_get_file(handle, path_p, type);
+}
+
+static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
+{
+ return sys_acl_get_fd(handle, fsp, fd);
+}
+
+static int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset)
+{
+ return sys_acl_clear_perms(permset);
+}
+
+static int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
+{
+ return sys_acl_add_perm(permset, perm);
+}
+
+static char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle, SMB_ACL_T theacl, ssize_t *plen)
+{
+ return sys_acl_to_text(theacl, plen);
+}
+
+static SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle, int count)
+{
+ return sys_acl_init(count);
+}
+
+static int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
+{
+ return sys_acl_create_entry(pacl, pentry);
+}
+
+static int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
+{
+ return sys_acl_set_tag_type(entry, tagtype);
+}
+
+static int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, void *qual)
+{
+ return sys_acl_set_qualifier(entry, qual);
+}
+
+static int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
+{
+ return sys_acl_set_permset(entry, permset);
+}
+
+static int vfswrap_sys_acl_valid(vfs_handle_struct *handle, SMB_ACL_T theacl )
+{
+ return sys_acl_valid(theacl );
+}
+
+static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
+{
+ return sys_acl_set_file(handle, name, acltype, theacl);
+}
+
+static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl)
+{
+ return sys_acl_set_fd(handle, fsp, fd, theacl);
+}
+
+static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path)
+{
+ return sys_acl_delete_def_file(handle, path);
+}
+
+static int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
+{
+ return sys_acl_get_perm(permset, perm);
+}
+
+static int vfswrap_sys_acl_free_text(vfs_handle_struct *handle, char *text)
+{
+ return sys_acl_free_text(text);
+}
+
+static int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle, SMB_ACL_T posix_acl)
+{
+ return sys_acl_free_acl(posix_acl);
+}
+
+static int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, void *qualifier, SMB_ACL_TAG_T tagtype)
+{
+ return sys_acl_free_qualifier(qualifier, tagtype);
+}
+
+/****************************************************************
+ Extended attribute operations.
+*****************************************************************/
+
+static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
+{
+ return sys_getxattr(path, name, value, size);
+}
+
+static ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
+{
+ return sys_lgetxattr(path, name, value, size);
+}
+
+static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size)
+{
+ return sys_fgetxattr(fd, name, value, size);
+}
+
+static ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
+{
+ return sys_listxattr(path, list, size);
+}
+
+ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
+{
+ return sys_llistxattr(path, list, size);
+}
+
+ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size)
+{
+ return sys_flistxattr(fd, list, size);
+}
+
+static int vfswrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
+{
+ return sys_removexattr(path, name);
+}
+
+static int vfswrap_lremovexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
+{
+ return sys_lremovexattr(path, name);
+}
+
+static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name)
+{
+ return sys_fremovexattr(fd, name);
+}
+
+static int vfswrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
+{
+ return sys_setxattr(path, name, value, size, flags);
+}
+
+static int vfswrap_lsetxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
+{
+ return sys_lsetxattr(path, name, value, size, flags);
+}
+
+static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags)
+{
+ return sys_fsetxattr(fd, name, value, size, flags);
+}
+
+static int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
+{
+ return sys_aio_read(aiocb);
+}
+
+static int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
+{
+ return sys_aio_write(aiocb);
+}
+
+static ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
+{
+ return sys_aio_return(aiocb);
+}
+
+static int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_AIOCB *aiocb)
+{
+ return sys_aio_cancel(fd, aiocb);
+}
+
+static int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
+{
+ return sys_aio_error(aiocb);
+}
+
+static int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb)
+{
+ return sys_aio_fsync(op, aiocb);
+}
+
+static int vfswrap_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *timeout)
+{
+ return sys_aio_suspend(aiocb, n, timeout);
+}
+
+static vfs_op_tuple vfs_default_ops[] = {
+
+ /* Disk operations */
+
+ {SMB_VFS_OP(vfswrap_connect), SMB_VFS_OP_CONNECT,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_disconnect), SMB_VFS_OP_DISCONNECT,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_disk_free), SMB_VFS_OP_DISK_FREE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_get_quota), SMB_VFS_OP_GET_QUOTA,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_set_quota), SMB_VFS_OP_SET_QUOTA,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_statvfs), SMB_VFS_OP_STATVFS,
+ SMB_VFS_LAYER_OPAQUE},
+
+ /* Directory operations */
+
+ {SMB_VFS_OP(vfswrap_opendir), SMB_VFS_OP_OPENDIR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_readdir), SMB_VFS_OP_READDIR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_seekdir), SMB_VFS_OP_SEEKDIR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_telldir), SMB_VFS_OP_TELLDIR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_rewinddir), SMB_VFS_OP_REWINDDIR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_mkdir), SMB_VFS_OP_MKDIR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_rmdir), SMB_VFS_OP_RMDIR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_closedir), SMB_VFS_OP_CLOSEDIR,
+ SMB_VFS_LAYER_OPAQUE},
+
+ /* File operations */
+
+ {SMB_VFS_OP(vfswrap_open), SMB_VFS_OP_OPEN,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_close), SMB_VFS_OP_CLOSE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_read), SMB_VFS_OP_READ,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_pread), SMB_VFS_OP_PREAD,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_write), SMB_VFS_OP_WRITE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_pwrite), SMB_VFS_OP_PWRITE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_lseek), SMB_VFS_OP_LSEEK,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sendfile), SMB_VFS_OP_SENDFILE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_rename), SMB_VFS_OP_RENAME,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_fsync), SMB_VFS_OP_FSYNC,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_stat), SMB_VFS_OP_STAT,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_fstat), SMB_VFS_OP_FSTAT,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_lstat), SMB_VFS_OP_LSTAT,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_unlink), SMB_VFS_OP_UNLINK,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_chmod), SMB_VFS_OP_CHMOD,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_fchmod), SMB_VFS_OP_FCHMOD,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_chown), SMB_VFS_OP_CHOWN,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_fchown), SMB_VFS_OP_FCHOWN,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_chdir), SMB_VFS_OP_CHDIR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_getwd), SMB_VFS_OP_GETWD,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_utime), SMB_VFS_OP_UTIME,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_ftruncate), SMB_VFS_OP_FTRUNCATE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_lock), SMB_VFS_OP_LOCK,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_kernel_flock), SMB_VFS_OP_KERNEL_FLOCK,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_getlock), SMB_VFS_OP_GETLOCK,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_symlink), SMB_VFS_OP_SYMLINK,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_readlink), SMB_VFS_OP_READLINK,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_link), SMB_VFS_OP_LINK,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_mknod), SMB_VFS_OP_MKNOD,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_realpath), SMB_VFS_OP_REALPATH,
+ SMB_VFS_LAYER_OPAQUE},
+
+ /* NT ACL operations. */
+
+ {SMB_VFS_OP(vfswrap_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_get_nt_acl), SMB_VFS_OP_GET_NT_ACL,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_fset_nt_acl), SMB_VFS_OP_FSET_NT_ACL,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_set_nt_acl), SMB_VFS_OP_SET_NT_ACL,
+ SMB_VFS_LAYER_OPAQUE},
+
+ /* POSIX ACL operations. */
+
+ {SMB_VFS_OP(vfswrap_chmod_acl), SMB_VFS_OP_CHMOD_ACL,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_get_entry), SMB_VFS_OP_SYS_ACL_GET_ENTRY,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_get_tag_type), SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_get_permset), SMB_VFS_OP_SYS_ACL_GET_PERMSET,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_get_qualifier), SMB_VFS_OP_SYS_ACL_GET_QUALIFIER,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_get_fd), SMB_VFS_OP_SYS_ACL_GET_FD,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_clear_perms), SMB_VFS_OP_SYS_ACL_CLEAR_PERMS,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_add_perm), SMB_VFS_OP_SYS_ACL_ADD_PERM,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_to_text), SMB_VFS_OP_SYS_ACL_TO_TEXT,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_init), SMB_VFS_OP_SYS_ACL_INIT,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_create_entry), SMB_VFS_OP_SYS_ACL_CREATE_ENTRY,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_set_tag_type), SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_set_qualifier), SMB_VFS_OP_SYS_ACL_SET_QUALIFIER,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_set_permset), SMB_VFS_OP_SYS_ACL_SET_PERMSET,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_valid), SMB_VFS_OP_SYS_ACL_VALID,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_set_file), SMB_VFS_OP_SYS_ACL_SET_FILE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_set_fd), SMB_VFS_OP_SYS_ACL_SET_FD,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_delete_def_file), SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_get_perm), SMB_VFS_OP_SYS_ACL_GET_PERM,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_free_text), SMB_VFS_OP_SYS_ACL_FREE_TEXT,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_free_acl), SMB_VFS_OP_SYS_ACL_FREE_ACL,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_sys_acl_free_qualifier), SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER,
+ SMB_VFS_LAYER_OPAQUE},
+
+ /* EA operations. */
+
+ {SMB_VFS_OP(vfswrap_getxattr), SMB_VFS_OP_GETXATTR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_lgetxattr), SMB_VFS_OP_LGETXATTR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_fgetxattr), SMB_VFS_OP_FGETXATTR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_listxattr), SMB_VFS_OP_LISTXATTR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_llistxattr), SMB_VFS_OP_LLISTXATTR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_flistxattr), SMB_VFS_OP_FLISTXATTR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_removexattr), SMB_VFS_OP_REMOVEXATTR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_lremovexattr), SMB_VFS_OP_LREMOVEXATTR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_fremovexattr), SMB_VFS_OP_FREMOVEXATTR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_setxattr), SMB_VFS_OP_SETXATTR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_lsetxattr), SMB_VFS_OP_LSETXATTR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_fsetxattr), SMB_VFS_OP_FSETXATTR,
+ SMB_VFS_LAYER_OPAQUE},
+
+ {SMB_VFS_OP(vfswrap_aio_read), SMB_VFS_OP_AIO_READ,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_aio_write), SMB_VFS_OP_AIO_WRITE,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_aio_return), SMB_VFS_OP_AIO_RETURN,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_aio_cancel), SMB_VFS_OP_AIO_CANCEL,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_aio_error), SMB_VFS_OP_AIO_ERROR,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_aio_fsync), SMB_VFS_OP_AIO_FSYNC,
+ SMB_VFS_LAYER_OPAQUE},
+ {SMB_VFS_OP(vfswrap_aio_suspend),SMB_VFS_OP_AIO_SUSPEND,
+ SMB_VFS_LAYER_OPAQUE},
+
+ /* Finish VFS operations definition */
+
+ {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP,
+ SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS vfs_default_init(void)
+{
+ unsigned int needed = SMB_VFS_OP_LAST + 1; /* convert from index to count */
+
+ if (ARRAY_SIZE(vfs_default_ops) != needed) {
+ DEBUG(0, ("%s: %u ops registered, but %u ops are required\n",
+ DEFAULT_VFS_MODULE_NAME, (unsigned int)ARRAY_SIZE(vfs_default_ops), needed));
+ smb_panic("operation(s) missing from default VFS module");
+ }
+
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
+ DEFAULT_VFS_MODULE_NAME, vfs_default_ops);
+}
diff --git a/source/modules/vfs_default_quota.c b/source/modules/vfs_default_quota.c
index 9922a30315d..55dc287b88a 100644
--- a/source/modules/vfs_default_quota.c
+++ b/source/modules/vfs_default_quota.c
@@ -92,11 +92,11 @@
#define DEFAULT_QUOTA_GID_NOLIMIT(handle) \
lp_parm_bool(SNUM((handle)->conn),DEFAULT_QUOTA_NAME,"gid nolimit",DEFAULT_QUOTA_GID_NOLIMIT_DEFAULT)
-static int default_quota_get_quota(vfs_handle_struct *handle, connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq)
+static int default_quota_get_quota(vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq)
{
int ret = -1;
- if ((ret=SMB_VFS_NEXT_GET_QUOTA(handle, conn, qtype, id, dq))!=0) {
+ if ((ret=SMB_VFS_NEXT_GET_QUOTA(handle, qtype, id, dq))!=0) {
return ret;
}
@@ -122,7 +122,7 @@ static int default_quota_get_quota(vfs_handle_struct *handle, connection_struct
unid_t qid;
uint32 qflags = dq->qflags;
qid.uid = DEFAULT_QUOTA_UID(handle);
- SMB_VFS_NEXT_GET_QUOTA(handle, conn, SMB_USER_QUOTA_TYPE, qid, dq);
+ SMB_VFS_NEXT_GET_QUOTA(handle, SMB_USER_QUOTA_TYPE, qid, dq);
dq->qflags = qflags;
}
break;
@@ -132,7 +132,7 @@ static int default_quota_get_quota(vfs_handle_struct *handle, connection_struct
unid_t qid;
uint32 qflags = dq->qflags;
qid.gid = DEFAULT_QUOTA_GID(handle);
- SMB_VFS_NEXT_GET_QUOTA(handle, conn, SMB_GROUP_QUOTA_TYPE, qid, dq);
+ SMB_VFS_NEXT_GET_QUOTA(handle, SMB_GROUP_QUOTA_TYPE, qid, dq);
dq->qflags = qflags;
}
break;
@@ -146,7 +146,7 @@ static int default_quota_get_quota(vfs_handle_struct *handle, connection_struct
return ret;
}
-static int default_quota_set_quota(vfs_handle_struct *handle, connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq)
+static int default_quota_set_quota(vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dq)
{
int ret = -1;
@@ -179,7 +179,7 @@ static int default_quota_set_quota(vfs_handle_struct *handle, connection_struct
break;
}
- if ((ret=SMB_VFS_NEXT_SET_QUOTA(handle, conn, qtype, id, dq))!=0) {
+ if ((ret=SMB_VFS_NEXT_SET_QUOTA(handle, qtype, id, dq))!=0) {
return ret;
}
@@ -194,7 +194,7 @@ static int default_quota_set_quota(vfs_handle_struct *handle, connection_struct
{
unid_t qid;
qid.uid = DEFAULT_QUOTA_UID(handle);
- ret = SMB_VFS_NEXT_SET_QUOTA(handle, conn, SMB_USER_QUOTA_TYPE, qid, dq);
+ ret = SMB_VFS_NEXT_SET_QUOTA(handle, SMB_USER_QUOTA_TYPE, qid, dq);
}
break;
#ifdef HAVE_GROUP_QUOTA
@@ -202,7 +202,7 @@ static int default_quota_set_quota(vfs_handle_struct *handle, connection_struct
{
unid_t qid;
qid.gid = DEFAULT_QUOTA_GID(handle);
- ret = SMB_VFS_NEXT_SET_QUOTA(handle, conn, SMB_GROUP_QUOTA_TYPE, qid, dq);
+ ret = SMB_VFS_NEXT_SET_QUOTA(handle, SMB_GROUP_QUOTA_TYPE, qid, dq);
}
break;
#endif /* HAVE_GROUP_QUOTA */
diff --git a/source/modules/vfs_expand_msdfs.c b/source/modules/vfs_expand_msdfs.c
index d22f6a7f98e..fdd9ac6fbd8 100644
--- a/source/modules/vfs_expand_msdfs.c
+++ b/source/modules/vfs_expand_msdfs.c
@@ -110,6 +110,7 @@ static BOOL expand_msdfs_target(connection_struct* conn, pstring target)
int filename_len;
pstring targethost;
pstring new_target;
+ extern userdom_struct current_user_info;
if (filename_start == NULL) {
DEBUG(10, ("No filename start in %s\n", target));
@@ -135,7 +136,11 @@ static BOOL expand_msdfs_target(connection_struct* conn, pstring target)
return False;
}
- standard_sub_conn(conn, mapfilename, sizeof(mapfilename));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ mapfilename, sizeof(mapfilename));
DEBUG(10, ("Expanded targethost to %s\n", targethost));
@@ -150,13 +155,12 @@ static BOOL expand_msdfs_target(connection_struct* conn, pstring target)
}
static int expand_msdfs_readlink(struct vfs_handle_struct *handle,
- struct connection_struct *conn,
const char *path, char *buf, size_t bufsiz)
{
pstring target;
int result;
- result = SMB_VFS_NEXT_READLINK(handle, conn, path, target,
+ result = SMB_VFS_NEXT_READLINK(handle, path, target,
sizeof(target));
if (result < 0)
@@ -166,7 +170,7 @@ static int expand_msdfs_readlink(struct vfs_handle_struct *handle,
if ((strncmp(target, "msdfs:", strlen("msdfs:")) == 0) &&
(strchr_m(target, '@') != NULL)) {
- if (!expand_msdfs_target(conn, target)) {
+ if (!expand_msdfs_target(handle->conn, target)) {
errno = ENOENT;
return -1;
}
diff --git a/source/modules/vfs_extd_audit.c b/source/modules/vfs_extd_audit.c
index cb8c3ffd6ab..1c3b25103c8 100644
--- a/source/modules/vfs_extd_audit.c
+++ b/source/modules/vfs_extd_audit.c
@@ -32,17 +32,17 @@ static int vfs_extd_audit_debug_level = DBGC_VFS;
/* Function prototypes */
-static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user);
-static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn);
-static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr);
-static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode);
-static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path);
-static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode);
+static int audit_connect(vfs_handle_struct *handle, const char *svc, const char *user);
+static void audit_disconnect(vfs_handle_struct *handle);
+static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr);
+static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode);
+static int audit_rmdir(vfs_handle_struct *handle, const char *path);
+static int audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode);
static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd);
-static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname);
-static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path);
-static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode);
-static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode);
+static int audit_rename(vfs_handle_struct *handle, const char *oldname, const char *newname);
+static int audit_unlink(vfs_handle_struct *handle, const char *path);
+static int audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode);
+static int audit_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode);
static int audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
static int audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode);
@@ -123,7 +123,7 @@ static int audit_syslog_priority(vfs_handle_struct *handle)
/* Implementation of vfs_ops. Pass everything on to the default
operation but log event first. */
-static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, const char *svc, const char *user)
+static int audit_connect(vfs_handle_struct *handle, const char *svc, const char *user)
{
int result;
@@ -134,25 +134,25 @@ static int audit_connect(vfs_handle_struct *handle, connection_struct *conn, con
DEBUG(10, ("Connected to service %s as user %s\n",
svc, user));
- result = SMB_VFS_NEXT_CONNECT(handle, conn, svc, user);
+ result = SMB_VFS_NEXT_CONNECT(handle, svc, user);
return result;
}
-static void audit_disconnect(vfs_handle_struct *handle, connection_struct *conn)
+static void audit_disconnect(vfs_handle_struct *handle)
{
syslog(audit_syslog_priority(handle), "disconnected\n");
DEBUG(10, ("Disconnected from VFS module extd_audit\n"));
- SMB_VFS_NEXT_DISCONNECT(handle, conn);
+ SMB_VFS_NEXT_DISCONNECT(handle);
return;
}
-static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr)
+static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
{
SMB_STRUCT_DIR *result;
- result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr);
+ result = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
syslog(audit_syslog_priority(handle), "opendir %s %s%s\n",
fname,
@@ -166,11 +166,11 @@ static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, connection_struc
return result;
}
-static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
+static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_MKDIR(handle, conn, path, mode);
+ result = SMB_VFS_NEXT_MKDIR(handle, path, mode);
syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n",
path,
@@ -184,11 +184,11 @@ static int audit_mkdir(vfs_handle_struct *handle, connection_struct *conn, const
return result;
}
-static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
+static int audit_rmdir(vfs_handle_struct *handle, const char *path)
{
int result;
- result = SMB_VFS_NEXT_RMDIR(handle, conn, path);
+ result = SMB_VFS_NEXT_RMDIR(handle, path);
syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n",
path,
@@ -202,11 +202,11 @@ static int audit_rmdir(vfs_handle_struct *handle, connection_struct *conn, const
return result;
}
-static int audit_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
+static int audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode);
+ result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n",
fname, result,
@@ -239,11 +239,11 @@ static int audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
return result;
}
-static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname)
+static int audit_rename(vfs_handle_struct *handle, const char *oldname, const char *newname)
{
int result;
- result = SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname);
+ result = SMB_VFS_NEXT_RENAME(handle, oldname, newname);
syslog(audit_syslog_priority(handle), "rename %s -> %s %s%s\n",
oldname, newname,
@@ -257,11 +257,11 @@ static int audit_rename(vfs_handle_struct *handle, connection_struct *conn, cons
return result;
}
-static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
+static int audit_unlink(vfs_handle_struct *handle, const char *path)
{
int result;
- result = SMB_VFS_NEXT_UNLINK(handle, conn, path);
+ result = SMB_VFS_NEXT_UNLINK(handle, path);
syslog(audit_syslog_priority(handle), "unlink %s %s%s\n",
path,
@@ -275,11 +275,11 @@ static int audit_unlink(vfs_handle_struct *handle, connection_struct *conn, cons
return result;
}
-static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
+static int audit_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode);
+ result = SMB_VFS_NEXT_CHMOD(handle, path, mode);
syslog(audit_syslog_priority(handle), "chmod %s mode 0x%x %s%s\n",
path, mode,
@@ -293,11 +293,11 @@ static int audit_chmod(vfs_handle_struct *handle, connection_struct *conn, const
return result;
}
-static int audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
+static int audit_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_CHMOD_ACL(handle, conn, path, mode);
+ result = SMB_VFS_NEXT_CHMOD_ACL(handle, path, mode);
syslog(audit_syslog_priority(handle), "chmod_acl %s mode 0x%x %s%s\n",
path, mode,
diff --git a/source/modules/vfs_fake_perms.c b/source/modules/vfs_fake_perms.c
index decbe01d3ca..8bd8bbf5321 100644
--- a/source/modules/vfs_fake_perms.c
+++ b/source/modules/vfs_fake_perms.c
@@ -29,11 +29,11 @@ extern struct current_user current_user;
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
-static int fake_perms_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
+static int fake_perms_stat(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf)
{
int ret = -1;
- ret = SMB_VFS_NEXT_STAT(handle, conn, fname, sbuf);
+ ret = SMB_VFS_NEXT_STAT(handle, fname, sbuf);
if (ret == 0) {
if (S_ISDIR(sbuf->st_mode)) {
sbuf->st_mode = S_IFDIR | S_IRWXU;
diff --git a/source/modules/vfs_full_audit.c b/source/modules/vfs_full_audit.c
index b9ffd6fc05f..fd15c5c3585 100644
--- a/source/modules/vfs_full_audit.c
+++ b/source/modules/vfs_full_audit.c
@@ -72,48 +72,44 @@ struct vfs_full_audit_private_data {
/* Function prototypes */
-static int smb_full_audit_connect(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_connect(vfs_handle_struct *handle,
const char *svc, const char *user);
-static void smb_full_audit_disconnect(vfs_handle_struct *handle,
- connection_struct *conn);
+static void smb_full_audit_disconnect(vfs_handle_struct *handle);
static SMB_BIG_UINT smb_full_audit_disk_free(vfs_handle_struct *handle,
- connection_struct *conn, const char *path,
+ const char *path,
BOOL small_query, SMB_BIG_UINT *bsize,
SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
static int smb_full_audit_get_quota(struct vfs_handle_struct *handle,
- struct connection_struct *conn,
enum SMB_QUOTA_TYPE qtype, unid_t id,
SMB_DISK_QUOTA *qt);
static int smb_full_audit_set_quota(struct vfs_handle_struct *handle,
- struct connection_struct *conn,
enum SMB_QUOTA_TYPE qtype, unid_t id,
SMB_DISK_QUOTA *qt);
static int smb_full_audit_get_shadow_copy_data(struct vfs_handle_struct *handle,
struct files_struct *fsp,
SHADOW_COPY_DATA *shadow_copy_data, BOOL labels);
static int smb_full_audit_statvfs(struct vfs_handle_struct *handle,
- struct connection_struct *conn,
const char *path,
struct vfs_statvfs_struct *statbuf);
-static SMB_STRUCT_DIR *smb_full_audit_opendir(vfs_handle_struct *handle, connection_struct *conn,
+static SMB_STRUCT_DIR *smb_full_audit_opendir(vfs_handle_struct *handle,
const char *fname, const char *mask, uint32 attr);
static SMB_STRUCT_DIRENT *smb_full_audit_readdir(vfs_handle_struct *handle,
- connection_struct *conn, SMB_STRUCT_DIR *dirp);
-static void smb_full_audit_seekdir(vfs_handle_struct *handle, connection_struct *conn,
+ SMB_STRUCT_DIR *dirp);
+static void smb_full_audit_seekdir(vfs_handle_struct *handle,
SMB_STRUCT_DIR *dirp, long offset);
-static long smb_full_audit_telldir(vfs_handle_struct *handle, connection_struct *conn,
+static long smb_full_audit_telldir(vfs_handle_struct *handle,
SMB_STRUCT_DIR *dirp);
-static void smb_full_audit_rewinddir(vfs_handle_struct *handle, connection_struct *conn,
+static void smb_full_audit_rewinddir(vfs_handle_struct *handle,
SMB_STRUCT_DIR *dirp);
-static int smb_full_audit_mkdir(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_mkdir(vfs_handle_struct *handle,
const char *path, mode_t mode);
-static int smb_full_audit_rmdir(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_rmdir(vfs_handle_struct *handle,
const char *path);
-static int smb_full_audit_closedir(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_closedir(vfs_handle_struct *handle,
SMB_STRUCT_DIR *dirp);
-static int smb_full_audit_open(vfs_handle_struct *handle, connection_struct *conn,
- const char *fname, int flags, mode_t mode);
+static int smb_full_audit_open(vfs_handle_struct *handle,
+ const char *fname, files_struct *fsp, int flags, mode_t mode);
static int smb_full_audit_close(vfs_handle_struct *handle, files_struct *fsp, int fd);
static ssize_t smb_full_audit_read(vfs_handle_struct *handle, files_struct *fsp,
int fd, void *data, size_t n);
@@ -130,30 +126,30 @@ static ssize_t smb_full_audit_sendfile(vfs_handle_struct *handle, int tofd,
files_struct *fsp, int fromfd,
const DATA_BLOB *hdr, SMB_OFF_T offset,
size_t n);
-static int smb_full_audit_rename(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_rename(vfs_handle_struct *handle,
const char *oldname, const char *newname);
static int smb_full_audit_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd);
-static int smb_full_audit_stat(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_stat(vfs_handle_struct *handle,
const char *fname, SMB_STRUCT_STAT *sbuf);
static int smb_full_audit_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd,
SMB_STRUCT_STAT *sbuf);
-static int smb_full_audit_lstat(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_lstat(vfs_handle_struct *handle,
const char *path, SMB_STRUCT_STAT *sbuf);
-static int smb_full_audit_unlink(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_unlink(vfs_handle_struct *handle,
const char *path);
-static int smb_full_audit_chmod(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_chmod(vfs_handle_struct *handle,
const char *path, mode_t mode);
static int smb_full_audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd,
mode_t mode);
-static int smb_full_audit_chown(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_chown(vfs_handle_struct *handle,
const char *path, uid_t uid, gid_t gid);
static int smb_full_audit_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd,
uid_t uid, gid_t gid);
-static int smb_full_audit_chdir(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_chdir(vfs_handle_struct *handle,
const char *path);
-static char *smb_full_audit_getwd(vfs_handle_struct *handle, connection_struct *conn,
+static char *smb_full_audit_getwd(vfs_handle_struct *handle,
char *path);
-static int smb_full_audit_utime(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_utime(vfs_handle_struct *handle,
const char *path, struct utimbuf *times);
static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp,
int fd, SMB_OFF_T len);
@@ -161,15 +157,15 @@ static BOOL smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp, in
int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
static BOOL smb_full_audit_getlock(vfs_handle_struct *handle, files_struct *fsp, int fd,
SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid);
-static int smb_full_audit_symlink(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_symlink(vfs_handle_struct *handle,
const char *oldpath, const char *newpath);
-static int smb_full_audit_readlink(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_readlink(vfs_handle_struct *handle,
const char *path, char *buf, size_t bufsiz);
-static int smb_full_audit_link(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_link(vfs_handle_struct *handle,
const char *oldpath, const char *newpath);
-static int smb_full_audit_mknod(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_mknod(vfs_handle_struct *handle,
const char *pathname, mode_t mode, SMB_DEV_T dev);
-static char *smb_full_audit_realpath(vfs_handle_struct *handle, connection_struct *conn,
+static char *smb_full_audit_realpath(vfs_handle_struct *handle,
const char *path, char *resolved_path);
static size_t smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
int fd, uint32 security_info,
@@ -183,120 +179,99 @@ static BOOL smb_full_audit_fset_nt_acl(vfs_handle_struct *handle, files_struct *
static BOOL smb_full_audit_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
const char *name, uint32 security_info_sent,
SEC_DESC *psd);
-static int smb_full_audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_chmod_acl(vfs_handle_struct *handle,
const char *path, mode_t mode);
static int smb_full_audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp,
int fd, mode_t mode);
static int smb_full_audit_sys_acl_get_entry(vfs_handle_struct *handle,
- connection_struct *conn,
SMB_ACL_T theacl, int entry_id,
SMB_ACL_ENTRY_T *entry_p);
static int smb_full_audit_sys_acl_get_tag_type(vfs_handle_struct *handle,
- connection_struct *conn,
SMB_ACL_ENTRY_T entry_d,
SMB_ACL_TAG_T *tag_type_p);
static int smb_full_audit_sys_acl_get_permset(vfs_handle_struct *handle,
- connection_struct *conn,
SMB_ACL_ENTRY_T entry_d,
SMB_ACL_PERMSET_T *permset_p);
static void * smb_full_audit_sys_acl_get_qualifier(vfs_handle_struct *handle,
- connection_struct *conn,
SMB_ACL_ENTRY_T entry_d);
static SMB_ACL_T smb_full_audit_sys_acl_get_file(vfs_handle_struct *handle,
- connection_struct *conn,
const char *path_p,
SMB_ACL_TYPE_T type);
static SMB_ACL_T smb_full_audit_sys_acl_get_fd(vfs_handle_struct *handle,
files_struct *fsp,
int fd);
static int smb_full_audit_sys_acl_clear_perms(vfs_handle_struct *handle,
- connection_struct *conn,
SMB_ACL_PERMSET_T permset);
static int smb_full_audit_sys_acl_add_perm(vfs_handle_struct *handle,
- connection_struct *conn,
SMB_ACL_PERMSET_T permset,
SMB_ACL_PERM_T perm);
static char * smb_full_audit_sys_acl_to_text(vfs_handle_struct *handle,
- connection_struct *conn, SMB_ACL_T theacl,
+ SMB_ACL_T theacl,
ssize_t *plen);
static SMB_ACL_T smb_full_audit_sys_acl_init(vfs_handle_struct *handle,
- connection_struct *conn,
int count);
static int smb_full_audit_sys_acl_create_entry(vfs_handle_struct *handle,
- connection_struct *conn, SMB_ACL_T *pacl,
+ SMB_ACL_T *pacl,
SMB_ACL_ENTRY_T *pentry);
static int smb_full_audit_sys_acl_set_tag_type(vfs_handle_struct *handle,
- connection_struct *conn,
SMB_ACL_ENTRY_T entry,
SMB_ACL_TAG_T tagtype);
static int smb_full_audit_sys_acl_set_qualifier(vfs_handle_struct *handle,
- connection_struct *conn,
SMB_ACL_ENTRY_T entry,
void *qual);
static int smb_full_audit_sys_acl_set_permset(vfs_handle_struct *handle,
- connection_struct *conn,
SMB_ACL_ENTRY_T entry,
SMB_ACL_PERMSET_T permset);
static int smb_full_audit_sys_acl_valid(vfs_handle_struct *handle,
- connection_struct *conn,
SMB_ACL_T theacl );
static int smb_full_audit_sys_acl_set_file(vfs_handle_struct *handle,
- connection_struct *conn,
const char *name, SMB_ACL_TYPE_T acltype,
SMB_ACL_T theacl);
static int smb_full_audit_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp,
int fd, SMB_ACL_T theacl);
static int smb_full_audit_sys_acl_delete_def_file(vfs_handle_struct *handle,
- connection_struct *conn,
const char *path);
static int smb_full_audit_sys_acl_get_perm(vfs_handle_struct *handle,
- connection_struct *conn,
SMB_ACL_PERMSET_T permset,
SMB_ACL_PERM_T perm);
static int smb_full_audit_sys_acl_free_text(vfs_handle_struct *handle,
- connection_struct *conn,
char *text);
static int smb_full_audit_sys_acl_free_acl(vfs_handle_struct *handle,
- connection_struct *conn,
SMB_ACL_T posix_acl);
static int smb_full_audit_sys_acl_free_qualifier(vfs_handle_struct *handle,
- connection_struct *conn,
void *qualifier,
SMB_ACL_TAG_T tagtype);
static ssize_t smb_full_audit_getxattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn, const char *path,
+ const char *path,
const char *name, void *value, size_t size);
static ssize_t smb_full_audit_lgetxattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn,
const char *path, const char *name,
void *value, size_t size);
static ssize_t smb_full_audit_fgetxattr(struct vfs_handle_struct *handle,
struct files_struct *fsp, int fd,
const char *name, void *value, size_t size);
static ssize_t smb_full_audit_listxattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn,
const char *path, char *list, size_t size);
static ssize_t smb_full_audit_llistxattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn,
const char *path, char *list, size_t size);
static ssize_t smb_full_audit_flistxattr(struct vfs_handle_struct *handle,
struct files_struct *fsp, int fd, char *list,
size_t size);
static int smb_full_audit_removexattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn, const char *path,
+ const char *path,
const char *name);
static int smb_full_audit_lremovexattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn, const char *path,
+ const char *path,
const char *name);
static int smb_full_audit_fremovexattr(struct vfs_handle_struct *handle,
struct files_struct *fsp, int fd,
const char *name);
static int smb_full_audit_setxattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn, const char *path,
+ const char *path,
const char *name, const void *value, size_t size,
int flags);
static int smb_full_audit_lsetxattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn, const char *path,
+ const char *path,
const char *name, const void *value, size_t size,
int flags);
static int smb_full_audit_fsetxattr(struct vfs_handle_struct *handle,
@@ -666,10 +641,15 @@ static int audit_syslog_priority(vfs_handle_struct *handle)
static char *audit_prefix(connection_struct *conn)
{
static pstring prefix;
+ extern userdom_struct current_user_info;
pstrcpy(prefix, lp_parm_const_string(SNUM(conn), "full_audit",
"prefix", "%u|%I"));
- standard_sub_snum(SNUM(conn), prefix, sizeof(prefix)-1);
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ prefix, sizeof(prefix));
return prefix;
}
@@ -811,7 +791,7 @@ static void free_private_data(void **p_data)
/* Implementation of vfs_ops. Pass everything on to the default
operation but log event first. */
-static int smb_full_audit_connect(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_connect(vfs_handle_struct *handle,
const char *svc, const char *user)
{
int result;
@@ -832,17 +812,17 @@ static int smb_full_audit_connect(vfs_handle_struct *handle, connection_struct *
openlog("smbd_audit", 0, audit_syslog_facility(handle));
init_bitmap(&pd->success_ops,
- lp_parm_string_list(SNUM(conn), "full_audit", "success",
+ lp_parm_string_list(SNUM(handle->conn), "full_audit", "success",
none));
init_bitmap(&pd->failure_ops,
- lp_parm_string_list(SNUM(conn), "full_audit", "failure",
+ lp_parm_string_list(SNUM(handle->conn), "full_audit", "failure",
all));
/* Store the private data. */
SMB_VFS_HANDLE_SET_DATA(handle, pd, free_private_data,
struct vfs_full_audit_private_data, return -1);
- result = SMB_VFS_NEXT_CONNECT(handle, conn, svc, user);
+ result = SMB_VFS_NEXT_CONNECT(handle, svc, user);
do_log(SMB_VFS_OP_CONNECT, True, handle,
"%s", svc);
@@ -850,13 +830,12 @@ static int smb_full_audit_connect(vfs_handle_struct *handle, connection_struct *
return result;
}
-static void smb_full_audit_disconnect(vfs_handle_struct *handle,
- connection_struct *conn)
+static void smb_full_audit_disconnect(vfs_handle_struct *handle)
{
- SMB_VFS_NEXT_DISCONNECT(handle, conn);
+ SMB_VFS_NEXT_DISCONNECT(handle);
do_log(SMB_VFS_OP_DISCONNECT, True, handle,
- "%s", lp_servicename(SNUM(conn)));
+ "%s", lp_servicename(SNUM(handle->conn)));
/* The bitmaps will be disconnected when the private
data is deleted. */
@@ -865,13 +844,13 @@ static void smb_full_audit_disconnect(vfs_handle_struct *handle,
}
static SMB_BIG_UINT smb_full_audit_disk_free(vfs_handle_struct *handle,
- connection_struct *conn, const char *path,
+ const char *path,
BOOL small_query, SMB_BIG_UINT *bsize,
SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
SMB_BIG_UINT result;
- result = SMB_VFS_NEXT_DISK_FREE(handle, conn, path, small_query, bsize,
+ result = SMB_VFS_NEXT_DISK_FREE(handle, path, small_query, bsize,
dfree, dsize);
/* Don't have a reasonable notion of failure here */
@@ -882,13 +861,12 @@ static SMB_BIG_UINT smb_full_audit_disk_free(vfs_handle_struct *handle,
}
static int smb_full_audit_get_quota(struct vfs_handle_struct *handle,
- struct connection_struct *conn,
enum SMB_QUOTA_TYPE qtype, unid_t id,
SMB_DISK_QUOTA *qt)
{
int result;
- result = SMB_VFS_NEXT_GET_QUOTA(handle, conn, qtype, id, qt);
+ result = SMB_VFS_NEXT_GET_QUOTA(handle, qtype, id, qt);
do_log(SMB_VFS_OP_GET_QUOTA, (result >= 0), handle, "");
@@ -897,13 +875,12 @@ static int smb_full_audit_get_quota(struct vfs_handle_struct *handle,
static int smb_full_audit_set_quota(struct vfs_handle_struct *handle,
- struct connection_struct *conn,
enum SMB_QUOTA_TYPE qtype, unid_t id,
SMB_DISK_QUOTA *qt)
{
int result;
- result = SMB_VFS_NEXT_SET_QUOTA(handle, conn, qtype, id, qt);
+ result = SMB_VFS_NEXT_SET_QUOTA(handle, qtype, id, qt);
do_log(SMB_VFS_OP_SET_QUOTA, (result >= 0), handle, "");
@@ -924,25 +901,24 @@ static int smb_full_audit_get_shadow_copy_data(struct vfs_handle_struct *handle,
}
static int smb_full_audit_statvfs(struct vfs_handle_struct *handle,
- struct connection_struct *conn,
const char *path,
struct vfs_statvfs_struct *statbuf)
{
int result;
- result = SMB_VFS_NEXT_STATVFS(handle, conn, path, statbuf);
+ result = SMB_VFS_NEXT_STATVFS(handle, path, statbuf);
do_log(SMB_VFS_OP_STATVFS, (result >= 0), handle, "");
return result;
}
-static SMB_STRUCT_DIR *smb_full_audit_opendir(vfs_handle_struct *handle, connection_struct *conn,
+static SMB_STRUCT_DIR *smb_full_audit_opendir(vfs_handle_struct *handle,
const char *fname, const char *mask, uint32 attr)
{
SMB_STRUCT_DIR *result;
- result = SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr);
+ result = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
do_log(SMB_VFS_OP_OPENDIR, (result != NULL), handle, "%s", fname);
@@ -950,11 +926,11 @@ static SMB_STRUCT_DIR *smb_full_audit_opendir(vfs_handle_struct *handle, connect
}
static SMB_STRUCT_DIRENT *smb_full_audit_readdir(vfs_handle_struct *handle,
- connection_struct *conn, SMB_STRUCT_DIR *dirp)
+ SMB_STRUCT_DIR *dirp)
{
SMB_STRUCT_DIRENT *result;
- result = SMB_VFS_NEXT_READDIR(handle, conn, dirp);
+ result = SMB_VFS_NEXT_READDIR(handle, dirp);
/* This operation has no reasonable error condition
* (End of dir is also failure), so always succeed.
@@ -964,78 +940,78 @@ static SMB_STRUCT_DIRENT *smb_full_audit_readdir(vfs_handle_struct *handle,
return result;
}
-static void smb_full_audit_seekdir(vfs_handle_struct *handle, connection_struct *conn,
+static void smb_full_audit_seekdir(vfs_handle_struct *handle,
SMB_STRUCT_DIR *dirp, long offset)
{
- SMB_VFS_NEXT_SEEKDIR(handle, conn, dirp, offset);
+ SMB_VFS_NEXT_SEEKDIR(handle, dirp, offset);
do_log(SMB_VFS_OP_SEEKDIR, True, handle, "");
return;
}
-static long smb_full_audit_telldir(vfs_handle_struct *handle, connection_struct *conn,
+static long smb_full_audit_telldir(vfs_handle_struct *handle,
SMB_STRUCT_DIR *dirp)
{
long result;
- result = SMB_VFS_NEXT_TELLDIR(handle, conn, dirp);
+ result = SMB_VFS_NEXT_TELLDIR(handle, dirp);
do_log(SMB_VFS_OP_TELLDIR, True, handle, "");
return result;
}
-static void smb_full_audit_rewinddir(vfs_handle_struct *handle, connection_struct *conn,
+static void smb_full_audit_rewinddir(vfs_handle_struct *handle,
SMB_STRUCT_DIR *dirp)
{
- SMB_VFS_NEXT_REWINDDIR(handle, conn, dirp);
+ SMB_VFS_NEXT_REWINDDIR(handle, dirp);
do_log(SMB_VFS_OP_REWINDDIR, True, handle, "");
return;
}
-static int smb_full_audit_mkdir(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_mkdir(vfs_handle_struct *handle,
const char *path, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_MKDIR(handle, conn, path, mode);
+ result = SMB_VFS_NEXT_MKDIR(handle, path, mode);
do_log(SMB_VFS_OP_MKDIR, (result >= 0), handle, "%s", path);
return result;
}
-static int smb_full_audit_rmdir(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_rmdir(vfs_handle_struct *handle,
const char *path)
{
int result;
- result = SMB_VFS_NEXT_RMDIR(handle, conn, path);
+ result = SMB_VFS_NEXT_RMDIR(handle, path);
do_log(SMB_VFS_OP_RMDIR, (result >= 0), handle, "%s", path);
return result;
}
-static int smb_full_audit_closedir(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_closedir(vfs_handle_struct *handle,
SMB_STRUCT_DIR *dirp)
{
int result;
- result = SMB_VFS_NEXT_CLOSEDIR(handle, conn, dirp);
+ result = SMB_VFS_NEXT_CLOSEDIR(handle, dirp);
do_log(SMB_VFS_OP_CLOSEDIR, (result >= 0), handle, "");
return result;
}
-static int smb_full_audit_open(vfs_handle_struct *handle, connection_struct *conn,
- const char *fname, int flags, mode_t mode)
+static int smb_full_audit_open(vfs_handle_struct *handle,
+ const char *fname, files_struct *fsp, int flags, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode);
+ result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
do_log(SMB_VFS_OP_OPEN, (result >= 0), handle, "%s|%s",
((flags & O_WRONLY) || (flags & O_RDWR))?"w":"r",
@@ -1133,12 +1109,12 @@ static ssize_t smb_full_audit_sendfile(vfs_handle_struct *handle, int tofd,
return result;
}
-static int smb_full_audit_rename(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_rename(vfs_handle_struct *handle,
const char *oldname, const char *newname)
{
int result;
- result = SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname);
+ result = SMB_VFS_NEXT_RENAME(handle, oldname, newname);
do_log(SMB_VFS_OP_RENAME, (result >= 0), handle, "%s|%s", oldname, newname);
@@ -1156,12 +1132,12 @@ static int smb_full_audit_fsync(vfs_handle_struct *handle, files_struct *fsp, in
return result;
}
-static int smb_full_audit_stat(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_stat(vfs_handle_struct *handle,
const char *fname, SMB_STRUCT_STAT *sbuf)
{
int result;
- result = SMB_VFS_NEXT_STAT(handle, conn, fname, sbuf);
+ result = SMB_VFS_NEXT_STAT(handle, fname, sbuf);
do_log(SMB_VFS_OP_STAT, (result >= 0), handle, "%s", fname);
@@ -1180,36 +1156,36 @@ static int smb_full_audit_fstat(vfs_handle_struct *handle, files_struct *fsp, in
return result;
}
-static int smb_full_audit_lstat(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_lstat(vfs_handle_struct *handle,
const char *path, SMB_STRUCT_STAT *sbuf)
{
int result;
- result = SMB_VFS_NEXT_LSTAT(handle, conn, path, sbuf);
+ result = SMB_VFS_NEXT_LSTAT(handle, path, sbuf);
do_log(SMB_VFS_OP_LSTAT, (result >= 0), handle, "%s", path);
return result;
}
-static int smb_full_audit_unlink(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_unlink(vfs_handle_struct *handle,
const char *path)
{
int result;
- result = SMB_VFS_NEXT_UNLINK(handle, conn, path);
+ result = SMB_VFS_NEXT_UNLINK(handle, path);
do_log(SMB_VFS_OP_UNLINK, (result >= 0), handle, "%s", path);
return result;
}
-static int smb_full_audit_chmod(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_chmod(vfs_handle_struct *handle,
const char *path, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode);
+ result = SMB_VFS_NEXT_CHMOD(handle, path, mode);
do_log(SMB_VFS_OP_CHMOD, (result >= 0), handle, "%s|%o", path, mode);
@@ -1229,12 +1205,12 @@ static int smb_full_audit_fchmod(vfs_handle_struct *handle, files_struct *fsp, i
return result;
}
-static int smb_full_audit_chown(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_chown(vfs_handle_struct *handle,
const char *path, uid_t uid, gid_t gid)
{
int result;
- result = SMB_VFS_NEXT_CHOWN(handle, conn, path, uid, gid);
+ result = SMB_VFS_NEXT_CHOWN(handle, path, uid, gid);
do_log(SMB_VFS_OP_CHOWN, (result >= 0), handle, "%s|%ld|%ld",
path, (long int)uid, (long int)gid);
@@ -1255,36 +1231,36 @@ static int smb_full_audit_fchown(vfs_handle_struct *handle, files_struct *fsp, i
return result;
}
-static int smb_full_audit_chdir(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_chdir(vfs_handle_struct *handle,
const char *path)
{
int result;
- result = SMB_VFS_NEXT_CHDIR(handle, conn, path);
+ result = SMB_VFS_NEXT_CHDIR(handle, path);
do_log(SMB_VFS_OP_CHDIR, (result >= 0), handle, "chdir|%s", path);
return result;
}
-static char *smb_full_audit_getwd(vfs_handle_struct *handle, connection_struct *conn,
+static char *smb_full_audit_getwd(vfs_handle_struct *handle,
char *path)
{
char *result;
- result = SMB_VFS_NEXT_GETWD(handle, conn, path);
+ result = SMB_VFS_NEXT_GETWD(handle, path);
do_log(SMB_VFS_OP_GETWD, (result != NULL), handle, "%s", path);
return result;
}
-static int smb_full_audit_utime(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_utime(vfs_handle_struct *handle,
const char *path, struct utimbuf *times)
{
int result;
- result = SMB_VFS_NEXT_UTIME(handle, conn, path, times);
+ result = SMB_VFS_NEXT_UTIME(handle, path, times);
do_log(SMB_VFS_OP_UTIME, (result >= 0), handle, "%s", path);
@@ -1328,12 +1304,12 @@ static BOOL smb_full_audit_getlock(vfs_handle_struct *handle, files_struct *fsp,
return result;
}
-static int smb_full_audit_symlink(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_symlink(vfs_handle_struct *handle,
const char *oldpath, const char *newpath)
{
int result;
- result = SMB_VFS_NEXT_SYMLINK(handle, conn, oldpath, newpath);
+ result = SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
do_log(SMB_VFS_OP_SYMLINK, (result >= 0), handle,
"%s|%s", oldpath, newpath);
@@ -1341,24 +1317,24 @@ static int smb_full_audit_symlink(vfs_handle_struct *handle, connection_struct *
return result;
}
-static int smb_full_audit_readlink(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_readlink(vfs_handle_struct *handle,
const char *path, char *buf, size_t bufsiz)
{
int result;
- result = SMB_VFS_NEXT_READLINK(handle, conn, path, buf, bufsiz);
+ result = SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz);
do_log(SMB_VFS_OP_READLINK, (result >= 0), handle, "%s", path);
return result;
}
-static int smb_full_audit_link(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_link(vfs_handle_struct *handle,
const char *oldpath, const char *newpath)
{
int result;
- result = SMB_VFS_NEXT_LINK(handle, conn, oldpath, newpath);
+ result = SMB_VFS_NEXT_LINK(handle, oldpath, newpath);
do_log(SMB_VFS_OP_LINK, (result >= 0), handle,
"%s|%s", oldpath, newpath);
@@ -1366,24 +1342,24 @@ static int smb_full_audit_link(vfs_handle_struct *handle, connection_struct *con
return result;
}
-static int smb_full_audit_mknod(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_mknod(vfs_handle_struct *handle,
const char *pathname, mode_t mode, SMB_DEV_T dev)
{
int result;
- result = SMB_VFS_NEXT_MKNOD(handle, conn, pathname, mode, dev);
+ result = SMB_VFS_NEXT_MKNOD(handle, pathname, mode, dev);
do_log(SMB_VFS_OP_MKNOD, (result >= 0), handle, "%s", pathname);
return result;
}
-static char *smb_full_audit_realpath(vfs_handle_struct *handle, connection_struct *conn,
+static char *smb_full_audit_realpath(vfs_handle_struct *handle,
const char *path, char *resolved_path)
{
char *result;
- result = SMB_VFS_NEXT_REALPATH(handle, conn, path, resolved_path);
+ result = SMB_VFS_NEXT_REALPATH(handle, path, resolved_path);
do_log(SMB_VFS_OP_REALPATH, (result != NULL), handle, "%s", path);
@@ -1448,12 +1424,12 @@ static BOOL smb_full_audit_set_nt_acl(vfs_handle_struct *handle, files_struct *f
return result;
}
-static int smb_full_audit_chmod_acl(vfs_handle_struct *handle, connection_struct *conn,
+static int smb_full_audit_chmod_acl(vfs_handle_struct *handle,
const char *path, mode_t mode)
{
int result;
- result = SMB_VFS_NEXT_CHMOD_ACL(handle, conn, path, mode);
+ result = SMB_VFS_NEXT_CHMOD_ACL(handle, path, mode);
do_log(SMB_VFS_OP_CHMOD_ACL, (result >= 0), handle,
"%s|%o", path, mode);
@@ -1475,13 +1451,13 @@ static int smb_full_audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fs
}
static int smb_full_audit_sys_acl_get_entry(vfs_handle_struct *handle,
- connection_struct *conn,
+
SMB_ACL_T theacl, int entry_id,
SMB_ACL_ENTRY_T *entry_p)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_GET_ENTRY(handle, conn, theacl, entry_id,
+ result = SMB_VFS_NEXT_SYS_ACL_GET_ENTRY(handle, theacl, entry_id,
entry_p);
do_log(SMB_VFS_OP_SYS_ACL_GET_ENTRY, (result >= 0), handle,
@@ -1491,13 +1467,13 @@ static int smb_full_audit_sys_acl_get_entry(vfs_handle_struct *handle,
}
static int smb_full_audit_sys_acl_get_tag_type(vfs_handle_struct *handle,
- connection_struct *conn,
+
SMB_ACL_ENTRY_T entry_d,
SMB_ACL_TAG_T *tag_type_p)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_GET_TAG_TYPE(handle, conn, entry_d,
+ result = SMB_VFS_NEXT_SYS_ACL_GET_TAG_TYPE(handle, entry_d,
tag_type_p);
do_log(SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE, (result >= 0), handle,
@@ -1507,13 +1483,13 @@ static int smb_full_audit_sys_acl_get_tag_type(vfs_handle_struct *handle,
}
static int smb_full_audit_sys_acl_get_permset(vfs_handle_struct *handle,
- connection_struct *conn,
+
SMB_ACL_ENTRY_T entry_d,
SMB_ACL_PERMSET_T *permset_p)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_GET_PERMSET(handle, conn, entry_d,
+ result = SMB_VFS_NEXT_SYS_ACL_GET_PERMSET(handle, entry_d,
permset_p);
do_log(SMB_VFS_OP_SYS_ACL_GET_PERMSET, (result >= 0), handle,
@@ -1523,12 +1499,12 @@ static int smb_full_audit_sys_acl_get_permset(vfs_handle_struct *handle,
}
static void * smb_full_audit_sys_acl_get_qualifier(vfs_handle_struct *handle,
- connection_struct *conn,
+
SMB_ACL_ENTRY_T entry_d)
{
void *result;
- result = SMB_VFS_NEXT_SYS_ACL_GET_QUALIFIER(handle, conn, entry_d);
+ result = SMB_VFS_NEXT_SYS_ACL_GET_QUALIFIER(handle, entry_d);
do_log(SMB_VFS_OP_SYS_ACL_GET_QUALIFIER, (result != NULL), handle,
"");
@@ -1537,13 +1513,12 @@ static void * smb_full_audit_sys_acl_get_qualifier(vfs_handle_struct *handle,
}
static SMB_ACL_T smb_full_audit_sys_acl_get_file(vfs_handle_struct *handle,
- connection_struct *conn,
const char *path_p,
SMB_ACL_TYPE_T type)
{
SMB_ACL_T result;
- result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, conn, path_p, type);
+ result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type);
do_log(SMB_VFS_OP_SYS_ACL_GET_FILE, (result != NULL), handle,
"%s", path_p);
@@ -1565,12 +1540,12 @@ static SMB_ACL_T smb_full_audit_sys_acl_get_fd(vfs_handle_struct *handle,
}
static int smb_full_audit_sys_acl_clear_perms(vfs_handle_struct *handle,
- connection_struct *conn,
+
SMB_ACL_PERMSET_T permset)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_CLEAR_PERMS(handle, conn, permset);
+ result = SMB_VFS_NEXT_SYS_ACL_CLEAR_PERMS(handle, permset);
do_log(SMB_VFS_OP_SYS_ACL_CLEAR_PERMS, (result >= 0), handle,
"");
@@ -1579,13 +1554,13 @@ static int smb_full_audit_sys_acl_clear_perms(vfs_handle_struct *handle,
}
static int smb_full_audit_sys_acl_add_perm(vfs_handle_struct *handle,
- connection_struct *conn,
+
SMB_ACL_PERMSET_T permset,
SMB_ACL_PERM_T perm)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_ADD_PERM(handle, conn, permset, perm);
+ result = SMB_VFS_NEXT_SYS_ACL_ADD_PERM(handle, permset, perm);
do_log(SMB_VFS_OP_SYS_ACL_ADD_PERM, (result >= 0), handle,
"");
@@ -1594,12 +1569,12 @@ static int smb_full_audit_sys_acl_add_perm(vfs_handle_struct *handle,
}
static char * smb_full_audit_sys_acl_to_text(vfs_handle_struct *handle,
- connection_struct *conn, SMB_ACL_T theacl,
+ SMB_ACL_T theacl,
ssize_t *plen)
{
char * result;
- result = SMB_VFS_NEXT_SYS_ACL_TO_TEXT(handle, conn, theacl, plen);
+ result = SMB_VFS_NEXT_SYS_ACL_TO_TEXT(handle, theacl, plen);
do_log(SMB_VFS_OP_SYS_ACL_TO_TEXT, (result != NULL), handle,
"");
@@ -1608,12 +1583,12 @@ static char * smb_full_audit_sys_acl_to_text(vfs_handle_struct *handle,
}
static SMB_ACL_T smb_full_audit_sys_acl_init(vfs_handle_struct *handle,
- connection_struct *conn,
+
int count)
{
SMB_ACL_T result;
- result = SMB_VFS_NEXT_SYS_ACL_INIT(handle, conn, count);
+ result = SMB_VFS_NEXT_SYS_ACL_INIT(handle, count);
do_log(SMB_VFS_OP_SYS_ACL_INIT, (result != NULL), handle,
"");
@@ -1622,12 +1597,12 @@ static SMB_ACL_T smb_full_audit_sys_acl_init(vfs_handle_struct *handle,
}
static int smb_full_audit_sys_acl_create_entry(vfs_handle_struct *handle,
- connection_struct *conn, SMB_ACL_T *pacl,
+ SMB_ACL_T *pacl,
SMB_ACL_ENTRY_T *pentry)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_CREATE_ENTRY(handle, conn, pacl, pentry);
+ result = SMB_VFS_NEXT_SYS_ACL_CREATE_ENTRY(handle, pacl, pentry);
do_log(SMB_VFS_OP_SYS_ACL_CREATE_ENTRY, (result >= 0), handle,
"");
@@ -1636,13 +1611,13 @@ static int smb_full_audit_sys_acl_create_entry(vfs_handle_struct *handle,
}
static int smb_full_audit_sys_acl_set_tag_type(vfs_handle_struct *handle,
- connection_struct *conn,
+
SMB_ACL_ENTRY_T entry,
SMB_ACL_TAG_T tagtype)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_SET_TAG_TYPE(handle, conn, entry,
+ result = SMB_VFS_NEXT_SYS_ACL_SET_TAG_TYPE(handle, entry,
tagtype);
do_log(SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE, (result >= 0), handle,
@@ -1652,13 +1627,13 @@ static int smb_full_audit_sys_acl_set_tag_type(vfs_handle_struct *handle,
}
static int smb_full_audit_sys_acl_set_qualifier(vfs_handle_struct *handle,
- connection_struct *conn,
+
SMB_ACL_ENTRY_T entry,
void *qual)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_SET_QUALIFIER(handle, conn, entry, qual);
+ result = SMB_VFS_NEXT_SYS_ACL_SET_QUALIFIER(handle, entry, qual);
do_log(SMB_VFS_OP_SYS_ACL_SET_QUALIFIER, (result >= 0), handle,
"");
@@ -1667,13 +1642,13 @@ static int smb_full_audit_sys_acl_set_qualifier(vfs_handle_struct *handle,
}
static int smb_full_audit_sys_acl_set_permset(vfs_handle_struct *handle,
- connection_struct *conn,
+
SMB_ACL_ENTRY_T entry,
SMB_ACL_PERMSET_T permset)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_SET_PERMSET(handle, conn, entry, permset);
+ result = SMB_VFS_NEXT_SYS_ACL_SET_PERMSET(handle, entry, permset);
do_log(SMB_VFS_OP_SYS_ACL_SET_PERMSET, (result >= 0), handle,
"");
@@ -1682,12 +1657,12 @@ static int smb_full_audit_sys_acl_set_permset(vfs_handle_struct *handle,
}
static int smb_full_audit_sys_acl_valid(vfs_handle_struct *handle,
- connection_struct *conn,
+
SMB_ACL_T theacl )
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_VALID(handle, conn, theacl);
+ result = SMB_VFS_NEXT_SYS_ACL_VALID(handle, theacl);
do_log(SMB_VFS_OP_SYS_ACL_VALID, (result >= 0), handle,
"");
@@ -1696,13 +1671,13 @@ static int smb_full_audit_sys_acl_valid(vfs_handle_struct *handle,
}
static int smb_full_audit_sys_acl_set_file(vfs_handle_struct *handle,
- connection_struct *conn,
+
const char *name, SMB_ACL_TYPE_T acltype,
SMB_ACL_T theacl)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, conn, name, acltype,
+ result = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, name, acltype,
theacl);
do_log(SMB_VFS_OP_SYS_ACL_SET_FILE, (result >= 0), handle,
@@ -1725,12 +1700,12 @@ static int smb_full_audit_sys_acl_set_fd(vfs_handle_struct *handle, files_struct
}
static int smb_full_audit_sys_acl_delete_def_file(vfs_handle_struct *handle,
- connection_struct *conn,
+
const char *path)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, conn, path);
+ result = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, path);
do_log(SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, (result >= 0), handle,
"%s", path);
@@ -1739,13 +1714,13 @@ static int smb_full_audit_sys_acl_delete_def_file(vfs_handle_struct *handle,
}
static int smb_full_audit_sys_acl_get_perm(vfs_handle_struct *handle,
- connection_struct *conn,
+
SMB_ACL_PERMSET_T permset,
SMB_ACL_PERM_T perm)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_GET_PERM(handle, conn, permset, perm);
+ result = SMB_VFS_NEXT_SYS_ACL_GET_PERM(handle, permset, perm);
do_log(SMB_VFS_OP_SYS_ACL_GET_PERM, (result >= 0), handle,
"");
@@ -1754,12 +1729,12 @@ static int smb_full_audit_sys_acl_get_perm(vfs_handle_struct *handle,
}
static int smb_full_audit_sys_acl_free_text(vfs_handle_struct *handle,
- connection_struct *conn,
+
char *text)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_FREE_TEXT(handle, conn, text);
+ result = SMB_VFS_NEXT_SYS_ACL_FREE_TEXT(handle, text);
do_log(SMB_VFS_OP_SYS_ACL_FREE_TEXT, (result >= 0), handle,
"");
@@ -1768,12 +1743,12 @@ static int smb_full_audit_sys_acl_free_text(vfs_handle_struct *handle,
}
static int smb_full_audit_sys_acl_free_acl(vfs_handle_struct *handle,
- connection_struct *conn,
+
SMB_ACL_T posix_acl)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_FREE_ACL(handle, conn, posix_acl);
+ result = SMB_VFS_NEXT_SYS_ACL_FREE_ACL(handle, posix_acl);
do_log(SMB_VFS_OP_SYS_ACL_FREE_ACL, (result >= 0), handle,
"");
@@ -1782,13 +1757,12 @@ static int smb_full_audit_sys_acl_free_acl(vfs_handle_struct *handle,
}
static int smb_full_audit_sys_acl_free_qualifier(vfs_handle_struct *handle,
- connection_struct *conn,
void *qualifier,
SMB_ACL_TAG_T tagtype)
{
int result;
- result = SMB_VFS_NEXT_SYS_ACL_FREE_QUALIFIER(handle, conn, qualifier,
+ result = SMB_VFS_NEXT_SYS_ACL_FREE_QUALIFIER(handle, qualifier,
tagtype);
do_log(SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER, (result >= 0), handle,
@@ -1798,12 +1772,12 @@ static int smb_full_audit_sys_acl_free_qualifier(vfs_handle_struct *handle,
}
static ssize_t smb_full_audit_getxattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn, const char *path,
+ const char *path,
const char *name, void *value, size_t size)
{
ssize_t result;
- result = SMB_VFS_NEXT_GETXATTR(handle, conn, path, name, value, size);
+ result = SMB_VFS_NEXT_GETXATTR(handle, path, name, value, size);
do_log(SMB_VFS_OP_GETXATTR, (result >= 0), handle,
"%s|%s", path, name);
@@ -1812,13 +1786,12 @@ static ssize_t smb_full_audit_getxattr(struct vfs_handle_struct *handle,
}
static ssize_t smb_full_audit_lgetxattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn,
const char *path, const char *name,
void *value, size_t size)
{
ssize_t result;
- result = SMB_VFS_NEXT_LGETXATTR(handle, conn, path, name, value, size);
+ result = SMB_VFS_NEXT_LGETXATTR(handle, path, name, value, size);
do_log(SMB_VFS_OP_LGETXATTR, (result >= 0), handle,
"%s|%s", path, name);
@@ -1841,12 +1814,11 @@ static ssize_t smb_full_audit_fgetxattr(struct vfs_handle_struct *handle,
}
static ssize_t smb_full_audit_listxattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn,
const char *path, char *list, size_t size)
{
ssize_t result;
- result = SMB_VFS_NEXT_LISTXATTR(handle, conn, path, list, size);
+ result = SMB_VFS_NEXT_LISTXATTR(handle, path, list, size);
do_log(SMB_VFS_OP_LISTXATTR, (result >= 0), handle, "%s", path);
@@ -1854,12 +1826,11 @@ static ssize_t smb_full_audit_listxattr(struct vfs_handle_struct *handle,
}
static ssize_t smb_full_audit_llistxattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn,
const char *path, char *list, size_t size)
{
ssize_t result;
- result = SMB_VFS_NEXT_LLISTXATTR(handle, conn, path, list, size);
+ result = SMB_VFS_NEXT_LLISTXATTR(handle, path, list, size);
do_log(SMB_VFS_OP_LLISTXATTR, (result >= 0), handle, "%s", path);
@@ -1881,12 +1852,12 @@ static ssize_t smb_full_audit_flistxattr(struct vfs_handle_struct *handle,
}
static int smb_full_audit_removexattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn, const char *path,
+ const char *path,
const char *name)
{
int result;
- result = SMB_VFS_NEXT_REMOVEXATTR(handle, conn, path, name);
+ result = SMB_VFS_NEXT_REMOVEXATTR(handle, path, name);
do_log(SMB_VFS_OP_REMOVEXATTR, (result >= 0), handle,
"%s|%s", path, name);
@@ -1895,12 +1866,12 @@ static int smb_full_audit_removexattr(struct vfs_handle_struct *handle,
}
static int smb_full_audit_lremovexattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn, const char *path,
+ const char *path,
const char *name)
{
int result;
- result = SMB_VFS_NEXT_LREMOVEXATTR(handle, conn, path, name);
+ result = SMB_VFS_NEXT_LREMOVEXATTR(handle, path, name);
do_log(SMB_VFS_OP_LREMOVEXATTR, (result >= 0), handle,
"%s|%s", path, name);
@@ -1923,13 +1894,13 @@ static int smb_full_audit_fremovexattr(struct vfs_handle_struct *handle,
}
static int smb_full_audit_setxattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn, const char *path,
+ const char *path,
const char *name, const void *value, size_t size,
int flags)
{
int result;
- result = SMB_VFS_NEXT_SETXATTR(handle, conn, path, name, value, size,
+ result = SMB_VFS_NEXT_SETXATTR(handle, path, name, value, size,
flags);
do_log(SMB_VFS_OP_SETXATTR, (result >= 0), handle,
@@ -1939,13 +1910,13 @@ static int smb_full_audit_setxattr(struct vfs_handle_struct *handle,
}
static int smb_full_audit_lsetxattr(struct vfs_handle_struct *handle,
- struct connection_struct *conn, const char *path,
+ const char *path,
const char *name, const void *value, size_t size,
int flags)
{
int result;
- result = SMB_VFS_NEXT_LSETXATTR(handle, conn, path, name, value, size,
+ result = SMB_VFS_NEXT_LSETXATTR(handle, path, name, value, size,
flags);
do_log(SMB_VFS_OP_LSETXATTR, (result >= 0), handle,
diff --git a/source/modules/vfs_netatalk.c b/source/modules/vfs_netatalk.c
index e9d4360cd80..279160d9665 100644
--- a/source/modules/vfs_netatalk.c
+++ b/source/modules/vfs_netatalk.c
@@ -172,11 +172,11 @@ static void atalk_rrmdir(TALLOC_CTX *ctx, char *path)
/* Directory operations */
-SMB_STRUCT_DIR *atalk_opendir(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *fname, const char *mask, uint32 attr)
+SMB_STRUCT_DIR *atalk_opendir(struct vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
{
SMB_STRUCT_DIR *ret = 0;
- ret = SMB_VFS_NEXT_OPENDIR(handle, conn, fname, mask, attr);
+ ret = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
/*
* when we try to perform delete operation upon file which has fork
@@ -187,19 +187,19 @@ SMB_STRUCT_DIR *atalk_opendir(struct vfs_handle_struct *handle, struct connectio
* list then it would be nice to add one.
*/
- atalk_add_to_list(&conn->hide_list);
- atalk_add_to_list(&conn->veto_list);
+ atalk_add_to_list(&handle->conn->hide_list);
+ atalk_add_to_list(&handle->conn->veto_list);
return ret;
}
-static int atalk_rmdir(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path)
+static int atalk_rmdir(struct vfs_handle_struct *handle, const char *path)
{
BOOL add = False;
TALLOC_CTX *ctx = 0;
char *dpath;
- if (!conn || !conn->origpath || !path) goto exit_rmdir;
+ if (!handle->conn->origpath || !path) goto exit_rmdir;
/* due to there is no way to change bDeleteVetoFiles variable
* from this module, gotta use talloc stuff..
@@ -211,19 +211,19 @@ static int atalk_rmdir(struct vfs_handle_struct *handle, struct connection_struc
goto exit_rmdir;
if (!(dpath = talloc_asprintf(ctx, "%s/%s%s",
- conn->origpath, path, add ? "/"APPLEDOUBLE : "")))
+ handle->conn->origpath, path, add ? "/"APPLEDOUBLE : "")))
goto exit_rmdir;
atalk_rrmdir(ctx, dpath);
exit_rmdir:
talloc_destroy(ctx);
- return SMB_VFS_NEXT_RMDIR(handle, conn, path);
+ return SMB_VFS_NEXT_RMDIR(handle, path);
}
/* File operations */
-static int atalk_rename(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *oldname, const char *newname)
+static int atalk_rename(struct vfs_handle_struct *handle, const char *oldname, const char *newname)
{
int ret = 0;
char *adbl_path = 0;
@@ -232,14 +232,14 @@ static int atalk_rename(struct vfs_handle_struct *handle, struct connection_stru
SMB_STRUCT_STAT orig_info;
TALLOC_CTX *ctx;
- ret = SMB_VFS_NEXT_RENAME(handle, conn, oldname, newname);
+ ret = SMB_VFS_NEXT_RENAME(handle, oldname, newname);
- if (!conn || !oldname) return ret;
+ if (!oldname) return ret;
if (!(ctx = talloc_init("rename_file")))
return ret;
- if (atalk_build_paths(ctx, conn->origpath, oldname, &adbl_path, &orig_path,
+ if (atalk_build_paths(ctx, handle->conn->origpath, oldname, &adbl_path, &orig_path,
&adbl_info, &orig_info) != 0)
return ret;
@@ -255,7 +255,7 @@ exit_rename:
return ret;
}
-static int atalk_unlink(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path)
+static int atalk_unlink(struct vfs_handle_struct *handle, const char *path)
{
int ret = 0, i;
char *adbl_path = 0;
@@ -264,25 +264,25 @@ static int atalk_unlink(struct vfs_handle_struct *handle, struct connection_stru
SMB_STRUCT_STAT orig_info;
TALLOC_CTX *ctx;
- ret = SMB_VFS_NEXT_UNLINK(handle, conn, path);
+ ret = SMB_VFS_NEXT_UNLINK(handle, path);
- if (!conn || !path) return ret;
+ if (!path) return ret;
/* no .AppleDouble sync if veto or hide list is empty,
* otherwise "Cannot find the specified file" error will be caused
*/
- if (!conn->veto_list) return ret;
- if (!conn->hide_list) return ret;
+ if (!handle->conn->veto_list) return ret;
+ if (!handle->conn->hide_list) return ret;
- for (i = 0; conn->veto_list[i].name; i ++) {
- if (strstr(conn->veto_list[i].name, APPLEDOUBLE))
+ for (i = 0; handle->conn->veto_list[i].name; i ++) {
+ if (strstr(handle->conn->veto_list[i].name, APPLEDOUBLE))
break;
}
- if (!conn->veto_list[i].name) {
- for (i = 0; conn->hide_list[i].name; i ++) {
- if (strstr(conn->hide_list[i].name, APPLEDOUBLE))
+ if (!handle->conn->veto_list[i].name) {
+ for (i = 0; handle->conn->hide_list[i].name; i ++) {
+ if (strstr(handle->conn->hide_list[i].name, APPLEDOUBLE))
break;
else {
DEBUG(3, ("ATALK: %s is not hidden, skipped..\n",
@@ -295,7 +295,7 @@ static int atalk_unlink(struct vfs_handle_struct *handle, struct connection_stru
if (!(ctx = talloc_init("unlink_file")))
return ret;
- if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
+ if (atalk_build_paths(ctx, handle->conn->origpath, path, &adbl_path, &orig_path,
&adbl_info, &orig_info) != 0)
return ret;
@@ -311,7 +311,7 @@ exit_unlink:
return ret;
}
-static int atalk_chmod(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, mode_t mode)
+static int atalk_chmod(struct vfs_handle_struct *handle, const char *path, mode_t mode)
{
int ret = 0;
char *adbl_path = 0;
@@ -320,14 +320,14 @@ static int atalk_chmod(struct vfs_handle_struct *handle, struct connection_struc
SMB_STRUCT_STAT orig_info;
TALLOC_CTX *ctx;
- ret = SMB_VFS_NEXT_CHMOD(handle, conn, path, mode);
+ ret = SMB_VFS_NEXT_CHMOD(handle, path, mode);
- if (!conn || !path) return ret;
+ if (!path) return ret;
if (!(ctx = talloc_init("chmod_file")))
return ret;
- if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
+ if (atalk_build_paths(ctx, handle->conn->origpath, path, &adbl_path, &orig_path,
&adbl_info, &orig_info) != 0)
return ret;
@@ -343,7 +343,7 @@ exit_chmod:
return ret;
}
-static int atalk_chown(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, uid_t uid, gid_t gid)
+static int atalk_chown(struct vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
{
int ret = 0;
char *adbl_path = 0;
@@ -352,14 +352,14 @@ static int atalk_chown(struct vfs_handle_struct *handle, struct connection_struc
SMB_STRUCT_STAT orig_info;
TALLOC_CTX *ctx;
- ret = SMB_VFS_NEXT_CHOWN(handle, conn, path, uid, gid);
+ ret = SMB_VFS_NEXT_CHOWN(handle, path, uid, gid);
- if (!conn || !path) return ret;
+ if (!path) return ret;
if (!(ctx = talloc_init("chown_file")))
return ret;
- if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path,
+ if (atalk_build_paths(ctx, handle->conn->origpath, path, &adbl_path, &orig_path,
&adbl_info, &orig_info) != 0)
return ret;
diff --git a/source/modules/vfs_prealloc.c b/source/modules/vfs_prealloc.c
new file mode 100644
index 00000000000..94db6423700
--- /dev/null
+++ b/source/modules/vfs_prealloc.c
@@ -0,0 +1,214 @@
+/*
+ * XFS preallocation support module.
+ *
+ * Copyright (c) James Peach 2006
+ *
+ * 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"
+
+/* Extent preallocation module.
+ *
+ * The purpose of this module is to preallocate space on the filesystem when
+ * we have a good idea of how large files are supposed to be. This lets writes
+ * proceed without having to allocate new extents and results in better file
+ * layouts on disk.
+ *
+ * Currently only implemented for XFS. This module is based on an original idea
+ * and implementation by Sebastian Brings.
+ *
+ * Tunables.
+ *
+ * prealloc: <ext> Number of bytes to preallocate for a file with
+ * the matching extension.
+ * prealloc:debug Debug level at which to emit messages.
+ *
+ * Example.
+ *
+ * prealloc:mpeg = 500M # Preallocate *.mpeg to 500 MiB.
+ */
+
+#ifdef HAVE_XFS_LIBXFS_H
+#include <xfs/libxfs.h>
+#define lock_type xfs_flock64_t
+#else
+#define lock_type struct flock64
+#endif
+
+#define MODULE "prealloc"
+static int module_debug;
+
+static int preallocate_space(int fd, SMB_OFF_T size)
+{
+ lock_type fl = {0};
+ int err;
+
+ if (size <= 0) {
+ return 0;
+ }
+
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = size;
+
+ /* IMPORTANT: We use RESVSP because we want the extents to be
+ * allocated, but we don't want the allocation to show up in
+ * st_size or persist after the close(2).
+ */
+
+#if defined(XFS_IOC_RESVSP64)
+ /* On Linux this comes in via libxfs.h. */
+ err = xfsctl(NULL, fd, XFS_IOC_RESVSP64, &fl);
+#elif defined(F_RESVSP64)
+ /* On IRIX, this comes from fcntl.h. */
+ err = fcntl(fd, F_RESVSP64, &fl);
+#else
+ err = -1;
+ errno = ENOSYS;
+#endif
+
+ if (err) {
+ DEBUG(module_debug,
+ ("%s: preallocate failed on fd=%d size=%lld: %s\n",
+ MODULE, fd, (long long)size, strerror(errno)));
+ }
+
+ return err;
+}
+
+static int prealloc_connect(
+ struct vfs_handle_struct * handle,
+ const char * service,
+ const char * user)
+{
+ module_debug = lp_parm_int(SNUM(handle->conn),
+ MODULE, "debug", 100);
+
+ return SMB_VFS_NEXT_CONNECT(handle, service, user);
+}
+
+static int prealloc_open(vfs_handle_struct* handle,
+ const char * fname,
+ files_struct * fsp,
+ int flags,
+ mode_t mode)
+{
+ int fd;
+ off64_t size = 0;
+
+ const char * dot;
+ char fext[10];
+
+ if (!(flags & (O_CREAT|O_TRUNC))) {
+ /* Caller is not intending to rewrite the file. Let's not mess
+ * with the allocation in this case.
+ */
+ goto normal_open;
+ }
+
+ *fext = '\0';
+ dot = strrchr(fname, '.');
+ if (dot && *++dot) {
+ if (strlen(dot) < sizeof(fext)) {
+ strncpy(fext, dot, sizeof(fext));
+ strnorm(fext, CASE_LOWER);
+ }
+ }
+
+ if (*fext == '\0') {
+ goto normal_open;
+ }
+
+ /* Syntax for specifying preallocation size is:
+ * MODULE: <extension> = <size>
+ * where
+ * <extension> is the file extension in lower case
+ * <size> is a size like 10, 10K, 10M
+ */
+ size = conv_str_size(lp_parm_const_string(SNUM(handle->conn), MODULE,
+ fext, NULL));
+ if (size <= 0) {
+ /* No need to preallocate this file. */
+ goto normal_open;
+ }
+
+ fd = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+ if (fd < 0) {
+ return fd;
+ }
+
+ /* Prellocate only if the file is being created or replaced. Note that
+ * Samba won't ever pass down O_TRUNC, which is why we have to handle
+ * truncate calls specially.
+ */
+ if ((flags & O_CREAT) || (flags & O_TRUNC)) {
+ SMB_OFF_T * psize;
+
+ psize = VFS_ADD_FSP_EXTENSION(handle, fsp, SMB_OFF_T);
+ if (psize == NULL || *psize == -1) {
+ return fd;
+ }
+
+ DEBUG(module_debug,
+ ("%s: preallocating %s (fd=%d) to %lld bytes\n",
+ MODULE, fname, fd, (long long)size));
+
+ *psize = size;
+ if (preallocate_space(fd, *psize) < 0) {
+ VFS_REMOVE_FSP_EXTENSION(handle, fsp);
+ }
+ }
+
+ return fd;
+
+normal_open:
+ /* We are not creating or replacing a file. Skip the
+ * preallocation.
+ */
+ DEBUG(module_debug, ("%s: skipping preallocation for %s\n",
+ MODULE, fname));
+ return SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+}
+
+static int prealloc_ftruncate(vfs_handle_struct * handle,
+ files_struct * fsp,
+ int fd,
+ SMB_OFF_T offset)
+{
+ SMB_OFF_T *psize;
+ int ret = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, fd, offset);
+
+ /* Maintain the allocated space even in the face of truncates. */
+ if ((psize = VFS_FETCH_FSP_EXTENSION(handle, fsp))) {
+ preallocate_space(fd, *psize);
+ }
+
+ return ret;
+}
+
+static vfs_op_tuple prealloc_op_tuples[] = {
+ {SMB_VFS_OP(prealloc_open), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(prealloc_ftruncate), SMB_VFS_OP_FTRUNCATE, SMB_VFS_LAYER_TRANSPARENT},
+ {SMB_VFS_OP(prealloc_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
+ {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
+};
+
+NTSTATUS vfs_prealloc_init(void)
+{
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
+ MODULE, prealloc_op_tuples);
+}
+
diff --git a/source/modules/vfs_readonly.c b/source/modules/vfs_readonly.c
index ee9e40c2fca..e69f7dac016 100644
--- a/source/modules/vfs_readonly.c
+++ b/source/modules/vfs_readonly.c
@@ -55,7 +55,6 @@
#define MODULE_NAME "readonly"
static int readonly_connect(vfs_handle_struct *handle,
- connection_struct *conn,
const char *service,
const char *user)
{
@@ -71,10 +70,10 @@ static int readonly_connect(vfs_handle_struct *handle,
time_t end_period = get_date(period[1], &current_time);
if ((current_time >= begin_period) && (current_time <= end_period)) {
- conn->read_only = True;
+ handle->conn->read_only = True;
}
- return SMB_VFS_NEXT_CONNECT(handle, conn, service, user);
+ return SMB_VFS_NEXT_CONNECT(handle, service, user);
} else {
diff --git a/source/modules/vfs_recycle.c b/source/modules/vfs_recycle.c
index 42f2f51416e..4ffd683bfd5 100644
--- a/source/modules/vfs_recycle.c
+++ b/source/modules/vfs_recycle.c
@@ -32,9 +32,9 @@ static int vfs_recycle_debug_level = DBGC_VFS;
#undef DBGC_CLASS
#define DBGC_CLASS vfs_recycle_debug_level
-static int recycle_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user);
-static void recycle_disconnect(vfs_handle_struct *handle, connection_struct *conn);
-static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *name);
+static int recycle_connect(vfs_handle_struct *handle, const char *service, const char *user);
+static void recycle_disconnect(vfs_handle_struct *handle);
+static int recycle_unlink(vfs_handle_struct *handle, const char *name);
static vfs_op_tuple recycle_ops[] = {
@@ -48,20 +48,20 @@ static vfs_op_tuple recycle_ops[] = {
{SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
};
-static int recycle_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user)
+static int recycle_connect(vfs_handle_struct *handle, const char *service, const char *user)
{
DEBUG(10,("recycle_connect() connect to service[%s] as user[%s].\n",
service,user));
- return SMB_VFS_NEXT_CONNECT(handle, conn, service, user);
+ return SMB_VFS_NEXT_CONNECT(handle, service, user);
}
-static void recycle_disconnect(vfs_handle_struct *handle, connection_struct *conn)
+static void recycle_disconnect(vfs_handle_struct *handle)
{
DEBUG(10,("recycle_disconnect() connect to service[%s].\n",
- lp_servicename(SNUM(conn))));
+ lp_servicename(SNUM(handle->conn))));
- SMB_VFS_NEXT_DISCONNECT(handle, conn);
+ SMB_VFS_NEXT_DISCONNECT(handle);
}
static const char *recycle_repository(vfs_handle_struct *handle)
@@ -202,7 +202,7 @@ static BOOL recycle_directory_exist(vfs_handle_struct *handle, const char *dname
{
SMB_STRUCT_STAT st;
- if (SMB_VFS_NEXT_STAT(handle, handle->conn, dname, &st) == 0) {
+ if (SMB_VFS_NEXT_STAT(handle, dname, &st) == 0) {
if (S_ISDIR(st.st_mode)) {
return True;
}
@@ -215,7 +215,7 @@ static BOOL recycle_file_exist(vfs_handle_struct *handle, const char *fname)
{
SMB_STRUCT_STAT st;
- if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) == 0) {
+ if (SMB_VFS_NEXT_STAT(handle, fname, &st) == 0) {
if (S_ISREG(st.st_mode)) {
return True;
}
@@ -234,7 +234,7 @@ static SMB_OFF_T recycle_get_file_size(vfs_handle_struct *handle, const char *fn
{
SMB_STRUCT_STAT st;
- if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) != 0) {
+ if (SMB_VFS_NEXT_STAT(handle, fname, &st) != 0) {
DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno)));
return (SMB_OFF_T)0;
}
@@ -280,7 +280,7 @@ static BOOL recycle_create_dir(vfs_handle_struct *handle, const char *dname)
DEBUG(10, ("recycle: dir %s already exists\n", new_dir));
else {
DEBUG(5, ("recycle: creating new dir %s\n", new_dir));
- if (SMB_VFS_NEXT_MKDIR(handle, handle->conn, new_dir, mode) != 0) {
+ if (SMB_VFS_NEXT_MKDIR(handle, new_dir, mode) != 0) {
DEBUG(1,("recycle: mkdir failed for %s with error: %s\n", new_dir, strerror(errno)));
ret = False;
goto done;
@@ -354,7 +354,7 @@ static void recycle_do_touch(vfs_handle_struct *handle, const char *fname, BOOL
struct utimbuf tb;
time_t currtime;
- if (SMB_VFS_NEXT_STAT(handle, handle->conn, fname, &st) != 0) {
+ if (SMB_VFS_NEXT_STAT(handle, fname, &st) != 0) {
DEBUG(0,("recycle: stat for %s returned %s\n", fname, strerror(errno)));
return;
}
@@ -362,16 +362,19 @@ static void recycle_do_touch(vfs_handle_struct *handle, const char *fname, BOOL
tb.actime = currtime;
tb.modtime = touch_mtime ? currtime : st.st_mtime;
- if (SMB_VFS_NEXT_UTIME(handle, handle->conn, fname, &tb) == -1 ) {
+ if (SMB_VFS_NEXT_UTIME(handle, fname, &tb) == -1 ) {
DEBUG(0, ("recycle: touching %s failed, reason = %s\n", fname, strerror(errno)));
}
}
+extern userdom_struct current_user_info;
+
/**
* Check if file should be recycled
**/
-static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *file_name)
+static int recycle_unlink(vfs_handle_struct *handle, const char *file_name)
{
+ connection_struct *conn = handle->conn;
char *path_name = NULL;
char *temp_name = NULL;
char *final_name = NULL;
@@ -383,7 +386,12 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co
BOOL exist;
int rc = -1;
- repository = alloc_sub_conn(conn, recycle_repository(handle));
+ repository = talloc_sub_advanced(NULL, lp_servicename(SNUM(conn)),
+ conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ recycle_repository(handle));
ALLOC_CHECK(repository, done);
/* shouldn't we allow absolute path names here? --metze */
/* Yes :-). JRA. */
@@ -391,14 +399,14 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co
if(!repository || *(repository) == '\0') {
DEBUG(3, ("recycle: repository path not set, purging %s...\n", file_name));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
+ rc = SMB_VFS_NEXT_UNLINK(handle, file_name);
goto done;
}
/* we don't recycle the recycle bin... */
if (strncmp(file_name, repository, strlen(repository)) == 0) {
DEBUG(3, ("recycle: File is within recycling bin, unlinking ...\n"));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
+ rc = SMB_VFS_NEXT_UNLINK(handle, file_name);
goto done;
}
@@ -408,7 +416,7 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co
*
if(fsize == 0) {
DEBUG(3, ("recycle: File %s is empty, purging...\n", file_name));
- rc = SMB_VFS_NEXT_UNLINK(handle,conn,file_name);
+ rc = SMB_VFS_NEXT_UNLINK(handle,file_name);
goto done;
}
*/
@@ -420,18 +428,18 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co
maxsize = recycle_maxsize(handle);
if(maxsize > 0 && file_size > maxsize) {
DEBUG(3, ("recycle: File %s exceeds maximum recycle size, purging... \n", file_name));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
+ rc = SMB_VFS_NEXT_UNLINK(handle, file_name);
goto done;
}
/* FIXME: this is wrong: moving files with rename does not change the disk space
* allocation
*
- space_avail = SMB_VFS_NEXT_DISK_FREE(handle, conn, ".", True, &bsize, &dfree, &dsize) * 1024L;
+ space_avail = SMB_VFS_NEXT_DISK_FREE(handle, ".", True, &bsize, &dfree, &dsize) * 1024L;
DEBUG(5, ("space_avail = %Lu, file_size = %Lu\n", space_avail, file_size));
if(space_avail < file_size) {
DEBUG(3, ("recycle: Not enough diskspace, purging file %s\n", file_name));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
+ rc = SMB_VFS_NEXT_UNLINK(handle, file_name);
goto done;
}
*/
@@ -456,7 +464,7 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co
if (matchparam(recycle_exclude(handle), base)) {
DEBUG(3, ("recycle: file %s is excluded \n", base));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
+ rc = SMB_VFS_NEXT_UNLINK(handle, file_name);
goto done;
}
@@ -466,7 +474,7 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co
*/
if (checkparam(recycle_exclude_dir(handle), path_name)) {
DEBUG(3, ("recycle: directory %s is excluded \n", path_name));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
+ rc = SMB_VFS_NEXT_UNLINK(handle, file_name);
goto done;
}
@@ -484,7 +492,7 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co
DEBUG(10, ("recycle: Creating directory %s\n", temp_name));
if (recycle_create_dir(handle, temp_name) == False) {
DEBUG(3, ("recycle: Could not create directory, purging %s...\n", file_name));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
+ rc = SMB_VFS_NEXT_UNLINK(handle, file_name);
goto done;
}
}
@@ -497,7 +505,7 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co
if (recycle_file_exist(handle, final_name)) {
if (recycle_versions(handle) == False || matchparam(recycle_noversions(handle), base) == True) {
DEBUG(3, ("recycle: Removing old file %s from recycle bin\n", final_name));
- if (SMB_VFS_NEXT_UNLINK(handle, conn, final_name) != 0) {
+ if (SMB_VFS_NEXT_UNLINK(handle, final_name) != 0) {
DEBUG(1, ("recycle: Error deleting old file: %s\n", strerror(errno)));
}
}
@@ -511,10 +519,10 @@ static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, co
}
DEBUG(10, ("recycle: Moving %s to %s\n", file_name, final_name));
- rc = SMB_VFS_NEXT_RENAME(handle, conn, file_name, final_name);
+ rc = SMB_VFS_NEXT_RENAME(handle, file_name, final_name);
if (rc != 0) {
DEBUG(3, ("recycle: Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno), file_name, final_name));
- rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
+ rc = SMB_VFS_NEXT_UNLINK(handle, file_name);
goto done;
}
@@ -526,7 +534,7 @@ done:
SAFE_FREE(path_name);
SAFE_FREE(temp_name);
SAFE_FREE(final_name);
- SAFE_FREE(repository);
+ TALLOC_FREE(repository);
return rc;
}
diff --git a/source/modules/vfs_shadow_copy.c b/source/modules/vfs_shadow_copy.c
index db1c8d007dc..447c53d773a 100644
--- a/source/modules/vfs_shadow_copy.c
+++ b/source/modules/vfs_shadow_copy.c
@@ -72,10 +72,10 @@ static BOOL shadow_copy_match_name(const char *name)
return False;
}
-static SMB_STRUCT_DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr)
+static SMB_STRUCT_DIR *shadow_copy_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
{
shadow_copy_Dir *dirp;
- SMB_STRUCT_DIR *p = SMB_VFS_NEXT_OPENDIR(handle,conn,fname,mask,attr);
+ SMB_STRUCT_DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fname,mask,attr);
if (!p) {
DEBUG(0,("shadow_copy_opendir: SMB_VFS_NEXT_OPENDIR() failed for [%s]\n",fname));
@@ -85,7 +85,7 @@ static SMB_STRUCT_DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection
dirp = SMB_MALLOC_P(shadow_copy_Dir);
if (!dirp) {
DEBUG(0,("shadow_copy_opendir: Out of memory\n"));
- SMB_VFS_NEXT_CLOSEDIR(handle,conn,p);
+ SMB_VFS_NEXT_CLOSEDIR(handle,p);
return NULL;
}
@@ -94,7 +94,7 @@ static SMB_STRUCT_DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection
while (True) {
SMB_STRUCT_DIRENT *d;
- d = SMB_VFS_NEXT_READDIR(handle, conn, p);
+ d = SMB_VFS_NEXT_READDIR(handle, p);
if (d == NULL) {
break;
}
@@ -115,11 +115,11 @@ static SMB_STRUCT_DIR *shadow_copy_opendir(vfs_handle_struct *handle, connection
dirp->dirs[dirp->num++] = *d;
}
- SMB_VFS_NEXT_CLOSEDIR(handle,conn,p);
+ SMB_VFS_NEXT_CLOSEDIR(handle,p);
return((SMB_STRUCT_DIR *)dirp);
}
-SMB_STRUCT_DIRENT *shadow_copy_readdir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *_dirp)
+SMB_STRUCT_DIRENT *shadow_copy_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp)
{
shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
@@ -130,7 +130,7 @@ SMB_STRUCT_DIRENT *shadow_copy_readdir(vfs_handle_struct *handle, connection_str
return NULL;
}
-static void shadow_copy_seekdir(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *_dirp, long offset)
+static void shadow_copy_seekdir(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp, long offset)
{
shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
@@ -139,19 +139,19 @@ static void shadow_copy_seekdir(struct vfs_handle_struct *handle, struct connect
}
}
-static long shadow_copy_telldir(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *_dirp)
+static long shadow_copy_telldir(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp)
{
shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
return( dirp->pos ) ;
}
-static void shadow_copy_rewinddir(struct vfs_handle_struct *handle, struct connection_struct *conn, SMB_STRUCT_DIR *_dirp)
+static void shadow_copy_rewinddir(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp)
{
shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
dirp->pos = 0 ;
}
-int shadow_copy_closedir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *_dirp)
+int shadow_copy_closedir(vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp)
{
shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
@@ -163,7 +163,7 @@ int shadow_copy_closedir(vfs_handle_struct *handle, connection_struct *conn, SMB
static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels)
{
- SMB_STRUCT_DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fsp->conn,fsp->conn->connectpath,NULL,0);
+ SMB_STRUCT_DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fsp->conn->connectpath,NULL,0);
shadow_copy_data->num_volumes = 0;
shadow_copy_data->labels = NULL;
@@ -177,7 +177,7 @@ static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_str
SHADOW_COPY_LABEL *tlabels;
SMB_STRUCT_DIRENT *d;
- d = SMB_VFS_NEXT_READDIR(handle, fsp->conn, p);
+ d = SMB_VFS_NEXT_READDIR(handle, p);
if (d == NULL) {
break;
}
@@ -200,7 +200,7 @@ static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_str
(shadow_copy_data->num_volumes+1)*sizeof(SHADOW_COPY_LABEL));
if (tlabels == NULL) {
DEBUG(0,("shadow_copy_get_shadow_copy_data: Out of memory\n"));
- SMB_VFS_NEXT_CLOSEDIR(handle,fsp->conn,p);
+ SMB_VFS_NEXT_CLOSEDIR(handle,p);
return -1;
}
@@ -209,7 +209,7 @@ static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_str
shadow_copy_data->labels = tlabels;
}
- SMB_VFS_NEXT_CLOSEDIR(handle,fsp->conn,p);
+ SMB_VFS_NEXT_CLOSEDIR(handle,p);
return 0;
}
diff --git a/source/nmbd/nmbd_synclists.c b/source/nmbd/nmbd_synclists.c
index 28ad92ed108..7fe39676c6f 100644
--- a/source/nmbd/nmbd_synclists.c
+++ b/source/nmbd/nmbd_synclists.c
@@ -68,7 +68,7 @@ static void sync_child(char *name, int nm_type,
char *fname)
{
fstring unix_workgroup;
- static struct cli_state cli;
+ struct cli_state *cli;
uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0;
struct nmb_name called, calling;
@@ -76,50 +76,56 @@ static void sync_child(char *name, int nm_type,
* Patch from Andy Levine andyl@epicrealm.com.
*/
- if (!cli_initialise(&cli) || !cli_set_port(&cli, 139) || !cli_connect(&cli, name, &ip)) {
+ cli = cli_initialise();
+ if (!cli) {
+ return;
+ }
+
+ if (!cli_set_port(cli, 139) || !cli_connect(cli, name, &ip)) {
return;
}
make_nmb_name(&calling, local_machine, 0x0);
make_nmb_name(&called , name, nm_type);
- if (!cli_session_request(&cli, &calling, &called)) {
- cli_shutdown(&cli);
+ if (!cli_session_request(cli, &calling, &called)) {
+ cli_shutdown(cli);
return;
}
- if (!cli_negprot(&cli)) {
- cli_shutdown(&cli);
+ if (!cli_negprot(cli)) {
+ cli_shutdown(cli);
return;
}
- if (!cli_session_setup(&cli, "", "", 1, "", 0, workgroup)) {
- cli_shutdown(&cli);
+ if (!NT_STATUS_IS_OK(cli_session_setup(cli, "", "", 1, "", 0,
+ workgroup))) {
+ cli_shutdown(cli);
return;
}
- if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
- cli_shutdown(&cli);
+ if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) {
+ cli_shutdown(cli);
return;
}
/* All the cli_XX functions take UNIX character set. */
- fstrcpy(unix_workgroup, cli.server_domain?cli.server_domain:workgroup);
+ fstrcpy(unix_workgroup, cli->server_domain ? cli->server_domain : workgroup);
/* Fetch a workgroup list. */
- cli_NetServerEnum(&cli, unix_workgroup,
+ cli_NetServerEnum(cli, unix_workgroup,
local_type|SV_TYPE_DOMAIN_ENUM,
callback, NULL);
/* Now fetch a server list. */
if (servers) {
fstrcpy(unix_workgroup, workgroup);
- cli_NetServerEnum(&cli, unix_workgroup,
+ cli_NetServerEnum(cli, unix_workgroup,
local?SV_TYPE_LOCAL_LIST_ONLY:SV_TYPE_ALL,
callback, NULL);
}
- cli_shutdown(&cli);
+ cli_shutdown(cli);
}
/*******************************************************************
diff --git a/source/nsswitch/winbindd_cm.c b/source/nsswitch/winbindd_cm.c
index 0be7093c641..3f392c48259 100644
--- a/source/nsswitch/winbindd_cm.c
+++ b/source/nsswitch/winbindd_cm.c
@@ -426,7 +426,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
goto done;
}
- if ((*cli = cli_initialise(NULL)) == NULL) {
+ if ((*cli = cli_initialise()) == NULL) {
DEBUG(1, ("Could not cli_initialize\n"));
result = NT_STATUS_NO_MEMORY;
goto done;
@@ -538,10 +538,11 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
"[%s]\\[%s]\n", controller, global_myname(),
ipc_domain, ipc_username));
- if (cli_session_setup(*cli, ipc_username,
+ if (NT_STATUS_IS_OK(cli_session_setup(
+ *cli, ipc_username,
ipc_password, strlen(ipc_password)+1,
ipc_password, strlen(ipc_password)+1,
- ipc_domain)) {
+ ipc_domain))) {
/* Successful logon with given username. */
cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
goto session_setup_done;
@@ -553,7 +554,8 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
/* Fall back to anonymous connection, this might fail later */
- if (cli_session_setup(*cli, "", NULL, 0, NULL, 0, "")) {
+ if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
+ NULL, 0, ""))) {
DEBUG(5, ("Connected anonymously\n"));
cli_init_creds(*cli, "", "", "");
goto session_setup_done;
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 1c3afef1f52..5e39544420d 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -58,6 +58,7 @@ BOOL bLoaded = False;
extern pstring user_socket_options;
extern enum protocol_types Protocol;
+extern userdom_struct current_user_info;
#ifndef GLOBAL_NAME
#define GLOBAL_NAME "global"
@@ -1545,8 +1546,8 @@ static void init_globals(BOOL first_time_only)
Globals.map_to_guest = 0; /* By Default, "Never" */
Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
Globals.enhanced_browsing = True;
- Globals.iLockSpinCount = 3; /* Try 3 times. */
- Globals.iLockSpinTime = 10; /* usec. */
+ Globals.iLockSpinCount = 0; /* Unused. */
+ Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
#ifdef MMAP_BLACKLIST
Globals.bUseMmap = False;
#else
@@ -1702,11 +1703,13 @@ static char *lp_string(const char *s)
if (!lp_talloc)
lp_talloc = talloc_init("lp_talloc");
- tmpstr = alloc_sub_basic(get_current_username(), s);
+ tmpstr = alloc_sub_basic(get_current_username(),
+ current_user_info.domain, s);
if (trim_char(tmpstr, '\"', '\"')) {
if (strchr(tmpstr,'\"') != NULL) {
SAFE_FREE(tmpstr);
- tmpstr = alloc_sub_basic(get_current_username(),s);
+ tmpstr = alloc_sub_basic(get_current_username(),
+ current_user_info.domain, s);
}
}
ret = talloc_strdup(lp_talloc, tmpstr);
@@ -1947,7 +1950,7 @@ FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout
FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
-FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
+FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
FN_LOCAL_STRING(lp_preexec, szPreExec)
@@ -2015,9 +2018,9 @@ FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
-FN_LOCAL_BOOL(lp_locking, bLocking)
-FN_LOCAL_INTEGER(lp_strict_locking, iStrictLocking)
-FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
+FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
+FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
+FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
FN_LOCAL_BOOL(lp_share_modes, bShareModes)
FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
@@ -3009,7 +3012,9 @@ BOOL lp_file_list_changed(void)
time_t mod_time;
pstrcpy(n2, f->name);
- standard_sub_basic( get_current_username(), n2, sizeof(n2) );
+ standard_sub_basic( get_current_username(),
+ current_user_info.domain,
+ n2, sizeof(n2) );
DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
f->name, n2, ctime(&f->modtime)));
@@ -3043,7 +3048,8 @@ static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
pstrcpy(netbios_name, pszParmValue);
- standard_sub_basic(get_current_username(), netbios_name,sizeof(netbios_name));
+ standard_sub_basic(get_current_username(), current_user_info.domain,
+ netbios_name, sizeof(netbios_name));
ret = set_global_myname(netbios_name);
string_set(&Globals.szNetbiosName,global_myname());
@@ -3101,7 +3107,8 @@ static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
pstring fname;
pstrcpy(fname, pszParmValue);
- standard_sub_basic(get_current_username(), fname,sizeof(fname));
+ standard_sub_basic(get_current_username(), current_user_info.domain,
+ fname,sizeof(fname));
add_to_file_list(pszParmValue, fname);
@@ -3859,7 +3866,6 @@ static void dump_a_service(service * pService, FILE * f)
BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
{
- service * pService = ServicePtrs[snum];
int i;
BOOL result = False;
parm_class p_class;
@@ -3902,11 +3908,13 @@ BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
{
void *ptr;
- if (isGlobal)
+ if (isGlobal) {
ptr = parm_table[i].ptr;
- else
+ } else {
+ service * pService = ServicePtrs[snum];
ptr = ((char *)pService) +
PTR_DIFF(parm_table[i].ptr, &sDefault);
+ }
print_parameter(&parm_table[i],
ptr, f);
@@ -4194,7 +4202,8 @@ static void set_server_role(void)
case SEC_SERVER:
if (lp_domain_logons())
DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
- server_role = ROLE_DOMAIN_MEMBER;
+ /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
+ server_role = ROLE_STANDALONE;
break;
case SEC_DOMAIN:
if (lp_domain_logons()) {
@@ -4562,7 +4571,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
/* Should we allow printers to be shared... ? */
ctx = talloc_init("usershare_sd_xctx");
if (!ctx) {
- SAFE_FREE(lines);
+ file_lines_free(lines);
return 1;
}
@@ -4570,11 +4579,11 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
iService, lines, numlines, sharepath,
comment, &psd, &guest_ok) != USERSHARE_OK) {
talloc_destroy(ctx);
- SAFE_FREE(lines);
+ file_lines_free(lines);
return -1;
}
- SAFE_FREE(lines);
+ file_lines_free(lines);
/* Everything ok - add the service possibly using a template. */
if (iService < 0) {
@@ -4595,7 +4604,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
}
/* Write the ACL of the new/modified share. */
- if (!set_share_security(ctx, service_name, psd)) {
+ if (!set_share_security(service_name, psd)) {
DEBUG(0, ("process_usershare_file: Failed to set share "
"security for user share %s\n",
service_name ));
@@ -4868,7 +4877,7 @@ int load_usershare_shares(void)
/* Remove from the share ACL db. */
DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
lp_servicename(iService) ));
- delete_share_security(iService);
+ delete_share_security(snum2params_static(iService));
free_service_byindex(iService);
}
}
@@ -4943,7 +4952,8 @@ BOOL lp_load(const char *pszFname,
pstrcpy(n2, pszFname);
- standard_sub_basic( get_current_username(), n2,sizeof(n2) );
+ standard_sub_basic( get_current_username(), current_user_info.domain,
+ n2,sizeof(n2) );
add_to_file_list(pszFname, n2);
@@ -5087,7 +5097,9 @@ int lp_servicenumber(const char *pszServiceName)
* service names
*/
fstrcpy(serviceName, ServicePtrs[iService]->szService);
- standard_sub_basic(get_current_username(), serviceName,sizeof(serviceName));
+ standard_sub_basic(get_current_username(),
+ current_user_info.domain,
+ serviceName,sizeof(serviceName));
if (strequal(serviceName, pszServiceName)) {
break;
}
@@ -5099,7 +5111,7 @@ int lp_servicenumber(const char *pszServiceName)
if (!usershare_exists(iService, &last_mod)) {
/* Remove the share security tdb entry for it. */
- delete_share_security(iService);
+ delete_share_security(snum2params_static(iService));
/* Remove it from the array. */
free_service_byindex(iService);
/* Doesn't exist anymore. */
@@ -5123,6 +5135,98 @@ int lp_servicenumber(const char *pszServiceName)
return (iService);
}
+BOOL share_defined(const char *service_name)
+{
+ return (lp_servicenumber(service_name) != -1);
+}
+
+struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
+ const char *sharename)
+{
+ struct share_params *result;
+ char *sname;
+ int snum;
+
+ if (!(sname = SMB_STRDUP(sharename))) {
+ return NULL;
+ }
+
+ snum = find_service(sname);
+ SAFE_FREE(sname);
+
+ if (snum < 0) {
+ return NULL;
+ }
+
+ if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
+ DEBUG(0, ("talloc failed\n"));
+ return NULL;
+ }
+
+ result->service = snum;
+ return result;
+}
+
+struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
+{
+ struct share_iterator *result;
+
+ if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
+ DEBUG(0, ("talloc failed\n"));
+ return NULL;
+ }
+
+ result->next_id = 0;
+ return result;
+}
+
+struct share_params *next_share(struct share_iterator *list)
+{
+ struct share_params *result;
+
+ while (!lp_snum_ok(list->next_id) &&
+ (list->next_id < lp_numservices())) {
+ list->next_id += 1;
+ }
+
+ if (list->next_id >= lp_numservices()) {
+ return NULL;
+ }
+
+ if (!(result = TALLOC_P(list, struct share_params))) {
+ DEBUG(0, ("talloc failed\n"));
+ return NULL;
+ }
+
+ result->service = list->next_id;
+ list->next_id += 1;
+ return result;
+}
+
+struct share_params *next_printer(struct share_iterator *list)
+{
+ struct share_params *result;
+
+ while ((result = next_share(list)) != NULL) {
+ if (lp_print_ok(result->service)) {
+ break;
+ }
+ }
+ return result;
+}
+
+/*
+ * This is a hack for a transition period until we transformed all code from
+ * service numbers to struct share_params.
+ */
+
+struct share_params *snum2params_static(int snum)
+{
+ static struct share_params result;
+ result.service = snum;
+ return &result;
+}
+
/*******************************************************************
A useful volume label function.
********************************************************************/
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index 444262a59d7..4bdceec5717 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -930,14 +930,15 @@ BOOL init_sam_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen)
if (homedir) {
fstrcpy( tmpstring, homedir );
if (expand_explicit) {
- standard_sub_basic( username, tmpstring,
+ standard_sub_basic( username, domain, tmpstring,
sizeof(tmpstring) );
}
pdb_set_homedir(sampass, tmpstring, PDB_SET);
}
else {
pdb_set_homedir(sampass,
- talloc_sub_basic(sampass, username, lp_logon_home()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_home()),
PDB_DEFAULT);
}
@@ -949,28 +950,29 @@ BOOL init_sam_from_buffer_v3(struct samu *sampass, uint8 *buf, uint32 buflen)
if (logon_script) {
fstrcpy( tmpstring, logon_script );
if (expand_explicit) {
- standard_sub_basic( username, tmpstring,
+ standard_sub_basic( username, domain, tmpstring,
sizeof(tmpstring) );
}
pdb_set_logon_script(sampass, tmpstring, PDB_SET);
}
else {
pdb_set_logon_script(sampass,
- talloc_sub_basic(sampass, username, lp_logon_script()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_script()),
PDB_DEFAULT);
}
if (profile_path) {
fstrcpy( tmpstring, profile_path );
if (expand_explicit) {
- standard_sub_basic( username, tmpstring,
+ standard_sub_basic( username, domain, tmpstring,
sizeof(tmpstring) );
}
pdb_set_profile_path(sampass, tmpstring, PDB_SET);
}
else {
pdb_set_profile_path(sampass,
- talloc_sub_basic(sampass, username, lp_logon_path()),
+ talloc_sub_basic(sampass, username, domain, lp_logon_path()),
PDB_DEFAULT);
}
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index c0b78cde5e5..f1c17100286 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
LDAP protocol helper functions for SAMBA
- Copyright (C) Jean François Micouleau 1998
+ Copyright (C) Jean François Micouleau 1998
Copyright (C) Gerald Carter 2001-2003
Copyright (C) Shahms King 2001
Copyright (C) Andrew Bartlett 2002-2003
@@ -650,12 +650,13 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_HOME_PATH), homedir))
{
pdb_set_homedir( sampass,
- talloc_sub_basic(sampass, username, lp_logon_home()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_home()),
PDB_DEFAULT );
} else {
pstrcpy( tmpstring, homedir );
if (expand_explicit) {
- standard_sub_basic( username, tmpstring,
+ standard_sub_basic( username, domain, tmpstring,
sizeof(tmpstring) );
}
pdb_set_homedir(sampass, tmpstring, PDB_SET);
@@ -665,12 +666,13 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_LOGON_SCRIPT), logon_script))
{
pdb_set_logon_script( sampass,
- talloc_sub_basic(sampass, username, lp_logon_script()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_script()),
PDB_DEFAULT );
} else {
pstrcpy( tmpstring, logon_script );
if (expand_explicit) {
- standard_sub_basic( username, tmpstring,
+ standard_sub_basic( username, domain, tmpstring,
sizeof(tmpstring) );
}
pdb_set_logon_script(sampass, tmpstring, PDB_SET);
@@ -680,12 +682,13 @@ static BOOL init_sam_from_ldap(struct ldapsam_privates *ldap_state,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PROFILE_PATH), profile_path))
{
pdb_set_profile_path( sampass,
- talloc_sub_basic( sampass, username, lp_logon_path()),
+ talloc_sub_basic( sampass, username, domain,
+ lp_logon_path()),
PDB_DEFAULT );
} else {
pstrcpy( tmpstring, profile_path );
if (expand_explicit) {
- standard_sub_basic( username, tmpstring,
+ standard_sub_basic( username, domain, tmpstring,
sizeof(tmpstring) );
}
pdb_set_profile_path(sampass, tmpstring, PDB_SET);
diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c
index 873850bfa97..e9beaa05368 100644
--- a/source/passdb/pdb_tdb.c
+++ b/source/passdb/pdb_tdb.c
@@ -169,7 +169,8 @@ static BOOL init_sam_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 buf
}
else {
pdb_set_homedir(sampass,
- talloc_sub_basic(sampass, username, lp_logon_home()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_home()),
PDB_DEFAULT);
}
@@ -177,7 +178,8 @@ static BOOL init_sam_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 buf
pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
else {
pdb_set_dir_drive(sampass,
- talloc_sub_basic(sampass, username, lp_logon_drive()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_drive()),
PDB_DEFAULT);
}
@@ -185,7 +187,8 @@ static BOOL init_sam_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 buf
pdb_set_logon_script(sampass, logon_script, PDB_SET);
else {
pdb_set_logon_script(sampass,
- talloc_sub_basic(sampass, username, lp_logon_script()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_script()),
PDB_DEFAULT);
}
@@ -193,7 +196,8 @@ static BOOL init_sam_from_buffer_v0(struct samu *sampass, uint8 *buf, uint32 buf
pdb_set_profile_path(sampass, profile_path, PDB_SET);
} else {
pdb_set_profile_path(sampass,
- talloc_sub_basic(sampass, username, lp_logon_path()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_path()),
PDB_DEFAULT);
}
@@ -356,7 +360,8 @@ static BOOL init_sam_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 buf
}
else {
pdb_set_homedir(sampass,
- talloc_sub_basic(sampass, username, lp_logon_home()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_home()),
PDB_DEFAULT);
}
@@ -364,7 +369,8 @@ static BOOL init_sam_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 buf
pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
else {
pdb_set_dir_drive(sampass,
- talloc_sub_basic(sampass, username, lp_logon_drive()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_drive()),
PDB_DEFAULT);
}
@@ -372,7 +378,8 @@ static BOOL init_sam_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 buf
pdb_set_logon_script(sampass, logon_script, PDB_SET);
else {
pdb_set_logon_script(sampass,
- talloc_sub_basic(sampass, username, lp_logon_script()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_script()),
PDB_DEFAULT);
}
@@ -380,7 +387,8 @@ static BOOL init_sam_from_buffer_v1(struct samu *sampass, uint8 *buf, uint32 buf
pdb_set_profile_path(sampass, profile_path, PDB_SET);
} else {
pdb_set_profile_path(sampass,
- talloc_sub_basic(sampass, username, lp_logon_path()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_path()),
PDB_DEFAULT);
}
@@ -541,14 +549,15 @@ BOOL init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen)
if (homedir) {
fstrcpy( tmpstring, homedir );
if (expand_explicit) {
- standard_sub_basic( username, tmpstring,
+ standard_sub_basic( username, domain, tmpstring,
sizeof(tmpstring) );
}
pdb_set_homedir(sampass, tmpstring, PDB_SET);
}
else {
pdb_set_homedir(sampass,
- talloc_sub_basic(sampass, username, lp_logon_home()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_home()),
PDB_DEFAULT);
}
@@ -560,28 +569,30 @@ BOOL init_sam_from_buffer_v2(struct samu *sampass, uint8 *buf, uint32 buflen)
if (logon_script) {
fstrcpy( tmpstring, logon_script );
if (expand_explicit) {
- standard_sub_basic( username, tmpstring,
+ standard_sub_basic( username, domain, tmpstring,
sizeof(tmpstring) );
}
pdb_set_logon_script(sampass, tmpstring, PDB_SET);
}
else {
pdb_set_logon_script(sampass,
- talloc_sub_basic(sampass, username, lp_logon_script()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_script()),
PDB_DEFAULT);
}
if (profile_path) {
fstrcpy( tmpstring, profile_path );
if (expand_explicit) {
- standard_sub_basic( username, tmpstring,
+ standard_sub_basic( username, domain, tmpstring,
sizeof(tmpstring) );
}
pdb_set_profile_path(sampass, tmpstring, PDB_SET);
}
else {
pdb_set_profile_path(sampass,
- talloc_sub_basic(sampass, username, lp_logon_path()),
+ talloc_sub_basic(sampass, username, domain,
+ lp_logon_path()),
PDB_DEFAULT);
}
diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c
index 427ed37229e..b74763b2e5e 100644
--- a/source/printing/nt_printing.c
+++ b/source/printing/nt_printing.c
@@ -1035,7 +1035,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
char *buf = NULL;
ssize_t byte_count;
- if ((buf=SMB_MALLOC(PE_HEADER_SIZE)) == NULL) {
+ if ((buf=(char *)SMB_MALLOC(PE_HEADER_SIZE)) == NULL) {
DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
fname, PE_HEADER_SIZE));
goto error_exit;
@@ -1091,7 +1091,7 @@ static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32
goto error_exit;
SAFE_FREE(buf);
- if ((buf=SMB_MALLOC(section_table_bytes)) == NULL) {
+ if ((buf=(char *)SMB_MALLOC(section_table_bytes)) == NULL) {
DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
fname, section_table_bytes));
goto error_exit;
@@ -1281,6 +1281,8 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
SMB_STRUCT_STAT stat_buf;
BOOL bad_path;
+ NTSTATUS status;
+
SET_STAT_INVALID(st);
SET_STAT_INVALID(stat_buf);
new_create_time = (time_t)0;
@@ -1291,16 +1293,16 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
- fsp = open_file_ntcreate(conn, filepath, &stat_buf,
+ status = open_file_ntcreate(conn, filepath, &stat_buf,
FILE_GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
INTERNAL_OPEN_ONLY,
- NULL);
+ NULL, &fsp);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(status)) {
/* Old file not found, so by definition new file is in fact newer */
DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
filepath, errno));
@@ -1327,16 +1329,16 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
pstrcpy(filepath, new_file);
driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
- fsp = open_file_ntcreate(conn, filepath, &stat_buf,
+ status = open_file_ntcreate(conn, filepath, &stat_buf,
FILE_GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
INTERNAL_OPEN_ONLY,
- NULL);
+ NULL, &fsp);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(status)) {
/* New file not found, this shouldn't occur if the caller did its job */
DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
filepath, errno));
@@ -1405,6 +1407,7 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
BOOL bad_path;
SMB_STRUCT_STAT st;
connection_struct *conn;
+ NTSTATUS status;
SET_STAT_INVALID(st);
@@ -1460,16 +1463,16 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
goto error_exit;
}
- fsp = open_file_ntcreate(conn, driverpath, &st,
+ status = open_file_ntcreate(conn, driverpath, &st,
FILE_GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
INTERNAL_OPEN_ONLY,
- NULL);
+ NULL, &fsp);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
driverpath, errno));
*perr = WERR_ACCESS_DENIED;
@@ -4368,7 +4371,8 @@ WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_print
fstrcpy( servername, print_hnd->servername );
else {
fstrcpy( servername, "%L" );
- standard_sub_basic( "", servername, sizeof(servername)-1 );
+ standard_sub_basic( "", "", servername,
+ sizeof(servername)-1 );
}
result = get_a_printer_2( (*pp_printer)->info_2, servername, sharename );
@@ -5441,7 +5445,7 @@ BOOL print_access_check(struct current_user *user, int snum, int access_type)
Check the time parameters allow a print operation.
*****************************************************************************/
-BOOL print_time_access_check(int snum)
+BOOL print_time_access_check(const char *servicename)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
BOOL ok = False;
@@ -5449,7 +5453,7 @@ BOOL print_time_access_check(int snum)
struct tm *t;
uint32 mins;
- if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
return False;
if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
diff --git a/source/printing/print_generic.c b/source/printing/print_generic.c
index 1ea762695b1..aef4e50bfaa 100644
--- a/source/printing/print_generic.c
+++ b/source/printing/print_generic.c
@@ -30,7 +30,9 @@ for local substitution strings
static int print_run_command(int snum, const char* printername, BOOL do_sub,
const char *command, int *outfd, ...)
{
-
+ extern struct current_user current_user;
+ extern userdom_struct current_user_info;
+
pstring syscmd;
char *arg;
int ret;
@@ -56,7 +58,12 @@ static int print_run_command(int snum, const char* printername, BOOL do_sub,
pstring_sub( syscmd, "%p", printername );
if ( do_sub && snum != -1 )
- standard_sub_snum(snum,syscmd,sizeof(syscmd));
+ standard_sub_advanced(lp_servicename(snum),
+ current_user_info.unix_name, "",
+ current_user.ut.gid,
+ get_current_username(),
+ current_user_info.domain,
+ syscmd, sizeof(syscmd));
ret = smbrun(syscmd,outfd);
diff --git a/source/printing/print_test.c b/source/printing/print_test.c
new file mode 100644
index 00000000000..d34bc2153a1
--- /dev/null
+++ b/source/printing/print_test.c
@@ -0,0 +1,81 @@
+/*
+ * Printing backend for the build farm
+ *
+ * Copyright (C) Volker Lendecke 2006
+ *
+ * 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"
+#include "printing.h"
+
+#if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
+
+static int test_queue_get(const char *printer_name,
+ enum printing_types printing_type,
+ char *lpq_command,
+ print_queue_struct **q,
+ print_status_struct *status)
+{
+ return -1;
+}
+
+static int test_queue_pause(int snum)
+{
+ return -1;
+}
+
+static int test_queue_resume(int snum)
+{
+ return -1;
+}
+
+static int test_job_delete(const char *sharename, const char *lprm_command,
+ struct printjob *pjob)
+{
+ return -1;
+}
+
+static int test_job_pause(int snum, struct printjob *pjob)
+{
+ return -1;
+}
+
+static int test_job_resume(int snum, struct printjob *pjob)
+{
+ return -1;
+}
+
+static int test_job_submit(int snum, struct printjob *pjob)
+{
+ return -1;
+};
+
+struct printif test_printif =
+{
+ PRINT_TEST,
+ test_queue_get,
+ test_queue_pause,
+ test_queue_resume,
+ test_job_delete,
+ test_job_pause,
+ test_job_resume,
+ test_job_submit,
+};
+
+#else
+ /* this keeps fussy compilers happy */
+ void print_test_dummy(void) {}
+#endif /* DEVELOPER||ENABLE_BUILD_FARM_HACKS */
diff --git a/source/printing/printfsp.c b/source/printing/printfsp.c
index c248851822b..5278c60f992 100644
--- a/source/printing/printfsp.c
+++ b/source/printing/printfsp.c
@@ -28,15 +28,19 @@ open a print file and setup a fsp for it. This is a wrapper around
print_job_start().
***************************************************************************/
-files_struct *print_fsp_open(connection_struct *conn, const char *fname)
+NTSTATUS print_fsp_open(connection_struct *conn, const char *fname,
+ files_struct **result)
{
int jobid;
SMB_STRUCT_STAT sbuf;
- files_struct *fsp = file_new(conn);
+ files_struct *fsp;
fstring name;
+ NTSTATUS status;
- if(!fsp)
- return NULL;
+ status = file_new(conn, &fsp);
+ if(!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
fstrcpy( name, "Remote Downlevel Document");
if (fname) {
@@ -50,8 +54,9 @@ files_struct *print_fsp_open(connection_struct *conn, const char *fname)
jobid = print_job_start(&current_user, SNUM(conn), name, NULL);
if (jobid == -1) {
+ status = map_nt_error_from_unix(errno);
file_free(fsp);
- return NULL;
+ return status;
}
/* Convert to RAP id. */
@@ -60,7 +65,7 @@ files_struct *print_fsp_open(connection_struct *conn, const char *fname)
/* We need to delete the entry in the tdb. */
pjob_delete(lp_const_servicename(SNUM(conn)), jobid);
file_free(fsp);
- return NULL;
+ return NT_STATUS_ACCESS_DENIED; /* No errno around here */
}
/* setup a full fsp */
@@ -87,7 +92,8 @@ files_struct *print_fsp_open(connection_struct *conn, const char *fname)
conn->num_files_open++;
- return fsp;
+ *result = fsp;
+ return NT_STATUS_OK;
}
/****************************************************************************
diff --git a/source/printing/printing.c b/source/printing/printing.c
index 9dd6bec0be4..0d9ae02545a 100644
--- a/source/printing/printing.c
+++ b/source/printing/printing.c
@@ -271,7 +271,7 @@ static TDB_DATA print_key(uint32 jobid)
TDB_DATA ret;
SIVAL(&j, 0, jobid);
- ret.dptr = (void *)&j;
+ ret.dptr = (char *)&j;
ret.dsize = sizeof(j);
return ret;
}
@@ -839,10 +839,9 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
Check if the print queue has been updated recently enough.
****************************************************************************/
-static void print_cache_flush(int snum)
+static void print_cache_flush(const char *sharename)
{
fstring key;
- const char *sharename = lp_const_servicename(snum);
struct tdb_print_db *pdb = get_print_db_byname(sharename);
if (!pdb)
@@ -918,7 +917,7 @@ static void set_updating_pid(const fstring sharename, BOOL updating)
}
SIVAL( buffer, 0, updating_pid);
- data.dptr = (void *)buffer;
+ data.dptr = (char *)buffer;
data.dsize = 4; /* we always assume this is a 4 byte value */
tdb_store(pdb->tdb, key, data, TDB_REPLACE);
@@ -985,7 +984,7 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct
queue[i].fs_file);
}
- if ((data.dptr = SMB_MALLOC(data.dsize)) == NULL)
+ if ((data.dptr = (char *)SMB_MALLOC(data.dsize)) == NULL)
return;
len = 0;
@@ -1236,7 +1235,7 @@ static void print_queue_update_internal( const char *sharename,
key.dsize = strlen(keystr);
status.qcount = qcount;
- data.dptr = (void *)&status;
+ data.dptr = (char *)&status;
data.dsize = sizeof(status);
tdb_store(pdb->tdb, key, data, TDB_REPLACE);
@@ -1358,7 +1357,7 @@ static void print_queue_receive(int msg_type, struct process_id src,
int printing_type;
size_t len;
- len = tdb_unpack( buf, msglen, "fdPP",
+ len = tdb_unpack( (char *)buf, msglen, "fdPP",
sharename,
&printing_type,
lpqcommand,
@@ -1439,6 +1438,8 @@ update the internal database from the system print queue for a queue
static void print_queue_update(int snum, BOOL force)
{
+ extern struct current_user current_user;
+ extern userdom_struct current_user_info;
fstring key;
fstring sharename;
pstring lpqcommand, lprmcommand;
@@ -1456,12 +1457,22 @@ static void print_queue_update(int snum, BOOL force)
pstrcpy( lpqcommand, lp_lpqcommand(snum));
string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand),
False, False, False );
- standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) );
+ standard_sub_advanced(lp_servicename(snum),
+ current_user_info.unix_name, "",
+ current_user.ut.gid,
+ get_current_username(),
+ current_user_info.domain,
+ lpqcommand, sizeof(lpqcommand) );
pstrcpy( lprmcommand, lp_lprmcommand(snum));
string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand),
False, False, False );
- standard_sub_snum( snum, lprmcommand, sizeof(lprmcommand) );
+ standard_sub_advanced(lp_servicename(snum),
+ current_user_info.unix_name, "",
+ current_user.ut.gid,
+ get_current_username(),
+ current_user_info.domain,
+ lprmcommand, sizeof(lprmcommand) );
/*
* Make sure that the background queue process exists.
@@ -1524,10 +1535,8 @@ static void print_queue_update(int snum, BOOL force)
/* finally send the message */
- become_root();
message_send_pid(pid_to_procid(background_lpq_updater_pid),
MSG_PRINTER_UPDATE, buffer, len, False);
- unbecome_root();
SAFE_FREE( buffer );
@@ -1596,7 +1605,7 @@ BOOL print_notify_register_pid(int snum)
if (i == data.dsize) {
/* We weren't in the list. Realloc. */
- data.dptr = SMB_REALLOC(data.dptr, data.dsize + 8);
+ data.dptr = (char *)SMB_REALLOC(data.dptr, data.dsize + 8);
if (!data.dptr) {
DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
printername));
@@ -1781,7 +1790,7 @@ NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
Set the place in the queue for a job.
****************************************************************************/
-BOOL print_job_set_place(int snum, uint32 jobid, int place)
+BOOL print_job_set_place(const char *sharename, uint32 jobid, int place)
{
DEBUG(2,("print_job_set_place not implemented yet\n"));
return False;
@@ -1791,9 +1800,8 @@ BOOL print_job_set_place(int snum, uint32 jobid, int place)
Set the name of a job. Only possible for owner.
****************************************************************************/
-BOOL print_job_set_name(int snum, uint32 jobid, char *name)
+BOOL print_job_set_name(const char *sharename, uint32 jobid, char *name)
{
- const char* sharename = lp_const_servicename(snum);
struct printjob *pjob;
pjob = print_job_find(sharename, jobid);
@@ -1930,9 +1938,10 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
Return true if the current user owns the print job.
****************************************************************************/
-static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
+static BOOL is_owner(struct current_user *user, const char *servicename,
+ uint32 jobid)
{
- struct printjob *pjob = print_job_find(lp_const_servicename(snum), jobid);
+ struct printjob *pjob = print_job_find(servicename, jobid);
user_struct *vuser;
if (!pjob || !user)
@@ -1958,7 +1967,7 @@ BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR
*errcode = WERR_OK;
- owner = is_owner(user, snum, jobid);
+ owner = is_owner(user, lp_const_servicename(snum), jobid);
/* Check access against security descriptor or whether the user
owns their job. */
@@ -2037,7 +2046,7 @@ BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *
return False;
}
- if (!is_owner(user, snum, jobid) &&
+ if (!is_owner(user, lp_const_servicename(snum), jobid) &&
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("pause denied by security descriptor\n"));
@@ -2061,7 +2070,7 @@ pause, or resume print job. User name: %s. Printer name: %s.",
}
/* force update the database */
- print_cache_flush(snum);
+ print_cache_flush(lp_const_servicename(snum));
/* Send a printer notify message */
@@ -2097,7 +2106,7 @@ BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR
return False;
}
- if (!is_owner(user, snum, jobid) &&
+ if (!is_owner(user, lp_const_servicename(snum), jobid) &&
!print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
DEBUG(3, ("resume denied by security descriptor\n"));
*errcode = WERR_ACCESS_DENIED;
@@ -2119,7 +2128,7 @@ pause, or resume print job. User name: %s. Printer name: %s.",
}
/* force update the database */
- print_cache_flush(snum);
+ print_cache_flush(lp_const_servicename(snum));
/* Send a printer notify message */
@@ -2325,7 +2334,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE
return (uint32)-1;
}
- if (!print_time_access_check(snum)) {
+ if (!print_time_access_check(lp_servicename(snum))) {
DEBUG(3, ("print_job_start: job start denied by time check\n"));
release_print_db(pdb);
return (uint32)-1;
@@ -2739,7 +2748,7 @@ BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
}
/* force update the database */
- print_cache_flush(snum);
+ print_cache_flush(lp_const_servicename(snum));
/* Send a printer notify message */
@@ -2805,7 +2814,7 @@ BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
become_root();
for (i=0;i<njobs;i++) {
- BOOL owner = is_owner(user, snum, queue[i].job);
+ BOOL owner = is_owner(user, lp_const_servicename(snum), queue[i].job);
if (owner || can_job_admin) {
print_job_delete1(snum, queue[i].job);
diff --git a/source/python/py_smb.c b/source/python/py_smb.c
index 679c113f397..2f5d1161d87 100644
--- a/source/python/py_smb.c
+++ b/source/python/py_smb.c
@@ -43,7 +43,7 @@ static PyObject *py_smb_connect(PyObject *self, PyObject *args, PyObject *kw)
if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &server))
return NULL;
- if (!(cli = cli_initialise(NULL)))
+ if (!(cli = cli_initialise()))
return NULL;
ZERO_STRUCT(ip);
@@ -99,7 +99,7 @@ static PyObject *py_smb_session_setup(PyObject *self, PyObject *args,
static char *kwlist[] = { "creds", NULL };
PyObject *creds;
char *username, *domain, *password, *errstr;
- BOOL result;
+ NTSTATUS result;
if (!PyArg_ParseTupleAndKeywords(args, kw, "|O", kwlist, &creds))
return NULL;
@@ -118,7 +118,7 @@ static PyObject *py_smb_session_setup(PyObject *self, PyObject *args,
return NULL;
}
- return Py_BuildValue("i", result);
+ return Py_BuildValue("i", NT_STATUS_IS_OK(result));
}
static PyObject *py_smb_tconx(PyObject *self, PyObject *args, PyObject *kw)
diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c
index 9cce7159674..e2562506975 100644
--- a/source/rpc_server/srv_srvsvc_nt.c
+++ b/source/rpc_server/srv_srvsvc_nt.c
@@ -137,43 +137,6 @@ static void map_generic_share_sd_bits(SEC_DESC *psd)
}
/*******************************************************************
- Can this user access with share with the required permissions ?
-********************************************************************/
-
-BOOL share_access_check(connection_struct *conn, int snum, user_struct *vuser, uint32 desired_access)
-{
- uint32 granted;
- NTSTATUS status;
- TALLOC_CTX *mem_ctx = NULL;
- SEC_DESC *psd = NULL;
- size_t sd_size;
- NT_USER_TOKEN *token = NULL;
- BOOL ret = True;
-
- mem_ctx = talloc_init("share_access_check");
- if (mem_ctx == NULL)
- return False;
-
- psd = get_share_security(mem_ctx, snum, &sd_size);
-
- if (!psd)
- goto out;
-
- if (conn->nt_user_token)
- token = conn->nt_user_token;
- else
- token = vuser->nt_user_token;
-
- ret = se_access_check(psd, token, desired_access, &granted, &status);
-
-out:
-
- talloc_destroy(mem_ctx);
-
- return ret;
-}
-
-/*******************************************************************
Fill in a share info level 501 structure.
********************************************************************/
diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c
index 934857c2c09..f489a8e96b2 100644
--- a/source/smbd/blocking.c
+++ b/source/smbd/blocking.c
@@ -19,6 +19,8 @@
*/
#include "includes.h"
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_LOCKING
/****************************************************************************
This is the structure to queue to implement blocking locks.
@@ -30,26 +32,29 @@ typedef struct _blocking_lock_record {
struct _blocking_lock_record *prev;
int com_type;
files_struct *fsp;
- time_t expire_time;
+ struct timeval expire_time;
int lock_num;
SMB_BIG_UINT offset;
SMB_BIG_UINT count;
- uint16 lock_pid;
+ uint32 lock_pid;
enum brl_flavour lock_flav;
enum brl_type lock_type;
char *inbuf;
int length;
} blocking_lock_record;
+/* dlink list we store pending lock records on. */
static blocking_lock_record *blocking_lock_queue;
+/* dlink list we move cancelled lock records onto. */
+static blocking_lock_record *blocking_lock_cancelled_queue;
+
/****************************************************************************
Destructor for the above structure.
****************************************************************************/
static void free_blocking_lock_record(blocking_lock_record *blr)
{
- DLIST_REMOVE(blocking_lock_queue, blr);
SAFE_FREE(blr->inbuf);
SAFE_FREE(blr);
}
@@ -70,19 +75,18 @@ static void received_unlock_msg(int msg_type, struct process_id src,
Function to push a blocking lock request onto the lock queue.
****************************************************************************/
-BOOL push_blocking_lock_request( char *inbuf, int length,
+BOOL push_blocking_lock_request( struct byte_range_lock *br_lck,
+ char *inbuf, int length,
files_struct *fsp,
int lock_timeout,
int lock_num,
- uint16 lock_pid,
+ uint32 lock_pid,
enum brl_type lock_type,
enum brl_flavour lock_flav,
SMB_BIG_UINT offset, SMB_BIG_UINT count)
{
static BOOL set_lock_msg;
blocking_lock_record *blr;
- BOOL my_lock_ctx = False;
- struct byte_range_lock *br_lck = NULL;
NTSTATUS status;
if(in_chained_smb() ) {
@@ -111,7 +115,13 @@ BOOL push_blocking_lock_request( char *inbuf, int length,
blr->com_type = CVAL(inbuf,smb_com);
blr->fsp = fsp;
- blr->expire_time = (lock_timeout == -1) ? (time_t)-1 : time(NULL) + (time_t)lock_timeout;
+ if (lock_timeout == -1) {
+ blr->expire_time.tv_sec = 0;
+ blr->expire_time.tv_usec = 0; /* Never expire. */
+ } else {
+ blr->expire_time = timeval_current_ofs(lock_timeout/1000,
+ (lock_timeout % 1000) * 1000);
+ }
blr->lock_num = lock_num;
blr->lock_pid = lock_pid;
blr->lock_flav = lock_flav;
@@ -121,25 +131,19 @@ BOOL push_blocking_lock_request( char *inbuf, int length,
memcpy(blr->inbuf, inbuf, length);
blr->length = length;
- br_lck = brl_get_locks(blr->fsp);
- if (!br_lck) {
- free_blocking_lock_record(blr);
- return False;
- }
-
/* Add a pending lock record for this. */
status = brl_lock(br_lck,
lock_pid,
procid_self(),
offset,
count,
- PENDING_LOCK,
+ lock_type == READ_LOCK ? PENDING_READ_LOCK : PENDING_WRITE_LOCK,
blr->lock_flav,
- &my_lock_ctx);
- byte_range_lock_destructor(br_lck);
+ lock_timeout ? True : False); /* blocking_lock. */
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
+ DLIST_REMOVE(blocking_lock_queue, blr);
free_blocking_lock_record(blr);
return False;
}
@@ -152,8 +156,10 @@ BOOL push_blocking_lock_request( char *inbuf, int length,
set_lock_msg = True;
}
- DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with expiry time %d (+%d) \
-for fnum = %d, name = %s\n", length, (int)blr->expire_time, lock_timeout,
+ DEBUG(3,("push_blocking_lock_request: lock request length=%d blocked with "
+ "expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n",
+ length, (unsigned int)blr->expire_time.tv_sec,
+ (unsigned int)blr->expire_time.tv_usec, lock_timeout,
blr->fsp->fnum, blr->fsp->fsp_name ));
/* Push the MID of this packet on the signing queue. */
@@ -220,9 +226,24 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat
status = NT_STATUS_FILE_LOCK_CONFLICT;
}
+ if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
+ /* Store the last lock error. */
+ files_struct *fsp = blr->fsp;
+
+ fsp->last_lock_failure.context.smbpid = blr->lock_pid;
+ fsp->last_lock_failure.context.tid = fsp->conn->cnum;
+ fsp->last_lock_failure.context.pid = procid_self();
+ fsp->last_lock_failure.start = blr->offset;
+ fsp->last_lock_failure.size = blr->count;
+ fsp->last_lock_failure.fnum = fsp->fnum;
+ fsp->last_lock_failure.lock_type = READ_LOCK; /* Don't care. */
+ fsp->last_lock_failure.lock_flav = blr->lock_flav;
+ }
+
ERROR_NT(status);
- if (!send_smb(smbd_server_fd(),outbuf))
+ if (!send_smb(smbd_server_fd(),outbuf)) {
exit_server("generic_blocking_lock_error: send_smb failed.");
+ }
}
/****************************************************************************
@@ -236,7 +257,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status)
files_struct *fsp = blr->fsp;
uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0;
- uint16 lock_pid;
+ uint32 lock_pid;
unsigned char locktype = CVAL(inbuf,smb_vwv3);
BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
char *data;
@@ -284,13 +305,6 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status)
static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status)
{
switch(blr->com_type) {
-#if 0
- /* We no longer push blocking lock requests for anything but lockingX and trans2. */
- case SMBlock:
- case SMBlockread:
- generic_blocking_lock_error(blr, status);
- break;
-#endif
case SMBlockingX:
reply_lockingX_error(blr, status);
break;
@@ -316,148 +330,6 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status
}
}
-#if 0
-/* We no longer push blocking lock requests for anything but lockingX and trans2. */
-
-/****************************************************************************
- Attempt to finish off getting all pending blocking locks for a lockread call.
- Returns True if we want to be removed from the list.
-*****************************************************************************/
-
-static BOOL process_lockread(blocking_lock_record *blr)
-{
- char *outbuf = get_OutBuffer();
- char *inbuf = blr->inbuf;
- ssize_t nread = -1;
- char *data, *p;
- int outsize = 0;
- SMB_BIG_UINT startpos;
- size_t numtoread;
- NTSTATUS status;
- files_struct *fsp = blr->fsp;
- BOOL my_lock_ctx = False;
-
- numtoread = SVAL(inbuf,smb_vwv1);
- startpos = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv2);
-
- numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
- data = smb_buf(outbuf) + 3;
-
- status = do_lock_spin(fsp,
- SVAL(inbuf,smb_pid),
- (SMB_BIG_UINT)numtoread,
- startpos,
- READ_LOCK,
- WINDOWS_LOCK,
- &my_lock_ctx);
-
- if (NT_STATUS_V(status)) {
- if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
- !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
- /*
- * We have other than a "can't get lock"
- * error. Send an error.
- * Return True so we get dequeued.
- */
- generic_blocking_lock_error(blr, status);
- return True;
- }
-
- /*
- * Still waiting for lock....
- */
-
- DEBUG(10,("process_lockread: failed to get lock for file = %s. Still waiting....\n",
- fsp->fsp_name));
- return False;
- }
-
- nread = read_file(fsp,data,startpos,numtoread);
-
- if (nread < 0) {
- generic_blocking_lock_error(blr,NT_STATUS_ACCESS_DENIED);
- return True;
- }
-
- construct_reply_common(inbuf, outbuf);
- outsize = set_message(outbuf,5,0,True);
-
- outsize += nread;
- SSVAL(outbuf,smb_vwv0,nread);
- SSVAL(outbuf,smb_vwv5,nread+3);
- p = smb_buf(outbuf);
- *p++ = 1;
- SSVAL(p,0,nread); p += 2;
- set_message_end(outbuf, p+nread);
-
- DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%lu nread=%ld\n",
- fsp->fsp_name, fsp->fnum, (unsigned long)numtoread, (long)nread ) );
-
- send_blocking_reply(outbuf,outsize);
- return True;
-}
-
-/****************************************************************************
- Attempt to finish off getting all pending blocking locks for a lock call.
- Returns True if we want to be removed from the list.
-*****************************************************************************/
-
-static BOOL process_lock(blocking_lock_record *blr)
-{
- char *outbuf = get_OutBuffer();
- char *inbuf = blr->inbuf;
- int outsize;
- SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0;
- NTSTATUS status;
- files_struct *fsp = blr->fsp;
- BOOL my_lock_ctx = False;
-
- count = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
- offset = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
-
- errno = 0;
- status = do_lock_spin(fsp,
- SVAL(inbuf,smb_pid),
- count,
- offset,
- WRITE_LOCK,
- WINDOWS_LOCK,
- &my_lock_ctx);
-
- if (NT_STATUS_IS_ERR(status)) {
- if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
- !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
- /*
- * We have other than a "can't get lock"
- * error. Send an error.
- * Return True so we get dequeued.
- */
-
- blocking_lock_reply_error(blr, status);
- return True;
- }
- /*
- * Still can't get the lock - keep waiting.
- */
- DEBUG(10,("process_lock: failed to get lock for file = %s. Still waiting....\n",
- fsp->fsp_name));
- return False;
- }
-
- /*
- * Success - we got the lock.
- */
-
- DEBUG(3,("process_lock : file=%s fnum=%d offset=%.0f count=%.0f\n",
- fsp->fsp_name, fsp->fnum, (double)offset, (double)count));
-
- construct_reply_common(inbuf, outbuf);
- outsize = set_message(outbuf,0,0,True);
- send_blocking_reply(outbuf,outsize);
- return True;
-}
-#endif
-
/****************************************************************************
Attempt to finish off getting all pending blocking locks for a lockingX call.
Returns True if we want to be removed from the list.
@@ -471,10 +343,9 @@ static BOOL process_lockingX(blocking_lock_record *blr)
uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
uint16 num_locks = SVAL(inbuf,smb_vwv7);
SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT)0;
- uint16 lock_pid;
+ uint32 lock_pid;
BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
char *data;
- BOOL my_lock_ctx = False;
NTSTATUS status = NT_STATUS_OK;
data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks);
@@ -483,8 +354,9 @@ static BOOL process_lockingX(blocking_lock_record *blr)
* Data now points at the beginning of the list
* of smb_lkrng structs.
*/
-
+
for(; blr->lock_num < num_locks; blr->lock_num++) {
+ struct byte_range_lock *br_lck = NULL;
BOOL err;
lock_pid = get_lock_pid( data, blr->lock_num, large_file_format);
@@ -496,13 +368,17 @@ static BOOL process_lockingX(blocking_lock_record *blr)
* request would never have been queued. JRA.
*/
errno = 0;
- status = do_lock_spin(fsp,
+ br_lck = do_lock(fsp,
lock_pid,
count,
offset,
- ((locktype & 1) ? READ_LOCK : WRITE_LOCK),
+ ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
+ READ_LOCK : WRITE_LOCK),
WINDOWS_LOCK,
- &my_lock_ctx);
+ True,
+ &status);
+
+ TALLOC_FREE(br_lck);
if (NT_STATUS_IS_ERR(status)) {
break;
@@ -552,17 +428,17 @@ static BOOL process_trans2(blocking_lock_record *blr)
extern int max_send;
char *inbuf = blr->inbuf;
char *outbuf;
- BOOL my_lock_ctx = False;
char params[2];
NTSTATUS status;
-
- status = do_lock(blr->fsp,
- blr->lock_pid,
- blr->count,
- blr->offset,
- blr->lock_type,
- blr->lock_flav,
- &my_lock_ctx);
+ struct byte_range_lock *br_lck = do_lock(blr->fsp,
+ blr->lock_pid,
+ blr->count,
+ blr->offset,
+ blr->lock_type,
+ blr->lock_flav,
+ True,
+ &status);
+ TALLOC_FREE(br_lck);
if (!NT_STATUS_IS_OK(status)) {
if (ERROR_WAS_LOCK_DENIED(status)) {
@@ -582,7 +458,8 @@ static BOOL process_trans2(blocking_lock_record *blr)
construct_reply_common(inbuf, outbuf);
SCVAL(outbuf,smb_com,SMBtrans2);
SSVAL(params,0,0);
- send_trans2_replies(outbuf, max_send, params, 2, NULL, 0);
+ /* Fake up max_data_bytes here - we know it fits. */
+ send_trans2_replies(outbuf, max_send, params, 2, NULL, 0, 0xffff);
return True;
}
@@ -595,13 +472,6 @@ static BOOL process_trans2(blocking_lock_record *blr)
static BOOL blocking_lock_record_process(blocking_lock_record *blr)
{
switch(blr->com_type) {
-#if 0
- /* We no longer push blocking lock requests for anything but lockingX and trans2. */
- case SMBlock:
- return process_lock(blr);
- case SMBlockread:
- return process_lockread(blr);
-#endif
case SMBlockingX:
return process_lockingX(blr);
case SMBtrans2:
@@ -615,33 +485,41 @@ static BOOL blocking_lock_record_process(blocking_lock_record *blr)
}
/****************************************************************************
- Delete entries by fnum from the blocking lock pending queue.
+ Cancel entries by fnum from the blocking lock pending queue.
*****************************************************************************/
-void remove_pending_lock_requests_by_fid(files_struct *fsp)
+void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lock *br_lck)
{
blocking_lock_record *blr, *next = NULL;
for(blr = blocking_lock_queue; blr; blr = next) {
next = blr->next;
if(blr->fsp->fnum == fsp->fnum) {
- struct byte_range_lock *br_lck = brl_get_locks(fsp);
+ unsigned char locktype = 0;
+
+ if (blr->com_type == SMBlockingX) {
+ locktype = CVAL(blr->inbuf,smb_vwv3);
+ }
if (br_lck) {
DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \
file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
- brl_remove_pending_lock(br_lck,
+ brl_lock_cancel(br_lck,
blr->lock_pid,
procid_self(),
blr->offset,
blr->count,
blr->lock_flav);
- byte_range_lock_destructor(br_lck);
+ blocking_lock_cancel(fsp,
+ blr->lock_pid,
+ blr->offset,
+ blr->count,
+ blr->lock_flav,
+ locktype,
+ NT_STATUS_RANGE_NOT_LOCKED);
}
-
- free_blocking_lock_record(blr);
}
}
}
@@ -658,22 +536,23 @@ void remove_pending_lock_requests_by_mid(int mid)
next = blr->next;
if(SVAL(blr->inbuf,smb_mid) == mid) {
files_struct *fsp = blr->fsp;
- struct byte_range_lock *br_lck = brl_get_locks(fsp);
+ struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp);
if (br_lck) {
DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \
file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
- brl_remove_pending_lock(br_lck,
+ brl_lock_cancel(br_lck,
blr->lock_pid,
procid_self(),
blr->offset,
blr->count,
blr->lock_flav);
- byte_range_lock_destructor(br_lck);
+ TALLOC_FREE(br_lck);
}
blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
+ DLIST_REMOVE(blocking_lock_queue, blr);
free_blocking_lock_record(blr);
}
}
@@ -687,44 +566,60 @@ static void received_unlock_msg(int msg_type, struct process_id src,
void *buf, size_t len)
{
DEBUG(10,("received_unlock_msg\n"));
- process_blocking_lock_queue(time(NULL));
+ process_blocking_lock_queue();
}
/****************************************************************************
- Return the number of seconds to the next blocking locks timeout, or default_timeout
+ Return the number of milliseconds to the next blocking locks timeout, or default_timeout
*****************************************************************************/
-unsigned blocking_locks_timeout(unsigned default_timeout)
+unsigned int blocking_locks_timeout_ms(unsigned int default_timeout_ms)
{
- unsigned timeout = default_timeout;
- time_t t;
+ unsigned int timeout_ms = default_timeout_ms;
+ struct timeval tv_curr;
+ SMB_BIG_INT min_tv_dif_us = 0x7FFFFFFF; /* A large +ve number. */
blocking_lock_record *blr = blocking_lock_queue;
- /* note that we avoid the time() syscall if there are no blocking locks */
- if (!blr)
- return timeout;
+ /* note that we avoid the GetTimeOfDay() syscall if there are no blocking locks */
+ if (!blr) {
+ return timeout_ms;
+ }
- t = time(NULL);
+ tv_curr = timeval_current();
for (; blr; blr = blr->next) {
- if ((blr->expire_time != (time_t)-1) &&
- (timeout > (blr->expire_time - t))) {
- timeout = blr->expire_time - t;
+ SMB_BIG_INT tv_dif_us;
+
+ if (timeval_is_zero(&blr->expire_time)) {
+ continue; /* Never timeout. */
}
+
+ tv_dif_us = usec_time_diff(&blr->expire_time, &tv_curr);
+ min_tv_dif_us = MIN(min_tv_dif_us, tv_dif_us);
}
- if (timeout < 1)
- timeout = 1;
+ if (min_tv_dif_us < 0) {
+ min_tv_dif_us = 0;
+ }
+
+ timeout_ms = (unsigned int)(min_tv_dif_us / (SMB_BIG_INT)1000);
+
+ if (timeout_ms < 1) {
+ timeout_ms = 1;
+ }
+
+ DEBUG(10,("blocking_locks_timeout_ms: returning %u\n", timeout_ms));
- return timeout;
+ return timeout_ms;
}
/****************************************************************************
Process the blocking lock queue. Note that this is only called as root.
*****************************************************************************/
-void process_blocking_lock_queue(time_t t)
+void process_blocking_lock_queue(void)
{
+ struct timeval tv_curr = timeval_current();
blocking_lock_record *blr, *next = NULL;
/*
@@ -753,8 +648,8 @@ void process_blocking_lock_queue(time_t t)
DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n",
fsp->fnum, fsp->fsp_name ));
- if((blr->expire_time != -1) && (blr->expire_time <= t)) {
- struct byte_range_lock *br_lck = brl_get_locks(fsp);
+ if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) {
+ struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp);
/*
* Lock expired - throw away all previously
@@ -765,63 +660,66 @@ void process_blocking_lock_queue(time_t t)
DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n",
fsp->fnum, fsp->fsp_name ));
- brl_remove_pending_lock(br_lck,
+ brl_lock_cancel(br_lck,
blr->lock_pid,
procid_self(),
blr->offset,
blr->count,
blr->lock_flav);
- byte_range_lock_destructor(br_lck);
+ TALLOC_FREE(br_lck);
}
blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
+ DLIST_REMOVE(blocking_lock_queue, blr);
free_blocking_lock_record(blr);
continue;
}
if(!change_to_user(conn,vuid)) {
- struct byte_range_lock *br_lck = brl_get_locks(fsp);
+ struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp);
/*
* Remove the entry and return an error to the client.
*/
if (br_lck) {
- brl_remove_pending_lock(br_lck,
+ brl_lock_cancel(br_lck,
blr->lock_pid,
procid_self(),
blr->offset,
blr->count,
blr->lock_flav);
- byte_range_lock_destructor(br_lck);
+ TALLOC_FREE(br_lck);
}
DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n",
vuid ));
blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
+ DLIST_REMOVE(blocking_lock_queue, blr);
free_blocking_lock_record(blr);
continue;
}
if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) {
- struct byte_range_lock *br_lck = brl_get_locks(fsp);
+ struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp);
/*
* Remove the entry and return an error to the client.
*/
if (br_lck) {
- brl_remove_pending_lock(br_lck,
+ brl_lock_cancel(br_lck,
blr->lock_pid,
procid_self(),
blr->offset,
blr->count,
blr->lock_flav);
- byte_range_lock_destructor(br_lck);
+ TALLOC_FREE(br_lck);
}
DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) ));
blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
+ DLIST_REMOVE(blocking_lock_queue, blr);
free_blocking_lock_record(blr);
change_to_root_user();
continue;
@@ -834,20 +732,115 @@ void process_blocking_lock_queue(time_t t)
*/
if(blocking_lock_record_process(blr)) {
- struct byte_range_lock *br_lck = brl_get_locks(fsp);
+ struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp);
if (br_lck) {
- brl_remove_pending_lock(br_lck,
+ brl_lock_cancel(br_lck,
blr->lock_pid,
procid_self(),
blr->offset,
blr->count,
blr->lock_flav);
- byte_range_lock_destructor(br_lck);
+ TALLOC_FREE(br_lck);
}
+ DLIST_REMOVE(blocking_lock_queue, blr);
free_blocking_lock_record(blr);
}
change_to_root_user();
}
}
+
+/****************************************************************************
+ Handle a cancel message. Lock already moved onto the cancel queue.
+*****************************************************************************/
+
+#define MSG_BLOCKING_LOCK_CANCEL_SIZE (sizeof(blocking_lock_record *) + sizeof(NTSTATUS))
+
+static void process_blocking_lock_cancel_message(int msg_type, struct process_id src,
+ void *buf, size_t len)
+{
+ NTSTATUS err;
+ const char *msg = (const char *)buf;
+ blocking_lock_record *blr;
+
+ if (buf == NULL) {
+ smb_panic("process_blocking_lock_cancel_message: null msg\n");
+ }
+
+ if (len != MSG_BLOCKING_LOCK_CANCEL_SIZE) {
+ DEBUG(0, ("process_blocking_lock_cancel_message: "
+ "Got invalid msg len %d\n", (int)len));
+ smb_panic("process_blocking_lock_cancel_message: bad msg\n");
+ }
+
+ memcpy(&blr, msg, sizeof(blr));
+ memcpy(&err, &msg[sizeof(blr)], sizeof(NTSTATUS));
+
+ DEBUG(10,("process_blocking_lock_cancel_message: returning error %s\n",
+ nt_errstr(err) ));
+
+ blocking_lock_reply_error(blr, err);
+ DLIST_REMOVE(blocking_lock_cancelled_queue, blr);
+ free_blocking_lock_record(blr);
+}
+
+/****************************************************************************
+ Send ourselves a blocking lock cancelled message. Handled asynchronously above.
+*****************************************************************************/
+
+BOOL blocking_lock_cancel(files_struct *fsp,
+ uint32 lock_pid,
+ SMB_BIG_UINT offset,
+ SMB_BIG_UINT count,
+ enum brl_flavour lock_flav,
+ unsigned char locktype,
+ NTSTATUS err)
+{
+ static BOOL initialized;
+ char msg[MSG_BLOCKING_LOCK_CANCEL_SIZE];
+ blocking_lock_record *blr;
+
+ if (!initialized) {
+ /* Register our message. */
+ message_register(MSG_SMB_BLOCKING_LOCK_CANCEL,
+ process_blocking_lock_cancel_message);
+
+ initialized = True;
+ }
+
+ for (blr = blocking_lock_queue; blr; blr = blr->next) {
+ if (fsp == blr->fsp &&
+ lock_pid == blr->lock_pid &&
+ offset == blr->offset &&
+ count == blr->count &&
+ lock_flav == blr->lock_flav) {
+ break;
+ }
+ }
+
+ if (!blr) {
+ return False;
+ }
+
+ /* Check the flags are right. */
+ if (blr->com_type == SMBlockingX &&
+ (locktype & LOCKING_ANDX_LARGE_FILES) !=
+ (CVAL(blr->inbuf,smb_vwv3) & LOCKING_ANDX_LARGE_FILES)) {
+ return False;
+ }
+
+ /* Move to cancelled queue. */
+ DLIST_REMOVE(blocking_lock_queue, blr);
+ DLIST_ADD(blocking_lock_cancelled_queue, blr);
+
+ /* Create the message. */
+ memcpy(msg, &blr, sizeof(blr));
+ memcpy(&msg[sizeof(blr)], &err, sizeof(NTSTATUS));
+
+ message_send_pid(pid_to_procid(sys_getpid()),
+ MSG_SMB_BLOCKING_LOCK_CANCEL,
+ &msg, sizeof(msg), True);
+
+ return True;
+}
diff --git a/source/smbd/close.c b/source/smbd/close.c
index 8a63d3b227b..a3ddcae11d0 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -134,10 +134,8 @@ static void notify_deferred_opens(struct share_mode_lock *lck)
share_mode_entry_to_message(msg, e);
- become_root();
message_send_pid(e->pid, MSG_SMB_OPEN_RETRY,
msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);
- unbecome_root();
}
}
}
@@ -268,8 +266,6 @@ static int close_normal_file(files_struct *fsp, enum file_close_type close_type)
int err = 0;
int err1 = 0;
- remove_pending_lock_requests_by_fid(fsp);
-
if (fsp->aio_write_behind) {
/*
* If we're finishing write behind on a close we can get a write
diff --git a/source/smbd/conn.c b/source/smbd/conn.c
index db9e759bb47..0b0da589e4d 100644
--- a/source/smbd/conn.c
+++ b/source/smbd/conn.c
@@ -107,7 +107,7 @@ find_again:
int newsz = bmap->n + BITMAP_BLOCK_SZ;
struct bitmap * nbmap;
- if (newsz <= 0) {
+ if (newsz <= oldsz) {
/* Integer wrap. */
DEBUG(0,("ERROR! Out of connection structures\n"));
return NULL;
@@ -131,13 +131,25 @@ find_again:
goto find_again;
}
+ /* The bitmap position is used below as the connection number
+ * conn->cnum). This ends up as the TID field in the SMB header,
+ * which is limited to 16 bits (we skip 0xffff which is the
+ * NULL TID).
+ */
+ if (i > 65534) {
+ DEBUG(0, ("Maximum connection limit reached\n"));
+ return NULL;
+ }
+
if ((mem_ctx=talloc_init("connection_struct"))==NULL) {
DEBUG(0,("talloc_init(connection_struct) failed!\n"));
return NULL;
}
- if ((conn=TALLOC_ZERO_P(mem_ctx, connection_struct))==NULL) {
+ if (!(conn=TALLOC_ZERO_P(mem_ctx, connection_struct)) ||
+ !(conn->params = TALLOC_P(mem_ctx, struct share_params))) {
DEBUG(0,("talloc_zero() failed!\n"));
+ TALLOC_FREE(mem_ctx);
return NULL;
}
conn->mem_ctx = mem_ctx;
diff --git a/source/smbd/dir.c b/source/smbd/dir.c
index e34a81ca0d2..1c77630ee72 100644
--- a/source/smbd/dir.c
+++ b/source/smbd/dir.c
@@ -869,17 +869,17 @@ static BOOL user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_S
/* Pseudo-open the file (note - no fd's created). */
if(S_ISDIR(pst->st_mode)) {
- fsp = open_directory(conn, name, pst,
+ status = open_directory(conn, name, pst,
READ_CONTROL_ACCESS,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
0, /* no create options. */
- NULL);
+ NULL, &fsp);
} else {
- fsp = open_file_stat(conn, name, pst);
+ status = open_file_stat(conn, name, pst, &fsp);
}
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(status)) {
return False;
}
@@ -932,17 +932,17 @@ static BOOL user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
if(S_ISDIR(pst->st_mode)) {
return True;
} else {
- fsp = open_file_ntcreate(conn, name, pst,
+ status = open_file_ntcreate(conn, name, pst,
FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
INTERNAL_OPEN_ONLY,
- &info);
+ &info, &fsp);
}
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(status)) {
return False;
}
diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c
index 61145fde2f0..260a8dadbd6 100644
--- a/source/smbd/dosmode.c
+++ b/source/smbd/dosmode.c
@@ -300,8 +300,7 @@ static BOOL set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_
* are not violating security in doing the setxattr.
*/
- fsp = open_file_fchmod(conn,path,sbuf);
- if (!fsp)
+ if (!NT_STATUS_IS_OK(open_file_fchmod(conn,path,sbuf,&fsp)))
return ret;
become_root();
if (SMB_VFS_SETXATTR(conn, path, SAMBA_XATTR_DOS_ATTRIB, attrstr, strlen(attrstr), 0) == 0) {
@@ -518,8 +517,8 @@ int file_set_dosmode(connection_struct *conn, const char *fname, uint32 dosmode,
* holding. We need to review this.... may need to
* break batch oplocks open by others. JRA.
*/
- files_struct *fsp = open_file_fchmod(conn,fname,st);
- if (!fsp)
+ files_struct *fsp;
+ if (!NT_STATUS_IS_OK(open_file_fchmod(conn,fname,st,&fsp)))
return -1;
become_root();
ret = SMB_VFS_FCHMOD(fsp, fsp->fh->fd, unixmode);
diff --git a/source/smbd/error.c b/source/smbd/error.c
index fa236f0de05..0860b7d1d91 100644
--- a/source/smbd/error.c
+++ b/source/smbd/error.c
@@ -24,40 +24,6 @@
extern struct unix_error_map unix_dos_nt_errmap[];
extern uint32 global_client_caps;
-/* these can be set by some functions to override the error codes */
-static int override_ERR_class;
-static uint32 override_ERR_code;
-static NTSTATUS override_ERR_ntstatus;
-
-/****************************************************************************
- Setting eclass and ecode only and status to NT_STATUS_INVALID forces DOS errors.
- Setting status only and eclass and ecode to -1 forces NT errors.
-****************************************************************************/
-
-void set_saved_error_triple(int eclass, int ecode, NTSTATUS status)
-{
- override_ERR_class = eclass;
- override_ERR_code = ecode;
- override_ERR_ntstatus = status;
-}
-
-void set_saved_ntstatus(NTSTATUS status)
-{
- uint8 tmp_eclass; /* Hmmm. override_ERR_class is not uint8... */
- override_ERR_ntstatus = status;
- ntstatus_to_dos(status, &tmp_eclass, &override_ERR_code);
- override_ERR_class = tmp_eclass;
-
-}
-
-/****************************************************************************
- Return the current settings of the error triple. Return True if any are set.
-****************************************************************************/
-
-NTSTATUS get_saved_ntstatus(void)
-{
- return override_ERR_ntstatus;
-}
/****************************************************************************
Create an error packet from a cached error.
@@ -103,6 +69,10 @@ int unix_error_packet(char *outbuf,int def_class,uint32 def_code, NTSTATUS def_s
return error_packet(outbuf,eclass,ecode,ntstatus,line,file);
}
+BOOL use_nt_status(void)
+{
+ return lp_nt_status_support() && (global_client_caps & CAP_STATUS32);
+}
/****************************************************************************
Create an error packet. Normally called using the ERROR() macro.
@@ -111,24 +81,14 @@ int unix_error_packet(char *outbuf,int def_class,uint32 def_code, NTSTATUS def_s
If the override errors are set they take precedence over any passed in values.
****************************************************************************/
-int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
+void error_packet_set(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
{
- int outsize = set_message(outbuf,0,0,True);
BOOL force_nt_status = False;
BOOL force_dos_status = False;
- if (override_ERR_class != SMB_SUCCESS || !NT_STATUS_IS_OK(override_ERR_ntstatus)) {
- eclass = override_ERR_class;
- ecode = override_ERR_code;
- ntstatus = override_ERR_ntstatus;
- override_ERR_class = SMB_SUCCESS;
- override_ERR_code = 0;
- override_ERR_ntstatus = NT_STATUS_OK;
- }
-
if (eclass == (uint8)-1) {
force_nt_status = True;
- } else if (NT_STATUS_IS_INVALID(ntstatus)) {
+ } else if (NT_STATUS_IS_DOS(ntstatus)) {
force_dos_status = True;
}
@@ -146,7 +106,10 @@ int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, in
nt_errstr(ntstatus)));
} else {
/* We're returning a DOS error only. */
- if (eclass == 0 && NT_STATUS_V(ntstatus)) {
+ if (NT_STATUS_IS_DOS(ntstatus)) {
+ eclass = NT_STATUS_DOS_CLASS(ntstatus);
+ ecode = NT_STATUS_DOS_CODE(ntstatus);
+ } else if (eclass == 0 && NT_STATUS_V(ntstatus)) {
ntstatus_to_dos(ntstatus, &eclass, &ecode);
}
@@ -161,6 +124,11 @@ int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, in
eclass,
ecode));
}
+}
+int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
+{
+ int outsize = set_message(outbuf,0,0,True);
+ error_packet_set(outbuf, eclass, ecode, ntstatus, line, file);
return outsize;
}
diff --git a/source/smbd/fake_file.c b/source/smbd/fake_file.c
index b4f1f02b724..7c5eeae5c7d 100644
--- a/source/smbd/fake_file.c
+++ b/source/smbd/fake_file.c
@@ -101,24 +101,26 @@ enum FAKE_FILE_TYPE is_fake_file(const char *fname)
Open a fake quota file with a share mode.
****************************************************************************/
-files_struct *open_fake_file(connection_struct *conn,
+NTSTATUS open_fake_file(connection_struct *conn,
enum FAKE_FILE_TYPE fake_file_type,
const char *fname,
- uint32 access_mask)
+ uint32 access_mask,
+ files_struct **result)
{
files_struct *fsp = NULL;
+ NTSTATUS status;
/* access check */
if (current_user.ut.uid != 0) {
DEBUG(1,("open_fake_file_shared: access_denied to service[%s] file[%s] user[%s]\n",
lp_servicename(SNUM(conn)),fname,conn->user));
- errno = EACCES;
- return NULL;
+ return NT_STATUS_ACCESS_DENIED;
+
}
- fsp = file_new(conn);
- if(!fsp) {
- return NULL;
+ status = file_new(conn, &fsp);
+ if(!NT_STATUS_IS_OK(status)) {
+ return status;
}
DEBUG(5,("open_fake_file_shared: fname = %s, FID = %d, access_mask = 0x%x\n",
@@ -128,7 +130,7 @@ files_struct *open_fake_file(connection_struct *conn,
fsp->fh->fd = -1;
fsp->vuid = current_user.vuid;
fsp->fh->pos = -1;
- fsp->can_lock = True; /* Should this be true ? */
+ fsp->can_lock = False; /* Should this be true ? - No, JRA */
fsp->access_mask = access_mask;
string_set(&fsp->fsp_name,fname);
@@ -136,11 +138,12 @@ files_struct *open_fake_file(connection_struct *conn,
if (fsp->fake_file_handle==NULL) {
file_free(fsp);
- return NULL;
+ return NT_STATUS_NO_MEMORY;
}
conn->num_files_open++;
- return fsp;
+ *result = fsp;
+ return NT_STATUS_OK;
}
void destroy_fake_file_handle(FAKE_FILE_HANDLE **fh)
diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c
index 375bfbe7cf3..e0945be8893 100644
--- a/source/smbd/fileio.c
+++ b/source/smbd/fileio.c
@@ -214,7 +214,7 @@ ssize_t write_file(files_struct *fsp, const char *data, SMB_OFF_T pos, size_t n)
if (!fsp->can_write) {
errno = EPERM;
- return(0);
+ return -1;
}
if (!fsp->modified) {
diff --git a/source/smbd/files.c b/source/smbd/files.c
index e020d8e13a6..7069818dee4 100644
--- a/source/smbd/files.c
+++ b/source/smbd/files.c
@@ -59,7 +59,7 @@ static unsigned long get_gen_count(void)
Find first available file slot.
****************************************************************************/
-files_struct *file_new(connection_struct *conn)
+NTSTATUS file_new(connection_struct *conn, files_struct **result)
{
int i;
static int first_file;
@@ -82,14 +82,12 @@ files_struct *file_new(connection_struct *conn)
/* TODO: We have to unconditionally return a DOS error here,
* W2k3 even returns ERRDOS/ERRnofids for ntcreate&x with
* NTSTATUS negotiated */
- set_saved_ntstatus(NT_STATUS_TOO_MANY_OPENED_FILES);
- return NULL;
+ return NT_STATUS_TOO_MANY_OPENED_FILES;
}
fsp = SMB_MALLOC_P(files_struct);
if (!fsp) {
- set_saved_ntstatus(NT_STATUS_NO_MEMORY);
- return NULL;
+ return NT_STATUS_NO_MEMORY;
}
ZERO_STRUCTP(fsp);
@@ -97,8 +95,7 @@ files_struct *file_new(connection_struct *conn)
fsp->fh = SMB_MALLOC_P(struct fd_handle);
if (!fsp->fh) {
SAFE_FREE(fsp);
- set_saved_ntstatus(NT_STATUS_NO_MEMORY);
- return NULL;
+ return NT_STATUS_NO_MEMORY;
}
ZERO_STRUCTP(fsp->fh);
@@ -131,8 +128,9 @@ files_struct *file_new(connection_struct *conn)
if (fsp_fi_cache.fsp == NULL) {
ZERO_STRUCT(fsp_fi_cache);
}
-
- return fsp;
+
+ *result = fsp;
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -464,24 +462,16 @@ void file_free(files_struct *fsp)
}
/****************************************************************************
- Get a fsp from a packet given the offset of a 16 bit fnum.
+ Get an fsp from a 16 bit fnum.
****************************************************************************/
-files_struct *file_fsp(char *buf, int where)
+files_struct *file_fnum(uint16 fnum)
{
- int fnum, count=0;
files_struct *fsp;
-
- if (chain_fsp)
- return chain_fsp;
-
- if (!buf)
- return NULL;
- fnum = SVAL(buf, where);
+ int count=0;
for (fsp=Files;fsp;fsp=fsp->next, count++) {
if (fsp->fnum == fnum) {
- chain_fsp = fsp;
if (count > 10) {
DLIST_PROMOTE(Files, fsp);
}
@@ -492,6 +482,29 @@ files_struct *file_fsp(char *buf, int where)
}
/****************************************************************************
+ Get an fsp from a packet given the offset of a 16 bit fnum.
+****************************************************************************/
+
+files_struct *file_fsp(char *buf, int where)
+{
+ files_struct *fsp;
+
+ if (chain_fsp) {
+ return chain_fsp;
+ }
+
+ if (!buf) {
+ return NULL;
+ }
+
+ fsp = file_fnum(SVAL(buf, where));
+ if (fsp) {
+ chain_fsp = fsp;
+ }
+ return fsp;
+}
+
+/****************************************************************************
Reset the chained fsp - done at the start of a packet reply.
****************************************************************************/
@@ -504,15 +517,19 @@ void file_chain_reset(void)
Duplicate the file handle part for a DOS or FCB open.
****************************************************************************/
-files_struct *dup_file_fsp(files_struct *fsp,
+NTSTATUS dup_file_fsp(files_struct *fsp,
uint32 access_mask,
uint32 share_access,
- uint32 create_options)
+ uint32 create_options,
+ files_struct **result)
{
- files_struct *dup_fsp = file_new(fsp->conn);
+ NTSTATUS status;
+ files_struct *dup_fsp;
- if (!dup_fsp) {
- return NULL;
+ status = file_new(fsp->conn, &dup_fsp);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
SAFE_FREE(dup_fsp->fh);
@@ -547,5 +564,6 @@ files_struct *dup_file_fsp(files_struct *fsp,
dup_fsp->aio_write_behind = fsp->aio_write_behind;
string_set(&dup_fsp->fsp_name,fsp->fsp_name);
- return dup_fsp;
+ *result = dup_fsp;
+ return NT_STATUS_OK;
}
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index 9e7e19080ec..8ecc965c0d3 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -72,7 +72,11 @@ static int CopyExpanded(connection_struct *conn,
StrnCpy(buf,src,sizeof(buf)/2);
pstring_sub(buf,"%S",lp_servicename(snum));
- standard_sub_conn(conn,buf,sizeof(buf));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ buf, sizeof(buf));
l = push_ascii(*dst,buf,*n, STR_TERMINATE);
(*dst) += l;
(*n) -= l;
@@ -99,7 +103,11 @@ static int StrlenExpanded(connection_struct *conn, int snum, char *s)
}
StrnCpy(buf,s,sizeof(buf)/2);
pstring_sub(buf,"%S",lp_servicename(snum));
- standard_sub_conn(conn,buf,sizeof(buf));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ buf, sizeof(buf));
return strlen(buf) + 1;
}
@@ -111,7 +119,11 @@ static char *Expand(connection_struct *conn, int snum, char *s)
}
StrnCpy(buf,s,sizeof(buf)/2);
pstring_sub(buf,"%S",lp_servicename(snum));
- standard_sub_conn(conn,buf,sizeof(buf));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ buf, sizeof(buf));
return &buf[0];
}
@@ -593,7 +605,7 @@ static void fill_printq_info_52(connection_struct *conn, int snum,
PACKS(desc, "z", driver.info_3->monitorname); /* language monitor */
fstrcpy(location, "\\\\%L\\print$\\WIN40\\0");
- standard_sub_basic( "", location, sizeof(location)-1 );
+ standard_sub_basic( "", "", location, sizeof(location)-1 );
PACKS(desc,"z", location); /* share to retrieve files */
PACKS(desc,"z", driver.info_3->defaultdatatype); /* default data type */
@@ -2530,7 +2542,6 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
char *str2 = skip_string(str1,1);
char *p = skip_string(str2,1);
uint32 jobid;
- int snum;
fstring sharename;
int uLevel = SVAL(p,2);
int function = SVAL(p,4);
@@ -2544,9 +2555,9 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
return False;
}
- if ( (snum = lp_servicenumber(sharename)) == -1 ) {
- DEBUG(0,("api_PrintJobInfo: unable to get service number from sharename [%s]\n",
- sharename));
+ if (!share_defined(sharename)) {
+ DEBUG(0,("api_PrintJobInfo: sharen [%s] not defined\n",
+ sharename));
return False;
}
@@ -2569,14 +2580,14 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
/* change job place in the queue,
data gives the new place */
place = SVAL(data,0);
- if (print_job_set_place(snum, jobid, place)) {
+ if (print_job_set_place(sharename, jobid, place)) {
errcode=NERR_Success;
}
break;
case 0xb:
/* change print job name, data gives the name */
- if (print_job_set_name(snum, jobid, data)) {
+ if (print_job_set_name(sharename, jobid, data)) {
errcode=NERR_Success;
}
break;
@@ -2666,7 +2677,7 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
p = *rdata;
p2 = p + struct_len;
if (uLevel != 20) {
- srvstr_push(NULL, p,get_local_machine_name(),16,
+ srvstr_push(NULL, p,global_myname(),16,
STR_ASCII|STR_UPPER|STR_TERMINATE);
}
p += 16;
@@ -2680,7 +2691,7 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) {
for (i=0;i<count;i++) {
- if (strequal(servers[i].name,get_local_machine_name())) {
+ if (strequal(servers[i].name,global_myname())) {
servertype = servers[i].type;
push_ascii(comment,servers[i].comment,sizeof(pstring),STR_TERMINATE);
}
@@ -2697,7 +2708,11 @@ static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *par
SIVAL(p,6,0);
} else {
SIVAL(p,6,PTR_DIFF(p2,*rdata));
- standard_sub_conn(conn,comment,sizeof(comment));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ comment, sizeof(comment));
StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0));
p2 = skip_string(p2,1);
}
@@ -3122,8 +3137,12 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
SSVALS(p,102,-1); /* bad_pw_count */
SSVALS(p,104,-1); /* num_logons */
SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */
- pstrcpy(p2,"\\\\%L");
- standard_sub_conn(conn, p2,0);
+ {
+ pstring tmp;
+ pstrcpy(tmp, "\\\\%L");
+ standard_sub_basic("", "", tmp, sizeof(tmp));
+ pstrcpy(p2, tmp);
+ }
p2 = skip_string(p2,1);
SSVAL(p,110,49); /* country_code */
SSVAL(p,112,860); /* code page */
diff --git a/source/smbd/message.c b/source/smbd/message.c
index 31dab458443..fd53e60c141 100644
--- a/source/smbd/message.c
+++ b/source/smbd/message.c
@@ -101,7 +101,8 @@ static void msg_deliver(void)
pstrcpy(s,lp_msg_command());
pstring_sub(s,"%f",alpha_strcpy(alpha_msgfrom,msgfrom,NULL,sizeof(alpha_msgfrom)));
pstring_sub(s,"%t",alpha_strcpy(alpha_msgto,msgto,NULL,sizeof(alpha_msgto)));
- standard_sub_basic(current_user_info.smb_name, s, sizeof(s));
+ standard_sub_basic(current_user_info.smb_name,
+ current_user_info.domain, s, sizeof(s));
pstring_sub(s,"%s",name);
smbrun(s,NULL);
}
diff --git a/source/smbd/msdfs.c b/source/smbd/msdfs.c
index c6d15ada53a..1f04356b4f3 100644
--- a/source/smbd/msdfs.c
+++ b/source/smbd/msdfs.c
@@ -30,7 +30,7 @@ extern uint32 global_client_caps;
into the dfs_path structure
**********************************************************************/
-static BOOL parse_dfs_path(char *pathname, struct dfs_path *pdp)
+static BOOL parse_dfs_path(const char *pathname, struct dfs_path *pdp)
{
pstring pathname_local;
char *p, *temp;
@@ -73,26 +73,32 @@ static BOOL parse_dfs_path(char *pathname, struct dfs_path *pdp)
}
/**********************************************************************
- Parse the pathname of the form /hostname/service/reqpath
- into the dfs_path structure
+ Parse the pathname of the form /hostname/service/reqpath
+ into the dfs_path structure
+ This code is dependent on the fact that check_path_syntax() will
+ convert '\\' characters to '/'.
+ When POSIX pathnames have been selected this doesn't happen, so we
+ must look for the unaltered separator of '\\' instead of the modified '/'.
+ JRA.
**********************************************************************/
static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path *pdp, BOOL allow_wcards)
{
pstring pathname_local;
char *p,*temp;
+ const char sepchar = lp_posix_pathnames() ? '\\' : '/';
pstrcpy(pathname_local,pathname);
p = temp = pathname_local;
ZERO_STRUCTP(pdp);
- trim_char(temp,'/','/');
+ trim_char(temp,sepchar,sepchar);
DEBUG(10,("temp in parse_processed_dfs_path: .%s. after trimming \\'s\n",temp));
/* now tokenize */
/* parse out hostname */
- p = strchr_m(temp,'/');
+ p = strchr_m(temp,sepchar);
if(p == NULL) {
return False;
}
@@ -102,7 +108,7 @@ static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path *pdp, BOOL
/* parse out servicename */
temp = p+1;
- p = strchr_m(temp,'/');
+ p = strchr_m(temp,sepchar);
if(p == NULL) {
pstrcpy(pdp->servicename,temp);
pdp->reqpath[0] = '\0';
@@ -144,7 +150,7 @@ static BOOL create_conn_struct(connection_struct *conn, int snum, char *path)
DEBUG(0,("talloc_init(connection_struct) failed!\n"));
return False;
}
-
+
if (!(conn->params = TALLOC_P(conn->mem_ctx, struct share_params))) {
DEBUG(0, ("TALLOC failed\n"));
return False;
@@ -311,7 +317,8 @@ TALLOC_CTX can be NULL here if struct referral **reflistpp, int *refcntp
are also NULL.
*****************************************************************/
-static BOOL resolve_dfs_path(TALLOC_CTX *ctx, pstring dfspath, struct dfs_path *dp,
+static BOOL resolve_dfs_path(TALLOC_CTX *ctx, const char *dfspath,
+ struct dfs_path *dp,
connection_struct *conn, BOOL search_flag,
struct referral **reflistpp, int *refcntp,
BOOL *self_referralp, int *consumedcntp)
@@ -453,7 +460,7 @@ BOOL dfs_redirect( pstring pathname, connection_struct *conn, BOOL search_wcard_
Return a self referral.
**********************************************************************/
-static BOOL self_ref(TALLOC_CTX *ctx, char *pathname, struct junction_map *jucn,
+static BOOL self_ref(TALLOC_CTX *ctx, const char *pathname, struct junction_map *jucn,
int *consumedcntp, BOOL *self_referralp)
{
struct referral *ref;
@@ -484,7 +491,7 @@ static BOOL self_ref(TALLOC_CTX *ctx, char *pathname, struct junction_map *jucn,
junction_map structure.
**********************************************************************/
-BOOL get_referred_path(TALLOC_CTX *ctx, char *pathname, struct junction_map *jucn,
+BOOL get_referred_path(TALLOC_CTX *ctx, const char *pathname, struct junction_map *jucn,
int *consumedcntp, BOOL *self_referralp)
{
struct dfs_path dp;
@@ -646,7 +653,7 @@ static int setup_ver2_dfs_referral(char *pathname, char **ppdata,
/* add the unexplained 0x16 bytes */
reply_size += 0x16;
- pdata = SMB_REALLOC(pdata,reply_size);
+ pdata = (char *)SMB_REALLOC(pdata,reply_size);
if(pdata == NULL) {
DEBUG(0,("malloc failed for Realloc!\n"));
return -1;
@@ -731,7 +738,7 @@ static int setup_ver3_dfs_referral(char *pathname, char **ppdata,
reply_size += (strlen(junction->referral_list[i].alternate_path)+1)*2;
}
- pdata = SMB_REALLOC(pdata,reply_size);
+ pdata = (char *)SMB_REALLOC(pdata,reply_size);
if(pdata == NULL) {
DEBUG(0,("version3 referral setup: malloc failed for Realloc!\n"));
return -1;
@@ -874,7 +881,7 @@ int setup_dfs_referral(connection_struct *orig_conn, char *pathname, int max_ref
Creates a junction structure from a Dfs pathname
**********************************************************************/
-BOOL create_junction(char *pathname, struct junction_map *jucn)
+BOOL create_junction(const char *pathname, struct junction_map *jucn)
{
struct dfs_path dp;
@@ -1059,6 +1066,7 @@ static int form_junctions(TALLOC_CTX *ctx, int snum, struct junction_map *jucn,
ref->ttl = REFERRAL_TTL;
if (*lp_msdfs_proxy(snum) != '\0') {
pstrcpy(ref->alternate_path, lp_msdfs_proxy(snum));
+ cnt++;
goto out;
}
diff --git a/source/smbd/negprot.c b/source/smbd/negprot.c
index 3347008cdf8..bbd10130509 100644
--- a/source/smbd/negprot.c
+++ b/source/smbd/negprot.c
@@ -33,7 +33,8 @@ static void get_challenge(char buff[8])
NTSTATUS nt_status;
const uint8 *cryptkey;
- /* We might be called more than once, muliple negprots are premitted */
+ /* We might be called more than once, multiple negprots are
+ * permitted */
if (negprot_global_auth_context) {
DEBUG(3, ("get challenge: is this a secondary negprot? negprot_global_auth_context is non-NULL!\n"));
(negprot_global_auth_context->free)(&negprot_global_auth_context);
@@ -168,7 +169,7 @@ static int reply_lanman2(char *inbuf, char *outbuf)
Generate the spnego negprot reply blob. Return the number of bytes used.
****************************************************************************/
-static int negprot_spnego(char *p, uint8 *pkeylen)
+static DATA_BLOB negprot_spnego(void)
{
DATA_BLOB blob;
nstring dos_name;
@@ -179,7 +180,6 @@ static int negprot_spnego(char *p, uint8 *pkeylen)
OID_NTLMSSP,
NULL};
const char *OIDs_plain[] = {OID_NTLMSSP, NULL};
- int len;
global_spnego_negotiated = True;
@@ -190,15 +190,6 @@ static int negprot_spnego(char *p, uint8 *pkeylen)
push_ascii_nstring(dos_name, unix_name);
safe_strcpy(guid, dos_name, sizeof(guid)-1);
-#ifdef DEVELOPER
- /* valgrind fixer... */
- {
- size_t sl = strlen(guid);
- if (sizeof(guid)-sl)
- memset(&guid[sl], '\0', sizeof(guid)-sl);
- }
-#endif
-
/* strangely enough, NT does not sent the single OID NTLMSSP when
not a ADS member, it sends no OIDs at all
@@ -230,20 +221,7 @@ static int negprot_spnego(char *p, uint8 *pkeylen)
SAFE_FREE(host_princ_s);
}
- memcpy(p, blob.data, blob.length);
- len = blob.length;
- if (len > 256) {
- DEBUG(0,("negprot_spnego: blob length too long (%d)\n", len));
- len = 255;
- }
- data_blob_free(&blob);
-
- if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
- *pkeylen = 0;
- } else {
- *pkeylen = len;
- }
- return len;
+ return blob;
}
/****************************************************************************
@@ -349,11 +327,17 @@ static int reply_nt1(char *inbuf, char *outbuf)
STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
DEBUG(3,("not using SPNEGO\n"));
} else {
- uint8 keylen;
- int len = negprot_spnego(p, &keylen);
-
- SCVAL(outbuf,smb_vwv16+1,keylen);
- p += len;
+ DATA_BLOB spnego_blob = negprot_spnego();
+
+ if (spnego_blob.data == NULL) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
+ memcpy(p, spnego_blob.data, spnego_blob.length);
+ p += spnego_blob.length;
+ data_blob_free(&spnego_blob);
+
+ SCVAL(outbuf,smb_vwv16+1, 0);
DEBUG(3,("using SPNEGO\n"));
}
diff --git a/source/smbd/ntquotas.c b/source/smbd/ntquotas.c
index a824978ecea..e754583312f 100644
--- a/source/smbd/ntquotas.c
+++ b/source/smbd/ntquotas.c
@@ -244,7 +244,7 @@ void destroy_quota_handle(void **pqt_handle)
if (!pqt_handle||!(*pqt_handle))
return;
- qt_handle = (*pqt_handle);
+ qt_handle = (SMB_NTQUOTA_HANDLE *)(*pqt_handle);
if (qt_handle->quota_list)
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index fae46f0ce66..2c37a17cc4a 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -37,6 +37,7 @@ static const char *known_nt_pipes[] = {
"\\lsass",
"\\lsarpc",
"\\winreg",
+ "\\initshutdown",
"\\spoolss",
"\\netdfs",
"\\rpcecho",
@@ -321,7 +322,7 @@ static int nt_open_pipe(char *fname, connection_struct *conn,
smb_np_struct *p = NULL;
uint16 vuid = SVAL(inbuf, smb_uid);
int i;
-
+
DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname));
/* See if it is one we want to handle. */
@@ -418,10 +419,14 @@ int reply_ntcreate_and_X_quota(connection_struct *conn,
int result;
char *p;
uint32 desired_access = IVAL(inbuf,smb_ntcreate_DesiredAccess);
- files_struct *fsp = open_fake_file(conn, fake_file_type, fname, desired_access);
+ files_struct *fsp;
+ NTSTATUS status;
- if (!fsp) {
- return ERROR_NT(NT_STATUS_ACCESS_DENIED);
+ status = open_fake_file(conn, fake_file_type, fname, desired_access,
+ &fsp);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return ERROR_NT(status);
}
set_message(outbuf,34,0,True);
@@ -431,31 +436,6 @@ int reply_ntcreate_and_X_quota(connection_struct *conn,
/* SCVAL(p,0,NO_OPLOCK_RETURN); */
p++;
SSVAL(p,0,fsp->fnum);
-#if 0
- p += 2;
- SIVAL(p,0,smb_action);
- p += 4;
-
- /* Create time. */
- put_long_date(p,c_time);
- p += 8;
- put_long_date(p,sbuf.st_atime); /* access time */
- p += 8;
- put_long_date(p,sbuf.st_mtime); /* write time */
- p += 8;
- put_long_date(p,sbuf.st_mtime); /* change time */
- p += 8;
- SIVAL(p,0,fattr); /* File Attributes. */
- p += 4;
- SOFF_T(p, 0, get_allocation_size(conn,fsp,&sbuf));
- p += 8;
- SOFF_T(p,0,file_len);
- p += 8;
- if (flags & EXTENDED_RESPONSE_REQUIRED)
- SSVAL(p,2,0x7);
- p += 4;
- SCVAL(p,0,fsp->is_directory ? 1 : 0);
-#endif
DEBUG(5,("reply_ntcreate_and_X_quota: fnum = %d, open name = %s\n", fsp->fnum, fsp->fsp_name));
@@ -489,13 +469,15 @@ int reply_ntcreate_and_X(connection_struct *conn,
BOOL bad_path = False;
files_struct *fsp=NULL;
char *p = NULL;
- time_t c_time;
+ struct timespec c_timespec;
+ struct timespec a_timespec;
+ struct timespec m_timespec;
BOOL extended_oplock_granted = False;
NTSTATUS status;
START_PROFILE(SMBntcreateX);
- DEBUG(10,("reply_ntcreateX: flags = 0x%x, access_mask = 0x%x \
+ DEBUG(10,("reply_ntcreate_and_X: flags = 0x%x, access_mask = 0x%x \
file_attributes = 0x%x, share_access = 0x%x, create_disposition = 0x%x \
create_options = 0x%x root_dir_fid = 0x%x\n",
(unsigned int)flags,
@@ -694,18 +676,18 @@ create_options = 0x%x root_dir_fid = 0x%x\n",
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
- fsp = open_directory(conn, fname, &sbuf,
+ status = open_directory(conn, fname, &sbuf,
access_mask,
share_access,
create_disposition,
create_options,
- &info);
+ &info, &fsp);
restore_case_semantics(conn, file_attributes);
- if(!fsp) {
+ if(!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBntcreateX);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+ return ERROR_NT(status);
}
} else {
/*
@@ -725,15 +707,15 @@ create_options = 0x%x root_dir_fid = 0x%x\n",
* before issuing an oplock break request to
* our client. JRA. */
- fsp = open_file_ntcreate(conn,fname,&sbuf,
+ status = open_file_ntcreate(conn,fname,&sbuf,
access_mask,
share_access,
create_disposition,
create_options,
file_attributes,
oplock_request,
- &info);
- if (!fsp) {
+ &info, &fsp);
+ if (!NT_STATUS_IS_OK(status)) {
/* We cheat here. There are two cases we
* care about. One is a directory rename,
* where the NT client will attempt to
@@ -753,7 +735,8 @@ create_options = 0x%x root_dir_fid = 0x%x\n",
* we handle in the open_file_stat case. JRA.
*/
- if(errno == EISDIR) {
+ if (NT_STATUS_EQUAL(status,
+ NT_STATUS_FILE_IS_A_DIRECTORY)) {
/*
* Fail the open if it was explicitly a non-directory file.
@@ -766,17 +749,17 @@ create_options = 0x%x root_dir_fid = 0x%x\n",
}
oplock_request = 0;
- fsp = open_directory(conn, fname, &sbuf,
+ status = open_directory(conn, fname, &sbuf,
access_mask,
share_access,
create_disposition,
create_options,
- &info);
+ &info, &fsp);
- if(!fsp) {
+ if(!NT_STATUS_IS_OK(status)) {
restore_case_semantics(conn, file_attributes);
END_PROFILE(SMBntcreateX);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+ return ERROR_NT(status);
}
} else {
@@ -786,7 +769,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n",
/* We have re-scheduled this call. */
return -1;
}
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+ return ERROR_NT(status);
}
}
}
@@ -879,22 +862,23 @@ create_options = 0x%x root_dir_fid = 0x%x\n",
p += 4;
/* Create time. */
- c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+ c_timespec = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+ a_timespec = get_atimespec(&sbuf);
+ m_timespec = get_mtimespec(&sbuf);
if (lp_dos_filetime_resolution(SNUM(conn))) {
- c_time &= ~1;
- sbuf.st_atime &= ~1;
- sbuf.st_mtime &= ~1;
- sbuf.st_mtime &= ~1;
+ dos_filetime_timespec(&c_timespec);
+ dos_filetime_timespec(&a_timespec);
+ dos_filetime_timespec(&m_timespec);
}
- put_long_date(p,c_time);
+ put_long_date_timespec(p, c_timespec);
p += 8;
- put_long_date(p,sbuf.st_atime); /* access time */
+ put_long_date_timespec(p, a_timespec); /* access time */
p += 8;
- put_long_date(p,sbuf.st_mtime); /* write time */
+ put_long_date_timespec(p, m_timespec); /* write time */
p += 8;
- put_long_date(p,sbuf.st_mtime); /* change time */
+ put_long_date_timespec(p, m_timespec); /* change time */
p += 8;
SIVAL(p,0,fattr); /* File Attributes. */
p += 4;
@@ -1026,16 +1010,16 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
return NT_STATUS_NO_MEMORY;
}
- if (psd->off_owner_sid==0) {
+ if (psd->owner_sid==0) {
security_info_sent &= ~OWNER_SECURITY_INFORMATION;
}
- if (psd->off_grp_sid==0) {
+ if (psd->grp_sid==0) {
security_info_sent &= ~GROUP_SECURITY_INFORMATION;
}
- if (psd->off_sacl==0) {
+ if (psd->sacl==0) {
security_info_sent &= ~SACL_SECURITY_INFORMATION;
}
- if (psd->off_dacl==0) {
+ if (psd->dacl==0) {
security_info_sent &= ~DACL_SECURITY_INFORMATION;
}
@@ -1113,7 +1097,9 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
uint32 sd_len;
uint32 ea_len;
uint16 root_dir_fid;
- time_t c_time;
+ struct timespec c_timespec;
+ struct timespec a_timespec;
+ struct timespec m_timespec;
struct ea_list *ea_list = NULL;
TALLOC_CTX *ctx = NULL;
char *pdata = NULL;
@@ -1336,16 +1322,16 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
* CreateDirectory() call.
*/
- fsp = open_directory(conn, fname, &sbuf,
+ status = open_directory(conn, fname, &sbuf,
access_mask,
share_access,
create_disposition,
create_options,
- &info);
- if(!fsp) {
+ &info, &fsp);
+ if(!NT_STATUS_IS_OK(status)) {
talloc_destroy(ctx);
restore_case_semantics(conn, file_attributes);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+ return ERROR_NT(status);
}
} else {
@@ -1354,17 +1340,18 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
* Ordinary file case.
*/
- fsp = open_file_ntcreate(conn,fname,&sbuf,
+ status = open_file_ntcreate(conn,fname,&sbuf,
access_mask,
share_access,
create_disposition,
create_options,
file_attributes,
oplock_request,
- &info);
+ &info, &fsp);
- if (!fsp) {
- if(errno == EISDIR) {
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status,
+ NT_STATUS_FILE_IS_A_DIRECTORY)) {
/*
* Fail the open if it was explicitly a non-directory file.
@@ -1376,16 +1363,16 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
}
oplock_request = 0;
- fsp = open_directory(conn, fname, &sbuf,
+ status = open_directory(conn, fname, &sbuf,
access_mask,
share_access,
create_disposition,
create_options,
- &info);
- if(!fsp) {
+ &info, &fsp);
+ if(!NT_STATUS_IS_OK(status)) {
talloc_destroy(ctx);
restore_case_semantics(conn, file_attributes);
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+ return ERROR_NT(status);
}
} else {
talloc_destroy(ctx);
@@ -1394,7 +1381,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
/* We have re-scheduled this call. */
return -1;
}
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
+ return ERROR_NT(status);
}
}
}
@@ -1511,22 +1498,23 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
p += 8;
/* Create time. */
- c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+ c_timespec = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+ a_timespec = get_atimespec(&sbuf);
+ m_timespec = get_mtimespec(&sbuf);
if (lp_dos_filetime_resolution(SNUM(conn))) {
- c_time &= ~1;
- sbuf.st_atime &= ~1;
- sbuf.st_mtime &= ~1;
- sbuf.st_mtime &= ~1;
+ dos_filetime_timespec(&c_timespec);
+ dos_filetime_timespec(&a_timespec);
+ dos_filetime_timespec(&m_timespec);
}
- put_long_date(p,c_time);
+ put_long_date_timespec(p, c_timespec); /* create time. */
p += 8;
- put_long_date(p,sbuf.st_atime); /* access time */
+ put_long_date_timespec(p, a_timespec); /* access time */
p += 8;
- put_long_date(p,sbuf.st_mtime); /* write time */
+ put_long_date_timespec(p, m_timespec); /* write time */
p += 8;
- put_long_date(p,sbuf.st_mtime); /* change time */
+ put_long_date_timespec(p, m_timespec); /* change time */
p += 8;
SIVAL(p,0,fattr); /* File Attributes. */
p += 4;
@@ -1660,39 +1648,29 @@ static NTSTATUS copy_internals(connection_struct *conn, char *oldname, char *new
DEBUG(10,("copy_internals: doing file copy %s to %s\n", oldname, newname));
- fsp1 = open_file_ntcreate(conn,oldname,&sbuf1,
+ status = open_file_ntcreate(conn,oldname,&sbuf1,
FILE_READ_DATA, /* Read-only. */
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN,
0, /* No create options. */
FILE_ATTRIBUTE_NORMAL,
NO_OPLOCK,
- &info);
+ &info, &fsp1);
- if (!fsp1) {
- status = get_saved_ntstatus();
- if (NT_STATUS_IS_OK(status)) {
- status = NT_STATUS_ACCESS_DENIED;
- }
- set_saved_ntstatus(NT_STATUS_OK);
+ if (!NT_STATUS_IS_OK(status)) {
return status;
}
- fsp2 = open_file_ntcreate(conn,newname,&sbuf2,
- FILE_WRITE_DATA, /* Write-only. */
+ status = open_file_ntcreate(conn,newname,&sbuf2,
+ FILE_WRITE_DATA, /* Read-only. */
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_CREATE,
0, /* No create options. */
fattr,
NO_OPLOCK,
- &info);
+ &info, &fsp2);
- if (!fsp2) {
- status = get_saved_ntstatus();
- if (NT_STATUS_IS_OK(status)) {
- status = NT_STATUS_ACCESS_DENIED;
- }
- set_saved_ntstatus(NT_STATUS_OK);
+ if (!NT_STATUS_IS_OK(status)) {
close_file(fsp1,ERROR_CLOSE);
return status;
}
diff --git a/source/smbd/open.c b/source/smbd/open.c
index e2ca81ccd7d..1899a6fce7c 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -38,24 +38,29 @@ struct deferred_open_record {
fd support routines - attempt to do a dos_open.
****************************************************************************/
-static int fd_open(struct connection_struct *conn,
- const char *fname,
- int flags,
- mode_t mode)
+static BOOL fd_open(struct connection_struct *conn,
+ const char *fname,
+ files_struct *fsp,
+ int flags,
+ mode_t mode)
{
- int fd;
+ int sav;
+
#ifdef O_NOFOLLOW
if (!lp_symlinks(SNUM(conn))) {
flags |= O_NOFOLLOW;
}
#endif
- fd = SMB_VFS_OPEN(conn,fname,flags,mode);
+ fsp->fh->fd = SMB_VFS_OPEN(conn,fname,fsp,flags,mode);
+ sav = errno;
- DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n", fname,
- flags, (int)mode, fd, (fd == -1) ? strerror(errno) : "" ));
+ DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
+ fname, flags, (int)mode, fsp->fh->fd,
+ (fsp->fh->fd == -1) ? strerror(errno) : "" ));
- return fd;
+ errno = sav;
+ return fsp->fh->fd != -1;
}
/****************************************************************************
@@ -63,7 +68,7 @@ static int fd_open(struct connection_struct *conn,
****************************************************************************/
int fd_close(struct connection_struct *conn,
- files_struct *fsp)
+ files_struct *fsp)
{
if (fsp->fh->fd == -1) {
return 0; /* What we used to call a stat open. */
@@ -80,9 +85,9 @@ int fd_close(struct connection_struct *conn,
****************************************************************************/
void change_owner_to_parent(connection_struct *conn,
- files_struct *fsp,
- const char *fname,
- SMB_STRUCT_STAT *psbuf)
+ files_struct *fsp,
+ const char *fname,
+ SMB_STRUCT_STAT *psbuf)
{
const char *parent_path = parent_dirname(fname);
SMB_STRUCT_STAT parent_st;
@@ -179,14 +184,14 @@ void change_owner_to_parent(connection_struct *conn,
Open a file.
****************************************************************************/
-static BOOL open_file(files_struct *fsp,
- connection_struct *conn,
- const char *fname,
- SMB_STRUCT_STAT *psbuf,
- int flags,
- mode_t unx_mode,
- uint32 access_mask, /* client requested access mask. */
- uint32 open_access_mask) /* what we're actually using in the open. */
+static NTSTATUS open_file(files_struct *fsp,
+ connection_struct *conn,
+ const char *fname,
+ SMB_STRUCT_STAT *psbuf,
+ int flags,
+ mode_t unx_mode,
+ uint32 access_mask, /* client requested access mask. */
+ uint32 open_access_mask) /* what we're actually using in the open. */
{
int accmode = (flags & O_ACCMODE);
int local_flags = flags;
@@ -211,7 +216,7 @@ static BOOL open_file(files_struct *fsp,
/* It's a read-only share - fail if we wanted to write. */
if(accmode != O_RDONLY) {
DEBUG(3,("Permission denied opening %s\n",fname));
- return False;
+ return NT_STATUS_ACCESS_DENIED;
} else if(flags & O_CREAT) {
/* We don't want to write - but we must make sure that
O_CREAT doesn't create the file if we have write
@@ -266,17 +271,15 @@ static BOOL open_file(files_struct *fsp,
/* Don't create files with Microsoft wildcard characters. */
if ((local_flags & O_CREAT) && !file_existed &&
ms_has_wild(fname)) {
- set_saved_ntstatus(NT_STATUS_OBJECT_NAME_INVALID);
- return False;
+ return NT_STATUS_OBJECT_NAME_INVALID;
}
/* Actually do the open */
- fsp->fh->fd = fd_open(conn, fname, local_flags, unx_mode);
- if (fsp->fh->fd == -1) {
+ if (!fd_open(conn, fname, fsp, local_flags, unx_mode)) {
DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
"(flags=%d)\n",
fname,strerror(errno),local_flags,flags));
- return False;
+ return map_nt_error_from_unix(errno);
}
/* Inherit the ACL if the file was created. */
@@ -304,8 +307,9 @@ static BOOL open_file(files_struct *fsp,
/* For a non-io open, this stat failing means file not found. JRA */
if (ret == -1) {
+ NTSTATUS status = map_nt_error_from_unix(errno);
fd_close(conn, fsp);
- return False;
+ return status;
}
}
@@ -318,7 +322,7 @@ static BOOL open_file(files_struct *fsp,
if(S_ISDIR(psbuf->st_mode)) {
fd_close(conn, fsp);
errno = EISDIR;
- return False;
+ return NT_STATUS_FILE_IS_A_DIRECTORY;
}
fsp->mode = psbuf->st_mode;
@@ -331,7 +335,8 @@ static BOOL open_file(files_struct *fsp,
if (!CAN_WRITE(conn)) {
fsp->can_write = False;
} else {
- fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ? True : False;
+ fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
+ True : False;
}
fsp->print_file = False;
fsp->modified = False;
@@ -347,12 +352,13 @@ static BOOL open_file(files_struct *fsp,
fsp->wcp = NULL; /* Write cache pointer. */
DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
- *current_user_info.smb_name ? current_user_info.smb_name : conn->user,fsp->fsp_name,
+ *current_user_info.smb_name ?
+ current_user_info.smb_name : conn->user,fsp->fsp_name,
BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
conn->num_files_open + 1));
errno = 0;
- return True;
+ return NT_STATUS_OK;
}
/*******************************************************************
@@ -469,8 +475,8 @@ static void validate_my_share_entries(int num,
if (is_deferred_open_entry(share_entry) &&
!open_was_deferred(share_entry->op_mid)) {
pstring str;
- DEBUG(0, ("Got a deferred entry without a request: "
- "PANIC: %s\n", share_mode_str(num, share_entry)));
+ pstr_sprintf(str, "Got a deferred entry without a request: "
+ "PANIC: %s\n", share_mode_str(num, share_entry));
smb_panic(str);
}
@@ -610,15 +616,17 @@ static BOOL is_delete_request(files_struct *fsp) {
*/
static BOOL delay_for_oplocks(struct share_mode_lock *lck,
- files_struct *fsp,
- int pass_number,
- int oplock_request)
+ files_struct *fsp,
+ int pass_number,
+ int oplock_request)
{
int i;
struct share_mode_entry *exclusive = NULL;
BOOL valid_entry = False;
BOOL delay_it = False;
BOOL have_level2 = False;
+ BOOL ret;
+ char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
if (oplock_request & INTERNAL_OPEN_ONLY) {
fsp->oplock_type = NO_OPLOCK;
@@ -682,34 +690,36 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck,
fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
}
- if (delay_it) {
- BOOL ret;
- char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
+ if (!delay_it) {
+ return False;
+ }
- DEBUG(10, ("Sending break request to PID %s\n",
- procid_str_static(&exclusive->pid)));
- exclusive->op_mid = get_current_mid();
+ /*
+ * Send a break message to the oplock holder and delay the open for
+ * our client.
+ */
- /* Create the message. */
- share_mode_entry_to_message(msg, exclusive);
+ DEBUG(10, ("Sending break request to PID %s\n",
+ procid_str_static(&exclusive->pid)));
+ exclusive->op_mid = get_current_mid();
- /* Add in the FORCE_OPLOCK_BREAK_TO_NONE bit in the message if set. We don't
- want this set in the share mode struct pointed to by lck. */
+ /* Create the message. */
+ share_mode_entry_to_message(msg, exclusive);
- if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) {
- SSVAL(msg,6,exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE);
- }
+ /* Add in the FORCE_OPLOCK_BREAK_TO_NONE bit in the message if set. We
+ don't want this set in the share mode struct pointed to by lck. */
- become_root();
- ret = message_send_pid(exclusive->pid, MSG_SMB_BREAK_REQUEST,
- msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);
- unbecome_root();
- if (!ret) {
- DEBUG(3, ("Could not send oplock break message\n"));
- }
+ if (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE) {
+ SSVAL(msg,6,exclusive->op_type | FORCE_OPLOCK_BREAK_TO_NONE);
+ }
+
+ ret = message_send_pid(exclusive->pid, MSG_SMB_BREAK_REQUEST,
+ msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);
+ if (!ret) {
+ DEBUG(3, ("Could not send oplock break message\n"));
}
- return delay_it;
+ return True;
}
static BOOL request_timed_out(struct timeval request_time,
@@ -773,17 +783,18 @@ static void defer_open(struct share_mode_lock *lck,
srv_defer_sign_response(mid);
}
+
/****************************************************************************
On overwrite open ensure that the attributes match.
****************************************************************************/
static BOOL open_match_attributes(connection_struct *conn,
- const char *path,
- uint32 old_dos_attr,
- uint32 new_dos_attr,
- mode_t existing_unx_mode,
- mode_t new_unx_mode,
- mode_t *returned_unx_mode)
+ const char *path,
+ uint32 old_dos_attr,
+ uint32 new_dos_attr,
+ mode_t existing_unx_mode,
+ mode_t new_unx_mode,
+ mode_t *returned_unx_mode)
{
uint32 noarch_old_dos_attr, noarch_new_dos_attr;
@@ -875,8 +886,8 @@ static files_struct *fcb_or_dos_open(connection_struct *conn,
}
/* We need to duplicate this fsp. */
- dup_fsp = dup_file_fsp(fsp, access_mask, share_access, create_options);
- if (!dup_fsp) {
+ if (!NT_STATUS_IS_OK(dup_file_fsp(fsp, access_mask, share_access,
+ create_options, &dup_fsp))) {
return NULL;
}
@@ -888,10 +899,10 @@ static files_struct *fcb_or_dos_open(connection_struct *conn,
****************************************************************************/
BOOL map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func,
- uint32 *paccess_mask,
- uint32 *pshare_mode,
- uint32 *pcreate_disposition,
- uint32 *pcreate_options)
+ uint32 *paccess_mask,
+ uint32 *pshare_mode,
+ uint32 *pcreate_disposition,
+ uint32 *pcreate_options)
{
uint32 access_mask;
uint32 share_mode;
@@ -1062,17 +1073,18 @@ static void schedule_defer_open(struct share_mode_lock *lck, struct timeval requ
Open a file with a share mode.
****************************************************************************/
-files_struct *open_file_ntcreate(connection_struct *conn,
- const char *fname,
- SMB_STRUCT_STAT *psbuf,
- uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
- uint32 share_access, /* share constants (FILE_SHARE_READ etc). */
- uint32 create_disposition, /* FILE_OPEN_IF etc. */
- uint32 create_options, /* options such as delete on close. */
- uint32 new_dos_attributes, /* attributes used for new file. */
- int oplock_request, /* internal Samba oplock codes. */
- /* Information (FILE_EXISTS etc.) */
- int *pinfo)
+NTSTATUS open_file_ntcreate(connection_struct *conn,
+ const char *fname,
+ SMB_STRUCT_STAT *psbuf,
+ uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
+ uint32 share_access, /* share constants (FILE_SHARE_READ etc) */
+ uint32 create_disposition, /* FILE_OPEN_IF etc. */
+ uint32 create_options, /* options such as delete on close. */
+ uint32 new_dos_attributes, /* attributes used for new file. */
+ int oplock_request, /* internal Samba oplock codes. */
+ /* Information (FILE_EXISTS etc.) */
+ int *pinfo,
+ files_struct **result)
{
int flags=0;
int flags2=0;
@@ -1080,7 +1092,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
BOOL def_acl = False;
SMB_DEV_T dev = 0;
SMB_INO_T inode = 0;
- BOOL fsp_open = False;
+ NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
files_struct *fsp = NULL;
mode_t new_unx_mode = (mode_t)0;
mode_t unx_mode = (mode_t)0;
@@ -1093,7 +1105,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
uint32 open_access_mask = access_mask;
NTSTATUS status;
int ret_flock;
-
+
if (conn->printer) {
/*
@@ -1107,7 +1119,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n", fname));
- return print_fsp_open(conn, fname);
+ return print_fsp_open(conn, fname, result);
}
/* We add aARCH to this as this mode is only used if the file is
@@ -1146,7 +1158,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
}
if (!check_name(fname,conn)) {
- return NULL;
+ return map_nt_error_from_unix(errno);
}
new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
@@ -1165,11 +1177,12 @@ files_struct *open_file_ntcreate(connection_struct *conn,
if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
/* OS/2 Workplace shell fix may be main code stream in a later
* release. */
- set_saved_error_triple(ERRDOS, ERRcannotopen,
- NT_STATUS_OBJECT_NAME_NOT_FOUND);
DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
"supported.\n"));
- return NULL;
+ if (use_nt_status()) {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+ return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
}
switch( create_disposition ) {
@@ -1197,9 +1210,8 @@ files_struct *open_file_ntcreate(connection_struct *conn,
DEBUG(5,("open_file_ntcreate: FILE_OPEN "
"requested for file %s and file "
"doesn't exist.\n", fname ));
- set_saved_ntstatus(NT_STATUS_OBJECT_NAME_NOT_FOUND);
errno = ENOENT;
- return NULL;
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
break;
@@ -1210,9 +1222,8 @@ files_struct *open_file_ntcreate(connection_struct *conn,
DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
"requested for file %s and file "
"doesn't exist.\n", fname ));
- set_saved_ntstatus(NT_STATUS_OBJECT_NAME_NOT_FOUND);
errno = ENOENT;
- return NULL;
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
flags2 |= O_TRUNC;
break;
@@ -1229,7 +1240,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
} else {
errno = EEXIST;
}
- return NULL;
+ return map_nt_error_from_unix(errno);
}
flags2 |= (O_CREAT|O_EXCL);
break;
@@ -1241,8 +1252,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
break;
default:
- set_saved_ntstatus(NT_STATUS_INVALID_PARAMETER);
- return NULL;
+ return NT_STATUS_INVALID_PARAMETER;
}
/* We only care about matching attributes on file exists and
@@ -1261,7 +1271,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
(unsigned int)psbuf->st_mode,
(unsigned int)unx_mode ));
errno = EACCES;
- return NULL;
+ return NT_STATUS_ACCESS_DENIED;
}
}
@@ -1323,21 +1333,22 @@ files_struct *open_file_ntcreate(connection_struct *conn,
DEBUG(5,("open_file_ntcreate: write access requested for "
"file %s on read only %s\n",
fname, !CAN_WRITE(conn) ? "share" : "file" ));
- set_saved_ntstatus(NT_STATUS_ACCESS_DENIED);
errno = EACCES;
- return NULL;
+ return NT_STATUS_ACCESS_DENIED;
}
- fsp = file_new(conn);
- if(!fsp) {
- return NULL;
+ status = file_new(conn, &fsp);
+ if(!NT_STATUS_IS_OK(status)) {
+ return status;
}
fsp->dev = psbuf->st_dev;
fsp->inode = psbuf->st_ino;
fsp->share_access = share_access;
fsp->fh->private_options = create_options;
- fsp->access_mask = open_access_mask; /* We change this to the requested access_mask after the open is done. */
+ fsp->access_mask = open_access_mask; /* We change this to the
+ * requested access_mask after
+ * the open is done. */
/* Ensure no SAMBA_PRIVATE bits can be set. */
fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
@@ -1350,14 +1361,13 @@ files_struct *open_file_ntcreate(connection_struct *conn,
inode = psbuf->st_ino;
lck = get_share_mode_lock(NULL, dev, inode,
- conn->connectpath,
- fname);
+ conn->connectpath,
+ fname);
if (lck == NULL) {
file_free(fsp);
DEBUG(0, ("Could not get share mode lock\n"));
- set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION);
- return NULL;
+ return NT_STATUS_SHARING_VIOLATION;
}
/* First pass - send break only on batch oplocks. */
@@ -1365,31 +1375,33 @@ files_struct *open_file_ntcreate(connection_struct *conn,
schedule_defer_open(lck, request_time);
TALLOC_FREE(lck);
file_free(fsp);
- return NULL;
+ return NT_STATUS_SHARING_VIOLATION;
}
- /* Use the client requested access mask here, not the one we open with. */
+ /* Use the client requested access mask here, not the one we
+ * open with. */
status = open_mode_check(conn, fname, lck,
access_mask, share_access,
create_options, &file_existed);
if (NT_STATUS_IS_OK(status)) {
- /* We might be going to allow this open. Check oplock status again. */
- /* Second pass - send break for both batch or exclusive oplocks. */
+ /* We might be going to allow this open. Check oplock
+ * status again. */
+ /* Second pass - send break for both batch or
+ * exclusive oplocks. */
if (delay_for_oplocks(lck, fsp, 2, oplock_request)) {
schedule_defer_open(lck, request_time);
TALLOC_FREE(lck);
file_free(fsp);
- return NULL;
+ return NT_STATUS_SHARING_VIOLATION;
}
}
if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) {
/* DELETE_PENDING is not deferred for a second */
- set_saved_ntstatus(status);
TALLOC_FREE(lck);
file_free(fsp);
- return NULL;
+ return status;
}
if (!NT_STATUS_IS_OK(status)) {
@@ -1405,7 +1417,8 @@ files_struct *open_file_ntcreate(connection_struct *conn,
NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
files_struct *fsp_dup;
- /* Use the client requested access mask here, not the one we open with. */
+ /* Use the client requested access mask here,
+ * not the one we open with. */
fsp_dup = fcb_or_dos_open(conn, fname, dev,
inode, access_mask,
share_access,
@@ -1418,7 +1431,8 @@ files_struct *open_file_ntcreate(connection_struct *conn,
*pinfo = FILE_WAS_OPENED;
}
conn->num_files_open++;
- return fsp_dup;
+ *result = fsp_dup;
+ return NT_STATUS_OK;
}
}
@@ -1439,10 +1453,10 @@ files_struct *open_file_ntcreate(connection_struct *conn,
}
if (((flags & O_RDWR) && !CAN_WRITE(conn)) ||
- !can_access_file(conn,fname,psbuf,can_access_mask)) {
+ !can_access_file(conn,fname,psbuf,can_access_mask)) {
can_access = False;
}
-
+
/*
* If we're returning a share violation, ensure we
* cope with the braindead 1 second delay.
@@ -1487,17 +1501,17 @@ files_struct *open_file_ntcreate(connection_struct *conn,
}
TALLOC_FREE(lck);
- if (!can_access) {
- set_saved_ntstatus(NT_STATUS_ACCESS_DENIED);
- } else {
+ if (can_access) {
/*
* We have detected a sharing violation here
* so return the correct error code
*/
- set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION);
+ status = NT_STATUS_SHARING_VIOLATION;
+ } else {
+ status = NT_STATUS_ACCESS_DENIED;
}
file_free(fsp);
- return NULL;
+ return status;
}
/*
@@ -1528,14 +1542,14 @@ files_struct *open_file_ntcreate(connection_struct *conn,
*/
fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,unx_mode,
- access_mask, open_access_mask);
+ access_mask, open_access_mask);
- if (!fsp_open) {
+ if (!NT_STATUS_IS_OK(fsp_open)) {
if (lck != NULL) {
TALLOC_FREE(lck);
}
file_free(fsp);
- return NULL;
+ return fsp_open;
}
if (!file_existed) {
@@ -1559,15 +1573,15 @@ files_struct *open_file_ntcreate(connection_struct *conn,
inode = fsp->inode;
lck = get_share_mode_lock(NULL, dev, inode,
- conn->connectpath,
- fname);
+ conn->connectpath,
+ fname);
if (lck == NULL) {
- DEBUG(0, ("open_file_ntcreate: Could not get share mode lock for %s\n", fname));
+ DEBUG(0, ("open_file_ntcreate: Could not get share "
+ "mode lock for %s\n", fname));
fd_close(conn, fsp);
file_free(fsp);
- set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION);
- return NULL;
+ return NT_STATUS_SHARING_VIOLATION;
}
status = open_mode_check(conn, fname, lck,
@@ -1594,7 +1608,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
defer_open(lck, request_time, timeval_zero(),
&state);
TALLOC_FREE(lck);
- return NULL;
+ return status;
}
/*
@@ -1620,11 +1634,9 @@ files_struct *open_file_ntcreate(connection_struct *conn,
fd_close(conn, fsp);
file_free(fsp);
- set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION);
- return NULL;
+ return NT_STATUS_SHARING_VIOLATION;
}
-
/*
* At this point onwards, we can guarentee that the share entry
* is locked, whether we created the file or not, and that the
@@ -1642,10 +1654,11 @@ files_struct *open_file_ntcreate(connection_struct *conn,
*/
if ((SMB_VFS_FTRUNCATE(fsp,fsp->fh->fd,0) == -1) ||
(SMB_VFS_FSTAT(fsp,fsp->fh->fd,psbuf)==-1)) {
+ status = map_nt_error_from_unix(errno);
TALLOC_FREE(lck);
fd_close(conn,fsp);
file_free(fsp);
- return NULL;
+ return status;
}
}
@@ -1693,20 +1706,19 @@ files_struct *open_file_ntcreate(connection_struct *conn,
set_share_mode(lck, fsp, current_user.ut.uid, 0, fsp->oplock_type);
if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
- info == FILE_WAS_SUPERSEDED) {
+ info == FILE_WAS_SUPERSEDED) {
/* Handle strange delete on close create semantics. */
if (create_options & FILE_DELETE_ON_CLOSE) {
- NTSTATUS result = can_set_delete_on_close(fsp, True, new_dos_attributes);
+ status = can_set_delete_on_close(fsp, True, new_dos_attributes);
- if (!NT_STATUS_IS_OK(result)) {
+ if (!NT_STATUS_IS_OK(status)) {
/* Remember to delete the mode we just added. */
del_share_mode(lck, fsp);
TALLOC_FREE(lck);
fd_close(conn,fsp);
file_free(fsp);
- set_saved_ntstatus(result);
- return NULL;
+ return status;
}
/* Note that here we set the *inital* delete on close flag,
not the regular one. */
@@ -1734,8 +1746,8 @@ files_struct *open_file_ntcreate(connection_struct *conn,
int saved_errno = errno; /* We might get ENOSYS in the next
* call.. */
- if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fh->fd, unx_mode) == -1
- && errno == ENOSYS) {
+ if (SMB_VFS_FCHMOD_ACL(fsp, fsp->fh->fd, unx_mode) == -1 &&
+ errno == ENOSYS) {
errno = saved_errno; /* Ignore ENOSYS */
}
@@ -1756,7 +1768,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
} else {
DEBUG(5, ("open_file_ntcreate: reset "
"attributes of file %s to 0%o\n",
- fname, (unsigned int)new_unx_mode));
+ fname, (unsigned int)new_unx_mode));
ret = 0; /* Don't do the fchmod below. */
}
}
@@ -1765,7 +1777,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
(SMB_VFS_FCHMOD(fsp, fsp->fh->fd, new_unx_mode) == -1))
DEBUG(5, ("open_file_ntcreate: failed to reset "
"attributes of file %s to 0%o\n",
- fname, (unsigned int)new_unx_mode));
+ fname, (unsigned int)new_unx_mode));
}
/* If this is a successful open, we must remove any deferred open
@@ -1775,31 +1787,32 @@ files_struct *open_file_ntcreate(connection_struct *conn,
conn->num_files_open++;
- return fsp;
+ *result = fsp;
+ return NT_STATUS_OK;
}
/****************************************************************************
Open a file for for write to ensure that we can fchmod it.
****************************************************************************/
-files_struct *open_file_fchmod(connection_struct *conn, const char *fname,
- SMB_STRUCT_STAT *psbuf)
+NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname,
+ SMB_STRUCT_STAT *psbuf, files_struct **result)
{
files_struct *fsp = NULL;
- BOOL fsp_open;
+ NTSTATUS status;
if (!VALID_STAT(*psbuf)) {
- return NULL;
+ return NT_STATUS_INVALID_PARAMETER;
}
- fsp = file_new(conn);
- if(!fsp) {
- return NULL;
+ status = file_new(conn, &fsp);
+ if(!NT_STATUS_IS_OK(status)) {
+ return status;
}
/* note! we must use a non-zero desired access or we don't get
a real file descriptor. Oh what a twisted web we weave. */
- fsp_open = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA,FILE_WRITE_DATA);
+ status = open_file(fsp,conn,fname,psbuf,O_WRONLY,0,FILE_WRITE_DATA,FILE_WRITE_DATA);
/*
* This is not a user visible file open.
@@ -1807,12 +1820,13 @@ files_struct *open_file_fchmod(connection_struct *conn, const char *fname,
* the conn->num_files_open.
*/
- if (!fsp_open) {
+ if (!NT_STATUS_IS_OK(status)) {
file_free(fsp);
- return NULL;
+ return status;
}
- return fsp;
+ *result = fsp;
+ return NT_STATUS_OK;
}
/****************************************************************************
@@ -1830,14 +1844,15 @@ int close_file_fchmod(files_struct *fsp)
Open a directory from an NT SMB call.
****************************************************************************/
-files_struct *open_directory(connection_struct *conn,
- const char *fname,
- SMB_STRUCT_STAT *psbuf,
- uint32 access_mask,
- uint32 share_access,
- uint32 create_disposition,
- uint32 create_options,
- int *pinfo)
+NTSTATUS open_directory(connection_struct *conn,
+ const char *fname,
+ SMB_STRUCT_STAT *psbuf,
+ uint32 access_mask,
+ uint32 share_access,
+ uint32 create_disposition,
+ uint32 create_options,
+ int *pinfo,
+ files_struct **result)
{
files_struct *fsp = NULL;
BOOL dir_existed = VALID_STAT(*psbuf) ? True : False;
@@ -1857,8 +1872,7 @@ files_struct *open_directory(connection_struct *conn,
if (is_ntfs_stream_name(fname)) {
DEBUG(0,("open_directory: %s is a stream name!\n", fname ));
- set_saved_ntstatus(NT_STATUS_NOT_A_DIRECTORY);
- return NULL;
+ return NT_STATUS_NOT_A_DIRECTORY;
}
switch( create_disposition ) {
@@ -1869,8 +1883,7 @@ files_struct *open_directory(connection_struct *conn,
DEBUG(5,("open_directory: FILE_OPEN requested "
"for directory %s and it doesn't "
"exist.\n", fname ));
- set_saved_ntstatus(NT_STATUS_OBJECT_NAME_NOT_FOUND);
- return NULL;
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
info = FILE_WAS_OPENED;
break;
@@ -1882,9 +1895,12 @@ files_struct *open_directory(connection_struct *conn,
DEBUG(5,("open_directory: FILE_CREATE "
"requested for directory %s and it "
"already exists.\n", fname ));
- set_saved_error_triple(ERRDOS, ERRfilexists,
- NT_STATUS_OBJECT_NAME_COLLISION);
- return NULL;
+ if (use_nt_status()) {
+ return NT_STATUS_OBJECT_NAME_COLLISION;
+ } else {
+ return NT_STATUS_DOS(ERRDOS,
+ ERRfilexists);
+ }
}
create_dir = True;
info = FILE_WAS_CREATED;
@@ -1908,8 +1924,7 @@ files_struct *open_directory(connection_struct *conn,
DEBUG(5,("open_directory: invalid create_disposition "
"0x%x for directory %s\n",
(unsigned int)create_disposition, fname));
- set_saved_ntstatus(NT_STATUS_INVALID_PARAMETER);
- return NULL;
+ return NT_STATUS_INVALID_PARAMETER;
}
if (create_dir) {
@@ -1926,27 +1941,26 @@ files_struct *open_directory(connection_struct *conn,
"Error was %s\n", fname, strerror(errno) ));
/* Ensure we return the correct NT status to the
* client. */
- set_saved_error_triple(0, 0, status);
- return NULL;
+ return status;
}
/* Ensure we're checking for a symlink here.... */
/* We don't want to get caught by a symlink racer. */
if(SMB_VFS_LSTAT(conn,fname, psbuf) != 0) {
- return NULL;
+ return map_nt_error_from_unix(errno);
}
if(!S_ISDIR(psbuf->st_mode)) {
DEBUG(0,("open_directory: %s is not a directory !\n",
fname ));
- return NULL;
+ return NT_STATUS_NOT_A_DIRECTORY;
}
}
- fsp = file_new(conn);
- if(!fsp) {
- return NULL;
+ status = file_new(conn, &fsp);
+ if(!NT_STATUS_IS_OK(status)) {
+ return status;
}
/*
@@ -1958,7 +1972,7 @@ files_struct *open_directory(connection_struct *conn,
fsp->dev = psbuf->st_dev;
fsp->vuid = current_user.vuid;
fsp->file_pid = global_smbpid;
- fsp->can_lock = True;
+ fsp->can_lock = False;
fsp->can_read = False;
fsp->can_write = False;
@@ -1975,14 +1989,13 @@ files_struct *open_directory(connection_struct *conn,
string_set(&fsp->fsp_name,fname);
lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode,
- conn->connectpath,
- fname);
+ conn->connectpath,
+ fname);
if (lck == NULL) {
DEBUG(0, ("open_directory: Could not get share mode lock for %s\n", fname));
file_free(fsp);
- set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION);
- return NULL;
+ return NT_STATUS_SHARING_VIOLATION;
}
status = open_mode_check(conn, fname, lck,
@@ -1990,10 +2003,9 @@ files_struct *open_directory(connection_struct *conn,
create_options, &dir_existed);
if (!NT_STATUS_IS_OK(status)) {
- set_saved_ntstatus(status);
TALLOC_FREE(lck);
file_free(fsp);
- return NULL;
+ return status;
}
set_share_mode(lck, fsp, current_user.ut.uid, 0, NO_OPLOCK);
@@ -2003,10 +2015,9 @@ files_struct *open_directory(connection_struct *conn,
if (create_options & FILE_DELETE_ON_CLOSE) {
status = can_set_delete_on_close(fsp, True, 0);
if (!NT_STATUS_IS_OK(status)) {
- set_saved_ntstatus(status);
TALLOC_FREE(lck);
file_free(fsp);
- return NULL;
+ return status;
}
set_delete_on_close_token(lck, &current_user.ut);
@@ -2027,28 +2038,33 @@ files_struct *open_directory(connection_struct *conn,
conn->num_files_open++;
- return fsp;
+ *result = fsp;
+ return NT_STATUS_OK;
}
/****************************************************************************
Open a pseudo-file (no locking checks - a 'stat' open).
****************************************************************************/
-files_struct *open_file_stat(connection_struct *conn, char *fname,
- SMB_STRUCT_STAT *psbuf)
+NTSTATUS open_file_stat(connection_struct *conn, const char *fname,
+ SMB_STRUCT_STAT *psbuf, files_struct **result)
{
files_struct *fsp = NULL;
+ NTSTATUS status;
- if (!VALID_STAT(*psbuf))
- return NULL;
+ if (!VALID_STAT(*psbuf)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
/* Can't 'stat' open directories. */
- if(S_ISDIR(psbuf->st_mode))
- return NULL;
+ if(S_ISDIR(psbuf->st_mode)) {
+ return NT_STATUS_FILE_IS_A_DIRECTORY;
+ }
- fsp = file_new(conn);
- if(!fsp)
- return NULL;
+ status = file_new(conn, &fsp);
+ if(!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
DEBUG(5,("open_file_stat: 'opening' file %s\n", fname));
@@ -2074,7 +2090,8 @@ files_struct *open_file_stat(connection_struct *conn, char *fname,
conn->num_files_open++;
- return fsp;
+ *result = fsp;
+ return NT_STATUS_OK;
}
/****************************************************************************
diff --git a/source/smbd/oplock_linux.c b/source/smbd/oplock_linux.c
index f186c13ebdd..518283c587e 100644
--- a/source/smbd/oplock_linux.c
+++ b/source/smbd/oplock_linux.c
@@ -89,7 +89,8 @@ static void set_capability(unsigned capability)
header.pid = 0;
if (capget(&header, &data) == -1) {
- DEBUG(3,("Unable to get kernel capabilities (%s)\n", strerror(errno)));
+ DEBUG(3,("Unable to get kernel capabilities (%s)\n",
+ strerror(errno)));
return;
}
@@ -156,15 +157,18 @@ static files_struct *linux_oplock_receive_message(fd_set *fds)
static BOOL linux_set_kernel_oplock(files_struct *fsp, int oplock_type)
{
if (linux_setlease(fsp->fh->fd, F_WRLCK) == -1) {
- DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
-inode = %.0f. (%s)\n",
+ DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, "
+ "fd = %d, dev = %x, inode = %.0f. (%s)\n",
fsp->fsp_name, fsp->fh->fd,
- (unsigned int)fsp->dev, (double)fsp->inode, strerror(errno)));
+ (unsigned int)fsp->dev, (double)fsp->inode,
+ strerror(errno)));
return False;
}
- DEBUG(3,("linux_set_kernel_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f, file_id = %lu\n",
- fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->fh->file_id));
+ DEBUG(3,("linux_set_kernel_oplock: got kernel oplock on file %s, "
+ "dev = %x, inode = %.0f, file_id = %lu\n",
+ fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode,
+ fsp->fh->file_id));
return True;
}
@@ -181,8 +185,9 @@ static void linux_release_kernel_oplock(files_struct *fsp)
* oplock state of this file.
*/
int state = fcntl(fsp->fh->fd, F_GETLEASE, 0);
- dbgtext("linux_release_kernel_oplock: file %s, dev = %x, inode = %.0f file_id = %lu has kernel \
-oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
+ dbgtext("linux_release_kernel_oplock: file %s, dev = %x, "
+ "inode = %.0f file_id = %lu has kernel oplock state "
+ "of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
(double)fsp->inode, fsp->fh->file_id, state );
}
@@ -191,10 +196,12 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
*/
if (linux_setlease(fsp->fh->fd, F_UNLCK) == -1) {
if (DEBUGLVL(0)) {
- dbgtext("linux_release_kernel_oplock: Error when removing kernel oplock on file " );
- dbgtext("%s, dev = %x, inode = %.0f, file_id = %lu. Error was %s\n",
- fsp->fsp_name, (unsigned int)fsp->dev,
- (double)fsp->inode, fsp->fh->file_id, strerror(errno) );
+ dbgtext("linux_release_kernel_oplock: Error when "
+ "removing kernel oplock on file " );
+ dbgtext("%s, dev = %x, inode = %.0f, file_id = %lu. "
+ "Error was %s\n", fsp->fsp_name,
+ (unsigned int)fsp->dev, (double)fsp->inode,
+ fsp->fh->file_id, strerror(errno) );
}
}
}
diff --git a/source/smbd/password.c b/source/smbd/password.c
index 814065dd34a..38000e93f4b 100644
--- a/source/smbd/password.c
+++ b/source/smbd/password.c
@@ -29,9 +29,6 @@ static user_struct *validated_users;
static int next_vuid = VUID_OFFSET;
static int num_validated_vuids;
-extern userdom_struct current_user_info;
-
-
/****************************************************************************
Check if a uid has been validated, and return an pointer to the user_struct
if it has. NULL if not. vuid is biased by an offset. This allows us to
@@ -549,9 +546,11 @@ static BOOL user_ok(const char *user, int snum)
str_list_copy(&invalid, lp_invalid_users(snum));
if (invalid &&
str_list_substitute(invalid, "%S", lp_servicename(snum))) {
- if ( invalid &&
- str_list_sub_basic(invalid,
- current_user_info.smb_name) ) {
+
+ /* This is used in sec=share only, so no current user
+ * around to pass to str_list_sub_basic() */
+
+ if ( invalid && str_list_sub_basic(invalid, "", "") ) {
ret = !user_in_list(user,
(const char **)invalid);
}
@@ -564,9 +563,11 @@ static BOOL user_ok(const char *user, int snum)
str_list_copy(&valid, lp_valid_users(snum));
if ( valid &&
str_list_substitute(valid, "%S", lp_servicename(snum)) ) {
- if ( valid &&
- str_list_sub_basic(valid,
- current_user_info.smb_name) ) {
+
+ /* This is used in sec=share only, so no current user
+ * around to pass to str_list_sub_basic() */
+
+ if ( valid && str_list_sub_basic(valid, "", "") ) {
ret = user_in_list(user, (const char **)valid);
}
}
diff --git a/source/smbd/pipes.c b/source/smbd/pipes.c
index 2d90383706b..52660da2ffe 100644
--- a/source/smbd/pipes.c
+++ b/source/smbd/pipes.c
@@ -31,6 +31,21 @@
#define PIPE "\\PIPE\\"
#define PIPELEN strlen(PIPE)
+#define MAX_PIPE_NAME_LEN 24
+
+/* PIPE/<name>/<pid>/<pnum> */
+#define PIPEDB_KEY_FORMAT "PIPE/%s/%u/%d"
+
+struct pipe_dbrec {
+ struct process_id pid;
+ int pnum;
+ uid_t uid;
+
+ char name[MAX_PIPE_NAME_LEN];
+ fstring user;
+};
+
+
extern struct pipe_id_info pipe_names[];
/****************************************************************************
@@ -284,6 +299,8 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf)
if (!close_rpc_pipe_hnd(p)) {
return ERROR_DOS(ERRDOS,ERRbadfid);
}
+
+ /* TODO: REMOVE PIPE FROM DB */
return(outsize);
}
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index 1c2cf3091fe..4cdb0908ce8 100644
--- a/source/smbd/posix_acls.c
+++ b/source/smbd/posix_acls.c
@@ -169,7 +169,7 @@ static char *create_pai_buf(canon_ace *file_ace_list, canon_ace *dir_ace_list, B
*store_size = PAI_ENTRIES_BASE + ((num_entries + num_def_entries)*PAI_ENTRY_LENGTH);
- pai_buf = SMB_MALLOC(*store_size);
+ pai_buf = (char *)SMB_MALLOC(*store_size);
if (!pai_buf) {
return NULL;
}
@@ -441,7 +441,7 @@ static struct pai_val *load_inherited_info(files_struct *fsp)
if (!lp_map_acl_inherit(SNUM(fsp->conn)))
return NULL;
- if ((pai_buf = SMB_MALLOC(pai_buf_size)) == NULL)
+ if ((pai_buf = (char *)SMB_MALLOC(pai_buf_size)) == NULL)
return NULL;
do {
@@ -462,7 +462,7 @@ static struct pai_val *load_inherited_info(files_struct *fsp)
if (pai_buf_size > 1024*1024) {
return NULL; /* Limit malloc to 1mb. */
}
- if ((pai_buf = SMB_MALLOC(pai_buf_size)) == NULL)
+ if ((pai_buf = (char *)SMB_MALLOC(pai_buf_size)) == NULL)
return NULL;
}
} while (ret == -1);
@@ -860,36 +860,36 @@ static SEC_ACCESS map_canon_ace_perms(int snum, int *pacl_type, DOM_SID *powner_
#define FILE_SPECIFIC_WRITE_BITS (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_EA|FILE_WRITE_ATTRIBUTES)
#define FILE_SPECIFIC_EXECUTE_BITS (FILE_EXECUTE)
-static mode_t map_nt_perms( SEC_ACCESS sec_access, int type)
+static mode_t map_nt_perms( uint32 *mask, int type)
{
mode_t mode = 0;
switch(type) {
case S_IRUSR:
- if(sec_access.mask & GENERIC_ALL_ACCESS)
+ if((*mask) & GENERIC_ALL_ACCESS)
mode = S_IRUSR|S_IWUSR|S_IXUSR;
else {
- mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRUSR : 0;
- mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWUSR : 0;
- mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXUSR : 0;
+ mode |= ((*mask) & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRUSR : 0;
+ mode |= ((*mask) & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWUSR : 0;
+ mode |= ((*mask) & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXUSR : 0;
}
break;
case S_IRGRP:
- if(sec_access.mask & GENERIC_ALL_ACCESS)
+ if((*mask) & GENERIC_ALL_ACCESS)
mode = S_IRGRP|S_IWGRP|S_IXGRP;
else {
- mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRGRP : 0;
- mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWGRP : 0;
- mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXGRP : 0;
+ mode |= ((*mask) & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRGRP : 0;
+ mode |= ((*mask) & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWGRP : 0;
+ mode |= ((*mask) & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXGRP : 0;
}
break;
case S_IROTH:
- if(sec_access.mask & GENERIC_ALL_ACCESS)
+ if((*mask) & GENERIC_ALL_ACCESS)
mode = S_IROTH|S_IWOTH|S_IXOTH;
else {
- mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IROTH : 0;
- mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWOTH : 0;
- mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXOTH : 0;
+ mode |= ((*mask) & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IROTH : 0;
+ mode |= ((*mask) & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWOTH : 0;
+ mode |= ((*mask) & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXOTH : 0;
}
break;
}
@@ -1408,7 +1408,7 @@ static BOOL create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst,
* S_I(R|W|X)USR bits.
*/
- current_ace->perms |= map_nt_perms( psa->info, S_IRUSR);
+ current_ace->perms |= map_nt_perms( &psa->info.mask, S_IRUSR);
current_ace->attr = (psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED) ? ALLOW_ACE : DENY_ACE;
current_ace->inherited = ((psa->flags & SEC_ACE_FLAG_INHERITED_ACE) ? True : False);
@@ -3031,8 +3031,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
return -1;
}
- fsp = open_file_fchmod(conn,fname,&st);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(open_file_fchmod(conn,fname,&st,&fsp))) {
return -1;
}
@@ -4351,7 +4350,7 @@ SEC_DESC* get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname)
DEBUG(0,("get_nt_acl_no_snum: talloc() failed!\n"));
return NULL;
}
-
+
if (!(conn.params = TALLOC_P(conn.mem_ctx, struct share_params))) {
DEBUG(0,("get_nt_acl_no_snum: talloc() failed!\n"));
TALLOC_FREE(conn.mem_ctx);
diff --git a/source/smbd/process.c b/source/smbd/process.c
index c5485defc9b..cf61e16a157 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -21,7 +21,7 @@
#include "includes.h"
-extern uint16 global_smbpid;
+uint16 global_smbpid;
extern int keepalive;
extern struct auth_context *negprot_global_auth_context;
extern int smb_echo_count;
@@ -171,7 +171,6 @@ BOOL open_was_deferred(uint16 mid)
for (pml = deferred_open_queue; pml; pml = pml->next) {
if (SVAL(pml->buf.data,smb_mid) == mid) {
- set_saved_ntstatus(NT_STATUS_OK);
return True;
}
}
@@ -462,11 +461,11 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
int sav;
START_PROFILE(smbd_idle);
- maxfd = select_on_fd(smbd_server_fd(), maxfd, &fds);
- maxfd = select_on_fd(change_notify_fd(), maxfd, &fds);
- maxfd = select_on_fd(oplock_notify_fd(), maxfd, &fds);
+ maxfd = select_on_fd(smbd_server_fd(), maxfd, &fds);
+ maxfd = select_on_fd(change_notify_fd(), maxfd, &fds);
+ maxfd = select_on_fd(oplock_notify_fd(), maxfd, &fds);
- selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&to);
+ selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&to);
sav = errno;
END_PROFILE(smbd_idle);
@@ -893,7 +892,6 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
pid = sys_getpid();
errno = 0;
- set_saved_ntstatus(NT_STATUS_OK);
last_message = type;
@@ -962,7 +960,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
}
if (!change_to_user(conn,session_tag)) {
- return(ERROR_FORCE_DOS(ERRSRV,ERRbaduid));
+ return(ERROR_NT(NT_STATUS_DOS(ERRSRV,ERRbaduid)));
}
/* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
@@ -1033,60 +1031,6 @@ static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
}
/****************************************************************************
- Keep track of the number of running smbd's. This functionality is used to
- 'hard' limit Samba overhead on resource constrained systems.
-****************************************************************************/
-
-static BOOL process_count_update_successful = False;
-
-static int32 increment_smbd_process_count(void)
-{
- int32 total_smbds;
-
- if (lp_max_smbd_processes()) {
- total_smbds = 0;
- if (tdb_change_int32_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, 1) == -1)
- return 1;
- process_count_update_successful = True;
- return total_smbds + 1;
- }
- return 1;
-}
-
-void decrement_smbd_process_count(void)
-{
- int32 total_smbds;
-
- if (lp_max_smbd_processes() && process_count_update_successful) {
- total_smbds = 1;
- tdb_change_int32_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, -1);
- }
-}
-
-static BOOL smbd_process_limit(void)
-{
- int32 total_smbds;
-
- if (lp_max_smbd_processes()) {
-
- /* Always add one to the smbd process count, as exit_server() always
- * subtracts one.
- */
-
- if (!conn_tdb_ctx()) {
- DEBUG(0,("smbd_process_limit: max smbd processes parameter set with status parameter not \
-set. Ignoring max smbd restriction.\n"));
- return False;
- }
-
- total_smbds = increment_smbd_process_count();
- return total_smbds > lp_max_smbd_processes();
- }
- else
- return False;
-}
-
-/****************************************************************************
Process an smb from the client
****************************************************************************/
@@ -1104,8 +1048,8 @@ static void process_smb(char *inbuf, char *outbuf)
deny parameters before doing any parsing of the packet
passed to us by the client. This prevents attacks on our
parsing code from hosts not in the hosts allow list */
- if (smbd_process_limit() ||
- !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1))) {
+ if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
+ lp_hostsdeny(-1))) {
/* send a negative session response "not listening on calling name" */
static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
DEBUG( 1, ( "Connection denied from %s\n", client_addr() ) );
@@ -1277,7 +1221,7 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
}
/****************************************************************************
- Setup the needed select timeout.
+ Setup the needed select timeout in milliseconds.
****************************************************************************/
static int setup_select_timeout(void)
@@ -1285,16 +1229,17 @@ static int setup_select_timeout(void)
int select_timeout;
int t;
- select_timeout = blocking_locks_timeout(SMBD_SELECT_TIMEOUT);
- select_timeout *= 1000;
+ select_timeout = blocking_locks_timeout_ms(SMBD_SELECT_TIMEOUT*1000);
t = change_notify_timeout();
DEBUG(10, ("change_notify_timeout: %d\n", t));
- if (t != -1)
+ if (t != -1) {
select_timeout = MIN(select_timeout, t*1000);
+ }
- if (print_notify_messages_pending())
+ if (print_notify_messages_pending()) {
select_timeout = MIN(select_timeout, 1000);
+ }
return select_timeout;
}
@@ -1483,7 +1428,7 @@ machine %s in domain %s.\n", global_myname(), lp_workgroup()));
* Check to see if we have any blocking locks
* outstanding on the queue.
*/
- process_blocking_lock_queue(t);
+ process_blocking_lock_queue();
/* update printer queue caches if necessary */
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index bbca95b0d30..a0596643f81 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -448,6 +448,7 @@ size_t srvstr_get_path_wcard(char *inbuf, char *dest, const char *src, size_t de
} else {
*err = check_path_syntax_wcard(dest, tmppath, contains_wcard);
}
+
return ret;
}
@@ -474,6 +475,7 @@ size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len
} else {
*err = check_path_syntax(dest, tmppath);
}
+
return ret;
}
@@ -830,6 +832,14 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBchkpth);
+
+ /* Strange DOS error code semantics only for chkpth... */
+ if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) {
+ if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) {
+ /* We need to map to ERRbadpath */
+ status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
+ }
+ }
return ERROR_NT(status);
}
@@ -1391,25 +1401,25 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
if (!map_open_params_to_ntcreate(fname, deny_mode, OPENX_FILE_EXISTS_OPEN,
&access_mask, &share_mode, &create_disposition, &create_options)) {
END_PROFILE(SMBopen);
- return ERROR_FORCE_DOS(ERRDOS, ERRbadaccess);
+ return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess));
}
- fsp = open_file_ntcreate(conn,fname,&sbuf,
+ status = open_file_ntcreate(conn,fname,&sbuf,
access_mask,
share_mode,
create_disposition,
create_options,
dos_attr,
oplock_request,
- &info);
+ &info, &fsp);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBopen);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
return -1;
}
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
+ return ERROR_NT(status);
}
size = sbuf.st_size;
@@ -1514,25 +1524,25 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
&create_disposition,
&create_options)) {
END_PROFILE(SMBopenX);
- return ERROR_FORCE_DOS(ERRDOS, ERRbadaccess);
+ return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRbadaccess));
}
- fsp = open_file_ntcreate(conn,fname,&sbuf,
+ status = open_file_ntcreate(conn,fname,&sbuf,
access_mask,
share_mode,
create_disposition,
create_options,
smb_attr,
oplock_request,
- &smb_action);
+ &smb_action, &fsp);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBopenX);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
return -1;
}
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
+ return ERROR_NT(status);
}
size = sbuf.st_size;
@@ -1693,22 +1703,22 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
}
/* Open file using ntcreate. */
- fsp = open_file_ntcreate(conn,fname,&sbuf,
+ status = open_file_ntcreate(conn,fname,&sbuf,
access_mask,
share_mode,
create_disposition,
create_options,
fattr,
oplock_request,
- NULL);
+ NULL, &fsp);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcreate);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
return -1;
}
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
+ return ERROR_NT(status);
}
outsize = set_message(outbuf,1,0,True);
@@ -1777,25 +1787,25 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
SMB_VFS_STAT(conn,fname,&sbuf);
/* We should fail if file does not exist. */
- fsp = open_file_ntcreate(conn,fname,&sbuf,
+ status = open_file_ntcreate(conn,fname,&sbuf,
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
0,
fattr,
oplock_request,
- NULL);
+ NULL, &fsp);
/* close fd from smb_mkstemp() */
close(tmpfd);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBctemp);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
return -1;
}
- return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
+ return ERROR_NT(status);
}
outsize = set_message(outbuf,1,0,True);
@@ -1843,6 +1853,7 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype,
{
files_struct *fsp;
uint32 fmode;
+ NTSTATUS status;
if (!CAN_WRITE(conn)) {
return NT_STATUS_MEDIA_WRITE_PROTECTED;
@@ -1857,25 +1868,16 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype,
return NT_STATUS_OK;
}
- /* We need a better way to return NT status codes from open... */
- set_saved_ntstatus(NT_STATUS_OK);
-
- fsp = open_file_ntcreate(conn, fname, pst,
+ status = open_file_ntcreate(conn, fname, pst,
DELETE_ACCESS,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
0,
- NULL);
+ NULL, &fsp);
- if (!fsp) {
- NTSTATUS ret = get_saved_ntstatus();
- if (!NT_STATUS_IS_OK(ret)) {
- set_saved_ntstatus(NT_STATUS_OK);
- return ret;
- }
- set_saved_ntstatus(NT_STATUS_OK);
+ if (!NT_STATUS_IS_OK(status)) {
return NT_STATUS_ACCESS_DENIED;
}
close_file(fsp,NORMAL_CLOSE);
@@ -1891,6 +1893,7 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL b
SMB_STRUCT_STAT sbuf;
uint32 fattr;
files_struct *fsp;
+ NTSTATUS status;
DEBUG(10,("can_delete: %s, dirtype = %d\n", fname, dirtype ));
@@ -1950,26 +1953,17 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL b
/* On open checks the open itself will check the share mode, so
don't do it here as we'll get it wrong. */
- /* We need a better way to return NT status codes from open... */
- set_saved_ntstatus(NT_STATUS_OK);
-
- fsp = open_file_ntcreate(conn, fname, &sbuf,
+ status = open_file_ntcreate(conn, fname, &sbuf,
DELETE_ACCESS,
FILE_SHARE_NONE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
0,
- NULL);
+ NULL, &fsp);
- if (!fsp) {
- NTSTATUS ret = get_saved_ntstatus();
- if (!NT_STATUS_IS_OK(ret)) {
- set_saved_ntstatus(NT_STATUS_OK);
- return ret;
- }
- set_saved_ntstatus(NT_STATUS_OK);
- return NT_STATUS_ACCESS_DENIED;
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
close_file(fsp,NORMAL_CLOSE);
}
@@ -2352,7 +2346,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
/* ensure we don't overrun the packet size */
maxcount = MIN(65535,maxcount);
- if (!is_locked(fsp,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
+ if (!is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
SMB_STRUCT_STAT st;
SMB_OFF_T size = 0;
@@ -2398,7 +2392,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
size_t numtoread;
NTSTATUS status;
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- BOOL my_lock_ctx = False;
+ struct byte_range_lock *br_lck = NULL;
START_PROFILE(SMBlockread);
CHECK_FSP(fsp,conn);
@@ -2423,42 +2417,17 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
* Note that the requested lock size is unaffected by max_recv.
*/
- status = do_lock_spin(fsp,
- SVAL(inbuf,smb_pid),
- (SMB_BIG_UINT)numtoread,
- (SMB_BIG_UINT)startpos,
- WRITE_LOCK,
- WINDOWS_LOCK,
- &my_lock_ctx);
+ br_lck = do_lock(fsp,
+ (uint32)SVAL(inbuf,smb_pid),
+ (SMB_BIG_UINT)numtoread,
+ (SMB_BIG_UINT)startpos,
+ WRITE_LOCK,
+ WINDOWS_LOCK,
+ False, /* Non-blocking lock. */
+ &status);
+ TALLOC_FREE(br_lck);
if (NT_STATUS_V(status)) {
-#if 0
- /*
- * We used to make lockread a blocking lock. It turns out
- * that this isn't on W2k. Found by the Samba 4 RAW-READ torture
- * tester. JRA.
- */
-
- if (lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) {
- /*
- * A blocking lock was requested. Package up
- * this smb into a queued request and push it
- * onto the blocking lock queue.
- */
- if(push_blocking_lock_request(inbuf, length,
- fsp,
- -1,
- 0,
- SVAL(inbuf,smb_pid),
- WRITE_LOCK,
- WINDOWS_LOCK,
- (SMB_BIG_UINT)startpos,
- (SMB_BIG_UINT)numtoread)) {
- END_PROFILE(SMBlockread);
- return -1;
- }
- }
-#endif
END_PROFILE(SMBlockread);
return ERROR_NT(status);
}
@@ -2531,7 +2500,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
data = smb_buf(outbuf) + 3;
- if (is_locked(fsp,(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) {
+ if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtoread,(SMB_BIG_UINT)startpos, READ_LOCK)) {
END_PROFILE(SMBread);
return ERROR_DOS(ERRDOS,ERRlock);
}
@@ -2738,7 +2707,7 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
}
- if (is_locked(fsp,(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) {
+ if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) {
END_PROFILE(SMBreadX);
return ERROR_DOS(ERRDOS,ERRlock);
}
@@ -2801,7 +2770,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
SCVAL(inbuf,smb_com,SMBwritec);
SCVAL(outbuf,smb_com,SMBwritec);
- if (is_locked(fsp,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+ if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwritebraw);
return(ERROR_DOS(ERRDOS,ERRlock));
}
@@ -2859,6 +2828,10 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
}
nwritten = write_file(fsp,inbuf+4,startpos+nwritten,numtowrite);
+ if (nwritten == -1) {
+ END_PROFILE(SMBwritebraw);
+ return(UNIXERROR(ERRHRD,ERRdiskfull));
+ }
if (nwritten < (ssize_t)numtowrite) {
SCVAL(outbuf,smb_rcls,ERRHRD);
@@ -2922,7 +2895,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
data = smb_buf(inbuf) + 3;
- if (numtowrite && is_locked(fsp,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+ if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwriteunlock);
return ERROR_DOS(ERRDOS,ERRlock);
}
@@ -2945,7 +2918,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf,
if (numtowrite) {
status = do_unlock(fsp,
- SVAL(inbuf,smb_pid),
+ (uint32)SVAL(inbuf,smb_pid),
(SMB_BIG_UINT)numtowrite,
(SMB_BIG_UINT)startpos,
WINDOWS_LOCK);
@@ -2999,7 +2972,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
data = smb_buf(inbuf) + 3;
- if (is_locked(fsp,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+ if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwrite);
return ERROR_DOS(ERRDOS,ERRlock);
}
@@ -3114,7 +3087,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
#endif /* LARGE_SMB_OFF_T */
}
- if (is_locked(fsp,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+ if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwriteX);
return ERROR_DOS(ERRDOS,ERRlock);
}
@@ -3389,7 +3362,7 @@ int reply_writeclose(connection_struct *conn,
mtime = srv_make_unix_date3(inbuf+smb_vwv4);
data = smb_buf(inbuf) + 1;
- if (numtowrite && is_locked(fsp,(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+ if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
END_PROFILE(SMBwriteclose);
return ERROR_DOS(ERRDOS,ERRlock);
}
@@ -3445,7 +3418,7 @@ int reply_lock(connection_struct *conn,
SMB_BIG_UINT count,offset;
NTSTATUS status;
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- BOOL my_lock_ctx = False;
+ struct byte_range_lock *br_lck = NULL;
START_PROFILE(SMBlock);
@@ -3459,35 +3432,18 @@ int reply_lock(connection_struct *conn,
DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
fsp->fh->fd, fsp->fnum, (double)offset, (double)count));
- status = do_lock_spin(fsp,
- SVAL(inbuf,smb_pid),
- count,
- offset,
- WRITE_LOCK,
- WINDOWS_LOCK,
- &my_lock_ctx);
+ br_lck = do_lock(fsp,
+ (uint32)SVAL(inbuf,smb_pid),
+ count,
+ offset,
+ WRITE_LOCK,
+ WINDOWS_LOCK,
+ False, /* Non-blocking lock. */
+ &status);
+
+ TALLOC_FREE(br_lck);
+
if (NT_STATUS_V(status)) {
-#if 0
- /* Tests using Samba4 against W2K show this call never creates a blocking lock. */
- if (lp_blocking_locks(SNUM(conn)) && !my_lock_ctx && ERROR_WAS_LOCK_DENIED(status)) {
- /*
- * A blocking lock was requested. Package up
- * this smb into a queued request and push it
- * onto the blocking lock queue.
- */
- if(push_blocking_lock_request(inbuf, length,
- fsp,
- -1,
- 0,
- SVAL(inbuf,smb_pid),
- WRITE_LOCK,
- WINDOWS_LOCK,
- offset, count)) {
- END_PROFILE(SMBlock);
- return -1;
- }
- }
-#endif
END_PROFILE(SMBlock);
return ERROR_NT(status);
}
@@ -3515,7 +3471,7 @@ int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size,
offset = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv3);
status = do_unlock(fsp,
- SVAL(inbuf,smb_pid),
+ (uint32)SVAL(inbuf,smb_pid),
count,
offset,
WINDOWS_LOCK);
@@ -3619,6 +3575,8 @@ int reply_printopen(connection_struct *conn,
{
int outsize = 0;
files_struct *fsp;
+ NTSTATUS status;
+
START_PROFILE(SMBsplopen);
if (!CAN_PRINT(conn)) {
@@ -3627,11 +3585,11 @@ int reply_printopen(connection_struct *conn,
}
/* Open for exclusive use, write only. */
- fsp = print_fsp_open(conn, NULL);
+ status = print_fsp_open(conn, NULL, &fsp);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBsplopen);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
+ return(ERROR_NT(status));
}
outsize = set_message(outbuf,1,0,True);
@@ -3859,6 +3817,17 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
status = mkdir_internal(conn, directory,bad_path);
if (!NT_STATUS_IS_OK(status)) {
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION) &&
+ !use_nt_status()) {
+ /*
+ * Yes, in the DOS error code case we get a
+ * ERRDOS:ERRnoaccess here. See BASE-SAMBA3ERROR
+ * samba4 torture test.
+ */
+ status = NT_STATUS_DOS(ERRDOS, ERRnoaccess);
+ }
+
END_PROFILE(SMBmkdir);
return ERROR_NT(status);
}
@@ -4760,6 +4729,7 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
pstring dest;
uint32 dosattrs;
uint32 new_create_disposition;
+ NTSTATUS status;
*err_ret = 0;
@@ -4788,16 +4758,16 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
}
}
- fsp1 = open_file_ntcreate(conn,src,&src_sbuf,
+ status = open_file_ntcreate(conn,src,&src_sbuf,
FILE_GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
INTERNAL_OPEN_ONLY,
- NULL);
+ NULL, &fsp1);
- if (!fsp1) {
+ if (!NT_STATUS_IS_OK(status)) {
return(False);
}
@@ -4806,16 +4776,16 @@ BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
ZERO_STRUCTP(&sbuf2);
}
- fsp2 = open_file_ntcreate(conn,dest,&sbuf2,
+ status = open_file_ntcreate(conn,dest,&sbuf2,
FILE_GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
new_create_disposition,
0,
dosattrs,
INTERNAL_OPEN_ONLY,
- NULL);
+ NULL, &fsp2);
- if (!fsp2) {
+ if (!NT_STATUS_IS_OK(status)) {
close_file(fsp1,ERROR_CLOSE);
return(False);
}
@@ -5016,8 +4986,12 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
END_PROFILE(SMBcopy);
return ERROR_DOS(ERRDOS,error);
} else {
- if((errno == ENOENT) && (bad_path1 || bad_path2)) {
- set_saved_error_triple(ERRDOS, ERRbadpath, NT_STATUS_OK);
+ if((errno == ENOENT) && (bad_path1 || bad_path2) &&
+ !use_nt_status()) {
+ /* Samba 3.0.22 has ERRDOS/ERRbadpath in the
+ * DOS error code case
+ */
+ return ERROR_DOS(ERRDOS, ERRbadpath);
}
END_PROFILE(SMBcopy);
return(UNIXERROR(ERRDOS,error));
@@ -5088,12 +5062,12 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
Get a lock pid, dealing with large count requests.
****************************************************************************/
-uint16 get_lock_pid( char *data, int data_offset, BOOL large_file_format)
+uint32 get_lock_pid( char *data, int data_offset, BOOL large_file_format)
{
if(!large_file_format)
- return SVAL(data,SMB_LPID_OFFSET(data_offset));
+ return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset));
else
- return SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
+ return (uint32)SVAL(data,SMB_LARGE_LPID_OFFSET(data_offset));
}
/****************************************************************************
@@ -5230,14 +5204,13 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
uint16 num_locks = SVAL(inbuf,smb_vwv7);
SMB_BIG_UINT count = 0, offset = 0;
- uint16 lock_pid;
+ uint32 lock_pid;
int32 lock_timeout = IVAL(inbuf,smb_vwv4);
int i;
char *data;
BOOL large_file_format =
(locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
BOOL err;
- BOOL my_lock_ctx = False;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
START_PROFILE(SMBlockingX);
@@ -5250,12 +5223,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
/* we don't support these - and CANCEL_LOCK makes w2k
and XP reboot so I don't really want to be
compatible! (tridge) */
- return ERROR_FORCE_DOS(ERRDOS, ERRnoatomiclocks);
- }
-
- if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
- /* Need to make this like a cancel.... JRA. */
- return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
+ return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks));
}
/* Check if this is an oplock break on a file
@@ -5369,7 +5337,9 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
/* Setup the timeout in seconds. */
- lock_timeout = ((lock_timeout == -1) ? -1 : (lock_timeout+999)/1000);
+ if (!lp_blocking_locks(SNUM(conn))) {
+ lock_timeout = 0;
+ }
/* Now do any requested locks */
data += ((large_file_format ? 20 : 10)*num_ulocks);
@@ -5378,7 +5348,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
of smb_lkrng structs */
for(i = 0; i < (int)num_locks; i++) {
- enum brl_type lock_type = ((locktype & 1) ? READ_LOCK:WRITE_LOCK);
+ enum brl_type lock_type = ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
+ READ_LOCK:WRITE_LOCK);
lock_pid = get_lock_pid( data, i, large_file_format);
count = get_lock_count( data, i, large_file_format);
offset = get_lock_offset( data, i, large_file_format, &err);
@@ -5396,50 +5367,101 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
(double)count, (unsigned int)lock_pid,
fsp->fsp_name, (int)lock_timeout ));
- status = do_lock_spin(fsp,
+ if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
+ if (lp_blocking_locks(SNUM(conn))) {
+
+ /* Schedule a message to ourselves to
+ remove the blocking lock record and
+ return the right error. */
+
+ if (!blocking_lock_cancel(fsp,
+ lock_pid,
+ offset,
+ count,
+ WINDOWS_LOCK,
+ locktype,
+ NT_STATUS_FILE_LOCK_CONFLICT)) {
+ END_PROFILE(SMBlockingX);
+ return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRcancelviolation));
+ }
+ }
+ /* Remove a matching pending lock. */
+ status = do_lock_cancel(fsp,
+ lock_pid,
+ count,
+ offset,
+ WINDOWS_LOCK);
+ } else {
+ BOOL blocking_lock = lock_timeout ? True : False;
+ BOOL defer_lock = False;
+ struct byte_range_lock *br_lck;
+
+ br_lck = do_lock(fsp,
lock_pid,
count,
offset,
lock_type,
WINDOWS_LOCK,
- &my_lock_ctx);
+ blocking_lock,
+ &status);
+
+ if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
+ /* Windows internal resolution for blocking locks seems
+ to be about 200ms... Don't wait for less than that. JRA. */
+ if (lock_timeout != -1 && lock_timeout < lp_lock_spin_time()) {
+ lock_timeout = lp_lock_spin_time();
+ }
+ defer_lock = True;
+ }
- if (NT_STATUS_V(status)) {
- /*
- * Interesting fact found by IFSTEST /t
- * LockOverlappedTest... Even if it's our own lock
- * context, we need to wait here as there may be an
- * unlock on the way. So I removed a "&&
- * !my_lock_ctx" from the following if statement. JRA.
- */
- if ((lock_timeout != 0) &&
- lp_blocking_locks(SNUM(conn)) &&
- ERROR_WAS_LOCK_DENIED(status)) {
+ /* This heuristic seems to match W2K3 very well. If a
+ lock sent with timeout of zero would fail with NT_STATUS_FILE_LOCK_CONFLICT
+ it pretends we asked for a timeout of between 150 - 300 milliseconds as
+ far as I can tell. Replacement for do_lock_spin(). JRA. */
+
+ if (br_lck && lp_blocking_locks(SNUM(conn)) && !blocking_lock &&
+ NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT)) {
+ defer_lock = True;
+ lock_timeout = lp_lock_spin_time();
+ }
+
+ if (br_lck && defer_lock) {
/*
* A blocking lock was requested. Package up
* this smb into a queued request and push it
* onto the blocking lock queue.
*/
- if(push_blocking_lock_request(inbuf, length,
- fsp,
- lock_timeout,
- i,
- lock_pid,
- lock_type,
- WINDOWS_LOCK,
- offset,
- count)) {
+ if(push_blocking_lock_request(br_lck,
+ inbuf, length,
+ fsp,
+ lock_timeout,
+ i,
+ lock_pid,
+ lock_type,
+ WINDOWS_LOCK,
+ offset,
+ count)) {
+ TALLOC_FREE(br_lck);
END_PROFILE(SMBlockingX);
return -1;
}
}
- break;
+
+ TALLOC_FREE(br_lck);
+ }
+
+ if (NT_STATUS_V(status)) {
+ END_PROFILE(SMBlockingX);
+ return ERROR_NT(status);
}
}
/* If any of the above locks failed, then we must unlock
all of the previous locks (X/Open spec). */
- if (i != num_locks && num_locks != 0) {
+
+ if (!(locktype & LOCKING_ANDX_CANCEL_LOCK) &&
+ (i != num_locks) &&
+ (num_locks != 0)) {
/*
* Ensure we don't do a remove on the lock that just failed,
* as under POSIX rules, if we have a lock already there, we
@@ -5526,7 +5548,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
tcount = maxcount;
total_read = 0;
- if (is_locked(fsp,(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
+ if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
END_PROFILE(SMBreadBmpx);
return ERROR_DOS(ERRDOS,ERRlock);
}
@@ -5658,7 +5680,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
not an SMBwritebmpx - set this up now so we don't forget */
SCVAL(outbuf,smb_com,SMBwritec);
- if (is_locked(fsp,(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) {
+ if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)tcount,(SMB_BIG_UINT)startpos,WRITE_LOCK)) {
END_PROFILE(SMBwriteBmpx);
return(ERROR_DOS(ERRDOS,ERRlock));
}
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 2bfeae9f541..593e2bfb12d 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -36,6 +36,7 @@ extern struct auth_context *negprot_global_auth_context;
extern pstring user_socket_options;
extern SIG_ATOMIC_T got_sig_term;
extern SIG_ATOMIC_T reload_after_sighup;
+static SIG_ATOMIC_T got_sig_cld;
#ifdef WITH_DFS
extern int dcelogin_atmost_once;
@@ -93,6 +94,15 @@ static void sig_hup(int sig)
}
/****************************************************************************
+ Catch a sigcld
+****************************************************************************/
+static void sig_cld(int sig)
+{
+ got_sig_cld = 1;
+ sys_select_signal(SIGCLD);
+}
+
+/****************************************************************************
Send a SIGTERM to our process group.
*****************************************************************************/
@@ -189,6 +199,54 @@ static void msg_inject_fault(int msg_type, struct process_id src,
}
#endif /* DEVELOPER */
+struct child_pid {
+ struct child_pid *prev, *next;
+ pid_t pid;
+};
+
+static struct child_pid *children;
+static int num_children;
+
+static void add_child_pid(pid_t pid)
+{
+ struct child_pid *child;
+
+ if (lp_max_smbd_processes() == 0) {
+ /* Don't bother with the child list if we don't care anyway */
+ return;
+ }
+
+ child = SMB_MALLOC_P(struct child_pid);
+ if (child == NULL) {
+ DEBUG(0, ("Could not add child struct -- malloc failed\n"));
+ return;
+ }
+ child->pid = pid;
+ DLIST_ADD(children, child);
+ num_children += 1;
+}
+
+static void remove_child_pid(pid_t pid)
+{
+ struct child_pid *child;
+
+ if (lp_max_smbd_processes() == 0) {
+ /* Don't bother with the child list if we don't care anyway */
+ return;
+ }
+
+ for (child = children; child != NULL; child = child->next) {
+ if (child->pid == pid) {
+ struct child_pid *tmp = child;
+ DLIST_REMOVE(children, child);
+ SAFE_FREE(tmp);
+ num_children -= 1;
+ return;
+ }
+ }
+
+ DEBUG(0, ("Could not find child %d -- ignoring\n", (int)pid));
+}
/****************************************************************************
Have we reached the process limit ?
@@ -201,27 +259,7 @@ static BOOL allowable_number_of_smbd_processes(void)
if (!max_processes)
return True;
- {
- TDB_CONTEXT *tdb = conn_tdb_ctx();
- int32 val;
- if (!tdb) {
- DEBUG(0,("allowable_number_of_smbd_processes: can't open connection tdb.\n" ));
- return False;
- }
-
- val = tdb_fetch_int32(tdb, "INFO/total_smbds");
- if (val == -1 && (tdb_error(tdb) != TDB_ERR_NOEXIST)) {
- DEBUG(0,("allowable_number_of_smbd_processes: can't fetch INFO/total_smbds. Error %s\n",
- tdb_errorstr(tdb) ));
- return False;
- }
- if (val > max_processes) {
- DEBUG(0,("allowable_number_of_smbd_processes: number of processes (%d) is over allowed limit (%d)\n",
- val, max_processes ));
- return False;
- }
- }
- return True;
+ return num_children < max_processes;
}
/****************************************************************************
@@ -255,7 +293,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
#endif
/* Stop zombies */
- CatchChild();
+ CatchSignal(SIGCLD, sig_cld);
FD_ZERO(&listen_set);
@@ -392,6 +430,15 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
/* Ensure we respond to PING and DEBUG messages from the main smbd. */
message_dispatch();
+ if (got_sig_cld) {
+ pid_t pid;
+ got_sig_cld = False;
+
+ while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) {
+ remove_child_pid(pid);
+ }
+ }
+
memcpy((char *)&lfds, (char *)&listen_set,
sizeof(listen_set));
@@ -421,6 +468,7 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
for( ; num > 0; num--) {
struct sockaddr addr;
socklen_t in_addrlen = sizeof(addr);
+ pid_t child = 0;
s = -1;
for(i = 0; i < num_sockets; i++) {
@@ -450,8 +498,14 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
if (smbd_server_fd() != -1 && interactive)
return True;
- if (allowable_number_of_smbd_processes() && smbd_server_fd() != -1 && sys_fork()==0) {
+ if (allowable_number_of_smbd_processes() &&
+ smbd_server_fd() != -1 &&
+ ((child = sys_fork())==0)) {
/* Child code ... */
+
+ /* Stop zombies, the parent explicitly handles
+ * them, counting worker smbds. */
+ CatchChild();
/* close the listening socket(s) */
for(i = 0; i < num_sockets; i++)
@@ -467,7 +521,8 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
/* this is needed so that we get decent entries
in smbstatus for port 445 connects */
- set_remote_machine_name(get_peer_addr(smbd_server_fd()), False);
+ set_remote_machine_name(get_peer_addr(smbd_server_fd()),
+ False);
/* Reset the state of the random
* number generation system, so
@@ -475,7 +530,8 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
* numbers as each other */
set_need_random_reseed();
- /* tdb needs special fork handling - remove CLEAR_IF_FIRST flags */
+ /* tdb needs special fork handling - remove
+ * CLEAR_IF_FIRST flags */
if (tdb_reopen_all(1) == -1) {
DEBUG(0,("tdb_reopen_all failed.\n"));
smb_panic("tdb_reopen_all failed.");
@@ -496,6 +552,10 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
smbd_set_server_fd(-1);
+ if (child != 0) {
+ add_child_pid(child);
+ }
+
/* Force parent to check log size after
* spawning child. Fix from
* klausr@ITAP.Physik.Uni-Stuttgart.De. The
@@ -637,7 +697,6 @@ static void exit_server_common(enum server_exit_reason how,
yield_connection(NULL,"");
respond_to_all_remaining_local_messages();
- decrement_smbd_process_count();
#ifdef WITH_DFS
if (dcelogin_atmost_once) {
@@ -666,9 +725,7 @@ static void exit_server_common(enum server_exit_reason how,
}
DEBUGLEVEL = oldlevel;
-#if DUMP_CORE
dump_core();
-#endif
} else {
DEBUG(3,("Server exit (%s)\n",
@@ -912,18 +969,12 @@ void build_options(BOOL screen);
if (!message_init())
exit(1);
- /* Initialize our global sam sid first -- quite a lot of the other
- * initialization routines further down depend on it.
- */
-
/* Initialise the password backed before the global_sam_sid
to ensure that we fetch from ldap before we make a domain sid up */
if(!initialize_password_db(False))
exit(1);
- /* Fail gracefully if we can't open secrets.tdb */
-
if (!secrets_init()) {
DEBUG(0, ("ERROR: smbd can not open secrets.tdb\n"));
exit(1);
diff --git a/source/smbd/service.c b/source/smbd/service.c
index 13f7f7866ad..60ba85ab65e 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -380,35 +380,38 @@ static NTSTATUS find_forced_user(int snum, BOOL vuser_is_guest,
{
TALLOC_CTX *mem_ctx;
char *fuser, *found_username;
+ struct nt_user_token *tmp_token;
NTSTATUS result;
- mem_ctx = talloc_new(NULL);
- if (mem_ctx == NULL) {
+ if (!(mem_ctx = talloc_new(NULL))) {
DEBUG(0, ("talloc_new failed\n"));
return NT_STATUS_NO_MEMORY;
}
- fuser = talloc_string_sub(mem_ctx, lp_force_user(snum), "%S",
- lp_servicename(snum));
- if (fuser == NULL) {
- result = NT_STATUS_NO_MEMORY;
- goto done;
+ if (!(fuser = talloc_string_sub(mem_ctx, lp_force_user(snum), "%S",
+ lp_servicename(snum)))) {
+ TALLOC_FREE(mem_ctx);
+ return NT_STATUS_NO_MEMORY;
+
}
result = create_token_from_username(mem_ctx, fuser, vuser_is_guest,
uid, gid, &found_username,
- token);
+ &tmp_token);
if (!NT_STATUS_IS_OK(result)) {
- goto done;
+ TALLOC_FREE(mem_ctx);
+ return result;
+ }
+
+ if (!(*token = dup_nt_token(NULL, tmp_token))) {
+ TALLOC_FREE(mem_ctx);
+ return NT_STATUS_NO_MEMORY;
}
- talloc_steal(NULL, *token);
fstrcpy(username, found_username);
- result = NT_STATUS_OK;
- done:
TALLOC_FREE(mem_ctx);
- return result;
+ return NT_STATUS_OK;
}
/*
@@ -764,7 +767,11 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
{
pstring s;
pstrcpy(s,lp_pathname(snum));
- standard_sub_conn(conn,s,sizeof(s));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ s, sizeof(s));
set_conn_connectpath(conn,s);
DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
lp_servicename(snum)));
@@ -778,11 +785,16 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
*/
{
- BOOL can_write = share_access_check(conn, snum, vuser,
+ NT_USER_TOKEN *token = conn->nt_user_token ?
+ conn->nt_user_token : vuser->nt_user_token;
+
+ BOOL can_write = share_access_check(token,
+ lp_servicename(snum),
FILE_WRITE_DATA);
if (!can_write) {
- if (!share_access_check(conn, snum, vuser,
+ if (!share_access_check(token,
+ lp_servicename(snum),
FILE_READ_DATA)) {
/* No access, read or write. */
DEBUG(0,("make_connection: connection to %s "
@@ -839,7 +851,11 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
if (*lp_rootpreexec(snum)) {
pstring cmd;
pstrcpy(cmd,lp_rootpreexec(snum));
- standard_sub_conn(conn,cmd,sizeof(cmd));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ cmd, sizeof(cmd));
DEBUG(5,("cmd=%s\n",cmd));
ret = smbrun(cmd,NULL);
if (ret != 0 && lp_rootpreexec_close(snum)) {
@@ -872,7 +888,11 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
if (*lp_preexec(snum)) {
pstring cmd;
pstrcpy(cmd,lp_preexec(snum));
- standard_sub_conn(conn,cmd,sizeof(cmd));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ cmd, sizeof(cmd));
ret = smbrun(cmd,NULL);
if (ret != 0 && lp_preexec_close(snum)) {
DEBUG(1,("preexec gave %d - failing connection\n",
@@ -1171,7 +1191,11 @@ void close_cnum(connection_struct *conn, uint16 vuid)
change_to_user(conn, vuid)) {
pstring cmd;
pstrcpy(cmd,lp_postexec(SNUM(conn)));
- standard_sub_conn(conn,cmd,sizeof(cmd));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ cmd, sizeof(cmd));
smbrun(cmd,NULL);
change_to_root_user();
}
@@ -1181,7 +1205,11 @@ void close_cnum(connection_struct *conn, uint16 vuid)
if (*lp_rootpostexec(SNUM(conn))) {
pstring cmd;
pstrcpy(cmd,lp_rootpostexec(SNUM(conn)));
- standard_sub_conn(conn,cmd,sizeof(cmd));
+ standard_sub_advanced(lp_servicename(SNUM(conn)), conn->user,
+ conn->connectpath, conn->gid,
+ get_current_username(),
+ current_user_info.domain,
+ cmd, sizeof(cmd));
smbrun(cmd,NULL);
}
diff --git a/source/smbd/share_access.c b/source/smbd/share_access.c
index 3bc442f1baf..adb9d169642 100644
--- a/source/smbd/share_access.c
+++ b/source/smbd/share_access.c
@@ -28,6 +28,8 @@
* + and & may be combined
*/
+extern userdom_struct current_user_info;
+
static BOOL do_group_checks(const char **name, const char **pattern)
{
if ((*name)[0] == '@') {
@@ -74,7 +76,8 @@ static BOOL token_contains_name(TALLOC_CTX *mem_ctx,
enum lsa_SidType type;
if (username != NULL) {
- name = talloc_sub_basic(mem_ctx, username, name);
+ name = talloc_sub_basic(mem_ctx, username,
+ current_user_info.domain, name);
}
if (sharename != NULL) {
name = talloc_string_sub(mem_ctx, name, "%S", sharename);
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index 068179cd4bb..f2f0150f6f8 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -171,7 +171,7 @@ static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_str
}
for (i = 0, ea_namelist = TALLOC_ARRAY(mem_ctx, char, ea_namelist_size); i < 6;
- ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) {
+ ea_namelist = TALLOC_REALLOC_ARRAY(mem_ctx, ea_namelist, char, ea_namelist_size), i++) {
if (!ea_namelist) {
return NULL;
@@ -571,7 +571,8 @@ int send_trans2_replies(char *outbuf,
char *params,
int paramsize,
char *pdata,
- int datasize)
+ int datasize,
+ int max_data_bytes)
{
/* As we are using a protocol > LANMAN1 then the max_send
variable must have been set in the sessetupX call.
@@ -592,6 +593,18 @@ int send_trans2_replies(char *outbuf,
set_message(outbuf,10,0,True);
+ /* Modify the data_to_send and datasize and set the error if
+ we're trying to send more than max_data_bytes. We still send
+ the part of the packet(s) that fit. Strange, but needed
+ for OS/2. */
+
+ if (max_data_bytes > 0 && datasize > max_data_bytes) {
+ DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
+ max_data_bytes, datasize ));
+ datasize = data_to_send = max_data_bytes;
+ error_packet_set(outbuf,ERRDOS,ERRbufferoverflow,STATUS_BUFFER_OVERFLOW,__LINE__,__FILE__);
+ }
+
/* If there genuinely are no parameters or data to send just send the empty packet */
if(params_to_send == 0 && data_to_send == 0) {
@@ -835,16 +848,16 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
- fsp = open_file_ntcreate(conn,fname,&sbuf,
+ status = open_file_ntcreate(conn,fname,&sbuf,
access_mask,
share_mode,
create_disposition,
create_options,
open_attr,
oplock_request,
- &smb_action);
+ &smb_action, &fsp);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(status)) {
talloc_destroy(ctx);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
@@ -930,7 +943,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
}
/* Send the required number of replies */
- send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0, max_data_bytes);
return -1;
}
@@ -1041,7 +1054,7 @@ static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *ps
****************************************************************************/
static BOOL get_lanman2_dir_entry(connection_struct *conn,
- void *inbuf, void *outbuf,
+ void *inbuf, char *outbuf,
char *path_mask,uint32 dirtype,int info_level,
int requires_resume_key,
BOOL dont_descend,char **ppdata,
@@ -1062,7 +1075,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SMB_OFF_T file_size = 0;
SMB_BIG_UINT allocation_size = 0;
uint32 len;
- time_t mdate=0, adate=0, cdate=0;
+ struct timespec mdate_ts, adate_ts, create_date_ts;
+ time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
char *nameptr;
char *last_entry_ptr;
BOOL was_8_3;
@@ -1074,6 +1088,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
*out_of_space = False;
*got_exact_match = False;
+ ZERO_STRUCT(mdate_ts);
+ ZERO_STRUCT(adate_ts);
+ ZERO_STRUCT(create_date_ts);
+
if (!conn->dirptr)
return(False);
@@ -1182,17 +1200,21 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
if (!(mode & aDIR))
file_size = get_file_size(sbuf);
allocation_size = get_allocation_size(conn,NULL,&sbuf);
- mdate = sbuf.st_mtime;
- adate = sbuf.st_atime;
- cdate = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+
+ mdate_ts = get_mtimespec(&sbuf);
+ adate_ts = get_atimespec(&sbuf);
+ create_date_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
if (lp_dos_filetime_resolution(SNUM(conn))) {
- cdate &= ~1;
- mdate &= ~1;
- adate &= ~1;
+ dos_filetime_timespec(&create_date_ts);
+ dos_filetime_timespec(&mdate_ts);
+ dos_filetime_timespec(&adate_ts);
}
-
+ create_date = convert_timespec_to_time_t(create_date_ts);
+ mdate = convert_timespec_to_time_t(mdate_ts);
+ adate = convert_timespec_to_time_t(adate_ts);
+
DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
found = True;
@@ -1215,7 +1237,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SIVAL(p,0,reskey);
p += 4;
}
- srv_put_dos_date2(p,0,cdate);
+ srv_put_dos_date2(p,0,create_date);
srv_put_dos_date2(p,4,adate);
srv_put_dos_date2(p,8,mdate);
SIVAL(p,12,(uint32)file_size);
@@ -1247,7 +1269,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SIVAL(p,0,reskey);
p += 4;
}
- srv_put_dos_date2(p,0,cdate);
+ srv_put_dos_date2(p,0,create_date);
srv_put_dos_date2(p,4,adate);
srv_put_dos_date2(p,8,mdate);
SIVAL(p,12,(uint32)file_size);
@@ -1291,7 +1313,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SIVAL(p,0,reskey);
p += 4;
}
- srv_put_dos_date2(p,0,cdate);
+ srv_put_dos_date2(p,0,create_date);
srv_put_dos_date2(p,4,adate);
srv_put_dos_date2(p,8,mdate);
SIVAL(p,12,(uint32)file_size);
@@ -1340,10 +1362,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
was_8_3 = mangle_is_8_3(fname, True, conn->params);
p += 4;
SIVAL(p,0,reskey); p += 4;
- put_long_date(p,cdate); p += 8;
- put_long_date(p,adate); p += 8;
- put_long_date(p,mdate); p += 8;
- put_long_date(p,mdate); p += 8;
+ put_long_date_timespec(p,create_date_ts); p += 8;
+ put_long_date_timespec(p,adate_ts); p += 8;
+ put_long_date_timespec(p,mdate_ts); p += 8;
+ put_long_date_timespec(p,mdate_ts); p += 8;
SOFF_T(p,0,file_size); p += 8;
SOFF_T(p,0,allocation_size); p += 8;
SIVAL(p,0,nt_extmode); p += 4;
@@ -1386,10 +1408,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
p += 4;
SIVAL(p,0,reskey); p += 4;
- put_long_date(p,cdate); p += 8;
- put_long_date(p,adate); p += 8;
- put_long_date(p,mdate); p += 8;
- put_long_date(p,mdate); p += 8;
+ put_long_date_timespec(p,create_date_ts); p += 8;
+ put_long_date_timespec(p,adate_ts); p += 8;
+ put_long_date_timespec(p,mdate_ts); p += 8;
+ put_long_date_timespec(p,mdate_ts); p += 8;
SOFF_T(p,0,file_size); p += 8;
SOFF_T(p,0,allocation_size); p += 8;
SIVAL(p,0,nt_extmode); p += 4;
@@ -1407,10 +1429,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
p += 4;
SIVAL(p,0,reskey); p += 4;
- put_long_date(p,cdate); p += 8;
- put_long_date(p,adate); p += 8;
- put_long_date(p,mdate); p += 8;
- put_long_date(p,mdate); p += 8;
+ put_long_date_timespec(p,create_date_ts); p += 8;
+ put_long_date_timespec(p,adate_ts); p += 8;
+ put_long_date_timespec(p,mdate_ts); p += 8;
+ put_long_date_timespec(p,mdate_ts); p += 8;
SOFF_T(p,0,file_size); p += 8;
SOFF_T(p,0,allocation_size); p += 8;
SIVAL(p,0,nt_extmode); p += 4;
@@ -1452,10 +1474,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
p += 4;
SIVAL(p,0,reskey); p += 4;
- put_long_date(p,cdate); p += 8;
- put_long_date(p,adate); p += 8;
- put_long_date(p,mdate); p += 8;
- put_long_date(p,mdate); p += 8;
+ put_long_date_timespec(p,create_date_ts); p += 8;
+ put_long_date_timespec(p,adate_ts); p += 8;
+ put_long_date_timespec(p,mdate_ts); p += 8;
+ put_long_date_timespec(p,mdate_ts); p += 8;
SOFF_T(p,0,file_size); p += 8;
SOFF_T(p,0,allocation_size); p += 8;
SIVAL(p,0,nt_extmode); p += 4;
@@ -1483,10 +1505,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
was_8_3 = mangle_is_8_3(fname, True, conn->params);
p += 4;
SIVAL(p,0,reskey); p += 4;
- put_long_date(p,cdate); p += 8;
- put_long_date(p,adate); p += 8;
- put_long_date(p,mdate); p += 8;
- put_long_date(p,mdate); p += 8;
+ put_long_date_timespec(p,create_date_ts); p += 8;
+ put_long_date_timespec(p,adate_ts); p += 8;
+ put_long_date_timespec(p,mdate_ts); p += 8;
+ put_long_date_timespec(p,mdate_ts); p += 8;
SOFF_T(p,0,file_size); p += 8;
SOFF_T(p,0,allocation_size); p += 8;
SIVAL(p,0,nt_extmode); p += 4;
@@ -1543,9 +1565,9 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SOFF_T(p,0,get_allocation_size(conn,NULL,&sbuf)); /* Number of bytes used on disk - 64 Bit */
p+= 8;
- put_long_date(p,sbuf.st_ctime); /* Inode change Time 64 Bit */
- put_long_date(p+8,sbuf.st_atime); /* Last access time 64 Bit */
- put_long_date(p+16,sbuf.st_mtime); /* Last modification time 64 Bit */
+ put_long_date_timespec(p,get_ctimespec(&sbuf)); /* Inode change Time 64 Bit */
+ put_long_date_timespec(p+8,get_atimespec(&sbuf)); /* Last access time 64 Bit */
+ put_long_date_timespec(p+16,get_mtimespec(&sbuf)); /* Last modification time 64 Bit */
p+= 24;
SIVAL(p,0,sbuf.st_uid); /* user id for the owner */
@@ -1749,7 +1771,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
}
- *ppdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
+ *ppdata = (char *)SMB_REALLOC(
+ *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
if(*ppdata == NULL ) {
talloc_destroy(ea_ctx);
return ERROR_NT(NT_STATUS_NO_MEMORY);
@@ -1757,7 +1780,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
pdata = *ppdata;
/* Realloc the params space */
- *pparams = SMB_REALLOC(*pparams, 10);
+ *pparams = (char *)SMB_REALLOC(*pparams, 10);
if (*pparams == NULL) {
talloc_destroy(ea_ctx);
return ERROR_NT(NT_STATUS_NO_MEMORY);
@@ -1855,7 +1878,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
SSVAL(params,6,0); /* Never an EA error */
SSVAL(params,8,last_entry_off);
- send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
+ send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata), max_data_bytes);
if ((! *directory) && dptr_path(dptr_num))
slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
@@ -2000,7 +2023,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
}
- *ppdata = SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
+ *ppdata = (char *)SMB_REALLOC(
+ *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
if(*ppdata == NULL) {
talloc_destroy(ea_ctx);
return ERROR_NT(NT_STATUS_NO_MEMORY);
@@ -2009,7 +2033,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
pdata = *ppdata;
/* Realloc the params space */
- *pparams = SMB_REALLOC(*pparams, 6*SIZEOFWORD);
+ *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD);
if(*pparams == NULL ) {
talloc_destroy(ea_ctx);
return ERROR_NT(NT_STATUS_NO_MEMORY);
@@ -2136,7 +2160,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
SSVAL(params,4,0); /* Never an EA error */
SSVAL(params,6,last_entry_off);
- send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
+ send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata), max_data_bytes);
if ((! *directory) && dptr_path(dptr_num))
slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
@@ -2173,7 +2197,8 @@ static int call_trans2qfsinfo(connection_struct *conn, char *inbuf, char *outbuf
return ERROR_DOS(ERRSRV,ERRinvdevice);
}
- *ppdata = SMB_REALLOC(*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
+ *ppdata = (char *)SMB_REALLOC(
+ *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
if (*ppdata == NULL ) {
return ERROR_NT(NT_STATUS_NO_MEMORY);
}
@@ -2443,17 +2468,10 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
/* We have POSIX ACLs, pathname and locking capability. */
-#if defined(DEVELOPER) /* Not quite finished yet... */
SBIG_UINT(pdata,4,((SMB_BIG_UINT)(
CIFS_UNIX_POSIX_ACLS_CAP|
CIFS_UNIX_POSIX_PATHNAMES_CAP|
CIFS_UNIX_FCNTL_LOCKS_CAP)));
-#else
- SBIG_UINT(pdata,4,((SMB_BIG_UINT)(
- CIFS_UNIX_POSIX_ACLS_CAP|
- CIFS_UNIX_POSIX_PATHNAMES_CAP|
- 0)));
-#endif
break;
case SMB_QUERY_POSIX_FS_INFO:
@@ -2505,7 +2523,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
}
- send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
+ send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len, max_data_bytes);
DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
@@ -2569,11 +2587,10 @@ cap_low = 0x%x, cap_high = 0x%x\n",
lp_set_posix_pathnames();
mangle_change_to_posix();
}
-#if defined(DEVELOPER)
+
if (client_unix_cap_low & CIFS_UNIX_FCNTL_LOCKS_CAP) {
lp_set_posix_cifsx_locktype(POSIX_LOCK);
}
-#endif
break;
}
case SMB_FS_QUOTA_INFORMATION:
@@ -2829,14 +2846,13 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
BOOL bad_path = False;
BOOL delete_pending = False;
int len;
- time_t c_time;
+ time_t create_time, mtime, atime;
+ struct timespec create_time_ts, mtime_ts, atime_ts;
files_struct *fsp = NULL;
TALLOC_CTX *data_ctx = NULL;
struct ea_list *ea_list = NULL;
uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
-#if defined(DEVELOPER)
char *lock_data = NULL;
-#endif
if (!params)
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
@@ -3008,7 +3024,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
break;
}
-#if defined(DEVELOPER)
+
case SMB_QUERY_POSIX_LOCK:
{
if (fsp == NULL || fsp->fh->fd == -1) {
@@ -3024,18 +3040,18 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
/* Copy the lock range data. */
- lock_data = talloc_memdup(data_ctx, pdata, total_data);
+ lock_data = (char *)talloc_memdup(
+ data_ctx, pdata, total_data);
if (!lock_data) {
talloc_destroy(data_ctx);
return ERROR_NT(NT_STATUS_NO_MEMORY);
}
}
-#endif
default:
break;
}
- *pparams = SMB_REALLOC(*pparams,2);
+ *pparams = (char *)SMB_REALLOC(*pparams,2);
if (*pparams == NULL) {
talloc_destroy(data_ctx);
return ERROR_NT(NT_STATUS_NO_MEMORY);
@@ -3043,28 +3059,32 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
params = *pparams;
SSVAL(params,0,0);
data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
- *ppdata = SMB_REALLOC(*ppdata, data_size);
+ *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
if (*ppdata == NULL ) {
talloc_destroy(data_ctx);
return ERROR_NT(NT_STATUS_NO_MEMORY);
}
pdata = *ppdata;
- c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+ create_time_ts = get_create_timespec(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
+ mtime_ts = get_mtimespec(&sbuf);
+ atime_ts = get_atimespec(&sbuf);
allocation_size = get_allocation_size(conn,fsp,&sbuf);
if (fsp) {
if (fsp->pending_modtime) {
/* the pending modtime overrides the current modtime */
- sbuf.st_mtime = fsp->pending_modtime;
+ mtime_ts.tv_sec = fsp->pending_modtime;
+ mtime_ts.tv_nsec = 0;
}
} else {
/* Do we have this path open ? */
files_struct *fsp1 = file_find_di_first(sbuf.st_dev, sbuf.st_ino);
if (fsp1 && fsp1->pending_modtime) {
/* the pending modtime overrides the current modtime */
- sbuf.st_mtime = fsp1->pending_modtime;
+ mtime_ts.tv_sec = fsp1->pending_modtime;
+ mtime_ts.tv_nsec = 0;
}
if (fsp1 && fsp1->initial_allocation_size) {
allocation_size = get_allocation_size(conn, fsp1, &sbuf);
@@ -3072,12 +3092,15 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
if (lp_dos_filetime_resolution(SNUM(conn))) {
- c_time &= ~1;
- sbuf.st_atime &= ~1;
- sbuf.st_ctime &= ~1;
- sbuf.st_mtime &= ~1;
+ dos_filetime_timespec(&create_time_ts);
+ dos_filetime_timespec(&mtime_ts);
+ dos_filetime_timespec(&atime_ts);
}
+ create_time = convert_timespec_to_time_t(create_time_ts);
+ mtime = convert_timespec_to_time_t(mtime_ts);
+ atime = convert_timespec_to_time_t(atime_ts);
+
/* NT expects the name to be in an exact form of the *full*
filename. See the trans2 torture test */
if (strequal(base_name,".")) {
@@ -3091,9 +3114,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_INFO_STANDARD:
DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_STANDARD\n"));
data_size = 22;
- srv_put_dos_date2(pdata,l1_fdateCreation,c_time);
- srv_put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
- srv_put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
+ srv_put_dos_date2(pdata,l1_fdateCreation,create_time);
+ srv_put_dos_date2(pdata,l1_fdateLastAccess,atime);
+ srv_put_dos_date2(pdata,l1_fdateLastWrite,mtime); /* write time */
SIVAL(pdata,l1_cbFile,(uint32)file_size);
SIVAL(pdata,l1_cbFileAlloc,(uint32)allocation_size);
SSVAL(pdata,l1_attrFile,mode);
@@ -3104,9 +3127,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
DEBUG(10,("call_trans2qfilepathinfo: SMB_INFO_QUERY_EA_SIZE\n"));
data_size = 26;
- srv_put_dos_date2(pdata,0,c_time);
- srv_put_dos_date2(pdata,4,sbuf.st_atime);
- srv_put_dos_date2(pdata,8,sbuf.st_mtime); /* write time */
+ srv_put_dos_date2(pdata,0,create_time);
+ srv_put_dos_date2(pdata,4,atime);
+ srv_put_dos_date2(pdata,8,mtime); /* write time */
SIVAL(pdata,12,(uint32)file_size);
SIVAL(pdata,16,(uint32)allocation_size);
SSVAL(pdata,20,mode);
@@ -3182,20 +3205,17 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
data_size = 40;
SIVAL(pdata,36,0);
}
- put_long_date(pdata,c_time);
- put_long_date(pdata+8,sbuf.st_atime);
- put_long_date(pdata+16,sbuf.st_mtime); /* write time */
- put_long_date(pdata+24,sbuf.st_mtime); /* change time */
+ put_long_date_timespec(pdata,create_time_ts);
+ put_long_date_timespec(pdata+8,atime_ts);
+ put_long_date_timespec(pdata+16,mtime_ts); /* write time */
+ put_long_date_timespec(pdata+24,mtime_ts); /* change time */
SIVAL(pdata,32,mode);
DEBUG(5,("SMB_QFBI - "));
- {
- time_t create_time = c_time;
- DEBUG(5,("create: %s ", ctime(&create_time)));
- }
- DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
- DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
- DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
+ DEBUG(5,("create: %s ", ctime(&create_time)));
+ DEBUG(5,("access: %s ", ctime(&atime)));
+ DEBUG(5,("write: %s ", ctime(&mtime)));
+ DEBUG(5,("change: %s ", ctime(&mtime)));
DEBUG(5,("mode: %x\n", mode));
break;
@@ -3269,10 +3289,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
{
unsigned int ea_size = estimate_ea_size(conn, fsp, fname);
DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
- put_long_date(pdata,c_time);
- put_long_date(pdata+8,sbuf.st_atime);
- put_long_date(pdata+16,sbuf.st_mtime); /* write time */
- put_long_date(pdata+24,sbuf.st_mtime); /* change time */
+ put_long_date_timespec(pdata,create_time_ts);
+ put_long_date_timespec(pdata+8,atime_ts);
+ put_long_date_timespec(pdata+16,mtime_ts); /* write time */
+ put_long_date_timespec(pdata+24,mtime_ts); /* change time */
SIVAL(pdata,32,mode);
SIVAL(pdata,36,0); /* padding. */
pdata += 40;
@@ -3379,10 +3399,10 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_FILE_NETWORK_OPEN_INFORMATION:
DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
- put_long_date(pdata,c_time);
- put_long_date(pdata+8,sbuf.st_atime);
- put_long_date(pdata+16,sbuf.st_mtime); /* write time */
- put_long_date(pdata+24,sbuf.st_mtime); /* change time */
+ put_long_date_timespec(pdata,create_time_ts);
+ put_long_date_timespec(pdata+8,atime_ts);
+ put_long_date_timespec(pdata+16,mtime_ts); /* write time */
+ put_long_date_timespec(pdata+24,mtime_ts); /* change time */
SIVAL(pdata,32,allocation_size);
SOFF_T(pdata,40,file_size);
SIVAL(pdata,48,mode);
@@ -3412,9 +3432,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
SOFF_T(pdata,0,get_allocation_size(conn,fsp,&sbuf)); /* Number of bytes used on disk - 64 Bit */
pdata += 8;
- put_long_date(pdata,sbuf.st_ctime); /* Creation Time 64 Bit */
- put_long_date(pdata+8,sbuf.st_atime); /* Last access time 64 Bit */
- put_long_date(pdata+16,sbuf.st_mtime); /* Last modification time 64 Bit */
+ put_long_date_timespec(pdata,get_ctimespec(&sbuf)); /* Creation Time 64 Bit */
+ put_long_date_timespec(pdata+8,get_atimespec(&sbuf)); /* Last access time 64 Bit */
+ put_long_date_timespec(pdata+16,get_mtimespec(&sbuf)); /* Last modification time 64 Bit */
pdata += 24;
SIVAL(pdata,0,sbuf.st_uid); /* user id for the owner */
@@ -3450,7 +3470,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
{
int i;
- DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC"));
+ DEBUG(4,("call_trans2qfilepathinfo: SMB_QUERY_FILE_UNIX_BASIC "));
for (i=0; i<100; i++)
DEBUG(4,("%d=%x, ",i, (*ppdata)[i]));
@@ -3561,13 +3581,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
#endif
-#if defined(DEVELOPER)
case SMB_QUERY_POSIX_LOCK:
{
NTSTATUS status = NT_STATUS_INVALID_LEVEL;
SMB_BIG_UINT count;
SMB_BIG_UINT offset;
- uint16 lock_pid;
+ uint32 lock_pid;
enum brl_type lock_type;
if (total_data != POSIX_LOCK_DATA_SIZE) {
@@ -3588,7 +3607,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
- lock_pid = (uint16)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
+ lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
#if defined(HAVE_LONGLONG)
offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET));
@@ -3634,13 +3653,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
break;
}
-#endif
default:
return ERROR_NT(NT_STATUS_INVALID_LEVEL);
}
- send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size);
+ send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size, max_data_bytes);
return(-1);
}
@@ -3789,7 +3807,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
return(-1);
} else
return (UNIXERROR(ERRDOS,ERRbadpath));
@@ -3901,7 +3919,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
/* We're done. We only get EA info in this call. */
SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
return(-1);
}
@@ -3932,7 +3950,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
/* We're done. We only get EA info in this call. */
SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
return(-1);
}
@@ -4032,16 +4050,16 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
if (fd == -1) {
files_struct *new_fsp = NULL;
- new_fsp = open_file_ntcreate(conn, fname, &sbuf,
+ status = open_file_ntcreate(conn, fname, &sbuf,
FILE_WRITE_DATA,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
FORCE_OPLOCK_BREAK_TO_NONE,
- NULL);
+ NULL, &new_fsp);
- if (new_fsp == NULL) {
+ if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
return -1;
@@ -4124,7 +4142,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
}
SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
return(-1);
}
@@ -4153,7 +4171,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
/* We're done. We only get position info in this call. */
SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
return(-1);
}
@@ -4177,7 +4195,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
/* We're done. We only get mode info in this call. */
SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
return(-1);
}
@@ -4292,7 +4310,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
inherit_access_acl(conn, fname, unixmode);
SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
return(-1);
}
@@ -4375,7 +4393,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
return(-1);
}
@@ -4399,7 +4417,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
return(-1);
}
@@ -4453,7 +4471,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
process_pending_change_notify_queue((time_t)0);
SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
return(-1);
}
@@ -4504,20 +4522,18 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
return(-1);
}
#endif
-#if defined(DEVELOPER)
case SMB_SET_POSIX_LOCK:
{
SMB_BIG_UINT count;
SMB_BIG_UINT offset;
- uint16 lock_pid;
- BOOL lock_blocking;
+ uint32 lock_pid;
+ BOOL blocking_lock = False;
enum brl_type lock_type;
- BOOL my_lock_ctx;
if (fsp == NULL || fsp->fh->fd == -1) {
return ERROR_NT(NT_STATUS_INVALID_HANDLE);
@@ -4546,14 +4562,18 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_NOWAIT) {
- lock_blocking = False;
+ blocking_lock = False;
} else if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_WAIT) {
- lock_blocking = True;
+ blocking_lock = True;
} else {
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
- lock_pid = (uint16)IVAL(pdata, POSIX_LOCK_PID_OFFSET);
+ if (!lp_blocking_locks(SNUM(conn))) {
+ blocking_lock = False;
+ }
+
+ lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
#if defined(HAVE_LONGLONG)
offset = (((SMB_BIG_UINT) IVAL(pdata,(POSIX_LOCK_START_OFFSET+4))) << 32) |
((SMB_BIG_UINT) IVAL(pdata,POSIX_LOCK_START_OFFSET));
@@ -4571,21 +4591,23 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
offset,
POSIX_LOCK);
} else {
- status = do_lock(fsp,
- lock_pid,
- count,
- offset,
- lock_type,
- POSIX_LOCK,
- &my_lock_ctx);
-
- if (lp_blocking_locks(SNUM(conn)) && ERROR_WAS_LOCK_DENIED(status)) {
+ struct byte_range_lock *br_lck = do_lock(fsp,
+ lock_pid,
+ count,
+ offset,
+ lock_type,
+ POSIX_LOCK,
+ blocking_lock,
+ &status);
+
+ if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
/*
* A blocking lock was requested. Package up
* this smb into a queued request and push it
* onto the blocking lock queue.
*/
- if(push_blocking_lock_request(inbuf, length,
+ if(push_blocking_lock_request(br_lck,
+ inbuf, length,
fsp,
-1, /* infinite timeout. */
0,
@@ -4594,9 +4616,11 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
POSIX_LOCK,
offset,
count)) {
+ TALLOC_FREE(br_lck);
return -1;
}
}
+ TALLOC_FREE(br_lck);
}
if (!NT_STATUS_IS_OK(status)) {
@@ -4604,10 +4628,9 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
return(-1);
}
-#endif
default:
return ERROR_NT(NT_STATUS_INVALID_LEVEL);
@@ -4675,16 +4698,16 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
if (fd == -1) {
files_struct *new_fsp = NULL;
- new_fsp = open_file_ntcreate(conn, fname, &sbuf,
+ status = open_file_ntcreate(conn, fname, &sbuf,
FILE_WRITE_DATA,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
FORCE_OPLOCK_BREAK_TO_NONE,
- NULL);
+ NULL, &new_fsp);
- if (new_fsp == NULL) {
+ if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
return -1;
@@ -4731,7 +4754,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
return(-1);
}
@@ -4836,7 +4859,7 @@ static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf,
SSVAL(params,0,0);
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
return(-1);
}
@@ -4885,7 +4908,7 @@ static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char
if(fnf_handle == 0)
fnf_handle = 257;
- send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0, max_data_bytes);
return(-1);
}
@@ -4913,7 +4936,7 @@ static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char
SSVAL(params,0,0); /* No changes */
SSVAL(params,2,0); /* No EA errors */
- send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
+ send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0, max_data_bytes);
return(-1);
}
@@ -4947,7 +4970,7 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char*
return UNIXERROR(ERRDOS,ERRbadfile);
SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
- send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
+ send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size, max_data_bytes);
return(-1);
}
@@ -4985,7 +5008,7 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf,
SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
- send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
+ send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32, max_data_bytes);
return(-1);
} else {
DEBUG(2,("Unknown TRANS2_IOCTL\n"));
@@ -5295,7 +5318,7 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf,
if (state->total_data) {
/* Can't use talloc here, the core routines do realloc on the
* params and data. */
- state->data = SMB_MALLOC(state->total_data);
+ state->data = (char *)SMB_MALLOC(state->total_data);
if (state->data == NULL) {
DEBUG(0,("reply_trans2: data malloc fail for %u "
"bytes !\n", (unsigned int)state->total_data));
@@ -5315,7 +5338,7 @@ int reply_trans2(connection_struct *conn, char *inbuf,char *outbuf,
if (state->total_param) {
/* Can't use talloc here, the core routines do realloc on the
* params and data. */
- state->param = SMB_MALLOC(state->total_param);
+ state->param = (char *)SMB_MALLOC(state->total_param);
if (state->param == NULL) {
DEBUG(0,("reply_trans: param malloc fail for %u "
"bytes !\n", (unsigned int)state->total_param));
diff --git a/source/smbd/uid.c b/source/smbd/uid.c
index c4213ba700f..85885803222 100644
--- a/source/smbd/uid.c
+++ b/source/smbd/uid.c
@@ -109,7 +109,8 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
conn->nt_user_token : vuser->nt_user_token;
if (!readonly_share &&
- !share_access_check(conn, snum, vuser, FILE_WRITE_DATA)) {
+ !share_access_check(token, lp_servicename(snum),
+ FILE_WRITE_DATA)) {
/* smb.conf allows r/w, but the security descriptor denies
* write. Fall back to looking at readonly. */
readonly_share = True;
@@ -117,7 +118,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
"security descriptor\n"));
}
- if (!share_access_check(conn, snum, vuser,
+ if (!share_access_check(token, lp_servicename(snum),
readonly_share ?
FILE_READ_DATA : FILE_WRITE_DATA)) {
return False;
@@ -419,4 +420,3 @@ BOOL unbecome_user(void)
pop_conn_ctx();
return True;
}
-
diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c
deleted file mode 100644
index f1c2ad335c1..00000000000
--- a/source/smbd/vfs-wrap.c
+++ /dev/null
@@ -1,1113 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Wrap disk only vfs functions to sidestep dodgy compilers.
- Copyright (C) Tim Potter 1998
-
- 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"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_VFS
-
-
-/* Check for NULL pointer parameters in vfswrap_* functions */
-
-/* We don't want to have NULL function pointers lying around. Someone
- is sure to try and execute them. These stubs are used to prevent
- this possibility. */
-
-int vfswrap_dummy_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user)
-{
- return 0; /* Return >= 0 for success */
-}
-
-void vfswrap_dummy_disconnect(vfs_handle_struct *handle, connection_struct *conn)
-{
-}
-
-/* Disk operations */
-
-SMB_BIG_UINT vfswrap_disk_free(vfs_handle_struct *handle, connection_struct *conn, const char *path, BOOL small_query, SMB_BIG_UINT *bsize,
- SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
-{
- SMB_BIG_UINT result;
-
- result = sys_disk_free(conn, path, small_query, bsize, dfree, dsize);
- return result;
-}
-
-int vfswrap_get_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
-{
-#ifdef HAVE_SYS_QUOTAS
- int result;
-
- START_PROFILE(syscall_get_quota);
- result = sys_get_quota(conn->connectpath, qtype, id, qt);
- END_PROFILE(syscall_get_quota);
- return result;
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-int vfswrap_set_quota(struct vfs_handle_struct *handle, struct connection_struct *conn, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
-{
-#ifdef HAVE_SYS_QUOTAS
- int result;
-
- START_PROFILE(syscall_set_quota);
- result = sys_set_quota(conn->connectpath, qtype, id, qt);
- END_PROFILE(syscall_set_quota);
- return result;
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, BOOL labels)
-{
- errno = ENOSYS;
- return -1; /* Not implemented. */
-}
-
-int vfswrap_statvfs(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path, vfs_statvfs_struct *statbuf)
-{
- return sys_statvfs(path, statbuf);
-}
-
-/* Directory operations */
-
-SMB_STRUCT_DIR *vfswrap_opendir(vfs_handle_struct *handle, connection_struct *conn, const char *fname, const char *mask, uint32 attr)
-{
- SMB_STRUCT_DIR *result;
-
- START_PROFILE(syscall_opendir);
- result = sys_opendir(fname);
- END_PROFILE(syscall_opendir);
- return result;
-}
-
-SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp)
-{
- SMB_STRUCT_DIRENT *result;
-
- START_PROFILE(syscall_readdir);
- result = sys_readdir(dirp);
- END_PROFILE(syscall_readdir);
- return result;
-}
-
-void vfswrap_seekdir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp, long offset)
-{
- START_PROFILE(syscall_seekdir);
- sys_seekdir(dirp, offset);
- END_PROFILE(syscall_seekdir);
-}
-
-long vfswrap_telldir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp)
-{
- long result;
- START_PROFILE(syscall_telldir);
- result = sys_telldir(dirp);
- END_PROFILE(syscall_telldir);
- return result;
-}
-
-void vfswrap_rewinddir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp)
-{
- START_PROFILE(syscall_rewinddir);
- sys_rewinddir(dirp);
- END_PROFILE(syscall_rewinddir);
-}
-
-int vfswrap_mkdir(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
-{
- int result;
- BOOL has_dacl = False;
-
- START_PROFILE(syscall_mkdir);
-
- if (lp_inherit_acls(SNUM(conn)) && (has_dacl = directory_has_default_acl(conn, parent_dirname(path))))
- mode = 0777;
-
- result = mkdir(path, mode);
-
- if (result == 0 && !has_dacl) {
- /*
- * We need to do this as the default behavior of POSIX ACLs
- * is to set the mask to be the requested group permission
- * bits, not the group permission bits to be the requested
- * group permission bits. This is not what we want, as it will
- * mess up any inherited ACL bits that were set. JRA.
- */
- int saved_errno = errno; /* We may get ENOSYS */
- if ((SMB_VFS_CHMOD_ACL(conn, path, mode) == -1) && (errno == ENOSYS))
- errno = saved_errno;
- }
-
- END_PROFILE(syscall_mkdir);
- return result;
-}
-
-int vfswrap_rmdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- int result;
-
- START_PROFILE(syscall_rmdir);
- result = rmdir(path);
- END_PROFILE(syscall_rmdir);
- return result;
-}
-
-int vfswrap_closedir(vfs_handle_struct *handle, connection_struct *conn, SMB_STRUCT_DIR *dirp)
-{
- int result;
-
- START_PROFILE(syscall_closedir);
- result = sys_closedir(dirp);
- END_PROFILE(syscall_closedir);
- return result;
-}
-
-/* File operations */
-
-int vfswrap_open(vfs_handle_struct *handle, connection_struct *conn, const char *fname, int flags, mode_t mode)
-{
- int result;
-
- START_PROFILE(syscall_open);
- result = sys_open(fname, flags, mode);
- END_PROFILE(syscall_open);
- return result;
-}
-
-int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
-{
- int result;
-
- START_PROFILE(syscall_close);
-
- result = close(fd);
- END_PROFILE(syscall_close);
- return result;
-}
-
-ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data, size_t n)
-{
- ssize_t result;
-
- START_PROFILE_BYTES(syscall_read, n);
- result = sys_read(fd, data, n);
- END_PROFILE(syscall_read);
- return result;
-}
-
-ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, int fd, void *data,
- size_t n, SMB_OFF_T offset)
-{
- ssize_t result;
-
-#if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
- START_PROFILE_BYTES(syscall_pread, n);
- result = sys_pread(fd, data, n, offset);
- END_PROFILE(syscall_pread);
-
- if (result == -1 && errno == ESPIPE) {
- /* Maintain the fiction that pipes can be seeked (sought?) on. */
- result = SMB_VFS_READ(fsp, fd, data, n);
- fsp->fh->pos = 0;
- }
-
-#else /* HAVE_PREAD */
- SMB_OFF_T curr;
- int lerrno;
-
- curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
- if (curr == -1 && errno == ESPIPE) {
- /* Maintain the fiction that pipes can be seeked (sought?) on. */
- result = SMB_VFS_READ(fsp, fd, data, n);
- fsp->fh->pos = 0;
- return result;
- }
-
- if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) {
- return -1;
- }
-
- errno = 0;
- result = SMB_VFS_READ(fsp, fd, data, n);
- lerrno = errno;
-
- SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET);
- errno = lerrno;
-
-#endif /* HAVE_PREAD */
-
- return result;
-}
-
-ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data, size_t n)
-{
- ssize_t result;
-
- START_PROFILE_BYTES(syscall_write, n);
- result = sys_write(fd, data, n);
- END_PROFILE(syscall_write);
- return result;
-}
-
-ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, int fd, const void *data,
- size_t n, SMB_OFF_T offset)
-{
- ssize_t result;
-
-#if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
- START_PROFILE_BYTES(syscall_pwrite, n);
- result = sys_pwrite(fd, data, n, offset);
- END_PROFILE(syscall_pwrite);
-
- if (result == -1 && errno == ESPIPE) {
- /* Maintain the fiction that pipes can be sought on. */
- result = SMB_VFS_WRITE(fsp, fd, data, n);
- }
-
-#else /* HAVE_PWRITE */
- SMB_OFF_T curr;
- int lerrno;
-
- curr = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
- if (curr == -1) {
- return -1;
- }
-
- if (SMB_VFS_LSEEK(fsp, fd, offset, SEEK_SET) == -1) {
- return -1;
- }
-
- result = SMB_VFS_WRITE(fsp, fd, data, n);
- lerrno = errno;
-
- SMB_VFS_LSEEK(fsp, fd, curr, SEEK_SET);
- errno = lerrno;
-
-#endif /* HAVE_PWRITE */
-
- return result;
-}
-
-SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, int filedes, SMB_OFF_T offset, int whence)
-{
- SMB_OFF_T result = 0;
-
- START_PROFILE(syscall_lseek);
-
- /* Cope with 'stat' file opens. */
- if (filedes != -1)
- result = sys_lseek(filedes, offset, whence);
-
- /*
- * We want to maintain the fiction that we can seek
- * on a fifo for file system purposes. This allows
- * people to set up UNIX fifo's that feed data to Windows
- * applications. JRA.
- */
-
- if((result == -1) && (errno == ESPIPE)) {
- result = 0;
- errno = 0;
- }
-
- END_PROFILE(syscall_lseek);
- return result;
-}
-
-ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fsp, int fromfd, const DATA_BLOB *hdr,
- SMB_OFF_T offset, size_t n)
-{
- ssize_t result;
-
- START_PROFILE_BYTES(syscall_sendfile, n);
- result = sys_sendfile(tofd, fromfd, hdr, offset, n);
- END_PROFILE(syscall_sendfile);
- return result;
-}
-
-/*********************************************************
- For rename across filesystems Patch from Warren Birnbaum
- <warrenb@hpcvscdp.cv.hp.com>
-**********************************************************/
-
-static int copy_reg(const char *source, const char *dest)
-{
- SMB_STRUCT_STAT source_stats;
- int saved_errno;
- int ifd = -1;
- int ofd = -1;
-
- if (sys_lstat (source, &source_stats) == -1)
- return -1;
-
- if (!S_ISREG (source_stats.st_mode))
- return -1;
-
- if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
- return -1;
-
- if (unlink (dest) && errno != ENOENT)
- return -1;
-
-#ifdef O_NOFOLLOW
- if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 )
-#else
- if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )
-#endif
- goto err;
-
- if (transfer_file(ifd, ofd, (size_t)-1) == -1)
- goto err;
-
- /*
- * Try to preserve ownership. For non-root it might fail, but that's ok.
- * But root probably wants to know, e.g. if NFS disallows it.
- */
-
-#ifdef HAVE_FCHOWN
- if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
-#else
- if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
-#endif
- goto err;
-
- /*
- * fchown turns off set[ug]id bits for non-root,
- * so do the chmod last.
- */
-
-#if defined(HAVE_FCHMOD)
- if (fchmod (ofd, source_stats.st_mode & 07777))
-#else
- if (chmod (dest, source_stats.st_mode & 07777))
-#endif
- goto err;
-
- if (close (ifd) == -1)
- goto err;
-
- if (close (ofd) == -1)
- return -1;
-
- /* Try to copy the old file's modtime and access time. */
- {
- struct utimbuf tv;
-
- tv.actime = source_stats.st_atime;
- tv.modtime = source_stats.st_mtime;
- utime(dest, &tv);
- }
-
- if (unlink (source) == -1)
- return -1;
-
- return 0;
-
- err:
-
- saved_errno = errno;
- if (ifd != -1)
- close(ifd);
- if (ofd != -1)
- close(ofd);
- errno = saved_errno;
- return -1;
-}
-
-int vfswrap_rename(vfs_handle_struct *handle, connection_struct *conn, const char *oldname, const char *newname)
-{
- int result;
-
- START_PROFILE(syscall_rename);
- result = rename(oldname, newname);
- if (errno == EXDEV) {
- /* Rename across filesystems needed. */
- result = copy_reg(oldname, newname);
- }
-
- END_PROFILE(syscall_rename);
- return result;
-}
-
-int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp, int fd)
-{
-#ifdef HAVE_FSYNC
- int result;
-
- START_PROFILE(syscall_fsync);
- result = fsync(fd);
- END_PROFILE(syscall_fsync);
- return result;
-#else
- return 0;
-#endif
-}
-
-int vfswrap_stat(vfs_handle_struct *handle, connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
-{
- int result;
-
- START_PROFILE(syscall_stat);
- result = sys_stat(fname, sbuf);
- END_PROFILE(syscall_stat);
- return result;
-}
-
-int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_STRUCT_STAT *sbuf)
-{
- int result;
-
- START_PROFILE(syscall_fstat);
- result = sys_fstat(fd, sbuf);
- END_PROFILE(syscall_fstat);
- return result;
-}
-
-int vfswrap_lstat(vfs_handle_struct *handle, connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf)
-{
- int result;
-
- START_PROFILE(syscall_lstat);
- result = sys_lstat(path, sbuf);
- END_PROFILE(syscall_lstat);
- return result;
-}
-
-int vfswrap_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- int result;
-
- START_PROFILE(syscall_unlink);
- result = unlink(path);
- END_PROFILE(syscall_unlink);
- return result;
-}
-
-int vfswrap_chmod(vfs_handle_struct *handle, connection_struct *conn, const char *path, mode_t mode)
-{
- int result;
-
- START_PROFILE(syscall_chmod);
-
- /*
- * We need to do this due to the fact that the default POSIX ACL
- * chmod modifies the ACL *mask* for the group owner, not the
- * group owner bits directly. JRA.
- */
-
-
- {
- int saved_errno = errno; /* We might get ENOSYS */
- if ((result = SMB_VFS_CHMOD_ACL(conn, path, mode)) == 0) {
- END_PROFILE(syscall_chmod);
- return result;
- }
- /* Error - return the old errno. */
- errno = saved_errno;
- }
-
- result = chmod(path, mode);
- END_PROFILE(syscall_chmod);
- return result;
-}
-
-int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
-{
- int result;
-
- START_PROFILE(syscall_fchmod);
-
- /*
- * We need to do this due to the fact that the default POSIX ACL
- * chmod modifies the ACL *mask* for the group owner, not the
- * group owner bits directly. JRA.
- */
-
- {
- int saved_errno = errno; /* We might get ENOSYS */
- if ((result = SMB_VFS_FCHMOD_ACL(fsp, fd, mode)) == 0) {
- END_PROFILE(syscall_fchmod);
- return result;
- }
- /* Error - return the old errno. */
- errno = saved_errno;
- }
-
-#if defined(HAVE_FCHMOD)
- result = fchmod(fd, mode);
-#else
- result = -1;
- errno = ENOSYS;
-#endif
-
- END_PROFILE(syscall_fchmod);
- return result;
-}
-
-int vfswrap_chown(vfs_handle_struct *handle, connection_struct *conn, const char *path, uid_t uid, gid_t gid)
-{
- int result;
-
- START_PROFILE(syscall_chown);
- result = sys_chown(path, uid, gid);
- END_PROFILE(syscall_chown);
- return result;
-}
-
-int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, int fd, uid_t uid, gid_t gid)
-{
-#ifdef HAVE_FCHOWN
- int result;
-
- START_PROFILE(syscall_fchown);
- result = fchown(fd, uid, gid);
- END_PROFILE(syscall_fchown);
- return result;
-#else
- errno = ENOSYS;
- return -1;
-#endif
-}
-
-int vfswrap_chdir(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- int result;
-
- START_PROFILE(syscall_chdir);
- result = chdir(path);
- END_PROFILE(syscall_chdir);
- return result;
-}
-
-char *vfswrap_getwd(vfs_handle_struct *handle, connection_struct *conn, char *path)
-{
- char *result;
-
- START_PROFILE(syscall_getwd);
- result = sys_getwd(path);
- END_PROFILE(syscall_getwd);
- return result;
-}
-
-int vfswrap_utime(vfs_handle_struct *handle, connection_struct *conn, const char *path, struct utimbuf *times)
-{
- int result;
-
- START_PROFILE(syscall_utime);
- result = utime(path, times);
- END_PROFILE(syscall_utime);
- return result;
-}
-
-/*********************************************************************
- A version of ftruncate that will write the space on disk if strict
- allocate is set.
-**********************************************************************/
-
-static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
-{
- SMB_STRUCT_STAT st;
- SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
- unsigned char zero_space[4096];
- SMB_OFF_T space_to_write;
-
- if (currpos == -1)
- return -1;
-
- if (SMB_VFS_FSTAT(fsp, fd, &st) == -1)
- return -1;
-
- space_to_write = len - st.st_size;
-
-#ifdef S_ISFIFO
- if (S_ISFIFO(st.st_mode))
- return 0;
-#endif
-
- if (st.st_size == len)
- return 0;
-
- /* Shrink - just ftruncate. */
- if (st.st_size > len)
- return sys_ftruncate(fd, len);
-
- /* Write out the real space on disk. */
- if (SMB_VFS_LSEEK(fsp, fd, st.st_size, SEEK_SET) != st.st_size)
- return -1;
-
- space_to_write = len - st.st_size;
-
- memset(zero_space, '\0', sizeof(zero_space));
- while ( space_to_write > 0) {
- SMB_OFF_T retlen;
- SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write);
-
- retlen = SMB_VFS_WRITE(fsp,fsp->fh->fd,(char *)zero_space,current_len_to_write);
- if (retlen <= 0)
- return -1;
-
- space_to_write -= retlen;
- }
-
- /* Seek to where we were */
- if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
- return -1;
-
- return 0;
-}
-
-int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T len)
-{
- int result = -1;
- SMB_STRUCT_STAT st;
- char c = 0;
- SMB_OFF_T currpos;
-
- START_PROFILE(syscall_ftruncate);
-
- if (lp_strict_allocate(SNUM(fsp->conn))) {
- result = strict_allocate_ftruncate(handle, fsp, fd, len);
- END_PROFILE(syscall_ftruncate);
- return result;
- }
-
- /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
- sys_ftruncate if the system supports it. Then I discovered that
- you can have some filesystems that support ftruncate
- expansion and some that don't! On Linux fat can't do
- ftruncate extend but ext2 can. */
-
- result = sys_ftruncate(fd, len);
- if (result == 0)
- goto done;
-
- /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
- extend a file with ftruncate. Provide alternate implementation
- for this */
- currpos = SMB_VFS_LSEEK(fsp, fd, 0, SEEK_CUR);
- if (currpos == -1) {
- goto done;
- }
-
- /* Do an fstat to see if the file is longer than the requested
- size in which case the ftruncate above should have
- succeeded or shorter, in which case seek to len - 1 and
- write 1 byte of zero */
- if (SMB_VFS_FSTAT(fsp, fd, &st) == -1) {
- goto done;
- }
-
-#ifdef S_ISFIFO
- if (S_ISFIFO(st.st_mode)) {
- result = 0;
- goto done;
- }
-#endif
-
- if (st.st_size == len) {
- result = 0;
- goto done;
- }
-
- if (st.st_size > len) {
- /* the sys_ftruncate should have worked */
- goto done;
- }
-
- if (SMB_VFS_LSEEK(fsp, fd, len-1, SEEK_SET) != len -1)
- goto done;
-
- if (SMB_VFS_WRITE(fsp, fd, &c, 1)!=1)
- goto done;
-
- /* Seek to where we were */
- if (SMB_VFS_LSEEK(fsp, fd, currpos, SEEK_SET) != currpos)
- goto done;
- result = 0;
-
- done:
-
- END_PROFILE(syscall_ftruncate);
- return result;
-}
-
-BOOL vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
-{
- BOOL result;
-
- START_PROFILE(syscall_fcntl_lock);
- result = fcntl_lock(fd, op, offset, count, type);
- END_PROFILE(syscall_fcntl_lock);
- return result;
-}
-
-int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
- int fd, uint32 share_mode)
-{
- START_PROFILE(syscall_kernel_flock);
- kernel_flock(fd, share_mode);
- END_PROFILE(syscall_kernel_flock);
- return 0;
-}
-
-BOOL vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
-{
- BOOL result;
-
- START_PROFILE(syscall_fcntl_getlock);
- result = fcntl_getlock(fd, poffset, pcount, ptype, ppid);
- END_PROFILE(syscall_fcntl_getlock);
- return result;
-}
-
-int vfswrap_symlink(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
-{
- int result;
-
- START_PROFILE(syscall_symlink);
- result = sys_symlink(oldpath, newpath);
- END_PROFILE(syscall_symlink);
- return result;
-}
-
-int vfswrap_readlink(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *buf, size_t bufsiz)
-{
- int result;
-
- START_PROFILE(syscall_readlink);
- result = sys_readlink(path, buf, bufsiz);
- END_PROFILE(syscall_readlink);
- return result;
-}
-
-int vfswrap_link(vfs_handle_struct *handle, connection_struct *conn, const char *oldpath, const char *newpath)
-{
- int result;
-
- START_PROFILE(syscall_link);
- result = sys_link(oldpath, newpath);
- END_PROFILE(syscall_link);
- return result;
-}
-
-int vfswrap_mknod(vfs_handle_struct *handle, connection_struct *conn, const char *pathname, mode_t mode, SMB_DEV_T dev)
-{
- int result;
-
- START_PROFILE(syscall_mknod);
- result = sys_mknod(pathname, mode, dev);
- END_PROFILE(syscall_mknod);
- return result;
-}
-
-char *vfswrap_realpath(vfs_handle_struct *handle, connection_struct *conn, const char *path, char *resolved_path)
-{
- char *result;
-
- START_PROFILE(syscall_realpath);
- result = sys_realpath(path, resolved_path);
- END_PROFILE(syscall_realpath);
- return result;
-}
-
-size_t vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc)
-{
- size_t result;
-
- START_PROFILE(fget_nt_acl);
- result = get_nt_acl(fsp, security_info, ppdesc);
- END_PROFILE(fget_nt_acl);
- return result;
-}
-
-size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, SEC_DESC **ppdesc)
-{
- size_t result;
-
- START_PROFILE(get_nt_acl);
- result = get_nt_acl(fsp, security_info, ppdesc);
- END_PROFILE(get_nt_acl);
- return result;
-}
-
-BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd)
-{
- BOOL result;
-
- START_PROFILE(fset_nt_acl);
- result = set_nt_acl(fsp, security_info_sent, psd);
- END_PROFILE(fset_nt_acl);
- return result;
-}
-
-BOOL vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd)
-{
- BOOL result;
-
- START_PROFILE(set_nt_acl);
- result = set_nt_acl(fsp, security_info_sent, psd);
- END_PROFILE(set_nt_acl);
- return result;
-}
-
-int vfswrap_chmod_acl(vfs_handle_struct *handle, connection_struct *conn, const char *name, mode_t mode)
-{
-#ifdef HAVE_NO_ACL
- errno = ENOSYS;
- return -1;
-#else
- int result;
-
- START_PROFILE(chmod_acl);
- result = chmod_acl(conn, name, mode);
- END_PROFILE(chmod_acl);
- return result;
-#endif
-}
-
-int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode)
-{
-#ifdef HAVE_NO_ACL
- errno = ENOSYS;
- return -1;
-#else
- int result;
-
- START_PROFILE(fchmod_acl);
- result = fchmod_acl(fsp, fd, mode);
- END_PROFILE(fchmod_acl);
- return result;
-#endif
-}
-
-int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
-{
- return sys_acl_get_entry(theacl, entry_id, entry_p);
-}
-
-int vfswrap_sys_acl_get_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p)
-{
- return sys_acl_get_tag_type(entry_d, tag_type_p);
-}
-
-int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
-{
- return sys_acl_get_permset(entry_d, permset_p);
-}
-
-void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry_d)
-{
- return sys_acl_get_qualifier(entry_d);
-}
-
-SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type)
-{
- return sys_acl_get_file(handle, path_p, type);
-}
-
-SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, int fd)
-{
- return sys_acl_get_fd(handle, fsp, fd);
-}
-
-int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset)
-{
- return sys_acl_clear_perms(permset);
-}
-
-int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
-{
- return sys_acl_add_perm(permset, perm);
-}
-
-char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen)
-{
- return sys_acl_to_text(theacl, plen);
-}
-
-SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle, connection_struct *conn, int count)
-{
- return sys_acl_init(count);
-}
-
-int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
-{
- return sys_acl_create_entry(pacl, pentry);
-}
-
-int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
-{
- return sys_acl_set_tag_type(entry, tagtype);
-}
-
-int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual)
-{
- return sys_acl_set_qualifier(entry, qual);
-}
-
-int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
-{
- return sys_acl_set_permset(entry, permset);
-}
-
-int vfswrap_sys_acl_valid(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T theacl )
-{
- return sys_acl_valid(theacl );
-}
-
-int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
-{
- return sys_acl_set_file(handle, name, acltype, theacl);
-}
-
-int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl)
-{
- return sys_acl_set_fd(handle, fsp, fd, theacl);
-}
-
-int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, connection_struct *conn, const char *path)
-{
- return sys_acl_delete_def_file(handle, path);
-}
-
-int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
-{
- return sys_acl_get_perm(permset, perm);
-}
-
-int vfswrap_sys_acl_free_text(vfs_handle_struct *handle, connection_struct *conn, char *text)
-{
- return sys_acl_free_text(text);
-}
-
-int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle, connection_struct *conn, SMB_ACL_T posix_acl)
-{
- return sys_acl_free_acl(posix_acl);
-}
-
-int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype)
-{
- return sys_acl_free_qualifier(qualifier, tagtype);
-}
-
-/****************************************************************
- Extended attribute operations.
-*****************************************************************/
-
-ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size)
-{
- return sys_getxattr(path, name, value, size);
-}
-
-ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,struct connection_struct *conn,const char *path, const char *name, void *value, size_t size)
-{
- return sys_lgetxattr(path, name, value, size);
-}
-
-ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size)
-{
- return sys_fgetxattr(fd, name, value, size);
-}
-
-ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
-{
- return sys_listxattr(path, list, size);
-}
-
-ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, char *list, size_t size)
-{
- return sys_llistxattr(path, list, size);
-}
-
-ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, char *list, size_t size)
-{
- return sys_flistxattr(fd, list, size);
-}
-
-int vfswrap_removexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
-{
- return sys_removexattr(path, name);
-}
-
-int vfswrap_lremovexattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name)
-{
- return sys_lremovexattr(path, name);
-}
-
-int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name)
-{
- return sys_fremovexattr(fd, name);
-}
-
-int vfswrap_setxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
-{
- return sys_setxattr(path, name, value, size, flags);
-}
-
-int vfswrap_lsetxattr(struct vfs_handle_struct *handle, struct connection_struct *conn,const char *path, const char *name, const void *value, size_t size, int flags)
-{
- return sys_lsetxattr(path, name, value, size, flags);
-}
-
-int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags)
-{
- return sys_fsetxattr(fd, name, value, size, flags);
-}
-
-int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
-{
- return sys_aio_read(aiocb);
-}
-
-int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
-{
- return sys_aio_write(aiocb);
-}
-
-ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
-{
- return sys_aio_return(aiocb);
-}
-
-int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, SMB_STRUCT_AIOCB *aiocb)
-{
- return sys_aio_cancel(fd, aiocb);
-}
-
-int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
-{
- return sys_aio_error(aiocb);
-}
-
-int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb)
-{
- return sys_aio_fsync(op, aiocb);
-}
-
-int vfswrap_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *timeout)
-{
- return sys_aio_suspend(aiocb, n, timeout);
-}
diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c
index 0e8e6babc40..3ed56d3bf6f 100644
--- a/source/smbd/vfs.c
+++ b/source/smbd/vfs.c
@@ -4,6 +4,7 @@
VFS initialisation and support functions
Copyright (C) Tim Potter 1999
Copyright (C) Alexander Bokovoy 2002
+ Copyright (C) James Peach 2006
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
@@ -37,132 +38,6 @@ struct vfs_init_function_entry {
static struct vfs_init_function_entry *backends = NULL;
-/* Some structures to help us initialise the vfs operations table */
-
-struct vfs_syminfo {
- char *name;
- void *fptr;
-};
-
-/* Default vfs hooks. WARNING: The order of these initialisers is
- very important. They must be in the same order as defined in
- vfs.h. Change at your own peril. */
-
-static struct vfs_ops default_vfs = {
-
- {
- /* Disk operations */
-
- vfswrap_dummy_connect,
- vfswrap_dummy_disconnect,
- vfswrap_disk_free,
- vfswrap_get_quota,
- vfswrap_set_quota,
- vfswrap_get_shadow_copy_data,
- vfswrap_statvfs,
-
- /* Directory operations */
-
- vfswrap_opendir,
- vfswrap_readdir,
- vfswrap_seekdir,
- vfswrap_telldir,
- vfswrap_rewinddir,
- vfswrap_mkdir,
- vfswrap_rmdir,
- vfswrap_closedir,
-
- /* File operations */
-
- vfswrap_open,
- vfswrap_close,
- vfswrap_read,
- vfswrap_pread,
- vfswrap_write,
- vfswrap_pwrite,
- vfswrap_lseek,
- vfswrap_sendfile,
- vfswrap_rename,
- vfswrap_fsync,
- vfswrap_stat,
- vfswrap_fstat,
- vfswrap_lstat,
- vfswrap_unlink,
- vfswrap_chmod,
- vfswrap_fchmod,
- vfswrap_chown,
- vfswrap_fchown,
- vfswrap_chdir,
- vfswrap_getwd,
- vfswrap_utime,
- vfswrap_ftruncate,
- vfswrap_lock,
- vfswrap_kernel_flock,
- vfswrap_getlock,
- vfswrap_symlink,
- vfswrap_readlink,
- vfswrap_link,
- vfswrap_mknod,
- vfswrap_realpath,
-
- /* Windows ACL operations. */
- vfswrap_fget_nt_acl,
- vfswrap_get_nt_acl,
- vfswrap_fset_nt_acl,
- vfswrap_set_nt_acl,
-
- /* POSIX ACL operations. */
- vfswrap_chmod_acl,
- vfswrap_fchmod_acl,
-
- vfswrap_sys_acl_get_entry,
- vfswrap_sys_acl_get_tag_type,
- vfswrap_sys_acl_get_permset,
- vfswrap_sys_acl_get_qualifier,
- vfswrap_sys_acl_get_file,
- vfswrap_sys_acl_get_fd,
- vfswrap_sys_acl_clear_perms,
- vfswrap_sys_acl_add_perm,
- vfswrap_sys_acl_to_text,
- vfswrap_sys_acl_init,
- vfswrap_sys_acl_create_entry,
- vfswrap_sys_acl_set_tag_type,
- vfswrap_sys_acl_set_qualifier,
- vfswrap_sys_acl_set_permset,
- vfswrap_sys_acl_valid,
- vfswrap_sys_acl_set_file,
- vfswrap_sys_acl_set_fd,
- vfswrap_sys_acl_delete_def_file,
- vfswrap_sys_acl_get_perm,
- vfswrap_sys_acl_free_text,
- vfswrap_sys_acl_free_acl,
- vfswrap_sys_acl_free_qualifier,
-
- /* EA operations. */
- vfswrap_getxattr,
- vfswrap_lgetxattr,
- vfswrap_fgetxattr,
- vfswrap_listxattr,
- vfswrap_llistxattr,
- vfswrap_flistxattr,
- vfswrap_removexattr,
- vfswrap_lremovexattr,
- vfswrap_fremovexattr,
- vfswrap_setxattr,
- vfswrap_lsetxattr,
- vfswrap_fsetxattr,
-
- /* AIO operations. */
- vfswrap_aio_read,
- vfswrap_aio_write,
- vfswrap_aio_return,
- vfswrap_aio_cancel,
- vfswrap_aio_error,
- vfswrap_aio_fsync,
- vfswrap_aio_suspend
- }
-};
-
/****************************************************************************
maintain the list of available backends
****************************************************************************/
@@ -218,15 +93,20 @@ NTSTATUS smb_register_vfs(int version, const char *name, vfs_op_tuple *vfs_op_tu
static void vfs_init_default(connection_struct *conn)
{
DEBUG(3, ("Initialising default vfs hooks\n"));
-
- memcpy(&conn->vfs.ops, &default_vfs.ops, sizeof(default_vfs.ops));
- memcpy(&conn->vfs_opaque.ops, &default_vfs.ops, sizeof(default_vfs.ops));
+ vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
}
/****************************************************************************
initialise custom vfs hooks
****************************************************************************/
+static inline void vfs_set_operation(struct vfs_ops * vfs, vfs_op_type which,
+ struct vfs_handle_struct * handle, void * op)
+{
+ ((struct vfs_handle_struct **)&vfs->handles)[which] = handle;
+ ((void **)(void *)&vfs->ops)[which] = op;
+}
+
BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object)
{
vfs_op_tuple *ops;
@@ -293,18 +173,15 @@ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object)
for(i=0; ops[i].op != NULL; i++) {
DEBUG(5, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer));
if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) {
- /* Check whether this operation was already made opaque by different module */
- if(((void**)&conn->vfs_opaque.ops)[ops[i].type] == ((void**)&default_vfs.ops)[ops[i].type]) {
- /* No, it isn't overloaded yet. Overload. */
- DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object));
- ((void**)&conn->vfs_opaque.ops)[ops[i].type] = ops[i].op;
- ((vfs_handle_struct **)&conn->vfs_opaque.handles)[ops[i].type] = handle;
- }
+ /* If this operation was already made opaque by different module, it
+ * will be overridded here.
+ */
+ DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object));
+ vfs_set_operation(&conn->vfs_opaque, ops[i].type, handle, ops[i].op);
}
/* Change current VFS disposition*/
DEBUGADD(5, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object));
- ((void**)&conn->vfs.ops)[ops[i].type] = ops[i].op;
- ((vfs_handle_struct **)&conn->vfs.handles)[ops[i].type] = handle;
+ vfs_set_operation(&conn->vfs, ops[i].type, handle, ops[i].op);
}
SAFE_FREE(module_name);
@@ -312,6 +189,71 @@ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object)
}
/*****************************************************************
+ Allow VFS modules to extend files_struct with VFS-specific state.
+ This will be ok for small numbers of extensions, but might need to
+ be refactored if it becomes more widely used.
+******************************************************************/
+
+#define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
+
+void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle, files_struct *fsp, size_t ext_size)
+{
+ struct vfs_fsp_data *ext;
+ void * ext_data;
+
+ /* Prevent VFS modules adding multiple extensions. */
+ if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
+ return ext_data;
+ }
+
+ ext = (struct vfs_fsp_data *)TALLOC_ZERO(
+ handle->conn->mem_ctx, sizeof(struct vfs_fsp_data) + ext_size);
+ if (ext == NULL) {
+ return NULL;
+ }
+
+ ext->owner = handle;
+ ext->next = fsp->vfs_extension;
+ fsp->vfs_extension = ext;
+ return EXT_DATA_AREA(ext);
+}
+
+void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
+{
+ struct vfs_fsp_data *curr;
+ struct vfs_fsp_data *prev;
+
+ for (curr = fsp->vfs_extension, prev = NULL;
+ curr;
+ prev = curr, curr = curr->next) {
+ if (curr->owner == handle) {
+ if (prev) {
+ prev->next = curr->next;
+ } else {
+ fsp->vfs_extension = curr->next;
+ }
+ TALLOC_FREE(curr);
+ return;
+ }
+ }
+}
+
+void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
+{
+ struct vfs_fsp_data *head;
+
+ for (head = fsp->vfs_extension; head; head = head->next) {
+ if (head->owner == handle) {
+ return EXT_DATA_AREA(head);
+ }
+ }
+
+ return NULL;
+}
+
+#undef EXT_DATA_AREA
+
+/*****************************************************************
Generic VFS init.
******************************************************************/
@@ -705,7 +647,7 @@ char *vfs_readdirname(connection_struct *conn, void *p)
if (!p)
return(NULL);
- ptr = SMB_VFS_READDIR(conn,p);
+ ptr = SMB_VFS_READDIR(conn, (DIR *)p);
if (!ptr)
return(NULL);
diff --git a/source/torture/cmd_vfs.c b/source/torture/cmd_vfs.c
index ad75a2a71f1..6cecd693f83 100644
--- a/source/torture/cmd_vfs.c
+++ b/source/torture/cmd_vfs.c
@@ -200,9 +200,10 @@ static NTSTATUS cmd_closedir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int arg
static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
- int flags, fd;
+ int flags;
mode_t mode;
const char *flagstr;
+ files_struct *fsp;
mode = 00400;
@@ -278,18 +279,21 @@ static NTSTATUS cmd_open(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, c
}
}
- fd = SMB_VFS_OPEN(vfs->conn, argv[1], flags, mode);
- if (fd == -1) {
+ fsp = SMB_MALLOC_P(struct files_struct);
+ fsp->fsp_name = SMB_STRDUP(argv[1]);
+ fsp->fh = SMB_MALLOC_P(struct fd_handle);
+ fsp->conn = vfs->conn;
+
+ fsp->fh->fd = SMB_VFS_OPEN(vfs->conn, argv[1], fsp, flags, mode);
+ if (fsp->fh->fd == -1) {
printf("open: error=%d (%s)\n", errno, strerror(errno));
+ SAFE_FREE(fsp->fh);
+ SAFE_FREE(fsp);
return NT_STATUS_UNSUCCESSFUL;
}
- vfs->files[fd] = SMB_MALLOC_P(struct files_struct);
- vfs->files[fd]->fsp_name = SMB_STRDUP(argv[1]);
- vfs->files[fd]->fh = SMB_MALLOC_P(struct fd_handle);
- vfs->files[fd]->fh->fd = fd;
- vfs->files[fd]->conn = vfs->conn;
- printf("open: fd=%d\n", fd);
+ vfs->files[fsp->fh->fd] = fsp;
+ printf("open: fd=%d\n", fsp->fh->fd);
return NT_STATUS_OK;
}
diff --git a/source/torture/denytest.c b/source/torture/denytest.c
index 291a4035af7..2dc5c2b634f 100644
--- a/source/torture/denytest.c
+++ b/source/torture/denytest.c
@@ -1412,7 +1412,7 @@ BOOL torture_denytest1(int dummy)
BOOL correct = True;
const char *fnames[2] = {"\\denytest1.dat", "\\denytest1.exe"};
- if (!torture_open_connection(&cli1)) {
+ if (!torture_open_connection(&cli1, 0)) {
return False;
}
@@ -1447,10 +1447,10 @@ BOOL torture_denytest1(int dummy)
} else {
char x = 1;
res = A_0;
- if (cli_read(cli1, fnum2, (void *)&x, 0, 1) == 1) {
+ if (cli_read(cli1, fnum2, (char *)&x, 0, 1) == 1) {
res += A_R;
}
- if (cli_write(cli1, fnum2, 0, (void *)&x, 0, 1) == 1) {
+ if (cli_write(cli1, fnum2, 0, (char *)&x, 0, 1) == 1) {
res += A_W;
}
}
@@ -1498,7 +1498,7 @@ BOOL torture_denytest2(int dummy)
BOOL correct = True;
const char *fnames[2] = {"\\denytest2.dat", "\\denytest2.exe"};
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+ if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
return False;
}
@@ -1531,10 +1531,10 @@ BOOL torture_denytest2(int dummy)
} else {
char x = 1;
res = A_0;
- if (cli_read(cli2, fnum2, (void *)&x, 0, 1) == 1) {
+ if (cli_read(cli2, fnum2, (char *)&x, 0, 1) == 1) {
res += A_R;
}
- if (cli_write(cli2, fnum2, 0, (void *)&x, 0, 1) == 1) {
+ if (cli_write(cli2, fnum2, 0, (char *)&x, 0, 1) == 1) {
res += A_W;
}
}
diff --git a/source/torture/locktest.c b/source/torture/locktest.c
index b946e48666e..c3200ca038c 100644
--- a/source/torture/locktest.c
+++ b/source/torture/locktest.c
@@ -113,9 +113,13 @@ static struct record preset[] = {
static struct record *recorded;
-static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid,
- enum brl_type lock_type,
- br_off start, br_off size)
+static void print_brl(SMB_DEV_T dev,
+ SMB_INO_T ino,
+ struct process_id pid,
+ enum brl_type lock_type,
+ enum brl_flavour lock_flav,
+ br_off start,
+ br_off size)
{
#if NASTY_POSIX_LOCK_HACK
{
@@ -178,7 +182,7 @@ static struct cli_state *connect_one(char *share, int snum)
zero_ip(&ip);
/* have to open a new connection */
- if (!(c=cli_initialise(NULL)) || !cli_connect(c, server_n, &ip)) {
+ if (!(c=cli_initialise()) || !cli_connect(c, server_n, &ip)) {
DEBUG(0,("Connection to %s failed\n", server_n));
return NULL;
}
@@ -216,10 +220,12 @@ static struct cli_state *connect_one(char *share, int snum)
fstrcpy(username[1], username[0]);
}
- if (!cli_session_setup(c, username[snum],
- password[snum], strlen(password[snum]),
- password[snum], strlen(password[snum]),
- lp_workgroup())) {
+ if (!NT_STATUS_IS_OK(cli_session_setup(c, username[snum],
+ password[snum],
+ strlen(password[snum]),
+ password[snum],
+ strlen(password[snum]),
+ lp_workgroup()))) {
DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
return NULL;
}
diff --git a/source/torture/locktest2.c b/source/torture/locktest2.c
index 519acebe8e8..5f2f2499acd 100644
--- a/source/torture/locktest2.c
+++ b/source/torture/locktest2.c
@@ -135,6 +135,7 @@ static BOOL try_unlock(struct cli_state *c, int fstype,
static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, struct process_id pid,
enum brl_type lock_type,
+ enum brl_flavour lock_flav,
br_off start, br_off size)
{
printf("%6d %05x:%05x %s %.0f:%.0f(%.0f)\n",
diff --git a/source/torture/mangle_test.c b/source/torture/mangle_test.c
index 9ce6afa038f..1c9fba355a6 100644
--- a/source/torture/mangle_test.c
+++ b/source/torture/mangle_test.c
@@ -167,7 +167,7 @@ BOOL torture_mangle(int dummy)
printf("starting mangle test\n");
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
diff --git a/source/torture/masktest.c b/source/torture/masktest.c
index ffc9a20e71c..2ce59c86e65 100644
--- a/source/torture/masktest.c
+++ b/source/torture/masktest.c
@@ -184,7 +184,7 @@ struct cli_state *connect_one(char *share)
zero_ip(&ip);
/* have to open a new connection */
- if (!(c=cli_initialise(NULL)) || !cli_connect(c, server_n, &ip)) {
+ if (!(c=cli_initialise()) || !cli_connect(c, server_n, &ip)) {
DEBUG(0,("Connection to %s failed\n", server_n));
return NULL;
}
@@ -216,10 +216,10 @@ struct cli_state *connect_one(char *share)
}
}
- if (!cli_session_setup(c, username,
- password, strlen(password),
- password, strlen(password),
- lp_workgroup())) {
+ if (!NT_STATUS_IS_OK(cli_session_setup(c, username,
+ password, strlen(password),
+ password, strlen(password),
+ lp_workgroup()))) {
DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
return NULL;
}
diff --git a/source/torture/nbio.c b/source/torture/nbio.c
index 795392ae5cb..9b2d58c86ee 100644
--- a/source/torture/nbio.c
+++ b/source/torture/nbio.c
@@ -34,7 +34,7 @@ static struct {
int handle;
} ftable[MAX_FILES];
-static struct {
+static struct children {
double bytes_in, bytes_out;
int line;
int done;
@@ -70,7 +70,7 @@ void nb_alarm(int ignore)
void nbio_shmem(int n)
{
nprocs = n;
- children = shm_setup(sizeof(*children) * nprocs);
+ children = (struct children *)shm_setup(sizeof(*children) * nprocs);
if (!children) {
printf("Failed to setup shared memory!\n");
exit(1);
diff --git a/source/torture/nsstest.c b/source/torture/nsstest.c
index d2b17f0f635..7673f922090 100644
--- a/source/torture/nsstest.c
+++ b/source/torture/nsstest.c
@@ -62,7 +62,9 @@ static void report_nss_error(const char *who, NSS_STATUS status)
static struct passwd *nss_getpwent(void)
{
NSS_STATUS (*_nss_getpwent_r)(struct passwd *, char *,
- size_t , int *) = find_fn("getpwent_r");
+ size_t , int *) =
+ (NSS_STATUS (*)(struct passwd *, char *,
+ size_t, int *))find_fn("getpwent_r");
static struct passwd pwd;
static char buf[1000];
NSS_STATUS status;
@@ -84,7 +86,9 @@ static struct passwd *nss_getpwent(void)
static struct passwd *nss_getpwnam(const char *name)
{
NSS_STATUS (*_nss_getpwnam_r)(const char *, struct passwd *, char *,
- size_t , int *) = find_fn("getpwnam_r");
+ size_t , int *) =
+ (NSS_STATUS (*)(const char *, struct passwd *, char *,
+ size_t, int *))find_fn("getpwnam_r");
static struct passwd pwd;
static char buf[1000];
NSS_STATUS status;
@@ -106,7 +110,9 @@ static struct passwd *nss_getpwnam(const char *name)
static struct passwd *nss_getpwuid(uid_t uid)
{
NSS_STATUS (*_nss_getpwuid_r)(uid_t , struct passwd *, char *,
- size_t , int *) = find_fn("getpwuid_r");
+ size_t , int *) =
+ (NSS_STATUS (*)(uid_t, struct passwd *, char *,
+ size_t, int *))find_fn("getpwuid_r");
static struct passwd pwd;
static char buf[1000];
NSS_STATUS status;
@@ -127,7 +133,8 @@ static struct passwd *nss_getpwuid(uid_t uid)
static void nss_setpwent(void)
{
- NSS_STATUS (*_nss_setpwent)(void) = find_fn("setpwent");
+ NSS_STATUS (*_nss_setpwent)(void) =
+ (NSS_STATUS(*)(void))find_fn("setpwent");
NSS_STATUS status;
if (!_nss_setpwent)
@@ -141,7 +148,8 @@ static void nss_setpwent(void)
static void nss_endpwent(void)
{
- NSS_STATUS (*_nss_endpwent)(void) = find_fn("endpwent");
+ NSS_STATUS (*_nss_endpwent)(void) =
+ (NSS_STATUS (*)(void))find_fn("endpwent");
NSS_STATUS status;
if (!_nss_endpwent)
@@ -157,7 +165,9 @@ static void nss_endpwent(void)
static struct group *nss_getgrent(void)
{
NSS_STATUS (*_nss_getgrent_r)(struct group *, char *,
- size_t , int *) = find_fn("getgrent_r");
+ size_t , int *) =
+ (NSS_STATUS (*)(struct group *, char *,
+ size_t, int *))find_fn("getgrent_r");
static struct group grp;
static char *buf;
static int buflen = 1024;
@@ -167,13 +177,13 @@ static struct group *nss_getgrent(void)
return NULL;
if (!buf)
- buf = SMB_MALLOC(buflen);
+ buf = SMB_MALLOC_ARRAY(char, buflen);
again:
status = _nss_getgrent_r(&grp, buf, buflen, &nss_errno);
if (status == NSS_STATUS_TRYAGAIN) {
buflen *= 2;
- buf = SMB_REALLOC(buf, buflen);
+ buf = SMB_REALLOC_ARRAY(buf, char, buflen);
if (!buf) {
return NULL;
}
@@ -192,7 +202,9 @@ again:
static struct group *nss_getgrnam(const char *name)
{
NSS_STATUS (*_nss_getgrnam_r)(const char *, struct group *, char *,
- size_t , int *) = find_fn("getgrnam_r");
+ size_t , int *) =
+ (NSS_STATUS (*)(const char *, struct group *, char *,
+ size_t, int *))find_fn("getgrnam_r");
static struct group grp;
static char *buf;
static int buflen = 1000;
@@ -202,12 +214,12 @@ static struct group *nss_getgrnam(const char *name)
return NULL;
if (!buf)
- buf = SMB_MALLOC(buflen);
+ buf = SMB_MALLOC_ARRAY(char, buflen);
again:
status = _nss_getgrnam_r(name, &grp, buf, buflen, &nss_errno);
if (status == NSS_STATUS_TRYAGAIN) {
buflen *= 2;
- buf = SMB_REALLOC(buf, buflen);
+ buf = SMB_REALLOC_ARRAY(buf, char, buflen);
if (!buf) {
return NULL;
}
@@ -226,7 +238,9 @@ again:
static struct group *nss_getgrgid(gid_t gid)
{
NSS_STATUS (*_nss_getgrgid_r)(gid_t , struct group *, char *,
- size_t , int *) = find_fn("getgrgid_r");
+ size_t , int *) =
+ (NSS_STATUS (*)(gid_t, struct group *, char *,
+ size_t, int *))find_fn("getgrgid_r");
static struct group grp;
static char *buf;
static int buflen = 1000;
@@ -236,13 +250,13 @@ static struct group *nss_getgrgid(gid_t gid)
return NULL;
if (!buf)
- buf = SMB_MALLOC(buflen);
+ buf = SMB_MALLOC_ARRAY(char, buflen);
again:
status = _nss_getgrgid_r(gid, &grp, buf, buflen, &nss_errno);
if (status == NSS_STATUS_TRYAGAIN) {
buflen *= 2;
- buf = SMB_REALLOC(buf, buflen);
+ buf = SMB_REALLOC_ARRAY(buf, char, buflen);
if (!buf) {
return NULL;
}
@@ -260,7 +274,8 @@ again:
static void nss_setgrent(void)
{
- NSS_STATUS (*_nss_setgrent)(void) = find_fn("setgrent");
+ NSS_STATUS (*_nss_setgrent)(void) =
+ (NSS_STATUS (*)(void))find_fn("setgrent");
NSS_STATUS status;
if (!_nss_setgrent)
@@ -274,7 +289,8 @@ static void nss_setgrent(void)
static void nss_endgrent(void)
{
- NSS_STATUS (*_nss_endgrent)(void) = find_fn("endgrent");
+ NSS_STATUS (*_nss_endgrent)(void) =
+ (NSS_STATUS (*)(void))find_fn("endgrent");
NSS_STATUS status;
if (!_nss_endgrent)
@@ -290,7 +306,9 @@ static int nss_initgroups(char *user, gid_t group, gid_t **groups, long int *sta
{
NSS_STATUS (*_nss_initgroups)(char *, gid_t , long int *,
long int *, gid_t **, long int , int *) =
- find_fn("initgroups_dyn");
+ (NSS_STATUS (*)(char *, gid_t, long int *,
+ long int *, gid_t **,
+ long int, int *))find_fn("initgroups_dyn");
NSS_STATUS status;
if (!_nss_initgroups)
diff --git a/source/torture/rpctorture.c b/source/torture/rpctorture.c
index d69cc8eb8df..98f2dc105fa 100644
--- a/source/torture/rpctorture.c
+++ b/source/torture/rpctorture.c
@@ -493,7 +493,7 @@ enum client_action
strupper_m(global_myname);
fstrcpy(cli_info.myhostname, global_myname);
- DEBUG(3,("%s client started (version %s)\n",timestring(False),SAMBA_VERSION_STRING));
+ DEBUG(3,("%s client started (version %s)\n",current_timestring(False),SAMBA_VERSION_STRING));
if (*smb_cli->domain == 0)
{
diff --git a/source/torture/scanner.c b/source/torture/scanner.c
index 1893be83699..87c82f8a737 100644
--- a/source/torture/scanner.c
+++ b/source/torture/scanner.c
@@ -49,7 +49,7 @@ static NTSTATUS try_trans2(struct cli_state *cli,
int op,
char *param, char *data,
int param_len, int data_len,
- int *rparam_len, int *rdata_len)
+ unsigned int *rparam_len, unsigned int *rdata_len)
{
uint16 setup = op;
char *rparam=NULL, *rdata=NULL;
@@ -80,7 +80,7 @@ static NTSTATUS try_trans2_len(struct cli_state *cli,
int op, int level,
char *param, char *data,
int param_len, int *data_len,
- int *rparam_len, int *rdata_len)
+ unsigned int *rparam_len, unsigned int *rdata_len)
{
NTSTATUS ret=NT_STATUS_OK;
@@ -115,7 +115,7 @@ static BOOL scan_trans2(struct cli_state *cli, int op, int level,
{
int data_len = 0;
int param_len = 0;
- int rparam_len, rdata_len;
+ unsigned int rparam_len, rdata_len;
pstring param, data;
NTSTATUS status;
@@ -196,7 +196,7 @@ BOOL torture_trans2_scan(int dummy)
printf("starting trans2 scan test\n");
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -253,7 +253,7 @@ static NTSTATUS try_nttrans(struct cli_state *cli,
int op,
char *param, char *data,
int param_len, int data_len,
- int *rparam_len, int *rdata_len)
+ unsigned int *rparam_len, unsigned int *rdata_len)
{
char *rparam=NULL, *rdata=NULL;
@@ -282,7 +282,7 @@ static NTSTATUS try_nttrans_len(struct cli_state *cli,
int op, int level,
char *param, char *data,
int param_len, int *data_len,
- int *rparam_len, int *rdata_len)
+ unsigned int *rparam_len, unsigned int *rdata_len)
{
NTSTATUS ret=NT_STATUS_OK;
@@ -317,7 +317,7 @@ static BOOL scan_nttrans(struct cli_state *cli, int op, int level,
{
int data_len = 0;
int param_len = 0;
- int rparam_len, rdata_len;
+ unsigned int rparam_len, rdata_len;
pstring param, data;
NTSTATUS status;
@@ -398,7 +398,7 @@ BOOL torture_nttrans_scan(int dummy)
printf("starting nttrans scan test\n");
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
diff --git a/source/torture/torture.c b/source/torture/torture.c
index a8a8e847fbb..79444946122 100644
--- a/source/torture/torture.c
+++ b/source/torture/torture.c
@@ -36,6 +36,8 @@ static BOOL use_oplocks;
static BOOL use_level_II_oplocks;
static const char *client_txt = "client_oplocks.txt";
static BOOL use_kerberos;
+static fstring multishare_conn_fname;
+static BOOL use_multishare_conn = False;
BOOL torture_showall = False;
@@ -44,6 +46,7 @@ static double create_procs(BOOL (*fn)(int), BOOL *result);
static struct timeval tp1,tp2;
+
void start_timer(void)
{
GetTimeOfDay(&tp1);
@@ -94,28 +97,27 @@ void *shm_setup(int size)
}
-static BOOL open_nbt_connection(struct cli_state *c)
+static struct cli_state *open_nbt_connection(void)
{
struct nmb_name called, calling;
struct in_addr ip;
-
- ZERO_STRUCTP(c);
+ struct cli_state *c;
make_nmb_name(&calling, myname, 0x0);
make_nmb_name(&called , host, 0x20);
zero_ip(&ip);
- if (!cli_initialise(c)) {
+ if (!(c = cli_initialise())) {
printf("Failed initialize cli_struct to connect with %s\n", host);
- return False;
+ return NULL;
}
c->port = port_to_use;
if (!cli_connect(c, host, &ip)) {
printf("Failed to connect with %s\n", host);
- return False;
+ return NULL;
}
c->use_kerberos = use_kerberos;
@@ -131,7 +133,7 @@ static BOOL open_nbt_connection(struct cli_state *c)
*/
if (!cli_connect(c, host, &ip)) {
printf("Failed to connect with %s\n", host);
- return False;
+ return NULL;
}
make_nmb_name(&called, "*SMBSERVER", 0x20);
@@ -140,14 +142,74 @@ static BOOL open_nbt_connection(struct cli_state *c)
printf("We tried with a called name of %s & %s\n",
host, "*SMBSERVER");
cli_shutdown(c);
- return False;
+ return NULL;
}
}
- return True;
+ return c;
+}
+
+/* Insert a NULL at the first separator of the given path and return a pointer
+ * to the remainder of the string.
+ */
+static char *
+terminate_path_at_separator(char * path)
+{
+ char * p;
+
+ if (!path) {
+ return NULL;
+ }
+
+ if ((p = strchr_m(path, '/'))) {
+ *p = '\0';
+ return p + 1;
+ }
+
+ if ((p = strchr_m(path, '\\'))) {
+ *p = '\0';
+ return p + 1;
+ }
+
+ /* No separator. */
+ return NULL;
+}
+
+/*
+ parse a //server/share type UNC name
+*/
+BOOL smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
+ char **hostname, char **sharename)
+{
+ char *p;
+
+ *hostname = *sharename = NULL;
+
+ if (strncmp(unc_name, "\\\\", 2) &&
+ strncmp(unc_name, "//", 2)) {
+ return False;
+ }
+
+ *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
+ p = terminate_path_at_separator(*hostname);
+
+ if (p && *p) {
+ *sharename = talloc_strdup(mem_ctx, p);
+ terminate_path_at_separator(*sharename);
+ }
+
+ if (*hostname && *sharename) {
+ return True;
+ }
+
+ TALLOC_FREE(*hostname);
+ TALLOC_FREE(*sharename);
+ return False;
}
-BOOL torture_open_connection(struct cli_state **c)
+static BOOL torture_open_connection_share(struct cli_state **c,
+ const char *hostname,
+ const char *sharename)
{
BOOL retry;
int flags = 0;
@@ -155,13 +217,15 @@ BOOL torture_open_connection(struct cli_state **c)
if (use_kerberos)
flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
-
+
status = cli_full_connection(c, myname,
- host, NULL, port_to_use,
- share, "?????",
+ hostname, NULL, port_to_use,
+ sharename, "?????",
username, workgroup,
password, flags, Undefined, &retry);
if (!NT_STATUS_IS_OK(status)) {
+ printf("failed to open share connection: //%s/%s port:%d - %s\n",
+ hostname, sharename, port_to_use, nt_errstr(status));
return False;
}
@@ -172,6 +236,47 @@ BOOL torture_open_connection(struct cli_state **c)
return True;
}
+void torture_open_connection_free_unclist(char **unc_list)
+{
+ if (unc_list!=NULL)
+ {
+ SAFE_FREE(unc_list[0]);
+ SAFE_FREE(unc_list);
+ }
+}
+
+BOOL torture_open_connection(struct cli_state **c, int conn_index)
+{
+ char **unc_list = NULL;
+ int num_unc_names = 0;
+ BOOL result;
+
+ if (use_multishare_conn==True) {
+ char *h, *s;
+ unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0);
+ if (!unc_list || num_unc_names <= 0) {
+ printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
+ exit(1);
+ }
+
+ if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
+ NULL, &h, &s)) {
+ printf("Failed to parse UNC name %s\n",
+ unc_list[conn_index % num_unc_names]);
+ torture_open_connection_free_unclist(unc_list);
+ exit(1);
+ }
+
+ result = torture_open_connection_share(c, h, s);
+
+ /* h, s were copied earlier */
+ torture_open_connection_free_unclist(unc_list);
+ return result;
+ }
+
+ return torture_open_connection_share(c, host, share);
+}
+
BOOL torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
{
uint16 old_vuid = cli->vuid;
@@ -181,7 +286,10 @@ BOOL torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
fstrcpy(old_user_name, cli->user_name);
cli->vuid = 0;
- ret = cli_session_setup(cli, username, password, passlen, password, passlen, workgroup);
+ ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
+ password, passlen,
+ password, passlen,
+ workgroup));
*new_vuid = cli->vuid;
cli->vuid = old_vuid;
fstrcpy(cli->user_name, old_user_name);
@@ -462,8 +570,8 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
int fnum1;
int fnum2;
int i;
- uchar buf[131072];
- uchar buf_rd[131072];
+ char buf[131072];
+ char buf_rd[131072];
BOOL correct = True;
ssize_t bytes_read;
@@ -494,7 +602,7 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
printf("%d\r", i); fflush(stdout);
}
- generate_random_buffer(buf, buf_size);
+ generate_random_buffer((unsigned char *)buf, buf_size);
if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
printf("write failed (%s)\n", cli_errstr(c1));
@@ -504,7 +612,7 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
printf("read failed (%s)\n", cli_errstr(c2));
- printf("read %d, expected %ld\n", bytes_read,
+ printf("read %d, expected %ld\n", (int)bytes_read,
(unsigned long)buf_size);
correct = False;
break;
@@ -540,7 +648,7 @@ static BOOL run_readwritetest(int dummy)
static struct cli_state *cli1, *cli2;
BOOL test1, test2 = False;
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+ if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
return False;
}
cli_sockopt(cli1, sockops);
@@ -595,7 +703,7 @@ static BOOL run_readwritelarge(int dummy)
char buf[126*1024];
BOOL correct = True;
- if (!torture_open_connection(&cli1)) {
+ if (!torture_open_connection(&cli1, 0)) {
return False;
}
cli_sockopt(cli1, sockops);
@@ -826,7 +934,7 @@ static BOOL run_locktest1(int dummy)
time_t t1, t2;
unsigned lock_timeout;
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+ if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
return False;
}
cli_sockopt(cli1, sockops);
@@ -941,7 +1049,7 @@ static BOOL run_tcon_test(int dummy)
char buf[4];
BOOL ret = True;
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
cli_sockopt(cli, sockops);
@@ -1043,7 +1151,7 @@ static BOOL run_tcon2_test(int dummy)
char *service;
NTSTATUS status;
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
cli_sockopt(cli, sockops);
@@ -1196,7 +1304,7 @@ static BOOL run_locktest2(int dummy)
int fnum1, fnum2, fnum3;
BOOL correct = True;
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -1335,7 +1443,7 @@ static BOOL run_locktest3(int dummy)
#define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+ if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
return False;
}
cli_sockopt(cli1, sockops);
@@ -1459,7 +1567,7 @@ static BOOL run_locktest4(int dummy)
char buf[1000];
BOOL correct = True;
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+ if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
return False;
}
@@ -1630,7 +1738,7 @@ static BOOL run_locktest5(int dummy)
char buf[1000];
BOOL correct = True;
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+ if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
return False;
}
@@ -1753,7 +1861,7 @@ static BOOL run_locktest6(int dummy)
int fnum;
NTSTATUS status;
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -1793,7 +1901,7 @@ static BOOL run_locktest7(int dummy)
char buf[200];
BOOL correct = False;
- if (!torture_open_connection(&cli1)) {
+ if (!torture_open_connection(&cli1, 0)) {
return False;
}
@@ -1929,7 +2037,7 @@ static BOOL run_fdpasstest(int dummy)
int fnum1;
pstring buf;
- if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+ if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
return False;
}
cli_sockopt(cli1, sockops);
@@ -1984,7 +2092,7 @@ static BOOL run_fdsesstest(int dummy)
pstring buf;
BOOL ret = True;
- if (!torture_open_connection(&cli))
+ if (!torture_open_connection(&cli, 0))
return False;
cli_sockopt(cli, sockops);
@@ -2066,7 +2174,7 @@ static BOOL run_unlinktest(int dummy)
int fnum;
BOOL correct = True;
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -2174,20 +2282,20 @@ static void rand_buf(char *buf, int len)
static BOOL run_negprot_nowait(int dummy)
{
int i;
- static struct cli_state cli;
+ static struct cli_state *cli;
BOOL correct = True;
printf("starting negprot nowait test\n");
- if (!open_nbt_connection(&cli)) {
+ if (!(cli = open_nbt_connection())) {
return False;
}
for (i=0;i<50000;i++) {
- cli_negprot_send(&cli);
+ cli_negprot_send(cli);
}
- if (!torture_close_connection(&cli)) {
+ if (!torture_close_connection(cli)) {
correct = False;
}
@@ -2202,7 +2310,7 @@ static BOOL run_randomipc(int dummy)
{
char *rparam = NULL;
char *rdata = NULL;
- int rdrcnt,rprcnt;
+ unsigned int rdrcnt,rprcnt;
pstring param;
int api, param_len, i;
struct cli_state *cli;
@@ -2211,7 +2319,7 @@ static BOOL run_randomipc(int dummy)
printf("starting random ipc test\n");
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -2264,7 +2372,7 @@ static BOOL run_browsetest(int dummy)
printf("starting browse test\n");
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -2302,7 +2410,7 @@ static BOOL run_attrtest(int dummy)
printf("starting attrib test\n");
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -2361,7 +2469,8 @@ static BOOL run_trans2test(int dummy)
struct cli_state *cli;
int fnum;
SMB_OFF_T size;
- time_t c_time, a_time, m_time, w_time, m_time2;
+ time_t c_time, a_time, m_time;
+ struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
const char *fname = "\\trans2.tst";
const char *dname = "\\trans2";
const char *fname2 = "\\trans2\\trans2.tst";
@@ -2370,15 +2479,15 @@ static BOOL run_trans2test(int dummy)
printf("starting trans2 test\n");
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
cli_unlink(cli, fname);
fnum = cli_open(cli, fname,
O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
- if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
- NULL, NULL)) {
+ if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
+ &m_time_ts, NULL)) {
printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
correct = False;
}
@@ -2433,13 +2542,13 @@ static BOOL run_trans2test(int dummy)
fnum = cli_open(cli, fname,
O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
cli_close(cli, fnum);
- if (!cli_qpathinfo2(cli, fname, &c_time, &a_time, &w_time,
- &m_time, &size, NULL, NULL)) {
+ if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
+ &m_time_ts, &size, NULL, NULL)) {
printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
correct = False;
} else {
- if (w_time < 60*60*24*2) {
- printf("write time=%s", ctime(&w_time));
+ if (w_time_ts.tv_sec < 60*60*24*2) {
+ printf("write time=%s", ctime(&w_time_ts.tv_sec));
printf("This system appears to set a initial 0 write time\n");
correct = False;
}
@@ -2455,8 +2564,8 @@ static BOOL run_trans2test(int dummy)
correct = False;
}
sleep(3);
- if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &w_time,
- &m_time, &size, NULL, NULL)) {
+ if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
+ &m_time_ts, &size, NULL, NULL)) {
printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
correct = False;
}
@@ -2465,12 +2574,13 @@ static BOOL run_trans2test(int dummy)
O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
cli_close(cli, fnum);
- if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &w_time,
- &m_time2, &size, NULL, NULL)) {
+ if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
+ &m_time2_ts, &size, NULL, NULL)) {
printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
correct = False;
} else {
- if (m_time2 == m_time) {
+ if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
+ == 0) {
printf("This system does not update directory modification times\n");
correct = False;
}
@@ -2519,7 +2629,7 @@ static BOOL run_w2ktest(int dummy)
printf("starting w2k test\n");
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -2554,7 +2664,7 @@ static BOOL run_oplock1(int dummy)
printf("starting oplock test 1\n");
- if (!torture_open_connection(&cli1)) {
+ if (!torture_open_connection(&cli1, 0)) {
return False;
}
@@ -2612,7 +2722,7 @@ static BOOL run_oplock2(int dummy)
printf("starting oplock test 2\n");
- if (!torture_open_connection(&cli1)) {
+ if (!torture_open_connection(&cli1, 0)) {
use_level_II_oplocks = False;
use_oplocks = saved_use_oplocks;
return False;
@@ -2621,7 +2731,7 @@ static BOOL run_oplock2(int dummy)
cli1->use_oplocks = True;
cli1->use_level_II_oplocks = True;
- if (!torture_open_connection(&cli2)) {
+ if (!torture_open_connection(&cli2, 1)) {
use_level_II_oplocks = False;
use_oplocks = saved_use_oplocks;
return False;
@@ -2755,7 +2865,7 @@ static BOOL run_oplock3(int dummy)
/* Child code */
use_oplocks = True;
use_level_II_oplocks = True;
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
*shared_correct = False;
exit(0);
}
@@ -2769,7 +2879,7 @@ static BOOL run_oplock3(int dummy)
/* parent code */
use_oplocks = True;
use_level_II_oplocks = True;
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 1)) { /* other is forked */
return False;
}
cli_oplock_handler(cli, oplock3_handler);
@@ -2802,7 +2912,7 @@ static BOOL run_deletetest(int dummy)
printf("starting delete test\n");
- if (!torture_open_connection(&cli1)) {
+ if (!torture_open_connection(&cli1, 0)) {
return False;
}
@@ -3116,7 +3226,7 @@ static BOOL run_deletetest(int dummy)
cli_setatr(cli1, fname, 0, 0);
cli_unlink(cli1, fname);
- if (!torture_open_connection(&cli2)) {
+ if (!torture_open_connection(&cli2, 1)) {
printf("[8] failed to open second connection.\n");
correct = False;
goto fail;
@@ -3283,7 +3393,7 @@ static BOOL run_properties(int dummy)
ZERO_STRUCT(cli);
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -3331,7 +3441,7 @@ static BOOL run_xcopy(int dummy)
printf("starting xcopy test\n");
- if (!torture_open_connection(&cli1)) {
+ if (!torture_open_connection(&cli1, 0)) {
return False;
}
@@ -3374,7 +3484,7 @@ static BOOL run_rename(int dummy)
printf("starting rename test\n");
- if (!torture_open_connection(&cli1)) {
+ if (!torture_open_connection(&cli1, 0)) {
return False;
}
@@ -3560,7 +3670,7 @@ static BOOL run_pipe_number(int dummy)
int num_pipes = 0;
printf("starting pipenumber test\n");
- if (!torture_open_connection(&cli1)) {
+ if (!torture_open_connection(&cli1, 0)) {
return False;
}
@@ -3574,6 +3684,7 @@ static BOOL run_pipe_number(int dummy)
break;
}
num_pipes++;
+ printf("\r%6d", num_pipes);
}
printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
@@ -3597,7 +3708,7 @@ static BOOL run_opentest(int dummy)
printf("starting open test\n");
- if (!torture_open_connection(&cli1)) {
+ if (!torture_open_connection(&cli1, 0)) {
return False;
}
@@ -3744,7 +3855,7 @@ static BOOL run_opentest(int dummy)
/* Test the non-io opens... */
- if (!torture_open_connection(&cli2)) {
+ if (!torture_open_connection(&cli2, 1)) {
return False;
}
@@ -4045,7 +4156,7 @@ static BOOL run_openattrtest(int dummy)
printf("starting open attr test\n");
- if (!torture_open_connection(&cli1)) {
+ if (!torture_open_connection(&cli1, 0)) {
return False;
}
@@ -4157,7 +4268,7 @@ static BOOL run_dirtest(int dummy)
printf("starting directory test\n");
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -4230,7 +4341,7 @@ BOOL torture_ioctl_test(int dummy)
DATA_BLOB blob;
NTSTATUS status;
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -4258,7 +4369,8 @@ BOOL torture_ioctl_test(int dummy)
status = cli_raw_ioctl(cli, fnum, code, &blob);
if (NT_STATUS_IS_OK(status)) {
- printf("ioctl 0x%x OK : %d bytes\n", code, blob.length);
+ printf("ioctl 0x%x OK : %d bytes\n", (int)code,
+ (int)blob.length);
data_blob_free(&blob);
}
}
@@ -4281,7 +4393,7 @@ BOOL torture_chkpath_test(int dummy)
int fnum;
BOOL ret;
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -4366,7 +4478,7 @@ static BOOL run_eatest(int dummy)
printf("starting eatest\n");
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -4409,7 +4521,7 @@ static BOOL run_eatest(int dummy)
correct = False;
}
- printf("num_eas = %d\n", num_eas);
+ printf("num_eas = %d\n", (int)num_eas);
if (num_eas != 20) {
printf("Should be 20 EA's stored... failing.\n");
@@ -4418,7 +4530,8 @@ static BOOL run_eatest(int dummy)
for (i = 0; i < num_eas; i++) {
printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
- dump_data(0, ea_list[i].value.data, ea_list[i].value.length);
+ dump_data(0, (char *)ea_list[i].value.data,
+ ea_list[i].value.length);
}
/* Setting EA's to zero length deletes them. Test this */
@@ -4442,10 +4555,11 @@ static BOOL run_eatest(int dummy)
correct = False;
}
- printf("num_eas = %d\n", num_eas);
+ printf("num_eas = %d\n", (int)num_eas);
for (i = 0; i < num_eas; i++) {
printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
- dump_data(0, ea_list[i].value.data, ea_list[i].value.length);
+ dump_data(0, (char *)ea_list[i].value.data,
+ ea_list[i].value.length);
}
if (num_eas != 0) {
@@ -4476,7 +4590,7 @@ static BOOL run_dirtest1(int dummy)
printf("starting directory test\n");
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -4550,8 +4664,8 @@ static BOOL run_dirtest1(int dummy)
static BOOL run_error_map_extract(int dummy) {
- static struct cli_state c_dos;
- static struct cli_state c_nt;
+ static struct cli_state *c_dos;
+ static struct cli_state *c_nt;
uint32 error;
@@ -4564,81 +4678,81 @@ static BOOL run_error_map_extract(int dummy) {
/* NT-Error connection */
- if (!open_nbt_connection(&c_nt)) {
+ if (!(c_nt = open_nbt_connection())) {
return False;
}
- c_nt.use_spnego = False;
+ c_nt->use_spnego = False;
- if (!cli_negprot(&c_nt)) {
- printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
- cli_shutdown(&c_nt);
+ if (!cli_negprot(c_nt)) {
+ printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(c_nt));
+ cli_shutdown(c_nt);
return False;
}
- if (!cli_session_setup(&c_nt, "", "", 0, "", 0,
- workgroup)) {
- printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt));
+ if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
+ workgroup))) {
+ printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
return False;
}
/* DOS-Error connection */
- if (!open_nbt_connection(&c_dos)) {
+ if (!(c_dos = open_nbt_connection())) {
return False;
}
- c_dos.use_spnego = False;
- c_dos.force_dos_errors = True;
+ c_dos->use_spnego = False;
+ c_dos->force_dos_errors = True;
- if (!cli_negprot(&c_dos)) {
- printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
- cli_shutdown(&c_dos);
+ if (!cli_negprot(c_dos)) {
+ printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(c_dos));
+ cli_shutdown(c_dos);
return False;
}
- if (!cli_session_setup(&c_dos, "", "", 0, "", 0,
- workgroup)) {
- printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos));
+ if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
+ workgroup))) {
+ printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
return False;
}
for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
fstr_sprintf(user, "%X", error);
- if (cli_session_setup(&c_nt, user,
- password, strlen(password),
- password, strlen(password),
- workgroup)) {
+ if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
+ password, strlen(password),
+ password, strlen(password),
+ workgroup))) {
printf("/** Session setup succeeded. This shouldn't happen...*/\n");
}
- flgs2 = SVAL(c_nt.inbuf,smb_flg2);
+ flgs2 = SVAL(c_nt->inbuf,smb_flg2);
/* Case #1: 32-bit NT errors */
if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
- nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
+ nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
} else {
printf("/** Dos error on NT connection! (%s) */\n",
- cli_errstr(&c_nt));
+ cli_errstr(c_nt));
nt_status = NT_STATUS(0xc0000000);
}
- if (cli_session_setup(&c_dos, user,
- password, strlen(password),
- password, strlen(password),
- workgroup)) {
+ if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
+ password, strlen(password),
+ password, strlen(password),
+ workgroup))) {
printf("/** Session setup succeeded. This shouldn't happen...*/\n");
}
- flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
+ flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
/* Case #1: 32-bit NT errors */
if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
printf("/** NT error on DOS connection! (%s) */\n",
- cli_errstr(&c_nt));
+ cli_errstr(c_nt));
errnum = errclass = 0;
} else {
- cli_dos_error(&c_dos, &errclass, &errnum);
+ cli_dos_error(c_dos, &errclass, &errnum);
}
if (NT_STATUS_V(nt_status) != error) {
@@ -4655,6 +4769,101 @@ static BOOL run_error_map_extract(int dummy) {
return True;
}
+static BOOL run_local_substitute(int dummy)
+{
+ TALLOC_CTX *mem_ctx;
+ int diff = 0;
+
+ if ((mem_ctx = talloc_init("run_local_subst")) == NULL) {
+ printf("talloc_init failed\n");
+ return False;
+ }
+
+ diff |= strcmp(talloc_sub_specified(mem_ctx, "%U", "bla", "", -1, -1),
+ "bla");
+ diff |= strcmp(talloc_sub_specified(mem_ctx, "%u%U", "bla", "", -1, -1),
+ "blabla");
+ diff |= strcmp(talloc_sub_specified(mem_ctx, "%g", "", "", -1, -1),
+ "NO_GROUP");
+ diff |= strcmp(talloc_sub_specified(mem_ctx, "%G", "", "", -1, -1),
+ "NO_GROUP");
+ diff |= strcmp(talloc_sub_specified(mem_ctx, "%g", "", "", -1, 0),
+ gidtoname(0));
+ diff |= strcmp(talloc_sub_specified(mem_ctx, "%G", "", "", -1, 0),
+ gidtoname(0));
+ diff |= strcmp(talloc_sub_specified(mem_ctx, "%D%u", "u", "dom", -1, 0),
+ "domu");
+ diff |= strcmp(talloc_sub_specified(mem_ctx, "%i %I", "", "", -1, -1),
+ "0.0.0.0 0.0.0.0");
+
+ /* Different captialization rules in sub_basic... */
+
+ diff |= strcmp(talloc_sub_basic(mem_ctx, "BLA", "dom", "%U%D"),
+ "blaDOM");
+
+ TALLOC_FREE(mem_ctx);
+ return (diff == 0);
+}
+
+static BOOL run_local_gencache(int dummy)
+{
+ char *val;
+ time_t tm;
+
+ if (!gencache_init()) {
+ d_printf("%s: gencache_init() failed\n", __location__);
+ return False;
+ }
+
+ if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
+ d_printf("%s: gencache_set() failed\n", __location__);
+ return False;
+ }
+
+ if (!gencache_get("foo", &val, &tm)) {
+ d_printf("%s: gencache_get() failed\n", __location__);
+ return False;
+ }
+
+ if (strcmp(val, "bar") != 0) {
+ d_printf("%s: gencache_get() returned %s, expected %s\n",
+ __location__, val, "bar");
+ SAFE_FREE(val);
+ return False;
+ }
+
+ SAFE_FREE(val);
+
+ if (!gencache_del("foo")) {
+ d_printf("%s: gencache_del() failed\n", __location__);
+ return False;
+ }
+ if (gencache_del("foo")) {
+ d_printf("%s: second gencache_del() succeeded\n",
+ __location__);
+ return False;
+ }
+
+ if (gencache_get("foo", &val, &tm)) {
+ d_printf("%s: gencache_get() on deleted entry "
+ "succeeded\n", __location__);
+ return False;
+ }
+
+ if (!gencache_shutdown()) {
+ d_printf("%s: gencache_shutdown() failed\n", __location__);
+ return False;
+ }
+
+ if (gencache_shutdown()) {
+ d_printf("%s: second gencache_shutdown() succeeded\n",
+ __location__);
+ return False;
+ }
+
+ return True;
+}
+
static double create_procs(BOOL (*fn)(int), BOOL *result)
{
int i, status;
@@ -4693,7 +4902,7 @@ static double create_procs(BOOL (*fn)(int), BOOL *result)
slprintf(myname,sizeof(myname),"CLIENT%d", i);
while (1) {
- if (torture_open_connection(&current_cli)) break;
+ if (torture_open_connection(&current_cli, i)) break;
if (tries-- == 0) {
printf("pid %d failed to start\n", (int)getpid());
_exit(1);
@@ -4805,6 +5014,8 @@ static struct {
{"CHKPATH", torture_chkpath_test, 0},
{"FDSESS", run_fdsesstest, 0},
{ "EATEST", run_eatest, 0},
+ { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
+ { "LOCAL-GENCACHE", run_local_gencache, 0},
{NULL, NULL, 0}};
@@ -4884,6 +5095,7 @@ static void usage(void)
printf("\t-A showall\n");
printf("\t-p port\n");
printf("\t-s seed\n");
+ printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
printf("\n\n");
printf("tests are:");
@@ -4952,7 +5164,7 @@ static void usage(void)
fstrcpy(workgroup, lp_workgroup());
- while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Ac:ks:")) != EOF) {
+ while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Ac:ks:b:")) != EOF) {
switch (opt) {
case 'p':
port_to_use = atoi(optarg);
@@ -5008,6 +5220,10 @@ static void usage(void)
gotpass = 1;
}
break;
+ case 'b':
+ fstrcpy(multishare_conn_fname, optarg);
+ use_multishare_conn = True;
+ break;
default:
printf("Unknown option %c (%d)\n", (char)opt, opt);
usage();
diff --git a/source/torture/utable.c b/source/torture/utable.c
index afc3b749a54..e5126da91d3 100644
--- a/source/torture/utable.c
+++ b/source/torture/utable.c
@@ -32,7 +32,7 @@ BOOL torture_utable(int dummy)
printf("starting utable\n");
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
@@ -121,7 +121,7 @@ BOOL torture_casetable(int dummy)
smb_ucs2_t equiv[0x10000][MAX_EQUIVALENCE];
printf("starting casetable\n");
- if (!torture_open_connection(&cli)) {
+ if (!torture_open_connection(&cli, 0)) {
return False;
}
diff --git a/source/torture/vfstest.c b/source/torture/vfstest.c
index 61bb4b0bf65..fa0545988e9 100644
--- a/source/torture/vfstest.c
+++ b/source/torture/vfstest.c
@@ -575,6 +575,6 @@ int main(int argc, char *argv[])
process_cmd(&vfs, line);
}
- free(vfs.conn);
+ conn_free(vfs.conn);
return 0;
}
diff --git a/source/utils/net_sam.c b/source/utils/net_sam.c
index 9edbc7b8cf4..03e0ff0a9c3 100644
--- a/source/utils/net_sam.c
+++ b/source/utils/net_sam.c
@@ -206,23 +206,20 @@ static int net_sam_set_pwnoexp(int argc, const char **argv)
}
/*
- * Set a user's time field
+ * Set pass last change time, based on force pass change now
*/
-static int net_sam_set_time(int argc, const char **argv, const char *field,
- BOOL (*fn)(struct samu *, time_t,
- enum pdb_value_state))
+static int net_sam_set_pwdmustchangenow(int argc, const char **argv)
{
struct samu *sam_acct = NULL;
DOM_SID sid;
enum lsa_SidType type;
const char *dom, *name;
NTSTATUS status;
- time_t new_time;
- if (argc != 2) {
- d_fprintf(stderr, "usage: net sam set %s <user> "
- "[now|YYYY-MM-DD HH:MM]\n", field);
+ if ((argc != 2) || (!strequal(argv[1], "yes") &&
+ !strequal(argv[1], "no"))) {
+ d_fprintf(stderr, "usage: net sam set pwdmustchangenow <user> [yes|no]\n");
return -1;
}
@@ -238,22 +235,6 @@ static int net_sam_set_time(int argc, const char **argv, const char *field,
return -1;
}
- if (strequal(argv[1], "now")) {
- new_time = time(NULL);
- } else {
- struct tm tm;
- char *end;
- ZERO_STRUCT(tm);
- end = strptime(argv[1], "%Y-%m-%d %H:%M", &tm);
- new_time = mktime(&tm);
- if ((end == NULL) || (*end != '\0') || (new_time == -1)) {
- d_fprintf(stderr, "Could not parse time string %s\n",
- argv[1]);
- return -1;
- }
- }
-
-
if ( !(sam_acct = samu_new( NULL )) ) {
d_fprintf(stderr, "Internal error\n");
return -1;
@@ -264,9 +245,10 @@ static int net_sam_set_time(int argc, const char **argv, const char *field,
return -1;
}
- if (!fn(sam_acct, new_time, PDB_CHANGED)) {
- d_fprintf(stderr, "Internal error\n");
- return -1;
+ if (strequal(argv[1], "yes")) {
+ pdb_set_pass_last_set_time(sam_acct, 0, PDB_CHANGED);
+ } else {
+ pdb_set_pass_last_set_time(sam_acct, time(NULL), PDB_CHANGED);
}
status = pdb_update_sam_account(sam_acct);
@@ -278,21 +260,11 @@ static int net_sam_set_time(int argc, const char **argv, const char *field,
TALLOC_FREE(sam_acct);
- d_printf("Updated %s for %s\\%s to %s\n", field, dom, name, argv[1]);
+ d_fprintf(stderr, "Updated 'user must change password at next logon' for %s\\%s to %s\n", dom,
+ name, argv[1]);
return 0;
}
-static int net_sam_set_pwdmustchange(int argc, const char **argv)
-{
- return net_sam_set_time(argc, argv, "pwdmustchange",
- pdb_set_pass_must_change_time);
-}
-
-static int net_sam_set_pwdcanchange(int argc, const char **argv)
-{
- return net_sam_set_time(argc, argv, "pwdcanchange",
- pdb_set_pass_can_change_time);
-}
/*
* Set a user's or a group's comment
@@ -376,10 +348,8 @@ static int net_sam_set(int argc, const char **argv)
"Disable/Enable a user's lockout flag" },
{ "pwnoexp", net_sam_set_pwnoexp,
"Disable/Enable whether a user's pw does not expire" },
- { "pwdmustchange", net_sam_set_pwdmustchange,
- "Set a users password must change time" },
- { "pwdcanchange", net_sam_set_pwdcanchange,
- "Set a users password can change time" },
+ { "pwdmustchangenow", net_sam_set_pwdmustchangenow,
+ "Force users password must change at next logon" },
{NULL, NULL}
};
@@ -387,6 +357,80 @@ static int net_sam_set(int argc, const char **argv)
}
/*
+ * Change account policies
+ */
+
+static int net_sam_policy(int argc, const char **argv)
+{
+
+ const char *account_policy = NULL;
+ uint32 value, old_value;
+ int field;
+
+ if ((argc < 1) || (argc > 2)) {
+ d_fprintf(stderr, "usage: net sam policy \"<account policy>\" "
+ "-> show current value\n");
+ d_fprintf(stderr, "usage: net sam policy \"<account policy>\" "
+ "<value> -> set a new value\n");
+ return -1;
+ }
+
+ account_policy = argv[0];
+ field = account_policy_name_to_fieldnum(account_policy);
+
+ if (field == 0) {
+ char *apn = account_policy_names_list();
+ d_fprintf(stderr, "No account policy by that name!\n");
+ if (apn) {
+ d_fprintf(stderr, "Valid account policies "
+ "are:\n%s\n", apn);
+ }
+ SAFE_FREE(apn);
+ return -1;
+ }
+
+ if (!pdb_get_account_policy(field, &old_value)) {
+ fprintf(stderr, "Valid account policy, but unable to "
+ "fetch value!\n");
+ return -1;
+ }
+
+ if (argc == 1) {
+ /*
+ * Just read the value
+ */
+
+ printf("Account policy \"%s\" description: %s\n",
+ account_policy, account_policy_get_desc(field));
+ printf("Account policy \"%s\" value is: %d\n", account_policy,
+ old_value);
+ return 0;
+ }
+
+ /*
+ * Here we know we have 2 args, so set it
+ */
+
+ value = strtoul(argv[1], NULL, 10);
+
+ printf("Account policy \"%s\" description: %s\n", account_policy,
+ account_policy_get_desc(field));
+ printf("Account policy \"%s\" value was: %d\n", account_policy,
+ old_value);
+
+ if (!pdb_set_account_policy(field, value)) {
+ d_fprintf(stderr, "Setting account policy %s to %u failed \n",
+ account_policy, value);
+ }
+
+ printf("Account policy \"%s\" value is now: %d\n", account_policy,
+ value);
+
+ return 0;
+}
+
+
+/*
* Map a unix group to a domain group
*/
@@ -1232,6 +1276,8 @@ int net_sam(int argc, const char **argv)
"Show details of a SAM entry" },
{ "set", net_sam_set,
"Set details of a SAM account" },
+ { "policy", net_sam_policy,
+ "Set account policies" },
#ifdef HAVE_LDAP
{ "provision", net_sam_provision,
"Provision a clean User Database" },
diff --git a/source/utils/net_time.c b/source/utils/net_time.c
index f6486286a65..f6269627dab 100644
--- a/source/utils/net_time.c
+++ b/source/utils/net_time.c
@@ -30,8 +30,10 @@ static time_t cli_servertime(const char *host, struct in_addr *ip, int *zone)
time_t ret = 0;
struct cli_state *cli = NULL;
- cli = cli_initialise(NULL);
- if (!cli) goto done;
+ cli = cli_initialise();
+ if (!cli) {
+ goto done;
+ }
if (!cli_connect(cli, host, ip)) {
fprintf(stderr,"Can't contact server\n");
@@ -58,7 +60,9 @@ static time_t cli_servertime(const char *host, struct in_addr *ip, int *zone)
if (zone) *zone = cli->serverzone;
done:
- if (cli) cli_shutdown(cli);
+ if (cli) {
+ cli_shutdown(cli);
+ }
return ret;
}
diff --git a/source/utils/status.c b/source/utils/status.c
index 163d99a2f69..4f66501511b 100644
--- a/source/utils/status.c
+++ b/source/utils/status.c
@@ -48,6 +48,9 @@ static BOOL numeric_only = False;
const char *username = NULL;
+extern BOOL status_profile_dump(BOOL be_verbose);
+extern BOOL status_profile_rates(BOOL be_verbose);
+
/* added by OH */
static void Ucrit_addUid(uid_t uid)
{
@@ -98,7 +101,10 @@ static BOOL Ucrit_addPid( pid_t pid )
return True;
}
-static void print_share_mode(const struct share_mode_entry *e, const char *sharepath, const char *fname)
+static void print_share_mode(const struct share_mode_entry *e,
+ const char *sharepath,
+ const char *fname,
+ void *dummy)
{
static int count;
@@ -182,368 +188,6 @@ static void print_brl(SMB_DEV_T dev,
(double)start, (double)size);
}
-
-/*******************************************************************
- dump the elements of the profile structure
- ******************************************************************/
-static int profile_dump(void)
-{
-#ifdef WITH_PROFILE
- if (!profile_setup(True)) {
- fprintf(stderr,"Failed to initialise profile memory\n");
- return -1;
- }
-
- d_printf("smb_count: %u\n", profile_p->smb_count);
- d_printf("uid_changes: %u\n", profile_p->uid_changes);
- d_printf("************************ System Calls ****************************\n");
- d_printf("opendir_count: %u\n", profile_p->syscall_opendir_count);
- d_printf("opendir_time: %u\n", profile_p->syscall_opendir_time);
- d_printf("readdir_count: %u\n", profile_p->syscall_readdir_count);
- d_printf("readdir_time: %u\n", profile_p->syscall_readdir_time);
- d_printf("mkdir_count: %u\n", profile_p->syscall_mkdir_count);
- d_printf("mkdir_time: %u\n", profile_p->syscall_mkdir_time);
- d_printf("rmdir_count: %u\n", profile_p->syscall_rmdir_count);
- d_printf("rmdir_time: %u\n", profile_p->syscall_rmdir_time);
- d_printf("closedir_count: %u\n", profile_p->syscall_closedir_count);
- d_printf("closedir_time: %u\n", profile_p->syscall_closedir_time);
- d_printf("open_count: %u\n", profile_p->syscall_open_count);
- d_printf("open_time: %u\n", profile_p->syscall_open_time);
- d_printf("close_count: %u\n", profile_p->syscall_close_count);
- d_printf("close_time: %u\n", profile_p->syscall_close_time);
- d_printf("read_count: %u\n", profile_p->syscall_read_count);
- d_printf("read_time: %u\n", profile_p->syscall_read_time);
- d_printf("read_bytes: %u\n", profile_p->syscall_read_bytes);
- d_printf("write_count: %u\n", profile_p->syscall_write_count);
- d_printf("write_time: %u\n", profile_p->syscall_write_time);
- d_printf("write_bytes: %u\n", profile_p->syscall_write_bytes);
- d_printf("pread_count: %u\n", profile_p->syscall_pread_count);
- d_printf("pread_time: %u\n", profile_p->syscall_pread_time);
- d_printf("pread_bytes: %u\n", profile_p->syscall_pread_bytes);
- d_printf("pwrite_count: %u\n", profile_p->syscall_pwrite_count);
- d_printf("pwrite_time: %u\n", profile_p->syscall_pwrite_time);
- d_printf("pwrite_bytes: %u\n", profile_p->syscall_pwrite_bytes);
-#ifdef WITH_SENDFILE
- d_printf("sendfile_count: %u\n", profile_p->syscall_sendfile_count);
- d_printf("sendfile_time: %u\n", profile_p->syscall_sendfile_time);
- d_printf("sendfile_bytes: %u\n", profile_p->syscall_sendfile_bytes);
-#endif
- d_printf("lseek_count: %u\n", profile_p->syscall_lseek_count);
- d_printf("lseek_time: %u\n", profile_p->syscall_lseek_time);
- d_printf("rename_count: %u\n", profile_p->syscall_rename_count);
- d_printf("rename_time: %u\n", profile_p->syscall_rename_time);
- d_printf("fsync_count: %u\n", profile_p->syscall_fsync_count);
- d_printf("fsync_time: %u\n", profile_p->syscall_fsync_time);
- d_printf("stat_count: %u\n", profile_p->syscall_stat_count);
- d_printf("stat_time: %u\n", profile_p->syscall_stat_time);
- d_printf("fstat_count: %u\n", profile_p->syscall_fstat_count);
- d_printf("fstat_time: %u\n", profile_p->syscall_fstat_time);
- d_printf("lstat_count: %u\n", profile_p->syscall_lstat_count);
- d_printf("lstat_time: %u\n", profile_p->syscall_lstat_time);
- d_printf("unlink_count: %u\n", profile_p->syscall_unlink_count);
- d_printf("unlink_time: %u\n", profile_p->syscall_unlink_time);
- d_printf("chmod_count: %u\n", profile_p->syscall_chmod_count);
- d_printf("chmod_time: %u\n", profile_p->syscall_chmod_time);
- d_printf("fchmod_count: %u\n", profile_p->syscall_fchmod_count);
- d_printf("fchmod_time: %u\n", profile_p->syscall_fchmod_time);
- d_printf("chown_count: %u\n", profile_p->syscall_chown_count);
- d_printf("chown_time: %u\n", profile_p->syscall_chown_time);
- d_printf("fchown_count: %u\n", profile_p->syscall_fchown_count);
- d_printf("fchown_time: %u\n", profile_p->syscall_fchown_time);
- d_printf("chdir_count: %u\n", profile_p->syscall_chdir_count);
- d_printf("chdir_time: %u\n", profile_p->syscall_chdir_time);
- d_printf("getwd_count: %u\n", profile_p->syscall_getwd_count);
- d_printf("getwd_time: %u\n", profile_p->syscall_getwd_time);
- d_printf("utime_count: %u\n", profile_p->syscall_utime_count);
- d_printf("utime_time: %u\n", profile_p->syscall_utime_time);
- d_printf("ftruncate_count: %u\n", profile_p->syscall_ftruncate_count);
- d_printf("ftruncate_time: %u\n", profile_p->syscall_ftruncate_time);
- d_printf("fcntl_lock_count: %u\n", profile_p->syscall_fcntl_lock_count);
- d_printf("fcntl_lock_time: %u\n", profile_p->syscall_fcntl_lock_time);
- d_printf("readlink_count: %u\n", profile_p->syscall_readlink_count);
- d_printf("readlink_time: %u\n", profile_p->syscall_readlink_time);
- d_printf("symlink_count: %u\n", profile_p->syscall_symlink_count);
- d_printf("symlink_time: %u\n", profile_p->syscall_symlink_time);
- d_printf("************************ Statcache *******************************\n");
- d_printf("lookups: %u\n", profile_p->statcache_lookups);
- d_printf("misses: %u\n", profile_p->statcache_misses);
- d_printf("hits: %u\n", profile_p->statcache_hits);
- d_printf("************************ Writecache ******************************\n");
- d_printf("read_hits: %u\n", profile_p->writecache_read_hits);
- d_printf("abutted_writes: %u\n", profile_p->writecache_abutted_writes);
- d_printf("total_writes: %u\n", profile_p->writecache_total_writes);
- d_printf("non_oplock_writes: %u\n", profile_p->writecache_non_oplock_writes);
- d_printf("direct_writes: %u\n", profile_p->writecache_direct_writes);
- d_printf("init_writes: %u\n", profile_p->writecache_init_writes);
- d_printf("flushed_writes[SEEK]: %u\n", profile_p->writecache_flushed_writes[SEEK_FLUSH]);
- d_printf("flushed_writes[READ]: %u\n", profile_p->writecache_flushed_writes[READ_FLUSH]);
- d_printf("flushed_writes[WRITE]: %u\n", profile_p->writecache_flushed_writes[WRITE_FLUSH]);
- d_printf("flushed_writes[READRAW]: %u\n", profile_p->writecache_flushed_writes[READRAW_FLUSH]);
- d_printf("flushed_writes[OPLOCK_RELEASE]: %u\n", profile_p->writecache_flushed_writes[OPLOCK_RELEASE_FLUSH]);
- d_printf("flushed_writes[CLOSE]: %u\n", profile_p->writecache_flushed_writes[CLOSE_FLUSH]);
- d_printf("flushed_writes[SYNC]: %u\n", profile_p->writecache_flushed_writes[SYNC_FLUSH]);
- d_printf("flushed_writes[SIZECHANGE]: %u\n", profile_p->writecache_flushed_writes[SIZECHANGE_FLUSH]);
- d_printf("num_perfect_writes: %u\n", profile_p->writecache_num_perfect_writes);
- d_printf("num_write_caches: %u\n", profile_p->writecache_num_write_caches);
- d_printf("allocated_write_caches: %u\n", profile_p->writecache_allocated_write_caches);
- d_printf("************************ SMB Calls *******************************\n");
- d_printf("mkdir_count: %u\n", profile_p->SMBmkdir_count);
- d_printf("mkdir_time: %u\n", profile_p->SMBmkdir_time);
- d_printf("rmdir_count: %u\n", profile_p->SMBrmdir_count);
- d_printf("rmdir_time: %u\n", profile_p->SMBrmdir_time);
- d_printf("open_count: %u\n", profile_p->SMBopen_count);
- d_printf("open_time: %u\n", profile_p->SMBopen_time);
- d_printf("create_count: %u\n", profile_p->SMBcreate_count);
- d_printf("create_time: %u\n", profile_p->SMBcreate_time);
- d_printf("close_count: %u\n", profile_p->SMBclose_count);
- d_printf("close_time: %u\n", profile_p->SMBclose_time);
- d_printf("flush_count: %u\n", profile_p->SMBflush_count);
- d_printf("flush_time: %u\n", profile_p->SMBflush_time);
- d_printf("unlink_count: %u\n", profile_p->SMBunlink_count);
- d_printf("unlink_time: %u\n", profile_p->SMBunlink_time);
- d_printf("mv_count: %u\n", profile_p->SMBmv_count);
- d_printf("mv_time: %u\n", profile_p->SMBmv_time);
- d_printf("getatr_count: %u\n", profile_p->SMBgetatr_count);
- d_printf("getatr_time: %u\n", profile_p->SMBgetatr_time);
- d_printf("setatr_count: %u\n", profile_p->SMBsetatr_count);
- d_printf("setatr_time: %u\n", profile_p->SMBsetatr_time);
- d_printf("read_count: %u\n", profile_p->SMBread_count);
- d_printf("read_time: %u\n", profile_p->SMBread_time);
- d_printf("write_count: %u\n", profile_p->SMBwrite_count);
- d_printf("write_time: %u\n", profile_p->SMBwrite_time);
- d_printf("lock_count: %u\n", profile_p->SMBlock_count);
- d_printf("lock_time: %u\n", profile_p->SMBlock_time);
- d_printf("unlock_count: %u\n", profile_p->SMBunlock_count);
- d_printf("unlock_time: %u\n", profile_p->SMBunlock_time);
- d_printf("ctemp_count: %u\n", profile_p->SMBctemp_count);
- d_printf("ctemp_time: %u\n", profile_p->SMBctemp_time);
- d_printf("mknew_count: %u\n", profile_p->SMBmknew_count);
- d_printf("mknew_time: %u\n", profile_p->SMBmknew_time);
- d_printf("chkpth_count: %u\n", profile_p->SMBchkpth_count);
- d_printf("chkpth_time: %u\n", profile_p->SMBchkpth_time);
- d_printf("exit_count: %u\n", profile_p->SMBexit_count);
- d_printf("exit_time: %u\n", profile_p->SMBexit_time);
- d_printf("lseek_count: %u\n", profile_p->SMBlseek_count);
- d_printf("lseek_time: %u\n", profile_p->SMBlseek_time);
- d_printf("lockread_count: %u\n", profile_p->SMBlockread_count);
- d_printf("lockread_time: %u\n", profile_p->SMBlockread_time);
- d_printf("writeunlock_count: %u\n", profile_p->SMBwriteunlock_count);
- d_printf("writeunlock_time: %u\n", profile_p->SMBwriteunlock_time);
- d_printf("readbraw_count: %u\n", profile_p->SMBreadbraw_count);
- d_printf("readbraw_time: %u\n", profile_p->SMBreadbraw_time);
- d_printf("readBmpx_count: %u\n", profile_p->SMBreadBmpx_count);
- d_printf("readBmpx_time: %u\n", profile_p->SMBreadBmpx_time);
- d_printf("readBs_count: %u\n", profile_p->SMBreadBs_count);
- d_printf("readBs_time: %u\n", profile_p->SMBreadBs_time);
- d_printf("writebraw_count: %u\n", profile_p->SMBwritebraw_count);
- d_printf("writebraw_time: %u\n", profile_p->SMBwritebraw_time);
- d_printf("writeBmpx_count: %u\n", profile_p->SMBwriteBmpx_count);
- d_printf("writeBmpx_time: %u\n", profile_p->SMBwriteBmpx_time);
- d_printf("writeBs_count: %u\n", profile_p->SMBwriteBs_count);
- d_printf("writeBs_time: %u\n", profile_p->SMBwriteBs_time);
- d_printf("writec_count: %u\n", profile_p->SMBwritec_count);
- d_printf("writec_time: %u\n", profile_p->SMBwritec_time);
- d_printf("setattrE_count: %u\n", profile_p->SMBsetattrE_count);
- d_printf("setattrE_time: %u\n", profile_p->SMBsetattrE_time);
- d_printf("getattrE_count: %u\n", profile_p->SMBgetattrE_count);
- d_printf("getattrE_time: %u\n", profile_p->SMBgetattrE_time);
- d_printf("lockingX_count: %u\n", profile_p->SMBlockingX_count);
- d_printf("lockingX_time: %u\n", profile_p->SMBlockingX_time);
- d_printf("trans_count: %u\n", profile_p->SMBtrans_count);
- d_printf("trans_time: %u\n", profile_p->SMBtrans_time);
- d_printf("transs_count: %u\n", profile_p->SMBtranss_count);
- d_printf("transs_time: %u\n", profile_p->SMBtranss_time);
- d_printf("ioctl_count: %u\n", profile_p->SMBioctl_count);
- d_printf("ioctl_time: %u\n", profile_p->SMBioctl_time);
- d_printf("ioctls_count: %u\n", profile_p->SMBioctls_count);
- d_printf("ioctls_time: %u\n", profile_p->SMBioctls_time);
- d_printf("copy_count: %u\n", profile_p->SMBcopy_count);
- d_printf("copy_time: %u\n", profile_p->SMBcopy_time);
- d_printf("move_count: %u\n", profile_p->SMBmove_count);
- d_printf("move_time: %u\n", profile_p->SMBmove_time);
- d_printf("echo_count: %u\n", profile_p->SMBecho_count);
- d_printf("echo_time: %u\n", profile_p->SMBecho_time);
- d_printf("writeclose_count: %u\n", profile_p->SMBwriteclose_count);
- d_printf("writeclose_time: %u\n", profile_p->SMBwriteclose_time);
- d_printf("openX_count: %u\n", profile_p->SMBopenX_count);
- d_printf("openX_time: %u\n", profile_p->SMBopenX_time);
- d_printf("readX_count: %u\n", profile_p->SMBreadX_count);
- d_printf("readX_time: %u\n", profile_p->SMBreadX_time);
- d_printf("writeX_count: %u\n", profile_p->SMBwriteX_count);
- d_printf("writeX_time: %u\n", profile_p->SMBwriteX_time);
- d_printf("trans2_count: %u\n", profile_p->SMBtrans2_count);
- d_printf("trans2_time: %u\n", profile_p->SMBtrans2_time);
- d_printf("transs2_count: %u\n", profile_p->SMBtranss2_count);
- d_printf("transs2_time: %u\n", profile_p->SMBtranss2_time);
- d_printf("findclose_count: %u\n", profile_p->SMBfindclose_count);
- d_printf("findclose_time: %u\n", profile_p->SMBfindclose_time);
- d_printf("findnclose_count: %u\n", profile_p->SMBfindnclose_count);
- d_printf("findnclose_time: %u\n", profile_p->SMBfindnclose_time);
- d_printf("tcon_count: %u\n", profile_p->SMBtcon_count);
- d_printf("tcon_time: %u\n", profile_p->SMBtcon_time);
- d_printf("tdis_count: %u\n", profile_p->SMBtdis_count);
- d_printf("tdis_time: %u\n", profile_p->SMBtdis_time);
- d_printf("negprot_count: %u\n", profile_p->SMBnegprot_count);
- d_printf("negprot_time: %u\n", profile_p->SMBnegprot_time);
- d_printf("sesssetupX_count: %u\n", profile_p->SMBsesssetupX_count);
- d_printf("sesssetupX_time: %u\n", profile_p->SMBsesssetupX_time);
- d_printf("ulogoffX_count: %u\n", profile_p->SMBulogoffX_count);
- d_printf("ulogoffX_time: %u\n", profile_p->SMBulogoffX_time);
- d_printf("tconX_count: %u\n", profile_p->SMBtconX_count);
- d_printf("tconX_time: %u\n", profile_p->SMBtconX_time);
- d_printf("dskattr_count: %u\n", profile_p->SMBdskattr_count);
- d_printf("dskattr_time: %u\n", profile_p->SMBdskattr_time);
- d_printf("search_count: %u\n", profile_p->SMBsearch_count);
- d_printf("search_time: %u\n", profile_p->SMBsearch_time);
- d_printf("ffirst_count: %u\n", profile_p->SMBffirst_count);
- d_printf("ffirst_time: %u\n", profile_p->SMBffirst_time);
- d_printf("funique_count: %u\n", profile_p->SMBfunique_count);
- d_printf("funique_time: %u\n", profile_p->SMBfunique_time);
- d_printf("fclose_count: %u\n", profile_p->SMBfclose_count);
- d_printf("fclose_time: %u\n", profile_p->SMBfclose_time);
- d_printf("nttrans_count: %u\n", profile_p->SMBnttrans_count);
- d_printf("nttrans_time: %u\n", profile_p->SMBnttrans_time);
- d_printf("nttranss_count: %u\n", profile_p->SMBnttranss_count);
- d_printf("nttranss_time: %u\n", profile_p->SMBnttranss_time);
- d_printf("ntcreateX_count: %u\n", profile_p->SMBntcreateX_count);
- d_printf("ntcreateX_time: %u\n", profile_p->SMBntcreateX_time);
- d_printf("ntcancel_count: %u\n", profile_p->SMBntcancel_count);
- d_printf("ntcancel_time: %u\n", profile_p->SMBntcancel_time);
- d_printf("splopen_count: %u\n", profile_p->SMBsplopen_count);
- d_printf("splopen_time: %u\n", profile_p->SMBsplopen_time);
- d_printf("splwr_count: %u\n", profile_p->SMBsplwr_count);
- d_printf("splwr_time: %u\n", profile_p->SMBsplwr_time);
- d_printf("splclose_count: %u\n", profile_p->SMBsplclose_count);
- d_printf("splclose_time: %u\n", profile_p->SMBsplclose_time);
- d_printf("splretq_count: %u\n", profile_p->SMBsplretq_count);
- d_printf("splretq_time: %u\n", profile_p->SMBsplretq_time);
- d_printf("sends_count: %u\n", profile_p->SMBsends_count);
- d_printf("sends_time: %u\n", profile_p->SMBsends_time);
- d_printf("sendb_count: %u\n", profile_p->SMBsendb_count);
- d_printf("sendb_time: %u\n", profile_p->SMBsendb_time);
- d_printf("fwdname_count: %u\n", profile_p->SMBfwdname_count);
- d_printf("fwdname_time: %u\n", profile_p->SMBfwdname_time);
- d_printf("cancelf_count: %u\n", profile_p->SMBcancelf_count);
- d_printf("cancelf_time: %u\n", profile_p->SMBcancelf_time);
- d_printf("getmac_count: %u\n", profile_p->SMBgetmac_count);
- d_printf("getmac_time: %u\n", profile_p->SMBgetmac_time);
- d_printf("sendstrt_count: %u\n", profile_p->SMBsendstrt_count);
- d_printf("sendstrt_time: %u\n", profile_p->SMBsendstrt_time);
- d_printf("sendend_count: %u\n", profile_p->SMBsendend_count);
- d_printf("sendend_time: %u\n", profile_p->SMBsendend_time);
- d_printf("sendtxt_count: %u\n", profile_p->SMBsendtxt_count);
- d_printf("sendtxt_time: %u\n", profile_p->SMBsendtxt_time);
- d_printf("invalid_count: %u\n", profile_p->SMBinvalid_count);
- d_printf("invalid_time: %u\n", profile_p->SMBinvalid_time);
- d_printf("************************ Pathworks Calls *************************\n");
- d_printf("setdir_count: %u\n", profile_p->pathworks_setdir_count);
- d_printf("setdir_time: %u\n", profile_p->pathworks_setdir_time);
- d_printf("************************ Trans2 Calls ****************************\n");
- d_printf("open_count: %u\n", profile_p->Trans2_open_count);
- d_printf("open_time: %u\n", profile_p->Trans2_open_time);
- d_printf("findfirst_count: %u\n", profile_p->Trans2_findfirst_count);
- d_printf("findfirst_time: %u\n", profile_p->Trans2_findfirst_time);
- d_printf("findnext_count: %u\n", profile_p->Trans2_findnext_count);
- d_printf("findnext_time: %u\n", profile_p->Trans2_findnext_time);
- d_printf("qfsinfo_count: %u\n", profile_p->Trans2_qfsinfo_count);
- d_printf("qfsinfo_time: %u\n", profile_p->Trans2_qfsinfo_time);
- d_printf("setfsinfo_count: %u\n", profile_p->Trans2_setfsinfo_count);
- d_printf("setfsinfo_time: %u\n", profile_p->Trans2_setfsinfo_time);
- d_printf("qpathinfo_count: %u\n", profile_p->Trans2_qpathinfo_count);
- d_printf("qpathinfo_time: %u\n", profile_p->Trans2_qpathinfo_time);
- d_printf("setpathinfo_count: %u\n", profile_p->Trans2_setpathinfo_count);
- d_printf("setpathinfo_time: %u\n", profile_p->Trans2_setpathinfo_time);
- d_printf("qfileinfo_count: %u\n", profile_p->Trans2_qfileinfo_count);
- d_printf("qfileinfo_time: %u\n", profile_p->Trans2_qfileinfo_time);
- d_printf("setfileinfo_count: %u\n", profile_p->Trans2_setfileinfo_count);
- d_printf("setfileinfo_time: %u\n", profile_p->Trans2_setfileinfo_time);
- d_printf("fsctl_count: %u\n", profile_p->Trans2_fsctl_count);
- d_printf("fsctl_time: %u\n", profile_p->Trans2_fsctl_time);
- d_printf("ioctl_count: %u\n", profile_p->Trans2_ioctl_count);
- d_printf("ioctl_time: %u\n", profile_p->Trans2_ioctl_time);
- d_printf("findnotifyfirst_count: %u\n", profile_p->Trans2_findnotifyfirst_count);
- d_printf("findnotifyfirst_time: %u\n", profile_p->Trans2_findnotifyfirst_time);
- d_printf("findnotifynext_count: %u\n", profile_p->Trans2_findnotifynext_count);
- d_printf("findnotifynext_time: %u\n", profile_p->Trans2_findnotifynext_time);
- d_printf("mkdir_count: %u\n", profile_p->Trans2_mkdir_count);
- d_printf("mkdir_time: %u\n", profile_p->Trans2_mkdir_time);
- d_printf("session_setup_count: %u\n", profile_p->Trans2_session_setup_count);
- d_printf("session_setup_time: %u\n", profile_p->Trans2_session_setup_time);
- d_printf("get_dfs_referral_count: %u\n", profile_p->Trans2_get_dfs_referral_count);
- d_printf("get_dfs_referral_time: %u\n", profile_p->Trans2_get_dfs_referral_time);
- d_printf("report_dfs_inconsistancy_count: %u\n", profile_p->Trans2_report_dfs_inconsistancy_count);
- d_printf("report_dfs_inconsistancy_time: %u\n", profile_p->Trans2_report_dfs_inconsistancy_time);
- d_printf("************************ NT Transact Calls ***********************\n");
- d_printf("create_count: %u\n", profile_p->NT_transact_create_count);
- d_printf("create_time: %u\n", profile_p->NT_transact_create_time);
- d_printf("ioctl_count: %u\n", profile_p->NT_transact_ioctl_count);
- d_printf("ioctl_time: %u\n", profile_p->NT_transact_ioctl_time);
- d_printf("set_security_desc_count: %u\n", profile_p->NT_transact_set_security_desc_count);
- d_printf("set_security_desc_time: %u\n", profile_p->NT_transact_set_security_desc_time);
- d_printf("notify_change_count: %u\n", profile_p->NT_transact_notify_change_count);
- d_printf("notify_change_time: %u\n", profile_p->NT_transact_notify_change_time);
- d_printf("rename_count: %u\n", profile_p->NT_transact_rename_count);
- d_printf("rename_time: %u\n", profile_p->NT_transact_rename_time);
- d_printf("query_security_desc_count: %u\n", profile_p->NT_transact_query_security_desc_count);
- d_printf("query_security_desc_time: %u\n", profile_p->NT_transact_query_security_desc_time);
- d_printf("************************ ACL Calls *******************************\n");
- d_printf("get_nt_acl_count: %u\n", profile_p->get_nt_acl_count);
- d_printf("get_nt_acl_time: %u\n", profile_p->get_nt_acl_time);
- d_printf("fget_nt_acl_count: %u\n", profile_p->fget_nt_acl_count);
- d_printf("fget_nt_acl_time: %u\n", profile_p->fget_nt_acl_time);
- d_printf("set_nt_acl_count: %u\n", profile_p->set_nt_acl_count);
- d_printf("set_nt_acl_time: %u\n", profile_p->set_nt_acl_time);
- d_printf("fset_nt_acl_count: %u\n", profile_p->fset_nt_acl_count);
- d_printf("fset_nt_acl_time: %u\n", profile_p->fset_nt_acl_time);
- d_printf("chmod_acl_count: %u\n", profile_p->chmod_acl_count);
- d_printf("chmod_acl_time: %u\n", profile_p->chmod_acl_time);
- d_printf("fchmod_acl_count: %u\n", profile_p->fchmod_acl_count);
- d_printf("fchmod_acl_time: %u\n", profile_p->fchmod_acl_time);
- d_printf("************************ NMBD Calls ****************************\n");
- d_printf("name_release_count: %u\n", profile_p->name_release_count);
- d_printf("name_release_time: %u\n", profile_p->name_release_time);
- d_printf("name_refresh_count: %u\n", profile_p->name_refresh_count);
- d_printf("name_refresh_time: %u\n", profile_p->name_refresh_time);
- d_printf("name_registration_count: %u\n", profile_p->name_registration_count);
- d_printf("name_registration_time: %u\n", profile_p->name_registration_time);
- d_printf("node_status_count: %u\n", profile_p->node_status_count);
- d_printf("node_status_time: %u\n", profile_p->node_status_time);
- d_printf("name_query_count: %u\n", profile_p->name_query_count);
- d_printf("name_query_time: %u\n", profile_p->name_query_time);
- d_printf("host_announce_count: %u\n", profile_p->host_announce_count);
- d_printf("host_announce_time: %u\n", profile_p->host_announce_time);
- d_printf("workgroup_announce_count: %u\n", profile_p->workgroup_announce_count);
- d_printf("workgroup_announce_time: %u\n", profile_p->workgroup_announce_time);
- d_printf("local_master_announce_count: %u\n", profile_p->local_master_announce_count);
- d_printf("local_master_announce_time: %u\n", profile_p->local_master_announce_time);
- d_printf("master_browser_announce_count: %u\n", profile_p->master_browser_announce_count);
- d_printf("master_browser_announce_time: %u\n", profile_p->master_browser_announce_time);
- d_printf("lm_host_announce_count: %u\n", profile_p->lm_host_announce_count);
- d_printf("lm_host_announce_time: %u\n", profile_p->lm_host_announce_time);
- d_printf("get_backup_list_count: %u\n", profile_p->get_backup_list_count);
- d_printf("get_backup_list_time: %u\n", profile_p->get_backup_list_time);
- d_printf("reset_browser_count: %u\n", profile_p->reset_browser_count);
- d_printf("reset_browser_time: %u\n", profile_p->reset_browser_time);
- d_printf("announce_request_count: %u\n", profile_p->announce_request_count);
- d_printf("announce_request_time: %u\n", profile_p->announce_request_time);
- d_printf("lm_announce_request_count: %u\n", profile_p->lm_announce_request_count);
- d_printf("lm_announce_request_time: %u\n", profile_p->lm_announce_request_time);
- d_printf("domain_logon_count: %u\n", profile_p->domain_logon_count);
- d_printf("domain_logon_time: %u\n", profile_p->domain_logon_time);
- d_printf("sync_browse_lists_count: %u\n", profile_p->sync_browse_lists_count);
- d_printf("sync_browse_lists_time: %u\n", profile_p->sync_browse_lists_time);
- d_printf("run_elections_count: %u\n", profile_p->run_elections_count);
- d_printf("run_elections_time: %u\n", profile_p->run_elections_time);
- d_printf("election_count: %u\n", profile_p->election_count);
- d_printf("election_time: %u\n", profile_p->election_time);
-#else /* WITH_PROFILE */
- fprintf(stderr, "Profile data unavailable\n");
-#endif /* WITH_PROFILE */
-
- return 0;
-}
-
-
static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
{
struct connections_data crec;
@@ -602,7 +246,7 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
int main(int argc, char *argv[])
{
int c;
- static int profile_only = 0;
+ int profile_only = 0;
TDB_CONTEXT *tdb;
BOOL show_processes, show_locks, show_shares;
poptContext pc;
@@ -614,9 +258,8 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
{"shares", 'S', POPT_ARG_NONE, &shares_only, 'S', "Show shares only" },
{"user", 'u', POPT_ARG_STRING, &username, 'u', "Switch to user" },
{"brief", 'b', POPT_ARG_NONE, &brief, 'b', "Be brief" },
-#ifdef WITH_PROFILE
- {"profile", 'P', POPT_ARG_NONE, &profile_only, 'P', "Do profiling" },
-#endif /* WITH_PROFILE */
+ {"profile", 'P', POPT_ARG_NONE, NULL, 'P', "Do profiling" },
+ {"profile-rates", 'R', POPT_ARG_NONE, NULL, 'R', "Show call rates" },
{"byterange", 'B', POPT_ARG_NONE, &show_brl, 'B', "Include byte range locks"},
{"numeric", 'n', POPT_ARG_NONE, &numeric_only, 'n', "Numeric uid/gid"},
POPT_COMMON_SAMBA
@@ -643,6 +286,9 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
case 'u':
Ucrit_addUid(nametouid(poptGetOptArg(pc)));
break;
+ case 'P':
+ case 'R':
+ profile_only = c;
}
}
@@ -663,11 +309,18 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
return (-1);
}
-
- if (profile_only) {
- return profile_dump();
+
+ switch (profile_only) {
+ case 'P':
+ /* Dump profile data */
+ return status_profile_dump(verbose);
+ case 'R':
+ /* Continuously display rate-converted data */
+ return status_profile_rates(verbose);
+ default:
+ break;
}
-
+
if ( show_processes ) {
tdb = tdb_open_log(lock_path("sessionid.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
if (!tdb) {
@@ -719,7 +372,7 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
exit(1);
}
- ret = share_mode_forall(print_share_mode);
+ ret = share_mode_forall(print_share_mode, NULL);
if (ret == 0) {
d_printf("No locked files\n");
diff --git a/source/web/diagnose.c b/source/web/diagnose.c
index d259717da0b..b53e139ca94 100644
--- a/source/web/diagnose.c
+++ b/source/web/diagnose.c
@@ -60,16 +60,16 @@ BOOL nmbd_running(void)
then closing it */
BOOL smbd_running(void)
{
- static struct cli_state cli;
+ struct cli_state *cli;
- if (!cli_initialise(&cli))
+ if ((cli = cli_initialise()) == NULL)
return False;
- if (!cli_connect(&cli, global_myname(), &loopback_ip)) {
- cli_shutdown(&cli);
+ if (!cli_connect(cli, global_myname(), &loopback_ip)) {
+ cli_shutdown(cli);
return False;
}
- cli_shutdown(&cli);
+ cli_shutdown(cli);
return True;
}
diff --git a/source/web/neg_lang.c b/source/web/neg_lang.c
index fb79f41f13c..207614655db 100644
--- a/source/web/neg_lang.c
+++ b/source/web/neg_lang.c
@@ -57,8 +57,8 @@ static int qsort_cmp_list(const void *x, const void *y) {
struct pri_list *a = (struct pri_list *)x;
struct pri_list *b = (struct pri_list *)y;
if (a->pri > b->pri) return -1;
- if (a->pri == b->pri) return 0;
- return 1;
+ if (a->pri < b->pri) return 1;
+ return 0;
}
/*
diff --git a/source/web/statuspage.c b/source/web/statuspage.c
index cb6fa911711..459b679d817 100644
--- a/source/web/statuspage.c
+++ b/source/web/statuspage.c
@@ -106,7 +106,10 @@ static char *tstring(time_t t)
return buf;
}
-static void print_share_mode(const struct share_mode_entry *e, const char *sharepath, const char *fname)
+static void print_share_mode(const struct share_mode_entry *e,
+ const char *sharepath,
+ const char *fname,
+ void *dummy)
{
char *utf8_fname;
int deny_mode;
@@ -434,7 +437,7 @@ void status_page(void)
printf("<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n", _("PID"), _("Sharing"), _("R/W"), _("Oplock"), _("File"), _("Date"));
locking_init(1);
- share_mode_forall(print_share_mode);
+ share_mode_forall(print_share_mode, NULL);
locking_end();
printf("</table>\n");