#define START_OF_DIRECTORY_OFFSET ((long)0)
#define DOT_DOT_DIRECTORY_OFFSET ((long)0x80000000)
-/* "Special" directory offsets in 32-bit wire format. */
-#define WIRE_END_OF_DIRECTORY_OFFSET ((uint32_t)0xFFFFFFFF)
-#define WIRE_START_OF_DIRECTORY_OFFSET ((uint32_t)0)
-#define WIRE_DOT_DOT_DIRECTORY_OFFSET ((uint32_t)0x80000000)
-
/* Make directory handle internals available. */
struct name_cache_entry {
bool did_stat; /* Optimisation for non-wcard searches. */
bool priv; /* Directory handle opened with privilege. */
uint32_t counter;
- struct memcache *dptr_cache;
};
static NTSTATUS OpenDir_fsp(
return SearchDir(dptr->dir_hnd, name, poffset);
}
-/****************************************************************************
- Map a native directory offset to a 32-bit cookie.
-****************************************************************************/
-
-static uint32_t map_dir_offset_to_wire(struct dptr_struct *dptr, long offset)
-{
- DATA_BLOB key;
- DATA_BLOB val;
-
- if (offset == END_OF_DIRECTORY_OFFSET) {
- return WIRE_END_OF_DIRECTORY_OFFSET;
- }
- if (offset == START_OF_DIRECTORY_OFFSET) {
- return WIRE_START_OF_DIRECTORY_OFFSET;
- }
- if (offset == DOT_DOT_DIRECTORY_OFFSET) {
- return WIRE_DOT_DOT_DIRECTORY_OFFSET;
- }
- if (sizeof(long) == 4) {
- /* 32-bit machine. We can cheat... */
- return (uint32_t)offset;
- }
- if (dptr->dptr_cache == NULL) {
- /* Lazy initialize cache. */
- dptr->dptr_cache = memcache_init(dptr, 0);
- if (dptr->dptr_cache == NULL) {
- return WIRE_END_OF_DIRECTORY_OFFSET;
- }
- } else {
- /* Have we seen this offset before ? */
- key.data = (void *)&offset;
- key.length = sizeof(offset);
- if (memcache_lookup(dptr->dptr_cache,
- SMB1_SEARCH_OFFSET_MAP,
- key,
- &val)) {
- uint32_t wire_offset;
- SMB_ASSERT(val.length == sizeof(wire_offset));
- memcpy(&wire_offset, val.data, sizeof(wire_offset));
- DEBUG(10,("found wire %u <-> offset %ld\n",
- (unsigned int)wire_offset,
- (long)offset));
- return wire_offset;
- }
- }
- /* Allocate a new wire cookie. */
- do {
- dptr->counter++;
- } while (dptr->counter == WIRE_START_OF_DIRECTORY_OFFSET ||
- dptr->counter == WIRE_END_OF_DIRECTORY_OFFSET ||
- dptr->counter == WIRE_DOT_DOT_DIRECTORY_OFFSET);
- /* Store it in the cache. */
- key.data = (void *)&offset;
- key.length = sizeof(offset);
- val.data = (void *)&dptr->counter;
- val.length = sizeof(dptr->counter); /* MUST BE uint32_t ! */
- memcache_add(dptr->dptr_cache,
- SMB1_SEARCH_OFFSET_MAP,
- key,
- val);
- /* And the reverse mapping for lookup from
- map_wire_to_dir_offset(). */
- memcache_add(dptr->dptr_cache,
- SMB1_SEARCH_OFFSET_MAP,
- val,
- key);
- DEBUG(10,("stored wire %u <-> offset %ld\n",
- (unsigned int)dptr->counter,
- (long)offset));
- return dptr->counter;
-}
-
-/****************************************************************************
- Fill the 5 byte server reserved dptr field.
-****************************************************************************/
-
-bool dptr_fill(struct smbd_server_connection *sconn,
- char *buf1,unsigned int key)
-{
- unsigned char *buf = (unsigned char *)buf1;
- struct dptr_struct *dptr = dptr_get(sconn, key);
- uint32_t wire_offset;
- if (!dptr) {
- DEBUG(1,("filling null dirptr %d\n",key));
- return(False);
- }
- wire_offset = map_dir_offset_to_wire(dptr,TellDir(dptr->dir_hnd));
- DEBUG(6,("fill on key %u dirptr 0x%lx now at %d\n",key,
- (long)dptr->dir_hnd,(int)wire_offset));
- buf[0] = key;
- SIVAL(buf,1,wire_offset);
- return(True);
-}
-
-/****************************************************************************
- Map a 32-bit wire cookie to a native directory offset.
-****************************************************************************/
-
-static long map_wire_to_dir_offset(struct dptr_struct *dptr, uint32_t wire_offset)
-{
- DATA_BLOB key;
- DATA_BLOB val;
-
- if (wire_offset == WIRE_END_OF_DIRECTORY_OFFSET) {
- return END_OF_DIRECTORY_OFFSET;
- } else if(wire_offset == WIRE_START_OF_DIRECTORY_OFFSET) {
- return START_OF_DIRECTORY_OFFSET;
- } else if (wire_offset == WIRE_DOT_DOT_DIRECTORY_OFFSET) {
- return DOT_DOT_DIRECTORY_OFFSET;
- }
- if (sizeof(long) == 4) {
- /* 32-bit machine. We can cheat... */
- return (long)wire_offset;
- }
- if (dptr->dptr_cache == NULL) {
- /* Logic error, cache should be initialized. */
- return END_OF_DIRECTORY_OFFSET;
- }
- key.data = (void *)&wire_offset;
- key.length = sizeof(wire_offset);
- if (memcache_lookup(dptr->dptr_cache,
- SMB1_SEARCH_OFFSET_MAP,
- key,
- &val)) {
- /* Found mapping. */
- long offset;
- SMB_ASSERT(val.length == sizeof(offset));
- memcpy(&offset, val.data, sizeof(offset));
- DEBUG(10,("lookup wire %u <-> offset %ld\n",
- (unsigned int)wire_offset,
- (long)offset));
- return offset;
- }
- return END_OF_DIRECTORY_OFFSET;
-}
-
-/****************************************************************************
- Return the associated fsp and seek the dir_hnd on it it given the 5 byte
- server field.
-****************************************************************************/
-
-files_struct *dptr_fetch_fsp(struct smbd_server_connection *sconn,
- char *buf, int *num)
-{
- unsigned int key = *(unsigned char *)buf;
- struct dptr_struct *dptr = dptr_get(sconn, key);
- uint32_t wire_offset;
- long seekoff;
-
- if (dptr == NULL) {
- DEBUG(3,("fetched null dirptr %d\n",key));
- return(NULL);
- }
- *num = key;
- wire_offset = IVAL(buf,1);
- seekoff = map_wire_to_dir_offset(dptr, wire_offset);
- SeekDir(dptr->dir_hnd,seekoff);
- DBG_NOTICE("fetching dirptr %d for path %s at offset %ld\n",
- key,
- dptr->dir_hnd->dir_smb_fname->base_name,
- seekoff);
- return dptr->dir_hnd->fsp;
-}
-
struct files_struct *dir_hnd_fetch_fsp(struct smb_Dir *dir_hnd)
{
return dir_hnd->fsp;