diff options
author | Bo Yang <boyang@novell.com> | 2009-02-20 12:00:46 +0800 |
---|---|---|
committer | Derrell Lipman <derrell.lipman@unwireduniverse.com> | 2009-02-20 09:46:46 -0500 |
commit | e256d72f0cd66c374f14a122623668de888aa5e7 (patch) | |
tree | ac0dfb0c38db1d9bb0ae353ef4013b5fd11f36ce /source3 | |
parent | 27307be0f726c899c0e8a0edfdf200650037bb61 (diff) | |
download | samba-e256d72f0cd66c374f14a122623668de888aa5e7.tar.gz samba-e256d72f0cd66c374f14a122623668de888aa5e7.tar.bz2 samba-e256d72f0cd66c374f14a122623668de888aa5e7.zip |
Make libsmbclient work with DFS
Signed-off-by: Derrell Lipman <derrell.lipman@unwireduniverse.com>
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/libsmbclient.h | 12 | ||||
-rw-r--r-- | source3/libsmb/libsmb_context.c | 37 | ||||
-rw-r--r-- | source3/libsmb/libsmb_dir.c | 27 | ||||
-rw-r--r-- | source3/libsmb/libsmb_file.c | 2 | ||||
-rw-r--r-- | source3/libsmb/libsmb_path.c | 15 | ||||
-rw-r--r-- | source3/libsmb/libsmb_server.c | 19 | ||||
-rw-r--r-- | source3/libsmb/libsmb_stat.c | 2 |
7 files changed, 108 insertions, 6 deletions
diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h index f8a6c8a235..efc471c85b 100644 --- a/source3/include/libsmbclient.h +++ b/source3/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/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index c1af48507c..0683f97ddd 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -652,3 +652,40 @@ smbc_set_credentials(char *workgroup, cli_cm_set_credentials(auth_info); TALLOC_FREE(auth_info); } + +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/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index e9b7b4f95a..1843fe262f 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -1500,6 +1500,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(); @@ -1550,6 +1552,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; @@ -1558,8 +1568,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; } @@ -1900,6 +1910,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)) { @@ -1907,6 +1923,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/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index ece056db87..28256bb241 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/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/source3/libsmb/libsmb_path.c b/source3/libsmb/libsmb_path.c index 6d69924231..3ea03446d8 100644 --- a/source3/libsmb/libsmb_path.c +++ b/source3/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/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 6d7a86241a..eda37f2187 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/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... */ @@ -601,6 +602,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/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c index 1ffe141796..f8571ff110 100644 --- a/source3/libsmb/libsmb_stat.c +++ b/source3/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) { |