LCOV - code coverage report
Current view: top level - source3/registry - reg_parse_internal.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 91 182 50.0 %
Date: 2021-09-23 10:06:22 Functions: 7 9 77.8 %

          Line data    Source code
       1             : /*
       2             :  * Unix SMB/CIFS implementation.
       3             :  *
       4             :  * Registry helper routines
       5             :  *
       6             :  * Copyright (C) Gregor Beck 2010
       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             : /**
      22             :  * @file   reg_parse_internal.h
      23             :  * @author Gregor Beck <gb@sernet.de>
      24             :  * @date   Sep 2010
      25             :  * @brief
      26             :  */
      27             : 
      28             : #include "reg_parse_internal.h"
      29             : #include "cbuf.h"
      30             : #include "srprs.h"
      31             : #include "registry.h"
      32             : 
      33        3366 : size_t iconvert_talloc(const void* ctx,
      34             :                        smb_iconv_t cd,
      35             :                        const char* src, size_t srclen,
      36             :                        char** pdst)
      37             : {
      38             :         size_t dstlen, ret;
      39             :         size_t obytes, ibytes;
      40             :         char *optr, *dst, *tmp;
      41             :         const char* iptr;
      42             : 
      43        3366 :         if (cd == NULL || cd == ((smb_iconv_t)-1)) {
      44           0 :                 return -1;
      45             :         }
      46             : 
      47        3366 :         dst = *pdst;
      48             : 
      49        3366 :         if (dst == NULL) {
      50             :                 /*
      51             :                  * Allocate an extra two bytes for the
      52             :                  * terminating zero.
      53             :                  */
      54        3366 :                 dstlen = srclen + 2;
      55        3366 :                 dst = (char *)talloc_size(ctx, dstlen);
      56        3366 :                 if (dst == NULL) {
      57           0 :                         DEBUG(0,("iconver_talloc no mem\n"));
      58           0 :                         return -1;
      59             :                 }
      60             :         } else {
      61           0 :                 dstlen = talloc_get_size(dst);
      62             :         }
      63        3366 : convert:
      64        3366 :         iptr   = src;
      65        3366 :         ibytes = srclen;
      66        3366 :         optr   = dst;
      67        3366 :         obytes = dstlen-2;
      68             : 
      69        3366 :         ret = smb_iconv(cd, &iptr, &ibytes, &optr, &obytes);
      70             : 
      71        3366 :         if(ret == -1) {
      72           0 :                 const char *reason="unknown error";
      73           0 :                 switch(errno) {
      74           0 :                 case EINVAL:
      75           0 :                         reason="Incomplete multibyte sequence";
      76           0 :                         break;
      77           0 :                 case E2BIG:
      78           0 :                         dstlen = 2*dstlen + 2;
      79           0 :                         tmp    = talloc_realloc(ctx, dst, char, dstlen);
      80           0 :                         if (tmp == NULL) {
      81           0 :                                 reason="talloc_realloc failed";
      82           0 :                                 break;
      83             :                         }
      84           0 :                         dst = tmp;
      85           0 :                         goto convert;
      86           0 :                 case EILSEQ:
      87           0 :                         reason="Illegal multibyte sequence";
      88           0 :                         break;
      89             :                 }
      90           0 :                 DEBUG(0,("Conversion error: %s(%.80s) %li\n", reason, iptr,
      91             :                          (long int)(iptr-src)));
      92           0 :                 talloc_free(dst);
      93           0 :                 return -1;
      94             :         }
      95             : 
      96        3366 :         dstlen = (dstlen-2) - obytes;
      97             : 
      98        3366 :         SSVAL(dst, dstlen, 0);
      99             : 
     100        3366 :         *pdst = dst;
     101        3366 :         return dstlen;
     102             : }
     103             : 
     104             : #ifndef HKEY_CURRENT_CONFIG
     105             : #define HKEY_CURRENT_CONFIG             0x80000005
     106             : #endif
     107             : #ifndef HKEY_DYN_DATA
     108             : #define HKEY_DYN_DATA                   0x80000006
     109             : #endif
     110             : #ifndef HKEY_PERFORMANCE_TEXT
     111             : #define HKEY_PERFORMANCE_TEXT           0x80000050
     112             : #endif
     113             : #ifndef HKEY_PERFORMANCE_NLSTEXT
     114             : #define HKEY_PERFORMANCE_NLSTEXT        0x80000060
     115             : #endif
     116             : 
     117             : #define HIVE_INFO_ENTRY(SHORT,LONG)             \
     118             : const struct hive_info HIVE_INFO_##SHORT = {    \
     119             :         .handle = LONG,                         \
     120             :         .short_name = #SHORT,                   \
     121             :         .short_name_len = sizeof(#SHORT)-1,     \
     122             :         .long_name = #LONG,                     \
     123             :         .long_name_len = sizeof(#LONG)-1,       \
     124             : }
     125             : 
     126             : HIVE_INFO_ENTRY(HKLM, HKEY_LOCAL_MACHINE);
     127             : HIVE_INFO_ENTRY(HKCU, HKEY_CURRENT_USER);
     128             : HIVE_INFO_ENTRY(HKCR, HKEY_CLASSES_ROOT);
     129             : HIVE_INFO_ENTRY(HKU , HKEY_USERS);
     130             : HIVE_INFO_ENTRY(HKCC, HKEY_CURRENT_CONFIG);
     131             : HIVE_INFO_ENTRY(HKDD, HKEY_DYN_DATA);
     132             : HIVE_INFO_ENTRY(HKPD, HKEY_PERFORMANCE_DATA);
     133             : HIVE_INFO_ENTRY(HKPT, HKEY_PERFORMANCE_TEXT);
     134             : HIVE_INFO_ENTRY(HKPN, HKEY_PERFORMANCE_NLSTEXT);
     135             : #undef HIVE_INFO_ENTRY
     136             : 
     137             : const struct hive_info* HIVE_INFO[] = {
     138             :         &HIVE_INFO_HKLM, &HIVE_INFO_HKCU, &HIVE_INFO_HKCR, &HIVE_INFO_HKU,
     139             :         &HIVE_INFO_HKCC, &HIVE_INFO_HKDD, &HIVE_INFO_HKPD, &HIVE_INFO_HKPT,
     140             :         &HIVE_INFO_HKPN, NULL
     141             : };
     142             : 
     143             : #define TOINT(A,B) ((int)(A) << 8) + (int)(B)
     144             : 
     145       48188 : bool srprs_hive(const char** ptr, const struct hive_info** result)
     146             : {
     147       48188 :         const char* str = *ptr;
     148       48188 :         const struct hive_info* info = NULL;
     149       48188 :         bool long_hive = false;
     150             : 
     151       48188 :         if ((toupper(str[0]) != 'H') || (toupper(str[1]) != 'K')
     152       47822 :             || (str[2] == '\0') )
     153             :         {
     154         366 :                 return false;
     155             :         }
     156             : 
     157       47822 :         switch ( TOINT(toupper(str[2]), toupper(str[3])) ) {
     158           0 :         case TOINT('E', 'Y'):
     159           0 :                 if (str[4] == '_') {
     160             :                         int i;
     161           0 :                         for (i=0; (info = HIVE_INFO[i]); i++) {
     162           0 :                                 if (strncmp(&str[5], &info->long_name[5],
     163           0 :                                             info->long_name_len-5) == 0)
     164             :                                 {
     165           0 :                                         long_hive = true;
     166           0 :                                         break;
     167             :                                 }
     168             :                         }
     169             :                 }
     170           0 :                 break;
     171       47271 :         case TOINT('L', 'M'):
     172       47271 :                 info = &HIVE_INFO_HKLM;
     173       47271 :                 break;
     174         277 :         case TOINT('C', 'U'):
     175         277 :                 info = &HIVE_INFO_HKCU;
     176         277 :                 break;
     177         101 :         case TOINT('C', 'R'):
     178         101 :                 info = &HIVE_INFO_HKCR;
     179         101 :                 break;
     180           0 :         case TOINT('C', 'C'):
     181           0 :                 info = &HIVE_INFO_HKCC;
     182           0 :                 break;
     183           0 :         case TOINT('D', 'D'):
     184           0 :                 info = &HIVE_INFO_HKDD;
     185           0 :                 break;
     186          34 :         case TOINT('P', 'D'):
     187          34 :                 info = &HIVE_INFO_HKPD;
     188          34 :                 break;
     189          34 :         case TOINT('P', 'T'):
     190          34 :                 info = &HIVE_INFO_HKPT;
     191          34 :                 break;
     192           0 :         case TOINT('P', 'N'):
     193           0 :                 info = &HIVE_INFO_HKPN;
     194           0 :                 break;
     195         101 :         default:
     196         101 :                 if (toupper(str[2]) == 'U') {
     197         101 :                         info = &HIVE_INFO_HKU;
     198             :                 }
     199         101 :                 break;
     200             :         }
     201       47822 :         if (info != NULL) {
     202       47822 :                 if (result != NULL) {
     203       45560 :                         *result = info;
     204             :                 }
     205       47822 :                 *ptr += long_hive ? info->long_name_len : info->short_name_len;
     206       47822 :                 return true;
     207             :         }
     208           0 :         return false;
     209             : }
     210             : 
     211       45562 : const struct hive_info* hive_info(const char* name)
     212             : {
     213       45562 :         const struct hive_info* info = NULL;
     214       45562 :         srprs_hive(&name, &info);
     215       45562 :         return info;
     216             : }
     217             : 
     218         138 : const char *smbreg_get_charset(const char *c)
     219             : {
     220         138 :         if (strcmp(c, "dos") == 0) {
     221           0 :                 return lp_dos_charset();
     222         138 :         } else if (strcmp(c, "unix") == 0) {
     223          62 :                 return lp_unix_charset();
     224             :         } else {
     225          76 :                 return c;
     226             :         }
     227             : }
     228             : 
     229          82 : bool set_iconv(smb_iconv_t* t, const char* to, const char* from)
     230             : {
     231          82 :         smb_iconv_t cd = (smb_iconv_t)-1;
     232             : 
     233          82 :         if (to && from) {
     234          62 :                 to   = smbreg_get_charset(to);
     235          62 :                 from = smbreg_get_charset(from);
     236          62 :                 cd   = smb_iconv_open(to, from);
     237          62 :                 if (cd == ((smb_iconv_t)-1)) {
     238           0 :                         return false;
     239             :                 }
     240             :         }
     241          82 :         if ((*t != (smb_iconv_t)NULL) && (*t != (smb_iconv_t)-1)) {
     242          34 :                 smb_iconv_close(*t);
     243             :         }
     244          82 :         *t = cd;
     245          82 :         return true;
     246             : }
     247             : 
     248             : /**
     249             :  * Parse option string
     250             :  * @param[in,out] ptr parse position
     251             :  * @param[in] mem_ctx talloc context
     252             :  * @param[out] name ptr 2 value
     253             :  * @param[out] value ptr 2 value
     254             :  * @return true on success
     255             :  */
     256           0 : bool srprs_option(const char** ptr, const void* mem_ctx, char** name, char** value)
     257             : {
     258           0 :         const char* pos = *ptr;
     259           0 :         void* ctx = talloc_new(mem_ctx);
     260             : 
     261           0 :         cbuf* key = cbuf_new(ctx);
     262           0 :         cbuf* val = NULL;
     263             : 
     264           0 :         while(srprs_charsetinv(&pos, ",= \t\n\r", key))
     265             :                 ;
     266           0 :         if (pos == *ptr) {
     267           0 :                 talloc_free(ctx);
     268           0 :                 return false;
     269             :         }
     270             : 
     271           0 :         if (name != NULL) {
     272           0 :                 *name = talloc_steal(mem_ctx, cbuf_gets(key, 0));
     273             :         }
     274             : 
     275           0 :         if (*pos == '=') {
     276           0 :                 val = cbuf_new(ctx);
     277           0 :                 pos++;
     278           0 :                 if (!srprs_quoted_string(ptr, val, NULL)) {
     279           0 :                         while(srprs_charsetinv(&pos, ", \t\n\r", val))
     280             :                                 ;
     281             :                 }
     282           0 :                 if (value != NULL) {
     283           0 :                         *value = talloc_steal(mem_ctx, cbuf_gets(val, 0));
     284             :                 }
     285             :         } else {
     286           0 :                 if (value != NULL) {
     287           0 :                         *value = NULL;
     288             :                 }
     289             :         }
     290             : 
     291           0 :         while(srprs_char(&pos, ','))
     292             :                 ;
     293             : 
     294           0 :         *ptr = pos;
     295           0 :         return true;
     296             : }
     297             : 
     298             : #define CH_INVALID ((charset_t)-1)
     299             : static const struct {
     300             :         const char* const name;
     301             :         charset_t ctype;
     302             :         int  len;
     303             :         uint8_t seq[4];
     304             : } BOM[] = {
     305             :         {"UTF-8",    CH_UTF8,    3, {0xEF, 0xBB, 0xBF}},
     306             :         {"UTF-32LE", CH_INVALID, 4, {0xFF, 0xFE, 0x00, 0x00}},
     307             :         {"UTF-16LE", CH_UTF16LE, 2, {0xFF, 0xFE}},
     308             :         {"UTF-16BE", CH_UTF16BE, 2, {0xFE, 0xFF}},
     309             :         {"UTF-32BE", CH_INVALID, 4, {0x00, 0x00, 0xFE, 0xFF}},
     310             :         { .name = NULL }
     311             : };
     312             : 
     313          10 : bool srprs_bom(const char** ptr, const char** name, charset_t* ctype)
     314             : {
     315             :         int i;
     316          54 :         for (i=0; BOM[i].name; i++) {
     317          46 :                 if (memcmp(*ptr, BOM[i].seq, BOM[i].len) == 0) {
     318           2 :                         break;
     319             :                 }
     320             :         }
     321             : 
     322          10 :         if (BOM[i].name != NULL) {
     323           2 :                 DEBUG(0, ("Found Byte Order Mark for : %s\n", BOM[i].name));
     324             : 
     325           2 :                 if (name != NULL) {
     326           2 :                         *name  = BOM[i].name;
     327             :                 }
     328             : 
     329           2 :                 if (ctype != NULL) {
     330           0 :                         *ctype = BOM[i].ctype;
     331             :                 }
     332             : 
     333           2 :                 *ptr  += BOM[i].len;
     334             : 
     335           2 :                 return true;
     336             :         }
     337           8 :         return false;
     338             : }
     339             : 
     340           0 : int write_bom(FILE* file, const char* charset, charset_t ctype)
     341             : {
     342             :         int i;
     343           0 :         if ( charset == NULL ) {
     344           0 :                 for (i=0; BOM[i].name; i++) {
     345           0 :                         if (BOM[i].ctype == ctype) {
     346           0 :                                 return fwrite(BOM[i].seq, 1, BOM[i].len, file);
     347             :                         }
     348             :                 }
     349           0 :                 DEBUG(0, ("No Byte Order Mark for charset_t: %u\n", (unsigned)ctype));
     350             :         } else {
     351           0 :                 for (i=0; BOM[i].name; i++) {
     352           0 :                         if (strcasecmp_m(BOM[i].name, charset) == 0) {
     353           0 :                                 return fwrite(BOM[i].seq, 1, BOM[i].len, file);
     354             :                         }
     355             :                 }
     356           0 :                 DEBUG(0, ("No Byte Order Mark for charset_t: %s\n", charset));
     357             :         }
     358           0 :         return 0;
     359             : }
     360             : 
     361             : 
     362        3404 : int cbuf_puts_case(cbuf* s, const char* str, size_t len, enum fmt_case fmt)
     363             : {
     364        3404 :         size_t pos = cbuf_getpos(s);
     365        3404 :         int ret = cbuf_puts(s, str, len);
     366        3404 :         char* ptr = cbuf_gets(s,pos);
     367             : 
     368        3404 :         if (ret <= 0) {
     369           0 :                 return ret;
     370             :         }
     371             : 
     372        3404 :         switch (fmt) {
     373        3404 :         case FMT_CASE_PRESERVE:
     374        3404 :                 break;
     375           0 :         case FMT_CASE_UPPER:
     376           0 :                 while(*ptr != '\0') {
     377           0 :                         *ptr = toupper(*ptr);
     378           0 :                         ptr++;
     379             :                 }
     380           0 :                 break;
     381           0 :         case FMT_CASE_TITLE:
     382           0 :                 *ptr = toupper(*ptr);
     383           0 :                 ptr++;
     384             :                 FALL_THROUGH;
     385           0 :         case FMT_CASE_LOWER:
     386           0 :                 while(*ptr != '\0') {
     387           0 :                         *ptr = tolower(*ptr);
     388           0 :                         ptr++;
     389             :                 }
     390             :         }
     391        3404 :         return ret;
     392             : }

Generated by: LCOV version 1.13