示例#1
0
文件: kmm_reg.c 项目: Brainiarc7/pbis
KHMEXP khm_int32   KHMAPI
kmm_get_plugin_config(wchar_t * plugin, khm_int32 flags, khm_handle * result)
{
    khm_handle csplugins;
    khm_handle csplugin;
    khm_int32 rv;

    if(!plugin || wcschr(plugin, L'/') || wcschr(plugin, L'\\'))
        return KHM_ERROR_INVALID_PARAM;

    if(KHM_FAILED(kmm_get_plugins_config(flags, &csplugins)))
        return KHM_ERROR_UNKNOWN;

    rv = khc_open_space(csplugins, plugin, flags, &csplugin);
    *result = csplugin;

    khc_close_space(csplugins);

    return rv;
}
示例#2
0
/* called by the NetIDMgr module manager */
KHMEXP_EXP khm_int32 KHMAPI init_module(kmm_module h_module) {
    khm_int32 rv = KHM_ERROR_SUCCESS;
    kmm_plugin_reg pi;
    wchar_t buf[256];

    h_khModule = h_module;

    rv = kmm_set_locale_info(h_module, locales, n_locales);
    if(KHM_SUCCEEDED(rv)) {
        hResModule = kmm_get_resource_hmodule(h_module);
    } else
        goto _exit;

    k5_commctl_version = khm_get_commctl_version(NULL);

    /* register the plugin */
    ZeroMemory(&pi, sizeof(pi));
    pi.name = KRB5_PLUGIN_NAME;
    pi.type = KHM_PITYPE_CRED;
    pi.icon = LoadImage(hResModule, MAKEINTRESOURCE(IDI_PLUGIN),
                        IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
    pi.flags = 0;
    pi.msg_proc = k5_msg_callback;
    pi.description = buf;
    pi.dependencies = NULL;
    LoadString(hResModule, IDS_PLUGIN_DESC,
               buf, ARRAYLENGTH(buf));
    kmm_provide_plugin(h_module, &pi);

    ZeroMemory(&pi, sizeof(pi));
    pi.name = KRB5_IDENTPRO_NAME;
    pi.type = KHM_PITYPE_IDENT;
    pi.icon = LoadImage(hResModule, MAKEINTRESOURCE(IDI_PLUGIN),
                        IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
    pi.flags = 0;
    pi.msg_proc = k5_ident_callback;
    pi.description = buf;
    pi.dependencies = KRB5_PLUGIN_NAME L"\0";
    LoadString(hResModule, IDS_IDENTPRO_DESC,
               buf, ARRAYLENGTH(buf));
    kmm_provide_plugin(h_module, &pi);

    if(KHM_FAILED(rv = init_imports()))
        goto _exit;

    if(KHM_FAILED(rv = init_error_funcs()))
        goto _exit;

    /* Register common data types */
    if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ENCTYPE, &type_id_enctype))) {
        kcdb_type type;
        kcdb_type *t32;

        kcdb_type_get_info(KCDB_TYPE_INT32, &t32);

        type.id = KCDB_TYPE_INVALID;
        type.name = TYPENAME_ENCTYPE;
        type.flags = KCDB_TYPE_FLAG_CB_FIXED;
        type.cb_max = t32->cb_max;
        type.cb_min = t32->cb_min;
        type.isValid = t32->isValid;
        type.comp = t32->comp;
        type.dup = t32->dup;
        type.toString = enctype_toString;

        rv = kcdb_type_register(&type, &type_id_enctype);
        kcdb_type_release_info(t32);

        if(KHM_FAILED(rv))
            goto _exit;
        type_regd_enctype = TRUE;
    }

    if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ADDR_LIST, &type_id_addr_list))) {
        kcdb_type type;
        kcdb_type *tdata;

        kcdb_type_get_info(KCDB_TYPE_DATA, &tdata);

        type.id = KCDB_TYPE_INVALID;
        type.name = TYPENAME_ADDR_LIST;
        type.flags = KCDB_TYPE_FLAG_CB_MIN;
        type.cb_min = 0;
        type.cb_max = 0;
        type.isValid = tdata->isValid;
        type.comp = addr_list_comp;
        type.dup = tdata->dup;
        type.toString = addr_list_toString;

        rv = kcdb_type_register(&type, &type_id_addr_list);
        kcdb_type_release_info(tdata);

        if(KHM_FAILED(rv))
            goto _exit;
        type_regd_addr_list = TRUE;
    }

    if(KHM_FAILED(kcdb_type_get_id(TYPENAME_KRB5_FLAGS, &type_id_krb5_flags))) {
        kcdb_type type;
        kcdb_type *t32;

        kcdb_type_get_info(KCDB_TYPE_INT32, &t32);

        type.id = KCDB_TYPE_INVALID;
        type.name = TYPENAME_KRB5_FLAGS;
        type.flags = KCDB_TYPE_FLAG_CB_FIXED;
        type.cb_max = t32->cb_max;
        type.cb_min = t32->cb_min;
        type.isValid = t32->isValid;
        type.comp = t32->comp;
        type.dup = t32->dup;
        type.toString = krb5flags_toString;

        rv = kcdb_type_register(&type, &type_id_krb5_flags);
        kcdb_type_release_info(t32);

        if(KHM_FAILED(rv))
            goto _exit;
        type_regd_krb5_flags = TRUE;
    }

    if (KHM_FAILED(kcdb_type_get_id(TYPENAME_KVNO, &type_id_kvno))) {
        kcdb_type type;
        kcdb_type *t32;

        kcdb_type_get_info(KCDB_TYPE_INT32, &t32);

        type.id = KCDB_TYPE_INVALID;
        type.name = TYPENAME_KVNO;
        type.flags = KCDB_TYPE_FLAG_CB_FIXED;
        type.cb_max = t32->cb_max;
        type.cb_min = t32->cb_min;
        type.isValid = t32->isValid;
        type.comp = t32->comp;
        type.dup = t32->dup;
        type.toString = kvno_toString;

        rv = kcdb_type_register(&type, &type_id_kvno);
        kcdb_type_release_info(t32);

        if (KHM_FAILED(rv))
            goto _exit;

        type_regd_kvno = TRUE;
    }

    /* Register common attributes */
    if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KEY_ENCTYPE, &attr_id_key_enctype))) {
        kcdb_attrib attrib;
        wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
        wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC];
        /* although we are loading a long descriptoin, it still fits
        in the short descriptoin buffer */

        ZeroMemory(&attrib, sizeof(attrib));

        attrib.name = ATTRNAME_KEY_ENCTYPE;
        attrib.id = KCDB_ATTR_INVALID;
        attrib.type = type_id_enctype;
        attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
        LoadString(hResModule, IDS_KEY_ENCTYPE_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
        LoadString(hResModule, IDS_KEY_ENCTYPE_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
        attrib.short_desc = sbuf;
        attrib.long_desc = lbuf;
        
        rv = kcdb_attrib_register(&attrib, &attr_id_key_enctype);

        if(KHM_FAILED(rv))
            goto _exit;

        attr_regd_key_enctype = TRUE;
    }

    if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_TKT_ENCTYPE, &attr_id_tkt_enctype))) {
        kcdb_attrib attrib;
        wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
        wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC];
        /* although we are loading a long descriptoin, it still fits
        in the short descriptoin buffer */

        ZeroMemory(&attrib, sizeof(attrib));

        attrib.name = ATTRNAME_TKT_ENCTYPE;
        attrib.id = KCDB_ATTR_INVALID;
        attrib.type = type_id_enctype;
        attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
        LoadString(hResModule, IDS_TKT_ENCTYPE_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
        LoadString(hResModule, IDS_TKT_ENCTYPE_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
        attrib.short_desc = sbuf;
        attrib.long_desc = lbuf;
        
        rv = kcdb_attrib_register(&attrib, &attr_id_tkt_enctype);

        if(KHM_FAILED(rv))
            goto _exit;

        attr_regd_tkt_enctype = TRUE;
    }

    if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_ADDR_LIST, &attr_id_addr_list))) {
        kcdb_attrib attrib;
        wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
        wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC];
        /* although we are loading a long descriptoin, it still fits
        in the short descriptoin buffer */

        ZeroMemory(&attrib, sizeof(attrib));

        attrib.name = ATTRNAME_ADDR_LIST;
        attrib.id = KCDB_ATTR_INVALID;
        attrib.type = type_id_addr_list;
        attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
        LoadString(hResModule, IDS_ADDR_LIST_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
        LoadString(hResModule, IDS_ADDR_LIST_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
        attrib.short_desc = sbuf;
        attrib.long_desc = lbuf;
        
        rv = kcdb_attrib_register(&attrib, &attr_id_addr_list);

        if(KHM_FAILED(rv))
            goto _exit;

        attr_regd_addr_list = TRUE;
    }

    if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_FLAGS, &attr_id_krb5_flags))) {
        kcdb_attrib attrib;
        wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];

        /* although we are loading a long descriptoin, it still fits
        in the short descriptoin buffer */

        ZeroMemory(&attrib, sizeof(attrib));

        attrib.name = ATTRNAME_KRB5_FLAGS;
        attrib.id = KCDB_ATTR_INVALID;
        attrib.type = type_id_krb5_flags;
        attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
        LoadString(hResModule, IDS_KRB5_FLAGS_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
        attrib.short_desc = sbuf;
        attrib.long_desc = NULL;
        
        rv = kcdb_attrib_register(&attrib, &attr_id_krb5_flags);

        if(KHM_FAILED(rv))
            goto _exit;

        attr_regd_krb5_flags = TRUE;
    }

    if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_CCNAME, &attr_id_krb5_ccname))) {
        kcdb_attrib attrib;
        wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
        wchar_t lbuf[KCDB_MAXCCH_SHORT_DESC];
        /* although we are loading a long descriptoin, it still fits
        in the short descriptoin buffer */

        ZeroMemory(&attrib, sizeof(attrib));

        attrib.name = ATTRNAME_KRB5_CCNAME;
        attrib.id = KCDB_ATTR_INVALID;
        attrib.type = KCDB_TYPE_STRING;
        attrib.flags =
	  KCDB_ATTR_FLAG_PROPERTY |
	  KCDB_ATTR_FLAG_TRANSIENT;
        LoadString(hResModule, IDS_KRB5_CCNAME_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
        LoadString(hResModule, IDS_KRB5_CCNAME_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
        attrib.short_desc = sbuf;
        attrib.long_desc = lbuf;
        
        rv = kcdb_attrib_register(&attrib, &attr_id_krb5_ccname);

        if(KHM_FAILED(rv))
            goto _exit;

        attr_regd_krb5_ccname = TRUE;
    }

    if (KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KVNO, &attr_id_kvno))) {
        kcdb_attrib attrib;
        wchar_t sbuf[KCDB_MAXCCH_SHORT_DESC];
        wchar_t lbuf[KCDB_MAXCCH_LONG_DESC];
        /* although we are loading a long description, it still fits
           in the short description buffer */

        ZeroMemory(&attrib, sizeof(attrib));

        attrib.name = ATTRNAME_KVNO;
        attrib.id = KCDB_ATTR_INVALID;
        attrib.type = type_id_kvno;
        attrib.flags = KCDB_ATTR_FLAG_TRANSIENT;
        LoadString(hResModule, IDS_KVNO_SHORT_DESC, sbuf, ARRAYLENGTH(sbuf));
        LoadString(hResModule, IDS_KVNO_LONG_DESC, lbuf, ARRAYLENGTH(lbuf));
        attrib.short_desc = sbuf;
        attrib.long_desc = lbuf;

        rv = kcdb_attrib_register(&attrib, &attr_id_kvno);

        if (KHM_FAILED(rv))
            goto _exit;

        attr_regd_kvno = TRUE;
    }

    if (KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_IDFLAGS, &attr_id_krb5_idflags))) {
        kcdb_attrib attrib;

        ZeroMemory(&attrib, sizeof(attrib));

        attrib.name = ATTRNAME_KRB5_IDFLAGS;
        attrib.id = KCDB_ATTR_INVALID;
        attrib.type = KCDB_TYPE_INT32;
        attrib.flags = KCDB_ATTR_FLAG_PROPERTY |
            KCDB_ATTR_FLAG_HIDDEN;
        /* we don't bother localizing these strings since the
           attribute is hidden.  The user will not see these
           descriptions anyway. */
        attrib.short_desc = L"Krb5 ID flags";
        attrib.long_desc = L"Kerberos 5 Identity Flags";

        rv = kcdb_attrib_register(&attrib, &attr_id_krb5_idflags);

        if (KHM_FAILED(rv))
            goto _exit;

        attr_regd_krb5_idflags = TRUE;
    }

    rv = kmm_get_plugins_config(0, &csp_plugins);
    if(KHM_FAILED(rv)) goto _exit;

    rv = khc_load_schema(csp_plugins, schema_krbconfig);
    if(KHM_FAILED(rv)) goto _exit;

    rv = khc_open_space(csp_plugins, CSNAME_KRB5CRED, 0, &csp_krbcred);
    if(KHM_FAILED(rv)) goto _exit;

    rv = khc_open_space(csp_krbcred, CSNAME_PARAMS, 0, &csp_params);
    if(KHM_FAILED(rv)) goto _exit;

_exit:
    return rv;
}
示例#3
0
khm_int32 KHMAPI
khm_krb5_find_ccache_for_identity(khm_handle ident, krb5_context *pctx,
                                  void * buffer, khm_size * pcbbuf)
{
    krb5_context        ctx = 0;
    krb5_ccache         cache = 0;
    krb5_error_code     code;
    apiCB *             cc_ctx = 0;
    struct _infoNC **   pNCi = NULL;
    int                 i;
    khm_int32           t;
    wchar_t *           ms = NULL;
    khm_size            cb;
    krb5_timestamp      expiration = 0;
    krb5_timestamp      best_match_expiration = 0;
    char                best_match_ccname[256] = "";
    khm_handle          csp_params = NULL;
    khm_handle          csp_plugins = NULL;

    if (!buffer || !pcbbuf)
    return KHM_ERROR_GENERAL;

    ctx = *pctx;

    if (!pcc_initialize ||
        !pcc_get_NC_info ||
        !pcc_free_NC_info ||
        !pcc_shutdown)
        goto _skip_cc_iter;

    code = pcc_initialize(&cc_ctx, CC_API_VER_2, NULL, NULL);
    if (code)
        goto _exit;

    code = pcc_get_NC_info(cc_ctx, &pNCi);

    if (code) 
        goto _exit;

    for(i=0; pNCi[i]; i++) {
        if (pNCi[i]->vers != CC_CRED_V5)
            continue;

        code = (*pkrb5_cc_resolve)(ctx, pNCi[i]->name, &cache);
        if (code)
            continue;

        /* need a function to check the cache for the identity
         * and determine if it has valid tickets.  If it has 
         * the right identity and valid tickets, store the 
         * expiration time and the cache name.  If it has the
         * right identity but no valid tickets, store the ccache
         * name and an expiration time of zero.  if it does not
         * have the right identity don't save the name.
         * 
         * Keep searching to find the best cache available.
         */

        if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache, 
                                                           ident, 
                                                           &expiration))) {
            if ( expiration > best_match_expiration ) {
                best_match_expiration = expiration;
                StringCbCopyA(best_match_ccname, 
                              sizeof(best_match_ccname),
                              "API:");
                StringCbCatA(best_match_ccname,
                             sizeof(best_match_ccname),
                             pNCi[i]->name);
                expiration = 0;
            }
        }

        if(ctx != NULL && cache != NULL)
            (*pkrb5_cc_close)(ctx, cache);
        cache = 0;
    }

 _skip_cc_iter:

    if (KHM_SUCCEEDED(kmm_get_plugins_config(0, &csp_plugins))) {
        khc_open_space(csp_plugins, L"Krb5Cred\\Parameters",  0, &csp_params);
        khc_close_space(csp_plugins);
        csp_plugins = NULL;
    }

#ifdef DEBUG
    if (csp_params == NULL) {
        assert(FALSE);
    }
#endif

    if (csp_params &&
        KHM_SUCCEEDED(khc_read_int32(csp_params, L"MsLsaList", &t)) && t) {
        code = (*pkrb5_cc_resolve)(ctx, "MSLSA:", &cache);
        if (code == 0 && cache) {
            if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache, 
                                                               ident, 
                                                               &expiration))) {
                if ( expiration > best_match_expiration ) {
                    best_match_expiration = expiration;
                    StringCbCopyA(best_match_ccname, sizeof(best_match_ccname),
                                  "MSLSA:");
                    expiration = 0;
                }
            }
        }

        if (ctx != NULL && cache != NULL)
            (*pkrb5_cc_close)(ctx, cache);

        cache = 0;
    }

    if (csp_params &&
        khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb)
        == KHM_ERROR_TOO_LONG &&
        cb > sizeof(wchar_t) * 2) {

        wchar_t * t;
        char ccname[MAX_PATH + 6];

        ms = PMALLOC(cb);

#ifdef DEBUG
        assert(ms);
#endif

        khc_read_multi_string(csp_params, L"FileCCList", ms, &cb);
        for(t = ms; t && *t; t = multi_string_next(t)) {
            StringCchPrintfA(ccname, ARRAYLENGTH(ccname),
                             "FILE:%S", t);

            code = (*pkrb5_cc_resolve)(ctx, ccname, &cache);
            if (code)
                continue;

            if (KHM_SUCCEEDED(khm_get_identity_expiration_time(ctx, cache, 
                                                               ident, 
                                                               &expiration))) {
                if ( expiration > best_match_expiration ) {
                    best_match_expiration = expiration;
                    StringCbCopyA(best_match_ccname,
                                  sizeof(best_match_ccname),
                                  ccname);
                    expiration = 0;
                }
            }

            if (ctx != NULL && cache != NULL)
                (*pkrb5_cc_close)(ctx, cache);
            cache = 0;
        }

        PFREE(ms);
    }
 _exit:
    if (csp_params)
        khc_close_space(csp_params);

    if (pNCi)
        (*pcc_free_NC_info)(cc_ctx, &pNCi);

    if (cc_ctx)
        (*pcc_shutdown)(&cc_ctx);

    if (best_match_ccname[0]) {
        
        if (*pcbbuf = AnsiStrToUnicode((wchar_t *)buffer, 
                                       *pcbbuf,
                                       best_match_ccname)) {

            *pcbbuf = (*pcbbuf + 1) * sizeof(wchar_t);

            return KHM_ERROR_SUCCESS;
        }

    }

    return KHM_ERROR_GENERAL;
}
示例#4
0
/*! \internal
  \brief Initialize a plugin

  \note If kmmint_init_plugin() is called on a plugin, then kmmint_exit_plugin()
      \b must be called for the plugin.

  \note Should only be called from the context of the registrar thread */
void kmmint_init_plugin(kmm_plugin_i * p) {
    DWORD dummy;
    khm_handle csp_plugin   = NULL;
    khm_handle csp_plugins  = NULL;
    khm_int32 t;

    /* the following will be undone in kmmint_exit_plugin() */
    kmm_hold_plugin(kmm_handle_from_plugin(p));

    EnterCriticalSection(&cs_kmm);
    if(p->state != KMM_PLUGIN_STATE_REG &&
        p->state != KMM_PLUGIN_STATE_HOLD)
    {
        LeaveCriticalSection(&cs_kmm);
        goto _exit;
    }

    _begin_task(0);
    _report_mr1(KHERR_NONE, MSG_IP_TASK_DESC, _cstr(p->p.name));
    _describe();

    if(p->state == KMM_PLUGIN_STATE_HOLD) {
        /* if this plugin was held, then we already had a hold
           from the initial attempt to start the plugin.  Undo
           the hold we did a few lines earlier. */
        kmm_release_plugin(kmm_handle_from_plugin(p));

        /* same for the plugin count for the module. */
#ifdef DEBUG
        assert(p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT);
#endif
        p->module->plugin_count--;
        p->flags &= ~KMM_PLUGIN_FLAG_IN_MODCOUNT;
    }

    p->state = KMM_PLUGIN_STATE_PREINIT;

    kmmint_delist_plugin(p);
    kmmint_list_plugin(p);

    LeaveCriticalSection(&cs_kmm);

    if(KHM_FAILED(kmm_get_plugins_config(0, &csp_plugins))) {
        _report_mr0(KHERR_ERROR, MSG_IP_GET_CONFIG);

        p->state = KMM_PLUGIN_STATE_FAIL_UNKNOWN;
        goto _exit;
    }

    if(KHM_FAILED(kmm_get_plugin_config(p->p.name, 0, &csp_plugin))) {
        if(KHM_FAILED(kmm_register_plugin(&(p->p), 0))) {
            _report_mr0(KHERR_ERROR, MSG_IP_NOT_REGISTERED);

            p->state = KMM_PLUGIN_STATE_FAIL_NOT_REGISTERED;
            goto _exit;
        }
        
        if(KHM_FAILED(kmm_get_plugin_config(p->p.name, 0, &csp_plugin))) {
            _report_mr0(KHERR_ERROR, MSG_IP_NOT_REGISTERED);

            p->state = KMM_PLUGIN_STATE_FAIL_NOT_REGISTERED;
            goto _exit;
        }
    }

    if (KHM_SUCCEEDED(khc_read_int32(csp_plugin, L"Disabled", &t)) && t) {
        p->flags |= KMM_PLUGIN_FLAG_DISABLED;
        p->state = KMM_PLUGIN_STATE_FAIL_DISABLED;
        goto _exit;
    }

#if 0
    /*TODO: check the failure count and act accordingly */
    if(KHM_SUCCEEDED(khc_read_int32(csp_plugin, L"FailureCount", &t)) && (t > 0)) {
    }
#endif

    EnterCriticalSection(&cs_kmm);

    p->n_depends = 0;
    p->n_unresolved = 0;
    
    do {
        wchar_t * deps = NULL;
        wchar_t * d;
        khm_size sz = 0;

        if(khc_read_multi_string(csp_plugin, L"Dependencies", 
                                 NULL, &sz) != KHM_ERROR_TOO_LONG)
            break;

        deps = PMALLOC(sz);
        if(KHM_FAILED(khc_read_multi_string(csp_plugin, L"Dependencies", 
                                            deps, &sz))) {
            if(deps)
                PFREE(deps);
            break;
        }

        for(d = deps; d && *d; d = multi_string_next(d)) {
            kmm_plugin_i * pd;
            int i;

            pd = kmmint_get_plugin_i(d);

            if(pd->state == KMM_PLUGIN_STATE_NONE) {
                /* the dependant was not previously known */
                pd->state = KMM_PLUGIN_STATE_PLACEHOLDER;
            }

            for(i=0; i < pd->n_dependants; i++) {
                if(pd->dependants[i] == p)
                    break;
            }

            if(i >= pd->n_dependants) {
                if( pd->n_dependants >= KMM_MAX_DEPENDANTS ) {
                    /*TODO: handle this gracefully */
                    RaiseException(1, EXCEPTION_NONCONTINUABLE, 0, NULL);
                }

                /* released in kmmint_free_plugin() */
                kmm_hold_plugin(kmm_handle_from_plugin(p));
                pd->dependants[pd->n_dependants] = p;
                pd->n_dependants++;
            }

            p->n_depends++;

            if(pd->state != KMM_PLUGIN_STATE_RUNNING) {
                p->n_unresolved++;
            }
        }

        if(p->n_unresolved > 0) {
            p->state = KMM_PLUGIN_STATE_HOLD;
        }

        PFREE(deps);

    } while(FALSE);

#ifdef DEBUG
    assert(!(p->flags & KMM_PLUGIN_FLAG_IN_MODCOUNT));
#endif
    p->flags |= KMM_PLUGIN_FLAG_IN_MODCOUNT;
    p->module->plugin_count++;

    LeaveCriticalSection(&cs_kmm);

    if(p->state == KMM_PLUGIN_STATE_HOLD) {
        _report_mr1(KHERR_INFO, MSG_IP_HOLD, _dupstr(p->p.name));

        goto _exit_post;
    }

    kmmint_add_to_plugin_queue(p);

    p->ht_thread = CreateThread(NULL,
                                0,
                                kmmint_plugin_broker,
                                (LPVOID) p,
                                CREATE_SUSPENDED,
                                &dummy);

    p->state = KMM_PLUGIN_STATE_INIT;

    ResumeThread(p->ht_thread);

_exit_post:
    if(csp_plugin != NULL)
        khc_close_space(csp_plugin);

    if(csp_plugins != NULL)
        khc_close_space(csp_plugins);

    _report_mr2(KHERR_INFO, MSG_IP_STATE, 
                _dupstr(p->p.name), _int32(p->state));

    _end_task();
    
    return;

    /* jump here if an error condition happens before the plugin
       broker thread starts and the plugin should be unloaded */

_exit:
    if(csp_plugin != NULL)
        khc_close_space(csp_plugin);
    if(csp_plugins != NULL)
        khc_close_space(csp_plugins);

    _report_mr2(KHERR_WARNING, MSG_IP_EXITING, 
                _dupstr(p->p.name), _int32(p->state));
    _end_task();


#ifdef ASYNC_PLUGIN_UNLOAD_ON_FAILURE

    kmm_hold_plugin(kmm_handle_from_plugin(p));

    kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_EXIT_PLUGIN, (void *) p);

#else

    kmmint_exit_plugin(p);

#endif
}
示例#5
0
/* Handler for system messages.  The only two we handle are
   KMSG_SYSTEM_INIT and KMSG_SYSTEM_EXIT. */
khm_int32 KHMAPI
handle_kmsg_system(khm_int32 msg_type,
                   khm_int32 msg_subtype,
                   khm_ui_4  uparam,
                   void *    vparam) {
    khm_int32 rv = KHM_ERROR_SUCCESS;

    switch (msg_subtype) {

        /* This is the first message that will be received by a
           plugin.  We use it to perform initialization operations
           such as registering any credential types, data types and
           attributes. */
    case KMSG_SYSTEM_INIT:
        {
            kcdb_credtype ct;
            wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];
            wchar_t long_desc[KCDB_MAXCCH_LONG_DESC];
            khui_config_node cnode;
            khui_config_node_reg creg;
            kcdb_attrib attr;
            khm_handle csp_plugin = NULL;
            khm_handle csp_plugins = NULL;

#ifdef BUILD_KRBCOMPAT
            /* If we don't have a Kerberos backend, then we can't
             * function. */
            if (!DelayLoadHeimdal()) {
		_reportf("Can't initialize a Kerberos backend.  LastError=%d", GetLastError());
                return KHM_ERROR_NOT_FOUND;
            }
#endif

#if KH_VERSION_API < 12

            do {
                khm_version libver;
                khm_ui_4 apiver;

                khm_get_lib_version(&libver, &apiver);

                if (apiver < 7)
                    break;

                hm_netidmgr = LoadLibrary(NIMDLLNAME);

                if (hm_netidmgr == NULL)
                    break;

#if KH_VERSION_API < 7
                pkhui_action_lock = (void (KHMAPI *)(void))
                    GetProcAddress(hm_netidmgr, API_khui_action_lock);
                pkhui_action_unlock = (void (KHMAPI *)(void))
                    GetProcAddress(hm_netidmgr, API_khui_action_unlock);
                pkhui_refresh_actions = (void (KHMAPI *)(void))
                    GetProcAddress(hm_netidmgr, API_khui_refresh_actions);
                pkhui_request_UI_callback = (khm_int32 (KHMAPI *)(khm_ui_callback, void *))
                    GetProcAddress(hm_netidmgr, API_khui_request_UI_callback);
#endif
                pkhui_cw_get_primary_id = (khm_int32 (KHMAPI *)(khui_new_creds *, khm_handle *))
                    GetProcAddress(hm_netidmgr, API_khui_cw_get_primary_id);
                pkhui_cw_get_result = (khm_int32 (KHMAPI *)(khui_new_creds *))
                    GetProcAddress(hm_netidmgr, API_khui_cw_get_result);
                pkhui_cw_get_subtype = (khui_nc_subtype (KHMAPI *)(khui_new_creds *))
                    GetProcAddress(hm_netidmgr, API_khui_cw_get_subtype);
                pkhui_cw_get_ctx = (khui_action_context * (KHMAPI *)(khui_new_creds *))
                    GetProcAddress(hm_netidmgr, API_khui_cw_get_ctx);
                pkcdb_get_resource = (khm_int32 (KHMAPI *)(khm_handle, kcdb_resource_id,
                                                           khm_int32, khm_int32 *,
                                                           void *, void *, khm_size *))
                    GetProcAddress(hm_netidmgr, API_kcdb_get_resource);
            } while (FALSE);

            if (pkhui_cw_get_primary_id == NULL)
              pkhui_cw_get_primary_id = int_khui_cw_get_primary_id;

            if (pkhui_cw_get_result == NULL)
                pkhui_cw_get_result = int_khui_cw_get_result;

            if (pkhui_cw_get_subtype == NULL)
                pkhui_cw_get_subtype = int_khui_cw_get_subtype;

            if (pkhui_cw_get_ctx == NULL)
                pkhui_cw_get_ctx = int_khui_cw_get_ctx;

            if (pkcdb_get_resource == NULL)
                pkcdb_get_resource = int_kcdb_get_resource;
#endif

            /* Add the icon now.  On NIM v2.x, doing so after tokens
               were reported may result in a deadlock as we try to
               switch to the UI thread and the UI thread is blocked on
               a resource request to this plug-in. */
            kca_icon_set_state(NULL);

            /* First and foremost, we need to register a credential
               type. */
            ZeroMemory(&ct, sizeof(ct));
            ct.id = KCDB_CREDTYPE_AUTO;
            ct.name = MYCREDTYPE_NAMEW;
            ct.short_desc = short_desc;
            ct.long_desc = long_desc;

            short_desc[0] = L'\0';
            LoadString(hResModule, IDS_CT_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));

            long_desc[0] = L'\0';
            LoadString(hResModule, IDS_CT_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            ct.icon = NULL;     /* We skip the icon for now, but you
                                   can assign a handle to an icon
                                   here.  The icon will be used to
                                   represent the credentials type.*/

            kmq_create_subscription(plugin_msg_proc, &ct.sub);

            ct.is_equal = cred_is_equal;

            rv = kcdb_credtype_register(&ct, &credtype_id);

            /* We create a global credential set that we use in the
               plug-in thread.  This alleviates the need to create one
               everytime we need one. Keep in mind that this should
               only be used in the plug-in thread and should not be
               touched from the UI thread or any other thread. */
            kcdb_credset_create(&g_credset);

            /* TODO: Perform additional initialization operations. */

            /* Register our attributes */

            ZeroMemory(&attr, sizeof(attr));

            attr.name = ATTRNAME_KCA_AUTHREALM;
            attr.id = KCDB_ATTR_INVALID;
            attr.alt_id = KCDB_ATTR_INVALID;
            attr.flags = 0;
            attr.type = KCDB_TYPE_STRING;
            attr.short_desc = short_desc;
            attr.long_desc = long_desc;
            attr.compute_cb = NULL;
            attr.compute_min_cbsize = 0;
            attr.compute_max_cbsize = 0;

            LoadString(hResModule, IDS_ATTR_REALM_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            LoadString(hResModule, IDS_ATTR_REALM_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            rv = kcdb_attrib_register(&attr, &attr_id_auth_realm);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_SUBJECT_EMAIL;

            LoadString(hResModule, IDS_ATTR_SUBJECT_EMAIL_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            LoadString(hResModule, IDS_ATTR_SUBJECT_EMAIL_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            rv = kcdb_attrib_register(&attr, &attr_id_subj_email);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_SUBJECT_DISPLAY;

            LoadString(hResModule, IDS_ATTR_SUBJECT_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            LoadString(hResModule, IDS_ATTR_SUBJECT_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            rv = kcdb_attrib_register(&attr, &attr_id_subj_display);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_ISSUER_DISPLAY;

            LoadString(hResModule, IDS_ATTR_ISSUER_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            LoadString(hResModule, IDS_ATTR_ISSUER_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            rv = kcdb_attrib_register(&attr, &attr_id_issuer_display);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_ISSUER_NAME;
            attr.flags = KCDB_ATTR_FLAG_HIDDEN;
            attr.type = KCDB_TYPE_DATA;
            attr.short_desc = NULL;
            attr.long_desc = NULL;

            rv = kcdb_attrib_register(&attr, &attr_id_issuer_name);
            if (KHM_FAILED(rv))
                break;

            attr.name = ATTRNAME_SERIAL;

            rv = kcdb_attrib_register(&attr, &attr_id_serial_number);
            if (KHM_FAILED(rv))
                break;

            /* List the credentials that are already here */
            kca_list_creds();

            /* Now we register our configuration panels. */

#ifdef GENERAL_CONFIG_PANEL
            /* This configuration panel is the one that controls
               general options.  We leave the identity specific and
               identity defaults for other configuration panels. */

            ZeroMemory(&creg, sizeof(creg));

            short_desc[0] = L'\0';

            LoadString(hResModule, IDS_CFG_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));

            long_desc[0] = L'\0';

            LoadString(hResModule, IDS_CFG_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            creg.name = CONFIGNODE_MAIN;
            creg.short_desc = short_desc;
            creg.long_desc = long_desc;
            creg.h_module = hResModule;
            creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG);
            creg.dlg_proc = config_dlgproc;
            creg.flags = 0;

            khui_cfg_register(NULL, &creg);
#endif

            /* Now we do the identity specific and identity default
               configuration panels. "KhmIdentities" is a predefined
               configuration node under which all the identity spcific
               configuration is managed. */

            if (KHM_FAILED(khui_cfg_open(NULL, L"KhmIdentities", &cnode))) {
                /* this should always work */
                assert(FALSE);
                rv = KHM_ERROR_NOT_FOUND;
                break;
            }

            /* First the tab panel for defaults for all identities */

            ZeroMemory(&creg, sizeof(creg));

            short_desc[0] = L'\0';
            LoadString(hResModule, IDS_CFG_IDS_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            long_desc[0] = L'\0';
            LoadString(hResModule, IDS_CFG_IDS_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            creg.name = CONFIGNODE_ALL_ID;
            creg.short_desc = short_desc;
            creg.long_desc = long_desc;
            creg.h_module = hResModule;
            creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG_IDS);
            creg.dlg_proc = config_ids_dlgproc;
            creg.flags = KHUI_CNFLAG_SUBPANEL;

            khui_cfg_register(cnode, &creg);

            /* Now the panel for per identity configuration */

            ZeroMemory(&creg, sizeof(creg));

            short_desc[0] = L'\0';
            LoadString(hResModule, IDS_CFG_ID_SHORT_DESC,
                       short_desc, ARRAYLENGTH(short_desc));
            long_desc[0] = L'\0';
            LoadString(hResModule, IDS_CFG_ID_LONG_DESC,
                       long_desc, ARRAYLENGTH(long_desc));

            creg.name = CONFIGNODE_PER_ID;
            creg.short_desc = short_desc;
            creg.long_desc = long_desc;
            creg.h_module = hResModule;
            creg.dlg_template = MAKEINTRESOURCE(IDD_CONFIG_ID);
            creg.dlg_proc = config_id_dlgproc;
            creg.flags = KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_INSTANCE;

            khui_cfg_register(cnode, &creg);

            khui_cfg_release(cnode);

            /* load the schema */
            if (KHM_SUCCEEDED(kmm_get_plugins_config(0, &csp_plugins))) {
                khc_load_schema(csp_plugins, plugin_schema);
                khc_close_space(csp_plugins);
            }

            /* open the plug-in and parameter configuration spaces */
            if (KHM_SUCCEEDED(kmm_get_plugin_config(MYPLUGIN_NAMEW,
                                                    KHM_FLAG_CREATE,
                                                    &csp_plugin))) {
                khc_open_space(csp_plugin, L"Parameters", KHM_FLAG_CREATE,
                               &csp_params);

                khc_close_space(csp_plugin);
            }

            /* try to install the kpkcs11 plugin now */
            install_kpkcs11_plugin();

            /* register the "KCA Help" menu item, so that we can add
               the plug-in menu item to the Help menu. */
            {
                khm_handle h_sub = NULL;

#if KH_VERSION_API < 7

                if (pkhui_action_lock == NULL ||
                    pkhui_action_unlock == NULL ||
                    pkhui_refresh_actions == NULL ||
                    pkhui_request_UI_callback == NULL)

                    goto no_custom_help;

#endif

                kmq_create_subscription(plugin_msg_proc, &h_sub);

                LoadString(hResModule, IDS_ACTION_KCA_HELP,
                           short_desc, ARRAYLENGTH(short_desc));
                LoadString(hResModule, IDS_ACTION_KCA_HELP_TT,
                           long_desc, ARRAYLENGTH(long_desc));

                action_id_kca_help = khui_action_create(NULL,
                                                        short_desc,
                                                        long_desc,
                                                        NULL,
                                                        KHUI_ACTIONTYPE_TRIGGER,
                                                        h_sub);

                if (action_id_kca_help != 0) {
                    khm_size s;
                    khm_size i;
                    khui_menu_def * help_menu;
                    khm_boolean refresh = FALSE;

                    khui_action_lock();

                    help_menu = khui_find_menu(KHUI_MENU_HELP);
                    if (help_menu) {
                        s = khui_menu_get_size(help_menu);

                        for (i=0; i < s; i++) {
                            khui_action_ref * aref;

                            aref = khui_menu_get_action(help_menu, i);

                            if (aref && !(aref->flags & KHUI_ACTIONREF_PACTION) &&
                                aref->action == KHUI_ACTION_HELP_INDEX) {

                                khui_menu_insert_action(help_menu,
                                                        i + 1,
                                                        action_id_kca_help,
                                                        0);
                                refresh = TRUE;
                                break;
                            }
                        }
                    }

                    khui_action_unlock();

                    if (refresh)
                        khui_refresh_actions();
                }

#if KH_VERSION_API < 7
            no_custom_help:
                ;
#endif
            }
        }
        break;

        /* This is the last message that will be received by the
           plugin. */
    case KMSG_SYSTEM_EXIT:
        {
            khui_config_node cnode;
            khui_config_node cn_idents;
            khm_int32 attr_id;

            kca_remove_icon();

            /* It should not be assumed that initialization of the
               plugin went well at this point since we receive a
               KMSG_SYSTEM_EXIT even if the initialization failed. */

            /* Try to remove the KCA plug-in action from Help menu if
               it was successfully registered.  Also, delete the
               action. */
            if (action_id_kca_help != 0) {

                khui_menu_def * help_menu;
                khm_boolean menu_changed = FALSE;

                khui_action_lock();

                help_menu = khui_find_menu(KHUI_MENU_HELP);
                if (help_menu) {
                    khm_size s;
                    khm_size i;

                    s = khui_menu_get_size(help_menu);
                    for (i=0; i < s; i++) {
                        khui_action_ref * aref = khui_menu_get_action(help_menu, i);

                        if (aref && !(aref->flags & KHUI_ACTIONREF_PACTION) &&
                            aref->action == action_id_kca_help) {

                            khui_menu_remove_action(help_menu, i);
                            menu_changed = TRUE;
                            break;

                        }
                    }
                }

                khui_action_delete(action_id_kca_help);

                khui_action_unlock();

                if (menu_changed)
                    khui_refresh_actions();

                action_id_kca_help = 0;
            }

            if (credtype_id != KCDB_CREDTYPE_INVALID) {
                kcdb_credtype_unregister(credtype_id);
                credtype_id = KCDB_CREDTYPE_INVALID;
            }

            if (g_credset) {
                kcdb_credset_delete(g_credset);
                g_credset = NULL;
            }

            /* Now unregister any configuration nodes we registered. */

            if (KHM_SUCCEEDED(khui_cfg_open(NULL, CONFIGNODE_MAIN, &cnode))) {
                khui_cfg_remove(cnode);
                khui_cfg_release(cnode);
            }

            if (KHM_SUCCEEDED(khui_cfg_open(NULL, L"KhmIdentities", &cn_idents))) {
                if (KHM_SUCCEEDED(khui_cfg_open(cn_idents,
                                                CONFIGNODE_ALL_ID,
                                                &cnode))) {
                    khui_cfg_remove(cnode);
                    khui_cfg_release(cnode);
                }

                if (KHM_SUCCEEDED(khui_cfg_open(cn_idents,
                                                CONFIGNODE_PER_ID,
                                                &cnode))) {
                    khui_cfg_remove(cnode);
                    khui_cfg_release(cnode);
                }

                khui_cfg_release(cn_idents);
            }

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_KCA_AUTHREALM,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_SUBJECT_EMAIL,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_SUBJECT_DISPLAY,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_ISSUER_DISPLAY,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_ISSUER_NAME,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (KHM_SUCCEEDED(kcdb_attrib_get_id(ATTRNAME_SERIAL,
                                                 &attr_id)))
                kcdb_attrib_unregister(attr_id);

            if (csp_params) {
                khc_close_space(csp_params);
                csp_params = NULL;
            }

#if KH_VERSION_API < 12
            if (hm_netidmgr)
                FreeLibrary(hm_netidmgr);

            pkhui_cw_get_primary_id = NULL;
#endif

#if KH_VERSION_API < 7
            pkhui_action_lock = NULL;
            pkhui_action_unlock = NULL;
            pkhui_refresh_actions = NULL;
            pkhui_request_UI_callback = NULL;
#endif

            /* TODO: Perform additional uninitialization
               operations. */
        }
        break;
    }

    return rv;
}