summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in30
-rw-r--r--source3/auth/auth_builtin.c12
-rw-r--r--source3/auth/auth_compat.c10
-rw-r--r--source3/auth/auth_domain.c12
-rw-r--r--source3/auth/auth_netlogond.c6
-rw-r--r--source3/auth/auth_ntlmssp.c2
-rw-r--r--source3/auth/auth_sam.c219
-rw-r--r--source3/auth/auth_script.c4
-rw-r--r--source3/auth/auth_server.c4
-rw-r--r--source3/auth/auth_unix.c4
-rw-r--r--source3/auth/auth_util.c64
-rw-r--r--source3/auth/auth_wbc.c4
-rw-r--r--source3/auth/auth_winbind.c4
-rw-r--r--source3/configure.in2
-rw-r--r--source3/groupdb/mapping.c3
-rw-r--r--source3/include/auth.h10
-rw-r--r--source3/include/proto.h38
-rw-r--r--source3/include/smb.h1
-rw-r--r--source3/lib/time.c12
-rw-r--r--source3/lib/util_seaccess.c40
-rw-r--r--source3/libnet/libnet_samsync_passdb.c15
-rw-r--r--source3/libsmb/cliconnect.c5
-rw-r--r--source3/libsmb/samlogon_cache.c6
-rw-r--r--source3/locking/locking.c3
-rw-r--r--source3/modules/vfs_acl_common.c127
-rw-r--r--source3/modules/vfs_acl_tdb.c3
-rw-r--r--source3/modules/vfs_acl_xattr.c2
-rw-r--r--source3/modules/vfs_cap.c3
-rw-r--r--source3/modules/vfs_scannedonly.c995
-rw-r--r--source3/modules/vfs_zfsacl.c10
-rw-r--r--source3/passdb/lookup_sid.c21
-rw-r--r--source3/passdb/passdb.c3
-rw-r--r--source3/passdb/pdb_compat.c10
-rw-r--r--source3/passdb/pdb_get_set.c141
-rw-r--r--source3/passdb/pdb_interface.c3
-rw-r--r--source3/passdb/pdb_ldap.c11
-rw-r--r--source3/passdb/util_unixsids.c26
-rw-r--r--source3/passdb/util_wellknown.c4
-rw-r--r--source3/printing/nt_printing.c4
-rw-r--r--source3/rpc_client/cli_netlogon.c7
-rw-r--r--source3/rpc_server/srv_lsa_nt.c3
-rw-r--r--source3/rpc_server/srv_netlog_nt.c4
-rw-r--r--source3/rpc_server/srv_samr_nt.c17
-rw-r--r--source3/rpc_server/srv_srvsvc_nt.c21
-rw-r--r--source3/smbd/chgpasswd.c87
-rw-r--r--source3/smbd/close.c11
-rw-r--r--source3/smbd/dir.c8
-rw-r--r--source3/smbd/file_access.c11
-rw-r--r--source3/smbd/globals.c1
-rw-r--r--source3/smbd/globals.h1
-rw-r--r--source3/smbd/lanman.c6
-rw-r--r--source3/smbd/password.c2
-rw-r--r--source3/smbd/posix_acls.c4
-rw-r--r--source3/smbd/reply.c8
-rw-r--r--source3/smbd/sesssetup.c12
-rw-r--r--source3/smbd/vfs.c21
-rw-r--r--source3/utils/net_groupmap.c9
-rw-r--r--source3/utils/net_rpc.c7
-rw-r--r--source3/utils/ntlm_auth.c72
-rw-r--r--source3/utils/pdbedit.c3
-rw-r--r--source3/winbindd/idmap_hash/idmap_hash.c3
-rw-r--r--source3/winbindd/idmap_tdb.c3
-rw-r--r--source3/winbindd/winbindd_ads.c3
-rw-r--r--source3/winbindd/winbindd_cache.c3
-rw-r--r--source3/winbindd/winbindd_ccache_access.c2
-rw-r--r--source3/winbindd/winbindd_cred_cache.c13
-rw-r--r--source3/winbindd/winbindd_creds.c12
-rw-r--r--source3/winbindd/winbindd_pam.c4
-rw-r--r--source3/winbindd/winbindd_rpc.c5
69 files changed, 1744 insertions, 492 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 1376f4c07a..f87cb88801 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -681,7 +681,7 @@ GROUPDB_OBJ = groupdb/mapping.o groupdb/mapping_tdb.o groupdb/mapping_ldb.o
PROFILE_OBJ = profile/profile.o
PROFILES_OBJ = utils/profiles.o \
- $(LIBSAMBA_OBJ) \
+ $(LIBSMB_ERR_OBJ) \
$(PARAM_OBJ) \
$(LIB_OBJ) $(LIB_DUMMY_OBJ) \
$(POPT_LIB_OBJ)
@@ -740,6 +740,7 @@ VFS_ONEFS_SHADOW_COPY_OBJ = modules/vfs_onefs_shadow_copy.o modules/onefs_shadow
PERFCOUNT_ONEFS_OBJ = modules/perfcount_onefs.o
PERFCOUNT_TEST_OBJ = modules/perfcount_test.o
VFS_DIRSORT_OBJ = modules/vfs_dirsort.o
+VFS_SCANNEDONLY_OBJ = modules/vfs_scannedonly.o
PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
@@ -860,7 +861,7 @@ SWAT_OBJ = $(SWAT_OBJ1) $(PARAM_OBJ) $(PRINTING_OBJ) $(PRINTBASE_OBJ) $(LIBSMB_O
STATUS_OBJ = utils/status.o utils/status_profile.o \
$(LOCKING_OBJ) $(PARAM_OBJ) \
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
- $(LIBSAMBA_OBJ) $(FNAME_UTIL_OBJ)
+ $(LIBSMB_ERR_OBJ) $(FNAME_UTIL_OBJ)
SMBCONTROL_OBJ = utils/smbcontrol.o $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
$(LIBSMB_ERR_OBJ) $(POPT_LIB_OBJ) $(PRINTBASE_OBJ)
@@ -875,7 +876,7 @@ SMBTREE_OBJ = utils/smbtree.o $(PARAM_OBJ) \
TESTPARM_OBJ = utils/testparm.o \
$(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) \
- $(LIBSAMBA_OBJ)
+ $(LIBSMB_ERR_OBJ)
TEST_LP_LOAD_OBJ = param/test_lp_load.o \
$(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
@@ -1038,7 +1039,7 @@ CIFS_UMOUNT_OBJ = ../client/umount.cifs.o ../client/mtab.o
CIFS_UPCALL_OBJ = ../client/cifs.upcall.o
NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(LIBNMB_OBJ) \
- $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(LIBSAMBA_OBJ)
+ $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(LIBSMB_ERR_OBJ)
SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/utable.o \
torture/denytest.o torture/mangle_test.o \
@@ -1053,7 +1054,7 @@ MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLI
$(LIB_NONSMBD_OBJ) \
$(LIBNDR_GEN_OBJ0)
-MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) $(KRBCLIENT_OBJ) \
+MSGTEST_OBJ = torture/msgtest.o $(PARAM_OBJ) $(LIBSMB_ERR_OBJ) $(LDB_OBJ) \
$(LIB_NONSMBD_OBJ) \
$(LIBNDR_GEN_OBJ0)
@@ -1070,7 +1071,7 @@ PDBTEST_OBJ = torture/pdbtest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
VFSTEST_OBJ = torture/cmd_vfs.o torture/vfstest.o $(SMBD_OBJ_BASE) $(READLINE_OBJ)
-SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(LIBSAMBA_OBJ)
+SMBICONV_OBJ = $(PARAM_OBJ) torture/smbiconv.o $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(LIBSMB_ERR_OBJ)
LOG2PCAP_OBJ = utils/log2pcaphex.o
@@ -1092,18 +1093,18 @@ SMBCQUOTAS_OBJ = utils/smbcquotas.o $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
EVTLOGADM_OBJ0 = utils/eventlogadm.o
EVTLOGADM_OBJ = $(EVTLOGADM_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
- $(LIBSAMBA_OBJ) \
+ $(LIBSMB_ERR_OBJ) \
registry/reg_eventlog.o $(LIB_EVENTLOG_OBJ) \
../librpc/gen_ndr/ndr_eventlog.o \
../librpc/gen_ndr/ndr_lsa.o
SHARESEC_OBJ0 = utils/sharesec.o
SHARESEC_OBJ = $(SHARESEC_OBJ0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
- $(LIBSAMBA_OBJ) \
+ $(LIBSMB_ERR_OBJ) \
$(POPT_LIB_OBJ)
TALLOCTORT_OBJ = @tallocdir@/testsuite.o @tallocdir@/testsuite_main.o \
- $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSAMBA_OBJ)
+ $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBSMB_ERR_OBJ)
REPLACETORT_OBJ = @libreplacedir@/test/testsuite.o \
@libreplacedir@/test/getifaddrs.o \
@@ -1119,8 +1120,7 @@ SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(LDB_OBJ) \
$(LIBNDR_GEN_OBJ0)
WINBIND_WINS_NSS_OBJ = ../nsswitch/wins.o $(PARAM_OBJ) \
- $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ) \
- $(LIBNDR_GEN_OBJ0) $(LDB_OBJ)
+ $(LIB_NONSMBD_OBJ) $(LIBSMB_ERR_OBJ) $(LIBNMB_OBJ)
PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \
pam_smbpass/pam_smb_acct.o pam_smbpass/support.o ../lib/util/asn1.o
@@ -1334,12 +1334,12 @@ RPC_OPEN_TCP_OBJ = torture/rpc_open_tcp.o \
DBWRAP_TOOL_OBJ = utils/dbwrap_tool.o \
$(PARAM_OBJ) \
$(LIB_NONSMBD_OBJ) \
- $(LIBSAMBA_OBJ)
+ $(LIBSMB_ERR_OBJ)
DBWRAP_TORTURE_OBJ = utils/dbwrap_torture.o \
$(PARAM_OBJ) \
$(LIB_NONSMBD_OBJ) \
- $(LIBSAMBA_OBJ) \
+ $(LIBSMB_ERR_OBJ) \
$(POPT_LIB_OBJ)
SPLIT_TOKENS_OBJ = utils/split_tokens.o \
@@ -2831,6 +2831,10 @@ bin/dirsort.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_DIRSORT_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_DIRSORT_OBJ)
+bin/scannedonly.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_SCANNEDONLY_OBJ)
+ @echo "Building plugin $@"
+ @$(SHLD_MODULE) $(VFS_SCANNEDONLY_OBJ)
+
#########################################################
## IdMap NSS plugins
diff --git a/source3/auth/auth_builtin.c b/source3/auth/auth_builtin.c
index 3741f29779..f8f048a6f2 100644
--- a/source3/auth/auth_builtin.c
+++ b/source3/auth/auth_builtin.c
@@ -34,8 +34,8 @@
static NTSTATUS check_guest_security(const struct auth_context *auth_context,
void *my_private_data,
TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+ const struct auth_usersupplied_info *user_info,
+ struct auth_serversupplied_info **server_info)
{
/* mark this as 'not for me' */
NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
@@ -77,8 +77,8 @@ static NTSTATUS auth_init_guest(struct auth_context *auth_context, const char *o
static NTSTATUS check_name_to_ntstatus_security(const struct auth_context *auth_context,
void *my_private_data,
TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+ const struct auth_usersupplied_info *user_info,
+ struct auth_serversupplied_info **server_info)
{
NTSTATUS nt_status;
fstring user;
@@ -130,8 +130,8 @@ static NTSTATUS auth_init_name_to_ntstatus(struct auth_context *auth_context, co
static NTSTATUS check_fixed_challenge_security(const struct auth_context *auth_context,
void *my_private_data,
TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+ const struct auth_usersupplied_info *user_info,
+ struct auth_serversupplied_info **server_info)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
diff --git a/source3/auth/auth_compat.c b/source3/auth/auth_compat.c
index 77a994828f..e90036f3ff 100644
--- a/source3/auth/auth_compat.c
+++ b/source3/auth/auth_compat.c
@@ -35,10 +35,12 @@ SMB hash
return True if the password is correct, False otherwise
****************************************************************************/
-NTSTATUS check_plaintext_password(const char *smb_name, DATA_BLOB plaintext_password, auth_serversupplied_info **server_info)
+NTSTATUS check_plaintext_password(const char *smb_name,
+ DATA_BLOB plaintext_password,
+ struct auth_serversupplied_info **server_info)
{
struct auth_context *plaintext_auth_context = NULL;
- auth_usersupplied_info *user_info = NULL;
+ struct auth_usersupplied_info *user_info = NULL;
uint8_t chal[8];
NTSTATUS nt_status;
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) {
@@ -72,9 +74,9 @@ static NTSTATUS pass_check_smb(struct auth_context *actx,
{
NTSTATUS nt_status;
- auth_serversupplied_info *server_info = NULL;
+ struct auth_serversupplied_info *server_info = NULL;
if (encrypted) {
- auth_usersupplied_info *user_info = NULL;
+ struct auth_usersupplied_info *user_info = NULL;
if (actx == NULL) {
return NT_STATUS_INTERNAL_ERROR;
}
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c
index c527360321..a07aa617c4 100644
--- a/source3/auth/auth_domain.c
+++ b/source3/auth/auth_domain.c
@@ -251,10 +251,10 @@ machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
************************************************************************/
static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
+ const struct auth_usersupplied_info *user_info,
const char *domain,
uchar chal[8],
- auth_serversupplied_info **server_info,
+ struct auth_serversupplied_info **server_info,
const char *dc_name,
struct sockaddr_storage *dc_ss)
@@ -372,8 +372,8 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
void *my_private_data,
TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+ const struct auth_usersupplied_info *user_info,
+ struct auth_serversupplied_info **server_info)
{
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
const char *domain = lp_workgroup();
@@ -441,8 +441,8 @@ static NTSTATUS auth_init_ntdomain(struct auth_context *auth_context, const char
static NTSTATUS check_trustdomain_security(const struct auth_context *auth_context,
void *my_private_data,
TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+ const struct auth_usersupplied_info *user_info,
+ struct auth_serversupplied_info **server_info)
{
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
unsigned char trust_md4_password[16];
diff --git a/source3/auth/auth_netlogond.c b/source3/auth/auth_netlogond.c
index ebfed83d41..bfd12281c4 100644
--- a/source3/auth/auth_netlogond.c
+++ b/source3/auth/auth_netlogond.c
@@ -27,7 +27,7 @@ static NTSTATUS netlogond_validate(TALLOC_CTX *mem_ctx,
const struct auth_context *auth_context,
const char *ncalrpc_sockname,
uint8_t schannel_key[16],
- const auth_usersupplied_info *user_info,
+ const struct auth_usersupplied_info *user_info,
struct netr_SamInfo3 **pinfo3,
NTSTATUS *schannel_bind_result)
{
@@ -153,8 +153,8 @@ static char *mymachinepw(TALLOC_CTX *mem_ctx)
static NTSTATUS check_netlogond_security(const struct auth_context *auth_context,
void *my_private_data,
TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+ const struct auth_usersupplied_info *user_info,
+ struct auth_serversupplied_info **server_info)
{
TALLOC_CTX *frame = talloc_stackframe();
struct netr_SamInfo3 *info3 = NULL;
diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c
index 4243a24ca7..88f0e69443 100644
--- a/source3/auth/auth_ntlmssp.c
+++ b/source3/auth/auth_ntlmssp.c
@@ -85,7 +85,7 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state,
{
AUTH_NTLMSSP_STATE *auth_ntlmssp_state =
(AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context;
- auth_usersupplied_info *user_info = NULL;
+ struct auth_usersupplied_info *user_info = NULL;
NTSTATUS nt_status;
bool username_was_mapped;
diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c
index f0500b3611..1dd8fc950e 100644
--- a/source3/auth/auth_sam.c
+++ b/source3/auth/auth_sam.c
@@ -33,21 +33,23 @@
static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
TALLOC_CTX *mem_ctx,
- struct samu *sampass,
- const auth_usersupplied_info *user_info,
+ const char *username,
+ uint32_t acct_ctrl,
+ const uint8_t *lm_pw,
+ const uint8_t *nt_pw,
+ const struct auth_usersupplied_info *user_info,
DATA_BLOB *user_sess_key,
DATA_BLOB *lm_sess_key)
{
- uint32 acct_ctrl;
- const uint8 *lm_pw, *nt_pw;
- struct samr_Password lm_hash, nt_hash, client_lm_hash, client_nt_hash;
- const char *username = pdb_get_username(sampass);
- bool got_lm = false, got_nt = false;
+ struct samr_Password _lm_hash, _nt_hash, _client_lm_hash, _client_nt_hash;
+ struct samr_Password *lm_hash = NULL;
+ struct samr_Password *nt_hash = NULL;
+ struct samr_Password *client_lm_hash = NULL;
+ struct samr_Password *client_nt_hash = NULL;
- *user_sess_key = data_blob(NULL, 0);
- *lm_sess_key = data_blob(NULL, 0);
+ *user_sess_key = data_blob_null;
+ *lm_sess_key = data_blob_null;
- acct_ctrl = pdb_get_acct_ctrl(sampass);
if (acct_ctrl & ACB_PWNOTREQ) {
if (lp_null_passwords()) {
DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", username));
@@ -58,34 +60,35 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
}
}
- lm_pw = pdb_get_lanman_passwd(sampass);
- nt_pw = pdb_get_nt_passwd(sampass);
if (lm_pw) {
- memcpy(lm_hash.hash, lm_pw, sizeof(lm_hash.hash));
+ memcpy(_lm_hash.hash, lm_pw, sizeof(_lm_hash.hash));
+ lm_hash = &_lm_hash;
}
if (nt_pw) {
- memcpy(nt_hash.hash, nt_pw, sizeof(nt_hash.hash));
+ memcpy(_nt_hash.hash, nt_pw, sizeof(_nt_hash.hash));
+ nt_hash = &_nt_hash;
}
- if (user_info->lm_interactive_pwd.data && sizeof(client_lm_hash.hash) == user_info->lm_interactive_pwd.length) {
- memcpy(client_lm_hash.hash, user_info->lm_interactive_pwd.data, sizeof(lm_hash.hash));
- got_lm = true;
+ if (user_info->lm_interactive_pwd.data && sizeof(_client_lm_hash.hash) == user_info->lm_interactive_pwd.length) {
+ memcpy(_client_lm_hash.hash, user_info->lm_interactive_pwd.data, sizeof(_lm_hash.hash));
+ client_lm_hash = &_client_lm_hash;
}
- if (user_info->nt_interactive_pwd.data && sizeof(client_nt_hash.hash) == user_info->nt_interactive_pwd.length) {
- memcpy(client_nt_hash.hash, user_info->nt_interactive_pwd.data, sizeof(nt_hash.hash));
- got_nt = true;
+ if (user_info->nt_interactive_pwd.data && sizeof(_client_nt_hash.hash) == user_info->nt_interactive_pwd.length) {
+ memcpy(_client_nt_hash.hash, user_info->nt_interactive_pwd.data, sizeof(_nt_hash.hash));
+ client_nt_hash = &_client_nt_hash;
}
- if (got_lm || got_nt) {
- *user_sess_key = data_blob(mem_ctx, 16);
+
+ if (client_lm_hash || client_nt_hash) {
+ *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);
if (!user_sess_key->data) {
return NT_STATUS_NO_MEMORY;
}
SMBsesskeygen_ntv1(nt_pw, user_sess_key->data);
return hash_password_check(mem_ctx, lp_lanman_auth(),
- got_lm ? &client_lm_hash : NULL,
- got_nt ? &client_nt_hash : NULL,
+ client_lm_hash,
+ client_nt_hash,
username,
- lm_pw ? &lm_hash: NULL,
- nt_pw ? &nt_hash : NULL);
+ lm_hash,
+ nt_hash);
} else {
return ntlm_password_check(mem_ctx, lp_lanman_auth(),
lp_ntlm_auth(),
@@ -95,8 +98,8 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
username,
user_info->smb_name,
user_info->client_domain,
- lm_pw ? &lm_hash: NULL,
- nt_pw ? &nt_hash : NULL,
+ lm_hash,
+ nt_hash,
user_sess_key, lm_sess_key);
}
}
@@ -165,7 +168,7 @@ static bool logon_hours_ok(struct samu *sampass)
static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,
struct samu *sampass,
- const auth_usersupplied_info *user_info)
+ const struct auth_usersupplied_info *user_info)
{
uint32 acct_ctrl = pdb_get_acct_ctrl(sampass);
char *workstation_list;
@@ -278,6 +281,75 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
+/**
+ * Check whether the given password is one of the last two
+ * password history entries. If so, the bad pwcount should
+ * not be incremented even thought the actual password check
+ * failed.
+ */
+static bool need_to_increment_bad_pw_count(
+ const struct auth_context *auth_context,
+ struct samu* sampass,
+ const struct auth_usersupplied_info *user_info)
+{
+ uint8_t i;
+ const uint8_t *pwhistory;
+ uint32_t pwhistory_len;
+ uint32_t policy_pwhistory_len;
+ uint32_t acct_ctrl;
+ const char *username;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
+ bool result = true;
+
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY,
+ &policy_pwhistory_len);
+ if (policy_pwhistory_len == 0) {
+ goto done;
+ }
+
+ pwhistory = pdb_get_pw_history(sampass, &pwhistory_len);
+ if (!pwhistory || pwhistory_len == 0) {
+ goto done;
+ }
+
+ acct_ctrl = pdb_get_acct_ctrl(sampass);
+ username = pdb_get_username(sampass);
+
+ for (i=1; i < MIN(MIN(3, policy_pwhistory_len), pwhistory_len); i++) {
+ static const uint8_t zero16[SALTED_MD5_HASH_LEN];
+ const uint8_t *salt;
+ const uint8_t *nt_pw;
+ NTSTATUS status;
+ DATA_BLOB user_sess_key = data_blob_null;
+ DATA_BLOB lm_sess_key = data_blob_null;
+
+ salt = &pwhistory[i*PW_HISTORY_ENTRY_LEN];
+ nt_pw = salt + PW_HISTORY_SALT_LEN;
+
+ if (memcmp(zero16, nt_pw, NT_HASH_LEN) == 0) {
+ /* skip zero password hash */
+ continue;
+ }
+
+ if (memcmp(zero16, salt, PW_HISTORY_SALT_LEN) != 0) {
+ /* skip nonzero salt (old format entry) */
+ continue;
+ }
+
+ status = sam_password_ok(auth_context, mem_ctx,
+ username, acct_ctrl, NULL, nt_pw,
+ user_info, &user_sess_key, &lm_sess_key);
+ if (NT_STATUS_IS_OK(status)) {
+ result = false;
+ break;
+ }
+ }
+
+done:
+ TALLOC_FREE(mem_ctx);
+ return result;
+}
+
/****************************************************************************
check if a username/password is OK assuming the password is a 24 byte
SMB hash supplied in the user_info structure
@@ -287,8 +359,8 @@ return an NT_STATUS constant.
static NTSTATUS check_sam_security(const struct auth_context *auth_context,
void *my_private_data,
TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+ const struct auth_usersupplied_info *user_info,
+ struct auth_serversupplied_info **server_info)
{
struct samu *sampass=NULL;
bool ret;
@@ -297,6 +369,10 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
DATA_BLOB user_sess_key = data_blob_null;
DATA_BLOB lm_sess_key = data_blob_null;
bool updated_autolock = False, updated_badpw = False;
+ uint32_t acct_ctrl;
+ const char *username;
+ const uint8_t *nt_pw;
+ const uint8_t *lm_pw;
if (!user_info || !auth_context) {
return NT_STATUS_UNSUCCESSFUL;
@@ -305,7 +381,8 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
/* the returned struct gets kept on the server_info, by means
of a steal further down */
- if ( !(sampass = samu_new( mem_ctx )) ) {
+ sampass = samu_new(mem_ctx);
+ if (sampass == NULL) {
return NT_STATUS_NO_MEMORY;
}
@@ -322,16 +399,22 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
return NT_STATUS_NO_SUCH_USER;
}
+ acct_ctrl = pdb_get_acct_ctrl(sampass);
+ username = pdb_get_username(sampass);
+ nt_pw = pdb_get_nt_passwd(sampass);
+ lm_pw = pdb_get_lanman_passwd(sampass);
+
/* see if autolock flag needs to be updated */
- if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL)
+ if (acct_ctrl & ACB_NORMAL)
pdb_update_autolock_flag(sampass, &updated_autolock);
/* Quit if the account was locked out. */
- if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) {
- DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", pdb_get_username(sampass)));
+ if (acct_ctrl & ACB_AUTOLOCK) {
+ DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", username));
return NT_STATUS_ACCOUNT_LOCKED_OUT;
}
- nt_status = sam_password_ok(auth_context, mem_ctx, sampass,
+ nt_status = sam_password_ok(auth_context, mem_ctx,
+ username, acct_ctrl, lm_pw, nt_pw,
user_info, &user_sess_key, &lm_sess_key);
/* Notify passdb backend of login success/failure. If not
@@ -340,10 +423,19 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
update_login_attempts_status = pdb_update_login_attempts(sampass, NT_STATUS_IS_OK(nt_status));
if (!NT_STATUS_IS_OK(nt_status)) {
+ bool increment_bad_pw_count = false;
+
if (NT_STATUS_EQUAL(nt_status,NT_STATUS_WRONG_PASSWORD) &&
- pdb_get_acct_ctrl(sampass) &ACB_NORMAL &&
+ acct_ctrl & ACB_NORMAL &&
NT_STATUS_IS_OK(update_login_attempts_status))
- {
+ {
+ increment_bad_pw_count =
+ need_to_increment_bad_pw_count(auth_context,
+ sampass,
+ user_info);
+ }
+
+ if (increment_bad_pw_count) {
pdb_increment_bad_password_count(sampass);
updated_badpw = True;
} else {
@@ -351,18 +443,21 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
&updated_badpw);
}
if (updated_autolock || updated_badpw){
+ NTSTATUS status;
+
become_root();
- if(!NT_STATUS_IS_OK(pdb_update_sam_account(sampass)))
- DEBUG(1, ("Failed to modify entry.\n"));
+ status = pdb_update_sam_account(sampass);
unbecome_root();
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Failed to modify entry: %s\n",
+ nt_errstr(status)));
+ }
}
- data_blob_free(&user_sess_key);
- data_blob_free(&lm_sess_key);
- TALLOC_FREE(sampass);
- return nt_status;
+ goto done;
}
- if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) &&
+ if ((acct_ctrl & ACB_NORMAL) &&
(pdb_get_bad_password_count(sampass) > 0)){
pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
@@ -370,30 +465,36 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
}
if (updated_autolock || updated_badpw){
+ NTSTATUS status;
+
become_root();
- if(!NT_STATUS_IS_OK(pdb_update_sam_account(sampass)))
- DEBUG(1, ("Failed to modify entry.\n"));
+ status = pdb_update_sam_account(sampass);
unbecome_root();
- }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Failed to modify entry: %s\n",
+ nt_errstr(status)));
+ }
+ }
nt_status = sam_account_ok(mem_ctx, sampass, user_info);
if (!NT_STATUS_IS_OK(nt_status)) {
- TALLOC_FREE(sampass);
- data_blob_free(&user_sess_key);
- data_blob_free(&lm_sess_key);
- return nt_status;
+ goto done;
}
become_root();
nt_status = make_server_info_sam(server_info, sampass);
unbecome_root();
+ /*
+ * sampass has been stolen to server_info.
+ * So NULL it out to prevent segfaults.
+ */
+ sampass = NULL;
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("check_sam_security: make_server_info_sam() failed with '%s'\n", nt_errstr(nt_status)));
- data_blob_free(&user_sess_key);
- data_blob_free(&lm_sess_key);
- return nt_status;
+ goto done;
}
(*server_info)->user_session_key =
@@ -408,6 +509,10 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
(*server_info)->nss_token |= user_info->was_mapped;
+done:
+ TALLOC_FREE(sampass);
+ data_blob_free(&user_sess_key);
+ data_blob_free(&lm_sess_key);
return nt_status;
}
@@ -431,8 +536,8 @@ Check SAM security (above) but with a few extra checks.
static NTSTATUS check_samstrict_security(const struct auth_context *auth_context,
void *my_private_data,
TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+ const struct auth_usersupplied_info *user_info,
+ struct auth_serversupplied_info **server_info)
{
bool is_local_name, is_my_domain;
diff --git a/source3/auth/auth_script.c b/source3/auth/auth_script.c
index 6cbace71e8..be1ae81501 100644
--- a/source3/auth/auth_script.c
+++ b/source3/auth/auth_script.c
@@ -40,8 +40,8 @@
static NTSTATUS script_check_user_credentials(const struct auth_context *auth_context,
void *my_private_data,
TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+ const struct auth_usersupplied_info *user_info,
+ struct auth_serversupplied_info **server_info)
{
const char *script = lp_parm_const_string( GLOBAL_SECTION_SNUM, "auth_script", "script", NULL);
char *secret_str;
diff --git a/source3/auth/auth_server.c b/source3/auth/auth_server.c
index 287b50b080..ec92787dce 100644
--- a/source3/auth/auth_server.c
+++ b/source3/auth/auth_server.c
@@ -270,8 +270,8 @@ static DATA_BLOB auth_get_challenge_server(const struct auth_context *auth_conte
static NTSTATUS check_smbserver_security(const struct auth_context *auth_context,
void *my_private_data,
TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+ const struct auth_usersupplied_info *user_info,
+ struct auth_serversupplied_info **server_info)
{
struct server_security_state *state = talloc_get_type_abort(
my_private_data, struct server_security_state);
diff --git a/source3/auth/auth_unix.c b/source3/auth/auth_unix.c
index 58c765226d..3e2df9a123 100644
--- a/source3/auth/auth_unix.c
+++ b/source3/auth/auth_unix.c
@@ -85,8 +85,8 @@ static bool update_smbpassword_file(const char *user, const char *password)
static NTSTATUS check_unix_security(const struct auth_context *auth_context,
void *my_private_data,
TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+ const struct auth_usersupplied_info *user_info,
+ struct auth_serversupplied_info **server_info)
{
NTSTATUS nt_status;
struct passwd *pass = NULL;
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 8167a80a4f..de552cf57e 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -33,7 +33,7 @@
auth_serversupplied_info struct.
****************************************************************************/
-static void sort_sid_array_for_smbd(auth_serversupplied_info *result,
+static void sort_sid_array_for_smbd(struct auth_serversupplied_info *result,
const DOM_SID *pgroup_sid)
{
unsigned int i;
@@ -107,7 +107,7 @@ static int _smb_create_user(const char *domain, const char *unix_username, const
Create an auth_usersupplied_data structure
****************************************************************************/
-static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
+static NTSTATUS make_user_info(struct auth_usersupplied_info **user_info,
const char *smb_name,
const char *internal_username,
const char *client_domain,
@@ -121,7 +121,7 @@ static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
- *user_info = SMB_MALLOC_P(auth_usersupplied_info);
+ *user_info = SMB_MALLOC_P(struct auth_usersupplied_info);
if (*user_info == NULL) {
DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
return NT_STATUS_NO_MEMORY;
@@ -188,7 +188,7 @@ static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
Create an auth_usersupplied_data structure after appropriate mapping.
****************************************************************************/
-NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
+NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info,
const char *smb_name,
const char *client_domain,
const char *wksta_name,
@@ -252,7 +252,7 @@ NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
Decrypt and encrypt the passwords.
****************************************************************************/
-bool make_user_info_netlogon_network(auth_usersupplied_info **user_info,
+bool make_user_info_netlogon_network(struct auth_usersupplied_info **user_info,
const char *smb_name,
const char *client_domain,
const char *wksta_name,
@@ -290,7 +290,7 @@ bool make_user_info_netlogon_network(auth_usersupplied_info **user_info,
Decrypt and encrypt the passwords.
****************************************************************************/
-bool make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
+bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_info,
const char *smb_name,
const char *client_domain,
const char *wksta_name,
@@ -402,7 +402,7 @@ bool make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
Create an auth_usersupplied_data structure
****************************************************************************/
-bool make_user_info_for_reply(auth_usersupplied_info **user_info,
+bool make_user_info_for_reply(struct auth_usersupplied_info **user_info,
const char *smb_name,
const char *client_domain,
const uint8 chal[8],
@@ -460,7 +460,7 @@ bool make_user_info_for_reply(auth_usersupplied_info **user_info,
Create an auth_usersupplied_data structure
****************************************************************************/
-NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
+NTSTATUS make_user_info_for_reply_enc(struct auth_usersupplied_info **user_info,
const char *smb_name,
const char *client_domain,
DATA_BLOB lm_resp, DATA_BLOB nt_resp)
@@ -478,7 +478,7 @@ NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
Create a guest user_info blob, for anonymous authenticaion.
****************************************************************************/
-bool make_user_info_guest(auth_usersupplied_info **user_info)
+bool make_user_info_guest(struct auth_usersupplied_info **user_info)
{
NTSTATUS nt_status;
@@ -494,7 +494,7 @@ bool make_user_info_guest(auth_usersupplied_info **user_info)
return NT_STATUS_IS_OK(nt_status) ? True : False;
}
-static int server_info_dtor(auth_serversupplied_info *server_info)
+static int server_info_dtor(struct auth_serversupplied_info *server_info)
{
TALLOC_FREE(server_info->sam_account);
ZERO_STRUCTP(server_info);
@@ -505,11 +505,11 @@ static int server_info_dtor(auth_serversupplied_info *server_info)
Make a server_info struct. Free with TALLOC_FREE().
***************************************************************************/
-static auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
+static struct auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
{
struct auth_serversupplied_info *result;
- result = TALLOC_ZERO_P(mem_ctx, auth_serversupplied_info);
+ result = TALLOC_ZERO_P(mem_ctx, struct auth_serversupplied_info);
if (result == NULL) {
DEBUG(0, ("talloc failed\n"));
return NULL;
@@ -562,12 +562,12 @@ static bool is_our_machine_account(const char *username)
Make (and fill) a user_info struct from a struct samu
***************************************************************************/
-NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
+NTSTATUS make_server_info_sam(struct auth_serversupplied_info **server_info,
struct samu *sampass)
{
struct passwd *pwd;
gid_t *gids;
- auth_serversupplied_info *result;
+ struct auth_serversupplied_info *result;
const char *username = pdb_get_username(sampass);
NTSTATUS status;
@@ -701,7 +701,7 @@ static NTSTATUS log_nt_token(NT_USER_TOKEN *token)
* server_info->sids (the info3/sam groups). Find the unix gids.
*/
-NTSTATUS create_local_token(auth_serversupplied_info *server_info)
+NTSTATUS create_local_token(struct auth_serversupplied_info *server_info)
{
NTSTATUS status;
size_t i;
@@ -1140,7 +1140,7 @@ bool user_in_group(const char *username, const char *groupname)
to a struct samu
***************************************************************************/
-NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
+NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
char *unix_username,
struct passwd *pwd)
{
@@ -1151,7 +1151,7 @@ NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
TALLOC_CTX *mem_ctx = NULL;
DOM_SID u_sid;
enum lsa_SidType type;
- auth_serversupplied_info *result;
+ struct auth_serversupplied_info *result;
if ( !(sampass = samu_new( NULL )) ) {
return NT_STATUS_NO_MEMORY;
@@ -1261,7 +1261,7 @@ NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
the guest gid, then create one.
***************************************************************************/
-static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
+static NTSTATUS make_new_server_info_guest(struct auth_serversupplied_info **server_info)
{
NTSTATUS status;
struct samu *sampass = NULL;
@@ -1274,8 +1274,7 @@ static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_inf
return NT_STATUS_NO_MEMORY;
}
- sid_copy(&guest_sid, get_global_sam_sid());
- sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
+ sid_compose(&guest_sid, get_global_sam_sid(), DOMAIN_USER_RID_GUEST);
become_root();
ret = pdb_getsampwsid(sampass, &guest_sid);
@@ -1355,9 +1354,9 @@ NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx,
struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
- const auth_serversupplied_info *src)
+ const struct auth_serversupplied_info *src)
{
- auth_serversupplied_info *dst;
+ struct auth_serversupplied_info *dst;
dst = make_server_info(mem_ctx);
if (dst == NULL) {
@@ -1433,7 +1432,7 @@ bool server_info_set_session_key(struct auth_serversupplied_info *info,
return (info->user_session_key.data != NULL);
}
-static auth_serversupplied_info *guest_info = NULL;
+static struct auth_serversupplied_info *guest_info = NULL;
bool init_guest_info(void)
{
@@ -1444,7 +1443,7 @@ bool init_guest_info(void)
}
NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
- auth_serversupplied_info **server_info)
+ struct auth_serversupplied_info **server_info)
{
*server_info = copy_serverinfo(mem_ctx, guest_info);
return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
@@ -1620,7 +1619,7 @@ struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
const char *sent_nt_username,
const char *domain,
- auth_serversupplied_info **server_info,
+ struct auth_serversupplied_info **server_info,
struct netr_SamInfo3 *info3)
{
char zeros[16];
@@ -1637,7 +1636,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
uid_t uid = (uid_t)-1;
gid_t gid = (gid_t)-1;
- auth_serversupplied_info *result;
+ struct auth_serversupplied_info *result;
/*
Here is where we should check the list of
@@ -1645,13 +1644,12 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
matches.
*/
- sid_copy(&user_sid, info3->base.domain_sid);
- if (!sid_append_rid(&user_sid, info3->base.rid)) {
+ if (!sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid)) {
return NT_STATUS_INVALID_PARAMETER;
}
- sid_copy(&group_sid, info3->base.domain_sid);
- if (!sid_append_rid(&group_sid, info3->base.primary_gid)) {
+ if (!sid_compose(&group_sid, info3->base.domain_sid,
+ info3->base.primary_gid)) {
return NT_STATUS_INVALID_PARAMETER;
}
@@ -1873,7 +1871,7 @@ NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
const char *sent_nt_username,
const char *domain,
const struct wbcAuthUserInfo *info,
- auth_serversupplied_info **server_info)
+ struct auth_serversupplied_info **server_info)
{
char zeros[16];
@@ -1890,7 +1888,7 @@ NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
uid_t uid = (uid_t)-1;
gid_t gid = (gid_t)-1;
- auth_serversupplied_info *result;
+ struct auth_serversupplied_info *result;
result = make_server_info(NULL);
if (result == NULL) {
@@ -2114,7 +2112,7 @@ NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
Free a user_info struct
***************************************************************************/
-void free_user_info(auth_usersupplied_info **user_info)
+void free_user_info(struct auth_usersupplied_info **user_info)
{
DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
if (*user_info != NULL) {
diff --git a/source3/auth/auth_wbc.c b/source3/auth/auth_wbc.c
index 580c8b550d..85b05efb36 100644
--- a/source3/auth/auth_wbc.c
+++ b/source3/auth/auth_wbc.c
@@ -47,8 +47,8 @@
static NTSTATUS check_wbc_security(const struct auth_context *auth_context,
void *my_private_data,
TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+ const struct auth_usersupplied_info *user_info,
+ struct auth_serversupplied_info **server_info)
{
NTSTATUS nt_status;
wbcErr wbc_status;
diff --git a/source3/auth/auth_winbind.c b/source3/auth/auth_winbind.c
index d1b00a3268..74723e6af4 100644
--- a/source3/auth/auth_winbind.c
+++ b/source3/auth/auth_winbind.c
@@ -30,8 +30,8 @@
static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
void *my_private_data,
TALLOC_CTX *mem_ctx,
- const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+ const struct auth_usersupplied_info *user_info,
+ struct auth_serversupplied_info **server_info)
{
NTSTATUS nt_status;
wbcErr wbc_status;
diff --git a/source3/configure.in b/source3/configure.in
index e3f53b45c2..d17cdac846 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -439,6 +439,7 @@ default_shared_modules="$default_shared_modules vfs_acl_tdb"
default_shared_modules="$default_shared_modules vfs_smb_traffic_analyzer"
default_shared_modules="$default_shared_modules vfs_preopen"
default_shared_modules="$default_shared_modules vfs_catia"
+default_shared_modules="$default_shared_modules vfs_scannedonly"
if test "x$developer" = xyes; then
default_static_modules="$default_static_modules rpc_rpcecho pdb_ads"
@@ -6552,6 +6553,7 @@ SMB_MODULE(vfs_smb_traffic_analyzer, \$(VFS_SMB_TRAFFIC_ANALYZER_OBJ), "bin/smb_
SMB_MODULE(vfs_onefs, \$(VFS_ONEFS), "bin/onefs.$SHLIBEXT", VFS)
SMB_MODULE(vfs_onefs_shadow_copy, \$(VFS_ONEFS_SHADOW_COPY), "bin/onefs_shadow_copy.$SHLIBEXT", VFS)
SMB_MODULE(vfs_dirsort, \$(VFS_DIRSORT_OBJ), "bin/dirsort.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_scannedonly, \$(VFS_SCANNEDONLY_OBJ), "bin/scannedonly.$SHLIBEXT", VFS)
SMB_SUBSYSTEM(VFS,smbd/vfs.o)
diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c
index 12d0bd365c..579486b874 100644
--- a/source3/groupdb/mapping.c
+++ b/source3/groupdb/mapping.c
@@ -519,8 +519,7 @@ NTSTATUS pdb_default_create_alias(struct pdb_methods *methods,
DEBUG(10, ("Creating alias %s with gid %u and rid %u\n",
name, (unsigned int)gid, (unsigned int)new_rid));
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, new_rid);
+ sid_compose(&sid, get_global_sam_sid(), new_rid);
map.gid = gid;
sid_copy(&map.sid, &sid);
diff --git a/source3/include/auth.h b/source3/include/auth.h
index 7d778b92d0..115143fb73 100644
--- a/source3/include/auth.h
+++ b/source3/include/auth.h
@@ -19,7 +19,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-typedef struct auth_usersupplied_info {
+struct auth_usersupplied_info {
DATA_BLOB lm_resp;
DATA_BLOB nt_resp;
DATA_BLOB lm_interactive_pwd;
@@ -38,9 +38,9 @@ typedef struct auth_usersupplied_info {
uint32 logon_parameters;
-} auth_usersupplied_info;
+};
-typedef struct auth_serversupplied_info {
+struct auth_serversupplied_info {
bool guest;
DOM_SID *sids; /* These SIDs are preliminary between
@@ -77,7 +77,7 @@ typedef struct auth_serversupplied_info {
* smb request. See set_current_user_info.
*/
char *sanitized_username;
-} auth_serversupplied_info;
+};
struct auth_context {
DATA_BLOB challenge;
@@ -110,7 +110,7 @@ typedef struct auth_methods
void *my_private_data,
TALLOC_CTX *mem_ctx,
const struct auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info);
+ struct auth_serversupplied_info **server_info);
/* If you are using this interface, then you are probably
* getting something wrong. This interface is only for
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 5b16120294..8e8b35cb5a 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -38,7 +38,9 @@ NTSTATUS auth_builtin_init(void);
/* The following definitions come from auth/auth_compat.c */
-NTSTATUS check_plaintext_password(const char *smb_name, DATA_BLOB plaintext_password, auth_serversupplied_info **server_info);
+NTSTATUS check_plaintext_password(const char *smb_name,
+ DATA_BLOB plaintext_password,
+ struct auth_serversupplied_info **server_info);
bool password_ok(struct auth_context *actx, bool global_encrypted,
const char *session_workgroup,
const char *smb_name, DATA_BLOB password_blob);
@@ -71,7 +73,7 @@ NTSTATUS auth_unix_init(void);
/* The following definitions come from auth/auth_util.c */
-NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
+NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info,
const char *smb_name,
const char *client_domain,
const char *wksta_name,
@@ -79,7 +81,7 @@ NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
DATA_BLOB *plaintext,
bool encrypted);
-bool make_user_info_netlogon_network(auth_usersupplied_info **user_info,
+bool make_user_info_netlogon_network(struct auth_usersupplied_info **user_info,
const char *smb_name,
const char *client_domain,
const char *wksta_name,
@@ -88,7 +90,7 @@ bool make_user_info_netlogon_network(auth_usersupplied_info **user_info,
int lm_pwd_len,
const uchar *nt_network_pwd,
int nt_pwd_len);
-bool make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
+bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_info,
const char *smb_name,
const char *client_domain,
const char *wksta_name,
@@ -97,19 +99,19 @@ bool make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
const uchar lm_interactive_pwd[16],
const uchar nt_interactive_pwd[16],
const uchar *dc_sess_key);
-bool make_user_info_for_reply(auth_usersupplied_info **user_info,
+bool make_user_info_for_reply(struct auth_usersupplied_info **user_info,
const char *smb_name,
const char *client_domain,
const uint8 chal[8],
DATA_BLOB plaintext_password);
-NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
+NTSTATUS make_user_info_for_reply_enc(struct auth_usersupplied_info **user_info,
const char *smb_name,
const char *client_domain,
DATA_BLOB lm_resp, DATA_BLOB nt_resp);
-bool make_user_info_guest(auth_usersupplied_info **user_info) ;
-NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
+bool make_user_info_guest(struct auth_usersupplied_info **user_info) ;
+NTSTATUS make_server_info_sam(struct auth_serversupplied_info **server_info,
struct samu *sampass);
-NTSTATUS create_local_token(auth_serversupplied_info *server_info);
+NTSTATUS create_local_token(struct auth_serversupplied_info *server_info);
NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
bool is_guest,
uid_t *uid, gid_t *gid,
@@ -117,7 +119,7 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
struct nt_user_token **token);
bool user_in_group_sid(const char *username, const DOM_SID *group_sid);
bool user_in_group(const char *username, const char *groupname);
-NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
+NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
char *unix_username,
struct passwd *pwd);
NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx,
@@ -125,26 +127,26 @@ NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx,
bool is_guest,
struct auth_serversupplied_info **presult);
struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
- const auth_serversupplied_info *src);
+ const struct auth_serversupplied_info *src);
bool init_guest_info(void);
bool server_info_set_session_key(struct auth_serversupplied_info *info,
DATA_BLOB session_key);
NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
- auth_serversupplied_info **server_info);
+ struct auth_serversupplied_info **server_info);
bool copy_current_user(struct current_user *dst, struct current_user *src);
struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
fstring save_username, bool create );
NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
const char *sent_nt_username,
const char *domain,
- auth_serversupplied_info **server_info,
+ struct auth_serversupplied_info **server_info,
struct netr_SamInfo3 *info3);
NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
const char *sent_nt_username,
const char *domain,
const struct wbcAuthUserInfo *info,
- auth_serversupplied_info **server_info);
-void free_user_info(auth_usersupplied_info **user_info);
+ struct auth_serversupplied_info **server_info);
+void free_user_info(struct auth_usersupplied_info **user_info);
bool make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) ;
bool is_trusted_domain(const char* dom_name);
@@ -1286,7 +1288,6 @@ void security_acl_map_generic(struct security_acl *sa, const struct generic_mapp
void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping);
NTSTATUS se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
uint32 acc_desired, uint32 *acc_granted);
-NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
/* The following definitions come from lib/util_sec.c */
@@ -6116,6 +6117,9 @@ NTSTATUS pass_oem_change(char *user,
uchar password_encrypted_with_nt_hash[516],
const uchar old_nt_hash_encrypted[16],
enum samPwdChangeReason *reject_reason);
+bool password_in_history(uint8_t nt_pw[NT_HASH_LEN],
+ uint32_t pw_history_len,
+ const uint8_t *pw_history);
NTSTATUS check_password_complexity(const char *username,
const char *password,
enum samPwdChangeReason *samr_reject_reason);
@@ -6713,7 +6717,7 @@ void invalidate_all_vuids(struct smbd_server_connection *sconn);
int register_initial_vuid(struct smbd_server_connection *sconn);
int register_existing_vuid(struct smbd_server_connection *sconn,
uint16 vuid,
- auth_serversupplied_info *server_info,
+ struct auth_serversupplied_info *server_info,
DATA_BLOB response_blob,
const char *smb_name);
void add_session_user(struct smbd_server_connection *sconn, const char *user);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index b23ea647ec..bc7a90d549 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -451,6 +451,7 @@ typedef struct files_struct {
bool aio_write_behind;
bool lockdb_clean;
bool initial_delete_on_close; /* Only set at NTCreateX if file was created. */
+ bool delete_on_close;
bool posix_open;
struct smb_filename *fsp_name;
diff --git a/source3/lib/time.c b/source3/lib/time.c
index 5286af37fd..dffc03b1cf 100644
--- a/source3/lib/time.c
+++ b/source3/lib/time.c
@@ -198,17 +198,17 @@ char *current_timestring(TALLOC_CTX *ctx, bool hires)
void srv_put_dos_date(char *buf,int offset,time_t unixdate)
{
- push_dos_date(buf, offset, unixdate, server_zone_offset);
+ push_dos_date((uint8_t *)buf, offset, unixdate, server_zone_offset);
}
void srv_put_dos_date2(char *buf,int offset, time_t unixdate)
{
- push_dos_date2(buf, offset, unixdate, server_zone_offset);
+ push_dos_date2((uint8_t *)buf, offset, unixdate, server_zone_offset);
}
void srv_put_dos_date3(char *buf,int offset,time_t unixdate)
{
- push_dos_date3(buf, offset, unixdate, server_zone_offset);
+ push_dos_date3((uint8_t *)buf, offset, unixdate, server_zone_offset);
}
void round_timespec(enum timestamp_set_resolution res, struct timespec *ts)
@@ -439,17 +439,17 @@ struct timespec interpret_long_date(const char *p)
void cli_put_dos_date(struct cli_state *cli, char *buf, int offset, time_t unixdate)
{
- push_dos_date(buf, offset, unixdate, cli->serverzone);
+ push_dos_date((uint8_t *)buf, offset, unixdate, cli->serverzone);
}
void cli_put_dos_date2(struct cli_state *cli, char *buf, int offset, time_t unixdate)
{
- push_dos_date2(buf, offset, unixdate, cli->serverzone);
+ push_dos_date2((uint8_t *)buf, offset, unixdate, cli->serverzone);
}
void cli_put_dos_date3(struct cli_state *cli, char *buf, int offset, time_t unixdate)
{
- push_dos_date3(buf, offset, unixdate, cli->serverzone);
+ push_dos_date3((uint8_t *)buf, offset, unixdate, cli->serverzone);
}
time_t cli_make_unix_date(struct cli_state *cli, const void *date_ptr)
diff --git a/source3/lib/util_seaccess.c b/source3/lib/util_seaccess.c
index 0da7442d19..e5562b5289 100644
--- a/source3/lib/util_seaccess.c
+++ b/source3/lib/util_seaccess.c
@@ -246,43 +246,3 @@ done:
return NT_STATUS_OK;
}
-
-/*******************************************************************
- samr_make_sam_obj_sd
- ********************************************************************/
-
-NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
-{
- DOM_SID adm_sid;
- DOM_SID act_sid;
-
- SEC_ACE ace[3];
-
- SEC_ACL *psa = NULL;
-
- sid_copy(&adm_sid, &global_sid_Builtin);
- sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
-
- sid_copy(&act_sid, &global_sid_Builtin);
- sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
-
- /*basic access for every one*/
- init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
- GENERIC_RIGHTS_SAM_EXECUTE | GENERIC_RIGHTS_SAM_READ, 0);
-
- /*full access for builtin aliases Administrators and Account Operators*/
- init_sec_ace(&ace[1], &adm_sid,
- SEC_ACE_TYPE_ACCESS_ALLOWED, GENERIC_RIGHTS_SAM_ALL_ACCESS, 0);
- init_sec_ace(&ace[2], &act_sid,
- SEC_ACE_TYPE_ACCESS_ALLOWED, GENERIC_RIGHTS_SAM_ALL_ACCESS, 0);
-
- if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- if ((*psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
- SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
- psa, sd_size)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- return NT_STATUS_OK;
-}
diff --git a/source3/libnet/libnet_samsync_passdb.c b/source3/libnet/libnet_samsync_passdb.c
index 41a9b3d9f3..51f96dc398 100644
--- a/source3/libnet/libnet_samsync_passdb.c
+++ b/source3/libnet/libnet_samsync_passdb.c
@@ -318,8 +318,7 @@ static NTSTATUS fetch_account_info(TALLOC_CTX *mem_ctx,
goto done;
}
- sid_copy(&user_sid, get_global_sam_sid());
- sid_append_rid(&user_sid, r->rid);
+ sid_compose(&user_sid, get_global_sam_sid(), r->rid);
DEBUG(3, ("Attempting to find SID %s for user %s in the passdb\n",
sid_to_fstring(sid_string, &user_sid), account));
@@ -395,8 +394,7 @@ static NTSTATUS fetch_group_info(TALLOC_CTX *mem_ctx,
fstrcpy(comment, r->description.string);
/* add the group to the mapping table */
- sid_copy(&group_sid, get_global_sam_sid());
- sid_append_rid(&group_sid, rid);
+ sid_compose(&group_sid, get_global_sam_sid(), rid);
sid_to_fstring(sid_string, &group_sid);
if (pdb_getgrsid(&map, group_sid)) {
@@ -459,8 +457,7 @@ static NTSTATUS fetch_group_mem_info(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
- sid_copy(&group_sid, get_global_sam_sid());
- sid_append_rid(&group_sid, rid);
+ sid_compose(&group_sid, get_global_sam_sid(), rid);
if (!get_domain_group_from_sid(group_sid, &map)) {
DEBUG(0, ("Could not find global group %d\n", rid));
@@ -491,8 +488,7 @@ static NTSTATUS fetch_group_mem_info(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
- sid_copy(&member_sid, get_global_sam_sid());
- sid_append_rid(&member_sid, r->rids[i]);
+ sid_compose(&member_sid, get_global_sam_sid(), r->rids[i]);
if (!pdb_getsampwsid(member, &member_sid)) {
DEBUG(1, ("Found bogus group member: %d (member_sid=%s group=%s)\n",
@@ -587,8 +583,7 @@ static NTSTATUS fetch_alias_info(TALLOC_CTX *mem_ctx,
fstrcpy(comment, r->description.string);
/* Find out whether the group is already mapped */
- sid_copy(&alias_sid, dom_sid);
- sid_append_rid(&alias_sid, rid);
+ sid_compose(&alias_sid, dom_sid, rid);
sid_to_fstring(sid_string, &alias_sid);
if (pdb_getgrsid(&map, alias_sid)) {
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 31216b8240..fa79ebcea3 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -1573,6 +1573,8 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
char *tmp = NULL;
uint8_t *bytes;
+ *psmbreq = NULL;
+
req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
if (req == NULL) {
return NULL;
@@ -1708,6 +1710,9 @@ struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
if (req == NULL) {
return NULL;
}
+ if (subreq == NULL) {
+ return req;
+ }
status = cli_smb_req_send(subreq);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c
index 12901826ee..7339acb4d7 100644
--- a/source3/libsmb/samlogon_cache.c
+++ b/source3/libsmb/samlogon_cache.c
@@ -113,8 +113,7 @@ void netsamlogon_clear_cached_user(struct netr_SamInfo3 *info3)
NETSAMLOGON_TDB));
return;
}
- sid_copy(&user_sid, info3->base.domain_sid);
- sid_append_rid(&user_sid, info3->base.rid);
+ sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid);
/* Prepare key as DOMAIN-SID/USER-RID string */
slprintf(keystr, sizeof(keystr), "%s", sid_to_fstring(tmp, &user_sid));
@@ -151,8 +150,7 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
return false;
}
- sid_copy(&user_sid, info3->base.domain_sid);
- sid_append_rid(&user_sid, info3->base.rid);
+ sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid);
/* Prepare key as DOMAIN-SID/USER-RID string */
slprintf(keystr, sizeof(keystr), "%s", sid_to_fstring(tmp, &user_sid));
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 26018f90db..095d0b17b9 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -1459,6 +1459,9 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USE
}
TALLOC_FREE(lck);
+
+ fsp->delete_on_close = delete_on_close;
+
return True;
}
diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c
index 1eec448083..aeb9ce37ea 100644
--- a/source3/modules/vfs_acl_common.c
+++ b/source3/modules/vfs_acl_common.c
@@ -760,6 +760,108 @@ static SMB_STRUCT_DIR *opendir_acl_common(vfs_handle_struct *handle,
return SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
}
+static int acl_common_remove_object(vfs_handle_struct *handle,
+ const char *path,
+ bool is_directory)
+{
+ connection_struct *conn = handle->conn;
+ struct file_id id;
+ files_struct *fsp = NULL;
+ int ret = 0;
+ char *parent_dir = NULL;
+ const char *final_component = NULL;
+ struct smb_filename local_fname;
+ int saved_errno = 0;
+
+ if (!parent_dirname(talloc_tos(), path,
+ &parent_dir, &final_component)) {
+ saved_errno = ENOMEM;
+ goto out;
+ }
+
+ DEBUG(10,("acl_common_remove_object: removing %s %s/%s\n",
+ is_directory ? "directory" : "file",
+ parent_dir, final_component ));
+
+ /* cd into the parent dir to pin it. */
+ ret = SMB_VFS_CHDIR(conn, parent_dir);
+ if (ret == -1) {
+ saved_errno = errno;
+ goto out;
+ }
+
+ ZERO_STRUCT(local_fname);
+ local_fname.base_name = CONST_DISCARD(char *,final_component);
+
+ /* Must use lstat here. */
+ ret = SMB_VFS_LSTAT(conn, &local_fname);
+ if (ret == -1) {
+ saved_errno = errno;
+ goto out;
+ }
+
+ /* Ensure we have this file open with DELETE access. */
+ id = vfs_file_id_from_sbuf(conn, &local_fname.st);
+ for (fsp = file_find_di_first(id); fsp; file_find_di_next(fsp)) {
+ if (fsp->access_mask & DELETE_ACCESS &&
+ fsp->delete_on_close) {
+ /* We did open this for delete,
+ * allow the delete as root.
+ */
+ break;
+ }
+ }
+
+ if (!fsp) {
+ DEBUG(10,("acl_common_remove_object: %s %s/%s "
+ "not an open file\n",
+ is_directory ? "directory" : "file",
+ parent_dir, final_component ));
+ saved_errno = EACCES;
+ goto out;
+ }
+
+ if (is_directory) {
+ ret = SMB_VFS_NEXT_RMDIR(handle, final_component);
+ } else {
+ ret = SMB_VFS_NEXT_UNLINK(handle, &local_fname);
+ }
+ if (ret == -1) {
+ saved_errno = errno;
+ }
+
+ out:
+
+ TALLOC_FREE(parent_dir);
+
+ vfs_ChDir(conn, conn->connectpath);
+ if (saved_errno) {
+ errno = saved_errno;
+ }
+ return ret;
+}
+
+static int rmdir_acl_common(struct vfs_handle_struct *handle,
+ const char *path)
+{
+ int ret;
+
+ ret = SMB_VFS_NEXT_RMDIR(handle, path);
+ if (!(ret == -1 && (errno == EACCES || errno == EPERM))) {
+ DEBUG(10,("rmdir_acl_common: unlink of %s failed %s\n",
+ path,
+ strerror(errno) ));
+ return ret;
+ }
+
+ become_root();
+ ret = acl_common_remove_object(handle,
+ path,
+ true);
+ unbecome_root();
+ return ret;
+}
+
static NTSTATUS create_file_acl_common(struct vfs_handle_struct *handle,
struct smb_request *req,
uint16_t root_dir_fid,
@@ -857,3 +959,28 @@ static NTSTATUS create_file_acl_common(struct vfs_handle_struct *handle,
/* NOTREACHED */
return status;
}
+
+static int unlink_acl_common(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
+{
+ int ret;
+
+ ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
+ if (!(ret == -1 && (errno == EACCES || errno == EPERM))) {
+ DEBUG(10,("unlink_acl_common: unlink of %s failed %s\n",
+ smb_fname->base_name,
+ strerror(errno) ));
+ return ret;
+ }
+ /* Don't do anything fancy for streams. */
+ if (smb_fname->stream_name) {
+ return ret;
+ }
+
+ become_root();
+ ret = acl_common_remove_object(handle,
+ smb_fname->base_name,
+ false);
+ unbecome_root();
+ return ret;
+}
diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c
index a1088ab63c..2afe69d764 100644
--- a/source3/modules/vfs_acl_tdb.c
+++ b/source3/modules/vfs_acl_tdb.c
@@ -265,7 +265,7 @@ static int unlink_acl_tdb(vfs_handle_struct *handle,
goto out;
}
- ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp);
+ ret = unlink_acl_common(handle, smb_fname_tmp);
if (ret == -1) {
goto out;
@@ -413,6 +413,7 @@ static struct vfs_fn_pointers vfs_acl_tdb_fns = {
.connect_fn = connect_acl_tdb,
.opendir = opendir_acl_common,
.mkdir = mkdir_acl_common,
+ .rmdir = rmdir_acl_common,
.open = open_acl_common,
.create_file = create_file_acl_common,
.unlink = unlink_acl_tdb,
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index 625ef91e8f..18f2d42784 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -199,8 +199,10 @@ static struct vfs_fn_pointers vfs_acl_xattr_fns = {
.connect_fn = connect_acl_xattr,
.opendir = opendir_acl_common,
.mkdir = mkdir_acl_common,
+ .rmdir = rmdir_acl_common,
.open = open_acl_common,
.create_file = create_file_acl_common,
+ .unlink = unlink_acl_common,
.fget_nt_acl = fget_nt_acl_common,
.get_nt_acl = get_nt_acl_common,
.fset_nt_acl = fset_nt_acl_common,
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 7edbb8783c..35fa740dd0 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -695,12 +695,13 @@ static char *capdecode(TALLOC_CTX *ctx, const char *from)
size_t len = 0;
for (p1 = from; *p1; len++) {
- if (is_hex(from)) {
+ if (is_hex(p1)) {
p1 += 3;
} else {
p1++;
}
}
+ len++;
to = TALLOC_ARRAY(ctx, char, len);
if (!to) {
diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c
new file mode 100644
index 0000000000..ff16d78c3f
--- /dev/null
+++ b/source3/modules/vfs_scannedonly.c
@@ -0,0 +1,995 @@
+/*
+ * scannedonly VFS module for Samba 3.5
+ *
+ * Copyright 2007,2008,2009 (C) Olivier Sessink
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * ABOUT SCANNEDONLY
+ *
+ * scannedonly implements a 'filter' like vfs module that talks over a
+ * unix domain socket or over UDP to a anti-virus engine.
+ *
+ * files that are clean have a corresponding .scanned:{filename} file
+ * in the same directory. So why the .scanned: files? They take up
+ * only an inode, because they are 0 bytes. To test if the file is
+ * scanned only a stat() call on the filesystem is needed which is
+ * very quick compared to a database lookup. All modern filesystems
+ * use database technology such as balanced trees for lookups anyway.
+ * The number of inodes in modern filesystems is also not limiting
+ * anymore. The .scanned: files are also easy scriptable. You can
+ * remove them with a simple find command or create them with a
+ * simple touch command. Extended filesystem attributes have similar
+ * properties, but are not supported on all filesystems, so that
+ * would limit the usage of the module (and attributes are not as
+ * easily scriptable)
+ *
+ * files that are not clean are sent to the AV-engine. Only the
+ * filename is sent over the socket. The protocol is very simple:
+ * a newline separated list of filenames inside each datagram.
+ *
+ * a file AV-scan may be requested multiple times, the AV-engine
+ * should also check if the file has been scanned already. Requests
+ * can also be dropped by the AV-engine (and we thus don't need the
+ * reliability of TCP).
+ *
+ */
+
+#include "includes.h"
+
+#include "config.h"
+
+#define SENDBUFFERSIZE 1450
+
+struct Tscannedonly {
+ int socket;
+ int domain_socket;
+ int portnum;
+ int scanning_message_len;
+ int recheck_time_open;
+ int recheck_tries_open;
+ int recheck_size_open;
+ int recheck_time_readdir;
+ int recheck_tries_readdir;
+ bool show_special_files;
+ bool rm_hidden_files_on_rmdir;
+ bool hide_nonscanned_files;
+ bool allow_nonscanned_files;
+ char *socketname;
+ char *scanhost;
+ char *scanning_message;
+ char *p_scanned; /* prefix for scanned files */
+ char *p_virus; /* prefix for virus containing files */
+ char *p_failed; /* prefix for failed to scan files */
+ char gsendbuffer[SENDBUFFERSIZE + 1];
+};
+
+#define STRUCTSCANO(var) ((struct Tscannedonly *)var)
+
+struct scannedonly_DIR {
+ char *base;
+ int notify_loop_done;
+ SMB_STRUCT_DIR *DIR;
+};
+#define SCANNEDONLY_DEBUG 9
+/*********************/
+/* utility functions */
+/*********************/
+
+static char *real_path_from_notify_path(TALLOC_CTX *ctx,
+ struct Tscannedonly *so,
+ const char *path)
+{
+ char *name;
+ int len, pathlen;
+
+ name = strrchr(path, '/');
+ if (!name) {
+ return NULL;
+ }
+ pathlen = name - path;
+ name++;
+ len = strlen(name);
+ if (len <= so->scanning_message_len) {
+ return NULL;
+ }
+
+ if (strcmp(name + (len - so->scanning_message_len),
+ so->scanning_message) != 0) {
+ return NULL;
+ }
+
+ return talloc_strndup(ctx,path,
+ pathlen + len - so->scanning_message_len);
+}
+
+static char *cachefile_name(TALLOC_CTX *ctx,
+ const char *shortname,
+ const char *base,
+ const char *p_scanned)
+{
+ return talloc_asprintf(ctx, "%s%s%s", base, p_scanned, shortname);
+}
+
+static char *name_w_ending_slash(TALLOC_CTX *ctx, const char *name)
+{
+ int len = strlen(name);
+ if (name[len - 1] == '/') {
+ return talloc_strdup(ctx,name);
+ } else {
+ return talloc_asprintf(ctx, "%s/", name);
+ }
+}
+
+static char *cachefile_name_f_fullpath(TALLOC_CTX *ctx,
+ const char *fullpath,
+ const char *p_scanned)
+{
+ const char *base;
+ char *tmp, *cachefile, *shortname;
+ tmp = strrchr(fullpath, '/');
+ if (tmp) {
+ base = talloc_strndup(ctx, fullpath, (tmp - fullpath) + 1);
+ shortname = tmp + 1;
+ } else {
+ base = "";
+ shortname = (char *)fullpath;
+ }
+ cachefile = cachefile_name(ctx, shortname, base, p_scanned);
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("cachefile_name_f_fullpath cachefile=%s\n", cachefile));
+ return cachefile;
+}
+
+static char *path_plus_name(TALLOC_CTX *ctx, const char *base,
+ const char *filename)
+{
+ return talloc_asprintf(ctx, "%s%s", base,filename);
+}
+
+static char *construct_full_path(TALLOC_CTX *ctx, vfs_handle_struct * handle,
+ const char *somepath, bool ending_slash)
+{
+ char *tmp;
+
+ if (!somepath) {
+ return NULL;
+ }
+ if (somepath[0] == '/') {
+ if (ending_slash) {
+ return name_w_ending_slash(ctx,somepath);
+ }
+ return talloc_strdup(ctx,somepath);
+ }
+ tmp=(char *)somepath;
+ if (tmp[0]=='.'&&tmp[1]=='/') {
+ tmp+=2;
+ }
+ /* vfs_GetWd() seems to return a path with a slash */
+ if (ending_slash) {
+ return talloc_asprintf(ctx, "%s%s/",
+ vfs_GetWd(ctx, handle->conn),tmp);
+ }
+ return talloc_asprintf(ctx, "%s%s",
+ vfs_GetWd(ctx, handle->conn),tmp);
+}
+
+static int connect_to_scanner(vfs_handle_struct * handle)
+{
+ struct Tscannedonly *so = (struct Tscannedonly *)handle->data;
+
+ if (so->domain_socket) {
+ struct sockaddr_un saun;
+ DEBUG(SCANNEDONLY_DEBUG, ("socket=%s\n", so->socketname));
+ if ((so->socket = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
+ DEBUG(2, ("failed to create socket %s\n",
+ so->socketname));
+ return -1;
+ }
+ saun.sun_family = AF_UNIX;
+ strncpy(saun.sun_path, so->socketname,
+ sizeof(saun.sun_path) - 1);
+ if (connect(so->socket, (struct sockaddr *)(void *)&saun,
+ SUN_LEN(&saun)) < 0) {
+ DEBUG(2, ("failed to connect to socket %s\n",
+ so->socketname));
+ return -1;
+ }
+ DEBUG(SCANNEDONLY_DEBUG,("bound %s to socket %d\n",
+ saun.sun_path, so->socket));
+
+ } else {
+ so->socket = open_udp_socket(so->scanhost, so->portnum);
+ if (so->socket < 0) {
+ DEBUG(2,("failed to open UDP socket to %s:%d\n",
+ so->scanhost,so->portnum));
+ return -1;
+ }
+ }
+
+ {/* increasing the socket buffer is done because we have large bursts
+ of UDP packets or DGRAM's on a domain socket whenever we hit a
+ large directory with lots of unscanned files. */
+ int sndsize;
+ socklen_t size = sizeof(int);
+ getsockopt(so->socket, SOL_SOCKET, SO_RCVBUF,
+ (char *)&sndsize, &size);
+ DEBUG(SCANNEDONLY_DEBUG, ("current socket buffer size=%d\n",
+ sndsize));
+ sndsize = 262144;
+ if (setsockopt(so->socket, SOL_SOCKET, SO_RCVBUF,
+ (char *)&sndsize,
+ (int)sizeof(sndsize)) != 0) {
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("error setting socket buffer %s (%d)\n",
+ strerror(errno), errno));
+ }
+ }
+ set_blocking(so->socket, false);
+ return 0;
+}
+
+static void flush_sendbuffer(vfs_handle_struct * handle)
+{
+ struct Tscannedonly *so = (struct Tscannedonly *)handle->data;
+ int ret, len, loop = 10;
+ if (so->gsendbuffer[0] == '\0') {
+ return;
+ }
+
+ do {
+ loop--;
+ len = strlen(so->gsendbuffer);
+ ret = send(so->socket, so->gsendbuffer, len, MSG_DONTWAIT);
+ if (ret == len) {
+ so->gsendbuffer[0] = '\0';
+ break;
+ }
+ if (ret == -1) {
+ DEBUG(3,("scannedonly flush_sendbuffer: "
+ "error sending on socket %d to scanner:"
+ " %s (%d)\n",
+ so->socket, strerror(errno), errno));
+ if (errno == ECONNREFUSED || errno == ENOTCONN
+ || errno == ECONNRESET) {
+ if (connect_to_scanner(handle) == -1)
+ break; /* connecting fails, abort */
+ /* try again */
+ } else if (errno != EINTR) {
+ /* on EINTR we just try again, all remaining
+ other errors we log the error
+ and try again ONCE */
+ loop = 1;
+ DEBUG(3,("scannedonly flush_sendbuffer: "
+ "error sending data to scanner: %s "
+ "(%d)\n", strerror(errno), errno));
+ }
+ } else {
+ /* --> partial write: Resend all filenames that were
+ not or not completely written. a partial filename
+ written means the filename will not arrive correctly,
+ so resend it completely */
+ int pos = 0;
+ while (pos < len) {
+ char *tmp = strchr(so->gsendbuffer+pos, '\n');
+ if (tmp && tmp - so->gsendbuffer < ret)
+ pos = tmp - so->gsendbuffer + 1;
+ else
+ break;
+ }
+ memmove(so->gsendbuffer, so->gsendbuffer + pos,
+ SENDBUFFERSIZE - ret);
+ /* now try again */
+ }
+ } while (loop > 0);
+
+ if (so->gsendbuffer[0] != '\0') {
+ DEBUG(2,
+ ("scannedonly flush_sendbuffer: "
+ "failed to send files to AV scanner, "
+ "discarding files."));
+ so->gsendbuffer[0] = '\0';
+ }
+}
+
+static void notify_scanner(vfs_handle_struct * handle, const char *scanfile)
+{
+ char *tmp;
+ int tmplen, gsendlen;
+ struct Tscannedonly *so = (struct Tscannedonly *)handle->data;
+ TALLOC_CTX *ctx=talloc_tos();
+ if (scanfile[0] != '/') {
+ tmp = construct_full_path(ctx,handle, scanfile, false);
+ } else {
+ tmp = (char *)scanfile;
+ }
+ tmplen = strlen(tmp);
+ gsendlen = strlen(so->gsendbuffer);
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("scannedonly notify_scanner: tmp=%s, tmplen=%d, gsendlen=%d\n",
+ tmp, tmplen, gsendlen));
+ if (gsendlen + tmplen >= SENDBUFFERSIZE) {
+ flush_sendbuffer(handle);
+ }
+ strlcat(so->gsendbuffer, tmp, SENDBUFFERSIZE + 1);
+ strlcat(so->gsendbuffer, "\n", SENDBUFFERSIZE + 1);
+}
+
+static bool is_scannedonly_file(struct Tscannedonly *so, const char *shortname)
+{
+ if (shortname[0]!='.') {
+ return false;
+ }
+ if (strncmp(shortname, so->p_scanned, strlen(so->p_scanned)) == 0) {
+ return true;
+ }
+ if (strncmp(shortname, so->p_virus, strlen(so->p_virus)) == 0) {
+ return true;
+ }
+ if (strncmp(shortname, so->p_failed, strlen(so->p_failed)) == 0) {
+ return true;
+ }
+ return false;
+}
+
+static bool timespec_is_newer(struct timespec *base, struct timespec *test)
+{
+ return timespec_compare(base,test) < 0;
+}
+
+/*
+vfs_handle_struct *handle the scannedonly handle
+scannedonly_DIR * sDIR the scannedonly struct if called from _readdir()
+or NULL
+fullpath is a full path starting from / or a relative path to the
+current working directory
+shortname is the filename without directory components
+basename, is the directory without file name component
+allow_nonexistant return TRUE if stat() on the requested file fails
+recheck_time, the time in milliseconds to wait for the daemon to
+create a .scanned file
+recheck_tries, the number of tries to wait
+recheck_size, size in Kb of files that should not be waited for
+loop : boolean if we should try to loop over all files in the directory
+and send a notify to the scanner for all files that need scanning
+*/
+static bool scannedonly_allow_access(vfs_handle_struct * handle,
+ struct scannedonly_DIR *sDIR,
+ struct smb_filename *smb_fname,
+ const char *shortname,
+ const char *base_name,
+ int allow_nonexistant,
+ int recheck_time, int recheck_tries,
+ int recheck_size, int loop)
+{
+ struct smb_filename *cache_smb_fname;
+ TALLOC_CTX *ctx=talloc_tos();
+ char *cachefile;
+ int retval;
+ int didloop;
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("smb_fname->base_name=%s, shortname=%s, base_name=%s\n"
+ ,smb_fname->base_name,shortname,base_name));
+
+ if (ISDOT(shortname) || ISDOTDOT(shortname)) {
+ return true;
+ }
+ if (is_scannedonly_file(STRUCTSCANO(handle->data), shortname)) {
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("scannedonly_allow_access, %s is a scannedonly file, "
+ "return 0\n", shortname));
+ return false;
+ }
+
+ if (!VALID_STAT(smb_fname->st)) {
+ DEBUG(SCANNEDONLY_DEBUG,("stat %s\n",smb_fname->base_name));
+ retval = SMB_VFS_NEXT_STAT(handle, smb_fname);
+ if (retval != 0) {
+ /* failed to stat this file?!? --> hide it */
+ DEBUG(SCANNEDONLY_DEBUG,("no valid stat, return"
+ " allow_nonexistant=%d\n",
+ allow_nonexistant));
+ return allow_nonexistant;
+ }
+ }
+ if (!S_ISREG(smb_fname->st.st_ex_mode)) {
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("%s is not a regular file, ISDIR=%d\n",
+ smb_fname->base_name,
+ S_ISDIR(smb_fname->st.st_ex_mode)));
+ return (STRUCTSCANO(handle->data)->
+ show_special_files ||
+ S_ISDIR(smb_fname->st.st_ex_mode));
+ }
+ if (smb_fname->st.st_ex_size == 0) {
+ DEBUG(SCANNEDONLY_DEBUG,("empty file, return 1\n"));
+ return true; /* empty files cannot contain viruses ! */
+ }
+ cachefile = cachefile_name(ctx,
+ shortname,
+ base_name,
+ STRUCTSCANO(handle->data)->p_scanned);
+ create_synthetic_smb_fname(ctx, cachefile,NULL,NULL,&cache_smb_fname);
+ if (!VALID_STAT(cache_smb_fname->st)) {
+ retval = SMB_VFS_NEXT_STAT(handle, cache_smb_fname);
+ }
+ if (retval == 0 && VALID_STAT(cache_smb_fname->st)) {
+ if (timespec_is_newer(&smb_fname->st.st_ex_mtime,
+ &cache_smb_fname->st.st_ex_mtime)) {
+ talloc_free(cache_smb_fname);
+ return true;
+ }
+ /* no cachefile or too old */
+ SMB_VFS_NEXT_UNLINK(handle, cache_smb_fname);
+ retval = -1;
+ }
+
+ notify_scanner(handle, smb_fname->base_name);
+
+ didloop = 0;
+ if (loop && sDIR && !sDIR->notify_loop_done) {
+ /* check the rest of the directory and notify the
+ scanner if some file needs scanning */
+ long offset;
+ SMB_STRUCT_DIRENT *dire;
+
+ offset = SMB_VFS_NEXT_TELLDIR(handle, sDIR->DIR);
+ dire = SMB_VFS_NEXT_READDIR(handle, sDIR->DIR, NULL);
+ while (dire) {
+ char *fpath2;
+ struct smb_filename *smb_fname2;
+ fpath2 = path_plus_name(ctx,base_name, dire->d_name);
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("scannedonly_allow_access in loop, "
+ "found %s\n", fpath2));
+ create_synthetic_smb_fname(ctx, fpath2,NULL,NULL,
+ &smb_fname2);
+ scannedonly_allow_access(handle, NULL,
+ smb_fname2,
+ dire->d_name,
+ base_name, 0, 0, 0, 0, 0);
+ talloc_free(fpath2);
+ talloc_free(smb_fname2);
+ dire = SMB_VFS_NEXT_READDIR(handle, sDIR->DIR,NULL);
+ }
+ sDIR->notify_loop_done = 1;
+ didloop = 1;
+ SMB_VFS_NEXT_SEEKDIR(handle, sDIR->DIR, offset);
+ }
+ if (recheck_time > 0
+ && ((recheck_size > 0
+ && smb_fname->st.st_ex_size < (1024 * recheck_size))
+ || didloop)) {
+ int i = 0;
+ flush_sendbuffer(handle);
+ while (retval != 0 /*&& errno == ENOENT */
+ && i < recheck_tries) {
+ struct timespec req = { 0, recheck_time * 10000 };
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("scannedonly_allow_access, wait (try=%d "
+ "(max %d), %d ms) for %s\n",
+ i, recheck_tries,
+ recheck_time, cache_smb_fname->base_name));
+ nanosleep(&req, NULL);
+ retval = SMB_VFS_NEXT_STAT(handle, cache_smb_fname);
+ i++;
+ }
+ }
+ /* still no cachefile, or still too old, return 0 */
+ if (retval != 0
+ || !timespec_is_newer(&smb_fname->st.st_ex_mtime,
+ &cache_smb_fname->st.st_ex_mtime)) {
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("retval=%d, return 0\n",retval));
+ return false;
+ }
+ return true;
+}
+
+/*********************/
+/* VFS functions */
+/*********************/
+
+static SMB_STRUCT_DIR *scannedonly_opendir(vfs_handle_struct * handle,
+ const char *fname,
+ const char *mask, uint32 attr)
+{
+ SMB_STRUCT_DIR *DIRp;
+ struct scannedonly_DIR *sDIR;
+
+ DIRp = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
+ if (!DIRp) {
+ return NULL;
+ }
+
+ sDIR = TALLOC_P(NULL, struct scannedonly_DIR);
+ if (fname[0] != '/') {
+ sDIR->base = construct_full_path(sDIR,handle, fname, true);
+ } else {
+ sDIR->base = name_w_ending_slash(sDIR, fname);
+ }
+ sDIR->DIR = DIRp;
+ sDIR->notify_loop_done = 0;
+ return (SMB_STRUCT_DIR *) sDIR;
+}
+
+static SMB_STRUCT_DIRENT *scannedonly_readdir(vfs_handle_struct *handle,
+ SMB_STRUCT_DIR * dirp,
+ SMB_STRUCT_STAT *sbuf)
+{
+ SMB_STRUCT_DIRENT *result;
+ int allowed = 0;
+ char *tmp;
+ struct smb_filename *smb_fname;
+ char *notify_name;
+ int namelen;
+ SMB_STRUCT_DIRENT *newdirent;
+ TALLOC_CTX *ctx=talloc_tos();
+
+ struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp;
+ if (!dirp) {
+ return NULL;
+ }
+
+ result = SMB_VFS_NEXT_READDIR(handle, sDIR->DIR, sbuf);
+
+ if (!result)
+ return NULL;
+
+ if (is_scannedonly_file(STRUCTSCANO(handle->data), result->d_name)) {
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("scannedonly_readdir, %s is a scannedonly file, "
+ "skip to next entry\n", result->d_name));
+ return scannedonly_readdir(handle, dirp, NULL);
+ }
+
+ tmp = path_plus_name(ctx,sDIR->base, result->d_name);
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("scannedonly_readdir, check access to %s (sbuf=%p)\n",
+ tmp,sbuf));
+
+ /* even if we don't hide nonscanned files or we allow non scanned
+ files we call allow_access because it will notify the daemon to
+ scan these files */
+ create_synthetic_smb_fname(ctx, tmp,NULL,
+ sbuf?VALID_STAT(*sbuf)?sbuf:NULL:NULL,
+ &smb_fname);
+ allowed = scannedonly_allow_access(
+ handle, sDIR, smb_fname,
+ result->d_name,
+ sDIR->base, 0,
+ STRUCTSCANO(handle->data)->hide_nonscanned_files
+ ? STRUCTSCANO(handle->data)->recheck_time_readdir
+ : 0,
+ STRUCTSCANO(handle->data)->recheck_tries_readdir,
+ -1,
+ 1);
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("scannedonly_readdir access to %s (%s) = %d\n", tmp,
+ result->d_name, allowed));
+ if (allowed) {
+ return result;
+ }
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("hide_nonscanned_files=%d, allow_nonscanned_files=%d\n",
+ STRUCTSCANO(handle->data)->hide_nonscanned_files,
+ STRUCTSCANO(handle->data)->allow_nonscanned_files
+ ));
+
+ if (!STRUCTSCANO(handle->data)->hide_nonscanned_files
+ || STRUCTSCANO(handle->data)->allow_nonscanned_files) {
+ return result;
+ }
+
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("scannedonly_readdir, readdir listing for %s not "
+ "allowed, notify user\n", result->d_name));
+ notify_name = talloc_asprintf(
+ ctx,"%s %s",result->d_name,
+ STRUCTSCANO(handle->data)->scanning_message);
+ namelen = strlen(notify_name);
+ newdirent = (SMB_STRUCT_DIRENT *)TALLOC_ARRAY(
+ ctx, char, sizeof(SMB_STRUCT_DIRENT) + namelen + 1);
+ if (!newdirent) {
+ return NULL;
+ }
+ memcpy(newdirent, result, sizeof(SMB_STRUCT_DIRENT));
+ memcpy(&newdirent->d_name, notify_name, namelen + 1);
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("scannedonly_readdir, return newdirent at %p with "
+ "notification %s\n", newdirent, newdirent->d_name));
+ return newdirent;
+}
+
+static void scannedonly_seekdir(struct vfs_handle_struct *handle,
+ SMB_STRUCT_DIR * dirp, long offset)
+{
+ struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp;
+ SMB_VFS_NEXT_SEEKDIR(handle, sDIR->DIR, offset);
+}
+
+static long scannedonly_telldir(struct vfs_handle_struct *handle,
+ SMB_STRUCT_DIR * dirp)
+{
+ struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp;
+ return SMB_VFS_NEXT_TELLDIR(handle, sDIR->DIR);
+}
+
+static void scannedonly_rewinddir(struct vfs_handle_struct *handle,
+ SMB_STRUCT_DIR * dirp)
+{
+ struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp;
+ SMB_VFS_NEXT_REWINDDIR(handle, sDIR->DIR);
+}
+
+static int scannedonly_closedir(vfs_handle_struct * handle,
+ SMB_STRUCT_DIR * dirp)
+{
+ int retval;
+ struct scannedonly_DIR *sDIR = (struct scannedonly_DIR *)dirp;
+ flush_sendbuffer(handle);
+ retval = SMB_VFS_NEXT_CLOSEDIR(handle, sDIR->DIR);
+ TALLOC_FREE(sDIR);
+ return retval;
+}
+
+static int scannedonly_stat(vfs_handle_struct * handle,
+ struct smb_filename *smb_fname)
+{
+ int ret;
+ ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
+ DEBUG(SCANNEDONLY_DEBUG, ("scannedonly_stat: %s returned %d\n",
+ smb_fname->base_name, ret));
+ if (ret != 0 && errno == ENOENT) {
+ TALLOC_CTX *ctx=talloc_tos();
+ char *test_base_name, *tmp_base_name = smb_fname->base_name;
+ /* possibly this was a fake name (file is being scanned for
+ viruses.txt): check for that and create the real name and
+ stat the real name */
+ test_base_name = real_path_from_notify_path(
+ ctx,
+ STRUCTSCANO(handle->data),
+ smb_fname->base_name);
+ if (test_base_name) {
+ smb_fname->base_name = test_base_name;
+ ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
+ DEBUG(5, ("_stat: %s returned %d\n",
+ test_base_name, ret));
+ smb_fname->base_name = tmp_base_name;
+ }
+ }
+ return ret;
+}
+
+static int scannedonly_lstat(vfs_handle_struct * handle,
+ struct smb_filename *smb_fname)
+{
+ int ret;
+ ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
+ DEBUG(SCANNEDONLY_DEBUG, ("scannedonly_lstat: %s returned %d\n",
+ smb_fname->base_name, ret));
+ if (ret != 0 && errno == ENOENT) {
+ TALLOC_CTX *ctx=talloc_tos();
+ char *test_base_name, *tmp_base_name = smb_fname->base_name;
+ /* possibly this was a fake name (file is being scanned for
+ viruses.txt): check for that and create the real name and
+ stat the real name */
+ test_base_name = real_path_from_notify_path(
+ ctx, STRUCTSCANO(handle->data), smb_fname->base_name);
+ if (test_base_name) {
+ smb_fname->base_name = test_base_name;
+ ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
+ DEBUG(5, ("_lstat: %s returned %d\n",
+ test_base_name, ret));
+ smb_fname->base_name = tmp_base_name;
+ }
+ }
+ return ret;
+}
+
+static int scannedonly_open(vfs_handle_struct * handle,
+ struct smb_filename *smb_fname,
+ files_struct * fsp, int flags, mode_t mode)
+{
+ const char *base;
+ char *tmp, *shortname;
+ int allowed, write_access = 0;
+ TALLOC_CTX *ctx=talloc_tos();
+ /* if open for writing ignore it */
+ if ((flags & O_ACCMODE) == O_WRONLY) {
+ return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+ }
+ if ((flags & O_ACCMODE) == O_RDWR) {
+ write_access = 1;
+ }
+ /* check if this file is scanned already */
+ tmp = strrchr(smb_fname->base_name, '/');
+ if (tmp) {
+ base = talloc_strndup(ctx,smb_fname->base_name,
+ (tmp - smb_fname->base_name) + 1);
+ shortname = tmp + 1;
+ } else {
+ base = "";
+ shortname = (char *)smb_fname->base_name;
+ }
+ allowed = scannedonly_allow_access(
+ handle, NULL, smb_fname, shortname,
+ base,
+ write_access,
+ STRUCTSCANO(handle->data)->recheck_time_open,
+ STRUCTSCANO(handle->data)->recheck_tries_open,
+ STRUCTSCANO(handle->data)->recheck_size_open,
+ 0);
+ flush_sendbuffer(handle);
+ DEBUG(SCANNEDONLY_DEBUG, ("scannedonly_open: allow=%d for %s\n",
+ allowed, smb_fname->base_name));
+ if (allowed
+ || STRUCTSCANO(handle->data)->allow_nonscanned_files) {
+ return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+ }
+ errno = EACCES;
+ return -1;
+}
+
+static int scannedonly_close(vfs_handle_struct * handle, files_struct * fsp)
+{
+ /* we only have to notify the scanner
+ for files that were open readwrite or writable. */
+ if (fsp->can_write) {
+ TALLOC_CTX *ctx = talloc_tos();
+ notify_scanner(handle, construct_full_path(
+ ctx,handle,
+ fsp->fsp_name->base_name,false));
+ flush_sendbuffer(handle);
+ }
+ return SMB_VFS_NEXT_CLOSE(handle, fsp);
+}
+
+static int scannedonly_rename(vfs_handle_struct * handle,
+ const struct smb_filename *smb_fname_src,
+ const struct smb_filename *smb_fname_dst)
+{
+ /* rename the cache file before we pass the actual rename on */
+ struct smb_filename *smb_fname_src_tmp = NULL;
+ struct smb_filename *smb_fname_dst_tmp = NULL;
+ char *cachefile_src, *cachefile_dst;
+ TALLOC_CTX *ctx = talloc_tos();
+
+ /* Setup temporary smb_filename structs. */
+ cachefile_src = cachefile_name_f_fullpath(
+ ctx,
+ smb_fname_src->base_name,
+ STRUCTSCANO(handle->data)->p_scanned);
+ cachefile_dst = cachefile_name_f_fullpath(
+ ctx,
+ smb_fname_dst->base_name,
+ STRUCTSCANO(handle->data)->p_scanned);
+
+ create_synthetic_smb_fname(ctx, cachefile_src,NULL,NULL,
+ &smb_fname_src_tmp);
+ create_synthetic_smb_fname(ctx, cachefile_dst,NULL,NULL,
+ &smb_fname_dst_tmp);
+
+ if (SMB_VFS_NEXT_RENAME(handle, smb_fname_src_tmp, smb_fname_dst_tmp)
+ != 0) {
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("failed to rename %s into %s\n", cachefile_src,
+ cachefile_dst));
+ }
+ return SMB_VFS_NEXT_RENAME(handle, smb_fname_src, smb_fname_dst);
+}
+
+static int scannedonly_unlink(vfs_handle_struct * handle,
+ const struct smb_filename *smb_fname)
+{
+ /* unlink the 'scanned' file too */
+ struct smb_filename *smb_fname_cache = NULL;
+ char * cachefile;
+ TALLOC_CTX *ctx = talloc_tos();
+
+ cachefile = cachefile_name_f_fullpath(
+ ctx,
+ smb_fname->base_name,
+ STRUCTSCANO(handle->data)->p_scanned);
+ create_synthetic_smb_fname(ctx, cachefile,NULL,NULL,
+ &smb_fname_cache);
+ if (SMB_VFS_NEXT_UNLINK(handle, smb_fname_cache) != 0) {
+ DEBUG(SCANNEDONLY_DEBUG, ("_unlink: failed to unlink %s\n",
+ smb_fname_cache->base_name));
+ }
+ return SMB_VFS_NEXT_UNLINK(handle, smb_fname);
+}
+
+static int scannedonly_rmdir(vfs_handle_struct * handle, const char *path)
+{
+ /* if there are only .scanned: .virus: or .failed: files, we delete
+ those, because the client cannot see them */
+ DIR *dirp;
+ SMB_STRUCT_DIRENT *dire;
+ TALLOC_CTX *ctx = talloc_tos();
+ bool only_deletable_files = true, have_files = false;
+ char *path_w_slash;
+
+ if (!STRUCTSCANO(handle->data)->rm_hidden_files_on_rmdir)
+ return SMB_VFS_NEXT_RMDIR(handle, path);
+
+ path_w_slash = name_w_ending_slash(ctx,path);
+ dirp = SMB_VFS_NEXT_OPENDIR(handle, path, NULL, 0);
+ while ((dire = SMB_VFS_NEXT_READDIR(handle, dirp, NULL)) != NULL) {
+ if (ISDOT(dire->d_name) || ISDOTDOT(dire->d_name)) {
+ continue;
+ }
+ have_files = true;
+ if (!is_scannedonly_file(STRUCTSCANO(handle->data),
+ dire->d_name)) {
+ struct smb_filename *smb_fname = NULL;
+ char *fullpath;
+ int retval;
+
+ if (STRUCTSCANO(handle->data)->show_special_files) {
+ only_deletable_files = false;
+ break;
+ }
+ /* stat the file and see if it is a
+ special file */
+ fullpath = path_plus_name(ctx,path_w_slash,
+ dire->d_name);
+ create_synthetic_smb_fname(ctx, fullpath,NULL,NULL,
+ &smb_fname);
+ retval = SMB_VFS_NEXT_STAT(handle, smb_fname);
+ if (retval == 0
+ && S_ISREG(smb_fname->st.st_ex_mode)) {
+ only_deletable_files = false;
+ }
+ TALLOC_FREE(fullpath);
+ TALLOC_FREE(smb_fname);
+ break;
+ }
+ }
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("path=%s, have_files=%d, only_deletable_files=%d\n",
+ path, have_files, only_deletable_files));
+ if (have_files && only_deletable_files) {
+ DEBUG(SCANNEDONLY_DEBUG,
+ ("scannedonly_rmdir, remove leftover scannedonly "
+ "files from %s\n", path_w_slash));
+ SMB_VFS_NEXT_REWINDDIR(handle, dirp);
+ while ((dire = SMB_VFS_NEXT_READDIR(handle, dirp, NULL))
+ != NULL) {
+ char *fullpath;
+ struct smb_filename *smb_fname = NULL;
+ if (ISDOT(dire->d_name) || ISDOTDOT(dire->d_name)) {
+ continue;
+ }
+ fullpath = path_plus_name(ctx,path_w_slash,
+ dire->d_name);
+ create_synthetic_smb_fname(ctx, fullpath,NULL,NULL,
+ &smb_fname);
+ DEBUG(SCANNEDONLY_DEBUG, ("unlink %s\n", fullpath));
+ SMB_VFS_NEXT_UNLINK(handle, smb_fname);
+ TALLOC_FREE(fullpath);
+ TALLOC_FREE(smb_fname);
+ }
+ }
+ return SMB_VFS_NEXT_CLOSEDIR(handle, dirp);
+}
+
+static void free_scannedonly_data(void **data)
+{
+ SAFE_FREE(*data);
+}
+
+static int scannedonly_connect(struct vfs_handle_struct *handle,
+ const char *service, const char *user)
+{
+
+ struct Tscannedonly *so;
+
+ so = SMB_MALLOC_P(struct Tscannedonly);
+ handle->data = (void *)so;
+ handle->free_data = free_scannedonly_data;
+ so->gsendbuffer[0]='\0';
+ so->domain_socket =
+ lp_parm_bool(SNUM(handle->conn), "scannedonly",
+ "domain_socket", True);
+ so->socketname =
+ (char *)lp_parm_const_string(SNUM(handle->conn),
+ "scannedonly", "socketname",
+ "/var/lib/scannedonly/scan");
+ so->portnum =
+ lp_parm_int(SNUM(handle->conn), "scannedonly", "portnum",
+ 2020);
+ so->scanhost =
+ (char *)lp_parm_const_string(SNUM(handle->conn),
+ "scannedonly", "scanhost",
+ "localhost");
+
+ so->show_special_files =
+ lp_parm_bool(SNUM(handle->conn), "scannedonly",
+ "show_special_files", True);
+ so->rm_hidden_files_on_rmdir =
+ lp_parm_bool(SNUM(handle->conn), "scannedonly",
+ "rm_hidden_files_on_rmdir", True);
+ so->hide_nonscanned_files =
+ lp_parm_bool(SNUM(handle->conn), "scannedonly",
+ "hide_nonscanned_files", False);
+ so->allow_nonscanned_files =
+ lp_parm_bool(SNUM(handle->conn), "scannedonly",
+ "allow_nonscanned_files", False);
+ so->scanning_message =
+ (char *)lp_parm_const_string(SNUM(handle->conn),
+ "scannedonly",
+ "scanning_message",
+ "is being scanned for viruses");
+ so->scanning_message_len = strlen(so->scanning_message);
+ so->recheck_time_open =
+ lp_parm_int(SNUM(handle->conn), "scannedonly",
+ "recheck_time_open", 50);
+ so->recheck_tries_open =
+ lp_parm_int(SNUM(handle->conn), "scannedonly",
+ "recheck_tries_open", 100);
+ so->recheck_size_open =
+ lp_parm_int(SNUM(handle->conn), "scannedonly",
+ "recheck_size_open", 100);
+ so->recheck_time_readdir =
+ lp_parm_int(SNUM(handle->conn), "scannedonly",
+ "recheck_time_readdir", 50);
+ so->recheck_tries_readdir =
+ lp_parm_int(SNUM(handle->conn), "scannedonly",
+ "recheck_tries_readdir", 20);
+
+ so->p_scanned =
+ (char *)lp_parm_const_string(SNUM(handle->conn),
+ "scannedonly",
+ "pref_scanned",
+ ".scanned:");
+ so->p_virus =
+ (char *)lp_parm_const_string(SNUM(handle->conn),
+ "scannedonly",
+ "pref_virus",
+ ".virus:");
+ so->p_failed =
+ (char *)lp_parm_const_string(SNUM(handle->conn),
+ "scannedonly",
+ "pref_failed",
+ ".failed:");
+ connect_to_scanner(handle);
+
+ return SMB_VFS_NEXT_CONNECT(handle, service, user);
+}
+
+/* VFS operations structure */
+static struct vfs_fn_pointers vfs_scannedonly_fns = {
+ .opendir = scannedonly_opendir,
+ .readdir = scannedonly_readdir,
+ .seekdir = scannedonly_seekdir,
+ .telldir = scannedonly_telldir,
+ .rewind_dir = scannedonly_rewinddir,
+ .closedir = scannedonly_closedir,
+ .rmdir = scannedonly_rmdir,
+ .stat = scannedonly_stat,
+ .lstat = scannedonly_lstat,
+ .open = scannedonly_open,
+ .close_fn = scannedonly_close,
+ .rename = scannedonly_rename,
+ .unlink = scannedonly_unlink,
+ .connect_fn = scannedonly_connect
+};
+
+NTSTATUS vfs_scannedonly_init(void)
+{
+ return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "scannedonly",
+ &vfs_scannedonly_fns);
+}
diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c
index 312160c026..a3de30e808 100644
--- a/source3/modules/vfs_zfsacl.c
+++ b/source3/modules/vfs_zfsacl.c
@@ -106,6 +106,7 @@ static bool zfs_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
ace_t *acebuf;
SMB4ACE_T *smbace;
TALLOC_CTX *mem_ctx;
+ bool have_special_id = false;
/* allocate the field of ZFS aces */
mem_ctx = talloc_tos();
@@ -140,8 +141,17 @@ static bool zfs_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
aceprop->who.special_id));
continue; /* don't add it !!! */
}
+ have_special_id = true;
}
}
+
+ if (!have_special_id
+ && lp_parm_bool(fsp->conn->params->service, "zfsacl",
+ "denymissingspecial", false)) {
+ errno = EACCES;
+ return false;
+ }
+
SMB_ASSERT(i == naces);
/* store acl */
diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
index a197c51ac8..6149f974ac 100644
--- a/source3/passdb/lookup_sid.c
+++ b/source3/passdb/lookup_sid.c
@@ -75,8 +75,7 @@ bool lookup_name(TALLOC_CTX *mem_ctx,
/* It's our own domain, lookup the name in passdb */
if (lookup_global_sam_name(name, flags, &rid, &type)) {
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, rid);
+ sid_compose(&sid, get_global_sam_sid(), rid);
goto ok;
}
TALLOC_FREE(tmp_ctx);
@@ -96,8 +95,7 @@ bool lookup_name(TALLOC_CTX *mem_ctx,
/* Explicit request for a name in BUILTIN */
if (lookup_builtin_name(name, &rid)) {
- sid_copy(&sid, &global_sid_Builtin);
- sid_append_rid(&sid, rid);
+ sid_compose(&sid, &global_sid_Builtin, rid);
type = SID_NAME_ALIAS;
goto ok;
}
@@ -215,8 +213,7 @@ bool lookup_name(TALLOC_CTX *mem_ctx,
lookup_builtin_name(name, &rid))
{
domain = talloc_strdup(tmp_ctx, builtin_domain_name());
- sid_copy(&sid, &global_sid_Builtin);
- sid_append_rid(&sid, rid);
+ sid_compose(&sid, &global_sid_Builtin, rid);
type = SID_NAME_ALIAS;
goto ok;
}
@@ -230,8 +227,7 @@ bool lookup_name(TALLOC_CTX *mem_ctx,
lookup_global_sam_name(name, flags, &rid, &type))
{
domain = talloc_strdup(tmp_ctx, get_global_sam_name());
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, rid);
+ sid_compose(&sid, get_global_sam_sid(), rid);
goto ok;
}
@@ -544,8 +540,7 @@ static bool lookup_rids(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
for (i=0; i<num_rids; i++) {
DOM_SID sid;
- sid_copy(&sid, domain_sid);
- sid_append_rid(&sid, rids[i]);
+ sid_compose(&sid, domain_sid, rids[i]);
if (lookup_wellknown_sid(mem_ctx, &sid,
domain_name, &(*names)[i])) {
if ((*names)[i] == NULL) {
@@ -1192,9 +1187,8 @@ static void legacy_gid_to_sid(DOM_SID *psid, gid_t gid)
static bool legacy_sid_to_uid(const DOM_SID *psid, uid_t *puid)
{
enum lsa_SidType type;
- uint32 rid;
- if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
+ if (sid_check_is_in_our_domain(psid)) {
union unid_t id;
bool ret;
@@ -1235,7 +1229,6 @@ done:
static bool legacy_sid_to_gid(const DOM_SID *psid, gid_t *pgid)
{
- uint32 rid;
GROUP_MAP map;
union unid_t id;
enum lsa_SidType type;
@@ -1257,7 +1250,7 @@ static bool legacy_sid_to_gid(const DOM_SID *psid, gid_t *pgid)
return false;
}
- if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
+ if (sid_check_is_in_our_domain(psid)) {
bool ret;
become_root();
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index b2c3b948f1..3ced150803 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -216,8 +216,7 @@ static NTSTATUS samu_set_unix_internal(struct samu *user, const struct passwd *p
return NT_STATUS_ACCESS_DENIED;
}
- sid_copy( &user_sid, get_global_sam_sid() );
- sid_append_rid( &user_sid, user_rid );
+ sid_compose(&user_sid, get_global_sam_sid(), user_rid);
if ( !pdb_set_user_sid(user, &user_sid, PDB_SET) ) {
DEBUG(3, ("pdb_set_user_sid failed\n"));
diff --git a/source3/passdb/pdb_compat.c b/source3/passdb/pdb_compat.c
index 9967eb53ad..b65be70758 100644
--- a/source3/passdb/pdb_compat.c
+++ b/source3/passdb/pdb_compat.c
@@ -60,10 +60,9 @@ bool pdb_set_user_sid_from_rid (struct samu *sampass, uint32 rid, enum pdb_value
return False;
}
- sid_copy(&u_sid, global_sam_sid);
-
- if (!sid_append_rid(&u_sid, rid))
+ if (!sid_compose(&u_sid, global_sam_sid, rid)) {
return False;
+ }
if (!pdb_set_user_sid(sampass, &u_sid, flag))
return False;
@@ -87,10 +86,9 @@ bool pdb_set_group_sid_from_rid (struct samu *sampass, uint32 grid, enum pdb_val
return False;
}
- sid_copy(&g_sid, global_sam_sid);
-
- if (!sid_append_rid(&g_sid, grid))
+ if (!sid_compose(&g_sid, global_sam_sid, grid)) {
return False;
+ }
if (!pdb_set_group_sid(sampass, &g_sid, flag))
return False;
diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c
index 30775e49fe..d7fc02f807 100644
--- a/source3/passdb/pdb_get_set.c
+++ b/source3/passdb/pdb_get_set.c
@@ -239,8 +239,7 @@ const DOM_SID *pdb_get_group_sid(struct samu *sampass)
/* Just set it to the 'Domain Users' RID of 512 which will
always resolve to a name */
- sid_copy( gsid, get_global_sam_sid() );
- sid_append_rid( gsid, DOMAIN_GROUP_RID_USERS );
+ sid_compose(gsid, get_global_sam_sid(), DOMAIN_GROUP_RID_USERS);
sampass->group_sid = gsid;
@@ -552,8 +551,8 @@ bool pdb_set_group_sid(struct samu *sampass, const DOM_SID *g_sid, enum pdb_valu
if ( sid_to_gid( g_sid, &gid ) ) {
sid_copy(sampass->group_sid, g_sid);
} else {
- sid_copy( sampass->group_sid, get_global_sam_sid() );
- sid_append_rid( sampass->group_sid, DOMAIN_GROUP_RID_USERS );
+ sid_compose(sampass->group_sid, get_global_sam_sid(),
+ DOMAIN_GROUP_RID_USERS);
}
DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n",
@@ -876,6 +875,7 @@ bool pdb_set_lanman_passwd(struct samu *sampass, const uint8 pwd[LM_HASH_LEN], e
bool pdb_set_pw_history(struct samu *sampass, const uint8 *pwd, uint32 historyLen, enum pdb_value_state flag)
{
if (historyLen && pwd){
+ data_blob_free(&(sampass->nt_pw_his));
sampass->nt_pw_his = data_blob_talloc(sampass,
pwd, historyLen*PW_HISTORY_ENTRY_LEN);
if (!sampass->nt_pw_his.length) {
@@ -980,6 +980,9 @@ bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext)
{
uchar new_lanman_p16[LM_HASH_LEN];
uchar new_nt_p16[NT_HASH_LEN];
+ uchar *pwhistory;
+ uint32 pwHistLen;
+ uint32 current_history_len;
if (!plaintext)
return False;
@@ -1009,68 +1012,80 @@ bool pdb_set_plaintext_passwd(struct samu *sampass, const char *plaintext)
if (!pdb_set_pass_last_set_time (sampass, time(NULL), PDB_CHANGED))
return False;
- /* Store the password history. */
- if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) {
- uchar *pwhistory;
- uint32 pwHistLen;
- pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
- if (pwHistLen != 0){
- uint32 current_history_len;
- /* We need to make sure we don't have a race condition here - the
- account policy history length can change between when the pw_history
- was first loaded into the struct samu struct and now.... JRA. */
- pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
-
- if (current_history_len != pwHistLen) {
- /* After closing and reopening struct samu the history
- values will sync up. We can't do this here. */
-
- /* current_history_len > pwHistLen is not a problem - we
- have more history than we need. */
-
- if (current_history_len < pwHistLen) {
- /* Ensure we have space for the needed history. */
- uchar *new_history = (uchar *)TALLOC(sampass,
- pwHistLen*PW_HISTORY_ENTRY_LEN);
- if (!new_history) {
- return False;
- }
-
- /* And copy it into the new buffer. */
- if (current_history_len) {
- memcpy(new_history, pwhistory,
- current_history_len*PW_HISTORY_ENTRY_LEN);
- }
- /* Clearing out any extra space. */
- memset(&new_history[current_history_len*PW_HISTORY_ENTRY_LEN],
- '\0', (pwHistLen-current_history_len)*PW_HISTORY_ENTRY_LEN);
- /* Finally replace it. */
- pwhistory = new_history;
- }
- }
- if (pwhistory && pwHistLen){
- /* Make room for the new password in the history list. */
- if (pwHistLen > 1) {
- memmove(&pwhistory[PW_HISTORY_ENTRY_LEN],
- pwhistory, (pwHistLen -1)*PW_HISTORY_ENTRY_LEN );
- }
- /* Create the new salt as the first part of the history entry. */
- generate_random_buffer(pwhistory, PW_HISTORY_SALT_LEN);
-
- /* Generate the md5 hash of the salt+new password as the second
- part of the history entry. */
-
- E_md5hash(pwhistory, new_nt_p16, &pwhistory[PW_HISTORY_SALT_LEN]);
- pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED);
- } else {
- DEBUG (10,("pdb_get_set.c: pdb_set_plaintext_passwd: pwhistory was NULL!\n"));
- }
- } else {
- /* Set the history length to zero. */
- pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED);
+ if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) == 0) {
+ /*
+ * No password history for non-user accounts
+ */
+ return true;
+ }
+
+ pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHistLen);
+
+ if (pwHistLen == 0) {
+ /* Set the history length to zero. */
+ pdb_set_pw_history(sampass, NULL, 0, PDB_CHANGED);
+ return true;
+ }
+
+ /*
+ * We need to make sure we don't have a race condition here -
+ * the account policy history length can change between when
+ * the pw_history was first loaded into the struct samu struct
+ * and now.... JRA.
+ */
+ pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
+
+ if ((current_history_len != 0) && (pwhistory == NULL)) {
+ DEBUG(1, ("pdb_set_plaintext_passwd: pwhistory == NULL!\n"));
+ return false;
+ }
+
+ if (current_history_len < pwHistLen) {
+ /*
+ * Ensure we have space for the needed history. This
+ * also takes care of an account which did not have
+ * any history at all so far, i.e. pwhistory==NULL
+ */
+ uchar *new_history = talloc_zero_array(
+ sampass, uchar,
+ pwHistLen*PW_HISTORY_ENTRY_LEN);
+
+ if (!new_history) {
+ return False;
}
+
+ memcpy(new_history, pwhistory,
+ current_history_len*PW_HISTORY_ENTRY_LEN);
+
+ pwhistory = new_history;
}
+ /*
+ * Make room for the new password in the history list.
+ */
+ if (pwHistLen > 1) {
+ memmove(&pwhistory[PW_HISTORY_ENTRY_LEN], pwhistory,
+ (pwHistLen-1)*PW_HISTORY_ENTRY_LEN );
+ }
+
+ /*
+ * Fill the salt area with 0-s: this indicates that
+ * a plain nt hash is stored in the has area.
+ * The old format was to store a 16 byte salt and
+ * then an md5hash of the nt_hash concatenated with
+ * the salt.
+ */
+ memset(pwhistory, 0, PW_HISTORY_SALT_LEN);
+
+ /*
+ * Store the plain nt hash in the second 16 bytes.
+ * The old format was to store the md5 hash of
+ * the salt+newpw.
+ */
+ memcpy(&pwhistory[PW_HISTORY_SALT_LEN], new_nt_p16, SALTED_MD5_HASH_LEN);
+
+ pdb_set_pw_history(sampass, pwhistory, pwHistLen, PDB_CHANGED);
+
return True;
}
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index de46254dde..bd85ded138 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -1472,8 +1472,7 @@ static bool lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid,
DEBUG(5,("lookup_global_sam_rid: looking up RID %u.\n",
(unsigned int)rid));
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, rid);
+ sid_compose(&sid, get_global_sam_sid(), rid);
/* see if the passdb can help us with the name of the user */
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index 90ac8e5ffa..30b27d4596 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -915,9 +915,9 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
pwHistLen = MIN(pwHistLen, MAX_PW_HISTORY_LEN);
- if ((pwhist = TALLOC_ARRAY(ctx, uint8,
- pwHistLen * PW_HISTORY_ENTRY_LEN)) ==
- NULL){
+ pwhist = TALLOC_ARRAY(ctx, uint8,
+ pwHistLen * PW_HISTORY_ENTRY_LEN);
+ if (pwhist == NULL) {
DEBUG(0, ("init_sam_from_ldap: talloc failed!\n"));
goto fn_exit;
}
@@ -6394,9 +6394,8 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location)
trim_char( uri, '\"', '\"' );
nt_status = pdb_init_ldapsam_common(pdb_method, uri);
- if (uri) {
- TALLOC_FREE(uri);
- }
+
+ TALLOC_FREE(uri);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
diff --git a/source3/passdb/util_unixsids.c b/source3/passdb/util_unixsids.c
index ad51253058..afda253c70 100644
--- a/source3/passdb/util_unixsids.c
+++ b/source3/passdb/util_unixsids.c
@@ -37,14 +37,12 @@ bool sid_check_is_in_unix_users(const DOM_SID *sid)
bool uid_to_unix_users_sid(uid_t uid, DOM_SID *sid)
{
- sid_copy(sid, &global_sid_Unix_Users);
- return sid_append_rid(sid, (uint32_t)uid);
+ return sid_compose(sid, &global_sid_Unix_Users, uid);
}
bool gid_to_unix_groups_sid(gid_t gid, DOM_SID *sid)
{
- sid_copy(sid, &global_sid_Unix_Groups);
- return sid_append_rid(sid, (uint32_t)gid);
+ return sid_compose(sid, &global_sid_Unix_Groups, gid);
}
const char *unix_users_domain_name(void)
@@ -55,17 +53,20 @@ const char *unix_users_domain_name(void)
bool lookup_unix_user_name(const char *name, DOM_SID *sid)
{
struct passwd *pwd;
+ bool ret;
pwd = getpwnam_alloc(talloc_autofree_context(), name);
if (pwd == NULL) {
return False;
}
- sid_copy(sid, &global_sid_Unix_Users);
- sid_append_rid(sid, (uint32_t)pwd->pw_uid); /* For 64-bit uid's we have enough
- * space ... */
+ /*
+ * For 64-bit uid's we have enough space in the whole SID,
+ * should they become necessary
+ */
+ ret = sid_compose(sid, &global_sid_Unix_Users, pwd->pw_uid);
TALLOC_FREE(pwd);
- return True;
+ return ret;
}
bool sid_check_is_unix_groups(const DOM_SID *sid)
@@ -98,8 +99,9 @@ bool lookup_unix_group_name(const char *name, DOM_SID *sid)
return False;
}
- sid_copy(sid, &global_sid_Unix_Groups);
- sid_append_rid(sid, (uint32_t)grp->gr_gid); /* For 64-bit uid's we have enough
- * space ... */
- return True;
+ /*
+ * For 64-bit gid's we have enough space in the whole SID,
+ * should they become necessary
+ */
+ return sid_compose(sid, &global_sid_Unix_Groups, grp->gr_gid);
}
diff --git a/source3/passdb/util_wellknown.c b/source3/passdb/util_wellknown.c
index 2af68b7e7c..0c45faab46 100644
--- a/source3/passdb/util_wellknown.c
+++ b/source3/passdb/util_wellknown.c
@@ -160,8 +160,8 @@ bool lookup_wellknown_name(TALLOC_CTX *mem_ctx, const char *name,
for (j=0; users[j].name != NULL; j++) {
if ( strequal(users[j].name, name) ) {
- sid_copy(sid, special_domains[i].sid);
- sid_append_rid(sid, users[j].rid);
+ sid_compose(sid, special_domains[i].sid,
+ users[j].rid);
*domain = talloc_strdup(
mem_ctx, special_domains[i].name);
return True;
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 1f306512af..7aef424961 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -5398,8 +5398,8 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
if ( IS_DC ) {
DOM_SID domadmins_sid;
- sid_copy(&domadmins_sid, get_global_sam_sid());
- sid_append_rid(&domadmins_sid, DOMAIN_GROUP_RID_ADMINS);
+ sid_compose(&domadmins_sid, get_global_sam_sid(),
+ DOMAIN_GROUP_RID_ADMINS);
sa = PRINTER_ACE_FULL_CONTROL;
init_sec_ace(&ace[i++], &domadmins_sid,
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index 03884479f9..e484209cbe 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -154,10 +154,8 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
uint8_t authoritative;
int validation_level = 3;
fstring clnt_name_slash;
- uint8 zeros[16];
ZERO_STRUCT(ret_creds);
- ZERO_STRUCT(zeros);
logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonLevel);
if (!logon) {
@@ -302,7 +300,6 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
int validation_level = 3;
const char *workstation_name_slash;
const char *server_name_slash;
- uint8 zeros[16];
struct netr_Authenticator clnt_creds;
struct netr_Authenticator ret_creds;
union netr_LogonLevel *logon = NULL;
@@ -314,7 +311,6 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
*info3 = NULL;
- ZERO_STRUCT(zeros);
ZERO_STRUCT(ret_creds);
ZERO_STRUCT(lm);
@@ -414,7 +410,6 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli,
int validation_level = 3;
const char *workstation_name_slash;
const char *server_name_slash;
- uint8 zeros[16];
union netr_LogonLevel *logon = NULL;
struct netr_NetworkInfo *network_info;
uint8_t authoritative;
@@ -425,8 +420,6 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli,
*info3 = NULL;
- ZERO_STRUCT(zeros);
-
ZERO_STRUCT(lm);
ZERO_STRUCT(nt);
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index e903f0e974..857040ec8b 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -335,8 +335,7 @@ static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, SEC_DESC **sd, size_t *s
SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
/* Add Full Access for Domain Admins */
- sid_copy(&adm_sid, get_global_sam_sid());
- sid_append_rid(&adm_sid, DOMAIN_GROUP_RID_ADMINS);
+ sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_GROUP_RID_ADMINS);
init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
map->generic_all, 0);
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index 8f4381cde1..66f3bd3130 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -1057,8 +1057,8 @@ static NTSTATUS _netr_LogonSamLogon_base(pipes_struct *p,
NTSTATUS status = NT_STATUS_OK;
union netr_LogonLevel *logon = r->in.logon;
const char *nt_username, *nt_domain, *nt_workstation;
- auth_usersupplied_info *user_info = NULL;
- auth_serversupplied_info *server_info = NULL;
+ struct auth_usersupplied_info *user_info = NULL;
+ struct auth_serversupplied_info *server_info = NULL;
struct auth_context *auth_context = NULL;
uint8_t pipe_session_key[16];
bool process_creds = true;
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 6b40385744..3626cbdf2a 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -145,8 +145,8 @@ static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd
/* Add Full Access for Domain Admins if we are a DC */
if ( IS_DC ) {
- sid_copy( &domadmin_sid, get_global_sam_sid() );
- sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
+ sid_compose(&domadmin_sid, get_global_sam_sid(),
+ DOMAIN_GROUP_RID_ADMINS);
init_sec_ace(&ace[i++], &domadmin_sid,
SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
}
@@ -266,8 +266,8 @@ void map_max_allowed_access(const NT_USER_TOKEN *nt_token,
/* Full access for DOMAIN\Domain Admins. */
if ( IS_DC ) {
DOM_SID domadmin_sid;
- sid_copy( &domadmin_sid, get_global_sam_sid() );
- sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
+ sid_compose(&domadmin_sid, get_global_sam_sid(),
+ DOMAIN_GROUP_RID_ADMINS);
if (is_sid_in_token(nt_token, &domadmin_sid)) {
*pacc_requested |= GENERIC_ALL_ACCESS;
return;
@@ -5837,8 +5837,9 @@ NTSTATUS _samr_CreateDomainGroup(pipes_struct *p,
return status;
}
- if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
+ if (!sid_check_is_domain(&dinfo->sid)) {
return NT_STATUS_ACCESS_DENIED;
+ }
name = r->in.name->string;
if (name == NULL) {
@@ -5898,8 +5899,9 @@ NTSTATUS _samr_CreateDomAlias(pipes_struct *p,
return result;
}
- if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
+ if (!sid_check_is_domain(&dinfo->sid)) {
return NT_STATUS_ACCESS_DENIED;
+ }
name = r->in.alias_name->string;
@@ -6277,8 +6279,9 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p,
/* this should not be hard-coded like this */
- if (!sid_equal(&dinfo->sid, get_global_sam_sid()))
+ if (!sid_check_is_domain(&dinfo->sid)) {
return NT_STATUS_ACCESS_DENIED;
+ }
sid_compose(&info_sid, &dinfo->sid, r->in.rid);
diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c
index d35557e5bd..a2d1d0716d 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -1033,6 +1033,13 @@ WERROR _srvsvc_NetFileEnum(pipes_struct *p,
return WERR_UNKNOWN_LEVEL;
}
+ if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
+ p->server_info->ptok)) {
+ DEBUG(1, ("Enumerating files only allowed for "
+ "administrators\n"));
+ return WERR_ACCESS_DENIED;
+ }
+
ctx = talloc_tos();
ctr3 = r->in.info_ctr->ctr.ctr3;
if (!ctr3) {
@@ -1185,6 +1192,13 @@ WERROR _srvsvc_NetConnEnum(pipes_struct *p,
DEBUG(5,("_srvsvc_NetConnEnum: %d\n", __LINE__));
+ if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
+ p->server_info->ptok)) {
+ DEBUG(1, ("Enumerating connections only allowed for "
+ "administrators\n"));
+ return WERR_ACCESS_DENIED;
+ }
+
switch (r->in.info_ctr->level) {
case 0:
werr = init_srv_conn_info_0(r->in.info_ctr->ctr.ctr0,
@@ -1216,6 +1230,13 @@ WERROR _srvsvc_NetSessEnum(pipes_struct *p,
DEBUG(5,("_srvsvc_NetSessEnum: %d\n", __LINE__));
+ if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
+ p->server_info->ptok)) {
+ DEBUG(1, ("Enumerating sessions only allowed for "
+ "administrators\n"));
+ return WERR_ACCESS_DENIED;
+ }
+
switch (r->in.info_ctr->level) {
case 0:
werr = init_srv_sess_info_0(p,
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index 2da36b2fe6..dcefc82bba 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -1008,6 +1008,59 @@ static NTSTATUS check_oem_password(const char *user,
return NT_STATUS_WRONG_PASSWORD;
}
+bool password_in_history(uint8_t nt_pw[NT_HASH_LEN],
+ uint32_t pw_history_len,
+ const uint8_t *pw_history)
+{
+ static const uint8_t zero_md5_nt_pw[SALTED_MD5_HASH_LEN] = { 0, };
+ int i;
+
+ dump_data(100, nt_pw, NT_HASH_LEN);
+ dump_data(100, pw_history, PW_HISTORY_ENTRY_LEN * pw_history_len);
+
+ for (i=0; i<pw_history_len; i++) {
+ uint8_t new_nt_pw_salted_md5_hash[SALTED_MD5_HASH_LEN];
+ const uint8_t *current_salt;
+ const uint8_t *old_nt_pw_salted_md5_hash;
+
+ current_salt = &pw_history[i*PW_HISTORY_ENTRY_LEN];
+ old_nt_pw_salted_md5_hash = current_salt + PW_HISTORY_SALT_LEN;
+
+ if (memcmp(zero_md5_nt_pw, old_nt_pw_salted_md5_hash,
+ SALTED_MD5_HASH_LEN) == 0) {
+ /* Ignore zero valued entries. */
+ continue;
+ }
+
+ if (memcmp(zero_md5_nt_pw, current_salt,
+ PW_HISTORY_SALT_LEN) == 0)
+ {
+ /*
+ * New format: zero salt and then plain nt hash.
+ * Directly compare the hashes.
+ */
+ if (memcmp(nt_pw, old_nt_pw_salted_md5_hash,
+ SALTED_MD5_HASH_LEN) == 0)
+ {
+ return true;
+ }
+ } else {
+ /*
+ * Old format: md5sum of salted nt hash.
+ * Create salted version of new pw to compare.
+ */
+ E_md5hash(current_salt, nt_pw, new_nt_pw_salted_md5_hash);
+
+ if (memcmp(new_nt_pw_salted_md5_hash,
+ old_nt_pw_salted_md5_hash,
+ SALTED_MD5_HASH_LEN) == 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
/***********************************************************
This routine takes the given password and checks it against
the password history. Returns True if this password has been
@@ -1017,11 +1070,8 @@ static NTSTATUS check_oem_password(const char *user,
static bool check_passwd_history(struct samu *sampass, const char *plaintext)
{
uchar new_nt_p16[NT_HASH_LEN];
- uchar zero_md5_nt_pw[SALTED_MD5_HASH_LEN];
const uint8 *nt_pw;
const uint8 *pwhistory;
- bool found = False;
- int i;
uint32 pwHisLen, curr_pwHisLen;
pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY, &pwHisLen);
@@ -1048,30 +1098,13 @@ static bool check_passwd_history(struct samu *sampass, const char *plaintext)
return True;
}
- dump_data(100, new_nt_p16, NT_HASH_LEN);
- dump_data(100, pwhistory, PW_HISTORY_ENTRY_LEN*pwHisLen);
-
- memset(zero_md5_nt_pw, '\0', SALTED_MD5_HASH_LEN);
- for (i=0; i<pwHisLen; i++) {
- uchar new_nt_pw_salted_md5_hash[SALTED_MD5_HASH_LEN];
- const uchar *current_salt = &pwhistory[i*PW_HISTORY_ENTRY_LEN];
- const uchar *old_nt_pw_salted_md5_hash = &pwhistory[(i*PW_HISTORY_ENTRY_LEN)+
- PW_HISTORY_SALT_LEN];
- if (!memcmp(zero_md5_nt_pw, old_nt_pw_salted_md5_hash, SALTED_MD5_HASH_LEN)) {
- /* Ignore zero valued entries. */
- continue;
- }
- /* Create salted versions of new to compare. */
- E_md5hash(current_salt, new_nt_p16, new_nt_pw_salted_md5_hash);
-
- if (!memcmp(new_nt_pw_salted_md5_hash, old_nt_pw_salted_md5_hash, SALTED_MD5_HASH_LEN)) {
- DEBUG(1,("check_passwd_history: proposed new password for user %s found in history list !\n",
- pdb_get_username(sampass) ));
- found = True;
- break;
- }
+ if (password_in_history(new_nt_p16, pwHisLen, pwhistory)) {
+ DEBUG(1,("check_passwd_history: proposed new password for "
+ "user %s found in history list !\n",
+ pdb_get_username(sampass) ));
+ return true;
}
- return found;
+ return false;
}
/***********************************************************
@@ -1156,7 +1189,7 @@ NTSTATUS change_oem_password(struct samu *hnd, char *old_passwd, char *new_passw
}
}
- /* removed calculation here, becuase passdb now calculates
+ /* removed calculation here, because passdb now calculates
based on policy. jmcd */
if ((can_change_time != 0) && (time(NULL) < can_change_time)) {
DEBUG(1, ("user %s cannot change password now, must "
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 05c3c709a1..ca1ac47fa0 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -336,6 +336,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
become_user(conn, fsp->vuid);
became_user = True;
}
+ fsp->delete_on_close = true;
set_delete_on_close_lck(lck, True, &current_user.ut);
if (became_user) {
unbecome_user();
@@ -481,6 +482,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
* the delete on close flag. JRA.
*/
+ fsp->delete_on_close = false;
set_delete_on_close_lck(lck, False, NULL);
done:
@@ -924,6 +926,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
struct share_mode_lock *lck = NULL;
bool delete_dir = False;
NTSTATUS status = NT_STATUS_OK;
+ NTSTATUS status1 = NT_STATUS_OK;
/*
* NT can set delete_on_close of the last open
@@ -958,6 +961,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
}
send_stat_cache_delete_message(fsp->fsp_name->base_name);
set_delete_on_close_lck(lck, True, &current_user.ut);
+ fsp->delete_on_close = true;
if (became_user) {
unbecome_user();
}
@@ -1022,9 +1026,9 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
fsp, NT_STATUS_OK);
}
- status = fd_close(fsp);
+ status1 = fd_close(fsp);
- if (!NT_STATUS_IS_OK(status)) {
+ if (!NT_STATUS_IS_OK(status1)) {
DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
fsp_str_dbg(fsp), fsp->fh->fd, errno,
strerror(errno)));
@@ -1042,6 +1046,9 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
out:
TALLOC_FREE(lck);
+ if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
+ status = status1;
+ }
return status;
}
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 5ce4a7b099..3fe3218762 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -1227,14 +1227,6 @@ bool is_visible_file(connection_struct *conn, const char *dir_path,
goto out;
}
- /* If it's a dfs symlink, ignore _hide xxxx_ options */
- if (lp_host_msdfs() &&
- lp_msdfs_root(SNUM(conn)) &&
- is_msdfs_link(conn, entry, NULL)) {
- ret = true;
- goto out;
- }
-
/* Create an smb_filename with stream_name == NULL. */
status = create_synthetic_smb_fname(talloc_tos(), entry, NULL,
pst, &smb_fname_base);
diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c
index 7d0a552956..631efce677 100644
--- a/source3/smbd/file_access.c
+++ b/source3/smbd/file_access.c
@@ -54,6 +54,17 @@ bool can_access_file_acl(struct connection_struct *conn,
status = se_access_check(secdesc, conn->server_info->ptok,
access_mask, &access_granted);
ret = NT_STATUS_IS_OK(status);
+
+ if (DEBUGLEVEL >= 10) {
+ DEBUG(10,("can_access_file_acl for file %s "
+ "access_mask 0x%x, access_granted 0x%x "
+ "access %s\n",
+ smb_fname_str_dbg(smb_fname),
+ (unsigned int)access_mask,
+ (unsigned int)access_granted,
+ ret ? "ALLOWED" : "DENIED" ));
+ NDR_PRINT_DEBUG(security_descriptor, secdesc);
+ }
out:
TALLOC_FREE(secdesc);
return ret;
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index 68fa795ba2..e6db5ec414 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -122,7 +122,6 @@ int conn_ctx_stack_ndx = 0;
struct vfs_init_function_entry *backends = NULL;
char *sparse_buf = NULL;
-char *LastDir = NULL;
/* Current number of oplocks we have outstanding. */
int32_t exclusive_oplocks_open = 0;
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 0db61f87a3..3cc967f4fd 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -131,7 +131,6 @@ extern int conn_ctx_stack_ndx;
struct vfs_init_function_entry;
extern struct vfs_init_function_entry *backends;
extern char *sparse_buf;
-extern char *LastDir;
/* Current number of oplocks we have outstanding. */
extern int32_t exclusive_oplocks_open;
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index 7ee6c9b59c..27115021bf 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -1569,7 +1569,9 @@ static bool check_share_info(int uLevel, char* id)
}
break;
case 1:
- if (strcmp(id,"B13BWz") != 0) {
+ /* Level-2 descriptor is allowed (and ignored) */
+ if (strcmp(id,"B13BWz") != 0 &&
+ strcmp(id,"B13BWzWWWzB9B") != 0) {
return False;
}
break;
@@ -2616,7 +2618,7 @@ static bool api_SetUserPassword(connection_struct *conn,uint16 vuid,
*/
{
- auth_serversupplied_info *server_info = NULL;
+ struct auth_serversupplied_info *server_info = NULL;
DATA_BLOB password = data_blob(pass1, strlen(pass1)+1);
if (NT_STATUS_IS_OK(check_plaintext_password(user,password,&server_info))) {
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 755ff5d6cd..2e63f7a395 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -248,7 +248,7 @@ static int register_homes_share(const char *username)
int register_existing_vuid(struct smbd_server_connection *sconn,
uint16 vuid,
- auth_serversupplied_info *server_info,
+ struct auth_serversupplied_info *server_info,
DATA_BLOB response_blob,
const char *smb_name)
{
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 828053811b..7342420a89 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -1109,6 +1109,10 @@ uint32_t map_canon_ace_perms(int snum,
}
}
+ if ((perms & S_IWUSR) && lp_dos_filemode(snum)) {
+ nt_mask |= (SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER|DELETE_ACCESS);
+ }
+
DEBUG(10,("map_canon_ace_perms: Mapped (UNIX) %x to (NT) %x\n",
(unsigned int)perms, (unsigned int)nt_mask ));
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index b2d98bfbc0..b6316aac46 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -5368,8 +5368,12 @@ void reply_rmdir(struct smb_request *req)
goto out;
}
- close_file(req, fsp, NORMAL_CLOSE);
- reply_outbuf(req, 0, 0);
+ status = close_file(req, fsp, NORMAL_CLOSE);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ } else {
+ reply_outbuf(req, 0, 0);
+ }
dptr_closepath(sconn, smb_dname->base_name, req->smbpid);
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 612cf2231a..ae99127db2 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -41,7 +41,7 @@ struct pending_auth_data {
is set approriately
*/
static NTSTATUS do_map_to_guest(NTSTATUS status,
- auth_serversupplied_info **server_info,
+ struct auth_serversupplied_info **server_info,
const char *user, const char *domain)
{
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
@@ -128,10 +128,10 @@ static void reply_sesssetup_blob(struct smb_request *req,
Do a 'guest' logon, getting back the
****************************************************************************/
-static NTSTATUS check_guest_password(auth_serversupplied_info **server_info)
+static NTSTATUS check_guest_password(struct auth_serversupplied_info **server_info)
{
struct auth_context *auth_context;
- auth_usersupplied_info *user_info = NULL;
+ struct auth_usersupplied_info *user_info = NULL;
NTSTATUS nt_status;
unsigned char chal[8];
@@ -244,7 +244,7 @@ static void reply_spnego_kerberos(struct smb_request *req,
NTSTATUS ret = NT_STATUS_OK;
struct PAC_DATA *pac_data = NULL;
DATA_BLOB ap_rep, ap_rep_wrapped, response;
- auth_serversupplied_info *server_info = NULL;
+ struct auth_serversupplied_info *server_info = NULL;
DATA_BLOB session_key = data_blob_null;
uint8 tok_id[2];
DATA_BLOB nullblob = data_blob_null;
@@ -1388,8 +1388,8 @@ void reply_sesssetup_and_X(struct smb_request *req)
const char *native_os;
const char *native_lanman;
const char *primary_domain;
- auth_usersupplied_info *user_info = NULL;
- auth_serversupplied_info *server_info = NULL;
+ struct auth_usersupplied_info *user_info = NULL;
+ struct auth_serversupplied_info *server_info = NULL;
uint16 smb_flag2 = req->flags2;
NTSTATUS nt_status;
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 2ce61eed30..5acec70f54 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -706,26 +706,7 @@ const char *vfs_readdirname(connection_struct *conn, void *p,
int vfs_ChDir(connection_struct *conn, const char *path)
{
- int res;
-
- if (!LastDir) {
- LastDir = SMB_STRDUP("");
- }
-
- if (strcsequal(path,"."))
- return(0);
-
- if (*path == '/' && strcsequal(LastDir,path))
- return(0);
-
- DEBUG(4,("vfs_ChDir to %s\n",path));
-
- res = SMB_VFS_CHDIR(conn,path);
- if (!res) {
- SAFE_FREE(LastDir);
- LastDir = SMB_STRDUP(path);
- }
- return(res);
+ return SMB_VFS_CHDIR(conn,path);
}
/*******************************************************************
diff --git a/source3/utils/net_groupmap.c b/source3/utils/net_groupmap.c
index 7180a953bb..e82c7b14f2 100644
--- a/source3/utils/net_groupmap.c
+++ b/source3/utils/net_groupmap.c
@@ -299,8 +299,7 @@ static int net_groupmap_add(struct net_context *c, int argc, const char **argv)
/* append the rid to our own domain/machine SID if we don't have a full SID */
if ( !string_sid[0] ) {
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, rid);
+ sid_compose(&sid, get_global_sam_sid(), rid);
sid_to_fstring(string_sid, &sid);
}
@@ -610,8 +609,7 @@ static int net_groupmap_set(struct net_context *c, int argc, const char **argv)
}
}
- sid_copy(&map.sid, get_global_sam_sid());
- sid_append_rid(&map.sid, c->opt_rid);
+ sid_compose(&map.sid, get_global_sam_sid(), c->opt_rid);
map.sid_name_use = SID_NAME_DOM_GRP;
fstrcpy(map.nt_name, ntgroup);
@@ -795,8 +793,7 @@ static bool print_alias_memberships(TALLOC_CTX *mem_ctx,
for (i = 0; i < num_alias_rids; i++) {
DOM_SID alias;
- sid_copy(&alias, domain_sid);
- sid_append_rid(&alias, alias_rids[i]);
+ sid_compose(&alias, domain_sid, alias_rids[i]);
printf("%s\n", sid_string_tos(&alias));
}
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index 7dc8c1dd2c..762af716f5 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -3889,8 +3889,8 @@ static NTSTATUS rpc_fetch_domain_aliases(struct rpc_pipe_client *pipe_hnd,
sid_array.sids[j].sid);
}
- sid_copy(&alias.sid, domain_sid);
- sid_append_rid(&alias.sid, groups->entries[i].idx);
+ sid_compose(&alias.sid, domain_sid,
+ groups->entries[i].idx);
push_alias(mem_ctx, &alias);
}
@@ -5450,8 +5450,7 @@ static NTSTATUS rpc_trustdom_del_internals(struct net_context *c,
}
/* append the rid to the domain sid */
- sid_copy(&trust_acct_sid, domain_sid);
- if (!sid_append_rid(&trust_acct_sid, user_rids.ids[0])) {
+ if (!sid_compose(&trust_acct_sid, domain_sid, user_rids.ids[0])) {
goto done;
}
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index 57e4251543..e018c28c30 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -223,7 +223,7 @@ DATA_BLOB get_challenge(void)
static DATA_BLOB chal;
if (opt_challenge.length)
return opt_challenge;
-
+
chal = data_blob(NULL, 8);
generate_random_buffer(chal.data, chal.length);
@@ -242,7 +242,7 @@ static bool parse_ntlm_auth_domain_user(const char *domuser, fstring domain,
if (!p) {
return False;
}
-
+
fstrcpy(user, p+1);
fstrcpy(domain, domuser);
domain[PTR_DIFF(p, domuser)] = 0;
@@ -300,23 +300,23 @@ int get_pam_winbind_config()
{
int ctrl = 0;
dictionary *d = NULL;
-
+
if (!opt_pam_winbind_conf || !*opt_pam_winbind_conf) {
opt_pam_winbind_conf = PAM_WINBIND_CONFIG_FILE;
}
d = iniparser_load(CONST_DISCARD(char *, opt_pam_winbind_conf));
-
+
if (!d) {
return 0;
}
-
+
if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:krb5_auth"), false)) {
ctrl |= WINBIND_KRB5_AUTH;
}
iniparser_freedict(d);
-
+
return ctrl;
}
@@ -438,7 +438,7 @@ NTSTATUS contact_winbind_auth_crap(const char *username,
}
request.data.auth_crap.nt_resp_len = nt_response->length;
}
-
+
result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response);
SAFE_FREE(request.extra_data.data);
@@ -451,7 +451,7 @@ NTSTATUS contact_winbind_auth_crap(const char *username,
winbindd_free_response(&response);
return nt_status;
}
-
+
nt_status = (NT_STATUS(response.data.auth.nt_status));
if (!NT_STATUS_IS_OK(nt_status)) {
if (error_string)
@@ -533,7 +533,7 @@ static NTSTATUS contact_winbind_change_pswd_auth_crap(const char *username,
memcpy(request.data.chng_pswd_auth_crap.old_lm_hash_enc, old_lm_hash_enc.data, sizeof(request.data.chng_pswd_auth_crap.old_lm_hash_enc));
request.data.chng_pswd_auth_crap.old_lm_hash_enc_len = old_lm_hash_enc.length;
}
-
+
result = winbindd_request_response(WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, &request, &response);
/* Display response */
@@ -546,7 +546,7 @@ static NTSTATUS contact_winbind_change_pswd_auth_crap(const char *username,
winbindd_free_response(&response);
return nt_status;
}
-
+
nt_status = (NT_STATUS(response.data.auth.nt_status));
if (!NT_STATUS_IS_OK(nt_status))
{
@@ -557,7 +557,7 @@ static NTSTATUS contact_winbind_change_pswd_auth_crap(const char *username,
}
winbindd_free_response(&response);
-
+
return nt_status;
}
@@ -585,7 +585,7 @@ static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB
memcpy(lm_session_key->data, lm_key, 8);
memset(lm_session_key->data+8, '\0', 8);
}
-
+
if (memcmp(user_sess_key, zeros, 16) != 0) {
*user_session_key = data_blob_talloc(ntlmssp_state, user_sess_key, 16);
}
@@ -611,7 +611,7 @@ static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *u
struct samr_Password lm_pw, nt_pw;
nt_lm_owf_gen (opt_password, nt_pw.hash, lm_pw.hash);
-
+
nt_status = ntlm_password_check(ntlmssp_state,
true, true, 0,
&ntlmssp_state->chal,
@@ -621,7 +621,7 @@ static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *u
ntlmssp_state->user,
ntlmssp_state->domain,
&lm_pw, &nt_pw, user_session_key, lm_session_key);
-
+
if (NT_STATUS_IS_OK(nt_status)) {
ntlmssp_state->auth_context = talloc_asprintf(ntlmssp_state,
"%s%c%s", ntlmssp_state->domain,
@@ -674,7 +674,7 @@ static NTSTATUS ntlm_auth_start_ntlmssp_client(struct ntlmssp_state **client_ntl
if (opt_password) {
status = ntlmssp_set_password(*client_ntlmssp_state, opt_password);
-
+
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Could not set password: %s\n",
nt_errstr(status)));
@@ -689,7 +689,7 @@ static NTSTATUS ntlm_auth_start_ntlmssp_client(struct ntlmssp_state **client_ntl
static NTSTATUS ntlm_auth_start_ntlmssp_server(struct ntlmssp_state **ntlmssp_state)
{
NTSTATUS status = ntlmssp_server_start(ntlmssp_state);
-
+
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Could not start NTLMSSP server: %s\n",
nt_errstr(status)));
@@ -1091,7 +1091,7 @@ static void manage_squid_basic_request(struct ntlm_auth_state *state,
{
char *user, *pass;
user=buf;
-
+
pass=(char *)memchr(buf,' ',length);
if (!pass) {
DEBUG(2, ("Password not found. Denying access\n"));
@@ -1100,12 +1100,12 @@ static void manage_squid_basic_request(struct ntlm_auth_state *state,
}
*pass='\0';
pass++;
-
+
if (state->helper_mode == SQUID_2_5_BASIC) {
rfc1738_unescape(user);
rfc1738_unescape(pass);
}
-
+
if (check_plaintext_auth(user, pass, False)) {
x_fprintf(x_stdout, "OK\n");
} else {
@@ -1513,7 +1513,7 @@ static void manage_client_ntlmssp_targ(struct spnego_data spnego)
status = ntlmssp_update(client_ntlmssp_state,
spnego.negTokenTarg.responseToken,
&request);
-
+
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED from "
"ntlmssp_client_update, got: %s\n",
@@ -1530,7 +1530,7 @@ static void manage_client_ntlmssp_targ(struct spnego_data spnego)
spnego.negTokenTarg.supportedMech = (char *)OID_NTLMSSP;
spnego.negTokenTarg.responseToken = request;
spnego.negTokenTarg.mechListMIC = null_blob;
-
+
spnego_write_data(ctx, &to_server, &spnego);
data_blob_free(&request);
@@ -1684,7 +1684,7 @@ static void manage_gss_spnego_client_request(struct ntlm_auth_state *state,
/* We asked for a password and obviously got it :-) */
opt_password = SMB_STRNDUP((const char *)request.data, request.length);
-
+
if (opt_password == NULL) {
DEBUG(1, ("Out of memory\n"));
x_fprintf(x_stdout, "BH Out of memory\n");
@@ -1812,7 +1812,7 @@ static void manage_ntlm_server_1_request(struct ntlm_auth_state *state,
static char *plaintext_password;
static bool ntlm_server_1_user_session_key;
static bool ntlm_server_1_lm_session_key;
-
+
if (strequal(buf, ".")) {
if (!full_username && !username) {
x_fprintf(x_stdout, "Error: No username supplied!\n");
@@ -1842,7 +1842,7 @@ static void manage_ntlm_server_1_request(struct ntlm_auth_state *state,
if (full_username && !username) {
fstring fstr_user;
fstring fstr_domain;
-
+
if (!parse_ntlm_auth_domain_user(full_username, fstr_user, fstr_domain)) {
/* username might be 'tainted', don't print into our new-line deleimianted stream */
x_fprintf(x_stdout, "Error: Could not parse into domain and username\n");
@@ -1859,7 +1859,7 @@ static void manage_ntlm_server_1_request(struct ntlm_auth_state *state,
if (ntlm_server_1_lm_session_key)
flags |= WBFLAG_PAM_LMKEY;
-
+
if (ntlm_server_1_user_session_key)
flags |= WBFLAG_PAM_USER_SESSION_KEY;
@@ -1928,13 +1928,13 @@ static void manage_ntlm_server_1_request(struct ntlm_auth_state *state,
parameter = strstr_m(request, ":: ");
if (!parameter) {
parameter = strstr_m(request, ": ");
-
+
if (!parameter) {
DEBUG(0, ("Parameter not found!\n"));
x_fprintf(x_stdout, "Error: Parameter not found!\n.\n");
return;
}
-
+
parameter[0] ='\0';
parameter++;
parameter[0] ='\0';
@@ -2015,7 +2015,7 @@ static void manage_ntlm_change_password_1_request(struct ntlm_auth_state *state,
new_nt_pswd = data_blob(NULL, 516);
old_nt_hash_enc = data_blob(NULL, 16);
-
+
/* Calculate the MD4 hash (NT compatible) of the
* password */
E_md4hash(oldpswd, old_nt_hash);
@@ -2023,7 +2023,7 @@ static void manage_ntlm_change_password_1_request(struct ntlm_auth_state *state,
/* E_deshash returns false for 'long'
passwords (> 14 DOS chars).
-
+
Therefore, don't send a buffer
encrypted with the truncated hash
(it could allow an even easier
@@ -2052,12 +2052,12 @@ static void manage_ntlm_change_password_1_request(struct ntlm_auth_state *state,
encode_pw_buffer(new_nt_pswd.data, newpswd,
STR_UNICODE);
-
+
arcfour_crypt(new_nt_pswd.data, old_nt_hash, 516);
E_old_pw_hash(new_nt_hash, old_nt_hash,
old_nt_hash_enc.data);
}
-
+
if (!full_username && !username) {
x_fprintf(x_stdout, "Error: No username supplied!\n");
} else if ((!new_nt_pswd.data || !old_nt_hash_enc.data) &&
@@ -2066,11 +2066,11 @@ static void manage_ntlm_change_password_1_request(struct ntlm_auth_state *state,
"blobs supplied!\n");
} else {
char *error_string = NULL;
-
+
if (full_username && !username) {
fstring fstr_user;
fstring fstr_domain;
-
+
if (!parse_ntlm_auth_domain_user(full_username,
fstr_user,
fstr_domain)) {
@@ -2088,7 +2088,7 @@ static void manage_ntlm_change_password_1_request(struct ntlm_auth_state *state,
username = smb_xstrdup(fstr_user);
domain = smb_xstrdup(fstr_domain);
}
-
+
}
if(!NT_STATUS_IS_OK(contact_winbind_change_pswd_auth_crap(
@@ -2128,13 +2128,13 @@ static void manage_ntlm_change_password_1_request(struct ntlm_auth_state *state,
parameter = strstr_m(request, ":: ");
if (!parameter) {
parameter = strstr_m(request, ": ");
-
+
if (!parameter) {
DEBUG(0, ("Parameter not found!\n"));
x_fprintf(x_stdout, "Error: Parameter not found!\n.\n");
return;
}
-
+
parameter[0] ='\0';
parameter++;
parameter[0] ='\0';
diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c
index 06eedef920..ac41dc0ad0 100644
--- a/source3/utils/pdbedit.c
+++ b/source3/utils/pdbedit.c
@@ -68,8 +68,7 @@ static int get_sid_from_cli_string(DOM_SID *sid, const char *str_sid)
"a complete SID or RID!\n");
return -1;
}
- sid_copy(sid, get_global_sam_sid());
- sid_append_rid(sid, rid);
+ sid_compose(sid, get_global_sam_sid(), rid);
}
return 0;
diff --git a/source3/winbindd/idmap_hash/idmap_hash.c b/source3/winbindd/idmap_hash/idmap_hash.c
index 7d4dd2b5ab..1227b2a052 100644
--- a/source3/winbindd/idmap_hash/idmap_hash.c
+++ b/source3/winbindd/idmap_hash/idmap_hash.c
@@ -193,8 +193,7 @@ static NTSTATUS unixids_to_sids(struct idmap_domain *dom,
if (!hashed_domains[h_domain].sid)
continue;
- sid_copy(ids[i]->sid, hashed_domains[h_domain].sid);
- sid_append_rid(ids[i]->sid, h_rid);
+ sid_compose(ids[i]->sid, hashed_domains[h_domain].sid, h_rid);
ids[i]->status = ID_MAPPED;
}
diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c
index 189b088809..8bfe751a8b 100644
--- a/source3/winbindd/idmap_tdb.c
+++ b/source3/winbindd/idmap_tdb.c
@@ -97,8 +97,7 @@ static int convert_fn(struct db_record *rec, void *private_data)
rid = atoi(p);
- sid_copy(&sid, &domain->sid);
- sid_append_rid(&sid, rid);
+ sid_compose(&sid, &domain->sid, rid);
sid_to_fstring(keystr, &sid);
key2 = string_term_tdb_data(keystr);
diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c
index d15fb86d86..f647a3ffaf 100644
--- a/source3/winbindd/winbindd_ads.c
+++ b/source3/winbindd/winbindd_ads.c
@@ -880,8 +880,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
goto done;
}
- sid_copy(&primary_group, &domain->sid);
- sid_append_rid(&primary_group, primary_group_rid);
+ sid_compose(&primary_group, &domain->sid, primary_group_rid);
count = ads_pull_sids(ads, mem_ctx, msg, "tokenGroups", &sids);
diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c
index 68972dd18d..b7b5e6d7ed 100644
--- a/source3/winbindd/winbindd_cache.c
+++ b/source3/winbindd/winbindd_cache.c
@@ -2986,8 +2986,7 @@ void wcache_invalidate_samlogon(struct winbindd_domain *domain,
return;
}
- sid_copy(&sid, info3->base.domain_sid);
- sid_append_rid(&sid, info3->base.rid);
+ sid_compose(&sid, info3->base.domain_sid, info3->base.rid);
/* Clear U/SID cache entry */
fstr_sprintf(key_str, "U/%s", sid_to_fstring(sid_string, &sid));
diff --git a/source3/winbindd/winbindd_ccache_access.c b/source3/winbindd/winbindd_ccache_access.c
index 921110a0be..2f71aaae52 100644
--- a/source3/winbindd/winbindd_ccache_access.c
+++ b/source3/winbindd/winbindd_ccache_access.c
@@ -116,7 +116,7 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username,
data_blob_free(&reply);
goto done;
}
- *auth_msg = reply;
+ *auth_msg = data_blob(reply.data, reply.length);
status = NT_STATUS_OK;
done:
diff --git a/source3/winbindd/winbindd_cred_cache.c b/source3/winbindd/winbindd_cred_cache.c
index e63e73221e..df09bbe1bd 100644
--- a/source3/winbindd/winbindd_cred_cache.c
+++ b/source3/winbindd/winbindd_cred_cache.c
@@ -523,11 +523,10 @@ NTSTATUS add_ccache_to_list(const char *princ_name,
"user krb5 ccache %s with %s\n", ccname,
error_message(ret)));
return krb5_to_nt_status(ret);
- } else {
- DEBUG(10, ("add_ccache_to_list: successfully destroyed "
- "krb5 ccache %s for user %s\n", ccname,
- username));
}
+ DEBUG(10, ("add_ccache_to_list: successfully destroyed "
+ "krb5 ccache %s for user %s\n", ccname,
+ username));
}
#endif
@@ -545,11 +544,11 @@ NTSTATUS add_ccache_to_list(const char *princ_name,
/* FIXME: in this case we still might want to have a krb5 cred
* event handler created - gd
* Add ticket refresh handler here */
-
+
if (!lp_winbind_refresh_tickets() || renew_until <= 0) {
return NT_STATUS_OK;
}
-
+
if (!entry->event) {
if (postponed_request) {
t = timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0);
@@ -586,7 +585,7 @@ NTSTATUS add_ccache_to_list(const char *princ_name,
DEBUG(10,("add_ccache_to_list: added krb5_ticket handler\n"));
}
-
+
return NT_STATUS_OK;
}
diff --git a/source3/winbindd/winbindd_creds.c b/source3/winbindd/winbindd_creds.c
index 98a16ee937..46c7a06f7c 100644
--- a/source3/winbindd/winbindd_creds.c
+++ b/source3/winbindd/winbindd_creds.c
@@ -4,17 +4,17 @@
Winbind daemon - cached credentials funcions
Copyright (C) Guenther Deschner 2005
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -66,10 +66,8 @@ NTSTATUS winbindd_store_creds(struct winbindd_domain *domain,
if (info3 != NULL) {
- DOM_SID sid;
- sid_copy(&sid, info3->base.domain_sid);
- sid_append_rid(&sid, info3->base.rid);
- sid_copy(&cred_sid, &sid);
+ sid_compose(&cred_sid, info3->base.domain_sid,
+ info3->base.rid);
info3->base.user_flags |= NETLOGON_CACHED_ACCOUNT;
} else if (user_sid != NULL) {
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 357b6463d5..4658231a5c 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -195,8 +195,8 @@ static NTSTATUS append_afs_token(TALLOC_CTX *mem_ctx,
DOM_SID user_sid;
fstring sidstr;
- sid_copy(&user_sid, info3->base.domain_sid);
- sid_append_rid(&user_sid, info3->base.rid);
+ sid_compose(&user_sid, info3->base.domain_sid,
+ info3->base.rid);
sid_to_fstring(sidstr, &user_sid);
afsname = talloc_string_sub(mem_ctx, afsname,
"%s", sidstr);
diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c
index 2146953639..87494db2bb 100644
--- a/source3/winbindd/winbindd_rpc.c
+++ b/source3/winbindd/winbindd_rpc.c
@@ -612,9 +612,8 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
return NT_STATUS_NO_MEMORY;
for (i=0;i<(*num_groups);i++) {
- sid_copy(&((*user_grpsids)[i]), &domain->sid);
- sid_append_rid(&((*user_grpsids)[i]),
- rid_array->rids[i].rid);
+ sid_compose(&((*user_grpsids)[i]), &domain->sid,
+ rid_array->rids[i].rid);
}
return NT_STATUS_OK;