Changeset 740 for vendor/current/source3/smbd/dir.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/smbd/dir.c
r478 r740 20 20 21 21 #include "includes.h" 22 #include "system/filesys.h" 23 #include "smbd/smbd.h" 22 24 #include "smbd/globals.h" 25 #include "libcli/security/security.h" 23 26 24 27 /* … … 63 66 }; 64 67 68 static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, 69 files_struct *fsp, 70 const char *mask, 71 uint32 attr); 65 72 66 73 #define INVALID_DPTR_KEY (-3) … … 86 93 } 87 94 88 if ((mode & aDIR) != 0) {95 if ((mode & FILE_ATTRIBUTE_DIRECTORY) != 0) { 89 96 size = 0; 90 97 } … … 118 125 bool init_dptrs(struct smbd_server_connection *sconn) 119 126 { 120 if (sconn->s mb1.searches.dptr_bmap) {127 if (sconn->searches.dptr_bmap) { 121 128 return true; 122 129 } 123 130 124 sconn->smb1.searches.dptr_bmap = bitmap_allocate(MAX_DIRECTORY_HANDLES); 125 126 if (sconn->smb1.searches.dptr_bmap == NULL) { 131 sconn->searches.dptr_bmap = bitmap_talloc( 132 sconn, MAX_DIRECTORY_HANDLES); 133 134 if (sconn->searches.dptr_bmap == NULL) { 127 135 return false; 128 136 } … … 154 162 * Go to the end of the list. 155 163 */ 156 for(dptr = sconn->smb1.searches.dirptrs; dptr && dptr->next; dptr = dptr->next) 157 ; 164 dptr = DLIST_TAIL(sconn->searches.dirptrs); 158 165 159 166 if(!dptr) { … … 166 173 */ 167 174 168 for(; dptr; dptr = dptr->prev) {175 for(; dptr; dptr = DLIST_PREV(dptr)) { 169 176 if (dptr->dir_hnd) { 170 177 dptr_idle(dptr); … … 183 190 struct dptr_struct *dptr; 184 191 185 for(dptr = sconn->s mb1.searches.dirptrs; dptr; dptr = dptr->next) {192 for(dptr = sconn->searches.dirptrs; dptr; dptr = dptr->next) { 186 193 if(dptr->dnum == key) { 187 194 if (!forclose && !dptr->dir_hnd) { 188 if (sconn->s mb1.searches.dirhandles_open >= MAX_OPEN_DIRECTORIES)195 if (sconn->searches.dirhandles_open >= MAX_OPEN_DIRECTORIES) 189 196 dptr_idleoldest(sconn); 190 197 DEBUG(4,("dptr_get: Reopening dptr key %d\n",key)); … … 197 204 } 198 205 } 199 DLIST_PROMOTE(sconn->s mb1.searches.dirptrs,dptr);206 DLIST_PROMOTE(sconn->searches.dirptrs,dptr); 200 207 return dptr; 201 208 } … … 254 261 } 255 262 256 DLIST_REMOVE(sconn->s mb1.searches.dirptrs, dptr);263 DLIST_REMOVE(sconn->searches.dirptrs, dptr); 257 264 258 265 /* … … 261 268 */ 262 269 263 if (bitmap_query(sconn->smb1.searches.dptr_bmap, dptr->dnum - 1) != true) {270 if (!bitmap_query(sconn->searches.dptr_bmap, dptr->dnum - 1)) { 264 271 DEBUG(0,("dptr_close_internal : Error - closing dnum = %d and bitmap not set !\n", 265 272 dptr->dnum )); 266 273 } 267 274 268 bitmap_clear(sconn->s mb1.searches.dptr_bmap, dptr->dnum - 1);275 bitmap_clear(sconn->searches.dptr_bmap, dptr->dnum - 1); 269 276 270 277 done: … … 291 298 if (*key == -1) { 292 299 struct dptr_struct *next; 293 for(dptr = sconn->s mb1.searches.dirptrs; dptr; dptr = next) {300 for(dptr = sconn->searches.dirptrs; dptr; dptr = next) { 294 301 next = dptr->next; 295 302 dptr_close_internal(dptr); … … 324 331 } 325 332 326 for(dptr = sconn->s mb1.searches.dirptrs; dptr; dptr = next) {333 for(dptr = sconn->searches.dirptrs; dptr; dptr = next) { 327 334 next = dptr->next; 328 335 if (dptr->conn == conn) { … … 345 352 } 346 353 347 for(dptr = sconn->s mb1.searches.dirptrs; dptr; dptr = dptr->next) {354 for(dptr = sconn->searches.dirptrs; dptr; dptr = dptr->next) { 348 355 if (dptr->conn == conn && dptr->dir_hnd) { 349 356 dptr_idle(dptr); … … 360 367 { 361 368 struct dptr_struct *dptr, *next; 362 for(dptr = sconn->s mb1.searches.dirptrs; dptr; dptr = next) {369 for(dptr = sconn->searches.dirptrs; dptr; dptr = next) { 363 370 next = dptr->next; 364 371 if (spid == dptr->spid && strequal(dptr->path,path)) … … 381 388 * Go to the end of the list. 382 389 */ 383 for(dptr = sconn->s mb1.searches.dirptrs; dptr && dptr->next; dptr = dptr->next)390 for(dptr = sconn->searches.dirptrs; dptr && dptr->next; dptr = dptr->next) 384 391 ; 385 392 … … 395 402 */ 396 403 397 for(; dptr; dptr = dptr->prev) {404 for(; dptr; dptr = DLIST_PREV(dptr)) { 398 405 if ((old && (dptr->dnum < 256) && !dptr->expect_close) || 399 406 (!old && (dptr->dnum > 255))) { … … 413 420 ****************************************************************************/ 414 421 415 NTSTATUS dptr_create(connection_struct *conn, const char *path, bool old_handle, bool expect_close,uint16 spid, 422 NTSTATUS dptr_create(connection_struct *conn, files_struct *fsp, 423 const char *path, bool old_handle, bool expect_close,uint16 spid, 416 424 const char *wcard, bool wcard_has_wild, uint32 attr, struct dptr_struct **dptr_ret) 417 425 { … … 421 429 NTSTATUS status; 422 430 431 if (fsp && fsp->is_directory && fsp->fh->fd != -1) { 432 path = fsp->fsp_name->base_name; 433 } 434 423 435 DEBUG(5,("dptr_create dir=%s\n", path)); 424 436 … … 432 444 } 433 445 434 status = check_name(conn,path); 435 if (!NT_STATUS_IS_OK(status)) { 436 return status; 437 } 438 439 dir_hnd = OpenDir(NULL, conn, path, wcard, attr); 446 if (fsp) { 447 dir_hnd = OpenDir_fsp(NULL, conn, fsp, wcard, attr); 448 } else { 449 status = check_name(conn,path); 450 if (!NT_STATUS_IS_OK(status)) { 451 return status; 452 } 453 dir_hnd = OpenDir(NULL, conn, path, wcard, attr); 454 } 455 440 456 if (!dir_hnd) { 441 457 return map_nt_error_from_unix(errno); 442 458 } 443 459 444 if (sconn->s mb1.searches.dirhandles_open >= MAX_OPEN_DIRECTORIES) {460 if (sconn->searches.dirhandles_open >= MAX_OPEN_DIRECTORIES) { 445 461 dptr_idleoldest(sconn); 446 462 } … … 462 478 */ 463 479 464 dptr->dnum = bitmap_find(sconn->s mb1.searches.dptr_bmap, 0);480 dptr->dnum = bitmap_find(sconn->searches.dptr_bmap, 0); 465 481 466 482 if(dptr->dnum == -1 || dptr->dnum > 254) { … … 475 491 476 492 /* Now try again... */ 477 dptr->dnum = bitmap_find(sconn->s mb1.searches.dptr_bmap, 0);493 dptr->dnum = bitmap_find(sconn->searches.dptr_bmap, 0); 478 494 if(dptr->dnum == -1 || dptr->dnum > 254) { 479 495 DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum)); … … 490 506 */ 491 507 492 dptr->dnum = bitmap_find(sconn->s mb1.searches.dptr_bmap, 255);508 dptr->dnum = bitmap_find(sconn->searches.dptr_bmap, 255); 493 509 494 510 if(dptr->dnum == -1 || dptr->dnum < 255) { … … 504 520 505 521 /* Now try again... */ 506 dptr->dnum = bitmap_find(sconn->s mb1.searches.dptr_bmap, 255);522 dptr->dnum = bitmap_find(sconn->searches.dptr_bmap, 255); 507 523 508 524 if(dptr->dnum == -1 || dptr->dnum < 255) { … … 515 531 } 516 532 517 bitmap_set(sconn->s mb1.searches.dptr_bmap, dptr->dnum);533 bitmap_set(sconn->searches.dptr_bmap, dptr->dnum); 518 534 519 535 dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */ … … 526 542 dptr->wcard = SMB_STRDUP(wcard); 527 543 if (!dptr->wcard) { 528 bitmap_clear(sconn->s mb1.searches.dptr_bmap, dptr->dnum - 1);544 bitmap_clear(sconn->searches.dptr_bmap, dptr->dnum - 1); 529 545 SAFE_FREE(dptr); 530 546 TALLOC_FREE(dir_hnd); … … 539 555 dptr->attr = attr; 540 556 541 DLIST_ADD(sconn->s mb1.searches.dirptrs, dptr);557 DLIST_ADD(sconn->searches.dirptrs, dptr); 542 558 543 559 DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n", … … 554 570 ****************************************************************************/ 555 571 556 int dptr_CloseDir(struct dptr_struct *dptr) 557 { 558 dptr_close_internal(dptr); 559 return 0; 572 void dptr_CloseDir(files_struct *fsp) 573 { 574 if (fsp->dptr) { 575 /* 576 * Ugly hack. We have defined fdopendir to return ENOSYS if dirfd also isn't 577 * present. I hate Solaris. JRA. 578 */ 579 #ifdef HAVE_DIRFD 580 if (fsp->fh->fd != -1 && 581 fsp->dptr->dir_hnd && 582 dirfd(fsp->dptr->dir_hnd->dir)) { 583 /* The call below closes the underlying fd. */ 584 fsp->fh->fd = -1; 585 } 586 #endif 587 dptr_close_internal(fsp->dptr); 588 fsp->dptr = NULL; 589 } 560 590 } 561 591 … … 843 873 844 874 /* Check the "may have" search bits. */ 845 if (((mode & ~dirtype) & ( aHIDDEN | aSYSTEM | aDIR)) != 0)875 if (((mode & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY)) != 0) 846 876 return False; 847 877 … … 849 879 /* If must have bit is set, the file/dir can not be returned in search unless the matching 850 880 file attribute is set */ 851 mask = ((dirtype >> 8) & ( aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM)); /* & 0x37 */881 mask = ((dirtype >> 8) & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)); /* & 0x37 */ 852 882 if(mask) { 853 if((mask & (mode & ( aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM))) == mask) /* check if matching attribute present */883 if((mask & (mode & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) == mask) /* check if matching attribute present */ 854 884 return True; 855 885 else … … 981 1011 fileid = vfs_file_id_from_sbuf(conn, 982 1012 &smb_fname.st); 983 get_file_infos(fileid, NULL, &write_time_ts);1013 get_file_infos(fileid, 0, NULL, &write_time_ts); 984 1014 if (!null_timespec(write_time_ts)) { 985 1015 update_stat_ex_mtime(&smb_fname.st, … … 1127 1157 { 1128 1158 /* 1129 * If user is a member of the Admin group 1130 * we never hide files from them. 1159 * Never hide files from the root user. 1160 * We use (uid_t)0 here not sec_initial_uid() 1161 * as make test uses a single user context. 1131 1162 */ 1132 1163 1133 if ( conn->admin_user) {1164 if (get_current_uid(conn) == (uid_t)0) { 1134 1165 return True; 1135 1166 } … … 1149 1180 { 1150 1181 /* 1151 * If user is a member of the Admin group 1152 * we never hide files from them. 1182 * Never hide files from the root user. 1183 * We use (uid_t)0 here not sec_initial_uid() 1184 * as make test uses a single user context. 1153 1185 */ 1154 1186 1155 if ( conn->admin_user) {1187 if (get_current_uid(conn) == (uid_t)0) { 1156 1188 return True; 1157 1189 } … … 1176 1208 { 1177 1209 /* 1178 * If user is a member of the Admin group 1179 * we never hide files from them. 1210 * Never hide files from the root user. 1211 * We use (uid_t)0 here not sec_initial_uid() 1212 * as make test uses a single user context. 1180 1213 */ 1181 1214 1182 if ( conn->admin_user)1215 if (get_current_uid(conn) == (uid_t)0) { 1183 1216 return False; 1217 } 1184 1218 1185 1219 SMB_ASSERT(VALID_STAT(smb_fname->st)); … … 1223 1257 if (!entry) { 1224 1258 ret = false; 1225 goto out;1226 }1227 1228 /* If it's a dfs symlink, ignore _hide xxxx_ options */1229 if (lp_host_msdfs() &&1230 lp_msdfs_root(SNUM(conn)) &&1231 is_msdfs_link(conn, entry, NULL)) {1232 ret = true;1233 1259 goto out; 1234 1260 } … … 1290 1316 { 1291 1317 if (dirp->dir) { 1318 #ifdef HAVE_DIRFD 1319 if (dirp->conn->sconn) { 1320 files_struct *fsp = file_find_fd(dirp->conn->sconn, 1321 dirfd(dirp->dir)); 1322 if (fsp) { 1323 /* The call below closes the underlying fd. */ 1324 fsp->fh->fd = -1; 1325 } 1326 } 1327 #endif 1292 1328 SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir); 1293 1329 } 1294 1330 if (dirp->conn->sconn) { 1295 dirp->conn->sconn->s mb1.searches.dirhandles_open--;1331 dirp->conn->sconn->searches.dirhandles_open--; 1296 1332 } 1297 1333 return 0; … … 1303 1339 1304 1340 struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, 1305 const char *name, const char *mask, uint32 attr) 1341 const char *name, 1342 const char *mask, 1343 uint32 attr) 1306 1344 { 1307 1345 struct smb_Dir *dirp = TALLOC_ZERO_P(mem_ctx, struct smb_Dir); … … 1322 1360 1323 1361 if (sconn) { 1324 sconn->s mb1.searches.dirhandles_open++;1362 sconn->searches.dirhandles_open++; 1325 1363 } 1326 1364 talloc_set_destructor(dirp, smb_Dir_destructor); … … 1339 1377 return NULL; 1340 1378 } 1379 1380 /******************************************************************* 1381 Open a directory from an fsp. 1382 ********************************************************************/ 1383 1384 static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, 1385 files_struct *fsp, 1386 const char *mask, 1387 uint32 attr) 1388 { 1389 struct smb_Dir *dirp = TALLOC_ZERO_P(mem_ctx, struct smb_Dir); 1390 struct smbd_server_connection *sconn = conn->sconn; 1391 1392 if (!dirp) { 1393 return NULL; 1394 } 1395 1396 dirp->conn = conn; 1397 dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); 1398 1399 dirp->dir_path = talloc_strdup(dirp, fsp->fsp_name->base_name); 1400 if (!dirp->dir_path) { 1401 errno = ENOMEM; 1402 goto fail; 1403 } 1404 1405 if (sconn) { 1406 sconn->searches.dirhandles_open++; 1407 } 1408 talloc_set_destructor(dirp, smb_Dir_destructor); 1409 1410 if (fsp->is_directory && fsp->fh->fd != -1) { 1411 dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); 1412 if (dirp->dir == NULL) { 1413 DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " 1414 "NULL (%s)\n", 1415 dirp->dir_path, 1416 strerror(errno))); 1417 if (errno != ENOSYS) { 1418 return NULL; 1419 } 1420 } 1421 } 1422 1423 if (dirp->dir == NULL) { 1424 /* FDOPENDIR didn't work. Use OPENDIR instead. */ 1425 dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); 1426 } 1427 1428 if (!dirp->dir) { 1429 DEBUG(5,("OpenDir_fsp: Can't open %s. %s\n", dirp->dir_path, 1430 strerror(errno) )); 1431 goto fail; 1432 } 1433 1434 return dirp; 1435 1436 fail: 1437 TALLOC_FREE(dirp); 1438 return NULL; 1439 } 1440 1341 1441 1342 1442 /******************************************************************* … … 1534 1634 char *talloced = NULL; 1535 1635 SMB_STRUCT_STAT st; 1536 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, dirname,1537 1636 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, 1637 dirname, NULL, 0); 1538 1638 1539 1639 if (!dir_hnd) {
Note:
See TracChangeset
for help on using the changeset viewer.