summaryrefslogtreecommitdiffstats
path: root/source/libsmb
diff options
context:
space:
mode:
Diffstat (limited to 'source/libsmb')
-rw-r--r--source/libsmb/clifile.c137
-rw-r--r--source/libsmb/clireadwrite.c8
-rw-r--r--source/libsmb/clisecdesc.c3
-rw-r--r--source/libsmb/doserr.c1
-rw-r--r--source/libsmb/libsmb_cache.c2
-rw-r--r--source/libsmb/libsmb_compat.c2
-rw-r--r--source/libsmb/libsmbclient.c3
-rw-r--r--source/libsmb/namequery.c39
-rw-r--r--source/libsmb/ntlm_check.c2
9 files changed, 175 insertions, 22 deletions
diff --git a/source/libsmb/clifile.c b/source/libsmb/clifile.c
index ff0edc6bb4e..144fc4a0c85 100644
--- a/source/libsmb/clifile.c
+++ b/source/libsmb/clifile.c
@@ -77,7 +77,7 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *oldname, const
Map standard UNIX permissions onto wire representations.
****************************************************************************/
-uint32 unix_perms_to_wire(mode_t perms)
+uint32 unix_perms_to_wire(mode_t perms)
{
unsigned int ret = 0;
@@ -103,6 +103,141 @@ uint32 unix_perms_to_wire(mode_t perms)
}
/****************************************************************************
+ Map wire permissions to standard UNIX.
+****************************************************************************/
+
+mode_t wire_perms_to_unix(uint32 perms)
+{
+ mode_t ret = (mode_t)0;
+
+ ret |= ((perms & UNIX_X_OTH) ? S_IXOTH : 0);
+ ret |= ((perms & UNIX_W_OTH) ? S_IWOTH : 0);
+ ret |= ((perms & UNIX_R_OTH) ? S_IROTH : 0);
+ ret |= ((perms & UNIX_X_GRP) ? S_IXGRP : 0);
+ ret |= ((perms & UNIX_W_GRP) ? S_IWGRP : 0);
+ ret |= ((perms & UNIX_R_GRP) ? S_IRGRP : 0);
+ ret |= ((perms & UNIX_X_USR) ? S_IXUSR : 0);
+ ret |= ((perms & UNIX_W_USR) ? S_IWUSR : 0);
+ ret |= ((perms & UNIX_R_USR) ? S_IRUSR : 0);
+#ifdef S_ISVTX
+ ret |= ((perms & UNIX_STICKY) ? S_ISVTX : 0);
+#endif
+#ifdef S_ISGID
+ ret |= ((perms & UNIX_SET_GID) ? S_ISGID : 0);
+#endif
+#ifdef S_ISUID
+ ret |= ((perms & UNIX_SET_UID) ? S_ISUID : 0);
+#endif
+ return ret;
+}
+
+/****************************************************************************
+ Return the file type from the wire filetype for UNIX extensions.
+****************************************************************************/
+
+static mode_t unix_filetype_from_wire(uint32 wire_type)
+{
+ switch (wire_type) {
+ case UNIX_TYPE_FILE:
+ return S_IFREG;
+ case UNIX_TYPE_DIR:
+ return S_IFDIR;
+#ifdef S_IFLNK
+ case UNIX_TYPE_SYMLINK:
+ return S_IFLNK;
+#endif
+#ifdef S_IFCHR
+ case UNIX_TYPE_CHARDEV:
+ return S_IFCHR;
+#endif
+#ifdef S_IFBLK
+ case UNIX_TYPE_BLKDEV:
+ return S_IFBLK;
+#endif
+#ifdef S_IFIFO
+ case UNIX_TYPE_FIFO:
+ return S_IFIFO;
+#endif
+#ifdef S_IFSOCK
+ case UNIX_TYPE_SOCKET:
+ return S_IFSOCK;
+#endif
+ default:
+ return (mode_t)0;
+ }
+}
+
+/****************************************************************************
+ Stat a file (UNIX extensions).
+****************************************************************************/
+
+BOOL cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf)
+{
+ unsigned int param_len = 0;
+ unsigned int data_len = 0;
+ uint16 setup = TRANSACT2_QPATHINFO;
+ char param[sizeof(pstring)+6];
+ char *rparam=NULL, *rdata=NULL;
+ char *p;
+
+ ZERO_STRUCTP(sbuf);
+
+ p = param;
+ memset(p, 0, 6);
+ SSVAL(p, 0, SMB_QUERY_FILE_UNIX_BASIC);
+ p += 6;
+ p += clistr_push(cli, p, name, sizeof(pstring)-6, STR_TERMINATE);
+ param_len = PTR_DIFF(p, param);
+
+ if (!cli_send_trans(cli, SMBtrans2,
+ NULL, /* name */
+ -1, 0, /* fid, flags */
+ &setup, 1, 0, /* setup, length, max */
+ param, param_len, 2, /* param, length, max */
+ NULL, 0, cli->max_xmit /* data, length, max */
+ )) {
+ return False;
+ }
+
+ if (!cli_receive_trans(cli, SMBtrans2,
+ &rparam, &param_len,
+ &rdata, &data_len)) {
+ return False;
+ }
+
+ if (data_len < 96) {
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
+ return False;
+ }
+
+ sbuf->st_size = IVAL2_TO_SMB_BIG_UINT(rdata,0); /* total size, in bytes */
+ sbuf->st_blocks = IVAL2_TO_SMB_BIG_UINT(rdata,8); /* number of blocks allocated */
+ sbuf->st_blocks /= STAT_ST_BLOCKSIZE;
+ sbuf->st_ctime = interpret_long_date(rdata + 16); /* time of last change */
+ sbuf->st_atime = interpret_long_date(rdata + 24); /* time of last access */
+ sbuf->st_mtime = interpret_long_date(rdata + 32); /* time of last modification */
+ sbuf->st_uid = IVAL(rdata,40); /* user ID of owner */
+ sbuf->st_gid = IVAL(rdata,48); /* group ID of owner */
+ sbuf->st_mode |= unix_filetype_from_wire(IVAL(rdata, 56));
+#if defined(HAVE_MAKEDEV)
+ {
+ uint32 dev_major = IVAL(rdata,60);
+ uint32 dev_minor = IVAL(rdata,68);
+ sbuf->st_rdev = makedev(dev_major, dev_minor);
+ }
+#endif
+ sbuf->st_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(rdata,76); /* inode */
+ sbuf->st_mode |= wire_perms_to_unix(IVAL(rdata,84)); /* protection */
+ sbuf->st_nlink = IVAL(rdata,92); /* number of hard links */
+
+ SAFE_FREE(rdata);
+ SAFE_FREE(rparam);
+
+ return True;
+}
+
+/****************************************************************************
Symlink a file (UNIX extensions).
****************************************************************************/
diff --git a/source/libsmb/clireadwrite.c b/source/libsmb/clireadwrite.c
index 3f14e530943..d1a23d36c8b 100644
--- a/source/libsmb/clireadwrite.c
+++ b/source/libsmb/clireadwrite.c
@@ -318,9 +318,9 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset,
0x0008 start of message mode named pipe protocol
****************************************************************************/
-ssize_t cli_write(struct cli_state *cli,
- int fnum, uint16 write_mode,
- const char *buf, off_t offset, size_t size)
+size_t cli_write(struct cli_state *cli,
+ int fnum, uint16 write_mode,
+ const char *buf, off_t offset, size_t size)
{
int bwritten = 0;
int issued = 0;
@@ -358,7 +358,7 @@ ssize_t cli_write(struct cli_state *cli,
break;
bwritten += SVAL(cli->inbuf, smb_vwv2);
- bwritten += (((int)(SVAL(cli->inbuf, smb_vwv4)))>>16);
+ bwritten += (((int)(SVAL(cli->inbuf, smb_vwv4)))<<16);
}
while (received < issued && cli_receive_smb(cli))
diff --git a/source/libsmb/clisecdesc.c b/source/libsmb/clisecdesc.c
index 2989966f4de..b79ea9d14ba 100644
--- a/source/libsmb/clisecdesc.c
+++ b/source/libsmb/clisecdesc.c
@@ -53,6 +53,9 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum,
goto cleanup;
}
+ if (cli_is_error(cli))
+ goto cleanup;
+
prs_init(&pd, rdata_count, mem_ctx, UNMARSHALL);
prs_copy_data_in(&pd, rdata, rdata_count);
prs_set_offset(&pd,0);
diff --git a/source/libsmb/doserr.c b/source/libsmb/doserr.c
index c6348568cf9..96c052c7c56 100644
--- a/source/libsmb/doserr.c
+++ b/source/libsmb/doserr.c
@@ -68,6 +68,7 @@ werror_code_struct dos_errs[] =
{ "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR },
{ "WERR_INVALID_OWNER", WERR_INVALID_OWNER },
{ "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE },
+ { "WERR_IO_PENDING", WERR_IO_PENDING },
{ NULL, W_ERROR(0) }
};
diff --git a/source/libsmb/libsmb_cache.c b/source/libsmb/libsmb_cache.c
index cb40b4aaa6b..caf226c5a6a 100644
--- a/source/libsmb/libsmb_cache.c
+++ b/source/libsmb/libsmb_cache.c
@@ -27,7 +27,7 @@
* Define this to get the real SMBCFILE and SMBCSRV structures
*/
#define _SMBC_INTERNAL
-#include "../include/libsmbclient.h"
+#include "include/libsmbclient.h"
/*
* Structure we use if internal caching mechanism is used
diff --git a/source/libsmb/libsmb_compat.c b/source/libsmb/libsmb_compat.c
index cc23835ae3d..c4be848cc17 100644
--- a/source/libsmb/libsmb_compat.c
+++ b/source/libsmb/libsmb_compat.c
@@ -25,7 +25,7 @@
#include "includes.h"
-#include "../include/libsmb_internal.h"
+#include "include/libsmb_internal.h"
struct smbc_compat_fdlist {
SMBCFILE * file;
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index e44bdea2d3d..2b0115eaaa4 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -24,7 +24,7 @@
#include "includes.h"
-#include "../include/libsmb_internal.h"
+#include "include/libsmb_internal.h"
/*
* Internal flags for extended attributes
@@ -596,6 +596,7 @@ SMBCSRV *smbc_server(SMBCCTX *context,
*/
c.port = 445;
if (!cli_connect(&c, server_n, &ip)) {
+ cli_shutdown(&c);
errno = ENETUNREACH;
return NULL;
}
diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c
index cee0015e257..2e6842088a4 100644
--- a/source/libsmb/namequery.c
+++ b/source/libsmb/namequery.c
@@ -855,22 +855,35 @@ static BOOL resolve_lmhosts(const char *name, int name_type,
fp = startlmhosts(dyn_LMHOSTSFILE);
if(fp) {
- while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
- if (strequal(name, lmhost_name) &&
- ((name_type2 == -1) || (name_type == name_type2))
- ) {
- endlmhosts(fp);
- if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) {
- DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
- return False;
- }
- (*return_iplist)[0].ip = return_ip;
- (*return_iplist)[0].port = PORT_NONE;
- *return_count = 1;
- return True;
+ while (getlmhostsent(fp, lmhost_name, &name_type2,
+ &return_ip)) {
+
+ if (!strequal(name, lmhost_name))
+ continue;
+
+ if ((name_type2 != -1) && (name_type != name_type2))
+ continue;
+
+ *return_iplist = (struct ip_service *)
+ realloc((*return_iplist),
+ sizeof(struct ip_service) *
+ ((*return_count)+1));
+
+ if ((*return_iplist) == NULL) {
+ DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
+ return False;
}
+
+ (*return_iplist)[*return_count].ip = return_ip;
+ (*return_iplist)[*return_count].port = PORT_NONE;
+ *return_count += 1;
+
+ /* Multiple names only for DC lookup */
+ if (name_type != 0x1c)
+ break;
}
endlmhosts(fp);
+ return True;
}
return False;
}
diff --git a/source/libsmb/ntlm_check.c b/source/libsmb/ntlm_check.c
index 1d02b03e0c3..a0ca08fb891 100644
--- a/source/libsmb/ntlm_check.c
+++ b/source/libsmb/ntlm_check.c
@@ -63,7 +63,7 @@ static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response,
}
-#if DEBUG_PASSWORD
+#ifdef DEBUG_PASSWORD
DEBUG(100,("Part password (P16) was |\n"));
dump_data(100, part_passwd, 16);
DEBUGADD(100,("Password from client was |\n"));