#endif
}
+struct wim_security_data *
+new_wim_security_data()
+{
+ return CALLOC(1, sizeof(struct wim_security_data));
+}
+
/*
* Reads the security data from the metadata resource.
*
/* Frees a security descriptor index set. */
void
-destroy_sd_set(struct sd_set *sd_set)
+destroy_sd_set(struct sd_set *sd_set, bool rollback)
{
+ if (rollback) {
+ struct wim_security_data *sd = sd_set->sd;
+ int32_t i;
+ for (i = sd_set->orig_num_entries; i < sd->num_entries; i++)
+ FREE(sd->descriptors[i]);
+ sd->num_entries = sd_set->orig_num_entries;
+ }
free_sd_tree(sd_set->rb_root.rb_node);
}
/* Inserts a a new node into the security descriptor index tree. */
-static void
+static bool
insert_sd_node(struct sd_set *set, struct sd_node *new)
{
struct rb_root *root = &set->rb_root;
else if (cmp > 0)
p = &((*p)->rb_right);
else
- wimlib_assert(0); /* Duplicate SHA1 message digest */
+ return false; /* Duplicate security descriptor */
}
rb_link_node(&new->rb_node, rb_parent, p);
rb_insert_color(&new->rb_node, root);
+ return true;
}
/* Returns the index of the security descriptor having a SHA1 message digest of
u64 *sizes;
u8 *descr_copy;
struct wim_security_data *sd;
+ bool bret;
sha1_buffer((const u8*)descriptor, size, hash);
sd->num_entries++;
DEBUG("There are now %d security descriptors", sd->num_entries);
sd->total_length += size + sizeof(sd->sizes[0]);
- insert_sd_node(sd_set, new);
+ bret = insert_sd_node(sd_set, new);
+ wimlib_assert(bret);
return new->security_id;
out_free_descr:
FREE(descr_copy);
out:
return -1;
}
+
+/* Initialize a `struct sd_set' mapping from SHA1 message digests of security
+ * descriptors to indices into the security descriptors table of the WIM image
+ * (security IDs). */
+int
+init_sd_set(struct sd_set *sd_set, struct wim_security_data *sd)
+{
+ int ret;
+
+ sd_set->sd = sd;
+ sd_set->rb_root.rb_node = NULL;
+
+ /* Remember the original number of security descriptors so that newly
+ * added ones can be rolled back if needed. */
+ sd_set->orig_num_entries = sd->num_entries;
+ for (int32_t i = 0; i < sd->num_entries; i++) {
+ struct sd_node *new;
+
+ new = MALLOC(sizeof(struct sd_node));
+ if (!new) {
+ ret = WIMLIB_ERR_NOMEM;
+ goto out_destroy_sd_set;
+ }
+ sha1_buffer(sd->descriptors[i], sd->sizes[i], new->hash);
+ new->security_id = i;
+ if (!insert_sd_node(sd_set, new))
+ FREE(new); /* Ignore duplicate security descriptor */
+ }
+ ret = 0;
+ goto out;
+out_destroy_sd_set:
+ destroy_sd_set(sd_set, false);
+out:
+ return ret;
+}