Make libsmbclient work with DFS
authorBo Yang <boyang@novell.com>
Fri, 20 Feb 2009 04:21:52 +0000 (12:21 +0800)
committerKarolin Seeger <kseeger@samba.org>
Mon, 23 Feb 2009 08:31:05 +0000 (09:31 +0100)
Signed-off-by: Derrell Lipman <derrell.lipman@unwireduniverse.com>
(cherry picked from commit 8457e7bba4ef2ba479340829bb89a3a8772f958b)

source/include/libsmbclient.h
source/libsmb/libsmb_context.c
source/libsmb/libsmb_dir.c
source/libsmb/libsmb_file.c
source/libsmb/libsmb_path.c
source/libsmb/libsmb_server.c
source/libsmb/libsmb_stat.c

index f8a6c8a235ece049b2e3b96bc6d4188bbdb67446..efc471c85b4c34b27cbf8fc0f02c2c09cf722bf3 100644 (file)
@@ -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
index 3f8e0c573cbd4a92fe449f4a45d709c2fe4a66b2..c8a10794351725e65f31187764951028c387e988 100644 (file)
@@ -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();
+       }
+}
index 761b8055091a1c09b4500ee815d7d44cd1362c5c..610cfcd3cf4346a024807a9cf6c41ce1b740a04d 100644 (file)
@@ -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,
index e162aaa16b75a6c4fc534114590b3bac2b8c13f0..1bbb47daebec1f330f98fe2e57cba3dfa5373b65 100644 (file)
@@ -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)) {
index 6d69924231b61b77014386e40771152ef93f1718..3ea03446d8931d38d79659097bb6c7429293394e 100644 (file)
@@ -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;
 }
index 0c411ea85f1103146453597e321b4c459a3ce54c..6880f5c3426eed4156c9f10e67ebd3b180b2cd3f 100644 (file)
@@ -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:
index 186ef130bf76219f7cc6bb6dacae804e2aee6fa3..64ddc780a8d4fce11d1aa8ad466ed9a65a69e9b1 100644 (file)
@@ -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) {