From fd2bac966783a9aa3f278cc67219920384bc0981 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 19 Nov 2008 22:55:06 +0100 Subject: For read&x replies, check the offset --- source3/libsmb/clireadwrite.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index ecf49396d1..1c2a0d56c4 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -109,6 +109,7 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, uint16_t *vwv; uint16_t num_bytes; uint8_t *bytes; + uint8_t *buf; NTSTATUS status; size_t size; @@ -136,6 +137,24 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, return NT_STATUS_UNEXPECTED_IO_ERROR; } + /* + * bcc field must be valid for small reads, for large reads the 16-bit + * bcc field can't be correct. + */ + + if ((size < 0xffff) && (size > num_bytes)) { + DEBUG(5, ("server announced more bytes than sent\n")); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + buf = (uint8_t *)smb_base(cli_req->inbuf) + SVAL(vwv+6, 0); + + if (trans_oob(smb_len(cli_req->inbuf), SVAL(vwv+6, 0), size) + || (buf < bytes)) { + DEBUG(5, ("server returned invalid read&x data offset\n")); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + *rcvbuf = (uint8_t *)(smb_base(cli_req->inbuf) + SVAL(vwv + 6, 0)); *received = size; return NT_STATUS_OK; -- cgit From 0c43f96330f2935805ba4f0f8f858a027a90bc4c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 27 Oct 2008 09:40:25 +0100 Subject: s3: libsmb/namequery: fallback to returning all dcs, when none is available in the requested site MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It could happen that all dcs in a site are unavailable (some sites have only one dc) and then we need to fallback to get all dcs. metze Signed-off-by: Stefan Metzmacher Signed-off-by: Günther Deschner (cherry picked from commit c127367b1dd622eeceb1f47de0a047c297dda222) --- source3/libsmb/namequery.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index bcf849b795..87ed5af14c 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -2098,6 +2098,15 @@ NTSTATUS get_sorted_dc_list( const char *domain, status = get_dc_list(domain, sitename, ip_list, count, lookup_type, &ordered); + if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS) + && sitename) { + DEBUG(3,("get_sorted_dc_list: no server for name %s available" + " in site %s, fallback to all servers\n", + domain, sitename)); + status = get_dc_list(domain, NULL, ip_list, + count, lookup_type, &ordered); + } + if (!NT_STATUS_IS_OK(status)) { SAFE_FREE(*ip_list); *count = 0; -- cgit From 895c40d03a07182c054a6fd857e7dd6838e698f4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 27 Oct 2008 19:31:30 +0100 Subject: s3:libsmb/namequery.c: add saf_join_store() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit saf_join_store() should be called after a successful domain join, the affinity to the dc used at join time has a larger ttl, to avoid problems with delayed replication. metze Signed-off-by: Stefan Metzmacher Signed-off-by: Günther Deschner (cherry picked from commit 80e74a27c55c01221091e3eec930c2ac4433c22c) --- source3/libsmb/namequery.c | 68 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 87ed5af14c..05679570d4 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -34,6 +34,8 @@ bool global_in_nmbd = False; ****************************************************************************/ #define SAFKEY_FMT "SAF/DOMAIN/%s" #define SAF_TTL 900 +#define SAFJOINKEY_FMT "SAFJOIN/DOMAIN/%s" +#define SAFJOIN_TTL 3600 static char *saf_key(const char *domain) { @@ -44,6 +46,15 @@ static char *saf_key(const char *domain) return keystr; } +static char *saf_join_key(const char *domain) +{ + char *keystr; + + asprintf_strupper_m(&keystr, SAFJOINKEY_FMT, domain); + + return keystr; +} + /**************************************************************************** ****************************************************************************/ @@ -69,7 +80,7 @@ bool saf_store( const char *domain, const char *servername ) return False; key = saf_key( domain ); - expire = time( NULL ) + SAF_TTL; + expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL); DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n", domain, servername, (unsigned int)expire )); @@ -81,6 +92,38 @@ bool saf_store( const char *domain, const char *servername ) return ret; } +bool saf_join_store( const char *domain, const char *servername ) +{ + char *key; + time_t expire; + bool ret = False; + + if ( !domain || !servername ) { + DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n")); + return False; + } + + if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) { + DEBUG(0,("saf_join_store: refusing to store 0 length domain or servername!\n")); + return False; + } + + if ( !gencache_init() ) + return False; + + key = saf_join_key( domain ); + expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL); + + DEBUG(10,("saf_join_store: domain = [%s], server = [%s], expire = [%u]\n", + domain, servername, (unsigned int)expire )); + + ret = gencache_set( key, servername, expire ); + + SAFE_FREE( key ); + + return ret; +} + bool saf_delete( const char *domain ) { char *key; @@ -94,15 +137,22 @@ bool saf_delete( const char *domain ) if ( !gencache_init() ) return False; + key = saf_join_key(domain); + ret = gencache_del(key); + SAFE_FREE(key); + + if (ret) { + DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain )); + } + key = saf_key(domain); ret = gencache_del(key); + SAFE_FREE(key); if (ret) { DEBUG(10,("saf_delete: domain = [%s]\n", domain )); } - SAFE_FREE( key ); - return ret; } @@ -124,6 +174,18 @@ char *saf_fetch( const char *domain ) if ( !gencache_init() ) return False; + key = saf_join_key( domain ); + + ret = gencache_get( key, &server, &timeout ); + + SAFE_FREE( key ); + + if ( ret ) { + DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n", + server, domain )); + return server; + } + key = saf_key( domain ); ret = gencache_get( key, &server, &timeout ); -- cgit From 1b7b0e924f3064a9774fd5d46bedc3d342b39ddb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 21 Nov 2008 08:28:13 +0100 Subject: s3:dsgetdcname: retry with the clients site metze --- source3/libsmb/dsgetdcname.c | 49 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index d8c2b70175..3491544175 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -1119,6 +1119,27 @@ static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx, num_dcs, info); } +static bool is_closest_site(struct netr_DsRGetDCNameInfo *info) +{ + if (info->dc_flags & DS_SERVER_CLOSEST) { + return true; + } + + if (!info->client_site_name) { + return true; + } + + if (!info->dc_site_name) { + return false; + } + + if (strcmp(info->client_site_name, info->dc_site_name) == 0) { + return true; + } + + return false; +} + /******************************************************************** dsgetdcname. @@ -1136,6 +1157,8 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; struct netr_DsRGetDCNameInfo *myinfo = NULL; char *query_site = NULL; + bool first = true; + struct netr_DsRGetDCNameInfo *first_info = NULL; DEBUG(10,("dsgetdcname: domain_name: %s, " "domain_guid: %s, site_name: %s, flags: 0x%08x\n", @@ -1163,7 +1186,6 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, status = dsgetdcname_cached(mem_ctx, msg_ctx, domain_name, domain_guid, flags, query_site, &myinfo); if (NT_STATUS_IS_OK(status)) { - *info = myinfo; goto done; } @@ -1176,12 +1198,27 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, domain_guid, flags, query_site, &myinfo); - if (NT_STATUS_IS_OK(status)) { - *info = myinfo; - } - done: SAFE_FREE(query_site); - return status; + if (!NT_STATUS_IS_OK(status)) { + if (!first) { + *info = first_info; + return NT_STATUS_OK; + } + return status; + } + + if (!first) { + TALLOC_FREE(first_info); + } else if (!is_closest_site(myinfo)) { + first = false; + first_info = myinfo; + /* TODO: may use the next_closest_site here */ + query_site = SMB_STRDUP(myinfo->client_site_name); + goto rediscover; + } + + *info = myinfo; + return NT_STATUS_OK; } -- cgit From b04d00744efb2189c37c01b2c57cc3899db1e482 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 Dec 2008 16:53:17 +0100 Subject: Micro-Optimize cliconnect.c In this form, the prots array is fully read-only in the text segment and thus can be shared between processes. Probably pointless, but I had fun doing it :-) --- source3/libsmb/cliconnect.c | 49 +++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index d33775fbb8..8194a36941 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -22,19 +22,18 @@ static const struct { int prot; - const char *name; -} prots[] = { - {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, - {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, - {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, - {PROTOCOL_LANMAN1,"LANMAN1.0"}, - {PROTOCOL_LANMAN2,"LM1.2X002"}, - {PROTOCOL_LANMAN2,"DOS LANMAN2.1"}, - {PROTOCOL_LANMAN2,"LANMAN2.1"}, - {PROTOCOL_LANMAN2,"Samba"}, - {PROTOCOL_NT1,"NT LANMAN 1.0"}, - {PROTOCOL_NT1,"NT LM 0.12"}, - {-1,NULL} + const char name[24]; +} prots[10] = { + {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"}, + {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"}, + {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"}, + {PROTOCOL_LANMAN1, "LANMAN1.0"}, + {PROTOCOL_LANMAN2, "LM1.2X002"}, + {PROTOCOL_LANMAN2, "DOS LANMAN2.1"}, + {PROTOCOL_LANMAN2, "LANMAN2.1"}, + {PROTOCOL_LANMAN2, "Samba"}, + {PROTOCOL_NT1, "NT LANMAN 1.0"}, + {PROTOCOL_NT1, "NT LM 0.12"}, }; static const char *star_smbserver_name = "*SMBSERVER"; @@ -1221,9 +1220,10 @@ void cli_negprot_send(struct cli_state *cli) cli_set_message(cli->outbuf,0,0,True); p = smb_buf(cli->outbuf); - for (numprots=0; - prots[numprots].name && prots[numprots].prot<=cli->protocol; - numprots++) { + for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) { + if (prots[numprots].prot > cli->protocol) { + break; + } *p++ = 2; p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE); } @@ -1252,18 +1252,23 @@ bool cli_negprot(struct cli_state *cli) memset(cli->outbuf,'\0',smb_size); + plength = 0; + /* setup the protocol strings */ - for (plength=0,numprots=0; - prots[numprots].name && prots[numprots].prot<=cli->protocol; - numprots++) + for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) { + if (prots[numprots].prot > cli->protocol) { + break; + } plength += strlen(prots[numprots].name)+2; + } cli_set_message(cli->outbuf,0,plength,True); p = smb_buf(cli->outbuf); - for (numprots=0; - prots[numprots].name && prots[numprots].prot<=cli->protocol; - numprots++) { + for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) { + if (prots[numprots].prot > cli->protocol) { + break; + } *p++ = 2; p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE); } -- cgit From da6be4102ed1e3d4e20f08dd8944f062d13c759a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 Dec 2008 17:04:12 +0100 Subject: Remove a static variable Derrell, please check! Thanks, Volker --- source3/libsmb/libsmb_dir.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index aa313f2c05..d12e7487f6 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -1193,8 +1193,6 @@ SMBC_mkdir_ctx(SMBCCTX *context, * Our list function simply checks to see if a directory is not empty */ -static int smbc_rmdir_dirempty = True; - static void rmdir_list_fn(const char *mnt, file_info *finfo, @@ -1203,7 +1201,8 @@ rmdir_list_fn(const char *mnt, { if (strncmp(finfo->name, ".", 1) != 0 && strncmp(finfo->name, "..", 2) != 0) { - smbc_rmdir_dirempty = False; + bool *smbc_rmdir_dirempty = (bool *)state; + *smbc_rmdir_dirempty = false; } } @@ -1292,8 +1291,7 @@ SMBC_rmdir_ctx(SMBCCTX *context, /* Local storage to avoid buffer overflows */ char *lpath; - - smbc_rmdir_dirempty = True; /* Make this so ... */ + bool smbc_rmdir_dirempty = true; lpath = talloc_asprintf(frame, "%s\\*", targetpath); @@ -1305,7 +1303,8 @@ SMBC_rmdir_ctx(SMBCCTX *context, if (cli_list(targetcli, lpath, aDIR | aSYSTEM | aHIDDEN, - rmdir_list_fn, NULL) < 0) { + rmdir_list_fn, + &smbc_rmdir_dirempty) < 0) { /* Fix errno to ignore latest error ... */ DEBUG(5, ("smbc_rmdir: " -- cgit From be3d9990635fa31e4110285842b1ca98ed4ce53c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 Dec 2008 16:40:25 +0100 Subject: Remove a pointless static variable Every sane compiler will only allocate "*SMBSERVER" once --- source3/libsmb/cliconnect.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8194a36941..125345fccb 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -36,7 +36,7 @@ static const struct { {PROTOCOL_NT1, "NT LM 0.12"}, }; -static const char *star_smbserver_name = "*SMBSERVER"; +#define STAR_SMBSERVER "*SMBSERVER" /** * Set the user session key for a connection @@ -862,7 +862,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, if (principal == NULL && !is_ipaddress(cli->desthost) && - !strequal(star_smbserver_name, + !strequal(STAR_SMBSERVER, cli->desthost)) { char *realm = NULL; char *machine = NULL; @@ -1500,7 +1500,7 @@ NTSTATUS cli_connect(struct cli_state *cli, /* reasonable default hostname */ if (!host) { - host = star_smbserver_name; + host = STAR_SMBSERVER; } fstrcpy(cli->desthost, host); @@ -1648,8 +1648,8 @@ again: *p = 0; goto again; } - if (strcmp(called.name, star_smbserver_name)) { - make_nmb_name(&called , star_smbserver_name, 0x20); + if (strcmp(called.name, STAR_SMBSERVER)) { + make_nmb_name(&called , STAR_SMBSERVER, 0x20); goto again; } return NT_STATUS_BAD_NETWORK_NAME; @@ -1779,7 +1779,7 @@ bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho */ if(is_ipaddress(desthost)) { - make_nmb_name(&called, star_smbserver_name, 0x20); + make_nmb_name(&called, STAR_SMBSERVER, 0x20); } else { make_nmb_name(&called, desthost, 0x20); } @@ -1788,7 +1788,7 @@ bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho NTSTATUS status; struct nmb_name smbservername; - make_nmb_name(&smbservername, star_smbserver_name, 0x20); + make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20); /* * If the name wasn't *SMBSERVER then -- cgit From daeb3a190d16a5bc05be63b2b136ebe65d6f6cf7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 14 Dec 2008 13:06:19 +0100 Subject: Remove the global "cmdline_auth_info" from source3/lib/util.c This involves changing all our clients, that's why it's so large. --- source3/libsmb/clidfs.c | 13 +++++++------ source3/libsmb/libsmb_context.c | 18 ++++++++++++------ 2 files changed, 19 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 35922b13e9..f0ac39fed0 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -471,18 +471,19 @@ static void cm_set_password(const char *newpass) /**************************************************************************** ****************************************************************************/ -void cli_cm_set_credentials(void) +void cli_cm_set_credentials(struct user_auth_info *auth_info) { SAFE_FREE(cm_creds.username); - cm_creds.username = SMB_STRDUP(get_cmdline_auth_info_username()); + cm_creds.username = SMB_STRDUP(get_cmdline_auth_info_username( + auth_info)); - if (get_cmdline_auth_info_got_pass()) { - cm_set_password(get_cmdline_auth_info_password()); + if (get_cmdline_auth_info_got_pass(auth_info)) { + cm_set_password(get_cmdline_auth_info_password(auth_info)); } - cm_creds.use_kerberos = get_cmdline_auth_info_use_kerberos(); + cm_creds.use_kerberos = get_cmdline_auth_info_use_kerberos(auth_info); cm_creds.fallback_after_kerberos = false; - cm_creds.signing_state = get_cmdline_auth_info_signing_state(); + cm_creds.signing_state = get_cmdline_auth_info_signing_state(auth_info); } /**************************************************************************** diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index 19843383de..becee17f65 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -633,13 +633,19 @@ smbc_set_credentials(char *workgroup, smbc_bool use_kerberos, char *signing_state) { - - set_cmdline_auth_info_username(user); - set_cmdline_auth_info_password(password); - set_cmdline_auth_info_use_kerberos(use_kerberos); - if (! set_cmdline_auth_info_signing_state(signing_state)) { + struct user_auth_info *auth_info; + + auth_info = user_auth_info_init(talloc_tos()); + if (auth_info == NULL) { + return; + } + set_cmdline_auth_info_username(auth_info, user); + set_cmdline_auth_info_password(auth_info, password); + set_cmdline_auth_info_use_kerberos(auth_info, use_kerberos); + if (! set_cmdline_auth_info_signing_state(auth_info, signing_state)) { DEBUG(0, ("Invalid signing state: %s", signing_state)); } set_global_myworkgroup(workgroup); - cli_cm_set_credentials(); + cli_cm_set_credentials(auth_info); + TALLOC_FREE(auth_info); } -- cgit