LCOV - code coverage report
Current view: top level - librpc/wsp - wsp_util.c (source / functions) Hit Total Coverage
Test: coverage report for support-claim-type-attributes 6b5c566e Lines: 120 457 26.3 %
Date: 2023-11-21 12:31:41 Functions: 10 29 34.5 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *
       4             :  *  Window Search Service
       5             :  *
       6             :  *  Copyright (c) Noel Power
       7             :  *
       8             :  *  This program is free software; you can redistribute it and/or modify
       9             :  *  it under the terms of the GNU General Public License as published by
      10             :  *  the Free Software Foundation; either version 3 of the License, or
      11             :  *  (at your option) any later version.
      12             :  *
      13             :  *  This program is distributed in the hope that it will be useful,
      14             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  *  GNU General Public License for more details.
      17             :  *
      18             :  *  You should have received a copy of the GNU General Public License
      19             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      20             :  */
      21             : #include "includes.h"
      22             : #include "librpc/wsp/wsp_util.h"
      23             : #include "librpc/gen_ndr/wsp.h"
      24             : #include "librpc/gen_ndr/ndr_wsp.h"
      25             : #include "lib/util/strv_util.h"
      26             : #include "lib/util/strv.h"
      27             : #include "lib/util/util_str_hex.h"
      28             : #include "source3/param/param_proto.h"
      29             : #include "lib/util/dlinklist.h"
      30             : 
      31             : #define BUFFER_SIZE  1024000
      32             : struct guidtopropmap_holder
      33             : {
      34             :         struct guidtopropmap *guidtopropmaploc;
      35             : };
      36             : 
      37             : struct full_propset_info_list {
      38             :         struct full_propset_info_list *prev, *next;
      39             :         struct full_propset_info info;
      40             : };
      41             : 
      42             : struct guidtopropmap {
      43             :         struct guidtopropmap *prev, *next;
      44             :         struct GUID guid;
      45             :         struct full_propset_info_list *propset;
      46             : };
      47             : 
      48           0 : static struct guidtopropmap *find_guid_props(
      49             :                 struct guidtopropmap_holder *holder,
      50             :                 const struct GUID *guid)
      51             : {
      52           0 :         struct guidtopropmap *mapitem;
      53           0 :         for (mapitem = holder->guidtopropmaploc; mapitem; mapitem = mapitem->next) {
      54           0 :                 if (GUID_equal(guid, &mapitem->guid)) {
      55             :                         return mapitem;
      56             :                 }
      57             :         }
      58             :         return NULL;
      59             : }
      60             : 
      61           0 : static bool getbool(char *str)
      62             : {
      63           0 :         char *cpy = talloc_strdup(NULL, str);
      64           0 :         bool result;
      65             : 
      66           0 :         trim_string(cpy, " ", " ");
      67           0 :         if (strequal("TRUE", cpy)) {
      68             :                 result = true;
      69             :         } else {
      70           0 :                 result = false;
      71             :         }
      72           0 :         TALLOC_FREE(cpy);
      73           0 :         return result;
      74             : }
      75             : 
      76             : struct {
      77             :         const char* typename;
      78             :         uint16_t type;
      79             : } vtype_map[]  = {
      80             :         {"GUID", VT_CLSID},
      81             :         {"String", VT_LPWSTR},
      82             :         {"BString", VT_BSTR},
      83             :         {"Double", VT_R8},
      84             :         {"Buffer", VT_BLOB_OBJECT},
      85             :         {"Byte", VT_UI1},
      86             :         {"UInt64", VT_UI8},
      87             :         {"Int64", VT_I8},
      88             :         {"UInt32", VT_UI4},
      89             :         {"Int32", VT_I4},
      90             :         {"UInt16", VT_UI2},
      91             :         {"Int16", VT_I2},
      92             :         {"DateTime", VT_FILETIME},
      93             :         {"Boolean", VT_BOOL}
      94             : };
      95             : 
      96           0 : static uint16_t getvtype(char *str, bool isvec)
      97             : {
      98           0 :         uint16_t result = UINT16_MAX;
      99           0 :         int i;
     100           0 :         for (i = 0; i < ARRAY_SIZE(vtype_map); i++) {
     101           0 :                 if (strequal(vtype_map[i].typename, str)) {
     102           0 :                         result = vtype_map[i].type;
     103           0 :                         if (isvec) {
     104           0 :                                 result |= VT_VECTOR;
     105             :                         }
     106             :                         break;
     107             :                 }
     108             :         }
     109           0 :         return result;
     110             : }
     111             : 
     112           0 : static bool parse_csv_line(TALLOC_CTX *ctx,
     113             :                 char **csvs, size_t num_values,
     114             :                 struct guidtopropmap_holder *propmap_holder)
     115             : {
     116           0 :         struct guidtopropmap *mapitem = NULL;
     117           0 :         struct full_propset_info_list *item = NULL;
     118             : 
     119           0 :         char *guid_str = NULL;
     120           0 :         struct GUID guid;
     121           0 :         bool ok;
     122             : 
     123           0 :         item = talloc_zero(ctx,
     124             :                         struct full_propset_info_list);
     125           0 :         if (!item) {
     126             :                 return false;
     127             :         }
     128             : 
     129           0 :         item->info.in_inverted_index = false;
     130           0 :         item->info.is_column = true;
     131           0 :         item->info.can_col_be_indexed = true;
     132             : 
     133           0 :         if (strlen(csvs[1])) {
     134           0 :                 guid_str = talloc_strdup(ctx, csvs[1]);
     135             :         }
     136             : 
     137           0 :         if (!guid_str) {
     138           0 :                 DBG_ERR("out of memory\n");
     139           0 :                 return false;
     140             :         }
     141             : 
     142           0 :         if (!trim_string(guid_str, "{", "}")) {
     143             :                 return false;
     144             :         }
     145             : 
     146           0 :         if (strlen(csvs[0])) {
     147           0 :                 char *tmp = talloc_strdup(item, csvs[0]);
     148           0 :                 trim_string(tmp, " ", " ");
     149           0 :                 item->info.name = tmp;
     150             :         }
     151             : 
     152           0 :         if (strlen(csvs[2])) {
     153           0 :                 item->info.id = atoi(csvs[2]);
     154             :         }
     155             : 
     156           0 :         if (strlen(csvs[3])) {
     157           0 :                 item->info.in_inverted_index = getbool(csvs[3]);
     158             :         }
     159             : 
     160           0 :         if (strlen(csvs[4])) {
     161           0 :                 item->info.is_column = getbool(csvs[4]);
     162             :         }
     163             : 
     164           0 :         if (strlen(csvs[5])) {
     165           0 :                 item->info.can_col_be_indexed = getbool(csvs[5]);
     166             :         }
     167             : 
     168           0 :         if (strlen(csvs[6])) {
     169           0 :                 bool isvec = false;
     170           0 :                 uint16_t type;
     171           0 :                 if (strlen(csvs[0])) {
     172           0 :                         isvec = getbool(csvs[8]);
     173             :                 }
     174           0 :                 type = getvtype(csvs[6], isvec);
     175           0 :                 if (type == UINT16_MAX) {
     176           0 :                         DBG_ERR("failed to parse type\n");
     177           0 :                         return false;
     178             :                 }
     179           0 :                 item->info.vtype = type;
     180             :         }
     181             : 
     182           0 :         ok = parse_guid_string(guid_str, &guid);
     183           0 :         if (!ok) {
     184             :                 return false;
     185             :         }
     186             : 
     187           0 :         mapitem = find_guid_props(propmap_holder, &guid);
     188           0 :         if (!mapitem) {
     189           0 :                 mapitem = talloc_zero(propmap_holder,
     190             :                         struct guidtopropmap);
     191           0 :                 if (!mapitem) {
     192             :                         return false;
     193             :                 }
     194           0 :                 mapitem->guid = guid;
     195           0 :                 DLIST_ADD_END(propmap_holder->guidtopropmaploc, mapitem);
     196             :         }
     197             : 
     198           0 :         talloc_steal(mapitem, item);
     199           0 :         DLIST_ADD_END(mapitem->propset, item);
     200             :         return true;
     201             : }
     202             : 
     203           0 : static bool parse_properties_line(TALLOC_CTX *ctx,
     204             :                 const char* line,
     205             :                 struct guidtopropmap_holder *propmap_holder)
     206             : {
     207           0 :         int ret;
     208           0 :         int pos;
     209           0 :         char* strv = NULL;
     210           0 :         char** csv_line = NULL;
     211           0 :         char* t = NULL;
     212           0 :         size_t len;
     213             : 
     214           0 :         ret = strv_split(ctx,
     215             :                         &strv,
     216             :                         line,
     217             :                         ",");
     218             : 
     219           0 :         if (ret != 0) {
     220           0 :                 DBG_ERR("failed to split line\n");
     221           0 :                 return false;
     222             :         }
     223             : 
     224           0 :         len = strv_count(strv);
     225             : 
     226           0 :         if (len < 9) {
     227           0 :                 DBG_WARNING("skipping line as it doesn't have "
     228             :                             "enough fields\n");
     229           0 :                 return true;
     230             :         }
     231             : 
     232           0 :         csv_line = talloc_zero_array(ctx,
     233             :                         char *,
     234             :                         len);
     235             : 
     236           0 :         if (!csv_line) {
     237           0 :                 DBG_ERR("out of memory\n");
     238           0 :                 return false;
     239             :         }
     240           0 :         for (pos = 0; pos < talloc_array_length(csv_line); pos++) {
     241           0 :                 t = strv_next(strv, t);
     242             :                 /* the scraped property file can have a non ascii char */
     243           0 :                 if (strlen(t) == 1 && *t == 0xa0) {
     244             :                         csv_line[pos] = talloc_strdup(csv_line,
     245             :                                         "");
     246             :                 } else {
     247           0 :                         csv_line[pos] = talloc_strdup(csv_line,
     248             :                                                 t);
     249             :                 }
     250           0 :                 trim_string(csv_line[pos], " ", " ");
     251             :         }
     252             : 
     253           0 :         if (!parse_csv_line(csv_line, csv_line, len, propmap_holder)) {
     254           0 :                 DBG_ERR("failed to parse line\n");
     255           0 :                 TALLOC_FREE(csv_line);
     256           0 :                 return false;
     257             :         }
     258           0 :         TALLOC_FREE(csv_line);
     259           0 :         return true;
     260             : }
     261             : 
     262           0 : static bool parse_properties_csvfile(TALLOC_CTX *ctx,
     263             :                 struct guidtopropmap_holder *propmap_holder,
     264             :                 const char* filename)
     265             : {
     266           0 :         char **lines = NULL;
     267           0 :         int numlines;
     268           0 :         int i;
     269             : 
     270           0 :         if (filename == NULL || strlen(filename) == 0) {
     271             :                 return false;
     272             :         }
     273             : 
     274           0 :         lines = file_lines_load(filename,
     275             :                         &numlines,
     276             :                         BUFFER_SIZE,
     277             :                         ctx);
     278           0 :         if (!lines) {
     279           0 :                 DBG_ERR("Failed to load %s\n", filename);
     280           0 :                 return false;
     281             :         }
     282           0 :         DBG_ERR("parsed %d lines\n", numlines);
     283             : 
     284           0 :         for (i = 0; i < numlines; i++) {
     285           0 :                 TALLOC_CTX *line_ctx = talloc_init("line context");
     286           0 :                 if (!line_ctx) {
     287           0 :                         DBG_ERR("out of memory\n");
     288           0 :                         return false;
     289             :                 }
     290             : 
     291           0 :                 trim_string(lines[i], " ", " ");
     292           0 :                 if (lines[i][0] == '#') {
     293           0 :                         DBG_WARNING("skipping comment at line %d.\n)", i);
     294           0 :                         TALLOC_FREE(line_ctx);
     295           0 :                         continue;
     296             :                 }
     297             : 
     298           0 :                 if (!parse_properties_line(line_ctx,
     299             :                                         lines[i],
     300             :                                         propmap_holder)) {
     301           0 :                         DBG_ERR("Failed to parse line %d\n", i);
     302             :                 }
     303           0 :                 TALLOC_FREE(line_ctx);
     304             :         }
     305             :         return true;
     306             : }
     307             : 
     308           0 : static bool populate_map(struct guidtopropmap_holder *propmap_holder)
     309             : {
     310           0 :         const char * path = NULL;
     311           0 :         path = lp_wsp_property_file();
     312             : 
     313             :         /* first populate the map from property file */
     314           0 :         if (path) {
     315           0 :                 parse_properties_csvfile(propmap_holder, propmap_holder, path);
     316             :         }
     317             : 
     318           0 :         return true;
     319             : }
     320             : 
     321           0 : static struct guidtopropmap_holder *propmap(void)
     322             : {
     323           0 :         static struct guidtopropmap_holder *holder = NULL;
     324             : 
     325           0 :         if (!holder) {
     326           0 :                 holder = talloc_zero(NULL, struct guidtopropmap_holder);
     327           0 :                 if (holder) {
     328           0 :                         populate_map(holder);
     329             :                 }
     330             :         }
     331             : 
     332           0 :         return holder;
     333             : }
     334             : 
     335          46 : const struct full_propset_info *get_propset_info_with_guid(
     336             :                                                 const char *prop_name,
     337             :                                                 struct GUID *propset_guid)
     338             : {
     339          46 :         const struct full_propset_info *result = NULL;
     340          46 :         struct guidtopropmap_holder *holder = NULL;
     341          46 :         struct guidtopropmap *mapitem = NULL;
     342             : 
     343          46 :         size_t i;
     344          46 :         const struct full_guid_propset *guid_propset = NULL;
     345             : 
     346             :         /* search builtin props first */
     347        4561 :         for (i = 0; full_propertyset[i].prop_info != NULL; i++) {
     348             :                 const struct full_propset_info *item = NULL;
     349       14406 :                 guid_propset = &full_propertyset[i];
     350             :                 item = guid_propset->prop_info;
     351       14406 :                 while (item->id) {
     352        9891 :                         if (strequal(prop_name, item->name)) {
     353          46 :                                 *propset_guid = guid_propset->guid;
     354          46 :                                 result = item;
     355          46 :                                 break;
     356             :                         }
     357        9845 :                         item++;
     358             :                 }
     359        4561 :                 if (result) {
     360             :                         break;
     361             :                 }
     362             :         }
     363             : 
     364          46 :         if (result) {
     365             :                 return result;
     366             :         }
     367             : 
     368             :         /* if we didn't find a match in builtin props try the extra props */
     369           0 :         holder = propmap();
     370           0 :         for (mapitem = holder->guidtopropmaploc; mapitem;
     371           0 :                         mapitem = mapitem->next) {
     372           0 :                 struct full_propset_info_list *propitem;
     373           0 :                 for (propitem = mapitem->propset; propitem;
     374           0 :                                 propitem = propitem->next) {
     375           0 :                         if (strequal(prop_name, propitem->info.name)) {
     376           0 :                                 *propset_guid = mapitem->guid;
     377           0 :                                 result = &propitem->info;
     378           0 :                                 break;
     379             :                         }
     380             :                 }
     381             :         }
     382             :         return result;
     383             : }
     384             : 
     385           3 : const struct full_propset_info *get_prop_info(const char *prop_name)
     386             : {
     387           3 :         const struct full_propset_info *result = NULL;
     388           3 :         struct GUID guid;
     389           3 :         result = get_propset_info_with_guid(prop_name, &guid);
     390           3 :         return result;
     391             : }
     392             : 
     393          32 : char *prop_from_fullprop(TALLOC_CTX *ctx, struct wsp_cfullpropspec *fullprop)
     394             : {
     395          32 :         size_t i;
     396          32 :         char *result = NULL;
     397          32 :         const struct full_propset_info *item = NULL;
     398          32 :         const struct full_propset_info_list *prop_item = NULL;
     399          32 :         bool search_by_id = (fullprop->ulkind == PRSPEC_PROPID);
     400          32 :         struct guidtopropmap_holder *holder = NULL;
     401          32 :         struct guidtopropmap *mapitem = NULL;
     402             : 
     403             :         /* check builtin properties */
     404        3260 :         for (i = 0; full_propertyset[i].prop_info != NULL; i++) {
     405             :                 /* find propset */
     406        3260 :                 if (GUID_equal(&fullprop->guidpropset,
     407             :                                &full_propertyset[i].guid)) {
     408             :                         item = full_propertyset[i].prop_info;
     409             :                         break;
     410             :                 }
     411             :         }
     412          32 :         if (item) {
     413         227 :                 while (item->id) {
     414         227 :                         if (search_by_id) {
     415         227 :                                 if( fullprop->name_or_id.prspec == item->id) {
     416          32 :                                         result = talloc_strdup(ctx, item->name);
     417          32 :                                         break;
     418             :                                 }
     419           0 :                         } else if (strcmp(item->name,
     420             :                                         fullprop->name_or_id.propname.vstring)
     421             :                                         == 0) {
     422           0 :                                 result = talloc_strdup(ctx, item->name);
     423           0 :                                 break;
     424             :                         }
     425         195 :                         item++;
     426             :                 }
     427             :         }
     428             : 
     429             :         /* not found, search the extra props */
     430          32 :         if (!result) {
     431           0 :                 holder = propmap();
     432             : 
     433           0 :                 for (mapitem = holder->guidtopropmaploc; mapitem;
     434           0 :                                 mapitem = mapitem->next) {
     435           0 :                         if (GUID_equal(&fullprop->guidpropset,
     436           0 :                                        &mapitem->guid)) {
     437           0 :                                 prop_item = mapitem->propset;
     438           0 :                                 break;
     439             :                         }
     440             :                 }
     441             : 
     442           0 :                 for (;prop_item; prop_item = prop_item->next) {
     443           0 :                         if (search_by_id) {
     444           0 :                                 if(fullprop->name_or_id.prspec ==
     445           0 :                                                 prop_item->info.id) {
     446           0 :                                         result = talloc_strdup(ctx,
     447           0 :                                                         prop_item->info.name);
     448           0 :                                         break;
     449             :                                 }
     450           0 :                         } else if (strcmp(prop_item->info.name,
     451             :                                 fullprop->name_or_id.propname.vstring) == 0) {
     452           0 :                                         result = talloc_strdup(ctx,
     453             :                                                         prop_item->info.name);
     454           0 :                                         break;
     455             :                         }
     456             :                 }
     457             :         }
     458             : 
     459          32 :         if (!result) {
     460           0 :                 result = GUID_string(ctx, &fullprop->guidpropset);
     461             : 
     462           0 :                 if (search_by_id) {
     463           0 :                         result = talloc_asprintf(result, "%s/%d", result,
     464             :                                                  fullprop->name_or_id.prspec);
     465             :                 } else {
     466           0 :                         result = talloc_asprintf(result, "%s/%s", result,
     467             :                                         fullprop->name_or_id.propname.vstring);
     468             :                 }
     469             :         }
     470          32 :         return result;
     471             : }
     472             : 
     473           2 : const char *genmeth_to_string(uint32_t genmethod)
     474             : {
     475           2 :         const char *result = NULL;
     476           2 :         switch (genmethod) {
     477             :                 case 0:
     478             :                         result = "equals";
     479             :                         break;
     480           1 :                 case 1:
     481           1 :                         result = "starts with";
     482           1 :                         break;
     483           0 :                 case 2:
     484           0 :                         result = "matches inflection";
     485           0 :                         break;
     486           0 :                 default:
     487           0 :                         result = NULL;
     488           0 :                         break;
     489             :         }
     490           2 :         return result;
     491             : }
     492             : 
     493          32 : bool is_operator(struct wsp_crestriction *restriction) {
     494          32 :         bool result;
     495          32 :         switch(restriction->ultype) {
     496             :                 case RTAND:
     497             :                 case RTOR:
     498             :                 case RTNOT:
     499             :                         result = true;
     500             :                         break;
     501          32 :                 default:
     502          32 :                         result = false;
     503          32 :                         break;
     504             :         }
     505          32 :         return result;
     506             : }
     507             : 
     508          32 : const char *op_as_string(struct wsp_crestriction *restriction)
     509             : {
     510          32 :         const char *op = NULL;
     511          32 :         if (is_operator(restriction)) {
     512           0 :                 switch(restriction->ultype) {
     513           0 :                         case RTAND:
     514           0 :                                 op = " && ";
     515           0 :                                 break;
     516           0 :                         case RTOR:
     517           0 :                                 op = " || ";
     518           0 :                                 break;
     519           0 :                         case RTNOT:
     520           0 :                                 op = "!";
     521           0 :                                 break;
     522             :                 }
     523          32 :         } else if (restriction->ultype == RTPROPERTY) {
     524          30 :                 struct wsp_cpropertyrestriction *prop_restr =
     525             :                         &restriction->restriction.cpropertyrestriction;
     526          30 :                 switch (prop_restr->relop & 0XF) {
     527          15 :                         case PREQ:
     528          15 :                                 op = "=";
     529          15 :                                 break;
     530           2 :                         case PRNE:
     531           2 :                                 op = "!=";
     532           2 :                                 break;
     533           5 :                         case PRGE:
     534           5 :                                 op = ">=";
     535           5 :                                 break;
     536           2 :                         case PRLE:
     537           2 :                                 op = "<=";
     538           2 :                                 break;
     539           4 :                         case PRLT:
     540           4 :                                 op = "<";
     541           4 :                                 break;
     542           2 :                         case PRGT:
     543           2 :                                 op = ">";
     544           2 :                                 break;
     545             :                         default:
     546             :                                 break;
     547             :                 }
     548           2 :         } else if (restriction->ultype == RTCONTENT) {
     549           2 :                 struct wsp_ccontentrestriction *content = NULL;
     550           2 :                 content = &restriction->restriction.ccontentrestriction;
     551           2 :                 op = genmeth_to_string(content->ulgeneratemethod);
     552           0 :         } else if (restriction->ultype == RTNATLANGUAGE) {
     553           0 :                 op = "=";
     554             :         }
     555          32 :         return op;
     556             : }
     557             : 
     558           0 : struct wsp_cfullpropspec *get_full_prop(struct wsp_crestriction *restriction)
     559             : {
     560           0 :         struct wsp_cfullpropspec *result;
     561           0 :         switch (restriction->ultype) {
     562           0 :                 case RTPROPERTY:
     563           0 :                         result = &restriction->restriction.cpropertyrestriction.property;
     564           0 :                         break;
     565           0 :                 case RTCONTENT:
     566           0 :                         result = &restriction->restriction.ccontentrestriction.property;
     567           0 :                         break;
     568           0 :                 case RTNATLANGUAGE:
     569           0 :                         result = &restriction->restriction.cnatlanguagerestriction.property;
     570           0 :                         break;
     571             :                 default:
     572             :                         result = NULL;
     573             :                         break;
     574             :         }
     575           0 :         return result;
     576             : }
     577             : 
     578          30 : const char *variant_as_string(TALLOC_CTX *ctx,
     579             :                         struct wsp_cbasestoragevariant *value, bool quote)
     580             : {
     581          30 :         const char* result = NULL;
     582          30 :         switch(value->vtype) {
     583           0 :                 case VT_UI1:
     584           0 :                         result = talloc_asprintf(ctx, "%u",
     585           0 :                                                  value->vvalue.vt_ui1);
     586           0 :                         break;
     587           0 :                 case VT_INT:
     588             :                 case VT_I4:
     589           0 :                         result = talloc_asprintf(ctx, "%d",
     590             :                                                  value->vvalue.vt_i4);
     591           0 :                         break;
     592           0 :                 case VT_ERROR:
     593             :                 case VT_UINT:
     594             :                 case VT_UI4:
     595           0 :                         result = talloc_asprintf(ctx, "%u",
     596             :                                                  value->vvalue.vt_ui4);
     597           0 :                         break;
     598           0 :                 case VT_UI2:
     599             :                 case VT_I2:
     600           0 :                         result = talloc_asprintf(ctx, "%u",
     601           0 :                                                  value->vvalue.vt_ui2);
     602           0 :                         break;
     603           0 :                 case VT_BOOL:
     604           0 :                         result = talloc_asprintf(ctx, "%s",
     605           0 :                                         value->vvalue.vt_ui2 == 0xFFFF ?
     606             :                                                 "true" : "false");
     607           0 :                         break;
     608           0 :                 case VT_DATE:
     609             :                 case VT_FILETIME: {
     610           0 :                         NTTIME filetime = value->vvalue.vt_ui8;
     611           0 :                         time_t unixtime;
     612           0 :                         struct tm *tm = NULL;
     613           0 :                         char datestring[256];
     614           0 :                         unixtime = nt_time_to_unix(filetime);
     615           0 :                         tm = gmtime(&unixtime);
     616           0 :                         strftime(datestring, sizeof(datestring), "%FT%TZ", tm);
     617           0 :                         result = talloc_strdup(ctx, datestring);
     618           0 :                         break;
     619             :                 }
     620             :                 case VT_R4: {
     621           0 :                         float f;
     622           0 :                         if (sizeof(f) != sizeof(value->vvalue.vt_ui4)) {
     623             :                                 DBG_ERR("can't convert float\n");
     624             :                                 break;
     625             :                         }
     626           0 :                         memcpy((void*)&f,
     627           0 :                                 (void*)&value->vvalue.vt_ui4,
     628             :                                 sizeof(value->vvalue.vt_ui4));
     629           0 :                         result = talloc_asprintf(ctx, "%f",
     630             :                                                  f);
     631           0 :                         break;
     632             :                 }
     633             :                 case VT_R8: {
     634             :                         /* should this really be unsigned ? */
     635           0 :                         double dval;
     636           0 :                         if (sizeof(dval) != sizeof(value->vvalue.vt_i8)) {
     637             :                                 DBG_ERR("can't convert double\n");
     638             :                                 break;
     639             :                         }
     640           0 :                         memcpy((void*)&dval,
     641           0 :                                 (void*)&value->vvalue.vt_i8,
     642             :                                 sizeof(dval));
     643           0 :                         result = talloc_asprintf(ctx, "%f",
     644             :                                                  dval);
     645           0 :                         break;
     646             :                 }
     647           0 :                 case VT_I8: {
     648           0 :                         result = talloc_asprintf(ctx, "%" PRIi64,
     649             :                                                  value->vvalue.vt_i8);
     650           0 :                         break;
     651             :                 }
     652          17 :                 case VT_UI8: {
     653          17 :                         result = talloc_asprintf(ctx, "%" PRIu64,
     654             :                                                  value->vvalue.vt_ui8);
     655          17 :                         break;
     656             :                 }
     657           4 :                 case VT_LPWSTR:
     658           4 :                         result = talloc_asprintf(ctx, "%s%s%s",
     659             :                                                 quote ? "\'" : "",
     660             :                                                 value->vvalue.vt_lpwstr.value,
     661             :                                                 quote ? "\'" : "");
     662           4 :                         break;
     663           9 :                 case VT_LPWSTR | VT_VECTOR: {
     664           9 :                         int num_elems =
     665           9 :                         value->vvalue.vt_lpwstr_v.vvector_elements;
     666           9 :                         int i;
     667          18 :                         for(i = 0; i < num_elems; i++) {
     668           9 :                                 struct vt_lpwstr_vec *vec;
     669           9 :                                 const char *val;
     670           9 :                                 vec = &value->vvalue.vt_lpwstr_v;
     671           9 :                                 val = vec->vvector_data[i].value;
     672           9 :                                 result =
     673          27 :                                         talloc_asprintf(ctx,
     674             :                                                         "%s%s%s%s%s",
     675             :                                                         result ? result : "",
     676             :                                                         i ? "," : "",
     677             :                                                         quote ? "\'" : "",
     678             :                                                         val,
     679             :                                                         quote ? "\'" : "");
     680             :                         }
     681             :                         break;
     682             :                 }
     683           0 :                 default:
     684           0 :                         DBG_INFO("can't represent unsupported vtype 0x%x as string\n",
     685             :                                 value->vtype);
     686             :                         break;
     687             :         }
     688          30 :         return result;
     689             : }
     690             : 
     691             : static const struct {
     692             :         uint32_t id;
     693             :         const char *name;
     694             : } typename_map[] = {
     695             :         {VT_EMPTY, "Empty"},
     696             :         {VT_NULL, "Null"},
     697             :         {VT_I2, "VT_I2"},
     698             :         {VT_I4, "VT_I4"},
     699             :         {VT_I4, "VT_I4"},
     700             :         {VT_R4, "VT_R4"},
     701             :         {VT_R8, "VT_R8"},
     702             :         {VT_CY, "VT_CY"},
     703             :         {VT_DATE, "VT_DATE"},
     704             :         {VT_BSTR, "VT_BSTR"},
     705             :         {VT_I1, "VT_I1"},
     706             :         {VT_UI1, "VT_UI1"},
     707             :         {VT_UI2, "VT_UI2"},
     708             :         {VT_UI4, "VT_UI4"},
     709             :         {VT_I8, "VT_I8"},
     710             :         {VT_UI8, "VT_UI8"},
     711             :         {VT_INT, "VT_INT"},
     712             :         {VT_UINT, "VT_UINT"},
     713             :         {VT_ERROR, "VT_ERROR"},
     714             :         {VT_BOOL, "VT_BOOL"},
     715             :         {VT_VARIANT, "VT_VARIANT"},
     716             :         {VT_DECIMAL, "VT_DECIMAL"},
     717             :         {VT_FILETIME, "VT_FILETIME"},
     718             :         {VT_BLOB, "VT_BLOB"},
     719             :         {VT_BLOB_OBJECT, "VT_BLOB_OBJECT"},
     720             :         {VT_CLSID, "VT_CLSID"},
     721             :         {VT_LPSTR, "VT_LPSTR"},
     722             :         {VT_LPWSTR, "VT_LPWSTR"},
     723             :         {VT_COMPRESSED_LPWSTR, "VT_COMPRESSED_LPWSTR"},
     724             : };
     725             : 
     726           0 : const char *get_vtype_name(uint32_t type)
     727             : {
     728           0 :         const char *type_name = NULL;
     729           0 :         static char result_buf[255];
     730           0 :         int i;
     731           0 :         uint32_t temp = type & ~(VT_VECTOR | VT_ARRAY);
     732           0 :         for (i = 0; i < ARRAY_SIZE(typename_map); i++) {
     733           0 :                 if (temp == typename_map[i].id) {
     734           0 :                         type_name = typename_map[i].name;
     735           0 :                         break;
     736             :                 }
     737             :         }
     738           0 :         if (type & VT_VECTOR) {
     739           0 :                 snprintf(result_buf, sizeof(result_buf), "Vector | %s", type_name);
     740           0 :         } else if (type & VT_ARRAY) {
     741           0 :                 snprintf(result_buf, sizeof(result_buf), "Array | %s", type_name);
     742             :         } else {
     743           0 :                 snprintf(result_buf, sizeof(result_buf), "%s", type_name);
     744             :         }
     745           0 :         return result_buf;
     746             : }
     747             : 
     748           0 : bool is_variable_size(uint16_t vtype)
     749             : {
     750           0 :         bool result;
     751           0 :         switch(vtype) {
     752             :                 case VT_LPWSTR:
     753             :                 case VT_COMPRESSED_LPWSTR:
     754             :                 case VT_BSTR:
     755             :                 case VT_BLOB:
     756             :                 case VT_BLOB_OBJECT:
     757             :                 case VT_VARIANT:
     758             :                         result = true;
     759             :                         break;
     760           0 :                 default:
     761           0 :                         result = false;
     762           0 :                         break;
     763             :         }
     764           0 :         return result;
     765             : }
     766             : 
     767           0 : const char *get_store_status(uint8_t status_byte)
     768             : {
     769           0 :         const char *result;
     770           0 :         switch(status_byte) {
     771             :                 case 0:
     772             :                         result = "StoreStatusOk";
     773             :                         break;
     774           0 :                 case 1:
     775           0 :                         result = "StoreStatusDeferred";
     776           0 :                         break;
     777           0 :                 case 2:
     778           0 :                         result = "StoreStatusNull";
     779           0 :                         break;
     780           0 :                 default:
     781           0 :                         result = "Unknown Status";
     782           0 :                         break;
     783             :         }
     784           0 :         return result;
     785             : }
     786             : 
     787           4 : void set_variant_lpwstr(TALLOC_CTX *ctx,
     788             :                         struct wsp_cbasestoragevariant *vvalue,
     789             :                         const char *string_val)
     790             : {
     791           4 :         vvalue->vtype = VT_LPWSTR;
     792           4 :         vvalue->vvalue.vt_lpwstr.value = talloc_strdup(ctx, string_val);
     793           4 : }
     794             : 
     795           0 : void set_variant_i4(TALLOC_CTX *ctx,
     796             :                     struct wsp_cbasestoragevariant *vvalue,
     797             :                     uint32_t val)
     798             : {
     799           0 :         vvalue->vtype = VT_I4;
     800           0 :         vvalue->vvalue.vt_i4 = val;
     801           0 : }
     802             : 
     803           0 : void set_variant_vt_bool(TALLOC_CTX *ctx,
     804             :                         struct wsp_cbasestoragevariant *variant,
     805             :                         bool bval)
     806             : {
     807           0 :         variant->vtype = VT_BOOL;
     808           0 :         variant->vvalue.vt_bool = bval;
     809           0 : }
     810             : 
     811           0 : static void fill_int32_vec(TALLOC_CTX* ctx,
     812             :                             int32_t **pdest,
     813             :                             int32_t* ivector, uint32_t elems)
     814             : {
     815           0 :         int i;
     816           0 :         int32_t *dest = talloc_zero_array(ctx, int32_t, elems);
     817           0 :         for ( i = 0; i < elems; i++ ) {
     818           0 :                 dest[ i ] = ivector[ i ];
     819             :         }
     820           0 :         *pdest = dest;
     821           0 : }
     822             : 
     823           0 : void set_variant_i4_vector(TALLOC_CTX *ctx,
     824             :                            struct wsp_cbasestoragevariant *variant,
     825             :                            int32_t* ivector, uint32_t elems)
     826             : {
     827           0 :         variant->vtype = VT_VECTOR | VT_I4;
     828           0 :         variant->vvalue.vt_i4_vec.vvector_elements = elems;
     829           0 :         fill_int32_vec(ctx, &variant->vvalue.vt_i4_vec.vvector_data, ivector, elems);
     830           0 : }
     831             : 
     832           9 : static void fill_string_vec(TALLOC_CTX* ctx,
     833             :                                 struct wsp_cbasestoragevariant *variant,
     834             :                                 const char **strings, uint16_t elems)
     835             : {
     836           9 :         int i;
     837           9 :         variant->vvalue.vt_lpwstr_v.vvector_elements = elems;
     838           9 :         variant->vvalue.vt_lpwstr_v.vvector_data = talloc_zero_array(ctx,
     839             :                                                         struct vt_lpwstr,
     840             :                                                         elems);
     841             : 
     842          18 :         for( i = 0; i < elems; i++ ) {
     843           9 :                 variant->vvalue.vt_lpwstr_v.vvector_data[ i ].value = talloc_strdup(ctx, strings[ i ]);
     844             :         }
     845           9 : }
     846             : 
     847           0 : static void fill_bstr_vec(TALLOC_CTX *ctx,
     848             :                   struct vt_bstr **pvector,
     849             :                   const char **strings, uint16_t elems)
     850             : {
     851           0 :         int i;
     852           0 :         struct vt_bstr *vdata = talloc_zero_array(ctx, struct vt_bstr, elems);
     853             : 
     854           0 :         for( i = 0; i < elems; i++ ) {
     855           0 :                 vdata [ i ].value = talloc_strdup(ctx, strings[ i ]);
     856             :         }
     857           0 :         *pvector = vdata;
     858           0 : }
     859             : 
     860           0 : void set_variant_bstr(TALLOC_CTX *ctx, struct wsp_cbasestoragevariant *variant,
     861             :                         const char *string_val)
     862             : {
     863           0 :         variant->vtype = VT_BSTR;
     864           0 :         variant->vvalue.vt_bstr.value = talloc_strdup(ctx, string_val);
     865           0 : }
     866             : 
     867           9 : void set_variant_lpwstr_vector(TALLOC_CTX *ctx,
     868             :                               struct wsp_cbasestoragevariant *variant,
     869             :                               const char **string_vals, uint32_t elems)
     870             : {
     871           9 :         variant->vtype = VT_LPWSTR | VT_VECTOR;
     872           9 :         fill_string_vec(ctx, variant, string_vals, elems);
     873           9 : }
     874             : 
     875           0 : void set_variant_array_bstr(TALLOC_CTX *ctx,
     876             :                            struct wsp_cbasestoragevariant *variant,
     877             :                            const char **string_vals, uint16_t elems)
     878             : {
     879           0 :         variant->vtype = VT_BSTR | VT_ARRAY;
     880           0 :         variant->vvalue.vt_bstr_array.cdims = 1;
     881           0 :         variant->vvalue.vt_bstr_array.ffeatures = 0;
     882             : 
     883           0 :         variant->vvalue.vt_bstr_array.rgsabound =
     884           0 :                 talloc_zero_array(ctx, struct safearraybound, 1);
     885             : 
     886           0 :         variant->vvalue.vt_bstr_array.rgsabound[0].celements = elems;
     887           0 :         variant->vvalue.vt_bstr_array.rgsabound[0].ilbound = 0;
     888           0 :         variant->vvalue.vt_bstr_array.cbelements = 0;
     889           0 :         fill_bstr_vec(ctx, &variant->vvalue.vt_bstr_array.vdata,
     890             :                       string_vals, elems);
     891             :         /*
     892             :          * if cbelements is the num bytes per elem it kindof means each
     893             :          * string in the array must be the same size ?
     894             :          */
     895             : 
     896           0 :         if (elems >0) {
     897           0 :                 variant->vvalue.vt_bstr_array.cbelements =
     898           0 :                         strlen_m_term(variant->vvalue.vt_bstr_array.vdata[0].value)*2;
     899             :         }
     900           0 : }
     901             : 
     902             : /* create single dim array of vt_i4 */
     903           0 : void set_variant_array_i4(TALLOC_CTX *ctx,
     904             :                          struct wsp_cbasestoragevariant *variant,
     905             :                          int32_t *vals, uint16_t elems)
     906             : {
     907             :         /* #TODO see if we can combine with other set_variant_array methods */
     908           0 :         variant->vtype = VT_I4 | VT_ARRAY;
     909           0 :         variant->vvalue.vt_i4_array.cdims = 1;
     910           0 :         variant->vvalue.vt_i4_array.ffeatures = 0;
     911             : 
     912           0 :         variant->vvalue.vt_i4_array.rgsabound =
     913           0 :                 talloc_zero_array(ctx, struct safearraybound, 1);
     914             : 
     915           0 :         variant->vvalue.vt_i4_array.rgsabound[0].celements = elems;
     916           0 :         variant->vvalue.vt_i4_array.rgsabound[0].ilbound = 0;
     917           0 :         variant->vvalue.vt_i4_array.cbelements = sizeof(uint32_t);
     918           0 :         fill_int32_vec(ctx, &variant->vvalue.vt_i4_array.vdata, vals, elems);
     919           0 : }

Generated by: LCOV version 1.14