summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WHATSNEW.txt5653
-rw-r--r--docs/README-NOW9
-rw-r--r--examples/libsmbclient/smbwrapper/bsd-strlcat.c71
-rw-r--r--examples/libsmbclient/smbwrapper/bsd-strlcpy.c67
-rw-r--r--examples/libsmbclient/smbwrapper/bsd-strlfunc.h7
-rw-r--r--examples/libsmbclient/teststat2.c72
-rw-r--r--make-tarball.sh57
-rw-r--r--source/.indent.pro30
-rw-r--r--source/Makefile.in29
-rw-r--r--source/VERSION8
-rw-r--r--source/aclocal.m42
-rw-r--r--source/auth/auth_util.c34
-rw-r--r--source/auth/pass_check.c4
-rw-r--r--source/client/client.c1
-rw-r--r--source/client/clitar.c2
-rw-r--r--source/configure.in100
-rw-r--r--source/groupdb/mapping.c88
-rw-r--r--source/include/auth.h2
-rw-r--r--source/include/debug.h6
-rw-r--r--source/include/includes.h6
-rw-r--r--source/include/libsmb_internal.h18
-rw-r--r--source/include/messages.h1
-rw-r--r--source/include/nameserv.h6
-rw-r--r--source/include/passdb.h37
-rw-r--r--source/include/smb.h63
-rw-r--r--source/include/smb_macros.h6
-rw-r--r--source/lib/charcnv.c13
-rw-r--r--source/lib/replace.c2
-rw-r--r--source/lib/smbldap.c8
-rw-r--r--source/lib/system_smbd.c4
-rw-r--r--source/lib/username.c34
-rw-r--r--source/lib/util_getent.c31
-rw-r--r--source/lib/util_sid.c90
-rw-r--r--source/lib/util_smbd.c86
-rw-r--r--source/lib/util_str.c90
-rw-r--r--source/lib/util_unistr.c56
-rw-r--r--source/lib/version.c6
-rw-r--r--source/libsmb/clilist.c6
-rw-r--r--source/libsmb/climessage.c2
-rw-r--r--source/libsmb/clirap.c10
-rw-r--r--source/libsmb/libsmbclient.c1054
-rw-r--r--source/libsmb/smb_share_modes.c37
-rw-r--r--source/locking/locking.c142
-rw-r--r--source/modules/vfs_afsacl.c35
-rw-r--r--source/nmbd/asyncdns.c28
-rw-r--r--source/nmbd/nmbd.c4
-rw-r--r--source/nmbd/nmbd_browserdb.c22
-rw-r--r--source/nmbd/nmbd_browsesync.c6
-rw-r--r--source/nmbd/nmbd_incomingrequests.c6
-rw-r--r--source/nmbd/nmbd_mynames.c8
-rw-r--r--source/nmbd/nmbd_namelistdb.c328
-rw-r--r--source/nmbd/nmbd_subnetdb.c33
-rw-r--r--source/nmbd/nmbd_winsproxy.c22
-rw-r--r--source/nmbd/nmbd_winsserver.c802
-rw-r--r--source/nsswitch/pam_winbind.c44
-rw-r--r--source/nsswitch/pam_winbind.h2
-rw-r--r--source/nsswitch/wb_client.c42
-rw-r--r--source/nsswitch/winbindd.c2
-rw-r--r--source/nsswitch/winbindd_ads.c2
-rw-r--r--source/nsswitch/winbindd_cache.c11
-rw-r--r--source/nsswitch/winbindd_ldap.c12
-rw-r--r--source/nsswitch/winbindd_pam.c18
-rw-r--r--source/nsswitch/winbindd_sid.c4
-rw-r--r--source/nsswitch/winbindd_util.c3
-rw-r--r--source/param/loadparm.c4
-rw-r--r--source/passdb/lookup_sid.c404
-rw-r--r--source/passdb/machine_sid.c24
-rw-r--r--source/passdb/passdb.c143
-rw-r--r--source/passdb/pdb_interface.c116
-rw-r--r--source/passdb/pdb_ldap.c16
-rw-r--r--source/passdb/pdb_nds.c2
-rw-r--r--source/passdb/pdb_pgsql.c2
-rw-r--r--source/passdb/util_builtin.c110
-rw-r--r--source/passdb/util_sam_sid.c238
-rw-r--r--source/passdb/util_wellknown.c149
-rw-r--r--source/rpc_server/srv_lsa_nt.c166
-rw-r--r--source/rpc_server/srv_samr.c34
-rw-r--r--source/rpc_server/srv_samr_nt.c286
-rw-r--r--source/smbd/chgpasswd.c10
-rw-r--r--source/smbd/close.c55
-rw-r--r--source/smbd/lanman.c10
-rw-r--r--source/smbd/mangle_hash.c6
-rw-r--r--source/smbd/mangle_hash2.c12
-rw-r--r--source/smbd/message.c2
-rw-r--r--source/smbd/msdfs.c2
-rw-r--r--source/smbd/notify.c8
-rw-r--r--source/smbd/notify_fam.c446
-rw-r--r--source/smbd/open.c74
-rw-r--r--source/smbd/oplock.c8
-rw-r--r--source/smbd/posix_acls.c6
-rw-r--r--source/smbd/quotas.c2
-rw-r--r--source/smbd/reply.c66
-rw-r--r--source/smbd/server.c9
-rw-r--r--source/smbd/service.c308
-rw-r--r--source/smbd/trans2.c26
-rw-r--r--source/smbd/uid.c38
-rw-r--r--source/torture/torture.c2
-rw-r--r--source/torture/vfstest.c1
-rw-r--r--source/ubiqx/COPYING.LIB481
-rw-r--r--source/ubiqx/README.UBI18
-rw-r--r--source/ubiqx/debugparse.c (renamed from source/utils/debugparse.c)0
-rw-r--r--source/ubiqx/debugparse.h (renamed from source/include/debugparse.h)2
-rw-r--r--source/ubiqx/sys_include.h52
-rw-r--r--source/ubiqx/ubi_BinTree.c1172
-rw-r--r--source/ubiqx/ubi_BinTree.h887
-rw-r--r--source/ubiqx/ubi_Cache.c505
-rw-r--r--source/ubiqx/ubi_Cache.h412
-rw-r--r--source/ubiqx/ubi_SplayTree.c512
-rw-r--r--source/ubiqx/ubi_SplayTree.h377
-rw-r--r--source/ubiqx/ubi_dLinkList.c171
-rw-r--r--source/ubiqx/ubi_dLinkList.h242
-rw-r--r--source/ubiqx/ubi_sLinkList.c187
-rw-r--r--source/ubiqx/ubi_sLinkList.h254
-rw-r--r--source/utils/net_groupmap.c92
-rw-r--r--source/utils/net_idmap.c28
-rw-r--r--source/utils/net_lookup.c2
-rw-r--r--source/utils/smbget.c28
-rw-r--r--source/utils/smbpasswd.c12
118 files changed, 13000 insertions, 4703 deletions
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 179a31c7fda..22e5b56accc 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,6 +1,5651 @@
- WHATS NEW IN Samba 3 SVN
- ========================
+ ===============================
+ Release Notes for Samba 3.0.21a
+ Dec 30, 2005
+ ===============================
-This file is NOT maintained but will be created during releases.
-See the SAMBA_3_0_RELEASE branch for the current WHATSNEW.
+This is the latest stable release of Samba. This is the version
+that production Samba servers should be running for all current
+bug-fixes. Please read the following important changes in this
+release.
+
+######################################################################
+Changes
+#######
+
+Changes since 3.0.21
+--------------------
+
+commits
+-------
+o Gerald (Jerry) Carter <jerry@samba.org>
+ * RedHat 9 packaging Fixes.
+
+
+o Guenther Deschner <gd@samba.org>
+ * eDirectory schema syntax fixes.
+
+
+o Volker Lendecke <vl@samba.org>
+ * BUG 3349: Deadlock caused logic error in oplock code.
+
+
+Release Notes for older release follow:
+
+ --------------------------------------------------
+ ==============================
+ Release Notes for Samba 3.0.21
+ Dec 20, 2005
+ ==============================
+
+Common bugs fixed in 3.0.21 include:
+
+ o Missing groups in a user's token when logging in via kerberos
+ o Incompatibilities with newer MS Windows hotfixes and
+ embedded OS platforms
+ o Portability and crash bugs.
+ o Performance issues in winbindd.
+
+New features introduced in Samba 3.0.21 include:
+
+ o Complete NTLMv2 support by consolidating authentication
+ mechanism used at the CIFS and RPC layers.
+ o The capability to manage Unix services using the Win32
+ Service Control API.
+ o The capability to view external Unix log files via the
+ Microsoft Event Viewer.
+ o New libmsrpc share library for application developers.
+ o Rewrite of CIFS oplock implementation.
+ o Performance Counter external daemon.
+ o Winbindd auto-detection query methods when communicating with
+ a domain controller.
+ o The ability to enumerate long share names in libsmbclient
+ applications.
+
+
+######################################################################
+Changes
+#######
+
+smb.conf changes
+----------------
+
+ Parameter Name Action
+ -------------- ------
+ dfree cache time New
+ dfree command Per share
+ eventlog list New
+ iprint server New
+ map read only New
+ passdb expand explicit New
+ rename user script New
+ reset on zero vc New
+ svcctl list Renamed from 'enable svcctl'
+
+
+
+Changes since 3.0.20b
+---------------------
+
+o Jeremy Allison <jra@samba.org>
+ * BUG 1828: Fixed SPNEGO issues with PocketPC clients.
+ * Added 'map readonly' parameter.
+ * BUG 3166: Fix crash in libsmbclient if the $HOME environment is
+ not defined.
+ * Maintain schannel client session keys in volatile
+ $(privatedir)/schannel_store.tdb.
+ * BUG 2769: Ensure we mangle filenames ending in a space
+ * Catch corner case of renaming a symlinked directory into
+ itself
+ * Ensure that smb.conf requests for hidden files are honored,
+ even when DOS attributes are stored in EA's
+ * Add new auth method "auth_script" for calling an external
+ program
+ * BUG 2152: Fix for mangled filenames when the client does
+ support long filenames
+ * Rewritten implementation of client and server DCE/RPC infrastructure
+ * BUG 3192: Adds a "dfree cache time" parameter.
+ * Fix acl evaluation bug found by Marc Cousin. Only evaluate
+ the S_IWGRP mask in the absence of a POSIX ACL.
+ * Remove use of 'long long' in libsmbclient code.
+ * Ensure the new canonicalize_servicename() in name/snum hash
+ is multi-byte safe.
+ * BUG 2922: Integration of FreeBSD AIO patches from Timur
+ Bakeyev.
+ * BUG 3216: Put directory opens into the share mode db so we
+ can treat them similarly to file opens (delete on close,
+ share mode violations etc.).
+ * Fix bug in name mangling code when case sensitivity is enabled.
+ * Remove external dependencies from the sharemodes library.
+ * BUG 3212: Ignore bogus OS/2 set EA values on trans2 calls.
+ * Don't misinterpret wild card characters in file names on disk
+ as they are actually valid characters.
+ * BUG 3223: Fix bug in account policy management when
+ account_pol.tdb settings have been migrating to an LDAP
+ backend.
+ * Allow the hash size of the tdb open (locking) database to be
+ set in local.h.
+ * Fix error code returns on client spoolss code.
+ * Remove unneeded strncpy use.
+ * Fix uninitialized variables warnings.
+ * Cleanup smbcacls security descriptor parsing and error codes.
+ * BUG 3224: Correctly use machine_account_name and client_name
+ when doing netlogon credential setup. Fixes winbindd running
+ on a Samba PDC.
+ * Backport Samba 4 time zone handling.
+ * Fix core dump if setmntent() returns NULL.
+ * Replace old crc32 code with one from the FreeBSD tree.
+ * Filter stored DOS attributes by SAMBA_ATTRIBUTES_MASK.
+ * Remove #define of close -> close_fn macro in libsmbclient.
+ * Return early if -1 returned from *BSD EA call (reported by
+ Timur).
+ * Name space cleanup by marking local functions static.
+ * Move samr enumeration cache from per handle basis to a shared
+ cache.
+ * BUG 3274: Fix invalid smbclient qpath_basic() queries against
+ OS/2 servers (based on patch from Guenter Kukkukk).
+ * Ensure default applies to new files (reported by Thomas
+ Neumann).
+ * BUG 3293: Use SMBecho to testing the server in client rather
+ than SMBchkpath.
+ * Merge talloc fixes from Samba 4 branch.
+ * Add support DCE/RPC cancel operation.
+ * Don't reset attrs to zero in EA get. Fixes 'hide dot files'
+ when using EA for DOS attributes.
+ * Fix bug in returning remote time (reported by Thomas Bork).
+ * No users or groups to return in BUILTIN domain.
+ * Removed separate "builtin" search enumeration.
+ * Added count_sam_aliases to return the correct alias count.
+ * Correctly handle the LDAP_UNWILLING_TO_PERFORM error from
+ eDirectory when accessing the universal password.
+ * Fix deadlock condition in share mode locking code.
+ * Fix logic bug in unix_mask_match().
+ * Fix memory leak in SMB client code found by Mikhail Kshevetskiy.
+
+
+o Rashid N. Achilov <shelton@granch.ru>
+ * Add better service description names to the svcctl code.
+
+
+o Timur Bakeyev <timur@com.bat.ru>
+ * BUG 3262: Improve FreeBSD DOS attribute error reporting.
+
+
+o Andrew Bartlett <abartlet@samba.org>
+ * Remove another ancient NTLMSSP implementation.
+ * Allow machine account logons work if the client gives the
+ appropriate flags.
+
+
+o Alexander Bokovoy <ab@samba.org>
+ * Add POSIX statvfs() to VFS api.
+
+
+o Gerald (Jerry) Carter <jerry@samba.org>
+ * Eventlog and ServiceControl support.
+ * BUG 1051: store the directory path so we can send the full
+ name in the unlink call from smbclient.
+ * Use reference count strategy for keeping the registry tdb
+ open.
+ * Convert internal registry objects to new hierarchical talloc
+ * Allow the root user a free pass for access checks in the
+ registry and service control checks.
+ * Sanity checks in the privilege code to prevent empty SID
+ entries
+ * Add basic infrastructure for 'make test' when the socket
+ wrapper library is configured at compile time
+ * Convert profiles utility to use the current regfio interface
+ for reading and writing user profiles
+ * Remove netsamlogon_cache interface
+ * Ensure that print jobs are removed even when the cancel
+ command is received before the print cache has been updated
+ * Fix linking problem on Solaris when including ACL support.
+ * Give root a free pass to open the eventlog tdb files.
+ * Fix segfault in addprinter due to mixing talloc() and
+ malloc()'d memory.
+ * fix invalid read reported by valgrind in the spoolss
+ backchannel connection.
+ * Remove use of 'long long' in perfcounter registry code.
+ * BUG 3201: make sure request structure is cleared prior to
+ sending the request to winbindd.
+ * Don't count open pipes in the num_files_open on a connection
+ (regression from Samba 2.2).
+ * Ensure servername hashing code normalizes the name.
+ * Fix checks for connect() in -lnsl[_s].
+ * Convert eventlog API to use NTSTATUS return codes rather
+ than WERROR.
+ * Fix segv in winbindd caused by an uninitialized variable
+ in winbindd_dual_getsidaliases().
+ * Allow winbindd to select the appropriate backend methods
+ based on the DC attributes and not the security parameter.
+ * Re-add the netsamlogon_cache tdb and ensure that user entries
+ are updated from the PAC data during kerberos ticket
+ validation.
+ * Fix lockup when running 'wbinfo -t' on a Samba PDC caused
+ by mangling machine names in sub_set_smb_name().
+ * Add smbget to the list of tools built by default.
+ * Fix clearing of eventlog tdb files.
+ * Fix sequential reads in eventlog support.
+ * BUG 2718: Don't use qpathinfo_basic() call when remote server
+ is Win9x.
+ * Fix build issues with the Sun compiler.
+ * BUG 3156: Don't use find_service() when explicitly looking
+ for a printer.
+ * Fix nss_winbind_solaris.c build breakage on HP-UX.
+ * Initialize the local group description.
+ * Disable WINS and NetLogon services in the MMC services
+ plugin when the associated smb.conf features are not enabled.
+ * Add checks for invalid characters in new share names on the
+ srvsvc pipe.
+ * Fix SWAT installation issues with 'make install'.
+
+
+o Alex Deiter <tiamat@komi.mts.ru>
+ * BUG 3196: Patch to compile against the Sun LDAP client libs.
+ (not for AD support; just ldap support).
+
+
+o Guenther Deschner <gd@samba.org>
+ * Fixed compile problems and warnings with newer OpenLDAP
+ and OpenSSL libs
+ * Fix bug when enumerating trusted domains via 'wbinfo -m'
+ * Parse the MS Kerberos PAC to obtain the user group
+ membership during logon.
+ * Add support for SeRestorePrivilege to allow a process to
+ change the ownership of a file to any arbitrary account
+ * Fix password history storage when using Novell eDirectory for
+ ldapsam storage
+ * Backport Kerberos PAC parsing from Samba 4 branch in order to
+ correctly create the NT User Token when logging into a Samba
+ member server
+ * Add small helper function to return a PAC_LOGON_INFO.
+ * Use LDAP bitwise matching rule when searching for groups
+ in ADS.
+ * Avoid an infinite loop when retrying to connect in smbspool.
+ * Memory leak fixes in the kerberos PAC parsing code.
+ * Improve NT_STATUS error messages returned from pam_winbind.
+ * Rename unknown samr group fields in samr structures with
+ the correct name.removed separate "builtin" search enumeration.
+ * Cleanup redundant StartTLS code.
+ * Allow StartTLS support when connecting to Windows 2003 by
+ setting 'ldap ssl = start_tls'.
+ * Support raw NTLMSSP session setups in smbspool.
+ * Add rpccli_samr_chgpasswd3().
+ * Add 'wbinfo --separator'.
+ * Uninitialized warnings fixes.
+ * Fix return value in client spooler code.
+ * Require forced migration of account policies.
+
+
+o Steve French <sfrench@us.ibm.com>
+ * Fix cifs to handle non-numeric uid and gid parameters.
+ * Merge trunk and SAMBA_3_0 mount.cifs code.
+ * Cleanup cifs cfs help message.
+
+
+o Paul Green <paulg@samba.org>
+ * Update to the latest config.guess and config.sub files.
+
+
+o Deryck Hodge <deryck@samba.org>
+ * Allow control of syslog facility and level in audit vfs modules.
+
+
+o S Murthy Kambhampaty <smk_va@yahoo.com>
+ * Patches for Fedora RPM specfile and init script
+
+
+o Krishna Ganugapati <krishnag@centeris.com>
+ * Use the subtree delete ldap control when running 'net ads
+ leave'.
+
+
+o Volker Lendecke <vl@samba.org>
+ * New oplock implementation.
+ * Add assert() call if winbindd cannot locate the domain SID in
+ secrets.tdb on startup
+ * Fix an annoying timeout in winbindd when nmbd is not running.
+ * Speed up loading smb.conf for large numbers of share
+ definitions by adding an internal hashing of names to snums.
+ Thanks to Michael Adam.
+ * Fix potential segv in rpcclient's lsarpc calls.
+ * Fix bugs in winbindd's use of rpccli_netlogon_getdcname().
+ * Fix alignment in getdc response.
+ * Allow pdbedit to set the domain for a user account.
+ * Fix fallback logic in rpc binds.
+ * Fix memleak in message handling code.
+ * Fix connection bug to port 445 and 139 after a successful
+ getdcname response.
+ * Add additional calls to initialize_krb5_error_table() for
+ kerberos client code.
+ * Implement the possibility to have AFS users as SIDs in pts.
+ * Removed unused alternative_name code from winbindd.
+ * Protect against NULL alternative_name strings in winbindd.
+ * Define a default panic action with -DEVELOPER is defined.
+ * Add the capability to reset smbd connections on a zero VC id.
+ * Allow smb.conf variable expansion to be disabled in passdb
+ backends.
+ * Add lookupname to rpcclient query_user as a fallback.
+ * BUG 3292: Prevent smbclient from spinning when the server
+ disconnects.
+ * BUG 2191: Fix valgrind error in cli_session_setup_guest().
+ * Add samr_lookup_rids for the builtin domain.
+ * Memory allocation cleanups in passdb.
+ * Restrict samr_open_domain() to our domain only.
+ * Change local_lookup_sid() to local_lookup_rid() since it
+ is responsible for our domain only.
+ * Fix some uninitialized variable warnings.
+ * Fix winbind_lookup_name for the local domain,
+
+
+o Derrell Lipman <derrell@samba.org>
+ * Cleanup libmsrpc version numbers.
+ * Libsmbclient memory & file descriptor leak fixes.
+ * Fix crash bug in libsmbclient.
+ * Add long share name support to libsmbclient when enumerating shares.
+
+
+o Jason Mader <jason@ncac.gwu.edu>
+ * Removed compiler various warnings.
+
+
+o Alex Masterov <alex@infobit.ru>
+ * BUG 3218: Fix XATTR calls on *BSD systems.
+
+
+o Jim McDonough <jmcd@us.ibm.com>
+ * Speed up string_to_sid by removing next_token calls and
+ unneeded strncmp() calls.
+ * Implement user rename for smbpasswd and LDAP backends.
+ * BUG 2961 (partial): Add rename support for user accounts to tdbsam
+ * BUG 3187: Fix time zone offset in logon hours restrictions.
+
+
+o Stefan Metzmacher <metze@samba.org>
+ * Fix setting of quotas on linux kernel with the struct
+ if_dqblk interface
+ * Enable sysquota interfact on Linux by default
+ * Use lp_socket_address() when binding to port 138/udp in nmbd.
+
+
+o Brian Moran <bmoran@centeris.com>
+ * Eventlog and ServiceControl support.
+ * Added eventlogadm tool for writing Eventlog records.
+ * Fix typo when creating Eventlog source DLL registry paths.
+ * Add simple script to tail syslog and write records to
+ eventlog tdb.
+ * Fix segv in eventlogadm when not event logs are listed in
+ smb.conf.
+
+
+o Lars Müller <lmuelle@samba.org>
+ * Only install smbsh manpage if smbwrapper has been successfully
+ built.
+ * Ensure setmntent() returns with != NULL in the disk_quotas()
+ Linux version.
+ * Add configure switch to disable libmsrpc build.
+ * Add a soname to libmsrpc.
+
+
+o Ricky Nance <ricky.nance@gmail.com>
+ * Updates for the mklogon perl scripts.
+
+
+o Chris Nicholls <skel@samba.org>
+ * New libmsrpc library (Google SoC Project).
+ * Fix libmsrpc build of on the Sun compiler by removing empty
+ structure declarations.
+
+
+o James Peach <jpeach@sgi.com>
+ * Fix parsing error for smb ports parameter.
+
+
+o Tim Potter <tpot@samba.org>
+ * BUG 3260: Fix DYNEXP flags on HPUX.
+
+
+o Marcin Porwit <mporwit@centeris.com>
+ * Eventlog and ServiceControl support.
+ * Added basic Performance Counter daemon which can feed data
+ for the Windows perfmon.exe tool.
+ * Fix directory permissions in the perfcounter daemon.
+ * Add the 'File' registry value for the eventlog keys.
+
+
+o Aruna Prabakar <aruna.prabakar@hp.com.
+ * Add checks to verify that the spooler is running on HP-UX when
+ reloading the printer name cache.
+
+
+o Joel Smith <joel.j.smith@novell.com>
+ * Add iPrint printing backend support.
+
+
+o Toomas Soome <Toomas.Soome@mls.ee>
+ * Implement host lookups in nss_winbind.so.1 on Solaris
+
+
+o Simo Sorce <idra@samba.org>
+ * Update Debian packaging.
+
+
+o John Terpstra <jht@samba.org>
+ * Add 'net idmap' usage help text.
+
+
+o Andrew Tridgell <tridge@samba.org>
+ * Change license notice of standalone talloc library to LGPL.
+
+
+o Darren Tucker <dtucker@zip.com.au>
+ o Crash fix for snprintf() code.
+
+
+o Rainer Weikusat <rainer.weikusat@sncag.com>
+ * Fix function name typo in skeleton VFS code.
+
+
+
+Release Notes for older release follow:
+
+ --------------------------------------------------
+ ===============================
+ Release Notes for Samba 3.0.20b
+ Oct 12, 2005
+ ===============================
+
+Common bugs fixed in 3.0.20b include:
+
+ o A crash bug in winbindd
+ o Reporting files as read-only instead of returning the
+ correct error code of "access denied"
+ o File system quota support defects
+
+
+######################################################################
+Changes
+#######
+
+
+Changes since 3.0.20a
+---------------------
+
+commits
+-------
+
+o Jeremy Allison <jra@samba.org>
+ * BUG 3088: Fix error condition for files on a read-write share
+ which cannot be read due to permissions.
+
+
+o Gerald (Jerry) Carter <jerry@samba.org>
+ * BUG 3070: Fix crash bug in qfsinfo when retrieving fs quota
+ details.
+ * BUG 1473, 3090: Quota detection and compilation problems on
+ Solaris.
+
+
+o Marc Balmer <marc@msys.ch>
+ * Build fixes when builddir != srcdir
+
+
+o Alex Deiter <tiamat@komi.mts.ru>
+ * BUG 3145: Fix build issue regarding quota support on Solaris.
+
+
+o Volker Lendecke <vl@samba.org>
+ * BUG 3068: Fix for winbindd crashed by empty DC alternative
+ name.
+
+
+ --------------------------------------------------
+ ===============================
+ Release Notes for Samba 3.0.20a
+ Sept 30, 2005
+ ===============================
+
+Common bugs fixed in 3.0.20a include:
+
+ o Stability problems with winbindd.
+ o Crash bugs caused by incompatibilities on 64-bit systems.
+ o Missing files from directory listings on AIX servers
+ o User Manager interoperability problems.
+ o Minor build difficulties on various platforms such as
+ Solaris and OpenBSD,
+
+
+Winbind, security = domain, and Active Directory
+================================================
+
+Recent security updates for Windows 2000 and Windows 2003 have
+changed the fashion in which user and group lists can be obtained
+from domain controllers. In short, the RPC mechanisms used by
+"security = domain" to retrieve users and groups is not compatible
+with these changes. The "security = ads" configuration is not
+affected by the Windows protocol changes.
+
+Samba developers are actively working to correct this problem in
+the 3.0.21 release. In the meantime, Administrators who are unable
+to migrate to "security = ads" and must continue using "security =
+domain", can define credentials to be used by winbindd for account
+enumeration by executing the following command as root.
+
+ wbinfo --set-auth-user='DOMAIN\username%password'
+
+
+
+######################################################################
+Changes
+#######
+
+
+Changes since 3.0.20
+--------------------
+
+commits
+-------
+
+o Jeremy Allison <jra@samba.org>
+ * BUG 3065: Fix for legacy clients retrieving a listing of
+ an empty directory.
+ * Added external library for accessing Samba's share mode
+ database.
+ * Fix winbindd credentials chain which caused logon failures
+ after attempting to authenticate an unknown user.
+ * Fix recursive looping bug in winbindd.
+ * Fix build errors on 64-bit systems.
+ * Posix ACL memory leak and crash bug fixes.
+ * BUG 3044: Ensure OPEN-EXEC is honored as read-only.
+ * BUG 3060: Ensure SMBcreate truncates the file if it exists.
+ * Hide dot files and directory logic fixes.
+ * Correct display of open file modes by smbstatus.
+ * BUG 3010: Fix missing files bug on AIX systems.
+
+
+o Gerald (Jerry) Carter <jerry@samba.org>
+ * Allow the root user to automatically pass se_access_checks()
+ in the registry and service control server code.
+ * Ensure that winbindd uses the correct name in the net_auth2()
+ request when running on a Samba PDC.
+ * Fix linking problem with tdb utilities.
+ * BUG 3080: Fix regression in 'net rpc shutdown' command.
+ * Fix segv in 'net rpc' when the pipe open fails.
+ * Fix upload bug when installing 64-bit Windows printer drivers.
+ * Fix regression in the smburi syntax used by smbspool.
+ * Fix sorting of subkey hash records in registry files.
+ * Correct REG_CREATE_KEY_EX parsing error.
+ * Interoperability issues with usrmgr.exe and Samba groups.
+ * Use the display names and not the Unix names when enumerating
+ groups in the ldapsam passdb backend.
+ * Ensure that Windows domain user names are converted to lower case.
+
+
+o Guenther Deschner <gd@samba.org>
+ * Prevent BUILTIN sids returned in the user's token from
+ a Windows DC from being applied to any local group mappings
+ on the Samba host.
+ * Plug memory leaks in the kerberos keytab code.
+ * Ensure BUILTIN groups are returned from winbindd's idmap_rid
+ backend when 'winbind nested groups' is enabled.
+ * Fix crash bug in winbindd caused by 64-bit build issues.
+ * Improve debug messages in smbspool.
+ * Give better error-message when "NDS Universal Password" change fails.
+ * Fix password history error in the eDirectory schema file.
+ * Ensure that Windows domain group names are converted to lower case.
+
+
+o Steve French <sfrench@us.ibm.com>
+ * Allow disabling mandatory byte range lock mount flag, and fix
+ corresponding entry in mtab.
+
+
+o Volker Lendecke <vl@samba.org>
+ * Fix race condition in the NTcreate&X open code when the
+ disposition is NTCREATEX_DISP_CREATE.
+ * Correct logic error when checking the pid for pending print
+ change notify messages.
+ * Ensure that winbindd child process complete startup even when
+ the parent is receiving authentication requests.
+ * Return the full NTSTATUS code to ntlm_auth and pam_winbindd
+ when authentication fails.
+
+
+o Jason Mader <jason@ncac.gwu.edu>
+ * Compile warning fixes.
+
+
+o Uli Meis <a.sporto@gmail.com>
+ * Patches for pdb_*sql.c
+
+
+o Luke Mewburn <lukem@NetBSD.org>
+ * Autoconf syntax fixes.
+
+
+o James Peach <jpeach@sgi.com>
+ * Correct problem with creating a core file in Linux.
+
+
+o Stefan Metzmacher <metze@samba.org>
+ * Quota fixes in smbd.
+
+
+o Peter Rindfuss <rindfuss@wz-berlin.de>
+ * Patches for pdb_*sql.c
+
+
+o Jiri Sasek <Jiri.Sasek@Sun.COM>
+ * Solaris toolchain patches for autoconf scripts.
+
+
+o Andrew Tridgell <tridge@samba.org>
+ * Fix for tdb clear-if-first race condition.
+
+
+o Leo Weppelman <leo@wau.mis.ah.nl>
+ * BUG 3104: Don't allow time updates to files on read-only shares.
+
+
+o Steve Williams <steve@celineandsteve.com>
+ * BUG 3052: Fix compile issues on OpenBSD.
+
+
+ --------------------------------------------------
+ ==============================
+ Release Notes for Samba 3.0.20
+ Aug 19, 2005
+ ==============================
+
+Additional features introduced in Samba 3.0.20 include:
+
+ o Support for several new Win32 rpc pipes.
+ o Improved support for OS/2 clients.
+ o New 'net rpc service' tool for managing Win32 services.
+ o Capability to set the owner on new files and directory
+ based on the parent's ownership.
+ o Experimental, asynchronous IO file serving support.
+ o Completed Support for Microsoft Print Migrator.
+ o New Winbind IDmap plugin (ad) for retrieving uid and gid
+ from AD servers which maintain the SFU user and group
+ attributes.
+ o Rewritten support for POSIX pathnames when utilizing
+ the Linux CIFS fs client.
+ o New asynchronous winbindd.
+ o Support for Microsoft Print Migrator.
+ o New Windows NT registry file I/O library.
+ o New user right (SeTakeOwnershipPrivilege) added.
+ o New "net share migrate" options.
+
+
+What happened to 3.0.15 - 3.0.19?
+==================================
+
+After some discussion it was deemed that the amount of changes
+going into the next Samba 3.0 release needed something to catch
+people's attention. Skipping several releases was chosen as
+the best solution with the least overhead. There will be no
+3.0.15 - 3.0.19 ever released. The next production release
+following 3.0.20 should be 3.0.21.
+
+The original announcement about the version number change can
+be found in the samba mailing list archives:
+
+http://marc.theaimsgroup.com/?l=samba&m=111721010206997&w=2
+
+
+Asynchronous Winbind Implementation
+===================================
+
+Winbindd has been completely rewritten in this release to support
+an almost completely non-blocking, asynchronous request/reply
+model. This means that winbindd will scale much better in
+large domain environments and on high latency networks. Neither
+the client interface nor the command line tools (i.e. wbinfo) have
+changed in their calling conventions or syntax. However, due to
+internal structure changes, it is required (more so than normal)
+that you install the nss_winbind.so library included in this release.
+
+
+Support for Microsoft Print Migrator
+====================================
+
+Samba 3.0.20 includes full support for migrating printers from
+Windows servers or other Samba servers via the Microsoft Print
+Migrator tool. Restoring printers requires a working "add printer
+command" defined in smb.conf. Current support also allows
+administrators to create a master list of printer drivers which
+can be restored in bulk on new (or existing) Samba installations.
+
+
+Asynchronous IO Support
+=======================
+
+Experimental support for async IO has been added to smbd for
+certain platforms. To enable this new feature, Samba must be
+compiled to include the --with-aio-support configure option.
+In addition, the "aio read size" and "aio write size" to non-zero
+values. See the smb.conf(5) man page for more details on these
+settings.
+
+
+######################################################################
+Changes
+#######
+
+smb.conf changes
+----------------
+
+ Parameter Name Action
+ -------------- ------
+ acl check permissions New
+ acl group control New
+ acl map full control New
+ aio read size New
+ aio write size New
+ enable asu support New
+ inherit owner New
+ ldap filter Removed
+ map to guest Modified (new value added)
+ max stat cache size New
+ min password length Removed
+ printer admin Deprecated
+ username map script New
+ winbind enable local accounts Removed
+ winbindd nss info New
+
+
+Changes since 3.0.14a
+---------------------
+
+
+commits
+-------
+
+o Jeremy Allison <jra@samba.org>
+ * BUG 2533: Fix incorrect directory listings for OS/2 clients.
+ * Ensure the old SMB search calls always ask mask_match() to
+ translate patterns like ????????.???.
+ * Split out the check_path_syntax() into a findfirst, findnext,
+ & wildcard versions.
+ * Fix checks for matching groups in an file ACL against the
+ user's primary and supplementary group list.
+ * BUG 2541: Ensure we recognize LANMAN2.1 as OS/2 and select
+ LANMAN2 protocol, ensure the EA size is always correctly
+ set on a query for a file with no EA's.
+ * BUG 2551: Look at the incoming flags2 flag
+ FLAGS2_LONG_PATH_COMPONENTS determines if a reply is
+ uppercased on a SMBsearch request, not the protocol level.
+ * Added "volume" command to smbclient that prints out the
+ volume name and serial number.
+ * Added "fix for broken SMB_INFO_VOLUME level used by OS/2.
+ * Add support for OS/2 Extended Attributes.
+ * Correctly check OpenX open modes.
+ * Ensure allocation size is correctly returned for OpenX.
+ * Only set allocation on create/truncate for nttrans.
+ * Fix oplock bug in trans2open() code.
+ * Remove unix_ERR_XXX global nastiness.
+ * Only do the strange DOS error for openX, not trans2open.
+ * Ensure SMBopen replies includes the share modes as well as
+ open modes.
+ * BUG 2581: Add size limit (in kb) to stat cache.
+ * Fix bug in the trans2 secondary processing.
+ * BUG 2601: Enforce DOS_OPEN_EXEC to mean read-only.
+ * Add an SMB counter per connection struct for gathering
+ profiling data.
+ * BUG 2605: Ensure smbclient doesn't perform commands if
+ the "chdir" fails in a scripted set.
+ * Ensure a 'forced group' is added to the list of effective
+ gids when processing ACLs.
+ * Refactor rpc_bind structures for better future work.
+ * BUG 2942: Add missing value in debug message.
+ * BUG 2946: Fix regressions in str[n]cmp_w) functions found
+ by 'mangling method = hash'.
+ * Fix memory leaks in the msdfs trans2 server code.
+ * Convert msdfs server to be talloc'd based.
+ * Fix up stackable vfs interface.
+ * Fix rpc fault when encountering an unknown rpc_bind auth
+ type.
+ * BUG 2954: More AIX 5.1 AIO compile fixes.
+ * Fix valgrind bug in interaction with new aio buffer (found
+ by Volker).
+ * BUG 2878: Fix Norton commander not running on OS/2 clients.
+ * Cleanup SAMR user info structure naming.
+ * BUG 2889: Fix directly listings from OS/2 clients.
+ * Added "acl group control" parameter.
+ * Add debug warning if AddPrinterEx() is called without having
+ an 'add printer command' defined.
+ * Add better log messages when modifying ldap entries.
+ * BUG 2829: Fix strXX_w() functions on non-x86 platforms when
+ when string is unaligned.
+ * BUG 2918: Fix SMB chaining by ensuring that deferred open
+ message buffer is nor reused.
+ * Add support for client setting capabilities to select posix
+ pathnames on the wire.
+ * Stop using C++ reserved words so that Samba can be compiled
+ using g++. Also allows VFS modules in C++.
+ * More fixes to allow better large directory scaling.
+ * BUG 2827: Ensure we call the vfs connection hook before
+ doing a vfs stat. Allows database vfs backends to initialize
+ with a working connection.
+ * BUG 2826: Ensure the correct return value for symlink and
+ readlink in the VFS.
+ * Merge handling of ASN.1 objects bigger than 64k from Samba 4.
+ * Added AIO support to smbd.
+ * Add "acl map full control", true by default, to allow people
+ to change mapping of rwx to full control or not.
+ * Transition smbd to use NTcreate&X for internal file opens.
+ * Add checks against the current effective group id (e.g. force
+ user) when testing write permissions one ACLs.
+ * Fix FindFirst/FindNext server code when parsing directories
+ on old IRIX XFS file systems (thanks to Cale Fairchild
+ for the debugging help).
+ * BUG 2644: Test for special files to be ignored was reversed.
+ * Ensure yield_connection() is called on all appropriate error
+ conditions.
+ * Fix EDEADLCK problem with deferred open calls.
+ * BUG 2622: Remove DPTR_MASK as it makes no sense.
+ * Fix the write cache based on some VERY good detective work
+ from Ingo Kilian.
+ * BUG 2346: Fix read-only excel file bugs.
+ * Don't wrap the setfsinfo call in HAVE_QUOTA as they'll just
+ return ENOSYS if not implemented.
+ * Add new CAP for POSIX pathnames.
+ * BUG 2703: Add NULL guard for disp_fields[0].
+ * BUG 2681: With "strict allocate = yes" we now zero fill when
+ a file is extended. Should catch disk full errors on write
+ from MS-Office.
+ * Add "acl check permissions" to turn on/off the new
+ behavior of checking for write access in a directory
+ before delete.
+ * Refactor printing interface to take offset into job.
+ * Allow mapping of POSIX ACLs to NT perms to differentiate
+ between directories and files.
+ * Added encrypt/decrypt function for LSA secrets and trusted
+ domain passwords on the wire.
+ * BUG 2729: Resume keys are *mandatory* for a search when
+ listing a W2K and above server from a FATxx filesystem only.
+ * BUG 2735: Ensure that smbd mangles control characters in file
+ and directory names.
+ * Refactor small pieces of socket handling code (in conjunction
+ with Derrell).
+ * BUG 2698: Fix infinite listing loop in smbclient caused by
+ an invalid character set conversion.
+ * Add client code that will abort a directory listing if we
+ see the same name twice between packets.
+ * Performance improvements in trans2 qfilepathinfo code by
+ removing unnecessary memset() calls.
+ * Rewrite the RPC bind parsing functions to follow the
+ spec; fixes bug with 64-bit Windows XP and OS X 10.4.
+ * BUG 2774: Set sparse flag if needed when returning
+ file attributes.
+ * Fix errors listing directories from Windows NT clients
+ which caused "." and ".." to show up in explorer.exe.
+ * Merge of error code fixes from SAMBA_4_0 branch.
+ * BUG 2801: Fix regression in the "delete veto files" option.
+ * Fix based on work from Shlomi Yaakobovich to catch loops
+ in corrupted tdb files.
+ * Allow someone with SeTakeOwnershipPrivilege to chown the
+ user of a file to herself.
+ * Fix minor compiler warnings in printing/printing.c.
+ * Merge new DOS error code from SAMBA_4.
+ * Fix issue when non-English characters in filenames and
+ directories.
+ * Fix bogus error message in smbstatus about unknown share modes.
+
+
+o Andrew Bartlett <abartlet@samba.org>
+ * Support raw NTLMSSP authentication for Windows Vista
+ clients.
+ * Fix parallel NTLMSSP processing by removing global state.
+ * BUG 2684: Add per service hosts allow/deny checks for
+ printers when connecting via MS-RPC.
+ * BUG 2391: Fix segv caused by free a static pointer returned
+ from getpwnam().
+ * Support kerberos authentication in smbd when using a keytab
+ and participating in a non-Microsoft Kerberos realm.
+
+
+o Timur Bakeyev <timur@com.bat.ru>
+ * BUG 2546: Add support for FreeBSD EA API
+ * Fix detection of FreeBSD 7.x platforms in autoconf checks.
+ * BUG 2908: Fix string length logic error in msdfs code.
+ * BUG 2909: Fix typo that caused smbd to call the wrong
+ aio_fsync function.
+
+
+o Ed Boraas <ed.boraas@concordia.ab.ca>.
+ * Added Linux per-socket TCP settings.
+
+
+o Gerald (Jerry) Carter <jerry@samba.org>
+ * Added support for \svcctl pipe rpcs.
+ * Added 'net rpc service' subcommand for managing Win32
+ services.
+ * Refactoring work on the rpc [un]marshalling layer and
+ structures.
+ * Verify privilege name in 'net rpc rights privileges' in
+ order to provide better error messages.
+ * Cleanup rpc structures in rpc_spoolss.h.
+ * Cleanups and fixes for the \winreg server code.
+ * Cleanup of rpc structures used by LsaEnumerateTrustedDomains.
+ * Fix bugs in client spoolss code after refactoring work.
+ * Fix Valgrind warnings of invalid reads in the spoolss
+ server code.
+ * Fixed a segv when enumerating services on a Samba host.
+ * Fix segv in the service control server code.
+ * Fix crashes in client spoolss calls caused by not checking
+ for a valid pointer from the caller.
+ * Fix regression in DeleteDriver() server routines.
+ * Fix dup_a_regval() when size is 0.
+ * Fix usrmgr.exe crash when viewing user properties at
+ debuglevel 10.
+ * Do not enumerate any privileges when 'enable privileges = no'
+ and log a message if a client tries.
+ * BUG 2872: Fix cut-n-paste error when checking pointer value
+ in ntlmssp_set_workstation().
+ * Fix upgrade path from earlier nt*tdb files.
+ * Removed print handle object cache.
+ * BUG 2853: Don't strip out characters like '$' from printer
+ names when substituting for the lpq command.
+ * BUG 2557: Gracefully fail on unsupported SetPrinter() levels.
+ * Fix build issues on x86_64-linux systems caused by valgrind
+ headers. Thanks to Bent Vangli to the suggestions.
+ * Refactor spoolss client calls.
+ * Adding 'username map script'.
+ * Disable schannel on the LSA and SAMR pipes in winbindd client
+ code to deal with Windows 2003 SP1 and Windows 2000 SP4 SR1.
+ * Cleanup of winreg API functions.
+ * Add server stubs for RegSetKeySec() and RegGetKeySec().
+ * Map generic bits to specific bits in reg_open_entry()
+ requests.
+ * Add write support to registry tdb and printing backends.
+ * Use tdb lookups rather than hard-coding certain registry
+ value names and data.
+ * BUG 2808: don't try to install man pages if they are not
+ present.
+ * Fix initialized variables reported by valgrind.
+ * Normalize key lookups in ntprinters.tdb.
+ * Mark "enumports command" as deprecated.
+ * Add missing class file for python share command example.
+ * Fix smbclient build issue on Solaris.
+ * BUG 2626: ensure that the calling_name is set to something
+ after parsing smb.conf (if not set via -n).
+ * Use "add machine script" when creating a user (ACB_NORMAL)
+ who has a name ending in '$' (e.g. usrmgr.exe creating
+ domain trust accounts).
+ * Add 'rid' synonym for idmap_rid IDMap module.
+ * Ensure that we set full access on the handle returned
+ from _samr_create_dom_{alias,group}() so that future
+ set_{alias,group}() commands succeed.
+ * Fix bug when looking for internal domains in winbindd
+ (caused winbindd_getgrgid() for local groups to fail).
+ * Fix query and set alias info calls (level 1 from the MMC
+ manage computer plug-in.
+ * Remove bogus log messages about unknown specversions.
+ * BUG 2680: copy files from an MS-DFS win2k root share
+ * BUG 2688: re-implement support for the -P (--port) option
+ * Support connecting to an 'msdfs proxy' share on a Samba
+ server.
+ * Strip the directory path from cups command line printing
+ defaults.
+ * Fix bug that prevented smbclient from creating directories
+ on non-dfs paths.
+ * Deprecate the "printer admin" parameter in favor of the
+ SePrintOperatorPrivilege.
+ * Add the capability to read and write WinNT regf registry
+ files.
+ * Implement access checks for RegOpenXXX() server calls.
+ * Extend registry client rpc calls.
+ * Add "net rpc registry" set of commands.
+ * Remove testprns tool.
+ * Ensure that printer ACLs use the specific bits as well as
+ the generic bits. Upgrade existing ntprinters.tdb SECDESC
+ records.
+ * Add server support for RegSaveKey() for dumping registry
+ trees to a regf file.
+ * Add "enable asu support" smb.conf parameter.
+ * Merge various small file changes from trunk.
+ * Remove "winbind enable local accounts" support.
+ * Remove "ldap filter" smb.conf option.
+ * Remove editreg utility (needs to be rewritten using regfio.c).
+ * Fix build failure when running 'make torture' without first
+ running 'make all' first.
+ * BUG 1261: Remove unusable libbiconv from iconv detection
+ in configure.
+ * Add new option for "map to guest". "Bad Uid" re-enables the
+ Samba 2.2 behavior of mapping authenticated users to the
+ guest account if there does not exist a valid Unix account
+ for the Windows domain user (based on patch from
+ aruna.prabakar@hp.com).
+ * Fix a couple of regressions after introduction of new winbindd.
+ * Fix smbpasswd user password change (still worked by bad error
+ messages) due to trying to strdup a NULL pointer.
+ * Implement default security descriptors for the
+ OpenService[Manager]() calls and check requested access mask
+ at connect time.
+ * Include access checks on handle mask for \svcctl operations
+ such as ControlService() and StartService().
+ * Implement simulated start and stop service control for
+ the spooler service as a per smbd service state value.
+ * Add interface structure for controlling service via rc.init
+ scripts (incomplete).
+ * Convert move_driver_to_download_area() to use copy_file()
+ rather than moving the files.
+ * Add version number to registry.tdb file since it can be
+ modified now.
+ * Remove over-paranoid assert() call when checking spoolss
+ buffer pointers
+ * Fix error in EnumPrinterData() reported by valgrind.
+ * Fix broken help links in SWAT editor caused by new doc layout.
+ * Ensure that a domain structure in winbind is initialized prior
+ to assigning the methods for communicating to a DC.
+ * BUG 3000: Remove background updates of winbind cache and allow
+ child processes to immediately update and expired cache entry.
+
+
+o David.Collier-Brown <David.Collier-Brown@sun.com>
+ * Added panic action script for Solaris.
+
+
+o Jeremy Cooper <jeremy@ncircle.com>
+ * Added support for several new \winreg client rpcs.
+
+
+o <core@road-star.jp>
+ * BUG 2792: Ensure the shadow copy module hooks seekdir,
+ telldir, rewinddir to match updated large directory code.
+
+
+o Guenther Deschner <gd@samba.org>
+ * Close handles on group creation in rpcclient to better
+ support mass group account creation.
+ * Fix account policy key lookup for minimum and maximum
+ password lengths.
+ * Fix some compiler warnings and add missing exclude-block
+ in 'net rpc share migrate'.
+ * Allow use of a non-default smb.conf by rpcclient.
+ * Fix querydispinfo search semantics in rpcclient test code.
+ * Fix querydispinfo server semantics to allow to list more
+ then 511 users.
+ * Fix server crash bug in ancient OpenPrinter() call.
+ * Fix a crash bug when enumerating privileges via the LSA
+ calls.
+ * Fix crash in EnumPrinterKey() client calls caused by previous
+ refactoring work.
+ * Various compiler warning fixes.
+ * Fix segfault in the client AddPrinterEx-call of 'net
+ rpc printer'.
+ * Fix build issues when --with-aio-support is enabled.
+ * BUG 2502: Removed the deprecated 'min passwd length parameter'.
+ * Honour the CC environment variable in python build.
+ * Fix searches in pdb_ldap for inter-domain trust accounts.
+ * Don't expand the %L in %LOGONSERVER% from user attributes.
+ * Fix bug in 'net rpc vampire' that caused accounts to be created
+ with no assigned ACB flags.
+ * Fix enumeration of builtin-aliases.
+ * Avoid unset rids for builtin-aliases.
+ * Add 'recycle:touch_mtime = true' vfs option for the recycle bin.
+ * More "net rpc share migrate" fixes.
+ * Merge PADL's idmap_ad plugin (taken from the latest
+ xad_oss_plugins-tarball).
+ * Add support for "idmap backend = ad" when "security = ads".
+ * Add home directory and shell support from AD via "winbindd nss
+ support = sfu" and "security = ads".
+ * Provide better feedback when we fail share-manipulation
+ due to missing scripts.
+ * Correctly substitute "\" as default winbind separator in
+ generate_parm_table.py example share command script.
+ * Document pam_winbind.c to clarify the working status of
+ require-membership-of option.
+ * Added client-support for various lsa_query_trust_dom_info()
+ calls and a rpcclient-tester for some info-levels.
+ * Add "net rpc trustdom vampire" tool (in conjunction with
+ Lars Mueller).
+ * Add missing cli_srvsvc_net_share_set_info-function and
+ rpcclient-testers (in preparation for net share acl migration).
+ * Print trusted domain passwords returned via rpcclient in
+ display charset.
+ * Error code fixes when attempting to manipulating
+ non-existent shares.
+ * Cleanup "net share migrate" code.
+ * Allow to touch mtime in vfs-recycle with "recycle:touch_mtime
+ = true".
+ * Allow admins to uncheck the "User must change Password at
+ next Logon" checkbox in User manager (merge from trunk).
+
+
+o Renaud Duhaut <rd@duhaut.com>
+ * BUG 1040: Add directory_mode parameter when creating recycle
+ directories.
+
+
+o Steven Edwards <steven_ed4153@yahoo.com>.
+ * Use chsize() if we don't have ftruncate().
+
+
+o Rodrigo Fernandez-Vizarra <Rodrigo.Fernandez-Vizarra@Sun.COM>
+ * BUG 1780: Add kerberos (file based ticket cache) support
+ to smbspool.
+
+
+o Steve French <sfrench@us.ibm.com>
+ * Update list of mount options for mount.cifs.
+ * Add more defines for POSIX extensions to match the newly
+ added client implementation.
+ * Add initial support for cifs umount utility.
+ * Fix cifs mounts to handle commas embedded in prompted
+ password, and password and credential files.
+ * Fix cifs mounts to handle domain name and user name in
+ username field (in form domain\user).
+ * Add missing error code mappings when a client unsuccessfully
+ tries to create a hard-link.
+ * Add support so umount.cifs can update mtab.
+ * Add two newer mount options to syntax help for mount.cifs.
+ * Add missing remount flag handling.
+ * Allow domain= to be specified in credentials file.
+ * Fix umount.cifs help, allow root to unmount someone else's
+ mount.
+ * Lock mtab when updating it during umount.cifs, also delete
+ only one matching entry at a time.
+ * Fix minor compiler warnings in the mount.cifs helper.
+
+
+o Deryck Hodge <deryck@samba.org>
+ * BUG 2137: Encode quotes for display in HTML (original patch
+ from Jay Fenlason).
+
+
+o Olaf Imig <Olaf.Imig@bifab.de>
+ * BUG 1998: Correct byte ordering bug when storing 16-bit RAP
+ print job ids.
+ * BUG 2653: Fix segv in rpcclient OpenPrinterEx() call.
+
+
+o Björn Jacke <bj@sernet.de>
+ * Added ioctl constants reported by msbackup.exe and filemon.exe.
+
+
+o Kevin Jamieson <bugzilla@kevinjamieson.com>
+ * BUG 2819: Fix typo when checking for ".." in smbd's statcache.
+
+
+o John Janosik <jpjanosi@us.ibm.com>
+ * BUG 2077: Correctly fill in the correct server name when
+ processing trusted domain logins.
+ * BUG 2976: Mark logons for unknown domains with a
+ non-authoritative response.
+
+
+o William Jojo <jojowil@hvcc.edu>
+ * AIX AIO fixes.
+
+
+o Guenter Kukkukk <guenter.kukkukk@kukkukk.com>
+ * BUG 2541: Fix copying of file(s) from samba share to an OS/2
+ local drive.
+
+
+o Tom Lackemann <cessnatomny@yahoo.com>
+ * BUG 2242: Patch to ensure that we only set the security
+ descriptor on an NTtransact create if we created the file.
+
+
+o Volker Lendecke <vl@samba.org>
+ * Port some of the non-critical changes from HEAD to 3_0.
+ The main one is the change in pdb_enum_alias_memberships
+ to match samr.idl a bit closer.
+ * Close handles on user creation in rpcclient to better
+ support mass user account creation.
+ * Implement client RAP calls for enumusers/enumgroups level 0.
+ * Implement a new caching API for enumerating the pdb elements.
+ * Convert the RAP user and group enumeration functions to the
+ utilized the pdb_search API.
+ * BUG 2438: Partial fix for 'net rpc trustdom establish' in
+ RestrictAnonymous environments.
+ * Internal passdb API changes for better search capabilities
+ (based on original work by Guenther Deschner).
+ * Fix various compiler warnings.
+ * Add chain length statistics to tdbtool.
+ * Fix set afs ACL calls on files and directories in the root of
+ a share.
+ * Refactoring work on internal open code
+ * Correctly initialize the version in a new set of nt*tdb files.
+ * Remove smb_run_idle_events() from main process loop in smbd
+ and instead rely upon the timeout processing to handle
+ dropping idle LDAP connections.
+ * Fix the bug where users show up as trusting domains.
+ * Fix an assertion failure in winbindd.
+ * Fix a memleak in vfs_afsacl.
+ * Various compiler warning fixes.
+ * Fix compile when --enable-socket-wrapper is defined.
+ * Fixes for top level acls in vfs_acl.c.
+ * Refactor passdb interface functions.
+ * Compile fixes when '#define PARANOID_MALLOC_CHECKER 1'.
+ * Correct 2 segv's in "net rpc printer migrate".
+ * Return correct group type from smbd for BUILTIN groups.
+ * Backport the talloc() layer from Samba 4.
+ * BUG 2701: Fix segv in ldap reconnection code.
+ * BUG 2705: Fix segv when connecting from usrmgr.exe.
+ * Use the SID in the user token for the %s expansion in 'afs
+ username map'.
+ * Memory leak fixes in passdb code.
+ * BUG 2720: Fixes for "net usersidlist".
+ * BUG 2725: Fix segv in "net ads user".
+ * Only allow schannel connections if a successful Auth2
+ has been previously performed.
+ * Don't look at gencache.tdb for the trusted domains if
+ winbind is present.
+ * Rewrite winbindd using an asynchronous process model.
+
+
+o Herb Lewis <herb@samba.org>
+ * Compiler warning cleanups.
+ * smbwrapper Makefile and compile time check cleanups.
+ * Adding robustness checks for tdbdump and tdbtool.
+ * Extend tdb command line parsing to arbitrary hex characters.
+ * Add LOCKING debug class.
+ * Fix more compiler warnings.
+
+
+o Derrell Lipman <derrell@samba.org>
+ * add support for opening a file for write with O_APPEND
+ in libsmbclient.
+ * Added smbsh/smbwrapper for Linux to example/libsmbclient
+ tree.
+ * Fix smbc_stat() from returning incorrect timestamps IFF
+ it used cli_qpathinfo2() to retrieve the timestamps (Win2k)
+ and not if it used cli-getatr() to retrieve the timestamps
+ (Win98).
+ * Fix handful of compiler warnings.
+ * BUG 2498, 2484: smbc_getxattr() fixes.
+ * BUG 1133: Added provision for overloading some global
+ configuration options via the new, per-user file
+ ~/.smb/smb.conf.append.
+ * BUG 2543: Properly cache anonymous username when reverting
+ to anonymous login, in libsmbclient.
+ * BUG 2505: Fix large file support in libsmbclient.
+ * BUG 2564: Ensure correct errno when smbc_opendir() was called
+ with a file rather than a directory.
+ * Correct deprecated lvalue casts in testsuite/libsmbclient.
+ * BUG 2663. cli_getattrE() and cli_setattrE() were not
+ formatting or parsing the timestamp values correctly.
+ * Correctly detect AF_LOCAL support in configure.
+ * Fix problem updating file times on Windows 98 hosts using
+ libsmbclient.
+ * Fix compile breakage on Solaris by eliminating the use of
+ ctime_r() in libsmbclient DEBUG statement.
+
+
+o Jason Mader <jason@ncac.gwu.edu>
+ * BUG 2483, 2468. 2469, 2478, 2093: Compiler warning fixes.
+ * Various compiler warning fixes about mistyped variables.
+ * BUG 2882, 2885, 2890, 2891, 2900: Various compiler warning fixes
+ and code cleanups.
+ * BUG 2527, 2538: Removed unused variables.
+
+
+o Marcel <samba.10.maazl@spamgourmet.com>
+ * Fix regression in OS/2 trans2 open code.
+
+
+o Jim McDonough <jmcd@us.ibm.com>
+ * Fixes for samr_lookup_rids() when using ldapsam:trusted=yes
+ (in conjunction with Volker).
+ * BUG 2953: Prevent the credentials chain on DC gets out
+ of sync with client when NT_STATUS_NO_USER is returned.
+ * Added subcommands to "net rpc vampire" (mostly done by Don
+ Watson <dwatson@us.ibm.com>) to allow data to be put into an
+ ldif file instead of actually writing to the passdb.
+ * BUG 2736: Add retries to workaround winbind race condition
+ with detecting idle clients.
+ * BUG 2953: Additional fixes for domain trusts. Also clears
+ up the "bad stub" error when attempting to logon to a Samba
+ domain with a bad username.
+
+
+o Luke Mewburn <lukem@NetBSD.org>
+ * Compiler warning fixes.
+
+
+o Kalim Moghul <kalim@samba.org>
+ * Removed unused printmode command from smbclient.
+
+
+o Lars Müller <lmuelle@samba.org>
+ * Re-enable the VERSION_REVISION option in case of another
+ letter release.
+ * Fix spoolss python bindings after C++ compiler changes and
+ other python fixes.
+ * BUG 2659: Don't trump on memory in smbtorture.
+ * BUG 2060: Add -fPIC which is the case for all other Samba
+ shared libs.
+ * Fix argv parsing in "net rpc".
+ * Add support to create position independent executable (PIE)
+ code if the compiler supports it.
+ * BUG 2767: Add new options to testparm (--show-all-parameters,
+ --parameter-name, and --section-name).
+ * Fix net share migrate files to also migrate the ACLs of
+ the top level dir of a share.
+
+
+o Marcel Muller <mueller@maazl.de>
+ * Patch to fix the OS/2 EA_FROM_LIST info level call.
+ * Mangled names fix for OS/2 clients.
+ * Ensure we correctly set the return packet size to include the
+ pad bytes in reply_readbmpx().
+ * Fix for bug in SMBwriteBraw that incorrectly returned the
+ number of bytes written.
+
+
+o Ricky Nance <ricky.nance@gmail.com>
+ * Implemented mklogon script generator for domain logon scripts.
+
+
+o James Peach <jpeach@sgi.com>
+ * BUG 1843: Fix quotas (with no soft limits) on IRIX.
+ * BUG 2285: Patch for hires timestamps and efficient notify code.
+ * MS-DFS tidyup patches.
+ * Build fixes on IRIX.
+ * IRIX compiler warning fixes.
+ * BUG 2596: Fix become_root link issues and one IRIX stack
+ backtrace bug.
+ * Fix for null pointer ACL free.
+ * BUG 2314: Fix const compiler warnings in the quota code.
+
+
+o Ed Plese <ed@edplese.com>
+ * Fix faulty logic which caused winbindd to return failure
+ when a user possessed no supplementary groups.
+
+
+o Marcin Porwit <mporwit@centeris.com>
+ * Initial support for the \eventlog pipe.
+ * Fix a memleak in the eventlog code.
+ * Miscellaneous fixes for Samba's experimental event log support.
+ * Add ServiceQueryConfig2() and ServiceQueryStatusEx() server
+ calls.
+
+
+o Tim Potter <tpot@samba.org>
+ * BUG 2940, 2943: Fixed various compiler warnings regarding
+ mismatched types and unused variables.
+ * BUG 1888, 1894: Fix warnings when time_t is an unsigned type.
+ * BUG 2733: Fix incorrect SHLIBEXT is set when running
+ configure script on HPUX IA.
+ * Remove unused autoconf #define's.
+ * BUG 2893: Fix inverted assignment in 'net rpc printer' code.
+ * Removed unused function declarations in tdb.h.
+ * BUG 2895: Don't wrap non-existent functions in the python
+ tdb bindings.
+ * BUG 2623, 2630: $< and $* are not valid in explicit rules
+ according to POSIX.
+ * BUG 2560: Fix compile error lurking where PATH_MAX is not
+ defined.
+ * BUG 2625: Remove configure check for FTRUNCATE_NEEDS_ROOT.
+ * BUG 2611: Add fflush(stdout) after displaying username prompt
+ in smbsh if username not specified on command line.
+ * BUG 2699: Fix for segfault in samba.winbind.auth_crap module
+ * BUG 2808: Update install swat message to reflect the fact
+ that swat/README no longer exists.
+
+
+o Denis Sbragion <d.sbragion@infotecna.it>
+ * BUG 2196: Allow absolute path (system wide) recycle bin.
+
+
+o Fernando Schapachnik <fernando@mecon.gov.ar>
+ * Add logon hours support for the Postgres backend.
+
+
+o Richard Sharpe <rsharpe@samba.org>
+ * Fix bug in profiles tool caused by use of MAP_PRIVATE.
+
+o Joerg Sonnenberger <joerg@leaf.dragonflybsd.org>
+ * BUG 2362: Quota support fix for DragonFly.
+ * Fix dragonfly detection in configure.
+
+
+o Simo Sorce <idra@samba.org>
+ * Allow Domain Admins to force user sessions to close via the
+ Windows Server Manager.
+ * Add support to 'net rpc right privileges <name>' to enumerate
+ accounts which possess a specific privilege.
+ * Fix memory issues issues in vfstest (reported by Rainer Link).
+ * Randomize reloading as to not overload cupsd.
+
+
+o Smitty <smitty@plainjoe.org>
+ * Compile fixes for smbget when using --enable-developer.
+ * Include LUID values to match Windows privileges since
+ apparently this matters to printmig.exe
+
+
+o John Terpstra <jht@samba.org>
+ * Solaris packaging fixes.
+ * Clean up usage help text in "net rpc user"
+
+
+o Andrew Tridgell <tridge@samba.org>
+ * Merge socket wrapper library fixes from Samba 4.
+
+
+o Brett Trotter <blt@iastate.edu>
+ * Fix definition of global_sid_* in vfs_acl.c.
+
+
+o Mark Weaver <mark-clist@npsl.co.uk>
+ * Patch to fix sys_select so it can't drop signals if another
+ fd is ready to read.
+
+
+o Jelmer Vernooij <jelmer@samba.org>
+ * Remove --with-manpage-languages configure option.
+ * Merge socket wrapper fixes for IRIX systems from the
+ Samba 4 branch.
+ * Add socket_wrapper library to 3.0. Can be enabled by passing
+ --enable-socket-wrapper to configure.
+ * Fix build of the various sql pdb backends after new talloc.
+
+
+o Qiao Yang <qyang@stbernard.com>
+ * Use our own DC when getting the SID for a domain.
+
+
+
+Release Notes for older release follow:
+
+ --------------------------------------------------
+ ===============================
+ Release Notes for Samba 3.0.14a
+ Apr 14, 2005
+ ===============================
+
+Common bugs fixed in 3.0.14a include:
+
+ o Compatibility issues between Winbind and Windows 2003 SP1
+ domain controllers (*2k3sp1*).
+ o MS-DFS errors with Windows XP SP2 clients.
+ o High CPU loads caused by infinite loops in the FindNext()
+ server code.
+ o Invalid SMB_ASSERT() which caused smbd to panic on ACL'd
+ files.
+
+
+######################################################################
+Changes
+#######
+
+Changes since 3.0.14
+--------------------
+
+commits
+-------
+o Jeremy Allison <jra@samba.org>
+ * Fixed invalid SMB_ASSERT() triggered by checking access on
+ ACL'd files.
+
+
+Changes since 3.0.13
+--------------------
+
+smb.conf changes
+----------------
+
+ Parameter Name Action
+ -------------- ------
+ dos filetimes Enabled by default
+
+
+commits
+-------
+o Jeremy Allison <jra@samba.org>
+ * Prevent nt_status code support when negotiating protocols
+ earlier than NT1.
+ * BUG 2533: Remove the UNICODE flags2 bit from SMBsearch calls
+ as this SMB is DOS codepage only.
+ * BUG 2585: Fix printf() issues in smbpasswd which caused
+ seg faults.
+ * BUG 2563: Fix infinite loop on non-existent file with
+ FindNext().
+ * BUG 2581 (partial): Ensure if realloc fails on an internal
+ tdb we fail gracefully.
+ * Ensure that 'dos filetimes' works with ACLs.
+ * Set 'dos filetimes = yes' as the default for smb.conf.
+
+
+o Gerald (Jerry) Carter <jerry@samba.org>
+ * Workaround autoconf issue to prevent debug symbols from
+ being included in the default build.
+ * Disable schannel on the \lsarpc pipe in order to successfully
+ enumerate users and groups (*2k3sp1*)
+ * Fix parsing error in rpc binds which broke NTLMSSP
+ authentication. And as a result broke CTL+ALT+DEL password
+ changes from a Windows 2003 SP1 member of a Samba domain
+ (*2k3sp1*).
+ * Revert change to FindFirst() server code that broke WinXP
+ SP2 clients from launching *.exe files from a dfs target
+ share.
+ * BUG 2588: Force smbclient to send netbios messages to port
+ 139 unless otherwise instructed (based on patch from Thomas
+ Bork).
+
+
+o Volker Lendecke <vl@samba.org>
+ * Fix build on FreeBSD 4 where Winbind is not supported.
+ * Fix 'wbinfo --user-sids' when using domain local groups.
+ * Restrict domain local groups reported by 'wbinfo -r' to
+ the Samba server domain and not the users domain.
+
+
+o Lin Li <linl@xandros.com>
+ * Ensure that winbind initializes internal trusted domain
+ structures when enumerating users and groups.
+
+
+o Tim Potter <tpot@samba.org>
+ * BUG 2565: Fix crash bug and compiler warnings in strchr_m()
+ test.
+ * Fix compiler warnings.
+
+
+o <psz@maths.usyd.edu.au>
+ * Fix for possible root squash NFS bugs.
+
+
+o Simo Sorce <irda@samba.org>
+ * Debian packaging fixes.
+
+
+ --------------------------------------------------
+ ==============================
+ Release Notes for Samba 3.0.13
+ Mar 24, 2005
+ ==============================
+
+Common bugs fixed in 3.0.13 include:
+
+ o Infinite FindNext() loop from Windows 9x client when
+ copying or deleting files on a Samba file share using
+ explorer.exe.
+ o Numerous smbclient bugs when listing directories.
+ o Failures in smbclient when connecting to a Windows 9x
+ file server.
+
+
+######################################################################
+Changes
+#######
+
+Changes since 3.0.12
+--------------------
+
+o Jeremy Allison <jra@samba.org>
+ * Fix typo bug in smbclient where flags overwrote info level
+ in the cli_list_new().
+ * Fix old smbclient bug where ff_searchcount was being compared
+ to -1 resulting in processing a filename twice.
+ * Fix segv in smbclient caused by overwriting the last 2 bytes
+ in cli_list_new().
+ * BUG 2530: Fix potential segv in smbclient when talking to a
+ Windows 9x file server.
+ * Fix last entry offset in cli_list_new() when using a
+ FindFirst/FindNext info level of 0x104.
+ * BUG 2501: Stop Win98 from looping doing FindNext on a
+ singleton directory.
+ * BUG 2521: Fix error in access checks when user group ACLs.
+
+
+o Gerald (Jerry) Carter <jerry@samba.org>
+ * BUG 2497: Fix bug in rpcclient's deletedriverex when asking
+ to delete all versions of a driver.
+ * BUG 2517: use the realm from smb.conf for 'net ads info' when
+ 'disable netbios = yes'.
+ * BUG 2530: Ensure that smbclient correctly detects MS-DFS root
+ shares.
+ * Update RedHat packaging files to require cups support. Also
+ remove requirement for 'idmap {uid,gid}' settings in smb.conf
+ from winbindd init script.
+ * BUG 2516: fix compile issue on True64.
+
+
+
+o Guenther Deschner <gd@samba.org>
+ * Check for the correct cli-struct when copying files in 'net
+ rpc printer' routines.
+
+
+o Herb Lewis <herb@samba.org>
+ * Fix incorrect test in 'net rpc user' when the user is not
+ a member of any groups.
+
+
+o Jim McDonough <jmcd@us.ibm.com>
+ * Make sure that enum_group_members() searches the correct suffix.
+
+
+ --------------------------------------------------
+ ==============================
+ Release Notes for Samba 3.0.12
+ Mar 18, 2005
+ ==============================
+
+Common bugs fixed in 3.0.12 include:
+
+ o Winbind failures when using 'disable netbios = yes'
+ o Failure to establish a trust relationship via 'net rpc trust
+ establish'
+ o Various portability & compiler issues.
+ o Read only file deletion failure caused by new delete semantics
+ in Windows XP SP2 and the MS 04-044 security hotfix.
+ o Error messages from shared Excel workbooks residing on Samba
+ file shares.
+ o Missing files in the output of smbclient -c 'dir' when run
+ against Windows file servers.
+ o Inability for Print Administrators to pause/resume/purge print
+ queues.
+
+Additional features introduced in Samba 3.0.12:
+
+ o Performance enhancements when serving directories containing
+ large number of files.
+ o MS-DFS support added to smbclient.
+ o More performance improvements when using Samba/OpenLDAP based
+ DC's via the 'ldapsam:trusted=yes' option.
+ o Support for the Novell NDS universal password when using the
+ ldapsam passdb backend.
+ o New 'net rpc trustdom {add,del}' functionality to eventually
+ replace 'smbpasswd {-a,-x} -i'.
+ o New libsmbclient functionality.
+
+
+
+=======================
+Large Directory Support
+=======================
+
+Samba 3.0.12pre1 introduces a specific mechanism for dealing
+with file services that frequently contain a large number of files
+per directory. Historically Samba's performance has suffered
+in such environments due to the translation from case
+insensitive lookups by Windows client to the case sensitive
+storage mechanisms used by UNIX filesystems.
+
+Configuration details along with a short HOWTO can be found at:
+
+http://www.samba.org/samba/ftp/HOWTO/Samba-LargeDirectory-HOWTO
+
+
+==================================
+libsmbclient Binary Compatibility
+==================================
+
+Please note that a change has been made to the _SMBCCTX structure
+in source/include/libsmbclient.h. This change is not backwards
+compatible with applications linked against the libsmbclient.so
+library from Samba 3.0.11. However, it is compatible with all
+other Samba 3.0.x releases. This means that it will be most likely
+be necessary to recompile any applications linked against the
+3.0.11 version of the library.
+
+
+######################################################################
+Changes
+#######
+
+smb.conf changes
+----------------
+
+ Parameter Name Action
+ -------------- ------
+ allocation roundup size New
+ log nt token command New
+ write cache Deprecated
+
+
+
+Changes since 3.0.11
+--------------------
+
+commits
+-------
+o Jeremy Allison <jra@samba.org>
+ * BUG 2146: Return correct allocation sizes so as not to crash
+ the VC++ compiler.
+ * BUG 962: Ensure that parsing of service names in smb.conf is
+ multibyte safe.
+ * BUG 2201, 2227: Support new delete semantics used by MS04-044
+ and XP SP2.
+ * BUG 1525: Correctly timestamps interpreted on 64-bit time_t
+ values (patch submitted by Jay Fenlason <fenlason@redhat.com>).
+ * Add special hooks when serving directories containing large
+ numbers of files.
+ * Ensure that WINS negative name query responses and WACK
+ packets use the correct RR type of 0xA instead of reflecting
+ back what the query RR type was (0x20).
+ * BUG 2310: Only do 16-bit normalization on small dfree request.
+ * BUG 2323: Correct authentication failure when using plaintext
+ passwords from Windows XP clients.
+ * BUG 2146: Add new smb.conf option 'allocation roundup size' to
+ work around issues building MS Visual Studio 6.0 project
+ on a Samba file share while restoring the pre-3.0.21pre1
+ behavior by default.
+ * BUG 2399 (partial): Ensure we use SMB_VFS_STAT instead of
+ stat when checking for existence of a pathname.
+ * Check the sticky bit on the parent directory for supporting
+ the new WinXP SP2 file deletion semantics.
+ * Various oplock, share mode, and byte range locking fixes
+ found by Connectathon tests.
+ * BUG 2271: Fix resume key issues in trans2FindFirst() client
+ code (inspired by patch from Satwik Hebbar).
+ * BUG 2382, 2045: More pending modtime and delayed write fixes
+ for MS Excel (incorporates partial patches from
+ ke_miyata@itg.hitachi.co.jp).
+ * Debug log message cleanups.
+ * Add case insensitive search for a principal match on logon
+ verification in the system keytab (based on patch by
+ Michael Brown <mbrown@fensystems.co.uk>).
+ * Revert the previous SMB signing change from Nalin Dahyabhai
+ when using DES keys.
+ * Add missing RESOLVE_DFSPATH() calls for older SMB commands.
+ * Fix FindFirst() server code to deal with resume names of ".."
+ and "." (found by Jim McDonough).
+ * BUG 2451: Fix missing functions in full audit VFS module.
+ * Ensure that smbd logs failures reported by DISK_FREE()
+ (reported by Ying Li <ying.li2@hp.com>).
+ * Ensure that smbclient obeys the max protocol argument again.
+ * BUG 2335: Return correct error code for OS/2 clients (based on
+ negotiated protocol level).
+ * BUG 2460, 2464: remove dead code and unused variables
+ (reported by Jason Mader).
+
+
+o Andrew Bartlett <abartlet@samba.org>
+ * Avoid length-limited intermediate copy of NT and LM responses
+ in NETLOGON client.
+ * Debug message cleanups in the NTLMSSP implementation.
+
+
+o Manuel Baena <mbaena@lcc.uma.es>
+ * Print actual error message in smbmnt.c:fullpath().
+
+
+o Vince Brimhall <vbrimhall@novell.com>
+ * Add support for Novell NDS universal password.
+ * BUG 2424: Ensure that uidNumber and gidNumber use match
+ the RFC2307 schema.
+ * BUG 2453: Change the way pdb_nds.c handles users with no
+ Universal or Simple Password.
+ * NDS schema file corrections.
+
+
+o Gerald (Jerry) Carter <jerry@samba.org>
+ * Add trans2 client call for checking dfs referrals
+ * Convert smbclient to use TRANS_QPATHINFO(SMB_QUERY_FILE_BASIC_INFO)
+ when checking directories on modern CIFS servers.
+ * Add MS-DFS support to smbclient.
+ * Code cleanup of adt_tree.[ch].
+ * Add missing checks to allow root to manage user rights.
+ * Allow domain admins to manage rights assignments on domain members
+ servers.
+ * BUG 2333: Use the lpq command to pass in the correct printer name
+ for cups_queue_get(). CUPS backend now sets 'lpq command= %p' as
+ the default.
+ * BUG 1439: make sure to initialize pointer to prevent invalid
+ free()'s on exit.
+ * BUG 2329: fix to re-enable winbindd to locate DC's when 'disable
+ netbios = yes'.
+ * Add cups-devel to BuidlRequires directive in Fedora spec file.
+ * BUG 858: Fix order of popt args evaluation so we don't crash
+ when given no command line args.
+ * Remove dependency on bash for source/autogen.sh.
+ * Fix clitar.c compile issues caused by broken MIT 1.4 headers.
+ * Implement MS-DFS for recursive directory listings in smbclient.
+ * BUG 2394: Fix nmbd linking issue on IRIX.
+ * Only display the publish check box in the client's printer
+ properties dialog if we are a member of an AD domain.
+ * BUG 2363: allow 'in use' driver to be removed as long as
+ one 'Windows NT x86' driver remains.
+ * BUG 1881: Allow PRINT_SPOOL_PREFIX to be set in local.h for
+ porting purposes.
+ * Enforce better printer.tdb cache consistency when removing
+ jobs from a print queue via SMB.
+ * Ensure that pause/resume/purge print queue commands are run
+ with the appropriate level of privilege necessary to actually
+ work.
+ * BUG 2355: Use bsd style commands (lpq, lpr, etc...) for default
+ for 'printing = cups' installations that do not actually have
+ libcups.
+ * BUG 2425: Remove incorrect checks for Win98 DFS clients.
+ * BUG 2215: Rewrite questionable code that was causing gcc to
+ choke.
+ * Add server support for LsaLookupPrivValue().
+ * Various small compile fixes and cleanup warnings.
+ * BUG 2456: Fix compile failure on non-gcc platforms due to
+ non-standard pragma.
+
+
+o Kevin Dalley <kevin@kelphead.org>
+ * BUG 2398: Don't force smbclient to assume a dry run if the
+ target tarfile is /dev/null.
+
+
+o Guenther Deschner <gd@samba.org>
+ * Fix crash bug in the client-spoolss enumdataex-call.
+ * Expand the valid-workstation-scheme by expanding names
+ beginning with a plus (+) as a unix group.
+ * Allow own netbios name to be set in smbclient's session setup.
+ * Better handling of LDAP over IPC connections that have expired
+ on the LDAP-Server.
+ * Fix pipe-mismatch for NETDFS in cli_dfs.c.
+ * Add examples/misc/adssearch.pl.
+ * BUG 2343: Build fixes.
+ * Support get_user_info_7 in SAMR server RPC.
+ * Fix server_role in the samr_query_dom_info calls.
+ * Add example perl script to check for multiple LDAP entries
+ after running 'net rpc vampire'.
+ * Add more output when listing printer forms via rpcclient.
+ * Debug log message cleanup.
+
+
+o Steve French <sfrench@us.ibm.com>
+ * On failed mount (ENXIO) retry share name in uppercase (fix
+ mount to FastConnect AIX SMB server).
+ * Add missing FILE_ATTRIBUTE_XXX defines to smb.h.
+ * Ignore user_xattr mount parm (mount.cifs) so as not to confuse
+ it with a user name.
+ * Update for new CIFS POSIX info levels.
+ * Ignore users mount parm in mount.cifs.
+
+o SATOH Fumiyasu <fumiya@samba.gr.jp>
+ * BUG 1549: Don't truncate service names in smbstatus.
+
+
+o William Jojo <jojowil@hvcc.edu>
+ * BUG 2445: Patch to avoid default ACLs on AIX.
+
+
+o S Murthy Kambhampaty <smk_va@yahoo.com>
+ * Add idmap_rid module to Fedora and RedHat spec files.
+
+
+o Volker Lendecke <vl@samba.org>
+ * BUG 2401: Flush internal getpwnam() cache after deleting a
+ user.
+ * BUG 1604: Make winbind work with more than 10 trusted domains.
+ * Cleanup various compiler warnings.
+ * Fix a memory leaks in privileges code and passdb backends.
+ * Fixes for samr_lookup_sids() client call.
+ * Optimize _samr_query_groupmem with LDAP backend for large
+ domains.
+ * Support SIDs as %s replacements in the afs username map
+ parameter.
+ * Add 'log nt token command' parameter. If set, %s is replaced
+ with the user sid, and %t takes all the group sids.
+ * Do not use the "Local Unix Group"-default description for
+ all kinds of group-mappings.
+ * Fix uninitialized variable in Linux nss_winbind library.
+ * Move 'net afskey' into a subcommand of its own, 'net afs key'.
+ * Implement 'net afs impersonate'.
+
+
+o Herb Lewis <herb@samba.org>
+ * Fix build problem when HAVE_POSIX_ACL is not defined.
+ * BUG 2417: Add help lines for net rpc group addmem and
+ delmem commands.
+
+
+o Derrell Lipman <derrell.lipman@unwireduniverse.com>
+ * Add support to libsmbclient for getting and setting DOS
+ attributes using EA functions.
+ * Fix libsmbclient's URL encoding/decoding.
+ * Replace browse listing URI queries with an internal options
+ structure (previous method violated the SMB URI syntax).
+ * Allow tree connects to be multiplexed over a single CIFS server
+ connection context.
+ * Ensure that cli_tdis() sets the cnum field to -1 so that callers
+ can determine a dead tree connection.
+ * Implement better solution for backwards binary compatibility
+ in libsmbclient while adding new fields to struct _SMBCCTX.
+
+
+o Mark Loeser <halcy0n@gentoo.org>
+ * BUG 2443: Compile fix for gcc4.
+
+
+o Jim McDonough <jmcd@us.ibm.com>
+ * BUG 2338: Fix coredump when OS/2 checks for long file name
+ support (with .+,;=[].) (thanks to Guenter Kukkukk).
+
+
+o Jason Mader <jason@ncac.gwu.edu>
+ * Compiler warning fixes (BUGS BUG 2132, 2134, 2289, 2327, 2340,
+ 2341, 2342)
+
+
+o Jim McDonough <jmcd@us.ibm.com>
+ * Fixes for server schannel implementation when 'restrict
+ anonymous = 1' is set in smb.conf.
+ * Fix bug in server side lookupsids reply that crashed lsass.exe
+ on Windows clients.
+ * Fix 'net rpc trustdom establish'.
+ * BUG 2062: Turn off broadcast for all 390 NICs.
+ * Fix 'net rpc trustdom add' to correctly add new domain trust
+ accounts. This will eventually replace 'smbpasswd -a -i'.
+ * Implement 'net rpc trustdom del', including client side of
+ samr_remove_sid_from_foreign_domain.
+ * Bring IBM Directory Server schema up to date with openldap
+ schema.
+ * Allow for better protection of sensitive attributes in IBM
+ Directory Server.
+
+
+o Stefan Metzmacher <metze@samba.org>
+ * Fix memleaks in the nttrans code.
+
+
+o Mike Nix <mnix@wanm.com.au>
+ * Add SMBsplopen and SMBsplclose client calls.
+
+
+o Justin Ossevoort <justin@snt.utwente.nl>
+ * BUG 2316: Fix crashes in pdb_pgsql.
+
+
+o James Peach <jpeach@sgi.com>
+ * Fixes in string handling code.
+ * Fix oplock2 test in client smbtorture.
+
+
+o Tim Potter <tpot@samba.org>
+ * Fix up example pdb modules after prototype change for
+ setsampwent.
+ * BUG 2058: Fix for shared object creation in examples.
+ * BUG 2315: Fix segv in LSA privileges server code.
+ * Build fixes for python wrapper libraries.
+
+
+o Richard Sharpe <rsharpe@samba.org>
+ * BUG 2044: Fix segv in profiles tool.
+ * Fix bogus error messages when enumerating user group
+ membership via 'net rpc'.
+
+
+o Simo Sorce <idra@samba.org>
+ * Debian packaging fixes.
+
+
+o John Terpstra <jht@samba.org>
+ * Add the capability to set account description using pdbedit.
+
+
+o Doug VanLeuven <roamdad@sonic.net>
+ * Add more case/realm/name permutations to the kerberos keytab.
+ * AIX compile fixes.
+
+
+o Jelmer Vernooij <jelmer@samba.org>
+ * BUG 892: Default unknown_6 field to 1260 in mySQL pdb module.
+ * BUG 1957: Implement minimal update of fields in mySQL pdb
+ module.
+
+
+o Torsten Werner <torsten.werner@assyst-intl.com>
+ * BUG 2405: Define 'lpstat' printcap output on HPUX.
+
+
+o Shlomi Yaakobovich" <Shlomi@exanet.com>
+ * Detect infinite loops when traversing tdbs.
+
+
+ --------------------------------------------------
+ ==============================
+ Release Notes for Samba 3.0.11
+ Feb 5, 2005
+ ==============================
+
+Common bugs fixed in 3.0.11 include:
+
+ o Crash in smbd when using CUPS printing.
+ o Parsing error of other SIDs included in the user_info_3
+ structure returned from domain controllers.
+ o Inefficiencies when searching non-AD LDAP directories.
+ o Failure to expand variables in user domain attributes
+ in tdbsam and ldapsam.
+ o Memory leaks.
+ o Failure to retrieve certain attribute when migrating from
+ a Windows DC to a Samba DC via 'net rpc vampire'.
+ o Numerous printing bugs bugs including memory
+ bloating on large/busy print servers.
+ o Compatibility issues with Exchange 5.5 SP4.
+ o sendfile fixes.
+
+Additional features introduced in Samba 3.0.11:
+
+ o Winbindd performance improvements.
+ o More 'net rpc vampire' functionality.
+ o Support for the Windows privilege model to assign rights
+ to specific SIDs.
+ o New administrative options to the 'net rpc' command.
+
+
+============
+LDAP Changes
+============
+
+If "ldap user suffix" or "ldap machine suffix" are defined in
+smb.conf, all user-accounts must reside below the user suffix,
+and all machine and inter-domain trust-accounts must be located
+below the machine suffix. Previous Samba releases would fall
+back to searching the 'ldap suffix' in some cases.
+
+
+===============
+Privilege Model
+===============
+
+Samba 3.0.11 supports the following assignable rights
+
+SeMachineAccountPrivilege Add machines to domain
+SePrintOperatorPrivilege Manage printers
+SeAddUsersPrivilege Add users and groups to the domain
+SeRemoteShutdownPrivilege Force shutdown from a remote system
+SeDiskOperatorPrivilege Manage disk shares
+
+These rights can be assigned to arbitrary users or groups
+via the 'net rpc rights grant/revoke' command. More details
+of Samba's privilege implementation can be found in the
+Samba-HOWTO-Collection.
+
+
+######################################################################
+Changes
+#######
+
+Changes since 3.0.10
+--------------------
+
+smb.conf changes
+----------------
+
+ Parameter Name Action
+ -------------- ------
+ afs token lifetime New
+ enable privileges New
+ ldap password sync Alias
+ min password length Deprecated
+ winbind enable local accounts Deprecated
+
+
+commits
+-------
+o Jeremy Allison <jra@samba.org>
+ * Extend vfs to add seekdir/telldir/rewinddir.
+ * Fix dirent return.
+ * Fix bugs when handling secondary trans2 requests.
+ * Implementation of get posix acls in UNIX extensions.
+ * Added set posix acl functionality into the UNIX extensions code.
+ * Updated config.guess/config.sub .
+ * Fix error reply when 'follow symlinks = no'.
+ * BUG 1061, 2045: Only set mtime from pending_modtime if it's
+ not already zero.
+ * Fixes for LARGE_READX support.
+ * Fix the problem we get on Linux where sendfile fails, but we've
+ already sent the header using send().
+ * BUG 2081: Ensure SE_DESC_DACL_PROTECTED is set if 'map acl
+ inherit = no'.
+ * BUG 2088: Ensure inherit permissions is only applied on a new
+ file, not an existing one.
+ * Don't go fishing for the krb5 authorization data unless we know
+ it's there.
+ * Fixes for libsmbclient to ensure that interrupted system calls
+ are restarted minus the already expired portion of the timeout
+ (based on work by Derrell Lipman).
+ * More Unicode string parsing fixes.
+ * Convert the winreg pipe to use WERROR returns.
+ * Make all LDAP timeouts consistent (input from Joe Meadows
+ <jameadows@webopolis.com>).
+ * BUG 2231: Remove double "\\" from client findfirst.
+ * BUG 2238: Fix memory leak in shadow copy vfs.
+ * Return correct DOS/NT error code on transact named pipe on
+ closed pipe handle.
+ * BUG 2211: Fix security descriptor parsing bug (based on work by
+ Mrinal Kalakrishnan <mail@mrinal.net>).
+ * BUG 2270: Fix memory leaks in cups printing backend support
+ (based on work by Lars Mueller).
+ * BUG 2255: Fix debug level in kerberos error messages.
+ * BUG 2110: Ensure we convert to ucs2 correctly after the
+ CAN-2004-0930 patch.
+ * Make strict locking an enum. Auto means use oplock optimization.
+ * Fix client & server to allow 127k READX calls.
+ * More *alloc fixes (includes additional fixes by Albert Chin.
+ * Catch sendfile errors correctly and return the correct values
+ we want the caller to return.
+ * BUG 2092: Prevent auto-anonymous logins via libsmbclient
+ for better use by desktop environments such as GNOME.
+ * Ensure we can't remove a level II oplock without having the
+ shared memory area locked.
+
+
+o Timur Bakeyev <timur@com.bat.ru>
+ * BUG 2100: change the way we check for errors after a dlopen().
+ * BUG 2263: Guard base64_encode_data_blob() against empty blobs.
+
+
+o Andrew Bartlett <abartlet@samba.org>
+ * Clarify error message when 'lanman auth = no'.
+ * Remove the unnecessary UTF-8 conversion calls in the calls to
+ auth_winbind from smbd.
+ * Don't store the auth-user credentials with the cli_state* as
+ this can cause the schannel setup to fail when the auth-user
+ domain is not our primary domain.
+
+
+o Grigory Batalov <bga@altlinux.org>
+ * Fix encoding while receiving of a message which was actually
+ sent using STR_ASCII.
+
+
+o Daniel Beschorner <db@unit-netz.de>
+ * BUG 603: Correct access mask check for _samr_lookup_domain()
+ to work with Windows RAS server
+
+
+o Jerome Borsboom <j.borsboom@erasmusmc.nl>
+ * Fix missing printer_tdb reference decrement.
+
+
+o Gerald (Jerry) Carter <jerry@samba.org>
+ * BUG 2073: fall back to smb_name if current_user_info is not
+ available in lp_file_list_changed().
+ * Fixes the spurious 'register_message_flags: tdb fetch failed'
+ errors.
+ * Don't run the background LPQ daemon when we are running in
+ interactive mode.
+ * prevent the background LPQ daemon from updating the print queue
+ cache just because multiple smbd processes sent a message that
+ it was out of date.
+ * consolidate printer searches to use find_service rather than
+ for(...) loops.
+ * BUG 2091: don't remove statically defined printers in
+ remove_stale_printers().
+ * Fix logic error in add_a_form() that only compared N characters
+ instead of the entire form name.
+ * BUG 2107: fix memory bloating caused by large numbers of
+ print_queue_updates() requests sent via messages.tdb.
+ * Check the setprinter(3) based on the access permissions on
+ the handle and avoid the call to print_access_check().
+ * Re-instantiate previous semantics for calling init_unistr2()
+ with a NULL source buffer.
+ * Support Windows privilege model for assigning rights
+ to specific SIDs. Based on work by Simo Sorce in the trunk
+ svn branch. This feature is controlled by the 'enable
+ privileges = [yes|no]' smb.conf(5) option.
+ * Add some smb.conf scripts for add/delete/change shares and
+ deleting cups printers.
+ * Expand variables in the profile path, logon home and logon script
+ values when using either tdbsam or ldapsam.
+ * Add Domain Admins (Full Control) to the default printer security
+ descriptor if we are a DC.
+ * RedHat and Fedora Packaging fixes for perl dependencies.
+ * Remove unused schema items from OpenLDAP schema file.
+ * Remove duplicate enumeration of "Windows x86" architecture
+ when listing printer drivers via rpcclient.
+ * Fail set_privileges() if 'enable privileges = no' to prevent
+ confused admins.
+ * Fix segfault in cups_queue_get().
+ * Tighten restrictions on changing user passwords when
+ the connected user possesses the SeMachineAccountPrivilege.
+ * Ensure we set NETBIOSNAME.domainname for the long machine name
+ when publishing printers in AD (based on input from Rob Foehl).
+ * Mark 'winbind enable local accounts' as deprecated.
+ * Mark testprns tool as deprecated.
+ * Allow root to grant/revoke privilege assignments.
+ * Correct interaction between user rights and se_access_check() on
+ SAMR objects.
+ * BUG 2286: Fix typo OpenLDAP schema file for sambaConfig object
+ class.
+ * BUG 2262: Add support in configure.in for *freebsd6*.
+ * BUG 2266: Portability fixes for quota code on FreeBSD4.
+ * BUG 2264: Remove shutdown and abortshutdown commands from
+ rpcclient in favor of using the same functions in 'net'.
+ * BUG 2295: Prevent smbd from returning an empty server name
+ in certain lanman api calls.
+ * BUG 2290: Fix autogen.sh script in examples (based on original
+ patch from Lars Mueller).
+ * Fix bug enumerating domain trusts in security = ads.
+ * Fix segv in rpcclient's dsenumdomtrusts.
+ * Fix bug in expansion of %U and %G in included filenames.
+ * BUG 2291: Restrict creation of server trust and domain trust
+ accounts to members of the "Domain Admins" group.
+
+o Nadav Danieli <nadavd@exanet.com>
+ * Short circuit some is_locked() tests if we are oplocked.
+
+
+o Guenther Deschner <gd@samba.org>
+ * Allow 'localhost' as a valid server name in the smbd for the
+ spoolss calls.
+ * Fix KRB5_SETPW-defines, no change in behavior (Thanks to Luke
+ Mewburn for the input).
+ * BUG 2059: Add additional checks needed after logic change to the
+ HAVE_WRFILE_KEYTAB detection test.
+ * BUG 1076: Fix interaction with Exchange 5.5. SP4 and a
+ Samba DC. Allow us to lookup at least our own SID.
+ * More fixes to have proper German in swat (Thanks to Reiner
+ Klaproth and Björn Jacke.
+ * BUG 404, 2076: Allow to set OWNER- and GROUP-entries while
+ setting security descriptors with smbcacls and using with
+ the -S or -M switch.
+ * Include the munged_dial, bad_password_count, logon_count, and
+ logon_hours attributes when running 'net rpc vampire'.
+ * Fix segfault in idmap_rid.
+ * When winbindd is operating in the multi-mapping mode of
+ idmap_rid, allow BUILTIN domain-mapping.
+ * Display infolevel 12 in query_dom_info in rpcclient.
+ * Fix bug in winbindd's lowercasing of usernames.
+ * Allow -v or -l for displaying verbose groupmap-listing
+ as well as "verbose".
+ * Backport Samba4 SAM_DELTA_DOMAIN_INFO for use in 'net rpc
+ vampire'.
+ * Close LDAP-Connection before retrying to open a new connection
+ in the retry-loop.
+ * Marking "min password length" as depreciated.
+ * Implement SAMR query_dom_info-call info-level 8 server- and
+ client-side, based on samba4-idl.
+ * Allow rpcclient to define a port to use when connecting
+ to a remote server.
+ * Allow Account Lockout with Lockout Duration "forever" (until
+ admin unlocks) to be set and displayed in User Manager.
+ * Allow to set acb_mask in rpcclient's enumdomusers.
+ * Add more generic rootDSE inspection function to check
+ for given controls or extensions and remember these on a
+ per server basis.
+ * Improve LDAP search efficiency by passing the acb_mask to
+ pdb_setsampwent().
+ * Fixes for ldapsam_enum_group_memberships().
+ * Add createdomgroup to rpcclient.
+ * Add "net rpc user RENAME"-command.
+ * Display sam_user_info_7 in rpcclient.
+ * Make multi-domain-mode in idmap_rid accessible from outside
+ (can be compiled with -DIDMAP_RID_SUPPORT_TRUSTED_DOMAINS).
+ * When vampiring account policy AP_LOCK_ACCOUNT_DURATION honor
+ "Lockout Duration: Forever".
+ * Fix configure.in tests using KRB5_CONFIG variable and krb5-
+ config utility.
+ * Require assignment of Administrator SID in the passdb
+ backend. Fall back to the default name of 'Administrator' if
+ the lookup fails rather than using the first name in the
+ default 'admin users' list.
+ * Enhance LDAP failure debug messages.
+ * BUG 2291: Call the 'add machine script' for server trust and
+ domain trust accounts as well as workstation accounts.
+
+
+o Levente Farkas <lfarkas@lfarkas.org>
+ * BUG 2299: Better logrotate scripts for RedHat and Fedora
+ packages.
+
+
+o Jay Fenlason <fenlason@redhat.com>
+ * Fix crash in 'net join' due to calling free on
+ static buffers.
+ * Several patches from RedHat's Fedora Core RPMS.
+
+
+o Rob Foehl <rwf@loonybin.net>.
+ * Compiler warnings.
+ * Try modifying printer published attributes before adding it a
+ new entry in AD.
+ * Solaris packaging fixes.
+ * Don't force the cups printer-make-and-model tag as the comment
+ for autoloaded printers.
+ * Implement caching of names from printcap to support a true
+ 'printcap cache time'.
+
+
+o Johann Hanne <jhml@gmx.net>
+ * BUG 2038: Only fail winbindd_getgroups() if all lookups fail.
+
+
+o Jeff Hardy <hardyjm@potsdam.edu>
+ * Example script for 'add print command' when using CUPS.
+
+
+o Deryck Hodge <deryck@samba.org>
+ * Add -P (--password-only-menu) to SWAT for displaying only the
+ password change page to non-root users.
+
+
+o David Hu <david.hu@hp.com>
+ * Copy structure from print_queue_update() message rather than
+ referencing it. Fixes seg fault on HP-UX.
+
+
+o Buck Huppmann <buckh@pobox.com>
+ * BUG 2186: Don't free uninitialized credentials.
+ * BUG 2189: Add the HOST/fqdn servicePrincipalName even when
+ dnsDomainName != realm.
+
+
+o Björn Jacke <bjoern@j3e.de>
+ * BUG 2040: Ensure the locale is reset to C to get ASCII-
+ compatible toupper/lower functions.
+
+
+o William Jojo <jojowil@hvcc.edu>
+ * Fix HPUX sendfile and add configure.in tests and code for
+ sendfile on AIX.
+ * AIX 5.3 compile fixes.
+
+
+o Volker Lendecke <vl@samba.org>
+ * Optimize anonymous session setups by workstations in a
+ Samba domain.
+ * Reimplment the QueryUserAliases() server RPC reply.
+ * Re-add the getpwnam-cache for performance.
+ * Cache the result of a pdb_getsampwnam for later SID lookup
+ queries.
+ * Unify the means of localtaing a user's global groups on a
+ Samba DC.
+ * Fix bug when serving the 'Start Menu' in a roaming user profile..
+ * Map more pre-defined NT security descriptors to AFS acls.
+ * Add timeout to AD search requests.
+ * If a connection to a DC is requested (in winbindd), open
+ connections simultaneously to all DCs found.
+ * Memleak fixes.
+ * Fix logic error in handling of 'printcap name' parameter.
+ * Prevent winbindd from SPAM'ing the log files with 'user root
+ does not exist'.
+ * Backport samr_DomInfo2 IDL specification from Samba 4.
+ * Implement smbstatus -n, don't lookup users and groups.
+ * Implement simple mapping that maps the space to another character
+ defined by afsacl:space.
+ * Add support for 'net idmap delete <idmap-file> <SID>'.
+ * Add new parameter 'afs token lifetime' tells the AFS client
+ when to throw away a token (patch from kllin@it.su.se).
+ * Initial work to allow support for multiple pipe opens on a
+ single cli_state*.
+ * Ensure that we still retrieve the netbios name of any DC
+ listed as a 'password server' to work around cases where the
+ DC was defined using an IP address or fqdn.
+ * Fix memleak in winbindd connection code.
+ * Fix cli_samr_queryuseraliases.
+ * Allow wbinfo --user-sids to expand expand domain local groups.
+ * Allow 'rpcclient -c enumtrust' to enumerate more than 10 trusts.
+ * Fix parsing of other_sids in net_user_info3.
+ * Correct bad failure logic when user was not a member of any
+ domain local groups.
+
+
+o Jason Mader <jason@ncac.gwu.edu>
+ * BUG 2113, 2289: Remove dead code.
+
+
+o Jim McDonough <jmcd@us.ibm.com>
+ * BUG 1952: Try INITSHUTDOWN pipe first, used by newer
+ clients. If it fails, fall back to WINREG.
+ * BUG 1770: Remove READ_ATTRIBUTES from GENERIC_EXECUTE.
+ * BUG 2198: Set password last change time when running 'net rpc
+ vampire'.
+ * Add "refuse machine password change" policy field.
+
+
+o Luke Mewburn <lukem@NetBSD.org>
+ * BUG 2150: shmget() - Use POSIX definitions instead of non-
+ standard SHM_.
+
+
+o Stefan Metzmacher <metze@samba.org>
+ * autogen.sh fixes.
+
+
+o Buchan Milne <bgmilne@mandrake.org>
+ * Mandrake packaging fixes.
+
+
+o Lars Mueller <lmuelle@samba.org>
+ * Fix build of libsmbclient on x86_64.
+ * BUG 2013: Fix testsuite build issues when libsmbclient.so
+ is installed in a non-default location.
+ * BUG 2050: Calculate max_fd for select correctly.
+ * Fix inverted logic heck for HAVE_WRFILE_KEYTAB in autoconf
+ script.
+
+
+o Jason Mader <jason@ncac.gwu.edu>
+ * BUG 2069: Remove unused variables.
+ * BUG 2075: Remove dead code paths.
+ * BUG 2083: Fix compiler warnings caused by bad type casts.
+
+
+o James Peach <jpeach@sgi.com>
+ * Fix rewinddir -> rewind_dir when using VFS macros.
+
+
+o Gavrie Philipson <gavrie@disksites.com>
+ * BUG 1838: Remove stale printers imeeddiately when
+ processing a SIGHUP and during smb.conf reload.
+
+
+o Tim Potter <tpot@samba.org>
+ * BUG 2080: Fix duplicate call to pdb_get_acct_desc().
+ * BUG 2168: Fix cast in SMB_XMALLOC_ARRAY.
+ * Change the license for the winbindd external interface
+ more liberal.
+ * HP-UX compile fixes.
+ * Compile fixes after new setsampwent() API.
+
+
+o Richard Renard <rrenard@idealx.com>
+ * Update Netscape DS 5.2 LDAP schema.
+
+
+o Simo Sorce <idra@samba.org>
+ * Backport pdbedit changes from trunk.
+ * Allows the add/change share command to create the shared
+ directory directory on disk.
+ * Log a warning in testparm if a print command is defined for
+ a print service using 'printing = cups'.
+
+o Jelmer Vernooij <jelmer@samba.org>
+ * Bug fixes for pdb_{xml,pqsql,xml}
+ * Fixes for pdb_mysql.
+
+
+o Andrew Tridgell <tridge@samba.org>
+ * Bring Samba3 into line with the Samba4 password change code.
+
+
+o Shiro Yamada <shiro@miraclelinux.com>
+ * BUG 2190: Force SWAT to display parameters in unix charset and
+ not UTF-8.
+
+
+ --------------------------------------------------
+ ==============================
+ Release Notes for Samba 3.0.10
+ Dec 16, 2004
+ ==============================
+
+Common bugs fixed in 3.0.10 include:
+
+ o Fix for security issues described in CAN-2004-1154.
+
+
+Changes since 3.0.9
+-------------------
+
+commits
+-------
+
+o Jeremy Allison <jra@samba.org>
+ * Added checks surrounding all *alloc() calls to fix
+ CAN-2004-1154.
+ * Fix long standing memory size bug in bitmap_allocate().
+ * Remove bogus error check in deferred open file serving
+ code.
+
+
+o Thomas Bork <tombork@web.de>
+ * Fix autoconf script on platforms using a version of GNU ld
+ that does not include a date stamp in the output of --version.
+
+
+o Luke Mewburn <lukem@NetBSD.org>
+ * Fix the swat install script to deal with the new image
+ destination directory used by the docs.
+
+
+
+ --------------------------------------------------
+
+ =============================
+ Release Notes for Samba 3.0.9
+ Nov 15, 2004
+ =============================
+
+Common bugs fixed in 3.0.9 include:
+
+ o Problem updating roaming user profiles.
+ o Crash in smbd when printing from a Windows 9x client.
+ o Unresolved symbols in libsmbclient which caused
+ applications such as KDE's konqueror to fail when
+ accessing smb:// URLs.
+
+
+Changes since 3.0.8
+-------------------
+
+
+commits
+-------
+
+o Jeremy Allison <jra@samba.org>
+ * Correctly detect errno for no acl/ea support.
+ * BUG 2036: Fix seg fault in 'net ads join'.
+
+
+o Gerald (Jerry) Carter <jerry@samba.org>
+ * Solaris packaging fixes.
+ * Fix seg fault in lanman printing code.
+ * BUG 2017: fix testparm reporting for the passwd program
+ string.
+ * Fix output of smbstatus to match the man page.
+ * BUG 2027: fix conflict with declaration MD5_CTX in system
+ headers.
+ * 2028: Avoid false error messages when copying a long
+ printer name to the device mode.
+
+
+o Guenther Deschner <gd@samba.org>
+ * Allow deldriverex in rpcclient to delete drivers for a
+ specific architecture and a specific version.
+ * Fix a couple of rpcclient spoolss commands (setprinter,
+ setprintername, getdriver) w.r.t to printer-naming scheme.
+ Allow 'localhost' in the server string for certain server-side
+ spoolss functions.
+ * BUG 2015: Do not fail on setting file attributes with
+ acl support enabled.
+
+
+o Michel Gravey <michel.gravey@optogone.com>
+ * Fix build when using gcc 3.0.
+
+
+o Volker Lendecke <vl@samba.org>
+ * Fix tdb open logic when checking our local_pid after
+ the fork().
+
+
+o Jim McDonough <jmcd@us.ibm.com>
+ * BUG 1932: Fix crash in 'net getlocalsid' when run as
+ non-root user.
+
+
+o Luke Mewburn <lukem@NetBSD.org>
+ BUG 1661: Fix KRB5_SETPW-defines
+
+
+o Buchan Milne <bgmilne@mandrake.org>
+ * BUG 2023: Mandrake packaging fixes for building 3.0.9.
+
+
+o Lars Mueller <lmuelle@samba.org>
+ * BUG 2013: Fix unresolved symbols in libsmbclient.so.
+
+
+o Martin Zielinski <mz@seh.de>
+ * Add DeletePrinterDriverEx() functionality to rpcclient.
+
+
+ --------------------------------------------------
+
+ =============================
+ Release Notes for Samba 3.0.8
+ Nov 7, 2004
+ =============================
+
+Common bugs fixed in 3.0.8 include:
+
+ o Compile fixes for HP-UX
+ o Fixes for the printer publishing code used when joined to
+ an AD domain.
+ o Incompatibilities with file system quotas.
+ o Several bugs in the spoolss printing code and print system
+ backends.
+ o Inconsistencies in the username map functionality when
+ configured on domain member servers.
+ o Various compile warnings and errors on various platforms.
+ o Fixes for kerberos interoperability with Windows 200x
+ domains when using DES keys.
+ o Fix for CAN-2004-0930 -- smbd remote DoS vulnerability.
+ o Fix for CAN-2004-0882 -- possible buffer overrun in smbd.
+
+
+New features included in the 3.0.8 release are:
+
+ o New migration functionality added the the net tool
+ for files/directories, printers, and shares.
+ o New experimental idmap backend for assigning uids/gids
+ directly based on the user/group RID when acting as a
+ member of single domain without any trusts.
+ o Additional printer migration support for XP/2003 platforms.
+
+
+===========================
+Change in Winbindd Behavior
+===========================
+
+All usernames returned by winbindd are now converted to lower
+case for better consistency. This means any winbind installation
+relying on the winbind username will need to rename existing
+directories and/or files based on the username (%u and %U) to lower
+case (e.g. mv $name `echo $name | tr '[A-Z]' '[a-z]'`). This may
+include mail spool files, home directories, valid user lines in
+smb.conf, etc....
+
+
+======================
+Change in Username Map
+======================
+
+Previous Samba releases would only support reading the fully qualified
+username (e.g. DOMAIN\user) from the username map when performing a
+kerberos login from a client. However, when looking up a map
+entry for a user authenticated by NTLM[SSP], only the login name would be
+used for matches. This resulted in inconsistent behavior sometimes
+even on the same server.
+
+Samba 3.0.8 obeys the following rules when applying the username
+map functionality:
+
+ * When performing local authentication, the username map is
+ applied to the login name before attempting to authenticate
+ the connection.
+ * When relying upon a external domain controller for validating
+ authentication requests, smbd will apply the username map
+ to the fully qualified username (i.e. DOMAIN\user) only
+ after the user has been successfully authenticated.
+
+
+######################################################################
+Changes
+#######
+
+Changes since 3.0.7
+-------------------
+
+smb.conf changes
+----------------
+ Parameter Name Action
+ -------------- ------
+ force printername New
+ sendfile disabled by default
+
+
+commits
+-------
+
+o Jeremy Allison <jra@samba.org>
+ * Ensure extended security bit is on only if we negotiated
+ extended security.
+ * Simplify statcache to use an in-memory tdb.
+ * If you're selecting a hash algorithm for tdb, you need
+ to do it at open time.
+ * Removed old dir caching code - not being used now we
+ have the statcache anyway.
+ * Simplify the mangle hash code to use an in-memory tdb.
+ * Merge iconv changes from Samba 4 branch.
+ * Fix parsing of names ending in dot and a few other error
+ returns.
+ * BUG 1667: Smbpasswd file could be left locked on some
+ error exits.
+ * Fixes for smbclient tar functionality.
+ * BUG 1743: Fix logic bug the deferred open code.
+ * Don't try to set security descriptors on shares where
+ this has been turned off.
+ * Return correct error codes on old SEARCH call.
+ * Ensure we set errno = E2BIG when we overflow in the
+ fast-path character conversion code.
+ * Fix the roundup problem (returning 1mb roundup) for
+ non-Windows clients.
+ * Added 'stat' command to smbclient to exercise the
+ UNIX_FILE_BASIC info level.
+ * Fix bug where we could incorrectly set sparse attribute.
+ * Fix incorrect locks/unlocks in tdb_lockkeys()/tdb_unlockkeys()
+ (reported by Taj Khattra <taj.khattra@gmail.com>).
+ * Remove locked keys tdb code.
+ * BUG 1886: Prevent delete on close being set for readonly files
+ (and return the correct error code).
+ * Ensure we pass most of the new lock tests except for the cancel
+ lock which is yet to be added (merged from Samba 4 branch).
+ * BUG 1947: Fix incorrect use of getpwnam() etc. interface.
+ * BUG 1956: Ensure errno is saved and restored consistently on a
+ normal_close.
+ * BUG 1651: Adapted patch from Nalin Dahyabhai for ensuring
+ that all of the appropriate service principal names are set
+ upon joining an AD domain.
+ * Fix the correct use of resume name in the trans2 code.
+ * BUG 1717: Adapted patch from Nalin Dahyabhai to detect the
+ correct salt used when generated the DES key after joining an
+ AD domain.
+ * Enhanced krb5 detection routines in the autoconf scripts.
+
+
+o Andrew Bartlett <abartlet@samba.org>
+ * Avoid changing the machine account password in the passdb
+ backend, when it has 'already been changed'. This occurs
+ in situations where the secure channel between the workstation
+ and the DC breaks down, such as occurred in the MS04-11
+ security patch.
+ * Fix utility name in error message in ntlm_auth.
+ * Fix NTLMv2 for use with pam_winbind.
+ * Remove conversion to and from UTF8 on the winbind pipe.
+ * Allow 'require_membership_of' and 'require-membership-of'.
+ * Fix the error code for 'you didn't specify a domain' in
+ ntlm_auth.
+ * Use sys_getgroups() rather than scanning all groups
+ when generating SAMR replies.
+
+
+o Igor Belyi <sambauser@katehok.ac93.org>
+ * Ensure pdb user is deleted first before deleting UNIX
+ user (LDAP backend needs this ordering).
+
+
+o Cornelio Bondad Jr <Corny.Bondad@hp.com>
+ * Fix core dump in 'net rpc vampire'.
+
+
+o Vince Brimhall <vbrimhall@novell.com>
+ * Make ldapsam_compat robust against NULL attributes.
+
+
+o Gerald Carter <jerry@samba.org>
+ * Don't limit the number of groups returned by winbindd_getgroups()
+ by NGROUPS_MAX.
+ * BUG 1519: Match Windows 2000 behavior when opening a
+ printer using a servername in the form of an IP address or
+ DNS name.
+ * BUG 1907: remove extra slashes from the printer name in
+ getprinterdriverdir_1().
+ * Fix standard_sub_snum() to use the current user's gid.
+ * Fix background queue update bug (based on Volker's initial work
+ in 3.1.0).
+ * Add 'force printername' service parameter for people that want
+ to enforce printername == sharename for spoolss printing.
+ * Ensure consistent usage of the username map. Use the fully
+ qualified DOMAIN\user format for 'security = domain|ads' and
+ apply after authentication has succeeded.
+ * Cosmetic fix for getent output -- lowercase the username only
+ and not the complete domain\username string.
+ * Packaging fixes for Solaris, Redhat, & Fedora.
+
+
+o Sean Chandler <sean.chandler@verizon.net>
+ * Fix memlieak in cliconnect.c.
+
+
+o Darren Chew <darrenc@vicscouts.asn.au>
+ * Solaris packaging fixes.
+
+
+o Nalin Dahyabhai <nalin@redhat.com>
+ * SMB signing fix for 56-bit DES session keys.
+
+
+o Guenther Deschner <gd@samba.org>
+ * add IA64 to the architecture table of printer-drivers.
+ * Add file/share/printer migration functionality to
+ the net command.
+ * Show correct help for net groupmap commands.
+ * Fix deadlock loop in winbind's required_membership_sid
+ verification.
+ * Bring the same level of "required_membership"-functionality
+ that ntlm_auth uses, to pam_winbindd as well.
+ * Prevent "net lookup kdc" from seg-faulting when
+ using our own implementation of krb5_lookup_kdc with
+ heimdal.
+ * Adding getprinter level 7 to rpcclient.
+ * Support migrating printers|shares|files from Server A
+ to Server B while running the net-command on client C.
+ * Fixed krb5_krbhost_get_addrinfo()-parameters and make
+ failure of this call non-critical (Thanks to Love @ Heimdal
+ for the explanation and patch).
+ * Fix typos in net's usage-output.
+ * Fix the paranoia-check to ensure the ldap-attribute and the
+ smb.conf-parameter for samba's "algorithmic rid base" in ldapsam
+ are identical.
+ * Fix several bugs in the _samr_query_useraliases() rpc reply.
+ * Check correct string length when verifying password-policies
+ and using extended characters (Thanks to Uwe Morgenroth from CC
+ Compunet and Volker).
+ * Make 'password history'-behavior in ldapsam more consistent.
+ * Adding "Windows x64" as architecture string and driverdir "x64"
+ for the 64bit AMD platform.
+ * BUG 1343: Readd WKGUID-binding to match the correct default-
+ locations of new User-, Group- and Machine-Accounts in Active
+ Directory (this got lost during the last trunk-merge).
+ * Fix printer-migration w.r.t. to new naming-convention for
+ policy-handles.
+ * Allow to migrate win2k3/xp-drivers as well.
+ * Add client-side support of triggering ads printer publishing
+ over msrpc setprinter calls inside the net-tool.
+ * Add the idmap_rid module (written in conjunction with
+ Sumit Bose <sbose@suse.de>).
+ * BUG 1661: Fix build with recent heimdal releases.
+ * Prevent idmap_rid from making unnecessary calls to domain
+ controllers for trusted domains.
+
+
+o Arthur van Dongen <avdongen@xs4all.nl>
+ * Fix typos in pam_winbind log messages and SuSE
+ packaging files.
+
+
+o Rob Foehl <rwf@loonybin.net>
+ * Typo fixes for log messages in printer publishing code.
+ * Fix memory leak in printer publishing code.
+ * Ensure print_backend_init() only gets called once.
+ * Have smbd check the published status of all printers
+ at startup.
+ * Cleanup up the XXX_a_printer() API for consistency.
+ * Refactored the printer publishing code and include better
+ error handling.
+
+
+o Steve French <sfrench@us.ibm.com>
+ * Fix IP address override in mount.cifs mount helper and clean
+ up warning messages from the sparse tool and expand syntax help.
+ * Strip guest mount option off before sending to kernel mount
+ routine to avoid logging spurious message.
+
+
+o Satoh Fumiyasu <fumiya@samba.gr.jp>
+ * BUG 1732: Limit share names returned by RAP based on windows
+ character width, not unix character width.
+ * BUG 1498: Ensure that acl entries are stored in the correct
+ order.
+
+
+o Brett Funderburg <brett@deepfile.com>
+ * Pass create options parameter to nt_create_andx() function
+ from the python bindings.
+ * BUG 1864: Add sd->type field to security descriptor Python
+ representation.
+ * Return an error if a Netapp filer returns NT_STATUS_ACCESS_DENIED
+ when trying to return the security descriptor for a file.
+ * BUG 1884: Fixes for the Python bindings to use the value
+ of the desired_access filed passed into the lsa_open_policy()
+ routines.
+
+
+o Michael Gravey <michel.gravey@optogone.com>
+ * BUG 1776: Fix warnings when building modules caused by
+ certain versions of GNU ld not using the the default
+ --allow-shlib-undefined flag.
+
+
+o Chris Hertel <crh@samba.org>
+ * Fix logic bug in splay tree data structure when finding
+ a leaf node.
+ * Fix bug where an invalid MAC address would be printed by
+ a node status lookup from nmblookup.
+
+
+o Uli Iske <iske@elkb.de>
+ * Update the DNS/eDirectory LDAP schema file.
+
+
+o Björn Jacke <bjacke@sernet.de>
+ * BUG 1766: Unify charset-handling in Content-Type:-headers to
+ UTF-8. Reformat msgstr in msg-files to UTF-8.
+ * Do not use display charset for swat output.
+ * Convert the share names correctly from unix encoding to web
+ encoding and vice versa.
+ * Convert files from status page from unix charset to UTF-8.
+
+
+o Guenter Kukkukk <guenter.kukkukk@kukkukk.com>
+ * BUG 1590: Fix for talking to OS/2 clients (max_mux ignored).
+
+
+o Tom Lackemann <cessnatomny@yahoo.com>
+ * BUG 1954: Fix memory leak in posix acl code.
+
+
+o Volker Lendecke <vl@samba.org>
+ * Robustnss fix for winbindd when sending multiple requests
+ at a high rate for a slow operation.
+ * Solve the problem of user sids ending up with gid's
+ and vice versa.
+ * Use sys_fork instead of fork for the dual daemon so that
+ we get the correct debug pid in the logfiles.
+ * Based on patch from jmcd, implement special lists for the LDAP
+ user attributes to delete.
+ * Fix creation of aliases via usrmgr. Winbind was too strict
+ checking the type of sids.
+ * Lowercase all usernames returned by winbind.
+ * BUG 1545, 1823: Only issue the ldap extended password change
+ operation if the ldap server supports it. Also ignore object
+ class violation errors from the extended operation.
+ * Optimization for 'idmap backend = ldap': When asking sid2id
+ for the wrong type, don't ask ldap when we have the opposite mapping
+ in the local tdb.
+ * Fix ldapsam_compat homeDrive.
+ * Add usersidlist and allowedusers subcommands to the net tool
+ in order to support scanning a file server's share and list
+ all users who have permission to connect there.
+ * Allow for multiple DC's to be named as #1c names in lmhosts.
+ * Memory leak fixes.
+ * Fix checks for the local pid of an smbd process after
+ reopening tdbs.
+
+
+o Herb Lewis <herb@samba.org>
+ * Added tdbtool to be built by default.
+
+
+o Love <lha@stacken.kth.se>
+ * BUG 1955: Inconsistent error return.
+
+
+o Sorin Manolache <sorinm@gmail.com>
+ * Memory leak fix.
+
+
+o Jim McDonough <jmcd@us.ibm.com>
+ * Allow 'net ads lookup' to rely on command line arguments
+ if contacting an ADS server fails; utilize cldap for lookups.
+ * Fixup formatting errors in TDB_LOG calls; add printf attribute
+ support to tdb log functions.
+
+
+o Bill McGonigle <bill+samba@bfccomputing.com>
+ * BUG 1926: Type in debug message.
+
+
+o Sean McGrath
+ * BUG 1822: Add -D_REENTRANT to CPPFLAGS and -lthread to LDFLAGS
+ for libsmbclient.
+
+
+o Luke Mewburn <lukem@NetBSD.org>
+ * BUG 1782: Prevent testparm from displaying parameter synonyms.
+
+
+o Stefan Metzmacher <metze@samba.org>
+ * Fix crash in smbcquotas and smbcacls caused by setup_logging().
+ * Fix client quota support.
+ * Fix opening of system quota file.
+
+
+o Lars Mueller <lmuelle@samba.org>
+ * Small fixes for autogen.sh to deal with version detection
+ of autoconf and autoheader; fixes for examples using
+ libtool to adhere to stricter syntax of newer version.
+
+
+o Henrik Nordstrom <hno@squid-cache.org>
+ * Allow winbindd to return the correct number of groups
+ when the groups array must be enlarged.
+
+
+o Narayana Pattipati <narayana.pattipati@wipro.com>
+ * Solaris autoconf detection fixes.
+
+
+o Tim Potter <tpot@samba.org>
+ * BUG 1360: (correct fix) Use -Wl when passing flags to
+ the linker.
+ * HP-UX compile fixes (from JBravo on #samba-technical).
+ * BUG 1731: More HP-UX compiles fixes.
+ * BUG 1778: Include yp_prot.h before ypclnt.h as AIX 5.2
+ spits the dummy otherwise.
+ * Fix bug in Python printerdata wrapper.
+ * BUG 1762: nss_winbind fixes on AIX 5.x (patch from
+ <bugzilla-samba@thewrittenword.com>).
+ * Fix parameter confusion in priming of name-to-sid cache
+ (Found by Qiao Yang).
+ * BUG 1888: Remove '..' from all pre-processor commands.
+ * BUG 1903: Change some #if DEBUG_PASSWORD's to #ifdef
+ DEBUG_PASSWORD.
+
+
+o Matt Selsky <selsky@columbia.edu>
+ * BUG 350: use autoconf 2.57 feature for checking header file
+ preprocessing (fixes configure warnings on Solaris).
+
+
+o Richard Renard <rrenard@idealx.com>
+ * Fix usermgr.exe and trust relationships.
+
+
+o Paul Szabo <psz@maths.usyd.edu.au>
+ * Fix to make find_workgroup use the same
+ truncation as create_workgroup.
+
+
+o Richard Sharpe <rsharpe@samba.org>
+ * Ensure cli_write() can support writes >= 65536 bytes.
+
+
+o Simo Sorce <idra@samba.org>
+ * Added check password script code in examples/auth/crackcheck/
+ * Fix memory corruption bug caused in freeing static memory.
+
+
+o Andrew Tridgell <tridge@samba.org>
+ * Remove lp_use_mmap() from map_file() since the latter
+ is for read only and does not require coherence.
+ * Ensure that the uuid pack/unpack routines do not go past
+ the end of the structure.
+ * Converted Samba 3 tree to use the new utf-16 aware iconv
+ code.
+ * Changed iconv to recognise UCS-2LE and UTF-16LE as synonyms.
+ * Ensure configure only uses '=' instead of the bashism '=='.
+ * Reduces the number of tdb locking calls made on file IO.
+
+
+o Jelmer Vernooij <jelmer@samba.org>
+ * Convert internal data to UTF-8 before calling libxml2.
+ * Complain if 'password chat' doesn't contain the %u variable
+ (based on a patch by Ronan Waide).
+
+
+o Josef Zlomek
+ * BUG 1541: Fix recursive ls in smbclient.
+
+
+o Igor Zhbanov <bsg@uniyar.ac.ru>
+ * BUG 1797: Prevent winbind and nmbd from ignoring the "-l"
+ option.
+
+ --------------------------------------------------
+
+ =============================
+ Release Notes for Samba 3.0.7
+ Sept 13, 2004
+ =============================
+
+Common bugs fixed in 3.0.7 include:
+
+ o Fixes for two Denial of Service vulnerabilities
+ (CVE ID# CAN-2004-0807 & CAN-2004-0808).
+ o Winbind failure to return user entries under certain
+ conditions.
+ o Syntax errors in the OpenLDAP schema file (samba.schema).
+ o Printing errors caused by not setting default values
+ for the various printing commands.
+
+
+Changes since 3.0.6
+-------------------
+
+smb.conf changes
+----------------
+
+ Parameter Name Action
+ -------------- ------
+ winbind enable local accounts disabled by default
+
+
+commits
+-------
+o Jeremy Allison <jra@samba.org>
+ * Fix parsing of names ending in dot and a few other error
+ returns.
+ * BUG 1674: Move the symlinks checks into reduce_name().
+ * Fix memleak when checking the valid names smb.conf option.
+ * Fix memleak on error return path in the file open code.
+ * More paranoia checks in the hash2 mangling code.
+ * Fix syntax error in configure.in.
+ * Match Win2k3's behavior for pathname parsing error returns.
+ * Make nmbd more robust against bad netbios packets
+ (CAN-2004-0808).
+ * Add more checks for invalid ASN.1 packets for SPNEGO packets
+ (CAN-2004-0807).
+
+
+o Andrew Bartlett <abartlet@samba.org>
+ * Janitor work in loadparm.c -- remove unused parameters.
+
+
+o Gerald Carter <jerry@samba.org>
+ * BUG 1464: Ensure that printing commands are initialized even
+ if the 'printing' parameter is not explicitly set.
+ * Resolve name conflict on DEC OSF-5.1 (inspired by patch from
+ Adharsh Praveen <rprav@india.hp.com>)
+ * Work around parsing error in the print change notify code.
+ * remove duplicate declaration of getprintprocdir from
+ rpcclient.
+ * Only use sAMAccountName and not userPrincipalName when looking
+ up a username in AD since the breaks winbindd (lookup_name()
+ only works with the sAMAccountName).
+ * Fix bug with winbindd_getpwnam() caused by Microsoft DC's not
+ filling in the username in the user_info3.
+ * Fix logic bug in the check for creating a user's home directory
+ in register_vuid(); caused home directory to be mismatched to
+ the first share in smb.conf under certain conditions.
+ * BUG 1656: rename auto.a to auto.smb.
+ * Ensure that we assign our pid to print jobs (and not our
+ parent's pid); ensures that spooling jobs from dead smbds
+ are removed from the tdb.
+ * Disable 'winbind enable local accounts' by default.
+ * Adding some initial checks for DragonFly (same as
+ FreeBSD 4.1).
+
+
+o Guenther Deschner <gd@samba.org>
+ * Use SMB_ASSERT() to track down NULL printer names in
+ the tdb open code.
+ * Revert fix for BUG 1474 to avoid unnecessary packaging
+ dependencies.
+
+
+o Olaf Flebbe <o.flebbe@science-computing.de>.
+ * BUG 1627: fix for NIS compiles on HPUX 11.00, AIX 4.3
+ and 5.1.
+ * BUG 1626: More compile fixes.
+
+
+o Rob Foehl <rwf@loonybin.net>
+ * Don't clear the PRINT_ATTRIBUTE_PUBLISHED was getting reset
+ by attempts to sanitize the defined attributes.
+
+
+o SATOH Fumiyasu <fumiya@miraclelinux.com>
+ * BUG 1546: Preserve errno in MB strupper_m/strlower_m.
+
+
+o Helmut Heinreichsberger <helmut.heinreichsberger@chello.at>.
+ * BUG 1657: Remove used initialized variable,
+ * BUG 1658: Add a little bit of const.
+
+
+o Volker Lendecke <vl@samba.org>
+ * If there's garbage in the pidfile, we should not panic
+ but assume that no one else is around. We can't find the
+ other guy anyway.
+
+
+o Jim McDonough <jmcd@us.ibm.com>
+ * Fixup format string in the tdb error messages.
+
+
+o Jonas Olsson <lexicon@lysator.liu.se>
+ * BUG 1416: Don't reuncture a users list to NGROUPS_MAX when
+ reporting the list in usrmgr.exe.
+
+
+o Tim Potter <tpot@samba.org>
+ * Fix out-of-tree builds (problem with the script to generate
+ the svn version number).
+ * BUG 1360: Need to use -Wl when passing flags to the linker.
+ * BUG 1741: Define a struct nss_groupsbymem for HPUX 11 which
+ doesn't have one of its own.
+
+o Simo Sorce <idra@samba.org>
+ * Fixup compile issues on AIX caused by broken strlen() and
+ strdup().
+ * Update debian packaging files.
+
+
+o Dimitri van der Spek <dwspek@aboveit.nl>
+ * Use the correct counter when copying group rids from the
+ user_info3 struct in pam_winbind.
+
+
+o Qiao Yang <qyang@stbernard.com>
+ * BUG 1622: Only cache the user
+
+
+ --------------------------------------------------
+
+ =============================
+ Release Notes for Samba 3.0.6
+ Aug 19, 2004
+ =============================
+
+Common bugs fixed in 3.0.6 include:
+
+ o Schannel failure in winbindd.
+ o Numerous memory leaks.
+ o Incompatibilities between the 'write list' and 'force user'
+ smb.conf options.
+ o Premature optimization of the open_directory() internal
+ function that broke tools such as the ArcServe backup
+ agent, Macromedia HomeSite, and Robocopy.
+ o Corrupt workgroup names in nmbd's browse.dat.
+ o Sharing violation errors commonly seen when opening
+ when serving Microsoft Office documents from a Samba
+ file share.
+ o Browsing problems caused by an apostrophe (') in the
+ computer's description field.
+ o Problems creating special file types from UNIX CIFS
+ clients and enabling 'unix extensions'.
+ o Fix stalls in smbd caused by inaccessible LDAP servers.
+ o Remove various memory leaks.
+ o Fix issues in the password lockout feature.
+
+New features introduced in this release include:
+
+ O Support symlinks created by CIFS clients which
+ can be followed on the server.
+ o Using a cups server other than localhost.
+ o Maintaining the service principal entry in the system
+ keytab for integration with other kerberized services.
+ Please refer to the 'use kerberos keytab' entry in
+ smb.conf(5). When using the heimdal kerberos libraries,
+ you must also specify the following in /etc/krb5.conf:
+ [libdefaults]
+ default_keytab_name = FILE:/etc/krb5.keytab
+ o Support for maintaining individual printer names
+ stored separately from the printer's sharename.
+ o Support for maintaining user password history.
+ o Support for honoring the logon times for user in a
+ Samba domain.
+
+
+============================================
+unix extensions = yes (default) and symlinks
+============================================
+
+Beginning with Samba 3.0.6pre1 (formerly known as 3.0.5pre1),
+clients supporting the UNIX extensions to the CIFS protocol
+can create symlinks to absolute paths which will be **followed**
+by the server. This functionality has been requested in order
+to correctly support certain applications when the user's home
+directory is mounted using some type of CIFS client (e.g. the
+cifsvfs in the Linux 2.6 kernel).
+
+If this behavior is not acceptable for your production environment
+you can set 'wide links = no' in the specific share declaration in
+the server's smb.conf. Be aware that disabling wide link support
+out of a share in Samba may impact the server's performance due
+to the fact that smbd will now have to check each path additional
+times before traversing it.
+
+
+========================
+Password History Support
+========================
+
+The new password history feature allows smbd to check the new
+password in password change requests against a list of the user's
+previous passwords. The number of previous passwords to save can
+be set using pdbedit (4 in this example):
+
+ root# pdbedit -P "password history" -C 4
+
+When using the ldapsam passdb backend, it is vital to secure the
+following attributes from access by non-administrative users:
+
+ * sambaNTPassword
+ * sambaLMPassword
+ * sambaPasswordHistory
+
+You should refer to your directory server's documentation on how
+to implement this restriction.
+
+
+Changes since 3.0.5
+-------------------
+
+smb.conf changes
+----------------
+
+ Parameter Name Action
+ -------------- ------
+ cups server New
+ defer sharing violations New
+ force unknown acl user New
+ ldap timeout New
+ printcap cache time New
+ use kerberos keytab New
+
+commits
+-------
+o Jeremy Allison <jra@samba.org>
+ * Correct path parsing bug that broke DeletePrinterDriverEx().
+ * Fix bugs in check_path_syntax() caught by asserts.
+ * Internal change - rearrange internal global case setting
+ variables to a per connection basis.
+ * BUG 1345: Fix premature optimization in unix_convert().
+ * Allow clients to truncate a locked file.
+ * BUG 1319: Always check to see if a user as write access
+ to a share, even when 'force user' is set.
+ * Fix specific case of open that doesn't cause oplock break,
+ or share mode check.
+ * Correct sid type is WKN_GROUP, not alias. Added some
+ more known types (inspired by patch from Jianliang Lu).
+ * Allow creation of absolute symlink paths via CIFS clients.
+ * Fix charset bug in when invoking send_mailslot().
+ * When using widelinks = no, use realpath to canonicalize
+ the connection path on connection create for the user.
+ * Enhance stat open code.
+ * Fix unix extensions mknod code path.
+ * Allow unix domain socket creation via unix extensions.
+ * Auto disable the 'store dos attribute' parameter if the
+ underlying filesystem doesn't support EAs.
+ * Implement deferred open code to fix a bug with Excel files
+ on Samba shares.
+ * BUG 1427: Catch bad path errors at the right point. Ensure
+ all our pathname parsing is consistent.
+ * Fix SMB signing error introduced by the new deferred open
+ code.
+ * Change default setting for case sensitivity to "auto". (see
+ commit message -- r1154 -- for details).
+ * Add new remote client arch -- CIFSFS.
+ * Allow smbd to maintain the service principal entry in the
+ system keytab file (based on patch Dan Perry <dperry@pppl.gov>,
+ Guenther Deschner, et. al.).
+ * Fix longstanding memleak bug with logfile name.
+ * Fix incorrect type in printer publishing (struct uuid,
+ not UUID_FLAT).
+ * Heimdal compile fixes after introduction of the new ketyab
+ feature.
+ * Ensure we check attributes correctly on rename request.
+ * Ensure we defer a sharing violation on rename correctly.
+ * BUG 607: Ensure we remove DNS and DNSFAIL records immediately
+ on timeout.
+ * Fix bogus error message when using "mangling method = hash"
+ rather than hash2.
+ * Turn on sendfile by default for non-Win9x clients.
+ * Handle non-io opens that cause oplock breaks correctly.
+ * Ensure ldap replication sleep time is not more than 5 seconds.
+ * Add support for storing a user's password history.
+ LDAP portion of the code was based on a patch from
+ Jianliang Lu <j.lu@tiesse.com>.
+ * Correct memory leaks found in the password change code.
+ * Fix support for the mknod command with the Linux CIFS client.
+ * Remove support for passing the new password to smbpasswd
+ on the command line without using the -s option.
+ * Ensure home directory service number is correctly reused
+ (inspired by patches from Michael Collin Nielsen
+ <michael@hum.aau.dk>).
+ * Fix to stop printing accounts from resetting the bas
+ password and account lockout flags.
+ * If a account was locked out by an admin (and has a bad
+ password count of zero) leave it locked out until an admin
+ unlocks it (but log a message).
+ * Ensure we return the same ACL revision on the wire that
+ W2K3 does.
+ * BUG 1578: Hardcode replacement for invalid characters as '_'
+ (based on fix from Alexander E. Patrakov <patrakov@ums.usu.ru>).
+ * Fix hashed password history for LDAP backends.
+ * Enforce logon hours restrictions if confiogured (based on code
+ from Richard Renard <rrenard@idealx.com>).
+ * BUG 1606: Force smbd to disable sendfile with DOS clients
+ and ensure that the chained header is filled in for ...&X
+ commands.
+ * BUG 1602: Fix access to shares when all symlink support
+ has been disabled.
+
+
+
+o Tom Alsberg <alsbergt@cs.huji.ac.il>
+ * Allow pdbedit to export a single user from a passdb backend.
+
+
+o Andrew Bartlett <abartlet@samba.org>
+ * Fix parsing bug in GetDomPwInfo().
+ * Fix segfault in 'ntlm_auth --diagnostics'.
+ * Re-enable code to allow sid_to_gid() to perform a group
+ mapping lookup before checking with winbindd.
+ * Fix memory leak in the trans2 signing code.
+ * Allow more flexible GSS-SPENGO client and server operation
+ in ntlm_auth.
+ * Improve smbd's internal random number generation.
+ * Fix a few outstanding long password changes in smbd.
+ * Fix LANMAN2 session setup code.
+
+
+o Eric Boehm <boehm@nortelnetworks.com>
+ BUG 703: Final touches on netgroup case lookups.
+
+
+o Jerome Borsboom <j.borsboom@erasmusmc.nl>
+ * Ensure error status codes don't get overwritten in
+ lsa_lookup_sids() server code.
+ * Correct bug that caused smbd to overwrite certain error
+ codes when returning up the call stack.
+ * Ensure the correct sid type returned for builtin sids.
+
+
+o Gerald Carter <jerry@samba.org>
+ * Fix a few bugs in the Fedora Packaging files.
+ * Fix for setting the called name to by our IP if the
+ called name was *SMBSERVER and *SMBSERV. Fixes issue
+ with connecting to printers via \\ip.ad.dr.ess\printer
+ UNC path.
+ * BUG 1315: fix for schannel client connections to servers
+ when we haven't specifically negotiated AUTH_PIPE_SEAL.
+ * Allow PrinterDriverData valuenames with embedded backslashes
+ (Fixes bug with one of the Konica Fiery drivers).
+ * Fixed string length miscalculation in netbios names that
+ resulted in corrupt workgroup names in browse.dat.
+ * When running smbd as a daemon, launch child smbd to update
+ the lpq cache listing in the background.
+ * Allow printers "Printers..." folder to be renamed to a string
+ other than the share name.
+ * Allow winbindd to use domain trust account passwords when
+ running on a Samba DC to establish an schannel to remote
+ domains.
+ * Fix bad merge and ensure that we always use tdb_open_log()
+ instead of tdb_open_ex() (the former call enforce the 'use
+ mmap' parameter).
+ * BUG 1221: revert old change that used single and double
+ quotes as delimeters in next_token(), and change
+ print_parameter() to print out parm values surrounded by
+ double quotes (instead of single quotes).
+ * Prevent home directories added during the SMBsesssetup&X from
+ being removed as unused services.
+ * Invalidate the print object cache for open printer handles when
+ smbd receives a message that an attribute on a given printer
+ has been changed.
+ * Cause the configure script to exit if --enable-cups[=yes] is
+ defined and the system does not have the cups devel files
+ installed.
+ * BUG 1297: Prevent map_username() from being called twice
+ during logon.
+ * Ensure that we use the userPrincipalName AD attribute
+ value for LDAP SASL binds.
+ * Ensure we remove the tdb entry when deleting a job that
+ is being spooled.
+ * BUG 1520: Work around bug in Windows XP SP2 RC2 where the
+ client sends a FindNextPrintChangeNotify() request without
+ previously sending a FindFirstPrintChangeNotify(). Return
+ the same error code as Windows 2000 SP4.
+ * BUG 1516: Manually declare ldap_open_with_timeout() to
+ workaround compiler errors on IRIX (or other systems without
+ LDAP headers).
+ * Merge security fixes for CAN-2004-0600, CAN-2004-0686 from
+ 3.0.5.
+ * Corrected syntax error in the OID for sambaUnixIdPool,
+ sambaSidEntry, & sambaIdmapEntry object classes.
+ * Tighten the cache consistency with the ntprinters.tdb entry
+ an the in memory cache associated with open printer handles.
+ * Make sure that register_messages_flags() doesn't overwrite
+ the originally registered flags.
+
+
+o Fabien Chevalier <fabien.chevalier@supelec.fr>
+ * Debian BUG 252591: Ensure that the return value from the
+ number of available interfaces is initialized in case no
+ interfaces are actually available.
+
+
+o Guenther Deschner <gd@sernet.de>
+ * Implement 'rpcclient setprintername'.
+ * Add local groups to the user's NT_TOKEN since they are
+ actually supported now.
+ * Heimdal compile fixes after introduction of the new keytab
+ feature.
+ * Correctly honor the info level parameter in 'rpcclient
+ enumprinters'.
+ * Reintroduce 'force unknown acl user' parameter. When getting a
+ security descriptor for a file, if the owner sid is not known,
+ the owner uid is set to the current uid. Same for group sid.
+ * Ensure that REG_SZ values in the SetPrinterData actually
+ get written in UNICODE strings rather than ASCII.
+ * Ensure that the last kerberos error return is not invalid.
+ * Display share ACL entries from rpcclient.
+ * Correct infinite loop in pam_winbind's verification of
+ group membership in the 'other sids' field in the user_info3
+ struct.
+
+
+o Fabian Franz <FabianFranz@gmx.de>
+ * Support specifying a port in the device URL passed to smbspool.
+
+
+o Steve French <sfrench@us.ibm.com>
+ * Handle -S and user mount parms in mount.cifs.
+ * Fix user unmount of shares mount with suid mount.cifs.
+ * prevent infinite recusion in reopen_logs() when expanding
+ the smb.conf variable %I.
+
+
+o Bjoern Jacke <bj@sernet.de>
+ * Install libsmbclient into $(LIBDIR), not into hard coded
+ ${prefix}/lib. This helps amd64 systems with /lib and /lib64
+ and an explicit configure --libdir setting.
+
+
+o <kawasa_r@itg.hitachi.co.jp>
+ * Correct more memory leaks and initialization bugs.
+ * Fix bug that prevented core dumps from being generated
+ even if you tried.
+ * Connect to the winbind pipe in non-blocking mode to
+ prevent processes from hanging.
+ * Memory leak fixes.
+
+
+o Stephan Kulow <coolo@suse.de>
+ * Fix crash bug in libsmbclient.
+
+
+o Volker Lendecke <vl@samba.org>
+ * Added vfs_full_audit module.
+ * Add vfs_afsacl.c which can display & set AFS acls via
+ the NT security editor.
+ * Fix crash bug caused by trying to Base64 encode a NULL string.
+ * Fix DOS error code bug in reply_chkpath().
+ * Correct misunderstanding of the max_size field in
+ cli_samr_enum_als_groups; it is more like an account_control
+ field with individual bits what to retrieve.
+ * Implement 'net rpc group rename' -- rename domain groups.
+ * Implement the 'cups server' option. This makes it possible
+ to have virtual smbd's connect to different cups daemons.
+ * Paranoia fixes when adding local aliases to a user's NT_TOKEN.
+ * Fix sid_to_gid() calls in winbindd to prevent loops.
+ * Ensure that local_sid_to_gid() sets the type of the group on
+ return.
+ * Make sure that the clients are given back the IP address to
+ which they connected in the case of a multi-homed host. Only
+ affects strings the spoolss printing replies.
+ * Fix the bad password lockout. This has not worked as pdb_ldap.c
+ did not ask for the modifyTimestamp attribute, so it could
+ not find it. Try not to regress by not putting that attrib
+ in the main list but append it manually for the relevant searches.
+ * Fix two memleaks in login_cache.c.
+ * fixes memory bloat when unmarshalling strings.
+ * Fix compile errors using gcc 3.2 on SuSE 8.2.
+ * Fix the build for systems without kerberos headers.
+ * Allow winbindd to handle authentication requests only when
+ started without either an 'idmap uid' or 'idmap gid' range.
+ * Fix the build for systems without ldap headers.
+ * Fix interaction between share security descriptor and the
+ 'read only' smb.conf option.
+ * Fix bug that caused _samr_lookupsids() with more than 32 (
+ MAX_REF_DOMAINS) SIDs to fail.
+ * Allow the 'idmap backend' parameter to accept a list of
+ LDAP servers for failover purposes.
+ * Revert code in smbd to remove a tdb when it has become
+ corrupted.
+ * Add paranoid checks when mapping SIDs to a uid/gid to
+ ensure that the type is correct.
+ * Initial work on getting client support for sending mailslot
+ datagrams.
+ * Add 'ldap timeout' parameter.
+ * Dont always uppercase 'afs username map'.
+ * Expand aliases for getusersids as well.
+ * Improved NT->AFS ACL mapping VFS module.
+
+
+o Herb Lewis <herb@samba.org>
+ * Add the acls debug class.
+ * Fix logic bug in netbios name truncate routine.
+ * Fix smbd crash caused by smbtorture IOCTL test.
+ * Fix errno tromping before calling iconv to reset the
+ conversion state.
+ * need to leave empty dacl so we can remove last ACE.
+
+
+o Jianliang Lu <Jianliang.Lu@getronics.com>
+ * Fix to stop smbd hanging on missing group member in
+ get_memberuids().
+ * Make sure Samba returns the correct group types.
+ * Reset the bad password count password counts upon a successful login.
+
+
+o Jason Mader <jason@ncac.gwu.edu>
+ * BUG 1385: Don't use non-consts in a structure initialization.
+
+
+o Jim McDonough <jmcd@us.ibm.com>
+ * BUG 1279: SMBjobid fix for Samba print servers running on
+ Big-Endian platforms.
+
+
+o Joe Meadows <jameadows@webopolis.com>
+ * Add optional timeout parameter to ldap open calls.
+ * Allow get_dc_list() to check the negative cache.
+
+
+o Stefan Metzmacher <metze@samba.org>
+ * fix a configure logic bug for linux/XFS quotas when
+ using --with-sys-quotas.
+ * Use quota debug class in quota code.
+ * print out the SVN revision by configure,
+
+
+o Buchan Milne <bgmilne@mandrake.org>
+ * Mandrake packaging fixes.
+
+
+o Lars Mueller <lmuelle@samba.org>
+ * BUG 1279: Added 'printcap cache time' parameter.
+ * Fix afs related build issues on SuSE.
+ * Fix compiler warnings in the kerberos client code.
+
+
+o James Peach <jpeach@sgi.com>
+ * More iconv detection fixes for IRIX.
+ * Compile fixed for systems that do not have C99/UNIX98 compliant
+ vsnprintf by default.
+ * Prevent smbd from attempting to use sendfile at all if it is
+ not supported by the server's OS.
+ * Allow SWAT to search for index.html when serving html files
+ in a directory.
+
+
+o Dan Peterson
+ * Implement NFS quota support on FreeBSD.
+
+
+o Tim Potter <tpot@samba.org>
+ * BUG 1360: Use -Bsymbolic when creating shared libraries to
+ avoid conflicts with identical symbols in the global namespace
+ when loading libnss_wins.so.
+
+
+o Richard Renard <rrenard@idealx.com>
+ * Save the current password as it is being changed into the
+ password history list.
+
+
+o Richard Sharpe <rsharpe@samba.org>
+ * Fix error return codes on some lock messages.
+ * BUG 1178: Make the libsmbclient routines callable
+ by C++ programs.
+ * BUG 1333: Make sure we return an error code when
+ things go wrong.
+ * BUG 1301: Return NT_STATUS_SHARING_VIOLATION when
+ share mode locking requests fail.
+
+
+o Simo Sorce <idra@samba.org>
+ * Update Debian stable & unstable packaging.
+ * Tidy up parametric options in testparm output.
+
+
+o Richard Sharpe <rsharpe@samba.org>
+ * Add sigchild handling to winbindd to restart the child
+ daemon if necessary.
+
+
+o Tom Shaw <tomisfaraway@gmail.com>
+ * Use winbindd_fill_pwent() consistently.
+
+
+o Nick Thompson <nickthompson@agere.com>
+ * Protect smbd against broken filesystems which return zero
+ blocksize.
+
+
+o Andrew Tridgell <tridge@samba.org>
+ * Fixed bug in handling of timeout in socket connections.
+
+
+o Nick Wellnhofer <wellnhofer@aevum.de>
+ * Prevent lp_interfaces() list from being corrupted. Fixes
+ bug where nmbd would lose the list of network interfaces
+ on the system and consequently shutdown.
+
+
+o James Wilkinson <jwilk@alumni.cse.ucsc.edu>
+ * Fix ntlm_auth memory leaks.
+
+
+o Jelmer Vernooij <jelmer@samba.org>
+ * Additional NT status to unix error mappings.
+ * BUG 478: Rename vsnprintf to smb_vsnprintf so we don't
+ get duplicate symbol errors.
+ * Return an error when the last command read from stdin
+ fails in smbclient.
+ * Prepare for better error checking in tar.
+ * BUG 1474: Fix build of --with-expsam stuff on Solaris.
+
+
+ --------------------------------------------------
+
+ =============================
+ Release Notes for Samba 3.0.5
+ July 20, 2004
+ =============================
+
+Please note that Samba 3.0.5 is identical to Samba 3.0.4 with
+the exception of correcting the two security issues outlined
+below.
+
+######################## SECURITY RELEASE ########################
+
+Summary: Multiple Potential Buffer Overruns in Samba 3.0.x
+CVE ID: CAN-2004-0600, CAN-2004-0686
+ (http://cve.mitre.org/)
+
+
+This is the latest stable release of Samba. This is the version
+that production Samba servers should be running for all current
+bug-fixes.
+
+It has been confirmed that versions of Samba 3 prior to v3.0.4
+are vulnerable to two potential buffer overruns. The individual
+details are given below.
+
+=============
+CAN-2004-0600
+=============
+
+Affected Versions: Samba 3.0.2 and later
+
+The internal routine used by the Samba Web Administration
+Tool (SWAT v3.0.2 and later) to decode the base64 data
+during HTTP basic authentication is subject to a buffer
+overrun caused by an invalid base64 character. It is
+recommended that all Samba v3.0.2 or later installations
+running SWAT either (a) upgrade to v3.0.5, or (b) disable
+the swat administration service as a temporary workaround.
+
+This same code is used internally to decode the
+sambaMungedDial attribute value when using the ldapsam
+passdb backend. While we do not believe that the base64
+decoding routines used by the ldapsam passdb backend can
+be exploited, sites using an LDAP directory service with
+Samba are strongly encouraged to verify that the DIT only
+allows write access to sambaSamAccount attributes by a
+sufficiently authorized user.
+
+The Samba Team would like to heartily thank Evgeny Demidov
+for analyzing and reporting this bug.
+
+-------------
+CAN-2004-0686
+-------------
+
+Affected Versions: Samba 3.0.0 and later
+
+A buffer overrun has been located in the code used to support
+the 'mangling method = hash' smb.conf option. Please be aware
+that the default setting for this parameter is 'mangling method
+= hash2' and therefore not vulnerable.
+
+Affected Samba 3 installations can avoid this possible security
+bug by using the default hash2 mangling method. Server
+installations requiring the hash mangling method are encouraged
+to upgrade to Samba 3.0.5.
+
+
+##################################################################
+
+ --------------------------------------------------
+
+ =============================
+ Release Notes for Samba 3.0.4
+ May 8, 2004
+ =============================
+
+Common bugs fixed in Samba 3.0.4 include:
+
+ o Password changing after applying the patch described in
+ the Microsoft KB828741 article to Windows clients.
+ o Crashes in smbd.
+ o Managing print jobs via Windows on Big-Endian servers.
+ o Several memory leaks in winbindd and smbd.
+ o Compile issues on AIX and *BSD.
+
+Changes since 3.0.3
+--------------------
+
+commits
+-------
+
+o Jeremy Allison <jra@samba.org>
+ * Fix path processing for DeletePrinterDriverEx().
+ * BUG 1303: Fix for Microsoft hotfix MS04-011 password change
+ breakage.
+
+
+o Andrew Bartlett <abartlet@samba.org>
+ * Fix alignment bug in GetDomPwInfo().
+
+
+o Alexander Bokovoy <ab@samba.org>
+ * Fix utime[s]() issues in smbwrapper on systems
+ that can boot both the 2.4 and 2.6 Linux kernels.
+
+
+o Gerald Carter <jerry@samba.org>
+ * Fedora packaging fixes.
+ * BUG 1302: Fix seg fault by not trying to optimize a list of
+ invalid gids using the wrong array size.
+ * BUG 1309: fix seg fault caused by trying to strdup(NULL)
+ seen when 'security = share'.
+ * Fix problems when using IBM's compiler on AIX.
+ * Link Developer's Guide, Example Guide, and multi-page HOWTO
+ into SWAT's welcome page.
+ * BUG 1293: fix double free in printer publishing code.
+
+
+o Wim Delvaux <wim.delvaux@adaptiveplanet.com>
+ * Fix for handling timeouts in socket connections.
+
+
+o Michel Gravey <michel.gravey@optogone.com>
+ * BUG 483: patch from to fix password hash creation in SWAT.
+
+
+o Volker Lendecke <vl@samba.org>
+ * Close the open NT pipes before the tdis.
+ * Fix AFS related build issues.
+ * Handle error conditions when base64 encoding a blob of 0 bytes.
+
+
+o Herb Lewis <herb@samba.org>
+ * Added 'acls' debug class.
+
+o kawasa_r@itg.hitachi.co.jp
+ * Multiple variable initialization and memory leak fixes.
+
+
+o Stephan Kulow <coolo@suse.de>
+ * Fix string length bug in libsmbclient that caused KDE's
+ Konqueror to crash.
+ * BUG 429: More libsmbclient fixes.
+
+
+o Jim McDonough <jmcd@us.ibm.com>
+ * BUG 1007, 1279: Store the print job using a little-endian key.
+
+
+o Eric Mertens
+ o Compile fix for OpenBSD (ENOTSUP not supported).
+
+
+o Stefan Metzmacher <metze@samba.org>
+ * Correct bug in disks quota views from explorer.
+
+
+o Tim Potter <tpot@samba.org>
+ BUG 1305: Correct debug output.
+
+
+o Richard Sharpe <rsharpe@samba.org>
+ * Fix incorrect error code mapping.
+
+
+o Jelmer Vernooij <jelmer@samba.org>
+ * Add additional NT_STATUS errorm mappings.
+
+
+ --------------------------------------------------
+
+ =============================
+ Release Notes for Samba 3.0.3
+ April 29, 2004
+ =============================
+
+
+Common bugs fixed in Samba 3.0.3 include:
+
+ o Crash bugs and change notify issues in Samba's printing code.
+ o Honoring secondary group membership on domain member servers.
+ o TDB scalability issue surrounding the TDB_CLEAR_IF_FIRST flag.
+ o Substitution errors for %[UuGg] in smb.conf.
+ o winbindd crashes when using ADS security mode.
+ o SMB signing errors.
+ o Delays in winbindd startup caused by unnecessary
+ connections to trusted domain controllers.
+ o Various small memory leaks.
+ o Winbindd failing due to expired Kerberos tickets.
+
+New features introduced in Samba 3.0.3 include:
+
+ o Improved support for i18n character sets.
+ o Support for account lockout policy based on
+ bad password attempts.
+ o Improved support for long password changes (>14
+ characters) and strong password enforcement.
+ o Support for Windows aliases (i.e. nested groups).
+ o Experimental support for storing DOS attribute on files
+ and folders in Extended Attributes.
+ o Support for local nested groups via winbindd.
+ o Specifying options to be passed directly to the CUPS libraries.
+
+Please be aware that the Samba source code repository was
+migrated from CVS to Subversion on April 4, 2004. Details on
+accessing the Samba source tree via anonymous svn can be found
+at http://svn.samba.org/samba/subversion.html.
+
+
+Changes since 3.0.2a
+--------------------
+smb.conf changes
+----------------
+
+ Parameter Name Action
+ -------------- ------
+ cups options New
+ ea support New
+ only user Deprecated
+ store dos attributes New
+ unicode Removed
+ winbind nested groups New
+
+
+commits
+-------
+
+o Jeremy Allison <jra@samba.org>
+ * Ensure that Kerberos mutex is always properly unlocked.
+ * Removed Heimdal "in-memory keytab" support.
+ * Fixup the 'multiple-vuids' bugs in our server code.
+ * Correct return code from lsa_lookup_sids() on unmapped
+ sids (based on work by vl@samba.org).
+ * Fix the "too many fcntl locks" scalability problem
+ raised by tridge.
+ * Fixup correct (as per W2K3) returns for lookupsids
+ as well as lookupnames.
+ * Fixups for delete-on-close semantics as per Win2k3 behavior.
+ * Make SMB_FILE_ACCESS_INFORMATION call work correctly.
+ * Fix "unable to initialize" bug when smbd hasn't been run with
+ new system and a user is being added via pdbedit/smbpasswd.
+ * Added NTrename SMB (0xA5).
+ * Fixup correct timeout values for blocking lock timeouts.
+ * Fix various bugs reported by 'gentest'.
+ * More locking fixes in the case where we own the lock.
+ * Fix up regression in IS_NAME_VALID and renames.
+ * Don't set allocation size on directories.
+ * Return correct error code on fail if file exists and target
+ is a directory.
+ * Added client "hardlink" comment to test doing NT rename with
+ hard links. Added hardlink_internals() code - UNIX extensions
+ now use this as well.
+ * Use a common function to parse all pathnames from the wire for
+ much closer emulation of Win2k3 error return codes.
+ * Implement check_path_syntax() and rewrite string sub
+ functions for better multibyte support.
+ * Ensure msdfs referrals are multibyte safe.
+ * Allow msdfs symlink syntax to be more forgiving.
+ eg. sym_link -> msdfs://server/share/path/in/share
+ or sym_link -> msdfs:\\server\share\path\in\share.
+ * Cleanup multibyte netbios name support in nmbd ( based on patch
+ by MORIYAMA Masayuki <moriyama@miraclelinux.com>).
+ * Fix check_path_syntax() for multibyte encodings which have
+ no '\' as second byte (based on work by ab@samba.org.
+ * Fix the "dfs self-referrals as anonymous user" problem
+ (based on patch from vl@samba.org).
+ * BUG 1064: Ensure truncate attribute checking is done correctly
+ on "hidden" dot files.
+ * Fix bug in anonymous dfs self-referrals again.
+ * Fix get/set of EA's in client library
+ * Added support for OS/2 EA's in smbd server.
+ * Added 'ea support' parameter to smb.conf.
+ * Added 'store dos attributes' parameter to smb.conf.
+ * Fix wildcard identical rename.
+ * Fix reply_ctemp - make compatible with w2k3.
+ * Fix wildcard unlink.
+ * Fix wildcard src with wildcard dest renames.
+ * BUG 1139: Fix based on suggestion by jdev@panix.com.
+ swap lookups for user and group - group will do an
+ algorithmic lookup if it fails, user won't.
+ * Make EA's lookups case independent.
+ * Fix SETPATHINFO in 'unix extensions' support.
+ * Make 3.x pass the Samba 4.x RAW-SEARCH tests - except for
+ the UNIX info levels, and the short case preserve names.
+
+
+o Timur Bakeyev <timur@com.bat.ru>
+ * BUG 1144: only set --with-fhs when the argument is 'yes'
+ * BUG 1152: Allow python modules to build despite libraries added
+ to LDFLAGS instead of LDPATH.
+ * BUG 1141: Fix nss*.so names on FreeBSD 5.x.
+
+
+o Craig Barratt <cbarratt@users.sourceforge.net>
+ * BUG 389: Allow multiple exclude arguments with smbclient
+ tar -Xr options (better support for Amanda backup client).
+
+
+o Andrew Bartlett <abartlet@samba.org>
+ * Include support for linking with cracklib for enforcing strong
+ password changes.
+ * Add support for >14 character password changes from Windows
+ clients.
+ * Add 'admin set password' capability to 'net rpc'.
+ * Allow 'net rpc samdump' to work with any joined domain
+ regardless of smb.conf settings.
+ * Use an allocated buffer for count_chars.
+ * Add sanity checks for changes in the domain SID in an
+ LDAP DIT.
+ * Implement python unit tests for Samba's multibyte string
+ support.
+ * Remove 'unicode' smb.conf option.
+ * BUG 1138: Fix support for 'optional' SMB signing and other
+ signing bugs.
+ * BUG 169: Fix NTLMv2-only behavior.
+ * Ensure 'net' honors the 'netbios name' in the smb.conf by
+ default.
+ * Support SMB signing on connections using only the LANMAN
+ password and generate the correct the 'session key' for these
+ connections.
+ * Implement --required-membership-of=, an ntlm_auth option
+ that restricts all authentication to members of this particular
+ group.
+ * Improve our fall back code for password changes.
+ * Only send the ntlm_auth 'ntlm-server-1' helper client a '.'
+ after the server had said something (such as an error).
+ * Add 'ntlm-server-1' helper protocol to ntlm_auth.
+
+
+o Alexander Bokovoy <ab@samba.org>
+ * Fix incorrect size calculation of the directory name
+ in recycle.so.
+ * Fix problems with very long filenames in both smbd and smbclient
+ caused by truncating paths during character conversions.
+ * Fix smbfs problem with Tree Disconnect issued before smbfs
+ starts its work.
+
+
+o Gerald Carter <jerry@samba.org>
+ * BUG 850: Fix 'make installmodules' bug on True64.
+ * BUG 66: mark 'only user' deprecated.
+ * Remove corrupt tdb and shutdown (only for printing tdbs,
+ connections, sessionid & locking).
+ * decrement smbd counter in connections.tdb in smb_panic().
+ * RedHat specfile updates.
+ * Fix xattr.h build issue on Debian testing and SuSE 8.2.
+ * BUG 1147; bad pointer case in get_stored_queue_info()
+ causing seg fault.
+ * BUG 761: read the config file before initialized default
+ values for printing options; don't default to bsd printing
+ Linux.
+ * Allow the 'printing' parameter to be set on a per share basis.
+ * BUG 503: RedHat/Fedora packaging fixes regarding logrotate.
+ * BUG 848: don't create winbind local users/groups that already
+ exist in the tdb.
+ * BUG 1080: fix declaration of SMB_BIG_UINT (broke compile on
+ LynxOS/ppc).
+ * BUG 488: fix the 'show client in col 1' button and correctly
+ enumerate active connections.
+ * BUG 1007 (partial): Fix abort in smbd caused by byte ordering
+ problem when storing the updating pid for the lpq cache.
+ * BUG 1007 (partial): Fix print change notify bugs.
+ * BUG 1165, 1126: Fix bug with secondary groups (security = ads)
+ and winbind use default domain = yes. Also ensures that
+ * BUG 1151: Ensure that winbindd users are passed through
+ the username map.
+ * Fix client rpc binds for ASU derived servers (pc netlink,
+ etc...).
+ * BUG 417, 1128: Ensure that the current_user_info is set
+ consistently so that %[UuGg] is expanded correctly.
+ * BUG 1195: Fix crash in winbindd when the ADS server is
+ unavailable.
+ * BUG 1185: Set reconnect time to be the same as the
+ 'winbind cache time'.
+ * Ensure that we return the sec_desc in smb_io_printer_info_2.
+ * Change Samba printers Win32 attribute to PRINTER_ATTRIBUTE_LOCAL.
+ * BUG 1095: Honor the '-l' option in smbclient.
+ * BUG 1023: surround get_group_from_gid() with become_unbecome_root()
+ block.
+ * Ensure server schannel uses the auth level requested by the
+ client.
+ * Removed --with-cracklib option due to potential crash issue.
+ * Fix -lcrypto linking problem with wbinfo.
+ * BUG 761: allow printing parameter to set defaults on a per
+ share basis.
+ * Add 'cups options' parameter to allow raw printing without
+ changing /etc/cups/cupsd.conf.
+ * BUG 1081, 1183: Added remove_duplicate_gids() to smbd and
+ winbindd.
+ * BUG 1246: Fix typo in Fedora /etc/init.d/winbind.
+ * BUG 1288: resolve any machine netbios name (0x00) and not just
+ servers (0x20).
+ * BUG 1199: Fix potential symlink issue in
+ examples/printing/smbprint.
+
+
+o Robert Dahlem <Robert.Dahlem@gmx.net>
+ * BUG 1048: Don't return short names when when 'mangled names = no'
+
+
+o Guenther Deschner <gd@suse.com>
+ * Remove hard coded attribute name in the ads ranged retrieval
+ code.
+ * Add --with-libdir and --with-mandir to autoconf script.
+
+
+o Bostjan Golob <golob@gimb.org>
+ * BUG 1046: Fix getpwent_list() so that the username is not
+ overwritten by other fields.
+
+
+o Landon Fuller <landonf@opendarwin.org>
+ * BUG 1232: patch from landonf@opendarwin.org (Landon Fuller)
+ to fix user/group enumeration on systems whose libc does not
+ call setgrent() before trying to enumerate users (i.e.
+ FreeBSD 5.2).
+
+
+o Steve French <sfrench@us.ibm.com>
+ * Update mount.cifs to version 1.1.
+ * Disable dev (MS_NODEV) on user mounts from cifs vfs.
+ * Fixes to minor security bug in the mount helper.
+ * Fix credential file mounting for cifs vfs.
+ * Fix free of incremented pointer in cifsvfs mount helper.
+ * Fix path canonicalization of the mount target path and help
+ text display in the cifs mount helper.
+ * Add missing guest mount option for mount.cifs.
+
+
+o SATOH Fumiyasu <fumiya@miraclelinux.com>
+ * BUG 1055; formatting fixes for 'net share'.
+ * BUG 692: correct truncation of share names and workgroup
+ names in smbclient.
+ * BUG 1088: use strchr_m() for query_host (smbclient -L).
+ * Patch from to internally count characters correctly.
+
+
+o Paul Green <paulg@samba.org>
+ * Update VOS _POSIX_C_SOURCE macro to 200112L.
+ * Fix bug in configure.ion by moving the first use of
+ AC_CHECK_HEADERS so it is always executed.
+ * Fix configure.in to only use $BLDSHARED to select whether to
+ build static or shared libraries.
+
+
+o Pat Haywarrd <Pat.Hayward@propero.net>
+ * Make the session_users list dynamic (max of 128K).
+
+
+o Cal Heldenbrand <calzplace@yahoo.com>
+ * Fix for for 'pam_smbpass migrate' functionality.
+
+
+o Chris Hertel <crh@samba.org>
+ * fix enumeration of shares 12 characters in length via
+ smbclient.
+
+
+o Ulrich Holeschak <ulrich@holeschak.de>
+ * BUG 932: fix local password change using pam_smbpass
+
+
+o Krischan Jodies <kj@sernet.de>
+ * Implement 'net rpc group delete'
+
+
+o John Klinger <john.klinger@lmco.com>
+ * Return NSS_SUCCESS once the max number of gids possible
+ has been found in initgroups() on Solaris.
+ * BUG 1182: Re-enable the -n 'no cache' option for winbindd.
+
+
+o Volker Lendecke <vl@samba.org>
+ * Fix success message for net groupmap modify.
+ * Fix errors when enumerating members of groups in 'net rpc'.
+ * Match Windows behavior in samr_lookup_names() by returning
+ ALIAS(4) when you search in BUILTIN.
+ * Fix server SAMR code to be able to set alias info for
+ builtin as well.
+ * Fix duplication of logic when creating groups via smbd.
+ * Ensure that the HWM values are set correctly after running
+ 'net idmap'.
+ * Add 'net rpc group add'.
+ * Implement 'net groupmap set' and 'net groupmap cleanup'.
+ * Add 'net rpc group [add|del]mem' for domain groups and aliases.
+ * Fix wb_delgrpmem (wbinfo -o).
+ * As a DC we should not reply to lsalookupnames on DCNAME\\user.
+ * Fix sambaUserWorkstations on a Samba DC.
+ * Implement wbinfo -k: Have winbind generate an AFS token after
+ authenticating the user.
+ * Add expand_msdfs VFS module for providing referrals based on the
+ the client's IP address.
+ * Implement client side NETLOGON GetDCName function.
+ * Fix caching of name->sid lookups.
+ * Add support in winbindd for expanding nested local groups.
+ * Fix memleak in winbindd.
+ * Fix msdfs proxy.
+ * Don't list domain groups from BUILTIN.
+ * Fix memleak in policy handle utility functions.
+ * Decrease winbindd startup time by only contacting trusted
+ domains as necessary.
+ * Allow winbindd to ask the DC for its domain for a trusted
+ DC.
+ * Fix Netscape DS schema based on comments from
+ <thomas.mueller@christ-wasser.de>.
+ * Correct case where adding a domain user to a XP local group
+ did a lsalookupname on the user without domain prefix, and
+ failed.
+ * Fix segfault in winbindd caused by 'wbinfo -a'.
+
+
+o Herb Lewis <herb@samba.org>
+ * Fix typo for tag in proto file.
+ * Add missing #ifdef HAVE_BICONV stuff.
+ * Truncate Samba's netbios name at the first '.' (not
+ right to left).
+
+
+o Derrell Lipman <Derrell.Lipman@UnwiredUniverse.com>
+ * Bug fixes and enhancements to libsmbclient library.
+
+
+o Jianliang Lu <j.lu@tiesse.com>
+ * Enforce the 'user must change password at next login' flag.
+ * Decode meaning of 'fields present' flags (improves support
+ for usrmgr.exe).
+ * NTLMv2 fixes.
+ * Don't force an upper case domain name in the ntlmssp code.
+
+
+o L. Lucius <ib@digicron.com>.
+ * type fixes.
+
+
+o Jim McDonough <jmcd@us.ibm.com>
+ * Add versioning support to tdbsam.
+ * Update the IBM Directory Server schema with the OpenLDAP
+ file.
+ * Various decoding fixes to improve usrmgr.exe support.
+ * Fix statfs redeclaration of statfs struct on ppc
+ * Implement support for password lockout of Samba domain
+ controllers and standalone servers.
+ * Get MungedDial attribute actually working with full TS
+ strings in it for pdb_ldap.
+ * BUG 1208 (partial): Improvements for working with expired krb5
+ tickets in winbindd.
+ * Use timegm, or our already existing replacement instead of
+ timezone (spotted by Andrzej Tobola <san@iem.pw.edu.pl>).
+ * Remove modifyTimestamp from list of our attributes.
+ * Fix lsalookupnames to check for domain users as well as local
+ users.
+ * Merge struct uuid replacement for GUID from trunk.
+ * BUG 1208: Finish support for handling expired tickets in
+ winbindd (in conjunction with Guenther Deschner <gd@suse.de>).
+
+
+o Stefan Metzmacher <metze@samba.org>
+ * Implement new VERSION schema based on subversion revision
+ numbers.
+ * Add shadow_copy vfs module.
+ * Fix segault in login_cache support.
+
+
+o Heinrich Mislik <Heinrich.Mislik@univie.ac.at>
+ o BUG 979 -- Fix quota display on AIX.
+
+
+o James Peach <jpeach@sgi.com>
+ * Correct check for printf() format when using the SGI MIPSPro
+ compiler.
+ * BUG 1038: support backtrace for 'panic action' on IRIX.
+ * BUG 768: Accept profileing arg to IRIX init script.
+ * BUG 748: Relax arg parsing to sambalp script (IRIX).
+ * BUG 758: Fix pdma build.
+ * Search IRIX ABI paths for libiconv. Based on initial fix from
+ Jason Mader.
+
+
+o Kurt Pfeifle <kpfeifle@danka.de>
+ * Add example shell script for migrating drivers and printers
+ from a Windows print server to a Samba print server using
+ smbclient/rpcclient (examples/printing/VamireDriversFunctions).
+
+
+o Tim Potter <tpot@samba.org>
+ * Fix logic bug in tdb non-blocking lock routines when
+ errno == EAGAIN.
+ * BUG 1025: Include sys/acl.h in check for broken nisplus
+ include files.
+ * BUG 1066: s/printf/d_printf/g in SWAT.
+ * BUG 1098: rename internal msleep() function to fix build
+ problems on AIX.
+ * BUG 1112: Fix for writable printerdata problem in python bindings.
+ * BUG 1154: Remove reference to <sys/mman.h> in tdbdump.c.
+ * BUG 1155: enclose use of fchown() with guards.
+ * Relicense tdb python module as LGPL.
+
+
+o Richard Sharpe <rsharpe@samba.org>
+ * Add support to smbclient for multiple logins on the same
+ session (based on work by abartlet@samba.org).
+ * Correct blocking condition in smbd's use of accept() on IRIX.
+ * Add support for printing out the MAC address on nmblookup.
+
+
+o Simo Sorce <idra@samba.org>
+ * Replace unknown_3 with fields_present in SAMR code.
+ * More length checks in strlcat().
+
+
+o Andrew Tridgell <tridge@samba.org>
+ * Rewrote the AIX UESS backend for winbindd.
+ * Fixed compilation with --enable-dmalloc.
+ * Change tdb license to LGPL (see source/tdb/tdb.c).
+ * Force winbindd to use schannel in clients connections to
+ DC's if possible.
+
+
+o Jelmer Vernooij <jelmer@samba.org>
+ * Fix ETA Calculation when resuming downloads in smbget.
+ * Add -O (for writing downloaded files to standard out)
+ based on patch by Bas van Sisseren <bas@dnd.utwente.nl>.
+ * Fix syntax error in example mysql table
+
+
+o TAKEDA yasuma <yasuma@miraclelinux.com>
+ * BUG 900: fix token processing in cmd_symlink, cmd_link,
+ cmd_chown, cmd_chmod smbclient functions.
+
+
+o Shiro Yamada <shiro@miraclelinux.com>
+ * BUG 1129: install image files for SWAT.
+
+
+ --------------------------------------------------
+
+ ==============================
+ Release Notes for Samba 3.0.2a
+ February 13, 2004
+ ==============================
+
+Samba 3.0.2a is a minor patch release for the 3.0.2 code base
+to address, in particular, a problem when using pdbedit to
+sanitize (--force-initialized-passwords) Samba's tdbsam
+backend. This is the latest stable release of Samba. This
+is the version that all production Samba servers should be
+running for all current bug-fixes.
+
+******************* Attention! Achtung! Kree! *********************
+
+Beginning with Samba 3.0.2, passwords for accounts with a last
+change time (LCT-XXX in smbpasswd, sambaPwdLastSet attribute in
+ldapsam, etc...) of zero (0) will be regarded as uninitialized
+strings. This will cause authentication to fail for such
+accounts. If you have valid passwords that meet this criteria,
+you must update the last change time to a non-zero value. If you
+do not, then 'pdbedit --force-initialized-passwords' will disable
+these accounts and reset the password hashes to a string of X's.
+
+******************* Attention! Achtung! Kree! *********************
+
+
+Changes since 3.0.2
+-------------------
+
+commits
+-------
+
+Please refer to the CVS log for the SAMBA_3_0 branch for complete
+details. The list of changes per contributor are as follows:
+
+
+o Jeremy Allison <jra@samba.org>
+ * Added paranoia checks in parsing code.
+
+
+o Andrew Bartlett <abartlet@samba.org>
+ * Ensure that changes to uninitialized passwords in ldapsam
+ are written to the DIT.
+
+
+o Gerald (Jerry) Carter <jerry@samba.org>
+ * Fixed iterator in tdbsam.
+ * Fix bug that disabled accounts with a valid NT password
+ hash, but no LanMan hash.
+
+
+o Steve French <sfrench@us.ibm.com>
+ * Added missing nosetuid and noexec options.
+
+
+o Bostjan Golob <golob@gimb.org>
+ * BUG 1046: Don't overwrite usernames of entries returned
+ by getpwent_list().
+
+
+o Sebastian Krahmer <krahmer@suse.de>
+ * Fixed potential crash bug in NTLMSSP parsing code.
+
+
+o Tim Potter <tpot@samba.org>
+ * Fixed logic in tdb_brlock error checking.
+
+
+o Urban Widmark <urban@teststation.com>
+ * Set nosuid,nodev flags in smbmnt by default.
+
+
+ --------------------------------------------------
+
+ =============================
+ Release Notes for Samba 3.0.2
+ February 9, 2004
+ =============================
+
+It has been confirmed that previous versions of Samba 3.0 are
+susceptible to a password initialization bug that could grant an
+attacker unauthorized access to a user account created by the
+mksmbpasswd.sh shell script.
+
+The Common Vulnerabilities and Exposures project (cve.mitre.org)
+has assigned the name CAN-2004-0082 to this issue.
+
+Samba administrators not wishing to upgrade to the current
+version should download the 3.0.2 release, build the pdbedit
+tool, and run
+
+ root# pdbedit-3.0.2 --force-initialized-passwords
+
+This will disable all accounts not possessing a valid password
+(e.g. the password field has been set a string of X's).
+
+Samba servers running 3.0.2 are not vulnerable to this bug
+regardless of whether or not pdbedit has been used to sanitize
+the passdb backend.
+
+Some of the more visible bugs in 3.0.1 addressed in the 3.0.2
+release include:
+
+ o Joining a Samba domain from Pre-SP2 Windows 2000 clients.
+ o Logging onto a Samba domain from Windows XP clients.
+ o Problems with the %U and %u smb.conf variables in relation to
+ Windows 9x/ME clients.
+ o Kerberos failures due to an invalid in memory keytab detection
+ test.
+ o Updates to the ntlm_auth tool.
+ o Fixes for various SMB signing errors.
+ o Better separation of WINS and DNS queries for domain controllers.
+ o Issues with nss_winbind FreeBSD and Solaris.
+ o Several crash bugs in smbd and winbindd.
+ o Output formatting fixes for smbclient for better compatibility
+ with scripts based on the 2.2 version.
+
+
+Changes since 3.0.1
+-------------------
+
+smb.conf changes
+----------------
+
+ Parameter Name Action
+ -------------- ------
+ ldap replication sleep New
+ read size removed (unused)
+ source environment removed (unused)
+
+
+commits
+-------
+
+Please refer to the CVS log for the SAMBA_3_0 branch for complete
+details. The list of changes per contributor are as follows:
+
+o Jeremy Allison <jra@samba.org>
+ * Revert change that broke Exchange clear text samlogons.
+ * Fix gcc 3.4 warning in MS-DFS code.
+ * Tidy up of NTLMSSP code.
+ * Fixes for SMB signing errors
+ * BUG 815: Workaround NT4 bug to support plaintext
+ password logins and UNICODE.
+ * Fix SMB signing bug when copying large files.
+ * Correct error logic in mkdir_internals() (caused a panic
+ when combined with --enable-developer).
+ * BUG 830: Protect against crashes due to bad character
+ conversions.
+
+
+o Petri Asikainen <paca@sci.fi>
+ * BUG 330, 387:Fix single valued attribute updates when
+ working with Novell NDS.
+
+
+o Andrew Bartlett <abartlet@samba.org>
+ * Correctly handle per-pipe NTLMSSP inside a NULL session.
+ * Fix segfault in gencache
+ * Fix early free() of encrypted_session_key.
+ * Change DC lookup routines to more carefully separate
+ DNS names (realms) from NetBIOS domain names.
+ * Add new sid_to_dn() function for internal winbindd use.
+ * Refactor cli_ds_enum_domain_trusts().
+ * BUG 707: Implement range retrieval of ADS attributes (based
+ on work from Volker <vl@samba.org> and Guenther Deschner
+ <gd@suse.com>).
+ * Automatically initialize the signing engine if a session key
+ is available.
+ * BUG 916: Do not perform a + -> ' ' substitution for squid URL
+ encoded strings, only form input in SWAT.
+ * Resets the NTLMSSP state for new negotiate packets.
+ * Add 2-byte alignments in net_samlogon() queries to parse
+ odd-length plain text passwords.
+ * Allow Windows groups with no members in winbindd.
+ * Allow normal authentication in the absence of a server
+ generated session key.
+ * More optimizations for looking up UNIX group lists.
+ * Clean up error codes and return values for pam_winbindd
+ and winbindd PAM interface.
+ * Fix string return values in ntlm_auth tool.
+ * Fix segfault when 'security = ads' but no realm is defined.
+ * BUG 722: Allow winbindd to map machine accounts to uids.
+ * More cleanups for winbindd's find_our_domain().
+ * More clearly detect whether a domain controller is an NT4
+ or mixed-mode AD DC (additional bug fixes by jerry & jmcd).
+ * Increase separation between DNS queries for hosts and queries
+ for AD domain controllers.
+ * Include additional NT_STATUS to PAM error mappings.
+ * Password initialization fixes.
+
+
+o Justin Baugh <justin.baugh@request.com>
+ * BUG 948: Implement missing functions required for FreeBSD
+ nss_winbind support.
+
+
+o Alexander Bokovoy <ab@samba.org>
+ * BUG 922: Make sure enable fast path for strlower_m() and
+ strupper_m().
+
+
+o Luca Bolcioni <Luca.Bolcioni@yacme.com>
+ * Fix crash when using 'security = server' and 'encrypt
+ passwords = no' by always initializing the session key.
+
+
+o Dmitry Butskoj <buc@odusz.elektra.ru>
+ * Fix for special files being hidden from admins.
+
+
+o Gerald (Jerry) Carter <jerry@samba.org>
+ * Fix bug in the lanman session key generation. Caused
+ "decode_pw: incorrect password length" error messages.
+ * Save the right case for the located user name in
+ fill_sam_account(). Fixes %U/%u expansion for win9x clients.
+ * BUG 897: Add well known rid for pre win2k compatible access
+ group.
+ * BUG 887: Correct typo in delete user script example.
+ * Use short lived TALLOC_CTX* for allocating printer objects
+ from the print handle cache.
+ * BUG 912: Fix check for HAVE_MEMORY_KEYTAB.
+ * Fix several warnings reported by the SUN Forte C compiler.
+ * Fully control DNS queries for AD DC's using 'name resolve order'.
+ * BUG 770: Send the SMBjobid for UNIX jobs back to the client.
+ * BUG 972: Fix segfault in cli_ds_getprimarydominfo().
+ * BUG 936: fix bind credentials for schannel binds in smbd.
+ * BUG 446: Fix output of smbclient for better compatibility
+ with scripts based on the 2.2 version (including Amanda).
+ * BUG 891, 949: Fedora packaging fixes.
+ * Fix bug that caused rpcclient to incorrectly retrieve
+ the SID for a server (this causing all calls that required
+ this information to fail).
+ * BUG 977: Don't create a homes share for a user if a static
+ share already exists by the same name.
+ * Removed unused smb.conf options.
+ * Password initialization fixes.
+ * Set the disable flag for template accounts created by
+ mksmbpasswd.sh.
+ * Disable any account has no passwords and does not have the
+ ACB_PWNOTREQ bit set.
+
+
+o Guenther Deschner <gd@suse.com>
+ * Install smbwrapper.so should be put into the $(libdir)
+ and not $(bindir).
+ * Add the capability to specify the new user password
+ for "net ads password" on the command line.
+ * Correctly detect AFS headers on SuSE.
+
+
+o James Flemer <jflemer@uvm.edu>
+ * Fix AIX compile bug by linking HAVE_ATTR_LIST to
+ HAVE_SYS_ATTRIBUTES_H.
+
+
+o Luke Howard <lukeh@PADL.COM>
+ * Fix segfault in session setup reply caused by a early free().
+
+
+o Stoian Ivanov <sdr@bultra.com>
+ * Implement grepable output for smbclient -L.
+
+
+o LaMont Jones <lamont@debian.org>
+ * BUG 225328 (Debian): Correct false failure LFS test that resulted
+ in _GNU_SOURCE not being defined (thus resulting in strndup()
+ not being defined).
+
+
+o Volker Lendecke <vl@samba.org>
+ * BUG 583: Ensure that user names always contain the short
+ version of the domain name.
+ * Fix our parsing of the LDAP uri.
+ * Don't show the 'afs username map' in the SWAT basic view.
+ * Fix SMB signing issues in relation to failed NTLMSSP logins.
+ * BUG 924: Fix return codes in smbtorture harness.
+ * Always lower-case usernames before handing it to AFS code.
+ * Add a German translation for SWAT.
+ * Fix a segfaults in winbindd.
+ * Fix the user's domain passed to register_vuid() from
+ reply_spnego_kerberos().
+ * Add NSS example code in nss_winbind to convert UNIX
+ id's <-> Windows SIDs.
+ * Display more descriptive error messages for login via 'net'.
+ * Fix compiler warning in the net tool.
+ * Fix length bug when decoding base64 strings.
+ * Ensure we don't call getpwnam() inside a loop that is iterating
+ over users with getpwent(). This broke on glibc 2.3.2.
+
+
+o Herb Lewis <herb@samba.org>
+ * Fix bit rot in psec.
+
+
+o Jianliang Lu <j.lu@tiesse.com>
+ * Ensure we delete the group mapping before calling the delete
+ group script.
+ * Define well known RID for managing the "Power Users" group.
+ * BUG 381: check builtin (not local) group SID when updating
+ group membership.
+ * BUG 101: set the SV_TYPE_PRINTQ_SERVER flag in host announcement
+ packet.
+
+
+o John Klinger <john.klinger@lmco.com>
+ * Implement initgroups() call in nss_winbind on Solaris.
+
+
+o Jim McDonough <jmcd@us.ibm.com>
+ * Fix regression in net rpc join caused by recent changes
+ to cli_lsa_query_info_policy().
+ * BUG 964: Fix crash bug in 'net rpc join' using a preexisting
+ machine account.
+
+
+o MORIYAMA Masayuki <moriyama@miraclelinux.com>
+ * BUG 570: Ensure that configure honors the LDFLAGS variable.
+
+
+o Stefan Metzmacher <metze@samba.org>
+ * Implement LDAP rebind sleep patch.
+ * Revert to 2.2 quota code because of so many broken quota files
+ out there.
+ * Fix XFS quotas: HAVE_XFS_QUOTA -> HAVE_XFS_QUOTAS
+ XFS_USER_QUOTA -> USRQUOTA
+ XFS_GROUP_QUOTA -> GRPQUOTA
+ * Fix disk_free calculation with group quotas.
+ * Add debug class 'quota' and a lot of DEBUG()'s
+ to the quota code.
+ * Fix sys_chown() when no chown() is present.
+ * Add SIGABRT to fault handling in order to catch got a
+ backtrace if an error occurs the OpenLDAP client libs.
+
+
+o <ndb@theghet.to>
+ * Allow an existing LDAP machine account to be re-used when
+ joining an AD domain.
+
+
+o James Peach <jpeach@sgi.com>
+ * BUG 889: Change smbd to use pread/pwrite on platforms that
+ support these calls. Can lead to a significant speed increase.
+
+
+o Tim Potter <tpot@samba.org>
+ * BUG 905: Remove POBAD_CC to fix Solaris Forte compiles.
+ * BUG 924: Fix typo in RW2 torture test.
+
+
+o Richard Sharpe <rsharpe@samba.org>
+ * Small fixes to torture.c to cleanup the error handling
+ and prevent crashes.
+
+
+o J. Tournier <jerome.tournier@IDEALX.com>
+ * Small fixes for the smbldap-tool scripts.
+
+
+o Andrew Tridgell <tridge@samba.org>
+ * Fix src len check in pull_usc2().
+
+
+o Jelmer Vernooij <jelmer@samba.org>
+ * Put functions for generating SQL queries in pdb_sql.c
+ * Add pgSQL backend (based on patch by Hamish Friedlander)
+ * BUG 908: Fix -s option to smbcontrol.
+ * Add smbget utility - a wget-clone for the SMB/CIFS protocol.
+ * Fix for libnss_wins on IRIX platforms.
+ * Fix swatdir for --with-fhs.
+
+
+ --------------------------------------------------
+
+ =============================
+ Release Notes for Samba 3.0.1
+ December 15, 2003
+ =============================
+
+Some of the more common bugs in 3.0.0 addressed in the release
+include:
+
+ o Substitution problems with smb.conf variables.
+ o Errors in return codes which caused some applications
+ to fail to open files.
+ o General Protection Faults on Windows 2000/XP clients
+ using Samba point-n-print features.
+ o Several miscellaneous crash bugs.
+ o Access problems when enumerating group mappings are
+ stored in an LDAP Directory.
+ o Several common SWAT bugs when writing changes to
+ smb.conf.
+ o Internal inconsistencies when 'winbind use default
+ domain = yes'
+
+
+
+Changes since 3.0.0
+----------------------
+
+ Parameter Name Action
+ -------------- ------
+ hide local users Removed
+ mangled map Deprecated
+ mangled stack Removed
+ passwd chat timeout New
+
+
+commits
+-------
+
+o Change the interface for init_unistr2 to not take a length
+ but a flags field. We were assuming that
+ 2*strlen(mb_string) == length of ucs2-le string. (bug 480).
+o Allow d_printf() to handle strings with escaped quotation
+ marks since the msg file includes the escape character (bug 489).
+o Fix bad html table row termination in SWAT wizard code (bug 413).
+o Fix to parse the level-2 strings.
+o Fix for "valid users = %S" in [homes]. Fix read/write
+ list as well.
+o Change AC_CHECK_LIB_EXT to prepend libraries instead of append.
+ This is the same way AC_CHECK_LIB works (bug 508).
+o Testparm output fixes for clarity.
+o Fix broken wins hook functionality -- i18n bug (bug 528).
+o Take care of condition where DOS and NT error codes must differ.
+o Default to using only built-in charsets when a working iconv
+ implementation cannot be located.
+o Wrap internals of sys_setgroups() so the sys_XX() call can
+ be done unconditionally (bug 550).
+o Remove duplicate smbspool link on SWAT's front page (bug 541).
+o Save and restore CFLAGS before/after AC_PROG_CC. Ensures that
+ --enable-debug=[yes|no] works correctly.
+o Allow ^C to interrupt smbpasswd if using our getpass
+ (e.g. smbpasswd command).
+o Support signing only on RPC's (bug 167).
+o Correct bug that prevented Excel 2000 clients from opening
+ files marked as read-only.
+o Portability fix bugs 546 - 549).
+o Explicitly initialize the value of AR for vendor makes that don't
+ do this (e.g. HPUX 11). (bug 552).
+o More i18n fixes for SWAT (bug 413).
+o Change the cwd before the postexec script to ensure that a
+ umount will succeed.
+o Correct double free that caused winbindd to crash when a DC
+ is rebooted (bug 437).
+o Fix incorrect mode sum (bug 562).
+o Canonicalize SMB_INFO_ALLOCATION in the same was as
+ SMB_FS_FULL_SIZE_INFORMATION (bug 564).
+o Add script to generate *msg files.
+o Add Dutch SWAT translation file.
+o Make sure to call get_user_groups() with the full winbindd
+ name for a user if he/she has one (bug 406).
+o Fix up error code returns from Samba4 tester. Ensure invalid
+ paths are validated the same way.
+o Allow Samba3 to pass the Samba4 RAW-READ tests.
+o Refuse to configure if --with-expsam=$BACKEND was used but no
+ libraries were found for $BACKEND.
+o Move sysquotas autoconf tests to a separate file.
+o Match W2K w.r.t. writelock and writeclose. Samba4 torture
+ tester
+o Make sure that the files that contain the static_init_$subsystem;
+ macro get recompiled after configure by removing the object
+ files.
+o Ensure canceling a blocking lock returns the correct error
+ message.
+o Match Samba 2.2 behavior; make ACB_NORMAL the default ACB value.
+o Updated Japanese welcome file in SWAT.
+o Fix to nt-time <-> unix-time functions reversible.
+o Ensure that winbindd uses the the escaped DN when querying
+ an AD ldap server.
+o Fix portability issues when compiling (bug 505, 550)
+o Compile fix for tdbbackup when Samba needs to override
+ non-C99 compliant implementations of snprintf().
+o Use @PICSUFFIX@ instead of .po in Makefile.in (bug 574).
+o Make sure we break out of samsync loop on error.
+o Ensure error code path doesn't free unmalloc()'d memory
+ (bug 628).
+o Add configure test for krb5_keytab_entry keyblock vs key
+ member (bug 636).
+o Fixed spinlocks.
+o Modified testparm so that all output so all debug output goes
+ to stderr, and all file processing goes to stdout.
+o Fix error return code for BUFFER_TOO_SMALL in smbcacls
+ and smbcquotas.
+o Fix "NULL dest in safe_strcpy()" log message by ensuring that
+ we have a devmode before copying a string to the devicename.
+o Support mapping REALM.COM\user to a local user account (without
+ running winbindd) for compatibility with 2.2.x release.
+o Ensure we don't use mmap() on blacklisted systems.
+o fixed a number of bugs and memory leaks in the AIX
+ winbindd shim
+o Call initgroups() in SWAT before becomming the user so that
+ secondary group permissions can be used when writing to
+ smb.conf.
+o Fix signing problems when reverse connecting back to a
+ client for printer notify
+o Fix signing problems caused by a miss-sequence bug.
+o Missing map in errormap for ERROR_MORE_DATA -> ERRDOS, ERRmoredata.
+ Fixes NEXUS tools running on Win9x clients (bug 64).
+o Don't leave the domain field uninitialized in cli_lsa.c if some
+ SID could not be mapped.
+o Fix segfault in mount.cifs helper when there is no options
+ specified during mount.
+o Change the \n after the password prompt to go to tty instead
+ of stdout (bug 668).
+o Stop net -P from prompting for machine account password (bug 451).
+o Change in behavior to Not only change the effective uid but also
+ the real uid when becoming unprivileged.
+o Cope with Exchange 5.5 cleartext pop password auth.
+o New files for support of initshutdown pipe. Win2k doesn't
+ respond properly to all requests on the winreg pipe, so we need
+ to handle this new pipe (bug 534).
+o Added more va_copy() checks in configure.in.
+o Include fixes for libsmbclient build problems.
+o Missing UNIX -> DOS codepage conversion in lanman.c.
+o Allow DFMS-S filenames can now have arbitrary case (bug 667).
+o Parameterize the listen backlog in smbd and make it larger by
+ default. A backlog of 5 is way too small these days.
+o Check for an invalid fid before dereferencing the fsp pointer
+ (bug 696).
+o Remove invalid memory frees and return codes in pdb_ldap.c.
+o Prompt for password when invoking --set-auth-user and no
+ password is given.
+o Bind the nmbd sending socket to the 'socket address'.
+o Re-order link command for smbd, rpcclient and smbpasswd to ensure
+ $LDFLAGS occurs before any library specification (bug 661).
+o Fix large number of printf() calls for 64-bit size_t.
+o Fix AC_CHECK_MEMBER so that SLES8 does correctly finds the
+ keyblock in the krb5 structs.
+o Remove #include <compat.h> in hopes to avoid problems with
+ apache header files.
+o Correct winbindd build problems on HP-UX 11.
+o Lowercase netgroups lookups (bug 703).
+o Use the actual size of the buffer in strftime instead of a made
+ up value which just happens to be less than sizeof(fstring).
+ (bug 713).
+o Add ldaplibs to pdbedit link line (bug 651).
+o Fix crash bug in smbclient completion (bug 659).
+o Fix packet length for browse list reply (bug 771).
+o Fix coredump in cli_get_backup_list().
+o Make sure that we expand %N (bug 612).
+o Allow rpcclient adddriver command to specify printer driver
+ version (bug 514).
+o Compile tdbdump by default.
+o Apply patches to fix iconv detection for FreeBSD.
+o Do not allow the 'guest account' to be added to a passdb backend
+ using smbpasswd or pdbedit (bug 624).
+o Save LDFLAGS during iconv detection (bug 57).
+o Run krb5 logins through the username map if the winbindd
+ lookup fails (bug 698).
+o Add const for lp_set_name_resolve_order() to avoid compiler
+ warnings (bug 471).
+o Add support for the %i macro in smb.conf to stand in for the for
+ the local IP address to which a client connected.
+o Allow winbindd to match local accounts to domain SID when
+ 'winbind trusted domains only = yes' (bug 680).
+o Remove code in idmap_ldap that searches the user suffix and group
+ suffix. It's not needed and provides inconsistent functionality
+ from the tdb backend.
+o Patch to handle munged dial string for Windows 2000 TSE.
+ Thanks to Gaz de France, Direction de la Recherche, Service
+ Informatique Métier for their supporting this work by Aurelien
+ Degrémont <adegremont@idealx.com>.
+o Correct the "smbldap_open: cannot access when not root error"
+ messages when looking up group information (bug 281).
+o Skip over the winbind separator when looking up a user.
+ This fixes the bug that prevented local users from
+ matching an AD user when not running winbindd (bug 698).
+o Fix a problem with configure on *BSD systems. Make sure
+ we add -liconv etc to LDFLAGS.
+o Fix core dump bug when "security = server" and the authentication
+ server goes away.
+o Correct crash bug due to an empty munged dial string.
+o Show files locked by a specific user (smbstatus -u 'user')
+ (bug 590).
+o Fix bug preventing print jobs from display in the queue
+ monitor used by Windows NT and later clients (bug 660).
+o Fix several reported problems with point-n-print from
+ Windows 2000/XP clients due to a bug in the EnumPrinterDataEx()
+ reply (bug 338, 527 & 643).
+o Fix a handful of potential memory leaks in the LDAP code used
+ by ldapsam[_compat] and the LDAP idmap backend.
+o Fix for pdbedit error code returns (bug 763).
+o Make sure we only enumerate group mapping entries (not
+ /etc/group) even when doing local aliases.
+o Relax check on the pipe name in a dce/rpc bind response to work
+ around issues with establishing trusts to a Windows 2003 domain.
+o Ensure we mangle names ending in '.' in hash2 mangling method.
+o Correct parsing issues with munged dial string.
+o Fix bugs in quota support for XFS.
+o Add a cleaner method for applications that need to provide
+ name->SID mappings to do this via NSS rather than having to
+ know the winbindd pipe protocol.
+o Adds a variant of the winbindd_getgroups() call called
+ winbindd_getusersids() that provides direct SID->SIDs listing of
+ a users supplementary groups. This is enough to allow non-Samba
+ applications to do ACL checking.
+o Make sure we don't append the 'ldap suffix' when writing out the
+ 'ldap XXX suffix' values in SWAT (bug 328).
+o Fix renames across file systems.
+o Ensure that items in a list of strings containing whitespace are
+ written out surrounded by single quotes. This means that both
+ double and single quotes are now used to surround strings in
+ smb.conf (bug 481).
+o Enable SWAT to correctly determine if winbindd is running (bug
+ 398).
+o Include WWW-Authenticate field in 401 response for bad auth
+ attempt (bug 629).
+o Add support for NTLM2 (NTLMv2 session security).
+o Add support for variable-length session keys.
+o More privilege fixes for group enumeration in LDAP (bug 281).
+o Use the dns name (or IP) as the originating client name when
+ using CUPS (bug 467).
+o Fix various SMB signing bugs.
+o Fix ACL propagation on a DFS root (bug 263).
+o Disable NTLM2 for RPC pipes.
+o Allow the client to specify the NTLM2 flags got NTLMSSP
+ authentication.
+o Change the name of the job passed off to cups from "Test Page"
+ to "smbprn.00000033 Test Page" so that we can get the smb
+ jobid back. This allow users to delete jobs with cups printing
+ backend (partial work on bug 770).
+o Fix build of winbindd with static pdb modules.
+o Retrieve the correct ACL group bits if the file has an ACL
+ (bug 802).
+o Implement "net rpc group members": Get members of a domain group
+ in human-readable format.
+o Add MacOSX (Darwin) specific charset module code.
+o Use samr_dispinfo(level == 1) for enumerating domain users so we
+ can include the full name in gecos field (bug 587).
+o Add support for winbind's NSS library on FeeeBSD 5.1 (bug 797).
+o Implement 'net rpc group list [global|local|builtin]*' for a
+ select listing of the respective user databases.
+o Don't automatically set NT status code flag unless client tells
+ us it can cope.
+o Add 'net status [sessions|shares] [parseable]'.
+o Don't mistake pre-existing UNIX jobs for smb jobs (remainder of
+ bug 770).
+o Add 'Replicator' and 'RAS Servers' to list of builtin SIDs
+ (bug 608).
+o Fix inverted logic in hosts allow/deny checks caused by
+ s/strcmp/strequal/ (bug 846).
+o Implement correct version SamrRemoveSidForeignDomain() (bug 252).
+o Fix typo in 'hash' mangling algorithm.
+o Support munged dial for ldapsam (bug 800).
+o Fix process_incoming_data() to return the number of bytes handled
+ this call whether we have a complete PDU or not; fixes bug
+ with multiple PDU request rpc's broken over SMBwriteX calls
+ each.
+o Fix incorrect smb flags2 for connections to pre-NT servers
+ (causes smbclient to fail to OS2 for example) (bug 821).
+o Update version string in smbldap-tools Makefile to 0.8.2.
+o Correct a problem with "net rpc vampire" mis-parsing the
+ alias member info reply.
+o Ensure the ${libdir} is created by the installclientlib script.
+o Fix detection of Windows 2003 client architecture in the smb.conf
+ %a variable.
+o Ensure that smbd calls the add user script for a missing UNIX
+ user on kerberos auth call (bug 445).
+o Fix bugs in hosts allow/deny when using a mismatched
+ network/netmask pair.
+o Protect alloc_sub_basic() from crashing when the source string
+ is NULL (partial work on bug 687).
+o Fix spinlocks on IRIX.
+o Corrected some bad destination paths when running "configure
+ --with-fhs".
+o Add packaging files for Fedora Core 1.
+o Correct bug in SWAT install script for non-english languages.
+o Support character set ISO-8859-1 internally (bug 558).
+o Fixed more LDAP access errors when looking up group mappings
+ (bug 281).
+o Fix UNISTR2 length bug in LsaQueryInfo(3) that caused SID
+ resolution to fail on local files on on domain members
+ (bug 875).
+o Fix uninitialized variable in passdb.c.
+o Fix formal parameter type in get_static() in nsswitch/wins.c.
+o Fix problem mounting directories when mount.cifs is installed
+ with the setuid bit on.
+o Fix bug that prevent --mandir from overriding the defaults
+ given in the --with-fhs macro.
+o Fix bug in in-memory Kerberos keytab detection routines
+ in configure.in
+
+
+
+######################################################################
+
+ The original 3.0.0 release notes follow
+ =======================================
+ WHATS NEW IN Samba 3.0.0
+ September 24, 2003
+ =======================================
+
+
+Major new features:
+-------------------
+
+1) Active Directory support. Samba 3.0 is now able to
+ join a ADS realm as a member server and authenticate
+ users using LDAP/Kerberos.
+
+2) Unicode support. Samba will now negotiate UNICODE on the wire
+ and internally there is now a much better infrastructure for
+ multi-byte and UNICODE character sets.
+
+3) New authentication system. The internal authentication system
+ has been almost completely rewritten. Most of the changes are
+ internal, but the new auth system is also very configurable.
+
+4) New default filename mangling system.
+
+5) A new "net" command has been added. It is somewhat similar to
+ the "net" command in windows. Eventually we plan to replace
+ numerous other utilities (such as smbpasswd) with subcommands
+ in "net".
+
+6) Samba now negotiates NT-style status32 codes on the wire. This
+ improves error handling a lot.
+
+7) Better Windows 2000/XP/2003 printing support including publishing
+ printer attributes in active directory.
+
+8) New loadable module support for passdb backends and character
+ sets.
+
+9) New default dual-daemon winbindd support for better performance.
+
+10) Support for migrating from a Windows NT 4.0 domain to a Samba
+ domain and maintaining user, group and domain SIDs.
+
+11) Support for establishing trust relationships with Windows NT 4.0
+ domain controllers.
+
+12) Initial support for a distributed Winbind architecture using
+ an LDAP directory for storing SID to uid/gid mappings.
+
+13) Major updates to the Samba documentation tree.
+
+14) Full support for client and server SMB signing to ensure
+ compatibility with default Windows 2003 security settings.
+
+15) Improvement of ACL mapping features based on code donated by
+ Andreas Grünbacher.
+
+
+Plus lots of other improvements!
+
+
+Additional Documentation
+------------------------
+
+Please refer to Samba documentation tree (included in the docs/
+subdirectory) for extensive explanations of installing, configuring
+and maintaining Samba 3.0 servers and clients. It is advised to
+begin with the Samba-HOWTO-Collection for overviews and specific
+tasks (the current book is up to approximately 400 pages) and to
+refer to the various man pages for information on individual options.
+
+We are very glad to be able to include the second edition of
+"Using Samba" by Jay Ts, Robert Eckstein, and David Collier-Brown
+(O'Reilly & Associates) in this release. The book is available
+on-line at http://samba.org/samba/docs/ and is included with
+the Samba Web Administration Tool (SWAT). Thanks to the authors and
+publisher for making "Using Samba" under the GNU Free Documentation
+License.
+
+
+######################################################################
+Upgrading from a previous Samba 3.0 beta
+########################################
+
+Beginning with Samba 3.0.0beta3, the RID allocation functions
+have been moved into winbindd. Previously these were handled
+by each passdb backend. This means that winbindd must be running
+to automatically allocate RIDs for users and/or groups. Otherwise,
+smbd will use the 2.2 algorithm for generating new RIDs.
+
+If you are using 'passdb backend = tdbsam' with a previous Samba
+3.0 beta release (or possibly alpha), it may be necessary to
+move the RID_COUNTER entry from /usr/local/samba/private/passdb.tdb
+to winbindd_idmap.tdb. To do this:
+
+1) Ensure that winbindd_idmap.tdb exists (launch winbindd at least
+ once)
+2) build tdbtool by executing 'make tdbtool' in the source/tdb/
+ directory
+3) run: (note that 'tdb>' is the tool's prompt for input)
+
+ root# ./tdbtool /usr/local/samba/private/passdb.tdb
+ tdb> show RID_COUNTER
+ key 12 bytes
+ RID_COUNTER
+ data 4 bytes
+ [000] 0A 52 00 00 .R.
+
+ tdb> move RID_COUNTER /usr/local/samba/var/locks/winbindd_idmap.tdb
+ ....
+ record moved
+
+If you are using 'passdb backend = ldapsam', it will be necessary to
+store idmap entries in the LDAP directory as well (i.e. idmap backend
+= ldap). Refer to the 'net idmap' command for more information on
+migrating SID<->UNIX id mappings from one backend to another.
+
+If the RID_COUNTER record does not exist, then these instructions are
+unneccessary and the new RID_COUNTER record will be correctly generated
+if needed.
+
+
+
+########################
+Upgrading from Samba 2.2
+########################
+
+This section is provided to help administrators understand the details
+involved with upgrading a Samba 2.2 server to Samba 3.0.
+
+
+Building
+--------
+
+Many of the options to the GNU autoconf script have been modified
+in the 3.0 release. The most noticeable are:
+
+ * removal of --with-tdbsam (is now included by default; see section
+ on passdb backends and authentication for more details)
+
+ * --with-ldapsam is now on used to provided backward compatible
+ parameters for LDAP enabled Samba 2.2 servers. Refer to the passdb
+ backend and authentication section for more details
+
+ * inclusion of non-standard passdb modules may be enabled using
+ --with-expsam. This includes an XML backend and a mysql backend.
+
+ * removal of --with-msdfs (is now enabled by default)
+
+ * removal of --with-ssl (no longer supported)
+
+ * --with-utmp now defaults to 'yes' on supported systems
+
+ * --with-sendfile-support is now enabled by default on supported
+ systems
+
+
+Parameters
+----------
+
+This section contains a brief listing of changes to smb.conf options
+in the 3.0.0 release. Please refer to the smb.conf(5) man page for
+complete descriptions of new or modified parameters.
+
+Removed Parameters (order alphabetically):
+
+ * admin log
+ * alternate permissions
+ * character set
+ * client codepage
+ * code page directory
+ * coding system
+ * domain admin group
+ * domain guest group
+ * force unknown acl user
+ * hide local users
+ * mangled stack
+ * nt smb support
+ * postscript
+ * printer driver
+ * printer driver file
+ * printer driver location
+ * read size
+ * source environment
+ * status
+ * strip dot
+ * total print jobs
+ * use rhosts
+ * valid chars
+ * vfs options
+
+New Parameters (new parameters have been grouped by function):
+
+ Remote management
+ -----------------
+ * abort shutdown script
+ * shutdown script
+
+ User and Group Account Management
+ ---------------------------------
+ * add group script
+ * add machine script
+ * add user to group script
+ * algorithmic rid base
+ * delete group script
+ * delete user from group script
+ * passdb backend
+ * set primary group script
+
+ Authentication
+ --------------
+ * auth methods
+ * realm
+ * passwd chat timeout
+
+ Protocol Options
+ ----------------
+ * client lanman auth
+ * client NTLMv2 auth
+ * client schannel
+ * client signing
+ * client use spnego
+ * disable netbios
+ * ntlm auth
+ * paranoid server security
+ * server schannel
+ * server signing
+ * smb ports
+ * use spnego
+
+ File Service
+ ------------
+ * get quota command
+ * hide special files
+ * hide unwriteable files
+ * hostname lookups
+ * kernel change notify
+ * mangle prefix
+ * map acl inherit
+ * msdfs proxy
+ * set quota command
+ * use sendfile
+ * vfs objects
+
+ Printing
+ --------
+ * max reported print jobs
+
+ UNICODE and Character Sets
+ --------------------------
+ * display charset
+ * dos charset
+ * unicode
+ * unix charset
+
+ SID to uid/gid Mappings
+ -----------------------
+ * idmap backend
+ * idmap gid
+ * idmap uid
+ * winbind enable local accounts
+ * winbind trusted domains only
+ * template primary group
+ * enable rid algorithm
+
+ LDAP
+ ----
+ * ldap delete dn
+ * ldap group suffix
+ * ldap idmap suffix
+ * ldap machine suffix
+ * ldap passwd sync
+ * ldap replication sleep
+ * ldap user suffix
+
+ General Configuration
+ ---------------------
+ * preload modules
+ * private dir
+
+Modified Parameters (changes in behavior):
+
+ * encrypt passwords (enabled by default)
+ * mangling method (set to 'hash2' by default)
+ * passwd chat
+ * passwd program
+ * restrict anonymous (integer value)
+ * security (new 'ads' value)
+ * strict locking (enabled by default)
+ * unix extensions (enabled by default)
+ * winbind cache time (increased to 5 minutes)
+ * winbind uid (deprecated in favor of 'idmap uid')
+ * winbind gid (deprecated in favor of 'idmap gid')
+
+
+Databases
+---------
+
+This section contains brief descriptions of any new databases
+introduced in Samba 3.0. Please remember to backup your existing
+${lock directory}/*tdb before upgrading to Samba 3.0. Samba will
+upgrade databases as they are opened (if necessary), but downgrading
+from 3.0 to 2.2 is an unsupported path.
+
+Name Description Backup?
+---- ----------- -------
+account_policy User policy settings yes
+gencache Generic caching db no
+group_mapping Mapping table from Windows yes
+ groups/SID to unix groups
+winbindd_idmap ID map table from SIDS to UNIX yes
+ uids/gids.
+namecache Name resolution cache entries no
+netsamlogon_cache Cache of NET_USER_INFO_3 structure no
+ returned as part of a successful
+ net_sam_logon request
+printing/*.tdb Cached output from 'lpq no
+ command' created on a per print
+ service basis
+registry Read-only samba registry skeleton no
+ that provides support for exporting
+ various db tables via the winreg RPCs
+
+
+Changes in Behavior
+-------------------
+
+The following issues are known changes in behavior between Samba 2.2 and
+Samba 3.0 that may affect certain installations of Samba.
+
+ 1) When operating as a member of a Windows domain, Samba 2.2 would
+ map any users authenticated by the remote DC to the 'guest account'
+ if a uid could not be obtained via the getpwnam() call. Samba 3.0
+ rejects the connection as NT_STATUS_LOGON_FAILURE. There is no
+ current work around to re-establish the 2.2 behavior.
+
+ 2) When adding machines to a Samba 2.2 controlled domain, the
+ 'add user script' was used to create the UNIX identity of the
+ machine trust account. Samba 3.0 introduces a new 'add machine
+ script' that must be specified for this purpose. Samba 3.0 will
+ not fall back to using the 'add user script' in the absence of
+ an 'add machine script'
+
+
+######################################################################
+Passdb Backends and Authentication
+##################################
+
+There have been a few new changes that Samba administrators should be
+aware of when moving to Samba 3.0.
+
+ 1) encrypted passwords have been enabled by default in order to
+ inter-operate better with out-of-the-box Windows client
+ installations. This does mean that either (a) a samba account
+ must be created for each user, or (b) 'encrypt passwords = no'
+ must be explicitly defined in smb.conf.
+
+ 2) Inclusion of new 'security = ads' option for integration
+ with an Active Directory domain using the native Windows
+ Kerberos 5 and LDAP protocols.
+
+ MIT kerberos 1.3.1 supports the ARCFOUR-HMAC-MD5 encryption
+ type which is neccessary for servers on which the
+ administrator password has not been changed, or kerberos-enabled
+ SMB connections to servers that require Kerberos SMB signing.
+ Besides this one difference, either MIT or Heimdal Kerberos
+ distributions are usable by Samba 3.0.
+
+
+Samba 3.0 also includes the possibility of setting up chains
+of authentication methods (auth methods) and account storage
+backends (passdb backend). Please refer to the smb.conf(5)
+man page for details. While both parameters assume sane default
+values, it is likely that you will need to understand what the
+values actually mean in order to ensure Samba operates correctly.
+
+The recommended passdb backends at this time are
+
+ * smbpasswd - 2.2 compatible flat file format
+ * tdbsam - attribute rich database intended as an smbpasswd
+ replacement for stand alone servers
+ * ldapsam - attribute rich account storage and retrieval
+ backend utilizing an LDAP directory.
+ * ldapsam_compat - a 2.2 backward compatible LDAP account
+ backend
+
+Certain functions of the smbpasswd(8) tool have been split between the
+new smbpasswd(8) utility, the net(8) tool, and the new pdbedit(8)
+utility. See the respective man pages for details.
+
+
+######################################################################
+LDAP
+####
+
+This section outlines the new features affecting Samba / LDAP
+integration.
+
+New Schema
+----------
+
+A new object class (sambaSamAccount) has been introduced to replace
+the old sambaAccount. This change aids us in the renaming of
+attributes to prevent clashes with attributes from other vendors.
+There is a conversion script (examples/LDAP/convertSambaAccount) to
+modify and LDIF file to the new schema.
+
+Example:
+
+ $ ldapsearch .... -b "ou=people,dc=..." > sambaAcct.ldif
+ $ convertSambaAccount --sid=<Domain SID> \
+ --input=sambaAcct.ldif --output=sambaSamAcct.ldif \
+ --changetype=[modify|add]
+
+The <DOM SID> can be obtained by running 'net getlocalsid
+<DOMAINNAME>' on the Samba PDC as root. The changetype determines
+the format of the generated LDIF output--either create new entries
+or modify existing entries.
+
+The old sambaAccount schema may still be used by specifying the
+"ldapsam_compat" passdb backend. However, the sambaAccount and
+associated attributes have been moved to the historical section of
+the schema file and must be uncommented before use if needed.
+The 2.2 object class declaration for a sambaAccount has not changed
+in the 3.0 samba.schema file.
+
+Other new object classes and their uses include:
+
+ * sambaDomain - domain information used to allocate rids
+ for users and groups as necessary. The attributes are added
+ in 'ldap suffix' directory entry automatically if
+ an idmap uid/gid range has been set and the 'ldapsam'
+ passdb backend has been selected.
+
+ * sambaGroupMapping - an object representing the
+ relationship between a posixGroup and a Windows
+ group/SID. These entries are stored in the 'ldap
+ group suffix' and managed by the 'net groupmap' command.
+
+ * sambaUnixIdPool - created in the 'ldap idmap suffix' entry
+ automatically and contains the next available 'idmap uid' and
+ 'idmap gid'
+
+ * sambaIdmapEntry - object storing a mapping between a
+ SID and a UNIX uid/gid. These objects are created by the
+ idmap_ldap module as needed.
+
+ * sambaSidEntry - object representing a SID alone, as a Structural
+ class on which to build the sambaIdmapEntry.
+
+
+New Suffix for Searching
+------------------------
+
+The following new smb.conf parameters have been added to aid in directing
+certain LDAP queries when 'passdb backend = ldapsam://...' has been
+specified.
+
+ * ldap suffix - used to search for user and computer accounts
+ * ldap user suffix - used to store user accounts
+ * ldap machine suffix - used to store machine trust accounts
+ * ldap group suffix - location of posixGroup/sambaGroupMapping entries
+ * ldap idmap suffix - location of sambaIdmapEntry objects
+
+If an 'ldap suffix' is defined, it will be appended to all of the
+remaining sub-suffix parameters. In this case, the order of the suffix
+listings in smb.conf is important. Always place the 'ldap suffix' first
+in the list.
+
+Due to a limitation in Samba's smb.conf parsing, you should not surround
+the DN's with quotation marks.
+
+
+IdMap LDAP support
+------------------
+
+Samba 3.0 supports an ldap backend for the idmap subsystem. The
+following options would inform Samba that the idmap table should be
+stored on the directory server onterose in the "ou=idmap,dc=plainjoe,
+dc=org" partition.
+
+ [global]
+ ...
+ idmap backend = ldap:ldap://onterose/
+ ldap idmap suffix = ou=idmap,dc=plainjoe,dc=org
+ idmap uid = 40000-50000
+ idmap gid = 40000-50000
+
+This configuration allows winbind installations on multiple servers to
+share a uid/gid number space, thus avoiding the interoperability problems
+with NFS that were present in Samba 2.2.
+
+
+
+######################################################################
+Trust Relationships and a Samba Domain
+######################################
+
+Samba 3.0.0beta2 is able to utilize winbindd as the means of
+allocating uids and gids to trusted users and groups. More
+information regarding Samba's support for establishing trust
+relationships can be found in the Samba-HOWTO-Collection included
+in the docs/ directory of this release.
+
+First create your Samba PDC and ensure that everything is
+working correctly before moving on the trusts.
+
+To establish Samba as the trusting domain (named SAMBA) from a Windows NT
+4.0 domain named WINDOWS:
+
+ 1) create the trust account for SAMBA in "User Manager for Domains"
+ 2) connect the trust from the Samba domain using
+ 'net rpc trustdom establish GLASS'
+
+To create a trustlationship with SAMBA as the trusted domain:
+
+ 1) create the initial trust account for GLASS using
+ 'smbpasswd -a -i GLASS'. You may need to create a UNIX
+ account for GLASS$ prior to this step (depending on your
+ local configuration).
+ 2) connect the trust from a WINDOWS DC using "User Manager
+ for Domains"
+
+Now join winbindd on the Samba PDC to the SAMBA domain using
+the normal steps for adding a Samba server to an NT4 domain:
+(note that smbd & nmbd must be running at this point)
+
+ root# net rpc join -U root
+ Password: <enter root password from smbpasswd file here>
+
+Start winbindd and test the join with 'wbinfo -t'.
+
+Now test the trust relationship by connecting to the SAMBA DC
+(e.g. POGO) as a user from the WINDOWS domain:
+
+ $ smbclient //pogo/netlogon -U Administrator -W WINDOWS
+ Password:
+
+Now connect to the WINDOWS DC (e.g. CRYSTAL) as a Samba user:
+
+ $ smbclient //crystal/netlogon -U root -W WINDOWS
+ Password:
+
+######################################################################
+Changes in Winbind
+##################
+
+Beginning with Samba3.0.0beta3, winbindd has been given new account
+manage functionality equivalent to the 'add user script' family of
+smb.conf parameters. The idmap design has also been changed to
+centralize control of foreign SID lookups and matching to UNIX
+uids and gids.
+
+
+Brief Description of Changes
+----------------------------
+
+1) The sid_to_uid() family of functions (smbd/uid.c) have been
+ reverted to the 2.2.x design. This means that when resolving a
+ SID to a UID or similar mapping:
+
+ a) First consult winbindd
+ b) perform a local lookup only if winbindd fails to
+ return a successful answer
+
+ There are some variations to this, but these two rules generally
+ apply.
+
+2) All idmap lookups have been moved into winbindd. This means that
+ a server must run winbindd (and support NSS) in order to achieve
+ any mappings of SID to dynamically allocated UNIX ids. This was
+ a conscious design choice.
+
+3) (OBSOLETE) New functions have been added to winbindd to emulate
+ the 'add user script' family of smbd functions without requiring
+ that external scripts be defined. This functionality is controlled
+ by the 'winbind enable local accounts' smb.conf parameter (enabled
+ by default).
+
+ However, this account management functionality is only supported
+ in a local tdb (winbindd_idmap.tdb). If these new UNIX accounts
+ must be shared among multiple Samba servers (such as a PDC and BDCs),
+ it will be necessary to define your own 'add user script', et. al.
+ programs that place the accounts/groups in some form of directory
+ such as NIS or LDAP. This requirement was deemed beyond the scope
+ of winbind's account management functions. Solutions for
+ distributing UNIX system information have been deployed and tested
+ for many years. We saw no need to reinvent the wheel.
+
+4) A member of a Samba controlled domain running winbindd is now able
+ to map domain users directly onto existing UNIX accounts while still
+ automatically creating accounts for trusted users and groups. This
+ behavior is controlled by the 'winbind trusted domains only' smb.conf
+ parameter (disabled by default to provide 2.2.x winbind behavior).
+
+5) Group mapping support is wrapped in the local_XX_to_XX() functions
+ in smbd/uid.c. The reason that group mappings are not included
+ in winbindd is because the purpose of Samba's group map is to
+ match any Windows SID with an existing UNIX group. These UNIX
+ groups can be created by winbindd (see next section), but the
+ SID<->gid mapping is retreived by smbd, not winbindd.
+
+
+Examples
+--------
+
+* security = server running winbindd to allocate accounts on demand
+
+* Samba PDC running winbindd to handle the automatic creation of UNIX
+ identities for machine trust accounts
+
+* Automtically creating UNIX user and groups when migrating a Windows NT
+ 4.0 PDC to a Samba PDC. Winbindd must be running when executing
+ 'net rpc vampire' for this to work.
+
+
+######################################################################
+Known Issues
+############
+
+* There are several bugs currently logged against the 3.0 codebase
+ that affect the use of NT 4.0 GUI domain management tools when run
+ against a Samba 3.0 PDC. This bugs should be released in an early
+ 3.0.x release.
+
+Please refer to https://bugzilla.samba.org/ for a current list of bugs
+filed against the Samba 3.0 codebase.
+
+
+######################################################################
+Reporting bugs & Development Discussion
+#######################################
+
+Please discuss this release on the samba-technical mailing list or by
+joining the #samba-technical IRC channel on irc.freenode.net.
+
+If you do report problems then please try to send high quality
+feedback. If you don't provide vital information to help us track down
+the problem then you will probably be ignored.
+
+A new bugzilla installation has been established to help support the
+Samba 3.0 community of users. This server, located at
+https://bugzilla.samba.org/, has replaced the older jitterbug server
+previously located at http://bugs.samba.org/.
diff --git a/docs/README-NOW b/docs/README-NOW
deleted file mode 100644
index cb9a4a68d50..00000000000
--- a/docs/README-NOW
+++ /dev/null
@@ -1,9 +0,0 @@
- ATTENTION
- DOCS TREE REMOVED
----------------------------------------------------
-
-This docs tree has been moved to a separate SVN
-module on svn.samba.org named 'samba-docs'.
-See http://svn.samba.org/samba/subversion.html
-for details on accessing Samba svn trees.
-
diff --git a/examples/libsmbclient/smbwrapper/bsd-strlcat.c b/examples/libsmbclient/smbwrapper/bsd-strlcat.c
deleted file mode 100644
index d82ced3e8a3..00000000000
--- a/examples/libsmbclient/smbwrapper/bsd-strlcat.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* $OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $ */
-
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * This version has been modified for inclusion in Samba.
- * It has been converted to ANSI C from old-style K&R C.
- */
-
-#include <sys/types.h>
-#include <string.h>
-
-/*
- * Appends src to string dst of size siz (unlike strncat, siz is the
- * full size of dst, not space left). At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
- * Returns strlen(src) + MIN(siz, strlen(initial dst)).
- * If retval >= siz, truncation occurred.
- */
-size_t
-smbw_strlcat(char *dst, const char *src, size_t siz)
-{
- char *d = dst;
- const char *s = src;
- size_t n = siz;
- size_t dlen;
-
- /* Find the end of dst and adjust bytes left but don't go past end */
- while (n-- != 0 && *d != '\0')
- d++;
- dlen = d - dst;
- n = siz - dlen;
-
- if (n == 0)
- return(dlen + strlen(s));
- while (*s != '\0') {
- if (n != 1) {
- *d++ = *s;
- n--;
- }
- s++;
- }
- *d = '\0';
-
- return(dlen + (s - src)); /* count does not include NUL */
-}
diff --git a/examples/libsmbclient/smbwrapper/bsd-strlcpy.c b/examples/libsmbclient/smbwrapper/bsd-strlcpy.c
deleted file mode 100644
index 9f7e55da8e0..00000000000
--- a/examples/libsmbclient/smbwrapper/bsd-strlcpy.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $ */
-
-/*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * This version has been modified for inclusion in Samba.
- * It has been converted to ANSI C from old-style K&R C.
- */
-
-#include <sys/types.h>
-#include <string.h>
-
-/*
- * Copy src to string dst of size siz. At most siz-1 characters
- * will be copied. Always NUL terminates (unless siz == 0).
- * Returns strlen(src); if retval >= siz, truncation occurred.
- */
-size_t
-smbw_strlcpy(char *dst, const char *src, size_t siz)
-{
- char *d = dst;
- const char *s = src;
- size_t n = siz;
-
- /* Copy as many bytes as will fit */
- if (n != 0 && --n != 0) {
- do {
- if ((*d++ = *s++) == 0)
- break;
- } while (--n != 0);
- }
-
- /* Not enough room in dst, add NUL and traverse rest of src */
- if (n == 0) {
- if (siz != 0)
- *d = '\0'; /* NUL-terminate dst */
- while (*s++)
- ;
- }
-
- return(s - src - 1); /* count does not include NUL */
-}
diff --git a/examples/libsmbclient/smbwrapper/bsd-strlfunc.h b/examples/libsmbclient/smbwrapper/bsd-strlfunc.h
deleted file mode 100644
index fb3a045ac6c..00000000000
--- a/examples/libsmbclient/smbwrapper/bsd-strlfunc.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __BSD_STRLFUNC_H__
-
-extern size_t strlcpy(char *dst, const char *src, size_t siz);
-extern size_t strlcat(char *dst, const char *src, size_t siz);
-
-#define __BSD_STRLFUNC_H__
-#endif
diff --git a/examples/libsmbclient/teststat2.c b/examples/libsmbclient/teststat2.c
deleted file mode 100644
index d1cdf285014..00000000000
--- a/examples/libsmbclient/teststat2.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include <libsmbclient.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <stdio.h>
-#include <time.h>
-#include "get_auth_data_fn.h"
-
-/*
- * This test is intended to ensure that the timestamps returned by
- * libsmbclient are the same as timestamps returned by the local system. To
- * test this, we assume a working Samba environment, and and access the same
- * file via SMB and locally (or NFS).
- *
- */
-
-
-static int gettime(const char * pUrl,
- const char * pLocalPath);
-
-
-int main(int argc, char* argv[])
-{
- if(argc != 3)
- {
- printf("usage: %s <file_url> <file_localpath>\n", argv[0]);
- return 1;
- }
-
- gettime(argv[1], argv[2]);
- return 0;
-}
-
-
-static int gettime(const char * pUrl,
- const char * pLocalPath)
-{
- //char *pSmbPath = 0;
- struct stat st;
- char mtime[32];
- char ctime[32];
- char atime[32];
-
- smbc_init(get_auth_data_fn, 0);
-
- if (smbc_stat(pUrl, &st) < 0)
- {
- perror("smbc_stat");
- return 1;
- }
-
- printf("SAMBA\n mtime:%lu/%s ctime:%lu/%s atime:%lu/%s\n",
- st.st_mtime, ctime_r(&st.st_mtime, mtime),
- st.st_ctime, ctime_r(&st.st_ctime, ctime),
- st.st_atime, ctime_r(&st.st_atime, atime));
-
-
- // check the stat on this file
- if (stat(pLocalPath, &st) < 0)
- {
- perror("stat");
- return 1;
- }
-
- printf("LOCAL\n mtime:%lu/%s ctime:%lu/%s atime:%lu/%s\n",
- st.st_mtime, ctime_r(&st.st_mtime, mtime),
- st.st_ctime, ctime_r(&st.st_ctime, ctime),
- st.st_atime, ctime_r(&st.st_atime, atime));
-
-
- return 0;
-}
-
diff --git a/make-tarball.sh b/make-tarball.sh
deleted file mode 100644
index f3250d5c732..00000000000
--- a/make-tarball.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/sh
-
-## A simple script to build a tarball of the current CVS tree.
-## You either need to include the using_samba cvs module in the
-## parent directory or tell the script where to find it
-##
-## Usgae: ./make-tarball.sh
-
-DOCSDIR=../samba-docs/
-USING_SAMBA=../using_samba/
-SRCDIR=`pwd`
-
-if [ ! -d $USING_SAMBA ]; then
-
- echo Cannot find "Using Samba" directory \(assuming $USING_SAMBA\).
- echo Please set the USING_SAMBA variable in this script to the correct
- echo location. The html files are available in the using_samba CVS
- echo module on cvs.samba.org. See http://cvs/samba.org/ for details
- echo about anonymous CVS access. Exiting now....
-
- exit 1
-
-fi
-
-if [ ! -d $DOCSDIR ]; then
-
- echo Cannot find samba-docs \(assuming $DOCSDIR\).
- echo Please set the DOCSDIR variable in this script
- echo to the correct path.
-
- exit 1
-
-fi
-
-
-VERSION=`grep SAMBA_VERSION_OFFICIAL_STRING source/include/version.h | cut -d\" -f2 | sed 's/ /_/g'`
-TARBALLDIR=/tmp/samba-$VERSION
-
-echo Creating the tarball source directory in $TARBALLDIR
-
-/bin/rm -rf $TARBALLDIR
-/bin/rm -f samba-$VERSION.tar
-
-mkdir $TARBALLDIR
-rsync -aC ./ $TARBALLDIR
-/bin/rm -rf $TARBALLDIR/docs/*
-rsync -aC $DOCSDIR/ $TARBALLDIR/docs/
-rsync -aC $USING_SAMBA $TARBALLDIR/docs/htmldocs/
-
-echo Creating packaging scripts...
-( cd $TARBALLDIR/packaging; sh bin/update-pkginfo $VERSION 1 )
-
-echo Creating source/configure...
-( cd $TARBALLDIR/source; ./autogen.sh )
-
-echo Making tarball samba-$VERSION.tar in current directory...
-( cd `dirname $TARBALLDIR`; tar cf $SRCDIR/samba-$VERSION.tar samba-$VERSION )
diff --git a/source/.indent.pro b/source/.indent.pro
deleted file mode 100644
index 05445f44924..00000000000
--- a/source/.indent.pro
+++ /dev/null
@@ -1,30 +0,0 @@
--bad
--bap
--bbb
--br
--ce
--ut
--ts8
--i8
--di1
--brs
--npsl
--npcs
--prs
--bbo
--hnl
--bad
--bap
--bbb
--br
--ce
--ut
--ts8
--i8
--di1
--brs
--npsl
--npcs
--prs
--bbo
--hnl
diff --git a/source/Makefile.in b/source/Makefile.in
index 15d22d8fa59..4cc662a18e2 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -104,9 +104,9 @@ LIBMSRPC_MINOR=1
LIBSMBSHAREMODES=bin/libsmbsharemodes.a @LIBSMBSHAREMODES_SHARED@
LIBSMBSHAREMODES_MAJOR=0
-LIBSMBSHAREMODES_MINOR=2
+LIBSMBSHAREMODES_MINOR=1
-FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/tdb @SMBWRAP_INC@ -I. $(CPPFLAGS) -I$(srcdir) -D_SAMBA_BUILD_
+FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/tdb @SMBWRAP_INC@ -I. $(CPPFLAGS) -I$(srcdir) -D_SAMBA_BUILD_
FLAGS2 =
FLAGS3 =
FLAGS4 =
@@ -219,6 +219,9 @@ READLINE_OBJ = lib/readline.o
# Be sure to include them into your application
POPT_LIB_OBJ = lib/popt_common.o
+UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \
+ ubiqx/ubi_dLinkList.o ubiqx/ubi_sLinkList.o
+
PARAM_OBJ = dynconfig.o param/loadparm.o param/params.o
KRBCLIENT_OBJ = libads/kerberos.o libads/ads_status.o
@@ -323,7 +326,7 @@ LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
PASSDB_GET_SET_OBJ = passdb/pdb_get_set.o
PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
- passdb/util_wellknown.o passdb/util_builtin.o passdb/pdb_compat.o \
+ passdb/util_sam_sid.o passdb/pdb_compat.o \
passdb/lookup_sid.o \
passdb/login_cache.o @PDB_STATIC@ passdb/pdb_sql.o \
lib/system_smbd.o lib/account_pol.o lib/privileges.o
@@ -347,7 +350,7 @@ PROFILES_OBJ = utils/profiles.o \
OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o
-NOTIFY_OBJ = smbd/notify.o smbd/notify_hash.o smbd/notify_kernel.o smbd/notify_fam.o
+NOTIFY_OBJ = smbd/notify.o smbd/notify_hash.o smbd/notify_kernel.o
VFS_AUDIT_OBJ = modules/vfs_audit.o
VFS_EXTD_AUDIT_OBJ = modules/vfs_extd_audit.o
@@ -438,13 +441,13 @@ NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
nmbd/nmbd_subnetdb.o nmbd/nmbd_winsproxy.o nmbd/nmbd_winsserver.o \
nmbd/nmbd_workgroupdb.o nmbd/nmbd_synclists.o
-NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \
+NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(UBIQX_OBJ) \
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
WREPL_OBJ1 = wrepld/server.o wrepld/process.o wrepld/parser.o wrepld/socket.o \
wrepld/partners.o
-WREPL_OBJ = $(WREPL_OBJ1) $(PARAM_OBJ) \
+WREPL_OBJ = $(WREPL_OBJ1) $(PARAM_OBJ) $(UBIQX_OBJ) \
$(PROFILE_OBJ) $(LIB_NONSMBD_OBJ) $(POPT_LIB_OBJ) $(SECRETS_OBJ) \
$(LIBSAMBA_OBJ)
@@ -540,7 +543,7 @@ LIBSMBSHAREMODES_OBJ = libsmb/smb_share_modes.o tdb/tdb.o tdb/spinlock.o
LIBBIGBALLOFMUD_MAJOR = 0
-LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ) \
+LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(UBIQX_OBJ) $(SECRETS_OBJ) \
$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \
$(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ)
@@ -641,7 +644,7 @@ RPCTORTURE_OBJ = torture/rpctorture.o \
$(PARAM_OBJ) $(LIBSMB_OBJ) $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \
$(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ)
-DEBUG2HTML_OBJ = utils/debug2html.o utils/debugparse.o
+DEBUG2HTML_OBJ = utils/debug2html.o ubiqx/debugparse.o
SMBFILTER_OBJ = utils/smbfilter.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(SECRETS_OBJ) \
$(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ)
@@ -815,7 +818,7 @@ MAKEDIR = || exec false; \
# of gcc-3.4 and run 'make pch' before you do the main build.
pch:
rm -f $(srcdir)/include/includes.h.gch
- $(CC) -I. -I$(srcdir) $(FLAGS) @PIE_CFLAGS@ -c $(srcdir)/include/includes.h -o $(srcdir)/include/includes.h.gch
+ $(CC) -I. -I$(srcdir) $(FLAGS) -c $(srcdir)/include/includes.h -o $(srcdir)/include/includes.h.gch
##
## Targets for 'make test'
@@ -877,7 +880,7 @@ bin/smbd@EXEEXT@: $(SMBD_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \
$(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \
- $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) @POPTLIBS@ @SMBD_LIBS@
+ $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) @POPTLIBS@
bin/nmbd@EXEEXT@: $(NMBD_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -1008,7 +1011,7 @@ bin/nsstest@EXEEXT@: $(NSSTEST_OBJ) bin/.dummy
bin/vfstest@EXEEXT@: $(VFSTEST_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) $(ACL_LIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) @SMBD_LIBS@
+ @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) $(ACL_LIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
bin/smbiconv@EXEEXT@: $(SMBICONV_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -1239,12 +1242,12 @@ bin/smbpasswd.@SHLIBEXT@: passdb/pdb_smbpasswd.@PICSUFFIX@
@$(SHLD) $(LDSHFLAGS) -o $@ passdb/pdb_smbpasswd.@PICSUFFIX@ \
@SONAMEFLAG@`basename $@`
-bin/rid.@SHLIBEXT@: sam/idmap_rid.@PICSUFFIX@
+bin/idmap_rid.@SHLIBEXT@: sam/idmap_rid.@PICSUFFIX@
@echo "Building plugin $@"
@$(SHLD) $(LDSHFLAGS) -o $@ sam/idmap_rid.@PICSUFFIX@ \
@SONAMEFLAG@`basename $@`
-bin/ad.@SHLIBEXT@: sam/idmap_ad.@PICSUFFIX@
+bin/idmap_ad.@SHLIBEXT@: sam/idmap_ad.@PICSUFFIX@
@echo "Building plugin $@"
@$(SHLD) $(LDSHFLAGS) -o $@ sam/idmap_ad.@PICSUFFIX@ \
@SONAMEFLAG@`basename $@`
diff --git a/source/VERSION b/source/VERSION
index 5119a954012..36aca8bb1f3 100644
--- a/source/VERSION
+++ b/source/VERSION
@@ -25,7 +25,7 @@
########################################################
SAMBA_VERSION_MAJOR=3
SAMBA_VERSION_MINOR=0
-SAMBA_VERSION_RELEASE=22
+SAMBA_VERSION_RELEASE=21
########################################################
# If a official release has a serious bug #
@@ -37,7 +37,7 @@ SAMBA_VERSION_RELEASE=22
# e.g. SAMBA_VERSION_REVISION=a #
# -> "2.2.8a" #
########################################################
-SAMBA_VERSION_REVISION=
+SAMBA_VERSION_REVISION=b
########################################################
# For 'pre' releases the version will be #
@@ -47,7 +47,7 @@ SAMBA_VERSION_REVISION=
# e.g. SAMBA_VERSION_PRE_RELEASE=1 #
# -> "2.2.9pre1" #
########################################################
-SAMBA_VERSION_PRE_RELEASE=1
+SAMBA_VERSION_PRE_RELEASE=
########################################################
# For 'rc' releases the version will be #
@@ -69,7 +69,7 @@ SAMBA_VERSION_RC_RELEASE=
# e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes #
# -> "3.0.0-SVN-build-199" #
########################################################
-SAMBA_VERSION_IS_SVN_SNAPSHOT=yes
+SAMBA_VERSION_IS_SVN_SNAPSHOT=
########################################################
# This can be set by vendors if they want... #
diff --git a/source/aclocal.m4 b/source/aclocal.m4
index 86c43f80dc0..af93aa23685 100644
--- a/source/aclocal.m4
+++ b/source/aclocal.m4
@@ -56,7 +56,7 @@ AC_DEFUN(SMB_MODULE,
[$6]
string_shared_modules="$string_shared_modules $1"
elif test x"$DEST" = xSTATIC; then
- [init_static_modules_]translit([$4], [A-Z], [a-z])="$[init_static_modules_]translit([$4], [A-Z], [a-z]) $1_init();"
+ [init_static_modules_]translit([$4], [A-Z], [a-z])="$[init_static_modules_]translit([$4], [A-Z], [a-z]) $1_init();"
string_static_modules="$string_static_modules $1"
$4_STATIC="$$4_STATIC $2"
AC_SUBST($4_STATIC)
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
index eb15fff7c8d..483686a9dee 100644
--- a/source/auth/auth_util.c
+++ b/source/auth/auth_util.c
@@ -591,36 +591,33 @@ static NTSTATUS create_nt_user_token(const DOM_SID *user_sid, const DOM_SID *gro
(strlen(lp_log_nt_token_command()) > 0)) {
TALLOC_CTX *mem_ctx;
char *command;
- char *group_sidstr;
+ fstring sidstr;
+ char *user_sidstr, *group_sidstr;
mem_ctx = talloc_init("setnttoken");
if (mem_ctx == NULL)
return NT_STATUS_NO_MEMORY;
+ sid_to_string(sidstr, &ptoken->user_sids[0]);
+ user_sidstr = talloc_strdup(mem_ctx, sidstr);
+
group_sidstr = talloc_strdup(mem_ctx, "");
for (i=1; i<ptoken->num_sids; i++) {
- group_sidstr = talloc_asprintf(
- mem_ctx, "%s %s", group_sidstr,
- sid_string_static(&ptoken->user_sids[i]));
- }
-
- command = talloc_string_sub(
- mem_ctx, lp_log_nt_token_command(),
- "%s", sid_string_static(&ptoken->user_sids[0]));
- command = talloc_string_sub(
- mem_ctx, command, "%t", group_sidstr);
-
- if (command == NULL) {
- talloc_destroy(mem_ctx);
- return NT_STATUS_NO_MEMORY;
+ sid_to_string(sidstr, &ptoken->user_sids[i]);
+ group_sidstr = talloc_asprintf(mem_ctx, "%s %s",
+ group_sidstr, sidstr);
}
+ command = SMB_STRDUP(lp_log_nt_token_command());
+ command = realloc_string_sub(command, "%s", user_sidstr);
+ command = realloc_string_sub(command, "%t", group_sidstr);
DEBUG(8, ("running command: [%s]\n", command));
if (smbrun(command, NULL) != 0) {
DEBUG(0, ("Could not log NT token\n"));
nt_status = NT_STATUS_ACCESS_DENIED;
}
talloc_destroy(mem_ctx);
+ SAFE_FREE(command);
}
*token = ptoken;
@@ -1603,7 +1600,7 @@ NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
Check for a SID in an NT_USER_TOKEN
****************************************************************************/
-static BOOL nt_token_check_sid ( DOM_SID *sid, NT_USER_TOKEN *token )
+BOOL nt_token_check_sid ( DOM_SID *sid, NT_USER_TOKEN *token )
{
int i;
@@ -1651,6 +1648,8 @@ BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid )
BOOL is_trusted_domain(const char* dom_name)
{
DOM_SID trustdom_sid;
+ char *pass = NULL;
+ time_t lct;
BOOL ret;
/* no trusted domains for a standalone server */
@@ -1664,8 +1663,9 @@ BOOL is_trusted_domain(const char* dom_name)
become_root();
DEBUG (5,("is_trusted_domain: Checking for domain trust with [%s]\n",
dom_name ));
- ret = secrets_fetch_trusted_domain_password(dom_name, NULL, NULL, NULL);
+ ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
unbecome_root();
+ SAFE_FREE(pass);
if (ret)
return True;
}
diff --git a/source/auth/pass_check.c b/source/auth/pass_check.c
index 507e8a3836e..0425e01cdcb 100644
--- a/source/auth/pass_check.c
+++ b/source/auth/pass_check.c
@@ -452,9 +452,9 @@ static NTSTATUS string_combinations2(char *s, int offset, NTSTATUS (*fn) (const
for (i = offset; i < (len - (N - 1)); i++) {
char c = s[i];
- if (!islower_ascii(c))
+ if (!islower(c))
continue;
- s[i] = toupper_ascii(c);
+ s[i] = toupper(c);
if (!NT_STATUS_EQUAL(nt_status = string_combinations2(s, i + 1, fn, N - 1),NT_STATUS_WRONG_PASSWORD)) {
return (nt_status);
}
diff --git a/source/client/client.c b/source/client/client.c
index 7ac64970f81..f95bbea6718 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -3326,7 +3326,6 @@ static int do_message_op(void)
POPT_TABLEEND
};
- load_case_tables();
#ifdef KANJI
pstrcpy(term_code, KANJI);
diff --git a/source/client/clitar.c b/source/client/clitar.c
index c15d24d619a..5afe154cbbe 100644
--- a/source/client/clitar.c
+++ b/source/client/clitar.c
@@ -482,7 +482,7 @@ static int strslashcmp(char *s1, char *s2)
{
char *s1_0=s1;
- while(*s1 && *s2 && (*s1 == *s2 || tolower_ascii(*s1) == tolower_ascii(*s2) ||
+ while(*s1 && *s2 && (*s1 == *s2 || tolower(*s1) == tolower(*s2) ||
(*s1 == '\\' && *s2=='/') || (*s1 == '/' && *s2=='\\'))) {
s1++; s2++;
}
diff --git a/source/configure.in b/source/configure.in
index 44517ae6eab..ec1bdacad84 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -795,7 +795,7 @@ AC_CHECK_HEADERS(shadow.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h)
AC_CHECK_HEADERS(nss.h nss_common.h nsswitch.h ns_api.h sys/security.h security/pam_appl.h)
AC_CHECK_HEADERS(stropts.h poll.h)
AC_CHECK_HEADERS(sys/capability.h syscall.h sys/syscall.h)
-AC_CHECK_HEADERS(sys/acl.h sys/attributes.h attr/xattr.h sys/xattr.h sys/extattr.h sys/uio.h sys/proplist.h)
+AC_CHECK_HEADERS(sys/acl.h sys/attributes.h attr/xattr.h sys/xattr.h sys/extattr.h sys/uio.h)
AC_CHECK_HEADERS(sys/cdefs.h glob.h)
AC_CHECK_HEADERS(netinet/ip.h,,,[[
@@ -1345,23 +1345,12 @@ AC_LIBTESTFUNC(sec, getprpwnam)
############################################
# Check if we have libattr
-case "$host_os" in
- *osf*)
- AC_SEARCH_LIBS(getproplist, [proplist])
- AC_CHECK_FUNCS(getproplist fgetproplist setproplist fsetproplist)
- AC_CHECK_FUNCS(delproplist fdelproplist add_proplist_entry get_proplist_entry)
- AC_CHECK_FUNCS(sizeof_proplist_entry)
- ;;
- *)
- AC_SEARCH_LIBS(getxattr, [attr])
- AC_CHECK_FUNCS(getxattr lgetxattr fgetxattr listxattr llistxattr)
- AC_CHECK_FUNCS(flistxattr removexattr lremovexattr fremovexattr)
- AC_CHECK_FUNCS(setxattr lsetxattr fsetxattr)
- AC_CHECK_FUNCS(attr_get attr_list attr_set attr_remove)
- AC_CHECK_FUNCS(attr_getf attr_listf attr_setf attr_removef)
- ;;
-esac
-
+AC_SEARCH_LIBS(getxattr, [attr])
+AC_CHECK_FUNCS(getxattr lgetxattr fgetxattr listxattr llistxattr)
+AC_CHECK_FUNCS(flistxattr removexattr lremovexattr fremovexattr)
+AC_CHECK_FUNCS(setxattr lsetxattr fsetxattr)
+AC_CHECK_FUNCS(attr_get attr_list attr_set attr_remove)
+AC_CHECK_FUNCS(attr_getf attr_listf attr_setf attr_removef)
# Check if we have extattr
case "$host_os" in
*freebsd4* | *dragonfly* )
@@ -1471,7 +1460,7 @@ if test "$enable_shared" = "yes"; then
*aix*) AC_DEFINE(AIX,1,[Whether the host os is aix])
BLDSHARED="true"
LDSHFLAGS="-Wl,-bexpall,-bM:SRE,-bnoentry,-berok"
- DYNEXP="-Wl,-brtl,-bexpall,-bbigtoc"
+ DYNEXP="-Wl,-brtl,-bexpall"
PICFLAGS="-O2"
if test "${GCC}" != "yes"; then
## for funky AIX compiler using strncpy()
@@ -1639,11 +1628,7 @@ if test x"$samba_cv_HAVE_OFF64_T" = x"yes"; then
fi
AC_CACHE_CHECK([for 64 bit ino_t],samba_cv_SIZEOF_INO_T,[
-AC_TRY_RUN([
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-#include <stdio.h>
+AC_TRY_RUN([#include <stdio.h>
#include <sys/stat.h>
main() { exit((sizeof(ino_t) == 8) ? 0 : 1); }],
samba_cv_SIZEOF_INO_T=yes,samba_cv_SIZEOF_INO_T=no,samba_cv_SIZEOF_INO_T=cross)])
@@ -1664,19 +1649,6 @@ if test x"$samba_cv_HAVE_INO64_T" = x"yes"; then
AC_DEFINE(HAVE_INO64_T,1,[Whether the 'ino64_t' type is available])
fi
-AC_CACHE_CHECK([for 64 bit dev_t],samba_cv_SIZEOF_DEV_T,[
-AC_TRY_RUN([
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-#include <stdio.h>
-#include <sys/stat.h>
-main() { exit((sizeof(dev_t) == 8) ? 0 : 1); }],
-samba_cv_SIZEOF_DEV_T=yes,samba_cv_SIZEOF_DEV_T=no,samba_cv_SIZEOF_DEV_T=cross)])
-if test x"$samba_cv_SIZEOF_DEV_T" = x"yes"; then
- AC_DEFINE(SIZEOF_DEV_T,8,[The size of the 'dev_t' type])
-fi
-
AC_CACHE_CHECK([for dev64_t],samba_cv_HAVE_DEV64_T,[
AC_TRY_RUN([
#if defined(HAVE_UNISTD_H)
@@ -2174,33 +2146,6 @@ if test x"$samba_cv_HAVE_KERNEL_CHANGE_NOTIFY" = x"yes"; then
AC_DEFINE(HAVE_KERNEL_CHANGE_NOTIFY,1,[Whether kernel notifies changes])
fi
-#################################################
-# Check if FAM notifications are available. For FAM info, see
-# http://oss.sgi.com/projects/fam/
-# http://savannah.nongnu.org/projects/fam/
-
-AC_CHECK_HEADERS(fam.h, [samba_cv_HAVE_FAM_H=yes], [samba_cv_HAVE_FAM_H=no])
-if test x"$samba_cv_HAVE_FAM_H" = x"yes"; then
- # On IRIX, libfam requires libC, but other FAM implementations might not
- # need it.
- AC_CHECK_LIB(fam, FAMOpen2,
- [samba_cv_HAVE_LIBFAM=yes; samba_fam_libs="-lfam"],
- [samba_cv_HAVE_LIBFAM=no])
-
- if test x"$samba_cv_HAVE_LIBFAM" = x"no" ; then
- samba_fam_xtra=-lC
- AC_CHECK_LIB_EXT(fam, samba_fam_xtra, FAMOpen2,
- [samba_cv_HAVE_LIBFAM=yes; samba_fam_libs="-lfam -lC"],
- [samba_cv_HAVE_LIBFAM=no])
- unset samba_fam_xtra
- fi
-fi
-
-if test x"$samba_cv_HAVE_LIBFAM" = x"yes" ; then
- AC_DEFINE(HAVE_FAM_CHANGE_NOTIFY, 1,
- [Whether FAM is file notifications are available])
-fi
-
AC_CACHE_CHECK([for kernel share modes],samba_cv_HAVE_KERNEL_SHARE_MODES,[
AC_TRY_RUN([
#include <sys/types.h>
@@ -2221,6 +2166,8 @@ if test x"$samba_cv_HAVE_KERNEL_SHARE_MODES" = x"yes"; then
fi
+
+
AC_CACHE_CHECK([for IRIX kernel oplock type definitions],samba_cv_HAVE_KERNEL_OPLOCKS_IRIX,[
AC_TRY_COMPILE([#include <sys/types.h>
#include <fcntl.h>],
@@ -4530,11 +4477,10 @@ AC_ARG_WITH(aio-support,
AC_MSG_RESULT(yes)
case "$host_os" in
*)
- AC_CHECK_LIB(rt,aio_read,[AIO_LIBS="$AIO_LIBS -lrt"])
- AC_CHECK_LIB(aio,aio_read,[AIO_LIBS="$AIO_LIBS -laio"])
+ AC_CHECK_LIB(rt,aio_read,[AIO_LIBS="$ACL_LIBS -lrt"])
AC_CACHE_CHECK([for asynchronous io support],samba_cv_HAVE_AIO,[
aio_LIBS=$LIBS
- LIBS=$AIO_LIBS
+ LIBS="$LIBS -lrt"
AC_TRY_LINK([#include <sys/types.h>
#include <aio.h>],
[ struct aiocb a; return aio_read(&a);],
@@ -4542,7 +4488,7 @@ samba_cv_HAVE_AIO=yes,samba_cv_HAVE_AIO=no)
LIBS=$aio_LIBS])
AC_CACHE_CHECK([for 64-bit asynchronous io support],samba_cv_HAVE_AIO64,[
aio_LIBS=$LIBS
- LIBS=$AIO_LIBS
+ LIBS="$LIBS -lrt"
AC_TRY_LINK([#include <sys/types.h>
#include <aio.h>],
[ struct aiocb64 a; return aio_read64(&a);],
@@ -4551,10 +4497,10 @@ samba_cv_HAVE_AIO64=yes,samba_cv_HAVE_AIO64=no)
if test x"$samba_cv_HAVE_AIO64" = x"yes"; then
AC_DEFINE(HAVE_AIOCB64,1,[Whether 64 bit aio is available])
AC_DEFINE(WITH_AIO, 1, [Using asynchronous io])
- LIBS=$AIO_LIBS
+ LIBS="$LIBS -lrt"
elif test x"$samba_cv_HAVE_AIO" = x"yes"; then
AC_DEFINE(WITH_AIO, 1, [Using asynchronous io])
- LIBS=$AIO_LIBS
+ LIBS="$LIBS -lrt"
fi
if test x"$samba_cv_HAVE_AIO" = x"yes"; then
@@ -5185,10 +5131,10 @@ SMB_MODULE(rpc_samr, \$(RPC_SAMR_OBJ), "bin/librpc_samr.$SHLIBEXT", RPC)
SMB_MODULE(rpc_echo, \$(RPC_ECHO_OBJ), "bin/librpc_echo.$SHLIBEXT", RPC)
SMB_SUBSYSTEM(RPC,smbd/server.o)
-SMB_MODULE(idmap_ldap, sam/idmap_ldap.o, "bin/ldap.$SHLIBEXT", IDMAP)
-SMB_MODULE(idmap_tdb, sam/idmap_tdb.o, "bin/tdb.$SHLIBEXT", IDMAP)
-SMB_MODULE(idmap_rid, sam/idmap_rid.o, "bin/rid.$SHLIBEXT", IDMAP)
-SMB_MODULE(idmap_ad, sam/idmap_ad.o, "bin/ad.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_ldap, sam/idmap_ldap.o, "bin/idmap_ldap.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_tdb, sam/idmap_tdb.o, "bin/idmap_tdb.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_rid, sam/idmap_rid.o, "bin/idmap_rid.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_ad, sam/idmap_ad.o, "bin/idmap_ad.$SHLIBEXT", IDMAP)
SMB_SUBSYSTEM(IDMAP,sam/idmap.o)
SMB_MODULE(charset_weird, modules/weird.o, "bin/weird.$SHLIBEXT", CHARSET)
@@ -5219,7 +5165,7 @@ SMB_MODULE(vfs_cap, \$(VFS_CAP_OBJ), "bin/cap.$SHLIBEXT", VFS)
SMB_MODULE(vfs_expand_msdfs, \$(VFS_EXPAND_MSDFS_OBJ), "bin/expand_msdfs.$SHLIBEXT", VFS)
SMB_MODULE(vfs_shadow_copy, \$(VFS_SHADOW_COPY_OBJ), "bin/shadow_copy.$SHLIBEXT", VFS)
SMB_MODULE(vfs_afsacl, \$(VFS_AFSACL_OBJ), "bin/afsacl.$SHLIBEXT", VFS)
-SMB_MODULE(vfs_catia, \$(VFS_CATIA_OBJ), "bin/catia.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_catia, \$(VFS_AFSACL_OBJ), "bin/catia.$SHLIBEXT", VFS)
SMB_SUBSYSTEM(VFS,smbd/vfs.o)
AC_DEFINE_UNQUOTED(STRING_STATIC_MODULES, "$string_static_modules", [String list of builtin modules])
@@ -5256,10 +5202,6 @@ AC_TRY_RUN([#include "${srcdir-.}/tests/summary.c"],
builddir=`pwd`
AC_SUBST(builddir)
-# Stuff the FAM libraries at the end of the smbd link path (if we have them).
-SMBD_LIBS="$samba_fam_libs"
-AC_SUBST(SMBD_LIBS)
-
dnl Remove -L/usr/lib/? from LDFLAGS and LIBS
LIB_REMOVE_USR_LIB(LDFLAGS)
LIB_REMOVE_USR_LIB(LIBS)
diff --git a/source/groupdb/mapping.c b/source/groupdb/mapping.c
index 7dc0426c449..1e8586786cd 100644
--- a/source/groupdb/mapping.c
+++ b/source/groupdb/mapping.c
@@ -36,6 +36,45 @@ static TDB_CONTEXT *tdb; /* used for driver files */
#define MEMBEROF_PREFIX "MEMBEROF/"
/****************************************************************************
+dump the mapping group mapping to a text file
+****************************************************************************/
+char *decode_sid_name_use(fstring group, enum SID_NAME_USE name_use)
+{
+ static fstring group_type;
+
+ switch(name_use) {
+ case SID_NAME_USER:
+ fstrcpy(group_type,"User");
+ break;
+ case SID_NAME_DOM_GRP:
+ fstrcpy(group_type,"Domain group");
+ break;
+ case SID_NAME_DOMAIN:
+ fstrcpy(group_type,"Domain");
+ break;
+ case SID_NAME_ALIAS:
+ fstrcpy(group_type,"Local group");
+ break;
+ case SID_NAME_WKN_GRP:
+ fstrcpy(group_type,"Builtin group");
+ break;
+ case SID_NAME_DELETED:
+ fstrcpy(group_type,"Deleted");
+ break;
+ case SID_NAME_INVALID:
+ fstrcpy(group_type,"Invalid");
+ break;
+ case SID_NAME_UNKNOWN:
+ default:
+ fstrcpy(group_type,"Unknown type");
+ break;
+ }
+
+ fstrcpy(group, group_type);
+ return group_type;
+}
+
+/****************************************************************************
initialise first time the mapping list - called from init_group_mapping()
****************************************************************************/
static BOOL default_group_mapping(void)
@@ -366,6 +405,7 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **pp_rm
{
TDB_DATA kbuf, dbuf, newkey;
fstring string_sid;
+ fstring group_type;
GROUP_MAP map;
GROUP_MAP *mapt;
int ret;
@@ -415,9 +455,8 @@ static BOOL enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **pp_rm
string_to_sid(&map.sid, string_sid);
- DEBUG(11,("enum_group_mapping: returning group %s of "
- "type %s\n", map.nt_name,
- sid_type_lookup(map.sid_name_use)));
+ decode_sid_name_use(group_type, map.sid_name_use);
+ DEBUG(11,("enum_group_mapping: returning group %s of type %s\n", map.nt_name ,group_type));
mapt= SMB_REALLOC_ARRAY((*pp_rmap), GROUP_MAP, entries+1);
if (!mapt) {
@@ -887,6 +926,34 @@ BOOL get_builtin_group_from_sid(DOM_SID *sid, GROUP_MAP *map)
return True;
}
+
+
+/****************************************************************************
+Returns a GROUP_MAP struct based on the gid.
+****************************************************************************/
+BOOL get_group_from_gid(gid_t gid, GROUP_MAP *map)
+{
+ BOOL ret;
+
+ if(!init_group_mapping()) {
+ DEBUG(0,("failed to initialize group mapping\n"));
+ return(False);
+ }
+
+ if ( getgrgid(gid) == NULL)
+ return False;
+
+ become_root();
+ ret = pdb_getgrgid(map, gid);
+ unbecome_root();
+
+ if ( !ret ) {
+ return False;
+ }
+
+ return True;
+}
+
/****************************************************************************
Create a UNIX group on demand.
****************************************************************************/
@@ -1099,22 +1166,11 @@ NTSTATUS pdb_default_create_alias(struct pdb_methods *methods,
enum SID_NAME_USE type;
uint32 new_rid;
gid_t gid;
- BOOL exists;
- GROUP_MAP map;
-
- TALLOC_CTX *mem_ctx = talloc_new(NULL);
- if (mem_ctx == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- exists = lookup_name(mem_ctx, name, LOOKUP_NAME_ISOLATED,
- NULL, NULL, &sid, &type);
- talloc_free(mem_ctx);
+ GROUP_MAP map;
- if (exists) {
+ if (lookup_name(get_global_sam_name(), name, &sid, &type))
return NT_STATUS_ALIAS_EXISTS;
- }
if (!winbind_allocate_rid_and_gid(&new_rid, &gid))
return NT_STATUS_ACCESS_DENIED;
diff --git a/source/include/auth.h b/source/include/auth.h
index 03206c03c6a..f3dae1108b3 100644
--- a/source/include/auth.h
+++ b/source/include/auth.h
@@ -58,7 +58,7 @@ typedef struct auth_serversupplied_info {
gid_t gid;
/* This groups info is needed for when we become_user() for this uid */
- size_t n_groups;
+ int n_groups;
gid_t *groups;
/* NT group information taken from the info3 structure */
diff --git a/source/include/debug.h b/source/include/debug.h
index b6fb50a9acb..99c96e6bb18 100644
--- a/source/include/debug.h
+++ b/source/include/debug.h
@@ -43,12 +43,6 @@ int Debug1( const char *, ... ) PRINTF_ATTRIBUTE(1,2);
BOOL dbgtext( const char *, ... ) PRINTF_ATTRIBUTE(1,2);
BOOL dbghdr( int level, const char *file, const char *func, int line );
-#if defined(sgi) && (_COMPILER_VERSION >= 730)
-#pragma mips_frequency_hint NEVER Debug1
-#pragma mips_frequency_hint NEVER dbgtext
-#pragma mips_frequency_hint NEVER dbghdr
-#endif
-
extern XFILE *dbf;
extern pstring debugf;
diff --git a/source/include/includes.h b/source/include/includes.h
index a9b792d5f67..6342925877c 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -880,6 +880,8 @@ extern int errno;
/* Lists, trees, caching, database... */
#include "xfile.h"
#include "intl.h"
+#include "ubi_sLinkList.h"
+#include "ubi_dLinkList.h"
#include "dlinklist.h"
#include "tdb/tdb.h"
#include "tdb/spinlock.h"
@@ -902,6 +904,10 @@ extern int errno;
#include "util_getent.h"
+#ifndef UBI_BINTREE_H
+#include "ubi_Cache.h"
+#endif /* UBI_BINTREE_H */
+
#include "debugparse.h"
#include "version.h"
diff --git a/source/include/libsmb_internal.h b/source/include/libsmb_internal.h
index 04264303288..081bb415e56 100644
--- a/source/include/libsmb_internal.h
+++ b/source/include/libsmb_internal.h
@@ -47,12 +47,11 @@ struct _SMBCFILE {
struct smbc_internal_data {
- /*
- * Is this handle initialized ?
+ /** INTERNAL: is this handle initialized ?
*/
- BOOL _initialized;
+ int _initialized;
- /* dirent pointer location
+ /** INTERNAL: dirent pointer location
*
* Leave room for any urlencoded filename and the comment field.
*
@@ -65,20 +64,13 @@ struct smbc_internal_data {
*/
char _dirent[1024];
- /*
- * server connection list
+ /** INTERNAL: server connection list
*/
SMBCSRV * _servers;
- /*
- * open file/dir list
+ /** INTERNAL: open file/dir list
*/
SMBCFILE * _files;
-
- /*
- * Log to standard error instead of the more typical standard output
- */
- BOOL _debug_stderr;
};
diff --git a/source/include/messages.h b/source/include/messages.h
index 4b1732d42d1..abe219374ed 100644
--- a/source/include/messages.h
+++ b/source/include/messages.h
@@ -68,7 +68,6 @@
#define MSG_SMB_ASYNC_LEVEL2_BREAK 3008
#define MSG_SMB_OPEN_RETRY 3009
#define MSG_SMB_KERNEL_BREAK 3010
-#define MSG_SMB_FILE_RENAME 3011
/* winbind messages */
#define MSG_WINBIND_FINISHED 4001
diff --git a/source/include/nameserv.h b/source/include/nameserv.h
index 9f6bf76a093..ec3d56c06b7 100644
--- a/source/include/nameserv.h
+++ b/source/include/nameserv.h
@@ -217,7 +217,7 @@ struct nmb_data {
/* This structure represents an entry in a local netbios name list. */
struct name_record {
- struct name_record *prev, *next;
+ ubi_trNode node[1];
struct subnet_record *subnet;
struct nmb_name name; /* The netbios name. */
struct nmb_data data; /* The netbios data. */
@@ -225,7 +225,7 @@ struct name_record {
/* Browser cache for synchronising browse lists. */
struct browse_cache_record {
- struct browse_cache_record *prev, *next;
+ ubi_dlNode node[1];
unstring lmb_name;
unstring work_group;
struct in_addr ip;
@@ -425,7 +425,7 @@ struct subnet_record {
enum subnet_type type; /* To catagorize the subnet. */
struct work_record *workgrouplist; /* List of workgroups. */
- struct name_record *namelist; /* List of netbios names. */
+ ubi_trRoot namelist[1]; /* List of netbios names. */
struct response_record *responselist; /* List of responses expected. */
BOOL namelist_changed;
diff --git a/source/include/passdb.h b/source/include/passdb.h
index f1896710dc9..0589b9a7cd4 100644
--- a/source/include/passdb.h
+++ b/source/include/passdb.h
@@ -200,6 +200,29 @@ typedef struct sam_passwd {
} SAM_ACCOUNT;
+typedef struct sam_group {
+ TALLOC_CTX *mem_ctx;
+
+ void (*free_fn)(struct sam_group **);
+
+ struct pdb_methods *methods;
+
+ struct group_data {
+ /* initialization flags */
+ struct bitmap *change_flags;
+ struct bitmap *set_flags;
+
+ const char *name; /* Windows group name string */
+
+ DOM_SID sid; /* Group SID */
+ enum SID_NAME_USE sid_name_use; /* Group type */
+
+ uint32 mem_num; /* Number of member SIDs */
+ DOM_SID *members; /* SID array */
+ } private_g;
+
+} SAM_GROUP;
+
struct acct_info {
fstring acct_name; /* account name */
fstring acct_desc; /* account name */
@@ -353,13 +376,6 @@ typedef struct pdb_context
const char **pp_names,
uint32 *attrs);
- NTSTATUS (*pdb_lookup_names)(struct pdb_context *context,
- const DOM_SID *domain_sid,
- size_t num_names,
- const char **names,
- uint32 *rids,
- uint32 *attrs);
-
NTSTATUS (*pdb_get_account_policy)(struct pdb_context *context,
int policy_index, uint32 *value);
@@ -483,13 +499,6 @@ typedef struct pdb_methods
const char **pp_names,
uint32 *attrs);
- NTSTATUS (*lookup_names)(struct pdb_methods *methods,
- const DOM_SID *domain_sid,
- int num_names,
- const char **pp_names,
- uint32 *rids,
- uint32 *attrs);
-
NTSTATUS (*get_account_policy)(struct pdb_methods *methods,
int policy_index, uint32 *value);
diff --git a/source/include/smb.h b/source/include/smb.h
index f899a71dc6d..b6f471c1a6f 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -172,9 +172,6 @@ typedef smb_ucs2_t wfstring[FSTRING_LEN];
/* turn a 7 bit character into a ucs2 character */
#define UCS2_CHAR(c) ((c) << UCS2_SHIFT)
-/* return an ascii version of a ucs2 character */
-#define UCS2_TO_CHAR(c) ((c) & 0xff)
-
/* Copy into a smb_ucs2_t from a possibly unaligned buffer. Return the copied smb_ucs2_t */
#define COPY_UCS2_CHAR(dest,src) (((unsigned char *)(dest))[0] = ((unsigned char *)(src))[0],\
((unsigned char *)(dest))[1] = ((unsigned char *)(src))[1], (dest))
@@ -267,10 +264,6 @@ enum SID_NAME_USE
SID_NAME_COMPUTER /* sid for a computer */
};
-#define LOOKUP_NAME_ISOLATED 1 /* Look up unqualified names */
-#define LOOKUP_NAME_REMOTE 2 /* Ask others */
-#define LOOKUP_NAME_ALL (LOOKUP_NAME_ISOLATED|LOOKUP_NAME_REMOTE)
-
/**
* @brief Security Identifier
*
@@ -333,6 +326,49 @@ typedef struct _nt_user_token {
SE_PRIV privileges;
} NT_USER_TOKEN;
+/*** query a local group, get a list of these: shows who is in that group ***/
+
+/* local group member info */
+typedef struct local_grp_member_info
+{
+ DOM_SID sid ; /* matches with name */
+ uint8 sid_use; /* usr=1 grp=2 dom=3 alias=4 wkng=5 del=6 inv=7 unk=8 */
+ fstring name ; /* matches with sid: must be of the form "DOMAIN\account" */
+
+} LOCAL_GRP_MEMBER;
+
+/* enumerate these to get list of local groups */
+
+/* local group info */
+typedef struct local_grp_info
+{
+ fstring name;
+ fstring comment;
+
+} LOCAL_GRP;
+
+/*** enumerate these to get list of domain groups ***/
+
+/* domain group member info */
+typedef struct domain_grp_info
+{
+ fstring name;
+ fstring comment;
+ uint32 rid; /* group rid */
+ uint8 attr; /* attributes forced to be set to 0x7: SE_GROUP_xxx */
+
+} DOMAIN_GRP;
+
+/*** query a domain group, get a list of these: shows who is in that group ***/
+
+/* domain group info */
+typedef struct domain_grp_member_info
+{
+ fstring name;
+ uint8 attr; /* attributes forced to be set to 0x7: SE_GROUP_xxx */
+
+} DOMAIN_GRP_MEMBER;
+
/* 32 bit time (sec) since 01jan1970 - cifs6.txt, section 3.5, page 30 */
typedef struct time_info
{
@@ -514,7 +550,7 @@ typedef struct connection_struct
/* following groups stuff added by ih */
/* This groups info is valid for the user that *opened* the connection */
- size_t ngroups;
+ int ngroups;
gid_t *groups;
NT_USER_TOKEN *nt_user_token;
@@ -619,9 +655,9 @@ struct share_mode_entry {
struct process_id pid;
uint16 op_mid;
uint16 op_type;
- uint32 access_mask; /* NTCreateX access bits (FILE_READ_DATA etc.) */
- uint32 share_access; /* NTCreateX share constants (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE). */
- uint32 private_options; /* NT Create options, but we only look at
+ uint32_t access_mask; /* NTCreateX access bits (FILE_READ_DATA etc.) */
+ uint32_t share_access; /* NTCreateX share constants (FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE). */
+ uint32_t private_options; /* NT Create options, but we only look at
* NTCREATEX_OPTIONS_PRIVATE_DENY_DOS and
* NTCREATEX_OPTIONS_PRIVATE_DENY_FCB for
* smbstatus and swat */
@@ -651,7 +687,6 @@ Offset Data length.
#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 48
struct share_mode_lock {
- const char *servicepath; /* canonicalized. */
const char *filename;
SMB_DEV_T dev;
SMB_INO_T ino;
@@ -1587,9 +1622,11 @@ struct pwd_info {
BOOL cleartext;
fstring password;
+
};
-typedef struct user_struct {
+typedef struct user_struct
+{
struct user_struct *next, *prev;
uint16 vuid; /* Tag for this entry. */
uid_t uid; /* uid of a validated user */
diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h
index 41eac7e9942..e1bed76f5be 100644
--- a/source/include/smb_macros.h
+++ b/source/include/smb_macros.h
@@ -24,6 +24,12 @@
#ifndef _SMB_MACROS_H
#define _SMB_MACROS_H
+/* no ops to help reduce the diff between the current 3.0 and release branch */
+
+#define toupper_ascii(x) toupper(x)
+#define tolower_ascii(x) tolower(x)
+
+
/* Misc bit macros */
#define BOOLSTR(b) ((b) ? "Yes" : "No")
#define BITSETW(ptr,bit) ((SVAL(ptr,0) & (1<<(bit)))!=0)
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index c4eeab135e9..4fbad0f3d18 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -84,6 +84,15 @@ static const char *charset_name(charset_t ch)
}
ret = ln;
}
+#ifdef HAVE_SETLOCALE
+ /* We set back the locale to C to get ASCII-compatible toupper/lower functions.
+ For now we do not need any other POSIX localisations anyway. When we should
+ really need localized string functions one day we need to write our own
+ ascii_tolower etc.
+ */
+ setlocale(LC_ALL, "C");
+ #endif
+
#endif
if (!ret || !*ret) ret = "ASCII";
@@ -738,7 +747,7 @@ char *strdup_upper(const char *s)
while (1) {
if (*p & 0x80)
break;
- *q++ = toupper_ascii(*p);
+ *q++ = toupper(*p);
if (!*p)
break;
p++;
@@ -772,7 +781,7 @@ size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
smb_ucs2_t *buffer = NULL;
size = convert_string_allocate(NULL, CH_UNIX, CH_UCS2, src, srclen,
- (void **)(void *)&buffer, True);
+ (void **) &buffer, True);
if (size == (size_t)-1 || !buffer) {
smb_panic("failed to create UCS2 buffer");
}
diff --git a/source/lib/replace.c b/source/lib/replace.c
index 120fd3a4688..57ee6ea11e6 100644
--- a/source/lib/replace.c
+++ b/source/lib/replace.c
@@ -390,7 +390,7 @@ char *rep_inet_ntoa(struct in_addr ip)
if (isdigit(c))
c -= '0';
else if (isalpha(c))
- c -= isupper_ascii(c) ? 'A' - 10 : 'a' - 10;
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >= base)
diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c
index 609816b8774..a3ebe72df21 100644
--- a/source/lib/smbldap.c
+++ b/source/lib/smbldap.c
@@ -664,21 +664,21 @@ int smb_ldap_upgrade_conn(LDAP *ldap_struct, int *new_version)
open a connection to the ldap server (just until the bind)
******************************************************************/
-int smb_ldap_setup_full_conn(LDAP **ldap_struct, const char *uri)
+int smb_ldap_setup_full_conn(LDAP *ldap_struct, const char *uri)
{
int rc, version;
- rc = smb_ldap_setup_conn(ldap_struct, uri);
+ rc = smb_ldap_setup_conn(&ldap_struct, uri);
if (rc) {
return rc;
}
- rc = smb_ldap_upgrade_conn(*ldap_struct, &version);
+ rc = smb_ldap_upgrade_conn(ldap_struct, &version);
if (rc) {
return rc;
}
- rc = smb_ldap_start_tls(*ldap_struct, version);
+ rc = smb_ldap_start_tls(ldap_struct, version);
if (rc) {
return rc;
}
diff --git a/source/lib/system_smbd.c b/source/lib/system_smbd.c
index 6c65f61ad7a..1afd44b7091 100644
--- a/source/lib/system_smbd.c
+++ b/source/lib/system_smbd.c
@@ -190,8 +190,8 @@ static int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grp
return retval;
}
-static BOOL getgroups_user(const char *user, gid_t primary_gid,
- gid_t **ret_groups, size_t *p_ngroups)
+BOOL getgroups_user(const char *user, gid_t primary_gid,
+ gid_t **ret_groups, size_t *p_ngroups)
{
size_t ngrp;
int max_grp;
diff --git a/source/lib/username.c b/source/lib/username.c
index 7d66b320adf..4dd5b5f7ce7 100644
--- a/source/lib/username.c
+++ b/source/lib/username.c
@@ -35,6 +35,34 @@ static BOOL name_is_local(const char *name)
return !(strchr_m(name, *lp_winbind_separator()));
}
+/*****************************************************************
+ Splits passed user or group name to domain and user/group name parts
+ Returns True if name was splitted and False otherwise.
+*****************************************************************/
+
+BOOL split_domain_and_name(const char *name, char *domain, char* username)
+{
+ char *p = strchr(name,*lp_winbind_separator());
+
+
+ /* Parse a string of the form DOMAIN/user into a domain and a user */
+ DEBUG(10,("split_domain_and_name: checking whether name |%s| local or not\n", name));
+
+ if (p) {
+ fstrcpy(username, p+1);
+ fstrcpy(domain, name);
+ domain[PTR_DIFF(p, name)] = 0;
+ } else if (lp_winbind_use_default_domain()) {
+ fstrcpy(username, name);
+ fstrcpy(domain, lp_workgroup());
+ } else {
+ return False;
+ }
+
+ DEBUG(10,("split_domain_and_name: all is fine, domain is |%s| and name is |%s|\n", domain, username));
+ return True;
+}
+
/****************************************************************************
Get a users home directory.
****************************************************************************/
@@ -669,7 +697,7 @@ BOOL user_in_list(const char *user,const char **list, gid_t *groups,
if ( winbind_lookup_name(domain, groupname,
&g_sid, &name_type)
- && ( name_type==SID_NAME_DOM_GRP ||
+ && ( name_type==SID_NAME_DOM_GRP ||
(strequal(lp_workgroup(), domain) &&
name_type==SID_NAME_ALIAS) ) )
{
@@ -716,9 +744,9 @@ static struct passwd *uname_string_combinations2(char *s,int offset,struct passw
for (i=offset;i<(len-(N-1));i++) {
char c = s[i];
- if (!islower_ascii((int)c))
+ if (!islower((int)c))
continue;
- s[i] = toupper_ascii(c);
+ s[i] = toupper(c);
ret = uname_string_combinations2(s,i+1,fn,N-1);
if(ret)
return(ret);
diff --git a/source/lib/util_getent.c b/source/lib/util_getent.c
index 7c045fccb22..475b0da87bf 100644
--- a/source/lib/util_getent.c
+++ b/source/lib/util_getent.c
@@ -239,37 +239,6 @@ static struct sys_userlist *add_members_to_userlist(struct sys_userlist *list_he
return list_head;
}
-/*****************************************************************
- Splits passed user or group name to domain and user/group name parts
- Returns True if name was splitted and False otherwise.
-*****************************************************************/
-
-static BOOL split_domain_and_name(const char *name, char *domain,
- char* username)
-{
- char *p = strchr(name,*lp_winbind_separator());
-
-
- /* Parse a string of the form DOMAIN/user into a domain and a user */
- DEBUG(10,("split_domain_and_name: checking whether name |%s| local or "
- "not\n", name));
-
- if (p) {
- fstrcpy(username, p+1);
- fstrcpy(domain, name);
- domain[PTR_DIFF(p, name)] = 0;
- } else if (lp_winbind_use_default_domain()) {
- fstrcpy(username, name);
- fstrcpy(domain, lp_workgroup());
- } else {
- return False;
- }
-
- DEBUG(10,("split_domain_and_name: all is fine, domain is |%s| and "
- "name is |%s|\n", domain, username));
- return True;
-}
-
/****************************************************************
Get the list of UNIX users in a group.
We have to enumerate the /etc/group file as some UNIX getgrnam()
diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c
index e2b2ebf28ca..4c274b5e01d 100644
--- a/source/lib/util_sid.c
+++ b/source/lib/util_sid.c
@@ -75,14 +75,11 @@ const DOM_SID global_sid_Builtin_Backup_Operators = /* Builtin backup operators
const DOM_SID global_sid_Builtin_Replicator = /* Builtin replicator */
{ 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}};
-/* Unused, left here for documentary purposes */
-#if 0
#define SECURITY_NULL_SID_AUTHORITY 0
#define SECURITY_WORLD_SID_AUTHORITY 1
#define SECURITY_LOCAL_SID_AUTHORITY 2
#define SECURITY_CREATOR_SID_AUTHORITY 3
#define SECURITY_NT_AUTHORITY 5
-#endif
/*
* An NT compatible anonymous token.
@@ -156,6 +153,59 @@ const char *get_global_sam_name(void)
return global_myname();
}
+/**************************************************************************
+ Splits a name of format \DOMAIN\name or name into its two components.
+ Sets the DOMAIN name to global_myname() if it has not been specified.
+***************************************************************************/
+
+void split_domain_name(const char *fullname, char *domain, char *name)
+{
+ pstring full_name;
+ const char *sep;
+ char *p;
+
+ sep = lp_winbind_separator();
+
+ *domain = *name = '\0';
+
+ if (fullname[0] == sep[0] || fullname[0] == '\\')
+ fullname++;
+
+ pstrcpy(full_name, fullname);
+ p = strchr_m(full_name+1, '\\');
+ if (!p) p = strchr_m(full_name+1, sep[0]);
+
+ if (p != NULL) {
+ *p = 0;
+ fstrcpy(domain, full_name);
+ fstrcpy(name, p+1);
+ } else {
+ fstrcpy(domain, get_global_sam_name());
+ fstrcpy(name, full_name);
+ }
+
+ DEBUG(10,("split_domain_name:name '%s' split into domain :'%s' and user :'%s'\n",
+ fullname, domain, name));
+}
+
+/****************************************************************************
+ Test if a SID is wellknown and resolvable.
+****************************************************************************/
+
+BOOL resolvable_wellknown_sid(DOM_SID *sid)
+{
+ uint32 ia = (sid->id_auth[5]) +
+ (sid->id_auth[4] << 8 ) +
+ (sid->id_auth[3] << 16) +
+ (sid->id_auth[2] << 24);
+
+ if (sid->sid_rev_num != SEC_DESC_REVISION || sid->num_auths < 1)
+ return False;
+
+ return (ia == SECURITY_WORLD_SID_AUTHORITY ||
+ ia == SECURITY_CREATOR_SID_AUTHORITY);
+}
+
/*****************************************************************
Convert a SID to an ascii string.
*****************************************************************/
@@ -213,7 +263,7 @@ BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
uint32 conv;
if ((sidstr[0] != 'S' && sidstr[0] != 's') || sidstr[1] != '-') {
- DEBUG(3,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
+ DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
return False;
}
@@ -223,7 +273,7 @@ BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
p = sidstr + 2;
conv = (uint32) strtoul(p, &q, 10);
if (!q || (*q != '-')) {
- DEBUG(3,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
+ DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
return False;
}
sidout->sid_rev_num = (uint8) conv;
@@ -483,6 +533,30 @@ BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
}
/*****************************************************************
+ Check if the SID is the builtin SID (S-1-5-32).
+*****************************************************************/
+
+BOOL sid_check_is_builtin(const DOM_SID *sid)
+{
+ return sid_equal(sid, &global_sid_Builtin);
+}
+
+/*****************************************************************
+ Check if the SID is one of the builtin SIDs (S-1-5-32-a).
+*****************************************************************/
+
+BOOL sid_check_is_in_builtin(const DOM_SID *sid)
+{
+ DOM_SID dom_sid;
+ uint32 rid;
+
+ sid_copy(&dom_sid, sid);
+ sid_split_rid(&dom_sid, &rid);
+
+ return sid_equal(&dom_sid, &global_sid_Builtin);
+}
+
+/*****************************************************************
Calculates size of a sid.
*****************************************************************/
@@ -619,9 +693,3 @@ void del_sid_from_array(const DOM_SID *sid, DOM_SID **sids, size_t *num)
return;
}
-
-BOOL is_null_sid(const DOM_SID *sid)
-{
- static const DOM_SID null_sid = {0};
- return sid_equal(sid, &null_sid);
-}
diff --git a/source/lib/util_smbd.c b/source/lib/util_smbd.c
new file mode 100644
index 00000000000..c6f6bc0a32a
--- /dev/null
+++ b/source/lib/util_smbd.c
@@ -0,0 +1,86 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions, used in smbd only
+ Copyright (C) Andrew Tridgell 2002
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/*
+ This function requires sys_getgrouplist - which is only
+ available in smbd due to it's use of become_root() in a
+ legacy systems hack.
+*/
+
+/*
+ return a full list of groups for a user
+
+ returns the number of groups the user is a member of. The return will include the
+ users primary group.
+
+ remember to free the resulting gid_t array
+
+ NOTE! uses become_root() to gain correct priviages on systems
+ that lack a native getgroups() call (uses initgroups and getgroups)
+*/
+BOOL getgroups_user(const char *user, gid_t primary_gid, gid_t **ret_groups, int *ngroups)
+{
+ int ngrp, max_grp;
+ gid_t *temp_groups;
+ gid_t *groups;
+ int i;
+
+ max_grp = groups_max();
+ temp_groups = SMB_MALLOC_ARRAY(gid_t, max_grp);
+ if (! temp_groups) {
+ return False;
+ }
+
+ if (sys_getgrouplist(user, primary_gid, temp_groups, &max_grp) == -1) {
+
+ gid_t *groups_tmp;
+
+ groups_tmp = SMB_REALLOC_ARRAY(temp_groups, gid_t, max_grp);
+
+ if (!groups_tmp) {
+ SAFE_FREE(temp_groups);
+ return False;
+ }
+ temp_groups = groups_tmp;
+
+ if (sys_getgrouplist(user, primary_gid, temp_groups, &max_grp) == -1) {
+ DEBUG(0, ("get_user_groups: failed to get the unix group list\n"));
+ SAFE_FREE(temp_groups);
+ return False;
+ }
+ }
+
+ ngrp = 0;
+ groups = NULL;
+
+ /* Add in primary group first */
+ add_gid_to_array_unique(NULL, primary_gid, &groups, &ngrp);
+
+ for (i=0; i<max_grp; i++)
+ add_gid_to_array_unique(NULL, temp_groups[i], &groups, &ngrp);
+
+ *ngroups = ngrp;
+ *ret_groups = groups;
+ SAFE_FREE(temp_groups);
+ return True;
+}
+
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index 0b02487f774..9b14dcfaf0f 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -201,8 +201,8 @@ int StrCaseCmp(const char *s, const char *t)
/* not ascii anymore, do it the hard way from here on in */
break;
- us = toupper_ascii(*ps);
- ut = toupper_ascii(*pt);
+ us = toupper(*ps);
+ ut = toupper(*pt);
if (us == ut)
continue;
else if (us < ut)
@@ -309,7 +309,7 @@ int strwicmp(const char *psz1, const char *psz2)
psz1++;
while (isspace((int)*psz2))
psz2++;
- if (toupper_ascii(*psz1) != toupper_ascii(*psz2) || *psz1 == '\0'
+ if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
|| *psz2 == '\0')
break;
psz1++;
@@ -680,7 +680,7 @@ char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, con
for(i = 0; i < len; i++) {
int val = (src[i] & 0xff);
- if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
+ if (isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
dest[i] = src[i];
else
dest[i] = '_';
@@ -774,12 +774,12 @@ size_t strhex_to_str(char *p, size_t len, const char *strhex)
continue;
}
- if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
+ if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
break;
i++; /* next hex digit */
- if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
+ if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
break;
/* get the two nybbles */
@@ -1003,8 +1003,7 @@ void pstring_sub(char *s,const char *pattern,const char *insert)
as string.
**/
-char *realloc_string_sub(char *string, const char *pattern,
- const char *insert)
+char *realloc_string_sub(char *string, const char *pattern, const char *insert)
{
char *p, *in;
char *s;
@@ -1064,77 +1063,6 @@ char *realloc_string_sub(char *string, const char *pattern,
return string;
}
-/* Same as string_sub, but returns a talloc'ed string */
-
-char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
- const char *pattern, const char *insert)
-{
- char *p, *in;
- char *s;
- char *string;
- ssize_t ls,lp,li,ld, i;
-
- if (!insert || !pattern || !*pattern || !src || !*src)
- return NULL;
-
- string = talloc_strdup(mem_ctx, src);
- if (string == NULL) {
- DEBUG(0, ("talloc_strdup failed\n"));
- return NULL;
- }
-
- s = string;
-
- in = SMB_STRDUP(insert);
- if (!in) {
- DEBUG(0, ("talloc_string_sub: out of memory!\n"));
- return NULL;
- }
- ls = (ssize_t)strlen(s);
- lp = (ssize_t)strlen(pattern);
- li = (ssize_t)strlen(insert);
- ld = li - lp;
- for (i=0;i<li;i++) {
- switch (in[i]) {
- case '`':
- case '"':
- case '\'':
- case ';':
- case '$':
- case '%':
- case '\r':
- case '\n':
- in[i] = '_';
- default:
- /* ok */
- break;
- }
- }
-
- while ((p = strstr_m(s,pattern))) {
- if (ld > 0) {
- int offset = PTR_DIFF(s,string);
- char *t = TALLOC_REALLOC(mem_ctx, string, ls + ld + 1);
- if (!t) {
- DEBUG(0, ("talloc_string_sub: out of "
- "memory!\n"));
- SAFE_FREE(in);
- return NULL;
- }
- string = t;
- p = t + offset + (p - s);
- }
- if (li != lp) {
- memmove(p+li,p+lp,strlen(p+lp)+1);
- }
- memcpy(p, in, li);
- s = p + li;
- ls += ld;
- }
- SAFE_FREE(in);
- return string;
-}
-
/**
Similar to string_sub() but allows for any character to be substituted.
Use with caution!
@@ -1510,7 +1438,7 @@ void strlower_m(char *s)
(ie. they match for the first 128 chars) */
while (*s && !(((unsigned char)s[0]) & 0x80)) {
- *s = tolower_ascii((unsigned char)*s);
+ *s = tolower((unsigned char)*s);
s++;
}
@@ -1544,7 +1472,7 @@ void strupper_m(char *s)
(ie. they match for the first 128 chars) */
while (*s && !(((unsigned char)s[0]) & 0x80)) {
- *s = toupper_ascii((unsigned char)*s);
+ *s = toupper((unsigned char)*s);
s++;
}
diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c
index 880416a5491..b979745d366 100644
--- a/source/lib/util_unistr.c
+++ b/source/lib/util_unistr.c
@@ -51,7 +51,6 @@ static uint8 doschar_table[8192]; /* 65536 characters / 8 bits/byte */
void load_case_tables(void)
{
static int initialised;
- char *old_locale = NULL, *saved_locale = NULL;
int i;
if (initialised) {
@@ -62,17 +61,6 @@ void load_case_tables(void)
upcase_table = map_file(lib_path("upcase.dat"), 0x20000);
lowcase_table = map_file(lib_path("lowcase.dat"), 0x20000);
-#ifdef HAVE_SETLOCALE
- /* Get the name of the current locale. */
- old_locale = setlocale(LC_ALL, NULL);
-
- /* Save it as it is in static storage. */
- saved_locale = SMB_STRDUP(old_locale);
-
- /* We set back the locale to C to get ASCII-compatible toupper/lower functions. */
- setlocale(LC_ALL, "C");
-#endif
-
/* we would like Samba to limp along even if these tables are
not available */
if (!upcase_table) {
@@ -104,12 +92,6 @@ void load_case_tables(void)
lowcase_table[v] = UCS2_CHAR(isupper(i)?tolower(i):i);
}
}
-
-#ifdef HAVE_SETLOCALE
- /* Restore the old locale. */
- setlocale (LC_ALL, saved_locale);
- SAFE_FREE(saved_locale);
-#endif
}
/*
@@ -1015,41 +997,3 @@ UNISTR2* ucs2_to_unistr2(TALLOC_CTX *ctx, UNISTR2* dst, smb_ucs2_t* src)
return dst;
}
-
-/*************************************************************
- ascii only toupper - saves the need for smbd to be in C locale.
-*************************************************************/
-
-int toupper_ascii(int c)
-{
- smb_ucs2_t uc = toupper_w(UCS2_CHAR(c));
- return UCS2_TO_CHAR(uc);
-}
-
-/*************************************************************
- ascii only tolower - saves the need for smbd to be in C locale.
-*************************************************************/
-
-int tolower_ascii(int c)
-{
- smb_ucs2_t uc = tolower_w(UCS2_CHAR(c));
- return UCS2_TO_CHAR(uc);
-}
-
-/*************************************************************
- ascii only isupper - saves the need for smbd to be in C locale.
-*************************************************************/
-
-int isupper_ascii(int c)
-{
- return isupper_w(UCS2_CHAR(c));
-}
-
-/*************************************************************
- ascii only islower - saves the need for smbd to be in C locale.
-*************************************************************/
-
-int islower_ascii(int c)
-{
- return islower_w(UCS2_CHAR(c));
-}
diff --git a/source/lib/version.c b/source/lib/version.c
index 3bd8304012c..99f836c2d5b 100644
--- a/source/lib/version.c
+++ b/source/lib/version.c
@@ -27,7 +27,6 @@ const char *samba_version_string(void)
return SAMBA_VERSION_OFFICIAL_STRING;
#else
static fstring samba_version;
- fstring tmp_version;
static BOOL init_samba_version;
if (init_samba_version)
@@ -37,11 +36,6 @@ const char *samba_version_string(void)
SAMBA_VERSION_OFFICIAL_STRING,
SAMBA_VERSION_VENDOR_SUFFIX);
-#ifdef SAMBA_VENDOR_PATCH
- fstr_sprintf( tmp_version, "-%d", SAMBA_VENDOR_PATCH );
- fstrcat( samba_version, tmp_version );
-#endif
-
init_samba_version = True;
return samba_version;
#endif
diff --git a/source/libsmb/clilist.c b/source/libsmb/clilist.c
index 48780e28dfa..252dafcfa8b 100644
--- a/source/libsmb/clilist.c
+++ b/source/libsmb/clilist.c
@@ -169,7 +169,11 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f
int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
void (*fn)(const char *, file_info *, const char *, void *), void *state)
{
- int max_matches = 1366;
+#if 1
+ int max_matches = 1366; /* Match W2k - was 512. */
+#else
+ int max_matches = 512;
+#endif
int info_level;
char *p, *p2;
pstring mask;
diff --git a/source/libsmb/climessage.c b/source/libsmb/climessage.c
index 1aa659c1ba3..f646096a4e5 100644
--- a/source/libsmb/climessage.c
+++ b/source/libsmb/climessage.c
@@ -85,7 +85,7 @@ int cli_message_text_build(struct cli_state *cli, char *msg, int len, int grp)
p = smb_buf(cli->outbuf);
*p++ = 1;
- if ((lendos = (int)convert_string_allocate(NULL,CH_UNIX, CH_DOS, msg,len, (void **)(void *)&msgdos, True)) < 0 || !msgdos) {
+ if ((lendos = (int)convert_string_allocate(NULL,CH_UNIX, CH_DOS, msg,len, (void **) &msgdos, True)) < 0 || !msgdos) {
DEBUG(3,("Conversion failed, sending message in UNIX charset\n"));
SSVAL(p, 0, len); p += 2;
memcpy(p, msg, len);
diff --git a/source/libsmb/clirap.c b/source/libsmb/clirap.c
index 6716971fe2c..172dea4090a 100644
--- a/source/libsmb/clirap.c
+++ b/source/libsmb/clirap.c
@@ -592,18 +592,18 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
if (!rdata || data_len < 22) {
return False;
}
-
+
if (c_time) {
*c_time = interpret_long_date(rdata+0);
}
if (a_time) {
*a_time = interpret_long_date(rdata+8);
}
- if (w_time) {
- *w_time = interpret_long_date(rdata+16);
- }
if (m_time) {
- *m_time = interpret_long_date(rdata+24);
+ *m_time = interpret_long_date(rdata+16);
+ }
+ if (w_time) {
+ *w_time = interpret_long_date(rdata+24);
}
if (mode) {
*mode = SVAL(rdata, 32);
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index 51f94e42e37..15210664b07 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -82,15 +82,11 @@ static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) {
/*
* Find an lsa pipe handle associated with a cli struct.
*/
-static struct rpc_pipe_client *
-find_lsa_pipe_hnd(struct cli_state *ipc_cli)
+static struct rpc_pipe_client *find_lsa_pipe_hnd(struct cli_state *ipc_cli)
{
struct rpc_pipe_client *pipe_hnd;
- for (pipe_hnd = ipc_cli->pipe_list;
- pipe_hnd;
- pipe_hnd = pipe_hnd->next) {
-
+ for (pipe_hnd = ipc_cli->pipe_list; pipe_hnd; pipe_hnd = pipe_hnd->next) {
if (pipe_hnd->pipe_idx == PI_LSARPC) {
return pipe_hnd;
}
@@ -99,14 +95,8 @@ find_lsa_pipe_hnd(struct cli_state *ipc_cli)
return NULL;
}
-static int
-smbc_close_ctx(SMBCCTX *context,
- SMBCFILE *file);
-static off_t
-smbc_lseek_ctx(SMBCCTX *context,
- SMBCFILE *file,
- off_t offset,
- int whence);
+static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file);
+static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence);
extern BOOL in_client;
@@ -325,9 +315,7 @@ smbc_parse_path(SMBCCTX *context,
if (*p == '/') {
strncpy(server, context->workgroup,
- ((strlen(context->workgroup) < 16)
- ? strlen(context->workgroup)
- : 16));
+ (strlen(context->workgroup) < 16)?strlen(context->workgroup):16);
return 0;
}
@@ -408,15 +396,9 @@ smbc_parse_path(SMBCCTX *context,
/*
* Verify that the options specified in a URL are valid
*/
-static int
-smbc_check_options(char *server,
- char *share,
- char *path,
- char *options)
+static int smbc_check_options(char *server, char *share, char *path, char *options)
{
- DEBUG(4, ("smbc_check_options(): server='%s' share='%s' "
- "path='%s' options='%s'\n",
- server, share, path, options));
+ DEBUG(4, ("smbc_check_options(): server='%s' share='%s' path='%s' options='%s'\n", server, share, path, options));
/* No options at all is always ok */
if (! *options) return 0;
@@ -428,9 +410,7 @@ smbc_check_options(char *server,
/*
* Convert an SMB error into a UNIX error ...
*/
-static int
-smbc_errno(SMBCCTX *context,
- struct cli_state *c)
+static int smbc_errno(SMBCCTX *context, struct cli_state *c)
{
int ret = cli_errno(c);
@@ -461,9 +441,7 @@ smbc_errno(SMBCCTX *context,
* Also useable outside libsmbclient to enable external cache
* to do some checks too.
*/
-static int
-smbc_check_server(SMBCCTX * context,
- SMBCSRV * server)
+int smbc_check_server(SMBCCTX * context, SMBCSRV * server)
{
if ( send_keepalive(server->cli.fd) == False )
return 1;
@@ -478,9 +456,7 @@ smbc_check_server(SMBCCTX * context,
*
* Also useable outside libsmbclient
*/
-int
-smbc_remove_unused_server(SMBCCTX * context,
- SMBCSRV * srv)
+int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv)
{
SMBCFILE * file;
@@ -493,8 +469,7 @@ smbc_remove_unused_server(SMBCCTX * context,
for (file = context->internal->_files; file; file=file->next) {
if (file->srv == srv) {
/* Still used */
- DEBUG(3, ("smbc_remove_usused_server: "
- "%p still used by %p.\n",
+ DEBUG(3, ("smbc_remove_usused_server: %p still used by %p.\n",
srv, file));
return 1;
}
@@ -513,13 +488,12 @@ smbc_remove_unused_server(SMBCCTX * context,
return 0;
}
-static SMBCSRV *
-find_server(SMBCCTX *context,
- const char *server,
- const char *share,
- fstring workgroup,
- fstring username,
- fstring password)
+SMBCSRV *find_server(SMBCCTX *context,
+ const char *server,
+ const char *share,
+ fstring workgroup,
+ fstring username,
+ fstring password)
{
SMBCSRV *srv;
int auth_called = 0;
@@ -587,14 +561,10 @@ find_server(SMBCCTX *context,
* info we need, unless the username and password were passed in.
*/
-static SMBCSRV *
-smbc_server(SMBCCTX *context,
- BOOL connect_if_not_found,
- const char *server,
- const char *share,
- fstring workgroup,
- fstring username,
- fstring password)
+SMBCSRV *smbc_server(SMBCCTX *context,
+ const char *server, const char *share,
+ fstring workgroup, fstring username,
+ fstring password)
{
SMBCSRV *srv=NULL;
struct cli_state c;
@@ -645,18 +615,13 @@ smbc_server(SMBCCTX *context,
errno = smbc_errno(context, &srv->cli);
cli_shutdown(&srv->cli);
- context->callbacks.remove_cached_srv_fn(context,
- srv);
+ context->callbacks.remove_cached_srv_fn(context, srv);
srv = NULL;
}
- /*
- * Regenerate the dev value since it's based on both
- * server and share
- */
+ /* Regenerate the dev value since it's based on both server and share */
if (srv) {
- srv->dev = (dev_t)(str_checksum(server) ^
- str_checksum(share));
+ srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share));
}
}
}
@@ -668,12 +633,6 @@ smbc_server(SMBCCTX *context,
return srv;
}
- /* If we're not asked to connect when a connection doesn't exist... */
- if (! connect_if_not_found) {
- /* ... then we're done here. */
- return NULL;
- }
-
make_nmb_name(&calling, context->netbios_name, 0x0);
make_nmb_name(&called , server, 0x20);
@@ -852,14 +811,11 @@ smbc_server(SMBCCTX *context,
* Connect to a server for getting/setting attributes, possibly on an existing
* connection. This works similarly to smbc_server().
*/
-static SMBCSRV *
-smbc_attr_server(SMBCCTX *context,
- const char *server,
- const char *share,
- fstring workgroup,
- fstring username,
- fstring password,
- POLICY_HND *pol)
+SMBCSRV *smbc_attr_server(SMBCCTX *context,
+ const char *server, const char *share,
+ fstring workgroup,
+ fstring username, fstring password,
+ POLICY_HND *pol)
{
struct in_addr ip;
struct cli_state *ipc_cli;
@@ -971,15 +927,11 @@ smbc_attr_server(SMBCCTX *context,
* Routine to open() a file ...
*/
-static SMBCFILE *
-smbc_open_ctx(SMBCCTX *context,
- const char *fname,
- int flags,
- mode_t mode)
+static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, mode_t mode)
{
fstring server, share, user, password, workgroup;
pstring path;
- pstring targetpath;
+ pstring targetpath;
struct cli_state *targetcli;
SMBCSRV *srv = NULL;
SMBCFILE *file = NULL;
@@ -1015,8 +967,7 @@ smbc_open_ctx(SMBCCTX *context,
fstrcpy(workgroup, context->workgroup);
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(context, server, share, workgroup, user, password);
if (!srv) {
@@ -1137,10 +1088,7 @@ smbc_open_ctx(SMBCCTX *context,
static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this */
-static SMBCFILE *
-smbc_creat_ctx(SMBCCTX *context,
- const char *path,
- mode_t mode)
+static SMBCFILE *smbc_creat_ctx(SMBCCTX *context, const char *path, mode_t mode)
{
if (!context || !context->internal ||
@@ -1158,11 +1106,7 @@ smbc_creat_ctx(SMBCCTX *context,
* Routine to read() a file ...
*/
-static ssize_t
-smbc_read_ctx(SMBCCTX *context,
- SMBCFILE *file,
- void *buf,
- size_t count)
+static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count)
{
int ret;
fstring server, share, user, password;
@@ -1219,8 +1163,7 @@ smbc_read_ctx(SMBCCTX *context,
}
/*d_printf(">>>read: resolving %s\n", path);*/
- if (!cli_resolve_path("", &file->srv->cli, path,
- &targetcli, targetpath))
+ if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
return -1;
@@ -1248,20 +1191,14 @@ smbc_read_ctx(SMBCCTX *context,
* Routine to write() a file ...
*/
-static ssize_t
-smbc_write_ctx(SMBCCTX *context,
- SMBCFILE *file,
- void *buf,
- size_t count)
+static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count)
{
int ret;
- off_t offset;
+ off_t offset = file->offset; /* See "offset" comment in smbc_read_ctx() */
fstring server, share, user, password;
pstring path, targetpath;
struct cli_state *targetcli;
- offset = file->offset; /* See "offset" comment in smbc_read_ctx() */
-
if (!context || !context->internal ||
!context->internal->_initialized) {
@@ -1299,8 +1236,7 @@ smbc_write_ctx(SMBCCTX *context,
}
/*d_printf(">>>write: resolving %s\n", path);*/
- if (!cli_resolve_path("", &file->srv->cli, path,
- &targetcli, targetpath))
+ if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
return -1;
@@ -1326,9 +1262,7 @@ smbc_write_ctx(SMBCCTX *context,
* Routine to close() a file ...
*/
-static int
-smbc_close_ctx(SMBCCTX *context,
- SMBCFILE *file)
+static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file)
{
SMBCSRV *srv;
fstring server, share, user, password;
@@ -1370,8 +1304,7 @@ smbc_close_ctx(SMBCCTX *context,
}
/*d_printf(">>>close: resolving %s\n", path);*/
- if (!cli_resolve_path("", &file->srv->cli, path,
- &targetcli, targetpath))
+ if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
return -1;
@@ -1406,21 +1339,14 @@ smbc_close_ctx(SMBCCTX *context,
* Get info from an SMB server on a file. Use a qpathinfo call first
* and if that fails, use getatr, as Win95 sometimes refuses qpathinfo
*/
-static BOOL
-smbc_getatr(SMBCCTX * context,
- SMBCSRV *srv,
- char *path,
- uint16 *mode,
- SMB_OFF_T *size,
- time_t *c_time,
- time_t *a_time,
- time_t *m_time,
- SMB_INO_T *ino)
+static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path,
+ uint16 *mode, SMB_OFF_T *size,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ SMB_INO_T *ino)
{
pstring fixedpath;
pstring targetpath;
struct cli_state *targetcli;
-
if (!context || !context->internal ||
!context->internal->_initialized) {
@@ -1450,15 +1376,12 @@ smbc_getatr(SMBCCTX * context,
{
pstring temppath;
pstrcpy(temppath, targetpath);
- cli_dfs_make_full_path(targetpath, targetcli->desthost,
- targetcli->share, temppath);
+ cli_dfs_make_full_path( targetpath, targetcli->desthost, targetcli->share, temppath);
}
if (!srv->no_pathinfo2 &&
- cli_qpathinfo2(targetcli, targetpath,
- c_time, a_time, m_time, NULL, size, mode, ino)) {
- return True;
- }
+ cli_qpathinfo2(targetcli, targetpath, c_time, a_time, m_time, NULL,
+ size, mode, ino)) return True;
/* if this is NT then don't bother with the getatr */
if (targetcli->capabilities & CAP_NT_SMBS) {
@@ -1490,10 +1413,9 @@ smbc_getatr(SMBCCTX * context,
*
* "mode" (attributes) parameter may be set to -1 if it is not to be set.
*/
-static BOOL
-smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
- time_t c_time, time_t a_time, time_t m_time,
- uint16 mode)
+static BOOL smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
+ time_t c_time, time_t a_time, time_t m_time,
+ uint16 mode)
{
int fd;
int ret;
@@ -1620,9 +1542,7 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path,
* Routine to unlink() a file
*/
-static int
-smbc_unlink_ctx(SMBCCTX *context,
- const char *fname)
+ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname)
{
fstring server, share, user, password, workgroup;
pstring path, targetpath;
@@ -1659,8 +1579,7 @@ smbc_unlink_ctx(SMBCCTX *context,
fstrcpy(workgroup, context->workgroup);
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(context, server, share, workgroup, user, password);
if (!srv) {
@@ -1719,27 +1638,12 @@ smbc_unlink_ctx(SMBCCTX *context,
* Routine to rename() a file
*/
-static int
-smbc_rename_ctx(SMBCCTX *ocontext,
- const char *oname,
- SMBCCTX *ncontext,
- const char *nname)
+static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname,
+ SMBCCTX *ncontext, const char *nname)
{
- fstring server1;
- fstring share1;
- fstring server2;
- fstring share2;
- fstring user1;
- fstring user2;
- fstring password1;
- fstring password2;
- fstring workgroup;
- pstring path1;
- pstring path2;
- pstring targetpath1;
- pstring targetpath2;
- struct cli_state *targetcli1;
- struct cli_state *targetcli2;
+ fstring server1, share1, server2, share2, user1, user2, password1, password2, workgroup;
+ pstring path1, path2, targetpath1, targetpath2;
+ struct cli_state *targetcli1, *targetcli2;
SMBCSRV *srv = NULL;
if (!ocontext || !ncontext ||
@@ -1792,9 +1696,8 @@ smbc_rename_ctx(SMBCCTX *ocontext,
}
fstrcpy(workgroup, ocontext->workgroup);
-
- srv = smbc_server(ocontext, True,
- server1, share1, workgroup, user1, password1);
+ /* HELP !!! Which workgroup should I use ? Or are they always the same -- Tom */
+ srv = smbc_server(ocontext, server1, share1, workgroup, user1, password1);
if (!srv) {
return -1;
@@ -1816,8 +1719,7 @@ smbc_rename_ctx(SMBCCTX *ocontext,
}
/*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/
- if (strcmp(targetcli1->desthost, targetcli2->desthost) ||
- strcmp(targetcli1->share, targetcli2->share))
+ if (strcmp(targetcli1->desthost, targetcli2->desthost) || strcmp(targetcli1->share, targetcli2->share))
{
/* can't rename across file systems */
@@ -1846,11 +1748,7 @@ smbc_rename_ctx(SMBCCTX *ocontext,
* A routine to lseek() a file
*/
-static off_t
-smbc_lseek_ctx(SMBCCTX *context,
- SMBCFILE *file,
- off_t offset,
- int whence)
+static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence)
{
SMB_OFF_T size;
fstring server, share, user, password;
@@ -1891,32 +1789,30 @@ smbc_lseek_ctx(SMBCCTX *context,
case SEEK_END:
/*d_printf(">>>lseek: parsing %s\n", file->fname);*/
if (smbc_parse_path(context, file->fname,
- server, sizeof(server),
- share, sizeof(share),
- path, sizeof(path),
- user, sizeof(user),
- password, sizeof(password),
- NULL, 0)) {
-
+ server, sizeof(server),
+ share, sizeof(share),
+ path, sizeof(path),
+ user, sizeof(user),
+ password, sizeof(password),
+ NULL, 0)) {
errno = EINVAL;
return -1;
}
/*d_printf(">>>lseek: resolving %s\n", path);*/
- if (!cli_resolve_path("", &file->srv->cli, path,
- &targetcli, targetpath))
+ if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
return -1;
}
/*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/
- if (!cli_qfileinfo(targetcli, file->cli_fd, NULL,
- &size, NULL, NULL, NULL, NULL, NULL))
+ if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, &size, NULL, NULL,
+ NULL, NULL, NULL))
{
SMB_OFF_T b_size = size;
- if (!cli_getattrE(targetcli, file->cli_fd,
- NULL, &b_size, NULL, NULL, NULL))
+ if (!cli_getattrE(targetcli, file->cli_fd, NULL, &b_size, NULL, NULL,
+ NULL))
{
errno = EINVAL;
return -1;
@@ -1940,9 +1836,8 @@ smbc_lseek_ctx(SMBCCTX *context,
* Generate an inode number from file name for those things that need it
*/
-static ino_t
-smbc_inode(SMBCCTX *context,
- const char *name)
+static
+ino_t smbc_inode(SMBCCTX *context, const char *name)
{
if (!context || !context->internal ||
@@ -1963,12 +1858,9 @@ smbc_inode(SMBCCTX *context,
* fstat below.
*/
-static int
-smbc_setup_stat(SMBCCTX *context,
- struct stat *st,
- char *fname,
- SMB_OFF_T size,
- int mode)
+static
+int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname,
+ SMB_OFF_T size, int mode)
{
st->st_mode = 0;
@@ -2012,21 +1904,12 @@ smbc_setup_stat(SMBCCTX *context,
* Routine to stat a file given a name
*/
-static int
-smbc_stat_ctx(SMBCCTX *context,
- const char *fname,
- struct stat *st)
+static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st)
{
SMBCSRV *srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
+ fstring server, share, user, password, workgroup;
pstring path;
- time_t m_time = 0;
- time_t a_time = 0;
- time_t c_time = 0;
+ time_t m_time = 0, a_time = 0, c_time = 0;
SMB_OFF_T size = 0;
uint16 mode = 0;
SMB_INO_T ino = 0;
@@ -2063,8 +1946,7 @@ smbc_stat_ctx(SMBCCTX *context,
fstrcpy(workgroup, context->workgroup);
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(context, server, share, workgroup, user, password);
if (!srv) {
return -1; /* errno set by smbc_server */
@@ -2095,22 +1977,13 @@ smbc_stat_ctx(SMBCCTX *context,
* Routine to stat a file given an fd
*/
-static int
-smbc_fstat_ctx(SMBCCTX *context,
- SMBCFILE *file,
- struct stat *st)
+static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st)
{
- time_t c_time;
- time_t a_time;
- time_t m_time;
+ time_t c_time, a_time, m_time;
SMB_OFF_T size;
uint16 mode;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- pstring path;
- pstring targetpath;
+ fstring server, share, user, password;
+ pstring path, targetpath;
struct cli_state *targetcli;
SMB_INO_T ino = 0;
@@ -2148,18 +2021,17 @@ smbc_fstat_ctx(SMBCCTX *context,
}
/*d_printf(">>>fstat: resolving %s\n", path);*/
- if (!cli_resolve_path("", &file->srv->cli, path,
- &targetcli, targetpath))
+ if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
return -1;
}
/*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/
- if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size,
- &c_time, &a_time, &m_time, NULL, &ino)) {
- if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size,
- &c_time, &a_time, &m_time)) {
+ if (!cli_qfileinfo(targetcli, file->cli_fd,
+ &mode, &size, &c_time, &a_time, &m_time, NULL, &ino)) {
+ if (!cli_getattrE(targetcli, file->cli_fd,
+ &mode, &size, &c_time, &a_time, &m_time)) {
errno = EINVAL;
return -1;
@@ -2184,8 +2056,7 @@ smbc_fstat_ctx(SMBCCTX *context,
* We accept the URL syntax explained in smbc_parse_path(), above.
*/
-static void
-smbc_remove_dir(SMBCFILE *dir)
+static void smbc_remove_dir(SMBCFILE *dir)
{
struct smbc_dir_list *d,*f;
@@ -2203,11 +2074,7 @@ smbc_remove_dir(SMBCFILE *dir)
}
-static int
-add_dirent(SMBCFILE *dir,
- const char *name,
- const char *comment,
- uint32 type)
+static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint32 type)
{
struct smbc_dirent *dirent;
int size;
@@ -2280,10 +2147,7 @@ add_dirent(SMBCFILE *dir,
}
static void
-list_unique_wg_fn(const char *name,
- uint32 type,
- const char *comment,
- void *state)
+list_unique_wg_fn(const char *name, uint32 type, const char *comment, void *state)
{
SMBCFILE *dir = (SMBCFILE *)state;
struct smbc_dir_list *dir_list;
@@ -2324,10 +2188,7 @@ list_unique_wg_fn(const char *name,
}
static void
-list_fn(const char *name,
- uint32 type,
- const char *comment,
- void *state)
+list_fn(const char *name, uint32 type, const char *comment, void *state)
{
SMBCFILE *dir = (SMBCFILE *)state;
int dirent_type;
@@ -2383,10 +2244,7 @@ list_fn(const char *name,
}
static void
-dir_list_fn(const char *mnt,
- file_info *finfo,
- const char *mask,
- void *state)
+dir_list_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
{
if (add_dirent((SMBCFILE *)state, finfo->name, "",
@@ -2482,9 +2340,7 @@ done:
-static SMBCFILE *
-smbc_opendir_ctx(SMBCCTX *context,
- const char *fname)
+static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname)
{
fstring server, share, user, password, options;
pstring workgroup;
@@ -2521,9 +2377,7 @@ smbc_opendir_ctx(SMBCCTX *context,
return NULL;
}
- DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' "
- "path='%s' options='%s'\n",
- fname, server, share, path, options));
+ DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' path='%s' options='%s'\n", fname, server, share, path, options));
/* Ensure the options are valid */
if (smbc_check_options(server, share, path, options)) {
@@ -2607,12 +2461,9 @@ smbc_opendir_ctx(SMBCCTX *context,
}
for (i = 0; i < count && i < max_lmb_count; i++) {
- DEBUG(99, ("Found master browser %d of %d: %s\n",
- i+1, MAX(count, max_lmb_count),
- inet_ntoa(ip_list[i].ip)));
+ DEBUG(99, ("Found master browser %d of %d: %s\n", i+1, MAX(count, max_lmb_count), inet_ntoa(ip_list[i].ip)));
- cli = get_ipc_connect_master_ip(&ip_list[i],
- workgroup, &u_info);
+ cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, &u_info);
/* cli == NULL is the master browser refused to talk or
could not be found */
if ( !cli )
@@ -2621,8 +2472,7 @@ smbc_opendir_ctx(SMBCCTX *context,
fstrcpy(server, cli->desthost);
cli_shutdown(cli);
- DEBUG(4, ("using workgroup %s %s\n",
- workgroup, server));
+ DEBUG(4, ("using workgroup %s %s\n", workgroup, server));
/*
* For each returned master browser IP address, get a
@@ -2631,8 +2481,8 @@ smbc_opendir_ctx(SMBCCTX *context,
* workgroups/domains that it knows about.
*/
- srv = smbc_server(context, True, server, "IPC$",
- workgroup, user, password);
+ srv = smbc_server(context, server,
+ "IPC$", workgroup, user, password);
if (!srv) {
continue;
}
@@ -2657,10 +2507,10 @@ smbc_opendir_ctx(SMBCCTX *context,
* Server not an empty string ... Check the rest and see what
* gives
*/
- if (*share == '\0') {
- if (*path != '\0') {
+ if (share[0] == (char)0) {
+
+ if (path[0] != (char)0) { /* Should not have empty share with path */
- /* Should not have empty share with path */
errno = EINVAL + 8197;
if (dir) {
SAFE_FREE(dir->fname);
@@ -2670,32 +2520,12 @@ smbc_opendir_ctx(SMBCCTX *context,
}
- /*
- * We don't know if <server> is really a server name
- * or is a workgroup/domain name. If we already have
- * a server structure for it, we'll use it.
- * Otherwise, check to see if <server><1D>,
- * <server><1B>, or <server><20> translates. We check
- * to see if <server> is an IP address first.
- */
-
- /*
- * See if we have an existing server. Do not
- * establish a connection if one does not already
- * exist.
- */
- srv = smbc_server(context, False, server, "IPC$",
- workgroup, user, password);
-
- /*
- * If no existing server and not an IP addr, look for
- * LMB or DMB
- */
- if (!srv &&
- !is_ipaddress(server) &&
- (resolve_name(server, &rem_ip, 0x1d) || /* LMB */
- resolve_name(server, &rem_ip, 0x1b) )) { /* DMB */
+ /* Check to see if <server><1D>, <server><1B>, or <server><20> translates */
+ /* However, we check to see if <server> is an IP address first */
+ if (!is_ipaddress(server) && /* Not an IP addr so check next */
+ (resolve_name(server, &rem_ip, 0x1d) || /* Found LMB */
+ resolve_name(server, &rem_ip, 0x1b) )) { /* Found DMB */
fstring buserver;
dir->dir_type = SMBC_SERVER;
@@ -2703,24 +2533,22 @@ smbc_opendir_ctx(SMBCCTX *context,
/*
* Get the backup list ...
*/
- if (!name_status_find(server, 0, 0,
- rem_ip, buserver)) {
- DEBUG(0, ("Could not get name of "
- "local/domain master browser "
- "for server %s\n", server));
- errno = EPERM;
+
+ if (!name_status_find(server, 0, 0, rem_ip, buserver)) {
+
+ DEBUG(0, ("Could not get name of local/domain master browser for server %s\n", server));
+ errno = EPERM; /* FIXME, is this correct */
return NULL;
}
/*
- * Get a connection to IPC$ on the server if
- * we do not already have one
- */
- srv = smbc_server(context, True,
- buserver, "IPC$",
- workgroup, user, password);
+ * Get a connection to IPC$ on the server if we do not already have one
+ */
+
+ srv = smbc_server(context, buserver, "IPC$", workgroup, user, password);
+
if (!srv) {
DEBUG(0, ("got no contact to IPC$\n"));
if (dir) {
@@ -2734,8 +2562,8 @@ smbc_opendir_ctx(SMBCCTX *context,
dir->srv = srv;
/* Now, list the servers ... */
- if (!cli_NetServerEnum(&srv->cli, server,
- 0x0000FFFE, list_fn,
+
+ if (!cli_NetServerEnum(&srv->cli, server, 0x0000FFFE, list_fn,
(void *)dir)) {
if (dir) {
@@ -2743,73 +2571,75 @@ smbc_opendir_ctx(SMBCCTX *context,
SAFE_FREE(dir);
}
return NULL;
+
}
- } else if (srv ||
- (resolve_name(server, &rem_ip, 0x20))) {
-
- /* If we hadn't found the server, get one now */
- if (!srv) {
- srv = smbc_server(context, True,
- server, "IPC$",
- workgroup,
- user, password);
- }
+ }
+ else {
- if (!srv) {
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
- }
- return NULL;
+ if (resolve_name(server, &rem_ip, 0x20)) {
- }
+ /* Now, list the shares ... */
+
+ dir->dir_type = SMBC_FILE_SHARE;
+
+ srv = smbc_server(context, server, "IPC$", workgroup, user, password);
- dir->dir_type = SMBC_FILE_SHARE;
- dir->srv = srv;
+ if (!srv) {
- /* List the shares ... */
+ if (dir) {
+ SAFE_FREE(dir->fname);
+ SAFE_FREE(dir);
+ }
+ return NULL;
- if (net_share_enum_rpc(
- &srv->cli,
- list_fn,
- (void *) dir) < 0 &&
- cli_RNetShareEnum(
- &srv->cli,
- list_fn,
- (void *)dir) < 0) {
+ }
+
+ dir->srv = srv;
+
+ /* Now, list the servers ... */
+
+ if (net_share_enum_rpc(
+ &srv->cli,
+ list_fn,
+ (void *) dir) < 0 &&
+ cli_RNetShareEnum(
+ &srv->cli,
+ list_fn,
+ (void *)dir) < 0) {
- errno = cli_errno(&srv->cli);
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
- }
- return NULL;
+ errno = cli_errno(&srv->cli);
+ if (dir) {
+ SAFE_FREE(dir->fname);
+ SAFE_FREE(dir);
+ }
+ return NULL;
+
+ }
+
+ }
+ else {
+
+ errno = ECONNREFUSED; /* Neither the workgroup nor server exists */
+ if (dir) {
+ SAFE_FREE(dir->fname);
+ SAFE_FREE(dir);
+ }
+ return NULL;
+
+ }
- }
- } else {
- /* Neither the workgroup nor server exists */
- errno = ECONNREFUSED;
- if (dir) {
- SAFE_FREE(dir->fname);
- SAFE_FREE(dir);
- }
- return NULL;
}
}
- else {
- /*
- * The server and share are specified ... work from
- * there ...
- */
+ else { /* The server and share are specified ... work from there ... */
pstring targetpath;
struct cli_state *targetcli;
- /* We connect to the server and list the directory */
+ /* Well, we connect to the server and list the directory */
+
dir->dir_type = SMBC_FILE_SHARE;
- srv = smbc_server(context, True, server, share,
- workgroup, user, password);
+ srv = smbc_server(context, server, share, workgroup, user, password);
if (!srv) {
@@ -2828,16 +2658,14 @@ smbc_opendir_ctx(SMBCCTX *context,
p = path + strlen(path);
pstrcat(path, "\\*");
- if (!cli_resolve_path("", &srv->cli, path,
- &targetcli, targetpath))
+ if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath))
{
d_printf("Could not resolve %s\n", path);
return NULL;
}
- if (cli_list(targetcli, targetpath,
- aDIR | aSYSTEM | aHIDDEN,
- dir_list_fn, (void *)dir) < 0) {
+ if (cli_list(targetcli, targetpath, aDIR | aSYSTEM | aHIDDEN, dir_list_fn,
+ (void *)dir) < 0) {
if (dir) {
SAFE_FREE(dir->fname);
@@ -2881,9 +2709,7 @@ smbc_opendir_ctx(SMBCCTX *context,
* Routine to close a directory
*/
-static int
-smbc_closedir_ctx(SMBCCTX *context,
- SMBCFILE *dir)
+static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir)
{
if (!context || !context->internal ||
@@ -2915,11 +2741,10 @@ smbc_closedir_ctx(SMBCCTX *context,
}
-static void
-smbc_readdir_internal(SMBCCTX * context,
- struct smbc_dirent *dest,
- struct smbc_dirent *src,
- int max_namebuf_len)
+static void smbc_readdir_internal(SMBCCTX * context,
+ struct smbc_dirent *dest,
+ struct smbc_dirent *src,
+ int max_namebuf_len)
{
if (context->options.urlencode_readdir_entries) {
@@ -2961,9 +2786,7 @@ smbc_readdir_internal(SMBCCTX * context,
* Routine to get a directory entry
*/
-struct smbc_dirent *
-smbc_readdir_ctx(SMBCCTX *context,
- SMBCFILE *dir)
+struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir)
{
int maxlen;
struct smbc_dirent *dirp, *dirent;
@@ -3022,11 +2845,10 @@ smbc_readdir_ctx(SMBCCTX *context,
* Routine to get directory entries
*/
-static int
-smbc_getdents_ctx(SMBCCTX *context,
- SMBCFILE *dir,
- struct smbc_dirent *dirp,
- int count)
+static int smbc_getdents_ctx(SMBCCTX *context,
+ SMBCFILE *dir,
+ struct smbc_dirent *dirp,
+ int count)
{
int rem = count;
int reqd;
@@ -3124,17 +2946,10 @@ smbc_getdents_ctx(SMBCCTX *context,
* Routine to create a directory ...
*/
-static int
-smbc_mkdir_ctx(SMBCCTX *context,
- const char *fname,
- mode_t mode)
+static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode)
{
SMBCSRV *srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
+ fstring server, share, user, password, workgroup;
pstring path, targetpath;
struct cli_state *targetcli;
@@ -3170,8 +2985,7 @@ smbc_mkdir_ctx(SMBCCTX *context,
fstrcpy(workgroup, context->workgroup);
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(context, server, share, workgroup, user, password);
if (!srv) {
@@ -3204,35 +3018,23 @@ smbc_mkdir_ctx(SMBCCTX *context,
static int smbc_rmdir_dirempty = True;
-static void
-rmdir_list_fn(const char *mnt,
- file_info *finfo,
- const char *mask,
- void *state)
+static void rmdir_list_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
{
- if (strncmp(finfo->name, ".", 1) != 0 &&
- strncmp(finfo->name, "..", 2) != 0) {
-
+
+ if (strncmp(finfo->name, ".", 1) != 0 && strncmp(finfo->name, "..", 2) != 0)
smbc_rmdir_dirempty = False;
- }
+
}
/*
* Routine to remove a directory
*/
-static int
-smbc_rmdir_ctx(SMBCCTX *context,
- const char *fname)
+static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname)
{
SMBCSRV *srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
- pstring path;
- pstring targetpath;
+ fstring server, share, user, password, workgroup;
+ pstring path, targetpath;
struct cli_state *targetcli;
if (!context || !context->internal ||
@@ -3268,8 +3070,7 @@ smbc_rmdir_ctx(SMBCCTX *context,
fstrcpy(workgroup, context->workgroup);
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(context, server, share, workgroup, user, password);
if (!srv) {
@@ -3277,6 +3078,27 @@ smbc_rmdir_ctx(SMBCCTX *context,
}
+ /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) {
+
+ mode = aDIR | aRONLY;
+
+ }
+ else if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
+
+ if (strcmp(path, "\\") == 0) {
+
+ mode = aDIR | aRONLY;
+
+ }
+ else {
+
+ mode = aRONLY;
+ smbc_stat_printjob(srv, path, &size, &m_time);
+ c_time = a_time = m_time;
+
+ }
+ else { */
+
/*d_printf(">>>rmdir: resolving %s\n", path);*/
if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath))
{
@@ -3292,21 +3114,19 @@ smbc_rmdir_ctx(SMBCCTX *context,
if (errno == EACCES) { /* Check if the dir empty or not */
- /* Local storage to avoid buffer overflows */
- pstring lpath;
+ pstring lpath; /* Local storage to avoid buffer overflows */
smbc_rmdir_dirempty = True; /* Make this so ... */
pstrcpy(lpath, targetpath);
pstrcat(lpath, "\\*");
- if (cli_list(targetcli, lpath,
- aDIR | aSYSTEM | aHIDDEN,
- rmdir_list_fn, NULL) < 0) {
+ if (cli_list(targetcli, lpath, aDIR | aSYSTEM | aHIDDEN, rmdir_list_fn,
+ NULL) < 0) {
/* Fix errno to ignore latest error ... */
- DEBUG(5, ("smbc_rmdir: "
- "cli_list returned an error: %d\n",
+
+ DEBUG(5, ("smbc_rmdir: cli_list returned an error: %d\n",
smbc_errno(context, targetcli)));
errno = EACCES;
@@ -3331,9 +3151,7 @@ smbc_rmdir_ctx(SMBCCTX *context,
* Routine to return the current directory position
*/
-static off_t
-smbc_telldir_ctx(SMBCCTX *context,
- SMBCFILE *dir)
+static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir)
{
off_t ret_val; /* Squash warnings about cast */
@@ -3371,9 +3189,8 @@ smbc_telldir_ctx(SMBCCTX *context,
* A routine to run down the list and see if the entry is OK
*/
-struct smbc_dir_list *
-smbc_check_dir_ent(struct smbc_dir_list *list,
- struct smbc_dirent *dirent)
+struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list,
+ struct smbc_dirent *dirent)
{
/* Run down the list looking for what we want */
@@ -3402,10 +3219,7 @@ smbc_check_dir_ent(struct smbc_dir_list *list,
* Routine to seek on a directory
*/
-static int
-smbc_lseekdir_ctx(SMBCCTX *context,
- SMBCFILE *dir,
- off_t offset)
+static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset)
{
long int l_offset = offset; /* Handle problems of size */
struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset;
@@ -3455,10 +3269,7 @@ smbc_lseekdir_ctx(SMBCCTX *context,
* Routine to fstat a dir
*/
-static int
-smbc_fstatdir_ctx(SMBCCTX *context,
- SMBCFILE *dir,
- struct stat *st)
+static int smbc_fstatdir_ctx(SMBCCTX *context, SMBCFILE *dir, struct stat *st)
{
if (!context || !context->internal ||
@@ -3475,17 +3286,10 @@ smbc_fstatdir_ctx(SMBCCTX *context,
}
-static int
-smbc_chmod_ctx(SMBCCTX *context,
- const char *fname,
- mode_t newmode)
+int smbc_chmod_ctx(SMBCCTX *context, const char *fname, mode_t newmode)
{
SMBCSRV *srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
+ fstring server, share, user, password, workgroup;
pstring path;
uint16 mode;
@@ -3521,8 +3325,7 @@ smbc_chmod_ctx(SMBCCTX *context,
fstrcpy(workgroup, context->workgroup);
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(context, server, share, workgroup, user, password);
if (!srv) {
return -1; /* errno set by smbc_server */
@@ -3543,17 +3346,10 @@ smbc_chmod_ctx(SMBCCTX *context,
return 0;
}
-static int
-smbc_utimes_ctx(SMBCCTX *context,
- const char *fname,
- struct timeval *tbuf)
+int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf)
{
SMBCSRV *srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
+ fstring server, share, user, password, workgroup;
pstring path;
time_t a_time;
time_t m_time;
@@ -3617,8 +3413,7 @@ smbc_utimes_ctx(SMBCCTX *context,
fstrcpy(workgroup, context->workgroup);
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(context, server, share, workgroup, user, password);
if (!srv) {
return -1; /* errno set by smbc_server */
@@ -3637,9 +3432,7 @@ smbc_utimes_ctx(SMBCCTX *context,
computer running Windows NT 5.0" if denied ACEs do not appear before
allowed ACEs. */
-static int
-ace_compare(SEC_ACE *ace1,
- SEC_ACE *ace2)
+static int ace_compare(SEC_ACE *ace1, SEC_ACE *ace2)
{
if (sec_ace_equal(ace1, ace2))
return 0;
@@ -3663,14 +3456,12 @@ ace_compare(SEC_ACE *ace1,
}
-static void
-sort_acl(SEC_ACL *the_acl)
+static void sort_acl(SEC_ACL *the_acl)
{
uint32 i;
if (!the_acl) return;
- qsort(the_acl->ace, the_acl->num_aces, sizeof(the_acl->ace[0]),
- QSORT_CAST ace_compare);
+ qsort(the_acl->ace, the_acl->num_aces, sizeof(the_acl->ace[0]), QSORT_CAST ace_compare);
for (i=1;i<the_acl->num_aces;) {
if (sec_ace_equal(&the_acl->ace[i-1], &the_acl->ace[i])) {
@@ -3686,12 +3477,11 @@ sort_acl(SEC_ACL *the_acl)
}
/* convert a SID to a string, either numeric or username/group */
-static void
-convert_sid_to_string(struct cli_state *ipc_cli,
- POLICY_HND *pol,
- fstring str,
- BOOL numeric,
- DOM_SID *sid)
+static void convert_sid_to_string(struct cli_state *ipc_cli,
+ POLICY_HND *pol,
+ fstring str,
+ BOOL numeric,
+ DOM_SID *sid)
{
char **domains = NULL;
char **names = NULL;
@@ -3724,12 +3514,11 @@ convert_sid_to_string(struct cli_state *ipc_cli,
}
/* convert a string to a SID, either numeric or username/group */
-static BOOL
-convert_string_to_sid(struct cli_state *ipc_cli,
- POLICY_HND *pol,
- BOOL numeric,
- DOM_SID *sid,
- const char *str)
+static BOOL convert_string_to_sid(struct cli_state *ipc_cli,
+ POLICY_HND *pol,
+ BOOL numeric,
+ DOM_SID *sid,
+ const char *str)
{
uint32 *types = NULL;
DOM_SID *sids = NULL;
@@ -3764,19 +3553,16 @@ convert_string_to_sid(struct cli_state *ipc_cli,
/* parse an ACE in the same format as print_ace() */
-static BOOL
-parse_ace(struct cli_state *ipc_cli,
- POLICY_HND *pol,
- SEC_ACE *ace,
- BOOL numeric,
- char *str)
+static BOOL parse_ace(struct cli_state *ipc_cli,
+ POLICY_HND *pol,
+ SEC_ACE *ace,
+ BOOL numeric,
+ char *str)
{
char *p;
const char *cp;
fstring tok;
- unsigned int atype;
- unsigned int aflags;
- unsigned int amask;
+ unsigned atype, aflags, amask;
DOM_SID sid;
SEC_ACCESS mask;
const struct perm_value *v;
@@ -3887,14 +3673,10 @@ parse_ace(struct cli_state *ipc_cli,
}
/* add an ACE to a list of ACEs in a SEC_ACL */
-static BOOL
-add_ace(SEC_ACL **the_acl,
- SEC_ACE *ace,
- TALLOC_CTX *ctx)
+static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace, TALLOC_CTX *ctx)
{
SEC_ACL *newacl;
SEC_ACE *aces;
-
if (! *the_acl) {
(*the_acl) = make_sec_acl(ctx, 3, 1, ace);
return True;
@@ -3903,8 +3685,7 @@ add_ace(SEC_ACL **the_acl,
aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces);
memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE));
memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE));
- newacl = make_sec_acl(ctx, (*the_acl)->revision,
- 1+(*the_acl)->num_aces, aces);
+ newacl = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces);
SAFE_FREE(aces);
(*the_acl) = newacl;
return True;
@@ -3912,19 +3693,17 @@ add_ace(SEC_ACL **the_acl,
/* parse a ascii version of a security descriptor */
-static SEC_DESC *
-sec_desc_parse(TALLOC_CTX *ctx,
- struct cli_state *ipc_cli,
- POLICY_HND *pol,
- BOOL numeric,
- char *str)
+static SEC_DESC *sec_desc_parse(TALLOC_CTX *ctx,
+ struct cli_state *ipc_cli,
+ POLICY_HND *pol,
+ BOOL numeric,
+ char *str)
{
const char *p = str;
fstring tok;
SEC_DESC *ret;
size_t sd_size;
- DOM_SID *grp_sid=NULL;
- DOM_SID *owner_sid=NULL;
+ DOM_SID *grp_sid=NULL, *owner_sid=NULL;
SEC_ACL *dacl=NULL;
int revision=1;
@@ -4024,11 +3803,10 @@ sec_desc_parse(TALLOC_CTX *ctx,
/* Obtain the current dos attributes */
-static DOS_ATTR_DESC *
-dos_attr_query(SMBCCTX *context,
- TALLOC_CTX *ctx,
- const char *filename,
- SMBCSRV *srv)
+static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context,
+ TALLOC_CTX *ctx,
+ const char *filename,
+ SMBCSRV *srv)
{
time_t m_time = 0, a_time = 0, c_time = 0;
SMB_OFF_T size = 0;
@@ -4065,11 +3843,10 @@ dos_attr_query(SMBCCTX *context,
/* parse a ascii version of a security descriptor */
-static void
-dos_attr_parse(SMBCCTX *context,
- DOS_ATTR_DESC *dad,
- SMBCSRV *srv,
- char *str)
+static void dos_attr_parse(SMBCCTX *context,
+ DOS_ATTR_DESC *dad,
+ SMBCSRV *srv,
+ char *str)
{
const char *p = str;
fstring tok;
@@ -4112,16 +3889,9 @@ dos_attr_parse(SMBCCTX *context,
Retrieve the acls for a file.
*******************************************************/
-static int
-cacl_get(SMBCCTX *context,
- TALLOC_CTX *ctx,
- SMBCSRV *srv,
- struct cli_state *ipc_cli,
- POLICY_HND *pol,
- char *filename,
- char *attr_name,
- char *buf,
- int bufsize)
+static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv,
+ struct cli_state *ipc_cli, POLICY_HND *pol,
+ char *filename, char *attr_name, char *buf, int bufsize)
{
uint32 i;
int n = 0;
@@ -4184,9 +3954,7 @@ cacl_get(SMBCCTX *context,
if (all || all_nt || all_dos) {
/* Exclusions are delimited by '!' */
- for (;
- pExclude != NULL;
- pExclude = (p == NULL ? NULL : p + 1)) {
+ for (; pExclude != NULL; pExclude = (p == NULL ? NULL : p + 1)) {
/* Find end of this exclusion name */
if ((p = strchr(pExclude, '!')) != NULL)
@@ -4278,8 +4046,7 @@ cacl_get(SMBCCTX *context,
n = strlen(p);
} else {
n = snprintf(buf, bufsize,
- "REVISION:%d",
- sd->revision);
+ "REVISION:%d", sd->revision);
}
} else if (StrCaseCmp(name, "revision") == 0) {
if (determine_size) {
@@ -4383,8 +4150,7 @@ cacl_get(SMBCCTX *context,
}
n = strlen(p);
} else {
- n = snprintf(buf, bufsize,
- "%s", sidstr);
+ n = snprintf(buf, bufsize, "%s", sidstr);
}
}
@@ -4431,9 +4197,9 @@ cacl_get(SMBCCTX *context,
ace->info.mask);
}
} else if ((StrnCaseCmp(name, "acl", 3) == 0 &&
- StrCaseCmp(name+3, sidstr) == 0) ||
+ StrCaseCmp(name + 3, sidstr) == 0) ||
(StrnCaseCmp(name, "acl+", 4) == 0 &&
- StrCaseCmp(name+4, sidstr) == 0)) {
+ StrCaseCmp(name + 4, sidstr) == 0)) {
if (determine_size) {
p = talloc_asprintf(
ctx,
@@ -4538,8 +4304,7 @@ cacl_get(SMBCCTX *context,
}
n = strlen(p);
} else {
- n = snprintf(buf, bufsize,
- "0x%x", mode);
+ n = snprintf(buf, bufsize, "0x%x", mode);
}
}
@@ -4620,8 +4385,7 @@ cacl_get(SMBCCTX *context,
}
n = strlen(p);
} else {
- n = snprintf(buf, bufsize,
- "%lu", c_time);
+ n = snprintf(buf, bufsize, "%lu", c_time);
}
}
@@ -4658,8 +4422,7 @@ cacl_get(SMBCCTX *context,
}
n = strlen(p);
} else {
- n = snprintf(buf, bufsize,
- "%lu", a_time);
+ n = snprintf(buf, bufsize, "%lu", a_time);
}
}
@@ -4696,8 +4459,7 @@ cacl_get(SMBCCTX *context,
}
n = strlen(p);
} else {
- n = snprintf(buf, bufsize,
- "%lu", m_time);
+ n = snprintf(buf, bufsize, "%lu", m_time);
}
}
@@ -4770,15 +4532,10 @@ cacl_get(SMBCCTX *context,
/*****************************************************
set the ACLs on a file given an ascii description
*******************************************************/
-static int
-cacl_set(TALLOC_CTX *ctx,
- struct cli_state *cli,
- struct cli_state *ipc_cli,
- POLICY_HND *pol,
- const char *filename,
- const char *the_acl,
- int mode,
- int flags)
+static int cacl_set(TALLOC_CTX *ctx, struct cli_state *cli,
+ struct cli_state *ipc_cli, POLICY_HND *pol,
+ const char *filename, const char *the_acl,
+ int mode, int flags)
{
int fnum;
int err = 0;
@@ -4853,8 +4610,7 @@ cacl_set(TALLOC_CTX *ctx,
&old->dacl->ace[j])) {
uint32 k;
for (k=j; k<old->dacl->num_aces-1;k++) {
- old->dacl->ace[k] =
- old->dacl->ace[k+1];
+ old->dacl->ace[k] = old->dacl->ace[k+1];
}
old->dacl->num_aces--;
if (old->dacl->num_aces == 0) {
@@ -4958,23 +4714,18 @@ cacl_set(TALLOC_CTX *ctx,
}
-static int
-smbc_setxattr_ctx(SMBCCTX *context,
- const char *fname,
- const char *name,
- const void *value,
- size_t size,
- int flags)
+int smbc_setxattr_ctx(SMBCCTX *context,
+ const char *fname,
+ const char *name,
+ const void *value,
+ size_t size,
+ int flags)
{
int ret;
int ret2;
SMBCSRV *srv;
SMBCSRV *ipc_srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
+ fstring server, share, user, password, workgroup;
pstring path;
TALLOC_CTX *ctx;
POLICY_HND pol;
@@ -4995,8 +4746,7 @@ smbc_setxattr_ctx(SMBCCTX *context,
}
- DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n",
- fname, name, (int) size, (const char*)value));
+ DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", fname, name, (int) size, (const char*)value));
if (smbc_parse_path(context, fname,
server, sizeof(server),
@@ -5013,8 +4763,7 @@ smbc_setxattr_ctx(SMBCCTX *context,
fstrcpy(workgroup, context->workgroup);
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(context, server, share, workgroup, user, password);
if (!srv) {
return -1; /* errno set by smbc_server */
}
@@ -5041,8 +4790,7 @@ smbc_setxattr_ctx(SMBCCTX *context,
StrCaseCmp(name, "system.*+") == 0) {
/* Yup. */
char *namevalue =
- talloc_asprintf(ctx, "%s:%s",
- name+7, (const char *) value);
+ talloc_asprintf(ctx, "%s:%s", name+7, (const char *) value);
if (! namevalue) {
errno = ENOMEM;
ret = -1;
@@ -5103,8 +4851,7 @@ smbc_setxattr_ctx(SMBCCTX *context,
/* Yup. */
char *namevalue =
- talloc_asprintf(ctx, "%s:%s",
- name+19, (const char *) value);
+ talloc_asprintf(ctx, "%s:%s", name+19, (const char *) value);
if (! ipc_srv) {
ret = -1; /* errno set by smbc_server() */
@@ -5133,8 +4880,7 @@ smbc_setxattr_ctx(SMBCCTX *context,
/* Yup. */
char *namevalue =
- talloc_asprintf(ctx, "%s:%s",
- name+19, (const char *) value);
+ talloc_asprintf(ctx, "%s:%s", name+19, (const char *) value);
if (! ipc_srv) {
@@ -5160,8 +4906,7 @@ smbc_setxattr_ctx(SMBCCTX *context,
/* Yup. */
char *namevalue =
- talloc_asprintf(ctx, "%s:%s",
- name+19, (const char *) value);
+ talloc_asprintf(ctx, "%s:%s", name+19, (const char *) value);
if (! ipc_srv) {
/* errno set by smbc_server() */
@@ -5192,8 +4937,7 @@ smbc_setxattr_ctx(SMBCCTX *context,
dad = dos_attr_query(context, ctx, path, srv);
if (dad) {
char *namevalue =
- talloc_asprintf(ctx, "%s:%s",
- name+16, (const char *) value);
+ talloc_asprintf(ctx, "%s:%s", name+16, (const char *) value);
if (! namevalue) {
errno = ENOMEM;
ret = -1;
@@ -5229,21 +4973,16 @@ smbc_setxattr_ctx(SMBCCTX *context,
return -1;
}
-static int
-smbc_getxattr_ctx(SMBCCTX *context,
- const char *fname,
- const char *name,
- const void *value,
- size_t size)
+int smbc_getxattr_ctx(SMBCCTX *context,
+ const char *fname,
+ const char *name,
+ const void *value,
+ size_t size)
{
int ret;
SMBCSRV *srv;
SMBCSRV *ipc_srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
+ fstring server, share, user, password, workgroup;
pstring path;
TALLOC_CTX *ctx;
POLICY_HND pol;
@@ -5281,8 +5020,7 @@ smbc_getxattr_ctx(SMBCCTX *context,
fstrcpy(workgroup, context->workgroup);
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(context, server, share, workgroup, user, password);
if (!srv) {
return -1; /* errno set by smbc_server */
}
@@ -5349,19 +5087,14 @@ smbc_getxattr_ctx(SMBCCTX *context,
}
-static int
-smbc_removexattr_ctx(SMBCCTX *context,
- const char *fname,
- const char *name)
+int smbc_removexattr_ctx(SMBCCTX *context,
+ const char *fname,
+ const char *name)
{
int ret;
SMBCSRV *srv;
SMBCSRV *ipc_srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
+ fstring server, share, user, password, workgroup;
pstring path;
TALLOC_CTX *ctx;
POLICY_HND pol;
@@ -5398,8 +5131,7 @@ smbc_removexattr_ctx(SMBCCTX *context,
fstrcpy(workgroup, context->workgroup);
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(context, server, share, workgroup, user, password);
if (!srv) {
return -1; /* errno set by smbc_server */
}
@@ -5461,11 +5193,10 @@ smbc_removexattr_ctx(SMBCCTX *context,
return -1;
}
-static int
-smbc_listxattr_ctx(SMBCCTX *context,
- const char *fname,
- char *list,
- size_t size)
+int smbc_listxattr_ctx(SMBCCTX *context,
+ const char *fname,
+ char *list,
+ size_t size)
{
/*
* This isn't quite what listxattr() is supposed to do. This returns
@@ -5511,14 +5242,9 @@ smbc_listxattr_ctx(SMBCCTX *context,
* Open a print file to be written to by other calls
*/
-static SMBCFILE *
-smbc_open_print_job_ctx(SMBCCTX *context,
- const char *fname)
+static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname)
{
- fstring server;
- fstring share;
- fstring user;
- fstring password;
+ fstring server, share, user, password;
pstring path;
if (!context || !context->internal ||
@@ -5562,17 +5288,10 @@ smbc_open_print_job_ctx(SMBCCTX *context,
* copy it to a print file on the share specified by printq.
*/
-static int
-smbc_print_file_ctx(SMBCCTX *c_file,
- const char *fname,
- SMBCCTX *c_print,
- const char *printq)
+static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_print, const char *printq)
{
- SMBCFILE *fid1;
- SMBCFILE *fid2;
- int bytes;
- int saverr;
- int tot_bytes = 0;
+ SMBCFILE *fid1, *fid2;
+ int bytes, saverr, tot_bytes = 0;
char buf[4096];
if (!c_file || !c_file->internal->_initialized || !c_print ||
@@ -5645,17 +5364,10 @@ smbc_print_file_ctx(SMBCCTX *c_file,
* Routine to list print jobs on a printer share ...
*/
-static int
-smbc_list_print_jobs_ctx(SMBCCTX *context,
- const char *fname,
- smbc_list_print_job_fn fn)
+static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_list_print_job_fn fn)
{
SMBCSRV *srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
+ fstring server, share, user, password, workgroup;
pstring path;
if (!context || !context->internal ||
@@ -5690,8 +5402,7 @@ smbc_list_print_jobs_ctx(SMBCCTX *context,
fstrcpy(workgroup, context->workgroup);
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(context, server, share, workgroup, user, password);
if (!srv) {
@@ -5699,8 +5410,7 @@ smbc_list_print_jobs_ctx(SMBCCTX *context,
}
- if (cli_print_queue(&srv->cli,
- (void (*)(struct print_job_info *))fn) < 0) {
+ if (cli_print_queue(&srv->cli, (void (*)(struct print_job_info *))fn) < 0) {
errno = smbc_errno(context, &srv->cli);
return -1;
@@ -5715,17 +5425,10 @@ smbc_list_print_jobs_ctx(SMBCCTX *context,
* Delete a print job from a remote printer share
*/
-static int
-smbc_unlink_print_job_ctx(SMBCCTX *context,
- const char *fname,
- int id)
+static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id)
{
SMBCSRV *srv;
- fstring server;
- fstring share;
- fstring user;
- fstring password;
- fstring workgroup;
+ fstring server, share, user, password, workgroup;
pstring path;
int err;
@@ -5761,8 +5464,7 @@ smbc_unlink_print_job_ctx(SMBCCTX *context,
fstrcpy(workgroup, context->workgroup);
- srv = smbc_server(context, True,
- server, share, workgroup, user, password);
+ srv = smbc_server(context, server, share, workgroup, user, password);
if (!srv) {
@@ -5787,10 +5489,9 @@ smbc_unlink_print_job_ctx(SMBCCTX *context,
/*
* Get a new empty handle to fill in with your own info
*/
-SMBCCTX *
-smbc_new_context(void)
+SMBCCTX * smbc_new_context(void)
{
- SMBCCTX *context;
+ SMBCCTX * context;
context = SMB_MALLOC_P(SMBCCTX);
if (!context) {
@@ -5862,9 +5563,7 @@ smbc_new_context(void)
* and thus you'll be leaking memory if not handled properly.
*
*/
-int
-smbc_free_context(SMBCCTX *context,
- int shutdown_ctx)
+int smbc_free_context(SMBCCTX * context, int shutdown_ctx)
{
if (!context) {
errno = EBADF;
@@ -5886,15 +5585,12 @@ smbc_free_context(SMBCCTX *context,
if (context->callbacks.purge_cached_fn(context)) {
SMBCSRV * s;
SMBCSRV * next;
- DEBUG(1, ("Could not purge all servers, "
- "Nice way shutdown failed.\n"));
+ DEBUG(1, ("Could not purge all servers, Nice way shutdown failed.\n"));
s = context->internal->_servers;
while (s) {
- DEBUG(1, ("Forced shutdown: %p (fd=%d)\n",
- s, s->cli.fd));
+ DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", s, s->cli.fd));
cli_shutdown(&s->cli);
- context->callbacks.remove_cached_srv_fn(context,
- s);
+ context->callbacks.remove_cached_srv_fn(context, s);
next = s->next;
DLIST_REMOVE(context->internal->_servers, s);
SAFE_FREE(s);
@@ -5906,20 +5602,17 @@ smbc_free_context(SMBCCTX *context,
else {
/* This is the polite way */
if (context->callbacks.purge_cached_fn(context)) {
- DEBUG(1, ("Could not purge all servers, "
- "free_context failed.\n"));
+ DEBUG(1, ("Could not purge all servers, free_context failed.\n"));
errno = EBUSY;
return 1;
}
if (context->internal->_servers) {
- DEBUG(1, ("Active servers in context, "
- "free_context failed.\n"));
+ DEBUG(1, ("Active servers in context, free_context failed.\n"));
errno = EBUSY;
return 1;
}
if (context->internal->_files) {
- DEBUG(1, ("Active files in context, "
- "free_context failed.\n"));
+ DEBUG(1, ("Active files in context, free_context failed.\n"));
errno = EBUSY;
return 1;
}
@@ -5938,48 +5631,17 @@ smbc_free_context(SMBCCTX *context,
/*
- * Each time the context structure is changed, we have binary backward
- * compatibility issues. Instead of modifying the public portions of the
- * context structure to add new options, instead, we put them in the internal
- * portion of the context structure and provide a set function for these new
- * options.
- */
-void
-smbc_option_set(SMBCCTX *context,
- char *option_name,
- ...)
-{
- va_list args;
-
- va_start(args, option_name);
-
- if (strcmp(option_name, "debug_stderr") == 0) {
- /*
- * Log to standard error instead of standard output.
- *
- * optional parameters: none (it can't be turned off once on)
- */
- context->internal->_debug_stderr = True;
- }
-
- va_end(args);
-}
-
-
-/*
* Initialise the library etc
*
* We accept a struct containing handle information.
* valid values for info->debug from 0 to 100,
* and insist that info->fn must be non-null.
*/
-SMBCCTX *
-smbc_init_context(SMBCCTX *context)
+SMBCCTX * smbc_init_context(SMBCCTX * context)
{
pstring conf;
int pid;
- char *user = NULL;
- char *home = NULL;
+ char *user = NULL, *home = NULL;
if (!context || !context->internal) {
errno = EBADF;
@@ -5991,9 +5653,7 @@ smbc_init_context(SMBCCTX *context)
return 0;
}
- if (!context->callbacks.auth_fn ||
- context->debug < 0 ||
- context->debug > 100) {
+ if (!context->callbacks.auth_fn || context->debug < 0 || context->debug > 100) {
errno = EINVAL;
return NULL;
@@ -6001,25 +5661,18 @@ smbc_init_context(SMBCCTX *context)
}
if (!smbc_initialized) {
- /*
- * Do some library-wide intializations the first time we get
- * called
- */
+ /* Do some library wide intialisations the first time we get called */
BOOL conf_loaded = False;
/* Set this to what the user wants */
DEBUGLEVEL = context->debug;
- load_case_tables();
-
- setup_logging("libsmbclient", True);
- if (context->internal->_debug_stderr) {
- dbf = x_stderr;
- x_setbuf(x_stderr, NULL);
- }
+ setup_logging( "libsmbclient", True);
/* Here we would open the smb.conf file if needed ... */
+ load_interfaces(); /* Load the list of interfaces ... */
+
in_client = True; /* FIXME, make a param */
home = getenv("HOME");
@@ -6061,8 +5714,6 @@ smbc_init_context(SMBCCTX *context)
}
}
- load_interfaces(); /* Load the list of interfaces ... */
-
reopen_logs(); /* Get logging working ... */
/*
@@ -6088,17 +5739,15 @@ smbc_init_context(SMBCCTX *context)
if (!context->netbios_name) {
/*
- * We try to get our netbios name from the config. If that
- * fails we fall back on constructing our netbios name from
- * our hostname etc
+ * We try to get our netbios name from the config. If that fails we fall
+ * back on constructing our netbios name from our hostname etc
*/
if (global_myname()) {
context->netbios_name = SMB_STRDUP(global_myname());
}
else {
/*
- * Hmmm, I want to get hostname as well, but I am too
- * lazy for the moment
+ * Hmmm, I want to get hostname as well, but I am too lazy for the moment
*/
pid = sys_getpid();
context->netbios_name = SMB_MALLOC(17);
@@ -6106,8 +5755,7 @@ smbc_init_context(SMBCCTX *context)
errno = ENOMEM;
return NULL;
}
- slprintf(context->netbios_name, 16,
- "smbc%s%d", context->user, pid);
+ slprintf(context->netbios_name, 16, "smbc%s%d", context->user, pid);
}
}
@@ -6133,7 +5781,7 @@ smbc_init_context(SMBCCTX *context)
* FIXME: Should we check the function pointers here?
*/
- context->internal->_initialized = True;
+ context->internal->_initialized = 1;
return context;
}
diff --git a/source/libsmb/smb_share_modes.c b/source/libsmb/smb_share_modes.c
index 43f25cd3787..40ccf15f946 100644
--- a/source/libsmb/smb_share_modes.c
+++ b/source/libsmb/smb_share_modes.c
@@ -255,12 +255,11 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
* Create an entry in the Samba share mode db.
*/
-int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
+int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
const struct smb_share_mode_entry *new_entry,
- const char *sharepath, /* Must be absolute utf8 path. */
- const char *filename) /* Must be relative utf8 path. */
+ const char *filename) /* Must be abolute utf8 path. */
{
TDB_DATA db_data;
TDB_DATA locking_key = get_locking_key(dev, ino);
@@ -273,9 +272,7 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
db_data = tdb_fetch(db_ctx->smb_tdb, locking_key);
if (!db_data.dptr) {
/* We must create the entry. */
- db_data.dptr = malloc((2*sizeof(struct share_mode_entry)) +
- strlen(sharepath) + 1 +
- strlen(filename) + 1);
+ db_data.dptr = malloc((2*sizeof(struct share_mode_entry)) + strlen(filename) + 1);
if (!db_data.dptr) {
return -1;
}
@@ -284,18 +281,11 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
ld->u.s.delete_on_close = 0;
shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry));
create_share_mode_entry(shares, new_entry);
-
memcpy(db_data.dptr + 2*sizeof(struct share_mode_entry),
- sharepath,
- strlen(sharepath) + 1);
- memcpy(db_data.dptr + 2*sizeof(struct share_mode_entry) +
- strlen(sharepath) + 1,
filename,
strlen(filename) + 1);
- db_data.dsize = 2*sizeof(struct share_mode_entry) +
- strlen(sharepath) + 1 +
- strlen(filename) + 1;
+ db_data.dsize = 2*sizeof(struct share_mode_entry) + strlen(filename) + 1;
if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_INSERT) == -1) {
free(db_data.dptr);
return -1;
@@ -346,25 +336,6 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
return 0;
}
-/*
- * Create an entry in the Samba share mode db. Original interface - doesn't
- * Distinguish between share path and filename. Fudge this by using a
- * sharepath of / and a relative filename of (filename+1).
- */
-
-int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
- uint64_t dev,
- uint64_t ino,
- const struct smb_share_mode_entry *new_entry,
- const char *filename) /* Must be absolute utf8 path. */
-{
- if (*filename != '/') {
- abort();
- }
- return smb_create_share_mode_entry_ex(db_ctx, dev, ino, new_entry,
- "/", &filename[1]);
-}
-
int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
diff --git a/source/locking/locking.c b/source/locking/locking.c
index d9737895ba1..591d1d0423d 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -464,15 +464,10 @@ static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
}
}
- /* Save off the associated service path and filename. */
- lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
- (lck->num_share_modes *
- sizeof(struct share_mode_entry)));
-
+ /* Save off the associated filename. */
lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
- (lck->num_share_modes *
- sizeof(struct share_mode_entry)) +
- strlen(lck->servicepath) + 1 );
+ lck->num_share_modes *
+ sizeof(struct share_mode_entry));
/*
* Ensure that each entry has a real process attached.
@@ -500,7 +495,6 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
int i;
struct locking_data *data;
ssize_t offset;
- ssize_t sp_len;
result.dptr = NULL;
result.dsize = 0;
@@ -515,11 +509,8 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
return result;
}
- sp_len = strlen(lck->servicepath);
-
result.dsize = sizeof(*data) +
lck->num_share_modes * sizeof(struct share_mode_entry) +
- sp_len + 1 +
strlen(lck->filename) + 1;
result.dptr = talloc_size(lck, result.dsize);
@@ -538,9 +529,6 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
sizeof(struct share_mode_entry)*lck->num_share_modes);
offset = sizeof(*data) +
sizeof(struct share_mode_entry)*lck->num_share_modes;
- safe_strcpy(result.dptr + offset, lck->servicepath,
- result.dsize - offset - 1);
- offset += sp_len + 1;
safe_strcpy(result.dptr + offset, lck->filename,
result.dsize - offset - 1);
print_share_mode_table(data);
@@ -581,9 +569,8 @@ static int share_mode_lock_destructor(void *p)
}
struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
- SMB_DEV_T dev, SMB_INO_T ino,
- const char *servicepath,
- const char *fname)
+ SMB_DEV_T dev, SMB_INO_T ino,
+ const char *fname)
{
struct share_mode_lock *lck;
TDB_DATA key = locking_key(dev, ino);
@@ -598,7 +585,6 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
/* Ensure we set every field here as the destructor must be
valid even if parse_share_modes fails. */
- lck->servicepath = NULL;
lck->filename = NULL;
lck->dev = dev;
lck->ino = ino;
@@ -624,15 +610,13 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
lck->fresh = (data.dptr == NULL);
if (lck->fresh) {
-
- if (fname == NULL || servicepath == NULL) {
- DEBUG(0, ("New file, but no filename or servicepath supplied\n"));
+ if (fname == NULL) {
+ DEBUG(0, ("New file, but no filename supplied\n"));
talloc_free(lck);
return NULL;
}
lck->filename = talloc_strdup(lck, fname);
- lck->servicepath = talloc_strdup(lck, servicepath);
- if (lck->filename == NULL || lck->servicepath == NULL) {
+ if (lck->filename == NULL) {
DEBUG(0, ("talloc failed\n"));
talloc_free(lck);
return NULL;
@@ -651,98 +635,12 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
return lck;
}
-/*******************************************************************
- Sets the service name and filename for rename.
- At this point we emit "file renamed" messages to all
- process id's that have this file open.
- Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
-********************************************************************/
-
-BOOL rename_share_filename(struct share_mode_lock *lck,
- const char *servicepath,
- const char *newname)
-{
- size_t sp_len;
- size_t fn_len;
- size_t msg_len;
- char *frm = NULL;
- int i;
-
- if (!lck) {
- return False;
- }
-
- DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
- servicepath, newname));
-
- /*
- * rename_internal_fsp() and rename_internals() add './' to
- * head of newname if newname does not contain a '/'.
- */
- while (newname[0] && newname[1] && newname[0] == '.' && newname[1] == '/') {
- newname += 2;
- }
-
- lck->servicepath = talloc_strdup(lck, servicepath);
- lck->filename = talloc_strdup(lck, newname);
- if (lck->filename == NULL || lck->servicepath == NULL) {
- DEBUG(0, ("rename_share_filename: talloc failed\n"));
- return False;
- }
- lck->modified = True;
-
- sp_len = strlen(lck->servicepath);
- fn_len = strlen(lck->filename);
-
- msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + fn_len + 1;
-
- /* Set up the name changed message. */
- frm = TALLOC(lck, msg_len);
- if (!frm) {
- return False;
- }
-
- SDEV_T_VAL(frm,0,lck->dev);
- SINO_T_VAL(frm,8,lck->ino);
-
- DEBUG(10,("rename_share_filename: msg_len = %d\n", msg_len ));
-
- safe_strcpy(&frm[16], lck->servicepath, sp_len);
- safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len);
-
- /* Send the messages. */
- for (i=0; i<lck->num_share_modes; i++) {
- struct share_mode_entry *se = &lck->share_modes[i];
- if (!is_valid_share_mode_entry(se)) {
- continue;
- }
- /* But not to ourselves... */
- if (procid_is_me(&se->pid)) {
- continue;
- }
-
- DEBUG(10,("rename_share_filename: sending rename message to pid %u "
- "dev %x, inode %.0f sharepath %s newname %s\n",
- (unsigned int)procid_to_pid(&se->pid),
- (unsigned int)lck->dev, (double)lck->ino,
- lck->servicepath, lck->filename ));
-
- become_root();
- message_send_pid(se->pid, MSG_SMB_FILE_RENAME,
- frm, msg_len, True);
- unbecome_root();
- }
-
- return True;
-}
-
-BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode)
+BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode,
+ const char *fname)
{
BOOL result;
- struct share_mode_lock *lck = get_share_mode_lock(NULL, dev, inode, NULL, NULL);
- if (!lck) {
- return False;
- }
+ struct share_mode_lock *lck = get_share_mode_lock(NULL, dev, inode,
+ fname);
result = lck->delete_on_close;
talloc_free(lck);
return result;
@@ -1076,7 +974,7 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close)
return True;
}
- lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
+ lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
if (lck == NULL) {
return False;
}
@@ -1094,10 +992,9 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
{
struct locking_data *data;
struct share_mode_entry *shares;
- const char *sharepath;
- const char *fname;
+ char *name;
int i;
- void (*traverse_callback)(struct share_mode_entry *, const char *, const char *) = state;
+ void (*traverse_callback)(struct share_mode_entry *, char *) = state;
/* Ensure this is a locking_key record. */
if (kbuf.dsize != sizeof(struct locking_key))
@@ -1105,14 +1002,11 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
data = (struct locking_data *)dbuf.dptr;
shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data));
- sharepath = dbuf.dptr + sizeof(*data) +
+ name = dbuf.dptr + sizeof(*data) +
data->u.s.num_share_mode_entries*sizeof(*shares);
- fname = dbuf.dptr + sizeof(*data) +
- data->u.s.num_share_mode_entries*sizeof(*shares) +
- strlen(sharepath) + 1;
for (i=0;i<data->u.s.num_share_mode_entries;i++) {
- traverse_callback(&shares[i], sharepath, fname);
+ traverse_callback(&shares[i], name);
}
return 0;
}
@@ -1122,7 +1016,7 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
share mode system.
********************************************************************/
-int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, const char *))
+int share_mode_forall(void (*fn)(const struct share_mode_entry *, char *))
{
if (tdb == NULL)
return 0;
diff --git a/source/modules/vfs_afsacl.c b/source/modules/vfs_afsacl.c
index 3794299b9a0..41f40d1e3c4 100644
--- a/source/modules/vfs_afsacl.c
+++ b/source/modules/vfs_afsacl.c
@@ -105,6 +105,27 @@ static struct afs_ace *clone_afs_ace(TALLOC_CTX *mem_ctx, struct afs_ace *ace)
return result;
}
+
+/* Ok, this is sort-of a hack. We assume here that we have winbind users in
+ * AFS. And yet another copy of parse_domain_user.... */
+
+static BOOL parse_domain_user(const char *domuser, fstring domain,
+ fstring user)
+{
+ char *p = strchr(domuser,*lp_winbind_separator());
+
+ if (p==NULL) {
+ return False;
+ }
+
+ fstrcpy(user, p+1);
+ fstrcpy(domain, domuser);
+ domain[PTR_DIFF(p, domuser)] = 0;
+ strupper_m(domain);
+
+ return True;
+}
+
static struct afs_ace *new_afs_ace(TALLOC_CTX *mem_ctx,
BOOL positive,
const char *name, uint32 rights)
@@ -147,16 +168,14 @@ static struct afs_ace *new_afs_ace(TALLOC_CTX *mem_ctx,
} else {
- fstring domain, uname;
- char *p;
+ fstring user, domain;
- p = strchr_m(name, lp_winbind_separator());
- if (p != NULL) {
- *p = '\\';
+ if (!parse_domain_user(name, domain, user)) {
+ fstrcpy(user, name);
+ fstrcpy(domain, lp_workgroup());
}
-
- if (!lookup_name(name, LOOKUP_NAME_FULL,
- domain, uname, &sid, &type)) {
+
+ if (!lookup_name(domain, user, &sid, &type)) {
DEBUG(10, ("Could not find AFS user %s\n", name));
sid_copy(&sid, &global_sid_NULL);
diff --git a/source/nmbd/asyncdns.c b/source/nmbd/asyncdns.c
index c8caa3fee29..4db54ea198c 100644
--- a/source/nmbd/asyncdns.c
+++ b/source/nmbd/asyncdns.c
@@ -34,18 +34,16 @@ static struct name_record *add_dns_result(struct nmb_name *question, struct in_a
if (!addr.s_addr) {
/* add the fail to WINS cache of names. give it 1 hour in the cache */
DEBUG(3,("add_dns_result: Negative DNS answer for %s\n", qname));
- add_name_to_subnet( wins_server_subnet, qname, name_type,
+ (void)add_name_to_subnet( wins_server_subnet, qname, name_type,
NB_ACTIVE, 60*60, DNSFAIL_NAME, 1, &addr );
- return NULL;
+ return( NULL );
}
/* add it to our WINS cache of names. give it 2 hours in the cache */
DEBUG(3,("add_dns_result: DNS gave answer for %s of %s\n", qname, inet_ntoa(addr)));
- add_name_to_subnet( wins_server_subnet, qname, name_type,
- NB_ACTIVE, 2*60*60, DNS_NAME, 1, &addr);
-
- return find_name_on_subnet(wins_server_subnet, question, FIND_ANY_NAME);
+ return( add_name_to_subnet( wins_server_subnet, qname, name_type,
+ NB_ACTIVE, 2*60*60, DNS_NAME, 1, &addr ) );
}
#ifndef SYNC_DNS
@@ -285,7 +283,8 @@ void run_dns_queue(void)
queue a DNS query
****************************************************************************/
-BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question)
+BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
+ struct name_record **n)
{
if (in_dns || fd_in == -1)
return False;
@@ -317,13 +316,13 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question)
we use this when we can't do async DNS lookups
****************************************************************************/
-BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question)
+BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
+ struct name_record **n)
{
- struct name_record *namerec = NULL;
struct in_addr dns_ip;
unstring qname;
- pull_ascii_nstring(qname, sizeof(qname), question->name);
+ pull_ascii_nstring(qname, question->name);
DEBUG(3,("DNS search for %s - ", nmb_namestr(question)));
@@ -335,12 +334,11 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question)
/* Re-block TERM signal. */
BlockSignals(True, SIGTERM);
- namerec = add_dns_result(question, dns_ip);
- if(namerec == NULL) {
+ *n = add_dns_result(question, dns_ip);
+ if(*n == NULL)
send_wins_name_query_response(NAM_ERR, p, NULL);
- } else {
- send_wins_name_query_response(0, p, namerec);
- }
+ else
+ send_wins_name_query_response(0, p, *n);
return False;
}
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index ea7e9a5288f..e9d7f8d1851 100644
--- a/source/nmbd/nmbd.c
+++ b/source/nmbd/nmbd.c
@@ -58,7 +58,7 @@ static void terminate(void)
DEBUG(0,("Got SIGTERM: going down...\n"));
/* Write out wins.dat file if samba is a WINS server */
- wins_write_database(0,False);
+ wins_write_database(False);
/* Remove all SELF registered names from WINS */
release_wins_names();
@@ -670,8 +670,6 @@ static BOOL open_sockets(BOOL isdaemon, int port)
{ NULL }
};
- load_case_tables();
-
global_nmb_port = NMB_PORT;
pc = poptGetContext("nmbd", argc, argv, long_options, 0);
diff --git a/source/nmbd/nmbd_browserdb.c b/source/nmbd/nmbd_browserdb.c
index e27e483702a..e8797a99d51 100644
--- a/source/nmbd/nmbd_browserdb.c
+++ b/source/nmbd/nmbd_browserdb.c
@@ -35,7 +35,7 @@
* lmb_browserlist - This is our local master browser list.
*/
-struct browse_cache_record *lmb_browserlist;
+ubi_dlNewList( lmb_browserlist );
/* -------------------------------------------------------------------------- **
* Functions...
@@ -52,8 +52,7 @@ struct browse_cache_record *lmb_browserlist;
*/
static void remove_lmb_browser_entry( struct browse_cache_record *browc )
{
- DLIST_REMOVE(lmb_browserlist, browc);
- SAFE_FREE(browc);
+ safe_free( ubi_dlRemThis( lmb_browserlist, browc ) );
}
/* ************************************************************************** **
@@ -86,7 +85,6 @@ struct browse_cache_record *create_browser_in_lmb_cache( const char *work_name,
struct in_addr ip )
{
struct browse_cache_record *browc;
- struct browse_cache_record *tmp_browc;
time_t now = time( NULL );
browc = SMB_MALLOC_P(struct browse_cache_record);
@@ -115,7 +113,7 @@ struct browse_cache_record *create_browser_in_lmb_cache( const char *work_name,
browc->ip = ip;
- DLIST_ADD_END(lmb_browserlist, browc, tmp_browc);
+ (void)ubi_dlAddTail( lmb_browserlist, browc );
if( DEBUGLVL( 3 ) ) {
Debug1( "nmbd_browserdb:create_browser_in_lmb_cache()\n" );
@@ -140,13 +138,12 @@ struct browse_cache_record *find_browser_in_lmb_cache( const char *browser_name
{
struct browse_cache_record *browc;
- for( browc = lmb_browserlist; browc; browc = browc->next ) {
- if( strequal( browser_name, browc->lmb_name ) ) {
+ for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
+ browc; browc = (struct browse_cache_record *)ubi_dlNext( browc ) )
+ if( strequal( browser_name, browc->lmb_name ) )
break;
- }
- }
- return browc;
+ return( browc );
}
/* ************************************************************************** **
@@ -163,8 +160,9 @@ void expire_lmb_browsers( time_t t )
struct browse_cache_record *browc;
struct browse_cache_record *nextbrowc;
- for( browc = lmb_browserlist; browc; browc = nextbrowc) {
- nextbrowc = browc->next;
+ for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
+ browc; browc = nextbrowc ) {
+ nextbrowc = (struct browse_cache_record *)ubi_dlNext( browc );
if( browc->death_time < t ) {
if( DEBUGLVL( 3 ) ) {
diff --git a/source/nmbd/nmbd_browsesync.c b/source/nmbd/nmbd_browsesync.c
index 9535a3115a6..03234bb98fa 100644
--- a/source/nmbd/nmbd_browsesync.c
+++ b/source/nmbd/nmbd_browsesync.c
@@ -24,7 +24,7 @@
#include "includes.h"
/* This is our local master browser list database. */
-extern struct browse_cache_record *lmb_browserlist;
+extern ubi_dlList lmb_browserlist[];
/****************************************************************************
As a domain master browser, do a sync with a local master browser.
@@ -87,7 +87,9 @@ void dmb_expire_and_sync_browser_lists(time_t t)
expire_lmb_browsers(t);
- for( browc = lmb_browserlist; browc; browc = browc->next ) {
+ for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist );
+ browc;
+ browc = (struct browse_cache_record *)ubi_dlNext( browc ) ) {
if (browc->sync_time < t)
sync_with_lmb(browc);
}
diff --git a/source/nmbd/nmbd_incomingrequests.c b/source/nmbd/nmbd_incomingrequests.c
index eaef7097b4a..7fac8c25739 100644
--- a/source/nmbd/nmbd_incomingrequests.c
+++ b/source/nmbd/nmbd_incomingrequests.c
@@ -339,7 +339,7 @@ subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
names_added = 0;
- namerec = subrec->namelist;
+ namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
while (buf < bufend) {
if( (namerec->data.source == SELF_NAME) || (namerec->data.source == PERMANENT_NAME) ) {
@@ -389,7 +389,7 @@ subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
buf = buf0 + 18*names_added;
- namerec = namerec->next;
+ namerec = (struct name_record *)ubi_trNext( namerec );
if (!namerec) {
/* End of the subnet specific name list. Now
@@ -398,7 +398,7 @@ subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
if (uni_subrec != subrec) {
subrec = uni_subrec;
- namerec = subrec->namelist;
+ namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
}
}
if (!namerec)
diff --git a/source/nmbd/nmbd_mynames.c b/source/nmbd/nmbd_mynames.c
index f34d98172c6..07247d5495e 100644
--- a/source/nmbd/nmbd_mynames.c
+++ b/source/nmbd/nmbd_mynames.c
@@ -182,8 +182,8 @@ void release_wins_names(void)
struct subnet_record *subrec = unicast_subnet;
struct name_record *namerec, *nextnamerec;
- for (namerec = subrec->namelist; namerec; namerec = nextnamerec) {
- nextnamerec = namerec->next;
+ for (namerec = (struct name_record *)ubi_trFirst( subrec->namelist ); namerec; namerec = nextnamerec) {
+ nextnamerec = (struct name_record *)ubi_trNext( namerec );
if( (namerec->data.source == SELF_NAME)
&& !NAME_IS_DEREGISTERING(namerec) )
release_name( subrec, namerec, standard_success_release,
@@ -202,7 +202,9 @@ void refresh_my_names(time_t t)
if (wins_srv_count() < 1)
return;
- for (namerec = unicast_subnet->namelist; namerec; namerec = namerec->next) {
+ for (namerec = (struct name_record *)ubi_trFirst(unicast_subnet->namelist);
+ namerec;
+ namerec = (struct name_record *)ubi_trNext(namerec)) {
/* Each SELF name has an individual time to be refreshed. */
if ((namerec->data.source == SELF_NAME) &&
(namerec->data.refresh_time < t) &&
diff --git a/source/nmbd/nmbd_namelistdb.c b/source/nmbd/nmbd_namelistdb.c
index 60023a7ed5e..344d3c7ca19 100644
--- a/source/nmbd/nmbd_namelistdb.c
+++ b/source/nmbd/nmbd_namelistdb.c
@@ -32,26 +32,24 @@ uint16 samba_nb_type = 0; /* samba's NetBIOS name type */
void set_samba_nb_type(void)
{
- if( lp_wins_support() || wins_srv_count() ) {
+ if( lp_wins_support() || wins_srv_count() )
samba_nb_type = NB_HFLAG; /* samba is a 'hybrid' node type. */
- } else {
+ else
samba_nb_type = NB_BFLAG; /* samba is broadcast-only node type. */
- }
}
/***************************************************************************
Convert a NetBIOS name to upper case.
***************************************************************************/
-static void upcase_name( struct nmb_name *target, const struct nmb_name *source )
+static void upcase_name( struct nmb_name *target, struct nmb_name *source )
{
int i;
unstring targ;
fstring scope;
- if( NULL != source ) {
+ if( NULL != source )
memcpy( target, source, sizeof( struct nmb_name ) );
- }
pull_ascii_nstring(targ, sizeof(targ), target->name);
strupper_m( targ );
@@ -65,94 +63,90 @@ static void upcase_name( struct nmb_name *target, const struct nmb_name *source
* unused space doesn't have garbage in it.
*/
- for( i = strlen( target->name ); i < sizeof( target->name ); i++ ) {
+ for( i = strlen( target->name ); i < sizeof( target->name ); i++ )
target->name[i] = '\0';
- }
- for( i = strlen( target->scope ); i < sizeof( target->scope ); i++ ) {
+ for( i = strlen( target->scope ); i < sizeof( target->scope ); i++ )
target->scope[i] = '\0';
- }
}
/**************************************************************************
- Remove a name from the namelist.
+ Add a new or overwrite an existing namelist entry.
***************************************************************************/
-void remove_name_from_namelist(struct subnet_record *subrec,
- struct name_record *namerec )
+static void update_name_in_namelist( struct subnet_record *subrec,
+ struct name_record *namerec )
{
- if (subrec == wins_server_subnet)
- remove_name_from_wins_namelist(namerec);
- else {
- subrec->namelist_changed = True;
- DLIST_REMOVE(subrec->namelist, namerec);
+ struct name_record *oldrec = NULL;
+
+ ubi_trInsert( subrec->namelist, namerec, &(namerec->name), &oldrec );
+ if( oldrec ) {
+ SAFE_FREE( oldrec->data.ip );
+ SAFE_FREE( oldrec );
}
+}
+
+/**************************************************************************
+ Remove a name from the namelist.
+***************************************************************************/
+void remove_name_from_namelist( struct subnet_record *subrec,
+ struct name_record *namerec )
+{
+ ubi_trRemove( subrec->namelist, namerec );
SAFE_FREE(namerec->data.ip);
ZERO_STRUCTP(namerec);
SAFE_FREE(namerec);
+ subrec->namelist_changed = True;
}
/**************************************************************************
Find a name in a subnet.
**************************************************************************/
-struct name_record *find_name_on_subnet(struct subnet_record *subrec,
- const struct nmb_name *nmbname,
- BOOL self_only)
+struct name_record *find_name_on_subnet( struct subnet_record *subrec,
+ struct nmb_name *nmbname,
+ BOOL self_only )
{
- struct nmb_name uc_name;
+ struct nmb_name uc_name[1];
struct name_record *name_ret;
- upcase_name( &uc_name, nmbname );
-
- if (subrec == wins_server_subnet) {
- return find_name_on_wins_subnet(&uc_name, self_only);
- }
-
- for( name_ret = subrec->namelist; name_ret; name_ret = name_ret->next) {
- if (memcmp(&uc_name, &name_ret->name, sizeof(struct nmb_name)) == 0) {
- break;
- }
- }
-
+ upcase_name( uc_name, nmbname );
+ name_ret = (struct name_record *)ubi_trFind( subrec->namelist, uc_name );
if( name_ret ) {
/* Self names only - these include permanent names. */
if( self_only && (name_ret->data.source != SELF_NAME) && (name_ret->data.source != PERMANENT_NAME) ) {
DEBUG( 9, ( "find_name_on_subnet: on subnet %s - self name %s NOT FOUND\n",
subrec->subnet_name, nmb_namestr(nmbname) ) );
- return False;
+ return( NULL );
}
DEBUG( 9, ("find_name_on_subnet: on subnet %s - found name %s source=%d\n",
subrec->subnet_name, nmb_namestr(nmbname), name_ret->data.source) );
-
- return name_ret;
+ return( name_ret );
}
DEBUG( 9, ( "find_name_on_subnet: on subnet %s - name %s NOT FOUND\n",
subrec->subnet_name, nmb_namestr(nmbname) ) );
-
- return NULL;
+ return( NULL );
}
/**************************************************************************
Find a name over all known broadcast subnets.
************************************************************************/
-struct name_record *find_name_for_remote_broadcast_subnet(struct nmb_name *nmbname,
- BOOL self_only)
+struct name_record *find_name_for_remote_broadcast_subnet(
+ struct nmb_name *nmbname,
+ BOOL self_only )
{
struct subnet_record *subrec;
- struct name_record *namerec;
+ struct name_record *namerec = NULL;
for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) ) {
- namerec = find_name_on_subnet(subrec, nmbname, self_only);
- if (namerec) {
- return namerec;
- }
+ if( NULL != (namerec = find_name_on_subnet(subrec, nmbname, self_only)) )
+ break;
}
- return NULL;
+ return( namerec );
}
/**************************************************************************
@@ -163,40 +157,34 @@ void update_name_ttl( struct name_record *namerec, int ttl )
{
time_t time_now = time(NULL);
- if( namerec->data.death_time != PERMANENT_TTL) {
+ if( namerec->data.death_time != PERMANENT_TTL )
namerec->data.death_time = time_now + ttl;
- }
namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);
- if (namerec->subnet == wins_server_subnet) {
- wins_store_changed_namerec(namerec);
- } else {
- namerec->subnet->namelist_changed = True;
- }
+ namerec->subnet->namelist_changed = True;
}
/**************************************************************************
Add an entry to a subnet name list.
***********************************************************************/
-BOOL add_name_to_subnet( struct subnet_record *subrec,
- const char *name,
- int type,
- uint16 nb_flags,
- int ttl,
- enum name_source source,
- int num_ips,
- struct in_addr *iplist)
+struct name_record *add_name_to_subnet( struct subnet_record *subrec,
+ const char *name,
+ int type,
+ uint16 nb_flags,
+ int ttl,
+ enum name_source source,
+ int num_ips,
+ struct in_addr *iplist)
{
- BOOL ret = False;
struct name_record *namerec;
time_t time_now = time(NULL);
namerec = SMB_MALLOC_P(struct name_record);
if( NULL == namerec ) {
DEBUG( 0, ( "add_name_to_subnet: malloc fail.\n" ) );
- return False;
+ return( NULL );
}
memset( (char *)namerec, '\0', sizeof(*namerec) );
@@ -205,7 +193,7 @@ BOOL add_name_to_subnet( struct subnet_record *subrec,
DEBUG( 0, ( "add_name_to_subnet: malloc fail when creating ip_flgs.\n" ) );
ZERO_STRUCTP(namerec);
SAFE_FREE(namerec);
- return False;
+ return NULL;
}
namerec->subnet = subrec;
@@ -218,9 +206,8 @@ BOOL add_name_to_subnet( struct subnet_record *subrec,
namerec->data.wins_flags = WINS_ACTIVE;
/* If it's our primary name, flag it as so. */
- if (strequal( my_netbios_names(0), name )) {
+ if( strequal( my_netbios_names(0), name ) )
namerec->data.nb_flags |= NB_PERM;
- }
/* Copy the IPs. */
namerec->data.num_ips = num_ips;
@@ -230,14 +217,16 @@ BOOL add_name_to_subnet( struct subnet_record *subrec,
namerec->data.source = source;
/* Setup the death_time and refresh_time. */
- if (ttl == PERMANENT_TTL) {
+ if( ttl == PERMANENT_TTL )
namerec->data.death_time = PERMANENT_TTL;
- } else {
+ else
namerec->data.death_time = time_now + ttl;
- }
namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);
+ /* Now add the record to the name list. */
+ update_name_in_namelist( subrec, namerec );
+
DEBUG( 3, ( "add_name_to_subnet: Added netbios name %s with first IP %s \
ttl=%d nb_flags=%2x to subnet %s\n",
nmb_namestr( &namerec->name ),
@@ -246,20 +235,9 @@ ttl=%d nb_flags=%2x to subnet %s\n",
(unsigned int)nb_flags,
subrec->subnet_name ) );
- /* Now add the record to the name list. */
-
- if (subrec == wins_server_subnet) {
- ret = add_name_to_wins_subnet(namerec);
- /* Free namerec - it's stored in the tdb. */
- SAFE_FREE(namerec->data.ip);
- SAFE_FREE(namerec);
- } else {
- DLIST_ADD(subrec->namelist, namerec);
- subrec->namelist_changed = True;
- ret = True;
- }
+ subrec->namelist_changed = True;
- return ret;
+ return(namerec);
}
/*******************************************************************
@@ -275,8 +253,8 @@ void standard_success_register(struct subnet_record *subrec,
{
struct name_record *namerec;
- namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME);
- if (namerec == NULL) {
+ namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME );
+ if( NULL == namerec ) {
unstring name;
pull_ascii_nstring(name, sizeof(name), nmbname->name);
add_name_to_subnet( subrec, name, nmbname->name_type,
@@ -299,15 +277,14 @@ void standard_fail_register( struct subnet_record *subrec,
{
struct name_record *namerec;
- namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME);
+ namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME );
DEBUG( 0, ( "standard_fail_register: Failed to register/refresh name %s \
on subnet %s\n", nmb_namestr(nmbname), subrec->subnet_name) );
/* Remove the name from the subnet. */
- if( namerec ) {
+ if( namerec )
remove_name_from_namelist(subrec, namerec);
- }
}
/*******************************************************************
@@ -316,18 +293,13 @@ on subnet %s\n", nmb_namestr(nmbname), subrec->subnet_name) );
static void remove_nth_ip_in_record( struct name_record *namerec, int ind)
{
- if( ind != namerec->data.num_ips ) {
+ if( ind != namerec->data.num_ips )
memmove( (char *)(&namerec->data.ip[ind]),
(char *)(&namerec->data.ip[ind+1]),
( namerec->data.num_ips - ind - 1) * sizeof(struct in_addr) );
- }
namerec->data.num_ips--;
- if (namerec->subnet == wins_server_subnet) {
- wins_store_changed_namerec(namerec);
- } else {
- namerec->subnet->namelist_changed = True;
- }
+ namerec->subnet->namelist_changed = True;
}
/*******************************************************************
@@ -338,11 +310,9 @@ BOOL find_ip_in_name_record( struct name_record *namerec, struct in_addr ip )
{
int i;
- for(i = 0; i < namerec->data.num_ips; i++) {
- if(ip_equal( namerec->data.ip[i], ip)) {
+ for(i = 0; i < namerec->data.num_ips; i++)
+ if(ip_equal( namerec->data.ip[i], ip))
return True;
- }
- }
return False;
}
@@ -356,9 +326,8 @@ void add_ip_to_name_record( struct name_record *namerec, struct in_addr new_ip )
struct in_addr *new_list;
/* Don't add one we already have. */
- if( find_ip_in_name_record( namerec, new_ip )) {
+ if( find_ip_in_name_record( namerec, new_ip ) )
return;
- }
new_list = SMB_MALLOC_ARRAY( struct in_addr, namerec->data.num_ips + 1);
if( NULL == new_list ) {
@@ -373,11 +342,7 @@ void add_ip_to_name_record( struct name_record *namerec, struct in_addr new_ip )
namerec->data.ip = new_list;
namerec->data.num_ips += 1;
- if (namerec->subnet == wins_server_subnet) {
- wins_store_changed_namerec(namerec);
- } else {
- namerec->subnet->namelist_changed = True;
- }
+ namerec->subnet->namelist_changed = True;
}
/*******************************************************************
@@ -423,29 +388,26 @@ on subnet %s. Name was not found on subnet.\n", nmb_namestr(nmbname), inet_ntoa(
remove_ip_from_name_record( namerec, released_ip );
- if( namerec->data.num_ips == orig_num ) {
+ if( namerec->data.num_ips == orig_num )
DEBUG( 0, ( "standard_success_release: Name release for name %s IP %s \
on subnet %s. This ip is not known for this name.\n", nmb_namestr(nmbname), inet_ntoa(released_ip), subrec->subnet_name ) );
- }
}
- if( namerec->data.num_ips == 0 ) {
+ if( namerec->data.num_ips == 0 )
remove_name_from_namelist( subrec, namerec );
- }
}
/*******************************************************************
- Expires old names in a subnet namelist.
- NB. Does not touch the wins_subnet - no wins specific processing here.
+ Expires old names in a subnet namelist.
******************************************************************/
-static void expire_names_on_subnet(struct subnet_record *subrec, time_t t)
+void expire_names_on_subnet(struct subnet_record *subrec, time_t t)
{
struct name_record *namerec;
struct name_record *next_namerec;
- for( namerec = subrec->namelist; namerec; namerec = next_namerec ) {
- next_namerec = namerec->next;
+ for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist ); namerec; namerec = next_namerec ) {
+ next_namerec = (struct name_record *)ubi_trNext( namerec );
if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < t) ) {
if( namerec->data.source == SELF_NAME ) {
DEBUG( 3, ( "expire_names_on_subnet: Subnet %s not expiring SELF \
@@ -458,14 +420,13 @@ name %s\n", subrec->subnet_name, nmb_namestr(&namerec->name) ) );
DEBUG(3,("expire_names_on_subnet: Subnet %s - removing expired name %s\n",
subrec->subnet_name, nmb_namestr(&namerec->name)));
- remove_name_from_namelist(subrec, namerec );
+ remove_name_from_namelist( subrec, namerec );
}
}
}
/*******************************************************************
- Expires old names in all subnet namelists.
- NB. Does not touch the wins_subnet.
+ Expires old names in all subnet namelists.
******************************************************************/
void expire_names(time_t t)
@@ -518,85 +479,75 @@ void add_samba_names_to_subnet( struct subnet_record *subrec )
add_name_to_subnet(subrec,"__SAMBA__",0x00,samba_nb_type,PERMANENT_TTL,
PERMANENT_NAME, num_ips, iplist);
- if(iplist != &subrec->myip) {
+ if(iplist != &subrec->myip)
SAFE_FREE(iplist);
- }
}
/****************************************************************************
- Dump a name_record struct.
+ Dump the contents of the namelists on all the subnets (including unicast)
+ into a file. Initiated by SIGHUP - used to debug the state of the namelists.
**************************************************************************/
-void dump_name_record( struct name_record *namerec, XFILE *fp)
+static void dump_subnet_namelist( struct subnet_record *subrec, XFILE *fp)
{
+ struct name_record *namerec;
const char *src_type;
struct tm *tm;
int i;
- x_fprintf(fp,"\tName = %s\t", nmb_namestr(&namerec->name));
- switch(namerec->data.source) {
- case LMHOSTS_NAME:
- src_type = "LMHOSTS_NAME";
- break;
- case WINS_PROXY_NAME:
- src_type = "WINS_PROXY_NAME";
- break;
- case REGISTER_NAME:
- src_type = "REGISTER_NAME";
- break;
- case SELF_NAME:
- src_type = "SELF_NAME";
- break;
- case DNS_NAME:
- src_type = "DNS_NAME";
- break;
- case DNSFAIL_NAME:
- src_type = "DNSFAIL_NAME";
- break;
- case PERMANENT_NAME:
- src_type = "PERMANENT_NAME";
- break;
- default:
- src_type = "unknown!";
- break;
- }
-
- x_fprintf(fp,"Source = %s\nb_flags = %x\t", src_type, namerec->data.nb_flags);
-
- if(namerec->data.death_time != PERMANENT_TTL) {
- tm = localtime(&namerec->data.death_time);
- x_fprintf(fp, "death_time = %s\t", asctime(tm));
- } else {
- x_fprintf(fp, "death_time = PERMANENT\t");
- }
+ x_fprintf(fp, "Subnet %s\n----------------------\n", subrec->subnet_name);
+ for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist ); namerec;
+ namerec = (struct name_record *)ubi_trNext( namerec ) ) {
+
+ x_fprintf(fp,"\tName = %s\t", nmb_namestr(&namerec->name));
+ switch(namerec->data.source) {
+ case LMHOSTS_NAME:
+ src_type = "LMHOSTS_NAME";
+ break;
+ case WINS_PROXY_NAME:
+ src_type = "WINS_PROXY_NAME";
+ break;
+ case REGISTER_NAME:
+ src_type = "REGISTER_NAME";
+ break;
+ case SELF_NAME:
+ src_type = "SELF_NAME";
+ break;
+ case DNS_NAME:
+ src_type = "DNS_NAME";
+ break;
+ case DNSFAIL_NAME:
+ src_type = "DNSFAIL_NAME";
+ break;
+ case PERMANENT_NAME:
+ src_type = "PERMANENT_NAME";
+ break;
+ default:
+ src_type = "unknown!";
+ break;
+ }
- if(namerec->data.refresh_time != PERMANENT_TTL) {
- tm = localtime(&namerec->data.refresh_time);
- x_fprintf(fp, "refresh_time = %s\n", asctime(tm));
- } else {
- x_fprintf(fp, "refresh_time = PERMANENT\n");
- }
+ x_fprintf(fp,"Source = %s\nb_flags = %x\t", src_type, namerec->data.nb_flags);
- x_fprintf(fp, "\t\tnumber of IPS = %d", namerec->data.num_ips);
- for(i = 0; i < namerec->data.num_ips; i++) {
- x_fprintf(fp, "\t%s", inet_ntoa(namerec->data.ip[i]));
- }
+ if(namerec->data.death_time != PERMANENT_TTL) {
+ tm = localtime(&namerec->data.death_time);
+ x_fprintf(fp, "death_time = %s\t", asctime(tm));
+ } else {
+ x_fprintf(fp, "death_time = PERMANENT\t");
+ }
- x_fprintf(fp, "\n\n");
-
-}
+ if(namerec->data.refresh_time != PERMANENT_TTL) {
+ tm = localtime(&namerec->data.refresh_time);
+ x_fprintf(fp, "refresh_time = %s\n", asctime(tm));
+ } else {
+ x_fprintf(fp, "refresh_time = PERMANENT\n");
+ }
-/****************************************************************************
- Dump the contents of the namelists on all the subnets (including unicast)
- into a file. Initiated by SIGHUP - used to debug the state of the namelists.
-**************************************************************************/
+ x_fprintf(fp, "\t\tnumber of IPS = %d", namerec->data.num_ips);
+ for(i = 0; i < namerec->data.num_ips; i++)
+ x_fprintf(fp, "\t%s", inet_ntoa(namerec->data.ip[i]));
-static void dump_subnet_namelist( struct subnet_record *subrec, XFILE *fp)
-{
- struct name_record *namerec;
- x_fprintf(fp, "Subnet %s\n----------------------\n", subrec->subnet_name);
- for( namerec = subrec->namelist; namerec; namerec = namerec->next) {
- dump_name_record(namerec, fp);
+ x_fprintf(fp, "\n\n");
}
}
@@ -618,21 +569,16 @@ void dump_all_namelists(void)
return;
}
- for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) {
+ for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec) )
dump_subnet_namelist( subrec, fp );
- }
- if (!we_are_a_wins_client()) {
+ if( !we_are_a_wins_client() )
dump_subnet_namelist( unicast_subnet, fp );
- }
- if (remote_broadcast_subnet->namelist != NULL) {
+ if( remote_broadcast_subnet->namelist != NULL )
dump_subnet_namelist( remote_broadcast_subnet, fp );
- }
-
- if (wins_server_subnet != NULL) {
- dump_wins_subnet_namelist(fp );
- }
+ if( wins_server_subnet != NULL )
+ dump_subnet_namelist( wins_server_subnet, fp );
x_fclose( fp );
}
diff --git a/source/nmbd/nmbd_subnetdb.c b/source/nmbd/nmbd_subnetdb.c
index b2e1178bebc..b53a6d7328f 100644
--- a/source/nmbd/nmbd_subnetdb.c
+++ b/source/nmbd/nmbd_subnetdb.c
@@ -51,6 +51,34 @@ static void add_subnet(struct subnet_record *subrec)
DLIST_ADD(subnetlist, subrec);
}
+/* ************************************************************************** **
+ * Comparison routine for ordering the splay-tree based namelists assoicated
+ * with each subnet record.
+ *
+ * Input: Item - Pointer to the comparison key.
+ * Node - Pointer to a node the splay tree.
+ *
+ * Output: The return value will be <0 , ==0, or >0 depending upon the
+ * ordinal relationship of the two keys.
+ *
+ * ************************************************************************** **
+ */
+static int namelist_entry_compare( ubi_trItemPtr Item, ubi_trNodePtr Node )
+{
+ struct name_record *NR = (struct name_record *)Node;
+
+ if( DEBUGLVL( 10 ) ) {
+ struct nmb_name *Iname = (struct nmb_name *)Item;
+
+ Debug1( "nmbd_subnetdb:namelist_entry_compare()\n" );
+ Debug1( "%d == memcmp( \"%s\", \"%s\", %d )\n",
+ memcmp( Item, &(NR->name), sizeof(struct nmb_name) ),
+ nmb_namestr(Iname), nmb_namestr(&NR->name), (int)sizeof(struct nmb_name) );
+ }
+
+ return( memcmp( Item, &(NR->name), sizeof(struct nmb_name) ) );
+}
+
/****************************************************************************
stop listening on a subnet
we don't free the record as we don't have proper reference counting for it
@@ -128,7 +156,10 @@ static struct subnet_record *make_subnet(const char *name, enum subnet_type type
return(NULL);
}
- ZERO_STRUCTP(subrec);
+ memset( (char *)subrec, '\0', sizeof(*subrec) );
+ (void)ubi_trInitTree( subrec->namelist,
+ namelist_entry_compare,
+ ubi_trOVERWRITE );
if((subrec->subnet_name = SMB_STRDUP(name)) == NULL) {
DEBUG(0,("make_subnet: malloc fail for subnet name !\n"));
diff --git a/source/nmbd/nmbd_winsproxy.c b/source/nmbd/nmbd_winsproxy.c
index d6dc6261c84..75319724616 100644
--- a/source/nmbd/nmbd_winsproxy.c
+++ b/source/nmbd/nmbd_winsproxy.c
@@ -33,7 +33,7 @@ static void wins_proxy_name_query_request_success( struct subnet_record *subrec,
unstring name;
struct packet_struct *original_packet;
struct subnet_record *orig_broadcast_subnet;
- struct name_record *namerec = NULL;
+ struct name_record *namerec;
uint16 nb_flags;
int num_ips;
int i;
@@ -64,34 +64,22 @@ returned for name %s.\n", nmb_namestr(nmbname) ));
return;
}
- for(i = 0; i < num_ips; i++) {
+ for(i = 0; i < num_ips; i++)
putip( (char *)&iplist[i], (char *)&rrec->rdata[ (i*6) + 2]);
- }
}
/* Add the queried name to the original subnet as a WINS_PROXY_NAME. */
- if(rrec == PERMANENT_TTL) {
+ if(rrec == PERMANENT_TTL)
ttl = lp_max_ttl();
- }
pull_ascii_nstring(name, sizeof(name), nmbname->name);
- add_name_to_subnet( orig_broadcast_subnet, name,
+ namerec = add_name_to_subnet( orig_broadcast_subnet, name,
nmbname->name_type, nb_flags, ttl,
WINS_PROXY_NAME, num_ips, iplist );
- namerec = find_name_on_subnet(orig_broadcast_subnet, nmbname, FIND_ANY_NAME);
- if (!namerec) {
- DEBUG(0,("wins_proxy_name_query_request_success: failed to add "
- "name %s to subnet %s !\n",
- name,
- orig_broadcast_subnet->subnet_name ));
- return;
- }
-
- if(iplist != &ip) {
+ if(iplist != &ip)
SAFE_FREE(iplist);
- }
/*
* Check that none of the IP addresses we are returning is on the
diff --git a/source/nmbd/nmbd_winsserver.c b/source/nmbd/nmbd_winsserver.c
index 9983efe5ebb..8a1f82c8b17 100644
--- a/source/nmbd/nmbd_winsserver.c
+++ b/source/nmbd/nmbd_winsserver.c
@@ -2,7 +2,7 @@
Unix SMB/CIFS implementation.
NBT netbios routines and daemon - version 2
- Copyright (C) Jeremy Allison 1994-2005
+ Copyright (C) Jeremy Allison 1994-2003
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,313 +18,12 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- Converted to store WINS data in a tdb. Dec 2005. JRA.
*/
#include "includes.h"
#define WINS_LIST "wins.dat"
#define WINS_VERSION 1
-#define WINSDB_VERSION 1
-
-/****************************************************************************
- We don't store the NetBIOS scope in the wins.tdb. We key off the (utf8) netbios
- name (65 bytes with the last byte being the name type).
-*****************************************************************************/
-
-TDB_CONTEXT *wins_tdb;
-
-/****************************************************************************
- Convert a wins.tdb record to a struct name_record. Add in our global_scope().
-*****************************************************************************/
-
-static struct name_record *wins_record_to_name_record(TDB_DATA key, TDB_DATA data)
-{
- struct name_record *namerec = NULL;
- uint16 nb_flags;
- unsigned char nr_src;
- uint32 death_time, refresh_time;
- uint32 id_low, id_high;
- uint32 saddr;
- uint32 wins_flags;
- uint32 num_ips;
- size_t len;
- int i;
-
- if (data.dptr == NULL || data.dsize == 0) {
- return NULL;
- }
-
- /* Min size is "wbddddddd" + 1 ip address (4). */
- if (data.dsize < 2 + 1 + (7*4) + 4) {
- return NULL;
- }
-
- len = tdb_unpack(data.dptr, data.dsize,
- "wbddddddd",
- &nb_flags,
- &nr_src,
- &death_time,
- &refresh_time,
- &id_low,
- &id_high,
- &saddr,
- &wins_flags,
- &num_ips );
-
- namerec = SMB_MALLOC_P(struct name_record);
- if (!namerec) {
- return NULL;
- }
-
- namerec->data.ip = SMB_MALLOC_ARRAY(struct in_addr, num_ips);
- if (!namerec->data.ip) {
- SAFE_FREE(namerec);
- return NULL;
- }
-
- namerec->subnet = wins_server_subnet;
- push_ascii_nstring(namerec->name.name, key.dptr);
- namerec->name.name_type = key.dptr[sizeof(unstring)];
- /* Add the scope. */
- push_ascii(namerec->name.scope, global_scope(), 64, STR_TERMINATE);
-
- /* We're using a byte-by-byte compare, so we must be sure that
- * unused space doesn't have garbage in it.
- */
-
- for( i = strlen( namerec->name.name ); i < sizeof( namerec->name.name ); i++ ) {
- namerec->name.name[i] = '\0';
- }
- for( i = strlen( namerec->name.scope ); i < sizeof( namerec->name.scope ); i++ ) {
- namerec->name.scope[i] = '\0';
- }
-
- namerec->data.nb_flags = nb_flags;
- namerec->data.source = (enum name_source)nr_src;
- namerec->data.death_time = (time_t)death_time;
- namerec->data.refresh_time = (time_t)refresh_time;
- namerec->data.id = id_low;
-#if defined(HAVE_LONGLONG)
- namerec->data.id |= ((SMB_BIG_UINT)id_high << 32);
-#endif
- namerec->data.wins_ip.s_addr = saddr;
- namerec->data.wins_flags = wins_flags,
- namerec->data.num_ips = num_ips;
-
- for (i = 0; i < num_ips; i++) {
- namerec->data.ip[i].s_addr = IVAL(data.dptr, len + (i*4));
- }
-
- return namerec;
-}
-
-/****************************************************************************
- Convert a struct name_record to a wins.tdb record. Ignore the scope.
-*****************************************************************************/
-
-static TDB_DATA name_record_to_wins_record(const struct name_record *namerec)
-{
- TDB_DATA data;
- size_t len = 0;
- int i;
- uint32 id_low = (namerec->data.id & 0xFFFFFFFF);
-#if defined(HAVE_LONGLONG)
- uint32 id_high = (namerec->data.id >> 32) & 0xFFFFFFFF;
-#else
- uint32 id_high = 0;
-#endif
-
- ZERO_STRUCT(data);
-
- len = (2 + 1 + (7*4)); /* "wbddddddd" */
- len += (namerec->data.num_ips * 4);
-
- data.dptr = SMB_MALLOC(len);
- if (!data.dptr) {
- return data;
- }
- data.dsize = len;
-
- len = tdb_pack(data.dptr, data.dsize, "wbddddddd",
- namerec->data.nb_flags,
- (unsigned char)namerec->data.source,
- (uint32)namerec->data.death_time,
- (uint32)namerec->data.refresh_time,
- id_low,
- id_high,
- (uint32)namerec->data.wins_ip.s_addr,
- (uint32)namerec->data.wins_flags,
- (uint32)namerec->data.num_ips );
-
- for (i = 0; i < namerec->data.num_ips; i++) {
- SIVAL(data.dptr, len + (i*4), namerec->data.ip[i].s_addr);
- }
-
- return data;
-}
-
-/****************************************************************************
- Create key. Key is UNIX codepage namestring (usually utf8 64 byte len) with 1 byte type.
-*****************************************************************************/
-
-static TDB_DATA name_to_key(const struct nmb_name *nmbname)
-{
- static char keydata[sizeof(unstring) + 1];
- TDB_DATA key;
-
- memset(keydata, '\0', sizeof(keydata));
-
- pull_ascii_nstring(keydata, sizeof(unstring), nmbname->name);
- strupper_m(keydata);
- keydata[sizeof(unstring)] = nmbname->name_type;
- key.dptr = keydata;
- key.dsize = sizeof(keydata);
-
- return key;
-}
-
-/****************************************************************************
- Lookup a given name in the wins.tdb and create a temporary malloc'ed data struct
- on the linked list. We will free this later in XXXX().
-*****************************************************************************/
-
-struct name_record *find_name_on_wins_subnet(const struct nmb_name *nmbname, BOOL self_only)
-{
- TDB_DATA data, key;
- struct name_record *nr = NULL;
- struct name_record *namerec = NULL;
-
- if (!wins_tdb) {
- return NULL;
- }
-
- key = name_to_key(nmbname);
- data = tdb_fetch(wins_tdb, key);
-
- if (data.dsize == 0) {
- return NULL;
- }
-
- namerec = wins_record_to_name_record(key, data);
- if (!namerec) {
- return NULL;
- }
-
- /* Search for this name record on the list. Replace it if found. */
-
- for( nr = wins_server_subnet->namelist; nr; nr = nr->next) {
- if (memcmp(nmbname->name, nr->name.name, 16) == 0) {
- /* Delete it. */
- DLIST_REMOVE(wins_server_subnet->namelist, nr);
- SAFE_FREE(nr->data.ip);
- SAFE_FREE(nr);
- break;
- }
- }
-
- DLIST_ADD(wins_server_subnet->namelist, namerec);
- return namerec;
-}
-
-/****************************************************************************
- Overwrite or add a given name in the wins.tdb.
-*****************************************************************************/
-
-static BOOL store_or_replace_wins_namerec(const struct name_record *namerec, int tdb_flag)
-{
- TDB_DATA key, data;
- int ret;
-
- if (!wins_tdb) {
- return False;
- }
-
- key = name_to_key(&namerec->name);
- data = name_record_to_wins_record(namerec);
-
- if (data.dptr == NULL) {
- return False;
- }
-
- ret = tdb_store(wins_tdb, key, data, tdb_flag);
-
- SAFE_FREE(data.dptr);
- return (ret == 0) ? True : False;
-}
-
-/****************************************************************************
- Overwrite a given name in the wins.tdb.
-*****************************************************************************/
-
-BOOL wins_store_changed_namerec(const struct name_record *namerec)
-{
- return store_or_replace_wins_namerec(namerec, TDB_REPLACE);
-}
-
-/****************************************************************************
- Primary interface into creating and overwriting records in the wins.tdb.
-*****************************************************************************/
-
-BOOL add_name_to_wins_subnet(const struct name_record *namerec)
-{
- return store_or_replace_wins_namerec(namerec, TDB_INSERT);
-}
-
-/****************************************************************************
- Delete a given name in the tdb and remove the temporary malloc'ed data struct
- on the linked list.
-*****************************************************************************/
-
-BOOL remove_name_from_wins_namelist(struct name_record *namerec)
-{
- TDB_DATA key;
- int ret;
-
- if (!wins_tdb) {
- return False;
- }
-
- key = name_to_key(&namerec->name);
- ret = tdb_delete(wins_tdb, key);
-
- DLIST_REMOVE(wins_server_subnet->namelist, namerec);
- SAFE_FREE(namerec->data.ip);
-
- /* namerec must be freed by the caller */
-
- return (ret == 0) ? True : False;
-}
-
-/****************************************************************************
- Dump out the complete namelist.
-*****************************************************************************/
-
-static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
-{
- struct name_record *namerec = NULL;
- XFILE *fp = (XFILE *)state;
-
- if (kbuf.dsize != sizeof(unstring) + 1) {
- return 0;
- }
-
- namerec = wins_record_to_name_record(kbuf, dbuf);
- if (!namerec) {
- return 0;
- }
-
- dump_name_record(namerec, fp);
-
- SAFE_FREE(namerec->data.ip);
- SAFE_FREE(namerec);
- return 0;
-}
-
-void dump_wins_subnet_namelist(XFILE *fp)
-{
- tdb_traverse(wins_tdb, traverse_fn, (void *)fp);
-}
/****************************************************************************
Change the wins owner address in the record.
@@ -332,6 +31,8 @@ void dump_wins_subnet_namelist(XFILE *fp)
static void update_wins_owner(struct name_record *namerec, struct in_addr wins_ip)
{
+ if (namerec==NULL)
+ return;
namerec->data.wins_ip=wins_ip;
}
@@ -341,35 +42,34 @@ static void update_wins_owner(struct name_record *namerec, struct in_addr wins_i
static void update_wins_flag(struct name_record *namerec, int flags)
{
+ if (namerec==NULL)
+ return;
+
namerec->data.wins_flags=0x0;
/* if it's a group, it can be a normal or a special one */
if (namerec->data.nb_flags & NB_GROUP) {
- if (namerec->name.name_type==0x1C) {
+ if (namerec->name.name_type==0x1C)
namerec->data.wins_flags|=WINS_SGROUP;
- } else {
- if (namerec->data.num_ips>1) {
+ else
+ if (namerec->data.num_ips>1)
namerec->data.wins_flags|=WINS_SGROUP;
- } else {
+ else
namerec->data.wins_flags|=WINS_NGROUP;
- }
- }
} else {
/* can be unique or multi-homed */
- if (namerec->data.num_ips>1) {
+ if (namerec->data.num_ips>1)
namerec->data.wins_flags|=WINS_MHOMED;
- } else {
+ else
namerec->data.wins_flags|=WINS_UNIQUE;
- }
}
/* the node type are the same bits */
namerec->data.wins_flags|=namerec->data.nb_flags&NB_NODETYPEMASK;
/* the static bit is elsewhere */
- if (namerec->data.death_time == PERMANENT_TTL) {
+ if (namerec->data.death_time == PERMANENT_TTL)
namerec->data.wins_flags|=WINS_STATIC;
- }
/* and add the given bits */
namerec->data.wins_flags|=flags;
@@ -395,14 +95,12 @@ static void get_global_id_and_update(SMB_BIG_UINT *current_id, BOOL update)
*current_id = general_id;
- if (update) {
+ if (update)
general_id++;
- }
}
/****************************************************************************
Possibly call the WINS hook external program when a WINS change is made.
- Also stores the changed record back in the wins_tdb.
*****************************************************************************/
static void wins_hook(const char *operation, struct name_record *namerec, int ttl)
@@ -412,11 +110,7 @@ static void wins_hook(const char *operation, struct name_record *namerec, int tt
char *p, *namestr;
int i;
- wins_store_changed_namerec(namerec);
-
- if (!cmd || !*cmd) {
- return;
- }
+ if (!cmd || !*cmd) return;
for (p=namerec->name.name; *p; p++) {
if (!(isalnum((int)*p) || strchr_m("._-",*p))) {
@@ -428,9 +122,8 @@ static void wins_hook(const char *operation, struct name_record *namerec, int tt
/* Use the name without the nametype (and scope) appended */
namestr = nmb_namestr(&namerec->name);
- if ((p = strchr(namestr, '<'))) {
+ if ((p = strchr(namestr, '<')))
*p = 0;
- }
p = command;
p += slprintf(p, sizeof(command)-1, "%s %s %s %02x %d",
@@ -448,6 +141,7 @@ static void wins_hook(const char *operation, struct name_record *namerec, int tt
smbrun(command, NULL);
}
+
/****************************************************************************
Determine if this packet should be allocated to the WINS server.
*****************************************************************************/
@@ -463,9 +157,8 @@ BOOL packet_is_for_wins_server(struct packet_struct *packet)
}
/* Check for node status requests. */
- if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY) {
+ if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY)
return False;
- }
switch(nmb->header.opcode) {
/*
@@ -517,13 +210,11 @@ static int get_ttl_from_packet(struct nmb_packet *nmb)
{
int ttl = nmb->additional->ttl;
- if (ttl < lp_min_wins_ttl()) {
+ if(ttl < lp_min_wins_ttl() )
ttl = lp_min_wins_ttl();
- }
- if (ttl > lp_max_wins_ttl()) {
+ if(ttl > lp_max_wins_ttl() )
ttl = lp_max_wins_ttl();
- }
return ttl;
}
@@ -538,19 +229,8 @@ BOOL initialise_wins(void)
XFILE *fp;
pstring line;
- if(!lp_we_are_a_wins_server()) {
+ if(!lp_we_are_a_wins_server())
return True;
- }
-
- /* Open the wins.tdb. */
- wins_tdb = tdb_open_log(lock_path("wins.tdb"), 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST, O_CREAT|O_RDWR, 0600);
- if (!wins_tdb) {
- DEBUG(0,("initialise_wins: failed to open wins.tdb. Error was %s\n",
- strerror(errno) ));
- return False;
- }
-
- tdb_store_int32(wins_tdb, "WINSDB_VERSION", WINSDB_VERSION);
add_samba_names_to_subnet(wins_server_subnet);
@@ -664,9 +344,8 @@ BOOL initialise_wins(void)
continue;
}
- if(nb_flags_str[strlen(nb_flags_str)-1] == 'R') {
+ if(nb_flags_str[strlen(nb_flags_str)-1] == 'R')
nb_flags_str[strlen(nb_flags_str)-1] = '\0';
- }
/* Netbios name. # divides the name from the type (hex): netbios#xx */
pstrcpy(name,name_str);
@@ -682,9 +361,8 @@ BOOL initialise_wins(void)
/* add all entries that have 60 seconds or more to live */
if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) {
- if(ttl != PERMANENT_TTL) {
+ if(ttl != PERMANENT_TTL)
ttl -= time_now;
- }
DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
@@ -692,8 +370,7 @@ BOOL initialise_wins(void)
(void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
ttl, REGISTER_NAME, num_ips, ip_list );
} else {
- DEBUG(4, ("initialise_wins: not adding name (ttl problem) "
- "%s#%02x ttl = %d first IP %s flags = %2x\n",
+ DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
}
@@ -719,21 +396,16 @@ static void send_wins_wack_response(int ttl, struct packet_struct *p)
identical bytes from the requesting packet header. */
rdata[0] = (nmb->header.opcode & 0xF) << 3;
- if (nmb->header.nm_flags.authoritative && nmb->header.response) {
+ if (nmb->header.nm_flags.authoritative && nmb->header.response)
rdata[0] |= 0x4;
- }
- if (nmb->header.nm_flags.trunc) {
+ if (nmb->header.nm_flags.trunc)
rdata[0] |= 0x2;
- }
- if (nmb->header.nm_flags.recursion_desired) {
+ if (nmb->header.nm_flags.recursion_desired)
rdata[0] |= 0x1;
- }
- if (nmb->header.nm_flags.recursion_available && nmb->header.response) {
+ if (nmb->header.nm_flags.recursion_available && nmb->header.response)
rdata[1] |= 0x80;
- }
- if (nmb->header.nm_flags.bcast) {
+ if (nmb->header.nm_flags.bcast)
rdata[1] |= 0x10;
- }
reply_netbios_packet(p, /* Packet to reply to. */
0, /* Result code. */
@@ -873,7 +545,7 @@ void wins_process_name_refresh_request( struct subnet_record *subrec,
* names update the ttl and return success.
*/
if( (!group || (group && (question->name_type == 0x1c)))
- && find_ip_in_name_record(namerec, from_ip) ) {
+ && find_ip_in_name_record(namerec, from_ip) ) {
/*
* Update the ttl.
*/
@@ -912,7 +584,6 @@ void wins_process_name_refresh_request( struct subnet_record *subrec,
* 255.255.255.255 so we can't search for the IP address.
*/
update_name_ttl(namerec, ttl);
- wins_hook("refresh", namerec, ttl);
send_wins_name_registration_response(0, ttl, p);
return;
} else if(!group && (question->name_type == 0x1d)) {
@@ -998,19 +669,16 @@ static void wins_register_query_fail(struct subnet_record *subrec,
namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
- if ((namerec != NULL) && (namerec->data.source == REGISTER_NAME) &&
- ip_equal(rrec->packet->ip, *namerec->data.ip)) {
+ if( (namerec != NULL) && (namerec->data.source == REGISTER_NAME) && ip_equal(rrec->packet->ip, *namerec->data.ip) ) {
remove_name_from_namelist( subrec, namerec);
namerec = NULL;
}
- if(namerec == NULL) {
+ if(namerec == NULL)
wins_process_name_registration_request(subrec, orig_reg_packet);
- } else {
- DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between "
- "querying for name %s in order to replace it and this reply.\n",
- nmb_namestr(question_name) ));
- }
+ else
+ DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between \
+querying for name %s in order to replace it and this reply.\n", nmb_namestr(question_name) ));
orig_reg_packet->locked = False;
free_packet(orig_reg_packet);
@@ -1160,9 +828,8 @@ to register name %s. Name already exists in WINS with source type %d.\n",
* Group names with type 0x1c are registered with individual IP addresses.
*/
- if(registering_group_name && (question->name_type != 0x1c)) {
+ if(registering_group_name && (question->name_type != 0x1c))
from_ip = *interpret_addr2("255.255.255.255");
- }
/*
* Ignore all attempts to register a unique 0x1d name, although return success.
@@ -1209,7 +876,6 @@ to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
update_wins_owner(namerec, our_fake_ip);
}
update_name_ttl(namerec, ttl);
- wins_hook("refresh", namerec, ttl);
send_wins_name_registration_response(0, ttl, p);
return;
} else {
@@ -1239,11 +905,8 @@ already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
* reject without doing the query - we know we will reject it.
*/
- if ( namerec != NULL ) {
+ if ( namerec != NULL )
pull_ascii_nstring(name, sizeof(name), namerec->name.name);
- } else {
- name[0] = '\0';
- }
if( is_myname(name) ) {
if(!ismyip(from_ip)) {
@@ -1256,8 +919,8 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
* It's one of our names and one of our IP's - update the ttl.
*/
update_name_ttl(namerec, ttl);
- wins_hook("refresh", namerec, ttl);
send_wins_name_registration_response(0, ttl, p);
+ wins_hook("refresh", namerec, ttl);
return;
}
}
@@ -1277,8 +940,8 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
&& ip_equal( namerec->data.ip[0], from_ip )
&& ip_equal(namerec->data.wins_ip, our_fake_ip) ) {
update_name_ttl( namerec, ttl );
- wins_hook("refresh", namerec, ttl);
send_wins_name_registration_response( 0, ttl, p );
+ wins_hook("refresh", namerec, ttl);
return;
}
@@ -1398,16 +1061,15 @@ a subsequent IP address.\n", nmb_namestr(question_name) ));
return;
}
- if(!find_ip_in_name_record(namerec, from_ip)) {
+ if(!find_ip_in_name_record(namerec, from_ip))
add_ip_to_name_record(namerec, from_ip);
- }
get_global_id_and_update(&namerec->data.id, True);
update_wins_owner(namerec, our_fake_ip);
update_wins_flag(namerec, WINS_ACTIVE);
update_name_ttl(namerec, ttl);
- wins_hook("add", namerec, ttl);
send_wins_name_registration_response(0, ttl, orig_reg_packet);
+ wins_hook("add", namerec, ttl);
orig_reg_packet->locked = False;
free_packet(orig_reg_packet);
@@ -1575,17 +1237,18 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
* It's one of our names and one of our IP's. Ensure the IP is in the record and
* update the ttl. Update the version ID to force replication.
*/
- update_name_ttl(namerec, ttl);
-
if(!find_ip_in_name_record(namerec, from_ip)) {
get_global_id_and_update(&namerec->data.id, True);
update_wins_owner(namerec, our_fake_ip);
update_wins_flag(namerec, WINS_ACTIVE);
add_ip_to_name_record(namerec, from_ip);
+ wins_hook("add", namerec, ttl);
+ } else {
+ wins_hook("refresh", namerec, ttl);
}
- wins_hook("refresh", namerec, ttl);
+ update_name_ttl(namerec, ttl);
send_wins_name_registration_response(0, ttl, p);
return;
}
@@ -1609,8 +1272,8 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
update_wins_flag(namerec, WINS_ACTIVE);
}
- wins_hook("refresh", namerec, ttl);
send_wins_name_registration_response(0, ttl, p);
+ wins_hook("refresh", namerec, ttl);
return;
}
@@ -1685,37 +1348,6 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
}
/***********************************************************************
- Fetch all *<1b> names from the WINS db and store on the namelist.
-***********************************************************************/
-
-static int fetch_1b_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
-{
- struct name_record *namerec = NULL;
-
- if (kbuf.dsize != sizeof(unstring) + 1) {
- return 0;
- }
-
- /* Filter out all non-1b names. */
- if (kbuf.dptr[sizeof(unstring)] != 0x1b) {
- return 0;
- }
-
- namerec = wins_record_to_name_record(kbuf, dbuf);
- if (!namerec) {
- return 0;
- }
-
- DLIST_ADD(wins_server_subnet->namelist, namerec);
- return 0;
-}
-
-void fetch_all_active_wins_1b_names(void)
-{
- tdb_traverse(wins_tdb, fetch_1b_traverse_fn, NULL);
-}
-
-/***********************************************************************
Deal with the special name query for *<1b>.
***********************************************************************/
@@ -1733,13 +1365,10 @@ static void process_wins_dmb_query_request(struct subnet_record *subrec,
*/
num_ips = 0;
-
- fetch_all_active_wins_1b_names();
-
- for( namerec = subrec->namelist; namerec; namerec = namerec->next ) {
- if( WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b) {
+ for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
+ namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
+ if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b )
num_ips += namerec->data.num_ips;
- }
}
if(num_ips == 0) {
@@ -1762,8 +1391,9 @@ static void process_wins_dmb_query_request(struct subnet_record *subrec,
*/
num_ips = 0;
- for( namerec = subrec->namelist; namerec; namerec = namerec->next ) {
- if( WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b) {
+ for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
+ namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
+ if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b) {
int i;
for(i = 0; i < namerec->data.num_ips; i++) {
set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
@@ -1835,9 +1465,8 @@ void send_wins_name_query_response(int rcode, struct packet_struct *p,
prdata, /* data to send. */
reply_data_len); /* data length. */
- if(prdata != rdata) {
+ if(prdata != rdata)
SAFE_FREE(prdata);
- }
}
/***********************************************************************
@@ -1919,7 +1548,7 @@ void wins_process_name_query_request(struct subnet_record *subrec,
DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
nmb_namestr(question) ));
- queue_dns_query(p, question);
+ queue_dns_query(p, question, &namerec);
return;
}
@@ -2051,7 +1680,6 @@ release name %s as this record is not active anymore.\n", nmb_namestr(question)
remove_ip_from_name_record(namerec, from_ip);
DEBUG(3,("wins_process_name_release_request: Remove IP %s from NAME: %s\n",
inet_ntoa(from_ip),nmb_namestr(question)));
- wins_hook("delete", namerec, 0);
send_wins_name_release_response(0, p);
return;
}
@@ -2061,235 +1689,118 @@ release name %s as this record is not active anymore.\n", nmb_namestr(question)
* Flag the name as released and update the ttl
*/
+ send_wins_name_release_response(0, p);
+
namerec->data.wins_flags |= WINS_RELEASED;
update_name_ttl(namerec, EXTINCTION_INTERVAL);
wins_hook("delete", namerec, 0);
- send_wins_name_release_response(0, p);
}
/*******************************************************************
WINS time dependent processing.
******************************************************************/
-static int wins_processing_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
-{
- time_t t = *(time_t *)state;
- BOOL store_record = False;
- struct name_record *namerec = NULL;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
-
- if (kbuf.dsize != sizeof(unstring) + 1) {
- return 0;
- }
-
- namerec = wins_record_to_name_record(kbuf, dbuf);
- if (!namerec) {
- return 0;
- }
-
- if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < t) ) {
- if( namerec->data.source == SELF_NAME ) {
- DEBUG( 3, ( "wins_processing_traverse_fn: Subnet %s not expiring SELF name %s\n",
- wins_server_subnet->subnet_name, nmb_namestr(&namerec->name) ) );
- namerec->data.death_time += 300;
- store_record = True;
- goto done;
- } else if (namerec->data.source == DNS_NAME || namerec->data.source == DNSFAIL_NAME) {
- DEBUG(3,("wins_processing_traverse_fn: deleting timed out DNS name %s\n",
- nmb_namestr(&namerec->name)));
- remove_name_from_wins_namelist(namerec );
- goto done;
- }
-
- /* 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) {
- case WINS_ACTIVE:
- namerec->data.wins_flags&=~WINS_STATE_MASK;
- namerec->data.wins_flags|=WINS_RELEASED;
- namerec->data.death_time = t + EXTINCTION_INTERVAL;
- DEBUG(3,("wins_processing_traverse_fn: expiring %s\n",
- nmb_namestr(&namerec->name)));
- store_record = True;
- goto done;
- case WINS_RELEASED:
- namerec->data.wins_flags&=~WINS_STATE_MASK;
- namerec->data.wins_flags|=WINS_TOMBSTONED;
- namerec->data.death_time = t + EXTINCTION_TIMEOUT;
- get_global_id_and_update(&namerec->data.id, True);
- DEBUG(3,("wins_processing_traverse_fn: tombstoning %s\n",
- nmb_namestr(&namerec->name)));
- store_record = True;
- goto done;
- case WINS_TOMBSTONED:
- DEBUG(3,("wins_processing_traverse_fn: deleting %s\n",
- nmb_namestr(&namerec->name)));
- remove_name_from_wins_namelist(namerec );
- goto done;
- }
- } else {
- 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;
- namerec->data.wins_flags|=WINS_TOMBSTONED;
- namerec->data.death_time = t + EXTINCTION_TIMEOUT;
- DEBUG(3,("wins_processing_traverse_fn: tombstoning %s\n",
- nmb_namestr(&namerec->name)));
- store_record = True;
- goto done;
- case WINS_TOMBSTONED:
- DEBUG(3,("wins_processing_traverse_fn: deleting %s\n",
- nmb_namestr(&namerec->name)));
- remove_name_from_wins_namelist(namerec );
- goto done;
- case WINS_RELEASED:
- DEBUG(0,("wins_processing_traverse_fn: %s is in released state and\
-we are not the wins owner !\n", nmb_namestr(&namerec->name)));
- goto done;
- }
- }
- }
-
- done:
-
- if (store_record) {
- wins_store_changed_namerec(namerec);
- }
-
- SAFE_FREE(namerec->data.ip);
- SAFE_FREE(namerec);
-
- return 0;
-}
-
-/*******************************************************************
- Time dependent wins processing.
-******************************************************************/
-
void initiate_wins_processing(time_t t)
{
static time_t lasttime = 0;
- struct name_record *nr = NULL;
- struct name_record *nrnext = NULL;
-
- if (!lasttime) {
- lasttime = t;
- }
- if (t - lasttime < 20) {
- return;
- }
+ struct name_record *namerec;
+ struct name_record *next_namerec;
+ struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
- if(!lp_we_are_a_wins_server()) {
+ if (!lasttime)
lasttime = t;
+ if (t - lasttime < 20)
return;
- }
-
- tdb_traverse(wins_tdb, wins_processing_traverse_fn, &t);
-
-
- /* Delete all temporary name records on the wins subnet linked list. */
- for( nr = wins_server_subnet->namelist; nr; nr = nrnext) {
- nrnext = nr->next;
- DLIST_REMOVE(wins_server_subnet->namelist, nr);
- SAFE_FREE(nr->data.ip);
- SAFE_FREE(nr);
- }
-
- wins_write_database(t, True);
lasttime = t;
-}
-/*******************************************************************
- Write out one record.
-******************************************************************/
-
-void wins_write_name_record(struct name_record *namerec, XFILE *fp)
-{
- int i;
- struct tm *tm;
+ if(!lp_we_are_a_wins_server())
+ return;
- DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
+ for( namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
+ namerec;
+ namerec = next_namerec ) {
+ next_namerec = (struct name_record *)ubi_trNext( namerec );
+
+ if( (namerec->data.death_time != PERMANENT_TTL)
+ && (namerec->data.death_time < t) ) {
+
+ if( namerec->data.source == SELF_NAME ) {
+ DEBUG( 3, ( "initiate_wins_processing: Subnet %s not expiring SELF name %s\n",
+ wins_server_subnet->subnet_name, nmb_namestr(&namerec->name) ) );
+ namerec->data.death_time += 300;
+ namerec->subnet->namelist_changed = True;
+ continue;
+ } else if (namerec->data.source == DNS_NAME || namerec->data.source == DNSFAIL_NAME) {
+ DEBUG(3,("initiate_wins_processing: deleting timed out DNS name %s\n",
+ nmb_namestr(&namerec->name)));
+ remove_name_from_namelist( wins_server_subnet, namerec );
+ continue;
+ }
- if( namerec->data.death_time != PERMANENT_TTL ) {
- char *ts, *nl;
+ /* 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) {
+ case WINS_ACTIVE:
+ namerec->data.wins_flags&=~WINS_STATE_MASK;
+ namerec->data.wins_flags|=WINS_RELEASED;
+ namerec->data.death_time = t + EXTINCTION_INTERVAL;
+ DEBUG(3,("initiate_wins_processing: expiring %s\n", nmb_namestr(&namerec->name)));
+ break;
+ case WINS_RELEASED:
+ namerec->data.wins_flags&=~WINS_STATE_MASK;
+ namerec->data.wins_flags|=WINS_TOMBSTONED;
+ namerec->data.death_time = t + EXTINCTION_TIMEOUT;
+ get_global_id_and_update(&namerec->data.id, True);
+ DEBUG(3,("initiate_wins_processing: tombstoning %s\n", nmb_namestr(&namerec->name)));
+ break;
+ case WINS_TOMBSTONED:
+ DEBUG(3,("initiate_wins_processing: deleting %s\n", nmb_namestr(&namerec->name)));
+ remove_name_from_namelist( wins_server_subnet, namerec );
+ break;
+ }
+ } else {
+ 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;
+ namerec->data.wins_flags|=WINS_TOMBSTONED;
+ namerec->data.death_time = t + EXTINCTION_TIMEOUT;
+ DEBUG(3,("initiate_wins_processing: tombstoning %s\n", nmb_namestr(&namerec->name)));
+ case WINS_TOMBSTONED:
+ DEBUG(3,("initiate_wins_processing: deleting %s\n", nmb_namestr(&namerec->name)));
+ remove_name_from_namelist( wins_server_subnet, namerec );
+ break;
+ case WINS_RELEASED:
+ DEBUG(0,("initiate_wins_processing: %s is in released state and\
+we are not the wins owner !\n", nmb_namestr(&namerec->name)));
+ break;
+ }
+ }
- tm = localtime(&namerec->data.death_time);
- ts = asctime(tm);
- nl = strrchr( ts, '\n' );
- if( NULL != nl ) {
- *nl = '\0';
}
- DEBUGADD(4,("TTL = %s ", ts ));
- } else {
- DEBUGADD(4,("TTL = PERMANENT "));
- }
-
- for (i = 0; i < namerec->data.num_ips; i++) {
- DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
}
- DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
- if( namerec->data.source == REGISTER_NAME ) {
- unstring name;
- pull_ascii_nstring(name, sizeof(name), namerec->name.name);
- x_fprintf(fp, "\"%s#%02x\" %d ", name,namerec->name.name_type, /* Ignore scope. */
- (int)namerec->data.death_time);
+ if(wins_server_subnet->namelist_changed)
+ wins_write_database(True);
- for (i = 0; i < namerec->data.num_ips; i++)
- x_fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
- x_fprintf( fp, "%2xR\n", namerec->data.nb_flags );
- }
+ wins_server_subnet->namelist_changed = False;
}
/*******************************************************************
Write out the current WINS database.
******************************************************************/
-static int wins_writedb_traverse_fn(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
+void wins_write_database(BOOL background)
{
- struct name_record *namerec = NULL;
- XFILE *fp = (XFILE *)state;
-
- if (kbuf.dsize != sizeof(unstring) + 1) {
- return 0;
- }
-
- namerec = wins_record_to_name_record(kbuf, dbuf);
- if (!namerec) {
- return 0;
- }
-
- wins_write_name_record(namerec, fp);
-
- SAFE_FREE(namerec->data.ip);
- SAFE_FREE(namerec);
- return 0;
-}
-
-
-void wins_write_database(time_t t, BOOL background)
-{
- static time_t last_write_time = 0;
+ struct name_record *namerec;
pstring fname, fnamenew;
XFILE *fp;
- if (background) {
- if (!last_write_time) {
- last_write_time = t;
- }
- if (t - last_write_time < 120) {
- return;
- }
-
- }
-
- if(!lp_we_are_a_wins_server()) {
+ if(!lp_we_are_a_wins_server())
return;
- }
/* We will do the writing in a child process to ensure that the parent doesn't block while this is done */
if (background) {
@@ -2297,11 +1808,6 @@ void wins_write_database(time_t t, BOOL background)
if (sys_fork()) {
return;
}
- if (tdb_reopen(wins_tdb)) {
- DEBUG(0,("wins_write_database: tdb_reopen failed. Error was %s\n",
- strerror(errno)));
- return;
- }
}
slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
@@ -2320,8 +1826,41 @@ void wins_write_database(time_t t, BOOL background)
x_fprintf(fp,"VERSION %d %u\n", WINS_VERSION, 0);
- tdb_traverse(wins_tdb, wins_writedb_traverse_fn, fp);
+ for( namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist ); namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) {
+ int i;
+ struct tm *tm;
+
+ DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
+
+ if( namerec->data.death_time != PERMANENT_TTL ) {
+ char *ts, *nl;
+
+ tm = localtime(&namerec->data.death_time);
+ ts = asctime(tm);
+ nl = strrchr( ts, '\n' );
+ if( NULL != nl )
+ *nl = '\0';
+ DEBUGADD(4,("TTL = %s ", ts ));
+ } else {
+ DEBUGADD(4,("TTL = PERMANENT "));
+ }
+ for (i = 0; i < namerec->data.num_ips; i++)
+ DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
+ DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
+
+ if( namerec->data.source == REGISTER_NAME ) {
+ unstring name;
+ pull_ascii_nstring(name, sizeof(name), namerec->name.name);
+ x_fprintf(fp, "\"%s#%02x\" %d ", name,namerec->name.name_type, /* Ignore scope. */
+ (int)namerec->data.death_time);
+
+ for (i = 0; i < namerec->data.num_ips; i++)
+ x_fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
+ x_fprintf( fp, "%2xR\n", namerec->data.nb_flags );
+ }
+ }
+
x_fclose(fp);
chmod(fnamenew,0644);
unlink(fname);
@@ -2331,8 +1870,6 @@ void wins_write_database(time_t t, BOOL background)
}
}
-#if 0
- Until winsrepl is done.
/****************************************************************************
Process a internal Samba message receiving a wins record.
***************************************************************************/
@@ -2348,9 +1885,8 @@ void nmbd_wins_new_entry(int msg_type, struct process_id src,
struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
int i;
- if (buf==NULL) {
+ if (buf==NULL)
return;
- }
/* Record should use UNIX codepage. Ensure this is so in the wrepld code. JRA. */
record=(WINS_RECORD *)buf;
@@ -2364,15 +1900,8 @@ void nmbd_wins_new_entry(int msg_type, struct process_id src,
DEBUG(3,("nmbd_wins_new_entry: adding new replicated record: %s<%02x> for wins server: %s\n",
record->name, record->type, inet_ntoa(record->wins_ip)));
- new_namerec=add_name_to_subnet( wins_server_subnet,
- record->name,
- record->type,
- record->nb_flags,
- EXTINCTION_INTERVAL,
- REGISTER_NAME,
- record->num_ips,
- record->ip);
-
+ new_namerec=add_name_to_subnet( wins_server_subnet, record->name, record->type, record->nb_flags,
+ EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, record->ip);
if (new_namerec!=NULL) {
update_wins_owner(new_namerec, record->wins_ip);
update_wins_flag(new_namerec, record->wins_flags);
@@ -2490,4 +2019,3 @@ void nmbd_wins_new_entry(int msg_type, struct process_id src,
}
}
-#endif
diff --git a/source/nsswitch/pam_winbind.c b/source/nsswitch/pam_winbind.c
index 61c01daa165..a87ccb4972e 100644
--- a/source/nsswitch/pam_winbind.c
+++ b/source/nsswitch/pam_winbind.c
@@ -57,11 +57,6 @@ static int _pam_parse(int argc, const char **argv)
return ctrl;
}
-static void _pam_winbind_cleanup_func(pam_handle_t *pamh, void *data, int error_status)
-{
- SAFE_FREE(data);
-}
-
/* --- authentication management functions --- */
/* Attempt a conversation */
@@ -513,22 +508,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
}
/* Now use the username to look up password */
- retval = winbind_auth_request(username, password, member, ctrl);
- if (retval == PAM_NEW_AUTHTOK_REQD ||
- retval == PAM_AUTHTOK_EXPIRED) {
-
- char *buf;
-
- if (!asprintf(&buf, "%d", retval)) {
- return PAM_BUF_ERR;
- }
-
- pam_set_data( pamh, PAM_WINBIND_NEW_AUTHTOK_REQD, (void *)buf, _pam_winbind_cleanup_func);
-
- return PAM_SUCCESS;
- }
-
- return retval;
+ return winbind_auth_request(username, password, member, ctrl);
}
PAM_EXTERN
@@ -547,8 +527,6 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
int argc, const char **argv)
{
const char *username;
- void *tmp = NULL;
-
int retval = PAM_USER_UNKNOWN;
/* parse arguments */
@@ -577,26 +555,6 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
return PAM_IGNORE;
return PAM_USER_UNKNOWN;
case 0:
- pam_get_data( pamh, PAM_WINBIND_NEW_AUTHTOK_REQD, (const void **)&tmp);
-
- if (tmp != NULL) {
- retval = atoi(tmp);
- switch (retval) {
- case PAM_AUTHTOK_EXPIRED:
- /* fall through, since new token is required in this case */
- case PAM_NEW_AUTHTOK_REQD:
- _pam_log(LOG_WARNING, "pam_sm_acct_mgmt success but %s is set",
- PAM_WINBIND_NEW_AUTHTOK_REQD);
- _pam_log(LOG_NOTICE, "user '%s' needs new password", username);
- /* PAM_AUTHTOKEN_REQD does not exist, but is documented in the manpage */
- return PAM_NEW_AUTHTOK_REQD;
- default:
- _pam_log(LOG_WARNING, "pam_sm_acct_mgmt success");
- _pam_log(LOG_NOTICE, "user '%s' granted access", username);
- return PAM_SUCCESS;
- }
- }
-
/* Otherwise, the authentication looked good */
_pam_log(LOG_NOTICE, "user '%s' granted access", username);
return PAM_SUCCESS;
diff --git a/source/nsswitch/pam_winbind.h b/source/nsswitch/pam_winbind.h
index 86ba9772879..7cae477714b 100644
--- a/source/nsswitch/pam_winbind.h
+++ b/source/nsswitch/pam_winbind.h
@@ -84,8 +84,6 @@ do { \
#define WINBIND__OLD_PASSWORD (1<<5)
#define WINBIND_REQUIRED_MEMBERSHIP (1<<6)
-#define PAM_WINBIND_NEW_AUTHTOK_REQD "PAM_WINBIND_NEW_AUTHTOK_REQD"
-
/*
* here is the string to inform the user that the new passwords they
* typed were not the same.
diff --git a/source/nsswitch/wb_client.c b/source/nsswitch/wb_client.c
index fcab76b033a..db56cf04441 100644
--- a/source/nsswitch/wb_client.c
+++ b/source/nsswitch/wb_client.c
@@ -64,53 +64,39 @@ BOOL winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
/* Call winbindd to convert sid to name */
-BOOL winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
- const char **domain, const char **name,
+BOOL winbind_lookup_sid(const DOM_SID *sid,
+ fstring dom_name, fstring name,
enum SID_NAME_USE *name_type)
{
struct winbindd_request request;
struct winbindd_response response;
NSS_STATUS result;
+ fstring sid_str;
/* Initialise request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- fstrcpy(request.data.sid, sid_string_static(sid));
+ sid_to_string(sid_str, sid);
+ fstrcpy(request.data.sid, sid_str);
/* Make request */
- result = winbindd_request_response(WINBINDD_LOOKUPSID, &request,
- &response);
-
- if (result != NSS_STATUS_SUCCESS) {
- return False;
- }
+ result = winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response);
/* Copy out result */
- if (domain != NULL) {
- *domain = talloc_strdup(mem_ctx, response.data.name.dom_name);
- if (*domain == NULL) {
- DEBUG(0, ("talloc failed\n"));
- return False;
- }
- }
- if (name != NULL) {
- *name = talloc_strdup(mem_ctx, response.data.name.name);
- if (*name == NULL) {
- DEBUG(0, ("talloc failed\n"));
- return False;
- }
- }
+ if (result == NSS_STATUS_SUCCESS) {
+ fstrcpy(dom_name, response.data.name.dom_name);
+ fstrcpy(name, response.data.name.name);
+ *name_type = (enum SID_NAME_USE)response.data.name.type;
- *name_type = (enum SID_NAME_USE)response.data.name.type;
+ DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n",
+ sid_str, dom_name, name));
+ }
- DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n",
- sid_string_static(sid), response.data.name.dom_name,
- response.data.name.name));
- return True;
+ return (result == NSS_STATUS_SUCCESS);
}
/* Call winbindd to convert SID to uid */
diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c
index e9b9ed42c4f..60a4e2f6c01 100644
--- a/source/nsswitch/winbindd.c
+++ b/source/nsswitch/winbindd.c
@@ -932,8 +932,6 @@ int main(int argc, char **argv)
fault_setup((void (*)(void *))fault_quit );
- load_case_tables();
-
/* Initialise for running in non-root mode */
sec_init();
diff --git a/source/nsswitch/winbindd_ads.c b/source/nsswitch/winbindd_ads.c
index 29129e823a2..ac24b35229c 100644
--- a/source/nsswitch/winbindd_ads.c
+++ b/source/nsswitch/winbindd_ads.c
@@ -621,7 +621,7 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
goto done;
}
- rc = ads_search_retry_dn(ads, (void**)(void *)&msg, user_dn, attrs);
+ rc = ads_search_retry_dn(ads, (void**)&msg, user_dn, attrs);
if (!ADS_ERR_OK(rc)) {
status = ads_ntstatus(rc);
DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: %s\n",
diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c
index 1d047b8356f..841b114a785 100644
--- a/source/nsswitch/winbindd_cache.c
+++ b/source/nsswitch/winbindd_cache.c
@@ -546,10 +546,8 @@ static void centry_put_string(struct cache_entry *centry, const char *s)
len = strlen(s);
/* can't handle more than 254 char strings. Truncating is probably best */
- if (len > 254) {
- DEBUG(10,("centry_put_string: truncating len (%d) to: 254\n", len));
+ if (len > 254)
len = 254;
- }
centry_put_uint8(centry, len);
centry_expand(centry, len);
memcpy(centry->data + centry->ofs, s, len);
@@ -991,11 +989,8 @@ do_query:
/* and save it */
wcache_save_name_to_sid(domain, status, domain_name, name, sid, *type);
- if (NT_STATUS_IS_OK(status)) {
- strupper_m(CONST_DISCARD(char *,domain_name));
- strlower_m(CONST_DISCARD(char *,name));
- wcache_save_sid_to_name(domain, status, sid, domain_name, name, *type);
- }
+ /* We can't save the sid to name mapping as we don't know the
+ correct case of the name without looking it up */
return status;
}
diff --git a/source/nsswitch/winbindd_ldap.c b/source/nsswitch/winbindd_ldap.c
index 736d852a74e..4eedf0ce9f3 100644
--- a/source/nsswitch/winbindd_ldap.c
+++ b/source/nsswitch/winbindd_ldap.c
@@ -34,7 +34,7 @@ struct ldap_message_queue {
};
struct rw_buffer {
- uint8 *data;
+ uint8_t *data;
size_t ofs, length;
};
@@ -67,7 +67,7 @@ struct pending_ldap_message {
struct pending_ldap_message *pending_messages;
-static BOOL append_to_buf(struct rw_buffer *buf, uint8 *data, size_t length)
+static BOOL append_to_buf(struct rw_buffer *buf, uint8_t *data, size_t length)
{
buf->data = SMB_REALLOC(buf->data, buf->length+length);
@@ -92,7 +92,7 @@ static BOOL read_into_buf(int fd, struct rw_buffer *buf)
return append_to_buf(buf, tmp_buf, len);
}
-static void peek_into_buf(struct rw_buffer *buf, uint8 **out,
+static void peek_into_buf(struct rw_buffer *buf, uint8_t **out,
size_t *out_length)
{
*out = buf->data;
@@ -101,7 +101,7 @@ static void peek_into_buf(struct rw_buffer *buf, uint8 **out,
static void consumed_from_buf(struct rw_buffer *buf, size_t length)
{
- uint8 *new = memdup(buf->data+length, buf->length-length);
+ uint8_t *new = memdup(buf->data+length, buf->length-length);
free(buf->data);
buf->data = new;
buf->length -= length;
@@ -109,7 +109,7 @@ static void consumed_from_buf(struct rw_buffer *buf, size_t length)
static BOOL write_out_of_buf(int fd, struct rw_buffer *buf)
{
- uint8 *tmp;
+ uint8_t *tmp;
size_t tmp_length, written;
peek_into_buf(buf, &tmp, &tmp_length);
@@ -176,7 +176,7 @@ static void new_ldap_client(int listen_sock)
static struct ldap_message *get_msg_from_buf(struct rw_buffer *buffer,
BOOL *error)
{
- uint8 *buf;
+ uint8_t *buf;
int buf_length, msg_length;
DATA_BLOB blob;
ASN1_DATA data;
diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c
index 890007ae389..5f1d37751df 100644
--- a/source/nsswitch/winbindd_pam.c
+++ b/source/nsswitch/winbindd_pam.c
@@ -419,21 +419,16 @@ done:
if ( NT_STATUS_IS_OK(result) &&
(state->request.flags & WBFLAG_PAM_AFS_TOKEN) ) {
- char *afsname = talloc_strdup(state->mem_ctx,
- lp_afs_username_map());
+ char *afsname = SMB_STRDUP(lp_afs_username_map());
char *cell;
if (afsname == NULL) {
goto no_token;
}
- afsname = talloc_string_sub(state->mem_ctx,
- lp_afs_username_map(),
- "%D", name_domain);
- afsname = talloc_string_sub(state->mem_ctx, afsname,
- "%u", name_user);
- afsname = talloc_string_sub(state->mem_ctx, afsname,
- "%U", name_user);
+ afsname = realloc_string_sub(afsname, "%D", name_domain);
+ afsname = realloc_string_sub(afsname, "%u", name_user);
+ afsname = realloc_string_sub(afsname, "%U", name_user);
{
DOM_SID user_sid;
@@ -442,8 +437,7 @@ done:
sid_copy(&user_sid, &info3.dom_sid.sid);
sid_append_rid(&user_sid, info3.user_rid);
sid_to_string(sidstr, &user_sid);
- afsname = talloc_string_sub(state->mem_ctx, afsname,
- "%s", sidstr);
+ afsname = realloc_string_sub(afsname, "%s", sidstr);
}
if (afsname == NULL) {
@@ -472,7 +466,7 @@ done:
strlen(state->response.extra_data)+1;
no_token:
- talloc_free(afsname);
+ SAFE_FREE(afsname);
}
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
diff --git a/source/nsswitch/winbindd_sid.c b/source/nsswitch/winbindd_sid.c
index fc878cb5ccb..2685e98555c 100644
--- a/source/nsswitch/winbindd_sid.c
+++ b/source/nsswitch/winbindd_sid.c
@@ -83,10 +83,10 @@ void winbindd_lookupname(struct winbindd_cli_state *state)
char *p;
/* Ensure null termination */
- state->request.data.name.dom_name[sizeof(state->request.data.name.dom_name)-1]='\0';
+ state->request.data.sid[sizeof(state->request.data.name.dom_name)-1]='\0';
/* Ensure null termination */
- state->request.data.name.name[sizeof(state->request.data.name.name)-1]='\0';
+ state->request.data.sid[sizeof(state->request.data.name.name)-1]='\0';
/* cope with the name being a fully qualified name */
p = strstr(state->request.data.name.name, lp_winbind_separator());
diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c
index 4c3306a8aca..efae9568845 100644
--- a/source/nsswitch/winbindd_util.c
+++ b/source/nsswitch/winbindd_util.c
@@ -106,6 +106,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
{
struct winbindd_domain *domain;
const char *alternative_name = NULL;
+ static const DOM_SID null_sid = {0};
/* ignore alt_name if we are not in an AD domain */
@@ -127,7 +128,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const
}
}
if (sid) {
- if (is_null_sid(sid)) {
+ if (sid_equal(sid, &null_sid) ) {
} else if (sid_equal(sid, &domain->sid)) {
return domain;
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 83a5b2fc3cf..526bce9b60e 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -294,7 +294,6 @@ typedef struct
BOOL bUnixExtensions;
BOOL bDisableNetbios;
BOOL bKernelChangeNotify;
- BOOL bFamChangeNotify;
BOOL bUseKerberosKeytab;
BOOL bDeferSharingViolations;
BOOL bEnablePrivileges;
@@ -993,7 +992,6 @@ static struct parm_struct parm_table[] = {
{"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
{"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED},
{"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED},
- {"fam change notify", P_BOOL, P_GLOBAL, &Globals.bFamChangeNotify, NULL, NULL, FLAG_ADVANCED},
{"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED},
{"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED},
@@ -1488,7 +1486,6 @@ static void init_globals(void)
Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
Globals.change_notify_timeout = 60; /* 1 minute default. */
Globals.bKernelChangeNotify = True; /* On if we have it. */
- Globals.bFamChangeNotify = True; /* On if we have it. */
Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
Globals.lm_interval = 60;
Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
@@ -1871,7 +1868,6 @@ FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
-FN_GLOBAL_BOOL(lp_fam_change_notify, &Globals.bFamChangeNotify)
FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
diff --git a/source/passdb/lookup_sid.c b/source/passdb/lookup_sid.c
index 4640eb6ae58..b397e084c33 100644
--- a/source/passdb/lookup_sid.c
+++ b/source/passdb/lookup_sid.c
@@ -22,247 +22,43 @@
#include "includes.h"
/*****************************************************************
- Dissect a user-provided name into domain, name, sid and type.
-
- If an explicit domain name was given in the form domain\user, it
- has to try that. If no explicit domain name was given, we have
- to do guesswork.
+ *THE CANONICAL* convert name to SID function.
+ Tries local lookup first - for local domains - then uses winbind.
*****************************************************************/
-BOOL lookup_name(TALLOC_CTX *mem_ctx,
- const char *full_name, int flags,
- const char **ret_domain, const char **ret_name,
- DOM_SID *ret_sid, enum SID_NAME_USE *ret_type)
+BOOL lookup_name(const char *domain, const char *name, DOM_SID *psid, enum SID_NAME_USE *name_type)
{
- char *p;
- const char *tmp;
- const char *domain = NULL;
- const char *name = NULL;
- uint32 rid;
- DOM_SID sid;
- enum SID_NAME_USE type;
- TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-
- if (tmp_ctx == NULL) {
- DEBUG(0, ("talloc_new failed\n"));
- return False;
- }
-
- p = strchr_m(full_name, '\\');
-
- if (p != NULL) {
- domain = talloc_strndup(tmp_ctx, full_name,
- PTR_DIFF(p, full_name));
- name = talloc_strdup(tmp_ctx, p+1);
- } else {
- domain = talloc_strdup(tmp_ctx, "");
- name = talloc_strdup(tmp_ctx, full_name);
- }
-
- if ((domain == NULL) || (name == NULL)) {
- DEBUG(0, ("talloc failed\n"));
- return False;
- }
+ fstring sid;
+ BOOL local_lookup = False;
+
+ *name_type = SID_NAME_UNKNOWN;
+ /* If we are looking up a domain user, make sure it is
+ for the local machine only */
+
if (strequal(domain, get_global_sam_name())) {
-
- /* It's our own domain, lookup the name in passdb */
- if (lookup_global_sam_name(name, &rid, &type)) {
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, rid);
- goto ok;
- }
- goto failed;
- }
-
- if (strequal(domain, builtin_domain_name())) {
-
- /* Explicit request for a name in BUILTIN */
- if (lookup_builtin_name(name, &rid)) {
- sid_copy(&sid, &global_sid_Builtin);
- sid_append_rid(&sid, rid);
- type = SID_NAME_ALIAS;
- goto ok;
- }
- goto failed;
- }
-
- if (domain[0] != '\0') {
- /* An explicit domain name was given, here our last resort is
- * winbind. */
- if (winbind_lookup_name(domain, name, &sid, &type)) {
- goto ok;
- }
- goto failed;
- }
-
- if (!(flags & LOOKUP_NAME_ISOLATED)) {
- goto failed;
- }
-
- /* Now the guesswork begins, we haven't been given an explicit
- * domain. Try the sequence as documented on
- * http://msdn.microsoft.com/library/en-us/secmgmt/security/lsalookupnames.asp
- * November 27, 2005 */
-
- /* 1. well-known names */
-
- {
- if (lookup_wellknown_name(tmp_ctx, name, &sid, &domain)) {
- type = SID_NAME_WKN_GRP;
- goto ok;
- }
- }
-
- /* 2. Builtin domain as such */
-
- if (strequal(name, builtin_domain_name())) {
- /* Swap domain and name */
- tmp = name; name = domain; domain = tmp;
- sid_copy(&sid, &global_sid_Builtin);
- type = SID_NAME_DOMAIN;
- goto ok;
- }
-
- /* 3. Account domain */
-
- if (strequal(name, get_global_sam_name())) {
- if (!secrets_fetch_domain_sid(name, &sid)) {
- DEBUG(3, ("Could not fetch my SID\n"));
- goto failed;
- }
- /* Swap domain and name */
- tmp = name; name = domain; domain = tmp;
- type = SID_NAME_DOMAIN;
- goto ok;
- }
-
- /* 4. Primary domain */
-
- if (!IS_DC && strequal(name, lp_workgroup())) {
- if (!secrets_fetch_domain_sid(name, &sid)) {
- DEBUG(3, ("Could not fetch the domain SID\n"));
- goto failed;
- }
- /* Swap domain and name */
- tmp = name; name = domain; domain = tmp;
- type = SID_NAME_DOMAIN;
- goto ok;
- }
-
- /* 5. Trusted domains as such, to me it looks as if members don't do
- this, tested an XP workstation in a NT domain -- vl */
-
- if (IS_DC && (secrets_fetch_trusted_domain_password(name, NULL,
- &sid, NULL))) {
- /* Swap domain and name */
- tmp = name; name = domain; domain = tmp;
- type = SID_NAME_DOMAIN;
- goto ok;
- }
-
- /* 6. Builtin aliases */
-
- if (lookup_builtin_name(name, &rid)) {
- domain = talloc_strdup(tmp_ctx, builtin_domain_name());
- sid_copy(&sid, &global_sid_Builtin);
- sid_append_rid(&sid, rid);
- type = SID_NAME_ALIAS;
- goto ok;
- }
-
- /* 7. Local systems' SAM (DCs don't have a local SAM) */
- /* 8. Primary SAM (On members, this is the domain) */
-
- /* Both cases are done by looking at our passdb */
-
- if (lookup_global_sam_name(name, &rid, &type)) {
- domain = talloc_strdup(tmp_ctx, get_global_sam_name());
- sid_copy(&sid, get_global_sam_sid());
- sid_append_rid(&sid, rid);
- goto ok;
- }
-
- /* Now our local possibilities are exhausted. */
-
- if (!(flags & LOOKUP_NAME_REMOTE)) {
- goto failed;
- }
-
- /* If we are not a DC, we have to ask in our primary domain. Let
- * winbind do that. */
-
- if (!IS_DC &&
- (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
- domain = talloc_strdup(tmp_ctx, lp_workgroup());
- goto ok;
- }
-
- /* 9. Trusted domains */
-
- /* If we're a DC we have to ask all trusted DC's. Winbind does not do
- * that (yet), but give it a chance. */
-
- if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
- DOM_SID dom_sid;
- uint32 tmp_rid;
- enum SID_NAME_USE domain_type;
-
- if (type == SID_NAME_DOMAIN) {
- /* Swap name and type */
- tmp = name; name = domain; domain = tmp;
- goto ok;
+ if (local_lookup_name(name, psid, name_type)) {
+ DEBUG(10,
+ ("lookup_name: (local) [%s]\\[%s] -> SID %s (type %s: %u)\n",
+ domain, name, sid_to_string(sid,psid),
+ sid_type_lookup(*name_type), (unsigned int)*name_type));
+ return True;
}
-
- /* Here we have to cope with a little deficiency in the
- * winbind API: We have to ask it again for the name of the
- * domain it figured out itself. Maybe fix that later... */
-
- sid_copy(&dom_sid, &sid);
- sid_split_rid(&dom_sid, &tmp_rid);
-
- if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
- &domain_type) ||
- (domain_type != SID_NAME_DOMAIN)) {
- DEBUG(2, ("winbind could not find the domain's name "
- "it just looked up for us\n"));
- goto failed;
+ } else {
+ /* Remote */
+ if (winbind_lookup_name(domain, name, psid, name_type)) {
+
+ DEBUG(10,("lookup_name (winbindd): [%s]\\[%s] -> SID %s (type %u)\n",
+ domain, name, sid_to_string(sid, psid),
+ (unsigned int)*name_type));
+ return True;
}
- goto ok;
}
+
+ DEBUG(10, ("lookup_name: %s lookup for [%s]\\[%s] failed\n",
+ local_lookup ? "local" : "winbind", domain, name));
- /* 10. Don't translate */
- failed:
- talloc_free(tmp_ctx);
return False;
-
- ok:
- if ((domain == NULL) || (name == NULL)) {
- DEBUG(0, ("talloc failed\n"));
- talloc_free(tmp_ctx);
- return False;
- }
-
- if (ret_name != NULL) {
- *ret_name = talloc_steal(mem_ctx, name);
- }
-
- if (ret_domain != NULL) {
- char *tmp_dom = talloc_strdup(tmp_ctx, domain);
- strupper_m(tmp_dom);
- *ret_domain = talloc_steal(mem_ctx, tmp_dom);
- }
-
- if (ret_sid != NULL) {
- sid_copy(ret_sid, &sid);
- }
-
- if (ret_type != NULL) {
- *ret_type = type;
- }
-
- talloc_free(tmp_ctx);
- return True;
}
/*****************************************************************
@@ -270,28 +66,22 @@ BOOL lookup_name(TALLOC_CTX *mem_ctx,
Tries local lookup first - for local sids, then tries winbind.
*****************************************************************/
-BOOL lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
- const char **ret_domain, const char **ret_name,
- enum SID_NAME_USE *ret_type)
+BOOL lookup_sid(const DOM_SID *sid, fstring dom_name, fstring name,
+ enum SID_NAME_USE *name_type)
{
- const char *domain = NULL;
- const char *name = NULL;
- enum SID_NAME_USE type;
- TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ if (!name_type)
+ return False;
+
+ *name_type = SID_NAME_UNKNOWN;
/* Check if this is our own sid. This should perhaps be done by
winbind? For the moment handle it here. */
- if (tmp_ctx == NULL) {
- DEBUG(0, ("talloc_new failed\n"));
- return False;
- }
-
if (sid_check_is_domain(sid)) {
- domain = talloc_strdup(tmp_ctx, get_global_sam_name());
- name = talloc_strdup(tmp_ctx, "");
- type = SID_NAME_DOMAIN;
- goto ok;
+ fstrcpy(dom_name, get_global_sam_name());
+ fstrcpy(name, "");
+ *name_type = SID_NAME_DOMAIN;
+ return True;
}
if (sid_check_is_in_our_domain(sid)) {
@@ -299,22 +89,22 @@ BOOL lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
SMB_ASSERT(sid_peek_rid(sid, &rid));
/* For our own domain passdb is responsible */
- if (!lookup_global_sam_rid(tmp_ctx, rid, &name, &type)) {
- goto failed;
- }
-
- domain = talloc_strdup(tmp_ctx, get_global_sam_name());
- goto ok;
+ fstrcpy(dom_name, get_global_sam_name());
+ return lookup_global_sam_rid(rid, name, name_type);
}
if (sid_check_is_builtin(sid)) {
- domain = talloc_strdup(tmp_ctx, builtin_domain_name());
+ /* Got through map_domain_sid_to_name here so that the mapping
+ * of S-1-5-32 to the name "BUILTIN" in as few places as
+ * possible. We might add i18n... */
+ SMB_ASSERT(map_domain_sid_to_name(sid, dom_name));
/* Yes, W2k3 returns "BUILTIN" both as domain and name here */
- name = talloc_strdup(tmp_ctx, builtin_domain_name());
- type = SID_NAME_DOMAIN;
- goto ok;
+ fstrcpy(name, dom_name);
+
+ *name_type = SID_NAME_DOMAIN;
+ return True;
}
if (sid_check_is_in_builtin(sid)) {
@@ -322,56 +112,39 @@ BOOL lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
SMB_ASSERT(sid_peek_rid(sid, &rid));
- if (!lookup_builtin_rid(tmp_ctx, rid, &name)) {
- goto failed;
- }
+ /* Got through map_domain_sid_to_name here so that the mapping
+ * of S-1-5-32 to the name "BUILTIN" in as few places as
+ * possible. We might add i18n... */
+ SMB_ASSERT(map_domain_sid_to_name(&global_sid_Builtin,
+ dom_name));
/* There's only aliases in S-1-5-32 */
- type = SID_NAME_ALIAS;
- domain = talloc_strdup(tmp_ctx, builtin_domain_name());
+ *name_type = SID_NAME_ALIAS;
- goto ok;
+ return lookup_builtin_rid(rid, name);
}
- if (winbind_lookup_sid(tmp_ctx, sid, &domain, &name, &type)) {
- goto ok;
+ if (winbind_lookup_sid(sid, dom_name, name, name_type)) {
+ return True;
}
DEBUG(10,("lookup_sid: winbind lookup for SID %s failed - trying "
"special SIDs.\n", sid_string_static(sid)));
- if (lookup_wellknown_sid(tmp_ctx, sid, &domain, &name)) {
- type = SID_NAME_WKN_GRP;
- goto ok;
- }
-
- failed:
- DEBUG(10, ("Failed to lookup sid %s\n", sid_string_static(sid)));
- talloc_free(tmp_ctx);
- return False;
-
- ok:
-
- if ((domain == NULL) || (name == NULL)) {
- DEBUG(0, ("talloc failed\n"));
- talloc_free(tmp_ctx);
- return False;
- }
-
- if (ret_domain != NULL) {
- *ret_domain = talloc_steal(mem_ctx, domain);
- }
-
- if (ret_name != NULL) {
- *ret_name = talloc_steal(mem_ctx, name);
+ {
+ const char *dom, *obj_name;
+
+ if (lookup_special_sid(sid, &dom, &obj_name, name_type)) {
+ DEBUG(10, ("found %s\\%s\n", dom, obj_name));
+ fstrcpy(dom_name, dom);
+ fstrcpy(name, obj_name);
+ return True;
+ }
}
- if (ret_type != NULL) {
- *ret_type = type;
- }
+ DEBUG(10, ("lookup_sid failed\n"));
- talloc_free(tmp_ctx);
- return True;
+ return False;
}
/*****************************************************************
@@ -414,9 +187,10 @@ static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid)
for (pc = uid_sid_cache_head; pc; pc = pc->next) {
if (pc->uid == uid) {
+ fstring sid;
*psid = pc->sid;
DEBUG(3,("fetch sid from uid cache %u -> %s\n",
- (unsigned int)uid, sid_string_static(psid)));
+ (unsigned int)uid, sid_to_string(sid, psid)));
DLIST_PROMOTE(uid_sid_cache_head, pc);
return True;
}
@@ -434,9 +208,10 @@ static BOOL fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid )
for (pc = uid_sid_cache_head; pc; pc = pc->next) {
if (sid_compare(&pc->sid, psid) == 0) {
+ fstring sid;
*puid = pc->uid;
DEBUG(3,("fetch uid from cache %u -> %s\n",
- (unsigned int)*puid, sid_string_static(psid)));
+ (unsigned int)*puid, sid_to_string(sid, psid)));
DLIST_PROMOTE(uid_sid_cache_head, pc);
return True;
}
@@ -486,9 +261,10 @@ static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid)
for (pc = gid_sid_cache_head; pc; pc = pc->next) {
if (pc->gid == gid) {
+ fstring sid;
*psid = pc->sid;
DEBUG(3,("fetch sid from gid cache %u -> %s\n",
- (unsigned int)gid, sid_string_static(psid)));
+ (unsigned int)gid, sid_to_string(sid, psid)));
DLIST_PROMOTE(gid_sid_cache_head, pc);
return True;
}
@@ -506,9 +282,10 @@ static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid)
for (pc = gid_sid_cache_head; pc; pc = pc->next) {
if (sid_compare(&pc->sid, psid) == 0) {
+ fstring sid;
*pgid = pc->gid;
DEBUG(3,("fetch gid from cache %u -> %s\n",
- (unsigned int)*pgid, sid_string_static(psid)));
+ (unsigned int)*pgid, sid_to_string(sid, psid)));
DLIST_PROMOTE(gid_sid_cache_head, pc);
return True;
}
@@ -554,6 +331,7 @@ static void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
{
+ fstring sid;
uid_t low, high;
ZERO_STRUCTP(psid);
@@ -570,7 +348,7 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
if (winbind_uid_to_sid(psid, uid)) {
DEBUG(10,("uid_to_sid: winbindd %u -> %s\n",
- (unsigned int)uid, sid_string_static(psid)));
+ (unsigned int)uid, sid_to_string(sid, psid)));
if (psid)
store_uid_sid_cache(psid, uid);
@@ -583,8 +361,7 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
return NT_STATUS_UNSUCCESSFUL;
}
- DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid,
- sid_string_static(psid)));
+ DEBUG(10,("uid_to_sid: local %u -> %s\n", (unsigned int)uid, sid_to_string(sid, psid)));
store_uid_sid_cache(psid, uid);
return NT_STATUS_OK;
@@ -596,6 +373,7 @@ NTSTATUS uid_to_sid(DOM_SID *psid, uid_t uid)
NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
{
+ fstring sid;
gid_t low, high;
ZERO_STRUCTP(psid);
@@ -612,7 +390,7 @@ NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
if (winbind_gid_to_sid(psid, gid)) {
DEBUG(10,("gid_to_sid: winbindd %u -> %s\n",
- (unsigned int)gid, sid_string_static(psid)));
+ (unsigned int)gid, sid_to_string(sid, psid)));
if (psid)
store_gid_sid_cache(psid, gid);
@@ -625,8 +403,7 @@ NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
return NT_STATUS_UNSUCCESSFUL;
}
- DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid,
- sid_string_static(psid)));
+ DEBUG(10,("gid_to_sid: local %u -> %s\n", (unsigned int)gid, sid_to_string(sid, psid)));
store_gid_sid_cache(psid, gid);
return NT_STATUS_OK;
@@ -638,6 +415,7 @@ NTSTATUS gid_to_sid(DOM_SID *psid, gid_t gid)
NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid)
{
+ fstring dom_name, name, sid_str;
enum SID_NAME_USE name_type;
if (fetch_uid_from_cache(puid, psid))
@@ -659,7 +437,7 @@ NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid)
/* If it is not our local domain, only hope is winbindd */
- if ( !winbind_lookup_sid(NULL, psid, NULL, NULL, &name_type) ) {
+ if ( !winbind_lookup_sid(psid, dom_name, name, &name_type) ) {
DEBUG(10,("sid_to_uid: winbind lookup for non-local sid %s failed\n",
sid_string_static(psid) ));
@@ -678,12 +456,12 @@ NTSTATUS sid_to_uid(const DOM_SID *psid, uid_t *puid)
if ( !winbind_sid_to_uid(puid, psid) ) {
DEBUG(10,("sid_to_uid: winbind failed to allocate a new uid for sid %s\n",
- sid_string_static(psid)));
+ sid_to_string(sid_str, psid) ));
return NT_STATUS_UNSUCCESSFUL;
}
success:
- DEBUG(10,("sid_to_uid: %s -> %u\n", sid_string_static(psid),
+ DEBUG(10,("sid_to_uid: %s -> %u\n", sid_to_string(sid_str, psid),
(unsigned int)*puid ));
store_uid_sid_cache(psid, *puid);
@@ -697,6 +475,7 @@ success:
NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
{
+ fstring dom_name, name, sid_str;
enum SID_NAME_USE name_type;
if (fetch_gid_from_cache(pgid, psid))
@@ -710,9 +489,8 @@ NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
if ( local_sid_to_gid(pgid, psid, &name_type) )
goto success;
- if (!winbind_lookup_sid(NULL, psid, NULL, NULL, &name_type)) {
- DEBUG(10,("sid_to_gid: no one knows the SID %s (tried local, then "
- "winbind)\n", sid_string_static(psid)));
+ if (!winbind_lookup_sid(psid, dom_name, name, &name_type)) {
+ DEBUG(10,("sid_to_gid: no one knows the SID %s (tried local, then winbind)\n", sid_to_string(sid_str, psid)));
return NT_STATUS_UNSUCCESSFUL;
}
@@ -736,13 +514,13 @@ NTSTATUS sid_to_gid(const DOM_SID *psid, gid_t *pgid)
if ( !winbind_sid_to_gid(pgid, psid) ) {
DEBUG(10,("sid_to_gid: winbind failed to allocate a new gid for sid %s\n",
- sid_string_static(psid)));
+ sid_to_string(sid_str, psid) ));
return NT_STATUS_UNSUCCESSFUL;
}
success:
- DEBUG(10,("sid_to_gid: %s -> %u\n", sid_string_static(psid),
- (unsigned int)*pgid ));
+ DEBUG(10,("sid_to_gid: %s -> %u\n", sid_to_string(sid_str, psid),
+ (unsigned int)*pgid ));
store_gid_sid_cache(psid, *pgid);
diff --git a/source/passdb/machine_sid.c b/source/passdb/machine_sid.c
index 074a516bcb6..87ec27d34ea 100644
--- a/source/passdb/machine_sid.c
+++ b/source/passdb/machine_sid.c
@@ -198,27 +198,3 @@ void reset_global_sam_sid(void)
{
SAFE_FREE(global_sam_sid);
}
-
-/*****************************************************************
- Check if the SID is our domain SID (S-1-5-21-x-y-z).
-*****************************************************************/
-
-BOOL sid_check_is_domain(const DOM_SID *sid)
-{
- return sid_equal(sid, get_global_sam_sid());
-}
-
-/*****************************************************************
- Check if the SID is our domain SID (S-1-5-21-x-y-z).
-*****************************************************************/
-
-BOOL sid_check_is_in_our_domain(const DOM_SID *sid)
-{
- DOM_SID dom_sid;
- uint32 rid;
-
- sid_copy(&dom_sid, sid);
- sid_split_rid(&dom_sid, &rid);
-
- return sid_equal(&dom_sid, get_global_sam_sid());
-}
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index f9f6021d81b..20aa4e04f2f 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -566,8 +566,8 @@ BOOL pdb_gethexpwd(const char *p, unsigned char *pwd)
return (False);
for (i = 0; i < 32; i += 2) {
- hinybble = toupper_ascii(p[i]);
- lonybble = toupper_ascii(p[i + 1]);
+ hinybble = toupper(p[i]);
+ lonybble = toupper(p[i + 1]);
p1 = strchr(hexchars, hinybble);
p2 = strchr(hexchars, lonybble);
@@ -616,8 +616,8 @@ BOOL pdb_gethexhours(const char *p, unsigned char *hours)
}
for (i = 0; i < 42; i += 2) {
- hinybble = toupper_ascii(p[i]);
- lonybble = toupper_ascii(p[i + 1]);
+ hinybble = toupper(p[i]);
+ lonybble = toupper(p[i + 1]);
p1 = strchr(hexchars, hinybble);
p2 = strchr(hexchars, lonybble);
@@ -735,7 +735,7 @@ BOOL algorithmic_pdb_rid_is_user(uint32 rid)
Look up a rid in the SAM we're responsible for (i.e. passdb)
********************************************************************/
-BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid, const char **name,
+BOOL lookup_global_sam_rid(uint32 rid, fstring name,
enum SID_NAME_USE *psid_name_use)
{
SAM_ACCOUNT *sam_account = NULL;
@@ -760,7 +760,7 @@ BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid, const char **name,
become_root();
if (pdb_getsampwsid(sam_account, &sid)) {
unbecome_root(); /* -----> EXIT BECOME_ROOT() */
- *name = talloc_strdup(mem_ctx, pdb_get_username(sam_account));
+ fstrcpy(name, pdb_get_username(sam_account));
*psid_name_use = SID_NAME_USER;
pdb_free_sam(&sam_account);
@@ -784,14 +784,14 @@ BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid, const char **name,
map.nt_name));
}
- *name = talloc_strdup(mem_ctx, map.nt_name);
+ fstrcpy(name, map.nt_name);
*psid_name_use = map.sid_name_use;
return True;
}
if (rid == DOMAIN_USER_RID_ADMIN) {
*psid_name_use = SID_NAME_USER;
- *name = talloc_strdup(mem_ctx, "Administrator");
+ fstrcpy(name, "Administrator");
return True;
}
@@ -807,15 +807,13 @@ BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid, const char **name,
DEBUG(5,("lookup_global_sam_rid: looking up uid %u %s\n",
(unsigned int)uid, pw ? "succeeded" : "failed" ));
- if ( !pw ) {
- *name = talloc_asprintf(mem_ctx, "unix_user.%u",
- (unsigned int)uid);
- } else {
- *name = talloc_strdup(mem_ctx, pw->pw_name );
- }
+ if ( !pw )
+ fstr_sprintf(name, "unix_user.%u", (unsigned int)uid);
+ else
+ fstrcpy( name, pw->pw_name );
DEBUG(5,("lookup_global_sam_rid: found user %s for rid %u\n",
- *name, (unsigned int)rid ));
+ name, (unsigned int)rid ));
*psid_name_use = SID_NAME_USER;
@@ -832,15 +830,13 @@ BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid, const char **name,
DEBUG(5,("lookup_global_sam_rid: looking up gid %u %s\n",
(unsigned int)gid, gr ? "succeeded" : "failed" ));
- if( !gr ) {
- *name = talloc_asprintf(mem_ctx, "unix_group.%u",
- (unsigned int)gid);
- } else {
- *name = talloc_strdup(mem_ctx, gr->gr_name);
- }
+ if( !gr )
+ fstr_sprintf(name, "unix_group.%u", (unsigned int)gid);
+ else
+ fstrcpy( name, gr->gr_name);
DEBUG(5,("lookup_global_sam_rid: found group %s for rid %u\n",
- *name, (unsigned int)rid ));
+ name, (unsigned int)rid ));
/* assume algorithmic groups are domain global groups */
@@ -854,13 +850,17 @@ BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid, const char **name,
Convert a name into a SID. Used in the lookup name rpc.
********************************************************************/
-BOOL lookup_global_sam_name(const char *c_user, uint32_t *rid, enum SID_NAME_USE *type)
+BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
{
+ DOM_SID local_sid;
+ DOM_SID sid;
fstring user;
SAM_ACCOUNT *sam_account = NULL;
struct group *grp;
GROUP_MAP map;
+ *psid_name_use = SID_NAME_UNKNOWN;
+
/*
* user may be quoted a const string, and map_username and
* friends can modify it. Make a modifiable copy. JRA.
@@ -868,6 +868,17 @@ BOOL lookup_global_sam_name(const char *c_user, uint32_t *rid, enum SID_NAME_USE
fstrcpy(user, c_user);
+ sid_copy(&local_sid, get_global_sam_sid());
+
+ if (map_name_to_wellknown_sid(&sid, psid_name_use, user)){
+ fstring sid_str;
+ sid_copy( psid, &sid);
+ sid_to_string(sid_str, &sid);
+ DEBUG(10,("lookup_name: name %s = SID %s, type = %u\n", user, sid_str,
+ (unsigned int)*psid_name_use ));
+ return True;
+ }
+
(void)map_username(user);
if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
@@ -878,28 +889,10 @@ BOOL lookup_global_sam_name(const char *c_user, uint32_t *rid, enum SID_NAME_USE
become_root();
if (pdb_getsampwnam(sam_account, user)) {
- const DOM_SID *user_sid;
-
unbecome_root();
-
- user_sid = pdb_get_user_sid(sam_account);
-
- if (!sid_check_is_in_our_domain(user_sid)) {
- DEBUG(0, ("User %s with invalid SID %s in passdb\n",
- user, sid_string_static(user_sid)));
- return False;
- }
-
- sid_peek_rid(user_sid, rid);
-
- if (pdb_get_acct_ctrl(sam_account) &
- (ACB_DOMTRUST|ACB_WSTRUST|ACB_SVRTRUST)) {
- /* We have to filter them out in lsa_lookupnames,
- * indicate that this is not a real user. */
- *type = SID_NAME_COMPUTER;
- } else {
- *type = SID_NAME_USER;
- }
+ sid_copy(psid, pdb_get_user_sid(sam_account));
+ *psid_name_use = SID_NAME_USER;
+
pdb_free_sam(&sam_account);
return True;
}
@@ -912,51 +905,41 @@ BOOL lookup_global_sam_name(const char *c_user, uint32_t *rid, enum SID_NAME_USE
/* check if it's a mapped group */
if (pdb_getgrnam(&map, user)) {
-
- unbecome_root();
-
- /* BUILTIN groups are looked up elsewhere */
- if (!sid_check_is_in_our_domain(&map.sid)) {
- DEBUG(10, ("Found group %s (%s) not in our domain -- "
- "ignoring.", user,
- sid_string_static(&map.sid)));
+ /* yes it's a mapped group */
+ sid_copy(&local_sid, &map.sid);
+ *psid_name_use = map.sid_name_use;
+ } else {
+ /* it's not a mapped group */
+ grp = getgrnam(user);
+ if(!grp) {
+ unbecome_root(); /* ---> exit form block */
return False;
}
- /* yes it's a mapped group */
- sid_peek_rid(&map.sid, rid);
- *type = map.sid_name_use;
- return True;
- }
-
- /* it's not a mapped group */
- grp = getgrnam(user);
- if(!grp) {
- unbecome_root(); /* ---> exit form block */
- return False;
- }
+ /*
+ *check if it's mapped, if it is reply it doesn't exist
+ *
+ * that's to prevent this case:
+ *
+ * unix group ug is mapped to nt group ng
+ * someone does a lookup on ug
+ * we must not reply as it doesn't "exist" anymore
+ * for NT. For NT only ng exists.
+ * JFM, 30/11/2001
+ */
- /*
- *check if it's mapped, if it is reply it doesn't exist
- *
- * that's to prevent this case:
- *
- * unix group ug is mapped to nt group ng
- * someone does a lookup on ug
- * we must not reply as it doesn't "exist" anymore
- * for NT. For NT only ng exists.
- * JFM, 30/11/2001
- */
+ if (pdb_getgrgid(&map, grp->gr_gid)){
+ unbecome_root(); /* ---> exit form block */
+ return False;
+ }
- if (pdb_getgrgid(&map, grp->gr_gid)) {
- unbecome_root(); /* ---> exit form block */
- return False;
+ sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
+ *psid_name_use = SID_NAME_ALIAS;
}
unbecome_root();
/* END ROOT BLOCK */
- *rid = pdb_gid_to_group_rid(grp->gr_gid);
- *type = SID_NAME_ALIAS;
+ sid_copy( psid, &local_sid);
return True;
}
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
index 4808af39081..875e264bf01 100644
--- a/source/passdb/pdb_interface.c
+++ b/source/passdb/pdb_interface.c
@@ -699,25 +699,6 @@ static NTSTATUS context_lookup_rids(struct pdb_context *context,
rids, pp_names, pp_attrs);
}
-static NTSTATUS context_lookup_names(struct pdb_context *context,
- const DOM_SID *domain_sid,
- size_t num_names,
- const char **pp_names,
- uint32 *rids,
- uint32 *pp_attrs)
-{
- NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
- if ((!context) || (!context->pdb_methods)) {
- DEBUG(0, ("invalid pdb_context specified!\n"));
- return ret;
- }
-
- return context->pdb_methods->lookup_names(context->pdb_methods,
- domain_sid, num_names,
- pp_names, rids, pp_attrs);
-}
-
static NTSTATUS context_get_account_policy(struct pdb_context *context,
int policy_index, uint32 *value)
{
@@ -925,7 +906,6 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
(*context)->pdb_enum_aliasmem = context_enum_aliasmem;
(*context)->pdb_enum_alias_memberships = context_enum_alias_memberships;
(*context)->pdb_lookup_rids = context_lookup_rids;
- (*context)->pdb_lookup_names = context_lookup_names;
(*context)->pdb_get_account_policy = context_get_account_policy;
(*context)->pdb_set_account_policy = context_set_account_policy;
@@ -1433,22 +1413,6 @@ NTSTATUS pdb_lookup_rids(const DOM_SID *domain_sid,
num_rids, rids, names, attrs);
}
-NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid,
- int num_names,
- const char **names,
- uint32 *rids,
- uint32 *attrs)
-{
- struct pdb_context *pdb_context = pdb_get_static_context(False);
-
- if (!pdb_context) {
- return NT_STATUS_NOT_IMPLEMENTED;
- }
-
- return pdb_context->pdb_lookup_names(pdb_context, domain_sid,
- num_names, names, rids, attrs);
-}
-
BOOL pdb_get_account_policy(int policy_index, uint32 *value)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -1691,11 +1655,14 @@ NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
if (sid_check_is_builtin(domain_sid)) {
for (i=0; i<num_rids; i++) {
- const char *name;
+ fstring name;
- if (lookup_builtin_rid(names, rids[i], &name)) {
+ if (lookup_builtin_rid(rids[i], name)) {
attrs[i] = SID_NAME_ALIAS;
- names[i] = name;
+ names[i] = talloc_strdup(names, name);
+ if (names[i] == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
DEBUG(5,("lookup_rids: %s:%d\n",
names[i], attrs[i]));
have_mapped = True;
@@ -1713,69 +1680,14 @@ NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
}
for (i = 0; i < num_rids; i++) {
- const char *name;
-
- if (lookup_global_sam_rid(names, rids[i], &name, &attrs[i])) {
- names[i] = name;
- DEBUG(5,("lookup_rids: %s:%d\n", names[i], attrs[i]));
- have_mapped = True;
- } else {
- have_unmapped = True;
- attrs[i] = SID_NAME_UNKNOWN;
- }
- }
-
- done:
-
- result = NT_STATUS_NONE_MAPPED;
-
- if (have_mapped)
- result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
-
- return result;
-}
-
-NTSTATUS pdb_default_lookup_names(struct pdb_methods *methods,
- const DOM_SID *domain_sid,
- int num_names,
- const char **names,
- uint32 *rids,
- uint32 *attrs)
-{
- int i;
- NTSTATUS result;
- BOOL have_mapped = False;
- BOOL have_unmapped = False;
-
- if (sid_check_is_builtin(domain_sid)) {
-
- for (i=0; i<num_names; i++) {
- uint32 rid;
-
- if (lookup_builtin_name(names[i], &rid)) {
- attrs[i] = SID_NAME_ALIAS;
- rids[i] = rid;
- DEBUG(5,("lookup_rids: %s:%d\n",
- names[i], attrs[i]));
- have_mapped = True;
- } else {
- have_unmapped = True;
- attrs[i] = SID_NAME_UNKNOWN;
- }
- }
- goto done;
- }
-
- /* Should not happen, but better check once too many */
- if (!sid_check_is_domain(domain_sid)) {
- return NT_STATUS_INVALID_HANDLE;
- }
-
- for (i = 0; i < num_names; i++) {
- const char *name;
-
- if (lookup_global_sam_rid(names, rids[i], &name, &attrs[i])) {
- names[i] = name;
+ fstring tmpname;
+ enum SID_NAME_USE type;
+
+ if (lookup_global_sam_rid(rids[i], tmpname, &type)) {
+ attrs[i] = (uint32)type;
+ names[i] = talloc_strdup(names, tmpname);
+ if (names[i] == NULL)
+ return NT_STATUS_NO_MEMORY;
DEBUG(5,("lookup_rids: %s:%d\n", names[i], attrs[i]));
have_mapped = True;
} else {
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index b35ce18eee5..9f0d530424e 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -3638,10 +3638,6 @@ static NTSTATUS ldapsam_lookup_rids(struct pdb_methods *methods,
goto done;
}
- if (msg != NULL) {
- ldap_msgfree(msg);
- }
-
/* Same game for groups */
{
@@ -3727,7 +3723,8 @@ char *get_ldap_filter(TALLOC_CTX *mem_ctx, const char *username)
escaped = escape_ldap_string_alloc(username);
if (escaped == NULL) goto done;
- result = talloc_string_sub(mem_ctx, filter, "%u", username);
+ filter = realloc_string_sub(filter, "%u", username);
+ result = talloc_strdup(mem_ctx, filter);
done:
SAFE_FREE(filter);
@@ -4074,9 +4071,6 @@ static BOOL ldapgroup2displayentry(struct ldap_search_state *state,
vals = ldap_get_values(ld, entry, "sambaGroupType");
if ((vals == NULL) || (vals[0] == NULL)) {
DEBUG(5, ("\"sambaGroupType\" not found\n"));
- if (vals != NULL) {
- ldap_value_free(vals);
- }
return False;
}
@@ -4084,12 +4078,9 @@ static BOOL ldapgroup2displayentry(struct ldap_search_state *state,
if ((state->group_type != 0) &&
((state->group_type != group_type))) {
- ldap_value_free(vals);
return False;
}
- ldap_value_free(vals);
-
/* display name is the NT group name */
vals = ldap_get_values(ld, entry, "displayName");
@@ -4129,9 +4120,6 @@ static BOOL ldapgroup2displayentry(struct ldap_search_state *state,
vals = ldap_get_values(ld, entry, "sambaSid");
if ((vals == NULL) || (vals[0] == NULL)) {
DEBUG(0, ("\"objectSid\" not found\n"));
- if (vals != NULL) {
- ldap_value_free(vals);
- }
return False;
}
diff --git a/source/passdb/pdb_nds.c b/source/passdb/pdb_nds.c
index cf2d1d7c8a8..1ec96932231 100644
--- a/source/passdb/pdb_nds.c
+++ b/source/passdb/pdb_nds.c
@@ -807,7 +807,7 @@ static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods,
if((success != True) || (got_clear_text_pw == True)) {
- rc = smb_ldap_setup_full_conn(&ld, ldap_state->location);
+ rc = smb_ldap_setup_full_conn(ld, ldap_state->location);
if (rc) {
return NT_STATUS_INVALID_CONNECTION;
}
diff --git a/source/passdb/pdb_pgsql.c b/source/passdb/pdb_pgsql.c
index 196fe8f855d..632903c1ac3 100644
--- a/source/passdb/pdb_pgsql.c
+++ b/source/passdb/pdb_pgsql.c
@@ -368,7 +368,7 @@ static NTSTATUS pgsqlsam_getsampwnam ( struct pdb_methods *methods, SAM_ACCOUNT
lowercasename = smb_xstrdup(sname);
l = strlen(lowercasename);
for(i = 0; i < l; i++) {
- lowercasename[i] = tolower_ascii(lowercasename[i]);
+ lowercasename[i] = tolower(lowercasename[i]);
}
result = pgsqlsam_select_by_field( methods, user, SQL_SEARCH_USER_NAME, lowercasename ) ;
diff --git a/source/passdb/util_builtin.c b/source/passdb/util_builtin.c
deleted file mode 100644
index 12a98d24ddb..00000000000
--- a/source/passdb/util_builtin.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Translate BUILTIN names to SIDs and vice versa
- Copyright (C) Volker Lendecke 2005
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-struct rid_name_map {
- uint32 rid;
- const char *name;
-};
-
-static const struct rid_name_map builtin_aliases[] = {
- { BUILTIN_ALIAS_RID_ADMINS, "Administrators" },
- { BUILTIN_ALIAS_RID_USERS, "Users" },
- { BUILTIN_ALIAS_RID_GUESTS, "Guests" },
- { BUILTIN_ALIAS_RID_POWER_USERS, "Power Users" },
- { BUILTIN_ALIAS_RID_ACCOUNT_OPS, "Account Operators" },
- { BUILTIN_ALIAS_RID_SYSTEM_OPS, "Server Operators" },
- { BUILTIN_ALIAS_RID_PRINT_OPS, "Print Operators" },
- { BUILTIN_ALIAS_RID_BACKUP_OPS, "Backup Operators" },
- { BUILTIN_ALIAS_RID_REPLICATOR, "Replicator" },
- { BUILTIN_ALIAS_RID_RAS_SERVERS, "RAS Servers" },
- { BUILTIN_ALIAS_RID_PRE_2K_ACCESS, "Pre-Windows 2000 Compatible Access" },
- { 0, NULL}};
-
-/*******************************************************************
- Look up a rid in the BUILTIN domain
- ********************************************************************/
-BOOL lookup_builtin_rid(TALLOC_CTX *mem_ctx, uint32 rid, const char **name)
-{
- const struct rid_name_map *aliases = builtin_aliases;
-
- while (aliases->name != NULL) {
- if (rid == aliases->rid) {
- *name = talloc_strdup(mem_ctx, aliases->name);
- return True;
- }
- aliases++;
- }
-
- return False;
-}
-
-/*******************************************************************
- Look up a name in the BUILTIN domain
- ********************************************************************/
-BOOL lookup_builtin_name(const char *name, uint32 *rid)
-{
- const struct rid_name_map *aliases = builtin_aliases;
-
- while (aliases->name != NULL) {
- if (strequal(name, aliases->name)) {
- *rid = aliases->rid;
- return True;
- }
- aliases++;
- }
-
- return False;
-}
-
-/*****************************************************************
- Return the name of the BUILTIN domain
-*****************************************************************/
-
-const char *builtin_domain_name(void)
-{
- return "BUILTIN";
-}
-
-/*****************************************************************
- Check if the SID is the builtin SID (S-1-5-32).
-*****************************************************************/
-
-BOOL sid_check_is_builtin(const DOM_SID *sid)
-{
- return sid_equal(sid, &global_sid_Builtin);
-}
-
-/*****************************************************************
- Check if the SID is one of the builtin SIDs (S-1-5-32-a).
-*****************************************************************/
-
-BOOL sid_check_is_in_builtin(const DOM_SID *sid)
-{
- DOM_SID dom_sid;
- uint32 rid;
-
- sid_copy(&dom_sid, sid);
- sid_split_rid(&dom_sid, &rid);
-
- return sid_equal(&dom_sid, &global_sid_Builtin);
-}
-
diff --git a/source/passdb/util_sam_sid.c b/source/passdb/util_sam_sid.c
new file mode 100644
index 00000000000..822b7f6a349
--- /dev/null
+++ b/source/passdb/util_sam_sid.c
@@ -0,0 +1,238 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
+ Copyright (C) Jeremy Allison 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+#define MAX_SID_NAMES 7
+
+typedef struct _known_sid_users {
+ uint32 rid;
+ enum SID_NAME_USE sid_name_use;
+ const char *known_user_name;
+} known_sid_users;
+
+struct sid_name_map_info
+{
+ const DOM_SID *sid;
+ const char *name;
+ const known_sid_users *known_users;
+};
+
+static const known_sid_users everyone_users[] = {
+ { 0, SID_NAME_WKN_GRP, "Everyone" },
+ {0, (enum SID_NAME_USE)0, NULL}};
+
+static const known_sid_users creator_owner_users[] = {
+ { 0, SID_NAME_WKN_GRP, "Creator Owner" },
+ { 1, SID_NAME_WKN_GRP, "Creator Group" },
+ {0, (enum SID_NAME_USE)0, NULL}};
+
+static const known_sid_users nt_authority_users[] = {
+ { 1, SID_NAME_WKN_GRP, "Dialup" },
+ { 2, SID_NAME_WKN_GRP, "Network"},
+ { 3, SID_NAME_WKN_GRP, "Batch"},
+ { 4, SID_NAME_WKN_GRP, "Interactive"},
+ { 6, SID_NAME_WKN_GRP, "Service"},
+ { 7, SID_NAME_WKN_GRP, "AnonymousLogon"},
+ { 8, SID_NAME_WKN_GRP, "Proxy"},
+ { 9, SID_NAME_WKN_GRP, "ServerLogon"},
+ { 10, SID_NAME_WKN_GRP, "Self"},
+ { 11, SID_NAME_WKN_GRP, "Authenticated Users"},
+ { 12, SID_NAME_WKN_GRP, "Restricted"},
+ { 13, SID_NAME_WKN_GRP, "Terminal Server User"},
+ { 14, SID_NAME_WKN_GRP, "Remote Interactive Logon"},
+ { 15, SID_NAME_WKN_GRP, "This Organization"},
+ { 18, SID_NAME_WKN_GRP, "SYSTEM"},
+ { 19, SID_NAME_WKN_GRP, "Local Service"},
+ { 20, SID_NAME_WKN_GRP, "Network Service"},
+ { 0, (enum SID_NAME_USE)0, NULL}};
+
+static const known_sid_users builtin_groups[] = {
+ { BUILTIN_ALIAS_RID_ADMINS, SID_NAME_ALIAS, "Administrators" },
+ { BUILTIN_ALIAS_RID_USERS, SID_NAME_ALIAS, "Users" },
+ { BUILTIN_ALIAS_RID_GUESTS, SID_NAME_ALIAS, "Guests" },
+ { BUILTIN_ALIAS_RID_POWER_USERS, SID_NAME_ALIAS, "Power Users" },
+ { BUILTIN_ALIAS_RID_ACCOUNT_OPS, SID_NAME_ALIAS, "Account Operators" },
+ { BUILTIN_ALIAS_RID_SYSTEM_OPS, SID_NAME_ALIAS, "Server Operators" },
+ { BUILTIN_ALIAS_RID_PRINT_OPS, SID_NAME_ALIAS, "Print Operators" },
+ { BUILTIN_ALIAS_RID_BACKUP_OPS, SID_NAME_ALIAS, "Backup Operators" },
+ { BUILTIN_ALIAS_RID_REPLICATOR, SID_NAME_ALIAS, "Replicator" },
+ { BUILTIN_ALIAS_RID_RAS_SERVERS, SID_NAME_ALIAS, "RAS Servers" },
+ { BUILTIN_ALIAS_RID_PRE_2K_ACCESS, SID_NAME_ALIAS, "Pre-Windows 2000 Compatible Access" },
+ { 0, (enum SID_NAME_USE)0, NULL}};
+
+static struct sid_name_map_info special_domains[] = {
+ { &global_sid_Builtin, "BUILTIN", builtin_groups },
+ { &global_sid_World_Domain, "", everyone_users },
+ { &global_sid_Creator_Owner_Domain, "", creator_owner_users },
+ { &global_sid_NT_Authority, "NT Authority", nt_authority_users },
+ { NULL, NULL, NULL }};
+
+/**************************************************************************
+ Turns a domain SID into a name, returned in the nt_domain argument.
+***************************************************************************/
+
+BOOL map_domain_sid_to_name(const DOM_SID *sid, fstring nt_domain)
+{
+ fstring sid_str;
+ int i = 0;
+
+ sid_to_string(sid_str, sid);
+
+ DEBUG(5,("map_domain_sid_to_name: %s\n", sid_str));
+
+ while (special_domains[i].sid != NULL) {
+ DEBUG(5,("map_domain_sid_to_name: compare: %s\n",
+ sid_string_static(special_domains[i].sid)));
+ if (sid_equal(special_domains[i].sid, sid)) {
+ fstrcpy(nt_domain, special_domains[i].name);
+ DEBUG(5,("map_domain_sid_to_name: found '%s'\n",
+ nt_domain));
+ return True;
+ }
+ i++;
+ }
+
+ DEBUG(5,("map_domain_sid_to_name: mapping for %s not found\n",
+ sid_string_static(sid)));
+
+ return False;
+}
+
+/**************************************************************************
+ Looks up a known username from one of the known domains.
+***************************************************************************/
+
+BOOL lookup_special_sid(const DOM_SID *sid, const char **domain,
+ const char **name, enum SID_NAME_USE *type)
+{
+ int i;
+ DOM_SID dom_sid;
+ uint32 rid;
+ const known_sid_users *users = NULL;
+
+ sid_copy(&dom_sid, sid);
+ if (!sid_split_rid(&dom_sid, &rid)) {
+ DEBUG(2, ("Could not split rid from SID\n"));
+ return False;
+ }
+
+ for (i=0; special_domains[i].sid != NULL; i++) {
+ if (sid_equal(&dom_sid, special_domains[i].sid)) {
+ *domain = special_domains[i].name;
+ users = special_domains[i].known_users;
+ break;
+ }
+ }
+
+ if (users == NULL) {
+ DEBUG(10, ("SID %s is no special sid\n",
+ sid_string_static(sid)));
+ return False;
+ }
+
+ for (i=0; users[i].known_user_name != NULL; i++) {
+ if (rid == users[i].rid) {
+ *name = users[i].known_user_name;
+ *type = users[i].sid_name_use;
+ return True;
+ }
+ }
+
+ DEBUG(10, ("RID of special SID %s not found\n",
+ sid_string_static(sid)));
+
+ return False;
+}
+
+/*******************************************************************
+ Look up a rid in the BUILTIN domain
+ ********************************************************************/
+BOOL lookup_builtin_rid(uint32 rid, fstring name)
+{
+ const known_sid_users *aliases = builtin_groups;
+ int i;
+
+ for (i=0; aliases[i].known_user_name != NULL; i++) {
+ if (rid == aliases[i].rid) {
+ fstrcpy(name, aliases[i].known_user_name);
+ return True;
+ }
+ }
+
+ return False;
+}
+
+/*****************************************************************
+ Check if the SID is our domain SID (S-1-5-21-x-y-z).
+*****************************************************************/
+
+BOOL sid_check_is_domain(const DOM_SID *sid)
+{
+ return sid_equal(sid, get_global_sam_sid());
+}
+
+/*****************************************************************
+ Check if the SID is our domain SID (S-1-5-21-x-y-z).
+*****************************************************************/
+
+BOOL sid_check_is_in_our_domain(const DOM_SID *sid)
+{
+ DOM_SID dom_sid;
+ uint32 rid;
+
+ sid_copy(&dom_sid, sid);
+ sid_split_rid(&dom_sid, &rid);
+
+ return sid_equal(&dom_sid, get_global_sam_sid());
+}
+
+/**************************************************************************
+ Try and map a name to one of the well known SIDs.
+***************************************************************************/
+
+BOOL map_name_to_wellknown_sid(DOM_SID *sid, enum SID_NAME_USE *use, const char *name)
+{
+ int i, j;
+
+ DEBUG(10,("map_name_to_wellknown_sid: looking up %s\n", name));
+
+ for (i=0; special_domains[i].sid != NULL; i++) {
+ const known_sid_users *users = special_domains[i].known_users;
+
+ if (users == NULL)
+ continue;
+
+ for (j=0; users[j].known_user_name != NULL; j++) {
+ if ( strequal(users[j].known_user_name, name) ) {
+ sid_copy(sid, special_domains[i].sid);
+ sid_append_rid(sid, users[j].rid);
+ *use = users[j].sid_name_use;
+ return True;
+ }
+ }
+ }
+
+ return False;
+}
+
+
diff --git a/source/passdb/util_wellknown.c b/source/passdb/util_wellknown.c
deleted file mode 100644
index 8caae3b2a01..00000000000
--- a/source/passdb/util_wellknown.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Lookup routines for well-known SIDs
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
- Copyright (C) Jeremy Allison 1999
- Copyright (C) Volker Lendecke 2005
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-struct rid_name_map {
- uint32 rid;
- const char *name;
-};
-
-struct sid_name_map_info
-{
- const DOM_SID *sid;
- const char *name;
- const struct rid_name_map *known_users;
-};
-
-static const struct rid_name_map everyone_users[] = {
- { 0, "Everyone" },
- { 0, NULL}};
-
-static const struct rid_name_map creator_owner_users[] = {
- { 0, "Creator Owner" },
- { 1, "Creator Group" },
- { 0, NULL}};
-
-static const struct rid_name_map nt_authority_users[] = {
- { 1, "Dialup" },
- { 2, "Network"},
- { 3, "Batch"},
- { 4, "Interactive"},
- { 6, "Service"},
- { 7, "AnonymousLogon"},
- { 8, "Proxy"},
- { 9, "ServerLogon"},
- { 10, "Self"},
- { 11, "Authenticated Users"},
- { 12, "Restricted"},
- { 13, "Terminal Server User"},
- { 14, "Remote Interactive Logon"},
- { 15, "This Organization"},
- { 18, "SYSTEM"},
- { 19, "Local Service"},
- { 20, "Network Service"},
- { 0, NULL}};
-
-static struct sid_name_map_info special_domains[] = {
- { &global_sid_World_Domain, "", everyone_users },
- { &global_sid_Creator_Owner_Domain, "", creator_owner_users },
- { &global_sid_NT_Authority, "NT Authority", nt_authority_users },
- { NULL, NULL, NULL }};
-
-/**************************************************************************
- Looks up a known username from one of the known domains.
-***************************************************************************/
-
-BOOL lookup_wellknown_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
- const char **domain, const char **name)
-{
- int i;
- DOM_SID dom_sid;
- uint32 rid;
- const struct rid_name_map *users = NULL;
-
- sid_copy(&dom_sid, sid);
- if (!sid_split_rid(&dom_sid, &rid)) {
- DEBUG(2, ("Could not split rid from SID\n"));
- return False;
- }
-
- for (i=0; special_domains[i].sid != NULL; i++) {
- if (sid_equal(&dom_sid, special_domains[i].sid)) {
- *domain = talloc_strdup(mem_ctx,
- special_domains[i].name);
- users = special_domains[i].known_users;
- break;
- }
- }
-
- if (users == NULL) {
- DEBUG(10, ("SID %s is no special sid\n",
- sid_string_static(sid)));
- return False;
- }
-
- for (i=0; users[i].name != NULL; i++) {
- if (rid == users[i].rid) {
- *name = talloc_strdup(mem_ctx, users[i].name);
- return True;
- }
- }
-
- DEBUG(10, ("RID of special SID %s not found\n",
- sid_string_static(sid)));
-
- return False;
-}
-
-/**************************************************************************
- Try and map a name to one of the well known SIDs.
-***************************************************************************/
-
-BOOL lookup_wellknown_name(TALLOC_CTX *mem_ctx, const char *name,
- DOM_SID *sid, const char **domain)
-{
- int i, j;
-
- DEBUG(10,("map_name_to_wellknown_sid: looking up %s\n", name));
-
- for (i=0; special_domains[i].sid != NULL; i++) {
- const struct rid_name_map *users =
- special_domains[i].known_users;
-
- if (users == NULL)
- continue;
-
- for (j=0; users[j].name != NULL; j++) {
- if ( strequal(users[j].name, name) ) {
- sid_copy(sid, special_domains[i].sid);
- sid_append_rid(sid, users[j].rid);
- *domain = talloc_strdup(
- mem_ctx, special_domains[i].name);
- return True;
- }
- }
- }
-
- return False;
-}
diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c
index 6cd673550ec..15d420538ef 100644
--- a/source/rpc_server/srv_lsa_nt.c
+++ b/source/rpc_server/srv_lsa_nt.c
@@ -96,7 +96,7 @@ static void init_dom_query(DOM_QUERY *d_q, const char *dom_name, DOM_SID *dom_si
init_dom_ref - adds a domain if it's not already in, returns the index.
***************************************************************************/
-static int init_dom_ref(DOM_R_REF *ref, const char *dom_name, DOM_SID *dom_sid)
+static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
{
int num = 0;
@@ -135,76 +135,67 @@ static int init_dom_ref(DOM_R_REF *ref, const char *dom_name, DOM_SID *dom_sid)
init_lsa_rid2s
***************************************************************************/
-static int init_lsa_rid2s(TALLOC_CTX *mem_ctx,
- DOM_R_REF *ref, DOM_RID2 *rid2,
- int num_entries, UNISTR2 *name,
- int flags)
+static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
+ int num_entries, UNISTR2 *name,
+ uint32 *mapped_count, BOOL endian)
{
- int mapped_count, i;
+ int i;
+ int total = 0;
+ *mapped_count = 0;
SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
- mapped_count = 0;
-
become_root(); /* lookup_name can require root privs */
for (i = 0; i < num_entries; i++) {
BOOL status = False;
DOM_SID sid;
- uint32 rid;
- int dom_idx;
- char *full_name;
- const char *domain;
- enum SID_NAME_USE type = SID_NAME_UNKNOWN;
+ uint32 rid = 0xffffffff;
+ int dom_idx = -1;
+ pstring full_name;
+ fstring dom_name, user;
+ enum SID_NAME_USE name_type = SID_NAME_UNKNOWN;
/* Split name into domain and user component */
- if (rpcstr_pull_unistr2_talloc(mem_ctx, &full_name,
- &name[i]) < 0) {
- DEBUG(0, ("pull_ucs2_talloc failed\n"));
- return 0;
- }
+ unistr2_to_ascii(full_name, &name[i], sizeof(full_name));
+ split_domain_name(full_name, dom_name, user);
- DEBUG(5, ("init_lsa_rid2s: looking up name %s\n", full_name));
+ /* Lookup name */
- /* We can ignore the result of lookup_name, it will not touch
- "type" if it's not successful */
+ DEBUG(5, ("init_lsa_rid2s: looking up name %s\n", full_name));
- lookup_name(mem_ctx, full_name, flags, &domain, NULL,
- &sid, &type);
+ status = lookup_name(dom_name, user, &sid, &name_type);
- DEBUG(5, ("init_lsa_rid2s: %s\n", status ? "found" :
- "not found"));
+ if((name_type == SID_NAME_UNKNOWN) && (lp_server_role() == ROLE_DOMAIN_MEMBER) && (strncmp(dom_name, full_name, strlen(dom_name)) != 0)) {
+ DEBUG(5, ("init_lsa_rid2s: domain name not provided and local account not found, using member domain\n"));
+ fstrcpy(dom_name, lp_workgroup());
+ status = lookup_name(dom_name, user, &sid, &name_type);
+ }
- switch (type) {
- case SID_NAME_USER:
- case SID_NAME_DOM_GRP:
- case SID_NAME_DOMAIN:
- case SID_NAME_ALIAS:
- case SID_NAME_WKN_GRP:
- /* Leave these unchanged */
- break;
- default:
- /* Don't hand out anything but the list above */
- type = SID_NAME_UNKNOWN;
- break;
+ if (name_type == SID_NAME_WKN_GRP) {
+ /* BUILTIN aliases are still aliases :-) */
+ name_type = SID_NAME_ALIAS;
}
- rid = 0;
- dom_idx = -1;
+ DEBUG(5, ("init_lsa_rid2s: %s\n", status ? "found" :
+ "not found"));
- if (type != SID_NAME_UNKNOWN) {
+ if (status && name_type != SID_NAME_UNKNOWN) {
sid_split_rid(&sid, &rid);
- dom_idx = init_dom_ref(ref, domain, &sid);
- mapped_count++;
+ dom_idx = init_dom_ref(ref, dom_name, &sid);
+ (*mapped_count)++;
+ } else {
+ dom_idx = -1;
+ rid = 0;
+ name_type = SID_NAME_UNKNOWN;
}
- init_dom_rid2(&rid2[i], rid, type, dom_idx);
+ init_dom_rid2(&rid2[total], rid, name_type, dom_idx);
+ total++;
}
unbecome_root();
-
- return mapped_count;
}
/***************************************************************************
@@ -259,44 +250,42 @@ static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME
DOM_SID find_sid = sid[i].sid;
uint32 rid = 0xffffffff;
int dom_idx = -1;
- const char *name, *domain;
- enum SID_NAME_USE type = SID_NAME_UNKNOWN;
+ fstring name, dom_name;
+ enum SID_NAME_USE sid_name_use = (enum SID_NAME_USE)0;
- DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n",
- sid_string_static(&find_sid)));
+ sid_to_string(name, &find_sid);
+ DEBUG(5, ("init_lsa_trans_names: looking up sid %s\n", name));
/* Lookup sid from winbindd */
- status = lookup_sid(ctx, &find_sid, &domain, &name, &type);
+ status = lookup_sid(&find_sid, dom_name, name, &sid_name_use);
DEBUG(5, ("init_lsa_trans_names: %s\n", status ? "found" :
"not found"));
if (!status) {
- type = SID_NAME_UNKNOWN;
- domain = talloc_strdup(ctx, "");
- name = talloc_strdup(ctx,
- sid_string_static(&find_sid));
+ sid_name_use = SID_NAME_UNKNOWN;
+ memset(dom_name, '\0', sizeof(dom_name));
+ sid_to_string(name, &find_sid);
dom_idx = -1;
- DEBUG(10,("init_lsa_trans_names: added unknown user "
- "'%s' to referenced list.\n", name ));
+ DEBUG(10,("init_lsa_trans_names: added unknown user '%s' to "
+ "referenced list.\n", name ));
} else {
(*mapped_count)++;
/* Store domain sid in ref array */
if (find_sid.num_auths == 5) {
sid_split_rid(&find_sid, &rid);
}
- dom_idx = init_dom_ref(ref, domain, &find_sid);
+ dom_idx = init_dom_ref(ref, dom_name, &find_sid);
- DEBUG(10,("init_lsa_trans_names: added %s '%s\\%s' "
- "(%d) to referenced list.\n",
- sid_type_lookup(type), domain, name, type));
+ DEBUG(10,("init_lsa_trans_names: added %s '%s\\%s' (%d) to referenced list.\n",
+ sid_type_lookup(sid_name_use), dom_name, name, sid_name_use ));
}
init_lsa_trans_name(&trn->name[total], &trn->uni_name[total],
- type, name, dom_idx);
+ sid_name_use, name, dom_idx);
total++;
}
@@ -512,7 +501,7 @@ NTSTATUS _lsa_enum_trust_dom(pipes_struct *p, LSA_Q_ENUM_TRUST_DOM *q_u, LSA_R_E
uint32 num_domains;
NTSTATUS nt_status;
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
/* check if the user have enough rights */
@@ -550,7 +539,7 @@ NTSTATUS _lsa_query_info(pipes_struct *p, LSA_Q_QUERY_INFO *q_u, LSA_R_QUERY_INF
r_u->status = NT_STATUS_OK;
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
return NT_STATUS_INVALID_HANDLE;
switch (q_u->info_class) {
@@ -668,7 +657,7 @@ NTSTATUS _lsa_lookup_sids(pipes_struct *p, LSA_Q_LOOKUP_SIDS *q_u, LSA_R_LOOKUP_
ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
names = TALLOC_ZERO_P(p->mem_ctx, LSA_TRANS_NAME_ENUM);
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) {
r_u->status = NT_STATUS_INVALID_HANDLE;
goto done;
}
@@ -708,22 +697,16 @@ NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP
DOM_R_REF *ref;
DOM_RID2 *rids;
uint32 mapped_count = 0;
- int flags = 0;
if (num_entries > MAX_LOOKUP_SIDS) {
num_entries = MAX_LOOKUP_SIDS;
DEBUG(5,("_lsa_lookup_names: truncating name lookup list to %d\n", num_entries));
}
- /* Probably the lookup_level is some sort of bitmask. */
- if (q_u->lookup_level == 1) {
- flags = LOOKUP_NAME_ALL;
- }
-
ref = TALLOC_ZERO_P(p->mem_ctx, DOM_R_REF);
rids = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_RID2, num_entries);
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle)) {
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle)) {
r_u->status = NT_STATUS_INVALID_HANDLE;
goto done;
}
@@ -737,11 +720,10 @@ NTSTATUS _lsa_lookup_names(pipes_struct *p,LSA_Q_LOOKUP_NAMES *q_u, LSA_R_LOOKUP
if (!ref || !rids)
return NT_STATUS_NO_MEMORY;
- /* set up the LSA Lookup RIDs response */
- mapped_count = init_lsa_rid2s(p->mem_ctx, ref, rids, num_entries,
- names, flags);
done:
+ /* set up the LSA Lookup RIDs response */
+ init_lsa_rid2s(ref, rids, num_entries, names, &mapped_count, p->endian);
if (NT_STATUS_IS_OK(r_u->status)) {
if (mapped_count == 0)
r_u->status = NT_STATUS_NONE_MAPPED;
@@ -835,7 +817,7 @@ NTSTATUS _lsa_enum_privs(pipes_struct *p, LSA_Q_ENUM_PRIVS *q_u, LSA_R_ENUM_PRIV
DEBUG(10,("_lsa_enum_privs: enum_context:%d total entries:%d\n",
enum_context, num_privs));
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
return NT_STATUS_INVALID_HANDLE;
/* check if the user have enough rights
@@ -882,7 +864,7 @@ NTSTATUS _lsa_priv_get_dispname(pipes_struct *p, LSA_Q_PRIV_GET_DISPNAME *q_u, L
fstring name_asc;
const char *description;
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
return NT_STATUS_INVALID_HANDLE;
/* check if the user have enough rights */
@@ -930,7 +912,7 @@ NTSTATUS _lsa_enum_accounts(pipes_struct *p, LSA_Q_ENUM_ACCOUNTS *q_u, LSA_R_ENU
LSA_SID_ENUM *sids=&r_u->sids;
NTSTATUS ret;
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
return NT_STATUS_INVALID_HANDLE;
if (!(handle->access & POLICY_VIEW_LOCAL_INFORMATION))
@@ -1006,7 +988,7 @@ NTSTATUS _lsa_create_account(pipes_struct *p, LSA_Q_CREATEACCOUNT *q_u, LSA_R_CR
struct lsa_info *info;
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
return NT_STATUS_INVALID_HANDLE;
/* check if the user have enough rights */
@@ -1054,7 +1036,7 @@ NTSTATUS _lsa_open_account(pipes_struct *p, LSA_Q_OPENACCOUNT *q_u, LSA_R_OPENAC
struct lsa_info *info;
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
return NT_STATUS_INVALID_HANDLE;
/* check if the user have enough rights */
@@ -1097,7 +1079,7 @@ NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVS
PRIVILEGE_SET privileges;
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
if ( !get_privileges_for_sids( &mask, &info->sid, 1 ) )
@@ -1127,13 +1109,15 @@ NTSTATUS _lsa_enum_privsaccount(pipes_struct *p, prs_struct *ps, LSA_Q_ENUMPRIVS
NTSTATUS _lsa_getsystemaccount(pipes_struct *p, LSA_Q_GETSYSTEMACCOUNT *q_u, LSA_R_GETSYSTEMACCOUNT *r_u)
{
struct lsa_info *info=NULL;
+ fstring name, dom_name;
+ enum SID_NAME_USE type;
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
- if (!lookup_sid(p->mem_ctx, &info->sid, NULL, NULL, NULL))
+ if (!lookup_sid(&info->sid, dom_name, name, &type))
return NT_STATUS_ACCESS_DENIED;
/*
@@ -1161,7 +1145,7 @@ NTSTATUS _lsa_setsystemaccount(pipes_struct *p, LSA_Q_SETSYSTEMACCOUNT *q_u, LSA
r_u->status = NT_STATUS_OK;
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
/* check to see if the pipe_user is a Domain Admin since
@@ -1191,7 +1175,7 @@ NTSTATUS _lsa_addprivs(pipes_struct *p, LSA_Q_ADDPRIVS *q_u, LSA_R_ADDPRIVS *r_u
struct current_user user;
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
/* check to see if the pipe_user is root or a Domain Admin since
@@ -1232,7 +1216,7 @@ NTSTATUS _lsa_removeprivs(pipes_struct *p, LSA_Q_REMOVEPRIVS *q_u, LSA_R_REMOVEP
struct current_user user;
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
/* check to see if the pipe_user is root or a Domain Admin since
@@ -1275,7 +1259,7 @@ NTSTATUS _lsa_query_secobj(pipes_struct *p, LSA_Q_QUERY_SEC_OBJ *q_u, LSA_R_QUER
r_u->status = NT_STATUS_OK;
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
return NT_STATUS_INVALID_HANDLE;
/* check if the user have enough rights */
@@ -1332,7 +1316,7 @@ NTSTATUS _lsa_query_info2(pipes_struct *p, LSA_Q_QUERY_INFO2 *q_u, LSA_R_QUERY_I
ZERO_STRUCT(guid);
r_u->status = NT_STATUS_OK;
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&handle))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&handle))
return NT_STATUS_INVALID_HANDLE;
switch (q_u->info_class) {
@@ -1394,7 +1378,7 @@ NTSTATUS _lsa_add_acct_rights(pipes_struct *p, LSA_Q_ADD_ACCT_RIGHTS *q_u, LSA_R
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
/* check to see if the pipe_user is a Domain Admin since
@@ -1452,7 +1436,7 @@ NTSTATUS _lsa_remove_acct_rights(pipes_struct *p, LSA_Q_REMOVE_ACCT_RIGHTS *q_u,
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
/* check to see if the pipe_user is a Domain Admin since
@@ -1514,7 +1498,7 @@ NTSTATUS _lsa_enum_acct_rights(pipes_struct *p, LSA_Q_ENUM_ACCT_RIGHTS *q_u, LSA
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
/* according to an NT4 PDC, you can add privileges to SIDs even without
@@ -1555,7 +1539,7 @@ NTSTATUS _lsa_lookup_priv_value(pipes_struct *p, LSA_Q_LOOKUP_PRIV_VALUE *q_u, L
/* find the connection policy handle. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
unistr2_to_ascii(name, &q_u->privname.unistring, sizeof(name));
diff --git a/source/rpc_server/srv_samr.c b/source/rpc_server/srv_samr.c
index e8fd86ba467..cbfad5688e1 100644
--- a/source/rpc_server/srv_samr.c
+++ b/source/rpc_server/srv_samr.c
@@ -679,37 +679,6 @@ static BOOL api_samr_connect4(pipes_struct *p)
return True;
}
-/*******************************************************************
- api_samr_connect5
- ********************************************************************/
-
-static BOOL api_samr_connect5(pipes_struct *p)
-{
- SAMR_Q_CONNECT5 q_u;
- SAMR_R_CONNECT5 r_u;
- prs_struct *data = &p->in_data.data;
- prs_struct *rdata = &p->out_data.rdata;
-
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- /* grab the samr open policy */
- if(!samr_io_q_connect5("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_connect5: unable to unmarshall SAMR_Q_CONNECT5.\n"));
- return False;
- }
-
- r_u.status = _samr_connect5(p, &q_u, &r_u);
-
- /* store the response in the SMB stream */
- if(!samr_io_r_connect5("", &r_u, rdata, 0)) {
- DEBUG(0,("api_samr_connect5: unable to marshall SAMR_R_CONNECT5.\n"));
- return False;
- }
-
- return True;
-}
-
/**********************************************************************
api_samr_lookup_domain
**********************************************************************/
@@ -1523,8 +1492,7 @@ static struct api_struct api_samr_cmds [] =
{"SAMR_GET_USRDOM_PWINFO" , SAMR_GET_USRDOM_PWINFO, api_samr_get_usrdom_pwinfo},
{"SAMR_QUERY_DOMAIN_INFO2", SAMR_QUERY_DOMAIN_INFO2, api_samr_query_domain_info2},
{"SAMR_SET_DOMAIN_INFO" , SAMR_SET_DOMAIN_INFO , api_samr_set_dom_info },
- {"SAMR_CONNECT4" , SAMR_CONNECT4 , api_samr_connect4 },
- {"SAMR_CONNECT5" , SAMR_CONNECT5 , api_samr_connect5 }
+ {"SAMR_CONNECT4" , SAMR_CONNECT4 , api_samr_connect4 }
};
void samr_get_pipe_fns( struct api_struct **fns, int *n_fns )
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index 8f8c035c9cd..d2ec30142b3 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -573,7 +573,7 @@ NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN
/* find the connection policy handle. */
- if ( !find_policy_by_hnd(p, &q_u->pol, (void**)(void *)&info) )
+ if ( !find_policy_by_hnd(p, &q_u->pol, (void**)&info) )
return NT_STATUS_INVALID_HANDLE;
status = access_check_samr_function( info->acc_granted,
@@ -627,7 +627,7 @@ NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u,
r_u->status = NT_STATUS_OK;
/* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
if (!sid_check_is_in_our_domain(&info->sid))
@@ -665,7 +665,7 @@ static BOOL get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
struct samr_info *info = NULL;
/* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, pol, (void **)&info))
return False;
if (!info)
@@ -803,7 +803,7 @@ NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
r_u->status = NT_STATUS_OK;
/* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
@@ -936,7 +936,7 @@ NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAM
r_u->status = NT_STATUS_OK;
/* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
r_u->status = access_check_samr_function(info->acc_granted,
@@ -995,7 +995,7 @@ NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, S
uint32 num_aliases = 0;
/* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
r_u->status = access_check_samr_function(info->acc_granted,
@@ -1061,7 +1061,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
r_u->status = NT_STATUS_UNSUCCESSFUL;
/* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
/*
@@ -1366,7 +1366,9 @@ NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAM
NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
{
uint32 rid[MAX_SAM_ENTRIES];
+ uint32 local_rid;
enum SID_NAME_USE type[MAX_SAM_ENTRIES];
+ enum SID_NAME_USE local_type;
int i;
int num_rids = q_u->num_names2;
DOM_SID pol_sid;
@@ -1398,30 +1400,42 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO
for (i = 0; i < num_rids; i++) {
fstring name;
+ DOM_SID sid;
int ret;
r_u->status = NT_STATUS_NONE_MAPPED;
- type[i] = SID_NAME_UNKNOWN;
rid [i] = 0xffffffff;
+ type[i] = SID_NAME_UNKNOWN;
ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
- if (ret <= 0) {
- continue;
- }
-
- if (sid_check_is_builtin(&pol_sid)) {
- if (lookup_builtin_name(name, &rid[i])) {
- type[i] = SID_NAME_ALIAS;
+ /*
+ * we are only looking for a name
+ * the SID we get back can be outside
+ * the scope of the pol_sid
+ *
+ * in clear: it prevents to reply to domain\group: yes
+ * when only builtin\group exists.
+ *
+ * a cleaner code is to add the sid of the domain we're looking in
+ * to the local_lookup_name function.
+ */
+
+ if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
+ sid_split_rid(&sid, &local_rid);
+
+ if (sid_equal(&sid, &pol_sid)) {
+ rid[i]=local_rid;
+
+ /* Windows does not return WKN_GRP here, even
+ * on lookups in builtin */
+ type[i] = (local_type == SID_NAME_WKN_GRP) ?
+ SID_NAME_ALIAS : local_type;
+
+ r_u->status = NT_STATUS_OK;
}
- } else {
- lookup_global_sam_name(name, &rid[i], &type[i]);
- }
-
- if (type[i] != SID_NAME_UNKNOWN) {
- r_u->status = NT_STATUS_OK;
- }
+ }
}
init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
@@ -1672,41 +1686,6 @@ static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx, SAM_USER_INFO_7 *id7, DOM_S
return NT_STATUS_OK;
}
-
-/*************************************************************************
- get_user_info_9. Only gives out primary group SID.
- *************************************************************************/
-static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx, SAM_USER_INFO_9 * id9, DOM_SID *user_sid)
-{
- SAM_ACCOUNT *smbpass=NULL;
- BOOL ret;
- NTSTATUS nt_status;
-
- nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- }
-
- become_root();
- ret = pdb_getsampwsid(smbpass, user_sid);
- unbecome_root();
-
- if (ret==False) {
- DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
- return NT_STATUS_NO_SUCH_USER;
- }
-
- DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
-
- ZERO_STRUCTP(id9);
- init_sam_user_info9(id9, pdb_get_group_rid(smbpass) );
-
- pdb_free_sam(&smbpass);
-
- return NT_STATUS_OK;
-}
-
/*************************************************************************
get_user_info_16. Safe. Only gives out acb bits.
*************************************************************************/
@@ -1878,7 +1857,7 @@ NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_
r_u->status=NT_STATUS_OK;
/* search for the handle */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
domain_sid = info->sid;
@@ -1899,8 +1878,6 @@ NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_
/* ok! user info levels (lots: see MSDEV help), off we go... */
ctr->switch_value = q_u->switch_value;
- DEBUG(5,("_samr_query_userinfo: user info level: %d\n", q_u->switch_value));
-
switch (q_u->switch_value) {
case 7:
ctr->info.id7 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_7);
@@ -1910,14 +1887,6 @@ NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_
if (!NT_STATUS_IS_OK(r_u->status = get_user_info_7(p->mem_ctx, ctr->info.id7, &info->sid)))
return r_u->status;
break;
- case 9:
- ctr->info.id9 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_9);
- if (ctr->info.id9 == NULL)
- return NT_STATUS_NO_MEMORY;
-
- if (!NT_STATUS_IS_OK(r_u->status = get_user_info_9(p->mem_ctx, ctr->info.id9, &info->sid)))
- return r_u->status;
- break;
case 16:
ctr->info.id16 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_16);
if (ctr->info.id16 == NULL)
@@ -2125,7 +2094,7 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)(void *)&info)) {
+ if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info)) {
return NT_STATUS_INVALID_HANDLE;
}
@@ -2196,11 +2165,7 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
/* AS ROOT !!! */
- {
- uint32 ul;
- pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
- u_logout = (time_t)ul;
- }
+ pdb_get_account_policy(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
/* !AS ROOT */
@@ -2278,44 +2243,6 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA
return r_u->status;
}
-/* W2k3 seems to use the same check for all 3 objects that can be created via
- * SAMR, if you try to create for example "Dialup" as an alias it says
- * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
- * database. */
-
-static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
-{
- enum SID_NAME_USE type;
- BOOL result;
-
- DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
-
- become_root();
- /* Lookup in our local databases (only LOOKUP_NAME_ISOLATED set)
- * whether the name already exists */
- result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_ISOLATED,
- NULL, NULL, NULL, &type);
- unbecome_root();
-
- if (!result) {
- DEBUG(10, ("%s does not exist, can create it\n", new_name));
- return NT_STATUS_OK;
- }
-
- DEBUG(5, ("trying to create %s, exists as %s\n",
- new_name, sid_type_lookup(type)));
-
- if (type == SID_NAME_DOM_GRP) {
- return NT_STATUS_GROUP_EXISTS;
- }
- if (type == SID_NAME_ALIAS) {
- return NT_STATUS_ALIAS_EXISTS;
- }
-
- /* Yes, the default is NT_STATUS_USER_EXISTS */
- return NT_STATUS_USER_EXISTS;
-}
-
/*******************************************************************
_samr_create_user
Create an account, can be either a normal user or a machine.
@@ -2363,11 +2290,19 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA
rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
strlower_m(account);
- nt_status = can_create(p->mem_ctx, account);
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
+ pdb_init_sam(&sam_pass);
+
+ become_root();
+ ret = pdb_getsampwnam(sam_pass, account);
+ unbecome_root();
+ if (ret == True) {
+ /* this account exists: say so */
+ pdb_free_sam(&sam_pass);
+ return NT_STATUS_USER_EXISTS;
}
+ pdb_free_sam(&sam_pass);
+
/*********************************************************************
* HEADS UP! If we have to create a new user account, we have to get
* a new RID from somewhere. This used to be done by the passdb
@@ -2640,60 +2575,6 @@ NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *
return r_u->status;
}
-/*******************************************************************
- samr_connect5
- ********************************************************************/
-
-NTSTATUS _samr_connect5(pipes_struct *p, SAMR_Q_CONNECT5 *q_u, SAMR_R_CONNECT5 *r_u)
-{
- struct samr_info *info = NULL;
- SEC_DESC *psd = NULL;
- uint32 acc_granted;
- uint32 des_access = q_u->access_mask;
- NTSTATUS nt_status;
- POLICY_HND pol;
- size_t sd_size;
-
-
- DEBUG(5,("_samr_connect5: %d\n", __LINE__));
-
- ZERO_STRUCTP(r_u);
-
- /* Access check */
-
- if (!pipe_access_check(p)) {
- DEBUG(3, ("access denied to samr_connect5\n"));
- r_u->status = NT_STATUS_ACCESS_DENIED;
- return r_u->status;
- }
-
- make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
- se_map_generic(&des_access, &sam_generic_mapping);
-
- nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
- NULL, 0, des_access, &acc_granted, "_samr_connect5");
-
- if ( !NT_STATUS_IS_OK(nt_status) )
- return nt_status;
-
- /* associate the user's SID and access granted with the new handle. */
- if ((info = get_samr_info_by_sid(NULL)) == NULL)
- return NT_STATUS_NO_MEMORY;
-
- info->acc_granted = acc_granted;
- info->status = q_u->access_mask;
-
- /* get a (unique) handle. open a policy on it. */
- if (!create_policy_hnd(p, &pol, free_samr_info, (void *)info))
- return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-
- DEBUG(5,("_samr_connect: %d\n", __LINE__));
-
- init_samr_r_connect5(r_u, &pol, NT_STATUS_OK);
-
- return r_u->status;
-}
-
/**********************************************************************
api_samr_lookup_domain
**********************************************************************/
@@ -2706,7 +2587,7 @@ NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_
r_u->status = NT_STATUS_OK;
- if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
return NT_STATUS_INVALID_HANDLE;
/* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
@@ -2722,12 +2603,8 @@ NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_
ZERO_STRUCT(sid);
- if (strequal(domain_name, builtin_domain_name())) {
- sid_copy(&sid, &global_sid_Builtin);
- } else {
- if (!secrets_fetch_domain_sid(domain_name, &sid)) {
- r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
- }
+ if (!secrets_fetch_domain_sid(domain_name, &sid)) {
+ r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
}
DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
@@ -2786,7 +2663,7 @@ NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_EN
r_u->status = NT_STATUS_OK;
- if (!find_policy_by_hnd(p, &q_u->pol, (void**)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
return NT_STATUS_INVALID_HANDLE;
if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
@@ -2841,7 +2718,7 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A
/* append the alias' RID to it */
if (!sid_append_rid(&sid, alias_rid))
- return NT_STATUS_NO_SUCH_ALIAS;
+ return NT_STATUS_NO_SUCH_USER;
/*check if access can be granted as requested by client. */
@@ -2858,21 +2735,12 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A
if ( !NT_STATUS_IS_OK(status) )
return status;
- {
- /* Check we actually have the requested alias */
- enum SID_NAME_USE type;
- BOOL result;
-
- become_root();
- result = lookup_sid(NULL, &sid, NULL, NULL, &type);
- unbecome_root();
-
- if (!result || (type != SID_NAME_ALIAS)) {
- return NT_STATUS_NO_SUCH_ALIAS;
- }
- }
+ /*
+ * we should check if the rid really exist !!!
+ * JFM.
+ */
- /* associate the alias SID with the new handle. */
+ /* associate the user's SID with the new handle. */
if ((info = get_samr_info_by_sid(&sid)) == NULL)
return NT_STATUS_NO_MEMORY;
@@ -2888,11 +2756,12 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A
/*******************************************************************
set_user_info_7
********************************************************************/
-static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
- const SAM_USER_INFO_7 *id7, SAM_ACCOUNT *pwd)
+static NTSTATUS set_user_info_7(const SAM_USER_INFO_7 *id7, SAM_ACCOUNT *pwd)
{
fstring new_name;
+ SAM_ACCOUNT *check_acct = NULL;
NTSTATUS rc;
+ BOOL check_rc;
if (id7 == NULL) {
DEBUG(5, ("set_user_info_7: NULL id7\n"));
@@ -2915,9 +2784,13 @@ static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
simply that the rename fails with a slightly different status
code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
- rc = can_create(mem_ctx, new_name);
- if (!NT_STATUS_IS_OK(rc)) {
- return rc;
+ pdb_init_sam(&check_acct);
+ check_rc = pdb_getsampwnam(check_acct, new_name);
+ pdb_free_sam(&check_acct);
+
+ if (check_rc == True) {
+ /* this account exists: say so */
+ return NT_STATUS_USER_EXISTS;
}
rc = pdb_rename_sam_account(pwd, new_name);
@@ -3434,8 +3307,7 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
switch (switch_value) {
case 7:
- r_u->status = set_user_info_7(p->mem_ctx,
- ctr->info.id7, pwd);
+ r_u->status = set_user_info_7(ctr->info.id7, pwd);
break;
case 16:
if (!set_user_info_16(ctr->info.id16, pwd))
@@ -3492,7 +3364,7 @@ NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u,
DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
@@ -4269,10 +4141,9 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S
unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
- r_u->status = can_create(p->mem_ctx, name);
- if (!NT_STATUS_IS_OK(r_u->status)) {
- return r_u->status;
- }
+ /* check if group already exist */
+ if ((grp=getgrnam(name)) != NULL)
+ return NT_STATUS_GROUP_EXISTS;
se_priv_copy( &se_rights, &se_add_users );
can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
@@ -4365,11 +4236,6 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S
se_priv_copy( &se_rights, &se_add_users );
can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
- result = can_create(p->mem_ctx, name);
- if (!NT_STATUS_IS_OK(result)) {
- return result;
- }
-
/******** BEGIN SeAddUsers BLOCK *********/
if ( can_add_accounts )
@@ -4786,7 +4652,7 @@ NTSTATUS _samr_query_domain_info2(pipes_struct *p,
DEBUG(5,("_samr_query_domain_info2: %d\n", __LINE__));
/* find the policy handle. open a policy on it. */
- if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)(void *)&info))
+ if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
return NT_STATUS_INVALID_HANDLE;
switch (q_u->switch_value) {
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
index 5a179dbf478..fed73db043f 100644
--- a/source/smbd/chgpasswd.c
+++ b/source/smbd/chgpasswd.c
@@ -153,13 +153,9 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass,
DEBUG(3, ("More weirdness, could not open %s\n", slavedev));
return (False);
}
-#if defined(I_PUSH) && defined(I_FIND)
- if (ioctl(slave, I_FIND, "ptem") == 0) {
- ioctl(slave, I_PUSH, "ptem");
- }
- if (ioctl(slave, I_FIND, "ldterm") == 0) {
- ioctl(slave, I_PUSH, "ldterm");
- }
+#ifdef I_PUSH
+ ioctl(slave, I_PUSH, "ptem");
+ ioctl(slave, I_PUSH, "ldterm");
#elif defined(TIOCSCTTY)
if (ioctl(slave, TIOCSCTTY, 0) < 0)
{
diff --git a/source/smbd/close.c b/source/smbd/close.c
index c0d87b1b212..24ca7a40927 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -130,13 +130,9 @@ static void notify_deferred_opens(struct share_mode_lock *lck)
*/
schedule_deferred_open_smb_message(e->op_mid);
} else {
- char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
-
- share_mode_entry_to_message(msg, e);
-
become_root();
message_send_pid(e->pid, MSG_SMB_OPEN_RETRY,
- msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);
+ e, sizeof(*e), True);
unbecome_root();
}
}
@@ -198,7 +194,7 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
* This prevents race conditions with the file being created. JRA.
*/
- lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
+ lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, fsp->fsp_name);
if (lck == NULL) {
DEBUG(0, ("close_file: Could not get share mode lock for file %s\n", fsp->fsp_name));
@@ -233,43 +229,20 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
*/
if (normal_close && delete_file) {
- SMB_STRUCT_STAT sbuf;
-
DEBUG(5,("close_file: file %s. Delete on close was set - deleting file.\n",
fsp->fsp_name));
-
- /* We can only delete the file if the name we have
- is still valid and hasn't been renamed. */
-
- if(SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) != 0) {
- DEBUG(5,("close_file: file %s. Delete on close was set "
- "and stat failed with error %s\n",
- fsp->fsp_name, strerror(errno) ));
- } else {
- if(sbuf.st_dev != fsp->dev || sbuf.st_ino != fsp->inode) {
- DEBUG(5,("close_file: file %s. Delete on close was set and "
- "dev and/or inode does not match\n",
- fsp->fsp_name ));
- DEBUG(5,("close_file: file %s. stored dev = %x, inode = %.0f "
- "stat dev = %x, inode = %.0f\n",
- fsp->fsp_name,
- (unsigned int)fsp->dev, (double)fsp->inode,
- (unsigned int)sbuf.st_dev, (double)sbuf.st_ino ));
-
- } else if(SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) {
- /*
- * This call can potentially fail as another smbd may have
- * had the file open with delete on close set and deleted
- * it when its last reference to this file went away. Hence
- * we log this but not at debug level zero.
- */
-
- DEBUG(5,("close_file: file %s. Delete on close was set "
- "and unlink failed with error %s\n",
- fsp->fsp_name, strerror(errno) ));
- }
- process_pending_change_notify_queue((time_t)0);
+ if(SMB_VFS_UNLINK(conn,fsp->fsp_name) != 0) {
+ /*
+ * This call can potentially fail as another smbd may have
+ * had the file open with delete on close set and deleted
+ * it when its last reference to this file went away. Hence
+ * we log this but not at debug level zero.
+ */
+
+ DEBUG(5,("close_file: file %s. Delete on close was set and unlink failed \
+with error %s\n", fsp->fsp_name, strerror(errno) ));
}
+ process_pending_change_notify_queue((time_t)0);
}
talloc_free(lck);
@@ -334,7 +307,7 @@ static int close_directory(files_struct *fsp, BOOL normal_close)
* reference to a directory also.
*/
- lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
+ lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, fsp->fsp_name);
if (lck == NULL) {
DEBUG(0, ("close_directory: Could not get share mode lock for %s\n", fsp->fsp_name));
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index 4778702e7ac..1e2a2488515 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -1837,6 +1837,9 @@ static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *para
gid_t *gids;
size_t num_groups;
size_t i;
+ fstring grp_domain;
+ fstring grp_name;
+ enum SID_NAME_USE grp_type;
struct passwd *passwd;
NTSTATUS result;
@@ -1893,12 +1896,9 @@ static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *para
goto out;
for (i=0; i<num_groups; i++) {
-
- const char *grp_name;
- if ( lookup_sid(sampw->mem_ctx, &sids[i], NULL, &grp_name,
- NULL) ) {
- pstrcpy(p, grp_name);
+ if ( lookup_sid(&sids[i], grp_domain, grp_name, &grp_type) ) {
+ pstrcpy(p, grp_name);
p += 21;
count++;
}
diff --git a/source/smbd/mangle_hash.c b/source/smbd/mangle_hash.c
index 2092f430c07..30befd2c849 100644
--- a/source/smbd/mangle_hash.c
+++ b/source/smbd/mangle_hash.c
@@ -372,8 +372,8 @@ static BOOL is_mangled(const char *s, int snum)
magic = strchr_m( s, magic_char );
while( magic && magic[1] && magic[2] ) { /* 3 chars, 1st is magic. */
if( ('.' == magic[3] || '/' == magic[3] || !(magic[3])) /* Ends with '.' or nul or '/' ? */
- && isbasechar( toupper_ascii(magic[1]) ) /* is 2nd char basechar? */
- && isbasechar( toupper_ascii(magic[2]) ) ) /* is 3rd char basechar? */
+ && isbasechar( toupper(magic[1]) ) /* is 2nd char basechar? */
+ && isbasechar( toupper(magic[2]) ) ) /* is 3rd char basechar? */
return( True ); /* If all above, then true, */
magic = strchr_m( magic+1, magic_char ); /* else seek next magic. */
}
@@ -426,7 +426,7 @@ static void cache_mangled_name( const char mangled_name[13], char *raw_name )
s1 = strrchr( mangled_name_key, '.' );
if( s1 && (s2 = strrchr( raw_name, '.' )) ) {
size_t i = 1;
- while( s1[i] && (tolower_ascii( s1[i] ) == s2[i]) )
+ while( s1[i] && (tolower( s1[i] ) == s2[i]) )
i++;
if( !s1[i] && !s2[i] ) {
/* Truncate at the '.' */
diff --git a/source/smbd/mangle_hash2.c b/source/smbd/mangle_hash2.c
index 0a161c9e769..335ba8e2ef9 100644
--- a/source/smbd/mangle_hash2.c
+++ b/source/smbd/mangle_hash2.c
@@ -560,7 +560,7 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case,
if (! FLAG_CHECK(lead_chars[i], FLAG_ASCII)) {
lead_chars[i] = '_';
}
- lead_chars[i] = toupper_ascii(lead_chars[i]);
+ lead_chars[i] = toupper(lead_chars[i]);
}
for (;i<mangle_prefix;i++) {
lead_chars[i] = '_';
@@ -580,7 +580,7 @@ static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case,
for (i=1; extension_length < 3 && dot_p[i]; i++) {
char c = dot_p[i];
if (FLAG_CHECK(c, FLAG_ASCII)) {
- extension[extension_length++] = toupper_ascii(c);
+ extension[extension_length++] = toupper(c);
}
}
}
@@ -679,10 +679,10 @@ static void init_tables(void)
char_flags[c2] |= FLAG_POSSIBLE2;
char_flags[c3] |= FLAG_POSSIBLE3;
char_flags[c4] |= FLAG_POSSIBLE4;
- char_flags[tolower_ascii(c1)] |= FLAG_POSSIBLE1;
- char_flags[tolower_ascii(c2)] |= FLAG_POSSIBLE2;
- char_flags[tolower_ascii(c3)] |= FLAG_POSSIBLE3;
- char_flags[tolower_ascii(c4)] |= FLAG_POSSIBLE4;
+ char_flags[tolower(c1)] |= FLAG_POSSIBLE1;
+ char_flags[tolower(c2)] |= FLAG_POSSIBLE2;
+ char_flags[tolower(c3)] |= FLAG_POSSIBLE3;
+ char_flags[tolower(c4)] |= FLAG_POSSIBLE4;
char_flags[(unsigned char)'.'] |= FLAG_POSSIBLE4;
}
diff --git a/source/smbd/message.c b/source/smbd/message.c
index fd28df0d801..e975da3e153 100644
--- a/source/smbd/message.c
+++ b/source/smbd/message.c
@@ -65,7 +65,7 @@ static void msg_deliver(void)
* Incoming message is in DOS codepage format. Convert to UNIX.
*/
- if ((len = (int)convert_string_allocate(NULL,CH_DOS, CH_UNIX, msgbuf, msgpos, (void **)(void *)&msg, True)) < 0 || !msg) {
+ if ((len = (int)convert_string_allocate(NULL,CH_DOS, CH_UNIX, msgbuf, msgpos, (void **) &msg, True)) < 0 || !msg) {
DEBUG(3,("Conversion failed, delivering message in DOS codepage format\n"));
for (i = 0; i < msgpos;) {
if (msgbuf[i] == '\r' && i < (msgpos-1) && msgbuf[i+1] == '\n') {
diff --git a/source/smbd/msdfs.c b/source/smbd/msdfs.c
index 1279fe185d2..a4f371b18ff 100644
--- a/source/smbd/msdfs.c
+++ b/source/smbd/msdfs.c
@@ -146,7 +146,7 @@ static BOOL create_conn_struct(connection_struct *conn, int snum, char *path)
return False;
}
- set_conn_connectpath(conn, connpath);
+ string_set(&conn->connectpath, connpath);
if (!smbd_vfs_init(conn)) {
DEBUG(0,("create_conn_struct: smbd_vfs_init failed.\n"));
diff --git a/source/smbd/notify.c b/source/smbd/notify.c
index df3d45d20b5..bc76cfb322f 100644
--- a/source/smbd/notify.c
+++ b/source/smbd/notify.c
@@ -212,16 +212,10 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn,
BOOL init_change_notify(void)
{
- cnotify = NULL;
-
#if HAVE_KERNEL_CHANGE_NOTIFY
- if (cnotify == NULL && lp_kernel_change_notify())
+ if (lp_kernel_change_notify())
cnotify = kernel_notify_init();
#endif
-#if HAVE_FAM_CHANGE_NOTIFY
- if (cnotify == NULL && lp_fam_change_notify())
- cnotify = fam_notify_init();
-#endif
if (!cnotify) cnotify = hash_notify_init();
if (!cnotify) {
diff --git a/source/smbd/notify_fam.c b/source/smbd/notify_fam.c
deleted file mode 100644
index 413340266ec..00000000000
--- a/source/smbd/notify_fam.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * FAM file notification support.
- *
- * Copyright (c) James Peach 2005
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "includes.h"
-
-#ifdef HAVE_FAM_CHANGE_NOTIFY
-
-#include <fam.h>
-
-/* NOTE: There are multiple versions of FAM floating around the net, each with
- * slight differences from the original SGI FAM implementation. In this file,
- * we rely only on the SGI features and do not assume any extensions. For
- * example, we do not look at FAMErrno, because it is not set by the original
- * implementation.
- *
- * Random FAM links:
- * http://oss.sgi.com/projects/fam/
- * http://savannah.nongnu.org/projects/fam/
- * http://sourceforge.net/projects/bsdfam/
- */
-
-struct fam_req_info
-{
- FAMRequest req;
- int generation;
- enum FAMCodes code;
- enum
- {
- /* We are waiting for an event. */
- FAM_REQ_MONITORING,
- /* An event has been receive, but we haven't been able to send it back
- * to the client yet. It is stashed in the code member.
- */
- FAM_REQ_FIRED
- } state;
-};
-
-/* Don't initialise this until the first register request. We want a single
- * FAM connection for each worker smbd. If we allow the master (parent) smbd to
- * open a FAM connection, multiple processes talking on the same socket will
- * undoubtedly create havoc.
- */
-static FAMConnection global_fc;
-static int global_fc_generation;
-
-#define FAM_TRACE 8
-#define FAM_TRACE_LOW 10
-
-#define FAM_NOTIFY_CHECK_TIMEOUT 1 /* secs */
-#define FAM_EVENT_DRAIN ((uint32_t)(-1))
-
-/* Turn a FAM event code into a string. Don't rely on specific code values,
- * because that might not work across all flavours of FAM.
- */
-static const char *
-fam_event_str(enum FAMCodes code)
-{
- static struct { enum FAMCodes code; const char * name; } evstr[] =
- {
- { FAMChanged, "FAMChanged"},
- { FAMDeleted, "FAMDeleted"},
- { FAMStartExecuting, "FAMStartExecuting"},
- { FAMStopExecuting, "FAMStopExecuting"},
- { FAMCreated, "FAMCreated"},
- { FAMMoved, "FAMMoved"},
- { FAMAcknowledge, "FAMAcknowledge"},
- { FAMExists, "FAMExists"},
- { FAMEndExist, "FAMEndExist"}
- };
-
- int i;
-
- for (i = 0; i < ARRAY_SIZE(evstr); ++i) {
- if (code == evstr[i].code)
- return(evstr[i].name);
- }
-
- return("<unknown>");
-}
-
-static BOOL
-fam_check_reconnect(void)
-{
- if (FAMCONNECTION_GETFD(&global_fc) < 0) {
- fstring name;
-
- global_fc_generation++;
- snprintf(name, sizeof(name), "smbd (%lu)", (unsigned long)sys_getpid());
-
- if (FAMOpen2(&global_fc, name) < 0) {
- DEBUG(0, ("failed to connect to FAM service\n"));
- return(False);
- }
- }
-
- return(True);
-}
-
-static BOOL
-fam_monitor_path(connection_struct * conn,
- struct fam_req_info * info,
- const char * path,
- uint32 flags)
-{
- SMB_STRUCT_STAT st;
- pstring fullpath;
-
- DEBUG(FAM_TRACE, ("requesting FAM notifications for '%s'\n", path));
-
- /* FAM needs an absolute pathname. */
-
- /* It would be better to use reduce_name() here, but reduce_name does not
- * actually return the reduced result. How utterly un-useful.
- */
- pstrcpy(fullpath, path);
- if (!canonicalize_path(conn, fullpath)) {
- DEBUG(0, ("failed to canonicalize path '%s'\n", path));
- return(False);
- }
-
- if (*fullpath != '/') {
- DEBUG(0, ("canonicalized path '%s' into `%s`\n", path, fullpath));
- DEBUGADD(0, ("but expected an absolute path\n"));
- return(False);
- }
-
- if (SMB_VFS_STAT(conn, path, &st) < 0) {
- DEBUG(0, ("stat of '%s' failed: %s\n", path, strerror(errno)));
- return(False);
- }
- /* Start monitoring this file or directory. We hand the state structure to
- * both the caller and the FAM library so we can match up the caller's
- * status requests with FAM notifications.
- */
- if (S_ISDIR(st.st_mode)) {
- FAMMonitorDirectory(&global_fc, fullpath, &(info->req), info);
- } else {
- FAMMonitorFile(&global_fc, fullpath, &(info->req), info);
- }
-
- /* Grr. On IRIX, neither of the monitor functions return a status. */
-
- /* We will stay in initialising state until we see the FAMendExist message
- * for this file.
- */
- info->state = FAM_REQ_MONITORING;
- info->generation = global_fc_generation;
- return(True);
-}
-
-static BOOL
-fam_handle_event(enum FAMCodes code, uint32 flags)
-{
-#define F_CHANGE_MASK (FILE_NOTIFY_CHANGE_FILE | \
- FILE_NOTIFY_CHANGE_ATTRIBUTES | \
- FILE_NOTIFY_CHANGE_SIZE | \
- FILE_NOTIFY_CHANGE_LAST_WRITE | \
- FILE_NOTIFY_CHANGE_LAST_ACCESS | \
- FILE_NOTIFY_CHANGE_CREATION | \
- FILE_NOTIFY_CHANGE_EA | \
- FILE_NOTIFY_CHANGE_SECURITY)
-
-#define F_DELETE_MASK (FILE_NOTIFY_CHANGE_FILE_NAME | \
- FILE_NOTIFY_CHANGE_DIR_NAME)
-
-#define F_CREATE_MASK (FILE_NOTIFY_CHANGE_FILE_NAME | \
- FILE_NOTIFY_CHANGE_DIR_NAME)
-
- switch (code) {
- case FAMChanged:
- if (flags & F_CHANGE_MASK)
- return(True);
- break;
- case FAMDeleted:
- if (flags & F_DELETE_MASK)
- return(True);
- break;
- case FAMCreated:
- if (flags & F_CREATE_MASK)
- return(True);
- break;
- default:
- /* Ignore anything else. */
- break;
- }
-
- return(False);
-
-#undef F_CHANGE_MASK
-#undef F_DELETE_MASK
-#undef F_CREATE_MASK
-}
-
-static BOOL
-fam_pump_events(struct fam_req_info * info, uint32_t flags)
-{
- FAMEvent ev;
-
- for (;;) {
-
- /* If we are draining the event queue we must keep going until we find
- * the correct FAMAcknowledge event or the connection drops. Otherwise
- * we should stop when there are no more events pending.
- */
- if (flags != FAM_EVENT_DRAIN && !FAMPending(&global_fc)) {
- break;
- }
-
- if (FAMNextEvent(&global_fc, &ev) < 0) {
- DEBUG(0, ("failed to fetch pending FAM event\n"));
- DEBUGADD(0, ("resetting FAM connection\n"));
- FAMClose(&global_fc);
- FAMCONNECTION_GETFD(&global_fc) = -1;
- return(False);
- }
-
- DEBUG(FAM_TRACE_LOW, ("FAM event %s on '%s' for request %d\n",
- fam_event_str(ev.code), ev.filename, ev.fr.reqnum));
-
- switch (ev.code) {
- case FAMAcknowledge:
- /* FAM generates an ACK event when we cancel a monitor. We need
- * this to know when it is safe to free out request state
- * structure.
- */
- if (info->generation == global_fc_generation &&
- info->req.reqnum == ev.fr.reqnum &&
- flags == FAM_EVENT_DRAIN) {
- return(True);
- }
-
- case FAMEndExist:
- case FAMExists:
- /* Ignore these. FAM sends these enumeration events when we
- * start monitoring. If we are monitoring a directory, we will
- * get a FAMExists event for each directory entry.
- */
-
- /* TODO: we might be able to use these to implement recursive
- * monitoring of entire subtrees.
- */
- case FAMMoved:
- /* These events never happen. A move or rename shows up as a
- * create/delete pair.
- */
- case FAMStartExecuting:
- case FAMStopExecuting:
- /* We might get these, but we just don't care. */
- break;
-
- case FAMChanged:
- case FAMDeleted:
- case FAMCreated:
- if (info->generation != global_fc_generation) {
- /* Ignore this; the req number can't be matched. */
- break;
- }
-
- if (info->req.reqnum == ev.fr.reqnum) {
- /* This is the event the caller was interested in. */
- DEBUG(FAM_TRACE, ("handling FAM %s event on '%s'\n",
- fam_event_str(ev.code), ev.filename));
- /* Ignore events if we are draining this request. */
- if (flags != FAM_EVENT_DRAIN) {
- return(fam_handle_event(ev.code, flags));
- }
- break;
- } else {
- /* Caller doesn't want this event. Stash the result so we
- * can come back to it. Unfortunately, FAM doesn't
- * guarantee to give us back evinfo.
- */
- struct fam_req_info * evinfo =
- (struct fam_req_info *)ev.userdata;
-
- if (evinfo) {
- DEBUG(FAM_TRACE, ("storing FAM %s event for winter\n",
- fam_event_str(ev.code)));
- evinfo->state = FAM_REQ_FIRED;
- evinfo->code = ev.code;
- } else {
- DEBUG(2, ("received FAM %s notification for %s, "
- "but userdata was unexpectedly NULL\n",
- fam_event_str(ev.code), ev.filename));
- }
- break;
- }
-
- default:
- DEBUG(0, ("ignoring unknown FAM event code %d for `%s`\n",
- ev.code, ev.filename));
- }
- }
-
- /* No more notifications pending. */
- return(False);
-}
-
-static BOOL
-fam_test_connection(void)
-{
- FAMConnection fc;
-
- /* On IRIX FAMOpen2 leaks 960 bytes in 48 blocks. It's a deliberate leak
- * in the library and there's nothing we can do about it here.
- */
- if (FAMOpen2(&fc, "smbd probe") < 0)
- return(False);
-
- FAMClose(&fc);
- return(True);
-}
-
-/* ------------------------------------------------------------------------- */
-
-static void *
-fam_register_notify(connection_struct * conn,
- char * path,
- uint32 flags)
-{
- struct fam_req_info * info;
-
- if (!fam_check_reconnect()) {
- return(False);
- }
-
- if ((info = SMB_MALLOC_P(struct fam_req_info)) == NULL) {
- DEBUG(0, ("malloc of %d bytes failed\n", sizeof(struct fam_req_info)));
- return(NULL);
- }
-
- if (fam_monitor_path(conn, info, path, flags)) {
- return(info);
- } else {
- SAFE_FREE(info);
- return(NULL);
- }
-}
-
-static BOOL
-fam_check_notify(connection_struct * conn,
- uint16_t vuid,
- char * path,
- uint32_t flags,
- void * data,
- time_t when)
-{
- struct fam_req_info * info;
-
- info = (struct fam_req_info *)data;
- SMB_ASSERT(info != NULL);
-
- DEBUG(10, ("checking FAM events for `%s`\n", path));
-
- if (info->state == FAM_REQ_FIRED) {
- DEBUG(FAM_TRACE, ("handling previously fired FAM %s event\n",
- fam_event_str(info->code)));
- info->state = FAM_REQ_MONITORING;
- return(fam_handle_event(info->code, flags));
- }
-
- if (!fam_check_reconnect()) {
- return(False);
- }
-
- if (info->generation != global_fc_generation) {
- DEBUG(FAM_TRACE, ("reapplying stale FAM monitor to %s\n", path));
- fam_monitor_path(conn, info, path, flags);
- return(False);
- }
-
- return(fam_pump_events(info, flags));
-}
-
-static void
-fam_remove_notify(void * data)
-{
- struct fam_req_info * info;
-
- if ((info = (struct fam_req_info *)data) == NULL)
- return;
-
- /* No need to reconnect. If the FAM connection is gone, there's no need to
- * cancel and we can safely let FAMCancelMonitor fail. If it we
- * reconnected, then the generation check will stop us cancelling the wrong
- * request.
- */
-
- if (info->generation == global_fc_generation) {
- DEBUG(FAM_TRACE, ("removing FAM notification for request %d\n",
- info->req.reqnum));
- FAMCancelMonitor(&global_fc, &(info->req));
-
- /* Soak up all events until the FAMAcknowledge. We can't free
- * our request state until we are sure there are no more events in
- * flight.
- */
- fam_pump_events(info, FAM_EVENT_DRAIN);
- }
-
- SAFE_FREE(info);
-}
-
-struct cnotify_fns * fam_notify_init(void)
-{
- static struct cnotify_fns global_fam_notify =
- {
- fam_register_notify,
- fam_check_notify,
- fam_remove_notify,
- FAM_NOTIFY_CHECK_TIMEOUT
- };
-
- /* TODO: rather than relying on FAM_NOTIFY_CHECK_TIMEOUT, we should have an
- * API to push the FAM fd into the global server fd set.
- */
-
- FAMCONNECTION_GETFD(&global_fc) = -1;
-
- if (!fam_test_connection()) {
- DEBUG(0, ("FAM file change notifications not available\n"));
- return(NULL);
- }
-
- DEBUG(FAM_TRACE, ("enabling FAM change notifications\n"));
- return &global_fam_notify;
-}
-
-#endif /* HAVE_FAM_CHANGE_NOTIFY */
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 0ccac592d61..27e83b76983 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -683,17 +683,12 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp)
if (delay_it) {
BOOL ret;
- char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
-
DEBUG(10, ("Sending break request to PID %s\n",
procid_str_static(&exclusive->pid)));
exclusive->op_mid = get_current_mid();
-
- share_mode_entry_to_message(msg, exclusive);
-
become_root();
ret = message_send_pid(exclusive->pid, MSG_SMB_BREAK_REQUEST,
- msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);
+ exclusive, sizeof(*exclusive), True);
unbecome_root();
if (!ret) {
DEBUG(3, ("Could not send oplock break message\n"));
@@ -1132,7 +1127,8 @@ files_struct *open_file_ntcreate(connection_struct *conn,
spurious oplock break. */
/* Now remove the deferred open entry under lock. */
- lck = get_share_mode_lock(NULL, state->dev, state->inode, NULL, NULL);
+ lck = get_share_mode_lock(NULL, state->dev, state->inode,
+ fname);
if (lck == NULL) {
DEBUG(0, ("could not get share mode lock\n"));
} else {
@@ -1342,9 +1338,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
dev = psbuf->st_dev;
inode = psbuf->st_ino;
- lck = get_share_mode_lock(NULL, dev, inode,
- conn->connectpath,
- fname);
+ lck = get_share_mode_lock(NULL, dev, inode, fname);
if (lck == NULL) {
DEBUG(0, ("Could not get share mode lock\n"));
@@ -1543,9 +1537,7 @@ files_struct *open_file_ntcreate(connection_struct *conn,
dev = fsp->dev;
inode = fsp->inode;
- lck = get_share_mode_lock(NULL, dev, inode,
- conn->connectpath,
- fname);
+ lck = get_share_mode_lock(NULL, dev, inode, fname);
if (lck == NULL) {
DEBUG(0, ("open_file_ntcreate: Could not get share mode lock for %s\n", fname));
@@ -1952,9 +1944,7 @@ files_struct *open_directory(connection_struct *conn,
fsp->is_stat = False;
string_set(&fsp->fsp_name,fname);
- lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode,
- conn->connectpath,
- fname);
+ lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, fname);
if (lck == NULL) {
DEBUG(0, ("open_directory: Could not get share mode lock for %s\n", fname));
@@ -2051,55 +2041,3 @@ files_struct *open_file_stat(connection_struct *conn, char *fname,
return fsp;
}
-
-/****************************************************************************
- Receive notification that one of our open files has been renamed by another
- smbd process.
-****************************************************************************/
-
-void msg_file_was_renamed(int msg_type, struct process_id src, void *buf, size_t len)
-{
- files_struct *fsp;
- char *frm = (char *)buf;
- SMB_DEV_T dev;
- SMB_INO_T inode;
- const char *sharepath;
- const char *newname;
- size_t sp_len;
-
- if (buf == NULL || len < MSG_FILE_RENAMED_MIN_SIZE + 2) {
- DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n", (int)len));
- return;
- }
-
- /* Unpack the message. */
- dev = DEV_T_VAL(frm,0);
- inode = INO_T_VAL(frm,8);
- sharepath = &frm[16];
- newname = sharepath + strlen(sharepath) + 1;
- sp_len = strlen(sharepath);
-
- DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
- "dev %x, inode %.0f\n",
- sharepath, newname, (unsigned int)dev, (double)inode ));
-
- for(fsp = file_find_di_first(dev, inode); fsp; fsp = file_find_di_next(fsp)) {
- if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
- DEBUG(10,("msg_file_was_renamed: renaming file fnum %d from %s -> %s\n",
- fsp->fnum, fsp->fsp_name, newname ));
- string_set(&fsp->fsp_name, newname);
- } else {
- /* TODO. JRA. */
- /* Now we have the complete path we can work out if this is
- actually within this share and adjust newname accordingly. */
- DEBUG(10,("msg_file_was_renamed: share mismatch (sharepath %s "
- "not sharepath %s) "
- "fnum %d from %s -> %s\n",
- fsp->conn->connectpath,
- sharepath,
- fsp->fnum,
- fsp->fsp_name,
- newname ));
- }
- }
-}
diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c
index 6739d29470b..52a61c0061b 100644
--- a/source/smbd/oplock.c
+++ b/source/smbd/oplock.c
@@ -192,7 +192,7 @@ BOOL remove_oplock(files_struct *fsp)
struct share_mode_lock *lck;
/* Remove the oplock flag from the sharemode. */
- lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
+ lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
if (lck == NULL) {
DEBUG(0,("remove_oplock: failed to lock share entry for "
"file %s\n", fsp->fsp_name ));
@@ -220,7 +220,7 @@ BOOL downgrade_oplock(files_struct *fsp)
BOOL ret;
struct share_mode_lock *lck;
- lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
+ lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
if (lck == NULL) {
DEBUG(0,("downgrade_oplock: failed to lock share entry for "
"file %s\n", fsp->fsp_name ));
@@ -233,7 +233,7 @@ BOOL downgrade_oplock(files_struct *fsp)
fsp->fsp_name, fsp->fnum, (unsigned int)dev,
(double)inode));
}
-
+
downgrade_file_oplock(fsp);
talloc_free(lck);
return ret;
@@ -670,7 +670,7 @@ void release_level_2_oplocks_on_change(files_struct *fsp)
if (!LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
return;
- lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
+ lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL);
if (lck == NULL) {
DEBUG(0,("release_level_2_oplocks_on_change: failed to lock "
"share mode entry for file %s.\n", fsp->fsp_name ));
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index e485dc1eb12..7187f61b023 100644
--- a/source/smbd/posix_acls.c
+++ b/source/smbd/posix_acls.c
@@ -4224,7 +4224,7 @@ SEC_DESC* get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname)
connection_struct conn;
files_struct finfo;
struct fd_handle fh;
- pstring path;
+ fstring path;
pstring filename;
ZERO_STRUCT( conn );
@@ -4235,8 +4235,8 @@ SEC_DESC* get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname)
return NULL;
}
- pstrcpy( path, "/" );
- set_conn_connectpath(&conn, path);
+ fstrcpy( path, "/" );
+ string_set(&conn.connectpath, path);
if (!smbd_vfs_init(&conn)) {
DEBUG(0,("novfs_get_nt_acl: Unable to create a fake connection struct!\n"));
diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c
index d6ba7bc2d55..de31376d6c6 100644
--- a/source/smbd/quotas.c
+++ b/source/smbd/quotas.c
@@ -206,8 +206,6 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
uid_t euser_id;
gid_t egrp_id;
- ZERO_STRUCT(D);
-
euser_id = geteuid();
egrp_id = getegid();
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index 69c71c74b59..81240fcb92d 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -1888,19 +1888,7 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL b
return NT_STATUS_OBJECT_NAME_INVALID;
#endif /* JRATEST */
- /* Fix for bug #3035 from SATOH Fumiyasu <fumiyas@miraclelinux.com>
-
- On a Windows share, a file with read-only dosmode can be opened with
- DELETE_ACCESS. But on a Samba share (delete readonly = no), it
- fails with NT_STATUS_CANNOT_DELETE error.
-
- This semantic causes a problem that a user can not
- rename a file with read-only dosmode on a Samba share
- from a Windows command prompt (i.e. cmd.exe, but can rename
- from Windows Explorer).
- */
-
- if (!check_is_at_open && !lp_delete_readonly(SNUM(conn))) {
+ if (!lp_delete_readonly(SNUM(conn))) {
if (fattr & aRONLY) {
return NT_STATUS_CANNOT_DELETE;
}
@@ -4094,24 +4082,15 @@ static BOOL resolve_wildcards(const char *name1, char *name2)
}
/****************************************************************************
- Ensure open files have their names updated. Updated to notify other smbd's
- asynchronously.
+ Ensure open files have their names updates.
****************************************************************************/
-static void rename_open_files(connection_struct *conn, struct share_mode_lock *lck,
- SMB_DEV_T dev, SMB_INO_T inode, const char *newname)
+static void rename_open_files(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode, char *newname)
{
files_struct *fsp;
BOOL did_rename = False;
for(fsp = file_find_di_first(dev, inode); fsp; fsp = file_find_di_next(fsp)) {
- /* fsp_name is a relative path under the fsp. To change this for other
- sharepaths we need to manipulate relative paths. */
- /* TODO - create the absolute path and manipulate the newname
- relative to the sharepath. */
- if (fsp->conn != conn) {
- continue;
- }
DEBUG(10,("rename_open_files: renaming file fnum %d (dev = %x, inode = %.0f) from %s -> %s\n",
fsp->fnum, (unsigned int)fsp->dev, (double)fsp->inode,
fsp->fsp_name, newname ));
@@ -4119,13 +4098,9 @@ static void rename_open_files(connection_struct *conn, struct share_mode_lock *l
did_rename = True;
}
- if (!did_rename) {
+ if (!did_rename)
DEBUG(10,("rename_open_files: no open files on dev %x, inode %.0f for %s\n",
(unsigned int)dev, (double)inode, newname ));
- }
-
- /* Send messages to all smbd's (not ourself) that the name has changed. */
- rename_share_filename(lck, conn->connectpath, newname);
}
/****************************************************************************
@@ -4169,7 +4144,6 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *
NTSTATUS error = NT_STATUS_OK;
BOOL dest_exists;
BOOL rcdest = True;
- struct share_mode_lock *lck = NULL;
ZERO_STRUCT(sbuf);
rcdest = unix_convert(newname,conn,newname_last_component,&bad_path,&sbuf);
@@ -4257,23 +4231,17 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *
return NT_STATUS_ACCESS_DENIED;
}
- lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
-
if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
fsp->fsp_name,newname));
- rename_open_files(conn, lck, fsp->dev, fsp->inode, newname);
- talloc_free(lck);
+ rename_open_files(conn, fsp->dev, fsp->inode, newname);
return NT_STATUS_OK;
}
- talloc_free(lck);
-
- if (errno == ENOTDIR || errno == EISDIR) {
+ if (errno == ENOTDIR || errno == EISDIR)
error = NT_STATUS_OBJECT_NAME_COLLISION;
- } else {
+ else
error = map_nt_error_from_unix(errno);
- }
DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
nt_errstr(error), fsp->fsp_name,newname));
@@ -4300,7 +4268,6 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, ui
BOOL rc = True;
BOOL rcdest = True;
SMB_STRUCT_STAT sbuf1, sbuf2;
- struct share_mode_lock *lck = NULL;
*directory = *mask = 0;
@@ -4471,7 +4438,7 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
*/
if (strcsequal(directory, newname)) {
- rename_open_files(conn, NULL, sbuf1.st_dev, sbuf1.st_ino, newname);
+ rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
DEBUG(3,("rename_internals: identical names in rename %s - returning success\n", directory));
return NT_STATUS_OK;
}
@@ -4486,17 +4453,13 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
return NT_STATUS_SHARING_VIOLATION;
}
- lck = get_share_mode_lock(NULL, sbuf1.st_dev, sbuf1.st_ino, NULL, NULL);
-
if(SMB_VFS_RENAME(conn,directory, newname) == 0) {
DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
directory,newname));
- rename_open_files(conn, lck, sbuf1.st_dev, sbuf1.st_ino, newname);
- talloc_free(lck);
+ rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
return NT_STATUS_OK;
}
- talloc_free(lck);
if (errno == ENOTDIR || errno == EISDIR)
error = NT_STATUS_OBJECT_NAME_COLLISION;
else
@@ -4574,7 +4537,7 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
}
if (strcsequal(fname,destname)) {
- rename_open_files(conn, NULL, sbuf1.st_dev, sbuf1.st_ino, newname);
+ rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
DEBUG(3,("rename_internals: identical names in wildcard rename %s - success\n", fname));
count++;
error = NT_STATUS_OK;
@@ -4592,14 +4555,11 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
return NT_STATUS_SHARING_VIOLATION;
}
- lck = get_share_mode_lock(NULL, sbuf1.st_dev, sbuf1.st_ino, NULL, NULL);
-
if (!SMB_VFS_RENAME(conn,fname,destname)) {
- rename_open_files(conn, lck, sbuf1.st_dev, sbuf1.st_ino, newname);
+ rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
count++;
error = NT_STATUS_OK;
}
- talloc_free(lck);
DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
}
CloseDir(dir_hnd);
@@ -4994,7 +4954,7 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
} else {
ok = vfs_directory_exist(conn,newdir,NULL);
if (ok)
- set_conn_connectpath(conn,newdir);
+ string_set(&conn->connectpath,newdir);
}
if (!ok) {
@@ -5477,7 +5437,7 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
outsize = set_message(outbuf,0,0,True);
if(!fsp || (fsp->conn != conn)) {
- END_PROFILE(SMBsetattrE);
+ END_PROFILE(SMBgetattrE);
return ERROR_DOS(ERRDOS,ERRbadfid);
}
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 620bf3ebbdd..1bf9dbc374a 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -330,7 +330,6 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
message_register(MSG_SMB_SAM_SYNC, msg_sam_sync);
message_register(MSG_SMB_SAM_REPL, msg_sam_repl);
message_register(MSG_SHUTDOWN, msg_exit_server);
- message_register(MSG_SMB_FILE_RENAME, msg_file_was_renamed);
/* now accept incoming connections - forking a new process
for each incoming connection */
@@ -718,8 +717,6 @@ void build_options(BOOL screen);
{ NULL }
};
- load_case_tables();
-
#ifdef HAVE_SET_AUTH_PARAMETERS
set_auth_parameters(argc,argv);
#endif
@@ -744,6 +741,8 @@ void build_options(BOOL screen);
sec_init();
+ load_case_tables();
+
set_remote_machine_name("smbd", False);
if (interactive) {
@@ -826,10 +825,8 @@ void build_options(BOOL screen);
init_structs();
- if (!init_guest_info()) {
- DEBUG(0,("ERROR: failed to setup guest info.\n"));
+ if (!init_guest_info())
return -1;
- }
#ifdef WITH_PROFILE
if (!profile_setup(False)) {
diff --git a/source/smbd/service.c b/source/smbd/service.c
index 7640559d538..52f9229ee1c 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -24,108 +24,6 @@ extern struct timeval smb_last_time;
extern userdom_struct current_user_info;
/****************************************************************************
- Ensure when setting connectpath it is a canonicalized (no ./ // or ../)
- absolute path stating in / and not ending in /.
- Observent people will notice a similarity between this and check_path_syntax :-).
-****************************************************************************/
-
-void set_conn_connectpath(connection_struct *conn, const pstring connectpath)
-{
- pstring destname;
- char *d = destname;
- const char *s = connectpath;
- BOOL start_of_name_component = True;
-
- *d++ = '/'; /* Always start with root. */
-
- while (*s) {
- if (*s == '/') {
- /* Eat multiple '/' */
- while (*s == '/') {
- s++;
- }
- if ((d > destname + 1) && (*s != '\0')) {
- *d++ = '/';
- }
- start_of_name_component = True;
- continue;
- }
-
- if (start_of_name_component) {
- if ((s[0] == '.') && (s[1] == '.') && (s[2] == '/' || s[2] == '\0')) {
- /* Uh oh - "/../" or "/..\0" ! */
-
- /* Go past the ../ or .. */
- if (s[2] == '/') {
- s += 3;
- } else {
- s += 2; /* Go past the .. */
- }
-
- /* If we just added a '/' - delete it */
- if ((d > destname) && (*(d-1) == '/')) {
- *(d-1) = '\0';
- d--;
- }
-
- /* Are we at the start ? Can't go back further if so. */
- if (d <= destname) {
- *d++ = '/'; /* Can't delete root */
- continue;
- }
- /* Go back one level... */
- /* Decrement d first as d points to the *next* char to write into. */
- for (d--; d > destname; d--) {
- if (*d == '/') {
- break;
- }
- }
- /* We're still at the start of a name component, just the previous one. */
- continue;
- } else if ((s[0] == '.') && ((s[1] == '\0') || s[1] == '/')) {
- /* Component of pathname can't be "." only - skip the '.' . */
- if (s[1] == '/') {
- s += 2;
- } else {
- s++;
- }
- continue;
- }
- }
-
- if (!(*s & 0x80)) {
- *d++ = *s++;
- } else {
- switch(next_mb_char_size(s)) {
- case 4:
- *d++ = *s++;
- case 3:
- *d++ = *s++;
- case 2:
- *d++ = *s++;
- case 1:
- *d++ = *s++;
- break;
- default:
- break;
- }
- }
- start_of_name_component = False;
- }
- *d = '\0';
-
- /* And must not end in '/' */
- if (d > destname + 1 && (*(d-1) == '/')) {
- *(d-1) = '\0';
- }
-
- DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n",
- lp_servicename(SNUM(conn)), destname ));
-
- string_set(&conn->connectpath, destname);
-}
-
-/****************************************************************************
Load parameters specific to a connection/service.
****************************************************************************/
@@ -366,8 +264,7 @@ static NTSTATUS share_sanity_checks(int snum, fstring dev)
static connection_struct *make_connection_snum(int snum, user_struct *vuser,
DATA_BLOB password,
- const char *pdev,
- NTSTATUS *status)
+ const char *pdev, NTSTATUS *status)
{
struct passwd *pass = NULL;
BOOL guest = False;
@@ -397,8 +294,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
guest = True;
pass = getpwnam_alloc(guestname);
if (!pass) {
- DEBUG(0,("make_connection_snum: Invalid guest "
- "account %s??\n",guestname));
+ DEBUG(0,("make_connection_snum: Invalid guest account %s??\n",guestname));
conn_free(conn);
*status = NT_STATUS_NO_SUCH_USER;
return NULL;
@@ -413,20 +309,14 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
} else if (vuser) {
if (vuser->guest) {
if (!lp_guest_ok(snum)) {
- DEBUG(2, ("guest user (from session setup) "
- "not permitted to access this share "
- "(%s)\n", lp_servicename(snum)));
+ DEBUG(2, ("guest user (from session setup) not permitted to access this share (%s)\n", lp_servicename(snum)));
conn_free(conn);
*status = NT_STATUS_ACCESS_DENIED;
return NULL;
}
} else {
- if (!user_ok(vuser->user.unix_name, snum,
- vuser->groups, vuser->n_groups)) {
- DEBUG(2, ("user '%s' (from session setup) not "
- "permitted to access this share "
- "(%s)\n", vuser->user.unix_name,
- lp_servicename(snum)));
+ if (!user_ok(vuser->user.unix_name, snum, vuser->groups, vuser->n_groups)) {
+ DEBUG(2, ("user '%s' (from session setup) not permitted to access this share (%s)\n", vuser->user.unix_name, lp_servicename(snum)));
conn_free(conn);
*status = NT_STATUS_ACCESS_DENIED;
return NULL;
@@ -473,14 +363,12 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
conn->service = snum;
conn->used = True;
conn->printer = (strncmp(dev,"LPT",3) == 0);
- conn->ipc = ( (strncmp(dev,"IPC",3) == 0) ||
- ( lp_enable_asu_support() && strequal(dev,"ADMIN$")) );
+ conn->ipc = ( (strncmp(dev,"IPC",3) == 0) || ( lp_enable_asu_support() && strequal(dev,"ADMIN$")) );
conn->dirptr = NULL;
/* Case options for the share. */
if (lp_casesensitive(snum) == Auto) {
- /* We will be setting this per packet. Set to be case
- * insensitive for now. */
+ /* We will be setting this per packet. Set to be case insensitive for now. */
conn->case_sensitive = False;
} else {
conn->case_sensitive = (BOOL)lp_casesensitive(snum);
@@ -555,30 +443,30 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
pstring_sub(gname,"%S",lp_servicename(snum));
gid = nametogid(gname);
- if (gid == (gid_t)-1) {
- DEBUG(1,("Couldn't find group %s\n",gname));
- conn_free(conn);
- *status = NT_STATUS_NO_SUCH_GROUP;
- return NULL;
- }
+ if (gid != (gid_t)-1) {
- /*
- * If the user has been forced and the forced group starts
- * with a '+', then we only set the group to be the forced
- * group if the forced user is a member of that group.
- * Otherwise, the meaning of the '+' would be ignored.
- */
- if (conn->force_user && user_must_be_member) {
- if (user_in_group_list( user, gname, NULL, 0)) {
+ /*
+ * If the user has been forced and the forced group starts
+ * with a '+', then we only set the group to be the forced
+ * group if the forced user is a member of that group.
+ * Otherwise, the meaning of the '+' would be ignored.
+ */
+ if (conn->force_user && user_must_be_member) {
+ if (user_in_group_list( user, gname, NULL, 0)) {
+ conn->gid = gid;
+ DEBUG(3,("Forced group %s for member %s\n",gname,user));
+ }
+ } else {
conn->gid = gid;
- DEBUG(3,("Forced group %s for member %s\n",
- gname,user));
+ DEBUG(3,("Forced group %s\n",gname));
}
+ conn->force_group = True;
} else {
- conn->gid = gid;
- DEBUG(3,("Forced group %s\n",gname));
+ DEBUG(1,("Couldn't find group %s\n",gname));
+ conn_free(conn);
+ *status = NT_STATUS_NO_SUCH_GROUP;
+ return NULL;
}
- conn->force_group = True;
}
#endif /* HAVE_GETGRNAM */
@@ -586,13 +474,11 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
pstring s;
pstrcpy(s,lp_pathname(snum));
standard_sub_conn(conn,s,sizeof(s));
- set_conn_connectpath(conn,s);
- DEBUG(3,("Connect path is '%s' for service [%s]\n",s,
- lp_servicename(snum)));
+ string_set(&conn->connectpath,s);
+ DEBUG(3,("Connect path is '%s' for service [%s]\n",s, lp_servicename(snum)));
}
if (conn->force_user || conn->force_group) {
- int ngroups = 0;
/* groups stuff added by ih */
conn->ngroups = 0;
@@ -601,13 +487,11 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
/* Find all the groups this uid is in and
store them. Used by change_to_user() */
initialise_groups(conn->user, conn->uid, conn->gid);
- get_current_groups(conn->gid, &ngroups, &conn->groups);
- conn->ngroups = ngroups;
+ get_current_groups(conn->gid, &conn->ngroups,&conn->groups);
- conn->nt_user_token =
- create_nt_token(conn->uid, conn->gid,
- conn->ngroups, conn->groups,
- guest);
+ conn->nt_user_token = create_nt_token(conn->uid, conn->gid,
+ conn->ngroups, conn->groups,
+ guest);
}
/*
@@ -618,16 +502,12 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
*/
{
- BOOL can_write = share_access_check(conn, snum, vuser,
- FILE_WRITE_DATA);
+ BOOL can_write = share_access_check(conn, snum, vuser, FILE_WRITE_DATA);
if (!can_write) {
- if (!share_access_check(conn, snum, vuser,
- FILE_READ_DATA)) {
+ if (!share_access_check(conn, snum, vuser, FILE_READ_DATA)) {
/* No access, read or write. */
- DEBUG(0,("make_connection: connection to %s "
- "denied due to security "
- "descriptor.\n",
+ DEBUG(0,( "make_connection: connection to %s denied due to security descriptor.\n",
lp_servicename(snum)));
conn_free(conn);
*status = NT_STATUS_ACCESS_DENIED;
@@ -640,25 +520,24 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
/* Initialise VFS function pointers */
if (!smbd_vfs_init(conn)) {
- DEBUG(0, ("vfs_init failed for service %s\n",
- lp_servicename(snum)));
+ DEBUG(0, ("vfs_init failed for service %s\n", lp_servicename(snum)));
conn_free(conn);
*status = NT_STATUS_BAD_NETWORK_NAME;
return NULL;
}
/*
- * If widelinks are disallowed we need to canonicalise the connect
- * path here to ensure we don't have any symlinks in the
- * connectpath. We will be checking all paths on this connection are
- * below this directory. We must do this after the VFS init as we
- * depend on the realpath() pointer in the vfs table. JRA.
+ * If widelinks are disallowed we need to canonicalise the
+ * connect path here to ensure we don't have any symlinks in
+ * the connectpath. We will be checking all paths on this
+ * connection are below this directory. We must do this after
+ * the VFS init as we depend on the realpath() pointer in the vfs table. JRA.
*/
if (!lp_widelinks(snum)) {
pstring s;
pstrcpy(s,conn->connectpath);
canonicalize_path(conn, s);
- set_conn_connectpath(conn,s);
+ string_set(&conn->connectpath,s);
}
/* ROOT Activities: */
@@ -673,8 +552,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
return NULL;
}
- /* Preexecs are done here as they might make the dir we are to ChDir
- * to below */
+ /* Preexecs are done here as they might make the dir we are to ChDir to below */
/* execute any "root preexec = " line */
if (*lp_rootpreexec(snum)) {
pstring cmd;
@@ -683,8 +561,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
DEBUG(5,("cmd=%s\n",cmd));
ret = smbrun(cmd,NULL);
if (ret != 0 && lp_rootpreexec_close(snum)) {
- DEBUG(1,("root preexec gave %d - failing "
- "connection\n", ret));
+ DEBUG(1,("root preexec gave %d - failing connection\n", ret));
yield_connection(conn, lp_servicename(snum));
conn_free(conn);
*status = NT_STATUS_ACCESS_DENIED;
@@ -702,12 +579,9 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
return NULL;
}
- /* Remember that a different vuid can connect later without these
- * checks... */
+ /* Remember that a different vuid can connect later without these checks... */
- /* Preexecs are done here as they might make the dir we are to ChDir
- * to below */
-
+ /* Preexecs are done here as they might make the dir we are to ChDir to below */
/* execute any "preexec = " line */
if (*lp_preexec(snum)) {
pstring cmd;
@@ -715,8 +589,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
standard_sub_conn(conn,cmd,sizeof(cmd));
ret = smbrun(cmd,NULL);
if (ret != 0 && lp_preexec_close(snum)) {
- DEBUG(1,("preexec gave %d - failing connection\n",
- ret));
+ DEBUG(1,("preexec gave %d - failing connection\n", ret));
change_to_root_user();
yield_connection(conn, lp_servicename(snum));
conn_free(conn);
@@ -738,9 +611,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(snum));
}
- /* Invoke VFS make connection hook - do this before the VFS_STAT call
- to allow any filesystems needing user credentials to initialize
- themselves. */
+ /* Invoke VFS make connection hook - do this before the VFS_STAT call to allow
+ any filesystems needing user credentials to initialize themselves. */
if (SMB_VFS_CONNECT(conn, lp_servicename(snum), user) < 0) {
DEBUG(0,("make_connection: VFS make connection failed!\n"));
@@ -756,17 +628,12 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
check during individual operations. To match this behaviour
I have disabled this chdir check (tridge) */
/* the alternative is just to check the directory exists */
- if ((ret = SMB_VFS_STAT(conn, conn->connectpath, &st)) != 0 ||
- !S_ISDIR(st.st_mode)) {
+ if ((ret = SMB_VFS_STAT(conn, conn->connectpath, &st)) != 0 || !S_ISDIR(st.st_mode)) {
if (ret == 0 && !S_ISDIR(st.st_mode)) {
- DEBUG(0,("'%s' is not a directory, when connecting to "
- "[%s]\n", conn->connectpath,
- lp_servicename(snum)));
+ DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", conn->connectpath, lp_servicename(snum)));
} else {
- DEBUG(0,("'%s' does not exist or permission denied "
- "when connecting to [%s] Error was %s\n",
- conn->connectpath, lp_servicename(snum),
- strerror(errno) ));
+ DEBUG(0,("'%s' does not exist or permission denied when connecting to [%s] "
+ "Error was %s\n", conn->connectpath, lp_servicename(snum), strerror(errno) ));
}
change_to_root_user();
/* Call VFS disconnect hook */
@@ -785,7 +652,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
pstring s;
pstrcpy(s,conn->connectpath);
vfs_GetWd(conn,s);
- set_conn_connectpath(conn,s);
+ string_set(&conn->connectpath,s);
vfs_ChDir(conn,conn->connectpath);
}
#endif
@@ -797,8 +664,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
*/
if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
- dbgtext( "%s (%s) ", get_remote_machine_name(),
- conn->client_address );
+ dbgtext( "%s (%s) ", get_remote_machine_name(), conn->client_address );
dbgtext( "%s", srv_is_signing_active() ? "signed " : "");
dbgtext( "connect to service %s ", lp_servicename(snum) );
dbgtext( "initially as user %s ", user );
@@ -816,10 +682,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
vfs_chdir()
**************************************************************************************/
-connection_struct *make_connection_with_chdir(const char *service_in,
- DATA_BLOB password,
- const char *dev, uint16 vuid,
- NTSTATUS *status)
+connection_struct *make_connection_with_chdir(const char *service_in, DATA_BLOB password,
+ const char *dev, uint16 vuid, NTSTATUS *status)
{
connection_struct *conn = NULL;
@@ -831,8 +695,7 @@ connection_struct *make_connection_with_chdir(const char *service_in,
*/
if ( conn && vfs_ChDir(conn,conn->connectpath) != 0 ) {
- DEBUG(0,("move_driver_to_download_area: Can't change "
- "directory to %s for [print$] (%s)\n",
+ DEBUG(0,("move_driver_to_download_area: Can't change directory to %s for [print$] (%s)\n",
conn->connectpath,strerror(errno)));
yield_connection(conn, lp_servicename(SNUM(conn)));
conn_free(conn);
@@ -850,8 +713,7 @@ connection_struct *make_connection_with_chdir(const char *service_in,
****************************************************************************/
connection_struct *make_connection(const char *service_in, DATA_BLOB password,
- const char *pdev, uint16 vuid,
- NTSTATUS *status)
+ const char *pdev, uint16 vuid, NTSTATUS *status)
{
uid_t euid;
user_struct *vuser = NULL;
@@ -861,52 +723,43 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password,
fstrcpy(dev, pdev);
- /* This must ONLY BE CALLED AS ROOT. As it exits this function as
- * root. */
+ /* This must ONLY BE CALLED AS ROOT. As it exits this function as root. */
if (!non_root_mode() && (euid = geteuid()) != 0) {
- DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot "
- "(%u)\n", (unsigned int)euid ));
+ DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot (%u)\n", (unsigned int)euid ));
smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
}
if(lp_security() != SEC_SHARE) {
vuser = get_valid_user_struct(vuid);
if (!vuser) {
- DEBUG(1,("make_connection: refusing to connect with "
- "no session setup\n"));
+ DEBUG(1,("make_connection: refusing to connect with no session setup\n"));
*status = NT_STATUS_ACCESS_DENIED;
return NULL;
}
}
- /* Logic to try and connect to the correct [homes] share, preferably
- without too many getpwnam() lookups. This is particulary nasty for
- winbind usernames, where the share name isn't the same as unix
- username.
+ /* Logic to try and connect to the correct [homes] share, preferably without too many
+ getpwnam() lookups. This is particulary nasty for winbind usernames, where the
+ share name isn't the same as unix username.
- The snum of the homes share is stored on the vuser at session setup
- time.
+ The snum of the homes share is stored on the vuser at session setup time.
*/
if (strequal(service_in,HOMES_NAME)) {
if(lp_security() != SEC_SHARE) {
DATA_BLOB no_pw = data_blob(NULL, 0);
if (vuser->homes_snum == -1) {
- DEBUG(2, ("[homes] share not available for "
- "this user because it was not found "
- "or created at session setup "
- "time\n"));
+ DEBUG(2, ("[homes] share not available for this user because it was not found or created at session setup time\n"));
*status = NT_STATUS_BAD_NETWORK_NAME;
return NULL;
}
- DEBUG(5, ("making a connection to [homes] service "
- "created at session setup time\n"));
+ DEBUG(5, ("making a connection to [homes] service created at session setup time\n"));
return make_connection_snum(vuser->homes_snum,
vuser, no_pw,
dev, status);
} else {
- /* Security = share. Try with
- * current_user_info.smb_name as the username. */
+ /* Security = share. Try with current_user_info.smb_name
+ * as the username. */
if (*current_user_info.smb_name) {
fstring unix_username;
fstrcpy(unix_username,
@@ -915,20 +768,16 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password,
snum = find_service(unix_username);
}
if (snum != -1) {
- DEBUG(5, ("making a connection to 'homes' "
- "service %s based on "
- "security=share\n", service_in));
+ DEBUG(5, ("making a connection to 'homes' service %s based on security=share\n", service_in));
return make_connection_snum(snum, NULL,
password,
dev, status);
}
}
} else if ((lp_security() != SEC_SHARE) && (vuser->homes_snum != -1)
- && strequal(service_in,
- lp_servicename(vuser->homes_snum))) {
+ && strequal(service_in, lp_servicename(vuser->homes_snum))) {
DATA_BLOB no_pw = data_blob(NULL, 0);
- DEBUG(5, ("making a connection to 'homes' service [%s] "
- "created at session setup time\n", service_in));
+ DEBUG(5, ("making a connection to 'homes' service [%s] created at session setup time\n", service_in));
return make_connection_snum(vuser->homes_snum,
vuser, no_pw,
dev, status);
@@ -941,8 +790,9 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password,
snum = find_service(service);
if (snum < 0) {
- if (strequal(service,"IPC$") ||
- (lp_enable_asu_support() && strequal(service,"ADMIN$"))) {
+ if (strequal(service,"IPC$")
+ || (lp_enable_asu_support() && strequal(service,"ADMIN$")))
+ {
DEBUG(3,("refusing IPC connection to %s\n", service));
*status = NT_STATUS_ACCESS_DENIED;
return NULL;
@@ -956,8 +806,7 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password,
/* Handle non-Dfs clients attempting connections to msdfs proxy */
if (lp_host_msdfs() && (*lp_msdfs_proxy(snum) != '\0')) {
- DEBUG(3, ("refusing connection to dfs proxy share '%s' "
- "(pointing to %s)\n",
+ DEBUG(3, ("refusing connection to dfs proxy share '%s' (pointing to %s)\n",
service, lp_msdfs_proxy(snum)));
*status = NT_STATUS_BAD_NETWORK_NAME;
return NULL;
@@ -986,8 +835,7 @@ void close_cnum(connection_struct *conn, uint16 vuid)
change_to_root_user();
DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n",
- get_remote_machine_name(),
- conn->client_address,
+ get_remote_machine_name(),conn->client_address,
lp_servicename(SNUM(conn))));
/* Call VFS disconnect hook */
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index 8ff219b468c..fc2a7686bd1 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -1436,8 +1436,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
p +=4;
}
SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
- SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
- SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
+ SIVAL(p,0,sbuf.st_dev); p += 4;
+ SIVAL(p,0,sbuf.st_ino); p += 4;
len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
SIVAL(q, 0, len);
p += len;
@@ -1486,8 +1486,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
}
p += 26;
SSVAL(p,0,0); p += 2; /* Reserved ? */
- SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */
- SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */
+ SIVAL(p,0,sbuf.st_dev); p += 4;
+ SIVAL(p,0,sbuf.st_ino); p += 4;
len = srvstr_push(outbuf, p, fname, -1, STR_TERMINATE_ASCII);
SIVAL(q,0,len);
p += len;
@@ -2824,7 +2824,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
}
- delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
+ delete_pending =
+ get_delete_on_close_flag(sbuf.st_dev,
+ sbuf.st_ino,
+ fname);
} else {
/*
* Original code - this is an open file.
@@ -2837,7 +2840,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
return(UNIXERROR(ERRDOS,ERRbadfid));
}
pos = fsp->fh->position_information;
- delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
+ delete_pending =
+ get_delete_on_close_flag(sbuf.st_dev,
+ sbuf.st_ino,
+ fname);
access_mask = fsp->access_mask;
}
} else {
@@ -2879,7 +2885,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
}
- delete_pending = get_delete_on_close_flag(sbuf.st_dev, sbuf.st_ino);
+ delete_pending = get_delete_on_close_flag(sbuf.st_dev,
+ sbuf.st_ino,
+ fname);
if (delete_pending) {
return ERROR_NT(NT_STATUS_DELETE_PENDING);
}
@@ -3216,8 +3224,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
BasicFileInformationTest. -tpot */
DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_INTERNAL_INFORMATION\n"));
- SIVAL(pdata,0,sbuf.st_ino); /* FileIndexLow */
- SIVAL(pdata,4,sbuf.st_dev); /* FileIndexHigh */
+ SIVAL(pdata,0,sbuf.st_dev);
+ SIVAL(pdata,4,sbuf.st_ino);
data_size = 8;
break;
diff --git a/source/smbd/uid.c b/source/smbd/uid.c
index 9db3d97ab2d..d1ecaf6625f 100644
--- a/source/smbd/uid.c
+++ b/source/smbd/uid.c
@@ -81,53 +81,45 @@ BOOL change_to_guest(void)
Readonly share for this user ?
****************************************************************************/
-static BOOL is_share_read_only_for_user(int snum, user_struct *vuser)
+static BOOL is_share_read_only_for_user(connection_struct *conn, user_struct *vuser)
{
char **list;
- const char *service = lp_servicename(snum);
- BOOL read_only_ret = lp_readonly(snum);
+ const char *service = lp_servicename(conn->service);
+ BOOL read_only_ret = lp_readonly(conn->service);
if (!service)
return read_only_ret;
- str_list_copy(&list, lp_readlist(snum));
+ str_list_copy(&list, lp_readlist(conn->service));
if (list) {
if (!str_list_sub_basic(list, vuser->user.smb_name) ) {
- DEBUG(0, ("is_share_read_only_for_user: ERROR: read "
- "list substitution failed\n"));
+ DEBUG(0, ("is_share_read_only_for_user: ERROR: read list substitution failed\n"));
}
if (!str_list_substitute(list, "%S", service)) {
- DEBUG(0, ("is_share_read_only_for_user: ERROR: read "
- "list service substitution failed\n"));
+ DEBUG(0, ("is_share_read_only_for_user: ERROR: read list service substitution failed\n"));
}
- if (user_in_list(vuser->user.unix_name, (const char **)list,
- vuser->groups, vuser->n_groups)) {
+ if (user_in_list(vuser->user.unix_name, (const char **)list, vuser->groups, vuser->n_groups)) {
read_only_ret = True;
}
str_list_free(&list);
}
- str_list_copy(&list, lp_writelist(snum));
+ str_list_copy(&list, lp_writelist(conn->service));
if (list) {
if (!str_list_sub_basic(list, vuser->user.smb_name) ) {
- DEBUG(0, ("is_share_read_only_for_user: ERROR: write "
- "list substitution failed\n"));
+ DEBUG(0, ("is_share_read_only_for_user: ERROR: write list substitution failed\n"));
}
if (!str_list_substitute(list, "%S", service)) {
- DEBUG(0, ("is_share_read_only_for_user: ERROR: write "
- "list service substitution failed\n"));
+ DEBUG(0, ("is_share_read_only_for_user: ERROR: write list service substitution failed\n"));
}
- if (user_in_list(vuser->user.unix_name, (const char **)list,
- vuser->groups, vuser->n_groups)) {
+ if (user_in_list(vuser->user.unix_name, (const char **)list, vuser->groups, vuser->n_groups)) {
read_only_ret = False;
}
str_list_free(&list);
}
- DEBUG(10,("is_share_read_only_for_user: share %s is %s for unix user "
- "%s\n", service,
- read_only_ret ? "read-only" : "read-write",
- vuser->user.unix_name ));
+ DEBUG(10,("is_share_read_only_for_user: share %s is %s for unix user %s\n",
+ service, read_only_ret ? "read-only" : "read-write", vuser->user.unix_name ));
return read_only_ret;
}
@@ -154,7 +146,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
if (!user_ok(vuser->user.unix_name,snum, vuser->groups, vuser->n_groups))
return(False);
- readonly_share = is_share_read_only_for_user(conn->service, vuser);
+ readonly_share = is_share_read_only_for_user(conn, vuser);
if (!readonly_share &&
!share_access_check(conn, snum, vuser, FILE_WRITE_DATA)) {
@@ -190,7 +182,7 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
/****************************************************************************
Become the user of a connection number without changing the security context
- stack, but modify the current_user entries.
+ stack, but modify the currnet_user entries.
****************************************************************************/
BOOL change_to_user(connection_struct *conn, uint16 vuid)
diff --git a/source/torture/torture.c b/source/torture/torture.c
index e995c3cc58a..0bd9aa1728b 100644
--- a/source/torture/torture.c
+++ b/source/torture/torture.c
@@ -4914,8 +4914,6 @@ static void usage(void)
setbuffer(stdout, NULL, 0);
#endif
- load_case_tables();
-
lp_load(dyn_CONFIGFILE,True,False,False);
load_interfaces();
diff --git a/source/torture/vfstest.c b/source/torture/vfstest.c
index 1914a4acb50..b5ccf930bc6 100644
--- a/source/torture/vfstest.c
+++ b/source/torture/vfstest.c
@@ -495,7 +495,6 @@ int main(int argc, char *argv[])
POPT_TABLEEND
};
- load_case_tables();
setlinebuf(stdout);
diff --git a/source/ubiqx/COPYING.LIB b/source/ubiqx/COPYING.LIB
new file mode 100644
index 00000000000..8c8377da464
--- /dev/null
+++ b/source/ubiqx/COPYING.LIB
@@ -0,0 +1,481 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/source/ubiqx/README.UBI b/source/ubiqx/README.UBI
new file mode 100644
index 00000000000..a2c14ca62c9
--- /dev/null
+++ b/source/ubiqx/README.UBI
@@ -0,0 +1,18 @@
+Fri Apr 17 10:21:56 CDT 1998
+
+The C code files in the samba/source/ubiqx directory are licensed under
+the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE (LGPL). A copy of the
+LGPL should also be included in this directory under the name COPYING.LIB.
+If this file is not present, you can obtain a copy of the LGPL by writing
+to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+USA.
+
+The versions of the ubiqx modules distributed with Samba may have been
+modified for inclusion with Samba. The main distribution, which contains
+additional available modules, can be found at:
+
+ http://www.interads.co.uk/~crh/ubiqx/
+
+Chris Hertel
+Samba Team
+ubiqx@ubiqx.mn.org
diff --git a/source/utils/debugparse.c b/source/ubiqx/debugparse.c
index c5fe3e2ee85..c5fe3e2ee85 100644
--- a/source/utils/debugparse.c
+++ b/source/ubiqx/debugparse.c
diff --git a/source/include/debugparse.h b/source/ubiqx/debugparse.h
index fb7f00f7792..458eee74558 100644
--- a/source/include/debugparse.h
+++ b/source/ubiqx/debugparse.h
@@ -31,7 +31,7 @@
* ========================================================================== **
*/
-#include "includes.h"
+#include "sys_include.h"
/* This module compiles quite nicely outside of the Samba environment.
* You'll need the following headers:
diff --git a/source/ubiqx/sys_include.h b/source/ubiqx/sys_include.h
new file mode 100644
index 00000000000..8ff270afe85
--- /dev/null
+++ b/source/ubiqx/sys_include.h
@@ -0,0 +1,52 @@
+#ifndef SYS_INCLUDE_H
+#define SYS_INCLUDE_H
+/* ========================================================================== **
+ * sys_include.h
+ *
+ * Copyright (C) 1998 by Christopher R. Hertel
+ *
+ * Email: crh@ubiqx.mn.org
+ * -------------------------------------------------------------------------- **
+ * This header provides system declarations and data types used internally
+ * by the ubiqx modules.
+ * -------------------------------------------------------------------------- **
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * Samba version of sys_include.h
+ *
+ * ========================================================================== **
+ */
+
+#ifndef _INCLUDES_H
+
+/* Block the inclusion of some Samba headers so that ubiqx types won't be
+ * used before the headers that define them. These headers are not needed
+ * in the ubiqx modules anyway.
+ */
+#define _PROTO_H_
+#define _NAMESERV_H_
+#define _HASH_H_
+
+/* The main Samba system-adaptive header file.
+ */
+#include "includes.h"
+
+#endif /* _INCLUDES_H */
+
+/* ================================ The End ================================= */
+#endif /* SYS_INCLUDE_H */
diff --git a/source/ubiqx/ubi_BinTree.c b/source/ubiqx/ubi_BinTree.c
new file mode 100644
index 00000000000..e452ac10dc2
--- /dev/null
+++ b/source/ubiqx/ubi_BinTree.c
@@ -0,0 +1,1172 @@
+/* ========================================================================== **
+ * ubi_BinTree.c
+ *
+ * Copyright (C) 1991-1998 by Christopher R. Hertel
+ *
+ * Email: crh@ubiqx.mn.org
+ * -------------------------------------------------------------------------- **
+ *
+ * This module implements a simple binary tree.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * Log: ubi_BinTree.c,v
+ * Revision 4.12 2004/06/06 04:51:56 crh
+ * Fixed a small typo in ubi_BinTree.c (leftover testing cruft).
+ * Did a small amount of formatting touchup to ubi_BinTree.h.
+ *
+ * Revision 4.11 2004/06/06 03:14:09 crh
+ * Rewrote the ubi_btLeafNode() function. It now takes several paths in an
+ * effort to find a deeper leaf node. There is a small amount of extra
+ * overhead, but it is limited.
+ *
+ * Revision 4.10 2000/06/06 20:38:40 crh
+ * In the ReplaceNode() function, the old node header was being copied
+ * to the new node header using a byte-by-byte copy. This was causing
+ * the 'insure' software testing program to report a memory leak. The
+ * fix was to do a simple assignement: *newnode = *oldnode;
+ * This quieted the (errant) memory leak reports and is probably a bit
+ * faster than the bytewise copy.
+ *
+ * Revision 4.9 2000/01/08 23:24:30 crh
+ * Clarified a variety of if( pointer ) lines, replacing them with
+ * if( NULL != pointer ). This is more correct, and I have heard
+ * of at least one (obscure?) system out there that uses a non-zero
+ * value for NULL.
+ * Also, speed improvement in Neighbor(). It was comparing pointers
+ * when it could have compared two gender values. The pointer
+ * comparison was somewhat indirect (does pointer equal the pointer
+ * of the parent of the node pointed to by pointer). Urq.
+ *
+ * Revision 4.8 1999/09/22 03:40:30 crh
+ * Modified ubi_btTraverse() and ubi_btKillTree(). They now return an
+ * unsigned long indicating the number of nodes processed. The change
+ * is subtle. An empty tree formerly returned False, and now returns
+ * zero.
+ *
+ * Revision 4.7 1998/10/21 06:14:42 crh
+ * Fixed bugs in FirstOf() and LastOf() reported by Massimo Campostrini.
+ * See function comments.
+ *
+ * Revision 4.6 1998/07/25 17:02:10 crh
+ * Added the ubi_trNewTree() macro.
+ *
+ * Revision 4.5 1998/06/04 21:29:27 crh
+ * Upper-cased defined constants (eg UBI_BINTREE_H) in some header files.
+ * This is more "standard", and is what people expect. Weird, eh?
+ *
+ * Revision 4.4 1998/06/03 17:42:46 crh
+ * Further fiddling with sys_include.h. It's now in ubi_BinTree.h which is
+ * included by all of the binary tree files.
+ *
+ * Reminder: Some of the ubi_tr* macros in ubi_BinTree.h are redefined in
+ * ubi_AVLtree.h and ubi_SplayTree.h. This allows easy swapping
+ * of tree types by simply changing a header. Unfortunately, the
+ * macro redefinitions in ubi_AVLtree.h and ubi_SplayTree.h will
+ * conflict if used together. You must either choose a single tree
+ * type, or use the underlying function calls directly. Compare
+ * the two header files for more information.
+ *
+ * Revision 4.3 1998/06/02 01:28:43 crh
+ * Changed ubi_null.h to sys_include.h to make it more generic.
+ *
+ * Revision 4.2 1998/05/20 04:32:36 crh
+ * The C file now includes ubi_null.h. See ubi_null.h for more info.
+ * Also, the balance and gender fields of the node were declared as
+ * signed char. As I understand it, at least one SunOS or Solaris
+ * compiler doesn't like "signed char". The declarations were
+ * wrong anyway, so I changed them to simple "char".
+ *
+ * Revision 4.1 1998/03/31 06:11:57 crh
+ * Thomas Aglassinger sent E'mail pointing out errors in the
+ * dereferencing of function pointers, and a missing typecast.
+ * Thanks, Thomas!
+ *
+ * Revision 4.0 1998/03/10 03:19:22 crh
+ * Added the AVL field 'balance' to the ubi_btNode structure. This means
+ * that all BinTree modules now use the same basic node structure, which
+ * greatly simplifies the AVL module.
+ * Decided that this was a big enough change to justify a new major revision
+ * number. 3.0 was an error, so we're at 4.0.
+ *
+ * Revision 2.6 1998/01/24 06:27:46 crh
+ * Added ubi_trCount() macro.
+ *
+ * Revision 2.5 1997/12/23 03:56:29 crh
+ * In this version, all constants & macros defined in the header file have
+ * the ubi_tr prefix. Also cleaned up anything that gcc complained about
+ * when run with '-pedantic -fsyntax-only -Wall'.
+ *
+ * Revision 2.4 1997/07/26 04:11:10 crh
+ * + Just to be annoying I changed ubi_TRUE and ubi_FALSE to ubi_trTRUE
+ * and ubi_trFALSE.
+ * + There is now a type ubi_trBool to go with ubi_trTRUE and ubi_trFALSE.
+ * + There used to be something called "ubi_TypeDefs.h". I got rid of it.
+ * + Added function ubi_btLeafNode().
+ *
+ * Revision 2.3 1997/06/03 05:16:17 crh
+ * Changed TRUE and FALSE to ubi_TRUE and ubi_FALSE to avoid conflicts.
+ * Also changed the interface to function InitTree(). See the comments
+ * for this function for more information.
+ *
+ * Revision 2.2 1995/10/03 22:00:07 CRH
+ * Ubisized!
+ *
+ * Revision 2.1 95/03/09 23:37:10 CRH
+ * Added the ModuleID static string and function. These modules are now
+ * self-identifying.
+ *
+ * Revision 2.0 95/02/27 22:00:17 CRH
+ * Revision 2.0 of this program includes the following changes:
+ *
+ * 1) A fix to a major typo in the RepaceNode() function.
+ * 2) The addition of the static function Border().
+ * 3) The addition of the public functions FirstOf() and LastOf(), which
+ * use Border(). These functions are used with trees that allow
+ * duplicate keys.
+ * 4) A complete rewrite of the Locate() function. Locate() now accepts
+ * a "comparison" operator.
+ * 5) Overall enhancements to both code and comments.
+ *
+ * I decided to give this a new major rev number because the interface has
+ * changed. In particular, there are two new functions, and changes to the
+ * Locate() function.
+ *
+ * Revision 1.0 93/10/15 22:44:59 CRH
+ * With this revision, I have added a set of #define's that provide a single,
+ * standard API to all existing tree modules. Until now, each of the three
+ * existing modules had a different function and typedef prefix, as follows:
+ *
+ * Module Prefix
+ * ubi_BinTree ubi_bt
+ * ubi_AVLtree ubi_avl
+ * ubi_SplayTree ubi_spt
+ *
+ * To further complicate matters, only those portions of the base module
+ * (ubi_BinTree) that were superceeded in the new module had the new names.
+ * For example, if you were using ubi_SplayTree, the locate function was
+ * called "ubi_sptLocate", but the next and previous functions remained
+ * "ubi_btNext" and "ubi_btPrev".
+ *
+ * This was not too terrible if you were familiar with the modules and knew
+ * exactly which tree model you wanted to use. If you wanted to be able to
+ * change modules (for speed comparisons, etc), things could get messy very
+ * quickly.
+ *
+ * So, I have added a set of defined names that get redefined in any of the
+ * descendant modules. To use this standardized interface in your code,
+ * simply replace all occurances of "ubi_bt", "ubi_avl", and "ubi_spt" with
+ * "ubi_tr". The "ubi_tr" names will resolve to the correct function or
+ * datatype names for the module that you are using. Just remember to
+ * include the header for that module in your program file. Because these
+ * names are handled by the preprocessor, there is no added run-time
+ * overhead.
+ *
+ * Note that the original names do still exist, and can be used if you wish
+ * to write code directly to a specific module. This should probably only be
+ * done if you are planning to implement a new descendant type, such as
+ * red/black trees. CRH
+ *
+ * V0.0 - June, 1991 - Written by Christopher R. Hertel (CRH).
+ *
+ * ========================================================================== **
+ */
+
+#include "ubi_BinTree.h" /* Header for this module. */
+
+
+/* ========================================================================== **
+ * Static data.
+ */
+
+static char ModuleID[] = "ubi_BinTree\n\
+\tRevision: 4.12\n\
+\tDate: 2004/06/06 04:51:56\n\
+\tAuthor: crh\n";
+
+/* ========================================================================== **
+ * Internal (private) functions.
+ */
+
+static ubi_btNodePtr qFind( ubi_btCompFunc cmp,
+ ubi_btItemPtr FindMe,
+ register ubi_btNodePtr p )
+ /* ------------------------------------------------------------------------ **
+ * This function performs a non-recursive search of a tree for a node
+ * matching a specific key. It is called "qFind()" because it is
+ * faster that TreeFind (below).
+ *
+ * Input:
+ * cmp - a pointer to the tree's comparison function.
+ * FindMe - a pointer to the key value for which to search.
+ * p - a pointer to the starting point of the search. <p>
+ * is considered to be the root of a subtree, and only
+ * the subtree will be searched.
+ *
+ * Output:
+ * A pointer to a node with a key that matches the key indicated by
+ * FindMe, or NULL if no such node was found.
+ *
+ * Note: In a tree that allows duplicates, the pointer returned *might
+ * not* point to the (sequentially) first occurance of the
+ * desired key.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ int tmp;
+
+ while( (NULL != p)
+ && ((tmp = ubi_trAbNormal( (*cmp)(FindMe, p) )) != ubi_trEQUAL) )
+ p = p->Link[tmp];
+
+ return( p );
+ } /* qFind */
+
+static ubi_btNodePtr TreeFind( ubi_btItemPtr findme,
+ ubi_btNodePtr p,
+ ubi_btNodePtr *parentp,
+ char *gender,
+ ubi_btCompFunc CmpFunc )
+ /* ------------------------------------------------------------------------ **
+ * TreeFind() searches a tree for a given value (findme). It will return a
+ * pointer to the target node, if found, or NULL if the target node was not
+ * found.
+ *
+ * TreeFind() also returns, via parameters, a pointer to the parent of the
+ * target node, and a LEFT or RIGHT value indicating which child of the
+ * parent is the target node. *If the target is not found*, then these
+ * values indicate the place at which the target *should be found*. This
+ * is useful when inserting a new node into a tree or searching for nodes
+ * "near" the target node.
+ *
+ * The parameters are:
+ *
+ * findme - is a pointer to the key information to be searched for.
+ * p - points to the root of the tree to be searched.
+ * parentp - will return a pointer to a pointer to the !parent! of the
+ * target node, which can be especially usefull if the target
+ * was not found.
+ * gender - returns LEFT or RIGHT to indicate which child of *parentp
+ * was last searched.
+ * CmpFunc - points to the comparison function.
+ *
+ * This function is called by ubi_btLocate() and ubi_btInsert().
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ register ubi_btNodePtr tmp_p = p;
+ ubi_btNodePtr tmp_pp = NULL;
+ char tmp_gender = ubi_trEQUAL;
+ int tmp_cmp;
+
+ while( (NULL != tmp_p)
+ && (ubi_trEQUAL != (tmp_cmp = ubi_trAbNormal((*CmpFunc)(findme, tmp_p)))) )
+ {
+ tmp_pp = tmp_p; /* Keep track of previous node. */
+ tmp_gender = (char)tmp_cmp; /* Keep track of sex of child. */
+ tmp_p = tmp_p->Link[tmp_cmp]; /* Go to child. */
+ }
+ *parentp = tmp_pp; /* Return results. */
+ *gender = tmp_gender;
+ return( tmp_p );
+ } /* TreeFind */
+
+static void ReplaceNode( ubi_btNodePtr *parent,
+ ubi_btNodePtr oldnode,
+ ubi_btNodePtr newnode )
+ /* ------------------------------------------------------------------------ **
+ * Remove node oldnode from the tree, replacing it with node newnode.
+ *
+ * Input:
+ * parent - A pointer to he parent pointer of the node to be
+ * replaced. <parent> may point to the Link[] field of
+ * a parent node, or it may indicate the root pointer at
+ * the top of the tree.
+ * oldnode - A pointer to the node that is to be replaced.
+ * newnode - A pointer to the node that is to be installed in the
+ * place of <*oldnode>.
+ *
+ * Notes: Don't forget to free oldnode.
+ * Also, this function used to have a really nasty typo
+ * bug. "oldnode" and "newnode" were swapped in the line
+ * that now reads:
+ * ((unsigned char *)newnode)[i] = ((unsigned char *)oldnode)[i];
+ * Bleah!
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ *newnode = *oldnode; /* Copy node internals to new node. */
+
+ (*parent) = newnode; /* Old node's parent points to new child. */
+ /* Now tell the children about their new step-parent. */
+ if( oldnode->Link[ubi_trLEFT] )
+ (oldnode->Link[ubi_trLEFT])->Link[ubi_trPARENT] = newnode;
+ if( oldnode->Link[ubi_trRIGHT] )
+ (oldnode->Link[ubi_trRIGHT])->Link[ubi_trPARENT] = newnode;
+ } /* ReplaceNode */
+
+static void SwapNodes( ubi_btRootPtr RootPtr,
+ ubi_btNodePtr Node1,
+ ubi_btNodePtr Node2 )
+ /* ------------------------------------------------------------------------ **
+ * This function swaps two nodes in the tree. Node1 will take the place of
+ * Node2, and Node2 will fill in the space left vacant by Node 1.
+ *
+ * Input:
+ * RootPtr - pointer to the tree header structure for this tree.
+ * Node1 - \
+ * > These are the two nodes which are to be swapped.
+ * Node2 - /
+ *
+ * Notes:
+ * This function does a three step swap, using a dummy node as a place
+ * holder. This function is used by ubi_btRemove().
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_btNodePtr *Parent;
+ ubi_btNode dummy;
+ ubi_btNodePtr dummy_p = &dummy;
+
+ /* Replace Node 1 with the dummy, thus removing Node1 from the tree. */
+ if( NULL != Node1->Link[ubi_trPARENT] )
+ Parent = &((Node1->Link[ubi_trPARENT])->Link[(int)(Node1->gender)]);
+ else
+ Parent = &(RootPtr->root);
+ ReplaceNode( Parent, Node1, dummy_p );
+
+ /* Swap Node 1 with Node 2, placing Node 1 back into the tree. */
+ if( NULL != Node2->Link[ubi_trPARENT] )
+ Parent = &((Node2->Link[ubi_trPARENT])->Link[(int)(Node2->gender)]);
+ else
+ Parent = &(RootPtr->root);
+ ReplaceNode( Parent, Node2, Node1 );
+
+ /* Swap Node 2 and the dummy, thus placing Node 2 back into the tree. */
+ if( NULL != dummy_p->Link[ubi_trPARENT] )
+ Parent = &((dummy_p->Link[ubi_trPARENT])->Link[(int)(dummy_p->gender)]);
+ else
+ Parent = &(RootPtr->root);
+ ReplaceNode( Parent, dummy_p, Node2 );
+ } /* SwapNodes */
+
+/* -------------------------------------------------------------------------- **
+ * These routines allow you to walk through the tree, forwards or backwards.
+ */
+
+static ubi_btNodePtr SubSlide( register ubi_btNodePtr P,
+ register int whichway )
+ /* ------------------------------------------------------------------------ **
+ * Slide down the side of a subtree.
+ *
+ * Given a starting node, this function returns a pointer to the LEFT-, or
+ * RIGHT-most descendent, *or* (if whichway is PARENT) to the tree root.
+ *
+ * Input: P - a pointer to a starting place.
+ * whichway - the direction (LEFT, RIGHT, or PARENT) in which to
+ * travel.
+ * Output: A pointer to a node that is either the root, or has no
+ * whichway-th child but is within the subtree of P. Note that
+ * the return value may be the same as P. The return value *will
+ * be* NULL if P is NULL.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+
+ if( NULL != P )
+ while( NULL != P->Link[ whichway ] )
+ P = P->Link[ whichway ];
+ return( P );
+ } /* SubSlide */
+
+static ubi_btNodePtr Neighbor( register ubi_btNodePtr P,
+ register int whichway )
+ /* ------------------------------------------------------------------------ **
+ * Given starting point p, return the (key order) next or preceeding node
+ * in the tree.
+ *
+ * Input: P - Pointer to our starting place node.
+ * whichway - the direction in which to travel to find the
+ * neighbor, i.e., the RIGHT neighbor or the LEFT
+ * neighbor.
+ *
+ * Output: A pointer to the neighboring node, or NULL if P was NULL.
+ *
+ * Notes: If whichway is PARENT, the results are unpredictable.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ if( P )
+ {
+ if( NULL != P->Link[ whichway ] )
+ return( SubSlide( P->Link[ whichway ], (char)ubi_trRevWay(whichway) ) );
+ else
+ while( NULL != P->Link[ ubi_trPARENT ] )
+ {
+ if( whichway == P->gender )
+ P = P->Link[ ubi_trPARENT ];
+ else
+ return( P->Link[ ubi_trPARENT ] );
+ }
+ }
+ return( NULL );
+ } /* Neighbor */
+
+static ubi_btNodePtr Border( ubi_btRootPtr RootPtr,
+ ubi_btItemPtr FindMe,
+ ubi_btNodePtr p,
+ int whichway )
+ /* ------------------------------------------------------------------------ **
+ * Given starting point p, which has a key value equal to *FindMe, locate
+ * the first (index order) node with the same key value.
+ *
+ * This function is useful in trees that have can have duplicate keys.
+ * For example, consider the following tree:
+ * Tree Traversal
+ * 2 If <p> points to the root and <whichway> is RIGHT, 3
+ * / \ then the return value will be a pointer to the / \
+ * 2 2 RIGHT child of the root node. The tree on 2 5
+ * / / \ the right shows the order of traversal. / / \
+ * 1 2 3 1 4 6
+ *
+ * Input: RootPtr - Pointer to the tree root structure.
+ * FindMe - Key value for comparisons.
+ * p - Pointer to the starting-point node.
+ * whichway - the direction in which to travel to find the
+ * neighbor, i.e., the RIGHT neighbor or the LEFT
+ * neighbor.
+ *
+ * Output: A pointer to the first (index, or "traversal", order) node with
+ * a Key value that matches *FindMe.
+ *
+ * Notes: If whichway is PARENT, or if the tree does not allow duplicate
+ * keys, this function will return <p>.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ register ubi_btNodePtr q;
+
+ /* Exit if there's nothing that can be done. */
+ if( !ubi_trDups_OK( RootPtr ) || (ubi_trPARENT == whichway) )
+ return( p );
+
+ /* First, if needed, move up the tree. We need to get to the root of the
+ * subtree that contains all of the matching nodes.
+ */
+ q = p->Link[ubi_trPARENT];
+ while( (NULL != q)
+ && (ubi_trEQUAL == ubi_trAbNormal( (*(RootPtr->cmp))(FindMe, q) )) )
+ {
+ p = q;
+ q = p->Link[ubi_trPARENT];
+ }
+
+ /* Next, move back down in the "whichway" direction. */
+ q = p->Link[whichway];
+ while( NULL != q )
+ {
+ q = qFind( RootPtr->cmp, FindMe, q );
+ if( q )
+ {
+ p = q;
+ q = p->Link[whichway];
+ }
+ }
+ return( p );
+ } /* Border */
+
+
+/* ========================================================================== **
+ * Exported utilities.
+ */
+
+long ubi_btSgn( register long x )
+ /* ------------------------------------------------------------------------ **
+ * Return the sign of x; {negative,zero,positive} ==> {-1, 0, 1}.
+ *
+ * Input: x - a signed long integer value.
+ *
+ * Output: the "sign" of x, represented as follows:
+ * -1 == negative
+ * 0 == zero (no sign)
+ * 1 == positive
+ *
+ * Note: This utility is provided in order to facilitate the conversion
+ * of C comparison function return values into BinTree direction
+ * values: {LEFT, PARENT, EQUAL}. It is INCORPORATED into the
+ * ubi_trAbNormal() conversion macro!
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ return( (x)?((x>0)?(1):(-1)):(0) );
+ } /* ubi_btSgn */
+
+ubi_btNodePtr ubi_btInitNode( ubi_btNodePtr NodePtr )
+ /* ------------------------------------------------------------------------ **
+ * Initialize a tree node.
+ *
+ * Input: a pointer to a ubi_btNode structure to be initialized.
+ * Output: a pointer to the initialized ubi_btNode structure (ie. the
+ * same as the input pointer).
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ NodePtr->Link[ ubi_trLEFT ] = NULL;
+ NodePtr->Link[ ubi_trPARENT ] = NULL;
+ NodePtr->Link[ ubi_trRIGHT ] = NULL;
+ NodePtr->gender = ubi_trEQUAL;
+ NodePtr->balance = ubi_trEQUAL;
+ return( NodePtr );
+ } /* ubi_btInitNode */
+
+ubi_btRootPtr ubi_btInitTree( ubi_btRootPtr RootPtr,
+ ubi_btCompFunc CompFunc,
+ char Flags )
+ /* ------------------------------------------------------------------------ **
+ * Initialize the fields of a Tree Root header structure.
+ *
+ * Input: RootPtr - a pointer to an ubi_btRoot structure to be
+ * initialized.
+ * CompFunc - a pointer to a comparison function that will be used
+ * whenever nodes in the tree must be compared against
+ * outside values.
+ * Flags - One bytes worth of flags. Flags include
+ * ubi_trOVERWRITE and ubi_trDUPKEY. See the header
+ * file for more info.
+ *
+ * Output: a pointer to the initialized ubi_btRoot structure (ie. the
+ * same value as RootPtr).
+ *
+ * Note: The interface to this function has changed from that of
+ * previous versions. The <Flags> parameter replaces two
+ * boolean parameters that had the same basic effect.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ if( RootPtr )
+ {
+ RootPtr->root = NULL;
+ RootPtr->count = 0L;
+ RootPtr->cmp = CompFunc;
+ RootPtr->flags = (Flags & ubi_trDUPKEY) ? ubi_trDUPKEY : Flags;
+ } /* There are only two supported flags, and they are
+ * mutually exclusive. ubi_trDUPKEY takes precedence
+ * over ubi_trOVERWRITE.
+ */
+ return( RootPtr );
+ } /* ubi_btInitTree */
+
+ubi_trBool ubi_btInsert( ubi_btRootPtr RootPtr,
+ ubi_btNodePtr NewNode,
+ ubi_btItemPtr ItemPtr,
+ ubi_btNodePtr *OldNode )
+ /* ------------------------------------------------------------------------ **
+ * This function uses a non-recursive algorithm to add a new element to the
+ * tree.
+ *
+ * Input: RootPtr - a pointer to the ubi_btRoot structure that indicates
+ * the root of the tree to which NewNode is to be added.
+ * NewNode - a pointer to an ubi_btNode structure that is NOT
+ * part of any tree.
+ * ItemPtr - A pointer to the sort key that is stored within
+ * *NewNode. ItemPtr MUST point to information stored
+ * in *NewNode or an EXACT DUPLICATE. The key data
+ * indicated by ItemPtr is used to place the new node
+ * into the tree.
+ * OldNode - a pointer to an ubi_btNodePtr. When searching
+ * the tree, a duplicate node may be found. If
+ * duplicates are allowed, then the new node will
+ * be simply placed into the tree. If duplicates
+ * are not allowed, however, then one of two things
+ * may happen.
+ * 1) if overwritting *is not* allowed, this
+ * function will return FALSE (indicating that
+ * the new node could not be inserted), and
+ * *OldNode will point to the duplicate that is
+ * still in the tree.
+ * 2) if overwritting *is* allowed, then this
+ * function will swap **OldNode for *NewNode.
+ * In this case, *OldNode will point to the node
+ * that was removed (thus allowing you to free
+ * the node).
+ * ** If you are using overwrite mode, ALWAYS **
+ * ** check the return value of this parameter! **
+ * Note: You may pass NULL in this parameter, the
+ * function knows how to cope. If you do this,
+ * however, there will be no way to return a
+ * pointer to an old (ie. replaced) node (which is
+ * a problem if you are using overwrite mode).
+ *
+ * Output: a boolean value indicating success or failure. The function
+ * will return FALSE if the node could not be added to the tree.
+ * Such failure will only occur if duplicates are not allowed,
+ * nodes cannot be overwritten, AND a duplicate key was found
+ * within the tree.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_btNodePtr OtherP,
+ parent = NULL;
+ char tmp;
+
+ if( NULL == OldNode ) /* If they didn't give us a pointer, supply our own. */
+ OldNode = &OtherP;
+
+ (void)ubi_btInitNode( NewNode ); /* Init the new node's BinTree fields. */
+
+ /* Find a place for the new node. */
+ *OldNode = TreeFind(ItemPtr, (RootPtr->root), &parent, &tmp, (RootPtr->cmp));
+
+ /* Now add the node to the tree... */
+ if( NULL == (*OldNode) ) /* The easy one: we have a space for a new node! */
+ {
+ if( NULL == parent )
+ RootPtr->root = NewNode;
+ else
+ {
+ parent->Link[(int)tmp] = NewNode;
+ NewNode->Link[ubi_trPARENT] = parent;
+ NewNode->gender = tmp;
+ }
+ (RootPtr->count)++;
+ return( ubi_trTRUE );
+ }
+
+ /* If we reach this point, we know that a duplicate node exists. This
+ * section adds the node to the tree if duplicate keys are allowed.
+ */
+ if( ubi_trDups_OK(RootPtr) ) /* Key exists, add duplicate */
+ {
+ ubi_btNodePtr q;
+
+ tmp = ubi_trRIGHT;
+ q = (*OldNode);
+ *OldNode = NULL;
+ while( NULL != q )
+ {
+ parent = q;
+ if( tmp == ubi_trEQUAL )
+ tmp = ubi_trRIGHT;
+ q = q->Link[(int)tmp];
+ if ( q )
+ tmp = ubi_trAbNormal( (*(RootPtr->cmp))(ItemPtr, q) );
+ }
+ parent->Link[(int)tmp] = NewNode;
+ NewNode->Link[ubi_trPARENT] = parent;
+ NewNode->gender = tmp;
+ (RootPtr->count)++;
+ return( ubi_trTRUE );
+ }
+
+ /* If we get to *this* point, we know that we are not allowed to have
+ * duplicate nodes, but our node keys match, so... may we replace the
+ * old one?
+ */
+ if( ubi_trOvwt_OK(RootPtr) ) /* Key exists, we replace */
+ {
+ if( NULL == parent )
+ ReplaceNode( &(RootPtr->root), *OldNode, NewNode );
+ else
+ ReplaceNode( &(parent->Link[(int)((*OldNode)->gender)]),
+ *OldNode, NewNode );
+ return( ubi_trTRUE );
+ }
+
+ return( ubi_trFALSE ); /* Failure: could not replace an existing node. */
+ } /* ubi_btInsert */
+
+ubi_btNodePtr ubi_btRemove( ubi_btRootPtr RootPtr,
+ ubi_btNodePtr DeadNode )
+ /* ------------------------------------------------------------------------ **
+ * This function removes the indicated node from the tree.
+ *
+ * Input: RootPtr - A pointer to the header of the tree that contains
+ * the node to be removed.
+ * DeadNode - A pointer to the node that will be removed.
+ *
+ * Output: This function returns a pointer to the node that was removed
+ * from the tree (ie. the same as DeadNode).
+ *
+ * Note: The node MUST be in the tree indicated by RootPtr. If not,
+ * strange and evil things will happen to your trees.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_btNodePtr p,
+ *parentp;
+ int tmp;
+
+ /* if the node has both left and right subtrees, then we have to swap
+ * it with another node. The other node we choose will be the Prev()ious
+ * node, which is garunteed to have no RIGHT child.
+ */
+ if( (NULL != DeadNode->Link[ubi_trLEFT])
+ && (NULL != DeadNode->Link[ubi_trRIGHT]) )
+ SwapNodes( RootPtr, DeadNode, ubi_btPrev( DeadNode ) );
+
+ /* The parent of the node to be deleted may be another node, or it may be
+ * the root of the tree. Since we're not sure, it's best just to have
+ * a pointer to the parent pointer, whatever it is.
+ */
+ if( NULL == DeadNode->Link[ubi_trPARENT] )
+ parentp = &( RootPtr->root );
+ else
+ parentp = &((DeadNode->Link[ubi_trPARENT])->Link[(int)(DeadNode->gender)]);
+
+ /* Now link the parent to the only grand-child and patch up the gender. */
+ tmp = ((DeadNode->Link[ubi_trLEFT])?ubi_trLEFT:ubi_trRIGHT);
+
+ p = (DeadNode->Link[tmp]);
+ if( NULL != p )
+ {
+ p->Link[ubi_trPARENT] = DeadNode->Link[ubi_trPARENT];
+ p->gender = DeadNode->gender;
+ }
+ (*parentp) = p;
+
+ /* Finished, reduce the node count and return. */
+ (RootPtr->count)--;
+ return( DeadNode );
+ } /* ubi_btRemove */
+
+ubi_btNodePtr ubi_btLocate( ubi_btRootPtr RootPtr,
+ ubi_btItemPtr FindMe,
+ ubi_trCompOps CompOp )
+ /* ------------------------------------------------------------------------ **
+ * The purpose of ubi_btLocate() is to find a node or set of nodes given
+ * a target value and a "comparison operator". The Locate() function is
+ * more flexible and (in the case of trees that may contain dupicate keys)
+ * more precise than the ubi_btFind() function. The latter is faster,
+ * but it only searches for exact matches and, if the tree contains
+ * duplicates, Find() may return a pointer to any one of the duplicate-
+ * keyed records.
+ *
+ * Input:
+ * RootPtr - A pointer to the header of the tree to be searched.
+ * FindMe - An ubi_btItemPtr that indicates the key for which to
+ * search.
+ * CompOp - One of the following:
+ * CompOp Return a pointer to the node with
+ * ------ ---------------------------------
+ * ubi_trLT - the last key value that is less
+ * than FindMe.
+ * ubi_trLE - the first key matching FindMe, or
+ * the last key that is less than
+ * FindMe.
+ * ubi_trEQ - the first key matching FindMe.
+ * ubi_trGE - the first key matching FindMe, or the
+ * first key greater than FindMe.
+ * ubi_trGT - the first key greater than FindMe.
+ * Output:
+ * A pointer to the node matching the criteria listed above under
+ * CompOp, or NULL if no node matched the criteria.
+ *
+ * Notes:
+ * In the case of trees with duplicate keys, Locate() will behave as
+ * follows:
+ *
+ * Find: 3 Find: 3
+ * Keys: 1 2 2 2 3 3 3 3 3 4 4 Keys: 1 1 2 2 2 4 4 5 5 5 6
+ * ^ ^ ^ ^ ^
+ * LT EQ GT LE GE
+ *
+ * That is, when returning a pointer to a node with a key that is LESS
+ * THAN the target key (FindMe), Locate() will return a pointer to the
+ * LAST matching node.
+ * When returning a pointer to a node with a key that is GREATER
+ * THAN the target key (FindMe), Locate() will return a pointer to the
+ * FIRST matching node.
+ *
+ * See Also: ubi_btFind(), ubi_btFirstOf(), ubi_btLastOf().
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ register ubi_btNodePtr p;
+ ubi_btNodePtr parent;
+ char whichkid;
+
+ /* Start by searching for a matching node. */
+ p = TreeFind( FindMe,
+ RootPtr->root,
+ &parent,
+ &whichkid,
+ RootPtr->cmp );
+
+ if( NULL != p ) /* If we have found a match, we can resolve as follows: */
+ {
+ switch( CompOp )
+ {
+ case ubi_trLT: /* It's just a jump to the left... */
+ p = Border( RootPtr, FindMe, p, ubi_trLEFT );
+ return( Neighbor( p, ubi_trLEFT ) );
+ case ubi_trGT: /* ...and then a jump to the right. */
+ p = Border( RootPtr, FindMe, p, ubi_trRIGHT );
+ return( Neighbor( p, ubi_trRIGHT ) );
+ default:
+ p = Border( RootPtr, FindMe, p, ubi_trLEFT );
+ return( p );
+ }
+ }
+
+ /* Else, no match. */
+ if( ubi_trEQ == CompOp ) /* If we were looking for an exact match... */
+ return( NULL ); /* ...forget it. */
+
+ /* We can still return a valid result for GT, GE, LE, and LT.
+ * <parent> points to a node with a value that is either just before or
+ * just after the target value.
+ * Remaining possibilities are LT and GT (including LE & GE).
+ */
+ if( (ubi_trLT == CompOp) || (ubi_trLE == CompOp) )
+ return( (ubi_trLEFT == whichkid) ? Neighbor( parent, whichkid ) : parent );
+ else
+ return( (ubi_trRIGHT == whichkid) ? Neighbor( parent, whichkid ) : parent );
+ } /* ubi_btLocate */
+
+ubi_btNodePtr ubi_btFind( ubi_btRootPtr RootPtr,
+ ubi_btItemPtr FindMe )
+ /* ------------------------------------------------------------------------ **
+ * This function performs a non-recursive search of a tree for any node
+ * matching a specific key.
+ *
+ * Input:
+ * RootPtr - a pointer to the header of the tree to be searched.
+ * FindMe - a pointer to the key value for which to search.
+ *
+ * Output:
+ * A pointer to a node with a key that matches the key indicated by
+ * FindMe, or NULL if no such node was found.
+ *
+ * Note: In a tree that allows duplicates, the pointer returned *might
+ * not* point to the (sequentially) first occurance of the
+ * desired key. In such a tree, it may be more useful to use
+ * ubi_btLocate().
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ return( qFind( RootPtr->cmp, FindMe, RootPtr->root ) );
+ } /* ubi_btFind */
+
+ubi_btNodePtr ubi_btNext( ubi_btNodePtr P )
+ /* ------------------------------------------------------------------------ **
+ * Given the node indicated by P, find the (sorted order) Next node in the
+ * tree.
+ * Input: P - a pointer to a node that exists in a binary tree.
+ * Output: A pointer to the "next" node in the tree, or NULL if P pointed
+ * to the "last" node in the tree or was NULL.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ return( Neighbor( P, ubi_trRIGHT ) );
+ } /* ubi_btNext */
+
+ubi_btNodePtr ubi_btPrev( ubi_btNodePtr P )
+ /* ------------------------------------------------------------------------ **
+ * Given the node indicated by P, find the (sorted order) Previous node in
+ * the tree.
+ * Input: P - a pointer to a node that exists in a binary tree.
+ * Output: A pointer to the "previous" node in the tree, or NULL if P
+ * pointed to the "first" node in the tree or was NULL.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ return( Neighbor( P, ubi_trLEFT ) );
+ } /* ubi_btPrev */
+
+ubi_btNodePtr ubi_btFirst( ubi_btNodePtr P )
+ /* ------------------------------------------------------------------------ **
+ * Given the node indicated by P, find the (sorted order) First node in the
+ * subtree of which *P is the root.
+ * Input: P - a pointer to a node that exists in a binary tree.
+ * Output: A pointer to the "first" node in a subtree that has *P as its
+ * root. This function will return NULL only if P is NULL.
+ * Note: In general, you will be passing in the value of the root field
+ * of an ubi_btRoot structure.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ return( SubSlide( P, ubi_trLEFT ) );
+ } /* ubi_btFirst */
+
+ubi_btNodePtr ubi_btLast( ubi_btNodePtr P )
+ /* ------------------------------------------------------------------------ **
+ * Given the node indicated by P, find the (sorted order) Last node in the
+ * subtree of which *P is the root.
+ * Input: P - a pointer to a node that exists in a binary tree.
+ * Output: A pointer to the "last" node in a subtree that has *P as its
+ * root. This function will return NULL only if P is NULL.
+ * Note: In general, you will be passing in the value of the root field
+ * of an ubi_btRoot structure.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ return( SubSlide( P, ubi_trRIGHT ) );
+ } /* ubi_btLast */
+
+ubi_btNodePtr ubi_btFirstOf( ubi_btRootPtr RootPtr,
+ ubi_btItemPtr MatchMe,
+ ubi_btNodePtr p )
+ /* ------------------------------------------------------------------------ **
+ * Given a tree that a allows duplicate keys, and a pointer to a node in
+ * the tree, this function will return a pointer to the first (traversal
+ * order) node with the same key value.
+ *
+ * Input: RootPtr - A pointer to the root of the tree.
+ * MatchMe - A pointer to the key value. This should probably
+ * point to the key within node *p.
+ * p - A pointer to a node in the tree.
+ * Output: A pointer to the first node in the set of nodes with keys
+ * matching <FindMe>.
+ * Notes: Node *p MUST be in the set of nodes with keys matching
+ * <FindMe>. If not, this function will return NULL.
+ *
+ * 4.7: Bug found & fixed by Massimo Campostrini,
+ * Istituto Nazionale di Fisica Nucleare, Sezione di Pisa.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ /* If our starting point is invalid, return NULL. */
+ if( (NULL == p)
+ || (ubi_trEQUAL != ubi_trAbNormal( (*(RootPtr->cmp))( MatchMe, p ) )) )
+ return( NULL );
+ return( Border( RootPtr, MatchMe, p, ubi_trLEFT ) );
+ } /* ubi_btFirstOf */
+
+ubi_btNodePtr ubi_btLastOf( ubi_btRootPtr RootPtr,
+ ubi_btItemPtr MatchMe,
+ ubi_btNodePtr p )
+ /* ------------------------------------------------------------------------ **
+ * Given a tree that a allows duplicate keys, and a pointer to a node in
+ * the tree, this function will return a pointer to the last (traversal
+ * order) node with the same key value.
+ *
+ * Input: RootPtr - A pointer to the root of the tree.
+ * MatchMe - A pointer to the key value. This should probably
+ * point to the key within node *p.
+ * p - A pointer to a node in the tree.
+ * Output: A pointer to the last node in the set of nodes with keys
+ * matching <FindMe>.
+ * Notes: Node *p MUST be in the set of nodes with keys matching
+ * <FindMe>. If not, this function will return NULL.
+ *
+ * 4.7: Bug found & fixed by Massimo Campostrini,
+ * Istituto Nazionale di Fisica Nucleare, Sezione di Pisa.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ /* If our starting point is invalid, return NULL. */
+ if( (NULL != p)
+ || (ubi_trEQUAL != ubi_trAbNormal( (*(RootPtr->cmp))( MatchMe, p ) )) )
+ return( NULL );
+ return( Border( RootPtr, MatchMe, p, ubi_trRIGHT ) );
+ } /* ubi_btLastOf */
+
+unsigned long ubi_btTraverse( ubi_btRootPtr RootPtr,
+ ubi_btActionRtn EachNode,
+ void *UserData )
+ /* ------------------------------------------------------------------------ **
+ * Traverse a tree in sorted order (non-recursively). At each node, call
+ * (*EachNode)(), passing a pointer to the current node, and UserData as the
+ * second parameter.
+ *
+ * Input: RootPtr - a pointer to an ubi_btRoot structure that indicates
+ * the tree to be traversed.
+ * EachNode - a pointer to a function to be called at each node
+ * as the node is visited.
+ * UserData - a generic pointer that may point to anything that
+ * you choose.
+ *
+ * Output: A count of the number of nodes visited. This will be zero
+ * if the tree is empty.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_btNodePtr p = ubi_btFirst( RootPtr->root );
+ unsigned long count = 0;
+
+ while( NULL != p )
+ {
+ (*EachNode)( p, UserData );
+ count++;
+ p = ubi_btNext( p );
+ }
+ return( count );
+ } /* ubi_btTraverse */
+
+unsigned long ubi_btKillTree( ubi_btRootPtr RootPtr,
+ ubi_btKillNodeRtn FreeNode )
+ /* ------------------------------------------------------------------------ **
+ * Delete an entire tree (non-recursively) and reinitialize the ubi_btRoot
+ * structure. Return a count of the number of nodes deleted.
+ *
+ * Input: RootPtr - a pointer to an ubi_btRoot structure that indicates
+ * the root of the tree to delete.
+ * FreeNode - a function that will be called for each node in the
+ * tree to deallocate the memory used by the node.
+ *
+ * Output: The number of nodes removed from the tree.
+ * A value of 0 will be returned if:
+ * - The tree actually contains 0 entries.
+ * - the value of <RootPtr> is NULL, in which case the tree is
+ * assumed to be empty
+ * - the value of <FreeNode> is NULL, in which case entries
+ * cannot be removed, so 0 is returned. *Make sure that you
+ * provide a valid value for <FreeNode>*.
+ * In all other cases, you should get a positive value equal to
+ * the value of RootPtr->count upon entry.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_btNodePtr p, q;
+ unsigned long count = 0;
+
+ if( (NULL == RootPtr) || (NULL == FreeNode) )
+ return( 0 );
+
+ p = ubi_btFirst( RootPtr->root );
+ while( NULL != p )
+ {
+ q = p;
+ while( q->Link[ubi_trRIGHT] )
+ q = SubSlide( q->Link[ubi_trRIGHT], ubi_trLEFT );
+ p = q->Link[ubi_trPARENT];
+ if( NULL != p )
+ p->Link[ ((p->Link[ubi_trLEFT] == q)?ubi_trLEFT:ubi_trRIGHT) ] = NULL;
+ (*FreeNode)((void *)q);
+ count++;
+ }
+
+ /* overkill... */
+ (void)ubi_btInitTree( RootPtr,
+ RootPtr->cmp,
+ RootPtr->flags );
+ return( count );
+ } /* ubi_btKillTree */
+
+ubi_btNodePtr ubi_btLeafNode( ubi_btNodePtr leader )
+ /* ------------------------------------------------------------------------ **
+ * Returns a pointer to a leaf node.
+ *
+ * Input: leader - Pointer to a node at which to start the descent.
+ *
+ * Output: A pointer to a leaf node, selected in a somewhat arbitrary
+ * manner but with an effort to dig deep.
+ *
+ * Notes: I wrote this function because I was using splay trees as a
+ * database cache. The cache had a maximum size on it, and I
+ * needed a way of choosing a node to sacrifice if the cache
+ * became full. In a splay tree, less recently accessed nodes
+ * tend toward the bottom of the tree, meaning that leaf nodes
+ * are good candidates for removal. (I really can't think of
+ * any other reason to use this function.)
+ * + In a simple binary tree, or in an AVL tree, the most recently
+ * added nodes tend to be nearer the bottom, making this a *bad*
+ * way to choose which node to remove from the cache.
+ * + Randomizing the traversal order is probably a good idea. You
+ * can improve the randomization of leaf node selection by passing
+ * in pointers to nodes other than the root node each time. A
+ * pointer to any node in the tree will do. Of course, if you
+ * pass a pointer to a leaf node you'll get the same thing back.
+ * + In an unbalanced splay tree, if you simply traverse downward
+ * until you hit a leaf node it is possible to accidentally
+ * stumble onto a short path. The result will be a leaf node
+ * that is actually very high in the tree--possibly a very
+ * recently accessed node. Not good. This function can follow
+ * multiple paths in an effort to find a leaf node deeper
+ * in the tree. Following a single path, of course, is the
+ * fastest way to find a leaf node. A complete traversal would
+ * be sure to find the deepest leaf but would be very costly in
+ * terms of time. This function uses a compromise that has
+ * worked well in testing.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ #define MAXPATHS 4 /* Set higher for more maximum paths, lower for fewer. */
+ ubi_trNodePtr p[MAXPATHS];
+ ubi_trNodePtr q[MAXPATHS];
+ int whichway = ubi_trLEFT;
+ int paths;
+ int i, j;
+
+ /* If the subtree is empty, return NULL.
+ */
+ if( NULL == leader )
+ return( NULL );
+
+ /* Initialize the p[] array with a pointer to the single node we've been
+ * given as a starting point.
+ */
+ p[0] = leader;
+ paths = 1;
+ while( paths > 0 )
+ {
+ for( i = 0; i < paths; i++ )
+ q[i] = p[i];
+
+ for( i = j = 0; (i < paths) && (j < MAXPATHS); i++ )
+ {
+ if( NULL != q[i]->Link[whichway] )
+ p[j++] = q[i]->Link[whichway];
+ whichway = ubi_trRevWay( whichway );
+ if( (j < MAXPATHS) && (NULL != q[i]->Link[whichway]) )
+ p[j++] = q[i]->Link[whichway];
+ }
+ paths = j;
+ }
+
+ return( q[0] );
+ } /* ubi_btLeafNode */
+
+int ubi_btModuleID( int size, char *list[] )
+ /* ------------------------------------------------------------------------ **
+ * Returns a set of strings that identify the module.
+ *
+ * Input: size - The number of elements in the array <list>.
+ * list - An array of pointers of type (char *). This array
+ * should, initially, be empty. This function will fill
+ * in the array with pointers to strings.
+ * Output: The number of elements of <list> that were used. If this value
+ * is less than <size>, the values of the remaining elements are
+ * not guaranteed.
+ *
+ * Notes: Please keep in mind that the pointers returned indicate strings
+ * stored in static memory. Don't free() them, don't write over
+ * them, etc. Just read them.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ if( size > 0 )
+ {
+ list[0] = ModuleID;
+ if( size > 1 )
+ list[1] = NULL;
+ return( 1 );
+ }
+ return( 0 );
+ } /* ubi_btModuleID */
+
+
+/* ========================================================================== */
diff --git a/source/ubiqx/ubi_BinTree.h b/source/ubiqx/ubi_BinTree.h
new file mode 100644
index 00000000000..43ca1a98716
--- /dev/null
+++ b/source/ubiqx/ubi_BinTree.h
@@ -0,0 +1,887 @@
+#ifndef UBI_BINTREE_H
+#define UBI_BINTREE_H
+/* ========================================================================== **
+ * ubi_BinTree.h
+ *
+ * Copyright (C) 1991-1998 by Christopher R. Hertel
+ *
+ * Email: crh@ubiqx.mn.org
+ * -------------------------------------------------------------------------- **
+ *
+ * This module implements a simple binary tree.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * Log: ubi_BinTree.h,v
+ * Revision 4.12 2004/06/06 04:51:56 crh
+ * Fixed a small typo in ubi_BinTree.c (leftover testing cruft).
+ * Did a small amount of formatting touchup to ubi_BinTree.h.
+ *
+ * Revision 4.11 2004/06/06 03:14:09 crh
+ * Rewrote the ubi_btLeafNode() function. It now takes several paths in an
+ * effort to find a deeper leaf node. There is a small amount of extra
+ * overhead, but it is limited.
+ *
+ * Revision 4.10 2000/06/06 20:38:40 crh
+ * In the ReplaceNode() function, the old node header was being copied
+ * to the new node header using a byte-by-byte copy. This was causing
+ * the 'insure' software testing program to report a memory leak. The
+ * fix was to do a simple assignement: *newnode = *oldnode;
+ * This quieted the (errant) memory leak reports and is probably a bit
+ * faster than the bytewise copy.
+ *
+ * Revision 4.9 2000/01/08 23:24:30 crh
+ * Clarified a variety of if( pointer ) lines, replacing them with
+ * if( NULL != pointer ). This is more correct, and I have heard
+ * of at least one (obscure?) system out there that uses a non-zero
+ * value for NULL.
+ * Also, speed improvement in Neighbor(). It was comparing pointers
+ * when it could have compared two gender values. The pointer
+ * comparison was somewhat indirect (does pointer equal the pointer
+ * of the parent of the node pointed to by pointer). Urq.
+ *
+ * Revision 4.8 1999/09/22 03:40:30 crh
+ * Modified ubi_btTraverse() and ubi_btKillTree(). They now return an
+ * unsigned long indicating the number of nodes processed. The change
+ * is subtle. An empty tree formerly returned False, and now returns
+ * zero.
+ *
+ * Revision 4.7 1998/10/21 06:15:07 crh
+ * Fixed bugs in FirstOf() and LastOf() reported by Massimo Campostrini.
+ * See function comments.
+ *
+ * Revision 4.6 1998/07/25 17:02:10 crh
+ * Added the ubi_trNewTree() macro.
+ *
+ * Revision 4.5 1998/06/04 21:29:27 crh
+ * Upper-cased defined constants (eg UBI_BINTREE_H) in some header files.
+ * This is more "standard", and is what people expect. Weird, eh?
+ *
+ * Revision 4.4 1998/06/03 17:42:46 crh
+ * Further fiddling with sys_include.h. It's now in ubi_BinTree.h which is
+ * included by all of the binary tree files.
+ *
+ * Reminder: Some of the ubi_tr* macros in ubi_BinTree.h are redefined in
+ * ubi_AVLtree.h and ubi_SplayTree.h. This allows easy swapping
+ * of tree types by simply changing a header. Unfortunately, the
+ * macro redefinitions in ubi_AVLtree.h and ubi_SplayTree.h will
+ * conflict if used together. You must either choose a single tree
+ * type, or use the underlying function calls directly. Compare
+ * the two header files for more information.
+ *
+ * Revision 4.3 1998/06/02 01:28:43 crh
+ * Changed ubi_null.h to sys_include.h to make it more generic.
+ *
+ * Revision 4.2 1998/05/20 04:32:36 crh
+ * The C file now includes ubi_null.h. See ubi_null.h for more info.
+ * Also, the balance and gender fields of the node were declared as
+ * signed char. As I understand it, at least one SunOS or Solaris
+ * compiler doesn't like "signed char". The declarations were
+ * wrong anyway, so I changed them to simple "char".
+ *
+ * Revision 4.1 1998/03/31 06:13:47 crh
+ * Thomas Aglassinger sent E'mail pointing out errors in the
+ * dereferencing of function pointers, and a missing typecast.
+ * Thanks, Thomas!
+ *
+ * Revision 4.0 1998/03/10 03:16:04 crh
+ * Added the AVL field 'balance' to the ubi_btNode structure. This means
+ * that all BinTree modules now use the same basic node structure, which
+ * greatly simplifies the AVL module.
+ * Decided that this was a big enough change to justify a new major revision
+ * number. 3.0 was an error, so we're at 4.0.
+ *
+ * Revision 2.6 1998/01/24 06:27:30 crh
+ * Added ubi_trCount() macro.
+ *
+ * Revision 2.5 1997/12/23 03:59:21 crh
+ * In this version, all constants & macros defined in the header file have
+ * the ubi_tr prefix. Also cleaned up anything that gcc complained about
+ * when run with '-pedantic -fsyntax-only -Wall'.
+ *
+ * Revision 2.4 1997/07/26 04:11:14 crh
+ * + Just to be annoying I changed ubi_TRUE and ubi_FALSE to ubi_trTRUE
+ * and ubi_trFALSE.
+ * + There is now a type ubi_trBool to go with ubi_trTRUE and ubi_trFALSE.
+ * + There used to be something called "ubi_TypeDefs.h". I got rid of it.
+ * + Added function ubi_btLeafNode().
+ *
+ * Revision 2.3 1997/06/03 05:15:27 crh
+ * Changed TRUE and FALSE to ubi_TRUE and ubi_FALSE to avoid conflicts.
+ * Also changed the interface to function InitTree(). See the comments
+ * for this function for more information.
+ *
+ * Revision 2.2 1995/10/03 22:00:40 CRH
+ * Ubisized!
+ *
+ * Revision 2.1 95/03/09 23:43:46 CRH
+ * Added the ModuleID static string and function. These modules are now
+ * self-identifying.
+ *
+ * Revision 2.0 95/02/27 22:00:33 CRH
+ * Revision 2.0 of this program includes the following changes:
+ *
+ * 1) A fix to a major typo in the RepaceNode() function.
+ * 2) The addition of the static function Border().
+ * 3) The addition of the public functions FirstOf() and LastOf(), which
+ * use Border(). These functions are used with trees that allow
+ * duplicate keys.
+ * 4) A complete rewrite of the Locate() function. Locate() now accepts
+ * a "comparison" operator.
+ * 5) Overall enhancements to both code and comments.
+ *
+ * I decided to give this a new major rev number because the interface has
+ * changed. In particular, there are two new functions, and changes to the
+ * Locate() function.
+ *
+ * Revision 1.0 93/10/15 22:55:04 CRH
+ * With this revision, I have added a set of #define's that provide a single,
+ * standard API to all existing tree modules. Until now, each of the three
+ * existing modules had a different function and typedef prefix, as follows:
+ *
+ * Module Prefix
+ * ubi_BinTree ubi_bt
+ * ubi_AVLtree ubi_avl
+ * ubi_SplayTree ubi_spt
+ *
+ * To further complicate matters, only those portions of the base module
+ * (ubi_BinTree) that were superceeded in the new module had the new names.
+ * For example, if you were using ubi_SplayTree, the locate function was
+ * called "ubi_sptLocate", but the next and previous functions remained
+ * "ubi_btNext" and "ubi_btPrev".
+ *
+ * This was not too terrible if you were familiar with the modules and knew
+ * exactly which tree model you wanted to use. If you wanted to be able to
+ * change modules (for speed comparisons, etc), things could get messy very
+ * quickly.
+ *
+ * So, I have added a set of defined names that get redefined in any of the
+ * descendant modules. To use this standardized interface in your code,
+ * simply replace all occurances of "ubi_bt", "ubi_avl", and "ubi_spt" with
+ * "ubi_tr". The "ubi_tr" names will resolve to the correct function or
+ * datatype names for the module that you are using. Just remember to
+ * include the header for that module in your program file. Because these
+ * names are handled by the preprocessor, there is no added run-time
+ * overhead.
+ *
+ * Note that the original names do still exist, and can be used if you wish
+ * to write code directly to a specific module. This should probably only be
+ * done if you are planning to implement a new descendant type, such as
+ * red/black trees. CRH
+ *
+ * V0.0 - June, 1991 - Written by Christopher R. Hertel (CRH).
+ *
+ * ========================================================================== **
+ */
+
+#include "sys_include.h" /* Global include file, used to adapt the ubiqx
+ * modules to the host environment and the project
+ * with which the modules will be used. See
+ * sys_include.h for more info.
+ */
+
+/* -------------------------------------------------------------------------- **
+ * Macros and constants.
+ *
+ * General purpose:
+ * ubi_trTRUE - Boolean TRUE.
+ * ubi_trFALSE - Boolean FALSE.
+ *
+ * Flags used in the tree header:
+ * ubi_trOVERWRITE - This flag indicates that an existing node may be
+ * overwritten by a new node with a matching key.
+ * ubi_trDUPKEY - This flag indicates that the tree allows duplicate
+ * keys. If the tree does allow duplicates, the
+ * overwrite flag is ignored.
+ *
+ * Node link array index constants: (Each node has an array of three
+ * pointers. One to the left, one to the right, and one back to the
+ * parent.)
+ * ubi_trLEFT - Left child pointer.
+ * ubi_trPARENT - Parent pointer.
+ * ubi_trRIGHT - Right child pointer.
+ * ubi_trEQUAL - Synonym for PARENT.
+ *
+ * ubi_trCompOps: These values are used in the ubi_trLocate() function.
+ * ubi_trLT - request the first instance of the greatest key less than
+ * the search key.
+ * ubi_trLE - request the first instance of the greatest key that is less
+ * than or equal to the search key.
+ * ubi_trEQ - request the first instance of key that is equal to the
+ * search key.
+ * ubi_trGE - request the first instance of a key that is greater than
+ * or equal to the search key.
+ * ubi_trGT - request the first instance of the first key that is greater
+ * than the search key.
+ * -------------------------------------------------------------------------- **
+ */
+
+#define ubi_trTRUE 0xFF
+#define ubi_trFALSE 0x00
+
+#define ubi_trOVERWRITE 0x01 /* Turn on allow overwrite */
+#define ubi_trDUPKEY 0x02 /* Turn on allow duplicate keys */
+
+/* Pointer array index constants... */
+#define ubi_trLEFT 0x00
+#define ubi_trPARENT 0x01
+#define ubi_trRIGHT 0x02
+#define ubi_trEQUAL ubi_trPARENT
+
+typedef enum {
+ ubi_trLT = 1,
+ ubi_trLE,
+ ubi_trEQ,
+ ubi_trGE,
+ ubi_trGT
+ } ubi_trCompOps;
+
+/* -------------------------------------------------------------------------- **
+ * These three macros allow simple manipulation of pointer index values (LEFT,
+ * RIGHT, and PARENT).
+ *
+ * Normalize() - converts {LEFT, PARENT, RIGHT} into {-1, 0 ,1}. C
+ * uses {negative, zero, positive} values to indicate
+ * {less than, equal to, greater than}.
+ * AbNormal() - converts {negative, zero, positive} to {LEFT, PARENT,
+ * RIGHT} (opposite of Normalize()). Note: C comparison
+ * functions, such as strcmp(), return {negative, zero,
+ * positive} values, which are not necessarily {-1, 0,
+ * 1}. This macro uses the the ubi_btSgn() function to
+ * compensate.
+ * RevWay() - converts LEFT to RIGHT and RIGHT to LEFT. PARENT (EQUAL)
+ * is left as is.
+ * -------------------------------------------------------------------------- **
+ */
+
+#define ubi_trNormalize(W) ((char)( (W) - ubi_trEQUAL ))
+#define ubi_trAbNormal(W) ((char)( ((char)ubi_btSgn( (long)(W) )) \
+ + ubi_trEQUAL ))
+#define ubi_trRevWay(W) ((char)( ubi_trEQUAL - ((W) - ubi_trEQUAL) ))
+
+/* -------------------------------------------------------------------------- **
+ * These macros allow us to quickly read the values of the OVERWRITE and
+ * DUPlicate KEY bits of the tree root flags field.
+ * -------------------------------------------------------------------------- **
+ */
+
+#define ubi_trDups_OK(A) \
+ ((ubi_trDUPKEY & ((A)->flags))?(ubi_trTRUE):(ubi_trFALSE))
+#define ubi_trOvwt_OK(A) \
+ ((ubi_trOVERWRITE & ((A)->flags))?(ubi_trTRUE):(ubi_trFALSE))
+
+/* -------------------------------------------------------------------------- **
+ * Additional Macros...
+ *
+ * ubi_trCount() - Given a pointer to a tree root, this macro returns the
+ * number of nodes currently in the tree.
+ *
+ * ubi_trNewTree() - This macro makes it easy to declare and initialize a
+ * tree header in one step. The line
+ *
+ * static ubi_trNewTree( MyTree, cmpfn, ubi_trDUPKEY );
+ *
+ * is equivalent to
+ *
+ * static ubi_trRoot MyTree[1]
+ * = {{ NULL, cmpfn, 0, ubi_trDUPKEY }};
+ *
+ * -------------------------------------------------------------------------- **
+ */
+
+#define ubi_trCount( R ) (((ubi_trRootPtr)(R))->count)
+
+#define ubi_trNewTree( N, C, F ) ubi_trRoot (N)[1] = {{ NULL, (C), 0, (F) }}
+
+/* -------------------------------------------------------------------------- **
+ * Typedefs...
+ *
+ * ubi_trBool - Your typcial true or false...
+ *
+ * Item Pointer: The ubi_btItemPtr is a generic pointer. It is used to
+ * indicate a key that is being searched for within the tree.
+ * Searching occurs whenever the ubi_trFind(), ubi_trLocate(),
+ * or ubi_trInsert() functions are called.
+ * -------------------------------------------------------------------------- **
+ */
+
+typedef unsigned char ubi_trBool;
+
+typedef void *ubi_btItemPtr; /* A pointer to key data within a node. */
+
+/* ------------------------------------------------------------------------- **
+ * Binary Tree Node Structure: This structure defines the basic elements of
+ * the tree nodes. In general you *SHOULD NOT PLAY WITH THESE FIELDS*!
+ * But, of course, I have to put the structure into this header so that
+ * you can use it as a building block.
+ *
+ * The fields are as follows:
+ * Link - an array of pointers. These pointers are manipulated by
+ * the BT routines. The pointers indicate the left and right
+ * child nodes and the parent node. By keeping track of the
+ * parent pointer, we avoid the need for recursive routines or
+ * hand-tooled stacks to keep track of our path back to the
+ * root. The use of these pointers is subject to change without
+ * notice.
+ * gender - a one-byte field indicating whether the node is the RIGHT or
+ * LEFT child of its parent. If the node is the root of the
+ * tree, gender will be PARENT.
+ * balance - only used by the AVL tree module. This field indicates
+ * the height balance at a given node. See ubi_AVLtree for
+ * details.
+ *
+ * ------------------------------------------------------------------------- **
+ */
+
+typedef struct ubi_btNodeStruct {
+ struct ubi_btNodeStruct *Link[ 3 ];
+ char gender;
+ char balance;
+ } ubi_btNode;
+
+typedef ubi_btNode *ubi_btNodePtr; /* Pointer to an ubi_btNode structure. */
+
+/* ------------------------------------------------------------------------- **
+ * The next three typedefs define standard function types used by the binary
+ * tree management routines. In particular:
+ *
+ * ubi_btCompFunc is a pointer to a comparison function. Comparison
+ * functions are passed an ubi_btItemPtr and an
+ * ubi_btNodePtr. They return a value that is (<0), 0,
+ * or (>0) to indicate that the Item is (respectively)
+ * "less than", "equal to", or "greater than" the Item
+ * contained within the node. (See ubi_btInitTree()).
+ * ubi_btActionRtn is a pointer to a function that may be called for each
+ * node visited when performing a tree traversal (see
+ * ubi_btTraverse()). The function will be passed two
+ * parameters: the first is a pointer to a node in the
+ * tree, the second is a generic pointer that may point to
+ * anything that you like.
+ * ubi_btKillNodeRtn is a pointer to a function that will deallocate the
+ * memory used by a node (see ubi_btKillTree()). Since
+ * memory management is left up to you, deallocation may
+ * mean anything that you want it to mean. Just remember
+ * that the tree *will* be destroyed and that none of the
+ * node pointers will be valid any more.
+ * ------------------------------------------------------------------------- **
+ */
+
+typedef int (*ubi_btCompFunc)( ubi_btItemPtr, ubi_btNodePtr );
+
+typedef void (*ubi_btActionRtn)( ubi_btNodePtr, void * );
+
+typedef void (*ubi_btKillNodeRtn)( ubi_btNodePtr );
+
+/* -------------------------------------------------------------------------- **
+ * Tree Root Structure: This structure gives us a convenient handle for
+ * accessing whole binary trees. The fields are:
+ * root - A pointer to the root node of the tree.
+ * count - A count of the number of nodes stored in the tree.
+ * cmp - A pointer to the comparison routine to be used when building or
+ * searching the tree.
+ * flags - A set of bit flags. Two flags are currently defined:
+ *
+ * ubi_trOVERWRITE - If set, this flag indicates that a new node should
+ * (bit 0x01) overwrite an old node if the two have identical
+ * keys (ie., the keys are equal).
+ * ubi_trDUPKEY - If set, this flag indicates that the tree is
+ * (bit 0x02) allowed to contain nodes with duplicate keys.
+ *
+ * NOTE: ubi_trInsert() tests ubi_trDUPKEY before ubi_trOVERWRITE.
+ *
+ * All of these values are set when you initialize the root structure by
+ * calling ubi_trInitTree().
+ * -------------------------------------------------------------------------- **
+ */
+
+typedef struct {
+ ubi_btNodePtr root; /* A pointer to the root node of the tree */
+ ubi_btCompFunc cmp; /* A pointer to the tree's comparison function */
+ unsigned long count; /* A count of the number of nodes in the tree */
+ char flags; /* Overwrite Y|N, Duplicate keys Y|N... */
+ } ubi_btRoot;
+
+typedef ubi_btRoot *ubi_btRootPtr; /* Pointer to an ubi_btRoot structure. */
+
+
+/* -------------------------------------------------------------------------- **
+ * Function Prototypes.
+ */
+
+long ubi_btSgn( long x );
+ /* ------------------------------------------------------------------------ **
+ * Return the sign of x; {negative,zero,positive} ==> {-1, 0, 1}.
+ *
+ * Input: x - a signed long integer value.
+ *
+ * Output: the "sign" of x, represented as follows:
+ * -1 == negative
+ * 0 == zero (no sign)
+ * 1 == positive
+ *
+ * Note: This utility is provided in order to facilitate the conversion
+ * of C comparison function return values into BinTree direction
+ * values: {LEFT, PARENT, EQUAL}. It is INCORPORATED into the
+ * AbNormal() conversion macro!
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btNodePtr ubi_btInitNode( ubi_btNodePtr NodePtr );
+ /* ------------------------------------------------------------------------ **
+ * Initialize a tree node.
+ *
+ * Input: a pointer to a ubi_btNode structure to be initialized.
+ * Output: a pointer to the initialized ubi_btNode structure (ie. the
+ * same as the input pointer).
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btRootPtr ubi_btInitTree( ubi_btRootPtr RootPtr,
+ ubi_btCompFunc CompFunc,
+ char Flags );
+ /* ------------------------------------------------------------------------ **
+ * Initialize the fields of a Tree Root header structure.
+ *
+ * Input: RootPtr - a pointer to an ubi_btRoot structure to be
+ * initialized.
+ * CompFunc - a pointer to a comparison function that will be used
+ * whenever nodes in the tree must be compared against
+ * outside values.
+ * Flags - One bytes worth of flags. Flags include
+ * ubi_trOVERWRITE and ubi_trDUPKEY. See the header
+ * file for more info.
+ *
+ * Output: a pointer to the initialized ubi_btRoot structure (ie. the
+ * same value as RootPtr).
+ *
+ * Note: The interface to this function has changed from that of
+ * previous versions. The <Flags> parameter replaces two
+ * boolean parameters that had the same basic effect.
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_trBool ubi_btInsert( ubi_btRootPtr RootPtr,
+ ubi_btNodePtr NewNode,
+ ubi_btItemPtr ItemPtr,
+ ubi_btNodePtr *OldNode );
+ /* ------------------------------------------------------------------------ **
+ * This function uses a non-recursive algorithm to add a new element to the
+ * tree.
+ *
+ * Input: RootPtr - a pointer to the ubi_btRoot structure that indicates
+ * the root of the tree to which NewNode is to be added.
+ * NewNode - a pointer to an ubi_btNode structure that is NOT
+ * part of any tree.
+ * ItemPtr - A pointer to the sort key that is stored within
+ * *NewNode. ItemPtr MUST point to information stored
+ * in *NewNode or an EXACT DUPLICATE. The key data
+ * indicated by ItemPtr is used to place the new node
+ * into the tree.
+ * OldNode - a pointer to an ubi_btNodePtr. When searching
+ * the tree, a duplicate node may be found. If
+ * duplicates are allowed, then the new node will
+ * be simply placed into the tree. If duplicates
+ * are not allowed, however, then one of two things
+ * may happen.
+ * 1) if overwritting *is not* allowed, this
+ * function will return FALSE (indicating that
+ * the new node could not be inserted), and
+ * *OldNode will point to the duplicate that is
+ * still in the tree.
+ * 2) if overwritting *is* allowed, then this
+ * function will swap **OldNode for *NewNode.
+ * In this case, *OldNode will point to the node
+ * that was removed (thus allowing you to free
+ * the node).
+ * ** If you are using overwrite mode, ALWAYS **
+ * ** check the return value of this parameter! **
+ * Note: You may pass NULL in this parameter, the
+ * function knows how to cope. If you do this,
+ * however, there will be no way to return a
+ * pointer to an old (ie. replaced) node (which is
+ * a problem if you are using overwrite mode).
+ *
+ * Output: a boolean value indicating success or failure. The function
+ * will return FALSE if the node could not be added to the tree.
+ * Such failure will only occur if duplicates are not allowed,
+ * nodes cannot be overwritten, AND a duplicate key was found
+ * within the tree.
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btNodePtr ubi_btRemove( ubi_btRootPtr RootPtr,
+ ubi_btNodePtr DeadNode );
+ /* ------------------------------------------------------------------------ **
+ * This function removes the indicated node from the tree.
+ *
+ * Input: RootPtr - A pointer to the header of the tree that contains
+ * the node to be removed.
+ * DeadNode - A pointer to the node that will be removed.
+ *
+ * Output: This function returns a pointer to the node that was removed
+ * from the tree (ie. the same as DeadNode).
+ *
+ * Note: The node MUST be in the tree indicated by RootPtr. If not,
+ * strange and evil things will happen to your trees.
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btNodePtr ubi_btLocate( ubi_btRootPtr RootPtr,
+ ubi_btItemPtr FindMe,
+ ubi_trCompOps CompOp );
+ /* ------------------------------------------------------------------------ **
+ * The purpose of ubi_btLocate() is to find a node or set of nodes given
+ * a target value and a "comparison operator". The Locate() function is
+ * more flexible and (in the case of trees that may contain dupicate keys)
+ * more precise than the ubi_btFind() function. The latter is faster,
+ * but it only searches for exact matches and, if the tree contains
+ * duplicates, Find() may return a pointer to any one of the duplicate-
+ * keyed records.
+ *
+ * Input:
+ * RootPtr - A pointer to the header of the tree to be searched.
+ * FindMe - An ubi_btItemPtr that indicates the key for which to
+ * search.
+ * CompOp - One of the following:
+ * CompOp Return a pointer to the node with
+ * ------ ---------------------------------
+ * ubi_trLT - the last key value that is less
+ * than FindMe.
+ * ubi_trLE - the first key matching FindMe, or
+ * the last key that is less than
+ * FindMe.
+ * ubi_trEQ - the first key matching FindMe.
+ * ubi_trGE - the first key matching FindMe, or the
+ * first key greater than FindMe.
+ * ubi_trGT - the first key greater than FindMe.
+ * Output:
+ * A pointer to the node matching the criteria listed above under
+ * CompOp, or NULL if no node matched the criteria.
+ *
+ * Notes:
+ * In the case of trees with duplicate keys, Locate() will behave as
+ * follows:
+ *
+ * Find: 3 Find: 3
+ * Keys: 1 2 2 2 3 3 3 3 3 4 4 Keys: 1 1 2 2 2 4 4 5 5 5 6
+ * ^ ^ ^ ^ ^
+ * LT EQ GT LE GE
+ *
+ * That is, when returning a pointer to a node with a key that is LESS
+ * THAN the target key (FindMe), Locate() will return a pointer to the
+ * LAST matching node.
+ * When returning a pointer to a node with a key that is GREATER
+ * THAN the target key (FindMe), Locate() will return a pointer to the
+ * FIRST matching node.
+ *
+ * See Also: ubi_btFind(), ubi_btFirstOf(), ubi_btLastOf().
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btNodePtr ubi_btFind( ubi_btRootPtr RootPtr,
+ ubi_btItemPtr FindMe );
+ /* ------------------------------------------------------------------------ **
+ * This function performs a non-recursive search of a tree for any node
+ * matching a specific key.
+ *
+ * Input:
+ * RootPtr - a pointer to the header of the tree to be searched.
+ * FindMe - a pointer to the key value for which to search.
+ *
+ * Output:
+ * A pointer to a node with a key that matches the key indicated by
+ * FindMe, or NULL if no such node was found.
+ *
+ * Note: In a tree that allows duplicates, the pointer returned *might
+ * not* point to the (sequentially) first occurance of the
+ * desired key. In such a tree, it may be more useful to use
+ * ubi_btLocate().
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btNodePtr ubi_btNext( ubi_btNodePtr P );
+ /* ------------------------------------------------------------------------ **
+ * Given the node indicated by P, find the (sorted order) Next node in the
+ * tree.
+ * Input: P - a pointer to a node that exists in a binary tree.
+ * Output: A pointer to the "next" node in the tree, or NULL if P pointed
+ * to the "last" node in the tree or was NULL.
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btNodePtr ubi_btPrev( ubi_btNodePtr P );
+ /* ------------------------------------------------------------------------ **
+ * Given the node indicated by P, find the (sorted order) Previous node in
+ * the tree.
+ * Input: P - a pointer to a node that exists in a binary tree.
+ * Output: A pointer to the "previous" node in the tree, or NULL if P
+ * pointed to the "first" node in the tree or was NULL.
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btNodePtr ubi_btFirst( ubi_btNodePtr P );
+ /* ------------------------------------------------------------------------ **
+ * Given the node indicated by P, find the (sorted order) First node in the
+ * subtree of which *P is the root.
+ * Input: P - a pointer to a node that exists in a binary tree.
+ * Output: A pointer to the "first" node in a subtree that has *P as its
+ * root. This function will return NULL only if P is NULL.
+ * Note: In general, you will be passing in the value of the root field
+ * of an ubi_btRoot structure.
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btNodePtr ubi_btLast( ubi_btNodePtr P );
+ /* ------------------------------------------------------------------------ **
+ * Given the node indicated by P, find the (sorted order) Last node in the
+ * subtree of which *P is the root.
+ * Input: P - a pointer to a node that exists in a binary tree.
+ * Output: A pointer to the "last" node in a subtree that has *P as its
+ * root. This function will return NULL only if P is NULL.
+ * Note: In general, you will be passing in the value of the root field
+ * of an ubi_btRoot structure.
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btNodePtr ubi_btFirstOf( ubi_btRootPtr RootPtr,
+ ubi_btItemPtr MatchMe,
+ ubi_btNodePtr p );
+ /* ------------------------------------------------------------------------ **
+ * Given a tree that a allows duplicate keys, and a pointer to a node in
+ * the tree, this function will return a pointer to the first (traversal
+ * order) node with the same key value.
+ *
+ * Input: RootPtr - A pointer to the root of the tree.
+ * MatchMe - A pointer to the key value. This should probably
+ * point to the key within node *p.
+ * p - A pointer to a node in the tree.
+ * Output: A pointer to the first node in the set of nodes with keys
+ * matching <FindMe>.
+ * Notes: Node *p MUST be in the set of nodes with keys matching
+ * <FindMe>. If not, this function will return NULL.
+ *
+ * 4.7: Bug found & fixed by Massimo Campostrini,
+ * Istituto Nazionale di Fisica Nucleare, Sezione di Pisa.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btNodePtr ubi_btLastOf( ubi_btRootPtr RootPtr,
+ ubi_btItemPtr MatchMe,
+ ubi_btNodePtr p );
+ /* ------------------------------------------------------------------------ **
+ * Given a tree that a allows duplicate keys, and a pointer to a node in
+ * the tree, this function will return a pointer to the last (traversal
+ * order) node with the same key value.
+ *
+ * Input: RootPtr - A pointer to the root of the tree.
+ * MatchMe - A pointer to the key value. This should probably
+ * point to the key within node *p.
+ * p - A pointer to a node in the tree.
+ * Output: A pointer to the last node in the set of nodes with keys
+ * matching <FindMe>.
+ * Notes: Node *p MUST be in the set of nodes with keys matching
+ * <FindMe>. If not, this function will return NULL.
+ *
+ * 4.7: Bug found & fixed by Massimo Campostrini,
+ * Istituto Nazionale di Fisica Nucleare, Sezione di Pisa.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+unsigned long ubi_btTraverse( ubi_btRootPtr RootPtr,
+ ubi_btActionRtn EachNode,
+ void *UserData );
+ /* ------------------------------------------------------------------------ **
+ * Traverse a tree in sorted order (non-recursively). At each node, call
+ * (*EachNode)(), passing a pointer to the current node, and UserData as the
+ * second parameter.
+ *
+ * Input: RootPtr - a pointer to an ubi_btRoot structure that indicates
+ * the tree to be traversed.
+ * EachNode - a pointer to a function to be called at each node
+ * as the node is visited.
+ * UserData - a generic pointer that may point to anything that
+ * you choose.
+ *
+ * Output: A count of the number of nodes visited. This will be zero
+ * if the tree is empty.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+
+unsigned long ubi_btKillTree( ubi_btRootPtr RootPtr,
+ ubi_btKillNodeRtn FreeNode );
+ /* ------------------------------------------------------------------------ **
+ * Delete an entire tree (non-recursively) and reinitialize the ubi_btRoot
+ * structure. Return a count of the number of nodes deleted.
+ *
+ * Input: RootPtr - a pointer to an ubi_btRoot structure that indicates
+ * the root of the tree to delete.
+ * FreeNode - a function that will be called for each node in the
+ * tree to deallocate the memory used by the node.
+ *
+ * Output: The number of nodes removed from the tree.
+ * A value of 0 will be returned if:
+ * - The tree actually contains 0 entries.
+ * - the value of <RootPtr> is NULL, in which case the tree is
+ * assumed to be empty
+ * - the value of <FreeNode> is NULL, in which case entries
+ * cannot be removed, so 0 is returned. *Make sure that you
+ * provide a valid value for <FreeNode>*.
+ * In all other cases, you should get a positive value equal to
+ * the value of RootPtr->count upon entry.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btNodePtr ubi_btLeafNode( ubi_btNodePtr leader );
+ /* ------------------------------------------------------------------------ **
+ * Returns a pointer to a leaf node.
+ *
+ * Input: leader - Pointer to a node at which to start the descent.
+ *
+ * Output: A pointer to a leaf node, selected in a somewhat arbitrary
+ * manner but with an effort to dig deep.
+ *
+ * Notes: I wrote this function because I was using splay trees as a
+ * database cache. The cache had a maximum size on it, and I
+ * needed a way of choosing a node to sacrifice if the cache
+ * became full. In a splay tree, less recently accessed nodes
+ * tend toward the bottom of the tree, meaning that leaf nodes
+ * are good candidates for removal. (I really can't think of
+ * any other reason to use this function.)
+ * + In a simple binary tree, or in an AVL tree, the most recently
+ * added nodes tend to be nearer the bottom, making this a *bad*
+ * way to choose which node to remove from the cache.
+ * + Randomizing the traversal order is probably a good idea. You
+ * can improve the randomization of leaf node selection by passing
+ * in pointers to nodes other than the root node each time. A
+ * pointer to any node in the tree will do. Of course, if you
+ * pass a pointer to a leaf node you'll get the same thing back.
+ * + In an unbalanced splay tree, if you simply traverse downward
+ * until you hit a leaf node it is possible to accidentally
+ * stumble onto a short path. The result will be a leaf node
+ * that is actually very high in the tree--possibly a very
+ * recently accessed node. Not good. This function can follow
+ * multiple paths in an effort to find a leaf node deeper
+ * in the tree. Following a single path, of course, is the
+ * fastest way to find a leaf node. A complete traversal would
+ * be sure to find the deepest leaf but would be very costly in
+ * terms of time. This function uses a compromise that has
+ * worked well in testing.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+
+int ubi_btModuleID( int size, char *list[] );
+ /* ------------------------------------------------------------------------ **
+ * Returns a set of strings that identify the module.
+ *
+ * Input: size - The number of elements in the array <list>.
+ * list - An array of pointers of type (char *). This array
+ * should, initially, be empty. This function will fill
+ * in the array with pointers to strings.
+ * Output: The number of elements of <list> that were used. If this value
+ * is less than <size>, the values of the remaining elements are
+ * not guaranteed.
+ *
+ * Notes: Please keep in mind that the pointers returned indicate strings
+ * stored in static memory. Don't free() them, don't write over
+ * them, etc. Just read them.
+ * ------------------------------------------------------------------------ **
+ */
+
+/* -------------------------------------------------------------------------- **
+ * Masquarade...
+ *
+ * This set of defines allows you to write programs that will use any of the
+ * implemented binary tree modules (currently BinTree, AVLtree, and SplayTree).
+ * Instead of using ubi_bt..., use ubi_tr..., and select the tree type by
+ * including the appropriate module header.
+ */
+
+#define ubi_trItemPtr ubi_btItemPtr
+
+#define ubi_trNode ubi_btNode
+#define ubi_trNodePtr ubi_btNodePtr
+
+#define ubi_trRoot ubi_btRoot
+#define ubi_trRootPtr ubi_btRootPtr
+
+#define ubi_trCompFunc ubi_btCompFunc
+#define ubi_trActionRtn ubi_btActionRtn
+#define ubi_trKillNodeRtn ubi_btKillNodeRtn
+
+#define ubi_trSgn( x ) ubi_btSgn( x )
+
+#define ubi_trInitNode( Np ) ubi_btInitNode( (ubi_btNodePtr)(Np) )
+
+#define ubi_trInitTree( Rp, Cf, Fl ) \
+ ubi_btInitTree( (ubi_btRootPtr)(Rp), (ubi_btCompFunc)(Cf), (Fl) )
+
+#define ubi_trInsert( Rp, Nn, Ip, On ) \
+ ubi_btInsert( (ubi_btRootPtr)(Rp), (ubi_btNodePtr)(Nn), \
+ (ubi_btItemPtr)(Ip), (ubi_btNodePtr *)(On) )
+
+#define ubi_trRemove( Rp, Dn ) \
+ ubi_btRemove( (ubi_btRootPtr)(Rp), (ubi_btNodePtr)(Dn) )
+
+#define ubi_trLocate( Rp, Ip, Op ) \
+ ubi_btLocate( (ubi_btRootPtr)(Rp), \
+ (ubi_btItemPtr)(Ip), \
+ (ubi_trCompOps)(Op) )
+
+#define ubi_trFind( Rp, Ip ) \
+ ubi_btFind( (ubi_btRootPtr)(Rp), (ubi_btItemPtr)(Ip) )
+
+#define ubi_trNext( P ) ubi_btNext( (ubi_btNodePtr)(P) )
+
+#define ubi_trPrev( P ) ubi_btPrev( (ubi_btNodePtr)(P) )
+
+#define ubi_trFirst( P ) ubi_btFirst( (ubi_btNodePtr)(P) )
+
+#define ubi_trLast( P ) ubi_btLast( (ubi_btNodePtr)(P) )
+
+#define ubi_trFirstOf( Rp, Ip, P ) \
+ ubi_btFirstOf( (ubi_btRootPtr)(Rp), \
+ (ubi_btItemPtr)(Ip), \
+ (ubi_btNodePtr)(P) )
+
+#define ubi_trLastOf( Rp, Ip, P ) \
+ ubi_btLastOf( (ubi_btRootPtr)(Rp), \
+ (ubi_btItemPtr)(Ip), \
+ (ubi_btNodePtr)(P) )
+
+#define ubi_trTraverse( Rp, En, Ud ) \
+ ubi_btTraverse((ubi_btRootPtr)(Rp), (ubi_btActionRtn)(En), (void *)(Ud))
+
+#define ubi_trKillTree( Rp, Fn ) \
+ ubi_btKillTree( (ubi_btRootPtr)(Rp), (ubi_btKillNodeRtn)(Fn) )
+
+#define ubi_trLeafNode( Nd ) \
+ ubi_btLeafNode( (ubi_btNodePtr)(Nd) )
+
+#define ubi_trModuleID( s, l ) ubi_btModuleID( s, l )
+
+/* ========================================================================== */
+#endif /* UBI_BINTREE_H */
diff --git a/source/ubiqx/ubi_Cache.c b/source/ubiqx/ubi_Cache.c
new file mode 100644
index 00000000000..f428dcefe97
--- /dev/null
+++ b/source/ubiqx/ubi_Cache.c
@@ -0,0 +1,505 @@
+/* ========================================================================== **
+ * ubi_Cache.c
+ *
+ * Copyright (C) 1997 by Christopher R. Hertel
+ *
+ * Email: crh@ubiqx.mn.org
+ * -------------------------------------------------------------------------- **
+ *
+ * This module implements a generic cache.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * This module uses a splay tree to implement a simple cache. The cache
+ * module adds a thin layer of functionality to the splay tree. In
+ * particular:
+ *
+ * - The tree (cache) may be limited in size by the number of
+ * entries permitted or the amount of memory used. When either
+ * limit is exceeded cache entries are removed until the cache
+ * conforms.
+ * - Some statistical information is kept so that an approximate
+ * "hit ratio" can be calculated.
+ * - There are several functions available that provide access to
+ * and management of cache size limits, hit ratio, and tree
+ * trimming.
+ *
+ * The splay tree is used because recently accessed items tend toward the
+ * top of the tree and less recently accessed items tend toward the bottom.
+ * This makes it easy to purge less recently used items should the cache
+ * exceed its limits.
+ *
+ * To use this module, you will need to supply a comparison function of
+ * type ubi_trCompFunc and a node-freeing function of type
+ * ubi_trKillNodeRtn. See ubi_BinTree.h for more information on
+ * these. (This is all basic ubiqx tree management stuff.)
+ *
+ * Notes:
+ *
+ * - Cache performance will start to suffer dramatically if the
+ * cache becomes large enough to force the OS to start swapping
+ * memory to disk. This is because the nodes of the underlying tree
+ * will be scattered across memory in an order that is completely
+ * unrelated to their traversal order. As more and more of the
+ * cache is placed into swap space, more and more swaps will be
+ * required for a simple traversal (...and then there's the splay
+ * operation).
+ *
+ * In one simple test under Linux, the load and dump of a cache of
+ * 400,000 entries took only 1min, 40sec of real time. The same
+ * test with 450,000 records took 2 *hours* and eight minutes.
+ *
+ * - In an effort to save memory, I considered using an unsigned
+ * short to save the per-entry entry size. I would have tucked this
+ * value into some unused space in the tree node structure. On
+ * 32-bit word aligned systems this would have saved an additional
+ * four bytes per entry. I may revisit this issue, but for now I've
+ * decided against it.
+ *
+ * Using an unsigned short would limit the size of an entry to 64K
+ * bytes. That's probably more than enough for most applications.
+ * The key word in that last sentence, however, is "probably". I
+ * really dislike imposing such limits on things.
+ *
+ * - Each entry keeps track of the amount of memory it used and the
+ * cache header keeps the total. This information is provided via
+ * the EntrySize parameter in ubi_cachePut(), so it is up to you to
+ * make sure that the numbers are accurate. (The numbers don't even
+ * have to represent bytes used.)
+ *
+ * As you consider this, note that the strdup() function--as an
+ * example--will call malloc(). The latter generally allocates a
+ * multiple of the system word size, which may be more than the
+ * number of bytes needed to store the string.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * Log: ubi_Cache.c,v
+ * Revision 0.4 1999/09/22 03:42:24 crh
+ * Fixed a minor typo.
+ *
+ * Revision 0.3 1998/06/03 18:00:15 crh
+ * Further fiddling with sys_include.h, which is no longer explicitly
+ * included by this module since it is inherited from ubi_BinTree.h.
+ *
+ * Revision 0.2 1998/06/02 01:36:18 crh
+ * Changed include name from ubi_null.h to sys_include.h to make it
+ * more generic.
+ *
+ * Revision 0.1 1998/05/20 04:36:02 crh
+ * The C file now includes ubi_null.h. See ubi_null.h for more info.
+ *
+ * Revision 0.0 1997/12/18 06:24:33 crh
+ * Initial Revision.
+ *
+ * ========================================================================== **
+ */
+
+#include "ubi_Cache.h" /* Header for *this* module. */
+
+/* -------------------------------------------------------------------------- **
+ * Static data...
+ */
+
+/* commented out until I make use of it...
+static char ModuleID[] =
+"ubi_Cache\n\
+\tRevision: 0.4 \n\
+\tDate: 1999/09/22 03:42:24 \n\
+\tAuthor: crh \n";
+*/
+
+/* -------------------------------------------------------------------------- **
+ * Internal functions...
+ */
+
+static void free_entry( ubi_cacheRootPtr CachePtr, ubi_cacheEntryPtr EntryPtr )
+ /* ------------------------------------------------------------------------ **
+ * Free a ubi_cacheEntry, and adjust the mem_used counter accordingly.
+ *
+ * Input: CachePtr - A pointer to the cache from which the entry has
+ * been removed.
+ * EntryPtr - A pointer to the already removed entry.
+ *
+ * Output: none.
+ *
+ * Notes: The entry must be removed from the cache *before* this function
+ * is called!!!!
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ CachePtr->mem_used -= EntryPtr->entry_size;
+ (*CachePtr->free_func)( (void *)EntryPtr );
+ } /* free_entry */
+
+static void cachetrim( ubi_cacheRootPtr crptr )
+ /* ------------------------------------------------------------------------ **
+ * Remove entries from the cache until the number of entries and the amount
+ * of memory used are *both* below or at the maximum.
+ *
+ * Input: crptr - pointer to the cache to be trimmed.
+ *
+ * Output: None.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ while( ( crptr->max_entries && (crptr->max_entries < crptr->root.count) )
+ || ( crptr->max_memory && (crptr->max_memory < crptr->mem_used) ) )
+ {
+ if( !ubi_cacheReduce( crptr, 1 ) )
+ return;
+ }
+ } /* cachetrim */
+
+
+/* -------------------------------------------------------------------------- **
+ * Exported functions...
+ */
+
+ubi_cacheRootPtr ubi_cacheInit( ubi_cacheRootPtr CachePtr,
+ ubi_trCompFunc CompFunc,
+ ubi_trKillNodeRtn FreeFunc,
+ unsigned long MaxEntries,
+ unsigned long MaxMemory )
+ /* ------------------------------------------------------------------------ **
+ * Initialize a cache header structure.
+ *
+ * Input: CachePtr - A pointer to a ubi_cacheRoot structure that is
+ * to be initialized.
+ * CompFunc - A pointer to the function that will be called
+ * to compare two cache values. See the module
+ * comments, above, for more information.
+ * FreeFunc - A pointer to a function that will be called
+ * to free a cache entry. If you allocated
+ * the cache entry using malloc(), then this
+ * will likely be free(). If you are allocating
+ * cache entries from a free list, then this will
+ * likely be a function that returns memory to the
+ * free list, etc.
+ * MaxEntries - The maximum number of entries that will be
+ * allowed to exist in the cache. If this limit
+ * is exceeded, then existing entries will be
+ * removed from the cache. A value of zero
+ * indicates that there is no limit on the number
+ * of cache entries. See ubi_cachePut().
+ * MaxMemory - The maximum amount of memory, in bytes, to be
+ * allocated to the cache (excluding the cache
+ * header). If this is exceeded, existing entries
+ * in the cache will be removed until enough memory
+ * has been freed to meet the condition. See
+ * ubi_cachePut().
+ *
+ * Output: A pointer to the initialized cache (i.e., the same as CachePtr).
+ *
+ * Notes: Both MaxEntries and MaxMemory may be changed after the cache
+ * has been created. See
+ * ubi_cacheSetMaxEntries()
+ * ubi_cacheSetMaxMemory()
+ * ubi_cacheGetMaxEntries()
+ * ubi_cacheGetMaxMemory() (the latter two are macros).
+ *
+ * - Memory is allocated in multiples of the word size. The
+ * return value of the strlen() function does not reflect
+ * this; it will allways be less than or equal to the amount
+ * of memory actually allocated. Keep this in mind when
+ * choosing a value for MaxMemory.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ if( CachePtr )
+ {
+ (void)ubi_trInitTree( CachePtr, CompFunc, ubi_trOVERWRITE );
+ CachePtr->free_func = FreeFunc;
+ CachePtr->max_entries = MaxEntries;
+ CachePtr->max_memory = MaxMemory;
+ CachePtr->mem_used = 0;
+ CachePtr->cache_hits = 0;
+ CachePtr->cache_trys = 0;
+ }
+ return( CachePtr );
+ } /* ubi_cacheInit */
+
+ubi_cacheRootPtr ubi_cacheClear( ubi_cacheRootPtr CachePtr )
+ /* ------------------------------------------------------------------------ **
+ * Remove and free all entries in an existing cache.
+ *
+ * Input: CachePtr - A pointer to the cache that is to be cleared.
+ *
+ * Output: A pointer to the cache header (i.e., the same as CachePtr).
+ * This function re-initializes the cache header.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ if( CachePtr )
+ {
+ (void)ubi_trKillTree( CachePtr, CachePtr->free_func );
+ CachePtr->mem_used = 0;
+ CachePtr->cache_hits = 0;
+ CachePtr->cache_trys = 0;
+ }
+ return( CachePtr );
+ } /* ubi_cacheClear */
+
+void ubi_cachePut( ubi_cacheRootPtr CachePtr,
+ unsigned long EntrySize,
+ ubi_cacheEntryPtr EntryPtr,
+ ubi_trItemPtr Key )
+ /* ------------------------------------------------------------------------ **
+ * Add an entry to the cache.
+ *
+ * Input: CachePtr - A pointer to the cache into which the entry
+ * will be added.
+ * EntrySize - The size, in bytes, of the memory block indicated
+ * by EntryPtr. This will be copied into the
+ * EntryPtr->entry_size field.
+ * EntryPtr - A pointer to a memory block that begins with a
+ * ubi_cacheEntry structure. The entry structure
+ * should be followed immediately by the data to be
+ * cached (even if that is a pointer to yet more data).
+ * Key - Pointer used to identify the lookup key within the
+ * Entry.
+ *
+ * Output: None.
+ *
+ * Notes: After adding the new node, the cache is "trimmed". This
+ * removes extra nodes if the tree has exceeded it's memory or
+ * entry count limits. It is unlikely that the newly added node
+ * will be purged from the cache (assuming a reasonably large
+ * cache), since new nodes in a splay tree (which is what this
+ * module was designed to use) are moved to the top of the tree
+ * and the cache purge process removes nodes from the bottom of
+ * the tree.
+ * - The underlying splay tree is opened in OVERWRITE mode. If
+ * the input key matches an existing key, the existing entry will
+ * be politely removed from the tree and freed.
+ * - Memory is allocated in multiples of the word size. The
+ * return value of the strlen() function does not reflect
+ * this; it will allways be less than or equal to the amount
+ * of memory actually allocated.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_trNodePtr OldNode;
+
+ EntryPtr->entry_size = EntrySize;
+ CachePtr->mem_used += EntrySize;
+ (void)ubi_trInsert( CachePtr, EntryPtr, Key, &OldNode );
+ if( OldNode )
+ free_entry( CachePtr, (ubi_cacheEntryPtr)OldNode );
+
+ cachetrim( CachePtr );
+ } /* ubi_cachePut */
+
+ubi_cacheEntryPtr ubi_cacheGet( ubi_cacheRootPtr CachePtr,
+ ubi_trItemPtr FindMe )
+ /* ------------------------------------------------------------------------ **
+ * Attempt to retrieve an entry from the cache.
+ *
+ * Input: CachePtr - A ponter to the cache that is to be searched.
+ * FindMe - A ubi_trItemPtr that indicates the key for which
+ * to search.
+ *
+ * Output: A pointer to the cache entry that was found, or NULL if no
+ * matching entry was found.
+ *
+ * Notes: This function also updates the hit ratio counters.
+ * The counters are unsigned short. If the number of cache tries
+ * reaches 32768, then both the number of tries and the number of
+ * hits are divided by two. This prevents the counters from
+ * overflowing. See the comments in ubi_cacheHitRatio() for
+ * additional notes.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_trNodePtr FoundPtr;
+
+ FoundPtr = ubi_trFind( CachePtr, FindMe );
+
+ if( FoundPtr )
+ CachePtr->cache_hits++;
+ CachePtr->cache_trys++;
+
+ if( CachePtr->cache_trys & 0x8000 )
+ {
+ CachePtr->cache_hits = CachePtr->cache_hits / 2;
+ CachePtr->cache_trys = CachePtr->cache_trys / 2;
+ }
+
+ return( (ubi_cacheEntryPtr)FoundPtr );
+ } /* ubi_cacheGet */
+
+ubi_trBool ubi_cacheDelete( ubi_cacheRootPtr CachePtr, ubi_trItemPtr DeleteMe )
+ /* ------------------------------------------------------------------------ **
+ * Find and delete the specified cache entry.
+ *
+ * Input: CachePtr - A pointer to the cache.
+ * DeleteMe - The key of the entry to be deleted.
+ *
+ * Output: TRUE if the entry was found & freed, else FALSE.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_trNodePtr FoundPtr;
+
+ FoundPtr = ubi_trFind( CachePtr, DeleteMe );
+ if( FoundPtr )
+ {
+ (void)ubi_trRemove( CachePtr, FoundPtr );
+ free_entry( CachePtr, (ubi_cacheEntryPtr)FoundPtr );
+ return( ubi_trTRUE );
+ }
+ return( ubi_trFALSE );
+ } /* ubi_cacheDelete */
+
+ubi_trBool ubi_cacheReduce( ubi_cacheRootPtr CachePtr, unsigned long count )
+ /* ------------------------------------------------------------------------ **
+ * Remove <count> entries from the bottom of the cache.
+ *
+ * Input: CachePtr - A pointer to the cache which is to be reduced in
+ * size.
+ * count - The number of entries to remove.
+ *
+ * Output: The function will return TRUE if <count> entries were removed,
+ * else FALSE. A return value of FALSE should indicate that
+ * there were less than <count> entries in the cache, and that the
+ * cache is now empty.
+ *
+ * Notes: This function forces a reduction in the number of cache entries
+ * without requiring that the MaxMemory or MaxEntries values be
+ * changed.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_trNodePtr NodePtr;
+
+ while( count )
+ {
+ NodePtr = ubi_trLeafNode( CachePtr->root.root );
+ if( NULL == NodePtr )
+ return( ubi_trFALSE );
+ else
+ {
+ (void)ubi_trRemove( CachePtr, NodePtr );
+ free_entry( CachePtr, (ubi_cacheEntryPtr)NodePtr );
+ }
+ count--;
+ }
+ return( ubi_trTRUE );
+ } /* ubi_cacheReduce */
+
+unsigned long ubi_cacheSetMaxEntries( ubi_cacheRootPtr CachePtr,
+ unsigned long NewSize )
+ /* ------------------------------------------------------------------------ **
+ * Change the maximum number of entries allowed to exist in the cache.
+ *
+ * Input: CachePtr - A pointer to the cache to be modified.
+ * NewSize - The new maximum number of cache entries.
+ *
+ * Output: The maximum number of entries previously allowed to exist in
+ * the cache.
+ *
+ * Notes: If the new size is less than the old size, this function will
+ * trim the cache (remove excess entries).
+ * - A value of zero indicates an unlimited number of entries.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ unsigned long oldsize = CachePtr->max_entries; /* Save the old value. */
+
+ CachePtr->max_entries = NewSize; /* Apply the new value. */
+ if( (NewSize < oldsize) || (NewSize && !oldsize) ) /* If size is smaller, */
+ cachetrim( CachePtr ); /* remove excess. */
+ return( oldsize );
+ } /* ubi_cacheSetMaxEntries */
+
+unsigned long ubi_cacheSetMaxMemory( ubi_cacheRootPtr CachePtr,
+ unsigned long NewSize )
+ /* ------------------------------------------------------------------------ **
+ * Change the maximum amount of memory to be used for storing cache
+ * entries.
+ *
+ * Input: CachePtr - A pointer to the cache to be modified.
+ * NewSize - The new cache memory size.
+ *
+ * Output: The previous maximum memory size.
+ *
+ * Notes: If the new size is less than the old size, this function will
+ * trim the cache (remove excess entries).
+ * - A value of zero indicates that the cache has no memory limit.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ unsigned long oldsize = CachePtr->max_memory; /* Save the old value. */
+
+ CachePtr->max_memory = NewSize; /* Apply the new value. */
+ if( (NewSize < oldsize) || (NewSize && !oldsize) ) /* If size is smaller, */
+ cachetrim( CachePtr ); /* remove excess. */
+ return( oldsize );
+ } /* ubi_cacheSetMaxMemory */
+
+int ubi_cacheHitRatio( ubi_cacheRootPtr CachePtr )
+ /* ------------------------------------------------------------------------ **
+ * Returns a value that is 10,000 times the slightly weighted average hit
+ * ratio for the cache.
+ *
+ * Input: CachePtr - Pointer to the cache to be queried.
+ *
+ * Output: An integer that is 10,000 times the number of successful
+ * cache hits divided by the number of cache lookups, or:
+ * (10000 * hits) / trys
+ * You can easily convert this to a float, or do something
+ * like this (where i is the return value of this function):
+ *
+ * printf( "Hit rate : %d.%02d%%\n", (i/100), (i%100) );
+ *
+ * Notes: I say "slightly-weighted", because the numerator and
+ * denominator are both accumulated in locations of type
+ * 'unsigned short'. If the number of cache trys becomes
+ * large enough, both are divided by two. (See function
+ * ubi_cacheGet().)
+ * Dividing both numerator and denominator by two does not
+ * change the ratio (much...it is an integer divide), but it
+ * does mean that subsequent increments to either counter will
+ * have twice as much significance as previous ones.
+ *
+ * - The value returned by this function will be in the range
+ * [0..10000] because ( 0 <= cache_hits <= cache_trys ) will
+ * always be true.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ int tmp = 0;
+
+ if( CachePtr->cache_trys )
+ tmp = (int)( (10000 * (long)(CachePtr->cache_hits) )
+ / (long)(CachePtr->cache_trys) );
+ return( tmp );
+ } /* ubi_cacheHitRatio */
+
+/* -------------------------------------------------------------------------- */
diff --git a/source/ubiqx/ubi_Cache.h b/source/ubiqx/ubi_Cache.h
new file mode 100644
index 00000000000..0fc3a074f72
--- /dev/null
+++ b/source/ubiqx/ubi_Cache.h
@@ -0,0 +1,412 @@
+#ifndef UBI_CACHE_H
+#define UBI_CACHE_H
+/* ========================================================================== **
+ * ubi_Cache.h
+ *
+ * Copyright (C) 1997 by Christopher R. Hertel
+ *
+ * Email: crh@ubiqx.mn.org
+ * -------------------------------------------------------------------------- **
+ *
+ * This module implements a generic cache.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * This module uses a splay tree to implement a simple cache. The cache
+ * module adds a thin layer of functionality to the splay tree. In
+ * particular:
+ *
+ * - The tree (cache) may be limited in size by the number of
+ * entries permitted or the amount of memory used. When either
+ * limit is exceeded cache entries are removed until the cache
+ * conforms.
+ * - Some statistical information is kept so that an approximate
+ * "hit ratio" can be calculated.
+ * - There are several functions available that provide access to
+ * and management of cache size limits, hit ratio, and tree
+ * trimming.
+ *
+ * The splay tree is used because recently accessed items tend toward the
+ * top of the tree and less recently accessed items tend toward the bottom.
+ * This makes it easy to purge less recently used items should the cache
+ * exceed its limits.
+ *
+ * To use this module, you will need to supply a comparison function of
+ * type ubi_trCompFunc and a node-freeing function of type
+ * ubi_trKillNodeRtn. See ubi_BinTree.h for more information on
+ * these. (This is all basic ubiqx tree management stuff.)
+ *
+ * Notes:
+ *
+ * - Cache performance will start to suffer dramatically if the
+ * cache becomes large enough to force the OS to start swapping
+ * memory to disk. This is because the nodes of the underlying tree
+ * will be scattered across memory in an order that is completely
+ * unrelated to their traversal order. As more and more of the
+ * cache is placed into swap space, more and more swaps will be
+ * required for a simple traversal (...and then there's the splay
+ * operation).
+ *
+ * In one simple test under Linux, the load and dump of a cache of
+ * 400,000 entries took only 1min, 40sec of real time. The same
+ * test with 450,000 records took 2 *hours* and eight minutes.
+ *
+ * - In an effort to save memory, I considered using an unsigned
+ * short to save the per-entry entry size. I would have tucked this
+ * value into some unused space in the tree node structure. On
+ * 32-bit word aligned systems this would have saved an additional
+ * four bytes per entry. I may revisit this issue, but for now I've
+ * decided against it.
+ *
+ * Using an unsigned short would limit the size of an entry to 64K
+ * bytes. That's probably more than enough for most applications.
+ * The key word in that last sentence, however, is "probably". I
+ * really dislike imposing such limits on things.
+ *
+ * - Each entry keeps track of the amount of memory it used and the
+ * cache header keeps the total. This information is provided via
+ * the EntrySize parameter in ubi_cachePut(), so it is up to you to
+ * make sure that the numbers are accurate. (The numbers don't even
+ * have to represent bytes used.)
+ *
+ * As you consider this, note that the strdup() function--as an
+ * example--will call malloc(). The latter generally allocates a
+ * multiple of the system word size, which may be more than the
+ * number of bytes needed to store the string.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * Log: ubi_Cache.h,v
+ * Revision 0.4 1999/09/22 03:42:24 crh
+ * Fixed a minor typo.
+ *
+ * Revision 0.3 1998/06/03 18:00:15 crh
+ * Further fiddling with sys_include.h, which is no longer explicitly
+ * included by this module since it is inherited from ubi_BinTree.h.
+ *
+ * Revision 0.2 1998/06/02 01:36:18 crh
+ * Changed include name from ubi_null.h to sys_include.h to make it
+ * more generic.
+ *
+ * Revision 0.1 1998/05/20 04:36:02 crh
+ * The C file now includes ubi_null.h. See ubi_null.h for more info.
+ *
+ * Revision 0.0 1997/12/18 06:25:23 crh
+ * Initial Revision.
+ *
+ * ========================================================================== **
+ */
+
+#include "ubi_SplayTree.h"
+
+/* -------------------------------------------------------------------------- **
+ * Typedefs...
+ *
+ * ubi_cacheRoot - Cache header structure, which consists of a binary
+ * tree root and other required housekeeping fields, as
+ * listed below.
+ * ubi_cacheRootPtr - Pointer to a Cache.
+ *
+ * ubi_cacheEntry - A cache Entry, which consists of a tree node
+ * structure and the size (in bytes) of the entry
+ * data. The entry size should be supplied via
+ * the EntrySize parameter of the ubi_cachePut()
+ * function.
+ *
+ * ubi_cacheEntryPtr - Pointer to a ubi_cacheEntry.
+ *
+ */
+
+typedef struct
+ {
+ ubi_trRoot root; /* Splay tree control structure. */
+ ubi_trKillNodeRtn free_func; /* Function used to free entries. */
+ unsigned long max_entries; /* Max cache entries. 0 == unlimited */
+ unsigned long max_memory; /* Max memory to use. 0 == unlimited */
+ unsigned long mem_used; /* Memory currently in use (bytes). */
+ unsigned short cache_hits; /* Incremented on succesful find. */
+ unsigned short cache_trys; /* Incremented on cache lookup. */
+ } ubi_cacheRoot;
+
+typedef ubi_cacheRoot *ubi_cacheRootPtr;
+
+
+typedef struct
+ {
+ ubi_trNode node; /* Tree node structure. */
+ unsigned long entry_size; /* Entry size. Used when managing
+ * caches with maximum memory limits.
+ */
+ } ubi_cacheEntry;
+
+typedef ubi_cacheEntry *ubi_cacheEntryPtr;
+
+
+/* -------------------------------------------------------------------------- **
+ * Macros...
+ *
+ * ubi_cacheGetMaxEntries() - Report the current maximum number of entries
+ * allowed in the cache. Zero indicates no
+ * maximum.
+ * ubi_cacheGetMaxMemory() - Report the current maximum amount of memory
+ * that may be used in the cache. Zero
+ * indicates no maximum.
+ * ubi_cacheGetEntryCount() - Report the current number of entries in the
+ * cache.
+ * ubi_cacheGetMemUsed() - Report the amount of memory currently in use
+ * by the cache.
+ */
+
+#define ubi_cacheGetMaxEntries( Cptr ) (((ubi_cacheRootPtr)(Cptr))->max_entries)
+#define ubi_cacheGetMaxMemory( Cptr ) (((ubi_cacheRootPtr)(Cptr))->max_memory)
+
+#define ubi_cacheGetEntryCount( Cptr ) (((ubi_cacheRootPtr)(Cptr))->root.count)
+#define ubi_cacheGetMemUsed( Cptr ) (((ubi_cacheRootPtr)(Cptr))->mem_used)
+
+/* -------------------------------------------------------------------------- **
+ * Prototypes...
+ */
+
+ubi_cacheRootPtr ubi_cacheInit( ubi_cacheRootPtr CachePtr,
+ ubi_trCompFunc CompFunc,
+ ubi_trKillNodeRtn FreeFunc,
+ unsigned long MaxEntries,
+ unsigned long MaxMemory );
+ /* ------------------------------------------------------------------------ **
+ * Initialize a cache header structure.
+ *
+ * Input: CachePtr - A pointer to a ubi_cacheRoot structure that is
+ * to be initialized.
+ * CompFunc - A pointer to the function that will be called
+ * to compare two cache values. See the module
+ * comments, above, for more information.
+ * FreeFunc - A pointer to a function that will be called
+ * to free a cache entry. If you allocated
+ * the cache entry using malloc(), then this
+ * will likely be free(). If you are allocating
+ * cache entries from a free list, then this will
+ * likely be a function that returns memory to the
+ * free list, etc.
+ * MaxEntries - The maximum number of entries that will be
+ * allowed to exist in the cache. If this limit
+ * is exceeded, then existing entries will be
+ * removed from the cache. A value of zero
+ * indicates that there is no limit on the number
+ * of cache entries. See ubi_cachePut().
+ * MaxMemory - The maximum amount of memory, in bytes, to be
+ * allocated to the cache (excluding the cache
+ * header). If this is exceeded, existing entries
+ * in the cache will be removed until enough memory
+ * has been freed to meet the condition. See
+ * ubi_cachePut().
+ *
+ * Output: A pointer to the initialized cache (i.e., the same as CachePtr).
+ *
+ * Notes: Both MaxEntries and MaxMemory may be changed after the cache
+ * has been created. See
+ * ubi_cacheSetMaxEntries()
+ * ubi_cacheSetMaxMemory()
+ * ubi_cacheGetMaxEntries()
+ * ubi_cacheGetMaxMemory() (the latter two are macros).
+ *
+ * - Memory is allocated in multiples of the word size. The
+ * return value of the strlen() function does not reflect
+ * this; it will allways be less than or equal to the amount
+ * of memory actually allocated. Keep this in mind when
+ * choosing a value for MaxMemory.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_cacheRootPtr ubi_cacheClear( ubi_cacheRootPtr CachePtr );
+ /* ------------------------------------------------------------------------ **
+ * Remove and free all entries in an existing cache.
+ *
+ * Input: CachePtr - A pointer to the cache that is to be cleared.
+ *
+ * Output: A pointer to the cache header (i.e., the same as CachePtr).
+ * This function re-initializes the cache header.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+void ubi_cachePut( ubi_cacheRootPtr CachePtr,
+ unsigned long EntrySize,
+ ubi_cacheEntryPtr EntryPtr,
+ ubi_trItemPtr Key );
+ /* ------------------------------------------------------------------------ **
+ * Add an entry to the cache.
+ *
+ * Input: CachePtr - A pointer to the cache into which the entry
+ * will be added.
+ * EntrySize - The size, in bytes, of the memory block indicated
+ * by EntryPtr. This will be copied into the
+ * EntryPtr->entry_size field.
+ * EntryPtr - A pointer to a memory block that begins with a
+ * ubi_cacheEntry structure. The entry structure
+ * should be followed immediately by the data to be
+ * cached (even if that is a pointer to yet more data).
+ * Key - Pointer used to identify the lookup key within the
+ * Entry.
+ *
+ * Output: None.
+ *
+ * Notes: After adding the new node, the cache is "trimmed". This
+ * removes extra nodes if the tree has exceeded it's memory or
+ * entry count limits. It is unlikely that the newly added node
+ * will be purged from the cache (assuming a reasonably large
+ * cache), since new nodes in a splay tree (which is what this
+ * module was designed to use) are moved to the top of the tree
+ * and the cache purge process removes nodes from the bottom of
+ * the tree.
+ * - The underlying splay tree is opened in OVERWRITE mode. If
+ * the input key matches an existing key, the existing entry will
+ * be politely removed from the tree and freed.
+ * - Memory is allocated in multiples of the word size. The
+ * return value of the strlen() function does not reflect
+ * this; it will allways be less than or equal to the amount
+ * of memory actually allocated.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_cacheEntryPtr ubi_cacheGet( ubi_cacheRootPtr CachePtr,
+ ubi_trItemPtr FindMe );
+ /* ------------------------------------------------------------------------ **
+ * Attempt to retrieve an entry from the cache.
+ *
+ * Input: CachePtr - A ponter to the cache that is to be searched.
+ * FindMe - A ubi_trItemPtr that indicates the key for which
+ * to search.
+ *
+ * Output: A pointer to the cache entry that was found, or NULL if no
+ * matching entry was found.
+ *
+ * Notes: This function also updates the hit ratio counters.
+ * The counters are unsigned short. If the number of cache tries
+ * reaches 32768, then both the number of tries and the number of
+ * hits are divided by two. This prevents the counters from
+ * overflowing. See the comments in ubi_cacheHitRatio() for
+ * additional notes.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_trBool ubi_cacheDelete( ubi_cacheRootPtr CachePtr, ubi_trItemPtr DeleteMe );
+ /* ------------------------------------------------------------------------ **
+ * Find and delete the specified cache entry.
+ *
+ * Input: CachePtr - A pointer to the cache.
+ * DeleteMe - The key of the entry to be deleted.
+ *
+ * Output: TRUE if the entry was found & freed, else FALSE.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_trBool ubi_cacheReduce( ubi_cacheRootPtr CachePtr, unsigned long count );
+ /* ------------------------------------------------------------------------ **
+ * Remove <count> entries from the bottom of the cache.
+ *
+ * Input: CachePtr - A pointer to the cache which is to be reduced in
+ * size.
+ * count - The number of entries to remove.
+ *
+ * Output: The function will return TRUE if <count> entries were removed,
+ * else FALSE. A return value of FALSE should indicate that
+ * there were less than <count> entries in the cache, and that the
+ * cache is now empty.
+ *
+ * Notes: This function forces a reduction in the number of cache entries
+ * without requiring that the MaxMemory or MaxEntries values be
+ * changed.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+unsigned long ubi_cacheSetMaxEntries( ubi_cacheRootPtr CachePtr,
+ unsigned long NewSize );
+ /* ------------------------------------------------------------------------ **
+ * Change the maximum number of entries allowed to exist in the cache.
+ *
+ * Input: CachePtr - A pointer to the cache to be modified.
+ * NewSize - The new maximum number of cache entries.
+ *
+ * Output: The maximum number of entries previously allowed to exist in
+ * the cache.
+ *
+ * Notes: If the new size is less than the old size, this function will
+ * trim the cache (remove excess entries).
+ * - A value of zero indicates an unlimited number of entries.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+unsigned long ubi_cacheSetMaxMemory( ubi_cacheRootPtr CachePtr,
+ unsigned long NewSize );
+ /* ------------------------------------------------------------------------ **
+ * Change the maximum amount of memory to be used for storing cache
+ * entries.
+ *
+ * Input: CachePtr - A pointer to the cache to be modified.
+ * NewSize - The new cache memory size.
+ *
+ * Output: The previous maximum memory size.
+ *
+ * Notes: If the new size is less than the old size, this function will
+ * trim the cache (remove excess entries).
+ * - A value of zero indicates that the cache has no memory limit.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+int ubi_cacheHitRatio( ubi_cacheRootPtr CachePtr );
+ /* ------------------------------------------------------------------------ **
+ * Returns a value that is 10,000 times the slightly weighted average hit
+ * ratio for the cache.
+ *
+ * Input: CachePtr - Pointer to the cache to be queried.
+ *
+ * Output: An integer that is 10,000 times the number of successful
+ * cache hits divided by the number of cache lookups, or:
+ * (10000 * hits) / trys
+ * You can easily convert this to a float, or do something
+ * like this (where i is the return value of this function):
+ *
+ * printf( "Hit rate : %d.%02d%%\n", (i/100), (i%100) );
+ *
+ * Notes: I say "slightly-weighted", because the numerator and
+ * denominator are both accumulated in locations of type
+ * 'unsigned short'. If the number of cache trys becomes
+ * large enough, both are divided by two. (See function
+ * ubi_cacheGet().)
+ * Dividing both numerator and denominator by two does not
+ * change the ratio (much...it is an integer divide), but it
+ * does mean that subsequent increments to either counter will
+ * have twice as much significance as previous ones.
+ *
+ * - The value returned by this function will be in the range
+ * [0..10000] because ( 0 <= cache_hits <= cache_trys ) will
+ * always be true.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+/* -------------------------------------------------------------------------- */
+#endif /* ubi_CACHE_H */
diff --git a/source/ubiqx/ubi_SplayTree.c b/source/ubiqx/ubi_SplayTree.c
new file mode 100644
index 00000000000..222506bd06b
--- /dev/null
+++ b/source/ubiqx/ubi_SplayTree.c
@@ -0,0 +1,512 @@
+/* ========================================================================== **
+ * ubi_SplayTree.c
+ *
+ * Copyright (C) 1993-1998 by Christopher R. Hertel
+ *
+ * Email: crh@ubiqx.mn.org
+ * -------------------------------------------------------------------------- **
+ *
+ * This module implements "splay" trees. Splay trees are binary trees
+ * that are rearranged (splayed) whenever a node is accessed. The
+ * splaying process *tends* to make the tree bushier (improves balance),
+ * and the nodes that are accessed most frequently *tend* to be closer to
+ * the top.
+ *
+ * References: "Self-Adjusting Binary Search Trees", by Daniel Sleator and
+ * Robert Tarjan. Journal of the Association for Computing
+ * Machinery Vol 32, No. 3, July 1985 pp. 652-686
+ *
+ * See also: http://www.cs.cmu.edu/~sleator/
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * Log: ubi_SplayTree.c,v
+ * Revision 4.5 2000/01/08 23:26:49 crh
+ * Added ubi_trSplay() macro, which does a type cast for us.
+ *
+ * Revision 4.4 1998/06/04 21:29:27 crh
+ * Upper-cased defined constants (eg UBI_BINTREE_H) in some header files.
+ * This is more "standard", and is what people expect. Weird, eh?
+ *
+ * Revision 4.3 1998/06/03 17:45:05 crh
+ * Further fiddling with sys_include.h. It's now in ubi_BinTree.h which is
+ * included by all of the binary tree files.
+ *
+ * Also fixed some warnings produced by lint on Irix 6.2, which doesn't seem
+ * to like syntax like this:
+ *
+ * if( (a = b) )
+ *
+ * The fix was to change lines like the above to:
+ *
+ * if( 0 != (a=b) )
+ *
+ * Which means the same thing.
+ *
+ * Reminder: Some of the ubi_tr* macros in ubi_BinTree.h are redefined in
+ * ubi_AVLtree.h and ubi_SplayTree.h. This allows easy swapping
+ * of tree types by simply changing a header. Unfortunately, the
+ * macro redefinitions in ubi_AVLtree.h and ubi_SplayTree.h will
+ * conflict if used together. You must either choose a single tree
+ * type, or use the underlying function calls directly. Compare
+ * the two header files for more information.
+ *
+ * Revision 4.2 1998/06/02 01:29:14 crh
+ * Changed ubi_null.h to sys_include.h to make it more generic.
+ *
+ * Revision 4.1 1998/05/20 04:37:54 crh
+ * The C file now includes ubi_null.h. See ubi_null.h for more info.
+ *
+ * Revision 4.0 1998/03/10 03:41:33 crh
+ * Minor comment changes. The revision number is now 4.0 to match the
+ * BinTree and AVLtree modules.
+ *
+ * Revision 2.7 1998/01/24 06:37:08 crh
+ * Added a URL for more information.
+ *
+ * Revision 2.6 1997/12/23 04:01:12 crh
+ * In this version, all constants & macros defined in the header file have
+ * the ubi_tr prefix. Also cleaned up anything that gcc complained about
+ * when run with '-pedantic -fsyntax-only -Wall'.
+ *
+ * Revision 2.5 1997/07/26 04:15:42 crh
+ * + Cleaned up a few minor syntax annoyances that gcc discovered for me.
+ * + Changed ubi_TRUE and ubi_FALSE to ubi_trTRUE and ubi_trFALSE.
+ *
+ * Revision 2.4 1997/06/03 04:42:21 crh
+ * Changed TRUE and FALSE to ubi_TRUE and ubi_FALSE to avoid causing
+ * problems.
+ *
+ * Revision 2.3 1995/10/03 22:19:07 CRH
+ * Ubisized!
+ * Also, added the function ubi_sptSplay().
+ *
+ * Revision 2.1 95/03/09 23:54:42 CRH
+ * Added the ModuleID static string and function. These modules are now
+ * self-identifying.
+ *
+ * Revision 2.0 95/02/27 22:34:46 CRH
+ * This module was updated to match the interface changes made to the
+ * ubi_BinTree module. In particular, the interface to the Locate() function
+ * has changed. See ubi_BinTree for more information on changes and new
+ * functions.
+ *
+ * The revision number was also upped to match ubi_BinTree.
+ *
+ * Revision 1.1 93/10/18 20:35:16 CRH
+ * I removed the hard-coded logical device names from the include file
+ * specifications. CRH
+ *
+ * Revision 1.0 93/10/15 23:00:15 CRH
+ * With this revision, I have added a set of #define's that provide a single,
+ * standard API to all existing tree modules. Until now, each of the three
+ * existing modules had a different function and typedef prefix, as follows:
+ *
+ * Module Prefix
+ * ubi_BinTree ubi_bt
+ * ubi_AVLtree ubi_avl
+ * ubi_SplayTree ubi_spt
+ *
+ * To further complicate matters, only those portions of the base module
+ * (ubi_BinTree) that were superceeded in the new module had the new names.
+ * For example, if you were using ubi_SplayTree, the locate function was
+ * called "ubi_sptLocate", but the next and previous functions remained
+ * "ubi_btNext" and "ubi_btPrev".
+ *
+ * This was not too terrible if you were familiar with the modules and knew
+ * exactly which tree model you wanted to use. If you wanted to be able to
+ * change modules (for speed comparisons, etc), things could get messy very
+ * quickly.
+ *
+ * So, I have added a set of defined names that get redefined in any of the
+ * descendant modules. To use this standardized interface in your code,
+ * simply replace all occurances of "ubi_bt", "ubi_avl", and "ubi_spt" with
+ * "ubi_tr". The "ubi_tr" names will resolve to the correct function or
+ * datatype names for the module that you are using. Just remember to
+ * include the header for that module in your program file. Because these
+ * names are handled by the preprocessor, there is no added run-time
+ * overhead.
+ *
+ * Note that the original names do still exist, and can be used if you wish
+ * to write code directly to a specific module. This should probably only be
+ * done if you are planning to implement a new descendant type, such as
+ * red/black trees. CRH
+ *
+ * Revision 0.1 93/04/25 22:03:32 CRH
+ * Simply changed the <exec/types.h> #include reference the .c file to
+ * use <stdlib.h> instead. The latter is portable, the former is not.
+ *
+ * Revision 0.0 93/04/21 23:05:52 CRH
+ * Initial version, written by Christopher R. Hertel.
+ * This module implements Splay Trees using the ubi_BinTree module as a basis.
+ *
+ * ========================================================================== **
+ */
+
+#include "ubi_SplayTree.h" /* Header for THIS module. */
+
+/* ========================================================================== **
+ * Static data.
+ */
+
+static char ModuleID[] = "ubi_SplayTree\n\
+\tRevision: 4.5 \n\
+\tDate: 2000/01/08 23:26:49 \n\
+\tAuthor: crh \n";
+
+
+/* ========================================================================== **
+ * Private functions...
+ */
+
+static void Rotate( ubi_btNodePtr p )
+ /* ------------------------------------------------------------------------ **
+ * This function performs a single rotation, moving node *p up one level
+ * in the tree.
+ *
+ * Input: p - a pointer to an ubi_btNode in a tree.
+ *
+ * Output: None.
+ *
+ * Notes: This implements a single rotation in either direction (left
+ * or right). This is the basic building block of all splay
+ * tree rotations.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_btNodePtr parentp;
+ ubi_btNodePtr tmp;
+ char way;
+ char revway;
+
+ parentp = p->Link[ubi_trPARENT]; /* Find parent. */
+
+ if( parentp ) /* If no parent, then we're already the root. */
+ {
+ way = p->gender;
+ revway = ubi_trRevWay(way);
+ tmp = p->Link[(int)revway];
+
+ parentp->Link[(int)way] = tmp;
+ if( tmp )
+ {
+ tmp->Link[ubi_trPARENT] = parentp;
+ tmp->gender = way;
+ }
+
+ tmp = parentp->Link[ubi_trPARENT];
+ p->Link[ubi_trPARENT] = tmp;
+ p->gender = parentp->gender;
+ if( tmp )
+ tmp->Link[(int)(p->gender)] = p;
+
+ parentp->Link[ubi_trPARENT] = p;
+ parentp->gender = revway;
+ p->Link[(int)revway] = parentp;
+ }
+ } /* Rotate */
+
+static ubi_btNodePtr Splay( ubi_btNodePtr SplayWithMe )
+ /* ------------------------------------------------------------------------ **
+ * Move the node indicated by SplayWithMe to the root of the tree by
+ * splaying the tree.
+ *
+ * Input: SplayWithMe - A pointer to an ubi_btNode within a tree.
+ *
+ * Output: A pointer to the root of the splay tree (i.e., the same as
+ * SplayWithMe).
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_btNodePtr parent;
+
+ while( NULL != (parent = SplayWithMe->Link[ubi_trPARENT]) )
+ {
+ if( parent->gender == SplayWithMe->gender ) /* Zig-Zig */
+ Rotate( parent );
+ else
+ {
+ if( ubi_trEQUAL != parent->gender ) /* Zig-Zag */
+ Rotate( SplayWithMe );
+ }
+ Rotate( SplayWithMe ); /* Zig */
+ } /* while */
+ return( SplayWithMe );
+ } /* Splay */
+
+/* ========================================================================== **
+ * Exported utilities.
+ */
+
+ubi_trBool ubi_sptInsert( ubi_btRootPtr RootPtr,
+ ubi_btNodePtr NewNode,
+ ubi_btItemPtr ItemPtr,
+ ubi_btNodePtr *OldNode )
+ /* ------------------------------------------------------------------------ **
+ * This function uses a non-recursive algorithm to add a new element to the
+ * splay tree.
+ *
+ * Input: RootPtr - a pointer to the ubi_btRoot structure that indicates
+ * the root of the tree to which NewNode is to be added.
+ * NewNode - a pointer to an ubi_btNode structure that is NOT
+ * part of any tree.
+ * ItemPtr - A pointer to the sort key that is stored within
+ * *NewNode. ItemPtr MUST point to information stored
+ * in *NewNode or an EXACT DUPLICATE. The key data
+ * indicated by ItemPtr is used to place the new node
+ * into the tree.
+ * OldNode - a pointer to an ubi_btNodePtr. When searching
+ * the tree, a duplicate node may be found. If
+ * duplicates are allowed, then the new node will
+ * be simply placed into the tree. If duplicates
+ * are not allowed, however, then one of two things
+ * may happen.
+ * 1) if overwritting *is not* allowed, this
+ * function will return FALSE (indicating that
+ * the new node could not be inserted), and
+ * *OldNode will point to the duplicate that is
+ * still in the tree.
+ * 2) if overwritting *is* allowed, then this
+ * function will swap **OldNode for *NewNode.
+ * In this case, *OldNode will point to the node
+ * that was removed (thus allowing you to free
+ * the node).
+ * ** If you are using overwrite mode, ALWAYS **
+ * ** check the return value of this parameter! **
+ * Note: You may pass NULL in this parameter, the
+ * function knows how to cope. If you do this,
+ * however, there will be no way to return a
+ * pointer to an old (ie. replaced) node (which is
+ * a problem if you are using overwrite mode).
+ *
+ * Output: a boolean value indicating success or failure. The function
+ * will return FALSE if the node could not be added to the tree.
+ * Such failure will only occur if duplicates are not allowed,
+ * nodes cannot be overwritten, AND a duplicate key was found
+ * within the tree.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_btNodePtr OtherP;
+
+ if( !(OldNode) )
+ OldNode = &OtherP;
+
+ if( ubi_btInsert( RootPtr, NewNode, ItemPtr, OldNode ) )
+ {
+ RootPtr->root = Splay( NewNode );
+ return( ubi_trTRUE );
+ }
+
+ /* Splay the unreplacable, duplicate keyed, unique, old node. */
+ RootPtr->root = Splay( (*OldNode) );
+ return( ubi_trFALSE );
+ } /* ubi_sptInsert */
+
+ubi_btNodePtr ubi_sptRemove( ubi_btRootPtr RootPtr, ubi_btNodePtr DeadNode )
+ /* ------------------------------------------------------------------------ **
+ * This function removes the indicated node from the tree.
+ *
+ * Input: RootPtr - A pointer to the header of the tree that contains
+ * the node to be removed.
+ * DeadNode - A pointer to the node that will be removed.
+ *
+ * Output: This function returns a pointer to the node that was removed
+ * from the tree (ie. the same as DeadNode).
+ *
+ * Note: The node MUST be in the tree indicated by RootPtr. If not,
+ * strange and evil things will happen to your trees.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_btNodePtr p;
+
+ (void)Splay( DeadNode ); /* Move dead node to root. */
+ if( NULL != (p = DeadNode->Link[ubi_trLEFT]) )
+ { /* If left subtree exists... */
+ ubi_btNodePtr q = DeadNode->Link[ubi_trRIGHT];
+
+ p->Link[ubi_trPARENT] = NULL; /* Left subtree node becomes root.*/
+ p->gender = ubi_trPARENT;
+ p = ubi_btLast( p ); /* Find rightmost left node... */
+ p->Link[ubi_trRIGHT] = q; /* ...attach right tree. */
+ if( q )
+ q->Link[ubi_trPARENT] = p;
+ RootPtr->root = Splay( p ); /* Resplay at p. */
+ }
+ else
+ {
+ if( NULL != (p = DeadNode->Link[ubi_trRIGHT]) )
+ { /* No left, but right subtree exists... */
+ p->Link[ubi_trPARENT] = NULL; /* Right subtree root becomes... */
+ p->gender = ubi_trPARENT; /* ...overall tree root. */
+ RootPtr->root = p;
+ }
+ else
+ RootPtr->root = NULL; /* No subtrees => empty tree. */
+ }
+
+ (RootPtr->count)--; /* Decrement node count. */
+ return( DeadNode ); /* Return pointer to pruned node. */
+ } /* ubi_sptRemove */
+
+ubi_btNodePtr ubi_sptLocate( ubi_btRootPtr RootPtr,
+ ubi_btItemPtr FindMe,
+ ubi_trCompOps CompOp )
+ /* ------------------------------------------------------------------------ **
+ * The purpose of ubi_btLocate() is to find a node or set of nodes given
+ * a target value and a "comparison operator". The Locate() function is
+ * more flexible and (in the case of trees that may contain dupicate keys)
+ * more precise than the ubi_btFind() function. The latter is faster,
+ * but it only searches for exact matches and, if the tree contains
+ * duplicates, Find() may return a pointer to any one of the duplicate-
+ * keyed records.
+ *
+ * Input:
+ * RootPtr - A pointer to the header of the tree to be searched.
+ * FindMe - An ubi_btItemPtr that indicates the key for which to
+ * search.
+ * CompOp - One of the following:
+ * CompOp Return a pointer to the node with
+ * ------ ---------------------------------
+ * ubi_trLT - the last key value that is less
+ * than FindMe.
+ * ubi_trLE - the first key matching FindMe, or
+ * the last key that is less than
+ * FindMe.
+ * ubi_trEQ - the first key matching FindMe.
+ * ubi_trGE - the first key matching FindMe, or the
+ * first key greater than FindMe.
+ * ubi_trGT - the first key greater than FindMe.
+ * Output:
+ * A pointer to the node matching the criteria listed above under
+ * CompOp, or NULL if no node matched the criteria.
+ *
+ * Notes:
+ * In the case of trees with duplicate keys, Locate() will behave as
+ * follows:
+ *
+ * Find: 3 Find: 3
+ * Keys: 1 2 2 2 3 3 3 3 3 4 4 Keys: 1 1 2 2 2 4 4 5 5 5 6
+ * ^ ^ ^ ^ ^
+ * LT EQ GT LE GE
+ *
+ * That is, when returning a pointer to a node with a key that is LESS
+ * THAN the target key (FindMe), Locate() will return a pointer to the
+ * LAST matching node.
+ * When returning a pointer to a node with a key that is GREATER
+ * THAN the target key (FindMe), Locate() will return a pointer to the
+ * FIRST matching node.
+ *
+ * See Also: ubi_btFind(), ubi_btFirstOf(), ubi_btLastOf().
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_btNodePtr p;
+
+ p = ubi_btLocate( RootPtr, FindMe, CompOp );
+ if( p )
+ RootPtr->root = Splay( p );
+ return( p );
+ } /* ubi_sptLocate */
+
+ubi_btNodePtr ubi_sptFind( ubi_btRootPtr RootPtr,
+ ubi_btItemPtr FindMe )
+ /* ------------------------------------------------------------------------ **
+ * This function performs a non-recursive search of a tree for any node
+ * matching a specific key.
+ *
+ * Input:
+ * RootPtr - a pointer to the header of the tree to be searched.
+ * FindMe - a pointer to the key value for which to search.
+ *
+ * Output:
+ * A pointer to a node with a key that matches the key indicated by
+ * FindMe, or NULL if no such node was found.
+ *
+ * Note: In a tree that allows duplicates, the pointer returned *might
+ * not* point to the (sequentially) first occurance of the
+ * desired key. In such a tree, it may be more useful to use
+ * ubi_sptLocate().
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_btNodePtr p;
+
+ p = ubi_btFind( RootPtr, FindMe );
+ if( p )
+ RootPtr->root = Splay( p );
+ return( p );
+ } /* ubi_sptFind */
+
+void ubi_sptSplay( ubi_btRootPtr RootPtr,
+ ubi_btNodePtr SplayMe )
+ /* ------------------------------------------------------------------------ **
+ * This function allows you to splay the tree at a given node, thus moving
+ * the node to the top of the tree.
+ *
+ * Input:
+ * RootPtr - a pointer to the header of the tree to be splayed.
+ * SplayMe - a pointer to a node within the tree. This will become
+ * the new root node.
+ * Output: None.
+ *
+ * Notes: This is an uncharacteristic function for this group of modules
+ * in that it provides access to the internal balancing routines,
+ * which would normally be hidden.
+ * Splaying the tree will not damage it (assuming that I've done
+ * *my* job), but there is overhead involved. I don't recommend
+ * that you use this function unless you understand the underlying
+ * Splay Tree principles involved.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ RootPtr->root = Splay( SplayMe );
+ } /* ubi_sptSplay */
+
+int ubi_sptModuleID( int size, char *list[] )
+ /* ------------------------------------------------------------------------ **
+ * Returns a set of strings that identify the module.
+ *
+ * Input: size - The number of elements in the array <list>.
+ * list - An array of pointers of type (char *). This array
+ * should, initially, be empty. This function will fill
+ * in the array with pointers to strings.
+ * Output: The number of elements of <list> that were used. If this value
+ * is less than <size>, the values of the remaining elements are
+ * not guaranteed.
+ *
+ * Notes: Please keep in mind that the pointers returned indicate strings
+ * stored in static memory. Don't free() them, don't write over
+ * them, etc. Just read them.
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ if( size > 0 )
+ {
+ list[0] = ModuleID;
+ if( size > 1 )
+ return( 1 + ubi_btModuleID( --size, &(list[1]) ) );
+ return( 1 );
+ }
+ return( 0 );
+ } /* ubi_sptModuleID */
+
+/* ================================ The End ================================= */
+
diff --git a/source/ubiqx/ubi_SplayTree.h b/source/ubiqx/ubi_SplayTree.h
new file mode 100644
index 00000000000..e4fac796a91
--- /dev/null
+++ b/source/ubiqx/ubi_SplayTree.h
@@ -0,0 +1,377 @@
+#ifndef UBI_SPLAYTREE_H
+#define UBI_SPLAYTREE_H
+/* ========================================================================== **
+ * ubi_SplayTree.h
+ *
+ * Copyright (C) 1993-1998 by Christopher R. Hertel
+ *
+ * Email: crh@ubiqx.mn.org
+ * -------------------------------------------------------------------------- **
+ *
+ * This module implements "splay" trees. Splay trees are binary trees
+ * that are rearranged (splayed) whenever a node is accessed. The
+ * splaying process *tends* to make the tree bushier (improves balance),
+ * and the nodes that are accessed most frequently *tend* to be closer to
+ * the top.
+ *
+ * References: "Self-Adjusting Binary Search Trees", by Daniel Sleator and
+ * Robert Tarjan. Journal of the Association for Computing
+ * Machinery Vol 32, No. 3, July 1985 pp. 652-686
+ *
+ * See also: http://www.cs.cmu.edu/~sleator/
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * Log: ubi_SplayTree.h,v
+ * Revision 4.5 2000/01/08 23:26:49 crh
+ * Added ubi_trSplay() macro, which does a type cast for us.
+ *
+ * Revision 4.4 1998/06/04 21:29:27 crh
+ * Upper-cased defined constants (eg UBI_BINTREE_H) in some header files.
+ * This is more "standard", and is what people expect. Weird, eh?
+ *
+ * Revision 4.3 1998/06/03 17:45:05 crh
+ * Further fiddling with sys_include.h. It's now in ubi_BinTree.h which is
+ * included by all of the binary tree files.
+ *
+ * Also fixed some warnings produced by lint on Irix 6.2, which doesn't seem
+ * to like syntax like this:
+ *
+ * if( (a = b) )
+ *
+ * The fix was to change lines like the above to:
+ *
+ * if( 0 != (a=b) )
+ *
+ * Which means the same thing.
+ *
+ * Reminder: Some of the ubi_tr* macros in ubi_BinTree.h are redefined in
+ * ubi_AVLtree.h and ubi_SplayTree.h. This allows easy swapping
+ * of tree types by simply changing a header. Unfortunately, the
+ * macro redefinitions in ubi_AVLtree.h and ubi_SplayTree.h will
+ * conflict if used together. You must either choose a single tree
+ * type, or use the underlying function calls directly. Compare
+ * the two header files for more information.
+ *
+ * Revision 4.2 1998/06/02 01:29:14 crh
+ * Changed ubi_null.h to sys_include.h to make it more generic.
+ *
+ * Revision 4.1 1998/05/20 04:37:54 crh
+ * The C file now includes ubi_null.h. See ubi_null.h for more info.
+ *
+ * Revision 4.0 1998/03/10 03:40:57 crh
+ * Minor comment changes. The revision number is now 4.0 to match the
+ * BinTree and AVLtree modules.
+ *
+ * Revision 2.7 1998/01/24 06:37:57 crh
+ * Added a URL for more information.
+ *
+ * Revision 2.6 1997/12/23 04:02:20 crh
+ * In this version, all constants & macros defined in the header file have
+ * the ubi_tr prefix. Also cleaned up anything that gcc complained about
+ * when run with '-pedantic -fsyntax-only -Wall'.
+ *
+ * Revision 2.5 1997/07/26 04:15:46 crh
+ * + Cleaned up a few minor syntax annoyances that gcc discovered for me.
+ * + Changed ubi_TRUE and ubi_FALSE to ubi_trTRUE and ubi_trFALSE.
+ *
+ * Revision 2.4 1997/06/03 05:22:56 crh
+ * Changed TRUE and FALSE to ubi_TRUE and ubi_FALSE to avoid causing
+ * problems.
+ *
+ * Revision 2.3 1995/10/03 22:19:37 CRH
+ * Ubisized!
+ * Also, added the function ubi_sptSplay().
+ *
+ * Revision 2.1 95/03/09 23:55:04 CRH
+ * Added the ModuleID static string and function. These modules are now
+ * self-identifying.
+ *
+ * Revision 2.0 95/02/27 22:34:55 CRH
+ * This module was updated to match the interface changes made to the
+ * ubi_BinTree module. In particular, the interface to the Locate() function
+ * has changed. See ubi_BinTree for more information on changes and new
+ * functions.
+ *
+ * The revision number was also upped to match ubi_BinTree.
+ *
+ *
+ * Revision 1.0 93/10/15 22:59:36 CRH
+ * With this revision, I have added a set of #define's that provide a single,
+ * standard API to all existing tree modules. Until now, each of the three
+ * existing modules had a different function and typedef prefix, as follows:
+ *
+ * Module Prefix
+ * ubi_BinTree ubi_bt
+ * ubi_AVLtree ubi_avl
+ * ubi_SplayTree ubi_spt
+ *
+ * To further complicate matters, only those portions of the base module
+ * (ubi_BinTree) that were superceeded in the new module had the new names.
+ * For example, if you were using ubi_SplayTree, the locate function was
+ * called "ubi_sptLocate", but the next and previous functions remained
+ * "ubi_btNext" and "ubi_btPrev".
+ *
+ * This was not too terrible if you were familiar with the modules and knew
+ * exactly which tree model you wanted to use. If you wanted to be able to
+ * change modules (for speed comparisons, etc), things could get messy very
+ * quickly.
+ *
+ * So, I have added a set of defined names that get redefined in any of the
+ * descendant modules. To use this standardized interface in your code,
+ * simply replace all occurances of "ubi_bt", "ubi_avl", and "ubi_spt" with
+ * "ubi_tr". The "ubi_tr" names will resolve to the correct function or
+ * datatype names for the module that you are using. Just remember to
+ * include the header for that module in your program file. Because these
+ * names are handled by the preprocessor, there is no added run-time
+ * overhead.
+ *
+ * Note that the original names do still exist, and can be used if you wish
+ * to write code directly to a specific module. This should probably only be
+ * done if you are planning to implement a new descendant type, such as
+ * red/black trees. CRH
+ *
+ * Revision 0.0 93/04/21 23:07:13 CRH
+ * Initial version, written by Christopher R. Hertel.
+ * This module implements Splay Trees using the ubi_BinTree module as a basis.
+ *
+ * ========================================================================== **
+ */
+
+#include "ubi_BinTree.h" /* Base binary tree functions, types, etc. */
+
+/* ========================================================================== **
+ * Function prototypes...
+ */
+
+ubi_trBool ubi_sptInsert( ubi_btRootPtr RootPtr,
+ ubi_btNodePtr NewNode,
+ ubi_btItemPtr ItemPtr,
+ ubi_btNodePtr *OldNode );
+ /* ------------------------------------------------------------------------ **
+ * This function uses a non-recursive algorithm to add a new element to the
+ * splay tree.
+ *
+ * Input: RootPtr - a pointer to the ubi_btRoot structure that indicates
+ * the root of the tree to which NewNode is to be added.
+ * NewNode - a pointer to an ubi_btNode structure that is NOT
+ * part of any tree.
+ * ItemPtr - A pointer to the sort key that is stored within
+ * *NewNode. ItemPtr MUST point to information stored
+ * in *NewNode or an EXACT DUPLICATE. The key data
+ * indicated by ItemPtr is used to place the new node
+ * into the tree.
+ * OldNode - a pointer to an ubi_btNodePtr. When searching
+ * the tree, a duplicate node may be found. If
+ * duplicates are allowed, then the new node will
+ * be simply placed into the tree. If duplicates
+ * are not allowed, however, then one of two things
+ * may happen.
+ * 1) if overwritting *is not* allowed, this
+ * function will return FALSE (indicating that
+ * the new node could not be inserted), and
+ * *OldNode will point to the duplicate that is
+ * still in the tree.
+ * 2) if overwritting *is* allowed, then this
+ * function will swap **OldNode for *NewNode.
+ * In this case, *OldNode will point to the node
+ * that was removed (thus allowing you to free
+ * the node).
+ * ** If you are using overwrite mode, ALWAYS **
+ * ** check the return value of this parameter! **
+ * Note: You may pass NULL in this parameter, the
+ * function knows how to cope. If you do this,
+ * however, there will be no way to return a
+ * pointer to an old (ie. replaced) node (which is
+ * a problem if you are using overwrite mode).
+ *
+ * Output: a boolean value indicating success or failure. The function
+ * will return FALSE if the node could not be added to the tree.
+ * Such failure will only occur if duplicates are not allowed,
+ * nodes cannot be overwritten, AND a duplicate key was found
+ * within the tree.
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btNodePtr ubi_sptRemove( ubi_btRootPtr RootPtr, ubi_btNodePtr DeadNode );
+ /* ------------------------------------------------------------------------ **
+ * This function removes the indicated node from the tree.
+ *
+ * Input: RootPtr - A pointer to the header of the tree that contains
+ * the node to be removed.
+ * DeadNode - A pointer to the node that will be removed.
+ *
+ * Output: This function returns a pointer to the node that was removed
+ * from the tree (ie. the same as DeadNode).
+ *
+ * Note: The node MUST be in the tree indicated by RootPtr. If not,
+ * strange and evil things will happen to your trees.
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btNodePtr ubi_sptLocate( ubi_btRootPtr RootPtr,
+ ubi_btItemPtr FindMe,
+ ubi_trCompOps CompOp );
+ /* ------------------------------------------------------------------------ **
+ * The purpose of ubi_btLocate() is to find a node or set of nodes given
+ * a target value and a "comparison operator". The Locate() function is
+ * more flexible and (in the case of trees that may contain dupicate keys)
+ * more precise than the ubi_btFind() function. The latter is faster,
+ * but it only searches for exact matches and, if the tree contains
+ * duplicates, Find() may return a pointer to any one of the duplicate-
+ * keyed records.
+ *
+ * Input:
+ * RootPtr - A pointer to the header of the tree to be searched.
+ * FindMe - An ubi_btItemPtr that indicates the key for which to
+ * search.
+ * CompOp - One of the following:
+ * CompOp Return a pointer to the node with
+ * ------ ---------------------------------
+ * ubi_trLT - the last key value that is less
+ * than FindMe.
+ * ubi_trLE - the first key matching FindMe, or
+ * the last key that is less than
+ * FindMe.
+ * ubi_trEQ - the first key matching FindMe.
+ * ubi_trGE - the first key matching FindMe, or the
+ * first key greater than FindMe.
+ * ubi_trGT - the first key greater than FindMe.
+ * Output:
+ * A pointer to the node matching the criteria listed above under
+ * CompOp, or NULL if no node matched the criteria.
+ *
+ * Notes:
+ * In the case of trees with duplicate keys, Locate() will behave as
+ * follows:
+ *
+ * Find: 3 Find: 3
+ * Keys: 1 2 2 2 3 3 3 3 3 4 4 Keys: 1 1 2 2 2 4 4 5 5 5 6
+ * ^ ^ ^ ^ ^
+ * LT EQ GT LE GE
+ *
+ * That is, when returning a pointer to a node with a key that is LESS
+ * THAN the target key (FindMe), Locate() will return a pointer to the
+ * LAST matching node.
+ * When returning a pointer to a node with a key that is GREATER
+ * THAN the target key (FindMe), Locate() will return a pointer to the
+ * FIRST matching node.
+ *
+ * See Also: ubi_btFind(), ubi_btFirstOf(), ubi_btLastOf().
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_btNodePtr ubi_sptFind( ubi_btRootPtr RootPtr,
+ ubi_btItemPtr FindMe );
+ /* ------------------------------------------------------------------------ **
+ * This function performs a non-recursive search of a tree for any node
+ * matching a specific key.
+ *
+ * Input:
+ * RootPtr - a pointer to the header of the tree to be searched.
+ * FindMe - a pointer to the key value for which to search.
+ *
+ * Output:
+ * A pointer to a node with a key that matches the key indicated by
+ * FindMe, or NULL if no such node was found.
+ *
+ * Note: In a tree that allows duplicates, the pointer returned *might
+ * not* point to the (sequentially) first occurance of the
+ * desired key. In such a tree, it may be more useful to use
+ * ubi_sptLocate().
+ * ------------------------------------------------------------------------ **
+ */
+
+void ubi_sptSplay( ubi_btRootPtr RootPtr,
+ ubi_btNodePtr SplayMe );
+ /* ------------------------------------------------------------------------ **
+ * This function allows you to splay the tree at a given node, thus moving
+ * the node to the top of the tree.
+ *
+ * Input:
+ * RootPtr - a pointer to the header of the tree to be splayed.
+ * SplayMe - a pointer to a node within the tree. This will become
+ * the new root node.
+ * Output: None.
+ *
+ * Notes: This is an uncharacteristic function for this group of modules
+ * in that it provides access to the internal balancing routines,
+ * which would normally be hidden.
+ * Splaying the tree will not damage it (assuming that I've done
+ * *my* job), but there is overhead involved. I don't recommend
+ * that you use this function unless you understand the underlying
+ * Splay Tree principles involved.
+ * ------------------------------------------------------------------------ **
+ */
+
+int ubi_sptModuleID( int size, char *list[] );
+ /* ------------------------------------------------------------------------ **
+ * Returns a set of strings that identify the module.
+ *
+ * Input: size - The number of elements in the array <list>.
+ * list - An array of pointers of type (char *). This array
+ * should, initially, be empty. This function will fill
+ * in the array with pointers to strings.
+ * Output: The number of elements of <list> that were used. If this value
+ * is less than <size>, the values of the remaining elements are
+ * not guaranteed.
+ *
+ * Notes: Please keep in mind that the pointers returned indicate strings
+ * stored in static memory. Don't free() them, don't write over
+ * them, etc. Just read them.
+ * ------------------------------------------------------------------------ **
+ */
+
+/* -------------------------------------------------------------------------- **
+ * Masquarade...
+ *
+ * This set of defines allows you to write programs that will use any of the
+ * implemented binary tree modules (currently BinTree, AVLtree, and SplayTree).
+ * Instead of using ubi_bt..., use ubi_tr..., and select the tree type by
+ * including the appropriate module header.
+ */
+
+#undef ubi_trInsert
+#undef ubi_trRemove
+#undef ubi_trLocate
+#undef ubi_trFind
+#undef ubi_trModuleID
+
+#define ubi_trInsert( Rp, Nn, Ip, On ) \
+ ubi_sptInsert( (ubi_btRootPtr)(Rp), (ubi_btNodePtr)(Nn), \
+ (ubi_btItemPtr)(Ip), (ubi_btNodePtr *)(On) )
+
+#define ubi_trRemove( Rp, Dn ) \
+ ubi_sptRemove( (ubi_btRootPtr)(Rp), (ubi_btNodePtr)(Dn) )
+
+#define ubi_trLocate( Rp, Ip, Op ) \
+ ubi_sptLocate( (ubi_btRootPtr)(Rp), \
+ (ubi_btItemPtr)(Ip), \
+ (ubi_trCompOps)(Op) )
+
+#define ubi_trFind( Rp, Ip ) \
+ ubi_sptFind( (ubi_btRootPtr)(Rp), (ubi_btItemPtr)(Ip) )
+
+#define ubi_trSplay( Rp, Sm ) \
+ ubi_sptSplay( (ubi_btRootPtr)(Rp), (ubi_btNodePtr)(Sm) )
+
+#define ubi_trModuleID( s, l ) ubi_sptModuleID( s, l )
+
+/* ================================ The End ================================= */
+#endif /* UBI_SPLAYTREE_H */
diff --git a/source/ubiqx/ubi_dLinkList.c b/source/ubiqx/ubi_dLinkList.c
new file mode 100644
index 00000000000..eb95033c695
--- /dev/null
+++ b/source/ubiqx/ubi_dLinkList.c
@@ -0,0 +1,171 @@
+/* ========================================================================== **
+ * ubi_dLinkList.c
+ *
+ * Copyright (C) 1997, 1998 by Christopher R. Hertel
+ *
+ * Email: crh@ubiqx.mn.org
+ * -------------------------------------------------------------------------- **
+ * This module implements simple doubly-linked lists.
+ * -------------------------------------------------------------------------- **
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * Log: ubi_dLinkList.c,v
+ * Revision 0.11 1999/06/19 16:58:06 crh
+ * Renamed the ubi_slRemove() function in ubi_sLinkList to
+ * ubi_slRemoveNext(). I was bothered by the fact that it didn't
+ * match the functionality of the ubi_dlRemove() function in
+ * ubi_dLinkList. The new name is more 'correct'.
+ *
+ * Revision 0.10 1998/07/24 07:30:20 crh
+ * Added the ubi_dlNewList() macro.
+ *
+ * Revision 0.9 1998/06/04 21:29:27 crh
+ * Upper-cased defined constants (eg UBI_BINTREE_H) in some header files.
+ * This is more "standard", and is what people expect. Weird, eh?
+ *
+ * Revision 0.8 1998/06/03 18:06:03 crh
+ * Further fiddling with sys_include.h, which has been moved from the .c file
+ * to the .h file.
+ *
+ * Revision 0.7 1998/06/02 01:38:47 crh
+ * Changed include file name from ubi_null.h to sys_include.h to make it
+ * more generic.
+ *
+ * Revision 0.6 1998/05/20 04:38:05 crh
+ * The C file now includes ubi_null.h. See ubi_null.h for more info.
+ *
+ * Revision 0.5 1998/03/10 02:55:00 crh
+ * Simplified the code and added macros for stack & queue manipulations.
+ *
+ * Revision 0.4 1998/01/03 01:53:56 crh
+ * Added ubi_dlCount() macro.
+ *
+ * Revision 0.3 1997/10/15 03:05:39 crh
+ * Added some handy type casting to the macros. Added AddHere and RemThis
+ * macros.
+ *
+ * Revision 0.2 1997/10/08 03:07:21 crh
+ * Fixed a few forgotten link-ups in Insert(), and fixed the AddHead()
+ * macro, which was passing the wrong value for <After> to Insert().
+ *
+ * Revision 0.1 1997/10/07 04:34:07 crh
+ * Initial Revision.
+ *
+ * -------------------------------------------------------------------------- **
+ * This module is similar to the ubi_sLinkList module, but it is neither a
+ * descendant type nor an easy drop-in replacement for the latter. One key
+ * difference is that the ubi_dlRemove() function removes the indicated node,
+ * while the ubi_slRemoveNext() function (in ubi_sLinkList) removes the node
+ * *following* the indicated node.
+ *
+ * ========================================================================== **
+ */
+
+#include "ubi_dLinkList.h" /* Header for *this* module. */
+
+/* ========================================================================== **
+ * Functions...
+ */
+
+ubi_dlListPtr ubi_dlInitList( ubi_dlListPtr ListPtr )
+ /* ------------------------------------------------------------------------ **
+ * Initialize a doubly-linked list header.
+ *
+ * Input: ListPtr - A pointer to the list structure that is to be
+ * initialized for use.
+ *
+ * Output: A pointer to the initialized list header (i.e., same as
+ * <ListPtr>).
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ListPtr->Head = NULL;
+ ListPtr->Tail = NULL;
+ ListPtr->count = 0;
+ return( ListPtr );
+ } /* ubi_dlInitList */
+
+ubi_dlNodePtr ubi_dlInsert( ubi_dlListPtr ListPtr,
+ ubi_dlNodePtr New,
+ ubi_dlNodePtr After )
+ /* ------------------------------------------------------------------------ **
+ * Insert a new node into the list.
+ *
+ * Input: ListPtr - A pointer to the list into which the node is to
+ * be inserted.
+ * New - Pointer to the new node.
+ * After - NULL, or a pointer to a node that is already in the
+ * list.
+ * If NULL, then <New> will be added at the head of the
+ * list, else it will be added following <After>.
+ *
+ * Output: A pointer to the node that was inserted into the list (i.e.,
+ * the same as <New>).
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_dlNodePtr PredNode = After ? After : (ubi_dlNodePtr)ListPtr;
+
+ New->Next = PredNode->Next;
+ New->Prev = After;
+ PredNode->Next = New;
+ if( New->Next )
+ New->Next->Prev = New;
+ else
+ ListPtr->Tail = New;
+
+ (ListPtr->count)++;
+
+ return( New );
+ } /* ubi_dlInsert */
+
+ubi_dlNodePtr ubi_dlRemove( ubi_dlListPtr ListPtr, ubi_dlNodePtr Old )
+ /* ------------------------------------------------------------------------ **
+ * Remove a node from the list.
+ *
+ * Input: ListPtr - A pointer to the list from which <Old> is to be
+ * removed.
+ * Old - A pointer to the node that is to be removed from the
+ * list.
+ *
+ * Output: A pointer to the node that was removed (i.e., <Old>).
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ if( Old )
+ {
+ if( Old->Next )
+ Old->Next->Prev = Old->Prev;
+ else
+ ListPtr->Tail = Old->Prev;
+
+ if( Old->Prev )
+ Old->Prev->Next = Old->Next;
+ else
+ ListPtr->Head = Old->Next;
+
+ (ListPtr->count)--;
+ }
+
+ return( Old );
+ } /* ubi_dlRemove */
+
+/* ================================ The End ================================= */
diff --git a/source/ubiqx/ubi_dLinkList.h b/source/ubiqx/ubi_dLinkList.h
new file mode 100644
index 00000000000..682e566ee67
--- /dev/null
+++ b/source/ubiqx/ubi_dLinkList.h
@@ -0,0 +1,242 @@
+#ifndef UBI_DLINKLIST_H
+#define UBI_DLINKLIST_H
+/* ========================================================================== **
+ * ubi_dLinkList.h
+ *
+ * Copyright (C) 1997, 1998 by Christopher R. Hertel
+ *
+ * Email: crh@ubiqx.mn.org
+ * -------------------------------------------------------------------------- **
+ * This module implements simple doubly-linked lists.
+ * -------------------------------------------------------------------------- **
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * Log: ubi_dLinkList.h,v
+ * Revision 0.11 1999/06/19 16:58:06 crh
+ * Renamed the ubi_slRemove() function in ubi_sLinkList to
+ * ubi_slRemoveNext(). I was bothered by the fact that it didn't
+ * match the functionality of the ubi_dlRemove() function in
+ * ubi_dLinkList. The new name is more 'correct'.
+ *
+ * Revision 0.10 1998/07/24 07:30:20 crh
+ * Added the ubi_dlNewList() macro.
+ *
+ * Revision 0.9 1998/06/04 21:29:27 crh
+ * Upper-cased defined constants (eg UBI_BINTREE_H) in some header files.
+ * This is more "standard", and is what people expect. Weird, eh?
+ *
+ * Revision 0.8 1998/06/03 18:06:03 crh
+ * Further fiddling with sys_include.h, which has been moved from the .c file
+ * to the .h file.
+ *
+ * Revision 0.7 1998/06/02 01:38:47 crh
+ * Changed include file name from ubi_null.h to sys_include.h to make it
+ * more generic.
+ *
+ * Revision 0.6 1998/05/20 04:38:05 crh
+ * The C file now includes ubi_null.h. See ubi_null.h for more info.
+ *
+ * Revision 0.5 1998/03/10 02:54:04 crh
+ * Simplified the code and added macros for stack & queue manipulations.
+ *
+ * Revision 0.4 1998/01/03 01:53:44 crh
+ * Added ubi_dlCount() macro.
+ *
+ * Revision 0.3 1997/10/15 03:04:31 crh
+ * Added some handy type casting to the macros. Added AddHere and RemThis
+ * macros.
+ *
+ * Revision 0.2 1997/10/08 03:08:16 crh
+ * Fixed a few forgotten link-ups in Insert(), and fixed the AddHead()
+ * macro, which was passing the wrong value for <After> to Insert().
+ *
+ * Revision 0.1 1997/10/07 04:34:38 crh
+ * Initial Revision.
+ *
+ * -------------------------------------------------------------------------- **
+ * This module is similar to the ubi_sLinkList module, but it is neither a
+ * descendant type nor an easy drop-in replacement for the latter. One key
+ * difference is that the ubi_dlRemove() function removes the indicated node,
+ * while the ubi_slRemoveNext() function (in ubi_sLinkList) removes the node
+ * *following* the indicated node.
+ *
+ * ========================================================================== **
+ */
+
+#include "sys_include.h" /* System-specific includes. */
+
+/* ========================================================================== **
+ * Typedefs...
+ *
+ * ubi_dlNode - This is the basic node structure.
+ * ubi_dlNodePtr - Pointer to a node.
+ * ubi_dlList - This is the list header structure.
+ * ubi_dlListPtr - Pointer to a List (i.e., a list header structure).
+ *
+ */
+
+typedef struct ubi_dlListNode
+ {
+ struct ubi_dlListNode *Next;
+ struct ubi_dlListNode *Prev;
+ } ubi_dlNode;
+
+typedef ubi_dlNode *ubi_dlNodePtr;
+
+typedef struct
+ {
+ ubi_dlNodePtr Head;
+ ubi_dlNodePtr Tail;
+ unsigned long count;
+ } ubi_dlList;
+
+typedef ubi_dlList *ubi_dlListPtr;
+
+/* ========================================================================== **
+ * Macros...
+ *
+ * ubi_dlNewList - Macro used to declare and initialize a new list in one
+ * swell foop. It is used when defining a variable of
+ * type ubi_dlList. The definition
+ * static ubi_dlNewList( gerbil );
+ * is translated to
+ * static ubi_dlList gerbil[1] = {{ NULL, NULL, 0 }};
+ *
+ * ubi_dlCount - Return the number of entries currently in the list.
+ *
+ * ubi_dlAddHead - Add a new node at the head of the list.
+ * ubi_dlAddNext - Add a node following the given node.
+ * ubi_dlAddTail - Add a new node at the tail of the list.
+ * Note: AddTail evaluates the L parameter twice.
+ *
+ * ubi_dlRemHead - Remove the node at the head of the list, if any.
+ * Note: RemHead evaluates the L parameter twice.
+ * ubi_dlRemThis - Remove the indicated node.
+ * ubi_dlRemTail - Remove the node at the tail of the list, if any.
+ * Note: RemTail evaluates the L parameter twice.
+ *
+ * ubi_dlFirst - Return a pointer to the first node in the list, if any.
+ * ubi_dlLast - Return a pointer to the last node in the list, if any.
+ * ubi_dlNext - Given a node, return a pointer to the next node.
+ * ubi_dlPrev - Given a node, return a pointer to the previous node.
+ *
+ * ubi_dlPush - Add a node at the head of the list (synonym of AddHead).
+ * ubi_dlPop - Remove a node at the head of the list (synonym of RemHead).
+ * ubi_dlEnqueue - Add a node at the tail of the list (sysnonym of AddTail).
+ * ubi_dlDequeue - Remove a node at the head of the list (synonym of RemHead).
+ *
+ * Note that all of these provide type casting of the parameters. The
+ * Add and Rem macros are nothing more than nice front-ends to the
+ * Insert and Remove operations.
+ *
+ * Also note that the First, Next and Last macros do no parameter checking!
+ *
+ */
+
+#define ubi_dlNewList( L ) ubi_dlList (L)[1] = {{ NULL, NULL, 0 }}
+
+#define ubi_dlCount( L ) (((ubi_dlListPtr)(L))->count)
+
+#define ubi_dlAddHead( L, N ) \
+ ubi_dlInsert( (ubi_dlListPtr)(L), (ubi_dlNodePtr)(N), NULL )
+
+#define ubi_dlAddNext( L, N, A ) \
+ ubi_dlInsert( (ubi_dlListPtr)(L), \
+ (ubi_dlNodePtr)(N), \
+ (ubi_dlNodePtr)(A) )
+
+#define ubi_dlAddTail( L, N ) \
+ ubi_dlInsert( (ubi_dlListPtr)(L), \
+ (ubi_dlNodePtr)(N), \
+ (((ubi_dlListPtr)(L))->Tail) )
+
+#define ubi_dlRemHead( L ) ubi_dlRemove( (ubi_dlListPtr)(L), \
+ (((ubi_dlListPtr)(L))->Head) )
+
+#define ubi_dlRemThis( L, N ) ubi_dlRemove( (ubi_dlListPtr)(L), \
+ (ubi_dlNodePtr)(N) )
+
+#define ubi_dlRemTail( L ) ubi_dlRemove( (ubi_dlListPtr)(L), \
+ (((ubi_dlListPtr)(L))->Tail) )
+
+#define ubi_dlFirst( L ) (((ubi_dlListPtr)(L))->Head)
+
+#define ubi_dlLast( L ) (((ubi_dlListPtr)(L))->Tail)
+
+#define ubi_dlNext( N ) (((ubi_dlNodePtr)(N))->Next)
+
+#define ubi_dlPrev( N ) (((ubi_dlNodePtr)(N))->Prev)
+
+#define ubi_dlPush ubi_dlAddHead
+#define ubi_dlPop ubi_dlRemHead
+#define ubi_dlEnqueue ubi_dlAddTail
+#define ubi_dlDequeue ubi_dlRemHead
+
+/* ========================================================================== **
+ * Function prototypes...
+ */
+
+ubi_dlListPtr ubi_dlInitList( ubi_dlListPtr ListPtr );
+ /* ------------------------------------------------------------------------ **
+ * Initialize a doubly-linked list header.
+ *
+ * Input: ListPtr - A pointer to the list structure that is to be
+ * initialized for use.
+ *
+ * Output: A pointer to the initialized list header (i.e., same as
+ * <ListPtr>).
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_dlNodePtr ubi_dlInsert( ubi_dlListPtr ListPtr,
+ ubi_dlNodePtr New,
+ ubi_dlNodePtr After );
+ /* ------------------------------------------------------------------------ **
+ * Insert a new node into the list.
+ *
+ * Input: ListPtr - A pointer to the list into which the node is to
+ * be inserted.
+ * New - Pointer to the new node.
+ * After - NULL, or a pointer to a node that is already in the
+ * list.
+ * If NULL, then <New> will be added at the head of the
+ * list, else it will be added following <After>.
+ *
+ * Output: A pointer to the node that was inserted into the list (i.e.,
+ * the same as <New>).
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_dlNodePtr ubi_dlRemove( ubi_dlListPtr ListPtr, ubi_dlNodePtr Old );
+ /* ------------------------------------------------------------------------ **
+ * Remove a node from the list.
+ *
+ * Input: ListPtr - A pointer to the list from which <Old> is to be
+ * removed.
+ * Old - A pointer to the node that is to be removed from the
+ * list.
+ *
+ * Output: A pointer to the node that was removed (i.e., <Old>).
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+/* ================================ The End ================================= */
+#endif /* UBI_DLINKLIST_H */
diff --git a/source/ubiqx/ubi_sLinkList.c b/source/ubiqx/ubi_sLinkList.c
new file mode 100644
index 00000000000..ff75931b470
--- /dev/null
+++ b/source/ubiqx/ubi_sLinkList.c
@@ -0,0 +1,187 @@
+/* ========================================================================== **
+ * ubi_sLinkList.c
+ *
+ * Copyright (C) 1997, 1998 by Christopher R. Hertel
+ *
+ * Email: crh@ubiqx.mn.org
+ * -------------------------------------------------------------------------- **
+ * This module implements a simple singly-linked list.
+ * -------------------------------------------------------------------------- **
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * Log: ubi_sLinkList.c,v
+ * Revision 0.10 1999/06/19 16:58:06 crh
+ * Renamed the ubi_slRemove() function in ubi_sLinkList to
+ * ubi_slRemoveNext(). I was bothered by the fact that it didn't
+ * match the functionality of the ubi_dlRemove() function in
+ * ubi_dLinkList. The new name is more 'correct'.
+ *
+ * Revision 0.9 1998/07/24 07:30:20 crh
+ * Added the ubi_slNewList() macro.
+ *
+ * Revision 0.8 1998/06/04 21:29:27 crh
+ * Upper-cased defined constants (eg UBI_BINTREE_H) in some header files.
+ * This is more "standard", and is what people expect. Weird, eh?
+ *
+ * Revision 0.7 1998/06/03 18:06:03 crh
+ * Further fiddling with sys_include.h, which has been moved from the .c file
+ * to the .h file.
+ *
+ * Revision 0.6 1998/06/02 01:38:47 crh
+ * Changed include file name from ubi_null.h to sys_include.h to make it
+ * more generic.
+ *
+ * Revision 0.5 1998/05/20 04:38:05 crh
+ * The C file now includes ubi_null.h. See ubi_null.h for more info.
+ *
+ * Revision 0.4 1998/03/10 02:23:20 crh
+ * Combined ubi_StackQueue and ubi_sLinkList into one module. Redesigned
+ * the functions and macros. Not a complete rewrite but close to it.
+ *
+ * Revision 0.3 1998/01/03 01:59:52 crh
+ * Added ubi_slCount() macro.
+ *
+ * Revision 0.2 1997/10/21 03:35:18 crh
+ * Added parameter <After> in function Insert(). Made necessary changes
+ * to macro AddHead() and added macro AddHere().
+ *
+ * Revision 0.1 1997/10/16 02:53:45 crh
+ * Initial Revision.
+ *
+ * -------------------------------------------------------------------------- **
+ * This module implements a singly-linked list which may also be used as a
+ * queue or a stack. For a queue, entries are added at the tail and removed
+ * from the head of the list. For a stack, the entries are entered and
+ * removed from the head of the list. A traversal of the list will always
+ * start at the head of the list and proceed toward the tail. This is all
+ * mind-numbingly simple, but I'm surprised by the number of programs out
+ * there which re-implement this a dozen or so times.
+ *
+ * Note: When the list header is initialized, the Tail pointer is set to
+ * point to the Head pointer. This simplifies things a great deal,
+ * except that you can't initialize a stack or queue by simply
+ * zeroing it out. One sure way to initialize the header is to call
+ * ubi_slInit(). Another option would be something like this:
+ *
+ * ubi_slNewList( MyList );
+ *
+ * Which translates to:
+ *
+ * ubi_slList MyList[1] = { NULL, (ubi_slNodePtr)MyList, 0 };
+ *
+ * See ubi_slInit(), ubi_slNewList(), and the ubi_slList structure
+ * for more info.
+ *
+ * + Also, note that this module is similar to the ubi_dLinkList
+ * module. There are three key differences:
+ * - This is a singly-linked list, the other is a doubly-linked
+ * list.
+ * - In this module, if the list is empty, the tail pointer will
+ * point back to the head of the list as described above. This
+ * is not done in ubi_dLinkList.
+ * - The ubi_slRemoveNext() function, by necessity, removes the
+ * 'next' node. In ubi_dLinkList, the ubi_dlRemove() function
+ * removes the 'current' node.
+ *
+ * ========================================================================== **
+ */
+
+#include "ubi_sLinkList.h" /* Header for *this* module. */
+
+/* ========================================================================== **
+ * Functions...
+ */
+
+ubi_slListPtr ubi_slInitList( ubi_slListPtr ListPtr )
+ /* ------------------------------------------------------------------------ **
+ * Initialize a singly-linked list header.
+ *
+ * Input: ListPtr - A pointer to the list structure that is to be
+ * initialized for use.
+ *
+ * Output: A pointer to the initialized list header (i.e., same as
+ * <ListPtr>).
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ListPtr->Head = NULL;
+ ListPtr->Tail = (ubi_slNodePtr)ListPtr;
+ ListPtr->count = 0;
+ return( ListPtr );
+ } /* ubi_slInitList */
+
+ubi_slNodePtr ubi_slInsert( ubi_slListPtr ListPtr,
+ ubi_slNodePtr New,
+ ubi_slNodePtr After )
+ /* ------------------------------------------------------------------------ **
+ * Add a node to the list.
+ *
+ * Input: ListPtr - A pointer to the list into which the node is to
+ * be inserted.
+ * New - Pointer to the node that is to be added to the list.
+ * After - Pointer to a list in a node after which the new node
+ * will be inserted. If NULL, then the new node will
+ * be added at the head of the list.
+ *
+ * Output: A pointer to the node that was inserted into the list (i.e.,
+ * the same as <New>).
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ After = After ? After : (ubi_slNodePtr)ListPtr;
+ New->Next = After->Next;
+ After->Next = New;
+ if( !(New->Next) )
+ ListPtr->Tail = New;
+ (ListPtr->count)++;
+ return( New );
+ } /* ubi_slInsert */
+
+ubi_slNodePtr ubi_slRemoveNext( ubi_slListPtr ListPtr, ubi_slNodePtr AfterMe )
+ /* ------------------------------------------------------------------------ **
+ * Remove the node followng <AfterMe>. If <AfterMe> is NULL, remove from
+ * the head of the list.
+ *
+ * Input: ListPtr - A pointer to the list from which the node is to be
+ * removed.
+ * AfterMe - Pointer to the node preceeding the node to be
+ * removed.
+ *
+ * Output: A pointer to the node that was removed, or NULL if the list is
+ * empty.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ ubi_slNodePtr DelNode;
+
+ AfterMe = AfterMe ? AfterMe : (ubi_slNodePtr)ListPtr;
+ DelNode = AfterMe->Next;
+ if( DelNode )
+ {
+ if( !(DelNode->Next) )
+ ListPtr->Tail = AfterMe;
+ AfterMe->Next = DelNode->Next;
+ (ListPtr->count)--;
+ }
+ return( DelNode );
+ } /* ubi_slRemoveNext */
+
+/* ================================ The End ================================= */
diff --git a/source/ubiqx/ubi_sLinkList.h b/source/ubiqx/ubi_sLinkList.h
new file mode 100644
index 00000000000..53bfa400671
--- /dev/null
+++ b/source/ubiqx/ubi_sLinkList.h
@@ -0,0 +1,254 @@
+#ifndef UBI_SLINKLIST_H
+#define UBI_SLINKLIST_H
+/* ========================================================================== **
+ * ubi_sLinkList.h
+ *
+ * Copyright (C) 1997, 1998 by Christopher R. Hertel
+ *
+ * Email: crh@ubiqx.mn.org
+ * -------------------------------------------------------------------------- **
+ * This module implements a simple singly-linked list.
+ * -------------------------------------------------------------------------- **
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * -------------------------------------------------------------------------- **
+ *
+ * Log: ubi_sLinkList.h,v
+ * Revision 0.10 1999/06/19 16:58:06 crh
+ * Renamed the ubi_slRemove() function in ubi_sLinkList to
+ * ubi_slRemoveNext(). I was bothered by the fact that it didn't
+ * match the functionality of the ubi_dlRemove() function in
+ * ubi_dLinkList. The new name is more 'correct'.
+ *
+ * Revision 0.9 1998/07/24 07:30:20 crh
+ * Added the ubi_slNewList() macro.
+ *
+ * Revision 0.8 1998/06/04 21:29:27 crh
+ * Upper-cased defined constants (eg UBI_BINTREE_H) in some header files.
+ * This is more "standard", and is what people expect. Weird, eh?
+ *
+ * Revision 0.7 1998/06/03 18:06:03 crh
+ * Further fiddling with sys_include.h, which has been moved from the .c file
+ * to the .h file.
+ *
+ * Revision 0.6 1998/06/02 01:38:47 crh
+ * Changed include file name from ubi_null.h to sys_include.h to make it
+ * more generic.
+ *
+ * Revision 0.5 1998/05/20 04:38:05 crh
+ * The C file now includes ubi_null.h. See ubi_null.h for more info.
+ *
+ * Revision 0.4 1998/03/10 02:22:39 crh
+ * Combined ubi_StackQueue and ubi_sLinkList into one module. Redesigned
+ * the functions and macros. Not a complete rewrite but close to it.
+ *
+ * Revision 0.3 1998/01/03 02:00:02 crh
+ * Added ubi_slCount() macro.
+ *
+ * Revision 0.2 1997/10/21 03:36:14 crh
+ * Added parameter <After> in function Insert(). Made necessary changes
+ * to macro AddHead() and added macro AddHere().
+ *
+ * Revision 0.1 1997/10/16 02:54:08 crh
+ * Initial Revision.
+ *
+ * -------------------------------------------------------------------------- **
+ * This module implements a singly-linked list which may also be used as a
+ * queue or a stack. For a queue, entries are added at the tail and removed
+ * from the head of the list. For a stack, the entries are entered and
+ * removed from the head of the list. A traversal of the list will always
+ * start at the head of the list and proceed toward the tail. This is all
+ * mind-numbingly simple, but I'm surprised by the number of programs out
+ * there which re-implement this a dozen or so times.
+ *
+ * Note: When the list header is initialized, the Tail pointer is set to
+ * point to the Head pointer. This simplifies things a great deal,
+ * except that you can't initialize a stack or queue by simply
+ * zeroing it out. One sure way to initialize the header is to call
+ * ubi_slInit(). Another option would be something like this:
+ *
+ * ubi_slNewList( MyList );
+ *
+ * Which translates to:
+ *
+ * ubi_slList MyList[1] = { NULL, (ubi_slNodePtr)MyList, 0 };
+ *
+ * See ubi_slInit(), ubi_slNewList(), and the ubi_slList structure
+ * for more info.
+ *
+ * + Also, note that this module is similar to the ubi_dLinkList
+ * module. There are three key differences:
+ * - This is a singly-linked list, the other is a doubly-linked
+ * list.
+ * - In this module, if the list is empty, the tail pointer will
+ * point back to the head of the list as described above. This
+ * is not done in ubi_dLinkList.
+ * - The ubi_slRemoveNext() function, by necessity, removes the
+ * 'next' node. In ubi_dLinkList, the ubi_dlRemove() function
+ * removes the 'current' node.
+ *
+ * ========================================================================== **
+ */
+
+#include "sys_include.h" /* System-specific includes. */
+
+/* ========================================================================== **
+ * Typedefs...
+ *
+ * ubi_slNode - This is the basic node structure.
+ * ubi_slNodePtr - Pointer to a node.
+ * ubi_slList - This is the list header structure.
+ * ubi_slListPtr - Pointer to a List (i.e., a list header structure).
+ *
+ */
+
+typedef struct ubi_slListNode
+ {
+ struct ubi_slListNode *Next;
+ } ubi_slNode;
+
+typedef ubi_slNode *ubi_slNodePtr;
+
+typedef struct
+ {
+ ubi_slNodePtr Head;
+ ubi_slNodePtr Tail;
+ unsigned long count;
+ } ubi_slList;
+
+typedef ubi_slList *ubi_slListPtr;
+
+
+/* ========================================================================== **
+ * Macros...
+ *
+ * ubi_slNewList - Macro used to declare and initialize a list header in
+ * one step.
+ *
+ * ubi_slCount - Returns the current number of entries in the list.
+ *
+ * ubi_slAddHead - Add a new node at the head of the list.
+ * ubi_slAddNext - Add a new node following the indicated node.
+ * ubi_slAddTail - Add a new node to the tail of the list.
+ * Note: AddTail evaluates the L parameter twice.
+ *
+ * ubi_slRemHead - Remove the node at the head of the list, if any.
+ * ubi_slRemNext - Remove the node following the given node.
+ *
+ * ubi_slFirst - Return a pointer to the first node in the list, if any.
+ * ubi_slNext - Given a node, return a pointer to the next node.
+ * ubi_slLast - Return a pointer to the last node in the list, if any.
+ *
+ * ubi_slPush - Add a node at the head of the list (synonym of AddHead).
+ * ubi_slPop - Remove a node at the head of the list (synonym of RemHead).
+ * ubi_slEnqueue - Add a node at the tail of the list (sysnonym of AddTail).
+ * ubi_slDequeue - Remove a node at the head of the list (synonym of RemHead).
+ *
+ * Note that all of these provide type casting of the parameters. The
+ * Add and Rem macros are nothing more than nice front-ends to the
+ * Insert and Remove functions.
+ *
+ * Also note that the First, Next and Last macros do no parameter checking!
+ *
+ */
+
+#define ubi_slNewList( L ) ubi_slList (L)[1] = {{ NULL, (ubi_slNodePtr)(L), 0 }}
+
+#define ubi_slCount( L ) (((ubi_slListPtr)(L))->count)
+
+#define ubi_slAddHead( L, N ) \
+ ubi_slInsert( (ubi_slListPtr)(L), (ubi_slNodePtr)(N), NULL )
+
+#define ubi_slAddNext( L, N, A ) \
+ ubi_slInsert( (ubi_slListPtr)(L), \
+ (ubi_slNodePtr)(N), \
+ (ubi_slNodePtr)(A) )
+
+#define ubi_slAddTail( L, N ) \
+ ubi_slInsert( (ubi_slListPtr)(L), \
+ (ubi_slNodePtr)(N), \
+ ((ubi_slListPtr)(L))->Tail )
+
+#define ubi_slRemHead( L ) ubi_slRemoveNext( (ubi_slListPtr)(L), NULL )
+
+#define ubi_slRemNext( L, N ) \
+ ubi_slRemoveNext( (ubi_slListPtr)(L), (ubi_slNodePtr)(N) )
+
+#define ubi_slFirst( L ) (((ubi_slListPtr)(L))->Head)
+
+#define ubi_slNext( N ) (((ubi_slNodePtr)(N))->Next)
+
+#define ubi_slLast( L ) (((ubi_slListPtr)(L))->Tail)
+
+#define ubi_slPush ubi_slAddHead
+#define ubi_slPop ubi_slRemHead
+#define ubi_slEnqueue ubi_slAddTail
+#define ubi_slDequeue ubi_slRemHead
+
+/* ========================================================================== **
+ * Function prototypes...
+ */
+
+ubi_slListPtr ubi_slInitList( ubi_slListPtr ListPtr );
+ /* ------------------------------------------------------------------------ **
+ * Initialize a singly-linked list header.
+ *
+ * Input: ListPtr - A pointer to the list structure that is to be
+ * initialized for use.
+ *
+ * Output: A pointer to the initialized list header (i.e., same as
+ * <ListPtr>).
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_slNodePtr ubi_slInsert( ubi_slListPtr ListPtr,
+ ubi_slNodePtr New,
+ ubi_slNodePtr After );
+ /* ------------------------------------------------------------------------ **
+ * Add a node to the list.
+ *
+ * Input: ListPtr - A pointer to the list into which the node is to
+ * be inserted.
+ * New - Pointer to the node that is to be added to the list.
+ * After - Pointer to a list in a node after which the new node
+ * will be inserted. If NULL, then the new node will
+ * be added at the head of the list.
+ *
+ * Output: A pointer to the node that was inserted into the list (i.e.,
+ * the same as <New>).
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+ubi_slNodePtr ubi_slRemoveNext( ubi_slListPtr ListPtr, ubi_slNodePtr AfterMe );
+ /* ------------------------------------------------------------------------ **
+ * Remove the node followng <AfterMe>. If <AfterMe> is NULL, remove from
+ * the head of the list.
+ *
+ * Input: ListPtr - A pointer to the list from which the node is to be
+ * removed.
+ * AfterMe - Pointer to the node preceeding the node to be
+ * removed.
+ *
+ * Output: A pointer to the node that was removed, or NULL if the list is
+ * empty.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+
+/* ================================ The End ================================= */
+#endif /* UBI_SLINKLIST_H */
diff --git a/source/utils/net_groupmap.c b/source/utils/net_groupmap.c
index 1cff120c393..9e897d8efc7 100644
--- a/source/utils/net_groupmap.c
+++ b/source/utils/net_groupmap.c
@@ -87,15 +87,19 @@ static BOOL get_sid_from_input(DOM_SID *sid, char *input)
static void print_map_entry ( GROUP_MAP map, BOOL long_list )
{
+ fstring string_sid;
+ fstring group_type;
+
+ decode_sid_name_use(group_type, map.sid_name_use);
+ sid_to_string(string_sid, &map.sid);
+
if (!long_list)
- d_printf("%s (%s) -> %s\n", map.nt_name,
- sid_string_static(&map.sid), gidtoname(map.gid));
+ d_printf("%s (%s) -> %s\n", map.nt_name, string_sid, gidtoname(map.gid));
else {
d_printf("%s\n", map.nt_name);
- d_printf("\tSID : %s\n", sid_string_static(&map.sid));
+ d_printf("\tSID : %s\n", string_sid);
d_printf("\tUnix group: %s\n", gidtoname(map.gid));
- d_printf("\tGroup type: %s\n",
- sid_type_lookup(map.sid_name_use));
+ d_printf("\tGroup type: %s\n", group_type);
d_printf("\tComment : %s\n", map.comment);
}
@@ -122,19 +126,19 @@ static int net_groupmap_list(int argc, const char **argv)
else if ( !StrnCaseCmp(argv[i], "ntgroup", strlen("ntgroup")) ) {
fstrcpy( ntgroup, get_string_param( argv[i] ) );
if ( !ntgroup[0] ) {
- d_fprintf(stderr, "must supply a name\n");
+ d_printf("must supply a name\n");
return -1;
}
}
else if ( !StrnCaseCmp(argv[i], "sid", strlen("sid")) ) {
fstrcpy( sid_string, get_string_param( argv[i] ) );
if ( !sid_string[0] ) {
- d_fprintf(stderr, "must supply a SID\n");
+ d_printf("must supply a SID\n");
return -1;
}
}
else {
- d_fprintf(stderr, "Bad option: %s\n", argv[i]);
+ d_printf("Bad option: %s\n", argv[i]);
return -1;
}
}
@@ -153,7 +157,7 @@ static int net_groupmap_list(int argc, const char **argv)
/* Get the current mapping from the database */
if(!pdb_getgrsid(&map, sid)) {
- d_fprintf(stderr, "Failure to local group SID in the database\n");
+ d_printf("Failure to local group SID in the database\n");
return -1;
}
@@ -197,35 +201,35 @@ static int net_groupmap_add(int argc, const char **argv)
if ( !StrnCaseCmp(argv[i], "rid", strlen("rid")) ) {
rid = get_int_param(argv[i]);
if ( rid < DOMAIN_GROUP_RID_ADMINS ) {
- d_fprintf(stderr, "RID must be greater than %d\n", (uint32)DOMAIN_GROUP_RID_ADMINS-1);
+ d_printf("RID must be greater than %d\n", (uint32)DOMAIN_GROUP_RID_ADMINS-1);
return -1;
}
}
else if ( !StrnCaseCmp(argv[i], "unixgroup", strlen("unixgroup")) ) {
fstrcpy( unixgrp, get_string_param( argv[i] ) );
if ( !unixgrp[0] ) {
- d_fprintf(stderr, "must supply a name\n");
+ d_printf("must supply a name\n");
return -1;
}
}
else if ( !StrnCaseCmp(argv[i], "ntgroup", strlen("ntgroup")) ) {
fstrcpy( ntgroup, get_string_param( argv[i] ) );
if ( !ntgroup[0] ) {
- d_fprintf(stderr, "must supply a name\n");
+ d_printf("must supply a name\n");
return -1;
}
}
else if ( !StrnCaseCmp(argv[i], "sid", strlen("sid")) ) {
fstrcpy( string_sid, get_string_param( argv[i] ) );
if ( !string_sid[0] ) {
- d_fprintf(stderr, "must supply a SID\n");
+ d_printf("must supply a SID\n");
return -1;
}
}
else if ( !StrnCaseCmp(argv[i], "comment", strlen("comment")) ) {
fstrcpy( ntcomment, get_string_param( argv[i] ) );
if ( !ntcomment[0] ) {
- d_fprintf(stderr, "must supply a comment string\n");
+ d_printf("must supply a comment string\n");
return -1;
}
}
@@ -247,7 +251,7 @@ static int net_groupmap_add(int argc, const char **argv)
}
}
else {
- d_fprintf(stderr, "Bad option: %s\n", argv[i]);
+ d_printf("Bad option: %s\n", argv[i]);
return -1;
}
}
@@ -258,7 +262,7 @@ static int net_groupmap_add(int argc, const char **argv)
}
if ( (gid = nametogid(unixgrp)) == (gid_t)-1 ) {
- d_fprintf(stderr, "Can't lookup UNIX group %s\n", unixgrp);
+ d_printf("Can't lookup UNIX group %s\n", unixgrp);
return -1;
}
@@ -296,7 +300,7 @@ static int net_groupmap_add(int argc, const char **argv)
if (!add_initial_entry(gid, string_sid, sid_type, ntgroup, ntcomment)) {
- d_fprintf(stderr, "adding entry for group %s failed!\n", ntgroup);
+ d_printf("adding entry for group %s failed!\n", ntgroup);
return -1;
}
@@ -322,28 +326,28 @@ static int net_groupmap_modify(int argc, const char **argv)
if ( !StrnCaseCmp(argv[i], "ntgroup", strlen("ntgroup")) ) {
fstrcpy( ntgroup, get_string_param( argv[i] ) );
if ( !ntgroup[0] ) {
- d_fprintf(stderr, "must supply a name\n");
+ d_printf("must supply a name\n");
return -1;
}
}
else if ( !StrnCaseCmp(argv[i], "sid", strlen("sid")) ) {
fstrcpy( sid_string, get_string_param( argv[i] ) );
if ( !sid_string[0] ) {
- d_fprintf(stderr, "must supply a name\n");
+ d_printf("must supply a name\n");
return -1;
}
}
else if ( !StrnCaseCmp(argv[i], "comment", strlen("comment")) ) {
fstrcpy( ntcomment, get_string_param( argv[i] ) );
if ( !ntcomment[0] ) {
- d_fprintf(stderr, "must supply a comment string\n");
+ d_printf("must supply a comment string\n");
return -1;
}
}
else if ( !StrnCaseCmp(argv[i], "unixgroup", strlen("unixgroup")) ) {
fstrcpy( unixgrp, get_string_param( argv[i] ) );
if ( !unixgrp[0] ) {
- d_fprintf(stderr, "must supply a group name\n");
+ d_printf("must supply a group name\n");
return -1;
}
}
@@ -361,7 +365,7 @@ static int net_groupmap_modify(int argc, const char **argv)
}
}
else {
- d_fprintf(stderr, "Bad option: %s\n", argv[i]);
+ d_printf("Bad option: %s\n", argv[i]);
return -1;
}
}
@@ -388,7 +392,7 @@ static int net_groupmap_modify(int argc, const char **argv)
/* Get the current mapping from the database */
if(!pdb_getgrsid(&map, sid)) {
- d_fprintf(stderr, "Failure to local group SID in the database\n");
+ d_printf("Failure to local group SID in the database\n");
return -1;
}
@@ -398,7 +402,7 @@ static int net_groupmap_modify(int argc, const char **argv)
*/
if (sid_type != SID_NAME_UNKNOWN) {
if (map.sid_name_use == SID_NAME_WKN_GRP) {
- d_fprintf(stderr, "You can only change between domain and local groups.\n");
+ d_printf("You can only change between domain and local groups.\n");
return -1;
}
@@ -415,7 +419,7 @@ static int net_groupmap_modify(int argc, const char **argv)
if ( unixgrp[0] ) {
gid = nametogid( unixgrp );
if ( gid == -1 ) {
- d_fprintf(stderr, "Unable to lookup UNIX group %s. Make sure the group exists.\n",
+ d_printf("Unable to lookup UNIX group %s. Make sure the group exists.\n",
unixgrp);
return -1;
}
@@ -424,7 +428,7 @@ static int net_groupmap_modify(int argc, const char **argv)
}
if ( !pdb_update_group_mapping_entry(&map) ) {
- d_fprintf(stderr, "Could not update group database\n");
+ d_printf("Could not update group database\n");
return -1;
}
@@ -445,19 +449,19 @@ static int net_groupmap_delete(int argc, const char **argv)
if ( !StrnCaseCmp(argv[i], "ntgroup", strlen("ntgroup")) ) {
fstrcpy( ntgroup, get_string_param( argv[i] ) );
if ( !ntgroup[0] ) {
- d_fprintf(stderr, "must supply a name\n");
+ d_printf("must supply a name\n");
return -1;
}
}
else if ( !StrnCaseCmp(argv[i], "sid", strlen("sid")) ) {
fstrcpy( sid_string, get_string_param( argv[i] ) );
if ( !sid_string[0] ) {
- d_fprintf(stderr, "must supply a SID\n");
+ d_printf("must supply a SID\n");
return -1;
}
}
else {
- d_fprintf(stderr, "Bad option: %s\n", argv[i]);
+ d_printf("Bad option: %s\n", argv[i]);
return -1;
}
}
@@ -473,12 +477,12 @@ static int net_groupmap_delete(int argc, const char **argv)
fstrcpy( ntgroup, sid_string );
if ( !get_sid_from_input(&sid, ntgroup) ) {
- d_fprintf(stderr, "Unable to resolve group %s to a SID\n", ntgroup);
+ d_printf("Unable to resolve group %s to a SID\n", ntgroup);
return -1;
}
if ( !pdb_delete_group_mapping_entry(sid) ) {
- d_fprintf(stderr, "Failed to removing group %s from the mapping db!\n", ntgroup);
+ printf("Failed to removing group %s from the mapping db!\n", ntgroup);
return -1;
}
@@ -511,7 +515,7 @@ static int net_groupmap_set(int argc, const char **argv)
grp = getgrnam(argv[1]);
if (grp == NULL) {
- d_fprintf(stderr, "Could not find unix group %s\n", argv[1]);
+ d_printf("Could not find unix group %s\n", argv[1]);
return -1;
}
}
@@ -530,7 +534,7 @@ static int net_groupmap_set(int argc, const char **argv)
/* Ok, add it */
if (grp == NULL) {
- d_fprintf(stderr, "Could not find group mapping for %s\n",
+ d_printf("Could not find group mapping for %s\n",
ntgroup);
return -1;
}
@@ -549,7 +553,7 @@ static int net_groupmap_set(int argc, const char **argv)
fstrcpy(map.comment, "");
if (!pdb_add_group_mapping_entry(&map)) {
- d_fprintf(stderr, "Could not add mapping entry for %s\n",
+ d_printf("Could not add mapping entry for %s\n",
ntgroup);
return -1;
}
@@ -559,7 +563,7 @@ static int net_groupmap_set(int argc, const char **argv)
if ( opt_localgroup || opt_domaingroup ) {
if (map.sid_name_use == SID_NAME_WKN_GRP) {
- d_fprintf(stderr, "Can't change type of the BUILTIN group %s\n",
+ d_printf("Can't change type of the BUILTIN group %s\n",
map.nt_name);
return -1;
}
@@ -583,7 +587,7 @@ static int net_groupmap_set(int argc, const char **argv)
map.gid = grp->gr_gid;
if (!pdb_update_group_mapping_entry(&map)) {
- d_fprintf(stderr, "Could not update group mapping for %s\n", ntgroup);
+ d_printf("Could not update group mapping for %s\n", ntgroup);
return -1;
}
@@ -597,7 +601,7 @@ static int net_groupmap_cleanup(int argc, const char **argv)
if (!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &entries,
ENUM_ALL_MAPPED)) {
- d_fprintf(stderr, "Could not list group mappings\n");
+ d_printf("Could not list group mappings\n");
return -1;
}
@@ -634,7 +638,7 @@ static int net_groupmap_addmem(int argc, const char **argv)
}
if (!pdb_add_aliasmem(&alias, &member)) {
- d_fprintf(stderr, "Could not add sid %s to alias %s\n",
+ d_printf("Could not add sid %s to alias %s\n",
argv[1], argv[0]);
return -1;
}
@@ -654,7 +658,7 @@ static int net_groupmap_delmem(int argc, const char **argv)
}
if (!pdb_del_aliasmem(&alias, &member)) {
- d_fprintf(stderr, "Could not delete sid %s from alias %s\n",
+ d_printf("Could not delete sid %s from alias %s\n",
argv[1], argv[0]);
return -1;
}
@@ -678,7 +682,7 @@ static int net_groupmap_listmem(int argc, const char **argv)
num = 0;
if (!pdb_enum_aliasmem(&alias, &members, &num)) {
- d_fprintf(stderr, "Could not list members for sid %s\n", argv[0]);
+ d_printf("Could not list members for sid %s\n", argv[0]);
return -1;
}
@@ -703,7 +707,7 @@ static BOOL print_alias_memberships(TALLOC_CTX *mem_ctx,
if (!pdb_enum_alias_memberships(mem_ctx, domain_sid, member, 1,
&alias_rids, &num_alias_rids)) {
- d_fprintf(stderr, "Could not list memberships for sid %s\n",
+ d_printf("Could not list memberships for sid %s\n",
sid_string_static(member));
return False;
}
@@ -731,14 +735,14 @@ static int net_groupmap_memberships(int argc, const char **argv)
mem_ctx = talloc_init("net_groupmap_memberships");
if (mem_ctx == NULL) {
- d_fprintf(stderr, "talloc_init failed\n");
+ d_printf("talloc_init failed\n");
return -1;
}
domain_sid = get_global_sam_sid();
builtin_sid = string_sid_talloc(mem_ctx, "S-1-5-32");
if ((domain_sid == NULL) || (builtin_sid == NULL)) {
- d_fprintf(stderr, "Could not get domain sid\n");
+ d_printf("Could not get domain sid\n");
return -1;
}
@@ -800,7 +804,7 @@ int net_groupmap(int argc, const char **argv)
/* we shouldn't have silly checks like this */
if (getuid() != 0) {
- d_fprintf(stderr, "You must be root to edit group mappings.\nExiting...\n");
+ d_printf("You must be root to edit group mappings.\nExiting...\n");
return -1;
}
diff --git a/source/utils/net_idmap.c b/source/utils/net_idmap.c
index 0b5f68101ed..8109bef5225 100644
--- a/source/utils/net_idmap.c
+++ b/source/utils/net_idmap.c
@@ -59,7 +59,7 @@ static int net_idmap_dump(int argc, const char **argv)
idmap_tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDONLY, 0);
if (idmap_tdb == NULL) {
- d_fprintf(stderr, "Could not open idmap: %s\n", argv[0]);
+ d_printf("Could not open idmap: %s\n", argv[0]);
return -1;
}
@@ -102,7 +102,7 @@ static int net_idmap_find_max_id(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data,
}
if (idptr == NULL) {
- d_fprintf(stderr, "Illegal idmap entry: [%s]->[%s]\n",
+ d_printf("Illegal idmap entry: [%s]->[%s]\n",
key.dptr, data.dptr);
hwms->ok = False;
return -1;
@@ -132,7 +132,7 @@ static NTSTATUS net_idmap_fixup_hwm(void)
if (!lp_idmap_uid(&hwms.user_hwm, &highest.user_hwm) ||
!lp_idmap_gid(&hwms.group_hwm, &highest.group_hwm)) {
- d_fprintf(stderr, "idmap range missing\n");
+ d_printf("idmap range missing\n");
return NT_STATUS_UNSUCCESSFUL;
}
@@ -145,7 +145,7 @@ static NTSTATUS net_idmap_fixup_hwm(void)
idmap_tdb = tdb_open_log(tdbfile, 0, TDB_DEFAULT, O_RDWR, 0);
if (idmap_tdb == NULL) {
- d_fprintf(stderr, "Could not open idmap: %s\n", tdbfile);
+ d_printf("Could not open idmap: %s\n", tdbfile);
return NT_STATUS_NO_SUCH_FILE;
}
@@ -161,18 +161,18 @@ static NTSTATUS net_idmap_fixup_hwm(void)
hwms.user_hwm, hwms.group_hwm);
if (hwms.user_hwm >= highest.user_hwm) {
- d_fprintf(stderr, "Highest UID out of uid range\n");
+ d_printf("Highest UID out of uid range\n");
goto done;
}
if (hwms.group_hwm >= highest.group_hwm) {
- d_fprintf(stderr, "Highest GID out of gid range\n");
+ d_printf("Highest GID out of gid range\n");
goto done;
}
if ((tdb_store_int32(idmap_tdb, "USER HWM", (int32)hwms.user_hwm) != 0) ||
(tdb_store_int32(idmap_tdb, "GROUP HWM", (int32)hwms.group_hwm) != 0)) {
- d_fprintf(stderr, "Could not store HWMs\n");
+ d_printf("Could not store HWMs\n");
goto done;
}
@@ -188,7 +188,7 @@ static NTSTATUS net_idmap_fixup_hwm(void)
static int net_idmap_restore(int argc, const char **argv)
{
if (!idmap_init(lp_idmap_backend())) {
- d_fprintf(stderr, "Could not init idmap\n");
+ d_printf("Could not init idmap\n");
return -1;
}
@@ -230,7 +230,7 @@ static int net_idmap_restore(int argc, const char **argv)
}
if (!NT_STATUS_IS_OK(idmap_set_mapping(&sid, id, type))) {
- d_fprintf(stderr, "Could not set mapping of %s %lu to sid %s\n",
+ d_printf("Could not set mapping of %s %lu to sid %s\n",
(type == ID_GROUPID) ? "GID" : "UID",
(type == ID_GROUPID) ? (unsigned long)id.gid:
(unsigned long)id.uid,
@@ -260,14 +260,14 @@ static int net_idmap_delete(int argc, const char **argv)
idmap_tdb = tdb_open_log(argv[0], 0, TDB_DEFAULT, O_RDWR, 0);
if (idmap_tdb == NULL) {
- d_fprintf(stderr, "Could not open idmap: %s\n", argv[0]);
+ d_printf("Could not open idmap: %s\n", argv[0]);
return -1;
}
fstrcpy(sid, argv[1]);
if (strncmp(sid, "S-1-5-", strlen("S-1-5-")) != 0) {
- d_fprintf(stderr, "Can only delete SIDs, %s is does not start with "
+ d_printf("Can only delete SIDs, %s is does not start with "
"S-1-5-\n", sid);
return -1;
}
@@ -278,17 +278,17 @@ static int net_idmap_delete(int argc, const char **argv)
data = tdb_fetch(idmap_tdb, key);
if (data.dptr == NULL) {
- d_fprintf(stderr, "Could not find sid %s\n", argv[1]);
+ d_printf("Could not find sid %s\n", argv[1]);
return -1;
}
if (tdb_delete(idmap_tdb, key) != 0) {
- d_fprintf(stderr, "Could not delete key %s\n", argv[1]);
+ d_printf("Could not delete key %s\n", argv[1]);
return -1;
}
if (tdb_delete(idmap_tdb, data) != 0) {
- d_fprintf(stderr, "Could not delete key %s\n", data.dptr);
+ d_printf("Could not delete key %s\n", data.dptr);
return -1;
}
diff --git a/source/utils/net_lookup.c b/source/utils/net_lookup.c
index 8ee63515d45..cd62245600d 100644
--- a/source/utils/net_lookup.c
+++ b/source/utils/net_lookup.c
@@ -211,7 +211,7 @@ static int net_lookup_kdc(int argc, const char **argv)
realm.length = strlen(realm.data);
}
- rc = krb5_locate_kdc(ctx, &realm, (struct sockaddr **)(void *)&addrs, &num_kdcs, 0);
+ rc = krb5_locate_kdc(ctx, &realm, (struct sockaddr **) &addrs, &num_kdcs, 0);
if (rc) {
DEBUG(1, ("krb5_locate_kdc failed (%s)\n", error_message(rc)));
return -1;
diff --git a/source/utils/smbget.c b/source/utils/smbget.c
index 4a2670e0c16..eab5e5ac02f 100644
--- a/source/utils/smbget.c
+++ b/source/utils/smbget.c
@@ -22,10 +22,8 @@
#if _FILE_OFFSET_BITS==64
#define OFF_T_FORMAT "%lld"
-#define OFF_T_FORMAT_CAST long long
#else
#define OFF_T_FORMAT "%ld"
-#define OFF_T_FORMAT_CAST long
#endif
int columns = 0;
@@ -78,7 +76,7 @@ void human_readable(off_t s, char *buffer, int l)
if(s > 1024 * 1024 * 1024) snprintf(buffer, l, "%.2fGb", 1.0 * s / (1024 * 1024 * 1024));
else if(s > 1024 * 1024) snprintf(buffer, l, "%.2fMb", 1.0 * s / (1024 * 1024));
else if(s > 1024) snprintf(buffer, l, "%.2fkb", 1.0 * s / 1024);
- else snprintf(buffer, l, OFF_T_FORMAT"b", (OFF_T_FORMAT_CAST)s);
+ else snprintf(buffer, l, OFF_T_FORMAT"b", s);
}
void get_auth_data(const char *srv, const char *shr, char *wg, int wglen, char *un, int unlen, char *pw, int pwlen)
@@ -329,10 +327,8 @@ int smb_download_file(const char *base, const char *name, int recursive, int res
offset_download = localstat.st_size - RESUME_DOWNLOAD_OFFSET;
offset_check = localstat.st_size - RESUME_CHECK_OFFSET;
if(verbose)printf("Trying to start resume of %s at "OFF_T_FORMAT"\n"
- "At the moment "OFF_T_FORMAT" of "OFF_T_FORMAT" bytes have been retrieved\n",
- newpath, (OFF_T_FORMAT_CAST)offset_check,
- (OFF_T_FORMAT_CAST)localstat.st_size,
- (OFF_T_FORMAT_CAST)remotestat.st_size);
+ "At the moment "OFF_T_FORMAT" of "OFF_T_FORMAT" bytes have been retrieved\n", newpath, offset_check,
+ localstat.st_size, remotestat.st_size);
}
if(offset_check) {
@@ -340,24 +336,20 @@ int smb_download_file(const char *base, const char *name, int recursive, int res
/* First, check all bytes from offset_check to offset_download */
off1 = lseek(localhandle, offset_check, SEEK_SET);
if(off1 < 0) {
- fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in local file %s\n",
- (OFF_T_FORMAT_CAST)offset_check, newpath);
+ fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in local file %s\n", offset_check, newpath);
smbc_close(remotehandle); close(localhandle);
return 0;
}
off2 = smbc_lseek(remotehandle, offset_check, SEEK_SET);
if(off2 < 0) {
- fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in remote file %s\n",
- (OFF_T_FORMAT_CAST)offset_check, newpath);
+ fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in remote file %s\n", offset_check, newpath);
smbc_close(remotehandle); close(localhandle);
return 0;
}
if(off1 != off2) {
- fprintf(stderr, "Offset in local and remote files is different (local: "OFF_T_FORMAT", remote: "OFF_T_FORMAT")\n",
- (OFF_T_FORMAT_CAST)off1,
- (OFF_T_FORMAT_CAST)off2);
+ fprintf(stderr, "Offset in local and remote files is different (local: "OFF_T_FORMAT", remote: "OFF_T_FORMAT")\n", off1, off2);
return 0;
}
@@ -374,7 +366,7 @@ int smb_download_file(const char *base, const char *name, int recursive, int res
}
if(memcmp(checkbuf[0], checkbuf[1], RESUME_CHECK_SIZE) == 0) {
- if(verbose)printf("Current local and remote file appear to be the same. Starting download from offset "OFF_T_FORMAT"\n", (OFF_T_FORMAT_CAST)offset_download);
+ if(verbose)printf("Current local and remote file appear to be the same. Starting download from offset "OFF_T_FORMAT"\n", offset_download);
} else {
fprintf(stderr, "Local and remote file appear to be different, not doing resume for %s\n", path);
smbc_close(remotehandle); close(localhandle);
@@ -394,7 +386,7 @@ int smb_download_file(const char *base, const char *name, int recursive, int res
for(curpos = offset_download; curpos < remotestat.st_size; curpos+=blocksize) {
ssize_t bytesread = smbc_read(remotehandle, readbuf, blocksize);
if(bytesread < 0) {
- fprintf(stderr, "Can't read %u bytes at offset "OFF_T_FORMAT", file %s\n", (unsigned int)blocksize, (OFF_T_FORMAT_CAST)curpos, path);
+ fprintf(stderr, "Can't read %d bytes at offset "OFF_T_FORMAT", file %s\n", blocksize, curpos, path);
smbc_close(remotehandle);
if (localhandle != STDOUT_FILENO) close(localhandle);
free(readbuf);
@@ -404,7 +396,7 @@ int smb_download_file(const char *base, const char *name, int recursive, int res
total_bytes += bytesread;
if(write(localhandle, readbuf, bytesread) < 0) {
- fprintf(stderr, "Can't write %u bytes to local file %s at offset "OFF_T_FORMAT"\n", (unsigned int)bytesread, path, (OFF_T_FORMAT_CAST)curpos);
+ fprintf(stderr, "Can't write %d bytes to local file %s at offset "OFF_T_FORMAT"\n", bytesread, path, curpos);
free(readbuf);
smbc_close(remotehandle);
if (localhandle != STDOUT_FILENO) close(localhandle);
@@ -544,8 +536,6 @@ int main(int argc, const char **argv)
};
poptContext pc;
- load_case_tables();
-
/* only read rcfile if it exists */
asprintf(&rcfile, "%s/.smbgetrc", getenv("HOME"));
if(access(rcfile, F_OK) == 0)
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c
index 7659bb2997a..708d44df9f0 100644
--- a/source/utils/smbpasswd.c
+++ b/source/utils/smbpasswd.c
@@ -92,7 +92,7 @@ static int process_options(int argc, char **argv, int local_flags)
user_name[0] = '\0';
- while ((ch = getopt(argc, argv, "c:axdehminjr:sw:R:D:U:LW")) != EOF) {
+ while ((ch = getopt(argc, argv, "c:axdehminjr:sw:R:D:U:L")) != EOF) {
switch(ch) {
case 'L':
local_flags |= LOCAL_AM_ROOT;
@@ -153,10 +153,6 @@ static int process_options(int argc, char **argv, int local_flags)
got_username = True;
fstrcpy(user_name, optarg);
break;
- case 'W':
- local_flags |= LOCAL_SET_LDAP_ADMIN_PW;
- *ldap_secret = '\0';
- break;
}
case 'h':
default:
@@ -329,10 +325,6 @@ static int process_root(int local_flags)
if (local_flags & LOCAL_SET_LDAP_ADMIN_PW) {
printf("Setting stored password for \"%s\" in secrets.tdb\n",
lp_ldap_admin_dn());
- if ( ! *ldap_secret ) {
- new_passwd = prompt_for_new_password(stdin_passwd_get);
- fstrcpy(ldap_secret, new_passwd);
- }
if (!store_ldap_admin_pw(ldap_secret))
DEBUG(0,("ERROR: Failed to store the ldap admin password!\n"));
goto done;
@@ -577,8 +569,6 @@ int main(int argc, char **argv)
local_flags = LOCAL_AM_ROOT;
}
- load_case_tables();
-
local_flags = process_options(argc, argv, local_flags);
setup_logging("smbpasswd", True);