int acl_rights_update_import(struct acl_rights_update *update, const char *id, const char *const *rights, const char **error_r) { ARRAY_TYPE(const_string) dest_rights, dest_neg_rights, *dest; unsigned int i, j; if (acl_identifier_parse(id, &update->rights) < 0) { *error_r = t_strdup_printf("Invalid ID: %s", id); return -1; } if (rights == NULL) { update->modify_mode = ACL_MODIFY_MODE_CLEAR; update->neg_modify_mode = ACL_MODIFY_MODE_CLEAR; return 0; } t_array_init(&dest_rights, 8); t_array_init(&dest_neg_rights, 8); for (i = 0; rights[i] != NULL; i++) { const char *right = rights[i]; if (right[0] != '-') dest = &dest_rights; else { right++; dest = &dest_neg_rights; } if (strcmp(right, "all") != 0) { if (*right == ':') { /* non-standard right */ right++; array_append(dest, &right, 1); } else if (is_standard_right(right)) { array_append(dest, &right, 1); } else { *error_r = t_strdup_printf("Invalid right '%s'", right); return -1; } } else { for (j = 0; all_mailbox_rights[j] != NULL; j++) array_append(dest, &all_mailbox_rights[j], 1); } } if (array_count(&dest_rights) > 0) { array_append_zero(&dest_rights); update->rights.rights = array_idx(&dest_rights, 0); } else if (update->modify_mode == ACL_MODIFY_MODE_REPLACE) { update->modify_mode = ACL_MODIFY_MODE_CLEAR; } if (array_count(&dest_neg_rights) > 0) { array_append_zero(&dest_neg_rights); update->rights.neg_rights = array_idx(&dest_neg_rights, 0); } else if (update->neg_modify_mode == ACL_MODIFY_MODE_REPLACE) { update->neg_modify_mode = ACL_MODIFY_MODE_CLEAR; } return 0; }
int acl_rights_parse_line(const char *line, pool_t pool, struct acl_rights *rights_r, const char **error_r) { const char *id_str, *const *right_names, *error = NULL; if (*line == '\0' || *line == '#') return 0; /* <id> [<imap acls>] [:<named acls>] */ if (*line == '"') { line++; if (str_unescape_next(&line, &id_str) < 0 || (line[0] != ' ' && line[0] != '\0')) { *error_r = "Invalid quoted ID"; return -1; } if (line[0] == ' ') line++; } else { id_str = line; line = strchr(id_str, ' '); if (line == NULL) line = ""; else id_str = t_strdup_until(id_str, line++); } memset(rights_r, 0, sizeof(*rights_r)); right_names = acl_right_names_parse(pool, line, &error); if (*id_str != '-') rights_r->rights = right_names; else { id_str++; rights_r->neg_rights = right_names; } if (acl_identifier_parse(id_str, rights_r) < 0) error = t_strdup_printf("Unknown ID '%s'", id_str); if (error != NULL) { *error_r = error; return -1; } rights_r->identifier = p_strdup(pool, rights_r->identifier); return 0; }
static int acl_attribute_get_acl(struct mailbox *box, const char *key, struct mail_attribute_value *value_r) { struct acl_object *aclobj = acl_mailbox_get_aclobj(box); struct acl_object_list_iter *iter; struct acl_rights rights, wanted_rights; const char *id; int ret; memset(value_r, 0, sizeof(*value_r)); if (!box->storage->user->dsyncing) { mail_storage_set_error(box->storage, MAIL_ERROR_PERM, MAIL_ERRSTR_NO_PERMISSION); return -1; } /* set last_change for all ACL objects, even if they don't exist (because they could have been removed by the last change, and dsync can use this information) */ (void)acl_object_last_changed(aclobj, &value_r->last_change); memset(&wanted_rights, 0, sizeof(wanted_rights)); id = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_ACL); if (acl_identifier_parse(id, &wanted_rights) < 0) { mail_storage_set_error(box->storage, MAIL_ERROR_PARAMS, t_strdup_printf("Invalid ID: %s", id)); return -1; } iter = acl_object_list_init(aclobj); while ((ret = acl_object_list_next(iter, &rights)) > 0) { if (!rights.global && rights.id_type == wanted_rights.id_type && null_strcmp(rights.identifier, wanted_rights.identifier) == 0) { value_r->value = acl_rights_export(&rights); break; } } if (ret < 0) mail_storage_set_internal_error(box->storage); acl_object_list_deinit(&iter); return ret; }