diff options
Diffstat (limited to 'source3/utils/editreg.c')
-rw-r--r-- | source3/utils/editreg.c | 712 |
1 files changed, 83 insertions, 629 deletions
diff --git a/source3/utils/editreg.c b/source3/utils/editreg.c index c00d9c22cb..ad4417921c 100644 --- a/source3/utils/editreg.c +++ b/source3/utils/editreg.c @@ -310,38 +310,10 @@ Hope this helps.... (Although it was "fun" for me to uncover this things, #define False 0 #define True 1 -#define REG_KEY_LIST_SIZE 10 - -/* - * Structures for dealing with the on-disk format of the registry - */ - -#define IVAL(buf) ((unsigned int) \ - (unsigned int)*((unsigned char *)(buf)+3)<<24| \ - (unsigned int)*((unsigned char *)(buf)+2)<<16| \ - (unsigned int)*((unsigned char *)(buf)+1)<<8| \ - (unsigned int)*((unsigned char *)(buf)+0)) - -#define SVAL(buf) ((unsigned short) \ - (unsigned short)*((unsigned char *)(buf)+1)<<8| \ - (unsigned short)*((unsigned char *)(buf)+0)) - -#define CVAL(buf) ((unsigned char)*((unsigned char *)(buf))) - -#define SIVAL(buf, val) \ - ((unsigned char)buf[0]=(unsigned char)((val)&0xFF),\ - (unsigned char)buf[1]=(unsigned char)(((val)>>8)&0xFF),\ - (unsigned char)buf[2]=(unsigned char)(((val)>>16)&0xFF),\ - (unsigned char)buf[3]=(unsigned char)((val)>>24)) - -#define SSVAL(buf, val) \ - ((unsigned char)buf[0]=(unsigned char)((val)&0xFF),\ - (unsigned char)buf[1]=(unsigned char)(((val)>>8)&0xFF)) +#define REG_KEY_LIST_SIZE 10; static int verbose = 0; static int print_security = 0; -static int full_print = 0; -static char *def_owner_sid_str = NULL; /* * These definitions are for the in-memory registry structure. @@ -365,8 +337,6 @@ typedef struct date_time_s { #define REG_SUB_KEY 2 #define REG_SYM_LINK 3 -typedef struct key_sec_desc_s KEY_SEC_DESC; - typedef struct reg_key_s { char *name; /* Name of the key */ char *class_name; @@ -375,7 +345,7 @@ typedef struct reg_key_s { struct reg_key_s *owner; struct key_list_s *sub_keys; struct val_list_s *values; - KEY_SEC_DESC *security; + struct key_sec_desc_s *security; } REG_KEY; /* @@ -398,7 +368,6 @@ typedef struct val_key_s { typedef struct val_list_s { int val_count; - int max_vals; VAL_KEY *vals[1]; } VAL_LIST; @@ -433,13 +402,13 @@ typedef struct sec_desc_s { #define SEC_DESC_NON 0 #define SEC_DESC_RES 1 #define SEC_DESC_OCU 2 -#define SEC_DESC_NBK 3 -struct key_sec_desc_s { + +typedef struct key_sec_desc_s { struct key_sec_desc_s *prev, *next; int ref_cnt; int state; SEC_DESC *sec_desc; -}; +} KEY_SEC_DESC; /* * All of the structures below actually have a four-byte lenght before them @@ -478,8 +447,8 @@ typedef struct hbin_sub_struct { typedef struct hbin_struct { DWORD HBIN_ID; /* hbin */ - DWORD prev_off; DWORD next_off; + DWORD prev_off; DWORD uk1; DWORD uk2; DWORD uk3; @@ -575,7 +544,6 @@ typedef struct vk_struct { char dat_name[1]; /* Name starts here ... */ } VK_HDR; -#define REG_TYPE_DELETE -1 #define REG_TYPE_NONE 0 #define REG_TYPE_REGSZ 1 #define REG_TYPE_EXPANDSZ 2 @@ -605,8 +573,6 @@ struct regf_struct_s { REG_KEY *root; /* Root of the tree for this file */ int sk_count, sk_map_size; SK_MAP *sk_map; - char *owner_sid_str; - SEC_DESC *def_sec_desc; }; typedef struct regf_struct_s REGF; @@ -756,7 +722,7 @@ REG_KEY *nt_find_key_in_list_by_name(KEY_LIST *list, char *key) if (!list || !key || !*key) return NULL; - for (i = 0; i < list->key_count; i++) + for (i = 0; i<= list->key_count; i++) if ((res = nt_find_key_by_name(list->keys[i], key))) return res; @@ -808,7 +774,6 @@ int nt_delete_val_key(VAL_KEY *val_key) { if (val_key) { - if (val_key->name) free(val_key->name); if (val_key->data_blk) free(val_key->data_blk); free(val_key); }; @@ -852,7 +817,6 @@ int nt_delete_key_by_name(REGF *regf, char *name) key = nt_find_key_by_name(regf->root, name); if (key) { - if (key == regf->root) regf->root = NULL; return nt_delete_reg_key(key, True); } @@ -975,142 +939,6 @@ int nt_delete_reg_key(REG_KEY *key, int delete_name) return 1; } -/* - * Convert a string to a value ... - * FIXME: Error handling and convert this at command parse time ... - */ -void *str_to_val(int type, char *val, int *len) -{ - unsigned int *dwordp = NULL; - - if (!len || !val) return NULL; - - switch (type) { - case REG_TYPE_REGSZ: - *len = strlen(val); - return (void *)val; - - case REG_TYPE_DWORD: - dwordp = (unsigned int *)malloc(sizeof(unsigned int)); - if (!dwordp) return NULL; - /* Allow for ddddd and 0xhhhhh and 0ooooo */ - if (strncmp(val, "0x", 2) == 0 || strncmp(val, "0X", 2) == 0) { - sscanf(&val[2], "%X", dwordp); - } - else if (*val == '0') { - sscanf(&val[1], "%o", dwordp); - } - else { - sscanf(val, "%d", dwordp); - } - *len = sizeof(unsigned int); - return (void *)dwordp; - - /* FIXME: Implement more of these */ - - default: - return NULL; - break; - } - - return NULL; -} - -/* - * Add a value to the key specified ... We have to parse the value some more - * based on the type to get it in the correct internal form - * An empty name will be converted to "<No Name>" before here - * Hmmm, maybe not. has_name is for that - */ -VAL_KEY *nt_add_reg_value(REG_KEY *key, char *name, int type, char *value) -{ - int i; - VAL_KEY *tmp = NULL; - - if (!key || !key->values || !name || !*name) return NULL; - - assert(type != REG_TYPE_DELETE); /* We never process deletes here */ - - for (i = 0; i < key->values->val_count; i++) { - if ((!key->values->vals[i]->has_name && !*name) || - (key->values->vals[i]->has_name && - strcmp(name, key->values->vals[i]->name) == 0)){ /* Change the value */ - free(key->values->vals[i]->data_blk); - key->values->vals[i]->data_blk = str_to_val(type, value, & - key->values->vals[i]->data_len); - return key->values->vals[i]; - } - } - - /* - * If we get here, the name was not found, so insert it - */ - - tmp = (VAL_KEY *)malloc(sizeof(VAL_KEY)); - if (!tmp) goto error; - - bzero(tmp, sizeof(VAL_KEY)); - tmp->name = strdup(name); - tmp->has_name = True; - if (!tmp->name) goto error; - tmp->data_type = type; - tmp->data_blk = str_to_val(type, value, &tmp->data_len); - - /* Now, add to val list */ - - if (key->values->val_count >= key->values->max_vals) { - /* - * Allocate some more space - */ - - if ((key->values = (VAL_LIST *)realloc(key->values, sizeof(VAL_LIST) + - key->values->val_count - 1 + - REG_KEY_LIST_SIZE))) { - key->values->max_vals += REG_KEY_LIST_SIZE; - } - else goto error; - } - - i = key->values->val_count; - key->values->val_count++; - key->values->vals[i] = tmp; - return tmp; - - error: - if (tmp) nt_delete_val_key(tmp); - return NULL; -} - -/* - * Delete a value. We return the value and let the caller deal with it. - */ -VAL_KEY *nt_delete_reg_value(REG_KEY *key, char *name) -{ - int i, j; - - if (!key || !key->values || !name || !*name) return NULL; - - /* FIXME: Allow empty value name */ - for (i = 0; i< key->values->val_count; i++) { - if ((!key->values->vals[i]->has_name && !*name) || - (key->values->vals[i]->has_name && - strcmp(name, key->values->vals[i]->name) == 0)) { - VAL_KEY *val; - - val = key->values->vals[i]; - - /* Shuffle down */ - for (j = i + 1; j < key->values->val_count; j++) - key->values->vals[j - 1] = key->values->vals[j]; - - key->values->val_count--; - - return val; - } - } - return NULL; -} - /* * Add a key to the tree ... We walk down the components matching until * we don't find any. There must be a match on the first component ... @@ -1136,189 +964,32 @@ REG_KEY *nt_create_reg_key1(char *name, REG_KEY *parent) if (!(tmp->name = strdup(name))) goto error; - error: - if (tmp) free(tmp); - return NULL; -} - -/* - * Convert a string of the form S-1-5-x[-y-z-r] to a SID - */ -int string_to_sid(DOM_SID **sid, char *sid_str) -{ - int i = 0, auth; - char *lstr; - - *sid = (DOM_SID *)malloc(sizeof(DOM_SID)); - if (!*sid) return 0; - - bzero(*sid, sizeof(DOM_SID)); - - if (strncmp(sid_str, "S-1-5", 5)) { - fprintf(stderr, "Does not conform to S-1-5...: %s\n", sid_str); - return 0; - } - - /* We only allow strings of form S-1-5... */ - - (*sid)->ver = 1; - (*sid)->auth[5] = 5; - - lstr = sid_str + 5; - - while (1) { - if (!lstr || !lstr[0] || sscanf(lstr, "-%u", &auth) == 0) { - if (i < 1) { - fprintf(stderr, "Not of form -d-d...: %s, %u\n", lstr, i); - return 0; - } - (*sid)->auths=i; - return 1; - } - - (*sid)->sub_auths[i] = auth; - i++; - lstr = strchr(lstr + 1, '-'); - } - - return 1; -} - -/* - * Create an ACE - */ -ACE *nt_create_ace(int type, int flags, unsigned int perms, char *sid) -{ - ACE *ace; - ace = (ACE *)malloc(sizeof(ACE)); - if (!ace) goto error; - ace->type = type; - ace->flags = flags; - ace->perms = perms; - if (!string_to_sid(&ace->trustee, sid)) - goto error; - return ace; error: - if (ace) nt_delete_ace(ace); - return NULL; -} - -/* - * Create a default ACL - */ -ACL *nt_create_default_acl(REGF *regf) -{ - ACL *acl; - - acl = (ACL *)malloc(sizeof(ACL) + 7*sizeof(ACE *)); - if (!acl) goto error; - - acl->rev = 2; - acl->refcnt = 1; - acl->num_aces = 8; - - acl->aces[0] = nt_create_ace(0x00, 0x0, 0xF003F, regf->owner_sid_str); - if (!acl->aces[0]) goto error; - acl->aces[1] = nt_create_ace(0x00, 0x0, 0xF003F, "S-1-5-18"); - if (!acl->aces[1]) goto error; - acl->aces[2] = nt_create_ace(0x00, 0x0, 0xF003F, "S-1-5-32-544"); - if (!acl->aces[2]) goto error; - acl->aces[3] = nt_create_ace(0x00, 0x0, 0x20019, "S-1-5-12"); - if (!acl->aces[3]) goto error; - acl->aces[4] = nt_create_ace(0x00, 0x0B, 0x10000000, regf->owner_sid_str); - if (!acl->aces[4]) goto error; - acl->aces[5] = nt_create_ace(0x00, 0x0B, 0x10000000, "S-1-5-18"); - if (!acl->aces[5]) goto error; - acl->aces[6] = nt_create_ace(0x00, 0x0B, 0x10000000, "S-1-5-32-544"); - if (!acl->aces[6]) goto error; - acl->aces[7] = nt_create_ace(0x00, 0x0B, 0x80000000, "S-1-5-12"); - if (!acl->aces[7]) goto error; - return acl; - - error: - if (acl) nt_delete_acl(acl); - return NULL; -} - -/* - * Create a default security descriptor. We pull in things from env - * if need be - */ -SEC_DESC *nt_create_def_sec_desc(REGF *regf) -{ - SEC_DESC *tmp; - - tmp = (SEC_DESC *)malloc(sizeof(SEC_DESC)); - if (!tmp) return NULL; - - tmp->rev = 1; - tmp->type = 0x8004; - if (!string_to_sid(&tmp->owner, "S-1-5-32-544")) goto error; - if (!string_to_sid(&tmp->group, "S-1-5-18")) goto error; - tmp->sacl = NULL; - tmp->dacl = nt_create_default_acl(regf); - - return tmp; - - error: - if (tmp) nt_delete_sec_desc(tmp); + if (tmp) free(tmp); return NULL; } -/* - * We will implement inheritence that is based on what the parent's SEC_DESC - * says, but the Owner and Group SIDs can be overwridden from the command line - * and additional ACEs can be applied from the command line etc. - */ -KEY_SEC_DESC *nt_inherit_security(REG_KEY *key) -{ - - if (!key) return NULL; - return key->security; -} - -/* - * Create an initial security descriptor and init other structures, if needed - * We assume that the initial security stuff is empty ... - */ -KEY_SEC_DESC *nt_create_init_sec(REGF *regf) -{ - KEY_SEC_DESC *tsec = NULL; - - tsec = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC)); - if (!tsec) return NULL; - - tsec->ref_cnt = 1; - tsec->state = SEC_DESC_NBK; - - tsec->sec_desc = regf->def_sec_desc; - - return tsec; -} - -/* - * Add a sub-key - */ -REG_KEY *nt_add_reg_key_list(REGF *regf, REG_KEY *key, char * name, int create) +REG_KEY *nt_add_reg_key(REG_KEY *key, char *name, int create); +REG_KEY *nt_add_reg_key_list(KEY_LIST *list, char * name, REG_KEY *parent, int create) { int i; - REG_KEY *ret = NULL, *tmp = NULL; - KEY_LIST *list; + REG_KEY *ret; char *lname, *c1, *c2; - if (!key || !name || !*name) return NULL; - - list = key->sub_keys; - if (!list) { /* Create an empty list */ - - list = (KEY_LIST *)malloc(sizeof(KEY_LIST) + (REG_KEY_LIST_SIZE - 1) * sizeof(REG_KEY *)); - list->key_count = 0; - list->max_keys = REG_KEY_LIST_SIZE; + if (!list || !name || !*name) return NULL; + for (i = 0; i < list->key_count; i++) { + if ((ret = nt_add_reg_key(list->keys[i], name, create))) + return ret; } + /* + * If we reach here we could not find the the first component + * so create it ... + */ + lname = strdup(name); if (!lname) return NULL; @@ -1329,86 +1000,30 @@ REG_KEY *nt_add_reg_key_list(REGF *regf, REG_KEY *key, char * name, int create) c2++; } - for (i = 0; i < list->key_count; i++) { - if (strcmp(list->keys[i]->name, c1) == 0) { - ret = nt_add_reg_key_list(regf, list->keys[i], c2, create); - free(lname); - return ret; - } - } - - /* - * If we reach here we could not find the the first component - * so create it ... - */ - if (list->key_count < list->max_keys){ list->key_count++; } else { /* Create more space in the list ... */ - if (!(list = (KEY_LIST *)realloc(list, sizeof(KEY_LIST) + - (list->max_keys + REG_KEY_LIST_SIZE - 1) - * sizeof(REG_KEY *)))); - goto error; - list->max_keys += REG_KEY_LIST_SIZE; - list->key_count++; - } - - /* - * add the new key at the new slot - * FIXME: Sort the list someday - */ - - /* - * We want to create the key, and then do the rest - */ - - tmp = (REG_KEY *)malloc(sizeof(REG_KEY)); - - bzero(tmp, sizeof(REG_KEY)); - - tmp->name = strdup(c1); - if (!tmp->name) goto error; - tmp->owner = key; - tmp->type = REG_SUB_KEY; - /* - * Next, pull security from the parent, but override with - * anything passed in on the command line - */ - tmp->security = nt_inherit_security(key); - - list->keys[list->key_count - 1] = tmp; - - if (c2) { - ret = nt_add_reg_key_list(regf, key, c2, True); } - if (lname) free(lname); - - return ret; - + return NULL; error: - if (tmp) free(tmp); if (lname) free(lname); return NULL; } -/* - * This routine only adds a key from the root down. - * It calls helper functions to handle sub-key lists and sub-keys - */ -REG_KEY *nt_add_reg_key(REGF *regf, char *name, int create) +REG_KEY *nt_add_reg_key(REG_KEY *key, char *name, int create) { char *lname = NULL, *c1, *c2; - REG_KEY * tmp = NULL; + REG_KEY * tmp; /* * Look until we hit the first component that does not exist, and * then add from there. However, if the first component does not * match and the path we are given is the root, then it must match */ - if (!regf || !name || !*name) return NULL; + if (!key || !name || !*name) return NULL; lname = strdup(name); if (!lname) return NULL; @@ -1421,45 +1036,38 @@ REG_KEY *nt_add_reg_key(REGF *regf, char *name, int create) } /* - * If the root does not exist, create it and make it equal to the - * first component ... + * If we don't match, then we have to return error ... + * If we do match on this component, check the next one in the + * list, and if not found, add it ... short circuit, add all the + * way down */ - if (!regf->root) { - - tmp = (REG_KEY *)malloc(sizeof(REG_KEY)); - if (!tmp) goto error; - bzero(tmp, sizeof(REG_KEY)); - tmp->name = strdup(c1); - if (!tmp->name) goto error; - tmp->security = nt_create_init_sec(regf); - if (!tmp->security) goto error; - regf->root = tmp; - - } - else { - /* - * If we don't match, then we have to return error ... - * If we do match on this component, check the next one in the - * list, and if not found, add it ... short circuit, add all the - * way down - */ - - if (strcmp(c1, regf->root->name) != 0) - goto error; - } - - tmp = nt_add_reg_key_list(regf, regf->root, c2, True); + if (strcmp(c1, key->name) != 0) + goto error; + + tmp = nt_add_reg_key_list(key->sub_keys, c2, key, True); free(lname); return tmp; error: - if (tmp) free(tmp); if (lname) free(lname); return NULL; } /* + * Create/delete value lists, add/delete values, count them + */ + + +/* + * Create/delete security descriptors, add/delete SIDS, count SIDS, etc. + * We reference count the security descriptors. Any new reference increments + * the ref count. If we modify an SD, we copy the old one, dec the ref count + * and make the change. We also want to be able to check for equality so + * we can reduce the number of SDs in use. + */ + +/* * Load and unload a registry file. * * Load, loads it into memory as a tree, while unload sealizes/flattens it @@ -1491,6 +1099,22 @@ REG_KEY *nt_add_reg_key(REGF *regf, char *name, int create) #define REGF_HDR_BLKSIZ 0x1000 +/* + * Structures for dealing with the on-disk format of the registry + */ + +#define IVAL(buf) ((unsigned int) \ + (unsigned int)*((unsigned char *)(buf)+3)<<24| \ + (unsigned int)*((unsigned char *)(buf)+2)<<16| \ + (unsigned int)*((unsigned char *)(buf)+1)<<8| \ + (unsigned int)*((unsigned char *)(buf)+0)) + +#define SVAL(buf) ((unsigned short) \ + (unsigned short)*((unsigned char *)(buf)+1)<<8| \ + (unsigned short)*((unsigned char *)(buf)+0)) + +#define CVAL(buf) ((unsigned char)*((unsigned char *)(buf))) + #define OFF(f) ((f) + REGF_HDR_BLKSIZ + 4) #define LOCN(base, f) ((base) + OFF(f)) @@ -1610,7 +1234,6 @@ REGF *nt_create_regf(void) REGF *tmp = (REGF *)malloc(sizeof(REGF)); if (!tmp) return tmp; bzero(tmp, sizeof(REGF)); - tmp->owner_sid_str = def_owner_sid_str; return tmp; } @@ -1623,6 +1246,12 @@ int nt_free_regf(REGF *regf) if (regf->regfile_name) free(regf->regfile_name); if (regf->outfile_name) free(regf->outfile_name); + /* Free the mmap'd area */ + + if (regf->base) munmap(regf->base, regf->sbuf.st_size); + regf->base = NULL; + close(regf->fd); /* Ignore the error :-) */ + nt_delete_reg_key(regf->root, False); /* Free the tree */ free(regf->sk_map); regf->sk_count = regf->sk_map_size = 0; @@ -1831,8 +1460,6 @@ ACL *dup_acl(REG_ACL *acl) tmp->num_aces = num_aces; tmp->refcnt = 1; tmp->rev = SVAL(&acl->rev); - if (verbose) fprintf(stdout, "ACL: refcnt: %u, rev: %u\n", tmp->refcnt, - tmp->rev); ace = (REG_ACE *)&acl->aces; for (i=0; i<num_aces; i++) { tmp->aces[i] = dup_ace(ace); @@ -1855,8 +1482,6 @@ SEC_DESC *process_sec_desc(REGF *regf, REG_SEC_DESC *sec_desc) tmp->rev = SVAL(&sec_desc->rev); tmp->type = SVAL(&sec_desc->type); - if (verbose) fprintf(stdout, "SEC_DESC Rev: %0X, Type: %0X\n", - tmp->rev, tmp->type); tmp->owner = dup_sid((DOM_SID *)((char *)sec_desc + IVAL(&sec_desc->owner_off))); if (!tmp->owner) { free(tmp); @@ -2049,7 +1674,7 @@ VAL_KEY *process_vk(REGF *regf, VK_HDR *vk_hdr, int size) return tmp; error: - if (tmp) nt_delete_val_key(tmp); + /* XXX: FIXME, free the partially allocated struct */ return NULL; } @@ -2085,7 +1710,6 @@ VAL_LIST *process_vl(REGF *regf, VL_TYPE vl, int count, int size) } tmp->val_count = count; - tmp->max_vals = count; return tmp; @@ -2114,7 +1738,7 @@ KEY_LIST *process_lf(REGF *regf, LF_HDR *lf_hdr, int size, REG_KEY *parent) assert(size < 0); count = SVAL(&lf_hdr->key_count); - if (verbose) fprintf(stdout, "Key Count: %u\n", count); + if (count <= 0) return NULL; /* Now, we should allocate a KEY_LIST struct and fill it in ... */ @@ -2131,7 +1755,6 @@ KEY_LIST *process_lf(REGF *regf, LF_HDR *lf_hdr, int size, REG_KEY *parent) NK_HDR *nk_hdr; nk_off = IVAL(&lf_hdr->hr[i].nk_off); - if (verbose) fprintf(stdout, "NK Offset: %0X\n", nk_off); nk_hdr = (NK_HDR *)LOCN(regf->base, nk_off); tmp->keys[i] = nt_get_key_tree(regf, nk_hdr, BLK_SIZE(nk_hdr), parent); if (!tmp->keys[i]) { @@ -2147,7 +1770,7 @@ KEY_LIST *process_lf(REGF *regf, LF_HDR *lf_hdr, int size, REG_KEY *parent) } /* - * This routine is passed an NK_HDR pointer and retrieves the entire tree + * This routine is passed a NK_HDR pointer and retrieves the entire tree * from there down. It returns a REG_KEY *. */ REG_KEY *nt_get_key_tree(REGF *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent) @@ -2223,7 +1846,6 @@ REG_KEY *nt_get_key_tree(REGF *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent) clsnam_off = IVAL(&nk_hdr->clsnam_off); clsnamep = LOCN(regf->base, clsnam_off); - if (verbose) fprintf(stdout, "Class Name Offset: %0X\n", clsnam_off); bzero(cls_name, clsname_len); uni_to_ascii(clsnamep, cls_name, sizeof(cls_name), clsname_len); @@ -2250,10 +1872,9 @@ REG_KEY *nt_get_key_tree(REGF *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent) own_off = IVAL(&nk_hdr->own_off); own = (REG_KEY *)LOCN(regf->base, own_off); - if (verbose) fprintf(stdout, "Owner Offset: %0X\n", own_off); - if (verbose) fprintf(stdout, " Owner locn: %0X, Our locn: %0X\n", - (unsigned int)own, (unsigned int)nk_hdr); + if (verbose) fprintf(stdout, " Owner offset: %0X, Our Offset: %0X\n", + own, nk_hdr); /* * We should verify that the owner field is correct ... @@ -2267,12 +1888,11 @@ REG_KEY *nt_get_key_tree(REGF *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent) */ val_count = IVAL(&nk_hdr->val_cnt); - if (verbose) fprintf(stdout, "Val Count: %d\n", val_count); + if (val_count) { val_off = IVAL(&nk_hdr->val_off); vl = (VL_TYPE *)LOCN(regf->base, val_off); - if (verbose) fprintf(stdout, "Val List Offset: %0X\n", val_off); tmp->values = process_vl(regf, *vl, val_count, BLK_SIZE(vl)); if (!tmp->values) { @@ -2287,7 +1907,6 @@ REG_KEY *nt_get_key_tree(REGF *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent) sk_off = IVAL(&nk_hdr->sk_off); sk_hdr = (SK_HDR *)LOCN(regf->base, sk_off); - if (verbose) fprintf(stdout, "SK Offset: %0X\n", sk_off); if (sk_off != -1) { @@ -2296,7 +1915,6 @@ REG_KEY *nt_get_key_tree(REGF *regf, NK_HDR *nk_hdr, int size, REG_KEY *parent) } lf_off = IVAL(&nk_hdr->lf_off); - if (verbose) fprintf(stdout, "SubKey list offset: %0X\n", lf_off); /* * No more subkeys if lf_off == -1 @@ -2371,21 +1989,7 @@ int nt_load_registry(REGF *regf) * Get a pointer to the first key from the hreg_hdr */ - if (verbose) fprintf(stdout, "First Key: %0X\n", - IVAL(®f_hdr->first_key)); - first_key = (NK_HDR *)LOCN(regf->base, IVAL(®f_hdr->first_key)); - if (verbose) fprintf(stdout, "First Key Offset: %0X\n", - IVAL(®f_hdr->first_key)); - - if (verbose) fprintf(stdout, "Data Block Size: %d\n", - IVAL(®f_hdr->dblk_size)); - - if (verbose) fprintf(stdout, "Offset to next hbin block: %0X\n", - IVAL(&hbin_hdr->next_off)); - - if (verbose) fprintf(stdout, "HBIN block size: %0X\n", - IVAL(&hbin_hdr->blk_size)); /* * Now, get the registry tree by processing that NK recursively @@ -2395,69 +1999,11 @@ int nt_load_registry(REGF *regf) assert(regf->root != NULL); - /* - * Unmap the registry file, as we might want to read in another - * tree etc. - */ - - if (regf->base) munmap(regf->base, regf->sbuf.st_size); - regf->base = NULL; - close(regf->fd); /* Ignore the error :-) */ - return 1; } /* - * These structures keep track of the output format of the registry - */ -typedef struct hbin_blk_s { - struct hbin_blk_s *next; - unsigned int file_offset; /* Offset in file */ - unsigned int free_space; /* Amount of free space in block */ - unsigned int fsp_off; /* Start of free space in block */ - int complete, stored; -} HBIN_BLK; - -/* - * Allocate a new hbin block and link it to the others. - */ -int nt_create_hbin_blk(REGF *regf) -{ - - return 0; -} - -/* - * Store a KEY in the file ... - * - * We store this depth first, and defer storing the lf struct until - * all the sub-keys have been stored. - */ -int nt_store_reg_key(REGF *regf, REG_KEY *key) -{ - NK_HDR *nk_hdr; - - return 0; -} - -/* - * Store the registry header ... - */ -int nt_store_reg_header(REGF *regf){ - - return 0; -} - -/* - * Store the registry in the output file - * We write out the header and then each of the keys etc into the file - * We have to flatten the data structure ... - * - * The structures are stored in a depth-first fashion, with all records - * aligned on 8-byte boundaries, with sub-keys and values layed down before - * the lists that contain them. SK records are layed down first, however. - * The lf fields are layed down after all sub-keys have been layed down, it - * seems, including the whole tree associated with each sub-key. + * Story the registry in the output file */ int nt_store_registry(REGF *regf) { @@ -2518,15 +2064,6 @@ typedef struct cmd_line { char *line; } CMD_LINE; -void free_val_spec_list(VAL_SPEC_LIST *vl) -{ - if (!vl) return; - if (vl->name) free(vl->name); - if (vl->val) free(vl->val); - free(vl); - -} - /* * Some routines to handle lines of info in the command files */ @@ -2663,9 +2200,6 @@ struct cmd_line *get_cmd_line(int fd) * * If it parsed OK, return the <value-name> as a string, and the * value type and value-string in parameters. - * - * The value name can be empty. There can only be one empty name in - * a list of values. A value of - removes the value entirely. */ char *dup_str(char *s, int len) @@ -2724,8 +2258,6 @@ int parse_value_type(char *tstr) return REG_TYPE_REGSZ; else if (strcmp(tstr, "REG_MULTI_SZ") == 0) return REG_TYPE_MULTISZ; - else if (strcmp(tstr, "-") == 0) - return REG_TYPE_DELETE; return 0; } @@ -2763,16 +2295,14 @@ char *parse_value(struct cmd_line *cl, int *vtype, char **val) while (*tstr == ' ') tstr++; /* Skip leading white space */ p2 = strchr(p2, ':'); - if (p2) { - *p2 = 0; p2++; /* split on the : */ - } + if (!p2) goto error; + + *p2 = 0; p2++; /* split on the : */ *vtype = parse_value_type(tstr); if (!vtype) goto error; - if (!p2 || !*p2) return nstr; - /* Now, parse the value string. It should return a newly malloc'd string */ while (*p2 == ' ') p2++; /* Skip leading space */ @@ -2937,7 +2467,6 @@ void trim_trailing_spaces(struct cmd_line *cl) * value ::= <value-name>=<value-type>':'<value-string> * <value-name> is some path, possibly enclosed in quotes ... * We alctually look for the next key to terminate a previous key - * if <value-type> == '-', then it is a delete type. */ CMD *regedit4_get_cmd(int fd) { @@ -2953,19 +2482,8 @@ CMD *regedit4_get_cmd(int fd) cmd->cmd = CMD_NONE; cmd->key = NULL; - cmd->val_count = 0; cmd->val_spec_list = cmd->val_spec_last = NULL; - while ((cl = get_cmd_line(fd))) { - - /* - * If it is an empty command line, and we already have a key - * then exit from here ... FIXME: Clean up the parser - */ - - if (cl->line_len == 0 && cmd->key) { - free_cmd_line(cl); - break; - } + while (cl = get_cmd_line(fd)) { strip_comment(cl); /* remove anything beyond a comment char */ trim_trailing_spaces(cl); @@ -2996,7 +2514,6 @@ CMD *regedit4_get_cmd(int fd) vl = (struct val_spec_list *)malloc(sizeof(struct val_spec_list)); if (!vl) goto error; vl->next = NULL; - vl->val = NULL; vl->name = parse_value(cl, &vl->type, &vl->val); if (!vl->name) goto error; if (cmd->val_spec_list == NULL) { @@ -3168,7 +2685,7 @@ int print_key(const char *path, char *name, char *class_name, int root, int terminal, int vals) { - if (full_print || terminal) fprintf(stdout, "[%s%s]\n", path, name); + /*if (terminal)*/ fprintf(stdout, "[%s%s]\n", path, name); return 1; } @@ -3320,10 +2837,9 @@ int print_val(const char *path, char *val_name, int val_type, int data_len, void usage(void) { - fprintf(stderr, "Usage: editreg [-f] [-v] [-p] [-k] [-s] [-c <command-file>] <registryfile>\n"); + fprintf(stderr, "Usage: editreg [-v] [-p] [-k] [-s] [-c <command-file>] <registryfile>\n"); fprintf(stderr, "Version: 0.1\n\n"); fprintf(stderr, "\n\t-v\t sets verbose mode"); - fprintf(stderr, "\n\t-f\t sets full print mode where non-terminals are printed"); fprintf(stderr, "\n\t-p\t prints the registry"); fprintf(stderr, "\n\t-s\t prints security descriptors"); fprintf(stderr, "\n\t-c <command-file>\t specifies a command file"); @@ -3341,7 +2857,6 @@ int main(int argc, char *argv[]) char *cmd_file_name = NULL; char *out_file_name = NULL; CMD_FILE *cmd_file = NULL; - DOM_SID *lsid; if (argc < 2) { usage(); @@ -3352,7 +2867,7 @@ int main(int argc, char *argv[]) * Now, process the arguments */ - while ((opt = getopt(argc, argv, "fspvko:O:c:")) != EOF) { + while ((opt = getopt(argc, argv, "spvko:c:")) != EOF) { switch (opt) { case 'c': commands = 1; @@ -3360,29 +2875,11 @@ int main(int argc, char *argv[]) regf_opt += 2; break; - case 'f': - full_print = 1; - regf_opt++; - break; - case 'o': out_file_name = optarg; regf_opt += 2; break; - case 'O': - def_owner_sid_str = strdup(optarg); - regf_opt += 2; - if (!string_to_sid(&lsid, def_owner_sid_str)) { - fprintf(stderr, "Default Owner SID: %s is incorrectly formatted\n", - def_owner_sid_str); - free(def_owner_sid_str); - def_owner_sid_str = NULL; - } - else - nt_delete_sid(lsid); - break; - case 'p': print_keys++; regf_opt++; @@ -3390,7 +2887,6 @@ int main(int argc, char *argv[]) case 's': print_security++; - full_print++; regf_opt++; break; @@ -3410,17 +2906,6 @@ int main(int argc, char *argv[]) } } - /* - * We only want to complain about the lack of a default owner SID if - * we need one. This approximates that need - */ - if (!def_owner_sid_str) { - def_owner_sid_str = "S-1-5-21-1-2-3-4"; - if (out_file_name || verbose) - fprintf(stderr, "Warning, default owner SID not set. Setting to %s\n", - def_owner_sid_str); - } - if ((regf = nt_create_regf()) == NULL) { fprintf(stderr, "Could not create registry object: %s\n", strerror(errno)); exit(2); @@ -3461,41 +2946,10 @@ int main(int argc, char *argv[]) * Now, apply the requests to the tree ... */ switch (cmd->cmd) { - case CMD_ADD_KEY: { - REG_KEY *tmp = NULL; - - tmp = nt_find_key_by_name(regf->root, cmd->key); - - /* If we found it, apply the other bits, else create such a key */ - - if (!tmp) - tmp = nt_add_reg_key(regf, cmd->key, True); - - if (tmp) { - - } - - while (cmd->val_count) { - VAL_SPEC_LIST *val = cmd->val_spec_list; - VAL_KEY *reg_val = NULL; - - if (val->type == REG_TYPE_DELETE) { - reg_val = nt_delete_reg_value(tmp, val -> name); - if (reg_val) nt_delete_val_key(reg_val); - } - else { - reg_val = nt_add_reg_value(tmp, val->name, val->type, - val->val); - } - - cmd->val_spec_list = val->next; - free_val_spec_list(val); - cmd->val_count--; - } + case CMD_ADD_KEY: break; - } - + case CMD_DEL_KEY: /* * Any value does not matter ... |