summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/cliconnect.c2
-rw-r--r--source3/libsmb/clidfs.c7
-rw-r--r--source3/libsmb/clidgram.c165
-rw-r--r--source3/libsmb/clientgen.c48
-rw-r--r--source3/libsmb/clireadwrite.c5
-rw-r--r--source3/libsmb/doserr.c4
-rw-r--r--source3/libsmb/dsgetdcname.c40
-rw-r--r--source3/libsmb/libsmb_dir.c4
-rw-r--r--source3/libsmb/libsmb_xattr.c2
-rw-r--r--source3/libsmb/passchange.c15
-rw-r--r--source3/libsmb/trusts_util.c2
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 */