Print this page
    
1575 untangle libmlrpc from SMB server
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/smbsrv/libmlsvc/common/eventlog_svc.c
          +++ new/usr/src/lib/smbsrv/libmlsvc/common/eventlog_svc.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  
    | 
      ↓ open down ↓ | 
    13 lines elided | 
    
      ↑ open up ↑ | 
  
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
       24 + * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  24   25   */
  25   26  
  26   27  /*
  27   28   * Event Log Service RPC (LOGR) interface definition.
  28   29   */
  29   30  #include <sys/utsname.h>
  30   31  #include <unistd.h>
  31   32  #include <strings.h>
       33 +#include <libmlrpc/libmlrpc.h>
  32   34  #include <smbsrv/libsmb.h>
  33      -#include <smbsrv/libmlrpc.h>
  34   35  #include <smbsrv/nmpipes.h>
  35   36  #include <smbsrv/libmlsvc.h>
  36   37  #include <smbsrv/ndl/eventlog.ndl>
  37   38  
  38   39  
  39   40  #define LOGR_FWD                +1
  40   41  #define LOGR_REW                -1
  41   42  #define LOGR_RECORD_SIGNATURE   0x654C664C
  42   43  
  43   44  #define LOGR_PRI(p)             ((p) & LOG_PRIMASK)
  44   45  #define LOGR_WNSTRLEN(S)        ((strlen((S)) + 1) * sizeof (smb_wchar_t))
  45   46  
  46   47  #define LOGR_MSG_DWORD_OFFSET   12
  47   48  #define LOGR_MSG_WORD_OFFSET    4
  48   49  
  49   50  /*
  50   51   * READ flags for EventLogRead
  51   52   *
  52   53   * EVENTLOG_SEEK_READ
  53   54   * The read operation proceeds from the record specified by the
  54   55   * dwRecordOffset parameter. This flag cannot be used with
  55   56   * EVENTLOG_SEQUENTIAL_READ.
  56   57   *
  57   58   * EVENTLOG_SEQUENTIAL_READ
  58   59   * The read operation proceeds sequentially from the last call to the
  59   60   * ReadEventLog function using this handle. This flag cannot be used
  60   61   * with EVENTLOG_SEEK_READ.
  61   62   *
  62   63   * If the buffer is large enough, more than one record can be read at
  63   64   * the specified seek position; you must specify one of the following
  64   65   * flags to indicate the direction for successive read operations.
  65   66   *
  66   67   * EVENTLOG_FORWARDS_READ
  67   68   * The log is read in chronological order. This flag cannot be used
  68   69   * with EVENTLOG_BACKWARDS_READ.
  69   70   *
  70   71   * EVENTLOG_BACKWARDS_READ
  71   72   * The log is read in reverse chronological order. This flag cannot be
  72   73   * used with EVENTLOG_FORWARDS_READ.
  73   74   */
  74   75  #define EVENTLOG_SEQUENTIAL_READ        0x0001
  75   76  #define EVENTLOG_SEEK_READ              0x0002
  76   77  #define EVENTLOG_FORWARDS_READ          0x0004
  77   78  #define EVENTLOG_BACKWARDS_READ         0x0008
  78   79  
  79   80  /*
  80   81   * The types of events that can be logged.
  81   82   */
  82   83  #define EVENTLOG_SUCCESS                0x0000
  83   84  #define EVENTLOG_ERROR_TYPE             0x0001
  84   85  #define EVENTLOG_WARNING_TYPE           0x0002
  85   86  #define EVENTLOG_INFORMATION_TYPE       0x0004
  86   87  #define EVENTLOG_AUDIT_SUCCESS          0x0008
  87   88  #define EVENTLOG_AUDIT_FAILURE          0x0010
  88   89  
  89   90  /*
  90   91   * Event Identifiers
  91   92   *
  92   93   * Event identifiers uniquely identify a particular event. Each event
  93   94   * source can define its own numbered events and the description strings
  94   95   * to which they are mapped. Event viewers can present these strings to
  95   96   * the user. They should help the user understand what went wrong and
  96   97   * suggest what actions to take. Direct the description at users solving
  97   98   * their own problems, not at administrators or support technicians.
  98   99   * Make the description clear and concise and avoid culture-specific
  99  100   * phrases.
 100  101   *
 101  102   * The following diagram illustrates the format of an event identifier.
 102  103   *
 103  104   *   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
 104  105   *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
 105  106   *  +---+-+-+-----------------------+-------------------------------+
 106  107   *  |Sev|C|R|     Facility          |               Code            |
 107  108   *  +---+-+-+-----------------------+-------------------------------+
 108  109   *
 109  110   *  Sev
 110  111   *        Indicates the severity. This is one of the following values:
 111  112   *        00 - Success
 112  113   *        01 - Informational
 113  114   *        10 - Warning
 114  115   *        11 - Error
 115  116   *
 116  117   *  C
 117  118   *        Indicates a customer code (1) or a system code (0).
 118  119   *  R
 119  120   *        Reserved bit.
 120  121   *  Facility
 121  122   *        Facility code.
 122  123   *  Code
 123  124   *        Status code for the facility.
 124  125   */
 125  126  #define EVENTID_SEVERITY_SUCCESS        0x00000000
 126  127  #define EVENTID_SEVERITY_INFO           0x40000000
 127  128  #define EVENTID_SEVERITY_WARNING        0x80000000
 128  129  #define EVENTID_SEVERITY_ERROR          0xC0000000
 129  130  
 130  131  #define EVENTID_SYSTEM_CODE             0x00000000
 131  132  #define EVENTID_CUSTOMER_CODE           0x20000000
 132  133  
 133  134  static int logr_s_EventLogClose(void *, ndr_xa_t *);
 134  135  static int logr_s_EventLogQueryCount(void *, ndr_xa_t *);
 135  136  static int logr_s_EventLogGetOldestRec(void *, ndr_xa_t *);
 136  137  static int logr_s_EventLogOpen(void *, ndr_xa_t *);
 137  138  static int logr_s_EventLogRead(void *, ndr_xa_t *);
 138  139  
 139  140  static ndr_stub_table_t logr_stub_table[] = {
 140  141          { logr_s_EventLogClose,         LOGR_OPNUM_EventLogClose },
 141  142          { logr_s_EventLogQueryCount,    LOGR_OPNUM_EventLogQueryCount },
 142  143          { logr_s_EventLogGetOldestRec,  LOGR_OPNUM_EventLogGetOldestRec },
 143  144          { logr_s_EventLogOpen,          LOGR_OPNUM_EventLogOpen },
 144  145          { logr_s_EventLogRead,          LOGR_OPNUM_EventLogRead },
 145  146          {0}
 146  147  };
 147  148  
 148  149  static ndr_service_t logr_service = {
 149  150          "LOGR",                         /* name */
 150  151          "Event Log Service",            /* desc */
 151  152          "\\eventlog",                   /* endpoint */
 152  153          PIPE_NTSVCS,                    /* sec_addr_port */
 153  154          "82273fdc-e32a-18c3-3f78-827929dc23ea", 0,      /* abstract */
 154  155          NDR_TRANSFER_SYNTAX_UUID,               2,      /* transfer */
 155  156          0,                              /* no bind_instance_size */
 156  157          0,                              /* no bind_req() */
 157  158          0,                              /* no unbind_and_close() */
 158  159          0,                              /* use generic_call_stub() */
 159  160          &TYPEINFO(logr_interface),      /* interface ti */
 160  161          logr_stub_table                 /* stub_table */
 161  162  };
 162  163  
 163  164  /*
 164  165   * logr_initialize
 165  166   *
 166  167   * This function registers the LOGR RPC interface with the RPC runtime
 167  168   * library. It must be called in order to use either the client side
 168  169   * or the server side functions.
 169  170   */
 170  171  void
 171  172  logr_initialize(void)
 172  173  {
 173  174          (void) ndr_svc_register(&logr_service);
 174  175          logr_init();
 175  176  }
 176  177  
 177  178  void
 178  179  logr_finalize(void)
 179  180  {
 180  181          logr_fini();
 181  182  }
 182  183  
 183  184  /*
 184  185   * logr_hdlookup
 185  186   *
 186  187   * Handle lookup wrapper to validate the local service and/or manager context.
 187  188   */
 188  189  static ndr_handle_t *
 189  190  logr_hdlookup(ndr_xa_t *mxa, ndr_hdid_t *id)
 190  191  {
 191  192          ndr_handle_t *hd;
 192  193          logr_context_t *ctx;
 193  194  
 194  195          if ((hd = ndr_hdlookup(mxa, id)) == NULL)
 195  196                  return (NULL);
 196  197  
 197  198          if ((ctx = (logr_context_t *)hd->nh_data) == NULL)
 198  199                  return (NULL);
 199  200  
 200  201          if (ctx->lc_source_name == NULL)
 201  202                  return (NULL);
 202  203  
 203  204          return (hd);
 204  205  }
 205  206  
 206  207  /*
 207  208   * logr_context_data_free
 208  209   *
 209  210   * Callback to free the context data associated with local service
 210  211   * and/or manager context.
 211  212   */
 212  213  static void
 213  214  logr_context_data_free(void *ctxp)
 214  215  {
 215  216          logr_context_t *ctx = (logr_context_t *)ctxp;
 216  217  
 217  218          if (ctx == NULL)
 218  219                  return;
 219  220  
 220  221          free(ctx->lc_source_name);
 221  222          free(ctx->lc_cached_read_data->rd_log);
 222  223          free(ctx->lc_cached_read_data);
 223  224          free(ctx);
 224  225          ctx = NULL;
 225  226  }
 226  227  
 227  228  /*
 228  229   * logr_hdalloc
 229  230   *
 230  231   * Handle allocation wrapper to setup the local manager context.
 231  232   */
 232  233  static ndr_hdid_t *
 233  234  logr_hdalloc(ndr_xa_t *mxa, char *logname)
 234  235  {
 235  236          logr_context_t *ctx;
 236  237  
 237  238          if ((ctx = malloc(sizeof (logr_context_t))) == NULL)
 238  239                  return (NULL);
 239  240          bzero(ctx, sizeof (logr_context_t));
 240  241  
 241  242          ctx->lc_source_name = strdup(logname);
 242  243          if (ctx->lc_source_name == NULL) {
 243  244                  free(ctx);
 244  245                  return (NULL);
 245  246          }
 246  247  
 247  248          if (logr_get_snapshot(ctx) != 0) {
 248  249                  free(ctx->lc_source_name);
 249  250                  free(ctx);
 250  251                  return (NULL);
 251  252          }
 252  253  
 253  254          return (ndr_hdalloc(mxa, ctx));
 254  255  }
 255  256  
 256  257  /*
 257  258   * logr_s_EventLogClose
 258  259   *
 259  260   * This is a request to close the LOGR interface specified by handle.
 260  261   * Free the handle and associated resources, and zero out the result
 261  262   * handle for the client.
 262  263   */
 263  264  static int
 264  265  logr_s_EventLogClose(void *arg, ndr_xa_t *mxa)
 265  266  {
 266  267          struct logr_EventLogClose *param = arg;
 267  268          ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
 268  269          ndr_handle_t *hd;
 269  270  
 270  271          if ((hd = ndr_hdlookup(mxa, id)) == NULL) {
 271  272                  bzero(¶m->result_handle, sizeof (logr_handle_t));
 272  273                  param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
 273  274                  return (NDR_DRC_OK);
 274  275          }
 275  276          logr_context_data_free(hd->nh_data);
 276  277          ndr_hdfree(mxa, id);
 277  278  
 278  279          bzero(¶m->result_handle, sizeof (logr_handle_t));
 279  280          param->status = NT_STATUS_SUCCESS;
 280  281  
 281  282          return (NDR_DRC_OK);
 282  283  }
 283  284  
 284  285  /*
 285  286   * logr_s_EventLogOpen
 286  287   *
 287  288   * Open the event log. Not supported yet.
 288  289   */
 289  290  /*ARGSUSED*/
 290  291  static int
 291  292  logr_s_EventLogOpen(void *arg, ndr_xa_t *mxa)
 292  293  {
 293  294          struct logr_EventLogOpen *param = arg;
 294  295          ndr_hdid_t *id = NULL;
 295  296          ndr_handle_t *hd;
 296  297          char *log_name = NULL;
 297  298  
 298  299          if (!ndr_is_admin(mxa)) {
 299  300                  bzero(¶m->handle, sizeof (logr_handle_t));
 300  301                  param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
 301  302                  return (NDR_DRC_OK);
 302  303          }
 303  304  
 304  305          if (param->log_name.length != 0)
 305  306                  log_name = (char *)param->log_name.str;
 306  307  
 307  308          if (!logr_is_supported(log_name)) {
 308  309                  bzero(¶m->handle, sizeof (logr_handle_t));
 309  310                  param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
 310  311                  return (NDR_DRC_OK);
 311  312          }
 312  313  
 313  314          id = logr_hdalloc(mxa, log_name);
 314  315          if (id && ((hd = logr_hdlookup(mxa, id)) != NULL)) {
 315  316                  hd->nh_data_free = logr_context_data_free;
 316  317                  bcopy(id, ¶m->handle, sizeof (logr_handle_t));
 317  318                  param->status = NT_STATUS_SUCCESS;
 318  319          } else {
 319  320                  bzero(¶m->handle, sizeof (logr_handle_t));
 320  321                  param->status = NT_SC_ERROR(NT_STATUS_ACCESS_DENIED);
 321  322          }
 322  323  
 323  324          return (NDR_DRC_OK);
 324  325  }
 325  326  
 326  327  /*
 327  328   * logr_s_EventLogQueryCount
 328  329   *
 329  330   * take a snapshot from system log, assign it to the given handle.
 330  331   * return number of log entries in the snapshot as result of RPC
 331  332   * call.
 332  333   */
 333  334  static int
 334  335  logr_s_EventLogQueryCount(void *arg, ndr_xa_t *mxa)
 335  336  {
 336  337          struct logr_EventLogQueryCount *param = arg;
 337  338          ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
 338  339          ndr_handle_t *hd;
 339  340          logr_context_t *ctx;
 340  341          logr_read_data_t *data;
 341  342  
 342  343          if ((hd = logr_hdlookup(mxa, id)) == NULL) {
 343  344                  param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
 344  345                  return (NDR_DRC_OK);
 345  346          }
 346  347  
 347  348          ctx = (logr_context_t *)hd->nh_data;
 348  349          data = ctx->lc_cached_read_data;
 349  350  
 350  351          param->rec_num = data->rd_tot_recnum;
 351  352          param->status = NT_STATUS_SUCCESS;
 352  353          return (NDR_DRC_OK);
 353  354  }
 354  355  
 355  356  /*
 356  357   * logr_s_EventLogGetOldestRec
 357  358   *
 358  359   * Return oldest record number in the snapshot as result of RPC call.
 359  360   */
 360  361  static int
 361  362  logr_s_EventLogGetOldestRec(void *arg, ndr_xa_t *mxa)
 362  363  {
 363  364          struct logr_EventLogGetOldestRec *param = arg;
 364  365          ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
 365  366          ndr_handle_t *hd;
 366  367          logr_context_t *ctx;
 367  368          logr_read_data_t *data;
 368  369  
 369  370          if ((hd = logr_hdlookup(mxa, id)) == NULL) {
 370  371                  param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
 371  372                  return (NDR_DRC_OK);
 372  373          }
 373  374  
 374  375          ctx = (logr_context_t *)hd->nh_data;
 375  376          data = ctx->lc_cached_read_data;
 376  377  
 377  378          param->oldest_rec = data->rd_log->li_idx - data->rd_tot_recnum + 1;
 378  379  
 379  380          param->status = NT_STATUS_SUCCESS;
 380  381          return (NDR_DRC_OK);
 381  382  }
 382  383  
 383  384  /*
 384  385   * logr_set_event_typeid
 385  386   *
 386  387   * Map the local system log priority to the event type and event ID
 387  388   * for Windows events.
 388  389   */
 389  390  void
 390  391  logr_set_event_typeid(int le_pri, WORD *etype, DWORD *eid)
 391  392  {
 392  393          switch (LOGR_PRI(le_pri)) {
 393  394          case LOG_EMERG:
 394  395          case LOG_ALERT:
 395  396          case LOG_CRIT:
 396  397          case LOG_ERR:
 397  398                  *eid   = EVENTID_SEVERITY_ERROR;
 398  399                  *etype = EVENTLOG_ERROR_TYPE;
 399  400                  break;
 400  401          case LOG_WARNING:
 401  402                  *eid   = EVENTID_SEVERITY_WARNING;
 402  403                  *etype = EVENTLOG_WARNING_TYPE;
 403  404                  break;
 404  405          case LOG_NOTICE:
 405  406          case LOG_INFO:
 406  407          case LOG_DEBUG:
 407  408                  *eid   = EVENTID_SEVERITY_INFO;
 408  409                  *etype = EVENTLOG_INFORMATION_TYPE;
 409  410                  break;
 410  411          default:
 411  412                  *eid   = EVENTID_SEVERITY_SUCCESS;
 412  413                  *etype = EVENTLOG_SUCCESS;
 413  414          }
 414  415  }
 415  416  
 416  417  /*
 417  418   * logr_get_entry
 418  419   *
 419  420   * Gets a log entry.
 420  421   */
 421  422  static logr_entry_t *
 422  423  logr_get_entry(logr_info_t *linfo, int entno)
 423  424  {
 424  425          return (&linfo->li_entry[entno]);
 425  426  }
 426  427  
 427  428  /*
 428  429   * logr_set_logrecord
 429  430   *
 430  431   * Fill a Windows event record based on a local system log record.
 431  432   */
 432  433  static void
 433  434  logr_set_logrecord(char *src_name, logr_entry_t *le,
 434  435      DWORD recno, logr_record_t *rec)
 435  436  {
 436  437          int srcname_len = 0, hostname_len = 0, len;
 437  438          int str_offs, sh_len;
 438  439          smb_wchar_t wcs_hostname[MAXHOSTNAMELEN];
 439  440          smb_wchar_t wcs_srcname[SYS_NMLN * 2];
 440  441  
 441  442          (void) smb_mbstowcs(wcs_srcname, src_name,
 442  443              strlen(src_name) + 1);
 443  444          srcname_len = LOGR_WNSTRLEN(src_name);
 444  445  
 445  446          /* Because, Solaris allows remote logging, need to get hostname here */
 446  447          (void) smb_mbstowcs(wcs_hostname, le->le_hostname,
 447  448              strlen(le->le_hostname) + 1);
 448  449          hostname_len = LOGR_WNSTRLEN(le->le_hostname);
 449  450  
 450  451          sh_len = srcname_len + hostname_len;
 451  452          str_offs = LOGR_MSG_DWORD_OFFSET * sizeof (DWORD) +
 452  453              LOGR_MSG_WORD_OFFSET * sizeof (WORD) + sh_len;
 453  454  
 454  455          rec->Length1 = sizeof (logr_record_t);
 455  456          rec->Reserved = LOGR_RECORD_SIGNATURE;
 456  457          rec->RecordNumber = recno;
 457  458          rec->TimeGenerated = le->le_timestamp.tv_sec;
 458  459          rec->TimeWritten = le->le_timestamp.tv_sec;
 459  460          logr_set_event_typeid(le->le_pri, &rec->EventType, &rec->EventID);
 460  461          rec->NumStrings = 1;
 461  462          rec->EventCategory = 0;
 462  463          rec->ReservedFlags = 0;
 463  464          rec->ClosingRecordNumber = 0;
 464  465          rec->StringOffset = str_offs;
 465  466          rec->UserSidLength = 0;
 466  467          rec->UserSidOffset = 0;
 467  468          rec->DataLength = 0;
 468  469          rec->DataOffset = 0;
 469  470  
 470  471          bzero(rec->info, LOGR_MAXENTRYLEN);
 471  472          (void) memcpy(rec->info, wcs_srcname, srcname_len);
 472  473          (void) memcpy(rec->info + srcname_len, wcs_hostname, hostname_len);
 473  474  
 474  475          len = strlen(le->le_msg) + 1;
 475  476          if (len > 0)
 476  477                  /*LINTED E_BAD_PTR_CAST_ALIGN*/
 477  478                  (void) smb_mbstowcs((smb_wchar_t *)(rec->info + sh_len),
 478  479                      le->le_msg, len);
 479  480  
 480  481          rec->Length2 = sizeof (logr_record_t);
 481  482  }
 482  483  
 483  484  /*
 484  485   * logr_s_EventLogRead
 485  486   *
 486  487   * Reads a whole number of entries from system log. The function can
 487  488   * read log entries in chronological or reverse chronological order.
 488  489   */
 489  490  static int
 490  491  logr_s_EventLogRead(void *arg, ndr_xa_t *mxa)
 491  492  {
 492  493          struct logr_EventLogRead *param = arg;
 493  494          ndr_hdid_t *id = (ndr_hdid_t *)¶m->handle;
 494  495          ndr_handle_t *hd;
 495  496          logr_read_data_t *rdata;
 496  497          logr_entry_t *le;
 497  498          DWORD ent_no, ent_num, ent_remain;
 498  499          logr_record_t *rec;
 499  500          BYTE *buf;
 500  501          int dir, ent_per_req, iter;
 501  502          logr_context_t *ctx;
 502  503  
 503  504          if ((hd = logr_hdlookup(mxa, id)) == NULL) {
 504  505                  param->status = NT_SC_ERROR(NT_STATUS_INVALID_HANDLE);
 505  506                  return (NDR_DRC_OK);
 506  507          }
 507  508  
 508  509          ctx = (logr_context_t *)hd->nh_data;
 509  510          rdata = ctx->lc_cached_read_data;
 510  511          if (rdata == NULL) {
 511  512                  param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
 512  513                  return (NDR_DRC_OK);
 513  514          }
 514  515  
 515  516          dir = (param->read_flags & EVENTLOG_FORWARDS_READ) ?
 516  517              LOGR_FWD : LOGR_REW;
 517  518  
 518  519          if (param->read_flags & EVENTLOG_SEEK_READ)
 519  520                  rdata->rd_last_sentrec = param->rec_offset;
 520  521          else if (rdata->rd_first_read)
 521  522                  /*
 522  523                   * set last record number which is read for
 523  524                   * the first iteration of sequential read.
 524  525                   */
 525  526                  rdata->rd_last_sentrec = (dir == LOGR_FWD)
 526  527                      ? (rdata->rd_log->li_idx - rdata->rd_tot_recnum)
 527  528                      : rdata->rd_log->li_idx;
 528  529  
 529  530          ent_remain = (dir == LOGR_FWD)
 530  531              ? (rdata->rd_tot_recnum - rdata->rd_last_sentrec)
 531  532              : rdata->rd_last_sentrec;
 532  533  
 533  534          /*
 534  535           * function should return as many whole log entries as
 535  536           * will fit in the buffer; it should not return partial
 536  537           * entries, even if there is room in the buffer.
 537  538           */
 538  539          ent_per_req = param->nbytes_to_read / sizeof (logr_record_t);
 539  540          if (ent_remain > ent_per_req)
 540  541                  ent_remain = ent_per_req;
 541  542  
 542  543          if (ent_remain == 0) {
 543  544                  /*
 544  545                   * Send this error to Windows client so that it
 545  546                   * can figure out that there is no more record
 546  547                   * to read.
 547  548                   */
 548  549                  param->buf = NDR_STRDUP(mxa, "");
 549  550                  param->sent_size = 0;
 550  551                  param->status = NT_SC_ERROR(NT_STATUS_END_OF_FILE);
 551  552                  return (NDR_DRC_OK);
 552  553          }
 553  554  
 554  555          param->buf = NDR_MALLOC(mxa, param->nbytes_to_read);
 555  556          buf = (BYTE *)param->buf;
 556  557  
 557  558          for (ent_num = 0, ent_no = rdata->rd_last_sentrec;
 558  559              ent_num < ent_remain; ent_num++, ent_no += dir) {
 559  560  
 560  561                  iter = ent_no & LOGR_NMSGMASK;
 561  562                  if (dir == LOGR_REW)
 562  563                          iter = (ent_no - 1) & LOGR_NMSGMASK;
 563  564  
 564  565                  le = logr_get_entry(rdata->rd_log, iter);
 565  566  
 566  567                  /*LINTED E_BAD_PTR_CAST_ALIGN*/
 567  568                  rec = (logr_record_t *)buf;
 568  569                  logr_set_logrecord(ctx->lc_source_name, le, ent_no, rec);
 569  570                  buf += sizeof (logr_record_t);
 570  571          }
 571  572  
 572  573          rdata->rd_last_sentrec = ent_no;
 573  574          rdata->rd_first_read = 0;
 574  575  
 575  576          param->sent_size = sizeof (logr_record_t) * ent_remain;
 576  577          param->status = NT_STATUS_SUCCESS;
 577  578  
 578  579          return (NDR_DRC_OK);
 579  580  }
  
    | 
      ↓ open down ↓ | 
    536 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX