summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.Coding215
-rw-r--r--source/aclocal.m417
-rw-r--r--source/auth/auth_server.c7
-rw-r--r--source/client/client.c29
-rw-r--r--source/client/smbmount.c2
-rw-r--r--source/configure.in8
-rw-r--r--source/include/includes.h6
-rw-r--r--source/include/rpc_samr.h16
-rw-r--r--source/include/smb_macros.h1
-rw-r--r--source/lib/iconv.c37
-rw-r--r--source/lib/messages.c4
-rw-r--r--source/lib/pidfile.c3
-rw-r--r--source/lib/system.c241
-rw-r--r--source/lib/util.c16
-rw-r--r--source/libads/dns.c6
-rw-r--r--source/libads/ldap.c2
-rw-r--r--source/libsmb/cliconnect.c29
-rw-r--r--source/libsmb/clidfs.c9
-rw-r--r--source/libsmb/errormap.c31
-rw-r--r--source/libsmb/libsmbclient.c55
-rw-r--r--source/libsmb/passchange.c10
-rw-r--r--source/locking/locking.c40
-rw-r--r--source/modules/nfs4_acls.h2
-rw-r--r--source/modules/vfs_readahead.c2
-rw-r--r--source/nmbd/nmbd_synclists.c8
-rw-r--r--source/nsswitch/nss_info.c2
-rw-r--r--source/nsswitch/nss_info_template.c2
-rw-r--r--source/nsswitch/wbinfo.c29
-rw-r--r--source/nsswitch/winbindd_util.c8
-rw-r--r--source/passdb/pdb_ldap.c2
-rw-r--r--source/rpc_parse/parse_samr.c21
-rw-r--r--source/rpc_server/srv_samr_nt.c9
-rw-r--r--source/rpc_server/srv_samr_util.c43
-rw-r--r--source/rpc_server/srv_spoolss_nt.c1
-rwxr-xr-xsource/script/mkversion.sh2
-rw-r--r--source/services/services_db.c4
-rw-r--r--source/smbd/close.c11
-rw-r--r--source/smbd/error.c19
-rw-r--r--source/smbd/fileio.c30
-rw-r--r--source/smbd/filename.c19
-rw-r--r--source/smbd/msdfs.c11
-rw-r--r--source/smbd/notify.c55
-rw-r--r--source/smbd/nttrans.c88
-rw-r--r--source/smbd/posix_acls.c283
-rw-r--r--source/smbd/reply.c9
-rw-r--r--source/smbd/trans2.c125
-rw-r--r--source/tdb/common/io.c38
-rw-r--r--source/tdb/common/open.c27
-rw-r--r--source/tdb/common/tdb.c6
-rw-r--r--source/tdb/common/tdbback.c2
-rw-r--r--source/torture/locktest.c9
-rw-r--r--source/torture/masktest.c9
-rw-r--r--source/torture/torture.c11
-rw-r--r--source/utils/net.c4
-rw-r--r--source/utils/net_ads.c2
-rw-r--r--source/utils/net_rpc.c4
-rw-r--r--source/utils/net_time.c6
-rw-r--r--source/web/diagnose.c4
58 files changed, 1365 insertions, 326 deletions
diff --git a/README.Coding b/README.Coding
new file mode 100644
index 00000000000..ba9e8be08c5
--- /dev/null
+++ b/README.Coding
@@ -0,0 +1,215 @@
+##
+## Coding conventions in the Samba 3.0 tree
+##
+
+===========
+Quick Start
+===========
+
+Coding style guidelines are about reducing the number of unnecessary
+reformatting patches and making things easier developers to work together.
+You don't have to like them or even agree with them, but once put in place
+we all have to abide by them (or vote to change them). However, coding
+style should never outweigh coding itself and so the the guidelines
+described here are hopefully easier enough to follow as they are very
+common and supported by tools and editors.
+
+The basic style, also mentioned in the SAMBA_4_0/prog_guide.txt is the
+Linux kernel coding style (See Documentation/CodingStyle in the kernel
+source tree). The closely matches what most Samba developers use already
+anyways.
+
+But to save you the trouble of reading the Linux kernel style guide, here
+are the highlights.
+
+
+* Maximum Line Width is 80 Characters
+ The reason is not for people with low-res screens but rather sticking
+ to 80 columns prevents you from easily nesting more than one level of
+ if statements or other code blocks. Use source/script/count_80_col.pl
+ to check your changes.
+
+* Use 8 Space Tabs to Indent
+ No whitespace filler.
+
+* No Trailing Whitespace
+ Use source/script/strip_trail_ws.pl to clean you files before committing.
+
+* Follow the K&R guidelines. We won't go throw them all here. You have
+ a copy of "The C Programming Language" anyways right? You can also use
+ the format_indent.sh script found in source/script/ if all else fails.
+
+
+
+============
+Editor Hints
+============
+
+Emacs
+-----
+Add the follow to your $HOME/.emacs file:
+
+ (add-hook 'c-mode-hook
+ (lambda ()
+ (c-set-style "linux")
+ (c-toggle-auto-state)))
+
+
+Vi
+--
+(Thanks to SATOH Fumiyasu <fumiyas@osstech.jp> for these hints):
+
+For the basic vi editor including with all variants of *nix, add the
+following to $HOME/.exrc:
+
+ set tabstop=8
+ set shiftwidth=8
+
+For Vim, the following settings in $HOME/.vimrc will also deal with
+displaying trailing whitespace:
+
+ if has("syntax") && (&t_Co > 2 || has("gui_running"))
+ syntax on
+ function! ActivateInvisibleCharIndicator()
+ syntax match TrailingSpace "[ \t]\+$" display containedin=ALL
+ highlight TrailingSpace ctermbg=Red
+ endf
+ autocmd BufNewFile,BufRead * call ActivateInvisibleCharIndicator()
+ endif
+
+
+=========================
+FAQ & Statement Reference
+=========================
+
+Comments
+--------
+
+Comments should always use the standard C syntax. I.e. /* ... */. C++
+style comments are not currently allowed.
+
+
+Indention & Whitespace & 80 columns
+-----------------------------------
+
+To avoid confusion, indentations are to be 8 character with tab (not
+8 ' ' characters. When wrapping parameters for function calls,
+alignment parameter list with the first parameter on the previous line.
+Use tabs to get as close as possible and then fill in the final 7
+characters or less with whitespace. For example,
+
+ var1 = foo(arg1, arg2,
+ arg3);
+
+The previous example is intended to illustrate alignment of function
+parameters across lines and not as encourage for gratuitous line
+splitting. Never split a line before columns 70 - 79 unless you
+have a really good reason. Be smart about formatting.
+
+
+If, switch, & Code blocks
+-------------------------
+
+Always follow an 'if' keyword with a space but don't include additional
+spaces following or preceding the parentheses in the conditional.
+This is good:
+
+ if (x == 1)
+
+This is bad:
+
+ if ( x == 1 )
+
+Yes we have a lot of code that uses the second form and we are trying
+to clean it up without being overly intrusive.
+
+Note that this is a rule about parentheses following keywords and not
+functions. Don't insert a space between the name and left parentheses when
+invoking functions.
+
+Braces for code blocks used by for, if, switch, while, do..while, etc...
+should begin on the same line as the statement keyword and end on a line
+of their own. NOTE: Functions are different and the beginning left brace
+should begin on a line of its own.
+
+If the beginning statement has to be broken across lines due to length,
+the beginning brace should be on a line of its own.
+
+The exception to the ending rule is when the closing brace is followed by
+another language keyword such as else or the closing while in a do..while
+loop.
+
+Good examples:
+
+ if (x == 1) {
+ printf("good\n");
+ }
+
+ for (x=1;
+ x<10;
+ x++)
+ {
+ print("%d\n", x);
+ }
+
+ do {
+ printf("also good\n");
+ } while (1);
+
+Bad examples:
+
+ while (1)
+ {
+ print("I'm in a loop!\n"); }
+
+
+Goto
+----
+
+While many people have been academically taught that goto's are fundamentally
+evil, then can greatly enhance readability and reduce memory leaks when used
+as the single exit point from a function. But in no Samba world what so ever
+is a goto outside of a function or block of code a good idea.
+
+Good Examples:
+
+int function foo(int y)
+{
+ int *z = NULL;
+ int ret = 0;
+
+ if ( y < 10 ) {
+ z = malloc(sizeof(int)*y);
+ if (!z) {
+ ret = 1;
+ goto done;
+ }
+ }
+
+ print("Allocated %d elements.\n", y);
+
+ done:
+ if (z)
+ free(z);
+
+ return ret;
+}
+
+
+Checking Pointer Values
+-----------------------
+
+When invoking functions that return pointer values, either of the following
+are acceptable. Use you best judgement and choose the more readable option.
+Remember that many other people will review it.
+
+ if ((x = malloc(sizeof(short)*10)) == NULL ) {
+ fprintf(stderr, "Unable to alloc memory!\n");
+ }
+
+or
+
+ x = malloc(sizeof(short)*10);
+ if (!x) {
+ fprintf(stderr, "Unable to alloc memory!\n");
+ }
diff --git a/source/aclocal.m4 b/source/aclocal.m4
index d36749a5f50..0b9bc0b689c 100644
--- a/source/aclocal.m4
+++ b/source/aclocal.m4
@@ -362,23 +362,6 @@ AC_DEFUN(jm_ICONV,
jm_cv_func_iconv=yes
jm_cv_lib_iconv="iconv")
LIBS="$jm_save_LIBS"
-
- if test "$jm_cv_lib_iconv" != yes; then
- jm_save_LIBS="$LIBS"
- LIBS="$LIBS -lbiconv"
- AC_TRY_LINK([#include <stdlib.h>
-#include <biconv.h>],
- [iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);],
- jm_cv_lib_iconv=yes
- jm_cv_func_iconv=yes
- jm_cv_include="biconv.h"
- jm_cv_biconv=yes
- jm_cv_lib_iconv="biconv")
-
- LIBS="$jm_save_LIBS"
- fi
fi
fi
fi
diff --git a/source/auth/auth_server.c b/source/auth/auth_server.c
index 3e29c246491..d490b1a467b 100644
--- a/source/auth/auth_server.c
+++ b/source/auth/auth_server.c
@@ -49,6 +49,8 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
p = pserver;
while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) {
+ NTSTATUS status;
+
standard_sub_basic(current_user_info.smb_name, current_user_info.domain,
desthost, sizeof(desthost));
strupper_m(desthost);
@@ -72,11 +74,14 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
return NULL;
}
- if (cli_connect(cli, desthost, &dest_ip)) {
+ status = cli_connect(cli, desthost, &dest_ip);
+ if (NT_STATUS_IS_OK(status)) {
DEBUG(3,("connected to password server %s\n",desthost));
connected_ok = True;
break;
}
+ DEBUG(10,("server_cryptkey: failed to connect to server %s. Error %s\n",
+ desthost, nt_errstr(status) ));
}
if (!connected_ok) {
diff --git a/source/client/client.c b/source/client/client.c
index 727e8db1f11..d05a2b8975a 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -2649,7 +2649,8 @@ static int cmd_rename(void)
pstring src,dest;
pstring buf,buf2;
struct cli_state *targetcli;
- pstring targetname;
+ pstring targetsrc;
+ pstring targetdest;
pstrcpy(src,cur_dir);
pstrcpy(dest,cur_dir);
@@ -2663,13 +2664,21 @@ static int cmd_rename(void)
pstrcat(src,buf);
pstrcat(dest,buf2);
- if ( !cli_resolve_path( "", cli, src, &targetcli, targetname ) ) {
- d_printf("chown %s: %s\n", src, cli_errstr(cli));
+ if ( !cli_resolve_path( "", cli, src, &targetcli, targetsrc ) ) {
+ d_printf("rename %s: %s\n", src, cli_errstr(cli));
+ return 1;
+ }
+
+ if ( !cli_resolve_path( "", cli, dest, &targetcli, targetdest ) ) {
+ d_printf("rename %s: %s\n", dest, cli_errstr(cli));
return 1;
}
- if (!cli_rename(targetcli, targetname, dest)) {
- d_printf("%s renaming files\n",cli_errstr(targetcli));
+ if (!cli_rename(targetcli, targetsrc, targetdest)) {
+ d_printf("%s renaming files %s -> %s \n",
+ cli_errstr(targetcli),
+ targetsrc,
+ targetdest);
return 1;
}
@@ -3796,6 +3805,7 @@ static int do_message_op(void)
fstring server_name;
char name_type_hex[10];
int msg_port;
+ NTSTATUS status;
make_nmb_name(&calling, calling_name, 0x0);
make_nmb_name(&called , desthost, name_type);
@@ -3812,12 +3822,17 @@ static int do_message_op(void)
msg_port = port ? port : 139;
- if (!(cli=cli_initialise()) || (cli_set_port(cli, msg_port) != msg_port) ||
- !cli_connect(cli, server_name, &ip)) {
+ if (!(cli=cli_initialise()) || (cli_set_port(cli, msg_port) != msg_port)) {
d_printf("Connection to %s failed\n", desthost);
return 1;
}
+ status = cli_connect(cli, server_name, &ip);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("Connection to %s failed. Error %s\n", desthost, nt_errstr(status));
+ return 1;
+ }
+
if (!cli_session_request(cli, &calling, &called)) {
d_printf("session request failed\n");
cli_cm_shutdown();
diff --git a/source/client/smbmount.c b/source/client/smbmount.c
index cce03e59a94..b1462dbddf1 100644
--- a/source/client/smbmount.c
+++ b/source/client/smbmount.c
@@ -152,7 +152,7 @@ static struct cli_state *do_connection(char *the_service)
/* have to open a new connection */
if (!(c=cli_initialise()) || (cli_set_port(c, smb_port) != smb_port) ||
- !cli_connect(c, server_n, &ip)) {
+ !NT_STATUS_IS_OK(cli_connect(c, server_n, &ip))) {
DEBUG(0,("%d: Connection to %s failed\n", sys_getpid(), server_n));
if (c) {
cli_shutdown(c);
diff --git a/source/configure.in b/source/configure.in
index f16766e0510..74fc8732f09 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -1591,6 +1591,14 @@ case "$host_os" in
esac
########################################################
+# Check if attropen() is present if this is Solaris
+case "$host_os" in
+ *solaris*)
+ AC_CHECK_FUNCS(attropen)
+ ;;
+esac
+
+########################################################
# Do xattr functions take additional options like on Darwin?
if test x"$ac_cv_func_getxattr" = x"yes" ; then
AC_CACHE_CHECK([whether xattr interface takes additional options], smb_attr_cv_xattr_add_opt, [
diff --git a/source/include/includes.h b/source/include/includes.h
index f8c2b50fd3d..3ddfc7d96d6 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -225,6 +225,10 @@ typedef int ber_int_t;
#include <sys/attributes.h>
#endif
+#ifndef ENOATTR
+#define ENOATTR ENODATA
+#endif
+
/* mutually exclusive (SuSE 8.2) */
#if HAVE_ATTR_XATTR_H
#include <attr/xattr.h>
@@ -757,8 +761,6 @@ struct functable2 {
struct printjob;
-struct smb_ldap_privates;
-
/* forward declarations from smbldap.c */
#include "smbldap.h"
diff --git a/source/include/rpc_samr.h b/source/include/rpc_samr.h
index 9a5484598a4..575cd78ef2f 100644
--- a/source/include/rpc_samr.h
+++ b/source/include/rpc_samr.h
@@ -262,7 +262,19 @@ typedef struct sam_user_info_25
uint32 acb_info; /* account info (ACB_xxxx bit-mask) */
uint32 fields_present;
- uint32 unknown_5[5];
+ uint16 logon_divs; /* 0x0000 00a8 which is 168 which is num hrs in a week */
+ /* uint8 pad[2] */
+ uint32 ptr_logon_hrs; /* pointer to logon hours */
+
+ /* Was unknown_5. */
+ uint16 bad_password_count;
+ uint16 logon_count;
+
+ uint8 padding1[6];
+
+ uint8 passmustchange; /* 0x00 must change = 0x01 */
+
+ uint8 padding2;
uint8 pass[532];
@@ -276,6 +288,8 @@ typedef struct sam_user_info_25
UNISTR2 uni_workstations; /* login from workstations unicode string */
UNISTR2 uni_comment;
UNISTR2 uni_munged_dial ; /* munged path name and dial-back tel no */
+ LOGON_HRS logon_hrs;
+
} SAM_USER_INFO_25;
/* SAM_USER_INFO_26 */
diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h
index d26433359be..a16ea7500f2 100644
--- a/source/include/smb_macros.h
+++ b/source/include/smb_macros.h
@@ -166,6 +166,7 @@
#define ERROR_DOS(class,code) error_packet(outbuf,class,code,NT_STATUS_OK,__LINE__,__FILE__)
#define ERROR_NT(status) error_packet(outbuf,0,0,status,__LINE__,__FILE__)
+#define ERROR_OPEN(status) error_open(outbuf,status,__LINE__,__FILE__)
#define ERROR_FORCE_NT(status) error_packet(outbuf,-1,-1,status,__LINE__,__FILE__)
#define ERROR_BOTH(status,class,code) error_packet(outbuf,class,code,status,__LINE__,__FILE__)
diff --git a/source/lib/iconv.c b/source/lib/iconv.c
index 6e040b77f17..90e2faab6fb 100644
--- a/source/lib/iconv.c
+++ b/source/lib/iconv.c
@@ -544,6 +544,8 @@ static size_t utf8_pull(void *cd, const char **inbuf, size_t *inbytesleft,
uint8 *uc = (uint8 *)*outbuf;
while (in_left >= 1 && out_left >= 2) {
+ unsigned int codepoint;
+
if ((c[0] & 0x80) == 0) {
uc[0] = c[0];
uc[1] = 0;
@@ -560,8 +562,14 @@ static size_t utf8_pull(void *cd, const char **inbuf, size_t *inbytesleft,
errno = EILSEQ;
goto error;
}
- uc[1] = (c[0]>>2) & 0x7;
- uc[0] = (c[0]<<6) | (c[1]&0x3f);
+ codepoint = (c[1]&0x3f) | ((c[0]&0x1f)<<6);
+ if (codepoint < 0x80) {
+ /* don't accept UTF-8 characters that are not minimally packed */
+ errno = EILSEQ;
+ goto error;
+ }
+ uc[1] = codepoint >> 8;
+ uc[0] = codepoint & 0xff;
c += 2;
in_left -= 2;
out_left -= 2;
@@ -576,8 +584,14 @@ static size_t utf8_pull(void *cd, const char **inbuf, size_t *inbytesleft,
errno = EILSEQ;
goto error;
}
- uc[1] = ((c[0]&0xF)<<4) | ((c[1]>>2)&0xF);
- uc[0] = (c[1]<<6) | (c[2]&0x3f);
+ codepoint = (c[2]&0x3f) | ((c[1]&0x3f)<<6) | ((c[0]&0xf)<<12);
+ if (codepoint < 0x800) {
+ /* don't accept UTF-8 characters that are not minimally packed */
+ errno = EILSEQ;
+ goto error;
+ }
+ uc[1] = codepoint >> 8;
+ uc[0] = codepoint & 0xff;
c += 3;
in_left -= 3;
out_left -= 2;
@@ -586,7 +600,6 @@ static size_t utf8_pull(void *cd, const char **inbuf, size_t *inbytesleft,
}
if ((c[0] & 0xf8) == 0xf0) {
- unsigned int codepoint;
if (in_left < 4 ||
(c[1] & 0xc0) != 0x80 ||
(c[2] & 0xc0) != 0x80 ||
@@ -599,16 +612,10 @@ static size_t utf8_pull(void *cd, const char **inbuf, size_t *inbytesleft,
((c[2]&0x3f)<<6) |
((c[1]&0x3f)<<12) |
((c[0]&0x7)<<18);
- if (codepoint < 0x10000) {
- /* accept UTF-8 characters that are not
- minimally packed, but pack the result */
- uc[0] = (codepoint & 0xFF);
- uc[1] = (codepoint >> 8);
- c += 4;
- in_left -= 4;
- out_left -= 2;
- uc += 2;
- continue;
+ if (codepoint < 0x10000 || codepoint > 0x10ffff) {
+ /* don't accept UTF-8 characters that are not minimally packed */
+ errno = EILSEQ;
+ goto error;
}
codepoint -= 0x10000;
diff --git a/source/lib/messages.c b/source/lib/messages.c
index 8e2456d5a5a..88b5f3ab936 100644
--- a/source/lib/messages.c
+++ b/source/lib/messages.c
@@ -281,12 +281,14 @@ static NTSTATUS message_send_pid_internal(struct process_id pid, int msg_type,
if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) {
DEBUG(0,("message_send_pid_internal: failed to get "
"chainlock with timeout %ul.\n", timeout));
+ SAFE_FREE(dbuf.dptr);
return NT_STATUS_IO_TIMEOUT;
}
} else {
if (tdb_chainlock(tdb, kbuf) == -1) {
DEBUG(0,("message_send_pid_internal: failed to get "
"chainlock.\n"));
+ SAFE_FREE(dbuf.dptr);
return NT_STATUS_LOCK_NOT_GRANTED;
}
}
@@ -303,12 +305,14 @@ static NTSTATUS message_send_pid_internal(struct process_id pid, int msg_type,
if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) {
DEBUG(0,("message_send_pid_internal: failed to get chainlock "
"with timeout %ul.\n", timeout));
+ SAFE_FREE(dbuf.dptr);
return NT_STATUS_IO_TIMEOUT;
}
} else {
if (tdb_chainlock(tdb, kbuf) == -1) {
DEBUG(0,("message_send_pid_internal: failed to get "
"chainlock.\n"));
+ SAFE_FREE(dbuf.dptr);
return NT_STATUS_LOCK_NOT_GRANTED;
}
}
diff --git a/source/lib/pidfile.c b/source/lib/pidfile.c
index 89ab6d799b7..42ecede1175 100644
--- a/source/lib/pidfile.c
+++ b/source/lib/pidfile.c
@@ -100,7 +100,8 @@ void pidfile_create(const char *program_name)
/* full/relative path provided */
short_configfile++;
}
- slprintf( name, sizeof( name)-1, "%s-%s", program_name, short_configfile+1);
+ slprintf( name, sizeof( name)-1, "%s-%s", program_name,
+ short_configfile );
}
slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_piddir(), name);
diff --git a/source/lib/system.c b/source/lib/system.c
index eaebc7190f0..1094cd20d61 100644
--- a/source/lib/system.c
+++ b/source/lib/system.c
@@ -4,6 +4,7 @@
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 1998-2005
Copyright (C) Timur Bakeyev 2005
+ Copyright (C) Bjoern Jacke 2006-2007
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1561,6 +1562,17 @@ int sys_dup2(int oldfd, int newfd)
SAFE_FREE(msgbuf);
}
+/******** Solaris EA helper function prototypes ********/
+#ifdef HAVE_ATTROPEN
+#define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
+int solaris_write_xattr(int attrfd, const char *value, size_t size);
+ssize_t solaris_read_xattr(int attrfd, void *value, size_t size);
+ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size);
+int solaris_unlinkat(int attrdirfd, const char *name);
+int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode);
+int solaris_openat(int fildes, const char *path, int oflag, mode_t mode);
+#endif
+
/**************************************************************************
Wrappers for extented attribute calls. Based on the Linux package with
support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
@@ -1609,6 +1621,14 @@ ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t si
retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
return retval ? retval : valuelength;
+#elif defined(HAVE_ATTROPEN)
+ ssize_t ret = -1;
+ int attrfd = solaris_attropen(path, name, O_RDONLY, 0);
+ if (attrfd >= 0) {
+ ret = solaris_read_xattr(attrfd, value, size);
+ close(attrfd);
+ }
+ return ret;
#else
errno = ENOSYS;
return -1;
@@ -1652,6 +1672,14 @@ ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t s
retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
return retval ? retval : valuelength;
+#elif defined(HAVE_ATTROPEN)
+ ssize_t ret = -1;
+ int attrfd = solaris_attropen(path, name, O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
+ if (attrfd >= 0) {
+ ret = solaris_read_xattr(attrfd, value, size);
+ close(attrfd);
+ }
+ return ret;
#else
errno = ENOSYS;
return -1;
@@ -1697,6 +1725,14 @@ ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
return retval ? retval : valuelength;
+#elif defined(HAVE_ATTROPEN)
+ ssize_t ret = -1;
+ int attrfd = solaris_openat(filedes, name, O_RDONLY|O_XATTR, 0);
+ if (attrfd >= 0) {
+ ret = solaris_read_xattr(attrfd, value, size);
+ close(attrfd);
+ }
+ return ret;
#else
errno = ENOSYS;
return -1;
@@ -1881,6 +1917,14 @@ ssize_t sys_listxattr (const char *path, char *list, size_t size)
return bsd_attr_list(0, arg, list, size);
#elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
return irix_attr_list(path, 0, list, size, 0);
+#elif defined(HAVE_ATTROPEN)
+ ssize_t ret = -1;
+ int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0);
+ if (attrdirfd >= 0) {
+ ret = solaris_list_xattr(attrdirfd, list, size);
+ close(attrdirfd);
+ }
+ return ret;
#else
errno = ENOSYS;
return -1;
@@ -1902,6 +1946,14 @@ ssize_t sys_llistxattr (const char *path, char *list, size_t size)
return bsd_attr_list(1, arg, list, size);
#elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
+#elif defined(HAVE_ATTROPEN)
+ ssize_t ret = -1;
+ int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
+ if (attrdirfd >= 0) {
+ ret = solaris_list_xattr(attrdirfd, list, size);
+ close(attrdirfd);
+ }
+ return ret;
#else
errno = ENOSYS;
return -1;
@@ -1925,6 +1977,14 @@ ssize_t sys_flistxattr (int filedes, char *list, size_t size)
return bsd_attr_list(2, arg, list, size);
#elif defined(HAVE_ATTR_LISTF)
return irix_attr_list(NULL, filedes, list, size, 0);
+#elif defined(HAVE_ATTROPEN)
+ ssize_t ret = -1;
+ int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0);
+ if (attrdirfd >= 0) {
+ ret = solaris_list_xattr(attrdirfd, list, size);
+ close(attrdirfd);
+ }
+ return ret;
#else
errno = ENOSYS;
return -1;
@@ -1956,6 +2016,14 @@ int sys_removexattr (const char *path, const char *name)
if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
return attr_remove(path, attrname, flags);
+#elif defined(HAVE_ATTROPEN)
+ int ret = -1;
+ int attrdirfd = solaris_attropen(path, ".", O_RDONLY, 0);
+ if (attrdirfd >= 0) {
+ ret = solaris_unlinkat(attrdirfd, name);
+ close(attrdirfd);
+ }
+ return ret;
#else
errno = ENOSYS;
return -1;
@@ -1985,6 +2053,14 @@ int sys_lremovexattr (const char *path, const char *name)
if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
return attr_remove(path, attrname, flags);
+#elif defined(HAVE_ATTROPEN)
+ int ret = -1;
+ int attrdirfd = solaris_attropen(path, ".", O_RDONLY|AT_SYMLINK_NOFOLLOW, 0);
+ if (attrdirfd >= 0) {
+ ret = solaris_unlinkat(attrdirfd, name);
+ close(attrdirfd);
+ }
+ return ret;
#else
errno = ENOSYS;
return -1;
@@ -2016,6 +2092,14 @@ int sys_fremovexattr (int filedes, const char *name)
if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
return attr_removef(filedes, attrname, flags);
+#elif defined(HAVE_ATTROPEN)
+ int ret = -1;
+ int attrdirfd = solaris_openat(filedes, ".", O_RDONLY|O_XATTR, 0);
+ if (attrdirfd >= 0) {
+ ret = solaris_unlinkat(attrdirfd, name);
+ close(attrdirfd);
+ }
+ return ret;
#else
errno = ENOSYS;
return -1;
@@ -2074,6 +2158,17 @@ int sys_setxattr (const char *path, const char *name, const void *value, size_t
if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
return attr_set(path, attrname, (const char *)value, size, myflags);
+#elif defined(HAVE_ATTROPEN)
+ int ret = -1;
+ int myflags = O_RDWR;
+ if (flags & XATTR_CREATE) myflags |= O_EXCL;
+ if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
+ int attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
+ if (attrfd >= 0) {
+ ret = solaris_write_xattr(attrfd, value, size);
+ close(attrfd);
+ }
+ return ret;
#else
errno = ENOSYS;
return -1;
@@ -2126,6 +2221,17 @@ int sys_lsetxattr (const char *path, const char *name, const void *value, size_t
if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
return attr_set(path, attrname, (const char *)value, size, myflags);
+#elif defined(HAVE_ATTROPEN)
+ int ret = -1;
+ int myflags = O_RDWR | AT_SYMLINK_NOFOLLOW;
+ if (flags & XATTR_CREATE) myflags |= O_EXCL;
+ if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
+ int attrfd = solaris_attropen(path, name, myflags, (mode_t) SOLARIS_ATTRMODE);
+ if (attrfd >= 0) {
+ ret = solaris_write_xattr(attrfd, value, size);
+ close(attrfd);
+ }
+ return ret;
#else
errno = ENOSYS;
return -1;
@@ -2179,12 +2285,147 @@ int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size
if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
return attr_setf(filedes, attrname, (const char *)value, size, myflags);
+#elif defined(HAVE_ATTROPEN)
+ int ret = -1;
+ int myflags = O_RDWR | O_XATTR;
+ if (flags & XATTR_CREATE) myflags |= O_EXCL;
+ if (!(flags & XATTR_REPLACE)) myflags |= O_CREAT;
+ int attrfd = solaris_openat(filedes, name, myflags, (mode_t) SOLARIS_ATTRMODE);
+ if (attrfd >= 0) {
+ ret = solaris_write_xattr(attrfd, value, size);
+ close(attrfd);
+ }
+ return ret;
#else
errno = ENOSYS;
return -1;
#endif
}
+/**************************************************************************
+ helper functions for Solaris' EA support
+****************************************************************************/
+#ifdef HAVE_ATTROPEN
+static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size)
+{
+ struct stat sbuf;
+
+ if (fstat(attrfd, &sbuf) == -1) {
+ errno = ENOATTR;
+ return -1;
+ }
+
+ /* This is to return the current size of the named extended attribute */
+ if (size == 0) {
+ return sbuf.st_size;
+ }
+
+ /* check size and read xattr */
+ if (sbuf.st_size > size) {
+ errno = ERANGE;
+ return -1;
+ }
+
+ return read(attrfd, value, sbuf.st_size);
+}
+
+static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size)
+{
+ ssize_t len = 0;
+ int stop = 0;
+ DIR *dirp;
+ struct dirent *de;
+ int newfd = dup(attrdirfd);
+ /* CAUTION: The originating file descriptor should not be
+ used again following the call to fdopendir().
+ For that reason we dup() the file descriptor
+ here to make things more clear. */
+ dirp = fdopendir(newfd);
+
+ while ((de = readdir(dirp))) {
+ size_t listlen = strlen(de->d_name);
+ if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
+ /* we don't want "." and ".." here: */
+ DEBUG(10,("skipped EA %s\n",de->d_name));
+ continue;
+ }
+
+ if (size == 0) {
+ /* return the current size of the list of extended attribute names*/
+ len += listlen + 1;
+ } else {
+ /* check size and copy entrieѕ + nul into list. */
+ if ((len + listlen + 1) > size) {
+ errno = ERANGE;
+ len = -1;
+ break;
+ } else {
+ safe_strcpy(list + len, de->d_name, listlen);
+ pstrcpy(list + len, de->d_name);
+ len += listlen;
+ list[len] = '\0';
+ ++len;
+ }
+ }
+ }
+
+ if (closedir(dirp) == -1) {
+ DEBUG(0,("closedir dirp failed: %s\n",strerror(errno)));
+ return -1;
+ }
+ return len;
+}
+
+static int solaris_unlinkat(int attrdirfd, const char *name)
+{
+ if (unlinkat(attrdirfd, name, 0) == -1) {
+ if (errno == ENOENT) {
+ errno = ENOATTR;
+ }
+ return -1;
+ }
+ return 0;
+}
+
+static int solaris_attropen(const char *path, const char *attrpath, int oflag, mode_t mode)
+{
+ int filedes = attropen(path, attrpath, oflag, mode);
+ if (filedes == -1) {
+ DEBUG(10,("attropen FAILED: path: %s, name: %s, errno: %s\n",path,attrpath,strerror(errno)));
+ if (errno == EINVAL) {
+ errno = ENOTSUP;
+ } else {
+ errno = ENOATTR;
+ }
+ }
+ return filedes;
+}
+
+static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode)
+{
+ int filedes = openat(fildes, path, oflag, mode);
+ if (filedes == -1) {
+ DEBUG(10,("openat FAILED: fd: %s, path: %s, errno: %s\n",filedes,path,strerror(errno)));
+ if (errno == EINVAL) {
+ errno = ENOTSUP;
+ } else {
+ errno = ENOATTR;
+ }
+ }
+ return filedes;
+}
+
+static int solaris_write_xattr(int attrfd, const char *value, size_t size)
+{
+ if ((ftruncate(attrfd, 0) == 0) && (write(attrfd, value, size) == size)) {
+ return 0;
+ } else {
+ DEBUG(10,("solaris_write_xattr FAILED!\n"));
+ return -1;
+ }
+}
+#endif /*HAVE_ATTROPEN*/
+
/****************************************************************************
Return the major devicenumber for UNIX extensions.
****************************************************************************/
diff --git a/source/lib/util.c b/source/lib/util.c
index 90100d83374..6ce260d5e54 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -1833,8 +1833,7 @@ const char *readdirname(SMB_STRUCT_DIR *p)
BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensitive)
{
- pstring last_component;
- char *p;
+ const char *last_component;
/* if we have no list it's obviously not in the path */
if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
@@ -1844,8 +1843,12 @@ BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensit
DEBUG(8, ("is_in_path: %s\n", name));
/* Get the last component of the unix name. */
- p = strrchr_m(name, '/');
- pstrcpy(last_component, p ? ++p : name);
+ last_component = strrchr_m(name, '/');
+ if (!last_component) {
+ last_component = name;
+ } else {
+ last_component++; /* Go past '/' */
+ }
for(; namelist->name != NULL; namelist++) {
if(namelist->is_wild) {
@@ -1862,7 +1865,6 @@ BOOL is_in_path(const char *name, name_compare_entry *namelist, BOOL case_sensit
}
}
DEBUG(8,("is_in_path: match not found\n"));
-
return False;
}
@@ -2748,7 +2750,7 @@ BOOL ms_has_wild_w(const smb_ucs2_t *s)
of the ".." name.
*******************************************************************/
-BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
+BOOL mask_match(const char *string, const char *pattern, BOOL is_case_sensitive)
{
if (strcmp(string,"..") == 0)
string = ".";
@@ -2764,7 +2766,7 @@ BOOL mask_match(const char *string, char *pattern, BOOL is_case_sensitive)
pattern translation.
*******************************************************************/
-BOOL mask_match_search(const char *string, char *pattern, BOOL is_case_sensitive)
+BOOL mask_match_search(const char *string, const char *pattern, BOOL is_case_sensitive)
{
if (strcmp(string,"..") == 0)
string = ".";
diff --git a/source/libads/dns.c b/source/libads/dns.c
index f16cea25554..bf51625797a 100644
--- a/source/libads/dns.c
+++ b/source/libads/dns.c
@@ -606,8 +606,6 @@ static char *sitename_key(const char *realm)
/****************************************************************************
Store the AD client sitename.
We store indefinately as every new CLDAP query will re-write this.
- If the sitename is "Default-First-Site-Name" we don't store it
- as this isn't a valid DNS name.
****************************************************************************/
BOOL sitename_store(const char *realm, const char *sitename)
@@ -621,7 +619,7 @@ BOOL sitename_store(const char *realm, const char *sitename)
}
if (!realm || (strlen(realm) == 0)) {
- DEBUG(0,("no realm\n"));
+ DEBUG(0,("sitename_store: no realm\n"));
return False;
}
@@ -692,7 +690,7 @@ BOOL stored_sitename_changed(const char *realm, const char *sitename)
char *new_sitename;
if (!realm || (strlen(realm) == 0)) {
- DEBUG(0,("no realm\n"));
+ DEBUG(0,("stored_sitename_changed: no realm\n"));
return False;
}
diff --git a/source/libads/ldap.c b/source/libads/ldap.c
index 452a2285313..5d498abb1c0 100644
--- a/source/libads/ldap.c
+++ b/source/libads/ldap.c
@@ -2618,7 +2618,7 @@ ADS_STATUS ads_site_dn_for_machine(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, const c
if (*site_dn == NULL) {
ads_msgfree(ads, res);
ads_memfree(ads, dn);
- ADS_ERROR(LDAP_NO_MEMORY);
+ return ADS_ERROR(LDAP_NO_MEMORY);
}
ads_memfree(ads, dn);
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index dd84db319eb..d458ce2757c 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -584,6 +584,7 @@ static BOOL cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_B
NT_STATUS_MORE_PROCESSING_REQUIRED)) {
DEBUG(0, ("cli_session_setup_blob: recieve failed (%s)\n",
nt_errstr(cli_get_nt_error(cli)) ));
+ cli->vuid = 0;
return False;
}
}
@@ -770,6 +771,9 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
ntlmssp_end(&ntlmssp_state);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ cli->vuid = 0;
+ }
return nt_status;
}
@@ -1402,7 +1406,7 @@ BOOL cli_session_request(struct cli_state *cli,
Open the client sockets.
****************************************************************************/
-BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
+NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
{
int name_type = 0x20;
char *p;
@@ -1420,7 +1424,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
if (!ip || is_zero_ip(*ip)) {
if (!resolve_name(cli->desthost, &cli->dest_ip, name_type)) {
- return False;
+ return NT_STATUS_BAD_NETWORK_NAME;
}
if (ip) *ip = cli->dest_ip;
} else {
@@ -1445,12 +1449,12 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
if (cli->fd == -1) {
DEBUG(1,("Error connecting to %s (%s)\n",
ip?inet_ntoa(*ip):host,strerror(errno)));
- return False;
+ return map_nt_error_from_unix(errno);
}
set_socket_options(cli->fd,user_socket_options);
- return True;
+ return NT_STATUS_OK;
}
/**
@@ -1504,15 +1508,12 @@ again:
DEBUG(3,("Connecting to host=%s\n", dest_host));
- if (!cli_connect(cli, dest_host, &ip)) {
- DEBUG(1,("cli_start_connection: failed to connect to %s (%s)\n",
- nmb_namestr(&called), inet_ntoa(ip)));
+ nt_status = cli_connect(cli, dest_host, &ip);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
+ nmb_namestr(&called), inet_ntoa(ip), nt_errstr(nt_status) ));
cli_shutdown(cli);
- if (is_zero_ip(ip)) {
- return NT_STATUS_BAD_NETWORK_NAME;
- } else {
- return NT_STATUS_CONNECTION_REFUSED;
- }
+ return nt_status;
}
if (retry)
@@ -1657,6 +1658,7 @@ BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho
}
if (!cli_session_request(*ppcli, &calling, &called)) {
+ NTSTATUS status;
struct nmb_name smbservername;
make_nmb_name(&smbservername , "*SMBSERVER", 0x20);
@@ -1686,7 +1688,8 @@ with error %s.\n", desthost, cli_errstr(*ppcli) ));
return False;
}
- if (!cli_connect(*ppcli, desthost, pdest_ip) ||
+ status = cli_connect(*ppcli, desthost, pdest_ip);
+ if (!NT_STATUS_IS_OK(status) ||
!cli_session_request(*ppcli, &calling, &smbservername)) {
DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
diff --git a/source/libsmb/clidfs.c b/source/libsmb/clidfs.c
index 4009b98b418..d5e31b5eb85 100644
--- a/source/libsmb/clidfs.c
+++ b/source/libsmb/clidfs.c
@@ -69,6 +69,7 @@ static struct cli_state *do_connect( const char *server, const char *share,
pstring servicename;
char *sharename;
fstring newserver, newshare;
+ NTSTATUS status;
/* make a copy so we don't modify the global string 'service' */
pstrcpy(servicename, share);
@@ -94,11 +95,15 @@ static struct cli_state *do_connect( const char *server, const char *share,
ip = dest_ip;
/* have to open a new connection */
- if (!(c=cli_initialise()) || (cli_set_port(c, port) != port) ||
- !cli_connect(c, server_n, &ip)) {
+ if (!(c=cli_initialise()) || (cli_set_port(c, port) != port)) {
d_printf("Connection to %s failed\n", server_n);
return NULL;
}
+ status = cli_connect(c, server_n, &ip);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("Connection to %s failed (Error %s)\n", server_n, nt_errstr(status));
+ return NULL;
+ }
c->protocol = max_protocol;
c->use_kerberos = use_kerberos;
diff --git a/source/libsmb/errormap.c b/source/libsmb/errormap.c
index cb5e8311cad..35da0f962be 100644
--- a/source/libsmb/errormap.c
+++ b/source/libsmb/errormap.c
@@ -1521,6 +1521,9 @@ const struct unix_error_map unix_dos_nt_errmap[] = {
{ ENOMEM, ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY },
{ EISDIR, ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY},
{ EMLINK, ERRDOS, ERRgeneral, NT_STATUS_TOO_MANY_LINKS },
+#ifdef ELOOP
+ { ELOOP, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND },
+#endif
#ifdef EDQUOT
{ EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, /* Windows apps need this, not NT_STATUS_QUOTA_EXCEEDED */
#endif
@@ -1542,6 +1545,34 @@ const struct unix_error_map unix_dos_nt_errmap[] = {
#ifdef ENOBUFS
{ ENOBUFS, ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES },
#endif
+ { EAGAIN, ERRDOS, 111, NT_STATUS_NETWORK_BUSY },
+#ifdef EADDRINUSE
+ { EADDRINUSE, ERRDOS, 52, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED},
+#endif
+#ifdef ENETUNREACH
+ { ENETUNREACH, ERRHRD, ERRgeneral, NT_STATUS_NETWORK_UNREACHABLE},
+#endif
+#ifdef EHOSTUNREACH
+ { EHOSTUNREACH, ERRHRD, ERRgeneral, NT_STATUS_HOST_UNREACHABLE},
+#endif
+#ifdef ECONNREFUSED
+ { ECONNREFUSED, ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_REFUSED},
+#endif
+#ifdef ETIMEDOUT
+ { ETIMEDOUT, ERRHRD, 121, NT_STATUS_IO_TIMEOUT},
+#endif
+#ifdef ECONNABORTED
+ { ECONNABORTED, ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ABORTED},
+#endif
+#ifdef ENODEV
+ { ENODEV, ERRDOS, 55, NT_STATUS_DEVICE_DOES_NOT_EXIST},
+#endif
+#ifdef EPIPE
+ {EPIPE, ERRDOS, 109, NT_STATUS_PIPE_BROKEN},
+#endif
+#ifdef EWOULDBLOCK
+ { EWOULDBLOCK, ERRDOS, 111, NT_STATUS_NETWORK_BUSY },
+#endif
{ 0, 0, 0, NT_STATUS_OK }
};
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index e04a6385a07..e13b21f1115 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -675,7 +675,8 @@ smbc_server(SMBCCTX *context,
int port_try_first;
int port_try_next;
const char *username_used;
-
+ NTSTATUS status;
+
zero_ip(&ip);
ZERO_STRUCT(c);
@@ -795,17 +796,19 @@ smbc_server(SMBCCTX *context,
c->port = port_try_first;
- if (!cli_connect(c, server_n, &ip)) {
+ status = cli_connect(c, server_n, &ip);
+ if (!NT_STATUS_IS_OK(status)) {
/* First connection attempt failed. Try alternate port. */
c->port = port_try_next;
- if (!cli_connect(c, server_n, &ip)) {
- cli_shutdown(c);
- errno = ETIMEDOUT;
- return NULL;
- }
- }
+ status = cli_connect(c, server_n, &ip);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_shutdown(c);
+ errno = ETIMEDOUT;
+ return NULL;
+ }
+ }
if (!cli_session_request(c, &calling, &called)) {
cli_shutdown(c);
@@ -3442,8 +3445,6 @@ static off_t
smbc_telldir_ctx(SMBCCTX *context,
SMBCFILE *dir)
{
- off_t ret_val; /* Squash warnings about cast */
-
if (!context || !context->internal ||
!context->internal->_initialized) {
@@ -3466,12 +3467,16 @@ smbc_telldir_ctx(SMBCCTX *context,
}
+ /* See if we're already at the end. */
+ if (dir->dir_next == NULL) {
+ /* We are. */
+ return -1;
+ }
+
/*
* We return the pointer here as the offset
*/
- ret_val = (off_t)(long)dir->dir_next;
- return ret_val;
-
+ return (off_t)(long)dir->dir_next->dirent;
}
/*
@@ -3542,6 +3547,11 @@ smbc_lseekdir_ctx(SMBCCTX *context,
}
+ if (offset == -1) { /* Seek to the end of the list */
+ dir->dir_next = NULL;
+ return 0;
+ }
+
/* Now, run down the list and make sure that the entry is OK */
/* This may need to be changed if we change the format of the list */
@@ -4534,6 +4544,7 @@ cacl_get(SMBCCTX *context,
buf += n;
n_used += n;
bufsize -= n;
+ n = 0;
}
if (! exclude_nt_owner) {
@@ -4581,6 +4592,7 @@ cacl_get(SMBCCTX *context,
buf += n;
n_used += n;
bufsize -= n;
+ n = 0;
}
if (! exclude_nt_group) {
@@ -4626,6 +4638,7 @@ cacl_get(SMBCCTX *context,
buf += n;
n_used += n;
bufsize -= n;
+ n = 0;
}
if (! exclude_nt_acl) {
@@ -4716,6 +4729,7 @@ cacl_get(SMBCCTX *context,
buf += n;
n_used += n;
bufsize -= n;
+ n = 0;
}
}
@@ -4790,6 +4804,7 @@ cacl_get(SMBCCTX *context,
buf += n;
n_used += n;
bufsize -= n;
+ n = 0;
}
if (! exclude_dos_size) {
@@ -4834,6 +4849,7 @@ cacl_get(SMBCCTX *context,
buf += n;
n_used += n;
bufsize -= n;
+ n = 0;
}
if (! exclude_dos_create_time &&
@@ -4876,6 +4892,7 @@ cacl_get(SMBCCTX *context,
buf += n;
n_used += n;
bufsize -= n;
+ n = 0;
}
if (! exclude_dos_access_time) {
@@ -4917,6 +4934,7 @@ cacl_get(SMBCCTX *context,
buf += n;
n_used += n;
bufsize -= n;
+ n = 0;
}
if (! exclude_dos_write_time) {
@@ -4958,6 +4976,7 @@ cacl_get(SMBCCTX *context,
buf += n;
n_used += n;
bufsize -= n;
+ n = 0;
}
if (! exclude_dos_change_time) {
@@ -4999,6 +5018,7 @@ cacl_get(SMBCCTX *context,
buf += n;
n_used += n;
bufsize -= n;
+ n = 0;
}
if (! exclude_dos_inode) {
@@ -5043,6 +5063,7 @@ cacl_get(SMBCCTX *context,
buf += n;
n_used += n;
bufsize -= n;
+ n = 0;
}
/* Restore name pointer to its original value */
@@ -5137,8 +5158,8 @@ cacl_set(TALLOC_CTX *ctx,
switch (mode) {
case SMBC_XATTR_MODE_REMOVE_ALL:
old->dacl->num_aces = 0;
- SAFE_FREE(old->dacl->aces);
- SAFE_FREE(old->dacl);
+ prs_mem_free(old->dacl->aces);
+ prs_mem_free(&old->dacl);
old->dacl = NULL;
dacl = old->dacl;
break;
@@ -5157,8 +5178,8 @@ cacl_set(TALLOC_CTX *ctx,
}
old->dacl->num_aces--;
if (old->dacl->num_aces == 0) {
- SAFE_FREE(old->dacl->aces);
- SAFE_FREE(old->dacl);
+ prs_mem_free(&old->dacl->aces);
+ prs_mem_free(&old->dacl);
old->dacl = NULL;
}
found = True;
diff --git a/source/libsmb/passchange.c b/source/libsmb/passchange.c
index 5b4b0896c0f..bfa513d002f 100644
--- a/source/libsmb/passchange.c
+++ b/source/libsmb/passchange.c
@@ -39,7 +39,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
*err_str = '\0';
if(!resolve_name( remote_machine, &ip, 0x20)) {
- slprintf(err_str, err_str_len-1, "unable to find an IP address for machine %s.\n",
+ slprintf(err_str, err_str_len-1, "Unable to find an IP address for machine %s.\n",
remote_machine );
return NT_STATUS_UNSUCCESSFUL;
}
@@ -49,10 +49,10 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam
return NT_STATUS_NO_MEMORY;
}
- if (!cli_connect(cli, remote_machine, &ip)) {
- slprintf(err_str, err_str_len-1, "unable to connect to SMB server on machine %s. Error was : %s.\n",
- remote_machine, cli_errstr(cli) );
- result = cli_nt_error(cli);
+ result = cli_connect(cli, remote_machine, &ip);
+ if (!NT_STATUS_IS_OK(result)) {
+ slprintf(err_str, err_str_len-1, "Unable to connect to SMB server on machine %s. Error was : %s.\n",
+ remote_machine, nt_errstr(result) );
cli_shutdown(cli);
return result;
}
diff --git a/source/locking/locking.c b/source/locking/locking.c
index 56d8ff206fe..a0debcd8de5 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -41,6 +41,8 @@
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_LOCKING
+#define NO_LOCKING_COUNT (-1)
+
/* the locking database handle */
static TDB_CONTEXT *tdb;
@@ -224,11 +226,19 @@ struct byte_range_lock *do_lock(files_struct *fsp,
blocking_lock,
plock_pid);
- /* blocking ie. pending, locks also count here,
- * as this is an efficiency counter to avoid checking
- * the lock db. on close. JRA. */
+ if (lock_flav == WINDOWS_LOCK &&
+ fsp->current_lock_count != NO_LOCKING_COUNT) {
+ /* blocking ie. pending, locks also count here,
+ * as this is an efficiency counter to avoid checking
+ * the lock db. on close. JRA. */
- fsp->current_lock_count++;
+ fsp->current_lock_count++;
+ } else {
+ /* Notice that this has had a POSIX lock request.
+ * We can't count locks after this so forget them.
+ */
+ fsp->current_lock_count = NO_LOCKING_COUNT;
+ }
return br_lck;
}
@@ -276,8 +286,11 @@ NTSTATUS do_unlock(files_struct *fsp,
return NT_STATUS_RANGE_NOT_LOCKED;
}
- SMB_ASSERT(fsp->current_lock_count > 0);
- fsp->current_lock_count--;
+ if (lock_flav == WINDOWS_LOCK &&
+ fsp->current_lock_count != NO_LOCKING_COUNT) {
+ SMB_ASSERT(fsp->current_lock_count > 0);
+ fsp->current_lock_count--;
+ }
return NT_STATUS_OK;
}
@@ -326,8 +339,11 @@ NTSTATUS do_lock_cancel(files_struct *fsp,
return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
}
- SMB_ASSERT(fsp->current_lock_count > 0);
- fsp->current_lock_count--;
+ if (lock_flav == WINDOWS_LOCK &&
+ fsp->current_lock_count != NO_LOCKING_COUNT) {
+ SMB_ASSERT(fsp->current_lock_count > 0);
+ fsp->current_lock_count--;
+ }
return NT_STATUS_OK;
}
@@ -913,6 +929,14 @@ BOOL is_valid_share_mode_entry(const struct share_mode_entry *e)
{
int num_props = 0;
+ if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
+ /* cope with dead entries from the process not
+ existing. These should not be considered valid,
+ otherwise we end up doing zero timeout sharing
+ violation */
+ return False;
+ }
+
num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
diff --git a/source/modules/nfs4_acls.h b/source/modules/nfs4_acls.h
index 469a50af56a..13f373c16cc 100644
--- a/source/modules/nfs4_acls.h
+++ b/source/modules/nfs4_acls.h
@@ -138,7 +138,7 @@ size_t smb_get_nt_acl_nfs4(files_struct *fsp,
* when applicable */
typedef BOOL (*set_nfs4acl_native_fn_t)(files_struct *, SMB4ACL_T *);
-BOOL smb_set_nt_acl_nfs4(files_struct *fsp,
+NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
uint32 security_info_sent,
SEC_DESC *psd,
set_nfs4acl_native_fn_t set_nfs4_native);
diff --git a/source/modules/vfs_readahead.c b/source/modules/vfs_readahead.c
index 9c20acebd94..e0f137af81f 100644
--- a/source/modules/vfs_readahead.c
+++ b/source/modules/vfs_readahead.c
@@ -160,7 +160,7 @@ static int readahead_connect(struct vfs_handle_struct *handle,
handle->data = (void *)rhd;
handle->free_data = free_readahead_data;
- return 0;
+ return SMB_VFS_NEXT_CONNECT(handle, service, user);
}
/*******************************************************************
diff --git a/source/nmbd/nmbd_synclists.c b/source/nmbd/nmbd_synclists.c
index 7fe39676c6f..fa1a41a5af7 100644
--- a/source/nmbd/nmbd_synclists.c
+++ b/source/nmbd/nmbd_synclists.c
@@ -71,6 +71,7 @@ static void sync_child(char *name, int nm_type,
struct cli_state *cli;
uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0;
struct nmb_name called, calling;
+ NTSTATUS status;
/* W2K DMB's return empty browse lists on port 445. Use 139.
* Patch from Andy Levine andyl@epicrealm.com.
@@ -81,7 +82,12 @@ static void sync_child(char *name, int nm_type,
return;
}
- if (!cli_set_port(cli, 139) || !cli_connect(cli, name, &ip)) {
+ if (!cli_set_port(cli, 139)) {
+ return;
+ }
+
+ status = cli_connect(cli, name, &ip);
+ if (!NT_STATUS_IS_OK(status)) {
return;
}
diff --git a/source/nsswitch/nss_info.c b/source/nsswitch/nss_info.c
index d2516296629..8c18162deb4 100644
--- a/source/nsswitch/nss_info.c
+++ b/source/nsswitch/nss_info.c
@@ -156,7 +156,7 @@ static BOOL parse_nss_parm( const char *config, char **backend, char **domain )
if ( !parse_nss_parm(nss_list[i], &backend, &domain) ) {
DEBUG(0,("nss_init: failed to parse \"%s\"!\n",
- nss_list[0]));
+ nss_list[i]));
continue;
}
diff --git a/source/nsswitch/nss_info_template.c b/source/nsswitch/nss_info_template.c
index 2a144288021..845371e53ba 100644
--- a/source/nsswitch/nss_info_template.c
+++ b/source/nsswitch/nss_info_template.c
@@ -42,7 +42,7 @@ static NTSTATUS nss_template_get_info( struct nss_domain_entry *e,
char **homedir,
char **shell,
char **gecos,
- uint32 *gid )
+ gid_t *gid )
{
if ( !homedir || !shell || !gecos )
return NT_STATUS_INVALID_PARAMETER;
diff --git a/source/nsswitch/wbinfo.c b/source/nsswitch/wbinfo.c
index 6db37fca80f..467afe82457 100644
--- a/source/nsswitch/wbinfo.c
+++ b/source/nsswitch/wbinfo.c
@@ -1459,37 +1459,16 @@ int main(int argc, char **argv, char **envp)
break;
}
case 'K': {
- BOOL got_error = False;
uint32 flags = WBFLAG_PAM_KRB5 |
WBFLAG_PAM_CACHED_LOGIN |
WBFLAG_PAM_FALLBACK_AFTER_KRB5 |
WBFLAG_PAM_INFO3_TEXT;
- fstring tok;
- int i;
- const char *arg[] = { NULL, NULL };
- const char *cctypes[] = { "FILE",
- "KCM",
- "KCM:0",
- "Garbage",
- NULL,
- "0"};
-
- arg[0] = string_arg;
-
- while (next_token(arg, tok, LIST_SEP, sizeof(tok))) {
-
- for (i=0; i < ARRAY_SIZE(cctypes); i++) {
- if (!wbinfo_auth_krb5(tok, cctypes[i], flags)) {
- d_fprintf(stderr, "Could not authenticate user [%s] with "
- "Kerberos (ccache: %s)\n", tok, cctypes[i]);
- got_error = True;
- }
- }
- }
- if (got_error)
+ if (!wbinfo_auth_krb5(string_arg, "FILE", flags)) {
+ d_fprintf(stderr, "Could not authenticate user [%s] with "
+ "Kerberos (ccache: %s)\n", string_arg, "FILE");
goto done;
-
+ }
break;
}
case 'k':
diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c
index 9a0ade55416..d2daf7830db 100644
--- a/source/nsswitch/winbindd_util.c
+++ b/source/nsswitch/winbindd_util.c
@@ -37,14 +37,6 @@ extern struct winbindd_methods passdb_methods;
**/
-/**
- * Used to clobber name fields that have an undefined value.
- *
- * Correct code should never look at a field that has this value.
- **/
-
-static const fstring name_deadbeef = "<deadbeef>";
-
/* The list of trusted domains. Note that the list can be deleted and
recreated using the init_domain_list() function so pointers to
individual winbindd_domain structures cannot be made. Keep a copy of
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index 24df6279341..afcb463a631 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -1611,7 +1611,7 @@ static NTSTATUS ldapsam_modify_entry(struct pdb_methods *my_methods,
ber_printf (ber, "{");
ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, utf8_dn);
ber_printf (ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, utf8_password);
- ber_printf (ber, "N}");
+ ber_printf (ber, "n}");
if ((rc = ber_flatten (ber, &bv))<0) {
DEBUG(0,("ldapsam_modify_entry: ber_flatten returns a value <0\n"));
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index fc35ccbe2bb..4410348abee 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -6064,9 +6064,26 @@ static BOOL sam_io_user_info25(const char *desc, SAM_USER_INFO_25 * usr, prs_str
if(!prs_uint32("fields_present ", ps, depth, &usr->fields_present))
return False;
- if(!prs_uint32s(False, "unknown_5 ", ps, depth, usr->unknown_5, 5))
+ if(!prs_uint16("logon_divs ", ps, depth, &usr->logon_divs)) /* logon divisions per week */
+ return False;
+ if(!prs_align(ps))
+ return False;
+ if(!prs_uint32("ptr_logon_hrs ", ps, depth, &usr->ptr_logon_hrs))
+ return False;
+
+ if(!prs_uint16("bad_password_count ", ps, depth, &usr->bad_password_count))
+ return False;
+ if(!prs_uint16("logon_count ", ps, depth, &usr->logon_count))
return False;
+ if(!prs_uint8s(False, "padding1 ", ps, depth, usr->padding1, sizeof(usr->padding1)))
+ return False;
+ if(!prs_uint8("passmustchange ", ps, depth, &usr->passmustchange))
+ return False;
+ if(!prs_uint8("padding2 ", ps, depth, &usr->padding2))
+ return False;
+
+
if(!prs_uint8s(False, "password ", ps, depth, usr->pass, sizeof(usr->pass)))
return False;
@@ -6102,13 +6119,11 @@ static BOOL sam_io_user_info25(const char *desc, SAM_USER_INFO_25 * usr, prs_str
if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial, usr->hdr_munged_dial.buffer, ps, depth))
return False;
-#if 0 /* JRA - unknown... */
/* ok, this is only guess-work (as usual) */
if (usr->ptr_logon_hrs) {
if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
return False;
}
-#endif
return True;
}
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index c924c75453d..3343f16f35d 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -3372,11 +3372,17 @@ static BOOL set_user_info_pw(uint8 *pass, struct samu *pwd)
uint32 len;
pstring plaintext_buf;
uint32 acct_ctrl;
+ time_t last_set_time;
+ enum pdb_value_state last_set_state;
DEBUG(5, ("Attempting administrator password change for user %s\n",
pdb_get_username(pwd)));
acct_ctrl = pdb_get_acct_ctrl(pwd);
+ /* we need to know if it's expired, because this is an admin change, not a
+ user change, so it's still expired when we're done */
+ last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET);
+ last_set_time = pdb_get_pass_last_set_time(pwd);
ZERO_STRUCT(plaintext_buf);
@@ -3418,6 +3424,9 @@ static BOOL set_user_info_pw(uint8 *pass, struct samu *pwd)
}
ZERO_STRUCT(plaintext_buf);
+
+ /* restore last set time as this is an admin change, not a user pw change */
+ pdb_set_pass_last_set_time (pwd, last_set_time, last_set_state);
DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
diff --git a/source/rpc_server/srv_samr_util.c b/source/rpc_server/srv_samr_util.c
index 8acc1785ef6..42ad462ee77 100644
--- a/source/rpc_server/srv_samr_util.c
+++ b/source/rpc_server/srv_samr_util.c
@@ -670,4 +670,47 @@ void copy_id25_to_sam_passwd(struct samu *to, SAM_USER_INFO_25 *from)
pdb_set_acct_ctrl(to, from->acb_info, PDB_CHANGED);
}
}
+
+ if (from->fields_present & ACCT_LOGON_HOURS) {
+ DEBUG(15,("INFO_25 LOGON_DIVS: %08X -> %08X\n",pdb_get_logon_divs(to),from->logon_divs));
+ if (from->logon_divs != pdb_get_logon_divs(to)) {
+ pdb_set_logon_divs(to, from->logon_divs, PDB_CHANGED);
+ }
+
+ DEBUG(15,("INFO_25 LOGON_HRS.LEN: %08X -> %08X\n",pdb_get_hours_len(to),from->logon_hrs.len));
+ if (from->logon_hrs.len != pdb_get_hours_len(to)) {
+ pdb_set_hours_len(to, from->logon_hrs.len, PDB_CHANGED);
+ }
+
+ DEBUG(15,("INFO_25 LOGON_HRS.HOURS: %s -> %s\n",pdb_get_hours(to),from->logon_hrs.hours));
+ /* Fix me: only update if it changes --metze */
+ pdb_set_hours(to, from->logon_hrs.hours, PDB_CHANGED);
+ }
+
+ if (from->fields_present & ACCT_BAD_PWD_COUNT) {
+ DEBUG(10,("INFO_25 BAD_PASSWORD_COUNT: %08X -> %08X\n",pdb_get_bad_password_count(to),from->bad_password_count));
+ if (from->bad_password_count != pdb_get_bad_password_count(to)) {
+ pdb_set_bad_password_count(to, from->bad_password_count, PDB_CHANGED);
+ }
+ }
+
+ if (from->fields_present & ACCT_NUM_LOGONS) {
+ DEBUG(10,("INFO_25 LOGON_COUNT: %08X -> %08X\n",pdb_get_logon_count(to),from->logon_count));
+ if (from->logon_count != pdb_get_logon_count(to)) {
+ pdb_set_logon_count(to, from->logon_count, PDB_CHANGED);
+ }
+ }
+
+ /* If the must change flag is set, the last set time goes to zero.
+ the must change and can change fields also do, but they are
+ calculated from policy, not set from the wire */
+
+ if (from->fields_present & ACCT_EXPIRED_FLAG) {
+ DEBUG(10,("INFO_25 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange));
+ if (from->passmustchange == PASS_MUST_CHANGE_AT_NEXT_LOGON) {
+ pdb_set_pass_last_set_time(to, 0, PDB_CHANGED);
+ } else {
+ pdb_set_pass_last_set_time(to, time(NULL),PDB_CHANGED);
+ }
+ }
}
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index 03a407ad557..4cf43f04e49 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -2263,6 +2263,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
*type = REG_DWORD;
if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
return WERR_NOMEM;
+ SIVAL(*data, 0, 0x00);
*needed = 0x4;
return WERR_OK;
}
diff --git a/source/script/mkversion.sh b/source/script/mkversion.sh
index 57840549213..aee7d0a1188 100755
--- a/source/script/mkversion.sh
+++ b/source/script/mkversion.sh
@@ -104,7 +104,7 @@ echo "$0: 'include/version.h' created for Samba(\"${SAMBA_VERSION_STRING}\")"
if test -n "${SAMBA_VERSION_VENDOR_SUFFIX}";then
echo -n "$0: with VENDOR_SUFFIX = \""
echo -n ${SAMBA_VERSION_VENDOR_SUFFIX} | sed 's/"//g'
- if test -n ${SAMBA_VENDOR_PATCH}; then
+ if test -n "${SAMBA_VENDOR_PATCH}"; then
echo -n "-${SAMBA_VENDOR_PATCH}"
fi
echo "\""
diff --git a/source/services/services_db.c b/source/services/services_db.c
index 5b4f58d766d..c8ba273e30f 100644
--- a/source/services/services_db.c
+++ b/source/services/services_db.c
@@ -416,7 +416,7 @@ void svcctl_init_keys( void )
REG_KEY_ALL );
if ( !W_ERROR_IS_OK(wresult) ) {
- DEBUG(0,("init_services_keys: key lookup failed! (%s)\n",
+ DEBUG(0,("svcctl_init_keys: key lookup failed! (%s)\n",
dos_errstr(wresult)));
return;
}
@@ -424,7 +424,7 @@ void svcctl_init_keys( void )
/* lookup the available subkeys */
if ( !(subkeys = TALLOC_ZERO_P( key, REGSUBKEY_CTR )) ) {
- DEBUG(0,("init_services_keys: talloc() failed!\n"));
+ DEBUG(0,("svcctl_init_keys: talloc() failed!\n"));
regkey_close_internal( key );
return;
}
diff --git a/source/smbd/close.c b/source/smbd/close.c
index 6a496f16a6e..a094d8a4da0 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -153,6 +153,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
struct share_mode_lock *lck;
SMB_STRUCT_STAT sbuf;
NTSTATUS status = NT_STATUS_OK;
+ int ret;
/*
* Lock the share entries, and determine if we should delete
@@ -245,8 +246,14 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
/* We can only delete the file if the name we have is still valid and
hasn't been renamed. */
-
- if(SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf) != 0) {
+
+ if (fsp->posix_open) {
+ ret = SMB_VFS_LSTAT(conn,fsp->fsp_name,&sbuf);
+ } else {
+ ret = SMB_VFS_STAT(conn,fsp->fsp_name,&sbuf);
+ }
+
+ if (ret != 0) {
DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
"was set and stat failed with error %s\n",
fsp->fsp_name, strerror(errno) ));
diff --git a/source/smbd/error.c b/source/smbd/error.c
index 0860b7d1d91..fa344e372e5 100644
--- a/source/smbd/error.c
+++ b/source/smbd/error.c
@@ -132,3 +132,22 @@ int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, in
error_packet_set(outbuf, eclass, ecode, ntstatus, line, file);
return outsize;
}
+
+/*******************************************************************************
+ Special error map processing needed for returning DOS errors on open calls.
+*******************************************************************************/
+
+int error_open(char *outbuf, NTSTATUS status, int line, const char *file)
+{
+ if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) {
+ /*
+ * We hit an existing file, and if we're returning DOS
+ * error codes OBJECT_NAME_COLLISION would map to
+ * ERRDOS/183, we need to return ERRDOS/80, see bug
+ * 4852.
+ */
+ return error_packet(outbuf, ERRDOS, ERRfilexists,
+ NT_STATUS_OBJECT_NAME_COLLISION, line, file);
+ }
+ return error_packet(outbuf,0,0,status,line,file);
+}
diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c
index 1227d12b08e..a5f8242d06e 100644
--- a/source/smbd/fileio.c
+++ b/source/smbd/fileio.c
@@ -509,15 +509,20 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
write_path = 3;
- } else if ( (pos >= wcp->file_size) &&
+ } else if ( (pos >= wcp->file_size) &&
(n == 1) &&
- (pos < wcp->offset + 2*wcp->alloc_size) &&
- (wcp->file_size == wcp->offset + wcp->data_size)) {
+ (wcp->file_size == wcp->offset + wcp->data_size) &&
+ (pos < wcp->file_size + wcp->alloc_size)) {
/*
- +---------------+
- | Cached data |
- +---------------+
+
+ End of file ---->|
+
+ +---------------+---------------+
+ | Cached data | Cache buffer |
+ +---------------+---------------+
+
+ |<------- allocated size ---------------->|
+--------+
| 1 Byte |
@@ -525,13 +530,18 @@ nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
MS-Office seems to do this a lot to determine if there's enough
space on the filesystem to write a new file.
- */
- SMB_BIG_UINT new_start = wcp->offset + wcp->data_size;
+ Change to :
+
+ End of file ---->|
+ +-----------------------+--------+
+ | Zeroed Cached data | 1 Byte |
+ +-----------------------+--------+
+ */
flush_write_cache(fsp, WRITE_FLUSH);
- wcp->offset = new_start;
- wcp->data_size = pos - new_start + 1;
+ wcp->offset = wcp->file_size;
+ wcp->data_size = pos - wcp->file_size + 1;
memset(wcp->data, '\0', wcp->data_size);
memcpy(wcp->data + wcp->data_size-1, data, 1);
diff --git a/source/smbd/filename.c b/source/smbd/filename.c
index eb86a0efd16..570297bf69f 100644
--- a/source/smbd/filename.c
+++ b/source/smbd/filename.c
@@ -392,20 +392,25 @@ NTSTATUS unix_convert(connection_struct *conn,
* these two errors.
*/
- /* ENOENT and ENOTDIR both map to NT_STATUS_OBJECT_PATH_NOT_FOUND
- in the filename walk. */
+ /* ENOENT, ENOTDIR and ELOOP all map to
+ * NT_STATUS_OBJECT_PATH_NOT_FOUND
+ * in the filename walk. */
- if (errno == ENOENT || errno == ENOTDIR) {
+ if (errno == ENOENT ||
+ errno == ENOTDIR ||
+ errno == ELOOP) {
return NT_STATUS_OBJECT_PATH_NOT_FOUND;
}
return map_nt_error_from_unix(errno);
}
-
+
/* ENOENT is the only valid error here. */
if (errno != ENOENT) {
- /* ENOENT and ENOTDIR both map to NT_STATUS_OBJECT_PATH_NOT_FOUND
- in the filename walk. */
- if (errno == ENOTDIR) {
+ /* ENOTDIR and ELOOP both map to
+ * NT_STATUS_OBJECT_PATH_NOT_FOUND
+ * in the filename walk. */
+ if (errno == ENOTDIR ||
+ errno == ELOOP) {
return NT_STATUS_OBJECT_PATH_NOT_FOUND;
}
return map_nt_error_from_unix(errno);
diff --git a/source/smbd/msdfs.c b/source/smbd/msdfs.c
index 7b660899d55..74acf3d37e3 100644
--- a/source/smbd/msdfs.c
+++ b/source/smbd/msdfs.c
@@ -388,7 +388,8 @@ static NTSTATUS dfs_path_lookup(connection_struct *conn,
pstrcpy(localpath, pdp->reqpath);
status = unix_convert(conn, localpath, search_flag, NULL, &sbuf);
- if (!NT_STATUS_IS_OK(status)) {
+ if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status,
+ NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
return status;
}
@@ -420,6 +421,14 @@ static NTSTATUS dfs_path_lookup(connection_struct *conn,
}
/*
+ * localpath comes out of unix_convert, so it has
+ * no trailing backslash. Make sure that canon_dfspath hasn't either.
+ * Fix for bug #4860 from Jan Martin <Jan.Martin@rwedea.com>.
+ */
+
+ trim_char(canon_dfspath,0,'/');
+
+ /*
* Redirect if any component in the path is a link.
* We do this by walking backwards through the
* local path, chopping off the last component
diff --git a/source/smbd/notify.c b/source/smbd/notify.c
index 7b831c2f560..df9d8ad1378 100644
--- a/source/smbd/notify.c
+++ b/source/smbd/notify.c
@@ -27,7 +27,7 @@ struct notify_change_request {
struct files_struct *fsp; /* backpointer for cancel by mid */
char request_buf[smb_size];
uint32 filter;
- uint32 current_bufsize;
+ uint32 max_param;
struct notify_mid_map *mid_map;
void *backend_data;
};
@@ -47,19 +47,40 @@ struct notify_mid_map {
uint16 mid;
};
+static BOOL notify_change_record_identical(struct notify_change *c1,
+ struct notify_change *c2)
+{
+ /* Note this is deliberately case sensitive. */
+ if (c1->action == c2->action &&
+ strcmp(c1->name, c2->name) == 0) {
+ return True;
+ }
+ return False;
+}
+
static BOOL notify_marshall_changes(int num_changes,
- struct notify_change *changes,
- prs_struct *ps)
+ uint32 max_offset,
+ struct notify_change *changes,
+ prs_struct *ps)
{
int i;
UNISTR uni_name;
for (i=0; i<num_changes; i++) {
- struct notify_change *c = &changes[i];
+ struct notify_change *c;
size_t namelen;
uint32 u32_tmp; /* Temp arg to prs_uint32 to avoid
* signed/unsigned issues */
+ /* Coalesce any identical records. */
+ while (i+1 < num_changes &&
+ notify_change_record_identical(&changes[i],
+ &changes[i+1])) {
+ i++;
+ }
+
+ c = &changes[i];
+
namelen = convert_string_allocate(
NULL, CH_UNIX, CH_UTF16LE, c->name, strlen(c->name)+1,
&uni_name.buffer, True);
@@ -90,6 +111,11 @@ static BOOL notify_marshall_changes(int num_changes,
prs_set_offset(ps, prs_offset(ps)-2);
SAFE_FREE(uni_name.buffer);
+
+ if (prs_offset(ps) > max_offset) {
+ /* Too much data for client. */
+ return False;
+ }
}
return True;
@@ -125,7 +151,7 @@ static void change_notify_reply_packet(const char *request_buf,
"failed.");
}
-void change_notify_reply(const char *request_buf,
+void change_notify_reply(const char *request_buf, uint32 max_param,
struct notify_change_buf *notify_buf)
{
char *outbuf = NULL;
@@ -134,13 +160,19 @@ void change_notify_reply(const char *request_buf,
if (notify_buf->num_changes == -1) {
change_notify_reply_packet(request_buf, NT_STATUS_OK);
+ notify_buf->num_changes = 0;
return;
}
- if (!prs_init(&ps, 0, NULL, False)
- || !notify_marshall_changes(notify_buf->num_changes,
+ prs_init(&ps, 0, NULL, MARSHALL);
+
+ if (!notify_marshall_changes(notify_buf->num_changes, max_param,
notify_buf->changes, &ps)) {
- change_notify_reply_packet(request_buf, NT_STATUS_NO_MEMORY);
+ /*
+ * We exceed what the client is willing to accept. Send
+ * nothing.
+ */
+ change_notify_reply_packet(request_buf, NT_STATUS_OK);
goto done;
}
@@ -206,7 +238,7 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter,
return status;
}
-NTSTATUS change_notify_add_request(const char *inbuf,
+NTSTATUS change_notify_add_request(const char *inbuf, uint32 max_param,
uint32 filter, BOOL recursive,
struct files_struct *fsp)
{
@@ -223,11 +255,11 @@ NTSTATUS change_notify_add_request(const char *inbuf,
map->req = request;
memcpy(request->request_buf, inbuf, sizeof(request->request_buf));
- request->current_bufsize = 0;
+ request->max_param = max_param;
request->filter = filter;
request->fsp = fsp;
request->backend_data = NULL;
-
+
DLIST_ADD_END(fsp->notify->requests, request,
struct notify_change_request *);
@@ -399,6 +431,7 @@ static void notify_fsp(files_struct *fsp, uint32 action, const char *name)
*/
change_notify_reply(fsp->notify->requests->request_buf,
+ fsp->notify->requests->max_param,
fsp->notify);
change_notify_remove_request(fsp->notify->requests);
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index 6da1bba8b9b..5a9e0a9367b 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -716,18 +716,6 @@ int reply_ntcreate_and_X(connection_struct *conn,
create_options,
new_file_attributes,
&info, &fsp);
-
- restore_case_semantics(conn, file_attributes);
-
- if(!NT_STATUS_IS_OK(status)) {
- if (!use_nt_status() && NT_STATUS_EQUAL(
- status, NT_STATUS_OBJECT_NAME_COLLISION)) {
- status = NT_STATUS_DOS(ERRDOS, ERRfilexists);
- }
- END_PROFILE(SMBntcreateX);
- return ERROR_NT(status);
- }
-
} else {
/*
@@ -756,7 +744,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
oplock_request,
&info, &fsp);
- if (!NT_STATUS_IS_OK(status)) {
+ if (!NT_STATUS_IS_OK(status)) {
/* We cheat here. There are two cases we
* care about. One is a directory rename,
* where the NT client will attempt to
@@ -788,7 +776,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
END_PROFILE(SMBntcreateX);
return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
}
-
+
oplock_request = 0;
status = open_directory(conn, fname, &sbuf,
access_mask,
@@ -798,29 +786,23 @@ int reply_ntcreate_and_X(connection_struct *conn,
new_file_attributes,
&info, &fsp);
- if(!NT_STATUS_IS_OK(status)) {
- restore_case_semantics(conn, file_attributes);
- if (!use_nt_status() && NT_STATUS_EQUAL(
- status, NT_STATUS_OBJECT_NAME_COLLISION)) {
- status = NT_STATUS_DOS(ERRDOS, ERRfilexists);
- }
- END_PROFILE(SMBntcreateX);
- return ERROR_NT(status);
- }
- } else {
- restore_case_semantics(conn, file_attributes);
- END_PROFILE(SMBntcreateX);
- if (open_was_deferred(SVAL(inbuf,smb_mid))) {
- /* We have re-scheduled this call. */
- return -1;
- }
- return ERROR_NT(status);
}
- }
+ }
}
-
+
restore_case_semantics(conn, file_attributes);
+ if(!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBntcreateX);
+
+ if (open_was_deferred(SVAL(inbuf,smb_mid))) {
+ /* We have re-scheduled this call. */
+ return -1;
+ }
+
+ return ERROR_OPEN(status);
+ }
+
file_len = sbuf.st_size;
fattr = dos_mode(conn,fname,&sbuf);
if(fattr == 0) {
@@ -1416,11 +1398,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
create_options,
new_file_attributes,
&info, &fsp);
- if(!NT_STATUS_IS_OK(status)) {
- restore_case_semantics(conn, file_attributes);
- return ERROR_NT(status);
- }
-
} else {
/*
@@ -1436,7 +1413,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
oplock_request,
&info, &fsp);
- if (!NT_STATUS_IS_OK(status)) {
+ if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,
NT_STATUS_FILE_IS_A_DIRECTORY)) {
@@ -1448,7 +1425,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
restore_case_semantics(conn, file_attributes);
return ERROR_FORCE_NT(NT_STATUS_FILE_IS_A_DIRECTORY);
}
-
+
oplock_request = 0;
status = open_directory(conn, fname, &sbuf,
access_mask,
@@ -1457,26 +1434,26 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
create_options,
new_file_attributes,
&info, &fsp);
- if(!NT_STATUS_IS_OK(status)) {
- restore_case_semantics(conn, file_attributes);
- return ERROR_NT(status);
- }
- } else {
- restore_case_semantics(conn, file_attributes);
- if (open_was_deferred(SVAL(inbuf,smb_mid))) {
- /* We have re-scheduled this call. */
- return -1;
- }
- return ERROR_NT(status);
}
- }
+ }
+ }
+
+ restore_case_semantics(conn, file_attributes);
+ if(!NT_STATUS_IS_OK(status)) {
+
+ if (open_was_deferred(SVAL(inbuf,smb_mid))) {
+ /* We have re-scheduled this call. */
+ return -1;
+ }
+
+ return ERROR_OPEN(status);
}
/*
* According to the MS documentation, the only time the security
* descriptor is applied to the opened file is iff we *created* the
* file; an existing file stays the same.
- *
+ *
* Also, it seems (from observation) that you can open the file with
* any access mask but you can still write the sd. We need to override
* the granted access before we call set_sd
@@ -1979,7 +1956,7 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,
* here.
*/
- change_notify_reply(inbuf, fsp->notify);
+ change_notify_reply(inbuf, max_param_count, fsp->notify);
/*
* change_notify_reply() above has independently sent its
@@ -1992,7 +1969,8 @@ static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,
* No changes pending, queue the request
*/
- status = change_notify_add_request(inbuf, filter, recursive, fsp);
+ status = change_notify_add_request(inbuf, max_param_count, filter,
+ recursive, fsp);
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
}
diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c
index 7eda998547e..def918b29fb 100644
--- a/source/smbd/posix_acls.c
+++ b/source/smbd/posix_acls.c
@@ -47,7 +47,7 @@ typedef struct canon_ace {
DOM_SID trustee;
enum ace_owner owner_type;
enum ace_attribute attr;
- posix_id unix_ug;
+ posix_id unix_ug;
BOOL inherited;
} canon_ace;
@@ -828,20 +828,23 @@ static BOOL nt4_compatible_acls(void)
not get. Deny entries are implicit on get with ace->perms = 0.
****************************************************************************/
-static SEC_ACCESS map_canon_ace_perms(int snum, int *pacl_type, DOM_SID *powner_sid, canon_ace *ace, BOOL directory_ace)
+static SEC_ACCESS map_canon_ace_perms(int snum,
+ int *pacl_type,
+ mode_t perms,
+ BOOL directory_ace)
{
SEC_ACCESS sa;
uint32 nt_mask = 0;
*pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED;
- if (lp_acl_map_full_control(snum) && ((ace->perms & ALL_ACE_PERMS) == ALL_ACE_PERMS)) {
+ if (lp_acl_map_full_control(snum) && ((perms & ALL_ACE_PERMS) == ALL_ACE_PERMS)) {
if (directory_ace) {
nt_mask = UNIX_DIRECTORY_ACCESS_RWX;
} else {
nt_mask = UNIX_ACCESS_RWX;
}
- } else if ((ace->perms & ALL_ACE_PERMS) == (mode_t)0) {
+ } else if ((perms & ALL_ACE_PERMS) == (mode_t)0) {
/*
* Windows NT refuses to display ACEs with no permissions in them (but
* they are perfectly legal with Windows 2000). If the ACE has empty
@@ -857,18 +860,18 @@ static SEC_ACCESS map_canon_ace_perms(int snum, int *pacl_type, DOM_SID *powner_
nt_mask = 0;
} else {
if (directory_ace) {
- nt_mask |= ((ace->perms & S_IRUSR) ? UNIX_DIRECTORY_ACCESS_R : 0 );
- nt_mask |= ((ace->perms & S_IWUSR) ? UNIX_DIRECTORY_ACCESS_W : 0 );
- nt_mask |= ((ace->perms & S_IXUSR) ? UNIX_DIRECTORY_ACCESS_X : 0 );
+ nt_mask |= ((perms & S_IRUSR) ? UNIX_DIRECTORY_ACCESS_R : 0 );
+ nt_mask |= ((perms & S_IWUSR) ? UNIX_DIRECTORY_ACCESS_W : 0 );
+ nt_mask |= ((perms & S_IXUSR) ? UNIX_DIRECTORY_ACCESS_X : 0 );
} else {
- nt_mask |= ((ace->perms & S_IRUSR) ? UNIX_ACCESS_R : 0 );
- nt_mask |= ((ace->perms & S_IWUSR) ? UNIX_ACCESS_W : 0 );
- nt_mask |= ((ace->perms & S_IXUSR) ? UNIX_ACCESS_X : 0 );
+ nt_mask |= ((perms & S_IRUSR) ? UNIX_ACCESS_R : 0 );
+ nt_mask |= ((perms & S_IWUSR) ? UNIX_ACCESS_W : 0 );
+ nt_mask |= ((perms & S_IXUSR) ? UNIX_ACCESS_X : 0 );
}
}
DEBUG(10,("map_canon_ace_perms: Mapped (UNIX) %x to (NT) %x\n",
- (unsigned int)ace->perms, (unsigned int)nt_mask ));
+ (unsigned int)perms, (unsigned int)nt_mask ));
init_sec_access(&sa,nt_mask);
return sa;
@@ -2889,26 +2892,37 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
}
memset(nt_ace_list, '\0', (num_acls + num_def_acls) * sizeof(SEC_ACE) );
-
+
/*
* Create the NT ACE list from the canonical ace lists.
*/
-
+
ace = file_ace;
for (i = 0; i < num_acls; i++, ace = ace->next) {
SEC_ACCESS acc;
- acc = map_canon_ace_perms(SNUM(conn), &nt_acl_type, &owner_sid, ace, fsp->is_directory);
- init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc, ace->inherited ? SEC_ACE_FLAG_INHERITED_ACE : 0);
+ acc = map_canon_ace_perms(SNUM(conn),
+ &nt_acl_type,
+ ace->perms,
+ fsp->is_directory);
+ init_sec_ace(&nt_ace_list[num_aces++],
+ &ace->trustee,
+ nt_acl_type,
+ acc,
+ ace->inherited ?
+ SEC_ACE_FLAG_INHERITED_ACE : 0);
}
- /* The User must have access to a profile share - even if we can't map the SID. */
+ /* The User must have access to a profile share - even
+ * if we can't map the SID. */
if (lp_profile_acls(SNUM(conn))) {
SEC_ACCESS acc;
init_sec_access(&acc,FILE_GENERIC_ALL);
- init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED,
+ init_sec_ace(&nt_ace_list[num_aces++],
+ &global_sid_Builtin_Users,
+ SEC_ACE_TYPE_ACCESS_ALLOWED,
acc, 0);
}
@@ -2916,18 +2930,27 @@ size_t get_nt_acl(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc)
for (i = 0; i < num_def_acls; i++, ace = ace->next) {
SEC_ACCESS acc;
-
- acc = map_canon_ace_perms(SNUM(conn), &nt_acl_type, &owner_sid, ace, fsp->is_directory);
- init_sec_ace(&nt_ace_list[num_aces++], &ace->trustee, nt_acl_type, acc,
- SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
- SEC_ACE_FLAG_INHERIT_ONLY|
- (ace->inherited ? SEC_ACE_FLAG_INHERITED_ACE : 0));
+
+ acc = map_canon_ace_perms(SNUM(conn),
+ &nt_acl_type,
+ ace->perms,
+ fsp->is_directory);
+ init_sec_ace(&nt_ace_list[num_aces++],
+ &ace->trustee,
+ nt_acl_type,
+ acc,
+ SEC_ACE_FLAG_OBJECT_INHERIT|
+ SEC_ACE_FLAG_CONTAINER_INHERIT|
+ SEC_ACE_FLAG_INHERIT_ONLY|
+ (ace->inherited ?
+ SEC_ACE_FLAG_INHERITED_ACE : 0));
}
- /* The User must have access to a profile share - even if we can't map the SID. */
+ /* The User must have access to a profile share - even
+ * if we can't map the SID. */
if (lp_profile_acls(SNUM(conn))) {
SEC_ACCESS acc;
-
+
init_sec_access(&acc,FILE_GENERIC_ALL);
init_sec_ace(&nt_ace_list[num_aces++], &global_sid_Builtin_Users, SEC_ACE_TYPE_ACCESS_ALLOWED, acc,
SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|
@@ -3076,6 +3099,198 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid)
return ret;
}
+static NTSTATUS append_ugw_ace(files_struct *fsp,
+ SMB_STRUCT_STAT *psbuf,
+ mode_t unx_mode,
+ int ugw,
+ SEC_ACE *se)
+{
+ mode_t perms;
+ SEC_ACCESS acc;
+ int acl_type;
+ DOM_SID trustee;
+
+ switch (ugw) {
+ case S_IRUSR:
+ perms = unix_perms_to_acl_perms(unx_mode,
+ S_IRUSR,
+ S_IWUSR,
+ S_IXUSR);
+ uid_to_sid(&trustee, psbuf->st_uid );
+ break;
+ case S_IRGRP:
+ perms = unix_perms_to_acl_perms(unx_mode,
+ S_IRGRP,
+ S_IWGRP,
+ S_IXGRP);
+ gid_to_sid(&trustee, psbuf->st_gid );
+ break;
+ case S_IROTH:
+ perms = unix_perms_to_acl_perms(unx_mode,
+ S_IROTH,
+ S_IWOTH,
+ S_IXOTH);
+ sid_copy(&trustee, &global_sid_World);
+ break;
+ default:
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ acc = map_canon_ace_perms(SNUM(fsp->conn),
+ &acl_type,
+ perms,
+ fsp->is_directory);
+
+ init_sec_ace(se,
+ &trustee,
+ acl_type,
+ acc,
+ 0);
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ If this is an
+****************************************************************************/
+
+static NTSTATUS append_parent_acl(files_struct *fsp,
+ SMB_STRUCT_STAT *psbuf,
+ SEC_DESC *psd,
+ SEC_DESC **pp_new_sd)
+{
+ SEC_DESC *parent_sd = NULL;
+ files_struct *parent_fsp = NULL;
+ TALLOC_CTX *mem_ctx = talloc_parent(psd);
+ char *parent_name = NULL;
+ SEC_ACE *new_ace = NULL;
+ unsigned int num_aces = psd->dacl->num_aces;
+ SMB_STRUCT_STAT sbuf;
+ NTSTATUS status;
+ int info;
+ size_t sd_size;
+ unsigned int i, j;
+ mode_t unx_mode;
+
+ ZERO_STRUCT(sbuf);
+
+ if (mem_ctx == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!parent_dirname_talloc(mem_ctx,
+ fsp->fsp_name,
+ &parent_name,
+ NULL)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* Create a default mode for u/g/w. */
+ unx_mode = unix_mode(fsp->conn,
+ aARCH | (fsp->is_directory ? aDIR : 0),
+ fsp->fsp_name,
+ parent_name);
+
+ status = open_directory(fsp->conn,
+ parent_name,
+ &sbuf,
+ FILE_READ_ATTRIBUTES, /* Just a stat open */
+ FILE_SHARE_NONE, /* Ignored for stat opens */
+ FILE_OPEN,
+ 0,
+ 0,
+ &info,
+ &parent_fsp);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ sd_size = SMB_VFS_GET_NT_ACL(parent_fsp, parent_fsp->fsp_name,
+ DACL_SECURITY_INFORMATION, &parent_sd );
+
+ close_file(parent_fsp, NORMAL_CLOSE);
+
+ if (!sd_size) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /*
+ * Make room for potentially all the ACLs from
+ * the parent, plus the user/group/other triple.
+ */
+
+ num_aces += parent_sd->dacl->num_aces + 3;
+
+ if((new_ace = TALLOC_ZERO_ARRAY(mem_ctx, SEC_ACE,
+ num_aces)) == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ DEBUG(10,("append_parent_acl: parent ACL has %u entries. New "
+ "ACL has %u entries\n",
+ parent_sd->dacl->num_aces, num_aces ));
+
+ /* Start by copying in all the given ACE entries. */
+ for (i = 0; i < psd->dacl->num_aces; i++) {
+ sec_ace_copy(&new_ace[i], &psd->dacl->aces[i]);
+ }
+
+ /*
+ * Note that we're ignoring "inherit permissions" here
+ * as that really only applies to newly created files. JRA.
+ */
+
+ /*
+ * Append u/g/w.
+ */
+
+ status = append_ugw_ace(fsp, psbuf, unx_mode, S_IRUSR, &new_ace[i++]);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ status = append_ugw_ace(fsp, psbuf, unx_mode, S_IRGRP, &new_ace[i++]);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ status = append_ugw_ace(fsp, psbuf, unx_mode, S_IROTH, &new_ace[i++]);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* Finally append any inherited ACEs. */
+ for (j = 0; j < parent_sd->dacl->num_aces; j++) {
+ SEC_ACE *se = &parent_sd->dacl->aces[j];
+ uint32 i_flags = se->flags & (SEC_ACE_FLAG_OBJECT_INHERIT|
+ SEC_ACE_FLAG_CONTAINER_INHERIT|
+ SEC_ACE_FLAG_INHERIT_ONLY);
+
+ if (fsp->is_directory) {
+ if (i_flags == SEC_ACE_FLAG_OBJECT_INHERIT) {
+ /* Should only apply to a file - ignore. */
+ continue;
+ }
+ } else {
+ if ((i_flags & (SEC_ACE_FLAG_OBJECT_INHERIT|
+ SEC_ACE_FLAG_INHERIT_ONLY)) !=
+ SEC_ACE_FLAG_OBJECT_INHERIT) {
+ /* Should not apply to a file - ignore. */
+ continue;
+ }
+ }
+ sec_ace_copy(&new_ace[i], se);
+ if (se->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
+ new_ace[i].flags &= ~(SEC_ACE_FLAG_VALID_INHERIT);
+ }
+ new_ace[i].flags |= SEC_ACE_FLAG_INHERITED_ACE;
+ i++;
+ }
+
+ parent_sd->dacl->aces = new_ace;
+ parent_sd->dacl->num_aces = i;
+
+ *pp_new_sd = parent_sd;
+ return status;
+}
+
/****************************************************************************
Reply to set a security descriptor on an fsp. security_info_sent is the
description of the following NT ACL.
@@ -3087,7 +3302,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
connection_struct *conn = fsp->conn;
uid_t user = (uid_t)-1;
gid_t grp = (gid_t)-1;
- SMB_STRUCT_STAT sbuf;
+ SMB_STRUCT_STAT sbuf;
DOM_SID file_owner_sid;
DOM_SID file_grp_sid;
canon_ace *file_ace_list = NULL;
@@ -3167,12 +3382,12 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
} else {
int ret;
-
+
if(fsp->fh->fd == -1)
ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf);
else
ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf);
-
+
if(ret != 0)
return False;
}
@@ -3188,6 +3403,18 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid);
+ if ((security_info_sent & DACL_SECURITY_INFORMATION) &&
+ psd->dacl != NULL &&
+ (psd->type & (SE_DESC_DACL_AUTO_INHERITED|
+ SE_DESC_DACL_AUTO_INHERIT_REQ))==
+ (SE_DESC_DACL_AUTO_INHERITED|
+ SE_DESC_DACL_AUTO_INHERIT_REQ) ) {
+ NTSTATUS status = append_parent_acl(fsp, &sbuf, psd, &psd);
+ if (!NT_STATUS_IS_OK(status)) {
+ return False;
+ }
+ }
+
acl_perms = unpack_canon_ace( fsp, &sbuf, &file_owner_sid, &file_grp_sid,
&file_ace_list, &dir_ace_list, security_info_sent, psd);
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index 99c3b478e47..55f62a26f7c 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -1321,7 +1321,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
/* We have re-scheduled this call. */
return -1;
}
- return ERROR_NT(status);
+ return ERROR_OPEN(status);
}
size = sbuf.st_size;
@@ -1455,7 +1455,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
/* We have re-scheduled this call. */
return -1;
}
- return ERROR_NT(status);
+ return ERROR_OPEN(status);
}
/* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
@@ -1644,7 +1644,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
/* We have re-scheduled this call. */
return -1;
}
- return ERROR_NT(status);
+ return ERROR_OPEN(status);
}
ts[0] = get_atimespec(&sbuf); /* atime. */
@@ -1746,7 +1746,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
/* We have re-scheduled this call. */
return -1;
}
- return ERROR_NT(status);
+ return ERROR_OPEN(status);
}
outsize = set_message(outbuf,1,0,True);
@@ -2126,6 +2126,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
status = unlink_internals(conn, dirtype, name, path_contains_wcard,
True);
if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBunlink);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
return -1;
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index e5a699047fd..b2ce5b8c26d 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -866,13 +866,13 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
open_attr,
oplock_request,
&smb_action, &fsp);
-
+
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
return -1;
}
- return ERROR_NT(status);
+ return ERROR_OPEN(status);
}
size = get_file_size(sbuf);
@@ -1999,11 +1999,11 @@ static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbu
complain (it thinks we're asking for the directory above the shared
path or an invalid name). Catch this as the resume name is only compared, never used in
a file access. JRA. */
- if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) {
- pstrcpy(resume_name, "..");
- } else if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_OBJECT_NAME_INVALID)) {
- pstrcpy(resume_name, ".");
- } else {
+ srvstr_pull(inbuf, resume_name, params+12,
+ sizeof(resume_name), total_params - 12,
+ STR_TERMINATE);
+
+ if (!(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
return ERROR_NT(ntstatus);
}
}
@@ -4845,17 +4845,24 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
allocation_size = smb_roundup(conn, allocation_size);
}
- if(allocation_size == get_file_size(*psbuf)) {
- return NT_STATUS_OK;
- }
-
DEBUG(10,("smb_set_file_allocation_info: file %s : setting new allocation size to %.0f\n",
fname, (double)allocation_size ));
-
+
if (fsp && fsp->fh->fd != -1) {
/* Open file handle. */
- if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
- return map_nt_error_from_unix(errno);
+ /* Only change if needed. */
+ if (allocation_size != get_file_size(*psbuf)) {
+ if (vfs_allocate_file_space(fsp, allocation_size) == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+ }
+ /* But always update the time. */
+ if (null_timespec(fsp->pending_modtime)) {
+ /*
+ * This is equivalent to a write. Ensure it's seen immediately
+ * if there are no pending writes.
+ */
+ set_filetime(fsp->conn, fsp->fsp_name, timespec_current());
}
return NT_STATUS_OK;
}
@@ -4870,17 +4877,27 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn,
FILE_ATTRIBUTE_NORMAL,
FORCE_OPLOCK_BREAK_TO_NONE,
NULL, &new_fsp);
-
+
if (!NT_STATUS_IS_OK(status)) {
/* NB. We check for open_was_deferred in the caller. */
return status;
}
- if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
- status = map_nt_error_from_unix(errno);
- close_file(new_fsp,NORMAL_CLOSE);
- return status;
+
+ /* Only change if needed. */
+ if (allocation_size != get_file_size(*psbuf)) {
+ if (vfs_allocate_file_space(new_fsp, allocation_size) == -1) {
+ status = map_nt_error_from_unix(errno);
+ close_file(new_fsp,NORMAL_CLOSE);
+ return status;
+ }
}
+ /* Changing the allocation size should set the last mod time. */
+ /* Don't need to call set_filetime as this will be flushed on
+ * close. */
+
+ fsp_set_pending_modtime(new_fsp, timespec_current());
+
close_file(new_fsp,NORMAL_CLOSE);
return NT_STATUS_OK;
}
@@ -5525,7 +5542,10 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
NTSTATUS status = NT_STATUS_OK;
files_struct *fsp = NULL;
uint16 flags = 0;
+ char del = 1;
int info = 0;
+ int i;
+ struct share_mode_lock *lck = NULL;
if (total_data < 2) {
return NT_STATUS_INVALID_PARAMETER;
@@ -5553,12 +5573,11 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
DELETE_ACCESS,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN,
- FILE_DELETE_ON_CLOSE,
+ 0,
FILE_FLAG_POSIX_SEMANTICS|0777,
- &info,
+ &info,
&fsp);
} else {
- char del = 1;
status = open_file_ntcreate(conn,
fname,
@@ -5571,26 +5590,59 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn,
0, /* No oplock, but break existing ones. */
&info,
&fsp);
- /*
- * For file opens we must set the delete on close
- * after the open.
- */
+ }
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
- status = smb_set_file_disposition_info(conn,
- &del,
- 1,
- fsp,
- fname,
- psbuf);
+ /*
+ * Don't lie to client. If we can't really delete due to
+ * non-POSIX opens return SHARING_VIOLATION.
+ */
+
+ lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
+ if (lck == NULL) {
+ DEBUG(0, ("smb_posix_unlink: Could not get share mode "
+ "lock for file %s\n", fsp->fsp_name));
+ close_file(fsp, NORMAL_CLOSE);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /*
+ * See if others still have the file open. If this is the case, then
+ * don't delete. If all opens are POSIX delete we can set the delete
+ * on close disposition.
+ */
+ for (i=0; i<lck->num_share_modes; i++) {
+ struct share_mode_entry *e = &lck->share_modes[i];
+ if (is_valid_share_mode_entry(e)) {
+ if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
+ continue;
+ }
+ /* Fail with sharing violation. */
+ close_file(fsp, NORMAL_CLOSE);
+ TALLOC_FREE(lck);
+ return NT_STATUS_SHARING_VIOLATION;
+ }
}
+ /*
+ * Set the delete on close.
+ */
+ status = smb_set_file_disposition_info(conn,
+ &del,
+ 1,
+ fsp,
+ fname,
+ psbuf);
+
if (!NT_STATUS_IS_OK(status)) {
+ close_file(fsp, NORMAL_CLOSE);
+ TALLOC_FREE(lck);
return status;
}
+ TALLOC_FREE(lck);
return close_file(fsp, NORMAL_CLOSE);
}
@@ -5986,6 +6038,9 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
}
+ if (info_level == SMB_POSIX_PATH_OPEN) {
+ return ERROR_OPEN(status);
+ }
return ERROR_NT(status);
}
diff --git a/source/tdb/common/io.c b/source/tdb/common/io.c
index 9a8e270dcc6..cccc9ecc1a6 100644
--- a/source/tdb/common/io.c
+++ b/source/tdb/common/io.c
@@ -221,7 +221,16 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad
if (ftruncate(tdb->fd, size+addition) == -1) {
char b = 0;
- if (pwrite(tdb->fd, &b, 1, (size+addition) - 1) != 1) {
+ ssize_t written = pwrite(tdb->fd, &b, 1, (size+addition) - 1);
+ if (written == 0) {
+ /* try once more, potentially revealing errno */
+ written = pwrite(tdb->fd, &b, 1, (size+addition) - 1);
+ }
+ if (written == 0) {
+ /* again - give up, guessing errno */
+ errno = ENOSPC;
+ }
+ if (written != 1) {
TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file to %d failed (%s)\n",
size+addition, strerror(errno)));
return -1;
@@ -233,15 +242,28 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad
disk. This must be done with write, not via mmap */
memset(buf, TDB_PAD_BYTE, sizeof(buf));
while (addition) {
- int n = addition>sizeof(buf)?sizeof(buf):addition;
- int ret = pwrite(tdb->fd, buf, n, size);
- if (ret != n) {
- TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of %d failed (%s)\n",
- n, strerror(errno)));
+ size_t n = addition>sizeof(buf)?sizeof(buf):addition;
+ ssize_t written = pwrite(tdb->fd, buf, n, size);
+ if (written == 0) {
+ /* prevent infinite loops: try _once_ more */
+ written = pwrite(tdb->fd, buf, n, size);
+ }
+ if (written == 0) {
+ /* give up, trying to provide a useful errno */
+ TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write "
+ "returned 0 twice: giving up!\n"));
+ errno = ENOSPC;
+ return -1;
+ } else if (written == -1) {
+ TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of "
+ "%d bytes failed (%s)\n", n, strerror(errno)));
return -1;
+ } else if (written != n) {
+ TDB_LOG((tdb, TDB_DEBUG_WARNING, "expand_file: wrote "
+ "only %d of %d bytes - retrying\n", written,n));
}
- addition -= n;
- size += n;
+ addition -= written;
+ size += written;
}
return 0;
}
diff --git a/source/tdb/common/open.c b/source/tdb/common/open.c
index c7fd3f66564..402352d3af2 100644
--- a/source/tdb/common/open.c
+++ b/source/tdb/common/open.c
@@ -50,7 +50,9 @@ static unsigned int default_tdb_hash(TDB_DATA *key)
static int tdb_new_database(struct tdb_context *tdb, int hash_size)
{
struct tdb_header *newdb;
- int size, ret = -1;
+ size_t size;
+ int ret = -1;
+ ssize_t written;
/* We make it up in memory, then write it out if not internal */
size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off_t);
@@ -79,10 +81,22 @@ static int tdb_new_database(struct tdb_context *tdb, int hash_size)
memcpy(&tdb->header, newdb, sizeof(tdb->header));
/* Don't endian-convert the magic food! */
memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
- if (write(tdb->fd, newdb, size) != size) {
- ret = -1;
- } else {
+ /* we still have "ret == -1" here */
+ written = write(tdb->fd, newdb, size);
+ if (written == size) {
ret = 0;
+ } else if (written != -1) {
+ /* call write once again, this usually should return -1 and
+ * set errno appropriately */
+ size -= written;
+ written = write(tdb->fd, newdb+written, size);
+ if (written == size) {
+ ret = 0;
+ } else if (written >= 0) {
+ /* a second incomplete write - we give up.
+ * guessing the errno... */
+ errno = ENOSPC;
+ }
}
fail:
@@ -217,13 +231,16 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
}
}
+ errno = 0;
if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header)
|| strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0
|| (tdb->header.version != TDB_VERSION
&& !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) {
/* its not a valid database - possibly initialise it */
if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) {
- errno = EIO; /* ie bad format or something */
+ if (errno == 0) {
+ errno = EIO; /* ie bad format or something */
+ }
goto fail;
}
rev = (tdb->flags & TDB_CONVERT);
diff --git a/source/tdb/common/tdb.c b/source/tdb/common/tdb.c
index bf43701d2ed..3e8358b00d2 100644
--- a/source/tdb/common/tdb.c
+++ b/source/tdb/common/tdb.c
@@ -566,8 +566,12 @@ int tdb_append(struct tdb_context *tdb, TDB_DATA key, TDB_DATA new_dbuf)
if (dbuf.dptr == NULL) {
dbuf.dptr = (char *)malloc(new_dbuf.dsize);
} else {
- dbuf.dptr = (char *)realloc(dbuf.dptr,
+ char *new_dptr = (char *)realloc(dbuf.dptr,
dbuf.dsize + new_dbuf.dsize);
+ if (new_dptr == NULL) {
+ free(dbuf.dptr);
+ }
+ dbuf.dptr = new_dptr;
}
if (dbuf.dptr == NULL) {
diff --git a/source/tdb/common/tdbback.c b/source/tdb/common/tdbback.c
index 28de85c29f8..1339bd22172 100644
--- a/source/tdb/common/tdbback.c
+++ b/source/tdb/common/tdbback.c
@@ -77,7 +77,7 @@ static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state;
if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) {
- fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb));
+ fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb_new));
failed = 1;
return 1;
}
diff --git a/source/torture/locktest.c b/source/torture/locktest.c
index d248a9459db..ff14b803a73 100644
--- a/source/torture/locktest.c
+++ b/source/torture/locktest.c
@@ -165,6 +165,7 @@ static struct cli_state *connect_one(char *share, int snum)
struct in_addr ip;
fstring myname;
static int count;
+ NTSTATUS status;
fstrcpy(server,share+2);
share = strchr_m(server,'\\');
@@ -185,11 +186,17 @@ static struct cli_state *connect_one(char *share, int snum)
zero_ip(&ip);
/* have to open a new connection */
- if (!(c=cli_initialise()) || !cli_connect(c, server_n, &ip)) {
+ if (!(c=cli_initialise())) {
DEBUG(0,("Connection to %s failed\n", server_n));
return NULL;
}
+ status = cli_connect(c, server_n, &ip);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Connection to %s failed. Error %s\n", server_n, nt_errstr(status) ));
+ return NULL;
+ }
+
c->use_kerberos = use_kerberos;
if (!cli_session_request(c, &calling, &called)) {
diff --git a/source/torture/masktest.c b/source/torture/masktest.c
index 0d6c0b16f28..e98cf81f333 100644
--- a/source/torture/masktest.c
+++ b/source/torture/masktest.c
@@ -170,6 +170,7 @@ static struct cli_state *connect_one(char *share)
char *server_n;
char *server;
struct in_addr ip;
+ NTSTATUS status;
server = share+2;
share = strchr_m(server,'\\');
@@ -188,11 +189,17 @@ static struct cli_state *connect_one(char *share)
zero_ip(&ip);
/* have to open a new connection */
- if (!(c=cli_initialise()) || !cli_connect(c, server_n, &ip)) {
+ if (!(c=cli_initialise())) {
DEBUG(0,("Connection to %s failed\n", server_n));
return NULL;
}
+ status = cli_connect(c, server_n, &ip);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Connection to %s failed. Error %s\n", server_n, nt_errstr(status) ));
+ return NULL;
+ }
+
c->protocol = max_protocol;
if (!cli_session_request(c, &calling, &called)) {
diff --git a/source/torture/torture.c b/source/torture/torture.c
index 925cac3f32c..8ca2eb58981 100644
--- a/source/torture/torture.c
+++ b/source/torture/torture.c
@@ -102,6 +102,7 @@ static struct cli_state *open_nbt_connection(void)
struct nmb_name called, calling;
struct in_addr ip;
struct cli_state *c;
+ NTSTATUS status;
make_nmb_name(&calling, myname, 0x0);
make_nmb_name(&called , host, 0x20);
@@ -115,8 +116,9 @@ static struct cli_state *open_nbt_connection(void)
c->port = port_to_use;
- if (!cli_connect(c, host, &ip)) {
- printf("Failed to connect with %s\n", host);
+ status = cli_connect(c, host, &ip);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
return NULL;
}
@@ -131,8 +133,9 @@ static struct cli_state *open_nbt_connection(void)
* Well, that failed, try *SMBSERVER ...
* However, we must reconnect as well ...
*/
- if (!cli_connect(c, host, &ip)) {
- printf("Failed to connect with %s\n", host);
+ status = cli_connect(c, host, &ip);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
return NULL;
}
diff --git a/source/utils/net.c b/source/utils/net.c
index 7b97476a25e..a030531947a 100644
--- a/source/utils/net.c
+++ b/source/utils/net.c
@@ -999,6 +999,10 @@ static struct functable net_func[] = {
opt_user_name = getenv("LOGNAME");
}
+ if (!opt_user_name) {
+ opt_user_name = "";
+ }
+
if (!opt_workgroup) {
opt_workgroup = smb_xstrdup(lp_workgroup());
}
diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c
index 52af6e68d77..75b631c351f 100644
--- a/source/utils/net_ads.c
+++ b/source/utils/net_ads.c
@@ -1720,7 +1720,7 @@ static int net_ads_dns_register(int argc, const char **argv)
#endif
if (argc > 0) {
- d_fprintf(stderr, "net ads dns register <name> <ip>\n");
+ d_fprintf(stderr, "net ads dns register\n");
return -1;
}
diff --git a/source/utils/net_rpc.c b/source/utils/net_rpc.c
index c300a7171ce..fee994b7519 100644
--- a/source/utils/net_rpc.c
+++ b/source/utils/net_rpc.c
@@ -6314,6 +6314,7 @@ BOOL net_rpc_check(unsigned flags)
BOOL ret = False;
struct in_addr server_ip;
char *server_name = NULL;
+ NTSTATUS status;
/* flags (i.e. server type) may depend on command */
if (!net_find_server(NULL, flags, &server_ip, &server_name))
@@ -6323,7 +6324,8 @@ BOOL net_rpc_check(unsigned flags)
return False;
}
- if (!cli_connect(cli, server_name, &server_ip))
+ status = cli_connect(cli, server_name, &server_ip);
+ if (!NT_STATUS_IS_OK(status))
goto done;
if (!attempt_netbios_session_request(&cli, global_myname(),
server_name, &server_ip))
diff --git a/source/utils/net_time.c b/source/utils/net_time.c
index f6269627dab..5e952780d32 100644
--- a/source/utils/net_time.c
+++ b/source/utils/net_time.c
@@ -29,14 +29,16 @@ static time_t cli_servertime(const char *host, struct in_addr *ip, int *zone)
struct nmb_name calling, called;
time_t ret = 0;
struct cli_state *cli = NULL;
+ NTSTATUS status;
cli = cli_initialise();
if (!cli) {
goto done;
}
- if (!cli_connect(cli, host, ip)) {
- fprintf(stderr,"Can't contact server\n");
+ status = cli_connect(cli, host, ip);
+ if (!NT_STATUS_IS_OK(status)) {
+ fprintf(stderr,"Can't contact server %s. Error %s\n", host, nt_errstr(status));
goto done;
}
diff --git a/source/web/diagnose.c b/source/web/diagnose.c
index b53e139ca94..5f05d8ac9e9 100644
--- a/source/web/diagnose.c
+++ b/source/web/diagnose.c
@@ -60,12 +60,14 @@ BOOL nmbd_running(void)
then closing it */
BOOL smbd_running(void)
{
+ NTSTATUS status;
struct cli_state *cli;
if ((cli = cli_initialise()) == NULL)
return False;
- if (!cli_connect(cli, global_myname(), &loopback_ip)) {
+ status = cli_connect(cli, global_myname(), &loopback_ip);
+ if (!NT_STATUS_IS_OK(status)) {
cli_shutdown(cli);
return False;
}