LCOV - code coverage report
Current view: top level - source3/rpc_client - cli_mdssvc_util.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 200 326 61.3 %
Date: 2021-09-23 10:06:22 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Main metadata server / Spotlight client functions
       4             : 
       5             :    Copyright (C) Ralph Boehme 2019
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "rpc_client.h"
      23             : #include "librpc/gen_ndr/mdssvc.h"
      24             : #include "cli_mdssvc.h"
      25             : #include "cli_mdssvc_private.h"
      26             : #include "cli_mdssvc_util.h"
      27             : #include "lib/util/tevent_ntstatus.h"
      28             : #include "rpc_server/mdssvc/dalloc.h"
      29             : #include "rpc_server/mdssvc/marshalling.h"
      30             : 
      31           6 : NTSTATUS mdscli_blob_search(TALLOC_CTX *mem_ctx,
      32             :                             struct mdscli_search_ctx *search,
      33             :                             struct mdssvc_blob *blob)
      34             : {
      35           6 :         struct mdscli_ctx *ctx = search->mdscli_ctx;
      36           6 :         DALLOC_CTX *d = NULL;
      37           6 :         uint64_t *uint64p = NULL;
      38           6 :         sl_array_t *array = NULL;
      39           6 :         sl_array_t *cmd_array = NULL;
      40           6 :         sl_dict_t *query_dict = NULL;
      41           6 :         sl_array_t *attr_array = NULL;
      42           6 :         sl_array_t *scope_array = NULL;
      43             :         double dval;
      44             :         uint64_t uint64val;
      45             :         ssize_t len;
      46             :         int ret;
      47             : 
      48           6 :         d = dalloc_new(mem_ctx);
      49           6 :         if (d == NULL) {
      50           0 :                 return NT_STATUS_NO_MEMORY;
      51             :         }
      52             : 
      53           6 :         array = dalloc_zero(d, sl_array_t);
      54           6 :         if (array == NULL) {
      55           0 :                 TALLOC_FREE(d);
      56           0 :                 return NT_STATUS_NO_MEMORY;
      57             :         }
      58             : 
      59           6 :         ret = dalloc_add(d, array, sl_array_t);
      60           6 :         if (ret != 0) {
      61           0 :                 TALLOC_FREE(d);
      62           0 :                 return NT_STATUS_NO_MEMORY;
      63             :         }
      64             : 
      65           6 :         cmd_array = dalloc_zero(d, sl_array_t);
      66           6 :         if (cmd_array == NULL) {
      67           0 :                 TALLOC_FREE(d);
      68           0 :                 return NT_STATUS_NO_MEMORY;
      69             :         }
      70             : 
      71           6 :         ret = dalloc_add(array, cmd_array, sl_array_t);
      72           6 :         if (ret != 0) {
      73           0 :                 TALLOC_FREE(d);
      74           0 :                 return NT_STATUS_NO_MEMORY;
      75             :         }
      76             : 
      77           6 :         ret = dalloc_stradd(cmd_array, "openQueryWithParams:forContext:");
      78           6 :         if (ret != 0) {
      79           0 :                 TALLOC_FREE(d);
      80           0 :                 return NT_STATUS_NO_MEMORY;
      81             :         }
      82             : 
      83           6 :         uint64p = talloc_zero_array(cmd_array, uint64_t, 2);
      84           6 :         if (uint64p == NULL) {
      85           0 :                 TALLOC_FREE(d);
      86           0 :                 return NT_STATUS_NO_MEMORY;
      87             :         }
      88             : 
      89           6 :         talloc_set_name(uint64p, "uint64_t *");
      90             : 
      91           6 :         uint64p[0] = search->ctx_id.id;
      92           6 :         uint64p[1] = search->ctx_id.connection;
      93             : 
      94           6 :         ret = dalloc_add(cmd_array, uint64p, uint64_t *);
      95           6 :         if (ret != 0) {
      96           0 :                 TALLOC_FREE(d);
      97           0 :                 return NT_STATUS_NO_MEMORY;
      98             :         }
      99             : 
     100           6 :         query_dict = dalloc_zero(array, sl_dict_t);
     101           6 :         if (query_dict == NULL) {
     102           0 :                 TALLOC_FREE(d);
     103           0 :                 return NT_STATUS_NO_MEMORY;
     104             :         }
     105             : 
     106           6 :         ret = dalloc_add(array, query_dict, sl_dict_t);
     107           6 :         if (ret != 0) {
     108           0 :                 TALLOC_FREE(d);
     109           0 :                 return NT_STATUS_NO_MEMORY;
     110             :         }
     111             : 
     112           6 :         ret = dalloc_stradd(query_dict, "kMDQueryBatchFirstDelay");
     113           6 :         if (ret != 0) {
     114           0 :                 TALLOC_FREE(d);
     115           0 :                 return NT_STATUS_NO_MEMORY;
     116             :         }
     117           6 :         dval = 1;
     118           6 :         ret = dalloc_add_copy(query_dict, &dval, double);
     119           6 :         if (ret != 0) {
     120           0 :                 TALLOC_FREE(d);
     121           0 :                 return NT_STATUS_NO_MEMORY;
     122             :         }
     123             : 
     124           6 :         ret = dalloc_stradd(query_dict, "kMDQueryUniqueId");
     125           6 :         if (ret != 0) {
     126           0 :                 TALLOC_FREE(d);
     127           0 :                 return NT_STATUS_NO_MEMORY;
     128             :         }
     129           6 :         ret = dalloc_add_copy(query_dict, &search->unique_id, uint64_t);
     130           6 :         if (ret != 0) {
     131           0 :                 TALLOC_FREE(d);
     132           0 :                 return NT_STATUS_NO_MEMORY;
     133             :         }
     134             : 
     135           6 :         ret = dalloc_stradd(query_dict, "kMDAttributeArray");
     136           6 :         if (ret != 0) {
     137           0 :                 TALLOC_FREE(d);
     138           0 :                 return NT_STATUS_NO_MEMORY;
     139             :         }
     140           6 :         attr_array = dalloc_zero(query_dict, sl_array_t);
     141           6 :         if (attr_array == NULL) {
     142           0 :                 TALLOC_FREE(d);
     143           0 :                 return NT_STATUS_NO_MEMORY;
     144             :         }
     145           6 :         ret = dalloc_add(query_dict, attr_array, sl_array_t);
     146           6 :         if (ret != 0) {
     147           0 :                 TALLOC_FREE(d);
     148           0 :                 return NT_STATUS_NO_MEMORY;
     149             :         }
     150           6 :         ret = dalloc_stradd(attr_array, "kMDItemFSName");
     151           6 :         if (ret != 0) {
     152           0 :                 TALLOC_FREE(d);
     153           0 :                 return NT_STATUS_NO_MEMORY;
     154             :         }
     155             : 
     156           6 :         ret = dalloc_stradd(query_dict, "kMDQueryBatchFirstCount");
     157           6 :         if (ret != 0) {
     158           0 :                 TALLOC_FREE(d);
     159           0 :                 return NT_STATUS_NO_MEMORY;
     160             :         }
     161           6 :         uint64val = 10;
     162           6 :         ret = dalloc_add_copy(query_dict, &uint64val, uint64_t);
     163           6 :         if (ret != 0) {
     164           0 :                 TALLOC_FREE(d);
     165           0 :                 return NT_STATUS_NO_MEMORY;
     166             :         }
     167             : 
     168           6 :         ret = dalloc_stradd(query_dict, "kMDQueryBatchUpdateCount");
     169           6 :         if (ret != 0) {
     170           0 :                 TALLOC_FREE(d);
     171           0 :                 return NT_STATUS_NO_MEMORY;
     172             :         }
     173           6 :         uint64val = 100;
     174           6 :         ret = dalloc_add_copy(query_dict, &uint64val, uint64_t);
     175           6 :         if (ret != 0) {
     176           0 :                 TALLOC_FREE(d);
     177           0 :                 return NT_STATUS_NO_MEMORY;
     178             :         }
     179             : 
     180           6 :         ret = dalloc_stradd(query_dict, "kMDQueryString");
     181           6 :         if (ret != 0) {
     182           0 :                 TALLOC_FREE(d);
     183           0 :                 return NT_STATUS_NO_MEMORY;
     184             :         }
     185           6 :         ret = dalloc_stradd(query_dict, search->mds_query);
     186           6 :         if (ret != 0) {
     187           0 :                 TALLOC_FREE(d);
     188           0 :                 return NT_STATUS_NO_MEMORY;
     189             :         }
     190             : 
     191           6 :         ret = dalloc_stradd(query_dict, "kMDScopeArray");
     192           6 :         if (ret != 0) {
     193           0 :                 TALLOC_FREE(d);
     194           0 :                 return NT_STATUS_NO_MEMORY;
     195             :         }
     196           6 :         scope_array = dalloc_zero(query_dict, sl_array_t);
     197           6 :         if (scope_array == NULL) {
     198           0 :                 TALLOC_FREE(d);
     199           0 :                 return NT_STATUS_NO_MEMORY;
     200             :         }
     201           6 :         ret = dalloc_add(query_dict, scope_array, sl_array_t);
     202           6 :         if (ret != 0) {
     203           0 :                 TALLOC_FREE(d);
     204           0 :                 return NT_STATUS_NO_MEMORY;
     205             :         }
     206           6 :         ret = dalloc_stradd(scope_array, search->path_scope);
     207           6 :         if (ret != 0) {
     208           0 :                 TALLOC_FREE(d);
     209           0 :                 return NT_STATUS_NO_MEMORY;
     210             :         }
     211             : 
     212           6 :         blob->spotlight_blob = talloc_array(d,
     213             :                                             uint8_t,
     214             :                                             ctx->max_fragment_size);
     215           6 :         if (blob->spotlight_blob == NULL) {
     216           0 :                 TALLOC_FREE(d);
     217           0 :                 return NT_STATUS_NO_MEMORY;
     218             :         }
     219           6 :         blob->size = ctx->max_fragment_size;
     220             : 
     221           6 :         len = sl_pack(d, (char *)blob->spotlight_blob, blob->size);
     222           6 :         TALLOC_FREE(d);
     223           6 :         if (len == -1) {
     224           0 :                 return NT_STATUS_NO_MEMORY;
     225             :         }
     226             : 
     227           6 :         blob->length = len;
     228           6 :         blob->size = len;
     229           6 :         return NT_STATUS_OK;
     230             : }
     231             : 
     232           8 : NTSTATUS mdscli_blob_get_results(TALLOC_CTX *mem_ctx,
     233             :                                  struct mdscli_search_ctx *search,
     234             :                                  struct mdssvc_blob *blob)
     235             : {
     236           8 :         struct mdscli_ctx *ctx = search->mdscli_ctx;
     237           8 :         DALLOC_CTX *d = NULL;
     238           8 :         uint64_t *uint64p = NULL;
     239           8 :         sl_array_t *array = NULL;
     240           8 :         sl_array_t *cmd_array = NULL;
     241             :         ssize_t len;
     242             :         int ret;
     243             : 
     244           8 :         d = dalloc_new(mem_ctx);
     245           8 :         if (d == NULL) {
     246           0 :                 return NT_STATUS_NO_MEMORY;
     247             :         }
     248             : 
     249           8 :         array = dalloc_zero(d, sl_array_t);
     250           8 :         if (array == NULL) {
     251           0 :                 TALLOC_FREE(d);
     252           0 :                 return NT_STATUS_NO_MEMORY;
     253             :         }
     254             : 
     255           8 :         ret = dalloc_add(d, array, sl_array_t);
     256           8 :         if (ret != 0) {
     257           0 :                 TALLOC_FREE(d);
     258           0 :                 return NT_STATUS_NO_MEMORY;
     259             :         }
     260             : 
     261           8 :         cmd_array = dalloc_zero(d, sl_array_t);
     262           8 :         if (cmd_array == NULL) {
     263           0 :                 TALLOC_FREE(d);
     264           0 :                 return NT_STATUS_NO_MEMORY;
     265             :         }
     266             : 
     267           8 :         ret = dalloc_add(array, cmd_array, sl_array_t);
     268           8 :         if (ret != 0) {
     269           0 :                 TALLOC_FREE(d);
     270           0 :                 return NT_STATUS_NO_MEMORY;
     271             :         }
     272             : 
     273           8 :         ret = dalloc_stradd(cmd_array, "fetchQueryResultsForContext:");
     274           8 :         if (ret != 0) {
     275           0 :                 TALLOC_FREE(d);
     276           0 :                 return NT_STATUS_NO_MEMORY;
     277             :         }
     278             : 
     279           8 :         uint64p = talloc_zero_array(cmd_array, uint64_t, 2);
     280           8 :         if (uint64p == NULL) {
     281           0 :                 TALLOC_FREE(d);
     282           0 :                 return NT_STATUS_NO_MEMORY;
     283             :         }
     284             : 
     285           8 :         talloc_set_name(uint64p, "uint64_t *");
     286             : 
     287           8 :         uint64p[0] = search->ctx_id.id;
     288           8 :         uint64p[1] = search->ctx_id.connection;
     289             : 
     290           8 :         ret = dalloc_add(cmd_array, uint64p, uint64_t *);
     291           8 :         if (ret != 0) {
     292           0 :                 TALLOC_FREE(d);
     293           0 :                 return NT_STATUS_NO_MEMORY;
     294             :         }
     295             : 
     296           8 :         blob->spotlight_blob = talloc_array(d,
     297             :                                             uint8_t,
     298             :                                             ctx->max_fragment_size);
     299           8 :         if (blob->spotlight_blob == NULL) {
     300           0 :                 TALLOC_FREE(d);
     301           0 :                 return NT_STATUS_NO_MEMORY;
     302             :         }
     303           8 :         blob->size = ctx->max_fragment_size;
     304             : 
     305           8 :         len = sl_pack(d, (char *)blob->spotlight_blob, blob->size);
     306           8 :         TALLOC_FREE(d);
     307           8 :         if (len == -1) {
     308           0 :                 return NT_STATUS_NO_MEMORY;
     309             :         }
     310             : 
     311           8 :         blob->length = len;
     312           8 :         blob->size = len;
     313           8 :         return NT_STATUS_OK;
     314             : }
     315             : 
     316          26 : NTSTATUS mdscli_blob_get_path(TALLOC_CTX *mem_ctx,
     317             :                               struct mdscli_ctx *ctx,
     318             :                               uint64_t cnid,
     319             :                               struct mdssvc_blob *blob)
     320             : {
     321          26 :         struct mdsctx_id ctx_id = mdscli_new_ctx_id(ctx);
     322          26 :         DALLOC_CTX *d = NULL;
     323          26 :         uint64_t *uint64var = NULL;
     324          26 :         sl_array_t *array = NULL;
     325          26 :         sl_array_t *cmd_array = NULL;
     326          26 :         sl_array_t *attr_array = NULL;
     327          26 :         sl_cnids_t *cnids = NULL;
     328             :         ssize_t len;
     329             :         int ret;
     330             : 
     331          26 :         d = dalloc_new(mem_ctx);
     332          26 :         if (d == NULL) {
     333           0 :                 return NT_STATUS_NO_MEMORY;
     334             :         }
     335             : 
     336          26 :         array = dalloc_zero(d, sl_array_t);
     337          26 :         if (array == NULL) {
     338           0 :                 TALLOC_FREE(d);
     339           0 :                 return NT_STATUS_NO_MEMORY;
     340             :         }
     341             : 
     342          26 :         ret = dalloc_add(d, array, sl_array_t);
     343          26 :         if (ret != 0) {
     344           0 :                 TALLOC_FREE(d);
     345           0 :                 return NT_STATUS_NO_MEMORY;
     346             :         }
     347             : 
     348          26 :         cmd_array = dalloc_zero(d, sl_array_t);
     349          26 :         if (cmd_array == NULL) {
     350           0 :                 TALLOC_FREE(d);
     351           0 :                 return NT_STATUS_NO_MEMORY;
     352             :         }
     353             : 
     354          26 :         ret = dalloc_add(array, cmd_array, sl_array_t);
     355          26 :         if (ret != 0) {
     356           0 :                 TALLOC_FREE(d);
     357           0 :                 return NT_STATUS_NO_MEMORY;
     358             :         }
     359             : 
     360          26 :         ret = dalloc_stradd(cmd_array, "fetchAttributes:forOIDArray:context:");
     361          26 :         if (ret != 0) {
     362           0 :                 TALLOC_FREE(d);
     363           0 :                 return NT_STATUS_NO_MEMORY;
     364             :         }
     365             : 
     366          26 :         uint64var = talloc_zero_array(cmd_array, uint64_t, 2);
     367          26 :         if (uint64var == NULL) {
     368           0 :                 TALLOC_FREE(d);
     369           0 :                 return NT_STATUS_NO_MEMORY;
     370             :         }
     371             : 
     372          26 :         talloc_set_name(uint64var, "uint64_t *");
     373             : 
     374          26 :         uint64var[0] = ctx_id.id;
     375          26 :         uint64var[1] = 0;
     376             : 
     377          26 :         ret = dalloc_add(cmd_array, &uint64var[0], uint64_t *);
     378          26 :         if (ret != 0) {
     379           0 :                 TALLOC_FREE(d);
     380           0 :                 return NT_STATUS_NO_MEMORY;
     381             :         }
     382             : 
     383          26 :         attr_array = dalloc_zero(d, sl_array_t);
     384          26 :         if (attr_array == NULL) {
     385           0 :                 TALLOC_FREE(d);
     386           0 :                 return NT_STATUS_NO_MEMORY;
     387             :         }
     388             : 
     389          26 :         ret = dalloc_add(array, attr_array, sl_array_t);
     390          26 :         if (ret != 0) {
     391           0 :                 TALLOC_FREE(d);
     392           0 :                 return NT_STATUS_NO_MEMORY;
     393             :         }
     394             : 
     395          26 :         ret = dalloc_stradd(attr_array, "kMDItemPath");
     396          26 :         if (ret != 0) {
     397           0 :                 TALLOC_FREE(d);
     398           0 :                 return NT_STATUS_NO_MEMORY;
     399             :         }
     400             : 
     401             :         /* CNIDs */
     402          26 :         cnids = talloc_zero(array, sl_cnids_t);
     403          26 :         if (cnids == NULL) {
     404           0 :                 TALLOC_FREE(d);
     405           0 :                 return NT_STATUS_NO_MEMORY;
     406             :         }
     407             : 
     408          26 :         cnids->ca_cnids = dalloc_new(cnids);
     409          26 :         if (cnids->ca_cnids == NULL) {
     410           0 :                 TALLOC_FREE(d);
     411           0 :                 return NT_STATUS_NO_MEMORY;
     412             :         }
     413             : 
     414          26 :         cnids->ca_unkn1 = 0xadd;
     415          26 :         cnids->ca_context = 0x6b000020;
     416             : 
     417          26 :         ret = dalloc_add_copy(cnids->ca_cnids, &cnid, uint64_t);
     418          26 :         if (ret != 0) {
     419           0 :                 TALLOC_FREE(d);
     420           0 :                 return NT_STATUS_NO_MEMORY;
     421             :         }
     422             : 
     423          26 :         ret = dalloc_add(array, cnids, sl_cnids_t);
     424          26 :         if (ret != 0) {
     425           0 :                 TALLOC_FREE(d);
     426           0 :                 return NT_STATUS_NO_MEMORY;
     427             :         }
     428             : 
     429          26 :         blob->spotlight_blob = talloc_array(d,
     430             :                                             uint8_t,
     431             :                                             ctx->max_fragment_size);
     432          26 :         if (blob->spotlight_blob == NULL) {
     433           0 :                 TALLOC_FREE(d);
     434           0 :                 return NT_STATUS_NO_MEMORY;
     435             :         }
     436          26 :         blob->size = ctx->max_fragment_size;
     437             : 
     438          26 :         len = sl_pack(d, (char *)blob->spotlight_blob, blob->size);
     439          26 :         TALLOC_FREE(d);
     440          26 :         if (len == -1) {
     441           0 :                 return NT_STATUS_NO_MEMORY;
     442             :         }
     443             : 
     444          26 :         blob->length = len;
     445          26 :         blob->size = len;
     446          26 :         return NT_STATUS_OK;
     447             : }
     448             : 
     449           6 : NTSTATUS mdscli_blob_close_search(TALLOC_CTX *mem_ctx,
     450             :                                   struct mdscli_search_ctx *search,
     451             :                                   struct mdssvc_blob *blob)
     452             : {
     453           6 :         struct mdscli_ctx *ctx = search->mdscli_ctx;
     454           6 :         DALLOC_CTX *d = NULL;
     455           6 :         uint64_t *uint64p = NULL;
     456           6 :         sl_array_t *array = NULL;
     457           6 :         sl_array_t *cmd_array = NULL;
     458             :         ssize_t len;
     459             :         int ret;
     460             : 
     461           6 :         d = dalloc_new(mem_ctx);
     462           6 :         if (d == NULL) {
     463           0 :                 return NT_STATUS_NO_MEMORY;
     464             :         }
     465             : 
     466           6 :         array = dalloc_zero(d, sl_array_t);
     467           6 :         if (array == NULL) {
     468           0 :                 TALLOC_FREE(d);
     469           0 :                 return NT_STATUS_NO_MEMORY;
     470             :         }
     471             : 
     472           6 :         ret = dalloc_add(d, array, sl_array_t);
     473           6 :         if (ret != 0) {
     474           0 :                 TALLOC_FREE(d);
     475           0 :                 return NT_STATUS_NO_MEMORY;
     476             :         }
     477             : 
     478           6 :         cmd_array = dalloc_zero(d, sl_array_t);
     479           6 :         if (cmd_array == NULL) {
     480           0 :                 TALLOC_FREE(d);
     481           0 :                 return NT_STATUS_NO_MEMORY;
     482             :         }
     483             : 
     484           6 :         ret = dalloc_add(array, cmd_array, sl_array_t);
     485           6 :         if (ret != 0) {
     486           0 :                 TALLOC_FREE(d);
     487           0 :                 return NT_STATUS_NO_MEMORY;
     488             :         }
     489             : 
     490           6 :         ret = dalloc_stradd(cmd_array, "closeQueryForContext:");
     491           6 :         if (ret != 0) {
     492           0 :                 TALLOC_FREE(d);
     493           0 :                 return NT_STATUS_NO_MEMORY;
     494             :         }
     495             : 
     496           6 :         uint64p = talloc_zero_array(cmd_array, uint64_t, 2);
     497           6 :         if (uint64p == NULL) {
     498           0 :                 TALLOC_FREE(d);
     499           0 :                 return NT_STATUS_NO_MEMORY;
     500             :         }
     501             : 
     502           6 :         talloc_set_name(uint64p, "uint64_t *");
     503             : 
     504           6 :         uint64p[0] = search->ctx_id.id;
     505           6 :         uint64p[1] = search->ctx_id.connection;
     506             : 
     507           6 :         ret = dalloc_add(cmd_array, uint64p, uint64_t *);
     508           6 :         if (ret != 0) {
     509           0 :                 TALLOC_FREE(d);
     510           0 :                 return NT_STATUS_NO_MEMORY;
     511             :         }
     512             : 
     513           6 :         blob->spotlight_blob = talloc_array(d,
     514             :                                             uint8_t,
     515             :                                             ctx->max_fragment_size);
     516           6 :         if (blob->spotlight_blob == NULL) {
     517           0 :                 TALLOC_FREE(d);
     518           0 :                 return NT_STATUS_NO_MEMORY;
     519             :         }
     520           6 :         blob->size = ctx->max_fragment_size;
     521             : 
     522           6 :         len = sl_pack(d, (char *)blob->spotlight_blob, blob->size);
     523           6 :         TALLOC_FREE(d);
     524           6 :         if (len == -1) {
     525           0 :                 return NT_STATUS_NO_MEMORY;
     526             :         }
     527             : 
     528           6 :         blob->length = len;
     529           6 :         blob->size = len;
     530           6 :         return NT_STATUS_OK;
     531             : }

Generated by: LCOV version 1.13