srvd_boolean_t srvd_service_nss_passwd_request_name_get(const srvd_service_request_t *request, char **name) { srvd_protocol_packet_field_t *field = NULL; srvd_protocol_packet_field_entry_t *entry = NULL; SRVD_RETURN_FALSE_UNLESS(request); SRVD_RETURN_FALSE_UNLESS(request->packet.field_count > 0); SRVD_RETURN_FALSE_UNLESS(name); SRVD_RETURN_FALSE_UNLESS(*name == NULL); srvd_protocol_packet_field_get_first(&request->packet, &field); if(field->type != SRVD_SERVICE_NSS_PASSWD_REQUEST_NAME) { SRVD_LOG_ERROR("srvd_service_nss_passwd_request_name_get: Invalid packet type"); return SRVD_FALSE; } SRVD_RETURN_FALSE_UNLESS(field->entry_count == 1); srvd_protocol_packet_field_entry_get_first(field, &entry); *name = malloc(entry->size); if(*name == NULL) { SRVD_LOG_ERROR("srvd_service_nss_passwd_request_name_get: Unable to allocate memory for name"); return SRVD_FALSE; } strncpy(*name, entry->data, entry->size); (*name)[entry->size - 1] = '\0'; return SRVD_TRUE; }
srvd_boolean_t srvd_service_nss_passwd_request_entities_get(const srvd_service_request_t *request, int32_t *offset) { srvd_protocol_packet_field_t *field = NULL; srvd_protocol_packet_field_entry_t *entry = NULL; SRVD_RETURN_FALSE_UNLESS(request); SRVD_RETURN_FALSE_UNLESS(request->packet.field_count > 0); SRVD_RETURN_FALSE_UNLESS(offset); srvd_protocol_packet_field_get_first(&request->packet, &field); if(field->type != SRVD_SERVICE_NSS_PASSWD_REQUEST_ENTITIES) { SRVD_LOG_ERROR("srvd_service_nss_passwd_request_entites_get: Invalid packet type"); return SRVD_FALSE; } SRVD_RETURN_FALSE_UNLESS(field->entry_count == 1); srvd_protocol_packet_field_entry_get_first(field, &entry); return srvd_protocol_packet_field_entry_get_uint32(entry, (uint32_t *)offset); }
srvd_boolean_t srvd_server_unsock_execute(srvd_server_unsock_t *server) { srvd_boolean_t status = SRVD_TRUE; SRVD_RETURN_FALSE_UNLESS(server); server->monitor.executing = SRVD_TRUE; if(bind(server->socket, (struct sockaddr *)&server->endpoint, sizeof(struct sockaddr_un)) == -1) { SRVD_LOG_ERROR("srvd_server_unsock_execute: Unable to bind to socket at \"%s\"", server->endpoint.sun_path); return SRVD_FALSE; } if(listen(server->socket, server->conf.queue_size) == -1) { SRVD_LOG_ERROR("srvd_server_unsock_execute: Unable to listen on bound socket"); return SRVD_FALSE; } for(;;) { int client = accept(server->socket, NULL, 0); if(client == -1) { SRVD_LOG_WARNING("srvd_server_unsock_execute: Error accept()ing client"); continue; } srvd_service_request_t request; srvd_service_response_t response; srvd_service_request_initialize(&request); srvd_service_response_initialize(&response); if(!_srvd_server_unsock_read(client, &request.packet)) { SRVD_LOG_WARNING("srvd_server_unsock_execute: Could not read data from client"); goto _srvd_server_unsock_execute_client_error; } srvd_protocol_packet_field_t *field = NULL; if(!srvd_protocol_packet_field_get_first(&request.packet, &field)) { /* Nothing valid? */ SRVD_LOG_WARNING("srvd_server_unsock_execute: Invalid packet"); goto _srvd_server_unsock_execute_client_error; } /* Okay, let's see if we have a matching handler for the request. */ srvd_server_service_handler_pt handler = NULL; if(srvd_server_service_get(&server->monitor, field->type, &handler)) { handler(&request, &response); /* Get the response status and inject it into the list of fields. */ srvd_protocol_packet_field_insert_uint16(&response.packet, SRVD_PROTOCOL_STATUS, response.status); } else /* Nope -- unavailable. */ srvd_protocol_packet_field_insert_uint16(&response.packet, SRVD_PROTOCOL_STATUS, SRVD_SERVICE_RESPONSE_UNAVAIL); if(!_srvd_server_unsock_write(client, &response.packet)) { SRVD_LOG_WARNING("srvd_server_unsock_execute: Could not write data to client"); goto _srvd_server_unsock_execute_client_error; } _srvd_server_unsock_execute_client_error: srvd_service_request_finalize(&request); srvd_service_response_finalize(&response); if(client >= 0) close(client); } close(server->socket); server->monitor.executing = SRVD_FALSE; return status; }