s3-talloc Change TALLOC_ZERO_P() to talloc_zero()
[nivanova/samba-autobuild/.git] / source3 / smbd / msdfs.c
index 433de8aea3ea586525a2ac6c75a5cb3786e198a9..af560ed19b432ccaeb76d3e1b070831c397242de 100644 (file)
 
 #define DBGC_CLASS DBGC_MSDFS
 #include "includes.h"
+#include "system/filesys.h"
+#include "smbd/smbd.h"
 #include "smbd/globals.h"
+#include "msdfs.h"
+#include "auth.h"
 
 /**********************************************************************
  Parse a DFS pathname of the form \hostname\service\reqpath
@@ -212,21 +216,22 @@ static NTSTATUS parse_dfs_path(connection_struct *conn,
 
 /********************************************************
  Fake up a connection struct for the VFS layer.
- Note this CHANGES CWD !!!! JRA.
+ Note: this performs a vfs connect and CHANGES CWD !!!! JRA.
 *********************************************************/
 
 NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
                                connection_struct **pconn,
                                int snum,
                                const char *path,
-                               struct auth_serversupplied_info *server_info,
+                               const struct auth_serversupplied_info *session_info,
                                char **poldcwd)
 {
        connection_struct *conn;
        char *connpath;
        char *oldcwd;
+       const char *vfs_user;
 
-       conn = TALLOC_ZERO_P(ctx, connection_struct);
+       conn = talloc_zero(ctx, connection_struct);
        if (conn == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -247,7 +252,7 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
 
        /* needed for smbd_vfs_init() */
 
-       if (!(conn->params = TALLOC_ZERO_P(conn, struct share_params))) {
+       if (!(conn->params = talloc_zero(conn, struct share_params))) {
                DEBUG(0, ("TALLOC failed\n"));
                TALLOC_FREE(conn);
                return NT_STATUS_NO_MEMORY;
@@ -255,13 +260,20 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
 
        conn->params->service = snum;
 
-       if (server_info != NULL) {
-               conn->server_info = copy_serverinfo(conn, server_info);
-               if (conn->server_info == NULL) {
+       conn->sconn = smbd_server_conn;
+       conn->sconn->num_tcons_open++;
+
+       if (session_info != NULL) {
+               conn->session_info = copy_serverinfo(conn, session_info);
+               if (conn->session_info == NULL) {
                        DEBUG(0, ("copy_serverinfo failed\n"));
                        TALLOC_FREE(conn);
                        return NT_STATUS_NO_MEMORY;
                }
+               vfs_user = conn->session_info->unix_name;
+       } else {
+               /* use current authenticated user in absence of session_info */
+               vfs_user = get_current_username();
        }
 
        set_conn_connectpath(conn, connpath);
@@ -273,6 +285,13 @@ NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
                return status;
        }
 
+       /* this must be the first filesystem operation that we do */
+       if (SMB_VFS_CONNECT(conn, lp_servicename(snum), vfs_user) < 0) {
+               DEBUG(0,("VFS connect failed!\n"));
+               conn_free(conn);
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
        conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res);
 
        /*
@@ -345,7 +364,7 @@ static bool parse_msdfs_symlink(TALLOC_CTX *ctx,
                return False;
        }
 
-       alt_path = TALLOC_ARRAY(ctx, char *, MAX_REFERRAL_COUNT);
+       alt_path = talloc_array(ctx, char *, MAX_REFERRAL_COUNT);
        if (!alt_path) {
                return False;
        }
@@ -424,7 +443,7 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx,
 
        if (pp_link_target) {
                bufsize = 1024;
-               link_target = TALLOC_ARRAY(ctx, char, bufsize);
+               link_target = talloc_array(ctx, char, bufsize);
                if (!link_target) {
                        return False;
                }
@@ -673,7 +692,7 @@ static NTSTATUS dfs_redirect(TALLOC_CTX *ctx,
                        bool *ppath_contains_wcard)
 {
        NTSTATUS status;
-       struct dfs_path *pdp = TALLOC_P(ctx, struct dfs_path);
+       struct dfs_path *pdp = talloc(ctx, struct dfs_path);
 
        if (!pdp) {
                return NT_STATUS_NO_MEMORY;
@@ -723,7 +742,7 @@ static NTSTATUS dfs_redirect(TALLOC_CTX *ctx,
        if (!( strequal(pdp->servicename, lp_servicename(SNUM(conn)))
                        || (strequal(pdp->servicename, HOMES_NAME)
                        && strequal(lp_servicename(SNUM(conn)),
-                               conn->server_info->sanitized_username) )) ) {
+                               conn->session_info->sanitized_username) )) ) {
 
                /* The given sharename doesn't match this connection. */
                TALLOC_FREE(pdp);
@@ -775,7 +794,7 @@ static NTSTATUS self_ref(TALLOC_CTX *ctx,
        *self_referralp = True;
 
        jucn->referral_count = 1;
-       if((ref = TALLOC_ZERO_P(ctx, struct referral)) == NULL) {
+       if((ref = talloc_zero(ctx, struct referral)) == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -806,7 +825,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
        int snum;
        NTSTATUS status = NT_STATUS_NOT_FOUND;
        bool dummy;
-       struct dfs_path *pdp = TALLOC_P(ctx, struct dfs_path);
+       struct dfs_path *pdp = talloc(ctx, struct dfs_path);
        char *oldpath;
 
        if (!pdp) {
@@ -830,11 +849,13 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
        /* Verify the share is a dfs root */
        snum = lp_servicenumber(jucn->service_name);
        if(snum < 0) {
-               fstring service_name;
-               fstrcpy(service_name, jucn->service_name);
-               if ((snum = find_service(service_name)) < 0) {
+               char *service_name = NULL;
+               if ((snum = find_service(ctx, jucn->service_name, &service_name)) < 0) {
                        return NT_STATUS_NOT_FOUND;
                }
+               if (!service_name) {
+                       return NT_STATUS_NO_MEMORY;
+               }
                TALLOC_FREE(jucn->service_name);
                jucn->service_name = talloc_strdup(ctx, service_name);
                if (!jucn->service_name) {
@@ -878,7 +899,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
                 */
 
                jucn->referral_count = 1;
-               if ((ref = TALLOC_ZERO_P(ctx, struct referral)) == NULL) {
+               if ((ref = talloc_zero(ctx, struct referral)) == NULL) {
                        TALLOC_FREE(pdp);
                        return NT_STATUS_NO_MEMORY;
                }
@@ -932,10 +953,7 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
        if (!NT_STATUS_EQUAL(status, NT_STATUS_PATH_NOT_COVERED)) {
                DEBUG(3,("get_referred_path: No valid referrals for path %s\n",
                        dfs_path));
-               vfs_ChDir(conn, oldpath);
-               conn_free(conn);
-               TALLOC_FREE(pdp);
-               return status;
+               goto err_exit;
        }
 
        /* We know this is a valid dfs link. Parse the targetpath. */
@@ -944,16 +962,17 @@ NTSTATUS get_referred_path(TALLOC_CTX *ctx,
                                &jucn->referral_count)) {
                DEBUG(3,("get_referred_path: failed to parse symlink "
                        "target %s\n", targetpath ));
-               vfs_ChDir(conn, oldpath);
-               conn_free(conn);
-               TALLOC_FREE(pdp);
-               return NT_STATUS_NOT_FOUND;
+               status = NT_STATUS_NOT_FOUND;
+               goto err_exit;
        }
 
+       status = NT_STATUS_OK;
+ err_exit:
        vfs_ChDir(conn, oldpath);
+       SMB_VFS_DISCONNECT(conn);
        conn_free(conn);
        TALLOC_FREE(pdp);
-       return NT_STATUS_OK;
+       return status;
 }
 
 static int setup_ver2_dfs_referral(const char *pathname,
@@ -1214,7 +1233,7 @@ int setup_dfs_referral(connection_struct *orig_conn,
                pathnamep++;
        }
 
-       junction = TALLOC_ZERO_P(ctx, struct junction_map);
+       junction = talloc_zero(ctx, struct junction_map);
        if (!junction) {
                *pstatus = NT_STATUS_NO_MEMORY;
                talloc_destroy(ctx);
@@ -1299,7 +1318,7 @@ bool create_junction(TALLOC_CTX *ctx,
 {
        int snum;
        bool dummy;
-       struct dfs_path *pdp = TALLOC_P(ctx,struct dfs_path);
+       struct dfs_path *pdp = talloc(ctx,struct dfs_path);
        NTSTATUS status;
 
        if (!pdp) {
@@ -1368,6 +1387,7 @@ static bool junction_to_local_path(const struct junction_map *jucn,
                        jucn->volume_name);
        if (!*pp_path_out) {
                vfs_ChDir(*conn_out, *oldpath);
+               SMB_VFS_DISCONNECT(*conn_out);
                conn_free(*conn_out);
                return False;
        }
@@ -1456,6 +1476,7 @@ bool create_msdfs_link(const struct junction_map *jucn)
 
 out:
        vfs_ChDir(conn, cwd);
+       SMB_VFS_DISCONNECT(conn);
        conn_free(conn);
        return ret;
 }
@@ -1487,6 +1508,7 @@ bool remove_msdfs_link(const struct junction_map *jucn)
 
        TALLOC_FREE(smb_fname);
        vfs_ChDir(conn, cwd);
+       SMB_VFS_DISCONNECT(conn);
        conn_free(conn);
        return ret;
 }
@@ -1551,6 +1573,7 @@ static int count_dfs_links(TALLOC_CTX *ctx, int snum)
 
 out:
        vfs_ChDir(conn, cwd);
+       SMB_VFS_DISCONNECT(conn);
        conn_free(conn);
        return cnt;
 }
@@ -1607,7 +1630,7 @@ static int form_junctions(TALLOC_CTX *ctx,
        jucn[cnt].comment = "";
        jucn[cnt].referral_count = 1;
 
-       ref = jucn[cnt].referral_list = TALLOC_ZERO_P(ctx, struct referral);
+       ref = jucn[cnt].referral_list = talloc_zero(ctx, struct referral);
        if (jucn[cnt].referral_list == NULL) {
                goto out;
        }
@@ -1686,7 +1709,8 @@ out:
        return cnt;
 }
 
-struct junction_map *enum_msdfs_links(TALLOC_CTX *ctx, size_t *p_num_jn)
+struct junction_map *enum_msdfs_links(struct smbd_server_connection *sconn,
+                                     TALLOC_CTX *ctx, size_t *p_num_jn)
 {
        struct junction_map *jn = NULL;
        int i=0;
@@ -1701,7 +1725,7 @@ struct junction_map *enum_msdfs_links(TALLOC_CTX *ctx, size_t *p_num_jn)
        /* Ensure all the usershares are loaded. */
        become_root();
        load_registry_shares();
-       sharecount = load_usershare_shares();
+       sharecount = load_usershare_shares(sconn);
        unbecome_root();
 
        for(i=0;i < sharecount;i++) {
@@ -1712,7 +1736,7 @@ struct junction_map *enum_msdfs_links(TALLOC_CTX *ctx, size_t *p_num_jn)
        if (jn_count == 0) {
                return NULL;
        }
-       jn = TALLOC_ARRAY(ctx,  struct junction_map, jn_count);
+       jn = talloc_array(ctx,  struct junction_map, jn_count);
        if (!jn) {
                return NULL;
        }
@@ -1763,7 +1787,7 @@ NTSTATUS resolve_dfspath_wcard(TALLOC_CTX *ctx,
                 * Once srvstr_get_path() uses talloc it'll
                 * be a talloced ptr anyway.
                 */
-               *pp_name_out = CONST_DISCARD(char *,name_in);
+               *pp_name_out = discard_const_p(char, name_in);
        }
        return status;
 }