Changeset 988 for vendor/current/source3/smbd/msdfs.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/smbd/msdfs.c
r860 r988 5 5 Copyright (C) Shirish Kalele 2000 6 6 Copyright (C) Jeremy Allison 2007 7 Copyright (C) Robin McCorkell 2015 7 8 8 9 This program is free software; you can redistribute it and/or modify … … 28 29 #include "msdfs.h" 29 30 #include "auth.h" 31 #include "lib/param/loadparm.h" 30 32 #include "libcli/security/security.h" 33 #include "librpc/gen_ndr/ndr_dfsblobs.h" 31 34 32 35 /********************************************************************** … … 53 56 const char *pathname, 54 57 bool allow_wcards, 58 bool allow_broken_path, 55 59 struct dfs_path *pdp, /* MUST BE TALLOCED */ 56 60 bool *ppath_contains_wcard) 57 61 { 58 struct smbd_server_connection *sconn = smbd_server_conn;59 62 char *pathname_local; 60 63 char *p,*temp; … … 84 87 sepchar = pdp->posix_path ? '/' : '\\'; 85 88 86 if ( !sconn->using_smb2&& (*pathname != sepchar)) {89 if (allow_broken_path && (*pathname != sepchar)) { 87 90 DEBUG(10,("parse_dfs_path: path %s doesn't start with %c\n", 88 91 pathname, sepchar )); … … 146 149 147 150 /* 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))) 149 152 || (strequal(servicename, HOMES_NAME) 150 && strequal(lp_servicename( SNUM(conn)),153 && strequal(lp_servicename(talloc_tos(), SNUM(conn)), 151 154 get_current_username()) )) ) { 152 155 DEBUG(10,("parse_dfs_path: %s is not our servicename\n", … … 217 220 218 221 /******************************************************** 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. 221 227 *********************************************************/ 222 228 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) 229 static 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) 229 236 { 230 237 connection_struct *conn; 231 238 char *connpath; 232 char *oldcwd;233 239 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); 236 252 if (conn == NULL) { 253 TALLOC_FREE(sconn); 237 254 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)"; 238 263 } 239 264 … … 244 269 } 245 270 connpath = talloc_string_sub(conn, 246 connpath,247 "%S",248 lp_servicename(snum));271 connpath, 272 "%S", 273 servicename); 249 274 if (!connpath) { 250 275 TALLOC_FREE(conn); … … 254 279 /* needed for smbd_vfs_init() */ 255 280 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 262 281 conn->params->service = snum; 263 264 conn->sconn = smbd_server_conn; 265 conn->sconn->num_tcons_open++; 282 conn->cnum = TID_FIELD_INVALID; 266 283 267 284 if (session_info != NULL) { 268 conn->session_info = copy_se rverinfo(conn, session_info);285 conn->session_info = copy_session_info(conn, session_info); 269 286 if (conn->session_info == NULL) { 270 287 DEBUG(0, ("copy_serverinfo failed\n")); … … 272 289 return NT_STATUS_NO_MEMORY; 273 290 } 274 vfs_user = conn->session_info->unix_ name;291 vfs_user = conn->session_info->unix_info->unix_name; 275 292 } else { 276 293 /* use current authenticated user in absence of session_info */ … … 281 298 282 299 /* 283 * New code to check if there's a share security descript er300 * New code to check if there's a share security descriptor 284 301 * added from NT server manager. This is done after the 285 302 * smb.conf checks are done as we need a uid and token. JRA. … … 288 305 if (conn->session_info) { 289 306 share_access_check(conn->session_info->security_token, 290 lp_servicename(snum), MAXIMUM_ALLOWED_ACCESS, 307 servicename, 308 MAXIMUM_ALLOWED_ACCESS, 291 309 &conn->share_access); 292 310 … … 294 312 if ((conn->share_access & FILE_READ_DATA) == 0) { 295 313 /* No access, read or write. */ 296 DEBUG( 0,("create_conn_struct: connection to %s "314 DEBUG(3,("create_conn_struct: connection to %s " 297 315 "denied due to security " 298 316 "descriptor.\n", 299 lp_servicename(snum)));317 servicename)); 300 318 conn_free(conn); 301 319 return NT_STATUS_ACCESS_DENIED; … … 317 335 318 336 /* 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) { 320 338 DEBUG(0,("VFS connect failed!\n")); 321 339 conn_free(conn); … … 324 342 325 343 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 357 NTSTATUS 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 383 NTSTATUS 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 } 326 402 327 403 /* … … 333 409 oldcwd = vfs_GetWd(ctx, conn); 334 410 if (oldcwd == NULL) { 335 NTSTATUSstatus = map_nt_error_from_unix(errno);411 status = map_nt_error_from_unix(errno); 336 412 DEBUG(3, ("vfs_GetWd failed: %s\n", strerror(errno))); 337 413 conn_free(conn); … … 340 416 341 417 if (vfs_ChDir(conn,conn->connectpath) != 0) { 342 NTSTATUSstatus = map_nt_error_from_unix(errno);418 status = map_nt_error_from_unix(errno); 343 419 DEBUG(3,("create_conn_struct: Can't ChDir to new conn path %s. " 344 420 "Error was %s\n", … … 354 430 } 355 431 432 static 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 356 447 /********************************************************************** 357 448 Parse the contents of a symlink to verify if it is an msdfs referral … … 374 465 375 466 static bool parse_msdfs_symlink(TALLOC_CTX *ctx, 467 int snum, 376 468 const char *target, 377 469 struct referral **preflist, … … 395 487 } 396 488 397 alt_path = TALLOC_ARRAY(ctx, char *, MAX_REFERRAL_COUNT);489 alt_path = talloc_array(ctx, char *, MAX_REFERRAL_COUNT); 398 490 if (!alt_path) { 399 491 return False; … … 406 498 } 407 499 500 /* shuffle alternate paths */ 501 if (lp_msdfs_shuffle_referrals(snum)) { 502 shuffle_strlist(alt_path, count); 503 } 504 408 505 DEBUG(10,("parse_msdfs_symlink: count=%d\n", count)); 409 506 410 507 if (count) { 411 reflist = *preflist = TALLOC_ZERO_ARRAY(ctx,508 reflist = *preflist = talloc_zero_array(ctx, 412 509 struct referral, count); 413 510 if(reflist == NULL) { … … 474 571 if (pp_link_target) { 475 572 bufsize = 1024; 476 link_target = TALLOC_ARRAY(ctx, char, bufsize);573 link_target = talloc_array(ctx, char, bufsize); 477 574 if (!link_target) { 478 575 return False; … … 576 673 577 674 /* 578 * Note the unix path conversion here we're doing we675 * Note the unix path conversion here we're doing we 579 676 * throw away. We're looking for a symlink for a dfs 580 677 * resolution, if we don't find it we'll do another … … 710 807 const char *path_in, 711 808 bool search_wcard_flag, 809 bool allow_broken_path, 712 810 char **pp_path_out, 713 811 bool *ppath_contains_wcard) 714 812 { 715 813 NTSTATUS status; 716 struct dfs_path *pdp = TALLOC_P(ctx, struct dfs_path);814 struct dfs_path *pdp = talloc(ctx, struct dfs_path); 717 815 718 816 if (!pdp) { … … 720 818 } 721 819 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, 723 822 ppath_contains_wcard); 724 823 if (!NT_STATUS_IS_OK(status)) { … … 761 860 } 762 861 763 if (!( strequal(pdp->servicename, lp_servicename( SNUM(conn)))862 if (!( strequal(pdp->servicename, lp_servicename(talloc_tos(), SNUM(conn))) 764 863 || (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) )) ) { 767 866 768 867 /* The given sharename doesn't match this connection. */ … … 816 915 817 916 jucn->referral_count = 1; 818 if((ref = TALLOC_ZERO_P(ctx, struct referral)) == NULL) {917 if((ref = talloc_zero(ctx, struct referral)) == NULL) { 819 918 return NT_STATUS_NO_MEMORY; 820 919 } … … 822 921 ref->alternate_path = talloc_strdup(ctx, dfs_path); 823 922 if (!ref->alternate_path) { 923 TALLOC_FREE(ref); 824 924 return NT_STATUS_NO_MEMORY; 825 925 } … … 838 938 NTSTATUS get_referred_path(TALLOC_CTX *ctx, 839 939 const char *dfs_path, 940 bool allow_broken_path, 840 941 struct junction_map *jucn, 841 942 int *consumedcntp, … … 847 948 NTSTATUS status = NT_STATUS_NOT_FOUND; 848 949 bool dummy; 849 struct dfs_path *pdp = TALLOC_P(ctx, struct dfs_path);950 struct dfs_path *pdp = talloc(ctx, struct dfs_path); 850 951 char *oldpath; 851 952 … … 856 957 *self_referralp = False; 857 958 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); 859 961 if (!NT_STATUS_IS_OK(status)) { 860 962 return status; … … 886 988 } 887 989 888 if (!lp_msdfs_root(snum) && (*lp_msdfs_proxy( snum) == '\0')) {990 if (!lp_msdfs_root(snum) && (*lp_msdfs_proxy(talloc_tos(), snum) == '\0')) { 889 991 DEBUG(3,("get_referred_path: |%s| in dfs path %s is not " 890 992 "a dfs root.\n", … … 905 1007 char *tmp; 906 1008 struct referral *ref; 907 908 if (*lp_msdfs_proxy(snum) == '\0') { 1009 int refcount; 1010 1011 if (*lp_msdfs_proxy(talloc_tos(), snum) == '\0') { 909 1012 TALLOC_FREE(pdp); 910 1013 return self_ref(ctx, … … 920 1023 */ 921 1024 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) { 924 1028 TALLOC_FREE(pdp); 925 1029 return NT_STATUS_NO_MEMORY; 926 1030 } 927 1031 928 if (!(tmp = talloc_strdup(ctx, lp_msdfs_proxy(snum)))) { 1032 if (!parse_msdfs_symlink(ctx, snum, tmp, &ref, &refcount)) { 1033 TALLOC_FREE(tmp); 929 1034 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 } 936 1037 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; 955 1039 jucn->referral_list = ref; 956 1040 *consumedcntp = strlen(dfs_path); … … 959 1043 } 960 1044 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); 963 1050 if (!NT_STATUS_IS_OK(status)) { 964 1051 TALLOC_FREE(pdp); … … 992 1079 993 1080 /* 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, 995 1082 &jucn->referral_list, 996 1083 &jucn->referral_count)) { … … 1010 1097 } 1011 1098 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 minus1080 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 minus1176 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 1221 1099 /****************************************************************** 1222 1100 Set up the DFS referral for the dfs pathname. This call returns … … 1231 1109 char **ppdata, NTSTATUS *pstatus) 1232 1110 { 1233 struct junction_map *junction = NULL; 1234 int consumedcnt = 0; 1235 bool self_referral = False; 1111 char *pdata = *ppdata; 1236 1112 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) { 1242 1120 *pstatus = NT_STATUS_NO_MEMORY; 1243 1121 return -1; 1244 1122 } 1245 1123 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; 1250 1129 return -1; 1251 1130 } 1252 1131 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; 1262 1136 return -1; 1263 1137 } 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; 1274 1145 return -1; 1275 1146 } 1276 1147 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")); 1283 1153 return -1; 1284 1154 } 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 1337 1160 *pstatus = NT_STATUS_OK; 1338 1161 return reply_size; … … 1349 1172 bool create_junction(TALLOC_CTX *ctx, 1350 1173 const char *dfs_path, 1174 bool allow_broken_path, 1351 1175 struct junction_map *jucn) 1352 1176 { 1353 1177 int snum; 1354 1178 bool dummy; 1355 struct dfs_path *pdp = TALLOC_P(ctx,struct dfs_path);1179 struct dfs_path *pdp = talloc(ctx,struct dfs_path); 1356 1180 NTSTATUS status; 1357 1181 … … 1359 1183 return False; 1360 1184 } 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); 1362 1187 if (!NT_STATUS_IS_OK(status)) { 1363 1188 return False; … … 1385 1210 jucn->service_name = talloc_strdup(ctx, pdp->servicename); 1386 1211 jucn->volume_name = talloc_strdup(ctx, pdp->reqpath); 1387 jucn->comment = talloc_strdup(ctx, lp_comment(snum));1212 jucn->comment = lp_comment(ctx, snum); 1388 1213 1389 1214 TALLOC_FREE(pdp); … … 1410 1235 return False; 1411 1236 } 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); 1414 1242 if (!NT_STATUS_IS_OK(status)) { 1415 1243 return False; … … 1418 1246 *pp_path_out = talloc_asprintf(*conn_out, 1419 1247 "%s/%s", 1420 lp_path name(snum),1248 lp_path(talloc_tos(), snum), 1421 1249 jucn->volume_name); 1422 1250 if (!*pp_path_out) { … … 1482 1310 if(SMB_VFS_SYMLINK(conn, msdfs_link, path) < 0) { 1483 1311 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; 1492 1318 goto out; 1493 1319 } … … 1522 1348 connection_struct *conn; 1523 1349 bool ret = False; 1524 struct smb_filename *smb_fname = NULL; 1525 NTSTATUS status; 1350 struct smb_filename *smb_fname; 1526 1351 1527 1352 if (!junction_to_local_path(jucn, &path, &conn, &cwd)) { … … 1529 1354 } 1530 1355 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; 1536 1359 return false; 1537 1360 } … … 1555 1378 { 1556 1379 size_t cnt = 0; 1557 SMB_STRUCT_DIR *dirp = NULL;1380 DIR *dirp = NULL; 1558 1381 const char *dname = NULL; 1559 1382 char *talloced = NULL; 1560 const char *connect_path = lp_path name(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); 1562 1385 connection_struct *conn; 1563 1386 NTSTATUS status; … … 1572 1395 */ 1573 1396 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); 1576 1402 if (!NT_STATUS_IS_OK(status)) { 1577 1403 DEBUG(3, ("create_conn_struct failed: %s\n", … … 1622 1448 { 1623 1449 size_t cnt = 0; 1624 SMB_STRUCT_DIR *dirp = NULL;1450 DIR *dirp = NULL; 1625 1451 const char *dname = NULL; 1626 1452 char *talloced = NULL; 1627 const char *connect_path = lp_path name(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); 1630 1456 connection_struct *conn; 1631 1457 struct referral *ref = NULL; … … 1645 1471 */ 1646 1472 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); 1649 1478 if (!NT_STATUS_IS_OK(status)) { 1650 1479 DEBUG(3, ("create_conn_struct failed: %s\n", … … 1665 1494 jucn[cnt].referral_count = 1; 1666 1495 1667 ref = jucn[cnt].referral_list = TALLOC_ZERO_P(ctx, struct referral);1496 ref = jucn[cnt].referral_list = talloc_zero(ctx, struct referral); 1668 1497 if (jucn[cnt].referral_list == NULL) { 1669 1498 goto out; … … 1711 1540 dname, &link_target, 1712 1541 NULL)) { 1713 if (parse_msdfs_symlink(ctx, 1542 if (parse_msdfs_symlink(ctx, snum, 1714 1543 link_target, 1715 1544 &jucn[cnt].referral_list, … … 1759 1588 become_root(); 1760 1589 load_registry_shares(); 1761 sharecount = load_usershare_shares( );1590 sharecount = load_usershare_shares(NULL, connections_snum_used); 1762 1591 unbecome_root(); 1763 1592 … … 1770 1599 return NULL; 1771 1600 } 1772 jn = TALLOC_ARRAY(ctx, struct junction_map, jn_count);1601 jn = talloc_array(ctx, struct junction_map, jn_count); 1773 1602 if (!jn) { 1774 1603 return NULL; … … 1798 1627 const char *name_in, 1799 1628 bool allow_wcards, 1629 bool allow_broken_path, 1800 1630 char **pp_name_out, 1801 1631 bool *ppath_contains_wcard) … … 1809 1639 name_in, 1810 1640 allow_wcards, 1641 allow_broken_path, 1811 1642 pp_name_out, 1812 1643 &path_contains_wcard); … … 1821 1652 * be a talloced ptr anyway. 1822 1653 */ 1823 *pp_name_out = CONST_DISCARD(char *,name_in);1654 *pp_name_out = discard_const_p(char, name_in); 1824 1655 } 1825 1656 return status;
Note:
See TracChangeset
for help on using the changeset viewer.