From a15641c1710ccb204f6dc66c539c42b7617a2ea9 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 29 Nov 2005 22:05:23 +0000 Subject: [PATCH] KFW Network Identity Manager (Beta 2) All features completed except for: * Debug Window * KRB5.INI (aka Realm) Editor * Column Selection * Graphics are incomplete * Documentation is incomplete ticket: new status: resolved component: windows target_version: 1.4.4 tags: pullup git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@17516 dc483132-0cff-0310-8789-dd5450dbe970 --- src/windows/identity/ChangeLog | 19 + src/windows/identity/Makefile | 77 +- src/windows/identity/apiversion.txt | 54 + src/windows/identity/config/Makefile | 96 +- src/windows/identity/config/Makefile.w32 | 62 +- .../identity/config/netidmgr_intver.h.in | 34 + .../identity/config/netidmgr_version.h.in | 62 + src/windows/identity/doc/Makefile | 8 +- src/windows/identity/doc/cred_aquisition.h | 4 +- src/windows/identity/doc/cred_data_types.h | 2 +- src/windows/identity/doc/cred_main.h | 2 +- src/windows/identity/doc/cred_msgs.h | 2 +- src/windows/identity/doc/cred_prop_pages.h | 2 +- src/windows/identity/doc/images/Thumbs.db | Bin 28160 -> 0 bytes .../identity/doc/images/khimaira_logo_old.jpg | Bin 9550 -> 0 bytes .../doc/images/khimaira_logo_small_old.jpg | Bin 1665 -> 0 bytes src/windows/identity/doc/main_page.h | 13 +- src/windows/identity/doc/plugin_framework.h | 2 +- src/windows/identity/doc/plugin_locale.h | 2 +- src/windows/identity/doc/plugin_main.h | 2 +- src/windows/identity/doc/plugin_structure.h | 2 +- src/windows/identity/doc/ui_actions.h | 2 +- src/windows/identity/doc/ui_context.h | 2 +- src/windows/identity/doc/ui_main.h | 2 +- src/windows/identity/doc/ui_menus.h | 2 +- src/windows/identity/help/Makefile | 2 +- .../identity/help/html/about_netidmgr.htm | 67 + .../help/html/{menu_exit.htm => act_chpw.htm} | 4 +- ...u_properties.htm => act_destroy_creds.htm} | 4 +- .../identity/help/html/act_import_creds.htm | 11 + .../identity/help/html/act_new_creds.htm | 11 + .../identity/help/html/act_renew_creds.htm | 11 + .../identity/help/html/act_set_default.htm | 11 + src/windows/identity/help/html/bugs.htm | 33 + .../identity/help/html/concept_cred_pro.htm | 11 + .../identity/help/html/concept_ident_pro.htm | 11 + .../identity/help/html/concept_identity.htm | 11 + src/windows/identity/help/html/concepts.htm | 11 + src/windows/identity/help/html/copyright.htm | 48 + src/windows/identity/help/html/howdoi.htm | 37 + .../identity/help/html/images/Thumbs.db | Bin 3584 -> 0 bytes .../identity/help/html/images/link.GIF | Bin 932 -> 0 bytes .../identity/help/html/images/logo.jpg | Bin 0 -> 2014 bytes .../identity/help/html/images/logo_shade.jpg | Bin 0 -> 1641 bytes .../help/html/images/screen_app_icon.bmp | Bin 0 -> 144666 bytes .../help/html/images/screen_main_wnd.bmp | Bin 0 -> 915894 bytes .../help/html/images/screen_menu_bar.bmp | Bin 0 -> 12374 bytes .../html/images/screen_menu_credential.bmp | Bin 0 -> 129846 bytes .../help/html/images/screen_menu_file.bmp | Bin 0 -> 36838 bytes .../help/html/images/screen_menu_help.bmp | Bin 0 -> 51414 bytes .../help/html/images/screen_menu_options.bmp | Bin 0 -> 29494 bytes .../help/html/images/screen_menu_view.bmp | Bin 0 -> 64854 bytes .../help/html/images/screen_tb_standard.bmp | Bin 0 -> 52634 bytes .../help/html/images/screen_tray_icon.bmp | Bin 0 -> 40122 bytes src/windows/identity/help/html/khm.css | 13 - src/windows/identity/help/html/menu_all.htm | 41 + .../identity/help/html/menu_credential.htm | 86 + src/windows/identity/help/html/menu_file.htm | 44 +- src/windows/identity/help/html/menu_help.htm | 60 + .../identity/help/html/menu_options.htm | 49 + src/windows/identity/help/html/menu_view.htm | 90 + src/windows/identity/help/html/nidmgr.css | 71 + .../identity/help/html/tb_standard.htm | 68 + src/windows/identity/help/html/template.htm | 4 +- src/windows/identity/help/html/use_start.htm | 65 + src/windows/identity/help/html/using.htm | 47 + src/windows/identity/help/html/welcome.htm | 64 +- src/windows/identity/help/html/wnd_main.htm | 89 + src/windows/identity/help/khhelp.h | 13 +- src/windows/identity/help/netidmgr.hhp | 11 + src/windows/identity/help/popups.txt | 1 + src/windows/identity/help/popups_newcreds.txt | 1 + src/windows/identity/help/toc.hhc | 131 +- src/windows/identity/include/Makefile | 3 +- src/windows/identity/include/khdefs.h | 2 +- src/windows/identity/include/kherror.h | 7 +- src/windows/identity/include/khlist.h | 2 +- src/windows/identity/include/khmsgtypes.h | 33 +- .../include/{khthread.h => netidmgr.h} | 27 +- src/windows/identity/kconfig/api.c | 483 +++-- src/windows/identity/kconfig/kconfig.h | 193 +- .../identity/kconfig/kconfiginternal.h | 29 +- src/windows/identity/kconfig/kconfigmain.c | 2 +- src/windows/identity/kconfig/registry.c | 2 +- src/windows/identity/kcreddb/attrib.c | 114 +- src/windows/identity/kcreddb/attrib.h | 4 +- src/windows/identity/kcreddb/buf.c | 38 +- src/windows/identity/kcreddb/buf.h | 2 +- src/windows/identity/kcreddb/credential.c | 307 +-- src/windows/identity/kcreddb/credential.h | 3 +- src/windows/identity/kcreddb/credset.c | 134 +- src/windows/identity/kcreddb/credset.h | 6 +- src/windows/identity/kcreddb/credtype.c | 52 +- src/windows/identity/kcreddb/credtype.h | 4 +- src/windows/identity/kcreddb/identity.c | 298 +-- src/windows/identity/kcreddb/identity.h | 6 +- src/windows/identity/kcreddb/init.c | 2 +- src/windows/identity/kcreddb/kcreddb.h | 132 +- .../identity/kcreddb/kcreddbinternal.h | 5 +- src/windows/identity/kcreddb/kcreddbmain.c | 2 +- src/windows/identity/kcreddb/type.c | 66 +- src/windows/identity/kcreddb/type.h | 4 +- src/windows/identity/kherr/kherr.c | 123 +- src/windows/identity/kherr/kherr.h | 25 +- src/windows/identity/kherr/kherrinternal.h | 6 +- src/windows/identity/kherr/kherrmain.c | 2 +- src/windows/identity/kmm/kmm.c | 43 +- src/windows/identity/kmm/kmm.h | 68 +- src/windows/identity/kmm/kmm_module.c | 396 +++- src/windows/identity/kmm/kmm_plugin.c | 66 +- src/windows/identity/kmm/kmm_reg.c | 54 +- src/windows/identity/kmm/kmm_registrar.c | 196 +- src/windows/identity/kmm/kmmconfig.csv | 15 +- src/windows/identity/kmm/kmminternal.h | 59 +- src/windows/identity/kmm/kmmmain.c | 10 +- src/windows/identity/kmm/kplugin.h | 2 +- src/windows/identity/kmm/lang/kmm_msgs.mc | 68 + src/windows/identity/kmq/consumer.c | 68 +- src/windows/identity/kmq/init.c | 4 +- src/windows/identity/kmq/kmq.h | 6 +- src/windows/identity/kmq/kmqinternal.h | 3 +- src/windows/identity/kmq/kmqmain.c | 2 +- src/windows/identity/kmq/msgtype.c | 30 +- src/windows/identity/kmq/publisher.c | 165 +- src/windows/identity/nidmgrdll/Makefile | 5 +- src/windows/identity/nidmgrdll/dllmain.c | 2 +- src/windows/identity/nidmgrdll/nidmgrdll.rc | 2 +- .../identity/plugins/common/dynimport.c | 150 +- .../identity/plugins/common/dynimport.h | 9 +- .../identity/plugins/common/krb5common.c | 305 ++- .../identity/plugins/common/krb5common.h | 13 +- src/windows/identity/plugins/krb4/Makefile | 9 +- .../identity/plugins/krb4/errorfuncs.c | 56 +- .../identity/plugins/krb4/errorfuncs.h | 19 +- .../identity/plugins/krb4/images/plugin.ico | Bin 0 -> 7278 bytes .../identity/plugins/krb4/krb4configdlg.c | 161 +- src/windows/identity/plugins/krb4/krb4funcs.c | 322 ++- src/windows/identity/plugins/krb4/krb4funcs.h | 96 +- .../plugins/krb4/{main.c => krb4main.c} | 42 +- .../identity/plugins/krb4/krb4newcreds.c | 657 +++++++ .../identity/plugins/krb4/krb4plugin.c | 167 +- .../identity/plugins/krb4/krbconfig.csv | 11 +- src/windows/identity/plugins/krb4/krbcred.h | 33 +- .../plugins/krb4/lang/en_us/langres.rc | 65 +- src/windows/identity/plugins/krb4/langres.h | 25 +- src/windows/identity/plugins/krb4/version.rc | 66 + src/windows/identity/plugins/krb5/Makefile | 15 +- src/windows/identity/plugins/krb5/datarep.c | 4 +- src/windows/identity/plugins/krb5/datarep.h | 4 +- .../identity/plugins/krb5/errorfuncs.c | 2 +- .../identity/plugins/krb5/errorfuncs.h | 2 +- .../krb5/images/deleted.ico} | Bin 1406 -> 1406 bytes .../plugins/krb5/images/krb5plugin.ico | Bin 0 -> 7278 bytes .../krb5/images/modified.ico} | Bin 1406 -> 1406 bytes .../identity/plugins/krb5/images/new.ico | Bin 0 -> 1406 bytes .../identity/plugins/krb5/images/normal.ico | Bin 0 -> 1406 bytes .../identity/plugins/krb5/krb5configcc.c | 547 ++++++ .../identity/plugins/krb5/krb5configdlg.c | 1719 +++++++++++++++-- .../identity/plugins/krb5/krb5configid.c | 254 +++ .../identity/plugins/krb5/krb5configids.c | 250 +++ src/windows/identity/plugins/krb5/krb5funcs.c | 216 ++- src/windows/identity/plugins/krb5/krb5funcs.h | 13 +- .../identity/plugins/krb5/krb5identpro.c | 345 +++- .../plugins/krb5/{main.c => krb5main.c} | 18 +- .../identity/plugins/krb5/krb5newcreds.c | 127 +- .../identity/plugins/krb5/krb5plugin.c | 224 ++- src/windows/identity/plugins/krb5/krb5props.c | 121 +- src/windows/identity/plugins/krb5/krb5util.c | 40 +- .../identity/plugins/krb5/krbconfig.csv | 6 +- src/windows/identity/plugins/krb5/krbcred.h | 46 +- .../plugins/krb5/lang/en_us/langres.rc | 149 +- src/windows/identity/plugins/krb5/langres.h | 63 +- src/windows/identity/plugins/krb5/version.rc | 64 + src/windows/identity/ui/Makefile | 16 +- src/windows/identity/ui/aboutwnd.c | 8 +- src/windows/identity/ui/aboutwnd.h | 2 +- src/windows/identity/ui/addrchange.c | 92 + .../krb4/datarep.h => ui/addrchange.h} | 17 +- src/windows/identity/ui/appglobal.h | 2 +- src/windows/identity/ui/appver.rc | 40 + src/windows/identity/ui/cfg_general_wnd.c | 27 +- src/windows/identity/ui/cfg_identities_wnd.c | 74 +- src/windows/identity/ui/cfg_notif_wnd.c | 17 +- src/windows/identity/ui/cfg_plugins_wnd.c | 15 +- src/windows/identity/ui/configwnd.c | 70 +- src/windows/identity/ui/configwnd.h | 2 +- src/windows/identity/ui/credfuncs.c | 167 +- src/windows/identity/ui/credfuncs.h | 8 +- src/windows/identity/ui/credwnd.c | 544 ++++-- src/windows/identity/ui/credwnd.h | 17 +- src/windows/identity/ui/htwnd.c | 26 +- src/windows/identity/ui/htwnd.h | 2 +- src/windows/identity/ui/images/Thumbs.db | Bin 116224 -> 0 bytes src/windows/identity/ui/images/bitmap1.bmp | Bin 1270 -> 0 bytes src/windows/identity/ui/images/cfg_plugin.ico | Bin 0 -> 10134 bytes src/windows/identity/ui/images/chpw.bmp | Bin 2430 -> 2430 bytes src/windows/identity/ui/images/help.bmp | Bin 2430 -> 2430 bytes src/windows/identity/ui/images/icon1.ico | Bin 766 -> 0 bytes src/windows/identity/ui/images/id-dis-sm.bmp | Bin 1014 -> 822 bytes src/windows/identity/ui/images/import.bmp | Bin 2430 -> 2430 bytes .../identity/ui/images/main_app_old.ico | Bin 7854 -> 0 bytes src/windows/identity/ui/images/text1138.png | Bin 378 -> 0 bytes src/windows/identity/ui/images/tk-delete.bmp | Bin 2430 -> 2430 bytes src/windows/identity/ui/images/tk-new.bmp | Bin 2430 -> 2430 bytes src/windows/identity/ui/images/tk-refresh.bmp | Bin 2430 -> 2430 bytes src/windows/identity/ui/images/vw-refresh.bmp | Bin 2430 -> 2430 bytes .../identity/ui/images/wdg_collapsed.bmp | Bin 1014 -> 774 bytes .../identity/ui/images/wdg_collapsed_hi.bmp | Bin 1014 -> 774 bytes .../identity/ui/images/wdg_expanded.bmp | Bin 1014 -> 774 bytes .../identity/ui/images/wdg_expanded_hi.bmp | Bin 1014 -> 774 bytes src/windows/identity/ui/images/wdg_stick.bmp | Bin 0 -> 774 bytes .../identity/ui/images/wdg_stick_hi.bmp | Bin 0 -> 774 bytes src/windows/identity/ui/images/wdg_stuck.bmp | Bin 0 -> 774 bytes .../identity/ui/images/wdg_stuck_hi.bmp | Bin 0 -> 774 bytes src/windows/identity/ui/khmapp.h | 5 +- src/windows/identity/ui/lang/en_us/khapp.rc | 94 +- src/windows/identity/ui/main.c | 108 +- src/windows/identity/ui/mainmenu.c | 47 +- src/windows/identity/ui/mainmenu.h | 2 +- src/windows/identity/ui/mainwnd.c | 58 +- src/windows/identity/ui/mainwnd.h | 2 +- src/windows/identity/ui/newcredwnd.c | 18 +- src/windows/identity/ui/newcredwnd.h | 2 +- src/windows/identity/ui/notifier.c | 193 +- src/windows/identity/ui/notifier.h | 10 +- src/windows/identity/ui/passwnd.h | 2 +- src/windows/identity/ui/propertywnd.c | 14 +- src/windows/identity/ui/propertywnd.h | 2 +- src/windows/identity/ui/reqdaemon.c | 10 +- src/windows/identity/ui/reqdaemon.h | 2 +- src/windows/identity/ui/resource.h | 19 +- src/windows/identity/ui/statusbar.c | 95 +- src/windows/identity/ui/statusbar.h | 21 +- src/windows/identity/ui/timer.c | 81 +- src/windows/identity/ui/timer.h | 2 +- src/windows/identity/ui/toolbar.c | 45 +- src/windows/identity/ui/toolbar.h | 4 +- src/windows/identity/uilib/accel.csv | 5 +- src/windows/identity/uilib/action.c | 36 +- src/windows/identity/uilib/actions.csv | 1 + src/windows/identity/uilib/alert.c | 46 +- src/windows/identity/uilib/configui.c | 137 +- src/windows/identity/uilib/configui.h | 2 +- src/windows/identity/uilib/creddlg.c | 76 +- src/windows/identity/uilib/khaction.h | 2 +- src/windows/identity/uilib/khactiondef.h | 4 +- src/windows/identity/uilib/khalerts.h | 12 +- src/windows/identity/uilib/khconfigui.h | 19 +- src/windows/identity/uilib/khhtlink.h | 2 +- src/windows/identity/uilib/khnewcred.h | 8 +- src/windows/identity/uilib/khprops.h | 9 +- src/windows/identity/uilib/khremote.h | 2 +- src/windows/identity/uilib/khrescache.h | 2 +- src/windows/identity/uilib/khtracker.h | 3 +- src/windows/identity/uilib/khuidefs.h | 2 +- src/windows/identity/uilib/propsheet.c | 104 +- src/windows/identity/uilib/propwnd.c | 2 +- src/windows/identity/uilib/rescache.c | 12 +- src/windows/identity/uilib/trackerwnd.c | 23 +- src/windows/identity/uilib/uilibmain.c | 7 +- src/windows/identity/util/Makefile | 16 +- src/windows/identity/util/hashtable.c | 13 +- src/windows/identity/util/hashtable.h | 2 +- src/windows/identity/util/mstring.c | 96 +- src/windows/identity/util/mstring.h | 18 +- src/windows/identity/util/perfstat.c | 249 +++ src/windows/identity/util/perfstat.h | 66 + src/windows/identity/util/sync.c | 7 +- src/windows/identity/util/sync.h | 2 +- src/windows/identity/util/utils.h | 3 +- 270 files changed, 11461 insertions(+), 3010 deletions(-) create mode 100644 src/windows/identity/ChangeLog create mode 100644 src/windows/identity/apiversion.txt create mode 100644 src/windows/identity/config/netidmgr_intver.h.in create mode 100644 src/windows/identity/config/netidmgr_version.h.in delete mode 100644 src/windows/identity/doc/images/Thumbs.db delete mode 100644 src/windows/identity/doc/images/khimaira_logo_old.jpg delete mode 100644 src/windows/identity/doc/images/khimaira_logo_small_old.jpg create mode 100644 src/windows/identity/help/html/about_netidmgr.htm rename src/windows/identity/help/html/{menu_exit.htm => act_chpw.htm} (56%) rename src/windows/identity/help/html/{menu_properties.htm => act_destroy_creds.htm} (56%) create mode 100644 src/windows/identity/help/html/act_import_creds.htm create mode 100644 src/windows/identity/help/html/act_new_creds.htm create mode 100644 src/windows/identity/help/html/act_renew_creds.htm create mode 100644 src/windows/identity/help/html/act_set_default.htm create mode 100644 src/windows/identity/help/html/bugs.htm create mode 100644 src/windows/identity/help/html/concept_cred_pro.htm create mode 100644 src/windows/identity/help/html/concept_ident_pro.htm create mode 100644 src/windows/identity/help/html/concept_identity.htm create mode 100644 src/windows/identity/help/html/concepts.htm create mode 100644 src/windows/identity/help/html/copyright.htm create mode 100644 src/windows/identity/help/html/howdoi.htm delete mode 100644 src/windows/identity/help/html/images/Thumbs.db delete mode 100644 src/windows/identity/help/html/images/link.GIF create mode 100644 src/windows/identity/help/html/images/logo.jpg create mode 100644 src/windows/identity/help/html/images/logo_shade.jpg create mode 100644 src/windows/identity/help/html/images/screen_app_icon.bmp create mode 100644 src/windows/identity/help/html/images/screen_main_wnd.bmp create mode 100644 src/windows/identity/help/html/images/screen_menu_bar.bmp create mode 100644 src/windows/identity/help/html/images/screen_menu_credential.bmp create mode 100644 src/windows/identity/help/html/images/screen_menu_file.bmp create mode 100644 src/windows/identity/help/html/images/screen_menu_help.bmp create mode 100644 src/windows/identity/help/html/images/screen_menu_options.bmp create mode 100644 src/windows/identity/help/html/images/screen_menu_view.bmp create mode 100644 src/windows/identity/help/html/images/screen_tb_standard.bmp create mode 100644 src/windows/identity/help/html/images/screen_tray_icon.bmp delete mode 100644 src/windows/identity/help/html/khm.css create mode 100644 src/windows/identity/help/html/menu_all.htm create mode 100644 src/windows/identity/help/html/menu_credential.htm create mode 100644 src/windows/identity/help/html/menu_help.htm create mode 100644 src/windows/identity/help/html/menu_options.htm create mode 100644 src/windows/identity/help/html/menu_view.htm create mode 100644 src/windows/identity/help/html/nidmgr.css create mode 100644 src/windows/identity/help/html/tb_standard.htm create mode 100644 src/windows/identity/help/html/use_start.htm create mode 100644 src/windows/identity/help/html/using.htm create mode 100644 src/windows/identity/help/html/wnd_main.htm create mode 100644 src/windows/identity/help/popups.txt create mode 100644 src/windows/identity/help/popups_newcreds.txt rename src/windows/identity/include/{khthread.h => netidmgr.h} (67%) create mode 100644 src/windows/identity/plugins/krb4/images/plugin.ico rename src/windows/identity/plugins/krb4/{main.c => krb4main.c} (75%) create mode 100644 src/windows/identity/plugins/krb4/krb4newcreds.c create mode 100644 src/windows/identity/plugins/krb4/version.rc rename src/windows/identity/{ui/images/wgt_arrow_expand.ico => plugins/krb5/images/deleted.ico} (77%) create mode 100644 src/windows/identity/plugins/krb5/images/krb5plugin.ico rename src/windows/identity/{ui/images/wgt_arrow_collapse.ico => plugins/krb5/images/modified.ico} (72%) create mode 100644 src/windows/identity/plugins/krb5/images/new.ico create mode 100644 src/windows/identity/plugins/krb5/images/normal.ico create mode 100644 src/windows/identity/plugins/krb5/krb5configcc.c create mode 100644 src/windows/identity/plugins/krb5/krb5configid.c create mode 100644 src/windows/identity/plugins/krb5/krb5configids.c rename src/windows/identity/plugins/krb5/{main.c => krb5main.c} (92%) create mode 100644 src/windows/identity/plugins/krb5/version.rc create mode 100644 src/windows/identity/ui/addrchange.c rename src/windows/identity/{plugins/krb4/datarep.h => ui/addrchange.h} (65%) create mode 100644 src/windows/identity/ui/appver.rc delete mode 100644 src/windows/identity/ui/images/Thumbs.db delete mode 100644 src/windows/identity/ui/images/bitmap1.bmp create mode 100644 src/windows/identity/ui/images/cfg_plugin.ico delete mode 100644 src/windows/identity/ui/images/icon1.ico delete mode 100644 src/windows/identity/ui/images/main_app_old.ico delete mode 100644 src/windows/identity/ui/images/text1138.png create mode 100644 src/windows/identity/ui/images/wdg_stick.bmp create mode 100644 src/windows/identity/ui/images/wdg_stick_hi.bmp create mode 100644 src/windows/identity/ui/images/wdg_stuck.bmp create mode 100644 src/windows/identity/ui/images/wdg_stuck_hi.bmp create mode 100644 src/windows/identity/util/perfstat.c create mode 100644 src/windows/identity/util/perfstat.h diff --git a/src/windows/identity/ChangeLog b/src/windows/identity/ChangeLog new file mode 100644 index 000000000..ada18d283 --- /dev/null +++ b/src/windows/identity/ChangeLog @@ -0,0 +1,19 @@ +2005-11-29 Jeffrey Altman + +Second Beta of KFW 3.0.0: + +All features completed except for: + + * Debug Window + + * KRB5.INI (aka Realm) Editor + + * Column Selection + + * Graphics are incomplete + + * Documentation is incomplete + + + + diff --git a/src/windows/identity/Makefile b/src/windows/identity/Makefile index 3a79ee5f5..253d71935 100644 --- a/src/windows/identity/Makefile +++ b/src/windows/identity/Makefile @@ -47,126 +47,137 @@ RMAKE=$(MAKECMD) /nologo clean start: config: start - $(ECHO) Entering $@: + $(ECHO) -- Entering $@: $(CD) $@ $(RMAKE) $(CD) .. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ include: config - $(ECHO) Entering $@: + $(ECHO) -- Entering $@: $(CD) $@ $(RMAKE) $(CD) .. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ util: include - $(ECHO) Entering $@: + $(ECHO) -- Entering $@: $(CD) $@ $(RMAKE) $(CD) .. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ kherr: util - $(ECHO) Entering $@: + $(ECHO) -- Entering $@: $(CD) $@ $(RMAKE) $(CD) .. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ kconfig: kherr - $(ECHO) Entering $@: + $(ECHO) -- Entering $@: $(CD) $@ $(RMAKE) $(CD) .. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ kmq: kconfig - $(ECHO) Entering $@: + $(ECHO) -- Entering $@: $(CD) $@ $(RMAKE) $(CD) .. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ kcreddb: kmq - $(ECHO) Entering $@: + $(ECHO) -- Entering $@: $(CD) $@ $(RMAKE) $(CD) .. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ kmm: kcreddb - $(ECHO) Entering $@: + $(ECHO) -- Entering $@: $(CD) $@ $(RMAKE) $(CD) .. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ help: kmm - $(ECHO) Entering $@: + $(ECHO) -- Entering $@: $(CD) $@ $(RMAKE) $(CD) .. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ uilib: help - $(ECHO) Entering $@: + $(ECHO) -- Entering $@: $(CD) $@ $(RMAKE) $(CD) .. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ nidmgrdll: uilib - $(ECHO) Entering $@ + $(ECHO) -- Entering $@ $(CD) $@ $(RMAKE) $(CD) .. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ ui: nidmgrdll - $(ECHO) Entering $@: + $(ECHO) -- Entering $@: $(CD) $@ $(RMAKE) $(CD) .. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ # Now build the plugins plugincommon: ui - $(ECHO) Entering $@ + $(ECHO) -- Entering $@ $(CD) plugins\common $(RMAKE) $(CD) ..\.. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ krb5plugin: plugincommon - $(ECHO) Entering $@ + $(ECHO) -- Entering $@ $(CD) plugins\krb5 $(RMAKE) $(CD) ..\.. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ !ifndef NO_KRB4 finale: krb4plugin krb4plugin: plugincommon - $(ECHO) Entering $@ + $(ECHO) -- Entering $@ $(CD) plugins\krb4 $(RMAKE) $(CD) ..\.. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ +!endif + +!ifdef BUILD_AFS +finale: afsplugin + +afsplugin: plugincommon + $(ECHO) -- Entering $@ + $(CD) plugins\afs + $(RMAKE) + $(CD) ..\.. + $(ECHO) -- Done with $@ !endif finale: krb5plugin - $(ECHO) Done. + $(ECHO) -- Done. pdoc: doc: pdoc - $(ECHO) Entering $@: + $(ECHO) -- Entering $@: $(CD) $@ $(RMAKE) $(CD) .. - $(ECHO) Done with $@ + $(ECHO) -- Done with $@ clean:: $(MAKECMD) /nologo CLEANRUN=1 diff --git a/src/windows/identity/apiversion.txt b/src/windows/identity/apiversion.txt new file mode 100644 index 000000000..44ce7603f --- /dev/null +++ b/src/windows/identity/apiversion.txt @@ -0,0 +1,54 @@ +# Copyright (c) 2004 Massachusetts Institute of Technology +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +# This file documents the versions of the API for NetIDMgr. The +# syntax of the file is: +# +# Version= +# AppVersion= +# Date= | NOTRELEASED +# # +# +# # comment +# Schema: +# # comment + + +#---------------------------------------------------------------- +Version=1 +AppVersion=0.1.0.0 +Date=NOTRELEASED +# Original Khimaira API. + +#---------------------------------------------------------------- +Version=2 +AppVersion=0.1.1.0 +Date=Nov 01, 2005 +# Alpha release of NetIDMgr + +#---------------------------------------------------------------- +Version=3 +AppVersion=0.1.2.0 +Date=NOTRELEASED +# Beta release + diff --git a/src/windows/identity/config/Makefile b/src/windows/identity/config/Makefile index 686a044ce..e720bd804 100644 --- a/src/windows/identity/config/Makefile +++ b/src/windows/identity/config/Makefile @@ -25,7 +25,16 @@ MODULE=config !include -all: mkalldirs mkversion +all: showvars mkalldirs mkversion + +showvars: + $(ECHO) SRC= $(SRC) + $(ECHO) DESTDIR = $(DESTDIR) + $(ECHO) OBJDIR = $(OBJDIR) + $(ECHO). + $(ECHO) CC = $(CC) + $(ECHO) DOXYGEN = $(DOXYGEN) + $(ECHO) HHC = $(HHC) mkalldirs: ! if !exist($(DESTROOT)) @@ -54,7 +63,9 @@ mkalldirs: ! endif $(ECHO) Done creating directories. -VERSIONINC=$(INCDIR)\khimaira_version.h +VERSIONINT=$(INCDIR)\netidmgr_intver.h + +VERSIONEXT=$(INCDIR)\netidmgr_version.h # Version related defines @@ -75,59 +86,40 @@ kh_fileos=VOS_NT_WINDOWS32 kh_filetype_app=VFT_APP kh_filetype_dll=VFT_DLL -mkversion: $(VERSIONINC) - -$(VERSIONINC): Makefile - $(CP) << $(VERSIONINC) -/* - * This is an autogenerated file. Do not modify directly. - * - * File generated by running $(MAKE) in $(MAKEDIR) - * To regenerate, run "$(MAKE) clean" and "$(MAKE) all" on $(MAKEDIR) - */ -#ifndef __KHIMAIRA_VERSION_H -#define __KHIMAIRA_VERSION_H - -/* Version number macros */ -#define KH_VERSION_MAJOR $(KHIMAIRA_VERSION_MAJOR) -#define KH_VERSION_MINOR $(KHIMAIRA_VERSION_MINOR) -#define KH_VERSION_PATCH $(KHIMAIRA_VERSION_PATCH) -#define KH_VERSION_AUX $(KHIMAIRA_VERSION_AUX) -#define KH_VERSION_LIST $(KHIMAIRA_VERSIONC) -#define KH_VERSION_STRING "$(KHIMAIRA_VERSION)" -#define KH_VERSION_STRINGW L"$(KHIMAIRA_VERSION)" -#define KH_VERSION_STRINGC "$(KHIMAIRA_VERSIONC)" -#define KH_VERSION_STRINGCW L"$(KHIMAIRA_VERSIONC)" - -/* Version definition macros */ -#define KH_VER_FILEFLAGS $(kh_fileflags) -#define KH_VER_FILEOS $(kh_fileos) -#define KH_VER_FILETYPEDLL $(kh_filetype_dll) -#define KH_VER_FILETYPEAPP $(kh_filetype_app) - -/* Language specific version strings */ -#define KH_VERSTR_COMPANY_1033 "$(KHIMAIRA_SRC_COMPANY_1033)" -#define KH_VERSTR_COPYRIGHT_1033 "$(KHIMAIRA_SRC_COPYRIGHT_1033)" -#define KH_VERSTR_PRODUCT_1033 "$(KHIMAIRA_PRODUCT_1033)" -#define KH_VERSTR_VERSION_1033 "$(KHIMAIRA_VERSION_STR_1033)" - -!ifdef KHIMAIRA_COMMENT_STR_1033 -#define KH_VERSTR_COMMENT_1033 "$(KHIMAIRA_COMMENT_STR_1033)" -#define KH_VERSTR_BUILDINFO_1033 KH_VERSTR_COMMENT_1033 +mkversion: $(VERSIONINT) $(VERSIONEXT) + +# Version and build strings + +!if "$(KH_RELEASE)" == "OFFICIAL" +NETIDMGR_VERSION_STR_1033=$(NETIDMGR_VERSION) +NETIDMGR_COMMENT_STR_1033=Official build. Please send bug reports to kfw-bugs@MIT.EDU +!elseif "$(KH_RELEASE)" == "PRERELEASE" +NETIDMGR_VERSION_STR_1033=$(NETIDMGR_VERSION) Alpha +NETIDMGR_COMMENT_STR_1033=Prerelease build. Please send bug reports to kfw-bugs@MIT.EDU +!elseif "$(KH_RELEASE)" == "PRIVATE" +NETIDMGR_VERSION_STR_1033=$(NETIDMGR_VERSION).PRIVATE +NETIDMGR_PRIVATE_STR_1033=Private build. Please send bug reports to kfw-bugs@MIT.EDU +!elseif "$(KH_RELEASE)" == "SPECIAL" +NETIDMGR_VERSION_STR_1033=$(NETIDMGR_VERSION).SPECIAL +NETIDMGR_SPECIAL_STR_1033=Special build. Please send bug reports to kfw-bugs@MIT.EDU !endif -!ifdef KHIMAIRA_PRIVATE_STR_1033 -#define KH_VERSTR_PRIVATE_1033 "$(KHIMAIRA_PRIVATE_STR_1033)" -#define KH_VERSTR_BUILDINFO_1033 KH_VERSTR_PRIVATE_1033 -!endif -!ifdef KHIMAIRA_SPECIAL_STR_1033 -#define KH_VERSTR_SPECIAL_1033 "$(KHIMAIRA_SPECIAL_STR_1033)" -#define KH_VERSTR_BUILDINFO_1033 KH_VERSTR_SPECIAL_1033 + +!if "$(KH_BUILD)" == "DEBUG" +NETIDMGR_VERSION_STR_1033=$(NETIDMGR_VERSION_STR_1033).DEBUG +!else !endif -#endif -<< + +NETIDMGR_PRODUCT_1033=NetIDMgr $(NETIDMGR_VERSION_STR_1033) + +!include netidmgr_version.h.in + +!include netidmgr_intver.h.in clean:: -! if exist($(VERSIONINC)) - $(RM) $(VERSIONINC) +! if exist($(VERSIONINT)) + $(RM) $(VERSIONINT) +! endif +! if exist($(VERSIONEXT)) + $(RM) $(VERSIONEXT) ! endif diff --git a/src/windows/identity/config/Makefile.w32 b/src/windows/identity/config/Makefile.w32 index 1b862a9ad..5d469c92b 100644 --- a/src/windows/identity/config/Makefile.w32 +++ b/src/windows/identity/config/Makefile.w32 @@ -44,17 +44,26 @@ KHIMAIRA_WIN32_CONFIG=1 # SPECIAL : Special build. Typically one with non-mainline patches. # Version info -KHIMAIRA_VERSION_MAJOR=0 -KHIMAIRA_VERSION_MINOR=1 -KHIMAIRA_VERSION_PATCH=1 -KHIMAIRA_VERSION_AUX=0 -KHIMAIRA_VERSION=$(KHIMAIRA_VERSION_MAJOR).$(KHIMAIRA_VERSION_MINOR).$(KHIMAIRA_VERSION_PATCH).$(KHIMAIRA_VERSION_AUX) -KHIMAIRA_VERSIONC=$(KHIMAIRA_VERSION_MAJOR),$(KHIMAIRA_VERSION_MINOR),$(KHIMAIRA_VERSION_PATCH),$(KHIMAIRA_VERSION_AUX) +NETIDMGR_VERSION_MAJOR=0 +NETIDMGR_VERSION_MINOR=1 +NETIDMGR_VERSION_PATCH=2 +NETIDMGR_VERSION_AUX=0 + +# The API version. This number must be incremented each time the API +# changes. Plugins specify the version of the API that they were +# compiled against and the Module Manager uses the API numbers to +# decide whether the plugin is safe to load or not. +# +# Changes to the API version numbers should be documented in +# apiversion.txt at the root of the source tree. +NETIDMGR_VERSION_API=3 -# Source information -KHIMAIRA_SRC_COMPANY_1033=Massachusetts Institute of Technology +NETIDMGR_VERSION=$(NETIDMGR_VERSION_MAJOR).$(NETIDMGR_VERSION_MINOR).$(NETIDMGR_VERSION_PATCH).$(NETIDMGR_VERSION_AUX) +NETIDMGR_VERSIONC=$(NETIDMGR_VERSION_MAJOR),$(NETIDMGR_VERSION_MINOR),$(NETIDMGR_VERSION_PATCH),$(NETIDMGR_VERSION_AUX) -KHIMAIRA_SRC_COPYRIGHT_1033=(C) 2005 Massachusetts Institute of Technology +# Source information +NETIDMGR_SRC_COMPANY_1033=Massachusetts Institute of Technology +NETIDMGR_SRC_COPYRIGHT_1033=(C) 2005 Massachusetts Institute of Technology # Choose the default build type if one is not set !if ("$(KH_BUILD)" != "DEBUG") && ("$(KH_BUILD)" != "RETAIL") @@ -74,28 +83,7 @@ KH_BUILD=DEBUG KH_RELEASE=PRERELEASE !endif -# Version and build strings - -!if "$(KH_RELEASE)" == "OFFICIAL" -KHIMAIRA_VERSION_STR_1033=$(KHIMAIRA_VERSION) -KHIMAIRA_COMMENT_STR_1033=Official build. -!elseif "$(KH_RELEASE)" == "PRERELEASE" -KHIMAIRA_VERSION_STR_1033=$(KHIMAIRA_VERSION) Alpha -KHIMAIRA_COMMENT_STR_1033=Prerelease build. -!elseif "$(KH_RELEASE)" == "PRIVATE" -KHIMAIRA_VERSION_STR_1033=$(KHIMAIRA_VERSION).PRIVATE -KHIMAIRA_PRIVATE_STR_1033=Private build. -!elseif "$(KH_RELEASE)" == "SPECIAL" -KHIMAIRA_VERSION_STR_1033=$(KHIMAIRA_VERSION).SPECIAL -KHIMAIRA_SPECIAL_STR_1033=Special build. -!endif - -!if "$(KH_BUILD)" == "DEBUG" -KHIMAIRA_VERSION_STR_1033=$(KHIMAIRA_VERSION_STR_1033).DEBUG -!else -!endif - -KHIMAIRA_PRODUCT_1033=NetIDMgr $(KHIMAIRA_VERSION_STR_1033) +# Actual build environment settings # See what compiler we are using # TODO: Update this to support other compilers @@ -110,7 +98,11 @@ KH_CLVER=vc7 ! error MODULE must be specified !endif !ifndef KH_ROOT +! ifndef PISMERE +! error Either KH_ROOT or PISMERE must be defined +! else KH_ROOT=$(PISMERE)\athena\auth\krb5\src\windows\identity +! endif !endif !ifdef NODEBUG @@ -126,7 +118,7 @@ OUTPRE=$(OUTPRE3)^\ # Output directory structure -DESTROOT=$(KH_ROOT)\dest +DESTROOT=$(KH_ROOT)\obj OBJROOT=$(KH_ROOT)\obj SRC=$(KH_ROOT) @@ -134,7 +126,7 @@ DESTDIR=$(DESTROOT)\$(CPU)\$(OUTPRE_DBG) OBJDIR=$(OBJROOT)\$(CPU)\$(OUTPRE_DBG) OBJ=$(OBJDIR)\$(MODULE) -INCDIR=$(DESTDIR)\include +INCDIR=$(DESTDIR)\inc #BINDIR=$(DESTDIR)\bin BINDIR=$(KH_ROOT)\$(OUTPRE) #LIBDIR=$(DESTDIR)\lib @@ -182,7 +174,7 @@ HHC=hhc KFWINCDIR=$(KH_KFWPATH)\inc kfwincflags = -I$(KFWINCDIR)\krb5 -I$(KFWINCDIR)\krb5\KerberosIV -I$(KFWINCDIR)\loadfuncs -I$(KFWINCDIR) KFWLIBDIR=$(KH_KFWPATH)\lib\$(CPU) -!else +!else if defined(PISMERE) KFWINCDIR=$(PISMERE)\athena\auth\krb5\src\include kfwincflags = -I$(KFWINCDIR) -I$(PISMERE)\athena\util\loadfuncs -I$(PISMERE)\athena\auth\krb5\src\include\kerberosIV -I$(PISMERE)\athena\auth\krb4\include KFWLIBDIR=$(PISMERE)\target\lib\$(CPU)\$(OUTPRE_DBG) @@ -275,4 +267,6 @@ etag:: .SUFFIXES: .h +.SILENT: + !endif diff --git a/src/windows/identity/config/netidmgr_intver.h.in b/src/windows/identity/config/netidmgr_intver.h.in new file mode 100644 index 000000000..d1863c433 --- /dev/null +++ b/src/windows/identity/config/netidmgr_intver.h.in @@ -0,0 +1,34 @@ +$(VERSIONINT): Makefile + $(CP) << $(VERSIONINT) +/* + * This is an autogenerated file. Do not modify directly. + * + * File generated by running $(MAKE) in $(MAKEDIR) + * To regenerate, run "$(MAKE) clean" and "$(MAKE) all" on $(MAKEDIR) + */ +#ifndef __NETIDMGR_VERSION_INTERNAL_H +#define __NETIDMGR_VERSION_INTERNAL_H + +#include + +/* Language specific version strings */ +#define KH_VERSTR_COMPANY_1033 "$(NETIDMGR_SRC_COMPANY_1033)" +#define KH_VERSTR_COPYRIGHT_1033 "$(NETIDMGR_SRC_COPYRIGHT_1033)" +#define KH_VERSTR_PRODUCT_1033 "$(NETIDMGR_PRODUCT_1033)" +#define KH_VERSTR_VERSION_1033 "$(NETIDMGR_VERSION_STR_1033)" + +!ifdef NETIDMGR_COMMENT_STR_1033 +#define KH_VERSTR_COMMENT_1033 "$(NETIDMGR_COMMENT_STR_1033)" +#define KH_VERSTR_BUILDINFO_1033 KH_VERSTR_COMMENT_1033 +!endif +!ifdef NETIDMGR_PRIVATE_STR_1033 +#define KH_VERSTR_PRIVATE_1033 "$(NETIDMGR_PRIVATE_STR_1033)" +#define KH_VERSTR_BUILDINFO_1033 KH_VERSTR_PRIVATE_1033 +!endif +!ifdef NETIDMGR_SPECIAL_STR_1033 +#define KH_VERSTR_SPECIAL_1033 "$(NETIDMGR_SPECIAL_STR_1033)" +#define KH_VERSTR_BUILDINFO_1033 KH_VERSTR_SPECIAL_1033 +!endif +#endif +<< + diff --git a/src/windows/identity/config/netidmgr_version.h.in b/src/windows/identity/config/netidmgr_version.h.in new file mode 100644 index 000000000..2be3943a5 --- /dev/null +++ b/src/windows/identity/config/netidmgr_version.h.in @@ -0,0 +1,62 @@ +$(VERSIONEXT): Makefile + $(CP) << $(VERSIONEXT) +/* Copyright (c) 2004 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#ifndef __NETIDMGR_VERSION_H +#define __NETIDMGR_VERSION_H + +#include + +/* Version number macros */ +#define KH_VERSION_MAJOR $(NETIDMGR_VERSION_MAJOR) +#define KH_VERSION_MINOR $(NETIDMGR_VERSION_MINOR) +#define KH_VERSION_PATCH $(NETIDMGR_VERSION_PATCH) +#define KH_VERSION_AUX $(NETIDMGR_VERSION_AUX) + +#define KH_VERSION_API $(NETIDMGR_VERSION_API) + +#define KH_VERSION_LIST $(NETIDMGR_VERSIONC) +#define KH_VERSION_STRING "$(NETIDMGR_VERSION)" +#define KH_VERSION_STRINGW L"$(NETIDMGR_VERSION)" +#define KH_VERSION_STRINGC "$(NETIDMGR_VERSIONC)" +#define KH_VERSION_STRINGCW L"$(NETIDMGR_VERSIONC)" +#define KH_VERSION_STRINGAPI "$(NETIDMGR_VERSION_API)" + +/* Version definition macros */ +#define KH_VER_FILEFLAGMASK 0x17L +#define KH_VER_FILEFLAGS $(kh_fileflags) +#define KH_VER_FILEOS $(kh_fileos) +#define KH_VER_FILETYPEDLL $(kh_filetype_dll) +#define KH_VER_FILETYPEAPP $(kh_filetype_app) + +/* Special macros for NetIDMgr special string resources */ +#define NIMV_MODULE "NIDM_Module" +#define NIMV_PLUGINS "NIDM_Plugins" +#define NIMV_APIVER "NIDM_APIVers" +#define NIMV_SUPPORT "NIDM_Support" + +#endif +<< + diff --git a/src/windows/identity/doc/Makefile b/src/windows/identity/doc/Makefile index 71e9f0f16..b9cc463b3 100644 --- a/src/windows/identity/doc/Makefile +++ b/src/windows/identity/doc/Makefile @@ -25,8 +25,6 @@ MODULE=doc !include <../config/Makefile.w32> -CONFFILE=$(OBJ)\DoxyConf.cfg - all: mkdirs docs docs: @@ -43,10 +41,9 @@ INTERNAL_DOCS = NO WARN_LOGFILE = "$(OBJ)\doxywarnings.txt" -INPUT = "$(SRC)\include" +INPUT = "$(SRC)\include" INPUT += "$(SRC)\kconfig" INPUT += "$(SRC)\kcreddb" -INPUT += "$(SRC)\khlog" INPUT += "$(SRC)\kmq" INPUT += "$(SRC)\ui" INPUT += "$(SRC)\uilib" @@ -54,6 +51,9 @@ INPUT += "$(SRC)\util" INPUT += "$(SRC)\doc" INPUT += "$(SRC)\kmm" INPUT += "$(SRC)\kherr" +!ifndef NO_AFS +INPUT += "$(SRC)\plugins\afs" +!endif IMAGE_PATH = "$(SRC)\doc\images" diff --git a/src/windows/identity/doc/cred_aquisition.h b/src/windows/identity/doc/cred_aquisition.h index 1adb3b8f5..251b5b2c7 100644 --- a/src/windows/identity/doc/cred_aquisition.h +++ b/src/windows/identity/doc/cred_aquisition.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -170,7 +170,7 @@ khui_new_creds_by_type * t; c = (khui_new_creds *) vparam; - t = malloc(sizeof(*t)); + t = PMALLOC(sizeof(*t)); ZeroMemory(t, sizeof(*t)); t->type = my_cred_type; diff --git a/src/windows/identity/doc/cred_data_types.h b/src/windows/identity/doc/cred_data_types.h index 3257520e1..8fa7b1f36 100644 --- a/src/windows/identity/doc/cred_data_types.h +++ b/src/windows/identity/doc/cred_data_types.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/doc/cred_main.h b/src/windows/identity/doc/cred_main.h index e8f7d2999..b5be8ad5a 100644 --- a/src/windows/identity/doc/cred_main.h +++ b/src/windows/identity/doc/cred_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/doc/cred_msgs.h b/src/windows/identity/doc/cred_msgs.h index a1b2c2cc2..49f644c91 100644 --- a/src/windows/identity/doc/cred_msgs.h +++ b/src/windows/identity/doc/cred_msgs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/doc/cred_prop_pages.h b/src/windows/identity/doc/cred_prop_pages.h index 5e844833f..e4d41b106 100644 --- a/src/windows/identity/doc/cred_prop_pages.h +++ b/src/windows/identity/doc/cred_prop_pages.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/doc/images/Thumbs.db b/src/windows/identity/doc/images/Thumbs.db deleted file mode 100644 index 371f5d62e6fde1193c679492a2d4c88b39a82638..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28160 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 Sc)xCkB3GW)%m2MK@P7cv76Cc{ diff --git a/src/windows/identity/doc/images/khimaira_logo_old.jpg b/src/windows/identity/doc/images/khimaira_logo_old.jpg deleted file mode 100644 index 10e8fde4dbe415603d7b48348d27fc09eb92b4c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9550 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 diff --git a/src/windows/identity/doc/images/khimaira_logo_small_old.jpg b/src/windows/identity/doc/images/khimaira_logo_small_old.jpg deleted file mode 100644 index 94d8d1911394d8ad15cea9d6f6fe2920f2fb6305..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1665 zcmbW!c{tR090%~?1PX&fU@#~Q4u>I-B1j}ZKT=FcSWrY#OiD^pOhN)Jr;I_%U}YsF_G|3N zs;J`dIBATgwx*i4vKmfp?+6GEha(Y4Q6y4S4K0CI`_IK~0#FD*6L18B6ahXI2#f-8 zTLBCJfS|mzdx8Hd5FePA7mnaZ3h)-{L;yYz7|aI&L!l4|Z##xJ2OucuJ_Q{TOw_>( zt{5Ulh|MfSU@fYf#T^G$lytpA*s$iATaE5_?3vrsOb2F#Oq1PH&Upytn8fJo44rqii%50%kDGEAJx>> z)jxjH@U-Ps>+81mj?S*Zp||gbM@Gk(Q`0jn_UzpJ!s6=Mmvzq9jc=P;y-0i=YI z-jwp{9_+-!3K~2nO*!4~zoLfUVMaQn6}^xmF-$LaWN{dhhwu4e3UOPX z(Wt#fZFsk2CZ2GLBA@Fc`$io#+rzrpepik{y0+>!v#oNZX3%V?dhK(r4i}(=*5}&F z)4$SOTIT^r){7SeO`lQ&Otpu#j4k~cOB<4g zqAiO9OgF>NG*zLHwo47|4CD1G|HrFbAc^%TeQH_IjSH}8g<3D|3Glfyrv2Vu7E%3y zY$K0`h1B#Vg^F`CuZeTo%)GRh%N*SAj9;m6s=&CJol5%8`46YZrzi-3mP> z9he1roEa`4U~E}3o|??co{G{oi$s3H)(D@8Uhh;DBs@eI#|e?X2Tc^FI^QkuXjis5 zP1W2iP3ik`zk>MMr>rupo%~>d45<GDl*3u{AfN7pH3%Npy1(}?Ua=2ZIF3>Chu zoXxY>P99p8DmJ23!A+u_xqvVeKWVL`yxZf3j}Y7kBhH!Gsk8iTP#L!ta0Y$%7>f`u zkg8mp(Ssy5`$;>aT(X7Ow6pco^VE>tm?b)Y{dx1;K&1~M-xt>n5g&q$ckfl-^x1JM z!p%Fe^ih%oh&`#_X4rnay~rTV;VNeYzsB+1ZrVn#3xf_TmnD2s%yBJ=>9g$`^V>|< z{dS7JnE~-k3IjrMh-i`jXw7i8R{l2sWeT;;q}GiG_nvStp|kAaODo zf$9@)W=y2ggLGS?J%{yVc8KZF9!-fDepyUk9gZs6F;hTZ&WfTPYd(0eKxWeAbO1f8 z9-a6&Tj_l3E6OvA6$IxuvH|^>CFZkcs}ItBtNO&`N>yoiKIYiFm2eZ&_w2WxdZ|=+ zY4q^VRf+2|(qQtruMSVwFKXyWZOt|wcp}i%nV(rvIK5?-#CaZw^G6xgo4fRI0lWyY zqo2r;Djy7RG(sgNmlCWOzKy)JYc9ff37)+$HZGq{(aI?OgqhdA3T9SUS{V8|iybe+VCgN#EcY2?`ql1HjaW*JoVV~D3vygqGOSeWeY+AWK(Uv3sE zGAj+ri3$%2GoUy}-U;`LkT1G_B)C4McmIUWMorwc62CLuhD@dFSOs4rC%e1b-p^%7 zE8&&dA<$)}AN?{rEYbcbwrs}D+sG?))e^0HJLfR48$OiOomWfK%@0msy7wdInformation Services and Technology at Massachusetts Institute of Technology @@ -86,7 +89,7 @@ /*! \page bugs Reporting bugs NetIDMgr bugs can be reported to - khimaira@mit.edu for now. + kfw-bugs@mit.edu for now. In the future, there will actually be a place to track NetIDMgr bugs. @@ -99,10 +102,8 @@ /*! \page releases Prior releases - - 0.1.1 (Charles Manson) [soon]\n - First alpha release. As stable as Charles Manson, hence the - name. + - 0.1.1 First Alpha release Nov 01, 2005\n + Released along with Kerberos for Windows 3.0.0 beta. - 0.1.2 (tbd) [tbd]\n - First beta release. */ diff --git a/src/windows/identity/doc/plugin_framework.h b/src/windows/identity/doc/plugin_framework.h index dbf160080..c714284ec 100644 --- a/src/windows/identity/doc/plugin_framework.h +++ b/src/windows/identity/doc/plugin_framework.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/doc/plugin_locale.h b/src/windows/identity/doc/plugin_locale.h index 3cb65a422..6c3774fa5 100644 --- a/src/windows/identity/doc/plugin_locale.h +++ b/src/windows/identity/doc/plugin_locale.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/doc/plugin_main.h b/src/windows/identity/doc/plugin_main.h index ed8d038e2..ed06c6d08 100644 --- a/src/windows/identity/doc/plugin_main.h +++ b/src/windows/identity/doc/plugin_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/doc/plugin_structure.h b/src/windows/identity/doc/plugin_structure.h index 8c57b0300..b41ff3a07 100644 --- a/src/windows/identity/doc/plugin_structure.h +++ b/src/windows/identity/doc/plugin_structure.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/doc/ui_actions.h b/src/windows/identity/doc/ui_actions.h index ab3848ed3..de4e802e3 100644 --- a/src/windows/identity/doc/ui_actions.h +++ b/src/windows/identity/doc/ui_actions.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/doc/ui_context.h b/src/windows/identity/doc/ui_context.h index 8ef325049..b9bfadd6b 100644 --- a/src/windows/identity/doc/ui_context.h +++ b/src/windows/identity/doc/ui_context.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/doc/ui_main.h b/src/windows/identity/doc/ui_main.h index 0f9ab661c..8cf735c04 100644 --- a/src/windows/identity/doc/ui_main.h +++ b/src/windows/identity/doc/ui_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/doc/ui_menus.h b/src/windows/identity/doc/ui_menus.h index c7a95a364..09cc16e67 100644 --- a/src/windows/identity/doc/ui_menus.h +++ b/src/windows/identity/doc/ui_menus.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/help/Makefile b/src/windows/identity/help/Makefile index 2b823d85a..c45a83f80 100644 --- a/src/windows/identity/help/Makefile +++ b/src/windows/identity/help/Makefile @@ -25,7 +25,7 @@ MODULE=help !include <..\config\Makefile.w32> -CHMFILE=$(DOCDIR)\netidmgr.chm +CHMFILE=$(BINDIR)\netidmgr.chm INCFILES=$(INCDIR)\khhelp.h diff --git a/src/windows/identity/help/html/about_netidmgr.htm b/src/windows/identity/help/html/about_netidmgr.htm new file mode 100644 index 000000000..76c5f9f22 --- /dev/null +++ b/src/windows/identity/help/html/about_netidmgr.htm @@ -0,0 +1,67 @@ + + + About Network Identity Manager + + + + + + +

About Network Identity Manager

+ +

+This is strictly an informative page about the origins of Network +Identity Manager. +

+ +

In the beginning

+ +

+Network Identity Manager was conceived as an identity management +solution to make up for the shortcomings of Leash32 (distributed with +MIT Kerberos for Windows) and AFSCREDS (distributed with OpenAFS). +

+ +

+The work started as Unified Credentials Manager, a final project for +the MIT course 6.831 : User Interface Design and Implementation, +taught by Professor Rob +Miller. By the time actual code was written, it was named +Khimaira (which was later changed to Network Identity Manager around +October, 2005). Traces of the name Khimaira might still exist in the +source code. +

+ +

+A presentation given about Khimaira at the AFS and Kerberos Best Practices +Workshop 2005 can be found on the workshop website and here. +

+ +

+The work on Khimaira was funded by MIT Information Services and +Technology. +

+ +

Design

+ +

+A plugin based architecture was chosen so that support for additional +credential types and features could be added without making changes to +the mainline code. In addition to making the application easily +extensible, this also allows the AFS plugin to be maintained within +the OpenAFS code base and separates the code supporting Kerberos 5 and +Kerberos 4. Furthermore, it is anticipated that this would encourage +third party developers to develop plugins for NetIDMgr. +

+ +

+More information about the concepts used in the design of Network +Identity Manager can be found here. +

+ + + \ No newline at end of file diff --git a/src/windows/identity/help/html/menu_exit.htm b/src/windows/identity/help/html/act_chpw.htm similarity index 56% rename from src/windows/identity/help/html/menu_exit.htm rename to src/windows/identity/help/html/act_chpw.htm index 2130df192..5e39963da 100644 --- a/src/windows/identity/help/html/menu_exit.htm +++ b/src/windows/identity/help/html/act_chpw.htm @@ -3,7 +3,9 @@ title - + + + \ No newline at end of file diff --git a/src/windows/identity/help/html/menu_properties.htm b/src/windows/identity/help/html/act_destroy_creds.htm similarity index 56% rename from src/windows/identity/help/html/menu_properties.htm rename to src/windows/identity/help/html/act_destroy_creds.htm index 2130df192..5e39963da 100644 --- a/src/windows/identity/help/html/menu_properties.htm +++ b/src/windows/identity/help/html/act_destroy_creds.htm @@ -3,7 +3,9 @@ title - + + + \ No newline at end of file diff --git a/src/windows/identity/help/html/act_import_creds.htm b/src/windows/identity/help/html/act_import_creds.htm new file mode 100644 index 000000000..5e39963da --- /dev/null +++ b/src/windows/identity/help/html/act_import_creds.htm @@ -0,0 +1,11 @@ + + + title + + + + + + + + \ No newline at end of file diff --git a/src/windows/identity/help/html/act_new_creds.htm b/src/windows/identity/help/html/act_new_creds.htm new file mode 100644 index 000000000..5e39963da --- /dev/null +++ b/src/windows/identity/help/html/act_new_creds.htm @@ -0,0 +1,11 @@ + + + title + + + + + + + + \ No newline at end of file diff --git a/src/windows/identity/help/html/act_renew_creds.htm b/src/windows/identity/help/html/act_renew_creds.htm new file mode 100644 index 000000000..5e39963da --- /dev/null +++ b/src/windows/identity/help/html/act_renew_creds.htm @@ -0,0 +1,11 @@ + + + title + + + + + + + + \ No newline at end of file diff --git a/src/windows/identity/help/html/act_set_default.htm b/src/windows/identity/help/html/act_set_default.htm new file mode 100644 index 000000000..5e39963da --- /dev/null +++ b/src/windows/identity/help/html/act_set_default.htm @@ -0,0 +1,11 @@ + + + title + + + + + + + + \ No newline at end of file diff --git a/src/windows/identity/help/html/bugs.htm b/src/windows/identity/help/html/bugs.htm new file mode 100644 index 000000000..a2e8d34ca --- /dev/null +++ b/src/windows/identity/help/html/bugs.htm @@ -0,0 +1,33 @@ + + + Reporting Bugs + + + + + + +

Reporting Bugs

+ +

If you encounter a bug in the software, please email +kfw-bugs@MIT.EDU +and report it. Please include as much information as possible to +enable us to reproduce the problem. +

+ +

kerberos@MIT.EDU +is a mailing list set up for discussing Kerberos issues. It is +gatewayed to the Usenet newsgroup 'comp.protocols.kerberos'. If you +prefer to read it via mail, send a request to kerberos-request@MIT.EDU +to get added or subscribe via the web page:

+ +

+http://mailman.mit.edu/mailman/listinfo/kerberos

+ +

Information about Kerberos mailing lists can be found at http://web.mit.edu/kerberos/mail-lists.html

+ + + \ No newline at end of file diff --git a/src/windows/identity/help/html/concept_cred_pro.htm b/src/windows/identity/help/html/concept_cred_pro.htm new file mode 100644 index 000000000..5e39963da --- /dev/null +++ b/src/windows/identity/help/html/concept_cred_pro.htm @@ -0,0 +1,11 @@ + + + title + + + + + + + + \ No newline at end of file diff --git a/src/windows/identity/help/html/concept_ident_pro.htm b/src/windows/identity/help/html/concept_ident_pro.htm new file mode 100644 index 000000000..5e39963da --- /dev/null +++ b/src/windows/identity/help/html/concept_ident_pro.htm @@ -0,0 +1,11 @@ + + + title + + + + + + + + \ No newline at end of file diff --git a/src/windows/identity/help/html/concept_identity.htm b/src/windows/identity/help/html/concept_identity.htm new file mode 100644 index 000000000..5e39963da --- /dev/null +++ b/src/windows/identity/help/html/concept_identity.htm @@ -0,0 +1,11 @@ + + + title + + + + + + + + \ No newline at end of file diff --git a/src/windows/identity/help/html/concepts.htm b/src/windows/identity/help/html/concepts.htm new file mode 100644 index 000000000..5e39963da --- /dev/null +++ b/src/windows/identity/help/html/concepts.htm @@ -0,0 +1,11 @@ + + + title + + + + + + + + \ No newline at end of file diff --git a/src/windows/identity/help/html/copyright.htm b/src/windows/identity/help/html/copyright.htm new file mode 100644 index 000000000..32453f740 --- /dev/null +++ b/src/windows/identity/help/html/copyright.htm @@ -0,0 +1,48 @@ + + + License + + + + + + +

Network Identity Manager License

+ +

This software is being provided to you, the LICENSEE, by the +Massachusetts Institute of Technology (M.I.T) under the following +license. By obtaining, using and/or copying this software, you agree +that you have read, understood, and will comply with these terms and +conditions:

+ +

Permission to use, copy, modify and distribute this software and its +documentation for any purpose and without fee or royalty is hereby +granted, provided that you agree to comply with the following +copyright notice and statements, including the disclaimer, and that +the same appear on ALL copies of the software and documentation, +including modifications that you make for internal use or for +distribution:

+ +

Copyright 1992-2005 by the Massachusetts Institute of Technology. All +rights reserved.

+ +

THIS SOFTWARE IS PROVIDED "AS IS", AND M.I.T. MAKES NO REPRESENTATIONS +OR WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not +limitation, M.I.T. MAKES NO REPRESENTATIONS OR WARRANTIES OF +MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE +OF THE LICENSED SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD +PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.

+ +

The name of the Massachusetts Institute of Technology or M.I.T. may +NOT be used in advertising or publicity pertaining to distribution of +the software. Title to copyright in this software and any associated +documentation shall at all times remain with M.I.T., and USER agrees +to preserve same.

+ +

Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, +OLC, X Window System, and Zephyr are trademarks of the Massachusetts +Institute of Technology (MIT). No commercial use of these trademarks +may be made without prior written permission of MIT.

+ + + diff --git a/src/windows/identity/help/html/howdoi.htm b/src/windows/identity/help/html/howdoi.htm new file mode 100644 index 000000000..3995335a4 --- /dev/null +++ b/src/windows/identity/help/html/howdoi.htm @@ -0,0 +1,37 @@ + + + How do I ... + + + + + + +

How do I ...

+ +

Startup

+ + +

Credentials related actions

+ + + + \ No newline at end of file diff --git a/src/windows/identity/help/html/images/Thumbs.db b/src/windows/identity/help/html/images/Thumbs.db deleted file mode 100644 index 01828e4debfe252e9da4b4bd28fd7122f9d4b540..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3584 zcmca`Uhu)fjZzO8(10BSGsD0CoD6J8;*3Bx2!nwD0|OI~0pkDr|NlQkkbwcn90fxt z1pWfu3W`4vW&uVbD>OcbkQYXsN;Sr0E8 zaOw0235dIQl#v-Ie*l!&fWQz!kxjBNFfoGc2bD!2nplJCp!Pd6Bm#Y%$dCgJg>+&y zBdHSrmVzLAVE{=ACsPP0V}etbbP1T=vt72p@5MI=teen4o)s^pn|Qy9LmVd%*4VBay3wOEl{3;MUYiU(a@1i zI53f2sZhkIapFP_Wv7h?MT0JWP%%y_YU1P)6PJ*bQdLve(9|+9H8Z!cv~qTFb#wRd z^a>6M4GWKmj7m;PO-s+n%qlJ^Ei136tZHs)ZENr7?3y%r%G7DoXUv?nXz`Mz%a*TL zxoXqqEnBy3-?4Mop~FXx9y@;Gy|miew|{A5 zR#ocTeT$dfJ2c&F`?N`GHk=n;kup)%lV{Bmfddm9S;8OBe|z{*ul=L?qxl`v{~2xE z_2GC|NpAT+!S#GwAK9IMb30k=?Lp-`f&VV5zDV;unztyVGSp$+;s^g3dUXG&mp+ca z`RMlXeKJ3yKiof3C%AL>&TD%rmmZt!TU_K~w1qEE*I4^-!Rp_4fBUvwl;`u`9<3j; z>6OL#`guk3`o!8*Z0A1bnsd%L=4v8e$j-%jr7CkRqn~9wzmok-{^rN!s@f-G*UBq} zXTG_5EB1Z$(&VrEx<322TW$T;|5&&9z@l%DkNk4$<|#V7)>qrxZe9$Vui3Y7%UOle zDxC`YnynM=v=)nepEo^D@yqd(`?re!5&rJ_cfmfzTQv?BYXa_Zew>oYVlHepk!@jW z*~H4(DU+Cz)8_LERrV?~%4qDi2-;hIX#S1Ehwk&%@mKt3I4Jz;SKHS5$3OIhkIYlb z$bI|ndF9(4BM!6U9gl)Ody4o!tIRe2bi1#vWzp_c$%UdTomxHb8HUAqy}kAO)3V!M z-+Z@Cy>0l--`1T>%-^wUORx6s-QtrXRf^&w zV{hJlQgrU!n=@z5cwSr7_0Y`z|4mRG!VWHffJF_cxM5HMVsK8*J`fap`v_wWLng3Y UlFgvU;LhO5;0BZ(1=I`y0HhmucmMzZ diff --git a/src/windows/identity/help/html/images/link.GIF b/src/windows/identity/help/html/images/link.GIF deleted file mode 100644 index 1af792f08de91b7f8d08e6103150793397f6bc67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 932 zcmb`Gy=#?W48`LY)X8F7XrUrS5Wlu4R5~ft+D;A*DqX}992|6TbGWq>hbl0iMnWrW))4vOw7eXEUVX5+{9fx#Ir_2 zB}~F4LZX;Ts-#J}WI(%s3mPnj>CW0yVXCegs#$Bv%+y>h)UsGmbW?ZrP|qSoZ#b5&s7QcmdxEe%(LXef?~KuSS0Ep zMX#k>h9&aw1DZ@@2l^p_LRbR^X;{(<4;F(BG+0^ARhgU!_bemP$6B%okHlBx!h)h_ zc;X{YV*tEp$7s}IC4NAYY3zU#f>8)-z#z>ewBW&Fuz}7xQFT)$Cz6X{B>GrO7VRY~ zU)#N_*iKkBx2sfdGrC-F-qmQcqmIxN7E&W!H)%WyxIyzea3#z`6RU>)Y~3W%Er;r@ zuK$E|O-pVcJh}K_b*8K5z~tKE!#6j&_e|V-)jd1f+q>=DrPb%Nqu2X)Eqwpv?k&#${CZtm+@IJNxZ(fZu(e0O+we(%`*k*n)}mp2~2pE-79Y3i(A+?dw!jkg28 q_Me`=cK3MS`sJy)CkHQl`}yO}*E7#{T(QXyOHaSN+_`15jQj)aZkRg& diff --git a/src/windows/identity/help/html/images/logo.jpg b/src/windows/identity/help/html/images/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1121f6416bf6f1d4bd107d84d10c94fe2dfc6ca0 GIT binary patch literal 2014 zcmbW!X;hPE76R zg?*-W2t|(oq(&6hEH#&f(zLJd#CZ+~w9Er9q{*W3O3DNkZ5>^b-hPV%mR1K39dqeSCw0L(ZKK4GWLH7;`B$E98Dc*Xu4TM~4z zT*x%f8y3|GgVWC?DT)JYd#Aquft7iutws=7q+q5NVB zkG3A$yD1L>wO(~)ev*?j5;zD9-@P8FevzCX{4&!z1?&gfmW#S&_{@o(a$ugu0b zCNQ`zS*%*~0cr~fWK6DT&3CLVl<-^8wpb5GU_0?Yx9w9?ZzD)dH`AlP_vaxqmyM`Z zCt0bk=Jk&OBYnRf&!8S|_dxFoZic43TJz?7x9{`Tq!(rV>-V3q)dJ;8B|e+_&PHKc zebqYUta0Awqj5Hqr!riPFADIZBYZmFtC(FhGl}~!yi(aCYha*e<<5UBu$zxq5j_%b z-D)DN$j2y;OrPi5Q^Tuin^4Xf|tFxCR|u4o$KFfm~fj z5a4_*Inhrc3qU|}^tO`Zq1QUa&ga^Hb{99vTu$%EYO>P3@=eL-S<0a@jd0%-cBJX_ z+;LM7h{J4!O=5qw?!YaW82=oPNV(-05*IjIDS9qgh}$?(d%$+h+a^F*m{Hem%$ay! zNH-+#$>$vg(vxwYO~kKcH;q96)!vX<_iaVI2D2!h(W|T0tTlrC?0PHgKr&%QUzAJb zix;zd30o0Q4TD?jTNn#3eAJ80TePw>Lu^VJZ|W!yvI(5{1R`tU#-0JSv)9P%0DoCQ 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

uWr-BG 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�W84a^04r7+! zZJjruCcI~9tdHeC1t?28w6hYtuma3AY>p`|yT5RQdCoG^)D#2OQ+*Pn|0q(2k>n3% zGaEfi3mX=yfq75X3{aQ${J7X>a(=317;Kmhbn*#Whq99=opa7;Du8FfFq-xQ+!SDM`So94k{til{g~AN+l$KW^`*<&;^G5 zeDS77)3F^eg}H=XkQdlxj;aD&)QsjfHWGHT?<3f@G0e7)ZP6$L54i$uQ^3VXi(ldj zxKN;NpEq8LD?kc3e6)~Ayi-CVpmPX5Iv9~Uquay8&Y0N6(q+@pzc@1&*u{Z~U62>1 zj78G~F{Y0(WKFNjppcd;V~Cs0bT=+qrYY~|y16Q^{H0gm`E7*FYks*EP&QlP5w5_m zRlxpt6<-tkQx literal 0 HcmV?d00001 diff --git a/src/windows/identity/help/html/images/screen_menu_bar.bmp b/src/windows/identity/help/html/images/screen_menu_bar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..947cd10c61eb1e9b3cb5597848d793a1b69941a7 GIT binary patch literal 12374 zcmeHNOLpWo40P_0MV47+nbjO1`)qUToWwKZCaHFoPN52bK&jpFr#+dMNDrpLB1p;Y zdIgZ`-+uq&*E?RH(Efs-Kk@S;etx+73GLn8&pytMH+|{FT3^~2W)8w}>wSc2igy`M zkTyC@v*fp>n~f&ZIzGhUXZ@wMrJY8#ej2N3!HR^hDHb`$tawBs#=wWk`oriC-R#sG z>|rtvP4O{ZVH%?UwKtfSQv0=cn&DwW&?d5REZ|FTX*Dvz$!YBij8i_h2HTGc_qMms zFh+iEr?5mg+S@%%VfU@=>~!B?Tm0$i>8_9rggba9#vD8o)o#bLzs|#K=`=X(p2y>C z3UhE7kFYs_-Trun+0dD0VQHKAr9XywuqH133_H`7abAu1+Fgg1Wtg4K6z|B=7c-7} zYsefEqhl;EO&NWG`E)u&#?omF9lRV7exY5H05qPeKSrn7ba`tG1ElWL(1bIqbi1ZJ zfbIsllq*iA(4G+L^oqM5Vd}cNGnq);BTRbl@?VuZebcjpXHLX}XEU*kMk-O@u!I0_ zguIt$wQiH2qV+aC+b;;j*9f7f{{0sjTo`Kn(1dD)uAkXl3Zg>U+@?$v5I5@gqRiDKq`>oYX(n8O2R62*^ zED<=Wr4q@m9JClx;#15X5snx}zO+8eV6e@6>Y0{8Yo#17`d*e*KPtJ{p=)nG*Jrs} z)@O;p$@)wn_y-4sKyZdh`Gi|>);(qupfI(SPl+SG;@Qo0Fp8vUc)5Foy}mxf%qu*@ zsHgyvt^QQqU)Tp&uCE`{4=W23roS`W?*MPrCqeSd^L^#E}s!`8y zw1Lr@NzoOemO~P%l(gD4pOMz`s6&pm^>T&{yB#=VEk7b`8T`D0M;>C*24OH+=$Uj~ z1Z>l>He#H4aXbM8ToEqPB$8w@gb7YVDM%()Axr!n&?x&Y_}SdsQnu6KR}?kvG-#Gc$tHv*a0ORXwAap&FCy zd0FOQyf(lS>V1H>K^ii~^P|OF!e@E2PjkaFP)e41CY~9X7sqtYw#kwVV*V_d6nDY& zEbz6AxTUhMLs=;|0B;Z@#Z|kg8D#g@wl$@43S{Ze}QMKn8iNe z{d#8X6bnC6&meEN(zBo)G)zYwE@oiH4fRaKm7WF7@Ve7zRP}7nsy(ub8Rou8&#IWg zw`@qerJiYDSsCWEs1n6PTEy@*dA$F&SLQBGj!%f_#TY7_1dKJAUc=jvgS(t4?Tn1c zT*(xfWU6Vjs+XoL=WgbwWoyC>4l$F8Mb=un(?4FV^GUC{+0iXxRPmgjufjc8>#R#p zeDb{Mnk2?tXq8Vr`#u+J_j87cTb@bzr7rtk*Y>q~&7m3%8pT#ri8V;Z+ROHp@x3ey ztNBq2RzzQU5)xm3vTro;J$iZ9B(@zqJ9y@j#&e2;XSUO{j9IGtL(k%Ss)wGHjlz*P kkGvW6I}5c)sj9bFqD|Ep@d-KVGgWC;v3b4!f3DB|2BtCM0{{R3 literal 0 HcmV?d00001 diff --git a/src/windows/identity/help/html/images/screen_menu_credential.bmp b/src/windows/identity/help/html/images/screen_menu_credential.bmp new file mode 100644 index 0000000000000000000000000000000000000000..eecddd21b1688223fa45685573be53e323fa6f10 GIT binary patch literal 129846 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 literal 0 HcmV?d00001 diff --git a/src/windows/identity/help/html/images/screen_menu_options.bmp b/src/windows/identity/help/html/images/screen_menu_options.bmp new file mode 100644 index 0000000000000000000000000000000000000000..4fba5d6d38ed35d7e34a4f38297f03a698dbcd52 GIT binary patch literal 29494 zcmeI2ZF3V<6vyMY@FVyM_yE3l#!un!!Wj|9QK2FfL70&d6&z?SLdO@t=rGz*U_c5q zg$fifEq$P*Pf63XdD_hrQ0VA?_iRp2c9Rg2y_=-nozvyq|2_BVx2HEZTi$(d+pd6l zZNvQ?{Orch`}lb)@HXzata>WYJyw1#EG$e;C539iQ*nzGK%1 zAARgwlLSB#JV6y~1A$ZLe)UZ$fe%0VwEO6>vlsukbo;K!`#=9uMgUK8XV=~%Cr)0t za_v@V!so4wG<6K#ySoqk(0BT;p`nN2S)aGhTQLD|yZ7_k=j|;4Z%6ayyeZ~6CMf4Ero|@PY1mBes%EV>7TC!hab=5|9?YhW~MfTDAGlJmP*#2@wo`c z89*Y(AfRHHvmq(%c~{AsSInGPspdE%ol3Q~9ih9*8*J#ZEghmwsaBMcz#wutTt?=8Zzo@M&H>!IXc40wNe@ZhO4XRhDAGr6$X^!dcSnQhLVeBRzZ zSD&}f+gk$Oj^^jL&)Zu9-j1dqzwzycFItSV$csePYhw_=Jy1Nia`r>P6?GO{=z#aW zLx+0Kp1nRYGPM|K`aCE}IN3C#5F}?0Qm^f|5Hk<$DsKrJBh=5v){xuMG-YkIK6ycH z?x^7nDs&OKQpxz26sE#TjTl=ewjQ{vj&RiQmP;q1q%d6$sG-P)HR8FdBOLX-fdS;` zA|$1f@h?MSkz=SK7b$>?F%WIvDansT)N_&)|LZyYGKFe}4G> z{io4r)8`Y+kuy~t6?HwUU@ZFtZ@~WZ>eYu66LZVUZt#}fEAl&<_wc>@fISn5L=uS( z;jQQ~deANM`)MRPACCieES>gwD`pPf@r)MNEc1E$ycHAhwtM9Fimt6{hOOwjpWlk{ zSKg`i7am{;Qg9nA9yF!DJO{OQP8vu*-Q*E-sFYjgO2?-VS+f!=XvC z;J*{WM~{P#LYT~E=Y1y>np%ubEJVlW79Y8x&AHl4MMg1NZi=-D)^6b2`y>trOBiqNwu)EWWO%wSVb>e)a5OT-RWX_xXaP4 zmBe&pX>0IKX2HGcRmbOz?c?W-iz}KINhD_?G3H%yHk8ej$CQqwAh@IQ8@yo^xne05 zb$3O47qIazZ4TCsVHKK zvdnME7;TMWZsYfm^4rjbXoj`_{+-I_VVEqald;bZbn+WhoISGw2kh}V{d6f_n>U6w zHW2fp6h4rXV*1wSrJ=O@=VjW2oyz5;Vd5y#o%CiD?m>3Q!(lhWaVY#Iylwf-`#1V; zf8K?Hfx*mjzLO&LCKcHgk3tSod?}p?$5xQvoW9n6!r5HDZ=g5YNhr$={5TkzG3N15 z9tMrmBGnpq^YBQIOP=z|Pl$9{w4WKR7&;*uheRX5Is+OGj(+k~Xq*J;>qP0Ci1$@k zV#ef+ESH7_QQouYmckvfgG7&|GqdHqF`T@JrMZjiS`HKMT;5u-i0Om6G*Ze|YzDAG zPl=jHk#w6PMQS4N0Kc5k=9X7$=Qm(;x5h?pW%GuJTA99-#Fk=ae|zM&UM%Wnife@e z879uY&8bmki>$wx$>;HvXTA>JoZphS#g&MP?V??IXNyG`sB`uhPoRn+hO4B{VgnAI z%!;PZ#}lv3@6E-#0aUIuaq>2}3ZqXuOUW7gcPHm};rVk|zIB#+_AIIAqN^z*zv)Y4 z`JH&v{$Rqkc$anz<1|7Ir9#IKQp%4a*3qJLCUKlbtansW-#Dw34kUOrWu8f_JH4r* zw^QP*LNB*Uk>>fNxVBb&@uJW=!=p~;^08!QYw&*Y>J{uc?B&Z=Sz&E0mCJ7d-uOdS YworJrzW%bMwzj^m<@1=#X5UZ#2j8r?*#H0l literal 0 HcmV?d00001 diff --git a/src/windows/identity/help/html/images/screen_menu_view.bmp b/src/windows/identity/help/html/images/screen_menu_view.bmp new file mode 100644 index 0000000000000000000000000000000000000000..9dfb871c2be593a5452452e9057199581414e579 GIT binary patch literal 64854 zcmeHNYiu0V6?R_|5^WJeRS~U3tNv)kuS%8rw^C7mw*SlzPzw>^A%s;PA|(xF!H{4# z4q#|XNg5JDd2LXuUz8PMhJPFJ?LPK5~#-%-jnnRy1 z4{1vPXGALA<)jDis23r7_F1yaKIc@xT7Q2(7zB@C8O*}7^n@9UYrDZ(hHC{W^0+ssdmQ+<`%yz}Ujx{fiBbdjMu_ZEelX z&5xNYQWXGe;0_FeN9Om%H{LQ5j|$*s#Cd~93XW*JiP8SOWUg3L0JrGVPd~k7%a-2W zUdysBT)2R=@O~AGUGpHAS8?ZW z%=;H5ugUWleh|gELOx%}7sZ9H5{ud?C`(>l((uEd&Oc-`V;&Xo@~d`P72AsDZn*vC zTW-GvZ|2Jr3Hq>zE@a7#jg7b7+<4>98-MjXMA`7oZ_OiCV>U_LLh*a;kF~Y93xzJq2|6byb>+mp*pdM5mYc|U zy%a4G4p_!tWo(jPxUK&4QNtBiBBZ9oZOM(v)h(;h{V=q6LNUVPFzNI%Ug;~Ru-{rMfQMlNxl$u1!>14_FWER9& zPFze~#^znuf7EMV64Cg@{)O9WJU4vjYAm!o(VpC%?AX75xU=Ka?Y+sZ+d4Wsz;FAS z_GDXoUm{NwQ-4H&kUUremV zbHi2NgNH;S(Yvd6$H^T7seys+eee8lAN1EZz6y%hKC||oL;{asT1c+NIx8HEhH#ga zl9miY(R4!U+ah>*QG|@tB(~b~d-eAbSW}{@?{Hr_mA+(MN~iXxr_$KV9Us39eqU%; zZ`98IwUgmQ(33i4N{Gyw%-C2Cl{EGm@GA9HI0X*Fi||loO6~c*@+w5K^q!^T`SD8y zJE+3ck?|v^w)bv*XKS(}`ONCXy64v|O(ZbZaLsixBdOanXBwZO8KY8K#S=?8t1;${ z&5KmIB=cLV-xnxCb^MN>>KW}pcxbcz*`7nYI`?%Z+tn*pTT5Fz@q5L$Vb7OOF0k<# z^%<&oqL0s74RPY6z^xala;*j8ciF?sx=(glUs#t8q*ObQO1||P9>K}2$xVq(p!lvk z{y^yjkDrSWe9C;6n3v~B7%vdNx7?ms+SbzaP}6g*ZK_?FzH(w~?+h_U;T7D5N5ykJhVc-`rkocstKt&GXHi(T+ z>1DHwiziW7sOIr)Wwk;qkm?@UB~=O6E1v9jgGSKs{i2Rq)~ z^~w8t_Tv|SHZV%0D*%4)edtfkYo2}iKX1Rcd*6 zCW1y~OG7~r%?WoSs>ni>OW`u)7i9@jnQ|2i4<00unDL9^Q`Vfjq>{n#a8yksoT-nK z`0>lh60?$1Lf9bc3iIoeR|xq<**S8iKtm`a2B}NN404woa+eIK8|hZdv}7*fDQg#%1AN%2CQ2|`3;zzF*E$e`yMd- z#-881?|a}cPqnUpBe`|^$DMokZ`;=$9vcx7k?B54gJkq-M@5#>2k3K)N@5IRi zsR6@pocMkCvB#fX_s@>)AMHQh*P9+WIy!FnjT65snw$T&VZ(bncOFcoj*pF<4By{h znftBc`wi#wBh62&-SAT9&aR%+K;PKuflM}R^$c4)6<2%lC)S-`aK{&=&s`{75UB%X z8)=|{)MbOqQwamVvhtG0;JVjRBGP}H^dLD#f?rC6(_sZKxs1OugdN6AK{fa)mm2te^ob{5 z*tluiuHA@mR!aN$}9?%s2BaA+`- z9iE&DaB#Xwq9d7QCe27W39(lty;I~reO8h@T(P*y4=c=0xZ|1A=#3phOh?> zhcP2;BiCAF9Wlg-Us*j_Ua2z$Y%E7fmo1rT2v5;)cFqR8N?jC$5l(&)7zvl90>nF| zoHxx9U06~}Qy3vj8f60ld5EWI2;qy_B7nzRTGqY1dHddwzF#e7HFzzQh4n})NMy}( z&;9GoH+LO4(3c(_nV1|~^!H~JknVG8saxNw#))5$``>NbK09)xe{`%~{Az60y}We~ zKr2YaT_l2?3v&C?>7g^3(aEX0?B9yxHxvCU0Deyn51$$zPiHdNyoO)@az$!S9(|?zCk=ppcmTTR|nmIi(!Gz>UPC0wwovYJ9x= z*s-0Tep*}kq__9@@bFYV51Dktn#{A51bGySGMLC)EMo2q$fHWJY_X?gEeqluCERKA zRu*DgX04nnjM$@jD`N|pWh~1hxr_zz;u@mN&fw%^agI=&r2^zpWlU0X)CDm&hXWbM zvU4DN&*!~|diNeWy1S<~va9DPr0eq|T?Y?$9qc(eG-UX-*{>VF$A*TF3=a1W3>`j| zhCr`I$VpHCVE6IVzN07h^z;~h>&x%RMNpUc|5Wee#}OAjW6 zXDub}^gQ05ad*u;6l$c8Pvr(rXO5>w48M{!x)~(m=nKhjHm_LLt^h9#+WW(-?&(}E zoyqp4N10#EzwFj!|H=SZSKG7H{)Itw_b>Q`R7t2d9WUw{zxKgg;(SKw>cTJ1aObcU zgvOKKLLplyWb9pxmIP&Ig>G-}5D+%wQBrW=r?V4%!(+UEiC=Ps)_M3AW*r^;{3SE+ z4h2NOm?zS+m2ma&wPOIN8IT#Zl1Ij2FLCa&AB^HSRk(2OnnmgPJ25>C0mTR&EeYvf zq@)?oVg)SYRqf=+xa1e!`27kxQLGgA{mKSa7;4CVzk*KODa5`QQA`PbC2_2iB6;K? z_>nkuRqJkN=#pPPpKZ%1@jE#^4MErwHpOUJA&?L+u1%3t z%o_3wpSYOBYWUUmZ-n_R7AK2Elm)w(T2@rC#3gY}M^_3q^2p>=YVGU;M`)FeEsQXU3b7AT8sZJ8wx_!povrGAm_irE3{rP$ z_BpH!Y=m|(z50?3aqS?^M38PBvPf~WPPWahx%k%{uf%=zquBDCB8@2k-q`J;$ zBKkIuJ`*{glGG<7`fknr+$6umQ)x~Wix4QZi+MZCF6(5*U8z84!CuDi%l(VXud`bv zr&6~+1v@tG{eX1%BJLd03l{Kr@S8h(7P%11L^QXgPzA_{d^>Ouzm8t1ze8q7}@XJRuzc{Ifv3eXU`sjQn9RVmrh+`uVIm-MJIEz!?{p&rS z!JT_!fZQ2=XO7}oCvY_Q&D;EfWfGK^7-ysc1vkd&oONnE!}}Nf;^E7?z~**tepN8` z4WKb@_?1sv|K~6Gg;YSI&y;ff%J(ax*x8%*`xWWl-RecE=T~lC=<3w9C4T$2cZ=+` x@%;IT!nEPH?)>J9#S0fNepPEZfAL~&dK!PFqn^3`hciaa`8@kCmuh%E{~!Ck>AwH~ literal 0 HcmV?d00001 diff --git a/src/windows/identity/help/html/images/screen_tb_standard.bmp b/src/windows/identity/help/html/images/screen_tb_standard.bmp new file mode 100644 index 0000000000000000000000000000000000000000..bd07cf208dfbd33188909eff0e7c58f5abc447d3 GIT binary patch literal 52634 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 XcYDu-AtB!@_j!pg)XkX(aL)YyWC{cm literal 0 HcmV?d00001 diff --git a/src/windows/identity/help/html/images/screen_tray_icon.bmp b/src/windows/identity/help/html/images/screen_tray_icon.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b2fb1ee863159fc9f106a28b5e3d67aef2873759 GIT binary patch literal 40122 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 literal 0 HcmV?d00001 diff --git a/src/windows/identity/help/html/khm.css b/src/windows/identity/help/html/khm.css deleted file mode 100644 index 82c4d57f7..000000000 --- a/src/windows/identity/help/html/khm.css +++ /dev/null @@ -1,13 +0,0 @@ -BODY { font-family:helvetica,sans-serif; - font-size:8pt; - font-style:normal; - background-color:white; } - -H1 { font-size: 10pt; - border:solid 1px black; - padding:5px; - background-color:lightgrey - } - -H2 { } - diff --git a/src/windows/identity/help/html/menu_all.htm b/src/windows/identity/help/html/menu_all.htm new file mode 100644 index 000000000..8118a8116 --- /dev/null +++ b/src/windows/identity/help/html/menu_all.htm @@ -0,0 +1,41 @@ + + + The Menu Bar + + + + + +

The Menu Bar

+ +

+Click an item on the menu to go to the description of the submenu, or +choose from the list below. You can activate the menu bar using F10. Alternatively, you can activate each +individual submenu by pressing Alt + +<key> where key is the +highlighted character on the submenu. +

+ + + + + + + + + +

+ +

+ + + + + \ No newline at end of file diff --git a/src/windows/identity/help/html/menu_credential.htm b/src/windows/identity/help/html/menu_credential.htm new file mode 100644 index 000000000..b17533ea3 --- /dev/null +++ b/src/windows/identity/help/html/menu_credential.htm @@ -0,0 +1,86 @@ + + + Credential Menu + + + + + + +

Credential Menu

+ +

+Click an item on the menu to go to the description of the action, or +choose from the list below. You can activate the by pressing Alt + C and you can activate each action by +pressing the highlited character. +

+ +

+Actions which have an associated hot key show this hot key to the +right of the action. You can use the hot key to trigger the action +without invoking the Credential menu. +

+ + + + + + + + + + + +

+ +

+ +
+ + + \ No newline at end of file diff --git a/src/windows/identity/help/html/menu_file.htm b/src/windows/identity/help/html/menu_file.htm index 021f71f5a..91f73dfa8 100644 --- a/src/windows/identity/help/html/menu_file.htm +++ b/src/windows/identity/help/html/menu_file.htm @@ -1,18 +1,46 @@ - File menu - - - + File Menu + + + + -

File menu

+

File Menu

-

Menu items

+

+Click an item on the menu to go to the description of the action, or +choose from the list below. You can activate the by pressing Alt + F and you can activate each action by +pressing the highlited character. +

+ +

+Actions which have an associated hot key show this hot key to the +right of the action. You can use the hot key to trigger the action +without invoking the File menu. +

+ + + + + + +

+ +

+ \ No newline at end of file diff --git a/src/windows/identity/help/html/menu_help.htm b/src/windows/identity/help/html/menu_help.htm new file mode 100644 index 000000000..d95545448 --- /dev/null +++ b/src/windows/identity/help/html/menu_help.htm @@ -0,0 +1,60 @@ + + + Help Menu + + + + + + +

Help Menu

+ +

+You can activate the menu by pressing Alt + H +and you can activate each action by pressing the highlighted character. +

+ +

+You can invoke help anytime by pressing the F1 key or if you are in a dialog box, by clicking +the question mark icon in the title bar and then clicking on the +dialog box control that you want help with. +

+ +

+This is the help menu. While it is ironic that the help menu itself +needs to be explained, we have decided to include it here just for +completeness. It is bad enough that it is the last menu on the menu +bar. We didn't want to pile on any more disrespect by not documenting +it. We encourage you to not read this and just go ahead and click any +item on this menu. It is guaranteed that nothing bad will happen. +This is not a generalization that would extend to, say, the Credentials menu. If anything bad +happens, please file a bug report at kfw-bugs@mit.edu. +

+ +

+ +

+ + + + + \ No newline at end of file diff --git a/src/windows/identity/help/html/menu_options.htm b/src/windows/identity/help/html/menu_options.htm new file mode 100644 index 000000000..4d5bea9bb --- /dev/null +++ b/src/windows/identity/help/html/menu_options.htm @@ -0,0 +1,49 @@ + + + Options Menu + + + + + + +

Options Menu

+ +

+Click an item on the menu to go to the description of the action, or +choose from the list below. You can activate the by pressing Alt + O and you can activate each action by +pressing the highlited character. +

+ +

+Actions which have an associated hot key show this hot key to the +right of the action. You can use the hot key to trigger the action +without invoking the Options menu. +

+ + + + + + + +

+ +

+ +
+ + + \ No newline at end of file diff --git a/src/windows/identity/help/html/menu_view.htm b/src/windows/identity/help/html/menu_view.htm new file mode 100644 index 000000000..94920e126 --- /dev/null +++ b/src/windows/identity/help/html/menu_view.htm @@ -0,0 +1,90 @@ + + + View Menu + + + + + + +

View Menu

+ +

+Click an item on the menu to go to the description of the action, or +choose from the list below. You can activate the by pressing Alt + V and you can activate each action by +pressing the highlited character. +

+ +

+Actions which have an associated hot key show this hot key to the +right of the action. You can use the hot key to trigger the action +without invoking the View menu. +

+ + + + + + + + + +

+ +

+ +
+ + + \ No newline at end of file diff --git a/src/windows/identity/help/html/nidmgr.css b/src/windows/identity/help/html/nidmgr.css new file mode 100644 index 000000000..16c45104b --- /dev/null +++ b/src/windows/identity/help/html/nidmgr.css @@ -0,0 +1,71 @@ +BODY { + font-family:helvetica,sans-serif; + font-size:8pt; + font-style:normal; + background-color:white; + margin-top: 0; + margin-left: 0; + margin-right: 0; + } + +H1 { + font-size: 10pt; + border-bottom:1px solid black; + padding:5px; + background-color:#eeeeee; + } + +H2 { + } + +H3 { + font-size: 9pt; + border-bottom: 1px solid lightgrey; + padding: 5px; + } + +H4 { + font-size: 9pt; + font-style: italic; + border-bottom: 1px dashed lightgrey; + margin-left: 10px; + } + +P { + margin-left: 5px; + margin-right: 5px; + } + +P.caption { + margin-left: 5px; + margin-right: 5px; + font-style: italic; +} + +DIV.inline { + float: left; +} + +DIV.sidebar { + float: right; + background-color:#ffffb9; + border: 1px solid #ffff00; +} + +A.external { +} + +A.mail { +} + +IMG { + border: 0; +} + +SPAN.pre { + font-family: courier; +} + +SPAN.title { + font-weight: bold; +} \ No newline at end of file diff --git a/src/windows/identity/help/html/tb_standard.htm b/src/windows/identity/help/html/tb_standard.htm new file mode 100644 index 000000000..945063ffc --- /dev/null +++ b/src/windows/identity/help/html/tb_standard.htm @@ -0,0 +1,68 @@ + + + Standard Toolbar + + + + + + +

Standard Toolbar

+ +

The standard toolbar appears below along with descriptions of what +each button does. +

+ +

+ +

+ +
    + +
  1. New credentials: Equivalent to + selecting New + credentials... from the Credential menu. +

    + See New Credentials Action for more + information.

  2. + +
  3. Renew credentials: Equivalent to + selecting Renew Credentials from + the Credential menu. +

    + See Renew Credentials Action for + more information.

  4. + +
  5. Import credentials: Equivalent to + selecting Import Credentials from + the Credential menu. +
  6. + +
  7. Destroy credentials: Equivalent to + selecting Destroy Credentials + from the Credential menu.
  8. + +
  9. Change password: Equivalent to + selecting Change Password ... from + the Credential menu.
  10. + +
  11. Refresh view: Equivalent to selecting + Refresh + View from the Credential menu.
  12. + +
  13. Help: Displays documentation
  14. + +
+ + + \ No newline at end of file diff --git a/src/windows/identity/help/html/template.htm b/src/windows/identity/help/html/template.htm index 2130df192..5e39963da 100644 --- a/src/windows/identity/help/html/template.htm +++ b/src/windows/identity/help/html/template.htm @@ -3,7 +3,9 @@ title - + + + \ No newline at end of file diff --git a/src/windows/identity/help/html/use_start.htm b/src/windows/identity/help/html/use_start.htm new file mode 100644 index 000000000..979197999 --- /dev/null +++ b/src/windows/identity/help/html/use_start.htm @@ -0,0 +1,65 @@ + + + Starting NetIDMgr + + + + + + +

Starting NetIDMgr

+ +

Opening the NetIDMgr window from the notification icon

+ +

Depending on how you have installed NetIDMgr, it may start as soon +as you login, or it may need to be started manually. NetIDMgr is a +tray application. Hence it doesn't appear on your task bar. This is +based on the assumption that you don't need to run NetIDMgr very +often, and helps reduce clutter on the desktop.

+ + + +

When NetIDMgr is running, it places an icon in the system +notification area (sometimes referred to as the "system tray") as +shown in figure 1.

+ +

Clicking on this icon brings up the NetIDMgr window. Right +clicking on the icon, on the other hand, brings up a menu.

+ +

Starting NetIDMgr from the Start Menu or command line

+ + + +

If NetIDMgr was not configured to start automatically when you +login to Windows, then you need to start it either from the +commandline or the start menu. The start menu application icon is +under "Kerberos for Windows" as shown in figure 2.

+ +

Alternatively, you can type 'netidmgr' at a command shell to start +NetIDMgr as well. When starting this way, you may specify additional +command line options.

+ +

Configuring startup options

+ +

+Note that you can configure options related to the startup of NetIDMgr +by using the NetIDMgr configuration dialog box. You can use the menu +items under the Options menu to invoke the +configuration dialog. +

+ +

+Only one instance of NetIDMgr can be running at any one time. +Attempting to start NetIDMgr while it is still running will not do +anything, unless you provide any command line options that trigger +some action in the running application instance. +

+ + + \ No newline at end of file diff --git a/src/windows/identity/help/html/using.htm b/src/windows/identity/help/html/using.htm new file mode 100644 index 000000000..2d84df2cd --- /dev/null +++ b/src/windows/identity/help/html/using.htm @@ -0,0 +1,47 @@ + + + Using NetIDMgr + + + + + + +

Using NetIDMgr

+ +

+Depending on how NetIDMgr was installed, it might already be running +in the system notification area or it might need to be started +manually. See the topic starting +NetIDMgr for details. Essentially, to open the NetIDMgr window, +you either have to click the application icon in the system +notification area, select the icon from the start menu, or type +'netidmgr' at a command prompt. +

+ +

+Once you open the NetIDMgr window, you will be presented with a view +of your existing credentials, or a message notifying you that you +don't have any. The credentials view should be fairly self +explanatory, but if there's any doubt, more information can be found here. +

+ +

+Brief overviews of how to perform common tasks are linked below: +

+ + + +

+A more comprehensive list of how-to topics can be found in the How do I... section.

+ + + \ No newline at end of file diff --git a/src/windows/identity/help/html/welcome.htm b/src/windows/identity/help/html/welcome.htm index 32d7d05b2..9cd7bc43e 100644 --- a/src/windows/identity/help/html/welcome.htm +++ b/src/windows/identity/help/html/welcome.htm @@ -1,24 +1,70 @@ - Welcome to Khimaira + Welcome to the Network Identity Manager - + -

Welcome to Khimaira

+

Welcome to the Network Identity Manager

-

Khimaira is a credentials manager that lets you manage Kerberos, -AFS and other types of credentials. +

+ +
+ +

+The Network Identity Manager (or NetIDMgr for short) allows you to +manage your credentials (Kerberos tickets, AFS tokens, etc.) on a per +identity basis. +

+ +

+NetIDMgr is extensible using plugins. In fact, most of the features +are implemented in plugins, some of which are themselves extensible. +Support for additional protocols and credential types can be added by +installing the appropriate plugins. +

+ +

+This version is distributed as a part of the MIT Kerberos for Windows +product along with the Kerberos 5 and Kerberos 4 plugins. The OpenAFS +plugin, which is required for supporting OpenAFS tokens, is +distributed separately.

-

The following web sites provide more information about Kerberos and -AFS:

+ + +

Getting started

+

Information for developers

+ +

+If you are interested in developing plugins or extending the features +of NetIDMgr, your first stop should be the NetIDMgr SDK. This is +included in the Kerberos for Windows SDK, which itself is a part of +the Kerberos for Windows distribution. +

+ +

External links

+ + \ No newline at end of file diff --git a/src/windows/identity/help/html/wnd_main.htm b/src/windows/identity/help/html/wnd_main.htm new file mode 100644 index 000000000..575e7ba3f --- /dev/null +++ b/src/windows/identity/help/html/wnd_main.htm @@ -0,0 +1,89 @@ + + + Main Window + + + + + + +

Main Window

+ +

The main window of Network Identity Manager is structured as follows

+ + + + + + + + + + + + + +
    +
  1. Menu bar
  2. +
  3. Tool bar
  4. + +
  5. An identity with a valid Kerberos 5 initial + ticket
  6. + +
  7. An identity with valid Kerberos 5 tickets and + AFS tokens
  8. + +
  9. A set of Kerberos 5 tickets
  10. + +
  11. A set of AFS tokens
  12. + +
  13. An identity with expired Kerberos 5 tickets
  14. + +
+ +

Identity views

+ +

+The default credentials view organizes them grouped by identity name +and then by credential type. Each credential is then shown under each +group heading sorted by the credential name. The default headings for +the credential view provides you with a minimal amount of information +to reduce clutter. If you wish you can add columns to the display +using the Choose columns... action on the +View menu. +

+ +

+The header backgrounds and the credential rows change color if the +credentials are about to expire or are expired. + +

    + +
  • Headers mean that +credentials at that level will expire unless renewed. Credentials +will have a warning icon next to them.
    + +The threshold for this can be set as the Warn +parameter in the Notifications configuration +panel.
  • + +
  • Headers mean that +credentials at that level will expire in a few minutes. Credentials +will have a critical icon next to them.
    + +The threshold for this can be set as the Warn +again parameter in the Notifications +configuration panel.
  • + +
  • Headers mean that +the credentials at that level have expired. Credentials will have an +expired icon next to them.
    + +The threshold for this is always zero. +
  • + +
+

+ + + diff --git a/src/windows/identity/help/khhelp.h b/src/windows/identity/help/khhelp.h index 4ffa6d8f5..1324c3dc4 100644 --- a/src/windows/identity/help/khhelp.h +++ b/src/windows/identity/help/khhelp.h @@ -1,10 +1,13 @@ +#define NIDM_HELPFILE L"netidmgr.chm" #define IDH_WELCOME 1000 -#define IDH_MENU_FILE 1001 -#define IDH_MENU_CRED 1002 -#define IDH_MENU_VIEW 1003 -#define IDH_MENU_OPTIONS 1004 -#define IDH_MENU_HELP 1005 +#define IDH_WIN_MAIN 1001 + +#define IDH_MENU_FILE 1501 +#define IDH_MENU_CRED 1502 +#define IDH_MENU_VIEW 1503 +#define IDH_MENU_OPTIONS 1504 +#define IDH_MENU_HELP 1505 #define IDH_ACTION_PROPERTIES 2000 #define IDH_ACTION_EXIT 2001 diff --git a/src/windows/identity/help/netidmgr.hhp b/src/windows/identity/help/netidmgr.hhp index 8e0d5a597..9930dc5bc 100644 --- a/src/windows/identity/help/netidmgr.hhp +++ b/src/windows/identity/help/netidmgr.hhp @@ -3,16 +3,27 @@ Auto Index=Yes Compatibility=1.1 or later Compiled file=netidmgr.chm Contents file=toc.hhc +Default Window=MainHelpWnd Default topic=html/welcome.htm Display compile progress=No Index file=Index.hhk Language=0x409 English (United States) Title=NetIDMgr +[WINDOWS] +MainHelpWnd="NetIDMgr Help","toc.hhc","Index.hhk","html/welcome.htm","html/welcome.htm",,,,,0x42120,,0x384e,[271,372,593,566],0x830000,,,,,,0 + + +[ALIAS] +IDH_WELCOME=html\welcome.htm [MAP] #include khhelp.h +[TEXT POPUPS] +khhelp.h +popups_newcreds.txt + [INFOTYPES] Category:Concepts CategoryDesc:Authentication, authorization and related concepts. diff --git a/src/windows/identity/help/popups.txt b/src/windows/identity/help/popups.txt new file mode 100644 index 000000000..7d58703b1 --- /dev/null +++ b/src/windows/identity/help/popups.txt @@ -0,0 +1 @@ +foo diff --git a/src/windows/identity/help/popups_newcreds.txt b/src/windows/identity/help/popups_newcreds.txt new file mode 100644 index 000000000..7d58703b1 --- /dev/null +++ b/src/windows/identity/help/popups_newcreds.txt @@ -0,0 +1 @@ +foo diff --git a/src/windows/identity/help/toc.hhc b/src/windows/identity/help/toc.hhc index cde5119a3..106c22054 100644 --- a/src/windows/identity/help/toc.hhc +++ b/src/windows/identity/help/toc.hhc @@ -8,40 +8,123 @@ - +
  • - +
  • - + + + +
  • + +
    • - - -
        -
      • - - - -
      -
    • - - -
        -
      • - - - -
      • - - - -
      + + + +
    • + + + +
    +
  • + + + +
      +
    • + + + +
    • + + + +
    • + + + +
    +
  • + + + +
      +
    • + + + +
    +
  • + + + +
      +
    • + + + +
    • + + + +
    • + + + +
    • + + + +
    • + + + +
    • + + + +
    +
  • + + +
      +
    • + + + +
    • + + + +
    • + + + +
    • + + + +
    • + + + +
    +
  • + + +
      +
    • + + +
diff --git a/src/windows/identity/include/Makefile b/src/windows/identity/include/Makefile index 17182d57a..be4ddf9a2 100644 --- a/src/windows/identity/include/Makefile +++ b/src/windows/identity/include/Makefile @@ -29,7 +29,8 @@ INCFILES= \ $(INCDIR)\khdefs.h \ $(INCDIR)\kherror.h \ $(INCDIR)\khlist.h \ - $(INCDIR)\khmsgtypes.h + $(INCDIR)\khmsgtypes.h \ + $(INCDIR)\netidmgr.h all: $(INCFILES) diff --git a/src/windows/identity/include/khdefs.h b/src/windows/identity/include/khdefs.h index 427926306..4a0251107 100644 --- a/src/windows/identity/include/khdefs.h +++ b/src/windows/identity/include/khdefs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/include/kherror.h b/src/windows/identity/include/kherror.h index d56fa7dc7..f11e28510 100644 --- a/src/windows/identity/include/kherror.h +++ b/src/windows/identity/include/kherror.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -66,7 +66,7 @@ #define KHM_ERROR_TOO_LONG (KHM_ERROR_BASE + 2) /*! \brief One or more parameters supplied to a function were invalid */ -#define KHM_ERROR_INVALID_PARM (KHM_ERROR_BASE + 3) +#define KHM_ERROR_INVALID_PARAM (KHM_ERROR_BASE + 3) /*! \brief A duplicate. @@ -165,6 +165,9 @@ */ #define KHM_ERROR_PARTIAL (KHM_ERROR_BASE + 20) +/*! \brief An incompatibility was found */ +#define KHM_ERROR_INCOMPATIBLE (KHM_ERROR_BASE + 21) + /*@}*/ /*kherror_codes*/ /*! \brief Tests whether a return value indicates success */ diff --git a/src/windows/identity/include/khlist.h b/src/windows/identity/include/khlist.h index 330cfc498..2eb85864a 100644 --- a/src/windows/identity/include/khlist.h +++ b/src/windows/identity/include/khlist.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/include/khmsgtypes.h b/src/windows/identity/include/khmsgtypes.h index 8348bbf95..dfc39e2f0 100644 --- a/src/windows/identity/include/khmsgtypes.h +++ b/src/windows/identity/include/khmsgtypes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -442,6 +442,15 @@ */ #define KMSG_CRED_PP_DESTROY 131 +/*! \brief An IP address change occurred + + There are no parameters for this message. The NetIDMgr + application handles this message and depending on configuration, + posts message for the individual credentials providers to either + obtain new credentials or renew old ones. + */ +#define KMSG_CRED_ADDR_CHANGE 140 + /*! \brief Check if a KMSG_CRED subtype is a credentials acquisition message Dialog messages are those that deal with the new or initial @@ -483,6 +492,28 @@ */ #define KMSG_ALERT_SHOW 1 +/*! \brief Add an alert to the alert queue + + Message parameters: + - \b vparam : held pointer to a ::khui_alert object + + \note the ::khui_alert object will be released when the queued + messages are displayed. + */ +#define KMSG_ALERT_QUEUE 2 + +/*! \brief Show the next queued alert + + There are no message parameters + */ +#define KMSG_ALERT_SHOW_QUEUED 3 + +/*! \brief Check if there are any queued messages and, if so, update the statusbar + + There are no message parameters + */ +#define KMSG_ALERT_CHECK_QUEUE 4 + /*@}*/ /*! \defgroup kmq_msg_ident KMSG_IDENT Subtypes diff --git a/src/windows/identity/include/khthread.h b/src/windows/identity/include/netidmgr.h similarity index 67% rename from src/windows/identity/include/khthread.h rename to src/windows/identity/include/netidmgr.h index b7354c468..94e188ff1 100644 --- a/src/windows/identity/include/khthread.h +++ b/src/windows/identity/include/netidmgr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -24,19 +24,20 @@ /* $Id$ */ -/* Not exported */ -#ifndef __KHIMAIRA_KTHREAD_H -#define __KHIMAIRA_KTHREAD_H +#ifndef __NETIDMGR_H +#define __NETIDMGR_H -#ifdef _WIN32 -#define khm_mutex CRITICAL_SECTION +#include "khdefs.h" -#define khp_mutex_init(pcs) InitializeCriticalSection(pcs) -#define khp_mutex_destroy(pcs) DeleteCriticalSection(pcs) -#define khp_mutex_lock(pcs) EnterCriticalSection(pcs) -#define khp_mutex_unlock(pcs) LeaveCriticalSection(pcs) -#define khp_mutex_trylock(pcs) (!TryEnterCriticalSection(pcs)) +#include "utils.h" +#include "khuidefs.h" +#include "kmq.h" +#include "khmsgtypes.h" +#include "kcreddb.h" +#include "kherr.h" +#include "kherror.h" +#include "kconfig.h" +#include "kmm.h" +#include "kplugin.h" #endif - -#endif \ No newline at end of file diff --git a/src/windows/identity/kconfig/api.c b/src/windows/identity/kconfig/api.c index 3d69c998e..39e72ecf5 100644 --- a/src/windows/identity/kconfig/api.c +++ b/src/windows/identity/kconfig/api.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2004 Massachusetts Institute of Technology +* Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -41,9 +41,9 @@ void init_kconf(void) { /* we are the first */ InitializeCriticalSection(&cs_conf_global); EnterCriticalSection(&cs_conf_global); - conf_root = khc_create_empty_space(); - conf_root->name = wcsdup(L"Root"); - conf_root->regpath = wcsdup(CONFIG_REGPATHW); + conf_root = khcint_create_empty_space(); + conf_root->name = PWCSDUP(L"Root"); + conf_root->regpath = PWCSDUP(CONFIG_REGPATHW); conf_root->refcount++; conf_status = 1; InitializeCriticalSection(&cs_conf_handle); @@ -61,20 +61,20 @@ void exit_kconf(void) { conf_init = 0; conf_status = 0; - khc_free_space(conf_root); + khcint_free_space(conf_root); EnterCriticalSection(&cs_conf_handle); while(conf_free_handles) { LPOP(&conf_free_handles, &h); if(h) { - free(h); + PFREE(h); } } while(conf_handles) { LPOP(&conf_handles, &h); if(h) { - free(h); + PFREE(h); } } LeaveCriticalSection(&cs_conf_handle); @@ -85,20 +85,21 @@ void exit_kconf(void) { } } -kconf_handle * khc_handle_from_space(kconf_conf_space * s, khm_int32 flags) +kconf_handle * +khcint_handle_from_space(kconf_conf_space * s, khm_int32 flags) { kconf_handle * h; EnterCriticalSection(&cs_conf_handle); LPOP(&conf_free_handles, &h); if(!h) { - h = malloc(sizeof(kconf_handle)); - assert(h != NULL); + h = PMALLOC(sizeof(kconf_handle)); + assert(h != NULL); } ZeroMemory((void *) h, sizeof(kconf_handle)); h->magic = KCONF_HANDLE_MAGIC; - khc_space_hold(s); + khcint_space_hold(s); h->space = s; h->flags = flags; @@ -109,7 +110,8 @@ kconf_handle * khc_handle_from_space(kconf_conf_space * s, khm_int32 flags) } /* must be called with cs_conf_global held */ -void khc_handle_free(kconf_handle * h) +void +khcint_handle_free(kconf_handle * h) { kconf_handle * lower; @@ -133,7 +135,7 @@ void khc_handle_free(kconf_handle * h) while(h) { LDELETE(&conf_handles, h); if(h->space) { - khc_space_release(h->space); + khcint_space_release(h->space); h->space = NULL; } lower = h->lower; @@ -143,16 +145,17 @@ void khc_handle_free(kconf_handle * h) LeaveCriticalSection(&cs_conf_handle); } -kconf_handle * khc_handle_dup(kconf_handle * o) +kconf_handle * +khcint_handle_dup(kconf_handle * o) { kconf_handle * h; kconf_handle * r; - r = khc_handle_from_space(o->space, o->flags); + r = khcint_handle_from_space(o->space, o->flags); h = r; while(o->lower) { - h->lower = khc_handle_from_space(o->lower->space, o->lower->flags); + h->lower = khcint_handle_from_space(o->lower->space, o->lower->flags); o = o->lower; h = h->lower; @@ -161,21 +164,26 @@ kconf_handle * khc_handle_dup(kconf_handle * o) return r; } -void khc_space_hold(kconf_conf_space * s) { +void +khcint_space_hold(kconf_conf_space * s) { InterlockedIncrement(&(s->refcount)); } -void khc_space_release(kconf_conf_space * s) { +void +khcint_space_release(kconf_conf_space * s) { LONG l = InterlockedDecrement(&(s->refcount)); if(!l) { EnterCriticalSection(&cs_conf_global); - if(s->regkey_machine) - RegCloseKey(s->regkey_machine); - if(s->regkey_user) - RegCloseKey(s->regkey_user); - s->regkey_machine = NULL; - s->regkey_user = NULL; + /* check again */ + if (!l) { + if(s->regkey_machine) + RegCloseKey(s->regkey_machine); + if(s->regkey_user) + RegCloseKey(s->regkey_user); + s->regkey_machine = NULL; + s->regkey_user = NULL; + } LeaveCriticalSection(&cs_conf_global); } @@ -407,7 +415,8 @@ khcint_RegCreateKeyEx(HKEY hKey, } -HKEY khc_space_open_key(kconf_conf_space * s, khm_int32 flags) { +HKEY +khcint_space_open_key(kconf_conf_space * s, khm_int32 flags) { HKEY hk = NULL; int nflags = 0; DWORD disp; @@ -479,7 +488,8 @@ HKEY khc_space_open_key(kconf_conf_space * s, khm_int32 flags) { } } -KHMEXP khm_int32 KHMAPI khc_shadow_space(khm_handle upper, khm_handle lower) +KHMEXP khm_int32 KHMAPI +khc_shadow_space(khm_handle upper, khm_handle lower) { kconf_handle * h; @@ -487,7 +497,7 @@ KHMEXP khm_int32 KHMAPI khc_shadow_space(khm_handle upper, khm_handle lower) return KHM_ERROR_NOT_READY; if(!khc_is_handle(upper)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; h = (kconf_handle *) upper; @@ -495,7 +505,7 @@ KHMEXP khm_int32 KHMAPI khc_shadow_space(khm_handle upper, khm_handle lower) if(h->lower) { LeaveCriticalSection(&cs_conf_handle); EnterCriticalSection(&cs_conf_global); - khc_handle_free(h->lower); + khcint_handle_free(h->lower); LeaveCriticalSection(&cs_conf_global); EnterCriticalSection(&cs_conf_handle); h->lower = NULL; @@ -507,7 +517,7 @@ KHMEXP khm_int32 KHMAPI khc_shadow_space(khm_handle upper, khm_handle lower) l = (kconf_handle *) lower; LeaveCriticalSection(&cs_conf_handle); - lc = khc_handle_dup(l); + lc = khcint_handle_dup(l); EnterCriticalSection(&cs_conf_handle); h->lower = lc; } @@ -516,17 +526,19 @@ KHMEXP khm_int32 KHMAPI khc_shadow_space(khm_handle upper, khm_handle lower) return KHM_ERROR_SUCCESS; } -kconf_conf_space * khc_create_empty_space(void) { +kconf_conf_space * +khcint_create_empty_space(void) { kconf_conf_space * r; - r = malloc(sizeof(kconf_conf_space)); - assert(r != NULL); + r = PMALLOC(sizeof(kconf_conf_space)); + assert(r != NULL); ZeroMemory(r,sizeof(kconf_conf_space)); return r; } -void khc_free_space(kconf_conf_space * r) { +void +khcint_free_space(kconf_conf_space * r) { kconf_conf_space * c; if(!r) @@ -534,15 +546,15 @@ void khc_free_space(kconf_conf_space * r) { LPOP(&r->children, &c); while(c) { - khc_free_space(c); + khcint_free_space(c); LPOP(&r->children, &c); } if(r->name) - free(r->name); + PFREE(r->name); if(r->regpath) - free(r->regpath); + PFREE(r->regpath); if(r->regkey_machine) RegCloseKey(r->regkey_machine); @@ -550,10 +562,13 @@ void khc_free_space(kconf_conf_space * r) { if(r->regkey_user) RegCloseKey(r->regkey_user); - free(r); + PFREE(r); } -khm_int32 khcint_open_space_int(kconf_conf_space * parent, wchar_t * sname, size_t n_sname, khm_int32 flags, kconf_conf_space **result) { +khm_int32 +khcint_open_space_int(kconf_conf_space * parent, + wchar_t * sname, size_t n_sname, + khm_int32 flags, kconf_conf_space **result) { kconf_conf_space * p; kconf_conf_space * c; HKEY pkey = NULL; @@ -566,10 +581,10 @@ khm_int32 khcint_open_space_int(kconf_conf_space * parent, wchar_t * sname, size p = parent; if(n_sname >= KCONF_MAXCCH_NAME || n_sname <= 0) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; - /*SAFE: buf: buffer size == KCONF_MAXCCH_NAME * wchar_t > - n_sname * wchar_t */ + /*SAFE: buf: buffer size == KCONF_MAXCCH_NAME * wchar_t > + n_sname * wchar_t */ wcsncpy(buf, sname, n_sname); buf[n_sname] = L'\0'; @@ -587,7 +602,7 @@ khm_int32 khcint_open_space_int(kconf_conf_space * parent, wchar_t * sname, size LeaveCriticalSection(&cs_conf_global); if(c) { - khc_space_hold(c); + khcint_space_hold(c); *result = c; return KHM_ERROR_SUCCESS; } @@ -598,14 +613,14 @@ khm_int32 khcint_open_space_int(kconf_conf_space * parent, wchar_t * sname, size registry key in HKLM or HKCU. If it existed as a schema, we would have already retured it above. */ if(flags & KCONF_FLAG_USER) - pkey = khc_space_open_key(p, KHM_PERM_READ | KCONF_FLAG_USER); + pkey = khcint_space_open_key(p, KHM_PERM_READ | KCONF_FLAG_USER); if((!pkey || (khcint_RegOpenKeyEx(pkey, buf, 0, KEY_READ, &ckey) != ERROR_SUCCESS)) && (flags & KCONF_FLAG_MACHINE)) { - pkey = khc_space_open_key(p, KHM_PERM_READ | KCONF_FLAG_MACHINE); + pkey = khcint_space_open_key(p, KHM_PERM_READ | KCONF_FLAG_MACHINE); if(!pkey || (khcint_RegOpenKeyEx(pkey, buf, 0, KEY_READ, &ckey) != ERROR_SUCCESS)) { @@ -620,15 +635,15 @@ khm_int32 khcint_open_space_int(kconf_conf_space * parent, wchar_t * sname, size } } - c = khc_create_empty_space(); + c = khcint_create_empty_space(); /*SAFE: buf: is of known length < KCONF_MAXCCH_NAME */ - c->name = wcsdup(buf); + c->name = PWCSDUP(buf); /*SAFE: p->regpath: is valid since it was set using this same function. */ /*SAFE: buf: see above */ - c->regpath = malloc((wcslen(p->regpath) + wcslen(buf) + 2) * sizeof(wchar_t)); + c->regpath = PMALLOC((wcslen(p->regpath) + wcslen(buf) + 2) * sizeof(wchar_t)); assert(c->regpath != NULL); @@ -642,7 +657,7 @@ khm_int32 khcint_open_space_int(kconf_conf_space * parent, wchar_t * sname, size wcscat(c->regpath, buf); #pragma warning( pop ) - khc_space_hold(c); + khcint_space_hold(c); EnterCriticalSection(&cs_conf_global); TADDCHILD(p,c); @@ -652,7 +667,9 @@ khm_int32 khcint_open_space_int(kconf_conf_space * parent, wchar_t * sname, size return KHM_ERROR_SUCCESS; } -KHMEXP khm_int32 KHMAPI khc_open_space(khm_handle parent, wchar_t * cspace, khm_int32 flags, khm_handle * result) { +KHMEXP khm_int32 KHMAPI +khc_open_space(khm_handle parent, wchar_t * cspace, khm_int32 flags, + khm_handle * result) { kconf_handle * h; kconf_conf_space * p; kconf_conf_space * c = NULL; @@ -665,7 +682,7 @@ KHMEXP khm_int32 KHMAPI khc_open_space(khm_handle parent, wchar_t * cspace, khm_ } if(!result || (parent && !khc_is_handle(parent))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(!parent) p = conf_root; @@ -674,7 +691,7 @@ KHMEXP khm_int32 KHMAPI khc_open_space(khm_handle parent, wchar_t * cspace, khm_ p = khc_space_from_handle(parent); } - khc_space_hold(p); + khcint_space_hold(p); /* if none of these flags are specified, make it seem like all of them were */ @@ -684,15 +701,15 @@ KHMEXP khm_int32 KHMAPI khc_open_space(khm_handle parent, wchar_t * cspace, khm_ flags |= KCONF_FLAG_USER | KCONF_FLAG_MACHINE | KCONF_FLAG_SCHEMA; if(cspace == NULL) { - khc_space_release(p); - *result = (khm_handle) khc_handle_from_space(p, flags); + khcint_space_release(p); + *result = (khm_handle) khcint_handle_from_space(p, flags); return KHM_ERROR_SUCCESS; } if(FAILED(StringCbLength(cspace, KCONF_MAXCB_PATH, &cbsize))) { - khc_space_release(p); + khcint_space_release(p); *result = NULL; - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } str = cspace; @@ -714,7 +731,7 @@ KHMEXP khm_int32 KHMAPI khc_open_space(khm_handle parent, wchar_t * cspace, khm_ if(flags & KCONF_FLAG_TRAILINGVALUE) { /* we are at the value component */ c = p; - khc_space_hold(c); + khcint_space_hold(c); break; } else end = str + wcslen(str); /* safe because cspace was @@ -728,7 +745,7 @@ KHMEXP khm_int32 KHMAPI khc_open_space(khm_handle parent, wchar_t * cspace, khm_ || *end == L'/' #endif )) { - khc_space_release(p); + khcint_space_release(p); p = c; c = NULL; str = end+1; @@ -737,30 +754,32 @@ KHMEXP khm_int32 KHMAPI khc_open_space(khm_handle parent, wchar_t * cspace, khm_ break; } - khc_space_release(p); + khcint_space_release(p); if(KHM_SUCCEEDED(rv)) { - *result = khc_handle_from_space(c, flags); + *result = khcint_handle_from_space(c, flags); } else *result = NULL; return rv; } -KHMEXP khm_int32 KHMAPI khc_close_space(khm_handle csp) { +KHMEXP khm_int32 KHMAPI +khc_close_space(khm_handle csp) { if(!khc_is_config_running()) return KHM_ERROR_NOT_READY; if(!khc_is_handle(csp)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; - khc_handle_free((kconf_handle *) csp); + khcint_handle_free((kconf_handle *) csp); return KHM_ERROR_SUCCESS; } -KHMEXP khm_int32 KHMAPI khc_read_string(khm_handle pconf, - wchar_t * pvalue, - wchar_t * buf, - khm_size * bufsize) +KHMEXP khm_int32 KHMAPI +khc_read_string(khm_handle pconf, + wchar_t * pvalue, + wchar_t * buf, + khm_size * bufsize) { kconf_conf_space * c; khm_int32 rv = KHM_ERROR_SUCCESS; @@ -815,10 +834,10 @@ KHMEXP khm_int32 KHMAPI khc_read_string(khm_handle pconf, c = khc_space_from_handle(conf); if(khc_is_user_handle(conf)) - hku = khc_space_open_key(c, KHM_PERM_READ); + hku = khcint_space_open_key(c, KHM_PERM_READ); if(khc_is_machine_handle(conf)) - hkm = khc_space_open_key(c, KHM_PERM_READ | KCONF_FLAG_MACHINE); + hkm = khcint_space_open_key(c, KHM_PERM_READ | KCONF_FLAG_MACHINE); size = (DWORD) *bufsize; if(hku) { @@ -919,7 +938,8 @@ _exit: return rv; } -KHMEXP khm_int32 KHMAPI khc_read_int32(khm_handle pconf, wchar_t * pvalue, khm_int32 * buf) { +KHMEXP khm_int32 KHMAPI +khc_read_int32(khm_handle pconf, wchar_t * pvalue, khm_int32 * buf) { kconf_conf_space * c; khm_int32 rv = KHM_ERROR_SUCCESS; @@ -927,7 +947,7 @@ KHMEXP khm_int32 KHMAPI khc_read_int32(khm_handle pconf, wchar_t * pvalue, khm_i return KHM_ERROR_NOT_READY; if(!buf || !pvalue) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; do { DWORD size; @@ -975,10 +995,10 @@ KHMEXP khm_int32 KHMAPI khc_read_int32(khm_handle pconf, wchar_t * pvalue, khm_i c = khc_space_from_handle(conf); if(khc_is_user_handle(conf)) - hku = khc_space_open_key(c, KHM_PERM_READ); + hku = khcint_space_open_key(c, KHM_PERM_READ); if(khc_is_machine_handle(conf)) - hkm = khc_space_open_key(c, KHM_PERM_READ | KCONF_FLAG_MACHINE); + hkm = khcint_space_open_key(c, KHM_PERM_READ | KCONF_FLAG_MACHINE); size = sizeof(DWORD); if(hku) { @@ -1040,7 +1060,8 @@ _exit: return rv; } -KHMEXP khm_int32 KHMAPI khc_read_int64(khm_handle pconf, wchar_t * pvalue, khm_int64 * buf) { +KHMEXP khm_int32 KHMAPI +khc_read_int64(khm_handle pconf, wchar_t * pvalue, khm_int64 * buf) { kconf_conf_space * c; khm_int32 rv = KHM_ERROR_SUCCESS; @@ -1093,10 +1114,10 @@ KHMEXP khm_int32 KHMAPI khc_read_int64(khm_handle pconf, wchar_t * pvalue, khm_i c = khc_space_from_handle(conf); if(khc_is_user_handle(conf)) - hku = khc_space_open_key(c, KHM_PERM_READ); + hku = khcint_space_open_key(c, KHM_PERM_READ); if(khc_is_machine_handle(conf)) - hkm = khc_space_open_key(c, KHM_PERM_READ | KCONF_FLAG_MACHINE); + hkm = khcint_space_open_key(c, KHM_PERM_READ | KCONF_FLAG_MACHINE); size = sizeof(khm_int64); if(hku) { @@ -1158,7 +1179,9 @@ _exit: return rv; } -KHMEXP khm_int32 KHMAPI khc_read_binary(khm_handle pconf, wchar_t * pvalue, void * buf, khm_size * bufsize) { +KHMEXP khm_int32 KHMAPI +khc_read_binary(khm_handle pconf, wchar_t * pvalue, + void * buf, khm_size * bufsize) { kconf_conf_space * c; khm_int32 rv = KHM_ERROR_SUCCESS; @@ -1209,10 +1232,10 @@ KHMEXP khm_int32 KHMAPI khc_read_binary(khm_handle pconf, wchar_t * pvalue, void c = khc_space_from_handle(conf); if(khc_is_user_handle(conf)) - hku = khc_space_open_key(c, KHM_PERM_READ); + hku = khcint_space_open_key(c, KHM_PERM_READ); if(khc_is_machine_handle(conf)) - hkm = khc_space_open_key(c, KHM_PERM_READ | KCONF_FLAG_MACHINE); + hkm = khcint_space_open_key(c, KHM_PERM_READ | KCONF_FLAG_MACHINE); size = (DWORD) *bufsize; if(hku) { @@ -1280,10 +1303,10 @@ _exit: return rv; } -KHMEXP khm_int32 KHMAPI khc_write_string( - khm_handle pconf, - wchar_t * pvalue, - wchar_t * buf) +KHMEXP khm_int32 KHMAPI +khc_write_string(khm_handle pconf, + wchar_t * pvalue, + wchar_t * buf) { HKEY pk = NULL; kconf_conf_space * c; @@ -1311,7 +1334,7 @@ KHMEXP khm_int32 KHMAPI khc_write_string( pvalue, KCONF_FLAG_TRAILINGVALUE | (pconf?khc_handle_flags(pconf):0), &conf))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; free_space = 1; #if 0 wchar_t * back, *forward; @@ -1329,23 +1352,23 @@ KHMEXP khm_int32 KHMAPI khc_write_string( } if(!khc_is_handle(conf) || !buf) { - rv = KHM_ERROR_INVALID_PARM; + rv = KHM_ERROR_INVALID_PARAM; goto _exit; } c = khc_space_from_handle(conf); if(FAILED(StringCbLength(buf, KCONF_MAXCB_STRING, &cbsize))) { - rv = KHM_ERROR_INVALID_PARM; + rv = KHM_ERROR_INVALID_PARAM; goto _exit; } cbsize += sizeof(wchar_t); if(khc_is_user_handle(conf)) { - pk = khc_space_open_key(c, KHM_PERM_WRITE | KHM_FLAG_CREATE); + pk = khcint_space_open_key(c, KHM_PERM_WRITE | KHM_FLAG_CREATE); } else { - pk = khc_space_open_key(c, KHM_PERM_WRITE | KCONF_FLAG_MACHINE | KHM_FLAG_CREATE); + pk = khcint_space_open_key(c, KHM_PERM_WRITE | KCONF_FLAG_MACHINE | KHM_FLAG_CREATE); } hr = RegSetValueEx(pk, value, 0, REG_SZ, (LPBYTE) buf, (DWORD) cbsize); @@ -1359,10 +1382,10 @@ _exit: return rv; } -KHMEXP khm_int32 KHMAPI khc_write_int32( - khm_handle pconf, - wchar_t * pvalue, - khm_int32 buf) +KHMEXP khm_int32 KHMAPI +khc_write_int32(khm_handle pconf, + wchar_t * pvalue, + khm_int32 buf) { HKEY pk = NULL; kconf_conf_space * c; @@ -1389,7 +1412,7 @@ KHMEXP khm_int32 KHMAPI khc_write_int32( pvalue, KCONF_FLAG_TRAILINGVALUE | (pconf?khc_handle_flags(pconf):0), &conf))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; free_space = 1; #if 0 wchar_t * back, *forward; @@ -1407,14 +1430,14 @@ KHMEXP khm_int32 KHMAPI khc_write_int32( } if(!khc_is_handle(conf)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; c = khc_space_from_handle( conf); if(khc_is_user_handle(conf)) { - pk = khc_space_open_key(c, KHM_PERM_WRITE | KHM_FLAG_CREATE); + pk = khcint_space_open_key(c, KHM_PERM_WRITE | KHM_FLAG_CREATE); } else { - pk = khc_space_open_key(c, KHM_PERM_WRITE | KCONF_FLAG_MACHINE | KHM_FLAG_CREATE); + pk = khcint_space_open_key(c, KHM_PERM_WRITE | KCONF_FLAG_MACHINE | KHM_FLAG_CREATE); } hr = RegSetValueEx(pk, value, 0, REG_DWORD, (LPBYTE) &buf, sizeof(khm_int32)); @@ -1428,7 +1451,8 @@ KHMEXP khm_int32 KHMAPI khc_write_int32( return rv; } -KHMEXP khm_int32 KHMAPI khc_write_int64(khm_handle pconf, wchar_t * pvalue, khm_int64 buf) { +KHMEXP khm_int32 KHMAPI +khc_write_int64(khm_handle pconf, wchar_t * pvalue, khm_int64 buf) { HKEY pk = NULL; kconf_conf_space * c; khm_int32 rv = KHM_ERROR_SUCCESS; @@ -1454,7 +1478,7 @@ KHMEXP khm_int32 KHMAPI khc_write_int64(khm_handle pconf, wchar_t * pvalue, khm_ pvalue, KCONF_FLAG_TRAILINGVALUE | (pconf?khc_handle_flags(pconf):0), &conf))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; free_space = 1; #if 0 wchar_t * back, *forward; @@ -1472,14 +1496,14 @@ KHMEXP khm_int32 KHMAPI khc_write_int64(khm_handle pconf, wchar_t * pvalue, khm_ } if(!khc_is_handle(conf)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; c = khc_space_from_handle( conf); if(khc_is_user_handle(conf)) { - pk = khc_space_open_key(c, KHM_PERM_WRITE | KHM_FLAG_CREATE); + pk = khcint_space_open_key(c, KHM_PERM_WRITE | KHM_FLAG_CREATE); } else { - pk = khc_space_open_key(c, KHM_PERM_WRITE | KCONF_FLAG_MACHINE | KHM_FLAG_CREATE); + pk = khcint_space_open_key(c, KHM_PERM_WRITE | KCONF_FLAG_MACHINE | KHM_FLAG_CREATE); } hr = RegSetValueEx(pk, value, 0, REG_QWORD, (LPBYTE) &buf, sizeof(khm_int64)); @@ -1493,7 +1517,10 @@ KHMEXP khm_int32 KHMAPI khc_write_int64(khm_handle pconf, wchar_t * pvalue, khm_ return rv; } -KHMEXP khm_int32 KHMAPI khc_write_binary(khm_handle pconf, wchar_t * pvalue, void * buf, khm_size bufsize) { +KHMEXP khm_int32 KHMAPI +khc_write_binary(khm_handle pconf, + wchar_t * pvalue, + void * buf, khm_size bufsize) { HKEY pk = NULL; kconf_conf_space * c; khm_int32 rv = KHM_ERROR_SUCCESS; @@ -1519,7 +1546,7 @@ KHMEXP khm_int32 KHMAPI khc_write_binary(khm_handle pconf, wchar_t * pvalue, voi pvalue, KCONF_FLAG_TRAILINGVALUE | (pconf?khc_handle_flags(pconf):0), &conf))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; free_space = 1; #if 0 wchar_t * back, *forward; @@ -1537,14 +1564,14 @@ KHMEXP khm_int32 KHMAPI khc_write_binary(khm_handle pconf, wchar_t * pvalue, voi } if(!khc_is_handle(conf)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; c = khc_space_from_handle(conf); if(khc_is_user_handle(conf)) { - pk = khc_space_open_key(c, KHM_PERM_WRITE | KHM_FLAG_CREATE); + pk = khcint_space_open_key(c, KHM_PERM_WRITE | KHM_FLAG_CREATE); } else { - pk = khc_space_open_key(c, KHM_PERM_WRITE | KCONF_FLAG_MACHINE | KHM_FLAG_CREATE); + pk = khcint_space_open_key(c, KHM_PERM_WRITE | KCONF_FLAG_MACHINE | KHM_FLAG_CREATE); } hr = RegSetValueEx(pk, value, 0, REG_BINARY, buf, (DWORD) bufsize); @@ -1558,7 +1585,9 @@ KHMEXP khm_int32 KHMAPI khc_write_binary(khm_handle pconf, wchar_t * pvalue, voi return rv; } -KHMEXP khm_int32 KHMAPI khc_get_config_space_name(khm_handle conf, wchar_t * buf, khm_size * bufsize) { +KHMEXP khm_int32 KHMAPI +khc_get_config_space_name(khm_handle conf, + wchar_t * buf, khm_size * bufsize) { kconf_conf_space * c; khm_int32 rv = KHM_ERROR_SUCCESS; @@ -1566,7 +1595,7 @@ KHMEXP khm_int32 KHMAPI khc_get_config_space_name(khm_handle conf, wchar_t * buf return KHM_ERROR_NOT_READY; if(!khc_is_handle(conf)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; c = khc_space_from_handle(conf); @@ -1597,26 +1626,28 @@ KHMEXP khm_int32 KHMAPI khc_get_config_space_name(khm_handle conf, wchar_t * buf return rv; } -KHMEXP khm_int32 KHMAPI khc_get_config_space_parent(khm_handle conf, khm_handle * parent) { +KHMEXP khm_int32 KHMAPI +khc_get_config_space_parent(khm_handle conf, khm_handle * parent) { kconf_conf_space * c; if(!khc_is_config_running()) return KHM_ERROR_NOT_READY; if(!khc_is_handle(conf)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; c = khc_space_from_handle(conf); if(c == conf_root || c->parent == conf_root) *parent = NULL; else - *parent = khc_handle_from_space(c->parent, khc_handle_flags(conf)); + *parent = khcint_handle_from_space(c->parent, khc_handle_flags(conf)); return KHM_ERROR_SUCCESS; } -KHMEXP khm_int32 KHMAPI khc_get_type(khm_handle conf, wchar_t * value) { +KHMEXP khm_int32 KHMAPI +khc_get_type(khm_handle conf, wchar_t * value) { HKEY hkm = NULL; HKEY hku = NULL; kconf_conf_space * c; @@ -1633,8 +1664,8 @@ KHMEXP khm_int32 KHMAPI khc_get_type(khm_handle conf, wchar_t * value) { c = (kconf_conf_space *) conf; if(!khc_is_machine_handle(conf)) - hku = khc_space_open_key(c, KHM_PERM_READ); - hkm = khc_space_open_key(c, KHM_PERM_READ | KCONF_FLAG_MACHINE); + hku = khcint_space_open_key(c, KHM_PERM_READ); + hkm = khcint_space_open_key(c, KHM_PERM_READ | KCONF_FLAG_MACHINE); if(hku) hr = RegQueryValueEx(hku, value, NULL, &type, NULL, NULL); @@ -1673,7 +1704,8 @@ KHMEXP khm_int32 KHMAPI khc_get_type(khm_handle conf, wchar_t * value) { return rv; } -KHMEXP khm_int32 KHMAPI khc_value_exists(khm_handle conf, wchar_t * value) { +KHMEXP khm_int32 KHMAPI +khc_value_exists(khm_handle conf, wchar_t * value) { HKEY hku = NULL; HKEY hkm = NULL; kconf_conf_space * c; @@ -1685,13 +1717,13 @@ KHMEXP khm_int32 KHMAPI khc_value_exists(khm_handle conf, wchar_t * value) { return KHM_ERROR_NOT_READY; if(!khc_is_handle(conf)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; c = khc_space_from_handle(conf); if(!khc_is_machine_handle(conf)) - hku = khc_space_open_key(c, KHM_PERM_READ); - hkm = khc_space_open_key(c, KHM_PERM_READ | KCONF_FLAG_MACHINE); + hku = khcint_space_open_key(c, KHM_PERM_READ); + hkm = khcint_space_open_key(c, KHM_PERM_READ | KCONF_FLAG_MACHINE); if(hku && (RegQueryValueEx(hku, value, NULL, &t, NULL, NULL) == ERROR_SUCCESS)) rv |= KCONF_FLAG_USER; @@ -1710,7 +1742,77 @@ KHMEXP khm_int32 KHMAPI khc_value_exists(khm_handle conf, wchar_t * value) { return rv; } -khm_boolean khc_is_valid_name(wchar_t * name) +KHMEXP khm_int32 KHMAPI +khc_remove_value(khm_handle conf, wchar_t * value, khm_int32 flags) { + HKEY hku = NULL; + HKEY hkm = NULL; + kconf_conf_space * c; + khm_int32 rv = KHM_ERROR_NOT_FOUND; + DWORD t; + LONG l; + + if(!khc_is_config_running()) + return KHM_ERROR_NOT_READY; + + if(!khc_is_handle(conf)) + return KHM_ERROR_INVALID_PARAM; + + c = khc_space_from_handle(conf); + + if(!khc_is_machine_handle(conf)) + hku = khcint_space_open_key(c, KHM_PERM_READ); + hkm = khcint_space_open_key(c, KHM_PERM_READ | KCONF_FLAG_MACHINE); + + if((flags == 0 || + (flags & KCONF_FLAG_USER)) && + hku && (RegQueryValueEx(hku, value, NULL, + &t, NULL, NULL) == ERROR_SUCCESS)) { + l = RegDeleteValue(hku, value); + if (l == ERROR_SUCCESS) + rv = KHM_ERROR_SUCCESS; + else + rv = KHM_ERROR_UNKNOWN; + } + if((flags == 0 || + (flags & KCONF_FLAG_MACHINE)) && + hkm && (RegQueryValueEx(hkm, value, NULL, + &t, NULL, NULL) == ERROR_SUCCESS)) { + l = RegDeleteValue(hkm, value); + if (l == ERROR_SUCCESS) + rv = (rv == KHM_ERROR_UNKNOWN)?KHM_ERROR_PARTIAL: + KHM_ERROR_SUCCESS; + else + rv = (rv == KHM_ERROR_SUCCESS)?KHM_ERROR_PARTIAL: + KHM_ERROR_UNKNOWN; + } + + return rv; +} + +KHMEXP khm_int32 KHMAPI +khc_remove_space(khm_handle conf) { + /* TODO: implement this */ + + /* + - mark this space as well as all child spaces as + 'delete-on-close' using flags. Mark should indicate which + repository to delete the space from. (user/machine) + + - When each subspace is released, check if it has been marked + for deletion. If so, delete the marked spaces as well as + removing the space from kconf space tree. + + - When removing a subspace from a space, check if the parent + space has any children left. If there are none, check if the + parent space is also marked for deletion. + */ + assert(FALSE); + + return 0; +} + +khm_boolean +khcint_is_valid_name(wchar_t * name) { size_t cbsize; if(FAILED(StringCbLength(name, KCONF_MAXCB_NAME, &cbsize))) @@ -1718,9 +1820,10 @@ khm_boolean khc_is_valid_name(wchar_t * name) return TRUE; } -khm_int32 khc_validate_schema(kconf_schema * schema, - int begin, - int *end) +khm_int32 +khcint_validate_schema(kconf_schema * schema, + int begin, + int *end) { int i; int state = 0; @@ -1730,18 +1833,18 @@ khm_int32 khc_validate_schema(kconf_schema * schema, while(!end_found) { switch(state) { case 0: /* initial. this record should start a config space */ - if(!khc_is_valid_name(schema[i].name) || + if(!khcint_is_valid_name(schema[i].name) || schema[i].type != KC_SPACE) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; state = 1; break; case 1: /* we are inside a config space, in the values area */ - if(!khc_is_valid_name(schema[i].name)) - return KHM_ERROR_INVALID_PARM; + if(!khcint_is_valid_name(schema[i].name)) + return KHM_ERROR_INVALID_PARAM; if(schema[i].type == KC_SPACE) { - if(KHM_FAILED(khc_validate_schema(schema, i, &i))) - return KHM_ERROR_INVALID_PARM; + if(KHM_FAILED(khcint_validate_schema(schema, i, &i))) + return KHM_ERROR_INVALID_PARAM; state = 2; } else if(schema[i].type == KC_ENDSPACE) { end_found = 1; @@ -1752,26 +1855,26 @@ khm_int32 khc_validate_schema(kconf_schema * schema, schema[i].type != KC_INT32 && schema[i].type != KC_INT64 && schema[i].type != KC_BINARY) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } break; case 2: /* we are inside a config space, in the subspace area */ if(schema[i].type == KC_SPACE) { - if(KHM_FAILED(khc_validate_schema(schema, i, &i))) - return KHM_ERROR_INVALID_PARM; + if(KHM_FAILED(khcint_validate_schema(schema, i, &i))) + return KHM_ERROR_INVALID_PARAM; } else if(schema[i].type == KC_ENDSPACE) { end_found = 1; if(end) *end = i; } else { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } break; default: /* unreachable */ - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } i++; } @@ -1779,7 +1882,9 @@ khm_int32 khc_validate_schema(kconf_schema * schema, return KHM_ERROR_SUCCESS; } -khm_int32 khc_load_schema_i(khm_handle parent, kconf_schema * schema, int begin, int * end) +khm_int32 +khcint_load_schema_i(khm_handle parent, kconf_schema * schema, + int begin, int * end) { int i; int state = 0; @@ -1791,8 +1896,9 @@ khm_int32 khc_load_schema_i(khm_handle parent, kconf_schema * schema, int begin, while(!end_found) { switch(state) { case 0: /* initial. this record should start a config space */ - if(KHM_FAILED(khc_open_space(parent, schema[i].name, KHM_FLAG_CREATE, &h))) - return KHM_ERROR_INVALID_PARM; + if(KHM_FAILED(khc_open_space(parent, schema[i].name, + KHM_FLAG_CREATE, &h))) + return KHM_ERROR_INVALID_PARAM; thisconf = khc_space_from_handle(h); thisconf->schema = schema + (begin + 1); state = 1; @@ -1801,8 +1907,8 @@ khm_int32 khc_load_schema_i(khm_handle parent, kconf_schema * schema, int begin, case 1: /* we are inside a config space, in the values area */ if(schema[i].type == KC_SPACE) { thisconf->nSchema = i - (begin + 1); - if(KHM_FAILED(khc_load_schema_i(h, schema, i, &i))) - return KHM_ERROR_INVALID_PARM; + if(KHM_FAILED(khcint_load_schema_i(h, schema, i, &i))) + return KHM_ERROR_INVALID_PARAM; state = 2; } else if(schema[i].type == KC_ENDSPACE) { thisconf->nSchema = i - (begin + 1); @@ -1815,21 +1921,21 @@ khm_int32 khc_load_schema_i(khm_handle parent, kconf_schema * schema, int begin, case 2: /* we are inside a config space, in the subspace area */ if(schema[i].type == KC_SPACE) { - if(KHM_FAILED(khc_load_schema_i(h, schema, i, &i))) - return KHM_ERROR_INVALID_PARM; + if(KHM_FAILED(khcint_load_schema_i(h, schema, i, &i))) + return KHM_ERROR_INVALID_PARAM; } else if(schema[i].type == KC_ENDSPACE) { end_found = 1; if(end) *end = i; khc_close_space(h); } else { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } break; default: /* unreachable */ - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } i++; } @@ -1837,7 +1943,8 @@ khm_int32 khc_load_schema_i(khm_handle parent, kconf_schema * schema, int begin, return KHM_ERROR_SUCCESS; } -KHMEXP khm_int32 KHMAPI khc_load_schema(khm_handle conf, kconf_schema * schema) +KHMEXP khm_int32 KHMAPI +khc_load_schema(khm_handle conf, kconf_schema * schema) { khm_int32 rv = KHM_ERROR_SUCCESS; @@ -1845,19 +1952,21 @@ KHMEXP khm_int32 KHMAPI khc_load_schema(khm_handle conf, kconf_schema * schema) return KHM_ERROR_NOT_READY; if(conf && !khc_is_handle(conf)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; - if(KHM_FAILED(khc_validate_schema(schema, 0, NULL))) - return KHM_ERROR_INVALID_PARM; + if(KHM_FAILED(khcint_validate_schema(schema, 0, NULL))) + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_conf_global); - rv = khc_load_schema_i(conf, schema, 0, NULL); + rv = khcint_load_schema_i(conf, schema, 0, NULL); LeaveCriticalSection(&cs_conf_global); return rv; } -khm_int32 khc_unload_schema_i(khm_handle parent, kconf_schema * schema, int begin, int * end) +khm_int32 +khcint_unload_schema_i(khm_handle parent, kconf_schema * schema, + int begin, int * end) { int i; int state = 0; @@ -1870,7 +1979,7 @@ khm_int32 khc_unload_schema_i(khm_handle parent, kconf_schema * schema, int begi switch(state) { case 0: /* initial. this record should start a config space */ if(KHM_FAILED(khc_open_space(parent, schema[i].name, 0, &h))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; thisconf = khc_space_from_handle(h); if(thisconf->schema == (schema + (begin + 1))) { thisconf->schema = NULL; @@ -1881,8 +1990,8 @@ khm_int32 khc_unload_schema_i(khm_handle parent, kconf_schema * schema, int begi case 1: /* we are inside a config space, in the values area */ if(schema[i].type == KC_SPACE) { - if(KHM_FAILED(khc_unload_schema_i(h, schema, i, &i))) - return KHM_ERROR_INVALID_PARM; + if(KHM_FAILED(khcint_unload_schema_i(h, schema, i, &i))) + return KHM_ERROR_INVALID_PARAM; state = 2; } else if(schema[i].type == KC_ENDSPACE) { end_found = 1; @@ -1894,21 +2003,21 @@ khm_int32 khc_unload_schema_i(khm_handle parent, kconf_schema * schema, int begi case 2: /* we are inside a config space, in the subspace area */ if(schema[i].type == KC_SPACE) { - if(KHM_FAILED(khc_unload_schema_i(h, schema, i, &i))) - return KHM_ERROR_INVALID_PARM; + if(KHM_FAILED(khcint_unload_schema_i(h, schema, i, &i))) + return KHM_ERROR_INVALID_PARAM; } else if(schema[i].type == KC_ENDSPACE) { end_found = 1; if(end) *end = i; khc_close_space(h); } else { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } break; default: /* unreachable */ - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } i++; } @@ -1916,7 +2025,8 @@ khm_int32 khc_unload_schema_i(khm_handle parent, kconf_schema * schema, int begi return KHM_ERROR_SUCCESS; } -KHMEXP khm_int32 KHMAPI khc_unload_schema(khm_handle conf, kconf_schema * schema) +KHMEXP khm_int32 KHMAPI +khc_unload_schema(khm_handle conf, kconf_schema * schema) { khm_int32 rv = KHM_ERROR_SUCCESS; @@ -1924,22 +2034,22 @@ KHMEXP khm_int32 KHMAPI khc_unload_schema(khm_handle conf, kconf_schema * schema return KHM_ERROR_NOT_READY; if(conf && !khc_is_handle(conf)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; - if(KHM_FAILED(khc_validate_schema(schema, 0, NULL))) - return KHM_ERROR_INVALID_PARM; + if(KHM_FAILED(khcint_validate_schema(schema, 0, NULL))) + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_conf_global); - rv = khc_unload_schema_i(conf, schema, 0, NULL); + rv = khcint_unload_schema_i(conf, schema, 0, NULL); LeaveCriticalSection(&cs_conf_global); return rv; } -KHMEXP khm_int32 KHMAPI khc_enum_subspaces( - khm_handle conf, - khm_handle prev, - khm_handle * next) +KHMEXP khm_int32 KHMAPI +khc_enum_subspaces(khm_handle conf, + khm_handle prev, + khm_handle * next) { kconf_conf_space * s; kconf_conf_space * c; @@ -1951,7 +2061,7 @@ KHMEXP khm_int32 KHMAPI khc_enum_subspaces( if(!khc_is_handle(conf) || next == NULL || (prev != NULL && !khc_is_handle(prev))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; s = khc_space_from_handle(conf); @@ -1965,7 +2075,7 @@ KHMEXP khm_int32 KHMAPI khc_enum_subspaces( { HKEY hk_conf; - hk_conf = khc_space_open_key(s, 0); + hk_conf = khcint_space_open_key(s, 0); if(hk_conf) { wchar_t name[KCONF_MAXCCH_NAME]; khm_handle h; @@ -1989,7 +2099,7 @@ KHMEXP khm_int32 KHMAPI khc_enum_subspaces( { HKEY hk_conf; - hk_conf = khc_space_open_key(s, KCONF_FLAG_MACHINE); + hk_conf = khcint_space_open_key(s, KCONF_FLAG_MACHINE); if(hk_conf) { wchar_t name[KCONF_MAXCCH_NAME]; khm_handle h; @@ -2033,7 +2143,7 @@ KHMEXP khm_int32 KHMAPI khc_enum_subspaces( khc_close_space(prev); if(c) { - *next = khc_handle_from_space(c, khc_handle_flags(conf)); + *next = khcint_handle_from_space(c, khc_handle_flags(conf)); rv = KHM_ERROR_SUCCESS; } else { *next = NULL; @@ -2043,31 +2153,42 @@ KHMEXP khm_int32 KHMAPI khc_enum_subspaces( return rv; } -KHMEXP khm_int32 KHMAPI khc_write_multi_string(khm_handle conf, wchar_t * value, wchar_t * buf) +KHMEXP khm_int32 KHMAPI +khc_write_multi_string(khm_handle conf, wchar_t * value, wchar_t * buf) { size_t cb; + wchar_t vbuf[KCONF_MAXCCH_STRING]; wchar_t *tb; khm_int32 rv; if(!khc_is_config_running()) return KHM_ERROR_NOT_READY; if(!khc_is_handle(conf) || buf == NULL || value == NULL) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(multi_string_to_csv(NULL, &cb, buf) != KHM_ERROR_TOO_LONG) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; + + if (cb < sizeof(vbuf)) + tb = vbuf; + else + tb = PMALLOC(cb); + + assert(tb != NULL); - tb = malloc(cb); - assert(tb != NULL); multi_string_to_csv(tb, &cb, buf); rv = khc_write_string(conf, value, tb); - free(tb); + if (tb != vbuf) + PFREE(tb); return rv; } -KHMEXP khm_int32 KHMAPI khc_read_multi_string(khm_handle conf, wchar_t * value, wchar_t * buf, khm_size * bufsize) +KHMEXP khm_int32 KHMAPI +khc_read_multi_string(khm_handle conf, wchar_t * value, + wchar_t * buf, khm_size * bufsize) { + wchar_t vbuf[KCONF_MAXCCH_STRING]; wchar_t * tb; khm_size cbbuf; khm_int32 rv = KHM_ERROR_SUCCESS; @@ -2076,14 +2197,19 @@ KHMEXP khm_int32 KHMAPI khc_read_multi_string(khm_handle conf, wchar_t * value, return KHM_ERROR_NOT_READY; if(!bufsize) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; rv = khc_read_string(conf, value, NULL, &cbbuf); if(rv != KHM_ERROR_TOO_LONG) return rv; - tb = malloc(cbbuf); - assert(tb != NULL); + if (cbbuf < sizeof(vbuf)) + tb = vbuf; + else + tb = PMALLOC(cbbuf); + + assert(tb != NULL); + rv = khc_read_string(conf, value, tb, &cbbuf); if(KHM_FAILED(rv)) @@ -2092,7 +2218,8 @@ KHMEXP khm_int32 KHMAPI khc_read_multi_string(khm_handle conf, wchar_t * value, rv = csv_to_multi_string(buf, bufsize, tb); _exit: - free(tb); + if (tb != vbuf) + PFREE(tb); return rv; } diff --git a/src/windows/identity/kconfig/kconfig.h b/src/windows/identity/kconfig/kconfig.h index 22d923bd6..d2226be20 100644 --- a/src/windows/identity/kconfig/kconfig.h +++ b/src/windows/identity/kconfig/kconfig.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -228,7 +228,9 @@ typedef struct kconf_schema_t { and settings \a flags to the required flags. */ -KHMEXP khm_int32 KHMAPI khc_open_space(khm_handle parent, wchar_t * cspace, khm_int32 flags, khm_handle * result); +KHMEXP khm_int32 KHMAPI +khc_open_space(khm_handle parent, wchar_t * cspace, khm_int32 flags, + khm_handle * result); /*! \brief Set the shadow space for a configuration handle @@ -250,11 +252,13 @@ KHMEXP khm_int32 KHMAPI khc_open_space(khm_handle parent, wchar_t * cspace, khm_ Specify NULL for \a lower to remove any prior shadow. */ -KHMEXP khm_int32 KHMAPI khc_shadow_space(khm_handle upper, khm_handle lower); +KHMEXP khm_int32 KHMAPI +khc_shadow_space(khm_handle upper, khm_handle lower); /*! \brief Close a handle opened with khc_open_space() */ -KHMEXP khm_int32 KHMAPI khc_close_space(khm_handle conf); +KHMEXP khm_int32 KHMAPI +khc_close_space(khm_handle conf); /*! \brief Read a string value from a configuration space @@ -295,18 +299,18 @@ KHMEXP khm_int32 KHMAPI khc_close_space(khm_handle conf); the required buffer if \a buf is NULL or insufficient. \retval KHM_ERROR_NOT_READY The configuration provider has not started - \retval KHM_ERROR_INVALID_PARM One or more of the supplied parameters are not valid + \retval KHM_ERROR_INVALID_PARAM One or more of the supplied parameters are not valid \retval KHM_ERROR_TYPE_MISMATCH The specified value is not a string \retval KHM_ERROR_TOO_LONG \a buf was NULL or the size of the buffer was insufficient. The required size is in bufsize. \retval KHM_ERROR_SUCCESS Success. The number of bytes copied is in bufsize. \see khc_open_space() */ -KHMEXP khm_int32 KHMAPI khc_read_string( - khm_handle conf, - wchar_t * value, - wchar_t * buf, - khm_size * bufsize); +KHMEXP khm_int32 KHMAPI +khc_read_string(khm_handle conf, + wchar_t * value, + wchar_t * buf, + khm_size * bufsize); /*! \brief Read a multi-string value from a configuration space @@ -355,18 +359,18 @@ KHMEXP khm_int32 KHMAPI khc_read_string( the required buffer if \a buf is NULL or insufficient. \retval KHM_ERROR_NOT_READY The configuration provider has not started - \retval KHM_ERROR_INVALID_PARM One or more of the supplied parameters are not valid + \retval KHM_ERROR_INVALID_PARAM One or more of the supplied parameters are not valid \retval KHM_ERROR_TYPE_MISMATCH The specified value is not a string \retval KHM_ERROR_TOO_LONG \a buf was NULL or the size of the buffer was insufficient. The required size is in bufsize. \retval KHM_ERROR_SUCCESS Success. The number of bytes copied is in bufsize. \see khc_open_space() */ -KHMEXP khm_int32 KHMAPI khc_read_multi_string( - khm_handle conf, - wchar_t * value, - wchar_t * buf, - khm_size * bufsize); +KHMEXP khm_int32 KHMAPI +khc_read_multi_string(khm_handle conf, + wchar_t * value, + wchar_t * buf, + khm_size * bufsize); /*! \brief Read a 32 bit integer value from a configuration space @@ -405,14 +409,14 @@ KHMEXP khm_int32 KHMAPI khc_read_multi_string( \retval KHM_ERROR_NOT_READY The configuration provider has not started. \retval KHM_ERROR_SUCCESS Success. The value that was read was placed in \a buf \retval KHM_ERROR_NOT_FOUND The specified value was not found - \retval KHM_ERROR_INVALID_PARM One or more parameters were invalid + \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid \retval KHM_ERROR_TYPE_MISMATCH The specified value was found but was not of the correct type. \see khc_open_space() */ -KHMEXP khm_int32 KHMAPI khc_read_int32( - khm_handle conf, - wchar_t * value, - khm_int32 * buf); +KHMEXP khm_int32 KHMAPI +khc_read_int32(khm_handle conf, + wchar_t * value, + khm_int32 * buf); /*! \brief Read a 64 bit integer value from a configuration space @@ -451,15 +455,15 @@ KHMEXP khm_int32 KHMAPI khc_read_int32( \retval KHM_ERROR_NOT_READY The configuration provider has not started \retval KHM_ERROR_SUCCESS Success. The value that was read was placed in \a buf \retval KHM_ERROR_NOT_FOUND The specified value was not found - \retval KHM_ERROR_INVALID_PARM One or more parameters were invalid + \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid \retval KHM_ERROR_TYPE_MISMATCH The specified value was found but was not the correct data type. \see khc_open_space() */ -KHMEXP khm_int32 KHMAPI khc_read_int64( - khm_handle conf, - wchar_t * value, - khm_int64 * buf); +KHMEXP khm_int32 KHMAPI +khc_read_int64(khm_handle conf, + wchar_t * value, + khm_int64 * buf); /*! \brief Read a binary value from a configuration space @@ -499,15 +503,15 @@ KHMEXP khm_int32 KHMAPI khc_read_int64( \retval KHM_ERROR_SUCCESS Success. The data was copied to \a buf. The number of bytes copied is stored in \a bufsize \retval KHM_ERROR_NOT_FOUND The specified value was not found - \retval KHM_ERROR_INVALID_PARM One or more parameters were invalid. + \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid. \see khc_open_space() */ -KHMEXP khm_int32 KHMAPI khc_read_binary( - khm_handle conf, - wchar_t * value, - void * buf, - khm_size * bufsize); +KHMEXP khm_int32 KHMAPI +khc_read_binary(khm_handle conf, + wchar_t * value, + void * buf, + khm_size * bufsize); /*! \brief Write a string value to a configuration space @@ -543,10 +547,10 @@ KHMEXP khm_int32 KHMAPI khc_read_binary( \see khc_open_space() */ -KHMEXP khm_int32 KHMAPI khc_write_string( - khm_handle conf, - wchar_t * value, - wchar_t * buf); +KHMEXP khm_int32 KHMAPI +khc_write_string(khm_handle conf, + wchar_t * value, + wchar_t * buf); /*! \brief Write a multi-string value to a configuration space @@ -584,10 +588,10 @@ KHMEXP khm_int32 KHMAPI khc_write_string( \see khc_open_space() */ -KHMEXP khm_int32 KHMAPI khc_write_multi_string( - khm_handle conf, - wchar_t * value, - wchar_t * buf); +KHMEXP khm_int32 KHMAPI +khc_write_multi_string(khm_handle conf, + wchar_t * value, + wchar_t * buf); /*! \brief Write a 32 bit integer value to a configuration space @@ -619,10 +623,10 @@ KHMEXP khm_int32 KHMAPI khc_write_multi_string( \see khc_open_space() */ -KHMEXP khm_int32 KHMAPI khc_write_int32( - khm_handle conf, - wchar_t * value, - khm_int32 buf); +KHMEXP khm_int32 KHMAPI +khc_write_int32(khm_handle conf, + wchar_t * value, + khm_int32 buf); /*! \brief Write a 64 bit integer value to a configuration space @@ -654,10 +658,10 @@ KHMEXP khm_int32 KHMAPI khc_write_int32( \see khc_open_space() */ -KHMEXP khm_int32 KHMAPI khc_write_int64( - khm_handle conf, - wchar_t * value, - khm_int64 buf); +KHMEXP khm_int32 KHMAPI +khc_write_int64(khm_handle conf, + wchar_t * value, + khm_int64 buf); /*! \brief Write a binary value to a configuration space @@ -689,18 +693,19 @@ KHMEXP khm_int32 KHMAPI khc_write_int64( \see khc_open_space() */ -KHMEXP khm_int32 KHMAPI khc_write_binary( - khm_handle conf, - wchar_t * value, - void * buf, - khm_size bufsize); +KHMEXP khm_int32 KHMAPI +khc_write_binary(khm_handle conf, + wchar_t * value, + void * buf, + khm_size bufsize); /*! \brief Get the type of a value in a configuration space \return The return value is the type of the specified value, or KC_NONE if the value does not exist. */ -KHMEXP khm_int32 KHMAPI khc_get_type(khm_handle conf, wchar_t * value); +KHMEXP khm_int32 KHMAPI +khc_get_type(khm_handle conf, wchar_t * value); /*! \brief Check which configuration stores contain a specific value. @@ -716,7 +721,49 @@ KHMEXP khm_int32 KHMAPI khc_get_type(khm_handle conf, wchar_t * value); and ::KCONF_FLAG_SCHEMA indicating which stores contain the value. */ -KHMEXP khm_int32 KHMAPI khc_value_exists(khm_handle conf, wchar_t * value); +KHMEXP khm_int32 KHMAPI +khc_value_exists(khm_handle conf, wchar_t * value); + +/*! \brief Remove a value from a configuration space + + Removes a value from one or more configuration stores. + + A value can exist in multiple configuration stores. Only the + values that are stored in writable stores can be removed. When + the function searches for values to remove, it will only look in + configuration stores that are specified in the handle. In + addition, the configuration stores affected can be further + narrowed by specifying them in the \a flags parameter. If \a + flags is zero, then all the stores visible to the handle are + searched. If \a flags specifies ::KCONF_FLAG_USER or + ::KCONF_FLAG_MACHINE or both, then only the specified stores are + searched, provided that the stores are visible to the handle. + + This function only operates on the topmost configuration space + visible to the handle. If the configuration handle is shadowed, + the shadowed configuration spaces are unaffected by the removal. + + \param[in] conf Handle to configuration space to remove value from + + \param[in] value Value to remove + + \param[in] flags Specifies which configuration stores will be + affected by the removal. See above. + + \retval KHM_ERROR_SUCCESS The value was removed from all the + specified configuration stores. + + \retval KHM_ERROR_NOT_FOUND The value was not found. + + \retval KHM_ERROR_UNKNOWN An unknown error occurred while trying + to remove the value. + + \retval KHM_ERROR_PARTIAL The value was successfully removed from + one or more stores, but the operation failed on one or more + other stores. + */ +KHMEXP khm_int32 KHMAPI +khc_remove_value(khm_handle conf, wchar_t * value, khm_int32 flags); /*! \brief Get the name of a configuration space @@ -729,10 +776,10 @@ KHMEXP khm_int32 KHMAPI khc_value_exists(khm_handle conf, wchar_t * value); pointed to by \a buf. On exit, holds the number of bytes copied into the buffer including the NULL terminator. */ -KHMEXP khm_int32 KHMAPI khc_get_config_space_name( - khm_handle conf, - wchar_t * buf, - khm_size * bufsize); +KHMEXP khm_int32 KHMAPI +khc_get_config_space_name(khm_handle conf, + wchar_t * buf, + khm_size * bufsize); /*! \brief Get a handle to the parent space @@ -742,9 +789,9 @@ KHMEXP khm_int32 KHMAPI khc_get_config_space_name( call succeeds. Receives NULL otherwise. The returned handle must be closed using khc_close_space() */ -KHMEXP khm_int32 KHMAPI khc_get_config_space_parent( - khm_handle conf, - khm_handle * parent); +KHMEXP khm_int32 KHMAPI +khc_get_config_space_parent(khm_handle conf, + khm_handle * parent); /*! \brief Load a configuration schema into the specified configuration space @@ -756,15 +803,15 @@ KHMEXP khm_int32 KHMAPI khc_get_config_space_parent( \see khc_unload_schema() */ -KHMEXP khm_int32 KHMAPI khc_load_schema( - khm_handle conf, - kconf_schema * schema); +KHMEXP khm_int32 KHMAPI +khc_load_schema(khm_handle conf, + kconf_schema * schema); /*! \brief Unload a schema from a configuration space */ -KHMEXP khm_int32 KHMAPI khc_unload_schema( - khm_handle conf, - kconf_schema * schema); +KHMEXP khm_int32 KHMAPI +khc_unload_schema(khm_handle conf, + kconf_schema * schema); /*! \brief Enumerate the subspaces of a configuration space @@ -788,7 +835,7 @@ KHMEXP khm_int32 KHMAPI khc_unload_schema( \retval KHM_ERROR_SUCCESS The call succeeded. There is a valid handle to a configuration space in \a first_subspace. - \retval KHM_ERROR_INVALID_PARM Either \a conf or \a prev was not a + \retval KHM_ERROR_INVALID_PARAM Either \a conf or \a prev was not a valid configuration space handle or \a first_subspace is NULL. Note that \a prev can be NULL. @@ -813,10 +860,10 @@ KHMEXP khm_int32 KHMAPI khc_unload_schema( However, the returned handle has the same domain restrictions as \a conf. */ -KHMEXP khm_int32 KHMAPI khc_enum_subspaces( - khm_handle conf, - khm_handle prev, - khm_handle * next); +KHMEXP khm_int32 KHMAPI +khc_enum_subspaces(khm_handle conf, + khm_handle prev, + khm_handle * next); /*@}*/ diff --git a/src/windows/identity/kconfig/kconfiginternal.h b/src/windows/identity/kconfig/kconfiginternal.h index 1b4b70170..6d5a63cbf 100644 --- a/src/windows/identity/kconfig/kconfiginternal.h +++ b/src/windows/identity/kconfig/kconfiginternal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -62,7 +62,8 @@ typedef struct kconf_conf_space_t { TDCL(struct kconf_conf_space_t); } kconf_conf_space; -#define KCONF_SPACE_FLAG_SCHEMA 32 +//#define KCONF_SPACE_FLAG_SCHEMA 0x00000020 +#define KCONF_SPACE_FLAG_DELETED 0x00000040 typedef struct kconf_conf_handle_t { khm_int32 magic; @@ -100,15 +101,25 @@ void exit_kconf(void); #define khc_is_machine_handle(h) (((kconf_handle *) h)->flags & KCONF_FLAG_MACHINE) #define khc_handle_flags(h) (((kconf_handle *) h)->flags) -kconf_handle * khc_handle_from_space(kconf_conf_space * s, khm_int32 flags); -void khc_handle_free(kconf_handle * h); +kconf_handle * +khcint_handle_from_space(kconf_conf_space * s, khm_int32 flags); -kconf_conf_space * khc_create_empty_space(void); -void khc_free_space(kconf_conf_space * r); +void +khcint_handle_free(kconf_handle * h); -void khc_space_hold(kconf_conf_space * s); -void khc_space_release(kconf_conf_space * s); +kconf_conf_space * +khcint_create_empty_space(void); -HKEY khc_space_open_key(kconf_conf_space * s, khm_int32 flags); +void +khcint_free_space(kconf_conf_space * r); + +void +khcint_space_hold(kconf_conf_space * s); + +void +khcint_space_release(kconf_conf_space * s); + +HKEY +khcint_space_open_key(kconf_conf_space * s, khm_int32 flags); #endif diff --git a/src/windows/identity/kconfig/kconfigmain.c b/src/windows/identity/kconfig/kconfigmain.c index 8a9d6578c..c49364ab2 100644 --- a/src/windows/identity/kconfig/kconfigmain.c +++ b/src/windows/identity/kconfig/kconfigmain.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/kconfig/registry.c b/src/windows/identity/kconfig/registry.c index 4a7b46682..03b49b2c0 100644 --- a/src/windows/identity/kconfig/registry.c +++ b/src/windows/identity/kconfig/registry.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/kcreddb/attrib.c b/src/windows/identity/kcreddb/attrib.c index e43540dc5..badfb2b49 100644 --- a/src/windows/identity/kcreddb/attrib.c +++ b/src/windows/identity/kcreddb/attrib.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -33,27 +33,31 @@ kcdb_attrib_i ** kcdb_attrib_tbl = NULL; kcdb_attrib_i ** kcdb_property_tbl = NULL; kcdb_attrib_i * kcdb_attribs = NULL; -void kcdb_attrib_add_ref_func(const void * key, void * va) +void +kcdb_attrib_add_ref_func(const void * key, void * va) { kcdb_attrib_hold((kcdb_attrib_i *) va); } -void kcdb_attrib_del_ref_func(const void * key, void * va) +void +kcdb_attrib_del_ref_func(const void * key, void * va) { kcdb_attrib_release((kcdb_attrib_i *) va); } -void kcdb_attrib_msg_completion(kmq_message * m) +void +kcdb_attrib_msg_completion(kmq_message * m) { if(m && m->vparam) { kcdb_attrib_release((kcdb_attrib_i *) m->vparam); } } -khm_int32 kcdb_attrib_hold(kcdb_attrib_i * ai) +khm_int32 +kcdb_attrib_hold(kcdb_attrib_i * ai) { if(!ai) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_attrib); ai->refcount++; @@ -61,10 +65,11 @@ khm_int32 kcdb_attrib_hold(kcdb_attrib_i * ai) return KHM_ERROR_SUCCESS; } -khm_int32 kcdb_attrib_release(kcdb_attrib_i * ai) +khm_int32 +kcdb_attrib_release(kcdb_attrib_i * ai) { if(!ai) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_attrib); ai->refcount--; @@ -72,16 +77,18 @@ khm_int32 kcdb_attrib_release(kcdb_attrib_i * ai) return KHM_ERROR_SUCCESS; } -void kcdb_attrib_post_message(khm_int32 op, kcdb_attrib_i * ai) +void +kcdb_attrib_post_message(khm_int32 op, kcdb_attrib_i * ai) { kcdb_attrib_hold(ai); kmq_post_message(KMSG_KCDB, KMSG_KCDB_ATTRIB, op, (void *) ai); } -khm_int32 KHMAPI kcdb_attr_sys_cb(khm_handle vcred, - khm_int32 attr, - void * buf, - khm_size * pcb_buf) +khm_int32 KHMAPI +kcdb_attr_sys_cb(khm_handle vcred, + khm_int32 attr, + void * buf, + khm_size * pcb_buf) { kcdb_cred * c; @@ -192,27 +199,28 @@ khm_int32 KHMAPI kcdb_attr_sys_cb(khm_handle vcred, } } -void kcdb_attrib_init(void) +void +kcdb_attrib_init(void) { kcdb_attrib attrib; wchar_t sbuf[256]; InitializeCriticalSection(&cs_attrib); - kcdb_attrib_namemap = hash_new_hashtable( - KCDB_ATTRIB_HASH_SIZE, - hash_string, - hash_string_comp, - kcdb_attrib_add_ref_func, - kcdb_attrib_del_ref_func); + kcdb_attrib_namemap = + hash_new_hashtable(KCDB_ATTRIB_HASH_SIZE, + hash_string, + hash_string_comp, + kcdb_attrib_add_ref_func, + kcdb_attrib_del_ref_func); kcdb_attrib_tbl = - malloc(sizeof(kcdb_attrib_i *) * (KCDB_ATTR_MAX_ID + 1)); + PMALLOC(sizeof(kcdb_attrib_i *) * (KCDB_ATTR_MAX_ID + 1)); assert(kcdb_attrib_tbl != NULL); ZeroMemory(kcdb_attrib_tbl, sizeof(kcdb_attrib_i *) * (KCDB_ATTR_MAX_ID + 1)); kcdb_property_tbl = - malloc(sizeof(kcdb_attrib_i *) * KCDB_ATTR_MAX_PROPS); + PMALLOC(sizeof(kcdb_attrib_i *) * KCDB_ATTR_MAX_PROPS); assert(kcdb_property_tbl != NULL); ZeroMemory(kcdb_property_tbl, sizeof(kcdb_attrib_i *) * KCDB_ATTR_MAX_PROPS); @@ -468,23 +476,25 @@ void kcdb_attrib_init(void) kcdb_attrib_register(&attrib, NULL); } -void kcdb_attrib_exit(void) +void +kcdb_attrib_exit(void) { DeleteCriticalSection(&cs_attrib); if(kcdb_attrib_tbl) - free(kcdb_attrib_tbl); + PFREE(kcdb_attrib_tbl); if(kcdb_property_tbl) - free(kcdb_property_tbl); + PFREE(kcdb_property_tbl); } -KHMEXP khm_int32 KHMAPI kcdb_attrib_get_id(wchar_t *name, khm_int32 * id) +KHMEXP khm_int32 KHMAPI +kcdb_attrib_get_id(wchar_t *name, khm_int32 * id) { kcdb_attrib_i * ai; if(!name) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_attrib); ai = hash_lookup(kcdb_attrib_namemap, (void *) name); @@ -499,7 +509,8 @@ KHMEXP khm_int32 KHMAPI kcdb_attrib_get_id(wchar_t *name, khm_int32 * id) } } -KHMEXP khm_int32 KHMAPI kcdb_attrib_register(kcdb_attrib * attrib, khm_int32 * new_id) +KHMEXP khm_int32 KHMAPI +kcdb_attrib_register(kcdb_attrib * attrib, khm_int32 * new_id) { kcdb_attrib_i * ai; size_t cb_name; @@ -511,7 +522,7 @@ KHMEXP khm_int32 KHMAPI kcdb_attrib_register(kcdb_attrib * attrib, khm_int32 * n if(!attrib || KHM_FAILED(kcdb_type_get_info(attrib->type, NULL)) || !attrib->name) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(FAILED(StringCbLength(attrib->name, KCDB_MAXCB_NAME, &cb_name))) return KHM_ERROR_TOO_LONG; @@ -535,50 +546,51 @@ KHMEXP khm_int32 KHMAPI kcdb_attrib_register(kcdb_attrib * attrib, khm_int32 * n (!attrib->compute_cb || attrib->compute_min_cbsize <= 0 || attrib->compute_max_cbsize < attrib->compute_min_cbsize)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if ((attrib->flags & KCDB_ATTR_FLAG_ALTVIEW) && KHM_FAILED(kcdb_attrib_get_info(attrib->alt_id, NULL))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; prop = !!(attrib->flags & KCDB_ATTR_FLAG_PROPERTY); EnterCriticalSection(&cs_attrib); - if( - !prop && - (attrib->id < 0 || attrib->id > KCDB_ATTR_MAX_ID)) + if(!prop && + (attrib->id < 0 || attrib->id > KCDB_ATTR_MAX_ID)) { if(KHM_FAILED(kcdb_attrib_next_free_id(&attr_id))) { LeaveCriticalSection(&cs_attrib); return KHM_ERROR_NO_RESOURCES; } - } else if ( - prop && - (attrib->id < KCDB_ATTR_MIN_PROP_ID || attrib->id > KCDB_ATTR_MAX_PROP_ID)) - { + } else if (prop && + (attrib->id < KCDB_ATTR_MIN_PROP_ID || + attrib->id > KCDB_ATTR_MAX_PROP_ID)) { + if(KHM_FAILED(kcdb_attrib_next_free_prop_id(&attr_id))) { LeaveCriticalSection(&cs_attrib); return KHM_ERROR_NO_RESOURCES; } + } else { attr_id = attrib->id; } #ifdef DEBUG assert(!prop || (attr_id >= KCDB_ATTR_MIN_PROP_ID && attr_id <= KCDB_ATTR_MAX_PROP_ID)); - assert(prop || (attr_id >= 0 && attr_id <= KCDB_ATTR_MAX_ID)); + assert(prop || (attr_id >= 0 && attr_id <= KCDB_ATTR_MAX_ID)); #endif if((!prop && kcdb_attrib_tbl[attr_id]) || - (prop && kcdb_property_tbl[attr_id - KCDB_ATTR_MIN_PROP_ID])) - { + (prop && kcdb_property_tbl[attr_id - KCDB_ATTR_MIN_PROP_ID])) { + LeaveCriticalSection(&cs_attrib); return KHM_ERROR_DUPLICATE; + } - ai = malloc(sizeof(kcdb_attrib_i)); + ai = PMALLOC(sizeof(kcdb_attrib_i)); ZeroMemory(ai, sizeof(kcdb_attrib_i)); ai->attr.type = attrib->type; @@ -588,14 +600,14 @@ KHMEXP khm_int32 KHMAPI kcdb_attrib_register(kcdb_attrib * attrib, khm_int32 * n ai->attr.compute_cb = attrib->compute_cb; ai->attr.compute_max_cbsize = attrib->compute_max_cbsize; ai->attr.compute_min_cbsize = attrib->compute_min_cbsize; - ai->attr.name = malloc(cb_name); + ai->attr.name = PMALLOC(cb_name); StringCbCopy(ai->attr.name, cb_name, attrib->name); if(cb_short_desc) { - ai->attr.short_desc = malloc(cb_short_desc); + ai->attr.short_desc = PMALLOC(cb_short_desc); StringCbCopy(ai->attr.short_desc, cb_short_desc, attrib->short_desc); } if(cb_long_desc) { - ai->attr.long_desc = malloc(cb_long_desc); + ai->attr.long_desc = PMALLOC(cb_long_desc); StringCbCopy(ai->attr.long_desc, cb_long_desc, attrib->long_desc); } @@ -632,7 +644,7 @@ KHMEXP khm_int32 KHMAPI kcdb_attrib_get_info( else if(id >= KCDB_ATTR_MIN_PROP_ID && id <= KCDB_ATTR_MAX_PROP_ID) prop = TRUE; else - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_attrib); if(prop) @@ -679,7 +691,7 @@ KHMEXP khm_int32 KHMAPI kcdb_attrib_describe( khm_boolean prop; if(!cbsize) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(id >= 0 && id <= KCDB_ATTR_MAX_ID) prop = FALSE; @@ -734,7 +746,7 @@ khm_int32 kcdb_attrib_next_free_prop_id(khm_int32 * id) int i; if(!id) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_attrib); for(i=0;i < KCDB_ATTR_MAX_PROPS; i++) { @@ -757,7 +769,7 @@ khm_int32 kcdb_attrib_next_free_id(khm_int32 * id) int i; if(!id) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_attrib); for(i=0;i<= KCDB_ATTR_MAX_ID; i++) { @@ -785,7 +797,7 @@ KHMEXP khm_int32 KHMAPI kcdb_attrib_get_count( int i; if(pcount == NULL) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; eq_flags &= and_flags; @@ -819,7 +831,7 @@ KHMEXP khm_int32 KHMAPI kcdb_attrib_get_ids( int i; if(plist == NULL || pcsize == NULL) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; eq_flags &= and_flags; diff --git a/src/windows/identity/kcreddb/attrib.h b/src/windows/identity/kcreddb/attrib.h index 5199aec92..f5647d67a 100644 --- a/src/windows/identity/kcreddb/attrib.h +++ b/src/windows/identity/kcreddb/attrib.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -52,4 +52,4 @@ khm_int32 kcdb_attrib_release(kcdb_attrib_i * ai); void kcdb_attrib_post_message(khm_int32 op, kcdb_attrib_i * ai); khm_int32 KHMAPI kcdb_attr_sys_cb(khm_handle cred, khm_int32 attr, void * buf, khm_size * pcb_buf); -#endif \ No newline at end of file +#endif diff --git a/src/windows/identity/kcreddb/buf.c b/src/windows/identity/kcreddb/buf.c index 0f50be25d..1811bc126 100644 --- a/src/windows/identity/kcreddb/buf.c +++ b/src/windows/identity/kcreddb/buf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -29,7 +29,7 @@ void kcdb_buf_new(kcdb_buf * buf, khm_size n_fields) { - buf->buffer = malloc(KCDB_BUF_CBBUF_INITIAL); + buf->buffer = PMALLOC(KCDB_BUF_CBBUF_INITIAL); buf->cb_buffer = KCDB_BUF_CBBUF_INITIAL; buf->cb_used = 0; @@ -40,7 +40,7 @@ void kcdb_buf_new(kcdb_buf * buf, khm_size n_fields) buf->n_fields = n_fields; buf->nc_fields = UBOUNDSS(n_fields, KCDB_BUF_FIELDS_INITIAL, KCDB_BUF_FIELDS_GROWTH); - buf->fields = malloc(sizeof(buf->fields[0]) * buf->n_fields); + buf->fields = PMALLOC(sizeof(buf->fields[0]) * buf->n_fields); ZeroMemory(buf->fields, sizeof(buf->fields[0]) * buf->n_fields); } @@ -49,13 +49,13 @@ void kcdb_buf_delete(kcdb_buf * buf) buf->cb_buffer = 0; buf->cb_used = 0; if(buf->buffer) - free(buf->buffer); + PFREE(buf->buffer); buf->buffer = NULL; buf->n_fields = 0; buf->nc_fields = 0; if(buf->fields) - free(buf->fields); + PFREE(buf->fields); buf->fields = NULL; } @@ -73,11 +73,11 @@ static void kcdb_buf_assert_size(kcdb_buf * buf, khm_size cbsize) assert(new_size > buf->cb_buffer && new_size > 0); - new_buf = malloc(new_size); + new_buf = PMALLOC(new_size); assert(new_buf != NULL); memcpy(new_buf, buf->buffer, buf->cb_used); - free(buf->buffer); + PFREE(buf->buffer); buf->buffer = new_buf; } @@ -106,13 +106,13 @@ void kcdb_buf_alloc(kcdb_buf * buf, khm_size slot, khm_ui_2 id, khm_size cbsize) ns = UBOUNDSS((slot + 1), KCDB_BUF_FIELDS_INITIAL, KCDB_BUF_FIELDS_GROWTH); - nf = malloc(sizeof(buf->fields[0]) * ns); + nf = PMALLOC(sizeof(buf->fields[0]) * ns); memcpy(nf, buf->fields, sizeof(buf->fields[0]) * buf->n_fields); if(ns > buf->n_fields) memset(&(nf[buf->n_fields]), 0, sizeof(buf->fields[0]) * (ns - buf->n_fields)); - free(buf->fields); + PFREE(buf->fields); buf->fields = nf; buf->nc_fields = ns; } @@ -191,13 +191,13 @@ void kcdb_buf_dup(kcdb_buf * dest, const kcdb_buf * src) dest->cb_buffer = cb_buf; dest->cb_used = src->cb_used; - dest->buffer = malloc(cb_buf); + dest->buffer = PMALLOC(cb_buf); memcpy(dest->buffer, src->buffer, src->cb_used); nc_fields = UBOUNDSS(src->n_fields, KCDB_BUF_FIELDS_INITIAL, KCDB_BUF_FIELDS_GROWTH); dest->nc_fields = nc_fields; dest->n_fields = src->n_fields; - dest->fields = malloc(nc_fields * sizeof(dest->fields[0])); + dest->fields = PMALLOC(nc_fields * sizeof(dest->fields[0])); memcpy(dest->fields, src->fields, src->n_fields * sizeof(dest->fields[0])); if(dest->n_fields < dest->nc_fields) memset(&(dest->fields[dest->n_fields]), 0, (src->nc_fields - src->n_fields) * sizeof(dest->fields[0])); @@ -293,7 +293,7 @@ KHMEXP khm_int32 KHMAPI kcdb_buf_get_attr( else if(kcdb_is_active_identity(record)) return kcdb_identity_get_attr(record, attr_id, attr_type, buffer, pcb_buf); else - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } KHMEXP khm_int32 KHMAPI kcdb_buf_get_attrib( @@ -308,7 +308,7 @@ KHMEXP khm_int32 KHMAPI kcdb_buf_get_attrib( else if(kcdb_is_active_identity(record)) return kcdb_identity_get_attrib(record, attr_name, attr_type, buffer, pcb_buf); else - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } KHMEXP khm_int32 KHMAPI kcdb_buf_get_attr_string( @@ -323,7 +323,7 @@ KHMEXP khm_int32 KHMAPI kcdb_buf_get_attr_string( else if(kcdb_is_active_identity(record)) return kcdb_identity_get_attr_string(record, attr_id, buffer, pcbbuf, flags); else - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } KHMEXP khm_int32 KHMAPI kcdb_buf_get_attrib_string( @@ -338,7 +338,7 @@ KHMEXP khm_int32 KHMAPI kcdb_buf_get_attrib_string( else if(kcdb_is_active_identity(record)) return kcdb_identity_get_attrib_string(record, attr_name, buffer, pcbbuf, flags); else - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } KHMEXP khm_int32 KHMAPI kcdb_buf_set_attr( @@ -352,7 +352,7 @@ KHMEXP khm_int32 KHMAPI kcdb_buf_set_attr( else if(kcdb_is_active_identity(record)) return kcdb_identity_set_attr(record, attr_id, buffer, cbbuf); else - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } KHMEXP khm_int32 KHMAPI kcdb_buf_set_attrib( @@ -366,7 +366,7 @@ KHMEXP khm_int32 KHMAPI kcdb_buf_set_attrib( else if(kcdb_is_active_identity(record)) return kcdb_identity_set_attrib(record, attr_name, buffer, cbbuf); else - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } KHMEXP khm_int32 KHMAPI kcdb_buf_hold(khm_handle record) @@ -376,7 +376,7 @@ KHMEXP khm_int32 KHMAPI kcdb_buf_hold(khm_handle record) else if(kcdb_is_active_identity(record)) return kcdb_identity_hold(record); else - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } KHMEXP khm_int32 KHMAPI kcdb_buf_release(khm_handle record) @@ -386,6 +386,6 @@ KHMEXP khm_int32 KHMAPI kcdb_buf_release(khm_handle record) else if(kcdb_is_active_identity(record)) return kcdb_identity_release(record); else - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } diff --git a/src/windows/identity/kcreddb/buf.h b/src/windows/identity/kcreddb/buf.h index 3ff1f041d..f47bd0a2a 100644 --- a/src/windows/identity/kcreddb/buf.h +++ b/src/windows/identity/kcreddb/buf.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/kcreddb/credential.c b/src/windows/identity/kcreddb/credential.c index 1fe1dcd97..335521e12 100644 --- a/src/windows/identity/kcreddb/credential.c +++ b/src/windows/identity/kcreddb/credential.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -59,11 +59,11 @@ void kcdb_cred_exit(void) can be called by kcdb_cred_dup with a write lock on l_creds and in other places with a read lock on l_creds. New credentials must be creatable while holding either lock. */ -KHMEXP khm_int32 KHMAPI kcdb_cred_create( - wchar_t * name, - khm_handle identity, - khm_int32 cred_type, - khm_handle * result) +KHMEXP khm_int32 KHMAPI +kcdb_cred_create(wchar_t * name, + khm_handle identity, + khm_int32 cred_type, + khm_handle * result) { kcdb_cred * cred; size_t cb_name; @@ -71,20 +71,18 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_create( if(!name || !result || FAILED(StringCbLength(name, KCDB_CRED_MAXCB_NAME, &cb_name)) || KHM_FAILED(kcdb_credtype_get_info(cred_type, NULL)) || - KHM_FAILED(kcdb_identity_hold(identity)) - ) - { - return KHM_ERROR_INVALID_PARM; + KHM_FAILED(kcdb_identity_hold(identity))) { + return KHM_ERROR_INVALID_PARAM; } cb_name += sizeof(wchar_t); - cred = malloc(sizeof(kcdb_cred)); + cred = PMALLOC(sizeof(kcdb_cred)); ZeroMemory(cred, sizeof(kcdb_cred)); cred->magic = KCDB_CRED_MAGIC; cred->identity = identity; - cred->name = malloc(cb_name); + cred->name = PMALLOC(cb_name); StringCbCopy(cred->name, cb_name, name); cred->type = cred_type; @@ -107,9 +105,8 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_create( return KHM_ERROR_SUCCESS; } -KHMEXP khm_int32 KHMAPI kcdb_cred_update( - khm_handle vdest, - khm_handle vsrc) +KHMEXP khm_int32 KHMAPI kcdb_cred_update(khm_handle vdest, + khm_handle vsrc) { khm_int32 rv = KHM_ERROR_EQUIVALENT; kcdb_cred * src; @@ -126,7 +123,7 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_update( kcdb_cred_lock_write(); if(!kcdb_cred_is_active_cred(vsrc) || - !kcdb_cred_is_active_cred(vdest)) + !kcdb_cred_is_active_cred(vdest)) goto _exit; src = (kcdb_cred *) vsrc; @@ -192,24 +189,23 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_dup( khm_handle vnewcred; if(!pnewcred) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; *pnewcred = NULL; kcdb_cred_lock_write(); if(!kcdb_cred_is_active_cred(vcred)) { - code = KHM_ERROR_INVALID_PARM; + code = KHM_ERROR_INVALID_PARAM; goto _exit; } cred = (kcdb_cred *) vcred; - if(KHM_FAILED(kcdb_cred_create( - cred->name, - cred->identity, - cred->type, - &vnewcred))) + if(KHM_FAILED(kcdb_cred_create(cred->name, + cred->identity, + cred->type, + &vnewcred))) { code = KHM_ERROR_UNKNOWN; goto _exit; @@ -236,20 +232,20 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_serial( kcdb_cred * c; if(!pserial) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; - LockObtainRead(&l_creds); + kcdb_cred_lock_read(); if(!kcdb_cred_is_active_cred(vcred)) { - LockReleaseRead(&l_creds); - return KHM_ERROR_INVALID_PARM; + kcdb_cred_unlock_read(); + return KHM_ERROR_INVALID_PARAM; } c = (kcdb_cred *) vcred; *pserial = c->id; - LockReleaseRead(&l_creds); + kcdb_cred_unlock_read(); return KHM_ERROR_SUCCESS; } @@ -261,12 +257,12 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_set_identity( kcdb_cred * c; if(!kcdb_is_identity(id)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; kcdb_cred_lock_write(); if(!kcdb_cred_is_active_cred(vcred)) { kcdb_cred_unlock_write(); - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } c = (kcdb_cred *) vcred; @@ -289,20 +285,20 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_type( kcdb_cred * c; if(!type) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; - LockObtainRead(&l_creds); + kcdb_cred_lock_read(); if(!kcdb_cred_is_active_cred(vcred)) { - LockReleaseRead(&l_creds); - return KHM_ERROR_INVALID_PARM; + kcdb_cred_unlock_read(); + return KHM_ERROR_INVALID_PARAM; } c = (kcdb_cred *) vcred; *type = c->type; - LockReleaseRead(&l_creds); + kcdb_cred_unlock_read(); return KHM_ERROR_SUCCESS; } @@ -316,7 +312,7 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_set_attrib( khm_int32 attr_id = -1; if(KHM_FAILED(kcdb_attrib_get_id(name, &attr_id))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; return kcdb_cred_set_attr( cred, @@ -338,20 +334,20 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_set_attr( khm_int32 code = KHM_ERROR_SUCCESS; if(attr_id < 0 || attr_id > KCDB_ATTR_MAX_ID) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; kcdb_cred_lock_write(); if(!kcdb_cred_is_active_cred(vcred)) { kcdb_cred_unlock_write(); - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } cred = (kcdb_cred *) vcred; if(KHM_FAILED(kcdb_attrib_get_info(attr_id, &attrib))) { kcdb_cred_unlock_write(); - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } if(attrib->flags & KCDB_ATTR_FLAG_COMPUTED) @@ -371,7 +367,7 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_set_attr( if(KHM_FAILED(kcdb_type_get_info(attrib->type, &type))) { kcdb_cred_unlock_write(); kcdb_attrib_release_info(attrib); - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } if(!(type->isValid(buffer,cbbuf))) { @@ -380,7 +376,7 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_set_attr( } if((type->dup(buffer, cbbuf, NULL, &cbdest)) != KHM_ERROR_TOO_LONG) { - code = KHM_ERROR_INVALID_PARM; + code = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -450,12 +446,12 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_attrib_string( flags); } -KHMEXP khm_int32 KHMAPI kcdb_cred_get_attr( - khm_handle vcred, - khm_int32 attr_id, - khm_int32 * attr_type, - void * buffer, - khm_size * pcbbuf) +KHMEXP khm_int32 KHMAPI +kcdb_cred_get_attr(khm_handle vcred, + khm_int32 attr_id, + khm_int32 * attr_type, + void * buffer, + khm_size * pcbbuf) { khm_int32 code = KHM_ERROR_SUCCESS; kcdb_cred * cred = NULL; @@ -463,10 +459,10 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_attr( kcdb_type * type = NULL; if(attr_id < 0 || attr_id > KCDB_ATTR_MAX_ID) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(KHM_FAILED(kcdb_attrib_get_info(attr_id, &attrib))) { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } if(KHM_FAILED(kcdb_type_get_info(attrib->type, &type))) { @@ -477,9 +473,9 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_attr( if(attr_type) *attr_type = attrib->type; - LockObtainRead(&l_creds); + kcdb_cred_lock_read(); if(!kcdb_cred_is_active_cred(vcred)) { - code = KHM_ERROR_INVALID_PARM; + code = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -511,7 +507,7 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_attr( } _exit: - LockReleaseRead(&l_creds); + kcdb_cred_unlock_read(); if(type) kcdb_type_release_info(type); if(attrib) @@ -533,10 +529,10 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_attr_string( kcdb_type * type = NULL; if(attr_id < 0 || attr_id > KCDB_ATTR_MAX_ID) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(KHM_FAILED(kcdb_attrib_get_info(attr_id, &attrib))) { - code = KHM_ERROR_INVALID_PARM; + code = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -545,17 +541,18 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_attr_string( goto _exit; } - LockObtainRead(&l_creds); + kcdb_cred_lock_read(); if(!kcdb_cred_is_active_cred(vcred)) { - code = KHM_ERROR_INVALID_PARM; + code = KHM_ERROR_INVALID_PARAM; goto _exit; } cred = (kcdb_cred *) vcred; if(!buffer && !pcbbuf) { - /* in this case the caller is only trying to determine if the field - contains data. We assume that computed fields are always non-null. */ + /* in this case the caller is only trying to determine if the + field contains data. We assume that computed fields are + always non-null. */ code = (kcdb_cred_val_exist(cred, attr_id) || (attrib->flags & KCDB_ATTR_FLAG_COMPUTED))?KHM_ERROR_SUCCESS:KHM_ERROR_NOT_FOUND; goto _exit; @@ -565,27 +562,32 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_attr_string( void * buf; khm_size cbbuf; - code = attrib->compute_cb( - vcred, - attr_id, - NULL, - &cbbuf); + code = attrib->compute_cb(vcred, + attr_id, + NULL, + &cbbuf); if(code == KHM_ERROR_TOO_LONG) { - buf = malloc(cbbuf); - code = attrib->compute_cb( - vcred, - attr_id, - buf, - &cbbuf); + wchar_t vbuf[KCDB_MAXCCH_NAME]; + + if (cbbuf < sizeof(vbuf)) + buf = vbuf; + else + buf = PMALLOC(cbbuf); + + code = attrib->compute_cb(vcred, + attr_id, + buf, + &cbbuf); if(KHM_SUCCEEDED(code)) { - code = type->toString( - buf, - cbbuf, - buffer, - pcbbuf, - flags); + code = type->toString(buf, + cbbuf, + buffer, + pcbbuf, + flags); } - free(buf); + + if (buf != vbuf) + PFREE(buf); } } else { if(kcdb_cred_buf_exist(cred, attr_id)) { @@ -600,7 +602,7 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_attr_string( } _exit: - LockReleaseRead(&l_creds); + kcdb_cred_unlock_read(); if(type) kcdb_type_release_info(type); if(attrib) @@ -620,12 +622,12 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_name( size_t cbsize; if(!cbbuf) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; - LockObtainRead(&l_creds); + kcdb_cred_lock_read(); if(!kcdb_cred_is_active_cred(vcred)) { - code = KHM_ERROR_INVALID_PARM; + code = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -650,7 +652,7 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_name( _exit: - LockReleaseRead(&l_creds); + kcdb_cred_unlock_read(); return code; } @@ -662,12 +664,12 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_identity( kcdb_cred * cred; if(!identity) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; - LockObtainRead(&l_creds); + kcdb_cred_lock_read(); if(!kcdb_cred_is_active_cred(vcred)) { - code = KHM_ERROR_INVALID_PARM; + code = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -678,7 +680,7 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_identity( *identity = cred->identity; _exit: - LockReleaseRead(&l_creds); + kcdb_cred_unlock_read(); return code; } @@ -689,8 +691,8 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_hold(khm_handle vcred) kcdb_cred_lock_write(); - if(!kcdb_cred_is_active_cred(vcred)) { - code = KHM_ERROR_INVALID_PARM; + if(!kcdb_cred_is_cred(vcred)) { + code = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -710,8 +712,8 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_release(khm_handle vcred) kcdb_cred_lock_write(); - if(!kcdb_cred_is_active_cred(vcred)) { - code = KHM_ERROR_INVALID_PARM; + if(!kcdb_cred_is_cred(vcred)) { + code = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -731,20 +733,17 @@ void kcdb_cred_check_and_delete(khm_handle vcred) { kcdb_cred * cred; - LockObtainRead(&l_creds); + kcdb_cred_lock_read(); if(!kcdb_cred_is_cred(vcred)) { goto _exit; } cred = (kcdb_cred *) vcred; - if(!(cred->flags & KCDB_CRED_FLAG_DELETED)) - goto _exit; - if(cred->refcount) goto _exit; - LockReleaseRead(&l_creds); + kcdb_cred_unlock_read(); kcdb_cred_lock_write(); if(!kcdb_cred_is_cred(vcred)) { /* did we lose the race? */ @@ -759,8 +758,8 @@ void kcdb_cred_check_and_delete(khm_handle vcred) LeaveCriticalSection(&cs_creds); kcdb_buf_delete(&cred->buf); - free(cred->name); - free(cred); + PFREE(cred->name); + PFREE(cred); /*TODO: notifications */ @@ -769,7 +768,7 @@ _exit2: return; _exit: - LockReleaseRead(&l_creds); + kcdb_cred_unlock_read(); } KHMEXP khm_int32 KHMAPI kcdb_cred_delete(khm_handle vcred) @@ -780,7 +779,7 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_delete(khm_handle vcred) kcdb_cred_lock_write(); if(!kcdb_cred_is_active_cred(vcred)) { - code = KHM_ERROR_INVALID_PARM; + code = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -796,10 +795,10 @@ _exit: return code; } -KHMEXP khm_int32 KHMAPI kcdb_creds_comp_attrib( - khm_handle cred1, - khm_handle cred2, - wchar_t * name) +KHMEXP khm_int32 KHMAPI +kcdb_creds_comp_attrib(khm_handle cred1, + khm_handle cred2, + wchar_t * name) { khm_int32 attr_id; @@ -809,10 +808,10 @@ KHMEXP khm_int32 KHMAPI kcdb_creds_comp_attrib( return kcdb_creds_comp_attr(cred1, cred2, attr_id); } -KHMEXP khm_int32 KHMAPI kcdb_creds_comp_attr( - khm_handle vcred1, - khm_handle vcred2, - khm_int32 attr_id) +KHMEXP khm_int32 KHMAPI +kcdb_creds_comp_attr(khm_handle vcred1, + khm_handle vcred2, + khm_int32 attr_id) { khm_int32 code = 0; kcdb_cred * cred1; @@ -826,7 +825,7 @@ KHMEXP khm_int32 KHMAPI kcdb_creds_comp_attr( cred1 = (kcdb_cred *) vcred1; cred2 = (kcdb_cred *) vcred2; - LockObtainRead(&l_creds); + kcdb_cred_lock_read(); if( !kcdb_cred_is_active_cred(vcred1) || !kcdb_cred_is_active_cred(vcred2)) @@ -858,6 +857,7 @@ KHMEXP khm_int32 KHMAPI kcdb_creds_comp_attr( goto _exit; if(attrib->flags & KCDB_ATTR_FLAG_COMPUTED) { + khm_octet vbuf[KCDB_MAXCB_NAME * 2]; void * buf1 = NULL; void * buf2 = NULL; khm_size cb1; @@ -865,31 +865,43 @@ KHMEXP khm_int32 KHMAPI kcdb_creds_comp_attr( code = 0; - if(attrib->compute_cb(vcred1, attr_id, NULL, &cb1) != KHM_ERROR_TOO_LONG) + if(attrib->compute_cb(vcred1, attr_id, + NULL, &cb1) != KHM_ERROR_TOO_LONG) goto _exit_1; - if(attrib->compute_cb(vcred2, attr_id, NULL, &cb2) != KHM_ERROR_TOO_LONG) + if(attrib->compute_cb(vcred2, attr_id, + NULL, &cb2) != KHM_ERROR_TOO_LONG) goto _exit_1; if(cb1) { - buf1 = malloc(cb1); + if (cb1 < sizeof(vbuf)) + buf1 = vbuf; + else + buf1 = PMALLOC(cb1); + if(KHM_FAILED(attrib->compute_cb(vcred1, attr_id, buf1, &cb1))) goto _exit_1; } + if(cb2) { - buf2 = malloc(cb2); + if (cb1 + cb2 < sizeof(vbuf)) + buf2 = vbuf + cb1; + else + buf2 = PMALLOC(cb2); + if(KHM_FAILED(attrib->compute_cb(vcred2, attr_id, buf2, &cb2))) goto _exit_1; } - code = type->comp( - buf1, cb1, - buf2, cb2); -_exit_1: - if(buf1) - free(buf1); - if(buf2) - free(buf2); + code = type->comp(buf1, cb1, + buf2, cb2); +_exit_1: + if(buf1 && (buf1 < (void *)vbuf || + buf1 >= (void*)(vbuf + sizeof(vbuf)))) + PFREE(buf1); + if(buf2 && (buf2 < (void *)vbuf || + buf2 >= (void *)(vbuf + sizeof(vbuf)))) + PFREE(buf2); } else { code = type->comp( kcdb_cred_buf_get(cred1, attr_id), @@ -899,7 +911,7 @@ _exit_1: } _exit: - LockReleaseRead(&l_creds); + kcdb_cred_unlock_read(); if(attrib) kcdb_attrib_release_info(attrib); if(type) @@ -907,17 +919,17 @@ _exit: return code; } -KHMEXP khm_int32 KHMAPI kcdb_creds_is_equal( - khm_handle vcred1, - khm_handle vcred2) +KHMEXP khm_int32 KHMAPI +kcdb_creds_is_equal(khm_handle vcred1, + khm_handle vcred2) { khm_int32 code = 0; kcdb_cred * cred1; kcdb_cred * cred2; - LockObtainRead(&l_creds); + kcdb_cred_lock_read(); if(!kcdb_cred_is_active_cred(vcred1) || - !kcdb_cred_is_active_cred(vcred2)) + !kcdb_cred_is_active_cred(vcred2)) goto _exit; if(vcred1 == vcred2) { @@ -929,19 +941,30 @@ KHMEXP khm_int32 KHMAPI kcdb_creds_is_equal( cred2 = vcred2; if(cred1->identity == cred2->identity && - cred1->type == cred2->type && - !wcscmp(cred1->name, cred2->name)) { + cred1->type == cred2->type && + !wcscmp(cred1->name, cred2->name)) { + + kcdb_credtype * type; + code = TRUE; + + if (KHM_SUCCEEDED(kcdb_credtype_get_info(cred1->type, &type))) { + if (type->is_equal && + (*type->is_equal)(vcred1, vcred2, NULL)) + code = 0; + + kcdb_credtype_release_info(type); } + } _exit: - LockReleaseRead(&l_creds); + kcdb_cred_unlock_read(); return code; } -KHMEXP khm_int32 KHMAPI kcdb_cred_get_flags( - khm_handle vcred, - khm_int32 * pflags) +KHMEXP khm_int32 KHMAPI +kcdb_cred_get_flags(khm_handle vcred, + khm_int32 * pflags) { khm_int32 f; khm_int32 rv = KHM_ERROR_SUCCESS; @@ -949,12 +972,12 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_flags( int release_lock = TRUE; if (pflags == NULL) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; - LockObtainRead(&l_creds); + kcdb_cred_lock_read(); if (!kcdb_cred_is_active_cred(vcred)) { *pflags = 0; - rv = KHM_ERROR_INVALID_PARM; + rv = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -995,16 +1018,16 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_flags( /* Commented out: this is a read operation. We shouldn't attempt to lock for writing */ if (f != cred->flags) { - LockReleaseRead(&l_creds); - LockObtainWrite(&l_creds); + kcdb_cred_unlock_read(); + kcdb_cred_lock_write(); /* Did we lose a race? */ if (kcdb_cred_is_active_cred(vcred)) cred->flags = f; else { - rv = KHM_ERROR_INVALID_PARM; + rv = KHM_ERROR_INVALID_PARAM; f = 0; } - LockReleaseWrite(&l_creds); + kcdb_cred_unlock_write(); release_lock = FALSE; } #endif @@ -1013,7 +1036,7 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_get_flags( _exit: if (release_lock) - LockReleaseRead(&l_creds); + kcdb_cred_unlock_read(); return rv; } @@ -1026,9 +1049,9 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_set_flags( khm_int32 rv = KHM_ERROR_SUCCESS; kcdb_cred * cred; - LockObtainWrite(&l_creds); + kcdb_cred_lock_write(); if(!kcdb_cred_is_active_cred(vcred)) { - rv = KHM_ERROR_INVALID_PARM; + rv = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -1042,6 +1065,6 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_set_flags( (flags & mask); _exit: - LockReleaseWrite(&l_creds); + kcdb_cred_unlock_write(); return rv; } diff --git a/src/windows/identity/kcreddb/credential.h b/src/windows/identity/kcreddb/credential.h index 8104f686b..9cb70ab4d 100644 --- a/src/windows/identity/kcreddb/credential.h +++ b/src/windows/identity/kcreddb/credential.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -58,6 +58,7 @@ extern khm_ui_8 kcdb_cred_id; #define kcdb_cred_is_cred(c) ((c) && ((kcdb_cred *) c)->magic == KCDB_CRED_MAGIC) #define kcdb_cred_is_active_cred(c) (kcdb_cred_is_cred(c) && !(((kcdb_cred *) c)->flags & KCDB_CRED_FLAG_DELETED)) + #define kcdb_cred_lock_read() (LockObtainRead(&l_creds)) #define kcdb_cred_unlock_read() (LockReleaseRead(&l_creds)) #define kcdb_cred_lock_write() (LockObtainWrite(&l_creds)) diff --git a/src/windows/identity/kcreddb/credset.c b/src/windows/identity/kcreddb/credset.c index 3a39d48a6..869cd8409 100644 --- a/src/windows/identity/kcreddb/credset.c +++ b/src/windows/identity/kcreddb/credset.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -52,8 +52,11 @@ void kcdb_credset_exit(void) /* called on an unreleased credset, or with credset::cs held */ void kcdb_credset_buf_new(kcdb_credset * cs) { - cs->clist = malloc(KCDB_CREDSET_INITIAL_SIZE * sizeof(kcdb_credset_credref)); - ZeroMemory(cs->clist, KCDB_CREDSET_INITIAL_SIZE * sizeof(kcdb_credset_credref)); + cs->clist = PMALLOC(KCDB_CREDSET_INITIAL_SIZE * + sizeof(kcdb_credset_credref)); + ZeroMemory(cs->clist, + KCDB_CREDSET_INITIAL_SIZE * + sizeof(kcdb_credset_credref)); cs->nc_clist = KCDB_CREDSET_INITIAL_SIZE; cs->nclist = 0; } @@ -61,7 +64,7 @@ void kcdb_credset_buf_new(kcdb_credset * cs) /* called on an unreleased credset, or with credset::cs held */ void kcdb_credset_buf_delete(kcdb_credset * cs) { - free(cs->clist); + PFREE(cs->clist); cs->nc_clist = 0; cs->nclist = 0; } @@ -80,7 +83,7 @@ void kcdb_credset_buf_assert_size(kcdb_credset * cs, khm_int32 nclist) memcpy(new_clist, cs->clist, cs->nclist * sizeof(kcdb_credset_credref)); - free(cs->clist); + PFREE(cs->clist); cs->clist = new_clist; } @@ -90,7 +93,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_create(khm_handle * result) { kcdb_credset * cs; - cs = malloc(sizeof(kcdb_credset)); + cs = PMALLOC(sizeof(kcdb_credset)); ZeroMemory(cs, sizeof(kcdb_credset)); cs->magic = KCDB_CREDSET_MAGIC; @@ -115,7 +118,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_delete(khm_handle vcredset) int i; if(!kcdb_credset_is_credset(vcredset)) { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } cs = (kcdb_credset *) vcredset; @@ -137,7 +140,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_delete(khm_handle vcredset) LeaveCriticalSection(&(cs->cs)); DeleteCriticalSection(&(cs->cs)); - free(cs); + PFREE(cs); return KHM_ERROR_SUCCESS; } @@ -153,14 +156,14 @@ cl1 and cl2. cl1 and cl2 will be modified. */ -khm_int32 kcdb_credset_collect_core( - kcdb_credset * cs1, - kcdb_cred ** cl1, - khm_int32 ncl1, - kcdb_credset * cs2, - kcdb_cred ** cl2, - khm_int32 ncl2, - khm_int32 * delta) +khm_int32 +kcdb_credset_collect_core(kcdb_credset * cs1, + kcdb_cred ** cl1, + khm_int32 ncl1, + kcdb_credset * cs2, + kcdb_cred ** cl2, + khm_int32 ncl2, + khm_int32 * delta) { int i, j; int ldelta = 0; @@ -243,10 +246,10 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_collect( (cs_dest && !kcdb_credset_is_credset(cs_dest)) || (cs_src == cs_dest)) /* works because credsets use shared handles */ - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(identity && !kcdb_is_active_identity(identity)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(cs_src) cs = (kcdb_credset *) cs_src; @@ -268,9 +271,9 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_collect( the ones we want */ if(rcs->nclist > 0) - r_sel = malloc(sizeof(kcdb_cred *) * rcs->nclist); + r_sel = PMALLOC(sizeof(kcdb_cred *) * rcs->nclist); if(cs->nclist > 0) - c_sel = malloc(sizeof(kcdb_cred *) * cs->nclist); + c_sel = PMALLOC(sizeof(kcdb_cred *) * cs->nclist); nr_sel = 0; nc_sel = 0; @@ -307,9 +310,9 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_collect( LeaveCriticalSection(&(cs->cs)); if(r_sel) - free(r_sel); + PFREE(r_sel); if(c_sel) - free(c_sel); + PFREE(c_sel); return code; } @@ -335,7 +338,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_collect_filtered( (cs_dest && !kcdb_credset_is_credset(cs_dest)) || (cs_src == cs_dest)) /* works because credsets use shared handles */ - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(cs_src) cs = (kcdb_credset *) cs_src; @@ -363,9 +366,9 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_collect_filtered( #endif if(rcs->nclist) - r_sel = malloc(sizeof(kcdb_cred *) * rcs->nclist); + r_sel = PMALLOC(sizeof(kcdb_cred *) * rcs->nclist); if(cs->nclist) - c_sel = malloc(sizeof(kcdb_cred *) * cs->nclist); + c_sel = PMALLOC(sizeof(kcdb_cred *) * cs->nclist); nr_sel = 0; nc_sel = 0; @@ -408,9 +411,9 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_collect_filtered( LeaveCriticalSection(&(cs->cs)); if(r_sel) - free(r_sel); + PFREE(r_sel); if(c_sel) - free(c_sel); + PFREE(c_sel); return code; } @@ -421,7 +424,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_flush(khm_handle vcredset) kcdb_credset * cs; if(!kcdb_credset_is_credset(vcredset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cs = (kcdb_credset *) vcredset; @@ -459,11 +462,11 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_extract( int i; if(!kcdb_credset_is_credset(destcredset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(sourcecredset) { if(!kcdb_credset_is_credset(sourcecredset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } else { sourcecredset = kcdb_root_credset; } @@ -538,11 +541,11 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_extract_filtered( int i; if(!kcdb_credset_is_credset(destcredset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(sourcecredset) { if(!kcdb_credset_is_credset(sourcecredset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } else { sourcecredset = kcdb_root_credset; isRoot = 1; @@ -611,7 +614,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_apply(khm_handle vcredset, kcdb_cred_apply_ int i; if(vcredset != NULL && !kcdb_credset_is_credset(vcredset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(vcredset == NULL) { cs = kcdb_root_credset; @@ -654,7 +657,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_get_cred( khm_int32 code = KHM_ERROR_SUCCESS; if(!kcdb_credset_is_credset(vcredset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cs = (kcdb_credset *) vcredset; @@ -692,7 +695,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_find_filtered( if((credset && !kcdb_credset_is_credset(credset)) || (!f || !cred)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(credset) cs = (kcdb_credset *) credset; @@ -743,10 +746,10 @@ kcdb_credset_find_cred(khm_handle vcredset, int idx; if (!kcdb_credset_is_credset(vcredset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if (!kcdb_cred_is_active_cred(vcred_src)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cs = (kcdb_credset *) vcredset; @@ -784,7 +787,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_del_cred( khm_int32 code = KHM_ERROR_SUCCESS; if(!kcdb_credset_is_credset(vcredset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cs = (kcdb_credset *) vcredset; @@ -793,7 +796,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_del_cred( EnterCriticalSection(&(cs->cs)); if(idx < 0 || idx >= cs->nclist) { - code = KHM_ERROR_INVALID_PARM; + code = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -828,7 +831,7 @@ khm_int32 kcdb_credset_update_cred_ref( int i; if(!kcdb_credset_is_credset(credset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cs = (kcdb_credset *) credset; @@ -858,7 +861,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_del_cred_ref( int i; if(!kcdb_credset_is_credset(credset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cs = (kcdb_credset *) credset; @@ -892,7 +895,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_add_cred( khm_int32 code = KHM_ERROR_SUCCESS; if(!kcdb_credset_is_credset(credset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cs = (kcdb_credset *) credset; @@ -958,7 +961,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_purge(khm_handle credset) int i,j; if(!kcdb_credset_is_credset(credset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cs = (kcdb_credset *) credset; @@ -996,7 +999,7 @@ kcdb_credset_seal(khm_handle credset) { kcdb_credset * cs; if (!kcdb_credset_is_credset(credset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cs = (kcdb_credset *) credset; @@ -1013,7 +1016,7 @@ kcdb_credset_unseal(khm_handle credset) { khm_int32 rv; if (!kcdb_credset_is_credset(credset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cs = (kcdb_credset *) credset; @@ -1046,7 +1049,9 @@ int __cdecl kcdb_creds_comp_wrapper(const void * a, const void * b) return 0; } - return comp((khm_handle) ((kcdb_credset_credref *)a)->cred, (khm_handle) ((kcdb_credset_credref *)b)->cred, rock); + return comp((khm_handle) ((kcdb_credset_credref *)a)->cred, + (khm_handle) ((kcdb_credset_credref *)b)->cred, + rock); } KHMEXP khm_int32 KHMAPI kcdb_credset_sort( @@ -1058,7 +1063,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credset_sort( kcdb_credset * cs; if(!kcdb_credset_is_credset(credset)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cs = (kcdb_credset *) credset; @@ -1089,31 +1094,42 @@ KHMEXP khm_int32 KHMAPI kcdb_cred_comp_generic( int i; khm_int32 r = 0; khm_int32 f1, f2; + khm_int32 t1, t2; khm_int32 pt; for(i=0; inFields; i++) { if (o->fields[i].order & KCDB_CRED_COMP_INITIAL_FIRST) { - kcdb_cred_get_flags(cred1, &f1); - kcdb_cred_get_flags(cred2, &f2); + if (o->fields[i].attrib == KCDB_ATTR_TYPE_NAME || + o->fields[i].attrib == KCDB_ATTR_TYPE) { - if (((f1 ^ f2) & KCDB_CRED_FLAG_INITIAL) == 0) { - kcdb_cred_get_type(cred1, &f1); - kcdb_cred_get_type(cred2, &f2); + kcdb_cred_get_type(cred1, &t1); + kcdb_cred_get_type(cred2, &t2); kcdb_identity_get_type(&pt); - if (f1 == f2) + if (t1 == t2) r = 0; - else if (f1 == pt) + else if (t1 == pt) r = -1; - else if (f2 == pt) + else if (t2 == pt) r = 1; else r = 0; - } else if (f1 & KCDB_CRED_FLAG_INITIAL) - r = -1; - else - r = 1; + + } else { + + kcdb_cred_get_flags(cred1, &f1); + kcdb_cred_get_flags(cred2, &f2); + + if (((f1 ^ f2) & KCDB_CRED_FLAG_INITIAL) == 0) + r = 0; + else if (f1 & KCDB_CRED_FLAG_INITIAL) + r = -1; + else + r = 1; + + } + } else { r = 0; } diff --git a/src/windows/identity/kcreddb/credset.h b/src/windows/identity/kcreddb/credset.h index c19246540..cd216fdd2 100644 --- a/src/windows/identity/kcreddb/credset.h +++ b/src/windows/identity/kcreddb/credset.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -63,8 +63,8 @@ typedef struct kcdb_credset_t { #define kcdb_credset_is_sealed(c) ((c)->seal_count != 0) -#define KCDB_CREDSET_INITIAL_SIZE 1024 -#define KCDB_CREDSET_GROWTH_FACTOR 1024 +#define KCDB_CREDSET_INITIAL_SIZE 256 +#define KCDB_CREDSET_GROWTH_FACTOR 256 void kcdb_credset_init(void); void kcdb_credset_exit(void); diff --git a/src/windows/identity/kcreddb/credtype.c b/src/windows/identity/kcreddb/credtype.c index dc2b7b85a..e57b22b53 100644 --- a/src/windows/identity/kcreddb/credtype.c +++ b/src/windows/identity/kcreddb/credtype.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -34,14 +34,15 @@ void kcdb_credtype_init(void) { InitializeCriticalSection(&cs_credtype); kcdb_credtypes = NULL; - kcdb_credtype_tbl = malloc(sizeof(kcdb_credtype_i *) * (KCDB_CREDTYPE_MAX_ID+1)); + + kcdb_credtype_tbl = PMALLOC(sizeof(kcdb_credtype_i *) * (KCDB_CREDTYPE_MAX_ID+1)); ZeroMemory(kcdb_credtype_tbl, sizeof(kcdb_credtype_i *) * (KCDB_CREDTYPE_MAX_ID+1)); } void kcdb_credtype_exit(void) { /*TODO:Free up the cred types */ - free(kcdb_credtype_tbl); + PFREE(kcdb_credtype_tbl); DeleteCriticalSection(&cs_credtype); } @@ -59,19 +60,20 @@ void kcdb_credtype_check_and_delete(khm_int32 id) kcdb_credtype_tbl[id] = NULL; LDELETE(&kcdb_credtypes, ict); - free(ict->ct.name); + PFREE(ict->ct.name); if(ict->ct.short_desc) - free(ict->ct.short_desc); + PFREE(ict->ct.short_desc); if(ict->ct.long_desc) - free(ict->ct.long_desc); + PFREE(ict->ct.long_desc); if(ict->ct.sub) kmq_delete_subscription(ict->ct.sub); - free(ict); + PFREE(ict); } } -KHMEXP khm_int32 KHMAPI kcdb_credtype_register(kcdb_credtype * type, khm_int32 * new_id) +KHMEXP khm_int32 KHMAPI +kcdb_credtype_register(kcdb_credtype * type, khm_int32 * new_id) { khm_int32 id; kcdb_credtype_i * ict; @@ -81,17 +83,17 @@ KHMEXP khm_int32 KHMAPI kcdb_credtype_register(kcdb_credtype * type, khm_int32 * int i; if(!type) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(type->id >= KCDB_CREDTYPE_MAX_ID) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(type->name) { if(FAILED(StringCbLength(type->name, KCDB_MAXCB_NAME, &cb_name))) return KHM_ERROR_TOO_LONG; cb_name += sizeof(wchar_t); } else - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(type->short_desc) { if(FAILED(StringCbLength(type->short_desc, KCDB_MAXCB_SHORT_DESC, &cb_short_desc))) @@ -108,7 +110,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credtype_register(kcdb_credtype * type, khm_int32 * cb_long_desc = 0; if(type->sub == NULL) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_credtype); @@ -133,19 +135,19 @@ KHMEXP khm_int32 KHMAPI kcdb_credtype_register(kcdb_credtype * type, khm_int32 * } } - ict = malloc(sizeof(kcdb_credtype_i)); + ict = PMALLOC(sizeof(kcdb_credtype_i)); ZeroMemory(ict, sizeof(kcdb_credtype_i)); - ict->ct.name = malloc(cb_name); + ict->ct.name = PMALLOC(cb_name); StringCbCopy(ict->ct.name, cb_name, type->name); if(cb_short_desc) { - ict->ct.short_desc = malloc(cb_short_desc); + ict->ct.short_desc = PMALLOC(cb_short_desc); StringCbCopy(ict->ct.short_desc, cb_short_desc, type->short_desc); } if(cb_long_desc) { - ict->ct.long_desc = malloc(cb_long_desc); + ict->ct.long_desc = PMALLOC(cb_long_desc); StringCbCopy(ict->ct.long_desc, cb_long_desc, type->long_desc); } @@ -155,6 +157,8 @@ KHMEXP khm_int32 KHMAPI kcdb_credtype_register(kcdb_credtype * type, khm_int32 * ict->ct.sub = type->sub; + ict->ct.is_equal = type->is_equal; + kcdb_credtype_tbl[id] = ict; LPUSH(&kcdb_credtypes, ict); @@ -176,7 +180,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credtype_get_info( int found = 0; if(id < 0 || id > KCDB_CREDTYPE_MAX_ID) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_credtype); if(kcdb_credtype_tbl[id] && @@ -204,7 +208,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credtype_release_info(kcdb_credtype * type) kcdb_credtype_i * ict; if(!type) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; ict = (kcdb_credtype_i *) type; return kcdb_credtype_release(ict); @@ -215,7 +219,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credtype_unregister(khm_int32 id) kcdb_credtype_i * ict; if(id < 0 || id > KCDB_CREDTYPE_MAX_ID) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_credtype); ict = kcdb_credtype_tbl[id]; @@ -259,7 +263,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credtype_describe( khm_int32 rv = KHM_ERROR_SUCCESS; if(!cbbuf || id < 0 || id > KCDB_CREDTYPE_MAX_ID) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_credtype); t = kcdb_credtype_tbl[id]; @@ -306,7 +310,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credtype_get_name( khm_int32 rv = KHM_ERROR_SUCCESS; if(!cbbuf || id < 0 || id > KCDB_CREDTYPE_MAX_ID) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_credtype); t = kcdb_credtype_tbl[id]; @@ -340,7 +344,7 @@ KHMEXP khm_int32 KHMAPI kcdb_credtype_get_id( *id = 0; if(!name) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_credtype); for(i=0;i <= KCDB_CREDTYPE_MAX_ID; i++) { @@ -379,7 +383,7 @@ khm_int32 kcdb_credtype_get_next_free_id(khm_int32 * id) khm_int32 kcdb_credtype_hold(kcdb_credtype_i * ict) { if(!ict) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_credtype); ict->refcount++; @@ -390,7 +394,7 @@ khm_int32 kcdb_credtype_hold(kcdb_credtype_i * ict) { khm_int32 kcdb_credtype_release(kcdb_credtype_i * ict) { if(!ict) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_credtype); ict->refcount--; diff --git a/src/windows/identity/kcreddb/credtype.h b/src/windows/identity/kcreddb/credtype.h index 6e46db303..aa605d730 100644 --- a/src/windows/identity/kcreddb/credtype.h +++ b/src/windows/identity/kcreddb/credtype.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -52,4 +52,4 @@ void kcdb_credtype_msg_completion(kmq_message * m); void kcdb_credtype_post_message(khm_int32 op, kcdb_credtype * type); khm_int32 kcdb_credtype_get_next_free_id(khm_int32 * id); -#endif \ No newline at end of file +#endif diff --git a/src/windows/identity/kcreddb/identity.c b/src/windows/identity/kcreddb/identity.c index d6ae129d6..43dd425c4 100644 --- a/src/windows/identity/kcreddb/identity.c +++ b/src/windows/identity/kcreddb/identity.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -27,7 +27,7 @@ #include #include -CRITICAL_SECTION cs_ident; +static CRITICAL_SECTION cs_ident; hashtable * kcdb_identities_namemap = NULL; khm_int32 kcdb_n_identities = 0; kcdb_identity * kcdb_identities = NULL; @@ -37,6 +37,16 @@ khm_int32 kcdb_ident_cred_type = KCDB_CREDTYPE_INVALID; /* primary credentials type */ khm_ui_4 kcdb_ident_refresh_cycle = 0; khm_boolean kcdb_checked_config = FALSE; +khm_boolean kcdb_checking_config = FALSE; + +KHMEXP khm_boolean KHMAPI +kcdb_identity_is_equal(khm_handle identity1, + khm_handle identity2) +{ + + return (identity1 == identity2); + +} KHMEXP khm_int32 KHMAPI kcdb_identity_set_provider(khm_handle sub) @@ -95,7 +105,7 @@ KHMEXP khm_int32 KHMAPI kcdb_identity_get_type(khm_int32 * ptype) { if (!ptype) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_ident); *ptype = kcdb_ident_cred_type; @@ -146,6 +156,7 @@ kcdbint_ident_exit(void) { DeleteCriticalSection(&cs_ident); } +/* NOT called with cs_ident held */ KHMEXP khm_boolean KHMAPI kcdb_identity_is_valid_name(const wchar_t * name) { @@ -174,7 +185,7 @@ kcdb_identity_create(const wchar_t *name, size_t namesize; if(!result || !name) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; *result = NULL; @@ -197,9 +208,10 @@ kcdb_identity_create(const wchar_t *name, /* nope. create it */ if((flags & ~KCDB_IDENT_FLAGMASK_RDWR) || (flags & (KCDB_IDENT_FLAG_DEFAULT | - KCDB_IDENT_FLAG_SEARCHABLE))) { + KCDB_IDENT_FLAG_SEARCHABLE | + KCDB_IDENT_FLAG_STICKY))) { /* can't specify this flag in create */ - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } if(!kcdb_identity_is_valid_name(name)) { @@ -211,13 +223,13 @@ kcdb_identity_create(const wchar_t *name, StringCbLength(name, KCDB_IDENT_MAXCB_NAME, &namesize); namesize += sizeof(wchar_t); - id = malloc(sizeof(kcdb_identity)); + id = PMALLOC(sizeof(kcdb_identity)); ZeroMemory(id, sizeof(kcdb_identity)); id->magic = KCDB_IDENT_MAGIC; - id->name = malloc(namesize); + id->name = PMALLOC(namesize); StringCbCopy(id->name, namesize, name); - id->flags = (flags & KCDB_IDENT_FLAGMASK_LOCAL); + id->flags = (flags & KCDB_IDENT_FLAGMASK_RDWR); id->flags |= KCDB_IDENT_FLAG_ACTIVE; LINIT(id); @@ -228,8 +240,8 @@ kcdb_identity_create(const wchar_t *name, kcdb_identity_hold((khm_handle) id_tmp); *result = (khm_handle) id_tmp; - free(id->name); - free(id); + PFREE(id->name); + PFREE(id); id = NULL; } else { @@ -245,7 +257,7 @@ kcdb_identity_create(const wchar_t *name, 0, &h_cfg))) { /* don't need to set the KCDB_IDENT_FLAG_CONFIG flags - since kcdb_identity_get_conifg() sets it for us. */ + since kcdb_identity_get_config() sets it for us. */ khm_int32 sticky; if (KHM_SUCCEEDED(khc_read_int32(h_cfg, L"Sticky", &sticky)) && @@ -276,7 +288,7 @@ kcdb_identity_delete(khm_handle vid) { EnterCriticalSection(&cs_ident); if(!kcdb_is_identity(vid)) { - code = KHM_ERROR_INVALID_PARM; + code = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -301,8 +313,8 @@ kcdb_identity_delete(khm_handle vid) { LDELETE(&kcdb_identities, id); if (id->name) - free(id->name); - free(id); + PFREE(id->name); + PFREE(id); } /* else, we have an identity that is not active, but has outstanding references. We have to wait until those references @@ -323,36 +335,45 @@ kcdb_identity_delete(khm_handle vid) { KHMEXP khm_int32 KHMAPI kcdb_identity_set_flags(khm_handle vid, - khm_int32 flag) { + khm_int32 flag, + khm_int32 mask) { kcdb_identity * id; khm_int32 oldflags; khm_int32 newflags; khm_int32 delta = 0; khm_int32 rv; + if (mask == 0) + return KHM_ERROR_SUCCESS; + if(!kcdb_is_active_identity(vid)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; id = (kcdb_identity *) vid; - if((flag & ~(KCDB_IDENT_FLAGMASK_RDWR | KCDB_IDENT_FLAG_INVERT)) || - ((flag & KCDB_IDENT_FLAG_INVALID) && (flag & KCDB_IDENT_FLAG_VALID))) - return KHM_ERROR_INVALID_PARM; + flag &= mask; + + if((mask & ~KCDB_IDENT_FLAGMASK_RDWR) || + ((flag & KCDB_IDENT_FLAG_INVALID) && (flag & KCDB_IDENT_FLAG_VALID))) + return KHM_ERROR_INVALID_PARAM; - if(flag & KCDB_IDENT_FLAG_DEFAULT) { + if((mask & KCDB_IDENT_FLAG_DEFAULT) && + (flag & KCDB_IDENT_FLAG_DEFAULT)) { /* kcdb_identity_set_default already does checking for redundant transitions */ - rv = kcdb_identity_set_default((flag & KCDB_IDENT_FLAG_INVERT)?NULL: vid); + rv = kcdb_identity_set_default(vid); if(KHM_FAILED(rv)) return rv; + mask &= ~KCDB_IDENT_FLAG_DEFAULT; flag &= ~KCDB_IDENT_FLAG_DEFAULT; } - if(flag & KCDB_IDENT_FLAG_SEARCHABLE) { - if(flag & KCDB_IDENT_FLAG_INVERT) { - EnterCriticalSection(&cs_ident); + EnterCriticalSection(&cs_ident); + + if(mask & KCDB_IDENT_FLAG_SEARCHABLE) { + if(!(flag & KCDB_IDENT_FLAG_SEARCHABLE)) { if(id->flags & KCDB_IDENT_FLAG_SEARCHABLE) { LeaveCriticalSection(&cs_ident); rv = kcdb_identpro_set_searchable(vid, FALSE); @@ -363,9 +384,7 @@ kcdb_identity_set_flags(khm_handle vid, delta |= KCDB_IDENT_FLAG_SEARCHABLE; } } - LeaveCriticalSection(&cs_ident); } else { - EnterCriticalSection(&cs_ident); if(!(id->flags & KCDB_IDENT_FLAG_SEARCHABLE)) { LeaveCriticalSection(&cs_ident); rv = kcdb_identpro_set_searchable(vid, TRUE); @@ -376,29 +395,50 @@ kcdb_identity_set_flags(khm_handle vid, delta |= KCDB_IDENT_FLAG_SEARCHABLE; } } - LeaveCriticalSection(&cs_ident); } flag &= ~KCDB_IDENT_FLAG_SEARCHABLE; + mask &= ~KCDB_IDENT_FLAG_SEARCHABLE; + } + + if (mask & KCDB_IDENT_FLAG_STICKY) { + if ((flag ^ id->flags) & KCDB_IDENT_FLAG_STICKY) { + khm_handle h_conf; + + if (KHM_SUCCEEDED(kcdb_identity_get_config(vid, + KHM_FLAG_CREATE, + &h_conf))) { + khc_write_int32(h_conf, L"Sticky", + !!(flag & KCDB_IDENT_FLAG_STICKY)); + khc_close_space(h_conf); + } + + id->flags = + ((id->flags & ~KCDB_IDENT_FLAG_STICKY) | + (flag & KCDB_IDENT_FLAG_STICKY)); + + delta |= KCDB_IDENT_FLAG_STICKY; + } + + flag &= ~KCDB_IDENT_FLAG_STICKY; + mask &= ~KCDB_IDENT_FLAG_STICKY; } /* deal with every other flag */ - EnterCriticalSection(&cs_ident); oldflags = id->flags; - if(flag & KCDB_IDENT_FLAG_INVERT) { - flag &= ~KCDB_IDENT_FLAG_INVERT; - id->flags &= ~flag; - } else { - id->flags |= flag; - if(flag & KCDB_IDENT_FLAG_VALID) - id->flags &= ~KCDB_IDENT_FLAG_INVALID; - if(flag & KCDB_IDENT_FLAG_INVALID) - id->flags &= ~KCDB_IDENT_FLAG_VALID; - } + id->flags = (id->flags & ~mask) | (flag & mask); + + if (flag & KCDB_IDENT_FLAG_VALID) + id->flags &= ~KCDB_IDENT_FLAG_INVALID; + if (flag & KCDB_IDENT_FLAG_INVALID) + id->flags &= ~KCDB_IDENT_FLAG_VALID; + newflags = id->flags; + LeaveCriticalSection(&cs_ident); + delta |= newflags ^ oldflags; if((delta & KCDB_IDENT_FLAG_HIDDEN)) { @@ -427,7 +467,7 @@ kcdb_identity_get_flags(khm_handle vid, *flags = 0; if(!kcdb_is_active_identity(vid)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; id = (kcdb_identity *) vid; @@ -444,7 +484,7 @@ kcdb_identity_get_name(khm_handle vid, kcdb_identity * id; if(!kcdb_is_active_identity(vid) || !pcbsize) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; id = (kcdb_identity *) vid; @@ -469,7 +509,7 @@ kcdb_identity_get_default(khm_handle * pvid) { khm_handle def; if (pvid == NULL) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_ident); def = kcdb_def_identity; @@ -492,15 +532,16 @@ kcdbint_ident_set_default(khm_handle vid, kcdb_identity * old_def; khm_int32 rv; - if(vid != NULL && !kcdb_is_active_identity(vid)) - return KHM_ERROR_INVALID_PARM; + if (vid != NULL && !kcdb_is_active_identity(vid)) + return KHM_ERROR_INVALID_PARAM; new_def = (kcdb_identity *)vid; - if(new_def != NULL && (new_def->flags & KCDB_IDENT_FLAG_DEFAULT)) + if (new_def != NULL && (new_def->flags & KCDB_IDENT_FLAG_DEFAULT)) return KHM_ERROR_SUCCESS; - if(new_def == NULL && kcdb_def_identity == NULL) + if ((new_def == NULL && kcdb_def_identity == NULL) || + (new_def == kcdb_def_identity)) return KHM_ERROR_SUCCESS; /* first check with the identity provider if this operation @@ -561,7 +602,7 @@ kcdb_identity_get_config(khm_handle vid, if(kcdb_is_active_identity(vid)) { id = (kcdb_identity *) vid; } else { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } hkcdb = kcdb_get_config(); @@ -609,7 +650,7 @@ kcdb_identity_hold(khm_handle vid) { id = vid; InterlockedIncrement(&(id->refcount)); } else - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; return ERROR_SUCCESS; } @@ -631,7 +672,7 @@ kcdb_identity_release(khm_handle vid) { LeaveCriticalSection(&cs_ident); } } else - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; return ERROR_SUCCESS; } @@ -651,6 +692,7 @@ kcdbint_idref_proc(khm_handle cred, void * r) { if (KHM_SUCCEEDED(kcdb_cred_get_identity(cred, &vid))) { if (result->ident == (kcdb_identity *) vid) { + result->count++; kcdb_cred_get_flags(cred, &flags); @@ -684,12 +726,11 @@ kcdb_identity_refresh(khm_handle vid) { kcdb_identity * ident; khm_int32 code = KHM_ERROR_SUCCESS; struct kcdb_idref_result result; - khm_int32 flags; EnterCriticalSection(&cs_ident); if (!kcdb_is_active_identity(vid)) { - code = KHM_ERROR_INVALID_PARM; + code = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -699,20 +740,20 @@ kcdb_identity_refresh(khm_handle vid) { result.flags = 0; result.count = 0; + LeaveCriticalSection(&cs_ident); + kcdb_credset_apply(NULL, kcdbint_idref_proc, &result); if (result.count == 0) result.flags |= KCDB_IDENT_FLAG_EMPTY; - kcdb_identity_set_flags(vid, result.flags); - kcdb_identity_get_flags(vid, &flags); - flags &= KCDB_IDENT_FLAGMASK_RDWR; - flags &= ~(KCDB_IDENT_FLAG_DEFAULT | - KCDB_IDENT_FLAG_SEARCHABLE); - flags ^= result.flags; - if (flags != 0) - kcdb_identity_set_flags(vid, flags | KCDB_IDENT_FLAG_INVERT); + kcdb_identity_set_flags(vid, result.flags, + KCDB_IDENT_FLAGMASK_RDWR & + ~(KCDB_IDENT_FLAG_DEFAULT | + KCDB_IDENT_FLAG_SEARCHABLE | + KCDB_IDENT_FLAG_STICKY)); + EnterCriticalSection(&cs_ident); ident->refresh_cycle = kcdb_ident_refresh_cycle; _exit: @@ -727,6 +768,7 @@ kcdb_identity_refresh(khm_handle vid) { KHMEXP khm_int32 KHMAPI kcdb_identity_refresh_all(void) { kcdb_identity * ident; + kcdb_identity * next; khm_int32 code = KHM_ERROR_SUCCESS; int hit_count; @@ -744,7 +786,9 @@ kcdb_identity_refresh_all(void) { for (ident = kcdb_identities; ident != NULL; - ident = LNEXT(ident)) { + ident = next) { + + next = LNEXT(ident); if (!kcdb_is_active_identity(ident) || ident->refresh_cycle == kcdb_ident_refresh_cycle) @@ -753,13 +797,16 @@ kcdb_identity_refresh_all(void) { kcdb_identity_hold((khm_handle) ident); LeaveCriticalSection(&cs_ident); + kcdb_identity_refresh((khm_handle) ident); + EnterCriticalSection(&cs_ident); kcdb_identity_release((khm_handle) ident); hit_count++; } + } while (hit_count > 0); LeaveCriticalSection(&cs_ident); @@ -786,7 +833,7 @@ kcdb_identity_set_attr(khm_handle vid, EnterCriticalSection(&cs_ident); if(!kcdb_is_active_identity(vid)) { LeaveCriticalSection(&cs_ident); - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } id = (kcdb_identity *) vid; @@ -798,7 +845,7 @@ kcdb_identity_set_attr(khm_handle vid, if(KHM_FAILED(kcdb_attrib_get_info(attr_id, &attrib))) { LeaveCriticalSection(&cs_ident); - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } #if 0 @@ -828,7 +875,7 @@ kcdb_identity_set_attr(khm_handle vid, if(KHM_FAILED(kcdb_type_get_info(attrib->type, &type))) { LeaveCriticalSection(&cs_ident); kcdb_attrib_release_info(attrib); - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } if(!(type->isValid(buffer,cbbuf))) { @@ -837,7 +884,7 @@ kcdb_identity_set_attr(khm_handle vid, } if((type->dup(buffer, cbbuf, NULL, &cbdest)) != KHM_ERROR_TOO_LONG) { - code = KHM_ERROR_INVALID_PARM; + code = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -869,8 +916,7 @@ _exit: } KHMEXP khm_int32 KHMAPI -kcdb_identity_set_attrib( - khm_handle vid, +kcdb_identity_set_attrib(khm_handle vid, wchar_t * attr_name, void * buffer, khm_size cbbuf) @@ -878,7 +924,7 @@ kcdb_identity_set_attrib( khm_int32 attr_id = -1; if(KHM_FAILED(kcdb_attrib_get_id(attr_name, &attr_id))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; return kcdb_identity_set_attr( vid, @@ -888,8 +934,7 @@ kcdb_identity_set_attrib( } KHMEXP khm_int32 KHMAPI -kcdb_identity_get_attr( - khm_handle vid, +kcdb_identity_get_attr(khm_handle vid, khm_int32 attr_id, khm_int32 * attr_type, void * buffer, @@ -902,7 +947,7 @@ kcdb_identity_get_attr( khm_size slot; if(KHM_FAILED(kcdb_attrib_get_info(attr_id, &attrib))) { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } if(KHM_FAILED(kcdb_type_get_info(attrib->type, &type))) { @@ -916,7 +961,7 @@ kcdb_identity_get_attr( EnterCriticalSection(&cs_ident); if(!kcdb_is_active_identity(vid)) { - code = KHM_ERROR_INVALID_PARM; + code = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -967,8 +1012,7 @@ _exit: } KHMEXP khm_int32 KHMAPI -kcdb_identity_get_attrib( - khm_handle vid, +kcdb_identity_get_attrib(khm_handle vid, wchar_t * attr_name, khm_int32 * attr_type, void * buffer, @@ -979,12 +1023,11 @@ kcdb_identity_get_attrib( if(KHM_FAILED(kcdb_attrib_get_id(attr_name, &attr_id))) return KHM_ERROR_NOT_FOUND; - return kcdb_identity_get_attr( - vid, - attr_id, - attr_type, - buffer, - pcbbuf); + return kcdb_identity_get_attr(vid, + attr_id, + attr_type, + buffer, + pcbbuf); } KHMEXP khm_int32 KHMAPI @@ -1002,7 +1045,7 @@ kcdb_identity_get_attr_string( khm_size slot; if(KHM_FAILED(kcdb_attrib_get_info(attr_id, &attrib))) { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } if(KHM_FAILED(kcdb_type_get_info(attrib->type, &type))) { @@ -1013,7 +1056,7 @@ kcdb_identity_get_attr_string( EnterCriticalSection(&cs_ident); if(!kcdb_is_active_identity(vid)) { - code = KHM_ERROR_INVALID_PARM; + code = KHM_ERROR_INVALID_PARAM; goto _exit; } @@ -1090,6 +1133,7 @@ kcdb_identity_get_attrib_string( /*****************************************/ /* Identity provider interface functions */ +/* NOT called with cs_ident held */ KHMEXP khm_int32 KHMAPI kcdb_identpro_validate_name(const wchar_t * name) { @@ -1139,7 +1183,7 @@ kcdb_identpro_validate_identity(khm_handle identity) khm_handle sub; if(!kcdb_is_active_identity(identity)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_ident); if(kcdb_ident_sub != NULL) { @@ -1237,49 +1281,47 @@ kcdb_identpro_compare_name( const wchar_t * name2) { khm_handle sub; - kcdb_ident_name_xfer namex; - khm_int32 rv = 0; + kcdb_ident_name_xfer namex; + khm_int32 rv = 0; - EnterCriticalSection(&cs_ident); - if(kcdb_ident_sub != NULL) { + EnterCriticalSection(&cs_ident); + if(kcdb_ident_sub != NULL) { sub = kcdb_ident_sub; - } else { + } else { sub = NULL; - /* Generally in kcdb_identpro_* functions we don't emulate - any behavior if the provider is not available, but lacking - a way to make this known, we emulate here */ - rv = wcscmp(name1, name2); - } - LeaveCriticalSection(&cs_ident); + /* Generally in kcdb_identpro_* functions we don't emulate + any behavior if the provider is not available, but lacking + a way to make this known, we emulate here */ + rv = wcscmp(name1, name2); + } + LeaveCriticalSection(&cs_ident); if(sub != NULL) { - ZeroMemory(&namex, sizeof(namex)); - namex.name_src = name1; - namex.name_alt = name2; - - kmq_send_sub_msg( - sub, - KMSG_IDENT, - KMSG_IDENT_COMPARE_NAME, - 0, - (void *) &namex); - - rv = namex.result; - } + ZeroMemory(&namex, sizeof(namex)); + namex.name_src = name1; + namex.name_alt = name2; - return rv; + kmq_send_sub_msg(sub, + KMSG_IDENT, + KMSG_IDENT_COMPARE_NAME, + 0, + (void *) &namex); + + rv = namex.result; + } + + return rv; } KHMEXP khm_int32 KHMAPI -kcdb_identpro_set_default( - khm_handle identity) +kcdb_identpro_set_default(khm_handle identity) { khm_handle sub; khm_int32 rv = KHM_ERROR_SUCCESS; if((identity != NULL) && !kcdb_is_active_identity(identity)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_ident); if(kcdb_ident_sub != NULL) { @@ -1311,7 +1353,7 @@ kcdb_identpro_set_searchable( khm_int32 rv = KHM_ERROR_SUCCESS; if(!kcdb_is_active_identity(identity)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_ident); if(kcdb_ident_sub != NULL) { @@ -1342,7 +1384,7 @@ kcdb_identpro_update(khm_handle identity) khm_int32 rv = KHM_ERROR_SUCCESS; if(!kcdb_is_active_identity(identity)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_ident); if(kcdb_ident_sub != NULL) { @@ -1354,12 +1396,11 @@ kcdb_identpro_update(khm_handle identity) LeaveCriticalSection(&cs_ident); if(sub != NULL) { - rv = kmq_send_sub_msg( - sub, - KMSG_IDENT, - KMSG_IDENT_UPDATE, - 0, - (void *) identity); + rv = kmq_send_sub_msg(sub, + KMSG_IDENT, + KMSG_IDENT_UPDATE, + 0, + (void *) identity); } return rv; @@ -1372,7 +1413,7 @@ kcdb_identpro_notify_create(khm_handle identity) khm_int32 rv = KHM_ERROR_SUCCESS; if(!kcdb_is_active_identity(identity)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_ident); if(kcdb_ident_sub != NULL) { @@ -1439,7 +1480,7 @@ KHMEXP khm_int32 KHMAPI kcdb_identity_enum( if ((name_buf == NULL && pcb_buf == NULL && pn_idents == NULL) || (name_buf != NULL && pcb_buf == NULL)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; eq_flags &= and_flags; @@ -1450,6 +1491,9 @@ KHMEXP khm_int32 KHMAPI kcdb_identity_enum( khm_handle h_idents = NULL; khm_handle h_ident = NULL; + kcdb_checked_config = TRUE; + kcdb_checking_config = TRUE; + h_kcdb = kcdb_get_config(); if (!h_kcdb) goto _config_check_cleanup; @@ -1457,8 +1501,8 @@ KHMEXP khm_int32 KHMAPI kcdb_identity_enum( goto _config_check_cleanup; while(KHM_SUCCEEDED(khc_enum_subspaces(h_idents, - h_ident, - &h_ident))) { + h_ident, + &h_ident))) { wchar_t wname[KCDB_IDENT_MAXCCH_NAME]; khm_size cb; @@ -1470,10 +1514,14 @@ KHMEXP khm_int32 KHMAPI kcdb_identity_enum( &cb))) continue; + LeaveCriticalSection(&cs_ident); + if (KHM_SUCCEEDED(kcdb_identity_create(wname, - KCDB_IDENT_FLAG_CREATE, - &t_id))) + KCDB_IDENT_FLAG_CREATE, + &t_id))) kcdb_identity_release(t_id); + + EnterCriticalSection(&cs_ident); } _config_check_cleanup: @@ -1482,7 +1530,7 @@ KHMEXP khm_int32 KHMAPI kcdb_identity_enum( if (h_idents) khc_close_space(h_idents); - kcdb_checked_config = TRUE; + kcdb_checking_config = FALSE; } for ( id = kcdb_identities; diff --git a/src/windows/identity/kcreddb/identity.h b/src/windows/identity/kcreddb/identity.h index 6c7e26ee8..be0205d96 100644 --- a/src/windows/identity/kcreddb/identity.h +++ b/src/windows/identity/kcreddb/identity.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -38,13 +38,11 @@ typedef struct kcdb_identity_t { khm_int32 refcount; kcdb_buf buf; khm_ui_4 refresh_cycle; - struct kcdb_identity_t * next; - struct kcdb_identity_t * prev; + LDCL(struct kcdb_identity_t); } kcdb_identity; #define KCDB_IDENT_MAGIC 0x31938d4f -extern CRITICAL_SECTION cs_ident; extern hashtable * kcdb_identities_namemap; extern khm_int32 kcdb_n_identities; extern kcdb_identity * kcdb_identities; /* all identities */ diff --git a/src/windows/identity/kcreddb/init.c b/src/windows/identity/kcreddb/init.c index 2df3f3e3f..13ef4da55 100644 --- a/src/windows/identity/kcreddb/init.c +++ b/src/windows/identity/kcreddb/init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/kcreddb/kcreddb.h b/src/windows/identity/kcreddb/kcreddb.h index e5be0f462..e49c750d5 100644 --- a/src/windows/identity/kcreddb/kcreddb.h +++ b/src/windows/identity/kcreddb/kcreddb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -110,12 +110,6 @@ Functions, macros etc. for manipulating identities. \note Only to be used with kcdb_identity_create() */ #define KCDB_IDENT_FLAG_CREATE 0x10000000L -/*! \brief Inverts the accompanying flags. - - \note Only to be used with kcdb_identity_set_flags() - \see kcdb_identity_set_flags() */ -#define KCDB_IDENT_FLAG_INVERT 0x40000000L - /*! \brief Has configuration information Indicates that the identity has persistent configuration @@ -132,12 +126,6 @@ Functions, macros etc. for manipulating identities. no longer have this flag. */ #define KCDB_IDENT_FLAG_ACTIVE 0x02000000L -/*! \brief Sticky identity - - Sticky identities are identities that are always visible in the - credentials display even if no credentials are associated with it. - */ -#define KCDB_IDENT_FLAG_STICKY 0x04000000L /*! \brief The identity has custom attributes assigned */ @@ -237,17 +225,18 @@ Functions, macros etc. for manipulating identities. */ #define KCDB_IDENT_FLAG_CRED_RENEW 0x00000400L -/*! \brief Bit mask for local flags +/*! \brief Sticky identity - Local flags are those local to the KCDB. + Sticky identities are identities that are always visible in the + credentials display even if no credentials are associated with it. */ -#define KCDB_IDENT_FLAGMASK_LOCAL 0x0000ffffL +#define KCDB_IDENT_FLAG_STICKY 0x00000800L /*! \brief Read/write flags mask. A bitmask that correspond to all the read/write flags in the mask. */ -#define KCDB_IDENT_FLAGMASK_RDWR 0x000007ffL +#define KCDB_IDENT_FLAGMASK_RDWR 0x00000fffL /*@}*/ @@ -434,15 +423,10 @@ kcdb_identity_delete(khm_handle id); /*! \brief Set or unset the specified flags in the specified identity. - Only flags that are in KCDB_IDENT_FLAGMASK_RDWR can be specifed - in the flags parameter. The only exception is the - KCDB_IDENT_FLAG_INVERT flag which controls whether the flags are - to be set or reset. - - If the ::KCDB_IDENT_FLAG_INVERT flag is not specified in \a flags, - then any flags set in \a flags will also be set in the identity. - If the ::KCDB_IDENT_FLAG_INVERT is specified, then any flag set in - \a flags will be reset in the identity. + Only flags that are in KCDB_IDENT_FLAGMASK_RDWR can be specifed in + the \a flags parameter or the \a mask parameter. The flags set in + the \a mask parameter of the identity will be set to the + corresponding values in the \a flags parameter. If ::KCDB_IDENT_FLAG_INVALID is set using this function, then the ::KCDB_IDENT_FLAG_VALID will be automatically reset, and vice @@ -459,9 +443,8 @@ kcdb_identity_delete(khm_handle id); - ::KCDB_IDENT_FLAG_SEARCHABLE : Setting this will result in the identity provider getting notified of the change. If the identity provider indicates that searchable flag should not be - set or reset (according to KCDB_IDENT_FLAG_INVERT setting) on - the identity, then kcdb_identity_set_flags() will return an - error. + set or reset on the identity, then kcdb_identity_set_flags() + will return an error. \note kcdb_identity_set_flags() is not atomic. Even if the function returns a failure code, some flags in the identity may @@ -471,7 +454,8 @@ kcdb_identity_delete(khm_handle id); */ KHMEXP khm_int32 KHMAPI kcdb_identity_set_flags(khm_handle id, - khm_int32 flags); + khm_int32 flags, + khm_int32 mask); /*! \brief Return all the flags for the identity @@ -612,6 +596,14 @@ kcdb_identity_get_provider(khm_handle * sub); KHMEXP khm_int32 KHMAPI kcdb_identity_get_type(khm_int32 * ptype); +/*! \brief Returns TRUE if the two identities are equal + + Also returns TRUE if both identities are NULL. + */ +KHMEXP khm_boolean KHMAPI +kcdb_identity_is_equal(khm_handle identity1, + khm_handle identity2); + /*! \brief Set an attribute in an identity by attribute id \param[in] buffer A pointer to a buffer containing the data to @@ -716,7 +708,7 @@ kcdb_identity_get_attrib(khm_handle identity, \retval KHM_ERROR_SUCCESS Success \retval KHM_ERROR_NOT_FOUND The given attribute was either invalid or was not defined for this identity - \retval KHM_ERROR_INVALID_PARM One or more parameters were invalid + \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid \retval KHM_ERROR_TOO_LONG Either \a buffer was NULL or the supplied buffer was insufficient */ @@ -799,7 +791,7 @@ kcdb_identity_get_attrib_string(khm_handle identity, buffer was insufficient. If \a pn_idents was valid, it contains the number of identities. - \retval KHM_ERROR_INVALID_PARM None of the parameters \a name_buf, + \retval KHM_ERROR_INVALID_PARAM None of the parameters \a name_buf, \a pcb_buf and \a pn_idents were supplied, or \a pcb_buf was NULL when \a name_buf was not. @@ -898,6 +890,7 @@ typedef khm_int32 - zero if \a cred1 == \a cred2 - a postive value if \a cred1 > \a cred2 \see kcdb_credset_sort() + \see ::kcdb_credtype */ typedef khm_int32 (KHMAPI *kcdb_cred_comp_func)(khm_handle cred1, @@ -1353,7 +1346,7 @@ kcdb_credset_purge(khm_handle credset); \retval KHM_ERROR_EXIT The supplied function signalled the processing to be aborted. - \retval KHM_ERROR_INVALID_PARM One or more parameters were invalid. + \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid. */ KHMEXP khm_int32 KHMAPI kcdb_credset_apply(khm_handle credset, @@ -1525,6 +1518,13 @@ kcdb_cred_comp_generic(khm_handle cred1, */ #define KCDB_CRED_FLAGMASK_ALL 0x0000ffff +/*! \brief External flags + + These are flags that are provided by the credentials providers. + The other flags are internal to KCDB and should not be modified. + */ +#define KCDB_CRED_FLAGMASK_EXT (KCDB_CRED_FLAG_INITIAL | KCDB_CRED_FLAG_EXPIRED | KCDB_CRED_FLAG_INVALID | KCDB_CRED_FLAG_RENEWABLE) + /*! \brief Bitmask indicating dditive flags Additive flags are special flags which are added to exiting @@ -1748,7 +1748,7 @@ kcdb_cred_get_name(khm_handle cred, \retval KHM_ERROR_SUCCESS Success \retval KHM_ERROR_NOT_FOUND The given attribute was either invalid or was not defined for this credential - \retval KHM_ERROR_INVALID_PARM One or more parameters were invalid + \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid \retval KHM_ERROR_TOO_LONG Either \a buffer was NULL or the supplied buffer was insufficient */ @@ -1972,7 +1972,7 @@ kcdb_creds_is_equal(khm_handle cred1, field was successfully copied to \a s_buf and the size of the buffer used was copied to \a pcb_s_buf. - \retval KHM_ERROR_INVALID_PARM One or more parameters were invalid + \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid \retval KHM_ERROR_TOO_LONG Either \a s_buf was \a NULL or the size indicated by \a pcb_s_buf was too small to contain the string @@ -2088,7 +2088,7 @@ typedef khm_int32 \retval KHM_ERROR_SUCCESS The data was successfully copied. The number of bytes copied is in \a pcb_data_dst - \retval KHM_ERROR_INVALID_PARM One or more parameters is incorrect. + \retval KHM_ERROR_INVALID_PARAM One or more parameters is incorrect. \retval KHM_ERROR_TOO_LONG Either \a data_dst was NULL or the size of the buffer was insufficient. The required size is in \a @@ -2317,7 +2317,7 @@ FtIntervalToString(LPFILETIME data, order in which the \a number \a unit specifications are given and the same unit may be repeated multiple times. - \retval KHM_ERROR_INVALID_PARM The given string was invalid or had + \retval KHM_ERROR_INVALID_PARAM The given string was invalid or had a token that could not be parsed. It can also mean that \a pft was NULL or \a str was NULL. @@ -2443,15 +2443,19 @@ typedef struct tag_kcdb_attrib { khm_int32 flags; /*!< Flags. Combination of \ref kcdb_credattr_flags "attribute flags" */ + khm_int32 type; /*!< Type of the attribute. Must be valid. */ + wchar_t * short_desc; /*!< Short description. (Localized, optional) */ + wchar_t * long_desc; /*!< Long description. (Localized, optional) */ kcdb_attrib_compute_cb compute_cb; /*!< Callback. Required if \a flags specify ::KCDB_ATTR_FLAG_COMPUTED. */ + khm_size compute_min_cbsize; /*!< Minimum number of bytes required to store this attribute. Required @@ -2807,25 +2811,37 @@ typedef struct tag_kcdb_credtype { wchar_t * name; /*!< name (less than KCDB_MAXCB_NAME bytes) */ khm_int32 id; wchar_t * short_desc; /*!< short localized description (less - than KCDB_MAXCB_SHORT_DESC - bytes) */ + than KCDB_MAXCB_SHORT_DESC bytes) */ wchar_t * long_desc; /*!< long localized descriptionn (less - than KCDB_MAXCB_LONG_DESC - bytes) */ + than KCDB_MAXCB_LONG_DESC bytes) */ khm_handle sub; /*!< Subscription for credentials type - hander. This should be a valid - subscription constructed through - a call to - kmq_create_subscription() and - must handle KMSG_CRED messages - that are marked as being sent to - type specific subscriptions. - - The subscription will be - automatically deleted with a call - to kmq_delete_subscription() when - the credentials type is - unregistered.*/ + hander. This should be a valid + subscription constructed through a + call to kmq_create_subscription() + and must handle KMSG_CRED messages + that are marked as being sent to + type specific subscriptions. + + The subscription will be + automatically deleted with a call to + kmq_delete_subscription() when the + credentials type is unregistered.*/ + + kcdb_cred_comp_func is_equal; /*!< Used to as an additional clause + when comparing two credentials for + equality. The function this is + actually a comparison function, it + should return zero if the two + credentials are equal and non-zero + if they are not. The addtional \a + rock parameter is always zero. + + It can be assumed that the identity, + name and credentials have already + been found to be equal among the + credentials and the credential type + is the type that is being + registered.*/ #ifdef _WIN32 HICON icon; @@ -2895,7 +2911,7 @@ typedef struct tag_kcdb_credtype { \retval KHM_ERROR_SUCCESS The credential type was successfully registered. - \retval KHM_ERROR_INVALID_PARM One or more of the parameters were invalid + \retval KHM_ERROR_INVALID_PARAM One or more of the parameters were invalid \retval KHM_ERROR_TOO_LONG One or more of the string fields in \a type exceeded the character limit for that field. @@ -2976,7 +2992,7 @@ kcdb_credtype_unregister(khm_int32 id); \retval KHM_ERROR_TOO_LONG Either \a buf was NULL or the supplied buffer was not large enough. The required size is in \a cbbuf. - \retval KHM_ERROR_INVALID_PARM Invalid parameter. + \retval KHM_ERROR_INVALID_PARAM Invalid parameter. */ KHMEXP khm_int32 KHMAPI kcdb_credtype_get_name(khm_int32 id, @@ -3011,7 +3027,7 @@ kcdb_credtype_get_sub(khm_int32 id); \retval KHM_ERROR_SUCCESS The call succeeded \retval KHM_ERROR_TOO_LONG Either \a buf was NULL or the supplied buffer was insufficient. The required size is specified in \a cbbuf. - \retval KHM_ERROR_INVALID_PARM One or more parameters were invalid. + \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid. */ KHMEXP khm_int32 KHMAPI kcdb_credtype_describe(khm_int32 id, @@ -3119,7 +3135,7 @@ kcdb_buf_get_attrib(khm_handle record, \retval KHM_ERROR_SUCCESS Success \retval KHM_ERROR_NOT_FOUND The given attribute was either invalid or was not defined for this record - \retval KHM_ERROR_INVALID_PARM One or more parameters were invalid + \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid \retval KHM_ERROR_TOO_LONG Either \a buffer was NULL or the supplied buffer was insufficient */ diff --git a/src/windows/identity/kcreddb/kcreddbinternal.h b/src/windows/identity/kcreddb/kcreddbinternal.h index 699954cf0..f7bf4e7bd 100644 --- a/src/windows/identity/kcreddb/kcreddbinternal.h +++ b/src/windows/identity/kcreddb/kcreddbinternal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -57,4 +57,5 @@ void kcdb_init(void); void kcdb_exit(void); khm_handle kcdb_get_config(void); -#endif \ No newline at end of file + +#endif diff --git a/src/windows/identity/kcreddb/kcreddbmain.c b/src/windows/identity/kcreddb/kcreddbmain.c index 796084a99..8f8a01b06 100644 --- a/src/windows/identity/kcreddb/kcreddbmain.c +++ b/src/windows/identity/kcreddb/kcreddbmain.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/kcreddb/type.c b/src/windows/identity/kcreddb/type.c index e41694544..004beb62f 100644 --- a/src/windows/identity/kcreddb/type.c +++ b/src/windows/identity/kcreddb/type.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -46,7 +46,7 @@ khm_int32 KHMAPI kcdb_type_void_toString( size_t cbsize; if(!cb_buf) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cbsize = sizeof(GENERIC_VOID_STR); @@ -87,7 +87,7 @@ khm_int32 KHMAPI kcdb_type_void_dup( khm_size * cbd_dst) { if(!cbd_dst) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; *cbd_dst = 0; @@ -108,12 +108,12 @@ khm_int32 KHMAPI kcdb_type_string_toString( wchar_t * sd; if(!cb_buf) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; sd = (wchar_t *) d; if(FAILED(StringCbLength(sd, KCDB_TYPE_MAXCB, &cbsize))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cbsize += sizeof(wchar_t); @@ -162,7 +162,7 @@ khm_int32 KHMAPI kcdb_type_string_dup( size_t cbsize; if(!cbd_dst) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(cbd_src == KCDB_CBSIZE_AUTO) { cbd_src = KCDB_TYPE_MAXCB; @@ -205,7 +205,7 @@ khm_int32 KHMAPI kcdb_type_date_toString( int today = 0; if(!cb_buf) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; ft = (FILETIME *) d; @@ -355,7 +355,7 @@ KHMEXP khm_int32 KHMAPI FtIntervalToString(LPFILETIME data, wchar_t * buffer, kh wchar_t * t; if(!cb_buf) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; s = *((__int64 *) data) / 10000000i64; m = s / 60; @@ -511,7 +511,7 @@ khm_int32 KHMAPI kcdb_type_int32_toString( wchar_t ibuf[12]; if(!cb_buf) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; StringCbPrintf(ibuf, sizeof(ibuf), L"%d", *((khm_int32 *) d)); StringCbLength(ibuf, sizeof(ibuf), &cbsize); @@ -573,7 +573,7 @@ khm_int32 KHMAPI kcdb_type_int64_toString( wchar_t ibuf[22]; if(!cb_buf) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; StringCbPrintf(ibuf, sizeof(ibuf), L"%I64d", *((__int64 *) d)); StringCbLength(ibuf, sizeof(ibuf), &cbsize); @@ -636,7 +636,7 @@ khm_int32 KHMAPI kcdb_type_data_toString( size_t cbsize; if(!cb_buf) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cbsize = sizeof(GENERIC_DATA_STR); @@ -677,7 +677,7 @@ khm_int32 KHMAPI kcdb_type_data_dup( khm_size * cbd_dst) { if(!cbd_dst) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; *cbd_dst = cbd_src; @@ -712,7 +712,7 @@ void kcdb_type_init(void) hash_string_comp, kcdb_type_add_ref, kcdb_type_del_ref); - kcdb_type_tbl = malloc(sizeof(kcdb_type_i *) * (KCDB_TYPE_MAX_ID + 1)); + kcdb_type_tbl = PMALLOC(sizeof(kcdb_type_i *) * (KCDB_TYPE_MAX_ID + 1)); ZeroMemory(kcdb_type_tbl, sizeof(kcdb_type_i *) * (KCDB_TYPE_MAX_ID + 1)); kcdb_types = NULL; @@ -815,7 +815,7 @@ void kcdb_type_del_ref(const void *key, void *vt) khm_int32 kcdb_type_hold(kcdb_type_i * t) { if(!t) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_type); t->refcount++; @@ -827,7 +827,7 @@ khm_int32 kcdb_type_hold(kcdb_type_i * t) khm_int32 kcdb_type_release(kcdb_type_i * t) { if(!t) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_type); t->refcount--; @@ -840,7 +840,7 @@ khm_int32 kcdb_type_release(kcdb_type_i * t) void kcdb_type_exit(void) { EnterCriticalSection(&cs_type); - free(kcdb_type_tbl); + PFREE(kcdb_type_tbl); /*TODO: free up the individual types */ LeaveCriticalSection(&cs_type); DeleteCriticalSection(&cs_type); @@ -860,8 +860,8 @@ void kcdb_type_check_and_delete(khm_int32 id) LDELETE(&kcdb_types, t); /* must already be out of the hash-table, otherwise refcount should not be zero */ - free(t->type.name); - free(t); + PFREE(t->type.name); + PFREE(t); } LeaveCriticalSection(&cs_type); } @@ -873,7 +873,7 @@ KHMEXP khm_int32 KHMAPI kcdb_type_get_id(wchar_t *name, khm_int32 * id) if(FAILED(StringCbLength(name, KCDB_MAXCB_NAME, &cbsize))) { /* also fails of name is NULL */ - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } EnterCriticalSection(&cs_type); @@ -894,7 +894,7 @@ KHMEXP khm_int32 KHMAPI kcdb_type_get_info(khm_int32 id, kcdb_type ** info) kcdb_type_i * t; if(id < 0 || id > KCDB_TYPE_MAX_ID) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_type); t = kcdb_type_tbl[id]; @@ -922,7 +922,7 @@ KHMEXP khm_int32 KHMAPI kcdb_type_get_name(khm_int32 id, wchar_t * buffer, khm_s kcdb_type_i * t; if(id < 0 || id > KCDB_TYPE_MAX_ID || !cbbuf) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; t = kcdb_type_tbl[id]; @@ -957,25 +957,25 @@ KHMEXP khm_int32 KHMAPI kcdb_type_register(kcdb_type * type, khm_int32 * new_id) !type->isValid || !type->toString || !type->name) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if((type->flags & KCDB_TYPE_FLAG_CB_MIN) && (type->cb_min < 0 || type->cb_min > KCDB_TYPE_MAXCB)) { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } if((type->flags & KCDB_TYPE_FLAG_CB_MAX) && (type->cb_max < 0 || type->cb_max > KCDB_TYPE_MAXCB)) { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } if((type->flags & KCDB_TYPE_FLAG_CB_MIN) && (type->flags & KCDB_TYPE_FLAG_CB_MAX) && (type->cb_max < type->cb_min)) { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } if(FAILED(StringCbLength(type->name, KCDB_MAXCB_NAME, &cbsize))) @@ -988,7 +988,7 @@ KHMEXP khm_int32 KHMAPI kcdb_type_register(kcdb_type * type, khm_int32 * new_id) kcdb_type_get_next_free(&type_id); } else if(type->id < 0 || type->id > KCDB_TYPE_MAX_ID) { LeaveCriticalSection(&cs_type); - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } else if(kcdb_type_tbl[type->id]) { LeaveCriticalSection(&cs_type); return KHM_ERROR_DUPLICATE; @@ -1001,10 +1001,10 @@ KHMEXP khm_int32 KHMAPI kcdb_type_register(kcdb_type * type, khm_int32 * new_id) return KHM_ERROR_NO_RESOURCES; } - t = malloc(sizeof(kcdb_type_i)); + t = PMALLOC(sizeof(kcdb_type_i)); ZeroMemory(t, sizeof(kcdb_type_i)); - t->type.name = malloc(cbsize); + t->type.name = PMALLOC(cbsize); StringCbCopy(t->type.name, cbsize, type->name); t->type.comp = type->comp; @@ -1036,7 +1036,7 @@ KHMEXP khm_int32 KHMAPI kcdb_type_unregister(khm_int32 id) kcdb_type_i * t; if(id < 0 || id > KCDB_TYPE_MAX_ID) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_type); t = kcdb_type_tbl[id]; @@ -1065,7 +1065,7 @@ KHMEXP khm_int32 KHMAPI kcdb_type_get_next_free(khm_int32 * id) int i; if(!id) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; /* do a linear search because this function only gets called a few times */ EnterCriticalSection(&cs_type); @@ -1246,7 +1246,7 @@ KHMEXP khm_int32 KHMAPI IntervalStringToFt(FILETIME * pft, wchar_t * str) } if(!str || FAILED(StringCbLength(str, MAX_IVL_SPECLIST_LEN, &cb))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; b = str; t = 0; @@ -1269,7 +1269,7 @@ KHMEXP khm_int32 KHMAPI IntervalStringToFt(FILETIME * pft, wchar_t * str) b++; if(!*b) /* no unit specified */ - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; e = b; @@ -1282,7 +1282,7 @@ KHMEXP khm_int32 KHMAPI IntervalStringToFt(FILETIME * pft, wchar_t * str) } if(i==MAX_IVL_UNITS) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; t += f * ivspecs[i].mul; diff --git a/src/windows/identity/kcreddb/type.h b/src/windows/identity/kcreddb/type.h index 9d8b52e25..f7ef26ac4 100644 --- a/src/windows/identity/kcreddb/type.h +++ b/src/windows/identity/kcreddb/type.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -213,4 +213,4 @@ khm_int32 KHMAPI kcdb_type_data_dup( void * d_dst, khm_size * cbd_dst); -#endif \ No newline at end of file +#endif diff --git a/src/windows/identity/kherr/kherr.c b/src/windows/identity/kherr/kherr.c index 04b45238b..cc4b9d3cc 100644 --- a/src/windows/identity/kherr/kherr.c +++ b/src/windows/identity/kherr/kherr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -41,10 +41,12 @@ kherr_handler_node * ctx_handlers = NULL; khm_size n_ctx_handlers; khm_size nc_ctx_handlers; -khm_ui_4 ctx_serial = 0; +kherr_serial ctx_serial = 0; #ifdef DEBUG -static void DebugPrintf(wchar_t * fmt, ...) { +#define DEBUG_CONTEXT + +KHMEXP void kherr_debug_printf(wchar_t * fmt, ...) { va_list vl; wchar_t buf[1024]; @@ -56,7 +58,8 @@ static void DebugPrintf(wchar_t * fmt, ...) { #endif KHMEXP void KHMAPI kherr_add_ctx_handler(kherr_ctx_handler h, - khm_int32 filter) { + khm_int32 filter, + kherr_serial serial) { assert(h); @@ -64,17 +67,17 @@ KHMEXP void KHMAPI kherr_add_ctx_handler(kherr_ctx_handler h, if( ctx_handlers == NULL) { nc_ctx_handlers = CTX_ALLOC_INCR; n_ctx_handlers = 0; - ctx_handlers = malloc(sizeof(*ctx_handlers) * nc_ctx_handlers); + ctx_handlers = PMALLOC(sizeof(*ctx_handlers) * nc_ctx_handlers); /* No need to initialize */ } else if (n_ctx_handlers == nc_ctx_handlers) { khm_size new_nc; kherr_handler_node * new_ctxs; new_nc = nc_ctx_handlers + CTX_ALLOC_INCR; - new_ctxs = malloc(sizeof(*new_ctxs) * new_nc); - memmove(new_ctxs, ctx_handlers, n_ctx_handlers); + new_ctxs = PMALLOC(sizeof(*new_ctxs) * new_nc); + memcpy(new_ctxs, ctx_handlers, n_ctx_handlers * sizeof(*new_ctxs)); - free(ctx_handlers); + PFREE(ctx_handlers); ctx_handlers = new_ctxs; nc_ctx_handlers = new_nc; } @@ -87,15 +90,21 @@ KHMEXP void KHMAPI kherr_add_ctx_handler(kherr_ctx_handler h, ctx_handlers[n_ctx_handlers].h = h; ctx_handlers[n_ctx_handlers].filter = filter; + ctx_handlers[n_ctx_handlers].serial = serial; + + n_ctx_handlers++; + LeaveCriticalSection(&cs_error); } -KHMEXP void KHMAPI kherr_remove_ctx_handler(kherr_ctx_handler h) { +KHMEXP void KHMAPI kherr_remove_ctx_handler(kherr_ctx_handler h, + kherr_serial serial) { khm_size i; EnterCriticalSection(&cs_error); for (i=0 ; i < n_ctx_handlers; i++) { - if (ctx_handlers[i].h == h) { + if (ctx_handlers[i].h == h && + ctx_handlers[i].serial == serial) { break; } } @@ -114,9 +123,25 @@ KHMEXP void KHMAPI kherr_remove_ctx_handler(kherr_ctx_handler h) { void notify_ctx_event(enum kherr_ctx_event e, kherr_context * c) { khm_size i; + kherr_ctx_handler h; + for (i=0; iserial)) { + if (IsBadCodePtr((FARPROC) ctx_handlers[i].h)) { + ctx_handlers[i].h = NULL; + } else { + h = ctx_handlers[i].h; + (*h)(e,c); + + /* a context handler is allowed to remove itself + during a callback. It is, however, not allowed to + remove anything else. */ + if (h != ctx_handlers[i].h) + i--; + } + } } } @@ -127,8 +152,8 @@ void attach_this_thread(void) { if (t) return; - t = malloc(sizeof(kherr_thread) + - sizeof(kherr_context *) * THREAD_STACK_SIZE); + t = PMALLOC(sizeof(kherr_thread) + + sizeof(kherr_context *) * THREAD_STACK_SIZE); t->nc_ctx = THREAD_STACK_SIZE; t->n_ctx = 0; t->ctx = (kherr_context **) &t[1]; @@ -145,7 +170,7 @@ void detach_this_thread(void) { for(i=0; i < t->n_ctx; i++) { kherr_release_context(t->ctx[i]); } - free(t); + PFREE(t); TlsSetValue(tls_error, 0); } } @@ -182,13 +207,13 @@ void push_context(kherr_context * c) { cb_new = sizeof(kherr_thread) + sizeof(kherr_context *) * nc_new; - nt = malloc(cb_new); + nt = PMALLOC(cb_new); memcpy(nt, t, sizeof(kherr_thread) + sizeof(kherr_context *) * t->n_ctx); nt->ctx = (kherr_context **) &nt[1]; nt->nc_ctx = nc_new; - free(t); + PFREE(t); t = nt; TlsSetValue(tls_error, t); } @@ -220,10 +245,11 @@ kherr_event * get_empty_event(void) { kherr_event * e; EnterCriticalSection(&cs_error); - if(evt_free_list) + if(evt_free_list) { LPOP(&evt_free_list, &e); - else - e = malloc(sizeof(*e)); + } else { + e = PMALLOC(sizeof(*e)); + } LeaveCriticalSection(&cs_error); ZeroMemory(e, sizeof(*e)); e->severity = KHERR_NONE; @@ -235,61 +261,63 @@ kherr_event * get_empty_event(void) { void free_event_params(kherr_event * e) { if(parm_type(e->p1) == KEPT_STRINGT) { assert((void *) parm_data(e->p1)); - free((void*) parm_data(e->p1)); + PFREE((void*) parm_data(e->p1)); e->p1 = (kherr_param) 0; } if(parm_type(e->p2) == KEPT_STRINGT) { assert((void *) parm_data(e->p2)); - free((void*) parm_data(e->p2)); + PFREE((void*) parm_data(e->p2)); e->p2 = (kherr_param) 0; } if(parm_type(e->p3) == KEPT_STRINGT) { assert((void *) parm_data(e->p3)); - free((void*) parm_data(e->p3)); + PFREE((void*) parm_data(e->p3)); e->p3 = (kherr_param) 0; } if(parm_type(e->p4) == KEPT_STRINGT) { assert((void *) parm_data(e->p4)); - free((void*) parm_data(e->p4)); + PFREE((void*) parm_data(e->p4)); e->p4 = (kherr_param) 0; } } void free_event(kherr_event * e) { + + EnterCriticalSection(&cs_error); + assert(e->magic == KHERR_EVENT_MAGIC); -#ifdef DEBUG - DebugPrintf(L"Freeing event 0x%x\n", e); +#ifdef DEBUG_CONTEXT + kherr_debug_printf(L"Freeing event 0x%x\n", e); if (!(e->flags & KHERR_RF_STR_RESOLVED)) resolve_event_strings(e); if (e->short_desc) - DebugPrintf(L" Desc(S):[%s]\n", e->short_desc); + kherr_debug_printf(L" Desc(S):[%s]\n", e->short_desc); if (e->long_desc) - DebugPrintf(L" Desc(L):[%s]\n", e->long_desc); + kherr_debug_printf(L" Desc(L):[%s]\n", e->long_desc); if (e->suggestion) - DebugPrintf(L" Suggest:[%s]\n", e->suggestion); + kherr_debug_printf(L" Suggest:[%s]\n", e->suggestion); if (e->facility) - DebugPrintf(L" Facility:[%s]\n", e->facility); + kherr_debug_printf(L" Facility:[%s]\n", e->facility); #endif if(e->flags & KHERR_RF_FREE_SHORT_DESC) { assert(e->short_desc); - free((void *) e->short_desc); + PFREE((void *) e->short_desc); } if(e->flags & KHERR_RF_FREE_LONG_DESC) { assert(e->long_desc); - free((void *) e->long_desc); + PFREE((void *) e->long_desc); } if(e->flags & KHERR_RF_FREE_SUGGEST) { assert(e->suggestion); - free((void *) e->suggestion); + PFREE((void *) e->suggestion); } free_event_params(e); ZeroMemory(e, sizeof(e)); - EnterCriticalSection(&cs_error); LPUSH(&evt_free_list, e); LeaveCriticalSection(&cs_error); } @@ -301,7 +329,7 @@ kherr_context * get_empty_context(void) { if(ctx_free_list) LPOP(&ctx_free_list, &c); else { - c = malloc(sizeof(kherr_context)); + c = PMALLOC(sizeof(kherr_context)); } ZeroMemory(c,sizeof(*c)); @@ -325,8 +353,8 @@ void free_context(kherr_context * c) { kherr_event * e; assert(c->magic == KHERR_CONTEXT_MAGIC); -#ifdef DEBUG - DebugPrintf(L"Freeing context 0x%x\n", c); +#ifdef DEBUG_CONTEXT + kherr_debug_printf(L"Freeing context 0x%x\n", c); #endif EnterCriticalSection(&cs_error); @@ -351,12 +379,11 @@ void free_context(kherr_context * c) { LPUSH(&ctx_free_list,c); LeaveCriticalSection(&cs_error); -#ifdef DEBUG - DebugPrintf(L"Done with context 0x%x\n", c); +#ifdef DEBUG_CONTEXT + kherr_debug_printf(L"Done with context 0x%x\n", c); #endif } - void add_event(kherr_context * c, kherr_event * e) { EnterCriticalSection(&cs_error); @@ -466,7 +493,7 @@ static void resolve_string_resource(kherr_event * e, *str = NULL; } else { bytes = (chars + 1) * sizeof(wchar_t); - s = malloc(bytes); + s = PMALLOC(bytes); assert(s); StringCbCopy(s, bytes, tbuf); *str = s; @@ -515,7 +542,7 @@ static void resolve_msg_resource(kherr_event * e, tbuf[--chars] = L'\0'; bytes = (chars + 1) * sizeof(wchar_t); - s = malloc(bytes); + s = PMALLOC(bytes); assert(s); StringCbCopy(s, bytes, tbuf); *str = s; @@ -551,7 +578,7 @@ static void resolve_string(kherr_event * e, (va_list *) args); if ((e->flags & mask) == free_if) { - free((void *) *str); + PFREE((void *) *str); } e->flags &= ~mask; @@ -562,7 +589,7 @@ static void resolve_string(kherr_event * e, wchar_t * s; bytes = (chars + 1) * sizeof(wchar_t); - s = malloc(bytes); + s = PMALLOC(bytes); assert(s); StringCbCopy(s, bytes, tbuf); *str = s; @@ -704,9 +731,7 @@ kherr_report(enum kherr_severity severity, if(!c) { /* the reason why we are doing it this way is because p1..p4, the descriptions and the suggestion may contain allocations - that has to be freed. In terms of performance we are - assuming that this case doesn't happen that much. Har - har */ + that has to be freed. */ free_event(e); e = NULL; } else { @@ -908,7 +933,7 @@ KHMEXP void KHMAPI kherr_push_new_context(khm_int32 flags) kherr_param dup_parm(kherr_param p) { if(parm_type(p) == KEPT_STRINGT) { - wchar_t * d = wcsdup((wchar_t *)parm_data(p)); + wchar_t * d = PWCSDUP((wchar_t *)parm_data(p)); return kherr_val(KEPT_STRINGT, d); } else return p; @@ -1154,7 +1179,7 @@ KHMEXP kherr_param kherr_dup_string(const wchar_t * s) else cb_s += sizeof(wchar_t); - dest = malloc(cb_s); + dest = PMALLOC(cb_s); assert(dest != NULL); dest[0] = L'\0'; diff --git a/src/windows/identity/kherr/kherr.h b/src/windows/identity/kherr/kherr.h index 7ccc6e560..973390f5e 100644 --- a/src/windows/identity/kherr/kherr.h +++ b/src/windows/identity/kherr/kherr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -261,13 +261,16 @@ enum kherr_event_flags { longer considered significant. */ }; +/*! \brief Serial number for error contexts */ +typedef khm_ui_4 kherr_serial; + /*! \brief An error context */ typedef struct tag_kherr_context { khm_int32 magic; /*!< Magic number. Always set to KHERR_CONTEXT_MAGIC */ - khm_ui_4 serial; /*!< Context instance serial number. + kherr_serial serial; /*!< Context instance serial number. Context objects themselves may be reused for different contexts as they are freed and reallocated. @@ -383,7 +386,8 @@ enum kherr_ctx_event { \see kherr_add_ctx_handler() */ -typedef void (*kherr_ctx_handler)(enum kherr_ctx_event, kherr_context *); +typedef void (KHMAPI * kherr_ctx_handler)(enum kherr_ctx_event, + kherr_context *); /*! \brief Add a context event handler @@ -430,9 +434,14 @@ typedef void (*kherr_ctx_handler)(enum kherr_ctx_event, kherr_context *); indication which notifications should be sent to the handler. If a \a filter value of zero is provided, all of the events will be sent to the handler. + + \param[in] serial The serial number of the error context that + should be tracked. If this is zero, all error contexts can + trigger the handler. */ KHMEXP void KHMAPI kherr_add_ctx_handler(kherr_ctx_handler h, - khm_int32 filter); + khm_int32 filter, + kherr_serial serial); /*! \brief Remove a context event handler @@ -440,7 +449,8 @@ KHMEXP void KHMAPI kherr_add_ctx_handler(kherr_ctx_handler h, \see kherr_add_ctx_handler() */ -KHMEXP void KHMAPI kherr_remove_ctx_handler(kherr_ctx_handler h); +KHMEXP void KHMAPI kherr_remove_ctx_handler(kherr_ctx_handler h, + kherr_serial serial); /*! \brief Report an error @@ -962,4 +972,9 @@ KHMEXP void KHMAPI kherr_evaluate_last_event(void); /*@}*/ +/* In debug mode, outputs the formatted string to the debug console */ +#ifdef DEBUG +KHMEXP void kherr_debug_printf(wchar_t * fmt, ...); +#endif + #endif diff --git a/src/windows/identity/kherr/kherrinternal.h b/src/windows/identity/kherr/kherrinternal.h index e91cc3d01..2b43fd7f4 100644 --- a/src/windows/identity/kherr/kherrinternal.h +++ b/src/windows/identity/kherr/kherrinternal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -29,6 +29,7 @@ #include #include +#include #include typedef struct tag_kherr_thread { @@ -40,8 +41,9 @@ typedef struct tag_kherr_thread { #define THREAD_STACK_SIZE 8 typedef struct tag_kherr_handler_node { - khm_int32 filter; + khm_int32 filter; kherr_ctx_handler h; + kherr_serial serial; } kherr_handler_node; #define CTX_ALLOC_INCR 4 diff --git a/src/windows/identity/kherr/kherrmain.c b/src/windows/identity/kherr/kherrmain.c index b108609db..0ae229204 100644 --- a/src/windows/identity/kherr/kherrmain.c +++ b/src/windows/identity/kherr/kherrmain.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/kmm/kmm.c b/src/windows/identity/kmm/kmm.c index af8419fda..5e955953d 100644 --- a/src/windows/identity/kmm/kmm.c +++ b/src/windows/identity/kmm/kmm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -25,13 +25,37 @@ /* $Id$ */ #include +#include -khm_boolean kmm_load_locale_lib(kmm_module_i * m, kmm_module_locale * l) +khm_boolean kmmint_load_locale_lib(kmm_module_i * m, kmm_module_locale * l) { HMODULE h; if(l->filename != NULL) { - h = LoadLibrary(l->filename); + wchar_t path[MAX_PATH]; + DWORD dw; + + /* construct the path name */ + assert(m->h_module != NULL); + + dw = PathIsFileSpec(l->filename); + + assert(dw); + if (!dw) + return FALSE; + + dw = GetModuleFileName(m->h_module, path, ARRAYLENGTH(path)); + assert(dw != 0); + if (dw == 0) + return FALSE; + + PathRemoveFileSpec(path); + dw = PathAppend(path, l->filename); + assert(dw); + if (!dw) + return FALSE; + + h = LoadLibrary(path); if(!h) return FALSE; @@ -41,6 +65,7 @@ khm_boolean kmm_load_locale_lib(kmm_module_i * m, kmm_module_locale * l) LeaveCriticalSection(&cs_kmm); return TRUE; + } else { /* in this case, the language resources are assumed to be in the main module library itself. */ @@ -69,9 +94,9 @@ KHMEXP khm_int32 KHMAPI kmm_set_locale_info(kmm_module module, kmm_module_locale return KHM_ERROR_INVALID_OPERATION; if(!locales || n_locales < 0) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; - f = malloc(n_locales * sizeof(int)); + f = PMALLOC(n_locales * sizeof(int)); if(!f) return KHM_ERROR_UNKNOWN; ZeroMemory(f, sizeof(int) * n_locales); @@ -82,7 +107,7 @@ KHMEXP khm_int32 KHMAPI kmm_set_locale_info(kmm_module module, kmm_module_locale for(i=0; i +#include +#include -kmm_module_i * kmm_get_module_i(wchar_t * name) +kmm_module_i * kmmint_get_module_i(wchar_t * name) { kmm_module_i * m; size_t sz; @@ -39,11 +41,11 @@ kmm_module_i * kmm_get_module_i(wchar_t * name) m = (kmm_module_i *) hash_lookup(hash_modules, (void *) name); if(m == NULL) { - m = malloc(sizeof(kmm_module_i)); + m = PMALLOC(sizeof(kmm_module_i)); ZeroMemory(m, sizeof(kmm_module_i)); m->magic = KMM_MODULE_MAGIC; - m->name = malloc(sz); + m->name = PMALLOC(sz); StringCbCopy(m->name, sz, name); m->state = KMM_MODULE_STATE_NONE; @@ -55,7 +57,7 @@ kmm_module_i * kmm_get_module_i(wchar_t * name) return m; } -kmm_module_i * kmm_find_module_i(wchar_t * name) +kmm_module_i * kmmint_find_module_i(wchar_t * name) { kmm_module_i * m; @@ -67,7 +69,7 @@ kmm_module_i * kmm_find_module_i(wchar_t * name) } /* called with cs_kmm held */ -void kmm_free_module(kmm_module_i * m) +void kmmint_free_module(kmm_module_i * m) { m->magic = 0; @@ -75,14 +77,24 @@ void kmm_free_module(kmm_module_i * m) LDELETE(&kmm_all_modules, m); if (m->name) - free(m->name); + PFREE(m->name); + + if (m->description) + PFREE(m->description); + if (m->path) - free(m->path); + PFREE(m->path); + if (m->vendor) - free(m->vendor); + PFREE(m->vendor); + + if (m->support) + PFREE(m->support); + if (m->version_info) - free(m->version_info); - free(m); + PFREE(m->version_info); + + PFREE(m); if (kmm_all_modules == NULL) SetEvent(evt_exit); @@ -91,7 +103,7 @@ void kmm_free_module(kmm_module_i * m) KHMEXP khm_int32 KHMAPI kmm_hold_module(kmm_module module) { if(!kmm_is_module(module)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_kmm); kmm_module_from_handle(module)->refcount++; LeaveCriticalSection(&cs_kmm); @@ -103,7 +115,7 @@ KHMEXP khm_int32 KHMAPI kmm_release_module(kmm_module vm) { kmm_module_i * m; if(!kmm_is_module(vm)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_kmm); m = kmm_module_from_handle(vm); @@ -111,12 +123,313 @@ KHMEXP khm_int32 KHMAPI kmm_release_module(kmm_module vm) { /* note that a 0 ref count means that there are no active plugins */ - kmm_free_module(m); + kmmint_free_module(m); } LeaveCriticalSection(&cs_kmm); return KHM_ERROR_SUCCESS; } +khm_int32 +kmmint_check_api_version(DWORD v) { + /* for now, we require an exact match. In the future when we are + swamped with so much time that we don't know what to do with + it, we can actually parse the apiversion.txt file and create a + compatibility table which we can check against the functions + used by the module and decide whether or not it is + compatible. */ + + if (v != KH_VERSION_API) + return KHM_ERROR_INCOMPATIBLE; + else + return KHM_ERROR_SUCCESS; +} + +struct lang_code { + WORD language; + WORD codepage; +}; + +khm_int32 +kmmint_read_module_info(kmm_module_i * m) { + /* the only fields we can count on at this point are m->name and + m->path */ + DWORD t; + size_t cb; + WORD lang; + khm_int32 rv = KHM_ERROR_SUCCESS; + struct lang_code *languages; + int n_languages; + int i; + wchar_t resname[256]; /* the resource names are a lot shorter */ + wchar_t * r; + VS_FIXEDFILEINFO *vff; + + assert(m->name); + assert(m->path); + + t = TRUE; + cb = GetFileVersionInfoSize(m->path, + &t); + /* if successful, cb gets the size in bytes of the version info + structure and sets t to zero */ + if (t) { + return KHM_ERROR_NOT_FOUND; + } else if (cb == 0) { + _report_mr1(KHERR_WARNING, MSG_RMI_NOT_FOUND, _dupstr(m->path)); + return KHM_ERROR_INVALID_PARAM; + } + + if (m->version_info) { + PFREE(m->version_info); + m->version_info = NULL; + } + + m->version_info = PMALLOC(cb); +#ifdef DEBUG + assert(m->version_info); +#endif + + if(!GetFileVersionInfo(m->path, + t, (DWORD) cb, m->version_info)) { + rv = KHM_ERROR_NOT_FOUND; + _report_mr1(KHERR_WARNING, MSG_RMI_NOT_FOUND, _dupstr(m->path)); + _location(L"GetFileVersionInfo"); + goto _cleanup; + } + + if(!VerQueryValue(m->version_info, + L"\\VarFileInfo\\Translation", + (LPVOID*) &languages, + &cb)) { + rv = KHM_ERROR_INVALID_PARAM; + _report_mr1(KHERR_WARNING, MSG_RMI_NO_TRANS, _dupstr(m->path)); + _location(L"VerQueryValue"); + goto _cleanup; + } + + n_languages = (int) (cb / sizeof(*languages)); + lang = GetUserDefaultLangID(); + for (i = 0; i < n_languages; i++) { + if(languages[i].language == lang) + break; + } + + if (i >= n_languages) { + lang = GetSystemDefaultLangID(); + for (i=0; i= n_languages) { + rv = KHM_ERROR_INVALID_PARAM; + _report_mr0(KHERR_WARNING, MSG_RMI_NO_LOCAL); + goto _cleanup; + } + + /* check module name */ + StringCbPrintf(resname, sizeof(resname), + L"\\StringFileInfo\\%04x%04x\\" TEXT(NIMV_MODULE), + languages[i].language, + languages[i].codepage); + + if (!VerQueryValue(m->version_info, + resname, (LPVOID *) &r, &cb)) { + rv = KHM_ERROR_INVALID_PARAM; + _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, + _cstr(TEXT(NIMV_MODULE))); + goto _cleanup; + } + + if (cb > KMM_MAXCB_NAME || + FAILED(StringCbLength(r, KMM_MAXCB_NAME, &cb))) { + rv = KHM_ERROR_INVALID_PARAM; + _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG, + _cstr(TEXT(NIMV_MODULE))); + goto _cleanup; + + } + + if (wcscmp(r, m->name)) { + rv = KHM_ERROR_INVALID_PARAM; + _report_mr2(KHERR_WARNING, MSG_RMI_MOD_MISMATCH, + _dupstr(r), _dupstr(m->name)); + goto _cleanup; + } + + /* check API version */ + StringCbPrintf(resname, sizeof(resname), + L"\\StringFileInfo\\%04x%04x\\" TEXT(NIMV_APIVER), + languages[i].language, + languages[i].codepage); + + if (!VerQueryValue(m->version_info, + resname, (LPVOID *) &r, &cb)) { + rv = KHM_ERROR_INVALID_PARAM; + _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, + _cstr(TEXT(NIMV_APIVER))); + goto _cleanup; + } + + if (cb > KMM_MAXCB_NAME || + FAILED(StringCbLength(r, KMM_MAXCB_NAME, &cb))) { + rv = KHM_ERROR_INVALID_PARAM; + _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG, + _cstr(TEXT(NIMV_APIVER))); + goto _cleanup; + } + + t = wcstol(r, NULL, 10); + + rv = kmmint_check_api_version(t); + + if (KHM_FAILED(rv)) { + _report_mr2(KHERR_WARNING, MSG_RMI_API_MISMATCH, + _int32(t), _int32(KH_VERSION_API)); + goto _cleanup; + } + + /* Looks good. Now load the description, copyright, support URI + and file versions */ + if (m->description) { + PFREE(m->description); + m->description = NULL; + } + + StringCbPrintf(resname, sizeof(resname), + L"\\StringFileInfo\\%04x%04x\\FileDescription", + languages[i].language, + languages[i].codepage); + + if (!VerQueryValue(m->version_info, + resname, (LPVOID *) &r, &cb)) { + rv = KHM_ERROR_INVALID_PARAM; + _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, + _cstr(L"FileDescription")); + goto _cleanup; + } + + if (cb > KMM_MAXCB_DESC || + FAILED(StringCbLength(r, KMM_MAXCB_DESC, &cb))) { + rv = KHM_ERROR_INVALID_PARAM; + _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG, + _cstr(L"FileDescription")); + goto _cleanup; + } + + cb += sizeof(wchar_t); + + m->description = PMALLOC(cb); +#ifdef DEBUG + assert(m->description); +#endif + StringCbCopy(m->description, cb, r); + + /* on to the support URI */ + if (m->support) { + PFREE(m->support); + m->support = NULL; + } + + StringCbPrintf(resname, sizeof(resname), + L"\\StringFileInfo\\%04x%04x\\" TEXT(NIMV_SUPPORT), + languages[i].language, + languages[i].codepage); + + if (!VerQueryValue(m->version_info, + resname, (LPVOID *) &r, &cb)) { + rv = KHM_ERROR_INVALID_PARAM; + _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, + _cstr(TEXT(NIMV_SUPPORT))); + goto _cleanup; + } + + if (cb > KMM_MAXCB_SUPPORT || + FAILED(StringCbLength(r, KMM_MAXCB_SUPPORT, &cb))) { + rv = KHM_ERROR_INVALID_PARAM; + _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG, + _cstr(TEXT(NIMV_SUPPORT))); + goto _cleanup; + } + + cb += sizeof(wchar_t); + + m->support = PMALLOC(cb); +#ifdef DEBUG + assert(m->support); +#endif + StringCbCopy(m->support, cb, r); + + /* the vendor/copyright */ + if (m->vendor) { + PFREE(m->vendor); + m->vendor = NULL; + } + + StringCbPrintf(resname, sizeof(resname), + L"\\StringFileInfo\\%04x%04x\\LegalCopyright", + languages[i].language, + languages[i].codepage); + + if (!VerQueryValue(m->version_info, + resname, (LPVOID *) &r, &cb)) { + rv = KHM_ERROR_INVALID_PARAM; + _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, + _cstr(L"LegalCopyright")); + goto _cleanup; + } + + if (cb > KMM_MAXCB_SUPPORT || + FAILED(StringCbLength(r, KMM_MAXCB_SUPPORT, &cb))) { + rv = KHM_ERROR_INVALID_PARAM; + _report_mr1(KHERR_WARNING, MSG_RMI_RES_TOO_LONG, + _cstr(L"LegalCopyright")); + goto _cleanup; + } + + cb += sizeof(wchar_t); + + m->vendor = PMALLOC(cb); +#ifdef DEBUG + assert(m->vendor); +#endif + StringCbCopy(m->vendor, cb, r); + + if (!VerQueryValue(m->version_info, + L"\\", + (LPVOID *) &vff, + &cb) || + cb != sizeof(*vff)) { + + rv = KHM_ERROR_INVALID_PARAM; + _report_mr1(KHERR_WARNING, MSG_RMI_RES_MISSING, + _cstr(L"Fixed Version Info")); + goto _cleanup; + } + + m->file_version.major = HIWORD(vff->dwFileVersionMS); + m->file_version.minor = LOWORD(vff->dwFileVersionMS); + m->file_version.patch = HIWORD(vff->dwFileVersionLS); + m->file_version.aux = LOWORD(vff->dwFileVersionLS); + + m->prod_version.major = HIWORD(vff->dwProductVersionMS); + m->prod_version.minor = LOWORD(vff->dwProductVersionMS); + m->prod_version.patch = HIWORD(vff->dwProductVersionLS); + m->prod_version.aux = LOWORD(vff->dwProductVersionLS); + + rv = KHM_ERROR_SUCCESS; + + _cleanup: + if (KHM_FAILED(rv)) { + if (m->version_info) { + PFREE(m->version_info); + m->version_info = NULL; + } + } + + return rv; +} + KHMEXP khm_int32 KHMAPI kmm_load_module(wchar_t * modname, khm_int32 flags, kmm_module * result) @@ -127,11 +440,11 @@ KHMEXP khm_int32 KHMAPI kmm_load_module(wchar_t * modname, khm_int32 rv = KHM_ERROR_SUCCESS; if(FAILED(StringCbLength(modname, KMM_MAXCB_NAME, &cbsize))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cbsize += sizeof(wchar_t); EnterCriticalSection(&cs_kmm); - mi = kmm_find_module_i(modname); + mi = kmmint_find_module_i(modname); if(mi != NULL) { kmm_hold_module(kmm_handle_from_module(mi)); @@ -158,7 +471,7 @@ KHMEXP khm_int32 KHMAPI kmm_load_module(wchar_t * modname, if(mi) { m = mi; } else { - m = kmm_get_module_i(modname); + m = kmmint_get_module_i(modname); m->state = KMM_MODULE_STATE_PREINIT; kmm_hold_module(kmm_handle_from_module(m)); } @@ -215,7 +528,8 @@ KHMEXP khm_int32 KHMAPI kmm_load_module(wchar_t * modname, return rv; } -KHMEXP khm_int32 KHMAPI kmm_get_module_state(kmm_module m) +KHMEXP khm_int32 KHMAPI +kmm_get_module_state(kmm_module m) { if(!kmm_is_module(m)) return KMM_MODULE_STATE_NONE; @@ -230,7 +544,7 @@ kmm_get_module_info_i(kmm_module vm, kmm_module_info * info) { EnterCriticalSection(&cs_kmm); if (!kmm_is_module(vm) || !info) - rv = KHM_ERROR_INVALID_PARM; + rv = KHM_ERROR_INVALID_PARAM; else { m = kmm_module_from_handle(vm); @@ -265,10 +579,11 @@ kmm_release_module_info_i(kmm_module_info * info) { } -KHMEXP khm_int32 KHMAPI kmm_unload_module(kmm_module module) +KHMEXP khm_int32 KHMAPI +kmm_unload_module(kmm_module module) { if(!kmm_is_module(module)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; kmm_hold_module(module); kmq_post_message(KMSG_KMM, @@ -279,11 +594,11 @@ KHMEXP khm_int32 KHMAPI kmm_unload_module(kmm_module module) return KHM_ERROR_SUCCESS; } -KHMEXP khm_int32 KHMAPI kmm_load_default_modules(void) { +KHMEXP khm_int32 KHMAPI +kmm_load_default_modules(void) { khm_handle csm = NULL; + khm_handle cs_mod = NULL; khm_int32 rv; - wchar_t * ll = NULL; - wchar_t *str; wchar_t buf[KMM_MAXCCH_NAME]; khm_size s; @@ -291,44 +606,35 @@ KHMEXP khm_int32 KHMAPI kmm_load_default_modules(void) { if(KHM_FAILED(rv)) return rv; - _begin_task(KHERR_CF_TRANSITIVE); _report_mr0(KHERR_NONE, MSG_LOAD_DEFAULT); _describe(); - rv = khc_read_multi_string(csm, KMM_VALNAME_LOADLIST, NULL, &s); - if(rv != KHM_ERROR_TOO_LONG) - goto _exit; + kmmint_add_to_module_queue(); + + while(KHM_SUCCEEDED(khc_enum_subspaces(csm, cs_mod, &cs_mod))) { - ll = malloc(s); - rv = khc_read_multi_string(csm, KMM_VALNAME_LOADLIST, ll, &s); - if(KHM_FAILED(rv)) - goto _exit; + s = sizeof(buf); + if (KHM_FAILED(khc_get_config_space_name(cs_mod, buf, &s))) + continue; - kmmint_add_to_module_queue(); + /* check for schema subspace. This is not an actual module. */ + if (!wcscmp(buf, L"_Schema")) + continue; - str = ll; - while(str && *str) { - if(SUCCEEDED(StringCbCopy(buf, sizeof(buf), str))) { - kmm_load_module(buf, 0, NULL); - } - str = multi_string_next(str); + kmm_load_module(buf, 0, NULL); } kmmint_remove_from_module_queue(); -_exit: - if(ll) - free(ll); if(csm) khc_close_space(csm); - _end_task(); - return rv; } #ifdef _WIN32 -KHMEXP HMODULE KHMAPI kmm_get_hmodule(kmm_module m) +KHMEXP HMODULE KHMAPI +kmm_get_hmodule(kmm_module m) { if(!kmm_is_module(m)) return NULL; diff --git a/src/windows/identity/kmm/kmm_plugin.c b/src/windows/identity/kmm/kmm_plugin.c index f37eaa186..b8a90c9fe 100644 --- a/src/windows/identity/kmm/kmm_plugin.c +++ b/src/windows/identity/kmm/kmm_plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -32,7 +32,7 @@ */ kmm_plugin_i * -kmm_get_plugin_i(wchar_t * name) +kmmint_get_plugin_i(wchar_t * name) { kmm_plugin_i * p; size_t cb; @@ -45,15 +45,15 @@ kmm_get_plugin_i(wchar_t * name) p = (kmm_plugin_i *) hash_lookup(hash_plugins, (void *) name); if(p == NULL) { - p = malloc(sizeof(kmm_plugin_i)); + p = PMALLOC(sizeof(kmm_plugin_i)); ZeroMemory(p, sizeof(kmm_plugin_i)); p->magic = KMM_PLUGIN_MAGIC; - p->p.name = malloc(cb); + p->p.name = PMALLOC(cb); StringCbCopy(p->p.name, cb, name); p->state = KMM_PLUGIN_STATE_NONE; hash_add(hash_plugins, (void *) p->p.name, (void *) p); - kmm_list_plugin(p); + kmmint_list_plugin(p); } LeaveCriticalSection(&cs_kmm); @@ -61,7 +61,7 @@ kmm_get_plugin_i(wchar_t * name) } kmm_plugin_i * -kmm_find_plugin_i(wchar_t * name) +kmmint_find_plugin_i(wchar_t * name) { kmm_plugin_i * p; size_t cb; @@ -78,7 +78,7 @@ kmm_find_plugin_i(wchar_t * name) /* the plugin must be delisted before calling this */ void -kmm_list_plugin(kmm_plugin_i * p) +kmmint_list_plugin(kmm_plugin_i * p) { EnterCriticalSection(&cs_kmm); if((p->flags & KMM_PLUGIN_FLAG_IN_MODLIST) || @@ -92,7 +92,7 @@ kmm_list_plugin(kmm_plugin_i * p) } void -kmm_delist_plugin(kmm_plugin_i * p) +kmmint_delist_plugin(kmm_plugin_i * p) { EnterCriticalSection(&cs_kmm); if(p->flags & KMM_PLUGIN_FLAG_IN_LIST) { @@ -112,7 +112,7 @@ kmm_hold_plugin(kmm_plugin p) kmm_plugin_i * pi; if(!kmm_is_plugin(p)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_kmm); pi = kmm_plugin_from_handle(p); @@ -124,14 +124,14 @@ kmm_hold_plugin(kmm_plugin p) /* called with cs_kmm held */ void -kmm_free_plugin(kmm_plugin_i * pi) +kmmint_free_plugin(kmm_plugin_i * pi) { int i; pi->magic = 0; hash_del(hash_plugins, (void *) pi->p.name); - kmm_delist_plugin(pi); + kmmint_delist_plugin(pi); for(i=0; in_dependants; i++) { kmm_release_plugin(kmm_handle_from_plugin(pi->dependants[i])); @@ -146,18 +146,18 @@ kmm_free_plugin(kmm_plugin_i * pi) pi->p.module = NULL; if(pi->p.name) - free(pi->p.name); + PFREE(pi->p.name); pi->p.name = NULL; if(pi->p.description) - free(pi->p.description); + PFREE(pi->p.description); pi->p.description = NULL; if(pi->p.dependencies) - free(pi->p.dependencies); + PFREE(pi->p.dependencies); pi->p.dependencies = NULL; - free(pi); + PFREE(pi); } KHMEXP khm_int32 KHMAPI @@ -167,11 +167,11 @@ kmm_get_plugin_info_i(kmm_plugin p, kmm_plugin_info * info) { khm_handle csp_plugin; if (!info) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_kmm); if (!kmm_is_plugin(p)) { - rv = KHM_ERROR_INVALID_PARM; + rv = KHM_ERROR_INVALID_PARAM; goto _cleanup; } @@ -217,7 +217,7 @@ kmm_release_plugin_info_i(kmm_plugin_info * info) { khm_int32 rv; if (!info || !info->h_plugin) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; rv = kmm_release_plugin(info->h_plugin); @@ -285,13 +285,13 @@ kmm_release_plugin(kmm_plugin p) kmm_plugin_i * pi; if(!kmm_is_plugin(p)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_kmm); pi = kmm_plugin_from_handle(p); pi->refcount--; if(pi->refcount == 0) { - kmm_free_plugin(pi); + kmmint_free_plugin(pi); } LeaveCriticalSection(&cs_kmm); @@ -314,20 +314,22 @@ kmm_provide_plugin(kmm_module module, kmm_plugin_reg * plugin) return KHM_ERROR_INVALID_OPERATION; if(!plugin || - FAILED(StringCbLength(plugin->name, KMM_MAXCB_NAME - sizeof(wchar_t), &cb_name)) || - (plugin->description && - FAILED(StringCbLength(plugin->description, KMM_MAXCB_DESC - sizeof(wchar_t), &cb_desc))) || - (plugin->dependencies && - KHM_FAILED(multi_string_length_cb(plugin->dependencies, KMM_MAXCB_DEPS, &cb_dep))) - ) - { - return KHM_ERROR_INVALID_PARM; + FAILED(StringCbLength(plugin->name, KMM_MAXCB_NAME - sizeof(wchar_t), + &cb_name)) || + (plugin->description && + FAILED(StringCbLength(plugin->description, + KMM_MAXCB_DESC - sizeof(wchar_t), + &cb_desc))) || + (plugin->dependencies && + KHM_FAILED(multi_string_length_cb(plugin->dependencies, + KMM_MAXCB_DEPS, &cb_dep)))) { + return KHM_ERROR_INVALID_PARAM; } cb_name += sizeof(wchar_t); cb_desc += sizeof(wchar_t); - p = kmm_get_plugin_i(plugin->name); + p = kmmint_get_plugin_i(plugin->name); /* released below or in kmm_init_module() */ kmm_hold_plugin(kmm_handle_from_plugin(p)); @@ -348,13 +350,13 @@ kmm_provide_plugin(kmm_module module, kmm_plugin_reg * plugin) p->p.type = plugin->type; if(plugin->description) { - p->p.description = malloc(cb_desc); + p->p.description = PMALLOC(cb_desc); StringCbCopy(p->p.description, cb_desc, plugin->description); } else p->p.description = NULL; if(plugin->dependencies) { - p->p.dependencies = malloc(cb_dep); + p->p.dependencies = PMALLOC(cb_dep); multi_string_copy_cb(p->p.dependencies, cb_dep, plugin->dependencies); } else p->p.dependencies = NULL; @@ -365,7 +367,7 @@ kmm_provide_plugin(kmm_module module, kmm_plugin_reg * plugin) p->state = KMM_PLUGIN_STATE_REG; - kmm_delist_plugin(p); + kmmint_delist_plugin(p); EnterCriticalSection(&cs_kmm); LPUSH(&(m->plugins), p); p->flags |= KMM_PLUGIN_FLAG_IN_MODLIST; diff --git a/src/windows/identity/kmm/kmm_reg.c b/src/windows/identity/kmm/kmm_reg.c index ea13fc19b..131cb7514 100644 --- a/src/windows/identity/kmm/kmm_reg.c +++ b/src/windows/identity/kmm/kmm_reg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -96,7 +96,7 @@ kmm_get_plugin_config(wchar_t * plugin, khm_int32 flags, khm_handle * result) khm_int32 rv; if(!plugin || wcschr(plugin, L'/') || wcschr(plugin, L'\\')) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(KHM_FAILED(kmm_get_plugins_config(flags, &csplugins))) return KHM_ERROR_UNKNOWN; @@ -118,7 +118,7 @@ kmm_get_module_config(wchar_t * module, khm_int32 flags, khm_handle * result) khm_int32 rv; if(!module || wcschr(module, L'/') || wcschr(module, L'\\')) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(KHM_FAILED(kmm_get_modules_config(flags, &csmodules))) return KHM_ERROR_UNKNOWN; @@ -143,14 +143,16 @@ kmm_register_plugin(kmm_plugin_reg * plugin, khm_int32 config_flags) config_flags &= ~KHM_FLAG_CREATE; if((plugin == NULL) || - (plugin->dependencies && - KHM_FAILED(multi_string_length_cch(plugin->dependencies, KMM_MAXCCH_DEPS, &cch))) || - FAILED(StringCchLength(plugin->module, KMM_MAXCCH_NAME - 1, &cch)) || - (plugin->description && - FAILED(StringCchLength(plugin->description, KMM_MAXCCH_DESC - 1, &cch))) || - FAILED(StringCchLength(plugin->name, KMM_MAXCCH_NAME - 1, &cch))) + (plugin->dependencies && + KHM_FAILED(multi_string_length_cch(plugin->dependencies, + KMM_MAXCCH_DEPS, &cch))) || + FAILED(StringCchLength(plugin->module, KMM_MAXCCH_NAME, &cch)) || + (plugin->description && + FAILED(StringCchLength(plugin->description, + KMM_MAXCCH_DESC, &cch))) || + FAILED(StringCchLength(plugin->name, KMM_MAXCCH_NAME, &cch))) { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } /* note that we are retaining the length of the plugin name in @@ -177,10 +179,13 @@ kmm_register_plugin(kmm_plugin_reg * plugin, khm_int32 config_flags) rv = khc_write_string(csp_plugin, L"Description", plugin->description); CKRV; } + if(plugin->dependencies) { - rv = khc_write_multi_string(csp_plugin, L"Dependencies", plugin->dependencies); + rv = khc_write_multi_string(csp_plugin, L"Dependencies", + plugin->dependencies); CKRV; } + rv = khc_write_int32(csp_plugin, L"Type", plugin->type); CKRV; rv = khc_write_int32(csp_plugin, L"Flags", plugin->flags); @@ -198,12 +203,12 @@ kmm_register_plugin(kmm_plugin_reg * plugin, khm_int32 config_flags) cb += cch * sizeof(wchar_t); scb = cb; - pl = malloc(cb); + pl = PMALLOC(cb); - rv = khc_read_multi_string(csp_module, L"PluginList", NULL, &cb); + rv = khc_read_multi_string(csp_module, L"PluginList", pl, &cb); if(KHM_FAILED(rv)) { if(pl) - free(pl); + PFREE(pl); goto _exit; } @@ -212,7 +217,7 @@ kmm_register_plugin(kmm_plugin_reg * plugin, khm_int32 config_flags) rv = khc_write_multi_string(csp_module, L"PluginList", pl); } - free(pl); + PFREE(pl); CKRV; } @@ -236,24 +241,21 @@ kmm_register_module(kmm_module_reg * module, khm_int32 config_flags) int i; if((module == NULL) || - FAILED(StringCchLength(module->name, KMM_MAXCCH_NAME - 1, &cch)) || + FAILED(StringCchLength(module->name, KMM_MAXCCH_NAME, &cch)) || (module->description && - FAILED(StringCchLength(module->description, KMM_MAXCCH_DESC - 1, &cch))) || + FAILED(StringCchLength(module->description, + KMM_MAXCCH_DESC, &cch))) || FAILED(StringCchLength(module->path, MAX_PATH, &cch)) || - (module->n_plugins > 0 && module->plugin_reg_info == NULL)) - { - return KHM_ERROR_INVALID_PARM; + (module->n_plugins > 0 && module->plugin_reg_info == NULL)) { + return KHM_ERROR_INVALID_PARAM; } #define CKRV if(KHM_FAILED(rv)) goto _exit - rv = kmm_get_module_config(module->name, config_flags | KHM_FLAG_CREATE, &csp_module); + rv = kmm_get_module_config(module->name, config_flags | KHM_FLAG_CREATE, + &csp_module); CKRV; - if(module->description) { - rv = khc_write_string(csp_module, L"Description", module->description); - CKRV; - } rv = khc_write_string(csp_module, L"ImagePath", module->path); CKRV; @@ -264,7 +266,7 @@ kmm_register_module(kmm_module_reg * module, khm_int32 config_flags) is loaded for the first time */ for(i=0; in_plugins; i++) { - rv = kmm_register_plugin(module->plugin_reg_info + i, config_flags); + rv = kmm_register_plugin(&(module->plugin_reg_info[i]), config_flags); CKRV; } diff --git a/src/windows/identity/kmm/kmm_registrar.c b/src/windows/identity/kmm/kmm_registrar.c index 3c690f36b..ae94a9ed3 100644 --- a/src/windows/identity/kmm/kmm_registrar.c +++ b/src/windows/identity/kmm/kmm_registrar.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -38,6 +38,9 @@ kmmint_check_completion(void) { InterlockedIncrement(&startup_signal) == 1) { load_done = TRUE; + + /* TODO: check for orphaned plugins */ + kmq_post_message(KMSG_KMM, KMSG_KMM_I_DONE, 0, 0); } } @@ -148,31 +151,35 @@ DWORD WINAPI kmm_plugin_broker(LPVOID lpParameter) p->tid_thread = GetCurrentThreadId(); - rv = (p->p.msg_proc(KMSG_SYSTEM, KMSG_SYSTEM_INIT, 0, (void *) &(p->p))); + if (IsBadCodePtr(p->p.msg_proc)) { + rv = KHM_ERROR_INVALID_PARAM; + } else { + rv = (p->p.msg_proc(KMSG_SYSTEM, KMSG_SYSTEM_INIT, + 0, (void *) &(p->p))); + } /* if it fails to initialize, we exit the plugin */ if(KHM_FAILED(rv)) { - kmmint_remove_from_plugin_queue(); + kmmint_remove_from_plugin_queue(); rv = 1; goto _exit; } /* subscribe to default message classes by plugin type */ - if(p->p.type & KHM_PITYPE_CRED) { + if(p->p.type == KHM_PITYPE_CRED) { kmq_subscribe(KMSG_SYSTEM, p->p.msg_proc); kmq_subscribe(KMSG_KCDB, p->p.msg_proc); kmq_subscribe(KMSG_CRED, p->p.msg_proc); - } - - if(p->p.flags & KHM_PIFLAG_IDENTITY_PROVIDER) { + } else if(p->p.type == KHM_PITYPE_IDENT) { khm_handle h = NULL; + kmq_subscribe(KMSG_SYSTEM, p->p.msg_proc); + kmq_subscribe(KMSG_KCDB, p->p.msg_proc); + kmq_create_subscription(p->p.msg_proc, &h); kcdb_identity_set_provider(h); /* kcdb deletes the subscription when it's done with it */ - } - - if(p->p.type == KHM_PITYPE_CONFIG) { + } else if(p->p.type == KHM_PITYPE_CONFIG) { /*TODO: subscribe to configuration provider messages here */ } @@ -204,17 +211,15 @@ DWORD WINAPI kmm_plugin_broker(LPVOID lpParameter) while(KHM_SUCCEEDED(kmq_dispatch(INFINITE))); /* unsubscribe from default message classes by plugin type */ - if(p->p.type & KHM_PITYPE_CRED) { + if(p->p.type == KHM_PITYPE_CRED) { kmq_unsubscribe(KMSG_SYSTEM, p->p.msg_proc); kmq_unsubscribe(KMSG_KCDB, p->p.msg_proc); kmq_unsubscribe(KMSG_CRED, p->p.msg_proc); - } - - if(p->p.flags & KHM_PIFLAG_IDENTITY_PROVIDER) { + } else if (p->p.type == KHM_PITYPE_IDENT) { + kmq_unsubscribe(KMSG_KCDB, p->p.msg_proc); + kmq_unsubscribe(KMSG_SYSTEM, p->p.msg_proc); kcdb_identity_set_provider(NULL); - } - - if(p->p.type == KHM_PITYPE_CONFIG) { + } else if(p->p.type == KHM_PITYPE_CONFIG) { /*TODO: unsubscribe from configuration provider messages here */ } @@ -224,7 +229,8 @@ _exit: p->state = KMM_PLUGIN_STATE_EXITED; /* the following call will automatically release the plugin */ - kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_EXIT_PLUGIN, (void *) p); + kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, + KMM_REG_EXIT_PLUGIN, (void *) p); TlsSetValue(tls_kmm, (LPVOID) 0); @@ -282,8 +288,7 @@ void kmm_init_plugin(kmm_plugin_i * p) { } if(KHM_FAILED(kmm_get_plugin_config(p->p.name, 0, &csp_plugin)) || - KHM_FAILED(khc_read_int32(csp_plugin, L"Flags", &t))) - { + KHM_FAILED(khc_read_int32(csp_plugin, L"Flags", &t))) { if(KHM_FAILED(kmm_register_plugin(&(p->p), 0))) { _report_mr0(KHERR_ERROR, MSG_IP_NOT_REGISTERED); @@ -329,13 +334,15 @@ void kmm_init_plugin(kmm_plugin_i * p) { wchar_t * d; khm_size sz = 0; - if(khc_read_multi_string(csp_plugin, L"Dependencies", NULL, &sz) != KHM_ERROR_TOO_LONG) + if(khc_read_multi_string(csp_plugin, L"Dependencies", + NULL, &sz) != KHM_ERROR_TOO_LONG) break; - deps = malloc(sz); - if(KHM_FAILED(khc_read_multi_string(csp_plugin, L"Dependencies", deps, &sz))) { + deps = PMALLOC(sz); + if(KHM_FAILED(khc_read_multi_string(csp_plugin, L"Dependencies", + deps, &sz))) { if(deps) - free(deps); + PFREE(deps); break; } @@ -343,14 +350,14 @@ void kmm_init_plugin(kmm_plugin_i * p) { kmm_plugin_i * pd; int i; - pd = kmm_get_plugin_i(d); + 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; in_dependants; i++) { + for(i=0; i < pd->n_dependants; i++) { if(pd->dependants[i] == p) break; } @@ -361,7 +368,7 @@ void kmm_init_plugin(kmm_plugin_i * p) { RaiseException(1, EXCEPTION_NONCONTINUABLE, 0, NULL); } - /* released in kmm_free_plugin() */ + /* released in kmmint_free_plugin() */ kmm_hold_plugin(kmm_handle_from_plugin(p)); pd->dependants[pd->n_dependants] = p; pd->n_dependants++; @@ -378,15 +385,15 @@ void kmm_init_plugin(kmm_plugin_i * p) { p->state = KMM_PLUGIN_STATE_HOLD; } - free(deps); + PFREE(deps); } while(FALSE); LeaveCriticalSection(&cs_kmm); EnterCriticalSection(&cs_kmm); p->module->plugin_count++; - kmm_delist_plugin(p); - kmm_list_plugin(p); + kmmint_delist_plugin(p); + kmmint_list_plugin(p); LeaveCriticalSection(&cs_kmm); if(p->state == KMM_PLUGIN_STATE_HOLD) { @@ -397,13 +404,12 @@ void kmm_init_plugin(kmm_plugin_i * p) { kmmint_add_to_plugin_queue(); - p->ht_thread = CreateThread( - NULL, - 0, - kmm_plugin_broker, - (LPVOID) p, - CREATE_SUSPENDED, - &dummy); + p->ht_thread = CreateThread(NULL, + 0, + kmm_plugin_broker, + (LPVOID) p, + CREATE_SUSPENDED, + &dummy); p->state = KMM_PLUGIN_STATE_INIT; @@ -549,18 +555,19 @@ void kmm_init_module(kmm_module_i * m) { goto _exit; } - if(KHM_SUCCEEDED(khc_read_int32(csp_mod, L"Flags", &i))) { - if(i & KMM_MODULE_FLAG_DISABLED) { - _report_mr0(KHERR_ERROR, MSG_IM_DISABLED); + if(KHM_SUCCEEDED(khc_read_int32(csp_mod, L"Flags", &i)) && + (i & KMM_MODULE_FLAG_DISABLED)) { - m->state = KMM_MODULE_STATE_FAIL_DISABLED; - goto _exit; - } + _report_mr0(KHERR_ERROR, MSG_IM_DISABLED); + + m->state = KMM_MODULE_STATE_FAIL_DISABLED; + goto _exit; } if(KHM_SUCCEEDED(khc_read_int32(csp_mod, L"FailureCount", &i))) { khm_int64 tm; khm_int64 ct; + khm_int32 last_reason = 0; /* reset the failure count if the failure count reset time period has elapsed */ @@ -578,7 +585,13 @@ void kmm_init_module(kmm_module_i * m) { } - if(i > max_fail_count) { + khc_read_int32(csp_mod, L"FailureReason", &last_reason); + + /* did we exceed the max failure count? However, we ignore + the max failure count if the reason why it didn't load the + last time was because the module wasn't found. */ + if(i > max_fail_count && + last_reason != KMM_MODULE_STATE_FAIL_NOT_FOUND) { /* failed too many times */ _report_mr0(KHERR_ERROR, MSG_IM_MAX_FAIL); @@ -587,10 +600,11 @@ void kmm_init_module(kmm_module_i * m) { } } - if(khc_read_string(csp_mod, L"ImagePath", NULL, &sz) == KHM_ERROR_TOO_LONG) { + if(khc_read_string(csp_mod, L"ImagePath", NULL, &sz) == + KHM_ERROR_TOO_LONG) { if(m->path) - free(m->path); - m->path = malloc(sz); + PFREE(m->path); + m->path = PMALLOC(sz); khc_read_string(csp_mod, L"ImagePath", m->path, &sz); } else { _report_mr0(KHERR_ERROR, MSG_IM_NOT_REGISTERED); @@ -599,11 +613,23 @@ void kmm_init_module(kmm_module_i * m) { goto _exit; } - if (khc_read_string(csp_mod, L"Vendor", NULL, &sz) == KHM_ERROR_TOO_LONG) { - if (m->vendor) - free(m->vendor); - m->vendor = malloc(sz); - khc_read_string(csp_mod, L"Vendor", m->vendor, &sz); + rv = kmmint_read_module_info(m); + + if (KHM_FAILED(rv)) { + if (rv == KHM_ERROR_INCOMPATIBLE) { + _report_mr0(KHERR_ERROR, MSG_IM_INCOMPATIBLE); + + m->state = KMM_MODULE_STATE_FAIL_INCOMPAT; + } else if (rv == KHM_ERROR_NOT_FOUND) { + _report_mr1(KHERR_ERROR, MSG_IM_NOT_FOUND, _dupstr(m->path)); + + m->state = KMM_MODULE_STATE_FAIL_NOT_FOUND; + } else { + _report_mr0(KHERR_ERROR, MSG_IM_INVALID_MODULE); + + m->state = KMM_MODULE_STATE_FAIL_INV_MODULE; + } + goto _exit; } /* check again */ @@ -613,11 +639,13 @@ void kmm_init_module(kmm_module_i * m) { goto _exit; } + /* from this point on, we must record any failure codes */ + record_failure = TRUE; + hm = LoadLibrary(m->path); if(!hm) { m->h_module = NULL; m->state = KMM_MODULE_STATE_FAIL_NOT_FOUND; - record_failure = TRUE; _report_mr1(KHERR_ERROR, MSG_IM_NOT_FOUND, _dupstr(m->path)); @@ -628,12 +656,11 @@ void kmm_init_module(kmm_module_i * m) { exit_module */ release_module = FALSE; exit_module = TRUE; - record_failure = TRUE; m->flags |= KMM_MODULE_FLAG_LOADED; m->h_module = hm; - /*TODO: check signatures */ + /* TODO: check signatures */ p_init_module = (init_module_t) GetProcAddress(hm, EXP_INIT_MODULE); @@ -646,7 +673,6 @@ void kmm_init_module(kmm_module_i * m) { m->state = KMM_MODULE_STATE_INIT; - /* call init_module() */ rv = (*p_init_module)(kmm_handle_from_module(m)); @@ -695,7 +721,7 @@ void kmm_init_module(kmm_module_i * m) { ResetEvent(evt_exit); -_exit: + _exit: if(csp_mod) { if(record_failure) { khm_int64 ct; @@ -709,18 +735,18 @@ _exit: GetSystemTimeAsFileTime((LPFILETIME) &ct); khc_write_int64(csp_mod, L"FailureTime", ct); } + + khc_write_int32(csp_mod, L"FailureReason", m->state); } khc_close_space(csp_mod); } + if(csp_mods) khc_close_space(csp_mods); _report_mr2(KHERR_INFO, MSG_IM_MOD_STATE, _dupstr(m->name), _int32(m->state)); - if(release_module) - kmm_release_module(kmm_handle_from_module(m)); - kmmint_remove_from_module_queue(); /* if something went wrong after init_module was called on the @@ -728,6 +754,53 @@ _exit: if(exit_module) kmm_exit_module(m); + if(release_module) + kmm_release_module(kmm_handle_from_module(m)); + + if (kherr_is_error()) { + kherr_context * c; + kherr_event * err_e = NULL; + kherr_event * warn_e = NULL; + kherr_event * e; + + c = kherr_peek_context(); + err_e = kherr_get_err_event(c); + for(e = kherr_get_first_event(c); + e; + e = kherr_get_next_event(e)) { + if (e != err_e && + e->severity == KHERR_WARNING) { + warn_e = e; + break; + } + } + + kherr_evaluate_event(err_e); + if (warn_e) + kherr_evaluate_event(warn_e); + + kherr_clear_error(); + + e = kherr_report(KHERR_ERROR, + (wchar_t *) MSG_IMERR_TITLE, + KHERR_FACILITY, + NULL, + err_e->long_desc, + ((warn_e)? (wchar_t *)MSG_IMERR_SUGGEST: NULL), + KHERR_FACILITY_ID, + KHERR_SUGGEST_NONE, + _cstr(m->name), + ((warn_e)? _cstr(warn_e->long_desc):0), + 0,0, + KHERR_RF_MSG_SHORT_DESC | + ((warn_e)? KHERR_RF_MSG_SUGGEST: 0), + KHERR_HMODULE); + + kherr_evaluate_event(e); + + kherr_release_context(c); + } + _end_task(); } @@ -780,7 +853,8 @@ void kmm_exit_module(kmm_module_i * m) { while(p) { if(p->module == m) { kmm_hold_plugin(kmm_handle_from_plugin(p)); - kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, KMM_REG_EXIT_PLUGIN, (void *) p); + kmq_post_message(KMSG_KMM, KMSG_KMM_I_REG, + KMM_REG_EXIT_PLUGIN, (void *) p); np++; } diff --git a/src/windows/identity/kmm/kmmconfig.csv b/src/windows/identity/kmm/kmmconfig.csv index 93444bdf4..b22e9b205 100644 --- a/src/windows/identity/kmm/kmmconfig.csv +++ b/src/windows/identity/kmm/kmmconfig.csv @@ -9,7 +9,7 @@ PluginManager,KC_SPACE,0,Plugin Manager Configuration Description,KC_STRING,,Description of the plugin Dependencies,KC_STRING,,Multi string of plugin names of plugins that this plugin depends on Type,KC_INT32,0,The type of the plugin - Flags,KC_INT32,0,Flags. Currently unused + Flags,KC_INT32,0,Flags FailureCount,KC_INT32,0,Number of failed loads FailureTime,KC_INT64,0,FILETIME of first failure FailureReason,KC_INT32,0,Reason for first failure. One of the plugin status values. @@ -22,31 +22,24 @@ PluginManager,KC_SPACE,0,Plugin Manager Configuration ModuleMaxFailureCount,KC_INT32,3,Maximum number of failure counts before module is disabled ModuleFailureCountResetTime,KC_INT64,72000,Time after first failure at which the failure count is reset _Schema,KC_SPACE,0,Module schema - ImagePath,KC_STRING,,Path to the DLL - Description,KC_STRING,,Description of the module - Vendor,KC_STRING,,Vendor or copyright string - Flags,KC_INT32,0,Flags. Currently unused. + ImagePath,KC_STRING,,Path to the DLL (including DLL name) + Flags,KC_INT32,0,Flags FailureCount,KC_INT32,0,Number of failed loads FailureTime,KC_INT64,0,FILETIME of first failure - FailureReason,KC_INT32,0,Reason for first failure. One of the module status values. - FileVersion,KC_INT64,0,khm_version of file - ProductVersion,KC_INT64,0,khm_version of product + FailureReason,KC_INT32,0,Reason for last failure. One of the module status values. PluginList,KC_STRING,,List of plugins implemented in the module _Schema,KC_ENDSPACE,0, OpenAFS,KC_SPACE,0,OpenAFS Module ImagePath,KC_STRING,afscred.dll, PluginList,KC_STRING,AfsCred, - Vendor,KC_STRING,OpenAFS.org, OpenAFS,KC_ENDSPACE,0, MITKrb5,KC_SPACE,0,MIT Kerberos V ImagePath,KC_STRING,krb5cred.dll, PluginList,KC_STRING,Krb5Cred, - Vendor,KC_STRING,Massachusetts Institute of Technology, MITKrb5,KC_ENDSPACE,0, MITKrb4,KC_SPACE,0,MIT Kerberos IV ImagePath,KC_STRING,krb4cred.dll, PluginList,KC_STRING,Krb4Cred, - Vendor,KC_STRING,Massachusetts Institute of Technology, MITKrb4,KC_ENDSPACE,0, Modules,KC_ENDSPACE,0, PluginManager,KC_ENDSPACE,0, diff --git a/src/windows/identity/kmm/kmminternal.h b/src/windows/identity/kmm/kmminternal.h index 662eff228..3ef45198e 100644 --- a/src/windows/identity/kmm/kmminternal.h +++ b/src/windows/identity/kmm/kmminternal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -28,6 +28,7 @@ #define __KHIMAIRA_KMMINTERNAL_H #include +#include #include #define KHERR_FACILITY kmm_facility @@ -44,7 +45,6 @@ #include #include - struct kmm_plugin_i_t; /* forward dcl */ typedef struct kmm_module_i_t { @@ -52,8 +52,12 @@ typedef struct kmm_module_i_t { wchar_t * name; wchar_t * path; - + wchar_t * description; wchar_t * vendor; + wchar_t * support; + + khm_version file_version; + khm_version prod_version; HMODULE h_module; @@ -80,22 +84,23 @@ typedef struct kmm_module_i_t { #define kmm_module_from_handle(m) ((kmm_module_i *) m) #define kmm_handle_from_module(m) ((kmm_module) m) -/* the resources have been loaded */ -#define KMM_MODULE_FLAG_RES_LOADED 8 - -/* the signature has been verified */ -#define KMM_MODULE_FLAG_SIG 16 - /* LoadLibrary succeeded for module */ #define KMM_MODULE_FLAG_LOADED 1 /* init_module entry called */ #define KMM_MODULE_FLAG_INITP 2 +/* the resources have been loaded */ +#define KMM_MODULE_FLAG_RES_LOADED 8 + +/* the signature has been verified */ +#define KMM_MODULE_FLAG_SIG 16 + /* the module is disabled by the user (option specifed in configuration) */ #define KMM_MODULE_FLAG_DISABLED 1024 + typedef struct kmm_plugin_i_t { kmm_plugin_reg p; @@ -182,18 +187,36 @@ void kmm_init_module(kmm_module_i * m); void kmm_exit_module(kmm_module_i * m); /* Modules */ -kmm_module_i * kmm_get_module_i(wchar_t * name); -kmm_module_i * kmm_find_module_i(wchar_t * name); -void kmm_free_module(kmm_module_i * m); +kmm_module_i * +kmmint_get_module_i(wchar_t * name); + +kmm_module_i * +kmmint_find_module_i(wchar_t * name); + +void +kmmint_free_module(kmm_module_i * m); + +khm_int32 +kmmint_read_module_info(kmm_module_i * m); /* Plugins */ -kmm_plugin_i * kmm_get_plugin_i(wchar_t * name); -kmm_plugin_i * kmm_find_plugin_i(wchar_t * name); -void kmm_free_plugin(kmm_plugin_i * pi); -void kmm_list_plugin(kmm_plugin_i * p); -void kmm_delist_plugin(kmm_plugin_i * p); +kmm_plugin_i * +kmmint_get_plugin_i(wchar_t * name); + +kmm_plugin_i * +kmmint_find_plugin_i(wchar_t * name); + +void +kmmint_free_plugin(kmm_plugin_i * pi); + +void +kmmint_list_plugin(kmm_plugin_i * p); + +void +kmmint_delist_plugin(kmm_plugin_i * p); -khm_boolean kmm_load_locale_lib(kmm_module_i * m, kmm_module_locale * l); +khm_boolean +kmmint_load_locale_lib(kmm_module_i * m, kmm_module_locale * l); #define KMM_CSNAME_ROOT L"PluginManager" #define KMM_CSNAME_PLUGINS L"Plugins" diff --git a/src/windows/identity/kmm/kmmmain.c b/src/windows/identity/kmm/kmmmain.c index 8ec4bc0a3..6489313f8 100644 --- a/src/windows/identity/kmm/kmmmain.c +++ b/src/windows/identity/kmm/kmmmain.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -96,9 +96,11 @@ KHMEXP void KHMAPI kmm_exit(void) kmm_plugin_i * pn; pn = LNEXT(p); - /* plugins that were never resolved should be kicked off - the list. Flipping the refcount will do that if no - other references exist for the plugin */ + /* plugins that were never resolved should be kicked off the + list. Flipping the refcount will do that if no other + references exist for the plugin. The plugins that were + waiting for unresolved dependencies will automatically get + freed when the placeholders and other plugins get freed. */ if(p->state == KMM_PLUGIN_STATE_PLACEHOLDER) { kmm_hold_plugin(kmm_handle_from_plugin(p)); kmm_release_plugin(kmm_handle_from_plugin(p)); diff --git a/src/windows/identity/kmm/kplugin.h b/src/windows/identity/kmm/kplugin.h index f7489bf4c..99f94f1f4 100644 --- a/src/windows/identity/kmm/kplugin.h +++ b/src/windows/identity/kmm/kplugin.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/kmm/lang/kmm_msgs.mc b/src/windows/identity/kmm/lang/kmm_msgs.mc index 5e88121d1..17bc6b80e 100644 --- a/src/windows/identity/kmm/lang/kmm_msgs.mc +++ b/src/windows/identity/kmm/lang/kmm_msgs.mc @@ -73,6 +73,18 @@ Language=English Module has failed too many times . +MessageId= +SymbolicName=MSG_IM_INVALID_MODULE +Language=English +The DLL containing the module was not of the correct format. +. + +MessageId= +SymbolicName=MSG_IM_INCOMPATIBLE +Language=English +The DLL containing the module was not compatible with this version of NetIDMgr. +. + Messageid= SymbolicName=MSG_IM_NOT_FOUND Language=English @@ -103,6 +115,20 @@ Language=English Module [%1] is in state [%2!d!] . +MessageId= +SymbolicName=MSG_IMERR_TITLE +Language=English +Failed to load module %1!s! +. + +MessageId= +SymbolicName=MSG_IMERR_SUGGEST +Language=English +The following information may help resolve this issue: + +%2!s! +. + MessageId= SymbolicName=MSG_IP_TASK_DESC Language=English @@ -144,3 +170,45 @@ SymbolicName=MSG_IP_EXITING Language=English The plugin [%1] is in error state [%2!d!]. Exiting plugin. . + +MessageId= +SymbolicName=MSG_RMI_NOT_FOUND +Language=English +Can't get file version information for path [%1!s!] +. + +MessageId= +SymbolicName=MSG_RMI_NO_TRANS +Language=English +Can't get version resource tranlations list for path [%1!s!] +. + +MessageId= +SymbolicName=MSG_RMI_NO_LOCAL +Language=English +The list of version translations were empty or did not contain a resource for the current user or system locale. +. + +MessageId= +SymbolicName=MSG_RMI_RES_MISSING +Language=English +Required resource %1!s! missing +. + +MessageId= +SymbolicName=MSG_RMI_MOD_MISMATCH +Language=English +The module name specified in the resource is [%1!s!] while the module name as registered is [%2!s!] +. + +MessageId= +SymbolicName=MSG_RMI_RES_TOO_LONG +Language=English +The resource %1!s! is malformed or too long +. + +MessageId= +SymbolicName=MSG_RMI_API_MISMATCH +Language=English +The module was compile for API version %1!d!. However the current API version is %2!d!. +. diff --git a/src/windows/identity/kmq/consumer.c b/src/windows/identity/kmq/consumer.c index 32072cf63..03519bafd 100644 --- a/src/windows/identity/kmq/consumer.c +++ b/src/windows/identity/kmq/consumer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -44,7 +44,7 @@ kmq_message_ref * kmqint_get_message_ref(void) { LPOP(&kmq_msg_ref_free, &r); if(!r) { - r = malloc(sizeof(kmq_message_ref)); + r = PMALLOC(sizeof(kmq_message_ref)); } ZeroMemory(r, sizeof(kmq_message_ref)); @@ -134,11 +134,20 @@ void kmqint_post(kmq_msg_subscription * s, kmq_message * m, khm_boolean try_send if(try_send && q->thread == GetCurrentThreadId()) { khm_int32 rv; - /* we are sending a message from this thread to this thread. - just call the recipient directly, bypassing the message queue. */ + /* we are sending a message from this thread to this + thread. just call the recipient directly, bypassing + the message queue. */ m->refcount++; m->nSent++; - rv = s->recipient.cb(m->type, m->subtype, m->uparam, m->vparam); + if (IsBadCodePtr(s->recipient.cb)) { + rv = KHM_ERROR_INVALID_OPERATION; + } else { + if (IsBadCodePtr(s->recipient.cb)) + rv = KHM_ERROR_INVALID_OPERATION; + else + rv = s->recipient.cb(m->type, m->subtype, + m->uparam, m->vparam); + } m->refcount--; if(KHM_SUCCEEDED(rv)) m->nCompleted++; @@ -166,26 +175,31 @@ void kmqint_post(kmq_msg_subscription * s, kmq_message * m, khm_boolean try_send else if(s->rcpt_type == KMQ_RCPTTYPE_HWND) { m->refcount++; - if(try_send && GetCurrentThreadId() == GetWindowThreadProcessId(s->recipient.hwnd, NULL)) { - /* kmqint_post does not know whether there are any other messages - waiting to be posted at this point. Hence, simply sending the - message is not the right thing to do as the recipient may - incorrectly assume that the message has completed when - (m->nCompleted + m->nFailed == m->nSent). Therefore, we only - increment nSent after the message is sent. */ - SendMessage(s->recipient.hwnd, KMQ_WM_DISPATCH, m->type, (LPARAM) m); + if(try_send && + GetCurrentThreadId() == GetWindowThreadProcessId(s->recipient.hwnd, + NULL)) { + /* kmqint_post does not know whether there are any other + messages waiting to be posted at this point. Hence, + simply sending the message is not the right thing to do + as the recipient may incorrectly assume that the + message has completed when (m->nCompleted + m->nFailed + == m->nSent). Therefore, we only increment nSent after + the message is sent. */ + SendMessage(s->recipient.hwnd, KMQ_WM_DISPATCH, + m->type, (LPARAM) m); m->nSent++; } else { m->nSent++; - PostMessage(s->recipient.hwnd, KMQ_WM_DISPATCH, m->type, (LPARAM) m); + PostMessage(s->recipient.hwnd, KMQ_WM_DISPATCH, + m->type, (LPARAM) m); } - } + } #endif else { - /* This could either be because we were passed in an invalid subscription - or because we lost a race to a thread that deleted an ad-hoc - subscription. */ + /* This could either be because we were passed in an invalid + subscription or because we lost a race to a thread that + deleted an ad-hoc subscription. */ #ifdef DEBUG assert(FALSE); #else @@ -201,7 +215,7 @@ void kmqint_post(kmq_msg_subscription * s, kmq_message * m, khm_boolean try_send KHMEXP khm_int32 KHMAPI kmq_subscribe_hwnd(khm_int32 type, HWND hwnd) { kmq_msg_subscription * s; - s = malloc(sizeof(kmq_msg_subscription)); + s = PMALLOC(sizeof(kmq_msg_subscription)); LINIT(s); s->queue = NULL; s->rcpt_type = KMQ_RCPTTYPE_HWND; @@ -217,7 +231,7 @@ KHMEXP khm_int32 KHMAPI kmq_subscribe_hwnd(khm_int32 type, HWND hwnd) { KHMEXP khm_int32 KHMAPI kmq_subscribe(khm_int32 type, kmq_callback_t cb) { kmq_msg_subscription * s; - s = malloc(sizeof(kmq_msg_subscription)); + s = PMALLOC(sizeof(kmq_msg_subscription)); LINIT(s); s->queue = kmqint_get_thread_queue(); s->rcpt_type = KMQ_RCPTTYPE_CB; @@ -230,11 +244,12 @@ KHMEXP khm_int32 KHMAPI kmq_subscribe(khm_int32 type, kmq_callback_t cb) { /*! \internal \note Obtains ::cs_kmq_global */ -KHMEXP khm_int32 KHMAPI kmq_create_subscription(kmq_callback_t cb, khm_handle * result) +KHMEXP khm_int32 KHMAPI kmq_create_subscription(kmq_callback_t cb, + khm_handle * result) { kmq_msg_subscription * s; - s = malloc(sizeof(kmq_msg_subscription)); + s = PMALLOC(sizeof(kmq_msg_subscription)); LINIT(s); s->queue = kmqint_get_thread_queue(); s->rcpt_type = KMQ_RCPTTYPE_CB; @@ -261,7 +276,7 @@ KHMEXP khm_int32 KHMAPI kmq_delete_subscription(khm_handle sub) LDELETE(&kmq_adhoc_subs, s); LeaveCriticalSection(&cs_kmq_global); - free(s); + PFREE(s); return KHM_ERROR_SUCCESS; } @@ -275,7 +290,7 @@ KHMEXP khm_int32 KHMAPI kmq_unsubscribe_hwnd(khm_int32 type, HWND hwnd) { s = kmqint_msg_type_del_sub_hwnd(type, hwnd); if(s) - free(s); + PFREE(s); return (s)?KHM_ERROR_SUCCESS:KHM_ERROR_NOT_FOUND; } @@ -288,7 +303,7 @@ KHMEXP khm_int32 KHMAPI kmq_unsubscribe(khm_int32 type, kmq_callback_t cb) { s = kmqint_msg_type_del_sub_cb(type,cb); if(s) - free(s); + PFREE(s); return (s)?KHM_ERROR_SUCCESS:KHM_ERROR_NOT_FOUND; } @@ -357,6 +372,7 @@ KHMEXP LRESULT KHMAPI kmq_wm_dispatch(LPARAM lparm, kmq_callback_t cb) { } /*! \internal + \note Obtains ::cs_kmq_global, kmq_queue::cs, ::cs_kmq_msg_ref, ::cs_kmq_msg, */ KHMEXP khm_int32 KHMAPI kmq_dispatch(kmq_timer timeout) { @@ -367,6 +383,8 @@ KHMEXP khm_int32 KHMAPI kmq_dispatch(kmq_timer timeout) { q = kmqint_get_thread_queue(); + assert(q->wait_o); + hr = WaitForSingleObject(q->wait_o, timeout); if(hr == WAIT_OBJECT_0) { /* signalled */ diff --git a/src/windows/identity/kmq/init.c b/src/windows/identity/kmq/init.c index cb50c5476..f157e6ab2 100644 --- a/src/windows/identity/kmq/init.c +++ b/src/windows/identity/kmq/init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -81,7 +81,7 @@ void kmqint_attach_this_thread(void) { if(!q) { EnterCriticalSection(&cs_kmq_global); - q = malloc(sizeof(kmq_queue)); + q = PMALLOC(sizeof(kmq_queue)); InitializeCriticalSection(&q->cs); q->thread = GetCurrentThreadId(); diff --git a/src/windows/identity/kmq/kmq.h b/src/windows/identity/kmq/kmq.h index 3d596d795..4c8c610cd 100644 --- a/src/windows/identity/kmq/kmq.h +++ b/src/windows/identity/kmq/kmq.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -258,7 +258,7 @@ KHMEXP khm_int32 KHMAPI kmq_exit(void); \see kmq_find_type() and kmq_unregister_type() - \retval KHM_ERROR_INVALID_PARM The \a name parameter was invalid. + \retval KHM_ERROR_INVALID_PARAM The \a name parameter was invalid. \retval KHM_ERROR_EXISTS A message type with that name already exists. \retval KHM_ERROR_NO_RESOURCES Can't register any more message types. \retval KHM_ERROR_SUCCESS The operation succeeded. @@ -725,7 +725,7 @@ KHMEXP khm_boolean KHMAPI kmq_has_completed(kmq_call call); \retval KHM_ERROR_SUCCESS The call completed \retval KHM_ERROR_TIMEOUT The timeout period expired - \retval KHM_ERROR_INVALID_PARM One of the parameters were invalid. + \retval KHM_ERROR_INVALID_PARAM One of the parameters were invalid. */ KHMEXP khm_int32 KHMAPI kmq_wait(kmq_call call, kmq_timer timeout); diff --git a/src/windows/identity/kmq/kmqinternal.h b/src/windows/identity/kmq/kmqinternal.h index c82fb925d..aeaf3366c 100644 --- a/src/windows/identity/kmq/kmqinternal.h +++ b/src/windows/identity/kmq/kmqinternal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -33,6 +33,7 @@ #include #include #include +#include #include #define KMQ_CONF_SPACE_NAME L"KMQ" diff --git a/src/windows/identity/kmq/kmqmain.c b/src/windows/identity/kmq/kmqmain.c index d93403a57..3e8176f1b 100644 --- a/src/windows/identity/kmq/kmqmain.c +++ b/src/windows/identity/kmq/kmqmain.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/kmq/msgtype.c b/src/windows/identity/kmq/msgtype.c index eb44eecf3..62a0133d2 100644 --- a/src/windows/identity/kmq/msgtype.c +++ b/src/windows/identity/kmq/msgtype.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -97,7 +97,7 @@ void kmqint_msg_type_create(int t) { EnterCriticalSection(&cs_kmq_types); if(!msg_types[t]) { kmq_msg_type * mt; - mt = malloc(sizeof(kmq_msg_type)); + mt = PMALLOC(sizeof(kmq_msg_type)); ZeroMemory(mt, sizeof(kmq_msg_type)); mt->id = t; LINIT(mt); @@ -119,8 +119,8 @@ KHMEXP khm_int32 KHMAPI kmq_register_type(wchar_t * name, size_t sz; if(FAILED(StringCbLength(name, KMQ_MAXCB_TYPE_NAME, &sz)) || - sz == 0) - return KHM_ERROR_INVALID_PARM; + sz == 0) + return KHM_ERROR_INVALID_PARAM; sz += sizeof(wchar_t); EnterCriticalSection(&cs_kmq_types); @@ -128,10 +128,17 @@ KHMEXP khm_int32 KHMAPI kmq_register_type(wchar_t * name, if(msg_types[i] == NULL) { if(first_free == 0) first_free = i; + /* continue searching since we might find that this type + is already registered. */ } else { if(msg_types[i]->name != NULL && - !wcscmp(msg_types[i]->name, name)) + !wcscmp(msg_types[i]->name, name)) { + registered = TRUE; + if (new_id) + *new_id = i; + break; + } } } @@ -141,7 +148,7 @@ KHMEXP khm_int32 KHMAPI kmq_register_type(wchar_t * name, rv = KHM_ERROR_NO_RESOURCES; } else { kmqint_msg_type_create(first_free); - msg_types[first_free]->name = malloc(sz); + msg_types[first_free]->name = PMALLOC(sz); StringCbCopy(msg_types[first_free]->name, sz, name); if(new_id != NULL) @@ -172,7 +179,6 @@ KHMEXP khm_int32 KHMAPI kmq_find_type(wchar_t * name, khm_int32 * id) } return KHM_ERROR_NOT_FOUND; - } KHMEXP khm_int32 KHMAPI kmq_unregister_type(khm_int32 id) @@ -180,7 +186,7 @@ KHMEXP khm_int32 KHMAPI kmq_unregister_type(khm_int32 id) khm_int32 rv = KHM_ERROR_SUCCESS; if(id < KMSGBASE_USER || id > KMQ_MSG_TYPE_MAX) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_kmq_types); if(msg_types[id] != NULL) { @@ -240,6 +246,7 @@ void kmqint_msg_type_del_sub(kmq_msg_subscription *s) { LeaveCriticalSection(&cs_kmq_types); } + /*! \internal \brief Deletes a window subscription from a message type \note Obtains ::cs_kmq_types @@ -288,7 +295,9 @@ kmq_msg_subscription * kmqint_msg_type_del_sub_cb(khm_int32 t, kmq_callback_t cb s = msg_types[t]->subs; while(s) { kmq_msg_subscription * n = LNEXT(s); - if(s->rcpt_type == KMQ_RCPTTYPE_CB && s->recipient.cb == cb && s->queue == q) { + if(s->rcpt_type == KMQ_RCPTTYPE_CB && + s->recipient.cb == cb && + s->queue == q) { /*TODO: do more here? */ LDELETE(&msg_types[t]->subs, s); break; @@ -306,6 +315,7 @@ kmq_msg_subscription * kmqint_msg_type_del_sub_cb(khm_int32 t, kmq_callback_t cb */ khm_int32 kmqint_msg_publish(kmq_message * m, khm_boolean try_send) { khm_int32 rv = KHM_ERROR_SUCCESS; + if(msg_types[m->type]) { kmq_msg_type *t; kmq_msg_subscription * s; @@ -341,7 +351,7 @@ khm_int32 kmqint_msg_publish(kmq_message * m, khm_boolean try_send) { khm_int32 kmqint_msg_type_set_handler(khm_int32 type, kmq_msg_completion_handler handler) { if (type == KMSG_SYSTEM) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(!msg_types[type]) kmqint_msg_type_create(type); diff --git a/src/windows/identity/kmq/publisher.c b/src/windows/identity/kmq/publisher.c index 5391844ac..af1f55566 100644 --- a/src/windows/identity/kmq/publisher.c +++ b/src/windows/identity/kmq/publisher.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -33,13 +33,14 @@ kmq_message * msg_active = NULL; /*! \internal \brief Get a message object \note called with ::cs_kmq_msg held */ -kmq_message * kmqint_get_message(void) { +kmq_message * +kmqint_get_message(void) { kmq_message * m; LPOP(&msg_free,&m); if(!m) { /* allocate one */ - m = malloc(sizeof(kmq_message)); + m = PMALLOC(sizeof(kmq_message)); } ZeroMemory((void*)m, sizeof(kmq_message)); @@ -52,7 +53,8 @@ kmq_message * kmqint_get_message(void) { \brief Frees a message object \note called with ::cs_kmq_msg held */ -void kmqint_put_message(kmq_message *m) { +void +kmqint_put_message(kmq_message *m) { int queued; /* we can only free a message if the refcount is zero. Otherwise we have to wait until the call is freed. */ @@ -80,7 +82,9 @@ void kmqint_put_message(kmq_message *m) { /*! \internal \note Obtains ::cs_kmq_msg, ::cs_kmq_types, ::cs_kmq_msg_ref, kmq_queue::cs */ -KHMEXP khm_int32 KHMAPI kmq_send_message(khm_int32 type, khm_int32 subtype, khm_ui_4 uparam, void * blob) { +KHMEXP khm_int32 KHMAPI +kmq_send_message(khm_int32 type, khm_int32 subtype, + khm_ui_4 uparam, void * blob) { kmq_call c; khm_int32 rv = KHM_ERROR_SUCCESS; @@ -100,7 +104,9 @@ KHMEXP khm_int32 KHMAPI kmq_send_message(khm_int32 type, khm_int32 subtype, khm_ /*! \internal \note Obtains ::cs_kmq_msg, ::cs_kmq_types, ::cs_kmq_msg_ref, kmq_queue::cs */ -KHMEXP khm_int32 KHMAPI kmq_post_message(khm_int32 type, khm_int32 subtype, khm_ui_4 uparam, void * blob) { +KHMEXP khm_int32 KHMAPI +kmq_post_message(khm_int32 type, khm_int32 subtype, + khm_ui_4 uparam, void * blob) { return kmqint_post_message_ex(type, subtype, uparam, blob, NULL, FALSE); } @@ -108,7 +114,8 @@ KHMEXP khm_int32 KHMAPI kmq_post_message(khm_int32 type, khm_int32 subtype, khm_ \brief Frees a call \note Obtains ::cs_kmq_msg */ -KHMEXP khm_int32 KHMAPI kmq_free_call(kmq_call call) { +KHMEXP khm_int32 KHMAPI +kmq_free_call(kmq_call call) { kmq_message * m; m = call; @@ -126,13 +133,10 @@ KHMEXP khm_int32 KHMAPI kmq_free_call(kmq_call call) { /*! \internal \note Obtains ::cs_kmq_msg, ::cs_kmq_types, ::cs_kmq_msg_ref, kmq_queue::cs */ -khm_int32 kmqint_post_message_ex( - khm_int32 type, - khm_int32 subtype, - khm_ui_4 uparam, - void * blob, - kmq_call * call, - khm_boolean try_send) { +khm_int32 +kmqint_post_message_ex(khm_int32 type, khm_int32 subtype, khm_ui_4 uparam, + void * blob, kmq_call * call, khm_boolean try_send) +{ kmq_message * m; kherr_context * ctx; @@ -170,7 +174,9 @@ khm_int32 kmqint_post_message_ex( return KHM_ERROR_SUCCESS; } -KHMEXP khm_int32 KHMAPI kmq_post_message_ex(khm_int32 type, khm_int32 subtype, khm_ui_4 uparam, void * blob, kmq_call * call) +KHMEXP khm_int32 KHMAPI +kmq_post_message_ex(khm_int32 type, khm_int32 subtype, + khm_ui_4 uparam, void * blob, kmq_call * call) { return kmqint_post_message_ex(type, subtype, uparam, blob, call, FALSE); } @@ -178,21 +184,19 @@ KHMEXP khm_int32 KHMAPI kmq_post_message_ex(khm_int32 type, khm_int32 subtype, k /*! \internal */ -KHMEXP khm_int32 KHMAPI kmq_post_sub_msg(khm_handle sub, khm_int32 type, khm_int32 subtype, khm_ui_4 uparam, void * vparam) +KHMEXP khm_int32 KHMAPI +kmq_post_sub_msg(khm_handle sub, khm_int32 type, khm_int32 subtype, + khm_ui_4 uparam, void * vparam) { return kmq_post_sub_msg_ex(sub, type, subtype, uparam, vparam, NULL); } /*! \internal */ -khm_int32 kmqint_post_sub_msg_ex( - khm_handle sub, - khm_int32 type, - khm_int32 subtype, - khm_ui_4 uparam, - void * vparam, - kmq_call * call, - khm_boolean try_send) +khm_int32 +kmqint_post_sub_msg_ex(khm_handle sub, khm_int32 type, khm_int32 subtype, + khm_ui_4 uparam, void * vparam, + kmq_call * call, khm_boolean try_send) { kmq_message * m; kherr_context * ctx; @@ -237,20 +241,18 @@ khm_int32 kmqint_post_sub_msg_ex( return KHM_ERROR_SUCCESS; } -KHMEXP khm_int32 KHMAPI kmq_post_sub_msg_ex(khm_handle sub, khm_int32 type, khm_int32 subtype, khm_ui_4 uparam, void * vparam, kmq_call * call) +KHMEXP khm_int32 KHMAPI +kmq_post_sub_msg_ex(khm_handle sub, khm_int32 type, khm_int32 subtype, + khm_ui_4 uparam, void * vparam, kmq_call * call) { - return kmqint_post_sub_msg_ex(sub, type, subtype, uparam, vparam, call, FALSE); + return kmqint_post_sub_msg_ex(sub, type, subtype, + uparam, vparam, call, FALSE); } -khm_int32 kmqint_post_subs_msg_ex( - khm_handle * subs, - khm_size n_subs, - khm_int32 type, - khm_int32 subtype, - khm_ui_4 uparam, - void * vparam, - kmq_call * call, - khm_boolean try_send) +khm_int32 +kmqint_post_subs_msg_ex(khm_handle * subs, khm_size n_subs, khm_int32 type, + khm_int32 subtype, khm_ui_4 uparam, void * vparam, + kmq_call * call, khm_boolean try_send) { kmq_message * m; kherr_context * ctx; @@ -301,49 +303,50 @@ khm_int32 kmqint_post_subs_msg_ex( return KHM_ERROR_SUCCESS; } -KHMEXP khm_int32 KHMAPI kmq_post_subs_msg( - khm_handle * subs, - khm_size n_subs, - khm_int32 type, - khm_int32 subtype, - khm_ui_4 uparam, - void * vparam) +KHMEXP khm_int32 KHMAPI +kmq_post_subs_msg(khm_handle * subs, + khm_size n_subs, + khm_int32 type, + khm_int32 subtype, + khm_ui_4 uparam, + void * vparam) { - return kmqint_post_subs_msg_ex( - subs, - n_subs, - type, - subtype, - uparam, - vparam, - NULL, - FALSE); + return kmqint_post_subs_msg_ex(subs, + n_subs, + type, + subtype, + uparam, + vparam, + NULL, + FALSE); } -KHMEXP khm_int32 KHMAPI kmq_post_subs_msg_ex( - khm_handle * subs, - khm_int32 n_subs, - khm_int32 type, - khm_int32 subtype, - khm_ui_4 uparam, - void * vparam, - kmq_call * call) +KHMEXP khm_int32 KHMAPI +kmq_post_subs_msg_ex(khm_handle * subs, + khm_int32 n_subs, + khm_int32 type, + khm_int32 subtype, + khm_ui_4 uparam, + void * vparam, + kmq_call * call) { - return kmqint_post_subs_msg_ex(subs, n_subs, type, subtype, uparam, vparam, call, FALSE); + return kmqint_post_subs_msg_ex(subs, n_subs, type, subtype, + uparam, vparam, call, FALSE); } -KHMEXP khm_int32 KHMAPI kmq_send_subs_msg( - khm_handle *subs, - khm_int32 n_subs, - khm_int32 type, - khm_int32 subtype, - khm_ui_4 uparam, - void * vparam) +KHMEXP khm_int32 KHMAPI +kmq_send_subs_msg(khm_handle *subs, + khm_int32 n_subs, + khm_int32 type, + khm_int32 subtype, + khm_ui_4 uparam, + void * vparam) { kmq_call c; khm_int32 rv = KHM_ERROR_SUCCESS; - rv = kmqint_post_subs_msg_ex(subs, n_subs, type, subtype, uparam, vparam, &c, TRUE); + rv = kmqint_post_subs_msg_ex(subs, n_subs, type, subtype, + uparam, vparam, &c, TRUE); if(KHM_FAILED(rv)) return rv; @@ -358,7 +361,9 @@ KHMEXP khm_int32 KHMAPI kmq_send_subs_msg( /*! \internal */ -KHMEXP khm_int32 KHMAPI kmq_send_sub_msg(khm_handle sub, khm_int32 type, khm_int32 subtype, khm_ui_4 uparam, void * vparam) +KHMEXP khm_int32 KHMAPI +kmq_send_sub_msg(khm_handle sub, khm_int32 type, khm_int32 subtype, + khm_ui_4 uparam, void * vparam) { kmq_call c; khm_int32 rv = KHM_ERROR_SUCCESS; @@ -379,7 +384,8 @@ KHMEXP khm_int32 KHMAPI kmq_send_sub_msg(khm_handle sub, khm_int32 type, khm_int /*! \internal \note Obtains ::cs_kmq_global, ::cs_kmq_msg, ::cs_kmq_msg_ref, kmq_queue::cs */ -KHMEXP khm_int32 KHMAPI kmq_send_thread_quit_message(kmq_thread_id thread, khm_ui_4 uparam) { +KHMEXP khm_int32 KHMAPI +kmq_send_thread_quit_message(kmq_thread_id thread, khm_ui_4 uparam) { kmq_call c; khm_int32 rv = KHM_ERROR_SUCCESS; @@ -397,7 +403,9 @@ KHMEXP khm_int32 KHMAPI kmq_send_thread_quit_message(kmq_thread_id thread, khm_u /*! \internal \note Obtains ::cs_kmq_global, ::cs_kmq_msg, ::cs_kmq_msg_ref, kmq_queue::cs */ -KHMEXP khm_int32 KHMAPI kmq_post_thread_quit_message(kmq_thread_id thread, khm_ui_4 uparam, kmq_call * call) { +KHMEXP khm_int32 KHMAPI +kmq_post_thread_quit_message(kmq_thread_id thread, + khm_ui_4 uparam, kmq_call * call) { kmq_message * m; kmq_queue * q; @@ -438,15 +446,18 @@ KHMEXP khm_int32 KHMAPI kmq_post_thread_quit_message(kmq_thread_id thread, khm_u } /* TODO:Implement these */ -KHMEXP khm_int32 KHMAPI kmq_get_next_response(kmq_call call, void ** resp) { +KHMEXP khm_int32 KHMAPI +kmq_get_next_response(kmq_call call, void ** resp) { return 0; } -KHMEXP khm_boolean KHMAPI kmq_has_completed(kmq_call call) { +KHMEXP khm_boolean KHMAPI +kmq_has_completed(kmq_call call) { return (call->nCompleted + call->nFailed == call->nSent); } -KHMEXP khm_int32 KHMAPI kmq_wait(kmq_call call, kmq_timer timeout) { +KHMEXP khm_int32 KHMAPI +kmq_wait(kmq_call call, kmq_timer timeout) { kmq_message * m = call; DWORD rv; /*TODO: check for call free */ @@ -458,13 +469,15 @@ KHMEXP khm_int32 KHMAPI kmq_wait(kmq_call call, kmq_timer timeout) { else return KHM_ERROR_TIMEOUT; } else - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } /*! \internal \note Obtains ::cs_kmq_types */ -KHMEXP khm_int32 KHMAPI kmq_set_completion_handler(khm_int32 type, kmq_msg_completion_handler handler) { +KHMEXP khm_int32 KHMAPI +kmq_set_completion_handler(khm_int32 type, + kmq_msg_completion_handler handler) { return kmqint_msg_type_set_handler(type, handler); } diff --git a/src/windows/identity/nidmgrdll/Makefile b/src/windows/identity/nidmgrdll/Makefile index 5d48c2d12..fc2887cc1 100644 --- a/src/windows/identity/nidmgrdll/Makefile +++ b/src/windows/identity/nidmgrdll/Makefile @@ -48,6 +48,7 @@ OBJFILES= \ $(UTILDIR)\hashtable.obj \ $(UTILDIR)\sync.obj \ $(UTILDIR)\mstring.obj \ + $(UTILDIR)\perfstat.obj \ $(KHERRDIR)\kherrmain.obj \ $(KHERRDIR)\kherr.obj \ $(KCONFIGDIR)\kconfigmain.obj \ @@ -95,7 +96,9 @@ RESFILES= \ SDKLIBFILES= \ advapi32.lib \ strsafe.lib \ - comctl32.lib + comctl32.lib \ + shlwapi.lib \ + version.lib $(DLLFILE): $(OBJFILES) $(RESFILES) $(DLLGUILINK) $(LIBFILES) $(SDKLIBFILES) diff --git a/src/windows/identity/nidmgrdll/dllmain.c b/src/windows/identity/nidmgrdll/dllmain.c index f54d4ef72..e54e28137 100644 --- a/src/windows/identity/nidmgrdll/dllmain.c +++ b/src/windows/identity/nidmgrdll/dllmain.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/nidmgrdll/nidmgrdll.rc b/src/windows/identity/nidmgrdll/nidmgrdll.rc index 10870e8c3..26aeaa691 100644 --- a/src/windows/identity/nidmgrdll/nidmgrdll.rc +++ b/src/windows/identity/nidmgrdll/nidmgrdll.rc @@ -25,7 +25,7 @@ /* $Id$ */ #include -#include +#include #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US diff --git a/src/windows/identity/plugins/common/dynimport.c b/src/windows/identity/plugins/common/dynimport.c index cd33813f7..ed5110e66 100644 --- a/src/windows/identity/plugins/common/dynimport.c +++ b/src/windows/identity/plugins/common/dynimport.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2004 Massachusetts Institute of Technology +* Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -134,6 +134,7 @@ DECL_FUNC_PTR(krb5_get_renewed_creds); DECL_FUNC_PTR(krb5_get_default_config_files); DECL_FUNC_PTR(krb5_free_config_files); DECL_FUNC_PTR(krb5_get_default_realm); +DECL_FUNC_PTR(krb5_set_default_realm); DECL_FUNC_PTR(krb5_free_ticket); DECL_FUNC_PTR(krb5_decode_ticket); DECL_FUNC_PTR(krb5_get_host_realm); @@ -152,10 +153,16 @@ DECL_FUNC_PTR(error_message); // Profile functions DECL_FUNC_PTR(profile_init); +DECL_FUNC_PTR(profile_flush); DECL_FUNC_PTR(profile_release); DECL_FUNC_PTR(profile_get_subsection_names); DECL_FUNC_PTR(profile_free_list); DECL_FUNC_PTR(profile_get_string); +DECL_FUNC_PTR(profile_get_values); +DECL_FUNC_PTR(profile_get_relation_names); +DECL_FUNC_PTR(profile_clear_relation); +DECL_FUNC_PTR(profile_add_relation); +DECL_FUNC_PTR(profile_update_relation); DECL_FUNC_PTR(profile_release_string); // Service functions @@ -217,67 +224,68 @@ FUNC_INFO k4_fi[] = { FUNC_INFO k5_fi[] = { MAKE_FUNC_INFO(krb5_change_password), - MAKE_FUNC_INFO(krb5_get_init_creds_opt_init), - MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_tkt_life), - MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_renew_life), - MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_forwardable), - MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_proxiable), - MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_address_list), - MAKE_FUNC_INFO(krb5_get_init_creds_password), - MAKE_FUNC_INFO(krb5_get_prompt_types), - MAKE_FUNC_INFO(krb5_build_principal_ext), - MAKE_FUNC_INFO(krb5_cc_get_name), - MAKE_FUNC_INFO(krb5_cc_resolve), - MAKE_FUNC_INFO(krb5_cc_default), - MAKE_FUNC_INFO(krb5_cc_default_name), - MAKE_FUNC_INFO(krb5_cc_set_default_name), - MAKE_FUNC_INFO(krb5_cc_initialize), - MAKE_FUNC_INFO(krb5_cc_destroy), - MAKE_FUNC_INFO(krb5_cc_close), - MAKE_FUNC_INFO(krb5_cc_copy_creds), - MAKE_FUNC_INFO(krb5_cc_store_cred), - MAKE_FUNC_INFO(krb5_cc_retrieve_cred), - MAKE_FUNC_INFO(krb5_cc_get_principal), - MAKE_FUNC_INFO(krb5_cc_start_seq_get), - MAKE_FUNC_INFO(krb5_cc_next_cred), - MAKE_FUNC_INFO(krb5_cc_end_seq_get), - MAKE_FUNC_INFO(krb5_cc_remove_cred), - MAKE_FUNC_INFO(krb5_cc_set_flags), - // MAKE_FUNC_INFO(krb5_cc_get_type), - MAKE_FUNC_INFO(krb5_free_context), - MAKE_FUNC_INFO(krb5_free_cred_contents), - MAKE_FUNC_INFO(krb5_free_principal), - MAKE_FUNC_INFO(krb5_get_in_tkt_with_password), - MAKE_FUNC_INFO(krb5_init_context), - MAKE_FUNC_INFO(krb5_parse_name), - MAKE_FUNC_INFO(krb5_timeofday), - MAKE_FUNC_INFO(krb5_timestamp_to_sfstring), - MAKE_FUNC_INFO(krb5_unparse_name), - MAKE_FUNC_INFO(krb5_get_credentials), - MAKE_FUNC_INFO(krb5_mk_req), - MAKE_FUNC_INFO(krb5_sname_to_principal), - MAKE_FUNC_INFO(krb5_get_credentials_renew), - MAKE_FUNC_INFO(krb5_free_data), - MAKE_FUNC_INFO(krb5_free_data_contents), - // MAKE_FUNC_INFO(krb5_get_realm_domain), - MAKE_FUNC_INFO(krb5_free_unparsed_name), - MAKE_FUNC_INFO(krb5_os_localaddr), - MAKE_FUNC_INFO(krb5_copy_keyblock_contents), - MAKE_FUNC_INFO(krb5_copy_data), - MAKE_FUNC_INFO(krb5_free_creds), - MAKE_FUNC_INFO(krb5_build_principal), - MAKE_FUNC_INFO(krb5_get_renewed_creds), - MAKE_FUNC_INFO(krb5_free_addresses), - MAKE_FUNC_INFO(krb5_get_default_config_files), - MAKE_FUNC_INFO(krb5_free_config_files), - MAKE_FUNC_INFO(krb5_get_default_realm), - MAKE_FUNC_INFO(krb5_free_ticket), - MAKE_FUNC_INFO(krb5_decode_ticket), - MAKE_FUNC_INFO(krb5_get_host_realm), - MAKE_FUNC_INFO(krb5_free_host_realm), - MAKE_FUNC_INFO(krb5_c_random_make_octets), - MAKE_FUNC_INFO(krb5_free_default_realm), - END_FUNC_INFO + MAKE_FUNC_INFO(krb5_get_init_creds_opt_init), + MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_tkt_life), + MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_renew_life), + MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_forwardable), + MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_proxiable), + MAKE_FUNC_INFO(krb5_get_init_creds_opt_set_address_list), + MAKE_FUNC_INFO(krb5_get_init_creds_password), + MAKE_FUNC_INFO(krb5_get_prompt_types), + MAKE_FUNC_INFO(krb5_build_principal_ext), + MAKE_FUNC_INFO(krb5_cc_get_name), + MAKE_FUNC_INFO(krb5_cc_resolve), + MAKE_FUNC_INFO(krb5_cc_default), + MAKE_FUNC_INFO(krb5_cc_default_name), + MAKE_FUNC_INFO(krb5_cc_set_default_name), + MAKE_FUNC_INFO(krb5_cc_initialize), + MAKE_FUNC_INFO(krb5_cc_destroy), + MAKE_FUNC_INFO(krb5_cc_close), + MAKE_FUNC_INFO(krb5_cc_copy_creds), + MAKE_FUNC_INFO(krb5_cc_store_cred), + MAKE_FUNC_INFO(krb5_cc_retrieve_cred), + MAKE_FUNC_INFO(krb5_cc_get_principal), + MAKE_FUNC_INFO(krb5_cc_start_seq_get), + MAKE_FUNC_INFO(krb5_cc_next_cred), + MAKE_FUNC_INFO(krb5_cc_end_seq_get), + MAKE_FUNC_INFO(krb5_cc_remove_cred), + MAKE_FUNC_INFO(krb5_cc_set_flags), + // MAKE_FUNC_INFO(krb5_cc_get_type), + MAKE_FUNC_INFO(krb5_free_context), + MAKE_FUNC_INFO(krb5_free_cred_contents), + MAKE_FUNC_INFO(krb5_free_principal), + MAKE_FUNC_INFO(krb5_get_in_tkt_with_password), + MAKE_FUNC_INFO(krb5_init_context), + MAKE_FUNC_INFO(krb5_parse_name), + MAKE_FUNC_INFO(krb5_timeofday), + MAKE_FUNC_INFO(krb5_timestamp_to_sfstring), + MAKE_FUNC_INFO(krb5_unparse_name), + MAKE_FUNC_INFO(krb5_get_credentials), + MAKE_FUNC_INFO(krb5_mk_req), + MAKE_FUNC_INFO(krb5_sname_to_principal), + MAKE_FUNC_INFO(krb5_get_credentials_renew), + MAKE_FUNC_INFO(krb5_free_data), + MAKE_FUNC_INFO(krb5_free_data_contents), + // MAKE_FUNC_INFO(krb5_get_realm_domain), + MAKE_FUNC_INFO(krb5_free_unparsed_name), + MAKE_FUNC_INFO(krb5_os_localaddr), + MAKE_FUNC_INFO(krb5_copy_keyblock_contents), + MAKE_FUNC_INFO(krb5_copy_data), + MAKE_FUNC_INFO(krb5_free_creds), + MAKE_FUNC_INFO(krb5_build_principal), + MAKE_FUNC_INFO(krb5_get_renewed_creds), + MAKE_FUNC_INFO(krb5_free_addresses), + MAKE_FUNC_INFO(krb5_get_default_config_files), + MAKE_FUNC_INFO(krb5_free_config_files), + MAKE_FUNC_INFO(krb5_get_default_realm), + MAKE_FUNC_INFO(krb5_set_default_realm), + MAKE_FUNC_INFO(krb5_free_ticket), + MAKE_FUNC_INFO(krb5_decode_ticket), + MAKE_FUNC_INFO(krb5_get_host_realm), + MAKE_FUNC_INFO(krb5_free_host_realm), + MAKE_FUNC_INFO(krb5_c_random_make_octets), + MAKE_FUNC_INFO(krb5_free_default_realm), + END_FUNC_INFO }; FUNC_INFO k524_fi[] = { @@ -288,12 +296,18 @@ FUNC_INFO k524_fi[] = { FUNC_INFO profile_fi[] = { MAKE_FUNC_INFO(profile_init), - MAKE_FUNC_INFO(profile_release), - MAKE_FUNC_INFO(profile_get_subsection_names), - MAKE_FUNC_INFO(profile_free_list), - MAKE_FUNC_INFO(profile_get_string), - MAKE_FUNC_INFO(profile_release_string), - END_FUNC_INFO + MAKE_FUNC_INFO(profile_flush), + MAKE_FUNC_INFO(profile_release), + MAKE_FUNC_INFO(profile_get_subsection_names), + MAKE_FUNC_INFO(profile_free_list), + MAKE_FUNC_INFO(profile_get_string), + MAKE_FUNC_INFO(profile_get_values), + MAKE_FUNC_INFO(profile_get_relation_names), + MAKE_FUNC_INFO(profile_clear_relation), + MAKE_FUNC_INFO(profile_add_relation), + MAKE_FUNC_INFO(profile_update_relation), + MAKE_FUNC_INFO(profile_release_string), + END_FUNC_INFO }; FUNC_INFO ce_fi[] = { diff --git a/src/windows/identity/plugins/common/dynimport.h b/src/windows/identity/plugins/common/dynimport.h index b3ba225a6..99aad9aed 100644 --- a/src/windows/identity/plugins/common/dynimport.h +++ b/src/windows/identity/plugins/common/dynimport.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -247,6 +247,7 @@ extern DECL_FUNC_PTR(krb5_free_addresses); extern DECL_FUNC_PTR(krb5_get_default_config_files); extern DECL_FUNC_PTR(krb5_free_config_files); extern DECL_FUNC_PTR(krb5_get_default_realm); +extern DECL_FUNC_PTR(krb5_set_default_realm); extern DECL_FUNC_PTR(krb5_free_ticket); extern DECL_FUNC_PTR(krb5_decode_ticket); extern DECL_FUNC_PTR(krb5_get_host_realm); @@ -264,10 +265,16 @@ extern DECL_FUNC_PTR(error_message); // Profile functions extern DECL_FUNC_PTR(profile_init); +extern DECL_FUNC_PTR(profile_flush); extern DECL_FUNC_PTR(profile_release); extern DECL_FUNC_PTR(profile_get_subsection_names); extern DECL_FUNC_PTR(profile_free_list); extern DECL_FUNC_PTR(profile_get_string); +extern DECL_FUNC_PTR(profile_get_values); +extern DECL_FUNC_PTR(profile_get_relation_names); +extern DECL_FUNC_PTR(profile_clear_relation); +extern DECL_FUNC_PTR(profile_add_relation); +extern DECL_FUNC_PTR(profile_update_relation); extern DECL_FUNC_PTR(profile_release_string); // Service functions diff --git a/src/windows/identity/plugins/common/krb5common.c b/src/windows/identity/plugins/common/krb5common.c index 5501a1206..6019c928e 100644 --- a/src/windows/identity/plugins/common/krb5common.c +++ b/src/windows/identity/plugins/common/krb5common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -25,9 +25,12 @@ /* $Id$ */ #include -#include -#include +#include #include +#include +#ifdef DEBUG +#include +#endif /**************************************/ /* khm_krb5_error(): */ @@ -94,15 +97,14 @@ khm_krb5_initialize(khm_handle ident, if (pkrb5_init_context == NULL) return 1; - if (*ctx == 0 && (rc = (*pkrb5_init_context)(ctx))) - { + if (*ctx == 0 && (rc = (*pkrb5_init_context)(ctx))) { functionName = "krb5_init_context()"; freeContextFlag = 0; goto on_error; } if(*cache == 0) { - wchar_t wccname[256]; + wchar_t wccname[MAX_PATH]; khm_size cbwccname; if(ident != NULL) { @@ -110,8 +112,21 @@ khm_krb5_initialize(khm_handle ident, do { char ccname[256]; - if(KHM_FAILED(kcdb_identity_get_attrib(ident, L"Krb5CCName", NULL, wccname, &cbwccname))) - break; + if(KHM_FAILED(kcdb_identity_get_attrib(ident, L"Krb5CCName", + NULL, wccname, + &cbwccname))) { + cbwccname = sizeof(wccname); + if (KHM_FAILED + (khm_krb5_find_ccache_for_identity(ident, + ctx, + wccname, + &cbwccname))) { +#ifdef DEBUG_LIKE_A_MADMAN + assert(FALSE); +#endif + break; + } + } if(UnicodeStrToAnsi(ccname, sizeof(ccname), wccname) == 0) break; @@ -124,8 +139,11 @@ khm_krb5_initialize(khm_handle ident, } while(FALSE); } - if (*cache == 0 && (rc = (*pkrb5_cc_default)(*ctx, cache))) - { + if (*cache == 0 +#ifdef FAILOVER_TO_DEFAULT_CCACHE + && (rc = (*pkrb5_cc_default)(*ctx, cache)) +#endif + ) { functionName = "krb5_cc_default()"; freeContextFlag = 1; goto on_error; @@ -141,8 +159,7 @@ khm_krb5_initialize(khm_handle ident, if (rc != KRB5_FCC_NOFILE && rc != KRB5_CC_NOTFOUND) khm_krb5_error(rc, "krb5_cc_set_flags()", 0, ctx, cache); - else if ((rc == KRB5_FCC_NOFILE || rc == KRB5_CC_NOTFOUND) && *ctx != NULL) - { + else if ((rc == KRB5_FCC_NOFILE || rc == KRB5_CC_NOTFOUND) && *ctx != NULL) { if (*cache != NULL) (*pkrb5_cc_close)(*ctx, *cache); } @@ -154,3 +171,267 @@ on_error: return khm_krb5_error(rc, functionName, freeContextFlag, ctx, cache); #endif //!NO_KRB5 } + +#define TIMET_TOLERANCE (60*5) + +khm_int32 KHMAPI +khm_get_identity_expiration_time(krb5_context ctx, krb5_ccache cc, + khm_handle ident, + krb5_timestamp * pexpiration) +{ + krb5_principal principal = 0; + char * princ_name = NULL; + krb5_creds creds; + krb5_error_code code; + krb5_error_code cc_code; + krb5_cc_cursor cur; + krb5_timestamp now, expiration = 0; + + wchar_t w_ident_name[KCDB_IDENT_MAXCCH_NAME]; + char ident_name[KCDB_IDENT_MAXCCH_NAME]; + khm_size cb; + + khm_int32 rv = KHM_ERROR_NOT_FOUND; + + if (!ctx || !cc || !ident || !pexpiration) + return KHM_ERROR_GENERAL; + + code = pkrb5_cc_get_principal(ctx, cc, &principal); + + if ( code ) + return KHM_ERROR_INVALID_PARAM; + + cb = sizeof(w_ident_name); + kcdb_identity_get_name(ident, w_ident_name, &cb); + UnicodeStrToAnsi(ident_name, sizeof(ident_name), w_ident_name); + + code = pkrb5_unparse_name(ctx, principal, &princ_name); + + /* compare principal to ident. */ + + if ( code || !princ_name || + strcmp(princ_name, ident_name) ) { + if (princ_name) + pkrb5_free_unparsed_name(ctx, princ_name); + pkrb5_free_principal(ctx, principal); + return KHM_ERROR_UNKNOWN; + } + + pkrb5_free_unparsed_name(ctx, princ_name); + pkrb5_free_principal(ctx, principal); + + code = pkrb5_timeofday(ctx, &now); + + if (code) + return KHM_ERROR_UNKNOWN; + + cc_code = pkrb5_cc_start_seq_get(ctx, cc, &cur); + + while (!(cc_code = pkrb5_cc_next_cred(ctx, cc, &cur, &creds))) { + krb5_data * c0 = krb5_princ_name(ctx, creds.server); + krb5_data * c1 = krb5_princ_component(ctx, creds.server, 1); + krb5_data * r = krb5_princ_realm(ctx, creds.server); + + if ( c0 && c1 && r && c1->length == r->length && + !strncmp(c1->data,r->data,r->length) && + !strncmp("krbtgt",c0->data,c0->length) ) { + + /* we have a TGT, check for the expiration time. + * if it is valid and renewable, use the renew time + */ + + if (!(creds.ticket_flags & TKT_FLG_INVALID) && + creds.times.starttime < (now + TIMET_TOLERANCE) && + (creds.times.endtime + TIMET_TOLERANCE) > now) { + expiration = creds.times.endtime; + + if ((creds.ticket_flags & TKT_FLG_RENEWABLE) && + (creds.times.renew_till > creds.times.endtime)) { + expiration = creds.times.renew_till; + } + } + } + } + + if (cc_code == KRB5_CC_END) { + cc_code = pkrb5_cc_end_seq_get(ctx, cc, &cur); + rv = KHM_ERROR_SUCCESS; + *pexpiration = expiration; + } + + return rv; +} + +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; + + 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; + } + + 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; +} diff --git a/src/windows/identity/plugins/common/krb5common.h b/src/windows/identity/plugins/common/krb5common.h index 7d998215a..bd6337192 100644 --- a/src/windows/identity/plugins/common/krb5common.h +++ b/src/windows/identity/plugins/common/krb5common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -38,6 +38,15 @@ int khm_krb5_error(krb5_error_code rc, LPCSTR FailedFunctionName, int khm_krb5_initialize(khm_handle ident, krb5_context *, krb5_ccache *); + +khm_int32 KHMAPI +khm_krb5_find_ccache_for_identity(khm_handle ident, krb5_context *pctx, + void * buffer, khm_size * pcbbuf); + +khm_int32 KHMAPI +khm_get_identity_expiration_time(krb5_context ctx, krb5_ccache cc, + khm_handle ident, + krb5_timestamp * pexpiration); #endif /* NO_KRB5 */ -#endif \ No newline at end of file +#endif diff --git a/src/windows/identity/plugins/krb4/Makefile b/src/windows/identity/plugins/krb4/Makefile index d6b749192..2385e6179 100644 --- a/src/windows/identity/plugins/krb4/Makefile +++ b/src/windows/identity/plugins/krb4/Makefile @@ -32,12 +32,13 @@ LIBFILE=$(LIBDIR)\krb4cred.lib OBJFILES= \ $(LIBDIR)\dynimport.obj \ $(LIBDIR)\krb5common.obj \ - $(OBJ)\main.obj \ + $(OBJ)\krb4main.obj \ $(OBJ)\krb4plugin.obj \ $(OBJ)\krb4funcs.obj \ $(OBJ)\errorfuncs.obj \ $(OBJ)\krb4config.obj \ - $(OBJ)\krb4configdlg.obj + $(OBJ)\krb4configdlg.obj \ + $(OBJ)\krb4newcreds.obj LIBFILES= \ $(LIBDIR)\nidmgr32.lib \ @@ -45,10 +46,12 @@ LIBFILES= \ SDKLIBFILES= +VERRESFILE=$(OBJ)\version.res + $(OBJ)\krb4config.c: krbconfig.csv $(CONFDIR)\csvschema.cfg $(CCSV) $** $@ -$(DLLFILE): $(OBJFILES) +$(DLLFILE): $(OBJFILES) $(VERRESFILE) $(DLLGUILINK) $(LIBFILES) $(SDKLIBFILES) all: mkdirs $(DLLFILE) lang diff --git a/src/windows/identity/plugins/krb4/errorfuncs.c b/src/windows/identity/plugins/krb4/errorfuncs.c index 9feaad2a7..dba9f5dc6 100644 --- a/src/windows/identity/plugins/krb4/errorfuncs.c +++ b/src/windows/identity/plugins/krb4/errorfuncs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -72,7 +72,7 @@ HWND GetRootParent (HWND Child) } -LPSTR err_describe(LPSTR buf, long code) +LPSTR err_describe(LPSTR buf, size_t len, long code) { LPSTR cp, com_err_msg; int offset; @@ -89,7 +89,8 @@ LPSTR err_describe(LPSTR buf, long code) case kadm_err_base: break; default: - strcpy(buf, com_err_msg); + strncpy(buf, com_err_msg, len); + buf[len-1] = '\0'; return buf; } @@ -192,8 +193,10 @@ LPSTR err_describe(LPSTR buf, long code) /* no extra error msg */ break; } - if(com_err_msg != buf) - strcpy(buf, com_err_msg); + if(com_err_msg != buf) { + strncpy(buf, com_err_msg, len); + buf[len-1] = '\0'; + } cp = buf + strlen(buf); *cp++ = '\n'; switch(table_num) { @@ -207,7 +210,7 @@ LPSTR err_describe(LPSTR buf, long code) etype = Lerror_table_name(table_num); break; } - wsprintfA((LPSTR) cp, (LPSTR) "(%s error %d" + StringCbPrintfA((LPSTR) cp, len - (cp-buf), (LPSTR) "(%s error %d" #ifdef DEBUG_COM_ERR " (absolute error %ld)" #endif @@ -221,44 +224,3 @@ LPSTR err_describe(LPSTR buf, long code) return (LPSTR)buf; } -int lsh_com_err_proc (LPSTR whoami, long code, - LPSTR fmt, va_list args) -{ - int retval; - HWND hOldFocus; - char buf[1024], *cp; /* changed to 512 by jms 8/23/93 */ - WORD mbformat = MB_OK | MB_ICONEXCLAMATION; - - cp = buf; - memset(buf, '\0', sizeof(buf)); - cp[0] = '\0'; - - if (code) - { - err_describe(buf, code); - while (*cp) - cp++; - } - - if (fmt) - { - if (fmt[0] == '%' && fmt[1] == 'b') - { - fmt += 2; - mbformat = va_arg(args, WORD); - /* if the first arg is a %b, we use it for the message - box MB_??? flags. */ - } - if (code) - { - *cp++ = '\n'; - *cp++ = '\n'; - } - wvsprintfA((LPSTR)cp, fmt, args); - } - hOldFocus = GetFocus(); - retval = MessageBoxA(/*GetRootParent(hOldFocus)*/NULL, buf, whoami, - mbformat | MB_ICONHAND | MB_TASKMODAL); - SetFocus(hOldFocus); - return retval; -} diff --git a/src/windows/identity/plugins/krb4/errorfuncs.h b/src/windows/identity/plugins/krb4/errorfuncs.h index be8f4e7c5..e339eca4f 100644 --- a/src/windows/identity/plugins/krb4/errorfuncs.h +++ b/src/windows/identity/plugins/krb4/errorfuncs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -43,32 +43,17 @@ typedef LPSTR (*err_func)(int, long); #endif #include -extern void Leash_initialize_krb_error_func(err_func func,struct et_list **); -#undef init_krb_err_func -#define init_krb_err_func(erf) Leash_initialize_krb_error_func(erf,&_et_list) - #include -extern void Leash_initialize_kadm_error_table(struct et_list **); -#undef init_kadm_err_tbl -#define init_kadm_err_tbl() Leash_initialize_kadm_error_table(&_et_list) #define kadm_err_base ERROR_TABLE_BASE_kadm -#define krb_err_func Leash_krb_err_func - #include -int lsh_com_err_proc (LPSTR whoami, long code, - LPSTR fmt, va_list args); -void FAR Leash_load_com_err_callback(FARPROC,FARPROC,FARPROC); #ifndef KRBERR #define KRBERR(code) (code + krb_err_base) #endif -int lsh_com_err_proc (LPSTR whoami, long code, LPSTR fmt, va_list args); -int DoNiftyErrorReport(long errnum, LPSTR what); - -LPSTR err_describe(LPSTR buf, long code); +LPSTR err_describe(LPSTR buf, size_t len, long code); /* */ diff --git a/src/windows/identity/plugins/krb4/images/plugin.ico b/src/windows/identity/plugins/krb4/images/plugin.ico new file mode 100644 index 0000000000000000000000000000000000000000..791b359694d86dcdc85bd083d502db8056283771 GIT binary patch literal 7278 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 #include #include +#include + +typedef struct tag_k4_ids_data { + khui_config_init_data cfg; + + khm_int32 get_tix; +} k4_ids_data; + +static void +k4_ids_read_params(k4_ids_data * d) { + khm_int32 t; +#ifdef DEBUG + assert(csp_params); +#endif + + t = 1; + khc_read_int32(csp_params, L"Krb4NewCreds", &t); + d->get_tix = !!t; +} + +static void +k4_ids_write_params(HWND hw, k4_ids_data * d) { + khm_int32 nv; + khm_boolean applied = FALSE; + + if (IsDlgButtonChecked(hw, IDC_CFG_GETTIX) == BST_CHECKED) + nv = TRUE; + else + nv = FALSE; + + if (!!nv != !!d->get_tix) { + d->get_tix = !!nv; + khc_write_int32(csp_params, L"Krb4NewCreds", d->get_tix); + applied = TRUE; + } + + khui_cfg_set_flags_inst(&d->cfg, + (applied)?KHUI_CNFLAG_APPLIED:0, + KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED); +} + +static void +k4_ids_check_mod(HWND hw, k4_ids_data * d) { + khm_int32 nv; + + if (IsDlgButtonChecked(hw, IDC_CFG_GETTIX) == BST_CHECKED) + nv = TRUE; + else + nv = FALSE; + + khui_cfg_set_flags_inst(&d->cfg, + (!!nv != !!d->get_tix)? KHUI_CNFLAG_MODIFIED: 0, + KHUI_CNFLAG_MODIFIED); +} + +INT_PTR CALLBACK +krb4_ids_config_proc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { + k4_ids_data * d; + + switch(uMsg) { + case WM_INITDIALOG: + d = PMALLOC(sizeof(*d)); + ZeroMemory(d, sizeof(*d)); + + d->cfg = *((khui_config_init_data *) lParam); + +#pragma warning(push) +#pragma warning(disable: 4244) + SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d); +#pragma warning(pop) + + k4_ids_read_params(d); + + CheckDlgButton(hwnd, IDC_CFG_GETTIX, + (d->get_tix)? BST_CHECKED: BST_UNCHECKED); + + break; + + case WM_COMMAND: + d = (k4_ids_data *) (LONG_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + + if (HIWORD(wParam) == BN_CLICKED) { + k4_ids_check_mod(hwnd, d); + } + break; + + case KHUI_WM_CFG_NOTIFY: + d = (k4_ids_data *) (LONG_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + + if (HIWORD(wParam) == WMCFG_APPLY) { + k4_ids_write_params(hwnd, d); + } + break; + + case WM_DESTROY: + d = (k4_ids_data *) (LONG_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + + PFREE(d); + break; + } + + return FALSE; +} + +INT_PTR CALLBACK +krb4_id_config_proc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { + switch(uMsg) { + case WM_INITDIALOG: + { + wchar_t idname[KCDB_IDENT_MAXCCH_NAME]; + khm_size cb; + khui_config_init_data * d; + khm_handle ident = NULL; + khm_int32 gettix = 0; + khm_int32 flags = 0; + + d = (khui_config_init_data *) lParam; + + khc_read_int32(csp_params, L"Krb4NewCreds", &gettix); + if (gettix == 0) + goto set_ui; + + *idname = 0; + cb = sizeof(idname); + khui_cfg_get_name(d->ctx_node, idname, &cb); + + kcdb_identity_create(idname, 0, &ident); + + if (ident == NULL) { + gettix = 0; + goto set_ui; + } + + kcdb_identity_get_flags(ident, &flags); + + kcdb_identity_release(ident); + + if (!(flags & KCDB_IDENT_FLAG_DEFAULT)) + gettix = 0; + + set_ui: + CheckDlgButton(hwnd, IDC_CFG_GETTIX, + (gettix)?BST_CHECKED: BST_UNCHECKED); + } + break; + } + + return FALSE; +} + INT_PTR CALLBACK krb4_confg_proc(HWND hwnd, diff --git a/src/windows/identity/plugins/krb4/krb4funcs.c b/src/windows/identity/plugins/krb4/krb4funcs.c index 8fda720b3..7798e5c9e 100644 --- a/src/windows/identity/plugins/krb4/krb4funcs.c +++ b/src/windows/identity/plugins/krb4/krb4funcs.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2004 Massachusetts Institute of Technology +* Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -78,11 +78,12 @@ int com_addr(void) long khm_krb4_list_tickets(void) { + char ptktname[MAX_PATH + 5]; char pname[ANAME_SZ]; char pinst[INST_SZ]; char prealm[REALM_SZ]; wchar_t wbuf[256]; - int k_errno; + int k_errno = 0; CREDENTIALS c; int newtickets = 0; int open = 0; @@ -91,6 +92,8 @@ khm_krb4_list_tickets(void) time_t tt; FILETIME ft; + kcdb_credset_flush(krb4_credset); + // Since krb_get_tf_realm will return a ticket_file error, // we will call tf_init and tf_close first to filter out // things like no ticket file. Otherwise, the error that @@ -98,7 +101,7 @@ khm_krb4_list_tickets(void) // klist: can't find realm of ticket file: No ticket file (tf_util) // instead of klist: No ticket file (tf_util) if (ptf_init == NULL) - return(KSUCCESS); + goto collect; com_addr(); @@ -126,6 +129,8 @@ khm_krb4_list_tickets(void) goto cleanup; } + StringCchCopyA(ptktname, ARRAYLENGTH(ptktname), (*ptkt_string)()); + open = 1; // Get principal name and instance @@ -147,8 +152,6 @@ khm_krb4_list_tickets(void) goto cleanup; } - kcdb_credset_flush(krb4_credset); - // Get KRB4 tickets while ((k_errno = (*ptf_get_cred)(&c)) == KSUCCESS) { @@ -174,12 +177,13 @@ khm_krb4_list_tickets(void) TimetToFileTimeInterval(tt, &ft); kcdb_cred_set_attr(cred, KCDB_ATTR_LIFETIME, &ft, sizeof(ft)); + AnsiStrToUnicode(wbuf, sizeof(wbuf), ptktname); + kcdb_cred_set_attr(cred, KCDB_ATTR_LOCATION, wbuf, KCDB_CBSIZE_AUTO); + kcdb_credset_add_cred(krb4_credset, cred, -1); } // while - kcdb_credset_collect(NULL, krb4_credset, ident, credtype_id_krb4, NULL); - cleanup: if (ptf_close == NULL) return(KSUCCESS); @@ -219,6 +223,10 @@ cleanup: MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND); } #endif + + collect: + kcdb_credset_collect(NULL, krb4_credset, ident, credtype_id_krb4, NULL); + return k_errno; } @@ -227,7 +235,7 @@ cleanup: #define KRB5_FILE "KRB5.INI" BOOL -khm_get_profile_file(LPSTR confname, UINT szConfname) +khm_krb5_get_profile_file(LPSTR confname, UINT szConfname) { char **configFile = NULL; if (pkrb5_get_default_config_files(&configFile)) @@ -271,7 +279,7 @@ khm_get_krb4_con_file(LPSTR confname, UINT szConfname) LPSTR pFind; //strcpy(krbConFile, CLeashApp::m_krbv5_profile->first_file->filename); - if (khm_get_profile_file(krbConFile, sizeof(krbConFile))) + if (khm_krb5_get_profile_file(krbConFile, sizeof(krbConFile))) { GetWindowsDirectoryA(krbConFile,sizeof(krbConFile)); krbConFile[MAX_PATH-1] = '\0'; @@ -368,7 +376,7 @@ wchar_t * khm_krb5_get_realm_list(void) char krb5_conf[MAX_PATH+1]; - if (!khm_get_profile_file(krb5_conf,sizeof(krb5_conf))) { + if (!khm_krb5_get_profile_file(krb5_conf,sizeof(krb5_conf))) { profile_t profile; long retval; const char *filenames[2]; @@ -392,7 +400,7 @@ wchar_t * khm_krb5_get_realm_list(void) } cbsize += sizeof(wchar_t); /* double null terminated */ - rlist = malloc(cbsize); + rlist = PMALLOC(cbsize); d = rlist; for (cpp = sections; *cpp; cpp++) { @@ -430,7 +438,7 @@ wchar_t * khm_krb5_get_realm_list(void) /*TODO: compute the actual required buffer size instead of hardcoding */ cbsize = 16384; // arbitrary - rlist = malloc(cbsize); + rlist = PMALLOC(cbsize); d = rlist; // Skip the default realm @@ -493,7 +501,7 @@ wchar_t * khm_krb5_get_default_realm(void) if (def) { cch = strlen(def) + 1; - realm = malloc(sizeof(wchar_t) * cch); + realm = PMALLOC(sizeof(wchar_t) * cch); AnsiStrToUnicode(realm, sizeof(wchar_t) * cch, def); pkrb5_free_default_realm(ctx, def); } else @@ -503,3 +511,291 @@ wchar_t * khm_krb5_get_default_realm(void) return realm; } + +static +char * +make_postfix(const char * base, + const char * postfix, + char ** rcopy) +{ + int base_size; + int ret_size; + char * copy = 0; + char * ret = 0; + + base_size = (int) strlen(base) + 1; + ret_size = base_size + (int) strlen(postfix) + 1; + copy = malloc(base_size); + ret = malloc(ret_size); + + if (!copy || !ret) + goto cleanup; + + strncpy(copy, base, base_size); + copy[base_size - 1] = 0; + + strncpy(ret, base, base_size); + strncpy(ret + (base_size - 1), postfix, ret_size - (base_size - 1)); + ret[ret_size - 1] = 0; + + cleanup: + if (!copy || !ret) { + if (copy) + free(copy); + if (ret) + free(ret); + copy = ret = 0; + } + // INVARIANT: (ret ==> copy) && (copy ==> ret) + *rcopy = copy; + return ret; +} + + +static +long +make_temp_cache_v4(const char * postfix) +{ + static char * old_cache = 0; + + if (!pkrb_set_tkt_string || !ptkt_string || !pdest_tkt) + return 0; // XXX - is this appropriate? + + if (old_cache) { + pdest_tkt(); + pkrb_set_tkt_string(old_cache); + free(old_cache); + old_cache = 0; + } + + if (postfix) + { + char * tmp_cache = make_postfix(ptkt_string(), postfix, &old_cache); + + if (!tmp_cache) + return KFAILURE; + + pkrb_set_tkt_string(tmp_cache); + free(tmp_cache); + } + return 0; +} + +long +khm_krb4_changepwd(char * principal, + char * password, + char * newpassword, + char** error_str) +{ + long k_errno; + + if (!pkrb_set_tkt_string || !ptkt_string || !pkadm_change_your_password || + !pdest_tkt) + return KFAILURE; + + k_errno = make_temp_cache_v4("_chgpwd"); + if (k_errno) return k_errno; + k_errno = pkadm_change_your_password(principal, password, newpassword, + error_str); + make_temp_cache_v4(0); + return k_errno; +} + +long +khm_convert524(khm_handle identity) +{ +#ifdef NO_KRB5 + return(0); +#else + krb5_context ctx = 0; + krb5_error_code code = 0; + int icode = 0; + krb5_principal me = 0; + krb5_principal server = 0; + krb5_creds *v5creds = 0; + krb5_creds increds; + krb5_ccache cc = 0; + CREDENTIALS * v4creds = NULL; + static int init_ets = 1; + + if (!pkrb5_init_context || + !pkrb_in_tkt || + !pkrb524_init_ets || + !pkrb524_convert_creds_kdc) + return 0; + + v4creds = (CREDENTIALS *) malloc(sizeof(CREDENTIALS)); + memset((char *) v4creds, 0, sizeof(CREDENTIALS)); + + memset((char *) &increds, 0, sizeof(increds)); + /* + From this point on, we can goto cleanup because increds is + initialized. + */ + + code = khm_krb5_initialize(identity, &ctx, &cc); + if (code) + goto cleanup; + + if ( init_ets ) { + pkrb524_init_ets(ctx); + init_ets = 0; + } + + if (code = pkrb5_cc_get_principal(ctx, cc, &me)) + goto cleanup; + + if ((code = pkrb5_build_principal(ctx, + &server, + krb5_princ_realm(ctx, me)->length, + krb5_princ_realm(ctx, me)->data, + "krbtgt", + krb5_princ_realm(ctx, me)->data, + NULL))) { + goto cleanup; + } + + increds.client = me; + increds.server = server; + increds.times.endtime = 0; + increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC; + if ((code = pkrb5_get_credentials(ctx, 0, + cc, + &increds, + &v5creds))) { + goto cleanup; + } + + if ((icode = pkrb524_convert_creds_kdc(ctx, + v5creds, + v4creds))) { + goto cleanup; + } + + /* initialize ticket cache */ + if ((icode = pkrb_in_tkt(v4creds->pname, v4creds->pinst, v4creds->realm) + != KSUCCESS)) { + goto cleanup; + } + /* stash ticket, session key, etc. for future use */ + if ((icode = pkrb_save_credentials(v4creds->service, + v4creds->instance, + v4creds->realm, + v4creds->session, + v4creds->lifetime, + v4creds->kvno, + &(v4creds->ticket_st), + v4creds->issue_date))) { + goto cleanup; + } + + cleanup: + memset(v4creds, 0, sizeof(v4creds)); + free(v4creds); + + if (v5creds) { + pkrb5_free_creds(ctx, v5creds); + } + if (increds.client == me) + me = 0; + if (increds.server == server) + server = 0; + + if (ctx) + pkrb5_free_cred_contents(ctx, &increds); + + if (server) { + pkrb5_free_principal(ctx, server); + } + + if (me) { + pkrb5_free_principal(ctx, me); + } + + if (ctx && cc) + pkrb5_cc_close(ctx, cc); + + if (ctx) { + pkrb5_free_context(ctx); + } + + return (code || icode); +#endif /* NO_KRB5 */ +} + +long +khm_krb4_kinit(char * aname, + char * inst, + char * realm, + long lifetime, + char * password) { + + wchar_t * functionName = NULL; + wchar_t * err_context = NULL; + int rc4 = 0; + int msg = 0; + + if (pkname_parse == NULL) { + goto cleanup; + } + + err_context = L"getting realm"; + if (!*realm && (rc4 = (int)(*pkrb_get_lrealm)(realm, 1))) { + functionName = L"krb_get_lrealm()"; + msg = IDS_ERR_REALM; + goto cleanup; + } + + err_context = L"checking principal"; + if ((!*aname) || (!(rc4 = (int)(*pk_isname)(aname)))) { + functionName = L"krb_get_lrealm()"; + msg = IDS_ERR_PRINCIPAL; + goto cleanup; + } + + /* optional instance */ + if (!(rc4 = (int)(*pk_isinst)(inst))) { + functionName = L"k_isinst()"; + msg = IDS_ERR_INVINST; + goto cleanup; + } + + if (!(rc4 = (int)(*pk_isrealm)(realm))) { + functionName = L"k_isrealm()"; + msg = IDS_ERR_REALM; + goto cleanup; + } + + err_context = L"fetching ticket"; + rc4 = (*pkrb_get_pw_in_tkt)(aname, inst, realm, "krbtgt", realm, + lifetime, password); + + if (rc4) /* XXX: do we want: && (rc != NO_TKT_FIL) as well? */ { + functionName = L"krb_get_pw_in_tkt()"; + msg = IDS_ERR_PWINTKT; + goto cleanup; + } + + return 0; + + cleanup: + { + _report_sr0(KHERR_ERROR, msg); + _location(functionName); + } + return rc4; +} + + +int khm_krb4_kdestroy(void) { + int k_errno = 0; + + if (pdest_tkt != NULL) + { + k_errno = (*pdest_tkt)(); + if (k_errno && (k_errno != RET_TKFIL)) + return KRBERR(k_errno); + } + + return k_errno; +} diff --git a/src/windows/identity/plugins/krb4/krb4funcs.h b/src/windows/identity/plugins/krb4/krb4funcs.h index ea97358b9..742036878 100644 --- a/src/windows/identity/plugins/krb4/krb4funcs.h +++ b/src/windows/identity/plugins/krb4/krb4funcs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -48,93 +48,21 @@ #define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */ -// Function Prototypes. -BOOL khm_krb5_ms2mit(BOOL); - -int -khm_krb5_kinit(krb5_context alt_ctx, - char * principal_name, - char * password, - krb5_deltat lifetime, - DWORD forwardable, - DWORD proxiable, - krb5_deltat renew_life, - DWORD addressless, - DWORD publicIP, - krb5_prompter_fct prompter, - void * p_data - ); - -long -Leash_int_kinit_ex( - krb5_context ctx, - HWND hParent, - char * principal, - char * password, - int lifetime, - int forwardable, - int proxiable, - int renew_life, - int addressless, - unsigned long publicIP, - int displayErrors - ); long -Leash_int_checkpwd( - char * principal, - char * password, - int displayErrors - ); - -long -Leash_int_changepwd( - char * principal, - char * password, - char * newpassword, - char** result_string, - int displayErrors - ); - -int -Leash_krb5_kdestroy( - void - ); - -int -Leash_krb5_kinit( - krb5_context, - HWND hParent, - char * principal_name, - char * password, - krb5_deltat lifetime, - DWORD forwardable, - DWORD proxiable, - krb5_deltat renew_life, - DWORD addressless, - DWORD publicIP - ); +khm_convert524(khm_handle identity); long -khm_convert524( - krb5_context ctx - ); - -int -Leash_afs_unlog( - void - ); +khm_krb4_kinit(char * aname, + char * inst, + char * realm, + long lifetime, + char * password); -int -Leash_afs_klog( - char *, - char *, - char *, - int - ); +long +khm_krb4_list_tickets(void); -int -LeashKRB5_renew(void); +int khm_krb4_kdestroy(void); LONG write_registry_setting( @@ -180,11 +108,7 @@ config_boolean_to_int( const char *s ); - wchar_t * khm_krb5_get_default_realm(void); wchar_t * khm_krb5_get_realm_list(void); -long khm_krb5_list_tickets(krb5_context *krbv5Context); -long khm_krb4_list_tickets(void); - #endif diff --git a/src/windows/identity/plugins/krb4/main.c b/src/windows/identity/plugins/krb4/krb4main.c similarity index 75% rename from src/windows/identity/plugins/krb4/main.c rename to src/windows/identity/plugins/krb4/krb4main.c index 60ceb7f83..b83cd5eb4 100644 --- a/src/windows/identity/plugins/krb4/main.c +++ b/src/windows/identity/plugins/krb4/krb4main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -39,8 +39,6 @@ khm_int32 attr_id_key_enctype = -1; khm_int32 attr_id_tkt_enctype = -1; khm_int32 attr_id_addr_list = -1; khm_int32 attr_id_krb5_flags = -1; -khm_int32 attr_id_renew_till = -1; -khm_int32 attr_id_renew_for = -1; khm_handle csp_plugins = NULL; khm_handle csp_krbcred = NULL; @@ -91,44 +89,6 @@ KHMEXP khm_int32 KHMAPI init_module(kmm_module h_module) { if(KHM_FAILED(rv = init_error_funcs())) goto _exit; - /* Lookup common data types */ - if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ENCTYPE, &type_id_enctype))) { - goto _exit; - } - - if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ADDR_LIST, &type_id_addr_list))) { - goto _exit; - } - - if(KHM_FAILED(kcdb_type_get_id(TYPENAME_KRB5_FLAGS, &type_id_krb5_flags))) { - goto _exit; - } - - /* Lookup common attributes */ - if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KEY_ENCTYPE, &attr_id_key_enctype))) { - goto _exit; - } - - if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_TKT_ENCTYPE, &attr_id_tkt_enctype))) { - goto _exit; - } - - if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_ADDR_LIST, &attr_id_addr_list))) { - goto _exit; - } - - if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_FLAGS, &attr_id_krb5_flags))) { - goto _exit; - } - - if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_RENEW_TILL, &attr_id_renew_till))) { - goto _exit; - } - - if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_RENEW_FOR, &attr_id_renew_for))) { - goto _exit; - } - rv = kmm_get_plugins_config(0, &csp_plugins); if(KHM_FAILED(rv)) goto _exit; diff --git a/src/windows/identity/plugins/krb4/krb4newcreds.c b/src/windows/identity/plugins/krb4/krb4newcreds.c new file mode 100644 index 000000000..fdbe304fa --- /dev/null +++ b/src/windows/identity/plugins/krb4/krb4newcreds.c @@ -0,0 +1,657 @@ +/* + * Copyright (c) 2005 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* $Id$ */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define K4_METHOD_AUTO 0 +#define K4_METHOD_PASSWORD 1 +#define K4_METHOD_K524 2 + +int method_to_id[] = { + IDC_NCK4_AUTO, + IDC_NCK4_PWD, + IDC_NCK4_K524 +}; + +typedef struct tag_k4_dlg_data { + HWND hwnd; + khui_new_creds * nc; + khui_new_creds_by_type * nct; + + khm_boolean k4_enabled; + khm_int32 method; + time_t lifetime; +} k4_dlg_data; + +void k4_update_display(k4_dlg_data * d) { + CheckDlgButton(d->hwnd, IDC_NCK4_OBTAIN, + (d->k4_enabled)?BST_CHECKED: BST_UNCHECKED); + + if (d->k4_enabled) { + EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_AUTO), TRUE); + EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_PWD ), TRUE); + EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_K524), TRUE); + } else { + EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_AUTO), FALSE); + EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_PWD ), FALSE); + EnableWindow(GetDlgItem(d->hwnd, IDC_NCK4_K524), FALSE); + } + + CheckRadioButton(d->hwnd, IDC_NCK4_AUTO, IDC_NCK4_K524, + method_to_id[d->method]); +} + +void k4_update_data(k4_dlg_data * d) { + int i; + khm_boolean oldstate; + + oldstate = d->k4_enabled; + + if (IsDlgButtonChecked(d->hwnd, IDC_NCK4_OBTAIN) == BST_CHECKED) + d->k4_enabled = TRUE; + else + d->k4_enabled = FALSE; + + if ((oldstate && !d->k4_enabled) || + (!oldstate && d->k4_enabled)) { + + khui_cw_enable_type(d->nc, credtype_id_krb4, d->k4_enabled); + } + + d->method = 0; + + for (i=K4_METHOD_AUTO; i<=K4_METHOD_K524; i++) { + if (IsDlgButtonChecked(d->hwnd, method_to_id[i]) == BST_CHECKED) { + d->method = i; + break; + } + } +} + +void k4_read_identity_data(k4_dlg_data * d) { + khm_handle csp_ident = NULL; + khm_handle csp_k4 = NULL; + + khm_int32 idflags = 0; + khm_int32 t; + + if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"Krb4NewCreds", &t))) + d->k4_enabled = !!t; + else + d->k4_enabled = TRUE; + + if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"Krb4Method", &t))) + d->method = t; + else + d->method = K4_METHOD_AUTO; + + if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"DefaultLifetime", &t))) + d->lifetime = t; + else + d->lifetime = 10 * 60 * 60; /* 10 hours */ + + if (d->nc->n_identities > 0 && + d->nc->identities[0]) { + + if (KHM_SUCCEEDED(kcdb_identity_get_config(d->nc->identities[0], + 0, + &csp_ident))) { + + khc_open_space(csp_ident, CSNAME_KRB4CRED, 0, &csp_k4); + + if (csp_k4) { + if (KHM_SUCCEEDED(khc_read_int32(csp_k4, L"Krb4NewCreds", &t))) + d->k4_enabled = !!t; + if (KHM_SUCCEEDED(khc_read_int32(csp_k4, L"Krb4Method", &t))) + d->method = t; + khc_close_space(csp_k4); + } + + khc_close_space(csp_ident); + + kcdb_identity_get_flags(d->nc->identities[0], &idflags); + } + + if (!(idflags & KCDB_IDENT_FLAG_DEFAULT)) { + /* we only support k4 for one identity, and that is the + default identity. If we are trying to get tickets for + a non-default identity, then we start off as + disabled. */ + + khm_handle defident = NULL; + + if (KHM_SUCCEEDED(kcdb_identity_get_default(&defident))) { + kcdb_identity_release(defident); + + d->k4_enabled = FALSE; + } + } + } else { + d->k4_enabled = FALSE; + } + + if (d->method < 0 || d->method > K4_METHOD_K524) + d->method = K4_METHOD_AUTO; +} + +void k4_write_identity_data(k4_dlg_data * d) { + khm_handle csp_ident = NULL; + khm_handle csp_k4 = NULL; + + if (d->nc->n_identities > 0 && + d->nc->identities[0] && + KHM_SUCCEEDED(kcdb_identity_get_config(d->nc->identities[0], + KHM_FLAG_CREATE, + &csp_ident))) { + khc_open_space(csp_ident, CSNAME_KRB4CRED, KHM_FLAG_CREATE, &csp_k4); + + if (csp_k4) { + khc_write_int32(csp_k4, L"Krb4NewCreds", !!d->k4_enabled); + khc_write_int32(csp_k4, L"Krb4Method", d->method); + + khc_close_space(csp_k4); + } + + khc_close_space(csp_ident); + } +} + +void k4_handle_wmnc_notify(k4_dlg_data * d, + WPARAM wParam, + LPARAM lParam) { + switch(HIWORD(wParam)) { + case WMNC_UPDATE_CREDTEXT: + { + if (d->nct->credtext) { + PFREE(d->nct->credtext); + d->nct->credtext = NULL; + } + + if (d->nc->n_identities > 0 && + d->nc->identities[0]) { + + khm_int32 flags = 0; + wchar_t idname[KCDB_IDENT_MAXCCH_NAME]; + wchar_t * atsign; + wchar_t * realm; + khm_size cb; + + kcdb_identity_get_flags(d->nc->identities[0], &flags); + + if (flags & KCDB_IDENT_FLAG_INVALID) + break; + + cb = sizeof(idname); + kcdb_identity_get_name(d->nc->identities[0], idname, + &cb); + + atsign = wcsrchr(idname, L'@'); + + if (atsign == NULL || !atsign[1]) + break; + + realm = ++atsign; + + if (d->k4_enabled) { + wchar_t wmethod[128]; + wchar_t wfmt[128]; + wchar_t wct[512]; + + LoadString(hResModule, IDS_CT_TGTFOR, + wfmt, ARRAYLENGTH(wfmt)); + + if (d->method == K4_METHOD_AUTO) + LoadString(hResModule, IDS_METHOD_AUTO, wmethod, + ARRAYLENGTH(wmethod)); + else if (d->method == K4_METHOD_PASSWORD) + LoadString(hResModule, IDS_METHOD_PWD, wmethod, + ARRAYLENGTH(wmethod)); + else if (d->method == K4_METHOD_K524) + LoadString(hResModule, IDS_METHOD_K524, wmethod, + ARRAYLENGTH(wmethod)); + else { + assert(FALSE); + } + + StringCbPrintf(wct, sizeof(wct), wfmt, realm, wmethod); + + StringCbLength(wct, sizeof(wct), &cb); + cb += sizeof(wchar_t); + + d->nct->credtext = PMALLOC(cb); + + StringCbCopy(d->nct->credtext, cb, wct); + } else { + wchar_t wct[256]; + + LoadString(hResModule, IDS_CT_DISABLED, + wct, ARRAYLENGTH(wct)); + + StringCbLength(wct, sizeof(wct), &cb); + cb += sizeof(wchar_t); + + d->nct->credtext = PMALLOC(cb); + + StringCbCopy(d->nct->credtext, cb, wct); + } + } + /* no identities were selected. it is not the + responsibility of krb4 to complain about this. */ + } + break; + + case WMNC_IDENTITY_CHANGE: + k4_read_identity_data(d); + k4_update_display(d); + break; + + case WMNC_CREDTEXT_LINK: + { + wchar_t wid[KHUI_MAXCCH_HTLINK_FIELD]; + wchar_t * wids; + khui_htwnd_link * l; + + l = (khui_htwnd_link *) lParam; + + wcsncpy(wid, l->id, l->id_len); + wid[l->id_len] = 0; + wids = wcschr(wid, L':'); + + if (!wids) + break; + else + wids++; + + if (!wcscmp(wids, L"Enable")) { + d->k4_enabled = TRUE; + + k4_update_display(d); + khui_cw_enable_type(d->nc, credtype_id_krb4, TRUE); + } + } + break; + } +} + +INT_PTR CALLBACK k4_nc_dlg_proc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { + + k4_dlg_data * d; + + switch(uMsg) { + case WM_INITDIALOG: + { + d = PMALLOC(sizeof(*d)); + ZeroMemory(d, sizeof(*d)); + + d->nc = (khui_new_creds *) lParam; + khui_cw_find_type(d->nc, credtype_id_krb4, &d->nct); + +#pragma warning(push) +#pragma warning(disable: 4244) + SetWindowLongPtr(hwnd, DWLP_USER, (LPARAM) d); +#pragma warning(pop) + + d->nct->aux = (LPARAM) d; + d->hwnd = hwnd; + + d->k4_enabled = TRUE; + d->method = K4_METHOD_AUTO; + + k4_update_display(d); + } + break; + + case WM_COMMAND: + { + d = (k4_dlg_data *) (LONG_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + + k4_update_data(d); + k4_update_display(d); + } + break; + + case KHUI_WM_NC_NOTIFY: + { + d = (k4_dlg_data *) (LONG_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + k4_handle_wmnc_notify(d, wParam, lParam); + } + break; + + case WM_DESTROY: + { + d = (k4_dlg_data *) (LONG_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + + d->nct->aux = 0; + + PFREE(d); + } + break; + } + + return FALSE; +} + +khm_int32 +krb4_msg_newcred(khm_int32 msg_type, khm_int32 msg_subtype, + khm_ui_4 uparam, void * vparam) { + + switch(msg_subtype) { + case KMSG_CRED_NEW_CREDS: + { + khui_new_creds * nc; + khui_new_creds_by_type * nct; + khm_size cbsize; + wchar_t wbuf[256]; + + nc = (khui_new_creds *) vparam; + + nct = PMALLOC(sizeof(*nct)); +#ifdef DEBUG + assert(nct); +#endif + ZeroMemory(nct, sizeof(*nct)); + + nct->type = credtype_id_krb4; + nct->ordinal = 3; + LoadString(hResModule, IDS_NC_K4_SHORT, + wbuf, ARRAYLENGTH(wbuf)); + StringCbLength(wbuf, sizeof(wbuf), &cbsize); + cbsize += sizeof(wchar_t); + + nct->name = PMALLOC(cbsize); + StringCbCopy(nct->name, cbsize, wbuf); + + nct->type_deps[nct->n_type_deps++] = credtype_id_krb5; + + nct->h_module = hResModule; + nct->dlg_proc = k4_nc_dlg_proc; + nct->dlg_template = MAKEINTRESOURCE(IDD_NC_KRB4); + + khui_cw_add_type(nc, nct); + } + break; + + case KMSG_CRED_RENEW_CREDS: + { + khui_new_creds * nc; + khui_new_creds_by_type * nct; + khm_size cbsize; + wchar_t wbuf[256]; + + nc = (khui_new_creds *) vparam; + + nct = PMALLOC(sizeof(*nct)); +#ifdef DEBUG + assert(nct); +#endif + + ZeroMemory(nct, sizeof(*nct)); + + nct->type = credtype_id_krb4; + nct->ordinal = 3; + LoadString(hResModule, IDS_NC_K4_SHORT, + wbuf, ARRAYLENGTH(wbuf)); + StringCbLength(wbuf, sizeof(wbuf), &cbsize); + cbsize += sizeof(wchar_t); + + nct->name = PMALLOC(cbsize); + StringCbCopy(nct->name, cbsize, wbuf); + + nct->type_deps[nct->n_type_deps++] = credtype_id_krb5; + + khui_cw_add_type(nc, nct); + } + break; + + case KMSG_CRED_DIALOG_SETUP: + break; + + case KMSG_CRED_PROCESS: + { + khui_new_creds * nc; + khui_new_creds_by_type * nct = NULL; + khm_handle ident = NULL; + k4_dlg_data * d = NULL; + long code = 0; + + nc = (khui_new_creds *) vparam; + if (KHM_FAILED(khui_cw_find_type(nc, credtype_id_krb4, &nct))) + break; + + if (nc->subtype == KMSG_CRED_NEW_CREDS || + nc->subtype == KMSG_CRED_RENEW_CREDS) { + khm_int32 method; + + if (nc->subtype == KMSG_CRED_NEW_CREDS) { + + d = (k4_dlg_data *) nct->aux; + if (!d || + nc->n_identities == 0 || + nc->identities[0] == NULL || + nc->result != KHUI_NC_RESULT_GET_CREDS) + break; + + if (!d->k4_enabled) { + k4_write_identity_data(d); + break; + } + + method = d->method; + ident = nc->identities[0]; + + } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) { + + if ((nc->ctx.scope == KHUI_SCOPE_IDENT && + nc->ctx.identity != NULL) || + + (nc->ctx.scope == KHUI_SCOPE_CREDTYPE && + nc->ctx.cred_type == credtype_id_krb4 && + nc->ctx.identity != NULL) || + + (nc->ctx.scope == KHUI_SCOPE_CRED && + nc->ctx.cred_type == credtype_id_krb4 && + nc->ctx.identity != NULL && + nc->ctx.cred != NULL)) { + + ident = nc->ctx.identity; + + } else { + break; + } + + method = K4_METHOD_K524; /* only k524 is supported + for renewals */ + } else { + assert(FALSE); + } + + if ((method == K4_METHOD_AUTO || + method == K4_METHOD_K524) && + khui_cw_type_succeeded(nc, credtype_id_krb5)) { + + code = khm_convert524(ident); + + if (code == 0) { + khui_cw_set_response(nc, credtype_id_krb4, + KHUI_NC_RESPONSE_SUCCESS | + KHUI_NC_RESPONSE_EXIT); + + if (nc->subtype == KMSG_CRED_NEW_CREDS) { + assert(d != NULL); + + k4_write_identity_data(d); + } + break; + } else if (method == K4_METHOD_K524) { + khui_cw_set_response(nc, credtype_id_krb4, + KHUI_NC_RESPONSE_FAILED | + KHUI_NC_RESPONSE_EXIT); + break; + } + } + + /* only supported for new credentials */ + if (method == K4_METHOD_AUTO || + method == K4_METHOD_PASSWORD) { + + khm_size n_prompts = 0; + khm_size idx; + khm_size cb; + wchar_t wpwd[KHUI_MAXCCH_PROMPT_VALUE]; + char pwd[KHUI_MAXCCH_PROMPT_VALUE]; + wchar_t widname[KCDB_IDENT_MAXCCH_NAME]; + char idname[KCDB_IDENT_MAXCCH_NAME]; + + char * aname = NULL; + char * inst = NULL; + char * realm = NULL; + + assert(nc->subtype == KMSG_CRED_NEW_CREDS); + + code = TRUE; /* just has to be non-zero */ + + khui_cw_get_prompt_count(nc, &n_prompts); + + if (n_prompts == 0) + goto _skip_pwd; + + for (idx = 0; idx < n_prompts; idx++) { + khui_new_creds_prompt * p; + + if (KHM_FAILED(khui_cw_get_prompt(nc, idx, &p))) + continue; + + if (p->type == KHUI_NCPROMPT_TYPE_PASSWORD) + break; + } + + if (idx >= n_prompts) + goto _skip_pwd; + + khui_cw_sync_prompt_values(nc); + + cb = sizeof(wpwd); + if (KHM_FAILED(khui_cw_get_prompt_value(nc, idx, + wpwd, + &cb))) + goto _skip_pwd; + + UnicodeStrToAnsi(pwd, sizeof(pwd), wpwd); + + cb = sizeof(widname); + kcdb_identity_get_name(ident, + widname, + &cb); + + UnicodeStrToAnsi(idname, sizeof(idname), widname); + + { + char * atsign; + + atsign = strchr(idname, '@'); + if (atsign == NULL) + goto _skip_pwd; + + *atsign++ = 0; + + realm = atsign; + } + + { + char * slash; + + slash = strchr(idname, '/'); + if (slash != NULL) { + *slash++ = 0; + inst = slash; + } else { + inst = ""; + } + } + + aname = idname; + + code = khm_krb4_kinit(aname, inst, realm, + (long) d->lifetime, pwd); + _skip_pwd: + + if (code) { + khui_cw_set_response(nc, credtype_id_krb4, + KHUI_NC_RESPONSE_EXIT | + KHUI_NC_RESPONSE_FAILED); + + } else { + khui_cw_set_response(nc, credtype_id_krb4, + KHUI_NC_RESPONSE_EXIT | + KHUI_NC_RESPONSE_SUCCESS); + + if (nc->subtype == KMSG_CRED_NEW_CREDS) { + + assert(d != NULL); + k4_write_identity_data(d); + + } + } + } + } + } + break; + + case KMSG_CRED_END: + { + khui_new_creds * nc; + khui_new_creds_by_type * nct = NULL; + + nc = (khui_new_creds *) vparam; + if (KHM_FAILED(khui_cw_find_type(nc, credtype_id_krb4, &nct))) + break; + + khui_cw_del_type(nc, credtype_id_krb4); + + if (nct->name) + PFREE(nct->name); + + PFREE(nct); + } + break; + } + + return KHM_ERROR_SUCCESS; +} diff --git a/src/windows/identity/plugins/krb4/krb4plugin.c b/src/windows/identity/plugins/krb4/krb4plugin.c index 106febac0..23f913bd9 100644 --- a/src/windows/identity/plugins/krb4/krb4plugin.c +++ b/src/windows/identity/plugins/krb4/krb4plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -28,11 +28,14 @@ #include #include #include +#include #include #include #include khm_int32 credtype_id_krb4 = KCDB_CREDTYPE_INVALID; +khm_int32 credtype_id_krb5 = KCDB_CREDTYPE_INVALID; + khm_boolean krb4_initialized = FALSE; khm_handle krb4_credset = NULL; @@ -64,7 +67,7 @@ krb4_msg_system(khm_int32 msg_type, khm_int32 msg_subtype, { StringCbLength(buf, KCDB_MAXCB_SHORT_DESC, &cbsize); cbsize += sizeof(wchar_t); - ct.short_desc = malloc(cbsize); + ct.short_desc = PMALLOC(cbsize); StringCbCopy(ct.short_desc, cbsize, buf); } @@ -76,7 +79,7 @@ krb4_msg_system(khm_int32 msg_type, khm_int32 msg_subtype, { StringCbLength(buf, KCDB_MAXCB_SHORT_DESC, &cbsize); cbsize += sizeof(wchar_t); - ct.long_desc = malloc(cbsize); + ct.long_desc = PMALLOC(cbsize); StringCbCopy(ct.long_desc, cbsize, buf); } @@ -88,34 +91,116 @@ krb4_msg_system(khm_int32 msg_type, khm_int32 msg_subtype, if(KHM_SUCCEEDED(rv)) rv = kcdb_credset_create(&krb4_credset); + if (KHM_SUCCEEDED(rv)) + rv = kcdb_credtype_get_id(KRB5_CREDTYPE_NAME, + &credtype_id_krb5); + if(ct.short_desc) - free(ct.short_desc); + PFREE(ct.short_desc); if(ct.long_desc) - free(ct.long_desc); + PFREE(ct.long_desc); + + if (KHM_SUCCEEDED(rv)) { + khui_config_node idents; + + ZeroMemory(®, sizeof(reg)); + + reg.name = KRB4_CONFIG_NODE_NAME; + reg.short_desc = wshort_desc; + reg.long_desc = wlong_desc; + reg.h_module = hResModule; + reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_KRB4); + reg.dlg_proc = krb4_confg_proc; + reg.flags = 0; + + LoadString(hResModule, IDS_CFG_KRB4_LONG, + wlong_desc, ARRAYLENGTH(wlong_desc)); + LoadString(hResModule, IDS_CFG_KRB4_SHORT, + wshort_desc, ARRAYLENGTH(wshort_desc)); + + khui_cfg_register(NULL, ®); + + khui_cfg_open(NULL, L"KhmIdentities", &idents); + + ZeroMemory(®, sizeof(reg)); + + reg.name = KRB4_IDS_CONFIG_NODE_NAME; + reg.short_desc = wshort_desc; + reg.long_desc = wlong_desc; + reg.h_module = hResModule; + reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_IDS_KRB4); + reg.dlg_proc = krb4_ids_config_proc; + reg.flags = KHUI_CNFLAG_SUBPANEL; + + LoadString(hResModule, IDS_CFG_KRB4_SHORT, + wlong_desc, ARRAYLENGTH(wlong_desc)); + LoadString(hResModule, IDS_CFG_KRB4_SHORT, + wshort_desc, ARRAYLENGTH(wshort_desc)); + + khui_cfg_register(idents, ®); - ZeroMemory(®, sizeof(reg)); + ZeroMemory(®, sizeof(reg)); - reg.name = KRB4_CONFIG_NODE_NAME; - reg.short_desc = wshort_desc; - reg.long_desc = wlong_desc; - reg.h_module = hResModule; - reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_KRB4); - reg.dlg_proc = krb4_confg_proc; - reg.flags = 0; + reg.name = KRB4_ID_CONFIG_NODE_NAME; + reg.short_desc = wshort_desc; + reg.long_desc = wlong_desc; + reg.h_module = hResModule; + reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_ID_KRB4); + reg.dlg_proc = krb4_id_config_proc; + reg.flags = KHUI_CNFLAG_SUBPANEL | KHUI_CNFLAG_PLURAL; - LoadString(hResModule, IDS_CFG_KRB4_LONG, - wlong_desc, ARRAYLENGTH(wlong_desc)); - LoadString(hResModule, IDS_CFG_KRB4_SHORT, - wshort_desc, ARRAYLENGTH(wshort_desc)); + LoadString(hResModule, IDS_CFG_KRB4_SHORT, + wlong_desc, ARRAYLENGTH(wlong_desc)); + LoadString(hResModule, IDS_CFG_KRB4_SHORT, + wshort_desc, ARRAYLENGTH(wshort_desc)); - khui_cfg_register(NULL, ®); + khui_cfg_register(idents, ®); + + khui_cfg_release(idents); - if(KHM_SUCCEEDED(rv)) { krb4_initialized = TRUE; khm_krb4_list_tickets(); } + + /* Lookup common data types */ + if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ENCTYPE, + &type_id_enctype))) { + rv = KHM_ERROR_UNKNOWN; + } + + if(KHM_FAILED(kcdb_type_get_id(TYPENAME_ADDR_LIST, + &type_id_addr_list))) { + rv = KHM_ERROR_UNKNOWN; + } + + if(KHM_FAILED(kcdb_type_get_id(TYPENAME_KRB5_FLAGS, + &type_id_krb5_flags))) { + rv = KHM_ERROR_UNKNOWN; + } + + /* Lookup common attributes */ + if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KEY_ENCTYPE, + &attr_id_key_enctype))) { + rv = KHM_ERROR_UNKNOWN; + } + + if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_TKT_ENCTYPE, + &attr_id_tkt_enctype))) { + rv = KHM_ERROR_UNKNOWN; + } + + if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_ADDR_LIST, + &attr_id_addr_list))) { + rv = KHM_ERROR_UNKNOWN; + } + + if(KHM_FAILED(kcdb_attrib_get_id(ATTRNAME_KRB5_FLAGS, + &attr_id_krb5_flags))) { + rv = KHM_ERROR_UNKNOWN; + } + } break; @@ -140,11 +225,47 @@ krb4_msg_cred(khm_int32 msg_type, khm_int32 msg_subtype, khm_int32 rv = KHM_ERROR_SUCCESS; switch(msg_subtype) { - case KMSG_CRED_REFRESH: - { - khm_krb4_list_tickets(); + case KMSG_CRED_REFRESH: + { + khm_krb4_list_tickets(); + } + break; + + case KMSG_CRED_DESTROY_CREDS: + { + khui_action_context * ctx; + khm_handle credset; + khm_size nc_root = 0; + khm_size nc_sel = 0; + + ctx = (khui_action_context *) vparam; + + /* if all krb4 tickets are selected, then we destroy all + of them. Otherwise, we do nothing. */ + + kcdb_credset_create(&credset); + + kcdb_credset_extract(credset, ctx->credset, + NULL, credtype_id_krb4); + kcdb_credset_get_size(credset, &nc_sel); + + kcdb_credset_flush(credset); + + kcdb_credset_extract(credset, NULL, + NULL, credtype_id_krb4); + kcdb_credset_get_size(credset, &nc_root); + + kcdb_credset_delete(credset); + + if (nc_root == nc_sel) { + khm_krb4_kdestroy(); } - break; + } + break; + + default: + if (IS_CRED_ACQ_MSG(msg_subtype)) + return krb4_msg_newcred(msg_type, msg_subtype, uparam, vparam); } return rv; diff --git a/src/windows/identity/plugins/krb4/krbconfig.csv b/src/windows/identity/plugins/krb4/krbconfig.csv index bed0d1ccb..9aa7cd944 100644 --- a/src/windows/identity/plugins/krb4/krbconfig.csv +++ b/src/windows/identity/plugins/krb4/krbconfig.csv @@ -6,18 +6,11 @@ Krb4Cred,KC_SPACE,0,"Kerberos IV Credentials Provider" Type,KC_INT32,1, Flags,KC_INT32,0, Parameters,KC_SPACE,0,Parameters for KrbCred + Krb4NewCreds,KC_INT32,1,Obtain Kerberos 4 tickets + Krb4Method,KC_INT32,0,Method for acquiring K4 tix. 0-Auto;1-Password;2-K524 CreateMissingConfig,KC_INT32,0,Create missing configuration files - MsLsaImport,KC_INT32,2,Automatically import MSLSA credentials - AutoRenewTickets,KC_INT32,1,Automatically renew expiring tickets DefaultLifetime,KC_INT32,36000,Default ticket lifetime MaxLifetime,KC_INT32,86400,Maximum lifetime MinLifetime,KC_INT32,60,Minimum lifetime - Forwardable,KC_INT32,1,Obtain forwardable tickets (boolean) - Proxiable,KC_INT32,0,Obtain proxiable tickets (boolean) - Addressless,KC_INT32,1,Obtain addressless tickets (boolean) - Renewable,KC_INT32,1,Obtain renewable tickets (boolean) - DefaultRenewLifetime,KC_INT32,604800,Default renewable lifetime - MaxRenewLifetime,KC_INT32,2592000,Maximum renewable lifetime - MinRenewLifetime,KC_INT32,60,Maximum renewable lifetime Parameters,KC_ENDSPACE,0, Krb4Cred,KC_ENDSPACE,0, diff --git a/src/windows/identity/plugins/krb4/krbcred.h b/src/windows/identity/plugins/krb4/krbcred.h index e56d114ee..9f5d3c932 100644 --- a/src/windows/identity/plugins/krb4/krbcred.h +++ b/src/windows/identity/plugins/krb4/krbcred.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -29,11 +29,11 @@ #include -#include -#include -#include -#include +#define KHERR_FACILITY L"Kerberos4" +#define KHERR_FACILITY_ID 65 +#define KHERR_HMODULE hResModule +#include #include #include @@ -41,7 +41,6 @@ #include #include -#include #define TYPENAME_ENCTYPE L"EncType" #define TYPENAME_ADDR_LIST L"AddrList" @@ -86,8 +85,13 @@ extern khm_int32 attr_id_renew_for; #define KRB4_CREDTYPE_NAME L"Krb4Cred" +#define KRB5_CREDTYPE_NAME L"Krb5Cred" + #define KRB4_CONFIG_NODE_NAME L"Krb4Config" +#define KRB4_ID_CONFIG_NODE_NAME L"Krb4IdentConfig" +#define KRB4_IDS_CONFIG_NODE_NAME L"Krb4IdentsConfig" + extern khm_handle csp_plugins; extern khm_handle csp_krbcred; extern khm_handle csp_params; @@ -96,6 +100,7 @@ extern kconf_schema schema_krbconfig[]; /* other globals */ extern khm_int32 credtype_id_krb4; +extern khm_int32 credtype_id_krb5; extern khm_boolean krb4_initialized; @@ -111,4 +116,20 @@ krb4_confg_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +INT_PTR CALLBACK +krb4_ids_config_proc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); + +INT_PTR CALLBACK +krb4_id_config_proc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); + +khm_int32 +krb4_msg_newcred(khm_int32 msg_type, khm_int32 msg_subtype, + khm_ui_4 uparam, void * vparam); #endif diff --git a/src/windows/identity/plugins/krb4/lang/en_us/langres.rc b/src/windows/identity/plugins/krb4/lang/en_us/langres.rc index a5d62a26a..042da77b7 100644 --- a/src/windows/identity/plugins/krb4/lang/en_us/langres.rc +++ b/src/windows/identity/plugins/krb4/lang/en_us/langres.rc @@ -57,7 +57,18 @@ STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - LTEXT "kRB4",IDC_STATIC,38,43,71,24 + CONTROL "Kerberos 4 Ticket Options",IDC_STATIC,"Static", + SS_LEFTNOWORDWRAP | SS_SUNKEN | WS_GROUP,7,7,286,11 + CONTROL "Obtain Kerberos 4 tickets",IDC_NCK4_OBTAIN,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,26,97,10 + CONTROL "Automatically determine method",IDC_NCK4_AUTO,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,23,58,119,10 + CONTROL "Password",IDC_NCK4_PWD,"Button",BS_AUTORADIOBUTTON | + WS_TABSTOP,23,75,47,10 + CONTROL "Kerberos 5 to 4 translation",IDC_NCK4_K524,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,23,92,101,10 + GROUPBOX "Obtain Kerberos 4 tickets using",IDC_STATIC,7,43,286,72, + WS_GROUP END IDD_CFG_KRB4 DIALOGEX 0, 0, 255, 182 @@ -75,6 +86,27 @@ BEGIN PUSHBUTTON "Browse...",IDC_CFG_RLMBROW,200,47,48,14 END +IDD_CFG_IDS_KRB4 DIALOGEX 0, 0, 235, 151 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "Obtain Kerberos 4 tickets",IDC_CFG_GETTIX,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,7,221,17 + LTEXT "Note that, if enabled, Kerberos 4 tickets will be acquired during initial credential acquisition and during credential renewals.\n\nHowever, currently Kerberos 4 tickets can only be obtained for the default identity.", + IDC_STATIC,7,91,221,53,SS_SUNKEN +END + +IDD_CFG_ID_KRB4 DIALOGEX 0, 0, 235, 151 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "Obtain Kerberos 4 tickets for this identity", + IDC_CFG_GETTIX,"Button",BS_AUTOCHECKBOX | WS_DISABLED | + WS_TABSTOP,7,7,147,10 +END + ///////////////////////////////////////////////////////////////////////////// // @@ -102,6 +134,22 @@ BEGIN TOPMARGIN, 7 BOTTOMMARGIN, 175 END + + IDD_CFG_IDS_KRB4, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 228 + TOPMARGIN, 7 + BOTTOMMARGIN, 144 + END + + IDD_CFG_ID_KRB4, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 228 + TOPMARGIN, 7 + BOTTOMMARGIN, 144 + END END #endif // APSTUDIO_INVOKED @@ -114,6 +162,14 @@ END STRINGTABLE BEGIN IDS_PLUGIN_DESC "Kerberos 4 Credentials Provider" + IDS_NC_K4_SHORT "Kerberos 4" + IDS_ERR_REALM "Could not resolve realm" + IDS_ERR_PRINCIPAL "Invalid principal" + IDS_ERR_INVINST "Invalid instance" + IDS_ERR_PWINTKT "Could not get Kerberos 4 tickets" + IDS_CT_DISABLED "

Krb4: Disabled (click here to enable)

" + IDS_CT_TGTFOR "

Krb4: Tickets for realm %s

" + IDS_METHOD_AUTO "Automatically determined method" END STRINGTABLE @@ -124,6 +180,13 @@ BEGIN IDS_CFG_KRB4_SHORT "Kerberos 4" END +STRINGTABLE +BEGIN + IDS_METHOD_PWD "Password" + IDS_METHOD_K524 "Kerberos 5 to 4 translation" + IDS_CFG_IDS_KRB4_SHORT "Kerberos 4" +END + #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/src/windows/identity/plugins/krb4/langres.h b/src/windows/identity/plugins/krb4/langres.h index 2096adec3..ceb236007 100644 --- a/src/windows/identity/plugins/krb4/langres.h +++ b/src/windows/identity/plugins/krb4/langres.h @@ -1,6 +1,6 @@ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. -// Used by D:\work\khimaira\src\plugins\krb4\lang\en_us\langres.rc +// Used by D:\work\pismere\athena\auth\krb5\src\windows\identity\plugins\krb4\lang\en_us\langres.rc // #define IDS_UNK_ADDR_FMT 101 #define IDS_KRB5_CREDTEXT_0 102 @@ -8,16 +8,29 @@ #define IDS_PLUGIN_DESC 103 #define IDS_KEY_ENCTYPE_SHORT_DESC 104 #define IDD_CFG_KRB4 104 +#define IDS_NC_K4_SHORT 104 #define IDS_TKT_ENCTYPE_SHORT_DESC 105 +#define IDS_ERR_REALM 105 +#define IDD_CFG_IDS_KRB4 105 #define IDS_KEY_ENCTYPE_LONG_DESC 106 +#define IDS_ERR_PRINCIPAL 106 +#define IDD_CFG_ID_KRB4 106 #define IDS_TKT_ENCTYPE_LONG_DESC 107 +#define IDS_ERR_INVINST 107 #define IDS_ADDR_LIST_SHORT_DESC 108 +#define IDS_ERR_PWINTKT 108 #define IDS_ADDR_LIST_LONG_DESC 109 +#define IDS_CT_DISABLED 109 #define IDS_ETYPE_NULL 110 +#define IDS_CT_TGTFOR 110 #define IDS_ETYPE_DES_CBC_CRC 111 +#define IDS_METHOD_AUTO 111 #define IDS_ETYPE_DES_CBC_MD4 112 +#define IDS_METHOD_PWD 112 #define IDS_ETYPE_DES_CBC_MD5 113 +#define IDS_METHOD_K524 113 #define IDS_ETYPE_DES_CBC_RAW 114 +#define IDS_CFG_IDS_KRB4_SHORT 114 #define IDS_ETYPE_DES3_CBC_SHA 115 #define IDS_ETYPE_DES3_CBC_RAW 116 #define IDS_ETYPE_DES_HMAC_SHA1 117 @@ -65,14 +78,20 @@ #define IDC_CFG_RLMPATH 1030 #define IDC_CFG_CFGBROW 1031 #define IDC_CFG_RLMBROW 1032 +#define IDC_NCK4_OBTAIN 1033 +#define IDC_NCK4_PWD 1034 +#define IDC_NCK4_K524 1035 +#define IDC_NCK4_AUTO 1036 +#define IDC_CFG_GETTIX 1037 +#define IDC_CHECK1 1038 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 105 +#define _APS_NEXT_RESOURCE_VALUE 107 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1033 +#define _APS_NEXT_CONTROL_VALUE 1039 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/src/windows/identity/plugins/krb4/version.rc b/src/windows/identity/plugins/krb4/version.rc new file mode 100644 index 000000000..3ca6b1cb9 --- /dev/null +++ b/src/windows/identity/plugins/krb4/version.rc @@ -0,0 +1,66 @@ +/* Copyright (c) 2004 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +/* $Id$ */ + +#include + +1 VERSIONINFO + FILEVERSION KH_VERSION_LIST + PRODUCTVERSION KH_VERSION_LIST + FILEFLAGSMASK KH_VER_FILEFLAGMASK + FILEFLAGS KH_VER_FILEFLAGS + FILEOS KH_VER_FILEOS + FILETYPE KH_VER_FILETYPEDLL + FILESUBTYPE 0 + { + + BLOCK "StringFileInfo" + { + BLOCK "040904b0" + { + VALUE "CompanyName", KH_VERSTR_COMPANY_1033 + VALUE "FileDescription", "Kerberos 4 plugin for NetIDMgr" + VALUE "FileVersion", KH_VERSTR_VERSION_1033 + VALUE "InternalName", "krb4cred" + VALUE "LegalCopyright", KH_VERSTR_COPYRIGHT_1033 + VALUE "OriginalFilename", "krb4cred.dll" + VALUE "ProductName", "NetIDMgr" + VALUE "ProductVersion", KH_VERSTR_PRODUCT_1033 +#ifdef KH_VERSTR_COMMENT_1033 + VALUE "Comment", KH_VERSTR_COMMENT_1033 +#endif + VALUE NIMV_MODULE, "MITKrb4" + VALUE NIMV_PLUGINS, "Krb4Cred" + VALUE NIMV_APIVER, KH_VERSION_STRINGAPI + VALUE NIMV_SUPPORT, "http://web.mit.edu/kerberos" + } + } + + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x409, 1200 + } + + } diff --git a/src/windows/identity/plugins/krb5/Makefile b/src/windows/identity/plugins/krb5/Makefile index 9bf9ef020..e0553d846 100644 --- a/src/windows/identity/plugins/krb5/Makefile +++ b/src/windows/identity/plugins/krb5/Makefile @@ -32,7 +32,7 @@ LIBFILE=$(LIBDIR)\krb5cred.lib OBJFILES= \ $(LIBDIR)\dynimport.obj \ $(LIBDIR)\krb5common.obj \ - $(OBJ)\main.obj \ + $(OBJ)\krb5main.obj \ $(OBJ)\datarep.obj \ $(OBJ)\errorfuncs.obj \ $(OBJ)\krb5plugin.obj \ @@ -41,21 +41,28 @@ OBJFILES= \ $(OBJ)\krb5funcs.obj \ $(OBJ)\krb5config.obj \ $(OBJ)\krb5identpro.obj \ - $(OBJ)\krb5configdlg.obj + $(OBJ)\krb5configdlg.obj \ + $(OBJ)\krb5configcc.obj \ + $(OBJ)\krb5configid.obj \ + $(OBJ)\krb5configids.obj LIBFILES= \ $(LIBDIR)\nidmgr32.lib \ $(KFWLIBDIR)\loadfuncs.lib SDKLIBFILES= \ - netapi32.lib + netapi32.lib \ + shlwapi.lib \ + comctl32.lib MSGRESFILE=$(OBJ)\krb5_msgs.res +VERRESFILE=$(OBJ)\version.res + $(OBJ)\krb5config.c: krbconfig.csv $(CONFDIR)\csvschema.cfg $(CCSV) $** $@ -$(DLLFILE): $(MSGRESFILE) $(OBJFILES) +$(DLLFILE): $(MSGRESFILE) $(VERRESFILE) $(OBJFILES) $(DLLGUILINK) $(LIBFILES) $(SDKLIBFILES) $(MSGRESFILE): $(OBJ)\krb5_msgs.rc diff --git a/src/windows/identity/plugins/krb5/datarep.c b/src/windows/identity/plugins/krb5/datarep.c index f8cc4cc48..2c4036083 100644 --- a/src/windows/identity/plugins/krb5/datarep.c +++ b/src/windows/identity/plugins/krb5/datarep.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -39,7 +39,7 @@ khm_int32 KHMAPI enctype_toString(const void * data, khm_size cbdata, wchar_t *d size_t cblength; if(cbdata != sizeof(khm_int32)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; etype = *((khm_int32 *) data); diff --git a/src/windows/identity/plugins/krb5/datarep.h b/src/windows/identity/plugins/krb5/datarep.h index e5388f01d..ac6771cb9 100644 --- a/src/windows/identity/plugins/krb5/datarep.h +++ b/src/windows/identity/plugins/krb5/datarep.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -34,4 +34,4 @@ khm_int32 KHMAPI krb5flags_toString(const void *, khm_size, wchar_t *, khm_size khm_int32 KHMAPI renew_for_cb(khm_handle cred, khm_int32 id, void * buffer, khm_size * pcbsize); -#endif \ No newline at end of file +#endif diff --git a/src/windows/identity/plugins/krb5/errorfuncs.c b/src/windows/identity/plugins/krb5/errorfuncs.c index ab64889cb..28016d3cb 100644 --- a/src/windows/identity/plugins/krb5/errorfuncs.c +++ b/src/windows/identity/plugins/krb5/errorfuncs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/plugins/krb5/errorfuncs.h b/src/windows/identity/plugins/krb5/errorfuncs.h index 46d68f9fc..86fc5b440 100644 --- a/src/windows/identity/plugins/krb5/errorfuncs.h +++ b/src/windows/identity/plugins/krb5/errorfuncs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/ui/images/wgt_arrow_expand.ico b/src/windows/identity/plugins/krb5/images/deleted.ico similarity index 77% rename from src/windows/identity/ui/images/wgt_arrow_expand.ico rename to src/windows/identity/plugins/krb5/images/deleted.ico index 485b537b03ce7758cc82dd275e16d3b2cc921898..a8063f9ee72d8b209717fad18acb3384f8309e44 100644 GIT binary patch delta 277 zcmah@%L#xm41Hox9mkW`9>k>thj0-`aH>Ktsd;G%JqQL~@;)K0M2Ytn&QiegK|-T- zPfC~BN;BVXI(LcBT+_b6oYJ};SF)=?yM2JHl|AhT>HO&{g(X1_Kvv+H6!QRTJz*Gq I=d}XF3w@W3h5!Hn delta 247 zcmeyz^^a?VE6Zd_R@KQ0teo{h45%OoO&|zO0LVvC0pcSIfcZ!Q*yNFHRANBY&H&^i sNduWdlLc9|9RB}jV1VJ@K=w}{{sF@EKx_}h@=zMY{|}J|se|bO0HBjD7ytkO diff --git a/src/windows/identity/plugins/krb5/images/krb5plugin.ico b/src/windows/identity/plugins/krb5/images/krb5plugin.ico new file mode 100644 index 0000000000000000000000000000000000000000..791b359694d86dcdc85bd083d502db8056283771 GIT binary patch literal 7278 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 diff --git a/src/windows/identity/plugins/krb5/images/new.ico b/src/windows/identity/plugins/krb5/images/new.ico new file mode 100644 index 0000000000000000000000000000000000000000..1049eb2148f1596a26c22ad7e4522af43af9c49c GIT binary patch literal 1406 zcmb7^p-&u95XL`Jnw&s@IfZCZMUPorgC`-mpmCG_2bhXe=q61_o-o2E@jNTAcdPS^g#JLTI z>vFuZOs5iGO{c?!Gega0GtGX^bpPXvR##Uw8jZBJwx*4Z4UNZRZEkLAYimo}+uJ%g zIMCkSo_2S4wX?IM>HF0Fe(Iwxl)pmXFYa`4bE6MmzhPvA6NQK&H8evrG^<(;QyksV z9o^9#y)G;01-+0I^n%Vsfgb3A9teS+LZxk{XnNrQ3lfhsx7z_qOLxRCz zFc=I5gP~!U%^My6f`7rkZc)L%(3=87fuYccx@~l&Jv|Cn z&UG8+5UX-rnlr z;X#j&kGk(upH5Ht9Z%_Q{SDL$^;%Zz*0g5-eXwkC3`>{UvfA^!|06KJpU=q`QeEG7 zUDwZtDK+o9N!Kk_wA+)(r29L6{_Otq^}Xi(Tz##yJf0+oPx7G;{MWtsH-t7_L>({l Kw~X&-U5(!qarT4& literal 0 HcmV?d00001 diff --git a/src/windows/identity/plugins/krb5/images/normal.ico b/src/windows/identity/plugins/krb5/images/normal.ico new file mode 100644 index 0000000000000000000000000000000000000000..56a702fee1913ebd6925a6d7fcf7f0e123be3062 GIT binary patch literal 1406 zcmd6np>A725Jj(5S2Bo{m>3zfK@A=h8XhUcIBe8E2q`c!u2d<~vVgWyK}o*AsGuI~ zkOl=riYhf>mI|h4$Bk4Kv?}X+p52}6-M#0{K3f`a@9n9smrtb$qZdS%o)H6$Xltf|K#Mr-BQ(5Lk`t#5Dj`ol+zjBuh6u}uxl&}d=JgTY`h7zzmngTY`h z7z~EOgu!4i7z_r3q0nJ47z_r3!C6+AwG^HM|>NHa2N^H@xdO${QX3hJVAqA5p`b%JfFtm$qwO5jAmE73!GqOtvnXH*SOSQ^uwDUJf`!4PKnPg)5bVR51T4|(Q7rv! z=%;`NL&A_SBn$~d!ceah3;{#JkT3)cY(p>~hJ+zuNEq0fK!+h=NEi};#6Q?9S(r?6 z_Hc5CBWv$I$MszAbb5NKv$HcT77Lx9pKG;R>GJYYS65fMzP{GY&5iEv?)32Rpv`8Z z`|qi@7Z?1F=Tx`<271SSmGyml+Oxl1yT4q0?k>xIUc3Kg{u}R~pKn_S{_CFnTRg7& E0S~(Oi~s-t literal 0 HcmV?d00001 diff --git a/src/windows/identity/plugins/krb5/krb5configcc.c b/src/windows/identity/plugins/krb5/krb5configcc.c new file mode 100644 index 000000000..256f6b75e --- /dev/null +++ b/src/windows/identity/plugins/krb5/krb5configcc.c @@ -0,0 +1,547 @@ +/* + * Copyright (c) 2005 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* $Id$ */ + +#include +#include +#include +#include +#include + +#pragma warning(push) +#pragma warning(disable: 4995) +#include +#pragma warning(pop) + +typedef struct tag_k5_file_cc { + wchar_t path[MAX_PATH]; + khm_int32 flags; +} k5_file_cc; + +#define K5_FCC_ALLOC_INCR 8 + +#define K5_FCC_FLAG_EXISTS 1 + +typedef struct tag_k5_ccc_data { + khm_boolean inc_api; + khm_boolean inc_mslsa; + k5_file_cc * file_ccs; + khm_size n_file_ccs; + khm_size nc_file_ccs; +} k5_ccc_data; + +typedef struct tag_k5_ccc_dlg_data { + khui_config_node node; + k5_ccc_data save; + k5_ccc_data work; +} k5_ccc_dlg_data; + +void k5_free_file_ccs(k5_ccc_data * d) { + if (d->file_ccs) + PFREE(d->file_ccs); + d->n_file_ccs = 0; + d->nc_file_ccs = 0; +} + +void k5_flush_file_ccs(k5_ccc_data * d) { + d->n_file_ccs = 0; +} + +void k5_del_file_cc(k5_ccc_data * d, khm_size idx) { + if (idx > d->n_file_ccs) + return; + + if (idx < d->n_file_ccs - 1) { + MoveMemory(&d->file_ccs[idx], + &d->file_ccs[idx + 1], + sizeof(d->file_ccs[0]) * (d->n_file_ccs - (idx + 1))); + } + + d->n_file_ccs--; +} + +void k5_add_file_cc(k5_ccc_data * d, wchar_t * path) { + khm_size i; + khm_size cch; + + if (FAILED(StringCchLength(path, MAX_PATH, &cch)) || + cch == 0) + return; + + /* see if it's there first */ + for (i=0; i < d->n_file_ccs; i++) { + if(!wcsicmp(d->file_ccs[i].path, path)) + return; + } + + if (d->n_file_ccs == d->nc_file_ccs) { + k5_file_cc * f; + + d->nc_file_ccs = UBOUNDSS(d->n_file_ccs + 1, + K5_FCC_ALLOC_INCR, + K5_FCC_ALLOC_INCR); +#ifdef DEBUG + assert(d->nc_file_ccs > d->n_file_ccs); +#endif + f = PMALLOC(sizeof(*f) * d->nc_file_ccs); + ZeroMemory(f, sizeof(*f) * d->nc_file_ccs); + + if (d->n_file_ccs > 0) { +#ifdef DEBUG + assert(d->file_ccs != NULL); +#endif + memcpy(f, d->file_ccs, sizeof(*f) * d->n_file_ccs); + } + if (d->file_ccs) + PFREE(d->file_ccs); + d->file_ccs = f; + } + + StringCbCopy(d->file_ccs[d->n_file_ccs].path, + sizeof(d->file_ccs[0].path), + path); + if(PathFileExists(path)) + d->file_ccs[d->n_file_ccs].flags = K5_FCC_FLAG_EXISTS; + else + d->file_ccs[d->n_file_ccs].flags = 0; + + d->n_file_ccs++; +} + +void k5_read_file_cc_data(k5_ccc_data * d) { + khm_int32 t; + wchar_t * fclist = NULL; + wchar_t * fc; + khm_size cb; + +#ifdef DEBUG + assert(csp_params); +#endif + + d->inc_api = TRUE; + t = TRUE; + khc_read_int32(csp_params, L"MsLsaList", &t); + d->inc_mslsa = t; + + if (khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb) + != KHM_ERROR_TOO_LONG || + cb <= sizeof(wchar_t) * 2) { + + k5_flush_file_ccs(d); + } else { + fclist = PMALLOC(cb); +#ifdef DEBUG + assert(fclist); +#endif + khc_read_multi_string(csp_params, L"FileCCList", fclist, &cb); + + for(fc = fclist; fc && *fc; fc = multi_string_next(fc)) { + k5_add_file_cc(d, fc); + } + + PFREE(fclist); + } +} + +void k5_write_file_cc_data(k5_ccc_data * d) { + wchar_t * ms; + khm_size cb; + khm_size cbt; + khm_int32 t; + khm_size i; + +#ifdef DEBUG + assert(csp_params); +#endif + if (KHM_FAILED(khc_read_int32(csp_params, L"MsLsaList", &t)) || + !!t != !!d->inc_mslsa) { + khc_write_int32(csp_params, L"MsLsaList", !!d->inc_mslsa); + } + + if (d->n_file_ccs > 0) { + cb = d->n_file_ccs * MAX_PATH * sizeof(wchar_t); + ms = PMALLOC(cb); +#ifdef DEBUG + assert(ms); +#endif + multi_string_init(ms, cb); + + for(i=0; in_file_ccs; i++) { + cbt = cb; + multi_string_append(ms, &cbt, d->file_ccs[i].path); + } + + khc_write_multi_string(csp_params, L"FileCCList", ms); + + PFREE(ms); + } else { + if (khc_read_multi_string(csp_params, L"FileCCList", NULL, &cb) + != KHM_ERROR_TOO_LONG || + cb != sizeof(wchar_t) * 2) + + khc_write_multi_string(csp_params, L"FileCCList", L"\0\0"); + } +} + +void k5_copy_file_cc_data(k5_ccc_data * dest, const k5_ccc_data * src) { + khm_size i; + + k5_flush_file_ccs(dest); + dest->inc_mslsa = src->inc_mslsa; + dest->inc_api = src->inc_api; + + for (i=0; i < src->n_file_ccs; i++) { + k5_add_file_cc(dest, src->file_ccs[i].path); + } +} + +BOOL k5_ccc_get_mod(k5_ccc_dlg_data * d) { + khm_size i, j; + + if (!!d->work.inc_mslsa != !!d->save.inc_mslsa || + !!d->work.inc_api != !!d->save.inc_api || + d->work.n_file_ccs != d->save.n_file_ccs) + return TRUE; + + for (i=0; i < d->work.n_file_ccs; i++) { + for (j=0; j < d->save.n_file_ccs; j++) { + if (!wcsicmp(d->work.file_ccs[i].path, + d->save.file_ccs[j].path)) + break; + } + if (j >= d->save.n_file_ccs) + return TRUE; + } + + return FALSE; +} + +void k5_ccc_update_ui(HWND hwnd, k5_ccc_dlg_data * d) { + khm_size i; + HWND lv; + + if (d->work.inc_api) + CheckDlgButton(hwnd, IDC_CFG_INCAPI, BST_CHECKED); + else + CheckDlgButton(hwnd, IDC_CFG_INCAPI, BST_UNCHECKED); + if (d->work.inc_mslsa) + CheckDlgButton(hwnd, IDC_CFG_INCMSLSA, BST_CHECKED); + else + CheckDlgButton(hwnd, IDC_CFG_INCMSLSA, BST_UNCHECKED); + + lv = GetDlgItem(hwnd, IDC_CFG_FCLIST); +#ifdef DEBUG + assert(lv); +#endif + ListView_DeleteAllItems(lv); + + for (i=0; iwork.n_file_ccs; i++) { + LVITEM lvi; + + ZeroMemory(&lvi, sizeof(lvi)); + + lvi.mask = LVIF_PARAM | LVIF_TEXT; + lvi.lParam = (LPARAM) i; + lvi.pszText = d->work.file_ccs[i].path; + + ListView_InsertItem(lv, &lvi); + } + + if (k5_ccc_get_mod(d)) { + khui_cfg_set_flags(d->node, + KHUI_CNFLAG_MODIFIED, + KHUI_CNFLAG_MODIFIED); + } else { + khui_cfg_set_flags(d->node, + 0, + KHUI_CNFLAG_MODIFIED); + } +} + +void k5_ccc_update_data(HWND hwnd, k5_ccc_data * d) { + if (IsDlgButtonChecked(hwnd, IDC_CFG_INCAPI) == BST_CHECKED) + d->inc_api = TRUE; + else + d->inc_api = FALSE; + + if (IsDlgButtonChecked(hwnd, IDC_CFG_INCMSLSA) == BST_CHECKED) + d->inc_mslsa = TRUE; + else + d->inc_mslsa = FALSE; + /* everything else is controlled by buttons */ +} + +INT_PTR CALLBACK +k5_ccconfig_dlgproc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { + + k5_ccc_dlg_data * d; + + switch(uMsg) { + case WM_INITDIALOG: + d = PMALLOC(sizeof(*d)); +#ifdef DEBUG + assert(d); +#endif + ZeroMemory(d, sizeof(*d)); + k5_read_file_cc_data(&d->save); + k5_copy_file_cc_data(&d->work, &d->save); + + d->node = (khui_config_node) lParam; + +#pragma warning(push) +#pragma warning(disable: 4244) + SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d); +#pragma warning(pop) + + { + LVCOLUMN lvc; + HWND lv; + wchar_t buf[256]; + RECT r; + + lv = GetDlgItem(hwnd, IDC_CFG_FCLIST); +#ifdef DEBUG + assert(lv); +#endif + ZeroMemory(&lvc, sizeof(lvc)); + lvc.mask = LVCF_TEXT | LVCF_WIDTH; + + LoadString(hResModule, IDS_CFG_FCTITLE, + buf, ARRAYLENGTH(buf)); + + GetWindowRect(lv, &r); + + lvc.pszText = buf; + lvc.cx = (r.right - r.left) * 9 / 10; + + ListView_InsertColumn(lv, 0, &lvc); + } + + SendDlgItemMessage(hwnd, IDC_CFG_FCNAME, EM_SETLIMITTEXT, + MAX_PATH - 1, 0); + + k5_ccc_update_ui(hwnd, d); + break; + + case WM_COMMAND: + d = (k5_ccc_dlg_data *) (DWORD_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + switch(wParam) { + case MAKEWPARAM(IDC_CFG_ADD, BN_CLICKED): + { + wchar_t path[MAX_PATH]; + wchar_t cpath[MAX_PATH]; + khm_size i; + + GetDlgItemText(hwnd, IDC_CFG_FCNAME, + cpath, ARRAYLENGTH(cpath)); + + PathCanonicalize(path, cpath); + + if (!*path) + return TRUE; /* nothing to add */ + + for (i=0; i < d->work.n_file_ccs; i++) { + if (!wcsicmp(path, d->work.file_ccs[i].path)) { + + /* allow the user to correct case, as appropriate */ + StringCbCopy(d->work.file_ccs[i].path, + sizeof(d->work.file_ccs[i].path), + path); + k5_ccc_update_ui(hwnd, d); + return TRUE; + } + } + + /* not there. we need to add. but check a few things + first */ + if (!PathFileExists(path)) { + EDITBALLOONTIP bt; + wchar_t title[64]; + wchar_t text[128]; + + bt.cbStruct = sizeof(bt); + bt.pszTitle = title; + LoadString(hResModule, IDS_CFG_FCN_WARNING, + title, ARRAYLENGTH(title)); + bt.pszText = text; + LoadString(hResModule, IDS_CFG_FCN_W_NOTFOUND, + text, ARRAYLENGTH(text)); + bt.ttiIcon = TTI_WARNING; + + SendDlgItemMessage(hwnd, IDC_CFG_FCNAME, + EM_SHOWBALLOONTIP, + 0, + (LPARAM) &bt); + + } else if (PathIsRelative(path)) { + EDITBALLOONTIP bt; + wchar_t title[64]; + wchar_t text[128]; + + bt.cbStruct = sizeof(bt); + bt.pszTitle = title; + LoadString(hResModule, IDS_CFG_FCN_WARNING, + title, ARRAYLENGTH(title)); + bt.pszText = text; + LoadString(hResModule, IDS_CFG_FCN_W_RELATIVE, + text, ARRAYLENGTH(text)); + bt.ttiIcon = TTI_WARNING; + + SendDlgItemMessage(hwnd, IDC_CFG_FCNAME, + EM_SHOWBALLOONTIP, + 0, + (LPARAM) &bt); + } + + k5_add_file_cc(&d->work, path); + + k5_ccc_update_ui(hwnd, d); + } + return TRUE; + + case MAKEWPARAM(IDC_CFG_BROWSE, BN_CLICKED): + { + OPENFILENAME ofn; + wchar_t path[MAX_PATH * 8]; + wchar_t title[128]; + + ZeroMemory(&ofn, sizeof(ofn)); + ZeroMemory(path, sizeof(path)); + + GetDlgItemText(hwnd, IDC_CFG_FCNAME, + path, ARRAYLENGTH(path)); + + /* don't pass in invalid paths */ + if (!PathFileExists(path)) + *path = 0; + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = L"All files\0*.*\0\0"; + ofn.nFilterIndex = 1; + ofn.lpstrFile = path; + ofn.nMaxFile = ARRAYLENGTH(path); + ofn.lpstrTitle = title; + + LoadString(hResModule, IDS_CFG_FCOPENTITLE, + title, ARRAYLENGTH(title)); + + ofn.Flags = OFN_ALLOWMULTISELECT | + OFN_DONTADDTORECENT | + OFN_FORCESHOWHIDDEN | + OFN_EXPLORER; + + if (GetOpenFileName(&ofn)) { + wchar_t * p; + wchar_t spath[MAX_PATH]; + + p = multi_string_next(path); + if (p) { + /* multi select */ + for(;p && *p; p = multi_string_next(p)) { + StringCbCopy(spath, sizeof(spath), path); + PathAppend(spath, p); + + k5_add_file_cc(&d->work, spath); + } + } else { + /* single select */ + k5_add_file_cc(&d->work, path); + } + k5_ccc_update_ui(hwnd, d); + } + } + return TRUE; + + case MAKEWPARAM(IDC_CFG_REMOVE, BN_CLICKED): + { + khm_size i; + int lv_idx; + HWND lv; + wchar_t buf[MAX_PATH]; + + lv = GetDlgItem(hwnd, IDC_CFG_FCLIST); +#ifdef DEBUG + assert(lv); +#endif + + lv_idx = -1; + while((lv_idx = ListView_GetNextItem(lv, lv_idx, + LVNI_SELECTED)) != -1) { + ListView_GetItemText(lv, lv_idx, 0, buf, ARRAYLENGTH(buf)); + for (i=0; i < d->work.n_file_ccs; i++) { + if (!wcsicmp(buf, d->work.file_ccs[i].path)) { + k5_del_file_cc(&d->work, i); + break; + } + } + } + + k5_ccc_update_ui(hwnd, d); + } + return TRUE; + + case MAKEWPARAM(IDC_CFG_INCAPI, BN_CLICKED): + case MAKEWPARAM(IDC_CFG_INCMSLSA, BN_CLICKED): + k5_ccc_update_data(hwnd, &d->work); + k5_ccc_update_ui(hwnd, d); + return TRUE; + } + break; + + case WM_DESTROY: + d = (k5_ccc_dlg_data *) (DWORD_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + + k5_free_file_ccs(&d->work); + k5_free_file_ccs(&d->save); + PFREE(d); + return TRUE; + + case KHUI_WM_CFG_NOTIFY: + d = (k5_ccc_dlg_data *) (DWORD_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + + switch(HIWORD(wParam)) { + case WMCFG_APPLY: + if (k5_ccc_get_mod(d)) { + k5_write_file_cc_data(&d->work); + k5_copy_file_cc_data(&d->save, &d->work); + khui_cfg_set_flags(d->node, + KHUI_CNFLAG_APPLIED, + KHUI_CNFLAG_APPLIED); + k5_ccc_update_ui(hwnd, d); + + kmq_post_sub_msg(k5_sub, KMSG_CRED, KMSG_CRED_REFRESH, 0, 0); + } + break; + } + } + return FALSE; +} diff --git a/src/windows/identity/plugins/krb5/krb5configdlg.c b/src/windows/identity/plugins/krb5/krb5configdlg.c index c3b00e161..63fdc32b6 100644 --- a/src/windows/identity/plugins/krb5/krb5configdlg.c +++ b/src/windows/identity/plugins/krb5/krb5configdlg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -28,6 +28,860 @@ #include #include #include +#include + +#pragma warning(push) +#pragma warning(disable: 4995) +#include +#pragma warning(pop) + + +typedef struct tag_k5_realm_kdc { + wchar_t name[K5_MAXCCH_HOST]; + khm_boolean admin; /* admin server? */ + khm_boolean master; /* master kdc? */ + khm_int32 flags; +} k5_realm_kdc; + +#define K5_RKFLAG_DELETED 1 +#define K5_RKFLAG_NEW 2 +#define K5_RKFLAG_MOD_ADMIN 4 +#define K5_RKFLAG_MOD_MASTER 8 + +typedef struct tag_k5_domain_map { + wchar_t name[K5_MAXCCH_HOST]; /* name of host that maps to a + realm */ + khm_int32 flags; +} k5_domain_map; + +#define K5_DMFLAG_DELETED 1 +#define K5_DMFLAG_NEW 2 + +typedef struct tag_k5_realm_data { + wchar_t realm[K5_MAXCCH_REALM]; + k5_realm_kdc kdcs[K5_MAX_KDC]; + khm_size n_kdcs; + k5_domain_map domain_maps[K5_MAX_DOMAIN_MAPPINGS]; + khm_size n_domain_maps; + + khm_int32 flags; +} k5_realm_data; + +#define K5_RDFLAG_DELETED 1 +#define K5_RDFLAG_NEW 2 +#define K5_RDFLAG_MODIFED 4 + +#define K5_REALMS_ALLOC_INCR 8 + +typedef struct tag_k5_config_data { + wchar_t def_realm[K5_MAXCCH_REALM]; /* default realm */ + + wchar_t config_file[MAX_PATH]; /* path to configuration file */ + khm_boolean create_config_file; /* create config_file if missing? */ + + /* [libdefaults] */ + khm_boolean dns_lookup_kdc; + khm_boolean dns_lookup_realm; + khm_boolean dns_fallback; + + khm_boolean noaddresses; + + k5_lsa_import lsa_import; /* import mslsa creds? */ + + /* [realms] */ + k5_realm_data *realms; + khm_size n_realms; + khm_size nc_realms; + khm_size c_realm; + + khui_config_node node_main; + khui_config_node node_realm; + + khm_int32 flags; +} k5_config_data; + +#define K5_CDFLAG_MOD_DEF_REALM 1 +#define K5_CDFLAG_MOD_CONF_FILE 2 +#define K5_CDFLAG_MOD_DNS_LOOKUP_KDC 4 +#define K5_CDFLAG_MOD_DNS_LOOKUP_RLM 8 +#define K5_CDFLAG_MOD_DNS_FALLBACK 0x10 +#define K5_CDFLAG_MOD_NOADDRESSES 0x20 +#define K5_CDFLAG_MOD_LSA_IMPORT 0x40 +#define K5_CDFLAG_MOD_CREATE_CONF 0x80 +#define K5_CDFLAG_MOD_REALMS 0x1000 + +static const char *const conf_yes[] = { + "y", "yes", "true", "t", "1", "on", + 0, +}; + +static const char *const conf_no[] = { + "n", "no", "false", "nil", "0", "off", + 0, +}; + +int +k5_parse_boolean(const char *s) +{ + const char *const *p; + + for(p=conf_yes; *p; p++) { + if (!stricmp(*p,s)) + return 1; + } + + for(p=conf_no; *p; p++) { + if (!stricmp(*p,s)) + return 0; + } + + /* Default to "no" */ + return 0; +} + +void +k5_init_config_data(k5_config_data * d) { + ZeroMemory(d, sizeof(*d)); +} + +void +k5_free_config_data(k5_config_data * d) { + if (d->realms) + PFREE(d->realms); + + k5_init_config_data(d); +} + +static void +k5_assert_n_realms(k5_config_data * d, khm_size n) { + khm_size nc_realms; + + if (n <= d->nc_realms) + return; + + nc_realms = UBOUNDSS(n, K5_REALMS_ALLOC_INCR, K5_REALMS_ALLOC_INCR); + assert(nc_realms > d->nc_realms); + + d->realms = PREALLOC(d->realms, nc_realms * sizeof(*(d->realms))); + d->nc_realms = nc_realms; + + ZeroMemory(&d->realms[d->n_realms], + (d->nc_realms - d->n_realms) * sizeof(*(d->realms))); +} + +void +k5_purge_config_data(k5_config_data * d, + khm_boolean purge_realms, + khm_boolean purge_kdcs, + khm_boolean purge_dmap) { + khm_size r; + khm_size k; + khm_size m; + + for (r=0; r < d->n_realms; r++) { + if (purge_realms && + (d->realms[r].flags & K5_RDFLAG_NEW) && + (d->realms[r].flags & K5_RDFLAG_DELETED)) { + + if (d->n_realms > r+1) + MoveMemory(&d->realms[r], &d->realms[r+1], + sizeof(d->realms[0]) * (d->n_realms - (r+1))); + r--; + d->n_realms--; + continue; + } + + for (k=0; k < d->realms[r].n_kdcs; k++) { + if (purge_kdcs && + (d->realms[r].kdcs[k].flags & K5_RKFLAG_NEW) && + (d->realms[r].kdcs[k].flags & K5_RKFLAG_DELETED)) { + if (d->realms[r].n_kdcs > k + 1) + MoveMemory(&d->realms[r].kdcs[k], + &d->realms[r].kdcs[k+1], + sizeof(d->realms[0].kdcs[0]) * + (d->realms[r].n_kdcs - (k+1))); + k--; + d->realms[r].n_kdcs--; + continue; + } + } + + if (K5_MAX_KDC > k+1) + ZeroMemory(&d->realms[r].kdcs[k], + sizeof(d->realms[0].kdcs[0]) * + (K5_MAX_KDC - (k + 1))); + + for (m=0; m < d->realms[r].n_domain_maps; m++) { + if (purge_dmap && + (d->realms[r].domain_maps[m].flags & K5_DMFLAG_NEW) && + (d->realms[r].domain_maps[m].flags & K5_DMFLAG_DELETED)) { + if (d->realms[r].n_domain_maps > m + 1) + MoveMemory(&d->realms[r].domain_maps[m], + &d->realms[r].domain_maps[m+1], + sizeof(d->realms[0].domain_maps[0]) * + (d->realms[r].n_domain_maps - (m+1))); + m--; + d->realms[r].n_domain_maps--; + continue; + } + } + + if (K5_MAX_DOMAIN_MAPPINGS > m+1) + ZeroMemory(&d->realms[r].domain_maps[m], + sizeof(d->realms[0].domain_maps[0]) * + (K5_MAX_DOMAIN_MAPPINGS - (m+1))); + } + + if (d->nc_realms > r + 1) + ZeroMemory(&d->realms[r], + sizeof(d->realms[0]) * + (d->nc_realms - (r + 1))); +} + +static khm_boolean +k5_is_profile_loaded(void) { +#ifdef DEBUG + assert(pprofile_init); + assert(pprofile_get_subsection_names); + assert(pprofile_get_values); + assert(pprofile_get_string); + assert(pprofile_get_relation_names); + assert(pprofile_free_list); + assert(pprofile_release_string); + assert(pprofile_release); + assert(pprofile_clear_relation); + assert(pprofile_add_relation); + assert(pprofile_update_relation); + assert(pprofile_flush); +#endif + + if (!pprofile_init || + !pprofile_get_subsection_names || + !pprofile_get_values || + !pprofile_get_string || + !pprofile_get_relation_names || + !pprofile_free_list || + !pprofile_release_string || + !pprofile_release || + !pprofile_clear_relation || + !pprofile_add_relation || + !pprofile_update_relation || + !pprofile_flush) + + return FALSE; + + return TRUE; +} + +void +k5_read_config_data(k5_config_data * d) { + wchar_t * defrealm; + char config_file[MAX_PATH]; + profile_t profile = NULL; + const char *filenames[2]; + long rv; + khm_size s; + + if (!k5_is_profile_loaded()) + return; + + defrealm = khm_krb5_get_default_realm(); + + if (defrealm) { + StringCbCopy(d->def_realm, sizeof(d->def_realm), defrealm); + PFREE(defrealm); + } else { + StringCbCopy(d->def_realm, sizeof(d->def_realm), L""); + } + + khm_krb5_get_profile_file(config_file, ARRAYLENGTH(config_file)); + + AnsiStrToUnicode(d->config_file, sizeof(d->config_file), config_file); + + filenames[0] = config_file; + filenames[1] = NULL; + + rv = pprofile_init(filenames, &profile); + + if (!rv) { + const char * sec_realms[] = { "realms", NULL }; + const char * sec_domain_realm[] = { "domain_realm", NULL }; + char ** sections; + char ** dr_from; + char * boolv; + + /* first fish out a few values from [libdefaults] */ + + rv = pprofile_get_string(profile, "libdefaults", "dns_lookup_kdc", + NULL, NULL, &boolv); + if (!rv && boolv) { + d->dns_lookup_kdc = k5_parse_boolean(boolv); + pprofile_release_string(boolv); + } else + d->dns_lookup_kdc = FALSE; + + rv = pprofile_get_string(profile, "libdefaults", "dns_lookup_realm", + NULL, NULL, &boolv); + if (!rv && boolv) { + d->dns_lookup_realm = k5_parse_boolean(boolv); + pprofile_release_string(boolv); + } else + d->dns_lookup_realm = FALSE; + + rv = pprofile_get_string(profile, "libdefaults", "dns_fallback", + NULL, NULL, &boolv); + if (!rv && boolv) { + d->dns_fallback = k5_parse_boolean(boolv); + pprofile_release_string(boolv); + } else + d->dns_fallback = FALSE; + + rv = pprofile_get_string(profile, "libdefaults", "noaddresses", + NULL, NULL, &boolv); + if (!rv && boolv) { + d->noaddresses = k5_parse_boolean(boolv); + pprofile_release_string(boolv); + } else + d->noaddresses = TRUE; + + /* now we look at the [realms] section */ + rv = pprofile_get_subsection_names(profile, sec_realms, §ions); + + /* what? no realms? whatever */ + if (rv) goto _skip_realms; + + /* get a count first */ + for (s=0; sections[s] && sections[s][0]; s++); + + k5_assert_n_realms(d, s); + d->n_realms = s; + + /* now go through each and fish out the kdcs, admin_server + and master_kdc. */ + for (s=0; sections[s] && sections[s][0]; s++) { + const char * sec_kdcs[] = + { "realms", sections[s], "kdc", NULL }; + + const char * sec_admin[] = + { "realms", sections[s], "admin_server", NULL }; + + const char * sec_master[] = + { "realms", sections[s], "master_kdc", NULL }; + + char ** values; + + AnsiStrToUnicode(d->realms[s].realm, sizeof(d->realms[s].realm), + sections[s]); + d->realms[s].n_kdcs = 0; + d->realms[s].n_domain_maps = 0; + + rv = pprofile_get_values(profile, sec_kdcs, &values); + if (!rv) { + khm_size i; + + for (i=0 ; values[i] && values[i][0] && i < K5_MAX_KDC; i++) { + AnsiStrToUnicode(d->realms[s].kdcs[i].name, + sizeof(d->realms[s].kdcs[i].name), + values[i]); + + } + d->realms[s].n_kdcs = i; + + pprofile_free_list(values); + } + + rv = pprofile_get_values(profile, sec_admin, &values); + if (!rv) { + khm_size i; + khm_size j; + wchar_t kdc_name[K5_MAXCCH_HOST]; + + for (i=0; values[i] && values[i][0]; i++) { + AnsiStrToUnicode(kdc_name, + sizeof(kdc_name), values[i]); + + for (j=0; j < d->realms[s].n_kdcs; j++) + if (!wcsicmp(kdc_name, d->realms[s].kdcs[j].name)) + break; + + if (j < d->realms[s].n_kdcs) { + d->realms[s].kdcs[j].admin = TRUE; + } else if (d->realms[s].n_kdcs < K5_MAX_KDC) { + j = d->realms[s].n_kdcs; + StringCbCopy(d->realms[s].kdcs[j].name, + sizeof(d->realms[s].kdcs[j].name), + kdc_name); + d->realms[s].kdcs[j].admin = TRUE; + d->realms[s].n_kdcs ++; + } + } + pprofile_free_list(values); + } + + rv = pprofile_get_values(profile, sec_master, &values); + if (!rv) { + khm_size i; + khm_size j; + wchar_t kdc_name[K5_MAXCCH_HOST]; + + for (i=0; values[i] && values[i][0]; i++) { + AnsiStrToUnicode(kdc_name, sizeof(kdc_name), values[i]); + + for (j=0; j < d->realms[s].n_kdcs; j++) + if (!wcsicmp(kdc_name, d->realms[s].kdcs[j].name)) + break; + + if (j < d->realms[s].n_kdcs) { + d->realms[s].kdcs[j].master = TRUE; + } else if (d->realms[s].n_kdcs < K5_MAX_KDC) { + j = d->realms[s].n_kdcs; + StringCbCopy(d->realms[s].kdcs[j].name, + sizeof(d->realms[s].kdcs[j].name), + kdc_name); + d->realms[s].kdcs[j].master = TRUE; + d->realms[s].n_kdcs ++; + } + } + + pprofile_free_list(values); + } + } + pprofile_free_list(sections); + + _skip_realms: + + rv = pprofile_get_relation_names(profile, sec_domain_realm, &dr_from); + if (!rv) { + khm_size i; + khm_size j; + char * dr_to; + wchar_t wdr_from[K5_MAXCCH_HOST]; + wchar_t wdr_to[K5_MAXCCH_HOST]; + + for (i=0; dr_from[i] && dr_from[i][0]; i++) { + AnsiStrToUnicode(wdr_from, sizeof(wdr_from), dr_from[i]); + + rv = pprofile_get_string(profile, "domain_realm", dr_from[i], + NULL, NULL, &dr_to); + + if (rv || !dr_to) + continue; + + AnsiStrToUnicode(wdr_to, sizeof(wdr_to), dr_to); + + for (j=0; j < d->n_realms; j++) { + if (!wcsicmp(wdr_to, d->realms[j].realm)) + break; + } + + if (j >= d->n_realms) { + j = d->n_realms; + k5_assert_n_realms(d, j + 1); + + StringCbCopy(d->realms[j].realm, + sizeof(d->realms[j].realm), + wdr_to); + d->realms[j].n_kdcs = 0; + d->realms[j].n_domain_maps = 0; + + d->n_realms++; + } + + if (d->realms[j].n_domain_maps < K5_MAX_DOMAIN_MAPPINGS) { + khm_size k; + + k = d->realms[j].n_domain_maps; + + StringCbCopy(d->realms[j].domain_maps[k].name, + sizeof(d->realms[j].domain_maps[k].name), + wdr_from); + + d->realms[j].n_domain_maps++; + } + + pprofile_release_string(dr_to); + } + pprofile_free_list(dr_from); + } + pprofile_release(profile); + } + + /* last, read the MSLSA import setting */ + { + khm_int32 t; + + if (KHM_SUCCEEDED(khc_read_int32(csp_params, + L"MsLsaImport", &t))) { + d->lsa_import = t; + } else { + d->lsa_import = K5_LSAIMPORT_ALWAYS; + } + } + + d->flags = 0; +} + +void +k5_write_config_data(k5_config_data * d) { + char astr[MAX_PATH * 2]; + char config_file[MAX_PATH]; + profile_t profile = NULL; + const char *filenames[2]; + long rv; + khm_size s; + + if (d->flags == 0) + return; + + if (!k5_is_profile_loaded()) + return; + + if (d->flags & K5_CDFLAG_MOD_DEF_REALM) { + if (SUCCEEDED(StringCbLength(d->def_realm, + sizeof(d->def_realm), &s)) && + s > 0) { + khm_krb5_set_default_realm(d->def_realm); + } + } + + /* write the MSLSA import setting */ + if (d->flags & K5_CDFLAG_MOD_LSA_IMPORT) { + + khc_write_int32(csp_params, L"MsLsaImport", d->lsa_import); + + } + + if (!(d->flags & + (K5_CDFLAG_MOD_CONF_FILE | + K5_CDFLAG_MOD_DNS_FALLBACK | + K5_CDFLAG_MOD_DNS_LOOKUP_RLM | + K5_CDFLAG_MOD_DNS_LOOKUP_KDC | + K5_CDFLAG_MOD_NOADDRESSES | + K5_CDFLAG_MOD_CREATE_CONF | + K5_CDFLAG_MOD_REALMS))) { + + d->flags = 0; + return; + + } + + khm_krb5_get_profile_file(config_file, ARRAYLENGTH(config_file)); + + UnicodeStrToAnsi(astr, sizeof(astr), d->config_file); + + if (stricmp(config_file, astr)) { + assert(FALSE); + } + + filenames[0] = config_file; + filenames[1] = NULL; + + rv = pprofile_init(filenames, &profile); + +#if FAILOVER_TO_TEMPORARY_FILE + if (rv) { + char temp_file[MAX_PATH]; + + khm_krb5_get_temp_profile_file(temp_file, + ARRAYLENGTH(temp_file)); + + filenames[0] = temp_file; + + rv = pprofile_init(filenames, &profile); + + ?? TODO: Also warn if we are doing this + } +#endif + + + if (!rv) { + const char * sec_realms[] = { "realms", NULL }; + const char * sec_domain_realm[] = { "domain_realm", NULL }; + const char * sec_libdefaults[] = { "libdefaults", NULL, NULL }; + khm_size r; + + if (d->flags & K5_CDFLAG_MOD_DNS_LOOKUP_KDC) { + + sec_libdefaults[1] = "dns_lookup_kdc"; + + pprofile_clear_relation(profile, sec_libdefaults); + + rv = pprofile_add_relation(profile, sec_libdefaults, + (d->dns_lookup_kdc)? + conf_yes[0]: + conf_no[0]); + } + + + if (d->flags & K5_CDFLAG_MOD_DNS_LOOKUP_RLM) { + + sec_libdefaults[1] = "dns_lookup_realm"; + + pprofile_clear_relation(profile, sec_libdefaults); + + rv = pprofile_add_relation(profile, sec_libdefaults, + (d->dns_lookup_realm)? + conf_yes[0]: + conf_no[0]); + + } + + if (d->flags & K5_CDFLAG_MOD_DNS_FALLBACK) { + + sec_libdefaults[1] = "dns_fallback"; + + pprofile_clear_relation(profile, sec_libdefaults); + + rv = pprofile_add_relation(profile, sec_libdefaults, + (d->dns_fallback)? + conf_yes[0]: + conf_no[0]); + } + + if (d->flags & K5_CDFLAG_MOD_NOADDRESSES) { + + sec_libdefaults[1] = "noaddresses"; + + pprofile_clear_relation(profile, sec_libdefaults); + + rv = pprofile_add_relation(profile, sec_libdefaults, + (d->noaddresses)? + conf_yes[0]: + conf_no[0]); + } + + /* now we look at the [realms] section */ + + for (r=0; r < d->n_realms; r++) { + char realm[K5_MAXCCH_REALM]; + char host[K5_MAXCCH_HOST]; + + const char * sec_kdcs[] = + { "realms", realm, "kdc", NULL }; + + const char * sec_admin[] = + { "realms", realm, "admin_server", NULL }; + + const char * sec_master[] = + { "realms", realm, "master_kdc", NULL }; + + const char * sec_domain_map[] = + { "domain_realm", host, NULL }; + + char ** values; + + UnicodeStrToAnsi(realm, sizeof(realm), + d->realms[r].realm); + + if (!(d->realms[r].flags & K5_RDFLAG_DELETED) && + (d->realms[r].flags & K5_RDFLAG_NEW)) { + + khm_size k; + khm_size m; + + /* this is a new realm */ + + for (k=0; k < d->realms[r].n_kdcs; k++) { + if (!(d->realms[r].kdcs[k].flags & K5_RKFLAG_DELETED)) { + UnicodeStrToAnsi(host, sizeof(host), + d->realms[r].kdcs[k].name); + + if (d->realms[r].kdcs[k].master) + pprofile_add_relation(profile, sec_master, + host); + else + pprofile_add_relation(profile, sec_kdcs, + host); + + if (d->realms[r].kdcs[k].admin) + pprofile_add_relation(profile, sec_admin, + host); + } + } + + for (m=0; m < d->realms[r].n_domain_maps; m++) { + + UnicodeStrToAnsi(host, sizeof(host), + d->realms[r].domain_maps[m].name); + + if ((d->realms[r].domain_maps[m].flags & + K5_DMFLAG_DELETED) && + !(d->realms[r].domain_maps[m].flags & + K5_DMFLAG_NEW)) + pprofile_clear_relation(profile, sec_domain_map); + else if (!(d->realms[r].domain_maps[m].flags & + K5_DMFLAG_DELETED) && + (d->realms[r].domain_maps[m].flags & + K5_DMFLAG_NEW)) + pprofile_add_relation(profile, sec_domain_map, + realm); + } + } else if ((d->realms[r].flags & K5_RDFLAG_DELETED) && + !(d->realms[r].flags & K5_RDFLAG_NEW)) { + + const char * sec_all[] = + { "realms", realm, NULL, NULL }; + khm_size v; + + /* this realm should be deleted */ + + rv = pprofile_get_relation_names(profile, sec_all, + &values); + if (!rv) { + for (v=0; values[v] && values[v][0]; v++) { + sec_all[2] = values[v]; + pprofile_clear_relation(profile, sec_all); + } + pprofile_free_list(values); + } + + rv = pprofile_get_relation_names(profile, sec_domain_realm, + &values); + if (!rv) { + char * maprealm; + + for (v=0; values[v] && values[v][0]; v++) { + + rv = pprofile_get_string(profile, "domain_realm", + values[v], NULL, NULL, + &maprealm); + + if (!rv) { + if (!strcmp(maprealm, realm)) { + StringCbCopyA(host, sizeof(host), + values[v]); + pprofile_clear_relation(profile, + sec_domain_map); + } + pprofile_release_string(maprealm); + } + } + + pprofile_free_list(values); + } + } else if (!(d->realms[r].flags & K5_RDFLAG_DELETED)) { + khm_size k; + khm_size m; + + /* same as before. check if we have to update the kdc + list or the domain_realm mappings */ + + for (k=0; k < d->realms[r].n_kdcs; k++) { + UnicodeStrToAnsi(host, sizeof(host), + d->realms[r].kdcs[k].name); + if (d->realms[r].kdcs[k].flags & K5_RKFLAG_DELETED) { + pprofile_update_relation(profile, sec_kdcs, + host, NULL); + pprofile_update_relation(profile, sec_admin, + host, NULL); + pprofile_update_relation(profile, sec_master, + host, NULL); + + continue; + } + + if (d->realms[r].kdcs[k].flags & K5_RKFLAG_NEW) { + if (d->realms[r].kdcs[k].master) + pprofile_add_relation(profile, sec_master, + host); + else + pprofile_add_relation(profile, sec_kdcs, + host); + + if (d->realms[r].kdcs[k].admin) + pprofile_add_relation(profile, sec_admin, + host); + continue; + } + + if (d->realms[r].kdcs[k].flags & K5_RKFLAG_MOD_MASTER) { + if (!d->realms[r].kdcs[k].master) { + pprofile_add_relation(profile, sec_kdcs, + host); + pprofile_update_relation(profile, sec_master, + host, NULL); + } else { + pprofile_add_relation(profile, sec_master, + host); + pprofile_update_relation(profile, sec_kdcs, + host, NULL); + } + } + + if (d->realms[r].kdcs[k].flags & K5_RKFLAG_MOD_ADMIN) { + if (d->realms[r].kdcs[k].admin) + pprofile_add_relation(profile, sec_admin, + host); + else + pprofile_update_relation(profile, sec_admin, + host, NULL); + } + } + + for (m=0; m < d->realms[r].n_domain_maps; m++) { + + UnicodeStrToAnsi(host, sizeof(host), + d->realms[r].domain_maps[m].name); + + if ((d->realms[r].domain_maps[m].flags & + K5_DMFLAG_DELETED) && + !(d->realms[r].domain_maps[m].flags & + K5_DMFLAG_NEW)) + pprofile_clear_relation(profile, sec_domain_map); + else if (!(d->realms[r].domain_maps[m].flags & + K5_DMFLAG_DELETED) && + (d->realms[r].domain_maps[m].flags & + K5_DMFLAG_NEW)) + pprofile_add_relation(profile, sec_domain_map, + realm); + } + } + } + + rv = pprofile_flush(profile); + + pprofile_release(profile); + } + + if (rv) { + khui_alert * alert; + wchar_t title[KHUI_MAXCCH_TITLE]; + wchar_t fmsg[KHUI_MAXCCH_MESSAGE]; + wchar_t msg[KHUI_MAXCCH_MESSAGE]; + wchar_t sugg[KHUI_MAXCCH_SUGGESTION]; + + LoadString(hResModule, IDS_K5ERR_CANTWRITEPROFILE, + title, ARRAYLENGTH(title)); + if (rv) + LoadString(hResModule, IDS_K5ERR_PROFNOWRITE, + fmsg, ARRAYLENGTH(fmsg)); + + LoadString(hResModule, IDS_K5ERR_PROFSUGGEST, + sugg, ARRAYLENGTH(sugg)); + + StringCbPrintf(msg, sizeof(msg), fmsg, config_file); + + khui_alert_create_empty(&alert); + khui_alert_set_severity(alert, (rv)?KHERR_ERROR:KHERR_WARNING); + khui_alert_set_title(alert, title); + khui_alert_set_message(alert, msg); + khui_alert_set_suggestion(alert, sugg); + + khui_alert_show(alert); + } + + d->flags = 0; +} + +/* actual dialog stuff */ + +#define IDX_NORMAL 1 +#define IDX_MODIFIED 2 +#define IDX_NEW 3 +#define IDX_DELETED 4 + +static k5_config_data k5_config_dlg_data; +static khm_boolean k5_dlg_data_valid = FALSE; INT_PTR CALLBACK k5_config_dlgproc(HWND hwnd, @@ -38,41 +892,42 @@ k5_config_dlgproc(HWND hwnd, case WM_INITDIALOG: { HWND hw; - wchar_t * realms; - wchar_t * defrealm; + khm_size i; + k5_config_data * d; + wchar_t * t; - char conffile[MAX_PATH]; - wchar_t wconffile[MAX_PATH]; wchar_t importopts[256]; WKSTA_INFO_100 * winfo100; - hw = GetDlgItem(hwnd, IDC_CFG_DEFREALM); #ifdef DEBUG - assert(hw); + assert(!k5_dlg_data_valid); #endif - realms = khm_krb5_get_realm_list(); - defrealm = khm_krb5_get_default_realm(); + + k5_init_config_data(&k5_config_dlg_data); + k5_read_config_data(&k5_config_dlg_data); + + k5_dlg_data_valid = TRUE; + + d = &k5_config_dlg_data; + + d->node_main = (khui_config_node) lParam; + + hw = GetDlgItem(hwnd, IDC_CFG_DEFREALM); #ifdef DEBUG - assert(realms); - assert(defrealm); + assert(hw); #endif SendMessage(hw, CB_RESETCONTENT, 0, 0); - for(t = realms; t && *t; t = multi_string_next(t)) { - SendMessage(hw, CB_ADDSTRING, 0, (LPARAM) t); + for (i=0; i < d->n_realms; i++) { + SendMessage(hw, CB_ADDSTRING, 0, + (LPARAM) d->realms[i].realm); } - SendMessage(hw, CB_SELECTSTRING, -1, (LPARAM) defrealm); - - free(defrealm); - free(realms); - - khm_get_profile_file(conffile, sizeof(conffile)); + SendMessage(hw, CB_SELECTSTRING, -1, + (LPARAM) d->def_realm); - AnsiStrToUnicode(wconffile, sizeof(wconffile), conffile); - - SetDlgItemText(hwnd, IDC_CFG_CFGFILE, wconffile); + SetDlgItemText(hwnd, IDC_CFG_CFGFILE, d->config_file); /* hostname/domain */ if (NetWkstaGetInfo(NULL, 100, (LPBYTE *) &winfo100) == NERR_Success) { @@ -99,175 +954,692 @@ k5_config_dlgproc(HWND hwnd, SendMessage(hw, CB_ADDSTRING, 0, (LPARAM) t); } - SendMessage(hw, CB_SETCURSEL, 0, 0); - + SendMessage(hw, CB_SETCURSEL, 0, d->lsa_import); + t = importopts; + SendMessage(hw, CB_GETLBTEXT, d->lsa_import,(LPARAM) t); + SendMessage(hw, CB_SELECTSTRING, -1, (LPARAM) t); } break; - case WM_DESTROY: + case WM_COMMAND: + { + k5_config_data * d; + + d = &k5_config_dlg_data; + + if (wParam == MAKEWPARAM(IDC_CFG_IMPORT, CBN_SELCHANGE)) { + int idx; + int modified = FALSE; + + idx = (int) SendDlgItemMessage(hwnd, IDC_CFG_IMPORT, + CB_GETCURSEL, 0, 0); + if (idx != CB_ERR && idx != d->lsa_import) { + d->lsa_import = idx; + d->flags |= K5_CDFLAG_MOD_LSA_IMPORT; + modified = TRUE; + } + + khui_cfg_set_flags(d->node_main, + (modified)?KHUI_CNFLAG_MODIFIED:0, + KHUI_CNFLAG_MODIFIED); + return TRUE; + } + } break; - } - return FALSE; -} -INT_PTR CALLBACK -k5_realms_dlgproc(HWND hwndDlg, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) { - switch(uMsg) { - case WM_INITDIALOG: + case KHUI_WM_CFG_NOTIFY: + { + k5_config_data * d; + + d = &k5_config_dlg_data; + + if (HIWORD(wParam) == WMCFG_APPLY) { + khm_int32 oflags; + + oflags = d->flags; + k5_write_config_data(d); + + if (d->flags != oflags) { + khui_cfg_set_flags(d->node_main, + KHUI_CNFLAG_APPLIED, + KHUI_CNFLAG_APPLIED | + KHUI_CNFLAG_MODIFIED); + } + return TRUE; + } + } break; case WM_DESTROY: + { + k5_free_config_data(&k5_config_dlg_data); + k5_dlg_data_valid = FALSE; + } break; } return FALSE; } -typedef struct tag_k5_ids_dlg_data { - khui_tracker tc_life; - khui_tracker tc_renew; - khui_tracker tc_life_min; - khui_tracker tc_life_max; - khui_tracker tc_renew_min; - khui_tracker tc_renew_max; - - time_t life; - time_t renew_life; - time_t life_min; - time_t life_max; - time_t renew_min; - time_t renew_max; -} k5_ids_dlg_data; +static HIMAGELIST +k5_get_state_image_list(void) { + HIMAGELIST hil; + HICON hicon; + + hil = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_COLOR | ILC_MASK, + 4, + 2); + + hicon = LoadImage(hResModule, + MAKEINTRESOURCE(IDI_NORMAL), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + LR_DEFAULTCOLOR); + + ImageList_AddIcon(hil, hicon); + + DestroyIcon(hicon); + + hicon = LoadImage(hResModule, + MAKEINTRESOURCE(IDI_MODIFIED), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + LR_DEFAULTCOLOR); + + ImageList_AddIcon(hil, hicon); + + DestroyIcon(hicon); + + hicon = LoadImage(hResModule, + MAKEINTRESOURCE(IDI_NEW), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + LR_DEFAULTCOLOR); + + ImageList_AddIcon(hil, hicon); + + DestroyIcon(hicon); + + hicon = LoadImage(hResModule, + MAKEINTRESOURCE(IDI_DELETED), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + LR_DEFAULTCOLOR); + + ImageList_AddIcon(hil, hicon); + + DestroyIcon(hicon); + + return hil; +} + +static void +k5_update_realms_display(HWND hw_list, k5_config_data * d) { + khm_size i; + LVITEM lvi; + wchar_t buf[64]; + + ListView_DeleteAllItems(hw_list); + + for (i=0; i < d->n_realms; i++) { + if ((d->realms[i].flags & K5_RDFLAG_DELETED) && + (d->realms[i].flags & K5_RDFLAG_NEW)) + continue; + + ZeroMemory(&lvi, sizeof(lvi)); + lvi.mask = LVIF_PARAM | LVIF_STATE | LVIF_TEXT; + lvi.iItem = 0; + lvi.iSubItem = 0; + lvi.pszText = d->realms[i].realm; + lvi.lParam = i; + + if (d->realms[i].flags & K5_RDFLAG_DELETED) { + lvi.state = INDEXTOSTATEIMAGEMASK(IDX_DELETED); + } else if (d->realms[i].flags & K5_RDFLAG_NEW) { + lvi.state = INDEXTOSTATEIMAGEMASK(IDX_NEW); + } else if (d->realms[i].flags & K5_RDFLAG_MODIFED) { + lvi.state = INDEXTOSTATEIMAGEMASK(IDX_MODIFIED); + } else { + lvi.state = INDEXTOSTATEIMAGEMASK(IDX_NORMAL); + } + lvi.stateMask = LVIS_STATEIMAGEMASK; + + ListView_InsertItem(hw_list, &lvi); + } + + ZeroMemory(&lvi, sizeof(lvi)); + lvi.mask = LVIF_PARAM | LVIF_STATE | LVIF_TEXT; + lvi.iItem = 0; + lvi.iSubItem = 0; + lvi.pszText = buf; + lvi.lParam = (LPARAM) -1; + + LoadString(hResModule, IDS_CFG_RE_NEWREALM, + buf, ARRAYLENGTH(buf)); + + lvi.state = INDEXTOSTATEIMAGEMASK(IDX_NEW); + lvi.stateMask = LVIS_STATEIMAGEMASK; + + ListView_InsertItem(hw_list, &lvi); + + if (d->flags & K5_CDFLAG_MOD_REALMS) { + khui_cfg_set_flags(d->node_realm, KHUI_CNFLAG_MODIFIED, + KHUI_CNFLAG_MODIFIED); + } else { + khui_cfg_set_flags(d->node_realm, 0, + KHUI_CNFLAG_MODIFIED); + } +} static void -k5_ids_read_params(k5_ids_dlg_data * d) { - khm_int32 t; - khm_int32 rv; +k5_update_kdcs_display(HWND hw_kdc, k5_config_data * d, khm_size idx_rlm) { + khm_size k; + LVITEM lvi; + int idx_item; + k5_realm_kdc * pkdc; + wchar_t wyes[8]; + wchar_t wno[8]; + wchar_t wbuf[64]; + + ListView_DeleteAllItems(hw_kdc); + + if (d == NULL) + return; #ifdef DEBUG - assert(csp_params); + assert(idx_rlm < d->n_realms); #endif + LoadString(hResModule, IDS_YES, wyes, ARRAYLENGTH(wyes)); + LoadString(hResModule, IDS_NO, wno, ARRAYLENGTH(wno)); + + for (k=0; k < d->realms[idx_rlm].n_kdcs; k++) { + if ((d->realms[idx_rlm].kdcs[k].flags & K5_RKFLAG_DELETED) && + (d->realms[idx_rlm].kdcs[k].flags & K5_RKFLAG_NEW)) + continue; + + pkdc = &(d->realms[idx_rlm].kdcs[k]); + + ZeroMemory(&lvi, sizeof(lvi)); + lvi.mask = LVIF_PARAM | LVIF_STATE | LVIF_TEXT; + lvi.iItem = K5_MAX_KDC; + lvi.iSubItem = 0; + lvi.lParam = k; + lvi.pszText = pkdc->name; + if (pkdc->flags & K5_RKFLAG_DELETED) { + lvi.state = INDEXTOSTATEIMAGEMASK(IDX_DELETED); + } else if (pkdc->flags & K5_RKFLAG_NEW) { + lvi.state = INDEXTOSTATEIMAGEMASK(IDX_NEW); + } else if ((pkdc->flags & K5_RKFLAG_MOD_ADMIN) || + (pkdc->flags & K5_RKFLAG_MOD_MASTER)) { + lvi.state = INDEXTOSTATEIMAGEMASK(IDX_MODIFIED); + } else { + lvi.state = INDEXTOSTATEIMAGEMASK(IDX_NORMAL); + } + lvi.stateMask = LVIS_STATEIMAGEMASK; + + idx_item = ListView_InsertItem(hw_kdc, &lvi); + + lvi.mask = LVIF_TEXT; + lvi.iItem = idx_item; + lvi.iSubItem = 1; + if (pkdc->admin) + lvi.pszText = wyes; + else + lvi.pszText = wno; + ListView_SetItem(hw_kdc, &lvi); + + lvi.iSubItem = 2; + if (pkdc->master) + lvi.pszText = wyes; + else + lvi.pszText = wno; + ListView_SetItem(hw_kdc, &lvi); + } + + ZeroMemory(&lvi, sizeof(lvi)); + lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE; + lvi.iItem = 0; + lvi.iSubItem = 0; + lvi.pszText = wbuf; + lvi.lParam = (LPARAM) -1; + lvi.state = INDEXTOSTATEIMAGEMASK(IDX_NEW); + lvi.stateMask = LVIS_STATEIMAGEMASK; - rv = khc_read_int32(csp_params, L"DefaultLifetime", &t); - assert(KHM_SUCCEEDED(rv)); - d->life = t; - - rv = khc_read_int32(csp_params, L"DefaultRenewLifetime", &t); - assert(KHM_SUCCEEDED(rv)); - d->renew_life = t; - - rv = khc_read_int32(csp_params, L"MaxLifetime", &t); - assert(KHM_SUCCEEDED(rv)); - d->life_max = t; - - rv = khc_read_int32(csp_params, L"MinLifetime", &t); - assert(KHM_SUCCEEDED(rv)); - d->life_min = t; - - rv = khc_read_int32(csp_params, L"MaxRenewLifetime", &t); - assert(KHM_SUCCEEDED(rv)); - d->renew_max = t; - - rv = khc_read_int32(csp_params, L"MinRenewLifetime", &t); - assert(KHM_SUCCEEDED(rv)); - d->renew_min = t; - - khui_tracker_initialize(&d->tc_life); - d->tc_life.current = d->life; - d->tc_life.min = 0; - d->tc_life.max = 3600 * 24 * 7; - - khui_tracker_initialize(&d->tc_renew); - d->tc_renew.current = d->renew_life; - d->tc_renew.min = 0; - d->tc_renew.max = 3600 * 24 * 30; - - khui_tracker_initialize(&d->tc_life_min); - d->tc_life_min.current = d->life_min; - d->tc_life_min.min = d->tc_life.min; - d->tc_life_min.max = d->tc_life.max; - - khui_tracker_initialize(&d->tc_life_max); - d->tc_life_max.current = d->life_max; - d->tc_life_max.min = d->tc_life.min; - d->tc_life_max.max = d->tc_life.max; - - khui_tracker_initialize(&d->tc_renew_min); - d->tc_renew_min.current = d->renew_min; - d->tc_renew_min.min = d->tc_renew.min; - d->tc_renew_min.max = d->tc_renew.max; - - khui_tracker_initialize(&d->tc_renew_max); - d->tc_renew_max.current = d->renew_max; - d->tc_renew_max.min = d->tc_renew.min; - d->tc_renew_max.max = d->tc_renew.max; + LoadString(hResModule, IDS_CFG_RE_NEWSERVER, + wbuf, ARRAYLENGTH(wbuf)); + + ListView_InsertItem(hw_kdc, &lvi); } -INT_PTR CALLBACK -k5_ids_tab_dlgproc(HWND hwnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) { - k5_ids_dlg_data * d; +static void +k5_update_dmap_display(HWND hw_dm, k5_config_data * d, khm_size idx_rlm) { + khm_size m; + LVITEM lvi; + k5_domain_map * map; + wchar_t wbuf[64]; + + ListView_DeleteAllItems(hw_dm); + + if (d == NULL) + return; - switch(uMsg) { - case WM_INITDIALOG: - d = malloc(sizeof(*d)); #ifdef DEBUG - assert(d); + assert(idx_rlm < d->n_realms); #endif - ZeroMemory(d, sizeof(*d)); -#pragma warning(push) -#pragma warning(disable: 4244) - SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d); -#pragma warning(pop) - k5_ids_read_params(d); - - khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_DEFLIFE), - &d->tc_life); - khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_DEFRLIFE), - &d->tc_renew); - khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_LRNG_MIN), - &d->tc_life_min); - khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_LRNG_MAX), - &d->tc_life_max); - khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_RLRNG_MIN), - &d->tc_renew_min); - khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_RLRNG_MAX), - &d->tc_renew_max); - khui_tracker_refresh(&d->tc_life); - khui_tracker_refresh(&d->tc_life_min); - khui_tracker_refresh(&d->tc_life_max); - khui_tracker_refresh(&d->tc_renew); - khui_tracker_refresh(&d->tc_renew_min); - khui_tracker_refresh(&d->tc_renew_max); - break; + for (m=0; m < d->realms[idx_rlm].n_domain_maps; m++) { + map = &(d->realms[idx_rlm].domain_maps[m]); - case WM_DESTROY: - d = (k5_ids_dlg_data *) (LONG_PTR) - GetWindowLongPtr(hwnd, DWLP_USER); - - khui_tracker_kill_controls(&d->tc_life); - khui_tracker_kill_controls(&d->tc_renew); - khui_tracker_kill_controls(&d->tc_life_min); - khui_tracker_kill_controls(&d->tc_life_max); - khui_tracker_kill_controls(&d->tc_renew_min); - khui_tracker_kill_controls(&d->tc_renew_max); - break; + if ((map->flags & K5_DMFLAG_NEW) && + (map->flags & K5_DMFLAG_DELETED)) + continue; + + ZeroMemory(&lvi, sizeof(lvi)); + + lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM; + lvi.pszText = map->name; + if (map->flags & K5_DMFLAG_DELETED) + lvi.state = INDEXTOSTATEIMAGEMASK(IDX_DELETED); + else if (map->flags & K5_DMFLAG_NEW) + lvi.state = INDEXTOSTATEIMAGEMASK(IDX_NEW); + else + lvi.state = INDEXTOSTATEIMAGEMASK(IDX_NORMAL); + lvi.stateMask = LVIS_STATEIMAGEMASK; + lvi.lParam = m; + + lvi.iItem = K5_MAX_DOMAIN_MAPPINGS; + lvi.iSubItem = 0; + + ListView_InsertItem(hw_dm, &lvi); } - return FALSE; + + ZeroMemory(&lvi, sizeof(lvi)); + lvi.mask = LVIF_PARAM | LVIF_TEXT | LVIF_STATE; + lvi.pszText = wbuf; + lvi.lParam = (LPARAM) -1; + lvi.state = INDEXTOSTATEIMAGEMASK(IDX_NEW); + lvi.stateMask = LVIS_STATEIMAGEMASK; + lvi.iItem = 0; + lvi.iSubItem = 0; + + LoadString(hResModule, IDS_CFG_RE_NEWDMAP, + wbuf, ARRAYLENGTH(wbuf)); + + ListView_InsertItem(hw_dm, &lvi); } INT_PTR CALLBACK -k5_id_tab_dlgproc(HWND hwndDlg, +k5_realms_dlgproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { + k5_config_data * d; + + d = &k5_config_dlg_data; + switch(uMsg) { case WM_INITDIALOG: + { + LVCOLUMN lvc; + HWND hw; + RECT r; + wchar_t buf[256]; + + assert(k5_dlg_data_valid); + + d->node_realm = (khui_config_node) lParam; + + /* set up columns for the Realms list */ + hw = GetDlgItem(hwnd, IDC_CFG_REALMS); +#ifdef DEBUG + assert(hw); +#endif + GetWindowRect(hw, &r); + r.right -= 5; /* shave a few pixels off the width */ + ZeroMemory(&lvc, sizeof(lvc)); + lvc.mask = LVCF_TEXT | LVCF_WIDTH; + lvc.pszText = buf; + lvc.cx = (r.right - r.left); + LoadString(hResModule, IDS_CFG_RE_REALMS, + buf, ARRAYLENGTH(buf)); + + ListView_InsertColumn(hw, 0, &lvc); + + ListView_SetImageList(hw, + k5_get_state_image_list(), + LVSIL_STATE); + + k5_update_realms_display(hw, d); + + /* set up columns for the servers list */ + hw = GetDlgItem(hwnd, IDC_CFG_KDC); +#ifdef DEBUG + assert(hw); +#endif + GetWindowRect(hw, &r); + r.right -= 5; + ZeroMemory(&lvc, sizeof(lvc)); + lvc.mask = LVCF_TEXT | LVCF_WIDTH; + lvc.pszText = buf; + lvc.cx = (r.right - r.left) * 2 / 4; + LoadString(hResModule, IDS_CFG_RE_HEAD_SVR, + buf, ARRAYLENGTH(buf)); + + ListView_InsertColumn(hw, 0, &lvc); + + lvc.cx = (r.right - r.left) * 1 / 4; + LoadString(hResModule, IDS_CFG_RE_HEAD_ADMIN, + buf, ARRAYLENGTH(buf)); + ListView_InsertColumn(hw, 1, &lvc); + + LoadString(hResModule, IDS_CFG_RE_HEAD_MASTER, + buf, ARRAYLENGTH(buf)); + ListView_InsertColumn(hw, 2, &lvc); + + ListView_SetImageList(hw, + k5_get_state_image_list(), + LVSIL_STATE); + + /* set up columns for the domain/host mapping list */ + hw = GetDlgItem(hwnd, IDC_CFG_DMAP); +#ifdef DEBUG + assert(hw); +#endif + GetWindowRect(hw, &r); + r.right -= 5; + ZeroMemory(&lvc, sizeof(lvc)); + lvc.mask = LVCF_TEXT | LVCF_WIDTH; + lvc.pszText = buf; + lvc.cx = (r.right - r.left); + LoadString(hResModule, IDS_CFG_RE_HEAD_DOMAIN, + buf, ARRAYLENGTH(buf)); + + ListView_InsertColumn(hw, 0, &lvc); + + + ListView_SetImageList(hw, + k5_get_state_image_list(), + LVSIL_STATE); + } + break; + + case WM_NOTIFY: + { + LPNMHDR pnmh; + HWND hw_rlm = NULL; + HWND hw_kdc = NULL; + HWND hw_dmp = NULL; + int i; + + pnmh = (LPNMHDR) lParam; + + if (pnmh->idFrom == IDC_CFG_REALMS) { + + hw_rlm = pnmh->hwndFrom; + + switch(pnmh->code) { + case LVN_ITEMCHANGED: + i = ListView_GetSelectedCount(hw_rlm); + hw_kdc = GetDlgItem(hwnd, IDC_CFG_KDC); + hw_dmp = GetDlgItem(hwnd, IDC_CFG_DMAP); + + d->c_realm = (khm_size) -1; + + if (i == 1) { + LVITEM lvi; + + i = ListView_GetNextItem(hw_rlm, -1, + LVNI_SELECTED); + if (i == -1) + goto _no_selection; + + ZeroMemory(&lvi, sizeof(lvi)); + + lvi.iItem = i; + lvi.iSubItem = 0; + lvi.mask = LVIF_PARAM; + + ListView_GetItem(hw_rlm, &lvi); + + if (lvi.lParam == -1) + goto _no_selection; + + d->c_realm = lvi.lParam; + + k5_update_kdcs_display(hw_kdc, d, lvi.lParam); + k5_update_dmap_display(hw_dmp, d, lvi.lParam); + return TRUE; + } + + _no_selection: + ListView_DeleteAllItems(hw_kdc); + ListView_DeleteAllItems(hw_dmp); + break; + + case LVN_BEGINLABELEDIT: + { + NMLVDISPINFO * pdisp; + LVITEM lvi; + + pdisp = (NMLVDISPINFO *) lParam; + + ZeroMemory(&lvi, sizeof(lvi)); + lvi.iItem = pdisp->item.iItem; + lvi.mask = LVIF_PARAM; + + ListView_GetItem(hw_rlm, &lvi); + + if (pdisp->item.iItem == -1 || + lvi.lParam != -1) { + SetWindowLongPtr(hwnd, DWL_MSGRESULT, TRUE); + } else { + /* allow editing */ + HWND hw_edit; + + hw_edit = ListView_GetEditControl(hw_rlm); + if (hw_edit != NULL) { + SendMessage(hw_edit, + EM_SETLIMITTEXT, + K5_MAXCCH_REALM - 1, + 0); + } + SetWindowLongPtr(hwnd, DWL_MSGRESULT, FALSE); + } + + return TRUE; + } + break; + + case LVN_ENDLABELEDIT: + { + NMLVDISPINFO * pdisp; + khm_size n; + + pdisp = (NMLVDISPINFO *) lParam; + + if (pdisp->item.pszText) { + n = d->n_realms; + k5_assert_n_realms(d, n+1); + StringCbCopy(d->realms[n].realm, + sizeof(d->realms[n].realm), + pdisp->item.pszText); + d->realms[n].flags = K5_RDFLAG_NEW; + d->n_realms++; + + d->flags |= K5_CDFLAG_MOD_REALMS; + + k5_update_realms_display(hw_rlm, d); + } + + return TRUE; + } + break; + + case LVN_KEYDOWN: + { + NMLVKEYDOWN * pnmk; + LVITEM lvi; + khm_size r; + int idx; + BOOL modified = FALSE; + + pnmk = (NMLVKEYDOWN *) lParam; + + if (pnmk->wVKey == VK_DELETE) { + idx = -1; + while((idx = ListView_GetNextItem(hw_rlm, idx, + LVNI_SELECTED)) + != -1) { + ZeroMemory(&lvi, sizeof(lvi)); + lvi.iItem = idx; + lvi.iSubItem = 0; + lvi.mask = LVIF_PARAM; + + ListView_GetItem(hw_rlm, &lvi); + + if (lvi.lParam != -1 && + (r = lvi.lParam) < d->n_realms) { + d->realms[r].flags ^= K5_RDFLAG_DELETED; + modified = TRUE; + } + } + + if (modified) { + d->flags |= K5_CDFLAG_MOD_REALMS; + + k5_purge_config_data(d, TRUE, TRUE, TRUE); + k5_update_realms_display(hw_rlm, d); + k5_update_dmap_display(GetDlgItem(hwnd, IDC_CFG_DMAP), NULL, 0); + k5_update_kdcs_display(GetDlgItem(hwnd, IDC_CFG_KDC), NULL, 0); + } + return TRUE; + } + } + break; + } + } else if (pnmh->idFrom == IDC_CFG_KDC) { + hw_kdc = pnmh->hwndFrom; + + switch (pnmh->code) { + case LVN_BEGINLABELEDIT: + { + NMLVDISPINFO * pdisp; + LVITEM lvi; + + pdisp = (NMLVDISPINFO *) lParam; + + ZeroMemory(&lvi, sizeof(lvi)); + lvi.iItem = pdisp->item.iItem; + lvi.mask = LVIF_PARAM; + + ListView_GetItem(hw_kdc, &lvi); + + if (pdisp->item.iItem == -1 || + lvi.lParam != -1) { + SetWindowLongPtr(hwnd, DWL_MSGRESULT, TRUE); + } else { + /* allow editing */ + HWND hw_edit; + + hw_edit = ListView_GetEditControl(hw_kdc); + if (hw_edit != NULL) { + SendMessage(hw_edit, + EM_SETLIMITTEXT, + K5_MAXCCH_HOST - 1, + 0); + } + SetWindowLongPtr(hwnd, DWL_MSGRESULT, FALSE); + } + return TRUE; + } + break; + + case LVN_ENDLABELEDIT: + { + NMLVDISPINFO * pdisp; + khm_size r; + khm_size k; + + r = d->c_realm; + + pdisp = (NMLVDISPINFO *) lParam; + + if (pdisp->item.pszText) { + k = d->realms[r].n_kdcs; + + if (k >= K5_MAX_KDC) { + SetWindowLongPtr(hwnd, DWL_MSGRESULT, FALSE); + /* TODO: show a message box saying + there are too many KDC's + already. */ + return TRUE; + } + + StringCbCopy(d->realms[r].kdcs[k].name, + sizeof(d->realms[0].kdcs[0].name), + pdisp->item.pszText); + d->realms[r].kdcs[k].flags = K5_RKFLAG_NEW; + d->realms[r].n_kdcs++; + + d->realms[r].flags |= K5_RDFLAG_MODIFED; + + k5_update_kdcs_display(hw_kdc, d, d->c_realm); + } + return TRUE; + } + break; + + case LVN_KEYDOWN: + { +#if 0 + NMLVKEYDOWN * pnmk; + LVITEM lvi; + khm_size r; + int idx; + BOOL modified = FALSE; + + pnmk = (NMLVKEYDOWN *) lParam; + + if (pnmk->wVKey == VK_DELETE) { + idx = -1; + while((idx = ListView_GetNextItem(hw_rlm, idx, + LVNI_SELECTED)) + != -1) { + ZeroMemory(&lvi, sizeof(lvi)); + lvi.iItem = idx; + lvi.iSubItem = 0; + lvi.mask = LVIF_PARAM; + + ListView_GetItem(hw_rlm, &lvi); + + if (lvi.lParam != -1 && + (r = lvi.lParam) < d->n_realms) { + d->realms[r].flags ^= K5_RDFLAG_DELETED; + modified = TRUE; + } + } + + if (modified) { + d->flags |= K5_CDFLAG_MOD_REALMS; + + k5_purge_config_data(d, TRUE, TRUE, TRUE); + k5_update_realms_display(hw_rlm, d); + k5_update_dmap_display(GetDlgItem(hwnd, IDC_CFG_DMAP), NULL, 0); + k5_update_kdcs_display(GetDlgItem(hwnd, IDC_CFG_KDC), NULL, 0); + } + return TRUE; + } +#endif + } + break; + } + } + } break; case WM_DESTROY: @@ -276,7 +1648,6 @@ k5_id_tab_dlgproc(HWND hwndDlg, return FALSE; } - void k5_register_config_panels(void) { khui_config_node node; @@ -308,6 +1679,7 @@ k5_register_config_panels(void) { #endif } +#ifdef REALM_EDITOR ZeroMemory(®, sizeof(reg)); LoadString(hResModule, IDS_K5RLM_SHORT_DESC, @@ -324,6 +1696,24 @@ k5_register_config_panels(void) { reg.flags = 0; khui_cfg_register(node, ®); +#endif + + ZeroMemory(®, sizeof(reg)); + + LoadString(hResModule, IDS_K5CCC_SHORT_DESC, + wshort, ARRAYLENGTH(wshort)); + LoadString(hResModule, IDS_K5CCC_LONG_DESC, + wlong, ARRAYLENGTH(wlong)); + + reg.name = L"KerberosCCaches"; + reg.short_desc = wshort; + reg.long_desc = wlong; + reg.h_module = hResModule; + reg.dlg_template = MAKEINTRESOURCE(IDD_CFG_CACHES); + reg.dlg_proc = k5_ccconfig_dlgproc; + reg.flags = 0; + + khui_cfg_register(node, ®); khui_cfg_release(node); @@ -374,9 +1764,12 @@ k5_register_config_panels(void) { void k5_unregister_config_panels(void) { khui_config_node node_main; +#ifdef REALM_EDITOR khui_config_node node_realms; +#endif khui_config_node node_ids; khui_config_node node_tab; + khui_config_node node_ccaches; if (KHM_FAILED(khui_cfg_open(NULL, L"Kerberos5", &node_main))) { node_main = NULL; @@ -385,6 +1778,7 @@ k5_unregister_config_panels(void) { #endif } +#ifdef REALM_EDITOR if (KHM_SUCCEEDED(khui_cfg_open(node_main, L"KerberosRealms", &node_realms))) { khui_cfg_remove(node_realms); @@ -394,6 +1788,17 @@ k5_unregister_config_panels(void) { else assert(FALSE); #endif +#endif + + if (KHM_SUCCEEDED(khui_cfg_open(node_main, L"KerberosCCaches", + &node_ccaches))) { + khui_cfg_remove(node_ccaches); + khui_cfg_release(node_ccaches); + } +#ifdef DEBUG + else + assert(FALSE); +#endif if (node_main) { khui_cfg_remove(node_main); diff --git a/src/windows/identity/plugins/krb5/krb5configid.c b/src/windows/identity/plugins/krb5/krb5configid.c new file mode 100644 index 000000000..17ab40929 --- /dev/null +++ b/src/windows/identity/plugins/krb5/krb5configid.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2005 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* $Id$ */ + +#include +#include +#include +#include +#include + +#pragma warning(push) +#pragma warning(disable: 4995) +#include +#pragma warning(pop) + +typedef struct tag_k5_id_dlg_data { + khui_config_init_data cfg; + + khm_handle ident; + + khui_tracker tc_life; + khui_tracker tc_renew; + + wchar_t ccache[KRB5_MAXCCH_CCNAME]; + + time_t life; + time_t renew_life; +} k5_id_dlg_data; + +static void +k5_id_read_params(k5_id_dlg_data * d) { + + wchar_t idname[KCDB_IDENT_MAXCCH_NAME]; + khm_size cb; + khm_int32 rv; + khm_int32 t; + khm_handle csp_ident; + khm_handle csp_idroot = NULL; + + cb = sizeof(idname); + khui_cfg_get_name(d->cfg.ctx_node, idname, &cb); + + rv = kcdb_identity_create(idname, 0, &d->ident); +#ifdef DEBUG + assert(KHM_SUCCEEDED(rv)); +#endif + + rv = kcdb_identity_get_config(d->ident, 0, &csp_idroot); + if (KHM_SUCCEEDED(rv) && + KHM_SUCCEEDED(khc_open_space(csp_idroot, CSNAME_KRB5CRED, 0, + &csp_ident))) { + khc_shadow_space(csp_ident, csp_params); + } else { + csp_ident = csp_params; + } + + if (csp_idroot) + khc_close_space(csp_idroot); + + rv = khc_read_int32(csp_ident, L"DefaultLifetime", &t); + if (KHM_SUCCEEDED(rv)) + d->life = t; + else + d->life = 36000; + + rv = khc_read_int32(csp_ident, L"DefaultRenewLifetime", &t); + if (KHM_SUCCEEDED(rv)) + d->renew_life = t; + else + d->renew_life = 604800; + + cb = sizeof(d->ccache); + rv = khc_read_string(csp_ident, L"DefaultCCName", d->ccache, &cb); + if (KHM_FAILED(rv)) + ZeroMemory(d->ccache, sizeof(d->ccache)); + + khui_tracker_initialize(&d->tc_life); + d->tc_life.current = d->life; + d->tc_life.min = 0; + d->tc_life.max = 3600 * 24 * 7; + + khui_tracker_initialize(&d->tc_renew); + d->tc_renew.current = d->renew_life; + d->tc_renew.min = 0; + d->tc_renew.max = 3600 * 24 * 30; + + if (csp_ident != csp_params) + khc_close_space(csp_ident); +} + +static khm_boolean +k5_id_is_mod(HWND hw, k5_id_dlg_data * d) { + wchar_t ccache[KRB5_MAXCCH_CCNAME]; + + GetDlgItemText(hw, IDC_CFG_CCACHE, ccache, ARRAYLENGTH(ccache)); + + if (wcsicmp(ccache, d->ccache) || + d->tc_renew.current != d->renew_life || + d->tc_life.current != d->life) + return TRUE; + return FALSE; +} + +static void +k5_id_check_mod(HWND hw, k5_id_dlg_data * d) { + BOOL modified = k5_id_is_mod(hw, d); + + khui_cfg_set_flags_inst(&d->cfg, + (modified)?KHUI_CNFLAG_MODIFIED:0, + KHUI_CNFLAG_MODIFIED); +} + +static void +k5_id_write_params(HWND hw, k5_id_dlg_data * d) { + + khm_handle csp_idroot = NULL; + khm_handle csp_ident = NULL; + wchar_t ccache[KRB5_MAXCCH_CCNAME]; + khm_size cb; + khm_int32 rv; + + if (!k5_id_is_mod(hw, d)) + return; + + rv = kcdb_identity_get_config(d->ident, KHM_FLAG_CREATE, &csp_idroot); + if (KHM_SUCCEEDED(rv)) { + khc_open_space(csp_idroot, CSNAME_KRB5CRED, + KHM_FLAG_CREATE, + &csp_ident); + } + + if (csp_idroot) + khc_close_space(csp_idroot); + + if (!csp_ident) + return; + + if (d->life != d->tc_life.current) { + d->life = d->tc_life.current; + khc_write_int32(csp_ident, L"DefaultLifetime", (khm_int32) d->life); + } + + if (d->renew_life != d->tc_renew.current) { + d->renew_life = d->tc_renew.current; + khc_write_int32(csp_ident, L"DefaultRenewLifetime", (khm_int32) d->renew_life); + } + + GetDlgItemText(hw, IDC_CFG_CCACHE, ccache, ARRAYLENGTH(ccache)); + + if (SUCCEEDED(StringCbLength(ccache, sizeof(ccache), &cb)) && + wcsicmp(ccache, d->ccache)) { + khc_write_string(csp_ident, L"DefaultCCName", ccache); + StringCbCopy(d->ccache, sizeof(d->ccache), ccache); + } else { + khc_remove_value(csp_ident, L"DefaultCCName", KCONF_FLAG_USER); + } + + if (csp_ident) + khc_close_space(csp_ident); + + khui_cfg_set_flags_inst(&d->cfg, + KHUI_CNFLAG_APPLIED, + KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED); +} + +INT_PTR CALLBACK +k5_id_tab_dlgproc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { + + k5_id_dlg_data * d; + + switch(uMsg) { + case WM_INITDIALOG: + d = PMALLOC(sizeof(*d)); +#ifdef DEBUG + assert(d); +#endif + ZeroMemory(d, sizeof(*d)); + + d->cfg = *((khui_config_init_data *) lParam); + +#pragma warning(push) +#pragma warning(disable: 4244) + SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d); +#pragma warning(pop) + + k5_id_read_params(d); + + khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_DEFLIFE), + &d->tc_life); + khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_DEFRLIFE), + &d->tc_renew); + khui_tracker_refresh(&d->tc_life); + khui_tracker_refresh(&d->tc_renew); + + SetDlgItemText(hwnd, IDC_CFG_CCACHE, d->ccache); + break; + + case WM_COMMAND: + d = (k5_id_dlg_data *) (LONG_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + + if (HIWORD(wParam) == EN_CHANGE) + k5_id_check_mod(hwnd, d); + break; + + case KHUI_WM_CFG_NOTIFY: + d = (k5_id_dlg_data *) (LONG_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + + if (HIWORD(wParam) == WMCFG_APPLY) { + k5_id_write_params(hwnd, d); + } + break; + + case WM_DESTROY: + d = (k5_id_dlg_data *) (LONG_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + + khui_tracker_kill_controls(&d->tc_life); + khui_tracker_kill_controls(&d->tc_renew); + + if (d->ident) + kcdb_identity_release(d->ident); + + PFREE(d); + break; + } + return FALSE; +} diff --git a/src/windows/identity/plugins/krb5/krb5configids.c b/src/windows/identity/plugins/krb5/krb5configids.c new file mode 100644 index 000000000..4eebb9c62 --- /dev/null +++ b/src/windows/identity/plugins/krb5/krb5configids.c @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2005 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* $Id$ */ + +#include +#include +#include +#include +#include + +#pragma warning(push) +#pragma warning(disable: 4995) +#include +#pragma warning(pop) + +typedef struct tag_k5_ids_dlg_data { + khui_config_init_data cfg; + + khui_tracker tc_life; + khui_tracker tc_renew; + khui_tracker tc_life_min; + khui_tracker tc_life_max; + khui_tracker tc_renew_min; + khui_tracker tc_renew_max; + + time_t life; + time_t renew_life; + time_t life_min; + time_t life_max; + time_t renew_min; + time_t renew_max; +} k5_ids_dlg_data; + +static khm_boolean +k5_ids_is_mod(k5_ids_dlg_data * d) { + if (d->life != d->tc_life.current || + d->renew_life != d->tc_renew.current || + d->life_max != d->tc_life_max.current || + d->life_min != d->tc_life_min.current || + d->renew_max != d->tc_renew_max.current || + d->renew_min != d->tc_renew_min.current) + return TRUE; + return FALSE; +} + +static void +k5_ids_check_mod(k5_ids_dlg_data * d) { + BOOL modified = k5_ids_is_mod(d); + + khui_cfg_set_flags_inst(&d->cfg, + (modified)?KHUI_CNFLAG_MODIFIED:0, + KHUI_CNFLAG_MODIFIED); +} + +static void +k5_ids_write_params(k5_ids_dlg_data * d) { + + khm_int32 rv; + +#ifdef DEBUG + assert(csp_params); +#endif + + if (!k5_ids_is_mod(d)) + return; + +#define WRITEPARAM(po,pn,vn) \ + if (po != pn) { \ + po = pn; \ + rv = khc_write_int32(csp_params, vn, (khm_int32) po); \ + assert(KHM_SUCCEEDED(rv)); \ + } + + WRITEPARAM(d->life,d->tc_life.current, L"DefaultLifetime"); + WRITEPARAM(d->renew_life,d->tc_renew.current, L"DefaultRenewLifetime"); + WRITEPARAM(d->life_max,d->tc_life_max.current, L"MaxLifetime"); + WRITEPARAM(d->life_min,d->tc_life_min.current, L"MinLifetime"); + WRITEPARAM(d->renew_max,d->tc_renew_max.current, L"MaxRenewLifetime"); + WRITEPARAM(d->renew_min,d->tc_renew_min.current, L"MinRenewLifetime"); + +#undef WRITEPARAM + + khui_cfg_set_flags_inst(&d->cfg, + KHUI_CNFLAG_APPLIED, + KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED); +} + +static void +k5_ids_read_params(k5_ids_dlg_data * d) { + khm_int32 t; + khm_int32 rv; + +#ifdef DEBUG + assert(csp_params); +#endif + + rv = khc_read_int32(csp_params, L"DefaultLifetime", &t); + assert(KHM_SUCCEEDED(rv)); + d->life = t; + + rv = khc_read_int32(csp_params, L"DefaultRenewLifetime", &t); + assert(KHM_SUCCEEDED(rv)); + d->renew_life = t; + + rv = khc_read_int32(csp_params, L"MaxLifetime", &t); + assert(KHM_SUCCEEDED(rv)); + d->life_max = t; + + rv = khc_read_int32(csp_params, L"MinLifetime", &t); + assert(KHM_SUCCEEDED(rv)); + d->life_min = t; + + rv = khc_read_int32(csp_params, L"MaxRenewLifetime", &t); + assert(KHM_SUCCEEDED(rv)); + d->renew_max = t; + + rv = khc_read_int32(csp_params, L"MinRenewLifetime", &t); + assert(KHM_SUCCEEDED(rv)); + d->renew_min = t; + + khui_tracker_initialize(&d->tc_life); + d->tc_life.current = d->life; + d->tc_life.min = 0; + d->tc_life.max = 3600 * 24 * 7; + + khui_tracker_initialize(&d->tc_renew); + d->tc_renew.current = d->renew_life; + d->tc_renew.min = 0; + d->tc_renew.max = 3600 * 24 * 30; + + khui_tracker_initialize(&d->tc_life_min); + d->tc_life_min.current = d->life_min; + d->tc_life_min.min = d->tc_life.min; + d->tc_life_min.max = d->tc_life.max; + + khui_tracker_initialize(&d->tc_life_max); + d->tc_life_max.current = d->life_max; + d->tc_life_max.min = d->tc_life.min; + d->tc_life_max.max = d->tc_life.max; + + khui_tracker_initialize(&d->tc_renew_min); + d->tc_renew_min.current = d->renew_min; + d->tc_renew_min.min = d->tc_renew.min; + d->tc_renew_min.max = d->tc_renew.max; + + khui_tracker_initialize(&d->tc_renew_max); + d->tc_renew_max.current = d->renew_max; + d->tc_renew_max.min = d->tc_renew.min; + d->tc_renew_max.max = d->tc_renew.max; +} + +INT_PTR CALLBACK +k5_ids_tab_dlgproc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { + k5_ids_dlg_data * d; + + switch(uMsg) { + case WM_INITDIALOG: + d = PMALLOC(sizeof(*d)); +#ifdef DEBUG + assert(d); +#endif + ZeroMemory(d, sizeof(*d)); +#pragma warning(push) +#pragma warning(disable: 4244) + SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) d); +#pragma warning(pop) + + d->cfg = *((khui_config_init_data *) lParam); + + k5_ids_read_params(d); + + khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_DEFLIFE), + &d->tc_life); + khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_DEFRLIFE), + &d->tc_renew); + khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_LRNG_MIN), + &d->tc_life_min); + khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_LRNG_MAX), + &d->tc_life_max); + khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_RLRNG_MIN), + &d->tc_renew_min); + khui_tracker_install(GetDlgItem(hwnd, IDC_CFG_RLRNG_MAX), + &d->tc_renew_max); + khui_tracker_refresh(&d->tc_life); + khui_tracker_refresh(&d->tc_life_min); + khui_tracker_refresh(&d->tc_life_max); + khui_tracker_refresh(&d->tc_renew); + khui_tracker_refresh(&d->tc_renew_min); + khui_tracker_refresh(&d->tc_renew_max); + break; + + case WM_COMMAND: + d = (k5_ids_dlg_data *) (LONG_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + + if (HIWORD(wParam) == EN_CHANGE) { + k5_ids_check_mod(d); + } + break; + + case KHUI_WM_CFG_NOTIFY: + d = (k5_ids_dlg_data *) (LONG_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + if (HIWORD(wParam) == WMCFG_APPLY) { + k5_ids_write_params(d); + } + break; + + case WM_DESTROY: + d = (k5_ids_dlg_data *) (LONG_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + + khui_tracker_kill_controls(&d->tc_life); + khui_tracker_kill_controls(&d->tc_renew); + khui_tracker_kill_controls(&d->tc_life_min); + khui_tracker_kill_controls(&d->tc_life_max); + khui_tracker_kill_controls(&d->tc_renew_min); + khui_tracker_kill_controls(&d->tc_renew_max); + + PFREE(d); + break; + } + return FALSE; +} + diff --git a/src/windows/identity/plugins/krb5/krb5funcs.c b/src/windows/identity/plugins/krb5/krb5funcs.c index d3c97fff2..d1a897d63 100644 --- a/src/windows/identity/plugins/krb5/krb5funcs.c +++ b/src/windows/identity/plugins/krb5/krb5funcs.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2004 Massachusetts Institute of Technology +* Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -59,7 +59,7 @@ khm_convert524(krb5_context alt_ctx) !pkrb524_convert_creds_kdc) return 0; - v4creds = (CREDENTIALS *) malloc(sizeof(CREDENTIALS)); + v4creds = (CREDENTIALS *) PMALLOC(sizeof(CREDENTIALS)); memset((char *) v4creds, 0, sizeof(CREDENTIALS)); memset((char *) &increds, 0, sizeof(increds)); @@ -140,7 +140,7 @@ khm_convert524(krb5_context alt_ctx) cleanup: memset(v4creds, 0, sizeof(v4creds)); - free(v4creds); + PFREE(v4creds); if (v5creds) { pkrb5_free_creds(ctx, v5creds); @@ -237,10 +237,10 @@ static long get_tickets_from_cache(krb5_context ctx, cc_name = (*pkrb5_cc_get_name)(ctx, cache); if(cc_name) { namelen = strlen(cc_name); - namelen = (namelen + 1 + 4) * sizeof(wchar_t); - /* the +4 is for the possible addtion of API: during the - cannonicalization process */ - wcc_name = malloc(namelen); + namelen = (namelen + 1 + 5) * sizeof(wchar_t); + /* the +5 is for the possible addtion of API: or FILE: + during the cannonicalization process */ + wcc_name = PMALLOC(namelen); AnsiStrToUnicode(wcc_name, namelen, cc_name); khm_krb5_canon_cc_name(wcc_name, namelen); } @@ -311,6 +311,7 @@ static long get_tickets_from_cache(krb5_context ctx, &KRBv5Credentials))) { khm_handle tident = NULL; + khm_int32 cred_flags = 0; if(ClientName != NULL) (*pkrb5_free_unparsed_name)(ctx, ClientName); @@ -371,7 +372,7 @@ static long get_tickets_from_cache(krb5_context ctx, eft -= ft; kcdb_cred_set_attr(cred, KCDB_ATTR_LIFETIME, &eft, sizeof(eft)); - if (KRBv5Credentials.times.renew_till >= 0) { + if (KRBv5Credentials.times.renew_till > 0) { tt = KRBv5Credentials.times.renew_till; TimetToFileTime(tt, (LPFILETIME) &eft); kcdb_cred_set_attr(cred, KCDB_ATTR_RENEW_EXPIRE, &eft, @@ -387,18 +388,29 @@ static long get_tickets_from_cache(krb5_context ctx, /* special flags understood by NetIDMgr */ { - khm_int32 oflags, nflags; - - kcdb_cred_get_flags(cred, &oflags); - nflags = oflags; + khm_int32 nflags = 0; if (ti & TKT_FLG_RENEWABLE) nflags |= KCDB_CRED_FLAG_RENEWABLE; if (ti & TKT_FLG_INITIAL) nflags |= KCDB_CRED_FLAG_INITIAL; + else { + krb5_data * c0, *c1, *r; + + /* these are macros that do not allocate any memory */ + c0 = krb5_princ_component(ctx,KRBv5Credentials.server,0); + c1 = krb5_princ_component(ctx,KRBv5Credentials.server,1); + r = krb5_princ_realm(ctx,KRBv5Credentials.server); + + if ( c0 && c1 && r && c1->length == r->length && + !strncmp(c1->data,r->data,r->length) && + !strncmp("krbtgt",c0->data,c0->length) ) + nflags |= KCDB_CRED_FLAG_INITIAL; + } + + kcdb_cred_set_flags(cred, nflags, KCDB_CRED_FLAGMASK_EXT); - if (oflags != nflags) - kcdb_cred_set_flags(cred, nflags, KCDB_CRED_FLAGMASK_ALL); + cred_flags = nflags; } if ( !pkrb5_decode_ticket(&KRBv5Credentials.ticket, &tkt)) { @@ -410,8 +422,8 @@ static long get_tickets_from_cache(krb5_context ctx, ti = KRBv5Credentials.keyblock.enctype; kcdb_cred_set_attr(cred, attr_id_key_enctype, &ti, sizeof(ti)); - - kcdb_cred_set_attr(cred, KCDB_ATTR_LOCATION, wcc_name, KCDB_CBSIZE_AUTO); + kcdb_cred_set_attr(cred, KCDB_ATTR_LOCATION, wcc_name, + KCDB_CBSIZE_AUTO); /*TODO: going here */ #if 0 @@ -438,7 +450,8 @@ static long get_tickets_from_cache(krb5_context ctx, } #endif - if(KRBv5Credentials.ticket_flags & TKT_FLG_INITIAL) { + if(cred_flags & KCDB_CRED_FLAG_INITIAL) { + __int64 t_issue_new; __int64 t_expire_old; __int64 t_expire_new; khm_size cb; @@ -451,6 +464,9 @@ static long get_tickets_from_cache(krb5_context ctx, tt = KRBv5Credentials.times.endtime; TimetToFileTime(tt, (LPFILETIME) &t_expire_new); + tt = KRBv5Credentials.times.starttime; + TimetToFileTime(tt, (LPFILETIME) &t_issue_new); + cb = sizeof(t_expire_old); if(KHM_FAILED(kcdb_identity_get_attr(tident, KCDB_ATTR_EXPIRE, @@ -463,8 +479,11 @@ static long get_tickets_from_cache(krb5_context ctx, kcdb_identity_set_attr(tident, KCDB_ATTR_EXPIRE, &t_expire_new, sizeof(t_expire_new)); + kcdb_identity_set_attr(tident, KCDB_ATTR_ISSUE, + &t_issue_new, + sizeof(t_issue_new)); - if (KRBv5Credentials.times.renew_till >= 0) { + if (KRBv5Credentials.times.renew_till > 0) { tt = KRBv5Credentials.times.renew_till; TimetToFileTime(tt, (LPFILETIME) &ft); kcdb_identity_set_attr(tident, @@ -525,7 +544,7 @@ static long get_tickets_from_cache(krb5_context ctx, _exit: if(wcc_name) - free(wcc_name); + PFREE(wcc_name); return code; } @@ -534,11 +553,14 @@ long khm_krb5_list_tickets(krb5_context *krbv5Context) { krb5_context ctx; - krb5_ccache cache; + krb5_ccache cache = 0; krb5_error_code code; - apiCB * cc_ctx = 0; - struct _infoNC ** pNCi = NULL; - int i; + apiCB * cc_ctx = 0; + struct _infoNC ** pNCi = NULL; + int i; + khm_int32 t; + wchar_t * ms = NULL; + khm_size cb; ctx = NULL; cache = NULL; @@ -576,6 +598,49 @@ khm_krb5_list_tickets(krb5_context *krbv5Context) cache = 0; } + if (KHM_SUCCEEDED(khc_read_int32(csp_params, L"MsLsaList", &t)) && t) { + code = (*pkrb5_cc_resolve)(ctx, "MSLSA:", &cache); + + if (code == 0 && cache) { + code = get_tickets_from_cache(ctx, cache); + } + + if (ctx != NULL && cache != NULL) + (*pkrb5_cc_close)(ctx, cache); + cache = 0; + } + + if (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; + + code = get_tickets_from_cache(ctx, cache); + + if (ctx != NULL && cache != NULL) + (*pkrb5_cc_close)(ctx, cache); + cache = 0; + } + + PFREE(ms); + } + _exit: if (pNCi) (*pcc_free_NC_info)(cc_ctx, &pNCi); @@ -585,7 +650,6 @@ _exit: kcdb_credset_collect(NULL, krb5_credset, NULL, credtype_id_krb5, NULL); return(code); - } int @@ -615,10 +679,10 @@ khm_krb5_renew(khm_handle identity) realm = krb5_princ_realm(ctx, me); code = pkrb5_build_principal_ext(ctx, &server, - realm->length,realm->data, - KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, - realm->length,realm->data, - 0); + realm->length,realm->data, + KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, + realm->length,realm->data, + 0); if (code) goto cleanup; @@ -744,7 +808,7 @@ khm_krb5_kinit(krb5_context alt_ctx, while ( local_addrs[i++] ); addr_count = i + 1; - addrs = (krb5_address **) malloc((addr_count+1) * sizeof(krb5_address *)); + addrs = (krb5_address **) PMALLOC((addr_count+1) * sizeof(krb5_address *)); if ( !addrs ) { pkrb5_free_addresses(ctx, local_addrs); assert(0); @@ -752,7 +816,7 @@ khm_krb5_kinit(krb5_context alt_ctx, memset(addrs, 0, sizeof(krb5_address *) * (addr_count+1)); i = 0; while ( local_addrs[i] ) { - addrs[i] = (krb5_address *)malloc(sizeof(krb5_address)); + addrs[i] = (krb5_address *)PMALLOC(sizeof(krb5_address)); if (addrs[i] == NULL) { pkrb5_free_addresses(ctx, local_addrs); assert(0); @@ -761,7 +825,7 @@ khm_krb5_kinit(krb5_context alt_ctx, addrs[i]->magic = local_addrs[i]->magic; addrs[i]->addrtype = local_addrs[i]->addrtype; addrs[i]->length = local_addrs[i]->length; - addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length); + addrs[i]->contents = (unsigned char *)PMALLOC(addrs[i]->length); if (!addrs[i]->contents) { pkrb5_free_addresses(ctx, local_addrs); assert(0); @@ -773,14 +837,14 @@ khm_krb5_kinit(krb5_context alt_ctx, } pkrb5_free_addresses(ctx, local_addrs); - addrs[i] = (krb5_address *)malloc(sizeof(krb5_address)); + addrs[i] = (krb5_address *)PMALLOC(sizeof(krb5_address)); if (addrs[i] == NULL) assert(0); addrs[i]->magic = KV5M_ADDRESS; addrs[i]->addrtype = AF_INET; addrs[i]->length = 4; - addrs[i]->contents = (unsigned char *)malloc(addrs[i]->length); + addrs[i]->contents = (unsigned char *)PMALLOC(addrs[i]->length); if (!addrs[i]->contents) assert(0); @@ -814,8 +878,8 @@ cleanup: for ( i=0;icontents ) - free(addrs[i]->contents); - free(addrs[i]); + PFREE(addrs[i]->contents); + PFREE(addrs[i]); } } } @@ -921,8 +985,19 @@ khm_krb5_canon_cc_name(wchar_t * wcc_name, colon = wcschr(wcc_name, L':'); - if (colon) + if (colon) { + /* if the colon is just 1 character away from the beginning, + it's a FILE: cc */ + if (colon - wcc_name == 1) { + if (cb_len + 5 * sizeof(wchar_t) > cb_cc_name) + return KHM_ERROR_TOO_LONG; + + memmove(&wcc_name[5], &wcc_name[0], cb_len); + memmove(&wcc_name[0], L"FILE:", sizeof(wchar_t) * 5); + } + return 0; + } if (cb_len + 4 * sizeof(wchar_t) > cb_cc_name) return KHM_ERROR_TOO_LONG; @@ -1495,18 +1570,29 @@ cleanup: #define KRB_FILE "KRB.CON" #define KRBREALM_FILE "KRBREALM.CON" #define KRB5_FILE "KRB5.INI" +#define KRB5_TMP_FILE "KRB5.INI.TMP" + +BOOL +khm_krb5_get_temp_profile_file(LPSTR confname, UINT szConfname) +{ + GetTempPathA(szConfname, confname); + confname[szConfname-1] = '\0'; + StringCchCatA(confname, szConfname, KRB5_TMP_FILE); + confname[szConfname-1] = '\0'; + return FALSE; +} BOOL -khm_get_profile_file(LPSTR confname, UINT szConfname) +khm_krb5_get_profile_file(LPSTR confname, UINT szConfname) { char **configFile = NULL; if (pkrb5_get_default_config_files(&configFile)) { GetWindowsDirectoryA(confname,szConfname); confname[szConfname-1] = '\0'; - strncat(confname, "\\",sizeof(confname)-strlen(confname)); + strncat(confname, "\\",sizeof(confname)-strlen(confname)); confname[szConfname-1] = '\0'; - strncat(confname, KRB5_FILE,sizeof(confname)-strlen(confname)); + strncat(confname, KRB5_FILE,sizeof(confname)-strlen(confname)); confname[szConfname-1] = '\0'; return FALSE; } @@ -1523,9 +1609,9 @@ khm_get_profile_file(LPSTR confname, UINT szConfname) { GetWindowsDirectoryA(confname,szConfname); confname[szConfname-1] = '\0'; - strncat(confname, "\\",sizeof(confname)-strlen(confname)); + strncat(confname, "\\",sizeof(confname)-strlen(confname)); confname[szConfname-1] = '\0'; - strncat(confname, KRB5_FILE,sizeof(confname)-strlen(confname)); + strncat(confname, KRB5_FILE,sizeof(confname)-strlen(confname)); confname[szConfname-1] = '\0'; } @@ -1540,7 +1626,7 @@ khm_get_krb4_con_file(LPSTR confname, UINT szConfname) LPSTR pFind; //strcpy(krbConFile, CLeashApp::m_krbv5_profile->first_file->filename); - if (khm_get_profile_file(krbConFile, sizeof(krbConFile))) { + if (khm_krb5_get_profile_file(krbConFile, sizeof(krbConFile))) { GetWindowsDirectoryA(krbConFile,sizeof(krbConFile)); krbConFile[MAX_PATH-1] = '\0'; strncat(krbConFile, "\\",sizeof(krbConFile)-strlen(krbConFile)); @@ -1634,7 +1720,7 @@ wchar_t * khm_krb5_get_realm_list(void) char krb5_conf[MAX_PATH+1]; - if (!khm_get_profile_file(krb5_conf,sizeof(krb5_conf))) { + if (!khm_krb5_get_profile_file(krb5_conf,sizeof(krb5_conf))) { profile_t profile; long retval; const char *filenames[2]; @@ -1659,7 +1745,7 @@ wchar_t * khm_krb5_get_realm_list(void) } cbsize += sizeof(wchar_t); /* double null terminated */ - rlist = malloc(cbsize); + rlist = PMALLOC(cbsize); d = rlist; for (cpp = sections; *cpp; cpp++) { @@ -1697,7 +1783,7 @@ wchar_t * khm_krb5_get_realm_list(void) /*TODO: compute the actual required buffer size instead of hardcoding */ cbsize = 16384; // arbitrary - rlist = malloc(cbsize); + rlist = PMALLOC(cbsize); d = rlist; // Skip the default realm @@ -1760,7 +1846,7 @@ wchar_t * khm_krb5_get_default_realm(void) if (def) { cch = strlen(def) + 1; - realm = malloc(sizeof(wchar_t) * cch); + realm = PMALLOC(sizeof(wchar_t) * cch); AnsiStrToUnicode(realm, sizeof(wchar_t) * cch, def); pkrb5_free_default_realm(ctx, def); } else @@ -1771,6 +1857,32 @@ wchar_t * khm_krb5_get_default_realm(void) return realm; } +long +khm_krb5_set_default_realm(wchar_t * realm) { + krb5_context ctx=0; + char * def = 0; + long rv = 0; + char astr[K5_MAXCCH_REALM]; + + UnicodeStrToAnsi(astr, sizeof(astr), realm); + + pkrb5_init_context(&ctx); + pkrb5_get_default_realm(ctx,&def); + + if ((def && strcmp(def, astr)) || + !def) { + rv = pkrb5_set_default_realm(ctx, astr); + } + + if (def) { + pkrb5_free_default_realm(ctx, def); + } + + pkrb5_free_context(ctx); + + return rv; +} + wchar_t * khm_get_realm_from_princ(wchar_t * princ) { wchar_t * t; @@ -1858,7 +1970,7 @@ khm_krb5_changepwd(char * principal, (result_string.length ? (sizeof(": ") - 1) : 0) + result_string.length; if (len && error_str) { - *error_str = malloc(len + 1); + *error_str = PMALLOC(len + 1); if (*error_str) StringCchPrintfA(*error_str, len+1, "%.*s%s%.*s", @@ -1887,3 +1999,13 @@ khm_krb5_changepwd(char * principal, return rc; } + +khm_int32 KHMAPI +khm_krb5_creds_is_equal(khm_handle vcred1, khm_handle vcred2, void * dummy) { + if (kcdb_creds_comp_attr(vcred1, vcred2, KCDB_ATTR_LOCATION) || + kcdb_creds_comp_attr(vcred1, vcred2, attr_id_key_enctype) || + kcdb_creds_comp_attr(vcred1, vcred2, attr_id_tkt_enctype)) + return 1; + else + return 0; +} diff --git a/src/windows/identity/plugins/krb5/krb5funcs.h b/src/windows/identity/plugins/krb5/krb5funcs.h index 79ca95646..6c2c3eb6b 100644 --- a/src/windows/identity/plugins/krb5/krb5funcs.h +++ b/src/windows/identity/plugins/krb5/krb5funcs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -90,6 +90,9 @@ khm_krb5_renew(khm_handle identity); wchar_t * khm_krb5_get_default_realm(void); +long +khm_krb5_set_default_realm(wchar_t * realm); + wchar_t * khm_krb5_get_realm_list(void); @@ -116,6 +119,12 @@ khm_krb5_cc_name_cmp(const wchar_t * cc_name_1, const wchar_t * cc_name_2); BOOL -khm_get_profile_file(LPSTR confname, UINT szConfname); +khm_krb5_get_profile_file(LPSTR confname, UINT szConfname); + +BOOL +khm_krb5_get_temp_profile_file(LPSTR confname, UINT szConfname); + +khm_int32 KHMAPI +khm_krb5_creds_is_equal(khm_handle vcred1, khm_handle vcred2, void * dummy); #endif diff --git a/src/windows/identity/plugins/krb5/krb5identpro.c b/src/windows/identity/plugins/krb5/krb5identpro.c index c568e49d0..dd4782e6f 100644 --- a/src/windows/identity/plugins/krb5/krb5identpro.c +++ b/src/windows/identity/plugins/krb5/krb5identpro.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -49,6 +49,7 @@ typedef struct tag_k5_new_cred_data { HWND hw_realm; } k5_new_cred_data; +/* Runs in the UI thread */ int k5_get_realm_from_nc(khui_new_creds * nc, wchar_t * buf, @@ -118,6 +119,7 @@ set_identity_from_ui(khui_new_creds * nc, return; } +/* runs in the UI thread */ static BOOL update_crossfeed(khui_new_creds * nc, k5_new_cred_data * d, @@ -127,6 +129,7 @@ update_crossfeed(khui_new_creds * nc, wchar_t realm[KCDB_IDENT_MAXCCH_NAME]; khm_size cch; khm_size cch_left; + int idx; cch = (khm_size) GetWindowTextLength(d->hw_username); #ifdef DEBUG @@ -145,6 +148,38 @@ update_crossfeed(khui_new_creds * nc, return FALSE; if (ctrl_id_src == K5_NCID_UN) { + + idx = (int)SendMessage(d->hw_realm, + CB_FINDSTRINGEXACT, + (WPARAM) -1, + (LPARAM) un_realm); + + if (idx != CB_ERR) { + wchar_t srealm[KCDB_IDENT_MAXCCH_NAME]; + + cch = SendMessage(d->hw_realm, + CB_GETLBTEXTLEN, + (WPARAM) idx, + 0); + +#ifdef DEBUG + assert(cch < ARRAYLENGTH(srealm) - 1); +#endif + SendMessage(d->hw_realm, + CB_GETLBTEXT, + (WPARAM) idx, + (LPARAM) srealm); + + if (!wcsicmp(srealm, un_realm) && wcscmp(srealm, un_realm)) { + /* differ only by case */ + + StringCchCopy(un_realm, ARRAYLENGTH(un) - (un_realm - un), + srealm); + + SetWindowText(d->hw_username, un); + } + } + SendMessage(d->hw_realm, CB_SELECTSTRING, (WPARAM) -1, @@ -170,6 +205,26 @@ update_crossfeed(khui_new_creds * nc, GetWindowText(d->hw_realm, realm, ARRAYLENGTH(realm)); + idx = (int)SendMessage(d->hw_realm, + CB_FINDSTRINGEXACT, + (WPARAM) -1, + (LPARAM) realm); + + if (idx != CB_ERR) { + wchar_t srealm[KCDB_IDENT_MAXCCH_NAME]; + + SendMessage(d->hw_realm, + CB_GETLBTEXT, + (WPARAM) idx, + (LPARAM) srealm); + + if (!wcsicmp(srealm, realm) && wcscmp(srealm, realm)) { + StringCbCopy(realm, sizeof(realm), srealm); + + SetWindowText(d->hw_realm, srealm); + } + } + StringCchCopy(un_realm, cch_left, realm); SendMessage(d->hw_username, @@ -258,6 +313,7 @@ ui_cb(khui_new_creds * nc, UINT uMsg, WPARAM wParam, LPARAM lParam) { + k5_new_cred_data * d; d = (k5_new_cred_data *) nc->ident_aux; @@ -285,7 +341,7 @@ ui_cb(khui_new_creds * nc, assert(hw_parent != NULL); #endif - d = malloc(sizeof(*d)); + d = PMALLOC(sizeof(*d)); assert(d); ZeroMemory(d, sizeof(*d)); @@ -385,7 +441,7 @@ ui_cb(khui_new_creds * nc, if (rv != KHM_ERROR_TOO_LONG) goto _add_lru_realms; - ms = malloc(cb_ms); + ms = PMALLOC(cb_ms); assert(ms != NULL); cb = cb_ms; @@ -430,13 +486,13 @@ ui_cb(khui_new_creds * nc, if (ms != NULL) { if (cb_ms < cb) { - free(ms); - ms = malloc(cb); + PFREE(ms); + ms = PMALLOC(cb); assert(ms); cb_ms = cb; } } else { - ms = malloc(cb); + ms = PMALLOC(cb); cb_ms = cb; } @@ -476,10 +532,10 @@ ui_cb(khui_new_creds * nc, } if (defrealm) - free(defrealm); + PFREE(defrealm); if (ms) - free(ms); + PFREE(ms); /* now see about that default identity */ if (nc->ctx.identity) { @@ -553,7 +609,7 @@ ui_cb(khui_new_creds * nc, /* since we created all the windows as child windows of the new creds window, they will be destroyed when that window is destroyed. */ - free(d); + PFREE(d); } return TRUE; } @@ -598,6 +654,20 @@ k5_ident_valiate_name(khm_int32 msg_type, return KHM_ERROR_SUCCESS; } +static void +k5_update_last_default_identity(khm_handle ident) { + wchar_t idname[KCDB_IDENT_MAXCCH_NAME]; + khm_size cb; + + cb = sizeof(idname); + if (KHM_FAILED(kcdb_identity_get_name(ident, idname, &cb))) + return; + + assert(csp_params); + + khc_write_string(csp_params, L"LastDefaultIdent", idname); +} + static khm_int32 k5_ident_set_default(khm_int32 msg_type, khm_int32 msg_subtype, @@ -702,9 +772,10 @@ k5_ident_set_default(khm_int32 msg_type, RegCloseKey(hk_ccname); - if (l == ERROR_SUCCESS) + if (l == ERROR_SUCCESS) { + k5_update_last_default_identity(def_ident); return KHM_ERROR_SUCCESS; - else + } else return KHM_ERROR_UNKNOWN; } else if (dw > ARRAYLENGTH(env_ccname)) { @@ -721,8 +792,10 @@ k5_ident_set_default(khm_int32 msg_type, /* if the %KRB5CCNAME is the same as the identity ccache, then it is already the default. */ - if (!khm_krb5_cc_name_cmp(id_ccname, env_ccname)) + if (!khm_krb5_cc_name_cmp(id_ccname, env_ccname)) { + k5_update_last_default_identity(def_ident); return KHM_ERROR_SUCCESS; + } /* if not, we have to copy the contents of id_ccname to env_ccname */ @@ -734,8 +807,10 @@ k5_ident_set_default(khm_int32 msg_type, env_ccname, id_ccname); - if (code == 0) + if (code == 0) { + k5_update_last_default_identity(def_ident); khm_krb5_list_tickets(&ctx); + } if (ctx) pkrb5_free_context(ctx); @@ -784,6 +859,17 @@ k5_ident_notify_create(khm_int32 msg_type, khm_size cb; khm_handle ident; + /* if there is a default identity already, we assume we don't need + to check this one. */ + + khm_handle def_ident; + + if (KHM_SUCCEEDED(kcdb_identity_get_default(&def_ident))) { + kcdb_identity_release(def_ident); + + return KHM_ERROR_SUCCESS; + } + ident = (khm_handle) vparam; assert(k5_identpro_ctx != NULL); @@ -829,7 +915,6 @@ k5_ident_notify_create(khm_int32 msg_type, if (cc) pkrb5_cc_close(k5_identpro_ctx, cc); - return KHM_ERROR_SUCCESS; } @@ -842,6 +927,7 @@ k5_ident_update_apply_proc(khm_handle cred, khm_int32 t; khm_int32 flags; __int64 t_expire; + __int64 t_cexpire; __int64 t_rexpire; khm_size cb; khm_int32 rv = KHM_ERROR_SUCCESS; @@ -851,32 +937,34 @@ k5_ident_update_apply_proc(khm_handle cred, KHM_FAILED(kcdb_cred_get_identity(cred, &ident))) return KHM_ERROR_SUCCESS; - if (ident != tident) + if (!kcdb_identity_is_equal(ident,tident)) goto _cleanup; if (KHM_FAILED(kcdb_cred_get_flags(cred, &flags))) flags = 0; - cb = sizeof(t_expire); - if (KHM_SUCCEEDED(kcdb_cred_get_attr(cred, - KCDB_ATTR_EXPIRE, - NULL, - &t_expire, - &cb))) { - __int64 t_cexpire; - + if (flags & KCDB_CRED_FLAG_INITIAL) { cb = sizeof(t_cexpire); - if ((flags & KCDB_CRED_FLAG_INITIAL) || - KHM_FAILED(kcdb_identity_get_attr(tident, - KCDB_ATTR_EXPIRE, - NULL, - &t_cexpire, - &cb)) || - t_cexpire > t_expire) - kcdb_identity_set_attr(tident, KCDB_ATTR_EXPIRE, - &t_expire, sizeof(t_expire)); - } else if (flags & KCDB_CRED_FLAG_INITIAL) { - kcdb_identity_set_attr(tident, KCDB_ATTR_EXPIRE, NULL, 0); + if (KHM_SUCCEEDED(kcdb_cred_get_attr(cred, + KCDB_ATTR_EXPIRE, + NULL, + &t_cexpire, + &cb))) { + t_expire = 0; + cb = sizeof(t_expire); + if (KHM_FAILED(kcdb_identity_get_attr(tident, + KCDB_ATTR_EXPIRE, + NULL, + &t_expire, + &cb)) || + (t_cexpire > t_expire)) + kcdb_identity_set_attr(tident, KCDB_ATTR_EXPIRE, + &t_cexpire, sizeof(t_cexpire)); + } else { + kcdb_identity_set_attr(tident, KCDB_ATTR_EXPIRE, NULL, 0); + } + } else { + goto _cleanup; } cb = sizeof(ccname); @@ -890,16 +978,14 @@ k5_ident_update_apply_proc(khm_handle cred, kcdb_identity_set_attr(tident, attr_id_krb5_ccname, NULL, 0); } - - if (!(flags & KCDB_CRED_FLAG_INITIAL)) - goto _cleanup; - + cb = sizeof(t); if (KHM_SUCCEEDED(kcdb_cred_get_attr(cred, attr_id_krb5_flags, NULL, &t, &cb))) { + kcdb_identity_set_attr(tident, attr_id_krb5_flags, &t, sizeof(t)); @@ -939,6 +1025,13 @@ k5_ident_update(khm_int32 msg_type, void * vparam) { khm_handle ident; + khm_handle tident; + krb5_ccache cc = NULL; + char * ccname; + krb5_error_code code; + khm_size cb; + wchar_t wid_ccname[MAX_PATH]; + wchar_t w_ccname[MAX_PATH]; ident = (khm_handle) vparam; if (ident == NULL) @@ -948,6 +1041,42 @@ k5_ident_update(khm_int32 msg_type, k5_ident_update_apply_proc, (void *) ident); + if (KHM_SUCCEEDED(kcdb_identity_get_default(&tident))) { + kcdb_identity_release(tident); + goto _iu_cleanup; + } + + cb = sizeof(wid_ccname); + if (KHM_FAILED(kcdb_identity_get_attr(ident, + attr_id_krb5_ccname, + NULL, + wid_ccname, + &cb))) + goto _iu_cleanup; + + if(k5_identpro_ctx == NULL) + goto _iu_cleanup; + + code = pkrb5_cc_default(k5_identpro_ctx, &cc); + if (code) + goto _iu_cleanup; + + ccname = pkrb5_cc_get_name(k5_identpro_ctx, cc); + if (ccname == NULL) + goto _iu_cleanup; + + AnsiStrToUnicode(w_ccname, sizeof(w_ccname), ccname); + + khm_krb5_canon_cc_name(w_ccname, sizeof(w_ccname)); + khm_krb5_canon_cc_name(wid_ccname, sizeof(wid_ccname)); + + if (!wcsicmp(w_ccname, wid_ccname)) + kcdb_identity_set_default_int(ident); + + _iu_cleanup: + if (cc && k5_identpro_ctx) + pkrb5_cc_close(k5_identpro_ctx, cc); + return KHM_ERROR_SUCCESS; } @@ -965,6 +1094,7 @@ k5_ident_init(khm_int32 msg_type, char * princ_nameA = NULL; wchar_t princ_nameW[KCDB_IDENT_MAXCCH_NAME]; khm_handle ident = NULL; + khm_boolean found_default = FALSE; assert(k5_identpro_ctx != NULL); @@ -995,6 +1125,8 @@ k5_ident_init(khm_int32 msg_type, kcdb_identity_set_default_int(ident); + found_default = TRUE; + _nc_cleanup: if (princ_nameA) pkrb5_free_unparsed_name(k5_identpro_ctx, @@ -1008,6 +1140,25 @@ k5_ident_init(khm_int32 msg_type, if (ident) kcdb_identity_release(ident); + if (!found_default) { + wchar_t widname[KCDB_IDENT_MAXCCH_NAME]; + khm_size cb; + + cb = sizeof(widname); + + assert(csp_params); + + if (KHM_SUCCEEDED(khc_read_string(csp_params, L"LastDefaultIdent", + widname, &cb))) { + ident = NULL; + kcdb_identity_create(widname, KCDB_IDENT_FLAG_CREATE, &ident); + if (ident) { + kcdb_identity_set_default_int(ident); + kcdb_identity_release(ident); + } + } + } + return KHM_ERROR_SUCCESS; } @@ -1106,3 +1257,121 @@ k5_msg_ident(khm_int32 msg_type, return KHM_ERROR_SUCCESS; } + +khm_int32 KHMAPI +k5_ident_name_comp_func(const void * dl, khm_size cb_dl, + const void * dr, khm_size cb_dr) { + wchar_t * idl = (wchar_t *) dl; + wchar_t * idr = (wchar_t *) dr; + wchar_t * rl; + wchar_t * rr; + khm_int32 r; + + rl = khm_get_realm_from_princ(idl); + rr = khm_get_realm_from_princ(idr); + + if (rl == NULL && rr == NULL) + return wcscmp(idl, idr); + else if (rl == NULL) + return 1; + else if (rr == NULL) + return -1; + + r = wcscmp(rl, rr); + if (r == 0) + return wcscmp(idl, idr); + else + return r; +} + +khm_int32 +k5_msg_system_idpro(khm_int32 msg_type, khm_int32 msg_subtype, + khm_ui_4 uparam, void * vparam) { + + switch(msg_subtype) { + case KMSG_SYSTEM_INIT: + { + + pkrb5_init_context(&k5_identpro_ctx); + kcdb_identity_set_type(credtype_id_krb5); + + if (KHM_FAILED(kcdb_type_get_id(TYPENAME_KRB5_PRINC, + &type_id_krb5_princ))) { + kcdb_type dt; + kcdb_type * pstr; + + kcdb_type_get_info(KCDB_TYPE_STRING, &pstr); + + ZeroMemory(&dt, sizeof(dt)); + dt.name = TYPENAME_KRB5_PRINC; + dt.id = KCDB_TYPE_INVALID; + dt.flags = KCDB_TYPE_FLAG_CB_AUTO; + dt.cb_min = pstr->cb_min; + dt.cb_max = pstr->cb_max; + dt.toString = pstr->toString; + dt.isValid = pstr->isValid; + dt.comp = k5_ident_name_comp_func; + dt.dup = pstr->dup; + + kcdb_type_register(&dt, &type_id_krb5_princ); + + type_regd_krb5_princ = TRUE; + + kcdb_type_release_info(pstr); + } + + if (type_id_krb5_princ != -1) { + kcdb_attrib * attr; + + kcdb_attrib_get_info(KCDB_ATTR_ID_NAME, &attr); + + attr->type = type_id_krb5_princ; + + kcdb_attrib_release_info(attr); + } + } + break; + + case KMSG_SYSTEM_EXIT: + { + if (k5_identpro_ctx) { + pkrb5_free_context(k5_identpro_ctx); + k5_identpro_ctx = NULL; + } + + if (type_id_krb5_princ != -1) { + kcdb_attrib * attr; + + kcdb_attrib_get_info(KCDB_ATTR_ID_NAME, &attr); + + attr->type = KCDB_TYPE_STRING; + + kcdb_attrib_release_info(attr); + } + + /* allow a brief moment for any stale references to die */ + Sleep(100); + + if (type_regd_krb5_princ) { + kcdb_type_unregister(type_id_krb5_princ); + } + } + break; + } + + return KHM_ERROR_SUCCESS; +} + +khm_int32 KHMAPI +k5_ident_callback(khm_int32 msg_type, khm_int32 msg_subtype, + khm_ui_4 uparam, void * vparam) { + switch(msg_type) { + case KMSG_SYSTEM: + return k5_msg_system_idpro(msg_type, msg_subtype, uparam, vparam); + + case KMSG_IDENT: + return k5_msg_ident(msg_type, msg_subtype, uparam, vparam); + } + + return KHM_ERROR_SUCCESS; +} diff --git a/src/windows/identity/plugins/krb5/main.c b/src/windows/identity/plugins/krb5/krb5main.c similarity index 92% rename from src/windows/identity/plugins/krb5/main.c rename to src/windows/identity/plugins/krb5/krb5main.c index db996d951..7bf121dd0 100644 --- a/src/windows/identity/plugins/krb5/main.c +++ b/src/windows/identity/plugins/krb5/krb5main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -35,10 +35,12 @@ const wchar_t * k5_facility = L"Krb5"; khm_int32 type_id_enctype = -1; khm_int32 type_id_addr_list = -1; khm_int32 type_id_krb5_flags = -1; +khm_int32 type_id_krb5_princ = -1; BOOL type_regd_enctype = FALSE; BOOL type_regd_addr_list = FALSE; BOOL type_regd_krb5_flags = FALSE; +BOOL type_regd_krb5_princ = FALSE; khm_int32 attr_id_key_enctype = -1; khm_int32 attr_id_tkt_enctype = -1; @@ -89,13 +91,25 @@ KHMEXP khm_int32 KHMAPI init_module(kmm_module h_module) { pi.name = KRB5_PLUGIN_NAME; pi.type = KHM_PITYPE_CRED; pi.icon = NULL; /*TODO: Assign icon */ - pi.flags = KHM_PIFLAG_IDENTITY_PROVIDER; + pi.flags = 0; pi.msg_proc = k5_msg_callback; pi.description = buf; 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 = NULL; /* ignored */ + 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; diff --git a/src/windows/identity/plugins/krb5/krb5newcreds.c b/src/windows/identity/plugins/krb5/krb5newcreds.c index 968e0e290..fc36d2c20 100644 --- a/src/windows/identity/plugins/krb5/krb5newcreds.c +++ b/src/windows/identity/plugins/krb5/krb5newcreds.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -63,7 +63,7 @@ k5_handle_wm_initdialog(HWND hwnd, k5_dlg_data * d; khui_new_creds_by_type * nct; - d = malloc(sizeof(*d)); + d = PMALLOC(sizeof(*d)); ZeroMemory(d, sizeof(*d)); /* lParam is a pointer to a khui_new_creds structure */ d->nc = (khui_new_creds *) lParam; @@ -116,7 +116,7 @@ k5_handle_wm_destroy(HWND hwnd, khui_tracker_kill_controls(&d->tc_lifetime); } - free(d); + PFREE(d); return TRUE; } @@ -200,7 +200,7 @@ k5_handle_wmnc_notify(HWND hwnd, break; if(nct->credtext) - free(nct->credtext); + PFREE(nct->credtext); nct->credtext = NULL; tbuf[0] = L'\0'; @@ -227,7 +227,7 @@ k5_handle_wmnc_notify(HWND hwnd, StringCbLength(sbuf, sizeof(sbuf), &cbsize); cbsize += sizeof(wchar_t); - nct->credtext = malloc(cbsize); + nct->credtext = PMALLOC(cbsize); StringCbCopy(nct->credtext, cbsize, sbuf); } else if (nc->n_identities > 0 && @@ -242,7 +242,7 @@ k5_handle_wmnc_notify(HWND hwnd, StringCbLength(sbuf, sizeof(sbuf), &cbsize); cbsize += sizeof(wchar_t); - nct->credtext = malloc(cbsize); + nct->credtext = PMALLOC(cbsize); StringCbCopy(nct->credtext, cbsize, sbuf); } else { @@ -251,7 +251,7 @@ k5_handle_wmnc_notify(HWND hwnd, &cbsize); cbsize += sizeof(wchar_t); - nct->credtext = malloc(cbsize); + nct->credtext = PMALLOC(cbsize); StringCbCopy(nct->credtext, cbsize, d->cred_message); } @@ -1131,7 +1131,7 @@ k5_prep_kinit_job(khui_new_creds * nc) g_fjob.nc = nc; g_fjob.nct = nct; g_fjob.dialog = nct->hwnd_panel; - g_fjob.principal = malloc(size); + g_fjob.principal = PMALLOC(size); UnicodeStrToAnsi(g_fjob.principal, size, idname); g_fjob.password = NULL; g_fjob.lifetime = (krb5_deltat) d->tc_lifetime.current; @@ -1155,7 +1155,7 @@ k5_prep_kinit_job(khui_new_creds * nc) SUCCEEDED(StringCchLength(pdlginfo->in.ccache, NETID_CCACHE_NAME_SZ, &size))) { - g_fjob.ccache = malloc(sizeof(char) * (size + 1)); + g_fjob.ccache = PMALLOC(sizeof(char) * (size + 1)); #ifdef DEBUG assert(g_fjob.ccache); #endif @@ -1210,16 +1210,16 @@ void k5_free_kinit_job(void) { if (g_fjob.principal) - free(g_fjob.principal); + PFREE(g_fjob.principal); if (g_fjob.password) - free(g_fjob.password); + PFREE(g_fjob.password); if (g_fjob.identity) kcdb_identity_release(g_fjob.identity); if (g_fjob.ccache) - free(g_fjob.ccache); + PFREE(g_fjob.ccache); ZeroMemory(&g_fjob, sizeof(g_fjob)); } @@ -1272,7 +1272,7 @@ k5_msg_cred_dialog(khm_int32 msg_type, nc = (khui_new_creds *) vparam; - nct = malloc(sizeof(*nct)); + nct = PMALLOC(sizeof(*nct)); ZeroMemory(nct, sizeof(*nct)); nct->type = credtype_id_krb5; @@ -1283,7 +1283,7 @@ k5_msg_cred_dialog(khm_int32 msg_type, StringCbLength(wbuf, sizeof(wbuf), &cbsize); cbsize += sizeof(wchar_t); - nct->name = malloc(cbsize); + nct->name = PMALLOC(cbsize); StringCbCopy(nct->name, cbsize, wbuf); nct->h_module = hResModule; @@ -1304,7 +1304,7 @@ k5_msg_cred_dialog(khm_int32 msg_type, nc = (khui_new_creds *) vparam; - nct = malloc(sizeof(*nct)); + nct = PMALLOC(sizeof(*nct)); ZeroMemory(nct, sizeof(*nct)); nct->type = credtype_id_krb5; @@ -1350,7 +1350,7 @@ k5_msg_cred_dialog(khm_int32 msg_type, 0, (LPARAM) t); t = multi_string_next(t); } - free(realms); + PFREE(realms); } /* and set the default realm */ @@ -1364,7 +1364,7 @@ k5_msg_cred_dialog(khm_int32 msg_type, SendDlgItemMessage(hwnd, IDC_NCK5_REALM, WM_SETTEXT, 0, (LPARAM) defrealm); - free(defrealm); + PFREE(defrealm); } } else { /* if krb5 is the identity provider */ HWND hw_realms; @@ -1526,14 +1526,15 @@ k5_msg_cred_dialog(khm_int32 msg_type, password */ if(g_fjob.code) { if (is_k5_identpro) - kcdb_identity_set_flags(ident, + kcdb_identity_set_flags(ident, + KCDB_IDENT_FLAG_INVALID, KCDB_IDENT_FLAG_INVALID); khui_cw_clear_prompts(nc); } if (d->cred_message) { - free(d->cred_message); + PFREE(d->cred_message); d->cred_message = NULL; } @@ -1576,7 +1577,7 @@ k5_msg_cred_dialog(khm_int32 msg_type, StringCbLength(msg, sizeof(msg), &cb); cb += sizeof(wchar_t); - d->cred_message = malloc(cb); + d->cred_message = PMALLOC(cb); StringCbCopy(d->cred_message, cb, msg); } @@ -1587,6 +1588,7 @@ k5_msg_cred_dialog(khm_int32 msg_type, if(is_k5_identpro) kcdb_identity_set_flags(ident, + KCDB_IDENT_FLAG_VALID, KCDB_IDENT_FLAG_VALID); } else { /* huh?? */ @@ -1688,12 +1690,12 @@ k5_msg_cred_dialog(khm_int32 msg_type, (nc->n_identities == 0 || nc->identities[0] == NULL || KHM_SUCCEEDED(kcdb_credset_find_filtered - (NULL, - -1, - k5_find_tgt_filter, - nc->identities[0], - NULL, - NULL)))) + (NULL, + -1, + k5_find_tgt_filter, + nc->identities[0], + NULL, + NULL)))) g_fjob.code = 0; @@ -1776,7 +1778,7 @@ k5_msg_cred_dialog(khm_int32 msg_type, &cb); assert(rv == KHM_ERROR_TOO_LONG); - idname = malloc(cb); + idname = PMALLOC(cb); assert(idname); rv = kcdb_identity_get_name(nc->identities[0], @@ -1793,7 +1795,7 @@ k5_msg_cred_dialog(khm_int32 msg_type, else cb_ms += cb + sizeof(wchar_t); - wbuf = malloc(cb_ms); + wbuf = PMALLOC(cb_ms); assert(wbuf); cb = cb_ms; @@ -1838,8 +1840,8 @@ k5_msg_cred_dialog(khm_int32 msg_type, &cb); if (rv == KHM_ERROR_TOO_LONG) { - free(wbuf); - wbuf = malloc(cb); + PFREE(wbuf); + wbuf = PMALLOC(cb); assert(wbuf); cb_ms = cb; @@ -1886,10 +1888,10 @@ k5_msg_cred_dialog(khm_int32 msg_type, pkrb5_free_context(ctx); if (idname) - free(idname); + PFREE(idname); if (wbuf) - free(wbuf); + PFREE(wbuf); } else if (g_fjob.state == FIBER_STATE_NONE) { /* the user cancelled the operation */ r = KHUI_NC_RESPONSE_EXIT | @@ -1921,6 +1923,12 @@ k5_msg_cred_dialog(khm_int32 msg_type, _end_task(); } else if (nc->subtype == KMSG_CRED_RENEW_CREDS) { + __int64 ftidexp = 0; + __int64 ftcurrent; + khm_size cb; + + GetSystemTimeAsFileTime((LPFILETIME) &ftcurrent); + _begin_task(0); _report_mr0(KHERR_NONE, MSG_CTX_RENEW_CREDS); _describe(); @@ -1930,10 +1938,20 @@ k5_msg_cred_dialog(khm_int32 msg_type, nc->ctx.cred_type == credtype_id_krb5)) { int code; - if (nc->ctx.identity != 0) + if (nc->ctx.identity != 0) { + /* get the current identity expiration time */ + cb = sizeof(ftidexp); + + kcdb_identity_get_attr(nc->ctx.identity, + KCDB_ATTR_EXPIRE, + NULL, + &ftidexp, + &cb); + code = khm_krb5_renew(nc->ctx.identity); - else + } else { code = 1; /* it just has to be non-zero */ + } if (code == 0) { khui_cw_set_response(nc, credtype_id_krb5, @@ -1946,6 +1964,29 @@ k5_msg_cred_dialog(khm_int32 msg_type, khui_cw_set_response(nc, credtype_id_krb5, KHUI_NC_RESPONSE_EXIT | KHUI_NC_RESPONSE_FAILED); + } else if (ftcurrent < ftidexp) { + wchar_t tbuf[1024]; + DWORD suggestion; + kherr_suggestion sug_id; + + /* if we failed to get new tickets, but the + identity isstill valid, then we assume that + the current tickets are still good enough + for other credential types to obtain their + credentials. */ + + khm_err_describe(code, tbuf, sizeof(tbuf), + &suggestion, &sug_id); + + _report_cs0(KHERR_WARNING, tbuf); + if (suggestion) + _suggest_mr(suggestion, sug_id); + + _resolve(); + + khui_cw_set_response(nc, credtype_id_krb5, + KHUI_NC_RESPONSE_EXIT | + KHUI_NC_RESPONSE_SUCCESS); } else { wchar_t tbuf[1024]; DWORD suggestion; @@ -2049,14 +2090,14 @@ k5_msg_cred_dialog(khm_int32 msg_type, } if (wcscmp(wnpwd, wnpwd2)) { - rv = KHM_ERROR_INVALID_PARM; + rv = KHM_ERROR_INVALID_PARAM; _report_mr0(KHERR_ERROR, MSG_PWD_NOT_SAME); _suggest_mr(MSG_PWD_S_NOT_SAME, KHERR_SUGGEST_INTERACT); goto _pwd_exit; } if (!wcscmp(wpwd, wnpwd)) { - rv = KHM_ERROR_INVALID_PARM; + rv = KHM_ERROR_INVALID_PARAM; _report_mr0(KHERR_ERROR, MSG_PWD_SAME); _suggest_mr(MSG_PWD_S_SAME, KHERR_SUGGEST_INTERACT); goto _pwd_exit; @@ -2082,7 +2123,7 @@ k5_msg_cred_dialog(khm_int32 msg_type, StringCchLengthA(result, KHERR_MAXCCH_STRING, &len); - wresult = malloc((len + 1) * sizeof(wchar_t)); + wresult = PMALLOC((len + 1) * sizeof(wchar_t)); #ifdef DEBUG assert(wresult); #endif @@ -2092,8 +2133,8 @@ k5_msg_cred_dialog(khm_int32 msg_type, _report_cs1(KHERR_ERROR, L"%1!s!", _cstr(wresult)); _resolve(); - free(result); - free(wresult); + PFREE(result); + PFREE(wresult); /* leave wresult. It will get freed when the reported event is freed. */ @@ -2149,10 +2190,12 @@ k5_msg_cred_dialog(khm_int32 msg_type, khui_cw_del_type(nc, credtype_id_krb5); - if(nct->name) - free(nct->name); + if (nct->name) + PFREE(nct->name); + if (nct->credtext) + PFREE(nct->credtext); - free(nct); + PFREE(nct); } break; diff --git a/src/windows/identity/plugins/krb5/krb5plugin.c b/src/windows/identity/plugins/krb5/krb5plugin.c index 4b53ed3e8..ecfde2f5a 100644 --- a/src/windows/identity/plugins/krb5/krb5plugin.c +++ b/src/windows/identity/plugins/krb5/krb5plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -47,91 +47,90 @@ krb5_context k5_identpro_ctx = NULL; /* The system message handler. Runs in the context of the plugin thread */ -khm_int32 KHMAPI k5_msg_system(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui_4 uparam, void * vparam) +khm_int32 KHMAPI +k5_msg_system(khm_int32 msg_type, khm_int32 msg_subtype, + khm_ui_4 uparam, void * vparam) { khm_int32 rv = KHM_ERROR_SUCCESS; switch(msg_subtype) { - case KMSG_SYSTEM_INIT: - { - kcdb_credtype ct; - wchar_t buf[KCDB_MAXCCH_SHORT_DESC]; - size_t cbsize; - - /* perform critical registrations and initialization - stuff */ - ZeroMemory(&ct, sizeof(ct)); - ct.id = KCDB_CREDTYPE_AUTO; - ct.name = KRB5_CREDTYPE_NAME; - - if(LoadString(hResModule, IDS_KRB5_SHORT_DESC, buf, ARRAYLENGTH(buf))) - { - StringCbLength(buf, KCDB_MAXCB_SHORT_DESC, &cbsize); - cbsize += sizeof(wchar_t); - ct.short_desc = malloc(cbsize); - StringCbCopy(ct.short_desc, cbsize, buf); - } - - /* even though ideally we should be setting limits - based KCDB_MAXCB_LONG_DESC, our long description - actually fits nicely in KCDB_MAXCB_SHORT_DESC */ - if(LoadString(hResModule, IDS_KRB5_LONG_DESC, buf, ARRAYLENGTH(buf))) - { - StringCbLength(buf, KCDB_MAXCB_SHORT_DESC, &cbsize); - cbsize += sizeof(wchar_t); - ct.long_desc = malloc(cbsize); - StringCbCopy(ct.long_desc, cbsize, buf); - } + case KMSG_SYSTEM_INIT: + { + kcdb_credtype ct; + wchar_t buf[KCDB_MAXCCH_SHORT_DESC]; + size_t cbsize; + + /* perform critical registrations and initialization + stuff */ + ZeroMemory(&ct, sizeof(ct)); + ct.id = KCDB_CREDTYPE_AUTO; + ct.name = KRB5_CREDTYPE_NAME; + + if(LoadString(hResModule, IDS_KRB5_SHORT_DESC, + buf, ARRAYLENGTH(buf))) { + StringCbLength(buf, KCDB_MAXCB_SHORT_DESC, &cbsize); + cbsize += sizeof(wchar_t); + ct.short_desc = PMALLOC(cbsize); + StringCbCopy(ct.short_desc, cbsize, buf); + } - ct.icon = NULL; /* TODO: set a proper icon */ + /* even though ideally we should be setting limits + based KCDB_MAXCB_LONG_DESC, our long description + actually fits nicely in KCDB_MAXCB_SHORT_DESC */ + if(LoadString(hResModule, IDS_KRB5_LONG_DESC, + buf, ARRAYLENGTH(buf))) { + StringCbLength(buf, KCDB_MAXCB_SHORT_DESC, &cbsize); + cbsize += sizeof(wchar_t); + ct.long_desc = PMALLOC(cbsize); + StringCbCopy(ct.long_desc, cbsize, buf); + } - kmq_create_subscription(k5_msg_callback, &ct.sub); + ct.icon = NULL; /* TODO: set a proper icon */ - rv = kcdb_credtype_register(&ct, &credtype_id_krb5); + kmq_create_subscription(k5_msg_callback, &ct.sub); - if(KHM_SUCCEEDED(rv)) - rv = kcdb_credset_create(&krb5_credset); + ct.is_equal = khm_krb5_creds_is_equal; - if(ct.short_desc) - free(ct.short_desc); + rv = kcdb_credtype_register(&ct, &credtype_id_krb5); - if(ct.long_desc) - free(ct.long_desc); + if(KHM_SUCCEEDED(rv)) + rv = kcdb_credset_create(&krb5_credset); - if (is_k5_identpro) - kcdb_identity_set_type(credtype_id_krb5); + if(ct.short_desc) + PFREE(ct.short_desc); - if(KHM_SUCCEEDED(rv)) { - krb5_context ctx = NULL; + if(ct.long_desc) + PFREE(ct.long_desc); - krb5_initialized = TRUE; + if(KHM_SUCCEEDED(rv)) { + krb5_context ctx = NULL; - khm_krb5_list_tickets(&ctx); + krb5_initialized = TRUE; - if(ctx != NULL) - pkrb5_free_context(ctx); + if(ctx != NULL) + pkrb5_free_context(ctx); - /* now convert this thread to a fiber and create a - separate fiber to do kinit stuff */ - k5_main_fiber = ConvertThreadToFiber(NULL); - k5_kinit_fiber = CreateFiber(0,k5_kinit_fiber_proc,NULL); + /* now convert this thread to a fiber and create a + separate fiber to do kinit stuff */ + k5_main_fiber = ConvertThreadToFiber(NULL); + k5_kinit_fiber = CreateFiber(0,k5_kinit_fiber_proc,NULL); - ZeroMemory(&g_fjob, sizeof(g_fjob)); + ZeroMemory(&g_fjob, sizeof(g_fjob)); - kmq_create_subscription(k5_msg_callback, &k5_sub); + kmq_create_subscription(k5_msg_callback, &k5_sub); - pkrb5_init_context(&k5_identpro_ctx); + k5_register_config_panels(); - k5_register_config_panels(); - } + khm_krb5_list_tickets(&ctx); } - break; + } + break; - case KMSG_SYSTEM_EXIT: + case KMSG_SYSTEM_EXIT: - k5_unregister_config_panels(); + k5_unregister_config_panels(); - if(credtype_id_krb5 >= 0) + if(credtype_id_krb5 >= 0) { /* basically just unregister the credential type */ kcdb_credtype_unregister(credtype_id_krb5); @@ -141,22 +140,19 @@ khm_int32 KHMAPI k5_msg_system(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui krb5_credset = NULL; } - if(k5_main_fiber != NULL) { - ConvertFiberToThread(); - k5_main_fiber = NULL; - } + if(k5_main_fiber != NULL) { +#if (_WIN32_WINNT >= 0x0501) + ConvertFiberToThread(); +#endif + k5_main_fiber = NULL; + } - if(k5_sub != NULL) { - kmq_delete_subscription(k5_sub); - k5_sub = NULL; - } + if(k5_sub != NULL) { + kmq_delete_subscription(k5_sub); + k5_sub = NULL; + } - if (k5_identpro_ctx) { - pkrb5_free_context(k5_identpro_ctx); - k5_identpro_ctx = NULL; - } - - break; + break; } return rv; @@ -167,45 +163,47 @@ khm_int32 KHMAPI k5_msg_system(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui Runs in the context of the Krb5 plugin */ -khm_int32 KHMAPI k5_msg_cred(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui_4 uparam, void * vparam) +khm_int32 KHMAPI +k5_msg_cred(khm_int32 msg_type, khm_int32 msg_subtype, + khm_ui_4 uparam, void * vparam) { khm_int32 rv = KHM_ERROR_SUCCESS; switch(msg_subtype) { - case KMSG_CRED_REFRESH: - { - krb5_context ctx = NULL; + case KMSG_CRED_REFRESH: + { + krb5_context ctx = NULL; - khm_krb5_list_tickets(&ctx); + khm_krb5_list_tickets(&ctx); - if(ctx != NULL) - pkrb5_free_context(ctx); - } - break; + if(ctx != NULL) + pkrb5_free_context(ctx); + } + break; - case KMSG_CRED_DESTROY_CREDS: - { - khui_action_context * ctx; + case KMSG_CRED_DESTROY_CREDS: + { + khui_action_context * ctx; - ctx = (khui_action_context *) vparam; + ctx = (khui_action_context *) vparam; - if (ctx->credset) - khm_krb5_destroy_by_credset(ctx->credset); - } - break; - - case KMSG_CRED_PP_BEGIN: - k5_pp_begin((khui_property_sheet *) vparam); - break; - - case KMSG_CRED_PP_END: - k5_pp_end((khui_property_sheet *) vparam); - break; - - default: - if(IS_CRED_ACQ_MSG(msg_subtype)) - return k5_msg_cred_dialog(msg_type, msg_subtype, - uparam, vparam); + if (ctx->credset) + khm_krb5_destroy_by_credset(ctx->credset); + } + break; + + case KMSG_CRED_PP_BEGIN: + k5_pp_begin((khui_property_sheet *) vparam); + break; + + case KMSG_CRED_PP_END: + k5_pp_end((khui_property_sheet *) vparam); + break; + + default: + if(IS_CRED_ACQ_MSG(msg_subtype)) + return k5_msg_cred_dialog(msg_type, msg_subtype, + uparam, vparam); } return rv; @@ -216,15 +214,15 @@ khm_int32 KHMAPI k5_msg_cred(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui_4 Runs in the context of the Krb5 plugin */ -khm_int32 KHMAPI k5_msg_callback(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui_4 uparam, void * vparam) +khm_int32 KHMAPI +k5_msg_callback(khm_int32 msg_type, khm_int32 msg_subtype, + khm_ui_4 uparam, void * vparam) { switch(msg_type) { - case KMSG_SYSTEM: - return k5_msg_system(msg_type, msg_subtype, uparam, vparam); - case KMSG_CRED: - return k5_msg_cred(msg_type, msg_subtype, uparam, vparam); - case KMSG_IDENT: - return k5_msg_ident(msg_type, msg_subtype, uparam, vparam); + case KMSG_SYSTEM: + return k5_msg_system(msg_type, msg_subtype, uparam, vparam); + case KMSG_CRED: + return k5_msg_cred(msg_type, msg_subtype, uparam, vparam); } return KHM_ERROR_SUCCESS; } diff --git a/src/windows/identity/plugins/krb5/krb5props.c b/src/windows/identity/plugins/krb5/krb5props.c index 9134de292..0d8d27276 100644 --- a/src/windows/identity/plugins/krb5/krb5props.c +++ b/src/windows/identity/plugins/krb5/krb5props.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -30,6 +30,9 @@ #include #include #include +#ifdef DEBUG +#include +#endif /* Property page @@ -42,44 +45,99 @@ INT_PTR CALLBACK krb5_pp_proc(HWND hwnd, ) { switch(uMsg) { - case WM_INITDIALOG: - { - khui_property_sheet * s; - PROPSHEETPAGE * p; - wchar_t buf[512]; - khm_size cbsize; - - p = (PROPSHEETPAGE *) lParam; - s = (khui_property_sheet *) p->lParam; + case WM_INITDIALOG: + { + khui_property_sheet * s; + PROPSHEETPAGE * p; + wchar_t buf[512]; + wchar_t unavailable[64]; + khm_size cbsize; + khm_int32 rv; + khm_int32 tflags; + + p = (PROPSHEETPAGE *) lParam; + s = (khui_property_sheet *) p->lParam; #pragma warning(push) #pragma warning(disable: 4244) - SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) s); + SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) s); #pragma warning(pop) - if(s->cred) { - cbsize = sizeof(buf); - kcdb_cred_get_name(s->cred, buf, &cbsize); - SetDlgItemText(hwnd, IDC_PPK5_NAME, buf); + LoadString(hResModule, IDS_UNAVAILABLE, + unavailable, ARRAYLENGTH(unavailable)); - cbsize = sizeof(buf); - kcdb_cred_get_attr_string(s->cred, KCDB_ATTR_ISSUE, buf, &cbsize, 0); - SetDlgItemText(hwnd, IDC_PPK5_ISSUE, buf); + if(s->cred) { + cbsize = sizeof(buf); + kcdb_cred_get_name(s->cred, buf, &cbsize); + SetDlgItemText(hwnd, IDC_PPK5_NAME, buf); - cbsize = sizeof(buf); - kcdb_cred_get_attr_string(s->cred, KCDB_ATTR_EXPIRE, buf, &cbsize, 0); + cbsize = sizeof(buf); + rv = kcdb_cred_get_attr_string(s->cred, + KCDB_ATTR_ISSUE, + buf, &cbsize, 0); + if (KHM_SUCCEEDED(rv)) + SetDlgItemText(hwnd, IDC_PPK5_ISSUE, buf); + else + SetDlgItemText(hwnd, IDC_PPK5_ISSUE, unavailable); + + cbsize = sizeof(buf); + rv = kcdb_cred_get_attr_string(s->cred, + KCDB_ATTR_EXPIRE, + buf, &cbsize, 0); + if (KHM_SUCCEEDED(rv)) SetDlgItemText(hwnd, IDC_PPK5_VALID, buf); - - cbsize = sizeof(buf); - kcdb_cred_get_attr_string(s->cred, KCDB_ATTR_RENEW_EXPIRE, buf, &cbsize, 0); + else + SetDlgItemText(hwnd, IDC_PPK5_VALID, unavailable); + + cbsize = sizeof(buf); + rv = kcdb_cred_get_attr_string(s->cred, + KCDB_ATTR_RENEW_EXPIRE, + buf, &cbsize, 0); + if (KHM_SUCCEEDED(rv)) SetDlgItemText(hwnd, IDC_PPK5_RENEW, buf); + else + SetDlgItemText(hwnd, IDC_PPK5_RENEW, unavailable); + + tflags = 0; + cbsize = sizeof(tflags); + rv = kcdb_cred_get_attr(s->cred, + attr_id_krb5_flags, + NULL, + &tflags, + &cbsize); + if (KHM_SUCCEEDED(rv)) { + +#define ADDBITFLAG(f,s) \ + if (tflags & f) { \ + LoadString(hResModule, s, buf, ARRAYLENGTH(buf)); \ + SendDlgItemMessage(hwnd, IDC_PPK5_FLAGS, LB_ADDSTRING, 0, (LPARAM) buf); \ + } + + ADDBITFLAG(TKT_FLG_FORWARDABLE, IDS_FLG_FORWARDABLE); + ADDBITFLAG(TKT_FLG_FORWARDED, IDS_FLG_FORWARDED); + ADDBITFLAG(TKT_FLG_PROXIABLE, IDS_FLG_PROXIABLE); + ADDBITFLAG(TKT_FLG_PROXY, IDS_FLG_PROXY); + ADDBITFLAG(TKT_FLG_MAY_POSTDATE, IDS_FLG_MAY_POSTDATE); + ADDBITFLAG(TKT_FLG_POSTDATED, IDS_FLG_POSTDATED); + ADDBITFLAG(TKT_FLG_INVALID, IDS_FLG_INVALID); + ADDBITFLAG(TKT_FLG_RENEWABLE, IDS_FLG_RENEWABLE); + ADDBITFLAG(TKT_FLG_INITIAL, IDS_FLG_INITIAL); + ADDBITFLAG(TKT_FLG_PRE_AUTH, IDS_FLG_PRE_AUTH); + ADDBITFLAG(TKT_FLG_HW_AUTH, IDS_FLG_HW_AUTH); + ADDBITFLAG(TKT_FLG_TRANSIT_POLICY_CHECKED, IDS_FLG_TRANSIT_POL); + ADDBITFLAG(TKT_FLG_OK_AS_DELEGATE, IDS_FLG_OK_DELEGATE); + ADDBITFLAG(TKT_FLG_ANONYMOUS, IDS_FLG_ANONYMOUS); + +#undef ADDBITFLAG - /*TODO: select other properties */ - } else { - /*TODO: select properties */ } + } else { +#ifdef DEBUG + assert(FALSE); +#endif } - return FALSE; + } + return FALSE; } return FALSE; @@ -89,14 +147,15 @@ void k5_pp_begin(khui_property_sheet * s) { PROPSHEETPAGE *p; - if(s->credtype == credtype_id_krb5) { - p = malloc(sizeof(*p)); + if(s->credtype == credtype_id_krb5 && + s->cred) { + p = PMALLOC(sizeof(*p)); ZeroMemory(p, sizeof(*p)); p->dwSize = sizeof(*p); p->dwFlags = 0; p->hInstance = hResModule; - p->pszTemplate = (s->cred)? MAKEINTRESOURCE(IDD_PP_KRB5C): MAKEINTRESOURCE(IDD_PP_KRB5); + p->pszTemplate = MAKEINTRESOURCE(IDD_PP_KRB5C); p->pfnDlgProc = krb5_pp_proc; p->lParam = (LPARAM) s; khui_ps_add_page(s, credtype_id_krb5, 0, p, NULL); @@ -110,7 +169,7 @@ void k5_pp_end(khui_property_sheet * s) khui_ps_find_page(s, credtype_id_krb5, &p); if(p) { if(p->p_page) - free(p->p_page); + PFREE(p->p_page); p->p_page = NULL; } } diff --git a/src/windows/identity/plugins/krb5/krb5util.c b/src/windows/identity/plugins/krb5/krb5util.c index b892531af..7be0f8e26 100644 --- a/src/windows/identity/plugins/krb5/krb5util.c +++ b/src/windows/identity/plugins/krb5/krb5util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -178,8 +178,8 @@ make_postfix( base_size = strlen(base) + 1; ret_size = base_size + strlen(postfix) + 1; - copy = malloc(base_size); - ret = malloc(ret_size); + copy = PMALLOC(base_size); + ret = PMALLOC(ret_size); if (!copy || !ret) goto cleanup; @@ -194,9 +194,9 @@ make_postfix( cleanup: if (!copy || !ret) { if (copy) - free(copy); + PFREE(copy); if (ret) - free(ret); + PFREE(ret); copy = ret = 0; } // INVARIANT: (ret ==> copy) && (copy ==> ret) @@ -218,7 +218,7 @@ make_temp_cache_v4( if (old_cache) { pdest_tkt(); pkrb_set_tkt_string(old_cache); - free(old_cache); + PFREE(old_cache); old_cache = 0; } @@ -230,7 +230,7 @@ make_temp_cache_v4( return KFAILURE; pkrb_set_tkt_string(tmp_cache); - free(tmp_cache); + PFREE(tmp_cache); } return 0; } @@ -259,7 +259,7 @@ make_temp_cache_v5( if (!pkrb5_cc_resolve(ctx, pkrb5_cc_default_name(ctx), &cc)) pkrb5_cc_destroy(ctx, cc); pkrb5_cc_set_default_name(ctx, old_cache); - free(old_cache); + PFREE(old_cache); old_cache = 0; } if (ctx) { @@ -291,7 +291,7 @@ make_temp_cache_v5( ctx = 0; } if (tmp_cache) - free(tmp_cache); + PFREE(tmp_cache); if (pctx) *pctx = ctx; return rc; @@ -408,7 +408,7 @@ Leash_changepwd_v5(char * principal, (result_string.length ? (sizeof(": ") - 1) : 0) + result_string.length; if (len && error_str) { - *error_str = malloc(len + 1); + *error_str = PMALLOC(len + 1); if (*error_str) _snprintf(*error_str, len + 1, "%.*s%s%.*s", @@ -516,7 +516,7 @@ Leash_int_changepwd( if (v4_error_str) len += sizeof(sep) + sizeof(v4_prefix) + strlen(v4_error_str) + sizeof(sep); - error_str = malloc(len + 1); + error_str = PMALLOC(len + 1); if (error_str) { char* p = error_str; int size = len + 1; @@ -1019,27 +1019,27 @@ not_an_API_LeashFreeTicketList(TicketList** ticketList) killList = tempList; tempList = (TicketList*)tempList->next; - free(killList->theTicket); + PFREE(killList->theTicket); if (killList->tktEncType) - free(killList->tktEncType); + PFREE(killList->tktEncType); if (killList->keyEncType) - free(killList->keyEncType); + PFREE(killList->keyEncType); if (killList->addrCount) { int n; for ( n=0; naddrCount; n++) { if (killList->addrList[n]) - free(killList->addrList[n]); + PFREE(killList->addrList[n]); } } if (killList->addrList) - free(killList->addrList); + PFREE(killList->addrList); if (killList->name) - free(killList->name); + PFREE(killList->name); if (killList->inst) - free(killList->inst); + PFREE(killList->inst); if (killList->realm) - free(killList->realm); - free(killList); + PFREE(killList->realm); + PFREE(killList); } *ticketList = NULL; diff --git a/src/windows/identity/plugins/krb5/krbconfig.csv b/src/windows/identity/plugins/krb5/krbconfig.csv index c577eec3b..0059f0ab1 100644 --- a/src/windows/identity/plugins/krb5/krbconfig.csv +++ b/src/windows/identity/plugins/krb5/krbconfig.csv @@ -6,7 +6,9 @@ Krb5Cred,KC_SPACE,0,Kerberos V Credentials Provider Flags,KC_INT32,0, Parameters,KC_SPACE,0,Parameters for KrbCred CreateMissingConfig,KC_INT32,0,Create missing configuration files - MsLsaImport,KC_INT32,2,Automatically import MSLSA credentials + MsLsaImport,KC_INT32,1,Automatically import MSLSA credentials: 0-never 1-always 2-if principle matches + MsLsaList,KC_INT32,1,Include MSLSA in the credentials list + FileCCList,KC_STRING,,List of file CCaches to include in listing AutoRenewTickets,KC_INT32,1,Automatically renew expiring tickets DefaultLifetime,KC_INT32,36000,Default ticket lifetime MaxLifetime,KC_INT32,86400,Maximum lifetime @@ -20,6 +22,8 @@ Krb5Cred,KC_SPACE,0,Kerberos V Credentials Provider MinRenewLifetime,KC_INT32,60,Maximum renewable lifetime LRURealms,KC_STRING,, LRUPrincipals,KC_STRING,, + LastDefaultIdent,KC_STRING,,Last known default identity + DefaultCCName,KC_STRING,,Default CC name (only per identity) PromptCache,KC_SPACE,0,Cache of prompts (only per identity) Name,KC_STRING,, Banner,KC_STRING,, diff --git a/src/windows/identity/plugins/krb5/krbcred.h b/src/windows/identity/plugins/krb5/krbcred.h index 08978f11f..7efc360a0 100644 --- a/src/windows/identity/plugins/krb5/krbcred.h +++ b/src/windows/identity/plugins/krb5/krbcred.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -51,9 +52,16 @@ #include #include +typedef enum tag_k5_lsa_import { + K5_LSAIMPORT_NEVER = 0, + K5_LSAIMPORT_ALWAYS = 1, + K5_LSAIMPORT_MATCH = 2, /* only when the principal name matches */ +} k5_lsa_import; + #define TYPENAME_ENCTYPE L"EncType" #define TYPENAME_ADDR_LIST L"AddrList" #define TYPENAME_KRB5_FLAGS L"Krb5Flags" +#define TYPENAME_KRB5_PRINC L"Krb5Principal" #define ATTRNAME_KEY_ENCTYPE L"KeyEncType" #define ATTRNAME_TKT_ENCTYPE L"TktEncType" @@ -75,6 +83,9 @@ extern const wchar_t * k5_facility; extern khm_int32 type_id_enctype; extern khm_int32 type_id_addr_list; extern khm_int32 type_id_krb5_flags; +extern khm_int32 type_id_krb5_princ; + +extern BOOL type_regd_krb5_princ; extern khm_int32 attr_id_key_enctype; extern khm_int32 attr_id_tkt_enctype; @@ -89,9 +100,23 @@ extern khm_int32 attr_id_krb5_ccname; /* plugin constants */ #define KRB5_PLUGIN_NAME L"Krb5Cred" +#define KRB5_IDENTPRO_NAME L"Krb5Ident" #define KRB5_CREDTYPE_NAME L"Krb5Cred" +/* limits */ +/* maximum number of characters in a realm name */ +#define K5_MAXCCH_REALM 256 + +/* maximum number of characters in a host name */ +#define K5_MAXCCH_HOST 128 + +/* maximum number of KDC's per realm */ +#define K5_MAX_KDC 64 + +/* maximum number of domains that map to a realm */ +#define K5_MAX_DOMAIN_MAPPINGS 32 + extern khm_handle csp_plugins; extern khm_handle csp_krbcred; extern khm_handle csp_params; @@ -113,6 +138,7 @@ extern BOOL is_k5_identpro; /* plugin callbacks */ khm_int32 KHMAPI k5_msg_callback(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui_4 uparam, void * vparam); +khm_int32 KHMAPI k5_ident_callback(khm_int32 msg_type, khm_int32 msg_subtype, khm_ui_4 uparam, void * vparam); /* kinit fiber */ typedef struct _fiber_job_t { @@ -179,4 +205,22 @@ k5_register_config_panels(void); void k5_unregister_config_panels(void); +INT_PTR CALLBACK +k5_ccconfig_dlgproc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); + +INT_PTR CALLBACK +k5_id_tab_dlgproc(HWND hwndDlg, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); + +INT_PTR CALLBACK +k5_ids_tab_dlgproc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam); + #endif diff --git a/src/windows/identity/plugins/krb5/lang/en_us/langres.rc b/src/windows/identity/plugins/krb5/lang/en_us/langres.rc index 087b93e47..d95c58d86 100644 --- a/src/windows/identity/plugins/krb5/lang/en_us/langres.rc +++ b/src/windows/identity/plugins/krb5/lang/en_us/langres.rc @@ -83,22 +83,14 @@ BEGIN LTEXT "Name",IDC_STATIC,7,7,19,8 LTEXT "Valid till",IDC_STATIC,7,39,24,8 LTEXT "Renewable till",IDC_STATIC,7,55,45,12 - CONTROL "Renewable",IDC_PPK5_CRENEW,"Button",BS_AUTOCHECKBOX | - WS_DISABLED | WS_TABSTOP,31,125,51,10 - CONTROL "Forwardable",IDC_PPK5_CFORWARD,"Button",BS_AUTOCHECKBOX | - WS_DISABLED | WS_TABSTOP,91,125,56,10 - CONTROL "Proxiable",IDC_PPK5_CPROXY,"Button",BS_AUTOCHECKBOX | - WS_DISABLED | WS_TABSTOP,156,125,45,10 LTEXT "Issued on",IDC_STATIC,7,23,32,8 - GROUPBOX "Ticket flags",IDC_STATIC,7,108,221,41 - LTEXT "Static",IDC_PPK5_NAME,72,7,156,12,NOT WS_GROUP, - WS_EX_CLIENTEDGE - LTEXT "Static",IDC_PPK5_ISSUE,72,23,156,12,NOT WS_GROUP, - WS_EX_CLIENTEDGE - LTEXT "Static",IDC_PPK5_VALID,72,39,156,12,NOT WS_GROUP, - WS_EX_CLIENTEDGE - LTEXT "Static",IDC_PPK5_RENEW,72,55,156,12,NOT WS_GROUP, - WS_EX_CLIENTEDGE + LTEXT "Ticket flags",IDC_STATIC,7,75,37,8 + EDITTEXT IDC_PPK5_NAME,72,7,156,12,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_PPK5_ISSUE,72,23,156,12,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_PPK5_VALID,72,39,156,12,ES_AUTOHSCROLL | ES_READONLY + EDITTEXT IDC_PPK5_RENEW,72,55,156,12,ES_AUTOHSCROLL | ES_READONLY + LISTBOX IDC_PPK5_FLAGS,72,74,156,75,LBS_SORT | + LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP END IDD_PP_KRB5 DIALOGEX 0, 0, 235, 156 @@ -137,14 +129,15 @@ BEGIN LTEXT "Default Realm",IDC_CFG_LBL_REALM,13,9,46,8 COMBOBOX IDC_CFG_DEFREALM,76,7,166,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure Realms ...",IDC_CFG_CFGREALMS,76,25,84,14 + PUSHBUTTON "Configure Realms ...",IDC_CFG_CFGREALMS,76,25,84,14, + WS_DISABLED GROUPBOX "Keberos Configuration File",IDC_CFG_CFGFILEGRP,7,57,241, 48 LTEXT "Location",IDC_CFG_LBL_CFGFILE,13,71,28,8 EDITTEXT IDC_CFG_CFGFILE,76,68,119,14,ES_AUTOHSCROLL PUSHBUTTON "Browse...",IDC_CFG_BROWSE,198,68,44,14 CONTROL "Create file if missing",IDC_CFG_CREATECONFIG,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,76,89,80,10 + BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,76,89,80,10 GROUPBOX "Windows® Options",IDC_CFG_WINGRP,7,110,241,65 LTEXT "Hostname",IDC_CFG_LBL_HOSTNAME,13,123,33,8 EDITTEXT IDC_CFG_HOSTNAME,76,120,166,14,ES_AUTOHSCROLL | @@ -153,7 +146,7 @@ BEGIN EDITTEXT IDC_CFG_DOMAIN,76,138,166,14,ES_AUTOHSCROLL | ES_READONLY LTEXT "Import tickets",IDC_LBL_IMPORT,13,158,45,8 - COMBOBOX IDC_CFG_IMPORT,76,156,166,30,CBS_DROPDOWNLIST | CBS_SORT | + COMBOBOX IDC_CFG_IMPORT,76,156,166,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END @@ -162,15 +155,17 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - CONTROL "",IDC_CFG_REALMS,"SysListView32",LVS_ALIGNLEFT | - WS_BORDER | WS_TABSTOP,7,19,81,148 - GROUPBOX "Servers",IDC_CFG_SERVERSGRP,93,7,155,91 - GROUPBOX "Domain/Hostname mappings",IDC_CFG_DOMAINGRP,93,101,155, - 74 - CONTROL "",IDC_LIST3,"SysListView32",LVS_ALIGNLEFT | WS_BORDER | - WS_TABSTOP,99,19,143,72 - CONTROL "",IDC_LIST4,"SysListView32",LVS_ALIGNLEFT | WS_BORDER | - WS_TABSTOP,99,111,143,56 + CONTROL "",IDC_CFG_REALMS,"SysListView32",LVS_REPORT | + LVS_SHOWSELALWAYS | LVS_SORTASCENDING | LVS_EDITLABELS | + LVS_ALIGNLEFT | LVS_NOCOLUMNHEADER | WS_TABSTOP,7,19,81, + 148 + GROUPBOX "Kerberos Servers",IDC_CFG_SERVERSGRP,93,7,155,91 + GROUPBOX "Domain mappings",IDC_CFG_DOMAINGRP,93,101,155,74 + CONTROL "",IDC_CFG_KDC,"SysListView32",LVS_REPORT | + LVS_EDITLABELS | LVS_ALIGNLEFT | WS_TABSTOP,99,19,143,72 + CONTROL "",IDC_CFG_DMAP,"SysListView32",LVS_REPORT | + LVS_EDITLABELS | LVS_ALIGNLEFT | WS_TABSTOP,99,111,143, + 56 END IDD_CFG_IDS_TAB DIALOGEX 0, 0, 235, 151 @@ -197,6 +192,7 @@ END IDD_CFG_ID_TAB DIALOGEX 0, 0, 235, 151 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Ticket lifetime",IDC_CFG_LBL_DEFLIFE,7,10,44,8 @@ -222,6 +218,25 @@ BEGIN 43,112,16,BS_NOTIFY | WS_DISABLED END +IDD_CFG_CACHES DIALOGEX 0, 0, 255, 182 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + GROUPBOX "File Caches",IDC_CFG_FCGRP,7,38,241,137 + CONTROL "",IDC_CFG_FCLIST,"SysListView32",LVS_REPORT | + LVS_SORTASCENDING | LVS_ALIGNLEFT | WS_BORDER | + WS_TABSTOP,13,48,229,86 + EDITTEXT IDC_CFG_FCNAME,13,139,173,14,ES_AUTOHSCROLL + PUSHBUTTON "&Browse ...",IDC_CFG_BROWSE,192,139,50,14 + PUSHBUTTON "Add",IDC_CFG_ADD,13,156,50,14 + PUSHBUTTON "Remove Selected",IDC_CFG_REMOVE,88,156,80,14 + CHECKBOX "Include all API: credentials caches",IDC_CFG_INCAPI,13, + 7,125,10 + CONTROL "Include Windows LSA cache (MSLSA:)",IDC_CFG_INCMSLSA, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,22,136,10 +END + ///////////////////////////////////////////////////////////////////////////// // @@ -306,10 +321,34 @@ BEGIN TOPMARGIN, 7 BOTTOMMARGIN, 159 END + + IDD_CFG_CACHES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 248 + VERTGUIDE, 7 + VERTGUIDE, 13 + VERTGUIDE, 242 + TOPMARGIN, 7 + BOTTOMMARGIN, 175 + END END #endif // APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_PLUGIN ICON "..\\..\\images\\krb5plugin.ico" +IDI_DELETED ICON "..\\..\\images\\deleted.ico" +IDI_NEW ICON "..\\..\\images\\new.ico" +IDI_NORMAL ICON "..\\..\\images\\normal.ico" +IDI_MODIFIED ICON "..\\..\\images\\modified.ico" + ///////////////////////////////////////////////////////////////////////////// // // String Table @@ -386,7 +425,61 @@ BEGIN IDS_NC_PWD_NPWD_AGAIN "New Password again" IDS_KRB5_CREDTEXT_P0 "

Krb5: Changing password for %s

" IDS_K5CFG_IMPORT_OPTIONS - "Never\000Always\000Only when the principal name matches\000 \000" + "Never\000Always\000Only when the principal name matches\000 " + IDS_IDENTPRO_DESC "Kerberos 5 Identity Provider" + IDS_K5CCC_SHORT_DESC "Credentials Caches" +END + +STRINGTABLE +BEGIN + IDS_K5CCC_LONG_DESC "Kerberos 5 Credentials Caches" + IDS_CFG_FCTITLE "File based Credential Caches" + IDS_CFG_FCN_WARNING "Warning:" + IDS_CFG_FCN_W_NOTFOUND "The credentials cache you specified does not exist." + IDS_CFG_FCN_W_RELATIVE "The path you specified not an absolute path." + IDS_CFG_FCOPENTITLE "Select a credential cache to add" + IDS_UNAVAILABLE "(Not available)" + IDS_FLG_FORWARDABLE "Forwardable" + IDS_FLG_FORWARDED "Forwarded" + IDS_FLG_PROXIABLE "Proxiable" + IDS_FLG_PROXY "Proxy" + IDS_FLG_MAY_POSTDATE "May postdate" + IDS_FLG_POSTDATED "Postdated" + IDS_FLG_INVALID "Invalid" + IDS_FLG_RENEWABLE "Renewable" + IDS_FLG_INITIAL "Initial" +END + +STRINGTABLE +BEGIN + IDS_FLG_PRE_AUTH "Pre-authenticated" + IDS_FLG_HW_AUTH "Hardware authentication" + IDS_FLG_TRANSIT_POL "Transit policy checked" + IDS_FLG_OK_DELEGATE "Approved for delegation" + IDS_FLG_ANONYMOUS "Anonymous" + IDS_K5ERR_CANTWRITEPROFILE + "The Kerberos 5 profile file could not be written" + IDS_K5ERR_PROFNOWRITE "The file %s could not be opened as a profile file for writing." + IDS_K5ERR_PROFUSETEMP "The file %s could not be opened for writing. The current changes will be saved to %s temporarily." + IDS_K5ERR_PROFSUGGEST "This may be due to not having privileges to modify the configuration file. Please contact your system administrator to resolve the issue." + IDS_CFG_RE_REALMS "Kerberos Realms" + IDS_CFG_RE_KDCS "Kerberos Servers" + IDS_CFG_RE_DMAPS "Domain mappings" + IDS_CFG_RE_KDCS_R "Kerberos Servers for %s" + IDS_CFG_RE_DMAPS_R "Domains that map to %s" + IDS_CFG_RE_HEAD_SVR "Server" + IDS_CFG_RE_HEAD_ADMIN "Admin" +END + +STRINGTABLE +BEGIN + IDS_CFG_RE_HEAD_MASTER "Master" + IDS_CFG_RE_HEAD_DOMAIN "Domain" + IDS_CFG_RE_NEWREALM "" + IDS_YES "Yes" + IDS_NO "No" + IDS_CFG_RE_NEWSERVER "" + IDS_CFG_RE_NEWDMAP "" END #endif // English (U.S.) resources diff --git a/src/windows/identity/plugins/krb5/langres.h b/src/windows/identity/plugins/krb5/langres.h index 87f74f547..52adc34e3 100644 --- a/src/windows/identity/plugins/krb5/langres.h +++ b/src/windows/identity/plugins/krb5/langres.h @@ -1,6 +1,6 @@ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. -// Used by D:\work\khimaira\src\plugins\krb5\lang\en_us\langres.rc +// Used by D:\work\pismere\athena\auth\krb5\src\windows\identity\plugins\krb5\lang\en_us\langres.rc // #define IDS_UNK_ADDR_FMT 101 #define IDD_NC_KRB5 102 @@ -21,11 +21,17 @@ #define IDS_ETYPE_NULL 110 #define IDD_NC_KRB5_PASSWORD 110 #define IDS_ETYPE_DES_CBC_CRC 111 +#define IDD_CFG_CACHES 111 #define IDS_ETYPE_DES_CBC_MD4 112 +#define IDI_PLUGIN 112 #define IDS_ETYPE_DES_CBC_MD5 113 +#define IDI_DELETED 113 #define IDS_ETYPE_DES_CBC_RAW 114 +#define IDI_NEW 114 #define IDS_ETYPE_DES3_CBC_SHA 115 +#define IDI_NORMAL 115 #define IDS_ETYPE_DES3_CBC_RAW 116 +#define IDI_MODIFIED 116 #define IDS_ETYPE_DES_HMAC_SHA1 117 #define IDS_ETYPE_DES3_CBC_SHA1 118 #define IDS_ETYPE_AES128_CTS_HMAC_SHA1_96 119 @@ -67,6 +73,47 @@ #define IDS_NC_PWD_NPWD_AGAIN 155 #define IDS_KRB5_CREDTEXT_P0 156 #define IDS_K5CFG_IMPORT_OPTIONS 157 +#define IDS_IDENTPRO_DESC 158 +#define IDS_K5CCC_SHORT_DESC 159 +#define IDS_K5CCC_LONG_DESC 160 +#define IDS_CFG_FCTITLE 161 +#define IDS_CFG_FCN_WARNING 162 +#define IDS_CFG_FCN_W_NOTFOUND 163 +#define IDS_CFG_FCN_W_RELATIVE 164 +#define IDS_CFG_FCOPENTITLE 165 +#define IDS_UNAVAILABLE 166 +#define IDS_FLG_FORWARDABLE 167 +#define IDS_FLG_FORWARDED 168 +#define IDS_FLG_PROXIABLE 169 +#define IDS_FLG_PROXY 170 +#define IDS_FLG_MAY_POSTDATE 171 +#define IDS_FLG_POSTDATED 172 +#define IDS_FLG_INVALID 173 +#define IDS_FLG_RENEWABLE 174 +#define IDS_FLG_INITIAL 175 +#define IDS_FLG_PRE_AUTH 176 +#define IDS_FLG_HW_AUTH 177 +#define IDS_FLG_TRANSIT_POL 178 +#define IDS_FLG_OK_DELEGATE 179 +#define IDS_FLG_ANONYMOUS 180 +#define IDS_K5ERR_CANTWRITEPROFILE 181 +#define IDS_K5ERR_PROFNOWRITE 182 +#define IDS_K5ERR_PROFUSETEMP 183 +#define IDS_K5ERR_PROFSUGGEST 184 +#define IDS_CFG_RE_REALMS 185 +#define IDS_CFG_RE_KDCS 186 +#define IDS_CFG_RE_DMAPS 187 +#define IDS_CFG_RE_KDCS_R 188 +#define IDS_CFG_RE_DMAPS_R 189 +#define IDS_CFG_RE_HEAD_SVR 190 +#define IDS_CFG_RE_HEAD_ADMIN 191 +#define IDS_CFG_RE_HEAD_MASTER 192 +#define IDS_CFG_RE_HEAD_DOMAIN 193 +#define IDS_CFG_RE_NEWREALM 194 +#define IDS_YES 195 +#define IDS_NO 196 +#define IDS_CFG_RE_NEWSERVER 197 +#define IDS_CFG_RE_NEWDMAP 198 #define IDC_NCK5_RENEWABLE 1002 #define IDC_NCK5_FORWARDABLE 1004 #define IDC_NCK5_REALM 1005 @@ -103,7 +150,9 @@ #define IDC_CFG_DOMAINGRP 1045 #define IDC_CFG_SERVERSGRP 1046 #define IDC_LIST3 1047 +#define IDC_CFG_KDC 1047 #define IDC_LIST4 1048 +#define IDC_CFG_DMAP 1048 #define IDC_CFG_LBL_DEFLIFE 1049 #define IDC_CFG_DEFLIFE 1050 #define IDC_CFG_LBL_DEFRLIFE 1051 @@ -114,14 +163,22 @@ #define IDC_CFG_RLRNG_MIN 1056 #define IDC_CFG_RLRNG_MAX 1057 #define IDC_CFG_CCACHE 1058 +#define IDC_CFG_FCGRP 1059 +#define IDC_CFG_FCLIST 1060 +#define IDC_CFG_FCNAME 1062 +#define IDC_CFG_ADD 1064 +#define IDC_CFG_REMOVE 1065 +#define IDC_CFG_INCAPI 1066 +#define IDC_CFG_INCMSLSA 1067 +#define IDC_PPK5_FLAGS 1072 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 111 +#define _APS_NEXT_RESOURCE_VALUE 117 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1059 +#define _APS_NEXT_CONTROL_VALUE 1073 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/src/windows/identity/plugins/krb5/version.rc b/src/windows/identity/plugins/krb5/version.rc new file mode 100644 index 000000000..10b16dd29 --- /dev/null +++ b/src/windows/identity/plugins/krb5/version.rc @@ -0,0 +1,64 @@ +/* Copyright (c) 2004 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +/* $Id$ */ + +#include + +1 VERSIONINFO + FILEVERSION KH_VERSION_LIST + PRODUCTVERSION KH_VERSION_LIST + FILEFLAGSMASK KH_VER_FILEFLAGMASK + FILEFLAGS KH_VER_FILEFLAGS + FILEOS KH_VER_FILEOS + FILETYPE KH_VER_FILETYPEDLL + FILESUBTYPE 0 + { + BLOCK "StringFileInfo" + { + BLOCK "040904b0" + { + VALUE "CompanyName", KH_VERSTR_COMPANY_1033 + VALUE "FileDescription", "Kerberos 5 plugin for NetIDMgr" + VALUE "FileVersion", KH_VERSTR_VERSION_1033 + VALUE "InternalName", "krb5cred" + VALUE "LegalCopyright", KH_VERSTR_COPYRIGHT_1033 + VALUE "OriginalFilename", "krb5cred.dll" + VALUE "ProductName", "NetIDMgr" + VALUE "ProductVersion", KH_VERSTR_PRODUCT_1033 +#ifdef KH_VERSTR_COMMENT_1033 + VALUE "Comment", KH_VERSTR_COMMENT_1033 +#endif + VALUE NIMV_MODULE, "MITKrb5" + VALUE NIMV_PLUGINS, "Krb5Cred,Krb5Ident" + VALUE NIMV_APIVER, KH_VERSION_STRINGAPI + VALUE NIMV_SUPPORT, "http://web.mit.edu/kerberos" + } + } + + BLOCK "VarFileInfo" + { + VALUE "Translation", 0x409, 0x4b0 + } + } diff --git a/src/windows/identity/ui/Makefile b/src/windows/identity/ui/Makefile index 402fc5d88..4419444a3 100644 --- a/src/windows/identity/ui/Makefile +++ b/src/windows/identity/ui/Makefile @@ -47,24 +47,32 @@ OBJFILES= \ $(OBJ)\configwnd.obj \ $(OBJ)\aboutwnd.obj \ $(OBJ)\reqdaemon.obj \ + $(OBJ)\addrchange.obj \ $(OBJ)\cfg_general_wnd.obj \ $(OBJ)\cfg_identities_wnd.obj \ $(OBJ)\cfg_notif_wnd.obj \ $(OBJ)\cfg_plugins_wnd.obj -RESFILE=$(OBJ)\khapp.res +RESFILES= \ + $(OBJ)\khapp.res \ + $(OBJ)\appver.res LIBFILES= \ $(LIBDIR)\nidmgr32.lib SDKLIBFILES= \ comctl32.lib \ - shell32.lib + shell32.lib \ + htmlhelp.lib \ + iphlpapi.lib $(OBJ)\uiconfig.c: uiconfig.csv $(CONFDIR)\csvschema.cfg $(CCSV) $** $@ -$(RESFILE): lang\en_us\khapp.rc +$(OBJ)\khapp.res: lang\en_us\khapp.rc + $(RC2RES) + +$(OBJ)\appver.res: appver.rc $(RC2RES) !if "$(KH_BUILD)"=="RETAIL" @@ -74,7 +82,7 @@ $(MANIFESTFILE): netidmgr.manifest.$(CPU).$(KH_CLVER).debug !endif $(CP) $** $@ -$(EXEFILE): $(OBJFILES) $(RESFILE) $(LIBFILES) +$(EXEFILE): $(OBJFILES) $(RESFILES) $(LIBFILES) $(EXEGUILINK) $(SDKLIBFILES) all: mkdirs $(EXEFILE) $(MANIFESTFILE) diff --git a/src/windows/identity/ui/aboutwnd.c b/src/windows/identity/ui/aboutwnd.c index 2dde601a4..4f5d38ef4 100644 --- a/src/windows/identity/ui/aboutwnd.c +++ b/src/windows/identity/ui/aboutwnd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -25,7 +25,7 @@ /* $Id$ */ #include -#include +#include #include #if DEBUG @@ -108,7 +108,11 @@ about_dlg_proc(HWND hwnd, mod.dwSize = sizeof(mod); } while(Module32Next(hsnap, &mod)); +#if (_WIN32_WINNT >= 0x501) + /* we are also setting the report style when creating + the control. this is actually optional. */ ListView_SetView(hw, LV_VIEW_DETAILS); +#endif _done_with_modules: CloseHandle(hsnap); diff --git a/src/windows/identity/ui/aboutwnd.h b/src/windows/identity/ui/aboutwnd.h index a427b7dd0..81b7e9047 100644 --- a/src/windows/identity/ui/aboutwnd.h +++ b/src/windows/identity/ui/aboutwnd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/ui/addrchange.c b/src/windows/identity/ui/addrchange.c new file mode 100644 index 000000000..8a671b3c9 --- /dev/null +++ b/src/windows/identity/ui/addrchange.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2005 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* $Id$ */ + +#include +#include + +static HANDLE evt_terminate = NULL; +static HANDLE h_thread = NULL; + +DWORD WINAPI +addr_change_thread(LPVOID dummy) { + + HANDLE h_waits[2]; + HANDLE h_notify; + + OVERLAPPED overlap; + DWORD ret; + + ZeroMemory(&overlap, sizeof(overlap)); + + h_notify = NULL; + overlap.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + do { + ret = NotifyAddrChange(&h_notify, &overlap); + + if (ret != ERROR_IO_PENDING) { + goto _end_thread; /* some error */ + } + + h_waits[0] = overlap.hEvent; + h_waits[1] = evt_terminate; + + ret = WaitForMultipleObjects(2, h_waits, FALSE, INFINITE); + + if ( ret == WAIT_OBJECT_0 ) { + kmq_post_message(KMSG_CRED, KMSG_CRED_ADDR_CHANGE, + 0, 0); + } else { + goto _end_thread; + } + } while(TRUE); + + _end_thread: + ExitThread(0); + return 0; /* unreachable */ +} + +void +khm_addr_change_notifier_init(void) { + evt_terminate = CreateEvent(NULL, FALSE, FALSE, NULL); + h_thread = CreateThread(NULL, + 64 * 4096, + addr_change_thread, + NULL, + 0, + NULL); +} + +void +khm_addr_change_notifier_exit(void) { + if (h_thread && evt_terminate) { + SetEvent(evt_terminate); + WaitForSingleObject(h_thread, INFINITE); + + CloseHandle(h_thread); + CloseHandle(evt_terminate); + } +} diff --git a/src/windows/identity/plugins/krb4/datarep.h b/src/windows/identity/ui/addrchange.h similarity index 65% rename from src/windows/identity/plugins/krb4/datarep.h rename to src/windows/identity/ui/addrchange.h index 9c7048e05..08c15041f 100644 --- a/src/windows/identity/plugins/krb4/datarep.h +++ b/src/windows/identity/ui/addrchange.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -24,14 +24,13 @@ /* $Id$ */ -#ifndef __KHIMAIRA_KRB_DATAREP_H -#define __KHIMAIRA_KRB_DATAREP_H +#ifndef __NETIDMGR_ADDRCHANGE_H +#define __NETIDMGR_ADDRCHANGE_H +void +khm_addr_change_notifier_init(void); -khm_int32 KHMAPI enctype_toString(const void * data, khm_int32 cbdata, wchar_t *destbuf, khm_int32 *pcbdestbuf, khm_int32 flags); -khm_int32 KHMAPI addr_list_toString(const void *, khm_int32, wchar_t *, khm_int32 *, khm_int32); -khm_int32 KHMAPI krb5flags_toString(const void *, khm_int32, wchar_t *, khm_int32 *, khm_int32); -khm_int32 KHMAPI renew_for_cb(khm_handle cred, khm_int32 id, void * buffer, khm_int32 * pcbsize); +void +khm_addr_change_notifier_exit(void); - -#endif \ No newline at end of file +#endif diff --git a/src/windows/identity/ui/appglobal.h b/src/windows/identity/ui/appglobal.h index 41fca2d17..d7e5667af 100644 --- a/src/windows/identity/ui/appglobal.h +++ b/src/windows/identity/ui/appglobal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/ui/appver.rc b/src/windows/identity/ui/appver.rc new file mode 100644 index 000000000..9d2dbc4eb --- /dev/null +++ b/src/windows/identity/ui/appver.rc @@ -0,0 +1,40 @@ + +#include +#include + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION KH_VERSION_LIST + PRODUCTVERSION KH_VERSION_LIST + FILEFLAGSMASK 0x17L + FILEFLAGS KH_VER_FILEFLAGS + FILEOS KH_VER_FILEOS + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", KH_VERSTR_COMPANY_1033 + VALUE "FileDescription", "Network Identity Manager" + VALUE "FileVersion", KH_VERSTR_VERSION_1033 + VALUE "InternalName", "NetIDMgr" + VALUE "LegalCopyright", KH_VERSTR_COPYRIGHT_1033 + VALUE "OriginalFilename", "netidmgr.exe" + VALUE "ProductName", "NetIDMgr" + VALUE "ProductVersion", KH_VERSTR_PRODUCT_1033 +#ifdef KH_VERSTR_COMMENT_1033 + VALUE "Comment", KH_VERSTR_COMMENT_1033 +#endif + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/src/windows/identity/ui/cfg_general_wnd.c b/src/windows/identity/ui/cfg_general_wnd.c index 37c7ba7d1..7b48975a9 100644 --- a/src/windows/identity/ui/cfg_general_wnd.c +++ b/src/windows/identity/ui/cfg_general_wnd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -81,6 +81,7 @@ static void write_params(dlg_data * dd) { cfg_data * d, * s; khm_handle csp_cw; + BOOL applied = FALSE; d = &dd->work; s = &dd->saved; @@ -93,25 +94,35 @@ write_params(dlg_data * dd) { return; } - if (!!d->auto_init != !!s->auto_init) + if (!!d->auto_init != !!s->auto_init) { khc_write_int32(csp_cw, L"AutoInit", d->auto_init); + applied = TRUE; + } - if (!!d->auto_start != !!s->auto_start) + if (!!d->auto_start != !!s->auto_start) { khc_write_int32(csp_cw, L"AutoStart", d->auto_start); + applied = TRUE; + } - if (!!d->auto_import != !!s->auto_import) + if (!!d->auto_import != !!s->auto_import) { khc_write_int32(csp_cw, L"AutoImport", d->auto_import); + applied = TRUE; + } - if (!!d->keep_running != !!s->keep_running) + if (!!d->keep_running != !!s->keep_running) { khc_write_int32(csp_cw, L"KeepRunning", d->keep_running); + applied = TRUE; + } - if (!!d->auto_detect_net != !!s->auto_detect_net) + if (!!d->auto_detect_net != !!s->auto_detect_net) { khc_write_int32(csp_cw, L"AutoDetectNet", d->auto_detect_net); + applied = TRUE; + } khc_close_space(csp_cw); khui_cfg_set_flags(dd->node, - KHUI_CNFLAG_APPLIED, + (applied) ? KHUI_CNFLAG_APPLIED : 0, KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED); *s = *d; @@ -179,7 +190,7 @@ khm_cfg_general_proc(HWND hwnd, switch(uMsg) { case WM_INITDIALOG: - d = malloc(sizeof(*d)); + d = PMALLOC(sizeof(*d)); #ifdef DEBUG assert(d != NULL); #endif diff --git a/src/windows/identity/ui/cfg_identities_wnd.c b/src/windows/identity/ui/cfg_identities_wnd.c index 1cef2d7ce..8b27c3334 100644 --- a/src/windows/identity/ui/cfg_identities_wnd.c +++ b/src/windows/identity/ui/cfg_identities_wnd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -46,6 +46,7 @@ static void add_subpanels(HWND hwnd, khui_config_node ctx_node, khui_config_node ref_node) { + HWND hw_tab; HWND hw_target; khui_config_node sub; @@ -315,6 +316,7 @@ typedef struct tag_idents_data { int idx_deleted; HWND hwnd; + khui_config_init_data cfg; } idents_data; static idents_data cfg_idents = {FALSE, NULL, 0, 0, 0, NULL }; @@ -411,14 +413,9 @@ write_params_ident(ident_data * d) { khc_write_int32(csp_ident, L"AllowAutoRenew", !!d->work.auto_renew); if (d->saved.sticky != d->work.sticky) { - khc_write_int32(csp_ident, L"Sticky", !!d->work.sticky); - if (d->work.sticky) { - kcdb_identity_set_flags(d->ident, KCDB_IDENT_FLAG_STICKY); - } else { - kcdb_identity_set_flags(d->ident, - KCDB_IDENT_FLAG_STICKY | - KCDB_IDENT_FLAG_INVERT); - } + kcdb_identity_set_flags(d->ident, + (d->work.sticky)?KCDB_IDENT_FLAG_STICKY:0, + KCDB_IDENT_FLAG_STICKY); } khc_close_space(csp_ident); @@ -476,8 +473,8 @@ init_idents_data(void) { break; if (widnames) - free(widnames); - widnames = malloc(cb); + PFREE(widnames); + widnames = PMALLOC(cb); #ifdef DEBUG assert(widnames); #endif @@ -497,7 +494,7 @@ init_idents_data(void) { goto _cleanup; } - cfg_idents.idents = malloc(sizeof(*cfg_idents.idents) * + cfg_idents.idents = PMALLOC(sizeof(*cfg_idents.idents) * cfg_idents.n_idents); #ifdef DEBUG assert(cfg_idents.idents); @@ -518,7 +515,7 @@ init_idents_data(void) { StringCbLength(t, KCDB_IDENT_MAXCB_NAME, &cb); cb += sizeof(wchar_t); - cfg_idents.idents[i].idname = malloc(cb); + cfg_idents.idents[i].idname = PMALLOC(cb); #ifdef DEBUG assert(cfg_idents.idents[i].idname); #endif @@ -540,7 +537,7 @@ init_idents_data(void) { cfg_idents.valid = TRUE; if (widnames) - free(widnames); + PFREE(widnames); } static void @@ -554,11 +551,11 @@ free_idents_data(void) { if (cfg_idents.idents[i].ident) kcdb_identity_release(cfg_idents.idents[i].ident); if (cfg_idents.idents[i].idname) - free(cfg_idents.idents[i].idname); + PFREE(cfg_idents.idents[i].idname); } if (cfg_idents.idents) - free(cfg_idents.idents); + PFREE(cfg_idents.idents); cfg_idents.idents = NULL; cfg_idents.n_idents = 0; @@ -658,8 +655,14 @@ refresh_view_idents_sel(HWND hwnd) { BST_INDETERMINATE)); if (sel_count > 0) { + EnableWindow(GetDlgItem(hwnd, IDC_CFG_MONITOR), TRUE); + EnableWindow(GetDlgItem(hwnd, IDC_CFG_RENEW), TRUE); + EnableWindow(GetDlgItem(hwnd, IDC_CFG_STICKY), TRUE); EnableWindow(GetDlgItem(hwnd, IDC_CFG_REMOVE), TRUE); } else { + EnableWindow(GetDlgItem(hwnd, IDC_CFG_MONITOR), FALSE); + EnableWindow(GetDlgItem(hwnd, IDC_CFG_RENEW), FALSE); + EnableWindow(GetDlgItem(hwnd, IDC_CFG_STICKY), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_CFG_REMOVE), FALSE); } } @@ -781,19 +784,14 @@ refresh_view_idents_state(HWND hwnd) { { khm_int32 flags = 0; - khui_config_node node = NULL; if (modified) flags |= KHUI_CNFLAG_MODIFIED; if (applied) flags |= KHUI_CNFLAG_APPLIED; - khui_cfg_open(NULL, L"KhmIdentities", &node); -#ifdef DEBUG - assert(node); -#endif - khui_cfg_set_flags(node, flags, - KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED); + khui_cfg_set_flags_inst(&cfg_idents.cfg, flags, + KHUI_CNFLAG_APPLIED | KHUI_CNFLAG_MODIFIED); } } @@ -853,6 +851,7 @@ khm_cfg_ids_tab_proc(HWND hwnd, hold_idents_data(); cfg_idents.hwnd = hwnd; + cfg_idents.cfg = *((khui_config_init_data *) lParam); /* first add the column */ hw = GetDlgItem(hwnd, IDC_CFG_IDENTS); @@ -875,12 +874,17 @@ khm_cfg_ids_tab_proc(HWND hwnd, if (cfg_idents.hi_status) goto _done_with_icons; - cfg_idents.hi_status = ImageList_Create(SM_CXICON, SM_CYICON, - ILC_COLOR8 | ILC_MASK, - 4,4); + cfg_idents.hi_status = + ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_COLOR8 | ILC_MASK, + 4,4); - hicon = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_ID), - IMAGE_ICON, SM_CXICON, SM_CYICON, LR_DEFAULTCOLOR); + hicon = + LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_ID), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); cfg_idents.idx_id = ImageList_AddIcon(cfg_idents.hi_status, hicon); @@ -888,7 +892,8 @@ khm_cfg_ids_tab_proc(HWND hwnd, DestroyIcon(hicon); hicon = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_CFG_DEFAULT), - IMAGE_ICON, SM_CXICON, SM_CYICON, LR_DEFAULTCOLOR); + IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); cfg_idents.idx_default = ImageList_AddIcon(cfg_idents.hi_status, hicon) + 1; @@ -896,7 +901,8 @@ khm_cfg_ids_tab_proc(HWND hwnd, DestroyIcon(hicon); hicon = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_CFG_MODIFIED), - IMAGE_ICON, SM_CXICON, SM_CYICON, LR_DEFAULTCOLOR); + IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); cfg_idents.idx_modified = ImageList_AddIcon(cfg_idents.hi_status, hicon) + 1; @@ -904,7 +910,8 @@ khm_cfg_ids_tab_proc(HWND hwnd, DestroyIcon(hicon); hicon = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_CFG_APPLIED), - IMAGE_ICON, SM_CXICON, SM_CYICON, LR_DEFAULTCOLOR); + IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); cfg_idents.idx_applied = ImageList_AddIcon(cfg_idents.hi_status, hicon) + 1; @@ -912,7 +919,8 @@ khm_cfg_ids_tab_proc(HWND hwnd, DestroyIcon(hicon); hicon = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_CFG_DELETED), - IMAGE_ICON, SM_CXICON, SM_CYICON, LR_DEFAULTCOLOR); + IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); cfg_idents.idx_deleted = ImageList_AddIcon(cfg_idents.hi_status, hicon) + 1; @@ -938,7 +946,9 @@ khm_cfg_ids_tab_proc(HWND hwnd, cfg_idents.idents[i].lv_idx = ListView_InsertItem(hw, &lvi); } +#if (_WIN32_WINNT >= 0x501) ListView_SetView(hw, LV_VIEW_DETAILS); +#endif } return FALSE; diff --git a/src/windows/identity/ui/cfg_notif_wnd.c b/src/windows/identity/ui/cfg_notif_wnd.c index aafa12d72..bca18012c 100644 --- a/src/windows/identity/ui/cfg_notif_wnd.c +++ b/src/windows/identity/ui/cfg_notif_wnd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -30,6 +30,8 @@ typedef struct tag_notif_data { khui_config_node node; + BOOL modified; + BOOL monitor; BOOL renew; BOOL warn1; @@ -90,6 +92,8 @@ read_params(notif_data * d) { d->tc_warn2.min = t; khc_close_space(csp_cw); + + d->modified = FALSE; } static void @@ -112,10 +116,14 @@ check_for_modification(notif_data * d) { KHUI_CNFLAG_MODIFIED, KHUI_CNFLAG_MODIFIED); + d->modified = TRUE; + } else { khui_cfg_set_flags(d->node, 0, KHUI_CNFLAG_MODIFIED); + + d->modified = FALSE; } } @@ -124,6 +132,9 @@ write_params(notif_data * d) { khm_handle csp_cw; khm_int32 rv; + if (!d->modified) + return; + rv = khc_open_space(NULL, L"CredWindow", KHM_PERM_WRITE, &csp_cw); assert(KHM_SUCCEEDED(rv)); @@ -215,7 +226,7 @@ khm_cfg_notifications_proc(HWND hwnd, case WM_INITDIALOG: { HWND hw; - d = malloc(sizeof(*d)); + d = PMALLOC(sizeof(*d)); #ifdef DEBUG assert(d != NULL); #endif @@ -286,7 +297,7 @@ khm_cfg_notifications_proc(HWND hwnd, khui_tracker_kill_controls(&d->tc_warn1); khui_tracker_kill_controls(&d->tc_warn2); - free(d); + PFREE(d); SetWindowLongPtr(hwnd, DWLP_USER, 0); diff --git a/src/windows/identity/ui/cfg_plugins_wnd.c b/src/windows/identity/ui/cfg_plugins_wnd.c index 16a344275..8bf767e8c 100644 --- a/src/windows/identity/ui/cfg_plugins_wnd.c +++ b/src/windows/identity/ui/cfg_plugins_wnd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -60,7 +60,7 @@ khm_cfg_plugins_proc(HWND hwnd, wchar_t buf[256]; - d = malloc(sizeof(*d)); + d = PMALLOC(sizeof(*d)); #ifdef DEBUG assert(d); #endif @@ -83,13 +83,13 @@ khm_cfg_plugins_proc(HWND hwnd, #ifdef DEBUG assert(d->info[i] == NULL); #endif - d->info[i] = malloc(sizeof(*(d->info[i]))); + d->info[i] = PMALLOC(sizeof(*(d->info[i]))); #ifdef DEBUG assert(d->info[i]); #endif if (KHM_FAILED(kmm_get_plugin_info_i(p, &d->info[i]->plugin))) { - free(d->info[i]); + PFREE(d->info[i]); d->info[i] = NULL; break; } @@ -120,8 +120,9 @@ khm_cfg_plugins_proc(HWND hwnd, #ifdef DEBUG assert(hw); #endif +#if (_WIN32_WINNT >= 0x501) ListView_SetView(hw, LV_VIEW_DETAILS); - +#endif ZeroMemory(&lvc, sizeof(lvc)); lvc.mask = LVCF_TEXT | LVCF_WIDTH; @@ -305,10 +306,10 @@ khm_cfg_plugins_proc(HWND hwnd, #endif kmm_release_plugin_info_i(&d->info[i]->plugin); kmm_release_module_info_i(&d->info[i]->module); - free(d->info[i]); + PFREE(d->info[i]); } - free(d); + PFREE(d); khm_set_dialog_result(hwnd, 0); } diff --git a/src/windows/identity/ui/configwnd.c b/src/windows/identity/ui/configwnd.c index 22a41eeb5..970599e85 100644 --- a/src/windows/identity/ui/configwnd.c +++ b/src/windows/identity/ui/configwnd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -145,12 +145,12 @@ cfgui_initialize_dialog(HWND hwnd) { /* create and fill the image list for the treeview */ - d->hi_status = ImageList_Create(SM_CXICON, SM_CYICON, + d->hi_status = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR8 | ILC_MASK, 4,4); hicon = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_CFG_DEFAULT), - IMAGE_ICON, SM_CXICON, SM_CYICON, LR_DEFAULTCOLOR); + IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); /* note that we can't use index 0 because that is used to indicate that there is no state image for the node */ @@ -161,14 +161,14 @@ cfgui_initialize_dialog(HWND hwnd) { DestroyIcon(hicon); hicon = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_CFG_MODIFIED), - IMAGE_ICON, SM_CXICON, SM_CYICON, LR_DEFAULTCOLOR); + IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); d->idx_modified = ImageList_AddIcon(d->hi_status, hicon); DestroyIcon(hicon); hicon = LoadImage(khm_hInstance, MAKEINTRESOURCE(IDI_CFG_APPLIED), - IMAGE_ICON, SM_CXICON, SM_CYICON, LR_DEFAULTCOLOR); + IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); d->idx_applied = ImageList_AddIcon(d->hi_status, hicon); @@ -253,6 +253,42 @@ cfgui_uninitialize_dialog(HWND hwnd) { ImageList_Destroy(d->hi_status); } +static HWND +cfgui_create_config_node_window(HWND hwnd, khui_config_node node) { + khui_config_node_reg reg; + khm_int32 rv; + HWND hw_new; + + khui_config_node parent; + + if (KHM_SUCCEEDED(khui_cfg_get_parent(node, &parent))) { + HWND hwp; + + hwp = khui_cfg_get_hwnd(parent); + + if (hwp == NULL) + cfgui_create_config_node_window(hwnd, parent); + + khui_cfg_release(parent); + } + + rv = khui_cfg_get_reg(node, ®); +#ifdef DEBUG + assert(KHM_SUCCEEDED(rv)); +#endif + hw_new = CreateDialogParam(reg.h_module, + reg.dlg_template, + hwnd, + reg.dlg_proc, + (LPARAM) node); +#ifdef DEBUG + assert(hw_new); +#endif + khui_cfg_set_hwnd(node, hw_new); + + return hw_new; +} + static void cfgui_activate_node(HWND hwnd, khui_config_node node) { @@ -273,25 +309,11 @@ cfgui_activate_node(HWND hwnd, khui_config_node node) { if (node == NULL) { hw_new = d->hw_generic_pane; } else { - khui_config_node_reg reg; - khm_int32 rv; hw_new = khui_cfg_get_hwnd(node); if (hw_new == NULL) { - rv = khui_cfg_get_reg(node, ®); -#ifdef DEBUG - assert(KHM_SUCCEEDED(rv)); -#endif - hw_new = CreateDialogParam(reg.h_module, - reg.dlg_template, - hwnd, - reg.dlg_proc, - (LPARAM) node); -#ifdef DEBUG - assert(hw_new); -#endif - khui_cfg_set_hwnd(node, hw_new); + hw_new = cfgui_create_config_node_window(hwnd, node); } } @@ -513,7 +535,7 @@ cfgui_dlgproc(HWND hwnd, khui_cfg_clear_params(); - d = malloc(sizeof(*d)); + d = PMALLOC(sizeof(*d)); ZeroMemory(d, sizeof(*d)); d->hbr_white = CreateSolidBrush(RGB(255,255,255)); @@ -682,8 +704,8 @@ void khm_refresh_config(void) { return; if (idents) - free(idents); - idents = malloc(cb); + PFREE(idents); + idents = PMALLOC(cb); #ifdef DEBUG assert(idents); #endif @@ -749,7 +771,7 @@ void khm_refresh_config(void) { khui_cfg_release(cfg_ids); if (idents) - free(idents); + PFREE(idents); } void khm_init_config(void) { diff --git a/src/windows/identity/ui/configwnd.h b/src/windows/identity/ui/configwnd.h index 64da77153..62747fcad 100644 --- a/src/windows/identity/ui/configwnd.h +++ b/src/windows/identity/ui/configwnd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/ui/credfuncs.c b/src/windows/identity/ui/credfuncs.c index b92e5d4a8..b88f3d14e 100644 --- a/src/windows/identity/ui/credfuncs.c +++ b/src/windows/identity/ui/credfuncs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -214,7 +214,10 @@ kmsg_cred_completion(kmq_message *m) khui_alert * alert; kherr_event * evt; kherr_context * ctx; - wchar_t ws_title[1024]; + 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; ctx = kherr_peek_context(); evt = kherr_get_err_event(ctx); @@ -224,10 +227,24 @@ kmsg_cred_completion(kmq_message *m) if (nc->subtype == KMSG_CRED_PASSWORD) LoadString(khm_hInstance, IDS_NC_PWD_FAILED_TITLE, - ws_title, ARRAYLENGTH(ws_title)); + ws_tfmt, ARRAYLENGTH(ws_tfmt)); + else if (nc->subtype == KMSG_CRED_RENEW_CREDS) + LoadString(khm_hInstance, IDS_NC_REN_FAILED_TITLE, + ws_tfmt, ARRAYLENGTH(ws_tfmt)); else LoadString(khm_hInstance, IDS_NC_FAILED_TITLE, - ws_title, ARRAYLENGTH(ws_title)); + ws_tfmt, ARRAYLENGTH(ws_tfmt)); + + if (nc->n_identities > 0) { + cb = sizeof(w_idname); + if (KHM_FAILED(kcdb_identity_get_name(nc->identities[0], + w_idname, &cb))) + StringCbCopy(w_idname, sizeof(w_idname), L"(?)"); + } else { + StringCbCopy(w_idname, sizeof(w_idname), L"(?)"); + } + + StringCbPrintf(ws_title, sizeof(ws_title), ws_tfmt, w_idname); khui_alert_set_title(alert, ws_title); khui_alert_set_severity(alert, evt->severity); @@ -267,8 +284,10 @@ kmsg_cred_completion(kmq_message *m) if (nc->subtype == KMSG_CRED_NEW_CREDS || nc->subtype == KMSG_CRED_PASSWORD) { + /* if (nc->subtype == KMSG_CRED_NEW_CREDS) khui_context_reset(); + */ khm_cred_end_dialog(nc->result); } @@ -300,7 +319,7 @@ kmsg_cred_completion(kmq_message *m) assert(m->vparam != NULL); #endif khui_context_release((khui_action_context *) m->vparam); - free(m->vparam); + PFREE(m->vparam); kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, 0); @@ -310,6 +329,10 @@ kmsg_cred_completion(kmq_message *m) case KMSG_CRED_IMPORT: khm_cred_process_commandline(); break; + + case KMSG_CRED_REFRESH: + kcdb_identity_refresh_all(); + break; } } @@ -342,7 +365,7 @@ void khm_cred_destroy_creds(void) { khui_action_context * pctx; - pctx = malloc(sizeof(*pctx)); + pctx = PMALLOC(sizeof(*pctx)); #ifdef DEBUG assert(pctx); #endif @@ -370,7 +393,7 @@ void khm_cred_destroy_creds(void) KHERR_WARNING); khui_context_release(pctx); - free(pctx); + PFREE(pctx); } else { _begin_task(KHERR_CF_TRANSITIVE); _report_sr0(KHERR_NONE, IDS_CTX_RENEW_CREDS); @@ -472,7 +495,7 @@ void khm_cred_change_password(wchar_t * title) if (SUCCEEDED(StringCbLength(title, KHUI_MAXCB_TITLE, &cb))) { cb += sizeof(wchar_t); - nc->window_title = malloc(cb); + nc->window_title = PMALLOC(cb); #ifdef DEBUG assert(nc->window_title); #endif @@ -487,7 +510,7 @@ void khm_cred_change_password(wchar_t * title) &cb))) { cb = (cb + 1) * sizeof(wchar_t); - nc->window_title = malloc(cb); + nc->window_title = PMALLOC(cb); #ifdef DEBUG assert(nc->window_title); #endif @@ -526,13 +549,40 @@ void khm_cred_obtain_new_creds(wchar_t * title) kcdb_identpro_get_ui_cb((void *) &nc->ident_cb); - assert(nc->ident_cb); + if (nc->ident_cb == NULL) { + wchar_t title[256]; + wchar_t msg[512]; + wchar_t suggestion[512]; + khui_alert * a; + + LoadString(khm_hInstance, IDS_ERR_TITLE_NO_IDENTPRO, + title, ARRAYLENGTH(title)); + LoadString(khm_hInstance, IDS_ERR_MSG_NO_IDENTPRO, + msg, ARRAYLENGTH(msg)); + LoadString(khm_hInstance, IDS_ERR_SUGG_NO_IDENTPRO, + suggestion, ARRAYLENGTH(suggestion)); + + khui_alert_create_simple(title, + msg, + KHERR_ERROR, + &a); + khui_alert_set_suggestion(a, suggestion); + + khui_alert_show(a); + + khui_alert_release(a); + + khui_context_release(&nc->ctx); + khui_cw_destroy_cred_blob(nc); + khm_cred_end_dialog(KHUI_NC_RESULT_CANCEL); + return; + } if (title) { if (SUCCEEDED(StringCbLength(title, KHUI_MAXCB_TITLE, &cb))) { cb += sizeof(wchar_t); - nc->window_title = malloc(cb); + nc->window_title = PMALLOC(cb); #ifdef DEBUG assert(nc->window_title); #endif @@ -547,7 +597,7 @@ void khm_cred_obtain_new_creds(wchar_t * title) &cb))) { cb = (cb + 1) * sizeof(wchar_t); - nc->window_title = malloc(cb); + nc->window_title = PMALLOC(cb); #ifdef DEBUG assert(nc->window_title); #endif @@ -566,7 +616,9 @@ void khm_cred_obtain_new_creds(wchar_t * title) _end_task(); } else { + khui_context_release(&nc->ctx); khui_cw_destroy_cred_blob(nc); + khm_cred_end_dialog(KHUI_NC_RESULT_CANCEL); } } @@ -825,3 +877,94 @@ khm_cred_begin_commandline(void) { khm_cred_process_commandline(); } + +void +khm_cred_refresh(void) { + kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, NULL); +} + +void +khm_cred_addr_change(void) { + khm_handle csp_cw = NULL; + khm_int32 check_net = 0; + + wchar_t * ids = NULL; + wchar_t * t; + khm_size cb; + khm_size n_idents; + + __int64 ft_now; + __int64 ft_exp; + __int64 ft_issue; + + if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow", + 0, &csp_cw))) { + khc_read_int32(csp_cw, L"AutoDetectNet", &check_net); + + khc_close_space(csp_cw); + } + + if (!check_net) + return; + + while(TRUE) { + if (ids) + PFREE(ids); + ids = NULL; + + if (kcdb_identity_enum(KCDB_IDENT_FLAG_VALID | + KCDB_IDENT_FLAG_RENEWABLE, + KCDB_IDENT_FLAG_VALID | + KCDB_IDENT_FLAG_RENEWABLE, + NULL, + &cb, + &n_idents) != KHM_ERROR_TOO_LONG) + break; + + ids = PMALLOC(cb); + + if (KHM_SUCCEEDED + (kcdb_identity_enum(KCDB_IDENT_FLAG_VALID | + KCDB_IDENT_FLAG_RENEWABLE, + KCDB_IDENT_FLAG_VALID | + KCDB_IDENT_FLAG_RENEWABLE, + ids, + &cb, + &n_idents))) + break; + } + + if (!ids) + return; + + GetSystemTimeAsFileTime((LPFILETIME) &ft_now); + + for (t=ids; t && *t; t = multi_string_next(t)) { + khm_handle ident; + + + if (KHM_FAILED + (kcdb_identity_create(t, 0, &ident))) + continue; + + cb = sizeof(ft_issue); + + if (KHM_SUCCEEDED + (kcdb_identity_get_attr(ident, KCDB_ATTR_ISSUE, NULL, + &ft_issue, &cb)) && + + (cb = sizeof(ft_exp)) && + KHM_SUCCEEDED + (kcdb_identity_get_attr(ident, KCDB_ATTR_EXPIRE, NULL, + &ft_exp, &cb)) && + + ft_now > (ft_issue + ft_exp)/2 && + ft_now < ft_exp) { + + khm_cred_renew_identity(ident); + + } + + kcdb_identity_release(ident); + } +} diff --git a/src/windows/identity/ui/credfuncs.h b/src/windows/identity/ui/credfuncs.h index b25b6630e..633783098 100644 --- a/src/windows/identity/ui/credfuncs.h +++ b/src/windows/identity/ui/credfuncs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -69,4 +69,10 @@ khm_cred_begin_commandline(void); void khm_cred_process_commandline(void); +void +khm_cred_refresh(void); + +void +khm_cred_addr_change(void); + #endif diff --git a/src/windows/identity/ui/credwnd.c b/src/windows/identity/ui/credwnd.c index 784a7f90b..be7610497 100644 --- a/src/windows/identity/ui/credwnd.c +++ b/src/windows/identity/ui/credwnd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -60,6 +60,7 @@ cw_load_view(khui_credwnd_tbl * tbl, wchar_t * view, HWND hwnd) { if(KHM_FAILED(khc_open_space(NULL, L"CredWindow", KHM_PERM_READ, &hc_cw))) return; + if(KHM_FAILED(khc_open_space(hc_cw, L"Views", KHM_PERM_READ, &hc_vs))) goto _exit; @@ -80,14 +81,15 @@ cw_load_view(khui_credwnd_tbl * tbl, wchar_t * view, HWND hwnd) { if(khc_read_multi_string(hc_v, L"ColumnList", NULL, &cbsize) != KHM_ERROR_TOO_LONG) goto _exit; - clist = malloc(cbsize); + /* temporary */ + clist = PMALLOC(cbsize); if(KHM_FAILED(khc_read_multi_string(hc_v, L"ColumnList", clist, &cbsize))) goto _exit; tbl->n_cols = (int) multi_string_length_n(clist); tbl->n_total_cols = UBOUNDSS(tbl->n_cols, KHUI_CW_COL_INITIAL, KHUI_CW_COL_INCREMENT); - tbl->cols = malloc(sizeof(khui_credwnd_col) * tbl->n_total_cols); + tbl->cols = PMALLOC(sizeof(khui_credwnd_col) * tbl->n_total_cols); ZeroMemory(tbl->cols, sizeof(khui_credwnd_col) * tbl->n_total_cols); iter = clist; @@ -103,7 +105,7 @@ cw_load_view(khui_credwnd_tbl * tbl, wchar_t * view, HWND hwnd) { if(kcdb_attrib_describe(attr_id, NULL, &cbsize, KCDB_TS_SHORT) != KHM_ERROR_TOO_LONG || cbsize == 0) goto _skip_col; - tbl->cols[i].title = malloc(cbsize); + tbl->cols[i].title = PMALLOC(cbsize); kcdb_attrib_describe(attr_id, tbl->cols[i].title, &cbsize, KCDB_TS_SHORT); } else { /* All current custom attributes are represented by icons, @@ -234,6 +236,7 @@ _skip_col: tbl->hb_hdr_bg_crit = CreateSolidBrush(RGB(240,133,117)); tbl->hb_hdr_bg_warn = CreateSolidBrush(RGB(251,199,77)); tbl->hb_hdr_bg_exp = CreateSolidBrush(RGB(255,144,144)); + tbl->hb_hdr_bg_def = CreateSolidBrush(RGB(186,254,184)); tbl->cr_normal = RGB(0,0,0); tbl->cr_sel = RGB(0,0,0); @@ -241,7 +244,7 @@ _skip_col: tbl->cr_hdr_normal = RGB(0,0,0); tbl->cr_hdr_sel = RGB(255,255,255); - tbl->ilist = khui_create_ilist(KHUI_SMICON_CX, KHUI_SMICON_CY-1, 16, 8, 0); + tbl->ilist = khui_create_ilist(KHUI_SMICON_CX, KHUI_SMICON_CY-1, 20, 8, 0); { HBITMAP hbm; @@ -265,6 +268,10 @@ _skip_col: ADD_BITMAP(IDB_FLAG_WARN); ADD_BITMAP(IDB_FLAG_EXPIRED); ADD_BITMAP(IDB_FLAG_CRITICAL); + ADD_BITMAP(IDB_WDG_STUCK); + ADD_BITMAP(IDB_WDG_STUCK_HI); + ADD_BITMAP(IDB_WDG_STICK); + ADD_BITMAP(IDB_WDG_STICK_HI); #undef ADD_BITMAP } @@ -285,7 +292,7 @@ _exit: if(hc_cs) khc_close_space(hc_cs); if(clist) - free(clist); + PFREE(clist); } void @@ -316,13 +323,13 @@ cw_update_creds(khui_credwnd_tbl * tbl) &delta); /* now we need to figure out how to sort the credentials */ - fields = malloc(sizeof(kcdb_cred_comp_field) * tbl->n_cols); + fields = PMALLOC(sizeof(kcdb_cred_comp_field) * tbl->n_cols); ZeroMemory(fields, sizeof(kcdb_cred_comp_field) * tbl->n_cols); for(i=0, n=0; in_cols; i++) { if((tbl->cols[i].flags & KHUI_CW_COL_SORT_INC) || - (tbl->cols[i].flags & KHUI_CW_COL_SORT_DEC) || - (tbl->cols[i].flags & KHUI_CW_COL_GROUP)) + (tbl->cols[i].flags & KHUI_CW_COL_SORT_DEC) || + (tbl->cols[i].flags & KHUI_CW_COL_GROUP)) { int si; /* we need to sort by this column */ @@ -377,15 +384,20 @@ cw_update_creds(khui_credwnd_tbl * tbl) kcdb_credset_get_size(tbl->credset, &s); for(i=0;icredset, (khm_int32) i, &hc))) + if(KHM_FAILED(kcdb_credset_get_cred(tbl->credset, + (khm_int32) i, &hc))) continue; /* lost a race */ - if(KHM_FAILED(kcdb_cred_get_attr(hc, khui_cw_flag_id, NULL, NULL, NULL))) { + if(KHM_FAILED(kcdb_cred_get_attr(hc, khui_cw_flag_id, NULL, + NULL, NULL))) { flags = 0; kcdb_cred_set_attr(hc, khui_cw_flag_id, &flags, sizeof(flags)); } kcdb_cred_release(hc); } } + + if (fields) + PFREE(fields); } void @@ -399,10 +411,14 @@ cw_del_outline(khui_credwnd_outline *o) { return; if(o->header) - free(o->header); + PFREE(o->header); if ((o->flags & KHUI_CW_O_DATAALLOC) && o->data) - free(o->data); + PFREE(o->data); + + if ((o->flags & KHUI_CW_O_STICKY) && + o->data) + kcdb_identity_release((khm_handle) o->data); LPOP(&(o->children), &c); while(c) { @@ -410,7 +426,7 @@ cw_del_outline(khui_credwnd_outline *o) { LPOP(&(o->children), &c); } - free(o); + PFREE(o); } khui_credwnd_outline * @@ -418,12 +434,12 @@ cw_new_outline_node(wchar_t * heading) { khui_credwnd_outline * o; size_t cblen; - o = malloc(sizeof(khui_credwnd_outline)); + o = PMALLOC(sizeof(khui_credwnd_outline)); ZeroMemory(o, sizeof(khui_credwnd_outline)); if(SUCCEEDED(StringCbLength(heading, KHUI_MAXCB_HEADING, &cblen))) { cblen += sizeof(wchar_t); - o->header = malloc(cblen); + o->header = PMALLOC(cblen); StringCbCopy(o->header, cblen, heading); } @@ -531,9 +547,9 @@ cw_set_tbl_row_cred(khui_credwnd_tbl * tbl, khm_size newsize; newsize = UBOUNDSS(row+1,KHUI_CW_ROW_INITIAL, KHUI_CW_ROW_INCREMENT); - newrows = malloc(sizeof(khui_credwnd_row) * newsize); + newrows = PMALLOC(sizeof(khui_credwnd_row) * newsize); memcpy(newrows, tbl->rows, sizeof(khui_credwnd_row) * tbl->n_rows); - free(tbl->rows); + PFREE(tbl->rows); tbl->rows = newrows; tbl->n_total_rows = newsize; } @@ -564,9 +580,9 @@ cw_set_tbl_row_header(khui_credwnd_tbl * tbl, khm_size newsize; newsize = UBOUNDSS(row+1,KHUI_CW_ROW_INITIAL, KHUI_CW_ROW_INCREMENT); - newrows = malloc(sizeof(khui_credwnd_row) * newsize); + newrows = PMALLOC(sizeof(khui_credwnd_row) * newsize); memcpy(newrows, tbl->rows, sizeof(khui_credwnd_row) * tbl->n_rows); - free(tbl->rows); + PFREE(tbl->rows); tbl->rows = newrows; tbl->n_total_rows = newsize; } @@ -635,9 +651,8 @@ cw_update_outline(khui_credwnd_tbl * tbl) } } - /* determine the grouping order */ - grouping = malloc(sizeof(khm_int32) * tbl->n_cols); + grouping = PMALLOC(sizeof(khm_int32) * tbl->n_cols); for(i=0; i < (int) tbl->n_cols; i++) grouping[i] = -1; n_grouping = 0; @@ -664,7 +679,7 @@ cw_update_outline(khui_credwnd_tbl * tbl) /* we haven't allocated memory yet */ tbl->n_total_rows = KHUI_CW_ROW_INITIAL; tbl->n_rows = 0; - tbl->rows = malloc(sizeof(khui_credwnd_row) * tbl->n_total_rows); + tbl->rows = PMALLOC(sizeof(khui_credwnd_row) * tbl->n_total_rows); } else { /* kill any pending timers */ for(i=0; i < (int) tbl->n_rows; i++) @@ -690,7 +705,8 @@ cw_update_outline(khui_credwnd_tbl * tbl) this view, we skip it */ if(prevcred) { for(j=0; j < (int) tbl->n_cols; j++) { - if(kcdb_creds_comp_attr(prevcred, thiscred, tbl->cols[j].attr_id)) + if(kcdb_creds_comp_attr(prevcred, thiscred, + tbl->cols[j].attr_id)) break; } @@ -708,7 +724,8 @@ cw_update_outline(khui_credwnd_tbl * tbl) for(j=0; j < n_grouping; j++) { /* determine the grouping level at which thiscred differs from prevcred */ - if(kcdb_creds_comp_attr(prevcred,thiscred,tbl->cols[grouping[j]].attr_id)) + if(kcdb_creds_comp_attr(prevcred,thiscred, + tbl->cols[grouping[j]].attr_id)) break; } level = j; @@ -791,6 +808,7 @@ cw_update_outline(khui_credwnd_tbl * tbl) } else if(tbl->cols[grouping[j]].attr_id == KCDB_ATTR_TYPE_NAME) { khm_int32 t; + ol->attr_id = KCDB_ATTR_TYPE; if(KHM_SUCCEEDED(kcdb_cred_get_type(thiscred, &t))) ol->data = (void *)(ssize_t) t; @@ -823,7 +841,7 @@ cw_update_outline(khui_credwnd_tbl * tbl) if (rv != KHM_ERROR_TOO_LONG || cbbuf == 0) { ol->data = NULL; } else { - ol->data = malloc(cbbuf); + ol->data = PMALLOC(cbbuf); assert(ol->data); rv = kcdb_cred_get_attr(thiscred, alt_id, @@ -945,8 +963,8 @@ cw_update_outline(khui_credwnd_tbl * tbl) cb_names == 0) goto _cleanup_sticky; - idnames = malloc(cb_names); - idarray = malloc(n_idents * sizeof(*idarray)); + idnames = PMALLOC(cb_names); + idarray = PMALLOC(n_idents * sizeof(*idarray)); #ifdef DEBUG assert(idnames); assert(idarray); @@ -966,6 +984,12 @@ cw_update_outline(khui_credwnd_tbl * tbl) qsort(idarray, n_idents, sizeof(*idarray), iwcscmp); for (i=0; i < (int) n_idents; i++) { + khm_handle h; + + if (KHM_FAILED(kcdb_identity_create(idarray[i], + KCDB_IDENT_FLAG_CREATE, &h))) + continue; + for (o = tbl->outline; o; o = LNEXT(o)) { if (!wcscmp(idarray[i], o->header)) break; @@ -975,15 +999,23 @@ cw_update_outline(khui_credwnd_tbl * tbl) /* found it */ if (o->start != -1) /* already visible? */ continue; + o->flags &= KHUI_CW_O_STICKY; + o->flags |= KHUI_CW_O_VISIBLE; } else { /* not found. create */ o = cw_new_outline_node(idarray[i]); o->flags = KHUI_CW_O_VISIBLE; o->level = 0; o->col = grouping[0]; + o->data = (void *) h; } - o->flags |= KHUI_CW_O_STICKY; + if (o->flags & KHUI_CW_O_STICKY) + kcdb_identity_release(h); + else + /* leave identity held in this case */ + o->flags |= KHUI_CW_O_STICKY; + o->flags &= ~KHUI_CW_O_EXPAND; o->start = n_rows; o->length = 1; @@ -996,9 +1028,9 @@ cw_update_outline(khui_credwnd_tbl * tbl) _cleanup_sticky: if (idnames) - free(idnames); + PFREE(idnames); if (idarray) - free(idarray); + PFREE(idarray); } tbl->n_rows = n_rows; @@ -1007,7 +1039,7 @@ cw_update_outline(khui_credwnd_tbl * tbl) tbl->flags &= ~KHUI_CW_TBL_COL_DIRTY; _exit: if(grouping) - free(grouping); + PFREE(grouping); } void @@ -1033,6 +1065,7 @@ cw_unload_view(khui_credwnd_tbl * tbl) SafeDeleteObject(tbl->hb_hdr_bg_crit); SafeDeleteObject(tbl->hb_hdr_bg_exp); SafeDeleteObject(tbl->hb_hdr_bg_warn); + SafeDeleteObject(tbl->hb_hdr_bg_def); #undef SafeDeleteObject @@ -1049,17 +1082,17 @@ cw_unload_view(khui_credwnd_tbl * tbl) khm_size i; for(i=0; i < tbl->n_cols; i++) { if(tbl->cols[i].title) - free(tbl->cols[i].title); + PFREE(tbl->cols[i].title); Header_DeleteItem(tbl->hwnd_header, 0); } - free(tbl->cols); + PFREE(tbl->cols); tbl->cols = NULL; tbl->n_cols = 0; tbl->n_total_cols = 0; } if(tbl->rows) { - free(tbl->rows); + PFREE(tbl->rows); tbl->rows = NULL; tbl->n_rows = 0; tbl->n_total_rows = 0; @@ -1091,11 +1124,13 @@ cw_hditem_from_tbl_col(khui_credwnd_col * col, HDITEM *phi) phi->fmt = HDF_CENTER | HDF_STRING; } phi->lParam = col->attr_id; +#if (_WIN32_WINNT >= 0x501) if(col->flags & KHUI_CW_COL_SORT_INC) { phi->fmt |= HDF_SORTUP; } else if(col->flags & KHUI_CW_COL_SORT_DEC) { phi->fmt |= HDF_SORTDOWN; } +#endif if(col->width < 0) { /*TODO: come up with a better way to handle this case */ col->width = 200; @@ -1328,7 +1363,8 @@ cw_draw_header(HDC hdc, khui_credwnd_row * cr; khui_credwnd_outline * o; int selected = 0; - + khm_int32 idf = 0; + /* each header consists of a 'expose' widget and some text */ /* we need to figure out the background color first */ @@ -1337,18 +1373,26 @@ cw_draw_header(HDC hdc, colattr = tbl->cols[cr->col].attr_id; + if (colattr == KCDB_ATTR_ID_NAME) { + khm_handle ident = o->data; + + kcdb_identity_get_flags(ident, &idf); + } + selected = o->flags & KHUI_CW_O_SELECTED; { HBRUSH hbr; if(selected) hbr = tbl->hb_hdr_bg_sel; - else if((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_EXPIRED) + else if ((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_EXPIRED) hbr = tbl->hb_hdr_bg_exp; - else if((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_CRITICAL) + else if ((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_CRITICAL) hbr = tbl->hb_hdr_bg_crit; - else if((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_WARN) + else if ((o->flags & CW_EXPSTATE_MASK) == CW_EXPSTATE_WARN) hbr = tbl->hb_hdr_bg_warn; + else if (idf & KCDB_IDENT_FLAG_DEFAULT) + hbr = tbl->hb_hdr_bg_def; else hbr = tbl->hb_hdr_bg; @@ -1365,24 +1409,45 @@ cw_draw_header(HDC hdc, if (o->flags & KHUI_CW_O_STICKY) { /* khui_ilist_draw_id(tbl->ilist, IDB_TK_NEW_SM, hdc, r->left, r->bottom - KHUI_SMICON_CY, 0); */ - } else if((tbl->mouse_state & CW_MOUSE_OUTLINE) && tbl->mouse_row == row) { + } else if((tbl->mouse_state & CW_MOUSE_WOUTLINE) && + tbl->mouse_row == row) { if(o->flags & KHUI_CW_O_EXPAND) { - khui_ilist_draw_id(tbl->ilist, IDB_WDG_EXPAND_HI, hdc, r->left, r->bottom - KHUI_SMICON_CY, 0); + khui_ilist_draw_id(tbl->ilist, IDB_WDG_EXPAND_HI, + hdc, r->left, r->bottom - KHUI_SMICON_CY, 0); } else { - khui_ilist_draw_id(tbl->ilist, IDB_WDG_COLLAPSE_HI, hdc, r->left, r->bottom - KHUI_SMICON_CY, 0); + khui_ilist_draw_id(tbl->ilist, IDB_WDG_COLLAPSE_HI, + hdc, r->left, r->bottom - KHUI_SMICON_CY, 0); } } else { if(o->flags & KHUI_CW_O_EXPAND) { - khui_ilist_draw_id(tbl->ilist, IDB_WDG_EXPAND, hdc, r->left, r->bottom - KHUI_SMICON_CY, 0); + khui_ilist_draw_id(tbl->ilist, IDB_WDG_EXPAND, + hdc, r->left, r->bottom - KHUI_SMICON_CY, 0); } else { - khui_ilist_draw_id(tbl->ilist, IDB_WDG_COLLAPSE, hdc, r->left, r->bottom - KHUI_SMICON_CY, 0); + khui_ilist_draw_id(tbl->ilist, IDB_WDG_COLLAPSE, + hdc, r->left, r->bottom - KHUI_SMICON_CY, 0); } } - r->left += KHUI_SMICON_CX * 2; + r->left += KHUI_SMICON_CX * 3 / 2; /* try to draw the icon, if there is one */ if(colattr == KCDB_ATTR_ID_NAME) { + + khui_ilist_draw_id(tbl->ilist, + (((tbl->mouse_state & CW_MOUSE_WSTICKY) && + tbl->mouse_row == row)? + ((idf & KCDB_IDENT_FLAG_STICKY)? + IDB_WDG_STUCK_HI: + IDB_WDG_STICK_HI): + ((idf & KCDB_IDENT_FLAG_STICKY)? + IDB_WDG_STUCK: + IDB_WDG_STICK)), + hdc, + r->left, r->bottom - KHUI_SMICON_CY, + 0); + + r->left += KHUI_SMICON_CX * 3 / 2; + khui_ilist_draw_id(tbl->ilist, ((o->flags & KHUI_CW_O_STICKY)? IDB_ID_DIS_SM: @@ -1404,6 +1469,23 @@ cw_draw_header(HDC hdc, SetTextColor(hdc, tbl->cr_hdr_normal); TextOut(hdc, r->left, r->bottom - tbl->vpad, o->header, (int) wcslen(o->header)); + + if (colattr == KCDB_ATTR_ID_NAME && + (idf & KCDB_IDENT_FLAG_DEFAULT)) { + wchar_t defstr[64]; + SIZE size; + + LoadString(khm_hInstance, IDS_CW_DEFAULT, + defstr, ARRAYLENGTH(defstr)); + + GetTextExtentPoint32(hdc, o->header, (int) wcslen(o->header), + &size); + + r->left += size.cx + KHUI_SMICON_CX * 2; + + TextOut(hdc, r->left, r->bottom - tbl->vpad, + defstr, (int) wcslen(defstr)); + } } LRESULT @@ -1474,8 +1556,10 @@ cw_wm_create(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) khui_credwnd_tbl * tbl; kmq_subscribe_hwnd(KMSG_CRED, hwnd); + kmq_subscribe_hwnd(KMSG_KCDB, hwnd); - tbl = malloc(sizeof(*tbl)); + /* freed in cw_wm_destroy */ + tbl = PMALLOC(sizeof(*tbl)); ZeroMemory(tbl, sizeof(*tbl)); /* some versions of VC generate portability warnings for @@ -1490,7 +1574,11 @@ cw_wm_create(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) WC_HEADER, (LPWSTR) NULL, WS_CHILD | HDS_BUTTONS | - HDS_FULLDRAG | HDS_HORZ | HDS_HOTTRACK | HDS_FLAT, + HDS_FULLDRAG | HDS_HORZ | HDS_HOTTRACK +#if (_WIN32_WINNT >= 0x501) + | HDS_FLAT +#endif + , 0,0,0,0,hwnd, (HMENU) 0, khm_hInstance, NULL); cw_load_view(tbl, NULL /* default view */, hwnd); @@ -1530,12 +1618,13 @@ cw_wm_destroy(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) khui_credwnd_tbl * tbl; kmq_unsubscribe_hwnd(KMSG_CRED, hwnd); + kmq_unsubscribe_hwnd(KMSG_KCDB, hwnd); tbl = (khui_credwnd_tbl *)(LONG_PTR) GetWindowLongPtr(hwnd, 0); cw_unload_view(tbl); - free(tbl); + PFREE(tbl); return DefWindowProc(hwnd, uMsg, wParam, lParam); } @@ -1838,19 +1927,42 @@ cw_kmq_wm_dispatch(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) kmq_wm_begin(lParam, &m); if(m->type == KMSG_CRED) { - if(m->subtype == KMSG_CRED_ROOTDELTA) { + switch (m->subtype) { + case KMSG_CRED_ROOTDELTA: cw_update_creds(tbl); cw_update_outline(tbl); cw_update_extents(tbl, TRUE); InvalidateRect(hwnd, NULL, FALSE); - } else if(m->subtype == KMSG_CRED_PP_BEGIN) { + break; + + case KMSG_CRED_PP_BEGIN: cw_pp_begin((khui_property_sheet *) m->vparam); - } else if(m->subtype == KMSG_CRED_PP_PRECREATE) { + break; + + case KMSG_CRED_PP_PRECREATE: cw_pp_precreate((khui_property_sheet *) m->vparam); - } else if(m->subtype == KMSG_CRED_PP_END) { + break; + + case KMSG_CRED_PP_END: cw_pp_end((khui_property_sheet *) m->vparam); - } else if(m->subtype == KMSG_CRED_PP_DESTROY) { + break; + + case KMSG_CRED_PP_DESTROY: cw_pp_destroy((khui_property_sheet *) m->vparam); + break; + } + } else if (m->type == KMSG_KCDB) { + if (m->subtype == KMSG_KCDB_IDENT && + m->uparam == KCDB_OP_MODIFY) { + + cw_update_outline(tbl); + cw_update_extents(tbl, TRUE); + InvalidateRect(hwnd, NULL, FALSE); + } + else if (m->subtype == KMSG_KCDB_IDENT && + m->uparam == KCDB_OP_NEW_DEFAULT) { + + InvalidateRect(hwnd, NULL, FALSE); } } return kmq_wm_end(m, rv); @@ -1963,6 +2075,15 @@ cw_set_row_context(khui_credwnd_tbl * tbl, int row) khui_credwnd_outline * o; BOOL set_context = TRUE; + if (row < 0 || row >= (int) tbl->n_rows) { + if (tbl->n_rows > 0) + row = 0; + else { + khui_context_reset(); + return; + } + } + if (tbl->rows[row].flags & KHUI_CW_ROW_HEADER) { o = (khui_credwnd_outline *) tbl->rows[row].data; @@ -2077,6 +2198,28 @@ cw_set_row_context(khui_credwnd_tbl * tbl, int row) } } +static void +cw_select_all(khui_credwnd_tbl * tbl) +{ + khm_size i; + + for(i=0; in_rows; i++) { + tbl->rows[i].flags |= KHUI_CW_ROW_SELECTED; + if (!(tbl->rows[i].flags & KHUI_CW_ROW_HEADER)) + kcdb_cred_set_flags((khm_handle) tbl->rows[i].data, + KCDB_CRED_FLAG_SELECTED, + KCDB_CRED_FLAG_SELECTED); + } + + cw_select_outline_level(tbl->outline, TRUE); + + cw_update_selection_state(tbl); + + cw_set_row_context(tbl, tbl->cursor_row); + + InvalidateRect(tbl->hwnd, NULL, FALSE); +} + static void cw_select_row(khui_credwnd_tbl * tbl, int row, WPARAM wParam) { @@ -2231,11 +2374,10 @@ cw_wm_mouse(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) tbl = (khui_credwnd_tbl *)(LONG_PTR) GetWindowLongPtr(hwnd, 0); /* we are basically trying to capture events where the mouse is - hovering over one of the 'hotspots'. There are two kinds of - hotspots one is the little widget thinggy that you click on to - expand or collapse an outline. The other is a text cell that is - partially concealed. - */ + hovering over one of the 'hotspots'. There are two kinds of + hotspots one is the little widget thinggy that you click on to + expand or collapse an outline. The other is a text cell that + is partially concealed. */ x = GET_X_LPARAM(lParam); y = GET_Y_LPARAM(lParam); @@ -2246,10 +2388,10 @@ cw_wm_mouse(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) col = -1; nm_state = CW_MOUSE_NONE; nm_row = nm_col = -1; + for(i=0; i < (int) tbl->n_cols; i++) { if(x >= tbl->cols[i].x && - x < tbl->cols[i].x + tbl->cols[i].width) - { + x < tbl->cols[i].x + tbl->cols[i].width) { col = i; break; } @@ -2266,68 +2408,126 @@ cw_wm_mouse(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) /* are we on a widget then? */ x -= tbl->cols[tbl->rows[row].col].x; if(x >= 0 && x < KHUI_SMICON_CX) /* hit */ { - nm_state |= CW_MOUSE_OUTLINE; + nm_state |= CW_MOUSE_WOUTLINE | CW_MOUSE_WIDGET; + } else if (tbl->cols[tbl->rows[row].col].attr_id == + KCDB_ATTR_ID_NAME && + col == tbl->rows[row].col && + x >= KHUI_SMICON_CX * 3 / 2 && + x < KHUI_SMICON_CX * 5 / 2){ + nm_state |= CW_MOUSE_WSTICKY | CW_MOUSE_WIDGET; } } } - if((tbl->mouse_state & CW_MOUSE_LDOWN) && - (tbl->mouse_state & CW_MOUSE_OUTLINE) && - (nm_row != tbl->mouse_row)) - { - nm_state &= ~CW_MOUSE_OUTLINE; + /* did the user drag the cursor off the current row? */ + if((tbl->mouse_state & CW_MOUSE_LDOWN) && + (nm_row != tbl->mouse_row)) { + nm_state &= ~(CW_MOUSE_WIDGET | CW_MOUSE_WOUTLINE | CW_MOUSE_WSTICKY); } if(!(nm_state & CW_MOUSE_LDOWN) && - (tbl->mouse_state & CW_MOUSE_LDOWN)) { + (tbl->mouse_state & CW_MOUSE_LDOWN) && + tbl->mouse_row == nm_row) { - if((nm_state & CW_MOUSE_OUTLINE) && - (tbl->mouse_state & CW_MOUSE_OUTLINE)) { - /* click on a widget */ + if((nm_state & CW_MOUSE_WOUTLINE) && + (tbl->mouse_state & CW_MOUSE_WOUTLINE)) { + /* click on an outline widget */ khui_credwnd_outline * o; o = (khui_credwnd_outline *) tbl->rows[nm_row].data; - tbl->mouse_state = CW_MOUSE_OUTLINE; + tbl->mouse_state = CW_MOUSE_WIDGET | CW_MOUSE_WOUTLINE; cw_toggle_outline_state(tbl, o); return 0; - } else if(nm_row == tbl->mouse_row) { + } else if ((nm_state & CW_MOUSE_WSTICKY) && + (tbl->mouse_state & CW_MOUSE_WSTICKY)) { + + khui_credwnd_outline * o; + khm_handle ident; + khm_int32 idf = 0; + + o = tbl->rows[nm_row].data; + ident = o->data; + + kcdb_identity_get_flags(ident, &idf); + idf &= KCDB_IDENT_FLAG_STICKY; + kcdb_identity_set_flags(ident, (idf ^ KCDB_IDENT_FLAG_STICKY), + KCDB_IDENT_FLAG_STICKY); + + tbl->mouse_state = CW_MOUSE_WIDGET | CW_MOUSE_WSTICKY; + + return 0; + } else { /* click on a row */ cw_select_row(tbl, nm_row, wParam); } - } - /*TODO: if a user clicks somewhere and drags on to an exand widget, it activates the widet. should not */ - /* ok, now if we are changing state, we need to invalidate a few regions */ - if((tbl->mouse_state ^ nm_state) & CW_MOUSE_OUTLINE) { - if(tbl->mouse_state & CW_MOUSE_OUTLINE) { + if (((tbl->mouse_state ^ nm_state) & (CW_MOUSE_WIDGET | + CW_MOUSE_WOUTLINE | + CW_MOUSE_WSTICKY)) || + tbl->mouse_row != nm_row) { + + if(tbl->mouse_state & CW_MOUSE_WOUTLINE) { r.left = tbl->cols[tbl->mouse_col].x - tbl->scr_left; - r.top = tbl->mouse_row * tbl->cell_height + tbl->header_height - tbl->scr_top; + r.top = tbl->mouse_row * tbl->cell_height + + tbl->header_height - tbl->scr_top; + r.right = r.left + KHUI_SMICON_CX; + r.bottom = r.top + tbl->cell_height; + InvalidateRect(tbl->hwnd, &r, TRUE); + } + if(tbl->mouse_state & CW_MOUSE_WSTICKY) { + r.left = KHUI_SMICON_CX * 3 / 2 + + tbl->cols[tbl->mouse_col].x - tbl->scr_left; + r.top = tbl->mouse_row * tbl->cell_height + + tbl->header_height - tbl->scr_top; r.right = r.left + KHUI_SMICON_CX; r.bottom = r.top + tbl->cell_height; InvalidateRect(tbl->hwnd, &r, TRUE); } - tbl->mouse_col = nm_col; - tbl->mouse_row = nm_row; + if ((tbl->mouse_state & nm_state) & CW_MOUSE_LDOWN) { + if (tbl->mouse_row == nm_row) + tbl->mouse_col = nm_col; + } else { + tbl->mouse_col = nm_col; + tbl->mouse_row = nm_row; + } tbl->mouse_state = nm_state; /* same code block as above */ - if(tbl->mouse_state & CW_MOUSE_OUTLINE) { + if(tbl->mouse_state & CW_MOUSE_WOUTLINE) { r.left = tbl->cols[tbl->mouse_col].x - tbl->scr_left; - r.top = tbl->mouse_row * tbl->cell_height + tbl->header_height - tbl->scr_top; + r.top = tbl->mouse_row * tbl->cell_height + + tbl->header_height - tbl->scr_top; + r.right = r.left + KHUI_SMICON_CX; + r.bottom = r.top + tbl->cell_height; + InvalidateRect(tbl->hwnd, &r, TRUE); + } + if(tbl->mouse_state & CW_MOUSE_WSTICKY) { + r.left = KHUI_SMICON_CX * 3 / 2 + + tbl->cols[tbl->mouse_col].x - tbl->scr_left; + r.top = tbl->mouse_row * tbl->cell_height + + tbl->header_height - tbl->scr_top; r.right = r.left + KHUI_SMICON_CX; r.bottom = r.top + tbl->cell_height; InvalidateRect(tbl->hwnd, &r, TRUE); } } else if(tbl->mouse_state != nm_state) { - tbl->mouse_col = nm_col; - tbl->mouse_row = nm_row; - tbl->mouse_state = nm_state; + + if ((tbl->mouse_state & nm_state) & CW_MOUSE_LDOWN) { + if (tbl->mouse_row == nm_row) { + tbl->mouse_col = nm_col; + tbl->mouse_state = nm_state; + } + } else { + tbl->mouse_col = nm_col; + tbl->mouse_row = nm_row; + tbl->mouse_state = nm_state; + } } /* if it was a double click, also show the property @@ -2553,13 +2753,13 @@ static INT_PTR CALLBACK cw_pp_ident_proc(HWND hwnd, UINT uMsg, WPARAM wParam, - LPARAM lParam - ) + LPARAM lParam) { + khui_property_sheet * s; + switch(uMsg) { case WM_INITDIALOG: { - khui_property_sheet * s; PROPSHEETPAGE * p; khm_handle ident; wchar_t idname[KCDB_IDENT_MAXCCH_NAME]; @@ -2582,23 +2782,108 @@ cw_pp_ident_proc(HWND hwnd, kcdb_identity_get_flags(ident, &i); - SendDlgItemMessage(hwnd, - IDC_PP_IDDEF, - BM_SETCHECK, - (WPARAM) ((i & KCDB_IDENT_FLAG_DEFAULT)?BST_CHECKED:BST_UNCHECKED), - 0); + CheckDlgButton(hwnd, IDC_PP_IDDEF, + ((i & KCDB_IDENT_FLAG_DEFAULT)?BST_CHECKED: + BST_UNCHECKED)); + + /* if it's default, you can't change it further */ + if (i & KCDB_IDENT_FLAG_DEFAULT) { + EnableWindow(GetDlgItem(hwnd, IDC_PP_IDDEF), FALSE); + } + + CheckDlgButton(hwnd, IDC_PP_IDSEARCH, + ((i & KCDB_IDENT_FLAG_SEARCHABLE)?BST_CHECKED: + BST_UNCHECKED)); - SendDlgItemMessage( - hwnd, - IDC_PP_IDSEARCH, - BM_SETCHECK, - (WPARAM) ((i & KCDB_IDENT_FLAG_SEARCHABLE)?BST_CHECKED:BST_UNCHECKED), - 0); + CheckDlgButton(hwnd, IDC_PP_STICKY, + ((i & KCDB_IDENT_FLAG_STICKY)?BST_CHECKED: + BST_UNCHECKED)); khui_property_wnd_set_record(GetDlgItem(hwnd, IDC_PP_PROPLIST), ident); } return TRUE; + + case WM_COMMAND: + s = (khui_property_sheet *) (LONG_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + + switch(wParam) { + case MAKEWPARAM(IDC_PP_IDDEF, BN_CLICKED): + /* fallthrough */ + case MAKEWPARAM(IDC_PP_STICKY, BN_CLICKED): + + if (s->status != KHUI_PS_STATUS_NONE) + PropSheet_Changed(s->hwnd, hwnd); + return TRUE; + + case MAKEWPARAM(IDC_PP_CONFIG, BN_CLICKED): + { + khui_config_node cfg_ids = NULL; + khm_int32 rv; + + khm_refresh_config(); + + rv = khui_cfg_open(NULL, + L"KhmIdentities", + &cfg_ids); + + if (KHM_FAILED(rv)) + return TRUE; + + khm_show_config_pane(cfg_ids); + + if (cfg_ids) + khui_cfg_release(cfg_ids); + } + return TRUE; + } + return FALSE; + + case WM_NOTIFY: + { + LPPSHNOTIFY lpp; + khm_int32 flags; + + lpp = (LPPSHNOTIFY) lParam; + s = (khui_property_sheet *) (LONG_PTR) + GetWindowLongPtr(hwnd, DWLP_USER); + + switch(lpp->hdr.code) { + case PSN_APPLY: + flags = 0; + if (IsDlgButtonChecked(hwnd, IDC_PP_STICKY) == BST_CHECKED) + flags |= KCDB_IDENT_FLAG_STICKY; + if (IsDlgButtonChecked(hwnd, IDC_PP_IDDEF) == BST_CHECKED) + flags |= KCDB_IDENT_FLAG_DEFAULT; + + kcdb_identity_set_flags(s->identity, flags, + KCDB_IDENT_FLAG_STICKY | + KCDB_IDENT_FLAG_DEFAULT); + return TRUE; + + case PSN_RESET: + kcdb_identity_get_flags(s->identity, &flags); + + CheckDlgButton(hwnd, + IDC_PP_IDDEF, + ((flags & KCDB_IDENT_FLAG_DEFAULT)?BST_CHECKED: + BST_UNCHECKED)); + + /* if it's default, you can't change it further */ + if (flags & KCDB_IDENT_FLAG_DEFAULT) { + EnableWindow(GetDlgItem(hwnd, IDC_PP_IDDEF), FALSE); + } + + CheckDlgButton(hwnd, IDC_PP_IDSEARCH, + ((flags & KCDB_IDENT_FLAG_SEARCHABLE)?BST_CHECKED:BST_UNCHECKED)); + + CheckDlgButton(hwnd, IDC_PP_STICKY, + ((flags & KCDB_IDENT_FLAG_STICKY)?BST_CHECKED:BST_UNCHECKED)); + return TRUE; + } + } + break; } return FALSE; } @@ -2642,7 +2927,7 @@ cw_pp_begin(khui_property_sheet * s) PROPSHEETPAGE *p; if(s->identity) { - p = malloc(sizeof(*p)); + p = PMALLOC(sizeof(*p)); ZeroMemory(p, sizeof(*p)); p->dwSize = sizeof(*p); @@ -2651,11 +2936,12 @@ cw_pp_begin(khui_property_sheet * s) p->pszTemplate = MAKEINTRESOURCE(IDD_PP_IDENT); p->pfnDlgProc = cw_pp_ident_proc; p->lParam = (LPARAM) s; - khui_ps_add_page(s, KHUI_PPCT_IDENTITY, 0, p, NULL); + + khui_ps_add_page(s, KHUI_PPCT_IDENTITY, 129, p, NULL); } if(s->cred) { - p = malloc(sizeof(*p)); + p = PMALLOC(sizeof(*p)); ZeroMemory(p, sizeof(*p)); p->dwSize = sizeof(*p); @@ -2664,7 +2950,8 @@ cw_pp_begin(khui_property_sheet * s) p->pszTemplate = MAKEINTRESOURCE(IDD_PP_CRED); p->pfnDlgProc = cw_pp_cred_proc; p->lParam = (LPARAM) s; - khui_ps_add_page(s, KHUI_PPCT_CREDENTIAL, 0, p, NULL); + + khui_ps_add_page(s, KHUI_PPCT_CREDENTIAL, 128, p, NULL); } } @@ -2683,7 +2970,7 @@ cw_pp_end(khui_property_sheet * s) khui_ps_find_page(s, KHUI_PPCT_IDENTITY, &p); if(p) { - free(p->p_page); + PFREE(p->p_page); p->p_page = NULL; } @@ -2691,7 +2978,7 @@ cw_pp_end(khui_property_sheet * s) khui_ps_find_page(s, KHUI_PPCT_CREDENTIAL, &p); if(p) { - free(p->p_page); + PFREE(p->p_page); p->p_page = NULL; } } @@ -2701,24 +2988,26 @@ cw_pp_destroy(khui_property_sheet *ps) { if(ps->ctx.scope == KHUI_SCOPE_CRED) { if(ps->header.pszCaption) - free((LPWSTR) ps->header.pszCaption); + PFREE((LPWSTR) ps->header.pszCaption); } + khui_context_release(&ps->ctx); + khui_ps_destroy_sheet(ps); /* this is pretty weird because ps gets freed when - khui_ps_destroy_sheet() is called. However, since destroying ps - involves sending a WM_DESTROY message to the property sheet, we - still need to keep it on the property sheet chain (or else the - messages will not be delivered). This is only safe because we are - not relinquishing the thread in-between destroying ps and removing - it from the chain. */ - - /*TODO: fix this */ + khui_ps_destroy_sheet() is called. However, since destroying + ps involves sending a WM_DESTROY message to the property sheet, + we still need to keep it on the property sheet chain (or else + the messages will not be delivered). This is only safe because + we are not relinquishing the thread in-between destroying ps + and removing it from the chain. */ + + /* TODO: fix this */ khm_del_property_sheet(ps); } -LRESULT +LRESULT cw_properties(HWND hwnd) { /* show a property sheet of some sort */ @@ -2730,7 +3019,7 @@ cw_properties(HWND hwnd) tbl = (khui_credwnd_tbl *)(LONG_PTR) GetWindowLongPtr(hwnd, 0); if(ctx.scope == KHUI_SCOPE_NONE) { - + khui_context_release(&ctx); return FALSE; /* While it seems like a good idea, doing this is not */ @@ -2764,6 +3053,7 @@ cw_properties(HWND hwnd) /* if still no context, then we can't show a property sheet */ if(ctx.scope == KHUI_SCOPE_NONE) { + khui_context_release(&ctx); return FALSE; } @@ -2781,8 +3071,9 @@ cw_properties(HWND hwnd) kcdb_identity_get_name(ident, NULL, &t); if(t > 0) { - ps->header.pszCaption = malloc(t); - kcdb_identity_get_name(ident, (wchar_t *) ps->header.pszCaption, &t); + ps->header.pszCaption = PMALLOC(t); + kcdb_identity_get_name(ident, + (wchar_t *) ps->header.pszCaption, &t); } else { ps->header.pszCaption = NULL; } @@ -2813,7 +3104,7 @@ cw_properties(HWND hwnd) something else */ kcdb_identity_get_name(ctx.identity, NULL, &t); if (t > 0) { - ps->header.pszCaption = malloc(t); + ps->header.pszCaption = PMALLOC(t); kcdb_identity_get_name(ctx.identity, (wchar_t *) ps->header.pszCaption, &t); } else { ps->header.pszCaption = NULL; @@ -2821,7 +3112,7 @@ cw_properties(HWND hwnd) } else { kcdb_credtype_describe(cred_type, NULL, &t, KCDB_TS_LONG); if(t > 0) { - ps->header.pszCaption = malloc(t); + ps->header.pszCaption = PMALLOC(t); kcdb_credtype_describe(cred_type, (wchar_t *) ps->header.pszCaption, &t, KCDB_TS_LONG); } else { ps->header.pszCaption = NULL; @@ -2840,7 +3131,7 @@ cw_properties(HWND hwnd) ps->ctx = ctx; kcdb_cred_get_name(cred, NULL, &t); - ps->header.pszCaption = malloc(t); + ps->header.pszCaption = PMALLOC(t); kcdb_cred_get_name(cred, (LPWSTR) ps->header.pszCaption, &t); kcdb_cred_get_identity(cred, &ps->identity); @@ -2849,10 +3140,13 @@ cw_properties(HWND hwnd) kmq_post_message(KMSG_CRED, KMSG_CRED_PP_BEGIN, 0, (void *) ps); } else { + khui_context_release(&ctx); khui_ps_destroy_sheet(ps); } - khui_context_reset(); + /* by the way, if we are actually opening a property sheet, we + leave ctx held (which is now copied to ps->ctx). it will be + released when the property sheet is destroyed */ return TRUE; } @@ -2989,6 +3283,12 @@ cw_wm_command(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } break; + case KHUI_PACTION_SELALL: + { + cw_select_all(tbl); + } + break; + case KHUI_PACTION_LEFT: { /* collapse and up*/ khui_credwnd_outline * o; diff --git a/src/windows/identity/ui/credwnd.h b/src/windows/identity/ui/credwnd.h index 66fc3d2fb..5d1137f84 100644 --- a/src/windows/identity/ui/credwnd.h +++ b/src/windows/identity/ui/credwnd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -173,6 +173,7 @@ typedef struct khui_credwnd_tbl_t { HBRUSH hb_hdr_bg_warn; /* header background color (warn) */ HBRUSH hb_hdr_bg_crit; /* header background color (critical) */ HBRUSH hb_hdr_bg_sel; /* header background color (selected) */ + HBRUSH hb_hdr_bg_def; /* header background color (default) */ HCURSOR hc_hand; /* the HAND cursor */ khui_ilist * ilist; /* image list */ @@ -205,10 +206,16 @@ typedef struct khui_credwnd_tbl_t { #define KHUI_CW_TBL_ACTIVE 0x00000100 /* mouse_state constants */ -#define CW_MOUSE_NONE 0 /* nothing interesting */ -#define CW_MOUSE_OUTLINE 1 /* mouse is highlighting an outline widget */ -#define CW_MOUSE_LDOWN 2 /* left button is down */ -#define CW_MOUSE_ROW 4 /* mouse is acive over a valid row */ +#define CW_MOUSE_NONE 0x00000000 /* nothing interesting */ +#define CW_MOUSE_WIDGET 0x00000001 /* mouse is highlighting a + widget */ +#define CW_MOUSE_LDOWN 0x00000002 /* left button is down */ +#define CW_MOUSE_ROW 0x00000004 /* mouse is acive over a valid + row */ +#define CW_MOUSE_WOUTLINE 0x00000008 /* mouse is highlighting an + outline widget */ +#define CW_MOUSE_WSTICKY 0x00000010 /* mouse is highlighting a + sticky widget */ void khm_unregister_credwnd_class(void); diff --git a/src/windows/identity/ui/htwnd.c b/src/windows/identity/ui/htwnd.c index 9acbac704..0ad9c880f 100644 --- a/src/windows/identity/ui/htwnd.c +++ b/src/windows/identity/ui/htwnd.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2004 Massachusetts Institute of Technology +* Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -384,7 +384,7 @@ static int htw_parse_tag( khui_htwnd_link * l; if(!d->links) { - d->links = malloc(sizeof(khui_htwnd_link *) * HTW_LINK_ALLOC); + d->links = PMALLOC(sizeof(khui_htwnd_link *) * HTW_LINK_ALLOC); ZeroMemory(d->links, sizeof(khui_htwnd_link *) * HTW_LINK_ALLOC); d->max_links = HTW_LINK_ALLOC; d->n_links = 0; @@ -396,17 +396,17 @@ static int htw_parse_tag( n_new = UBOUNDSS(d->n_links + 1, HTW_LINK_ALLOC, HTW_LINK_ALLOC); - ll = malloc(sizeof(khui_htwnd_link *) * n_new); + ll = PMALLOC(sizeof(khui_htwnd_link *) * n_new); ZeroMemory(ll, sizeof(khui_htwnd_link *) * n_new); memcpy(ll, d->links, sizeof(khui_htwnd_link *) * d->max_links); - free(d->links); + PFREE(d->links); d->links = ll; d->max_links = n_new; } l = d->links[d->n_links]; if(!l) { - l = malloc(sizeof(khui_htwnd_link)); + l = PMALLOC(sizeof(khui_htwnd_link)); d->links[d->n_links] = l; } @@ -807,7 +807,7 @@ LRESULT CALLBACK khui_htwnd_proc(HWND hwnd, cs = (CREATESTRUCT *) lParam; - d = malloc(sizeof(*d)); + d = PMALLOC(sizeof(*d)); ZeroMemory(d, sizeof(*d)); if(cs->dwExStyle & WS_EX_TRANSPARENT) { @@ -824,7 +824,7 @@ LRESULT CALLBACK khui_htwnd_proc(HWND hwnd, if(SUCCEEDED(StringCbLength(cs->lpszName, KHUI_HTWND_MAXCB_TEXT, &cbsize))) { cbsize += sizeof(wchar_t); - d->text = malloc(cbsize); + d->text = PMALLOC(cbsize); StringCbCopy(d->text, cbsize, cs->lpszName); } @@ -848,13 +848,13 @@ LRESULT CALLBACK khui_htwnd_proc(HWND hwnd, newtext = (wchar_t *) lParam; if(d->text) { - free(d->text); + PFREE(d->text); d->text = NULL; } if(SUCCEEDED(StringCbLength(newtext, KHUI_HTWND_MAXCB_TEXT, &cbsize))) { cbsize += sizeof(wchar_t); - d->text = malloc(cbsize); + d->text = PMALLOC(cbsize); StringCbCopy(d->text, cbsize, newtext); rv = TRUE; } else @@ -875,20 +875,20 @@ LRESULT CALLBACK khui_htwnd_proc(HWND hwnd, d = (khui_htwnd_data *)(LONG_PTR) GetWindowLongPtr(hwnd, 0); if(d->text) - free(d->text); + PFREE(d->text); d->text = 0; if(d->links) { for(i=0;imax_links;i++) { if(d->links[i]) - free(d->links[i]); + PFREE(d->links[i]); } - free(d->links); + PFREE(d->links); } clear_styles(d); - free(d); + PFREE(d); } break; diff --git a/src/windows/identity/ui/htwnd.h b/src/windows/identity/ui/htwnd.h index 9e7478803..e83dbb684 100644 --- a/src/windows/identity/ui/htwnd.h +++ b/src/windows/identity/ui/htwnd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/ui/images/Thumbs.db b/src/windows/identity/ui/images/Thumbs.db deleted file mode 100644 index a80265f86769c7c1326186f19842f6d26393516c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 116224 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 literal 0 HcmV?d00001 diff --git a/src/windows/identity/ui/images/chpw.bmp b/src/windows/identity/ui/images/chpw.bmp index 688da40df318687db35d1ba6c97c2d68ea4a626d..71c95ad4ab86dc604782a084b96ee72e124e64fa 100644 GIT binary patch literal 2430 zcmcJPT}V@59LC@1rf%}K2)hd+h!KH77e;j>gn82nDh8qX(R50N)Cp$|RvU_wMrNXh zy4e=21?x*Or{RJPMT?bRW0MAJM_QX3?IU&ev@=e=+q&`SpXdB}-v9ePzjutoIbAH@ zO;S~Weh5!Kp8a@skiF=H6s7l5i*%dWo+8_Wok?@oQzf}_S%^3Y_e1}2%gaiI3uubl z(f&wQEfub}Z(h^f$L*CB9*}xJJXX8tL_H?i9N!(#P{UV!_y7G&(#cp3vGx zD8~iiqs>Nf%`Z%KwX$rkc`iW|eyGIo6XBD+0d8qs{GH7O!C|*k+*cOM&H5Vydfj?5 znW0*)7ZJ7oPlZ_C7z4%rXIGJ3G TaNC-IO5z)v!R0R5!cP7G@lw?l literal 2430 zcmeH`I}XAy3_#7u4UiD(ih2OnN=z(_ow*4dg`G=qj2d^`O!v>c&5QTKH>JTTAZg4T6Ph5C}`BQFq&6=33H`Ryu g`#M3>?LJ^0ZRQ(Yl^(0s1m6{8eIyPG$USi1t2><{9 diff --git a/src/windows/identity/ui/images/help.bmp b/src/windows/identity/ui/images/help.bmp index d7d4eafacca37cc90c33f900c2a82289bd54c295..568c46bec871cfc538f175fad4a4b2c88b1685bb 100644 GIT binary patch literal 2430 zcmcJQZA@Eb6vwY0)hUT4#zYMoznHlMCDCj%6LoW$Srme9OVDl^66P{sINn4$m;tp#Dr+Nj@-irIEu}zVmKJDxTPUs2w*g(DP@uJ=w9wLm2OeyC3w|-~`Iv&Xc~{mv54j zZxt0G_H95SGC`kz_kKZ2PWn2G+?;HwM535lV(YdF@LgJ`x5ka;_O`aGX{llTa0DNM zZ)L^pw3I7Bva>S#MIyFtGwR+Z#@L70?oH`KH=oA~j-ZX8i%;-n&}rG38HjQUMf<=K z)9%L@+eC8wS0(-eMW9?AfE+9EN3eEFa5NbW`Q*IdY;TW{;LEyGbDf+A6c-j+9j>TG zFGll5)OcAFzD++N0)D^4vr!=PK?881&o?(~L9>wi`$Ys_PF-zrQ6Vt(z!X*Q!Kfa{ z%Wj{4V;hshCwjO`P!yTH5zOt*{E_wHAt@Rci~k__HZ?R*N=v(Vyz4_AtjZP1UR`pn zZ}_|jB!Uj~&8!7=*dx(sUuRY`z+p%#CHS^-Tc}l)CW|eC_7_&}=y|ZZzUB!+9$Wzt z5mrhOZI?)0kH*zw;2@XD2)_Kz&W`rBYTSX9&L6wG=yth6`F_9-Izpg#hL+~+D@cb; z4U?%-Dha+lLZMtXlEAfMKbmQ>#YawODBtxhfR5l#EQgk0f4X4~N}zY~`D*nT!FOO_ zKsPz@UX2O6scTnT?aND{WDCroBmS)lJqo$}Ppy{VE0szNdfic)1|usM=B;65w(CJh zaPgUatI(sw6?&bH;47EQCMPBi-sA>JhEPl)VT2%7Pn6$BQ@BDgGd)f4h3^HfmQ#BlORA6kMWEGa z!f5W7vjxM$_*j?@$7ilI!IV&{f``mvu@HO>2E9^=cZj6emvo?0B!P96Uu(;y4Q>lYuageuCsURXQmed7xc1zcR zb0wfx{N4!<12`-$+6cb0vljT;G@9|24&Do&=V2dTJDFZ46m}zyT>c3ZLLvP+X=olo6WovgM(rUgZ)%YB6gT`=uCPwyN=7{*3~z@L&`aL z_S%_@TX2NPEvb4s<|6dG`dJE8M@L7|xYOw*_&V(Nh5314)?$HoK~Y)d^GD*bgC~La z&t1Bdl}|4E89_?Rjr{N|Dn-X7F@C)R|BYxC@~X>4@LgG10c(V9VS&fvQOYYmh(C|L z9JMdc9Xdw3{4JeMmq;YRLD;N$JOp3Yo=~Y&3_AVB4>!L^xN!9NC$GI3jW~Wfj+B^O zQc}WVu?z-7*qqnvCHTVo4y3(-<2Z-IDJv@@{}WUywYj+&ejIz7-EMdIdlSwOKA&&% SzeXSsKqiFyMTh?}V}AoBVWltt delta 332 zcmew-^iOEQo5?zyK@4PMtb* z=+L=y=b-$eu4%rtlcz3P0p$nOP2ul3UeYrS!siL8odD!p7Ix2A3{;{HG*W2C?me*$ z6QnDa2-R;2uIxT}>hwfM#fiPz{F`>{HZSS}Dt9evzjEcuL`S)ay?Q(c4Bg(ZH3!nCt_q#G!+rS`!}=v9Ju|@e%SZt2T(frFwApj}W-n-( aHotE2+=dA=4jw){(NSe$Z#+g|1pxpJq@7&= diff --git a/src/windows/identity/ui/images/icon1.ico b/src/windows/identity/ui/images/icon1.ico deleted file mode 100644 index c2746b065c2bcfa0ed621cb018262323a49744a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 766 zcmeH_u@QhU3ns%qtu-P=I9FIyq@_ks6HHWSon%Gdl`&pr(}$ k*gf#+`-YR8rA#{nF=Gs-lbWR}I|LoM{rL0?@CRPS1!#7awg3PC diff --git a/src/windows/identity/ui/images/id-dis-sm.bmp b/src/windows/identity/ui/images/id-dis-sm.bmp index ff0c38e4d169e66a2356c1b41a0687d9bb51dc1f..d028d84ca89804ab8d62141f18eac3d16a89820b 100644 GIT binary patch literal 822 zcmbV}u@QqX3`NDI=Tc^bOuztCG^soUYiKkV?7$4!BHw&06bB!^=&+IH_a)gLU&Bo{ z8!$gH?)&KEvBd@ZOV7c8$oiMf4aUR`;DJDb#XFm-PT3B~c?BP1%=i>SaNzD1JnC2p z@Fr0e3VwMjK^SsGV3#}^Bh16qc*fvs literal 1014 zcmb`Fy=nqM6oogWPx1&UeS$nduyi*f2E;;kv!Vt?Wkm)5A_yz~Y+*2hxP^k1#e!gA zB`#(W5iD%P7fE|EGa(R2F&oH*GfXkxy>srp_u|K;z~YXa9-d4@r99^6hpT%jFXD`5cqU1cqUt zP$(c0i69t!V>^7P|M~C9y}O&= zo_qJ)yWf2O>ukiO&mpdWg967=IHn+rAtK0kQm`rSLEsI4qP( z4GE@h3kiLlY1C~m9ZIEzQn!bP?bsdxc0=5WzT`&k+6mqk92DUHEq(vKgt$0HeEcg; zOh|a)gA9h-TLJ?@g0}97iu`eR6rf4m(vp&&_U_#g5doQE80LQRB;&JZ&tm9w8kHKo zZ(r8gvm~ydy!_|r=%B4X+!6{WiJN$v*=*jlaU;-Q<=(ESh&ymVrL5`c=^maSi^T%z z3{FDAveF|=CWpfz6gD+ALdq|sR4UzE=ZI~%zsFRsYu2L8I$Z;b>QS`b6&tkL+S=OFzh|;i zkMplxBXRFlSD(trD7kqrxRD$`n%vs&QZr0KE`IVW9ZRP40k1B z61UM{fU#USf4;c580J(el}RL$s;VkhS{hWxVDF&AIy&^IU69Yq&B`v}UK)I8!fm6@ zQ74Q8xGWZH&+grMTrLck#5Ee5%gf4^iLI0j^&D3H3(ufty4$w?$8D(m@~OjZTH|NUb7Ln@MpqqO>Dc)1Ox>5`}>PU zqSlrc61Sxl);)%#n`Zfje6sRWA0MB!YuC-0`}WM>Lx{&p;NHJ~zrJ4gyt1JJ>ogjb z+bF6+QT67{fqH$txub)`E!K4-+2-kfLCcq~@bvu9+uIu^;jQh*kR$`L>(1;Hl`C6! zp0A0p`lF&EVejke>LhWOo@|=_MbMfx-m6xvqEI|%%$zlQ=ZOW`2CWuFj+&-0)%WgI zL$W#@EKC#(Aa?`$ckbK{4-12r*4@?B*Vjwpp1jrk&Wg{xyq5d=e(AaFBgAhHjQwz0 z&hgar{j76P*D*0MiHQsbBLNg2A0HPN8ykB71U)8`sZc2TT!KxT#D&>sRkzRk*vG?T zF%p?b-HD@+ll>Qa>8+< MVn|$f=YNdIKMt75s{jB1 literal 2430 zcmeH`F>1sx5Je|tZV(8;ZP){(T}YKCrE1?~<(qhmRJw%s5Q1$2K8o^2W4tbGg9Mvu zg*0f_=*`#H%;)#%S@QTGzO&v~udF9|A&PuW-}8?tT<&%kPC*mtc?kb3TV5gdwIemL}Nd9vxg}0^KV&dO>Fg z49&F)xviJRA;(JCqF#SY)P_RGXkW{?JP20iM+-9==b*5zf#HTDg4?3Zqd& z_|xj)-;0WY8c+pB=DG6*r}20fD#;N}CI9ciLt>EQ!_o6@RN)%YzTD GxgmeD&mEos diff --git a/src/windows/identity/ui/images/main_app_old.ico b/src/windows/identity/ui/images/main_app_old.ico deleted file mode 100644 index e3222e7fddff3012958d7265d6c8848018b446b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7854 zcmeI0JBVCI7KTf1EhA?2u>4RotY^EEosDL=ut+G75Q=Ui@NH16?BZyX9#CMz4lIby zY%mCJroe01V8KXXClfiaZY(9MNP&$Qu*D_<2esdSs_H(vdqx9eC-zi#JzwNxZ&J@V4!+8n z&^6;m-qYcxa=z8+#X#qL|G)e0r|-UYXV0E>=gysT=g*&amoHy-SFT)f8yg#LI2^jI ztu1%=?p=51&K-B_)-8AK+BLWLnRg$5?A@2{nezv=`}Wz7?%DU>yD$FzA0jBvCAFf~ zL9|1FE<=||$8uy+Vp}pO(U<5;^nz9BEA$mYg}y>h=W6sd`Wk(WqE=dvJ+iMYvL1j8 z=NXPNKpAO`XOJE}95Og$a6qJD4~Gm685}Y=7)>~2aLC}0!6Ac#QHMhYhYSuG95Og$ z9vwU~cx2+icH!Dsl(Z#WO1PA8u_Z&OBzQ@n5~n3xEDcPS3`)3^aIv(&ql8BZj}jgw zJSzjItq4%TsUmj8 zWQCK8*cGvDJ1jPO;#b74h_5ZGh+mPL3Jw(TMY7|kv5j#D2{YcfFI;}@~{ejxC5+Up>DwkpqS<&;0a7*yl4aHiekhJKFochUoBhFw~2o{9~HwU*)R_bh~d^Po`@@A*cGWz5Z~A{E|j;l0vXFk%Am|UV}>>r zT*`y&7x3~C3SQ+P7Ws|Cjg2s2_{lgQ*%l;N+XwT6YN>#qjQOq0{$V^8ffkfTEi5r; z-3bqS&X4k<3?x+S`;aIpPn7Z4;-3(&V=oSQF&^dp^#|q_DMq%=f?Knz`_mj)4tRKm zeg0ioGX~1$s@Nq(=!+MJ9H4x}t{#GKH_d?2DqM0n&;wvR7VzO=O_5oTp&O%gNy-5? zAkW}(_|EnPFfCTrBs@t_S;E_aj}CO2t)vj6-X(4LG}ZJ0k&wh~s0RwW>GPvOEDU1I z*!3qzqsiOw%4(h*#f-UT&bXJZ*MDn5Y%#{nx%B&hoRwPV-Vorbq>R$WTVExGCt1@ z{XsreNTIj+b0VNp+k~Gi;ZcZto|8y}Z^geh27gWH4*kRMM&bRb!YBA(YbyjBH-`lp ztKxgxL?v)4^!jix@Ph&9=-^k!TMDLpH&!wJo#3Wy5@^!V4G#DxJFPz2CI?4DdCh)0L`YCu=WSrvBK#Wy9{@m5Z}S U%`MvYT25#1$3<8`#7@j?O!0`6{Cx-tV(hN2(;S4OILfj1BzPx96_2nDG^H;wZ z{{LcUkl^{kAj5rtVb9t}3@ohdd<=T(dJM?m!kNPipI-MdaDRHpz$CArz<>_8`Ggog ze|pcr^zS^&Kmu?pHY})N;Qs%Dfmg|g!NNWO(+ZX!j~QfGE-`%l_zJ}Y Y03JqGqf;=&8vp$G+E}SCAwwmvT17A@Umoy&RuYGB3`y7YpZTEfF^S)8nSTNxQIFt z#oJ1yV4(}JLT%Mjq+)Nh7Ch~M7Ef=qwu26^R44_ZmR?WyZ|jI>SvEe*C(rqxx9@rT zJI{H~dC%Frvvd(k=v}B3*j|I}RoGrYOQ0f@4#&G+N^Xe`C%Dux zdw0`!)2MsswEr}W{N}5@Nhcx6>wlUTy7p&ff??dQ9oqr=LqS2(KNc4Li;v|Tf$?n9JpQoY2h74D3f1tY&W0$+F`e9k)qb47+#sOnKK`)zHuoM4p_SggP-X z0fXY#8zqQvX!_CEh{HbWa6on1?L&6^AXI2O959T-t}Q=(N-mRWJ-r6A-PbFX%5!JWK(a2i zn#9%X^>u9aEs;p4>$6&|kQyqey}cc{LiHqa+n;ILg3-}rh2G8%jcsyR58zzWQB+i{2)5@hCt*sKF(1hI$ zKK2lyV2mKRTyB2e_qD9*-ku&3*JLza7YKMQ&D~vHkX@(KK?QL*oCG%-=LY=4M%`^b zU)0iKQY(Vf<8Y>EC=w%LEEenVp+og`b^UrhiEFV~+C(CVESJl*T5WZ8+(Mz2!C=I> zp(qgyKY28wxX$O*b2?gn^|=O#P$&xh32tR&Wp-9pV?%?{U?6c}K06hPI(GAxFWS(u zYiMOt+;6nJyrRbCngMRuH$9ANxlCr=Wrl>u4NXlD!ALY1f%8G$l9CcSjn>lKJYcbq zxmKH0qFKI)gVwWNqzK;6=**yZE?p-?saMgPVoc=*?p=PYcefp9!;Af9*s{;agLk6K%WgM))4u3RyMQaDTBlGtqSi3u-`n~KZy zh{8n_-iA-jfX+T>ip);COg)YsWzaiL%msM=TfQE_cm@6i^apk!z3=_suitc z<>U;_%>{fu|3$_KqBJ4OH8y9~>6}KZn_pQgf&V`hH0IlhuB}_QZc9&x96!WF6alBfPr!l*N6@NPv_v&9V20I*ngrlemnU zLA0)VOS-D`1db^D1T>ILH#HSQs|9P)tbe8bhdrz#8kPEo)9LkkNnE|&jZzvGy)H%+ z7NXP?7MpE0xVH|6!+9Xr0P~yid5_r~&uccD3G*36#oQoWjn_KUG{@QkYOdK|vl_u$mw#2tElU zE?k?-<$wD_BRs!onRL@<#!WkH%QmV|YCT#mtF49ahX2U|1f0Kfq08+KmYkYioYIX} disD}0`N8(lzP@N=0fIZ6oOlv9`Qv}A=ug6K@aF&k literal 2430 zcmeH{F;2uV5JgQ%Lyd$`TC@kCU5Sc@a_Za!=O)>LYA%tDM48eO%}PE>_~S8Q6*&f5 zq5xsZvq>C3|9x@t@br9XLc2%3L%&78LBBB9sKz{E{PjwExPbEZGwq+NUjLGZuIqHy zRBV}?2Wl<%d^{a17RYk<1nA4*fI3fe(E?v^0aY&dPUxZG3bjOg%J|vjVj3oEUbVpk zYigyVVic~D^i3|F7_@@*k(cMe@eopbAu1hf7jsnt&?*5e!3EJvWYg@v%caIq!F7{|MBWq6G)aapqIC$nrHwhwdJmMzKhJr3 z?&&$d^FJ>+pC%Q=iFmyS`3)#*p}Y#^1<@;zMWWB)f9=X>;Ts?gKOa43F6Oo4yHtqn zU#BcTQn!B-9Tg=&j;{Y7zwo_#XF7EHGAZ%rpMK2E$yrVuK6D5iY)Rg{D?JS&ijLuC zW@PM2Plrw>lWA$@2Nq;@+H}q zty^tvNAmM7)zk>Nr%x5$Y`HNpKJMli^M3x*zh-KzoPwkX-ilQKoTdiYOs|_;L zDGE09dgImOM+>gVWkPOAadC6g^^uVgund}>o`&4t-yh|MnGo%9kD5&*BxxbZVUm1I zl7I36mA<|{x$N?B9L$q_$V(#r3 z(CLjjUB6z}r|UNAx-Emod-v{1E6aZ?I(?(LNyx2|N*n6yz#y!BNv*A|&<_EZ4I`Ef z&NSw*BY)!rK&o)&tXF$CL9W*P=s4l zRFs{a4LjMb)e5=l_B$U}X~kOnJ~jXLAQkV$@jkrXWGiR6*IAt5V<*WTMOj&u)Sa3=4N;Z75x{W!=*{01X_)6&wmBqzhMo6V6oD~2n1 zNUhPaE2bG@eB$N#g>>&?<0AbL9r$E~`oQj5HH#1WLldOI+S3`DbD=;81=w(q3kM?H zl$4ZBn>IB!H^BuJa>ZwHoEj687!1C{u%mR)%W_P8dzLXUS2Ob~D@JeU}rAqH{08fOi<%)Cq{QV?pjIyLp% z>WdeFFgG_VLo(8zZ|rLI3~& literal 2430 zcmeH{F-`+95JgQ%Lyd$`T9gCOMxvsjbe)@!+{7uUe2GmY$}KI?Ao(cfjmI%a@vgFq zC_q?a%dzD*-`}%&czV7xx!p6~(QoND^b2#%Xv`z~uUFdh0>j(Sw12Mp`j>pzZns)B zGfHO62fNU-!kR_xl^g&px{kZV_# z!|H=d_FWL+1uhBriC0bfAeR^8*4$n7GN#NGbQGe1QzG|duH4rJWHM2)s<%Snn#J;5 zu5rn9asaUgMV-7GT!|PEORMOif3AiP0!4`PfS4%JMiK}VVu8j$?kU`uxuBVJ$;LoP zCX^oaB6*0YwzTwu%M>w0Bd>_eFM20)NhnGQpzAyq)!9~5AKM7Jp;x%+$OTQr;!Jf` z$<%nW7=&=TQ7Q6(5H%=_D71pk;AwhGJ*1-1N?~Zhg-rV#CUTvWL2(0m%yZ|>CIFJQ kSn5}Pde^$r@ZoSc)a}`m2Dk6~*|>VJ!L57WnfyBL2N-EX8vp?nwa@v{_}sIo}Tmecb;>t zv-_R*?W{To@oRW?!}A$D@7a9<(az2V+Iib-kF^5Az`M~q=B`;48WMaqz#r^;#(T4U z&UpKHd%fl}UY<6?n?L*cf^87n_}BA=Du9Ch{e0csPDNh4a3dxLjKg9#JLdZJ&BjJY zgT1{xe{y#_cQzm>@GNjp+&U)nLU{Nu!NJgZcXzj~=eLaW^YdxHr+S=rKOY+UAT15W zWi>Qhy?hyxEuqog61VxamoHzs{BSZfBqS>{6UA+5ZpOvL)H9hgGt>G_T3%jWSXh9J z{!<<8?Kg4Qoa}5Aw~fudgTGz-Cu3q_;?=8H(7#RNR*k(`qZ?w>)Zk*U`FW2}TrP)` zln_sUT0N>(&p^%_>g(&XjMt1HCga@X#F$Dsu2PK+D*sX{hn319h)^CJR45c>rLx{h zmm}b`3%Q&=v9PhRkwhfK-;Jv%FGq1D63L_7+_KUVC@7W6{{DVjGo4NcECO7U88Mmk zT8*5`ZmDCo*44Gv*7oqZGis%AURzmNnUb8CoRmbbd5Yq8b;+qkloDDopU>;sBr26^ z;hGS{xQZB!`kCh(CZndjobmXvyuHaVH;t?q)(|8=KmQIsHvPeUI0q8-Q9&!F zwzsvxoZ2K3iE?sstX#8&t6v(CbygP@RglSDEe(d*N$APEvbu(>Wn^SvuV2d|WHvQ6 zqPWU|0T?ocOoj#?kH_M&NOV#zBllMPEeqFZMhvD!%~&0cT98Gop%l#jtwIbdW&_k) zxCsdf5#iw^A`$j0iaR_s#A>K7$j^%)N3hsUL>9^6-d0TP2S>0+=H}*rYg(97OL>J4 z?h}(!8RYyG-4qbbhE>F11TGGT3keB^72@+cP+Zsn?ABIig0sWzt-n$(5*o5Gsh@t4 z{7ps`!G(FsRpz3f9dDxMr{nR-H*uAJ5R9|aYkGjft=MkANY^YRLOGlM=#-$&$76vIQ!(hjGhecR(cKahAhm6fuh zn;esJ2RiBvS`D&nK$eYW{i=D{!u9ghrw`|_^4Z42+a)-GN>6rb09P%vS|agRK6@l1I(=BT_;S+ zZuRWA$pkwV&Vh-g;b97#95bEl6CLfY*b!?9B2gz;D12tKSS;-96o3N){22`T*q9o{ zmH1;5=MkMX$d z5gmOkDk>^6GV;=;OSaF88+!7jN~hE6bUL`ZQCt{!zo!3KvGd;aFEi!DC;=8WToB{D zX70s~_?<_{M?+X4quS9$wBWDgH38>!E>yLQv|Qy~onD%DW}L8(#e7FTY&M(aFXUmZ YVch53)i(=P7#eM>g5uh~{EyM@A3>+wGXMYp literal 2430 zcmeH{F;2uV5Jf{tLyd&cwkQXnMWUjioH{qbxrw)+@+Gp7C{sqFSt&;`f99Jgh2v#| zC_q^Dtaqb*{_|(z$LE*J%Emq79o8+@4c0|Z?9Wj`Ri|IGO3($~M_L)*6O znhh;e@^rZ4pgR{AxO4VP^q<2Qg2)obVR<73R zHHz)U3((MLQRQ;1)iC2jV)+_ApwF~QUU(9r8ZoA^&>ML!l(KmN4V`L4hk-8MB`6#y z-my8Zr5~IF5fzIaT3FG{;~QKv6hw#xCAd^KT0sZO=Ax20y;ds_)dYLll->op4B{-g z@M`3_nzF~`py?|GC9=|i&bHm6SF?Z>D4hxyy>u)CoJ8Cl3#H5GWuMbc9+39HaO`Tm kA6DM9^ml$NW8e47uiN$+y~8kUV=e!c;VvI<-v2u82jzJbasU7T diff --git a/src/windows/identity/ui/images/vw-refresh.bmp b/src/windows/identity/ui/images/vw-refresh.bmp index 76b68ddf758d97b377305f789cd1469cd8150d39..6d284a50e59150861c46b66a08edcfbcecd61e2c 100644 GIT binary patch literal 2430 zcmcJPdrVtZ9LF)?(E^3e;VSD05(6s4nI)zK=2%3?RIg34^i(=uS7ji_C(Ha=Mk8za+x%3avbUzSpB)qsKpyu@{KA}eZFS|@t*EYwyu^>>M}Q!eNGRMGK{WB`$neUO<$r5geqQXiF(BmS=1{l^ z@$sUnfWYJMk9v&X=xx0IMc))&se#uEmg9H6r!{)VGQF0Op*9r(?pVjC65TWySoQ z7H+)RU~g{^nuCJ_kH=f@SknYYXaWzK|3Ny9M(1#x{r&yPbf-f@N!G~leL%{~|(n*uwy@BJMDKy0465rpuoVX$;rx!iq_Uv3b&}R5NFoS%?*W%j*cc@0Xm*0J;;g-Z`G#cy)GvmvwRVX^z+bP^K`R|&0_q@D5L3t z!1FB{_ib}?3l@XPK5pxL#mDD#&_!9wQKpq6i9t1x0^MwAP$`vvbahdg#(5wYz)czf-SPx3;zbEtCC<5*r#CdV715@^M~cTn(}Q_#GSXBd#qKLfxWT_as)Q z>n$lQW82`^nECqpVwv!*TaA5vy_EGfH#IdkH?`<>qpr@y#RaQC;ZPG6i*3f(bIhF` zaLmco<*>5ugX}#1!9!lC49ohJ7(onnNsR2l!9fbQv!eqgZ)m_)HiSQ%lcOW(IIwh6 zroI&W7)(1$E4(yY>wOL(r_Ly96zkDywOXZWX>JB&NTZ=}`+9rfrrWpi3Bg3wRaMzp zS?9yUPoDJu@~hy0z^?;>LU~~qQd83bQYlsVmm&tn>*?+30bz7xgu=x<#1-Y`ICC)0 z4L-_E|5jRxp~{L%;xf6sw4`Kn6f3=t|G!2vF+NV=jy-rl+~41ypO=@VS58h&?have z+cT8m;n)}qO;1l#xKmS;o4$K@@TydrmX?+-7H9me^z`(M40x;7Z&BWlLL}TwEOLfFrdd kd}(fO4xH^=JX(Fau!GUj(Wj5EkF2e&ZRe6n{>RqfFA6k6X8-^I literal 2430 zcmeHHJ5I$g5DX;^H4;K;Q4T_pKkTx6d_ z0b;dY`8zuvZ}R;5cHNjgB0iwqqurrhHMfXO^Mduy8#S9i`1%?9$Ca*sKnGSz+l976 zTstZr3~fmxu9{T~s-gonmwgt70CXR2>O<(m`pUU{Tvq|KlW$8R3Fn6-|2Q1v%0Xx(xLAiYrZnaP^f9wck(6`KmpbMiMYDfyO_Tw5~oD?W7Tb4}4$Bpt@D%8PU zXLe13nlT5}pg1ZLNP!i9odI_tK^zuwM0kqCCA4t8d~s5sph?C{hPcE3!7X$s=l`e#t$ zASsfmU_)qQg@8dyo5iIdI6bD78wyby5np)jrr&cnyn&gwVWu}z?m6LR%+08qA!gh? zKj(ggVY;DXnkN1#s;Z(~F8{humSwOki^Ogcx~}`~$>nmWR4S-GJtMNY1;X>bIz&L~nM?-FX0y*H3YVB$iQ-t4zI1f|(&;oD$Laag>pLumV>l8{est8QQYk2kf@my` Y1O9MeN4+FT$Y!&s*XzD5?fCEe1BcZt8vp=%0CF+a|9$xoD2@pr;+X3H hBLSc;B;J1@cVN{cI|j(cbPv#Zm_CJzpgEpYE&$N+^RoZ| literal 1014 zcmZ?r{l?4y24+A~1BeBHm>-B485Dpd1RUXGU;tqlxPJZme;A%IYxe)MXV1dO5Sn*t6Mw&U%PgVWOH=9BL4HQc>kZTdfk6rAbauh6(pIV?FrEjHe=bF|3Zmv z{~f~<{~tJTfGBe`k@SPi0Gl)C{(njTjQ?@DCI2s6xPaFj4UcfJ9++Nany2gNeukv{|`yY`G4%#F%*5U^rheuf?+@J%v=BE zLi7IzBxe0Ta^whBeK7s<&ItXybMF0@i75H+9iQ?4;K74<^}+NjyGQ=#oA=-B485Dpd1RUXGU;tqlxPJZme_GTsw*PG;x?#u8o&SR>d;S;gz6Zws zsRjS9UcE}RKcX}8{&yaI_`mD;V=yjRzVClW-vpxc&tJ6of90%I{}*0*iGpLYiwL>_ zQ_wV2T|M20%|BoL({vVVM&Ye5=|Ki1q|F2xR z@;^R49!#UBdyu|On>PJlzkdDyHEY)VU$J7v|D{Wp{$I3c(f|4L=l`EGXU_kbGiUyv OHf-B485Dpd1RUXGU;tqlxPJZme|-4j#f$&1UcHJ}4L<#` zIYs~L+PlcozkBzd{{o)L|0QgE{)60s&mL@Y#@=E7`Q|{|`&cB}#uNP#sUtF%F1mO@V}*hB!>P|r%wG>bPLC;7o;DA1>+k3FJ8I~#SGur)c?E_&k?1c zZ^_I5`tHGS{j1ij{V(Dk_n&9N+5fzgFaGD9b_Ez#*Z=d*y8WMT?tNf*Jo?YK=-Gde zKECB|!FCAe&G_F3Oe3IlH-F)x|GAa*;53$6T=_pCzwCc(Zt?%f%!2=*xC~6r`tO&J g@!u;Z<-dDW(tlTA9Jquh{?99`g1Z4*`XxpT007d}8~^|S diff --git a/src/windows/identity/ui/images/wdg_stick.bmp b/src/windows/identity/ui/images/wdg_stick.bmp new file mode 100644 index 0000000000000000000000000000000000000000..071a238c4d9fe2ddf0c475d1803a2776db76d5d7 GIT binary patch literal 774 zcmc(ZOA3HM3`47eTU~ktPv8OEdv|vpXABc4bpq0r7Ml6+(q=!#!D?;L6+NRTbY~0H z?Ck6Dkn4{^g8W**r4)wFxSXf!-4bE&v~U+xy~@)?RZE5k6N?$*Sib{nBH`y_K1OZA S@EId%V6`}(fqjL};m-}3SO&fT literal 0 HcmV?d00001 diff --git a/src/windows/identity/ui/images/wdg_stick_hi.bmp b/src/windows/identity/ui/images/wdg_stick_hi.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8857fec2207fad491c611187501d8dd5e2bcf147 GIT binary patch literal 774 zcmZ?rWn*Rl12Z700mK48%n!tj3=%++f#CuZm_i}04+H?ZfOubzvf)IHvg!^*|C6&_X@3Q_&m);Q|!^T>>YuszDZns{}HT#qqH5s009^ C@cUl? literal 0 HcmV?d00001 diff --git a/src/windows/identity/ui/images/wdg_stuck.bmp b/src/windows/identity/ui/images/wdg_stuck.bmp new file mode 100644 index 0000000000000000000000000000000000000000..68295181d54551f38d7ae37a326dd285cd71542c GIT binary patch literal 774 zcmb`CK@vbP3`K((Tb7RC1P);D?sksD*RP#OwG1+oG)dq8YMkmyTnwl^vPCw?LON8D zxpc>=EPq6Byfq`a`rw#R0r2c`VsptGXRV4Qv}M&K`;WY~)qUPP+-eDWg!x}=%$psx f7wl0DkC9hKm4aXJl<2RZN5n5N8)8pLBTS7O`9Kui literal 0 HcmV?d00001 diff --git a/src/windows/identity/ui/images/wdg_stuck_hi.bmp b/src/windows/identity/ui/images/wdg_stuck_hi.bmp new file mode 100644 index 0000000000000000000000000000000000000000..3b780712914f23410e4d6925e485edb8cda6f6a2 GIT binary patch literal 774 zcmZ?rWn*Rl12Z700mK48%n!tj3=%++f#CuZm_i}0Qv<+FBxo2!<&W+2APB<6qYJ3u z*OB#b1k?o-!Kxl&)bC42FcGE}pa{gMKX)!-BCP6xZUBn^efba*p{WOQ;cfu3|Dysl z#X!FRMc{4#vVj1u1Hwh~FHjK84G?7zaUhAN9%2RDOk@UD#bl_5XaSlAHyp?Y0!){n Oi9nPQqY_OcE-nE4K?Gj_ literal 0 HcmV?d00001 diff --git a/src/windows/identity/ui/khmapp.h b/src/windows/identity/ui/khmapp.h index bd53bde28..7f12c7ffa 100644 --- a/src/windows/identity/ui/khmapp.h +++ b/src/windows/identity/ui/khmapp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -31,6 +31,7 @@ #include #include #include +#include #define KHERR_HMODULE khm_hInstance #define KHERR_FACILITY khm_facility @@ -46,6 +47,7 @@ #include #include #include +#include #include #include @@ -65,5 +67,6 @@ #include #include #include +#include #endif diff --git a/src/windows/identity/ui/lang/en_us/khapp.rc b/src/windows/identity/ui/lang/en_us/khapp.rc index a1b03b411..eb2d4a9bb 100644 --- a/src/windows/identity/ui/lang/en_us/khapp.rc +++ b/src/windows/identity/ui/lang/en_us/khapp.rc @@ -8,7 +8,7 @@ // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" -#include + ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS @@ -35,7 +35,6 @@ END 2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" - "#include \0" END 3 TEXTINCLUDE @@ -55,8 +54,6 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_MAIN_APP ICON "..\\..\\images\\main_app.ico" -IDI_WGT_COLLAPSE ICON "..\\..\\images\\wgt_arrow_collapse.ico" -IDI_WGT_EXPAND ICON "..\\..\\images\\wgt_arrow_expand.ico" IDI_ENABLED ICON "..\\..\\images\\enabled.ico" IDI_DISABLED ICON "..\\..\\images\\disabled.ico" IDI_NOTIFY_NONE ICON "..\\..\\images\\app_notify_none.ico" @@ -69,45 +66,6 @@ IDI_CFG_APPLIED ICON "..\\..\\images\\cfg_applied.ico IDI_CFG_DELETED ICON "..\\..\\images\\cfg_deleted.ico" IDI_ID ICON "..\\..\\images\\id.ico" -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,1,1,0 - PRODUCTVERSION 0,1,1,0 - FILEFLAGSMASK 0x17L -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x0L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "CompanyName", "Massachusetts Institute of Technology" - VALUE "FileDescription", "Network Identity Manager" - VALUE "FileVersion", "0.1.1.0" - VALUE "InternalName", "NetIDMgr" - VALUE "LegalCopyright", "Copyright (C) 2005 Massachusetts Institute of Technology" - VALUE "OriginalFilename", "netidmgr.exe" - VALUE "ProductName", "NetIDMgr" - VALUE "ProductVersion", "0.1.1.0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - - ///////////////////////////////////////////////////////////////////////////// // // Bitmap @@ -170,6 +128,10 @@ IDB_CHPW BITMAP "..\\..\\images\\chpw.bmp" IDB_CHPW_DIS BITMAP "..\\..\\images\\chpw-dis.bmp" IDB_CHPW_DIS_SM BITMAP "..\\..\\images\\chpw-dis-sm.bmp" IDB_TB_SPACE BITMAP "..\\..\\images\\tb-space.bmp" +IDB_WDG_STUCK_HI BITMAP "..\\..\\images\\wdg_stuck_hi.bmp" +IDB_WDG_STICK BITMAP "..\\..\\images\\wdg_stick.bmp" +IDB_WDG_STICK_HI BITMAP "..\\..\\images\\wdg_stick_hi.bmp" +IDB_WDG_STUCK BITMAP "..\\..\\images\\wdg_stuck.bmp" ///////////////////////////////////////////////////////////////////////////// // @@ -248,13 +210,15 @@ BEGIN LTEXT "IdentityName",IDC_PP_IDNAME,34,7,194,12,NOT WS_GROUP, WS_EX_CLIENTEDGE CONTROL "Default identity",IDC_PP_IDDEF,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,34,25,71,12 + WS_TABSTOP,34,22,71,12 CONTROL "Searchable",IDC_PP_IDSEARCH,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,34,43,74,12 + WS_DISABLED | WS_TABSTOP,117,36,74,12 CONTROL "Custom1",IDC_PP_PROPLIST,"NetIDMgrPropertyWnd", - WS_TABSTOP,7,61,221,88 + WS_TABSTOP,7,51,221,80 CONTROL "Always visible (sticky)",IDC_PP_STICKY,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,117,25,85,10 + BS_AUTOCHECKBOX | WS_TABSTOP,117,22,85,12 + PUSHBUTTON "Identity configuration ...",IDC_PP_CONFIG,117,135,111, + 14 END IDD_PP_CRED DIALOGEX 0, 0, 236, 158 @@ -272,7 +236,7 @@ IDD_CFG_MAIN DIALOGEX 0, 0, 357, 222 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_CONTEXTHELP -CAPTION "Khimaira Configuration" +CAPTION "NetIDMgr Configuration" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Title",IDC_CFG_TITLE,0,0,357,20,SS_CENTERIMAGE @@ -311,7 +275,7 @@ BEGIN IDC_CFG_KEEPRUNNING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,78,158,10 CONTROL "Detect network connectivity",IDC_CFG_NETDETECT,"Button", - BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,16,96,106,10 + BS_AUTOCHECKBOX | WS_TABSTOP,16,96,106,10 CONTROL "A&utomatically import credentials from Windows", IDC_CFG_AUTOIMPORT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 16,113,165,10 @@ -349,8 +313,8 @@ IDD_CFG_PLUGINS DIALOGEX 0, 0, 255, 182 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - CONTROL "",IDC_CFG_PLUGINS,"SysListView32",LVS_ALIGNLEFT | - WS_BORDER | WS_TABSTOP,7,7,75,168 + CONTROL "",IDC_CFG_PLUGINS,"SysListView32",LVS_REPORT | + LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,75,168 GROUPBOX "Plugin",IDC_CFG_PLUGINGRP,86,7,162,103 LTEXT "Description",IDC_CFG_LBL_DESC,90,20,36,8 EDITTEXT IDC_CFG_DESC,134,17,109,14,ES_AUTOHSCROLL | ES_READONLY @@ -387,16 +351,17 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - CONTROL "",IDC_CFG_IDENTS,"SysListView32",LVS_SHAREIMAGELISTS | - LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,221,72 + CONTROL "",IDC_CFG_IDENTS,"SysListView32",LVS_REPORT | + LVS_SHAREIMAGELISTS | LVS_ALIGNLEFT | WS_BORDER | + WS_TABSTOP,7,7,221,72 GROUPBOX "Selected identity",IDC_CFG_IDENTITY,7,81,221,63 CONTROL "Monitor credential expiration",IDC_CFG_MONITOR,"Button", - BS_3STATE | WS_TABSTOP,13,92,107,10 + BS_3STATE | WS_DISABLED | WS_TABSTOP,13,92,107,10 CONTROL "Automatically renew",IDC_CFG_RENEW,"Button",BS_3STATE | - WS_TABSTOP,13,106,81,10 + WS_DISABLED | WS_TABSTOP,13,106,81,10 CONTROL "Always show in the credentials list (Sticky)", - IDC_CFG_STICKY,"Button",BS_3STATE | WS_TABSTOP,13,120, - 151,10 + IDC_CFG_STICKY,"Button",BS_3STATE | WS_DISABLED | + WS_TABSTOP,13,120,151,10 PUSHBUTTON "&Remove",IDC_CFG_REMOVE,174,126,50,14,WS_DISABLED END @@ -425,8 +390,8 @@ BEGIN IDC_COPYRIGHT,41,23,220,18,NOT WS_GROUP LTEXT "BuildInfo",IDC_BUILDINFO,41,41,220,17,NOT WS_GROUP ICON IDI_MAIN_APP,IDC_STATIC,6,7,21,20 - CONTROL "",IDC_MODULES,"SysListView32",LVS_ALIGNLEFT | WS_BORDER | - WS_TABSTOP,41,72,220,91 + CONTROL "",IDC_MODULES,"SysListView32",LVS_REPORT | + LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,41,72,220,91 LTEXT "Loaded modules",IDC_STATIC,41,60,52,8 END @@ -709,6 +674,17 @@ BEGIN IDS_CTX_PROC_PASSWORD "Changing password for %1!s!" IDS_NC_PWD_FAILED_TITLE "Failed to change password" IDS_CMDLINE_HELP "Command line options for NetIDMgr are :\n\n-a or --autoinit: Auto initialize credentials\n-i or --kinit: Obtain new credentials\n-d or --destroy: Destroy default identity\n-r or --renew: Renew all credentials" + IDS_PACTION_NEXT "Next alert..." + IDS_ERR_TITLE_NO_IDENTPRO "Cannot proceed without identity provider" +END + +STRINGTABLE +BEGIN + IDS_ERR_MSG_NO_IDENTPRO "There is no identity provider currently loaded. The identity provider is the component of Network Identity Manager that verifies and performs operations on actual identities. Without this provider, many critical operations cannot be performed." + IDS_ERR_SUGG_NO_IDENTPRO + "This is quite possibly caused by the identity provider module failing to load properly." + IDS_NC_REN_FAILED_TITLE "Failed to renew credentials" + IDS_CW_DEFAULT "(Default)" END #endif // English (U.S.) resources diff --git a/src/windows/identity/ui/main.c b/src/windows/identity/ui/main.c index b92c540b5..4f1aa7d5d 100644 --- a/src/windows/identity/ui/main.c +++ b/src/windows/identity/ui/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -41,13 +41,13 @@ void khm_init_gui(void) { khui_init_rescache(); khui_init_menu(); khui_init_toolbar(); - khui_init_notifier(); + khm_init_notifier(); khm_init_config(); } void khm_exit_gui(void) { khm_exit_config(); - khui_exit_notifier(); + khm_exit_notifier(); khui_exit_toolbar(); khui_exit_menu(); khui_exit_rescache(); @@ -67,31 +67,36 @@ void khm_parse_commandline(void) { for (i=1; i= 0x501) ICC_LINK_CLASS | - ICC_LISTVIEW_CLASSES | ICC_STANDARD_CLASSES | +#endif + ICC_LISTVIEW_CLASSES | ICC_TAB_CLASSES; InitCommonControlsEx(&ics); @@ -184,7 +191,7 @@ void khm_enter_modal(HWND hwnd) { } } - khui_main_window_active = IsWindowEnabled(khm_hwnd_main); + khui_main_window_active = khm_is_main_window_active(); EnableWindow(khm_hwnd_main, FALSE); khui_modal_dialog = hwnd; @@ -200,7 +207,9 @@ void khm_leave_modal(void) { } } - EnableWindow(khm_hwnd_main, khui_main_window_active); + EnableWindow(khm_hwnd_main, TRUE); + if (khui_main_window_active) + SetForegroundWindow(khm_hwnd_main); khui_modal_dialog = NULL; } @@ -225,15 +234,15 @@ void khm_del_dialog(HWND dlg) { BOOL khm_check_dlg_message(LPMSG pmsg) { int i; + BOOL found = FALSE; for(i=0;iseverity == KHERR_ERROR || + e->severity == KHERR_WARNING) && + e->short_desc && + e->long_desc) { + + khui_alert_create_empty(&a); + + khui_alert_set_severity(a, e->severity); + khui_alert_set_title(a, e->short_desc); + khui_alert_set_message(a, e->long_desc); + if (e->suggestion) + khui_alert_set_suggestion(a, e->suggestion); + + khui_alert_queue(a); + + khui_alert_release(a); + } + } + + kherr_remove_ctx_handler(khm_module_load_ctx_handler, + c->serial); +} + +void khm_load_default_modules(void) { + kherr_context * c; + + _begin_task(KHERR_CF_TRANSITIVE); + + kmm_load_default_modules(); + + c = kherr_peek_context(); + kherr_add_ctx_handler(khm_module_load_ctx_handler, + KHERR_CTX_END, + c->serial); + kherr_release_context(c); + + _end_task(); +} + int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, @@ -350,6 +410,14 @@ int WINAPI WinMain(HINSTANCE hInstance, khc_load_schema(NULL, schema_uiconfig); if(!slave) { + + /* set this so that we don't accidently invoke an API that + inadvertently puts up the new creds dialog at an + inopportune moment, like, say, during the new creds dialog + is open. This only affects this process, and any child + processes started by plugins. */ + SetEnvironmentVariable(L"KERBEROSLOGIN_NEVER_PROMPT", L"1"); + /* we only open a main window if this is the only instance of the application that is running. */ kmq_init(); @@ -359,7 +427,7 @@ int WINAPI WinMain(HINSTANCE hInstance, kmq_set_completion_handler(KMSG_CRED, kmsg_cred_completion); /* load the standard plugins */ - kmm_load_default_modules(); + khm_load_default_modules(); khm_register_window_classes(); @@ -438,5 +506,11 @@ int WINAPI WinMain(HINSTANCE hInstance, CloseHandle(hmap); } +#if 0 + /* writes a report of memory leaks to the specified file. Should + only be enabled on development versions. */ + PDUMP("memleak.txt"); +#endif + return rv; } diff --git a/src/windows/identity/ui/mainmenu.c b/src/windows/identity/ui/mainmenu.c index 6115204f3..c7bf94da1 100644 --- a/src/windows/identity/ui/mainmenu.c +++ b/src/windows/identity/ui/mainmenu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -147,7 +147,8 @@ static HMENU mm_create_menu_from_def(khui_menu_def * def) { hm = CreatePopupMenu(); act = def->items; i = 0; - while(act->action != KHUI_MENU_END) { + while((def->n_items == -1 && act->action != KHUI_MENU_END) || + (def->n_items >= 0 && i < (int) def->n_items)) { add_action_to_menu(hm,khui_find_action(act->action),i,act->flags); act++; i++; } @@ -223,7 +224,6 @@ LRESULT khm_menu_activate(int menu_id) { TB_SETHOTITEM, menu_id, 0); - khm_menu_track_current(); @@ -321,7 +321,7 @@ LRESULT khm_menu_handle_select(WPARAM wParam, LPARAM lParam) { if((HIWORD(wParam) == 0xffff && lParam == 0) || (HIWORD(wParam) & MF_POPUP)) { /* the menu was closed */ - khui_statusbar_set_text(KHUI_SBPART_INFO, NULL); + khm_statusbar_set_part(KHUI_SBPART_INFO, NULL, NULL); } else { khui_action * act; int id; @@ -330,12 +330,12 @@ LRESULT khm_menu_handle_select(WPARAM wParam, LPARAM lParam) { id = LOWORD(wParam); act = khui_find_action(id); if(act == NULL || act->is_tooltip == 0) - khui_statusbar_set_text(KHUI_SBPART_INFO, NULL); + khm_statusbar_set_part(KHUI_SBPART_INFO, NULL, NULL); else { LoadString(khm_hInstance, act->is_tooltip, buf, ARRAYLENGTH(buf)); - khui_statusbar_set_text(KHUI_SBPART_INFO, buf); + khm_statusbar_set_part(KHUI_SBPART_INFO, NULL, buf); } } return 0; @@ -429,7 +429,7 @@ LRESULT khm_menu_notify_main(LPNMHDR notice) { ret = TBDDRET_DEFAULT; break; - case TBN_HOTITEMCHANGE: + case TBN_HOTITEMCHANGE: { LPNMTBHOTITEM nmhi; int new_item = -1; @@ -485,21 +485,24 @@ void khm_menu_create_main(HWND rebar) { mm = mmdef->items; nmm = (int) khui_action_list_length(mm); - hwtb = CreateWindowEx( - TBSTYLE_EX_MIXEDBUTTONS, - TOOLBARCLASSNAME, - (LPWSTR) NULL, - WS_CHILD | - CCS_ADJUSTABLE | - TBSTYLE_FLAT | - TBSTYLE_AUTOSIZE | - TBSTYLE_LIST | - CCS_NORESIZE | - CCS_NOPARENTALIGN | - CCS_NODIVIDER, - 0, 0, 0, 0, rebar, - (HMENU) NULL, khm_hInstance, - NULL); + hwtb = CreateWindowEx(0 +#if (_WIN32_IE >= 0x0501) + | TBSTYLE_EX_MIXEDBUTTONS +#endif + , + TOOLBARCLASSNAME, + (LPWSTR) NULL, + WS_CHILD | + CCS_ADJUSTABLE | + TBSTYLE_FLAT | + TBSTYLE_AUTOSIZE | + TBSTYLE_LIST | + CCS_NORESIZE | + CCS_NOPARENTALIGN | + CCS_NODIVIDER, + 0, 0, 0, 0, rebar, + (HMENU) NULL, khm_hInstance, + NULL); if(!hwtb) { #ifdef DEBUG diff --git a/src/windows/identity/ui/mainmenu.h b/src/windows/identity/ui/mainmenu.h index 7cd8e01ca..59638cdd4 100644 --- a/src/windows/identity/ui/mainmenu.h +++ b/src/windows/identity/ui/mainmenu.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/ui/mainwnd.c b/src/windows/identity/ui/mainwnd.c index 0f5c7e043..5fbd1ec9b 100644 --- a/src/windows/identity/ui/mainwnd.c +++ b/src/windows/identity/ui/mainwnd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -94,6 +94,7 @@ LRESULT CALLBACK khm_main_wnd_proc( case WM_DESTROY: kmq_unsubscribe_hwnd(KMSG_ACT, hwnd); kmq_unsubscribe_hwnd(KMSG_CRED, hwnd); + HtmlHelp(NULL, NULL, HH_CLOSE_ALL, 0); PostQuitMessage(0); break; @@ -105,15 +106,21 @@ LRESULT CALLBACK khm_main_wnd_proc( return khm_toolbar_notify(lpnm); } else if(lpnm->hwndFrom == khm_hwnd_rebar) { return khm_rebar_notify(lpnm); + } else if(lpnm->hwndFrom == khm_hwnd_statusbar) { + return khm_statusbar_notify(lpnm); } break; + case WM_HELP: + MessageBox(khm_hwnd_main, L"WM_HELP", L"Notice", MB_OK); + break; + case WM_COMMAND: switch(LOWORD(wParam)) { /* general actions */ case KHUI_ACTION_VIEW_REFRESH: + khm_cred_refresh(); InvalidateRect(khm_hwnd_main_cred, NULL, FALSE); - kmq_post_message(KMSG_CRED, KMSG_CRED_REFRESH, 0, NULL); return 0; case KHUI_ACTION_PASSWD_ID: @@ -168,6 +175,21 @@ LRESULT CALLBACK khm_main_wnd_proc( } break; + case KHUI_ACTION_HELP_CTX: + HtmlHelp(khm_hwnd_main, NIDM_HELPFILE, + HH_HELP_CONTEXT, IDH_WELCOME); + break; + + case KHUI_ACTION_HELP_CONTENTS: + HtmlHelp(khm_hwnd_main, NIDM_HELPFILE, + HH_DISPLAY_TOC, 0); + break; + + case KHUI_ACTION_HELP_INDEX: + HtmlHelp(khm_hwnd_main, NIDM_HELPFILE, + HH_DISPLAY_INDEX, (DWORD_PTR) L""); + break; + case KHUI_ACTION_HELP_ABOUT: khm_create_about_window(); break; @@ -223,6 +245,7 @@ LRESULT CALLBACK khm_main_wnd_proc( case KHUI_PACTION_DELETE: + case KHUI_PACTION_SELALL: case KHUI_ACTION_LAYOUT_ID: case KHUI_ACTION_LAYOUT_TYPE: case KHUI_ACTION_LAYOUT_LOC: @@ -301,10 +324,10 @@ LRESULT CALLBACK khm_main_wnd_proc( /* resize the rebar control */ SendMessage(khm_hwnd_rebar, WM_SIZE, 0, 0); - khui_update_statusbar(hwnd); + khm_update_statusbar(hwnd); GetWindowRect(khm_hwnd_rebar, &r_rebar); - GetWindowRect(khui_hwnd_statusbar, &r_status); + GetWindowRect(khm_hwnd_statusbar, &r_status); /* the cred window fills the area between the rebar and the status bar */ @@ -383,6 +406,9 @@ LRESULT CALLBACK khm_main_wnd_proc( } else if (m->type == KMSG_CRED && m->subtype == KMSG_CRED_REFRESH) { mw_restart_refresh_timer(hwnd); + } else if (m->type == KMSG_CRED && + m->subtype == KMSG_CRED_ADDR_CHANGE) { + khm_cred_addr_change(); } else if (m->type == KMSG_KMM && m->subtype == KMSG_KMM_I_DONE) { kmq_post_message(KMSG_ACT, KMSG_ACT_BEGIN_CMDLINE, 0, 0); @@ -442,13 +468,14 @@ LRESULT CALLBACK khm_null_wnd_proc( LRESULT khm_rebar_notify(LPNMHDR lpnm) { switch(lpnm->code) { +#if (_WIN32_WINNT >= 0x0501) case RBN_AUTOBREAK: { LPNMREBARAUTOBREAK lpra = (LPNMREBARAUTOBREAK) lpnm; lpra->fAutoBreak = TRUE; } break; - +#endif case RBN_BEGINDRAG: { LPNMREBAR lprb = (LPNMREBAR) lpnm; @@ -505,7 +532,7 @@ void khm_create_main_window_controls(HWND hwnd_main) { /* self attach */ khm_menu_create_main(hwRebar); khm_create_standard_toolbar(hwRebar); - khui_create_statusbar(hwnd_main); + khm_create_statusbar(hwnd_main); /* manual attach */ khm_hwnd_main_cred = khm_create_credwnd(hwnd_main); @@ -517,7 +544,8 @@ void khm_create_main_window(void) { khm_handle csp_mw = NULL; int x,y,width,height; - LoadString(khm_hInstance, IDS_MAIN_WINDOW_TITLE, buf, sizeof(buf)/sizeof(buf[0])); + LoadString(khm_hInstance, IDS_MAIN_WINDOW_TITLE, + buf, ARRAYLENGTH(buf)); khm_hwnd_null = CreateWindow(MAKEINTATOM(khm_null_window_class), @@ -573,8 +601,6 @@ void khm_create_main_window(void) { NULL, NULL); - if (!khm_hwnd_main) - return; } void khm_show_main_window(void) { @@ -587,8 +613,14 @@ void khm_show_main_window(void) { SetForegroundWindow(khm_hwnd_main); } - ShowWindow(khm_hwnd_main, khm_nCmdShow); - UpdateWindow(khm_hwnd_main); + if (khm_nCmdShow == SW_SHOWMINIMIZED || + khm_nCmdShow == SW_SHOWMINNOACTIVE || + khm_nCmdShow == SW_MINIMIZE) { + khm_hide_main_window(); + } else { + ShowWindow(khm_hwnd_main, khm_nCmdShow); + UpdateWindow(khm_hwnd_main); + } khm_nCmdShow = SW_RESTORE; } @@ -597,11 +629,13 @@ void khm_hide_main_window(void) { khm_handle csp_notices = NULL; khm_int32 show_warning = FALSE; - if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow\\Notices", + if (khm_nCmdShow != SW_MINIMIZE && + KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow\\Notices", KHM_PERM_WRITE, &csp_notices)) && KHM_SUCCEEDED(khc_read_int32(csp_notices, L"MinimizeWarning", &show_warning)) && show_warning != 0) { + khui_alert * alert; wchar_t title[KHUI_MAXCCH_TITLE]; wchar_t msg[KHUI_MAXCCH_MESSAGE]; diff --git a/src/windows/identity/ui/mainwnd.h b/src/windows/identity/ui/mainwnd.h index cdaac1e96..95b28b733 100644 --- a/src/windows/identity/ui/mainwnd.h +++ b/src/windows/identity/ui/mainwnd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/ui/newcredwnd.c b/src/windows/identity/ui/newcredwnd.c index 4b6ce08bf..6852846fb 100644 --- a/src/windows/identity/ui/newcredwnd.c +++ b/src/windows/identity/ui/newcredwnd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -244,7 +244,7 @@ nc_update_credtext(khui_nc_wnd_data * d) HWND hw = NULL; size_t cch = 0; - ctbuf = malloc(NC_MAXCB_CREDTEXT); + ctbuf = PMALLOC(NC_MAXCB_CREDTEXT); assert(ctbuf != NULL); @@ -308,7 +308,7 @@ nc_update_credtext(khui_nc_wnd_data * d) a comma separated string */ /* d->nc->n_identities is at least 2 */ - ids_string = malloc((KCDB_IDENT_MAXCB_NAME + sizeof(id_fmt)) * + ids_string = PMALLOC((KCDB_IDENT_MAXCB_NAME + sizeof(id_fmt)) * (d->nc->n_identities - 1)); cb_ids_string = (KCDB_IDENT_MAXCB_NAME + sizeof(id_fmt)) * @@ -365,7 +365,7 @@ nc_update_credtext(khui_nc_wnd_data * d) StringCbPrintf(buf, NC_MAXCB_CREDTEXT - cch*sizeof(wchar_t), main_fmt, id_string, ids_string); - free(ids_string); + PFREE(ids_string); } } else { LoadString(khm_hInstance, IDS_NC_CREDTEXT_ID_NONE, @@ -393,7 +393,7 @@ nc_update_credtext(khui_nc_wnd_data * d) SetDlgItemText(d->dlg_main, IDC_NC_CREDTEXT, ctbuf); - free(ctbuf); + PFREE(ctbuf); /* so depending on whether the primary identity was found to be invalid, we need to disable the Ok button and set the title to @@ -471,7 +471,7 @@ nc_handle_wm_create(HWND hwnd, lpc = (LPCREATESTRUCT) lParam; - ncd = malloc(sizeof(*ncd)); + ncd = PMALLOC(sizeof(*ncd)); ZeroMemory(ncd, sizeof(*ncd)); c = (khui_new_creds *) lpc->lpCreateParams; @@ -821,7 +821,7 @@ nc_handle_wm_destroy(HWND hwnd, d->dlg_main = NULL; d->dlg_ts = NULL; - free(d); + PFREE(d); return TRUE; } @@ -1188,7 +1188,7 @@ static LRESULT nc_handle_wm_nc_notify(HWND hwnd, &cbsize, KCDB_TS_SHORT) == KHM_ERROR_TOO_LONG) { - name = malloc(cbsize); + name = PMALLOC(cbsize); kcdb_credtype_describe(d->nc->types[i]->type, name, &cbsize, @@ -1235,7 +1235,7 @@ static LRESULT nc_handle_wm_nc_notify(HWND hwnd, x += width; if(!(d->nc->types[i]->name)) - free(name); + PFREE(name); /* Now set the position of the type panel */ ShowWindow(d->nc->types[i]->hwnd_panel, SW_HIDE); diff --git a/src/windows/identity/ui/newcredwnd.h b/src/windows/identity/ui/newcredwnd.h index d0b676422..22505bc74 100644 --- a/src/windows/identity/ui/newcredwnd.h +++ b/src/windows/identity/ui/newcredwnd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/ui/notifier.c b/src/windows/identity/ui/notifier.c index 0ebdbd4cb..c795245b1 100644 --- a/src/windows/identity/ui/notifier.c +++ b/src/windows/identity/ui/notifier.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -37,6 +37,8 @@ /* notifier message for notification icon */ #define KHUI_WM_NOTIFIER WM_COMMAND +#define KHUI_ALERT_QUEUE_MAX 64 + /* window class registration atom for message only notifier window class */ ATOM atom_notifier = 0; @@ -51,6 +53,70 @@ BOOL notifier_ready = FALSE; khui_alert * current_alert = NULL; +khui_alert * alert_queue[KHUI_ALERT_QUEUE_MAX]; +khm_int32 alert_queue_head = 0; +khm_int32 alert_queue_tail = 0; + +#define is_alert_queue_empty() (alert_queue_head == alert_queue_tail) +#define is_alert_queue_full() (((alert_queue_tail + 1) % KHUI_ALERT_QUEUE_MAX) == alert_queue_head) + +static void +add_to_alert_queue(khui_alert * a) { + if (is_alert_queue_full()) return; + alert_queue[alert_queue_tail++] = a; + khui_alert_hold(a); + alert_queue_tail %= KHUI_ALERT_QUEUE_MAX; +} + +static khui_alert * +del_from_alert_queue(void) { + khui_alert * a; + + if (is_alert_queue_empty()) return NULL; + a = alert_queue[alert_queue_head++]; + alert_queue_head %= KHUI_ALERT_QUEUE_MAX; + + return a; /* held */ +} + +static khui_alert * +peek_alert_queue(void) { + if (is_alert_queue_empty()) return NULL; + return alert_queue[alert_queue_head]; +} + +static void +check_for_queued_alerts(void) { + if (!is_alert_queue_empty()) { + khui_alert * a; + + a = peek_alert_queue(); + + if (a->title) { + HICON hi; + int res; + + if (a->severity == KHERR_ERROR) + res = OIC_ERROR; + else if (a->severity == KHERR_WARNING) + res = OIC_WARNING; + else + res = OIC_INFORMATION; + + hi = LoadImage(0, MAKEINTRESOURCE(res), + IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), + LR_SHARED); + + khm_statusbar_set_part(KHUI_SBPART_NOTICE, + hi, + a->title); + } + } else { + khm_statusbar_set_part(KHUI_SBPART_NOTICE, + NULL, NULL); + } +} + /* forward dcls */ static khm_int32 @@ -62,6 +128,9 @@ alert_show_minimized(khui_alert * a); static khm_int32 alert_show_normal(khui_alert * a); +static khm_int32 +alert_enqueue(khui_alert * a); + /********************************************************************** Notifier *********************************************************************** @@ -87,17 +156,41 @@ notifier_wnd_proc(HWND hwnd, if(m->type == KMSG_ALERT) { /* handle notifier messages */ switch(m->subtype) { - case KMSG_ALERT_SHOW: - rv = alert_show((khui_alert *) m->vparam); - khui_alert_release((khui_alert *) m->vparam); - break; + case KMSG_ALERT_SHOW: + rv = alert_show((khui_alert *) m->vparam); + khui_alert_release((khui_alert *) m->vparam); + break; + + case KMSG_ALERT_QUEUE: + rv = alert_enqueue((khui_alert *) m->vparam); + khui_alert_release((khui_alert *) m->vparam); + break; + + case KMSG_ALERT_CHECK_QUEUE: + check_for_queued_alerts(); + break; + + case KMSG_ALERT_SHOW_QUEUED: + if (current_alert == NULL) { + khui_alert * a; + + a = del_from_alert_queue(); + if (a) { + rv = alert_show(a); + check_for_queued_alerts(); + khui_alert_release(a); + } + } + break; } } else if (m->type == KMSG_CRED && m->subtype == KMSG_CRED_ROOTDELTA) { + KillTimer(hwnd, KHUI_REFRESH_TIMER_ID); SetTimer(hwnd, KHUI_REFRESH_TIMER_ID, KHUI_REFRESH_TIMEOUT, NULL); + } return kmq_wm_end(m, rv); @@ -140,26 +233,30 @@ notifier_wnd_proc(HWND hwnd, khm_show_main_window(); break; +#if (_WIN32_IE >= 0x0501) case NIN_BALLOONUSERCLICK: if (current_alert) { if ((current_alert->flags & KHUI_ALERT_FLAG_DEFACTION) && current_alert->n_alert_commands > 0) { PostMessage(khm_hwnd_main, WM_COMMAND, - MAKEWPARAM(current_alert->alert_commands[0], 0), + MAKEWPARAM(current_alert->alert_commands[0], + 0), 0); - } else if (current_alert->flags & KHUI_ALERT_FLAG_REQUEST_WINDOW) { + } else if (current_alert->flags & + KHUI_ALERT_FLAG_REQUEST_WINDOW) { khm_show_main_window(); alert_show_normal(current_alert); } } /* fallthrough */ case NIN_BALLOONTIMEOUT: - khui_notify_icon_change(KHERR_NONE); + khm_notify_icon_change(KHERR_NONE); if (current_alert) { khui_alert_release(current_alert); current_alert = NULL; } break; +#endif } } else if (uMsg == WM_TIMER) { if (wParam == KHUI_TRIGGER_TIMER_ID) { @@ -175,7 +272,7 @@ notifier_wnd_proc(HWND hwnd, } ATOM -khui_register_notifier_wnd_class(void) +khm_register_notifier_wnd_class(void) { WNDCLASSEX wcx; @@ -315,10 +412,12 @@ alert_show_minimized(khui_alert * a) { a->flags |= KHUI_ALERT_FLAG_DISPLAY_BALLOON; +#if (_WIN32_IE >= 0x0501) current_alert = a; khui_alert_hold(a); +#endif - khui_notify_icon_balloon(a->severity, + khm_notify_icon_balloon(a->severity, tbuf, mbuf, NTF_TIMEOUT); @@ -340,10 +439,14 @@ alert_show_normal(khui_alert * a) { title = a->title; /* if we don't have any commands, we just add a "close" button */ - if(a->n_alert_commands == 0) { + if (a->n_alert_commands == 0) { khui_alert_add_command(a, KHUI_PACTION_CLOSE); } + if (!is_alert_queue_empty()) { + khui_alert_add_command(a, KHUI_PACTION_NEXT); + } + /* we don't need to keep track of the window handle because the window procedure adds it to the dialog list automatically */ @@ -365,6 +468,12 @@ alert_show_normal(khui_alert * a) { static khm_int32 alert_show(khui_alert * a) { + /* is there an alert already? If so, we just enqueue the message + and let it sit. */ + if (current_alert) { + return alert_enqueue(a); + } + /* the window has already been shown */ if((a->flags & KHUI_ALERT_FLAG_DISPLAY_WINDOW) || ((a->flags & KHUI_ALERT_FLAG_DISPLAY_BALLOON) && @@ -387,6 +496,17 @@ alert_show(khui_alert * a) { return alert_show_minimized(a); } +static khm_int32 +alert_enqueue(khui_alert * a) { + if (is_alert_queue_full()) + return KHM_ERROR_NO_RESOURCES; + + add_to_alert_queue(a); + check_for_queued_alerts(); + + return KHM_ERROR_SUCCESS; +} + /* the alerter window is actually a dialog */ static LRESULT CALLBACK alerter_wnd_proc(HWND hwnd, @@ -410,7 +530,7 @@ alerter_wnd_proc(HWND hwnd, a = (khui_alert *) lpcs->lpCreateParams; khui_alert_hold(a); - d = malloc(sizeof(*d)); + d = PMALLOC(sizeof(*d)); ZeroMemory(d, sizeof(*d)); d->alert = a; @@ -570,7 +690,7 @@ alerter_wnd_proc(HWND hwnd, } } - khui_notify_icon_change(a->severity); + khm_notify_icon_change(a->severity); khui_alert_unlock(a); @@ -603,9 +723,9 @@ alerter_wnd_proc(HWND hwnd, DeleteObject(d->hfont); - free(d); + PFREE(d); - khui_notify_icon_change(KHERR_NONE); + khm_notify_icon_change(KHERR_NONE); return TRUE; } @@ -659,7 +779,7 @@ alerter_wnd_proc(HWND hwnd, hicon = LoadImage(NULL, MAKEINTRESOURCE(iid), IMAGE_ICON, - SM_CXICON, SM_CYICON, + GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); DrawIcon(hdc, x, y, hicon); @@ -718,7 +838,7 @@ alerter_wnd_proc(HWND hwnd, CopyRect(&ro, &r); // adjust for icon and padding - r.left += SM_CXICON + d->dx_suggest_pad * 2; + r.left += GetSystemMetrics(SM_CXSMICON) + d->dx_suggest_pad * 2; r.top += d->dx_suggest_pad; r.right -= d->dx_suggest_pad; r.bottom -= d->dx_suggest_pad; @@ -748,7 +868,7 @@ alerter_wnd_proc(HWND hwnd, LoadImage(0, MAKEINTRESOURCE(OIC_INFORMATION), IMAGE_ICON, - SM_CXICON, SM_CYICON, + GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED); assert(h_sug_ico != NULL); @@ -757,7 +877,7 @@ alerter_wnd_proc(HWND hwnd, ro.left + d->dx_suggest_pad, ro.top + d->dx_suggest_pad, h_sug_ico, - SM_CXICON, SM_CYICON, + GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0, NULL, DI_NORMAL); @@ -847,6 +967,9 @@ alerter_wnd_proc(HWND hwnd, khm_leave_modal(); DestroyWindow(hwnd); + + if (LOWORD(wParam) == KHUI_PACTION_NEXT) + kmq_post_message(KMSG_ALERT, KMSG_ALERT_SHOW_QUEUED, 0, 0); return 0; } } @@ -857,14 +980,18 @@ alerter_wnd_proc(HWND hwnd, //return DefWindowProc(hwnd, uMsg, wParam, lParam); } -ATOM khui_register_alerter_wnd_class(void) +ATOM khm_register_alerter_wnd_class(void) { WNDCLASSEX wcx; ZeroMemory(&wcx, sizeof(wcx)); wcx.cbSize = sizeof(wcx); - wcx.style = CS_DROPSHADOW | CS_OWNDC; + wcx.style = +#if(_WIN32_WINNT >= 0x0501) + CS_DROPSHADOW | +#endif + CS_OWNDC; wcx.lpfnWndProc = alerter_wnd_proc; wcx.cbClsExtra = 0; wcx.cbWndExtra = DLGWINDOWEXTRA + sizeof(LONG_PTR); @@ -887,7 +1014,7 @@ ATOM khui_register_alerter_wnd_class(void) #define KHUI_NOTIFY_ICON_ID 0 -void khui_notify_icon_add(void) { +void khm_notify_icon_add(void) { NOTIFYICONDATA ni; wchar_t buf[256]; @@ -914,7 +1041,7 @@ void khui_notify_icon_add(void) { } void -khui_notify_icon_balloon(khm_int32 severity, +khm_notify_icon_balloon(khm_int32 severity, wchar_t * title, wchar_t * msg, khm_int32 timeout) { @@ -970,7 +1097,7 @@ khui_notify_icon_balloon(khm_int32 severity, DestroyIcon(ni.hIcon); } -void khui_notify_icon_change(khm_int32 severity) { +void khm_notify_icon_change(khm_int32 severity) { NOTIFYICONDATA ni; wchar_t buf[256]; int iid; @@ -1004,7 +1131,7 @@ void khui_notify_icon_change(khm_int32 severity) { DestroyIcon(ni.hIcon); } -void khui_notify_icon_remove(void) { +void khm_notify_icon_remove(void) { NOTIFYICONDATA ni; ZeroMemory(&ni, sizeof(ni)); @@ -1020,12 +1147,12 @@ void khui_notify_icon_remove(void) { Initialization **********************************************************************/ -void khui_init_notifier(void) +void khm_init_notifier(void) { - if(!khui_register_notifier_wnd_class()) + if(!khm_register_notifier_wnd_class()) return; - if(!khui_register_alerter_wnd_class()) + if(!khm_register_alerter_wnd_class()) return; hwnd_notifier = CreateWindowEx(0, @@ -1043,7 +1170,7 @@ void khui_init_notifier(void) kmq_subscribe_hwnd(KMSG_CRED, hwnd_notifier); notifier_ready = TRUE; - khui_notify_icon_add(); + khm_notify_icon_add(); } #ifdef DEBUG else { @@ -1051,14 +1178,18 @@ void khui_init_notifier(void) } #endif khm_timer_init(); + + khm_addr_change_notifier_init(); } -void khui_exit_notifier(void) +void khm_exit_notifier(void) { + khm_addr_change_notifier_exit(); + khm_timer_exit(); if(hwnd_notifier != NULL) { - khui_notify_icon_remove(); + khm_notify_icon_remove(); kmq_unsubscribe_hwnd(KMSG_ALERT, hwnd_notifier); kmq_unsubscribe_hwnd(KMSG_CRED, hwnd_notifier); DestroyWindow(hwnd_notifier); diff --git a/src/windows/identity/ui/notifier.h b/src/windows/identity/ui/notifier.h index bfe9656b8..de9fb60fa 100644 --- a/src/windows/identity/ui/notifier.h +++ b/src/windows/identity/ui/notifier.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -28,16 +28,16 @@ #define __KHIMAIRA_NOTIFIER_H void -khui_init_notifier(void); +khm_init_notifier(void); void -khui_exit_notifier(void); +khm_exit_notifier(void); void -khui_notify_icon_change(khm_int32 severity); +khm_notify_icon_change(khm_int32 severity); void -khui_notify_icon_balloon(khm_int32 severity, +khm_notify_icon_balloon(khm_int32 severity, wchar_t * title, wchar_t * msg, khm_int32 timeout); diff --git a/src/windows/identity/ui/passwnd.h b/src/windows/identity/ui/passwnd.h index f8c17f68e..b0adcf689 100644 --- a/src/windows/identity/ui/passwnd.h +++ b/src/windows/identity/ui/passwnd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/ui/propertywnd.c b/src/windows/identity/ui/propertywnd.c index fe603c015..79a6cc35a 100644 --- a/src/windows/identity/ui/propertywnd.c +++ b/src/windows/identity/ui/propertywnd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -66,7 +66,7 @@ void pw_update_property_data(HWND hw, pw_data * d) &attr_count))) return; - attrs = malloc(sizeof(khm_int32) * attr_count); + attrs = PMALLOC(sizeof(khm_int32) * attr_count); assert(attrs != NULL); kcdb_attrib_get_ids( @@ -77,7 +77,7 @@ void pw_update_property_data(HWND hw, pw_data * d) &attr_count); cb_buf = sizeof(wchar_t) * 2048; - buffer = malloc(cb_buf); + buffer = PMALLOC(cb_buf); assert(buffer != NULL); for(i=0; irecord); - free(child); + PFREE(child); } break; diff --git a/src/windows/identity/ui/propertywnd.h b/src/windows/identity/ui/propertywnd.h index 67250c96d..89305dd7b 100644 --- a/src/windows/identity/ui/propertywnd.h +++ b/src/windows/identity/ui/propertywnd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/ui/reqdaemon.c b/src/windows/identity/ui/reqdaemon.c index b73ec4820..620bdc54e 100644 --- a/src/windows/identity/ui/reqdaemon.c +++ b/src/windows/identity/ui/reqdaemon.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -172,7 +172,7 @@ reqdaemonwnd_proc(HWND hwnd, #ifdef DEBUG assert(FALSE); #endif - rv = KHM_ERROR_INVALID_PARM; + rv = KHM_ERROR_INVALID_PARAM; goto _exit_tgt_with_lparam; } @@ -185,7 +185,7 @@ reqdaemonwnd_proc(HWND hwnd, #ifdef DEBUG assert(FALSE); #endif - rv = KHM_ERROR_INVALID_PARM; + rv = KHM_ERROR_INVALID_PARAM; goto _exit_tgt_with_lparam; } @@ -198,7 +198,7 @@ reqdaemonwnd_proc(HWND hwnd, #ifdef DEBUG assert(FALSE); #endif - rv = KHM_ERROR_INVALID_PARM; + rv = KHM_ERROR_INVALID_PARAM; goto _exit_tgt_with_lparam; } @@ -212,7 +212,7 @@ reqdaemonwnd_proc(HWND hwnd, if (FAILED(StringCbPrintf(widname, sizeof(widname), L"%hs@%hs", username, realm))) { - rv = KHM_ERROR_INVALID_PARM; + rv = KHM_ERROR_INVALID_PARAM; goto _exit_tgt_with_lparam; } diff --git a/src/windows/identity/ui/reqdaemon.h b/src/windows/identity/ui/reqdaemon.h index 13b0ebd2c..b55e93c99 100644 --- a/src/windows/identity/ui/reqdaemon.h +++ b/src/windows/identity/ui/reqdaemon.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/ui/resource.h b/src/windows/identity/ui/resource.h index a58cebb8d..4bee5f206 100644 --- a/src/windows/identity/ui/resource.h +++ b/src/windows/identity/ui/resource.h @@ -1,6 +1,6 @@ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. -// Used by D:\work\khimaira\src\ui\lang\en_us\khapp.rc +// Used by D:\work\pismere\athena\auth\krb5\src\windows\identity\ui\lang\en_us\khapp.rc // #define IDI_MAIN_APP 104 #define IDD_PROPPAGE_MEDIUM 106 @@ -94,9 +94,7 @@ #define IDS_NC_CREDTEXT_ID_MANY 148 #define IDB_LOGO_SHADE 149 #define IDS_NC_CREDTEXT_ID_INVALID 149 -#define IDI_WGT_COLLAPSE 150 #define IDS_WTPOST_INIT_CREDS 150 -#define IDI_WGT_EXPAND 151 #define IDS_WTPOST_NEW_CREDS 151 #define IDB_WDG_EXPAND 152 #define IDS_ACTION_RENEW_CRED 152 @@ -191,9 +189,13 @@ #define IDS_CFG_ID_TAB_SHORT 197 #define IDB_TB_SPACE 197 #define IDS_CFG_ID_TAB_LONG 198 +#define IDB_WDG_STUCK_HI 198 #define IDS_CFG_IDS_TAB_SHORT 199 +#define IDB_WDG_STICK 199 #define IDS_CFG_IDS_TAB_LONG 200 +#define IDB_WDG_STICK_HI 200 #define IDS_CFG_IDS_IDENTITY 201 +#define IDB_WDG_STUCK 201 #define IDS_ACTION_IMPORT 202 #define IDS_CTX_IMPORT 203 #define IDS_CFG_PI_COL_PLUGINS 204 @@ -214,6 +216,12 @@ #define IDS_CTX_PROC_PASSWORD 219 #define IDS_NC_PWD_FAILED_TITLE 220 #define IDS_CMDLINE_HELP 221 +#define IDS_PACTION_NEXT 222 +#define IDS_ERR_TITLE_NO_IDENTPRO 223 +#define IDS_ERR_MSG_NO_IDENTPRO 224 +#define IDS_ERR_SUGG_NO_IDENTPRO 225 +#define IDS_NC_REN_FAILED_TITLE 226 +#define IDS_CW_DEFAULT 227 #define IDC_NC_USERNAME 1007 #define IDC_NC_PASSWORD 1008 #define IDC_NC_CREDTEXT_LABEL 1009 @@ -293,6 +301,7 @@ #define IDC_BUILDINFO 1102 #define IDC_LIST1 1103 #define IDC_MODULES 1103 +#define IDC_PP_CONFIG 1104 #define IDA_ACTIVATE_MENU 40003 #define IDA_UP 40004 #define IDA_DOWN 40005 @@ -305,9 +314,9 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 198 +#define _APS_NEXT_RESOURCE_VALUE 202 #define _APS_NEXT_COMMAND_VALUE 40010 -#define _APS_NEXT_CONTROL_VALUE 1104 +#define _APS_NEXT_CONTROL_VALUE 1105 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/src/windows/identity/ui/statusbar.c b/src/windows/identity/ui/statusbar.c index 75f520c57..9a2f8e79c 100644 --- a/src/windows/identity/ui/statusbar.c +++ b/src/windows/identity/ui/statusbar.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -26,17 +26,41 @@ #include -khui_statusbar_part khui_statusbar_parts[] = { +khm_statusbar_part khm_statusbar_parts[] = { {KHUI_SBPART_INFO, 0, KHUI_SB_WTYPE_FILLER}, {KHUI_SBPART_NOTICE, 40, KHUI_SB_WTYPE_RELATIVE}, {KHUI_SBPART_LOC, 40, KHUI_SB_WTYPE_ABSOLUTE} }; -int khui_n_statusbar_parts = sizeof(khui_statusbar_parts) / sizeof(khui_statusbar_part); +int khm_n_statusbar_parts = sizeof(khm_statusbar_parts) / sizeof(khm_statusbar_part); -HWND khui_hwnd_statusbar = NULL; +HWND khm_hwnd_statusbar = NULL; -void khui_statusbar_set_parts(HWND parent) { +LRESULT +khm_statusbar_notify(LPNMHDR nmhdr) { + LPNMMOUSE pnmm; + + switch(nmhdr->code) { + case NM_CLICK: + case NM_DBLCLK: + pnmm = (LPNMMOUSE) nmhdr; + + if (pnmm->dwItemSpec >= (DWORD) khm_n_statusbar_parts) + return TRUE; + + if (khm_statusbar_parts[pnmm->dwItemSpec].id == KHUI_SBPART_NOTICE) { + /* means, show next notification */ + kmq_post_message(KMSG_ALERT, KMSG_ALERT_SHOW_QUEUED, 0, 0); + } + + return TRUE; + } + + return FALSE; +} + +void +khui_statusbar_set_parts(HWND parent) { int i; int fillerwidth; int staticwidth; @@ -50,28 +74,28 @@ void khui_statusbar_set_parts(HWND parent) { /* calculate fillerwidth and staticwidth */ staticwidth = 0; - for(i=0;i= 0); @@ -426,12 +431,37 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { khc_close_space(csp_id); if (monitor && do_renew) { + int prev; + TimetToFileTimeInterval(to_renew, (LPFILETIME) &ft); fte = ft_expiry - ft; - if (fte > ft_current) { - tmr_update(ident, KHUI_TTYPE_ID_RENEW, fte, ft, 0); + prev = + tmr_find(ident, KHUI_TTYPE_ID_RENEW, 0, 0); + + /* we set off a renew notification immediately if the + renew threshold has passed but a renew was never sent. + This maybe because that NetIDMgr was started at the + last minute, or because for some reason the renew timer + could not be triggered earlier. */ + if (fte > ft_current || + prev == -1 || + !(khui_timers[prev].flags & KHUI_TE_FLAG_EXPIRED)) { + + if (fte <= ft_current) + fte = ft_current; + + tmr_update(ident, KHUI_TTYPE_ID_RENEW, + fte, ft, 0, fte > ft_current + ft_reinst); renew_done = TRUE; + } else { + /* special case. If the renew timer was in the past + and it was expired, then we retain the record as + long as the credentials are around. If the renewal + failed we don't want to automatically retry + everytime we check the timers. */ + tmr_update(ident, KHUI_TTYPE_ID_RENEW, + fte, ft, 0, FALSE); } } @@ -440,7 +470,8 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { fte = ft_expiry - ft; if (fte > ft_current) - tmr_update(ident, KHUI_TTYPE_ID_WARN, fte, ft, 0); + tmr_update(ident, KHUI_TTYPE_ID_WARN, + fte, ft, 0, fte > ft_current + ft_reinst); } if (monitor && do_crit && !renew_done) { @@ -448,12 +479,14 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { fte = ft_expiry - ft; if (fte > ft_current) - tmr_update(ident, KHUI_TTYPE_ID_CRIT, fte, ft, 0); + tmr_update(ident, KHUI_TTYPE_ID_CRIT, + fte, ft, 0, fte > ft_current + ft_reinst); } if (monitor && !renew_done) { if (ft_expiry > ft_current) - tmr_update(ident, KHUI_TTYPE_ID_EXP, ft_expiry, 0, 0); + tmr_update(ident, KHUI_TTYPE_ID_EXP, + ft_expiry, 0, 0, fte > ft_current + ft_reinst); } _done_with_ident: @@ -474,12 +507,13 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { goto _cleanup; if ((idx = tmr_find(ident, KHUI_TTYPE_ID_WARN, 0, 0)) >= 0 && - !(khui_timers[idx].flags & KHUI_TE_FLAG_STALE)) { + !(khui_timers[idx].flags & KHUI_TE_FLAG_STALE)) { fte = ft_cred_expiry - khui_timers[idx].offset; if (fte > ft_current) { tmr_update(cred, KHUI_TTYPE_CRED_WARN, fte, - khui_timers[idx].offset, 0); + khui_timers[idx].offset, 0, + fte > ft_current + ft_reinst); kcdb_cred_hold(cred); } } @@ -490,7 +524,8 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { fte = ft_cred_expiry - khui_timers[idx].offset; if (fte > ft_current) { tmr_update(cred, KHUI_TTYPE_CRED_CRIT, fte, - khui_timers[idx].offset, 0); + khui_timers[idx].offset, 0, + fte > ft_current + ft_reinst); kcdb_cred_hold(cred); } } @@ -501,7 +536,8 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { fte = ft_cred_expiry - khui_timers[idx].offset; if (fte > ft_current) { tmr_update(cred, KHUI_TTYPE_CRED_RENEW, fte, - khui_timers[idx].offset, 0); + khui_timers[idx].offset, 0, + fte > ft_current + ft_reinst); kcdb_cred_hold(cred); } } @@ -511,7 +547,8 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { if (ft_cred_expiry > ft_current) { tmr_update(cred, KHUI_TTYPE_CRED_EXP, ft_cred_expiry, - 0, 0); + 0, 0, + ft_cred_expiry > ft_current + ft_reinst); } } @@ -577,6 +614,7 @@ tmr_purge(void) { khui_n_timers = j; } +/* go through all the credentials and set timers as appropriate. */ void khm_timer_refresh(HWND hwnd) { int i; @@ -608,10 +646,11 @@ khm_timer_refresh(HWND hwnd) { next_event = 0; for (i=0; i < (int) khui_n_timers; i++) { - if (next_event == 0 || - (!(khui_timers[i].flags & KHUI_TE_FLAG_EXPIRED) && - khui_timers[i].type != KHUI_TTYPE_ID_MARK && + if (!(khui_timers[i].flags & KHUI_TE_FLAG_EXPIRED) && + khui_timers[i].type != KHUI_TTYPE_ID_MARK && + (next_event == 0 || next_event > khui_timers[i].expire)) + next_event = khui_timers[i].expire; } diff --git a/src/windows/identity/ui/timer.h b/src/windows/identity/ui/timer.h index 921b9dcc5..3a5791721 100644 --- a/src/windows/identity/ui/timer.h +++ b/src/windows/identity/ui/timer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/ui/toolbar.c b/src/windows/identity/ui/toolbar.c index d1a84e235..fcc0d9ebd 100644 --- a/src/windows/identity/ui/toolbar.c +++ b/src/windows/identity/ui/toolbar.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -124,8 +124,7 @@ void khui_add_action_to_toolbar(HWND tb, khui_action *a, int opt, HIMAGELIST hiL bn.fsStyle = BTNS_SEP; bn.iBitmap = 3; - lr = SendMessage( - tb, + lr = SendMessage(tb, TB_ADDBUTTONS, 1, (LPARAM) &bn); @@ -158,7 +157,9 @@ void khui_add_action_to_toolbar(HWND tb, khui_action *a, int opt, HIMAGELIST hiL TB_ADDSTRING, (WPARAM) NULL, (LPARAM) buf); +#if (_WIN32_IE >= 0x0501) bn.fsStyle |= BTNS_SHOWTEXT; +#endif bn.iString = idx_caption; } } @@ -170,8 +171,11 @@ void khui_add_action_to_toolbar(HWND tb, khui_action *a, int opt, HIMAGELIST hiL if((opt & KHUI_TOOLBAR_ADD_BITMAP) && a->ib_normal) { bn.fsStyle |= TBSTYLE_CUSTOMERASE; bn.iBitmap = khui_tb_blank; - } else + } else { +#if (_WIN32_IE >= 0x0501) bn.iBitmap = I_IMAGENONE; +#endif + } bn.idCommand = a->cmd; @@ -242,21 +246,24 @@ void khm_create_standard_toolbar(HWND rebar) { def = khui_find_menu(KHUI_TOOLBAR_STANDARD); - hwtb = CreateWindowEx( - TBSTYLE_EX_MIXEDBUTTONS, - TOOLBARCLASSNAME, - (LPWSTR) NULL, - WS_CHILD | - TBSTYLE_FLAT | - TBSTYLE_AUTOSIZE | - TBSTYLE_LIST | - CCS_NORESIZE | - CCS_NOPARENTALIGN | - CCS_ADJUSTABLE | - CCS_NODIVIDER, - 0, 0, 0, 0, rebar, - (HMENU) NULL, khm_hInstance, - NULL); + hwtb = CreateWindowEx(0 +#if (_WIN32_IE >= 0x0501) + | TBSTYLE_EX_MIXEDBUTTONS +#endif + , + TOOLBARCLASSNAME, + (LPWSTR) NULL, + WS_CHILD | + TBSTYLE_FLAT | + TBSTYLE_AUTOSIZE | + TBSTYLE_LIST | + CCS_NORESIZE | + CCS_NOPARENTALIGN | + CCS_ADJUSTABLE | + CCS_NODIVIDER, + 0, 0, 0, 0, rebar, + (HMENU) NULL, khm_hInstance, + NULL); if(!hwtb) { #ifdef DEBUG diff --git a/src/windows/identity/ui/toolbar.h b/src/windows/identity/ui/toolbar.h index 65598debc..89700f2e4 100644 --- a/src/windows/identity/ui/toolbar.h +++ b/src/windows/identity/ui/toolbar.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -49,4 +49,4 @@ void khm_update_standard_toolbar(void); #define KHUI_TOOLBAR_BGCOLOR RGB(0xd7,0xd7,0xd7) #define KHUI_TOOLBAR_MAX_BTNS 64 -#endif \ No newline at end of file +#endif diff --git a/src/windows/identity/uilib/accel.csv b/src/windows/identity/uilib/accel.csv index 80b6ad05f..05b945514 100644 --- a/src/windows/identity/uilib/accel.csv +++ b/src/windows/identity/uilib/accel.csv @@ -12,6 +12,7 @@ KHUI_PACTION_ENTER,FVIRTKEY,VK_RETURN,KHUI_ACCEL_SCOPE_GLOBAL KHUI_PACTION_ESC,FVIRTKEY,VK_ESCAPE,KHUI_ACCEL_SCOPE_GLOBAL #KHUI_PACTION_DELETE,FVIRTKEY,VK_DELETE,KHUI_ACCEL_SCOPE_GLOBAL KHUI_ACTION_DESTROY_CRED,FVIRTKEY,VK_DELETE,KHUI_ACCEL_SCOPE_GLOBAL -KHUI_ACTION_EXIT,FCONTROL,\'X\',KHUI_ACCEL_SCOPE_GLOBAL +KHUI_ACTION_EXIT,FCONTROL|FVIRTKEY,\'X\',KHUI_ACCEL_SCOPE_GLOBAL KHUI_ACTION_VIEW_REFRESH,FVIRTKEY,VK_F5,KHUI_ACCEL_SCOPE_GLOBAL -KHUI_ACTION_NEW_CRED,FCONTROL,\'N\',KHUI_ACCEL_SCOPE_GLOBAL +KHUI_ACTION_NEW_CRED,FCONTROL|FVIRTKEY,\'N\',KHUI_ACCEL_SCOPE_GLOBAL +KHUI_PACTION_SELALL,FCONTROL|FVIRTKEY,\'A\',KHUI_ACCEL_SCOPE_GLOBAL diff --git a/src/windows/identity/uilib/action.c b/src/windows/identity/uilib/action.c index cc383c689..0ebb9ae0c 100644 --- a/src/windows/identity/uilib/action.c +++ b/src/windows/identity/uilib/action.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -26,6 +26,7 @@ #define NOEXPORT #include +#include #include khui_action_ref khui_main_menu[] = { @@ -212,12 +213,13 @@ KHMEXP khui_menu_def * KHMAPI khui_menu_create(int cmd) { khui_menu_def * d; - d = malloc(sizeof(*d)); + + d = PMALLOC(sizeof(*d)); ZeroMemory(d, sizeof(*d)); d->cmd = cmd; d->nc_items = MENU_NC_ITEMS; - d->items = malloc(sizeof(*(d->items)) * d->nc_items); + d->items = PMALLOC(sizeof(*(d->items)) * d->nc_items); d->state = KHUI_MENUSTATE_ALLOCD; @@ -261,12 +263,12 @@ khui_menu_delete(khui_menu_def * d) for(i=0; i< (int) d->n_items; i++) { if(d->items[i].flags & KHUI_ACTIONREF_FREE_PACTION) - free(d->items[i].p_action); + PFREE(d->items[i].p_action); } if(d->items) - free(d->items); - free(d); + PFREE(d->items); + PFREE(d); } static void khui_menu_assert_size(khui_menu_def * d, size_t n) @@ -275,9 +277,9 @@ static void khui_menu_assert_size(khui_menu_def * d, size_t n) khui_action_ref * ni; d->nc_items = UBOUNDSS(n, MENU_NC_ITEMS, MENU_NC_ITEMS); - ni = malloc(sizeof(*(d->items)) * d->nc_items); + ni = PMALLOC(sizeof(*(d->items)) * d->nc_items); memcpy(ni, d->items, sizeof(*(d->items)) * d->n_items); - free(d->items); + PFREE(d->items); d->items = ni; } } @@ -420,7 +422,7 @@ KHMEXP void KHMAPI khui_enable_actions(khui_menu_def * d, khm_boolean enable) } if(delta) { - kmq_send_message(KMSG_ACT, KMSG_ACT_ENABLE, 0, 0); + kmq_post_message(KMSG_ACT, KMSG_ACT_ENABLE, 0, 0); } } @@ -438,7 +440,7 @@ KHMEXP void KHMAPI khui_enable_action(int cmd, khm_boolean enable) { } else return; - kmq_send_message(KMSG_ACT, KMSG_ACT_ENABLE, 0, 0); + kmq_post_message(KMSG_ACT, KMSG_ACT_ENABLE, 0, 0); } KHMEXP HACCEL KHMAPI khui_create_global_accel_table(void) { @@ -446,7 +448,7 @@ KHMEXP HACCEL KHMAPI khui_create_global_accel_table(void) { ACCEL * accels; HACCEL ha; - accels = malloc(sizeof(ACCEL) * khui_n_accel_global); + accels = PMALLOC(sizeof(ACCEL) * khui_n_accel_global); for(i=0;iint_cb_buf < cb_total) { if (ctxdest->int_buf) - free(ctxdest->int_buf); + PFREE(ctxdest->int_buf); ctxdest->int_cb_buf = cb_total; - ctxdest->int_buf = malloc(cb_total); + ctxdest->int_buf = PMALLOC(cb_total); } #ifdef DEBUG @@ -680,7 +682,7 @@ khuiint_copy_context(khui_action_context * ctxdest, khui_context_release() to free the allocated buffer */ #if 0 if (ctxsrc->vparam && ctxsrc->cb_vparam) { - ctxdest->vparam = malloc(ctxsrc->cb_vparam); + ctxdest->vparam = PMALLOC(ctxsrc->cb_vparam); #ifdef DEBUG assert(ctxdest->vparam); #endif @@ -891,11 +893,11 @@ khui_context_release(khui_action_context * ctx) } ctx->credset = NULL; if (ctx->int_buf) - free(ctx->int_buf); + PFREE(ctx->int_buf); ctx->int_buf = NULL; #if 0 if (ctx->vparam && ctx->cb_vparam > 0) { - free(ctx->vparam); + PFREE(ctx->vparam); ctx->vparam = NULL; } ctx->cb_vparam = 0; diff --git a/src/windows/identity/uilib/actions.csv b/src/windows/identity/uilib/actions.csv index e317c7cc5..371fb8798 100644 --- a/src/windows/identity/uilib/actions.csv +++ b/src/windows/identity/uilib/actions.csv @@ -35,3 +35,4 @@ KHUI_PACTION_OK,KHUI_ACTIONTYPE_TRIGGER,,0,0,0,0,0,IDS_PACTION_OK,0,0,0 KHUI_PACTION_CANCEL,KHUI_ACTIONTYPE_TRIGGER,,0,0,0,0,0,IDS_PACTION_CANCEL,0,0,0 KHUI_PACTION_CLOSE,KHUI_ACTIONTYPE_TRIGGER,,0,0,0,0,0,IDS_PACTION_CLOSE,0,0,0 KHUI_PACTION_BLANK,0,,IDB_TB_SPACE,0,IDB_TB_SPACE,IDB_TB_BLANK_SM,IDB_TB_BLANK_SM,0,0,0,KHUI_ACTIONSTATE_DISABLED +KHUI_PACTION_NEXT,KHUI_ACTIONTYPE_TRIGGER,,0,0,0,0,0,IDS_PACTION_NEXT,0,0,0 diff --git a/src/windows/identity/uilib/alert.c b/src/windows/identity/uilib/alert.c index 69ef01f93..dd096063b 100644 --- a/src/windows/identity/uilib/alert.c +++ b/src/windows/identity/uilib/alert.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -25,6 +25,7 @@ /* $Id$ */ #include +#include #include /*********************************************************************** @@ -51,7 +52,7 @@ khui_alert_create_empty(khui_alert ** result) { khui_alert * a; - a = malloc(sizeof(*a)); + a = PMALLOC(sizeof(*a)); ZeroMemory(a, sizeof(*a)); a->magic = KHUI_ALERT_MAGIC; @@ -97,21 +98,21 @@ khui_alert_set_title(khui_alert * alert, const wchar_t * title) if(title) { if(FAILED(StringCbLength(title, - KHUI_MAXCB_TITLE - sizeof(wchar_t), + KHUI_MAXCB_TITLE, &cb))) { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } cb += sizeof(wchar_t); } EnterCriticalSection(&cs_alerts); if(alert->title && (alert->flags & KHUI_ALERT_FLAG_FREE_TITLE)) { - free(alert->title); + PFREE(alert->title); alert->title = NULL; alert->flags &= ~KHUI_ALERT_FLAG_FREE_TITLE; } if(title) { - alert->title = malloc(cb); + alert->title = PMALLOC(cb); StringCbCopy(alert->title, cb, title); alert->flags |= KHUI_ALERT_FLAG_FREE_TITLE; } @@ -126,7 +127,7 @@ khui_alert_set_flags(khui_alert * alert, khm_int32 mask, khm_int32 flags) assert(alert->magic == KHUI_ALERT_MAGIC); if (mask & ~KHUI_ALERT_FLAGMASK_RDWR) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_alerts); alert->flags = @@ -160,7 +161,7 @@ khui_alert_set_suggestion(khui_alert * alert, if(FAILED(StringCbLength(suggestion, KHUI_MAXCB_MESSAGE - sizeof(wchar_t), &cb))) { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } cb += sizeof(wchar_t); } @@ -169,14 +170,14 @@ khui_alert_set_suggestion(khui_alert * alert, if(alert->suggestion && (alert->flags & KHUI_ALERT_FLAG_FREE_SUGGEST)) { - free(alert->suggestion); + PFREE(alert->suggestion); alert->suggestion = NULL; alert->flags &= ~KHUI_ALERT_FLAG_FREE_SUGGEST; } if(suggestion) { - alert->suggestion = malloc(cb); + alert->suggestion = PMALLOC(cb); StringCbCopy(alert->suggestion, cb, suggestion); alert->flags |= KHUI_ALERT_FLAG_FREE_SUGGEST; } @@ -196,7 +197,7 @@ khui_alert_set_message(khui_alert * alert, const wchar_t * message) if(FAILED(StringCbLength(message, KHUI_MAXCB_MESSAGE - sizeof(wchar_t), &cb))) { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } cb += sizeof(wchar_t); } @@ -205,14 +206,14 @@ khui_alert_set_message(khui_alert * alert, const wchar_t * message) if(alert->message && (alert->flags & KHUI_ALERT_FLAG_FREE_MESSAGE)) { - free(alert->message); + PFREE(alert->message); alert->message = NULL; alert->flags &= ~KHUI_ALERT_FLAG_FREE_MESSAGE; } if(message) { - alert->message = malloc(cb); + alert->message = PMALLOC(cb); StringCbCopy(alert->message, cb, message); alert->flags |= KHUI_ALERT_FLAG_FREE_MESSAGE; } @@ -262,6 +263,17 @@ khui_alert_show(khui_alert * alert) return KHM_ERROR_SUCCESS; } +KHMEXP khm_int32 KHMAPI +khui_alert_queue(khui_alert * alert) +{ + assert(alert->magic == KHUI_ALERT_MAGIC); + + khui_alert_hold(alert); + kmq_post_message(KMSG_ALERT, KMSG_ALERT_QUEUE, 0, (void *) alert); + + return KHM_ERROR_SUCCESS; +} + KHMEXP khm_int32 KHMAPI khui_alert_show_simple(const wchar_t * title, const wchar_t * message, @@ -303,26 +315,26 @@ free_alert(khui_alert * alert) if(alert->flags & KHUI_ALERT_FLAG_FREE_TITLE) { assert(alert->title); - free(alert->title); + PFREE(alert->title); alert->title = NULL; alert->flags &= ~KHUI_ALERT_FLAG_FREE_TITLE; } if(alert->flags & KHUI_ALERT_FLAG_FREE_MESSAGE) { assert(alert->message); - free(alert->message); + PFREE(alert->message); alert->message = NULL; alert->flags &= ~KHUI_ALERT_FLAG_FREE_MESSAGE; } if(alert->flags & KHUI_ALERT_FLAG_FREE_SUGGEST) { assert(alert->suggestion); - free(alert->suggestion); + PFREE(alert->suggestion); alert->suggestion = NULL; alert->flags &= ~KHUI_ALERT_FLAG_FREE_SUGGEST; } if(alert->flags & KHUI_ALERT_FLAG_FREE_STRUCT) { alert->flags &= ~KHUI_ALERT_FLAG_FREE_STRUCT; alert->magic = 0; - free(alert); + PFREE(alert); } } diff --git a/src/windows/identity/uilib/configui.c b/src/windows/identity/uilib/configui.c index 5c97c701f..51498c0b2 100644 --- a/src/windows/identity/uilib/configui.c +++ b/src/windows/identity/uilib/configui.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -27,6 +27,7 @@ #include #include #include +#include #include khm_int32 cfgui_node_serial; @@ -39,7 +40,7 @@ static khui_config_node_i * cfgui_create_new_node(void) { khui_config_node_i * node; - node = malloc(sizeof(*node)); + node = PMALLOC(sizeof(*node)); #ifdef DEBUG assert(node); #endif @@ -60,13 +61,13 @@ cfgui_free_node(khui_config_node_i * node) { return; if (node->reg.name) - free((void *) node->reg.name); + PFREE((void *) node->reg.name); if (node->reg.short_desc) - free((void *) node->reg.short_desc); + PFREE((void *) node->reg.short_desc); if (node->reg.long_desc) - free((void *) node->reg.long_desc); + PFREE((void *) node->reg.long_desc); node->magic = 0; @@ -75,7 +76,7 @@ cfgui_free_node(khui_config_node_i * node) { ZeroMemory(node, sizeof(*node)); - free(node); + PFREE(node); } @@ -145,7 +146,7 @@ khui_cfg_register(khui_config_node vparent, &cb_long_desc)) || (vparent && !cfgui_is_valid_node_handle(vparent))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if (KHM_SUCCEEDED(khui_cfg_open(vparent, reg->name, @@ -163,11 +164,11 @@ khui_cfg_register(khui_config_node vparent, node->reg = *reg; node->reg.flags &= KHUI_CNFLAGMASK_STATIC; - name = malloc(cb_name); + name = PMALLOC(cb_name); StringCbCopy(name, cb_name, reg->name); - short_desc = malloc(cb_short_desc); + short_desc = PMALLOC(cb_short_desc); StringCbCopy(short_desc, cb_short_desc, reg->short_desc); - long_desc = malloc(cb_long_desc); + long_desc = PMALLOC(cb_long_desc); StringCbCopy(long_desc, cb_long_desc, reg->long_desc); node->reg.name = name; @@ -204,7 +205,7 @@ khui_cfg_open(khui_config_node vparent, !cfgui_is_valid_node_handle(vparent)) || FAILED(StringCbLength(name, KHUI_MAXCCH_NAME, &sz)) || !result) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_cfgui); if (vparent) @@ -238,7 +239,7 @@ KHMEXP khm_int32 KHMAPI khui_cfg_remove(khui_config_node vnode) { khui_config_node_i * node; if (!cfgui_is_valid_node_handle(vnode)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_cfgui); node = cfgui_node_i_from_handle(vnode); @@ -251,7 +252,7 @@ khui_cfg_remove(khui_config_node vnode) { KHMEXP khm_int32 KHMAPI khui_cfg_hold(khui_config_node vnode) { if (!cfgui_is_valid_node_handle(vnode)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cfgui_hold_node(cfgui_node_i_from_handle(vnode)); @@ -261,13 +262,46 @@ khui_cfg_hold(khui_config_node vnode) { KHMEXP khm_int32 KHMAPI khui_cfg_release(khui_config_node vnode) { if (!cfgui_is_valid_node_handle(vnode)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cfgui_release_node(cfgui_node_i_from_handle(vnode)); return KHM_ERROR_SUCCESS; } +KHMEXP khm_int32 KHMAPI +khui_cfg_get_parent(khui_config_node vnode, + khui_config_node * result) { + + khui_config_node_i * node; + khui_config_node_i * parent; + + if(!cfgui_is_valid_node_handle(vnode) || + !result) + return KHM_ERROR_INVALID_PARAM; + + EnterCriticalSection(&cs_cfgui); + if (cfgui_is_valid_node_handle(vnode)) { + node = cfgui_node_i_from_handle(vnode); + parent = TPARENT(node); + if (parent == cfgui_root_config) + parent = NULL; + } else { + parent = NULL; + } + if (parent) { + cfgui_hold_node(parent); + } + LeaveCriticalSection(&cs_cfgui); + + *result = parent; + + if (parent) + return KHM_ERROR_SUCCESS; + else + return KHM_ERROR_NOT_FOUND; +} + KHMEXP khm_int32 KHMAPI khui_cfg_get_first_child(khui_config_node vparent, khui_config_node * result) { @@ -278,7 +312,7 @@ khui_cfg_get_first_child(khui_config_node vparent, if((vparent && !cfgui_is_valid_node_handle(vparent)) || !result) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_cfgui); if (cfgui_is_valid_node_handle(vparent)) { @@ -319,7 +353,7 @@ khui_cfg_get_first_subpanel(khui_config_node vparent, if((vparent && !cfgui_is_valid_node_handle(vparent)) || !result) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_cfgui); if (cfgui_is_valid_node_handle(vparent)) { @@ -360,7 +394,7 @@ khui_cfg_get_next(khui_config_node vnode, if (!cfgui_is_valid_node_handle(vnode) || !result) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_cfgui); if (cfgui_is_valid_node_handle(vnode)) { @@ -393,7 +427,7 @@ khui_cfg_get_next_release(khui_config_node * pvnode) { if (!pvnode || !cfgui_is_valid_node_handle(*pvnode)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_cfgui); if (cfgui_is_valid_node_handle(*pvnode)) { @@ -429,7 +463,7 @@ khui_cfg_get_reg(khui_config_node vnode, if ((vnode && !cfgui_is_valid_node_handle(vnode)) || !reg) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_cfgui); if (cfgui_is_valid_node_handle(vnode)) { @@ -447,7 +481,7 @@ khui_cfg_get_reg(khui_config_node vnode, if (node) return KHM_ERROR_SUCCESS; else - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } KHMEXP HWND KHMAPI @@ -575,7 +609,7 @@ get_node_data(khui_config_node_i * node, #ifdef DEBUG assert(node->nc_data >= node->n_data + 1); #endif - newdata = malloc(sizeof(*newdata) * node->nc_data); + newdata = PMALLOC(sizeof(*newdata) * node->nc_data); #ifdef DEBUG assert(newdata); #endif @@ -583,7 +617,7 @@ get_node_data(khui_config_node_i * node, if (node->data && node->n_data > 0) { memcpy(newdata, node->data, node->n_data * sizeof(*newdata)); - free(node->data); + PFREE(node->data); } node->data = newdata; } @@ -790,11 +824,12 @@ khui_cfg_set_flags(khui_config_node vnode, /* called with cs_cfgui held */ static void -recalc_node_flags(khui_config_node vnode) { +recalc_node_flags(khui_config_node vnode, khm_boolean plural) { khui_config_node_i * node; khui_config_node_i * parent; + khui_config_node_i * subpanel; + cfg_node_data * data; khm_int32 flags; - khm_size i; #ifdef DEBUG assert(cfgui_is_valid_node_handle(vnode)); @@ -802,33 +837,43 @@ recalc_node_flags(khui_config_node vnode) { node = cfgui_node_i_from_handle(vnode); - parent = TPARENT(node); + if (plural) + parent = TPARENT(node); + else + parent = node; #ifdef DEBUG assert(parent); #endif flags = 0; - /* this code is wrong. we need to go through all the subpanels in - the parent and pick the data record corresponding to this node - and then merge the flags from there. */ - /* TODO: fix this */ - for (i=0; i < parent->n_data; i++) { - if (parent->data[i].key == vnode) - flags |= parent->data[i].flags; + for(subpanel = TFIRSTCHILD(parent); subpanel; + subpanel = LNEXT(subpanel)) { + if (!(subpanel->reg.flags & KHUI_CNFLAG_SUBPANEL) || + (plural && !(subpanel->reg.flags & KHUI_CNFLAG_PLURAL)) || + (!plural && (subpanel->reg.flags & KHUI_CNFLAG_PLURAL))) + continue; + + data = get_node_data(subpanel, + vnode, + FALSE); + + if (data) { + flags |= data->flags; + } } flags &= KHUI_CNFLAGMASK_DYNAMIC; - if ((node->flags & flags) != flags) { - node->flags = flags | - (node->flags & ~KHUI_CNFLAGMASK_DYNAMIC); + if ((node->flags & KHUI_CNFLAGMASK_DYNAMIC) == flags) + return; + + node->flags = (node->flags & ~KHUI_CNFLAGMASK_DYNAMIC) | flags; - if (hwnd_cfgui) - PostMessage(hwnd_cfgui, KHUI_WM_CFG_NOTIFY, - MAKEWPARAM((WORD) node->flags, WMCFG_UPDATE_STATE), - (LPARAM) vnode); - } + if (hwnd_cfgui) + PostMessage(hwnd_cfgui, KHUI_WM_CFG_NOTIFY, + MAKEWPARAM((WORD) node->flags, WMCFG_UPDATE_STATE), + (LPARAM) vnode); } KHMEXP void KHMAPI @@ -862,7 +907,9 @@ khui_cfg_set_flags_inst(khui_config_init_data * d, data->flags = new_flags; if (d->ctx_node != d->ref_node) - recalc_node_flags(d->ctx_node); + recalc_node_flags(d->ctx_node, TRUE); + else + recalc_node_flags(d->ctx_node, FALSE); } } } @@ -900,7 +947,7 @@ khui_cfg_get_name(khui_config_node vnode, if (!cb_buf || !cfgui_is_valid_node_handle(vnode)) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_cfgui); if (cfgui_is_valid_node_handle(vnode) && @@ -919,7 +966,7 @@ khui_cfg_get_name(khui_config_node vnode, *cb_buf = cb; } } else { - rv = KHM_ERROR_INVALID_PARM; + rv = KHM_ERROR_INVALID_PARAM; } LeaveCriticalSection(&cs_cfgui); @@ -936,7 +983,7 @@ khui_cfg_init_dialog_data(HWND hwnd_dlg, khui_config_init_data * d; cb = sizeof(khui_config_init_data) + cb_extra; - d = malloc(cb); + d = PMALLOC(cb); #ifdef DEBUG assert(d); #endif @@ -994,7 +1041,7 @@ khui_cfg_free_dialog_data(HWND hwnd_dlg) { #endif if (d) { - free(d); + PFREE(d); } return (d)?KHM_ERROR_SUCCESS: KHM_ERROR_NOT_FOUND; diff --git a/src/windows/identity/uilib/configui.h b/src/windows/identity/uilib/configui.h index 37d5e9705..c7ff88bdb 100644 --- a/src/windows/identity/uilib/configui.h +++ b/src/windows/identity/uilib/configui.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/uilib/creddlg.c b/src/windows/identity/uilib/creddlg.c index ccc27b401..2cb4e92f9 100644 --- a/src/windows/identity/uilib/creddlg.c +++ b/src/windows/identity/uilib/creddlg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -25,6 +25,7 @@ /* $Id$ */ #include +#include #include #define CW_ALLOC_INCR 8 @@ -46,7 +47,7 @@ khui_cw_create_cred_blob(khui_new_creds ** ppnc) { khui_new_creds * c; - c = malloc(sizeof(*c)); + c = PMALLOC(sizeof(*c)); ZeroMemory(c, sizeof(*c)); c->magic = KHUI_NC_MAGIC; @@ -73,22 +74,25 @@ khui_cw_destroy_cred_blob(khui_new_creds *c) LeaveCriticalSection(&c->cs); DeleteCriticalSection(&c->cs); - if(c->password) { + if (c->password) { len = wcslen(c->password); SecureZeroMemory(c->password, sizeof(wchar_t) * len); - free(c->password); + PFREE(c->password); } - if(c->identities) - free(c->identities); + if (c->identities) + PFREE(c->identities); - if(c->types) - free(c->types); + if (c->types) + PFREE(c->types); + + if (c->type_subs) + PFREE(c->type_subs); if (c->window_title) - free(c->window_title); + PFREE(c->window_title); - free(c); + PFREE(c); return KHM_ERROR_SUCCESS; } @@ -121,7 +125,7 @@ khui_cw_add_identity(khui_new_creds * c, if(c->identities == NULL) { c->nc_identities = NC_N_IDENTITIES; - c->identities = malloc(sizeof(*(c->identities)) * + c->identities = PMALLOC(sizeof(*(c->identities)) * c->nc_identities); c->n_identities = 0; } else if(c->n_identities + 1 > c->nc_identities) { @@ -130,10 +134,10 @@ khui_cw_add_identity(khui_new_creds * c, c->nc_identities = UBOUNDSS(c->n_identities + 1, NC_N_IDENTITIES, NC_N_IDENTITIES); - ni = malloc(sizeof(*(c->identities)) * c->nc_identities); + ni = PMALLOC(sizeof(*(c->identities)) * c->nc_identities); memcpy(ni, c->identities, sizeof(*(c->identities)) * c->n_identities); - free(c->identities); + PFREE(c->identities); c->identities = ni; } @@ -187,8 +191,8 @@ khui_cw_add_type(khui_new_creds * c, if(c->types == NULL) { c->nc_types = CW_ALLOC_INCR; - c->types = malloc(sizeof(*(c->types)) * c->nc_types); - c->type_subs = malloc(sizeof(*(c->type_subs)) * c->nc_types); + c->types = PMALLOC(sizeof(*(c->types)) * c->nc_types); + c->type_subs = PMALLOC(sizeof(*(c->type_subs)) * c->nc_types); c->n_types = 0; } @@ -198,14 +202,14 @@ khui_cw_add_type(khui_new_creds * c, n = UBOUNDSS(c->n_types + 1, CW_ALLOC_INCR, CW_ALLOC_INCR); - t = malloc(sizeof(*(c->types)) * n); + t = PMALLOC(sizeof(*(c->types)) * n); memcpy(t, (void *) c->types, sizeof(*(c->types)) * c->n_types); - free(c->types); + PFREE(c->types); c->types = t; - t = malloc(sizeof(*(c->type_subs)) * n); + t = PMALLOC(sizeof(*(c->type_subs)) * n); memcpy(t, (void *) c->type_subs, sizeof(*(c->type_subs)) * c->n_types); - free(c->type_subs); + PFREE(c->type_subs); c->type_subs = t; c->nc_types = n; @@ -329,22 +333,22 @@ cw_create_prompt(khm_size idx, if(def && FAILED(StringCbLength(def, KHUI_MAXCB_PROMPT_VALUE, &cb_def))) return NULL; - p = malloc(sizeof(*p)); + p = PMALLOC(sizeof(*p)); ZeroMemory(p, sizeof(*p)); if(prompt) { cb_prompt += sizeof(wchar_t); - p->prompt = malloc(cb_prompt); + p->prompt = PMALLOC(cb_prompt); StringCbCopy(p->prompt, cb_prompt, prompt); } if(def) { cb_def += sizeof(wchar_t); - p->def = malloc(cb_def); + p->def = PMALLOC(cb_def); StringCbCopy(p->def, cb_def, def); } - p->value = malloc(KHUI_MAXCB_PROMPT_VALUE); + p->value = PMALLOC(KHUI_MAXCB_PROMPT_VALUE); ZeroMemory(p->value, KHUI_MAXCB_PROMPT_VALUE); p->type = type; @@ -361,22 +365,22 @@ cw_free_prompt(khui_new_creds_prompt * p) { if(p->prompt) { if(SUCCEEDED(StringCbLength(p->prompt, KHUI_MAXCB_PROMPT, &cb))) SecureZeroMemory(p->prompt, cb); - free(p->prompt); + PFREE(p->prompt); } if(p->def) { if(SUCCEEDED(StringCbLength(p->def, KHUI_MAXCB_PROMPT, &cb))) SecureZeroMemory(p->def, cb); - free(p->def); + PFREE(p->def); } if(p->value) { if(SUCCEEDED(StringCbLength(p->value, KHUI_MAXCB_PROMPT_VALUE, &cb))) SecureZeroMemory(p->value, cb); - free(p->value); + PFREE(p->value); } - free(p); + PFREE(p); } static void @@ -385,12 +389,12 @@ cw_free_prompts(khui_new_creds * c) khm_size i; if(c->banner != NULL) { - free(c->banner); + PFREE(c->banner); c->banner = NULL; } if(c->pname != NULL) { - free(c->pname); + PFREE(c->pname); c->pname = NULL; } @@ -402,7 +406,7 @@ cw_free_prompts(khui_new_creds * c) } if(c->prompts != NULL) { - free(c->prompts); + PFREE(c->prompts); c->prompts = NULL; } @@ -443,7 +447,7 @@ khui_cw_begin_custom_prompts(khui_new_creds * c, if(SUCCEEDED(StringCbLength(banner, KHUI_MAXCB_BANNER, &cb)) && cb > 0) { cb += sizeof(wchar_t); - c->banner = malloc(cb); + c->banner = PMALLOC(cb); StringCbCopy(c->banner, cb, banner); } else { c->banner = NULL; @@ -453,7 +457,7 @@ khui_cw_begin_custom_prompts(khui_new_creds * c, cb > 0) { cb += sizeof(wchar_t); - c->pname = malloc(cb); + c->pname = PMALLOC(cb); StringCbCopy(c->pname, cb, pname); } else { @@ -463,8 +467,7 @@ khui_cw_begin_custom_prompts(khui_new_creds * c, } if(n_prompts > 0) { - - c->prompts = malloc(sizeof(*(c->prompts)) * n_prompts); + c->prompts = PMALLOC(sizeof(*(c->prompts)) * n_prompts); ZeroMemory(c->prompts, sizeof(*(c->prompts)) * n_prompts); c->nc_prompts = n_prompts; c->n_prompts = 0; @@ -505,7 +508,7 @@ khui_cw_add_prompt(khui_new_creds * c, p = cw_create_prompt(c->n_prompts, type, prompt, def, flags); if(p == NULL) { LeaveCriticalSection(&c->cs); - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } c->prompts[c->n_prompts++] = p; LeaveCriticalSection(&c->cs); @@ -637,6 +640,7 @@ khui_cw_set_response(khui_new_creds * c, if(t) { t->flags &= ~KHUI_NCMASK_RESULT; t->flags |= (response & KHUI_NCMASK_RESULT); + if (!(response & KHUI_NC_RESPONSE_NOEXIT) && !(response & KHUI_NC_RESPONSE_PENDING)) t->flags |= KHUI_NC_RESPONSE_COMPLETED; @@ -666,6 +670,6 @@ khui_cw_add_control_row(khui_new_creds * c, return KHM_ERROR_SUCCESS; } else { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } } diff --git a/src/windows/identity/uilib/khaction.h b/src/windows/identity/uilib/khaction.h index 7b7c22a57..fccdab549 100644 --- a/src/windows/identity/uilib/khaction.h +++ b/src/windows/identity/uilib/khaction.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/uilib/khactiondef.h b/src/windows/identity/uilib/khactiondef.h index d01eb2add..b880721b6 100644 --- a/src/windows/identity/uilib/khactiondef.h +++ b/src/windows/identity/uilib/khactiondef.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -89,6 +89,8 @@ context. #define KHUI_PACTION_DOWN_EXTEND (KHUI_PACTION_BASE + 13) #define KHUI_PACTION_DOWN_TOGGLE (KHUI_PACTION_BASE + 14) #define KHUI_PACTION_BLANK (KHUI_PACTION_BASE + 15) +#define KHUI_PACTION_NEXT (KHUI_PACTION_BASE + 16) +#define KHUI_PACTION_SELALL (KHUI_PACTION_BASE + 17) /*@}*/ /*! \name Menus diff --git a/src/windows/identity/uilib/khalerts.h b/src/windows/identity/uilib/khalerts.h index c41dddf1f..36b13a333 100644 --- a/src/windows/identity/uilib/khalerts.h +++ b/src/windows/identity/uilib/khalerts.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -306,6 +306,16 @@ khui_alert_add_command(khui_alert * alert, KHMEXP khm_int32 KHMAPI khui_alert_show(khui_alert * alert); +/*! \brief Queue an alert + + Instead of displaying the alert immediately, the alert is queued + and the status bar updated to notify the user that there is a + pending alert. Once the user activates the pending alert, it will + be displayed as if khui_alert_show() was called. + */ +KHMEXP khm_int32 KHMAPI +khui_alert_queue(khui_alert * alert); + /*! \brief Display a simple alert \see khui_alert_show() diff --git a/src/windows/identity/uilib/khconfigui.h b/src/windows/identity/uilib/khconfigui.h index 9a96d41f9..ac9fc614c 100644 --- a/src/windows/identity/uilib/khconfigui.h +++ b/src/windows/identity/uilib/khconfigui.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -246,7 +246,7 @@ typedef struct tag_khui_config_init_data { required. \retval KHM_ERROR_SUCCESS Success - \retval KHM_ERROR_INVALID_PARM One or more parameters, or fields + \retval KHM_ERROR_INVALID_PARAM One or more parameters, or fields of reg were invalid \retval KHM_ERROR_DUPLICATE A node with the same name exists as a child of the specified parent node. @@ -293,6 +293,19 @@ khui_cfg_hold(khui_config_node node); KHMEXP khm_int32 KHMAPI khui_cfg_release(khui_config_node node); +/*! \brief Get the parent of a node + + Returns a held handle to the parent of the node, or NULL if the + current node is a top level node. The returned handle must be + released with khui_cfg_release(). + + \retval KHM_ERROR_SUCCESS The handle to the parent node is in \a result + \retval KHM_ERROR_NOT_FOUND The node is a top level node + */ +KHMEXP khm_int32 KHMAPI +khui_cfg_get_parent(khui_config_node vnode, + khui_config_node * result); + /*! \brief Get a handle to the first child node If the call is successful, \a result will receieve a handle to the @@ -366,7 +379,7 @@ khui_cfg_get_next(khui_config_node node, the function is released. \retval KHM_ERROR_SUCCESS The next node is now in \a node - \retval KHM_ERROR_INVALID_PARM \a node was not a valid handle + \retval KHM_ERROR_INVALID_PARAM \a node was not a valid handle \retval KHM_ERROR_NOT_FOUND There are no more siblings. \a node is set to NULL. diff --git a/src/windows/identity/uilib/khhtlink.h b/src/windows/identity/uilib/khhtlink.h index dcbf328ff..f5fb3deef 100644 --- a/src/windows/identity/uilib/khhtlink.h +++ b/src/windows/identity/uilib/khhtlink.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/uilib/khnewcred.h b/src/windows/identity/uilib/khnewcred.h index 1742f4a1a..ff693b3b1 100644 --- a/src/windows/identity/uilib/khnewcred.h +++ b/src/windows/identity/uilib/khnewcred.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -146,6 +146,12 @@ enum khui_wm_nc_notifications { internal message. */ }; +/*! \brief Plugins can use WMNC_NOTIFY message codes from here on up + + \see ::KHUI_WM_NC_NOTIFY + */ +#define WMNC_USER 2048 + /*! \brief Notifications to the identity provider These notifications are sent through to the identity provider's UI diff --git a/src/windows/identity/uilib/khprops.h b/src/windows/identity/uilib/khprops.h index b77269021..fc5629dc9 100644 --- a/src/windows/identity/uilib/khprops.h +++ b/src/windows/identity/uilib/khprops.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -141,7 +141,12 @@ khui_ps_create_sheet(khui_property_sheet ** sheet); used to order the pages in a property sheet. The pages are ordered based on ordinal first and then alphabetically by credentials type name. If the type is unavailable, then the - ordering is undefined. + ordering is undefined. Ordinals for credential type property + pages can be in the range from 0 to 127. Ordinals 128 and + above are reserved. Passing in 0 will work for credentials + providers unless they provide more than one property page per + credential, in which case the ordinal should be used to + enforce an order. \param[in] ppage Pointer to structure that will be passed to CreatePropertySheetPage() to create the property page. The diff --git a/src/windows/identity/uilib/khremote.h b/src/windows/identity/uilib/khremote.h index a5b9d67de..accff416b 100644 --- a/src/windows/identity/uilib/khremote.h +++ b/src/windows/identity/uilib/khremote.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/uilib/khrescache.h b/src/windows/identity/uilib/khrescache.h index 96bec88ab..eeb4f6585 100644 --- a/src/windows/identity/uilib/khrescache.h +++ b/src/windows/identity/uilib/khrescache.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/uilib/khtracker.h b/src/windows/identity/uilib/khtracker.h index f03d2b425..c12cd4fac 100644 --- a/src/windows/identity/uilib/khtracker.h +++ b/src/windows/identity/uilib/khtracker.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -77,6 +77,7 @@ typedef struct tag_khui_tracker { int lbl_y; int lbl_lx; int lbl_rx; + DWORD act_time; time_t current; /*!< Current selection */ time_t min; /*!< Minimum (inclusive) */ diff --git a/src/windows/identity/uilib/khuidefs.h b/src/windows/identity/uilib/khuidefs.h index d92eb6444..50214c373 100644 --- a/src/windows/identity/uilib/khuidefs.h +++ b/src/windows/identity/uilib/khuidefs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/uilib/propsheet.c b/src/windows/identity/uilib/propsheet.c index 749aa53bf..705dd96a3 100644 --- a/src/windows/identity/uilib/propsheet.c +++ b/src/windows/identity/uilib/propsheet.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -25,15 +25,29 @@ /* $Id$ */ #include +#include #ifdef DEBUG #include #endif -KHMEXP khm_int32 KHMAPI khui_ps_create_sheet(khui_property_sheet ** sheet) +CRITICAL_SECTION cs_props; + +void +ps_init(void) { + InitializeCriticalSection(&cs_props); +} + +void +ps_exit(void) { + DeleteCriticalSection(&cs_props); +} + +KHMEXP khm_int32 KHMAPI +khui_ps_create_sheet(khui_property_sheet ** sheet) { khui_property_sheet * ps; - ps = malloc(sizeof(*ps)); + ps = PMALLOC(sizeof(*ps)); ZeroMemory(ps, sizeof(*ps)); ps->header.dwSize = sizeof(ps->header); @@ -45,24 +59,26 @@ KHMEXP khm_int32 KHMAPI khui_ps_create_sheet(khui_property_sheet ** sheet) return KHM_ERROR_SUCCESS; } -KHMEXP khm_int32 KHMAPI khui_ps_add_page( - khui_property_sheet * sheet, - khm_int32 credtype, - khm_int32 ordinal, - LPPROPSHEETPAGE ppage, - khui_property_page ** page) +KHMEXP khm_int32 KHMAPI +khui_ps_add_page(khui_property_sheet * sheet, + khm_int32 credtype, + khm_int32 ordinal, + LPPROPSHEETPAGE ppage, + khui_property_page ** page) { khui_property_page * p; - p = malloc(sizeof(*p)); + p = PMALLOC(sizeof(*p)); ZeroMemory(p, sizeof(*p)); p->credtype = credtype; p->ordinal = ordinal; p->p_page = ppage; - + + EnterCriticalSection(&cs_props); QPUT(sheet, p); sheet->n_pages++; + LeaveCriticalSection(&cs_props); if(page) *page = p; @@ -70,13 +86,14 @@ KHMEXP khm_int32 KHMAPI khui_ps_add_page( return KHM_ERROR_SUCCESS; } -KHMEXP khm_int32 KHMAPI khui_ps_find_page( - khui_property_sheet * sheet, - khm_int32 credtype, - khui_property_page ** page) +KHMEXP khm_int32 KHMAPI +khui_ps_find_page(khui_property_sheet * sheet, + khm_int32 credtype, + khui_property_page ** page) { khui_property_page * p; + EnterCriticalSection(&cs_props); p = QTOP(sheet); while(p) { @@ -84,6 +101,7 @@ KHMEXP khm_int32 KHMAPI khui_ps_find_page( break; p = QNEXT(p); } + LeaveCriticalSection(&cs_props); if(p) { *page = p; @@ -94,12 +112,22 @@ KHMEXP khm_int32 KHMAPI khui_ps_find_page( } } -int __cdecl ps_order_func(const void *l, const void * r) { - /* l is a ** */ - return 0; +int __cdecl +ps_order_func(const void *l, const void * r) { + khui_property_page * lp; + khui_property_page * rp; + + lp = *(khui_property_page **)l; + rp = *(khui_property_page **)r; + + if (lp->ordinal == rp->ordinal) + return lp->credtype - rp->credtype; + else + return lp->ordinal - rp->ordinal; } -KHMEXP HWND KHMAPI khui_ps_show_sheet(HWND parent, khui_property_sheet * s) +KHMEXP HWND KHMAPI +khui_ps_show_sheet(HWND parent, khui_property_sheet * s) { khui_property_page * p; HPROPSHEETPAGE phpsp[KHUI_PS_MAX_PSP]; @@ -108,6 +136,8 @@ KHMEXP HWND KHMAPI khui_ps_show_sheet(HWND parent, khui_property_sheet * s) INT_PTR prv; HWND hw; + EnterCriticalSection(&cs_props); + s->header.hwndParent = parent; s->header.nPages = s->n_pages; @@ -118,16 +148,26 @@ KHMEXP HWND KHMAPI khui_ps_show_sheet(HWND parent, khui_property_sheet * s) #ifdef DEBUG assert(p->h_page); #endif - ppgs[i] = p; - phpsp[i++] = p->h_page; + ppgs[i++] = p; p = QNEXT(p); } - /*TODO: sort property sheets */ +#ifdef DEBUG + assert(i == s->n_pages); +#endif + + qsort(ppgs, s->n_pages, sizeof(ppgs[0]), ps_order_func); + + for (i=0; i < s->n_pages; i++) { + phpsp[i] = ppgs[i]->h_page; + } s->header.phpage = phpsp; prv = PropertySheet(&s->header); + + s->header.phpage = NULL; + if(prv <= 0) { #ifdef DEBUG assert(FALSE); @@ -135,22 +175,20 @@ KHMEXP HWND KHMAPI khui_ps_show_sheet(HWND parent, khui_property_sheet * s) /*TODO: better handling for this */ hw = NULL; } else { - DWORD dw; - - dw = GetLastError(); s->status = KHUI_PS_STATUS_RUNNING; hw = (HWND) prv; s->hwnd = hw; s->hwnd_page = PropSheet_GetCurrentPageHwnd(hw); } + LeaveCriticalSection(&cs_props); return hw; } -KHMEXP LRESULT KHMAPI khui_ps_check_message( - khui_property_sheet * sheet, - PMSG pmsg) +KHMEXP LRESULT KHMAPI +khui_ps_check_message(khui_property_sheet * sheet, + PMSG pmsg) { LRESULT lr; @@ -169,20 +207,24 @@ KHMEXP LRESULT KHMAPI khui_ps_check_message( return lr; } -KHMEXP khm_int32 KHMAPI khui_ps_destroy_sheet(khui_property_sheet * sheet) +KHMEXP khm_int32 KHMAPI +khui_ps_destroy_sheet(khui_property_sheet * sheet) { khui_property_page * p; + EnterCriticalSection(&cs_props); + DestroyWindow(sheet->hwnd); sheet->hwnd = NULL; QGET(sheet, &p); while(p) { - free(p); + PFREE(p); QGET(sheet, &p); } + PFREE(sheet); - free(sheet); + LeaveCriticalSection(&cs_props); return KHM_ERROR_SUCCESS; } diff --git a/src/windows/identity/uilib/propwnd.c b/src/windows/identity/uilib/propwnd.c index 4d5d5488d..5ae93a7a5 100644 --- a/src/windows/identity/uilib/propwnd.c +++ b/src/windows/identity/uilib/propwnd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/uilib/rescache.c b/src/windows/identity/uilib/rescache.c index 57ff30907..6d5259142 100644 --- a/src/windows/identity/uilib/rescache.c +++ b/src/windows/identity/uilib/rescache.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -25,7 +25,7 @@ /* $Id$ */ #include -#include +#include hashtable * h_bitmaps; @@ -76,7 +76,7 @@ khui_create_ilist(int cx, int cy, int n, int ng, int opt) { BITMAPV5HEADER head; HDC hdc; - khui_ilist * il = malloc(sizeof(khui_ilist)); + khui_ilist * il = PMALLOC(sizeof(khui_ilist)); il->cx = cx; il->cy = cy; il->n = n; @@ -102,7 +102,7 @@ khui_create_ilist(int cx, int cy, int n, int ng, int opt) { head.bV5Reserved = 0; il->img = CreateDIBitmap(hdc, (BITMAPINFOHEADER *) &head, 0, NULL, NULL, DIB_RGB_COLORS); il->mask = CreateBitmap(cx * n, cy, 1, 1, NULL); - il->idlist = malloc(sizeof(int) * n); + il->idlist = PMALLOC(sizeof(int) * n); return il; } @@ -111,8 +111,8 @@ KHMEXP BOOL KHMAPI khui_delete_ilist(khui_ilist * il) { DeleteObject(il->img); DeleteObject(il->mask); - free(il->idlist); - free(il); + PFREE(il->idlist); + PFREE(il); return TRUE; } diff --git a/src/windows/identity/uilib/trackerwnd.c b/src/windows/identity/uilib/trackerwnd.c index 04de09641..814e28808 100644 --- a/src/windows/identity/uilib/trackerwnd.c +++ b/src/windows/identity/uilib/trackerwnd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -261,7 +261,10 @@ create_edit_sliders(HWND hwnd, TRACKBAR_CLASS, L"NetIDMgrTimeTickerTrackbar", WS_POPUP | TBS_AUTOTICKS | TBS_BOTTOM | - TBS_DOWNISLEFT | TBS_HORZ | WS_CLIPCHILDREN, +#if (_WIN32_IE >= 0x0501) + TBS_DOWNISLEFT | +#endif + TBS_HORZ | WS_CLIPCHILDREN, r.left,r.bottom,rs.right,rs.bottom, hwnd, NULL, @@ -311,6 +314,8 @@ duration_edit_proc(HWND hwnd, } khui_tracker_reposition(tc); ShowWindow(tc->hw_slider, SW_SHOWNOACTIVATE); + + tc->act_time = GetTickCount(); //SetActiveWindow(p); } break; @@ -347,6 +352,18 @@ duration_edit_proc(HWND hwnd, } return TRUE; + case WM_LBUTTONUP: + if (IsWindowVisible(tc->hw_slider)) { + DWORD tm; + + tm = GetTickCount(); + if (tm - tc->act_time > 500) + ShowWindow(tc->hw_slider, SW_HIDE); + } else { + ShowWindow(tc->hw_slider, SW_SHOWNOACTIVATE); + } + break; + /* these messages can potentially change the text in the edit control. We intercept them and see what changed. We may need to grab and handle them */ @@ -354,7 +371,9 @@ duration_edit_proc(HWND hwnd, case EM_UNDO: case WM_UNDO: case WM_CHAR: +#if (_WIN32_WINNT >= 0x0501) case WM_UNICHAR: +#endif { wchar_t buf[256]; size_t nchars; diff --git a/src/windows/identity/uilib/uilibmain.c b/src/windows/identity/uilib/uilibmain.c index 65fa7aff5..4d0b012f1 100644 --- a/src/windows/identity/uilib/uilibmain.c +++ b/src/windows/identity/uilib/uilibmain.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -28,14 +28,17 @@ extern void alert_init(void); extern void alert_exit(void); +extern void ps_init(void); +extern void ps_exit(void); void uilib_process_attach(void) { alert_init(); + ps_init(); } void uilib_process_detach(void) { + ps_exit(); alert_exit(); } - diff --git a/src/windows/identity/util/Makefile b/src/windows/identity/util/Makefile index b9fc80e20..9d1cad2f0 100644 --- a/src/windows/identity/util/Makefile +++ b/src/windows/identity/util/Makefile @@ -26,15 +26,17 @@ MODULE=util !include <../config/Makefile.w32> INCFILES= \ - $(INCDIR)\utils.h \ - $(INCDIR)\hashtable.h \ - $(INCDIR)\mstring.h \ - $(INCDIR)\sync.h + $(INCDIR)\utils.h \ + $(INCDIR)\hashtable.h \ + $(INCDIR)\mstring.h \ + $(INCDIR)\sync.h \ + $(INCDIR)\perfstat.h OBJFILES= \ - $(OBJ)\hashtable.obj \ - $(OBJ)\mstring.obj \ - $(OBJ)\sync.obj + $(OBJ)\hashtable.obj \ + $(OBJ)\mstring.obj \ + $(OBJ)\sync.obj \ + $(OBJ)\perfstat.obj LIBFILES= diff --git a/src/windows/identity/util/hashtable.c b/src/windows/identity/util/hashtable.c index 41f785a95..d1b02e64f 100644 --- a/src/windows/identity/util/hashtable.c +++ b/src/windows/identity/util/hashtable.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -24,6 +24,7 @@ /* $Id$ */ +#include #include #include @@ -35,7 +36,7 @@ KHMEXP hashtable * KHMAPI hash_new_hashtable(khm_int32 n, { hashtable * h; - h = malloc(sizeof(hashtable)); + h = PMALLOC(sizeof(hashtable)); h->n = n; h->addr = addr; @@ -57,12 +58,12 @@ KHMEXP void KHMAPI hash_del_hashtable(hashtable * h) { while(b) { if(h->delr) h->delr(b->key, b->data); - free(b); + PFREE(b); LPOP(&h->bins[i], &b); } } - free(h); + PFREE(h); } KHMEXP void KHMAPI hash_add(hashtable * h, void * key, void * data) { @@ -86,7 +87,7 @@ KHMEXP void KHMAPI hash_add(hashtable * h, void * key, void * data) { } if(!b) { - b = malloc(sizeof(hash_bin)); + b = PMALLOC(sizeof(hash_bin)); b->data = data; b->key = key; LINIT(b); @@ -109,7 +110,7 @@ KHMEXP void KHMAPI hash_del(hashtable * h, void * key) { LDELETE(&h->bins[hv], b); if(h->delr) h->delr(b->key, b->data); - free(b); + PFREE(b); break; } b = LNEXT(b); diff --git a/src/windows/identity/util/hashtable.h b/src/windows/identity/util/hashtable.h index 179d311f8..fc7d829f2 100644 --- a/src/windows/identity/util/hashtable.h +++ b/src/windows/identity/util/hashtable.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/util/mstring.c b/src/windows/identity/util/mstring.c index e9120d600..75bab0174 100644 --- a/src/windows/identity/util/mstring.c +++ b/src/windows/identity/util/mstring.c @@ -1,5 +1,5 @@ /* -* Copyright (c) 2004 Massachusetts Institute of Technology +* Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -34,9 +34,9 @@ KHMEXP khm_int32 KHMAPI multi_string_init(wchar_t * ms, - khm_size cb_ms) { + khm_size cb_ms) { if (!ms || cb_ms < sizeof(wchar_t) * 2) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; memset(ms, 0, cb_ms); @@ -44,10 +44,9 @@ multi_string_init(wchar_t * ms, } KHMEXP khm_int32 KHMAPI -multi_string_append( - wchar_t * ms, - khm_size * pcb_ms, - const wchar_t * str) +multi_string_append(wchar_t * ms, + khm_size * pcb_ms, + const wchar_t * str) { wchar_t * s; size_t cch_s; @@ -55,22 +54,22 @@ multi_string_append( size_t cch_r; if(!ms || !pcb_ms || !str) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(FAILED(StringCchLength(str, KHM_MAXCCH_STRING, &cch_s)) || cch_s == 0) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cch_s++; s = ms; while(*s && ((s - ms) < KHM_MAXCCH_STRING)) { if(FAILED(StringCchLength(s, KHM_MAXCB_STRING, &cch_t))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; s += cch_t + 1; } if(*s || (s - ms) >= KHM_MAXCCH_STRING) { - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; } /* now s points to the second NULL of the terminating double NULL */ @@ -91,10 +90,9 @@ multi_string_append( } KHMEXP khm_int32 KHMAPI -multi_string_prepend( - wchar_t * ms, - khm_size * pcb_ms, - const wchar_t * str) +multi_string_prepend(wchar_t * ms, + khm_size * pcb_ms, + const wchar_t * str) { size_t cch_s; size_t cch_t; @@ -102,16 +100,16 @@ multi_string_prepend( khm_size cb_r; if(!ms || !pcb_ms || !str) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(FAILED(StringCchLength(str, KHM_MAXCCH_STRING, &cch_s)) || cch_s == 0) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cch_s++; if(KHM_FAILED(multi_string_length_cch(ms, KHM_MAXCCH_STRING, &cch_r))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cch_t = cch_s + cch_r; cb_r = cch_t * sizeof(wchar_t); @@ -130,10 +128,9 @@ multi_string_prepend( } KHMEXP khm_int32 KHMAPI -multi_string_delete( - wchar_t * ms, - const wchar_t * str, - const khm_int32 flags) +multi_string_delete(wchar_t * ms, + const wchar_t * str, + const khm_int32 flags) { wchar_t * s; wchar_t * n; @@ -141,7 +138,7 @@ multi_string_delete( size_t cch; if(!ms || !str) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; s = multi_string_find(ms, str, flags); if(!s) @@ -151,7 +148,7 @@ multi_string_delete( n = NULL; while(*e && (e - s) < KHM_MAXCCH_STRING) { if(FAILED(StringCchLength(e, KHM_MAXCCH_STRING, &cch))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; e += cch + 1; if(!n) @@ -159,7 +156,7 @@ multi_string_delete( } if(*e || (e - s) >= KHM_MAXCCH_STRING) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; if(e == s) return KHM_ERROR_SUCCESS; @@ -170,10 +167,9 @@ multi_string_delete( } KHMEXP wchar_t * KHMAPI -multi_string_find( - const wchar_t * ms, - const wchar_t * str, - const khm_int32 flags) +multi_string_find(const wchar_t * ms, + const wchar_t * str, + const khm_int32 flags) { const wchar_t *s; size_t cch; @@ -210,10 +206,9 @@ multi_string_find( } KHMEXP khm_int32 KHMAPI -multi_string_to_csv( - wchar_t * csvbuf, - khm_size * pcb_csvbuf, - const wchar_t * ms) +multi_string_to_csv(wchar_t * csvbuf, + khm_size * pcb_csvbuf, + const wchar_t * ms) { size_t cb; size_t cbt; @@ -221,7 +216,7 @@ multi_string_to_csv( wchar_t * d; if(!pcb_csvbuf || !ms) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; /* dry run */ cbt = 0; @@ -230,7 +225,7 @@ multi_string_to_csv( khm_boolean quotes = FALSE; if(FAILED(StringCbLength(t, KHM_MAXCB_STRING, &cb))) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cb += sizeof(wchar_t); cbt += cb; @@ -252,7 +247,7 @@ multi_string_to_csv( } if(cbt > KHM_MAXCB_STRING) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; /* happens if the multi string contained no strings */ if(cbt == 0) @@ -302,10 +297,9 @@ multi_string_to_csv( } KHMEXP khm_int32 KHMAPI -csv_to_multi_string( - wchar_t * ms, - khm_size * pcb_ms, - const wchar_t * csv) +csv_to_multi_string(wchar_t * ms, + khm_size * pcb_ms, + const wchar_t * csv) { const wchar_t * t; wchar_t * p; @@ -314,7 +308,7 @@ csv_to_multi_string( if(!pcb_ms || !csv) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cchr = 0; @@ -346,7 +340,7 @@ csv_to_multi_string( } if((t - csv) >= KHM_MAXCCH_STRING) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; cchr++; /* last string ends */ cchr++; /* double NULL */ @@ -427,8 +421,8 @@ multi_string_length_n(const wchar_t * str) KHMEXP khm_int32 KHMAPI multi_string_length_cb(const wchar_t * str, - khm_size max_cb, - khm_size * len_cb) + khm_size max_cb, + khm_size * len_cb) { khm_size cch; khm_int32 rv; @@ -446,15 +440,15 @@ multi_string_length_cb(const wchar_t * str, KHMEXP khm_int32 KHMAPI multi_string_length_cch(const wchar_t * str, - khm_size max_cch, - khm_size * len_cch) + khm_size max_cch, + khm_size * len_cch) { const wchar_t * s; khm_size cch; size_t tcch; if(!str) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; s = str; cch = 0; @@ -484,7 +478,7 @@ multi_string_copy_cb(wchar_t * s_dest, khm_int32 rv = KHM_ERROR_SUCCESS; if(!s_dest) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; rv = multi_string_length_cb(src, max_cb_dest, &cb_dest); if(KHM_FAILED(rv)) @@ -497,14 +491,14 @@ multi_string_copy_cb(wchar_t * s_dest, KHMEXP khm_int32 KHMAPI multi_string_copy_cch(wchar_t * s_dest, - khm_size max_cch_dest, - const wchar_t * src) + khm_size max_cch_dest, + const wchar_t * src) { khm_size cch_dest; khm_int32 rv = KHM_ERROR_SUCCESS; if(!s_dest) - return KHM_ERROR_INVALID_PARM; + return KHM_ERROR_INVALID_PARAM; rv = multi_string_length_cch(src, max_cch_dest, &cch_dest); if(KHM_FAILED(rv)) diff --git a/src/windows/identity/util/mstring.h b/src/windows/identity/util/mstring.h index 9b4e3800e..a7f6cf523 100644 --- a/src/windows/identity/util/mstring.h +++ b/src/windows/identity/util/mstring.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -95,7 +95,7 @@ multi_string_prepend(wchar_t * ms, \retval KHM_ERROR_TOO_LONG The buffer pointed to by \a ms was insufficient. The required size of the buffer is in \a pcb_ms - \retval KHM_ERROR_INVALID_PARM One of more of the parameters were invalid. + \retval KHM_ERROR_INVALID_PARAM One of more of the parameters were invalid. */ KHMEXP khm_int32 KHMAPI multi_string_append(wchar_t * ms, @@ -127,7 +127,7 @@ multi_string_append(wchar_t * ms, \retval KHM_ERROR_NOT_FOUND No matches were found - \retval KHM_ERROR_INVALID_PARM One or more parameters were incorrect. + \retval KHM_ERROR_INVALID_PARAM One or more parameters were incorrect. \note The search for the existing string is done with multi_string_find() @@ -209,7 +209,7 @@ multi_string_find(const wchar_t * ms, was NULL. The required number of bytes in the buffer is in \a pcb_csvbuf. - \retval KHM_ERROR_INVALID_PARM One or more parameters were ivnalid. + \retval KHM_ERROR_INVALID_PARAM One or more parameters were ivnalid. \see csv_to_multi_string() */ @@ -240,7 +240,7 @@ multi_string_to_csv(wchar_t * csvbuf, ms was NULL. The required size of the buffer in bytes is in \a pcb_ms. - \retval KHM_ERROR_INVALID_PARM One or more parameters were invalid. + \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid. */ KHMEXP khm_int32 KHMAPI @@ -281,7 +281,7 @@ multi_string_next(const wchar_t * str); is successful. \retval KHM_ERROR_SUCCESS The length of the string is in \a len_cb - \retval KHM_ERROR_INVALID_PARM One or more parameters were invalid + \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid \retval KHM_ERROR_TOO_LONG The multi string is longer than \a max_cb bytes. */ @@ -302,7 +302,7 @@ multi_string_length_cb(const wchar_t * str, is successful. \retval KHM_ERROR_SUCCESS The length of the string is in \a len_cch - \retval KHM_ERROR_INVALID_PARM One or more parameters were invalid + \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid \retval KHM_ERROR_TOO_LONG The multi string is longer than \a max_cch characters. */ @@ -326,7 +326,7 @@ multi_string_length_n(const wchar_t * str); \param[in] src The source multi string \retval KHM_ERROR_SUCCESS The multi string was copied successfully - \retval KHM_ERROR_INVALID_PARM One or more parameters were + \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid. \retval KHM_ERROR_TOO_LONG The size of the destination buffer was insufficient. @@ -346,7 +346,7 @@ multi_string_copy_cb(wchar_t * s_dest, \param[in] src The source multi string \retval KHM_ERROR_SUCCESS The multi string was copied successfully - \retval KHM_ERROR_INVALID_PARM One or more parameters were + \retval KHM_ERROR_INVALID_PARAM One or more parameters were invalid. \retval KHM_ERROR_TOO_LONG The size of the destination buffer was insufficient. diff --git a/src/windows/identity/util/perfstat.c b/src/windows/identity/util/perfstat.c new file mode 100644 index 000000000..2ddcedb2c --- /dev/null +++ b/src/windows/identity/util/perfstat.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2005 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* $Id$ */ + +#include +#include +#include +#include +#include +#include + +#define HASHSIZE 1151 +#define ALLOCBLOCK 1024 + +#define HASHPTR(p) (((size_t) (p)) % HASHSIZE) + +typedef struct tag_allocation { + char file[8]; + int line; + size_t size; + void * ptr; + + LDCL(struct tag_allocation); +} allocation; + +static allocation * ht[HASHSIZE]; + +static allocation * next_alloc = NULL; +static size_t idx_next_alloc = 0; +static allocation * free_alloc = NULL; + +static CRITICAL_SECTION cs_alloc; +static LONG ctr = 0; +static int perf_ready = 0; + +static void perf_once(void) { + if (InterlockedIncrement(&ctr) == 1) { + InitializeCriticalSection(&cs_alloc); + ZeroMemory(ht, sizeof(ht)); + + next_alloc = malloc(sizeof(allocation) * ALLOCBLOCK); + assert(next_alloc); + idx_next_alloc = 0; + free_alloc = NULL; + + perf_ready = 1; + } else { + while(!perf_ready) { + Sleep(0); /* relinquish control to the thread + that is initializing the alloc + data. */ + } + } +} + +static allocation * get_allocation(void) { + allocation * a; + + LPOP(&free_alloc, &a); + if (!a) { + if (idx_next_alloc == ALLOCBLOCK) { + next_alloc = malloc(sizeof(allocation) * ALLOCBLOCK); + assert(next_alloc); + idx_next_alloc = 0; + } + + a = &next_alloc[idx_next_alloc]; + idx_next_alloc++; + } + + return a; +} + +#define MAXCB_STR 32768 + +KHMEXP wchar_t * +perf_wcsdup(char * file, int line, const wchar_t * str) { + size_t cb; + wchar_t * dest; + + if (FAILED(StringCbLength(str, MAXCB_STR, &cb))) + return NULL; + cb += sizeof(wchar_t); + + dest = (wchar_t *) perf_malloc(file, line, cb); + StringCbCopy(dest, cb, str); + + return dest; +} + +KHMEXP char * +perf_strdup(char * file, int line, const char * str) { + size_t cb; + char * dest; + + if (FAILED(StringCbLengthA(str, MAXCB_STR, &cb))) + return NULL; + cb += sizeof(char); + + dest = (char *) perf_malloc(file, line, cb); + StringCbCopyA(dest, cb, str); + + return dest; +} + +KHMEXP void * +perf_malloc(char * file, int line, size_t s) { + allocation * a; + void * ptr; + size_t h; + + perf_once(); + + assert(s > 0); + + EnterCriticalSection(&cs_alloc); + a = get_allocation(); + + ptr = malloc(s); + + assert(ptr); /* TODO: handle this gracefully */ + + if (file[0] == '.' && file[1] == '\\') + file += 2; + + StringCbCopyA(a->file, sizeof(a->file), file); + a->line = line; + a->size = s; + a->ptr = ptr; + + h = HASHPTR(ptr); + + LPUSH(&ht[h], a); + LeaveCriticalSection(&cs_alloc); + + return ptr; +} + +KHMEXP void * +perf_realloc(char * file, int line, void * data, size_t s) { + void * n_data; + allocation * a; + size_t h; + + if (data == NULL) + return perf_malloc(file, line, s); + + perf_once(); + h = HASHPTR(data); + + n_data = realloc(data, s); + + assert(n_data); + + EnterCriticalSection(&cs_alloc); + for (a = ht[h]; a; a = LNEXT(a)) { + if (a->ptr == data) + break; + } + + assert(a); + + LDELETE(&ht[h], a); + + a->size = s; + a->ptr = n_data; + + h = HASHPTR(n_data); + LPUSH(&ht[h], a); + LeaveCriticalSection(&cs_alloc); + + return n_data; +} + +KHMEXP void +perf_free (void * b) { + size_t h; + allocation * a; + + perf_once(); + h = HASHPTR(b); + + EnterCriticalSection(&cs_alloc); + for(a = ht[h]; a; a = LNEXT(a)) { + if (a->ptr == b) + break; + } + + assert(a); + + LDELETE(&ht[h], a); + LPUSH(&free_alloc, a); + LeaveCriticalSection(&cs_alloc); +} + +KHMEXP void +perf_dump(char * file) { + FILE * f; + size_t i; + allocation * a; + size_t total = 0; + + perf_once(); + + EnterCriticalSection(&cs_alloc); + f = fopen(file, "w"); + if (!f) + return; + + fprintf(f, "Leaked allocations list ....\n"); + fprintf(f, "File\tLine\tSize\n"); + + for (i=0; i < HASHSIZE; i++) { + for (a = ht[i]; a; a = LNEXT(a)) { + fprintf(f, "%s\t%6d\t%6d\n", a->file, a->line, a->size); + total += a->size; + } + } + + fprintf(f, "----------------------------------------\n"); + fprintf(f, "Total\t\t%d\n", total); + fprintf(f, "----------------- End ------------------\n"); + + fclose(f); + + LeaveCriticalSection(&cs_alloc); +} diff --git a/src/windows/identity/util/perfstat.h b/src/windows/identity/util/perfstat.h new file mode 100644 index 000000000..ad620fd57 --- /dev/null +++ b/src/windows/identity/util/perfstat.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2005 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* $Id$ */ + +#ifndef __KHIMAIRA_PERFSTAT_H +#define __KHIMAIRA_PERFSTAT_H + +#include + +#ifdef DEBUG +#define PMALLOC(s) perf_malloc(__FILE__,__LINE__,s) +#define PREALLOC(d,s) perf_realloc(__FILE__,__LINE__,d,s) +#define PFREE(p) perf_free(p) +#define PDUMP(f) perf_dump(f) +#define PWCSDUP(s) perf_wcsdup(__FILE__,__LINE__,s) +#define PSTRDUP(s) perf_strdup(__FILE__,__LINE__,s) +#else +#define PMALLOC(s) malloc(s) +#define PREALLOC(d,s) realloc(d,s) +#define PFREE(p) free(p) +#define PDUMP(f) ((void) 0) +#define PWCSDUP(s) wcsdup(s) +#define PSTRDUP(s) strdup(s) +#endif + +KHMEXP void * +perf_malloc(char * file, int line, size_t s); + +KHMEXP void * +perf_realloc(char * file, int line, void * data, size_t s); + +KHMEXP void +perf_free (void * b); + +KHMEXP void +perf_dump (char * filename); + +KHMEXP wchar_t * +perf_wcsdup(char * file, int line, const wchar_t * str); + +KHMEXP char * +perf_strdup(char * file, int line, const char * str); + +#endif diff --git a/src/windows/identity/util/sync.c b/src/windows/identity/util/sync.c index b50d484da..d686a8e80 100644 --- a/src/windows/identity/util/sync.c +++ b/src/windows/identity/util/sync.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -52,6 +52,8 @@ KHMEXP void KHMAPI DeleteRwLock(PRWLOCK pLock) DeleteCriticalSection(&(pLock->cs)); CloseHandle(pLock->readwx); CloseHandle(pLock->writewx); + pLock->readwx = NULL; + pLock->writewx = NULL; } KHMEXP void KHMAPI LockObtainRead(PRWLOCK pLock) @@ -91,6 +93,7 @@ KHMEXP void KHMAPI LockObtainWrite(PRWLOCK pLock) pLock->writer == GetCurrentThreadId()) { pLock->locks++; LeaveCriticalSection(&(pLock->cs)); + assert(FALSE); return; } LeaveCriticalSection(&(pLock->cs)); @@ -103,6 +106,7 @@ KHMEXP void KHMAPI LockObtainWrite(PRWLOCK pLock) } pLock->status = LOCK_WRITING; pLock->locks++; + pLock->writer = GetCurrentThreadId(); ResetEvent(pLock->readwx); LeaveCriticalSection(&(pLock->cs)); } @@ -114,6 +118,7 @@ KHMEXP void KHMAPI LockReleaseWrite(PRWLOCK pLock) pLock->locks--; if(!pLock->locks) { pLock->status = LOCK_OPEN; + pLock->writer = 0; SetEvent(pLock->readwx); SetEvent(pLock->writewx); } diff --git a/src/windows/identity/util/sync.h b/src/windows/identity/util/sync.h index 5410d0e52..e423e6766 100644 --- a/src/windows/identity/util/sync.h +++ b/src/windows/identity/util/sync.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/src/windows/identity/util/utils.h b/src/windows/identity/util/utils.h index 2e3b6b7da..4ba86f6ed 100644 --- a/src/windows/identity/util/utils.h +++ b/src/windows/identity/util/utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 Massachusetts Institute of Technology + * Copyright (c) 2005 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -32,5 +32,6 @@ #include #include #include +#include #endif -- 2.26.2