コード例 #1
0
ファイル: credprov.c プロジェクト: secure-endpoints/netidmgr
khm_int32
handle_kmsg_system_exit(void)
{
    khui_config_node cnode;
    khui_config_node cn_idents;

    /* 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. */

    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 (h_idprov_event != NULL) {
	CloseHandle(h_idprov_event);
	h_idprov_event = NULL;
    }

    /* TODO: Perform additional uninitialization operations. */

    return KHM_ERROR_SUCCESS;
}
コード例 #2
0
ファイル: mainwnd.c プロジェクト: Brainiarc7/pbis
/* perform shutdown operations */
static void
khm_pre_shutdown(void) {
    khm_handle csp_cw = NULL;
    khm_handle credset = NULL;
    khm_int32 t;
    khm_size s;

    /* Check if we should destroy all credentials on exit... */

    if (KHM_FAILED(khc_open_space(NULL, L"CredWindow", 0, &csp_cw)))
        return;

    if (KHM_FAILED(khc_read_int32(csp_cw, L"DestroyCredsOnExit", &t)) ||
        !t)
        goto _cleanup;

    if (KHM_FAILED(kcdb_credset_create(&credset)))
        goto _cleanup;

    if (KHM_FAILED(kcdb_credset_extract(credset, NULL, NULL,
                                        KCDB_TYPE_INVALID)))
        goto _cleanup;

    if (KHM_FAILED(kcdb_credset_get_size(credset, &s)) ||
        s == 0)
        goto _cleanup;

    kcdb_credset_apply(credset, mw_select_cred, NULL);

    khui_context_set(KHUI_SCOPE_GROUP,
                     NULL,
                     KCDB_CREDTYPE_INVALID,
                     NULL,
                     NULL,
                     0,
                     credset);

    khm_cred_destroy_creds(TRUE, TRUE);

 _cleanup:

    if (credset)
        kcdb_credset_delete(credset);

    if (csp_cw)
        khc_close_space(csp_cw);
}
コード例 #3
0
ファイル: afsplugin.c プロジェクト: bagdxk/openafs
/* process KMSG_SYSTEM messages */
khm_int32 KHMAPI
afs_msg_system(khm_int32 msg_subtype,
               khm_ui_4 uparam,
               void * vparam)
{
    khm_int32 rv = KHM_ERROR_UNKNOWN;

    switch(msg_subtype) {
    case KMSG_SYSTEM_INIT:

        /* If we are building against an older SDK, we should try to
           load newer APIs if it's available at run-time. */
#if KH_VERSION_API < 7
        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;

            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);

        } while (FALSE);
#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. */
        afs_icon_set_state(AFSICON_SERVICE_STOPPED, NULL);

        /* Perform critical registrations and data structure
           initalization */
        {
            kcdb_credtype ct;
            wchar_t buf[KCDB_MAXCCH_LONG_DESC];
            size_t cbsize;
            kcdb_attrib att;
            khm_handle csp_afscred = NULL;
            khm_int32 disable_afscreds = FALSE;

            ZeroMemory(&ct, sizeof(ct));
            /* first of all, register the AFS token credential type */
            ct.id = KCDB_CREDTYPE_AUTO;
            ct.name = AFS_CREDTYPE_NAME;

            if(LoadString(hResModule,
                          IDS_AFS_SHORT_DESC,
                          buf,
                          ARRAYLENGTH(buf)) != 0) {
                StringCbLength(buf, sizeof(buf), &cbsize);
                cbsize += sizeof(wchar_t);
                ct.short_desc = PMALLOC(cbsize);
                StringCbCopy(ct.short_desc, cbsize, buf);
            } else
                ct.short_desc = NULL;

            if(LoadString(hResModule,
                          IDS_AFS_LONG_DESC,
                          buf,
                          ARRAYLENGTH(buf)) != 0) {
                StringCbLength(buf, sizeof(buf), &cbsize);
                cbsize += sizeof(wchar_t);
                ct.long_desc = PMALLOC(cbsize);
                StringCbCopy(ct.long_desc, cbsize, buf);
            } else
                ct.long_desc = NULL;

            ct.icon = LoadImage(hResModule,
                                MAKEINTRESOURCE(IDI_AFSTOKEN),
                                IMAGE_ICON,
                                0, 0, LR_DEFAULTSIZE);

            kmq_create_subscription(afs_plugin_cb, &afs_sub);
            ct.sub = afs_sub;

            kcdb_credtype_register(&ct, &afs_credtype_id);

            /* register the attribute types */
            {
                kcdb_type type;

                ZeroMemory(&type, sizeof(type));
                type.comp = afs_type_principal_comp;
                type.dup = afs_type_principal_dup;
                type.isValid = afs_type_principal_isValid;
                type.toString = afs_type_principal_toString;
                type.name = AFS_TYPENAME_PRINCIPAL;
                type.id = KCDB_TYPE_INVALID;
                type.cb_max = sizeof(struct ktc_principal);
                type.cb_min = sizeof(struct ktc_principal);
                type.flags = KCDB_TYPE_FLAG_CB_FIXED;

                if(KHM_FAILED(kcdb_type_register(&type,
                                                 &afs_type_principal)))
                    goto _exit_init;
            }

            {
                kcdb_type type;
                kcdb_type *ti32 = NULL;

                kcdb_type_get_info(KCDB_TYPE_INT32, &ti32);

                ZeroMemory(&type, sizeof(type));
                type.comp = ti32->comp;
                type.dup = ti32->dup;
                type.isValid = ti32->isValid;
                type.toString = afs_type_method_toString;
                type.name = AFS_TYPENAME_METHOD;
                type.id = KCDB_TYPE_INVALID;
                type.cb_max = sizeof(khm_int32);
                type.cb_min = sizeof(khm_int32);
                type.flags = KCDB_TYPE_FLAG_CB_FIXED;

                if(KHM_FAILED(kcdb_type_register(&type,
                                                 &afs_type_method))) {
                    kcdb_type_release_info(ti32);
                    goto _exit_init;
                }

                kcdb_type_release_info(ti32);
            }

            /* now register the attributes */
            {
                wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];

                ZeroMemory(&att, sizeof(att));

                att.type = KCDB_TYPE_STRING;
                att.name = AFS_ATTRNAME_CELL;
                LoadString(hResModule,
                           IDS_ATTR_CELL_SHORT_DESC,
                           short_desc,
                           ARRAYLENGTH(short_desc));
                att.short_desc = short_desc;
                att.long_desc = NULL;
                att.id = KCDB_ATTR_INVALID;
                att.flags = KCDB_ATTR_FLAG_TRANSIENT;

                if(KHM_FAILED(rv = kcdb_attrib_register(&att,
                                                        &afs_attr_cell)))
                    goto _exit_init;
            }

            {
                wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];

                ZeroMemory(&att, sizeof(att));

                att.type = KCDB_TYPE_STRING;
                att.name = AFS_ATTRNAME_REALM;
                LoadString(hResModule,
                           IDS_ATTR_REALM_SHORT_DESC,
                           short_desc,
                           ARRAYLENGTH(short_desc));
                att.short_desc = short_desc;
                att.long_desc = NULL;
                att.id = KCDB_ATTR_INVALID;
                att.flags = KCDB_ATTR_FLAG_TRANSIENT;

                if(KHM_FAILED(rv = kcdb_attrib_register(&att,
                                                        &afs_attr_realm)))
                    goto _exit_init;
            }

            {
                wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];

                ZeroMemory(&att, sizeof(att));

                att.type = afs_type_method;
                att.name = AFS_ATTRNAME_METHOD;
                LoadString(hResModule,
                           IDS_ATTR_METHOD_SHORT_DESC,
                           short_desc,
                           ARRAYLENGTH(short_desc));
                att.short_desc = short_desc;
                att.long_desc = NULL;
                att.id = KCDB_ATTR_INVALID;
                att.flags = KCDB_ATTR_FLAG_TRANSIENT;

                if(KHM_FAILED(rv = kcdb_attrib_register(&att,
                                                        &afs_attr_method)))
                    goto _exit_init;
            }

            {
                wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];

                ZeroMemory(&att, sizeof(att));

                att.type = afs_type_principal;
                att.name = AFS_ATTRNAME_CLIENT_PRINC;
                LoadString(hResModule,
                           IDS_ATTR_CLIENT_PRINC_SHORT_DESC,
                           short_desc,
                           ARRAYLENGTH(short_desc));
                att.short_desc = short_desc;
                att.long_desc = NULL;
                att.id = KCDB_ATTR_INVALID;
                att.flags = KCDB_ATTR_FLAG_TRANSIENT;

                if(KHM_FAILED(rv = kcdb_attrib_register(&att, &afs_attr_client_princ)))
                    goto _exit_init;
            }

            {
                wchar_t short_desc[KCDB_MAXCCH_SHORT_DESC];

                ZeroMemory(&att, sizeof(att));

                att.type = afs_type_principal;
                att.name = AFS_ATTRNAME_SERVER_PRINC;
                LoadString(hResModule,
                           IDS_ATTR_SERVER_PRINC_SHORT_DESC,
                           short_desc, ARRAYLENGTH(short_desc));
                att.short_desc = short_desc;
                att.long_desc = NULL;
                att.id = KCDB_ATTR_INVALID;
                att.flags = KCDB_ATTR_FLAG_TRANSIENT;

                if(KHM_FAILED(rv = kcdb_attrib_register(&att, &afs_attr_server_princ)))
                    goto _exit_init;
            }

            /* afs_credset is our stock credentials set that we
               use for all our credset needs (instead of creating
               a new one every time) */

            if(KHM_FAILED(rv = kcdb_credset_create(&afs_credset)))
                goto _exit_init;

            if(KHM_FAILED(rv = kcdb_credtype_get_id(KRB5_CREDTYPE_NAME,
                                                    &krb5_credtype_id)))
                goto _exit_init;

            /* register the configuration nodes */
            {
                khui_config_node node_ident;
                khui_config_node_reg reg;
                wchar_t wshort_desc[KHUI_MAXCCH_SHORT_DESC];
                wchar_t wlong_desc[KHUI_MAXCCH_LONG_DESC];

                if (KHM_FAILED(rv = khui_cfg_open(NULL,
                                                  L"KhmIdentities",
                                                  &node_ident)))
                    goto _exit_init;

                ZeroMemory(&reg, sizeof(reg));
                reg.name = AFS_CONFIG_NODE_MAIN;
                reg.short_desc = wshort_desc;
                reg.long_desc = wlong_desc;
                reg.h_module = hResModule;
                reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_AFS);
                reg.dlg_proc = afs_cfg_main_proc;
                reg.flags = 0;
                LoadString(hResModule, IDS_CFG_MAIN_LONG,
                           wlong_desc, ARRAYLENGTH(wlong_desc));
                LoadString(hResModule, IDS_CFG_MAIN_SHORT,
                           wshort_desc, ARRAYLENGTH(wshort_desc));

                khui_cfg_register(NULL, &reg);

                ZeroMemory(&reg, sizeof(reg));
                reg.name = AFS_CONFIG_NODE_IDS;
                reg.short_desc = wshort_desc;
                reg.long_desc = wshort_desc;
                reg.h_module = hResModule;
                reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_IDS_TAB);
                reg.dlg_proc = afs_cfg_ids_proc;
                reg.flags = KHUI_CNFLAG_SUBPANEL;
                LoadString(hResModule, IDS_CFG_IDS_TAB,
                           wshort_desc, ARRAYLENGTH(wshort_desc));

                khui_cfg_register(node_ident, &reg);

                ZeroMemory(&reg, sizeof(reg));
                reg.name = AFS_CONFIG_NODE_ID;
                reg.short_desc = wshort_desc;
                reg.long_desc = wshort_desc;
                reg.h_module = hResModule;
                reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_ID_TAB);
                reg.dlg_proc = afs_cfg_id_proc;
                reg.flags = KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_PLURAL;
                LoadString(hResModule, IDS_CFG_ID_TAB,
                           wshort_desc, ARRAYLENGTH(wshort_desc));

                khui_cfg_register(node_ident, &reg);
            }

            /* and register the AFS message type */
            rv = kmq_register_type(AFS_MSG_TYPENAME, &afs_msg_type_id);

            if (KHM_SUCCEEDED(rv))
                kmq_subscribe(afs_msg_type_id, afs_plugin_cb);

            /* if the configuration is set to disable afscreds.exe,
               then we look for the shortcut and remove it if
               found. */
            if (KHM_SUCCEEDED(kmm_get_plugin_config(AFS_PLUGIN_NAME,
                                                    0,
                                                    &csp_afscred))) {
                wchar_t wpath[MAX_PATH];

                khc_read_int32(csp_afscred, L"Disableafscreds",
                               &disable_afscreds);

                if (disable_afscreds &&
                    afs_cfg_get_afscreds_shortcut(wpath)) {

                    DeleteFile(wpath);

                }

                khc_close_space(csp_afscred);
            }

            /* try to register the "AFS Help" menu item, if
               possible */
            {
                khm_handle h_sub = NULL;
                wchar_t short_desc[KHUI_MAXCCH_SHORT_DESC];
                wchar_t long_desc[KHUI_MAXCCH_LONG_DESC];

#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(afs_plugin_cb, &h_sub);

                LoadString(hResModule, IDS_ACTION_AFS_HELP,
                           short_desc, ARRAYLENGTH(short_desc));
                LoadString(hResModule, IDS_ACTION_AFS_HELP_TT,
                           long_desc, ARRAYLENGTH(long_desc));

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

                if (action_id_afs_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_afs_help,
                                                        0);
                                refresh = TRUE;
                                break;
                            }
                        }
                    }

                    khui_action_unlock();

                    if (refresh)
                        khui_refresh_actions();
                }

#if KH_VERSION_API < 7
            no_custom_help:
                ;
#endif
            }

        _exit_init:
            if(ct.short_desc)
                PFREE(ct.short_desc);
            if(ct.long_desc)
                PFREE(ct.long_desc);
        }
        /* now that the critical stuff is done, we move on to the
           non-critical stuff */
        if(KHM_SUCCEEDED(rv)) {
            initialized = TRUE;

            /* obtain existing tokens */
            afs_list_tokens();
        }

        /* define this so that if there are no TGT's, we don't
           deadlock trying to open a new creds dialog from within the
           new creds dialog. */
        SetEnvironmentVariable(L"KERBEROSLOGIN_NEVER_PROMPT", L"1");

        break;
        /* end of KMSG_SYSTEM_INIT */

    case KMSG_SYSTEM_EXIT:

        afs_remove_icon();

        /* Try to remove the AFS plug-in action from Help menu if it
           was successfully registered.  Also, delete the action. */
        if (action_id_afs_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_afs_help) {

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

            khui_action_delete(action_id_afs_help);

            khui_action_unlock();

            if (menu_changed)
                khui_refresh_actions();

            action_id_afs_help = 0;
        }

        if (afs_msg_type_id != -1) {
            kmq_unsubscribe(afs_msg_type_id, afs_plugin_cb);
            kmq_unregister_type(afs_msg_type_id);
        }
        if(afs_credtype_id >= 0) {
            kcdb_credtype_unregister(afs_credtype_id);
        }
#if 0
        if(afs_attr_client >= 0) {
            kcdb_attrib_unregister(afs_attr_client);
        }
#endif
        if(afs_attr_cell >= 0) {
            kcdb_attrib_unregister(afs_attr_cell);
        }
        if(afs_attr_realm >= 0) {
            kcdb_attrib_unregister(afs_attr_realm);
        }
        if(afs_attr_method >= 0) {
            kcdb_attrib_unregister(afs_attr_method);
        }
        if(afs_attr_client_princ >= 0) {
            kcdb_attrib_unregister(afs_attr_client_princ);
        }
        if(afs_attr_server_princ >= 0) {
            kcdb_attrib_unregister(afs_attr_server_princ);
        }
        if(afs_type_principal >= 0) {
            kcdb_type_unregister(afs_type_principal);
        }
        if(afs_type_method >= 0) {
            kcdb_type_unregister(afs_type_method);
        }
        initialized = FALSE;
        if(afs_credset)
            kcdb_credset_delete(afs_credset);

        /* afs_sub doesn't need to be deleted.  That is taken care
           of when unregistering the afs cred type */
        afs_sub = NULL;

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

        pkhui_action_lock = NULL;
        pkhui_action_unlock = NULL;
        pkhui_refresh_actions = NULL;
        pkhui_request_UI_callback = NULL;
#endif

        rv = KHM_ERROR_SUCCESS;
        break;
        /* end of KMSG_SYSTEM_EXIT */
    }
    return rv;
}
コード例 #4
0
ファイル: credfuncs.c プロジェクト: FarazShaikh/LikewiseSMB2
/* Completion handler for KMSG_CRED messages.  We control the overall
   logic of credentials acquisition and other operations here.  Once a
   credentials operation is triggered, each successive message
   completion notification will be used to dispatch the messages for
   the next step in processing the operation. */
void KHMAPI 
kmsg_cred_completion(kmq_message *m)
{
    khui_new_creds * nc;

#ifdef DEBUG
    assert(m->type == KMSG_CRED);
#else
    if(m->type != KMSG_CRED)
        return; /* huh? */
#endif

    switch(m->subtype) {
    case KMSG_CRED_PASSWORD:
        /* fallthrough */
    case KMSG_CRED_NEW_CREDS:
        /* Cred types have attached themselves.  Trigger the next
           phase. */
        kmq_post_message(KMSG_CRED, KMSG_CRED_DIALOG_SETUP, 0, 
                         m->vparam);
        break;

    case KMSG_CRED_RENEW_CREDS:
        nc = (khui_new_creds *) m->vparam;

        /* khm_cred_dispatch_process_message() deals with the case
           where there are no credential types that wants to
           participate in this operation. */
        khm_cred_dispatch_process_message(nc);
        break;

    case KMSG_CRED_DIALOG_SETUP:
        nc = (khui_new_creds *) m->vparam;

        khm_prep_newcredwnd(nc->hwnd);
            
        /* all the controls have been created.  Now initialize them */
        if (nc->n_types > 0) {
            kmq_post_subs_msg(nc->type_subs, 
                              nc->n_types, 
                              KMSG_CRED, 
                              KMSG_CRED_DIALOG_PRESTART, 
                              0, 
                              m->vparam);
        } else {
            PostMessage(nc->hwnd, KHUI_WM_NC_NOTIFY, 
                        MAKEWPARAM(0, WMNC_DIALOG_PROCESS_COMPLETE), 0);
        }
        break;

    case KMSG_CRED_DIALOG_PRESTART:
        /* all prestart stuff is done.  Now to activate the dialog */
        nc = (khui_new_creds *) m->vparam;
        khm_show_newcredwnd(nc->hwnd);
        
        kmq_post_subs_msg(nc->type_subs,
                          nc->n_types,
                          KMSG_CRED, 
                          KMSG_CRED_DIALOG_START, 
                          0, 
                          m->vparam);
        /* at this point, the dialog window takes over.  We let it run
           the show until KMSG_CRED_DIALOG_END is posted by the dialog
           procedure. */
        break;

    case KMSG_CRED_PROCESS:
        /* a wave of these messages have completed.  We should check
           if there's more */
        nc = (khui_new_creds *) m->vparam;

        /* if we are done processing all the plug-ins, then check if
           there were any errors reported.  Otherwise we dispatch
           another set of messages. */
        if(!khm_cred_dispatch_process_level(nc)) {

            if(kherr_is_error()) {
                khui_alert * alert;
                kherr_event * evt;
                kherr_context * ctx;
                wchar_t ws_tfmt[512];
                wchar_t w_idname[KCDB_IDENT_MAXCCH_NAME];
                wchar_t ws_title[ARRAYLENGTH(ws_tfmt) + KCDB_IDENT_MAXCCH_NAME];
                khm_size cb;

                /* For renewals, we suppress the error message for the
                   following case:

                   - The renewal was for an identity

                   - There are no identity credentials for the
                     identity (no credentials that have the same type
                     as the identity provider). */

                if (nc->subtype == KMSG_CRED_RENEW_CREDS &&
                    nc->ctx.scope == KHUI_SCOPE_IDENT &&
                    nc->ctx.identity != NULL) {
                    khm_handle tcs = NULL; /* credential set */
                    khm_size count = 0;
                    khm_int32 id_ctype = KCDB_CREDTYPE_INVALID;
                    khm_int32 delta = 0;

                    kcdb_identity_get_type(&id_ctype);
                    kcdb_credset_create(&tcs);
                    kcdb_credset_collect(tcs, NULL,
                                         nc->ctx.identity,
                                         id_ctype,
                                         &delta);
                    kcdb_credset_get_size(tcs, &count);
                    kcdb_credset_delete(tcs);

                    if (count == 0) {
                        goto done_with_op;
                    }
                }

                ctx = kherr_peek_context();
                evt = kherr_get_err_event(ctx);
                kherr_evaluate_event(evt);

                khui_alert_create_empty(&alert);

                if (nc->subtype == KMSG_CRED_NEW_CREDS) {

                    khui_alert_set_type(alert, KHUI_ALERTTYPE_ACQUIREFAIL);

                    cb = sizeof(w_idname);
                    if (nc->n_identities == 0 ||
                        KHM_FAILED(kcdb_identity_get_name(nc->identities[0],
                                                          w_idname, &cb))) {
                        /* an identity could not be determined */
                        LoadString(khm_hInstance, IDS_NC_FAILED_TITLE,
                                   ws_title, ARRAYLENGTH(ws_title));
                    } else {
                        LoadString(khm_hInstance, IDS_NC_FAILED_TITLE_I,
                                   ws_tfmt, ARRAYLENGTH(ws_tfmt));
                        StringCbPrintf(ws_title, sizeof(ws_title),
                                       ws_tfmt, w_idname);
                        khui_alert_set_ctx(alert,
                                           KHUI_SCOPE_IDENT,
                                           nc->identities[0],
                                           KCDB_CREDTYPE_INVALID,
                                           NULL);
                    }

                } else if (nc->subtype == KMSG_CRED_PASSWORD) {

                    khui_alert_set_type(alert, KHUI_ALERTTYPE_CHPW);

                    cb = sizeof(w_idname);
                    if (nc->n_identities == 0 ||
                        KHM_FAILED(kcdb_identity_get_name(nc->identities[0],
                                                          w_idname, &cb))) {
                        LoadString(khm_hInstance, IDS_NC_PWD_FAILED_TITLE,
                                   ws_title, ARRAYLENGTH(ws_title));
                    } else {
                        LoadString(khm_hInstance, IDS_NC_PWD_FAILED_TITLE_I,
                                   ws_tfmt, ARRAYLENGTH(ws_tfmt));
                        StringCbPrintf(ws_title, sizeof(ws_title),
                                       ws_tfmt, w_idname);
                        khui_alert_set_ctx(alert,
                                           KHUI_SCOPE_IDENT,
                                           nc->identities[0],
                                           KCDB_CREDTYPE_INVALID,
                                           NULL);
                    }

                } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) {

                    khui_alert_set_type(alert, KHUI_ALERTTYPE_RENEWFAIL);

                    cb = sizeof(w_idname);
                    if (nc->ctx.identity == NULL ||
                        KHM_FAILED(kcdb_identity_get_name(nc->ctx.identity,
                                                          w_idname, &cb))) {
                        LoadString(khm_hInstance, IDS_NC_REN_FAILED_TITLE,
                                   ws_title, ARRAYLENGTH(ws_title));
                    } else {
                        LoadString(khm_hInstance, IDS_NC_REN_FAILED_TITLE_I,
                                   ws_tfmt, ARRAYLENGTH(ws_tfmt));
                        StringCbPrintf(ws_title, sizeof(ws_title),
                                       ws_tfmt, w_idname);
                        khui_alert_set_ctx(alert,
                                           KHUI_SCOPE_IDENT,
                                           nc->ctx.identity,
                                           KCDB_CREDTYPE_INVALID,
                                           NULL);
                    }

                } else {
#ifdef DEBUG
                    assert(FALSE);
#endif
                }

                khui_alert_set_title(alert, ws_title);
                khui_alert_set_severity(alert, evt->severity);

                if(!evt->long_desc)
                    khui_alert_set_message(alert, evt->short_desc);
                else
                    khui_alert_set_message(alert, evt->long_desc);

                if(evt->suggestion)
                    khui_alert_set_suggestion(alert, evt->suggestion);

                if (nc->subtype == KMSG_CRED_RENEW_CREDS &&
                    nc->ctx.identity != NULL) {

                    khm_int32 n_cmd;

                    n_cmd = khm_get_identity_new_creds_action(nc->ctx.identity);

                    if (n_cmd != 0) {
                        khui_alert_add_command(alert, n_cmd);
                        khui_alert_add_command(alert, KHUI_PACTION_CLOSE);

                        khui_alert_set_flags(alert, KHUI_ALERT_FLAG_DISPATCH_CMD,
                                             KHUI_ALERT_FLAG_DISPATCH_CMD);
                    }
                }

                khui_alert_show(alert);
                khui_alert_release(alert);

                kherr_release_context(ctx);

                kherr_clear_error();
            }

        done_with_op:

            if (nc->subtype == KMSG_CRED_RENEW_CREDS) {
                kmq_post_message(KMSG_CRED, KMSG_CRED_END, 0, 
                                 m->vparam);
            } else {
                PostMessage(nc->hwnd, KHUI_WM_NC_NOTIFY, 
                            MAKEWPARAM(0, WMNC_DIALOG_PROCESS_COMPLETE),
                            0);
            }
        }
        break;

    case KMSG_CRED_END:
        /* all is done. */
        {
            khui_new_creds * nc;
            khm_boolean continue_cmdline = TRUE;

            nc = (khui_new_creds *) m->vparam;

            if (nc->subtype == KMSG_CRED_NEW_CREDS ||
                nc->subtype == KMSG_CRED_PASSWORD) {

                khm_cred_end_dialog(nc);

            } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) {

                /* if this is a renewal that was triggered while we
                   were processing the commandline, then we need to
                   update the pending renewal count. */

                if (khm_startup.processing) {
                    LONG renewals;
                    renewals = InterlockedDecrement(&khm_startup.pending_renewals);

                    if (renewals != 0) {
                        continue_cmdline = FALSE;
                    }
                }
            }

            khui_cw_destroy_cred_blob(nc);

            kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, 0);

            if (continue_cmdline)
                kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0);
        }
        break;

        /* property sheet stuff */

    case KMSG_CRED_PP_BEGIN:
        /* all the pages should have been added by now.  Just send out
           the precreate message */
        kmq_post_message(KMSG_CRED, KMSG_CRED_PP_PRECREATE, 0, 
                         m->vparam);
        break;

    case KMSG_CRED_PP_END:
        kmq_post_message(KMSG_CRED, KMSG_CRED_PP_DESTROY, 0, 
                         m->vparam);
        break;

    case KMSG_CRED_DESTROY_CREDS:
#ifdef DEBUG
        assert(m->vparam != NULL);
#endif
        khui_context_release((khui_action_context *) m->vparam);
        PFREE(m->vparam);

        kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, 0);

        kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0);
        break;

    case KMSG_CRED_IMPORT:
        {
            khm_boolean continue_cmdline = FALSE;
            LONG pending_renewals;

            /* once an import operation ends, we have to trigger a
               renewal so that other plug-ins that didn't participate
               in the import operation can have a chance at getting
               the necessary credentials.

               If we are in the middle of processing the commandline,
               we have to be a little bit careful.  We can't issue a
               commandline conituation message right now because the
               import action is still ongoing (since the renewals are
               part of the action).  Once the renewals have completed,
               the completion handler will automatically issue a
               commandline continuation message.  However, if there
               were no identities to renew, then we have to issue the
               message ourselves.
            */

            InterlockedIncrement(&khm_startup.pending_renewals);

            khm_cred_renew_all_identities();

            pending_renewals = InterlockedDecrement(&khm_startup.pending_renewals);

            if (pending_renewals == 0 && khm_startup.processing)
                kmq_post_message(KMSG_ACT, KMSG_ACT_CONTINUE_CMDLINE, 0, 0);
        }
        break;

    case KMSG_CRED_REFRESH:
        kcdb_identity_refresh_all();
        break;
    }
}
コード例 #5
0
ファイル: credfuncs.c プロジェクト: FarazShaikh/LikewiseSMB2
void
khm_cred_process_startup_actions(void) {
    khm_handle defident = NULL;

    if (!khm_startup.processing)
        return;

    if (khm_startup.init ||
        khm_startup.renew ||
        khm_startup.destroy ||
        khm_startup.autoinit) {
        kcdb_identity_get_default(&defident);
    }

    /* For asynchronous actions, we trigger the action and then exit
       the loop.  Once the action completes, the completion handler
       will trigger a continuation message which will result in this
       function getting called again.  Then we can proceed with the
       rest of the startup actions. */
    do {
        if (khm_startup.init) {

            khm_cred_obtain_new_creds_for_ident(defident, NULL);
            khm_startup.init = FALSE;
            break;
        }

        if (khm_startup.import) {
            khm_cred_import();
            khm_startup.import = FALSE;

            /* we also set the renew command to false here because we
               trigger a renewal for all the identities at the end of
               the import operation anyway. */
            khm_startup.renew = FALSE;
            break;
        }

        if (khm_startup.renew) {
            LONG pending_renewals;

            /* if there are no credentials, we just skip over the
               renew action. */

            khm_startup.renew = FALSE;

            InterlockedIncrement(&khm_startup.pending_renewals);

            khm_cred_renew_all_identities();

            pending_renewals = InterlockedDecrement(&khm_startup.pending_renewals);

            if (pending_renewals != 0)
                break;

            /* if there were no pending renewals, then we just fall
               through. This means that either there were no
               identities to renew, or all the renewals completed.  If
               all the renewals completed, then the commandline
               contiuation message wasn't triggered.  Either way, we
               must fall through if the count is zero. */
        }

        if (khm_startup.destroy) {

            khm_startup.destroy = FALSE;

            if (defident) {
                khm_cred_destroy_identity(defident);
                break;
            }
        }

        if (khm_startup.autoinit) {
            khm_size count = 0;
            khm_handle credset = NULL;
            khm_int32 ctype_ident = KCDB_CREDTYPE_INVALID;
            khm_int32 delta = 0;

            khm_startup.autoinit = FALSE;

            kcdb_credset_create(&credset);
            kcdb_identity_get_type(&ctype_ident);

            kcdb_credset_collect(credset, NULL,
                                 defident, ctype_ident,
                                 &delta);

            kcdb_credset_get_size(credset, &count);

            kcdb_credset_delete(credset);

            if (count == 0) {
                if (defident)
                    khui_context_set(KHUI_SCOPE_IDENT,
                                     defident,
                                     KCDB_CREDTYPE_INVALID,
                                     NULL, NULL, 0,
                                     NULL);
                else
                    khui_context_reset();

                khm_cred_obtain_new_creds(NULL);
                break;
            }
        }

        if (khm_startup.exit) {
            PostMessage(khm_hwnd_main,
                        WM_COMMAND,
                        MAKEWPARAM(KHUI_ACTION_EXIT, 0), 0);
            khm_startup.exit = FALSE;
            break;
        }

        if (khm_startup.display & SOPTS_DISPLAY_HIDE) {
            khm_hide_main_window();
        } else if (khm_startup.display & SOPTS_DISPLAY_SHOW) {
            khm_show_main_window();
        }
        khm_startup.display = 0;

        /* when we get here, then we are all done with the command
           line stuff */
        khm_startup.processing = FALSE;
        khm_startup.remote = FALSE;

        kmq_post_message(KMSG_ACT, KMSG_ACT_END_CMDLINE, 0, 0);
    } while(FALSE);

    if (defident)
        kcdb_identity_release(defident);
}
コード例 #6
0
ファイル: plugin.c プロジェクト: secure-endpoints/netidmgr
/* 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;

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

        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. */

        /* TODO: Also list out the credentials of this type that
           already exist. */

        /* Now we register our configuration panels. */


        /* 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);

        /* 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);

        /* get IdentProvider handle to which this plugin belongs
           it is possible to use kcdb_identity_create_ex() function with
           proper h_idprov */
        if (KHM_FAILED(kcdb_identpro_find(IDPROV_NAMEW, &h_idprov))) {
            return KHM_ERROR_UNKNOWN;
        }
    }
    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;

        /* 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. */

        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);
        }

        /* TODO: Perform additional uninitialization
           operations. */

        kcdb_identpro_release(h_idprov);
    }
    break;
    }

    return rv;
}
コード例 #7
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;
}