Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/smbd/msdfs.c

    r860 r988  
    55   Copyright (C) Shirish Kalele 2000
    66   Copyright (C) Jeremy Allison 2007
     7   Copyright (C) Robin McCorkell 2015
    78
    89   This program is free software; you can redistribute it and/or modify
     
    2829#include "msdfs.h"
    2930#include "auth.h"
     31#include "lib/param/loadparm.h"
    3032#include "libcli/security/security.h"
     33#include "librpc/gen_ndr/ndr_dfsblobs.h"
    3134
    3235/**********************************************************************
     
    5356                                const char *pathname,
    5457                                bool allow_wcards,
     58                                bool allow_broken_path,
    5559                                struct dfs_path *pdp, /* MUST BE TALLOCED */
    5660                                bool *ppath_contains_wcard)
    5761{
    58         struct smbd_server_connection *sconn = smbd_server_conn;
    5962        char *pathname_local;
    6063        char *p,*temp;
     
    8487        sepchar = pdp->posix_path ? '/' : '\\';
    8588
    86         if (!sconn->using_smb2 && (*pathname != sepchar)) {
     89        if (allow_broken_path && (*pathname != sepchar)) {
    8790                DEBUG(10,("parse_dfs_path: path %s doesn't start with %c\n",
    8891                        pathname, sepchar ));
     
    146149
    147150        /* Is this really our servicename ? */
    148         if (conn && !( strequal(servicename, lp_servicename(SNUM(conn)))
     151        if (conn && !( strequal(servicename, lp_servicename(talloc_tos(), SNUM(conn)))
    149152                        || (strequal(servicename, HOMES_NAME)
    150                         && strequal(lp_servicename(SNUM(conn)),
     153                        && strequal(lp_servicename(talloc_tos(), SNUM(conn)),
    151154                                get_current_username()) )) ) {
    152155                DEBUG(10,("parse_dfs_path: %s is not our servicename\n",
     
    217220
    218221/********************************************************
    219  Fake up a connection struct for the VFS layer.
    220  Note: this performs a vfs connect and CHANGES CWD !!!! JRA.
     222 Fake up a connection struct for the VFS layer, for use in
     223 applications (such as the python bindings), that do not want the
     224 global working directory changed under them.
     225
     226 SMB_VFS_CONNECT requires root privileges.
    221227*********************************************************/
    222228
    223 NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
    224                                 connection_struct **pconn,
    225                                 int snum,
    226                                 const char *path,
    227                                 const struct auth_serversupplied_info *session_info,
    228                                 char **poldcwd)
     229static NTSTATUS create_conn_struct_as_root(TALLOC_CTX *ctx,
     230                            struct tevent_context *ev,
     231                            struct messaging_context *msg,
     232                            connection_struct **pconn,
     233                            int snum,
     234                            const char *path,
     235                            const struct auth_session_info *session_info)
    229236{
    230237        connection_struct *conn;
    231238        char *connpath;
    232         char *oldcwd;
    233239        const char *vfs_user;
    234 
    235         conn = TALLOC_ZERO_P(ctx, connection_struct);
     240        struct smbd_server_connection *sconn;
     241        const char *servicename = lp_const_servicename(snum);
     242
     243        sconn = talloc_zero(ctx, struct smbd_server_connection);
     244        if (sconn == NULL) {
     245                return NT_STATUS_NO_MEMORY;
     246        }
     247
     248        sconn->ev_ctx = ev;
     249        sconn->msg_ctx = msg;
     250
     251        conn = conn_new(sconn);
    236252        if (conn == NULL) {
     253                TALLOC_FREE(sconn);
    237254                return NT_STATUS_NO_MEMORY;
     255        }
     256
     257        /* Now we have conn, we need to make sconn a child of conn,
     258         * for a proper talloc tree */
     259        talloc_steal(conn, sconn);
     260
     261        if (snum == -1 && servicename == NULL) {
     262                servicename = "Unknown Service (snum == -1)";
    238263        }
    239264
     
    244269        }
    245270        connpath = talloc_string_sub(conn,
    246                                 connpath,
    247                                 "%S",
    248                                 lp_servicename(snum));
     271                                     connpath,
     272                                     "%S",
     273                                     servicename);
    249274        if (!connpath) {
    250275                TALLOC_FREE(conn);
     
    254279        /* needed for smbd_vfs_init() */
    255280
    256         if (!(conn->params = TALLOC_ZERO_P(conn, struct share_params))) {
    257                 DEBUG(0, ("TALLOC failed\n"));
    258                 TALLOC_FREE(conn);
    259                 return NT_STATUS_NO_MEMORY;
    260         }
    261 
    262281        conn->params->service = snum;
    263 
    264         conn->sconn = smbd_server_conn;
    265         conn->sconn->num_tcons_open++;
     282        conn->cnum = TID_FIELD_INVALID;
    266283
    267284        if (session_info != NULL) {
    268                 conn->session_info = copy_serverinfo(conn, session_info);
     285                conn->session_info = copy_session_info(conn, session_info);
    269286                if (conn->session_info == NULL) {
    270287                        DEBUG(0, ("copy_serverinfo failed\n"));
     
    272289                        return NT_STATUS_NO_MEMORY;
    273290                }
    274                 vfs_user = conn->session_info->unix_name;
     291                vfs_user = conn->session_info->unix_info->unix_name;
    275292        } else {
    276293                /* use current authenticated user in absence of session_info */
     
    281298
    282299        /*
    283          * New code to check if there's a share security descripter
     300         * New code to check if there's a share security descriptor
    284301         * added from NT server manager. This is done after the
    285302         * smb.conf checks are done as we need a uid and token. JRA.
     
    288305        if (conn->session_info) {
    289306                share_access_check(conn->session_info->security_token,
    290                                    lp_servicename(snum), MAXIMUM_ALLOWED_ACCESS,
     307                                   servicename,
     308                                   MAXIMUM_ALLOWED_ACCESS,
    291309                                   &conn->share_access);
    292310
     
    294312                        if ((conn->share_access & FILE_READ_DATA) == 0) {
    295313                                /* No access, read or write. */
    296                                 DEBUG(0,("create_conn_struct: connection to %s "
     314                                DEBUG(3,("create_conn_struct: connection to %s "
    297315                                         "denied due to security "
    298316                                         "descriptor.\n",
    299                                          lp_servicename(snum)));
     317                                         servicename));
    300318                                conn_free(conn);
    301319                                return NT_STATUS_ACCESS_DENIED;
     
    317335
    318336        /* this must be the first filesystem operation that we do */
    319         if (SMB_VFS_CONNECT(conn, lp_servicename(snum), vfs_user) < 0) {
     337        if (SMB_VFS_CONNECT(conn, servicename, vfs_user) < 0) {
    320338                DEBUG(0,("VFS connect failed!\n"));
    321339                conn_free(conn);
     
    324342
    325343        conn->fs_capabilities = SMB_VFS_FS_CAPABILITIES(conn, &conn->ts_res);
     344        *pconn = conn;
     345
     346        return NT_STATUS_OK;
     347}
     348
     349/********************************************************
     350 Fake up a connection struct for the VFS layer, for use in
     351 applications (such as the python bindings), that do not want the
     352 global working directory changed under them.
     353
     354 SMB_VFS_CONNECT requires root privileges.
     355*********************************************************/
     356
     357NTSTATUS create_conn_struct(TALLOC_CTX *ctx,
     358                            struct tevent_context *ev,
     359                            struct messaging_context *msg,
     360                            connection_struct **pconn,
     361                            int snum,
     362                            const char *path,
     363                            const struct auth_session_info *session_info)
     364{
     365        NTSTATUS status;
     366        become_root();
     367        status = create_conn_struct_as_root(ctx, ev,
     368                                            msg, pconn,
     369                                            snum, path,
     370                                            session_info);
     371        unbecome_root();
     372
     373        return status;
     374}
     375
     376/********************************************************
     377 Fake up a connection struct for the VFS layer.
     378 Note: this performs a vfs connect and CHANGES CWD !!!! JRA.
     379
     380 The old working directory is returned on *poldcwd, allocated on ctx.
     381*********************************************************/
     382
     383NTSTATUS create_conn_struct_cwd(TALLOC_CTX *ctx,
     384                                struct tevent_context *ev,
     385                                struct messaging_context *msg,
     386                                connection_struct **pconn,
     387                                int snum,
     388                                const char *path,
     389                                const struct auth_session_info *session_info,
     390                                char **poldcwd)
     391{
     392        connection_struct *conn;
     393        char *oldcwd;
     394
     395        NTSTATUS status = create_conn_struct(ctx, ev,
     396                                             msg, &conn,
     397                                             snum, path,
     398                                             session_info);
     399        if (!NT_STATUS_IS_OK(status)) {
     400                return status;
     401        }
    326402
    327403        /*
     
    333409        oldcwd = vfs_GetWd(ctx, conn);
    334410        if (oldcwd == NULL) {
    335                 NTSTATUS status = map_nt_error_from_unix(errno);
     411                status = map_nt_error_from_unix(errno);
    336412                DEBUG(3, ("vfs_GetWd failed: %s\n", strerror(errno)));
    337413                conn_free(conn);
     
    340416
    341417        if (vfs_ChDir(conn,conn->connectpath) != 0) {
    342                 NTSTATUS status = map_nt_error_from_unix(errno);
     418                status = map_nt_error_from_unix(errno);
    343419                DEBUG(3,("create_conn_struct: Can't ChDir to new conn path %s. "
    344420                        "Error was %s\n",
     
    354430}
    355431
     432static void shuffle_strlist(char **list, int count)
     433{
     434        int i;
     435        uint32_t r;
     436        char *tmp;
     437
     438        for (i = count; i > 1; i--) {
     439                r = generate_random() % i;
     440
     441                tmp = list[i-1];
     442                list[i-1] = list[r];
     443                list[r] = tmp;
     444        }
     445}
     446
    356447/**********************************************************************
    357448 Parse the contents of a symlink to verify if it is an msdfs referral
     
    374465
    375466static bool parse_msdfs_symlink(TALLOC_CTX *ctx,
     467                                int snum,
    376468                                const char *target,
    377469                                struct referral **preflist,
     
    395487        }
    396488
    397         alt_path = TALLOC_ARRAY(ctx, char *, MAX_REFERRAL_COUNT);
     489        alt_path = talloc_array(ctx, char *, MAX_REFERRAL_COUNT);
    398490        if (!alt_path) {
    399491                return False;
     
    406498        }
    407499
     500        /* shuffle alternate paths */
     501        if (lp_msdfs_shuffle_referrals(snum)) {
     502                shuffle_strlist(alt_path, count);
     503        }
     504
    408505        DEBUG(10,("parse_msdfs_symlink: count=%d\n", count));
    409506
    410507        if (count) {
    411                 reflist = *preflist = TALLOC_ZERO_ARRAY(ctx,
     508                reflist = *preflist = talloc_zero_array(ctx,
    412509                                struct referral, count);
    413510                if(reflist == NULL) {
     
    474571        if (pp_link_target) {
    475572                bufsize = 1024;
    476                 link_target = TALLOC_ARRAY(ctx, char, bufsize);
     573                link_target = talloc_array(ctx, char, bufsize);
    477574                if (!link_target) {
    478575                        return False;
     
    576673
    577674        /*
    578          * Note the unix path conversion here we're doing we
     675         * Note the unix path conversion here we're doing we
    579676         * throw away. We're looking for a symlink for a dfs
    580677         * resolution, if we don't find it we'll do another
     
    710807                        const char *path_in,
    711808                        bool search_wcard_flag,
     809                        bool allow_broken_path,
    712810                        char **pp_path_out,
    713811                        bool *ppath_contains_wcard)
    714812{
    715813        NTSTATUS status;
    716         struct dfs_path *pdp = TALLOC_P(ctx, struct dfs_path);
     814        struct dfs_path *pdp = talloc(ctx, struct dfs_path);
    717815
    718816        if (!pdp) {
     
    720818        }
    721819
    722         status = parse_dfs_path(conn, path_in, search_wcard_flag, pdp,
     820        status = parse_dfs_path(conn, path_in, search_wcard_flag,
     821                                allow_broken_path, pdp,
    723822                        ppath_contains_wcard);
    724823        if (!NT_STATUS_IS_OK(status)) {
     
    761860        }
    762861
    763         if (!( strequal(pdp->servicename, lp_servicename(SNUM(conn)))
     862        if (!( strequal(pdp->servicename, lp_servicename(talloc_tos(), SNUM(conn)))
    764863                        || (strequal(pdp->servicename, HOMES_NAME)
    765                         && strequal(lp_servicename(SNUM(conn)),
    766                                 conn->session_info->sanitized_username) )) ) {
     864                        && strequal(lp_servicename(talloc_tos(), SNUM(conn)),
     865                                conn->session_info->unix_info->sanitized_username) )) ) {
    767866
    768867                /* The given sharename doesn't match this connection. */
     
    816915
    817916        jucn->referral_count = 1;
    818         if((ref = TALLOC_ZERO_P(ctx, struct referral)) == NULL) {
     917        if((ref = talloc_zero(ctx, struct referral)) == NULL) {
    819918                return NT_STATUS_NO_MEMORY;
    820919        }
     
    822921        ref->alternate_path = talloc_strdup(ctx, dfs_path);
    823922        if (!ref->alternate_path) {
     923                TALLOC_FREE(ref);
    824924                return NT_STATUS_NO_MEMORY;
    825925        }
     
    838938NTSTATUS get_referred_path(TALLOC_CTX *ctx,
    839939                        const char *dfs_path,
     940                        bool allow_broken_path,
    840941                        struct junction_map *jucn,
    841942                        int *consumedcntp,
     
    847948        NTSTATUS status = NT_STATUS_NOT_FOUND;
    848949        bool dummy;
    849         struct dfs_path *pdp = TALLOC_P(ctx, struct dfs_path);
     950        struct dfs_path *pdp = talloc(ctx, struct dfs_path);
    850951        char *oldpath;
    851952
     
    856957        *self_referralp = False;
    857958
    858         status = parse_dfs_path(NULL, dfs_path, False, pdp, &dummy);
     959        status = parse_dfs_path(NULL, dfs_path, False, allow_broken_path,
     960                                pdp, &dummy);
    859961        if (!NT_STATUS_IS_OK(status)) {
    860962                return status;
     
    886988        }
    887989
    888         if (!lp_msdfs_root(snum) && (*lp_msdfs_proxy(snum) == '\0')) {
     990        if (!lp_msdfs_root(snum) && (*lp_msdfs_proxy(talloc_tos(), snum) == '\0')) {
    889991                DEBUG(3,("get_referred_path: |%s| in dfs path %s is not "
    890992                        "a dfs root.\n",
     
    9051007                char *tmp;
    9061008                struct referral *ref;
    907 
    908                 if (*lp_msdfs_proxy(snum) == '\0') {
     1009                int refcount;
     1010
     1011                if (*lp_msdfs_proxy(talloc_tos(), snum) == '\0') {
    9091012                        TALLOC_FREE(pdp);
    9101013                        return self_ref(ctx,
     
    9201023                 */
    9211024
    922                 jucn->referral_count = 1;
    923                 if ((ref = TALLOC_ZERO_P(ctx, struct referral)) == NULL) {
     1025                tmp = talloc_asprintf(talloc_tos(), "msdfs:%s",
     1026                                      lp_msdfs_proxy(talloc_tos(), snum));
     1027                if (tmp == NULL) {
    9241028                        TALLOC_FREE(pdp);
    9251029                        return NT_STATUS_NO_MEMORY;
    9261030                }
    9271031
    928                 if (!(tmp = talloc_strdup(ctx, lp_msdfs_proxy(snum)))) {
     1032                if (!parse_msdfs_symlink(ctx, snum, tmp, &ref, &refcount)) {
     1033                        TALLOC_FREE(tmp);
    9291034                        TALLOC_FREE(pdp);
    930                         return NT_STATUS_NO_MEMORY;
    931                 }
    932 
    933                 trim_string(tmp, "\\", 0);
    934 
    935                 ref->alternate_path = talloc_asprintf(ctx, "\\%s", tmp);
     1035                        return NT_STATUS_INVALID_PARAMETER;
     1036                }
    9361037                TALLOC_FREE(tmp);
    937 
    938                 if (!ref->alternate_path) {
    939                         TALLOC_FREE(pdp);
    940                         return NT_STATUS_NO_MEMORY;
    941                 }
    942 
    943                 if (pdp->reqpath[0] != '\0') {
    944                         ref->alternate_path = talloc_asprintf_append(
    945                                         ref->alternate_path,
    946                                         "%s",
    947                                         pdp->reqpath);
    948                         if (!ref->alternate_path) {
    949                                 TALLOC_FREE(pdp);
    950                                 return NT_STATUS_NO_MEMORY;
    951                         }
    952                 }
    953                 ref->proximity = 0;
    954                 ref->ttl = REFERRAL_TTL;
     1038                jucn->referral_count = refcount;
    9551039                jucn->referral_list = ref;
    9561040                *consumedcntp = strlen(dfs_path);
     
    9591043        }
    9601044
    961         status = create_conn_struct(ctx, &conn, snum, lp_pathname(snum),
    962                                     NULL, &oldpath);
     1045        status = create_conn_struct_cwd(ctx,
     1046                                        server_event_context(),
     1047                                        server_messaging_context(),
     1048                                        &conn, snum,
     1049                                        lp_path(talloc_tos(), snum), NULL, &oldpath);
    9631050        if (!NT_STATUS_IS_OK(status)) {
    9641051                TALLOC_FREE(pdp);
     
    9921079
    9931080        /* We know this is a valid dfs link. Parse the targetpath. */
    994         if (!parse_msdfs_symlink(ctx, targetpath,
     1081        if (!parse_msdfs_symlink(ctx, snum, targetpath,
    9951082                                &jucn->referral_list,
    9961083                                &jucn->referral_count)) {
     
    10101097}
    10111098
    1012 static int setup_ver2_dfs_referral(const char *pathname,
    1013                                 char **ppdata,
    1014                                 struct junction_map *junction,
    1015                                 bool self_referral)
    1016 {
    1017         char* pdata = *ppdata;
    1018 
    1019         smb_ucs2_t *uni_requestedpath = NULL;
    1020         int uni_reqpathoffset1,uni_reqpathoffset2;
    1021         int uni_curroffset;
    1022         int requestedpathlen=0;
    1023         int offset;
    1024         int reply_size = 0;
    1025         int i=0;
    1026 
    1027         DEBUG(10,("Setting up version2 referral\nRequested path:\n"));
    1028 
    1029         requestedpathlen = rpcstr_push_talloc(talloc_tos(),
    1030                                         &uni_requestedpath, pathname);
    1031         if (uni_requestedpath == NULL || requestedpathlen == 0) {
    1032                 return -1;
    1033         }
    1034 
    1035         if (DEBUGLVL(10)) {
    1036                 dump_data(0, (unsigned char *)uni_requestedpath,
    1037                         requestedpathlen);
    1038         }
    1039 
    1040         DEBUG(10,("ref count = %u\n",junction->referral_count));
    1041 
    1042         uni_reqpathoffset1 = REFERRAL_HEADER_SIZE +
    1043                         VERSION2_REFERRAL_SIZE * junction->referral_count;
    1044 
    1045         uni_reqpathoffset2 = uni_reqpathoffset1 + requestedpathlen;
    1046 
    1047         uni_curroffset = uni_reqpathoffset2 + requestedpathlen;
    1048 
    1049         reply_size = REFERRAL_HEADER_SIZE +
    1050                         VERSION2_REFERRAL_SIZE*junction->referral_count +
    1051                         2 * requestedpathlen;
    1052         DEBUG(10,("reply_size: %u\n",reply_size));
    1053 
    1054         /* add up the unicode lengths of all the referral paths */
    1055         for(i=0;i<junction->referral_count;i++) {
    1056                 DEBUG(10,("referral %u : %s\n",
    1057                         i,
    1058                         junction->referral_list[i].alternate_path));
    1059                 reply_size +=
    1060                         (strlen(junction->referral_list[i].alternate_path)+1)*2;
    1061         }
    1062 
    1063         DEBUG(10,("reply_size = %u\n",reply_size));
    1064         /* add the unexplained 0x16 bytes */
    1065         reply_size += 0x16;
    1066 
    1067         pdata = (char *)SMB_REALLOC(pdata,reply_size);
    1068         if(pdata == NULL) {
    1069                 DEBUG(0,("Realloc failed!\n"));
    1070                 return -1;
    1071         }
    1072         *ppdata = pdata;
    1073 
    1074         /* copy in the dfs requested paths.. required for offset calculations */
    1075         memcpy(pdata+uni_reqpathoffset1,uni_requestedpath,requestedpathlen);
    1076         memcpy(pdata+uni_reqpathoffset2,uni_requestedpath,requestedpathlen);
    1077 
    1078         /* create the header */
    1079         SSVAL(pdata,0,requestedpathlen - 2); /* UCS2 of path consumed minus
    1080                                                 2 byte null */
    1081         /* number of referral in this pkt */
    1082         SSVAL(pdata,2,junction->referral_count);
    1083         if(self_referral) {
    1084                 SIVAL(pdata,4,DFSREF_REFERRAL_SERVER | DFSREF_STORAGE_SERVER);
    1085         } else {
    1086                 SIVAL(pdata,4,DFSREF_STORAGE_SERVER);
    1087         }
    1088 
    1089         offset = 8;
    1090         /* add the referral elements */
    1091         for(i=0;i<junction->referral_count;i++) {
    1092                 struct referral* ref = &junction->referral_list[i];
    1093                 int unilen;
    1094 
    1095                 SSVAL(pdata,offset,2); /* version 2 */
    1096                 SSVAL(pdata,offset+2,VERSION2_REFERRAL_SIZE);
    1097                 if(self_referral) {
    1098                         SSVAL(pdata,offset+4,1);
    1099                 } else {
    1100                         SSVAL(pdata,offset+4,0);
    1101                 }
    1102 
    1103                 /* ref_flags :use path_consumed bytes? */
    1104                 SSVAL(pdata,offset+6,0);
    1105                 SIVAL(pdata,offset+8,ref->proximity);
    1106                 SIVAL(pdata,offset+12,ref->ttl);
    1107 
    1108                 SSVAL(pdata,offset+16,uni_reqpathoffset1-offset);
    1109                 SSVAL(pdata,offset+18,uni_reqpathoffset2-offset);
    1110                 /* copy referred path into current offset */
    1111                 unilen = rpcstr_push(pdata+uni_curroffset,
    1112                                         ref->alternate_path,
    1113                                         reply_size - uni_curroffset,
    1114                                         STR_UNICODE);
    1115 
    1116                 SSVAL(pdata,offset+20,uni_curroffset-offset);
    1117 
    1118                 uni_curroffset += unilen;
    1119                 offset += VERSION2_REFERRAL_SIZE;
    1120         }
    1121         /* add in the unexplained 22 (0x16) bytes at the end */
    1122         memset(pdata+uni_curroffset,'\0',0x16);
    1123         return reply_size;
    1124 }
    1125 
    1126 static int setup_ver3_dfs_referral(const char *pathname,
    1127                                 char **ppdata,
    1128                                 struct junction_map *junction,
    1129                                 bool self_referral)
    1130 {
    1131         char *pdata = *ppdata;
    1132 
    1133         smb_ucs2_t *uni_reqpath = NULL;
    1134         int uni_reqpathoffset1, uni_reqpathoffset2;
    1135         int uni_curroffset;
    1136         int reply_size = 0;
    1137 
    1138         int reqpathlen = 0;
    1139         int offset,i=0;
    1140 
    1141         DEBUG(10,("setting up version3 referral\n"));
    1142 
    1143         reqpathlen = rpcstr_push_talloc(talloc_tos(), &uni_reqpath, pathname);
    1144         if (uni_reqpath == NULL || reqpathlen == 0) {
    1145                 return -1;
    1146         }
    1147 
    1148         if (DEBUGLVL(10)) {
    1149                 dump_data(0, (unsigned char *)uni_reqpath,
    1150                         reqpathlen);
    1151         }
    1152 
    1153         uni_reqpathoffset1 = REFERRAL_HEADER_SIZE +
    1154                         VERSION3_REFERRAL_SIZE * junction->referral_count;
    1155         uni_reqpathoffset2 = uni_reqpathoffset1 + reqpathlen;
    1156         reply_size = uni_curroffset = uni_reqpathoffset2 + reqpathlen;
    1157 
    1158         for(i=0;i<junction->referral_count;i++) {
    1159                 DEBUG(10,("referral %u : %s\n",
    1160                         i,
    1161                         junction->referral_list[i].alternate_path));
    1162                 reply_size +=
    1163                         (strlen(junction->referral_list[i].alternate_path)+1)*2;
    1164         }
    1165 
    1166         pdata = (char *)SMB_REALLOC(pdata,reply_size);
    1167         if(pdata == NULL) {
    1168                 DEBUG(0,("version3 referral setup:"
    1169                         "malloc failed for Realloc!\n"));
    1170                 return -1;
    1171         }
    1172         *ppdata = pdata;
    1173 
    1174         /* create the header */
    1175         SSVAL(pdata,0,reqpathlen - 2); /* UCS2 of path consumed minus
    1176                                           2 byte null */
    1177         SSVAL(pdata,2,junction->referral_count); /* number of referral */
    1178         if(self_referral) {
    1179                 SIVAL(pdata,4,DFSREF_REFERRAL_SERVER | DFSREF_STORAGE_SERVER);
    1180         } else {
    1181                 SIVAL(pdata,4,DFSREF_STORAGE_SERVER);
    1182         }
    1183 
    1184         /* copy in the reqpaths */
    1185         memcpy(pdata+uni_reqpathoffset1,uni_reqpath,reqpathlen);
    1186         memcpy(pdata+uni_reqpathoffset2,uni_reqpath,reqpathlen);
    1187 
    1188         offset = 8;
    1189         for(i=0;i<junction->referral_count;i++) {
    1190                 struct referral* ref = &(junction->referral_list[i]);
    1191                 int unilen;
    1192 
    1193                 SSVAL(pdata,offset,3); /* version 3 */
    1194                 SSVAL(pdata,offset+2,VERSION3_REFERRAL_SIZE);
    1195                 if(self_referral) {
    1196                         SSVAL(pdata,offset+4,1);
    1197                 } else {
    1198                         SSVAL(pdata,offset+4,0);
    1199                 }
    1200 
    1201                 /* ref_flags :use path_consumed bytes? */
    1202                 SSVAL(pdata,offset+6,0);
    1203                 SIVAL(pdata,offset+8,ref->ttl);
    1204 
    1205                 SSVAL(pdata,offset+12,uni_reqpathoffset1-offset);
    1206                 SSVAL(pdata,offset+14,uni_reqpathoffset2-offset);
    1207                 /* copy referred path into current offset */
    1208                 unilen = rpcstr_push(pdata+uni_curroffset,ref->alternate_path,
    1209                                         reply_size - uni_curroffset,
    1210                                         STR_UNICODE | STR_TERMINATE);
    1211                 SSVAL(pdata,offset+16,uni_curroffset-offset);
    1212                 /* copy 0x10 bytes of 00's in the ServiceSite GUID */
    1213                 memset(pdata+offset+18,'\0',16);
    1214 
    1215                 uni_curroffset += unilen;
    1216                 offset += VERSION3_REFERRAL_SIZE;
    1217         }
    1218         return reply_size;
    1219 }
    1220 
    12211099/******************************************************************
    12221100 Set up the DFS referral for the dfs pathname. This call returns
     
    12311109                        char **ppdata, NTSTATUS *pstatus)
    12321110{
    1233         struct junction_map *junction = NULL;
    1234         int consumedcnt = 0;
    1235         bool self_referral = False;
     1111        char *pdata = *ppdata;
    12361112        int reply_size = 0;
    1237         char *pathnamep = NULL;
    1238         char *local_dfs_path = NULL;
    1239         TALLOC_CTX *ctx;
    1240 
    1241         if (!(ctx=talloc_init("setup_dfs_referral"))) {
     1113        struct dfs_GetDFSReferral *r;
     1114        DATA_BLOB blob = data_blob_null;
     1115        NTSTATUS status;
     1116        enum ndr_err_code ndr_err;
     1117
     1118        r = talloc_zero(talloc_tos(), struct dfs_GetDFSReferral);
     1119        if (r == NULL) {
    12421120                *pstatus = NT_STATUS_NO_MEMORY;
    12431121                return -1;
    12441122        }
    12451123
    1246         /* get the junction entry */
    1247         if (!dfs_path) {
    1248                 talloc_destroy(ctx);
    1249                 *pstatus = NT_STATUS_NOT_FOUND;
     1124        r->in.req.max_referral_level = max_referral_level;
     1125        r->in.req.servername = talloc_strdup(r, dfs_path);
     1126        if (r->in.req.servername == NULL) {
     1127                talloc_free(r);
     1128                *pstatus = NT_STATUS_NO_MEMORY;
    12501129                return -1;
    12511130        }
    12521131
    1253         /*
    1254          * Trim pathname sent by client so it begins with only one backslash.
    1255          * Two backslashes confuse some dfs clients
    1256          */
    1257 
    1258         local_dfs_path = talloc_strdup(ctx,dfs_path);
    1259         if (!local_dfs_path) {
    1260                 *pstatus = NT_STATUS_NO_MEMORY;
    1261                 talloc_destroy(ctx);
     1132        status = SMB_VFS_GET_DFS_REFERRALS(orig_conn, r);
     1133        if (!NT_STATUS_IS_OK(status)) {
     1134                talloc_free(r);
     1135                *pstatus = status;
    12621136                return -1;
    12631137        }
    1264         pathnamep = local_dfs_path;
    1265         while (IS_DIRECTORY_SEP(pathnamep[0]) &&
    1266                         IS_DIRECTORY_SEP(pathnamep[1])) {
    1267                 pathnamep++;
    1268         }
    1269 
    1270         junction = TALLOC_ZERO_P(ctx, struct junction_map);
    1271         if (!junction) {
    1272                 *pstatus = NT_STATUS_NO_MEMORY;
    1273                 talloc_destroy(ctx);
     1138
     1139        ndr_err = ndr_push_struct_blob(&blob, r,
     1140                                r->out.resp,
     1141                                (ndr_push_flags_fn_t)ndr_push_dfs_referral_resp);
     1142        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1143                TALLOC_FREE(r);
     1144                *pstatus = NT_STATUS_INVALID_PARAMETER;
    12741145                return -1;
    12751146        }
    12761147
    1277         /* The following call can change cwd. */
    1278         *pstatus = get_referred_path(ctx, pathnamep, junction,
    1279                         &consumedcnt, &self_referral);
    1280         if (!NT_STATUS_IS_OK(*pstatus)) {
    1281                 vfs_ChDir(orig_conn,orig_conn->connectpath);
    1282                 talloc_destroy(ctx);
     1148        pdata = (char *)SMB_REALLOC(pdata, blob.length);
     1149        if(pdata == NULL) {
     1150                TALLOC_FREE(r);
     1151                DEBUG(0,("referral setup:"
     1152                         "malloc failed for Realloc!\n"));
    12831153                return -1;
    12841154        }
    1285         vfs_ChDir(orig_conn,orig_conn->connectpath);
    1286 
    1287         if (!self_referral) {
    1288                 pathnamep[consumedcnt] = '\0';
    1289 
    1290                 if( DEBUGLVL( 3 ) ) {
    1291                         int i=0;
    1292                         dbgtext("setup_dfs_referral: Path %s to "
    1293                                 "alternate path(s):",
    1294                                 pathnamep);
    1295                         for(i=0;i<junction->referral_count;i++)
    1296                                 dbgtext(" %s",
    1297                                 junction->referral_list[i].alternate_path);
    1298                         dbgtext(".\n");
    1299                 }
    1300         }
    1301 
    1302         /* create the referral depeding on version */
    1303         DEBUG(10,("max_referral_level :%d\n",max_referral_level));
    1304 
    1305         if (max_referral_level < 2) {
    1306                 max_referral_level = 2;
    1307         }
    1308         if (max_referral_level > 3) {
    1309                 max_referral_level = 3;
    1310         }
    1311 
    1312         switch(max_referral_level) {
    1313         case 2:
    1314                 reply_size = setup_ver2_dfs_referral(pathnamep,
    1315                                         ppdata, junction,
    1316                                         self_referral);
    1317                 break;
    1318         case 3:
    1319                 reply_size = setup_ver3_dfs_referral(pathnamep, ppdata,
    1320                                         junction, self_referral);
    1321                 break;
    1322         default:
    1323                 DEBUG(0,("setup_dfs_referral: Invalid dfs referral "
    1324                         "version: %d\n",
    1325                         max_referral_level));
    1326                 talloc_destroy(ctx);
    1327                 *pstatus = NT_STATUS_INVALID_LEVEL;
    1328                 return -1;
    1329         }
    1330 
    1331         if (DEBUGLVL(10)) {
    1332                 DEBUGADD(0,("DFS Referral pdata:\n"));
    1333                 dump_data(0,(uint8 *)*ppdata,reply_size);
    1334         }
    1335 
    1336         talloc_destroy(ctx);
     1155        *ppdata = pdata;
     1156        reply_size = blob.length;
     1157        memcpy(pdata, blob.data, blob.length);
     1158        TALLOC_FREE(r);
     1159
    13371160        *pstatus = NT_STATUS_OK;
    13381161        return reply_size;
     
    13491172bool create_junction(TALLOC_CTX *ctx,
    13501173                const char *dfs_path,
     1174                bool allow_broken_path,
    13511175                struct junction_map *jucn)
    13521176{
    13531177        int snum;
    13541178        bool dummy;
    1355         struct dfs_path *pdp = TALLOC_P(ctx,struct dfs_path);
     1179        struct dfs_path *pdp = talloc(ctx,struct dfs_path);
    13561180        NTSTATUS status;
    13571181
     
    13591183                return False;
    13601184        }
    1361         status = parse_dfs_path(NULL, dfs_path, False, pdp, &dummy);
     1185        status = parse_dfs_path(NULL, dfs_path, False, allow_broken_path,
     1186                                pdp, &dummy);
    13621187        if (!NT_STATUS_IS_OK(status)) {
    13631188                return False;
     
    13851210        jucn->service_name = talloc_strdup(ctx, pdp->servicename);
    13861211        jucn->volume_name = talloc_strdup(ctx, pdp->reqpath);
    1387         jucn->comment = talloc_strdup(ctx, lp_comment(snum));
     1212        jucn->comment = lp_comment(ctx, snum);
    13881213
    13891214        TALLOC_FREE(pdp);
     
    14101235                return False;
    14111236        }
    1412         status = create_conn_struct(talloc_tos(), conn_out, snum,
    1413                                     lp_pathname(snum), NULL, oldpath);
     1237        status = create_conn_struct_cwd(talloc_tos(),
     1238                                        server_event_context(),
     1239                                        server_messaging_context(),
     1240                                        conn_out,
     1241                                        snum, lp_path(talloc_tos(), snum), NULL, oldpath);
    14141242        if (!NT_STATUS_IS_OK(status)) {
    14151243                return False;
     
    14181246        *pp_path_out = talloc_asprintf(*conn_out,
    14191247                        "%s/%s",
    1420                         lp_pathname(snum),
     1248                        lp_path(talloc_tos(), snum),
    14211249                        jucn->volume_name);
    14221250        if (!*pp_path_out) {
     
    14821310        if(SMB_VFS_SYMLINK(conn, msdfs_link, path) < 0) {
    14831311                if (errno == EEXIST) {
    1484                         struct smb_filename *smb_fname = NULL;
    1485                         NTSTATUS status;
    1486 
    1487                         status = create_synthetic_smb_fname(talloc_tos(), path,
    1488                                                             NULL, NULL,
    1489                                                             &smb_fname);
    1490                         if (!NT_STATUS_IS_OK(status)) {
    1491                                 errno = map_errno_from_nt_status(status);
     1312                        struct smb_filename *smb_fname;
     1313
     1314                        smb_fname = synthetic_smb_fname(talloc_tos(), path,
     1315                                                        NULL, NULL);
     1316                        if (smb_fname == NULL) {
     1317                                errno = ENOMEM;
    14921318                                goto out;
    14931319                        }
     
    15221348        connection_struct *conn;
    15231349        bool ret = False;
    1524         struct smb_filename *smb_fname = NULL;
    1525         NTSTATUS status;
     1350        struct smb_filename *smb_fname;
    15261351
    15271352        if (!junction_to_local_path(jucn, &path, &conn, &cwd)) {
     
    15291354        }
    15301355
    1531         status = create_synthetic_smb_fname(talloc_tos(), path,
    1532                                             NULL, NULL,
    1533                                             &smb_fname);
    1534         if (!NT_STATUS_IS_OK(status)) {
    1535                 errno = map_errno_from_nt_status(status);
     1356        smb_fname = synthetic_smb_fname(talloc_tos(), path, NULL, NULL);
     1357        if (smb_fname == NULL) {
     1358                errno = ENOMEM;
    15361359                return false;
    15371360        }
     
    15551378{
    15561379        size_t cnt = 0;
    1557         SMB_STRUCT_DIR *dirp = NULL;
     1380        DIR *dirp = NULL;
    15581381        const char *dname = NULL;
    15591382        char *talloced = NULL;
    1560         const char *connect_path = lp_pathname(snum);
    1561         const char *msdfs_proxy = lp_msdfs_proxy(snum);
     1383        const char *connect_path = lp_path(talloc_tos(), snum);
     1384        const char *msdfs_proxy = lp_msdfs_proxy(talloc_tos(), snum);
    15621385        connection_struct *conn;
    15631386        NTSTATUS status;
     
    15721395         */
    15731396
    1574         status = create_conn_struct(talloc_tos(), &conn, snum, connect_path,
    1575                                     NULL, &cwd);
     1397        status = create_conn_struct_cwd(talloc_tos(),
     1398                                        server_event_context(),
     1399                                        server_messaging_context(),
     1400                                        &conn,
     1401                                        snum, connect_path, NULL, &cwd);
    15761402        if (!NT_STATUS_IS_OK(status)) {
    15771403                DEBUG(3, ("create_conn_struct failed: %s\n",
     
    16221448{
    16231449        size_t cnt = 0;
    1624         SMB_STRUCT_DIR *dirp = NULL;
     1450        DIR *dirp = NULL;
    16251451        const char *dname = NULL;
    16261452        char *talloced = NULL;
    1627         const char *connect_path = lp_pathname(snum);
    1628         char *service_name = lp_servicename(snum);
    1629         const char *msdfs_proxy = lp_msdfs_proxy(snum);
     1453        const char *connect_path = lp_path(talloc_tos(), snum);
     1454        char *service_name = lp_servicename(talloc_tos(), snum);
     1455        const char *msdfs_proxy = lp_msdfs_proxy(talloc_tos(), snum);
    16301456        connection_struct *conn;
    16311457        struct referral *ref = NULL;
     
    16451471         */
    16461472
    1647         status = create_conn_struct(ctx, &conn, snum, connect_path, NULL,
    1648                                     &cwd);
     1473        status = create_conn_struct_cwd(ctx,
     1474                                        server_event_context(),
     1475                                        server_messaging_context(),
     1476                                        &conn, snum, connect_path, NULL,
     1477                                        &cwd);
    16491478        if (!NT_STATUS_IS_OK(status)) {
    16501479                DEBUG(3, ("create_conn_struct failed: %s\n",
     
    16651494        jucn[cnt].referral_count = 1;
    16661495
    1667         ref = jucn[cnt].referral_list = TALLOC_ZERO_P(ctx, struct referral);
     1496        ref = jucn[cnt].referral_list = talloc_zero(ctx, struct referral);
    16681497        if (jucn[cnt].referral_list == NULL) {
    16691498                goto out;
     
    17111540                                        dname, &link_target,
    17121541                                        NULL)) {
    1713                         if (parse_msdfs_symlink(ctx,
     1542                        if (parse_msdfs_symlink(ctx, snum,
    17141543                                        link_target,
    17151544                                        &jucn[cnt].referral_list,
     
    17591588        become_root();
    17601589        load_registry_shares();
    1761         sharecount = load_usershare_shares();
     1590        sharecount = load_usershare_shares(NULL, connections_snum_used);
    17621591        unbecome_root();
    17631592
     
    17701599                return NULL;
    17711600        }
    1772         jn = TALLOC_ARRAY(ctx,  struct junction_map, jn_count);
     1601        jn = talloc_array(ctx,  struct junction_map, jn_count);
    17731602        if (!jn) {
    17741603                return NULL;
     
    17981627                                const char *name_in,
    17991628                                bool allow_wcards,
     1629                                bool allow_broken_path,
    18001630                                char **pp_name_out,
    18011631                                bool *ppath_contains_wcard)
     
    18091639                                        name_in,
    18101640                                        allow_wcards,
     1641                                        allow_broken_path,
    18111642                                        pp_name_out,
    18121643                                        &path_contains_wcard);
     
    18211652                 * be a talloced ptr anyway.
    18221653                 */
    1823                 *pp_name_out = CONST_DISCARD(char *,name_in);
     1654                *pp_name_out = discard_const_p(char, name_in);
    18241655        }
    18251656        return status;
Note: See TracChangeset for help on using the changeset viewer.