summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2006-08-29 16:01:18 +0000
committerGerald Carter <jerry@samba.org>2006-08-29 16:01:18 +0000
commit43328fbd2ec7062be792f5eca188364a904ec240 (patch)
tree3a0940a5ca2fe05f1b025dd52efb3077f37e1724 /source
parent7d7b83d9978e85253e67818979dd3a57ec9bbc7d (diff)
downloadsamba-43328fbd2ec7062be792f5eca188364a904ec240.tar.gz
samba-43328fbd2ec7062be792f5eca188364a904ec240.tar.xz
samba-43328fbd2ec7062be792f5eca188364a904ec240.zip
r17912: * mssed DNS SRV fix
* internal_resolve_name() fix * time fixes * NULL deref fixes
Diffstat (limited to 'source')
-rw-r--r--source/libsmb/clierror.c9
-rw-r--r--source/libsmb/clifile.c4
-rw-r--r--source/libsmb/clilist.c18
-rw-r--r--source/libsmb/clirap.c47
-rw-r--r--source/libsmb/libsmbclient.c4
-rw-r--r--source/libsmb/namecache.c4
-rw-r--r--source/libsmb/namequery.c182
7 files changed, 139 insertions, 129 deletions
diff --git a/source/libsmb/clierror.c b/source/libsmb/clierror.c
index b84a8ee70f8..44573bd29b1 100644
--- a/source/libsmb/clierror.c
+++ b/source/libsmb/clierror.c
@@ -201,8 +201,6 @@ NTSTATUS cli_nt_error(struct cli_state *cli)
void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode)
{
int flgs2;
- char rcls;
- int code;
if(!cli->initialised) {
return;
@@ -223,11 +221,8 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode)
return;
}
- rcls = CVAL(cli->inbuf,smb_rcls);
- code = SVAL(cli->inbuf,smb_err);
-
- if (eclass) *eclass = rcls;
- if (ecode) *ecode = code;
+ *eclass = CVAL(cli->inbuf,smb_rcls);
+ *ecode = SVAL(cli->inbuf,smb_err);
}
/* Return a UNIX errno from a NT status code */
diff --git a/source/libsmb/clifile.c b/source/libsmb/clifile.c
index 46ff8af6d5c..ea6501dac89 100644
--- a/source/libsmb/clifile.c
+++ b/source/libsmb/clifile.c
@@ -1612,7 +1612,9 @@ static BOOL cli_get_ea_list(struct cli_state *cli,
struct ea_struct *ea_list;
*pnum_eas = 0;
- *pea_list = NULL;
+ if (pea_list) {
+ *pea_list = NULL;
+ }
if (!cli_send_trans(cli, SMBtrans2,
NULL, /* Name */
diff --git a/source/libsmb/clilist.c b/source/libsmb/clilist.c
index e18bb185d56..536bed5f787 100644
--- a/source/libsmb/clilist.c
+++ b/source/libsmb/clilist.c
@@ -94,27 +94,13 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f
}
p += 4; /* fileindex */
- /* these dates appear to arrive in a
- weird way. It seems to be localtime
- plus the serverzone given in the
- initial connect. This is GMT when
- DST is not in effect and one hour
- from GMT otherwise. Can this really
- be right??
-
- I suppose this could be called
- kludge-GMT. Is is the GMT you get
- by using the current DST setting on
- a different localtime. It will be
- cheap to calculate, I suppose, as
- no DST tables will be needed */
-
- finfo->ctime = interpret_long_date(p);
+ /* Offset zero is "create time", not "change time". */
p += 8;
finfo->atime = interpret_long_date(p);
p += 8;
finfo->mtime = interpret_long_date(p);
p += 8;
+ finfo->ctime = interpret_long_date(p);
p += 8;
finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0);
p += 8;
diff --git a/source/libsmb/clirap.c b/source/libsmb/clirap.c
index 58fa9c8dfff..2be4da8f7fd 100644
--- a/source/libsmb/clirap.c
+++ b/source/libsmb/clirap.c
@@ -553,9 +553,10 @@ BOOL cli_setpathinfo(struct cli_state *cli, const char *fname,
/****************************************************************************
send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level
****************************************************************************/
+
BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
- time_t *c_time, time_t *a_time, time_t *m_time,
- time_t *w_time, SMB_OFF_T *size, uint16 *mode,
+ time_t *create_time, time_t *access_time, time_t *write_time,
+ time_t *change_time, SMB_OFF_T *size, uint16 *mode,
SMB_INO_T *ino)
{
unsigned int data_len = 0;
@@ -593,17 +594,17 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
return False;
}
- if (c_time) {
- *c_time = interpret_long_date(rdata+0);
+ if (create_time) {
+ *create_time = interpret_long_date(rdata+0);
}
- if (a_time) {
- *a_time = interpret_long_date(rdata+8);
+ if (access_time) {
+ *access_time = interpret_long_date(rdata+8);
}
- if (w_time) {
- *w_time = interpret_long_date(rdata+16);
+ if (write_time) {
+ *write_time = interpret_long_date(rdata+16);
}
- if (m_time) {
- *m_time = interpret_long_date(rdata+24);
+ if (change_time) {
+ *change_time = interpret_long_date(rdata+24);
}
if (mode) {
*mode = SVAL(rdata, 32);
@@ -669,8 +670,8 @@ send a qfileinfo call
****************************************************************************/
BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
uint16 *mode, SMB_OFF_T *size,
- time_t *c_time, time_t *a_time, time_t *m_time,
- time_t *w_time, SMB_INO_T *ino)
+ time_t *create_time, time_t *access_time, time_t *write_time,
+ time_t *change_time, SMB_INO_T *ino)
{
unsigned int data_len = 0;
unsigned int param_len = 0;
@@ -708,17 +709,17 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
return False;
}
- if (c_time) {
- *c_time = interpret_long_date(rdata+0) - cli->serverzone;
+ if (create_time) {
+ *create_time = interpret_long_date(rdata+0);
}
- if (a_time) {
- *a_time = interpret_long_date(rdata+8) - cli->serverzone;
+ if (access_time) {
+ *access_time = interpret_long_date(rdata+8);
}
- if (m_time) {
- *m_time = interpret_long_date(rdata+16) - cli->serverzone;
+ if (write_time) {
+ *write_time = interpret_long_date(rdata+16);
}
- if (w_time) {
- *w_time = interpret_long_date(rdata+24) - cli->serverzone;
+ if (change_time) {
+ *change_time = interpret_long_date(rdata+24);
}
if (mode) {
*mode = SVAL(rdata, 32);
@@ -793,9 +794,9 @@ BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name,
return False;
}
- sbuf->st_atime = interpret_long_date( rdata+8 );
- sbuf->st_mtime = interpret_long_date( rdata+16 );
- sbuf->st_ctime = interpret_long_date( rdata+24 );
+ sbuf->st_atime = interpret_long_date( rdata+8 ); /* Access time. */
+ sbuf->st_mtime = interpret_long_date( rdata+16 ); /* Write time. */
+ sbuf->st_ctime = interpret_long_date( rdata+24 ); /* Change time. */
*attributes = IVAL( rdata, 32 );
diff --git a/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c
index 98264dfa862..caa26a70a80 100644
--- a/source/libsmb/libsmbclient.c
+++ b/source/libsmb/libsmbclient.c
@@ -1516,7 +1516,7 @@ smbc_getatr(SMBCCTX * context,
if (!srv->no_pathinfo2 &&
cli_qpathinfo2(targetcli, targetpath,
- c_time, a_time, m_time, NULL, size, mode, ino)) {
+ NULL, a_time, m_time, c_time, size, mode, ino)) {
return True;
}
@@ -2184,7 +2184,7 @@ smbc_fstat_ctx(SMBCCTX *context,
/*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/
if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size,
- &c_time, &a_time, &m_time, NULL, &ino)) {
+ NULL, &a_time, &m_time, &c_time, &ino)) {
if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size,
&c_time, &a_time, &m_time)) {
diff --git a/source/libsmb/namecache.c b/source/libsmb/namecache.c
index e3e7ac4e3c2..ec8a1900d87 100644
--- a/source/libsmb/namecache.c
+++ b/source/libsmb/namecache.c
@@ -178,14 +178,14 @@ BOOL namecache_fetch(const char *name, int name_type, struct ip_service **ip_lis
char *key, *value;
time_t timeout;
- *num_names = 0;
-
/* exit now if null pointers were passed as they're required further */
if (!ip_list || !num_names) return False;
if (!gencache_init())
return False;
+ *num_names = 0;
+
/*
* Use gencache interface - lookup the key
*/
diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c
index f6dbe3c5483..57a74ea3c3e 100644
--- a/source/libsmb/namequery.c
+++ b/source/libsmb/namequery.c
@@ -1024,11 +1024,12 @@ static BOOL resolve_hosts(const char *name, int name_type,
static BOOL resolve_ads(const char *name, int name_type,
struct ip_service **return_iplist, int *return_count)
{
- int i = 0;
+ int i, j;
NTSTATUS status;
TALLOC_CTX *ctx;
struct dns_rr_srv *dcs = NULL;
int numdcs = 0;
+ int numaddrs = 0;
if ( name_type != 0x1c )
return False;
@@ -1045,24 +1046,44 @@ static BOOL resolve_ads(const char *name, int name_type,
if ( !NT_STATUS_IS_OK( status ) ) {
return False;
}
+
+ for (i=0;i<numdcs;i++) {
+ numaddrs += MAX(dcs[i].num_ips,1);
+ }
- if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numdcs)) == NULL ) {
- DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numdcs ));
+ if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) == NULL ) {
+ DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numaddrs ));
return False;
}
+
+ /* now unroll the list of IP addresses */
*return_count = 0;
-
- for (i=0;i<numdcs;i++) {
+ i = 0;
+ j = 0;
+ while ( i < numdcs && (*return_count<numaddrs) ) {
struct ip_service *r = &(*return_iplist)[*return_count];
- /* use the IP address from the SRV structure if we have one */
- if ( is_zero_ip( dcs[i].ip ) )
- r->ip = *interpret_addr2(dcs[i].hostname);
- else
- r->ip = dcs[i].ip;
-
r->port = dcs[i].port;
+
+ /* If we don't have an IP list for a name, lookup it up */
+
+ if ( !dcs[i].ips ) {
+ r->ip = *interpret_addr2(dcs[i].hostname);
+ i++;
+ j = 0;
+ } else {
+ /* use the IP addresses from the SRV sresponse */
+
+ if ( j >= dcs[i].num_ips ) {
+ i++;
+ j = 0;
+ continue;
+ }
+
+ r->ip = dcs[i].ips[j];
+ j++;
+ }
/* make sure it is a valid IP. I considered checking the negative
connection cache, but this is the wrong place for it. Maybe only
@@ -1151,86 +1172,86 @@ BOOL internal_resolve_name(const char *name, int name_type,
pstrcpy(name_resolve_list, lp_name_resolve_order());
} else {
pstrcpy(name_resolve_list, resolve_order);
+ }
- if ( !name_resolve_list[0] ) {
- ptr = "host";
- } else {
- ptr = name_resolve_list;
- }
+ if ( !name_resolve_list[0] ) {
+ ptr = "host";
+ } else {
+ ptr = name_resolve_list;
+ }
- /* iterate through the name resolution backends */
+ /* iterate through the name resolution backends */
- while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
- if((strequal(tok, "host") || strequal(tok, "hosts"))) {
- if (resolve_hosts(name, name_type, return_iplist, return_count)) {
- result = True;
- goto done;
- }
- } else if(strequal( tok, "ads")) {
- /* deal with 0x1c names here. This will result in a
- SRV record lookup */
- if (resolve_ads(name, name_type, return_iplist, return_count)) {
- result = True;
- goto done;
- }
- } else if(strequal( tok, "lmhosts")) {
- if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
- result = True;
- goto done;
- }
- } else if(strequal( tok, "wins")) {
- /* don't resolve 1D via WINS */
- if (name_type != 0x1D && resolve_wins(name, name_type, return_iplist, return_count)) {
- result = True;
- goto done;
- }
- } else if(strequal( tok, "bcast")) {
- if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
- result = True;
- goto done;
- }
- } else {
- DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
+ while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
+ if((strequal(tok, "host") || strequal(tok, "hosts"))) {
+ if (resolve_hosts(name, name_type, return_iplist, return_count)) {
+ result = True;
+ goto done;
+ }
+ } else if(strequal( tok, "ads")) {
+ /* deal with 0x1c names here. This will result in a
+ SRV record lookup */
+ if (resolve_ads(name, name_type, return_iplist, return_count)) {
+ result = True;
+ goto done;
+ }
+ } else if(strequal( tok, "lmhosts")) {
+ if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
+ result = True;
+ goto done;
+ }
+ } else if(strequal( tok, "wins")) {
+ /* don't resolve 1D via WINS */
+ if (name_type != 0x1D && resolve_wins(name, name_type, return_iplist, return_count)) {
+ result = True;
+ goto done;
+ }
+ } else if(strequal( tok, "bcast")) {
+ if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
+ result = True;
+ goto done;
}
+ } else {
+ DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
}
+ }
- /* All of the resolve_* functions above have returned false. */
+ /* All of the resolve_* functions above have returned false. */
- SAFE_FREE(*return_iplist);
- *return_count = 0;
+ SAFE_FREE(*return_iplist);
+ *return_count = 0;
- return False;
+ return False;
done:
- /* Remove duplicate entries. Some queries, notably #1c (domain
- controllers) return the PDC in iplist[0] and then all domain
- controllers including the PDC in iplist[1..n]. Iterating over
- the iplist when the PDC is down will cause two sets of timeouts. */
+ /* Remove duplicate entries. Some queries, notably #1c (domain
+ controllers) return the PDC in iplist[0] and then all domain
+ controllers including the PDC in iplist[1..n]. Iterating over
+ the iplist when the PDC is down will cause two sets of timeouts. */
- if ( *return_count ) {
- *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
- }
+ if ( *return_count ) {
+ *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
+ }
- /* Save in name cache */
- if ( DEBUGLEVEL >= 100 ) {
- for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
- DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
- name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
- }
+ /* Save in name cache */
+ if ( DEBUGLEVEL >= 100 ) {
+ for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
+ DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
+ name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
+ }
- namecache_store(name, name_type, *return_count, *return_iplist);
+ namecache_store(name, name_type, *return_count, *return_iplist);
- /* Display some debugging info */
+ /* Display some debugging info */
- if ( DEBUGLEVEL >= 10 ) {
- DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count));
+ if ( DEBUGLEVEL >= 10 ) {
+ DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count));
- for (i = 0; i < *return_count; i++) {
- DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
- }
- DEBUG(10, ("\n"));
+ for (i = 0; i < *return_count; i++) {
+ DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
}
+ DEBUG(10, ("\n"));
}
return result;
@@ -1356,6 +1377,8 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list,
BOOL done_auto_lookup = False;
int auto_count = 0;
+ *ordered = False;
+
/* if we are restricted to solely using DNS for looking
up a domain controller, make sure that host lookups
are enabled for the 'name resolve order'. If host lookups
@@ -1365,14 +1388,17 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list,
fstrcpy( resolve_order, lp_name_resolve_order() );
strlower_m( resolve_order );
if ( ads_only ) {
- if ( strstr( resolve_order, "host" ) )
+ if ( strstr( resolve_order, "host" ) ) {
fstrcpy( resolve_order, "ads" );
- else
- fstrcpy( resolve_order, "NULL" );
+
+ /* DNS SRV lookups used by the ads resolver
+ are already sorted by priority and weight */
+ *ordered = True;
+ } else {
+ fstrcpy( resolve_order, "NULL" );
+ }
}
- *ordered = False;
-
/* fetch the server we have affinity for. Add the
'password server' list to a search for our domain controllers */