static int acl_attribute_update_acl(struct mailbox_transaction_context *t, const char *key, const struct mail_attribute_value *value) { const char *value_str, *id, *const *rights, *error; struct acl_rights_update update; /* for now allow only dsync to update ACLs this way. if this check is removed, it should be replaced by a setting, since some admins may still have configured Dovecot using dovecot-acl files directly that they don't want users to update. and in any case ACL_STORAGE_RIGHT_ADMIN must be checked then. */ if (!t->box->storage->user->dsyncing) { mail_storage_set_error(t->box->storage, MAIL_ERROR_PERM, MAIL_ERRSTR_NO_PERMISSION); return -1; } if (mailbox_attribute_value_to_string(t->box->storage, value, &value_str) < 0) return -1; memset(&update, 0, sizeof(update)); update.modify_mode = ACL_MODIFY_MODE_REPLACE; update.neg_modify_mode = ACL_MODIFY_MODE_REPLACE; update.last_change = value->last_change; id = key + strlen(MAILBOX_ATTRIBUTE_PREFIX_ACL); rights = value_str == NULL ? NULL : t_strsplit(value_str, " "); if (acl_rights_update_import(&update, id, rights, &error) < 0) { mail_storage_set_error(t->box->storage, MAIL_ERROR_PARAMS, error); return -1; } /* FIXME: this should actually be done only at commit().. */ return acl_mailbox_update_acl(t, &update); }
static int sieve_attribute_set_active(struct mail_storage *storage, struct sieve_storage *svstorage, const struct mail_attribute_value *value) { const char *scriptname; struct sieve_script *script; int ret; if (mailbox_attribute_value_to_string(storage, value, &scriptname) < 0) return -1; if (scriptname == NULL) { /* don't affect non-link active script */ if ((ret=sieve_storage_is_singular(svstorage)) != 0) { if (ret < 0) { mail_storage_set_internal_error(storage); return -1; } return 0; } /* deactivate current script */ if (sieve_storage_deactivate(svstorage, value->last_change) < 0) { mail_storage_set_critical(storage, "Failed to deactivate Sieve: %s", sieve_storage_get_last_error(svstorage, NULL)); return -1; } return 0; } i_assert(scriptname[0] == MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_LINK); scriptname++; /* activate specified script */ script = sieve_storage_open_script(svstorage, scriptname, NULL); ret = script == NULL ? -1 : sieve_script_activate(script, value->last_change); if (ret < 0) { mail_storage_set_critical(storage, "Failed to activate Sieve script '%s': %s", scriptname, sieve_storage_get_last_error(svstorage, NULL)); } if (script != NULL) sieve_script_unref(&script); sieve_storage_set_modified(svstorage, value->last_change); return ret; }
int index_storage_attribute_set(struct mailbox_transaction_context *t, enum mail_attribute_type type, const char *key, const struct mail_attribute_value *value, bool internal_attribute) { struct dict_transaction_context *dtrans; const char *mailbox_prefix; bool pvt = type == MAIL_ATTRIBUTE_TYPE_PRIVATE; time_t ts = value->last_change != 0 ? value->last_change : ioloop_time; int ret = 0; if (!internal_attribute && !MAILBOX_ATTRIBUTE_KEY_IS_USER_ACCESSIBLE(key)) { mail_storage_set_error(t->box->storage, MAIL_ERROR_PARAMS, "Internal attributes cannot be changed directly"); return -1; } if (index_storage_attribute_get_dict_trans(t, type, &dtrans, &mailbox_prefix) < 0) return -1; T_BEGIN { const char *prefixed_key = key_get_prefixed(type, mailbox_prefix, key); const char *value_str; if (mailbox_attribute_value_to_string(t->box->storage, value, &value_str) < 0) { ret = -1; } else if (value_str != NULL) { dict_set(dtrans, prefixed_key, value_str); mail_index_attribute_set(t->itrans, pvt, key, ts, strlen(value_str)); } else { dict_unset(dtrans, prefixed_key); mail_index_attribute_unset(t->itrans, pvt, key, ts); } } T_END; return ret; }