int ast_sip_location_delete_contact(struct ast_sip_contact *contact) { void *contact_status_obj; contact_status_obj = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), CONTACT_STATUS, ast_sorcery_object_get_id(contact)); if (contact_status_obj) { ast_sorcery_delete(ast_sip_get_sorcery(), contact_status_obj); ao2_ref(contact_status_obj, -1); } return ast_sorcery_delete(ast_sip_get_sorcery(), contact); }
/*! \brief Scheduler function which deletes a contact */ static int contact_expiration_expire(const void *data) { struct contact_expiration *expiration = (void *) data; expiration->sched = -1; /* This will end up invoking the deleted observer callback, which will perform the unlinking and such */ ast_sorcery_delete(ast_sip_get_sorcery(), expiration->contact); ao2_ref(expiration, -1); return 0; }
static void delete_contact_status(const struct ast_sip_contact *contact) { struct ast_sip_contact_status *status = ast_sorcery_retrieve_by_id( ast_sip_get_sorcery(), CONTACT_STATUS, ast_sorcery_object_get_id(contact)); if (!status) { return; } ast_sorcery_delete(ast_sip_get_sorcery(), status); ao2_ref(status, -1); }
/*! \brief Callback function which deletes a contact if it has expired or sets up auto-expiry */ static int contact_expiration_setup(void *obj, void *arg, int flags) { struct ast_sip_contact *contact = obj; int expires = MAX(0, ast_tvdiff_ms(contact->expiration_time, ast_tvnow())); if (!expires) { ast_sorcery_delete(ast_sip_get_sorcery(), contact); } else { contact_expiration_observer_created(contact); } return 0; }
static void *bucket_http_wizard_retrieve_id(const struct ast_sorcery *sorcery, void *data, const char *type, const char *id) { struct ast_bucket_file *bucket_file; if (strcmp(type, "file")) { ast_log(LOG_WARNING, "Failed to create storage: invalid bucket type '%s'\n", type); return NULL; } if (ast_strlen_zero(id)) { ast_log(LOG_WARNING, "Failed to create storage: no URI\n"); return NULL; } bucket_file = ast_bucket_file_alloc(id); if (!bucket_file) { ast_log(LOG_WARNING, "Failed to create storage for '%s'\n", id); return NULL; } if (ast_bucket_file_temporary_create(bucket_file)) { ast_log(LOG_WARNING, "Failed to create temporary storage for '%s'\n", id); ast_sorcery_delete(sorcery, bucket_file); ao2_ref(bucket_file, -1); return NULL; } if (bucket_file_run_curl(bucket_file)) { ast_sorcery_delete(sorcery, bucket_file); ao2_ref(bucket_file, -1); return NULL; } return bucket_file; }
void ast_ari_asterisk_delete_object(struct ast_variable *headers, struct ast_ari_asterisk_delete_object_args *args, struct ast_ari_response *response) { RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref); RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup); RAII_VAR(void *, sorcery_obj, NULL, ao2_cleanup); sorcery = ast_sorcery_retrieve_by_module_name(args->config_class); if (!sorcery) { ast_ari_response_error( response, 404, "Not Found", "configClass '%s' not found", args->config_class); return; } object_type = ast_sorcery_get_object_type(sorcery, args->object_type); if (!object_type) { ast_ari_response_error( response, 404, "Not Found", "objectType '%s' not found", args->object_type); return; } sorcery_obj = ast_sorcery_retrieve_by_id(sorcery, args->object_type, args->id); if (!sorcery_obj) { ast_ari_response_error( response, 404, "Not Found", "Object with id '%s' not found", args->id); return; } if (ast_sorcery_delete(sorcery, sorcery_obj)) { ast_ari_response_error( response, 403, "Forbidden", "Could not delete object with id '%s'", args->id); return; } ast_ari_response_no_content(response); }
/*! * \internal * \brief A contact has been deleted remove status tracking. */ static void contact_deleted(const void *obj) { struct ast_sip_contact *contact = (struct ast_sip_contact *) obj; struct ast_sip_contact_status *status; unschedule_qualify(contact); status = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), CONTACT_STATUS, ast_sorcery_object_get_id(contact)); if (!status) { return; } if (ast_sorcery_delete(ast_sip_get_sorcery(), status)) { ast_log(LOG_ERROR, "Unable to delete ast_sip_contact_status for contact %s\n", contact->uri); } ao2_ref(status, -1); }
int ast_sip_location_delete_contact(struct ast_sip_contact *contact) { return ast_sorcery_delete(ast_sip_get_sorcery(), contact); }
/*! * \internal * \brief Delete a mailbox. * \since 12.1.0 * * \param mailbox Mailbox object to delete from sorcery. * * \return Nothing */ static void mwi_mailbox_delete(struct ast_mwi_mailbox_object *mailbox) { ast_sorcery_delete(mwi_sorcery, mailbox); }
static int rx_task(void *data) { static const pj_str_t USER_AGENT = { "User-Agent", 10 }; RAII_VAR(struct rx_task_data *, task_data, data, ao2_cleanup); RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup); int added = 0, updated = 0, deleted = 0; pjsip_contact_hdr *contact_hdr = NULL; struct registrar_contact_details details = { 0, }; pjsip_tx_data *tdata; const char *aor_name = ast_sorcery_object_get_id(task_data->aor); RAII_VAR(struct ast_str *, path_str, NULL, ast_free); struct ast_sip_contact *response_contact; char *user_agent = NULL; pjsip_user_agent_hdr *user_agent_hdr; pjsip_expires_hdr *expires_hdr; /* Retrieve the current contacts, we'll need to know whether to update or not */ contacts = ast_sip_location_retrieve_aor_contacts(task_data->aor); /* So we don't count static contacts against max_contacts we prune them out from the container */ ao2_callback(contacts, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, registrar_prune_static, NULL); if (registrar_validate_contacts(task_data->rdata, contacts, task_data->aor, &added, &updated, &deleted)) { /* The provided Contact headers do not conform to the specification */ pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 400, NULL, NULL, NULL); ast_sip_report_failed_acl(task_data->endpoint, task_data->rdata, "registrar_invalid_contacts_provided"); ast_log(LOG_WARNING, "Failed to validate contacts in REGISTER request from '%s'\n", ast_sorcery_object_get_id(task_data->endpoint)); return PJ_TRUE; } if (registrar_validate_path(task_data, &path_str)) { /* Ensure that intervening proxies did not make invalid modifications to the request */ pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 420, NULL, NULL, NULL); ast_log(LOG_WARNING, "Invalid modifications made to REGISTER request from '%s' by intervening proxy\n", ast_sorcery_object_get_id(task_data->endpoint)); return PJ_TRUE; } if ((MAX(added - deleted, 0) + (!task_data->aor->remove_existing ? ao2_container_count(contacts) : 0)) > task_data->aor->max_contacts) { /* Enforce the maximum number of contacts */ pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 403, NULL, NULL, NULL); ast_sip_report_failed_acl(task_data->endpoint, task_data->rdata, "registrar_attempt_exceeds_maximum_configured_contacts"); ast_log(LOG_WARNING, "Registration attempt from endpoint '%s' to AOR '%s' will exceed max contacts of %u\n", ast_sorcery_object_get_id(task_data->endpoint), ast_sorcery_object_get_id(task_data->aor), task_data->aor->max_contacts); return PJ_TRUE; } if (!(details.pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Contact Comparison", 256, 256))) { pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 500, NULL, NULL, NULL); return PJ_TRUE; } user_agent_hdr = pjsip_msg_find_hdr_by_name(task_data->rdata->msg_info.msg, &USER_AGENT, NULL); if (user_agent_hdr) { size_t alloc_size = pj_strlen(&user_agent_hdr->hvalue) + 1; user_agent = ast_alloca(alloc_size); ast_copy_pj_str(user_agent, &user_agent_hdr->hvalue, alloc_size); } /* Iterate each provided Contact header and add, update, or delete */ while ((contact_hdr = pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_CONTACT, contact_hdr ? contact_hdr->next : NULL))) { int expiration; char contact_uri[PJSIP_MAX_URL_SIZE]; RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup); if (contact_hdr->star) { /* A star means to unregister everything, so do so for the possible contacts */ ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, registrar_delete_contact, (void *)aor_name); break; } if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)) { /* This registrar only currently supports sip: and sips: URI schemes */ continue; } expiration = registrar_get_expiration(task_data->aor, contact_hdr, task_data->rdata); details.uri = pjsip_uri_get_uri(contact_hdr->uri); pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri)); if (!(contact = ao2_callback(contacts, OBJ_UNLINK, registrar_find_contact, &details))) { /* If they are actually trying to delete a contact that does not exist... be forgiving */ if (!expiration) { ast_verb(3, "Attempted to remove non-existent contact '%s' from AOR '%s' by request\n", contact_uri, aor_name); continue; } if (ast_sip_location_add_contact(task_data->aor, contact_uri, ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1)), path_str ? ast_str_buffer(path_str) : NULL, user_agent, task_data->endpoint)) { ast_log(LOG_ERROR, "Unable to bind contact '%s' to AOR '%s'\n", contact_uri, aor_name); continue; } ast_verb(3, "Added contact '%s' to AOR '%s' with expiration of %d seconds\n", contact_uri, aor_name, expiration); ast_test_suite_event_notify("AOR_CONTACT_ADDED", "Contact: %s\r\n" "AOR: %s\r\n" "Expiration: %d\r\n" "UserAgent: %s", contact_uri, aor_name, expiration, user_agent); } else if (expiration) { struct ast_sip_contact *contact_update; contact_update = ast_sorcery_copy(ast_sip_get_sorcery(), contact); if (!contact_update) { ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n", contact->uri, expiration); continue; } contact_update->expiration_time = ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1)); contact_update->qualify_frequency = task_data->aor->qualify_frequency; contact_update->authenticate_qualify = task_data->aor->authenticate_qualify; if (path_str) { ast_string_field_set(contact_update, path, ast_str_buffer(path_str)); } if (user_agent) { ast_string_field_set(contact_update, user_agent, user_agent); } if (ast_sip_location_update_contact(contact_update)) { ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n", contact->uri, expiration); ast_sorcery_delete(ast_sip_get_sorcery(), contact); continue; } ast_debug(3, "Refreshed contact '%s' on AOR '%s' with new expiration of %d seconds\n", contact_uri, aor_name, expiration); ast_test_suite_event_notify("AOR_CONTACT_REFRESHED", "Contact: %s\r\n" "AOR: %s\r\n" "Expiration: %d\r\n" "UserAgent: %s", contact_uri, aor_name, expiration, contact_update->user_agent); ao2_cleanup(contact_update); } else { /* We want to report the user agent that was actually in the removed contact */ user_agent = ast_strdupa(contact->user_agent); ast_sip_location_delete_contact(contact); ast_verb(3, "Removed contact '%s' from AOR '%s' due to request\n", contact_uri, aor_name); ast_test_suite_event_notify("AOR_CONTACT_REMOVED", "Contact: %s\r\n" "AOR: %s\r\n" "UserAgent: %s", contact_uri, aor_name, user_agent); } } pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool); /* If the AOR is configured to remove any existing contacts that have not been updated/added as a result of this REGISTER * do so */ if (task_data->aor->remove_existing) { ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, registrar_delete_contact, NULL); } /* Update the contacts as things will probably have changed */ ao2_cleanup(contacts); contacts = ast_sip_location_retrieve_aor_contacts(task_data->aor); response_contact = ao2_callback(contacts, 0, NULL, NULL); /* Send a response containing all of the contacts (including static) that are present on this AOR */ if (ast_sip_create_response(task_data->rdata, 200, response_contact, &tdata) != PJ_SUCCESS) { ao2_cleanup(response_contact); return PJ_TRUE; } ao2_cleanup(response_contact); /* Add the date header to the response, some UAs use this to set their date and time */ registrar_add_date_header(tdata); ao2_callback(contacts, 0, registrar_add_contact, tdata); if ((expires_hdr = pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) { expires_hdr = pjsip_expires_hdr_create(tdata->pool, registrar_get_expiration(task_data->aor, NULL, task_data->rdata)); pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)expires_hdr); } ast_sip_send_stateful_response(task_data->rdata, tdata, task_data->endpoint); return PJ_TRUE; }