diff options
-rw-r--r-- | source3/utils/editreg.c | 197 |
1 files changed, 146 insertions, 51 deletions
diff --git a/source3/utils/editreg.c b/source3/utils/editreg.c index b8670eb8b6..9d155a9a11 100644 --- a/source3/utils/editreg.c +++ b/source3/utils/editreg.c @@ -312,6 +312,22 @@ Hope this helps.... (Although it was "fun" for me to uncover this things, #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))) + static int verbose = 0; static int print_security = 0; @@ -337,6 +353,8 @@ 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; @@ -345,7 +363,7 @@ typedef struct reg_key_s { struct reg_key_s *owner; struct key_list_s *sub_keys; struct val_list_s *values; - struct key_sec_desc_s *security; + KEY_SEC_DESC *security; } REG_KEY; /* @@ -403,12 +421,12 @@ typedef struct sec_desc_s { #define SEC_DESC_RES 1 #define SEC_DESC_OCU 2 -typedef struct key_sec_desc_s { +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 @@ -817,6 +835,7 @@ 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); } @@ -982,14 +1001,55 @@ 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 strng_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; +} + +/* * 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. @@ -1001,8 +1061,24 @@ KEY_SEC_DESC *nt_inherit_security(REG_KEY *key) return key->security; } -REG_KEY *nt_add_reg_key(REG_KEY *key, char *name, int create); -REG_KEY *nt_add_reg_key_list(REG_KEY *key, char * name, int create) +/* + * 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; + + + return tsec; +} + +REG_KEY *nt_add_reg_subkey(REGF *regf, REG_KEY *key, char *name, int create); + +/* + * Add a sub-key + */ +REG_KEY *nt_add_reg_key_list(REGF *regf, REG_KEY *key, char * name, int create) { int i; REG_KEY *ret = NULL, *tmp = NULL; @@ -1021,7 +1097,7 @@ REG_KEY *nt_add_reg_key_list(REG_KEY *key, char * name, int create) } for (i = 0; i < list->key_count; i++) { - if ((ret = nt_add_reg_key(list->keys[i], name, create))) + if ((ret = nt_add_reg_subkey(regf, key, name, create))) return ret; } @@ -1069,6 +1145,7 @@ REG_KEY *nt_add_reg_key_list(REG_KEY *key, char * name, int create) 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 by with * anything passed in on the command line @@ -1078,7 +1155,7 @@ REG_KEY *nt_add_reg_key_list(REG_KEY *key, char * name, int create) list->keys[list->key_count - 1] = tmp; if (c2) { - ret = nt_add_reg_key(key, c2, True); + ret = nt_add_reg_subkey(regf, key, c2, True); } if (lname) free(lname); @@ -1091,17 +1168,27 @@ REG_KEY *nt_add_reg_key_list(REG_KEY *key, char * name, int create) return NULL; } -REG_KEY *nt_add_reg_key(REG_KEY *key, char *name, int create) +REG_KEY *nt_add_reg_subkey(REGF *regf, REG_KEY *key, char *name, int create) +{ + + 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) { char *lname = NULL, *c1, *c2; - REG_KEY * tmp; + REG_KEY * tmp = NULL, *key = NULL; /* * 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 (!key || !name || !*name) return NULL; + if (!regf || !name || !*name) return NULL; lname = strdup(name); if (!lname) return NULL; @@ -1114,38 +1201,45 @@ REG_KEY *nt_add_reg_key(REG_KEY *key, char *name, int create) } /* - * 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 the root does not exist, create it and make it equal to the + * first component ... */ - if (strcmp(c1, key->name) != 0) - goto error; - - tmp = nt_add_reg_key_list(key, c2, True); + 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, key->name) != 0) + goto error; + } + + tmp = nt_add_reg_key_list(regf, key, c2, 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 @@ -1177,22 +1271,6 @@ REG_KEY *nt_add_reg_key(REG_KEY *key, 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)) @@ -3030,10 +3108,27 @@ int main(int argc, char *argv[]) * Now, apply the requests to the tree ... */ switch (cmd->cmd) { - case CMD_ADD_KEY: + case CMD_ADD_KEY: { + REG_KEY *tmp = NULL; - break; + 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) { + + } + + break; + } + case CMD_DEL_KEY: /* * Any value does not matter ... |