Make libsmbclient work with DFS
[kamenim/samba.git] / source3 / libsmb / libsmb_dir.c
index 612a8772c0efdb6a93882bb4c890a1450b1cbb2d..1843fe262f04d4198200bb416d5325efb12d9000 100644 (file)
@@ -273,8 +273,9 @@ net_share_enum_rpc(struct cli_state *cli,
        uint32_t total_entries = 0;
 
         /* Open the server service pipe */
-        pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status);
-        if (!pipe_hnd) {
+        nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_srvsvc.syntax_id,
+                                            &pipe_hnd);
+        if (!NT_STATUS_IS_OK(nt_status)) {
                 DEBUG(1, ("net_share_enum_rpc pipe open fail!\n"));
                 return -1;
         }
@@ -319,7 +320,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;
@@ -894,7 +895,7 @@ smbc_readdir_internal(SMBCCTX * context,
 
                 /* url-encode the name.  get back remaining buffer space */
                 max_namebuf_len =
-                        SMBC_urlencode(dest->name, src->name, max_namebuf_len);
+                        smbc_urlencode(dest->name, src->name, max_namebuf_len);
 
                 /* We now know the name length */
                 dest->namelen = strlen(dest->name);
@@ -975,9 +976,8 @@ SMBC_readdir_ctx(SMBCCTX *context,
 
         }
 
-        dirp = (struct smbc_dirent *)context->internal->dirent;
-        maxlen = (sizeof(context->internal->dirent) -
-                  sizeof(struct smbc_dirent));
+        dirp = &context->internal->dirent;
+        maxlen = sizeof(context->internal->_dirent_name);
 
         smbc_readdir_internal(context, dirp, dirent, maxlen);
 
@@ -1048,9 +1048,8 @@ SMBC_getdents_ctx(SMBCCTX *context,
                }
 
                 /* Do urlencoding of next entry, if so selected */
-                dirent = (struct smbc_dirent *)context->internal->dirent;
-                maxlen = (sizeof(context->internal->dirent) -
-                          sizeof(struct smbc_dirent));
+                dirent = &context->internal->dirent;
+                maxlen = sizeof(context->internal->_dirent_name);
                 smbc_readdir_internal(context, dirent,
                                       dirlist->dirent, maxlen);
 
@@ -1192,8 +1191,6 @@ SMBC_mkdir_ctx(SMBCCTX *context,
  * Our list function simply checks to see if a directory is not empty
  */
 
-static int smbc_rmdir_dirempty = True;
-
 static void
 rmdir_list_fn(const char *mnt,
               file_info *finfo,
@@ -1202,7 +1199,8 @@ rmdir_list_fn(const char *mnt,
 {
        if (strncmp(finfo->name, ".", 1) != 0 &&
             strncmp(finfo->name, "..", 2) != 0) {
-               smbc_rmdir_dirempty = False;
+               bool *smbc_rmdir_dirempty = (bool *)state;
+               *smbc_rmdir_dirempty = false;
         }
 }
 
@@ -1291,8 +1289,7 @@ SMBC_rmdir_ctx(SMBCCTX *context,
 
                         /* Local storage to avoid buffer overflows */
                        char *lpath;
-
-                       smbc_rmdir_dirempty = True;  /* Make this so ... */
+                       bool smbc_rmdir_dirempty = true;
 
                        lpath = talloc_asprintf(frame, "%s\\*",
                                                targetpath);
@@ -1304,7 +1301,8 @@ SMBC_rmdir_ctx(SMBCCTX *context,
 
                        if (cli_list(targetcli, lpath,
                                      aDIR | aSYSTEM | aHIDDEN,
-                                     rmdir_list_fn, NULL) < 0) {
+                                     rmdir_list_fn,
+                                    &smbc_rmdir_dirempty) < 0) {
 
                                /* Fix errno to ignore latest error ... */
                                DEBUG(5, ("smbc_rmdir: "
@@ -1502,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();
@@ -1552,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;
 
@@ -1560,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;
        }
@@ -1902,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)) {
@@ -1909,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,