as a separator when looking at the pathname part.... JRA.
********************************************************************/
-static struct cm_cred_struct {
- char *username;
- char *password;
- bool got_pass;
- bool use_kerberos;
- bool fallback_after_kerberos;
- int signing_state;
-} cm_creds;
-
-static void cm_set_password(const char *newpass);
-
-static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
- struct cli_state *cli,
- const char *sharename,
- char **pp_newserver,
- char **pp_newshare,
- bool force_encrypt,
- const char *username,
- const char *password,
- const char *domain);
-
/********************************************************************
Ensure a connection is encrypted.
********************************************************************/
static struct cli_state *do_connect(TALLOC_CTX *ctx,
const char *server,
const char *share,
+ const struct user_auth_info *auth_info,
bool show_sessetup,
bool force_encrypt,
int max_protocol,
{
struct cli_state *c = NULL;
struct nmb_name called, calling;
+ const char *called_str;
const char *server_n;
struct sockaddr_storage ss;
char *servicename;
sharename = servicename;
if (*sharename == '\\') {
sharename += 2;
+ called_str = sharename;
if (server == NULL) {
server = sharename;
}
}
*sharename = 0;
sharename++;
+ } else {
+ called_str = server;
}
server_n = server;
zero_sockaddr(&ss);
make_nmb_name(&calling, global_myname(), 0x0);
- make_nmb_name(&called , server, name_type);
+ make_nmb_name(&called , called_str, name_type);
again:
zero_sockaddr(&ss);
/* have to open a new connection */
- if (!(c=cli_initialise_ex(cm_creds.signing_state))) {
+ if (!(c=cli_initialise_ex(get_cmdline_auth_info_signing_state(auth_info)))) {
d_printf("Connection to %s failed\n", server_n);
if (c) {
cli_shutdown(c);
max_protocol = PROTOCOL_NT1;
}
c->protocol = max_protocol;
- c->use_kerberos = cm_creds.use_kerberos;
- c->fallback_after_kerberos = cm_creds.fallback_after_kerberos;
+ c->use_kerberos = get_cmdline_auth_info_use_kerberos(auth_info);
+ c->fallback_after_kerberos =
+ get_cmdline_auth_info_fallback_after_kerberos(auth_info);
+ c->use_ccache = get_cmdline_auth_info_use_ccache(auth_info);
if (!cli_session_request(c, &calling, &called)) {
char *p;
return NULL;
}
- if (!cm_creds.got_pass && !cm_creds.use_kerberos) {
- 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 : "";
- password = cm_creds.password ? cm_creds.password : "";
+ username = get_cmdline_auth_info_username(auth_info);
+ password = get_cmdline_auth_info_password(auth_info);
if (!NT_STATUS_IS_OK(cli_session_setup(c, username,
password, strlen(password),
lp_workgroup()))) {
/* If a password was not supplied then
* try again with a null username. */
- if (password[0] || !username[0] || cm_creds.use_kerberos ||
- !NT_STATUS_IS_OK(cli_session_setup(c, "",
+ if (password[0] || !username[0] ||
+ get_cmdline_auth_info_use_kerberos(auth_info) ||
+ !NT_STATUS_IS_OK(cli_session_setup(c, "",
"", 0,
"", 0,
lp_workgroup()))) {
return NULL;
}
d_printf("Anonymous login successful\n");
+ status = cli_init_creds(c, "", lp_workgroup(), "");
+ } else {
+ status = cli_init_creds(c, username, lp_workgroup(), password);
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10,("cli_init_creds() failed: %s\n", nt_errstr(status)));
+ cli_shutdown(c);
+ return NULL;
}
if ( show_sessetup ) {
/* here's the fun part....to support 'msdfs proxy' shares
(on Samba or windows) we have to issues a TRANS_GET_DFS_REFERRAL
here before trying to connect to the original share.
- check_dfs_proxy() will fail if it is a normal share. */
+ cli_check_msdfs_proxy() will fail if it is a normal share. */
if ((c->capabilities & CAP_DFS) &&
cli_check_msdfs_proxy(ctx, c, sharename,
lp_workgroup())) {
cli_shutdown(c);
return do_connect(ctx, newserver,
- newshare, false,
+ newshare, auth_info, false,
force_encrypt, max_protocol,
port, name_type);
}
struct cli_state *referring_cli,
const char *server,
const char *share,
+ const struct user_auth_info *auth_info,
bool show_hdr,
bool force_encrypt,
int max_protocol,
struct cli_state *cli;
cli = do_connect(ctx, server, share,
+ auth_info,
show_hdr, force_encrypt, max_protocol,
port, name_type);
if (referring_cli && referring_cli->posix_capabilities) {
uint16 major, minor;
uint32 caplow, caphigh;
- if (cli_unix_extensions_version(cli, &major,
- &minor, &caplow, &caphigh)) {
+ NTSTATUS status;
+ status = cli_unix_extensions_version(cli, &major, &minor,
+ &caplow, &caphigh);
+ if (NT_STATUS_IS_OK(status)) {
cli_set_unix_extensions_capabilities(cli,
major, minor,
caplow, caphigh);
}
/* Search to the start of the list. */
- for (p = cli; p; p = p->prev) {
+ for (p = cli; p; p = DLIST_PREV(p)) {
if (strequal(server, p->desthost) &&
strequal(share,p->share)) {
return p;
struct cli_state *referring_cli,
const char *server,
const char *share,
+ const struct user_auth_info *auth_info,
bool show_hdr,
bool force_encrypt,
int max_protocol,
return c;
}
- return cli_cm_connect(ctx, referring_cli,
- server, share, show_hdr, force_encrypt,
- max_protocol, port, name_type);
+ if (auth_info == NULL) {
+ /* Can't do a new connection
+ * without auth info. */
+ d_printf("cli_cm_open() Unable to open connection [\\%s\\%s] "
+ "without auth info\n",
+ server, share );
+ return NULL;
+ }
+
+ return cli_cm_connect(ctx,
+ referring_cli,
+ server,
+ share,
+ auth_info,
+ show_hdr,
+ force_encrypt,
+ max_protocol,
+ port,
+ name_type);
}
/****************************************************************************
/****************************************************************************
****************************************************************************/
-static void cm_set_password(const char *newpass)
-{
- SAFE_FREE(cm_creds.password);
- cm_creds.password = SMB_STRDUP(newpass);
- if (cm_creds.password) {
- cm_creds.got_pass = true;
- }
-}
-
/****************************************************************************
****************************************************************************/
+#if 0
void cli_cm_set_credentials(struct user_auth_info *auth_info)
{
SAFE_FREE(cm_creds.username);
cm_creds.fallback_after_kerberos = false;
cm_creds.signing_state = get_cmdline_auth_info_signing_state(auth_info);
}
-
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_set_signing_state(int state)
-{
- cm_creds.signing_state = state;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_set_username(const char *username)
-{
- SAFE_FREE(cm_creds.username);
- cm_creds.username = SMB_STRDUP(username);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_set_password(const char *newpass)
-{
- SAFE_FREE(cm_creds.password);
- cm_creds.password = SMB_STRDUP(newpass);
- if (cm_creds.password) {
- cm_creds.got_pass = true;
- }
-}
-
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_set_use_kerberos(void)
-{
- cm_creds.use_kerberos = true;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-void cli_cm_set_fallback_after_kerberos(void)
-{
- cm_creds.fallback_after_kerberos = true;
-}
+#endif
/**********************************************************************
split a dfs path into the server, share name, and extrapath components
struct cli_state *cli,
const char *dir)
{
+ char path_sep = '\\';
+
/* Ensure the extrapath doesn't start with a separator. */
while (IS_DIRECTORY_SEP(*dir)) {
dir++;
}
- return talloc_asprintf(ctx, "\\%s\\%s\\%s",
- cli->desthost, cli->share, dir);
+ if (cli->posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
+ path_sep = '/';
+ }
+ return talloc_asprintf(ctx, "%c%s%c%s%c%s",
+ path_sep,
+ cli->desthost,
+ path_sep,
+ cli->share,
+ path_sep,
+ dir);
}
/********************************************************************
bool cli_dfs_get_referral(TALLOC_CTX *ctx,
struct cli_state *cli,
const char *path,
- CLIENT_DFS_REFERRAL**refs,
+ struct client_dfs_referral **refs,
size_t *num_refs,
- uint16 *consumed)
+ size_t *consumed)
{
unsigned int data_len = 0;
unsigned int param_len = 0;
uint16 setup = TRANSACT2_GET_DFS_REFERRAL;
- char *param;
+ char *param = NULL;
char *rparam=NULL, *rdata=NULL;
char *p;
char *endp;
size_t pathlen = 2*(strlen(path)+1);
+ smb_ucs2_t *path_ucs;
+ char *consumed_path = NULL;
+ uint16_t consumed_ucs;
uint16 num_referrals;
- CLIENT_DFS_REFERRAL *referrals = NULL;
+ struct client_dfs_referral *referrals = NULL;
bool ret = false;
*num_refs = 0;
param = SMB_MALLOC_ARRAY(char, 2+pathlen+2);
if (!param) {
- return false;
+ goto out;
}
SSVAL(param, 0, 0x03); /* max referral level */
p = ¶m[2];
+ path_ucs = (smb_ucs2_t *)p;
p += clistr_push(cli, p, path, pathlen, STR_TERMINATE);
param_len = PTR_DIFF(p, param);
param, param_len, 2, /* param, length, max */
NULL, 0, cli->max_xmit /* data, length, max */
)) {
- SAFE_FREE(param);
- return false;
+ goto out;
}
- SAFE_FREE(param);
-
if (!cli_receive_trans(cli, SMBtrans2,
&rparam, ¶m_len,
&rdata, &data_len)) {
- return false;
+ goto out;
}
if (data_len < 4) {
endp = rdata + data_len;
- *consumed = SVAL(rdata, 0);
+ consumed_ucs = SVAL(rdata, 0);
num_referrals = SVAL(rdata, 2);
+ /* consumed_ucs is the number of bytes
+ * of the UCS2 path consumed not counting any
+ * terminating null. We need to convert
+ * back to unix charset and count again
+ * to get the number of bytes consumed from
+ * the incoming path. */
+
+ if (pull_string_talloc(talloc_tos(),
+ NULL,
+ 0,
+ &consumed_path,
+ path_ucs,
+ consumed_ucs,
+ STR_UNICODE) == 0) {
+ goto out;
+ }
+ if (consumed_path == NULL) {
+ goto out;
+ }
+ *consumed = strlen(consumed_path);
+
if (num_referrals != 0) {
uint16 ref_version;
uint16 ref_size;
int i;
uint16 node_offset;
- referrals = TALLOC_ARRAY(ctx, CLIENT_DFS_REFERRAL,
- num_referrals);
+ referrals = talloc_array(ctx, struct client_dfs_referral,
+ num_referrals);
if (!referrals) {
goto out;
out:
+ TALLOC_FREE(consumed_path);
+ SAFE_FREE(param);
SAFE_FREE(rdata);
SAFE_FREE(rparam);
return ret;
bool cli_resolve_path(TALLOC_CTX *ctx,
const char *mountpt,
+ const struct user_auth_info *dfs_auth_info,
struct cli_state *rootcli,
const char *path,
struct cli_state **targetcli,
char **pp_targetpath)
{
- CLIENT_DFS_REFERRAL *refs = NULL;
+ struct client_dfs_referral *refs = NULL;
size_t num_refs = 0;
- uint16 consumed;
+ size_t consumed = 0;
struct cli_state *cli_ipc = NULL;
char *dfs_path = NULL;
char *cleanpath = NULL;
/* Check for the referral. */
- if (!(cli_ipc = cli_cm_open(ctx, rootcli,
- rootcli->desthost,
- "IPC$", false,
- (rootcli->trans_enc_state != NULL),
- rootcli->protocol,
- 0,
- 0x20))) {
+ if (!(cli_ipc = cli_cm_open(ctx,
+ rootcli,
+ rootcli->desthost,
+ "IPC$",
+ dfs_auth_info,
+ false,
+ (rootcli->trans_enc_state != NULL),
+ rootcli->protocol,
+ 0,
+ 0x20))) {
return false;
}
if (!dfs_path) {
return false;
}
- pathlen = strlen(dfs_path)*2;
+ pathlen = strlen(dfs_path);
consumed = MIN(pathlen, consumed);
- *pp_targetpath = talloc_strdup(ctx, &dfs_path[consumed/2]);
+ *pp_targetpath = talloc_strdup(ctx, &dfs_path[consumed]);
if (!*pp_targetpath) {
return false;
}
- dfs_path[consumed/2] = '\0';
+ dfs_path[consumed] = '\0';
/*
* *pp_targetpath is now the unconsumed part of the path.
if ((*targetcli = cli_cm_open(ctx, rootcli,
server,
share,
+ dfs_auth_info,
false,
(rootcli->trans_enc_state != NULL),
rootcli->protocol,
if (!strequal(*pp_targetpath, "\\") && !strequal(*pp_targetpath, "/")) {
if (cli_resolve_path(ctx,
newmount,
+ dfs_auth_info,
*targetcli,
*pp_targetpath,
&newcli,
/********************************************************************
********************************************************************/
-static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
+bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
struct cli_state *cli,
const char *sharename,
char **pp_newserver,
const char *password,
const char *domain)
{
- CLIENT_DFS_REFERRAL *refs = NULL;
+ struct client_dfs_referral *refs = NULL;
size_t num_refs = 0;
- uint16 consumed;
+ size_t consumed = 0;
char *fullpath = NULL;
bool res;
uint16 cnum;
char *newextrapath = NULL;
+ NTSTATUS status;
if (!cli || !sharename) {
return false;
}
if (force_encrypt) {
- NTSTATUS status = cli_cm_force_encryption(cli,
+ status = cli_cm_force_encryption(cli,
username,
password,
lp_workgroup(),
res = cli_dfs_get_referral(ctx, cli, fullpath, &refs, &num_refs, &consumed);
- if (!cli_tdis(cli)) {
+ status = cli_tdis(cli);
+ if (!NT_STATUS_IS_OK(status)) {
return false;
}