summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/utils/editreg.c149
1 files changed, 121 insertions, 28 deletions
diff --git a/source3/utils/editreg.c b/source3/utils/editreg.c
index 4fc9d1b7c7..0a526e5abe 100644
--- a/source3/utils/editreg.c
+++ b/source3/utils/editreg.c
@@ -393,9 +393,14 @@ typedef struct sec_desc_s {
ACL *sacl, *dacl;
} SEC_DESC;
+#define SEC_DESC_NON 0
+#define SEC_DESC_RES 1
+#define SEC_DESC_OCU 2
+
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;
@@ -706,6 +711,15 @@ typedef struct sk_struct {
char sec_desc[1];
} SK_HDR;
+typedef struct sec_desc_rec {
+ WORD rev;
+ WORD type;
+ DWORD owner_off;
+ DWORD group_off;
+ DWORD sacl_off;
+ DWORD dacl_off;
+} REG_SEC_DESC;
+
typedef struct hash_struct {
DWORD nk_off;
char hash[4];
@@ -897,6 +911,45 @@ int valid_regf_hdr(REGF_HDR *regf_hdr)
* We allocate the map in increments of 10 entries.
*/
+/*
+ * Create a new entry in the map, and increase the size of the map if needed
+ */
+
+SK_MAP **alloc_sk_map_entry(REGF *regf, KEY_SEC_DESC *tmp, int sk_off)
+{
+ if (!regf->sk_map) { /* Allocate a block of 10 */
+ regf->sk_map = (SK_MAP **)malloc(sizeof(SK_MAP) * 10);
+ if (!regf->sk_map) {
+ free(tmp);
+ return NULL;
+ }
+ regf->sk_map_size = 10;
+ regf->sk_count = 1;
+ (*regf->sk_map)[0].sk_off = sk_off;
+ (*regf->sk_map)[0].key_sec_desc = tmp;
+ }
+ else { /* Simply allocate a new slot, unless we have to expand the list */
+ int index = regf->sk_count;
+ if (regf->sk_count == regf->sk_map_size) {
+ regf->sk_map = (SK_MAP **)realloc(regf->sk_map, regf->sk_map_size + 10);
+ if (!regf->sk_map) {
+ free(tmp);
+ return NULL;
+ }
+ index++;
+ }
+ (*regf->sk_map)[index].sk_off = sk_off;
+ (*regf->sk_map)[index].key_sec_desc = tmp;
+ regf->sk_count++;
+ }
+ return regf->sk_map;
+}
+
+/*
+ * Search for a KEY_SEC_DESC in the sk_map, but dont create one if not
+ * found
+ */
+
KEY_SEC_DESC *lookup_sec_key(SK_MAP *sk_map, int count, int sk_off)
{
int i;
@@ -914,9 +967,42 @@ KEY_SEC_DESC *lookup_sec_key(SK_MAP *sk_map, int count, int sk_off)
}
+/*
+ * Allocate a KEY_SEC_DESC if we can't find one in the map
+ */
+
+KEY_SEC_DESC *lookup_create_sec_key(REGF *regf, SK_MAP *sk_map, int sk_off)
+{
+ KEY_SEC_DESC *tmp = lookup_sec_key(*regf->sk_map, regf->sk_count, sk_off);
+
+ if (tmp) {
+ return tmp;
+ }
+ else { /* Allocate a new one */
+ tmp = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC));
+ if (!tmp) {
+ return NULL;
+ }
+ tmp->state = SEC_DESC_RES;
+ if (!alloc_sk_map_entry(regf, tmp, sk_off)) {
+ return NULL;
+ }
+ return tmp;
+ }
+}
+
+SEC_DESC *process_sec_desc(REGF *regf, REG_SEC_DESC *sec_desc)
+{
+ SEC_DESC *tmp = NULL;
+
+ return tmp;
+}
+
KEY_SEC_DESC *process_sk(REGF *regf, SK_HDR *sk_hdr, int sk_off, int size)
{
KEY_SEC_DESC *tmp = NULL;
+ int sk_next_off, sk_prev_off;
+ REG_SEC_DESC *sec_desc;
if (!sk_hdr) return NULL;
@@ -932,53 +1018,60 @@ KEY_SEC_DESC *process_sk(REGF *regf, SK_HDR *sk_hdr, int sk_off, int size)
* use that
*/
- if ((tmp = lookup_sec_key(*regf->sk_map, regf->sk_count, sk_off)) != NULL) {
+ if (((tmp = lookup_sec_key(*regf->sk_map, regf->sk_count, sk_off)) != NULL)
+ && (tmp->state == SEC_DESC_OCU)) {
tmp->ref_cnt++;
return tmp;
}
+ /* Here, we have an item in the map that has been reserved, or tmp==NULL. */
+
+ assert(tmp && tmp->state != SEC_DESC_NON);
+
/*
* Now, allocate a KEY_SEC_DESC, and parse the structure here, and add the
* new KEY_SEC_DESC to the mapping structure, since the offset supplied is
* the actual offset of structure. The same offset will be used by all
* all future references to this structure
+ * We chould put all this unpleasantness in a function.
*/
- tmp = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC));
- if (!tmp) return NULL;
-
- tmp->ref_cnt++;
-
- if (!regf->sk_map) { /* Allocate a block of 10 */
- regf->sk_map = (SK_MAP **)malloc(sizeof(SK_MAP) * 10);
- if (!regf->sk_map) {
- free(tmp);
+ if (!tmp) {
+ tmp = (KEY_SEC_DESC *)malloc(sizeof(KEY_SEC_DESC));
+ if (!tmp) return NULL;
+ bzero(tmp, sizeof(KEY_SEC_DESC));
+
+ /*
+ * Allocate an entry in the SK_MAP ...
+ */
+
+ if (!alloc_sk_map_entry(regf, tmp, sk_off)) {
return NULL;
}
- regf->sk_map_size = 10;
- regf->sk_count = 1;
- (*regf->sk_map)[0].sk_off = sk_off;
- (*regf->sk_map)[0].key_sec_desc = tmp;
- }
- else { /* Simply allocate a new slot, unless we have to expand the list */
- int index = regf->sk_count;
- if (regf->sk_count == regf->sk_map_size) {
- regf->sk_map = (SK_MAP **)realloc(regf->sk_map, regf->sk_map_size + 10);
- if (!regf->sk_map) {
- free(tmp);
- return NULL;
- }
- index++;
- }
- (*regf->sk_map)[index].sk_off = sk_off;
- (*regf->sk_map)[index].key_sec_desc = tmp;
- regf->sk_count++;
}
+ tmp->ref_cnt++;
+ tmp->state = SEC_DESC_OCU;
+
/*
* Now, process the actual sec desc and plug the values in
*/
+ sec_desc = (REG_SEC_DESC *)&sk_hdr->sec_desc[0];
+ tmp->sec_desc = process_sec_desc(regf, sec_desc);
+
+ /*
+ * Now forward and back links. Here we allocate an entry in the sk_map
+ * if it does not exist, and mark it reserved
+ */
+
+ sk_prev_off = IVAL(&sk_hdr->prev_off);
+ tmp->prev = lookup_create_sec_key(regf, *regf->sk_map, sk_prev_off);
+ assert(tmp->prev != NULL);
+ sk_next_off = IVAL(&sk_hdr->prev_off);
+ tmp->next = lookup_create_sec_key(regf, *regf->sk_map, sk_next_off);
+ assert(tmp->next != NULL);
+
return tmp;
}