00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 static const char *copyright =
00025 "Copyright (C) 2006-2007 Micro Focus (IP) Limited";
00026 static const char *sccsid =
00027 "@(#)safmgr.c $Revision: 1.2 $ built " __DATE__ " " __TIME__;
00028
00029
00030
00031
00048
00049
00050
00051 #include <stddef.h>
00052 #include <stdlib.h>
00053 #include <stdio.h>
00054 #include <stdarg.h>
00055 #include <string.h>
00056 #include <time.h>
00057 #include <errno.h>
00058 #include <ctype.h>
00059
00060
00061 #if defined(UNIX)
00062 # include <unistd.h>
00063 # include <sys/time.h>
00064 #endif
00065
00066
00067 #if defined(WIN32)
00068 # include <windows.h>
00069 # include <sys/types.h>
00070 # include <sys/stat.h>
00071 #endif
00072
00073
00074
00075 #if defined(UNIX)
00076 # include "gptypes.h"
00077 #elif defined(WIN32)
00078 # include "pc_rts.h"
00079 #endif
00080 #include "cci.h"
00081
00082 #include "mdsa.h"
00083
00084
00085
00086 #include "safmgr.h"
00087 #include "saf-env.h"
00088 #include "saf-cache.h"
00089 #include "saf-esm.h"
00090 #include "saf-process.h"
00091 #include "saf-audit.h"
00092 #include "mfaudit.h"
00093
00094 #if defined(WIN32)
00095
00096 BOOL APIENTRY DllMain(HANDLE Inst, DWORD Reason, LPVOID Reserved)
00097 {
00098 switch (Reason)
00099 {
00100 case DLL_PROCESS_ATTACH:
00101 case DLL_THREAD_ATTACH:
00102 case DLL_PROCESS_DETACH:
00103 case DLL_THREAD_DETACH:
00104 break;
00105 }
00106 return TRUE;
00107 }
00108 #endif
00109
00110
00111 static int EsmCmp(const void *EPtr1, const void *EPtr2);
00112
00113
00114 static enum
00115 {
00116 SafUNINITIALIZED = 0
00117 , SafRUNNING = 1
00118 , SafTERMINATED = 2
00119 } ManagerState = SafUNINITIALIZED;
00120
00121
00122 static struct SafStore *CustCfg = NULL;
00123
00124
00125
00163 mf_uns32 safmgr(struct SafInit *Init)
00164 {
00165 unsigned Esm;
00166 mf_uns32 Ret = SafINIT_OK;
00167 struct SafInit *NewSafInit = NULL, *CallerInit = NULL;
00168 struct cas_saf_config_internal *NewSafCfg;
00169 struct cas_esm_config_internal *NewEsmCfg;
00170 char *CfgVal = NULL;
00171 SafRet SRet;
00172
00173
00174 #if defined WIN32 && defined _DEBUG
00175
00176
00177
00178
00179
00180 if
00181 (
00182 CreateFile
00183 (
00184 "c:/tmp/debug-safmgr"
00185 , FILE_READ_DATA
00186 , 0
00187 , NULL
00188 , OPEN_EXISTING
00189 , 0
00190 , NULL
00191 ) != INVALID_HANDLE_VALUE
00192 )
00193 {
00194 #if 0
00195 DebugBreak();
00196 #elif 0
00197 extern void CBL_DEBUGBREAK(void);
00198 CBL_DEBUGBREAK();
00199 #else
00200 char DbgBuf[80];
00201 DWORD Pid = GetCurrentProcessId();
00202 sprintf(DbgBuf, "cmd /c \"start windbg -p %lu\"", Pid);
00203 system(DbgBuf);
00204 Sleep(15000);
00205 DebugBreak();
00206 #endif
00207 }
00208 #endif
00209
00210 if (! Init)
00211 {
00212 Ret = SafINIT_NULL;
00213 goto done;
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223 if (Init->Version > 10 ||
00224 Init->ESMCnt > 10*SafESM_MAX)
00225 {
00226 Ret = SafINIT_BAD_CB;
00227 goto done;
00228 }
00229
00230
00231 if (Init->Version != SafMGR_API_VER)
00232 {
00233 Ret = SafINIT_VER;
00234 goto done;
00235 }
00236 if (! Init->Config)
00237 {
00238 Ret = SafINIT_CFG;
00239 goto done;
00240 }
00241 if (Init->ESMCnt > SafESM_MAX)
00242 {
00243 Ret = SafINIT_CNT;
00244 goto done;
00245 }
00246
00247
00248 for (Esm = 0; Esm < Init->ESMCnt; Esm++)
00249 if (! Init->ESMCfg[Esm])
00250 {
00251 Ret = SafINIT_ESMCFG;
00252 goto done;
00253 }
00254
00255
00256
00257 Init->Reason = Init->Detail = 0;
00258
00259
00260
00261 if (ManagerState == SafRUNNING)
00262 {
00263 Ret = SafINIT_OK;
00264 goto done;
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 NewSafInit = malloc(sizeof *NewSafInit);
00278 if (! NewSafInit)
00279 {
00280 Ret = SafINIT_RESRCE;
00281 goto done;
00282 }
00283 *NewSafInit = *Init;
00284
00285
00286 CallerInit = Init;
00287 Init = NewSafInit;
00288
00289
00290 NewSafCfg = malloc(sizeof *NewSafCfg);
00291 if (! NewSafCfg)
00292 {
00293 Ret = SafINIT_RESRCE;
00294 goto done;
00295 }
00296
00297 NewSafCfg->version = SafNative32u(Init->Config->version);
00298 NewSafCfg->cache_TTL = SafNative32u(Init->Config->cache_TTL);
00299 NewSafCfg->cache_limit = SafNative32u(Init->Config->cache_limit);
00300 NewSafCfg->option_flags = SafNative32u(Init->Config->option_flags);
00301
00302
00303 NewSafCfg->config = Init->Config->config;
00304 NewSafCfg->reserved = Init->Config->reserved;
00305
00306
00307 Init->Config = NewSafCfg;
00308
00309
00310 for (Esm = 0; Esm < Init->ESMCnt; Esm++)
00311 {
00312 NewEsmCfg = malloc(sizeof *NewEsmCfg);
00313 if (! NewEsmCfg)
00314 {
00315 Ret = SafINIT_RESRCE;
00316 goto done;
00317 }
00318
00319 NewEsmCfg->version = SafNative32u(Init->ESMCfg[Esm]->version);
00320 NewEsmCfg->state = SafNative32u(Init->ESMCfg[Esm]->state);
00321 NewEsmCfg->priority = SafNative32u(Init->ESMCfg[Esm]->priority);
00322 NewEsmCfg->cache_TTL = SafNative32u(Init->ESMCfg[Esm]->cache_TTL);
00323 NewEsmCfg->cache_limit = SafNative32u(Init->ESMCfg[Esm]->cache_limit);
00324
00325 strcpy(NewEsmCfg->name, Init->ESMCfg[Esm]->name);
00326 strcpy(NewEsmCfg->module, Init->ESMCfg[Esm]->module);
00327 strcpy(NewEsmCfg->psz_id, Init->ESMCfg[Esm]->psz_id);
00328 strcpy(NewEsmCfg->psz_pwd, Init->ESMCfg[Esm]->psz_pwd);
00329 strcpy(NewEsmCfg->psz_connection_path,
00330 Init->ESMCfg[Esm]->psz_connection_path);
00331
00332
00333 NewEsmCfg->config = Init->ESMCfg[Esm]->config;
00334 NewEsmCfg->reserved = Init->ESMCfg[Esm]->reserved;
00335
00336
00337 Init->ESMCfg[Esm] = NewEsmCfg;
00338 }
00339
00340
00341 qsort(Init->ESMCfg, Init->ESMCnt, sizeof *Init->ESMCfg, EsmCmp);
00342
00343
00344
00345 Ret = SafEnvInit(Init);
00346
00347
00348 if (Ret >= SafINIT_BADENV || (Ret == SafINIT_FAIL && ! Init->Reason))
00349 {
00350
00351
00352
00353
00354
00355 Init->Reason = SafMGR_FAIL_ENV;
00356 Init->Detail = Ret;
00357 Ret = SafINIT_FAIL;
00358 }
00359 if (Ret) goto done;
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 SRet = SafAllocStore(&CustCfg);
00370 if (SRet)
00371 {
00372 Init->Reason = SafMGR_FAIL_RESOURCE;
00373 Ret = SafINIT_FAIL;
00374 goto done;
00375 }
00376
00377 if (Init->Config->config) SafStoreLoad(CustCfg, Init->Config->config);
00378
00379
00380
00381
00382
00383
00384
00385 SRet = SafQueryCfg("Admin", "allow-list", &CfgVal);
00386 if (SRet || !CfgVal || !*CfgVal)
00387 {
00388 char *EnvVal = getenv("ES_ESF_ALLOW_LIST");
00389 if (EnvVal) SafStoreAdd(CustCfg, "Admin", "allow-list", EnvVal);
00390 }
00391
00392
00393
00394 Ret = SafInitAuditing(Init);
00395
00396
00397 if (Ret >= SafINIT_BADENV || (Ret == SafINIT_FAIL && ! Init->Reason))
00398 {
00399 Init->Reason = SafMGR_FAIL_ENV;
00400 Init->Detail = Ret;
00401 Ret = SafINIT_FAIL;
00402 }
00403 if (Ret)
00404 {
00405
00406 const char *Reason = "unrecognized failure code";
00407
00408 switch (Ret)
00409 {
00410 case SafINIT_EXTERNAL:
00411 Reason = "Could not connect to audit manager";
00412 break;
00413 case SafINIT_ENVFUNC:
00414 Reason = "Could not resolve audit functions";
00415 break;
00416 }
00417
00418 SafLog
00419 (
00420 601
00421 , SafMsgCRIT
00422 , "Auditing subsystem startup failed: (%d) %s"
00423 , Ret
00424 , Reason
00425 );
00426
00427 goto done;
00428 }
00429
00430
00431 Ret = SafRaiseAuditEvent
00432 (
00433 AUDIT_EVENT_SAFMGR_INITIALIZING
00434 , AUDIT_EVENT_CATEGORY_SYSTEM
00435 , 0
00436 );
00437
00438
00439 if (Ret >= SafINIT_BADENV || (Ret == SafINIT_FAIL && ! Init->Reason))
00440 {
00441
00442 Init->Reason = SafMGR_FAIL_ENV;
00443 Init->Detail = Ret;
00444 Ret = SafINIT_FAIL;
00445 }
00446 if (Ret) goto done;
00447
00448
00449
00450
00451
00452
00453 Ret = SafEsmInit(Init);
00454 if (Ret >= SafINIT_BADENV || (Ret == SafINIT_FAIL && ! Init->Reason))
00455 {
00456 if (! Init->Reason)
00457 Ret = SafINIT_OTHER;
00458 else
00459 Ret = SafINIT_FAIL;
00460 }
00461
00462 if (Ret)
00463 {
00464
00465
00466 goto done;
00467 }
00468
00469
00470
00471 Ret = SafProcInit(Init);
00472 if (Ret) goto done;
00473
00474
00475
00476 SafThrLock("manager-state", 1);
00477 ManagerState = SafRUNNING;
00478 SafThrUnlock("manager-state");
00479
00480 done:
00481
00482 if (CallerInit)
00483 {
00484
00485 CallerInit->Reason = Init->Reason;
00486 CallerInit->Detail = Init->Detail;
00487 CallerInit->ESMCnt = Init->ESMCnt;
00488 }
00489
00490 switch (Ret)
00491 {
00492 case SafINIT_OK:
00493
00494 SafRaiseAuditEvent
00495 (
00496 AUDIT_EVENT_SAFMGR_STARTED
00497 , AUDIT_EVENT_CATEGORY_SYSTEM
00498 , 0
00499 );
00500 break;
00501
00502 case SafR_PARAM:
00503 case SafR_RESOURCE:
00504 case SafR_EXFAIL:
00505 case SafR_STATE:
00506 case SafR_INTERNAL:
00507 case SafR_NOTFOUND:
00508 case SafR_TRUNCATED:
00509 default:
00510
00511
00512 break;
00513 }
00514
00515 return Ret;
00516 }
00517
00518
00534 mf_uns32 safterm(mf_uns32 What, void *Reserved)
00535 {
00536
00537
00538
00539
00540
00541
00542
00543
00544 if (What == SafTERM_PROCESS)
00545 {
00546
00547 SafThrLock("manager-state", 1);
00548
00549 if (ManagerState == SafRUNNING)
00550 {
00551
00552 SafRaiseAuditEvent
00553 (
00554 AUDIT_EVENT_SAFMGR_TERMINATING
00555 , AUDIT_EVENT_CATEGORY_SYSTEM
00556 , 0
00557 );
00558
00559
00560 SafEsmExit();
00561
00562
00563 ManagerState = SafTERMINATED;
00564 }
00565
00566 SafThrUnlock("manager-state");
00567 }
00568
00569 return 0;
00570 }
00571
00572
00586 int SafState(void)
00587 {
00588 return (int)ManagerState;
00589 }
00590
00591
00610 SafRet SafQueryCfg(const char *Class, const char *Name, char **ValueP)
00611 {
00612 return SafStoreFind(CustCfg, Class, Name, (void**)ValueP);
00613 }
00614
00615
00616
00617
00618 mf_uns32 SafNative32u(mf_uns32 NetValue)
00619 {
00620 unsigned char *Bytes = (unsigned char *)&NetValue;
00621 return (Bytes[0] << 24) |
00622 (Bytes[1] << 16) |
00623 (Bytes[2] << 8) |
00624 (Bytes[3] << 0);
00625 }
00626
00627
00628
00629 static int EsmCmp(const void *EPtr1, const void *EPtr2)
00630 {
00631
00632
00633
00634
00635
00636
00637
00638 const struct cas_esm_config_internal
00639 **EsmPtr1 = (const struct cas_esm_config_internal **)EPtr1,
00640 **EsmPtr2 = (const struct cas_esm_config_internal **)EPtr2;
00641
00642
00643
00644
00645
00646
00647
00648 return (*EsmPtr1)->priority - (*EsmPtr2)->priority;
00649 }
00650
00651
00652
00653