Ods::pag* CryptoManager::encrypt(ISC_STATUS* sv, Ods::pag* from, Ods::pag* to) { // Code calling us is not ready to process exceptions correctly // Therefore use old (status vector based) method try { if (crypt && cryptPlugin && Ods::pag_crypt_page[from->pag_type % (pag_max + 1)]) { to[0] = from[0]; LocalStatus status; cryptPlugin->encrypt(&status, dbb.dbb_page_size - sizeof(Ods::pag), &from[1], &to[1]); if (!status.isSuccess()) { memcpy(sv, status.get(), sizeof(ISC_STATUS_ARRAY)); return NULL; } to->pag_flags |= Ods::crypted_page; return to; } else { from->pag_flags &= ~Ods::crypted_page; return from; } } catch (const Exception& ex) { ex.stuff_exception(sv); } return NULL; }
void setCharSet(thread_db* tdbb, EngineAttachmentInfo* attInfo, T* obj) { attachment->att_charset = attInfo->adminCharSet; if (!obj) return; Utf8 charSetName[MAX_SQL_IDENTIFIER_SIZE]; { // scope Attachment::Checkout attCout(attachment, FB_FUNCTION); LocalStatus status; obj->getCharSet(&status, attInfo->context, charSetName, MAX_SQL_IDENTIFIER_LEN); status.check(); charSetName[MAX_SQL_IDENTIFIER_LEN] = '\0'; } USHORT charSetId; if (!MET_get_char_coll_subtype(tdbb, &charSetId, reinterpret_cast<const UCHAR*>(charSetName), static_cast<USHORT>(strlen(charSetName)))) { status_exception::raise(Arg::Gds(isc_charset_not_found) << Arg::Str(charSetName)); } attachment->att_charset = charSetId; }
bool CryptoManager::decrypt(ISC_STATUS* sv, Ods::pag* page) { // Code calling us is not ready to process exceptions correctly // Therefore use old (status vector based) method try { if (page->pag_flags & Ods::crypted_page) { if (!cryptPlugin) { // We are invoked from shared cache manager, i.e. no valid attachment in tdbb // Therefore create system temporary attachment like in crypt thread to be able to work with locks UserId user; user.usr_user_name = "(Crypt plugin loader)"; Jrd::Attachment* const attachment = Jrd::Attachment::create(&dbb); RefPtr<SysAttachment> jAtt(new SysAttachment(attachment)); attachment->att_interface = jAtt; attachment->att_filename = dbb.dbb_filename; attachment->att_user = &user; BackgroundContextHolder tdbb(&dbb, attachment, sv, FB_FUNCTION); // Lock crypt state takeStateLock(tdbb); Header hdr(tdbb, LCK_read); crypt = hdr->hdr_flags & Ods::hdr_encrypted; process = hdr->hdr_flags & Ods::hdr_crypt_process; if (crypt || process) { loadPlugin(hdr->hdr_crypt_plugin); } if (!cryptPlugin) { (Arg::Gds(isc_decrypt_error)).raise(); return false; } } LocalStatus status; cryptPlugin->decrypt(&status, dbb.dbb_page_size - sizeof(Ods::pag), &page[1], &page[1]); if (!status.isSuccess()) { memcpy(sv, status.get(), sizeof(ISC_STATUS_ARRAY)); return false; } } return true; } catch (const Exception& ex) { ex.stuff_exception(sv); } return false; }
void ExtEngineManager::Trigger::execute(thread_db* tdbb, ExternalTrigger::Action action, record_param* oldRpb, record_param* newRpb) const { EngineAttachmentInfo* attInfo = extManager->getEngineAttachment(tdbb, engine); ContextManager<ExternalTrigger> ctxManager(tdbb, attInfo, trigger, CallerName(obj_trigger, trg->name)); // ASF: Using Array instead of HalfStaticArray to not need to do alignment hacks here. Array<UCHAR> oldMsg; Array<UCHAR> newMsg; if (oldRpb) setValues(tdbb, oldMsg, oldRpb); if (newRpb) setValues(tdbb, newMsg, newRpb); { // scope Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION); LocalStatus status; trigger->execute(&status, attInfo->context, action, (oldMsg.hasData() ? oldMsg.begin() : NULL), (newMsg.hasData() ? newMsg.begin() : NULL)); status.check(); } if (newRpb) { // Move data back from the message to the record. Record* record = newRpb->rpb_record; UCHAR* p = newMsg.begin(); for (unsigned i = 0; i < format->fmt_count / 2u; ++i) { USHORT fieldPos = fieldsPos[i]; dsc target; bool readonly = !EVL_field(newRpb->rpb_relation, record, fieldPos, &target) && target.dsc_address && !(target.dsc_flags & DSC_null); if (!readonly) { SSHORT* nullSource = (SSHORT*) (p + (IPTR) format->fmt_desc[i * 2 + 1].dsc_address); if (*nullSource == 0) { dsc source = format->fmt_desc[i * 2]; source.dsc_address += (IPTR) p; MOV_move(tdbb, &source, &target); record->clearNull(fieldPos); } else record->setNull(fieldPos); } } } }
void TraceManager::update_session(const TraceSession& session) { // if this session is already known, nothing to do FB_SIZE_T pos; if (trace_sessions.find(session.ses_id, pos)) { return; } // if this session is not from administrator, it may trace connections // only created by the same user if (!(session.ses_flags & trs_admin)) { if (attachment) { if (!attachment->att_user || attachment->att_user->usr_user_name != session.ses_user) return; } else if (service) { if (session.ses_user != service->getUserName()) return; } else { // failed attachment attempts traced by admin trace only return; } } MasterInterfacePtr master; for (FactoryInfo* info = factories->begin(); info != factories->end(); ++info) { TraceInitInfoImpl attachInfo(session, attachment, filename); LocalStatus status; ITracePlugin* plugin = info->factory->trace_create(&status, &attachInfo); if (plugin) { plugin->addRef(); SessionInfo sesInfo; sesInfo.plugin = plugin; sesInfo.factory_info = info; sesInfo.ses_id = session.ses_id; trace_sessions.add(sesInfo); trace_needs |= info->factory->trace_needs(); } else if (status.getStatus() & IStatus::FB_HAS_ERRORS) { string header; header.printf("Trace plugin %s returned error on call trace_create.", info->name); iscLogStatus(header.c_str(), &status); } } }
void ExtEngineManager::Function::execute(thread_db* tdbb, UCHAR* inMsg, UCHAR* outMsg) const { EngineAttachmentInfo* attInfo = extManager->getEngineAttachment(tdbb, engine); ContextManager<ExternalFunction> ctxManager(tdbb, attInfo, function, (udf->getName().package.isEmpty() ? CallerName(obj_udf, udf->getName().identifier) : CallerName(obj_package_header, udf->getName().package))); Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION); LocalStatus status; function->execute(&status, attInfo->context, inMsg, outMsg); status.check(); }
ExtEngineManager::Trigger::Trigger(thread_db* tdbb, MemoryPool& pool, ExtEngineManager* aExtManager, ExternalEngine* aEngine, RoutineMetadata* aMetadata, ExternalTrigger* aTrigger, const Jrd::Trigger* aTrg) : extManager(aExtManager), engine(aEngine), metadata(aMetadata), trigger(aTrigger), trg(aTrg), fieldsPos(pool), database(tdbb->getDatabase()) { dsc shortDesc; shortDesc.makeShort(0); jrd_rel* relation = trg->relation; if (relation) { GenericMap<Left<MetaName, USHORT> > fieldsMap; for (FB_SIZE_T i = 0; i < relation->rel_fields->count(); ++i) { jrd_fld* field = (*relation->rel_fields)[i]; if (field) fieldsMap.put(field->fld_name, (USHORT) i); } format = Routine::createFormat(pool, metadata->triggerFields, false); LocalStatus status; for (unsigned i = 0; i < format->fmt_count / 2u; ++i) { const char* fieldName = metadata->triggerFields->getField(&status, i); status.check(); USHORT pos; if (!fieldsMap.get(fieldName, pos)) fb_assert(false); else fieldsPos.add(pos); } } }
void CryptoManager::KeyHolderPlugins::init(IDbCryptPlugin* crypt) { MutexLockGuard g(holdersMutex, FB_FUNCTION); Firebird::HalfStaticArray<Firebird::IKeyHolderPlugin*, 64> holdersVector; unsigned int length = knownHolders.getCount(); IKeyHolderPlugin** vector = holdersVector.getBuffer(length); for (unsigned i = 0; i < length; ++i) { vector[i] = knownHolders[i].getPlugin(); } LocalStatus st; crypt->setKey(&st, length, vector); if (!st.isSuccess()) { status_exception::raise(st.get()); } }
void UserManagement::commit() { for (unsigned i = 0; i < managers.getCount(); ++i) { IManagement* manager = managers[i].second; if (manager) { LocalStatus status; CheckStatusWrapper statusWrapper(&status); manager->commit(&statusWrapper); if (status.getState() & IStatus::STATE_ERRORS) status_exception::raise(&statusWrapper); PluginManagerInterfacePtr()->releasePlugin(manager); managers[i].second = NULL; } } }
ExtEngineManager::ResultSet::ResultSet(thread_db* tdbb, UCHAR* inMsg, UCHAR* outMsg, const ExtEngineManager::Procedure* aProcedure) : procedure(aProcedure), attachment(tdbb->getAttachment()), firstFetch(true) { attInfo = procedure->extManager->getEngineAttachment(tdbb, procedure->engine); ContextManager<ExternalProcedure> ctxManager(tdbb, attInfo, procedure->procedure, (procedure->prc->getName().package.isEmpty() ? CallerName(obj_procedure, procedure->prc->getName().identifier) : CallerName(obj_package_header, procedure->prc->getName().package))); charSet = attachment->att_charset; Attachment::Checkout attCout(attachment, FB_FUNCTION); LocalStatus status; resultSet = procedure->procedure->open(&status, attInfo->context, inMsg, outMsg); status.check(); }
void ExtEngineManager::setupAdminCharSet(thread_db* tdbb, ExternalEngine* engine, EngineAttachmentInfo* attInfo) { ContextManager<ExternalFunction> ctxManager(tdbb, attInfo, CS_UTF8); Utf8 charSetName[MAX_SQL_IDENTIFIER_SIZE] = "NONE"; LocalStatus status; engine->open(&status, attInfo->context, charSetName, MAX_SQL_IDENTIFIER_LEN); status.check(); charSetName[MAX_SQL_IDENTIFIER_LEN] = '\0'; if (!MET_get_char_coll_subtype(tdbb, &attInfo->adminCharSet, reinterpret_cast<const UCHAR*>(charSetName), static_cast<USHORT>(strlen(charSetName)))) { status_exception::raise( Arg::Gds(isc_charset_not_found) << Arg::Str(charSetName)); } }
bool ExtEngineManager::ResultSet::fetch(thread_db* tdbb) { bool wasFirstFetch = firstFetch; firstFetch = false; if (!resultSet) return wasFirstFetch; ContextManager<ExternalProcedure> ctxManager(tdbb, attInfo, charSet, (procedure->prc->getName().package.isEmpty() ? CallerName(obj_procedure, procedure->prc->getName().identifier) : CallerName(obj_package_header, procedure->prc->getName().package))); fb_assert(attachment == tdbb->getAttachment()); Attachment::Checkout attCout(attachment, FB_FUNCTION); LocalStatus status; bool ret = resultSet->fetch(&status); status.check(); return ret; }
void CryptoManager::KeyHolderPlugins::attach(Attachment* att, Config* config) { MutexLockGuard g(holdersMutex, FB_FUNCTION); for (GetPlugins<IKeyHolderPlugin> keyControl(PluginType::KeyHolder, FB_KEYHOLDER_PLUGIN_VERSION, upInfo, config); keyControl.hasData(); keyControl.next()) { IKeyHolderPlugin* keyPlugin = keyControl.plugin(); LocalStatus st; if (keyPlugin->keyCallback(&st, att->att_crypt_callback) == 1) { // holder accepted attachment's key HolderAttachments* ha = NULL; for (unsigned i = 0; i < knownHolders.getCount(); ++i) { if (knownHolders[i] == keyPlugin) { ha = &knownHolders[i]; break; } } if (!ha) { ha = &(knownHolders.add()); ha->setPlugin(keyPlugin); } ha->registerAttachment(att); break; // Do not need >1 key from attachment to single DB } else if (!st.isSuccess()) { status_exception::raise(st.get()); } } }
IManagement* UserManagement::registerManager(Auth::Get& getPlugin, const char* plugName) { IManagement* manager = getPlugin.plugin(); fb_assert(manager); // Start new management plugin ... LocalStatus status; CheckStatusWrapper statusWrapper(&status); UserIdInfo idInfo(att); manager->start(&statusWrapper, &idInfo); if (status.getState() & IStatus::STATE_ERRORS) { status_exception::raise(&statusWrapper); } // ... and store it in cache Manager& m(managers.add()); m.first = plugName; m.second = manager; manager->addRef(); return manager; }
void ExtEngineManager::makeProcedure(thread_db* tdbb, jrd_prc* prc, const MetaName& engine, const string& entryPoint, const string& body) { string entryPointTrimmed = entryPoint; entryPointTrimmed.trim(); EngineAttachmentInfo* attInfo = getEngineAttachment(tdbb, engine); ContextManager<ExternalProcedure> ctxManager(tdbb, attInfo, attInfo->adminCharSet, (prc->getName().package.isEmpty() ? CallerName(obj_procedure, prc->getName().identifier) : CallerName(obj_package_header, prc->getName().package))); ///MemoryPool& pool = *tdbb->getDefaultPool(); MemoryPool& pool = *getDefaultMemoryPool(); AutoPtr<RoutineMetadata> metadata(FB_NEW(pool) RoutineMetadata(pool)); metadata->package = prc->getName().package; metadata->name = prc->getName().identifier; metadata->entryPoint = entryPointTrimmed; metadata->body = body; metadata->inputParameters = Routine::createMetadata(prc->getInputFields()); metadata->outputParameters = Routine::createMetadata(prc->getOutputFields()); LocalStatus status; RefPtr<IMetadataBuilder> inBuilder(metadata->inputParameters->getBuilder(&status)); status.check(); inBuilder->release(); RefPtr<IMetadataBuilder> outBuilder(metadata->outputParameters->getBuilder(&status)); status.check(); outBuilder->release(); ExternalProcedure* externalProcedure; { // scope Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION); externalProcedure = attInfo->engine->makeProcedure(&status, attInfo->context, metadata, inBuilder, outBuilder); status.check(); if (!externalProcedure) { status_exception::raise( Arg::Gds(isc_eem_proc_not_returned) << prc->getName().toString() << engine); } metadata->inputParameters = inBuilder->getMetadata(&status); status.check(); metadata->outputParameters = outBuilder->getMetadata(&status); status.check(); } try { prc->setInputFormat(Routine::createFormat(pool, metadata->inputParameters, false)); prc->setOutputFormat(Routine::createFormat(pool, metadata->outputParameters, false)); prc->setExternal(FB_NEW(getPool()) Procedure(tdbb, this, attInfo->engine, metadata.release(), externalProcedure, prc)); } catch (...) { Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION); externalProcedure->dispose(); throw; } }
void ExtEngineManager::makeProcedure(thread_db* tdbb, CompilerScratch* csb, jrd_prc* prc, const MetaName& engine, const string& entryPoint, const string& body) { string entryPointTrimmed = entryPoint; entryPointTrimmed.trim(); EngineAttachmentInfo* attInfo = getEngineAttachment(tdbb, engine); ContextManager<ExternalProcedure> ctxManager(tdbb, attInfo, attInfo->adminCharSet, (prc->getName().package.isEmpty() ? CallerName(obj_procedure, prc->getName().identifier) : CallerName(obj_package_header, prc->getName().package))); ///MemoryPool& pool = *tdbb->getDefaultPool(); MemoryPool& pool = *getDefaultMemoryPool(); AutoPtr<RoutineMetadata> metadata(FB_NEW(pool) RoutineMetadata(pool)); metadata->package = prc->getName().package; metadata->name = prc->getName().identifier; metadata->entryPoint = entryPointTrimmed; metadata->body = body; metadata->inputParameters = Routine::createMetadata(prc->getInputFields()); metadata->outputParameters = Routine::createMetadata(prc->getOutputFields()); LocalStatus status; RefPtr<IMetadataBuilder> inBuilder(REF_NO_INCR, metadata->inputParameters->getBuilder(&status)); status.check(); RefPtr<IMetadataBuilder> outBuilder(REF_NO_INCR, metadata->outputParameters->getBuilder(&status)); status.check(); ExternalProcedure* externalProcedure; { // scope Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION); externalProcedure = attInfo->engine->makeProcedure(&status, attInfo->context, metadata, inBuilder, outBuilder); status.check(); if (!externalProcedure) { status_exception::raise( Arg::Gds(isc_eem_proc_not_returned) << prc->getName().toString() << engine); } metadata->inputParameters = inBuilder->getMetadata(&status); status.check(); metadata->outputParameters = outBuilder->getMetadata(&status); status.check(); } prc->setInputFormat(Routine::createFormat(pool, metadata->inputParameters, false)); prc->setOutputFormat(Routine::createFormat(pool, metadata->outputParameters, true)); try { prc->setExternal(FB_NEW(getPool()) Procedure(tdbb, this, attInfo->engine, metadata.release(), externalProcedure, prc)); CompoundStmtNode* mainNode = FB_NEW(getPool()) CompoundStmtNode(getPool()); ExtMessageNode* inMessageNode = prc->getInputFields().hasData() ? FB_NEW(getPool()) ExtMessageNode(tdbb, getPool(), csb, 0, prc->getInputFields(), prc->getInputFormat()) : NULL; if (inMessageNode) mainNode->statements.add(inMessageNode); ExtMessageNode* outMessageNode = FB_NEW(getPool()) ExtMessageNode(tdbb, getPool(), csb, 1, prc->getOutputFields(), prc->getOutputFormat()); mainNode->statements.add(outMessageNode); ExtInitOutputNode* initOutputNode = FB_NEW(getPool()) ExtInitOutputNode( tdbb, getPool(), csb, outMessageNode); mainNode->statements.add(initOutputNode); ReceiveNode* receiveNode = inMessageNode ? FB_NEW(getPool()) ReceiveNode(getPool()) : NULL; if (inMessageNode) { receiveNode->message = inMessageNode; receiveNode->statement = FB_NEW(getPool()) ExtValidationNode( getPool(), inMessageNode, true, true); mainNode->statements.add(receiveNode); } ExtProcedureNode* extProcedureNode = FB_NEW(getPool()) ExtProcedureNode(getPool(), receiveNode, prc->getExternal()); mainNode->statements.add(extProcedureNode); extProcedureNode->message = outMessageNode; extProcedureNode->statement = FB_NEW(getPool()) ExtValidationNode( getPool(), outMessageNode, true, false); JrdStatement* statement = prc->getStatement(); PAR_preparsed_node(tdbb, NULL, mainNode, NULL, &csb, &statement, false, 0); prc->setStatement(statement); } catch (...) { Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION); externalProcedure->dispose(); throw; } }
void ExtEngineManager::makeTrigger(thread_db* tdbb, CompilerScratch* csb, Jrd::Trigger* trg, const MetaName& engine, const string& entryPoint, const string& body, ExternalTrigger::Type type) { string entryPointTrimmed = entryPoint; entryPointTrimmed.trim(); EngineAttachmentInfo* attInfo = getEngineAttachment(tdbb, engine); ContextManager<ExternalTrigger> ctxManager(tdbb, attInfo, attInfo->adminCharSet, CallerName(obj_trigger, trg->name)); ///MemoryPool& pool = *tdbb->getDefaultPool(); MemoryPool& pool = *getDefaultMemoryPool(); AutoPtr<RoutineMetadata> metadata(FB_NEW(pool) RoutineMetadata(pool)); metadata->name = trg->name; metadata->entryPoint = entryPointTrimmed; metadata->body = body; metadata->triggerType = type; jrd_rel* relation = trg->relation; if (relation) { metadata->triggerTable = relation->rel_name; MsgMetadata* fieldsMsg = new MsgMetadata; metadata->triggerFields = fieldsMsg; Format* relFormat = relation->rel_current_format; for (FB_SIZE_T i = 0; i < relation->rel_fields->count(); ++i) { jrd_fld* field = (*relation->rel_fields)[i]; if (field) fieldsMsg->addItem(field->fld_name, !field->fld_not_null, relFormat->fmt_desc[i]); } } LocalStatus status; RefPtr<IMetadataBuilder> fieldsBuilder(REF_NO_INCR, relation ? metadata->triggerFields->getBuilder(&status) : NULL); if (relation) { status.check(); } ExternalTrigger* externalTrigger; { // scope Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION); LocalStatus status; externalTrigger = attInfo->engine->makeTrigger(&status, attInfo->context, metadata, fieldsBuilder); status.check(); if (!externalTrigger) { status_exception::raise( Arg::Gds(isc_eem_trig_not_returned) << trg->name << engine); } if (relation) { metadata->triggerFields = fieldsBuilder->getMetadata(&status); status.check(); } } try { trg->extTrigger = FB_NEW(getPool()) Trigger(tdbb, pool, this, attInfo->engine, metadata.release(), externalTrigger, trg); CompoundStmtNode* mainNode = FB_NEW(getPool()) CompoundStmtNode(getPool()); ExtTriggerNode* extTriggerNode = FB_NEW(getPool()) ExtTriggerNode(getPool(), trg->extTrigger); mainNode->statements.add(extTriggerNode); PAR_preparsed_node(tdbb, trg->relation, mainNode, NULL, &csb, &trg->statement, true, 0); } catch (...) { Attachment::Checkout attCout(tdbb->getAttachment(), FB_FUNCTION); externalTrigger->dispose(); throw; } }
void UserManagement::execute(USHORT id) { if (id >= commands.getCount()) { status_exception::raise(Arg::Gds(isc_random) << "Wrong job id passed to UserManagement::execute()"); } if (!commands[id]) return; // Already executed Auth::UserData* command = commands[id]; IManagement* manager = getManager(command->plugin.c_str()); if (!manager) return; // Already commited LocalStatus status; CheckStatusWrapper statusWrapper(&status); if (command->attr.entered() || command->op == Auth::ADDMOD_OPER) { Auth::StackUserData cmd; cmd.op = Auth::DIS_OPER; cmd.user.set(&statusWrapper, command->userName()->get()); check(&statusWrapper); cmd.user.setEntered(&statusWrapper, 1); check(&statusWrapper); OldAttributes oldAttributes; int ret = manager->execute(&statusWrapper, &cmd, &oldAttributes); if (ret == 0 || status.getErrors()[1] != isc_missing_data_structures) checkSecurityResult(ret, &status, command->userName()->get(), command->operation()); else statusWrapper.init(); if (command->op == Auth::ADDMOD_OPER) command->op = oldAttributes.present ? Auth::MOD_OPER : Auth::ADD_OPER; if (command->attr.entered()) { ConfigFile ocf(ConfigFile::USE_TEXT, oldAttributes.value.c_str(), ConfigFile::NO_COMMENTS); ConfigFile::Parameters::const_iterator old(ocf.getParameters().begin()); ConfigFile::Parameters::const_iterator oldEnd(ocf.getParameters().end()); ConfigFile ccf(ConfigFile::USE_TEXT, command->attr.get(), ConfigFile::NO_COMMENTS); ConfigFile::Parameters::const_iterator cur(ccf.getParameters().begin()); ConfigFile::Parameters::const_iterator curEnd(ccf.getParameters().end()); // Dup check ConfigFile::KeyType prev; while (cur != curEnd) { if (cur->name == prev) (Arg::Gds(isc_dup_attribute) << cur->name).raise(); prev = cur->name; ++cur; } cur = ccf.getParameters().begin(); string merged; while (old != oldEnd && cur != curEnd) { if (old->name == cur->name) { merge(merged, cur); ++old; ++cur; } else if (old->name < cur->name) { merge(merged, old); ++old; } else { merge(merged, cur); ++cur; } } while (cur != curEnd) { merge(merged, cur); ++cur; } while (old != oldEnd) { merge(merged, old); ++old; } if (merged.hasData()) { command->attr.set(&statusWrapper, merged.c_str()); check(&statusWrapper); } else { command->attr.setEntered(&statusWrapper, 0); check(&statusWrapper); command->attr.setSpecified(1); command->attr.set(&statusWrapper, ""); check(&statusWrapper); } } } if (command->op == Auth::ADD_OPER) { if (!command->pass.entered()) Arg::PrivateDyn(291).raise(); if (!command->act.entered()) { command->act.set(&statusWrapper, 1); check(&statusWrapper); command->act.setEntered(&statusWrapper, 1); check(&statusWrapper); } } int errcode = manager->execute(&statusWrapper, command, NULL); checkSecurityResult(errcode, &status, command->userName()->get(), command->operation()); delete commands[id]; commands[id] = NULL; }