diff options
Diffstat (limited to 'source3/libsmb')
-rw-r--r-- | source3/libsmb/cliconnect.c | 2 | ||||
-rw-r--r-- | source3/libsmb/clidfs.c | 7 | ||||
-rw-r--r-- | source3/libsmb/clidgram.c | 165 | ||||
-rw-r--r-- | source3/libsmb/clientgen.c | 48 | ||||
-rw-r--r-- | source3/libsmb/clireadwrite.c | 5 | ||||
-rw-r--r-- | source3/libsmb/doserr.c | 4 | ||||
-rw-r--r-- | source3/libsmb/dsgetdcname.c | 40 | ||||
-rw-r--r-- | source3/libsmb/libsmb_dir.c | 4 | ||||
-rw-r--r-- | source3/libsmb/libsmb_xattr.c | 2 | ||||
-rw-r--r-- | source3/libsmb/passchange.c | 15 | ||||
-rw-r--r-- | source3/libsmb/trusts_util.c | 2 |
11 files changed, 217 insertions, 77 deletions
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 949bca747d..7d3d246da5 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1492,8 +1492,6 @@ NTSTATUS cli_connect(struct cli_state *cli, } fstrcpy(cli->desthost, host); - fstr_sprintf(cli->srv_name_slash, "\\\\%s", cli->desthost); - strupper_m(cli->srv_name_slash); /* allow hostnames of the form NAME#xx and do a netbios lookup */ if ((p = strchr(cli->desthost, '#'))) { diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 0b55d930aa..7b63f9535e 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -202,10 +202,15 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, } if (!cm_creds.got_pass && !cm_creds.use_kerberos) { - char *pass = getpass("Password: "); + char *label = NULL; + char *pass; + label = talloc_asprintf(ctx, "Enter %s's password: ", + cm_creds.username); + pass = getpass(label); if (pass) { cm_set_password(pass); } + TALLOC_FREE(label); } username = cm_creds.username ? cm_creds.username : ""; diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 66c6ee1022..baee95b9aa 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -119,3 +119,168 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx, MSG_SEND_PACKET, (uint8 *)&p, sizeof(p))); } + +static void mailslot_name(struct in_addr dc_ip, fstring name) +{ + fstr_sprintf(name, "\\MAILSLOT\\NET\\GETDC%X", dc_ip.s_addr); +} + +bool send_getdc_request(struct messaging_context *msg_ctx, + struct sockaddr_storage *dc_ss, + const char *domain_name, + const DOM_SID *sid) +{ + char outbuf[1024]; + struct in_addr dc_ip; + char *p; + fstring my_acct_name; + fstring my_mailslot; + size_t sid_size; + + if (dc_ss->ss_family != AF_INET) { + return false; + } + + dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr; + mailslot_name(dc_ip, my_mailslot); + + memset(outbuf, '\0', sizeof(outbuf)); + + p = outbuf; + + SCVAL(p, 0, SAMLOGON); + p++; + + SCVAL(p, 0, 0); /* Count pointer ... */ + p++; + + SIVAL(p, 0, 0); /* The sender's token ... */ + p += 2; + + p += dos_PutUniCode(p, global_myname(), + sizeof(outbuf) - PTR_DIFF(p, outbuf), True); + fstr_sprintf(my_acct_name, "%s$", global_myname()); + p += dos_PutUniCode(p, my_acct_name, + sizeof(outbuf) - PTR_DIFF(p, outbuf), True); + + if (strlen(my_mailslot)+1 > sizeof(outbuf) - PTR_DIFF(p, outbuf)) { + return false; + } + + memcpy(p, my_mailslot, strlen(my_mailslot)+1); + p += strlen(my_mailslot)+1; + + if (sizeof(outbuf) - PTR_DIFF(p, outbuf) < 8) { + return false; + } + + SIVAL(p, 0, 0x80); + p+=4; + + sid_size = ndr_size_dom_sid(sid, 0); + + SIVAL(p, 0, sid_size); + p+=4; + + p = ALIGN4(p, outbuf); + if (PTR_DIFF(p, outbuf) > sizeof(outbuf)) { + return false; + } + + if (sid_size + 8 > sizeof(outbuf) - PTR_DIFF(p, outbuf)) { + return false; + } + if (sid) { + sid_linearize(p, sizeof(outbuf) - PTR_DIFF(p, outbuf), sid); + } + + p += sid_size; + + SIVAL(p, 0, 1); + SSVAL(p, 4, 0xffff); + SSVAL(p, 6, 0xffff); + p+=8; + + return cli_send_mailslot(msg_ctx, + False, "\\MAILSLOT\\NET\\NTLOGON", 0, + outbuf, PTR_DIFF(p, outbuf), + global_myname(), 0, domain_name, 0x1c, + dc_ss); +} + +bool receive_getdc_response(struct sockaddr_storage *dc_ss, + const char *domain_name, + fstring dc_name) +{ + struct packet_struct *packet; + fstring my_mailslot; + char *buf, *p; + fstring dcname, user, domain; + int len; + struct in_addr dc_ip; + + if (dc_ss->ss_family != AF_INET) { + return false; + } + dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr; + mailslot_name(dc_ip, my_mailslot); + + packet = receive_unexpected(DGRAM_PACKET, 0, my_mailslot); + + if (packet == NULL) { + DEBUG(5, ("Did not receive packet for %s\n", my_mailslot)); + return False; + } + + DEBUG(5, ("Received packet for %s\n", my_mailslot)); + + buf = packet->packet.dgram.data; + len = packet->packet.dgram.datasize; + + if (len < 70) { + /* 70 is a completely arbitrary value to make sure + the SVAL below does not read uninitialized memory */ + DEBUG(3, ("GetDC got short response\n")); + return False; + } + + /* This should be (buf-4)+SVAL(buf-4, smb_vwv12)... */ + p = buf+SVAL(buf, smb_vwv10); + + switch (CVAL(p, 0)) { + case SAMLOGON_R: + case SAMLOGON_UNK_R: + p+=2; + pull_ucs2(buf, dcname, p, sizeof(dcname), PTR_DIFF(buf+len, p), + STR_TERMINATE|STR_NOALIGN); + p = skip_unibuf(p, PTR_DIFF(buf+len, p)); + pull_ucs2(buf, user, p, sizeof(user), PTR_DIFF(buf+len, p), + STR_TERMINATE|STR_NOALIGN); + p = skip_unibuf(p, PTR_DIFF(buf+len, p)); + pull_ucs2(buf, domain, p, sizeof(domain), PTR_DIFF(buf+len, p), + STR_TERMINATE|STR_NOALIGN); + p = skip_unibuf(p, PTR_DIFF(buf+len, p)); + + if (!strequal(domain, domain_name)) { + DEBUG(3, ("GetDC: Expected domain %s, got %s\n", + domain_name, domain)); + return False; + } + break; + + default: + DEBUG(8, ("GetDC got invalid response type %d\n", CVAL(p, 0))); + return False; + } + p = dcname; + if (*p == '\\') p += 1; + if (*p == '\\') p += 1; + + fstrcpy(dc_name, p); + + DEBUG(10, ("GetDC gave name %s for domain %s\n", + dc_name, domain)); + + return True; +} + diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 64191239d3..e64b6fa278 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -617,54 +617,16 @@ struct cli_state *cli_initialise(void) } /**************************************************************************** - External interface. - Close an open named pipe over SMB. Free any authentication data. - Returns false if the cli_close call failed. - ****************************************************************************/ - -bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) -{ - bool ret; - - if (!cli) { - return false; - } - - ret = cli_close(cli->cli, cli->fnum); - - if (!ret) { - DEBUG(1,("cli_rpc_pipe_close: cli_close failed on pipe %s, " - "fnum 0x%x " - "to machine %s. Error was %s\n", - cli->pipe_name, - (int) cli->fnum, - cli->cli->desthost, - cli_errstr(cli->cli))); - } - - if (cli->auth.cli_auth_data_free_func) { - (*cli->auth.cli_auth_data_free_func)(&cli->auth); - } - - DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n", - cli->pipe_name, cli->cli->desthost )); - - DLIST_REMOVE(cli->cli->pipe_list, cli); - talloc_destroy(cli->mem_ctx); - return ret; -} - -/**************************************************************************** Close all pipes open on this session. ****************************************************************************/ void cli_nt_pipes_close(struct cli_state *cli) { - struct rpc_pipe_client *cp, *next; - - for (cp = cli->pipe_list; cp; cp = next) { - next = cp->next; - cli_rpc_pipe_close(cp); + while (cli->pipe_list != NULL) { + /* + * No TALLOC_FREE here! + */ + talloc_free(cli->pipe_list); } } diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index e79fd90614..12ba4b737f 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -150,11 +150,6 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, return NT_STATUS_UNEXPECTED_IO_ERROR; } - if (size < 0) { - DEBUG(5,("read return < 0!\n")); - return NT_STATUS_UNEXPECTED_IO_ERROR; - } - *rcvbuf = (uint8_t *) (smb_base(cli_req->inbuf) + SVAL(cli_req->inbuf, smb_vwv6)); *received = size; diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index fb5f2e1bac..8761106e58 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -67,6 +67,7 @@ werror_code_struct dos_errs[] = { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, { "WERR_NO_SUCH_LOGON_SESSION", WERR_NO_SUCH_LOGON_SESSION }, { "WERR_USER_ALREADY_EXISTS", WERR_USER_ALREADY_EXISTS }, + { "WERR_NO_SUCH_USER", WERR_NO_SUCH_USER }, { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, { "WERR_STATUS_MORE_ENTRIES ", WERR_STATUS_MORE_ENTRIES }, { "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL }, @@ -85,6 +86,7 @@ werror_code_struct dos_errs[] = { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, { "WERR_PASSWORD_RESTRICTION", WERR_PASSWORD_RESTRICTION }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, + { "WERR_NONE_MAPPED", WERR_NONE_MAPPED }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_INVALID_DOMAIN_STATE", WERR_INVALID_DOMAIN_STATE }, { "WERR_INVALID_DOMAIN_ROLE", WERR_INVALID_DOMAIN_ROLE }, @@ -130,6 +132,8 @@ werror_str_struct dos_err_strs[] = { { WERR_TIME_SKEW, "Time difference between client and server" }, { WERR_USER_ALREADY_EXISTS, "User already exists" }, { WERR_PASSWORD_RESTRICTION, "Password does not meet restrictions" }, + { WERR_NONE_MAPPED, "Could not map names to SIDs" }, + { WERR_NO_SUCH_USER, "No such User" }, }; /***************************************************************************** diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 7af43648d7..00841f0684 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -418,6 +418,8 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, struct dns_rr_srv *dcs = NULL; int numdcs = 0; int numaddrs = 0; + struct ip_service_name *dclist = NULL; + int count = 0; if ((!(flags & DS_DIRECTORY_SERVICE_REQUIRED)) && (!(flags & DS_KDC_REQUIRED)) && @@ -460,9 +462,10 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, numaddrs += MAX(dcs[i].num_ips,1); } - if ((*returned_dclist = TALLOC_ZERO_ARRAY(mem_ctx, - struct ip_service_name, - numaddrs)) == NULL) { + dclist = TALLOC_ZERO_ARRAY(mem_ctx, + struct ip_service_name, + numaddrs); + if (!dclist) { return NT_STATUS_NO_MEMORY; } @@ -471,15 +474,16 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, *return_count = 0; i = 0; j = 0; - while (i < numdcs && (*return_count<numaddrs)) { - struct ip_service_name *r = &(*returned_dclist)[*return_count]; + while ((i < numdcs) && (count < numaddrs)) { + + struct ip_service_name *r = &dclist[count]; r->port = dcs[i].port; r->hostname = dcs[i].hostname; if (!(flags & DS_IP_REQUIRED)) { - (*return_count)++; + count++; continue; } @@ -511,13 +515,19 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, * anything about the DC's -- jerry */ if (!is_zero_addr(&r->ss)) { - (*return_count)++; + count++; continue; } } - return (*return_count > 0) ? NT_STATUS_OK : - NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + *returned_dclist = dclist; + *return_count = count; + + if (count > 0) { + return NT_STATUS_OK; + } + + return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; } /**************************************************************** @@ -590,7 +600,7 @@ static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, const char *domain_name, uint32_t flags, - struct ip_service_name **dclist, + struct ip_service_name *dclist, int num_dcs, struct netr_DsRGetDCNameInfo **info) { @@ -607,7 +617,9 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, ZERO_STRUCT(r); - if ((ads_cldap_netlogon(dclist[i]->hostname, + DEBUG(10,("LDAP ping to %s\n", dclist[i].hostname)); + + if ((ads_cldap_netlogon(dclist[i].hostname, domain_name, &r)) && (check_cldap_reply_required_flags(r.flags, flags))) { valid_dc = true; @@ -645,7 +657,7 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, if (flags & DS_IP_REQUIRED) { char addr[INET6_ADDRSTRLEN]; - print_sockaddr(addr, sizeof(addr), &dclist[i]->ss); + print_sockaddr(addr, sizeof(addr), &dclist[i].ss); dc_address = talloc_asprintf(mem_ctx, "\\\\%s", addr); dc_address_type = DS_ADDRESS_TYPE_INET; @@ -723,7 +735,7 @@ static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx, NT_STATUS_NOT_OK_RETURN(status); return process_dc_dns(mem_ctx, domain_name, flags, - &dclist, num_dcs, info); + dclist, num_dcs, info); } status = discover_dc_dns(mem_ctx, domain_name, domain_guid, flags, @@ -731,7 +743,7 @@ static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx, if (NT_STATUS_IS_OK(status) && num_dcs != 0) { - status = process_dc_dns(mem_ctx, domain_name, flags, &dclist, + status = process_dc_dns(mem_ctx, domain_name, flags, dclist, num_dcs, info); if (NT_STATUS_IS_OK(status)) { return status; diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index f836989004..aea4f103b6 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -287,7 +287,7 @@ net_share_enum_rpc(struct cli_state *cli, /* Issue the NetShareEnum RPC call and retrieve the response */ nt_status = rpccli_srvsvc_NetShareEnumAll(pipe_hnd, talloc_tos(), - pipe_hnd->cli->desthost, + pipe_hnd->desthost, &info_ctr, preferred_len, &total_entries, @@ -319,7 +319,7 @@ net_share_enum_rpc(struct cli_state *cli, done: /* Close the server service pipe */ - cli_rpc_pipe_close(pipe_hnd); + TALLOC_FREE(pipe_hnd); /* Tell 'em if it worked */ return W_ERROR_IS_OK(result) ? 0 : -1; diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index e17146e611..8763205d1f 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -39,7 +39,7 @@ find_lsa_pipe_hnd(struct cli_state *ipc_cli) pipe_hnd; pipe_hnd = pipe_hnd->next) { - if (pipe_hnd->pipe_idx == PI_LSARPC) { + if (rpccli_is_pipe_idx(pipe_hnd, PI_LSARPC)) { return pipe_hnd; } } diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 468750f801..8f7cbf265e 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -177,8 +177,9 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam } } - if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, pipe_hnd->mem_ctx, user_name, - new_passwd, old_passwd))) { + result = rpccli_samr_chgpasswd_user(pipe_hnd, talloc_tos(), + user_name, new_passwd, old_passwd); + if (NT_STATUS_IS_OK(result)) { /* Great - it all worked! */ cli_shutdown(cli); return NT_STATUS_OK; @@ -195,7 +196,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam } /* OK, that failed, so try again... */ - cli_rpc_pipe_close(pipe_hnd); + TALLOC_FREE(pipe_hnd); /* Try anonymous NTLMSSP... */ cli_init_creds(cli, "", "", NULL); @@ -206,11 +207,9 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result); if ( pipe_hnd && - (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, - pipe_hnd->mem_ctx, - user_name, - new_passwd, - old_passwd)))) { + (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user( + pipe_hnd, talloc_tos(), user_name, + new_passwd, old_passwd)))) { /* Great - it all worked! */ cli_shutdown(cli); return NT_STATUS_OK; diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index c3f5f2538a..20ac0143fd 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -43,7 +43,7 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; result = rpccli_netlogon_setup_creds(cli, - cli->cli->desthost, /* server name */ + cli->desthost, /* server name */ lp_workgroup(), /* domain */ global_myname(), /* client name */ global_myname(), /* machine account name */ |