summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2004-08-04 05:42:36 +0000
committerGerald Carter <jerry@samba.org>2004-08-04 05:42:36 +0000
commitfecd5ea163ffcd1bbee5b06e05112dbff9aa71b1 (patch)
tree917402d02525c39dd42d3aed01609ac02be104b4
parent7cc5217c98cab4d0d970a2eb7f378319bedb6a46 (diff)
downloadsamba-fecd5ea163ffcd1bbee5b06e05112dbff9aa71b1.tar.gz
samba-fecd5ea163ffcd1bbee5b06e05112dbff9aa71b1.tar.xz
samba-fecd5ea163ffcd1bbee5b06e05112dbff9aa71b1.zip
r1643: syncing all changes from 3.0 and hopefully get 3.0.6rc2 out tomorrow
-rw-r--r--WHATSNEW.txt127
-rw-r--r--source/Makefile.in2
-rw-r--r--source/VERSION4
-rw-r--r--source/auth/auth.c2
-rw-r--r--source/auth/auth_sam.c6
-rw-r--r--source/configure.in48
-rw-r--r--source/include/includes.h9
-rw-r--r--source/include/mangle.h2
-rw-r--r--source/include/ntdomain.h110
-rw-r--r--source/include/passdb.h8
-rw-r--r--source/include/smbldap.h7
-rw-r--r--source/lib/account_pol.c27
-rw-r--r--source/lib/afs.c2
-rw-r--r--source/lib/debug.c604
-rw-r--r--source/lib/fsusage.c11
-rw-r--r--source/lib/genrand.c38
-rw-r--r--source/lib/smbldap.c191
-rw-r--r--source/lib/util_str.c16
-rw-r--r--source/lib/util_uuid.c2
-rw-r--r--source/libsmb/cliconnect.c9
-rw-r--r--source/libsmb/clidgram.c2
-rw-r--r--source/libsmb/clientgen.c2
-rw-r--r--source/libsmb/clikrb5.c2
-rw-r--r--source/libsmb/ntlmssp.c6
-rw-r--r--source/libsmb/passchange.c2
-rw-r--r--source/libsmb/smb_signing.c4
-rw-r--r--source/libsmb/smbencrypt.c6
-rw-r--r--source/nsswitch/wbinfo.c43
-rw-r--r--source/nsswitch/winbindd.c13
-rw-r--r--source/nsswitch/winbindd_cm.c1
-rw-r--r--source/nsswitch/winbindd_pam.c2
-rw-r--r--source/nsswitch/wins.c2
-rw-r--r--source/param/loadparm.c22
-rw-r--r--source/passdb/machine_sid.c2
-rw-r--r--source/passdb/passdb.c810
-rw-r--r--source/passdb/pdb_get_set.c84
-rw-r--r--source/passdb/pdb_ldap.c72
-rw-r--r--source/passdb/pdb_tdb.c9
-rw-r--r--source/passdb/secrets.c60
-rw-r--r--source/printing/printing.c3
-rw-r--r--source/python/py_winbind.c4
-rw-r--r--source/rpc_client/cli_netlogon.c4
-rw-r--r--source/rpc_client/cli_srvsvc.c36
-rw-r--r--source/rpc_parse/parse_prs.c2
-rw-r--r--source/rpc_server/srv_netlog_nt.c2
-rw-r--r--source/rpc_server/srv_pipe.c39
-rw-r--r--source/rpc_server/srv_pipe_hnd.c19
-rw-r--r--source/rpc_server/srv_spoolss_nt.c18
-rw-r--r--source/rpcclient/cmd_netlogon.c10
-rw-r--r--source/rpcclient/cmd_srvsvc.c23
-rw-r--r--source/sam/idmap.c7
-rwxr-xr-xsource/script/installswat.sh2
-rw-r--r--source/smbd/chgpasswd.c85
-rw-r--r--source/smbd/filename.c4
-rw-r--r--source/smbd/mangle.c4
-rw-r--r--source/smbd/mangle_hash.c10
-rw-r--r--source/smbd/mangle_hash2.c8
-rw-r--r--source/smbd/password.c26
-rw-r--r--source/smbd/reply.c6
-rw-r--r--source/smbd/server.c11
-rw-r--r--source/smbd/service.c8
-rw-r--r--source/smbd/trans2.c39
-rw-r--r--source/torture/mangle_test.c4
-rw-r--r--source/torture/torture.c2
-rw-r--r--source/utils/ntlm_auth.c4
-rw-r--r--source/utils/pdbedit.c62
-rw-r--r--source/utils/smbpasswd.c31
-rw-r--r--source/wrepld/server.c2
68 files changed, 1689 insertions, 1155 deletions
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index d637d0065be..ea97e56844f 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,6 +1,6 @@
================================
- Release Notes for Samba 3.0.5rc1
- July 8, 2004
+ Release Notes for Samba 3.0.6rc2
+ Aug 3, 2004
================================
This is a release candidate snapshot of the Samba 3.0.5 code
@@ -15,6 +15,120 @@ we feel are important to make available to the Samba community
for wider testings. See the "Changes" section for details on
exact updates.
+Common bugs fixed in 3.0.6rc2 include:
+
+ o
+
+New features introduced in this release include:
+
+ o Support for maintaining user password history.
+
+
+######################################################################
+Changes
+#######
+
+Changes since 3.0.6rc1
+(formally referred to as 3.0.5rc1)
+----------------------------------
+
+smb.conf changes
+----------------
+
+ Parameter Name Action
+ -------------- ------
+
+
+commits
+-------
+o Jeremy Allison <jra@samba.org>
+ * Add support for storing a user's password history.
+ LDAP portion of the code was based on a patch from
+ Jianliang Lu <j.lu@tiesse.com>.
+
+
+
+Changes for older versions follow below:
+
+ --------------------------------------------------
+
+ =============================
+ Release Notes for Samba 3.0.5
+ July 20, 2004
+ =============================
+
+Please note that Samba 3.0.5 is identical to Samba 3.0.4 with
+the exception of correcting the two security issues outlined
+below.
+
+######################## SECURITY RELEASE ########################
+
+Summary: Multiple Potential Buffer Overruns in Samba 3.0.x
+CVE ID: CAN-2004-0600, CAN-2004-0686
+ (http://cve.mitre.org/)
+
+
+This is the latest stable release of Samba. This is the version
+that production Samba servers should be running for all current
+bug-fixes.
+
+It has been confirmed that versions of Samba 3 prior to v3.0.4
+are vulnerable to two potential buffer overruns. The individual
+details are given below.
+
+-------------
+CAN-2004-0600
+-------------
+
+Affected Versions: Samba 3.0.2 and later
+
+The internal routine used by the Samba Web Administration
+Tool (SWAT v3.0.2 and later) to decode the base64 data
+during HTTP basic authentication is subject to a buffer
+overrun caused by an invalid base64 character. It is
+recommended that all Samba v3.0.2 or later installations
+running SWAT either (a) upgrade to v3.0.5, or (b) disable
+the swat administration service as a temporary workaround.
+
+This same code is used internally to decode the
+sambaMungedDial attribute value when using the ldapsam
+passdb backend. While we do not believe that the base64
+decoding routines used by the ldapsam passdb backend can
+be exploited, sites using an LDAP directory service with
+Samba are strongly encouraged to verify that the DIT only
+allows write access to sambaSamAccount attributes by a
+sufficiently authorized user.
+
+The Samba Team would like to heartily thank Evgeny Demidov
+for analyzing and reporting this bug.
+
+-------------
+CAN-2004-0686
+-------------
+
+Affected Versions: Samba 3.0.0 and later
+
+A buffer overrun has been located in the code used to support
+the 'mangling method = hash' smb.conf option. Please be aware
+that the default setting for this parameter is 'mangling method
+= hash2' and therefore not vulnerable.
+
+Affected Samba 3 installations can avoid this possible security
+bug by using the default hash2 mangling method. Server
+installations requiring the hash mangling method are encouraged
+to upgrade to Samba 3.0.5.
+
+
+##################################################################
+
+
+ --------------------------------------------------
+
+ ================================
+ Release Notes for Samba 3.0.5rc1
+ July 8, 2004
+ ================================
+
Common bugs fixed in this 3.0.5rc1 include:
o Corrupt workgroup names in nmbd's browse.dat.
@@ -50,10 +164,8 @@ New features introduced in this release include:
Changes
#######
-
-
-Changes since 3.0.4
---------------------
+Changes since 3.0.5pre1
+-----------------------
smb.conf changes
----------------
@@ -267,9 +379,6 @@ o Jelmer Vernooij <jelmer@samba.org>
* Prepare for better error checking in tar.
-
-Changes for older versions follow below:
-
--------------------------------------------------
=================================
diff --git a/source/Makefile.in b/source/Makefile.in
index 398ad4e0e3f..58c8a7895d6 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -307,7 +307,7 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_net.o \
RPC_CLIENT_OBJ = rpc_client/cli_pipe.o
-LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o smbd/tdbutil.o
+LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o
diff --git a/source/VERSION b/source/VERSION
index b6dcf4957e3..6a3dd5010f9 100644
--- a/source/VERSION
+++ b/source/VERSION
@@ -19,7 +19,7 @@
########################################################
SAMBA_VERSION_MAJOR=3
SAMBA_VERSION_MINOR=0
-SAMBA_VERSION_RELEASE=5
+SAMBA_VERSION_RELEASE=6
########################################################
# For 'pre' releases the version will be #
@@ -39,7 +39,7 @@ SAMBA_VERSION_PRE_RELEASE=
# e.g. SAMBA_VERSION_RC_RELEASE=1 #
# -> "3.0.0rc1" #
########################################################
-SAMBA_VERSION_RC_RELEASE=1
+SAMBA_VERSION_RC_RELEASE=2
########################################################
# To mark SVN snapshots this should be set to 'yes' #
diff --git a/source/auth/auth.c b/source/auth/auth.c
index 1b49699fbca..7cfe3fc6394 100644
--- a/source/auth/auth.c
+++ b/source/auth/auth.c
@@ -124,7 +124,7 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context)
if (!challenge_set_by) {
uchar chal[8];
- generate_random_buffer(chal, sizeof(chal), False);
+ generate_random_buffer(chal, sizeof(chal));
auth_context->challenge = data_blob_talloc(auth_context->mem_ctx,
chal, sizeof(chal));
diff --git a/source/auth/auth_sam.c b/source/auth/auth_sam.c
index 2f9ff6265c9..44e0a1810fe 100644
--- a/source/auth/auth_sam.c
+++ b/source/auth/auth_sam.c
@@ -231,6 +231,8 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
DEBUG(1, ("Failed to modify entry.\n"));
unbecome_root();
}
+ data_blob_free(&user_sess_key);
+ data_blob_free(&lm_sess_key);
pdb_free_sam(&sampass);
return nt_status;
}
@@ -253,11 +255,15 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context,
if (!NT_STATUS_IS_OK(nt_status)) {
pdb_free_sam(&sampass);
+ data_blob_free(&user_sess_key);
+ data_blob_free(&lm_sess_key);
return nt_status;
}
if (!NT_STATUS_IS_OK(nt_status = make_server_info_sam(server_info, sampass))) {
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;
}
diff --git a/source/configure.in b/source/configure.in
index e57076a346a..4076f654ef8 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -643,7 +643,7 @@ AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/i
AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h sys/socket.h)
AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h)
AC_CHECK_HEADERS(sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h)
-AC_CHECK_HEADERS(security/pam_modules.h security/_pam_macros.h dlfcn.h)
+AC_CHECK_HEADERS(sys/sysmacros.h security/pam_modules.h security/_pam_macros.h dlfcn.h)
AC_CHECK_HEADERS(sys/syslog.h syslog.h execinfo.h)
AC_CHECK_HEADERS(langinfo.h locale.h)
@@ -1130,7 +1130,7 @@ if test "$enable_shared" = "yes"; then
case "$host_os" in
*linux*) AC_DEFINE(LINUX,1,[Whether the host os is linux])
BLDSHARED="true"
- LDSHFLAGS="-shared"
+ LDSHFLAGS="-shared -Bsymbolic"
DYNEXP="-Wl,--export-dynamic"
PICFLAGS="-fPIC"
SONAMEFLAG="-Wl,-soname="
@@ -1429,6 +1429,18 @@ if test x"$samba_cv_HAVE_DEVICE_MINOR_FN" = x"yes"; then
AC_DEFINE(HAVE_DEVICE_MINOR_FN,1,[Whether the minor macro for dev_t is available])
fi
+AC_CACHE_CHECK([for makedev macro],samba_cv_HAVE_MAKEDEV,[
+AC_TRY_RUN([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+main() { dev_t dev = makedev(1,2); return 0; }],
+samba_cv_HAVE_MAKEDEV=yes,samba_cv_HAVE_MAKEDEV=no,samba_cv_HAVE_MAKEDEV=cross)])
+if test x"$samba_cv_HAVE_MAKEDEV" = x"yes"; then
+ AC_DEFINE(HAVE_MAKEDEV,1,[Whether the macro for makedev is available])
+fi
+
AC_CACHE_CHECK([for unsigned char],samba_cv_HAVE_UNSIGNED_CHAR,[
AC_TRY_RUN([#include <stdio.h>
main() { char c; c=250; exit((c > 0)?0:1); }],
@@ -1680,31 +1692,37 @@ AC_ARG_WITH(libiconv,
fi
])
-ICONV_FOUND="no"
-libext=""
for i in $LOOK_DIRS ; do
save_LIBS=$LIBS
save_LDFLAGS=$LDFLAGS
save_CPPFLAGS=$CPPFLAGS
+ ICONV_FOUND="no"
+ unset libext
CPPFLAGS="$CPPFLAGS -I$i/include"
dnl This is here to handle -withval stuff for --with-libiconv
dnl Perhaps we should always add a -L
dnl Check lib and lib32 library variants to cater for IRIX ABI-specific
-dnl installation paths.
- for l in "lib" "lib32" ; do
- LDFLAGS="$LDFLAGS -L$i/$l"
- LIBS=
- export LDFLAGS LIBS CPPFLAGS
+dnl installation paths. This gets a little tricky since we might have iconv
+dnl in both libiconv and in libc. In this case the jm_ICONV test will always
+dnl succeed when the header is found. To counter this, make sure the
+dnl library directory is there and check the ABI directory first (which
+dnl should be harmless on other systems.
+ for l in "lib32" "lib" ; do
+ if test -d "$i/$l" ; then
+ LDFLAGS="$save_LDFLAGS -L$i/$l"
+ LIBS=
+ export LDFLAGS LIBS CPPFLAGS
dnl Try to find iconv(3)
- jm_ICONV($i)
- if test "$ICONV_FOUND" = yes; then
- libext="$l"
- break;
+ jm_ICONV($i/$l)
+ if test x"$ICONV_FOUND" = "xyes" ; then
+ libext="$l"
+ break;
+ fi
fi
done
- if test "$ICONV_FOUND" = yes; then
+ if test x"$ICONV_FOUND" = "xyes" ; then
LDFLAGS=$save_LDFLAGS
LIB_ADD_DIR(LDFLAGS, "$i/$libext")
CFLAGS_ADD_DIR(CPPFLAGS, "$i/include")
@@ -1718,7 +1736,7 @@ dnl there might be a working iconv further down the list of LOOK_DIRS
# check for iconv in libc
ic_save_LIBS="$LIBS"
if test x"$ICONV_PATH_SPEC" = "xyes" ; then
- LIBS="$LIBS -L$ICONV_LOCATION/lib"
+ LIBS="$LIBS -L$ICONV_LOCATION/$libext"
fi
if test x"$jm_cv_lib_iconv" != x; then
LIBS="$LIBS -l$jm_cv_lib_iconv"
diff --git a/source/include/includes.h b/source/include/includes.h
index 7657984bfb1..2664cad098f 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -1309,6 +1309,15 @@ void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes);
BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote);
#endif /* HAVE_KRB5 */
+
+#ifdef HAVE_LDAP
+
+/* function declarations not included in proto.h */
+LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int to);
+
+#endif /* HAVE_LDAP */
+
+
/* TRUE and FALSE are part of the C99 standard and gcc, but
unfortunately many vendor compilers don't support them. Use True
and False instead. */
diff --git a/source/include/mangle.h b/source/include/mangle.h
index 1d7cdf73628..08d511689dc 100644
--- a/source/include/mangle.h
+++ b/source/include/mangle.h
@@ -8,7 +8,7 @@ struct mangle_fns {
BOOL (*is_mangled)(const char *s);
BOOL (*is_8_3)(const char *fname, BOOL check_case, BOOL allow_wildcards);
void (*reset)(void);
- BOOL (*check_cache)(char *s);
+ BOOL (*check_cache)(char *s, size_t maxlen);
void (*name_map)(char *OutName, BOOL need83, BOOL cache83, int default_case);
};
#endif /* _MANGLE_H_ */
diff --git a/source/include/ntdomain.h b/source/include/ntdomain.h
index 084e56b51e1..a63272fd18f 100644
--- a/source/include/ntdomain.h
+++ b/source/include/ntdomain.h
@@ -4,6 +4,7 @@
Copyright (C) Andrew Tridgell 1992-1997
Copyright (C) Luke Kenneth Casson Leighton 1996-1997
Copyright (C) Paul Ashton 1997
+ Copyright (C) Jeremy Allison 200-2004
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
@@ -23,19 +24,17 @@
#ifndef _NT_DOMAIN_H /* _NT_DOMAIN_H */
#define _NT_DOMAIN_H
-struct uuid
-{
- uint32 time_low;
- uint16 time_mid;
- uint16 time_hi_and_version;
- uint8 clock_seq[2];
- uint8 node[6];
+struct uuid {
+ uint32 time_low;
+ uint16 time_mid;
+ uint16 time_hi_and_version;
+ uint8 clock_seq[2];
+ uint8 node[6];
};
#define UUID_SIZE 16
#define UUID_FLAT_SIZE 16
-typedef struct uuid_flat
-{
+typedef struct uuid_flat {
uint8 info[UUID_FLAT_SIZE];
} UUID_FLAT;
@@ -54,8 +53,7 @@ typedef struct uuid_flat
* in the NTDOM branch - it didn't belong there.
*/
-typedef struct _prs_struct
-{
+typedef struct _prs_struct {
BOOL io; /* parsing in or out of data stream */
/*
* If the (incoming) data is big-endian. On output we are
@@ -109,49 +107,47 @@ typedef struct _output_data {
} output_data;
typedef struct _input_data {
- /*
- * This is the current incoming pdu. The data here
- * is collected via multiple writes until a complete
- * pdu is seen, then the data is copied into the in_data
- * structure. The maximum size of this is 0x1630 (MAX_PDU_FRAG_LEN).
- */
- unsigned char current_in_pdu[MAX_PDU_FRAG_LEN];
-
- /*
- * The amount of data needed to complete the in_pdu.
- * If this is zero, then we are at the start of a new
- * pdu.
- */
- uint32 pdu_needed_len;
-
- /*
- * The amount of data received so far in the in_pdu.
- * If this is zero, then we are at the start of a new
- * pdu.
- */
- uint32 pdu_received_len;
-
- /*
- * This is the collection of input data with all
- * the rpc headers and auth footers removed.
- * The maximum length of this (1Mb) is strictly enforced.
- */
- prs_struct data;
+ /*
+ * This is the current incoming pdu. The data here
+ * is collected via multiple writes until a complete
+ * pdu is seen, then the data is copied into the in_data
+ * structure. The maximum size of this is 0x1630 (MAX_PDU_FRAG_LEN).
+ */
+ unsigned char current_in_pdu[MAX_PDU_FRAG_LEN];
+
+ /*
+ * The amount of data needed to complete the in_pdu.
+ * If this is zero, then we are at the start of a new
+ * pdu.
+ */
+ uint32 pdu_needed_len;
+
+ /*
+ * The amount of data received so far in the in_pdu.
+ * If this is zero, then we are at the start of a new
+ * pdu.
+ */
+ uint32 pdu_received_len;
+
+ /*
+ * This is the collection of input data with all
+ * the rpc headers and auth footers removed.
+ * The maximum length of this (1Mb) is strictly enforced.
+ */
+ prs_struct data;
} input_data;
/*
* Handle database - stored per pipe.
*/
-struct policy
-{
- struct policy *next, *prev;
+struct policy {
+ struct policy *next, *prev;
- POLICY_HND pol_hnd;
-
- void *data_ptr;
- void (*free_fn)(void *);
+ POLICY_HND pol_hnd;
+ void *data_ptr;
+ void (*free_fn)(void *);
};
struct handle_list {
@@ -161,8 +157,7 @@ struct handle_list {
};
/* Domain controller authentication protocol info */
-struct dcinfo
-{
+struct dcinfo {
DOM_CHAL clnt_chal; /* Initial challenge received from client */
DOM_CHAL srv_chal; /* Initial server challenge */
DOM_CRED clnt_cred; /* Last client credential */
@@ -198,8 +193,7 @@ typedef struct pipe_rpc_fns {
* NamedPipes.
*/
-typedef struct pipes_struct
-{
+typedef struct pipes_struct {
struct pipes_struct *next, *prev;
connection_struct *conn;
@@ -291,8 +285,7 @@ typedef struct pipes_struct
} pipes_struct;
-typedef struct smb_np_struct
-{
+typedef struct smb_np_struct {
struct smb_np_struct *next, *prev;
int pnum;
connection_struct *conn;
@@ -368,18 +361,15 @@ typedef struct smb_np_struct
} smb_np_struct;
-struct api_struct
-{
- const char *name;
- uint8 opnum;
- BOOL (*fn) (pipes_struct *);
+struct api_struct {
+ const char *name;
+ uint8 opnum;
+ BOOL (*fn) (pipes_struct *);
};
-typedef struct
-{
+typedef struct {
uint32 rid;
const char *name;
-
} rid_name;
/*
diff --git a/source/include/passdb.h b/source/include/passdb.h
index d08fd13a723..7d3e0014b65 100644
--- a/source/include/passdb.h
+++ b/source/include/passdb.h
@@ -99,6 +99,7 @@ enum pdb_elements {
PDB_UNKNOWN6,
PDB_LMPASSWD,
PDB_NTPASSWD,
+ PDB_PWHISTORY,
PDB_BACKEND_PRIVATE_DATA,
/* this must be the last element */
@@ -165,16 +166,17 @@ typedef struct sam_passwd
const char * dir_drive; /* home directory drive string */
const char * logon_script; /* logon script string */
const char * profile_path; /* profile path string */
- const char * acct_desc ; /* user description string */
+ const char * acct_desc; /* user description string */
const char * workstations; /* login from workstations string */
- const char * unknown_str ; /* don't know what this is, yet. */
- const char * munged_dial ; /* munged path name and dial-back tel number */
+ const char * unknown_str; /* don't know what this is, yet. */
+ const char * munged_dial; /* munged path name and dial-back tel number */
DOM_SID user_sid; /* Primary User SID */
DOM_SID group_sid; /* Primary Group SID */
DATA_BLOB lm_pw; /* .data is Null if no password */
DATA_BLOB nt_pw; /* .data is Null if no password */
+ DATA_BLOB nt_pw_his; /* nt hashed password history .data is Null if not available */
char* plaintext_pw; /* is Null if not available */
uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
diff --git a/source/include/smbldap.h b/source/include/smbldap.h
index c7de7d84b37..6046af464e6 100644
--- a/source/include/smbldap.h
+++ b/source/include/smbldap.h
@@ -93,8 +93,9 @@
#define LDAP_ATTR_LOGON_COUNT 36
#define LDAP_ATTR_MUNGED_DIAL 37
#define LDAP_ATTR_BAD_PASSWORD_TIME 38
-
-#define LDAP_ATTR_SID_LIST 40
+#define LDAP_ATTR_PWD_HISTORY 39
+#define LDAP_ATTR_SID_LIST 40
+#define LDAP_ATTR_MOD_TIMESTAMP 41
typedef struct _attrib_map_entry {
int attrib;
@@ -153,6 +154,6 @@ struct smbldap_state {
struct smbldap_state;
-#define LDAP_CONNECT_DEFAULT_TIMEOUT 5
+#define LDAP_CONNECT_DEFAULT_TIMEOUT 15
#endif /* _SMBLDAP_H */
diff --git a/source/lib/account_pol.c b/source/lib/account_pol.c
index c2c63493a6f..8d5b963da28 100644
--- a/source/lib/account_pol.c
+++ b/source/lib/account_pol.c
@@ -81,6 +81,30 @@ static const struct {
{0, NULL}
};
+char *account_policy_names_list(void)
+{
+ char *nl, *p;
+ int i;
+ size_t len = 0;
+
+ for (i=0; account_policy_names[i].string; i++) {
+ len += strlen(account_policy_names[i].string) + 1;
+ }
+ len++;
+ nl = malloc(len);
+ if (!nl) {
+ return NULL;
+ }
+ p = nl;
+ for (i=0; account_policy_names[i].string; i++) {
+ memcpy(p, account_policy_names[i].string, strlen(account_policy_names[i].string) + 1);
+ p[strlen(account_policy_names[i].string)] = '\n';
+ p += strlen(account_policy_names[i].string) + 1;
+ }
+ *p = '\0';
+ return nl;
+}
+
/****************************************************************************
Get the account policy name as a string from its #define'ed number
****************************************************************************/
@@ -111,9 +135,9 @@ int account_policy_name_to_fieldnum(const char *name)
}
-
/****************************************************************************
****************************************************************************/
+
BOOL account_policy_get(int field, uint32 *value)
{
fstring name;
@@ -159,4 +183,3 @@ BOOL account_policy_set(int field, uint32 value)
return True;
}
-
diff --git a/source/lib/afs.c b/source/lib/afs.c
index 0830a3a0e7f..8688fde6b1c 100644
--- a/source/lib/afs.c
+++ b/source/lib/afs.c
@@ -116,7 +116,7 @@ static BOOL afs_createtoken(const char *username, const char *cell,
p += 4;
/* We need to create a session key */
- generate_random_buffer(p, 8, False);
+ generate_random_buffer(p, 8);
/* Our client code needs the the key in the clear, it does not
know the server-key ... */
diff --git a/source/lib/debug.c b/source/lib/debug.c
index f9c8b0c46ab..e5e203e076a 100644
--- a/source/lib/debug.c
+++ b/source/lib/debug.c
@@ -239,8 +239,9 @@ done:
}
/****************************************************************************
-utility access to debug class names's
+ Utility access to debug class names's.
****************************************************************************/
+
const char *debug_classname_from_index(int ndx)
{
if (ndx < 0 || ndx >= debug_num_classes)
@@ -250,8 +251,9 @@ const char *debug_classname_from_index(int ndx)
}
/****************************************************************************
-utility to translate names to debug class index's (internal version)
+ Utility to translate names to debug class index's (internal version).
****************************************************************************/
+
static int debug_lookup_classname_int(const char* classname)
{
int i;
@@ -266,8 +268,9 @@ static int debug_lookup_classname_int(const char* classname)
}
/****************************************************************************
-Add a new debug class to the system
+ Add a new debug class to the system.
****************************************************************************/
+
int debug_add_class(const char *classname)
{
int ndx;
@@ -285,33 +288,28 @@ int debug_add_class(const char *classname)
ndx = debug_num_classes;
new_ptr = DEBUGLEVEL_CLASS;
- if (DEBUGLEVEL_CLASS == &debug_all_class_hack)
- {
+ if (DEBUGLEVEL_CLASS == &debug_all_class_hack) {
/* Initial loading... */
new_ptr = NULL;
}
- new_ptr = Realloc(new_ptr,
- sizeof(int) * (debug_num_classes + 1));
+ new_ptr = Realloc(new_ptr, sizeof(int) * (debug_num_classes + 1));
if (!new_ptr)
return -1;
DEBUGLEVEL_CLASS = new_ptr;
DEBUGLEVEL_CLASS[ndx] = 0;
/* debug_level is the pointer used for the DEBUGLEVEL-thingy */
- if (ndx==0)
- {
+ if (ndx==0) {
/* Transfer the initial level from debug_all_class_hack */
DEBUGLEVEL_CLASS[ndx] = DEBUGLEVEL;
}
debug_level = DEBUGLEVEL_CLASS;
new_ptr = DEBUGLEVEL_CLASS_ISSET;
- if (new_ptr == &debug_all_class_isset_hack)
- {
+ if (new_ptr == &debug_all_class_isset_hack) {
new_ptr = NULL;
}
- new_ptr = Realloc(new_ptr,
- sizeof(BOOL) * (debug_num_classes + 1));
+ new_ptr = Realloc(new_ptr, sizeof(BOOL) * (debug_num_classes + 1));
if (!new_ptr)
return -1;
DEBUGLEVEL_CLASS_ISSET = new_ptr;
@@ -333,42 +331,41 @@ int debug_add_class(const char *classname)
}
/****************************************************************************
-utility to translate names to debug class index's (public version)
+ Utility to translate names to debug class index's (public version).
****************************************************************************/
+
int debug_lookup_classname(const char *classname)
{
int ndx;
- if (!classname || !*classname) return -1;
+ if (!classname || !*classname)
+ return -1;
ndx = debug_lookup_classname_int(classname);
if (ndx != -1)
return ndx;
- if (debug_warn_unknown_class)
- {
+ if (debug_warn_unknown_class) {
DEBUG(0, ("debug_lookup_classname(%s): Unknown class\n",
classname));
}
- if (debug_auto_add_unknown_class)
- {
+ if (debug_auto_add_unknown_class) {
return debug_add_class(classname);
}
return -1;
}
-
/****************************************************************************
-dump the current registered debug levels
+ Dump the current registered debug levels.
****************************************************************************/
+
static void debug_dump_status(int level)
{
int q;
DEBUG(level, ("INFO: Current debug levels:\n"));
- for (q = 0; q < debug_num_classes; q++)
- {
+ for (q = 0; q < debug_num_classes; q++) {
DEBUGADD(level, (" %s: %s/%d\n",
classname_table[q],
(DEBUGLEVEL_CLASS_ISSET[q]
@@ -378,9 +375,10 @@ static void debug_dump_status(int level)
}
/****************************************************************************
-parse the debug levels from smbcontrol. Example debug level parameter:
- printdrivers:7
+ parse the debug levels from smbcontrol. Example debug level parameter:
+ printdrivers:7
****************************************************************************/
+
static BOOL debug_parse_params(char **params)
{
int i, ndx;
@@ -397,9 +395,9 @@ static BOOL debug_parse_params(char **params)
DEBUGLEVEL_CLASS[DBGC_ALL] = atoi(params[0]);
DEBUGLEVEL_CLASS_ISSET[DBGC_ALL] = True;
i = 1; /* start processing at the next params */
- }
- else
+ } else {
i = 0; /* DBGC_ALL not specified OR class name was included */
+ }
/* Fill in new debug class levels */
for (; i < debug_num_classes && params[i]; i++) {
@@ -418,10 +416,11 @@ static BOOL debug_parse_params(char **params)
}
/****************************************************************************
-parse the debug levels from smb.conf. Example debug level string:
+ Parse the debug levels from smb.conf. Example debug level string:
3 tdb:5 printdrivers:7
-Note: the 1st param has no "name:" preceeding it.
+ Note: the 1st param has no "name:" preceeding it.
****************************************************************************/
+
BOOL debug_parse_levels(const char *params_str)
{
char **params;
@@ -434,8 +433,7 @@ BOOL debug_parse_levels(const char *params_str)
params = str_list_make(params_str, NULL);
- if (debug_parse_params(params))
- {
+ if (debug_parse_params(params)) {
debug_dump_status(5);
str_list_free(&params);
return True;
@@ -446,15 +444,15 @@ BOOL debug_parse_levels(const char *params_str)
}
/****************************************************************************
-receive a "set debug level" message
+ Receive a "set debug level" message.
****************************************************************************/
+
static void debug_message(int msg_type, pid_t src, void *buf, size_t len)
{
const char *params_str = buf;
/* Check, it's a proper string! */
- if (params_str[len-1] != '\0')
- {
+ if (params_str[len-1] != '\0') {
DEBUG(1, ("Invalid debug message from pid %u to pid %u\n",
(unsigned int)src, (unsigned int)getpid()));
return;
@@ -466,10 +464,10 @@ static void debug_message(int msg_type, pid_t src, void *buf, size_t len)
debug_parse_levels(params_str);
}
-
/****************************************************************************
-send a "set debug level" message
+ Send a "set debug level" message.
****************************************************************************/
+
void debug_message_send(pid_t pid, const char *params_str)
{
if (!params_str)
@@ -495,6 +493,7 @@ static void debuglevel_message(int msg_type, pid_t src, void *buf, size_t len)
/****************************************************************************
Init debugging (one time stuff)
****************************************************************************/
+
void debug_init(void)
{
static BOOL initialised = False;
@@ -508,17 +507,15 @@ void debug_init(void)
message_register(MSG_DEBUG, debug_message);
message_register(MSG_REQ_DEBUGLEVEL, debuglevel_message);
- for(p = default_classname_table; *p; p++)
- {
+ for(p = default_classname_table; *p; p++) {
debug_add_class(*p);
}
}
+/***************************************************************************
+ Get ready for syslog stuff
+**************************************************************************/
-/* ************************************************************************** **
- * get ready for syslog stuff
- * ************************************************************************** **
- */
void setup_logging(const char *pname, BOOL interactive)
{
debug_init();
@@ -526,6 +523,11 @@ void setup_logging(const char *pname, BOOL interactive)
/* reset to allow multiple setup calls, going from interactive to
non-interactive */
stdout_logging = False;
+ if (dbf) {
+ x_fflush(dbf);
+ (void) x_fclose(dbf);
+ }
+
dbf = NULL;
if (interactive) {
@@ -546,16 +548,15 @@ void setup_logging(const char *pname, BOOL interactive)
#endif
}
#endif
-} /* setup_logging */
-
-/* ************************************************************************** **
- * reopen the log files
- * note that we now do this unconditionally
- * We attempt to open the new debug fp before closing the old. This means
- * if we run out of fd's we just keep using the old fd rather than aborting.
- * Fix from dgibson@linuxcare.com.
- * ************************************************************************** **
- */
+}
+
+/**************************************************************************
+ reopen the log files
+ note that we now do this unconditionally
+ We attempt to open the new debug fp before closing the old. This means
+ if we run out of fd's we just keep using the old fd rather than aborting.
+ Fix from dgibson@linuxcare.com.
+**************************************************************************/
BOOL reopen_logs( void )
{
@@ -614,13 +615,13 @@ BOOL reopen_logs( void )
return ret;
}
-/* ************************************************************************** **
- * Force a check of the log size.
- * ************************************************************************** **
- */
+/**************************************************************************
+ Force a check of the log size.
+ ***************************************************************************/
+
void force_check_log_size( void )
{
- debug_count = 100;
+ debug_count = 100;
}
/***************************************************************************
@@ -642,10 +643,9 @@ BOOL need_to_check_log_size( void )
return( True );
}
-/* ************************************************************************** **
- * Check to see if the log has grown to be too big.
- * ************************************************************************** **
- */
+/**************************************************************************
+ Check to see if the log has grown to be too big.
+ **************************************************************************/
void check_log_size( void )
{
@@ -704,293 +704,273 @@ void check_log_size( void )
}
}
debug_count = 0;
-} /* check_log_size */
+}
+
+/*************************************************************************
+ Write an debug message on the debugfile.
+ This is called by dbghdr() and format_debug_text().
+************************************************************************/
-/* ************************************************************************** **
- * Write an debug message on the debugfile.
- * This is called by dbghdr() and format_debug_text().
- * ************************************************************************** **
- */
int Debug1( const char *format_str, ... )
{
- va_list ap;
- int old_errno = errno;
-
- debug_count++;
-
- if( stdout_logging )
- {
- va_start( ap, format_str );
- if(dbf)
- (void)x_vfprintf( dbf, format_str, ap );
- va_end( ap );
- errno = old_errno;
- return( 0 );
- }
+ va_list ap;
+ int old_errno = errno;
+
+ debug_count++;
+
+ if( stdout_logging ) {
+ va_start( ap, format_str );
+ if(dbf)
+ (void)x_vfprintf( dbf, format_str, ap );
+ va_end( ap );
+ errno = old_errno;
+ return( 0 );
+ }
#ifdef WITH_SYSLOG
- if( !lp_syslog_only() )
+ if( !lp_syslog_only() )
#endif
- {
- if( !dbf )
- {
- mode_t oldumask = umask( 022 );
-
- dbf = x_fopen( debugf, O_WRONLY|O_APPEND|O_CREAT, 0644 );
- (void)umask( oldumask );
- if( dbf )
- {
- x_setbuf( dbf, NULL );
- }
- else
- {
- errno = old_errno;
- return(0);
- }
- }
- }
+ {
+ if( !dbf ) {
+ mode_t oldumask = umask( 022 );
+
+ dbf = x_fopen( debugf, O_WRONLY|O_APPEND|O_CREAT, 0644 );
+ (void)umask( oldumask );
+ if( dbf ) {
+ x_setbuf( dbf, NULL );
+ } else {
+ errno = old_errno;
+ return(0);
+ }
+ }
+ }
#ifdef WITH_SYSLOG
- if( syslog_level < lp_syslog() )
- {
- /* map debug levels to syslog() priorities
- * note that not all DEBUG(0, ...) calls are
- * necessarily errors
- */
- static int priority_map[] = {
- LOG_ERR, /* 0 */
- LOG_WARNING, /* 1 */
- LOG_NOTICE, /* 2 */
- LOG_INFO, /* 3 */
- };
- int priority;
- pstring msgbuf;
-
- if( syslog_level >= ( sizeof(priority_map) / sizeof(priority_map[0]) )
- || syslog_level < 0)
- priority = LOG_DEBUG;
- else
- priority = priority_map[syslog_level];
-
- va_start( ap, format_str );
- vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
- va_end( ap );
-
- msgbuf[255] = '\0';
- syslog( priority, "%s", msgbuf );
- }
+ if( syslog_level < lp_syslog() ) {
+ /* map debug levels to syslog() priorities
+ * note that not all DEBUG(0, ...) calls are
+ * necessarily errors */
+ static int priority_map[] = {
+ LOG_ERR, /* 0 */
+ LOG_WARNING, /* 1 */
+ LOG_NOTICE, /* 2 */
+ LOG_INFO, /* 3 */
+ };
+ int priority;
+ pstring msgbuf;
+
+ if( syslog_level >= ( sizeof(priority_map) / sizeof(priority_map[0]) ) || syslog_level < 0)
+ priority = LOG_DEBUG;
+ else
+ priority = priority_map[syslog_level];
+
+ va_start( ap, format_str );
+ vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
+ va_end( ap );
+
+ msgbuf[255] = '\0';
+ syslog( priority, "%s", msgbuf );
+ }
#endif
- check_log_size();
+ check_log_size();
#ifdef WITH_SYSLOG
- if( !lp_syslog_only() )
+ if( !lp_syslog_only() )
#endif
- {
- va_start( ap, format_str );
- if(dbf)
- (void)x_vfprintf( dbf, format_str, ap );
- va_end( ap );
- if(dbf)
- (void)x_fflush( dbf );
- }
+ {
+ va_start( ap, format_str );
+ if(dbf)
+ (void)x_vfprintf( dbf, format_str, ap );
+ va_end( ap );
+ if(dbf)
+ (void)x_fflush( dbf );
+ }
- errno = old_errno;
+ errno = old_errno;
- return( 0 );
- } /* Debug1 */
+ return( 0 );
+}
-/* ************************************************************************** **
- * Print the buffer content via Debug1(), then reset the buffer.
- *
- * Input: none
- * Output: none
- *
- * ************************************************************************** **
- */
+/**************************************************************************
+ Print the buffer content via Debug1(), then reset the buffer.
+ Input: none
+ Output: none
+****************************************************************************/
+
static void bufr_print( void )
- {
- format_bufr[format_pos] = '\0';
- (void)Debug1( "%s", format_bufr );
- format_pos = 0;
- } /* bufr_print */
-
-/* ************************************************************************** **
- * Format the debug message text.
- *
- * Input: msg - Text to be added to the "current" debug message text.
- *
- * Output: none.
- *
- * Notes: The purpose of this is two-fold. First, each call to syslog()
- * (used by Debug1(), see above) generates a new line of syslog
- * output. This is fixed by storing the partial lines until the
- * newline character is encountered. Second, printing the debug
- * message lines when a newline is encountered allows us to add
- * spaces, thus indenting the body of the message and making it
- * more readable.
- *
- * ************************************************************************** **
- */
-static void format_debug_text( char *msg )
- {
- size_t i;
- BOOL timestamp = (!stdout_logging && (lp_timestamp_logs() ||
- !(lp_loaded())));
-
- for( i = 0; msg[i]; i++ )
- {
- /* Indent two spaces at each new line. */
- if(timestamp && 0 == format_pos)
- {
- format_bufr[0] = format_bufr[1] = ' ';
- format_pos = 2;
- }
-
- /* If there's room, copy the character to the format buffer. */
- if( format_pos < FORMAT_BUFR_MAX )
- format_bufr[format_pos++] = msg[i];
-
- /* If a newline is encountered, print & restart. */
- if( '\n' == msg[i] )
- bufr_print();
-
- /* If the buffer is full dump it out, reset it, and put out a line
- * continuation indicator.
- */
- if( format_pos >= FORMAT_BUFR_MAX )
- {
- bufr_print();
- (void)Debug1( " +>\n" );
- }
- }
-
- /* Just to be safe... */
- format_bufr[format_pos] = '\0';
- } /* format_debug_text */
-
-/* ************************************************************************** **
- * Flush debug output, including the format buffer content.
- *
- * Input: none
- * Output: none
- *
- * ************************************************************************** **
- */
+{
+ format_bufr[format_pos] = '\0';
+ (void)Debug1( "%s", format_bufr );
+ format_pos = 0;
+}
+
+/***************************************************************************
+ Format the debug message text.
+
+ Input: msg - Text to be added to the "current" debug message text.
+
+ Output: none.
+
+ Notes: The purpose of this is two-fold. First, each call to syslog()
+ (used by Debug1(), see above) generates a new line of syslog
+ output. This is fixed by storing the partial lines until the
+ newline character is encountered. Second, printing the debug
+ message lines when a newline is encountered allows us to add
+ spaces, thus indenting the body of the message and making it
+ more readable.
+**************************************************************************/
+
+static void format_debug_text( const char *msg )
+{
+ size_t i;
+ BOOL timestamp = (!stdout_logging && (lp_timestamp_logs() || !(lp_loaded())));
+
+ for( i = 0; msg[i]; i++ ) {
+ /* Indent two spaces at each new line. */
+ if(timestamp && 0 == format_pos) {
+ format_bufr[0] = format_bufr[1] = ' ';
+ format_pos = 2;
+ }
+
+ /* If there's room, copy the character to the format buffer. */
+ if( format_pos < FORMAT_BUFR_MAX )
+ format_bufr[format_pos++] = msg[i];
+
+ /* If a newline is encountered, print & restart. */
+ if( '\n' == msg[i] )
+ bufr_print();
+
+ /* If the buffer is full dump it out, reset it, and put out a line
+ * continuation indicator.
+ */
+ if( format_pos >= FORMAT_BUFR_MAX ) {
+ bufr_print();
+ (void)Debug1( " +>\n" );
+ }
+ }
+
+ /* Just to be safe... */
+ format_bufr[format_pos] = '\0';
+}
+
+/***************************************************************************
+ Flush debug output, including the format buffer content.
+
+ Input: none
+ Output: none
+***************************************************************************/
+
void dbgflush( void )
- {
- bufr_print();
- if(dbf)
- (void)x_fflush( dbf );
- } /* dbgflush */
-
-/* ************************************************************************** **
- * Print a Debug Header.
- *
- * Input: level - Debug level of the message (not the system-wide debug
- * level. )
- * file - Pointer to a string containing the name of the file
- * from which this function was called, or an empty string
- * if the __FILE__ macro is not implemented.
- * func - Pointer to a string containing the name of the function
- * from which this function was called, or an empty string
- * if the __FUNCTION__ macro is not implemented.
- * line - line number of the call to dbghdr, assuming __LINE__
- * works.
- *
- * Output: Always True. This makes it easy to fudge a call to dbghdr()
- * in a macro, since the function can be called as part of a test.
- * Eg: ( (level <= DEBUGLEVEL) && (dbghdr(level,"",line)) )
- *
- * Notes: This function takes care of setting syslog_level.
- *
- * ************************************************************************** **
- */
+{
+ bufr_print();
+ if(dbf)
+ (void)x_fflush( dbf );
+}
+
+/***************************************************************************
+ Print a Debug Header.
+
+ Input: level - Debug level of the message (not the system-wide debug
+ level. )
+ file - Pointer to a string containing the name of the file
+ from which this function was called, or an empty string
+ if the __FILE__ macro is not implemented.
+ func - Pointer to a string containing the name of the function
+ from which this function was called, or an empty string
+ if the __FUNCTION__ macro is not implemented.
+ line - line number of the call to dbghdr, assuming __LINE__
+ works.
+
+ Output: Always True. This makes it easy to fudge a call to dbghdr()
+ in a macro, since the function can be called as part of a test.
+ Eg: ( (level <= DEBUGLEVEL) && (dbghdr(level,"",line)) )
+
+ Notes: This function takes care of setting syslog_level.
+
+****************************************************************************/
BOOL dbghdr( int level, const char *file, const char *func, int line )
{
- /* Ensure we don't lose any real errno value. */
- int old_errno = errno;
-
- if( format_pos ) {
- /* This is a fudge. If there is stuff sitting in the format_bufr, then
- * the *right* thing to do is to call
- * format_debug_text( "\n" );
- * to write the remainder, and then proceed with the new header.
- * Unfortunately, there are several places in the code at which
- * the DEBUG() macro is used to build partial lines. That in mind,
- * we'll work under the assumption that an incomplete line indicates
- * that a new header is *not* desired.
- */
- return( True );
- }
+ /* Ensure we don't lose any real errno value. */
+ int old_errno = errno;
+
+ if( format_pos ) {
+ /* This is a fudge. If there is stuff sitting in the format_bufr, then
+ * the *right* thing to do is to call
+ * format_debug_text( "\n" );
+ * to write the remainder, and then proceed with the new header.
+ * Unfortunately, there are several places in the code at which
+ * the DEBUG() macro is used to build partial lines. That in mind,
+ * we'll work under the assumption that an incomplete line indicates
+ * that a new header is *not* desired.
+ */
+ return( True );
+ }
#ifdef WITH_SYSLOG
- /* Set syslog_level. */
- syslog_level = level;
+ /* Set syslog_level. */
+ syslog_level = level;
#endif
- /* Don't print a header if we're logging to stdout. */
- if( stdout_logging )
- return( True );
+ /* Don't print a header if we're logging to stdout. */
+ if( stdout_logging )
+ return( True );
- /* Print the header if timestamps are turned on. If parameters are
- * not yet loaded, then default to timestamps on.
- */
- if( lp_timestamp_logs() || !(lp_loaded()) ) {
- char header_str[200];
+ /* Print the header if timestamps are turned on. If parameters are
+ * not yet loaded, then default to timestamps on.
+ */
+ if( lp_timestamp_logs() || !(lp_loaded()) ) {
+ char header_str[200];
- header_str[0] = '\0';
+ header_str[0] = '\0';
- if( lp_debug_pid())
- slprintf(header_str,sizeof(header_str)-1,", pid=%u",(unsigned int)sys_getpid());
+ if( lp_debug_pid())
+ slprintf(header_str,sizeof(header_str)-1,", pid=%u",(unsigned int)sys_getpid());
- if( lp_debug_uid()) {
- size_t hs_len = strlen(header_str);
- slprintf(header_str + hs_len,
- sizeof(header_str) - 1 - hs_len,
- ", effective(%u, %u), real(%u, %u)",
- (unsigned int)geteuid(), (unsigned int)getegid(),
- (unsigned int)getuid(), (unsigned int)getgid());
- }
+ if( lp_debug_uid()) {
+ size_t hs_len = strlen(header_str);
+ slprintf(header_str + hs_len,
+ sizeof(header_str) - 1 - hs_len,
+ ", effective(%u, %u), real(%u, %u)",
+ (unsigned int)geteuid(), (unsigned int)getegid(),
+ (unsigned int)getuid(), (unsigned int)getgid());
+ }
- /* Print it all out at once to prevent split syslog output. */
- (void)Debug1( "[%s, %d%s] %s:%s(%d)\n",
- timestring(lp_debug_hires_timestamp()), level,
- header_str, file, func, line );
- }
+ /* Print it all out at once to prevent split syslog output. */
+ (void)Debug1( "[%s, %d%s] %s:%s(%d)\n",
+ timestring(lp_debug_hires_timestamp()), level,
+ header_str, file, func, line );
+ }
- errno = old_errno;
- return( True );
+ errno = old_errno;
+ return( True );
}
-/* ************************************************************************** **
- * Add text to the body of the "current" debug message via the format buffer.
- *
- * Input: format_str - Format string, as used in printf(), et. al.
- * ... - Variable argument list.
- *
- * ..or.. va_alist - Old style variable parameter list starting point.
- *
- * Output: Always True. See dbghdr() for more info, though this is not
- * likely to be used in the same way.
- *
- * ************************************************************************** **
- */
- BOOL dbgtext( const char *format_str, ... )
- {
- va_list ap;
- pstring msgbuf;
+/***************************************************************************
+ Add text to the body of the "current" debug message via the format buffer.
- va_start( ap, format_str );
- vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
- va_end( ap );
+ Input: format_str - Format string, as used in printf(), et. al.
+ ... - Variable argument list.
- format_debug_text( msgbuf );
+ ..or.. va_alist - Old style variable parameter list starting point.
- return( True );
- } /* dbgtext */
+ Output: Always True. See dbghdr() for more info, though this is not
+ likely to be used in the same way.
+***************************************************************************/
-/* ************************************************************************** */
+ BOOL dbgtext( const char *format_str, ... )
+{
+ va_list ap;
+ pstring msgbuf;
+
+ va_start( ap, format_str );
+ vslprintf( msgbuf, sizeof(msgbuf)-1, format_str, ap );
+ va_end( ap );
+
+ format_debug_text( msgbuf );
+
+ return( True );
+}
diff --git a/source/lib/fsusage.c b/source/lib/fsusage.c
index bb7cff06453..036f276319f 100644
--- a/source/lib/fsusage.c
+++ b/source/lib/fsusage.c
@@ -26,12 +26,17 @@
*/
static SMB_BIG_UINT adjust_blocks(SMB_BIG_UINT blocks, SMB_BIG_UINT fromsize, SMB_BIG_UINT tosize)
{
- if (fromsize == tosize) /* e.g., from 512 to 512 */
+ if (fromsize == tosize) { /* e.g., from 512 to 512 */
return blocks;
- else if (fromsize > tosize) /* e.g., from 2048 to 512 */
+ } else if (fromsize > tosize) { /* e.g., from 2048 to 512 */
return blocks * (fromsize / tosize);
- else /* e.g., from 256 to 512 */
+ } else { /* e.g., from 256 to 512 */
+ /* Protect against broken filesystems... */
+ if (fromsize == 0) {
+ fromsize = tosize;
+ }
return (blocks + 1) / (tosize / fromsize);
+ }
}
/* this does all of the system specific guff to get the free disk space.
diff --git a/source/lib/genrand.c b/source/lib/genrand.c
index bc9f21c6403..9ccddfa4c53 100644
--- a/source/lib/genrand.c
+++ b/source/lib/genrand.c
@@ -24,21 +24,32 @@
static unsigned char hash[258];
static uint32 counter;
-static unsigned char *reseed_data;
-static size_t reseed_data_size;
+
+static BOOL done_reseed = False;
+static void (*reseed_callback)(int *newseed);
/****************************************************************
Copy any user given reseed data.
*****************************************************************/
-void set_rand_reseed_data(unsigned char *data, size_t len)
+void set_rand_reseed_callback(void (*fn)(int *))
{
- SAFE_FREE(reseed_data);
- reseed_data_size = 0;
+ reseed_callback = fn;
+ set_need_random_reseed();
+}
- reseed_data = (unsigned char *)memdup(data, len);
- if (reseed_data)
- reseed_data_size = len;
+void set_need_random_reseed(void)
+{
+ done_reseed = False;
+}
+
+static void get_rand_reseed_data(int *reseed_data)
+{
+ if (reseed_callback) {
+ reseed_callback(reseed_data);
+ } else {
+ *reseed_data = 0;
+ }
}
/****************************************************************
@@ -136,6 +147,7 @@ static int do_reseed(BOOL use_fd, int fd)
unsigned char seed_inbuf[40];
uint32 v1, v2; struct timeval tval; pid_t mypid;
struct passwd *pw;
+ int reseed_data = 0;
if (use_fd) {
if (fd != -1)
@@ -183,10 +195,11 @@ static int do_reseed(BOOL use_fd, int fd)
* Add any user-given reseed data.
*/
+ get_rand_reseed_data(&reseed_data);
if (reseed_data) {
size_t i;
for (i = 0; i < sizeof(seed_inbuf); i++)
- seed_inbuf[i] ^= reseed_data[i % reseed_data_size];
+ seed_inbuf[i] ^= ((char *)(&reseed_data))[i % sizeof(reseed_data)];
}
seed_random_stream(seed_inbuf, sizeof(seed_inbuf));
@@ -198,15 +211,14 @@ static int do_reseed(BOOL use_fd, int fd)
Interface to the (hopefully) good crypto random number generator.
********************************************************************/
-void generate_random_buffer( unsigned char *out, int len, BOOL do_reseed_now)
+void generate_random_buffer( unsigned char *out, int len)
{
- static BOOL done_reseed = False;
static int urand_fd = -1;
unsigned char md4_buf[64];
unsigned char tmp_buf[16];
unsigned char *p;
- if(!done_reseed || do_reseed_now) {
+ if(!done_reseed) {
urand_fd = do_reseed(True, urand_fd);
done_reseed = True;
}
@@ -257,7 +269,7 @@ char *generate_random_str(size_t len)
if (len > sizeof(retstr)-1)
len = sizeof(retstr) -1;
- generate_random_buffer( retstr, len, False);
+ generate_random_buffer( retstr, len);
for (i = 0; i < len; i++)
retstr[i] = c_list[ retstr[i] % (sizeof(c_list)-1) ];
diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c
index f07187c68a0..0980b763adb 100644
--- a/source/lib/smbldap.c
+++ b/source/lib/smbldap.c
@@ -100,6 +100,8 @@ ATTRIB_MAP_ENTRY attrib_map_v30[] = {
{ LDAP_ATTR_MUNGED_DIAL, "sambaMungedDial" },
{ LDAP_ATTR_BAD_PASSWORD_COUNT, "sambaBadPasswordCount" },
{ LDAP_ATTR_BAD_PASSWORD_TIME, "sambaBadPasswordTime" },
+ { LDAP_ATTR_PWD_HISTORY, "sambaPasswordHistory" },
+ { LDAP_ATTR_MOD_TIMESTAMP, "modifyTimestamp" },
{ LDAP_ATTR_LIST_END, NULL }
};
@@ -345,19 +347,19 @@ static BOOL fetch_ldap_pw(char **dn, char** pw)
/* sanity checks on the mod values */
- if (attribute == NULL || *attribute == '\0')
+ if (attribute == NULL || *attribute == '\0') {
return;
+ }
+
#if 0 /* commented out after discussion with abartlet. Do not reenable.
left here so other so re-add similar code --jerry */
if (value == NULL || *value == '\0')
return;
#endif
- if (mods == NULL)
- {
+ if (mods == NULL) {
mods = (LDAPMod **) malloc(sizeof(LDAPMod *));
- if (mods == NULL)
- {
+ if (mods == NULL) {
DEBUG(0, ("make_a_mod: out of memory!\n"));
return;
}
@@ -369,17 +371,14 @@ static BOOL fetch_ldap_pw(char **dn, char** pw)
break;
}
- if (mods[i] == NULL)
- {
+ if (mods[i] == NULL) {
mods = (LDAPMod **) Realloc (mods, (i + 2) * sizeof (LDAPMod *));
- if (mods == NULL)
- {
+ if (mods == NULL) {
DEBUG(0, ("make_a_mod: out of memory!\n"));
return;
}
mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
- if (mods[i] == NULL)
- {
+ if (mods[i] == NULL) {
DEBUG(0, ("make_a_mod: out of memory!\n"));
return;
}
@@ -389,8 +388,7 @@ static BOOL fetch_ldap_pw(char **dn, char** pw)
mods[i + 1] = NULL;
}
- if (value != NULL)
- {
+ if (value != NULL) {
char *utf8_value = NULL;
j = 0;
@@ -881,37 +879,69 @@ static NTSTATUS smbldap_close(struct smbldap_state *ldap_state)
return NT_STATUS_OK;
}
-int smbldap_retry_open(struct smbldap_state *ldap_state, int *attempts)
+static BOOL got_alarm;
+
+static void (*old_handler)(int);
+
+static void gotalarm_sig(int dummy)
{
- int rc;
+ got_alarm = True;
+}
- SMB_ASSERT(ldap_state && attempts);
-
- if (*attempts != 0) {
- unsigned int sleep_time;
- uint8 rand_byte;
-
- /* Sleep for a random timeout */
- rand_byte = (char)(sys_random());
-
- sleep_time = (((*attempts)*(*attempts))/2)*rand_byte*2;
- /* we retry after (0.5, 1, 2, 3, 4.5, 6) seconds
- on average.
- */
- DEBUG(3, ("Sleeping for %u milliseconds before reconnecting\n",
- sleep_time));
- smb_msleep(sleep_time);
+static int another_ldap_try(struct smbldap_state *ldap_state, int *rc,
+ int *attempts, time_t endtime)
+{
+ time_t now = time(NULL);
+ int open_rc = LDAP_SERVER_DOWN;
+
+ if (*rc != LDAP_SERVER_DOWN)
+ goto no_next;
+
+ now = time(NULL);
+
+ if (now >= endtime) {
+ smbldap_close(ldap_state);
+ *rc = LDAP_TIMEOUT;
+ goto no_next;
}
- (*attempts)++;
- if ((rc = smbldap_open(ldap_state))) {
- DEBUG(1,("Connection to LDAP Server failed for the %d try!\n",*attempts));
- return rc;
- }
-
- return LDAP_SUCCESS;
-}
+ if (*attempts == 0) {
+ got_alarm = False;
+ old_handler = CatchSignal(SIGALRM, gotalarm_sig);
+ alarm(endtime - now);
+ }
+
+ while (1) {
+ if (*attempts != 0)
+ smb_msleep(1000);
+
+ *attempts += 1;
+
+ open_rc = smbldap_open(ldap_state);
+
+ if (open_rc == LDAP_SUCCESS) {
+ ldap_state->last_use = now;
+ return True;
+ }
+
+ if (got_alarm) {
+ *rc = LDAP_TIMEOUT;
+ break;
+ }
+
+ if (open_rc != LDAP_SUCCESS) {
+ DEBUG(1, ("Connection to LDAP server failed for the "
+ "%d try!\n", *attempts));
+ }
+ }
+
+ no_next:
+ CatchSignal(SIGALRM, old_handler);
+ alarm(0);
+ ldap_state->last_use = now;
+ return False;
+}
/*********************************************************************
********************************************************************/
@@ -924,6 +954,7 @@ int smbldap_search(struct smbldap_state *ldap_state,
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
char *utf8_filter;
+ time_t endtime = time(NULL)+lp_ldap_timeout();
SMB_ASSERT(ldap_state);
@@ -957,22 +988,10 @@ int smbldap_search(struct smbldap_state *ldap_state,
return LDAP_NO_MEMORY;
}
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
rc = ldap_search_s(ldap_state->ldap_struct, base, scope,
utf8_filter, attrs, attrsonly, res);
- }
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
SAFE_FREE(utf8_filter);
return rc;
}
@@ -982,6 +1001,7 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
char *utf8_dn;
+ time_t endtime = time(NULL)+lp_ldap_timeout();
SMB_ASSERT(ldap_state);
@@ -991,21 +1011,9 @@ int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *at
return LDAP_NO_MEMORY;
}
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
rc = ldap_modify_s(ldap_state->ldap_struct, utf8_dn, attrs);
- }
-
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
+
SAFE_FREE(utf8_dn);
return rc;
}
@@ -1015,6 +1023,7 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
char *utf8_dn;
+ time_t endtime = time(NULL)+lp_ldap_timeout();
SMB_ASSERT(ldap_state);
@@ -1024,21 +1033,9 @@ int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs
return LDAP_NO_MEMORY;
}
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
rc = ldap_add_s(ldap_state->ldap_struct, utf8_dn, attrs);
- }
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
SAFE_FREE(utf8_dn);
return rc;
}
@@ -1048,6 +1045,7 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
char *utf8_dn;
+ time_t endtime = time(NULL)+lp_ldap_timeout();
SMB_ASSERT(ldap_state);
@@ -1057,21 +1055,9 @@ int smbldap_delete(struct smbldap_state *ldap_state, const char *dn)
return LDAP_NO_MEMORY;
}
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
rc = ldap_delete_s(ldap_state->ldap_struct, utf8_dn);
- }
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
SAFE_FREE(utf8_dn);
return rc;
}
@@ -1083,26 +1069,15 @@ int smbldap_extended_operation(struct smbldap_state *ldap_state,
{
int rc = LDAP_SERVER_DOWN;
int attempts = 0;
+ time_t endtime = time(NULL)+lp_ldap_timeout();
if (!ldap_state)
return (-1);
- while ((rc == LDAP_SERVER_DOWN) && (attempts < SMBLDAP_NUM_RETRIES)) {
-
- if ((rc = smbldap_retry_open(ldap_state,&attempts)) != LDAP_SUCCESS)
- continue;
-
- rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid, reqdata,
- serverctrls, clientctrls, retoidp, retdatap);
- }
-
- if (rc == LDAP_SERVER_DOWN) {
- DEBUG(0,("%s: LDAP server is down!\n",FUNCTION_MACRO));
- smbldap_close(ldap_state);
- }
-
- ldap_state->last_use = time(NULL);
-
+ while (another_ldap_try(ldap_state, &rc, &attempts, endtime))
+ rc = ldap_extended_operation_s(ldap_state->ldap_struct, reqoid,
+ reqdata, serverctrls,
+ clientctrls, retoidp, retdatap);
return rc;
}
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index 7c5fa11c92d..1083076edd4 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -1949,7 +1949,9 @@ DATA_BLOB base64_decode_data_blob(const char *s)
s++; i++;
}
- if (*s == '=') n -= 1;
+ if ((n > 0) && (*s == '=')) {
+ n -= 1;
+ }
/* fix up length */
decoded.length = n;
@@ -1962,9 +1964,15 @@ DATA_BLOB base64_decode_data_blob(const char *s)
void base64_decode_inplace(char *s)
{
DATA_BLOB decoded = base64_decode_data_blob(s);
- memcpy(s, decoded.data, decoded.length);
- /* null terminate */
- s[decoded.length] = '\0';
+
+ if ( decoded.length != 0 ) {
+ memcpy(s, decoded.data, decoded.length);
+
+ /* null terminate */
+ s[decoded.length] = '\0';
+ } else {
+ *s = '\0';
+ }
data_blob_free(&decoded);
}
diff --git a/source/lib/util_uuid.c b/source/lib/util_uuid.c
index dc9bc920230..8f86c2109ea 100644
--- a/source/lib/util_uuid.c
+++ b/source/lib/util_uuid.c
@@ -57,7 +57,7 @@ void smb_uuid_generate_random(struct uuid *uu)
{
UUID_FLAT tmp;
- generate_random_buffer(tmp.info, sizeof(tmp.info), True);
+ generate_random_buffer(tmp.info, sizeof(tmp.info));
smb_uuid_unpack(tmp, uu);
uu->clock_seq[0] = (uu->clock_seq[0] & 0x3F) | 0x80;
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index afbd2079eac..559538aac9b 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -81,7 +81,10 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user,
if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) {
/* Encrypted mode needed, and non encrypted password supplied. */
lm_response = data_blob(NULL, 24);
- SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data);
+ if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) {
+ DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n"));
+ return False;
+ }
} else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) {
/* Encrypted mode needed, and encrypted password supplied. */
lm_response = data_blob(pass, passlen);
@@ -106,7 +109,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user,
p = smb_buf(cli->outbuf);
memcpy(p,lm_response.data,lm_response.length);
- p += passlen;
+ p += lm_response.length;
p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER);
p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
@@ -675,7 +678,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
for checking the first reply from the server */
cli_calculate_sign_mac(cli);
- if (!cli_check_sign_mac(cli, True)) {
+ if (!cli_check_sign_mac(cli)) {
nt_status = NT_STATUS_ACCESS_DENIED;
}
}
diff --git a/source/libsmb/clidgram.c b/source/libsmb/clidgram.c
index c4675f1938a..ba65c46d16e 100644
--- a/source/libsmb/clidgram.c
+++ b/source/libsmb/clidgram.c
@@ -63,7 +63,7 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, const char *mailslot,
/* Setup the smb part. */
ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
memcpy(tmp,ptr,4);
- set_message(ptr,17,17 + len,True);
+ set_message(ptr,17,strlen(mailslot) + 1 + len,True);
memcpy(ptr,tmp,4);
SCVAL(ptr,smb_com,SMBtrans);
diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c
index 281ee3af845..974ebf91f5c 100644
--- a/source/libsmb/clientgen.c
+++ b/source/libsmb/clientgen.c
@@ -117,7 +117,7 @@ BOOL cli_receive_smb(struct cli_state *cli)
return ret;
}
- if (!cli_check_sign_mac(cli, True)) {
+ if (!cli_check_sign_mac(cli)) {
DEBUG(0, ("SMB Signature verification failed on incoming packet!\n"));
cli->smb_rw_error = READ_BAD_SIG;
close(cli->fd);
diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c
index b9a3dda4944..5fcde4654ad 100644
--- a/source/libsmb/clikrb5.c
+++ b/source/libsmb/clikrb5.c
@@ -442,8 +442,6 @@ failed:
krb5_error_code err;
BOOL ret = False;
- memset(session_key, 0, 16);
-
if (remote)
err = krb5_auth_con_getremotesubkey(context, auth_context, &skey);
else
diff --git a/source/libsmb/ntlmssp.c b/source/libsmb/ntlmssp.c
index 66d48afc463..6e41a61bf1b 100644
--- a/source/libsmb/ntlmssp.c
+++ b/source/libsmb/ntlmssp.c
@@ -103,7 +103,7 @@ void debug_ntlmssp_flags(uint32 neg_flags)
static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state)
{
static uchar chal[8];
- generate_random_buffer(chal, sizeof(chal), False);
+ generate_random_buffer(chal, sizeof(chal));
return chal;
}
@@ -960,7 +960,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
E_md4hash(ntlmssp_state->password, nt_hash);
lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
- generate_random_buffer(lm_response.data, 8, False);
+ generate_random_buffer(lm_response.data, 8);
memset(lm_response.data+8, 0, 16);
memcpy(session_nonce, challenge_blob.data, 8);
@@ -1022,7 +1022,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
/* Make up a new session key */
uint8 client_session_key[16];
- generate_random_buffer(client_session_key, sizeof(client_session_key), False);
+ generate_random_buffer(client_session_key, sizeof(client_session_key));
/* Encrypt the new session key with the old one */
encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key));
diff --git a/source/libsmb/passchange.c b/source/libsmb/passchange.c
index 9f46c131fee..8bce9c86a1e 100644
--- a/source/libsmb/passchange.c
+++ b/source/libsmb/passchange.c
@@ -144,6 +144,8 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
init_creds(&creds, "", "", NULL);
cli_init_creds(&cli, &creds);
+ cli.pipe_auth_flags = 0;
+
result = NT_STATUS_UNSUCCESSFUL;
/* OK, this is ugly, but... */
diff --git a/source/libsmb/smb_signing.c b/source/libsmb/smb_signing.c
index 8c59e49ebb9..39131debf5e 100644
--- a/source/libsmb/smb_signing.c
+++ b/source/libsmb/smb_signing.c
@@ -627,9 +627,9 @@ void cli_calculate_sign_mac(struct cli_state *cli)
* which had a bad checksum, True otherwise.
*/
-BOOL cli_check_sign_mac(struct cli_state *cli, BOOL must_be_ok)
+BOOL cli_check_sign_mac(struct cli_state *cli)
{
- if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, must_be_ok)) {
+ if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) {
free_signing_context(&cli->sign_info);
return False;
}
diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c
index 44f7428086b..9f936b77aec 100644
--- a/source/libsmb/smbencrypt.c
+++ b/source/libsmb/smbencrypt.c
@@ -352,7 +352,7 @@ static DATA_BLOB NTLMv2_generate_client_data(const DATA_BLOB *names_blob)
DATA_BLOB response = data_blob(NULL, 0);
char long_date[8];
- generate_random_buffer(client_chal, sizeof(client_chal), False);
+ generate_random_buffer(client_chal, sizeof(client_chal));
put_long_date(long_date, time(NULL));
@@ -406,7 +406,7 @@ static DATA_BLOB LMv2_generate_response(const uchar ntlm_v2_hash[16],
/* LMv2 */
/* client-supplied random data */
- generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length, False);
+ generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length);
/* Given that data, and the challenge from the server, generate a response */
SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response);
@@ -476,7 +476,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags)
memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len);
- generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len, True);
+ generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len);
/*
* The length of the new password is in the last 4 bytes of
diff --git a/source/nsswitch/wbinfo.c b/source/nsswitch/wbinfo.c
index ce48e9ae652..0028982d201 100644
--- a/source/nsswitch/wbinfo.c
+++ b/source/nsswitch/wbinfo.c
@@ -398,6 +398,27 @@ static BOOL wbinfo_sid_to_uid(char *sid)
ZERO_STRUCT(request);
ZERO_STRUCT(response);
+ /* First see whether the SID is actually a user -- otherwise
+ * winbind might end up a uid number for a group SID and this
+ * is asking for trouble later. */
+
+ fstrcpy(request.data.sid, sid);
+
+ if (winbindd_request(WINBINDD_LOOKUPSID, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
+ d_printf("Could not lookup sid %s\n", sid);
+ return False;
+ }
+
+ if (response.data.name.type != SID_NAME_USER) {
+ d_printf("SID is of type %s\n",
+ sid_type_lookup(response.data.name.type));
+ return False;
+ }
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
/* Send request */
fstrcpy(request.data.sid, sid);
@@ -421,6 +442,26 @@ static BOOL wbinfo_sid_to_gid(char *sid)
ZERO_STRUCT(request);
ZERO_STRUCT(response);
+ /* First see whether the SID is actually a group -- otherwise
+ * winbind might end up a gid number for a user SID and this
+ * is asking for trouble later. */
+
+ fstrcpy(request.data.sid, sid);
+
+ if (winbindd_request(WINBINDD_LOOKUPSID, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
+ d_printf("Could not lookup sid %s\n", sid);
+ return False;
+ }
+
+ if ((response.data.name.type != SID_NAME_DOM_GRP) &&
+ (response.data.name.type != SID_NAME_ALIAS) &&
+ (response.data.name.type != SID_NAME_WKN_GRP)) {
+ d_printf("SID is of type %s\n",
+ sid_type_lookup(response.data.name.type));
+ return False;
+ }
+
/* Send request */
fstrcpy(request.data.sid, sid);
@@ -580,7 +621,7 @@ static BOOL wbinfo_auth_crap(char *username)
return False;
}
- generate_random_buffer(request.data.auth_crap.chal, 8, False);
+ generate_random_buffer(request.data.auth_crap.chal, 8);
SMBencrypt(pass, request.data.auth_crap.chal,
(uchar *)request.data.auth_crap.lm_resp);
diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c
index 50b6f0a87fb..d08aa84face 100644
--- a/source/nsswitch/winbindd.c
+++ b/source/nsswitch/winbindd.c
@@ -188,6 +188,17 @@ static void sighup_handler(int signum)
sys_select_signal();
}
+static void sigchld_handler(int signum)
+{
+ pid_t pid;
+ int status;
+
+ while ((pid = wait(&status)) != -1 || errno == EINTR) {
+ continue; /* Reap children */
+ }
+ sys_select_signal();
+}
+
/* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
static void msg_reload_services(int msg_type, pid_t src, void *buf, size_t len)
{
@@ -888,12 +899,14 @@ int main(int argc, char **argv)
BlockSignals(False, SIGUSR1);
BlockSignals(False, SIGUSR2);
BlockSignals(False, SIGHUP);
+ BlockSignals(False, SIGCHLD);
/* Setup signal handlers */
CatchSignal(SIGINT, termination_handler); /* Exit on these sigs */
CatchSignal(SIGQUIT, termination_handler);
CatchSignal(SIGTERM, termination_handler);
+ CatchSignal(SIGCHLD, sigchld_handler);
CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
diff --git a/source/nsswitch/winbindd_cm.c b/source/nsswitch/winbindd_cm.c
index 04f87fc1a2f..ad49df3982b 100644
--- a/source/nsswitch/winbindd_cm.c
+++ b/source/nsswitch/winbindd_cm.c
@@ -70,7 +70,6 @@ struct winbindd_cm_conn {
fstring domain;
fstring controller;
fstring pipe_name;
- size_t mutex_ref_count;
struct cli_state *cli;
POLICY_HND pol;
};
diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c
index 25f53e7a535..81d4e69ccd6 100644
--- a/source/nsswitch/winbindd_pam.c
+++ b/source/nsswitch/winbindd_pam.c
@@ -190,7 +190,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
/* do password magic */
- generate_random_buffer(chal, 8, False);
+ generate_random_buffer(chal, 8);
SMBencrypt(state->request.data.auth.pass, chal, local_lm_response);
SMBNTencrypt(state->request.data.auth.pass, chal, local_nt_response);
diff --git a/source/nsswitch/wins.c b/source/nsswitch/wins.c
index b71995998f5..a1c4f4deec0 100644
--- a/source/nsswitch/wins.c
+++ b/source/nsswitch/wins.c
@@ -90,7 +90,7 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
{
int fd = -1;
struct ip_service *address = NULL;
- struct in_addr *ret;
+ struct in_addr *ret = NULL;
int j, flags = 0;
if (!initialised) {
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 0710c36514b..978ea89d5c6 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -176,7 +176,7 @@ typedef struct
BOOL bWinbindTrustedDomainsOnly;
BOOL bWinbindNestedGroups;
char *szWinbindBackend;
- char *szIdmapBackend;
+ char **szIdmapBackend;
char *szAddShareCommand;
char *szChangeShareCommand;
char *szDeleteShareCommand;
@@ -1165,7 +1165,7 @@ static struct parm_struct parm_table[] = {
{N_("Winbind options"), P_SEP, P_SEPARATOR},
{"enable rid algorithm", P_BOOL, P_GLOBAL, &Globals.bEnableRidAlgorithm, NULL, NULL, FLAG_DEPRECATED},
- {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED},
+ {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED},
{"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED},
{"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE},
{"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED},
@@ -1710,7 +1710,7 @@ FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
-FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
+FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend)
FN_GLOBAL_BOOL(lp_enable_rid_algorithm, &Globals.bEnableRidAlgorithm)
#ifdef WITH_LDAP_SAMCONFIG
@@ -3552,14 +3552,14 @@ static void dump_a_service(service * pService, FILE * f)
((char *)pService) + pdiff, f);
fprintf(f, "\n");
}
+ }
- if (pService->param_opt != NULL) {
- data = pService->param_opt;
- while(data) {
- fprintf(f, "\t%s = %s\n", data->key, data->value);
- data = data->next;
- }
- }
+ if (pService->param_opt != NULL) {
+ data = pService->param_opt;
+ while(data) {
+ fprintf(f, "\t%s = %s\n", data->key, data->value);
+ data = data->next;
+ }
}
}
@@ -4320,7 +4320,7 @@ int lp_maxprintjobs(int snum)
BOOL lp_use_sendfile(int snum)
{
- return (_lp_use_sendfile(snum) && !srv_is_signing_active());
+ return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
}
/*******************************************************************
diff --git a/source/passdb/machine_sid.c b/source/passdb/machine_sid.c
index 47b9e2d487e..ce1354ce818 100644
--- a/source/passdb/machine_sid.c
+++ b/source/passdb/machine_sid.c
@@ -67,7 +67,7 @@ static void generate_random_sid(DOM_SID *sid)
sid->num_auths = 0;
sid->sub_auths[sid->num_auths++] = 21;
- generate_random_buffer(raw_sid_data, 12, True);
+ generate_random_buffer(raw_sid_data, 12);
for (i = 0; i < 3; i++)
sid->sub_auths[sid->num_auths++] = IVAL(raw_sid_data, i*4);
}
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index c3a423c2636..2f9742e17da 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -932,7 +932,7 @@ BOOL local_password_change(const char *user_name, int local_flags,
if ((local_flags & LOCAL_ADD_USER) || (local_flags & LOCAL_DELETE_USER)) {
/* Might not exist in /etc/passwd. Use rid algorithm here */
if (!NT_STATUS_IS_OK(pdb_init_sam_new(&sam_pass, user_name, 0))) {
- slprintf(err_str, err_str_len-1, "Failed to initialise SAM_ACCOUNT for user %s.\n", user_name);
+ slprintf(err_str, err_str_len-1, "Failed to initialise SAM_ACCOUNT for user %s. Does this user exist in the UNIX password database ?\n", user_name);
return False;
}
} else {
@@ -1301,6 +1301,7 @@ BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_
#define TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd"
#define TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd"
+#define TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd"
/**********************************************************************
Intialize a SAM_ACCOUNT struct from a BYTE buffer of size len
@@ -1308,7 +1309,7 @@ BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_
BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
{
- return(init_sam_from_buffer_v1(sampass, buf, buflen));
+ return(init_sam_from_buffer_v2(sampass, buf, buflen));
}
/**********************************************************************
@@ -1317,7 +1318,7 @@ BOOL init_sam_from_buffer(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
uint32 init_buffer_from_sam (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
{
- return(init_buffer_from_sam_v1(buf, sampass, size_only));
+ return(init_buffer_from_sam_v2(buf, sampass, size_only));
}
@@ -1354,48 +1355,50 @@ BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
uint16 acct_ctrl, logon_divs;
uint16 bad_password_count, logon_count;
uint8 *hours;
- static uint8 *lm_pw_ptr, *nt_pw_ptr;
+ uint8 *lm_pw_ptr, *nt_pw_ptr;
uint32 len = 0;
uint32 lm_pw_len, nt_pw_len, hourslen;
BOOL ret = True;
if(sampass == NULL || buf == NULL) {
- DEBUG(0, ("init_sam_from_buffer: NULL parameters found!\n"));
+ DEBUG(0, ("init_sam_from_buffer_v0: NULL parameters found!\n"));
return False;
}
-
+
+/* TDB_FORMAT_STRING_V0 "ddddddBBBBBBBBBBBBddBBwdwdBwwd" */
+
/* unpack the buffer into variables */
len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V0,
- &logon_time,
- &logoff_time,
- &kickoff_time,
- &pass_last_set_time,
- &pass_can_change_time,
- &pass_must_change_time,
- &username_len, &username,
- &domain_len, &domain,
- &nt_username_len, &nt_username,
- &fullname_len, &fullname,
- &homedir_len, &homedir,
- &dir_drive_len, &dir_drive,
- &logon_script_len, &logon_script,
- &profile_path_len, &profile_path,
- &acct_desc_len, &acct_desc,
- &workstations_len, &workstations,
- &unknown_str_len, &unknown_str,
- &munged_dial_len, &munged_dial,
- &user_rid,
- &group_rid,
- &lm_pw_len, &lm_pw_ptr,
- &nt_pw_len, &nt_pw_ptr,
- &acct_ctrl,
- &remove_me, /* remove on the next TDB_FORMAT upgarde */
- &logon_divs,
- &hours_len,
- &hourslen, &hours,
- &bad_password_count,
- &logon_count,
- &unknown_6);
+ &logon_time, /* d */
+ &logoff_time, /* d */
+ &kickoff_time, /* d */
+ &pass_last_set_time, /* d */
+ &pass_can_change_time, /* d */
+ &pass_must_change_time, /* d */
+ &username_len, &username, /* B */
+ &domain_len, &domain, /* B */
+ &nt_username_len, &nt_username, /* B */
+ &fullname_len, &fullname, /* B */
+ &homedir_len, &homedir, /* B */
+ &dir_drive_len, &dir_drive, /* B */
+ &logon_script_len, &logon_script, /* B */
+ &profile_path_len, &profile_path, /* B */
+ &acct_desc_len, &acct_desc, /* B */
+ &workstations_len, &workstations, /* B */
+ &unknown_str_len, &unknown_str, /* B */
+ &munged_dial_len, &munged_dial, /* B */
+ &user_rid, /* d */
+ &group_rid, /* d */
+ &lm_pw_len, &lm_pw_ptr, /* B */
+ &nt_pw_len, &nt_pw_ptr, /* B */
+ &acct_ctrl, /* w */
+ &remove_me, /* remove on the next TDB_FORMAT upgarde */ /* d */
+ &logon_divs, /* w */
+ &hours_len, /* d */
+ &hourslen, &hours, /* B */
+ &bad_password_count, /* w */
+ &logon_count, /* w */
+ &unknown_6); /* d */
if (len == (uint32) -1) {
ret = False;
@@ -1465,6 +1468,7 @@ BOOL init_sam_from_buffer_v0(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
}
}
+ pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
pdb_set_hours_len(sampass, hours_len, PDB_SET);
@@ -1489,15 +1493,15 @@ done:
SAFE_FREE(workstations);
SAFE_FREE(munged_dial);
SAFE_FREE(unknown_str);
+ SAFE_FREE(lm_pw_ptr);
+ SAFE_FREE(nt_pw_ptr);
SAFE_FREE(hours);
return ret;
}
-
-uint32 init_buffer_from_sam_v0 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
+BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
{
- size_t len, buflen;
/* times are stored as 32bit integer
take care on system with 64bit wide time_t
@@ -1505,237 +1509,184 @@ uint32 init_buffer_from_sam_v0 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
uint32 logon_time,
logoff_time,
kickoff_time,
+ bad_password_time,
pass_last_set_time,
pass_can_change_time,
pass_must_change_time;
-
- uint32 user_rid, group_rid;
-
- const char *username;
- const char *domain;
- const char *nt_username;
- const char *dir_drive;
- const char *unknown_str;
- const char *munged_dial;
- const char *fullname;
- const char *homedir;
- const char *logon_script;
- const char *profile_path;
- const char *acct_desc;
- const char *workstations;
+ char *username;
+ char *domain;
+ char *nt_username;
+ char *dir_drive;
+ char *unknown_str;
+ char *munged_dial;
+ char *fullname;
+ char *homedir;
+ char *logon_script;
+ char *profile_path;
+ char *acct_desc;
+ char *workstations;
uint32 username_len, domain_len, nt_username_len,
dir_drive_len, unknown_str_len, munged_dial_len,
fullname_len, homedir_len, logon_script_len,
profile_path_len, acct_desc_len, workstations_len;
-
- const uint8 *lm_pw;
- const uint8 *nt_pw;
- uint32 lm_pw_len = 16;
- uint32 nt_pw_len = 16;
-
- /* do we have a valid SAM_ACCOUNT pointer? */
- if (sampass == NULL) {
- DEBUG(0, ("init_buffer_from_sam: SAM_ACCOUNT is NULL!\n"));
- return -1;
- }
+
+ uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
+ uint16 acct_ctrl, logon_divs;
+ uint16 bad_password_count, logon_count;
+ uint8 *hours;
+ uint8 *lm_pw_ptr, *nt_pw_ptr;
+ uint32 len = 0;
+ uint32 lm_pw_len, nt_pw_len, hourslen;
+ BOOL ret = True;
- *buf = NULL;
- buflen = 0;
+ if(sampass == NULL || buf == NULL) {
+ DEBUG(0, ("init_sam_from_buffer_v1: NULL parameters found!\n"));
+ return False;
+ }
- logon_time = (uint32)pdb_get_logon_time(sampass);
- logoff_time = (uint32)pdb_get_logoff_time(sampass);
- kickoff_time = (uint32)pdb_get_kickoff_time(sampass);
- pass_can_change_time = (uint32)pdb_get_pass_can_change_time(sampass);
- pass_must_change_time = (uint32)pdb_get_pass_must_change_time(sampass);
- pass_last_set_time = (uint32)pdb_get_pass_last_set_time(sampass);
+/* TDB_FORMAT_STRING_V1 "dddddddBBBBBBBBBBBBddBBwdwdBwwd" */
- user_rid = pdb_get_user_rid(sampass);
- group_rid = pdb_get_group_rid(sampass);
+ /* unpack the buffer into variables */
+ len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
+ &logon_time, /* d */
+ &logoff_time, /* d */
+ &kickoff_time, /* d */
+ /* Change from V0 is addition of bad_password_time field. */
+ &bad_password_time, /* d */
+ &pass_last_set_time, /* d */
+ &pass_can_change_time, /* d */
+ &pass_must_change_time, /* d */
+ &username_len, &username, /* B */
+ &domain_len, &domain, /* B */
+ &nt_username_len, &nt_username, /* B */
+ &fullname_len, &fullname, /* B */
+ &homedir_len, &homedir, /* B */
+ &dir_drive_len, &dir_drive, /* B */
+ &logon_script_len, &logon_script, /* B */
+ &profile_path_len, &profile_path, /* B */
+ &acct_desc_len, &acct_desc, /* B */
+ &workstations_len, &workstations, /* B */
+ &unknown_str_len, &unknown_str, /* B */
+ &munged_dial_len, &munged_dial, /* B */
+ &user_rid, /* d */
+ &group_rid, /* d */
+ &lm_pw_len, &lm_pw_ptr, /* B */
+ &nt_pw_len, &nt_pw_ptr, /* B */
+ &acct_ctrl, /* w */
+ &remove_me, /* d */
+ &logon_divs, /* w */
+ &hours_len, /* d */
+ &hourslen, &hours, /* B */
+ &bad_password_count, /* w */
+ &logon_count, /* w */
+ &unknown_6); /* d */
+
+ if (len == (uint32) -1) {
+ ret = False;
+ goto done;
+ }
- username = pdb_get_username(sampass);
- if (username)
- username_len = strlen(username) +1;
- else
- username_len = 0;
+ pdb_set_logon_time(sampass, logon_time, PDB_SET);
+ pdb_set_logoff_time(sampass, logoff_time, PDB_SET);
+ pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET);
- domain = pdb_get_domain(sampass);
- if (domain)
- domain_len = strlen(domain) +1;
- else
- domain_len = 0;
+ /* Change from V0 is addition of bad_password_time field. */
+ pdb_set_bad_password_time(sampass, bad_password_time, PDB_SET);
+ pdb_set_pass_can_change_time(sampass, pass_can_change_time, PDB_SET);
+ pdb_set_pass_must_change_time(sampass, pass_must_change_time, PDB_SET);
+ pdb_set_pass_last_set_time(sampass, pass_last_set_time, PDB_SET);
- nt_username = pdb_get_nt_username(sampass);
- if (nt_username)
- nt_username_len = strlen(nt_username) +1;
- else
- nt_username_len = 0;
+ pdb_set_username(sampass, username, PDB_SET);
+ pdb_set_domain(sampass, domain, PDB_SET);
+ pdb_set_nt_username(sampass, nt_username, PDB_SET);
+ pdb_set_fullname(sampass, fullname, PDB_SET);
- fullname = pdb_get_fullname(sampass);
- if (fullname)
- fullname_len = strlen(fullname) +1;
- else
- fullname_len = 0;
+ if (homedir) {
+ pdb_set_homedir(sampass, homedir, PDB_SET);
+ }
+ else {
+ pdb_set_homedir(sampass,
+ talloc_sub_basic(sampass->mem_ctx, username, lp_logon_home()),
+ PDB_DEFAULT);
+ }
- /*
- * Only updates fields which have been set (not defaults from smb.conf)
- */
+ if (dir_drive)
+ pdb_set_dir_drive(sampass, dir_drive, PDB_SET);
+ else {
+ pdb_set_dir_drive(sampass,
+ talloc_sub_basic(sampass->mem_ctx, username, lp_logon_drive()),
+ PDB_DEFAULT);
+ }
- if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE))
- dir_drive = pdb_get_dir_drive(sampass);
- else
- dir_drive = NULL;
- if (dir_drive)
- dir_drive_len = strlen(dir_drive) +1;
- else
- dir_drive_len = 0;
+ if (logon_script)
+ pdb_set_logon_script(sampass, logon_script, PDB_SET);
+ else {
+ pdb_set_logon_script(sampass,
+ talloc_sub_basic(sampass->mem_ctx, username, lp_logon_script()),
+ PDB_DEFAULT);
+ }
+
+ if (profile_path) {
+ pdb_set_profile_path(sampass, profile_path, PDB_SET);
+ } else {
+ pdb_set_profile_path(sampass,
+ talloc_sub_basic(sampass->mem_ctx, username, lp_logon_path()),
+ PDB_DEFAULT);
+ }
- if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME))
- homedir = pdb_get_homedir(sampass);
- else
- homedir = NULL;
- if (homedir)
- homedir_len = strlen(homedir) +1;
- else
- homedir_len = 0;
+ pdb_set_acct_desc(sampass, acct_desc, PDB_SET);
+ pdb_set_workstations(sampass, workstations, PDB_SET);
+ pdb_set_munged_dial(sampass, munged_dial, PDB_SET);
- if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT))
- logon_script = pdb_get_logon_script(sampass);
- else
- logon_script = NULL;
- if (logon_script)
- logon_script_len = strlen(logon_script) +1;
- else
- logon_script_len = 0;
+ if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
+ if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr, PDB_SET)) {
+ ret = False;
+ goto done;
+ }
+ }
- if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE))
- profile_path = pdb_get_profile_path(sampass);
- else
- profile_path = NULL;
- if (profile_path)
- profile_path_len = strlen(profile_path) +1;
- else
- profile_path_len = 0;
-
- lm_pw = pdb_get_lanman_passwd(sampass);
- if (!lm_pw)
- lm_pw_len = 0;
-
- nt_pw = pdb_get_nt_passwd(sampass);
- if (!nt_pw)
- nt_pw_len = 0;
-
- acct_desc = pdb_get_acct_desc(sampass);
- if (acct_desc)
- acct_desc_len = strlen(acct_desc) +1;
- else
- acct_desc_len = 0;
+ if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
+ if (!pdb_set_nt_passwd(sampass, nt_pw_ptr, PDB_SET)) {
+ ret = False;
+ goto done;
+ }
+ }
- workstations = pdb_get_workstations(sampass);
- if (workstations)
- workstations_len = strlen(workstations) +1;
- else
- workstations_len = 0;
+ pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
- unknown_str = NULL;
- unknown_str_len = 0;
+ pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
+ pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
+ pdb_set_hours_len(sampass, hours_len, PDB_SET);
+ pdb_set_bad_password_count(sampass, bad_password_count, PDB_SET);
+ pdb_set_logon_count(sampass, logon_count, PDB_SET);
+ pdb_set_unknown_6(sampass, unknown_6, PDB_SET);
+ pdb_set_acct_ctrl(sampass, acct_ctrl, PDB_SET);
+ pdb_set_logon_divs(sampass, logon_divs, PDB_SET);
+ pdb_set_hours(sampass, hours, PDB_SET);
- munged_dial = pdb_get_munged_dial(sampass);
- if (munged_dial)
- munged_dial_len = strlen(munged_dial) +1;
- else
- munged_dial_len = 0;
-
- /* one time to get the size needed */
- len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V0,
- logon_time,
- logoff_time,
- kickoff_time,
- pass_last_set_time,
- pass_can_change_time,
- pass_must_change_time,
- username_len, username,
- domain_len, domain,
- nt_username_len, nt_username,
- fullname_len, fullname,
- homedir_len, homedir,
- dir_drive_len, dir_drive,
- logon_script_len, logon_script,
- profile_path_len, profile_path,
- acct_desc_len, acct_desc,
- workstations_len, workstations,
- unknown_str_len, unknown_str,
- munged_dial_len, munged_dial,
- user_rid,
- group_rid,
- lm_pw_len, lm_pw,
- nt_pw_len, nt_pw,
- pdb_get_acct_ctrl(sampass),
- 0, /* was: fileds_present, to be removed on format change */
- pdb_get_logon_divs(sampass),
- pdb_get_hours_len(sampass),
- MAX_HOURS_LEN, pdb_get_hours(sampass),
- pdb_get_bad_password_count(sampass),
- pdb_get_logon_count(sampass),
- pdb_get_unknown_6(sampass));
-
-
- if (size_only)
- return buflen;
+done:
- /* malloc the space needed */
- if ( (*buf=(uint8*)malloc(len)) == NULL) {
- DEBUG(0,("init_buffer_from_sam: Unable to malloc() memory for buffer!\n"));
- return (-1);
- }
-
- /* now for the real call to tdb_pack() */
- buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V0,
- logon_time,
- logoff_time,
- kickoff_time,
- pass_last_set_time,
- pass_can_change_time,
- pass_must_change_time,
- username_len, username,
- domain_len, domain,
- nt_username_len, nt_username,
- fullname_len, fullname,
- homedir_len, homedir,
- dir_drive_len, dir_drive,
- logon_script_len, logon_script,
- profile_path_len, profile_path,
- acct_desc_len, acct_desc,
- workstations_len, workstations,
- unknown_str_len, unknown_str,
- munged_dial_len, munged_dial,
- user_rid,
- group_rid,
- lm_pw_len, lm_pw,
- nt_pw_len, nt_pw,
- pdb_get_acct_ctrl(sampass),
- 0, /* was: fileds_present, to be removed on format change */
- pdb_get_logon_divs(sampass),
- pdb_get_hours_len(sampass),
- MAX_HOURS_LEN, pdb_get_hours(sampass),
- pdb_get_bad_password_count(sampass),
- pdb_get_logon_count(sampass),
- pdb_get_unknown_6(sampass));
-
-
- /* check to make sure we got it correct */
- if (buflen != len) {
- DEBUG(0, ("init_buffer_from_sam: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
- (unsigned long)buflen, (unsigned long)len));
- /* error */
- SAFE_FREE (*buf);
- return (-1);
- }
+ SAFE_FREE(username);
+ SAFE_FREE(domain);
+ SAFE_FREE(nt_username);
+ SAFE_FREE(fullname);
+ SAFE_FREE(homedir);
+ SAFE_FREE(dir_drive);
+ SAFE_FREE(logon_script);
+ SAFE_FREE(profile_path);
+ SAFE_FREE(acct_desc);
+ SAFE_FREE(workstations);
+ SAFE_FREE(munged_dial);
+ SAFE_FREE(unknown_str);
+ SAFE_FREE(lm_pw_ptr);
+ SAFE_FREE(nt_pw_ptr);
+ SAFE_FREE(hours);
- return (buflen);
+ return ret;
}
-BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
+BOOL init_sam_from_buffer_v2(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
{
/* times are stored as 32bit integer
@@ -1765,53 +1716,58 @@ BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
fullname_len, homedir_len, logon_script_len,
profile_path_len, acct_desc_len, workstations_len;
- uint32 user_rid, group_rid, remove_me, hours_len, unknown_6;
+ uint32 user_rid, group_rid, hours_len, unknown_6;
uint16 acct_ctrl, logon_divs;
uint16 bad_password_count, logon_count;
uint8 *hours;
- static uint8 *lm_pw_ptr, *nt_pw_ptr;
+ uint8 *lm_pw_ptr, *nt_pw_ptr, *nt_pw_hist_ptr;
uint32 len = 0;
- uint32 lm_pw_len, nt_pw_len, hourslen;
+ uint32 lm_pw_len, nt_pw_len, nt_pw_hist_len, hourslen;
+ uint32 pwHistLen = 0;
BOOL ret = True;
if(sampass == NULL || buf == NULL) {
- DEBUG(0, ("init_sam_from_buffer: NULL parameters found!\n"));
+ DEBUG(0, ("init_sam_from_buffer_v2: NULL parameters found!\n"));
return False;
}
+/* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
+
/* unpack the buffer into variables */
- len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V1,
- &logon_time,
- &logoff_time,
- &kickoff_time,
- &bad_password_time,
- &pass_last_set_time,
- &pass_can_change_time,
- &pass_must_change_time,
- &username_len, &username,
- &domain_len, &domain,
- &nt_username_len, &nt_username,
- &fullname_len, &fullname,
- &homedir_len, &homedir,
- &dir_drive_len, &dir_drive,
- &logon_script_len, &logon_script,
- &profile_path_len, &profile_path,
- &acct_desc_len, &acct_desc,
- &workstations_len, &workstations,
- &unknown_str_len, &unknown_str,
- &munged_dial_len, &munged_dial,
- &user_rid,
- &group_rid,
- &lm_pw_len, &lm_pw_ptr,
- &nt_pw_len, &nt_pw_ptr,
- &acct_ctrl,
- &remove_me,
- &logon_divs,
- &hours_len,
- &hourslen, &hours,
- &bad_password_count,
- &logon_count,
- &unknown_6);
+ len = tdb_unpack ((char *)buf, buflen, TDB_FORMAT_STRING_V2,
+ &logon_time, /* d */
+ &logoff_time, /* d */
+ &kickoff_time, /* d */
+ &bad_password_time, /* d */
+ &pass_last_set_time, /* d */
+ &pass_can_change_time, /* d */
+ &pass_must_change_time, /* d */
+ &username_len, &username, /* B */
+ &domain_len, &domain, /* B */
+ &nt_username_len, &nt_username, /* B */
+ &fullname_len, &fullname, /* B */
+ &homedir_len, &homedir, /* B */
+ &dir_drive_len, &dir_drive, /* B */
+ &logon_script_len, &logon_script, /* B */
+ &profile_path_len, &profile_path, /* B */
+ &acct_desc_len, &acct_desc, /* B */
+ &workstations_len, &workstations, /* B */
+ &unknown_str_len, &unknown_str, /* B */
+ &munged_dial_len, &munged_dial, /* B */
+ &user_rid, /* d */
+ &group_rid, /* d */
+ &lm_pw_len, &lm_pw_ptr, /* B */
+ &nt_pw_len, &nt_pw_ptr, /* B */
+ /* Change from V1 is addition of password history field. */
+ &nt_pw_hist_len, &nt_pw_hist_ptr, /* B */
+ &acct_ctrl, /* w */
+ /* Also "remove_me" field was removed. */
+ &logon_divs, /* w */
+ &hours_len, /* d */
+ &hourslen, &hours, /* B */
+ &bad_password_count, /* w */
+ &logon_count, /* w */
+ &unknown_6); /* d */
if (len == (uint32) -1) {
ret = False;
@@ -1882,6 +1838,33 @@ BOOL init_sam_from_buffer_v1(SAM_ACCOUNT *sampass, uint8 *buf, uint32 buflen)
}
}
+ /* Change from V1 is addition of password history field. */
+ account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
+ if (pwHistLen) {
+ char *pw_hist = malloc(pwHistLen * NT_HASH_LEN);
+ if (!pw_hist) {
+ ret = False;
+ goto done;
+ }
+ memset(pw_hist, '\0', pwHistLen * NT_HASH_LEN);
+ if (nt_pw_hist_ptr && nt_pw_hist_len) {
+ int i;
+ SMB_ASSERT((nt_pw_hist_len % NT_HASH_LEN) == 0);
+ nt_pw_hist_len /= NT_HASH_LEN;
+ for (i = 0; (i < pwHistLen) && (i < nt_pw_hist_len); i++) {
+ memcpy(&pw_hist[i*NT_HASH_LEN], &nt_pw_hist_ptr[i*NT_HASH_LEN], NT_HASH_LEN);
+ }
+ }
+ if (!pdb_set_pw_history(sampass, pw_hist, pwHistLen, PDB_SET)) {
+ SAFE_FREE(pw_hist);
+ ret = False;
+ goto done;
+ }
+ SAFE_FREE(pw_hist);
+ } else {
+ pdb_set_pw_history(sampass, NULL, 0, PDB_SET);
+ }
+
pdb_set_user_sid_from_rid(sampass, user_rid, PDB_SET);
pdb_set_group_sid_from_rid(sampass, group_rid, PDB_SET);
pdb_set_hours_len(sampass, hours_len, PDB_SET);
@@ -1906,13 +1889,15 @@ done:
SAFE_FREE(workstations);
SAFE_FREE(munged_dial);
SAFE_FREE(unknown_str);
+ SAFE_FREE(lm_pw_ptr);
+ SAFE_FREE(nt_pw_ptr);
+ SAFE_FREE(nt_pw_hist_ptr);
SAFE_FREE(hours);
return ret;
}
-
-uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
+uint32 init_buffer_from_sam_v2 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL size_only)
{
size_t len, buflen;
@@ -1948,8 +1933,11 @@ uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
const uint8 *lm_pw;
const uint8 *nt_pw;
+ const uint8 *nt_pw_hist;
uint32 lm_pw_len = 16;
uint32 nt_pw_len = 16;
+ uint32 nt_pw_hist_len;
+ uint32 pwHistLen = 0;
/* do we have a valid SAM_ACCOUNT pointer? */
if (sampass == NULL) {
@@ -1972,180 +1960,206 @@ uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
group_rid = pdb_get_group_rid(sampass);
username = pdb_get_username(sampass);
- if (username)
+ if (username) {
username_len = strlen(username) +1;
- else
+ } else {
username_len = 0;
+ }
domain = pdb_get_domain(sampass);
- if (domain)
+ if (domain) {
domain_len = strlen(domain) +1;
- else
+ } else {
domain_len = 0;
+ }
nt_username = pdb_get_nt_username(sampass);
- if (nt_username)
+ if (nt_username) {
nt_username_len = strlen(nt_username) +1;
- else
+ } else {
nt_username_len = 0;
+ }
fullname = pdb_get_fullname(sampass);
- if (fullname)
+ if (fullname) {
fullname_len = strlen(fullname) +1;
- else
+ } else {
fullname_len = 0;
+ }
/*
* Only updates fields which have been set (not defaults from smb.conf)
*/
- if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE))
+ if (!IS_SAM_DEFAULT(sampass, PDB_DRIVE)) {
dir_drive = pdb_get_dir_drive(sampass);
- else
+ } else {
dir_drive = NULL;
- if (dir_drive)
+ }
+ if (dir_drive) {
dir_drive_len = strlen(dir_drive) +1;
- else
+ } else {
dir_drive_len = 0;
+ }
- if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME))
+ if (!IS_SAM_DEFAULT(sampass, PDB_SMBHOME)) {
homedir = pdb_get_homedir(sampass);
- else
+ } else {
homedir = NULL;
- if (homedir)
+ }
+ if (homedir) {
homedir_len = strlen(homedir) +1;
- else
+ } else {
homedir_len = 0;
+ }
- if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT))
+ if (!IS_SAM_DEFAULT(sampass, PDB_LOGONSCRIPT)) {
logon_script = pdb_get_logon_script(sampass);
- else
+ } else {
logon_script = NULL;
- if (logon_script)
+ }
+ if (logon_script) {
logon_script_len = strlen(logon_script) +1;
- else
+ } else {
logon_script_len = 0;
+ }
- if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE))
+ if (!IS_SAM_DEFAULT(sampass, PDB_PROFILE)) {
profile_path = pdb_get_profile_path(sampass);
- else
+ } else {
profile_path = NULL;
- if (profile_path)
+ }
+ if (profile_path) {
profile_path_len = strlen(profile_path) +1;
- else
+ } else {
profile_path_len = 0;
+ }
lm_pw = pdb_get_lanman_passwd(sampass);
- if (!lm_pw)
+ if (!lm_pw) {
lm_pw_len = 0;
+ }
nt_pw = pdb_get_nt_passwd(sampass);
- if (!nt_pw)
+ if (!nt_pw) {
nt_pw_len = 0;
-
+ }
+
+ account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
+ nt_pw_hist = pdb_get_pw_history(sampass, &nt_pw_hist_len);
+ if (pwHistLen && nt_pw_hist && nt_pw_hist_len) {
+ nt_pw_hist_len *= NT_HASH_LEN;
+ } else {
+ nt_pw_hist_len = 0;
+ }
+
acct_desc = pdb_get_acct_desc(sampass);
- if (acct_desc)
+ if (acct_desc) {
acct_desc_len = strlen(acct_desc) +1;
- else
+ } else {
acct_desc_len = 0;
+ }
workstations = pdb_get_workstations(sampass);
- if (workstations)
+ if (workstations) {
workstations_len = strlen(workstations) +1;
- else
+ } else {
workstations_len = 0;
+ }
unknown_str = NULL;
unknown_str_len = 0;
munged_dial = pdb_get_munged_dial(sampass);
- if (munged_dial)
+ if (munged_dial) {
munged_dial_len = strlen(munged_dial) +1;
- else
+ } else {
munged_dial_len = 0;
-
+ }
+
+/* TDB_FORMAT_STRING_V2 "dddddddBBBBBBBBBBBBddBBBwwdBwwd" */
+
/* one time to get the size needed */
- len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V1,
- logon_time,
- logoff_time,
- kickoff_time,
- bad_password_time,
- pass_last_set_time,
- pass_can_change_time,
- pass_must_change_time,
- username_len, username,
- domain_len, domain,
- nt_username_len, nt_username,
- fullname_len, fullname,
- homedir_len, homedir,
- dir_drive_len, dir_drive,
- logon_script_len, logon_script,
- profile_path_len, profile_path,
- acct_desc_len, acct_desc,
- workstations_len, workstations,
- unknown_str_len, unknown_str,
- munged_dial_len, munged_dial,
- user_rid,
- group_rid,
- lm_pw_len, lm_pw,
- nt_pw_len, nt_pw,
- pdb_get_acct_ctrl(sampass),
- 0,
- pdb_get_logon_divs(sampass),
- pdb_get_hours_len(sampass),
- MAX_HOURS_LEN, pdb_get_hours(sampass),
- pdb_get_bad_password_count(sampass),
- pdb_get_logon_count(sampass),
- pdb_get_unknown_6(sampass));
-
-
- if (size_only)
+ len = tdb_pack(NULL, 0, TDB_FORMAT_STRING_V2,
+ logon_time, /* d */
+ logoff_time, /* d */
+ kickoff_time, /* d */
+ bad_password_time, /* d */
+ pass_last_set_time, /* d */
+ pass_can_change_time, /* d */
+ pass_must_change_time, /* d */
+ username_len, username, /* B */
+ domain_len, domain, /* B */
+ nt_username_len, nt_username, /* B */
+ fullname_len, fullname, /* B */
+ homedir_len, homedir, /* B */
+ dir_drive_len, dir_drive, /* B */
+ logon_script_len, logon_script, /* B */
+ profile_path_len, profile_path, /* B */
+ acct_desc_len, acct_desc, /* B */
+ workstations_len, workstations, /* B */
+ unknown_str_len, unknown_str, /* B */
+ munged_dial_len, munged_dial, /* B */
+ user_rid, /* d */
+ group_rid, /* d */
+ lm_pw_len, lm_pw, /* B */
+ nt_pw_len, nt_pw, /* B */
+ nt_pw_hist_len, nt_pw_hist, /* B */
+ pdb_get_acct_ctrl(sampass), /* w */
+ pdb_get_logon_divs(sampass), /* w */
+ pdb_get_hours_len(sampass), /* d */
+ MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
+ pdb_get_bad_password_count(sampass), /* w */
+ pdb_get_logon_count(sampass), /* w */
+ pdb_get_unknown_6(sampass)); /* d */
+
+ if (size_only) {
return buflen;
+ }
/* malloc the space needed */
if ( (*buf=(uint8*)malloc(len)) == NULL) {
- DEBUG(0,("init_buffer_from_sam: Unable to malloc() memory for buffer!\n"));
+ DEBUG(0,("init_buffer_from_sam_v2: Unable to malloc() memory for buffer!\n"));
return (-1);
}
/* now for the real call to tdb_pack() */
- buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V1,
- logon_time,
- logoff_time,
- kickoff_time,
- bad_password_time,
- pass_last_set_time,
- pass_can_change_time,
- pass_must_change_time,
- username_len, username,
- domain_len, domain,
- nt_username_len, nt_username,
- fullname_len, fullname,
- homedir_len, homedir,
- dir_drive_len, dir_drive,
- logon_script_len, logon_script,
- profile_path_len, profile_path,
- acct_desc_len, acct_desc,
- workstations_len, workstations,
- unknown_str_len, unknown_str,
- munged_dial_len, munged_dial,
- user_rid,
- group_rid,
- lm_pw_len, lm_pw,
- nt_pw_len, nt_pw,
- pdb_get_acct_ctrl(sampass),
- 0,
- pdb_get_logon_divs(sampass),
- pdb_get_hours_len(sampass),
- MAX_HOURS_LEN, pdb_get_hours(sampass),
- pdb_get_bad_password_count(sampass),
- pdb_get_logon_count(sampass),
- pdb_get_unknown_6(sampass));
-
+ buflen = tdb_pack((char *)*buf, len, TDB_FORMAT_STRING_V2,
+ logon_time, /* d */
+ logoff_time, /* d */
+ kickoff_time, /* d */
+ bad_password_time, /* d */
+ pass_last_set_time, /* d */
+ pass_can_change_time, /* d */
+ pass_must_change_time, /* d */
+ username_len, username, /* B */
+ domain_len, domain, /* B */
+ nt_username_len, nt_username, /* B */
+ fullname_len, fullname, /* B */
+ homedir_len, homedir, /* B */
+ dir_drive_len, dir_drive, /* B */
+ logon_script_len, logon_script, /* B */
+ profile_path_len, profile_path, /* B */
+ acct_desc_len, acct_desc, /* B */
+ workstations_len, workstations, /* B */
+ unknown_str_len, unknown_str, /* B */
+ munged_dial_len, munged_dial, /* B */
+ user_rid, /* d */
+ group_rid, /* d */
+ lm_pw_len, lm_pw, /* B */
+ nt_pw_len, nt_pw, /* B */
+ nt_pw_hist_len, nt_pw_hist, /* B */
+ pdb_get_acct_ctrl(sampass), /* w */
+ pdb_get_logon_divs(sampass), /* w */
+ pdb_get_hours_len(sampass), /* d */
+ MAX_HOURS_LEN, pdb_get_hours(sampass), /* B */
+ pdb_get_bad_password_count(sampass), /* w */
+ pdb_get_logon_count(sampass), /* w */
+ pdb_get_unknown_6(sampass)); /* d */
/* check to make sure we got it correct */
if (buflen != len) {
- DEBUG(0, ("init_buffer_from_sam: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
+ DEBUG(0, ("init_buffer_from_sam_v2: somthing odd is going on here: bufflen (%lu) != len (%lu) in tdb_pack operations!\n",
(unsigned long)buflen, (unsigned long)len));
/* error */
SAFE_FREE (*buf);
@@ -2155,7 +2169,6 @@ uint32 init_buffer_from_sam_v1 (uint8 **buf, const SAM_ACCOUNT *sampass, BOOL si
return (buflen);
}
-
/**********************************************************************
**********************************************************************/
@@ -2236,7 +2249,9 @@ BOOL pdb_update_bad_password_count(SAM_ACCOUNT *sampass, BOOL *updated)
if (time(NULL) > (LastBadPassword + (time_t)resettime*60)){
pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
- if (updated) *updated = True;
+ if (updated) {
+ *updated = True;
+ }
}
return True;
@@ -2254,7 +2269,8 @@ BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated)
if (!sampass) return False;
if (!(pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK)) {
- DEBUG(9, ("Account not autolocked, no check needed\n"));
+ DEBUG(9, ("pdb_update_autolock_flag: Account %s not autolocked, no check needed\n",
+ pdb_get_username(sampass)));
return True;
}
@@ -2265,20 +2281,30 @@ BOOL pdb_update_autolock_flag(SAM_ACCOUNT *sampass, BOOL *updated)
/* First, check if there is a duration to compare */
if ((duration == (uint32) -1) || (duration == 0)) {
- DEBUG(9, ("No reset duration, can't reset autolock\n"));
+ DEBUG(9, ("pdb_update_autolock_flag: No reset duration, can't reset autolock\n"));
return True;
}
LastBadPassword = pdb_get_bad_password_time(sampass);
- DEBUG(7, ("LastBadPassword=%d, duration=%d, current time =%d.\n",
- (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
+ DEBUG(7, ("pdb_update_autolock_flag: Account %s, LastBadPassword=%d, duration=%d, current time =%d.\n",
+ pdb_get_username(sampass), (uint32)LastBadPassword, duration*60, (uint32)time(NULL)));
+
+ if (LastBadPassword == (time_t)0) {
+ DEBUG(1,("pdb_update_autolock_flag: Account %s administratively locked out with no \
+bad password time. Leaving locked out.\n",
+ pdb_get_username(sampass) ));
+ return True;
+ }
+
if ((time(NULL) > (LastBadPassword + (time_t) duration * 60))) {
pdb_set_acct_ctrl(sampass,
pdb_get_acct_ctrl(sampass) & ~ACB_AUTOLOCK,
PDB_CHANGED);
pdb_set_bad_password_count(sampass, 0, PDB_CHANGED);
pdb_set_bad_password_time(sampass, 0, PDB_CHANGED);
- if (updated) *updated = True;
+ if (updated) {
+ *updated = True;
+ }
}
return True;
diff --git a/source/passdb/pdb_get_set.c b/source/passdb/pdb_get_set.c
index e69dac524f0..dc8a2f68d21 100644
--- a/source/passdb/pdb_get_set.c
+++ b/source/passdb/pdb_get_set.c
@@ -150,6 +150,19 @@ const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass)
return (NULL);
}
+const uint8* pdb_get_pw_history (const SAM_ACCOUNT *sampass, uint32 *current_hist_len)
+{
+ if (sampass) {
+ SMB_ASSERT((!sampass->private.nt_pw_his.data)
+ || ((sampass->private.nt_pw_his.length % NT_HASH_LEN) == 0));
+ *current_hist_len = sampass->private.nt_pw_his.length / NT_HASH_LEN;
+ return ((uint8*)sampass->private.nt_pw_his.data);
+ } else {
+ *current_hist_len = 0;
+ return (NULL);
+ }
+}
+
/* Return the plaintext password if known. Most of the time
it isn't, so don't assume anything magic about this function.
@@ -982,6 +995,30 @@ BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[LM_HASH_LEN],
}
/*********************************************************************
+ Set the user's password history hash. historyLen is the number of NT_HASH_LEN
+ entries to store in the history - this must match the size of the uint8 array
+ in pwd.
+********************************************************************/
+
+BOOL pdb_set_pw_history (SAM_ACCOUNT *sampass, const uint8 *pwd, uint32 historyLen, enum pdb_value_state flag)
+{
+ if (!sampass)
+ return False;
+
+ if (historyLen && pwd){
+ sampass->private.nt_pw_his = data_blob_talloc(sampass->mem_ctx, pwd, historyLen*NT_HASH_LEN);
+ if (!sampass->private.nt_pw_his.length) {
+ DEBUG(0, ("pdb_set_pw_history: data_blob_talloc() failed!\n"));
+ return False;
+ }
+ } else {
+ sampass->private.nt_pw_his = data_blob_talloc(sampass->mem_ctx, NULL, 0);
+ }
+
+ return pdb_set_init_flags(sampass, PDB_PWHISTORY, flag);
+}
+
+/*********************************************************************
Set the user's plaintext password only (base procedure, see helper
below)
********************************************************************/
@@ -1133,12 +1170,12 @@ BOOL pdb_set_pass_changed_now (SAM_ACCOUNT *sampass)
BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
{
- uchar new_lanman_p16[16];
- uchar new_nt_p16[16];
+ uchar new_lanman_p16[LM_HASH_LEN];
+ uchar new_nt_p16[NT_HASH_LEN];
if (!sampass || !plaintext)
return False;
-
+
/* Calculate the MD4 hash (NT compatible) of the password */
E_md4hash(plaintext, new_nt_p16);
@@ -1164,6 +1201,47 @@ BOOL pdb_set_plaintext_passwd (SAM_ACCOUNT *sampass, const char *plaintext)
if (!pdb_set_pass_changed_now (sampass))
return False;
+ /* Store the password history. */
+ if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) {
+ uchar *pwhistory;
+ uint32 pwHistLen;
+ account_policy_get(AP_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 SAM_ACCOUNT struct and now.... JRA. */
+ pwhistory = (uchar *)pdb_get_pw_history(sampass, &current_history_len);
+
+ if (current_history_len != pwHistLen) {
+ /* After closing and reopening SAM_ACCOUNT 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) {
+ /* We only have room for current_history_len entries. */
+ pwHistLen = current_history_len;
+ }
+ }
+ if (pwhistory && pwHistLen){
+ /* Make room for the new password in the history list. */
+ if (pwHistLen > 1) {
+ memmove(&pwhistory[NT_HASH_LEN], pwhistory, (pwHistLen -1)*NT_HASH_LEN );
+ }
+ /* Ensure we have a copy of the new password as the first history entry. */
+ memcpy(pwhistory, new_nt_p16, NT_HASH_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);
+ }
+ }
+
return True;
}
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index d2ee9a2d9dc..fed92cea568 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -81,8 +81,6 @@
#define SAM_ACCOUNT struct sam_passwd
#endif
-#define MODIFY_TIMESTAMP_STRING "modifyTimestamp"
-
#include "smbldap.h"
struct ldapsam_privates {
@@ -301,7 +299,9 @@ static NTSTATUS ldapsam_delete_entry(struct ldapsam_privates *ldap_state,
really exist. */
for (attrib = attrs; *attrib != NULL; attrib++) {
- if (StrCaseCmp(*attrib, name) == 0) {
+ if ((StrCaseCmp(*attrib, name) == 0) &&
+ !(StrCaseCmp(*attrib,
+ get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_MOD_TIMESTAMP)))) {
DEBUG(10, ("ldapsam_delete_entry: deleting attribute %s\n", name));
smbldap_set_mod(&mods, LDAP_MOD_DELETE, name, NULL);
}
@@ -400,8 +400,9 @@ static time_t ldapsam_get_entry_timestamp(
pstring temp;
struct tm tm;
- if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct,
- entry, MODIFY_TIMESTAMP_STRING, temp))
+ if (!smbldap_get_single_pstring(ldap_state->smbldap_state->ldap_struct, entry,
+ get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP),
+ temp))
return (time_t) 0;
strptime(temp, "%Y%m%d%H%M%SZ", &tm);
@@ -448,6 +449,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
uint8 hours[MAX_HOURS_LEN];
pstring temp;
LOGIN_CACHE *cache_entry = NULL;
+ int pwHistLen;
/*
* do a little initialization
@@ -694,6 +696,37 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
ZERO_STRUCT(smbntpwd);
}
+ account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
+ if (pwHistLen > 0){
+ uint8 *pwhist = NULL;
+ int i;
+
+ if ((pwhist = malloc(NT_HASH_LEN * pwHistLen)) == NULL){
+ DEBUG(0, ("init_sam_from_ldap: malloc failed!\n"));
+ return False;
+ }
+ memset(pwhist, '\0', NT_HASH_LEN * pwHistLen);
+
+ if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
+ get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY), temp)) {
+ /* leave as default - zeros */
+ } else {
+ for (i = 0; i < pwHistLen; i++){
+ if (!pdb_gethexpwd(&temp[i*32], smbntpwd)) {
+ break;
+ }
+ memset(&temp[i*32], '\0', 32);
+ memcpy(&pwhist[i*NT_HASH_LEN], smbntpwd, NT_HASH_LEN);
+ ZERO_STRUCT(smbntpwd);
+ }
+ }
+ if (!pdb_set_pw_history(sampass, pwhist, pwHistLen, PDB_SET)){
+ SAFE_FREE(pwhist);
+ return False;
+ }
+ SAFE_FREE(pwhist);
+ }
+
if (!smbldap_get_single_pstring (ldap_state->smbldap_state->ldap_struct, entry,
get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_ACB_INFO), temp)) {
acct_ctrl |= ACB_NORMAL;
@@ -781,7 +814,7 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
}
/**********************************************************************
- Initialize SAM_ACCOUNT from an LDAP query.
+ Initialize the ldap db from a SAM_ACCOUNT. Called on update.
(Based on init_buffer_from_sam in pdb_tdb.c)
*********************************************************************/
@@ -985,6 +1018,29 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
}
}
+ if (need_update(sampass, PDB_PWHISTORY)) {
+ int pwHistLen = 0;
+ account_policy_get(AP_PASSWORD_HISTORY, &pwHistLen);
+ if (pwHistLen == 0) {
+ /* Remove any password history from the LDAP store. */
+ pstrcpy(temp, "00000000000000000000000000000000");
+ } else {
+ int i, currHistLen = 0;
+ const uint8 *pwhist = pdb_get_pw_history(sampass, &currHistLen);
+ if (pwhist != NULL) {
+ /* We can only store (sizeof(pstring)-1)/32 password history entries. */
+ pwHistLen = MIN(pwHistLen, ((sizeof(temp)-1)/32));
+ for (i=0; i< pwHistLen && i < currHistLen; i++) {
+ pdb_sethexpwd (&temp[i*32], &pwhist[i*NT_HASH_LEN], 0);
+ DEBUG(100, ("temp=%s\n", temp));
+ }
+ }
+ }
+ smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
+ get_userattr_key2string(ldap_state->schema_ver, LDAP_ATTR_PWD_HISTORY),
+ temp);
+ }
+
if (need_update(sampass, PDB_PASSLASTSET)) {
slprintf (temp, sizeof (temp) - 1, "%li", pdb_get_pass_last_set_time(sampass));
smbldap_make_mod(ldap_state->smbldap_state->ldap_struct, existing, mods,
@@ -1162,7 +1218,7 @@ static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT
int rc;
attr_list = get_userattr_list( ldap_state->schema_ver );
- append_attr(&attr_list, MODIFY_TIMESTAMP_STRING);
+ append_attr(&attr_list, get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP));
rc = ldapsam_search_suffix_by_name(ldap_state, sname, &result, attr_list);
free_attr_list( attr_list );
@@ -1208,7 +1264,7 @@ static int ldapsam_get_ldap_user_by_sid(struct ldapsam_privates *ldap_state,
switch ( ldap_state->schema_ver ) {
case SCHEMAVER_SAMBASAMACCOUNT:
attr_list = get_userattr_list(ldap_state->schema_ver);
- append_attr(&attr_list, MODIFY_TIMESTAMP_STRING);
+ append_attr(&attr_list, get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP));
rc = ldapsam_search_suffix_by_sid(ldap_state, sid, result, attr_list);
free_attr_list( attr_list );
diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c
index 9bfb10c4009..5fb5ce38913 100644
--- a/source/passdb/pdb_tdb.c
+++ b/source/passdb/pdb_tdb.c
@@ -37,7 +37,7 @@ static int tdbsam_debug_level = DBGC_ALL;
#endif
-#define TDBSAM_VERSION 1 /* Most recent TDBSAM version */
+#define TDBSAM_VERSION 2 /* Most recent TDBSAM version */
#define TDBSAM_VERSION_STRING "INFO/version"
#define PASSDB_FILE_NAME "passdb.tdb"
#define USERPREFIX "USER_"
@@ -125,6 +125,9 @@ static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from)
case 1:
ret = init_sam_from_buffer_v1(user, (uint8 *)data.dptr, data.dsize);
break;
+ case 2:
+ ret = init_sam_from_buffer_v2(user, (uint8 *)data.dptr, data.dsize);
+ break;
default:
/* unknown tdbsam version */
ret = False;
@@ -135,6 +138,9 @@ static BOOL tdbsam_convert(TDB_CONTEXT *pdb_tdb, tdbsamver_t from)
return False;
}
+ /* We're finished with the old data. */
+ SAFE_FREE(data.dptr);
+
/* pack from the buffer into the new format */
DEBUG(10,("tdbsam_convert: Try packing a record (key:%s) (version:%d)\n", key.dptr, from));
if ((data.dsize=init_buffer_from_sam (&buf, user, False)) == -1) {
@@ -746,4 +752,3 @@ NTSTATUS pdb_tdbsam_init(void)
{
return smb_register_passdb(PASSDB_INTERFACE_VERSION, "tdbsam", pdb_init_tdbsam);
}
-
diff --git a/source/passdb/secrets.c b/source/passdb/secrets.c
index 2b3175bed23..e7637f689d2 100644
--- a/source/passdb/secrets.c
+++ b/source/passdb/secrets.c
@@ -30,10 +30,27 @@
static TDB_CONTEXT *tdb;
+/**
+ * Use a TDB to store an incrementing random seed.
+ *
+ * Initialised to the current pid, the very first time Samba starts,
+ * and incremented by one each time it is needed.
+ *
+ * @note Not called by systems with a working /dev/urandom.
+ */
+static void get_rand_seed(int *new_seed)
+{
+ *new_seed = sys_getpid();
+ if (tdb) {
+ tdb_change_int32_atomic(tdb, "INFO/random_seed", new_seed, 1);
+ }
+}
+
/* open up the secrets database */
BOOL secrets_init(void)
{
pstring fname;
+ char dummy;
if (tdb)
return True;
@@ -47,6 +64,18 @@ BOOL secrets_init(void)
DEBUG(0,("Failed to open %s\n", fname));
return False;
}
+
+ /**
+ * Set a reseed function for the crypto random generator
+ *
+ * This avoids a problem where systems without /dev/urandom
+ * could send the same challenge to multiple clients
+ */
+ set_rand_reseed_callback(get_rand_seed);
+
+ /* Ensure that the reseed is done now, while we are root, etc */
+ generate_random_buffer(&dummy, sizeof(dummy));
+
return True;
}
@@ -504,37 +533,6 @@ BOOL trusted_domain_password_delete(const char *domain)
}
-/*******************************************************************
- Reset the 'done' variables so after a client process is created
- from a fork call these calls will be re-done. This should be
- expanded if more variables need reseting.
- ******************************************************************/
-
-void reset_globals_after_fork(void)
-{
- unsigned char dummy;
-
- secrets_init();
-
- /*
- * Increment the global seed value to ensure every smbd starts
- * with a new random seed.
- */
-
- if (tdb) {
- uint32 initial_val = sys_getpid();
- tdb_change_int32_atomic(tdb, "INFO/random_seed", (int *)&initial_val, 1);
- set_rand_reseed_data((unsigned char *)&initial_val, sizeof(initial_val));
- }
-
- /*
- * Re-seed the random crypto generator, so all smbd's
- * started from the same parent won't generate the same
- * sequence.
- */
- generate_random_buffer( &dummy, 1, True);
-}
-
BOOL secrets_store_ldap_pw(const char* dn, char* pw)
{
char *key = NULL;
diff --git a/source/printing/printing.c b/source/printing/printing.c
index 8beea9d0cec..10ca7e47e71 100644
--- a/source/printing/printing.c
+++ b/source/printing/printing.c
@@ -600,7 +600,6 @@ void pjob_delete(int snum, uint32 jobid)
tdb_delete(pdb->tdb, print_key(jobid));
release_print_db(pdb);
rap_jobid_delete(snum, jobid);
- remove_from_jobs_changed( snum, jobid );
}
/****************************************************************************
@@ -1685,8 +1684,6 @@ pause, or resume print job. User name: %s. Printer name: %s.",
*errcode = map_werror_from_unix(errno);
return False;
}
-
- return True;
}
if (!print_job_delete1(snum, jobid)) {
diff --git a/source/python/py_winbind.c b/source/python/py_winbind.c
index 130f78d7e12..7256f77002b 100644
--- a/source/python/py_winbind.c
+++ b/source/python/py_winbind.c
@@ -432,7 +432,7 @@ static PyObject *py_auth_crap(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
- generate_random_buffer(request.data.auth_crap.chal, 8, False);
+ generate_random_buffer(request.data.auth_crap.chal, 8);
if (use_lm_hash) {
SMBencrypt((uchar *)password, request.data.auth_crap.chal,
@@ -481,7 +481,7 @@ static PyObject *py_auth_smbd(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
- generate_random_buffer(request.data.smbd_auth_crap.chal, 8, False);
+ generate_random_buffer(request.data.smbd_auth_crap.chal, 8);
if (use_lm_hash) {
SMBencrypt((uchar *)password,
diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c
index 02d2611d88c..3fb032234f5 100644
--- a/source/rpc_client/cli_netlogon.c
+++ b/source/rpc_client/cli_netlogon.c
@@ -247,7 +247,7 @@ NTSTATUS cli_nt_setup_creds(struct cli_state *cli,
/******************* Request Challenge ********************/
- generate_random_buffer(clnt_chal.data, 8, False);
+ generate_random_buffer(clnt_chal.data, 8);
/* send a client challenge; receive a server challenge */
result = cli_net_req_chal(cli, &clnt_chal, &srv_chal);
@@ -580,7 +580,7 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
unsigned char local_lm_response[24];
unsigned char local_nt_response[24];
- generate_random_buffer(chal, 8, False);
+ generate_random_buffer(chal, 8);
SMBencrypt(password, chal, local_lm_response);
SMBNTencrypt(password, chal, local_nt_response);
diff --git a/source/rpc_client/cli_srvsvc.c b/source/rpc_client/cli_srvsvc.c
index 555703cf4d8..68eb17074f6 100644
--- a/source/rpc_client/cli_srvsvc.c
+++ b/source/rpc_client/cli_srvsvc.c
@@ -181,6 +181,42 @@ WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx,
init_unistr2(&info2->info_2_str.uni_passwd, s, UNI_STR_TERMINATE);
}
break;
+ /* adding info-level 502 here */
+ case 502:
+ ctr->share.info502 = (SRV_SHARE_INFO_502 *)talloc(
+ mem_ctx, sizeof(SRV_SHARE_INFO_502) * ctr->num_entries);
+
+ memset(ctr->share.info502, 0, sizeof(SRV_SHARE_INFO_502));
+
+ for (i = 0; i < ctr->num_entries; i++) {
+ SRV_SHARE_INFO_502 *info502 = &ctr->share.info502[i];
+ char *s;
+
+ /* Copy pointer crap */
+ memcpy(&info502->info_502, &r.ctr.share.info502[i].info_502,
+ sizeof(SH_INFO_502));
+
+ /* Duplicate strings */
+
+ s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_netname);
+ if (s)
+ init_unistr2(&info502->info_502_str.uni_netname, s, UNI_STR_TERMINATE);
+
+ s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_remark);
+ if (s)
+ init_unistr2(&info502->info_502_str.uni_remark, s, UNI_STR_TERMINATE);
+
+ s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_path);
+ if (s)
+ init_unistr2(&info502->info_502_str.uni_path, s, UNI_STR_TERMINATE);
+
+ s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_passwd);
+ if (s)
+ init_unistr2(&info502->info_502_str.uni_passwd, s, UNI_STR_TERMINATE);
+
+ info502->info_502_str.sd = dup_sec_desc(mem_ctx, r.ctr.share.info502[i].info_502_str.sd);
+ }
+ break;
}
done:
prs_mem_free(&qbuf);
diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c
index 92c5b13632a..c70011c6484 100644
--- a/source/rpc_parse/parse_prs.c
+++ b/source/rpc_parse/parse_prs.c
@@ -1471,7 +1471,7 @@ void netsec_encode(struct netsec_auth_struct *a, int auth_flags,
}
/* fill the 'confounder' with random data */
- generate_random_buffer(confounder, sizeof(confounder), False);
+ generate_random_buffer(confounder, sizeof(confounder));
dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
diff --git a/source/rpc_server/srv_netlog_nt.c b/source/rpc_server/srv_netlog_nt.c
index 264b7a74a79..b5871a7e56d 100644
--- a/source/rpc_server/srv_netlog_nt.c
+++ b/source/rpc_server/srv_netlog_nt.c
@@ -276,7 +276,7 @@ NTSTATUS _net_req_chal(pipes_struct *p, NET_Q_REQ_CHAL *q_u, NET_R_REQ_CHAL *r_u
/* create a server challenge for the client */
/* Set these to random values. */
- generate_random_buffer(p->dc.srv_chal.data, 8, False);
+ generate_random_buffer(p->dc.srv_chal.data, 8);
memcpy(p->dc.srv_cred.challenge.data, p->dc.srv_chal.data, 8);
diff --git a/source/rpc_server/srv_pipe.c b/source/rpc_server/srv_pipe.c
index 36929150e54..bcf5eb533fd 100644
--- a/source/rpc_server/srv_pipe.c
+++ b/source/rpc_server/srv_pipe.c
@@ -52,28 +52,28 @@ struct dcinfo last_dcinfo;
static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len)
{
- unsigned char *hash = p->ntlmssp_hash;
- unsigned char index_i = hash[256];
- unsigned char index_j = hash[257];
- int ind;
+ unsigned char *hash = p->ntlmssp_hash;
+ unsigned char index_i = hash[256];
+ unsigned char index_j = hash[257];
+ int ind;
- for( ind = 0; ind < len; ind++) {
- unsigned char tc;
- unsigned char t;
+ for( ind = 0; ind < len; ind++) {
+ unsigned char tc;
+ unsigned char t;
- index_i++;
- index_j += hash[index_i];
+ index_i++;
+ index_j += hash[index_i];
- tc = hash[index_i];
- hash[index_i] = hash[index_j];
- hash[index_j] = tc;
+ tc = hash[index_i];
+ hash[index_i] = hash[index_j];
+ hash[index_j] = tc;
- t = hash[index_i] + hash[index_j];
- data[ind] = data[ind] ^ hash[t];
- }
+ t = hash[index_i] + hash[index_j];
+ data[ind] = data[ind] ^ hash[t];
+ }
- hash[256] = index_i;
- hash[257] = index_j;
+ hash[256] = index_i;
+ hash[257] = index_j;
}
/*******************************************************************
@@ -501,6 +501,9 @@ succeeded authentication on named pipe %s, but session key was of incorrect leng
* Store the UNIX credential data (uid/gid pair) in the pipe structure.
*/
+ if (p->session_key.data) {
+ data_blob_free(&p->session_key);
+ }
p->session_key = data_blob(server_info->lm_session_key.data, server_info->lm_session_key.length);
p->pipe_user.uid = server_info->uid;
@@ -1094,7 +1097,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p)
RPC_AUTH_VERIFIER auth_verifier;
RPC_AUTH_NTLMSSP_CHAL ntlmssp_chal;
- generate_random_buffer(p->challenge, 8, False);
+ generate_random_buffer(p->challenge, 8);
/*** Authentication info ***/
diff --git a/source/rpc_server/srv_pipe_hnd.c b/source/rpc_server/srv_pipe_hnd.c
index 7f7a3025a90..562b55b8f76 100644
--- a/source/rpc_server/srv_pipe_hnd.c
+++ b/source/rpc_server/srv_pipe_hnd.c
@@ -1092,6 +1092,22 @@ BOOL close_rpc_pipe_hnd(smb_np_struct *p)
}
/****************************************************************************
+ Close all pipes on a connection.
+****************************************************************************/
+
+void pipe_close_conn(connection_struct *conn)
+{
+ smb_np_struct *p, *next;
+
+ for (p=Pipes;p;p=next) {
+ next = p->next;
+ if (p->conn == conn) {
+ close_rpc_pipe_hnd(p);
+ }
+ }
+}
+
+/****************************************************************************
Close an rpc pipe.
****************************************************************************/
@@ -1114,9 +1130,6 @@ static BOOL close_internal_rpc_pipe_hnd(void *np_conn)
/* Free the handles database. */
close_policy_by_pipe(p);
- if (p->session_key.data != NULL)
- data_blob_free(&p->session_key);
-
delete_nt_token(&p->pipe_user.nt_user_token);
data_blob_free(&p->session_key);
SAFE_FREE(p->pipe_user.groups);
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index 06ba5435976..e3c9ff08d93 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -671,7 +671,11 @@ static BOOL is_monitoring_event(Printer_entry *p, uint16 notify_type,
* might use the flags though instead of the NOTIFY_OPTION_INFO
* --jerry
*/
-
+
+ if (!option) {
+ return False;
+ }
+
if (p->notify.flags)
return is_monitoring_event_flags(
p->notify.flags, notify_type, notify_field);
@@ -3725,6 +3729,12 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
info->data=NULL;
info->count=0;
+ /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
+ sending a ffpcn() request first */
+
+ if ( !option )
+ return WERR_BADFID;
+
for (i=0; i<option->count; i++) {
option_type=&(option->ctr.type[i]);
@@ -3787,6 +3797,12 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
info->data=NULL;
info->count=0;
+ /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
+ sending a ffpcn() request first */
+
+ if ( !option )
+ return WERR_BADFID;
+
get_printer_snum(p, hnd, &snum);
for (i=0; i<option->count; i++) {
diff --git a/source/rpcclient/cmd_netlogon.c b/source/rpcclient/cmd_netlogon.c
index 9e281fefce4..b55306ddc88 100644
--- a/source/rpcclient/cmd_netlogon.c
+++ b/source/rpcclient/cmd_netlogon.c
@@ -266,10 +266,10 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
username = argv[1];
password = argv[2];
- if (argc == 4)
+ if (argc >= 4)
sscanf(argv[3], "%i", &logon_type);
- if (argc == 5)
+ if (argc >= 5)
sscanf(argv[4], "%i", &neg_flags);
if (argc == 6)
@@ -283,10 +283,6 @@ static NTSTATUS cmd_netlogon_sam_logon(struct cli_state *cli,
clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
- result = cli_netlogon_sam_logon(cli, mem_ctx, &ret_creds, username, password, logon_type);
-
- clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
-
if (!NT_STATUS_IS_OK(result))
goto done;
@@ -339,7 +335,7 @@ struct cmd_set netlogon_commands[] = {
{ "samsync", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_sync, NULL, PI_NETLOGON, "Sam Synchronisation", "" },
{ "samdeltas", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_deltas, NULL, PI_NETLOGON, "Query Sam Deltas", "" },
{ "samlogon", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_logon, NULL, PI_NETLOGON, "Sam Logon", "" },
- { "samlogon", RPC_RTYPE_NTSTATUS, cmd_netlogon_change_trust_pw, NULL, PI_NETLOGON, "Change Trust Account Password", "" },
+ { "change_trust_pw", RPC_RTYPE_NTSTATUS, cmd_netlogon_change_trust_pw, NULL, PI_NETLOGON, "Change Trust Account Password", "" },
{ NULL }
};
diff --git a/source/rpcclient/cmd_srvsvc.c b/source/rpcclient/cmd_srvsvc.c
index 3e569f51cea..6e295a50fa9 100644
--- a/source/rpcclient/cmd_srvsvc.c
+++ b/source/rpcclient/cmd_srvsvc.c
@@ -246,6 +246,25 @@ static void display_share_info_2(SRV_SHARE_INFO_2 *info2)
printf("\tpassword:\t%s\n", passwd);
}
+static void display_share_info_502(SRV_SHARE_INFO_502 *info502)
+{
+ fstring netname = "", remark = "", path = "", passwd = "";
+
+ rpcstr_pull_unistr2_fstring(netname, &info502->info_502_str.uni_netname);
+ rpcstr_pull_unistr2_fstring(remark, &info502->info_502_str.uni_remark);
+ rpcstr_pull_unistr2_fstring(path, &info502->info_502_str.uni_path);
+ rpcstr_pull_unistr2_fstring(passwd, &info502->info_502_str.uni_passwd);
+
+ printf("netname: %s\n", netname);
+ printf("\tremark:\t%s\n", remark);
+ printf("\tpath:\t%s\n", path);
+ printf("\tpassword:\t%s\n", passwd);
+
+ if (info502->info_502_str.sd)
+ display_sec_desc(info502->info_502_str.sd);
+
+}
+
static WERROR cmd_srvsvc_net_share_enum(struct cli_state *cli,
TALLOC_CTX *mem_ctx,
int argc, const char **argv)
@@ -283,6 +302,10 @@ static WERROR cmd_srvsvc_net_share_enum(struct cli_state *cli,
for (i = 0; i < ctr.num_entries; i++)
display_share_info_2(&ctr.share.info2[i]);
break;
+ case 502:
+ for (i = 0; i < ctr.num_entries; i++)
+ display_share_info_502(&ctr.share.info502[i]);
+ break;
default:
printf("unsupported info level %d\n", info_level);
break;
diff --git a/source/sam/idmap.c b/source/sam/idmap.c
index bbb4980c766..d541776f391 100644
--- a/source/sam/idmap.c
+++ b/source/sam/idmap.c
@@ -96,7 +96,7 @@ NTSTATUS smb_register_idmap(int version, const char *name, struct idmap_methods
Initialise idmap cache and a remote backend (if configured).
**********************************************************************/
-BOOL idmap_init(const char *remote_backend)
+BOOL idmap_init(const char **remote_backend)
{
if (!backends)
static_init_idmap;
@@ -115,8 +115,9 @@ BOOL idmap_init(const char *remote_backend)
}
}
- if (!remote_map && remote_backend && *remote_backend != 0) {
- char *rem_backend = smb_xstrdup(remote_backend);
+ if ((remote_map == NULL) && (remote_backend != NULL) &&
+ (*remote_backend != NULL) && (**remote_backend != '\0')) {
+ char *rem_backend = smb_xstrdup(*remote_backend);
fstring params = "";
char *pparams;
diff --git a/source/script/installswat.sh b/source/script/installswat.sh
index 67586a89674..9e3ab689b4d 100755
--- a/source/script/installswat.sh
+++ b/source/script/installswat.sh
@@ -75,7 +75,7 @@ done
if [ -d $SRCDIR../docs/htmldocs/ ]; then
- for dir in htmldocs/ htmldocs/howto htmldocs/guide htmldocs/devel
+ for dir in htmldocs/ htmldocs/Samba-HOWTO-Collection htmldocs/Samba-Guide htmldocs/Samba-Developers-Guide
do
if [ ! -d $SRCDIR../docs/$dir ]; then
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
index ca13a167fb0..a1b90c8fed4 100644
--- a/source/smbd/chgpasswd.c
+++ b/source/smbd/chgpasswd.c
@@ -933,6 +933,65 @@ static NTSTATUS check_oem_password(const char *user,
}
/***********************************************************
+ This routine takes the given password and checks it against
+ the password history. Returns True if this password has been
+ found in the history list.
+************************************************************/
+
+static BOOL check_passwd_history(SAM_ACCOUNT *sampass, const char *plaintext)
+{
+ uchar new_nt_p16[NT_HASH_LEN];
+ uchar zero_nt_pw[NT_HASH_LEN];
+ const uint8 *nt_pw;
+ const uint8 *pwhistory;
+ BOOL found = False;
+ int i, pwHisLen, curr_pwHisLen;
+
+ account_policy_get(AP_PASSWORD_HISTORY, &pwHisLen);
+ if (pwHisLen == 0) {
+ return False;
+ }
+
+ pwhistory = pdb_get_pw_history(sampass, &curr_pwHisLen);
+ if (!pwhistory || curr_pwHisLen == 0) {
+ return False;
+ }
+
+ /* Only examine the minimum of the current history len and
+ the stored history len. Avoids race conditions. */
+ pwHisLen = MIN(pwHisLen,curr_pwHisLen);
+
+ nt_pw = pdb_get_nt_passwd(sampass);
+
+ E_md4hash(plaintext, new_nt_p16);
+
+ if (!memcmp(nt_pw, new_nt_p16, NT_HASH_LEN)) {
+ DEBUG(10,("check_passwd_history: proposed new password for user %s is the same as the current password !\n",
+ pdb_get_username(sampass) ));
+ return True;
+ }
+
+ dump_data(100, new_nt_p16, NT_HASH_LEN);
+ dump_data(100, pwhistory, NT_HASH_LEN*pwHisLen);
+
+ memset(zero_nt_pw, '\0', NT_HASH_LEN);
+ for (i=0; i<pwHisLen; i++) {
+ if (!memcmp(&pwhistory[i*NT_HASH_LEN], zero_nt_pw, NT_HASH_LEN)) {
+ /* Ignore zero entries. */
+ continue;
+ }
+ if (!memcmp(&pwhistory[i*NT_HASH_LEN], new_nt_p16, NT_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;
+ }
+ }
+
+ return found;
+}
+
+/***********************************************************
Code to change the oem password. Changes both the lanman
and NT hashes. Old_passwd is almost always NULL.
NOTE this function is designed to be called as root. Check the old password
@@ -941,20 +1000,21 @@ static NTSTATUS check_oem_password(const char *user,
NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passwd, BOOL as_root)
{
- struct passwd *pass;
-
BOOL ret;
uint32 min_len;
+ struct passwd *pass = NULL;
+ const char *username = pdb_get_username(hnd);
+ time_t can_change_time = pdb_get_pass_can_change_time(hnd);
- if (time(NULL) < pdb_get_pass_can_change_time(hnd)) {
+ if ((can_change_time != 0) && (time(NULL) < can_change_time)) {
DEBUG(1, ("user %s cannot change password now, must wait until %s\n",
- pdb_get_username(hnd), http_timestring(pdb_get_pass_can_change_time(hnd))));
- return NT_STATUS_PASSWORD_RESTRICTION;
+ username, http_timestring(can_change_time)));
+ return NT_STATUS_ACCOUNT_RESTRICTION;
}
if (account_policy_get(AP_MIN_PASSWORD_LEN, &min_len) && (strlen(new_passwd) < min_len)) {
DEBUG(1, ("user %s cannot change password - password too short\n",
- pdb_get_username(hnd)));
+ username));
DEBUGADD(1, (" account policy min password len = %d\n", min_len));
return NT_STATUS_PASSWORD_RESTRICTION;
/* return NT_STATUS_PWD_TOO_SHORT; */
@@ -965,14 +1025,19 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw
if (strlen(new_passwd) < lp_min_passwd_length()) {
/* too short, must be at least MINPASSWDLENGTH */
DEBUG(1, ("Password Change: user %s, New password is shorter than minimum password length = %d\n",
- pdb_get_username(hnd), lp_min_passwd_length()));
+ username, lp_min_passwd_length()));
return NT_STATUS_PASSWORD_RESTRICTION;
/* return NT_STATUS_PWD_TOO_SHORT; */
}
- pass = Get_Pwnam(pdb_get_username(hnd));
+ if (check_passwd_history(hnd,new_passwd)) {
+ return NT_STATUS_PASSWORD_RESTRICTION;
+ }
+
+ pass = Get_Pwnam(username);
if (!pass) {
- DEBUG(1, ("check_oem_password: Username does not exist in system !?!\n"));
+ DEBUG(1, ("check_oem_password: Username %s does not exist in system !?!\n", username));
+ return NT_STATUS_ACCESS_DENIED;
}
/*
@@ -988,7 +1053,7 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw
*/
if(lp_unix_password_sync() &&
- !chgpasswd(pdb_get_username(hnd), pass, old_passwd, new_passwd, as_root)) {
+ !chgpasswd(username, pass, old_passwd, new_passwd, as_root)) {
return NT_STATUS_ACCESS_DENIED;
}
diff --git a/source/smbd/filename.c b/source/smbd/filename.c
index ab75d9c06ae..cc1c0a40b66 100644
--- a/source/smbd/filename.c
+++ b/source/smbd/filename.c
@@ -326,7 +326,7 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
*/
if (mangle_is_mangled(start)) {
- mangle_check_cache( start );
+ mangle_check_cache( start, sizeof(pstring) - 1 - (start - name) );
}
DEBUG(5,("New file %s\n",start));
@@ -476,7 +476,7 @@ static BOOL scan_directory(const char *path, char *name, size_t maxlength,
* (JRA).
*/
if (mangled)
- mangled = !mangle_check_cache( name );
+ mangled = !mangle_check_cache( name, maxlength );
/* open the directory */
if (!(cur_dir = OpenDir(conn, path, True))) {
diff --git a/source/smbd/mangle.c b/source/smbd/mangle.c
index b77fe601b69..43becff69db 100644
--- a/source/smbd/mangle.c
+++ b/source/smbd/mangle.c
@@ -98,9 +98,9 @@ BOOL mangle_is_8_3_wildcards(const char *fname, BOOL check_case)
looking for a matching name if it doesn't. It should succeed most of the time
or there will be a huge performance penalty
*/
-BOOL mangle_check_cache(char *s)
+BOOL mangle_check_cache(char *s, size_t maxlen)
{
- return mangle_fns->check_cache(s);
+ return mangle_fns->check_cache(s, maxlen);
}
/*
diff --git a/source/smbd/mangle_hash.c b/source/smbd/mangle_hash.c
index d7239b82a79..13ec99a917f 100644
--- a/source/smbd/mangle_hash.c
+++ b/source/smbd/mangle_hash.c
@@ -557,7 +557,7 @@ static void cache_mangled_name( char *mangled_name, char *raw_name )
* Check for a name on the mangled name stack
*
* Input: s - Input *and* output string buffer.
- *
+ * maxlen - space in i/o string buffer.
* Output: True if the name was found in the cache, else False.
*
* Notes: If a reverse map is found, the function will overwrite the string
@@ -568,7 +568,7 @@ static void cache_mangled_name( char *mangled_name, char *raw_name )
* ************************************************************************** **
*/
-static BOOL check_cache( char *s )
+static BOOL check_cache( char *s, size_t maxlen )
{
ubi_cacheEntryPtr FoundPtr;
char *ext_start = NULL;
@@ -602,7 +602,7 @@ static BOOL check_cache( char *s )
if( !FoundPtr ) {
if(saved_ext) {
/* Replace the saved_ext as it was truncated. */
- (void)pstrcat( s, saved_ext );
+ (void)safe_strcat( s, saved_ext, maxlen );
SAFE_FREE(saved_ext);
}
return( False );
@@ -612,10 +612,10 @@ static BOOL check_cache( char *s )
found_name = (char *)(FoundPtr + 1);
found_name += (strlen( found_name ) + 1);
- (void)pstrcpy( s, found_name );
+ (void)safe_strcpy( s, found_name, maxlen );
if( saved_ext ) {
/* Replace the saved_ext as it was truncated. */
- (void)pstrcat( s, saved_ext );
+ (void)safe_strcat( s, saved_ext, maxlen );
SAFE_FREE(saved_ext);
}
diff --git a/source/smbd/mangle_hash2.c b/source/smbd/mangle_hash2.c
index dcfd7663ba3..f68873687bd 100644
--- a/source/smbd/mangle_hash2.c
+++ b/source/smbd/mangle_hash2.c
@@ -362,10 +362,8 @@ static void mangle_reset(void)
/*
try to find a 8.3 name in the cache, and if found then
replace the string with the original long name.
-
- The filename must be able to hold at least sizeof(fstring)
*/
-static BOOL check_cache(char *name)
+static BOOL check_cache(char *name, size_t maxlen)
{
u32 hash, multiplier;
unsigned int i;
@@ -403,10 +401,10 @@ static BOOL check_cache(char *name)
if (extension[0]) {
M_DEBUG(10,("check_cache: %s -> %s.%s\n", name, prefix, extension));
- slprintf(name, sizeof(fstring), "%s.%s", prefix, extension);
+ slprintf(name, maxlen, "%s.%s", prefix, extension);
} else {
M_DEBUG(10,("check_cache: %s -> %s\n", name, prefix));
- fstrcpy(name, prefix);
+ safe_strcpy(name, prefix, maxlen);
}
return True;
diff --git a/source/smbd/password.c b/source/smbd/password.c
index b2dbde151d0..3be1516cf04 100644
--- a/source/smbd/password.c
+++ b/source/smbd/password.c
@@ -253,19 +253,23 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key,
/* Register a home dir service for this user iff
(a) This is not a guest connection,
- (b) we have a home directory defined, and
- (c) there s not an existing static share by that name */
-
- if ( (!vuser->guest)
- && vuser->unix_homedir
- && *(vuser->unix_homedir)
- && (lp_servicenumber(vuser->user.unix_name) == -1) )
- {
- DEBUG(3, ("Adding/updating homes service for user '%s' using home directory: '%s'\n",
+ (b) we have a home directory defined
+ If a share exists by this name (autoloaded or not) reuse it so
+ long as the home directory is the same as the share directory. */
+
+ if ( (!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) {
+ int servicenumber = lp_servicenumber(vuser->user.unix_name);
+ if ( servicenumber == -1 ) {
+ DEBUG(3, ("Adding homes service for user '%s' using home directory: '%s'\n",
vuser->user.unix_name, vuser->unix_homedir));
-
vuser->homes_snum = add_home_service(vuser->user.unix_name,
- vuser->user.unix_name, vuser->unix_homedir);
+ vuser->user.unix_name, vuser->unix_homedir);
+ } else if (strcmp(lp_pathname(servicenumber),vuser->unix_homedir) == 0) {
+ DEBUG(3, ("Reusing homes service for user '%s' using home directory: '%s'\n",
+ vuser->user.unix_name, vuser->unix_homedir));
+
+ vuser->homes_snum = servicenumber;
+ }
} else {
vuser->homes_snum = -1;
}
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index 71efb793af0..f3ab709df48 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -1583,7 +1583,7 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
*/
if (!rc && mangle_is_mangled(mask))
- mangle_check_cache( mask );
+ mangle_check_cache( mask, sizeof(pstring)-1 );
if (!has_wild) {
pstrcat(directory,"/");
@@ -3738,7 +3738,7 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, ui
*/
if (!rc && mangle_is_mangled(mask))
- mangle_check_cache( mask );
+ mangle_check_cache( mask, sizeof(pstring)-1 );
has_wild = ms_has_wild(mask);
@@ -4216,7 +4216,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
*/
if (!rc && mangle_is_mangled(mask))
- mangle_check_cache( mask );
+ mangle_check_cache( mask, sizeof(pstring)-1 );
has_wild = ms_has_wild(mask);
diff --git a/source/smbd/server.c b/source/smbd/server.c
index c3e0da542e2..16281dd86cb 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -409,11 +409,12 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
in smbstatus for port 445 connects */
set_remote_machine_name(get_peer_addr(smbd_server_fd()), False);
- /* Reset global variables in util.c so
- that client substitutions will be
- done correctly in the process. */
- reset_globals_after_fork();
+ /* Reset the state of the random
+ * number generation system, so
+ * children do not get the same random
+ * numbers as each other */
+ set_need_random_reseed();
/* tdb needs special fork handling - remove CLEAR_IF_FIRST flags */
if (tdb_reopen_all() == -1) {
DEBUG(0,("tdb_reopen_all failed.\n"));
@@ -717,7 +718,7 @@ void build_options(BOOL screen);
/* we want to re-seed early to prevent time delays causing
client problems at a later date. (tridge) */
- generate_random_buffer(NULL, 0, False);
+ generate_random_buffer(NULL, 0);
/* make absolutely sure we run as root - to handle cases where people
are crazy enough to have it setuid */
diff --git a/source/smbd/service.c b/source/smbd/service.c
index 3b499d5cc1d..794b5332ac5 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -823,8 +823,12 @@ void close_cnum(connection_struct *conn, uint16 vuid)
{
DirCacheFlush(SNUM(conn));
- file_close_conn(conn);
- dptr_closecnum(conn);
+ if (IS_IPC(conn)) {
+ pipe_close_conn(conn);
+ } else {
+ file_close_conn(conn);
+ dptr_closecnum(conn);
+ }
change_to_root_user();
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index a7db9daf7d6..f3176940c2f 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -3358,16 +3358,15 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
* a new info level should be used for mknod. JRA.
*/
-#if !defined(HAVE_MAKEDEV_FN)
- return(ERROR_DOS(ERRDOS,ERRnoaccess));
-#else /* HAVE_MAKEDEV_FN */
uint32 file_type = IVAL(pdata,0);
+#if defined(HAVE_MAKEDEV)
uint32 dev_major = IVAL(pdata,4);
uint32 dev_minor = IVAL(pdata,12);
+#endif
uid_t myuid = geteuid();
gid_t mygid = getegid();
- SMB_DEV_T dev;
+ SMB_DEV_T dev = (SMB_DEV_T)0;
if (tran_call == TRANSACT2_SETFILEINFO)
return(ERROR_DOS(ERRDOS,ERRnoaccess));
@@ -3375,7 +3374,9 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
if (raw_unixmode == SMB_MODE_NO_CHANGE)
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
+#if defined(HAVE_MAKEDEV)
dev = makedev(dev_major, dev_minor);
+#endif
/* We can only create as the owner/group we are. */
@@ -3384,10 +3385,30 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
if ((set_grp != mygid) && (set_grp != (gid_t)SMB_GID_NO_CHANGE))
return(ERROR_DOS(ERRDOS,ERRnoaccess));
- if (file_type != UNIX_TYPE_CHARDEV && file_type != UNIX_TYPE_BLKDEV &&
- file_type != UNIX_TYPE_FIFO &&
- file_type != UNIX_TYPE_SOCKET)
- return(ERROR_DOS(ERRDOS,ERRnoaccess));
+ switch (file_type) {
+#if defined(S_IFIFO)
+ case UNIX_TYPE_FIFO:
+ unixmode |= S_IFIFO;
+ break;
+#endif
+#if defined(S_IFSOCK)
+ case UNIX_TYPE_SOCKET:
+ unixmode |= S_IFSOCK;
+ break;
+#endif
+#if defined(S_IFCHR)
+ case UNIX_TYPE_CHARDEV:
+ unixmode |= S_IFCHR;
+ break;
+#endif
+#if defined(S_IFBLK)
+ case UNIX_TYPE_BLKDEV:
+ unixmode |= S_IFBLK;
+ break;
+#endif
+ default:
+ return(ERROR_DOS(ERRDOS,ERRnoaccess));
+ }
DEBUG(10,("call_trans2setfilepathinfo: SMB_SET_FILE_UNIX_BASIC doing mknod dev %.0f mode \
0%o for file %s\n", (double)dev, unixmode, fname ));
@@ -3401,8 +3422,6 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
SSVAL(params,0,0);
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
return(-1);
-#endif /* HAVE_MAKEDEV_FN */
-
}
/*
diff --git a/source/torture/mangle_test.c b/source/torture/mangle_test.c
index f31621b23b7..5acad2d015d 100644
--- a/source/torture/mangle_test.c
+++ b/source/torture/mangle_test.c
@@ -150,6 +150,10 @@ static void gen_name(char *name)
s[4] = 0;
}
}
+
+ /* ..... and a 100% proability of a file not ending in "." */
+ if (p[strlen(p)-1] == '.')
+ p[strlen(p)-1] = '_';
}
diff --git a/source/torture/torture.c b/source/torture/torture.c
index e3960d34061..6c3860e233e 100644
--- a/source/torture/torture.c
+++ b/source/torture/torture.c
@@ -493,7 +493,7 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
printf("%d\r", i); fflush(stdout);
}
- generate_random_buffer(buf, buf_size, False);
+ generate_random_buffer(buf, buf_size);
if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
printf("write failed (%s)\n", cli_errstr(c1));
diff --git a/source/utils/ntlm_auth.c b/source/utils/ntlm_auth.c
index 39dcd9993d0..4d369630ab3 100644
--- a/source/utils/ntlm_auth.c
+++ b/source/utils/ntlm_auth.c
@@ -181,7 +181,7 @@ DATA_BLOB get_challenge(void)
chal = data_blob(NULL, 8);
- generate_random_buffer(chal.data, chal.length, False);
+ generate_random_buffer(chal.data, chal.length);
return chal;
}
@@ -1557,7 +1557,7 @@ static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mod
if (nt_response.length < 24) {
x_fprintf(x_stdout, "Error: hex decode of %s failed! (only got %d bytes, needed at least 24)\n.\n",
parameter,
- (int)opt_nt_response.length);
+ (int)nt_response.length);
nt_response = data_blob(NULL, 0);
}
} else if (strequal(request, "LANMAN-Response")) {
diff --git a/source/utils/pdbedit.c b/source/utils/pdbedit.c
index 3f7aba83668..1201cf88fcf 100644
--- a/source/utils/pdbedit.c
+++ b/source/utils/pdbedit.c
@@ -57,9 +57,12 @@
Add all currently available users to another db
********************************************************/
-static int export_database (struct pdb_context *in, struct pdb_context *out) {
+static int export_database (struct pdb_context *in, struct pdb_context
+ *out, const char *username) {
SAM_ACCOUNT *user = NULL;
+ DEBUG(3, ("called with username=\"%s\"\n", username));
+
if (NT_STATUS_IS_ERR(in->pdb_setsampwent(in, 0))) {
fprintf(stderr, "Can't sampwent!\n");
return 1;
@@ -71,10 +74,17 @@ static int export_database (struct pdb_context *in, struct pdb_context *out) {
}
while (NT_STATUS_IS_OK(in->pdb_getsampwent(in, user))) {
- out->pdb_add_sam_account(out, user);
- if (!NT_STATUS_IS_OK(pdb_reset_sam(user))){
- fprintf(stderr, "Can't reset SAM_ACCOUNT!\n");
- return 1;
+ DEBUG(4, ("Processing account %s\n",
+ user->private.username));
+ if (!username ||
+ (strcmp(username, user->private.username)
+ == 0)) {
+ out->pdb_add_sam_account(out, user);
+ if (!NT_STATUS_IS_OK(pdb_reset_sam(user))) {
+ fprintf(stderr,
+ "Can't reset SAM_ACCOUNT!\n");
+ return 1;
+ }
}
}
@@ -192,7 +202,6 @@ static int print_user_info (struct pdb_context *in, const char *username, BOOL v
{
SAM_ACCOUNT *sam_pwent=NULL;
BOOL ret;
- BOOL updated_autolock = False, updated_badpw = False;
if (!NT_STATUS_IS_OK(pdb_init_sam (&sam_pwent))) {
return -1;
@@ -206,19 +215,6 @@ static int print_user_info (struct pdb_context *in, const char *username, BOOL v
return -1;
}
- if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock))
- DEBUG(2,("pdb_update_autolock_flag failed.\n"));
-
- if (!pdb_update_bad_password_count(sam_pwent, &updated_badpw))
- DEBUG(2,("pdb_update_bad_password_count failed.\n"));
-
- if (updated_autolock || updated_badpw) {
- become_root();
- if(!pdb_update_sam_account(sam_pwent))
- DEBUG(1, ("Failed to modify entry.\n"));
- unbecome_root();
- }
-
ret=print_sam_info (sam_pwent, verbosity, smbpwdstyle);
pdb_free_sam(&sam_pwent);
@@ -300,6 +296,7 @@ static int set_user_info (struct pdb_context *in, const char *username,
const char *user_sid, const char *group_sid,
const BOOL badpw)
{
+ BOOL updated_autolock = False, updated_badpw = False;
SAM_ACCOUNT *sam_pwent=NULL;
BOOL ret;
@@ -312,6 +309,14 @@ static int set_user_info (struct pdb_context *in, const char *username,
return -1;
}
+ if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock)) {
+ DEBUG(2,("pdb_update_autolock_flag failed.\n"));
+ }
+
+ if (!pdb_update_bad_password_count(sam_pwent, &updated_badpw)) {
+ DEBUG(2,("pdb_update_bad_password_count failed.\n"));
+ }
+
if (fullname)
pdb_set_fullname(sam_pwent, fullname, PDB_CHANGED);
if (homedir)
@@ -374,7 +379,7 @@ static int set_user_info (struct pdb_context *in, const char *username,
pdb_set_bad_password_count(sam_pwent, 0, PDB_CHANGED);
pdb_set_bad_password_time(sam_pwent, 0, PDB_CHANGED);
}
-
+
if (NT_STATUS_IS_OK(in->pdb_update_sam_account (in, sam_pwent)))
print_user_info (in, username, True, False);
else {
@@ -736,7 +741,12 @@ int main (int argc, char **argv)
uint32 value;
int field = account_policy_name_to_fieldnum(account_policy);
if (field == 0) {
+ char *apn = account_policy_names_list();
fprintf(stderr, "No account policy by that name\n");
+ if (apn) {
+ fprintf(stderr, "Account policy names are :\n%s\n", apn);
+ }
+ SAFE_FREE(apn);
exit(1);
}
if (!account_policy_get(field, &value)) {
@@ -759,7 +769,7 @@ int main (int argc, char **argv)
/* import and export operations */
if (((checkparms & BIT_IMPORT) || (checkparms & BIT_EXPORT))
- && !(checkparms & ~(BIT_IMPORT +BIT_EXPORT))) {
+ && !(checkparms & ~(BIT_IMPORT +BIT_EXPORT +BIT_USER))) {
if (backend_in) {
if (!NT_STATUS_IS_OK(make_pdb_context_string(&bin, backend_in))) {
fprintf(stderr, "Can't initialize passdb backend.\n");
@@ -777,9 +787,15 @@ int main (int argc, char **argv)
bout = bdef;
}
if (transfer_groups) {
- return export_groups(bin, bout);
+ if (!(checkparms & BIT_USER))
+ return export_groups(bin, bout);
} else {
- return export_database(bin, bout);
+ if (checkparms & BIT_USER)
+ return export_database(bin, bout,
+ user_name);
+ else
+ return export_database(bin, bout,
+ NULL);
}
}
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c
index 0476a2e39c0..74480f5fc53 100644
--- a/source/utils/smbpasswd.c
+++ b/source/utils/smbpasswd.c
@@ -29,9 +29,9 @@ extern char *optarg;
extern int optind;
/* forced running in root-mode */
-static BOOL got_pass = False, got_username = False;
+static BOOL got_username = False;
static BOOL stdin_passwd_get = False;
-static fstring user_name, user_password;
+static fstring user_name;
static char *new_passwd = NULL;
static const char *remote_machine = NULL;
@@ -44,9 +44,9 @@ static fstring ldap_secret;
static void usage(void)
{
printf("When run by root:\n");
- printf(" smbpasswd [options] [username] [password]\n");
+ printf(" smbpasswd [options] [username]\n");
printf("otherwise:\n");
- printf(" smbpasswd [options] [password]\n\n");
+ printf(" smbpasswd [options]\n\n");
printf("options:\n");
printf(" -L local mode (must be first option)\n");
@@ -79,6 +79,7 @@ static void set_line_buffering(FILE *f)
/*******************************************************************
Process command line options
******************************************************************/
+
static int process_options(int argc, char **argv, int local_flags)
{
int ch;
@@ -88,7 +89,6 @@ static int process_options(int argc, char **argv, int local_flags)
local_flags |= LOCAL_SET_PASSWORD;
ZERO_STRUCT(user_name);
- ZERO_STRUCT(user_password);
user_name[0] = '\0';
@@ -150,19 +150,8 @@ static int process_options(int argc, char **argv, int local_flags)
DEBUGLEVEL = atoi(optarg);
break;
case 'U': {
- char *lp;
-
got_username = True;
fstrcpy(user_name, optarg);
-
- if ((lp = strchr(user_name, '%'))) {
- *lp = 0;
- fstrcpy(user_password, lp + 1);
- got_pass = True;
- memset(strchr_m(optarg, '%') + 1, 'X',
- strlen(user_password));
- }
-
break;
}
case 'h':
@@ -181,7 +170,7 @@ static int process_options(int argc, char **argv, int local_flags)
break;
case 1:
if (!(local_flags & LOCAL_AM_ROOT)) {
- new_passwd = argv[0];
+ usage();
} else {
if (got_username) {
usage();
@@ -190,14 +179,6 @@ static int process_options(int argc, char **argv, int local_flags)
}
}
break;
- case 2:
- if (!(local_flags & LOCAL_AM_ROOT) || got_username || got_pass) {
- usage();
- }
-
- fstrcpy(user_name, argv[0]);
- new_passwd = smb_xstrdup(argv[1]);
- break;
default:
usage();
}
diff --git a/source/wrepld/server.c b/source/wrepld/server.c
index 80694a616bb..d78e0b206f3 100644
--- a/source/wrepld/server.c
+++ b/source/wrepld/server.c
@@ -551,7 +551,7 @@ static void process(void)
/* we want to re-seed early to prevent time delays causing
client problems at a later date. (tridge) */
- generate_random_buffer(NULL, 0, False);
+ generate_random_buffer(NULL, 0);
/* make absolutely sure we run as root - to handle cases where people
are crazy enough to have it setuid */