summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBo Yang <boyang@novell.com>2009-02-20 12:21:52 +0800
committerKarolin Seeger <kseeger@samba.org>2009-02-23 09:31:05 +0100
commit922f61060c6a90bd197bfadabbf943e19318082b (patch)
tree0bfcf043ce2b9e642d791baec5924989dd70741b
parentfb89a59aa5f7b5ca5b4f2c8f20b69641c3d5c486 (diff)
downloadsamba-922f61060c6a90bd197bfadabbf943e19318082b.tar.gz
Make libsmbclient work with DFS
Signed-off-by: Derrell Lipman <derrell.lipman@unwireduniverse.com> (cherry picked from commit 8457e7bba4ef2ba479340829bb89a3a8772f958b)
-rw-r--r--source/include/libsmbclient.h12
-rw-r--r--source/libsmb/libsmb_context.c37
-rw-r--r--source/libsmb/libsmb_dir.c27
-rw-r--r--source/libsmb/libsmb_file.c2
-rw-r--r--source/libsmb/libsmb_path.c15
-rw-r--r--source/libsmb/libsmb_server.c19
-rw-r--r--source/libsmb/libsmb_stat.c2
7 files changed, 108 insertions, 6 deletions
diff --git a/source/include/libsmbclient.h b/source/include/libsmbclient.h
index f8a6c8a235e..efc471c85b4 100644
--- a/source/include/libsmbclient.h
+++ b/source/include/libsmbclient.h
@@ -2683,6 +2683,18 @@ smbc_set_credentials(char *workgroup,
smbc_bool use_kerberos,
char *signing_state);
+/*
+ * Wrapper around smbc_set_credentials.
+ * Used to set correct credentials that will
+ * be used to connect to DFS target share
+ * in libsmbclient
+ */
+
+void
+smbc_set_credentials_with_fallback(SMBCCTX *ctx,
+ char *workgroup,
+ char *user,
+ char *password);
/**
* @ingroup structure
diff --git a/source/libsmb/libsmb_context.c b/source/libsmb/libsmb_context.c
index 3f8e0c573cb..c8a10794351 100644
--- a/source/libsmb/libsmb_context.c
+++ b/source/libsmb/libsmb_context.c
@@ -646,3 +646,40 @@ smbc_set_credentials(char *workgroup,
set_global_myworkgroup(workgroup);
cli_cm_set_credentials();
}
+
+void smbc_set_credentials_with_fallback(SMBCCTX *context,
+ char *workgroup,
+ char *user,
+ char *password)
+{
+ smbc_bool use_kerberos = false;
+ const char *signing_state = "off";
+
+ if (!context || !workgroup || !*workgroup
+ || !user || !*user || !password
+ || !*password) {
+ return;
+ }
+
+ if (smbc_getOptionUseKerberos(context)) {
+ use_kerberos = True;
+ }
+
+ if (lp_client_signing()) {
+ signing_state = "on";
+ }
+
+ if (lp_client_signing() == Required) {
+ signing_state = "force";
+ }
+
+ smbc_set_credentials(workgroup,
+ user,
+ password,
+ use_kerberos,
+ (char *)signing_state);
+
+ if (smbc_getOptionFallbackAfterKerberos(context)) {
+ cli_cm_set_fallback_after_kerberos();
+ }
+}
diff --git a/source/libsmb/libsmb_dir.c b/source/libsmb/libsmb_dir.c
index 761b8055091..610cfcd3cf4 100644
--- a/source/libsmb/libsmb_dir.c
+++ b/source/libsmb/libsmb_dir.c
@@ -1501,6 +1501,8 @@ SMBC_chmod_ctx(SMBCCTX *context,
char *user = NULL;
char *password = NULL;
char *workgroup = NULL;
+ char *targetpath = NULL;
+ struct cli_state *targetcli = NULL;
char *path = NULL;
uint16 mode;
TALLOC_CTX *frame = talloc_stackframe();
@@ -1551,6 +1553,14 @@ SMBC_chmod_ctx(SMBCCTX *context,
TALLOC_FREE(frame);
return -1; /* errno set by SMBC_server */
}
+
+ /*d_printf(">>>unlink: resolving %s\n", path);*/
+ if (!cli_resolve_path(frame, "", srv->cli, path,
+ &targetcli, &targetpath)) {
+ d_printf("Could not resolve %s\n", path);
+ TALLOC_FREE(frame);
+ return -1;
+ }
mode = 0;
@@ -1559,8 +1569,8 @@ SMBC_chmod_ctx(SMBCCTX *context,
if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM;
if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN;
- if (!cli_setatr(srv->cli, path, mode, 0)) {
- errno = SMBC_errno(context, srv->cli);
+ if (!cli_setatr(targetcli, targetpath, mode, 0)) {
+ errno = SMBC_errno(context, targetcli);
TALLOC_FREE(frame);
return -1;
}
@@ -1901,6 +1911,12 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
}
+ /* set the credentials to make DFS work */
+ smbc_set_credentials_with_fallback(ocontext,
+ workgroup,
+ user1,
+ password1);
+
/*d_printf(">>>rename: resolving %s\n", path1);*/
if (!cli_resolve_path(frame, "", srv->cli, path1,
&targetcli1, &targetpath1)) {
@@ -1908,6 +1924,13 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
TALLOC_FREE(frame);
return -1;
}
+
+ /* set the credentials to make DFS work */
+ smbc_set_credentials_with_fallback(ncontext,
+ workgroup,
+ user2,
+ password2);
+
/*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/
/*d_printf(">>>rename: resolving %s\n", path2);*/
if (!cli_resolve_path(frame, "", srv->cli, path2,
diff --git a/source/libsmb/libsmb_file.c b/source/libsmb/libsmb_file.c
index e162aaa16b7..1bbb47daebe 100644
--- a/source/libsmb/libsmb_file.c
+++ b/source/libsmb/libsmb_file.c
@@ -382,7 +382,7 @@ SMBC_write_ctx(SMBCCTX *context,
TALLOC_FREE(frame);
return -1;
}
-
+
/*d_printf(">>>write: resolving %s\n", path);*/
if (!cli_resolve_path(frame, "", file->srv->cli, path,
&targetcli, &targetpath)) {
diff --git a/source/libsmb/libsmb_path.c b/source/libsmb/libsmb_path.c
index 6d69924231b..3ea03446d89 100644
--- a/source/libsmb/libsmb_path.c
+++ b/source/libsmb/libsmb_path.c
@@ -233,6 +233,7 @@ SMBC_parse_path(TALLOC_CTX *ctx,
char *s;
const char *p;
char *q, *r;
+ char *workgroup = NULL;
int len;
/* Ensure these returns are at least valid pointers. */
@@ -332,7 +333,6 @@ SMBC_parse_path(TALLOC_CTX *ctx,
u = userinfo;
if (strchr_m(u, ';')) {
- char *workgroup;
next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";");
if (!workgroup) {
return -1;
@@ -394,6 +394,19 @@ decoding:
(void) urldecode_talloc(ctx, pp_share, *pp_share);
(void) urldecode_talloc(ctx, pp_user, *pp_user);
(void) urldecode_talloc(ctx, pp_password, *pp_password);
+
+ if (!workgroup) {
+ workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context));
+ }
+ if (!workgroup) {
+ return -1;
+ }
+
+ /* set the credentials to make DFS work */
+ smbc_set_credentials_with_fallback(context,
+ workgroup,
+ *pp_user,
+ *pp_password);
return 0;
}
diff --git a/source/libsmb/libsmb_server.c b/source/libsmb/libsmb_server.c
index 0c411ea85f1..6880f5c3426 100644
--- a/source/libsmb/libsmb_server.c
+++ b/source/libsmb/libsmb_server.c
@@ -238,6 +238,7 @@ SMBC_server(TALLOC_CTX *ctx,
char **pp_password)
{
SMBCSRV *srv=NULL;
+ char *workgroup = NULL;
struct cli_state *c;
struct nmb_name called, calling;
const char *server_n = server;
@@ -359,7 +360,7 @@ SMBC_server(TALLOC_CTX *ctx,
if (srv) {
/* ... then we're done here. Give 'em what they came for. */
- return srv;
+ goto done;
}
/* If we're not asked to connect when a connection doesn't exist... */
@@ -598,6 +599,22 @@ again:
server, share, srv));
DLIST_ADD(context->internal->servers, srv);
+done:
+ if (!pp_workgroup || !*pp_workgroup || !**pp_workgroup) {
+ workgroup = talloc_strdup(ctx, smbc_getWorkgroup(context));
+ } else {
+ workgroup = *pp_workgroup;
+ }
+ if(!workgroup) {
+ return NULL;
+ }
+
+ /* set the credentials to make DFS work */
+ smbc_set_credentials_with_fallback(context,
+ workgroup,
+ *pp_username,
+ *pp_password);
+
return srv;
failed:
diff --git a/source/libsmb/libsmb_stat.c b/source/libsmb/libsmb_stat.c
index 186ef130bf7..64ddc780a8d 100644
--- a/source/libsmb/libsmb_stat.c
+++ b/source/libsmb/libsmb_stat.c
@@ -155,7 +155,7 @@ SMBC_stat_ctx(SMBCCTX *context,
TALLOC_FREE(frame);
return -1;
}
-
+
if (!user || user[0] == (char)0) {
user = talloc_strdup(frame, smbc_getUser(context));
if (!user) {