LCOV - code coverage report
Current view: top level - source4/libcli/smb_composite - fsinfo.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 80 94 85.1 %
Date: 2024-04-21 15:09:00 Functions: 7 8 87.5 %

          Line data    Source code
       1             : /*
       2             :   a composite API for querying file system information
       3             : */
       4             : 
       5             : #include "includes.h"
       6             : #include "libcli/raw/libcliraw.h"
       7             : #include "libcli/raw/raw_proto.h"
       8             : #include "libcli/composite/composite.h"
       9             : #include "libcli/smb_composite/smb_composite.h"
      10             : #include "libcli/resolve/resolve.h"
      11             : 
      12             : /* the stages of this call */
      13             : enum fsinfo_stage {FSINFO_CONNECT, FSINFO_QUERY};
      14             : 
      15             : 
      16             : static void fsinfo_raw_handler(struct smbcli_request *req);
      17             : static void fsinfo_composite_handler(struct composite_context *c);
      18             : static void fsinfo_state_handler(struct composite_context *c);
      19             : 
      20             : struct fsinfo_state {
      21             :         enum fsinfo_stage stage;
      22             :         struct composite_context *creq;
      23             :         struct smb_composite_fsinfo *io;
      24             :         struct smb_composite_connect *connect;
      25             :         union smb_fsinfo *fsinfo;
      26             :         struct smbcli_tree *tree;
      27             :         struct smbcli_request *req;
      28             : };
      29             : 
      30          50 : static NTSTATUS fsinfo_connect(struct composite_context *c,
      31             :                                struct smb_composite_fsinfo *io)
      32             : {
      33           0 :         NTSTATUS status;
      34           0 :         struct fsinfo_state *state;
      35          50 :         state = talloc_get_type(c->private_data, struct fsinfo_state);
      36             : 
      37          50 :         status = smb_composite_connect_recv(state->creq, c);
      38          50 :         NT_STATUS_NOT_OK_RETURN(status);
      39             : 
      40          50 :         state->fsinfo = talloc(state, union smb_fsinfo);
      41          50 :         NT_STATUS_HAVE_NO_MEMORY(state->fsinfo);
      42             : 
      43          50 :         state->fsinfo->generic.level = io->in.level;
      44             : 
      45          50 :         state->req = smb_raw_fsinfo_send(state->connect->out.tree,
      46             :                                          state,
      47             :                                          state->fsinfo);
      48          50 :         NT_STATUS_HAVE_NO_MEMORY(state->req);
      49             : 
      50          50 :         state->req->async.private_data = c;
      51          50 :         state->req->async.fn = fsinfo_raw_handler;
      52             : 
      53          50 :         state->stage = FSINFO_QUERY;
      54             : 
      55          50 :         return NT_STATUS_OK;
      56             : }
      57             : 
      58          50 : static NTSTATUS fsinfo_query(struct composite_context *c,
      59             :                                struct smb_composite_fsinfo *io)
      60             : {
      61           0 :         NTSTATUS status;
      62           0 :         struct fsinfo_state *state;
      63          50 :         state = talloc_get_type(c->private_data, struct fsinfo_state);
      64             : 
      65          50 :         status = smb_raw_fsinfo_recv(state->req, state, state->fsinfo);
      66          50 :         NT_STATUS_NOT_OK_RETURN(status);
      67             : 
      68          50 :         state->io->out.fsinfo = state->fsinfo;
      69             : 
      70          50 :         c->state = COMPOSITE_STATE_DONE;
      71             : 
      72          50 :         if (c->async.fn)
      73          50 :                 c->async.fn(c);
      74             : 
      75          50 :         return NT_STATUS_OK;
      76             : 
      77             : }
      78             : 
      79             : /*
      80             :   handler for completion of a sub-request in fsinfo
      81             : */
      82         100 : static void fsinfo_state_handler(struct composite_context *creq)
      83             : {
      84         100 :         struct fsinfo_state *state = talloc_get_type(creq->private_data, struct fsinfo_state);
      85             : 
      86             :         /* when this handler is called, the stage indicates what
      87             :            call has just finished */
      88         100 :         switch (state->stage) {
      89          50 :         case FSINFO_CONNECT:
      90          50 :                 creq->status = fsinfo_connect(creq, state->io);
      91          50 :                 break;
      92             : 
      93          50 :         case FSINFO_QUERY:
      94          50 :                 creq->status = fsinfo_query(creq, state->io);
      95          50 :                 break;
      96             :         }
      97             : 
      98         100 :         if (!NT_STATUS_IS_OK(creq->status)) {
      99           0 :                 creq->state = COMPOSITE_STATE_ERROR;
     100             :         }
     101             : 
     102         100 :         if (creq->state >= COMPOSITE_STATE_DONE && creq->async.fn) {
     103          50 :                 creq->async.fn(creq);
     104             :         }
     105         100 : }
     106             : 
     107             : /* 
     108             :    As raw and composite handlers take different requests, we need to handlers
     109             :    to adapt both for the same state machine in fsinfo_state_handler()
     110             : */
     111          50 : static void fsinfo_raw_handler(struct smbcli_request *req)
     112             : {
     113          50 :         struct composite_context *c = talloc_get_type(req->async.private_data,
     114             :                                                       struct composite_context);
     115          50 :         fsinfo_state_handler(c);
     116          50 : }
     117             : 
     118          50 : static void fsinfo_composite_handler(struct composite_context *creq)
     119             : {
     120          50 :         struct composite_context *c = talloc_get_type(creq->async.private_data, 
     121             :                                                       struct composite_context);
     122          50 :         fsinfo_state_handler(c);
     123          50 : }
     124             : 
     125             : /*
     126             :   composite fsinfo call - connects to a tree and queries a file system information
     127             : */
     128          50 : struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, 
     129             :                                                     struct smb_composite_fsinfo *io,
     130             :                                                     struct resolve_context *resolve_ctx,
     131             :                                                     struct tevent_context *event_ctx)
     132             : {
     133           0 :         struct composite_context *c;
     134           0 :         struct fsinfo_state *state;
     135             : 
     136          50 :         c = talloc_zero(tree, struct composite_context);
     137          50 :         if (c == NULL) goto failed;
     138             : 
     139          50 :         c->event_ctx = event_ctx;
     140          50 :         if (c->event_ctx == NULL) goto failed;
     141             : 
     142          50 :         state = talloc(c, struct fsinfo_state);
     143          50 :         if (state == NULL) goto failed;
     144             : 
     145          50 :         state->io = io;
     146             : 
     147          50 :         state->connect = talloc_zero(state, struct smb_composite_connect);
     148             : 
     149          50 :         if (state->connect == NULL) goto failed;
     150             : 
     151          50 :         state->connect->in.dest_host    = io->in.dest_host;
     152          50 :         state->connect->in.dest_ports   = io->in.dest_ports;
     153          50 :         state->connect->in.socket_options = io->in.socket_options;
     154          50 :         state->connect->in.called_name  = io->in.called_name;
     155          50 :         state->connect->in.service      = io->in.service;
     156          50 :         state->connect->in.service_type = io->in.service_type;
     157          50 :         state->connect->in.credentials  = io->in.credentials;
     158          50 :         state->connect->in.fallback_to_anonymous = false;
     159          50 :         state->connect->in.workgroup    = io->in.workgroup;
     160          50 :         state->connect->in.gensec_settings = io->in.gensec_settings;
     161             : 
     162          50 :         state->connect->in.options = tree->session->transport->options;
     163          50 :         state->connect->in.session_options = tree->session->options;
     164             : 
     165          50 :         c->state = COMPOSITE_STATE_IN_PROGRESS;
     166          50 :         state->stage = FSINFO_CONNECT;
     167          50 :         c->private_data = state;
     168             : 
     169          50 :         state->creq = smb_composite_connect_send(state->connect, state,
     170             :                          resolve_ctx, c->event_ctx);
     171             : 
     172          50 :         if (state->creq == NULL) goto failed;
     173             :   
     174          50 :         state->creq->async.private_data = c;
     175          50 :         state->creq->async.fn = fsinfo_composite_handler;
     176             :   
     177          50 :         return c;
     178           0 : failed:
     179           0 :         talloc_free(c);
     180           0 :         return NULL;
     181             : }
     182             : 
     183             : /*
     184             :   composite fsinfo call - recv side
     185             : */
     186          50 : NTSTATUS smb_composite_fsinfo_recv(struct composite_context *c, TALLOC_CTX *mem_ctx)
     187             : {
     188           0 :         NTSTATUS status;
     189             : 
     190          50 :         status = composite_wait(c);
     191             : 
     192          50 :         if (NT_STATUS_IS_OK(status)) {
     193          50 :                 struct fsinfo_state *state = talloc_get_type(c->private_data, struct fsinfo_state);
     194          50 :                 talloc_steal(mem_ctx, state->io->out.fsinfo);
     195             :         }
     196             : 
     197          50 :         talloc_free(c);
     198          50 :         return status;
     199             : }
     200             : 
     201             : 
     202             : /*
     203             :   composite fsinfo call - sync interface
     204             : */
     205           0 : NTSTATUS smb_composite_fsinfo(struct smbcli_tree *tree, 
     206             :                               TALLOC_CTX *mem_ctx,
     207             :                               struct smb_composite_fsinfo *io,
     208             :                               struct resolve_context *resolve_ctx,
     209             :                               struct tevent_context *ev)
     210             : {
     211           0 :         struct composite_context *c = smb_composite_fsinfo_send(tree, io, resolve_ctx, ev);
     212           0 :         return smb_composite_fsinfo_recv(c, mem_ctx);
     213             : }
     214             : 

Generated by: LCOV version 1.14