LCOV - code coverage report
Current view: top level - source3/lib - string_replace.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 49 65 75.4 %
Date: 2021-09-23 10:06:22 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Unix SMB/CIFS implementation.
       3             :  *
       4             :  * Copyright (C) Volker Lendecke, 2005
       5             :  * Copyright (C) Aravind Srinivasan, 2009
       6             :  * Copyright (C) Guenter Kukkukk, 2013
       7             :  * Copyright (C) Ralph Boehme, 2017
       8             :  *
       9             :  * This program is free software; you can redistribute it and/or modify
      10             :  * it under the terms of the GNU General Public License as published by
      11             :  * the Free Software Foundation; either version 3 of the License, or
      12             :  * (at your option) any later version.
      13             :  *
      14             :  * This program is distributed in the hope that it will be useful,
      15             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      17             :  * GNU General Public License for more details.
      18             :  *
      19             :  * You should have received a copy of the GNU General Public License
      20             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      21             :  */
      22             : 
      23             : #include "includes.h"
      24             : #include "smbd/smbd.h"
      25             : #include "string_replace.h"
      26             : #include "lib/util/string_wrappers.h"
      27             : 
      28             : #define MAP_SIZE        0xFF
      29             : #define MAP_NUM         0x101 /* max unicode charval / MAP_SIZE */
      30             : #define T_OFFSET(_v_)   ((_v_ % MAP_SIZE))
      31             : #define T_START(_v_)    (((_v_ / MAP_SIZE) * MAP_SIZE))
      32             : #define T_PICK(_v_)     ((_v_ / MAP_SIZE))
      33             : 
      34             : struct char_mappings {
      35             :         smb_ucs2_t entry[MAP_SIZE][2];
      36             : };
      37             : 
      38         346 : static bool build_table(struct char_mappings **cmaps, int value)
      39             : {
      40             :         int i;
      41         346 :         int start = T_START(value);
      42             : 
      43         346 :         (*cmaps) = talloc_zero(NULL, struct char_mappings);
      44             : 
      45         346 :         if (!*cmaps)
      46           0 :                 return False;
      47             : 
      48       88576 :         for (i = 0; i < MAP_SIZE;i++) {
      49       88230 :                 (*cmaps)->entry[i][vfs_translate_to_unix] = start + i;
      50       88230 :                 (*cmaps)->entry[i][vfs_translate_to_windows] = start + i;
      51             :         }
      52             : 
      53         346 :         return True;
      54             : }
      55             : 
      56        4370 : static void set_tables(struct char_mappings **cmaps,
      57             :                        long unix_map,
      58             :                        long windows_map)
      59             : {
      60             :         int i;
      61             : 
      62             :         /* set unix -> windows */
      63        4370 :         i = T_OFFSET(unix_map);
      64        4370 :         cmaps[T_PICK(unix_map)]->entry[i][vfs_translate_to_windows] = windows_map;
      65             : 
      66             :         /* set windows -> unix */
      67        4370 :         i = T_OFFSET(windows_map);
      68        4370 :         cmaps[T_PICK(windows_map)]->entry[i][vfs_translate_to_unix] = unix_map;
      69        4370 : }
      70             : 
      71        4370 : static bool build_ranges(struct char_mappings **cmaps,
      72             :                          long unix_map,
      73             :                          long windows_map)
      74             : {
      75             : 
      76        4370 :         if (!cmaps[T_PICK(unix_map)]) {
      77         118 :                 if (!build_table(&cmaps[T_PICK(unix_map)], unix_map))
      78           0 :                         return False;
      79             :         }
      80             : 
      81        4370 :         if (!cmaps[T_PICK(windows_map)]) {
      82         228 :                 if (!build_table(&cmaps[T_PICK(windows_map)], windows_map))
      83           0 :                         return False;
      84             :         }
      85             : 
      86        4370 :         set_tables(cmaps, unix_map, windows_map);
      87             : 
      88        4370 :         return True;
      89             : }
      90             : 
      91         118 : struct char_mappings **string_replace_init_map(TALLOC_CTX *mem_ctx,
      92             :                                                const char **mappings)
      93             : {
      94             :         int i;
      95             :         char *tmp;
      96             :         fstring mapping;
      97             :         long unix_map, windows_map;
      98         118 :         struct char_mappings **cmaps = NULL;
      99             : 
     100         118 :         if (mappings == NULL) {
     101           0 :                 return NULL;
     102             :         }
     103             : 
     104         118 :         cmaps = talloc_zero_array(mem_ctx, struct char_mappings *, MAP_NUM);
     105         118 :         if (cmaps == NULL) {
     106           0 :                 return NULL;
     107             :         }
     108             : 
     109             :         /*
     110             :          * catia mappings are of the form :
     111             :          * UNIX char (in 0xnn hex) : WINDOWS char (in 0xnn hex)
     112             :          *
     113             :          * multiple mappings are comma separated in smb.conf
     114             :          */
     115             : 
     116        4488 :         for (i = 0; mappings[i]; i++) {
     117        4370 :                 fstrcpy(mapping, mappings[i]);
     118        4370 :                 unix_map = strtol(mapping, &tmp, 16);
     119        4370 :                 if (unix_map == 0 && errno == EINVAL) {
     120           0 :                         DEBUG(0, ("INVALID CATIA MAPPINGS - %s\n", mapping));
     121           0 :                         continue;
     122             :                 }
     123        4370 :                 windows_map = strtol(++tmp, NULL, 16);
     124        4370 :                 if (windows_map == 0 && errno == EINVAL) {
     125           0 :                         DEBUG(0, ("INVALID CATIA MAPPINGS - %s\n", mapping));
     126           0 :                         continue;
     127             :                 }
     128             : 
     129        4370 :                 if (!build_ranges(cmaps, unix_map, windows_map)) {
     130           0 :                         DEBUG(0, ("TABLE ERROR - CATIA MAPPINGS - %s\n", mapping));
     131           0 :                         continue;
     132             :                 }
     133             :         }
     134             : 
     135         118 :         return cmaps;
     136             : }
     137             : 
     138      424120 : NTSTATUS string_replace_allocate(connection_struct *conn,
     139             :                                  const char *name_in,
     140             :                                  struct char_mappings **cmaps,
     141             :                                  TALLOC_CTX *mem_ctx,
     142             :                                  char **mapped_name,
     143             :                                  enum vfs_translate_direction direction)
     144             : {
     145             :         static smb_ucs2_t *tmpbuf = NULL;
     146      424120 :         smb_ucs2_t *ptr = NULL;
     147      424120 :         struct char_mappings *map = NULL;
     148             :         size_t converted_size;
     149             :         bool ok;
     150             : 
     151      424120 :         ok = push_ucs2_talloc(talloc_tos(), &tmpbuf, name_in,
     152             :                               &converted_size);
     153      424120 :         if (!ok) {
     154           0 :                 return map_nt_error_from_unix(errno);
     155             :         }
     156             : 
     157     8006813 :         for (ptr = tmpbuf; *ptr; ptr++) {
     158     7582693 :                 if (*ptr == 0) {
     159           0 :                         break;
     160             :                 }
     161     7582693 :                 if (cmaps == NULL) {
     162           0 :                         continue;
     163             :                 }
     164     7582693 :                 map = cmaps[T_PICK((*ptr))];
     165     7582693 :                 if (map == NULL) {
     166             :                         /* nothing to do */
     167           0 :                         continue;
     168             :                 }
     169             : 
     170     7582693 :                 *ptr = map->entry[T_OFFSET((*ptr))][direction];
     171             :         }
     172             : 
     173      424120 :         ok = pull_ucs2_talloc(mem_ctx, mapped_name, tmpbuf,
     174             :                               &converted_size);
     175      424120 :         TALLOC_FREE(tmpbuf);
     176      424120 :         if (!ok) {
     177           0 :                 return map_nt_error_from_unix(errno);
     178             :         }
     179      424120 :         return NT_STATUS_OK;
     180             : }
     181             : 
     182             : const char *macos_string_replace_map =
     183             :         "0x01:0xf001,0x02:0xf002,0x03:0xf003,0x04:0xf004,"
     184             :         "0x05:0xf005,0x06:0xf006,0x07:0xf007,0x08:0xf008,"
     185             :         "0x09:0xf009,0x0a:0xf00a,0x0b:0xf00b,0x0c:0xf00c,"
     186             :         "0x0d:0xf00d,0x0e:0xf00e,0x0f:0xf00f,0x10:0xf010,"
     187             :         "0x11:0xf011,0x12:0xf012,0x13:0xf013,0x14:0xf014,"
     188             :         "0x15:0xf015,0x16:0xf016,0x17:0xf017,0x18:0xf018,"
     189             :         "0x19:0xf019,0x1a:0xf01a,0x1b:0xf01b,0x1c:0xf01c,"
     190             :         "0x1d:0xf01d,0x1e:0xf01e,0x1f:0xf01f,"
     191             :         "0x22:0xf020,0x2a:0xf021,0x3a:0xf022,0x3c:0xf023,"
     192             :         "0x3e:0xf024,0x3f:0xf025,0x5c:0xf026,0x7c:0xf027";

Generated by: LCOV version 1.13