From 6c43e50ecd10fb085b4c3dbb83560c759980f917 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 2 Dec 2005 13:33:07 +0000 Subject: r12017: starting the sync up for 3.0.21. Gotten through r11915 so far. Jeremy, This is turning out ot be more changes that I anticipated and may end up being a full sync. But the changes appear sar or on a non-default code path. --- WHATSNEW.txt | 350 +++++++++++----------- examples/VFS/skel_opaque.c | 2 +- source/Makefile.in | 2 +- source/VERSION | 2 +- source/auth/auth_sam.c | 5 +- source/client/client.c | 5 +- source/client/smbspool.c | 14 +- source/configure.in | 40 ++- source/include/includes.h | 9 + source/include/libsmbclient.h | 7 - source/include/rpc_eventlog.h | 10 + source/include/rpc_samr.h | 18 +- source/lib/crc32.c | 2 +- source/lib/smbldap.c | 202 +++++++++---- source/lib/snprintf.c | 23 +- source/lib/system.c | 54 ++-- source/libads/kerberos_verify.c | 6 +- source/libads/ldap.c | 13 +- source/nsswitch/winbind_nss_solaris.c | 4 +- source/nsswitch/winbindd.h | 3 - source/nsswitch/winbindd_ads.c | 37 --- source/nsswitch/winbindd_cache.c | 13 - source/nsswitch/winbindd_misc.c | 3 +- source/nsswitch/winbindd_pam.c | 2 +- source/nsswitch/winbindd_passdb.c | 12 - source/nsswitch/winbindd_reconnect.c | 14 - source/nsswitch/winbindd_rpc.c | 8 - source/param/loadparm.c | 8 +- source/passdb/pdb_ldap.c | 2 +- source/passdb/pdb_nds.c | 54 +--- source/rpc_client/cli_lsarpc.c | 2 +- source/rpc_parse/parse_eventlog.c | 2 +- source/rpc_parse/parse_samr.c | 26 +- source/rpc_server/srv_eventlog_lib.c | 107 ++++--- source/rpc_server/srv_eventlog_nt.c | 235 ++++++++------- source/rpc_server/srv_samr.c | 20 +- source/rpc_server/srv_samr_nt.c | 539 ++++++++++++++++++++++++++-------- source/rpc_server/srv_util.c | 2 +- source/rpcclient/cmd_lsarpc.c | 2 +- source/rpcclient/cmd_samr.c | 15 +- source/script/installman.sh | 17 +- source/script/mkproto.awk | 2 +- source/services/services_db.c | 72 +++-- source/smbd/dosmode.c | 2 +- source/smbd/filename.c | 18 +- source/smbd/session.c | 3 +- source/smbd/sesssetup.c | 33 +++ source/utils/eventlogadm.c | 8 +- source/utils/net_lookup.c | 4 +- source/utils/smbget.c | 24 +- 50 files changed, 1268 insertions(+), 789 deletions(-) diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 91ed878e93f..479c86f9f40 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,19 +1,31 @@ - ================================= - Release Notes for Samba 3.0.21rc1 - Nov 12, 2005 - ================================= + ============================== + Release Notes for Samba 3.0.21 + Dec 3, 2005 + ============================== -This is a release candidate of the 3.0.21 code base and is provided -for testing purposes only. While close to the final stable release, -this snapshot is *not* intended for production servers. +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. Common bugs fixed in 3.0.21rc1 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.21rc1 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. @@ -30,15 +42,122 @@ smb.conf changes -------------- ------ dfree cache time New dfree command Per share + eventlog list New + iprint server New + map read only New + rename user script New + reset on zero vc New + svcctl list Renamed from 'enable svcctl' -Changes since 3.0.21pre1 +Changes since 3.0.21rc1 ------------------------ commits ------- +o Jeremy Allison + * Remove #define of close -> close_fn maxcor 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). + + +o Rashid N. Achilov + * Add better service description names to the svcctl code. + + +o Timur Bakeyev + * BUG 3262: Improve FreeBSD DOS attribute error reporting. + + +o Gerald (Jerry) Carter + * 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. + + +o Alex Deiter + * BUG 3196: Patch to compile against the Sun LDAP client libs. + (not for AD support; just ldap support). + + +o Guenther Deschner + * Avoid an inifinite loop when retying 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. + * Cleanup redundant StartTLS code. + * Allow StartTLS support when connecting to Windows 2003 by + setting 'ldap ssl = start_tls'. + + +o Volker Lendecke + * Removed unused alternative_name cocde from winbindd. + * Protect against NULL alternative_name strings in winbindd. + * Define a default panic action with -DEVELOPER is defined. + * Add the capability ot reset smbd connections on a zero VC id. + + +o Jim McDonough + * BUG 3187: Fix time zone offset in logon hours restrictions. + + +o Lars Müller + * Only install smbsh manpage if smbwrapper has been successfully + built. + + +o Tim Potter + * BUG 3260: Fix DYNEXP flags on HPUX. + + +o Aruna Prabakar + o Crash fix for snprintf() code. + + +o Rainer Weikusat + * Fix function name typo in skeleton VFS code. + + + +Changes since 3.0.20b +--------------------- o Jeremy Allison + * 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. @@ -83,6 +202,23 @@ o Alexander Bokovoy o Gerald (Jerry) Carter + * 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 @@ -110,6 +246,18 @@ o Gerald (Jerry) Carter o Guenther Deschner + * 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. @@ -119,7 +267,18 @@ o Paul Green * Update to the latest config.guess and config.sub files. +o Deryck Hodge + * Allow control of syslog facility and level in audit vfs modules. + + +o S Murthy Kambhampaty + * Patches for Fedora RPM specfile and init script + + o Volker Lendecke + * 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. @@ -141,6 +300,10 @@ o Derrell Lipman * Cleanup libmsrpc version numbers. +o Jason Mader + * Removed compiler various warnings. + + o Alex Masterov * BUG 3218: Fix XATTR calls on *BSD systems. @@ -149,189 +312,42 @@ o Jim McDonough * 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 o Stefan Metzmacher + * 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 + * 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. -o Lars Müller - * Only install smbsh manpage if smbwrapper has been successfully - built. - - o Ricky Nance * Updates for the mklogon perl scripts. o Chris Nicholls + * New libmsrpc library (Google SoC Project). * Fix libmsrpc build of on the Sun compiler by removing empty structure declarations. -o Marcin Porwit - * Added basic Performance Counter daemon which can feed data - for the Windows perfmon.exe tool. - - -o Simo Sorce - * Update Debian packaging. - - - -Release Notes for older release follow: - - -------------------------------------------------- - - ================================== - Release Notes for Samba 3.0.21pre1 - Oct 18, 2005 - ================================== - - -Common bugs fixed in 3.0.21pre1 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 - -New features introduced in Samba 3.0.21pre1 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. - - -###################################################################### -Changes -####### - -smb.conf changes ----------------- - - Parameter Name Action - -------------- ------ - eventlog list New - iprint server New - map read only New - rename user script New - svcctl list Renamed from 'enable svcctl' - - -Changes since 3.0.20[a-b] -------------------------- - -commits -------- - -o Jeremy Allison - * 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 - - -o Gerald (Jerry) Carter - * 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 - - -o Guenther Deschner - * 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 - - -o Deryck Hodge - * Allow control of syslog facility and level in audit vfs modules. - - -o S Murthy Kambhampaty - * Patches for Fedora RPM specfile and init script - - -o Volker Lendecke - * New oplock implementation. - * Add assert() call if winbindd cannot locate the domain SID in - secrets.tdb on startup - - -o Jason Mader - * Removed compiler various warnings. - - -o Jim McDonough - * BUG 2961 (partial): Add rename support for user accounts to tdbsam - - -o Stefan Metzmacher - * Fix setting of quotas on linux kernel with the struct - if_dqblk interface - * Enable sysquota interfact on Linux by default - - -o Brian Moran - * Eventlog and ServiceControl support. - * Added eventlogadm tool for writing Eventlog records. - - -o Chris Nicholls - * New libmsrpc library (Google SoC Project). - - o James Peach * Fix parsing error for smb ports parameter. o Marcin Porwit * Eventlog and ServiceControl support. + * Added basic Performance Counter daemon which can feed data + for the Windows perfmon.exe tool. o Joel Smith @@ -342,6 +358,12 @@ o Toomas Soome * Implement host lookups in nss_winbind.so.1 on Solaris +o Simo Sorce + * Update Debian packaging. + + +Release Notes for older release follow: + -------------------------------------------------- =============================== Release Notes for Samba 3.0.20b diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index e6b7d032fcf..e6af475da6e 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -524,7 +524,7 @@ static int skel_aio_fsync(struct vfs_handle_struct *handle, struct files_struct static int skel_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *ts) { - return vfswrap_aioi_suspend(NULL, fsp, aiocb, n, ts); + return vfswrap_aio_suspend(NULL, fsp, aiocb, n, ts); } /* VFS operations structure */ diff --git a/source/Makefile.in b/source/Makefile.in index 6a12b2e25e9..cca0715a3aa 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -128,7 +128,7 @@ PATH_FLAGS = $(PATH_FLAGS6) $(PASSWD_FLAGS) SBIN_PROGS = bin/smbd@EXEEXT@ bin/nmbd@EXEEXT@ bin/swat@EXEEXT@ @EXTRA_SBIN_PROGS@ BIN_PROGS1 = bin/smbclient@EXEEXT@ bin/net@EXEEXT@ bin/smbspool@EXEEXT@ \ - bin/testparm@EXEEXT@ bin/smbstatus@EXEEXT@ + bin/testparm@EXEEXT@ bin/smbstatus@EXEEXT@ bin/smbget@EXEEXT@ BIN_PROGS2 = bin/smbcontrol@EXEEXT@ bin/smbtree@EXEEXT@ bin/tdbbackup@EXEEXT@ \ bin/nmblookup@EXEEXT@ bin/pdbedit@EXEEXT@ bin/tdbdump@EXEEXT@ \ bin/tdbtool@EXEEXT@ diff --git a/source/VERSION b/source/VERSION index c377386a9c4..9895f797c4d 100644 --- a/source/VERSION +++ b/source/VERSION @@ -51,7 +51,7 @@ SAMBA_VERSION_PRE_RELEASE= # e.g. SAMBA_VERSION_RC_RELEASE=1 # # -> "3.0.0rc1" # ######################################################## -SAMBA_VERSION_RC_RELEASE=1 +SAMBA_VERSION_RC_RELEASE= ######################################################## # To mark SVN snapshots this should be set to 'yes' # diff --git a/source/auth/auth_sam.c b/source/auth/auth_sam.c index c92cecdde59..558c181f704 100644 --- a/source/auth/auth_sam.c +++ b/source/auth/auth_sam.c @@ -88,7 +88,7 @@ static BOOL logon_hours_ok(SAM_ACCOUNT *sampass) } lasttime = (time_t)smb_last_time.tv_sec; - utctime = localtime(&lasttime); + utctime = gmtime(&lasttime); /* find the corresponding byte and bit */ bitpos = (utctime->tm_wday * 24 + utctime->tm_hour) % 168; @@ -96,7 +96,8 @@ static BOOL logon_hours_ok(SAM_ACCOUNT *sampass) if (! (hours[bitpos/8] & bitmask)) { DEBUG(1,("logon_hours_ok: Account for user %s not allowed to logon at this time (%s).\n", - pdb_get_username(sampass), asctime(utctime) )); + pdb_get_username(sampass), + asctime(localtime(&lasttime)) )); return False; } diff --git a/source/client/client.c b/source/client/client.c index f849738da0a..47a45b8a53b 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -288,9 +288,10 @@ static int do_cd(char *newdir) if ( strequal(targetpath,"\\" ) ) return 0; - /* use a trans2_qpathinfo to test directories for modern servers */ + /* Use a trans2_qpathinfo to test directories for modern servers. + Except Win9x doesn't support the qpathinfo_basic() call..... */ - if ( targetcli->protocol >= PROTOCOL_LANMAN2 ) { + if ( targetcli->protocol > PROTOCOL_LANMAN2 && !targetcli->win95 ) { if ( !cli_qpathinfo_basic( targetcli, targetpath, &sbuf, &attributes ) ) { d_printf("cd %s: %s\n", dname, cli_errstr(targetcli)); pstrcpy(cur_dir,saved_dir); diff --git a/source/client/smbspool.c b/source/client/smbspool.c index da517297f71..aff241adeed 100644 --- a/source/client/smbspool.c +++ b/source/client/smbspool.c @@ -30,6 +30,7 @@ #define CC_MAX_FILE_PATH_LEN (sizeof(TICKET_CC_DIR)-1)+ CC_MAX_FILE_LEN+2 #define OVERWRITE 1 #define KRB5CCNAME "KRB5CCNAME" +#define MAX_RETRY_CONNECT 3 /* @@ -71,6 +72,7 @@ static int smb_print(struct cli_state *, char *, FILE *); int status=0; /* Status of LPD job */ struct cli_state *cli; /* SMB interface */ char null_str[1]; + int tries = 0; null_str[0] = '\0'; @@ -229,17 +231,23 @@ static int smb_print(struct cli_state *, char *, FILE *); { if (getenv("CLASS") == NULL) { - fprintf(stderr, "ERROR: Unable to connect to CIFS host, will retry in 60 seconds..."); + fprintf(stderr, "ERROR: Unable to connect to CIFS host, will retry in 60 seconds...\n"); sleep (60); /* should just waiting and retrying fix authentication ??? */ + tries++; } else { - fprintf(stderr, "ERROR: Unable to connect to CIFS host, trying next printer..."); + fprintf(stderr, "ERROR: Unable to connect to CIFS host, trying next printer...\n"); return (1); } } } - while (cli == NULL); + while ((cli == NULL) && (tries < MAX_RETRY_CONNECT)); + + if (cli == NULL) { + fprintf(stderr, "ERROR: Unable to connect to CIFS host after (tried %d times)\n", tries); + return (1); + } /* * Now that we are connected to the server, ignore SIGTERM so that we diff --git a/source/configure.in b/source/configure.in index eb1974ccf7a..296673e4b53 100644 --- a/source/configure.in +++ b/source/configure.in @@ -1480,10 +1480,10 @@ if test "$enable_shared" = "yes"; then fi if test "$host_cpu" = "ia64"; then SHLIBEXT="so" - DYNEXP="-Wl,-E,+b /usr/local/lib/hpux32:/usr/lib/hpux32" + DYNEXP="-Wl,-E,+b/usr/local/lib/hpux32:/usr/lib/hpux32" else SHLIBEXT="sl" - DYNEXP="-Wl,-E,+b /usr/local/lib:/usr/lib" + DYNEXP="-Wl,-E,+b/usr/local/lib:/usr/lib" fi AC_DEFINE(STAT_ST_BLOCKSIZE,8192,[The size of a block]) AC_DEFINE(POSIX_ACL_NEEDS_MASK,1,[Does a POSIX ACL need a mask element]) @@ -2796,8 +2796,6 @@ if test x"$with_ldap_support" != x"no"; then # now see if we can find the ldap libs in standard paths AC_CHECK_LIB_EXT(ldap, LDAP_LIBS, ldap_init) - AC_CHECK_FUNC_EXT(ldap_domain2hostlist,$LDAP_LIBS) - ######################################################## # If we have LDAP, does it's rebind procedure take 2 or 3 arguments? # Check found in pam_ldap 145. @@ -2816,9 +2814,7 @@ if test x"$with_ldap_support" != x"no"; then AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $smb_ldap_cv_ldap_set_rebind_proc, [Number of arguments to ldap_set_rebind_proc]) - AC_CHECK_FUNC_EXT(ldap_initialize,$LDAP_LIBS) - - if test x"$ac_cv_lib_ext_ldap_ldap_init" = x"yes" -a x"$ac_cv_func_ext_ldap_domain2hostlist" = x"yes"; then + if test x"$ac_cv_lib_ext_ldap_ldap_init" = x"yes"; then AC_DEFINE(HAVE_LDAP,1,[Whether ldap is available]) CPPFLAGS="$CPPFLAGS -DLDAP_DEPRECATED" default_static_modules="$default_static_modules pdb_ldap idmap_ldap"; @@ -2870,6 +2866,36 @@ if test x"$with_ldap_support" != x"yes"; then with_ads_support=no fi +AC_CHECK_FUNC_EXT(ldap_initialize,$LDAP_LIBS) + +if test x"$ac_cv_func_ext_ldap_initialize" != x"yes"; then + if test x"$with_ads_support" = x"yes"; then + AC_MSG_ERROR(Active Directory Support requires ldap_initialize) + fi + AC_MSG_WARN(Active Directory Support requires ldap_initialize) + with_ads_support=no +fi + +AC_CHECK_FUNC_EXT(ldap_domain2hostlist,$LDAP_LIBS) + +if test x"$ac_cv_func_ext_ldap_domain2hostlist" != x"yes"; then + if test x"$with_ads_support" = x"yes"; then + AC_MSG_ERROR(Active Directory Support requires ldap_domain2hostlist) + fi + AC_MSG_WARN(Active Directory Support requires ldap_domain2hostlist) + with_ads_support=no +fi + +AC_CHECK_FUNC_EXT(ldap_add_result_entry,$LDAP_LIBS) + +if test x"$ac_cv_func_ext_ldap_add_result_entry" != x"yes"; then + if test x"$with_ads_support" = x"yes"; then + AC_MSG_ERROR(Active Directory Support requires ldap_add_result_entry) + fi + AC_MSG_WARN(Active Directory Support requires ldap_add_result_entry) + with_ads_support=no +fi + if test x"$with_ads_support" != x"no"; then # Do no harm to the values of CFLAGS and LIBS while testing for diff --git a/source/include/includes.h b/source/include/includes.h index 626124523e5..cde199eed8b 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -458,10 +458,19 @@ #if HAVE_LBER_H #include +#ifndef LBER_USE_DER +#define LBER_USE_DER 0x01 +#endif #endif #if HAVE_LDAP_H #include +#ifndef LDAP_CONST +#define LDAP_CONST const +#endif +#ifndef LDAP_OPT_SUCCESS +#define LDAP_OPT_SUCCESS 0 +#endif #else #undef HAVE_LDAP #endif diff --git a/source/include/libsmbclient.h b/source/include/libsmbclient.h index 46896d68e48..6d3a0cda09d 100644 --- a/source/include/libsmbclient.h +++ b/source/include/libsmbclient.h @@ -339,13 +339,6 @@ typedef int (*smbc_remove_cached_srv_fn)(SMBCCTX * c, SMBCSRV *srv); typedef int (*smbc_purge_cached_fn) (SMBCCTX * c); -/* close was renamed to close_fn, because close is often a macro. - * Allow backward compatability where this is not the case */ -#ifndef close -#define close close_fn -#endif - - /**@ingroup structure * Structure that contains a client context information * This structure is know as SMBCCTX diff --git a/source/include/rpc_eventlog.h b/source/include/rpc_eventlog.h index 67e03edbc6e..5bede97d1c9 100644 --- a/source/include/rpc_eventlog.h +++ b/source/include/rpc_eventlog.h @@ -57,6 +57,16 @@ #define ELOG_SYS "System" #define ELOG_SEC "Security" +typedef struct elog_tdb { + struct elog_tdb *prev, *next; + char *name; + TDB_CONTEXT *tdb; + int ref_count; +} ELOG_TDB; + +#define ELOG_TDB_CTX(x) ((x)->tdb) + + #define EVENTLOG_DATABASE_VERSION_V1 1 /***********************************/ diff --git a/source/include/rpc_samr.h b/source/include/rpc_samr.h index 6067587654e..f19de2ef4fc 100644 --- a/source/include/rpc_samr.h +++ b/source/include/rpc_samr.h @@ -126,7 +126,7 @@ SamrTestPrivateFunctionsUser #define SAMR_UNKNOWN_2b 0x2b #define SAMR_GET_USRDOM_PWINFO 0x2c #define SAMR_REMOVE_SID_FOREIGN_DOMAIN 0x2d -#define SAMR_UNKNOWN_2E 0x2e /* looks like an alias for SAMR_QUERY_DOMAIN_INFO */ +#define SAMR_QUERY_DOMAIN_INFO2 0x2e /* looks like an alias for SAMR_QUERY_DOMAIN_INFO */ #define SAMR_UNKNOWN_2f 0x2f #define SAMR_QUERY_DISPINFO3 0x30 /* Alias for SAMR_QUERY_DISPINFO with info level 3 */ @@ -1064,7 +1064,7 @@ typedef struct samr_group_info1 { UNIHDR hdr_acct_name; - uint32 unknown_1; /* 0x0000 0003 - number of group members? */ + uint32 group_attr; /* 0x0000 0003 - group attribute */ uint32 num_members; /* 0x0000 0001 - number of group members? */ UNIHDR hdr_acct_desc; @@ -1084,7 +1084,7 @@ typedef struct samr_group_info2 typedef struct samr_group_info3 { - uint32 unknown_1; /* 0x0000 0003 - number of group members? */ + uint32 group_attr; /* 0x0000 0003 - group attribute */ } GROUP_INFO3; @@ -1813,23 +1813,23 @@ typedef struct sid_info_3 } DOM_SID3; -/* SAMR_Q_UNKNOWN_2E */ -typedef struct q_samr_unknown_2e_info +/* SAMR_Q_QUERY_DOMAIN_INFO2 */ +typedef struct q_samr_query_domain_info2 { POLICY_HND domain_pol; /* policy handle */ uint16 switch_value; -} SAMR_Q_UNKNOWN_2E; +} SAMR_Q_QUERY_DOMAIN_INFO2; -/* SAMR_R_UNKNOWN_2E */ -typedef struct r_samr_unknown_2e_info +/* SAMR_R_QUERY_DOMAIN_INFO2 */ +typedef struct r_samr_query_domain_info2 { uint32 ptr_0; uint16 switch_value; SAM_UNK_CTR *ctr; NTSTATUS status; /* return status */ -} SAMR_R_UNKNOWN_2E; +} SAMR_R_QUERY_DOMAIN_INFO2; /* SAMR_Q_SET_DOMAIN_INFO */ typedef struct q_samr_set_domain_info diff --git a/source/lib/crc32.c b/source/lib/crc32.c index c6a13fada12..7522ab7c811 100644 --- a/source/lib/crc32.c +++ b/source/lib/crc32.c @@ -42,7 +42,7 @@ #include "includes.h" -const uint32 crc32_tab[] = { +static const uint32 crc32_tab[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, diff --git a/source/lib/smbldap.c b/source/lib/smbldap.c index f08a67a22c8..a3ebe72df21 100644 --- a/source/lib/smbldap.c +++ b/source/lib/smbldap.c @@ -523,24 +523,56 @@ static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state) t->smbldap_state = smbldap_state; } -/******************************************************************* - open a connection to the ldap server. -******************************************************************/ -static int smbldap_open_connection (struct smbldap_state *ldap_state) +/******************************************************************** + start TLS on an existing LDAP connection +*******************************************************************/ + +int smb_ldap_start_tls(LDAP *ldap_struct, int version) +{ + int rc; + + if (lp_ldap_ssl() != LDAP_SSL_START_TLS) { + return LDAP_SUCCESS; + } + +#ifdef LDAP_OPT_X_TLS + if (version != LDAP_VERSION3) { + DEBUG(0, ("Need LDAPv3 for Start TLS\n")); + return LDAP_OPERATIONS_ERROR; + } + + if ((rc = ldap_start_tls_s (ldap_struct, NULL, NULL)) != LDAP_SUCCESS) { + DEBUG(0,("Failed to issue the StartTLS instruction: %s\n", + ldap_err2string(rc))); + return rc; + } + + DEBUG (3, ("StartTLS issued: using a TLS connection\n")); + return LDAP_SUCCESS; +#else + DEBUG(0,("StartTLS not supported by LDAP client libraries!\n")); + return LDAP_OPERATIONS_ERROR; +#endif +} +/******************************************************************** + setup a connection to the LDAP server based on a uri +*******************************************************************/ + +int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri) { - int rc = LDAP_SUCCESS; - int version; - BOOL ldap_v3 = False; - LDAP **ldap_struct = &ldap_state->ldap_struct; + int rc; + DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri)); + #ifdef HAVE_LDAP_INITIALIZE - DEBUG(10, ("smbldap_open_connection: %s\n", ldap_state->uri)); - if ((rc = ldap_initialize(ldap_struct, ldap_state->uri)) != LDAP_SUCCESS) { + rc = ldap_initialize(ldap_struct, uri); + if (rc) { DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc))); - return rc; } + + return rc; #else /* Parse the string manually */ @@ -549,15 +581,15 @@ static int smbldap_open_connection (struct smbldap_state *ldap_state) int port = 0; fstring protocol; fstring host; - const char *p = ldap_state->uri; SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254); - + + /* skip leading "URL:" (if any) */ - if ( strnequal( p, "URL:", 4 ) ) { - p += 4; + if ( strnequal( uri, "URL:", 4 ) ) { + uri += 4; } - sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, host, &port); + sscanf(uri, "%10[^:]://%254[^:/]:%d", protocol, host, &port); if (port == 0) { if (strequal(protocol, "ldap")) { @@ -586,10 +618,88 @@ static int smbldap_open_connection (struct smbldap_state *ldap_state) #else DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n")); return LDAP_OPERATIONS_ERROR; -#endif +#endif /* LDAP_OPT_X_TLS */ } + + } +#endif /* HAVE_LDAP_INITIALIZE */ + return LDAP_SUCCESS; +} + +/******************************************************************** + try to upgrade to Version 3 LDAP if not already, in either case return current + version + *******************************************************************/ + +int smb_ldap_upgrade_conn(LDAP *ldap_struct, int *new_version) +{ + int version; + int rc; + + /* assume the worst */ + *new_version = LDAP_VERSION2; + + rc = ldap_get_option(ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version); + if (rc) { + return rc; + } + + if (version == LDAP_VERSION3) { + *new_version = LDAP_VERSION3; + return LDAP_SUCCESS; + } + + /* try upgrade */ + version = LDAP_VERSION3; + rc = ldap_set_option (ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version); + if (rc) { + return rc; + } + + *new_version = LDAP_VERSION3; + return LDAP_SUCCESS; +} + +/******************************************************************* + open a connection to the ldap server (just until the bind) + ******************************************************************/ + +int smb_ldap_setup_full_conn(LDAP *ldap_struct, const char *uri) +{ + int rc, version; + + rc = smb_ldap_setup_conn(&ldap_struct, uri); + if (rc) { + return rc; + } + + rc = smb_ldap_upgrade_conn(ldap_struct, &version); + if (rc) { + return rc; + } + + rc = smb_ldap_start_tls(ldap_struct, version); + if (rc) { + return rc; + } + + return LDAP_SUCCESS; +} + +/******************************************************************* + open a connection to the ldap server. +******************************************************************/ +static int smbldap_open_connection (struct smbldap_state *ldap_state) + +{ + int rc = LDAP_SUCCESS; + int version; + LDAP **ldap_struct = &ldap_state->ldap_struct; + + rc = smb_ldap_setup_conn(ldap_struct, ldap_state->uri); + if (rc) { + return rc; } -#endif /* Store the LDAP pointer in a lookup list */ @@ -597,45 +707,22 @@ static int smbldap_open_connection (struct smbldap_state *ldap_state) /* Upgrade to LDAPv3 if possible */ - if (ldap_get_option(*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) - { - if (version != LDAP_VERSION3) - { - version = LDAP_VERSION3; - if (ldap_set_option (*ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) { - ldap_v3 = True; - } - } else { - ldap_v3 = True; - } + rc = smb_ldap_upgrade_conn(*ldap_struct, &version); + if (rc) { + return rc; } - if (lp_ldap_ssl() == LDAP_SSL_START_TLS) { -#ifdef LDAP_OPT_X_TLS - if (ldap_v3) { - if ((rc = ldap_start_tls_s (*ldap_struct, NULL, NULL)) != LDAP_SUCCESS) - { - DEBUG(0,("Failed to issue the StartTLS instruction: %s\n", - ldap_err2string(rc))); - return rc; - } - DEBUG (3, ("StartTLS issued: using a TLS connection\n")); - } else { - - DEBUG(0, ("Need LDAPv3 for Start TLS\n")); - return LDAP_OPERATIONS_ERROR; - } -#else - DEBUG(0,("smbldap_open_connection: StartTLS not supported by LDAP client libraries!\n")); - return LDAP_OPERATIONS_ERROR; -#endif - } + /* Start TLS if required */ + rc = smb_ldap_start_tls(*ldap_struct, version); + if (rc) { + return rc; + } + DEBUG(2, ("smbldap_open_connection: connection opened\n")); return rc; } - /******************************************************************* a rebind function for authenticated referrals This version takes a void* that we can shove useful stuff in :-) @@ -690,9 +777,18 @@ static int rebindproc_connect_with_state (LDAP *ldap_struct, { struct smbldap_state *ldap_state = arg; int rc; - DEBUG(5,("rebindproc_connect_with_state: Rebinding as \"%s\"\n", - ldap_state->bind_dn)); - + int version; + + DEBUG(5,("rebindproc_connect_with_state: Rebinding to %s as \"%s\"\n", + url, ldap_state->bind_dn)); + + /* call START_TLS again (ldaps:// is handled by the OpenLDAP library + * itself) before rebinding to another LDAP server to avoid to expose + * our credentials. At least *try* to secure the connection - Guenther */ + + smb_ldap_upgrade_conn(ldap_struct, &version); + smb_ldap_start_tls(ldap_struct, version); + /** @TODO Should we be doing something to check what servers we rebind to? Could we get a referral to a machine that we don't want to give our username and password to? */ diff --git a/source/lib/snprintf.c b/source/lib/snprintf.c index 633517def28..a3e4b06d47f 100644 --- a/source/lib/snprintf.c +++ b/source/lib/snprintf.c @@ -89,6 +89,12 @@ * * Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even * if the C library has some snprintf functions already. + * + * Darren Tucker (dtucker@zip.com.au) + * Fix bug allowing read overruns of the source string with "%.*s" + * Usually harmless unless the read runs outside the process' allocation + * (eg if your malloc does guard pages) in which case it will segfault. + * From OpenSSH. Also added test for same. **************************************************************/ #ifndef NO_CONFIG_H @@ -479,7 +485,7 @@ static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, value = ""; } - for (strln = 0; value[strln]; ++strln); /* strlen */ + for (strln = 0; strln < max && value[strln]; ++strln); /* strlen */ padlen = min - strln; if (padlen < 0) padlen = 0; @@ -892,6 +898,7 @@ int smb_snprintf(char *str,size_t count,const char *fmt,...) { char buf1[1024]; char buf2[1024]; + char *buf3; char *fp_fmt[] = { "%1.1f", "%-1.5f", @@ -1001,6 +1008,20 @@ int smb_snprintf(char *str,size_t count,const char *fmt,...) } } +#define BUFSZ 2048 + + if ((buf3 = malloc(BUFSZ)) == NULL) { + fail++; + } else { + num++; + memset(buf3, 'a', BUFSZ); + snprintf(buf1, sizeof(buf1), "%.*s", 1, buf3); + if (strcmp(buf1, "a") != 0) { + printf("length limit buf1 '%s' expected 'a'\n", buf1); + fail++; + } + } + printf ("%d tests failed out of %d.\n", fail, num); printf("seeing how many digits we support\n"); diff --git a/source/lib/system.c b/source/lib/system.c index c59fe5c34d9..e9c13e6d079 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -1385,14 +1385,17 @@ ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t si * the returned value to the size of the buffer, so we have to check * that the buffer is large enough to fit the returned value. */ - retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0); - - if(retval > size) { - errno = ERANGE; - return -1; + if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) { + if(retval > size) { + errno = ERANGE; + return -1; + } + if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0) + return retval; } - return extattr_get_file(path, attrnamespace, attrname, value, size); + DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno))); + return -1; #elif defined(HAVE_ATTR_GET) int retval, flags = 0; int valuelength = (int)size; @@ -1420,14 +1423,17 @@ ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t s EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER; const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1; - retval = extattr_get_link(path, attrnamespace, attrname, NULL, 0); - - if(retval > size) { - errno = ERANGE; - return -1; + if((retval=extattr_get_link(path, attrnamespace, attrname, NULL, 0)) >= 0) { + if(retval > size) { + errno = ERANGE; + return -1; + } + if((retval=extattr_get_link(path, attrnamespace, attrname, value, size)) >= 0) + return retval; } - - return extattr_get_link(path, attrnamespace, attrname, value, size); + + DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno))); + return -1; #elif defined(HAVE_ATTR_GET) int retval, flags = ATTR_DONTFOLLOW; int valuelength = (int)size; @@ -1455,14 +1461,17 @@ ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size) EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER; const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1; - retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0); - - if(retval > size) { - errno = ERANGE; - return -1; + if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) { + if(retval > size) { + errno = ERANGE; + return -1; + } + if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0) + return retval; } - - return extattr_get_fd(filedes, attrnamespace, attrname, value, size); + + DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno))); + return -1; #elif defined(HAVE_ATTR_GETF) int retval, flags = 0; int valuelength = (int)size; @@ -1554,7 +1563,7 @@ static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size errno = ERANGE; return -1; } - /* Shift the results back, so we can prepend prefixes */ + /* Shift results back, so we can prepend prefixes */ buf = memmove(list + len, list, list_size); for(i = 0; i < list_size; i += len + 1) { @@ -1784,6 +1793,7 @@ int sys_setxattr (const char *path, const char *name, const void *value, size_t errno = ENOATTR; return -1; } + /* Ignore other errors */ } else { /* CREATE attribute, that already exists */ @@ -1829,6 +1839,7 @@ int sys_lsetxattr (const char *path, const char *name, const void *value, size_t errno = ENOATTR; return -1; } + /* Ignore other errors */ } else { /* CREATE attribute, that already exists */ @@ -1875,6 +1886,7 @@ int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size errno = ENOATTR; return -1; } + /* Ignore other errors */ } else { /* CREATE attribute, that already exists */ diff --git a/source/libads/kerberos_verify.c b/source/libads/kerberos_verify.c index f21577d0802..220bf14e32c 100644 --- a/source/libads/kerberos_verify.c +++ b/source/libads/kerberos_verify.c @@ -400,9 +400,9 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx, file_save("/tmp/ticket.dat", ticket->data, ticket->length); #endif - /* continue when no PAC is retrieved - (like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set, - or Kerberos tickets encryped using a DES key) - Guenther */ + /* continue when no PAC is retrieved or we couldn't decode the PAC + (like accounts that have the UF_NO_AUTH_DATA_REQUIRED flag set, or + Kerberos tickets encrypted using a DES key) - Guenther */ got_auth_data = get_auth_data_from_tkt(mem_ctx, &auth_data, tkt); if (!got_auth_data) { diff --git a/source/libads/ldap.c b/source/libads/ldap.c index bf402b3499e..e4cfc456a21 100644 --- a/source/libads/ldap.c +++ b/source/libads/ldap.c @@ -292,6 +292,11 @@ got_connection: ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); + status = ADS_ERROR(smb_ldap_start_tls(ads->ld, version)); + if (!ADS_ERR_OK(status)) { + return status; + } + if (!ads->auth.user_name) { /* have to use the userPrincipalName value here and not servicePrincipalName; found by Guenther Deschner @ Sernet */ @@ -577,8 +582,10 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, status = ads_do_paged_search(ads, bind_path, scope, expr, attrs, res, &count, &cookie); - if (!ADS_ERR_OK(status)) return status; + if (!ADS_ERR_OK(status)) + return status; +#ifdef HAVE_LDAP_ADD_RESULT_ENTRY while (cookie) { void *res2 = NULL; ADS_STATUS status2; @@ -598,6 +605,10 @@ ADS_STATUS ads_do_search_all(ADS_STRUCT *ads, const char *bind_path, /* note that we do not free res2, as the memory is now part of the main returned list */ } +#else + DEBUG(0, ("no ldap_add_result_entry() support in LDAP libs!\n")); + status = ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); +#endif return status; } diff --git a/source/nsswitch/winbind_nss_solaris.c b/source/nsswitch/winbind_nss_solaris.c index 64b8b734f17..8076c043e04 100644 --- a/source/nsswitch/winbind_nss_solaris.c +++ b/source/nsswitch/winbind_nss_solaris.c @@ -340,6 +340,7 @@ _nss_winbind_group_constr (const char* db_name, /***************************************************************** hosts and ipnodes backend *****************************************************************/ +#if defined(SUNOS5) /* not compatible with HP-UX */ /* this parser is shared between get*byname and get*byaddr, as key type in request is stored in different locations, I had to provide the @@ -627,4 +628,5 @@ _nss_winbind_hosts_constr(dummy1, dummy2, dummy3) sizeof (host_ops) / sizeof (host_ops[0]))); } -#endif /* SUN_NSS */ +#endif /* defined(SUNOS5) */ +#endif /* defined(HAVE_NSS_COMMON_H) || defined(HPUX) */ diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h index 3adf7717d6d..00a02330559 100644 --- a/source/nsswitch/winbindd.h +++ b/source/nsswitch/winbindd.h @@ -275,9 +275,6 @@ struct winbindd_methods { char ***names, char ***alt_names, DOM_SID **dom_sids); - - /* setup the list of alternate names for the domain, if any */ - NTSTATUS (*alternate_name)(struct winbindd_domain *domain); }; /* Used to glue a policy handle and cli_state together */ diff --git a/source/nsswitch/winbindd_ads.c b/source/nsswitch/winbindd_ads.c index 32bc641b6a6..ac24b35229c 100644 --- a/source/nsswitch/winbindd_ads.c +++ b/source/nsswitch/winbindd_ads.c @@ -933,42 +933,6 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, return result; } -/* find alternate names list for the domain - for ADS this is the - netbios name */ -static NTSTATUS alternate_name(struct winbindd_domain *domain) -{ - ADS_STRUCT *ads; - ADS_STATUS rc; - TALLOC_CTX *ctx; - const char *workgroup; - - DEBUG(3,("ads: alternate_name\n")); - - ads = ads_cached_connection(domain); - - if (!ads) { - domain->last_status = NT_STATUS_SERVER_DISABLED; - return NT_STATUS_UNSUCCESSFUL; - } - - if (!(ctx = talloc_init("alternate_name"))) { - return NT_STATUS_NO_MEMORY; - } - - rc = ads_workgroup_name(ads, ctx, &workgroup); - - if (ADS_ERR_OK(rc)) { - fstrcpy(domain->name, workgroup); - fstrcpy(domain->alt_name, ads->config.realm); - strupper_m(domain->alt_name); - strupper_m(domain->name); - } - - talloc_destroy(ctx); - - return ads_ntstatus(rc); -} - /* the ADS backend methods are exposed via this structure */ struct winbindd_methods ads_methods = { True, @@ -983,7 +947,6 @@ struct winbindd_methods ads_methods = { lookup_groupmem, sequence_number, trusted_domains, - alternate_name }; #endif diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c index 83ded01d4ea..2d03e452ad6 100644 --- a/source/nsswitch/winbindd_cache.c +++ b/source/nsswitch/winbindd_cache.c @@ -1401,18 +1401,6 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, names, alt_names, dom_sids); } -/* find the alternate names for the domain, if any */ -static NTSTATUS alternate_name(struct winbindd_domain *domain) -{ - get_cache(domain); - - DEBUG(10,("alternate_name: [Cached] - doing backend query for info for domain %s\n", - domain->name )); - - /* we don't cache this call */ - return domain->backend->alternate_name(domain); -} - /* Invalidate cached user and group lists coherently */ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, @@ -1467,7 +1455,6 @@ struct winbindd_methods cache_methods = { lookup_groupmem, sequence_number, trusted_domains, - alternate_name }; static BOOL init_wcache(void) diff --git a/source/nsswitch/winbindd_misc.c b/source/nsswitch/winbindd_misc.c index 4afc525b301..ec8bacc4745 100644 --- a/source/nsswitch/winbindd_misc.c +++ b/source/nsswitch/winbindd_misc.c @@ -134,7 +134,8 @@ enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain * for (i=1; imem_ctx, "%s\n%s\\%s\\%s", extra_data, - names[i], alt_names[i], + names[i], + alt_names[i] ? alt_names[i] : names[i], sid_string_static(&sids[i])); /* This is a bit excessive, but the extra data sooner or later will be diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c index 4582eced0e5..e683f397b66 100644 --- a/source/nsswitch/winbindd_pam.c +++ b/source/nsswitch/winbindd_pam.c @@ -797,7 +797,7 @@ void winbindd_pam_chauthtok(struct winbindd_cli_state *state) done: state->response.data.auth.nt_status = NT_STATUS_V(result); fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - fstrcpy(state->response.data.auth.error_string, nt_errstr(result)); + fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result)); state->response.data.auth.pam_error = nt_status_to_pam(result); DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, diff --git a/source/nsswitch/winbindd_passdb.c b/source/nsswitch/winbindd_passdb.c index 238e80f31b1..c32aa01a38a 100644 --- a/source/nsswitch/winbindd_passdb.c +++ b/source/nsswitch/winbindd_passdb.c @@ -378,17 +378,6 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, return nt_status; } -/* find alternate names list for the domain - * should we look for netbios aliases?? - SSS */ -static NTSTATUS alternate_name(struct winbindd_domain *domain) -{ - DEBUG(3,("pdb: alternate_name\n")); - - return NT_STATUS_OK; -} - - /* the rpc backend methods are exposed via this structure */ struct winbindd_methods passdb_methods = { False, @@ -403,5 +392,4 @@ struct winbindd_methods passdb_methods = { lookup_groupmem, sequence_number, trusted_domains, - alternate_name }; diff --git a/source/nsswitch/winbindd_reconnect.c b/source/nsswitch/winbindd_reconnect.c index 1a90717db31..77df9c1513c 100644 --- a/source/nsswitch/winbindd_reconnect.c +++ b/source/nsswitch/winbindd_reconnect.c @@ -242,19 +242,6 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, return result; } -static NTSTATUS alternate_name(struct winbindd_domain *domain) -{ - NTSTATUS result; - - result = msrpc_methods.alternate_name(domain); - - if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) - result = msrpc_methods.alternate_name(domain); - - return result; -} - - /* the rpc backend methods are exposed via this structure */ struct winbindd_methods reconnect_methods = { False, @@ -269,5 +256,4 @@ struct winbindd_methods reconnect_methods = { lookup_groupmem, sequence_number, trusted_domains, - alternate_name }; diff --git a/source/nsswitch/winbindd_rpc.c b/source/nsswitch/winbindd_rpc.c index 63e24877008..6179189e309 100644 --- a/source/nsswitch/winbindd_rpc.c +++ b/source/nsswitch/winbindd_rpc.c @@ -883,13 +883,6 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, return result; } -/* find alternate names list for the domain - none for rpc */ -static NTSTATUS alternate_name(struct winbindd_domain *domain) -{ - return NT_STATUS_OK; -} - - /* the rpc backend methods are exposed via this structure */ struct winbindd_methods msrpc_methods = { False, @@ -904,5 +897,4 @@ struct winbindd_methods msrpc_methods = { lookup_groupmem, sequence_number, trusted_domains, - alternate_name }; diff --git a/source/param/loadparm.c b/source/param/loadparm.c index d2d739fa726..86a5353dca7 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -145,7 +145,6 @@ typedef struct char *szNetbiosName; char **szNetbiosAliases; char *szNetbiosScope; - char *szDomainOtherSIDs; char *szNameResolveOrder; char *szPanicAction; char *szAddUserScript; @@ -302,6 +301,7 @@ typedef struct int name_cache_timeout; int client_signing; int server_signing; + BOOL bResetOnZeroVC; param_opt_struct *param_opt; } global; @@ -952,6 +952,7 @@ static struct parm_struct parm_table[] = { {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED}, {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED}, {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED}, + {"reset on zero vc", P_BOOL, P_GLOBAL, &Globals.bResetOnZeroVC, NULL, NULL, FLAG_ADVANCED}, {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, {"defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, @@ -1425,6 +1426,9 @@ static void init_globals(void) slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION); string_set(&Globals.szAnnounceVersion, s); +#ifdef DEVELOPER + string_set(&Globals.szPanicAction, "/bin/sleep 999999999"); +#endif pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS); @@ -1520,6 +1524,7 @@ static void init_globals(void) Globals.bUseMmap = True; #endif Globals.bUnixExtensions = True; + Globals.bResetOnZeroVC = False; /* hostname lookups can be very expensive and are broken on a large number of sites (tridge) */ @@ -1807,6 +1812,7 @@ FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand) FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs) FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios) +FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC) FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard) FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy) FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport) diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c index 92ef5133258..8a9730c3c8a 100644 --- a/source/passdb/pdb_ldap.c +++ b/source/passdb/pdb_ldap.c @@ -3415,7 +3415,7 @@ static NTSTATUS ldapsam_get_account_policy_from_ldap(struct pdb_methods *methods ldap_get_option(ldap_state->smbldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,&ld_error); - DEBUG(0, ("ldapsam_get_account_policy_from_ldap: Could not set account policy " + DEBUG(0, ("ldapsam_get_account_policy_from_ldap: Could not get account policy " "for %s, error: %s (%s)\n", ldap_state->domain_dn, ldap_err2string(rc), ld_error?ld_error:"unknown")); SAFE_FREE(ld_error); diff --git a/source/passdb/pdb_nds.c b/source/passdb/pdb_nds.c index 5de80a827fa..c6d644827c7 100644 --- a/source/passdb/pdb_nds.c +++ b/source/passdb/pdb_nds.c @@ -762,11 +762,7 @@ static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods, const char **attr_list; size_t pwd_len; char clear_text_pw[512]; - const char *p = NULL; LDAP *ld = NULL; - int ldap_port = 0; - char protocol[12]; - char ldap_server[256]; const char *username = pdb_get_username(sam_acct); BOOL got_clear_text_pw = False; @@ -809,53 +805,13 @@ static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods, DEBUG(5,("pdb_nds_update_login_attempts: using random password %s\n", clear_text_pw)); } - /* Parse the location string */ - p = ldap_state->location; - - /* skip leading "URL:" (if any) */ - if ( strnequal( p, "URL:", 4 ) ) { - p += 4; - } - - sscanf(p, "%10[^:]://%254[^:/]:%d", protocol, ldap_server, &ldap_port); - - if (ldap_port == 0) { - if (strequal(protocol, "ldap")) { - ldap_port = LDAP_PORT; - } else if (strequal(protocol, "ldaps")) { - ldap_port = LDAPS_PORT; - } else { - DEBUG(0, ("unrecognised protocol (%s)!\n", protocol)); - } - } - - ld = ldap_init(ldap_server, ldap_port); - - if(ld != NULL) { - int version; - - /* LDAP version 3 required for ldap_sasl */ - if (ldap_get_option(ld, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) { - if (version != LDAP_VERSION3) { - version = LDAP_VERSION3; - if (ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &version) == LDAP_OPT_SUCCESS) { - DEBUG(4, ("pdb_nds_update_login_attempts: Set protocol version to LDAP_VERSION3\n")); - } - } - } - - /* Turn on ssl if required */ - if(strequal(protocol, "ldaps")) { - int tls = LDAP_OPT_X_TLS_HARD; - if (ldap_set_option (ld, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS) { - DEBUG(1, ("pdb_nds_update_login_attempts: Failed to setup a TLS session\n")); - } else { - DEBUG(4, ("pdb_nds_update_login_attempts: Activated TLS on session\n")); - } + if((success != True) || (got_clear_text_pw == True)) { + + rc = smb_ldap_setup_full_conn(ld, ldap_state->location); + if (rc) { + return NT_STATUS_INVALID_CONNECTION; } - } - if((success != True) || (got_clear_text_pw == True)) { /* Attempt simple bind with real or bogus password */ rc = ldap_simple_bind_s(ld, dn, clear_text_pw); if (rc == LDAP_SUCCESS) { diff --git a/source/rpc_client/cli_lsarpc.c b/source/rpc_client/cli_lsarpc.c index c64de2b8e88..aa1cb95fda1 100644 --- a/source/rpc_client/cli_lsarpc.c +++ b/source/rpc_client/cli_lsarpc.c @@ -1264,7 +1264,7 @@ NTSTATUS rpccli_lsa_open_trusted_domain(struct rpc_pipe_client *cli, TALLOC_CTX NTSTATUS rpccli_lsa_query_trusted_domain_info(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, - uint16 info_class, DOM_SID *dom_sid, + uint16 info_class, LSA_TRUSTED_DOMAIN_INFO **info) { prs_struct qbuf, rbuf; diff --git a/source/rpc_parse/parse_eventlog.c b/source/rpc_parse/parse_eventlog.c index 0f0b02748b3..5e28a4aba5d 100644 --- a/source/rpc_parse/parse_eventlog.c +++ b/source/rpc_parse/parse_eventlog.c @@ -294,7 +294,7 @@ BOOL eventlog_io_r_read_eventlog(const char *desc, while(entry != NULL && record_written < record_total) { - DEBUG(10, ("eventlog_io_r_read_eventlog: writing record [%d] out of [%d].\n", record_written, record_total)); + DEBUG(11, ("eventlog_io_r_read_eventlog: writing record [%d] out of [%d].\n", record_written, record_total)); /* Encode the actual eventlog record record */ diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c index dfe80a65e27..2ba99fff495 100644 --- a/source/rpc_parse/parse_samr.c +++ b/source/rpc_parse/parse_samr.c @@ -2141,7 +2141,7 @@ void init_samr_group_info1(GROUP_INFO1 * gr1, { DEBUG(5, ("init_samr_group_info1\n")); - gr1->unknown_1 = 0x3; + gr1->group_attr = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT); /* why not | SE_GROUP_ENABLED ? */ gr1->num_members = num_members; init_unistr2(&gr1->uni_acct_name, acct_name, UNI_FLAGS_NONE); @@ -2174,7 +2174,7 @@ BOOL samr_io_group_info1(const char *desc, GROUP_INFO1 * gr1, if(!smb_io_unihdr("hdr_acct_name", &gr1->hdr_acct_name, ps, depth)) return False; - if(!prs_uint32("unknown_1", ps, depth, &gr1->unknown_1)) + if(!prs_uint32("group_attr", ps, depth, &gr1->group_attr)) return False; if(!prs_uint32("num_members", ps, depth, &gr1->num_members)) return False; @@ -2238,7 +2238,7 @@ void init_samr_group_info3(GROUP_INFO3 *gr3) { DEBUG(5, ("init_samr_group_info3\n")); - gr3->unknown_1 = 0x3; + gr3->group_attr = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT); /* why not | SE_GROUP_ENABLED ? */ } /******************************************************************* @@ -2256,7 +2256,7 @@ BOOL samr_io_group_info3(const char *desc, GROUP_INFO3 *gr3, prs_struct *ps, int if(!prs_align(ps)) return False; - if(!prs_uint32("unknown_1", ps, depth, &gr3->unknown_1)) + if(!prs_uint32("group_attr", ps, depth, &gr3->group_attr)) return False; return True; @@ -7143,10 +7143,10 @@ BOOL samr_io_r_chgpasswd_user(const char *desc, SAMR_R_CHGPASSWD_USER * r_u, reads or writes a structure. ********************************************************************/ -void init_samr_q_unknown_2e(SAMR_Q_UNKNOWN_2E *q_u, +void init_samr_q_query_domain_info2(SAMR_Q_QUERY_DOMAIN_INFO2 *q_u, POLICY_HND *domain_pol, uint16 switch_value) { - DEBUG(5, ("init_samr_q_unknown_2e\n")); + DEBUG(5, ("init_samr_q_query_domain_info2\n")); q_u->domain_pol = *domain_pol; q_u->switch_value = switch_value; @@ -7156,13 +7156,13 @@ void init_samr_q_unknown_2e(SAMR_Q_UNKNOWN_2E *q_u, reads or writes a structure. ********************************************************************/ -BOOL samr_io_q_unknown_2e(const char *desc, SAMR_Q_UNKNOWN_2E *q_u, +BOOL samr_io_q_query_domain_info2(const char *desc, SAMR_Q_QUERY_DOMAIN_INFO2 *q_u, prs_struct *ps, int depth) { if (q_u == NULL) return False; - prs_debug(ps, depth, desc, "samr_io_q_unknown_2e"); + prs_debug(ps, depth, desc, "samr_io_q_query_domain_info2"); depth++; if(!prs_align(ps)) @@ -7181,11 +7181,11 @@ BOOL samr_io_q_unknown_2e(const char *desc, SAMR_Q_UNKNOWN_2E *q_u, inits a SAMR_R_QUERY_DOMAIN_INFO structure. ********************************************************************/ -void init_samr_r_samr_unknown_2e(SAMR_R_UNKNOWN_2E * r_u, +void init_samr_r_samr_query_domain_info2(SAMR_R_QUERY_DOMAIN_INFO2 * r_u, uint16 switch_value, SAM_UNK_CTR * ctr, NTSTATUS status) { - DEBUG(5, ("init_samr_r_samr_unknown_2e\n")); + DEBUG(5, ("init_samr_r_samr_query_domain_info2\n")); r_u->ptr_0 = 0; r_u->switch_value = 0; @@ -7202,13 +7202,13 @@ void init_samr_r_samr_unknown_2e(SAMR_R_UNKNOWN_2E * r_u, reads or writes a structure. ********************************************************************/ -BOOL samr_io_r_samr_unknown_2e(const char *desc, SAMR_R_UNKNOWN_2E * r_u, +BOOL samr_io_r_samr_query_domain_info2(const char *desc, SAMR_R_QUERY_DOMAIN_INFO2 * r_u, prs_struct *ps, int depth) { if (r_u == NULL) return False; - prs_debug(ps, depth, desc, "samr_io_r_samr_unknown_2e"); + prs_debug(ps, depth, desc, "samr_io_r_samr_query_domain_info2"); depth++; if(!prs_align(ps)) @@ -7253,7 +7253,7 @@ BOOL samr_io_r_samr_unknown_2e(const char *desc, SAMR_R_UNKNOWN_2E * r_u, return False; break; default: - DEBUG(0, ("samr_io_r_samr_unknown_2e: unknown switch level 0x%x\n", + DEBUG(0, ("samr_io_r_samr_query_domain_info2: unknown switch level 0x%x\n", r_u->switch_value)); r_u->status = NT_STATUS_INVALID_INFO_CLASS; return False; diff --git a/source/rpc_server/srv_eventlog_lib.c b/source/rpc_server/srv_eventlog_lib.c index b21c2a2529f..ec5edf2f347 100644 --- a/source/rpc_server/srv_eventlog_lib.c +++ b/source/rpc_server/srv_eventlog_lib.c @@ -24,14 +24,7 @@ /* maintain a list of open eventlog tdbs with reference counts */ -struct elog_open_tdb { - struct elog_open_tdb *prev, *next; - char *name; - TDB_CONTEXT *tdb; - int ref_count; -}; - -static struct elog_open_tdb *open_elog_list; +static ELOG_TDB *open_elog_list; /******************************************************************** Init an Eventlog TDB, and return it. If null, something bad @@ -317,14 +310,14 @@ BOOL can_write_to_eventlog( TDB_CONTEXT * tdb, int32 needed ) /******************************************************************* *******************************************************************/ -TDB_CONTEXT *elog_open_tdb( char *logname ) +ELOG_TDB *elog_open_tdb( char *logname, BOOL force_clear ) { - TDB_CONTEXT *tdb; + TDB_CONTEXT *tdb = NULL; uint32 vers_id; - struct elog_open_tdb *ptr; + ELOG_TDB *ptr; char *tdbfilename; pstring tdbpath; - struct elog_open_tdb *tdb_node; + ELOG_TDB *tdb_node = NULL; char *eventlogdir; /* first see if we have an open context */ @@ -332,7 +325,19 @@ TDB_CONTEXT *elog_open_tdb( char *logname ) for ( ptr=open_elog_list; ptr; ptr=ptr->next ) { if ( strequal( ptr->name, logname ) ) { ptr->ref_count++; - return ptr->tdb; + + /* trick to alow clearing of the eventlog tdb. + The force_clear flag should imply that someone + has done a force close. So make sure the tdb + is NULL. If this is a normal open, then just + return the existing reference */ + + if ( force_clear ) { + SMB_ASSERT( ptr->tdb == NULL ); + break; + } + else + return ptr; } } @@ -348,27 +353,41 @@ TDB_CONTEXT *elog_open_tdb( char *logname ) pstrcpy( tdbpath, tdbfilename ); SAFE_FREE( tdbfilename ); - DEBUG(7,("elog_open_tdb: Opening %s...\n", tdbpath )); + DEBUG(7,("elog_open_tdb: Opening %s...(force_clear == %s)\n", + tdbpath, force_clear?"True":"False" )); + + /* the tdb wasn't already open or this is a forced clear open */ - tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, O_RDWR , 0 ); - if ( tdb ) { - vers_id = tdb_fetch_int32( tdb, EVT_VERSION ); + if ( !force_clear ) { - if ( vers_id != EVENTLOG_DATABASE_VERSION_V1 ) { - DEBUG(1,("elog_open_tdb: Invalid version [%d] on file [%s].\n", - vers_id, tdbpath)); - tdb_close( tdb ); - tdb = elog_init_tdb( tdbpath ); + tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, O_RDWR , 0 ); + if ( tdb ) { + vers_id = tdb_fetch_int32( tdb, EVT_VERSION ); + + if ( vers_id != EVENTLOG_DATABASE_VERSION_V1 ) { + DEBUG(1,("elog_open_tdb: Invalid version [%d] on file [%s].\n", + vers_id, tdbpath)); + tdb_close( tdb ); + tdb = elog_init_tdb( tdbpath ); + } } } - else { + + if ( !tdb ) tdb = elog_init_tdb( tdbpath ); - } /* if we got a valid context, then add it to the list */ if ( tdb ) { - if ( !(tdb_node = TALLOC_ZERO_P( NULL, struct elog_open_tdb )) ) { + /* on a forced clear, just reset the tdb context if we already + have an open entry in the list */ + + if ( ptr ) { + ptr->tdb = tdb; + return ptr; + } + + if ( !(tdb_node = TALLOC_ZERO_P( NULL, ELOG_TDB)) ) { DEBUG(0,("elog_open_tdb: talloc() failure!\n")); tdb_close( tdb ); return NULL; @@ -381,42 +400,34 @@ TDB_CONTEXT *elog_open_tdb( char *logname ) DLIST_ADD( open_elog_list, tdb_node ); } - return tdb; + return tdb_node; } /******************************************************************* Wrapper to handle reference counts to the tdb *******************************************************************/ -int elog_close_tdb( TDB_CONTEXT *tdb ) +int elog_close_tdb( ELOG_TDB *etdb, BOOL force_close ) { - struct elog_open_tdb *ptr; + TDB_CONTEXT *tdb; - if ( !tdb ) + if ( !etdb ) return 0; - /* See if we can just decrement the ref_count. - Just compare pointer values (not names ) */ - - for ( ptr=open_elog_list; ptr; ptr=ptr->next ) { - if ( tdb == ptr->tdb ) { - ptr->ref_count--; - break; - } - } + etdb->ref_count--; - /* if we have a NULL pointer; it means we are trying to - close a tdb not in the list of open eventlogs */ - - SMB_ASSERT( ptr != NULL ); - if ( !ptr ) + SMB_ASSERT( etdb->ref_count >= 0 ); + + if ( etdb->ref_count == 0 ) { + tdb = etdb->tdb; + DLIST_REMOVE( open_elog_list, etdb ); + TALLOC_FREE( etdb ); return tdb_close( tdb ); + } - SMB_ASSERT( ptr->ref_count >= 0 ); - - if ( ptr->ref_count == 0 ) { - DLIST_REMOVE( open_elog_list, ptr ); - TALLOC_FREE( ptr ); + if ( force_close ) { + tdb = etdb->tdb; + etdb->tdb = NULL; return tdb_close( tdb ); } diff --git a/source/rpc_server/srv_eventlog_nt.c b/source/rpc_server/srv_eventlog_nt.c index 6413221031c..658928b9270 100644 --- a/source/rpc_server/srv_eventlog_nt.c +++ b/source/rpc_server/srv_eventlog_nt.c @@ -27,7 +27,8 @@ typedef struct { char *logname; - TDB_CONTEXT *tdb; + ELOG_TDB *etdb; + uint32 current_record; uint32 num_records; uint32 oldest_entry; uint32 flags; @@ -41,8 +42,8 @@ static void free_eventlog_info( void *ptr ) { EVENTLOG_INFO *elog = (EVENTLOG_INFO *)ptr; - if ( elog->tdb ) - elog_close_tdb( elog->tdb ); + if ( elog->etdb ) + elog_close_tdb( elog->etdb, False ); TALLOC_FREE( elog ); } @@ -130,6 +131,45 @@ static BOOL elog_validate_logname( const char *name ) return False; } +/******************************************************************** +********************************************************************/ + +static BOOL get_num_records_hook( EVENTLOG_INFO * info ) +{ + int next_record; + int oldest_record; + + if ( !info->etdb ) { + DEBUG( 10, ( "No open tdb for %s\n", info->logname ) ); + return False; + } + + /* lock the tdb since we have to get 2 records */ + + tdb_lock_bystring( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD, 1 ); + next_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD); + oldest_record = tdb_fetch_int32( ELOG_TDB_CTX(info->etdb), EVT_OLDEST_ENTRY); + tdb_unlock_bystring( ELOG_TDB_CTX(info->etdb), EVT_NEXT_RECORD); + + DEBUG( 8, + ( "Oldest Record %d; Next Record %d\n", oldest_record, + next_record ) ); + + info->num_records = ( next_record - oldest_record ); + info->oldest_entry = oldest_record; + + return True; +} + +/******************************************************************** + ********************************************************************/ + +static BOOL get_oldest_entry_hook( EVENTLOG_INFO * info ) +{ + /* it's the same thing */ + return get_num_records_hook( info ); +} + /******************************************************************** ********************************************************************/ @@ -153,10 +193,10 @@ static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hn in a single process */ become_root(); - elog->tdb = elog_open_tdb( elog->logname ); + elog->etdb = elog_open_tdb( elog->logname, False ); unbecome_root(); - if ( !elog->tdb ) { + if ( !elog->etdb ) { /* according to MSDN, if the logfile cannot be found, we should default to the "Application" log */ @@ -173,11 +213,11 @@ static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hn } become_root(); - elog->tdb = elog_open_tdb( elog->logname ); + elog->etdb = elog_open_tdb( elog->logname, False ); unbecome_root(); } - if ( !elog->tdb ) { + if ( !elog->etdb ) { TALLOC_FREE( elog ); return NT_STATUS_ACCESS_DENIED; /* ??? */ } @@ -186,7 +226,7 @@ static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hn /* now do the access check. Close the tdb if we fail here */ if ( !elog_check_access( elog, p->pipe_user.nt_user_token ) ) { - elog_close_tdb( elog->tdb ); + elog_close_tdb( elog->etdb, False ); TALLOC_FREE( elog ); return NT_STATUS_ACCESS_DENIED; } @@ -199,6 +239,15 @@ static NTSTATUS elog_open( pipes_struct * p, const char *logname, POLICY_HND *hn return NT_STATUS_NO_MEMORY; } + /* set the initial current_record pointer */ + + if ( !get_oldest_entry_hook( elog ) ) { + DEBUG(3,("elog_open: Successfully opened eventlog but can't " + "get any information on internal records!\n")); + } + + elog->current_record = elog->oldest_entry; + return NT_STATUS_OK; } @@ -219,12 +268,12 @@ static NTSTATUS elog_close( pipes_struct *p, POLICY_HND *hnd ) static int elog_size( EVENTLOG_INFO *info ) { - if ( !info || !info->tdb ) { + if ( !info || !info->etdb ) { DEBUG(0,("elog_size: Invalid info* structure!\n")); return 0; } - return elog_tdb_size( info->tdb, NULL, NULL ); + return elog_tdb_size( ELOG_TDB_CTX(info->etdb), NULL, NULL ); } /******************************************************************** @@ -348,7 +397,7 @@ static BOOL sync_eventlog_params( EVENTLOG_INFO *info ) DEBUG( 4, ( "sync_eventlog_params with %s\n", elogname ) ); - if ( !info->tdb ) { + if ( !info->etdb ) { DEBUG( 4, ( "No open tdb! (%s)\n", info->logname ) ); return False; } @@ -391,51 +440,12 @@ static BOOL sync_eventlog_params( EVENTLOG_INFO *info ) regkey_close_internal( keyinfo ); - tdb_store_int32( info->tdb, EVT_MAXSIZE, uiMaxSize ); - tdb_store_int32( info->tdb, EVT_RETENTION, uiRetention ); - - return True; -} - -/******************************************************************** -********************************************************************/ - -static BOOL get_num_records_hook( EVENTLOG_INFO * info ) -{ - int next_record; - int oldest_record; - - if ( !info->tdb ) { - DEBUG( 10, ( "No open tdb for %s\n", info->logname ) ); - return False; - } - - /* lock the tdb since we have to get 2 records */ - - tdb_lock_bystring( info->tdb, EVT_NEXT_RECORD, 1 ); - next_record = tdb_fetch_int32( info->tdb, EVT_NEXT_RECORD); - oldest_record = tdb_fetch_int32( info->tdb, EVT_OLDEST_ENTRY); - tdb_unlock_bystring( info->tdb, EVT_NEXT_RECORD); - - DEBUG( 8, - ( "Oldest Record %d; Next Record %d\n", oldest_record, - next_record ) ); - - info->num_records = ( next_record - oldest_record ); - info->oldest_entry = oldest_record; + tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_MAXSIZE, uiMaxSize ); + tdb_store_int32( ELOG_TDB_CTX(info->etdb), EVT_RETENTION, uiRetention ); return True; } -/******************************************************************** - ********************************************************************/ - -static BOOL get_oldest_entry_hook( EVENTLOG_INFO * info ) -{ - /* it's the same thing */ - return get_num_records_hook( info ); -} - /******************************************************************** ********************************************************************/ @@ -600,7 +610,7 @@ NTSTATUS _eventlog_open_eventlog( pipes_struct * p, DEBUG(10,("_eventlog_open_eventlog: Size [%d]\n", elog_size( info ))); sync_eventlog_params( info ); - prune_eventlog( info->tdb ); + prune_eventlog( ELOG_TDB_CTX(info->etdb) ); return NT_STATUS_OK; } @@ -624,20 +634,26 @@ NTSTATUS _eventlog_clear_eventlog( pipes_struct * p, rpcstr_pull( backup_file_name, q_u->backupfile.string->buffer, sizeof( backup_file_name ), q_u->backupfile.string->uni_str_len * 2, 0 ); + + DEBUG(8,( "_eventlog_clear_eventlog: Using [%s] as the backup " + "file name for log [%s].", + backup_file_name, info->logname ) ); } - DEBUG( 8, - ( "_eventlog_clear_eventlog: Using [%s] as the backup file name for log [%s].", - backup_file_name, info->logname ) ); + /* check for WRITE access to the file */ -#if 0 - /* close the current one, reinit */ + if ( !(info->access_granted&SA_RIGHT_FILE_WRITE_DATA) ) + return NT_STATUS_ACCESS_DENIED; - tdb_close( info->tdb ); + /* Force a close and reopen */ - if ( !(info->tdb = elog_init_tdb( ttdb[i].tdbfname )) ) + elog_close_tdb( info->etdb, True ); + become_root(); + info->etdb = elog_open_tdb( info->logname, True ); + unbecome_root(); + + if ( !info->etdb ) return NT_STATUS_ACCESS_DENIED; -#endif return NT_STATUS_OK; } @@ -661,71 +677,86 @@ NTSTATUS _eventlog_read_eventlog( pipes_struct * p, { EVENTLOG_INFO *info = find_eventlog_info_by_hnd( p, &q_u->handle ); Eventlog_entry entry, *ee_new; - uint32 num_records_read = 0; prs_struct *ps; int bytes_left, record_number; - TDB_CONTEXT *tdb; + uint32 elog_read_type, elog_read_dir; info->flags = q_u->flags; ps = &p->out_data.rdata; bytes_left = q_u->max_read_size; - tdb = info->tdb; - if ( !tdb ) { + + if ( !info->etdb ) return NT_STATUS_ACCESS_DENIED; + + /* check for valid flags. Can't use the sequential and seek flags together */ + + elog_read_type = q_u->flags & (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ); + elog_read_dir = q_u->flags & (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ); + + if ( elog_read_type == (EVENTLOG_SEQUENTIAL_READ|EVENTLOG_SEEK_READ) + || elog_read_dir == (EVENTLOG_FORWARDS_READ|EVENTLOG_BACKWARDS_READ) ) + { + DEBUG(3,("_eventlog_read_eventlog: Invalid flags [0x%x] for ReadEventLog\n", q_u->flags)); + return NT_STATUS_INVALID_PARAMETER; } - /* DEBUG(8,("Bytes left is %d\n",bytes_left)); */ + /* a sequential read should ignore the offset */ - record_number = q_u->offset; + if ( elog_read_type & EVENTLOG_SEQUENTIAL_READ ) + record_number = info->current_record; + else + record_number = q_u->offset; while ( bytes_left > 0 ) { - if ( get_eventlog_record - ( ps, tdb, record_number, &entry ) ) { - DEBUG( 8, - ( "Retrieved record %d\n", record_number ) ); + + /* assume that when the record fetch fails, that we are done */ + + if ( !get_eventlog_record ( ps, ELOG_TDB_CTX(info->etdb), record_number, &entry ) ) + break; + + DEBUG( 8, ( "Retrieved record %d\n", record_number ) ); - /* Now see if there is enough room to add */ - ee_new = read_package_entry( ps, q_u, r_u,&entry ); - if ( !ee_new ) - return NT_STATUS_NO_MEMORY; - - if ( r_u->num_bytes_in_resp + ee_new->record.length > - q_u->max_read_size ) { - r_u->bytes_in_next_record = - ee_new->record.length; - - /* response would be too big to fit in client-size buffer */ + /* Now see if there is enough room to add */ + + if ( !(ee_new = read_package_entry( ps, q_u, r_u,&entry )) ) + return NT_STATUS_NO_MEMORY; + + if ( r_u->num_bytes_in_resp + ee_new->record.length > q_u->max_read_size ) { + r_u->bytes_in_next_record = ee_new->record.length; + + /* response would be too big to fit in client-size buffer */ - bytes_left = 0; - break; - } + bytes_left = 0; + break; + } - add_record_to_resp( r_u, ee_new ); - bytes_left -= ee_new->record.length; - ZERO_STRUCT( entry ); - num_records_read = - r_u->num_records - num_records_read; + add_record_to_resp( r_u, ee_new ); + bytes_left -= ee_new->record.length; + ZERO_STRUCT( entry ); + num_records_read = r_u->num_records - num_records_read; - DEBUG( 10, - ( "_eventlog_read_eventlog: read [%d] records for a total of [%d] records using [%d] bytes out of a max of [%d].\n", - num_records_read, r_u->num_records, - r_u->num_bytes_in_resp, - q_u->max_read_size ) ); - } else { - DEBUG( 8, ( "get_eventlog_record returned NULL\n" ) ); - return NT_STATUS_NO_MEMORY; /* wrong error - but return one anyway */ - } - + DEBUG( 10, ( "_eventlog_read_eventlog: read [%d] records for a total " + "of [%d] records using [%d] bytes out of a max of [%d].\n", + num_records_read, r_u->num_records, + r_u->num_bytes_in_resp, + q_u->max_read_size ) ); if ( info->flags & EVENTLOG_FORWARDS_READ ) record_number++; else record_number--; + + /* update the eventlog record pointer */ + + info->current_record = record_number; } - - return NT_STATUS_OK; + + /* crazy by WinXP uses NT_STATUS_BUFFER_TOO_SMALL to + say when there are no more records */ + + return (num_records_read ? NT_STATUS_OK : NT_STATUS_BUFFER_TOO_SMALL); } /******************************************************************** diff --git a/source/rpc_server/srv_samr.c b/source/rpc_server/srv_samr.c index ffb7882e110..cbfad5688e1 100644 --- a/source/rpc_server/srv_samr.c +++ b/source/rpc_server/srv_samr.c @@ -1374,13 +1374,13 @@ static BOOL api_samr_remove_sid_foreign_domain(pipes_struct *p) } /******************************************************************* - api_samr_query_dom_info + api_samr_query_dom_info2 ********************************************************************/ -static BOOL api_samr_unknown_2e(pipes_struct *p) +static BOOL api_samr_query_domain_info2(pipes_struct *p) { - SAMR_Q_UNKNOWN_2E q_u; - SAMR_R_UNKNOWN_2E r_u; + SAMR_Q_QUERY_DOMAIN_INFO2 q_u; + SAMR_R_QUERY_DOMAIN_INFO2 r_u; prs_struct *data = &p->in_data.data; prs_struct *rdata = &p->out_data.rdata; @@ -1388,16 +1388,16 @@ static BOOL api_samr_unknown_2e(pipes_struct *p) ZERO_STRUCT(r_u); /* grab the samr unknown 8 command */ - if(!samr_io_q_unknown_2e("", &q_u, data, 0)) { - DEBUG(0,("api_samr_unknown_2e: unable to unmarshall SAMR_Q_UNKNOWN_2E.\n")); + if(!samr_io_q_query_domain_info2("", &q_u, data, 0)) { + DEBUG(0,("api_samr_query_domain_info2: unable to unmarshall SAMR_Q_QUERY_DOMAIN_INFO2.\n")); return False; } - r_u.status = _samr_unknown_2e(p, &q_u, &r_u); + r_u.status = _samr_query_domain_info2(p, &q_u, &r_u); /* store the response in the SMB stream */ - if(!samr_io_r_samr_unknown_2e("", &r_u, rdata, 0)) { - DEBUG(0,("api_samr_unknown_2e: unable to marshall SAMR_R_UNKNOWN_2E.\n")); + if(!samr_io_r_samr_query_domain_info2("", &r_u, rdata, 0)) { + DEBUG(0,("api_samr_query_domain_info2: unable to marshall SAMR_R_QUERY_DOMAIN_INFO2.\n")); return False; } @@ -1490,7 +1490,7 @@ static struct api_struct api_samr_cmds [] = {"SAMR_QUERY_SEC_OBJECT" , SAMR_QUERY_SEC_OBJECT , api_samr_query_sec_obj }, {"SAMR_SET_SEC_OBJECT" , SAMR_SET_SEC_OBJECT , api_samr_set_sec_obj }, {"SAMR_GET_USRDOM_PWINFO" , SAMR_GET_USRDOM_PWINFO, api_samr_get_usrdom_pwinfo}, - {"SAMR_UNKNOWN_2E" , SAMR_UNKNOWN_2E , api_samr_unknown_2e }, + {"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 } }; diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c index 71272a9a98b..4d44f8312b3 100644 --- a/source/rpc_server/srv_samr_nt.c +++ b/source/rpc_server/srv_samr_nt.c @@ -40,11 +40,12 @@ SA_RIGHT_USER_CHANGE_PASSWORD | \ SA_RIGHT_USER_SET_LOC_COM ) -extern rid_name domain_group_rids[]; -extern rid_name domain_alias_rids[]; -extern rid_name builtin_alias_rids[]; +#define DISP_INFO_CACHE_TIMEOUT 10 typedef struct disp_info { + struct disp_info *next, *prev; + TALLOC_CTX *mem_ctx; + DOM_SID sid; /* identify which domain this is. */ struct pdb_search *users; /* querydispinfo 1 and 4 */ struct pdb_search *machines; /* querydispinfo 2 */ struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */ @@ -53,8 +54,15 @@ typedef struct disp_info { uint16 enum_acb_mask; struct pdb_search *enum_users; /* enumusers with a mask */ + + smb_event_id_t di_cache_timeout_event; /* cache idle timeout handler. */ } DISP_INFO; +/* We keep a static list of these by SID as modern clients close down + all resources between each request in a complete enumeration. */ + +static DISP_INFO *disp_info_list; + struct samr_info { /* for use by the \PIPE\samr policy */ DOM_SID sid; @@ -62,8 +70,7 @@ struct samr_info { uint32 acc_granted; uint16 acb_mask; BOOL only_machines; - DISP_INFO disp_info; - + DISP_INFO *disp_info; TALLOC_CTX *mem_ctx; }; @@ -215,6 +222,39 @@ static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_requir return NT_STATUS_ACCESS_DENIED; } +/******************************************************************* + Fetch or create a dispinfo struct. +********************************************************************/ + +static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid, const char *sid_str) +{ + TALLOC_CTX *mem_ctx; + DISP_INFO *dpi; + + for (dpi = disp_info_list; dpi; dpi = dpi->next) { + if (sid_equal(psid, &dpi->sid)) { + return dpi; + } + } + + /* This struct is never free'd - I'm using talloc so we + can get a list out of smbd using smbcontrol. There will + be one of these per SID we're authorative for. JRA. */ + + mem_ctx = talloc_init("DISP_INFO for domain sid %s", sid_str); + + if ((dpi = TALLOC_ZERO_P(mem_ctx, DISP_INFO)) == NULL) + return NULL; + + dpi->mem_ctx = mem_ctx; + if (psid) { + sid_copy( &dpi->sid, psid); + } + + DLIST_ADD(disp_info_list, dpi); + + return dpi; +} /******************************************************************* Create a samr_info struct. @@ -244,41 +284,155 @@ static struct samr_info *get_samr_info_by_sid(DOM_SID *psid) DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n")); } info->mem_ctx = mem_ctx; + + info->disp_info = get_samr_dispinfo_by_sid(psid, sid_str); + + if (!info->disp_info) { + talloc_destroy(mem_ctx); + return NULL; + } + return info; } /******************************************************************* - Function to free the per handle data. + Function to free the per SID data. ********************************************************************/ +static void free_samr_cache(DISP_INFO *disp_info, const char *sid_str) +{ + DEBUG(10,("free_samr_cache: deleting cache for SID %s\n", sid_str)); + + /* We need to become root here because the paged search might have to + * tell the LDAP server we're not interested in the rest anymore. */ + + become_root(); + + if (disp_info->users) { + DEBUG(10,("free_samr_cache: deleting users cache\n")); + pdb_search_destroy(disp_info->users); + disp_info->users = NULL; + } + if (disp_info->machines) { + DEBUG(10,("free_samr_cache: deleting machines cache\n")); + pdb_search_destroy(disp_info->machines); + disp_info->machines = NULL; + } + if (disp_info->groups) { + DEBUG(10,("free_samr_cache: deleting groups cache\n")); + pdb_search_destroy(disp_info->groups); + disp_info->groups = NULL; + } + if (disp_info->aliases) { + DEBUG(10,("free_samr_cache: deleting aliases cache\n")); + pdb_search_destroy(disp_info->aliases); + disp_info->aliases = NULL; + } + if (disp_info->builtins) { + DEBUG(10,("free_samr_cache: deleting builtins cache\n")); + pdb_search_destroy(disp_info->builtins); + disp_info->builtins = NULL; + } + if (disp_info->enum_users) { + DEBUG(10,("free_samr_cache: deleting enum_users cache\n")); + pdb_search_destroy(disp_info->enum_users); + disp_info->enum_users = NULL; + } + disp_info->enum_acb_mask = 0; + + unbecome_root(); +} + /******************************************************************* Function to free the per handle data. ********************************************************************/ -static void free_samr_db(struct samr_info *info) -{ - pdb_search_destroy(info->disp_info.users); - info->disp_info.users = NULL; - pdb_search_destroy(info->disp_info.machines); - info->disp_info.machines = NULL; - pdb_search_destroy(info->disp_info.groups); - info->disp_info.groups = NULL; - pdb_search_destroy(info->disp_info.aliases); - info->disp_info.aliases = NULL; - pdb_search_destroy(info->disp_info.builtins); - info->disp_info.builtins = NULL; - pdb_search_destroy(info->disp_info.enum_users); - info->disp_info.enum_users = NULL; -} - static void free_samr_info(void *ptr) { struct samr_info *info=(struct samr_info *) ptr; - free_samr_db(info); + /* Only free the dispinfo cache if no one bothered to set up + a timeout. */ + + if (info->disp_info && info->disp_info->di_cache_timeout_event == (smb_event_id_t)0) { + fstring sid_str; + sid_to_string(sid_str, &info->disp_info->sid); + free_samr_cache(info->disp_info, sid_str); + } + talloc_destroy(info->mem_ctx); } +/******************************************************************* + Idle event handler. Throw away the disp info cache. + ********************************************************************/ + +static void disp_info_cache_idle_timeout_handler(void **private_data, + time_t *ev_interval, + time_t ev_now) +{ + fstring sid_str; + DISP_INFO *disp_info = (DISP_INFO *)(*private_data); + + sid_to_string(sid_str, &disp_info->sid); + + free_samr_cache(disp_info, sid_str); + + /* Remove the event. */ + smb_unregister_idle_event(disp_info->di_cache_timeout_event); + disp_info->di_cache_timeout_event = (smb_event_id_t)0; + + DEBUG(10,("disp_info_cache_idle_timeout_handler: caching timed out for SID %s at %u\n", + sid_str, (unsigned int)ev_now)); +} + +/******************************************************************* + Setup cache removal idle event handler. + ********************************************************************/ + +static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow) +{ + fstring sid_str; + + sid_to_string(sid_str, &disp_info->sid); + + /* Remove any pending timeout and update. */ + + if (disp_info->di_cache_timeout_event) { + smb_unregister_idle_event(disp_info->di_cache_timeout_event); + disp_info->di_cache_timeout_event = (smb_event_id_t)0; + } + + DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for SID %s for %u seconds\n", + sid_str, (unsigned int)secs_fromnow )); + + disp_info->di_cache_timeout_event = + smb_register_idle_event(disp_info_cache_idle_timeout_handler, + disp_info, + secs_fromnow); +} + +/******************************************************************* + Force flush any cache. We do this on any samr_set_xxx call. + We must also remove the timeout handler. + ********************************************************************/ + +static void force_flush_samr_cache(DISP_INFO *disp_info) +{ + if (disp_info) { + fstring sid_str; + + sid_to_string(sid_str, &disp_info->sid); + if (disp_info->di_cache_timeout_event) { + smb_unregister_idle_event(disp_info->di_cache_timeout_event); + disp_info->di_cache_timeout_event = (smb_event_id_t)0; + DEBUG(10,("force_flush_samr_cache: clearing idle event for SID %s\n", + sid_str)); + } + free_samr_cache(disp_info, sid_str); + } +} + /******************************************************************* Ensure password info is never given out. Paranioa... JRA. ********************************************************************/ @@ -298,24 +452,36 @@ static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass) static uint32 count_sam_users(struct disp_info *info, uint16 acct_flags) { struct samr_displayentry *entry; - if (info->users == NULL) + if (info->users == NULL) { info->users = pdb_search_users(acct_flags); - if (info->users == NULL) - return 0; + if (info->users == NULL) { + return 0; + } + } /* Fetch the last possible entry, thus trigger an enumeration */ pdb_search_entries(info->users, 0xffffffff, 1, &entry); + + /* Ensure we cache this enumeration. */ + set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT); + return info->users->num_entries; } static uint32 count_sam_groups(struct disp_info *info) { struct samr_displayentry *entry; - if (info->groups == NULL) + if (info->groups == NULL) { info->groups = pdb_search_groups(); - if (info->groups == NULL) - return 0; + if (info->groups == NULL) { + return 0; + } + } /* Fetch the last possible entry, thus trigger an enumeration */ pdb_search_entries(info->groups, 0xffffffff, 1, &entry); + + /* Ensure we cache this enumeration. */ + set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT); + return info->groups->num_entries; } @@ -431,12 +597,12 @@ NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_ return NT_STATUS_NOT_IMPLEMENTED; } - /******************************************************************* ********************************************************************/ static BOOL get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol, - DOM_SID *sid, uint32 *acc_granted) + DOM_SID *sid, uint32 *acc_granted, + DISP_INFO **ppdisp_info) { struct samr_info *info = NULL; @@ -449,6 +615,10 @@ static BOOL get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol, *sid = info->sid; *acc_granted = info->acc_granted; + if (ppdisp_info) { + *ppdisp_info = info->disp_info; + } + return True; } @@ -467,42 +637,35 @@ NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_ r_u->status = NT_STATUS_OK; /* Get the SID. */ - if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted, NULL)) return NT_STATUS_INVALID_HANDLE; - - DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid))); /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */ /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */ - if (pol_sid.sid_rev_num == 0) - { + if (pol_sid.sid_rev_num == 0) { DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n")); r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0); - } - else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */ - - { + } else if (sid_equal(&pol_sid,get_global_sam_sid())) { + /* check if it is our domain SID */ DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid))); r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0); - } - else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */ - { + } else if (sid_equal(&pol_sid,&global_sid_Builtin)) { + /* check if it is the Builtin Domain */ /* TODO: Builtin probably needs a different SD with restricted write access*/ DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid))); r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0); - } - else if (sid_check_is_in_our_domain(&pol_sid) || - sid_check_is_in_builtin(&pol_sid)) - { + } else if (sid_check_is_in_our_domain(&pol_sid) || + sid_check_is_in_builtin(&pol_sid)) { /* TODO: different SDs have to be generated for aliases groups and users. Currently all three get a default user SD */ DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid))); r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &pol_sid, SAMR_USR_RIGHTS_WRITE_PW); + } else { + return NT_STATUS_OBJECT_TYPE_MISMATCH; } - else return NT_STATUS_OBJECT_TYPE_MISMATCH; if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL) return NT_STATUS_NO_MEMORY; @@ -594,21 +757,32 @@ NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__)); become_root(); - if ((info->disp_info.enum_users != NULL) && - (info->disp_info.enum_acb_mask != q_u->acb_mask)) { - pdb_search_destroy(info->disp_info.enum_users); - info->disp_info.enum_users = NULL; + + /* AS ROOT !!!! */ + + if ((info->disp_info->enum_users != NULL) && + (info->disp_info->enum_acb_mask != q_u->acb_mask)) { + pdb_search_destroy(info->disp_info->enum_users); + info->disp_info->enum_users = NULL; } - if (info->disp_info.enum_users == NULL) { - info->disp_info.enum_users = pdb_search_users(q_u->acb_mask); - info->disp_info.enum_acb_mask = q_u->acb_mask; + if (info->disp_info->enum_users == NULL) { + info->disp_info->enum_users = pdb_search_users(q_u->acb_mask); + info->disp_info->enum_acb_mask = q_u->acb_mask; } - if (info->disp_info.enum_users == NULL) + + if (info->disp_info->enum_users == NULL) { + /* END AS ROOT !!!! */ + unbecome_root(); return NT_STATUS_ACCESS_DENIED; - num_account = pdb_search_entries(info->disp_info.enum_users, + } + + num_account = pdb_search_entries(info->disp_info->enum_users, enum_context, max_entries, &entries); + + /* END AS ROOT !!!! */ + unbecome_root(); if (num_account == 0) { @@ -625,8 +799,14 @@ NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, if (!NT_STATUS_IS_OK(r_u->status)) return r_u->status; - if (max_entries <= num_account) + if (max_entries <= num_account) { r_u->status = STATUS_MORE_ENTRIES; + } else { + r_u->status = NT_STATUS_OK; + } + + /* Ensure we cache this enumeration. */ + set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT); DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__)); @@ -705,18 +885,23 @@ NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAM /* the domain group array is being allocated in the function below */ become_root(); - if (info->disp_info.groups == NULL) - info->disp_info.groups = pdb_search_groups(); - unbecome_root(); - if (info->disp_info.groups == NULL) - return NT_STATUS_ACCESS_DENIED; + if (info->disp_info->groups == NULL) { + info->disp_info->groups = pdb_search_groups(); - become_root(); - num_groups = pdb_search_entries(info->disp_info.groups, q_u->start_idx, + if (info->disp_info->groups == NULL) { + unbecome_root(); + return NT_STATUS_ACCESS_DENIED; + } + } + + num_groups = pdb_search_entries(info->disp_info->groups, q_u->start_idx, MAX_SAM_ENTRIES, &groups); unbecome_root(); + /* Ensure we cache this enumeration. */ + set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT); + make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_groups, groups); @@ -752,26 +937,30 @@ NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, S sid_string_static(&info->sid))); if (sid_check_is_domain(&info->sid)) - search = &info->disp_info.aliases; + search = &info->disp_info->aliases; if (sid_check_is_builtin(&info->sid)) - search = &info->disp_info.builtins; + search = &info->disp_info->builtins; if (search == NULL) return NT_STATUS_INVALID_HANDLE; become_root(); - if (*search == NULL) - *search = pdb_search_aliases(&info->sid); - unbecome_root(); - if (*search == NULL) - return NT_STATUS_ACCESS_DENIED; + if (*search == NULL) { + *search = pdb_search_aliases(&info->sid); + if (*search == NULL) { + unbecome_root(); + return NT_STATUS_ACCESS_DENIED; + } + } - become_root(); num_aliases = pdb_search_entries(*search, q_u->start_idx, MAX_SAM_ENTRIES, &aliases); unbecome_root(); + /* Ensure we cache this enumeration. */ + set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT); + make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_aliases, aliases); @@ -872,38 +1061,68 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, become_root(); + /* THe following done as ROOT. Don't return without unbecome_root(). */ + switch (q_u->switch_level) { case 0x1: case 0x4: - if (info->disp_info.users == NULL) - info->disp_info.users = pdb_search_users(ACB_NORMAL); - if (info->disp_info.users == NULL) - return NT_STATUS_ACCESS_DENIED; - num_account = pdb_search_entries(info->disp_info.users, + if (info->disp_info->users == NULL) { + info->disp_info->users = pdb_search_users(ACB_NORMAL); + if (info->disp_info->users == NULL) { + unbecome_root(); + return NT_STATUS_ACCESS_DENIED; + } + DEBUG(10,("samr_reply_query_dispinfo: starting user enumeration at index %u\n", + (unsigned int)enum_context )); + } else { + DEBUG(10,("samr_reply_query_dispinfo: using cached user enumeration at index %u\n", + (unsigned int)enum_context )); + } + + num_account = pdb_search_entries(info->disp_info->users, enum_context, max_entries, &entries); break; case 0x2: - if (info->disp_info.machines == NULL) - info->disp_info.machines = + if (info->disp_info->machines == NULL) { + info->disp_info->machines = pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST); - if (info->disp_info.machines == NULL) - return NT_STATUS_ACCESS_DENIED; - num_account = pdb_search_entries(info->disp_info.machines, + if (info->disp_info->machines == NULL) { + unbecome_root(); + return NT_STATUS_ACCESS_DENIED; + } + DEBUG(10,("samr_reply_query_dispinfo: starting machine enumeration at index %u\n", + (unsigned int)enum_context )); + } else { + DEBUG(10,("samr_reply_query_dispinfo: using cached machine enumeration at index %u\n", + (unsigned int)enum_context )); + } + + num_account = pdb_search_entries(info->disp_info->machines, enum_context, max_entries, &entries); break; case 0x3: case 0x5: - if (info->disp_info.groups == NULL) - info->disp_info.groups = pdb_search_groups(); - if (info->disp_info.groups == NULL) - return NT_STATUS_ACCESS_DENIED; - num_account = pdb_search_entries(info->disp_info.groups, + if (info->disp_info->groups == NULL) { + info->disp_info->groups = pdb_search_groups(); + if (info->disp_info->groups == NULL) { + unbecome_root(); + return NT_STATUS_ACCESS_DENIED; + } + DEBUG(10,("samr_reply_query_dispinfo: starting group enumeration at index %u\n", + (unsigned int)enum_context )); + } else { + DEBUG(10,("samr_reply_query_dispinfo: using cached group enumeration at index %u\n", + (unsigned int)enum_context )); + } + + num_account = pdb_search_entries(info->disp_info->groups, enum_context, max_entries, &entries); break; default: + unbecome_root(); smb_panic("info class changed"); break; } @@ -947,10 +1166,14 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, /* calculate the total size */ total_data_size=num_account*struct_size; - if (num_account) + if (num_account) { r_u->status = STATUS_MORE_ENTRIES; - else + } else { r_u->status = NT_STATUS_OK; + } + + /* Ensure we cache this enumeration. */ + set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT); DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__)); @@ -978,7 +1201,7 @@ NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAM DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__)); /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted, NULL)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) { return r_u->status; @@ -1096,7 +1319,7 @@ NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LO ZERO_ARRAY(rid); ZERO_ARRAY(type); - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) { + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted, NULL)) { init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH); return r_u->status; } @@ -1255,7 +1478,7 @@ NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOK DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__)); /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted, NULL)) return NT_STATUS_INVALID_HANDLE; if (num_rids > 1000) { @@ -1317,7 +1540,7 @@ NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USE /* find the domain policy handle and get domain SID / access bits in the domain policy. */ - if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) ) + if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) ) return NT_STATUS_INVALID_HANDLE; nt_status = access_check_samr_function( acc_granted, @@ -1712,7 +1935,7 @@ NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, S DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__)); /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted, NULL)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) { @@ -1766,7 +1989,7 @@ NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, S continue; gids = TALLOC_REALLOC_ARRAY(p->mem_ctx, gids, DOM_GID, num_gids+1); - gids[num_gids].attr=7; + gids[num_gids].attr= (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_ENABLED); gids[num_gids].g_rid = rid; num_gids += 1; } @@ -1858,9 +2081,9 @@ NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SA /* AS ROOT !!! */ - num_users=count_sam_users(&info->disp_info, + num_users=count_sam_users(info->disp_info, ACB_NORMAL); - num_groups=count_sam_groups(&info->disp_info); + num_groups=count_sam_groups(info->disp_info); pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp); u_logout = account_policy_temp; @@ -1993,9 +2216,10 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS; BOOL can_add_account = False; SE_PRIV se_rights; + DISP_INFO *disp_info = NULL; /* Get the domain SID stored in the domain policy */ - if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) { @@ -2141,6 +2365,9 @@ NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREA return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + /* After a "set" ensure we have no cached display info. */ + force_flush_samr_cache(info->disp_info); + r_u->user_rid=pdb_get_user_rid(sam_pass); r_u->access_granted = acc_granted; @@ -2424,7 +2651,7 @@ NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_A /* find the domain policy and get the SID / access bits stored in the domain policy */ - if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) ) + if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) ) return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, @@ -2819,13 +3046,14 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE BOOL ret; BOOL has_enough_rights = False; uint32 acb_info; + DISP_INFO *disp_info = NULL; DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__)); r_u->status = NT_STATUS_OK; /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; /* observed when joining an XP client to a Samba domain */ @@ -2941,6 +3169,10 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE /* ================ END SeMachineAccountPrivilege BLOCK ================ */ + if (NT_STATUS_IS_OK(r_u->status)) { + force_flush_samr_cache(disp_info); + } + return r_u->status; } @@ -2960,13 +3192,14 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_ BOOL ret; BOOL has_enough_rights = False; uint32 acb_info; + DISP_INFO *disp_info = NULL; DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__)); r_u->status = NT_STATUS_OK; /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; /* observed when joining XP client to Samba domain */ @@ -3047,6 +3280,10 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_ /* ================ END SeMachineAccountPrivilege BLOCK ================ */ + if (NT_STATUS_IS_OK(r_u->status)) { + force_flush_samr_cache(disp_info); + } + return r_u->status; } @@ -3130,7 +3367,7 @@ NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_ uint32 acc_granted; /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted, NULL)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = @@ -3242,7 +3479,7 @@ NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_ NTSTATUS result; /* find the policy handle. open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted, NULL)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) { @@ -3291,10 +3528,10 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD SE_PRIV se_rights; BOOL can_add_accounts; BOOL ret; - + DISP_INFO *disp_info = NULL; /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) { @@ -3318,6 +3555,10 @@ NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_AD /******** END SeAddUsers BLOCK *********/ + if (ret) { + force_flush_samr_cache(disp_info); + } + return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED; } @@ -3332,9 +3573,10 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE SE_PRIV se_rights; BOOL can_add_accounts; BOOL ret; + DISP_INFO *disp_info = NULL; /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) { @@ -3359,6 +3601,10 @@ NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DE /******** END SeAddUsers BLOCK *********/ + if (ret) { + force_flush_samr_cache(disp_info); + } + return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED; } @@ -3382,9 +3628,10 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD uint32 acc_granted; SE_PRIV se_rights; BOOL can_add_accounts; + DISP_INFO *disp_info = NULL; /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) { @@ -3470,6 +3717,9 @@ NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_AD } passwd_free(&pwd); + + force_flush_samr_cache(disp_info); + return NT_STATUS_OK; } @@ -3488,6 +3738,7 @@ NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DE uint32 acc_granted; SE_PRIV se_rights; BOOL can_add_accounts; + DISP_INFO *disp_info = NULL; /* * delete the group member named q_u->rid @@ -3496,7 +3747,7 @@ NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DE */ /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) { @@ -3555,6 +3806,9 @@ NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DE } pdb_free_sam(&sam_pass); + + force_flush_samr_cache(disp_info); + return NT_STATUS_OK; } @@ -3590,11 +3844,12 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM uint32 acc_granted; BOOL can_add_accounts; BOOL ret; + DISP_INFO *disp_info = NULL; DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__)); /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) { @@ -3651,6 +3906,8 @@ NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAM if (!close_policy_hnd(p, &q_u->user_pol)) return NT_STATUS_OBJECT_NAME_INVALID; + force_flush_samr_cache(disp_info); + return NT_STATUS_OK; } @@ -3671,11 +3928,12 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S SE_PRIV se_rights; BOOL can_add_accounts; BOOL ret; + DISP_INFO *disp_info = NULL; DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__)); /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) { @@ -3734,6 +3992,8 @@ NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, S if (!close_policy_hnd(p, &q_u->group_pol)) return NT_STATUS_OBJECT_NAME_INVALID; + force_flush_samr_cache(disp_info); + return NT_STATUS_OK; } @@ -3748,11 +4008,12 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S SE_PRIV se_rights; BOOL can_add_accounts; BOOL ret; + DISP_INFO *disp_info = NULL; DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__)); /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) { @@ -3788,6 +4049,8 @@ NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, S if (!close_policy_hnd(p, &q_u->alias_pol)) return NT_STATUS_OBJECT_NAME_INVALID; + force_flush_samr_cache(disp_info); + return NT_STATUS_OK; } @@ -3808,9 +4071,10 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S SE_PRIV se_rights; BOOL can_add_accounts; NTSTATUS result; + DISP_INFO *disp_info = NULL; /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) { @@ -3879,6 +4143,8 @@ NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, S if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info)) return NT_STATUS_OBJECT_NAME_NOT_FOUND; + force_flush_samr_cache(disp_info); + return NT_STATUS_OK; } @@ -3897,9 +4163,10 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S NTSTATUS result; SE_PRIV se_rights; BOOL can_add_accounts; + DISP_INFO *disp_info = NULL; /* Find the policy handle. Open a policy on it. */ - if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) { @@ -3951,6 +4218,8 @@ NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, S if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info)) return NT_STATUS_OBJECT_NAME_NOT_FOUND; + force_flush_samr_cache(disp_info); + return NT_STATUS_OK; } @@ -3972,7 +4241,7 @@ NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAM uint32 acc_granted; BOOL ret; - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted, NULL)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) { @@ -4029,8 +4298,9 @@ NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_ uint32 acc_granted; BOOL ret; BOOL can_mod_accounts; + DISP_INFO *disp_info = NULL; - if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) { @@ -4067,6 +4337,10 @@ NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_ /******** End SeAddUsers BLOCK *********/ + if (ret) { + force_flush_samr_cache(disp_info); + } + return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED; } @@ -4084,8 +4358,9 @@ NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_ uint32 acc_granted; BOOL ret; BOOL can_mod_accounts; + DISP_INFO *disp_info = NULL; - if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) { @@ -4120,6 +4395,10 @@ NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_ /******** End SeAddUsers BLOCK *********/ + if (ret) { + force_flush_samr_cache(disp_info); + } + return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED; } @@ -4163,7 +4442,7 @@ NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_G BOOL ret; SE_PRIV se_rights; - if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) + if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted, NULL)) return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, @@ -4226,7 +4505,8 @@ NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p, DOM_SID delete_sid, domain_sid; uint32 acc_granted; NTSTATUS result; - + DISP_INFO *disp_info = NULL; + sid_copy( &delete_sid, &q_u->sid.sid ); DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n", @@ -4235,7 +4515,7 @@ NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p, /* Find the policy handle. Open a policy on it. */ if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &domain_sid, - &acc_granted)) + &acc_granted, &disp_info)) return NT_STATUS_INVALID_HANDLE; result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, @@ -4270,6 +4550,7 @@ NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p, return NT_STATUS_OK; } + force_flush_samr_cache(disp_info); result = NT_STATUS_OK; @@ -4277,10 +4558,12 @@ NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p, } /******************************************************************* - _samr_unknown_2e + _samr_query_domain_info2 ********************************************************************/ -NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u) +NTSTATUS _samr_query_domain_info2(pipes_struct *p, + SAMR_Q_QUERY_DOMAIN_INFO2 *q_u, + SAMR_R_QUERY_DOMAIN_INFO2 *r_u) { struct samr_info *info = NULL; SAM_UNK_CTR *ctr; @@ -4309,7 +4592,7 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW r_u->status = NT_STATUS_OK; - DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__)); + 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 **)&info)) @@ -4340,13 +4623,11 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW break; case 0x02: become_root(); - num_users = count_sam_users(&info->disp_info, + num_users = count_sam_users(info->disp_info, ACB_NORMAL); - num_groups = count_sam_groups(&info->disp_info); + num_groups = count_sam_groups(info->disp_info); unbecome_root(); - free_samr_db(info); - pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp); u_logout = account_policy_temp; @@ -4410,9 +4691,9 @@ NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOW return NT_STATUS_INVALID_INFO_CLASS; } - init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK); + init_samr_r_samr_query_domain_info2(r_u, q_u->switch_value, ctr, NT_STATUS_OK); - DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__)); + DEBUG(5,("_samr_query_domain_info2: %d\n", __LINE__)); return r_u->status; } diff --git a/source/rpc_server/srv_util.c b/source/rpc_server/srv_util.c index 79d5d06d23a..3666d474787 100644 --- a/source/rpc_server/srv_util.c +++ b/source/rpc_server/srv_util.c @@ -102,7 +102,7 @@ NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid, for (i=PRIMARY_GROUP_SID_INDEX; i < nt_token->num_sids; i++) { if (sid_compare_domain(domain_sid, &nt_token->user_sids[i])==0) { sid_peek_rid(&nt_token->user_sids[i], &(gids[*numgroups].g_rid)); - gids[*numgroups].attr=7; + gids[*numgroups].attr= (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|SE_GROUP_ENABLED); (*numgroups)++; } } diff --git a/source/rpcclient/cmd_lsarpc.c b/source/rpcclient/cmd_lsarpc.c index 2cc1ffcca0f..5a0ba054833 100644 --- a/source/rpcclient/cmd_lsarpc.c +++ b/source/rpcclient/cmd_lsarpc.c @@ -934,7 +934,7 @@ static NTSTATUS cmd_lsa_query_trustdominfo(struct rpc_pipe_client *cli, goto done; result = rpccli_lsa_query_trusted_domain_info(cli, mem_ctx, &trustdom_pol, - info_class, &dom_sid, &info); + info_class, &info); if (!NT_STATUS_IS_OK(result)) goto done; diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c index 665fe342265..6ff2bce8518 100644 --- a/source/rpcclient/cmd_samr.c +++ b/source/rpcclient/cmd_samr.c @@ -404,10 +404,19 @@ static void display_group_info1(GROUP_INFO1 *info1) printf("\tGroup Name:\t%s\n", temp); unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp)-1); printf("\tDescription:\t%s\n", temp); - printf("\tunk1:%d\n", info1->unknown_1); + printf("\tGroup Attribute:%d\n", info1->group_attr); printf("\tNum Members:%d\n", info1->num_members); } +/**************************************************************************** + display group info + ****************************************************************************/ +static void display_group_info3(GROUP_INFO3 *info3) +{ + printf("\tGroup Attribute:%d\n", info3->group_attr); +} + + /**************************************************************************** display group info ****************************************************************************/ @@ -429,6 +438,10 @@ static void display_group_info_ctr(GROUP_INFO_CTR *ctr) display_group_info1(&ctr->group.info1); break; } + case 3: { + display_group_info3(&ctr->group.info3); + break; + } case 4: { display_group_info4(&ctr->group.info4); break; diff --git a/source/script/installman.sh b/source/script/installman.sh index 6278012635f..3bbca1a8aa5 100755 --- a/source/script/installman.sh +++ b/source/script/installman.sh @@ -18,6 +18,10 @@ if test ! -d $SRCDIR../docs/manpages; then exit 0 fi +# Get the configured feature set +test -f "${SRCDIR}/config.log" && \ + eval $( grep "^[[:alnum:]]*=.*" "${SRCDIR}/config.log") + for lang in $langs; do if [ "X$lang" = XC ]; then echo Installing default man pages in $MANDIR/ @@ -40,13 +44,20 @@ for lang in $langs; do for sect in 1 5 7 8 ; do for m in $langdir/man$sect ; do for s in $SRCDIR../docs/manpages/$lang/*$sect; do - FNAME=$m/`basename $s` - + MP_BASENAME=${s##*/} + + # Check if this man page if required by the configured feature set + case "${MP_BASENAME}" in + smbsh.1) test -z "${SMBWRAPPER}" && continue ;; + *) ;; + esac + + FNAME="$m/${MP_BASENAME}" + # Test for writability. Involves # blowing away existing files. if (rm -f $FNAME && touch $FNAME); then - rm $FNAME if [ "x$GROFF" = x ] ; then cp $s $m # Copy raw nroff else diff --git a/source/script/mkproto.awk b/source/script/mkproto.awk index 73a1c2b3f0a..a0f3096c842 100644 --- a/source/script/mkproto.awk +++ b/source/script/mkproto.awk @@ -136,7 +136,7 @@ END { gotstart = 1; } - if( $0 ~ /^NODE_STATUS_STRUCT|SMB_STRUCT_DIR/ ) { + if( $0 ~ /^NODE_STATUS_STRUCT|SMB_STRUCT_DIR|ELOG_TDB/ ) { gotstart = 1; } diff --git a/source/services/services_db.c b/source/services/services_db.c index 5c87225f573..c75cb38c48b 100644 --- a/source/services/services_db.c +++ b/source/services/services_db.c @@ -35,43 +35,51 @@ struct service_display_info { }; struct service_display_info builtin_svcs[] = { - { "Spooler", "smbd", "Print Spooler", - "Internal service for spooling files to print devices" }, - { "NETLOGON", "smbd", "Net Logon", - "File service providing access to policy and profile data" }, - { "RemoteRegistry", "smbd", "Remote Registry Service", - "Internal service providing remote access to the Samba registry" }, - { "WINS", "nmbd", "Windows Internet Name Service (WINS)", - "Internal service providing a NetBIOS point-to-point name server" }, + { "Spooler", "smbd", "Print Spooler", "Internal service for spooling files to print devices" }, + { "NETLOGON", "smbd", "Net Logon", "File service providing access to policy and profile data" }, + { "RemoteRegistry", "smbd", "Remote Registry Service", "Internal service providing remote access to " + "the Samba registry" }, + { "WINS", "nmbd", "Windows Internet Name Service (WINS)", "Internal service providing a " + "NetBIOS point-to-point name server" }, { NULL, NULL, NULL, NULL } }; struct service_display_info common_unix_svcs[] = { - { "cups", NULL, "Common Unix Printing System", NULL }, - { "postfix", NULL, "Internet Mail Service", NULL }, - { "sendmail", NULL, "Internet Mail Service", NULL }, - { "portmap", NULL, "TCP Port to RPC PortMapper", NULL }, - { "xinetd", NULL, "Internet Meta-Daemon", NULL }, - { "inet", NULL, "Internet Meta-Daemon", NULL }, - { "xntpd", NULL, "Network Time Service", NULL }, - { "ntpd", NULL, "Network Time Service", NULL }, - { "lpd", NULL, "BSD Print Spooler", NULL }, - { "nfsserver", NULL, "Network File Service", NULL }, - { "cron", NULL, "Scheduling Service", NULL }, - { "at", NULL, "Scheduling Service", NULL }, - { "nscd", NULL, "Name Service Cache Daemon", NULL }, - { "slapd", NULL, "LDAP Directory Service", NULL }, - { "ldap", NULL, "LDAP DIrectory Service", NULL }, - { "ypbind", NULL, "NIS Directory Service", NULL }, - { "courier-imap", NULL, "IMAP4 Mail Service", NULL }, - { "courier-pop3", NULL, "POP3 Mail Service", NULL }, - { "named", NULL, "Domain Name Service", NULL }, - { "bind", NULL, "Domain Name Service", NULL }, - { "httpd", NULL, "HTTP Server", NULL }, - { "apache", NULL, "HTTP Server", NULL }, - { "autofs", NULL, "Automounter", NULL }, - { "squid", NULL, "Web Cache Proxy ", NULL }, + { "cups", NULL, "Common Unix Printing System","Provides unified printing support for all operating systems" }, + { "postfix", NULL, "Internet Mail Service", "Provides support for sending and receiving electonic mail" }, + { "sendmail", NULL, "Internet Mail Service", "Provides support for sending and receiving electonic mail" }, + { "portmap", NULL, "TCP Port to RPC PortMapper",NULL }, + { "xinetd", NULL, "Internet Meta-Daemon", NULL }, + { "inet", NULL, "Internet Meta-Daemon", NULL }, + { "xntpd", NULL, "Network Time Service", NULL }, + { "ntpd", NULL, "Network Time Service", NULL }, + { "lpd", NULL, "BSD Print Spooler", NULL }, + { "nfsserver", NULL, "Network File Service", NULL }, + { "cron", NULL, "Scheduling Service", NULL }, + { "at", NULL, "Scheduling Service", NULL }, + { "nscd", NULL, "Name Service Cache Daemon", NULL }, + { "slapd", NULL, "LDAP Directory Service", NULL }, + { "ldap", NULL, "LDAP DIrectory Service", NULL }, + { "ypbind", NULL, "NIS Directory Service", NULL }, + { "courier-imap", NULL, "IMAP4 Mail Service", NULL }, + { "courier-pop3", NULL, "POP3 Mail Service", NULL }, + { "named", NULL, "Domain Name Service", NULL }, + { "bind", NULL, "Domain Name Service", NULL }, + { "httpd", NULL, "HTTP Server", NULL }, + { "apache", NULL, "HTTP Server", "Provides s highly scalable and flexible web server " + "capable of implementing various protocols incluing " + "but not limited to HTTP" }, + { "autofs", NULL, "Automounter", NULL }, + { "squid", NULL, "Web Cache Proxy ", NULL }, { "perfcountd", NULL, "Performance Monitoring Daemon", NULL }, + { "pgsql", NULL, "PgSQL Database Server", "Provides service for SQL database from Postgresql.org" }, + { "arpwatch", NULL, "ARP Tables watcher", "Provides service for monitoring ARP tables for changes" }, + { "dhcpd", NULL, "DHCP Server", "Provides service for dynamic host configuration and IP assignment" }, + { "nwserv", NULL, "NetWare Server Emulator", "Provides service for emulating Novell NetWare 3.12 server" }, + { "proftpd", NULL, "Professional FTP Server", "Provides high configurable service for FTP connection and " + "file transferring" }, + { "ssh2", NULL, "SSH Secure Shell", "Provides service for secure connection for remote administration" }, + { "sshd", NULL, "SSH Secure Shell", "Provides service for secure connection for remote administration" }, { NULL, NULL, NULL, NULL } }; diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c index fec148b8e63..532c79043a2 100644 --- a/source/smbd/dosmode.c +++ b/source/smbd/dosmode.c @@ -126,7 +126,7 @@ mode_t unix_mode(connection_struct *conn, int dosmode, const char *fname, BOOL c Change a unix mode to a dos mode. ****************************************************************************/ -uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) +static uint32 dos_mode_from_sbuf(connection_struct *conn, const char *path, SMB_STRUCT_STAT *sbuf) { int result = 0; enum mapreadonly_options ro_opts = (enum mapreadonly_options)lp_map_readonly(SNUM(conn)); diff --git a/source/smbd/filename.c b/source/smbd/filename.c index b389b9c1ae7..2ee8ba1e4ff 100644 --- a/source/smbd/filename.c +++ b/source/smbd/filename.c @@ -150,9 +150,6 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen pstrcpy(saved_last_component, name); } - if (!conn->case_preserve || (mangle_is_8_3(name, False, SNUM(conn)) && !conn->short_case_preserve)) - strnorm(name, lp_defaultcase(SNUM(conn))); - start = name; pstrcpy(orig_path, name); @@ -301,16 +298,17 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen return(False); } - /* + /* * Just the last part of the name doesn't exist. - * We may need to strupper() or strlower() it in case - * this conversion is being used for file creation - * purposes. If the filename is of mixed case then - * don't normalise it. + * We need to strupper() or strlower() it as + * this conversion may be used for file creation + * purposes. Fix inspired by Thomas Neumann . */ - - if (!conn->case_preserve && (!strhasupper(start) || !strhaslower(start))) + if (!conn->case_preserve || + (mangle_is_8_3(start, False, SNUM(conn)) && + !conn->short_case_preserve)) { strnorm(start, lp_defaultcase(SNUM(conn))); + } /* * check on the mangled stack to see if we can recover the diff --git a/source/smbd/session.c b/source/smbd/session.c index 9a9a0d90b24..27f760a088e 100644 --- a/source/smbd/session.c +++ b/source/smbd/session.c @@ -198,7 +198,8 @@ void session_yield(user_struct *vuser) tdb_delete(tdb, key); } -static BOOL session_traverse(int (*fn)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *), void *state) +BOOL session_traverse(int (*fn)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *), + void *state) { if (!session_init()) { DEBUG(3, ("No tdb opened\n")); diff --git a/source/smbd/sesssetup.c b/source/smbd/sesssetup.c index 2c967601678..a22a575c762 100644 --- a/source/smbd/sesssetup.c +++ b/source/smbd/sesssetup.c @@ -168,6 +168,7 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_NO_MEMORY); if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) { + talloc_destroy(mem_ctx); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -177,6 +178,7 @@ static int reply_spnego_kerberos(connection_struct *conn, if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("Failed to verify incoming ticket!\n")); + talloc_destroy(mem_ctx); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -188,6 +190,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); SAFE_FREE(client); + talloc_destroy(mem_ctx); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -206,6 +209,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); SAFE_FREE(client); + talloc_destroy(mem_ctx); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } } @@ -283,6 +287,7 @@ static int reply_spnego_kerberos(connection_struct *conn, SAFE_FREE(client); data_blob_free(&ap_rep); data_blob_free(&session_key); + talloc_destroy(mem_ctx); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } } @@ -302,6 +307,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); passwd_free(&pw); + talloc_destroy(mem_ctx); return ERROR_NT(ret); } @@ -314,6 +320,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); passwd_free(&pw); + talloc_destroy(mem_ctx); return ERROR_NT(ret); } @@ -737,6 +744,29 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, a new session setup with VC==0 is ignored. ****************************************************************************/ +static int shutdown_other_smbds(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, + void *p) +{ + struct sessionid *sessionid = (struct sessionid *)dbuf.dptr; + const char *ip = (const char *)p; + + if (!process_exists(pid_to_procid(sessionid->pid))) { + return 0; + } + + if (sessionid->pid == sys_getpid()) { + return 0; + } + + if (strcmp(ip, sessionid->ip_addr) != 0) { + return 0; + } + + message_send_pid(pid_to_procid(sessionid->pid), MSG_SHUTDOWN, + NULL, 0, True); + return 0; +} + static void setup_new_vc_session(void) { DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x compatible we would close all old resources.\n")); @@ -744,6 +774,9 @@ static void setup_new_vc_session(void) conn_close_all(); invalidate_all_vuids(); #endif + if (lp_reset_on_zero_vc()) { + session_traverse(shutdown_other_smbds, client_addr()); + } } /**************************************************************************** diff --git a/source/utils/eventlogadm.c b/source/utils/eventlogadm.c index 31e853b61f4..1d60d6b7ea8 100644 --- a/source/utils/eventlogadm.c +++ b/source/utils/eventlogadm.c @@ -79,7 +79,7 @@ int DoWriteCommand( int argc, char **argv, BOOL debugflag, char *exename ) { FILE *f1; char *argfname; - TDB_CONTEXT *elog_tdb; + ELOG_TDB *etdb; /* fixed constants are bad bad bad */ pstring linein; @@ -100,7 +100,7 @@ int DoWriteCommand( int argc, char **argv, BOOL debugflag, char *exename ) argfname = argv[0]; - if ( !( elog_tdb = elog_open_tdb( argfname ) ) ) { + if ( !( etdb = elog_open_tdb( argfname, False ) ) ) { printf( "can't open the eventlog TDB (%s)\n", argfname ); return -1; } @@ -130,7 +130,7 @@ int DoWriteCommand( int argc, char **argv, BOOL debugflag, char *exename ) /* printf("Writing to the event log\n"); */ - rcnum = write_eventlog_tdb( elog_tdb, &ee ); + rcnum = write_eventlog_tdb( ELOG_TDB_CTX(etdb), &ee ); if ( !rcnum ) { printf( "Can't write to the event log\n" ); } else { @@ -146,7 +146,7 @@ int DoWriteCommand( int argc, char **argv, BOOL debugflag, char *exename ) } } - tdb_close( elog_tdb ); + elog_close_tdb( etdb , False ); return 0; } diff --git a/source/utils/net_lookup.c b/source/utils/net_lookup.c index 3a6781f7621..cd62245600d 100644 --- a/source/utils/net_lookup.c +++ b/source/utils/net_lookup.c @@ -85,7 +85,7 @@ static void print_ldap_srvlist(char *srvlist) static int net_lookup_ldap(int argc, const char **argv) { -#ifdef HAVE_LDAP +#ifdef HAVE_ADS char *srvlist; const char *domain; int rc; @@ -127,7 +127,7 @@ static int net_lookup_ldap(int argc, const char **argv) } return -1; #endif - DEBUG(1,("No LDAP support\n")); + DEBUG(1,("No ADS support\n")); return -1; } diff --git a/source/utils/smbget.c b/source/utils/smbget.c index e8069802ca9..eab5e5ac02f 100644 --- a/source/utils/smbget.c +++ b/source/utils/smbget.c @@ -28,6 +28,10 @@ int columns = 0; +static int _resume, _recursive, debuglevel; +static char *outputfile; + + time_t total_start_time = 0; off_t total_bytes = 0; @@ -507,16 +511,13 @@ int readrcfile(const char *name, const struct poptOption long_options[]) int main(int argc, const char **argv) { - int resume = 0, recursive = 0; int c = 0; - int debuglevel = 0; const char *file = NULL; char *rcfile = NULL; - char *outputfile = NULL; struct poptOption long_options[] = { {"guest", 'a', POPT_ARG_NONE, NULL, 'a', "Work as user guest" }, - {"resume", 'r', POPT_ARG_NONE, &resume, 0, "Automatically resume aborted files" }, - {"recursive", 'R', POPT_ARG_NONE, &recursive, 0, "Recursively download files" }, + {"resume", 'r', POPT_ARG_NONE, &_resume, 0, "Automatically resume aborted files" }, + {"recursive", 'R', POPT_ARG_NONE, &_recursive, 0, "Recursively download files" }, {"username", 'u', POPT_ARG_STRING, &username, 'u', "Username to use" }, {"password", 'p', POPT_ARG_STRING, &password, 'p', "Password to use" }, {"workgroup", 'w', POPT_ARG_STRING, &workgroup, 'w', "Workgroup to use (optional)" }, @@ -537,7 +538,8 @@ int main(int argc, const char **argv) /* only read rcfile if it exists */ asprintf(&rcfile, "%s/.smbgetrc", getenv("HOME")); - if(access(rcfile, F_OK) == 0) readrcfile(rcfile, long_options); + if(access(rcfile, F_OK) == 0) + readrcfile(rcfile, long_options); free(rcfile); #ifdef SIGWINCH @@ -559,7 +561,7 @@ int main(int argc, const char **argv) } } - if((send_stdout || outputfile) && recursive) { + if((send_stdout || outputfile) && _recursive) { fprintf(stderr, "The -o or -O and -R options can not be used together.\n"); return 1; } @@ -578,9 +580,11 @@ int main(int argc, const char **argv) total_start_time = time(NULL); - while((file = poptGetArg(pc))) { - if(!recursive) return smb_download_file(file, "", recursive, resume, outputfile); - else return smb_download_dir(file, "", resume); + while ( (file = poptGetArg(pc)) ) { + if (!_recursive) + return smb_download_file(file, "", _recursive, _resume, outputfile); + else + return smb_download_dir(file, "", _resume); } clean_exit(); -- cgit