diff options
Diffstat (limited to 'source/libsmb')
-rw-r--r-- | source/libsmb/cliconnect.c | 65 | ||||
-rw-r--r-- | source/libsmb/clierror.c | 12 | ||||
-rw-r--r-- | source/libsmb/clikrb5.c | 10 | ||||
-rw-r--r-- | source/libsmb/clilist.c | 16 | ||||
-rw-r--r-- | source/libsmb/clitrans.c | 14 | ||||
-rw-r--r-- | source/libsmb/nmblib.c | 2 | ||||
-rw-r--r-- | source/libsmb/smb_signing.c | 79 | ||||
-rw-r--r-- | source/libsmb/smbencrypt.c | 2 | ||||
-rw-r--r-- | source/libsmb/trusts_util.c | 2 | ||||
-rw-r--r-- | source/libsmb/unexpected.c | 10 |
10 files changed, 107 insertions, 105 deletions
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c index d458ce2757..42e0b63511 100644 --- a/source/libsmb/cliconnect.c +++ b/source/libsmb/cliconnect.c @@ -40,6 +40,8 @@ static const struct { {-1,NULL} }; +static const char *star_smbserver_name = "*SMBSERVER"; + /** * Set the user session key for a connection * @param cli The cli structure to add it too @@ -628,7 +630,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char * if (!cli_session_setup_blob(cli, negTokenTarg, session_key_krb5)) { data_blob_free(&negTokenTarg); data_blob_free(&session_key_krb5); - ADS_ERROR_NT(cli_nt_error(cli)); + return ADS_ERROR_NT(cli_nt_error(cli)); } cli_set_session_key(cli, session_key_krb5); @@ -861,10 +863,55 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, } } - rc = cli_session_setup_kerberos(cli, principal, domain); - if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) { + /* If we get a bad principal, try to guess it if + we have a valid host NetBIOS name. + */ + if (strequal(principal, ADS_IGNORE_PRINCIPAL)) { SAFE_FREE(principal); - return rc; + } + if (principal == NULL && + !is_ipaddress(cli->desthost) && + !strequal(star_smbserver_name, + cli->desthost)) { + char *realm = NULL; + char *machine = NULL; + char *host = NULL; + DEBUG(3,("cli_session_setup_spnego: got a " + "bad server principal, trying to guess ...\n")); + + host = strchr_m(cli->desthost, '.'); + if (host) { + machine = SMB_STRNDUP(cli->desthost, + host - cli->desthost); + } else { + machine = SMB_STRDUP(cli->desthost); + } + if (machine == NULL) { + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + + realm = kerberos_get_default_realm_from_ccache(); + if (realm && *realm) { + if (asprintf(&principal, "%s$@%s", + machine, realm) < 0) { + SAFE_FREE(machine); + SAFE_FREE(realm); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + DEBUG(3,("cli_session_setup_spnego: guessed " + "server principal=%s\n", + principal ? principal : "<null>")); + } + SAFE_FREE(machine); + SAFE_FREE(realm); + } + + if (principal) { + rc = cli_session_setup_kerberos(cli, principal, domain); + if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) { + SAFE_FREE(principal); + return rc; + } } } #endif @@ -1412,7 +1459,7 @@ NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip char *p; /* reasonable default hostname */ - if (!host) host = "*SMBSERVER"; + if (!host) host = star_smbserver_name; fstrcpy(cli->desthost, host); @@ -1527,8 +1574,8 @@ again: *p = 0; goto again; } - if (strcmp(called.name, "*SMBSERVER")) { - make_nmb_name(&called , "*SMBSERVER", 0x20); + if (strcmp(called.name, star_smbserver_name)) { + make_nmb_name(&called , star_smbserver_name, 0x20); goto again; } return NT_STATUS_BAD_NETWORK_NAME; @@ -1652,7 +1699,7 @@ BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho */ if(is_ipaddress(desthost)) { - make_nmb_name(&called, "*SMBSERVER", 0x20); + make_nmb_name(&called, star_smbserver_name, 0x20); } else { make_nmb_name(&called, desthost, 0x20); } @@ -1661,7 +1708,7 @@ BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho NTSTATUS status; struct nmb_name smbservername; - make_nmb_name(&smbservername , "*SMBSERVER", 0x20); + make_nmb_name(&smbservername, star_smbserver_name, 0x20); /* * If the name wasn't *SMBSERVER then diff --git a/source/libsmb/clierror.c b/source/libsmb/clierror.c index ff6fbf522f..cacfe8221c 100644 --- a/source/libsmb/clierror.c +++ b/source/libsmb/clierror.c @@ -469,3 +469,15 @@ void cli_set_nt_error(struct cli_state *cli, NTSTATUS status) SSVAL(cli->inbuf,smb_flg2, SVAL(cli->inbuf,smb_flg2)|FLAGS2_32_BIT_ERROR_CODES); SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(status)); } + +/* Reset an error. */ + +void cli_reset_error(struct cli_state *cli) +{ + if (SVAL(cli->inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES) { + SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(NT_STATUS_OK)); + } else { + SCVAL(cli->inbuf,smb_rcls,0); + SSVAL(cli->inbuf,smb_err,0); + } +} diff --git a/source/libsmb/clikrb5.c b/source/libsmb/clikrb5.c index 6337b50ce9..e7b68921e5 100644 --- a/source/libsmb/clikrb5.c +++ b/source/libsmb/clikrb5.c @@ -336,8 +336,8 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ got_auth_data_pac = unwrap_pac(mem_ctx, &auth_data_wrapped, auth_data); data_blob_free(&auth_data_wrapped); - if (!got_auth_data_pac) { - continue; + if (got_auth_data_pac) { + return true; } } @@ -363,9 +363,9 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ /* check if it is a PAC */ got_auth_data_pac = unwrap_pac(mem_ctx, &auth_data_wrapped, auth_data); data_blob_free(&auth_data_wrapped); - - if (!got_auth_data_pac) { - continue; + + if (got_auth_data_pac) { + return true; } } diff --git a/source/libsmb/clilist.c b/source/libsmb/clilist.c index 3e76cd4775..98c043635f 100644 --- a/source/libsmb/clilist.c +++ b/source/libsmb/clilist.c @@ -247,7 +247,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, &rparam, ¶m_len, &rdata, &data_len) && cli_is_dos_error(cli)) { - /* we need to work around a Win95 bug - sometimes + /* We need to work around a Win95 bug - sometimes it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; @@ -256,6 +256,20 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SAFE_FREE(rparam); cli_dos_error(cli, &eclass, &ecode); + + /* + * OS/2 might return "no more files", + * which just tells us, that searchcount is zero + * in this search. + * Guenter Kukkukk <linux@kukkukk.com> + */ + + if (eclass == ERRDOS && ecode == ERRnofiles) { + ff_searchcount = 0; + cli_reset_error(cli); + break; + } + if (eclass != ERRSRV || ecode != ERRerror) break; smb_msleep(100); diff --git a/source/libsmb/clitrans.c b/source/libsmb/clitrans.c index f212f49994..f43a2aa028 100644 --- a/source/libsmb/clitrans.c +++ b/source/libsmb/clitrans.c @@ -95,14 +95,9 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, return False; } - /* Note we're in a trans state. Save the sequence - * numbers for replies. */ - client_set_trans_sign_state_on(cli, mid); - if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { - client_set_trans_sign_state_off(cli, mid); return(False); } @@ -144,7 +139,6 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, show_msg(cli->outbuf); if (!cli_send_smb(cli)) { - client_set_trans_sign_state_off(cli, mid); return False; } @@ -323,7 +317,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, out: - client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); return ret; } @@ -391,14 +384,9 @@ BOOL cli_send_nt_trans(struct cli_state *cli, return False; } - /* Note we're in a trans state. Save the sequence - * numbers for replies. */ - client_set_trans_sign_state_on(cli, mid); - if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { - client_set_trans_sign_state_off(cli, mid); return(False); } @@ -440,7 +428,6 @@ BOOL cli_send_nt_trans(struct cli_state *cli, show_msg(cli->outbuf); if (!cli_send_smb(cli)) { - client_set_trans_sign_state_off(cli, mid); return False; } @@ -640,6 +627,5 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, out: - client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); return ret; } diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c index 5280dfdbff..641473bea1 100644 --- a/source/libsmb/nmblib.c +++ b/source/libsmb/nmblib.c @@ -702,6 +702,8 @@ struct packet_struct *parse_packet(char *buf,int length, if (!p) return(NULL); + ZERO_STRUCTP(p); /* initialize for possible padding */ + p->next = NULL; p->prev = NULL; p->ip = lastip; diff --git a/source/libsmb/smb_signing.c b/source/libsmb/smb_signing.c index df74b2db36..6768c2accc 100644 --- a/source/libsmb/smb_signing.c +++ b/source/libsmb/smb_signing.c @@ -26,7 +26,6 @@ struct outstanding_packet_lookup { struct outstanding_packet_lookup *prev, *next; uint16 mid; uint32 reply_seq_num; - BOOL can_delete; /* Set to False in trans state. */ }; struct smb_basic_signing_context { @@ -43,7 +42,9 @@ static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list, /* Ensure we only add a mid once. */ for (t = *list; t; t = t->next) { if (t->mid == mid) { - return False; + DLIST_REMOVE(*list, t); + SAFE_FREE(t); + break; } } @@ -52,7 +53,6 @@ static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list, t->mid = mid; t->reply_seq_num = reply_seq_num; - t->can_delete = True; /* * Add to the *start* of the list not the end of the list. @@ -79,23 +79,8 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, *reply_seq_num = t->reply_seq_num; DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); - if (t->can_delete) { - DLIST_REMOVE(*list, t); - SAFE_FREE(t); - } - return True; - } - } - return False; -} - -static BOOL set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, BOOL can_delete_entry) -{ - struct outstanding_packet_lookup *t; - - for (t = *list; t; t = t->next) { - if (t->mid == mid) { - t->can_delete = can_delete_entry; + DLIST_REMOVE(*list, t); + SAFE_FREE(t); return True; } } @@ -604,60 +589,6 @@ BOOL cli_check_sign_mac(struct cli_state *cli) } /*********************************************************** - Enter trans/trans2/nttrans state. -************************************************************/ - -BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) -{ - struct smb_sign_info *si = &cli->sign_info; - struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) { - return True; - } - - if (!data) { - return False; - } - - if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) { - return False; - } - - return True; -} - -/*********************************************************** - Leave trans/trans2/nttrans state. -************************************************************/ - -BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) -{ - uint32 reply_seq_num; - struct smb_sign_info *si = &cli->sign_info; - struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) { - return True; - } - - if (!data) { - return False; - } - - if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) { - return False; - } - - /* Now delete the stored mid entry. */ - if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) { - return False; - } - - return True; -} - -/*********************************************************** SMB signing - Server implementation - send the MAC. ************************************************************/ diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c index 5f7b5b1809..9812cbf67a 100644 --- a/source/libsmb/smbencrypt.c +++ b/source/libsmb/smbencrypt.c @@ -444,7 +444,7 @@ BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uchar nt_ the username and domain. This prevents username swapping during the auth exchange */ - if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) { + if (!ntv2_owf_gen(nt_hash, user, domain, False, ntlm_v2_hash)) { return False; } diff --git a/source/libsmb/trusts_util.c b/source/libsmb/trusts_util.c index e4061883eb..2580b50054 100644 --- a/source/libsmb/trusts_util.c +++ b/source/libsmb/trusts_util.c @@ -41,7 +41,7 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX already have valid creds. If not we must set them up. */ if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; + uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS; result = rpccli_netlogon_setup_creds(cli, cli->cli->desthost, /* server name */ diff --git a/source/libsmb/unexpected.c b/source/libsmb/unexpected.c index 97d6071e71..0e4e03384c 100644 --- a/source/libsmb/unexpected.c +++ b/source/libsmb/unexpected.c @@ -59,6 +59,8 @@ void unexpected_packet(struct packet_struct *p) len = build_packet(buf, p); + ZERO_STRUCT(key); /* needed for potential alignment */ + key.packet_type = p->packet_type; key.timestamp = p->timestamp; key.count = count++; @@ -81,6 +83,10 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st { struct unexpected_key key; + if (kbuf.dsize != sizeof(key)) { + tdb_delete(ttdb, kbuf); + } + memcpy(&key, kbuf.dptr, sizeof(key)); if (lastt - key.timestamp > NMBD_UNEXPECTED_TIMEOUT) { @@ -120,6 +126,10 @@ static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void struct unexpected_key key; struct packet_struct *p; + if (kbuf.dsize != sizeof(key)) { + return 0; + } + memcpy(&key, kbuf.dptr, sizeof(key)); if (key.packet_type != match_type) return 0; |