From fbdcce61a0c4d128075ef9e1b1bd458dfd9e51d5 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 19 Jun 2007 16:01:58 +0000 Subject: r23544: sync 3.0.25b release with SAMBA_3_0_25 svn r23530. --- packaging/Debian/debian-sarge/changelog | 37 +++ .../debian-sarge/patches/documentation.patch | 80 +++---- packaging/Debian/debian-sarge/patches/fhs.patch | 202 ++++++++-------- .../debian-sarge/patches/non-linux-ports.patch | 4 +- packaging/Debian/debian-sarge/patches/samba.patch | 6 +- .../debian-sarge/patches/undefined-symbols.patch | 22 -- source/Makefile.in | 10 +- source/VERSION | 2 +- source/auth/auth_sam.c | 2 +- source/auth/auth_util.c | 54 +++++ source/client/smbspool.c | 49 ++-- source/include/ads.h | 2 +- source/include/doserr.h | 3 + source/include/rpc_lsa.h | 6 +- source/include/rpc_netlogon.h | 111 ++++++++- source/lib/smbldap.c | 1 + source/lib/time.c | 2 +- source/lib/util_str.c | 2 +- source/libads/kerberos.c | 3 +- source/libsmb/clifile.c | 10 +- source/libsmb/clireadwrite.c | 2 +- source/libsmb/doserr.c | 6 +- source/locking/brlock.c | 6 + source/modules/vfs_catia.c | 4 +- source/nmbd/nmbd_subnetdb.c | 16 ++ source/nmbd/nmbd_winsserver.c | 4 +- source/nsswitch/idmap.c | 2 +- source/nsswitch/idmap_ldap.c | 6 +- source/nsswitch/idmap_nss.c | 8 + source/nsswitch/idmap_passdb.c | 8 + source/nsswitch/idmap_rid.c | 42 +++- source/nsswitch/winbindd.c | 3 + source/nsswitch/winbindd_cm.c | 10 +- source/nsswitch/winbindd_dual.c | 64 +++++ source/nsswitch/winbindd_misc.c | 6 +- source/pam_smbpass/general.h | 2 +- source/rpc_client/cli_lsarpc.c | 9 +- source/rpc_client/cli_netlogon.c | 258 +++++++++++++++------ source/rpc_parse/parse_lsa.c | 6 +- source/rpc_parse/parse_net.c | 239 +++++++++++++++++-- source/rpc_parse/parse_prs.c | 3 + source/rpc_parse/parse_spoolss.c | 65 ++++-- source/rpc_server/srv_lsa_nt.c | 40 ++-- source/rpcclient/cmd_netlogon.c | 204 ++++++++++++++-- source/rpcclient/rpcclient.c | 7 +- source/smbd/aio.c | 9 +- source/smbd/fileio.c | 15 +- source/smbd/notify.c | 18 +- source/smbd/nttrans.c | 14 +- source/smbd/open.c | 23 ++ source/smbd/reply.c | 62 ++++- source/tdb/common/traverse.c | 16 +- source/torture/denytest.c | 2 +- source/utils/pdbedit.c | 31 ++- 54 files changed, 1374 insertions(+), 444 deletions(-) delete mode 100644 packaging/Debian/debian-sarge/patches/undefined-symbols.patch diff --git a/packaging/Debian/debian-sarge/changelog b/packaging/Debian/debian-sarge/changelog index bd66900a7f2..26e1568432b 100644 --- a/packaging/Debian/debian-sarge/changelog +++ b/packaging/Debian/debian-sarge/changelog @@ -1,3 +1,40 @@ +samba (3.0.25a-2) stable; urgency=low + + * Fix bug in fhs.patch + + -- Simo Sorce Wed, 6 Jun 2007 11:33:30 -0400 + +samba (3.0.25a-1) stable; urgency=high + + * samba 3.0.25a Stabilizing release + * Includes Security fixes release with 3.0.24a and 3.0.25 + + -- Simo Sorce Mon, 28 May 2007 20:45:30 -0400 + +samba (3.0.24-1) stable; urgency=high + + * samba 3.0.24 Security Release + + -- Simo Sorce Mon, 19 Feb 2007 15:53:30 -0500 + +samba (3.0.23d-1) stable; urgency=low + + * samba 3.0.23d Samba Team Release + + -- Simo Sorce Fri, 17 Nov 2006 15:39:30 -0500 + +samba (3.0.23c-1) stable; urgency=low + + * samba 3.0.23c Samba Team Release + + -- Simo Sorce Fri, 8 Sep 2006 14:12:30 -0400 + +samba (3.0.23a-1) stable; urgency=low + + * samba 3.0.23a Samba Team Release + + -- Simo Sorce Tue, 1 Aug 2006 22:01:30 -0400 + samba (3.0.23-1) stable; urgency=low * samba 3.0.23 Samba Team Release diff --git a/packaging/Debian/debian-sarge/patches/documentation.patch b/packaging/Debian/debian-sarge/patches/documentation.patch index 505a53c51b6..c7291eff98f 100644 --- a/packaging/Debian/debian-sarge/patches/documentation.patch +++ b/packaging/Debian/debian-sarge/patches/documentation.patch @@ -1,66 +1,66 @@ --- samba-3.0.4/docs/manpages/swat.8.orig 2004-05-05 10:22:50.000000000 -0400 +++ samba-3.0.4/docs/manpages/swat.8 2004-05-10 13:25:53.000000000 -0400 -@@ -80,6 +80,13 @@ +@@ -80,4 +80,10 @@ .SH "INSTALLATION" - .PP +\fBDebian-specific Note\fR: all these steps have already been done for +you. However, by default, swat is not enabled. This has been done for +security reasons. To enable swat you need to edit /etc/inetd.conf, +uncomment the swat entry (usually at the end of the file), and then +restart inetd. -+ +.PP Swat is included as binary package with most distributions\&. The package manager in this case takes care of the installation and configuration\&. This section is only for those who have compiled swat from scratch\&. - .PP -@@ -87,13 +94,13 @@ - - .TP 3 - \(bu +@@ -87,12 +94,12 @@ + .TP 3n + • -/usr/local/samba/sbin/swat +/usr/sbin/swat - .TP - \(bu + .TP 3n + • -/usr/local/samba/swat/images/* +/usr/share/samba/swat/images/* - .TP - \(bu + .TP 3n + • -/usr/local/samba/swat/help/* +/usr/share/samba/swat/help/* - .LP - .SS "Inetd Installation" -@@ -102,7 +109,7 @@ - You need to edit your \fI/etc/inetd\&.conf \fR and \fI/etc/services\fR to enable SWAT to be launched via \fBinetd\fR\&. - .PP --In \fI/etc/services\fR you need to add a line like this: -+In \fI/etc/services\fR you need to add a line like this (not needed for Debian): - + You need to edit your +@@ -125,7 +131,7 @@ + .PP + In + \fI/etc/services\fR +-you need to add a line like this: ++you need to add a line like this (not needed for Debian): .PP \fBswat 901/tcp\fR -@@ -114,10 +121,10 @@ - the choice of port number isn't really important except that it should be less than 1024 and not currently used (using a number above 1024 presents an obscure security hole depending on the implementation details of your\fBinetd\fR daemon)\&. - .PP --In \fI/etc/inetd\&.conf\fR you should add a line like this: -+In \fI/etc/inetd\&.conf\fR you should add a line like this (not needed for Debian since the maintainer scripts do it automatically. You need to uncomment the line, though, because it is added commented out for security reasons): - +@@ -140,9 +146,9 @@ + .PP + In + \fI/etc/inetd.conf\fR +-you should add a line like this: ++you should add a line like this (not needed for Debian since the maintainer scripts do it automatically. You need to uncomment the line, though, because it is added commented out for security reasons): .PP --\fBswat stream tcp nowait\&.400 root /usr/local/samba/sbin/swat swat\fR -+\fBswat stream tcp nowait\&.400 root /usr/sbin/swat swat\fR - +-\fBswat stream tcp nowait.400 root /usr/local/samba/sbin/swat swat\fR ++\fBswat stream tcp nowait.400 root /usr/sbin/swat swat\fR .PP - Once you have edited \fI/etc/services\fR and \fI/etc/inetd\&.conf\fR you need to send a HUP signal to inetd\&. To do this use \fBkill \-1 PID \fR where PID is the process ID of the inetd daemon\&. -@@ -141,8 +148,8 @@ - This file must contain a mapping of service name (e\&.g\&., swat) to service port (e\&.g\&., 901) and protocol type (e\&.g\&., tcp)\&. - - .TP --\fI/usr/local/samba/lib/smb\&.conf\fR --This is the default location of the \fBsmb\&.conf\fR(5) server configuration file that swat edits\&. Other common places that systems install this file are \fI /usr/samba/lib/smb\&.conf\fR and \fI/etc/smb\&.conf \fR\&. This file describes all the services the server is to make available to clients\&. -+\fI/etc/samba/smb\&.conf\fR -+This is the default location of the \fBsmb\&.conf\fR(5) server configuration file that swat edits\&. This file describes all the services the server is to make available to clients\&. - + Once you have edited + \fI/etc/services\fR +@@ -166,13 +172,13 @@ + .RE + .PP +-\fI/usr/local/samba/lib/smb.conf\fR ++\fI/etc/samba/smb.conf\fR + .RS 3n + This is the default location of the + \fBsmb.conf\fR(5) + server configuration file that swat edits. Other common places that systems install this file are + \fI /usr/samba/lib/smb.conf\fR + and +-\fI/etc/smb.conf \fR. This file describes all the services the server is to make available to clients. ++\fI/etc/samba/smb.conf \fR. This file describes all the services the server is to make available to clients. + .RE .SH "WARNINGS" - + .PP diff --git a/packaging/Debian/debian-sarge/patches/fhs.patch b/packaging/Debian/debian-sarge/patches/fhs.patch index e152ec873e9..5ab5053bed9 100644 --- a/packaging/Debian/debian-sarge/patches/fhs.patch +++ b/packaging/Debian/debian-sarge/patches/fhs.patch @@ -111,19 +111,6 @@ diff -uNr samba-3.0.10.orig/source/dynconfig.c samba-3.0.10/source/dynconfig.c + return lp_lockdir(); +#endif +} -diff -uNr samba-3.0.10.orig/source/groupdb/mapping.c samba-3.0.10/source/groupdb/mapping.c ---- samba-3.0.10.orig/source/groupdb/mapping.c 2004-12-17 03:50:08.000000000 -0800 -+++ samba-3.0.10/source/groupdb/mapping.c 2004-12-17 03:55:29.000000000 -0800 -@@ -140,8 +140,8 @@ - - if (tdb) - return True; - -- tdb = tdb_open_log(lock_path("group_mapping.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); -+ tdb = tdb_open_log(state_path("group_mapping.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); - if (!tdb) { - DEBUG(0,("Failed to open group mapping database\n")); - return False; diff -uNr samba-3.0.10.orig/source/include/dynconfig.h samba-3.0.10/source/include/dynconfig.h --- samba-3.0.10.orig/source/include/dynconfig.h 2004-12-17 03:50:08.000000000 -0800 +++ samba-3.0.10/source/include/dynconfig.h 2004-12-17 03:55:29.000000000 -0800 @@ -152,18 +139,6 @@ diff -uNr samba-3.0.10.orig/source/intl/lang_tdb.c samba-3.0.10/source/intl/lang if (stat(msg_path, &st) != 0) { /* the msg file isn't available */ DEBUG(10, ("lang_tdb_init: %s: %s\n", msg_path, -diff -uNr samba-3.0.21.orig/source/lib/account_pol.c samba-3.0.21/source/lib/account_pol.c ---- samba-3.0.21.orig/source/lib/account_pol.c 2005-12-20 15:28:38.000000000 +0000 -+++ samba-3.0.21/source/lib/account_pol.c 2005-12-23 11:41:08.000000000 +0000 -@@ -262,7 +262,7 @@ - return True; - } - -- tdb = tdb_open_log(lock_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); -+ tdb = tdb_open_log(state_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); - if (!tdb) { - DEBUG(0,("Failed to open account policy database\n")); - return False; diff -uNr samba-3.0.10.orig/source/lib/util.c samba-3.0.10/source/lib/util.c --- samba-3.0.10.orig/source/lib/util.c 2004-12-17 03:50:08.000000000 -0800 +++ samba-3.0.10/source/lib/util.c 2004-12-17 03:55:29.000000000 -0800 @@ -229,32 +204,6 @@ diff -uNr samba-3.0.10.orig/source/lib/util.c samba-3.0.10/source/lib/util.c * @brief Returns the platform specific shared library extension. * * @retval Pointer to a static #fstring containing the extension. -diff -uNr samba-3.0.10.orig/source/lib/util_unistr.c samba-3.0.10/source/lib/util_unistr.c ---- samba-3.0.10.orig/source/lib/util_unistr.c 2004-12-17 03:50:08.000000000 -0800 -+++ samba-3.0.10/source/lib/util_unistr.c 2004-12-17 03:55:29.000000000 -0800 -@@ -54,11 +54,11 @@ - } - initialised = 1; - -- upcase_table = map_file(lib_path("upcase.dat"), 0x20000); -+ upcase_table = map_file(data_path("upcase.dat"), 0x20000); - upcase_table_use_unmap = ( upcase_table != NULL ); - -- lowcase_table = map_file(lib_path("lowcase.dat"), 0x20000); -+ lowcase_table = map_file(data_path("lowcase.dat"), 0x20000); - lowcase_table_use_unmap = ( lowcase_table != NULL ); - - #ifdef HAVE_SETLOCALE - /* Get the name of the current locale. */ -@@ -161,7 +161,7 @@ - return; - } - -- valid_file = map_file(lib_path("valid.dat"), 0x10000); -+ valid_file = map_file(data_path("valid.dat"), 0x10000); - if (valid_file) { - valid_table = valid_file; - mapped_file = 1; diff -uNr samba-3.0.10.orig/source/libsmb/samlogon_cache.c samba-3.0.10/source/libsmb/samlogon_cache.c --- samba-3.0.10.orig/source/libsmb/samlogon_cache.c 2004-12-17 03:50:08.000000000 -0800 +++ samba-3.0.10/source/libsmb/samlogon_cache.c 2004-12-17 03:55:29.000000000 -0800 @@ -267,15 +216,6 @@ diff -uNr samba-3.0.10.orig/source/libsmb/samlogon_cache.c samba-3.0.10/source/l TDB_DEFAULT, O_RDWR | O_CREAT, 0600); } -@@ -67,7 +67,7 @@ - winbindd_cache.tdb open. Open the tdb if a NULL is passed. */ - - if (!tdb) { -- tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000, -+ tdb = tdb_open_log(cache_path("winbindd_cache.tdb"), 5000, - TDB_DEFAULT, O_RDWR, 0600); - if (!tdb) { - DEBUG(5, ("netsamlogon_clear_cached_user: failed to open cache\n")); diff -uNr samba-3.0.10.orig/source/nmbd/nmbd_serverlistdb.c samba-3.0.10/source/nmbd/nmbd_serverlistdb.c --- samba-3.0.10.orig/source/nmbd/nmbd_serverlistdb.c 2004-12-17 03:50:09.000000000 -0800 +++ samba-3.0.10/source/nmbd/nmbd_serverlistdb.c 2004-12-17 03:55:29.000000000 -0800 @@ -321,18 +261,27 @@ diff -uNr samba-3.0.23.orig/source/nsswitch/winbindd_cache.c samba-3.0.23/source WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, TDB_DEFAULT /*TDB_CLEAR_IF_FIRST*/, O_RDWR|O_CREAT, 0600); -diff -uNr samba-3.0.10.orig/source/nsswitch/winbindd_util.c samba-3.0.10/source/nsswitch/winbindd_util.c ---- samba-3.0.10.orig/source/nsswitch/winbindd_util.c 2004-12-17 03:50:09.000000000 -0800 -+++ samba-3.0.10/source/nsswitch/winbindd_util.c 2004-12-17 03:55:30.000000000 -0800 -@@ -957,7 +957,7 @@ - SMB_STRUCT_STAT stbuf; - TDB_CONTEXT *idmap_tdb; +@@ -2223,9 +2223,9 @@ + tdb_close(wcache->tdb); + wcache->tdb = NULL; -- pstrcpy(idmap_name, lock_path("winbindd_idmap.tdb")); -+ pstrcpy(idmap_name, state_path("winbindd_idmap.tdb")); +- if (unlink(lock_path("winbindd_cache.tdb")) == -1) { ++ if (unlink(cache_path("winbindd_cache.tdb")) == -1) { + DEBUG(0,("initialize_winbindd_cache: unlink %s failed %s ", +- lock_path("winbindd_cache.tdb"), ++ cache_path("winbindd_cache.tdb"), + strerror(errno) )); + return False; + } +@@ -2487,7 +2487,7 @@ + return; - if (!file_exist(idmap_name, &stbuf)) { - /* nothing to convert return */ + /* when working offline we must not clear the cache on restart */ +- wcache->tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), ++ wcache->tdb = tdb_open_log(cache_path("winbindd_cache.tdb"), + WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, + lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST), + O_RDWR|O_CREAT, 0600); diff -uNr samba-3.0.10.orig/source/param/loadparm.c samba-3.0.10/source/param/loadparm.c --- samba-3.0.10.orig/source/param/loadparm.c 2004-12-17 03:50:09.000000000 -0800 +++ samba-3.0.10/source/param/loadparm.c 2004-12-17 03:55:30.000000000 -0800 @@ -498,18 +447,6 @@ diff -uNr samba-3.0.23.orig/source/lib/sharesec.c samba-3.0.23/source/lib/shares return False; } -diff -uNr samba-3.0.10.orig/source/sam/idmap_tdb.c samba-3.0.10/source/sam/idmap_tdb.c ---- samba-3.0.10.orig/source/sam/idmap_tdb.c 2004-12-17 03:50:09.000000000 -0800 -+++ samba-3.0.10/source/sam/idmap_tdb.c 2004-12-17 03:55:31.000000000 -0800 -@@ -487,7 +487,7 @@ - BOOL tdb_is_new = False; - - /* use the old database if present */ -- tdbfile = SMB_STRDUP(lock_path("winbindd_idmap.tdb")); -+ tdbfile = SMB_STRDUP(state_path("winbindd_idmap.tdb")); - if (!tdbfile) { - DEBUG(0, ("idmap_init: out of memory!\n")); - return NT_STATUS_NO_MEMORY; diff -uNr samba-3.0.23.orig/source/smbd/lanman.c samba-3.0.23/source/smbd/lanman.c --- samba-3.0.23.orig/source/smbd/lanman.c 2006-07-15 09:50:10.000000000 -0400 +++ samba-3.0.23/source/smbd/lanman.c 2006-07-15 09:55:31.000000000 -0400 @@ -525,18 +462,6 @@ diff -uNr samba-3.0.23.orig/source/smbd/lanman.c samba-3.0.23/source/smbd/lanman return 0; } -diff -uNr samba-3.0.10.orig/source/utils/net_idmap.c samba-3.0.10/source/utils/net_idmap.c ---- samba-3.0.10.orig/source/utils/net_idmap.c 2004-12-17 03:50:10.000000000 -0800 -+++ samba-3.0.10/source/utils/net_idmap.c 2004-12-17 03:55:32.000000000 -0800 -@@ -126,7 +126,7 @@ - return NT_STATUS_UNSUCCESSFUL; - } - -- tdbfile = SMB_STRDUP(lock_path("winbindd_idmap.tdb")); -+ tdbfile = SMB_STRDUP(state_path("winbindd_idmap.tdb")); - if (!tdbfile) { - DEBUG(0, ("idmap_init: out of memory!\n")); - return NT_STATUS_NO_MEMORY; diff -uNr samba-3.0.11.orig/source/printing/nt_printing.c samba-3.0.11/source/printing/nt_printing.c --- samba-3.0.11.orig/source/printing/nt_printing.c 2005-03-23 02:51:08.000000000 -0800 +++ samba-3.0.11/source/printing/nt_printing.c 2005-03-23 02:54:33.000000000 -0800 @@ -549,3 +474,92 @@ diff -uNr samba-3.0.11.orig/source/printing/nt_printing.c samba-3.0.11/source/pr pstrcat(printdb_path, sharename); pstrcat(printdb_path, ".tdb"); +diff -uPr samba-3.0.25a.orig/source/groupdb/mapping_tdb.c samba-3.0.25a/source/groupdb/mapping_tdb.c +--- samba-3.0.25a.orig/source/groupdb/mapping_tdb.c 2007-04-25 09:38:59.000000000 +0000 ++++ samba-3.0.25a/source/groupdb/mapping_tdb.c 2007-05-29 00:28:42.000000000 +0000 +@@ -39,7 +39,7 @@ + if (tdb) + return True; + +- tdb = tdb_open_log(lock_path("group_mapping.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); ++ tdb = tdb_open_log(state_path("group_mapping.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); + if (!tdb) { + DEBUG(0,("Failed to open group mapping database\n")); + return False; +diff -uPr samba-3.0.25a.orig/source/lib/account_pol.c samba-3.0.25a/source/lib/account_pol.c +--- samba-3.0.25a.orig/source/lib/account_pol.c 2007-03-01 04:54:30.000000000 +0000 ++++ samba-3.0.25a/source/lib/account_pol.c 2007-05-29 00:21:35.000000000 +0000 +@@ -213,9 +213,9 @@ + return True; + } + +- tdb = tdb_open_log(lock_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600); ++ tdb = tdb_open_log(state_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600); + if (!tdb) { /* the account policies files does not exist or open failed, try to create a new one */ +- tdb = tdb_open_log(lock_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); ++ tdb = tdb_open_log(state_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); + if (!tdb) { + DEBUG(0,("Failed to open account policy database\n")); + return False; +diff -uPr samba-3.0.25a.orig/source/lib/util_unistr.c samba-3.0.25a/source/lib/util_unistr.c +--- samba-3.0.25a.orig/source/lib/util_unistr.c 2007-03-01 04:54:30.000000000 +0000 ++++ samba-3.0.25a/source/lib/util_unistr.c 2007-05-29 00:24:07.000000000 +0000 +@@ -88,11 +88,11 @@ + } + initialised = 1; + +- upcase_table = (smb_ucs2_t *)map_file(lib_path("upcase.dat"), ++ upcase_table = (smb_ucs2_t *)map_file(data_path("upcase.dat"), + 0x20000); + upcase_table_use_unmap = ( upcase_table != NULL ); + +- lowcase_table = (smb_ucs2_t *)map_file(lib_path("lowcase.dat"), ++ lowcase_table = (smb_ucs2_t *)map_file(data_path("lowcase.dat"), + 0x20000); + lowcase_table_use_unmap = ( lowcase_table != NULL ); + +@@ -230,7 +230,7 @@ + return; + } + +- valid_file = (uint8 *)map_file(lib_path("valid.dat"), 0x10000); ++ valid_file = (uint8 *)map_file(data_path("valid.dat"), 0x10000); + if (valid_file) { + valid_table = valid_file; + mapped_file = 1; +diff -uPr samba-3.0.25a.orig/source/libsmb/samlogon_cache.c samba-3.0.25a/source/libsmb/samlogon_cache.c +--- samba-3.0.25a.orig/source/libsmb/samlogon_cache.c 2007-05-10 22:09:35.000000000 +0000 ++++ samba-3.0.25a/source/libsmb/samlogon_cache.c 2007-05-29 00:38:41.000000000 +0000 +@@ -67,7 +67,7 @@ + winbindd_cache.tdb open. Open the tdb if a NULL is passed. */ + + if (!tdb) { +- tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), ++ tdb = tdb_open_log(cache_path("winbindd_cache.tdb"), + WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, + TDB_DEFAULT, O_RDWR, 0600); + if (!tdb) { +diff -uPr samba-3.0.25a.orig/source/nsswitch/idmap_tdb.c samba-3.0.25a/source/nsswitch/idmap_tdb.c +--- samba-3.0.25a.orig/source/nsswitch/idmap_tdb.c 2007-05-10 22:09:34.000000000 +0000 ++++ samba-3.0.25a/source/nsswitch/idmap_tdb.c 2007-05-29 00:27:55.000000000 +0000 +@@ -247,7 +247,7 @@ + } + + /* use the old database if present */ +- tdbfile = talloc_strdup(ctx, lock_path("winbindd_idmap.tdb")); ++ tdbfile = talloc_strdup(ctx, state_path("winbindd_idmap.tdb")); + if (!tdbfile) { + DEBUG(0, ("Out of memory!\n")); + ret = NT_STATUS_NO_MEMORY; +diff -uPr samba-3.0.25a.orig/source/passdb/pdb_tdb.c samba-3.0.25a/source/passdb/pdb_tdb.c +--- samba-3.0.25a.orig/source/passdb/pdb_tdb.c 2007-03-01 04:54:41.000000000 +0000 ++++ samba-3.0.25a/source/passdb/pdb_tdb.c 2007-05-29 00:38:41.000000000 +0000 +@@ -1559,7 +1559,7 @@ + uint32 rid; + BOOL ret = False; + +- tdb = tdb_open_log(lock_path("winbindd_idmap.tdb"), 0, ++ tdb = tdb_open_log(state_path("winbindd_idmap.tdb"), 0, + TDB_DEFAULT, O_RDWR | O_CREAT, 0644); + + if (tdb == NULL) { diff --git a/packaging/Debian/debian-sarge/patches/non-linux-ports.patch b/packaging/Debian/debian-sarge/patches/non-linux-ports.patch index ac2ee1dcf54..2a3f55ed4d4 100644 --- a/packaging/Debian/debian-sarge/patches/non-linux-ports.patch +++ b/packaging/Debian/debian-sarge/patches/non-linux-ports.patch @@ -47,16 +47,18 @@ diff -uNr samba-3.0.11.orig/source/configure.in samba-3.0.11/source/configure.in AC_CACHE_CHECK([for linux sendfile64 support],samba_cv_HAVE_SENDFILE64,[ AC_TRY_LINK([#include ], [\ -@@ -4307,10 +4319,10 @@ +@@ -4307,12 +4319,12 @@ WINBIND_NSS_LDSHFLAGS=$LDSHFLAGS case "$host_os" in - *linux*) + linux*-gnu* | gnu* | k*bsd*-gnu) + NSSSONAMEVERSIONSUFFIX=".2" WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_linux.o" ;; - *freebsd[[5-9]]*) + freebsd5*|*freebsd[[6-9]]*) # FreeBSD winbind client is implemented as a wrapper around # the Linux version. + NSSSONAMEVERSIONSUFFIX=".1" WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_freebsd.o \ diff --git a/packaging/Debian/debian-sarge/patches/samba.patch b/packaging/Debian/debian-sarge/patches/samba.patch index 8e77cfb86e5..d1d443af26f 100644 --- a/packaging/Debian/debian-sarge/patches/samba.patch +++ b/packaging/Debian/debian-sarge/patches/samba.patch @@ -32,11 +32,11 @@ diff -uNr samba-3.0.0beta1.orig/source/web/diagnose.c samba-3.0.0beta1/source/we --- samba-3.0.0beta1.orig/source/web/diagnose.c 2003-06-07 12:57:41.000000000 -0500 +++ samba-3.0.0beta1/source/web/diagnose.c 2003-06-30 20:12:22.000000000 -0500 @@ -66,6 +66,7 @@ - static struct cli_state cli; - extern struct in_addr loopback_ip; + { + struct cli_state *cli; + loopback_ip.s_addr = htonl((127 << 24) + 1); - if (!cli_initialise(&cli)) + if ((cli = cli_initialise()) == NULL) return False; --- samba-3.0.23/source/script/installbin.sh.in.orig 2006-07-15 09:08:36.000000000 -0400 diff --git a/packaging/Debian/debian-sarge/patches/undefined-symbols.patch b/packaging/Debian/debian-sarge/patches/undefined-symbols.patch deleted file mode 100644 index e9a376ea9b8..00000000000 --- a/packaging/Debian/debian-sarge/patches/undefined-symbols.patch +++ /dev/null @@ -1,22 +0,0 @@ -diff -uNr samba-3.0.11.orig/source/Makefile.in samba-3.0.11/source/Makefile.in ---- samba-3.0.11.orig/source/Makefile.in 2005-03-23 02:40:40.000000000 -0800 -+++ samba-3.0.11/source/Makefile.in 2005-03-23 02:48:59.000000000 -0800 -@@ -631,7 +631,8 @@ - $(RPC_ECHO_OBJ) $(SMBLDAP_OBJ) $(IDMAP_OBJ) libsmb/spnego.o $(PASSCHANGE_OBJ) - - WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) \ -- $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ) -+ $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ) \ -+ $(SECRETS_OBJ) - - WINBIND_WINS_NSS_PICOBJS = $(WINBIND_WINS_NSS_OBJ:.o=.@PICSUFFIX@) - -@@ -997,7 +998,7 @@ - - bin/libsmbclient.@SHLIBEXT@: $(LIBSMBCLIENT_PICOBJS) - @echo Linking libsmbclient shared library $@ -- @$(SHLD) $(LDSHFLAGS) -o $@ $(LIBSMBCLIENT_PICOBJS) $(LDFLAGS) $(LIBS) \ -+ @$(SHLD) $(LDSHFLAGS) -Wl,-z,defs -o $@ $(LIBSMBCLIENT_PICOBJS) $(LDFLAGS) $(LIBS) \ - $(KRB5LIBS) $(LDAP_LIBS) \ - @SONAMEFLAG@`basename $@`.$(LIBSMBCLIENT_MAJOR) - diff --git a/source/Makefile.in b/source/Makefile.in index 0da9a8bbc93..ee6d6ed559d 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -162,8 +162,8 @@ TORTURE_PROGS = bin/smbtorture@EXEEXT@ bin/msgtest@EXEEXT@ \ bin/locktest2@EXEEXT@ bin/nsstest@EXEEXT@ bin/vfstest@EXEEXT@ \ bin/pdbtest@EXEEXT@ bin/talloctort@EXEEXT@ bin/replacetort@EXEEXT@ -BIN_PROGS = $(BIN_PROGS1) $(BIN_PROGS2) $(BIN_PROGS3) @EXTRA_BIN_PROGS@ \ - @SMBMOUNT_PROGS@ +BIN_PROGS = @SMBMOUNT_PROGS@ @EXTRA_BIN_PROGS@ \ + $(BIN_PROGS1) $(BIN_PROGS2) $(BIN_PROGS3) EVERYTHING_PROGS = bin/debug2html@EXEEXT@ bin/smbfilter@EXEEXT@ \ bin/talloctort@EXEEXT@ bin/replacetort@EXEEXT@ \ @@ -750,10 +750,10 @@ WINBIND_WINS_NSS_OBJ = nsswitch/wins.o $(PARAM_OBJ) \ $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(NSSWINS_OBJ) $(KRBCLIENT_OBJ) $(SECRETS_OBJ) PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \ - pam_smbpass/pam_smb_acct.o pam_smbpass/support.o \ - $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ + pam_smbpass/pam_smb_acct.o pam_smbpass/support.o +PAM_SMBPASS_OBJ = $(PAM_SMBPASS_OBJ_0) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \ $(SECRETS_OBJ) $(SMBLDAP_OBJ) $(LIBSAMBA_OBJ) \ - $(RPC_PARSE_OBJ1) $(DOSERR_OBJ) + $(RPC_PARSE_OBJ1) $(DOSERR_OBJ) $(ERRORMAP_OBJ) IDMAP_OBJ = nsswitch/idmap.o nsswitch/idmap_cache.o nsswitch/idmap_util.o @IDMAP_STATIC@ diff --git a/source/VERSION b/source/VERSION index 824f9d54a97..7d94b0b2bc1 100644 --- a/source/VERSION +++ b/source/VERSION @@ -36,7 +36,7 @@ SAMBA_VERSION_RELEASE=25 # e.g. SAMBA_VERSION_REVISION=a # # -> "2.2.8a" # ######################################################## -SAMBA_VERSION_REVISION=a +SAMBA_VERSION_REVISION=b ######################################################## # For 'pre' releases the version will be # diff --git a/source/auth/auth_sam.c b/source/auth/auth_sam.c index 847315ef888..80e02c318bd 100644 --- a/source/auth/auth_sam.c +++ b/source/auth/auth_sam.c @@ -163,7 +163,7 @@ static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx, return NT_STATUS_ACCOUNT_EXPIRED; } - if (!(pdb_get_acct_ctrl(sampass) & ACB_PWNOEXP)) { + if (!(pdb_get_acct_ctrl(sampass) & ACB_PWNOEXP) && !(pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)) { time_t must_change_time = pdb_get_pass_must_change_time(sampass); time_t last_set_time = pdb_get_pass_last_set_time(sampass); diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c index 87fb9e55b7b..822a4669d8b 100644 --- a/source/auth/auth_util.c +++ b/source/auth/auth_util.c @@ -1356,6 +1356,10 @@ NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, NTSTATUS status; struct samu *sampass = NULL; gid_t *gids; + char *qualified_name = NULL; + TALLOC_CTX *mem_ctx = NULL; + DOM_SID u_sid; + enum lsa_SidType type; auth_serversupplied_info *result; if ( !(sampass = samu_new( NULL )) ) { @@ -1389,6 +1393,56 @@ NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, return status; } + /* + * The SID returned in server_info->sam_account is based + * on our SAM sid even though for a pure UNIX account this should + * not be the case as it doesn't really exist in the SAM db. + * This causes lookups on "[in]valid users" to fail as they + * will lookup this name as a "Unix User" SID to check against + * the user token. Fix this by adding the "Unix User"\unix_username + * SID to the sid array. The correct fix should probably be + * changing the server_info->sam_account user SID to be a + * S-1-22 Unix SID, but this might break old configs where + * plaintext passwords were used with no SAM backend. + */ + + mem_ctx = talloc_init("make_server_info_pw_tmp"); + if (!mem_ctx) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + qualified_name = talloc_asprintf(mem_ctx, "%s\\%s", + unix_users_domain_name(), + unix_username ); + if (!qualified_name) { + TALLOC_FREE(result); + TALLOC_FREE(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL, + NULL, NULL, + &u_sid, &type)) { + TALLOC_FREE(result); + TALLOC_FREE(mem_ctx); + return NT_STATUS_NO_SUCH_USER; + } + + TALLOC_FREE(mem_ctx); + + if (type != SID_NAME_USER) { + TALLOC_FREE(result); + return NT_STATUS_NO_SUCH_USER; + } + + if (!add_sid_to_array_unique(result, &u_sid, + &result->sids, + &result->num_sids)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + /* For now we throw away the gids and convert via sid_to_gid * later. This needs fixing, but I'd like to get the code straight and * simple first. */ diff --git a/source/client/smbspool.c b/source/client/smbspool.c index 5783cbe1381..a4681e9f615 100644 --- a/source/client/smbspool.c +++ b/source/client/smbspool.c @@ -47,6 +47,7 @@ static void list_devices(void); static struct cli_state *smb_complete_connection(const char *, const char *,int , const char *, const char *, const char *, const char *, int); static struct cli_state *smb_connect(const char *, const char *, int, const char *, const char *, const char *, const char *); static int smb_print(struct cli_state *, char *, FILE *); +static char * uri_unescape_alloc(const char *); /* @@ -62,8 +63,9 @@ static int smb_print(struct cli_state *, char *, FILE *); int port; /* Port number */ char uri[1024], /* URI */ *sep, /* Pointer to separator */ + *tmp, *tmp2, /* Temp pointers to do escaping */ *password; /* Password */ - const char *username, /* Username */ + char *username, /* Username */ *server, /* Server name */ *printer; /* Printer name */ const char *workgroup; /* Workgroup */ @@ -152,19 +154,24 @@ static int smb_print(struct cli_state *, char *, FILE *); if ((sep = strrchr_m(uri, '@')) != NULL) { - username = uri + 6; + tmp = uri + 6; *sep++ = '\0'; + /* username is in tmp */ + server = sep; /* * Extract password as needed... */ - if ((password = strchr_m(username, ':')) != NULL) - *password++ = '\0'; - else + if ((tmp2 = strchr_m(tmp, ':')) != NULL) { + *tmp2++ = '\0'; + password = uri_unescape_alloc(tmp2); + } else { password = null_str; + } + username = uri_unescape_alloc(tmp); } else { @@ -173,16 +180,18 @@ static int smb_print(struct cli_state *, char *, FILE *); server = uri + 6; } - if ((sep = strchr_m(server, '/')) == NULL) + tmp = server; + + if ((sep = strchr_m(tmp, '/')) == NULL) { fputs("ERROR: Bad URI - need printer name!\n", stderr); return (1); } *sep++ = '\0'; - printer = sep; + tmp2 = sep; - if ((sep = strchr_m(printer, '/')) != NULL) + if ((sep = strchr_m(tmp2, '/')) != NULL) { /* * Convert to smb://[username:password@]workgroup/server/printer... @@ -190,12 +199,15 @@ static int smb_print(struct cli_state *, char *, FILE *); *sep++ = '\0'; - workgroup = server; - server = printer; - printer = sep; + workgroup = uri_unescape_alloc(tmp); + server = uri_unescape_alloc(tmp2); + printer = uri_unescape_alloc(sep); } - else + else { workgroup = NULL; + server = uri_unescape_alloc(tmp); + printer = uri_unescape_alloc(tmp2); + } if ((sep = strrchr_m(server, ':')) != NULL) { @@ -203,7 +215,7 @@ static int smb_print(struct cli_state *, char *, FILE *); port=atoi(sep); } - else + else port=0; @@ -588,3 +600,14 @@ smb_print(struct cli_state *cli, /* I - SMB connection */ else return (0); } + +static char *uri_unescape_alloc(const char *uritok) +{ + char *ret; + + ret = (char *)SMB_STRDUP(uritok); + if (!ret) return NULL; + + rfc1738_unescape(ret); + return ret; +} diff --git a/source/include/ads.h b/source/include/ads.h index 40942d339f8..fcaeb2069d2 100644 --- a/source/include/ads.h +++ b/source/include/ads.h @@ -258,7 +258,7 @@ typedef void **ADS_MODLIST; #define ADS_DNS_DOMAIN 0x40000000 /* DomainName is a DNS name */ #define ADS_DNS_FOREST 0x80000000 /* DnsForestName is a DNS name */ -/* DomainCntrollerAddressType */ +/* DomainControllerAddressType */ #define ADS_INET_ADDRESS 0x00000001 #define ADS_NETBIOS_ADDRESS 0x00000002 diff --git a/source/include/doserr.h b/source/include/doserr.h index 3c3978a5b9f..5073cd005c1 100644 --- a/source/include/doserr.h +++ b/source/include/doserr.h @@ -184,6 +184,7 @@ #define WERR_ALREADY_EXISTS W_ERROR(80) #define WERR_BAD_PASSWORD W_ERROR(86) #define WERR_INVALID_PARAM W_ERROR(87) +#define WERR_SEM_TIMEOUT W_ERROR(121) #define WERR_INSUFFICIENT_BUFFER W_ERROR(122) #define WERR_INVALID_NAME W_ERROR(123) #define WERR_UNKNOWN_LEVEL W_ERROR(124) @@ -193,6 +194,7 @@ #define WERR_INVALID_OWNER W_ERROR(1307) #define WERR_IO_PENDING W_ERROR(997) #define WERR_CAN_NOT_COMPLETE W_ERROR(1003) +#define WERR_INVALID_FLAGS W_ERROR(1004) #define WERR_REG_CORRUPT W_ERROR(1015) #define WERR_REG_IO_FAILURE W_ERROR(1016) #define WERR_REG_FILE_INVALID W_ERROR(1017) @@ -214,6 +216,7 @@ #define WERR_JOB_NOT_FOUND W_ERROR(2151) #define WERR_DEST_NOT_FOUND W_ERROR(2152) #define WERR_NOT_LOCAL_DOMAIN W_ERROR(2320) +#define WERR_DOMAIN_CONTROLLER_NOT_FOUND W_ERROR(2453) #define WERR_STATUS_MORE_ENTRIES W_ERROR(0x0105) #define WERR_PRINTER_DRIVER_ALREADY_INSTALLED W_ERROR(ERRdriveralreadyinstalled) diff --git a/source/include/rpc_lsa.h b/source/include/rpc_lsa.h index 28dea219777..1d575c8955d 100644 --- a/source/include/rpc_lsa.h +++ b/source/include/rpc_lsa.h @@ -515,7 +515,7 @@ typedef struct lsa_r_lookup_sids uint32 ptr_dom_ref; DOM_R_REF *dom_ref; /* domain reference info */ - LSA_TRANS_NAME_ENUM *names; + LSA_TRANS_NAME_ENUM names; uint32 mapped_count; NTSTATUS status; /* return code */ @@ -541,7 +541,7 @@ typedef struct lsa_r_lookup_sids2 uint32 ptr_dom_ref; DOM_R_REF *dom_ref; /* domain reference info */ - LSA_TRANS_NAME_ENUM2 *names; + LSA_TRANS_NAME_ENUM2 names; uint32 mapped_count; NTSTATUS status; /* return code */ @@ -566,7 +566,7 @@ typedef struct lsa_r_lookup_sids3 uint32 ptr_dom_ref; DOM_R_REF *dom_ref; /* domain reference info */ - LSA_TRANS_NAME_ENUM2 *names; + LSA_TRANS_NAME_ENUM2 names; uint32 mapped_count; NTSTATUS status; /* return code */ diff --git a/source/include/rpc_netlogon.h b/source/include/rpc_netlogon.h index d2d5cf2fbb4..324755a2659 100644 --- a/source/include/rpc_netlogon.h +++ b/source/include/rpc_netlogon.h @@ -33,14 +33,16 @@ #define NET_SRVPWSET 0x06 #define NET_SAM_DELTAS 0x07 #define NET_LOGON_CTRL 0x0c -#define NET_GETDCNAME 0x0d +#define NET_GETANYDCNAME 0x0d #define NET_AUTH2 0x0f #define NET_LOGON_CTRL2 0x0e #define NET_SAM_SYNC 0x10 #define NET_TRUST_DOM_LIST 0x13 #define NET_DSR_GETDCNAME 0x14 #define NET_AUTH3 0x1a +#define NET_DSR_GETDCNAMEEX 0x1b #define NET_DSR_GETSITENAME 0x1c +#define NET_DSR_GETDCNAMEEX2 0x22 #define NET_SAMLOGON_EX 0x27 /* Secure Channel types. used in NetrServerAuthenticate negotiation */ @@ -417,22 +419,22 @@ typedef struct net_r_logon_ctrl2_info { NTSTATUS status; /* return code */ } NET_R_LOGON_CTRL2; -/* NET_Q_GETDCNAME - Ask a DC for a trusted DC name */ +/* NET_Q_GETANYDCNAME - Ask a DC for a trusted DC name */ -typedef struct net_q_getdcname { +typedef struct net_q_getanydcname { uint32 ptr_logon_server; UNISTR2 uni_logon_server; uint32 ptr_domainname; UNISTR2 uni_domainname; -} NET_Q_GETDCNAME; +} NET_Q_GETANYDCNAME; -/* NET_R_GETDCNAME - Ask a DC for a trusted DC name */ +/* NET_R_GETANYDCNAME - Ask a DC for a trusted DC name */ -typedef struct net_r_getdcname { +typedef struct net_r_getanydcname { uint32 ptr_dcname; UNISTR2 uni_dcname; WERROR status; -} NET_R_GETDCNAME; +} NET_R_GETANYDCNAME; /* NET_Q_TRUST_DOM_LIST - LSA Query Trusted Domains */ typedef struct net_q_trust_dom_info { @@ -1034,7 +1036,63 @@ typedef struct net_r_sam_deltas_info { NTSTATUS status; } NET_R_SAM_DELTAS; -/* NET_Q_DSR_GETDCNAME - Ask a DC for a trusted DC name and its address */ +#define DS_FORCE_REDISCOVERY 0x00000001 +#define DS_DIRECTORY_SERVICE_REQUIRED 0x00000010 +#define DS_DIRECTORY_SERVICE_PREFERRED 0x00000020 +#define DS_GC_SERVER_REQUIRED 0x00000040 +#define DS_PDC_REQUIRED 0x00000080 +#define DS_BACKGROUND_ONLY 0x00000100 +#define DS_IP_REQUIRED 0x00000200 +#define DS_KDC_REQUIRED 0x00000400 +#define DS_TIMESERV_REQUIRED 0x00000800 +#define DS_WRITABLE_REQUIRED 0x00001000 +#define DS_GOOD_TIMESERV_PREFERRED 0x00002000 +#define DS_AVOID_SELF 0x00004000 +#define DS_ONLY_LDAP_NEEDED 0x00008000 + +#define DS_IS_FLAT_NAME 0x00010000 +#define DS_IS_DNS_NAME 0x00020000 + +#define DS_RETURN_DNS_NAME 0x40000000 +#define DS_RETURN_FLAT_NAME 0x80000000 + +#if 0 /* unknown yet */ +#define DS_IP_VERSION_AGNOSTIC +#define DS_TRY_NEXTCLOSEST_SITE +#endif + +#define DSGETDC_VALID_FLAGS ( \ + DS_FORCE_REDISCOVERY | \ + DS_DIRECTORY_SERVICE_REQUIRED | \ + DS_DIRECTORY_SERVICE_PREFERRED | \ + DS_GC_SERVER_REQUIRED | \ + DS_PDC_REQUIRED | \ + DS_BACKGROUND_ONLY | \ + DS_IP_REQUIRED | \ + DS_KDC_REQUIRED | \ + DS_TIMESERV_REQUIRED | \ + DS_WRITABLE_REQUIRED | \ + DS_GOOD_TIMESERV_PREFERRED | \ + DS_AVOID_SELF | \ + DS_ONLY_LDAP_NEEDED | \ + DS_IS_FLAT_NAME | \ + DS_IS_DNS_NAME | \ + DS_RETURN_FLAT_NAME | \ + DS_RETURN_DNS_NAME ) + +struct DS_DOMAIN_CONTROLLER_INFO { + const char *domain_controller_name; + const char *domain_controller_address; + int32 domain_controller_address_type; + struct GUID *domain_guid; + const char *domain_name; + const char *dns_forest_name; + uint32 flags; + const char *dc_site_name; + const char *client_site_name; +}; + +/* NET_Q_DSR_GETDCNAME */ typedef struct net_q_dsr_getdcname { uint32 ptr_server_unc; UNISTR2 uni_server_unc; @@ -1047,7 +1105,7 @@ typedef struct net_q_dsr_getdcname { uint32 flags; } NET_Q_DSR_GETDCNAME; -/* NET_R_DSR_GETDCNAME - Ask a DC for a trusted DC name and its address */ +/* NET_R_DSR_GETDCNAME */ typedef struct net_r_dsr_getdcname { uint32 ptr_dc_unc; UNISTR2 uni_dc_unc; @@ -1067,6 +1125,41 @@ typedef struct net_r_dsr_getdcname { WERROR result; } NET_R_DSR_GETDCNAME; +/* NET_Q_DSR_GETDCNAMEEX */ +typedef struct net_q_dsr_getdcnameex { + uint32 ptr_server_unc; + UNISTR2 uni_server_unc; + uint32 ptr_domain_name; + UNISTR2 uni_domain_name; + uint32 ptr_domain_guid; + struct GUID *domain_guid; + uint32 ptr_site_name; + UNISTR2 uni_site_name; + uint32 flags; +} NET_Q_DSR_GETDCNAMEEX; + +/* NET_R_DSR_GETDCNAMEEX */ +typedef struct NET_R_DSR_GETDCNAME NET_R_DSR_GETDCNAMEEX; + +/* NET_Q_DSR_GETDCNAMEEX2 */ +typedef struct net_q_dsr_getdcnameex2 { + uint32 ptr_server_unc; + UNISTR2 uni_server_unc; + uint32 ptr_client_account; + UNISTR2 uni_client_account; + uint32 mask; + uint32 ptr_domain_name; + UNISTR2 uni_domain_name; + uint32 ptr_domain_guid; + struct GUID *domain_guid; + uint32 ptr_site_name; + UNISTR2 uni_site_name; + uint32 flags; +} NET_Q_DSR_GETDCNAMEEX2; + +/* NET_R_DSR_GETDCNAMEEX */ +typedef struct NET_R_DSR_GETDCNAME NET_R_DSR_GETDCNAMEEX2; + /* NET_Q_DSR_GESITENAME */ typedef struct net_q_dsr_getsitename { uint32 ptr_computer_name; diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c index c102c2185f5..c09e0968c52 100644 --- a/source/lib/smbldap.c +++ b/source/lib/smbldap.c @@ -138,6 +138,7 @@ ATTRIB_MAP_ENTRY attrib_map_to_delete_v30[] = { { LDAP_ATTR_LOGON_TIME, "sambaLogonTime" }, { LDAP_ATTR_LOGOFF_TIME, "sambaLogoffTime" }, { LDAP_ATTR_KICKOFF_TIME, "sambaKickoffTime" }, + { LDAP_ATTR_DISPLAY_NAME, "displayName" }, { LDAP_ATTR_HOME_DRIVE, "sambaHomeDrive" }, { LDAP_ATTR_HOME_PATH, "sambaHomePath" }, { LDAP_ATTR_LOGON_SCRIPT, "sambaLogonScript" }, diff --git a/source/lib/time.c b/source/lib/time.c index ee44f5eb134..a703066248e 100644 --- a/source/lib/time.c +++ b/source/lib/time.c @@ -1111,7 +1111,7 @@ struct timespec timespec_current(void) struct timespec ts; GetTimeOfDay(&tv); ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_sec * 1000; + ts.tv_nsec = tv.tv_usec * 1000; return ts; } diff --git a/source/lib/util_str.c b/source/lib/util_str.c index 1439ac6fcd3..52cdbfceddc 100644 --- a/source/lib/util_str.c +++ b/source/lib/util_str.c @@ -2622,7 +2622,7 @@ size_t utf16_len_n(const void *src, size_t n) of characters. UNIX charset format. *******************************************************************/ -#define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabdefghijklmnopqrstuvwxyz_/ \t.," +#define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.," #define INSIDE_DQUOTE_LIST "$`\n\"\\" char *escape_shell_string(const char *src) diff --git a/source/libads/kerberos.c b/source/libads/kerberos.c index b6627075b02..f703a4cfac7 100644 --- a/source/libads/kerberos.c +++ b/source/libads/kerberos.c @@ -138,7 +138,8 @@ int kerberos_kinit_password_ext(const char *principal, } if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, CONST_DISCARD(char *,password), - kerb_prompter, NULL, 0, NULL, opt))) + kerb_prompter, CONST_DISCARD(char *,password), + 0, NULL, opt))) { smb_krb5_get_init_creds_opt_free(ctx, opt); smb_krb5_free_addresses(ctx, addr); diff --git a/source/libsmb/clifile.c b/source/libsmb/clifile.c index 4f4f4745454..ce2081a81e1 100644 --- a/source/libsmb/clifile.c +++ b/source/libsmb/clifile.c @@ -1692,13 +1692,9 @@ static BOOL cli_get_ea_list(struct cli_state *cli, goto out; } - if (num_eas) { - ea_list = TALLOC_ARRAY(ctx, struct ea_struct, num_eas); - if (!ea_list) { - goto out; - } - } else { - ea_list = NULL; + ea_list = TALLOC_ARRAY(ctx, struct ea_struct, num_eas); + if (!ea_list) { + goto out; } ea_size = (size_t)IVAL(rdata,0); diff --git a/source/libsmb/clireadwrite.c b/source/libsmb/clireadwrite.c index 02fa804f41f..dd7ddcebb55 100644 --- a/source/libsmb/clireadwrite.c +++ b/source/libsmb/clireadwrite.c @@ -413,7 +413,7 @@ ssize_t cli_smbwrite(struct cli_state *cli, p = smb_buf(cli->outbuf); *p++ = 1; SSVAL(p, 0, size); p += 2; - memcpy(p, buf, size); p += size; + memcpy(p, buf + total, size); p += size; cli_setup_bcc(cli, p); diff --git a/source/libsmb/doserr.c b/source/libsmb/doserr.c index 414c2d49168..022d9b62473 100644 --- a/source/libsmb/doserr.c +++ b/source/libsmb/doserr.c @@ -37,6 +37,7 @@ werror_code_struct dos_errs[] = { "WERR_BADFID", WERR_BADFID }, { "WERR_BADFUNC", WERR_BADFUNC }, { "WERR_INSUFFICIENT_BUFFER", WERR_INSUFFICIENT_BUFFER }, + { "WERR_SEM_TIMEOUT", WERR_SEM_TIMEOUT }, { "WERR_NO_SUCH_SHARE", WERR_NO_SUCH_SHARE }, { "WERR_ALREADY_EXISTS", WERR_ALREADY_EXISTS }, { "WERR_INVALID_PARAM", WERR_INVALID_PARAM }, @@ -59,6 +60,7 @@ werror_code_struct dos_errs[] = { "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND }, { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, + { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, { "WERR_STATUS_MORE_ENTRIES ", WERR_STATUS_MORE_ENTRIES }, { "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL }, @@ -67,7 +69,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED }, - { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, + { "WERR_DOMAIN_CONTROLLER_NOT_FOUND", WERR_DOMAIN_CONTROLLER_NOT_FOUND }, { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, @@ -80,6 +82,8 @@ werror_code_struct dos_errs[] = { "WERR_REG_IO_FAILURE", WERR_REG_IO_FAILURE }, { "WERR_REG_FILE_INVALID", WERR_REG_FILE_INVALID }, { "WERR_SERVICE_DISABLED", WERR_SERVICE_DISABLED }, + { "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE}, + { "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS}, { NULL, W_ERROR(0) } }; diff --git a/source/locking/brlock.c b/source/locking/brlock.c index e2afa968061..38f96e78a74 100644 --- a/source/locking/brlock.c +++ b/source/locking/brlock.c @@ -1609,6 +1609,7 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, br_lck->num_locks = data.dsize / sizeof(struct lock_struct); if (!fsp->lockdb_clean) { + int orig_num_locks = br_lck->num_locks; /* This is the first time we've accessed this. */ /* Go through and ensure all entries exist - remove any that don't. */ @@ -1623,6 +1624,11 @@ static struct byte_range_lock *brl_get_locks_internal(TALLOC_CTX *mem_ctx, return NULL; } + /* Ensure invalid locks are cleaned up in the destructor. */ + if (orig_num_locks != br_lck->num_locks) { + br_lck->modified = True; + } + /* * validate_lock_entries might have changed locks. We can't * use a direct pointer here because otherwise gcc warnes diff --git a/source/modules/vfs_catia.c b/source/modules/vfs_catia.c index fe1ce830f7b..870bf626565 100644 --- a/source/modules/vfs_catia.c +++ b/source/modules/vfs_catia.c @@ -222,7 +222,7 @@ static char *catia_realpath(vfs_handle_struct *handle, static size_t catia_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, - struct security_descriptor **ppdesc) + struct security_descriptor_info **ppdesc) { return SMB_VFS_NEXT_GET_NT_ACL(handle, fsp, name, security_info, ppdesc); @@ -230,7 +230,7 @@ static size_t catia_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, static BOOL catia_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, - struct security_descriptor *psd) + struct security_descriptor_info *psd) { return SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, name, security_info_sent, psd); diff --git a/source/nmbd/nmbd_subnetdb.c b/source/nmbd/nmbd_subnetdb.c index 4b04751235d..398119cc829 100644 --- a/source/nmbd/nmbd_subnetdb.c +++ b/source/nmbd/nmbd_subnetdb.c @@ -185,12 +185,28 @@ BOOL create_subnets(void) struct in_addr unicast_ip, ipzero; if(num_interfaces == 0) { + void (*saved_handler)(int); + DEBUG(0,("create_subnets: No local interfaces !\n")); DEBUG(0,("create_subnets: Waiting for an interface to appear ...\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 ); } num_interfaces = iface_count(); diff --git a/source/nmbd/nmbd_winsserver.c b/source/nmbd/nmbd_winsserver.c index 6ea102c3913..c0d21ba42dc 100644 --- a/source/nmbd/nmbd_winsserver.c +++ b/source/nmbd/nmbd_winsserver.c @@ -2140,7 +2140,7 @@ static int wins_processing_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA /* handle records, samba is the wins owner */ if (ip_equal(namerec->data.wins_ip, our_fake_ip)) { - switch (namerec->data.wins_flags | WINS_STATE_MASK) { + switch (namerec->data.wins_flags & WINS_STATE_MASK) { case WINS_ACTIVE: namerec->data.wins_flags&=~WINS_STATE_MASK; namerec->data.wins_flags|=WINS_RELEASED; @@ -2165,7 +2165,7 @@ static int wins_processing_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA goto done; } } else { - switch (namerec->data.wins_flags | WINS_STATE_MASK) { + switch (namerec->data.wins_flags & WINS_STATE_MASK) { case WINS_ACTIVE: /* that's not as MS says it should be */ namerec->data.wins_flags&=~WINS_STATE_MASK; diff --git a/source/nsswitch/idmap.c b/source/nsswitch/idmap.c index 73a30f60874..fd6de933f24 100644 --- a/source/nsswitch/idmap.c +++ b/source/nsswitch/idmap.c @@ -417,7 +417,7 @@ NTSTATUS idmap_init(void) /* check the set_mapping function exists otherwise mark the module as readonly */ if ( ! dom->methods->set_mapping) { - DEBUG(5, ("Forcing to readonly, as ithis module can't store arbitrary mappings.\n")); + DEBUG(5, ("Forcing to readonly, as this module can't store arbitrary mappings.\n")); dom->readonly = True; } diff --git a/source/nsswitch/idmap_ldap.c b/source/nsswitch/idmap_ldap.c index dbec94f5599..ca7d32b3924 100644 --- a/source/nsswitch/idmap_ldap.c +++ b/source/nsswitch/idmap_ldap.c @@ -962,7 +962,7 @@ again: } if ( ! entry) { DEBUG(2, ("ERROR: Unable to fetch ldap entries from results\n")); - continue; + break; } /* first check if the SID is present */ @@ -1177,6 +1177,10 @@ again: } else { /* following ones */ entry = ldap_next_entry(ctx->smbldap_state->ldap_struct, entry); } + if ( ! entry) { + DEBUG(2, ("ERROR: Unable to fetch ldap entries from results\n")); + break; + } /* first check if the SID is present */ sidstr = smbldap_talloc_single_attribute( diff --git a/source/nsswitch/idmap_nss.c b/source/nsswitch/idmap_nss.c index e3e425f105f..fbdd391965c 100644 --- a/source/nsswitch/idmap_nss.c +++ b/source/nsswitch/idmap_nss.c @@ -45,6 +45,10 @@ static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_ma TALLOC_CTX *ctx; int i; + if (! dom->initialized) { + return NT_STATUS_UNSUCCESSFUL; + } + ctx = talloc_new(dom); if ( ! ctx) { DEBUG(0, ("Out of memory!\n")); @@ -131,6 +135,10 @@ static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_ma TALLOC_CTX *ctx; int i; + if (! dom->initialized) { + return NT_STATUS_UNSUCCESSFUL; + } + ctx = talloc_new(dom); if ( ! ctx) { DEBUG(0, ("Out of memory!\n")); diff --git a/source/nsswitch/idmap_passdb.c b/source/nsswitch/idmap_passdb.c index 665ead5bb10..c4533aa3a53 100644 --- a/source/nsswitch/idmap_passdb.c +++ b/source/nsswitch/idmap_passdb.c @@ -43,6 +43,10 @@ static NTSTATUS idmap_pdb_unixids_to_sids(struct idmap_domain *dom, struct id_ma { int i; + if (! dom->initialized) { + return NT_STATUS_UNSUCCESSFUL; + } + for (i = 0; ids[i]; i++) { /* unmapped by default */ @@ -75,6 +79,10 @@ static NTSTATUS idmap_pdb_sids_to_unixids(struct idmap_domain *dom, struct id_ma { int i; + if (! dom->initialized) { + return NT_STATUS_UNSUCCESSFUL; + } + for (i = 0; ids[i]; i++) { enum lsa_SidType type; union unid_t id; diff --git a/source/nsswitch/idmap_rid.c b/source/nsswitch/idmap_rid.c index f7503a4dd67..c6839dca314 100644 --- a/source/nsswitch/idmap_rid.c +++ b/source/nsswitch/idmap_rid.c @@ -43,6 +43,10 @@ static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom) struct idmap_rid_context *ctx; char *config_option = NULL; const char *range; + uid_t low_uid = 0; + uid_t high_uid = 0; + gid_t low_gid = 0; + gid_t high_gid = 0; if ( (ctx = TALLOC_ZERO_P(dom, struct idmap_rid_context)) == NULL ) { DEBUG(0, ("Out of memory!\n")); @@ -65,8 +69,25 @@ static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom) ctx->high_id = 0; } - if ( !ctx->low_id || !ctx->high_id ) { - DEBUG(1, ("ERROR: Invalid configuration, ID range missing\n")); + /* lets see if the range is defined by the old idmap uid/idmap gid */ + if (!ctx->low_id && !ctx->high_id) { + if (lp_idmap_uid(&low_uid, &high_uid)) { + ctx->low_id = low_uid; + ctx->high_id = high_uid; + } + + if (lp_idmap_gid(&low_gid, &high_gid)) { + if ((ctx->low_id != low_gid) || + (ctx->high_id != high_uid)) { + DEBUG(1, ("ERROR: idmap uid irange must match idmap gid range\n")); + ret = NT_STATUS_UNSUCCESSFUL; + goto failed; + } + } + } + + if (!ctx->low_id || !ctx->high_id) { + DEBUG(1, ("ERROR: Invalid configuration, ID range missing or invalid\n")); ret = NT_STATUS_UNSUCCESSFUL; goto failed; } @@ -75,6 +96,7 @@ static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom) ctx->domain_name = talloc_strdup( ctx, dom->name ); dom->private_data = ctx; + dom->initialized = True; talloc_free(config_option); return NT_STATUS_OK; @@ -150,6 +172,14 @@ static NTSTATUS idmap_rid_unixids_to_sids(struct idmap_domain *dom, struct id_ma NTSTATUS ret; int i; + /* Initilization my have been deferred because of an error, retry or fail */ + if ( ! dom->initialized) { + ret = idmap_rid_initialize(dom); + if ( ! NT_STATUS_IS_OK(ret)) { + return ret; + } + } + ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context); ctx = talloc_new(dom); @@ -184,6 +214,14 @@ static NTSTATUS idmap_rid_sids_to_unixids(struct idmap_domain *dom, struct id_ma NTSTATUS ret; int i; + /* Initilization my have been deferred because of an error, retry or fail */ + if ( ! dom->initialized) { + ret = idmap_rid_initialize(dom); + if ( ! NT_STATUS_IS_OK(ret)) { + return ret; + } + } + ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context); ctx = talloc_new(dom); diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c index 59bb04e7d2a..34f04adab2e 100644 --- a/source/nsswitch/winbindd.c +++ b/source/nsswitch/winbindd.c @@ -303,6 +303,9 @@ static void process_request(struct winbindd_cli_state *state) if (state->mem_ctx == NULL) return; + /* Remember who asked us. */ + state->pid = state->request.pid; + /* Process command */ for (table = dispatch_table; table->fn; table++) { diff --git a/source/nsswitch/winbindd_cm.c b/source/nsswitch/winbindd_cm.c index 010d38fde97..92119022290 100644 --- a/source/nsswitch/winbindd_cm.c +++ b/source/nsswitch/winbindd_cm.c @@ -557,8 +557,8 @@ static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain, orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000); - werr = rpccli_netlogon_getdcname(netlogon_pipe, mem_ctx, our_domain->dcname, - domain->name, tmp); + werr = rpccli_netlogon_getanydcname(netlogon_pipe, mem_ctx, our_domain->dcname, + domain->name, tmp); /* And restore our original timeout. */ cli_set_timeout(netlogon_pipe->cli, orig_timeout); @@ -566,12 +566,12 @@ static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain, talloc_destroy(mem_ctx); if (!W_ERROR_IS_OK(werr)) { - DEBUG(10, ("rpccli_netlogon_getdcname failed: %s\n", + DEBUG(10, ("rpccli_netlogon_getanydcname failed: %s\n", dos_errstr(werr))); return False; } - /* cli_netlogon_getdcname gives us a name with \\ */ + /* cli_netlogon_getanydcname gives us a name with \\ */ p = tmp; if (*p == '\\') { p+=1; @@ -582,7 +582,7 @@ static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain, fstrcpy(dcname, p); - DEBUG(10, ("rpccli_netlogon_getdcname returned %s\n", dcname)); + DEBUG(10, ("rpccli_netlogon_getanydcname returned %s\n", dcname)); if (!resolve_name(dcname, dc_ip, 0x20)) { return False; diff --git a/source/nsswitch/winbindd_dual.c b/source/nsswitch/winbindd_dual.c index 8d475e6c9f9..169ea5e6882 100644 --- a/source/nsswitch/winbindd_dual.c +++ b/source/nsswitch/winbindd_dual.c @@ -96,6 +96,7 @@ struct winbindd_async_request { struct winbindd_request *request; struct winbindd_response *response; void (*continuation)(void *private_data, BOOL success); + struct timed_event *reply_timeout_event; void *private_data; }; @@ -160,8 +161,40 @@ static void async_main_request_sent(void *private_data, BOOL success) async_request_sent, state); } +/**************************************************************** + Handler triggered if the child winbindd doesn't respond within + a given timeout. +****************************************************************/ + +static void async_request_timeout_handler(struct event_context *ctx, + struct timed_event *te, + const struct timeval *now, + void *private_data) +{ + struct winbindd_async_request *state = + talloc_get_type_abort(private_data, struct winbindd_async_request); + + /* Deal with the reply - set to error. */ + + async_reply_recv(private_data, False); + + DEBUG(0,("async_request_timeout_handler: child pid %u is not responding. " + "Closing connection to it.\n", + state->child->pid )); + + /* Send kill signal to child. */ + kill(state->child->pid, SIGTERM); + + /* + * Close the socket to the child. + */ + + winbind_child_died(state->child->pid); +} + static void async_request_sent(void *private_data_data, BOOL success) { + uint32_t timeout = 30; struct winbindd_async_request *state = talloc_get_type_abort(private_data_data, struct winbindd_async_request); @@ -180,6 +213,33 @@ static void async_request_sent(void *private_data_data, BOOL success) &state->response->result, sizeof(state->response->result), async_reply_recv, state); + + /* + * Normal timeouts are 30s, but auth requests may take a long + * time to timeout. + */ + + if (state->request->cmd == WINBINDD_PAM_AUTH || + state->request->cmd == WINBINDD_PAM_AUTH_CRAP ) { + + timeout = 300; + } + + /* + * Set up a timeout of 30 seconds for the response. + * If we don't get it close the child socket and + * report failure. + */ + + state->reply_timeout_event = event_add_timed(winbind_event_context(), + NULL, + timeval_current_ofs(timeout,0), + "async_request_timeout", + async_request_timeout_handler, + state); + if (!state->reply_timeout_event) { + smb_panic("async_request_sent: failed to add timeout handler.\n"); + } } static void async_reply_recv(void *private_data, BOOL success) @@ -188,6 +248,10 @@ static void async_reply_recv(void *private_data, BOOL success) talloc_get_type_abort(private_data, struct winbindd_async_request); struct winbindd_child *child = state->child; + if (state->reply_timeout_event) { + TALLOC_FREE(state->reply_timeout_event); + } + state->response->length = sizeof(struct winbindd_response); if (!success) { diff --git a/source/nsswitch/winbindd_misc.c b/source/nsswitch/winbindd_misc.c index f5363cad1a2..1aa3c7c398a 100644 --- a/source/nsswitch/winbindd_misc.c +++ b/source/nsswitch/winbindd_misc.c @@ -216,9 +216,9 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000); - werr = rpccli_netlogon_getdcname(netlogon_pipe, state->mem_ctx, domain->dcname, - state->request.domain_name, - dcname_slash); + werr = rpccli_netlogon_getanydcname(netlogon_pipe, state->mem_ctx, domain->dcname, + state->request.domain_name, + dcname_slash); /* And restore our original timeout. */ cli_set_timeout(netlogon_pipe->cli, orig_timeout); diff --git a/source/pam_smbpass/general.h b/source/pam_smbpass/general.h index f84c2544440..781581aaf55 100644 --- a/source/pam_smbpass/general.h +++ b/source/pam_smbpass/general.h @@ -113,7 +113,7 @@ static const SMB_Ctrls smb_args[SMB_CTRLS_] = { struct _pam_failed_auth { char *user; /* user that's failed to be authenticated */ - int id; /* uid of requested user */ + uid_t id; /* uid of requested user */ char *agent; /* attempt from user with name */ int count; /* number of failures so far */ }; diff --git a/source/rpc_client/cli_lsarpc.c b/source/rpc_client/cli_lsarpc.c index b31f7fc064d..4dfce181430 100644 --- a/source/rpc_client/cli_lsarpc.c +++ b/source/rpc_client/cli_lsarpc.c @@ -181,7 +181,6 @@ NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, LSA_Q_LOOKUP_SIDS q; LSA_R_LOOKUP_SIDS r; DOM_R_REF ref; - LSA_TRANS_NAME_ENUM t_names; NTSTATUS result = NT_STATUS_OK; int i; @@ -191,10 +190,8 @@ NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, init_q_lookup_sids(mem_ctx, &q, pol, num_sids, sids, 1); ZERO_STRUCT(ref); - ZERO_STRUCT(t_names); r.dom_ref = &ref; - r.names = &t_names; CLI_DO_RPC( cli, mem_ctx, PI_LSARPC, LSA_LOOKUPSIDS, q, r, @@ -245,7 +242,7 @@ NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, for (i = 0; i < num_sids; i++) { fstring name, dom_name; - uint32 dom_idx = t_names.name[i].domain_idx; + uint32 dom_idx = r.names.name[i].domain_idx; /* Translate optimised name through domain index array */ @@ -254,11 +251,11 @@ NTSTATUS rpccli_lsa_lookup_sids(struct rpc_pipe_client *cli, rpcstr_pull_unistr2_fstring( dom_name, &ref.ref_dom[dom_idx].uni_dom_name); rpcstr_pull_unistr2_fstring( - name, &t_names.uni_name[i]); + name, &r.names.uni_name[i]); (*names)[i] = talloc_strdup(mem_ctx, name); (*domains)[i] = talloc_strdup(mem_ctx, dom_name); - (*types)[i] = t_names.name[i].sid_name_use; + (*types)[i] = r.names.name[i].sid_name_use; if (((*names)[i] == NULL) || ((*domains)[i] == NULL)) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c index 7296c45ebc4..13a31e81d45 100644 --- a/source/rpc_client/cli_netlogon.c +++ b/source/rpc_client/cli_netlogon.c @@ -380,15 +380,15 @@ NTSTATUS rpccli_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, TALLOC_CTX *me return result; } -/* GetDCName */ +/* GetAnyDCName */ -WERROR rpccli_netlogon_getdcname(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, const char *mydcname, - const char *domainname, fstring newdcname) +WERROR rpccli_netlogon_getanydcname(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, const char *mydcname, + const char *domainname, fstring newdcname) { prs_struct qbuf, rbuf; - NET_Q_GETDCNAME q; - NET_R_GETDCNAME r; + NET_Q_GETANYDCNAME q; + NET_R_GETANYDCNAME r; WERROR result; fstring mydcname_slash; @@ -398,15 +398,15 @@ WERROR rpccli_netlogon_getdcname(struct rpc_pipe_client *cli, /* Initialise input parameters */ slprintf(mydcname_slash, sizeof(fstring)-1, "\\\\%s", mydcname); - init_net_q_getdcname(&q, mydcname_slash, domainname); + init_net_q_getanydcname(&q, mydcname_slash, domainname); /* Marshall data and send request */ - CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_GETDCNAME, + CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_GETANYDCNAME, q, r, qbuf, rbuf, - net_io_q_getdcname, - net_io_r_getdcname, + net_io_q_getanydcname, + net_io_r_getanydcname, WERR_GENERAL_FAILURE); result = r.status; @@ -418,6 +418,91 @@ WERROR rpccli_netlogon_getdcname(struct rpc_pipe_client *cli, return result; } +static WERROR pull_domain_controller_info_from_getdcname_reply(TALLOC_CTX *mem_ctx, + struct DS_DOMAIN_CONTROLLER_INFO **info_out, + NET_R_DSR_GETDCNAME *r) +{ + struct DS_DOMAIN_CONTROLLER_INFO *info; + + info = TALLOC_ZERO_P(mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO); + if (!info) { + return WERR_NOMEM; + } + + if (&r->uni_dc_unc) { + + char *tmp; + tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_unc); + if (tmp == NULL) { + return WERR_GENERAL_FAILURE; + } + if (*tmp == '\\') tmp += 1; + if (*tmp == '\\') tmp += 1; + + info->domain_controller_name = talloc_strdup(mem_ctx, tmp); + if (info->domain_controller_name == NULL) { + return WERR_GENERAL_FAILURE; + } + } + + if (&r->uni_dc_address) { + + char *tmp; + tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_address); + if (tmp == NULL) { + return WERR_GENERAL_FAILURE; + } + if (*tmp == '\\') tmp += 1; + if (*tmp == '\\') tmp += 1; + + info->domain_controller_address = talloc_strdup(mem_ctx, tmp); + if (info->domain_controller_address == NULL) { + return WERR_GENERAL_FAILURE; + } + } + + info->domain_controller_address_type = r->dc_address_type; + + info->domain_guid = talloc_memdup(mem_ctx, &r->domain_guid, sizeof(struct GUID)); + if (!info->domain_guid) { + return WERR_GENERAL_FAILURE; + } + + if (&r->uni_domain_name) { + info->domain_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_domain_name); + if (!info->domain_name) { + return WERR_GENERAL_FAILURE; + } + } + + if (&r->uni_forest_name) { + info->dns_forest_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_forest_name); + if (!info->dns_forest_name) { + return WERR_GENERAL_FAILURE; + } + } + + info->flags = r->dc_flags; + + if (&r->uni_dc_site_name) { + info->dc_site_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_site_name); + if (!info->dc_site_name) { + return WERR_GENERAL_FAILURE; + } + } + + if (&r->uni_client_site_name) { + info->client_site_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_client_site_name); + if (!info->client_site_name) { + return WERR_GENERAL_FAILURE; + } + } + + *info_out = info; + + return WERR_OK; +} + /* Dsr_GetDCName */ WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli, @@ -427,14 +512,7 @@ WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli, struct GUID *domain_guid, struct GUID *site_guid, uint32_t flags, - char **dc_unc, char **dc_address, - int32 *dc_address_type, - struct GUID *domain_guid_out, - char **domain_name_out, - char **forest_name, - uint32 *dc_flags, - char **dc_site_name, - char **client_site_name) + struct DS_DOMAIN_CONTROLLER_INFO **info_out) { prs_struct qbuf, rbuf; NET_Q_DSR_GETDCNAME q; @@ -467,79 +545,117 @@ WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli, return r.result; } - if (dc_unc != NULL) { - char *tmp; - tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r.uni_dc_unc); - if (tmp == NULL) { - return WERR_GENERAL_FAILURE; - } - if (*tmp == '\\') tmp += 1; - if (*tmp == '\\') tmp += 1; - - /* We have to talloc_strdup, otherwise a talloc_steal would - fail */ - *dc_unc = talloc_strdup(mem_ctx, tmp); - if (*dc_unc == NULL) { - return WERR_NOMEM; - } + r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r); + if (!W_ERROR_IS_OK(r.result)) { + return r.result; } - if (dc_address != NULL) { - char *tmp; - tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r.uni_dc_address); - if (tmp == NULL) { - return WERR_GENERAL_FAILURE; - } - if (*tmp == '\\') tmp += 1; - if (*tmp == '\\') tmp += 1; + return WERR_OK; +} - /* We have to talloc_strdup, otherwise a talloc_steal would - fail */ - *dc_address = talloc_strdup(mem_ctx, tmp); - if (*dc_address == NULL) { - return WERR_NOMEM; - } - } +/* Dsr_GetDCNameEx */ - if (dc_address_type != NULL) { - *dc_address_type = r.dc_address_type; - } +WERROR rpccli_netlogon_dsr_getdcnameex(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *server_name, + const char *domain_name, + struct GUID *domain_guid, + const char *site_name, + uint32_t flags, + struct DS_DOMAIN_CONTROLLER_INFO **info_out) +{ + prs_struct qbuf, rbuf; + NET_Q_DSR_GETDCNAMEEX q; + NET_R_DSR_GETDCNAME r; + char *tmp_str; - if (domain_guid_out != NULL) { - *domain_guid_out = r.domain_guid; + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialize input parameters */ + + tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name); + if (tmp_str == NULL) { + return WERR_NOMEM; } - if ((domain_name_out != NULL) && - ((*domain_name_out = rpcstr_pull_unistr2_talloc( - mem_ctx, &r.uni_domain_name)) == NULL)) { - return WERR_GENERAL_FAILURE; + init_net_q_dsr_getdcnameex(&q, server_name, domain_name, domain_guid, + site_name, flags); + + /* Marshall data and send request */ + + CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAMEEX, + q, r, + qbuf, rbuf, + net_io_q_dsr_getdcnameex, + net_io_r_dsr_getdcname, + WERR_GENERAL_FAILURE); + + if (!W_ERROR_IS_OK(r.result)) { + return r.result; } - if ((forest_name != NULL) && - ((*forest_name = rpcstr_pull_unistr2_talloc( - mem_ctx, &r.uni_forest_name)) == NULL)) { - return WERR_GENERAL_FAILURE; + r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r); + if (!W_ERROR_IS_OK(r.result)) { + return r.result; } - if (dc_flags != NULL) { - *dc_flags = r.dc_flags; + return WERR_OK; +} + +/* Dsr_GetDCNameEx */ + +WERROR rpccli_netlogon_dsr_getdcnameex2(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const char *server_name, + const char *client_account, + uint32 mask, + const char *domain_name, + struct GUID *domain_guid, + const char *site_name, + uint32_t flags, + struct DS_DOMAIN_CONTROLLER_INFO **info_out) +{ + prs_struct qbuf, rbuf; + NET_Q_DSR_GETDCNAMEEX2 q; + NET_R_DSR_GETDCNAME r; + char *tmp_str; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialize input parameters */ + + tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name); + if (tmp_str == NULL) { + return WERR_NOMEM; } - if ((dc_site_name != NULL) && - ((*dc_site_name = rpcstr_pull_unistr2_talloc( - mem_ctx, &r.uni_dc_site_name)) == NULL)) { - return WERR_GENERAL_FAILURE; + init_net_q_dsr_getdcnameex2(&q, server_name, domain_name, client_account, + mask, domain_guid, site_name, flags); + + /* Marshall data and send request */ + + CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAMEEX2, + q, r, + qbuf, rbuf, + net_io_q_dsr_getdcnameex2, + net_io_r_dsr_getdcname, + WERR_GENERAL_FAILURE); + + if (!W_ERROR_IS_OK(r.result)) { + return r.result; } - if ((client_site_name != NULL) && - ((*client_site_name = rpcstr_pull_unistr2_talloc( - mem_ctx, &r.uni_client_site_name)) == NULL)) { - return WERR_GENERAL_FAILURE; + r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r); + if (!W_ERROR_IS_OK(r.result)) { + return r.result; } return WERR_OK; } + /* Dsr_GetSiteName */ WERROR rpccli_netlogon_dsr_getsitename(struct rpc_pipe_client *cli, diff --git a/source/rpc_parse/parse_lsa.c b/source/rpc_parse/parse_lsa.c index 0add8b2bb0c..0c07e7fe221 100644 --- a/source/rpc_parse/parse_lsa.c +++ b/source/rpc_parse/parse_lsa.c @@ -1476,7 +1476,7 @@ BOOL lsa_io_r_lookup_sids(const char *desc, LSA_R_LOOKUP_SIDS *r_s, if(!lsa_io_dom_r_ref ("dom_ref", r_s->dom_ref, ps, depth)) /* domain reference info */ return False; - if(!lsa_io_trans_names("names ", r_s->names, ps, depth)) /* translated names */ + if(!lsa_io_trans_names("names ", &r_s->names, ps, depth)) /* translated names */ return False; if(!prs_align(ps)) @@ -1511,7 +1511,7 @@ BOOL lsa_io_r_lookup_sids2(const char *desc, LSA_R_LOOKUP_SIDS2 *r_s, if(!lsa_io_dom_r_ref ("dom_ref", r_s->dom_ref, ps, depth)) /* domain reference info */ return False; - if(!lsa_io_trans_names2("names ", r_s->names, ps, depth)) /* translated names */ + if(!lsa_io_trans_names2("names ", &r_s->names, ps, depth)) /* translated names */ return False; if(!prs_align(ps)) @@ -1547,7 +1547,7 @@ BOOL lsa_io_r_lookup_sids3(const char *desc, LSA_R_LOOKUP_SIDS3 *r_s, if(!lsa_io_dom_r_ref ("dom_ref", r_s->dom_ref, ps, depth)) /* domain reference info */ return False; - if(!lsa_io_trans_names2("names ", r_s->names, ps, depth)) /* translated names */ + if(!lsa_io_trans_names2("names ", &r_s->names, ps, depth)) /* translated names */ return False; if(!prs_align(ps)) diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c index 93e3dc16eb1..5837ee6fd84 100644 --- a/source/rpc_parse/parse_net.c +++ b/source/rpc_parse/parse_net.c @@ -480,12 +480,12 @@ BOOL net_io_r_logon_ctrl(const char *desc, NET_R_LOGON_CTRL *r_l, prs_struct *ps } /******************************************************************* - Inits an NET_R_GETDCNAME structure. + Inits an NET_R_GETANYDCNAME structure. ********************************************************************/ -void init_net_q_getdcname(NET_Q_GETDCNAME *r_t, const char *logon_server, - const char *domainname) +void init_net_q_getanydcname(NET_Q_GETANYDCNAME *r_t, const char *logon_server, + const char *domainname) { - DEBUG(5,("init_q_getdcname\n")); + DEBUG(5,("init_q_getanydcname\n")); r_t->ptr_logon_server = (logon_server != NULL); init_unistr2(&r_t->uni_logon_server, logon_server, UNI_STR_TERMINATE); @@ -494,16 +494,16 @@ void init_net_q_getdcname(NET_Q_GETDCNAME *r_t, const char *logon_server, } /******************************************************************* - Reads or writes an NET_Q_GETDCNAME structure. + Reads or writes an NET_Q_GETANYDCNAME structure. ********************************************************************/ -BOOL net_io_q_getdcname(const char *desc, NET_Q_GETDCNAME *r_t, prs_struct *ps, - int depth) +BOOL net_io_q_getanydcname(const char *desc, NET_Q_GETANYDCNAME *r_t, prs_struct *ps, + int depth) { if (r_t == NULL) return False; - prs_debug(ps, depth, desc, "net_io_q_getdcname"); + prs_debug(ps, depth, desc, "net_io_q_getanydcname"); depth++; if (!prs_uint32("ptr_logon_server", ps, depth, &r_t->ptr_logon_server)) @@ -528,26 +528,26 @@ BOOL net_io_q_getdcname(const char *desc, NET_Q_GETDCNAME *r_t, prs_struct *ps, /******************************************************************* - Inits an NET_R_GETDCNAME structure. + Inits an NET_R_GETANYDCNAME structure. ********************************************************************/ -void init_net_r_getdcname(NET_R_GETDCNAME *r_t, const char *dcname) +void init_net_r_getanydcname(NET_R_GETANYDCNAME *r_t, const char *dcname) { - DEBUG(5,("init_r_getdcname\n")); + DEBUG(5,("init_r_getanydcname\n")); init_unistr2(&r_t->uni_dcname, dcname, UNI_STR_TERMINATE); } /******************************************************************* - Reads or writes an NET_R_GETDCNAME structure. + Reads or writes an NET_R_GETANYDCNAME structure. ********************************************************************/ -BOOL net_io_r_getdcname(const char *desc, NET_R_GETDCNAME *r_t, prs_struct *ps, - int depth) +BOOL net_io_r_getanydcname(const char *desc, NET_R_GETANYDCNAME *r_t, prs_struct *ps, + int depth) { if (r_t == NULL) return False; - prs_debug(ps, depth, desc, "net_io_r_getdcname"); + prs_debug(ps, depth, desc, "net_io_r_getanydcname"); depth++; if (!prs_uint32("ptr_dcname", ps, depth, &r_t->ptr_dcname)) @@ -3332,6 +3332,67 @@ void init_net_q_dsr_getdcname(NET_Q_DSR_GETDCNAME *r_t, const char *server_unc, r_t->flags = flags; } +/******************************************************************* + Inits a NET_Q_DSR_GETDCNAMEEX structure. +********************************************************************/ + +void init_net_q_dsr_getdcnameex(NET_Q_DSR_GETDCNAMEEX *r_t, const char *server_unc, + const char *domain_name, + struct GUID *domain_guid, + const char *site_name, + uint32_t flags) +{ + DEBUG(5, ("init_net_q_dsr_getdcnameex\n")); + + r_t->ptr_server_unc = (server_unc != NULL); + init_unistr2(&r_t->uni_server_unc, server_unc, UNI_STR_TERMINATE); + + r_t->ptr_domain_name = (domain_name != NULL); + init_unistr2(&r_t->uni_domain_name, domain_name, UNI_STR_TERMINATE); + + r_t->ptr_domain_guid = (domain_guid != NULL); + r_t->domain_guid = domain_guid; + + r_t->ptr_site_name = (site_name != NULL); + init_unistr2(&r_t->uni_site_name, site_name, UNI_STR_TERMINATE); + + r_t->flags = flags; +} + +/******************************************************************* + Inits a NET_Q_DSR_GETDCNAMEEX2 structure. +********************************************************************/ + +void init_net_q_dsr_getdcnameex2(NET_Q_DSR_GETDCNAMEEX2 *r_t, const char *server_unc, + const char *domain_name, + const char *client_account, + uint32 mask, + struct GUID *domain_guid, + const char *site_name, + uint32_t flags) +{ + DEBUG(5, ("init_net_q_dsr_getdcnameex2\n")); + + r_t->ptr_server_unc = (server_unc != NULL); + init_unistr2(&r_t->uni_server_unc, server_unc, UNI_STR_TERMINATE); + + r_t->ptr_client_account = (client_account != NULL); + init_unistr2(&r_t->uni_client_account, client_account, UNI_STR_TERMINATE); + + r_t->mask = mask; + + r_t->ptr_domain_name = (domain_name != NULL); + init_unistr2(&r_t->uni_domain_name, domain_name, UNI_STR_TERMINATE); + + r_t->ptr_domain_guid = (domain_guid != NULL); + r_t->domain_guid = domain_guid; + + r_t->ptr_site_name = (site_name != NULL); + init_unistr2(&r_t->uni_site_name, site_name, UNI_STR_TERMINATE); + + r_t->flags = flags; +} + /******************************************************************* Reads or writes an NET_Q_DSR_GETDCNAME structure. ********************************************************************/ @@ -3403,6 +3464,154 @@ BOOL net_io_q_dsr_getdcname(const char *desc, NET_Q_DSR_GETDCNAME *r_t, return True; } +/******************************************************************* + Reads or writes an NET_Q_DSR_GETDCNAMEEX structure. +********************************************************************/ + +BOOL net_io_q_dsr_getdcnameex(const char *desc, NET_Q_DSR_GETDCNAMEEX *r_t, + prs_struct *ps, int depth) +{ + if (r_t == NULL) + return False; + + prs_debug(ps, depth, desc, "net_io_q_dsr_getdcnameex"); + depth++; + + if (!prs_uint32("ptr_server_unc", ps, depth, &r_t->ptr_server_unc)) + return False; + + if (!smb_io_unistr2("server_unc", &r_t->uni_server_unc, + r_t->ptr_server_unc, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("ptr_domain_name", ps, depth, &r_t->ptr_domain_name)) + return False; + + if (!smb_io_unistr2("domain_name", &r_t->uni_domain_name, + r_t->ptr_domain_name, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("ptr_domain_guid", ps, depth, &r_t->ptr_domain_guid)) + return False; + + if (UNMARSHALLING(ps) && (r_t->ptr_domain_guid)) { + r_t->domain_guid = PRS_ALLOC_MEM(ps, struct GUID, 1); + if (r_t->domain_guid == NULL) + return False; + } + + if ((r_t->ptr_domain_guid) && + (!smb_io_uuid("domain_guid", r_t->domain_guid, ps, depth))) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("ptr_site_name", ps, depth, &r_t->ptr_site_name)) + return False; + + if (!smb_io_unistr2("site_name", &r_t->uni_site_name, + r_t->ptr_site_name, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("flags", ps, depth, &r_t->flags)) + return False; + + return True; +} + +/******************************************************************* + Reads or writes an NET_Q_DSR_GETDCNAMEEX2 structure. +********************************************************************/ + +BOOL net_io_q_dsr_getdcnameex2(const char *desc, NET_Q_DSR_GETDCNAMEEX2 *r_t, + prs_struct *ps, int depth) +{ + if (r_t == NULL) + return False; + + prs_debug(ps, depth, desc, "net_io_q_dsr_getdcnameex2"); + depth++; + + if (!prs_uint32("ptr_server_unc", ps, depth, &r_t->ptr_server_unc)) + return False; + + if (!smb_io_unistr2("server_unc", &r_t->uni_server_unc, + r_t->ptr_server_unc, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("ptr_client_account", ps, depth, &r_t->ptr_client_account)) + return False; + + if (!smb_io_unistr2("client_account", &r_t->uni_client_account, + r_t->ptr_client_account, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("mask", ps, depth, &r_t->mask)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("ptr_domain_name", ps, depth, &r_t->ptr_domain_name)) + return False; + + if (!smb_io_unistr2("domain_name", &r_t->uni_domain_name, + r_t->ptr_domain_name, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("ptr_domain_guid", ps, depth, &r_t->ptr_domain_guid)) + return False; + + if (UNMARSHALLING(ps) && (r_t->ptr_domain_guid)) { + r_t->domain_guid = PRS_ALLOC_MEM(ps, struct GUID, 1); + if (r_t->domain_guid == NULL) + return False; + } + + if ((r_t->ptr_domain_guid) && + (!smb_io_uuid("domain_guid", r_t->domain_guid, ps, depth))) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("ptr_site_name", ps, depth, &r_t->ptr_site_name)) + return False; + + if (!smb_io_unistr2("site_name", &r_t->uni_site_name, + r_t->ptr_site_name, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("flags", ps, depth, &r_t->flags)) + return False; + + return True; +} + + + /******************************************************************* Inits a NET_R_DSR_GETDCNAME structure. ********************************************************************/ diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c index 0254abf791e..be3d9e8b886 100644 --- a/source/rpc_parse/parse_prs.c +++ b/source/rpc_parse/parse_prs.c @@ -1094,6 +1094,9 @@ BOOL prs_string2(BOOL charmode, const char *name, prs_struct *ps, int depth, STR return False; } else { str->buffer = NULL; + /* Return early to ensure Coverity isn't confused. */ + DEBUG(5,("%s%04x %s: \n", tab_depth(depth), ps->data_offset, name)); + return True; } } diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c index 00490fe798c..38141515dc1 100644 --- a/source/rpc_parse/parse_spoolss.c +++ b/source/rpc_parse/parse_spoolss.c @@ -7026,10 +7026,10 @@ static BOOL spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, data_offset, current_offset; const uint32 basic_unit = 20; /* size of static portion of enum_values */ - + prs_debug(ps, depth, desc, "spoolss_io_printer_enum_values_ctr"); depth++; - + /* * offset data begins at 20 bytes per structure * size_of_array. * Don't forget the uint32 at the beginning @@ -7046,10 +7046,29 @@ static BOOL spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, } for (i=0; isize_of_array; i++) { + uint32 base_offset, return_offset; + + base_offset = prs_offset(ps); + valuename_offset = current_offset; if (!prs_uint32("valuename_offset", ps, depth, &valuename_offset)) return False; + /* Read or write the value. */ + + return_offset = prs_offset(ps); + + if (!prs_set_offset(ps, base_offset + valuename_offset)) { + return False; + } + + if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename)) + return False; + + /* And go back. */ + if (!prs_set_offset(ps, return_offset)) + return False; + if (!prs_uint32("value_len", ps, depth, &ctr->values[i].value_len)) return False; @@ -7064,21 +7083,14 @@ static BOOL spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, if (!prs_uint32("data_len", ps, depth, &ctr->values[i].data_len)) return False; - current_offset = data_offset + ctr->values[i].data_len - basic_unit; - /* account for 2 byte alignment */ - current_offset += (current_offset % 2); - } + /* Read or write the data. */ - /* - * loop #2 for writing the dynamically size objects; pay - * attention to 2-byte alignment here.... - */ - - for (i=0; isize_of_array; i++) { - - if (!prs_unistr("valuename", ps, depth, &ctr->values[i].valuename)) + return_offset = prs_offset(ps); + + if (!prs_set_offset(ps, base_offset + data_offset)) { return False; - + } + if ( ctr->values[i].data_len ) { if ( UNMARSHALLING(ps) ) { ctr->values[i].data = PRS_ALLOC_MEM(ps, uint8, ctr->values[i].data_len); @@ -7088,11 +7100,30 @@ static BOOL spoolss_io_printer_enum_values_ctr(const char *desc, prs_struct *ps, if (!prs_uint8s(False, "data", ps, depth, ctr->values[i].data, ctr->values[i].data_len)) return False; } - - if ( !prs_align_uint16(ps) ) + + current_offset = data_offset + ctr->values[i].data_len - basic_unit; + /* account for 2 byte alignment */ + current_offset += (current_offset % 2); + + /* Remember how far we got. */ + data_offset = prs_offset(ps); + + /* And go back. */ + if (!prs_set_offset(ps, return_offset)) return False; + } + /* Go to the last data offset we got to. */ + + if (!prs_set_offset(ps, data_offset)) + return False; + + /* And ensure we're 2 byte aligned. */ + + if ( !prs_align_uint16(ps) ) + return False; + return True; } diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c index ff35e61e263..7a47cedf4a5 100644 --- a/source/rpc_server/srv_lsa_nt.c +++ b/source/rpc_server/srv_lsa_nt.c @@ -380,12 +380,10 @@ static void init_reply_lookup_names4(LSA_R_LOOKUP_NAMES4 *r_l, static void init_reply_lookup_sids2(LSA_R_LOOKUP_SIDS2 *r_l, DOM_R_REF *ref, - LSA_TRANS_NAME_ENUM2 *names, uint32 mapped_count) { r_l->ptr_dom_ref = ref ? 1 : 0; r_l->dom_ref = ref; - r_l->names = names; r_l->mapped_count = mapped_count; } @@ -395,12 +393,10 @@ static void init_reply_lookup_sids2(LSA_R_LOOKUP_SIDS2 *r_l, static void init_reply_lookup_sids3(LSA_R_LOOKUP_SIDS3 *r_l, DOM_R_REF *ref, - LSA_TRANS_NAME_ENUM2 *names, uint32 mapped_count) { r_l->ptr_dom_ref = ref ? 1 : 0; r_l->dom_ref = ref; - r_l->names = names; r_l->mapped_count = mapped_count; } @@ -414,11 +410,7 @@ static NTSTATUS init_reply_lookup_sids(TALLOC_CTX *mem_ctx, LSA_TRANS_NAME_ENUM2 *names, uint32 mapped_count) { - LSA_TRANS_NAME_ENUM *oldnames = TALLOC_ZERO_P(mem_ctx, LSA_TRANS_NAME_ENUM); - - if (!oldnames) { - return NT_STATUS_NO_MEMORY; - } + LSA_TRANS_NAME_ENUM *oldnames = &r_l->names; oldnames->num_entries = names->num_entries; oldnames->ptr_trans_names = names->ptr_trans_names; @@ -428,7 +420,7 @@ static NTSTATUS init_reply_lookup_sids(TALLOC_CTX *mem_ctx, if (names->num_entries) { int i; - oldnames->name = TALLOC_ARRAY(oldnames, LSA_TRANS_NAME, names->num_entries); + oldnames->name = TALLOC_ARRAY(mem_ctx, LSA_TRANS_NAME, names->num_entries); if (!oldnames->name) { return NT_STATUS_NO_MEMORY; @@ -442,7 +434,6 @@ static NTSTATUS init_reply_lookup_sids(TALLOC_CTX *mem_ctx, r_l->ptr_dom_ref = ref ? 1 : 0; r_l->dom_ref = ref; - r_l->names = oldnames; r_l->mapped_count = mapped_count; return NT_STATUS_OK; } @@ -811,13 +802,12 @@ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, int num_sids, /* input */ const DOM_SID2 *sid, /* input */ DOM_R_REF **pp_ref, /* output */ - LSA_TRANS_NAME_ENUM2 **pp_names, /* output */ + LSA_TRANS_NAME_ENUM2 *names, /* input/output */ uint32 *pp_mapped_count) { NTSTATUS status; int i; const DOM_SID **sids = NULL; - LSA_TRANS_NAME_ENUM2 *names = NULL; DOM_R_REF *ref = NULL; uint32 mapped_count = 0; struct lsa_dom_info *dom_infos = NULL; @@ -825,17 +815,16 @@ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, *pp_mapped_count = 0; *pp_ref = NULL; - *pp_names = NULL; + ZERO_STRUCTP(names); if (num_sids == 0) { return NT_STATUS_OK; } - names = TALLOC_ZERO_P(p->mem_ctx, LSA_TRANS_NAME_ENUM2); sids = TALLOC_ARRAY(p->mem_ctx, const DOM_SID *, num_sids); ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF); - if (sids == NULL || names == NULL || ref == NULL) { + if (sids == NULL || ref == NULL) { return NT_STATUS_NO_MEMORY; } @@ -850,8 +839,8 @@ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, return status; } - names->name = TALLOC_ARRAY(names, LSA_TRANS_NAME2, num_sids); - names->uni_name = TALLOC_ARRAY(names, UNISTR2, num_sids); + names->name = TALLOC_ARRAY(p->mem_ctx, LSA_TRANS_NAME2, num_sids); + names->uni_name = TALLOC_ARRAY(p->mem_ctx, UNISTR2, num_sids); if ((names->name == NULL) || (names->uni_name == NULL)) { return NT_STATUS_NO_MEMORY; } @@ -903,7 +892,6 @@ static NTSTATUS _lsa_lookup_sids_internal(pipes_struct *p, *pp_mapped_count = mapped_count; *pp_ref = ref; - *pp_names = names; return status; } @@ -920,7 +908,7 @@ NTSTATUS _lsa_lookup_sids(pipes_struct *p, int num_sids = q_u->sids.num_entries; uint32 mapped_count = 0; DOM_R_REF *ref = NULL; - LSA_TRANS_NAME_ENUM2 *names = NULL; + LSA_TRANS_NAME_ENUM2 names; NTSTATUS status; if ((q_u->level < 1) || (q_u->level > 6)) { @@ -952,7 +940,7 @@ NTSTATUS _lsa_lookup_sids(pipes_struct *p, /* Convert from LSA_TRANS_NAME_ENUM2 to LSA_TRANS_NAME_ENUM */ - status = init_reply_lookup_sids(p->mem_ctx, r_u, ref, names, mapped_count); + status = init_reply_lookup_sids(p->mem_ctx, r_u, ref, &names, mapped_count); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -971,7 +959,6 @@ NTSTATUS _lsa_lookup_sids2(pipes_struct *p, int num_sids = q_u->sids.num_entries; uint32 mapped_count = 0; DOM_R_REF *ref = NULL; - LSA_TRANS_NAME_ENUM2 *names = NULL; if ((q_u->level < 1) || (q_u->level > 6)) { return NT_STATUS_INVALID_PARAMETER; @@ -997,10 +984,10 @@ NTSTATUS _lsa_lookup_sids2(pipes_struct *p, num_sids, q_u->sids.sid, &ref, - &names, + &r_u->names, &mapped_count); - init_reply_lookup_sids2(r_u, ref, names, mapped_count); + init_reply_lookup_sids2(r_u, ref, mapped_count); return r_u->status; } @@ -1015,7 +1002,6 @@ NTSTATUS _lsa_lookup_sids3(pipes_struct *p, int num_sids = q_u->sids.num_entries; uint32 mapped_count = 0; DOM_R_REF *ref = NULL; - LSA_TRANS_NAME_ENUM2 *names = NULL; if ((q_u->level < 1) || (q_u->level > 6)) { return NT_STATUS_INVALID_PARAMETER; @@ -1039,10 +1025,10 @@ NTSTATUS _lsa_lookup_sids3(pipes_struct *p, num_sids, q_u->sids.sid, &ref, - &names, + &r_u->names, &mapped_count); - init_reply_lookup_sids3(r_u, ref, names, mapped_count); + init_reply_lookup_sids3(r_u, ref, mapped_count); return r_u->status; } diff --git a/source/rpcclient/cmd_netlogon.c b/source/rpcclient/cmd_netlogon.c index f199a4a0f2c..c6ace9ae541 100644 --- a/source/rpcclient/cmd_netlogon.c +++ b/source/rpcclient/cmd_netlogon.c @@ -45,9 +45,9 @@ static NTSTATUS cmd_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, return result; } -static WERROR cmd_netlogon_getdcname(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, int argc, - const char **argv) +static WERROR cmd_netlogon_getanydcname(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) { fstring dcname; WERROR result = WERR_GENERAL_FAILURE; @@ -57,7 +57,7 @@ static WERROR cmd_netlogon_getdcname(struct rpc_pipe_client *cli, return WERR_OK; } - result = rpccli_netlogon_getdcname(cli, mem_ctx, cli->cli->desthost, argv[1], dcname); + result = rpccli_netlogon_getanydcname(cli, mem_ctx, cli->cli->desthost, argv[1], dcname); if (!W_ERROR_IS_OK(result)) goto done; @@ -70,35 +70,205 @@ static WERROR cmd_netlogon_getdcname(struct rpc_pipe_client *cli, return result; } +static void display_ds_domain_controller_info(TALLOC_CTX *mem_ctx, const struct DS_DOMAIN_CONTROLLER_INFO *info) +{ + d_printf("domain_controller_name: %s\n", info->domain_controller_name); + d_printf("domain_controller_address: %s\n", info->domain_controller_address); + d_printf("domain_controller_address_type: %d\n", info->domain_controller_address_type); + d_printf("domain_guid: %s\n", GUID_string(mem_ctx, info->domain_guid)); + d_printf("domain_name: %s\n", info->domain_name); + d_printf("dns_forest_name: %s\n", info->dns_forest_name); + d_printf("flags: 0x%08x\n" + "\tIs a PDC: %s\n" + "\tIs a GC of the forest: %s\n" + "\tIs an LDAP server: %s\n" + "\tSupports DS: %s\n" + "\tIs running a KDC: %s\n" + "\tIs running time services: %s\n" + "\tIs the closest DC: %s\n" + "\tIs writable: %s\n" + "\tHas a hardware clock: %s\n" + "\tIs a non-domain NC serviced by LDAP server: %s\n" + "\tDomainControllerName is a DNS name: %s\n" + "\tDomainName is a DNS name: %s\n" + "\tDnsForestName is a DNS name: %s\n", + info->flags, + (info->flags & ADS_PDC) ? "yes" : "no", + (info->flags & ADS_GC) ? "yes" : "no", + (info->flags & ADS_LDAP) ? "yes" : "no", + (info->flags & ADS_DS) ? "yes" : "no", + (info->flags & ADS_KDC) ? "yes" : "no", + (info->flags & ADS_TIMESERV) ? "yes" : "no", + (info->flags & ADS_CLOSEST) ? "yes" : "no", + (info->flags & ADS_WRITABLE) ? "yes" : "no", + (info->flags & ADS_GOOD_TIMESERV) ? "yes" : "no", + (info->flags & ADS_NDNC) ? "yes" : "no", + (info->flags & ADS_DNS_CONTROLLER) ? "yes":"no", + (info->flags & ADS_DNS_DOMAIN) ? "yes":"no", + (info->flags & ADS_DNS_FOREST) ? "yes":"no"); + + d_printf("dc_site_name: %s\n", info->dc_site_name); + d_printf("client_site_name: %s\n", info->client_site_name); +} + static WERROR cmd_netlogon_dsr_getdcname(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) { WERROR result; - char *dcname, *dcaddress; - - if (argc != 2) { - fprintf(stderr, "Usage: %s domainname\n", argv[0]); + uint32 flags = DS_RETURN_DNS_NAME; + const char *server_name = cli->cli->desthost; + const char *domain_name; + struct GUID domain_guid = GUID_zero(); + struct GUID site_guid = GUID_zero(); + struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + + if (argc < 2) { + fprintf(stderr, "Usage: %s [domainname] [domain_name] [domain_guid] [site_guid] [flags]\n", argv[0]); return WERR_OK; } - result = rpccli_netlogon_dsr_getdcname( - cli, mem_ctx, cli->cli->desthost, argv[1], NULL, NULL, - 0x40000000, &dcname, &dcaddress, NULL, NULL, NULL, NULL, - NULL, NULL, NULL); + if (argc >= 2) + domain_name = argv[1]; + + if (argc >= 3) { + if (!NT_STATUS_IS_OK(GUID_from_string(argv[2], &domain_guid))) { + return WERR_NOMEM; + } + } + + if (argc >= 4) { + if (!NT_STATUS_IS_OK(GUID_from_string(argv[3], &site_guid))) { + return WERR_NOMEM; + } + } + + if (argc >= 5) + sscanf(argv[4], "%x", &flags); + + result = rpccli_netlogon_dsr_getdcname(cli, mem_ctx, server_name, domain_name, + &domain_guid, &site_guid, flags, + &info); if (W_ERROR_IS_OK(result)) { - printf("Domain %s's DC is called %s at IP %s\n", - argv[1], dcname, dcaddress); + d_printf("DsGetDcName gave\n"); + display_ds_domain_controller_info(mem_ctx, info); return WERR_OK; } printf("rpccli_netlogon_dsr_getdcname returned %s\n", - nt_errstr(werror_to_ntstatus(result))); + dos_errstr(result)); + + return result; +} + +static WERROR cmd_netlogon_dsr_getdcnameex(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + WERROR result; + uint32 flags = DS_RETURN_DNS_NAME; + const char *server_name = cli->cli->desthost; + const char *domain_name; + const char *site_name = NULL; + struct GUID domain_guid = GUID_zero(); + struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + + if (argc < 2) { + fprintf(stderr, "Usage: %s [domainname] [domain_name] [domain_guid] [site_name] [flags]\n", argv[0]); + return WERR_OK; + } + + if (argc >= 2) + domain_name = argv[1]; + + if (argc >= 3) { + if (!NT_STATUS_IS_OK(GUID_from_string(argv[2], &domain_guid))) { + return WERR_NOMEM; + } + } + + if (argc >= 4) + site_name = argv[3]; + + if (argc >= 5) + sscanf(argv[4], "%x", &flags); + + result = rpccli_netlogon_dsr_getdcnameex(cli, mem_ctx, server_name, domain_name, + &domain_guid, site_name, flags, + &info); + + if (W_ERROR_IS_OK(result)) { + d_printf("DsGetDcNameEx gave\n"); + display_ds_domain_controller_info(mem_ctx, info); + return WERR_OK; + } + + printf("rpccli_netlogon_dsr_getdcnameex returned %s\n", + dos_errstr(result)); + + return result; +} + +static WERROR cmd_netlogon_dsr_getdcnameex2(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + WERROR result; + uint32 flags = DS_RETURN_DNS_NAME; + const char *server_name = cli->cli->desthost; + const char *domain_name; + const char *client_account = NULL; + uint32 mask = 0; + const char *site_name = NULL; + struct GUID domain_guid = GUID_zero(); + struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + + if (argc < 2) { + fprintf(stderr, "Usage: %s [domainname] [client_account] [acb_mask] [domain_name] [domain_guid] [site_name] [flags]\n", argv[0]); + return WERR_OK; + } + + if (argc >= 2) + client_account = argv[1]; + + if (argc >= 3) + mask = atoi(argv[2]); + + if (argc >= 4) + domain_name = argv[3]; + + if (argc >= 5) { + if (!NT_STATUS_IS_OK(GUID_from_string(argv[4], &domain_guid))) { + return WERR_NOMEM; + } + } + + if (argc >= 6) + site_name = argv[5]; + + if (argc >= 7) + sscanf(argv[6], "%x", &flags); + + result = rpccli_netlogon_dsr_getdcnameex2(cli, mem_ctx, server_name, + client_account, mask, + domain_name, &domain_guid, + site_name, flags, + &info); + + if (W_ERROR_IS_OK(result)) { + d_printf("DsGetDcNameEx2 gave\n"); + display_ds_domain_controller_info(mem_ctx, info); + return WERR_OK; + } + + printf("rpccli_netlogon_dsr_getdcnameex2 returned %s\n", + dos_errstr(result)); return result; } + static WERROR cmd_netlogon_dsr_getsitename(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, const char **argv) @@ -372,8 +542,10 @@ struct cmd_set netlogon_commands[] = { { "NETLOGON" }, { "logonctrl2", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl2, NULL, PI_NETLOGON, NULL, "Logon Control 2", "" }, - { "getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getdcname, PI_NETLOGON, NULL, "Get trusted DC name", "" }, + { "getanydcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getanydcname, PI_NETLOGON, NULL, "Get trusted DC name", "" }, { "dsr_getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcname, PI_NETLOGON, NULL, "Get trusted DC name", "" }, + { "dsr_getdcnameex", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcnameex, PI_NETLOGON, NULL, "Get trusted DC name", "" }, + { "dsr_getdcnameex2", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcnameex2, PI_NETLOGON, NULL, "Get trusted DC name", "" }, { "dsr_getsitename", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getsitename, PI_NETLOGON, NULL, "Get sitename", "" }, { "logonctrl", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl, NULL, PI_NETLOGON, NULL, "Logon Control", "" }, { "samsync", RPC_RTYPE_NTSTATUS, cmd_netlogon_sam_sync, NULL, PI_NETLOGON, NULL, "Sam Synchronisation", "" }, diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c index e40bda08c2d..f671e892a0f 100644 --- a/source/rpcclient/rpcclient.c +++ b/source/rpcclient/rpcclient.c @@ -107,9 +107,9 @@ static char **completion_fn(const char *text, int start, int end) return matches; } -static char* next_command (char** cmdstr) +static char *next_command (char **cmdstr) { - static pstring command; + char *command; char *p; if (!cmdstr || !(*cmdstr)) @@ -118,7 +118,7 @@ static char* next_command (char** cmdstr) p = strchr_m(*cmdstr, ';'); if (p) *p = '\0'; - pstrcpy(command, *cmdstr); + command = SMB_STRDUP(*cmdstr); if (p) *cmdstr = p + 1; else @@ -828,6 +828,7 @@ out_free: while((cmd=next_command(&p)) != NULL) { NTSTATUS cmd_result = process_cmd(cli, cmd); + SAFE_FREE(cmd); result = NT_STATUS_IS_ERR(cmd_result); } diff --git a/source/smbd/aio.c b/source/smbd/aio.c index 8a9fabf2286..2559dc95057 100644 --- a/source/smbd/aio.c +++ b/source/smbd/aio.c @@ -497,6 +497,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) ret = errno; } else { BOOL write_through = BITSETW(aio_ex->inbuf+smb_vwv7,0); + NTSTATUS status; SSVAL(outbuf,smb_vwv2,nwritten); SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1); @@ -507,7 +508,13 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) DEBUG(3,("handle_aio_write: fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten)); - sync_file(fsp->conn,fsp, write_through); + status = sync_file(fsp->conn,fsp, write_through); + if (!NT_STATUS_IS_OK(status)) { + UNIXERROR(ERRHRD,ERRdiskfull); + ret = errno; + DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n", + fsp->fsp_name, nt_errstr(status) )); + } } show_msg(outbuf); diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c index 65238c0e9ee..1227d12b08e 100644 --- a/source/smbd/fileio.c +++ b/source/smbd/fileio.c @@ -834,16 +834,23 @@ ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason) sync a file ********************************************************************/ -void sync_file(connection_struct *conn, files_struct *fsp, BOOL write_through) +NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, BOOL write_through) { if (fsp->fh->fd == -1) - return; + return NT_STATUS_INVALID_HANDLE; if (lp_strict_sync(SNUM(conn)) && (lp_syncalways(SNUM(conn)) || write_through)) { - flush_write_cache(fsp, SYNC_FLUSH); - SMB_VFS_FSYNC(fsp,fsp->fh->fd); + int ret = flush_write_cache(fsp, SYNC_FLUSH); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + ret = SMB_VFS_FSYNC(fsp,fsp->fh->fd); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } } + return NT_STATUS_OK; } /************************************************************ diff --git a/source/smbd/notify.c b/source/smbd/notify.c index d6a2fe76927..7b831c2f560 100644 --- a/source/smbd/notify.c +++ b/source/smbd/notify.c @@ -27,7 +27,6 @@ struct notify_change_request { struct files_struct *fsp; /* backpointer for cancel by mid */ char request_buf[smb_size]; uint32 filter; - uint32 max_param_count; uint32 current_bufsize; struct notify_mid_map *mid_map; void *backend_data; @@ -126,12 +125,12 @@ static void change_notify_reply_packet(const char *request_buf, "failed."); } -void change_notify_reply(const char *request_buf, uint32 max_param_count, +void change_notify_reply(const char *request_buf, struct notify_change_buf *notify_buf) { char *outbuf = NULL; prs_struct ps; - size_t buflen = smb_size+38+max_param_count; + size_t buflen; if (notify_buf->num_changes == -1) { change_notify_reply_packet(request_buf, NT_STATUS_OK); @@ -145,14 +144,7 @@ void change_notify_reply(const char *request_buf, uint32 max_param_count, goto done; } - if (prs_offset(&ps) > max_param_count) { - /* - * We exceed what the client is willing to accept. Send - * nothing. - */ - change_notify_reply_packet(request_buf, NT_STATUS_OK); - goto done; - } + buflen = smb_size+38+prs_offset(&ps) + 4 /* padding */; if (!(outbuf = SMB_MALLOC_ARRAY(char, buflen))) { change_notify_reply_packet(request_buf, NT_STATUS_NO_MEMORY); @@ -214,7 +206,7 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter, return status; } -NTSTATUS change_notify_add_request(const char *inbuf, uint32 max_param_count, +NTSTATUS change_notify_add_request(const char *inbuf, uint32 filter, BOOL recursive, struct files_struct *fsp) { @@ -231,7 +223,6 @@ NTSTATUS change_notify_add_request(const char *inbuf, uint32 max_param_count, map->req = request; memcpy(request->request_buf, inbuf, sizeof(request->request_buf)); - request->max_param_count = max_param_count; request->current_bufsize = 0; request->filter = filter; request->fsp = fsp; @@ -408,7 +399,6 @@ static void notify_fsp(files_struct *fsp, uint32 action, const char *name) */ change_notify_reply(fsp->notify->requests->request_buf, - fsp->notify->requests->max_param_count, fsp->notify); change_notify_remove_request(fsp->notify->requests); diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c index 40d323c75cf..6da1bba8b9b 100644 --- a/source/smbd/nttrans.c +++ b/source/smbd/nttrans.c @@ -414,7 +414,7 @@ static int do_ntcreate_pipe_open(connection_struct *conn, p += 4; if (flags & EXTENDED_RESPONSE_REQUIRED) { - p += 26; + p += 25; SIVAL(p,0,FILE_GENERIC_ALL); /* * For pipes W2K3 seems to return @@ -944,7 +944,7 @@ int reply_ntcreate_and_X(connection_struct *conn, if (flags & EXTENDED_RESPONSE_REQUIRED) { uint32 perms = 0; - p += 26; + p += 25; if (fsp->is_directory || can_write_to_file(conn, fname, &sbuf)) { perms = FILE_GENERIC_ALL; } else { @@ -1029,7 +1029,7 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha p += 4; if (flags & EXTENDED_RESPONSE_REQUIRED) { - p += 26; + p += 25; SIVAL(p,0,FILE_GENERIC_ALL); /* * For pipes W2K3 seems to return @@ -1625,7 +1625,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o if (flags & EXTENDED_RESPONSE_REQUIRED) { uint32 perms = 0; - p += 26; + p += 25; if (fsp->is_directory || can_write_to_file(conn, fname, &sbuf)) { perms = FILE_GENERIC_ALL; } else { @@ -1979,8 +1979,7 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, * here. */ - change_notify_reply(inbuf, max_param_count, - fsp->notify); + change_notify_reply(inbuf, fsp->notify); /* * change_notify_reply() above has independently sent its @@ -1993,8 +1992,7 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf, * No changes pending, queue the request */ - status = change_notify_add_request(inbuf, max_param_count, filter, - recursive, fsp); + status = change_notify_add_request(inbuf, filter, recursive, fsp); if (!NT_STATUS_IS_OK(status)) { return ERROR_NT(status); } diff --git a/source/smbd/open.c b/source/smbd/open.c index 7bfeeb8b7e8..0a6be4c79fd 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -1652,10 +1652,33 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, return NT_STATUS_SHARING_VIOLATION; } + /* First pass - send break only on batch oplocks. */ + if (delay_for_oplocks(lck, fsp, 1, oplock_request)) { + schedule_defer_open(lck, request_time); + TALLOC_FREE(lck); + fd_close(conn, fsp); + file_free(fsp); + return NT_STATUS_SHARING_VIOLATION; + } + status = open_mode_check(conn, fname, lck, access_mask, share_access, create_options, &file_existed); + if (NT_STATUS_IS_OK(status)) { + /* We might be going to allow this open. Check oplock + * status again. */ + /* Second pass - send break for both batch or + * exclusive oplocks. */ + if (delay_for_oplocks(lck, fsp, 2, oplock_request)) { + schedule_defer_open(lck, request_time); + TALLOC_FREE(lck); + fd_close(conn, fsp); + file_free(fsp); + return NT_STATUS_SHARING_VIOLATION; + } + } + if (!NT_STATUS_IS_OK(status)) { struct deferred_open_record state; diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 6e9aa65dded..99c3b478e47 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -2743,6 +2743,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, BOOL write_through; files_struct *fsp = file_fsp(inbuf,smb_vwv0); int outsize = 0; + NTSTATUS status; START_PROFILE(SMBwritebraw); if (srv_is_signing_active()) { @@ -2847,7 +2848,13 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, SSVAL(outbuf,smb_vwv0,total_written); - sync_file(conn, fsp, write_through); + status = sync_file(conn, fsp, write_through); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n", + fsp->fsp_name, nt_errstr(status) )); + END_PROFILE(SMBwritebraw); + return ERROR_NT(status); + } DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n", fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written)); @@ -2912,7 +2919,13 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, nwritten = write_file(fsp,data,startpos,numtowrite); } - sync_file(conn, fsp, False /* write through */); + status = sync_file(conn, fsp, False /* write through */); + if (!NT_STATUS_IS_OK(status)) { + END_PROFILE(SMBwriteunlock); + DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n", + fsp->fsp_name, nt_errstr(status) )); + return ERROR_NT(status); + } if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { END_PROFILE(SMBwriteunlock); @@ -2958,6 +2971,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d char *data; files_struct *fsp = file_fsp(inbuf,smb_vwv0); int outsize = 0; + NTSTATUS status; START_PROFILE(SMBwrite); /* If it's an IPC, pass off the pipe handler. */ @@ -2968,6 +2982,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d CHECK_FSP(fsp,conn); if (!CHECK_WRITE(fsp)) { + END_PROFILE(SMBwrite); return(ERROR_DOS(ERRDOS,ERRbadaccess)); } @@ -3003,7 +3018,13 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d } else nwritten = write_file(fsp,data,startpos,numtowrite); - sync_file(conn, fsp, False); + status = sync_file(conn, fsp, False); + if (!NT_STATUS_IS_OK(status)) { + END_PROFILE(SMBwrite); + DEBUG(5,("reply_write: sync_file for %s returned %s\n", + fsp->fsp_name, nt_errstr(status) )); + return ERROR_NT(status); + } if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) { END_PROFILE(SMBwrite); @@ -3040,6 +3061,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng unsigned int smblen = smb_len(inbuf); char *data; BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF)); + NTSTATUS status; START_PROFILE(SMBwriteX); /* If it's an IPC, pass off the pipe handler. */ @@ -3130,7 +3152,13 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten)); - sync_file(conn, fsp, write_through); + status = sync_file(conn, fsp, write_through); + if (!NT_STATUS_IS_OK(status)) { + END_PROFILE(SMBwriteX); + DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n", + fsp->fsp_name, nt_errstr(status) )); + return ERROR_NT(status); + } END_PROFILE(SMBwriteX); return chain_reply(inbuf,outbuf,length,bufsize); @@ -3227,7 +3255,13 @@ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int if (!fsp) { file_sync_all(conn); } else { - sync_file(conn,fsp, True); + NTSTATUS status = sync_file(conn, fsp, True); + if (!NT_STATUS_IS_OK(status)) { + END_PROFILE(SMBflush); + DEBUG(5,("reply_flush: sync_file for %s returned %s\n", + fsp->fsp_name, nt_errstr(status) )); + return ERROR_NT(status); + } } DEBUG(3,("flush\n")); @@ -4586,8 +4620,6 @@ NTSTATUS rename_internals(connection_struct *conn, */ if (strcsequal(directory, newname)) { - rename_open_files(conn, NULL, sbuf1.st_dev, - sbuf1.st_ino, newname); DEBUG(3, ("rename_internals: identical names in " "rename %s - returning success\n", directory)); @@ -4719,8 +4751,6 @@ NTSTATUS rename_internals(connection_struct *conn, } if (strcsequal(fname,destname)) { - rename_open_files(conn, NULL, sbuf1.st_dev, - sbuf1.st_ino, newname); DEBUG(3,("rename_internals: identical names " "in wildcard rename %s - success\n", fname)); @@ -5835,6 +5865,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int smb_doff; char *data; files_struct *fsp = file_fsp(inbuf,smb_vwv0); + NTSTATUS status; START_PROFILE(SMBwriteBmpx); CHECK_FSP(fsp,conn); @@ -5864,7 +5895,13 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, nwritten = write_file(fsp,data,startpos,numtowrite); - sync_file(conn, fsp, write_through); + status = sync_file(conn, fsp, write_through); + if (!NT_STATUS_IS_OK(status)) { + END_PROFILE(SMBwriteBmpx); + DEBUG(5,("reply_writebmpx: sync_file for %s returned %s\n", + fsp->fsp_name, nt_errstr(status) )); + return ERROR_NT(status); + } if(nwritten < (ssize_t)numtowrite) { END_PROFILE(SMBwriteBmpx); @@ -5940,6 +5977,7 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz write_bmpx_struct *wbms; BOOL send_response = False; files_struct *fsp = file_fsp(inbuf,smb_vwv0); + NTSTATUS status; START_PROFILE(SMBwriteBs); CHECK_FSP(fsp,conn); @@ -5976,9 +6014,9 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz nwritten = write_file(fsp,data,startpos,numtowrite); - sync_file(conn, fsp, write_through); + status = sync_file(conn, fsp, write_through); - if (nwritten < (ssize_t)numtowrite) { + if (nwritten < (ssize_t)numtowrite || !NT_STATUS_IS_OK(status)) { if(write_through) { /* We are returning an error - we can delete the aux struct */ if (wbms) diff --git a/source/tdb/common/traverse.c b/source/tdb/common/traverse.c index 6d3b111479c..03c208fc290 100644 --- a/source/tdb/common/traverse.c +++ b/source/tdb/common/traverse.c @@ -263,12 +263,15 @@ TDB_DATA tdb_firstkey(struct tdb_context *tdb) tdb->travlocks.off = tdb->travlocks.hash = 0; tdb->travlocks.lock_rw = F_RDLCK; + /* Grab first record: locks chain and returned record. */ if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0) return tdb_null; /* now read the key */ key.dsize = rec.key_len; key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize); - if (tdb_unlock(tdb, BUCKET(tdb->travlocks.hash), F_WRLCK) != 0) + + /* Unlock the hash chain of the record we just read. */ + if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_firstkey: error occurred while tdb_unlocking!\n")); return key; } @@ -283,7 +286,7 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) /* Is locked key the old key? If so, traverse will be reliable. */ if (tdb->travlocks.off) { - if (tdb_lock(tdb,tdb->travlocks.hash,F_WRLCK)) + if (tdb_lock(tdb,tdb->travlocks.hash,tdb->travlocks.lock_rw)) return tdb_null; if (tdb_rec_read(tdb, tdb->travlocks.off, &rec) == -1 || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec), @@ -294,7 +297,7 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) SAFE_FREE(k); return tdb_null; } - if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0) { + if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) { SAFE_FREE(k); return tdb_null; } @@ -306,7 +309,7 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) if (!tdb->travlocks.off) { /* No previous element: do normal find, and lock record */ - tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), F_WRLCK, &rec); + tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), tdb->travlocks.lock_rw, &rec); if (!tdb->travlocks.off) return tdb_null; tdb->travlocks.hash = BUCKET(rec.full_hash); @@ -324,12 +327,11 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey) key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec), key.dsize); /* Unlock the chain of this new record */ - if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0) + if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); } /* Unlock the chain of old record */ - if (tdb_unlock(tdb, BUCKET(oldhash), F_WRLCK) != 0) + if (tdb_unlock(tdb, BUCKET(oldhash), tdb->travlocks.lock_rw) != 0) TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n")); return key; } - diff --git a/source/torture/denytest.c b/source/torture/denytest.c index 2dc5c2b634f..99cbaee0158 100644 --- a/source/torture/denytest.c +++ b/source/torture/denytest.c @@ -1515,7 +1515,7 @@ BOOL torture_denytest2(int dummy) enum deny_result res; const char *fname = fnames[denytable2[i].isexe]; - progress_bar(i, ARRAY_SIZE(denytable1)); + progress_bar(i, ARRAY_SIZE(denytable2)); fnum1 = cli_open(cli1, fname, denytable2[i].mode1, diff --git a/source/utils/pdbedit.c b/source/utils/pdbedit.c index 078eae71ac2..82e5934165a 100644 --- a/source/utils/pdbedit.c +++ b/source/utils/pdbedit.c @@ -624,28 +624,25 @@ static int new_machine (struct pdb_methods *in, const char *machine_in) fstrcpy(machineaccount, machinename); fstrcat(machineaccount, "$"); - if ((pwd = getpwnam_alloc(NULL, machineaccount))) { - - if ( (sam_pwent = samu_new( NULL )) == NULL ) { - fprintf(stderr, "Memory allocation error!\n"); - TALLOC_FREE(pwd); - return -1; - } + if ( !(pwd = getpwnam_alloc( NULL, machineaccount )) ) { + DEBUG(0,("Cannot locate Unix account for %s\n", machineaccount)); + return -1; + } - if ( !NT_STATUS_IS_OK(samu_set_unix(sam_pwent, pwd )) ) { - fprintf(stderr, "Could not init sam from pw\n"); - TALLOC_FREE(pwd); - return -1; - } + if ( (sam_pwent = samu_new( NULL )) == NULL ) { + fprintf(stderr, "Memory allocation error!\n"); + TALLOC_FREE(pwd); + return -1; + } + if ( !NT_STATUS_IS_OK(samu_alloc_rid_unix(sam_pwent, pwd )) ) { + fprintf(stderr, "Could not init sam from pw\n"); TALLOC_FREE(pwd); - } else { - if ( (sam_pwent = samu_new( NULL )) == NULL ) { - fprintf(stderr, "Could not init sam from pw\n"); - return -1; - } + return -1; } + TALLOC_FREE(pwd); + pdb_set_plaintext_passwd (sam_pwent, machinename); pdb_set_username (sam_pwent, machineaccount, PDB_CHANGED); pdb_set_acct_ctrl (sam_pwent, ACB_WSTRUST, PDB_CHANGED); -- cgit v1.2.1