From 43328fbd2ec7062be792f5eca188364a904ec240 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 29 Aug 2006 16:01:18 +0000 Subject: [PATCH] r17912: * mssed DNS SRV fix * internal_resolve_name() fix * time fixes * NULL deref fixes --- source/libsmb/clierror.c | 9 +-- source/libsmb/clifile.c | 4 +- source/libsmb/clilist.c | 18 +---- source/libsmb/clirap.c | 47 +++++------ source/libsmb/libsmbclient.c | 4 +- source/libsmb/namecache.c | 4 +- source/libsmb/namequery.c | 182 ++++++++++++++++++++++++------------------- 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;iip = *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 */ -- 2.11.4.GIT