krb5_error_code krb5_db2_lock(krb5_context context, int lockmode) { if (!inited(context)) return KRB5_KDB_DBNOTINITED; return ctx_lock(context, context->dal_handle->db_context, lockmode); }
bool VideoOutputOpenGL::SetDeinterlacingEnabled(bool enable) { (void) enable; if (!gl_videochain || !gl_context) return false; OpenGLLocker ctx_lock(gl_context); if (enable) { if (m_deintfiltername.isEmpty()) return SetupDeinterlace(enable); if (m_deintfiltername.contains("opengl")) { if (gl_videochain->GetDeinterlacer().isEmpty()) return SetupDeinterlace(enable); } else if (!m_deintfiltername.contains("opengl")) { // make sure opengl deinterlacing is disabled gl_videochain->SetDeinterlacing(false); if (!m_deintFiltMan || !m_deintFilter) return VideoOutput::SetupDeinterlace(enable); } } MoveResize(); gl_videochain->SetDeinterlacing(enable); m_deinterlacing = enable; return m_deinterlacing; }
bool VideoOutputOpenGLVAAPI::CreateVAAPIContext(QSize size) { // FIXME During a video stream change this is called from the decoder // thread - which breaks all other efforts to remove non-UI thread // access to the OpenGL context. There is no obvious fix however - if we // don't delete and re-create the VAAPI decoder context immediately then // the decoder fails and playback exits. OpenGLLocker ctx_lock(gl_context); if (m_ctx) DeleteVAAPIContext(); m_ctx = new VAAPIContext(video_codec_id); if (m_ctx && m_ctx->CreateDisplay(size) && m_ctx->CreateBuffers()) { int num_buffers = m_ctx->GetNumBuffers(); const QSize video_dim = window.GetActualVideoDim(); bool ok = true; for (int i = 0; i < num_buffers; i++) { ok &= vbuffers.CreateBuffer(video_dim.width(), video_dim.height(), i, m_ctx->GetVideoSurface(i), FMT_VAAPI); } InitPictureAttributes(); return ok; } LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create VAAPI context."); errorState = kError_Unknown; return false; }
krb5_error_code krb5_db2_get_principal(krb5_context context, krb5_const_principal searchfor, unsigned int flags, krb5_db_entry **entry) { krb5_db2_context *dbc; krb5_error_code retval; DB *db; DBT key, contents; krb5_data keydata, contdata; int trynum, dbret; *entry = NULL; if (!inited(context)) return KRB5_KDB_DBNOTINITED; dbc = context->dal_handle->db_context; for (trynum = 0; trynum < KRB5_DB2_MAX_RETRY; trynum++) { if ((retval = ctx_lock(context, dbc, KRB5_LOCKMODE_SHARED))) { if (dbc->db_nb_locks) return (retval); sleep(1); continue; } break; } if (trynum == KRB5_DB2_MAX_RETRY) return KRB5_KDB_DB_INUSE; /* XXX deal with wildcard lookups */ retval = krb5_encode_princ_dbkey(context, &keydata, searchfor); if (retval) goto cleanup; key.data = keydata.data; key.size = keydata.length; db = dbc->db; dbret = (*db->get)(db, &key, &contents, 0); retval = errno; krb5_free_data_contents(context, &keydata); switch (dbret) { case 1: retval = KRB5_KDB_NOENTRY; /* Fall through. */ case -1: default: goto cleanup; case 0: contdata.data = contents.data; contdata.length = contents.size; retval = krb5_decode_princ_entry(context, &contdata, entry); break; } cleanup: (void) krb5_db2_unlock(context); /* unlock read lock */ return retval; }
/* Lock DB handle of curs, updating curs->islocked. */ static krb5_error_code curs_lock(iter_curs *curs) { krb5_error_code retval; retval = ctx_lock(curs->ctx, curs->dbc, curs->lockmode); if (retval) return retval; curs->islocked = TRUE; return 0; }
void VideoOutputOpenGL::Show(FrameScanType /*scan*/) { OpenGLLocker ctx_lock(gl_context); if (IsErrored()) { LOG(VB_GENERAL, LOG_ERR, LOC + "IsErrored() is true in Show()"); return; } if (gl_context) gl_context->swapBuffers(); }
static krb5_error_code ctx_iterate(krb5_context context, krb5_db2_context *dbc, krb5_error_code (*func)(krb5_pointer, krb5_db_entry *), krb5_pointer func_arg) { DB *db; DBT key, contents; krb5_data contdata; krb5_db_entry *entry; krb5_error_code retval, retval2; int dbret; retval = ctx_lock(context, dbc, KRB5_LOCKMODE_SHARED); if (retval) return retval; db = dbc->db; dbret = db->seq(db, &key, &contents, R_FIRST); while (dbret == 0) { contdata.data = contents.data; contdata.length = contents.size; retval = krb5_decode_princ_entry(context, &contdata, &entry); if (retval) break; retval = k5_mutex_unlock(krb5_db2_mutex); if (retval) break; retval = (*func)(func_arg, entry); krb5_dbe_free(context, entry); retval2 = k5_mutex_lock(krb5_db2_mutex); /* Note: If re-locking fails, the wrapper in db2_exp.c will still try to unlock it again. That would be a bug. Fix when integrating the locking better. */ if (retval) break; if (retval2) { retval = retval2; break; } dbret = db->seq(db, &key, &contents, R_NEXT); } switch (dbret) { case 1: case 0: break; case -1: default: retval = errno; } (void) ctx_unlock(context, dbc); return retval; }
krb5_error_code krb5_db2_put_principal(krb5_context context, krb5_db_entry *entry, char **db_args) { int dbret; DB *db; DBT key, contents; krb5_data contdata, keydata; krb5_error_code retval; krb5_db2_context *dbc; krb5_clear_error_message (context); if (db_args) { /* DB2 does not support db_args DB arguments for principal */ krb5_set_error_message(context, EINVAL, _("Unsupported argument \"%s\" for db2"), db_args[0]); return EINVAL; } if (!inited(context)) return KRB5_KDB_DBNOTINITED; dbc = context->dal_handle->db_context; if ((retval = ctx_lock(context, dbc, KRB5_LOCKMODE_EXCLUSIVE))) return retval; db = dbc->db; retval = krb5_encode_princ_entry(context, &contdata, entry); if (retval) goto cleanup; contents.data = contdata.data; contents.size = contdata.length; retval = krb5_encode_princ_dbkey(context, &keydata, entry->princ); if (retval) { krb5_free_data_contents(context, &contdata); goto cleanup; } key.data = keydata.data; key.size = keydata.length; dbret = (*db->put)(db, &key, &contents, 0); retval = dbret ? errno : 0; krb5_free_data_contents(context, &keydata); krb5_free_data_contents(context, &contdata); cleanup: ctx_update_age(dbc); (void) krb5_db2_unlock(context); /* unlock database */ return (retval); }
void VideoOutputOpenGL::RemovePIP(MythPlayer *pipplayer) { if (!gl_pipchains.contains(pipplayer)) return; OpenGLLocker ctx_lock(gl_context); OpenGLVideo *gl_pipchain = gl_pipchains[pipplayer]; if (gl_pipchain) delete gl_pipchain; gl_pip_ready.remove(pipplayer); gl_pipchains.remove(pipplayer); }
void VideoOutputOpenGL::ProcessFrame(VideoFrame *frame, OSD *osd, FilterChain *filterList, const PIPMap &pipPlayers, FrameScanType scan) { QMutexLocker locker(&gl_context_lock); if (!gl_context) return; bool sw_frame = codec_is_std(video_codec_id) && video_codec_id != kCodec_NONE; bool deint_proc = m_deinterlacing && (m_deintFilter != NULL); OpenGLLocker ctx_lock(gl_context); bool pauseframe = false; if (!frame) { frame = vbuffers.GetScratchFrame(); CopyFrame(vbuffers.GetScratchFrame(), &av_pause_frame); pauseframe = true; } if (filterList && sw_frame) filterList->ProcessFrame(frame); bool safepauseframe = pauseframe && !IsBobDeint(); if (sw_frame && deint_proc && m_deinterlaceBeforeOSD && (!pauseframe || safepauseframe)) { m_deintFilter->ProcessFrame(frame, scan); } if (!window.IsEmbedding()) { gl_pipchain_active = NULL; ShowPIPs(frame, pipPlayers); } if (sw_frame && (!pauseframe || safepauseframe) && deint_proc && !m_deinterlaceBeforeOSD) { m_deintFilter->ProcessFrame(frame, scan); } if (gl_videochain && sw_frame) { bool soft_bob = m_deinterlacing && (m_deintfiltername == "bobdeint"); gl_videochain->UpdateInputFrame(frame, soft_bob); } }
bool VideoOutputOpenGL::SetupOpenGL(void) { if (!gl_context) return false; const QRect dvr = window.GetDisplayVisibleRect(); if (video_codec_id == kCodec_NONE) { gl_context->SetViewPort(QRect(QPoint(),dvr.size())); return true; } if (window.GetPIPState() >= kPIPStandAlone) { QRect tmprect = QRect(QPoint(0,0), dvr.size()); ResizeDisplayWindow(tmprect, true); } bool success = false; OpenGLLocker ctx_lock(gl_context); gl_videochain = new OpenGLVideo(); QString options = GetFilters(); if (gl_opengl_lite) options += " preferycbcr"; success = gl_videochain->Init(gl_context, &videoColourSpace, window.GetVideoDim(), window.GetVideoDispDim(), dvr, window.GetDisplayVideoRect(), window.GetVideoRect(), true, options, !codec_is_std(video_codec_id)); if (success) { bool temp_deinterlacing = m_deinterlacing; if (!m_deintfiltername.isEmpty() && !m_deintfiltername.contains("opengl")) { gl_videochain->SetSoftwareDeinterlacer(m_deintfiltername); } SetDeinterlacingEnabled(true); if (!temp_deinterlacing) { SetDeinterlacingEnabled(false); } } return success; }
bool VideoOutputOpenGLVAAPI::CreateVAAPIContext(QSize size) { // FIXME During a video stream change this is called from the decoder // thread - which breaks all other efforts to remove non-UI thread // access to the OpenGL context. There is no obvious fix however - if we // don't delete and re-create the VAAPI decoder context immediately then // the decoder fails and playback exits. // lvr 27-oct-13 // in 0.27 if m_ctx->CreateDisplay is called outside of the UI thread then // it fails, which then causes subsequent unbalanced calls to doneCurrent // which results in Qt aborting. So just fail if non-UI. if (!gCoreContext->IsUIThread()) { LOG(VB_GENERAL, LOG_ERR, LOC + "CreateVAAPIContext called from non-UI thread"); return false; } OpenGLLocker ctx_lock(gl_context); if (m_ctx) DeleteVAAPIContext(); m_ctx = new VAAPIContext(kVADisplayGLX, video_codec_id); if (m_ctx && m_ctx->CreateDisplay(size) && m_ctx->CreateBuffers()) { int num_buffers = m_ctx->GetNumBuffers(); const QSize video_dim = window.GetActualVideoDim(); bool ok = true; for (int i = 0; i < num_buffers; i++) { ok &= vbuffers.CreateBuffer(video_dim.width(), video_dim.height(), i, m_ctx->GetVideoSurface(i), FMT_VAAPI); } InitPictureAttributes(); return ok; } LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to create VAAPI context."); errorState = kError_Unknown; return false; }
bool VideoOutputOpenGL::SetupDeinterlace( bool interlaced, const QString &overridefilter) { if (!gl_videochain || !gl_context) return false; OpenGLLocker ctx_lock(gl_context); if (db_vdisp_profile) m_deintfiltername = db_vdisp_profile->GetFilteredDeint(overridefilter); if (!m_deintfiltername.contains("opengl")) { gl_videochain->SetDeinterlacing(false); gl_videochain->SetSoftwareDeinterlacer(QString::null); VideoOutput::SetupDeinterlace(interlaced, overridefilter); if (m_deinterlacing) gl_videochain->SetSoftwareDeinterlacer(m_deintfiltername); return m_deinterlacing; } // clear any non opengl filters if (m_deintFiltMan) { delete m_deintFiltMan; m_deintFiltMan = NULL; } if (m_deintFilter) { delete m_deintFilter; m_deintFilter = NULL; } m_deinterlacing = interlaced; if (m_deinterlacing && !m_deintfiltername.isEmpty()) { if (gl_videochain->GetDeinterlacer() != m_deintfiltername) { if (!gl_videochain->AddDeinterlacer(m_deintfiltername)) { VERBOSE(VB_IMPORTANT, LOC + QString("Couldn't load deinterlace filter %1") .arg(m_deintfiltername)); m_deinterlacing = false; m_deintfiltername = ""; } else { VERBOSE(VB_PLAYBACK, LOC + QString("Using deinterlace method %1") .arg(m_deintfiltername)); } } } gl_videochain->SetDeinterlacing(m_deinterlacing); return m_deinterlacing; }
bool VideoOutputOpenGL::SetupDeinterlace( bool interlaced, const QString &overridefilter) { if (!gl_videochain || !gl_context) return false; OpenGLLocker ctx_lock(gl_context); if (db_vdisp_profile) m_deintfiltername = db_vdisp_profile->GetFilteredDeint(overridefilter); if (MythCodecContext::isCodecDeinterlacer(m_deintfiltername)) return false; if (!m_deintfiltername.contains("opengl")) { gl_videochain->SetDeinterlacing(false); gl_videochain->SetSoftwareDeinterlacer(QString()); VideoOutput::SetupDeinterlace(interlaced, overridefilter); if (m_deinterlacing) gl_videochain->SetSoftwareDeinterlacer(m_deintfiltername); return m_deinterlacing; } // clear any non opengl filters if (m_deintFiltMan) { delete m_deintFiltMan; m_deintFiltMan = nullptr; } if (m_deintFilter) { delete m_deintFilter; m_deintFilter = nullptr; } MoveResize(); m_deinterlacing = interlaced; if (m_deinterlacing && !m_deintfiltername.isEmpty()) { if (gl_videochain->GetDeinterlacer() != m_deintfiltername) { if (!gl_videochain->AddDeinterlacer(m_deintfiltername)) { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Couldn't load deinterlace filter %1") .arg(m_deintfiltername)); m_deinterlacing = false; m_deintfiltername = ""; } else { LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Using deinterlace method %1") .arg(m_deintfiltername)); } } } gl_videochain->SetDeinterlacing(m_deinterlacing); return m_deinterlacing; }
void VideoOutputOpenGL::PrepareFrame(VideoFrame *buffer, FrameScanType t, OSD *osd) { if (!gl_context) return; OpenGLLocker ctx_lock(gl_context); if (!buffer) { buffer = vbuffers.GetScratchFrame(); if (m_deinterlacing && !IsBobDeint()) t = kScan_Interlaced; } gl_context_lock.lock(); framesPlayed = buffer->frameNumber + 1; gl_context_lock.unlock(); gl_context->BindFramebuffer(0); if (db_letterbox_colour == kLetterBoxColour_Gray25) gl_context->SetBackground(127, 127, 127, 255); else gl_context->SetBackground(0, 0, 0, 255); gl_context->ClearFramebuffer(); // stereoscopic views QRect main = gl_context->GetViewPort(); QRect first = main; QRect second = main; bool twopass = (m_stereo == kStereoscopicModeSideBySide) || (m_stereo == kStereoscopicModeTopAndBottom); if (kStereoscopicModeSideBySide == m_stereo) { first = QRect(main.left() / 2, main.top(), main.width() / 2, main.height()); second = first.translated(main.width() / 2, 0); } else if (kStereoscopicModeTopAndBottom == m_stereo) { first = QRect(main.left(), main.top() / 2, main.width(), main.height() / 2); second = first.translated(0, main.height() / 2); } // main UI when embedded MythMainWindow *mwnd = GetMythMainWindow(); if (mwnd && mwnd->GetPaintWindow() && window.IsEmbedding()) { if (twopass) gl_context->SetViewPort(first, true); mwnd->GetPaintWindow()->clearMask(); // Must force a UI redraw when embedded. If not, when the EPG or // finder screen is popped up over the video and the user then clicks // away from Myth, the UI is left blank. mwnd->GetMainStack()->GetTopScreen()->SetRedraw(); mwnd->draw(gl_painter); if (twopass) { gl_context->SetViewPort(second, true); mwnd->GetPaintWindow()->clearMask(); mwnd->GetMainStack()->GetTopScreen()->SetRedraw(); mwnd->draw(gl_painter); gl_context->SetViewPort(main, true); } } // video if (gl_videochain && !buffer->dummy) { gl_videochain->SetVideoRect(vsz_enabled ? vsz_desired_display_rect : window.GetDisplayVideoRect(), window.GetVideoRect()); gl_videochain->PrepareFrame(buffer->top_field_first, t, m_deinterlacing, framesPlayed, m_stereo); } // PiPs/PBPs if (gl_pipchains.size()) { QMap<MythPlayer*,OpenGLVideo*>::iterator it = gl_pipchains.begin(); for (; it != gl_pipchains.end(); ++it) { if (gl_pip_ready[it.key()]) { bool active = gl_pipchain_active == *it; if (twopass) gl_context->SetViewPort(first, true); (*it)->PrepareFrame(buffer->top_field_first, t, m_deinterlacing, framesPlayed, kStereoscopicModeNone, active); if (twopass) { gl_context->SetViewPort(second, true); (*it)->PrepareFrame(buffer->top_field_first, t, m_deinterlacing, framesPlayed, kStereoscopicModeNone, active); gl_context->SetViewPort(main); } } } } // visualisation if (m_visual && gl_painter && !window.IsEmbedding()) { if (twopass) gl_context->SetViewPort(first, true); m_visual->Draw(GetTotalOSDBounds(), gl_painter, nullptr); if (twopass) { gl_context->SetViewPort(second, true); m_visual->Draw(GetTotalOSDBounds(), gl_painter, nullptr); gl_context->SetViewPort(main); } } // OSD if (osd && gl_painter && !window.IsEmbedding()) { if (twopass) gl_context->SetViewPort(first, true); osd->DrawDirect(gl_painter, GetTotalOSDBounds().size(), true); if (twopass) { gl_context->SetViewPort(second, true); osd->DrawDirect(gl_painter, GetTotalOSDBounds().size(), true); gl_context->SetViewPort(main); } } gl_context->Flush(false); if (vbuffers.GetScratchFrame() == buffer) vbuffers.SetLastShownFrameToScratch(); }
void VideoOutputOpenGL::ProcessFrame(VideoFrame *frame, OSD */*osd*/, FilterChain *filterList, const PIPMap &pipPlayers, FrameScanType scan) { QMutexLocker locker(&gl_context_lock); if (!gl_context) return; if (!gl_valid) { if (!gCoreContext->IsUIThread()) { LOG(VB_GENERAL, LOG_ERR, LOC + "ProcessFrame called from wrong thread"); } QSize size = window.GetActualVideoDim(); InitDisplayMeasurements(size.width(), size.height(), false); DestroyVideoResources(); CreateVideoResources(); BestDeint(); gl_valid = true; } bool sw_frame = codec_sw_copy(video_codec_id) && video_codec_id != kCodec_NONE; bool deint_proc = m_deinterlacing && (m_deintFilter != nullptr); OpenGLLocker ctx_lock(gl_context); bool pauseframe = false; if (!frame) { frame = vbuffers.GetScratchFrame(); CopyFrame(vbuffers.GetScratchFrame(), &av_pause_frame); pauseframe = true; } if (sw_frame) { CropToDisplay(frame); } bool dummy = frame->dummy; if (filterList && sw_frame && !dummy) filterList->ProcessFrame(frame); bool safepauseframe = pauseframe && !IsBobDeint(); if (sw_frame && deint_proc && m_deinterlaceBeforeOSD && (!pauseframe || safepauseframe) && !dummy) { m_deintFilter->ProcessFrame(frame, scan); } if (!window.IsEmbedding()) { gl_pipchain_active = nullptr; ShowPIPs(frame, pipPlayers); } if (sw_frame && (!pauseframe || safepauseframe) && deint_proc && !m_deinterlaceBeforeOSD && !dummy) { m_deintFilter->ProcessFrame(frame, scan); } if (gl_videochain && sw_frame && !dummy) { bool soft_bob = m_deinterlacing && (m_deintfiltername == "bobdeint"); gl_videochain->UpdateInputFrame(frame, soft_bob); } }
bool VideoOutputOpenGL::SetupOpenGL(void) { if (!gl_context) return false; QRect dvr = window.GetDisplayVisibleRect(); MythMainWindow *mainWin = GetMythMainWindow(); QSize mainSize = mainWin->size(); // If the Video screen mode has vertically less pixels // than the GUI screen mode - OpenGL coordinate adjustments // must be made to put the video at the top of the display // area instead of at the bottom. if (dvr.height() < mainSize.height()) dvr.setTop(dvr.top()-mainSize.height()+dvr.height()); // If the Video screen mode has horizontally less pixels // than the GUI screen mode - OpenGL width must be set // as the higher GUI width so that the Program Guide // invoked from playback is not cut off. if (dvr.width() < mainSize.width()) dvr.setWidth(mainSize.width()); if (video_codec_id == kCodec_NONE) { gl_context->SetViewPort(QRect(QPoint(),dvr.size())); return true; } if (window.GetPIPState() >= kPIPStandAlone) { QRect tmprect = QRect(QPoint(0,0), dvr.size()); ResizeDisplayWindow(tmprect, true); } bool success = false; OpenGLLocker ctx_lock(gl_context); gl_videochain = new OpenGLVideo(); QString options = GetFilters(); if (gl_opengl_lite) options += " preferycbcr"; success = gl_videochain->Init(gl_context, &videoColourSpace, window.GetVideoDim(), window.GetVideoDispDim(), dvr, window.GetDisplayVideoRect(), window.GetVideoRect(), true, options, !codec_sw_copy(video_codec_id)); if (success) { bool temp_deinterlacing = m_deinterlacing; if (!m_deintfiltername.isEmpty() && !m_deintfiltername.contains("opengl")) { gl_videochain->SetSoftwareDeinterlacer(m_deintfiltername); } SetDeinterlacingEnabled(true); if (!temp_deinterlacing) { SetDeinterlacingEnabled(false); } } return success; }
void VideoOutputOpenGL::PrepareFrame(VideoFrame *buffer, FrameScanType t, OSD *osd) { (void)osd; if (!gl_context) return; OpenGLLocker ctx_lock(gl_context); if (!buffer) { buffer = vbuffers.GetScratchFrame(); if (m_deinterlacing && !IsBobDeint()) t = kScan_Interlaced; } gl_context_lock.lock(); framesPlayed = buffer->frameNumber + 1; gl_context_lock.unlock(); gl_context->BindFramebuffer(0); if (db_letterbox_colour == kLetterBoxColour_Gray25) gl_context->SetBackground(127, 127, 127, 255); else gl_context->SetBackground(0, 0, 0, 255); gl_context->ClearFramebuffer(); if (gl_context->IsShared() && GetMythMainWindow() && window.IsEmbedding()) GetMythMainWindow()->draw(); if (gl_videochain) { gl_videochain->SetVideoRect(vsz_enabled ? vsz_desired_display_rect : window.GetDisplayVideoRect(), window.GetVideoRect()); gl_videochain->PrepareFrame(buffer->top_field_first, t, m_deinterlacing, framesPlayed); } QMap<MythPlayer*,OpenGLVideo*>::iterator it = gl_pipchains.begin(); for (; it != gl_pipchains.end(); ++it) { if (gl_pip_ready[it.key()]) { bool active = gl_pipchain_active == *it; (*it)->PrepareFrame(buffer->top_field_first, t, m_deinterlacing, framesPlayed, active); } } if (m_visual && gl_painter && !window.IsEmbedding()) m_visual->Draw(GetTotalOSDBounds(), gl_painter, NULL); if (osd && gl_painter && !window.IsEmbedding()) osd->DrawDirect(gl_painter, GetTotalOSDBounds().size(), true); gl_context->Flush(false); if (vbuffers.GetScratchFrame() == buffer) vbuffers.SetLastShownFrameToScratch(); }
krb5_error_code krb5_db2_delete_principal(krb5_context context, krb5_const_principal searchfor) { krb5_error_code retval; krb5_db_entry *entry; krb5_db2_context *dbc; DB *db; DBT key, contents; krb5_data keydata, contdata; int i, dbret; if (!inited(context)) return KRB5_KDB_DBNOTINITED; dbc = context->dal_handle->db_context; if ((retval = ctx_lock(context, dbc, KRB5_LOCKMODE_EXCLUSIVE))) return (retval); if ((retval = krb5_encode_princ_dbkey(context, &keydata, searchfor))) goto cleanup; key.data = keydata.data; key.size = keydata.length; db = dbc->db; dbret = (*db->get) (db, &key, &contents, 0); retval = errno; switch (dbret) { case 1: retval = KRB5_KDB_NOENTRY; /* Fall through. */ case -1: default: goto cleankey; case 0: ; } contdata.data = contents.data; contdata.length = contents.size; retval = krb5_decode_princ_entry(context, &contdata, &entry); if (retval) goto cleankey; /* Clear encrypted key contents */ for (i = 0; i < entry->n_key_data; i++) { if (entry->key_data[i].key_data_length[0]) { memset(entry->key_data[i].key_data_contents[0], 0, (unsigned) entry->key_data[i].key_data_length[0]); } } retval = krb5_encode_princ_entry(context, &contdata, entry); krb5_dbe_free(context, entry); if (retval) goto cleankey; contents.data = contdata.data; contents.size = contdata.length; dbret = (*db->put) (db, &key, &contents, 0); retval = dbret ? errno : 0; krb5_free_data_contents(context, &contdata); if (retval) goto cleankey; dbret = (*db->del) (db, &key, 0); retval = dbret ? errno : 0; cleankey: krb5_free_data_contents(context, &keydata); cleanup: ctx_update_age(dbc); (void) krb5_db2_unlock(context); /* unlock write lock */ return retval; }
krb5_error_code krb5_db2_promote_db(krb5_context context, char *conf_section, char **db_args) { krb5_error_code retval; krb5_boolean merge_nra = FALSE, real_locked = FALSE; krb5_db2_context *dbc_temp, *dbc_real = NULL; char **db_argp; /* context must be initialized with an exclusively locked temp DB. */ if (!inited(context)) return KRB5_KDB_DBNOTINITED; dbc_temp = context->dal_handle->db_context; if (dbc_temp->db_lock_mode != KRB5_LOCKMODE_EXCLUSIVE) return KRB5_KDB_NOTLOCKED; if (!dbc_temp->tempdb) return EINVAL; /* Check db_args for whether we should merge non-replicated attributes. */ for (db_argp = db_args; *db_argp; db_argp++) { if (!strcmp(*db_argp, "merge_nra")) { merge_nra = TRUE; break; } } /* Make a db2 context for the real DB. */ dbc_real = k5alloc(sizeof(*dbc_real), &retval); if (dbc_real == NULL) return retval; ctx_clear(dbc_real); /* Try creating the real DB. */ dbc_real->db_name = strdup(dbc_temp->db_name); if (dbc_real->db_name == NULL) goto cleanup; dbc_real->tempdb = FALSE; retval = ctx_create_db(context, dbc_real); if (retval == EEXIST) { /* The real database already exists, so open and lock it. */ dbc_real->db_name = strdup(dbc_temp->db_name); if (dbc_real->db_name == NULL) goto cleanup; dbc_real->tempdb = FALSE; retval = ctx_init(dbc_real); if (retval) goto cleanup; retval = ctx_lock(context, dbc_real, KRB5_DB_LOCKMODE_EXCLUSIVE); if (retval) goto cleanup; } else if (retval) goto cleanup; real_locked = TRUE; if (merge_nra) { retval = ctx_merge_nra(context, dbc_temp, dbc_real); if (retval) goto cleanup; } /* Perform filesystem manipulations for the promotion. */ retval = ctx_promote(context, dbc_temp, dbc_real); if (retval) goto cleanup; /* Unlock and finalize context since the temp DB is gone. */ (void) krb5_db2_unlock(context); krb5_db2_fini(context); cleanup: if (real_locked) (void) ctx_unlock(context, dbc_real); if (dbc_real) ctx_fini(dbc_real); return retval; }