Changeset 42 for trunk/src/reglookup.c


Ignore:
Timestamp:
08/03/05 22:41:25 (19 years ago)
Author:
tim
Message:

Changed to a CSV-like output format to accommodate extended fields

Added mtime output for keys

Added security descriptor columns (probably broken right now)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/reglookup.c

    r41 r42  
    11/*
    2  * A utility to test functionality of Gerald Carter''s regfio interface.
     2 * A utility to read a Windows NT/2K/XP/2K3 registry file, using
     3 * Gerald Carter''s regfio interface.
    34 *
    45 * Copyright (C) 2005 Timothy D. Morgan
     6 * Copyright (C) 2002 Richard Sharpe, rsharpe@richardsharpe.com
    57 *
    68 * This program is free software; you can redistribute it and/or modify
     
    2527#include <string.h>
    2628#include <strings.h>
     29#include <time.h>
    2730#include "../include/regfio.h"
    2831#include "../include/void_stack.h"
    29 
    3032
    3133/* Globals, influenced by command line parameters */
    3234bool print_verbose = false;
    3335bool print_security = false;
     36bool print_header = true;
    3437bool path_filter_enabled = false;
    3538bool type_filter_enabled = false;
     
    3841char* registry_file = NULL;
    3942
     43/* Other globals */
     44const char* special_chars = ",\"\\";
    4045
    4146void bailOut(int code, char* message)
     
    9196static char* quote_string(const char* str, char* special)
    9297{
    93   unsigned int len = strlen(str);
    94   char* ret_val = quote_buffer((const unsigned char*)str, len, special);
    95 
    96   return ret_val;
     98  unsigned int len;
     99
     100  if(str == NULL)
     101    return NULL;
     102
     103  len = strlen(str);
     104  return quote_buffer((const unsigned char*)str, len, special);
    97105}
    98106
     
    148156    /* XXX: This has to be fixed. It has to be UNICODE */
    149157    uni_to_ascii(datap, ascii, len, ascii_max);
    150     return ascii;
     158    cur_quoted = quote_string((char*)ascii, special_chars);
     159    free(ascii);
     160    return (unsigned char*)cur_quoted;
    151161    break;
    152162
     
    158168
    159169    uni_to_ascii(datap, ascii, len, ascii_max);
    160     return ascii;
    161     break;
    162 
    163   case REG_BINARY:
    164     ascii = (unsigned char*)quote_buffer(datap, len, "\\");
    165     return ascii;
     170    cur_quoted = quote_string((char*)ascii, special_chars);
     171    free(ascii);
     172    return (unsigned char*)cur_quoted;
    166173    break;
    167174
     
    179186    break;
    180187
     188  /* XXX: this MULTI_SZ parser is pretty inefficient.  Should be
     189   *      redone with fewer malloc and better string concatenation.
     190   */
    181191  case REG_MULTI_SZ:
    182192    ascii_max = sizeof(char)*len*4;
     
    185195    cur_ascii = malloc(cur_str_max);
    186196    ascii = malloc(ascii_max+4);
    187     if(ascii == NULL)
     197    if(ascii == NULL || cur_str == NULL || cur_ascii == NULL)
    188198      return NULL;
    189199
     
    211221      {
    212222        uni_to_ascii(cur_str, cur_ascii, cur_str_max, 0);
    213         /* XXX: Should backslashes be quoted as well? */
    214         cur_quoted = quote_string((char*)cur_ascii, "|");
     223        cur_quoted = quote_string((char*)cur_ascii, ",|\"\\");
    215224        alen = snprintf((char*)asciip, str_rem, "%s", cur_quoted);
    216225        asciip += alen;
     
    234243    }
    235244    *asciip = 0;
     245    free(cur_str);
     246    free(cur_ascii);
    236247    return ascii;
     248    break;
     249
     250  /* XXX: Dont know what to do with these yet, just print as binary... */
     251  case REG_RESOURCE_LIST:
     252  case REG_FULL_RESOURCE_DESCRIPTOR:
     253  case REG_RESOURCE_REQUIREMENTS_LIST:
     254
     255  case REG_BINARY:
     256    return (unsigned char*)quote_buffer(datap, len, special_chars);
    237257    break;
    238258
     
    243263
    244264  return NULL;
     265}
     266
     267
     268/* Security descriptor print functions  */
     269
     270const char* ace_type2str(uint8 type)
     271{
     272  static const char* map[7]
     273    = {"ALLOW", "DENY", "AUDIT", "ALARM",
     274       "ALLOW CPD", "OBJ ALLOW", "OBJ DENY"};
     275  if(type < 7)
     276    return map[type];
     277  else
     278    return "UNKNOWN";
     279}
     280
     281
     282char* ace_flags2str(uint8 flags)
     283{
     284  char* flg_output = malloc(21*sizeof(char));
     285  int some = 0;
     286
     287  if(flg_output == NULL)
     288    return NULL;
     289
     290  flg_output[0] = '\0';
     291  if (!flags)
     292    return flg_output;
     293
     294  if (flags & 0x01) {
     295    if (some) strcat(flg_output, " ");
     296    some = 1;
     297    strcat(flg_output, "OI");
     298  }
     299  if (flags & 0x02) {
     300    if (some) strcat(flg_output, " ");
     301    some = 1;
     302    strcat(flg_output, "CI");
     303  }
     304  if (flags & 0x04) {
     305    if (some) strcat(flg_output, " ");
     306    some = 1;
     307    strcat(flg_output, "NP");
     308  }
     309  if (flags & 0x08) {
     310    if (some) strcat(flg_output, " ");
     311    some = 1;
     312    strcat(flg_output, "IO");
     313  }
     314  if (flags & 0x10) {
     315    if (some) strcat(flg_output, " ");
     316    some = 1;
     317    strcat(flg_output, "IA");
     318  }
     319  if (flags == 0xF) {
     320    if (some) strcat(flg_output, " ");
     321    some = 1;
     322    strcat(flg_output, "VI");
     323  }
     324
     325  return flg_output;
     326}
     327
     328
     329char* ace_perms2str(uint32 perms)
     330{
     331  char* ret_val = malloc(9*sizeof(char));
     332  sprintf(ret_val, "%8X", perms);
     333
     334  return ret_val;
     335}
     336
     337
     338char* sid2str(DOM_SID* sid)
     339{
     340  uint32 i, size = MAXSUBAUTHS*11 + 24;
     341  uint32 left = size;
     342  uint8 comps = sid->num_auths;
     343  char* ret_val = malloc(size);
     344 
     345  if(ret_val == NULL)
     346    return NULL;
     347
     348  if(comps > MAXSUBAUTHS)
     349    comps = MAXSUBAUTHS;
     350
     351  left -= sprintf(ret_val, "S-%u-%u", sid->sid_rev_num, sid->id_auth[5]);
     352
     353  for (i = 0; i < comps; i++)
     354    left -= snprintf(ret_val+(size-left), left, "-%u", sid->sub_auths[i]);
     355
     356  return ret_val;
     357}
     358
     359
     360char* get_acl(SEC_ACL* acl)
     361{
     362  uint32 i, extra, size = 0;
     363  const char* type_str;
     364  char* flags_str;
     365  char* perms_str;
     366  char* sid_str;
     367  char* ret_val = NULL;
     368  char* ace_delim = "";
     369  char field_delim = ':';
     370
     371  for (i = 0; i < acl->num_aces; i++)
     372  {
     373    /* XXX: check for NULL */
     374    sid_str = sid2str(&acl->ace[i].trustee);
     375    type_str = ace_type2str(acl->ace[i].type);
     376    perms_str = ace_perms2str(acl->ace[i].info.mask);
     377    flags_str = ace_flags2str(acl->ace[i].flags);
     378
     379    /* XXX: this is slow */
     380    extra = strlen(sid_str) + strlen(type_str)
     381          + strlen(perms_str) + strlen(flags_str);
     382    ret_val = realloc(ret_val, size+extra+5);
     383    if(ret_val == NULL)
     384      return NULL;
     385    snprintf(ret_val+size, extra+4, "%s%s%c%s%c%s%c%s",
     386             ace_delim,sid_str,
     387             field_delim,type_str,
     388             field_delim,perms_str,
     389             field_delim,flags_str);
     390    size += extra;
     391    ace_delim = "|";
     392    free(sid_str);
     393    free(perms_str);
     394    free(flags_str);
     395  }
     396
     397  return ret_val;
     398}
     399
     400
     401char* get_sacl(SEC_DESC *sec_desc)
     402{
     403  if (sec_desc->sacl)
     404    return get_acl(sec_desc->sacl);
     405  else
     406    return "";
     407}
     408
     409
     410char* get_dacl(SEC_DESC *sec_desc)
     411{
     412  if (sec_desc->dacl)
     413    return get_acl(sec_desc->dacl);
     414  else
     415    return "";
     416}
     417
     418
     419char* get_owner(SEC_DESC *sec_desc)
     420{
     421  return sid2str(sec_desc->owner_sid);
     422}
     423
     424
     425char* get_group(SEC_DESC *sec_desc)
     426{
     427  return sid2str(sec_desc->grp_sid);
    245428}
    246429
     
    343526  uint32 size;
    344527  uint8 tmp_buf[4];
    345   char* quoted_value;
     528  unsigned char* quoted_value;
     529  char* quoted_prefix;
     530  char* quoted_name;
    346531
    347532  if(!type_filter_enabled || (vk->type == type_filter))
     
    367552      if(size > 16384)
    368553      {
    369         printf("WARNING: key size %d larger than 16384, truncating...\n", size);
     554        fprintf(stderr, "WARNING: key size %d larger than "
     555                        "16384, truncating...\n", size);
    370556        size = 16384;
    371557      }
     
    373559    }
    374560
    375     printf("%s/%s:%s=%s\n", prefix, vk->valuename,
     561    /* XXX: Sometimes value names can be NULL in registry.  Need to
     562     *      figure out why and when, and generate the appropriate output
     563     *      for that condition.
     564     */
     565    quoted_prefix = quote_string(prefix, special_chars);
     566    quoted_name = quote_string(vk->valuename, special_chars);
     567
     568    printf("%s/%s,%s,%s,,,,,\n", quoted_prefix, quoted_name,
    376569           regfio_type_val2str(vk->type), quoted_value);
     570
     571    if(quoted_value != NULL)
     572      free(quoted_value);
     573    if(quoted_prefix != NULL)
     574      free(quoted_prefix);
     575    if(quoted_name != NULL)
     576      free(quoted_name);
    377577  }
    378578}
     
    393593  REGF_NK_REC* cur;
    394594  REGF_NK_REC* sub;
    395   char* path;
    396   char* val_path;
     595  char* path = NULL;
     596  char* val_path = NULL;
     597  char* owner = NULL;
     598  char* group = NULL;
     599  char* sacl = NULL;
     600  char* dacl = NULL;
     601  char mtime[20];
     602  time_t tmp_time[1];
     603  struct tm* tmp_time_s = NULL;
     604
    397605  int key_type = regfio_type_str2val("KEY");
    398606
     
    404612    if(strlen(path) > 0)
    405613      if(!type_filter_enabled || (key_type == type_filter))
    406         printf("%s%s:KEY\n", prefix, path);
     614      {
     615        owner = get_owner(cur->sec_desc->sec_desc);
     616        group = get_group(cur->sec_desc->sec_desc);
     617        sacl = get_sacl(cur->sec_desc->sec_desc);
     618        dacl = get_dacl(cur->sec_desc->sec_desc);
     619        *tmp_time = nt_time_to_unix(&cur->mtime);
     620        tmp_time_s = gmtime(tmp_time);
     621        strftime(mtime, sizeof(mtime), "%Y-%m-%d %H:%M:%S", tmp_time_s);
     622        printf("%s%s,KEY,,%s,%s,%s,%s,%s\n", prefix, path, mtime,
     623               owner, group, sacl, dacl);
     624        if(owner != NULL)
     625          free(owner);
     626        owner = NULL;
     627        if(group != NULL)
     628          free(group);
     629        group = NULL;
     630        if(sacl != NULL)
     631          free(sacl);
     632        sacl = NULL;
     633        if(dacl != NULL)
     634          free(dacl);
     635        dacl = NULL;
     636      }
    407637    if(!type_filter_enabled || (key_type != type_filter))
    408638      printValueList(cur, path);
     
    419649          sprintf(val_path, "%s%s", prefix, path);
    420650          if(!type_filter_enabled || (key_type == type_filter))
    421             printf("%s:KEY\n", val_path);
     651          {
     652            owner = get_owner(sub->sec_desc->sec_desc);
     653            group = get_group(sub->sec_desc->sec_desc);
     654            sacl = get_sacl(sub->sec_desc->sec_desc);
     655            dacl = get_dacl(sub->sec_desc->sec_desc);
     656            *tmp_time = nt_time_to_unix(&cur->mtime);
     657            tmp_time_s = gmtime(tmp_time);
     658            strftime(mtime, sizeof(mtime), "%Y-%m-%d %H:%M:%S", tmp_time_s);
     659            printf("%s,KEY,,%s,%s,%s,%s,%s\n", val_path, mtime,
     660                   owner, group, sacl, dacl);
     661          }
    422662          if(!type_filter_enabled || (key_type != type_filter))
    423663            printValueList(sub, val_path);
    424           free(val_path);
    425           free(path);
     664          if(val_path != NULL)
     665            free(val_path);
     666          val_path = NULL;
     667          if(path != NULL)
     668            free(path);
     669          path = NULL;
     670          if(owner != NULL)
     671            free(owner);
     672          owner = NULL;
     673          if(group != NULL)
     674            free(group);
     675          group = NULL;
     676          /* XXX: causes segfaults.  fix mem allocation bug */
     677          /*      if(sacl != NULL)
     678            free(sacl);*/
     679          sacl = NULL;
     680          if(dacl != NULL)
     681            free(dacl);
     682          dacl = NULL;
     683          tmp_time_s = NULL;
    426684        }
    427685      }
     
    608866  if(void_stack_push(nk_stack, root))
    609867  {
     868    if(print_header)
     869      printf("PATH,TYPE,VALUE,MTIME,OWNER,GROUP,SACL,DACL\n");
     870
    610871    path_stack = path2Stack(path_filter);
    611872    if(void_stack_size(path_stack) < 1)
Note: See TracChangeset for help on using the changeset viewer.