Samba 3.3 recall offline file support - Samba

This is a discussion on Samba 3.3 recall offline file support - Samba ; This series of patches adds FSCTL_RECALL_FILE support to Samba 3.3. for details on the fsctl: http://msdn.microsoft.com/en-us/libr...87(VS.85).aspx This is a 3.3 rebase of previously sent patches, as well as a correction to how pad1 and pad2 fields are calculated in nttrans ...

+ Reply to Thread
Results 1 to 17 of 17

Thread: Samba 3.3 recall offline file support

  1. Samba 3.3 recall offline file support

    This series of patches adds FSCTL_RECALL_FILE support to Samba 3.3.

    for details on the fsctl:
    http://msdn.microsoft.com/en-us/libr...87(VS.85).aspx

    This is a 3.3 rebase of previously sent patches, as well as a correction
    to how pad1 and pad2 fields are calculated in nttrans response packets.

    Tested with QUERY / SET SECURITY_DESC, NOTIFY_CHANGE and FSCTL_RECALL_FILE
    nttrans packets.

    Cheers, Dave

    --
    b/examples/VFS/skel_transparent.c | 6 -
    b/source/include/ntioctl.h | 2
    b/source/include/proto.h | 4
    b/source/include/smb.h | 2
    b/source/include/vfs.h | 4
    b/source/include/vfs_macros.h | 3
    b/source/modules/vfs_default.c | 17 +++
    b/source/smbd/notify.c | 4
    b/source/smbd/nttrans.c | 177 +++++++++++++++++++++-----------------
    source/smbd/nttrans.c | 58 ++++++++++++
    10 files changed, 191 insertions(+), 86 deletions(-)


  2. [PATCH] Add new RECALL_OFFLINE vfs function

    To be used for recalling files migrated to offline storage by a
    Hierarchical Storage Management system.
    ---
    examples/VFS/skel_transparent.c | 6 ++++--
    source/include/vfs.h | 4 ++++
    source/include/vfs_macros.h | 3 +++
    source/modules/vfs_default.c | 16 +++++++++++++++-
    4 files changed, 26 insertions(+), 3 deletions(-)

    diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
    index ea8530d..c5d1a65 100644
    --- a/examples/VFS/skel_transparent.c
    +++ b/examples/VFS/skel_transparent.c
    @@ -548,11 +548,12 @@ static int skel_set_offline(struct vfs_handle_struct *handle, const char *path)
    return SMB_VFS_NEXT_SET_OFFLINE(handle, path);
    }

    -static bool skel_is_remotestorage(struct vfs_handle_struct *handle, const char *path)
    +static int skel_recall_offline(struct vfs_handle_struct *handle, struct files_struct *fsp)
    {
    - return SMB_VFS_NEXT_IS_REMOTESTORAGE(handle, path);
    + return SMB_VFS_NEXT_RECALL_OFFLINE(handle, fsp);
    }

    +
    /* VFS operations structure */

    static vfs_op_tuple skel_op_tuples[] = {
    @@ -674,6 +675,7 @@ static vfs_op_tuple skel_op_tuples[] = {
    /* offline operations */
    {SMB_VFS_OP(skel_is_offline), SMB_VFS_OP_IS_OFFLINE, SMB_VFS_LAYER_TRANSPARENT},
    {SMB_VFS_OP(skel_set_offline), SMB_VFS_OP_SET_OFFLINE, SMB_VFS_LAYER_TRANSPARENT},
    + {SMB_VFS_OP(skel_recall_offline), SMB_VFS_OP_RECALL_OFFLINE, SMB_VFS_LAYER_TRANSPARENT},

    {NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
    };
    diff --git a/source/include/vfs.h b/source/include/vfs.h
    index 9b72f69..6500c58 100644
    --- a/source/include/vfs.h
    +++ b/source/include/vfs.h
    @@ -108,6 +108,7 @@
    /* Leave at 22 - not yet released. Remove parameter fd from close_fn. - obnox */
    /* Changed to version 23 - remove set_nt_acl call. This can only be done via an
    open handle. JRA. */
    +/* Leave at 23 - not yet released. Add recall_offline for offline files */

    #define SMB_VFS_INTERFACE_VERSION 23

    @@ -266,6 +267,7 @@ typedef enum _vfs_op_type {
    /* offline operations */
    SMB_VFS_OP_IS_OFFLINE,
    SMB_VFS_OP_SET_OFFLINE,
    + SMB_VFS_OP_RECALL_OFFLINE,

    /* This should always be last enum value */

    @@ -422,6 +424,7 @@ struct vfs_ops {
    /* offline operations */
    bool (*is_offline)(struct vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf);
    int (*set_offline)(struct vfs_handle_struct *handle, const char *path);
    + int (*recall_offline)(struct vfs_handle_struct *handle, struct files_struct *fsp);
    } ops;

    struct vfs_handles_pointers {
    @@ -548,6 +551,7 @@ struct vfs_ops {
    /* offline operations */
    struct vfs_handle_struct *is_offline;
    struct vfs_handle_struct *set_offline;
    + struct vfs_handle_struct *recall_offline;
    } handles;
    };

    diff --git a/source/include/vfs_macros.h b/source/include/vfs_macros.h
    index 7b3aeaa..c5bf386 100644
    --- a/source/include/vfs_macros.h
    +++ b/source/include/vfs_macros.h
    @@ -144,6 +144,7 @@
    /* Offline operations */
    #define SMB_VFS_IS_OFFLINE(conn,path,sbuf) ((conn)->vfs.ops.is_offline((conn)->vfs.handles.is_offline,(path),(sbuf)))
    #define SMB_VFS_SET_OFFLINE(conn,path) ((conn)->vfs.ops.set_offline((conn)->vfs.handles.set_offline,(path)))
    +#define SMB_VFS_RECALL_OFFLINE(fsp) ((fsp)->conn->vfs.ops.recall_offline((fsp)->conn->vfs.handles.recall_offline,(fsp)))

    /************************************************** *****************
    Don't access conn->vfs_opaque.ops directly!!!
    @@ -269,6 +270,7 @@
    /* Offline operations */
    #define SMB_VFS_OPAQUE_IS_OFFLINE(conn,path,sbuf) ((conn)->vfs_opaque.ops.is_offline((conn)->vfs_opaque.handles.is_offline,(path),(sbuf)))
    #define SMB_VFS_OPAQUE_SET_OFFLINE(conn,path) ((conn)->vfs_opaque.ops.set_offline((conn)->vfs_opaque.handles.set_offline,(path)))
    +#define SMB_VFS_OPAQUE_RECALL_OFFLINE(fsp) ((fsp)->conn->vfs_opaque.ops.recall_offline((fsp)->conn->vfs_opaque.handles.recall_offline,(fsp)))

    /************************************************** *****************
    Don't access handle->vfs_next.ops.* directly!!!
    @@ -395,5 +397,6 @@
    /* Offline operations */
    #define SMB_VFS_NEXT_IS_OFFLINE(handle,path,sbuf) ((handle)->vfs_next.ops.is_offline((handle)->vfs_next.handles.is_offline,(path),(sbuf)))
    #define SMB_VFS_NEXT_SET_OFFLINE(handle,path) ((handle)->vfs_next.ops.set_offline((handle)->vfs_next.handles.set_offline,(path)))
    +#define SMB_VFS_NEXT_RECALL_OFFLINE(handle,fsp) ((handle)->vfs_next.ops.recall_offline((handle)->vfs_next.handles.recall_offline,(fsp)))

    #endif /* _VFS_MACROS_H */
    diff --git a/source/modules/vfs_default.c b/source/modules/vfs_default.c
    index 6ee677e..c6c450c 100644
    --- a/source/modules/vfs_default.c
    +++ b/source/modules/vfs_default.c
    @@ -1311,6 +1311,18 @@ static int vfswrap_set_offline(struct vfs_handle_struct *handle, const char *pat
    return -1;
    }

    +static int vfswrap_recall_offline(struct vfs_handle_struct *handle, struct files_struct *fsp)
    +{
    + /*
    + * We don't know how to recall an offline file by default, needs to be
    + * overriden in other vfs modules
    + */
    +#if defined(ENOTSUP)
    + errno = ENOTSUP;
    +#endif
    + return -1;
    +}
    +
    static vfs_op_tuple vfs_default_ops[] = {

    /* Disk operations */
    @@ -1529,7 +1541,6 @@ static vfs_op_tuple vfs_default_ops[] = {
    SMB_VFS_LAYER_OPAQUE},
    {SMB_VFS_OP(vfswrap_aio_suspend),SMB_VFS_OP_AIO_SU SPEND,
    SMB_VFS_LAYER_OPAQUE},
    -
    {SMB_VFS_OP(vfswrap_aio_force), SMB_VFS_OP_AIO_FORCE,
    SMB_VFS_LAYER_OPAQUE},

    @@ -1537,6 +1548,9 @@ static vfs_op_tuple vfs_default_ops[] = {
    SMB_VFS_LAYER_OPAQUE},
    {SMB_VFS_OP(vfswrap_set_offline),SMB_VFS_OP_SET_OF FLINE,
    SMB_VFS_LAYER_OPAQUE},
    + {SMB_VFS_OP(vfswrap_recall_offline),SMB_VFS_OP_REC ALL_OFFLINE,
    + SMB_VFS_LAYER_OPAQUE},
    +

    /* Finish VFS operations definition */

    --
    1.5.4.rc0


  3. [PATCH] Support Setup[SetupCount] values in nttrans response packets

    send_nt_replies currently sets SetupCount to zero, however some packets
    require different values. When testing FSCTL_RECALL_FILE, Windows XPsp2
    was observed dropping connections where SetupCount was not one in the server
    response.

    The SNIA CIFS documentation also describes NT_TRANSACT_IOCTL server response
    packets as having a SetupCount of 1.
    ---
    source/include/smb.h | 2 +
    source/smbd/notify.c | 4 +-
    source/smbd/nttrans.c | 172 +++++++++++++++++++++++++++++--------------------
    3 files changed, 105 insertions(+), 73 deletions(-)

    diff --git a/source/include/smb.h b/source/include/smb.h
    index 76cc389..be32ea9 100644
    --- a/source/include/smb.h
    +++ b/source/include/smb.h
    @@ -1203,6 +1203,8 @@ struct bitmap {
    #define smb_ntr_DataCount (smb_vwv0 + 23)
    #define smb_ntr_DataOffset (smb_vwv0 + 27)
    #define smb_ntr_DataDisplacement (smb_vwv0 + 31)
    +#define smb_ntr_SetupCount (smb_vwv0 + 35)
    +#define smb_ntr_SetupStart (smb_vwv0 + 36)

    /* these are for the NT create_and_X */
    #define smb_ntcreate_NameLength (smb_vwv0 + 5)
    diff --git a/source/smbd/notify.c b/source/smbd/notify.c
    index eb3384d..e1157b8 100644
    --- a/source/smbd/notify.c
    +++ b/source/smbd/notify.c
    @@ -196,8 +196,8 @@ void change_notify_reply(connection_struct *conn,

    init_smb_request(req, tmp_request,0, conn->encrypted_tid);

    - send_nt_replies(conn, req, NT_STATUS_OK, prs_data_p(&ps),
    - prs_offset(&ps), NULL, 0);
    + send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0,
    + prs_data_p(&ps), prs_offset(&ps), NULL, 0);

    done:
    TALLOC_FREE(req);
    diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
    index cbe1299..270f382 100644
    --- a/source/smbd/nttrans.c
    +++ b/source/smbd/nttrans.c
    @@ -63,11 +63,11 @@ static char *nttrans_realloc(char **ptr, size_t size)
    Send the required number of replies back.
    We assume all fields other than the data fields are
    set correctly for the type of call.
    - HACK ! Always assumes smb_setup field is zero.
    ************************************************** **************************/

    void send_nt_replies(connection_struct *conn,
    - struct smb_request *req, NTSTATUS nt_error,
    + struct smb_request *req, NTSTATUS nt_error,
    + uint16 *setup, uint8 setup_count,
    char *params, int paramsize,
    char *pdata, int datasize)
    {
    @@ -76,30 +76,28 @@ void send_nt_replies(connection_struct *conn,
    int useable_space;
    char *pp = params;
    char *pd = pdata;
    - int params_sent_thistime, data_sent_thistime, total_sent_thistime;
    - int alignment_offset = 3;
    - int data_alignment_offset = 0;
    + int params_sent_thistime, data_sent_thistime;
    + int i;
    + int pad1 = 0;
    + int pad2 = 0;

    /*
    - * If there genuinely are no parameters or data to send just send
    + * If there genuinely are no parameters, data or setup to send just send
    * the empty packet.
    */

    - if(params_to_send == 0 && data_to_send == 0) {
    + if(params_to_send == 0 && data_to_send == 0 && setup_count == 0) {
    reply_outbuf(req, 18, 0);
    show_msg((char *)req->outbuf);
    return;
    }

    /*
    - * When sending params and data ensure that both are nicely aligned.
    - * Only do this alignment when there is also data to send - else
    - * can cause NT redirector problems.
    + * pad1 pushes out to a four byte boundary after:
    + * UCHAR SetupCount + USHORT Setup[SetupCount] + USHORT ByteCount
    */
    -
    - if (((params_to_send % 4) != 0) && (data_to_send != 0)) {
    - data_alignment_offset = 4 - (params_to_send % 4);
    - }
    + pad1 = (((1 + 2 * setup_count + 2) + 3) & ~3)
    + - (1 + 2 * setup_count + 2);

    /*
    * Space is bufsize minus Netbios over TCP header minus SMB header.
    @@ -109,35 +107,60 @@ void send_nt_replies(connection_struct *conn,
    */

    useable_space = max_send - (smb_size
    - + 2 * 18 /* wct */
    - + alignment_offset
    - + data_alignment_offset);
    + + 2 * 18 /* wct no setup */
    + + 1 /* UCHAR SetupCount */
    + + 2 * setup_count /* USHORT Setup[SetupCount] */
    + + 2 /* USHORT ByteCount */
    + + pad1);

    /*
    - * useable_space can never be more than max_send minus the
    - * alignment offset.
    + * if Setup[] is to big, there will be no room for data or
    + * parameters.
    */
    + if (useable_space <= 0) {
    + exit_server_cleanly(
    + "send_nt_replies: no usable space in nt reply packet");
    + return;
    + }

    - useable_space = MIN(useable_space,
    - max_send - (alignment_offset+data_alignment_offset));
    -
    -
    - while (params_to_send || data_to_send) {
    + do {

    /*
    - * Calculate whether we will totally or partially fill this packet.
    + * Calculate how many parameters and data we can fit into
    + * this packet. Parameters get precedence.
    */

    - total_sent_thistime = params_to_send + data_to_send +
    - alignment_offset + data_alignment_offset;
    + params_sent_thistime = MIN(params_to_send,useable_space);
    + /*
    + * When sending params and data ensure that both are nicely aligned.
    + * Only do this alignment when there is also data to send - else
    + * can cause NT redirector problems.
    + *
    + * pad2 pushes out to a four byte boundary after parameters
    + */
    + if ((data_to_send) && (params_sent_thistime)) {
    + pad2 = ((params_sent_thistime + 3) & ~3)
    + - params_sent_thistime;
    + }
    + else {
    + pad2 = 0;
    + }
    + data_sent_thistime = useable_space - params_sent_thistime - pad2;
    + /*
    + * check if pad2 pushed past packet end
    + */
    + if (data_sent_thistime <= 0) {
    + pad2 = 0;
    + data_sent_thistime = 0;
    + }
    + data_sent_thistime = MIN(data_sent_thistime,data_to_send);

    /*
    * We can never send more than useable_space.
    */

    - total_sent_thistime = MIN(total_sent_thistime, useable_space);
    -
    - reply_outbuf(req, 18, total_sent_thistime);
    + reply_outbuf(req, 18 + setup_count,
    + pad1 + params_sent_thistime + pad2 + data_sent_thistime);

    /*
    * Set total params and data to be sent.
    @@ -145,16 +168,6 @@ void send_nt_replies(connection_struct *conn,

    SIVAL(req->outbuf,smb_ntr_TotalParameterCount,paramsize);
    SIVAL(req->outbuf,smb_ntr_TotalDataCount,datasize);
    -
    - /*
    - * Calculate how many parameters and data we can fit into
    - * this packet. Parameters get precedence.
    - */
    -
    - params_sent_thistime = MIN(params_to_send,useable_space);
    - data_sent_thistime = useable_space - params_sent_thistime;
    - data_sent_thistime = MIN(data_sent_thistime,data_to_send);
    -
    SIVAL(req->outbuf, smb_ntr_ParameterCount,
    params_sent_thistime);

    @@ -163,14 +176,14 @@ void send_nt_replies(connection_struct *conn,
    SIVAL(req->outbuf,smb_ntr_ParameterDisplacement,0);
    } else {
    /*
    - * smb_ntr_ParameterOffset is the offset from the start of the SMB header to the
    - * parameter bytes, however the first 4 bytes of outbuf are
    - * the Netbios over TCP header. Thus use smb_base() to subtract
    - * them from the calculation.
    + * smb_ntr_ParameterOffset is the offset from the start of the
    + * SMB header to the parameter bytes, however the first 4 bytes of
    + * outbuf are the Netbios over TCP header. Thus use smb_base() to
    + * subtract them from the calculation.
    */

    SIVAL(req->outbuf,smb_ntr_ParameterOffset,
    - ((smb_buf(req->outbuf)+alignment_offset)
    + ((smb_buf(req->outbuf) + pad1)
    - smb_base(req->outbuf)));
    /*
    * Absolute displacement of param bytes sent in this packet.
    @@ -196,22 +209,35 @@ void send_nt_replies(connection_struct *conn,
    */

    SIVAL(req->outbuf, smb_ntr_DataOffset,
    - ((smb_buf(req->outbuf)+alignment_offset) -
    + ((smb_buf(req->outbuf) + pad1) -
    smb_base(req->outbuf))
    - + params_sent_thistime + data_alignment_offset);
    + + params_sent_thistime + pad2);
    SIVAL(req->outbuf,smb_ntr_DataDisplacement, pd - pdata);
    }

    /*
    + * Deal with the setup portion.
    + */
    +
    + SCVAL(req->outbuf,smb_ntr_SetupCount,setup_count);
    + for (i=0;i + SSVAL(req->outbuf,smb_ntr_SetupStart+i*2,setup[i]);
    + }
    +
    + /*
    + * zero pading
    + */
    + if (pad1 != 0) {
    + memset(smb_buf(req->outbuf), 0,
    + pad1);
    + }
    +
    + /*
    * Copy the param bytes into the packet.
    */

    if(params_sent_thistime) {
    - if (alignment_offset != 0) {
    - memset(smb_buf(req->outbuf), 0,
    - alignment_offset);
    - }
    - memcpy((smb_buf(req->outbuf)+alignment_offset), pp,
    + memcpy((smb_buf(req->outbuf) + pad1), pp,
    params_sent_thistime);
    }

    @@ -220,13 +246,13 @@ void send_nt_replies(connection_struct *conn,
    */

    if(data_sent_thistime) {
    - if (data_alignment_offset != 0) {
    - memset((smb_buf(req->outbuf)+alignment_offset+
    - params_sent_thistime), 0,
    - data_alignment_offset);
    + if (pad2 != 0) {
    + memset((smb_buf(req->outbuf) + pad1
    + +params_sent_thistime), 0,
    + pad2);
    }
    - memcpy(smb_buf(req->outbuf)+alignment_offset
    - +params_sent_thistime+data_alignment_offset,
    + memcpy(smb_buf(req->outbuf) + pad1
    + +params_sent_thistime+pad2,
    pd,data_sent_thistime);
    }

    @@ -266,7 +292,7 @@ void send_nt_replies(connection_struct *conn,
    params_to_send, data_to_send));
    return;
    }
    - }
    + } while (params_to_send || data_to_send);
    }

    /************************************************** **************************
    @@ -732,7 +758,8 @@ static void do_nt_transact_create_pipe(connection_struct *conn,
    DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));

    /* Send the required number of replies */
    - send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
    + send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0,
    + params, param_len, *ppdata, 0);

    return;
    }
    @@ -1078,7 +1105,8 @@ static void call_nt_transact_create(connection_struct *conn,
    DEBUG(5,("call_nt_transact_create: open name = %s\n", fsp->fsp_name));

    /* Send the required number of replies */
    - send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);
    + send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0,
    + params, param_len, *ppdata, 0);

    return;
    }
    @@ -1535,7 +1563,7 @@ static void call_nt_transact_rename(connection_struct *conn,
    * W2K3 ignores this request as the RAW-RENAME test
    * demonstrates, so we do.
    */
    - send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
    + send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0, NULL, 0);

    DEBUG(3,("nt transact rename from = %s, to = %s ignored!\n",
    fsp->fsp_name, new_name));
    @@ -1629,7 +1657,7 @@ static void call_nt_transact_query_security_desc(connection_st ruct *conn,

    if (max_data_count < sd_size) {
    send_nt_replies(conn, req, NT_STATUS_BUFFER_TOO_SMALL,
    - params, 4, *ppdata, 0);
    + NULL, 0, params, 4, *ppdata, 0);
    return;
    }

    @@ -1654,7 +1682,8 @@ static void call_nt_transact_query_security_desc(connection_st ruct *conn,
    SMB_ASSERT(sd_size == blob.length);
    memcpy(data, blob.data, sd_size);

    - send_nt_replies(conn, req, NT_STATUS_OK, params, 4, data, (int)sd_size);
    + send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, params, 4,
    + data, (int)sd_size);

    return;
    }
    @@ -1711,7 +1740,7 @@ static void call_nt_transact_set_security_desc(connection_stru ct *conn,
    }

    done:
    - send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
    + send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0, NULL, 0);
    return;
    }

    @@ -1760,7 +1789,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
    so we can know if we need to pre-allocate or not */

    DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
    - send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
    + send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0, NULL, 0);
    return;

    case FSCTL_CREATE_OR_GET_OBJECT_ID:
    @@ -1786,7 +1815,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
    push_file_id_16(pdata, &fsp->file_id);
    memcpy(pdata+16,create_volume_objectid(conn,objid) ,16);
    push_file_id_16(pdata+32, &fsp->file_id);
    - send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0,
    + send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0,
    pdata, data_count);
    return;
    }
    @@ -1931,7 +1960,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,

    talloc_destroy(shadow_data->mem_ctx);

    - send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0,
    + send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0,
    pdata, data_count);

    return;
    @@ -1987,9 +2016,10 @@ static void call_nt_transact_ioctl(connection_struct *conn,
    */

    /* this works for now... */
    - send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0);
    + send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, NULL, 0, NULL, 0);
    return;
    }
    +
    default:
    if (!logged_message) {
    logged_message = True; /* Only print this once... */
    @@ -2274,7 +2304,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn,
    break;
    }

    - send_nt_replies(conn, req, nt_status, params, param_len,
    + send_nt_replies(conn, req, nt_status, NULL, 0, params, param_len,
    pdata, data_len);
    }

    @@ -2405,7 +2435,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn,
    return;
    }

    - send_nt_replies(conn, req, NT_STATUS_OK, params, param_len,
    + send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, params, param_len,
    pdata, data_len);
    }
    #endif /* HAVE_SYS_QUOTAS */
    --
    1.5.4.rc0


  4. [PATCH] support FSCTL_RECALL_FILE nttrans

    FSCTL_RECALL_FILE can be used to recall files moved offline by hierarchical
    storage management software.

    The nttrans ioctl packet is handled in the following steps:
    - check for FILE_SUPPORTS_REMOTE_STORAGE, if without, return error
    - return error if attempting to recall a directory.
    - if SMB_VFS_IS_OFFLINE() is false return success immediately
    - otherwise, call SMB_VFS_RECALL_OFFLINE() to recall the file
    ---
    source/include/ntioctl.h | 2 +-
    source/smbd/nttrans.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++
    2 files changed, 58 insertions(+), 1 deletions(-)

    diff --git a/source/include/ntioctl.h b/source/include/ntioctl.h
    index c565b8f..fb91c01 100644
    --- a/source/include/ntioctl.h
    +++ b/source/include/ntioctl.h
    @@ -54,6 +54,7 @@
    #define FSCTL_WRITE_RAW_ENCRYPTED 0x000900DF
    #define FSCTL_READ_RAW_ENCRYPTED 0x000900E3
    #define FSCTL_SIS_COPYFILE 0x00090100
    +#define FSCTL_RECALL_FILE 0x00090117
    #define FSCTL_QUERY_ALLOCATED_RANGES 0x000940CF
    #define FSCTL_SIS_LINK_FILES 0x0009C104

    @@ -64,7 +65,6 @@
    #define FSCTL_DISMOUNT_VOLUME
    #define FSCTL_GET_NTFS_FILE_RECORD
    #define FSCTL_ALLOW_EXTENDED_DASD_IO
    -#define FSCTL_RECALL_FILE

    #endif

    diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
    index 270f382..f013250 100644
    --- a/source/smbd/nttrans.c
    +++ b/source/smbd/nttrans.c
    @@ -2020,6 +2020,63 @@ static void call_nt_transact_ioctl(connection_struct *conn,
    return;
    }

    + case FSCTL_RECALL_FILE:
    + {
    + /*
    + * recall an offline file
    + */
    + SMB_STRUCT_STAT st;
    + uint16 setup_data = 0;
    +
    + if (!fsp_belongs_conn(conn, req, fsp, &current_user)) {
    + return;
    + }
    +
    + if (!(conn->fs_capabilities & FILE_SUPPORTS_REMOTE_STORAGE)) {
    + /* no hsm support */
    + reply_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
    + DEBUG(0,("FSCTL_RECALL_FILE called without REMOTE_STORAGE"
    + " capabilities\n"));
    + return;
    + }
    +
    + if (SMB_VFS_STAT(conn, fsp->fsp_name, &st)) {
    + reply_nterror(req, NT_STATUS_INVALID_HANDLE);
    + DEBUG(3,("FSCTL_RECALL_FILE stat failed\n"));
    + return;
    + }
    +
    + if (S_ISDIR(st.st_mode)) {
    + /* directories cannot be offline */
    + reply_nterror(req, NT_STATUS_INVALID_HANDLE);
    + DEBUG(3,("FSCTL_RECALL_FILE cannot recall directory\n"));
    + return;
    + }
    +
    + if (SMB_VFS_IS_OFFLINE(conn, fsp->fsp_name, &st) == false) {
    + /* file already online, return success */
    + send_nt_replies(conn, req, NT_STATUS_OK,
    + &setup_data, 1, /* NT_TRANSACT_IOCTL replies */
    + NULL, 0, /* no params */
    + NULL, 0); /* no data */
    + DEBUG(3,("FSCTL_RECALL_FILE file already online\n"));
    + return;
    + }
    +
    + if (SMB_VFS_RECALL_OFFLINE(fsp) == 0) {
    + send_nt_replies(conn, req, NT_STATUS_OK,
    + &setup_data, 1, /* NT_TRANSACT_IOCTL replies */
    + NULL, 0, /* no params */
    + NULL, 0); /* no data */
    + DEBUG(3,("FSCTL_RECALL_FILE successfully recalled\n"));
    + }
    + else {
    + reply_nterror(req, NT_STATUS_ACCESS_DENIED);
    + DEBUG(3,("FSCTL_RECALL_FILE recall failed\n"));
    + }
    + return;
    + }
    +
    default:
    if (!logged_message) {
    logged_message = True; /* Only print this once... */
    --
    1.5.4.rc0


  5. [PATCH] Update send_nt_replies() definition in proto.h to includesetup and

    ---
    source/include/proto.h | 3 ++-
    1 files changed, 2 insertions(+), 1 deletions(-)

    diff --git a/source/include/proto.h b/source/include/proto.h
    index dfde0c7..48f57bf 100644
    --- a/source/include/proto.h
    +++ b/source/include/proto.h
    @@ -9852,7 +9852,8 @@ void *init_quota_handle(TALLOC_CTX *mem_ctx);
    /* The following definitions come from smbd/nttrans.c */

    void send_nt_replies(connection_struct *conn,
    - struct smb_request *req, NTSTATUS nt_error,
    + struct smb_request *req, NTSTATUS nt_error,
    + uint16 *setup, uint8 setup_count,
    char *params, int paramsize,
    char *pdata, int datasize);
    bool is_ntfs_stream_name(const char *fname);
    --
    1.5.4.rc0


  6. Re: Samba 3.3 recall offline file support

    On Fri, Jun 13, 2008 at 06:19:07PM +1000, David Disseldorp wrote:
    > This series of patches adds FSCTL_RECALL_FILE support to Samba 3.3.


    Quick reply: I did not see the patch to vfs_full_audit.c.
    Did I miss anything?

    Volker

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.5 (GNU/Linux)

    iD8DBQFIUmxYUzqjrWwMRl0RAgkJAJ9ddQ+C61yg717VtwMwGb WNJVWKtACdFUh3
    rkOXIODMjY9CUCSFIhlSck0=
    =CPy3
    -----END PGP SIGNATURE-----


  7. Re: Samba 3.3 recall offline file support

    On Fri, 13 Jun 2008 14:47:20 +0200
    Volker Lendecke wrote:

    > Quick reply: I did not see the patch to vfs_full_audit.c.
    > Did I miss anything?


    Thanks for the feedback Volker, patch below.

    Cheers, Dave


  8. [PATCH] Add HSM offline and aio_force functions to vfs_full_audit

    ---
    source/modules/vfs_full_audit.c | 65 +++++++++++++++++++++++++++++++++++++-
    1 files changed, 63 insertions(+), 2 deletions(-)

    diff --git a/source/modules/vfs_full_audit.c b/source/modules/vfs_full_audit.c
    index 3005de3..57bc769 100644
    --- a/source/modules/vfs_full_audit.c
    +++ b/source/modules/vfs_full_audit.c
    @@ -308,6 +308,15 @@ static int smb_full_audit_aio_cancel(struct vfs_handle_struct *handle, struct fi
    static int smb_full_audit_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb);
    static int smb_full_audit_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb);
    static int smb_full_audit_aio_suspend(struct vfs_handle_struct *handle, struct files_struct *fsp, const SMB_STRUCT_AIOCB * const aiocb[], int n, const struct timespec *ts);
    +static bool smb_full_audit_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp);
    +
    +static bool smb_full_audit_is_offline(struct vfs_handle_struct *handle,
    + const char *path, SMB_STRUCT_STAT *sbuf);
    +static int smb_full_audit_set_offline(struct vfs_handle_struct *handle,
    + const char *path);
    +static int smb_full_audit_recall_offline(struct vfs_handle_struct *handle,
    + struct files_struct *fsp);
    +

    /* VFS operations */

    @@ -527,6 +536,16 @@ static vfs_op_tuple audit_op_tuples[] = {
    SMB_VFS_LAYER_LOGGER},
    {SMB_VFS_OP(smb_full_audit_aio_suspend),SMB_VFS_OP _AIO_SUSPEND,
    SMB_VFS_LAYER_LOGGER},
    + {SMB_VFS_OP(smb_full_audit_aio_force),SMB_VFS_OP_A IO_FORCE,
    + SMB_VFS_LAYER_LOGGER},
    +
    + /* offline operations */
    + {SMB_VFS_OP(smb_full_audit_is_offline),SMB_VFS_OP_ IS_OFFLINE,
    + SMB_VFS_LAYER_LOGGER},
    + {SMB_VFS_OP(smb_full_audit_set_offline),SMB_VFS_OP _SET_OFFLINE,
    + SMB_VFS_LAYER_LOGGER},
    + {SMB_VFS_OP(smb_full_audit_recall_offline),SMB_VFS _OP_RECALL_OFFLINE,
    + SMB_VFS_LAYER_LOGGER},

    /* Finish VFS operations definition */

    @@ -639,8 +658,9 @@ static struct {
    { SMB_VFS_OP_AIO_FSYNC, "aio_fsync" },
    { SMB_VFS_OP_AIO_SUSPEND,"aio_suspend" },
    { SMB_VFS_OP_AIO_FORCE, "aio_force" },
    - { SMB_VFS_OP_IS_OFFLINE, "aio_is_offline" },
    - { SMB_VFS_OP_SET_OFFLINE, "aio_set_offline" },
    + { SMB_VFS_OP_IS_OFFLINE, "is_offline" },
    + { SMB_VFS_OP_SET_OFFLINE, "set_offline" },
    + { SMB_VFS_OP_RECALL_OFFLINE, "recall_offline" },
    { SMB_VFS_OP_LAST, NULL }
    };

    @@ -2185,6 +2205,47 @@ static int smb_full_audit_aio_suspend(struct vfs_handle_struct *handle, struct f
    return result;
    }

    +static bool smb_full_audit_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
    +{
    + bool result;
    +
    + result = SMB_VFS_NEXT_AIO_FORCE(handle, fsp);
    + do_log(SMB_VFS_OP_AIO_FORCE, (result == true), handle,
    + "%s", fsp->fsp_name);
    +
    + return result;
    +}
    +
    +static bool smb_full_audit_is_offline(struct vfs_handle_struct *handle,
    + const char *path, SMB_STRUCT_STAT *sbuf)
    +{
    + bool result;
    +
    + result = SMB_VFS_NEXT_IS_OFFLINE(handle, path, sbuf);
    + do_log(SMB_VFS_OP_IS_OFFLINE, (result == true), handle, "%s", path);
    + return result;
    +}
    +
    +static int smb_full_audit_set_offline(struct vfs_handle_struct *handle,
    + const char *path)
    +{
    + int result;
    +
    + result = SMB_VFS_NEXT_SET_OFFLINE(handle, path);
    + do_log(SMB_VFS_OP_SET_OFFLINE, (result == 0), handle, "%s", path);
    + return result;
    +}
    +
    +static int smb_full_audit_recall_offline(struct vfs_handle_struct *handle,
    + struct files_struct *fsp)
    +{
    + int result;
    +
    + SMB_VFS_NEXT_RECALL_OFFLINE(handle, fsp);
    + do_log(SMB_VFS_OP_RECALL_OFFLINE, (result == 0), handle,
    + "%s", fsp->fsp_name);
    + return result;
    +}

    NTSTATUS vfs_full_audit_init(void);
    NTSTATUS vfs_full_audit_init(void)
    --
    1.5.4.rc0


  9. Re: Samba 3.3 recall offline file support

    2008/6/18 David Disseldorp :
    > On Fri, 13 Jun 2008 14:47:20 +0200
    > Volker Lendecke wrote:
    >
    >> Quick reply: I did not see the patch to vfs_full_audit.c.
    >> Did I miss anything?

    >
    > Thanks for the feedback Volker, patch below.

    I've reviewed all set of HSM-related patches that add recall
    functionality and I think they are OK.
    Volker, you want me to check them in into 3.3 or you'd do it?

    --
    / Alexander Bokovoy


  10. Re: Samba 3.3 recall offline file support

    On Wed, Jun 18, 2008 at 08:10:45AM +0400, Alexander Bokovoy wrote:
    > > On Fri, 13 Jun 2008 14:47:20 +0200
    > > Volker Lendecke wrote:
    > >
    > >> Quick reply: I did not see the patch to vfs_full_audit.c.
    > >> Did I miss anything?

    > >
    > > Thanks for the feedback Volker, patch below.

    > I've reviewed all set of HSM-related patches that add recall
    > functionality and I think they are OK.
    > Volker, you want me to check them in into 3.3 or you'd do it?


    The one that I still have to look at very closely is the
    change to nttrans.c. I'd like to know a way to run this code
    somehow. Any idea how to set this up?

    Volker

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.5 (GNU/Linux)

    iD8DBQFIWKsEUzqjrWwMRl0RAvs8AJ4/Y3UaFy0uUMCJh/Sg1IuOTbnxpgCfenr0
    7U8ggsI5hNzg7dW9nYqu1jk=
    =srqN
    -----END PGP SIGNATURE-----


  11. Re: Samba 3.3 recall offline file support

    On Wed, 18 Jun 2008 08:28:20 +0200
    Volker Lendecke wrote:

    > The one that I still have to look at very closely is the
    > change to nttrans.c. I'd like to know a way to run this code
    > somehow. Any idea how to set this up?


    To test FSCTL_RECALL_FILE, see the client application available at:
    http://msdn.microsoft.com/en-us/libr...87(VS.85).aspx

    With the patches applied on the server side, ensure fs_capabilities
    returns FILE_SUPPORTS_REMOTE_STORAGE.

    The SMB_VFS_OP_RECALL_OFFLINE handler will then be called when the server
    receives a FSCTL_RECALL_FILE nttrans and the file is flagged as offline.

    If you wan't to test it with a DMAPI based HSM i'd recommend having a
    play with sample_hsm found in the XFS cmds tree.

    http://oss.sgi.com/cgi-bin/cvsweb.cg...rc/sample_hsm/

    Cheers, Dave


  12. Re: [PATCH] Support Setup[SetupCount] values in nttrans responsepackets

    On Fri, Jun 13, 2008 at 06:19:09PM +1000, David Disseldorp wrote:
    > send_nt_replies currently sets SetupCount to zero, however some packets
    > require different values. When testing FSCTL_RECALL_FILE, Windows XPsp2
    > was observed dropping connections where SetupCount was not one in the server
    > response.
    >
    > The SNIA CIFS documentation also describes NT_TRANSACT_IOCTL server response
    > packets as having a SetupCount of 1.


    Looking at send_nt_replies I've got some points:

    First a purely stylistic, trivial one: We're trying to
    standardize on uint16_t, not uint16 these days. For new code
    that should be the the one to use.

    Then another stylistic one: The do {} while variant of a
    loop is a bit cumbersome to read. Can we turn that into the
    old form again?

    And then a real question: You seem to send the setup
    portion of the reply in every partial nttrans reply packet.
    Is that the right way to do? I don't know how to trigger
    that with Windows, but it looks wrong to me.

    Volker

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.5 (GNU/Linux)

    iD8DBQFIW3mcUzqjrWwMRl0RAgx3AJ4rbUAXccwhsl5ZmLobyS 0V1E1GbgCeLHTb
    oUe4i7scTrdnZlVZoIgcaDg=
    =dyzC
    -----END PGP SIGNATURE-----


  13. Re: [PATCH] Support Setup[SetupCount] values in nttrans responsepackets

    On Fri, 20 Jun 2008 11:34:21 +0200
    Volker Lendecke wrote:

    > First a purely stylistic, trivial one: We're trying to
    > standardize on uint16_t, not uint16 these days. For new code
    > that should be the the one to use.
    >
    > Then another stylistic one: The do {} while variant of a
    > loop is a bit cumbersome to read. Can we turn that into the
    > old form again?


    No problems, i'll change the areas above.

    > And then a real question: You seem to send the setup
    > portion of the reply in every partial nttrans reply packet.
    > Is that the right way to do? I don't know how to trigger
    > that with Windows, but it looks wrong to me.


    Not sure, draft-leach-cifs-v1-spec-02 is vaugue in this regard.
    As you say, triggering a multi packet nttrans server response
    will be difficult. I'm not sure what the maximum security descriptor
    size is, but i'd assume I wont be able to hit it using
    QUERY_SECURITY_DESC. I'll do some investigation.

    Cheers, Dave


  14. Re: [PATCH] Support Setup[SetupCount] values in nttrans responsepackets

    On Mon, Jun 23, 2008 at 11:21:44AM +1000, David Disseldorp wrote:
    > > First a purely stylistic, trivial one: We're trying to
    > > standardize on uint16_t, not uint16 these days. For new code
    > > that should be the the one to use.
    > >
    > > Then another stylistic one: The do {} while variant of a
    > > loop is a bit cumbersome to read. Can we turn that into the
    > > old form again?

    >
    > No problems, i'll change the areas above.
    >
    > > And then a real question: You seem to send the setup
    > > portion of the reply in every partial nttrans reply packet.
    > > Is that the right way to do? I don't know how to trigger
    > > that with Windows, but it looks wrong to me.

    >
    > Not sure, draft-leach-cifs-v1-spec-02 is vaugue in this regard.
    > As you say, triggering a multi packet nttrans server response
    > will be difficult. I'm not sure what the maximum security descriptor
    > size is, but i'd assume I wont be able to hit it using
    > QUERY_SECURITY_DESC. I'll do some investigation.


    Thanks!

    Sorry if I'm picky on that, this is really tricky code that
    we already had security bugs in in the past.

    Volker

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.5 (GNU/Linux)

    iD8DBQFIXxs/UzqjrWwMRl0RAuIhAJ0UDpjb0an4lsJzlPiqREcehOAYmgCfRQ f1
    qZoqzxbocmEtkMLB+XOMgJc=
    =DjRd
    -----END PGP SIGNATURE-----


  15. Re: [PATCH] Support Setup[SetupCount] values in nttrans responsepackets

    * Volker Lendecke wrote, On 23/06/08 04:40:
    > On Mon, Jun 23, 2008 at 11:21:44AM +1000, David Disseldorp wrote:
    >
    >>> First a purely stylistic, trivial one: We're trying to
    >>> standardize on uint16_t, not uint16 these days. For new code
    >>> that should be the the one to use.
    >>>
    >>> Then another stylistic one: The do {} while variant of a
    >>> loop is a bit cumbersome to read. Can we turn that into the
    >>> old form again?
    >>>

    >> No problems, i'll change the areas above.
    >>
    >>
    >>> And then a real question: You seem to send the setup
    >>> portion of the reply in every partial nttrans reply packet.
    >>> Is that the right way to do? I don't know how to trigger
    >>> that with Windows, but it looks wrong to me.
    >>>

    >> Not sure, draft-leach-cifs-v1-spec-02 is vaugue in this regard.
    >> As you say, triggering a multi packet nttrans server response
    >> will be difficult. I'm not sure what the maximum security descriptor
    >> size is, but i'd assume I wont be able to hit it using
    >> QUERY_SECURITY_DESC. I'll do some investigation.
    >>

    >
    > Thanks!
    >
    > Sorry if I'm picky on that, this is really tricky code that
    > we already had security bugs in in the past.
    >

    I've been triggering multi-packet nttrans responses, is there some
    testing I can do for you?

    Sam


  16. Re: [PATCH] Support Setup[SetupCount] values in nttrans responsepackets

    On Tue, 01 Jul 2008 13:06:27 +0100
    Sam Liddicott wrote:

    > I've been triggering multi-packet nttrans responses, is there some
    > testing I can do for you?


    Thanks for the offer Sam. Any tips on how to trigger the multi-packet
    nttrans response would be appreciated.

    What I really need is for the response to include one or more setup words.
    AFICT only NT_TRANSACT_IOCTL responses will add a setup word. So maybe a
    huge GET_SHADOW_COPY_DATA will work.

    Cheers, Dave


  17. Re: [PATCH] Support Setup[SetupCount] values in nttrans responsepackets

    * David Disseldorp wrote, On 02/07/08 01:59:
    > On Tue, 01 Jul 2008 13:06:27 +0100
    > Sam Liddicott wrote:
    >
    >
    >> I've been triggering multi-packet nttrans responses, is there some
    >> testing I can do for you?
    >>

    >
    > Thanks for the offer Sam. Any tips on how to trigger the multi-packet
    > nttrans response would be appreciated.
    >
    > What I really need is for the response to include one or more setup words.
    > AFICT only NT_TRANSACT_IOCTL responses will add a setup word. So maybe a
    > huge GET_SHADOW_COPY_DATA will work.
    >

    I spoke to Volker on this, it seems you are anxious to get real live
    responses from a windows server, I've been getting them from my own
    nttrans server code on a samba server.

    Therefore (sorry) my only tip is to negotiate a small MAX_XMIT size so
    that any decent sized response will be multi-part.

    Sam


+ Reply to Thread