Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/smbd/smb2_getinfo.c

    r414 r745  
    44
    55   Copyright (C) Stefan Metzmacher 2009
     6   Copyright (C) Jeremy Allison 2010
    67
    78   This program is free software; you can redistribute it and/or modify
     
    2021
    2122#include "includes.h"
     23#include "smbd/smbd.h"
    2224#include "smbd/globals.h"
    2325#include "../libcli/smb/smb_common.h"
     26#include "trans2.h"
     27#include "../lib/util/tevent_ntstatus.h"
    2428
    2529static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
     
    3539static NTSTATUS smbd_smb2_getinfo_recv(struct tevent_req *req,
    3640                                       TALLOC_CTX *mem_ctx,
    37                                        DATA_BLOB *out_output_buffer);
     41                                       DATA_BLOB *out_output_buffer,
     42                                       NTSTATUS *p_call_status);
    3843
    3944static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq);
     
    96101        if (req->compat_chain_fsp) {
    97102                /* skip check */
    98         } else if (in_file_id_persistent != 0) {
     103        } else if (in_file_id_persistent != in_file_id_volatile) {
    99104                return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
    100105        }
     
    129134        DATA_BLOB out_output_buffer = data_blob_null;
    130135        NTSTATUS status;
     136        NTSTATUS call_status = NT_STATUS_OK;
    131137        NTSTATUS error; /* transport error */
    132138
    133139        status = smbd_smb2_getinfo_recv(subreq,
    134140                                        req,
    135                                         &out_output_buffer);
     141                                        &out_output_buffer,
     142                                        &call_status);
    136143        TALLOC_FREE(subreq);
    137144        if (!NT_STATUS_IS_OK(status)) {
     
    145152        }
    146153
     154        if (!NT_STATUS_IS_OK(call_status)) {
     155                /* Return a specific error with data. */
     156                error = smbd_smb2_request_error_ex(req,
     157                                                call_status,
     158                                                &out_output_buffer,
     159                                                __location__);
     160                if (!NT_STATUS_IS_OK(error)) {
     161                        smbd_server_connection_terminate(req->sconn,
     162                                                         nt_errstr(error));
     163                        return;
     164                }
     165                return;
     166        }
     167
    147168        out_output_buffer_offset = SMB2_HDR_BODY + 0x08;
    148169
     
    181202        DATA_BLOB out_output_buffer;
    182203};
     204
     205static void smb2_ipc_getinfo(struct tevent_req *req,
     206                                struct smbd_smb2_getinfo_state *state,
     207                                struct tevent_context *ev,
     208                                uint8_t in_info_type,
     209                                uint8_t in_file_info_class)
     210{
     211        /* We want to reply to SMB2_GETINFO_FILE
     212           with a class of SMB2_FILE_STANDARD_INFO as
     213           otherwise a Win7 client issues this request
     214           twice (2xroundtrips) if we return NOT_SUPPORTED.
     215           NB. We do the same for SMB1 in call_trans2qpipeinfo() */
     216
     217        if (in_info_type == 0x01 && /* SMB2_GETINFO_FILE */
     218                        in_file_info_class == 0x05) { /* SMB2_FILE_STANDARD_INFO */
     219                state->out_output_buffer = data_blob_talloc(state,
     220                                                NULL, 24);
     221                if (tevent_req_nomem(state->out_output_buffer.data, req)) {
     222                        return;
     223                }
     224
     225                memset(state->out_output_buffer.data,0,24);
     226                SOFF_T(state->out_output_buffer.data,0,4096LL);
     227                SIVAL(state->out_output_buffer.data,16,1);
     228                SIVAL(state->out_output_buffer.data,20,1);
     229                tevent_req_done(req);
     230        } else {
     231                tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
     232        }
     233}
    183234
    184235static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
     
    198249        connection_struct *conn = smb2req->tcon->compat_conn;
    199250        files_struct *fsp;
     251        NTSTATUS status;
    200252
    201253        req = tevent_req_create(mem_ctx, &state,
     
    205257        }
    206258        state->smb2req = smb2req;
    207         state->status = NT_STATUS_INTERNAL_ERROR;
     259        state->status = NT_STATUS_OK;
    208260        state->out_output_buffer = data_blob_null;
    209261
     
    231283
    232284        if (IS_IPC(conn)) {
    233                 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED);
     285                smb2_ipc_getinfo(req, state, ev,
     286                        in_info_type, in_file_info_class);
    234287                return tevent_req_post(req, ev);
    235288        }
     
    247300                int lock_data_count = 0;
    248301                char *lock_data = NULL;
    249                 bool ms_dfs_link = false;
    250                 NTSTATUS status;
    251302
    252303                ZERO_STRUCT(write_time_ts);
     
    274325                        /* We know this name is ok, it's already passed the checks. */
    275326
    276                 } else if (fsp && (fsp->is_directory || fsp->fh->fd == -1)) {
     327                } else if (fsp && fsp->fh->fd == -1) {
    277328                        /*
    278329                         * This is actually a QFILEINFO on a directory
     
    304355                        fileid = vfs_file_id_from_sbuf(conn,
    305356                                                       &fsp->fsp_name->st);
    306                         get_file_infos(fileid, &delete_pending, &write_time_ts);
     357                        get_file_infos(fileid, fsp->name_hash,
     358                                &delete_pending, &write_time_ts);
    307359                } else {
    308360                        /*
     
    320372                        fileid = vfs_file_id_from_sbuf(conn,
    321373                                                       &fsp->fsp_name->st);
    322                         get_file_infos(fileid, &delete_pending, &write_time_ts);
     374                        get_file_infos(fileid, fsp->name_hash,
     375                                &delete_pending, &write_time_ts);
    323376                }
    324377
     
    329382                                               delete_pending,
    330383                                               write_time_ts,
    331                                                ms_dfs_link,
    332384                                               ea_list,
    333385                                               lock_data_count,
     
    363415                char *data = NULL;
    364416                int data_size = 0;
    365                 NTSTATUS status;
    366417
    367418                /* the levels directly map to the passthru levels */
     
    395446        }
    396447
     448        case 0x03:/* SMB2_GETINFO_SEC */
     449        {
     450                uint8_t *p_marshalled_sd = NULL;
     451                size_t sd_size = 0;
     452
     453                status = smbd_do_query_security_desc(conn,
     454                                state,
     455                                fsp,
     456                                /* Security info wanted. */
     457                                in_additional_information,
     458                                in_output_buffer_length,
     459                                &p_marshalled_sd,
     460                                &sd_size);
     461
     462                if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
     463                        /* Return needed size. */
     464                        state->out_output_buffer = data_blob_talloc(state,
     465                                                                    NULL,
     466                                                                    4);
     467                        if (tevent_req_nomem(state->out_output_buffer.data, req)) {
     468                                return tevent_req_post(req, ev);
     469                        }
     470                        SIVAL(state->out_output_buffer.data,0,(uint32_t)sd_size);
     471                        state->status = NT_STATUS_BUFFER_TOO_SMALL;
     472                        break;
     473                }
     474                if (!NT_STATUS_IS_OK(status)) {
     475                        DEBUG(10,("smbd_smb2_getinfo_send: "
     476                                 "smbd_do_query_security_desc of %s failed "
     477                                 "(%s)\n", fsp_str_dbg(fsp),
     478                                 nt_errstr(status)));
     479                        tevent_req_nterror(req, status);
     480                        return tevent_req_post(req, ev);
     481                }
     482
     483                if (sd_size > 0) {
     484                        state->out_output_buffer = data_blob_talloc(state,
     485                                                                    p_marshalled_sd,
     486                                                                    sd_size);
     487                        if (tevent_req_nomem(state->out_output_buffer.data, req)) {
     488                                return tevent_req_post(req, ev);
     489                        }
     490                }
     491                break;
     492        }
     493
    397494        default:
     495                DEBUG(10,("smbd_smb2_getinfo_send: "
     496                        "unknown in_info_type of %u "
     497                        " for file %s\n",
     498                        (unsigned int)in_info_type,
     499                        fsp_str_dbg(fsp) ));
     500
    398501                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
    399502                return tevent_req_post(req, ev);
     
    406509static NTSTATUS smbd_smb2_getinfo_recv(struct tevent_req *req,
    407510                                       TALLOC_CTX *mem_ctx,
    408                                        DATA_BLOB *out_output_buffer)
     511                                       DATA_BLOB *out_output_buffer,
     512                                       NTSTATUS *pstatus)
    409513{
    410514        NTSTATUS status;
     
    419523        *out_output_buffer = state->out_output_buffer;
    420524        talloc_steal(mem_ctx, out_output_buffer->data);
     525        *pstatus = state->status;
    421526
    422527        tevent_req_received(req);
Note: See TracChangeset for help on using the changeset viewer.