Exemple #1
0
static int fill_create_process_event( struct debug_event *event, const void *arg )
{
    struct process *debugger = event->debugger->process;
    struct thread *thread = event->sender;
    struct process *process = thread->process;
    struct process_dll *exe_module = get_process_exe_module( process );
    const client_ptr_t *entry = arg;
    obj_handle_t handle;

    /* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */
    if (!(handle = alloc_handle( debugger, process, PROCESS_ALL_ACCESS, 0 ))) return 0;
    event->data.create_process.process = handle;

    /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
    if (!(handle = alloc_handle( debugger, thread, THREAD_ALL_ACCESS, 0 )))
    {
        close_handle( debugger, event->data.create_process.process );
        return 0;
    }
    event->data.create_process.thread     = handle;
    event->data.create_process.file       = 0;
    event->data.create_process.teb        = thread->teb;
    event->data.create_process.base       = exe_module->base;
    event->data.create_process.start      = *entry;
    event->data.create_process.dbg_offset = exe_module->dbg_offset;
    event->data.create_process.dbg_size   = exe_module->dbg_size;
    event->data.create_process.name       = exe_module->name;
    event->data.create_process.unicode    = 1;

    if (exe_module->mapping)  /* the doc says write access too, but this doesn't seem a good idea */
        event->data.create_process.file = open_mapping_file( debugger, exe_module->mapping, GENERIC_READ,
                                                             FILE_SHARE_READ | FILE_SHARE_WRITE );
    return 1;
}
		Registration::Registration()
		 : _handle(alloc_handle()),
		   _default_eid(core::BundleCore::local), _no_more_bundles(false),
		   _persistent(false), _detached(false), _expiry(0), _filter_fragments(true)
		{
			_default_eid.setApplication(_handle);
		}
Exemple #3
0
/******************************************************************************
 *  new_object
 *
 * Allocates a new object of size cbSize on the current process's heap.
 * Initializes the object header using the destructor and dwType params.
 * Allocates a handle to the object in the handle table pointed to by lpTable.
 * Returns a pointer to the created object in ppObject.
 * Returns a handle to the created object.
 *
 * PARAMS
 *  lpTable    [I] Pointer to the handle table, from which a handle is to be 
 *              allocated.
 *  cbSize     [I] Size of the object to be allocated in bytes.
 *  dwType     [I] Object type; will be copied to the object header.
 *  destructor [I] Function pointer to a destructor function. Will be called
 *                 once the object's reference count gets zero.
 *  ppObject   [O] Pointer to a pointer variable, where a pointer to the newly
 *                 created object will be stored. You may set this to NULL.
 *
 * RETURNS
 *  INVALID_HANDLE_VALUE,        if something went wrong.
 *  a handle to the new object,  if successful. 
 */
unsigned int new_object(HANDLETABLE *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor, 
                        OBJECTHDR **ppObject)
{
    OBJECTHDR *pObject;
    unsigned int hObject;

    if (ppObject)
        *ppObject = NULL;

    pObject = HeapAlloc(GetProcessHeap(), 0, cbSize);
    if (!pObject)
        return (unsigned int)INVALID_HANDLE_VALUE;

    pObject->dwType = dwType;
    pObject->refcount = 0;
    pObject->destructor = destructor;

    if (!alloc_handle(lpTable, pObject, &hObject))
        HeapFree(GetProcessHeap(), 0, pObject);
    else
        if (ppObject)
            *ppObject = pObject;

    return hObject;
}
Exemple #4
0
/* lookup
 * deprecated NULL parent && NULL path implies root handle
 */
static fsal_status_t lookup(struct fsal_obj_handle *parent,
			    const char *path, struct fsal_obj_handle **handle,
			    struct attrlist *attrs_out)
{
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int retval = 0;
	fsal_status_t status;
	struct gpfs_fsal_obj_handle *hdl;
	struct attrlist attrib;
	struct gpfs_file_handle *fh = alloca(sizeof(struct gpfs_file_handle));
	struct fsal_filesystem *fs;

	*handle = NULL;		/* poison it first */
	fs = parent->fs;
	if (!path)
		return fsalstat(ERR_FSAL_FAULT, 0);
	memset(fh, 0, sizeof(struct gpfs_file_handle));
	fh->handle_size = GPFS_MAX_FH_SIZE;
	if (!parent->obj_ops.handle_is(parent, DIRECTORY)) {
		LogCrit(COMPONENT_FSAL,
			"Parent handle is not a directory. hdl = 0x%p", parent);
		return fsalstat(ERR_FSAL_NOTDIR, 0);
	}

	if (parent->fsal != parent->fs->fsal) {
		LogDebug(COMPONENT_FSAL,
			 "FSAL %s operation for handle belonging to FSAL %s, return EXDEV",
			 parent->fsal->name, parent->fs->fsal->name);
		retval = EXDEV;
		goto hdlerr;
	}

	fsal_prepare_attrs(&attrib, ATTR_GPFS_ALLOC_HANDLE);

	if (attrs_out != NULL)
		attrib.mask |= attrs_out->mask;

	status = GPFSFSAL_lookup(op_ctx, parent, path, &attrib, fh, &fs);
	if (FSAL_IS_ERROR(status))
		return status;

	/* allocate an obj_handle and fill it up */
	hdl = alloc_handle(fh, fs, &attrib, NULL, op_ctx->fsal_export);

	if (attrs_out != NULL) {
		/* Copy the attributes to caller, passing ACL ref. */
		fsal_copy_attrs(attrs_out, &attrib, true);
	} else {
		/* Done with the attrs */
		fsal_release_attrs(&attrib);
	}

	*handle = &hdl->obj_handle;
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

 hdlerr:
	fsal_error = posix2fsal_error(retval);
	return fsalstat(fsal_error, retval);
}
Exemple #5
0
TC_HANDLE_T
TC_INIT(const char *tablename)
{
	TC_HANDLE_T h;
	STRUCT_GETINFO info;
	unsigned int i;
	int tmp;
	socklen_t s;

	iptc_fn = TC_INIT;

	if (sockfd != -1)
		close(sockfd);

	sockfd = socket(TC_AF, SOCK_RAW, IPPROTO_RAW);
	if (sockfd < 0)
		return NULL;

	s = sizeof(info);
	if (strlen(tablename) >= TABLE_MAXNAMELEN) {
		errno = EINVAL;
		return NULL;
	}
	strcpy(info.name, tablename);
	if (getsockopt(sockfd, TC_IPPROTO, SO_GET_INFO, &info, &s) < 0)
		return NULL;

	if ((h = alloc_handle(info.name, info.size, info.num_entries))
	    == NULL)
		return NULL;

/* Too hard --RR */
#if 0
	sprintf(pathname, "%s/%s", IPT_LIB_DIR, info.name);
	dynlib = dlopen(pathname, RTLD_NOW);
	if (!dynlib) {
		errno = ENOENT;
		return NULL;
	}
	h->hooknames = dlsym(dynlib, "hooknames");
	if (!h->hooknames) {
		errno = ENOENT;
		return NULL;
	}
#else
	h->hooknames = hooknames;
#endif

	/* Initialize current state */
	h->info = info;
	h->new_number = h->info.num_entries;
	for (i = 0; i < h->info.num_entries; i++)
		h->counter_map[i]
			= ((struct counter_map){COUNTER_MAP_NORMAL_MAP, i});
Exemple #6
0
static int fill_create_thread_event( struct debug_event *event, void *arg )
{
    struct process *debugger = event->debugger->process;
    struct thread *thread = event->sender;
    obj_handle_t handle;

    /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
    if (!(handle = alloc_handle( debugger, thread, THREAD_ALL_ACCESS, 0 ))) return 0;
    event->data.info.create_thread.handle = handle;
    event->data.info.create_thread.teb    = thread->teb;
    event->data.info.create_thread.start  = arg;
    return 1;
}
Exemple #7
0
static fsal_status_t makenode(struct fsal_obj_handle *dir_hdl,
			      const char *name,
			      object_file_type_t nodetype,	/* IN */
			      fsal_dev_t *dev,	/* IN */
			      struct attrlist *attrib,
			      struct fsal_obj_handle **handle)
{
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int retval = 0;
	fsal_status_t status;
	struct pt_fsal_obj_handle *hdl;
	ptfsal_handle_t *dir_fh = NULL;
	ptfsal_handle_t *fh = alloca(sizeof(ptfsal_handle_t));

	*handle = NULL;		/* poison it */
	if (!dir_hdl->ops->handle_is(dir_hdl, DIRECTORY)) {
		LogCrit(COMPONENT_FSAL,
			"Parent handle is not a directory. hdl = 0x%p",
			dir_hdl);

		return fsalstat(ERR_FSAL_NOTDIR, 0);
	}
	memset(fh, 0, sizeof(ptfsal_handle_t));
	fh->data.handle.handle_size = FSI_CCL_PERSISTENT_HANDLE_N_BYTES;

	attrib->mask =
	    op_ctx->fsal_export->ops->fs_supported_attrs(op_ctx->fsal_export);
	status =
	    PTFSAL_mknode(dir_hdl, name, op_ctx, attrib->mode,
			  nodetype, dev, fh,
			  attrib);
	if (FSAL_IS_ERROR(status))
		return status;

	/* allocate an obj_handle and fill it up */
	hdl = alloc_handle(fh, attrib, NULL, dir_fh, NULL,
			   op_ctx->fsal_export);
	if (hdl == NULL) {
		retval = ENOMEM;
		goto nodeerr;
	}
	*handle = &hdl->obj_handle;
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

 nodeerr:
	fsal_error = posix2fsal_error(retval);
	return fsalstat(fsal_error, retval);
}
Exemple #8
0
static int fill_load_dll_event( struct debug_event *event, void *arg )
{
    struct process *debugger = event->debugger->process;
    struct process_dll *dll = arg;
    obj_handle_t handle = 0;

    if (dll->file && !(handle = alloc_handle( debugger, dll->file, GENERIC_READ, 0 )))
        return 0;
    event->data.info.load_dll.handle     = handle;
    event->data.info.load_dll.base       = dll->base;
    event->data.info.load_dll.dbg_offset = dll->dbg_offset;
    event->data.info.load_dll.dbg_size   = dll->dbg_size;
    event->data.info.load_dll.name       = dll->name;
    event->data.info.load_dll.unicode    = 1;
    return 1;
}
Exemple #9
0
/*
 * Call this to do a TLS accept on a sockbuf.
 * Everything else is the same as with tls_connect.
 */
int
ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg )
{
	int	err;
	tls_session	*ssl = NULL;

	if ( HAS_TLS( sb )) {
		ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
	} else {
		ssl = alloc_handle( ctx_arg, 1 );
		if ( ssl == NULL ) return -1;

#ifdef LDAP_DEBUG
		ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
			LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" );
#endif
		ber_sockbuf_add_io( sb, tls_imp->ti_sbio,
			LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
	}

	err = tls_imp->ti_session_accept( ssl );

#ifdef HAVE_WINSOCK
	errno = WSAGetLastError();
#endif

	if ( err < 0 )
	{
		if ( update_flags( sb, ssl, err )) return 1;

		if ( DebugTest( LDAP_DEBUG_ANY ) ) {
			char buf[256], *msg;
			msg = tls_imp->ti_session_errmsg( ssl, err, buf, sizeof(buf) );
			Debug( LDAP_DEBUG_ANY,"TLS: can't accept: %s.\n",
				msg ? msg : "(unknown)", 0, 0 );
		}

		ber_sockbuf_remove_io( sb, tls_imp->ti_sbio,
			LBER_SBIOD_LEVEL_TRANSPORT );
#ifdef LDAP_DEBUG
		ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
			LBER_SBIOD_LEVEL_TRANSPORT );
#endif
		return -1;
	}
	return 0;
}
Exemple #10
0
/* duplicate a handle */
obj_handle_t duplicate_handle( struct process *src, obj_handle_t src_handle, struct process *dst,
                               unsigned int access, unsigned int attr, unsigned int options )
{
    obj_handle_t res;
    struct handle_entry *entry;
    unsigned int src_access;
    struct object *obj = get_handle_obj( src, src_handle, 0, NULL );

    if (!obj) return 0;
    if ((entry = get_handle( src, src_handle )))
        src_access = entry->access;
    else  /* pseudo-handle, give it full access */
        src_access = obj->ops->map_access( obj, GENERIC_ALL );
    src_access &= ~RESERVED_ALL;

    if (options & DUP_HANDLE_SAME_ACCESS)
        access = src_access;
    else
        access = obj->ops->map_access( obj, access ) & ~RESERVED_ALL;

    /* asking for the more access rights than src_access? */
    if (access & ~src_access)
    {
        if (options & DUP_HANDLE_MAKE_GLOBAL)
            res = alloc_global_handle( obj, access );
        else
            res = alloc_handle( dst, obj, access, attr );
    }
    else
    {
        if (options & DUP_HANDLE_MAKE_GLOBAL)
            res = alloc_global_handle_no_access_check( obj, access );
        else if ((options & DUP_HANDLE_CLOSE_SOURCE) && src == dst &&
                 entry && !(entry->access & RESERVED_CLOSE_PROTECT))
        {
            if (attr & OBJ_INHERIT) access |= RESERVED_INHERIT;
            entry->access = access;
            res = src_handle;
        }
        else
            res = alloc_handle_entry( dst, obj, access, attr );
    }

    release_object( obj );
    return res;
}
Exemple #11
0
/* queue an irp to the device */
static obj_handle_t queue_irp( struct device_file *file, struct irp_call *irp,
                               const async_data_t *async_data, int blocking )
{
    obj_handle_t handle = 0;

    if (blocking && !(handle = alloc_handle( current->process, irp, SYNCHRONIZE, 0 ))) return 0;

    if (!(irp->async = fd_queue_async( file->fd, async_data, ASYNC_TYPE_WAIT )))
    {
        if (handle) close_handle( current->process, handle );
        return 0;
    }
    irp->user_arg = async_data->arg;
    add_irp_to_queue( file, irp, current );
    set_error( STATUS_PENDING );
    return handle;
}
Exemple #12
0
/* create
 * create a regular file and set its attributes
 */
fsal_status_t create(struct fsal_obj_handle *dir_hdl,
		     const char *name, struct attrlist *attr_in,
		     struct fsal_obj_handle **handle,
		     struct attrlist *attrs_out)
{
	struct gpfs_fsal_obj_handle *hdl;
	fsal_status_t status;
	/* Use a separate attrlist to getch the actual attributes into */
	struct attrlist attrib;

	struct gpfs_file_handle *fh = alloca(sizeof(struct gpfs_file_handle));

	*handle = NULL;		/* poison it */
	if (!dir_hdl->obj_ops.handle_is(dir_hdl, DIRECTORY)) {
		LogCrit(COMPONENT_FSAL,
			"Parent handle is not a directory. hdl = 0x%p",
			dir_hdl);
		return fsalstat(ERR_FSAL_NOTDIR, 0);
	}
	memset(fh, 0, sizeof(struct gpfs_file_handle));
	fh->handle_size = GPFS_MAX_FH_SIZE;

	fsal_prepare_attrs(&attrib, ATTR_GPFS_ALLOC_HANDLE);

	if (attrs_out != NULL)
		attrib.mask |= attrs_out->mask;

	status =
	    GPFSFSAL_create(dir_hdl, name, op_ctx, attr_in->mode, fh, &attrib);
	if (FSAL_IS_ERROR(status))
		return status;

	/* allocate an obj_handle and fill it up */
	hdl = alloc_handle(fh, dir_hdl->fs, &attrib, NULL, op_ctx->fsal_export);

	if (attrs_out != NULL) {
		/* Copy the attributes to caller, passing ACL ref. */
		fsal_copy_attrs(attrs_out, &attrib, true);
	} else {
		/* Done with the attrs */
		fsal_release_attrs(&attrib);
	}

	*handle = &hdl->obj_handle;
	return fsalstat(ERR_FSAL_NO_ERROR, 0);
}
Exemple #13
0
/******************************************************************************
 *  copy_handle
 *
 * Copies a handle. Increments the reference count of the object referenced
 * by the handle.
 *
 * PARAMS
 *  lpTable [I] Pointer to the handle table, which holds the handle to be copied.
 *  handle  [I] The handle to be copied.
 *  copy    [O] Pointer to a handle variable, where the copied handle is put.
 *
 * RETURNS
 *  non zero,  if successful
 *  zero,      if not successful (invalid handle or out of memory)
 */
int copy_handle(struct handle_table *lpTable, HCRYPTKEY handle, DWORD dwType, HCRYPTKEY *copy)
{
    OBJECTHDR *pObject;
    int ret;
        
    TRACE("(lpTable=%p, handle=%ld, copy=%p)\n", lpTable, handle, copy);

    EnterCriticalSection(&lpTable->mutex);
    if (!lookup_handle(lpTable, handle, dwType, &pObject)) 
    {
        *copy = (HCRYPTKEY)INVALID_HANDLE_VALUE;
        LeaveCriticalSection(&lpTable->mutex);
        return 0;
    }

    ret = alloc_handle(lpTable, pObject, copy);
    LeaveCriticalSection(&lpTable->mutex);
    return ret;
}
Exemple #14
0
/******************************************************************************
 *  copy_handle
 *
 * Copies a handle. Increments the reference count of the object referenced
 * by the handle.
 *
 * PARAMS
 *  lpTable [I] Pointer to the handle table, which holds the handle to be copied.
 *  handle  [I] The handle to be copied.
 *  copy    [O] Pointer to a handle variable, where the copied handle is put.
 *
 * RETURNS
 *  non zero,  if successful
 *  zero,      if not successful (invalid handle or out of memory)
 */
int copy_handle(HANDLETABLE *lpTable, unsigned int handle, DWORD dwType, unsigned int *copy)
{
    OBJECTHDR *pObject;
    int ret;
        
    TRACE("(lpTable=%p, handle=%d, copy=%p)\n", lpTable, handle, copy);

    EnterCriticalSection(&lpTable->mutex);
    if (!lookup_handle(lpTable, handle, dwType, &pObject)) 
    {
        *copy = (unsigned int)INVALID_HANDLE_VALUE;
        LeaveCriticalSection(&lpTable->mutex);
        return 0;
    }

    ret = alloc_handle(lpTable, pObject, copy);
    LeaveCriticalSection(&lpTable->mutex);
    return ret;
}
Exemple #15
0
int sqlcli( int aArg1 )
{
    SQLRETURN    rc;


    SQLHENV  env;  // Environment Handle
    SQLHDBC  dbc;  // Connection Handle
    int      conn_flag;

    env = SQL_NULL_HENV;
    dbc = SQL_NULL_HDBC;
    conn_flag = 0;

    /* allocate handle */
    rc = alloc_handle(env, dbc);
    if ( rc != SQL_SUCCESS )
    {
        free_handle(env, dbc, conn_flag);
        exit(1);
    }

    /* Connect to Altibase Server */
    rc = db_connect(dbc, conn_flag);
    if ( rc != SQL_SUCCESS )
    {
        free_handle(env, dbc, conn_flag);
        exit(1);
    }

    /* select data */
    rc = execute_select(dbc);
    if ( rc != SQL_SUCCESS )
    {
        free_handle(env, dbc, conn_flag);
        exit(1);
    }

    /* disconnect, free handles */
    free_handle(env, dbc, conn_flag);
}
Exemple #16
0
static fsal_status_t pt_lookup(struct fsal_obj_handle *parent,
			       const char *path,
			       struct fsal_obj_handle **handle)
{
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int retval = 0;
	fsal_status_t status;
	struct pt_fsal_obj_handle *hdl;
	struct attrlist attrib;
	ptfsal_handle_t *fh = alloca(sizeof(ptfsal_handle_t));

	*handle = NULL;		/* poison it first */
	if (!path)
		return fsalstat(ERR_FSAL_FAULT, 0);
	memset(fh, 0, sizeof(ptfsal_handle_t));
	fh->data.handle.handle_size = FSI_CCL_PERSISTENT_HANDLE_N_BYTES;
	if (!parent->ops->handle_is(parent, DIRECTORY)) {
		LogCrit(COMPONENT_FSAL,
			"Parent handle is not a directory. hdl = 0x%p", parent);
		return fsalstat(ERR_FSAL_NOTDIR, 0);
	}
	attrib.mask = parent->attributes.mask;
	status = PTFSAL_lookup(op_ctx, parent, path, &attrib, fh);
	if (FSAL_IS_ERROR(status))
		return status;

	/* allocate an obj_handle and fill it up */
	hdl = alloc_handle(fh, &attrib, NULL, NULL, NULL,
			   op_ctx->fsal_export);
	if (hdl == NULL) {
		retval = ENOMEM;
		goto hdlerr;
	}
	*handle = &hdl->obj_handle;
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

 hdlerr:
	fsal_error = posix2fsal_error(retval);
	return fsalstat(fsal_error, retval);
}
Exemple #17
0
static inline int make_file_safe(struct vfs_fsal_obj_handle *dir_hdl,
				 const struct req_op_context *opctx,
				 int dir_fd, const char *name, mode_t unix_mode,
				 uid_t user, gid_t group,
				 struct vfs_fsal_obj_handle **hdl)
{
	int retval;
	struct stat stat;
	vfs_file_handle_t *fh;

	vfs_alloc_handle(fh);

	retval = fchownat(dir_fd, name, user, group, AT_SYMLINK_NOFOLLOW);
	if (retval < 0)
		goto fileerr;

	/* now that it is owned properly, set accessible mode */

	retval = fchmodat(dir_fd, name, unix_mode, 0);
	if (retval < 0)
		goto fileerr;
	retval = vfs_name_to_handle(dir_fd, dir_hdl->obj_handle.fs, name, fh);
	if (retval < 0)
		goto fileerr;
	retval = fstatat(dir_fd, name, &stat, AT_SYMLINK_NOFOLLOW);
	if (retval < 0)
		goto fileerr;

	/* allocate an obj_handle and fill it up */
	*hdl = alloc_handle(dir_fd, fh, dir_hdl->obj_handle.fs, &stat,
			    dir_hdl->handle, name, opctx->fsal_export);
	if (*hdl == NULL)
		return ENOMEM;
	return 0;

 fileerr:
	retval = errno;
	return retval;
}
Exemple #18
0
static obj_handle_t device_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data,
                                  int blocking, const void *data, data_size_t size )
{
    struct device *device = get_fd_user( fd );
    struct ioctl_call *ioctl;
    obj_handle_t handle;

    if (!device->manager)  /* it has been deleted */
    {
        set_error( STATUS_FILE_DELETED );
        return 0;
    }

    if (!(ioctl = create_ioctl( device, code, data, size, get_reply_max_size() )))
        return 0;

    ioctl->thread   = (struct thread *)grab_object( current );
    ioctl->user_arg = async_data->arg;

    if (!(handle = alloc_handle( current->process, ioctl, SYNCHRONIZE, 0 )))
    {
        release_object( ioctl );
        return 0;
    }

    if (!(ioctl->async = fd_queue_async( device->fd, async_data, ASYNC_TYPE_WAIT )))
    {
        close_handle( current->process, handle );
        release_object( ioctl );
        return 0;
    }
    list_add_tail( &device->requests, &ioctl->dev_entry );
    list_add_tail( &device->manager->requests, &ioctl->mgr_entry );
    if (list_head( &device->manager->requests ) == &ioctl->mgr_entry)  /* first one */
        wake_up( &device->manager->obj, 0 );
    /* don't release ioctl since it is now queued in the device */
    set_error( STATUS_PENDING );
    return handle;
}
Exemple #19
0
/* open a new handle to an existing object */
obj_handle_t open_object( struct process *process, obj_handle_t parent, unsigned int access,
                          const struct object_ops *ops, const struct unicode_str *name,
                          unsigned int attributes )
{
    obj_handle_t handle = 0;
    struct directory *root = NULL;
    struct object *obj;

    if (name->len >= 65534)
    {
        set_error( STATUS_OBJECT_NAME_INVALID );
        return 0;
    }

    if (parent && !(root = get_directory_obj( process, parent, 0 ))) return 0;

    if ((obj = open_object_dir( root, name, attributes, ops )))
    {
        handle = alloc_handle( process, obj, access, attributes );
        release_object( obj );
    }
    if (root) release_object( root );
    return handle;
}
Exemple #20
0
fsal_status_t vfs_open2(struct fsal_obj_handle *obj_hdl,
			struct state_t *state,
			fsal_openflags_t openflags,
			enum fsal_create_mode createmode,
			const char *name,
			struct attrlist *attrib_set,
			fsal_verifier_t verifier,
			struct fsal_obj_handle **new_obj,
			struct attrlist *attrs_out,
			bool *caller_perm_check)
{
	int posix_flags = 0;
	int fd, dir_fd;
	int retval = 0;
	mode_t unix_mode;
	fsal_status_t status = {0, 0};
	struct vfs_fd *my_fd = NULL;
	struct vfs_fsal_obj_handle *myself, *hdl = NULL;
	struct stat stat;
	vfs_file_handle_t *fh = NULL;
	bool truncated;
	bool created = false;

	if (state != NULL)
		my_fd = (struct vfs_fd *)(state + 1);

	myself = container_of(obj_hdl, struct vfs_fsal_obj_handle, obj_handle);

	LogAttrlist(COMPONENT_FSAL, NIV_FULL_DEBUG,
		    "attrib_set ", attrib_set, false);

	fsal2posix_openflags(openflags, &posix_flags);

	truncated = (posix_flags & O_TRUNC) != 0;

	LogFullDebug(COMPONENT_FSAL,
		     truncated ? "Truncate" : "No truncate");

	if (createmode >= FSAL_EXCLUSIVE) {
		/* Now fixup attrs for verifier if exclusive create */
		set_common_verifier(attrib_set, verifier);
	}

	if (name == NULL) {
		/* This is an open by handle */
		struct vfs_fsal_obj_handle *myself;

		myself = container_of(obj_hdl,
				      struct vfs_fsal_obj_handle,
				      obj_handle);

		if (obj_hdl->fsal != obj_hdl->fs->fsal) {
			LogDebug(COMPONENT_FSAL,
				 "FSAL %s operation for handle belonging to FSAL %s, return EXDEV",
				 obj_hdl->fsal->name, obj_hdl->fs->fsal->name);
			return fsalstat(posix2fsal_error(EXDEV), EXDEV);
		}

		if (state != NULL) {
			/* Prepare to take the share reservation, but only if we
			 * are called with a valid state (if state is NULL the
			 * caller is a stateless create such as NFS v3 CREATE).
			 */

			/* This can block over an I/O operation. */
			PTHREAD_RWLOCK_wrlock(&obj_hdl->lock);

			/* Check share reservation conflicts. */
			status = check_share_conflict(&myself->u.file.share,
						      openflags,
						      false);

			if (FSAL_IS_ERROR(status)) {
				PTHREAD_RWLOCK_unlock(&obj_hdl->lock);
				return status;
			}

			/* Take the share reservation now by updating the
			 * counters.
			 */
			update_share_counters(&myself->u.file.share,
					      FSAL_O_CLOSED,
					      openflags);

			PTHREAD_RWLOCK_unlock(&obj_hdl->lock);
		} else {
			/* We need to use the global fd to continue, and take
			 * the lock to protect it.
			 */
			my_fd = &hdl->u.file.fd;
			PTHREAD_RWLOCK_wrlock(&obj_hdl->lock);
		}

		status = vfs_open_my_fd(myself, openflags, posix_flags, my_fd);

		if (FSAL_IS_ERROR(status)) {
			if (state == NULL) {
				/* Release the lock taken above, and return
				 * since there is nothing to undo.
				 */
				PTHREAD_RWLOCK_unlock(&obj_hdl->lock);
				return status;
			} else {
				/* Error - need to release the share */
				goto undo_share;
			}
		}

		if (createmode >= FSAL_EXCLUSIVE || truncated) {
			/* Refresh the attributes */
			struct stat stat;

			retval = fstat(my_fd->fd, &stat);

			if (retval == 0) {
				LogFullDebug(COMPONENT_FSAL,
					     "New size = %" PRIx64,
					     stat.st_size);
			} else {
				if (errno == EBADF)
					errno = ESTALE;
				status = fsalstat(posix2fsal_error(errno),
						  errno);
			}

			/* Now check verifier for exclusive, but not for
			 * FSAL_EXCLUSIVE_9P.
			 */
			if (!FSAL_IS_ERROR(status) &&
			    createmode >= FSAL_EXCLUSIVE &&
			    createmode != FSAL_EXCLUSIVE_9P &&
			    !check_verifier_stat(&stat, verifier)) {
				/* Verifier didn't match, return EEXIST */
				status =
				    fsalstat(posix2fsal_error(EEXIST), EEXIST);
			}
		}

		if (state == NULL) {
			/* If no state, release the lock taken above and return
			 * status.
			 */
			PTHREAD_RWLOCK_unlock(&obj_hdl->lock);
			return status;
		}

		if (!FSAL_IS_ERROR(status)) {
			/* Return success. */
			return status;
		}

		(void) vfs_close_my_fd(my_fd);

 undo_share:

		/* Can only get here with state not NULL and an error */

		/* On error we need to release our share reservation
		 * and undo the update of the share counters.
		 * This can block over an I/O operation.
		 */
		PTHREAD_RWLOCK_wrlock(&obj_hdl->lock);

		update_share_counters(&myself->u.file.share,
				      openflags,
				      FSAL_O_CLOSED);

		PTHREAD_RWLOCK_unlock(&obj_hdl->lock);

		return status;
	}

	/* In this path where we are opening by name, we can't check share
	 * reservation yet since we don't have an object_handle yet. If we
	 * indeed create the object handle (there is no race with another
	 * open by name), then there CAN NOT be a share conflict, otherwise
	 * the share conflict will be resolved when the object handles are
	 * merged.
	 */

#ifdef ENABLE_VFS_DEBUG_ACL
	if (createmode != FSAL_NO_CREATE) {
		/* Need to ammend attributes for inherited ACL, these will be
		 * set later. We also need to test for permission to create
		 * since there might be an ACL.
		 */
		struct attrlist attrs;
		fsal_accessflags_t access_type;

		access_type = FSAL_MODE_MASK_SET(FSAL_W_OK) |
			FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_ADD_FILE);
		status = obj_hdl->obj_ops.test_access(obj_hdl, access_type,
						      NULL, NULL, false);

		if (FSAL_IS_ERROR(status))
			return status;

		fsal_prepare_attrs(&attrs, ATTR_ACL);

		status = obj_hdl->obj_ops.getattrs(obj_hdl, &attrs);

		if (FSAL_IS_ERROR(status))
			return status;

		status.major = fsal_inherit_acls(attrib_set, attrs.acl,
						 FSAL_ACE_FLAG_FILE_INHERIT);

		/* Done with the attrs */
		fsal_release_attrs(&attrs);

		if (FSAL_IS_ERROR(status))
			return status;
	}
#endif /* ENABLE_VFS_DEBUG_ACL */

	if (createmode != FSAL_NO_CREATE) {
		/* Now add in O_CREAT and O_EXCL. */
		posix_flags |= O_CREAT;

		/* And if we are at least FSAL_GUARDED, do an O_EXCL create. */
		if (createmode >= FSAL_GUARDED)
			posix_flags |= O_EXCL;

		/* Fetch the mode attribute to use in the openat system call. */
		unix_mode = fsal2unix_mode(attrib_set->mode) &
		    ~op_ctx->fsal_export->exp_ops.fs_umask(op_ctx->fsal_export);

		/* Don't set the mode if we later set the attributes */
		FSAL_UNSET_MASK(attrib_set->mask, ATTR_MODE);
	}

	if (createmode == FSAL_UNCHECKED && (attrib_set->mask != 0)) {
		/* If we have FSAL_UNCHECKED and want to set more attributes
		 * than the mode, we attempt an O_EXCL create first, if that
		 * succeeds, then we will be allowed to set the additional
		 * attributes, otherwise, we don't know we created the file
		 * and this can NOT set the attributes.
		 */
		posix_flags |= O_EXCL;
	}

	dir_fd = vfs_fsal_open(myself, O_PATH | O_NOACCESS, &status.major);

	if (dir_fd < 0)
		return fsalstat(status.major, -dir_fd);

	/** @todo: not sure what this accomplishes... */
	retval = vfs_stat_by_handle(dir_fd, &stat);

	if (retval < 0) {
		retval = errno;
		status = fsalstat(posix2fsal_error(retval), retval);
		goto direrr;
	}

	/* Become the user because we are creating an object in this dir.
	 */
	if (createmode != FSAL_NO_CREATE)
		fsal_set_credentials(op_ctx->creds);

	if ((posix_flags & O_CREAT) != 0)
		fd = openat(dir_fd, name, posix_flags, unix_mode);
	else
		fd = openat(dir_fd, name, posix_flags);

	if (fd == -1 && errno == EEXIST && createmode == FSAL_UNCHECKED) {
		/* We tried to create O_EXCL to set attributes and failed.
		 * Remove O_EXCL and retry. We still try O_CREAT again just in
		 * case file disappears out from under us.
		 *
		 * Note that because we have dropped O_EXCL, later on we will
		 * not assume we created the file, and thus will not set
		 * additional attributes. We don't need to separately track
		 * the condition of not wanting to set attributes.
		 */
		posix_flags &= ~O_EXCL;
		fd = openat(dir_fd, name, posix_flags, unix_mode);
	}

	/* Preserve errno */
	retval = errno;

	/* If we were creating, restore credentials now. */
	if (createmode != FSAL_NO_CREATE)
		fsal_restore_ganesha_credentials();

	if (fd < 0) {
		status = fsalstat(posix2fsal_error(retval), retval);
		goto direrr;
	}

	/* Remember if we were responsible for creating the file.
	 * Note that in an UNCHECKED retry we MIGHT have re-created the
	 * file and won't remember that. Oh well, so in that rare case we
	 * leak a partially created file if we have a subsequent error in here.
	 * Also notify caller to do permission check if we DID NOT create the
	 * file. Note it IS possible in the case of a race between an UNCHECKED
	 * open and an external unlink, we did create the file, but we will
	 * still force a permission check. Of course that permission check
	 * SHOULD succeed since we also won't set the mode the caller requested
	 * and the default file create permissions SHOULD allow the owner
	 * read/write.
	 */
	created = (posix_flags & O_EXCL) != 0;
	*caller_perm_check = !created;

	vfs_alloc_handle(fh);

	retval = vfs_name_to_handle(dir_fd, obj_hdl->fs, name, fh);

	if (retval < 0) {
		retval = errno;
		status = fsalstat(posix2fsal_error(retval), retval);
		goto fileerr;
	}

	retval = fstat(fd, &stat);

	if (retval < 0) {
		retval = errno;
		status = fsalstat(posix2fsal_error(retval), retval);
		goto fileerr;
	}

	/* allocate an obj_handle and fill it up */
	hdl = alloc_handle(dir_fd, fh, obj_hdl->fs, &stat, myself->handle, name,
			   op_ctx->fsal_export);

	if (hdl == NULL) {
		status = fsalstat(posix2fsal_error(ENOMEM), ENOMEM);
		goto fileerr;
	}

	/* If we didn't have a state above, use the global fd. At this point,
	 * since we just created the global fd, no one else can have a
	 * reference to it, and thus we can mamnipulate unlocked which is
	 * handy since we can then call setattr2 which WILL take the lock
	 * without a double locking deadlock.
	 */
	if (my_fd == NULL)
		my_fd = &hdl->u.file.fd;

	my_fd->fd = fd;
	my_fd->openflags = openflags;

	*new_obj = &hdl->obj_handle;

	if (created && attrib_set->mask != 0) {
		/* Set attributes using our newly opened file descriptor as the
		 * share_fd if there are any left to set (mode and truncate
		 * have already been handled).
		 *
		 * Note that we only set the attributes if we were responsible
		 * for creating the file and we have attributes to set.
		 *
		 * Note if we have ENABLE_VFS_DEBUG_ACL an inherited ACL might
		 * be part of the attributes we are setting here.
		 */
		status = (*new_obj)->obj_ops.setattr2(*new_obj,
						      false,
						      state,
						      attrib_set);

		if (FSAL_IS_ERROR(status)) {
			/* Release the handle we just allocated. */
			(*new_obj)->obj_ops.release(*new_obj);
			*new_obj = NULL;
			goto fileerr;
		}

		if (attrs_out != NULL) {
			status = (*new_obj)->obj_ops.getattrs(*new_obj,
							      attrs_out);
			if (FSAL_IS_ERROR(status) &&
			    (attrs_out->mask & ATTR_RDATTR_ERR) == 0) {
				/* Get attributes failed and caller expected
				 * to get the attributes. Otherwise continue
				 * with attrs_out indicating ATTR_RDATTR_ERR.
				 */
				goto fileerr;
			}
		}
	} else if (attrs_out != NULL) {
		/* Since we haven't set any attributes other than what was set
		 * on create (if we even created), just use the stat results
		 * we used to create the fsal_obj_handle.
		 */
		posix2fsal_attributes(&stat, attrs_out);

		/* Make sure ATTR_RDATTR_ERR is cleared on success. */
		attrs_out->mask &= ~ATTR_RDATTR_ERR;
	}

	close(dir_fd);

	if (state != NULL) {
		/* Prepare to take the share reservation, but only if we are
		 * called with a valid state (if state is NULL the caller is
		 * a stateless create such as NFS v3 CREATE).
		 */

		/* This can block over an I/O operation. */
		PTHREAD_RWLOCK_wrlock(&(*new_obj)->lock);

		/* Take the share reservation now by updating the counters. */
		update_share_counters(&hdl->u.file.share,
				      FSAL_O_CLOSED,
				      openflags);

		PTHREAD_RWLOCK_unlock(&(*new_obj)->lock);
	}

	return fsalstat(ERR_FSAL_NO_ERROR, 0);

 fileerr:

	close(fd);

	/* Delete the file if we actually created it. */
	if (created)
		unlinkat(dir_fd, name, 0);

 direrr:

	close(dir_fd);
	return fsalstat(posix2fsal_error(retval), retval);
}
Exemple #21
0
static fsal_status_t lookup(struct fsal_obj_handle *parent,
			    const char *path, struct fsal_obj_handle **handle)
{
	struct vfs_fsal_obj_handle *parent_hdl, *hdl;
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int retval, dirfd;
	struct stat stat;
	vfs_file_handle_t *fh = NULL;
	vfs_alloc_handle(fh);
	fsal_dev_t dev;
	struct fsal_filesystem *fs;
	bool xfsal = false;

	*handle = NULL;		/* poison it first */
	parent_hdl =
	    container_of(parent, struct vfs_fsal_obj_handle, obj_handle);
	if (!parent->obj_ops.handle_is(parent, DIRECTORY)) {
		LogCrit(COMPONENT_FSAL,
			"Parent handle is not a directory. hdl = 0x%p", parent);
		return fsalstat(ERR_FSAL_NOTDIR, 0);
	}

	if (parent->fsal != parent->fs->fsal) {
		LogDebug(COMPONENT_FSAL,
			 "FSAL %s operation for handle belonging to FSAL %s, return EXDEV",
			 parent->fsal->name,
			 parent->fs->fsal != NULL
				? parent->fs->fsal->name
				: "(none)");
		retval = EXDEV;
		goto hdlerr;
	}

	fs = parent->fs;
	dirfd = vfs_fsal_open(parent_hdl, O_PATH | O_NOACCESS, &fsal_error);

	if (dirfd < 0)
		return fsalstat(fsal_error, -dirfd);

	retval = fstatat(dirfd, path, &stat, AT_SYMLINK_NOFOLLOW);

	if (retval < 0) {
		retval = errno;
		goto direrr;
	}

	dev = posix2fsal_devt(stat.st_dev);

	if ((dev.minor != parent_hdl->dev.minor) ||
	    (dev.major != parent_hdl->dev.major)) {
		/* XDEV */
		fs = lookup_dev(&dev);
		if (fs == NULL) {
			LogDebug(COMPONENT_FSAL,
				 "Lookup of %s crosses filesystem boundary to "
				 "unknown file system dev=%"PRIu64".%"PRIu64,
				 path, dev.major, dev.minor);
			retval = EXDEV;
			goto direrr;
		}

		if (fs->fsal != parent->fsal) {
			xfsal = true;
			LogDebug(COMPONENT_FSAL,
				 "Lookup of %s crosses filesystem boundary to file system %s into FSAL %s",
				 path, fs->path,
				 fs->fsal != NULL
					? fs->fsal->name
					: "(none)");
		} else {
			LogDebug(COMPONENT_FSAL,
				 "Lookup of %s crosses filesystem boundary to file system %s",
				 path, fs->path);
		}
	}

	if (xfsal || vfs_name_to_handle(dirfd, fs, path, fh) < 0) {
		retval = errno;
		if (((retval == ENOTTY) ||
		     (retval == EOPNOTSUPP) ||
		     (retval == ENOTSUP) ||
		     xfsal) &&
		    (fs != parent->fs)) {
			/* Crossed device into territory not handled by
			 * this FSAL (XFS or VFS). Need to invent a handle.
			 * The made up handle will be JUST the fsid, we
			 * do not expect to see the handle on the wire, and
			 * this handle will not be valid for any form of this
			 * FSAL.
			 */
			LogDebug(COMPONENT_FSAL,
				 "vfs_name_to_handle %s, inventing FSAL %s handle for FSAL %s filesystem %s",
				 xfsal ? "skipped" : "failed",
				 parent->fsal->name,
				 fs->fsal != NULL
					? fs->fsal->name
					: "(none)",
				 path);

			retval = vfs_encode_dummy_handle(fh, fs);

			if (retval < 0) {
				retval = errno;
				goto direrr;
			}

			retval = 0;
		} else {
			/* Some other error */
			goto direrr;
		}
	}

	/* allocate an obj_handle and fill it up */
	hdl = alloc_handle(dirfd, fh, fs, &stat, parent_hdl->handle, path,
			   op_ctx->fsal_export);
	close(dirfd);
	if (hdl == NULL) {
		retval = ENOMEM;
		goto hdlerr;
	}
	*handle = &hdl->obj_handle;
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

 direrr:
	close(dirfd);
 hdlerr:
	fsal_error = posix2fsal_error(retval);
	return fsalstat(fsal_error, retval);
}
Exemple #22
0
fsal_status_t vfs_create_handle(struct fsal_export *exp_hdl,
				struct gsh_buffdesc *hdl_desc,
				struct fsal_obj_handle **handle)
{
	fsal_status_t status;
	struct vfs_fsal_obj_handle *hdl;
	struct stat obj_stat;
	vfs_file_handle_t *fh = NULL;
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int retval = 0;
	int fd;
	int flags = O_PATH | O_NOACCESS | O_NOFOLLOW;
	struct fsal_filesystem *fs;
	bool dummy;

	vfs_alloc_handle(fh);
	*handle = NULL;		/* poison it first */

	status = vfs_check_handle(exp_hdl, hdl_desc, &fs, fh, &dummy);

	if (FSAL_IS_ERROR(status))
		return status;

	if (dummy) {
		/* We don't need fd here, just stat the fs->path */
		fd = -1;
		retval = stat(fs->path, &obj_stat);
	} else {
		fd = vfs_open_by_handle(fs->private, fh, flags, &fsal_error);

		if (fd < 0) {
			retval = -fd;
			goto errout;
		}

		retval = vfs_stat_by_handle(fd, fh, &obj_stat, flags);
	}

	/* Test the result of stat */
	if (retval != 0) {
		retval = errno;
		LogDebug(COMPONENT_FSAL,
			 "%s failed with %s",
			 dummy ? "stat" : "vfs_stat_by_handle",
			 strerror(retval));
		fsal_error = posix2fsal_error(retval);
		if (fd >= 0)
			close(fd);
		goto errout;
	}

	hdl = alloc_handle(fd, fh, fs, &obj_stat, NULL, "", exp_hdl);

	if (fd >= 0)
		close(fd);

	if (hdl == NULL) {
		LogDebug(COMPONENT_FSAL,
			 "Could not allocate handle");
		fsal_error = ERR_FSAL_NOMEM;
		goto errout;
	}
	*handle = &hdl->obj_handle;

 errout:
	return fsalstat(fsal_error, retval);
}
Exemple #23
0
static fsal_status_t makedir(struct fsal_obj_handle *dir_hdl,
			     const char *name, struct attrlist *attrib,
			     struct fsal_obj_handle **handle)
{
	struct vfs_fsal_obj_handle *myself, *hdl;
	int dir_fd;
	struct stat stat;
	mode_t unix_mode;
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int retval = 0;
	int flags = O_PATH | O_NOACCESS;
	vfs_file_handle_t *fh = NULL;
	vfs_alloc_handle(fh);

	LogDebug(COMPONENT_FSAL, "create %s", name);

	*handle = NULL;		/* poison it */
	if (!dir_hdl->obj_ops.handle_is(dir_hdl, DIRECTORY)) {
		LogCrit(COMPONENT_FSAL,
			"Parent handle is not a directory. hdl = 0x%p",
			dir_hdl);
		return fsalstat(ERR_FSAL_NOTDIR, 0);
	}
	myself = container_of(dir_hdl, struct vfs_fsal_obj_handle, obj_handle);
	if (dir_hdl->fsal != dir_hdl->fs->fsal) {
		LogDebug(COMPONENT_FSAL,
			 "FSAL %s operation for handle belonging to FSAL %s, return EXDEV",
			 dir_hdl->fsal->name,
			 dir_hdl->fs->fsal != NULL
				? dir_hdl->fs->fsal->name
				: "(none)");
		retval = EXDEV;
		goto hdlerr;
	}
	unix_mode = fsal2unix_mode(attrib->mode)
	    & ~op_ctx->fsal_export->exp_ops.fs_umask(op_ctx->fsal_export);
	dir_fd = vfs_fsal_open(myself, flags, &fsal_error);
	if (dir_fd < 0)
		return fsalstat(fsal_error, -dir_fd);
	retval = vfs_stat_by_handle(dir_fd, myself->handle, &stat, flags);
	if (retval < 0) {
		retval = errno;
		goto direrr;
	}
	/* Become the user because we are creating an object in this dir.
	 */
	fsal_set_credentials(op_ctx->creds);
	retval = mkdirat(dir_fd, name, unix_mode);
	if (retval < 0) {
		retval = errno;
		fsal_restore_ganesha_credentials();
		goto direrr;
	}
	fsal_restore_ganesha_credentials();
	retval =  vfs_name_to_handle(dir_fd, dir_hdl->fs, name, fh);
	if (retval < 0) {
		retval = errno;
		goto fileerr;
	}
	retval = fstatat(dir_fd, name, &stat, AT_SYMLINK_NOFOLLOW);
	if (retval < 0) {
		retval = errno;
		goto fileerr;
	}

	/* allocate an obj_handle and fill it up */
	hdl = alloc_handle(dir_fd, fh, dir_hdl->fs, &stat,
			   myself->handle, name,
			   op_ctx->fsal_export);
	if (hdl == NULL) {
		retval = ENOMEM;
		goto fileerr;
	}
	*handle = &hdl->obj_handle;

	close(dir_fd);
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

 fileerr:
	unlinkat(dir_fd, name, 0);
 direrr:
	close(dir_fd);
 hdlerr:
	fsal_error = posix2fsal_error(retval);
	return fsalstat(fsal_error, retval);
}
Exemple #24
0
static int
ldap_int_tls_connect( LDAP *ld, LDAPConn *conn )
{
	Sockbuf *sb = conn->lconn_sb;
	int	err;
	tls_session	*ssl = NULL;

	if ( HAS_TLS( sb )) {
		ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
	} else {
		struct ldapoptions *lo;
		tls_ctx *ctx;

		ctx = ld->ld_options.ldo_tls_ctx;

		ssl = alloc_handle( ctx, 0 );

		if ( ssl == NULL ) return -1;

#ifdef LDAP_DEBUG
		ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
			LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" );
#endif
		ber_sockbuf_add_io( sb, tls_imp->ti_sbio,
			LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );

		lo = LDAP_INT_GLOBAL_OPT();   
		if( ctx == NULL ) {
			ctx = lo->ldo_tls_ctx;
			ld->ld_options.ldo_tls_ctx = ctx;
			tls_ctx_ref( ctx );
		}
		if ( ld->ld_options.ldo_tls_connect_cb )
			ld->ld_options.ldo_tls_connect_cb( ld, ssl, ctx,
			ld->ld_options.ldo_tls_connect_arg );
		if ( lo && lo->ldo_tls_connect_cb && lo->ldo_tls_connect_cb !=
			ld->ld_options.ldo_tls_connect_cb )
			lo->ldo_tls_connect_cb( ld, ssl, ctx, lo->ldo_tls_connect_arg );
	}

	err = tls_imp->ti_session_connect( ld, ssl );

#ifdef HAVE_WINSOCK
	errno = WSAGetLastError();
#endif

	if ( err < 0 )
	{
		char buf[256], *msg;
		if ( update_flags( sb, ssl, err )) {
			return 1;
		}

		msg = tls_imp->ti_session_errmsg( ssl, err, buf, sizeof(buf) );
		if ( msg ) {
			if ( ld->ld_error ) {
				LDAP_FREE( ld->ld_error );
			}
			ld->ld_error = LDAP_STRDUP( msg );
#ifdef HAVE_EBCDIC
			if ( ld->ld_error ) __etoa(ld->ld_error);
#endif
		}

		Debug( LDAP_DEBUG_ANY,"TLS: can't connect: %s.\n",
			ld->ld_error ? ld->ld_error : "" ,0,0);

		ber_sockbuf_remove_io( sb, tls_imp->ti_sbio,
			LBER_SBIOD_LEVEL_TRANSPORT );
#ifdef LDAP_DEBUG
		ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
			LBER_SBIOD_LEVEL_TRANSPORT );
#endif
		return -1;
	}

	return 0;
}
Exemple #25
0
static fsal_status_t makesymlink(struct fsal_obj_handle *dir_hdl,
				 const char *name, const char *link_path,
				 struct attrlist *attrib,
				 struct fsal_obj_handle **handle)
{
	struct vfs_fsal_obj_handle *myself, *hdl;
	int dir_fd = -1;
	struct stat stat;
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int retval = 0;
	int flags = O_PATH | O_NOACCESS;
	vfs_file_handle_t *fh = NULL;
	vfs_alloc_handle(fh);

	LogDebug(COMPONENT_FSAL, "create %s", name);

	*handle = NULL;		/* poison it first */
	if (!dir_hdl->obj_ops.handle_is(dir_hdl, DIRECTORY)) {
		LogCrit(COMPONENT_FSAL,
			"Parent handle is not a directory. hdl = 0x%p",
			dir_hdl);
		return fsalstat(ERR_FSAL_NOTDIR, 0);
	}
	myself = container_of(dir_hdl, struct vfs_fsal_obj_handle, obj_handle);
	if (dir_hdl->fsal != dir_hdl->fs->fsal) {
		LogDebug(COMPONENT_FSAL,
			 "FSAL %s operation for handle belonging to FSAL %s, return EXDEV",
			 dir_hdl->fsal->name,
			 dir_hdl->fs->fsal != NULL
				? dir_hdl->fs->fsal->name
				: "(none)");
		retval = EXDEV;
		goto hdlerr;
	}
	dir_fd = vfs_fsal_open(myself, flags, &fsal_error);
	if (dir_fd < 0)
		return fsalstat(fsal_error, -dir_fd);
	flags |= O_NOFOLLOW;	/* BSD needs O_NOFOLLOW for
				 * fhopen() of symlinks */
	retval = vfs_stat_by_handle(dir_fd, myself->handle, &stat, flags);
	if (retval < 0) {
		retval = errno;
		goto direrr;
	}
	/* Become the user because we are creating an object in this dir.
	 */
	fsal_set_credentials(op_ctx->creds);
	retval = symlinkat(link_path, dir_fd, name);
	if (retval < 0) {
		retval = errno;
		fsal_restore_ganesha_credentials();
		goto direrr;
	}
	fsal_restore_ganesha_credentials();
	retval = vfs_name_to_handle(dir_fd, dir_hdl->fs, name, fh);
	if (retval < 0) {
		retval = errno;
		goto linkerr;
	}
	/* now get attributes info,
	 * being careful to get the link, not the target */
	retval = fstatat(dir_fd, name, &stat, AT_SYMLINK_NOFOLLOW);
	if (retval < 0) {
		retval = errno;
		goto linkerr;
	}

	/* allocate an obj_handle and fill it up */
	hdl = alloc_handle(dir_fd, fh, dir_hdl->fs, &stat, NULL, name,
			   op_ctx->fsal_export);
	if (hdl == NULL) {
		retval = ENOMEM;
		goto linkerr;
	}
	*handle = &hdl->obj_handle;

	close(dir_fd);
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

 linkerr:
	unlinkat(dir_fd, name, 0);

 direrr:
	close(dir_fd);
 hdlerr:
	if (retval == ENOENT)
		fsal_error = ERR_FSAL_STALE;
	else
		fsal_error = posix2fsal_error(retval);
	return fsalstat(fsal_error, retval);
}
Exemple #26
0
/* lookup
 * deprecated NULL parent && NULL path implies root handle
 */
static fsal_status_t lustre_lookup(struct fsal_obj_handle *parent,
				   const char *path,
				   struct fsal_obj_handle **handle)
{
	struct lustre_fsal_obj_handle *parent_hdl, *hdl;
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int rc;
	struct stat stat;
	char *link_content = NULL;
	struct lustre_file_handle *dir_hdl = NULL;
	const char *sock_name = NULL;
	ssize_t retlink;
	char fidpath[MAXPATHLEN];
	char link_buff[PATH_MAX+1];
	struct lustre_file_handle *fh =
	    alloca(sizeof(struct lustre_file_handle));
	struct fsal_filesystem *fs;

	*handle = NULL;		/* poison it first */
	fs = parent->fs;

	if (!path)
		return fsalstat(ERR_FSAL_FAULT, 0);

	memset(fh, 0, sizeof(struct lustre_file_handle));
	parent_hdl =
	    container_of(parent, struct lustre_fsal_obj_handle, obj_handle);
	if (!parent->ops->handle_is(parent, DIRECTORY)) {
		LogCrit(COMPONENT_FSAL,
			"Parent handle is not a directory. hdl = 0x%p", parent);
		return fsalstat(ERR_FSAL_NOTDIR, 0);
	}

	if (parent->fsal != parent->fs->fsal) {
		LogDebug(COMPONENT_FSAL,
			 "FSAL %s operation for handle belonging to FSAL %s, return EXDEV",
			 parent->fsal->name, parent->fs->fsal->name);
		rc = EXDEV;
		return fsalstat(posix2fsal_error(rc), rc);
	}

	rc = lustre_name_to_handle_at(fs->path,
					  parent_hdl->handle, path, fh, 0);
	if (rc < 0) {
		rc = errno;
		fsal_error = posix2fsal_error(rc);
		goto errout;
	}

	lustre_handle_to_path(fs->path, fh,
			      fidpath);

	rc = lstat(fidpath, &stat);
	if (rc < 0) {
		rc = errno;
		fsal_error = posix2fsal_error(rc);
		goto errout;
	}
	if (S_ISLNK(stat.st_mode)) {	/* I could lazy eval this... */
		retlink = readlink(fidpath, link_buff, PATH_MAX);
		if (retlink < 0 || retlink == PATH_MAX) {
			rc = errno;
			if (retlink == PATH_MAX)
				rc = ENAMETOOLONG;
			fsal_error = posix2fsal_error(rc);
			goto errout;
		}
		link_buff[retlink] = '\0';
		link_content = &link_buff[0];
	} else if (S_ISSOCK(stat.st_mode)) {
		dir_hdl = parent_hdl->handle;
		sock_name = path;
	}
	/* allocate an obj_handle and fill it up */
	hdl =
	    alloc_handle(fh, fs, &stat, link_content, dir_hdl, sock_name,
			 op_ctx->fsal_export);
	if (hdl != NULL) {
		*handle = &hdl->obj_handle;
	} else {
		fsal_error = ERR_FSAL_NOMEM;
		*handle = NULL;	/* poison it */
		goto errout;
	}
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

 errout:
	return fsalstat(fsal_error, rc);
}
Exemple #27
0
static fsal_status_t lustre_makedir(struct fsal_obj_handle *dir_hdl,
				    const char *name, struct attrlist *attrib,
				    struct fsal_obj_handle **handle)
{
	struct lustre_fsal_obj_handle *myself, *hdl;
	char dirpath[MAXPATHLEN];
	char newpath[MAXPATHLEN];
	struct stat stat;
	mode_t unix_mode;
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int rc = 0;
	struct lustre_file_handle *fh =
	    alloca(sizeof(struct lustre_file_handle));

	*handle = NULL;		/* poison it */
	if (!dir_hdl->ops->handle_is(dir_hdl, DIRECTORY)) {
		LogCrit(COMPONENT_FSAL,
			"Parent handle is not a directory. hdl = 0x%p",
			dir_hdl);
		return fsalstat(ERR_FSAL_NOTDIR, 0);
	}
	memset(fh, 0, sizeof(struct lustre_file_handle));
	myself =
	    container_of(dir_hdl, struct lustre_fsal_obj_handle, obj_handle);
	unix_mode = fsal2unix_mode(attrib->mode)
	    & ~op_ctx->fsal_export->ops->fs_umask(op_ctx->fsal_export);
	lustre_handle_to_path(dir_hdl->fs->path,
			      myself->handle, dirpath);
	rc = lstat(dirpath, &stat);
	if (rc < 0) {
		rc = errno;
		goto direrr;
	}

	/* create it with no access because we are root when we do this */
	snprintf(newpath, MAXPATHLEN, "%s/%s", dirpath, name);
	rc = CRED_WRAP(op_ctx->creds, int, mkdir, newpath, unix_mode);
	if (rc < 0) {
		rc = errno;
		goto direrr;
	}
	rc =
	    get_stat_by_handle_at(dir_hdl->fs->path,
				  myself->handle, name, fh, &stat);
	if (rc < 0)
		goto fileerr;

	/* allocate an obj_handle and fill it up */
	hdl = alloc_handle(fh, dir_hdl->fs,
			   &stat, NULL, NULL, NULL, op_ctx->fsal_export);
	if (hdl != NULL) {
		*handle = &hdl->obj_handle;
	} else {
		fsal_error = ERR_FSAL_NOMEM;
		goto errout;
	}
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

 direrr:
	rc = errno;
	fsal_error = posix2fsal_error(rc);

	return fsalstat(fsal_error, rc);

 fileerr:
	fsal_error = posix2fsal_error(rc);
	rmdir(newpath);		/* remove the evidence on errors */
 errout:
	return fsalstat(fsal_error, rc);
}
Exemple #28
0
static fsal_status_t lustre_makenode(struct fsal_obj_handle *dir_hdl,
				     const char *name,
				     object_file_type_t nodetype,	/* IN */
				     fsal_dev_t *dev,	/* IN */
				     struct attrlist *attrib,
				     struct fsal_obj_handle **handle)
{
	struct lustre_fsal_obj_handle *myself, *hdl;
	char dirpath[MAXPATHLEN];
	char newpath[MAXPATHLEN];
	struct stat stat;
	mode_t unix_mode;
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int rc = 0;
	dev_t unix_dev = 0;
	struct lustre_file_handle *dir_fh = NULL;
	const char *sock_name = NULL;
	struct lustre_file_handle *fh =
	    alloca(sizeof(struct lustre_file_handle));

	*handle = NULL;		/* poison it */
	if (!dir_hdl->ops->handle_is(dir_hdl, DIRECTORY)) {
		LogCrit(COMPONENT_FSAL,
			"Parent handle is not a directory. hdl = 0x%p",
			dir_hdl);

		return fsalstat(ERR_FSAL_NOTDIR, 0);
	}
	memset(fh, 0, sizeof(struct lustre_file_handle));
	myself =
	    container_of(dir_hdl, struct lustre_fsal_obj_handle, obj_handle);
	unix_mode = fsal2unix_mode(attrib->mode)
	    & ~op_ctx->fsal_export->ops->fs_umask(op_ctx->fsal_export);
	switch (nodetype) {
	case BLOCK_FILE:
		if (!dev) {
			fsal_error = ERR_FSAL_FAULT;
			goto errout;
		}
		unix_dev =
		    CRED_WRAP(op_ctx->creds, dev_t, makedev, dev->major,
			      dev->minor);
		break;
	case CHARACTER_FILE:
		if (!dev) {
			fsal_error = ERR_FSAL_FAULT;
			goto errout;

		}
		unix_dev =
		    CRED_WRAP(op_ctx->creds, dev_t, makedev, dev->major,
			      dev->minor);
		break;
	case FIFO_FILE:
		break;
	case SOCKET_FILE:
		dir_fh = myself->handle;
		sock_name = name;
		break;
	default:
		LogMajor(COMPONENT_FSAL, "Invalid node type in FSAL_mknode: %d",
			 nodetype);
		fsal_error = ERR_FSAL_INVAL;
		goto errout;
	}
	lustre_handle_to_path(dir_hdl->fs->path,
			      myself->handle, dirpath);
	rc = lstat(dirpath, &stat);
	if (rc < 0) {
		rc = errno;
		goto errout;
	}

	/* create it with no access because we are root when we do this */
	snprintf(newpath, MAXPATHLEN, "%s/%s", dirpath, name);
	rc =
	    CRED_WRAP(op_ctx->creds, int, mknod, newpath, unix_mode, unix_dev);
	if (rc < 0) {
		rc = errno;
		goto direrr;
	}
	rc =
	    get_stat_by_handle_at(dir_hdl->fs->path,
				  myself->handle, name, fh, &stat);
	if (rc < 0)
		goto direrr;

	/* allocate an obj_handle and fill it up */
	hdl = alloc_handle(fh, dir_hdl->fs,
			   &stat, NULL, dir_fh, sock_name,
			   op_ctx->fsal_export);
	if (hdl == NULL) {
		fsal_error = ERR_FSAL_NOMEM;
		goto unlinkout;
	}
	*handle = &hdl->obj_handle;
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

 direrr:
	fsal_error = posix2fsal_error(rc);
 unlinkout:
	unlink(newpath);
 errout:
	return fsalstat(fsal_error, rc);
}
Exemple #29
0
static fsal_status_t lustre_makesymlink(struct fsal_obj_handle *dir_hdl,
					const char *name, const char *link_path,
					struct attrlist *attrib,
					struct fsal_obj_handle **handle)
{
	struct lustre_fsal_obj_handle *myself, *hdl;
	char dirpath[MAXPATHLEN];
	char newpath[MAXPATHLEN];
	struct stat stat;
	fsal_errors_t fsal_error = ERR_FSAL_NO_ERROR;
	int rc = 0;
	uid_t user;
	gid_t group;
	struct lustre_file_handle *fh =
	    alloca(sizeof(struct lustre_file_handle));

	*handle = NULL;		/* poison it first */
	if (!dir_hdl->ops->handle_is(dir_hdl, DIRECTORY)) {
		LogCrit(COMPONENT_FSAL,
			"Parent handle is not a directory. hdl = 0x%p",
			dir_hdl);
		return fsalstat(ERR_FSAL_NOTDIR, 0);
	}
	memset(fh, 0, sizeof(struct lustre_file_handle));
	myself =
	    container_of(dir_hdl, struct lustre_fsal_obj_handle, obj_handle);
	user = attrib->owner;
	group = attrib->group;
	lustre_handle_to_path(dir_hdl->fs->path,
			      myself->handle, dirpath);
	rc = lstat(dirpath, &stat);
	if (rc < 0)
		goto direrr;
	if (stat.st_mode & S_ISGID) {
		/*setgid bit on dir propagates dir group owner */
		group = -1;
	}

	/* create it with no access because we are root when we do this */
	snprintf(newpath, MAXPATHLEN, "%s/%s", dirpath, name);

	rc = CRED_WRAP(op_ctx->creds, int, symlink, link_path, newpath);
	if (rc < 0)
		goto direrr;

	/* do this all by hand because we can't use fchmodat on symlinks...
	 */
	rc = lchown(newpath, user, group);
	if (rc < 0)
		goto linkerr;

	rc =
	    lustre_name_to_handle_at(dir_hdl->fs->path,
				     myself->handle, name, fh, 0);
	if (rc < 0)
		goto linkerr;

	/* now get attributes info, being careful
	 * to get the link, not the target */
	rc = lstat(newpath, &stat);
	if (rc < 0)
		goto linkerr;

	/* allocate an obj_handle and fill it up */
	hdl = alloc_handle(fh, dir_hdl->fs,
			   &stat, link_path, NULL, NULL,
			   op_ctx->fsal_export);
	if (hdl == NULL) {
		rc = ENOMEM;
		goto errout;
	}
	*handle = &hdl->obj_handle;
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

 linkerr:
	rc = errno;
	unlink(newpath);
	goto errout;

 direrr:
	rc = errno;
 errout:
	if (rc == ENOENT)
		fsal_error = ERR_FSAL_STALE;
	else
		fsal_error = posix2fsal_error(rc);
	return fsalstat(fsal_error, rc);
}
Exemple #30
0
static long stm_v4l2_do_ioctl(struct file  *file, unsigned int  cmd, void *arg)
#endif
{
  struct stm_v4l2_handles *handle = file->private_data;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
  unsigned int     minor          = iminor(inode);
#else
  unsigned minor = iminor(file->f_dentry->d_inode);
#endif
  int ret = 0;
  int type = -1,index  = -1;
  int n;

    switch (cmd)
    {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)
    case VIDIOC_RESERVED:         //_IO   ('V',  1)
    case VIDIOC_G_MPEGCOMP:       //_IOR  ('V',  6, struct v4l2_mpeg_compression)
    case VIDIOC_S_MPEGCOMP:       //_IOW  ('V',  7, struct v4l2_mpeg_compression)
    case VIDIOC_G_PRIORITY:       //_IOR  ('V', 67, enum v4l2_priority)
    case VIDIOC_S_PRIORITY:       //_IOW  ('V', 68, enum v4l2_priority)
    case VIDIOC_G_SLICED_VBI_CAP: //_IOR  ('V', 69, struct v4l2_sliced_vbi_cap)
    case VIDIOC_G_MODULATOR:      //_IOWR ('V', 54, struct v4l2_modulator)
    case VIDIOC_S_MODULATOR:      //_IOW  ('V', 55, struct v4l2_modulator)
    case VIDIOC_G_FREQUENCY:      //_IOWR ('V', 56, struct v4l2_frequency)
    case VIDIOC_S_FREQUENCY:      //_IOW  ('V', 57, struct v4l2_frequency)
    case VIDIOC_G_TUNER:          //_IOWR ('V', 29, struct v4l2_tuner)
    case VIDIOC_S_TUNER:          //_IOW  ('V', 30, struct v4l2_tuner)
    case VIDIOC_G_JPEGCOMP:       //_IOR  ('V', 61, struct v4l2_jpegcompression)
    case VIDIOC_S_JPEGCOMP:       //_IOW  ('V', 62, struct v4l2_jpegcompression)
    default:
      debug_msg("IOCTL is not implemented\n");
      ret = -ENODEV;// TIMPLEMENTED;
      break;
#endif
      // video ioctls
    case VIDIOC_QUERYCAP:         //_IOR  ('V',  0, struct v4l2_capability)
    {
      struct v4l2_capability *b = arg;

      //debug_msg("v4l2_ioctl - VIDIOC_QUERYCAP\n");

      strcpy(b->driver, "stm_v4l2");
      strcpy(b->card, "STMicroelectronics CE Device");
      strcpy(b->bus_info,"");

      b->version      = LINUX_VERSION_CODE;
      b->capabilities = V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
      return 0;
    }

      // audio input ioctls
    case VIDIOC_G_AUDIO:          //_IOR  ('V', 33, struct v4l2_audio)
    case VIDIOC_S_AUDIO:          //_IOW  ('V', 34, struct v4l2_audio)
    case VIDIOC_ENUMAUDIO:        //_IOWR ('V', 65, struct v4l2_audio)
      {
	struct v4l2_audio *audio = arg;
	type = STM_V4L2_AUDIO_INPUT;
	if (audio) index = audio->index;
	else ret = -EINVAL;
      }
      break;

      // audio output ioctls
    case VIDIOC_ENUMAUDOUT:       //_IOWR ('V', 66, struct v4l2_audioout)
    case VIDIOC_G_AUDOUT:         //_IOR  ('V', 49, struct v4l2_audioout)
    case VIDIOC_S_AUDOUT:         //_IOW  ('V', 50, struct v4l2_audioout)
      {
	struct v4l2_audio *audio = arg;
	type = STM_V4L2_AUDIO_OUTPUT;
	if (audio) index = audio->index;
	else ret = -EINVAL;
      }
      break;


      // video input ioctls
    case VIDIOC_ENUMINPUT:        //_IOWR ('V', 26, struct v4l2_input)
      {
	struct v4l2_input *input = arg;
	type = STM_V4L2_VIDEO_INPUT;
	if (input) index = input->index;
	else ret = -EINVAL;
      }
      break;

    case VIDIOC_G_INPUT:          //_IOR  ('V', 38, int)
    case VIDIOC_S_INPUT:          //_IOWR ('V', 39, int)
      {
	int *input = arg;
	type = STM_V4L2_VIDEO_INPUT;
	if (arg) index = *input;
	else ret = -EINVAL;
      }
      break;

    case VIDIOC_G_FBUF:           //_IOR  ('V', 10, struct v4l2_framebuffer)
    case VIDIOC_S_FBUF:           //_IOW  ('V', 11, struct v4l2_framebuffer)
    case VIDIOC_OVERLAY:          //_IOW  ('V', 14, int)
	type = STM_V4L2_VIDEO_INPUT;
	break;

	// these are for inputs only, read the spec...
    case VIDIOC_G_STD:            //_IOR  ('V', 23, v4l2_std_id)
    case VIDIOC_S_STD:            //_IOW  ('V', 24, v4l2_std_id)
      	type = STM_V4L2_VIDEO_INPUT;
	break;


      // video output ioctls
    case VIDIOC_G_OUTPUT:         //_IOR  ('V', 46, int)
    case VIDIOC_S_OUTPUT:         //_IOWR ('V', 47, int)
      {
	int *input = arg;
	type = STM_V4L2_VIDEO_OUTPUT;
	if (arg) index = *input;
	else ret = -EINVAL;
      }
      break;

    case VIDIOC_ENUMOUTPUT:       //_IOWR ('V', 48, struct v4l2_output)
      {
	struct v4l2_output *output = arg;
	type = STM_V4L2_VIDEO_OUTPUT;
	if (output) index = output->index;
	else ret = -EINVAL;
      }
      break;

    case VIDIOC_G_FMT:            //_IOWR ('V',  4, struct v4l2_format)
    case VIDIOC_S_FMT:            //_IOWR ('V',  5, struct v4l2_format)
    case VIDIOC_TRY_FMT:          //_IOWR ('V', 64, struct v4l2_format)
      {
	struct v4l2_format *format = arg;
	if (format) {
	  if (format->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
	    type = STM_V4L2_VIDEO_OUTPUT;
	  else
	    type = STM_V4L2_VIDEO_INPUT;
	} else ret = -EINVAL;
      }
      break;

      // this needs to be generic, and probably a way to allocate from video or system memory
      // remember buffers can be allocated for input or output, for the moment we will pass to the driver
    case VIDIOC_REQBUFS:          //_IOWR ('V',  8, struct v4l2_requestbuffers)
      {
	struct v4l2_requestbuffers *rb = arg;
	if (rb) {
	  if (rb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
	    type = STM_V4L2_VIDEO_OUTPUT;
	  else
	    type = STM_V4L2_VIDEO_INPUT;
	} else ret = -EINVAL;
      }
      break;

    case VIDIOC_QUERYBUF:         //_IOWR ('V',  9, struct v4l2_buffer)
    case VIDIOC_QBUF:             //_IOWR ('V', 15, struct v4l2_buffer)
    case VIDIOC_DQBUF:            //_IOWR ('V', 17, struct v4l2_buffer)
      {
	struct v4l2_buffer *buffer = arg;
	if (buffer) {
	  if (buffer->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
	    type = STM_V4L2_VIDEO_OUTPUT;
	  else
	    type = STM_V4L2_VIDEO_INPUT;

	} else ret = -EINVAL;
      }
      break;

    case VIDIOC_G_PARM:           //_IOWR ('V', 21, struct v4l2_streamparm)
    case VIDIOC_S_PARM:           //_IOWR ('V', 22, struct v4l2_streamparm)
      {
	struct v4l2_streamparm *param = arg;
	if (param) {
	  if (param->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
	    type = STM_V4L2_VIDEO_OUTPUT;
	  else
	    type = STM_V4L2_VIDEO_INPUT;
	} else ret = -EINVAL;
      }
      break;

    case VIDIOC_CROPCAP:          //_IOWR ('V', 58, struct v4l2_cropcap)
      {
	struct v4l2_cropcap *cropcap = arg;
	if (cropcap) {
	  if (cropcap->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
	    type = STM_V4L2_VIDEO_OUTPUT;
	  else
	    type = STM_V4L2_VIDEO_INPUT;
	} else ret = -EINVAL;
      }
      break;

    case VIDIOC_G_CROP:           //_IOWR ('V', 59, struct v4l2_crop)
    case VIDIOC_S_CROP:           //_IOW  ('V', 60, struct v4l2_crop)
      {
	struct v4l2_crop *crop = arg;
	if (crop) {
		// what should we do about BUF_TYPE_PRIVATE
	  if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT || crop->type == V4L2_BUF_TYPE_PRIVATE)
	    type = STM_V4L2_VIDEO_OUTPUT;
	  else
	    type = STM_V4L2_VIDEO_INPUT;
	} else ret = -EINVAL;
      }
      break;

      // can be input or output but why not audio?????
    case VIDIOC_STREAMON:         //_IOW  ('V', 18, int)
    case VIDIOC_STREAMOFF:        //_IOW  ('V', 19, int)
      {
	int *v4ltype = arg;
	if (v4ltype) {
	  if (*v4ltype == V4L2_BUF_TYPE_VIDEO_OUTPUT)
	    type = STM_V4L2_VIDEO_OUTPUT;
	  else
	    type = STM_V4L2_VIDEO_INPUT;
	} else ret = -EINVAL;
      }
      break;

      // Driver independent
      // however we need to get the correct ones
    case VIDIOC_ENUM_FMT:         //_IOWR ('V',  2, struct v4l2_fmtdesc)
      {
	struct v4l2_fmtdesc *crop = arg;
	if (crop) {
	  if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
	    type = STM_V4L2_VIDEO_OUTPUT;
	  else
	    type = STM_V4L2_VIDEO_INPUT;
	} else ret = -EINVAL;
      }
      break;

      // These should be driver independent the stmvout modules does not
      // comply with the spec...
    case VIDIOC_ENUMSTD:          //_IOWR ('V', 25, struct v4l2_standard)
    case VIDIOC_QUERYSTD:         //_IOR  ('V', 63, v4l2_std_id)
      type = STM_V4L2_VIDEO_OUTPUT;
      break;

      // control ioctls
    case VIDIOC_G_CTRL:           //_IOWR ('V', 27, struct v4l2_control)
    case VIDIOC_S_CTRL:           //_IOWR ('V', 28, struct v4l2_control)
    case VIDIOC_QUERYCTRL:        //_IOWR ('V', 36, struct v4l2_queryctrl)
    case VIDIOC_QUERYMENU:        //_IOWR ('V', 37, struct v4l2_querymenu)
      { // cheat a little we know id is always first one
	struct v4l2_control *control = arg;
	if (arg) index = control->id;
	else ret = -EINVAL;

	type = STM_V4L2_VIDEO_INPUT;
      }
      break;
    };

    // Cool now we have all the information we need.

    // first if we got an error lets just return that
    if (ret) return ret;

    // If it is a control let's deal with that
    if (type==STM_V4L2_MAX_TYPES) {
      for (n=0;n<number_drivers;n++)
	if (index >= drivers[n].control_start_index[minor] && index < (drivers[n].control_start_index[minor] + drivers[n].number_controls[minor]))
	  {
	    struct v4l2_control *control = arg;

	    control->id -= drivers[n].control_start_index[minor];
	    ret = drivers[n].ioctl(handle,&drivers[n],minor,drivers[n].type,file,cmd,arg);
	    control->id += drivers[n].control_start_index[minor];
	    return ret;
	  }
      return -EINVAL;
    }


    // if no handle, then we need to get one
    // or there would be no handle for a specified type
    if (!handle || (handle && type != -1 && handle->v4l2type[type].driver == NULL)) {
		if (!handle) handle = alloc_handle();

      		for (n=0;n<number_drivers;n++) {
				if (type == -1 || type == drivers[n].type) {
				  ret = drivers[n].ioctl(handle,&drivers[n],minor,drivers[n].type,file,cmd,arg);
	  				if (handle->v4l2type[drivers[n].type].handle) {
	    				if (ret) printk("%s: BUG ON... can't set a handle and return an error\n",__FUNCTION__);
					    	handle->v4l2type[drivers[n].type].driver = &drivers[n];
						handle->device = minor;
						printk("%s: Assigning handle %x to device %d\n",__FUNCTION__,(unsigned int)handle,minor);
				    	file->private_data = handle;
				    	return ret;
	  				}

				  // Not sure if this is safe but if the driver didn't return a problem then assume
				  // it was an enum or something that didn't need to be associated (allocated is too strong a word)
				 if (!ret) {
				    if (!file->private_data) memset(handle,0,sizeof(struct stm_v4l2_handles));
				    return ret;
				  }
			}
		}

      // Nothing worked so clear the handle and go again
      if (!file->private_data) memset(handle,0,sizeof(struct stm_v4l2_handles));
      return -ENODEV;
    }

    // Ok if type != -1 and handle[type].driver->ioctl and handle[type].handle, just call it
    if (type != -1)
    {
      if (handle->v4l2type[type].driver)
      {
	return handle->v4l2type[type].driver->ioctl(handle,handle->v4l2type[type].driver,minor,type,file,cmd,arg);
      }
      else
      {
		return -ENODEV;
      }
    }

    for (n=0;n<STM_V4L2_MAX_TYPES;n++)
      if (handle->v4l2type[n].driver)
	if (!handle->v4l2type[n].driver->ioctl(handle,handle->v4l2type[n].driver,minor,n,file,cmd,arg))
      	  return 0;

    return -ENODEV;
}