summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvorlon <vorlon@alioth.debian.org>2008-03-09 10:22:43 +0000
committervorlon <vorlon@alioth.debian.org>2008-03-09 10:22:43 +0000
commit8f965abadc5783dc5df0a86f98b4fbfd5b001b52 (patch)
treeee76489b4823398625707e63a6bf51a68cd29e0f
parent868390f57c071cf3548bae532bf06b78688c3930 (diff)
downloadsamba-8f965abadc5783dc5df0a86f98b4fbfd5b001b52.tar.gz
Load samba-3.0.28a into branches/samba/upstream.upstream/3.0.28a
git-svn-id: svn://svn.debian.org/svn/pkg-samba/branches/samba/upstream@1755 fc4039ab-9d04-0410-8cac-899223bdd6b0
-rw-r--r--.gitignore2
-rw-r--r--WHATSNEW.txt204
-rw-r--r--examples/logon/genlogon/genlogon.pl2
-rwxr-xr-xpackaging/Example/setup.sh2
-rw-r--r--packaging/RHEL/makerpms.sh2
-rw-r--r--packaging/RHEL/samba.spec2
-rw-r--r--source/Makefile.in8
-rw-r--r--source/VERSION2
-rw-r--r--source/auth/auth_domain.c9
-rw-r--r--source/auth/auth_ntlmssp.c8
-rw-r--r--source/auth/auth_server.c1
-rw-r--r--source/auth/auth_util.c2
-rw-r--r--source/client/client.c41
-rwxr-xr-xsource/client/mount.cifs.c181
-rw-r--r--source/client/umount.cifs.c2
-rwxr-xr-xsource/configure585
-rw-r--r--source/configure.in42
-rw-r--r--source/groupdb/mapping.c2
-rw-r--r--source/include/ads.h3
-rw-r--r--source/include/config.h.in21
-rw-r--r--source/include/includes.h1
-rw-r--r--source/include/rpc_dce.h2
-rw-r--r--source/include/rpc_samr.h27
-rw-r--r--source/include/smb.h39
-rw-r--r--source/include/version.h3
-rw-r--r--source/lib/charcnv.c20
-rw-r--r--source/lib/clobber.c4
-rw-r--r--source/lib/ldap_debug_handler.c52
-rw-r--r--source/lib/replace/getpass.c15
-rw-r--r--source/lib/replace/getpass.m410
-rw-r--r--source/lib/replace/libreplace.m42
-rw-r--r--source/lib/replace/system/network.h4
-rw-r--r--source/lib/system.c9
-rw-r--r--source/lib/util_str.c24
-rw-r--r--source/libads/kerberos.c69
-rw-r--r--source/libads/sasl.c140
-rw-r--r--source/libads/util.c57
-rw-r--r--source/libmsrpc/cac_samr.c12
-rw-r--r--source/libsmb/cliconnect.c65
-rw-r--r--source/libsmb/clierror.c12
-rw-r--r--source/libsmb/clikrb5.c10
-rw-r--r--source/libsmb/clilist.c16
-rw-r--r--source/libsmb/clitrans.c14
-rw-r--r--source/libsmb/nmblib.c2
-rw-r--r--source/libsmb/smb_signing.c79
-rw-r--r--source/libsmb/smbencrypt.c2
-rw-r--r--source/libsmb/trusts_util.c2
-rw-r--r--source/libsmb/unexpected.c10
-rw-r--r--source/modules/vfs_default.c2
-rw-r--r--source/modules/vfs_hpuxacl.c4
-rw-r--r--source/modules/vfs_notify_fam.c3
-rw-r--r--source/nmbd/nmbd.c64
-rw-r--r--source/nmbd/nmbd_namelistdb.c1
-rw-r--r--source/nmbd/nmbd_nameregister.c6
-rw-r--r--source/nmbd/nmbd_packets.c5
-rw-r--r--source/nmbd/nmbd_responserecordsdb.c40
-rw-r--r--source/nsswitch/idmap.c4
-rw-r--r--source/nsswitch/pam_winbind.c4
-rw-r--r--source/nsswitch/winbind_nss_config.h2
-rw-r--r--source/nsswitch/winbindd.c2
-rw-r--r--source/nsswitch/winbindd_async.c57
-rw-r--r--source/nsswitch/winbindd_cm.c184
-rw-r--r--source/nsswitch/winbindd_cred_cache.c2
-rw-r--r--source/nsswitch/winbindd_dual.c11
-rw-r--r--source/nsswitch/winbindd_nss.h2
-rw-r--r--source/nsswitch/winbindd_pam.c10
-rw-r--r--source/nsswitch/winbindd_util.c6
-rw-r--r--source/pam_smbpass/pam_smb_acct.c5
-rw-r--r--source/pam_smbpass/pam_smb_auth.c6
-rw-r--r--source/pam_smbpass/pam_smb_passwd.c5
-rw-r--r--source/param/loadparm.c24
-rw-r--r--source/passdb/lookup_sid.c46
-rw-r--r--source/passdb/pdb_ldap.c10
-rw-r--r--source/passdb/secrets.c157
-rw-r--r--source/python/py_samr.c9
-rw-r--r--source/rpc_client/cli_pipe.c136
-rw-r--r--source/rpc_parse/parse_samr.c25
-rw-r--r--source/rpc_server/srv_lsa_nt.c37
-rw-r--r--source/rpc_server/srv_samr_nt.c4
-rw-r--r--source/rpc_server/srv_spoolss_nt.c4
-rw-r--r--source/rpc_server/srv_srvsvc_nt.c5
-rw-r--r--source/rpcclient/cmd_samr.c11
-rw-r--r--source/rpcclient/rpcclient.c2
-rw-r--r--source/smbd/chgpasswd.c24
-rw-r--r--source/smbd/dosmode.c18
-rw-r--r--source/smbd/notify.c2
-rw-r--r--source/smbd/notify_inotify.c8
-rw-r--r--source/smbd/open.c14
-rw-r--r--source/smbd/password.c30
-rw-r--r--source/smbd/posix_acls.c196
-rw-r--r--source/smbd/reply.c2
-rw-r--r--source/smbd/server.c2
-rw-r--r--source/smbd/sesssetup.c41
-rw-r--r--source/smbd/trans2.c69
-rw-r--r--source/tdb/common/io.c7
-rw-r--r--source/tdb/tools/tdbtool.c2
-rw-r--r--source/torture/torture.c42
-rw-r--r--source/utils/net.c10
-rw-r--r--source/utils/net_domain.c90
-rw-r--r--source/utils/net_rpc.c24
-rw-r--r--source/utils/net_rpc_join.c12
-rw-r--r--source/utils/net_rpc_samsync.c2
-rw-r--r--source/utils/net_sam.c20
-rw-r--r--source/utils/smbcacls.c3
-rw-r--r--source/utils/smbpasswd.c6
-rw-r--r--source/utils/status.c10
106 files changed, 2534 insertions, 818 deletions
diff --git a/.gitignore b/.gitignore
index d5e5177e22..4d39d12177 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,4 +28,4 @@ source/config.cache
source/library-versions
source/nsswitch/*.so
source/proto_exists
-source/winbindd/winbindd_proto.h
+source/nsswitch/winbindd_proto.h
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 9e023d1c04..71d3c3a09f 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,3 +1,205 @@
+ ===============================
+ Release Notes for Samba 3.0.28a
+ Mar 8, 2008
+ ===============================
+
+This is the second production release of the Samba 3.0.28 code
+base and is the version that servers should be run for for all
+current bug fixes.
+
+Major bug fixes included in Samba 3.0.28a are:
+
+ o Failure to join Windows 2008 domains
+ o Windows Vista (including SP1 RC) interop issues
+
+
+
+######################################################################
+Changes
+#######
+
+smb.conf changes
+----------------
+
+ Parameter Name Description Default
+ -------------- ----------- -------
+ administrative share New No
+ ldap debug level New 0
+ ldap debug threshold New 10
+
+
+Changes since 3.0.28
+--------------------
+
+o Michael Adam <obnox@samba.org>
+ * Fix bug in version string's vendor tag.
+ * Prevent net getdomainsid from crashing when called as non-root.
+ * BUG 4801: Correctly implement LSA lookup levels for LookupNames.
+ * Fixes for internal LookupNames() calls for unqualified users and
+ groups.
+ * Remove unnecessary functions when managing domain trust
+ passwords.
+ * Fix winbindd on a Samba DC talking to a trusted domain DC
+ (again).
+ * Consolidate the detection of the machine_account_name when
+ obtaining trust credentials from the local database.
+ * Refactor trust account database routines and session key
+ management.
+ * Fix retrieval of trusted domain password policies when
+ authenticating a user (only when WBFLAG_PAM_GET_PWD is config
+ flags is set).
+ * Refactor Winbind's cm_connect_sam().
+ * Enable building the notify_fam module.
+ * Add "ldap debug level" and "ldap debug threshold" smb.conf options.
+
+
+o Jeremy Allison <jra@samba.org>
+ * Fix cut-n-paste bug when filling in form values for Printer
+ info.
+ * Fix SMB signing bug found by Volker.
+ * Create locking.tdb when running smbstatus before smbd to avoid
+ confusing error messages.
+ * Add a portable version of strlcpy and strlcat.
+ * BUG 4780: Cause user mounts to inherit uid= and gid= from the
+ calling user when called as non-root, except when overridden on
+ the command line. Original patch by Steve Langasek.
+ * BUG 5802: Recent versions of Linux-PAM support localization of
+ user prompts, so Samba must use the C locale when invoking PAM
+ * Merge Vista principal detection changes by Andreas Schneider
+ from 3.2 branch.
+ * BUG 5121: Fix problems running unix passwd sync on streams based
+ systems.
+ * BUG 4612: Fix smbd crash when connecting from an OS/2 client.
+ * Back port Volker's ACL fixes on newly create files form 3.2.
+ * Ensure that send_getdc_request() matches the 3.2 code base.
+ * BUG 3617: Fix crash in nmbd caused by referencing freed memory.
+ * Fixes for issues reported by IBM checker.
+ * Fixes for issues reported by Coverity.
+ * Back port Volker's fix for nlink count.
+ * Back port SAMR flag fixes from Matt Geddes
+ <musicalcarrion@gmail.com>.
+ * BUG 4929: Cope with protected ACL set correctly (based on work
+ from Jim McDonough).
+ * Fix ACL set bug when group being set is the primary group.
+ * Ensure NDR wire-reads of string types are always null
+ terminated.
+ * BUG 5247: Fix mget wildcard expansion in smbclient.
+ * Fix bug in SPNEGO negotiation.
+ * BUG 3617: Fix "Invalid read of size 4" errors.
+ * BUG 5267: Prevent nmbd from shutting down when no network
+ interfaces can be located.
+
+
+o Kai Blin <kai@samba.org>
+ * libsmb: Do not upper-case target name on NTLMv2 hash generation.
+ * Fix an incompatible pointer type warning.
+
+
+o Gerald Carter <jerry@samba.org>
+ * Restrict the enctypes in the generated krb5.conf files to
+ Win2003 types.
+
+
+o Steven Danneman <steven.danneman@isilon.com>
+ * Error path memory leak fixes.
+
+
+o Guenther Deschner <gd@samba.org>
+ * Fix PAC decoding from Vista SP1 client.
+ * Fix get_trust_creds() to return always an upper-cased krb5
+ principal.
+ * Back port additional fixes necessary for support Windows 2008
+ domain joins from the 3.2 branch.
+
+
+o Mathias Gug <mathiaz@ubuntu.com>
+ * BUG 5802: Recent versions of Linux-PAM support localization of
+ user prompts, so Samba must use the C locale when invoking PAM
+
+
+o Steve Langasek <vorlon@debian.org>
+ * BUG 3727: Fix smbpasswd abort when called by non-root user.
+ * BUG 4784: Prevent umount.cifs from allowing all users to unmount shares.
+ * BUG 5802: Recent versions of Linux-PAM support localization of
+ user prompts, so Samba must use the C locale when invoking PAM
+
+
+o Volker Lendecke <vl@samba.org>
+ * When allocating a new vuid, also avoid partial ones. Also
+ fully invalidate intermediate ones.
+ * Fix error path exit in create_local_nt_token() to correctly roll
+ back security contexts.
+ * Fix valgrind warnings in nmbd.
+ * Pointer initialization fixes in notify_marshall_changes().
+ * BUG 5208: Fix uninitialized variables in vfs_hpuxacl.c (reported
+ by David Leonard <David.Leonard@quest.com>).
+ * Copy the 3.2 version of string_replace to 3.0.
+ * Port SMB_FS_OBJECTID_INFORMATION from 3.2 (Patch by Corinna
+ Vinschen).
+ * Memory leak fixes.
+ * Fix error code propagation from cli_session_setup_kerberos().
+ * BUG 5217: Fix inotify detection.
+ * BUG 5279: Correctly check return of rename().
+ * BUG 5252: Fix confusing error messages in mount.cifs.
+ * BUG 5307: Respect FAMChanged (Thanks to Ricardo Santos).
+ * Work around a handle leak in XP 64 bit.
+
+
+o Guenter Kukkukk <linux@kukkukk.com>
+ * OS/2 returns eclass == ERRDOS && ecode == ERRnofiles for a zero
+ entry directory listing.
+
+
+o Tom Maher <tmaher@watson.org>
+ * BUG 5175: Support krb5 auth in smbcacls.
+
+
+o Hans Mayer <hans.mayer@ages.at>
+ * BUG 5141: Solaris 9 compile fix.
+
+
+o Stefan Metzmacher <metze@samba.org>
+ * Fix default printing system detection in libreplace.
+
+
+o Laurent Pinchart <pinchart@skynet.be>
+ * BUG 5163: Return better error codes when a password cannot be
+ set in and LDAP directory.
+
+
+o Jiri Sasek <Jiri.Sasek@Sun.COM>
+ * BUG 4866: Correct password routine detection on Solaris.
+
+
+o Andreas Schneider <anschneider@suse.de>
+ * Remove trailing slashes on server names when parsing input from
+ smbclient.
+ * Support Windows 2008 domain joins (variant of Todd Stecher's
+ original patch).
+ * Add "administrative share" service parameter for defining hidden
+ administrative shares that cannot be managed from Windows.
+
+
+o Karolin Seeger <kseeger@samba.org>
+ * Use the "ldap user suffix" when enumerating a users group
+ memberships.
+
+
+o Simo Sorce <idra@samba.org>
+ * Don't assume NULL termination when copying the principal name
+ in kerberos_get_default_realm_from_ccache().
+ * Fix winbindd running on a Samba DC (again).
+
+
+o Bo Yang <boyang@novell.com>
+ * Fix bad private_data pointer in winbindd_lookupname_async().
+
+
+
+Release notes for older releases follow:
+
+ --------------------------------------------------
+
==============================
Release Notes for Samba 3.0.28
Dec 10, 2007
@@ -29,8 +231,6 @@ o Volker Lendecke <vl@samba.org>
when failing to add local groups in create_local_nt_token().
-Release notes for older releases follow:
-
--------------------------------------------------
===============================
diff --git a/examples/logon/genlogon/genlogon.pl b/examples/logon/genlogon/genlogon.pl
index 8ebf392141..4799ac8452 100644
--- a/examples/logon/genlogon/genlogon.pl
+++ b/examples/logon/genlogon/genlogon.pl
@@ -45,7 +45,7 @@ if ($ARGV[1] eq "SUPPORT" || $ARGV[0] eq "support")
}
# Connect shares just used by Administration staff
-If ($ARGV[1] eq "ADMIN" || $ARGV[0] eq "admin")
+if ($ARGV[1] eq "ADMIN" || $ARGV[0] eq "admin")
{
print LOGON "NET USE L: \\\\$ARGV[2]\\ADMIN\r\n";
print LOGON "NET USE K: \\\\$ARGV[2]\\MKTING\r\n";
diff --git a/packaging/Example/setup.sh b/packaging/Example/setup.sh
index 994b16d5ef..7fd8fc4110 100755
--- a/packaging/Example/setup.sh
+++ b/packaging/Example/setup.sh
@@ -24,4 +24,4 @@ echo "Done. Now settting up samba command"
ln /sbin/init.d/samba.init /sbin/samba
echo "Done."
echo "To start / stop samba:"
-echo " execute: samba [start | stop]
+echo " execute: samba [start | stop]"
diff --git a/packaging/RHEL/makerpms.sh b/packaging/RHEL/makerpms.sh
index cbf5421422..2cb05a9288 100644
--- a/packaging/RHEL/makerpms.sh
+++ b/packaging/RHEL/makerpms.sh
@@ -20,7 +20,7 @@ SRCDIR=`rpm --eval %_sourcedir`
USERID=`id -u`
GRPID=`id -g`
-VERSION='3.0.28'
+VERSION='3.0.28a'
REVISION=''
SPECFILE="samba.spec"
RPMVER=`rpm --version | awk '{print $3}'`
diff --git a/packaging/RHEL/samba.spec b/packaging/RHEL/samba.spec
index cfe55bda8f..85e3e7585e 100644
--- a/packaging/RHEL/samba.spec
+++ b/packaging/RHEL/samba.spec
@@ -5,7 +5,7 @@ Summary: Samba SMB client and server
Vendor: Samba Team
Packager: Samba Team <samba@samba.org>
Name: samba
-Version: 3.0.28
+Version: 3.0.28a
Release: 1
Epoch: 0
License: GNU GPL version 2
diff --git a/source/Makefile.in b/source/Makefile.in
index ee6d6ed559..f37a94e35a 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -270,7 +270,7 @@ READLINE_OBJ = lib/readline.o
# Be sure to include them into your application
POPT_LIB_OBJ = lib/popt_common.o
-PARAM_OBJ = dynconfig.o param/loadparm.o param/params.o lib/sharesec.o
+PARAM_OBJ = dynconfig.o param/loadparm.o param/params.o lib/sharesec.o lib/ldap_debug_handler.o
KRBCLIENT_OBJ = libads/kerberos.o libads/ads_status.o
@@ -286,9 +286,9 @@ LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o libads/sasl.o \
libads/krb5_setpw.o libads/ldap_user.o \
libads/ads_struct.o libads/kerberos_keytab.o \
libads/disp_sec.o libads/ads_utils.o libads/ldap_utils.o \
- libads/authdata.o libads/cldap.o
+ libads/authdata.o libads/cldap.o libads/util.o
-LIBADS_SERVER_OBJ = libads/util.o libads/kerberos_verify.o \
+LIBADS_SERVER_OBJ = libads/kerberos_verify.o \
libads/ldap_schema.o
SECRETS_OBJ = passdb/secrets.o passdb/machine_sid.o
@@ -1681,6 +1681,7 @@ python_install: $(PYTHON_OBJ)
python_clean:
@-if test -n "$(PYTHON)"; then $(PYTHON) python/setup.py clean; fi
+ @-rm -rf build/
# revert to the previously installed version
revert:
@@ -1869,6 +1870,7 @@ realclean: clean delheaders
distclean: realclean
-rm -f include/stamp-h
+ -rm -f smbadduser
-rm -f include/config.h Makefile
-rm -f config.status config.cache so_locations
-rm -rf .deps TAGS
diff --git a/source/VERSION b/source/VERSION
index d80ff13cbe..73ca31d623 100644
--- a/source/VERSION
+++ b/source/VERSION
@@ -36,7 +36,7 @@ SAMBA_VERSION_RELEASE=28
# e.g. SAMBA_VERSION_REVISION=a #
# -> "2.2.8a" #
########################################################
-SAMBA_VERSION_REVISION=
+SAMBA_VERSION_REVISION=a
########################################################
# For 'pre' releases the version will be #
diff --git a/source/auth/auth_domain.c b/source/auth/auth_domain.c
index a32677d037..115c57fbe0 100644
--- a/source/auth/auth_domain.c
+++ b/source/auth/auth_domain.c
@@ -125,11 +125,14 @@ machine %s. Error was : %s.\n", dc_name, nt_errstr(result)));
if (!lp_client_schannel()) {
/* We need to set up a creds chain on an unauthenticated netlogon pipe. */
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS;
uint32 sec_chan_type = 0;
unsigned char machine_pwd[16];
+ const char *account_name;
- if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) {
+ if (!get_trust_pw_hash(domain, machine_pwd, &account_name,
+ &sec_chan_type))
+ {
DEBUG(0, ("connect_to_domain_password_server: could not fetch "
"trust account password for domain '%s'\n",
domain));
@@ -143,7 +146,7 @@ machine %s. Error was : %s.\n", dc_name, nt_errstr(result)));
dc_name, /* server name */
domain, /* domain */
global_myname(), /* client name */
- global_myname(), /* machine account name */
+ account_name, /* machine account name */
machine_pwd,
sec_chan_type,
&neg_flags);
diff --git a/source/auth/auth_ntlmssp.c b/source/auth/auth_ntlmssp.c
index 51b145a760..a49b36a0a1 100644
--- a/source/auth/auth_ntlmssp.c
+++ b/source/auth/auth_ntlmssp.c
@@ -187,7 +187,13 @@ NTSTATUS auth_ntlmssp_start(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
void auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
{
- TALLOC_CTX *mem_ctx = (*auth_ntlmssp_state)->mem_ctx;
+ TALLOC_CTX *mem_ctx;
+
+ if (*auth_ntlmssp_state == NULL) {
+ return;
+ }
+
+ mem_ctx = (*auth_ntlmssp_state)->mem_ctx;
if ((*auth_ntlmssp_state)->ntlmssp_state) {
ntlmssp_end(&(*auth_ntlmssp_state)->ntlmssp_state);
diff --git a/source/auth/auth_server.c b/source/auth/auth_server.c
index d490b1a467..ba2a714539 100644
--- a/source/auth/auth_server.c
+++ b/source/auth/auth_server.c
@@ -71,6 +71,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
connection (tridge) */
if (!grab_server_mutex(desthost)) {
+ cli_shutdown(cli);
return NULL;
}
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
index 32224fa219..b3a3d39924 100644
--- a/source/auth/auth_util.c
+++ b/source/auth/auth_util.c
@@ -811,7 +811,7 @@ static NTSTATUS create_builtin_administrators( void )
return NT_STATUS_NO_MEMORY;
}
fstr_sprintf( root_name, "%s\\root", get_global_sam_name() );
- ret = lookup_name( ctx, root_name, 0, NULL, NULL, &root_sid, &type );
+ ret = lookup_name( ctx, root_name, LOOKUP_NAME_DOMAIN, NULL, NULL, &root_sid, &type );
TALLOC_FREE( ctx );
if ( ret ) {
diff --git a/source/client/client.c b/source/client/client.c
index 0cc14330cc..3f96f63f90 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -279,9 +279,11 @@ static int do_cd(char *newdir)
pstrcpy(cur_dir,p);
} else {
pstrcat(cur_dir,p);
- if ((cur_dir[0] != '\0') && (*(cur_dir+strlen(cur_dir)-1) != CLI_DIRSEP_CHAR)) {
- pstrcat(cur_dir, CLI_DIRSEP_STR);
- }
+ }
+
+ /* Ensure cur_dir ends in a DIRSEP */
+ if ((cur_dir[0] != '\0') && (*(cur_dir+strlen(cur_dir)-1) != CLI_DIRSEP_CHAR)) {
+ pstrcat(cur_dir, CLI_DIRSEP_STR);
}
clean_name(cur_dir);
@@ -699,18 +701,12 @@ static int cmd_dir(void)
int rc;
dir_total = 0;
- if (strcmp(cur_dir, CLI_DIRSEP_STR) != 0) {
- pstrcpy(mask,cur_dir);
- if ((mask[0] != '\0') && (mask[strlen(mask)-1]!=CLI_DIRSEP_CHAR))
- pstrcat(mask,CLI_DIRSEP_STR);
- } else {
- pstrcpy(mask, CLI_DIRSEP_STR);
- }
+ pstrcpy(mask,cur_dir);
if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
dos_format(p);
if (*p == CLI_DIRSEP_CHAR)
- pstrcpy(mask,p + 1);
+ pstrcpy(mask,p);
else
pstrcat(mask,p);
} else {
@@ -745,9 +741,7 @@ static int cmd_du(void)
dir_total = 0;
pstrcpy(mask,cur_dir);
- if ((mask[0] != '\0') && (mask[strlen(mask)-1]!=CLI_DIRSEP_CHAR))
- pstrcat(mask,CLI_DIRSEP_STR);
-
+
if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
dos_format(p);
if (*p == CLI_DIRSEP_CHAR)
@@ -912,7 +906,6 @@ static int cmd_get(void)
char *p;
pstrcpy(rname,cur_dir);
- pstrcat(rname,CLI_DIRSEP_STR);
p = rname + strlen(rname);
@@ -1007,7 +1000,6 @@ static int cmd_more(void)
int rc = 0;
pstrcpy(rname,cur_dir);
- pstrcat(rname,CLI_DIRSEP_STR);
slprintf(lname,sizeof(lname)-1, "%s/smbmore.XXXXXX",tmpdir());
fd = smb_mkstemp(lname);
@@ -1056,8 +1048,6 @@ static int cmd_mget(void)
while (next_token_nr(NULL,p,NULL,sizeof(buf))) {
pstrcpy(mget_mask,cur_dir);
- if ((mget_mask[0] != '\0') && (mget_mask[strlen(mget_mask)-1]!=CLI_DIRSEP_CHAR))
- pstrcat(mget_mask,CLI_DIRSEP_STR);
if (*p == CLI_DIRSEP_CHAR)
pstrcpy(mget_mask,p);
@@ -1068,8 +1058,6 @@ static int cmd_mget(void)
if (!*mget_mask) {
pstrcpy(mget_mask,cur_dir);
- if(mget_mask[strlen(mget_mask)-1]!=CLI_DIRSEP_CHAR)
- pstrcat(mget_mask,CLI_DIRSEP_STR);
pstrcat(mget_mask,"*");
do_list(mget_mask, attribute,do_mget,False,True);
}
@@ -1348,7 +1336,6 @@ static int cmd_put(void)
char *p=buf;
pstrcpy(rname,cur_dir);
- pstrcat(rname,CLI_DIRSEP_STR);
if (!next_token_nr(NULL,p,NULL,sizeof(buf))) {
d_printf("put <filename>\n");
@@ -1997,6 +1984,7 @@ static int cmd_posix(void)
CLI_DIRSEP_CHAR = '/';
*CLI_DIRSEP_STR = '/';
pstrcpy(cur_dir, CLI_DIRSEP_STR);
+ do_cd(cur_dir);
}
return 0;
@@ -2902,7 +2890,6 @@ static int cmd_reget(void)
char *p;
pstrcpy(remote_name, cur_dir);
- pstrcat(remote_name, CLI_DIRSEP_STR);
p = remote_name + strlen(remote_name);
@@ -2931,7 +2918,6 @@ static int cmd_reput(void)
SMB_STRUCT_STAT st;
pstrcpy(remote_name, cur_dir);
- pstrcat(remote_name, CLI_DIRSEP_STR);
if (!next_token_nr(NULL, p, NULL, sizeof(buf))) {
d_printf("reput <filename>\n");
@@ -3857,6 +3843,7 @@ static int do_message_op(void)
int main(int argc,char *argv[])
{
pstring base_directory;
+ int len = 0;
int opt;
pstring query_host;
BOOL message = False;
@@ -3907,7 +3894,7 @@ static int do_message_op(void)
set_global_myworkgroup( "" );
set_global_myname( "" );
- /* set default debug level to 0 regardless of what smb.conf sets */
+ /* set default debug level to 1 regardless of what smb.conf sets */
setup_logging( "smbclient", True );
DEBUGLEVEL_CLASS[DBGC_ALL] = 1;
if ((dbf = x_fdup(x_stderr))) {
@@ -4068,6 +4055,12 @@ static int do_message_op(void)
poptPrintUsage(pc, stderr, 0);
exit(1);
}
+ /* Remove trailing slashes */
+ len = strlen(service);
+ while(len > 0 && service[len - 1] == '\\') {
+ --len;
+ service[len] = '\0';
+ }
}
if ( strlen(new_workgroup) != 0 )
diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c
index 2e48a42aaf..4385412f98 100755
--- a/source/client/mount.cifs.c
+++ b/source/client/mount.cifs.c
@@ -80,6 +80,40 @@ static char * mountpassword = NULL;
char * domain_name = NULL;
char * prefixpath = NULL;
+/* glibc doesn't have strlcpy, strlcat. Ensure we do. JRA. We
+ * don't link to libreplace so need them here. */
+
+/* like strncpy but does not 0 fill the buffer and always null
+ * terminates. bufsize is the size of the destination buffer */
+size_t strlcpy(char *d, const char *s, size_t bufsize)
+{
+ size_t len = strlen(s);
+ size_t ret = len;
+ if (bufsize <= 0) return 0;
+ if (len >= bufsize) len = bufsize-1;
+ memcpy(d, s, len);
+ d[len] = 0;
+ return ret;
+}
+
+/* like strncat but does not 0 fill the buffer and always null
+ * terminates. bufsize is the length of the buffer, which should
+ * be one more than the maximum resulting string length */
+size_t strlcat(char *d, const char *s, size_t bufsize)
+{
+ size_t len1 = strlen(d);
+ size_t len2 = strlen(s);
+ size_t ret = len1 + len2;
+
+ if (len1+len2 >= bufsize) {
+ len2 = bufsize - (len1+1);
+ }
+ if (len2 > 0) {
+ memcpy(d+len1, s, len2);
+ d[len1+len2] = 0;
+ }
+ return ret;
+}
/* BB finish BB
@@ -169,8 +203,10 @@ static int open_cred_file(char * file_name)
/* go past equals sign */
temp_val++;
for(length = 0;length<4087;length++) {
- if(temp_val[length] == '\n')
+ if ((temp_val[length] == '\n')
+ || (temp_val[length] == '\0')) {
break;
+ }
}
if(length > 4086) {
printf("mount.cifs failed due to malformed username in credentials file");
@@ -193,8 +229,10 @@ static int open_cred_file(char * file_name)
/* go past equals sign */
temp_val++;
for(length = 0;length<65;length++) {
- if(temp_val[length] == '\n')
+ if ((temp_val[length] == '\n')
+ || (temp_val[length] == '\0')) {
break;
+ }
}
if(length > 64) {
printf("mount.cifs failed: password in credentials file too long\n");
@@ -222,8 +260,10 @@ static int open_cred_file(char * file_name)
if(verboseflag)
printf("\nDomain %s\n",temp_val);
for(length = 0;length<65;length++) {
- if(temp_val[length] == '\n')
- break;
+ if ((temp_val[length] == '\n')
+ || (temp_val[length] == '\0')) {
+ break;
+ }
}
if(length > 64) {
printf("mount.cifs failed: domain in credentials file too long\n");
@@ -321,6 +361,8 @@ static int parse_options(char ** optionsp, int * filesys_flags)
int out_len = 0;
int word_len;
int rc = 0;
+ char user[32];
+ char group[32];
if (!optionsp || !*optionsp)
return 1;
@@ -331,6 +373,13 @@ static int parse_options(char ** optionsp, int * filesys_flags)
/* BB fixme check for separator override BB */
+ if (getuid()) {
+ got_uid = 1;
+ snprintf(user,sizeof(user),"%u",getuid());
+ got_gid = 1;
+ snprintf(group,sizeof(group),"%u",getgid());
+ }
+
/* while ((data = strsep(&options, ",")) != NULL) { */
while(data != NULL) {
/* check if ends with trailing comma */
@@ -493,33 +542,33 @@ static int parse_options(char ** optionsp, int * filesys_flags)
got_uid = 1;
if (!isdigit(*value)) {
struct passwd *pw;
- static char temp[32];
if (!(pw = getpwnam(value))) {
printf("bad user name \"%s\"\n", value);
exit(1);
}
- sprintf(temp, "%u", pw->pw_uid);
- value = temp;
- endpwent();
+ snprintf(user, sizeof(user), "%u", pw->pw_uid);
+ } else {
+ strlcpy(user,value,sizeof(user));
}
}
+ goto nocopy;
} else if (strncmp(data, "gid", 3) == 0) {
if (value && *value) {
got_gid = 1;
if (!isdigit(*value)) {
struct group *gr;
- static char temp[32];
if (!(gr = getgrnam(value))) {
printf("bad group name \"%s\"\n", value);
exit(1);
}
- sprintf(temp, "%u", gr->gr_gid);
- value = temp;
- endpwent();
+ snprintf(group, sizeof(group), "%u", gr->gr_gid);
+ } else {
+ strlcpy(group,value,sizeof(group));
}
}
+ goto nocopy;
/* fmask and dmask synonyms for people used to smbfs syntax */
} else if (strcmp(data, "file_mode") == 0 || strcmp(data, "fmask")==0) {
if (!value || !*value) {
@@ -610,17 +659,55 @@ static int parse_options(char ** optionsp, int * filesys_flags)
exit(1);
}
- if (out_len)
- out[out_len++] = ',';
+ if (out_len) {
+ strlcat(out, ",", out_len + word_len + 2);
+ out_len++;
+ }
+
if (value)
- sprintf(out + out_len, "%s=%s", data, value);
+ snprintf(out + out_len, word_len + 1, "%s=%s", data, value);
else
- sprintf(out + out_len, "%s", data);
+ snprintf(out + out_len, word_len + 1, "%s", data);
out_len = strlen(out);
nocopy:
data = next_keyword;
}
+
+ /* special-case the uid and gid */
+ if (got_uid) {
+ word_len = strlen(user);
+
+ out = (char *)realloc(out, out_len + word_len + 6);
+ if (out == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+
+ if (out_len) {
+ strlcat(out, ",", out_len + word_len + 6);
+ out_len++;
+ }
+ snprintf(out + out_len, word_len + 5, "uid=%s", user);
+ out_len = strlen(out);
+ }
+ if (got_gid) {
+ word_len = strlen(group);
+
+ out = (char *)realloc(out, out_len + 1 + word_len + 6);
+ if (out == NULL) {
+ perror("malloc");
+ exit(1);
+ }
+
+ if (out_len) {
+ strlcat(out, ",", out_len + word_len + 6);
+ out_len++;
+ }
+ snprintf(out + out_len, word_len + 5, "gid=%s", group);
+ out_len = strlen(out);
+ }
+
free(*optionsp);
*optionsp = out;
return 0;
@@ -723,7 +810,7 @@ static char * check_for_domain(char **ppuser)
if(domainnm == NULL)
return NULL;
- strcpy(domainnm,*ppuser);
+ strlcpy(domainnm,*ppuser,len+1);
/* move_string(*ppuser, usernm+1) */
len = strlen(usernm+1);
@@ -894,6 +981,7 @@ int main(int argc, char ** argv)
int gid = 0;
int optlen = 0;
int orgoptlen = 0;
+ size_t options_size = 0;
int retry = 0; /* set when we have to retry mount with uppercase */
struct stat statbuf;
struct utsname sysinfo;
@@ -1163,38 +1251,38 @@ mount_retry:
optlen += strlen(mountpassword) + 6;
if(options)
free(options);
- options = (char *)malloc(optlen + 10 + 64 /* space for commas in password */ + 8 /* space for domain= , domain name itself was counted as part of the length username string above */);
+ options_size = optlen + 10 + 64;
+ options = (char *)malloc(options_size /* space for commas in password */ + 8 /* space for domain= , domain name itself was counted as part of the length username string above */);
if(options == NULL) {
printf("Could not allocate memory for mount options\n");
return -1;
}
-
options[0] = 0;
- strncat(options,"unc=",4);
- strcat(options,share_name);
+ strlcpy(options,"unc=",options_size);
+ strlcat(options,share_name,options_size);
/* scan backwards and reverse direction of slash */
temp = strrchr(options, '/');
if(temp > options + 6)
*temp = '\\';
if(ipaddr) {
- strncat(options,",ip=",4);
- strcat(options,ipaddr);
+ strlcat(options,",ip=",options_size);
+ strlcat(options,ipaddr,options_size);
}
if(user_name) {
/* check for syntax like user=domain\user */
if(got_domain == 0)
domain_name = check_for_domain(&user_name);
- strncat(options,",user=",6);
- strcat(options,user_name);
+ strlcat(options,",user=",options_size);
+ strlcat(options,user_name,options_size);
}
if(retry == 0) {
- if(domain_name) {
+ if(domain_name) {
/* extra length accounted for in option string above */
- strncat(options,",domain=",8);
- strcat(options,domain_name);
+ strlcat(options,",domain=",options_size);
+ strlcat(options,domain_name,options_size);
}
}
if(mountpassword) {
@@ -1203,21 +1291,21 @@ mount_retry:
/* if(sep is not set)*/
if(retry == 0)
check_for_comma(&mountpassword);
- strncat(options,",pass=",6);
- strcat(options,mountpassword);
+ strlcat(options,",pass=",options_size);
+ strlcat(options,mountpassword,options_size);
}
- strncat(options,",ver=",5);
- strcat(options,MOUNT_CIFS_VERSION_MAJOR);
+ strlcat(options,",ver=",options_size);
+ strlcat(options,MOUNT_CIFS_VERSION_MAJOR,options_size);
if(orgoptions) {
- strcat(options,",");
- strcat(options,orgoptions);
+ strlcat(options,",",options_size);
+ strlcat(options,orgoptions,options_size);
}
if(prefixpath) {
- strncat(options,",prefixpath=",12);
- strcat(options,prefixpath); /* no need to cat the / */
- }
+ strlcat(options,",prefixpath=",options_size);
+ strlcat(options,prefixpath,options_size); /* no need to cat the / */
+ }
if(verboseflag)
printf("\nmount.cifs kernel mount options %s \n",options);
if(mount(share_name, mountpoint, "cifs", flags, options)) {
@@ -1261,23 +1349,23 @@ mount_retry:
char * mount_user = getusername();
memset(mountent.mnt_opts,0,200);
if(flags & MS_RDONLY)
- strcat(mountent.mnt_opts,"ro");
+ strlcat(mountent.mnt_opts,"ro",220);
else
- strcat(mountent.mnt_opts,"rw");
+ strlcat(mountent.mnt_opts,"rw",220);
if(flags & MS_MANDLOCK)
- strcat(mountent.mnt_opts,",mand");
+ strlcat(mountent.mnt_opts,",mand",220);
if(flags & MS_NOEXEC)
- strcat(mountent.mnt_opts,",noexec");
+ strlcat(mountent.mnt_opts,",noexec",220);
if(flags & MS_NOSUID)
- strcat(mountent.mnt_opts,",nosuid");
+ strlcat(mountent.mnt_opts,",nosuid",220);
if(flags & MS_NODEV)
- strcat(mountent.mnt_opts,",nodev");
+ strlcat(mountent.mnt_opts,",nodev",220);
if(flags & MS_SYNCHRONOUS)
- strcat(mountent.mnt_opts,",synch");
+ strlcat(mountent.mnt_opts,",synch",220);
if(mount_user) {
if(getuid() != 0) {
- strcat(mountent.mnt_opts,",user=");
- strcat(mountent.mnt_opts,mount_user);
+ strlcat(mountent.mnt_opts,",user=",220);
+ strlcat(mountent.mnt_opts,mount_user,220);
}
/* free(mount_user); do not free static mem */
}
@@ -1318,4 +1406,3 @@ mount_exit:
}
return rc;
}
-
diff --git a/source/client/umount.cifs.c b/source/client/umount.cifs.c
index 47ddd1e92e..70829ebaa8 100644
--- a/source/client/umount.cifs.c
+++ b/source/client/umount.cifs.c
@@ -131,7 +131,7 @@ static int umount_check_perm(char * dir)
printf("user unmounting via %s is an optional feature of",thisprogram);
printf(" the cifs filesystem driver (cifs.ko)");
printf("\n\tand requires cifs.ko version 1.32 or later\n");
- } else if (rc > 0)
+ } else if (rc != 0)
printf("user unmount of %s failed with %d %s\n",dir,errno,strerror(errno));
close(fileid);
diff --git a/source/configure b/source/configure
index 9f158f0503..c8f462c55b 100755
--- a/source/configure
+++ b/source/configure
@@ -14277,6 +14277,145 @@ fi
done
+for ac_header in stropts.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+ ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
{ echo "$as_me:$LINENO: checking for usable net/if.h" >&5
echo $ECHO_N "checking for usable net/if.h... $ECHO_C" >&6; }
@@ -19001,6 +19140,190 @@ LIBDL="$LIBS"
LIBS="$save_LIBS"
+{ echo "$as_me:$LINENO: checking for getpass" >&5
+echo $ECHO_N "checking for getpass... $ECHO_C" >&6; }
+if test "${ac_cv_func_getpass+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define getpass to an innocuous variant, in case <limits.h> declares getpass.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define getpass innocuous_getpass
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char getpass (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef getpass
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getpass ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_getpass || defined __stub___getpass
+choke me
+#endif
+
+int
+main ()
+{
+return getpass ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ ac_cv_func_getpass=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_func_getpass=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_getpass" >&5
+echo "${ECHO_T}$ac_cv_func_getpass" >&6; }
+if test $ac_cv_func_getpass = yes; then
+ samba_cv_HAVE_GETPASS=yes
+fi
+
+{ echo "$as_me:$LINENO: checking for getpassphrase" >&5
+echo $ECHO_N "checking for getpassphrase... $ECHO_C" >&6; }
+if test "${ac_cv_func_getpassphrase+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* Define getpassphrase to an innocuous variant, in case <limits.h> declares getpassphrase.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define getpassphrase innocuous_getpassphrase
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char getpassphrase (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef getpassphrase
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char getpassphrase ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_getpassphrase || defined __stub___getpassphrase
+choke me
+#endif
+
+int
+main ()
+{
+return getpassphrase ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ ac_cv_func_getpassphrase=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_func_getpassphrase=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_getpassphrase" >&5
+echo "${ECHO_T}$ac_cv_func_getpassphrase" >&6; }
+if test $ac_cv_func_getpassphrase = yes; then
+ samba_cv_HAVE_GETPASSPHRASE=yes
+fi
+
+if test x"$samba_cv_HAVE_GETPASS" = x"yes" -a x"$samba_cv_HAVE_GETPASSPHRASE" = x"yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define REPLACE_GETPASS_BY_GETPASSPHRASE 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define REPLACE_GETPASS 1
+_ACEOF
+
+ LIBREPLACEOBJ="${LIBREPLACEOBJ} getpass.o"
+else
+
{ echo "$as_me:$LINENO: checking whether getpass should be replaced" >&5
echo $ECHO_N "checking whether getpass should be replaced... $ECHO_C" >&6; }
if test "${samba_cv_REPLACE_GETPASS+set}" = set; then
@@ -19071,6 +19394,8 @@ _ACEOF
LIBREPLACEOBJ="${LIBREPLACEOBJ} getpass.o"
fi
+fi
+
{ echo "$as_me:$LINENO: checking whether strptime is available and works" >&5
echo $ECHO_N "checking whether strptime is available and works... $ECHO_C" >&6; }
if test "${libreplace_cv_STRPTIME_OK+set}" = set; then
@@ -43756,9 +44081,13 @@ fi
done
-{ echo "$as_me:$LINENO: checking for inotify_init" >&5
-echo $ECHO_N "checking for inotify_init... $ECHO_C" >&6; }
-if test "${ac_cv_func_inotify_init+set}" = set; then
+
+for ac_func in inotify_init
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
@@ -43767,12 +44096,12 @@ _ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-/* Define inotify_init to an innocuous variant, in case <limits.h> declares inotify_init.
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define inotify_init innocuous_inotify_init
+#define $ac_func innocuous_$ac_func
/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char inotify_init (); below.
+ which can conflict with char $ac_func (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
@@ -43782,7 +44111,7 @@ cat >>conftest.$ac_ext <<_ACEOF
# include <assert.h>
#endif
-#undef inotify_init
+#undef $ac_func
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
@@ -43790,18 +44119,18 @@ cat >>conftest.$ac_ext <<_ACEOF
#ifdef __cplusplus
extern "C"
#endif
-char inotify_init ();
+char $ac_func ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
-#if defined __stub_inotify_init || defined __stub___inotify_init
+#if defined __stub_$ac_func || defined __stub___$ac_func
choke me
#endif
int
main ()
{
-return inotify_init ();
+return $ac_func ();
;
return 0;
}
@@ -43824,19 +44153,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
test ! -s conftest.err
} && test -s conftest$ac_exeext &&
$as_test_x conftest$ac_exeext; then
- ac_cv_func_inotify_init=yes
+ eval "$as_ac_var=yes"
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
- ac_cv_func_inotify_init=no
+ eval "$as_ac_var=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_inotify_init" >&5
-echo "${ECHO_T}$ac_cv_func_inotify_init" >&6; }
+ac_res=`eval echo '${'$as_ac_var'}'`
+ { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
{ echo "$as_me:$LINENO: checking for __NR_inotify_init declaration" >&5
@@ -48274,6 +48611,67 @@ _ACEOF
fi
+ #######################################################
+ # if we have LBER_OPT_LOG_PRINT_FN, we can intercept
+ # ldap logging and print it out in the samba logs
+ { echo "$as_me:$LINENO: checking for LBER_OPT_LOG_PRINT_FN" >&5
+echo $ECHO_N "checking for LBER_OPT_LOG_PRINT_FN... $ECHO_C" >&6; }
+if test "${samba_cv_HAVE_LBER_OPT_LOG_PRINT_FN+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <lber.h>
+int
+main ()
+{
+int val = LBER_OPT_LOG_PRINT_FN;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ samba_cv_HAVE_LBER_OPT_LOG_PRINT_FN=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ samba_cv_HAVE_LBER_OPT_LOG_PRINT_FN=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $samba_cv_HAVE_LBER_OPT_LOG_PRINT_FN" >&5
+echo "${ECHO_T}$samba_cv_HAVE_LBER_OPT_LOG_PRINT_FN" >&6; }
+
+ if test x"$samba_cv_HAVE_LBER_OPT_LOG_PRINT_FN" = x"yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LBER_LOG_PRINT_FN 1
+_ACEOF
+
+ fi
+
########################################################
# now see if we can find the ldap libs in standard paths
@@ -55931,6 +56329,128 @@ _ACEOF
fi
+ { echo "$as_me:$LINENO: checking for krb5_principal_get_realm" >&5
+echo $ECHO_N "checking for krb5_principal_get_realm... $ECHO_C" >&6; }
+if test "${samba_cv_HAVE_KRB5_PRINCIPAL_GET_REALM+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <krb5.h>
+int
+main ()
+{
+krb5_context ctx = NULL; krb5_principal princ = NULL; const char *str = krb5_principal_get_realm(ctx, princ);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ samba_cv_HAVE_KRB5_PRINCIPAL_GET_REALM=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ samba_cv_HAVE_KRB5_PRINCIPAL_GET_REALM=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $samba_cv_HAVE_KRB5_PRINCIPAL_GET_REALM" >&5
+echo "${ECHO_T}$samba_cv_HAVE_KRB5_PRINCIPAL_GET_REALM" >&6; }
+
+ if test x"$samba_cv_HAVE_KRB5_PRINCIPAL_GET_REALM" = x"yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_KRB5_PRINCIPAL_GET_REALM 1
+_ACEOF
+
+ fi
+
+ { echo "$as_me:$LINENO: checking for krb5_princ_realm" >&5
+echo $ECHO_N "checking for krb5_princ_realm... $ECHO_C" >&6; }
+if test "${samba_cv_HAVE_KRB5_PRINC_REALM+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <krb5.h>
+int
+main ()
+{
+krb5_context ctx = NULL; krb5_principal princ = NULL; const char *str = krb5_princ_realm(ctx, princ)->data;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ samba_cv_HAVE_KRB5_PRINC_REALM=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ samba_cv_HAVE_KRB5_PRINC_REALM=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $samba_cv_HAVE_KRB5_PRINC_REALM" >&5
+echo "${ECHO_T}$samba_cv_HAVE_KRB5_PRINC_REALM" >&6; }
+
+ if test x"$samba_cv_HAVE_KRB5_PRINC_REALM" = x"yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_KRB5_PRINC_REALM 1
+_ACEOF
+
+ fi
+
#
#
# Now the decisions whether we can support krb5
@@ -66139,6 +66659,43 @@ echo "${ECHO_T}not" >&6; }
fi
+ { echo "$as_me:$LINENO: checking how to build vfs_notify_fam" >&5
+echo $ECHO_N "checking how to build vfs_notify_fam... $ECHO_C" >&6; }
+ if test "$MODULE_vfs_notify_fam"; then
+ DEST=$MODULE_vfs_notify_fam
+ elif test "$MODULE_vfs" -a "$MODULE_DEFAULT_vfs_notify_fam"; then
+ DEST=$MODULE_vfs
+ else
+ DEST=$MODULE_DEFAULT_vfs_notify_fam
+ fi
+
+ if test x"$DEST" = xSHARED; then
+
+cat >>confdefs.h <<\_ACEOF
+#define vfs_notify_fam_init init_module
+_ACEOF
+
+ VFS_MODULES="$VFS_MODULES "bin/notify_fam.$SHLIBEXT""
+ { echo "$as_me:$LINENO: result: shared" >&5
+echo "${ECHO_T}shared" >&6; }
+
+ string_shared_modules="$string_shared_modules vfs_notify_fam"
+ elif test x"$DEST" = xSTATIC; then
+ init_static_modules_vfs="$init_static_modules_vfs vfs_notify_fam_init();"
+ decl_static_modules_vfs="$decl_static_modules_vfs extern NTSTATUS vfs_notify_fam_init(void);"
+ string_static_modules="$string_static_modules vfs_notify_fam"
+ VFS_STATIC="$VFS_STATIC \$(VFS_NOTIFY_FAM_OBJ)"
+
+
+ { echo "$as_me:$LINENO: result: static" >&5
+echo "${ECHO_T}static" >&6; }
+ else
+ string_ignored_modules="$string_ignored_modules vfs_notify_fam"
+ { echo "$as_me:$LINENO: result: not" >&5
+echo "${ECHO_T}not" >&6; }
+ fi
+
+
diff --git a/source/configure.in b/source/configure.in
index 91f1582c56..9c31de4bf3 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -2541,7 +2541,7 @@ fi
AC_CACHE_CHECK([for inotify support],samba_cv_HAVE_INOTIFY,[
AC_CHECK_HEADERS(linux/inotify.h asm/unistd.h)
-AC_CHECK_FUNC(inotify_init)
+AC_CHECK_FUNCS(inotify_init)
AC_HAVE_DECL(__NR_inotify_init, [#include <asm/unistd.h>])
],
samba_cv_HAVE_INOTIFY=yes,
@@ -3243,6 +3243,21 @@ if test x"$with_ldap_support" != x"no"; then
# this test must be before the libldap test
AC_CHECK_LIB_EXT(lber, LDAP_LIBS, ber_scanf)
+ #######################################################
+ # if we have LBER_OPT_LOG_PRINT_FN, we can intercept
+ # ldap logging and print it out in the samba logs
+ AC_CACHE_CHECK([for LBER_OPT_LOG_PRINT_FN],
+ samba_cv_HAVE_LBER_OPT_LOG_PRINT_FN,
+ [AC_TRY_COMPILE([#include <lber.h>],
+ [int val = LBER_OPT_LOG_PRINT_FN;],
+ samba_cv_HAVE_LBER_OPT_LOG_PRINT_FN=yes,
+ samba_cv_HAVE_LBER_OPT_LOG_PRINT_FN=no)])
+
+ if test x"$samba_cv_HAVE_LBER_OPT_LOG_PRINT_FN" = x"yes"; then
+ AC_DEFINE(HAVE_LBER_LOG_PRINT_FN, 1,
+ [Support for LDAP/LBER logging interception])
+ fi
+
########################################################
# now see if we can find the ldap libs in standard paths
AC_CHECK_LIB_EXT(ldap, LDAP_LIBS, ldap_init)
@@ -3944,6 +3959,30 @@ if test x"$with_ads_support" != x"no"; then
fi
+ AC_CACHE_CHECK([for krb5_principal_get_realm],
+ samba_cv_HAVE_KRB5_PRINCIPAL_GET_REALM,[
+ AC_TRY_LINK([#include <krb5.h>],
+ [krb5_context ctx = NULL; krb5_principal princ = NULL; const char *str = krb5_principal_get_realm(ctx, princ);],
+ samba_cv_HAVE_KRB5_PRINCIPAL_GET_REALM=yes,
+ samba_cv_HAVE_KRB5_PRINCIPAL_GET_REALM=no)])
+
+ if test x"$samba_cv_HAVE_KRB5_PRINCIPAL_GET_REALM" = x"yes"; then
+ AC_DEFINE(HAVE_KRB5_PRINCIPAL_GET_REALM,1,
+ [Whether the function krb5_principal_get_realm is defined])
+ fi
+
+ AC_CACHE_CHECK([for krb5_princ_realm],
+ samba_cv_HAVE_KRB5_PRINC_REALM,[
+ AC_TRY_LINK([#include <krb5.h>],
+ [krb5_context ctx = NULL; krb5_principal princ = NULL; const char *str = krb5_princ_realm(ctx, princ)->data;],
+ samba_cv_HAVE_KRB5_PRINC_REALM=yes,
+ samba_cv_HAVE_KRB5_PRINC_REALM=no)])
+
+ if test x"$samba_cv_HAVE_KRB5_PRINC_REALM" = x"yes"; then
+ AC_DEFINE(HAVE_KRB5_PRINC_REALM,1,
+ [Whether the macro krb5_princ_realm is defined])
+ fi
+
#
#
# Now the decisions whether we can support krb5
@@ -6099,6 +6138,7 @@ SMB_MODULE(vfs_prealloc, \$(VFS_PREALLOC_OBJ), "bin/prealloc.$SHLIBEXT", VFS)
SMB_MODULE(vfs_commit, \$(VFS_COMMIT_OBJ), "bin/commit.$SHLIBEXT", VFS)
SMB_MODULE(vfs_gpfs, \$(VFS_GPFS_OBJ), "bin/gpfs.$SHLIBEXT", VFS)
SMB_MODULE(vfs_readahead, \$(VFS_READAHEAD_OBJ), "bin/readahead.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_notify_fam, \$(VFS_NOTIFY_FAM_OBJ), "bin/notify_fam.$SHLIBEXT", VFS)
SMB_SUBSYSTEM(VFS,smbd/vfs.o)
diff --git a/source/groupdb/mapping.c b/source/groupdb/mapping.c
index b0e59c0ddd..cf015a5eab 100644
--- a/source/groupdb/mapping.c
+++ b/source/groupdb/mapping.c
@@ -452,7 +452,7 @@ NTSTATUS pdb_default_create_alias(struct pdb_methods *methods,
return NT_STATUS_NO_MEMORY;
}
- exists = lookup_name(mem_ctx, name, LOOKUP_NAME_ISOLATED,
+ exists = lookup_name(mem_ctx, name, LOOKUP_NAME_LOCAL,
NULL, NULL, &sid, &type);
TALLOC_FREE(mem_ctx);
diff --git a/source/include/ads.h b/source/include/ads.h
index fcaeb2069d..24884f5e18 100644
--- a/source/include/ads.h
+++ b/source/include/ads.h
@@ -321,4 +321,7 @@ typedef struct {
int val;
int critical;
} ads_control;
+
+#define ADS_IGNORE_PRINCIPAL "not_defined_in_RFC4178@please_ignore"
+
#endif /* _INCLUDE_ADS_H_ */
diff --git a/source/include/config.h.in b/source/include/config.h.in
index f8f3516e8a..892d80d125 100644
--- a/source/include/config.h.in
+++ b/source/include/config.h.in
@@ -685,6 +685,9 @@
/* Whether kernel has inotify support */
#undef HAVE_INOTIFY
+/* Define to 1 if you have the `inotify_init' function. */
+#undef HAVE_INOTIFY_INIT
+
/* Whether int16 typedef is included by rpc/rpc.h */
#undef HAVE_INT16_FROM_RPC_RPC_H
@@ -842,9 +845,15 @@
/* Define to 1 if you have the `krb5_principal_get_comp_string' function. */
#undef HAVE_KRB5_PRINCIPAL_GET_COMP_STRING
+/* Whether the function krb5_principal_get_realm is defined */
+#undef HAVE_KRB5_PRINCIPAL_GET_REALM
+
/* Whether krb5_princ_component is available */
#undef HAVE_KRB5_PRINC_COMPONENT
+/* Whether the macro krb5_princ_realm is defined */
+#undef HAVE_KRB5_PRINC_REALM
+
/* Define to 1 if you have the `krb5_princ_size' function. */
#undef HAVE_KRB5_PRINC_SIZE
@@ -890,6 +899,9 @@
/* Define to 1 if you have the <lber.h> header file. */
#undef HAVE_LBER_H
+/* Support for LDAP/LBER logging interception */
+#undef HAVE_LBER_LOG_PRINT_FN
+
/* Whether ldap is available */
#undef HAVE_LDAP
@@ -1571,6 +1583,9 @@
/* Define to 1 if you have the `strnlen' function. */
#undef HAVE_STRNLEN
+/* Define to 1 if you have the <stropts.h> header file. */
+#undef HAVE_STROPTS_H
+
/* Define to 1 if you have the `strpbrk' function. */
#undef HAVE_STRPBRK
@@ -2279,6 +2294,9 @@
/* Whether getpass should be replaced */
#undef REPLACE_GETPASS
+/* getpass returns <9 chars where getpassphrase returns <265 chars */
+#undef REPLACE_GETPASS_BY_GETPASSPHRASE
+
/* Whether inet_ntoa should be replaced */
#undef REPLACE_INET_NTOA
@@ -2825,6 +2843,9 @@
/* Whether to build vfs_netatalk as shared module */
#undef vfs_netatalk_init
+/* Whether to build vfs_notify_fam as shared module */
+#undef vfs_notify_fam_init
+
/* Whether to build vfs_posixacl as shared module */
#undef vfs_posixacl_init
diff --git a/source/include/includes.h b/source/include/includes.h
index 3ddfc7d96d..045b989158 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -107,7 +107,6 @@
#include "system/locale.h"
#include "system/network.h"
#include "system/passwd.h"
-#include "system/printing.h"
#include "system/readline.h"
#include "system/select.h"
#include "system/shmem.h"
diff --git a/source/include/rpc_dce.h b/source/include/rpc_dce.h
index 09e5f25da8..8a7934c04a 100644
--- a/source/include/rpc_dce.h
+++ b/source/include/rpc_dce.h
@@ -112,6 +112,8 @@ enum RPC_PKT_TYPE {
/* these are the flags that ADS clients use */
#define NETLOGON_NEG_AUTH2_ADS_FLAGS (0x200fbffb | NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_128BIT | NETLOGON_NEG_SCHANNEL)
+#define NETLOGON_NEG_SELECT_AUTH2_FLAGS ((lp_security() == SEC_ADS) ? NETLOGON_NEG_AUTH2_ADS_FLAGS : NETLOGON_NEG_AUTH2_FLAGS)
+
enum schannel_direction {
SENDER_IS_INITIATOR,
SENDER_IS_ACCEPTOR
diff --git a/source/include/rpc_samr.h b/source/include/rpc_samr.h
index 575cd78ef2..a7a9660c7f 100644
--- a/source/include/rpc_samr.h
+++ b/source/include/rpc_samr.h
@@ -146,6 +146,31 @@ SamrTestPrivateFunctionsUser
#define SAMR_CHGPASSWD_USER3 0x3F
#define SAMR_CONNECT5 0x40
+/* SAMR account creation flags/permissions */
+#define SAMR_USER_GETNAME 0x1
+#define SAMR_USER_GETLOCALE 0x2
+#define SAMR_USER_GETLOCCOM 0x4
+#define SAMR_USER_GETLOGONINFO 0x8
+#define SAMR_USER_GETATTR 0x10
+#define SAMR_USER_SETATTR 0x20
+#define SAMR_USER_CHPASS 0x40
+#define SAMR_USER_SETPASS 0x80
+#define SAMR_USER_GETGROUPS 0x100
+#define SAMR_USER_GETMEMBERSHIP 0x200
+#define SAMR_USER_CHMEMBERSHIP 0x400
+#define SAMR_STANDARD_DELETE 0x10000
+#define SAMR_STANDARD_READCTRL 0x20000
+#define SAMR_STANDARD_WRITEDAC 0x40000
+#define SAMR_STANDARD_WRITEOWNER 0x80000
+#define SAMR_STANDARD_SYNC 0x100000
+#define SAMR_GENERIC_ACCESSSACL 0x800000
+#define SAMR_GENERIC_MAXALLOWED 0x2000000
+#define SAMR_GENERIC_ALL 0x10000000
+#define SAMR_GENERIC_EXECUTE 0x20000000
+#define SAMR_GENERIC_WRITE 0x40000000
+#define SAMR_GENERIC_READ 0x80000000
+
+
typedef struct logon_hours_info
{
uint32 max_len; /* normally 1260 bytes */
@@ -1557,7 +1582,7 @@ typedef struct q_samr_create_user_info
UNISTR2 uni_name; /* unicode account name */
uint32 acb_info; /* account control info */
- uint32 access_mask; /* 0xe005 00b0 */
+ uint32 acct_flags; /* 0xe005 00b0 */
} SAMR_Q_CREATE_USER;
diff --git a/source/include/smb.h b/source/include/smb.h
index 3f2f2235f6..46afcde7c6 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -28,7 +28,7 @@
#define _SMB_H
/* logged when starting the various Samba daemons */
-#define COPYRIGHT_STARTUP_MESSAGE "Copyright Andrew Tridgell and the Samba Team 1992-2007"
+#define COPYRIGHT_STARTUP_MESSAGE "Copyright Andrew Tridgell and the Samba Team 1992-2008"
#if defined(LARGE_SMB_OFF_T)
@@ -257,12 +257,28 @@ enum lsa_SidType {
SID_NAME_COMPUTER /* sid for a computer */
};
-#define LOOKUP_NAME_ISOLATED 1 /* Look up unqualified names */
-#define LOOKUP_NAME_REMOTE 2 /* Ask others */
-#define LOOKUP_NAME_ALL (LOOKUP_NAME_ISOLATED|LOOKUP_NAME_REMOTE)
-#define LOOKUP_NAME_GROUP 4 /* (unused) This is a NASTY hack for valid users = @foo
- * where foo also exists in as user. */
+#define LOOKUP_NAME_NONE 0x00000000
+#define LOOKUP_NAME_ISOLATED 0x00000001 /* Look up unqualified names */
+#define LOOKUP_NAME_REMOTE 0x00000002 /* Ask others */
+#define LOOKUP_NAME_GROUP 0x00000004 /* (unused) This is a NASTY hack for
+ valid users = @foo where foo also
+ exists in as user. */
+#define LOOKUP_NAME_EXPLICIT 0x00000008 /* Only include
+ explicitly mapped names and not
+ the Unix {User,Group} domain */
+#define LOOKUP_NAME_BUILTIN 0x00000010 /* builtin names */
+#define LOOKUP_NAME_WKN 0x00000020 /* well known names */
+#define LOOKUP_NAME_DOMAIN 0x00000040 /* only lookup own domain */
+#define LOOKUP_NAME_LOCAL (LOOKUP_NAME_ISOLATED\
+ |LOOKUP_NAME_BUILTIN\
+ |LOOKUP_NAME_WKN\
+ |LOOKUP_NAME_DOMAIN)
+#define LOOKUP_NAME_ALL (LOOKUP_NAME_ISOLATED\
+ |LOOKUP_NAME_REMOTE\
+ |LOOKUP_NAME_BUILTIN\
+ |LOOKUP_NAME_WKN\
+ |LOOKUP_NAME_DOMAIN)
/**
* @brief Security Identifier
@@ -1918,4 +1934,15 @@ enum usershare_err {
/* Different reasons for closing a file. */
enum file_close_type {NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE};
+/* Used in SMB_FS_OBJECTID_INFORMATION requests. Must be exactly 48 bytes. */
+#define SAMBA_EXTENDED_INFO_MAGIC 0x536d4261 /* "SmBa" */
+#define SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH 28
+struct smb_extended_info {
+ uint32 samba_magic; /* Always SAMBA_EXTRA_INFO_MAGIC */
+ uint32 samba_version; /* Major/Minor/Release/Revision */
+ uint32 samba_subversion; /* Prerelease/RC/Vendor patch */
+ NTTIME samba_gitcommitdate;
+ char samba_version_string[SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH];
+};
+
#endif /* _SMB_H */
diff --git a/source/include/version.h b/source/include/version.h
index 9d5070159c..9f5bd0c7bb 100644
--- a/source/include/version.h
+++ b/source/include/version.h
@@ -2,5 +2,6 @@
#define SAMBA_VERSION_MAJOR 3
#define SAMBA_VERSION_MINOR 0
#define SAMBA_VERSION_RELEASE 28
-#define SAMBA_VERSION_OFFICIAL_STRING "3.0.28"
+#define SAMBA_VERSION_REVISION "a"
+#define SAMBA_VERSION_OFFICIAL_STRING "3.0.28a"
#define SAMBA_VERSION_STRING samba_version_string()
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index 7b52830cde..7d42e50c52 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -525,7 +525,7 @@ size_t convert_string(charset_t from, charset_t to,
size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
void const *src, size_t srclen, void *dst, BOOL allow_bad_conv)
{
- size_t i_len, o_len, destlen = MAX(srclen, 512);
+ size_t i_len, o_len, destlen = (srclen * 3) / 2;
size_t retval;
const char *inbuf = (const char *)src;
char *outbuf = NULL, *ob = NULL;
@@ -551,7 +551,8 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
convert:
- if ((destlen*2) < destlen) {
+ /* +2 is for ucs2 null termination. */
+ if ((destlen*2)+2 < destlen) {
/* wrapped ! abort. */
if (!conv_silent)
DEBUG(0, ("convert_string_allocate: destlen wrapped !\n"));
@@ -562,10 +563,11 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
destlen = destlen * 2;
}
+ /* +2 is for ucs2 null termination. */
if (ctx) {
- ob = (char *)TALLOC_REALLOC(ctx, ob, destlen);
+ ob = (char *)TALLOC_REALLOC(ctx, ob, destlen + 2);
} else {
- ob = (char *)SMB_REALLOC(ob, destlen);
+ ob = (char *)SMB_REALLOC(ob, destlen + 2);
}
if (!ob) {
@@ -611,9 +613,10 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
destlen = destlen - o_len;
if (ctx) {
- ob = (char *)TALLOC_REALLOC(ctx,ob,destlen);
+ /* We're shrinking here so we know the +2 is safe from wrap. */
+ ob = (char *)TALLOC_REALLOC(ctx,ob,destlen + 2);
} else {
- ob = (char *)SMB_REALLOC(ob,destlen);
+ ob = (char *)SMB_REALLOC(ob,destlen + 2);
}
if (destlen && !ob) {
@@ -622,6 +625,11 @@ size_t convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
}
*dest = ob;
+
+ /* Must ucs2 null terminate in the extra space we allocated. */
+ ob[destlen] = '\0';
+ ob[destlen+1] = '\0';
+
return destlen;
use_as_is:
diff --git a/source/lib/clobber.c b/source/lib/clobber.c
index fb3a0dc281..d3a9c59c36 100644
--- a/source/lib/clobber.c
+++ b/source/lib/clobber.c
@@ -54,7 +54,11 @@ void clobber_region(const char *fn, unsigned int line, char *dest, size_t len)
* (This is not redundant with the clobbering above. The
* marking might not actually take effect if we're not running
* under valgrind.) */
+#if defined(VALGRIND_MAKE_MEM_UNDEFINED)
+ VALGRIND_MAKE_MEM_UNDEFINED(dest, len);
+#elif defined(VALGRIND_MAKE_WRITABLE)
VALGRIND_MAKE_WRITABLE(dest, len);
+#endif
#endif /* VALGRIND */
#endif /* DEVELOPER */
}
diff --git a/source/lib/ldap_debug_handler.c b/source/lib/ldap_debug_handler.c
new file mode 100644
index 0000000000..f289f743fb
--- /dev/null
+++ b/source/lib/ldap_debug_handler.c
@@ -0,0 +1,52 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Intercept libldap debug output.
+ * Copyright (C) Michael Adam 2008
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+
+#if HAVE_LDAP
+
+static void samba_ldap_log_print_fn(LDAP_CONST char *data)
+{
+ DEBUG(lp_ldap_debug_threshold(), ("[LDAP] %s", data));
+}
+
+#endif
+
+void init_ldap_debugging(void)
+{
+#if defined(HAVE_LDAP) && defined(HAVE_LBER_LOG_PRINT_FN)
+ int ret;
+ int ldap_debug_level = lp_ldap_debug_level();
+
+ ret = ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &ldap_debug_level);
+ if (ret != LDAP_OPT_SUCCESS) {
+ DEBUG(10, ("Error setting LDAP debug level.\n"));
+ }
+
+ if (ldap_debug_level == 0) {
+ return;
+ }
+
+ ret = ber_set_option(NULL, LBER_OPT_LOG_PRINT_FN,
+ (void *)samba_ldap_log_print_fn);
+ if (ret != LBER_OPT_SUCCESS) {
+ DEBUG(10, ("Error setting LBER log print function.\n"));
+ }
+#endif /* HAVE_LDAP && HAVE_LBER_LOG_PRINT_FN */
+}
diff --git a/source/lib/replace/getpass.c b/source/lib/replace/getpass.c
index 2ccbf7b733..90f9af9ec6 100644
--- a/source/lib/replace/getpass.c
+++ b/source/lib/replace/getpass.c
@@ -20,6 +20,19 @@ Cambridge, MA 02139, USA. */
#include "replace.h"
+#if defined(REPLACE_GETPASS_BY_GETPASSPHRASE)
+
+#if defined(HAVE_STDIO_H)
+#include <stdio.h>
+#endif
+
+char *getsmbpass(const char *prompt)
+{
+ return getpassphrase(prompt);
+}
+
+#else /* !REPLACE_GETPASS_BY_GETPASSPHRASE */
+
#if defined(HAVE_TERMIOS_H)
/* POSIX terminal handling. */
#include <termios.h>
@@ -210,3 +223,5 @@ char *getsmbpass(const char *prompt)
void getsmbpasswd_dummy(void);
void getsmbpasswd_dummy(void) {;}
#endif
+
+#endif /* REPLACE_GETPASS_BY_GETPASSPHRASE */
diff --git a/source/lib/replace/getpass.m4 b/source/lib/replace/getpass.m4
index 20d04a63f6..9e3a5e11c4 100644
--- a/source/lib/replace/getpass.m4
+++ b/source/lib/replace/getpass.m4
@@ -1,3 +1,11 @@
+AC_CHECK_FUNC(getpass, samba_cv_HAVE_GETPASS=yes)
+AC_CHECK_FUNC(getpassphrase, samba_cv_HAVE_GETPASSPHRASE=yes)
+if test x"$samba_cv_HAVE_GETPASS" = x"yes" -a x"$samba_cv_HAVE_GETPASSPHRASE" = x"yes"; then
+ AC_DEFINE(REPLACE_GETPASS_BY_GETPASSPHRASE, 1, [getpass returns <9 chars where getpassphrase returns <265 chars])
+ AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced])
+ LIBREPLACEOBJ="${LIBREPLACEOBJ} getpass.o"
+else
+
AC_CACHE_CHECK([whether getpass should be replaced],samba_cv_REPLACE_GETPASS,[
SAVE_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -I$libreplacedir/"
@@ -15,3 +23,5 @@ if test x"$samba_cv_REPLACE_GETPASS" = x"yes"; then
AC_DEFINE(REPLACE_GETPASS,1,[Whether getpass should be replaced])
LIBREPLACEOBJ="${LIBREPLACEOBJ} getpass.o"
fi
+
+fi
diff --git a/source/lib/replace/libreplace.m4 b/source/lib/replace/libreplace.m4
index e9b19b7cf5..e430a7f151 100644
--- a/source/lib/replace/libreplace.m4
+++ b/source/lib/replace/libreplace.m4
@@ -99,7 +99,7 @@ AC_CHECK_HEADERS(stdarg.h vararg.h)
AC_CHECK_HEADERS(sys/socket.h netinet/in.h netdb.h arpa/inet.h)
AC_CHECK_HEADERS(netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h)
AC_CHECK_HEADERS(sys/sockio.h sys/un.h)
-
+AC_CHECK_HEADERS(stropts.h)
dnl we need to check that net/if.h really can be used, to cope with hpux
dnl where including it always fails
diff --git a/source/lib/replace/system/network.h b/source/lib/replace/system/network.h
index 5e648dcd15..94ec132a2e 100644
--- a/source/lib/replace/system/network.h
+++ b/source/lib/replace/system/network.h
@@ -74,6 +74,10 @@
#include <sys/ioctl.h>
#endif
+#ifdef HAVE_STROPTS_H
+#include <stropts.h>
+#endif
+
#ifdef SOCKET_WRAPPER
#ifndef SOCKET_WRAPPER_NOT_REPLACE
#define SOCKET_WRAPPER_REPLACE
diff --git a/source/lib/system.c b/source/lib/system.c
index ac1add8fc1..b23aa04846 100644
--- a/source/lib/system.c
+++ b/source/lib/system.c
@@ -2161,9 +2161,10 @@ int sys_setxattr (const char *path, const char *name, const void *value, size_t
#elif defined(HAVE_ATTROPEN)
int ret = -1;
int myflags = O_RDWR;
+ int attrfd;
if (flags & XATTR_CREATE) myflags |= O_EXCL;
if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
- int attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
+ attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
if (attrfd >= 0) {
ret = solaris_write_xattr(attrfd, value, size);
close(attrfd);
@@ -2224,9 +2225,10 @@ int sys_lsetxattr (const char *path, const char *name, const void *value, size_t
#elif defined(HAVE_ATTROPEN)
int ret = -1;
int myflags = O_RDWR | AT_SYMLINK_NOFOLLOW;
+ int attrfd;
if (flags & XATTR_CREATE) myflags |= O_EXCL;
if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
- int attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
+ attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
if (attrfd >= 0) {
ret = solaris_write_xattr(attrfd, value, size);
close(attrfd);
@@ -2288,9 +2290,10 @@ int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size
#elif defined(HAVE_ATTROPEN)
int ret = -1;
int myflags = O_RDWR | O_XATTR;
+ int attrfd;
if (flags & XATTR_CREATE) myflags |= O_EXCL;
if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
- int attrfd = solaris_openat(filedes, name, myflags, (mode_t) SOLARIS_ATTRMODE);
+ attrfd = solaris_openat(filedes, name, myflags, (mode_t) SOLARIS_ATTRMODE);
if (attrfd >= 0) {
ret = solaris_write_xattr(attrfd, value, size);
close(attrfd);
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index 52cdbfcedd..b734495b83 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -394,7 +394,11 @@ BOOL strisnormal(const char *s, int case_default)
NOTE: oldc and newc must be 7 bit characters
**/
-void string_replace( pstring s, char oldc, char newc )
+/**
+ String replace.
+ NOTE: oldc and newc must be 7 bit characters
+**/
+void string_replace( char *s, char oldc, char newc )
{
char *p;
@@ -406,8 +410,9 @@ void string_replace( pstring s, char oldc, char newc )
for (p = s; *p; p++) {
if (*p & 0x80) /* mb string - slow path. */
break;
- if (*p == oldc)
+ if (*p == oldc) {
*p = newc;
+ }
}
if (!*p)
@@ -418,9 +423,18 @@ void string_replace( pstring s, char oldc, char newc )
/* With compose characters we must restart from the beginning. JRA. */
p = s;
#endif
- push_ucs2(NULL, tmpbuf, p, sizeof(tmpbuf), STR_TERMINATE);
- string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc));
- pull_ucs2(NULL, p, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
+
+ while (*p) {
+ size_t c_size;
+ next_codepoint(p, &c_size);
+
+ if (c_size == 1) {
+ if (*p == oldc) {
+ *p = newc;
+ }
+ }
+ p += c_size;
+ }
}
/**
diff --git a/source/libads/kerberos.c b/source/libads/kerberos.c
index c74c98dd97..089540536c 100644
--- a/source/libads/kerberos.c
+++ b/source/libads/kerberos.c
@@ -362,6 +362,61 @@ char* kerberos_secrets_fetch_des_salt( void )
return salt;
}
+/************************************************************************
+ Routine to get the default realm from the kerberos credentials cache.
+ Caller must free if the return value is not NULL.
+************************************************************************/
+
+char *kerberos_get_default_realm_from_ccache( void )
+{
+ char *realm = NULL;
+ krb5_context ctx = NULL;
+ krb5_ccache cc = NULL;
+ krb5_principal princ = NULL;
+
+ initialize_krb5_error_table();
+ if (krb5_init_context(&ctx)) {
+ return NULL;
+ }
+
+ DEBUG(5,("kerberos_get_default_realm_from_ccache: "
+ "Trying to read krb5 cache: %s\n",
+ krb5_cc_default_name(ctx)));
+ if (krb5_cc_default(ctx, &cc)) {
+ DEBUG(0,("kerberos_get_default_realm_from_ccache: "
+ "failed to read default cache\n"));
+ goto out;
+ }
+ if (krb5_cc_get_principal(ctx, cc, &princ)) {
+ DEBUG(0,("kerberos_get_default_realm_from_ccache: "
+ "failed to get default principal\n"));
+ goto out;
+ }
+
+#if defined(HAVE_KRB5_PRINCIPAL_GET_REALM)
+ realm = SMB_STRDUP(krb5_principal_get_realm(ctx, princ));
+#elif defined(HAVE_KRB5_PRINC_REALM)
+ {
+ krb5_data *realm_data = krb5_princ_realm(ctx, princ);
+ realm = SMB_STRNDUP(realm_data->data, realm_data->length);
+ }
+#endif
+
+ out:
+
+ if (princ) {
+ krb5_free_principal(ctx, princ);
+ }
+ if (cc) {
+ krb5_cc_close(ctx, cc);
+ }
+ if (ctx) {
+ krb5_free_context(ctx);
+ }
+
+ return realm;
+}
+
/************************************************************************
Routine to get the salting principal for this service. This is
@@ -621,11 +676,15 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do
TALLOC_FREE(dname);
return False;
}
-
- file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n"
- "[realms]\n\t%s = {\n"
- "\t%s\t}\n",
- realm_upper, realm_upper, kdc_ip_string);
+
+ file_contents = talloc_asprintf(fname,
+ "[libdefaults]\n\tdefault_realm = %s\n"
+ "default_tgs_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
+ "default_tkt_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
+ "preferred_enctypes = RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n\n"
+ "[realms]\n\t%s = {\n"
+ "\t%s\t}\n",
+ realm_upper, realm_upper, kdc_ip_string);
if (!file_contents) {
TALLOC_FREE(dname);
diff --git a/source/libads/sasl.c b/source/libads/sasl.c
index 0067a19d3b..40749be745 100644
--- a/source/libads/sasl.c
+++ b/source/libads/sasl.c
@@ -137,10 +137,81 @@ static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
}
#ifdef HAVE_KRB5
+struct ads_service_principal {
+ char *string;
+#ifdef HAVE_GSSAPI
+ gss_name_t name;
+#endif
+};
+
+static void ads_free_service_principal(struct ads_service_principal *p)
+{
+ SAFE_FREE(p->string);
+
+#ifdef HAVE_GSSAPI
+ if (p->name) {
+ uint32 minor_status;
+ gss_release_name(&minor_status, &p->name);
+ }
+#endif
+ ZERO_STRUCTP(p);
+}
+
+static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads,
+ const char *given_principal,
+ struct ads_service_principal *p)
+{
+ ADS_STATUS status;
+#ifdef HAVE_GSSAPI
+ gss_buffer_desc input_name;
+ /* GSS_KRB5_NT_PRINCIPAL_NAME */
+ gss_OID_desc nt_principal =
+ {10, CONST_DISCARD(char *, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01")};
+ uint32 minor_status;
+ int gss_rc;
+#endif
+
+ ZERO_STRUCTP(p);
+
+ /* I've seen a child Windows 2000 domain not send
+ the principal name back in the first round of
+ the SASL bind reply. So we guess based on server
+ name and realm. --jerry */
+ /* Also try best guess when we get the w2k8 ignore
+ principal back - gd */
+
+ if (!given_principal ||
+ strequal(given_principal, ADS_IGNORE_PRINCIPAL)) {
+
+ status = ads_guess_service_principal(ads, &p->string);
+ if (!ADS_ERR_OK(status)) {
+ return status;
+ }
+ } else {
+ p->string = SMB_STRDUP(given_principal);
+ if (!p->string) {
+ return ADS_ERROR(LDAP_NO_MEMORY);
+ }
+ }
+
+#ifdef HAVE_GSSAPI
+ input_name.value = p->string;
+ input_name.length = strlen(p->string);
+
+ gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &p->name);
+ if (gss_rc) {
+ ads_free_service_principal(p);
+ return ADS_ERROR_GSS(gss_rc, minor_status);
+ }
+#endif
+
+ return ADS_SUCCESS;
+}
+
/*
perform a LDAP/SASL/SPNEGO/KRB5 bind
*/
-static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *principal)
+static ADS_STATUS ads_sasl_spnego_rawkrb5_bind(ADS_STRUCT *ads, const char *principal)
{
DATA_BLOB blob = data_blob(NULL, 0);
struct berval cred, *scred = NULL;
@@ -167,6 +238,13 @@ static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads, const char *princip
return ADS_ERROR(rc);
}
+
+static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads,
+ struct ads_service_principal *p)
+{
+ return ads_sasl_spnego_rawkrb5_bind(ads, p->string);
+}
+
#endif
/*
@@ -178,7 +256,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
int rc, i;
ADS_STATUS status;
DATA_BLOB blob;
- char *principal = NULL;
+ char *given_principal = NULL;
char *OIDs[ASN1_MAX_OIDS];
#ifdef HAVE_KRB5
BOOL got_kerberos_mechanism = False;
@@ -201,7 +279,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
/* the server sent us the first part of the SPNEGO exchange in the negprot
reply */
- if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) {
+ if (!spnego_parse_negTokenInit(blob, OIDs, &given_principal)) {
data_blob_free(&blob);
status = ADS_ERROR(LDAP_OPERATIONS_ERROR);
goto failed;
@@ -219,42 +297,23 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
#endif
free(OIDs[i]);
}
- DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", principal));
+ DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", given_principal));
#ifdef HAVE_KRB5
if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) &&
got_kerberos_mechanism)
{
- /* I've seen a child Windows 2000 domain not send
- the principal name back in the first round of
- the SASL bind reply. So we guess based on server
- name and realm. --jerry */
- if ( !principal ) {
- if ( ads->server.realm && ads->server.ldap_server ) {
- char *server, *server_realm;
-
- server = SMB_STRDUP( ads->server.ldap_server );
- server_realm = SMB_STRDUP( ads->server.realm );
-
- if ( !server || !server_realm )
- return ADS_ERROR(LDAP_NO_MEMORY);
-
- strlower_m( server );
- strupper_m( server_realm );
- asprintf( &principal, "ldap/%s@%s", server, server_realm );
-
- SAFE_FREE( server );
- SAFE_FREE( server_realm );
-
- if ( !principal )
- return ADS_ERROR(LDAP_NO_MEMORY);
- }
-
+ struct ads_service_principal p;
+
+ status = ads_generate_service_principal(ads, given_principal, &p);
+ SAFE_FREE(given_principal);
+ if (!ADS_ERR_OK(status)) {
+ return status;
}
-
- status = ads_sasl_spnego_krb5_bind(ads, principal);
+
+ status = ads_sasl_spnego_krb5_bind(ads, &p);
if (ADS_ERR_OK(status)) {
- SAFE_FREE(principal);
+ ads_free_service_principal(&p);
return status;
}
@@ -264,19 +323,26 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
status = ADS_ERROR_KRB5(ads_kinit_password(ads));
if (ADS_ERR_OK(status)) {
- status = ads_sasl_spnego_krb5_bind(ads, principal);
+ status = ads_sasl_spnego_krb5_bind(ads, &p);
+ if (!ADS_ERR_OK(status)) {
+ DEBUG(0,("kinit succeeded but "
+ "ads_sasl_spnego_krb5_bind failed: %s\n",
+ ads_errstr(status)));
+ }
}
+ ads_free_service_principal(&p);
+
/* only fallback to NTLMSSP if allowed */
if (ADS_ERR_OK(status) ||
!(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) {
- SAFE_FREE(principal);
return status;
}
- }
+ } else
#endif
-
- SAFE_FREE(principal);
+ {
+ SAFE_FREE(given_principal);
+ }
/* lets do NTLMSSP ... this has the big advantage that we don't need
to sync clocks, and we don't rely on special versions of the krb5
diff --git a/source/libads/util.c b/source/libads/util.c
index eb6dccb3af..365f72e7da 100644
--- a/source/libads/util.c
+++ b/source/libads/util.c
@@ -52,4 +52,61 @@ failed:
SAFE_FREE(password);
return ret;
}
+
+ADS_STATUS ads_guess_service_principal(ADS_STRUCT *ads,
+ char **returned_principal)
+{
+ char *princ = NULL;
+
+ if (ads->server.realm && ads->server.ldap_server) {
+ char *server, *server_realm;
+
+ server = SMB_STRDUP(ads->server.ldap_server);
+ server_realm = SMB_STRDUP(ads->server.realm);
+
+ if (!server || !server_realm) {
+ return ADS_ERROR(LDAP_NO_MEMORY);
+ }
+
+ strlower_m(server);
+ strupper_m(server_realm);
+ asprintf(&princ, "ldap/%s@%s", server, server_realm);
+
+ SAFE_FREE(server);
+ SAFE_FREE(server_realm);
+
+ if (!princ) {
+ return ADS_ERROR(LDAP_NO_MEMORY);
+ }
+ } else if (ads->config.realm && ads->config.ldap_server_name) {
+ char *server, *server_realm;
+
+ server = SMB_STRDUP(ads->config.ldap_server_name);
+ server_realm = SMB_STRDUP(ads->config.realm);
+
+ if (!server || !server_realm) {
+ return ADS_ERROR(LDAP_NO_MEMORY);
+ }
+
+ strlower_m(server);
+ strupper_m(server_realm);
+ asprintf(&princ, "ldap/%s@%s", server, server_realm);
+
+ SAFE_FREE(server);
+ SAFE_FREE(server_realm);
+
+ if (!princ) {
+ return ADS_ERROR(LDAP_NO_MEMORY);
+ }
+ }
+
+ if (!princ) {
+ return ADS_ERROR(LDAP_PARAM_ERROR);
+ }
+
+ *returned_principal = princ;
+
+ return ADS_SUCCESS;
+}
+
#endif
diff --git a/source/libmsrpc/cac_samr.c b/source/libmsrpc/cac_samr.c
index 4d3acc85e3..dd9e2c28db 100644
--- a/source/libmsrpc/cac_samr.c
+++ b/source/libmsrpc/cac_samr.c
@@ -365,9 +365,7 @@ int cac_SamCreateUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
POLICY_HND *user_out = NULL;
uint32 rid_out;
-
- /**found in rpcclient/cmd_samr.c*/
- uint32 unknown = 0xe005000b;
+ uint32 acct_flags=0;
if ( !hnd )
return CAC_FAILURE;
@@ -395,10 +393,16 @@ int cac_SamCreateUser( CacServerHandle * hnd, TALLOC_CTX * mem_ctx,
return CAC_FAILURE;
}
+ acct_flags = SAMR_GENERIC_READ | SAMR_GENERIC_WRITE |
+ SAMR_GENERIC_EXECUTE | SAMR_STANDARD_WRITEDAC |
+ SAMR_STANDARD_DELETE | SAMR_USER_SETPASS | SAMR_USER_GETATTR |
+ SAMR_USER_SETATTR;
+ DEBUG(10, ("Creating account with flags: %d\n",acct_flags));
+
hnd->status =
rpccli_samr_create_dom_user( pipe_hnd, mem_ctx,
op->in.dom_hnd, op->in.name,
- op->in.acb_mask, unknown,
+ op->in.acb_mask, acct_flags,
user_out, &rid_out );
if ( !NT_STATUS_IS_OK( hnd->status ) )
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index d458ce2757..42e0b63511 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -40,6 +40,8 @@ static const struct {
{-1,NULL}
};
+static const char *star_smbserver_name = "*SMBSERVER";
+
/**
* Set the user session key for a connection
* @param cli The cli structure to add it too
@@ -628,7 +630,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *
if (!cli_session_setup_blob(cli, negTokenTarg, session_key_krb5)) {
data_blob_free(&negTokenTarg);
data_blob_free(&session_key_krb5);
- ADS_ERROR_NT(cli_nt_error(cli));
+ return ADS_ERROR_NT(cli_nt_error(cli));
}
cli_set_session_key(cli, session_key_krb5);
@@ -861,10 +863,55 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
}
}
- rc = cli_session_setup_kerberos(cli, principal, domain);
- if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
+ /* If we get a bad principal, try to guess it if
+ we have a valid host NetBIOS name.
+ */
+ if (strequal(principal, ADS_IGNORE_PRINCIPAL)) {
SAFE_FREE(principal);
- return rc;
+ }
+ if (principal == NULL &&
+ !is_ipaddress(cli->desthost) &&
+ !strequal(star_smbserver_name,
+ cli->desthost)) {
+ char *realm = NULL;
+ char *machine = NULL;
+ char *host = NULL;
+ DEBUG(3,("cli_session_setup_spnego: got a "
+ "bad server principal, trying to guess ...\n"));
+
+ host = strchr_m(cli->desthost, '.');
+ if (host) {
+ machine = SMB_STRNDUP(cli->desthost,
+ host - cli->desthost);
+ } else {
+ machine = SMB_STRDUP(cli->desthost);
+ }
+ if (machine == NULL) {
+ return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
+ realm = kerberos_get_default_realm_from_ccache();
+ if (realm && *realm) {
+ if (asprintf(&principal, "%s$@%s",
+ machine, realm) < 0) {
+ SAFE_FREE(machine);
+ SAFE_FREE(realm);
+ return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+ DEBUG(3,("cli_session_setup_spnego: guessed "
+ "server principal=%s\n",
+ principal ? principal : "<null>"));
+ }
+ SAFE_FREE(machine);
+ SAFE_FREE(realm);
+ }
+
+ if (principal) {
+ rc = cli_session_setup_kerberos(cli, principal, domain);
+ if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
+ SAFE_FREE(principal);
+ return rc;
+ }
}
}
#endif
@@ -1412,7 +1459,7 @@ NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip
char *p;
/* reasonable default hostname */
- if (!host) host = "*SMBSERVER";
+ if (!host) host = star_smbserver_name;
fstrcpy(cli->desthost, host);
@@ -1527,8 +1574,8 @@ again:
*p = 0;
goto again;
}
- if (strcmp(called.name, "*SMBSERVER")) {
- make_nmb_name(&called , "*SMBSERVER", 0x20);
+ if (strcmp(called.name, star_smbserver_name)) {
+ make_nmb_name(&called , star_smbserver_name, 0x20);
goto again;
}
return NT_STATUS_BAD_NETWORK_NAME;
@@ -1652,7 +1699,7 @@ BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho
*/
if(is_ipaddress(desthost)) {
- make_nmb_name(&called, "*SMBSERVER", 0x20);
+ make_nmb_name(&called, star_smbserver_name, 0x20);
} else {
make_nmb_name(&called, desthost, 0x20);
}
@@ -1661,7 +1708,7 @@ BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho
NTSTATUS status;
struct nmb_name smbservername;
- make_nmb_name(&smbservername , "*SMBSERVER", 0x20);
+ make_nmb_name(&smbservername, star_smbserver_name, 0x20);
/*
* If the name wasn't *SMBSERVER then
diff --git a/source/libsmb/clierror.c b/source/libsmb/clierror.c
index ff6fbf522f..cacfe8221c 100644
--- a/source/libsmb/clierror.c
+++ b/source/libsmb/clierror.c
@@ -469,3 +469,15 @@ void cli_set_nt_error(struct cli_state *cli, NTSTATUS status)
SSVAL(cli->inbuf,smb_flg2, SVAL(cli->inbuf,smb_flg2)|FLAGS2_32_BIT_ERROR_CODES);
SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(status));
}
+
+/* Reset an error. */
+
+void cli_reset_error(struct cli_state *cli)
+{
+ if (SVAL(cli->inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES) {
+ SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(NT_STATUS_OK));
+ } else {
+ SCVAL(cli->inbuf,smb_rcls,0);
+ SSVAL(cli->inbuf,smb_err,0);
+ }
+}
diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c
index 6337b50ce9..e7b68921e5 100644
--- a/source/libsmb/clikrb5.c
+++ b/source/libsmb/clikrb5.c
@@ -336,8 +336,8 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_
got_auth_data_pac = unwrap_pac(mem_ctx, &auth_data_wrapped, auth_data);
data_blob_free(&auth_data_wrapped);
- if (!got_auth_data_pac) {
- continue;
+ if (got_auth_data_pac) {
+ return true;
}
}
@@ -363,9 +363,9 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_
/* check if it is a PAC */
got_auth_data_pac = unwrap_pac(mem_ctx, &auth_data_wrapped, auth_data);
data_blob_free(&auth_data_wrapped);
-
- if (!got_auth_data_pac) {
- continue;
+
+ if (got_auth_data_pac) {
+ return true;
}
}
diff --git a/source/libsmb/clilist.c b/source/libsmb/clilist.c
index 3e76cd4775..98c043635f 100644
--- a/source/libsmb/clilist.c
+++ b/source/libsmb/clilist.c
@@ -247,7 +247,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
&rparam, &param_len,
&rdata, &data_len) &&
cli_is_dos_error(cli)) {
- /* we need to work around a Win95 bug - sometimes
+ /* We need to work around a Win95 bug - sometimes
it gives ERRSRV/ERRerror temprarily */
uint8 eclass;
uint32 ecode;
@@ -256,6 +256,20 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
SAFE_FREE(rparam);
cli_dos_error(cli, &eclass, &ecode);
+
+ /*
+ * OS/2 might return "no more files",
+ * which just tells us, that searchcount is zero
+ * in this search.
+ * Guenter Kukkukk <linux@kukkukk.com>
+ */
+
+ if (eclass == ERRDOS && ecode == ERRnofiles) {
+ ff_searchcount = 0;
+ cli_reset_error(cli);
+ break;
+ }
+
if (eclass != ERRSRV || ecode != ERRerror)
break;
smb_msleep(100);
diff --git a/source/libsmb/clitrans.c b/source/libsmb/clitrans.c
index f212f49994..f43a2aa028 100644
--- a/source/libsmb/clitrans.c
+++ b/source/libsmb/clitrans.c
@@ -95,14 +95,9 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
return False;
}
- /* Note we're in a trans state. Save the sequence
- * numbers for replies. */
- client_set_trans_sign_state_on(cli, mid);
-
if (this_ldata < ldata || this_lparam < lparam) {
/* receive interim response */
if (!cli_receive_smb(cli) || cli_is_error(cli)) {
- client_set_trans_sign_state_off(cli, mid);
return(False);
}
@@ -144,7 +139,6 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
show_msg(cli->outbuf);
if (!cli_send_smb(cli)) {
- client_set_trans_sign_state_off(cli, mid);
return False;
}
@@ -323,7 +317,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans,
out:
- client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid));
return ret;
}
@@ -391,14 +384,9 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
return False;
}
- /* Note we're in a trans state. Save the sequence
- * numbers for replies. */
- client_set_trans_sign_state_on(cli, mid);
-
if (this_ldata < ldata || this_lparam < lparam) {
/* receive interim response */
if (!cli_receive_smb(cli) || cli_is_error(cli)) {
- client_set_trans_sign_state_off(cli, mid);
return(False);
}
@@ -440,7 +428,6 @@ BOOL cli_send_nt_trans(struct cli_state *cli,
show_msg(cli->outbuf);
if (!cli_send_smb(cli)) {
- client_set_trans_sign_state_off(cli, mid);
return False;
}
@@ -640,6 +627,5 @@ BOOL cli_receive_nt_trans(struct cli_state *cli,
out:
- client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid));
return ret;
}
diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c
index 5280dfdbff..641473bea1 100644
--- a/source/libsmb/nmblib.c
+++ b/source/libsmb/nmblib.c
@@ -702,6 +702,8 @@ struct packet_struct *parse_packet(char *buf,int length,
if (!p)
return(NULL);
+ ZERO_STRUCTP(p); /* initialize for possible padding */
+
p->next = NULL;
p->prev = NULL;
p->ip = lastip;
diff --git a/source/libsmb/smb_signing.c b/source/libsmb/smb_signing.c
index df74b2db36..6768c2accc 100644
--- a/source/libsmb/smb_signing.c
+++ b/source/libsmb/smb_signing.c
@@ -26,7 +26,6 @@ struct outstanding_packet_lookup {
struct outstanding_packet_lookup *prev, *next;
uint16 mid;
uint32 reply_seq_num;
- BOOL can_delete; /* Set to False in trans state. */
};
struct smb_basic_signing_context {
@@ -43,7 +42,9 @@ static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list,
/* Ensure we only add a mid once. */
for (t = *list; t; t = t->next) {
if (t->mid == mid) {
- return False;
+ DLIST_REMOVE(*list, t);
+ SAFE_FREE(t);
+ break;
}
}
@@ -52,7 +53,6 @@ static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list,
t->mid = mid;
t->reply_seq_num = reply_seq_num;
- t->can_delete = True;
/*
* Add to the *start* of the list not the end of the list.
@@ -79,23 +79,8 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list,
*reply_seq_num = t->reply_seq_num;
DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n",
(unsigned int)t->reply_seq_num, (unsigned int)t->mid ));
- if (t->can_delete) {
- DLIST_REMOVE(*list, t);
- SAFE_FREE(t);
- }
- return True;
- }
- }
- return False;
-}
-
-static BOOL set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, BOOL can_delete_entry)
-{
- struct outstanding_packet_lookup *t;
-
- for (t = *list; t; t = t->next) {
- if (t->mid == mid) {
- t->can_delete = can_delete_entry;
+ DLIST_REMOVE(*list, t);
+ SAFE_FREE(t);
return True;
}
}
@@ -604,60 +589,6 @@ BOOL cli_check_sign_mac(struct cli_state *cli)
}
/***********************************************************
- Enter trans/trans2/nttrans state.
-************************************************************/
-
-BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid)
-{
- struct smb_sign_info *si = &cli->sign_info;
- struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context;
-
- if (!si->doing_signing) {
- return True;
- }
-
- if (!data) {
- return False;
- }
-
- if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) {
- return False;
- }
-
- return True;
-}
-
-/***********************************************************
- Leave trans/trans2/nttrans state.
-************************************************************/
-
-BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid)
-{
- uint32 reply_seq_num;
- struct smb_sign_info *si = &cli->sign_info;
- struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context;
-
- if (!si->doing_signing) {
- return True;
- }
-
- if (!data) {
- return False;
- }
-
- if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) {
- return False;
- }
-
- /* Now delete the stored mid entry. */
- if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) {
- return False;
- }
-
- return True;
-}
-
-/***********************************************************
SMB signing - Server implementation - send the MAC.
************************************************************/
diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c
index 5f7b5b1809..9812cbf67a 100644
--- a/source/libsmb/smbencrypt.c
+++ b/source/libsmb/smbencrypt.c
@@ -444,7 +444,7 @@ BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uchar nt_
the username and domain.
This prevents username swapping during the auth exchange
*/
- if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) {
+ if (!ntv2_owf_gen(nt_hash, user, domain, False, ntlm_v2_hash)) {
return False;
}
diff --git a/source/libsmb/trusts_util.c b/source/libsmb/trusts_util.c
index e4061883eb..2580b50054 100644
--- a/source/libsmb/trusts_util.c
+++ b/source/libsmb/trusts_util.c
@@ -41,7 +41,7 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX
already have valid creds. If not we must set them up. */
if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) {
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS;
result = rpccli_netlogon_setup_creds(cli,
cli->cli->desthost, /* server name */
diff --git a/source/libsmb/unexpected.c b/source/libsmb/unexpected.c
index 97d6071e71..0e4e03384c 100644
--- a/source/libsmb/unexpected.c
+++ b/source/libsmb/unexpected.c
@@ -59,6 +59,8 @@ void unexpected_packet(struct packet_struct *p)
len = build_packet(buf, p);
+ ZERO_STRUCT(key); /* needed for potential alignment */
+
key.packet_type = p->packet_type;
key.timestamp = p->timestamp;
key.count = count++;
@@ -81,6 +83,10 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st
{
struct unexpected_key key;
+ if (kbuf.dsize != sizeof(key)) {
+ tdb_delete(ttdb, kbuf);
+ }
+
memcpy(&key, kbuf.dptr, sizeof(key));
if (lastt - key.timestamp > NMBD_UNEXPECTED_TIMEOUT) {
@@ -120,6 +126,10 @@ static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void
struct unexpected_key key;
struct packet_struct *p;
+ if (kbuf.dsize != sizeof(key)) {
+ return 0;
+ }
+
memcpy(&key, kbuf.dptr, sizeof(key));
if (key.packet_type != match_type) return 0;
diff --git a/source/modules/vfs_default.c b/source/modules/vfs_default.c
index 98e9aaa263..4cc6e8856b 100644
--- a/source/modules/vfs_default.c
+++ b/source/modules/vfs_default.c
@@ -444,7 +444,7 @@ static int vfswrap_rename(vfs_handle_struct *handle, const char *oldname, const
START_PROFILE(syscall_rename);
result = rename(oldname, newname);
- if (errno == EXDEV) {
+ if ((result == -1) && (errno == EXDEV)) {
/* Rename across filesystems needed. */
result = copy_reg(oldname, newname);
}
diff --git a/source/modules/vfs_hpuxacl.c b/source/modules/vfs_hpuxacl.c
index 3885758523..f1e0c5087b 100644
--- a/source/modules/vfs_hpuxacl.c
+++ b/source/modules/vfs_hpuxacl.c
@@ -141,7 +141,7 @@ SMB_ACL_T hpuxacl_sys_acl_get_file(vfs_handle_struct *handle,
{
SMB_ACL_T result = NULL;
int count;
- HPUX_ACL_T hpux_acl;
+ HPUX_ACL_T hpux_acl = NULL;
DEBUG(10, ("hpuxacl_sys_acl_get_file called for file '%s'.\n",
path_p));
@@ -215,7 +215,7 @@ int hpuxacl_sys_acl_set_file(vfs_handle_struct *handle,
{
int ret = -1;
SMB_STRUCT_STAT s;
- HPUX_ACL_T hpux_acl;
+ HPUX_ACL_T hpux_acl = NULL;
int count;
DEBUG(10, ("hpuxacl_sys_acl_set_file called for file '%s'\n",
diff --git a/source/modules/vfs_notify_fam.c b/source/modules/vfs_notify_fam.c
index b76046b378..1758a9f2bc 100644
--- a/source/modules/vfs_notify_fam.c
+++ b/source/modules/vfs_notify_fam.c
@@ -156,6 +156,9 @@ static void fam_handler(struct event_context *event_ctx,
fam_event.filename));
switch (fam_event.code) {
+ case FAMChanged:
+ ne.action = NOTIFY_ACTION_MODIFIED;
+ break;
case FAMCreated:
ne.action = NOTIFY_ACTION_ADDED;
break;
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index 46f209872b..742c747ae5 100644
--- a/source/nmbd/nmbd.c
+++ b/source/nmbd/nmbd.c
@@ -150,23 +150,30 @@ static void expire_names_and_servers(time_t t)
/************************************************************************** **
Reload the list of network interfaces.
+ Doesn't return until a network interface is up.
************************************************************************** */
-static BOOL reload_interfaces(time_t t)
+static void reload_interfaces(time_t t)
{
static time_t lastt;
int n;
struct subnet_record *subrec;
- if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return False;
+ if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) {
+ return;
+ }
lastt = t;
- if (!interfaces_changed()) return False;
+ if (!interfaces_changed()) {
+ return;
+ }
/* the list of probed interfaces has changed, we may need to add/remove
some subnets */
load_interfaces();
+ try_again:
+
/* find any interfaces that need adding */
for (n=iface_count() - 1; n >= 0; n--) {
struct interface *iface = get_interface(n);
@@ -221,15 +228,35 @@ static BOOL reload_interfaces(time_t t)
close_subnet(subrec);
}
}
-
+
rescan_listen_set = True;
- /* We need to shutdown if there are no subnets... */
+ /* We need to wait if there are no subnets... */
if (FIRST_SUBNET == NULL) {
- DEBUG(0,("reload_interfaces: No subnets to listen to. Shutting down...\n"));
- return True;
+ void (*saved_handler)(int);
+
+ DEBUG(0,("reload_interfaces: "
+ "No subnets to listen to. Waiting..\n"));
+
+ /*
+ * Whilst we're waiting for an interface, allow SIGTERM to
+ * cause us to exit.
+ */
+
+ saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );
+
+ while (iface_count() == 0) {
+ sleep(5);
+ load_interfaces();
+ }
+
+ /*
+ * We got an interface, restore our normal term handler.
+ */
+
+ CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
+ goto try_again;
}
- return False;
}
/**************************************************************************** **
@@ -267,8 +294,6 @@ static BOOL reload_nmbd_services(BOOL test)
/**************************************************************************** **
* React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
- * We use buf here to return BOOL result to process() when reload_interfaces()
- * detects that there are no subnets.
**************************************************************************** */
static void msg_reload_nmbd_services(int msg_type, struct process_id src,
@@ -278,14 +303,7 @@ static void msg_reload_nmbd_services(int msg_type, struct process_id src,
dump_all_namelists();
reload_nmbd_services( True );
reopen_logs();
-
- if(buf) {
- /* We were called from process() */
- /* If reload_interfaces() returned True */
- /* we need to shutdown if there are no subnets... */
- /* pass this info back to process() */
- *((BOOL*)buf) = reload_interfaces(0);
- }
+ reload_interfaces(0);
}
static void msg_nmbd_send_packet(int msg_type, struct process_id src,
@@ -348,7 +366,6 @@ static void msg_nmbd_send_packet(int msg_type, struct process_id src,
static void process(void)
{
BOOL run_election;
- BOOL no_subnets;
while( True ) {
time_t t = time(NULL);
@@ -558,19 +575,16 @@ static void process(void)
if(reload_after_sighup) {
DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
msg_reload_nmbd_services(MSG_SMB_CONF_UPDATED,
- pid_to_procid(0), (void*) &no_subnets, 0, NULL);
- if(no_subnets)
- return;
+ pid_to_procid(0), NULL, 0, NULL);
reload_after_sighup = 0;
}
/* check for new network interfaces */
- if(reload_interfaces(t))
- return;
+ reload_interfaces(t);
/* free up temp memory */
- lp_TALLOC_FREE();
+ lp_TALLOC_FREE();
}
}
diff --git a/source/nmbd/nmbd_namelistdb.c b/source/nmbd/nmbd_namelistdb.c
index cda12885ef..a4ad6cfca3 100644
--- a/source/nmbd/nmbd_namelistdb.c
+++ b/source/nmbd/nmbd_namelistdb.c
@@ -294,7 +294,6 @@ void standard_success_register(struct subnet_record *subrec,
******************************************************************/
void standard_fail_register( struct subnet_record *subrec,
- struct response_record *rrec,
struct nmb_name *nmbname )
{
struct name_record *namerec;
diff --git a/source/nmbd/nmbd_nameregister.c b/source/nmbd/nmbd_nameregister.c
index 8f2a889254..541d594d82 100644
--- a/source/nmbd/nmbd_nameregister.c
+++ b/source/nmbd/nmbd_nameregister.c
@@ -153,10 +153,11 @@ static void register_name_response(struct subnet_record *subrec,
if( rrec->success_fn)
(*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, answer_name, nb_flags, ttl, register_ip);
} else {
+ struct nmb_name qname = *question_name;
if( rrec->fail_fn)
(*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
/* Remove the name. */
- standard_fail_register( subrec, rrec, question_name);
+ standard_fail_register( subrec, &qname);
}
/* Ensure we don't retry. */
@@ -281,10 +282,11 @@ static void register_name_timeout_response(struct subnet_record *subrec,
if( rrec->success_fn)
(*(register_name_success_function)rrec->success_fn)(subrec, rrec->userdata, question_name, nb_flags, ttl, registered_ip);
} else {
+ struct nmb_name qname = *question_name;
if( rrec->fail_fn)
(*(register_name_fail_function)rrec->fail_fn)(subrec, rrec, question_name);
/* Remove the name. */
- standard_fail_register( subrec, rrec, question_name);
+ standard_fail_register( subrec, &qname);
}
/* Ensure we don't retry. */
diff --git a/source/nmbd/nmbd_packets.c b/source/nmbd/nmbd_packets.c
index 1460f7d8cd..97a81fe5e1 100644
--- a/source/nmbd/nmbd_packets.c
+++ b/source/nmbd/nmbd_packets.c
@@ -1606,6 +1606,8 @@ void retransmit_or_expire_response_records(time_t t)
for (subrec = FIRST_SUBNET; subrec; subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) {
struct response_record *rrec, *nextrrec;
+ restart:
+
for (rrec = subrec->responselist; rrec; rrec = nextrrec) {
nextrrec = rrec->next;
@@ -1644,6 +1646,9 @@ on subnet %s\n", rrec->response_id, inet_ntoa(rrec->packet->ip), subrec->subnet_
no timeout function. */
remove_response_record(subrec, rrec);
}
+ /* We have changed subrec->responselist,
+ * restart from the beginning of this list. */
+ goto restart;
} /* !rrec->in_expitation_processing */
} /* rrec->repeat_count > 0 */
} /* rrec->repeat_time <= t */
diff --git a/source/nmbd/nmbd_responserecordsdb.c b/source/nmbd/nmbd_responserecordsdb.c
index 367c1f4427..dc16a07ccf 100644
--- a/source/nmbd/nmbd_responserecordsdb.c
+++ b/source/nmbd/nmbd_responserecordsdb.c
@@ -32,26 +32,12 @@ int num_response_packets = 0;
static void add_response_record(struct subnet_record *subrec,
struct response_record *rrec)
{
- struct response_record *rrec2;
-
num_response_packets++; /* count of total number of packets still around */
DEBUG(4,("add_response_record: adding response record id:%hu to subnet %s. num_records:%d\n",
rrec->response_id, subrec->subnet_name, num_response_packets));
- if (!subrec->responselist) {
- subrec->responselist = rrec;
- rrec->prev = NULL;
- rrec->next = NULL;
- return;
- }
-
- for (rrec2 = subrec->responselist; rrec2->next; rrec2 = rrec2->next)
- ;
-
- rrec2->next = rrec;
- rrec->next = NULL;
- rrec->prev = rrec2;
+ DLIST_ADD_END(subrec->responselist, rrec, struct response_record *);
}
/***************************************************************************
@@ -61,13 +47,25 @@ static void add_response_record(struct subnet_record *subrec,
void remove_response_record(struct subnet_record *subrec,
struct response_record *rrec)
{
- if (rrec->prev)
- rrec->prev->next = rrec->next;
- if (rrec->next)
- rrec->next->prev = rrec->prev;
+ /* It is possible this can be called twice,
+ with a rrec pointer that has been freed. So
+ before we inderect into rrec, search for it
+ on the responselist first. Bug #3617. JRA. */
+
+ struct response_record *p = NULL;
+
+ for (p = subrec->responselist; p; p = p->next) {
+ if (p == rrec) {
+ break;
+ }
+ }
+
+ if (p == NULL) {
+ /* We didn't find rrec on the list. */
+ return;
+ }
- if (subrec->responselist == rrec)
- subrec->responselist = rrec->next;
+ DLIST_REMOVE(subrec->responselist, rrec);
if(rrec->userdata) {
if(rrec->userdata->free_fn) {
diff --git a/source/nsswitch/idmap.c b/source/nsswitch/idmap.c
index 9c38f6b5ad..49ed62bfef 100644
--- a/source/nsswitch/idmap.c
+++ b/source/nsswitch/idmap.c
@@ -367,7 +367,7 @@ NTSTATUS idmap_init(void)
/* terminate */
dl[1] = NULL;
- dom_list = dl;
+ dom_list = (const char **)dl;
default_domain = dl[0];
}
@@ -906,7 +906,7 @@ static NTSTATUS idmap_can_map(const struct id_map *map,
if ( (dom = find_idmap_domain_from_sid( map->sid )) == NULL ) {
/* huh, couldn't find a suitable domain,
* let's just leave it unmapped */
- DEBUG(10, ("Could not find idmap backend for SID %s",
+ DEBUG(10, ("Could not find idmap backend for SID %s\n",
sid_string_static(map->sid)));
return NT_STATUS_NO_SUCH_DOMAIN;
}
diff --git a/source/nsswitch/pam_winbind.c b/source/nsswitch/pam_winbind.c
index ec6361e52b..2846e141fd 100644
--- a/source/nsswitch/pam_winbind.c
+++ b/source/nsswitch/pam_winbind.c
@@ -1028,7 +1028,9 @@ static int winbind_auth_request(pam_handle_t * pamh,
request.data.auth.krb5_cc_type[0] = '\0';
request.data.auth.uid = -1;
- request.flags = WBFLAG_PAM_INFO3_TEXT | WBFLAG_PAM_CONTACT_TRUSTDOM;
+ request.flags = WBFLAG_PAM_INFO3_TEXT |
+ WBFLAG_PAM_GET_PWD_POLICY |
+ WBFLAG_PAM_CONTACT_TRUSTDOM;
if (ctrl & (WINBIND_KRB5_AUTH|WINBIND_CACHED_LOGIN)) {
struct passwd *pwd = NULL;
diff --git a/source/nsswitch/winbind_nss_config.h b/source/nsswitch/winbind_nss_config.h
index c36d4e7232..3722db62d1 100644
--- a/source/nsswitch/winbind_nss_config.h
+++ b/source/nsswitch/winbind_nss_config.h
@@ -36,9 +36,9 @@
#include "lib/replace/replace.h"
#endif
-#include "system/passwd.h"
#include "system/filesys.h"
#include "system/network.h"
+#include "system/passwd.h"
#include "nsswitch/winbind_nss.h"
diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c
index 9bbc0f088b..18abdab348 100644
--- a/source/nsswitch/winbindd.c
+++ b/source/nsswitch/winbindd.c
@@ -541,7 +541,7 @@ static void request_len_recv(void *private_data, BOOL success)
if (*(uint32 *)(&state->request) != sizeof(state->request)) {
DEBUG(0,("request_len_recv: Invalid request size received: %d (expected %d)\n",
- *(uint32 *)(&state->request), sizeof(state->request)));
+ *(uint32 *)(&state->request), (uint32)sizeof(state->request)));
state->finished = True;
return;
}
diff --git a/source/nsswitch/winbindd_async.c b/source/nsswitch/winbindd_async.c
index 32d4e66b0a..ad136bdc0d 100644
--- a/source/nsswitch/winbindd_async.c
+++ b/source/nsswitch/winbindd_async.c
@@ -782,6 +782,12 @@ enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain,
This is the second callback after contacting the forest root
********************************************************************/
+struct lookupname_state {
+ char *dom_name;
+ char *name;
+ void *caller_private_data;
+};
+
static void lookupname_recv2(TALLOC_CTX *mem_ctx, BOOL success,
struct winbindd_response *response,
void *c, void *private_data)
@@ -790,27 +796,28 @@ static void lookupname_recv2(TALLOC_CTX *mem_ctx, BOOL success,
enum lsa_SidType type) =
(void (*)(void *, BOOL, const DOM_SID *, enum lsa_SidType))c;
DOM_SID sid;
+ struct lookupname_state *s = talloc_get_type_abort(private_data, struct lookupname_state);
if (!success) {
DEBUG(5, ("Could not trigger lookup_name\n"));
- cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+ cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
return;
}
if (response->result != WINBINDD_OK) {
DEBUG(5, ("lookup_name returned an error\n"));
- cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+ cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
return;
}
if (!string_to_sid(&sid, response->data.sid.sid)) {
DEBUG(0, ("Could not convert string %s to sid\n",
response->data.sid.sid));
- cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+ cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
return;
}
- cont(private_data, True, &sid,
+ cont(s->caller_private_data, True, &sid,
(enum lsa_SidType)response->data.sid.type);
}
@@ -826,36 +833,32 @@ static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success,
enum lsa_SidType type) =
(void (*)(void *, BOOL, const DOM_SID *, enum lsa_SidType))c;
DOM_SID sid;
+ struct lookupname_state *s = talloc_get_type_abort(private_data, struct lookupname_state);
if (!success) {
DEBUG(5, ("lookupname_recv: lookup_name() failed!\n"));
- cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+ cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
return;
}
if (response->result != WINBINDD_OK) {
/* Try again using the forest root */
struct winbindd_domain *root_domain = find_root_domain();
- struct winbindd_cli_state *state = (struct winbindd_cli_state*)private_data;
- struct winbindd_request request;
- char *name_domain, *name_account;
-
+ struct winbindd_request request;
+
if ( !root_domain ) {
DEBUG(5,("lookupname_recv: unable to determine forest root\n"));
- cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+ cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
return;
}
- name_domain = state->request.data.name.dom_name;
- name_account = state->request.data.name.name;
-
ZERO_STRUCT(request);
request.cmd = WINBINDD_LOOKUPNAME;
- fstrcpy(request.data.name.dom_name, name_domain);
- fstrcpy(request.data.name.name, name_account);
+ fstrcpy(request.data.name.dom_name, s->dom_name);
+ fstrcpy(request.data.name.name, s->name);
do_async_domain(mem_ctx, root_domain, &request, lookupname_recv2,
- (void *)cont, private_data);
+ (void *)cont, s);
return;
}
@@ -863,11 +866,11 @@ static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success,
if (!string_to_sid(&sid, response->data.sid.sid)) {
DEBUG(0, ("Could not convert string %s to sid\n",
response->data.sid.sid));
- cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+ cont(s->caller_private_data, False, NULL, SID_NAME_UNKNOWN);
return;
}
- cont(private_data, True, &sid,
+ cont(s->caller_private_data, True, &sid,
(enum lsa_SidType)response->data.sid.type);
}
@@ -886,6 +889,7 @@ void winbindd_lookupname_async(TALLOC_CTX *mem_ctx,
{
struct winbindd_request request;
struct winbindd_domain *domain;
+ struct lookupname_state *s;
if ( (domain = find_lookup_domain_from_name(dom_name)) == NULL ) {
DEBUG(5, ("Could not find domain for name %s\n", dom_name));
@@ -898,8 +902,23 @@ void winbindd_lookupname_async(TALLOC_CTX *mem_ctx,
fstrcpy(request.data.name.dom_name, dom_name);
fstrcpy(request.data.name.name, name);
+ if ( (s = TALLOC_ZERO_P(mem_ctx, struct lookupname_state)) == NULL ) {
+ DEBUG(0, ("winbindd_lookupname_async: talloc failed\n"));
+ cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+ return;
+ }
+
+ s->dom_name = talloc_strdup( s, dom_name );
+ s->name = talloc_strdup( s, name );
+ if (!s->dom_name || !s->name) {
+ cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+ return;
+ }
+
+ s->caller_private_data = private_data;
+
do_async_domain(mem_ctx, domain, &request, lookupname_recv,
- (void *)cont, private_data);
+ (void *)cont, s);
}
enum winbindd_result winbindd_dual_lookupname(struct winbindd_domain *domain,
diff --git a/source/nsswitch/winbindd_cm.c b/source/nsswitch/winbindd_cm.c
index 9fa1ef1626..14c3fc1fde 100644
--- a/source/nsswitch/winbindd_cm.c
+++ b/source/nsswitch/winbindd_cm.c
@@ -585,6 +585,44 @@ static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
return True;
}
+/**
+ * Helper function to assemble trust password and account name
+ */
+static NTSTATUS get_trust_creds(const struct winbindd_domain *domain,
+ char **machine_password,
+ char **machine_account,
+ char **machine_krb5_principal)
+{
+ const char *account_name;
+
+ if (!get_trust_pw_clear(domain->name, machine_password,
+ &account_name, NULL))
+ {
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+
+ if ((machine_account != NULL) &&
+ (asprintf(machine_account, "%s$", account_name) == -1))
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* this is at least correct when domain is our domain,
+ * which is the only case, when this is currently used: */
+ if (machine_krb5_principal != NULL)
+ {
+ if (asprintf(machine_krb5_principal, "%s$@%s",
+ account_name, domain->alt_name) == -1)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ strupper_m(*machine_krb5_principal);
+ }
+
+ return NT_STATUS_OK;
+}
+
/************************************************************************
Given a fd with a just-connected TCP connection to a DC, open a connection
to the pipe.
@@ -596,8 +634,12 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
struct cli_state **cli,
BOOL *retry)
{
- char *machine_password, *machine_krb5_principal, *machine_account;
- char *ipc_username, *ipc_domain, *ipc_password;
+ char *machine_password = NULL;
+ char *machine_krb5_principal = NULL;
+ char *machine_account = NULL;
+ char *ipc_username = NULL;
+ char *ipc_domain = NULL;
+ char *ipc_password = NULL;
BOOL got_mutex;
@@ -611,23 +653,6 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
controller, domain->name ));
- machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL,
- NULL);
-
- if (asprintf(&machine_account, "%s$", global_myname()) == -1) {
- SAFE_FREE(machine_password);
- return NT_STATUS_NO_MEMORY;
- }
-
- if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(),
- lp_realm()) == -1) {
- SAFE_FREE(machine_account);
- SAFE_FREE(machine_password);
- return NT_STATUS_NO_MEMORY;
- }
-
- cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
-
*retry = True;
got_mutex = secrets_named_mutex(controller,
@@ -684,10 +709,20 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
result = NT_STATUS_UNSUCCESSFUL;
goto done;
}
-
- if ((*cli)->protocol >= PROTOCOL_NT1 && (*cli)->capabilities & CAP_EXTENDED_SECURITY) {
+
+ if (!is_trusted_domain_situation(domain->name) &&
+ (*cli)->protocol >= PROTOCOL_NT1 &&
+ (*cli)->capabilities & CAP_EXTENDED_SECURITY)
+ {
ADS_STATUS ads_status;
+ result = get_trust_creds(domain, &machine_password,
+ &machine_account,
+ &machine_krb5_principal);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto done;
+ }
+
if (lp_security() == SEC_ADS) {
/* Try a krb5 session */
@@ -700,7 +735,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
ads_status = cli_session_setup_spnego(*cli,
machine_krb5_principal,
machine_password,
- lp_workgroup());
+ domain->name);
if (!ADS_ERR_OK(ads_status)) {
DEBUG(4,("failed kerberos session setup with %s\n",
@@ -710,7 +745,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
result = ads_ntstatus(ads_status);
if (NT_STATUS_IS_OK(result)) {
/* Ensure creds are stored for NTLMSSP authenticated pipe access. */
- cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
+ cli_init_creds(*cli, machine_account, domain->name, machine_password);
goto session_setup_done;
}
}
@@ -720,12 +755,12 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
DEBUG(5, ("connecting to %s from %s with username "
"[%s]\\[%s]\n", controller, global_myname(),
- lp_workgroup(), machine_account));
+ domain->name, machine_account));
ads_status = cli_session_setup_spnego(*cli,
machine_account,
machine_password,
- lp_workgroup());
+ domain->name);
if (!ADS_ERR_OK(ads_status)) {
DEBUG(4, ("authenticated session setup failed with %s\n",
ads_errstr(ads_status)));
@@ -734,15 +769,17 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
result = ads_ntstatus(ads_status);
if (NT_STATUS_IS_OK(result)) {
/* Ensure creds are stored for NTLMSSP authenticated pipe access. */
- cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
+ cli_init_creds(*cli, machine_account, domain->name, machine_password);
goto session_setup_done;
}
}
- /* Fall back to non-kerberos session setup */
+ /* Fall back to non-kerberos session setup with auth_user */
(*cli)->use_kerberos = False;
+ cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
+
if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
(strlen(ipc_username) > 0)) {
@@ -907,13 +944,22 @@ static BOOL send_getdc_request(struct in_addr dc_ip,
SIVAL(p, 0, 0); /* The sender's token ... */
p += 2;
- p += dos_PutUniCode(p, global_myname(), sizeof(pstring), True);
+ p += dos_PutUniCode(p, global_myname(),
+ sizeof(outbuf) - PTR_DIFF(p, outbuf), True);
fstr_sprintf(my_acct_name, "%s$", global_myname());
- p += dos_PutUniCode(p, my_acct_name, sizeof(pstring), True);
+ p += dos_PutUniCode(p, my_acct_name,
+ sizeof(outbuf) - PTR_DIFF(p, outbuf), True);
+
+ if (strlen(my_mailslot)+1 > sizeof(outbuf) - PTR_DIFF(p, outbuf)) {
+ return False;
+ }
memcpy(p, my_mailslot, strlen(my_mailslot)+1);
p += strlen(my_mailslot)+1;
+ if (sizeof(outbuf) - PTR_DIFF(p, outbuf) < 8) {
+ return False;
+ }
SIVAL(p, 0, 0x80);
p+=4;
@@ -922,7 +968,15 @@ static BOOL send_getdc_request(struct in_addr dc_ip,
p = ALIGN4(p, outbuf);
- sid_linearize(p, sid_size(sid), sid);
+ if (PTR_DIFF(p, outbuf) > sizeof(outbuf)) {
+ return False;
+ }
+
+ if (sid_size(sid) + 8 > sizeof(outbuf) - PTR_DIFF(p, outbuf)) {
+ return False;
+ }
+
+ sid_linearize(p, sizeof(outbuf) - PTR_DIFF(p, outbuf), sid);
p += sid_size(sid);
SIVAL(p, 0, 1);
@@ -1689,6 +1743,9 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
fstring conn_pwd;
struct dcinfo *p_dcinfo;
+ char *machine_password = NULL;
+ char *machine_account = NULL;
+ char *domain_name = NULL;
result = init_dc_connection(domain);
if (!NT_STATUS_IS_OK(result)) {
@@ -1711,10 +1768,25 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
if ((conn->cli->user_name[0] == '\0') ||
(conn->cli->domain[0] == '\0') ||
- (conn_pwd[0] == '\0')) {
- DEBUG(10, ("cm_connect_sam: No no user available for "
- "domain %s, trying schannel\n", conn->cli->domain));
- goto schannel;
+ (conn_pwd[0] == '\0'))
+ {
+ result = get_trust_creds(domain, &machine_password,
+ &machine_account, NULL);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(10, ("cm_connect_sam: No no user available for "
+ "domain %s, trying schannel\n", conn->cli->domain));
+ goto schannel;
+ }
+ domain_name = domain->name;
+ } else {
+ machine_password = SMB_STRDUP(conn_pwd);
+ machine_account = SMB_STRDUP(conn->cli->user_name);
+ domain_name = conn->cli->domain;
+ }
+
+ if (!machine_password || !machine_account) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
}
/* We have an authenticated connection. Use a NTLMSSP SPNEGO
@@ -1722,23 +1794,23 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
conn->samr_pipe =
cli_rpc_pipe_open_spnego_ntlmssp(conn->cli, PI_SAMR,
PIPE_AUTH_LEVEL_PRIVACY,
- conn->cli->domain,
- conn->cli->user_name,
- conn_pwd, &result);
+ domain_name,
+ machine_account,
+ machine_password, &result);
if (conn->samr_pipe == NULL) {
DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
"pipe for domain %s using NTLMSSP "
"authenticated pipe: user %s\\%s. Error was "
- "%s\n", domain->name, conn->cli->domain,
- conn->cli->user_name, nt_errstr(result)));
+ "%s\n", domain->name, domain_name,
+ machine_account, nt_errstr(result)));
goto schannel;
}
DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
"domain %s using NTLMSSP authenticated "
"pipe: user %s\\%s\n", domain->name,
- conn->cli->domain, conn->cli->user_name ));
+ domain_name, machine_account));
result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
SEC_RIGHTS_MAXIMUM_ALLOWED,
@@ -1823,6 +1895,8 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
*cli = conn->samr_pipe;
*sam_handle = conn->sam_domain_handle;
+ SAFE_FREE(machine_password);
+ SAFE_FREE(machine_account);
return result;
}
@@ -1953,7 +2027,7 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
struct winbindd_cm_conn *conn;
NTSTATUS result;
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS;
uint8 mach_pwd[16];
uint32 sec_chan_type;
const char *account_name;
@@ -1973,36 +2047,27 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
return NT_STATUS_OK;
}
- if (!get_trust_pw(domain->name, mach_pwd, &sec_chan_type)) {
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- }
-
netlogon_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_NETLOGON,
&result);
if (netlogon_pipe == NULL) {
return result;
}
+ if ((!IS_DC) && (!domain->primary)) {
+ /* Clear the schannel request bit and drop down */
+ neg_flags &= ~NETLOGON_NEG_SCHANNEL;
+ goto no_schannel;
+ }
+
if (lp_client_schannel() != False) {
neg_flags |= NETLOGON_NEG_SCHANNEL;
}
- /* if we are a DC and this is a trusted domain, then we need to use our
- domain name in the net_req_auth2() request */
-
- if ( IS_DC
- && !strequal(domain->name, lp_workgroup())
- && lp_allow_trusted_domains() )
+ if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name,
+ &sec_chan_type))
{
- account_name = lp_workgroup();
- } else {
- account_name = domain->primary ?
- global_myname() : domain->name;
- }
-
- if (account_name == NULL) {
cli_rpc_pipe_close(netlogon_pipe);
- return NT_STATUS_NO_MEMORY;
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
result = rpccli_netlogon_setup_creds(
@@ -2027,6 +2092,7 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
return NT_STATUS_ACCESS_DENIED;
}
+ no_schannel:
if ((lp_client_schannel() == False) ||
((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
/* We're done - just keep the existing connection to NETLOGON
diff --git a/source/nsswitch/winbindd_cred_cache.c b/source/nsswitch/winbindd_cred_cache.c
index 368090c390..e47858b628 100644
--- a/source/nsswitch/winbindd_cred_cache.c
+++ b/source/nsswitch/winbindd_cred_cache.c
@@ -426,7 +426,7 @@ NTSTATUS add_ccache_to_list(const char *princ_name,
NTSTATUS remove_ccache(const char *username)
{
struct WINBINDD_CCACHE_ENTRY *entry = get_ccache_by_username(username);
- NTSTATUS status;
+ NTSTATUS status = NT_STATUS_OK;
#ifdef HAVE_KRB5
krb5_error_code ret;
#endif
diff --git a/source/nsswitch/winbindd_dual.c b/source/nsswitch/winbindd_dual.c
index ffbedfa9bf..fa6add3aab 100644
--- a/source/nsswitch/winbindd_dual.c
+++ b/source/nsswitch/winbindd_dual.c
@@ -35,6 +35,7 @@
#define DBGC_CLASS DBGC_WINBIND
extern BOOL override_logfile;
+extern struct winbindd_methods cache_methods;
/* Read some data from a client connection */
@@ -988,6 +989,16 @@ static BOOL fork_domain_child(struct winbindd_child *child)
child);
}
+ /* Special case for Winbindd on a Samba DC,
+ * We want to make sure the child can connect to smbd
+ * but not the main daemon */
+
+ if (child->domain && child->domain->internal && IS_DC) {
+ child->domain->internal = False;
+ child->domain->methods = &cache_methods;
+ child->domain->online = False;
+ }
+
while (1) {
int ret;
diff --git a/source/nsswitch/winbindd_nss.h b/source/nsswitch/winbindd_nss.h
index 135849ae8f..8f22e158f5 100644
--- a/source/nsswitch/winbindd_nss.h
+++ b/source/nsswitch/winbindd_nss.h
@@ -206,7 +206,7 @@ typedef struct winbindd_gr {
#define WBFLAG_PAM_KRB5 0x1000
#define WBFLAG_PAM_FALLBACK_AFTER_KRB5 0x2000
#define WBFLAG_PAM_CACHED_LOGIN 0x4000
-#define WBFLAG_PAM_GET_PWD_POLICY 0x8000 /* not used */
+#define WBFLAG_PAM_GET_PWD_POLICY 0x8000
#define WINBINDD_MAX_EXTRA_DATA (128*1024)
diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c
index 589f4839e0..e5e55e60f9 100644
--- a/source/nsswitch/winbindd_pam.c
+++ b/source/nsswitch/winbindd_pam.c
@@ -1517,11 +1517,13 @@ process_result:
}
}
- result = fillup_password_policy(domain, state);
+ if (state->request.flags & WBFLAG_PAM_GET_PWD_POLICY) {
+ result = fillup_password_policy(domain, state);
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(10,("Failed to get password policies: %s\n", nt_errstr(result)));
- goto done;
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(10,("Failed to get password policies: %s\n", nt_errstr(result)));
+ goto done;
+ }
}
if (state->request.flags & WBFLAG_PAM_UNIX_NAME) {
diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c
index d2daf7830d..ecd919d6ff 100644
--- a/source/nsswitch/winbindd_util.c
+++ b/source/nsswitch/winbindd_util.c
@@ -83,9 +83,6 @@ static BOOL is_internal_domain(const DOM_SID *sid)
if (sid == NULL)
return False;
- if ( IS_DC )
- return sid_check_is_builtin(sid);
-
return (sid_check_is_domain(sid) || sid_check_is_builtin(sid));
}
@@ -94,9 +91,6 @@ static BOOL is_in_internal_domain(const DOM_SID *sid)
if (sid == NULL)
return False;
- if ( IS_DC )
- return sid_check_is_in_builtin(sid);
-
return (sid_check_is_in_our_domain(sid) || sid_check_is_in_builtin(sid));
}
diff --git a/source/pam_smbpass/pam_smb_acct.c b/source/pam_smbpass/pam_smb_acct.c
index 47bf059479..b5dbd9ca6c 100644
--- a/source/pam_smbpass/pam_smb_acct.c
+++ b/source/pam_smbpass/pam_smb_acct.c
@@ -70,6 +70,11 @@ int pam_sm_acct_mgmt( pam_handle_t *pamh, int flags,
_log_err( LOG_DEBUG, "acct: username [%s] obtained", name );
}
+ if (geteuid() != 0) {
+ _log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root.");
+ return PAM_AUTHINFO_UNAVAIL;
+ }
+
/* Getting into places that might use LDAP -- protect the app
from a SIGPIPE it's not expecting */
oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
diff --git a/source/pam_smbpass/pam_smb_auth.c b/source/pam_smbpass/pam_smb_auth.c
index df6d20e01a..2b0735f2fb 100644
--- a/source/pam_smbpass/pam_smb_auth.c
+++ b/source/pam_smbpass/pam_smb_auth.c
@@ -101,6 +101,12 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
_log_err( LOG_DEBUG, "username [%s] obtained", name );
}
+ if (geteuid() != 0) {
+ _log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root.");
+ retval = PAM_AUTHINFO_UNAVAIL;
+ AUTH_RETURN;
+ }
+
if (!initialize_password_db(True)) {
_log_err( LOG_ALERT, "Cannot access samba password database" );
retval = PAM_AUTHINFO_UNAVAIL;
diff --git a/source/pam_smbpass/pam_smb_passwd.c b/source/pam_smbpass/pam_smb_passwd.c
index 79bcfb6ff0..62c056ba01 100644
--- a/source/pam_smbpass/pam_smb_passwd.c
+++ b/source/pam_smbpass/pam_smb_passwd.c
@@ -125,6 +125,11 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
_log_err( LOG_DEBUG, "username [%s] obtained", user );
}
+ if (geteuid() != 0) {
+ _log_err(pamh, LOG_DEBUG, "Cannot access samba password database, not running as root.");
+ return PAM_AUTHINFO_UNAVAIL;
+ }
+
/* Getting into places that might use LDAP -- protect the app
from a SIGPIPE it's not expecting */
oldsig_handler = CatchSignal(SIGPIPE, SIGNAL_CAST SIG_IGN);
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index be49927cc6..4f44088c8f 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -237,6 +237,8 @@ typedef struct {
int ldap_ssl;
char *szLdapSuffix;
char *szLdapAdminDn;
+ int ldap_debug_level;
+ int ldap_debug_threshold;
int iAclCompat;
char *szCupsServer;
char *szIPrintServer;
@@ -403,6 +405,7 @@ typedef struct {
BOOL bRead_only;
BOOL bNo_set_dir;
BOOL bGuest_only;
+ BOOL bAdministrative_share;
BOOL bGuest_ok;
BOOL bPrint_ok;
BOOL bMap_system;
@@ -545,6 +548,7 @@ static service sDefault = {
True, /* bRead_only */
True, /* bNo_set_dir */
False, /* bGuest_only */
+ False, /* bAdministrative_share */
False, /* bGuest_ok */
False, /* bPrint_ok */
False, /* bMap_system */
@@ -634,6 +638,7 @@ static BOOL handle_netbios_aliases( int snum, const char *pszParmValue, char **p
static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
+static BOOL handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
static void set_server_role(void);
static void set_default_server_announce_type(void);
@@ -935,6 +940,7 @@ static struct parm_struct parm_table[] = {
{"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
+ {"administrative share", P_BOOL, P_LOCAL, &sDefault.bAdministrative_share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
{"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
{"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
@@ -1189,6 +1195,10 @@ static struct parm_struct parm_table[] = {
{"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
{"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
+ {"ldap debug level", P_INTEGER, P_GLOBAL, &Globals.ldap_debug_level, handle_ldap_debug_level, NULL, FLAG_ADVANCED},
+ {"ldap debug threshold", P_INTEGER, P_GLOBAL, &Globals.ldap_debug_threshold, NULL, NULL, FLAG_ADVANCED},
+
+
{N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
{"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
{"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
@@ -1592,6 +1602,9 @@ static void init_globals(BOOL first_time_only)
Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
Globals.ldap_page_size = LDAP_PAGE_SIZE;
+ Globals.ldap_debug_level = 0;
+ Globals.ldap_debug_threshold = 10;
+
/* This is what we tell the afs client. in reality we set the token
* to never expire, though, when this runs out the afs client will
* forget the token. Set to 0 to get NEVERDATE.*/
@@ -1918,6 +1931,8 @@ FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
+FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
+FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
@@ -2081,6 +2096,7 @@ FN_LOCAL_BOOL(lp_readonly, bRead_only)
FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
+FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
@@ -2701,6 +2717,7 @@ static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
ServicePtrs[i]->bAvailable = True;
ServicePtrs[i]->bRead_only = True;
ServicePtrs[i]->bGuest_only = False;
+ ServicePtrs[i]->bAdministrative_share = True;
ServicePtrs[i]->bGuest_ok = guest_ok;
ServicePtrs[i]->bPrint_ok = False;
ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
@@ -3227,6 +3244,13 @@ static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
return (bRetval);
}
+static BOOL handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
+{
+ Globals.ldap_debug_level = lp_int(pszParmValue);
+ init_ldap_debugging();
+ return True;
+}
+
/***************************************************************************
Handle idmap/non unix account uid and gid allocation parameters. The format of these
parameters is:
diff --git a/source/passdb/lookup_sid.c b/source/passdb/lookup_sid.c
index 37285f01d2..d1390fdadb 100644
--- a/source/passdb/lookup_sid.c
+++ b/source/passdb/lookup_sid.c
@@ -60,16 +60,19 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
name = talloc_strdup(tmp_ctx, full_name);
}
- DEBUG(10,("lookup_name: %s => %s (domain), %s (name)\n",
- full_name, domain, name));
-
if ((domain == NULL) || (name == NULL)) {
DEBUG(0, ("talloc failed\n"));
TALLOC_FREE(tmp_ctx);
return False;
}
- if (strequal(domain, get_global_sam_name())) {
+ DEBUG(10,("lookup_name: %s => %s (domain), %s (name)\n",
+ full_name, domain, name));
+ DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
+
+ if ((flags & LOOKUP_NAME_DOMAIN) &&
+ strequal(domain, get_global_sam_name()))
+ {
/* It's our own domain, lookup the name in passdb */
if (lookup_global_sam_name(name, flags, &rid, &type)) {
@@ -81,8 +84,9 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
return False;
}
- if (strequal(domain, builtin_domain_name())) {
-
+ if ((flags & LOOKUP_NAME_BUILTIN) &&
+ strequal(domain, builtin_domain_name()))
+ {
/* Explicit request for a name in BUILTIN */
if (lookup_builtin_name(name, &rid)) {
sid_copy(&sid, &global_sid_Builtin);
@@ -98,6 +102,7 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
* domain yet at this point yet. This comes later. */
if ((domain[0] != '\0') &&
+ (flags & ~(LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED)) &&
(winbind_lookup_name(domain, name, &sid, &type))) {
goto ok;
}
@@ -132,14 +137,18 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
/* 1. well-known names */
- if (lookup_wellknown_name(tmp_ctx, name, &sid, &domain)) {
+ if ((flags & LOOKUP_NAME_WKN) &&
+ lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
+ {
type = SID_NAME_WKN_GRP;
goto ok;
}
/* 2. Builtin domain as such */
- if (strequal(name, builtin_domain_name())) {
+ if ((flags & (LOOKUP_NAME_BUILTIN|LOOKUP_NAME_REMOTE)) &&
+ strequal(name, builtin_domain_name()))
+ {
/* Swap domain and name */
tmp = name; name = domain; domain = tmp;
sid_copy(&sid, &global_sid_Builtin);
@@ -149,7 +158,9 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
/* 3. Account domain */
- if (strequal(name, get_global_sam_name())) {
+ if ((flags & LOOKUP_NAME_DOMAIN) &&
+ strequal(name, get_global_sam_name()))
+ {
if (!secrets_fetch_domain_sid(name, &sid)) {
DEBUG(3, ("Could not fetch my SID\n"));
TALLOC_FREE(tmp_ctx);
@@ -163,7 +174,9 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
/* 4. Primary domain */
- if (!IS_DC && strequal(name, lp_workgroup())) {
+ if ((flags & LOOKUP_NAME_DOMAIN) && !IS_DC &&
+ strequal(name, lp_workgroup()))
+ {
if (!secrets_fetch_domain_sid(name, &sid)) {
DEBUG(3, ("Could not fetch the domain SID\n"));
TALLOC_FREE(tmp_ctx);
@@ -178,8 +191,9 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
/* 5. Trusted domains as such, to me it looks as if members don't do
this, tested an XP workstation in a NT domain -- vl */
- if (IS_DC && (secrets_fetch_trusted_domain_password(name, NULL,
- &sid, NULL))) {
+ if ((flags & LOOKUP_NAME_REMOTE) && IS_DC &&
+ (secrets_fetch_trusted_domain_password(name, NULL, &sid, NULL)))
+ {
/* Swap domain and name */
tmp = name; name = domain; domain = tmp;
type = SID_NAME_DOMAIN;
@@ -188,7 +202,9 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
/* 6. Builtin aliases */
- if (lookup_builtin_name(name, &rid)) {
+ if ((flags & LOOKUP_NAME_BUILTIN) &&
+ lookup_builtin_name(name, &rid))
+ {
domain = talloc_strdup(tmp_ctx, builtin_domain_name());
sid_copy(&sid, &global_sid_Builtin);
sid_append_rid(&sid, rid);
@@ -201,7 +217,9 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
/* Both cases are done by looking at our passdb */
- if (lookup_global_sam_name(name, flags, &rid, &type)) {
+ if ((flags & LOOKUP_NAME_DOMAIN) &&
+ lookup_global_sam_name(name, flags, &rid, &type))
+ {
domain = talloc_strdup(tmp_ctx, get_global_sam_name());
sid_copy(&sid, get_global_sam_sid());
sid_append_rid(&sid, rid);
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index afcb463a63..8c6fa81edb 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -1651,6 +1651,10 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
pdb_get_username(newpwd), ldap_err2string(rc), ld_error?ld_error:"unknown"));
SAFE_FREE(ld_error);
ber_bvfree(bv);
+#if defined(LDAP_CONSTRAINT_VIOLATION)
+ if (rc == LDAP_CONSTRAINT_VIOLATION)
+ return NT_STATUS_PASSWORD_RESTRICTION;
+#endif
return NT_STATUS_UNSUCCESSFUL;
} else {
DEBUG(3,("ldapsam_modify_entry: LDAP Password changed for user %s\n",pdb_get_username(newpwd)));
@@ -2454,7 +2458,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
goto done;
}
- rc = smbldap_search(conn, lp_ldap_user_suffix(),
+ rc = smbldap_search(conn, lp_ldap_suffix(),
LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
&result);
@@ -2510,7 +2514,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
LDAP_OBJ_SAMBASAMACCOUNT,
gidstr);
- rc = smbldap_search(conn, lp_ldap_user_suffix(),
+ rc = smbldap_search(conn, lp_ldap_suffix(),
LDAP_SCOPE_SUBTREE, filter, sid_attrs, 0,
&result);
@@ -2594,7 +2598,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods,
goto done;
}
- rc = smbldap_search(conn, lp_ldap_user_suffix(),
+ rc = smbldap_search(conn, lp_ldap_suffix(),
LDAP_SCOPE_SUBTREE, filter, attrs, 0, &result);
if (rc != LDAP_SUCCESS)
diff --git a/source/passdb/secrets.c b/source/passdb/secrets.c
index 3ac3a93233..cd6c751979 100644
--- a/source/passdb/secrets.c
+++ b/source/passdb/secrets.c
@@ -268,27 +268,19 @@ uint32 get_default_sec_channel(void)
/************************************************************************
Routine to get the trust account password for a domain.
+ This only tries to get the legacy hashed version of the password.
The user of this function must have locked the trust password file using
the above secrets_lock_trust_account_password().
************************************************************************/
-BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
- time_t *pass_last_set_time,
- uint32 *channel)
+BOOL secrets_fetch_trust_account_password_legacy(const char *domain,
+ uint8 ret_pwd[16],
+ time_t *pass_last_set_time,
+ uint32 *channel)
{
struct machine_acct_pass *pass;
- char *plaintext;
size_t size = 0;
- plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
- channel);
- if (plaintext) {
- DEBUG(4,("Using cleartext machine password\n"));
- E_md4hash(plaintext, ret_pwd);
- SAFE_FREE(plaintext);
- return True;
- }
-
if (!(pass = (struct machine_acct_pass *)secrets_fetch(
trust_keystr(domain), &size))) {
DEBUG(5, ("secrets_fetch failed!\n"));
@@ -321,6 +313,32 @@ BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
return True;
}
+/************************************************************************
+ Routine to get the trust account password for a domain.
+ The user of this function must have locked the trust password file using
+ the above secrets_lock_trust_account_password().
+************************************************************************/
+
+BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
+ time_t *pass_last_set_time,
+ uint32 *channel)
+{
+ char *plaintext;
+
+ plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
+ channel);
+ if (plaintext) {
+ DEBUG(4,("Using cleartext machine password\n"));
+ E_md4hash(plaintext, ret_pwd);
+ SAFE_FREE(plaintext);
+ return True;
+ }
+
+ return secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
+ pass_last_set_time,
+ channel);
+}
+
/**
* Pack SID passed by pointer
*
@@ -500,20 +518,6 @@ BOOL secrets_fetch_trusted_domain_password(const char *domain, char** pwd,
return True;
}
-/************************************************************************
- Routine to set the trust account password for a domain.
-************************************************************************/
-
-BOOL secrets_store_trust_account_password(const char *domain, uint8 new_pwd[16])
-{
- struct machine_acct_pass pass;
-
- pass.mod_time = time(NULL);
- memcpy(pass.hash, new_pwd, 16);
-
- return secrets_store(trust_keystr(domain), (void *)&pass, sizeof(pass));
-}
-
/**
* Routine to store the password for trusted domain
*
@@ -655,54 +659,103 @@ char *secrets_fetch_machine_password(const char *domain,
return ret;
}
+BOOL is_trusted_domain_situation(const char *domain_name)
+{
+ return IS_DC &&
+ lp_allow_trusted_domains() &&
+ !strequal(domain_name, lp_workgroup());
+}
+
/*******************************************************************
- Wrapper around retrieving the trust account password
+ Wrapper around retrieving the clear text trust account password.
+ appropriate account name is stored in account_name.
+ Caller must free password, but not account_name.
*******************************************************************/
-
-BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16], uint32 *channel)
+
+BOOL get_trust_pw_clear(const char *domain, char **ret_pwd,
+ const char **account_name, uint32 *channel)
{
- DOM_SID sid;
char *pwd;
time_t last_set_time;
-
+
/* if we are a DC and this is not our domain, then lookup an account
- for the domain trust */
-
- if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() ) {
- if (!secrets_fetch_trusted_domain_password(domain, &pwd, &sid,
- &last_set_time)) {
+ * for the domain trust */
+
+ if (is_trusted_domain_situation(domain)) {
+ if (!secrets_fetch_trusted_domain_password(domain, ret_pwd,
+ NULL, &last_set_time))
+ {
DEBUG(0, ("get_trust_pw: could not fetch trust "
"account password for trusted domain %s\n",
domain));
return False;
}
-
- *channel = SEC_CHAN_DOMAIN;
- E_md4hash(pwd, ret_pwd);
- SAFE_FREE(pwd);
+
+ if (channel != NULL) {
+ *channel = SEC_CHAN_DOMAIN;
+ }
+
+ if (account_name != NULL) {
+ *account_name = lp_workgroup();
+ }
return True;
}
-
+
/* Just get the account for the requested domain. In the future this
* might also cover to be member of more than one domain. */
-
- if (secrets_fetch_trust_account_password(domain, ret_pwd,
- &last_set_time, channel))
+
+ pwd = secrets_fetch_machine_password(domain, &last_set_time, channel);
+
+ if (pwd != NULL) {
+ *ret_pwd = pwd;
+ if (account_name != NULL) {
+ *account_name = global_myname();
+ }
+
return True;
+ }
- DEBUG(5, ("get_trust_pw: could not fetch trust account "
- "password for domain %s\n", domain));
+ DEBUG(5, ("get_trust_pw_clear: could not fetch clear text trust "
+ "account password for domain %s\n", domain));
return False;
}
-/************************************************************************
- Routine to delete the machine trust account password file for a domain.
-************************************************************************/
+/*******************************************************************
+ Wrapper around retrieving the trust account password.
+ appropriate account name is stored in account_name.
+*******************************************************************/
-BOOL trust_password_delete(const char *domain)
+BOOL get_trust_pw_hash(const char *domain, uint8 ret_pwd[16],
+ const char **account_name, uint32 *channel)
{
- return secrets_delete(trust_keystr(domain));
+ char *pwd = NULL;
+ time_t last_set_time;
+
+ if (get_trust_pw_clear(domain, &pwd, account_name, channel)) {
+ E_md4hash(pwd, ret_pwd);
+ SAFE_FREE(pwd);
+ return True;
+ } else if (is_trusted_domain_situation(domain)) {
+ return False;
+ }
+
+ /* as a fallback, try to get the hashed pwd directly from the tdb... */
+
+ if (secrets_fetch_trust_account_password_legacy(domain, ret_pwd,
+ &last_set_time,
+ channel))
+ {
+ if (account_name != NULL) {
+ *account_name = global_myname();
+ }
+
+ return True;
+ }
+
+ DEBUG(5, ("get_trust_pw_hash: could not fetch trust account "
+ "password for domain %s\n", domain));
+ return False;
}
/************************************************************************
diff --git a/source/python/py_samr.c b/source/python/py_samr.c
index fced5b3ddd..e2600bc3f6 100644
--- a/source/python/py_samr.c
+++ b/source/python/py_samr.c
@@ -463,7 +463,7 @@ static PyObject *samr_create_dom_user(PyObject *self, PyObject *args,
static char *kwlist[] = { "account_name", "acb_info", NULL };
char *account_name;
NTSTATUS ntstatus;
- uint32 unknown = 0xe005000b; /* Access mask? */
+ uint32 acct_flags = 0;
uint32 user_rid;
PyObject *result = NULL;
TALLOC_CTX *mem_ctx;
@@ -479,9 +479,14 @@ static PyObject *samr_create_dom_user(PyObject *self, PyObject *args,
return NULL;
}
+ acct_flags = SAMR_GENERIC_READ | SAMR_GENERIC_WRITE |
+ SAMR_GENERIC_EXECUTE | SAMR_STANDARD_WRITEDAC |
+ SAMR_STANDARD_DELETE | SAMR_USER_SETPASS | SAMR_USER_GETATTR |
+ SAMR_USER_SETATTR;
+ DEBUG(10, ("Creating account with flags: %d\n",acct_flags));
ntstatus = rpccli_samr_create_dom_user(
domain_hnd->cli, mem_ctx, &domain_hnd->domain_pol,
- account_name, acb_info, unknown, &user_pol, &user_rid);
+ account_name, acb_info, acct_flags, &user_pol, &user_rid);
if (!NT_STATUS_IS_OK(ntstatus)) {
PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c
index 61f5ee51bd..43c3044ce4 100644
--- a/source/rpc_client/cli_pipe.c
+++ b/source/rpc_client/cli_pipe.c
@@ -1806,6 +1806,7 @@ static NTSTATUS rpc_finish_auth3_bind(struct rpc_pipe_client *cli,
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0,("rpc_finish_auth3_bind: NTLMSSP update using server blob failed.\n"));
+ data_blob_free(&server_response);
return nt_status;
}
@@ -2363,8 +2364,8 @@ static struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_internal(struct cli_sta
goto err;
}
- DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to machine %s and"
- "bound NTLMSSP as user %s\\%s.\n",
+ DEBUG(10,("cli_rpc_pipe_open_ntlmssp_internal: opened pipe %s to "
+ "machine %s and bound NTLMSSP as user %s\\%s.\n",
result->pipe_name, cli->desthost,
domain, username ));
@@ -2423,49 +2424,29 @@ struct rpc_pipe_client *cli_rpc_pipe_open_spnego_ntlmssp(struct cli_state *cli,
}
/****************************************************************************
- Open a netlogon pipe and get the schannel session key.
- Now exposed to external callers.
+ Get a the schannel session key out of an already opened netlogon pipe.
****************************************************************************/
-
-struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
- const char *domain,
- uint32 *pneg_flags,
- NTSTATUS *perr)
+static BOOL get_schannel_session_key_common(struct rpc_pipe_client *netlogon_pipe,
+ struct cli_state *cli,
+ const char *domain,
+ uint32 *pneg_flags,
+ NTSTATUS *perr)
{
- struct rpc_pipe_client *netlogon_pipe = NULL;
uint32 sec_chan_type = 0;
unsigned char machine_pwd[16];
- fstring machine_account;
-
- netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
- if (!netlogon_pipe) {
- return NULL;
- }
+ const char *machine_account;
/* Get the machine account credentials from secrets.tdb. */
- if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) {
+ if (!get_trust_pw_hash(domain, machine_pwd, &machine_account,
+ &sec_chan_type))
+ {
DEBUG(0, ("get_schannel_session_key: could not fetch "
"trust account password for domain '%s'\n",
domain));
- cli_rpc_pipe_close(netlogon_pipe);
*perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- return NULL;
+ return False;
}
- /* A DC should use DOMAIN$ as its account name.
- A member server can only use it's machine name since it
- does not have an account in a trusted domain.
-
- We don't check the domain against lp_workgroup() here since
- 'net ads join' has to continue to work with only the realm
- specified in smb.conf. -- jerry */
-
- if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains()) {
- fstrcpy( machine_account, lp_workgroup() );
- } else {
- fstrcpy(machine_account, global_myname());
- }
-
*perr = rpccli_netlogon_setup_creds(netlogon_pipe,
cli->desthost, /* server name */
domain, /* domain */
@@ -2476,18 +2457,44 @@ struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
pneg_flags);
if (!NT_STATUS_IS_OK(*perr)) {
- DEBUG(3,("get_schannel_session_key: rpccli_netlogon_setup_creds "
+ DEBUG(3,("get_schannel_session_key_common: rpccli_netlogon_setup_creds "
"failed with result %s to server %s, domain %s, machine account %s.\n",
nt_errstr(*perr), cli->desthost, domain, machine_account ));
- cli_rpc_pipe_close(netlogon_pipe);
- return NULL;
+ return False;
}
if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
DEBUG(3, ("get_schannel_session_key: Server %s did not offer schannel\n",
cli->desthost));
- cli_rpc_pipe_close(netlogon_pipe);
*perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+ Open a netlogon pipe and get the schannel session key.
+ Now exposed to external callers.
+ ****************************************************************************/
+
+
+struct rpc_pipe_client *get_schannel_session_key(struct cli_state *cli,
+ const char *domain,
+ uint32 *pneg_flags,
+ NTSTATUS *perr)
+{
+ struct rpc_pipe_client *netlogon_pipe = NULL;
+
+ netlogon_pipe = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, perr);
+ if (!netlogon_pipe) {
+ return NULL;
+ }
+
+ if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
+ pneg_flags, perr))
+ {
+ cli_rpc_pipe_close(netlogon_pipe);
return NULL;
}
@@ -2559,61 +2566,16 @@ static struct rpc_pipe_client *get_schannel_session_key_auth_ntlmssp(struct cli_
NTSTATUS *perr)
{
struct rpc_pipe_client *netlogon_pipe = NULL;
- uint32 sec_chan_type = 0;
- unsigned char machine_pwd[16];
- fstring machine_account;
netlogon_pipe = cli_rpc_pipe_open_spnego_ntlmssp(cli, PI_NETLOGON, PIPE_AUTH_LEVEL_PRIVACY, domain, username, password, perr);
if (!netlogon_pipe) {
return NULL;
}
- /* Get the machine account credentials from secrets.tdb. */
- if (!get_trust_pw(domain, machine_pwd, &sec_chan_type)) {
- DEBUG(0, ("get_schannel_session_key_auth_ntlmssp: could not fetch "
- "trust account password for domain '%s'\n",
- domain));
- cli_rpc_pipe_close(netlogon_pipe);
- *perr = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
- return NULL;
- }
-
- /* if we are a DC and this is a trusted domain, then we need to use our
- domain name in the net_req_auth2() request */
-
- if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains()) {
- fstrcpy( machine_account, lp_workgroup() );
- } else {
- /* Hmmm. Is this correct for trusted domains when we're a member server ? JRA. */
- if (strequal(domain, lp_workgroup())) {
- fstrcpy(machine_account, global_myname());
- } else {
- fstrcpy(machine_account, domain);
- }
- }
-
- *perr = rpccli_netlogon_setup_creds(netlogon_pipe,
- cli->desthost, /* server name */
- domain, /* domain */
- global_myname(), /* client name */
- machine_account, /* machine account name */
- machine_pwd,
- sec_chan_type,
- pneg_flags);
-
- if (!NT_STATUS_IS_OK(*perr)) {
- DEBUG(3,("get_schannel_session_key_auth_ntlmssp: rpccli_netlogon_setup_creds "
- "failed with result %s\n",
- nt_errstr(*perr) ));
- cli_rpc_pipe_close(netlogon_pipe);
- return NULL;
- }
-
- if (((*pneg_flags) & NETLOGON_NEG_SCHANNEL) == 0) {
- DEBUG(3, ("get_schannel_session_key_auth_ntlmssp: Server %s did not offer schannel\n",
- cli->desthost));
+ if (!get_schannel_session_key_common(netlogon_pipe, cli, domain,
+ pneg_flags, perr))
+ {
cli_rpc_pipe_close(netlogon_pipe);
- *perr = NT_STATUS_INVALID_NETWORK_RESPONSE;
return NULL;
}
@@ -2634,7 +2596,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_ntlmssp_auth_schannel(struct cli_state
const char *password,
NTSTATUS *perr)
{
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
struct rpc_pipe_client *netlogon_pipe = NULL;
struct rpc_pipe_client *result = NULL;
@@ -2668,7 +2630,7 @@ struct rpc_pipe_client *cli_rpc_pipe_open_schannel(struct cli_state *cli,
const char *domain,
NTSTATUS *perr)
{
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
struct rpc_pipe_client *netlogon_pipe = NULL;
struct rpc_pipe_client *result = NULL;
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index 4410348abe..d452c1fe82 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -5182,7 +5182,7 @@ reads or writes a structure.
void init_samr_q_create_user(SAMR_Q_CREATE_USER * q_u,
POLICY_HND *pol,
const char *name,
- uint32 acb_info, uint32 access_mask)
+ uint32 acb_info, uint32 acct_flags)
{
DEBUG(5, ("samr_init_samr_q_create_user\n"));
@@ -5192,7 +5192,7 @@ void init_samr_q_create_user(SAMR_Q_CREATE_USER * q_u,
init_uni_hdr(&q_u->hdr_name, &q_u->uni_name);
q_u->acb_info = acb_info;
- q_u->access_mask = access_mask;
+ q_u->acct_flags = acct_flags;
}
/*******************************************************************
@@ -5223,7 +5223,7 @@ BOOL samr_io_q_create_user(const char *desc, SAMR_Q_CREATE_USER * q_u,
return False;
if(!prs_uint32("acb_info ", ps, depth, &q_u->acb_info))
return False;
- if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
+ if(!prs_uint32("acct_flags", ps, depth, &q_u->acct_flags))
return False;
return True;
@@ -5870,6 +5870,25 @@ void init_sam_user_info23A(SAM_USER_INFO_23 * usr, NTTIME * logon_time, /* all z
}
}
+
+/*************************************************************************
+ init_samr_user_info25P
+ fields_present = ACCT_NT_PWD_SET | ACCT_LM_PWD_SET | ACCT_FLAGS
+*************************************************************************/
+
+void init_sam_user_info25P(SAM_USER_INFO_25 * usr,
+ uint32 fields_present, uint32 acb_info,
+ char newpass[532])
+{
+ usr->fields_present = fields_present;
+ ZERO_STRUCT(usr->padding1);
+ ZERO_STRUCT(usr->padding2);
+
+ usr->acb_info = acb_info;
+ memcpy(usr->pass, newpass, sizeof(usr->pass));
+}
+
+
/*******************************************************************
reads or writes a structure.
********************************************************************/
diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c
index 7a47cedf4a..c105edf19d 100644
--- a/source/rpc_server/srv_lsa_nt.c
+++ b/source/rpc_server/srv_lsa_nt.c
@@ -1032,6 +1032,31 @@ NTSTATUS _lsa_lookup_sids3(pipes_struct *p,
return r_u->status;
}
+static int lsa_lookup_level_to_flags(uint16 level)
+{
+ int flags;
+
+ switch (level) {
+ case 1:
+ flags = LOOKUP_NAME_ALL;
+ break;
+ case 2:
+ flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
+ break;
+ case 3:
+ flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
+ break;
+ case 4:
+ case 5:
+ case 6:
+ default:
+ flags = LOOKUP_NAME_NONE;
+ break;
+ }
+
+ return flags;
+}
+
/***************************************************************************
lsa_reply_lookup_names
***************************************************************************/
@@ -1051,10 +1076,7 @@ NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP
DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries));
}
- /* Probably the lookup_level is some sort of bitmask. */
- if (q_u->lookup_level == 1) {
- flags = LOOKUP_NAME_ALL;
- }
+ flags = lsa_lookup_level_to_flags(q_u->lookup_level);
ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
if (!ref) {
@@ -1120,11 +1142,8 @@ NTSTATUS _lsa_lookup_names2(pipes_struct *p, LSA_Q_LOOKUP_NAMES2 *q_u, LSA_R_LOO
num_entries = MAX_LOOKUP_SIDS;
DEBUG(5,("_lsa_lookup_names2: truncating name lookup list to %d\n", num_entries));
}
-
- /* Probably the lookup_level is some sort of bitmask. */
- if (q_u->lookup_level == 1) {
- flags = LOOKUP_NAME_ALL;
- }
+
+ flags = lsa_lookup_level_to_flags(q_u->lookup_level);
ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
if (ref == NULL) {
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index 3343f16f35..cc289cad05 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -2507,9 +2507,9 @@ static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
become_root();
- /* Lookup in our local databases (only LOOKUP_NAME_ISOLATED set)
+ /* Lookup in our local databases (LOOKUP_NAME_REMOTE not set)
* whether the name already exists */
- result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_ISOLATED,
+ result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_LOCAL,
NULL, NULL, NULL, &type);
unbecome_root();
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index 4cf43f04e4..0bc7a39dd0 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -1403,8 +1403,8 @@ static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode)
len = unistrlen(devmode->formname.buffer);
if (len != -1) {
- d->devicename.buffer = TALLOC_ARRAY(ctx, uint16, len);
- if (!d->devicename.buffer) {
+ d->formname.buffer = TALLOC_ARRAY(ctx, uint16, len);
+ if (!d->formname.buffer) {
return NULL;
}
if (unistrcpy(d->formname.buffer, devmode->formname.buffer) != len)
diff --git a/source/rpc_server/srv_srvsvc_nt.c b/source/rpc_server/srv_srvsvc_nt.c
index d03ab66b50..173979f8c6 100644
--- a/source/rpc_server/srv_srvsvc_nt.c
+++ b/source/rpc_server/srv_srvsvc_nt.c
@@ -203,9 +203,6 @@ static WERROR net_enum_files( TALLOC_CTX *ctx, FILE_INFO_3 **info,
********************************************************************/
static uint32 get_share_type(int snum)
{
- char *net_name = lp_servicename(snum);
- int len_net_name = strlen(net_name);
-
/* work out the share type */
uint32 type = STYPE_DISKTREE;
@@ -213,7 +210,7 @@ static uint32 get_share_type(int snum)
type = STYPE_PRINTQ;
if (strequal(lp_fstype(snum), "IPC"))
type = STYPE_IPC;
- if (net_name[len_net_name-1] == '$')
+ if (lp_administrative_share(snum))
type |= STYPE_HIDDEN;
return type;
diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c
index dd55e65fb9..8487d2b8c7 100644
--- a/source/rpcclient/cmd_samr.c
+++ b/source/rpcclient/cmd_samr.c
@@ -1450,7 +1450,7 @@ static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
const char *acct_name;
uint32 acb_info;
- uint32 unknown, user_rid;
+ uint32 acct_flags, user_rid;
uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
if ((argc < 2) || (argc > 3)) {
@@ -1483,10 +1483,13 @@ static NTSTATUS cmd_samr_create_dom_user(struct rpc_pipe_client *cli,
/* Create domain user */
acb_info = ACB_NORMAL;
- unknown = 0xe005000b; /* No idea what this is - a permission mask? */
-
+ acct_flags = SAMR_GENERIC_READ | SAMR_GENERIC_WRITE |
+ SAMR_GENERIC_EXECUTE | SAMR_STANDARD_WRITEDAC |
+ SAMR_STANDARD_DELETE | SAMR_USER_SETPASS | SAMR_USER_GETATTR |
+ SAMR_USER_SETATTR;
+ DEBUG(10, ("Creating account with flags: %d\n",acct_flags));
result = rpccli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
- acct_name, acb_info, unknown,
+ acct_name, acb_info, acct_flags,
&user_pol, &user_rid);
if (!NT_STATUS_IS_OK(result))
diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c
index f671e892a0..0f7ff63aa0 100644
--- a/source/rpcclient/rpcclient.c
+++ b/source/rpcclient/rpcclient.c
@@ -568,7 +568,7 @@ static NTSTATUS do_cmd(struct cli_state *cli,
}
if (cmd_entry->pipe_idx == PI_NETLOGON) {
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS;
uint32 sec_channel_type;
uchar trust_password[16];
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
index 7c6886b81c..2a4d96598b 100644
--- a/source/smbd/chgpasswd.c
+++ b/source/smbd/chgpasswd.c
@@ -126,6 +126,7 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass,
struct termios stermios;
gid_t gid;
uid_t uid;
+ char * const eptrs[1] = { NULL };
if (pass == NULL)
{
@@ -153,19 +154,19 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass,
DEBUG(3, ("More weirdness, could not open %s\n", slavedev));
return (False);
}
-#if defined(I_PUSH) && defined(I_FIND)
+#if defined(TIOCSCTTY)
+ if (ioctl(slave, TIOCSCTTY, 0) < 0)
+ {
+ DEBUG(3, ("Error in ioctl call for slave pty\n"));
+ /* return(False); */
+ }
+#elif defined(I_PUSH) && defined(I_FIND)
if (ioctl(slave, I_FIND, "ptem") == 0) {
ioctl(slave, I_PUSH, "ptem");
}
if (ioctl(slave, I_FIND, "ldterm") == 0) {
ioctl(slave, I_PUSH, "ldterm");
}
-#elif defined(TIOCSCTTY)
- if (ioctl(slave, TIOCSCTTY, 0) < 0)
- {
- DEBUG(3, ("Error in ioctl call for slave pty\n"));
- /* return(False); */
- }
#endif
/* Close master. */
@@ -222,7 +223,7 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass,
passwordprogram));
/* execl() password-change application */
- if (execl("/bin/sh", "sh", "-c", passwordprogram, NULL) < 0)
+ if (execle("/bin/sh", "sh", "-c", passwordprogram, NULL, eptrs) < 0)
{
DEBUG(3, ("Bad status returned from %s\n", passwordprogram));
return (False);
@@ -498,6 +499,9 @@ BOOL chgpasswd(const char *name, const struct passwd *pass,
#ifdef WITH_PAM
if (lp_pam_password_change()) {
BOOL ret;
+#ifdef HAVE_SETLOCALE
+ char *prevlocale = setlocale(LC_ALL, "C");
+#endif
if (as_root)
become_root();
@@ -511,6 +515,10 @@ BOOL chgpasswd(const char *name, const struct passwd *pass,
if (as_root)
unbecome_root();
+#ifdef HAVE_SETLOCALE
+ setlocale(LC_ALL, prevlocale);
+#endif
+
return ret;
}
#endif
diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c
index 71d4fa179d..28d8a77a96 100644
--- a/source/smbd/dosmode.c
+++ b/source/smbd/dosmode.c
@@ -438,12 +438,19 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
dosmode &= SAMBA_ATTRIBUTES_MASK;
DEBUG(10,("file_set_dosmode: setting dos mode 0x%x on file %s\n", dosmode, fname));
- if (!st || (st && !VALID_STAT(*st))) {
+
+ if (st == NULL) {
+ SET_STAT_INVALID(st1);
st = &st1;
+ }
+
+ if (!VALID_STAT(*st)) {
if (SMB_VFS_STAT(conn,fname,st))
return(-1);
}
+ unixmode = st->st_mode;
+
get_acl_group_bits(conn, fname, &st->st_mode);
if (S_ISDIR(st->st_mode))
@@ -451,11 +458,14 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
else
dosmode &= ~aDIR;
- if (dos_mode(conn,fname,st) == dosmode)
+ if (dos_mode(conn,fname,st) == dosmode) {
+ st->st_mode = unixmode;
return(0);
+ }
/* Store the DOS attributes in an EA by preference. */
if (set_ea_dos_attribute(conn, fname, st, dosmode)) {
+ st->st_mode = unixmode;
return 0;
}
@@ -494,6 +504,7 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
if ((ret = SMB_VFS_CHMOD(conn,fname,unixmode)) == 0) {
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
+ st->st_mode = unixmode;
return 0;
}
@@ -526,6 +537,9 @@ int file_set_dosmode(connection_struct *conn, const char *fname,
close_file_fchmod(fsp);
notify_fname(conn, NOTIFY_ACTION_MODIFIED,
FILE_NOTIFY_CHANGE_ATTRIBUTES, fname);
+ if (ret == 0) {
+ st->st_mode = unixmode;
+ }
}
return( ret );
diff --git a/source/smbd/notify.c b/source/smbd/notify.c
index df9d8ad137..6e244663f2 100644
--- a/source/smbd/notify.c
+++ b/source/smbd/notify.c
@@ -66,6 +66,8 @@ static BOOL notify_marshall_changes(int num_changes,
int i;
UNISTR uni_name;
+ uni_name.buffer = NULL;
+
for (i=0; i<num_changes; i++) {
struct notify_change *c;
size_t namelen;
diff --git a/source/smbd/notify_inotify.c b/source/smbd/notify_inotify.c
index 1b1bad7e96..a9eb221cb9 100644
--- a/source/smbd/notify_inotify.c
+++ b/source/smbd/notify_inotify.c
@@ -30,10 +30,12 @@
#include <asm/types.h>
#endif
+#ifndef HAVE_INOTIFY_INIT
+
#include <linux/inotify.h>
#include <asm/unistd.h>
-#ifndef HAVE_INOTIFY_INIT
+
/*
glibc doesn't define these functions yet (as of March 2006)
*/
@@ -51,6 +53,10 @@ static int inotify_rm_watch(int fd, int wd)
{
return syscall(__NR_inotify_rm_watch, fd, wd);
}
+#else
+
+#include <sys/inotify.h>
+
#endif
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 0fa11a56c8..69551405bf 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -1375,7 +1375,7 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
}
#endif /* O_SYNC */
- if (posix_open & (access_mask & FILE_APPEND_DATA)) {
+ if (posix_open && (access_mask & FILE_APPEND_DATA)) {
flags2 |= O_APPEND;
}
@@ -1818,9 +1818,15 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
if (lp_map_archive(SNUM(conn)) ||
lp_store_dos_attributes(SNUM(conn))) {
if (!posix_open) {
- file_set_dosmode(conn, fname,
- new_dos_attributes | aARCH, NULL,
- parent_dir);
+ SMB_STRUCT_STAT tmp_sbuf;
+ SET_STAT_INVALID(tmp_sbuf);
+ if (file_set_dosmode(
+ conn, fname,
+ new_dos_attributes | aARCH,
+ &tmp_sbuf,
+ parent_dir) == 0) {
+ unx_mode = tmp_sbuf.st_mode;
+ }
}
}
}
diff --git a/source/smbd/password.c b/source/smbd/password.c
index bf4e9258ff..a617d3c5b1 100644
--- a/source/smbd/password.c
+++ b/source/smbd/password.c
@@ -91,11 +91,15 @@ void invalidate_vuid(uint16 vuid)
if (vuser == NULL)
return;
-
+
SAFE_FREE(vuser->homedir);
SAFE_FREE(vuser->unix_homedir);
SAFE_FREE(vuser->logon_script);
-
+
+ if (vuser->auth_ntlmssp_state) {
+ auth_ntlmssp_end(&vuser->auth_ntlmssp_state);
+ }
+
session_yield(vuser);
SAFE_FREE(vuser->session_keystr);
@@ -116,6 +120,23 @@ void invalidate_vuid(uint16 vuid)
num_validated_vuids--;
}
+void invalidate_intermediate_vuid(uint16 vuid)
+{
+ user_struct *vuser = get_partial_auth_user_struct(vuid);
+
+ if (vuser == NULL)
+ return;
+
+ if (vuser->auth_ntlmssp_state) {
+ auth_ntlmssp_end(&vuser->auth_ntlmssp_state);
+ }
+
+ DLIST_REMOVE(validated_users, vuser);
+
+ SAFE_FREE(vuser);
+ num_validated_vuids--;
+}
+
/****************************************************************************
Invalidate all vuid entries for this process.
****************************************************************************/
@@ -163,19 +184,22 @@ int register_vuid(auth_serversupplied_info *server_info,
/* Limit allowed vuids to 16bits - VUID_OFFSET. */
if (num_validated_vuids >= 0xFFFF-VUID_OFFSET) {
data_blob_free(&session_key);
+ TALLOC_FREE(server_info);
return UID_FIELD_INVALID;
}
if((vuser = SMB_MALLOC_P(user_struct)) == NULL) {
DEBUG(0,("Failed to malloc users struct!\n"));
data_blob_free(&session_key);
+ TALLOC_FREE(server_info);
return UID_FIELD_INVALID;
}
ZERO_STRUCTP(vuser);
/* Allocate a free vuid. Yes this is a linear search... :-) */
- while( get_valid_user_struct(next_vuid) != NULL ) {
+ while( (get_valid_user_struct(next_vuid) != NULL)
+ || (get_partial_auth_user_struct(next_vuid) != NULL) ) {
next_vuid++;
/* Check for vuid wrap. */
if (next_vuid == UID_FIELD_INVALID)
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index 1088e8ebfb..f40a344124 100644
--- a/source/smbd/posix_acls.c
+++ b/source/smbd/posix_acls.c
@@ -1336,12 +1336,12 @@ static BOOL create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst,
psa1->flags |= (psa2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT));
psa2->flags &= ~(SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT);
-
+
} else if (psa2->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
psa2->flags |= (psa1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT));
psa1->flags &= ~(SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT);
-
+
}
}
}
@@ -1402,10 +1402,22 @@ static BOOL create_canon_ace_lists(files_struct *fsp, SMB_STRUCT_STAT *pst,
} else if (sid_to_uid( &current_ace->trustee, &current_ace->unix_ug.uid)) {
current_ace->owner_type = UID_ACE;
- current_ace->type = SMB_ACL_USER;
+ /* If it's the owning user, this is a user_obj, not
+ * a user. */
+ if (current_ace->unix_ug.uid == pst->st_uid) {
+ current_ace->type = SMB_ACL_USER_OBJ;
+ } else {
+ current_ace->type = SMB_ACL_USER;
+ }
} else if (sid_to_gid( &current_ace->trustee, &current_ace->unix_ug.gid)) {
current_ace->owner_type = GID_ACE;
- current_ace->type = SMB_ACL_GROUP;
+ /* If it's the primary group, this is a group_obj, not
+ * a group. */
+ if (current_ace->unix_ug.gid == pst->st_gid) {
+ current_ace->type = SMB_ACL_GROUP_OBJ;
+ } else {
+ current_ace->type = SMB_ACL_GROUP;
+ }
} else {
fstring str;
@@ -3099,57 +3111,8 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
return ret;
}
-static NTSTATUS append_ugw_ace(files_struct *fsp,
- SMB_STRUCT_STAT *psbuf,
- mode_t unx_mode,
- int ugw,
- SEC_ACE *se)
-{
- mode_t perms;
- SEC_ACCESS acc;
- int nt_acl_type; /* Tru64 has "acl_type" as a macro.. */
- DOM_SID trustee;
-
- switch (ugw) {
- case S_IRUSR:
- perms = unix_perms_to_acl_perms(unx_mode,
- S_IRUSR,
- S_IWUSR,
- S_IXUSR);
- uid_to_sid(&trustee, psbuf->st_uid );
- break;
- case S_IRGRP:
- perms = unix_perms_to_acl_perms(unx_mode,
- S_IRGRP,
- S_IWGRP,
- S_IXGRP);
- gid_to_sid(&trustee, psbuf->st_gid );
- break;
- case S_IROTH:
- perms = unix_perms_to_acl_perms(unx_mode,
- S_IROTH,
- S_IWOTH,
- S_IXOTH);
- sid_copy(&trustee, &global_sid_World);
- break;
- default:
- return NT_STATUS_INVALID_PARAMETER;
- }
- acc = map_canon_ace_perms(SNUM(fsp->conn),
- &nt_acl_type,
- perms,
- fsp->is_directory);
-
- init_sec_ace(se,
- &trustee,
- nt_acl_type,
- acc,
- 0);
- return NT_STATUS_OK;
-}
-
/****************************************************************************
- If this is an
+ Take care of parent ACL inheritance.
****************************************************************************/
static NTSTATUS append_parent_acl(files_struct *fsp,
@@ -3168,7 +3131,7 @@ static NTSTATUS append_parent_acl(files_struct *fsp,
int info;
size_t sd_size;
unsigned int i, j;
- mode_t unx_mode;
+ BOOL is_dacl_protected = (psd->type & SE_DESC_DACL_PROTECTED);
ZERO_STRUCT(sbuf);
@@ -3183,12 +3146,6 @@ static NTSTATUS append_parent_acl(files_struct *fsp,
return NT_STATUS_NO_MEMORY;
}
- /* Create a default mode for u/g/w. */
- unx_mode = unix_mode(fsp->conn,
- aARCH | (fsp->is_directory ? aDIR : 0),
- fsp->fsp_name,
- parent_name);
-
status = open_directory(fsp->conn,
parent_name,
&sbuf,
@@ -3213,22 +3170,25 @@ static NTSTATUS append_parent_acl(files_struct *fsp,
return NT_STATUS_ACCESS_DENIED;
}
- /*
+ /*
* Make room for potentially all the ACLs from
- * the parent, plus the user/group/other triple.
+ * the parent. We used to add the ugw triple here,
+ * as we knew we were dealing with POSIX ACLs.
+ * We no longer need to do so as we can guarentee
+ * that a default ACL from the parent directory will
+ * be well formed for POSIX ACLs if it came from a
+ * POSIX ACL source, and if we're not writing to a
+ * POSIX ACL sink then we don't care if it's not well
+ * formed. JRA.
*/
- num_aces += parent_sd->dacl->num_aces + 3;
+ num_aces += parent_sd->dacl->num_aces;
if((new_ace = TALLOC_ZERO_ARRAY(mem_ctx, SEC_ACE,
num_aces)) == NULL) {
return NT_STATUS_NO_MEMORY;
}
- DEBUG(10,("append_parent_acl: parent ACL has %u entries. New "
- "ACL has %u entries\n",
- parent_sd->dacl->num_aces, num_aces ));
-
/* Start by copying in all the given ACE entries. */
for (i = 0; i < psd->dacl->num_aces; i++) {
sec_ace_copy(&new_ace[i], &psd->dacl->aces[i]);
@@ -3239,49 +3199,97 @@ static NTSTATUS append_parent_acl(files_struct *fsp,
* as that really only applies to newly created files. JRA.
*/
- /*
- * Append u/g/w.
- */
-
- status = append_ugw_ace(fsp, psbuf, unx_mode, S_IRUSR, &new_ace[i++]);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- status = append_ugw_ace(fsp, psbuf, unx_mode, S_IRGRP, &new_ace[i++]);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- status = append_ugw_ace(fsp, psbuf, unx_mode, S_IROTH, &new_ace[i++]);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
/* Finally append any inherited ACEs. */
for (j = 0; j < parent_sd->dacl->num_aces; j++) {
SEC_ACE *se = &parent_sd->dacl->aces[j];
- uint32 i_flags = se->flags & (SEC_ACE_FLAG_OBJECT_INHERIT|
- SEC_ACE_FLAG_CONTAINER_INHERIT|
- SEC_ACE_FLAG_INHERIT_ONLY);
if (fsp->is_directory) {
- if (i_flags == SEC_ACE_FLAG_OBJECT_INHERIT) {
- /* Should only apply to a file - ignore. */
+ if (!(se->flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
+ /* Doesn't apply to a directory - ignore. */
+ DEBUG(10,("append_parent_acl: directory %s "
+ "ignoring non container "
+ "inherit flags %u on ACE with sid %s "
+ "from parent %s\n",
+ fsp->fsp_name,
+ (unsigned int)se->flags,
+ sid_string_static(&se->trustee),
+ parent_name));
continue;
}
} else {
- if ((i_flags & (SEC_ACE_FLAG_OBJECT_INHERIT|
- SEC_ACE_FLAG_INHERIT_ONLY)) !=
- SEC_ACE_FLAG_OBJECT_INHERIT) {
- /* Should not apply to a file - ignore. */
+ if (!(se->flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
+ /* Doesn't apply to a file - ignore. */
+ DEBUG(10,("append_parent_acl: file %s "
+ "ignoring non object "
+ "inherit flags %u on ACE with sid %s "
+ "from parent %s\n",
+ fsp->fsp_name,
+ (unsigned int)se->flags,
+ sid_string_static(&se->trustee),
+ parent_name));
continue;
}
}
+
+ if (is_dacl_protected) {
+ /* If the DACL is protected it means we must
+ * not overwrite an existing ACE entry with the
+ * same SID. This is order N^2. Ouch :-(. JRA. */
+ unsigned int k;
+ for (k = 0; k < psd->dacl->num_aces; k++) {
+ if (sid_equal(&psd->dacl->aces[k].trustee,
+ &se->trustee)) {
+ break;
+ }
+ }
+ if (k < psd->dacl->num_aces) {
+ /* SID matched. Ignore. */
+ DEBUG(10,("append_parent_acl: path %s "
+ "ignoring ACE with protected sid %s "
+ "from parent %s\n",
+ fsp->fsp_name,
+ sid_string_static(&se->trustee),
+ parent_name));
+ continue;
+ }
+ }
+
sec_ace_copy(&new_ace[i], se);
if (se->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
new_ace[i].flags &= ~(SEC_ACE_FLAG_VALID_INHERIT);
}
new_ace[i].flags |= SEC_ACE_FLAG_INHERITED_ACE;
+
+ if (fsp->is_directory) {
+ /*
+ * Strip off any inherit only. It's applied.
+ */
+ new_ace[i].flags &= ~(SEC_ACE_FLAG_INHERIT_ONLY);
+ if (se->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
+ /* No further inheritance. */
+ new_ace[i].flags &=
+ ~(SEC_ACE_FLAG_CONTAINER_INHERIT|
+ SEC_ACE_FLAG_OBJECT_INHERIT);
+ }
+ } else {
+ /*
+ * Strip off any container or inherit
+ * flags, they can't apply to objects.
+ */
+ new_ace[i].flags &= ~(SEC_ACE_FLAG_CONTAINER_INHERIT|
+ SEC_ACE_FLAG_INHERIT_ONLY|
+ SEC_ACE_FLAG_NO_PROPAGATE_INHERIT);
+ }
+
i++;
+
+ DEBUG(10,("append_parent_acl: path %s "
+ "inheriting ACE with sid %s "
+ "from parent %s\n",
+ fsp->fsp_name,
+ sid_string_static(&se->trustee),
+ parent_name));
+
}
parent_sd->dacl->aces = new_ace;
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index 54bf88844d..b954395278 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -5169,11 +5169,13 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
status = check_name(conn, fname);
if (!NT_STATUS_IS_OK(status)) {
+ CloseDir(dir_hnd);
return ERROR_NT(status);
}
status = check_name(conn, destname);
if (!NT_STATUS_IS_OK(status)) {
+ CloseDir(dir_hnd);
return ERROR_NT(status);
}
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 89cceae2a6..c90d5e727f 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -30,7 +30,7 @@ static int am_parent = 1;
int last_message = -1;
/* a useful macro to debug the last message processed */
-#define LAST_MESSAGE() smb_fn_name(last_message)
+#define LAST_MESSAGE() (last_message != -1 ? smb_fn_name(last_message) : "")
extern struct auth_context *negprot_global_auth_context;
extern pstring user_socket_options;
diff --git a/source/smbd/sesssetup.c b/source/smbd/sesssetup.c
index 058faedd5e..378d8aa20c 100644
--- a/source/smbd/sesssetup.c
+++ b/source/smbd/sesssetup.c
@@ -624,7 +624,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out
/* NB. This is *NOT* an error case. JRA */
auth_ntlmssp_end(auth_ntlmssp_state);
/* Kill the intermediate vuid */
- invalidate_vuid(vuid);
+ invalidate_intermediate_vuid(vuid);
}
return ret;
@@ -690,7 +690,7 @@ static int reply_spnego_negotiate(connection_struct *conn,
status = parse_spnego_mechanisms(blob1, &secblob, &got_kerberos_mechanism);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
- invalidate_vuid(vuid);
+ invalidate_intermediate_vuid(vuid);
return ERROR_NT(nt_status_squash(status));
}
@@ -704,12 +704,21 @@ static int reply_spnego_negotiate(connection_struct *conn,
data_blob_free(&secblob);
if (destroy_vuid) {
/* Kill the intermediate vuid */
- invalidate_vuid(vuid);
+ invalidate_intermediate_vuid(vuid);
}
return ret;
}
#endif
+ if (got_kerberos_mechanism) {
+ invalidate_intermediate_vuid(vuid);
+ DEBUG(3,("reply_spnego_negotiate: network "
+ "misconfiguration, client sent us a "
+ "krb5 ticket and kerberos security "
+ "not enabled"));
+ return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
+ }
+
if (*auth_ntlmssp_state) {
auth_ntlmssp_end(auth_ntlmssp_state);
}
@@ -717,7 +726,7 @@ static int reply_spnego_negotiate(connection_struct *conn,
status = auth_ntlmssp_start(auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
- invalidate_vuid(vuid);
+ invalidate_intermediate_vuid(vuid);
return ERROR_NT(nt_status_squash(status));
}
@@ -755,9 +764,9 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
file_save("auth.dat", blob1.data, blob1.length);
#endif
/* Kill the intermediate vuid */
- invalidate_vuid(vuid);
+ invalidate_intermediate_vuid(vuid);
- return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
+ return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
}
if (auth.data[0] == ASN1_APPLICATION(0)) {
@@ -776,7 +785,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
data_blob_free(&auth);
if (destroy_vuid) {
/* Kill the intermediate vuid */
- invalidate_vuid(vuid);
+ invalidate_intermediate_vuid(vuid);
}
return ret;
}
@@ -786,24 +795,24 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
/* If we get here it wasn't a negTokenTarg auth packet. */
data_blob_free(&secblob);
-
+
if (!*auth_ntlmssp_state) {
/* Kill the intermediate vuid */
- invalidate_vuid(vuid);
+ invalidate_intermediate_vuid(vuid);
/* auth before negotiatiate? */
- return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
+ return ERROR_NT(NT_STATUS_LOGON_FAILURE);
}
-
- status = auth_ntlmssp_update(*auth_ntlmssp_state,
+
+ status = auth_ntlmssp_update(*auth_ntlmssp_state,
auth, &auth_reply);
data_blob_free(&auth);
- reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid,
+ reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid,
auth_ntlmssp_state,
&auth_reply, status, True);
-
+
data_blob_free(&auth_reply);
/* and tell smbd that we have already replied to this packet */
@@ -1112,7 +1121,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,
if (!NT_STATUS_IS_OK(status)) {
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
/* Real error - kill the intermediate vuid */
- invalidate_vuid(vuid);
+ invalidate_intermediate_vuid(vuid);
}
data_blob_free(&blob1);
return ERROR_NT(nt_status_squash(status));
@@ -1140,7 +1149,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,
status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
/* Kill the intermediate vuid */
- invalidate_vuid(vuid);
+ invalidate_intermediate_vuid(vuid);
data_blob_free(&blob1);
return ERROR_NT(nt_status_squash(status));
}
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index 0d9dac3e5f..a60f306c7b 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -2223,6 +2223,41 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
return(-1);
}
+static void samba_extended_info_version(struct smb_extended_info *extended_info)
+{
+ SMB_ASSERT(extended_info != NULL);
+
+ extended_info->samba_magic = SAMBA_EXTENDED_INFO_MAGIC;
+ extended_info->samba_version = ((SAMBA_VERSION_MAJOR & 0xff) << 24)
+ | ((SAMBA_VERSION_MINOR & 0xff) << 16)
+ | ((SAMBA_VERSION_RELEASE & 0xff) << 8);
+#ifdef SAMBA_VERSION_REVISION
+ extended_info->samba_version |= (tolower(*SAMBA_VERSION_REVISION) - 'a' + 1) & 0xff;
+#endif
+ extended_info->samba_subversion = 0;
+#ifdef SAMBA_VERSION_RC_RELEASE
+ extended_info->samba_subversion |= (SAMBA_VERSION_RC_RELEASE & 0xff) << 24;
+#else
+#ifdef SAMBA_VERSION_PRE_RELEASE
+ extended_info->samba_subversion |= (SAMBA_VERSION_PRE_RELEASE & 0xff) << 16;
+#endif
+#endif
+#ifdef SAMBA_VERSION_VENDOR_PATCH
+ extended_info->samba_subversion |= (SAMBA_VERSION_VENDOR_PATCH & 0xffff);
+#endif
+ extended_info->samba_subversion = 0;
+#ifdef SAMBA_VERSION_GIT_COMMIT_TIME
+ unix_to_nt_time(&extended_info->samba_gitcommitdate, SAMBA_VERSION_GIT_COMMIT_TIME);
+#endif
+
+ memset(extended_info->samba_version_string, 0,
+ sizeof(extended_info->samba_version_string));
+
+ snprintf (extended_info->samba_version_string,
+ sizeof(extended_info->samba_version_string),
+ "%s", samba_version_string());
+}
+
/****************************************************************************
Reply to a TRANS2_QFSINFO (query filesystem info).
****************************************************************************/
@@ -2330,6 +2365,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)st.st_dev, (unsi
SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
(lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
+ FILE_UNICODE_ON_DISK|
quota_flag); /* FS ATTRIBUTES */
SIVAL(pdata,4,255); /* Max filename component length */
@@ -2511,8 +2547,20 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
}
#endif /* HAVE_SYS_QUOTAS */
case SMB_FS_OBJECTID_INFORMATION:
+ {
+ /*
+ * No object id, but we transmit version information.
+ */
+ struct smb_extended_info extended_info;
+ samba_extended_info_version (&extended_info);
+ SIVAL(pdata,16,extended_info.samba_magic);
+ SIVAL(pdata,20,extended_info.samba_version);
+ SIVAL(pdata,24,extended_info.samba_subversion);
+ SBIG_UINT(pdata,28,extended_info.samba_gitcommitdate);
+ memcpy(pdata+36,extended_info.samba_version_string,28);
data_len = 64;
break;
+ }
/*
* Query the version and capabilities of the CIFS UNIX extensions
@@ -3299,17 +3347,6 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
}
}
- nlink = sbuf.st_nlink;
-
- if ((nlink > 0) && S_ISDIR(sbuf.st_mode)) {
- /* NTFS does not seem to count ".." */
- nlink -= 1;
- }
-
- if ((nlink > 0) && delete_pending) {
- nlink -= 1;
- }
-
if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
return ERROR_NT(NT_STATUS_INVALID_LEVEL);
}
@@ -3327,6 +3364,16 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
if (!mode)
mode = FILE_ATTRIBUTE_NORMAL;
+ nlink = sbuf.st_nlink;
+
+ if (nlink && (mode&aDIR)) {
+ nlink = 1;
+ }
+
+ if ((nlink > 0) && delete_pending) {
+ nlink -= 1;
+ }
+
fullpathname = fname;
if (!(mode & aDIR))
file_size = get_file_size(sbuf);
diff --git a/source/tdb/common/io.c b/source/tdb/common/io.c
index 01ada7647b..4b7e33ab65 100644
--- a/source/tdb/common/io.c
+++ b/source/tdb/common/io.c
@@ -95,7 +95,7 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off,
/* try once more */
TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: wrote only "
"%d of %d bytes at %d, trying once more\n",
- written, len, off));
+ (uint32_t)written, len, off));
errno = ENOSPC;
written = pwrite(tdb->fd, (void *)((char *)buf+written),
len-written,
@@ -275,11 +275,12 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad
return -1;
} else if (written == -1) {
TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of "
- "%d bytes failed (%s)\n", n, strerror(errno)));
+ "%d bytes failed (%s)\n", (uint32_t)n, strerror(errno)));
return -1;
} else if (written != n) {
TDB_LOG((tdb, TDB_DEBUG_WARNING, "expand_file: wrote "
- "only %d of %d bytes - retrying\n", written,n));
+ "only %d of %d bytes - retrying\n",
+ (uint32_t)written, (uint32_t)n));
}
addition -= written;
size += written;
diff --git a/source/tdb/tools/tdbtool.c b/source/tdb/tools/tdbtool.c
index 2f549ef91b..4bddf76a23 100644
--- a/source/tdb/tools/tdbtool.c
+++ b/source/tdb/tools/tdbtool.c
@@ -151,7 +151,7 @@ static void print_data(const char *buf,int len)
if (len<=0) return;
printf("[%03X] ",i);
for (i=0;i<len;) {
- printf("%02X ",(int)buf[i]);
+ printf("%02X ",(int)((unsigned char)buf[i]));
i++;
if (i%8 == 0) printf(" ");
if (i%16 == 0) {
diff --git a/source/torture/torture.c b/source/torture/torture.c
index 8ca2eb5898..aa83f52c23 100644
--- a/source/torture/torture.c
+++ b/source/torture/torture.c
@@ -4781,6 +4781,47 @@ static BOOL run_error_map_extract(int dummy) {
return True;
}
+static BOOL run_sesssetup_bench(int dummy)
+{
+ static struct cli_state *c;
+ NTSTATUS status;
+ int i;
+
+ if (!(c = open_nbt_connection())) {
+ return false;
+ }
+
+ if (!cli_negprot(c)) {
+ printf("%s rejected the NT-error negprot (%s)\n", host,
+ cli_errstr(c));
+ cli_shutdown(c);
+ return false;
+ }
+
+ for (i=0; i<torture_numops; i++) {
+ status = cli_session_setup(
+ c, username,
+ password, strlen(password),
+ password, strlen(password),
+ workgroup);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("(%s) cli_session_setup failed: %s\n",
+ __location__, nt_errstr(status));
+ return false;
+ }
+
+ if (!cli_ulogoff(c)) {
+ d_printf("(%s) cli_ulogoff failed: %s\n",
+ __location__, cli_errstr(c));
+ return false;
+ }
+
+ c->vuid = 0;
+ }
+
+ return True;
+}
+
static BOOL run_local_substitute(int dummy)
{
TALLOC_CTX *mem_ctx;
@@ -5026,6 +5067,7 @@ static struct {
{"CHKPATH", torture_chkpath_test, 0},
{"FDSESS", run_fdsesstest, 0},
{ "EATEST", run_eatest, 0},
+ { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
{ "LOCAL-SUBSTITUTE", run_local_substitute, 0},
{ "LOCAL-GENCACHE", run_local_gencache, 0},
{NULL, NULL, 0}};
diff --git a/source/utils/net.c b/source/utils/net.c
index a030531947..99384ad61a 100644
--- a/source/utils/net.c
+++ b/source/utils/net.c
@@ -677,6 +677,16 @@ static int net_getdomainsid(int argc, const char **argv)
"backend knowlege (such as the sid stored in LDAP)\n"));
}
+ /* first check to see if we can even access secrets, so we don't
+ panic when we can't. */
+
+ if (!secrets_init()) {
+ d_fprintf(stderr, "Unable to open secrets.tdb. "
+ "Can't fetch domainSID for name: %s\n",
+ get_global_sam_name());
+ return 1;
+ }
+
/* Generate one, if it doesn't exist */
get_global_sam_sid();
diff --git a/source/utils/net_domain.c b/source/utils/net_domain.c
index 5b330d8765..533bb9c698 100644
--- a/source/utils/net_domain.c
+++ b/source/utils/net_domain.c
@@ -209,10 +209,15 @@ NTSTATUS netdom_join_domain( TALLOC_CTX *mem_ctx, struct cli_state *cli,
uint32 num_rids, *name_types, *user_rids;
uint32 flags = 0x3e8;
uint32 acb_info = ACB_WSTRUST;
- uchar pwbuf[516];
+ uint32 acct_flags=0;
+ uint32 fields_present;
+ uchar pwbuf[532];
SAM_USERINFO_CTR ctr;
- SAM_USER_INFO_24 p24;
- SAM_USER_INFO_16 p16;
+ SAM_USER_INFO_25 p25;
+ const int infolevel = 25;
+ struct MD5Context md5ctx;
+ uchar md5buffer[16];
+ DATA_BLOB digested_session_key;
uchar md4_trust_password[16];
/* Open the domain */
@@ -242,8 +247,13 @@ NTSTATUS netdom_join_domain( TALLOC_CTX *mem_ctx, struct cli_state *cli,
/* Don't try to set any acb_info flags other than ACB_WSTRUST */
+ acct_flags = SAMR_GENERIC_READ | SAMR_GENERIC_WRITE |
+ SAMR_GENERIC_EXECUTE | SAMR_STANDARD_WRITEDAC |
+ SAMR_STANDARD_DELETE | SAMR_USER_SETPASS | SAMR_USER_GETATTR |
+ SAMR_USER_SETATTR;
+ DEBUG(10, ("Creating account with flags: %d\n",acct_flags));
status = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
- acct_name, acb_info, 0xe005000b, &user_pol, &user_rid);
+ acct_name, acb_info, acct_flags, &user_pol, &user_rid);
if ( !NT_STATUS_IS_OK(status)
&& !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS))
@@ -283,44 +293,25 @@ NTSTATUS netdom_join_domain( TALLOC_CTX *mem_ctx, struct cli_state *cli,
status = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol);
-
- /* Create a random machine account password */
-
- E_md4hash( clear_pw, md4_trust_password);
- encode_pw_buffer(pwbuf, clear_pw, STR_UNICODE);
-
- /* Set password on machine account */
-
- ZERO_STRUCT(ctr);
- ZERO_STRUCT(p24);
-
- init_sam_user_info24(&p24, (char *)pwbuf,24);
-
- ctr.switch_value = 24;
- ctr.info.id24 = &p24;
-
- status = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol,
- 24, &cli->user_session_key, &ctr);
-
- if ( !NT_STATUS_IS_OK(status) ) {
- d_fprintf( stderr, "Failed to set password for machine account (%s)\n",
- nt_errstr(status));
+ if (!NT_STATUS_IS_OK(status)) {
return status;
}
+
+ /* Create a random machine account password and generate the hash */
-
- /* Why do we have to try to (re-)set the ACB to be the same as what
- we passed in the samr_create_dom_user() call? When a NT
- workstation is joined to a domain by an administrator the
- acb_info is set to 0x80. For a normal user with "Add
- workstations to the domain" rights the acb_info is 0x84. I'm
- not sure whether it is supposed to make a difference or not. NT
- seems to cope with either value so don't bomb out if the set
- userinfo2 level 0x10 fails. -tpot */
-
- ZERO_STRUCT(ctr);
- ctr.switch_value = 16;
- ctr.info.id16 = &p16;
+ E_md4hash(clear_pw, md4_trust_password);
+ encode_pw_buffer(pwbuf, clear_pw, STR_UNICODE);
+
+ generate_random_buffer((uint8*)md5buffer, sizeof(md5buffer));
+ digested_session_key = data_blob_talloc(mem_ctx, 0, 16);
+
+ MD5Init(&md5ctx);
+ MD5Update(&md5ctx, md5buffer, sizeof(md5buffer));
+ MD5Update(&md5ctx, cli->user_session_key.data, cli->user_session_key.length);
+ MD5Final(digested_session_key.data, &md5ctx);
+
+ SamOEMhashBlob(pwbuf, sizeof(pwbuf), &digested_session_key);
+ memcpy(&pwbuf[516], md5buffer, sizeof(md5buffer));
/* Fill in the additional account flags now */
@@ -332,10 +323,25 @@ NTSTATUS netdom_join_domain( TALLOC_CTX *mem_ctx, struct cli_state *cli,
;;
}
- init_sam_user_info16(&p16, acb_info);
+ /* Set password and account flags on machine account */
- status = rpccli_samr_set_userinfo2(pipe_hnd, mem_ctx, &user_pol, 16,
- &cli->user_session_key, &ctr);
+ ZERO_STRUCT(ctr);
+ ZERO_STRUCT(p25);
+
+ fields_present = ACCT_NT_PWD_SET | ACCT_LM_PWD_SET | ACCT_FLAGS;
+ init_sam_user_info25P(&p25, fields_present, acb_info, (char *)pwbuf);
+
+ ctr.switch_value = infolevel;
+ ctr.info.id25 = &p25;
+
+ status = rpccli_samr_set_userinfo2(pipe_hnd, mem_ctx, &user_pol,
+ infolevel, &cli->user_session_key, &ctr);
+
+ if ( !NT_STATUS_IS_OK(status) ) {
+ d_fprintf( stderr, "Failed to set password for machine account (%s)\n",
+ nt_errstr(status));
+ return status;
+ }
rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */
diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c
index fee994b751..9944ef0701 100644
--- a/source/utils/net_rpc.c
+++ b/source/utils/net_rpc.c
@@ -381,7 +381,7 @@ static int rpc_join_usage(int argc, const char **argv)
* @param argc Standard main() style argv. Initial components are already
* stripped
*
- * Main 'net_rpc_join()' (where the admain username/password is used) is
+ * Main 'net_rpc_join()' (where the admin username/password is used) is
* in net_rpc_join.c
* Try to just change the password, but if that doesn't work, use/prompt
* for a username/password.
@@ -581,7 +581,8 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
const char *acct_name;
uint32 acb_info;
- uint32 unknown, user_rid;
+ uint32 acct_flags=0;
+ uint32 user_rid;
if (argc < 1) {
d_printf("User must be specified\n");
@@ -611,10 +612,14 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid,
/* Create domain user */
acb_info = ACB_NORMAL;
- unknown = 0xe005000b; /* No idea what this is - a permission mask? */
+ acct_flags = SAMR_GENERIC_READ | SAMR_GENERIC_WRITE |
+ SAMR_GENERIC_EXECUTE | SAMR_STANDARD_WRITEDAC |
+ SAMR_STANDARD_DELETE | SAMR_USER_SETPASS | SAMR_USER_GETATTR |
+ SAMR_USER_SETATTR;
+ DEBUG(10, ("Creating account with flags: %d\n",acct_flags));
result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
- acct_name, acb_info, unknown,
+ acct_name, acb_info, acct_flags,
&user_pol, &user_rid);
if (!NT_STATUS_IS_OK(result)) {
goto done;
@@ -5335,7 +5340,8 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
char *acct_name;
uint32 acb_info;
- uint32 unknown, user_rid;
+ uint32 user_rid;
+ uint32 acct_flags=0;
if (argc != 2) {
d_printf("Usage: net rpc trustdom add <domain_name> <pw>\n");
@@ -5369,11 +5375,13 @@ static NTSTATUS rpc_trustdom_add_internals(const DOM_SID *domain_sid,
/* Create trusting domain's account */
acb_info = ACB_NORMAL;
- unknown = 0xe00500b0; /* No idea what this is - a permission mask?
- mimir: yes, most probably it is */
+ acct_flags = SAMR_GENERIC_READ | SAMR_GENERIC_WRITE |
+ SAMR_GENERIC_EXECUTE | SAMR_STANDARD_WRITEDAC |
+ SAMR_STANDARD_DELETE | SAMR_USER_SETPASS | SAMR_USER_GETATTR |
+ SAMR_USER_SETATTR;
result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
- acct_name, acb_info, unknown,
+ acct_name, acb_info, acct_flags,
&user_pol, &user_rid);
if (!NT_STATUS_IS_OK(result)) {
goto done;
diff --git a/source/utils/net_rpc_join.c b/source/utils/net_rpc_join.c
index d23bd76751..fe5cef1803 100644
--- a/source/utils/net_rpc_join.c
+++ b/source/utils/net_rpc_join.c
@@ -43,7 +43,7 @@
**/
int net_rpc_join_ok(const char *domain, const char *server, struct in_addr *ip )
{
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
struct cli_state *cli = NULL;
struct rpc_pipe_client *pipe_hnd = NULL;
struct rpc_pipe_client *netlogon_pipe = NULL;
@@ -114,7 +114,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
struct cli_state *cli;
TALLOC_CTX *mem_ctx;
uint32 acb_info = ACB_WSTRUST;
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|(lp_client_schannel() ? NETLOGON_NEG_SCHANNEL : 0);
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS|(lp_client_schannel() ? NETLOGON_NEG_SCHANNEL : 0);
uint32 sec_channel_type;
struct rpc_pipe_client *pipe_hnd = NULL;
@@ -142,6 +142,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
uint32 flags = 0x3e8;
char *acct_name;
const char *const_acct_name;
+ uint32 acct_flags=0;
/* check what type of join */
if (argc >= 0) {
@@ -229,9 +230,14 @@ int net_rpc_join_newstyle(int argc, const char **argv)
strlower_m(acct_name);
const_acct_name = acct_name;
+ acct_flags = SAMR_GENERIC_READ | SAMR_GENERIC_WRITE |
+ SAMR_GENERIC_EXECUTE | SAMR_STANDARD_WRITEDAC |
+ SAMR_STANDARD_DELETE | SAMR_USER_SETPASS | SAMR_USER_GETATTR |
+ SAMR_USER_SETATTR;
+ DEBUG(10, ("Creating account with flags: %d\n",acct_flags));
result = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
acct_name, acb_info,
- 0xe005000b, &user_pol,
+ acct_flags, &user_pol,
&user_rid);
if (!NT_STATUS_IS_OK(result) &&
diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c
index d8ddff20bc..bd209de0c1 100644
--- a/source/utils/net_rpc_samsync.c
+++ b/source/utils/net_rpc_samsync.c
@@ -238,7 +238,7 @@ NTSTATUS rpc_samdump_internals(const DOM_SID *domain_sid,
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
uchar trust_password[16];
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
+ uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS;
uint32 sec_channel_type = 0;
if (!secrets_fetch_trust_account_password(domain_name,
diff --git a/source/utils/net_sam.c b/source/utils/net_sam.c
index bf397803bc..e01142e6d1 100644
--- a/source/utils/net_sam.c
+++ b/source/utils/net_sam.c
@@ -42,7 +42,7 @@ static int net_sam_userset(int argc, const char **argv, const char *field,
return -1;
}
- if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_ISOLATED,
+ if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_LOCAL,
&dom, &name, &sid, &type)) {
d_fprintf(stderr, "Could not find name %s\n", argv[0]);
return -1;
@@ -139,7 +139,7 @@ static int net_sam_set_userflag(int argc, const char **argv, const char *field,
return -1;
}
- if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_ISOLATED,
+ if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_LOCAL,
&dom, &name, &sid, &type)) {
d_fprintf(stderr, "Could not find name %s\n", argv[0]);
return -1;
@@ -223,7 +223,7 @@ static int net_sam_set_pwdmustchangenow(int argc, const char **argv)
return -1;
}
- if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_ISOLATED,
+ if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_LOCAL,
&dom, &name, &sid, &type)) {
d_fprintf(stderr, "Could not find name %s\n", argv[0]);
return -1;
@@ -284,7 +284,7 @@ static int net_sam_set_comment(int argc, const char **argv)
return -1;
}
- if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_ISOLATED,
+ if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_LOCAL,
&dom, &name, &sid, &type)) {
d_fprintf(stderr, "Could not find name %s\n", argv[0]);
return -1;
@@ -639,7 +639,7 @@ static int net_sam_addmem(int argc, const char **argv)
return -1;
}
- if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_ISOLATED,
+ if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_LOCAL,
&groupdomain, &groupname, &group, &grouptype)) {
d_fprintf(stderr, "Could not find group %s\n", argv[0]);
return -1;
@@ -647,7 +647,7 @@ static int net_sam_addmem(int argc, const char **argv)
/* check to see if the member to be added is a name or a SID */
- if (!lookup_name(tmp_talloc_ctx(), argv[1], LOOKUP_NAME_ISOLATED,
+ if (!lookup_name(tmp_talloc_ctx(), argv[1], LOOKUP_NAME_LOCAL,
&memberdomain, &membername, &member, &membertype))
{
/* try it as a SID */
@@ -712,13 +712,13 @@ static int net_sam_delmem(int argc, const char **argv)
return -1;
}
- if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_ISOLATED,
+ if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_LOCAL,
&groupdomain, &groupname, &group, &grouptype)) {
d_fprintf(stderr, "Could not find group %s\n", argv[0]);
return -1;
}
- if (!lookup_name(tmp_talloc_ctx(), argv[1], LOOKUP_NAME_ISOLATED,
+ if (!lookup_name(tmp_talloc_ctx(), argv[1], LOOKUP_NAME_LOCAL,
&memberdomain, &membername, &member, NULL)) {
if (!string_to_sid(&member, argv[1])) {
d_fprintf(stderr, "Could not find member %s\n",
@@ -770,7 +770,7 @@ static int net_sam_listmem(int argc, const char **argv)
return -1;
}
- if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_ISOLATED,
+ if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_LOCAL,
&groupdomain, &groupname, &group, &grouptype)) {
d_fprintf(stderr, "Could not find group %s\n", argv[0]);
return -1;
@@ -918,7 +918,7 @@ static int net_sam_show(int argc, const char **argv)
return -1;
}
- if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_ISOLATED,
+ if (!lookup_name(tmp_talloc_ctx(), argv[0], LOOKUP_NAME_LOCAL,
&dom, &name, &sid, &type)) {
d_fprintf(stderr, "Could not find name %s\n", argv[0]);
return -1;
diff --git a/source/utils/smbcacls.c b/source/utils/smbcacls.c
index 82cae03720..6d4fbaa5d1 100644
--- a/source/utils/smbcacls.c
+++ b/source/utils/smbcacls.c
@@ -788,7 +788,8 @@ static struct cli_state *connect_one(const char *share)
&ip, 0,
share, "?????",
cmdline_auth_info.username, lp_workgroup(),
- cmdline_auth_info.password, 0,
+ cmdline_auth_info.password,
+ cmdline_auth_info.use_kerberos ? CLI_FULL_CONNECTION_USE_KERBEROS : 0,
cmdline_auth_info.signing_state, NULL))) {
return c;
} else {
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c
index 7460662441..ef4e20bb7f 100644
--- a/source/utils/smbpasswd.c
+++ b/source/utils/smbpasswd.c
@@ -96,6 +96,12 @@ static int process_options(int argc, char **argv, int local_flags)
while ((ch = getopt(argc, argv, "c:axdehminjr:sw:R:D:U:LW")) != EOF) {
switch(ch) {
case 'L':
+#if !defined(DEVELOPER)
+ if (getuid() != 0) {
+ fprintf(stderr, "smbpasswd -L can only be used by root.\n");
+ exit(1);
+ }
+#endif
local_flags |= LOCAL_AM_ROOT;
break;
case 'c':
diff --git a/source/utils/status.c b/source/utils/status.c
index df742f73e7..0dc1253a97 100644
--- a/source/utils/status.c
+++ b/source/utils/status.c
@@ -367,6 +367,16 @@ static int traverse_sessionid(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
if ( show_locks ) {
int ret;
+ tdb = tdb_open_log(lock_path("locking.tdb"), 0, TDB_DEFAULT, O_RDONLY, 0);
+
+ if (!tdb) {
+ d_printf("%s not initialised\n", lock_path("locking.tdb"));
+ d_printf("This is normal if an SMB client has never connected to your server.\n");
+ exit(0);
+ } else {
+ tdb_close(tdb);
+ }
+
if (!locking_init(1)) {
d_printf("Can't initialise locking module - exiting\n");
exit(1);