diff options
40 files changed, 430 insertions, 192 deletions
diff --git a/source/Makefile.in b/source/Makefile.in index c7ee496c77a..86b104bf696 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -97,8 +97,12 @@ LIBSMBCLIENT=bin/libsmbclient.a @LIBSMBCLIENT_SHARED@ LIBSMBCLIENT_MAJOR=0 LIBSMBCLIENT_MINOR=1 +LIBSMBSHAREMODES=bin/libsmbsharemodes.a @LIBSMBSHAREMODES_SHARED@ +LIBSMBSHAREMODES_MAJOR=0 +LIBSMBSHAREMODES_MINOR=1 -FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx @SMBWRAP_INC@ -I. $(CPPFLAGS) -I$(srcdir) + +FLAGS1 = $(CFLAGS) @FLAGS1@ -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx @SMBWRAP_INC@ -I. $(CPPFLAGS) -I$(srcdir) -I$(srcdir)/tdb FLAGS2 = FLAGS3 = FLAGS4 = @@ -137,7 +141,7 @@ BIN_PROGS = $(BIN_PROGS1) $(BIN_PROGS2) $(BIN_PROGS3) @EXTRA_BIN_PROGS@ EVERYTHING_PROGS = bin/debug2html@EXEEXT@ bin/smbfilter@EXEEXT@ bin/talloctort@EXEEXT@ \ bin/log2pcap@EXEEXT@ -SHLIBS = @SHLIB_PROGS@ @LIBSMBCLIENT@ +SHLIBS = @SHLIB_PROGS@ @LIBSMBCLIENT@ @LIBSMBSHAREMODES@ SCRIPTS = $(srcdir)/script/smbtar $(builddir)/script/findsmb @@ -510,6 +514,7 @@ LIBSMBCLIENT_OBJ = libsmb/libsmbclient.o libsmb/libsmb_compat.o \ $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) \ $(SECRETS_OBJ) $(PASSDB_OBJ) $(SMBLDAP_OBJ) $(GROUPDB_OBJ) +LIBSMBSHAREMODES_OBJ = libsmb/smb_share_modes.o tdb/tdb.o tdb/spinlock.o # This shared library is intended for linking with unit test programs # to test Samba internals. It's called libbigballofmud.so to # discourage casual usage. @@ -633,6 +638,7 @@ WINBIND_WINS_NSS_PICOBJS = $(WINBIND_WINS_NSS_OBJ:.o=.@PICSUFFIX@) PICOBJS = $(SMBWRAPPER_OBJ:.o=.@PICSUFFIX@) LIBSMBCLIENT_PICOBJS = $(LIBSMBCLIENT_OBJ:.o=.@PICSUFFIX@) +LIBSMBSHAREMODES_PICOBJS = $(LIBSMBSHAREMODES_OBJ:.o=.@PICSUFFIX@) PAM_SMBPASS_OBJ_0 = pam_smbpass/pam_smb_auth.o pam_smbpass/pam_smb_passwd.o \ pam_smbpass/pam_smb_acct.o pam_smbpass/support.o \ @@ -996,6 +1002,16 @@ bin/libsmbclient.a: $(LIBSMBCLIENT_PICOBJS) @echo Linking libsmbclient non-shared library $@ @-$(AR) -rc $@ $(LIBSMBCLIENT_PICOBJS) +bin/libsmbsharemodes.@SHLIBEXT@: $(LIBSMBSHAREMODES_PICOBJS) + @echo Linking libsmbsharemodes shared library $@ + @$(SHLD) $(LDSHFLAGS) -o $@ $(LIBSMBSHAREMODES_PICOBJS) $(LDFLAGS) $(LIBS) \ + $(KRB5LIBS) $(LDAP_LIBS) \ + @SONAMEFLAG@`basename $@`.$(LIBSMBSHAREMODES_MAJOR) + +bin/libsmbsharemodes.a: $(LIBSMBSHAREMODES_PICOBJS) + @echo Linking libsmbsharemodes non-shared library $@ + @-$(AR) -rc $@ $(LIBSMBSHAREMODES_PICOBJS) + # This is probably wrong for anything other than the GNU linker. bin/libbigballofmud.@SHLIBEXT@: $(LIBBIGBALLOFMUD_PICOBJS) @echo Linking bigballofmud shared library $@ @@ -1010,6 +1026,7 @@ bin/libbigballofmud.@SHLIBEXT@: $(LIBBIGBALLOFMUD_PICOBJS) # library. libsmbclient: $(LIBSMBCLIENT) +libsmbsharemodes: $(LIBSMBSHAREMODES) bin/librpc_lsarpc.@SHLIBEXT@: $(RPC_LSA_OBJ) @echo "Linking $@" @@ -1433,7 +1450,8 @@ TOPFILES=dynconfig.o dynconfig.@PICSUFFIX@ clean: delheaders python_clean -rm -f core */*~ *~ */*.o */*.@PICSUFFIX@ */*.@SHLIBEXT@ \ $(TOPFILES) $(BIN_PROGS) $(SBIN_PROGS) $(MODULES) $(TORTURE_PROGS) \ - $(LIBSMBCLIENT) $(EVERYTHING_PROGS) .headers.stamp + $(LIBSMBCLIENT) $(LIBSMBSHAREMODES) $(EVERYTHING_PROGS) .headers.stamp + -rm -rf t_dir # Making this target will just make sure that the prototype files # exist, not necessarily that they are up to date. Since they're diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c index 0c3b0b321e8..a6136a9e2c2 100755 --- a/source/client/mount.cifs.c +++ b/source/client/mount.cifs.c @@ -506,6 +506,8 @@ static int parse_options(char * options, int * filesys_flags) *filesys_flags &= ~MS_NOSUID; } else if (strncmp(data, "nodev", 5) == 0) { *filesys_flags |= MS_NODEV; + } else if (strncmp(data, "nobrl", 5) == 0) { + *filesys_flags &= ~MS_MANDLOCK; } else if (strncmp(data, "dev", 3) == 0) { *filesys_flags &= ~MS_NODEV; } else if (strncmp(data, "noexec", 6) == 0) { @@ -1138,8 +1140,6 @@ mount_retry: strcat(mountent.mnt_opts,"rw"); if(flags & MS_MANDLOCK) strcat(mountent.mnt_opts,",mand"); - else - strcat(mountent.mnt_opts,",nomand"); if(flags & MS_NOEXEC) strcat(mountent.mnt_opts,",noexec"); if(flags & MS_NOSUID) diff --git a/source/configure.in b/source/configure.in index 0341e9fbe9f..18cc099badb 100644 --- a/source/configure.in +++ b/source/configure.in @@ -219,6 +219,8 @@ AC_SUBST(INSTALLCLIENTCMD_SH) AC_SUBST(INSTALLCLIENTCMD_A) AC_SUBST(LIBSMBCLIENT_SHARED) AC_SUBST(LIBSMBCLIENT) +AC_SUBST(LIBSMBSHAREMODES_SHARED) +AC_SUBST(LIBSMBSHAREMODES) AC_SUBST(PRINT_LIBS) AC_SUBST(AUTH_LIBS) AC_SUBST(ACL_LIBS) @@ -729,9 +731,9 @@ AC_HEADER_DIRENT AC_HEADER_TIME AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(aio.h arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h rpc/nettype.h) -AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h limits.h memory.h) +AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h limits.h memory.h alloca.h) AC_CHECK_HEADERS(rpc/rpc.h rpcsvc/nis.h rpcsvc/ypclnt.h) -AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h) +AC_CHECK_HEADERS(sys/param.h ctype.h sys/wait.h sys/resource.h sys/ioctl.h sys/ipc.h sys/prctl.h) AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h sys/shm.h string.h strings.h stdlib.h sys/socket.h) AC_CHECK_HEADERS(sys/un.h) AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h) @@ -1158,6 +1160,15 @@ AC_CHECK_FUNCS(__sys_llseek llseek _llseek __llseek readdir64 _readdir64 __readd AC_CHECK_FUNCS(pread _pread __pread pread64 _pread64 __pread64) AC_CHECK_FUNCS(pwrite _pwrite __pwrite pwrite64 _pwrite64 __pwrite64) AC_CHECK_FUNCS(open64 _open64 __open64 creat64) +AC_CHECK_FUNCS(prctl) + +AC_TRY_COMPILE([ +#ifdef HAVE_SYS_PRCTL_H +#include <sys/prctl.h> +#endif +], +[int i; i = prtcl(0); ], +AC_DEFINE(HAVE_PRCTL, 1, [Whether prctl is available]),[]) # # @@ -3504,8 +3515,8 @@ samba_cv_WITH_QUOTAS=auto samba_cv_TRY_QUOTAS=no samba_cv_RUN_QUOTA_TESTS=auto samba_cv_WITH_SYS_QUOTAS=auto -samba_cv_TRY_SYS_QUOTAS=no -samba_cv_SYSQUOTA_FOUND=no; +samba_cv_TRY_SYS_QUOTAS=auto +samba_cv_SYSQUOTA_FOUND=no AC_MSG_CHECKING(whether to try disk-quotas support) AC_ARG_WITH(quotas, @@ -3568,18 +3579,13 @@ AC_ARG_WITH(sys-quotas, AC_MSG_RESULT(${samba_cv_TRY_SYS_QUOTAS}) ) -if test x"$samba_cv_TRY_SYS_QUOTAS" != x"no"; then +if test x"$samba_cv_TRY_SYS_QUOTAS" = x"auto"; then AC_MSG_CHECKING(whether to try the lib/sysquotas.c interface on ${host_os}) case "$host_os" in *linux*) AC_MSG_RESULT(yes) samba_cv_TRY_SYS_QUOTAS=yes samba_cv_RUN_QUOTA_TESTS=yes - samba_cv_SYSQUOTA_FOUND=yes - AC_DEFINE(HAVE_QUOTACTL_LINUX,1,[Whether Linux quota support is available]) - samba_cv_sysquotas_file="lib/sysquotas_linux.c" - AC_DEFINE(HAVE_LINUX_XFS_QUOTAS,1,[Whether Linux xfs quota support is available]) - samba_cv_found_xfs_header=yes ;; *) AC_MSG_RESULT(no) @@ -3592,6 +3598,24 @@ fi # only check for quota stuff if --with-quotas if test x"$samba_cv_RUN_QUOTA_TESTS" != x"no"; then +case "$host_os" in + # on linux we didn't need to test we have builtin support + *linux*) + samba_cv_SYSQUOTA_FOUND=yes + AC_DEFINE(HAVE_QUOTACTL_LINUX,1,[Whether Linux quota support is available]) + samba_cv_sysquotas_file="lib/sysquotas_linux.c" + AC_MSG_CHECKING(whether to use the lib/sysquotas_linux.c builtin support) + AC_MSG_RESULT(yes) + + AC_DEFINE(HAVE_LINUX_XFS_QUOTAS,1,[Whether Linux xfs quota support is available]) + samba_cv_found_xfs_header=yes + AC_MSG_CHECKING(whether to use the lib/sysquotas_xfs.c builtin support) + AC_MSG_RESULT(yes) + ;; + *) + ;; +esac + # some broken header files need this AC_CHECK_HEADER(asm/types.h,[ AC_DEFINE(HAVE_ASM_TYPES_H,1,[check for <asm/types.h>]) @@ -3881,6 +3905,56 @@ AC_ARG_WITH(libsmbclient, ) +INSTALLCLIENTCMD_SH=: +INSTALLCLIENTCMD_A=: +INSTALLCLIENT= +LIBSMBSHAREMODES_SHARED= +LIBSMBSHAREMODES= +AC_MSG_CHECKING(whether to build the libsmbsharemodes shared library) +AC_ARG_WITH(libsmbsharemodes, +[ --with-libsmbsharemodes Build the libsmbsharemodes shared library (default=yes if shared libs supported)], +[ case "$withval" in + no) + AC_MSG_RESULT(no) + ;; + *) + if test $BLDSHARED = true; then + INSTALLCLIENTCMD_SH="\$(INSTALLCMD)" + ## build the static version of libsmbsharemodes as well + INSTALLCLIENTCMD_A="\$(INSTALLCMD)" + LIBSMBSHAREMODES_SHARED=bin/libsmbsharemodes.$SHLIBEXT + LIBSMBSHAREMODES=libsmbsharemodes + AC_MSG_RESULT(yes) + else + enable_static=yes + AC_MSG_RESULT(no shared library support -- will supply static library) + fi + if test $enable_static = yes; then + INSTALLCLIENTCMD_A="\$(INSTALLCMD)" + LIBSMBSHAREMODES=libsmbsharemodes + fi + INSTALLCLIENT=installclientlib + ;; + esac ], +[ +# if unspecified, default is to built it iff possible. + if test $BLDSHARED = true; then + INSTALLCLIENTCMD_SH="\$(INSTALLCMD)" + LIBSMBSHAREMODES_SHARED=bin/libsmbsharemodes.$SHLIBEXT + LIBSMBSHAREMODES=libsmbsharemodes + AC_MSG_RESULT(yes) + else + enable_static=yes + AC_MSG_RESULT(no shared library support -- will supply static library) + fi + if test $enable_static = yes; then + INSTALLCLIENTCMD_A="\$(INSTALLCMD)" + LIBSMBSHAREMODES=libsmbsharemodes + fi] + INSTALLCLIENT=installclientlib +) + + ################################################# # these tests are taken from the GNU fileutils package AC_CHECKING(how to get filesystem space usage) diff --git a/source/include/libsmbclient.h b/source/include/libsmbclient.h index 3269d6f0bf7..2d7d96c2dd0 100644 --- a/source/include/libsmbclient.h +++ b/source/include/libsmbclient.h @@ -105,15 +105,15 @@ struct smbc_dirent /** Length of this smbc_dirent in bytes */ unsigned int dirlen; - /** The length of the comment string in bytes (includes null - * terminator) + /** The length of the comment string in bytes (does not include + * null terminator) */ unsigned int commentlen; /** Points to the null terminated comment string */ char *comment; - /** The length of the name string in bytes (includes null - * terminator) + /** The length of the name string in bytes (does not include + * null terminator) */ unsigned int namelen; /** Points to the null terminated name string diff --git a/source/lib/fault.c b/source/lib/fault.c index d8364ff2257..3cb66846393 100644 --- a/source/lib/fault.c +++ b/source/lib/fault.c @@ -35,7 +35,8 @@ static void fault_report(int sig) DEBUG(0,("===============================================================\n")); DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)sys_getpid(),SAMBA_VERSION_STRING)); - DEBUG(0,("\nPlease read the appendix Bugs of the Samba HOWTO collection\n")); + DEBUG(0,("\nPlease read the Trouble-Shooting section of the Samba3-HOWTO\n")); + DEBUG(0,("\nFrom: http://www.samba.org/samba/docs/Samba3-HOWTO.pdf\n")); DEBUG(0,("===============================================================\n")); smb_panic("internal error"); diff --git a/source/lib/sysquotas_4A.c b/source/lib/sysquotas_4A.c index 5596481bd29..99b1a13e997 100644 --- a/source/lib/sysquotas_4A.c +++ b/source/lib/sysquotas_4A.c @@ -24,6 +24,12 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_QUOTA +#ifndef HAVE_SYS_QUOTAS +#ifdef HAVE_QUOTACTL_4A +#undef HAVE_QUOTACTL_4A +#endif +#endif + #ifdef HAVE_QUOTACTL_4A /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */ /* this is used by: HPUX,IRIX */ diff --git a/source/lib/sysquotas_linux.c b/source/lib/sysquotas_linux.c index 4c024b04cc4..28a86196e2b 100644 --- a/source/lib/sysquotas_linux.c +++ b/source/lib/sysquotas_linux.c @@ -24,6 +24,12 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_QUOTA +#ifndef HAVE_SYS_QUOTAS +#ifdef HAVE_QUOTACTL_LINUX +#undef HAVE_QUOTACTL_LINUX +#endif +#endif + #ifdef HAVE_QUOTACTL_LINUX #include "samba_linux_quota.h" diff --git a/source/lib/util.c b/source/lib/util.c index f66397104d6..39938921968 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -1618,7 +1618,7 @@ void smb_panic2(const char *why, BOOL decrement_pid_count ) A readdir wrapper which just returns the file name. ********************************************************************/ -const char *readdirname(DIR *p) +const char *readdirname(SMB_STRUCT_DIR *p) { SMB_STRUCT_DIRENT *ptr; char *dname; diff --git a/source/libads/kerberos_verify.c b/source/libads/kerberos_verify.c index d6cca793187..770d129e5da 100644 --- a/source/libads/kerberos_verify.c +++ b/source/libads/kerberos_verify.c @@ -86,7 +86,6 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut goto out; } - ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor); if (ret != KRB5_KT_END && ret != ENOENT ) { while (!auth_ok && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) { ret = krb5_unparse_name(context, kt_entry.principal, &entry_princ_s); @@ -128,7 +127,11 @@ static BOOL ads_keytab_verify_ticket(krb5_context context, krb5_auth_context aut ZERO_STRUCT(kt_cursor); out: - + + for (i = 0; i < sizeof(valid_princ_formats) / sizeof(valid_princ_formats[0]); i++) { + SAFE_FREE(valid_princ_formats[i]); + } + if (!auth_ok) { if (!number_matched_principals) { DEBUG(3, ("ads_keytab_verify_ticket: no keytab principals matched expected file service name.\n")); diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c index e70c2b8beca..1741c1db3cd 100644 --- a/source/libsmb/clikrb5.c +++ b/source/libsmb/clikrb5.c @@ -119,8 +119,10 @@ DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); return ret; } - return krb5_string_to_key_salt(context, enctype, password->data, - salt, key); + + ret = krb5_string_to_key_salt(context, enctype, password->data, salt, key); + krb5_free_salt(context, salt); + return ret; } #else #error UNKNOWN_CREATE_KEY_FUNCTIONS diff --git a/source/libsmb/credentials.c b/source/libsmb/credentials.c index 322b25ee43f..0d521bae8ac 100644 --- a/source/libsmb/credentials.c +++ b/source/libsmb/credentials.c @@ -208,36 +208,8 @@ BOOL deal_with_creds(uchar sess_key[8], DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data))); - /* Bug #2953 - don't store new seed in client credentials - here, because we need to make sure we're moving forward first - */ + /* store new seed in client credentials */ + SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); return True; } - -/* - stores new seed in client credentials - jmcd - Bug #2953 - moved this functionality out of deal_with_creds, because we're - not supposed to move to the next step in the chain if a nonexistent user tries to logon -*/ -void reseed_client_creds(DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_clnt_cred) -{ - UTIME new_clnt_time; - uint32 new_cred; - - /* increment client time by one second */ - new_clnt_time.time = rcv_clnt_cred->timestamp.time + 1; - - /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ - new_cred = IVAL(sto_clnt_cred->challenge.data, 0); - new_cred += new_clnt_time.time; - - DEBUG(5,("reseed_client_creds: new_cred[0]=%x\n", new_cred)); - DEBUG(5,("reseed_client_creds: new_clnt_time=%x\n", - new_clnt_time.time)); - DEBUG(5,("reseed_client_creds: clnt_cred=%s\n", - credstr(sto_clnt_cred->challenge.data))); - - /* store new seed in client credentials */ - SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); -} diff --git a/source/modules/vfs_default_quota.c b/source/modules/vfs_default_quota.c index f7c5dce4d67..9922a30315d 100644 --- a/source/modules/vfs_default_quota.c +++ b/source/modules/vfs_default_quota.c @@ -18,6 +18,56 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* + * This module allows the default quota values, + * in the windows explorer GUI, to be stored on a samba server. + * The problem is that linux filesystems only store quotas + * for users and groups, but no default quotas. + * + * Samba returns NO_LIMIT as the default quotas by default + * and refuses to update them. + * + * With this module you can store the default quotas that are reported to + * a windows client, in the quota record of a user. By default the root user + * is taken because quota limits for root are typically not enforced. + * + * This module takes 2 parametric parameters in smb.conf: + * (the default prefix for them is 'default_quota', + * it can be overwrittem when you load the module in + * the 'vfs objects' parameter like this: + * vfs objects = default_quota:myprefix) + * + * "<myprefix>:uid" parameter takes a integer argument, + * it specifies the uid of the quota record, that will be taken for + * storing the default USER-quotas. + * + * - default value: '0' (for root user) + * - e.g.: default_quota:uid = 65534 + * + * "<myprefix>:uid nolimit" parameter takes a boolean argument, + * it specifies if we should report the stored default quota values, + * also for the user record, or if you should just report NO_LIMIT + * to the windows client for the user specified by the "<prefix>:uid" parameter. + * + * - default value: yes (that means to report NO_LIMIT) + * - e.g.: default_quota:uid nolimit = no + * + * "<myprefix>:gid" parameter takes a integer argument, + * it's just like "<prefix>:uid" but for group quotas. + * (NOTE: group quotas are not supported from the windows explorer!) + * + * - default value: '0' (for root group) + * - e.g.: default_quota:gid = 65534 + * + * "<myprefix>:gid nolimit" parameter takes a boolean argument, + * it's just like "<prefix>:uid nolimit" but for group quotas. + * (NOTE: group quotas are not supported from the windows explorer!) + * + * - default value: yes (that means to report NO_LIMIT) + * - e.g.: default_quota:uid nolimit = no + * + */ + #include "includes.h" #undef DBGC_CLASS diff --git a/source/modules/vfs_full_audit.c b/source/modules/vfs_full_audit.c index d79e2e8f1cc..175dda7a69e 100644 --- a/source/modules/vfs_full_audit.c +++ b/source/modules/vfs_full_audit.c @@ -888,7 +888,7 @@ static long smb_full_audit_telldir(vfs_handle_struct *handle, connection_struct result = SMB_VFS_NEXT_TELLDIR(handle, conn, dirp); - do_log(SMB_VFS_OP_OPENDIR, True, handle, ""); + do_log(SMB_VFS_OP_TELLDIR, True, handle, ""); return result; } diff --git a/source/nsswitch/pam_winbind.c b/source/nsswitch/pam_winbind.c index 8d4f59101cb..a87ccb4972e 100644 --- a/source/nsswitch/pam_winbind.c +++ b/source/nsswitch/pam_winbind.c @@ -106,7 +106,7 @@ static int pam_winbind_request(enum winbindd_cmd req_type, /* Fill in request and send down pipe */ init_request(request, req_type); - if (write_sock(request, sizeof(*request)) == -1) { + if (write_sock(request, sizeof(*request), 0) == -1) { _pam_log(LOG_ERR, "write to socket failed!"); close_sock(); return PAM_SERVICE_ERR; diff --git a/source/nsswitch/wb_common.c b/source/nsswitch/wb_common.c index 5ed0b9161e7..6d09666525f 100644 --- a/source/nsswitch/wb_common.c +++ b/source/nsswitch/wb_common.c @@ -284,7 +284,7 @@ static int winbind_named_pipe_sock(const char *dir) /* Connect to winbindd socket */ -int winbind_open_pipe_sock(void) +static int winbind_open_pipe_sock(int recursing) { #ifdef HAVE_UNIXSOCKET static pid_t our_pid; @@ -302,12 +302,17 @@ int winbind_open_pipe_sock(void) return winbindd_fd; } + if (recursing) { + return -1; + } + if ((winbindd_fd = winbind_named_pipe_sock(WINBINDD_SOCKET_DIR)) == -1) { return -1; } /* version-check the socket */ + request.flags = WBFLAG_RECURSE; if ((winbindd_request_response(WINBINDD_INTERFACE_VERSION, &request, &response) != NSS_STATUS_SUCCESS) || (response.data.interface_version != WINBIND_INTERFACE_VERSION)) { close_sock(); return -1; @@ -315,6 +320,7 @@ int winbind_open_pipe_sock(void) /* try and get priv pipe */ + request.flags = WBFLAG_RECURSE; if (winbindd_request_response(WINBINDD_PRIV_PIPE_DIR, &request, &response) == NSS_STATUS_SUCCESS) { int fd; if ((fd = winbind_named_pipe_sock(response.extra_data)) != -1) { @@ -333,7 +339,7 @@ int winbind_open_pipe_sock(void) /* Write data to winbindd socket */ -int write_sock(void *buffer, int count) +int write_sock(void *buffer, int count, int recursing) { int result, nwritten; @@ -341,7 +347,7 @@ int write_sock(void *buffer, int count) restart: - if (winbind_open_pipe_sock() == -1) { + if (winbind_open_pipe_sock(recursing) == -1) { return -1; } @@ -534,7 +540,7 @@ NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request) init_request(request, req_type); - if (write_sock(request, sizeof(*request)) == -1) { + if (write_sock(request, sizeof(*request), request->flags & WBFLAG_RECURSE) == -1) { return NSS_STATUS_UNAVAIL; } diff --git a/source/nsswitch/winbind_client.h b/source/nsswitch/winbind_client.h index ec20cd78ef4..1d3d379af00 100644 --- a/source/nsswitch/winbind_client.h +++ b/source/nsswitch/winbind_client.h @@ -8,8 +8,7 @@ NSS_STATUS winbindd_get_response(struct winbindd_response *response); NSS_STATUS winbindd_request_response(int req_type, struct winbindd_request *request, struct winbindd_response *response); -int winbind_open_pipe_sock(void); -int write_sock(void *buffer, int count); +int write_sock(void *buffer, int count, int recursing); int read_reply(struct winbindd_response *response); void close_sock(void); void free_response(struct winbindd_response *response); diff --git a/source/nsswitch/winbindd_ads.c b/source/nsswitch/winbindd_ads.c index a7849e59b16..7851fdabc36 100644 --- a/source/nsswitch/winbindd_ads.c +++ b/source/nsswitch/winbindd_ads.c @@ -282,6 +282,9 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, continue; } + if (sid_check_is_in_builtin(&sid)) + continue; + if (!sid_peek_check_rid(&domain->sid, &sid, &rid)) { DEBUG(1,("No rid for %s !?\n", name)); continue; diff --git a/source/nsswitch/winbindd_dual.c b/source/nsswitch/winbindd_dual.c index e26cc4729ff..ec0b7a36e2f 100644 --- a/source/nsswitch/winbindd_dual.c +++ b/source/nsswitch/winbindd_dual.c @@ -160,6 +160,7 @@ static void async_reply_recv(void *private_data, BOOL success) SMB_ASSERT(cache_retrieve_response(child->pid, state->response)); + DLIST_REMOVE(child->requests, state); schedule_async_request(child); @@ -302,34 +303,27 @@ struct winbindd_child_dispatch_table { static struct winbindd_child_dispatch_table child_dispatch_table[] = { - { WINBINDD_LOOKUPSID, winbindd_dual_lookupsid, "LOOKUPSID" }, - { WINBINDD_LOOKUPNAME, winbindd_dual_lookupname, "LOOKUPNAME" }, - { WINBINDD_LIST_TRUSTDOM, winbindd_dual_list_trusted_domains, - "LIST_TRUSTDOM" }, - { WINBINDD_INIT_CONNECTION, winbindd_dual_init_connection, - "INIT_CONNECTION" }, - { WINBINDD_GETDCNAME, winbindd_dual_getdcname, "GETDCNAME" }, - { WINBINDD_SHOW_SEQUENCE, winbindd_dual_show_sequence, - "SHOW_SEQUENCE" }, - { WINBINDD_PAM_AUTH, winbindd_dual_pam_auth, "PAM_AUTH" }, - { WINBINDD_PAM_AUTH_CRAP, winbindd_dual_pam_auth_crap, "AUTH_CRAP" }, - { WINBINDD_CHECK_MACHACC, winbindd_dual_check_machine_acct, - "CHECK_MACHACC" }, - { WINBINDD_DUAL_SID2UID, winbindd_dual_sid2uid, "DUAL_SID2UID" }, - { WINBINDD_DUAL_SID2GID, winbindd_dual_sid2gid, "DUAL_SID2GID" }, - { WINBINDD_DUAL_UID2NAME, winbindd_dual_uid2name, "DUAL_UID2NAME" }, - { WINBINDD_DUAL_NAME2UID, winbindd_dual_name2uid, "DUAL_NAME2UID" }, - { WINBINDD_DUAL_GID2NAME, winbindd_dual_gid2name, "DUAL_GID2NAME" }, - { WINBINDD_DUAL_NAME2GID, winbindd_dual_name2gid, "DUAL_NAME2GID" }, - { WINBINDD_DUAL_IDMAPSET, winbindd_dual_idmapset, "DUAL_IDMAPSET" }, - { WINBINDD_DUAL_USERINFO, winbindd_dual_userinfo, "DUAL_USERINFO" }, - { WINBINDD_ALLOCATE_RID, winbindd_dual_allocate_rid, "ALLOCATE_RID" }, - { WINBINDD_ALLOCATE_RID_AND_GID, winbindd_dual_allocate_rid_and_gid, - "ALLOCATE_RID_AND_GID" }, - { WINBINDD_GETUSERDOMGROUPS, winbindd_dual_getuserdomgroups, - "GETUSERDOMGROUPS" }, - { WINBINDD_DUAL_GETSIDALIASES, winbindd_dual_getsidaliases, - "GETSIDALIASES" }, + { WINBINDD_LOOKUPSID, winbindd_dual_lookupsid, "LOOKUPSID" }, + { WINBINDD_LOOKUPNAME, winbindd_dual_lookupname, "LOOKUPNAME" }, + { WINBINDD_LIST_TRUSTDOM, winbindd_dual_list_trusted_domains, "LIST_TRUSTDOM" }, + { WINBINDD_INIT_CONNECTION, winbindd_dual_init_connection, "INIT_CONNECTION" }, + { WINBINDD_GETDCNAME, winbindd_dual_getdcname, "GETDCNAME" }, + { WINBINDD_SHOW_SEQUENCE, winbindd_dual_show_sequence, "SHOW_SEQUENCE" }, + { WINBINDD_PAM_AUTH, winbindd_dual_pam_auth, "PAM_AUTH" }, + { WINBINDD_PAM_AUTH_CRAP, winbindd_dual_pam_auth_crap, "AUTH_CRAP" }, + { WINBINDD_CHECK_MACHACC, winbindd_dual_check_machine_acct, "CHECK_MACHACC" }, + { WINBINDD_DUAL_SID2UID, winbindd_dual_sid2uid, "DUAL_SID2UID" }, + { WINBINDD_DUAL_SID2GID, winbindd_dual_sid2gid, "DUAL_SID2GID" }, + { WINBINDD_DUAL_UID2NAME, winbindd_dual_uid2name, "DUAL_UID2NAME" }, + { WINBINDD_DUAL_NAME2UID, winbindd_dual_name2uid, "DUAL_NAME2UID" }, + { WINBINDD_DUAL_GID2NAME, winbindd_dual_gid2name, "DUAL_GID2NAME" }, + { WINBINDD_DUAL_NAME2GID, winbindd_dual_name2gid, "DUAL_NAME2GID" }, + { WINBINDD_DUAL_IDMAPSET, winbindd_dual_idmapset, "DUAL_IDMAPSET" }, + { WINBINDD_DUAL_USERINFO, winbindd_dual_userinfo, "DUAL_USERINFO" }, + { WINBINDD_ALLOCATE_RID, winbindd_dual_allocate_rid, "ALLOCATE_RID" }, + { WINBINDD_ALLOCATE_RID_AND_GID, winbindd_dual_allocate_rid_and_gid, "ALLOCATE_RID_AND_GID" }, + { WINBINDD_GETUSERDOMGROUPS, winbindd_dual_getuserdomgroups, "GETUSERDOMGROUPS" }, + { WINBINDD_DUAL_GETSIDALIASES, winbindd_dual_getsidaliases, "GETSIDALIASES" }, /* End of list */ { WINBINDD_NUM_CMDS, NULL, "NONE" } diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c index cc8af6adcf6..6261dfb6165 100644 --- a/source/nsswitch/winbindd_group.c +++ b/source/nsswitch/winbindd_group.c @@ -259,9 +259,10 @@ void winbindd_getgrnam(struct winbindd_cli_state *state) if ( !((name_type==SID_NAME_DOM_GRP) || ((name_type==SID_NAME_ALIAS) && domain->primary) || - ((name_type==SID_NAME_ALIAS) && domain->internal)) ) + ((name_type==SID_NAME_ALIAS) && domain->internal) || + ((name_type==SID_NAME_WKN_GRP) && domain->internal)) ) { - DEBUG(1, ("name '%s' is not a local or domain group: %d\n", + DEBUG(1, ("name '%s' is not a local, domain or builtin group: %d\n", name_group, name_type)); request_error(state); return; @@ -518,7 +519,8 @@ static BOOL get_sam_group_entries(struct getent_state *ent) if ( ( lp_security() != SEC_ADS && domain->native_mode && domain->primary) || domain->internal ) { - DEBUG(4,("get_sam_group_entries: Native Mode 2k domain; enumerating local groups as well\n")); + DEBUG(4,("get_sam_group_entries: %s domain; enumerating local groups as well\n", + domain->native_mode ? "Native Mode 2k":"BUILTIN or local")); status = domain->methods->enum_local_groups(domain, mem_ctx, &num_entries, &sam_grp_entries); diff --git a/source/nsswitch/winbindd_nss.h b/source/nsswitch/winbindd_nss.h index cf0fae74a06..d012811d379 100644 --- a/source/nsswitch/winbindd_nss.h +++ b/source/nsswitch/winbindd_nss.h @@ -172,6 +172,8 @@ typedef struct winbindd_gr { /* This is a flag that can only be sent from parent to child */ #define WBFLAG_IS_PRIVILEGED 0x0400 +/* Flag to say this is a winbindd internal send - don't recurse. */ +#define WBFLAG_RECURSE 0x0800 /* Winbind request structure */ diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c index 4797ba79f4f..0b3c119afa0 100644 --- a/source/nsswitch/winbindd_pam.c +++ b/source/nsswitch/winbindd_pam.c @@ -404,12 +404,15 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, } while ( (attempts < 2) && retry ); - if (NT_STATUS_IS_OK(result) && - (!clnt_deal_with_creds(session_key, credentials, - &ret_creds))) { - DEBUG(3, ("DC %s sent wrong credentials\n", - pipe_cli->cli->srv_name_slash)); - result = NT_STATUS_ACCESS_DENIED; + /* Only check creds if we got a connection. */ + if (contact_domain->conn.cli && + !(NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || + NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) { + if (!clnt_deal_with_creds(session_key, credentials, &ret_creds)) { + DEBUG(3, ("DC %s sent wrong credentials\n", + pipe_cli->cli->srv_name_slash)); + result = NT_STATUS_ACCESS_DENIED; + } } if (NT_STATUS_IS_OK(result)) { @@ -712,12 +715,15 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, } while ( (attempts < 2) && retry ); - if (NT_STATUS_IS_OK(result) && - (!clnt_deal_with_creds(session_key, credentials, - &ret_creds))) { - DEBUG(3, ("DC %s sent wrong credentials\n", - pipe_cli->cli->srv_name_slash)); - result = NT_STATUS_ACCESS_DENIED; + /* Only check creds if we got a connection. */ + if (contact_domain->conn.cli && + !(NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || + (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) { + if (!clnt_deal_with_creds(session_key, credentials, &ret_creds)) { + DEBUG(3, ("DC %s sent wrong credentials\n", + pipe_cli->cli->srv_name_slash)); + result = NT_STATUS_ACCESS_DENIED; + } } if (NT_STATUS_IS_OK(result)) { diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c index 14b6f03fd41..d934bc2927f 100644 --- a/source/nsswitch/winbindd_util.c +++ b/source/nsswitch/winbindd_util.c @@ -506,7 +506,7 @@ void init_domain_list(void) DOM_SID our_sid; if (!secrets_fetch_domain_sid(lp_workgroup(), &our_sid)) { - DEBUG(0, ("Could not fetch our SID - did we join?\n")); + smb_panic("Could not fetch our SID - did we join?\n"); } domain = add_trusted_domain( lp_workgroup(), lp_realm(), @@ -805,7 +805,7 @@ static BOOL assume_domain(const char *domain) { return False; } -/* Parse a string of the form DOMAIN/user into a domain and a user */ +/* Parse a string of the form DOMAIN\user into a domain and a user */ BOOL parse_domain_user(const char *domuser, fstring domain, fstring user) { @@ -859,6 +859,7 @@ void fill_domain_username(fstring name, const char *domain, const char *user) fstring tmp_user; fstrcpy(tmp_user, user); + strlower_m(tmp_user); if (assume_domain(domain)) { strlcpy(name, user, sizeof(fstring)); diff --git a/source/passdb/pdb_nds.c b/source/passdb/pdb_nds.c index e2f3128fd5d..3e5f8d1b930 100644 --- a/source/passdb/pdb_nds.c +++ b/source/passdb/pdb_nds.c @@ -227,7 +227,7 @@ static int berDecodeLoginData( size_t *retDataLen, void *retData ) { - int rc=0, err = 0; + int err = 0; BerElement *replyBer = NULL; char *retOctStr = NULL; size_t retOctStrLen = 0; @@ -248,7 +248,7 @@ static int berDecodeLoginData( goto Cleanup; } - if( (rc = ber_scanf(replyBer, "{iis}", serverVersion, &err, retOctStr, &retOctStrLen)) != -1) + if(ber_scanf(replyBer, "{iis}", serverVersion, &err, retOctStr, &retOctStrLen) != -1) { if (*retDataLen >= retOctStrLen) { @@ -268,7 +268,7 @@ static int berDecodeLoginData( } else { - if( (rc = ber_scanf(replyBer, "{ii}", serverVersion, &err)) == -1) + if(ber_scanf(replyBer, "{ii}", serverVersion, &err) == -1) { if (!err) { @@ -663,7 +663,7 @@ Cleanup: int pdb_nds_get_password( struct smbldap_state *ldap_state, char *object_dn, - int *pwd_len, + size_t *pwd_len, char *pwd ) { LDAP *ld = ldap_state->ldap_struct; @@ -714,9 +714,13 @@ int pdb_nds_set_password( if (rc == LDAP_SUCCESS) { DEBUG(5,("NDS Universal Password changed for user %s\n", object_dn)); } else { + char *ld_error = NULL; + ldap_get_option(ld, LDAP_OPT_ERROR_STRING, &ld_error); + /* This will fail if Universal Password is not enabled for the user's context */ - DEBUG(3,("NDS Universal Password could not be changed for user %s: %d\n", - object_dn, rc)); + DEBUG(3,("NDS Universal Password could not be changed for user %s: %s (%s)\n", + object_dn, ldap_err2string(rc), ld_error?ld_error:"unknown")); + SAFE_FREE(ld_error); } /* Set eDirectory Password */ @@ -757,7 +761,7 @@ static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods, LDAPMessage *entry = NULL; const char **attr_list; size_t pwd_len; - uchar clear_text_pw[512]; + char clear_text_pw[512]; const char *p = NULL; LDAP *ld = NULL; int ldap_port = 0; @@ -800,7 +804,7 @@ static NTSTATUS pdb_nds_update_login_attempts(struct pdb_methods *methods, got_clear_text_pw = True; } } else { - generate_random_buffer(clear_text_pw, 24); + generate_random_buffer((unsigned char *)clear_text_pw, 24); clear_text_pw[24] = '\0'; DEBUG(5,("pdb_nds_update_login_attempts: using random password %s\n", clear_text_pw)); } diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c index 1474c94513f..fad60dbc20d 100644 --- a/source/rpc_client/cli_netlogon.c +++ b/source/rpc_client/cli_netlogon.c @@ -931,7 +931,6 @@ NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx, { /* report error code */ DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(nt_status))); - goto done; } /* Update the credentials. */ diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c index a92f16d6485..3a050148c9f 100644 --- a/source/rpc_parse/parse_net.c +++ b/source/rpc_parse/parse_net.c @@ -1626,7 +1626,7 @@ BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, if(!smb_io_unistr2("uni_logon_srv", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */ return False; - if(!smb_io_unistr2("uni_logon_dom", &usr->uni_logon_dom, usr->hdr_logon_srv.buffer, ps, depth)) /* logon domain unicode string */ + if(!smb_io_unistr2("uni_logon_dom", &usr->uni_logon_dom, usr->hdr_logon_dom.buffer, ps, depth)) /* logon domain unicode string */ return False; if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth)) /* domain SID */ diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c index 493536eb2a2..709a5d39af6 100644 --- a/source/rpc_parse/parse_prs.c +++ b/source/rpc_parse/parse_prs.c @@ -529,8 +529,10 @@ char *prs_mem_get(prs_struct *ps, uint32 extra_size) * If reading, ensure that we can read the requested size item. */ if (ps->data_offset + extra_size > ps->buffer_size) { - DEBUG(0,("prs_mem_get: reading data of size %u would overrun buffer.\n", - (unsigned int)extra_size )); + DEBUG(0,("prs_mem_get: reading data of size %u would overrun " + "buffer by %u bytes.\n", + (unsigned int)extra_size, + (unsigned int)(ps->data_offset + extra_size - ps->buffer_size) )); return NULL; } } else { diff --git a/source/rpc_server/srv_netlog_nt.c b/source/rpc_server/srv_netlog_nt.c index 78ff669d075..15827a8b55e 100644 --- a/source/rpc_server/srv_netlog_nt.c +++ b/source/rpc_server/srv_netlog_nt.c @@ -449,7 +449,6 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET * if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->clnt_id.cred, &srv_cred))) return NT_STATUS_INVALID_HANDLE; - reseed_client_creds(&p->dc.clnt_cred, &q_u->clnt_id.cred); memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred)); DEBUG(5,("_net_srv_pwset: %d\n", __LINE__)); @@ -547,7 +546,6 @@ NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOF return NT_STATUS_INVALID_HANDLE; /* what happens if we get a logoff for an unknown user? */ - reseed_client_creds(&p->dc.clnt_cred, &q_u->sam_id.client.cred); memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred)); /* XXXX maybe we want to say 'no', reject the client's credentials */ @@ -606,6 +604,8 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON * if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->sam_id.client.cred, &srv_cred))) return NT_STATUS_INVALID_HANDLE; + memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred)); + r_u->buffer_creds = 1; /* yes, we have valid server credentials */ memcpy(&r_u->srv_creds, &srv_cred, sizeof(r_u->srv_creds)); @@ -729,12 +729,6 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON * return status; } - /* moved from right after deal_with_creds above, since we weren't - supposed to update unless logon was successful */ - - reseed_client_creds(&p->dc.clnt_cred, &q_u->sam_id.client.cred); - memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred)); - if (server_info->guest) { /* We don't like guest domain logons... */ DEBUG(5,("_net_sam_logon: Attempted domain logon as GUEST denied.\n")); diff --git a/source/smbd/dir.c b/source/smbd/dir.c index 11b1df347b5..02e15d222a9 100644 --- a/source/smbd/dir.c +++ b/source/smbd/dir.c @@ -378,6 +378,7 @@ static void dptr_close_oldest(BOOL old) one byte long. If old_handle is false we allocate from the range 256 - MAX_DIRECTORY_HANDLES. We bias the number we return by 1 to ensure a directory handle is never zero. + wcard must not be zero. ****************************************************************************/ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid, @@ -389,6 +390,10 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp DEBUG(5,("dptr_create dir=%s\n", path)); + if (!wcard) { + return -1; + } + if (!check_name(path,conn)) return(-2); /* Code to say use a unix error return code. */ @@ -485,24 +490,21 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp dptr->dir_hnd = dir_hnd; dptr->spid = spid; dptr->expect_close = expect_close; - if (wcard) { - dptr->wcard = SMB_STRDUP(wcard); - if (!dptr->wcard) { - bitmap_clear(dptr_bmap, dptr->dnum - 1); - SAFE_FREE(dptr); - CloseDir(dir_hnd); - return -1; - } - } else { - dptr->wcard = NULL; + dptr->wcard = SMB_STRDUP(wcard); + if (!dptr->wcard) { + bitmap_clear(dptr_bmap, dptr->dnum - 1); + SAFE_FREE(dptr); + CloseDir(dir_hnd); + return -1; } - dptr->attr = attr; - if (lp_posix_pathnames() || (wcard && (wcard[0] == '.' && wcard[1] == 0))) { + if (lp_posix_pathnames() || (wcard[0] == '.' && wcard[1] == 0)) { dptr->has_wild = True; } else { dptr->has_wild = ms_has_wild(wcard); } + dptr->attr = attr; + DLIST_ADD(dirptrs, dptr); DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n", diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c index a2bc424b8e7..efbd5f04cb9 100644 --- a/source/smbd/dosmode.c +++ b/source/smbd/dosmode.c @@ -297,27 +297,28 @@ uint32 dos_mode(connection_struct *conn, const char *path,SMB_STRUCT_STAT *sbuf) return 0; } - /* Get the DOS attributes from an EA by preference. */ - if (get_ea_dos_attribute(conn, path, sbuf, &result)) { - result |= set_sparse_flag(sbuf); - return result; - } - - result = dos_mode_from_sbuf(conn, path, sbuf); - - /* Now do any modifications that depend on the path name. */ + /* First do any modifications that depend on the path name. */ /* hide files with a name starting with a . */ if (lp_hide_dot_files(SNUM(conn))) { const char *p = strrchr_m(path,'/'); - if (p) + if (p) { p++; - else + } else { p = path; + } - if (p[0] == '.' && p[1] != '.' && p[1] != 0) + if (p[0] == '.' && p[1] != '.' && p[1] != 0) { result |= aHIDDEN; + } } + /* Get the DOS attributes from an EA by preference. */ + if (get_ea_dos_attribute(conn, path, sbuf, &result)) { + result |= set_sparse_flag(sbuf); + } else { + result |= dos_mode_from_sbuf(conn, path, sbuf); + } + /* Optimization : Only call is_hidden_path if it's not already hidden. */ if (!(result & aHIDDEN) && IS_HIDDEN_PATH(conn,path)) { @@ -451,6 +452,17 @@ int file_utime(connection_struct *conn, const char *fname, struct utimbuf *times errno = 0; ZERO_STRUCT(sbuf); + /* Don't update the time on read-only shares */ + /* We need this as set_filetime (which can be called on + close and other paths) can end up calling this function + without the NEED_WRITE protection. Found by : + Leo Weppelman <leo@wau.mis.ah.nl> + */ + + if (!CAN_WRITE(conn)) { + return 0; + } + if(SMB_VFS_UTIME(conn,fname, times) == 0) return 0; diff --git a/source/smbd/open.c b/source/smbd/open.c index 99a284832f3..ed847826d52 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -1585,6 +1585,15 @@ files_struct *open_file_ntcreate(connection_struct *conn, fsp_open = open_file(fsp,conn,fname,psbuf,flags|flags2,unx_mode,access_mask); + if (!fsp_open && (flags2 & O_EXCL) && (errno == EEXIST)) { + /* + * Two smbd's tried to open exclusively, but only one of them + * succeeded. + */ + file_free(fsp); + return NULL; + } + if (!fsp_open && (flags == O_RDWR) && (errno != ENOENT)) { if((fsp_open = open_file(fsp,conn,fname,psbuf, O_RDONLY,unx_mode,access_mask)) == True) { diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c index a1855b0fa98..2f5bcb57faa 100644 --- a/source/smbd/posix_acls.c +++ b/source/smbd/posix_acls.c @@ -1548,8 +1548,12 @@ Deny entry after Allow entry. Failing to set on file %s.\n", fsp->fsp_name )); * entries can be converted to *_OBJ. Usually we will already have these * entries in the Default ACL, and the Access ACL will not have them. */ - check_owning_objs(file_ace, pfile_owner_sid, pfile_grp_sid); - check_owning_objs(dir_ace, pfile_owner_sid, pfile_grp_sid); + if (file_ace) { + check_owning_objs(file_ace, pfile_owner_sid, pfile_grp_sid); + } + if (dir_ace) { + check_owning_objs(dir_ace, pfile_owner_sid, pfile_grp_sid); + } } *ppfile_ace = file_ace; @@ -2801,7 +2805,7 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) if (count_canon_ace_list(file_ace) == 0) { DEBUG(0,("get_nt_acl : No ACLs on file (%s) !\n", fsp->fsp_name )); - return 0; + goto done; } if (fsp->is_directory && def_acl) { @@ -2950,33 +2954,37 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) if(!psd) { DEBUG(0,("get_nt_acl: Unable to malloc space for security descriptor.\n")); sd_size = 0; - } else { - /* - * Windows 2000: The DACL_PROTECTED flag in the security - * descriptor marks the ACL as non-inheriting, i.e., no - * ACEs from higher level directories propagate to this - * ACL. In the POSIX ACL model permissions are only - * inherited at file create time, so ACLs never contain - * any ACEs that are inherited dynamically. The DACL_PROTECTED - * flag doesn't seem to bother Windows NT. - * Always set this if map acl inherit is turned off. - */ - if (get_protected_flag(pal) || !lp_map_acl_inherit(SNUM(conn))) { - psd->type |= SE_DESC_DACL_PROTECTED; - } + goto done; } - if (psd->dacl) + /* + * Windows 2000: The DACL_PROTECTED flag in the security + * descriptor marks the ACL as non-inheriting, i.e., no + * ACEs from higher level directories propagate to this + * ACL. In the POSIX ACL model permissions are only + * inherited at file create time, so ACLs never contain + * any ACEs that are inherited dynamically. The DACL_PROTECTED + * flag doesn't seem to bother Windows NT. + * Always set this if map acl inherit is turned off. + */ + if (get_protected_flag(pal) || !lp_map_acl_inherit(SNUM(conn))) { + psd->type |= SE_DESC_DACL_PROTECTED; + } + + if (psd->dacl) { dacl_sort_into_canonical_order(psd->dacl->ace, (unsigned int)psd->dacl->num_aces); + } *ppdesc = psd; done: - if (posix_acl) + if (posix_acl) { SMB_VFS_SYS_ACL_FREE_ACL(conn, posix_acl); - if (def_acl) + } + if (def_acl) { SMB_VFS_SYS_ACL_FREE_ACL(conn, def_acl); + } free_canon_ace_list(file_ace); free_canon_ace_list(dir_ace); free_inherited_info(pal); diff --git a/source/smbd/process.c b/source/smbd/process.c index 1deb4da2696..8f9cc528821 100644 --- a/source/smbd/process.c +++ b/source/smbd/process.c @@ -897,7 +897,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid); connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); - DEBUG(3,("switch message %s (pid %d) conn 0x%x\n",smb_fn_name(type),(int)pid,(unsigned int)conn)); + DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n",smb_fn_name(type),(int)pid,(unsigned long)conn)); smb_dump(smb_fn_name(type), 1, inbuf, size); if(global_oplock_break) { diff --git a/source/smbd/server.c b/source/smbd/server.c index 4217d821f4c..a10968749d9 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -22,6 +22,10 @@ #include "includes.h" +#ifdef HAVE_SYS_PRCTL_H +#include <sys/prctl.h> +#endif + static int am_parent = 1; /* the last message the was processed */ @@ -915,6 +919,14 @@ void build_options(BOOL screen); * everything after this point is run after the fork() */ +#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) + /* On Linux we lose the ability to dump core when we change our user + * ID. We know how to dump core safely, so let's make sure we have our + * dumpable flag set. + */ + prctl(PR_SET_DUMPABLE, 1); +#endif + /* Initialise the password backed before the global_sam_sid to ensure that we fetch from ldap before we make a domain sid up */ diff --git a/source/smbd/statcache.c b/source/smbd/statcache.c index 97ecd4152c8..548d7c4a487 100644 --- a/source/smbd/statcache.c +++ b/source/smbd/statcache.c @@ -136,8 +136,8 @@ void stat_cache_add( const char *full_orig_name, const char *orig_translated_pat if (tdb_store_bystring(tdb_stat_cache, original_path, data_val, TDB_REPLACE) != 0) { DEBUG(0,("stat_cache_add: Error storing entry %s -> %s\n", original_path, translated_path)); } else { - DEBUG(5,("stat_cache_add: Added entry (%x:size%x) %s -> %s\n", - (unsigned int)data_val.dptr, data_val.dsize, original_path, translated_path)); + DEBUG(5,("stat_cache_add: Added entry (%lx:size%x) %s -> %s\n", + (unsigned long)data_val.dptr, (unsigned int)data_val.dsize, original_path, translated_path)); } SAFE_FREE(original_path); diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index 6cebff61ed4..38363bf66ae 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -135,7 +135,7 @@ static BOOL get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn, files_str return False; } - DEBUG(10,("get_ea_value: EA %s is of length %d: ", ea_name, sizeret)); + DEBUG(10,("get_ea_value: EA %s is of length %u: ", ea_name, (unsigned int)sizeret)); dump_data(10, val, sizeret); pea->flags = 0; @@ -188,7 +188,7 @@ static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_str if (sizeret == -1) return NULL; - DEBUG(10,("get_ea_list_from_file: ea_namelist size = %d\n", sizeret )); + DEBUG(10,("get_ea_list_from_file: ea_namelist size = %u\n", (unsigned int)sizeret )); if (sizeret) { for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p) + 1) { @@ -210,7 +210,7 @@ static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_str push_ascii_fstring(dos_ea_name, listp->ea.name); *pea_total_len += 4 + strlen(dos_ea_name) + 1 + listp->ea.value.length; DEBUG(10,("get_ea_list_from_file: total_len = %u, %s, val len = %u\n", - *pea_total_len, dos_ea_name, + (unsigned int)*pea_total_len, dos_ea_name, (unsigned int)listp->ea.value.length )); } DLIST_ADD_END(ea_list_head, listp, tmp); @@ -221,7 +221,7 @@ static struct ea_list *get_ea_list_from_file(TALLOC_CTX *mem_ctx, connection_str } } - DEBUG(10,("get_ea_list_from_file: total_len = %u\n", *pea_total_len)); + DEBUG(10,("get_ea_list_from_file: total_len = %u\n", (unsigned int)*pea_total_len)); return ea_list_head; } @@ -329,7 +329,7 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp, const char *fname, s canonicalize_ea_name(conn, fsp, fname, unix_ea_name); - DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, ea_list->ea.value.length)); + DEBUG(10,("set_ea: ea_name %s ealen = %u\n", unix_ea_name, (unsigned int)ea_list->ea.value.length)); if (samba_private_attr_name(unix_ea_name)) { DEBUG(10,("set_ea: ea name %s is a private Samba name.\n", unix_ea_name)); diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c index 2129cf85417..9ae1592a8e1 100644 --- a/source/smbd/vfs-wrap.c +++ b/source/smbd/vfs-wrap.c @@ -1063,7 +1063,7 @@ int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp return sys_aio_write(aiocb); } -int vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) +ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb) { return sys_aio_return(aiocb); } diff --git a/source/smbwrapper/smbw_dir.c b/source/smbwrapper/smbw_dir.c index 0a6deede41f..a89af54e1a3 100644 --- a/source/smbwrapper/smbw_dir.c +++ b/source/smbwrapper/smbw_dir.c @@ -188,7 +188,7 @@ int smbw_dir_open(const char *fname) goto failed; } - dir = (struct smbw_dir *)malloc(sizeof(*dir)); + dir = SMB_MALLOC_P(struct smbw_dir); if (!dir) { errno = ENOMEM; goto failed; @@ -265,7 +265,7 @@ int smbw_dir_open(const char *fname) dir->fd = fd; dir->srv = srv; - dir->path = strdup(s); + dir->path = SMB_STRDUP(s); DEBUG(4,(" -> %d\n", dir->count)); @@ -578,7 +578,7 @@ char *smbw_getcwd(char *buf, size_t size) if (!buf) { if (size <= 0) size = strlen(smbw_cwd)+1; - buf = (char *)malloc(size); + buf = SMB_MALLOC_ARRAY(char, size); if (!buf) { errno = ENOMEM; smbw_busy--; diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c index d68df037768..5d70c046d37 100644 --- a/source/tdb/tdb.c +++ b/source/tdb/tdb.c @@ -1248,6 +1248,54 @@ static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock, /* Lock each chain from the start one. */ for (; tlock->hash < tdb->header.hash_size; tlock->hash++) { + + /* this is an optimisation for the common case where + the hash chain is empty, which is particularly + common for the use of tdb with ldb, where large + hashes are used. In that case we spend most of our + time in tdb_brlock(), locking empty hash chains. + + To avoid this, we do an unlocked pre-check to see + if the hash chain is empty before starting to look + inside it. If it is empty then we can avoid that + hash chain. If it isn't empty then we can't believe + the value we get back, as we read it without a + lock, so instead we get the lock and re-fetch the + value below. + + Notice that not doing this optimisation on the + first hash chain is critical. We must guarantee + that we have done at least one fcntl lock at the + start of a search to guarantee that memory is + coherent on SMP systems. If records are added by + others during the search then thats OK, and we + could possibly miss those with this trick, but we + could miss them anyway without this trick, so the + semantics don't change. + + With a non-indexed ldb search this trick gains us a + factor of around 80 in speed on a linux 2.6.x + system (testing using ldbtest). + */ + if (!tlock->off && tlock->hash != 0) { + u32 off; + if (tdb->map_ptr) { + for (;tlock->hash < tdb->header.hash_size;tlock->hash++) { + if (0 != *(u32 *)(TDB_HASH_TOP(tlock->hash) + (unsigned char *)tdb->map_ptr)) { + break; + } + } + if (tlock->hash == tdb->header.hash_size) { + continue; + } + } else { + if (ofs_read(tdb, TDB_HASH_TOP(tlock->hash), &off) == 0 && + off == 0) { + continue; + } + } + } + if (tdb_lock(tdb, tlock->hash, F_WRLCK) == -1) return -1; @@ -2023,6 +2071,11 @@ int tdb_reopen(TDB_CONTEXT *tdb) TDB_LOG((tdb, 0, "tdb_reopen: open failed (%s)\n", strerror(errno))); goto fail; } + if ((tdb->flags & TDB_CLEAR_IF_FIRST) && + (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)) { + TDB_LOG((tdb, 0, "tdb_reopen: failed to obtain active lock\n")); + goto fail; + } if (fstat(tdb->fd, &st) != 0) { TDB_LOG((tdb, 0, "tdb_reopen: fstat failed (%s)\n", strerror(errno))); goto fail; @@ -2032,10 +2085,6 @@ int tdb_reopen(TDB_CONTEXT *tdb) goto fail; } tdb_mmap(tdb); - if ((tdb->flags & TDB_CLEAR_IF_FIRST) && (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1)) { - TDB_LOG((tdb, 0, "tdb_reopen: failed to obtain active lock\n")); - goto fail; - } return 0; @@ -2050,8 +2099,6 @@ int tdb_reopen_all(void) TDB_CONTEXT *tdb; for (tdb=tdbs; tdb; tdb = tdb->next) { - /* Ensure no clear-if-first. */ - tdb->flags &= ~TDB_CLEAR_IF_FIRST; if (tdb_reopen(tdb) != 0) return -1; } diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c index 50114d5fac6..ac7e5663441 100644 --- a/source/utils/net_rpc.c +++ b/source/utils/net_rpc.c @@ -4469,7 +4469,10 @@ static NTSTATUS rpc_init_shutdown_internals(const DOM_SID *domain_sid, if (opt_comment) { msg = opt_comment; + } else { + msg = ""; } + if (opt_timeout) { timeout = opt_timeout; } @@ -5965,7 +5968,7 @@ int net_rpc_usage(int argc, const char **argv) d_printf("\t-r or --reboot\trequest remote server reboot on shutdown\n"); d_printf("\t-f or --force\trequest the remote server force its shutdown\n"); d_printf("\t-t or --timeout=<timeout>\tnumber of seconds before shutdown\n"); - d_printf("\t-c or --comment=<message>\ttext message to display on impending shutdown\n"); + d_printf("\t-C or --comment=<message>\ttext message to display on impending shutdown\n"); return -1; } diff --git a/source/utils/status.c b/source/utils/status.c index bed9828c228..96e4bd266b9 100644 --- a/source/utils/status.c +++ b/source/utils/status.c @@ -128,7 +128,8 @@ static void print_share_mode(share_mode_entry *e, char *fname) } } d_printf("0x%-8x ",(unsigned int)e->access_mask); - if (e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA)) { + if ((e->access_mask & (FILE_READ_DATA|FILE_WRITE_DATA))== + (FILE_READ_DATA|FILE_WRITE_DATA)) { d_printf("RDWR "); } else if (e->access_mask & FILE_WRITE_DATA) { d_printf("WRONLY "); |