static int dict_free(struct label_dict *dict);
static const char *dict_get_label(const struct label_dict *dict, int id);
static ssize_t dict_add_label(struct label_dict *dict, int *id, const char *src);
+static int accesses_print(struct smack_accesses *handle, int clear,
+ int load_fd, int change_fd, int use_long, int add_lf);
int smack_accesses_new(struct smack_accesses **accesses)
{
int smack_accesses_save(struct smack_accesses *handle, int fd)
{
- struct smack_rule *rule = handle->first;
- char allow_str[ACC_LEN + 1];
- char deny_str[ACC_LEN + 1];
- FILE *file;
- int ret;
- int newfd;
-
- newfd = dup(fd);
- if (newfd == -1)
- return -1;
-
- file = fdopen(newfd, "w");
- if (file == NULL) {
- close(newfd);
- return -1;
- }
-
- while (rule) {
- access_code_to_str(rule->allow_code, allow_str);
-
- if (rule->deny_code != -1) /* modify? */ {
- access_code_to_str(rule->deny_code, deny_str);
-
- ret = fprintf(file, "%s %s %s %s\n",
- dict_get_label(handle->dict, rule->subject_id),
- dict_get_label(handle->dict, rule->object_id),
- allow_str, deny_str);
- } else {
- ret = fprintf(file, "%s %s %s\n",
- dict_get_label(handle->dict, rule->subject_id),
- dict_get_label(handle->dict, rule->object_id),
- allow_str);
- }
-
- if (ret < 0) {
- fclose(file);
- return -1;
- }
-
- rule = rule->next;
- }
-
- fclose(file);
- return 0;
+ return accesses_print(handle, 0, fd, fd, 1, 1);
}
int smack_accesses_apply(struct smack_accesses *handle)
static int accesses_apply(struct smack_accesses *handle, int clear)
{
- char buf[LOAD_LEN + 1];
- char allow_str[ACC_LEN + 1];
- char deny_str[ACC_LEN + 1];
- struct smack_rule *rule;
int ret;
- int fd;
int load_fd;
int change_fd;
int load2 = 1;
goto err_out;
}
+ ret = accesses_print(handle, clear, load_fd, change_fd, load2, 0);
+
+err_out:
+ if (load_fd >= 0)
+ close(load_fd);
+ if (change_fd >= 0)
+ close(change_fd);
+ return ret;
+}
+
+static int accesses_print(struct smack_accesses *handle, int clear,
+ int load_fd, int change_fd, int use_long, int add_lf)
+{
+ char buf[LOAD_LEN + 1];
+ char allow_str[ACC_LEN + 1];
+ char deny_str[ACC_LEN + 1];
+ struct smack_rule *rule;
+ int ret;
+ int fd;
+ int i;
+ int cnt;
+
for (rule = handle->first; rule != NULL; rule = rule->next) {
/* Fail immediately without doing any further processing
if modify rules are not supported. */
- if (rule->deny_code >= 0 && change_fd < 0) {
- ret = -1;
- goto err_out;
- }
+ if (rule->deny_code >= 0 && change_fd < 0)
+ return -1;
access_code_to_str(clear ? 0 : rule->allow_code, allow_str);
access_code_to_str(rule->deny_code, deny_str);
fd = change_fd;
- ret = snprintf(buf, LOAD_LEN + 1, KERNEL_MODIFY_FORMAT,
+ cnt = snprintf(buf, LOAD_LEN + 1, KERNEL_MODIFY_FORMAT,
dict_get_label(handle->dict, rule->subject_id),
dict_get_label(handle->dict, rule->object_id),
allow_str,
deny_str);
} else {
fd = load_fd;
- if (load2)
- ret = snprintf(buf, LOAD_LEN + 1, KERNEL_LONG_FORMAT,
+ if (use_long)
+ cnt = snprintf(buf, LOAD_LEN + 1, KERNEL_LONG_FORMAT,
dict_get_label(handle->dict, rule->subject_id),
dict_get_label(handle->dict, rule->object_id),
allow_str);
else {
if (rule->subject_len > SHORT_LABEL_LEN ||
- rule->object_len > SHORT_LABEL_LEN) {
- ret = -1;
- goto err_out;
- }
+ rule->object_len > SHORT_LABEL_LEN)
+ return -1;
- ret = snprintf(buf, LOAD_LEN + 1, KERNEL_SHORT_FORMAT,
+ cnt = snprintf(buf, LOAD_LEN + 1, KERNEL_SHORT_FORMAT,
dict_get_label(handle->dict, rule->subject_id),
dict_get_label(handle->dict, rule->object_id),
allow_str);
}
}
- if (ret < 0) {
- ret = -1;
- goto err_out;
- }
-
- ret = write(fd, buf, ret);
- if (ret < 0) {
- ret = -1;
- goto err_out;
+ if (cnt < 0)
+ return -1;
+ if (add_lf)
+ buf[cnt++] = '\n';
+
+ for (i = 0; i < cnt; ) {
+ ret = write(fd, buf + i, cnt - i);
+ if (ret == -1) {
+ if (errno == EINTR)
+ continue;
+ return -1;
+ }
+ i += ret;
}
}
- ret = 0;
-err_out:
- if (load_fd >= 0)
- close(load_fd);
- if (change_fd >= 0)
- close(change_fd);
- return ret;
+ return 0;
}
static inline ssize_t get_label(char *dest, const char *src)