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-2008 Micro Focus (IP) Limited";
00026 static const char *sccsid =
00027 "@(#)saf-process.c $Revision: 1.2 $ built " __DATE__ " " __TIME__;
00028
00029
00030
00031
00051
00052
00053
00054 #include <stddef.h>
00055 #include <stdlib.h>
00056 #include <stdio.h>
00057 #include <stdarg.h>
00058 #include <string.h>
00059 #include <time.h>
00060 #include <errno.h>
00061 #include <ctype.h>
00062
00063
00064 #if defined(UNIX)
00065 # include <unistd.h>
00066 # include <sys/time.h>
00067 #endif
00068
00069
00070 #if defined(WIN32)
00071 # include <windows.h>
00072 # include <sys/types.h>
00073 # include <sys/stat.h>
00074 #endif
00075
00076
00077
00078 #if defined(UNIX)
00079 # include "gptypes.h"
00080 #elif defined(WIN32)
00081 # include "pc_rts.h"
00082 #endif
00083 #include "cci.h"
00084
00085 #include "mdsa.h"
00086
00087
00088
00089
00090 #define saf78_SAFADMIN_DATA_AREAS
00091 #include "safapi.h"
00092 #include "safmgr.h"
00093 #include "saf-esm.h"
00094 #include "saf-env.h"
00095 #include "saf-acee.h"
00096 #include "saf-process.h"
00097 #include "saf-audit.h"
00098 #include "mfaudit.h"
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 #define SafCACHE_MAX_ENTITY_LEN 1024
00123
00124 struct UpdateCache
00125 {
00126 mf_uns32 Sequence;
00127 Safpb_Parameter_Block PBlock;
00128 SafACEE ACEE;
00129 char Entity[SafCACHE_MAX_ENTITY_LEN];
00130
00131 };
00132
00133
00134
00135 static SafRet AuditAdminReq(struct safpb_parameter_block *PBlock,
00136 int ReqType, SafACEE *AceePtr,
00137 const char *CmdName, int CmdLen);
00138 static int LockUpdateArea(void);
00139 static int UnlockUpdateArea(void);
00140 static SafRet HandlePendingUpdates(struct UpdateCache *Cache);
00141 static mf_uns32 CheckForPendingSharedUpdate(struct UpdateCache *Cache);
00142 static struct UpdateCache *GetUpdateCache(void);
00143 static const char *UpdateTypeToString(unsigned char Type);
00144 static const char *EsmrcToString(mf_uns32 EsmRet);
00145
00146
00147
00148 static mf_uns32 NumESMMods = 0;
00149 static int AllowUnknownUsers = 0,
00150 AllowUnknownResources = 0,
00151 VerifyAllESMs = 0;
00152
00153
00154
00155
00156
00171 mf_uns32 SafProcInit(struct SafInit *Init)
00172 {
00173
00174 NumESMMods = Init->ESMCnt;
00175
00176
00177 AllowUnknownUsers =
00178 !! (Init->Config->option_flags & SAF_OPTION_ALLOW_UNKNOWN_USERS);
00179 AllowUnknownResources =
00180 !! (Init->Config->option_flags & SAF_OPTION_ALLOW_UNKNOWN_RESOURCES);
00181 VerifyAllESMs =
00182 !! (Init->Config->option_flags & SAF_OPTION_VERIFY_AGAINST_ALL_ESMS);
00183
00184 return SafINIT_OK;
00185 }
00186
00187
00188
00189
00190
00201 int SafVerify(struct safpb_parameter_block *PBlock)
00202 {
00203 int Ret = saf78_SAF_RC_SUCCESS, Resolved = 0, Tentative = 0, Allowed = 0,
00204 IsSysUser = 0;
00205 mf_uns32 CurrEsm, EsmRet, NumCalled = 0;
00206 SafRet SRet;
00207 struct SafACEE *Acee = NULL;
00208 char AUserBuf[16] = "???", *MUserBuf = NULL, *UserBuf = AUserBuf;
00209 char GroupBuf[9] = "", *GrpBufPtr, *GrpPtr;
00210 mf_uns32 UserLen;
00211 extern int SafCasOldAcee;
00212
00213
00214 #define SafPT_UNKNOWN (1u<<7)
00215 #define SafPT_GEN_ALLOWED (1u<<0)
00216 #define SafPT_USE_ALLOWED (1u<<1)
00217 static unsigned TokenPerm = SafPT_UNKNOWN;
00218
00219
00220 if (!PBlock)
00221 return 0;
00222
00223 UserLen = PBlock->REQUESTS.VERIFY.safpb_verify_USERID_len;
00224
00225
00226
00227 if (SafState() != 1)
00228 {
00229 Ret = saf78_SAF_RC_FAILURE;
00230 PBlock->RETCODES.DISCRETE.safpb_mgr_return = saf78_RC_DATABASE_ERROR;
00231 goto done;
00232 }
00233
00234
00235 if (PBlock->safpb_type == saf78_TYPE_ENVIR_DESTROY)
00236 {
00237
00238 return 0;
00239 }
00240
00241
00242 SafRaiseAuditEvent
00243 (
00244 AUDIT_EVENT_CHECK_VERIFY
00245 , AUDIT_EVENT_CATEGORY_SEC_API_REQ_CHECK
00246 , 2
00247 , SafEventData
00248 (
00249 AUDIT_RECORD_DATA_TYPE_STRING
00250 ,PBlock->REQUESTS.VERIFY.safpb_verify_USERID_ptr
00251 ,PBlock->REQUESTS.VERIFY.safpb_verify_USERID_len
00252 )
00253 , SafEventData
00254 (
00255 AUDIT_RECORD_DATA_TYPE_STRING
00256 ,PBlock->REQUESTS.VERIFY.safpb_verify_group
00257 ,sizeof(PBlock->REQUESTS.VERIFY.safpb_verify_group)
00258 )
00259 );
00260
00261
00262
00263 HandlePendingUpdates(NULL);
00264
00265
00266
00267 AUserBuf[0] = '\0';
00268 UserBuf = AUserBuf;
00269
00270 if (UserLen < sizeof AUserBuf)
00271 {
00272 UserBuf = AUserBuf;
00273 }
00274 else
00275 {
00276 MUserBuf = malloc(UserLen + 1);
00277 if (! MUserBuf)
00278 {
00279
00280 Ret = saf78_SAF_RC_FAILURE;
00281 PBlock->RETCODES.DISCRETE.safpb_mgr_return = saf78_RC_DATABASE_ERROR;
00282 goto done;
00283 }
00284 UserBuf = MUserBuf;
00285 }
00286
00287 memcpy(UserBuf, PBlock->REQUESTS.VERIFY.safpb_verify_USERID_ptr, UserLen);
00288 UserBuf[UserLen] = '\0';
00289
00290
00291
00292 for (GrpBufPtr = GroupBuf,
00293 GrpPtr = PBlock->REQUESTS.VERIFY.safpb_verify_group;
00294 *GrpPtr > ' '
00295 && GrpPtr < PBlock->REQUESTS.VERIFY.safpb_verify_group + 8;
00296 GrpBufPtr++, GrpPtr++)
00297 {
00298 *GrpBufPtr = *GrpPtr;
00299 }
00300 *GrpBufPtr = '\0';
00301
00302
00303
00304 IsSysUser = PBlock->safpb_flag & saf78_VER_NO_PASSWORD;
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 if ((PBlock->safpb_flag & saf78_VER_PT_TICKET) ||
00315 (PBlock->safpb_flag & saf78_VER_PASSTOKEN) ||
00316 (PBlock->safpb_flag & saf78_VER_PT_SURROGATE) ||
00317 (PBlock->safpb_type == saf78_TYPE_TOKEN_CREATE))
00318 {
00319
00320 if (TokenPerm == SafPT_UNKNOWN)
00321 {
00322 char *PTAllow = NULL;
00323 SafQueryCfg("Passtoken", "allow", &PTAllow);
00324 if (! PTAllow) PTAllow = "";
00325 if (SafSTRCMP_CI(PTAllow, ==, "none"))
00326 TokenPerm = 0;
00327 else if (SafSTRCMP_CI(PTAllow, ==, "generate"))
00328 TokenPerm = SafPT_GEN_ALLOWED;
00329 else if (SafSTRCMP_CI(PTAllow, ==, "signon"))
00330 TokenPerm = SafPT_USE_ALLOWED;
00331 else
00332 TokenPerm = SafPT_GEN_ALLOWED | SafPT_USE_ALLOWED;
00333 }
00334
00335
00336 if (PBlock->safpb_flag & saf78_VER_PT_TICKET)
00337 {
00338
00339
00340
00341
00342
00343
00344 if (! (TokenPerm & SafPT_GEN_ALLOWED)
00345 || (PBlock->safpb_flag & saf78_VER_NO_PASSWORD)
00346 || (PBlock->safpb_flag & saf78_VER_PT_SURROGATE))
00347 {
00348
00349 PBlock->safpb_flag &= ~saf78_VER_PT_TICKET;
00350 }
00351 }
00352
00353 if (PBlock->safpb_type == saf78_TYPE_TOKEN_CREATE)
00354 {
00355
00356 if (! (TokenPerm & SafPT_GEN_ALLOWED))
00357 {
00358
00359 Ret = saf78_SAF_RC_FAILURE;
00360 PBlock->RETCODES.DISCRETE.safpb_mgr_return =
00361 saf78_RC_TOKEN_REFUSED;
00362 goto done;
00363 }
00364 }
00365
00366 if ((PBlock->safpb_flag & saf78_VER_PASSTOKEN) ||
00367 (PBlock->safpb_flag & saf78_VER_PT_SURROGATE))
00368 {
00369
00370 if (! (TokenPerm & SafPT_USE_ALLOWED))
00371 {
00372
00373 Ret = saf78_SAF_RC_FAILURE;
00374 PBlock->RETCODES.DISCRETE.safpb_mgr_return =
00375 saf78_RC_TOKEN_REFUSED;
00376 #if _DEBUG && SafLOG_ALL
00377 SafLog
00378 (
00379 2002
00380 , SafMsgINFO
00381 , "Passtoken Verify refused for user \"%s\""
00382 , UserBuf
00383 );
00384 #endif
00385 goto done;
00386 }
00387 }
00388 }
00389
00390
00391
00392 if (PBlock->safpb_type == saf78_TYPE_TOKEN_DELETE)
00393 {
00394
00395 if (! PBlock->safpb_safesm_index)
00396 {
00397 Ret = saf78_SAF_RC_PARM_ERROR;
00398 PBlock->RETCODES.DISCRETE.safpb_mgr_return = saf78_RC_SAFESM_INDEX;
00399 PBlock->RETCODES.DISCRETE.safpb_mgr_reason = saf78_RS_BAD_VALUE;
00400 goto done;
00401 }
00402
00403
00404 Ret = 0;
00405 PBlock->RETCODES.DISCRETE.safpb_api_rc = 0;
00406 PBlock->RETCODES.DISCRETE.safpb_mgr_return = 0;
00407 PBlock->RETCODES.DISCRETE.safpb_mgr_reason = 0;
00408
00409
00410 EsmRet = SafEsmCVerify(PBlock->safpb_safesm_index - 1, PBlock);
00411
00412 if (EsmRet)
00413 {
00414 Ret = saf78_SAF_RC_FAILURE;
00415 if (! PBlock->RETCODES.DISCRETE.safpb_mgr_return)
00416 {
00417 PBlock->RETCODES.DISCRETE.safpb_mgr_return =
00418 saf78_RC_DATABASE_ERROR;
00419 }
00420 }
00421
00422 goto done;
00423 }
00424
00425
00426
00427 PBlock->RETCODES.DISCRETE.safpb_api_rc = saf78_SAF_RC_NOT_COMPLETE;
00428 PBlock->RETCODES.DISCRETE.safpb_mgr_return = 0;
00429 PBlock->RETCODES.DISCRETE.safpb_mgr_reason = 0;
00430
00431 for (CurrEsm=0; CurrEsm < NumESMMods && !Resolved; CurrEsm++)
00432 {
00433 const char *ErrType = NULL;
00434
00435
00436 PBlock->safpb_safesm_index = (unsigned char) CurrEsm + 1;
00437
00438
00439 EsmRet = SafEsmCVerify(CurrEsm, PBlock);
00440
00441
00442
00443 switch (EsmRet)
00444 {
00445 case SafESMRC_OK:
00446
00447 if (PBlock->RETCODES.DISCRETE.safpb_api_rc !=
00448 saf78_SAF_RC_NOT_COMPLETE)
00449 {
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 if (Allowed)
00474 {
00475
00476 PBlock->RETCODES.DISCRETE.safpb_api_rc = saf78_SAF_RC_SUCCESS;
00477 }
00478 else if (PBlock->RETCODES.DISCRETE.safpb_api_rc !=
00479 saf78_SAF_RC_SUCCESS)
00480 {
00481
00482 Resolved = 1;
00483 Tentative = 0;
00484 }
00485 else if (VerifyAllESMs)
00486 {
00487
00488 Tentative = 1;
00489 PBlock->RETCODES.DISCRETE.safpb_api_rc =
00490 saf78_SAF_RC_NOT_COMPLETE;
00491 }
00492 else
00493 {
00494
00495 Allowed = 1;
00496 }
00497 }
00498
00499
00500 NumCalled++;
00501 break;
00502
00503 case SafESMRC_NOTIMPL:
00504
00505 break;
00506
00507
00508 case SafESMRC_PARAM:
00509 ErrType = "parameter error";
00510 break;
00511 case SafESMRC_RESOURCE:
00512 ErrType = "resource unavailable";
00513 break;
00514 case SafESMRC_EXTERNAL:
00515 ErrType = "ESM error";
00516 break;
00517 case SafESMRC_MGRFAIL:
00518 ErrType = "ESF Manager failure";
00519 break;
00520 case SafESMRC_FAIL:
00521 ErrType = "miscellaneous failure";
00522 break;
00523 default:
00524 ErrType = "unknown error";
00525 break;
00526 }
00527
00528
00529 if (ErrType)
00530 {
00531 mf_uns32 esmnum;
00532 const char* esmname;
00533
00534
00535 SafLog
00536 (
00537 110
00538 , SafMsgERR
00539 , "ESM Module %d (%s) returned error code %d (%s) from Verify"
00540 , CurrEsm+1
00541 , SafEsmName(CurrEsm)
00542 , (int)EsmRet
00543 , ErrType
00544 );
00545
00546
00547 esmnum=CurrEsm+1;
00548 esmname=SafEsmName(CurrEsm);
00549
00550
00551 SafRaiseAuditEvent
00552 (
00553 AUDIT_EVENT_VERIFY_ESM_ERROR
00554 , AUDIT_EVENT_CATEGORY_SEC_API_RES_ERROR
00555 , 4
00556 , SafEventData
00557 (
00558 AUDIT_RECORD_DATA_TYPE_COMP5
00559 , (void*)&esmnum
00560 , sizeof(esmnum)
00561 )
00562 , SafEventData
00563 (
00564 AUDIT_RECORD_DATA_TYPE_STRING
00565 , (void*)esmname
00566 , (int)strlen(esmname)
00567 )
00568 , SafEventData
00569 (
00570 AUDIT_RECORD_DATA_TYPE_COMP5
00571 , (void*)&EsmRet
00572 , sizeof(EsmRet)
00573 )
00574 , SafEventData
00575 (
00576 AUDIT_RECORD_DATA_TYPE_STRING
00577 , (void*)ErrType
00578 , (int)strlen(ErrType)
00579 )
00580
00581 );
00582
00583
00584
00585 PBlock->RETCODES.DISCRETE.safpb_api_rc = saf78_SAF_RC_FAILURE;
00586 PBlock->RETCODES.DISCRETE.safpb_mgr_return =
00587 saf78_RC_DATABASE_ERROR;
00588 Resolved = 1;
00589 }
00590 }
00591
00592
00593
00594
00595
00596
00597
00598
00599 if (Tentative || Allowed)
00600 {
00601 Resolved = 1;
00602 if (PBlock->RETCODES.DISCRETE.safpb_api_rc == saf78_SAF_RC_NOT_COMPLETE)
00603 {
00604
00605 PBlock->RETCODES.DISCRETE.safpb_api_rc = saf78_SAF_RC_SUCCESS;
00606 }
00607 }
00608
00609
00610
00611 if (! Resolved)
00612 {
00613
00614 PBlock->safpb_safesm_index = 0;
00615
00616 if (NumCalled == 0)
00617 {
00618
00619 PBlock->RETCODES.DISCRETE.safpb_api_rc = saf78_SAF_RC_SUCCESS;
00620 }
00621 else
00622 {
00623
00624
00625
00626
00627
00628 if (AllowUnknownUsers || IsSysUser)
00629 {
00630 PBlock->RETCODES.DISCRETE.safpb_api_rc = saf78_SAF_RC_SUCCESS;
00631
00632
00633 SafRaiseAuditEvent
00634 (
00635 AUDIT_EVENT_VERIFY_ALLOW_UNKNOWN
00636 , AUDIT_EVENT_CATEGORY_SEC_API_RES_ALLOW
00637 , 1
00638 , SafEventData
00639 (
00640 AUDIT_RECORD_DATA_TYPE_STRING
00641 , (void*)UserBuf
00642 , (int)strlen(UserBuf)
00643 )
00644 );
00645 }
00646 else
00647 {
00648
00649 PBlock->RETCODES.DISCRETE.safpb_api_rc = saf78_SAF_RC_FAILURE;
00650 PBlock->RETCODES.DISCRETE.safpb_mgr_return =
00651 saf78_RC_NO_USER_PROFILE;
00652 }
00653 }
00654 }
00655
00656
00657
00658 Ret = PBlock->RETCODES.DISCRETE.safpb_api_rc;
00659
00660
00661
00662 if (Ret) goto done;
00663
00664
00665
00666 if (! PBlock->REQUESTS.VERIFY.safpb_verify_ACEE_ptr)
00667 {
00668
00669
00670 SRet = SafAceeAlloc(UserBuf, *GroupBuf? GroupBuf : NULL, &Acee, NULL);
00671 if (SRet)
00672 {
00673 Ret = saf78_SAF_RC_FAILURE;
00674 PBlock->RETCODES.DISCRETE.safpb_mgr_return = saf78_RC_DATABASE_ERROR;
00675 }
00676
00677 if (SafCasOldAcee)
00678 {
00679 unsigned char *TmpPtr;
00680 TmpPtr = (unsigned char *)Acee;
00681 TmpPtr -= 8;
00682 PBlock->REQUESTS.VERIFY.safpb_verify_ACEE_ptr = (void *)TmpPtr;
00683 }
00684 else
00685 PBlock->REQUESTS.VERIFY.safpb_verify_ACEE_ptr = Acee;
00686
00687
00688 memset(Acee->SecurityKeys, 0xff, sizeof Acee->SecurityKeys);
00689 memset(Acee->ResourceKeys, 0xff, sizeof Acee->ResourceKeys);
00690 memset(Acee->UserResourceKeys, 0xff, sizeof Acee->UserResourceKeys);
00691 memset(Acee->RdAccessFlags, 1, sizeof Acee->RdAccessFlags);
00692
00693
00694
00695
00696 if (IsSysUser)
00697 {
00698 if (SafSTRCMP(UserBuf, ==, "mfuser"))
00699 {
00700 Acee->Flag3 |= SafACEE_F3_DUID;
00701 memcpy(Acee->OperId, "mfu", 3);
00702 Acee->OperClass[2] = '\x01';
00703 }
00704 else
00705 {
00706 Acee->Flag3 |= SafACEE_F3_NPWR;
00707 }
00708 }
00709 }
00710
00711 else
00712 {
00713
00714
00715
00716
00717
00718 unsigned char *AceePtr;
00719
00720 AceePtr = (unsigned char *)PBlock->REQUESTS.VERIFY.safpb_verify_ACEE_ptr;
00721
00722 if (SafCasOldAcee && memcmp(AceePtr, "ACEE", 4) == 0)
00723 {
00724 AceePtr -= 8;
00725 PBlock->REQUESTS.VERIFY.safpb_verify_ACEE_ptr = (void *)AceePtr;
00726 }
00727 }
00728
00729
00730
00731
00732 done:
00733
00734 if (PBlock)
00735 {
00736
00737 PBlock->RETCODES.DISCRETE.safpb_api_rc = Ret;
00738
00739
00740 if (Ret >= saf78_SAF_RC_FAILURE)
00741 {
00742 switch (PBlock->RETCODES.DISCRETE.safpb_mgr_return)
00743 {
00744 case saf78_RC_PWRD_INVALID:
00745
00746 SafRaiseAuditEvent
00747 (
00748 AUDIT_EVENT_VERIFY_PWD_INVALID
00749 , AUDIT_EVENT_CATEGORY_SEC_API_RES_DENY
00750 , 2
00751 , SafEventData
00752 (
00753 AUDIT_RECORD_DATA_TYPE_STRING
00754 ,PBlock->REQUESTS.VERIFY.safpb_verify_USERID_ptr
00755 ,PBlock->REQUESTS.VERIFY.safpb_verify_USERID_len
00756 )
00757 , SafEventData
00758 (
00759 AUDIT_RECORD_DATA_TYPE_STRING
00760 ,PBlock->REQUESTS.VERIFY.safpb_verify_group
00761 ,sizeof(PBlock->REQUESTS.VERIFY.safpb_verify_group)
00762 )
00763 );
00764 break;
00765
00766 case saf78_RC_PWRD_EXPIRED:
00767
00768 SafRaiseAuditEvent
00769 (
00770 AUDIT_EVENT_VERIFY_PWD_EXPIRED
00771 , AUDIT_EVENT_CATEGORY_SEC_API_RES_DENY
00772 , 2
00773 , SafEventData
00774 (
00775 AUDIT_RECORD_DATA_TYPE_STRING
00776 ,PBlock->REQUESTS.VERIFY.safpb_verify_USERID_ptr
00777 ,PBlock->REQUESTS.VERIFY.safpb_verify_USERID_len
00778 )
00779 , SafEventData
00780 (
00781 AUDIT_RECORD_DATA_TYPE_STRING
00782 ,PBlock->REQUESTS.VERIFY.safpb_verify_group
00783 ,sizeof(PBlock->REQUESTS.VERIFY.safpb_verify_group)
00784 )
00785 );
00786 break;
00787
00788 case saf78_RC_PWRD_CHANGE_ERR:
00789
00790 SafRaiseAuditEvent
00791 (
00792 AUDIT_EVENT_VERIFY_PWD_CHANGE
00793 , AUDIT_EVENT_CATEGORY_SEC_API_RES_DENY
00794 , 2
00795 , SafEventData
00796 (
00797 AUDIT_RECORD_DATA_TYPE_STRING
00798 , PBlock->REQUESTS.VERIFY.safpb_verify_USERID_ptr
00799 , PBlock->REQUESTS.VERIFY.safpb_verify_USERID_len
00800 )
00801 , SafEventData
00802 (
00803 AUDIT_RECORD_DATA_TYPE_STRING
00804 , PBlock->REQUESTS.VERIFY.safpb_verify_group
00805 , sizeof(PBlock->REQUESTS.VERIFY.safpb_verify_group)
00806 )
00807 );
00808 break;
00809
00810 case saf78_RC_USER_NOT_IN_GROUP:
00811
00812 SafRaiseAuditEvent
00813 (
00814 AUDIT_EVENT_VERIFY_USR_NOT_IN_GROUP
00815 , AUDIT_EVENT_CATEGORY_SEC_API_RES_DENY
00816 , 2
00817 , SafEventData
00818 (
00819 AUDIT_RECORD_DATA_TYPE_STRING
00820 , PBlock->REQUESTS.VERIFY.safpb_verify_USERID_ptr
00821 , PBlock->REQUESTS.VERIFY.safpb_verify_USERID_len
00822 )
00823 , SafEventData
00824 (
00825 AUDIT_RECORD_DATA_TYPE_STRING
00826 , PBlock->REQUESTS.VERIFY.safpb_verify_group
00827 , sizeof(PBlock->REQUESTS.VERIFY.safpb_verify_group)
00828 )
00829 );
00830 break;
00831 case saf78_RC_NO_USER_PROFILE:
00832
00833 SafRaiseAuditEvent
00834 (
00835 AUDIT_EVENT_VERIFY_DENY_UNKNOWN
00836 , AUDIT_EVENT_CATEGORY_SEC_API_RES_DENY
00837 , 2
00838 , SafEventData
00839 (
00840 AUDIT_RECORD_DATA_TYPE_STRING
00841 , (void*)UserBuf
00842 , (int)strlen(UserBuf)
00843 )
00844 , SafEventData
00845 (
00846 AUDIT_RECORD_DATA_TYPE_STRING
00847 , PBlock->REQUESTS.VERIFY.safpb_verify_group
00848 , sizeof(PBlock->REQUESTS.VERIFY.safpb_verify_group)
00849 )
00850 );
00851 break;
00852 default:
00853
00854 SafRaiseAuditEvent
00855 (
00856 AUDIT_EVENT_VERIFY_FAIL_UNKNOWN
00857 , AUDIT_EVENT_CATEGORY_SEC_API_RES_DENY
00858 , 2
00859 , SafEventData
00860 (
00861 AUDIT_RECORD_DATA_TYPE_STRING
00862 , PBlock->REQUESTS.VERIFY.safpb_verify_USERID_ptr
00863 , PBlock->REQUESTS.VERIFY.safpb_verify_USERID_len
00864 )
00865 , SafEventData
00866 (
00867 AUDIT_RECORD_DATA_TYPE_STRING
00868 , PBlock->REQUESTS.VERIFY.safpb_verify_group
00869 , sizeof(PBlock->REQUESTS.VERIFY.safpb_verify_group)
00870 )
00871 );
00872
00873 }
00874 }
00875 else if (Ret == saf78_SAF_RC_SUCCESS)
00876 {
00877
00878 SafRaiseAuditEvent
00879 (
00880 AUDIT_EVENT_VERIFY_SUCCESS
00881 , AUDIT_EVENT_CATEGORY_SEC_API_RES_ALLOW
00882 , 2
00883 , SafEventData
00884 (
00885 AUDIT_RECORD_DATA_TYPE_STRING
00886 , PBlock->REQUESTS.VERIFY.safpb_verify_USERID_ptr
00887 , PBlock->REQUESTS.VERIFY.safpb_verify_USERID_len
00888 )
00889 , SafEventData
00890 (
00891 AUDIT_RECORD_DATA_TYPE_STRING
00892 , PBlock->REQUESTS.VERIFY.safpb_verify_group
00893 , sizeof(PBlock->REQUESTS.VERIFY.safpb_verify_group)
00894 )
00895 );
00896 }
00897 }
00898
00899 #if _DEBUG && SafLOG_ALL
00900
00901 if (Ret) SafLog(2001, SafMsgINFO, "Verify failed for \"%s\"", UserBuf);
00902 #endif
00903
00904 free(MUserBuf);
00905 return Ret;
00906 }
00907
00925 int SafAuth(struct safpb_parameter_block *PBlock)
00926 {
00927 int Ret;
00928 int Resolved = 0;
00929 mf_uns32 CurrEsm, EsmRet, NumCalled = 0;
00930 unsigned char *AceePtr;
00931 if (!PBlock)
00932 return 0;
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942 AceePtr = (unsigned char *)PBlock->REQUESTS.AUTH.safpb_auth_ACEE_ptr;
00943 if (memcmp(AceePtr, SafACEE_NAME, 4) != 0) AceePtr += 8;
00944
00945
00946 SafRaiseAuditEvent
00947 (
00948 AUDIT_EVENT_CHECK_AUTH
00949 , AUDIT_EVENT_CATEGORY_SEC_API_REQ_CHECK
00950 , 3
00951 , SafEventData
00952 (
00953 AUDIT_RECORD_DATA_TYPE_STRING
00954 ,((SafACEE *)AceePtr)->User
00955 ,((SafACEE *)AceePtr)->UserLen
00956 )
00957 , SafEventData
00958 (
00959 AUDIT_RECORD_DATA_TYPE_STRING
00960 ,PBlock->REQUESTS.AUTH.safpb_auth_class
00961 ,sizeof(PBlock->REQUESTS.AUTH.safpb_auth_class)
00962 )
00963 , SafEventData
00964 (
00965 AUDIT_RECORD_DATA_TYPE_STRING
00966 ,PBlock->REQUESTS.AUTH.safpb_auth_ENTITY_ptr
00967 ,PBlock->REQUESTS.AUTH.safpb_auth_ENTITY_len
00968 )
00969 );
00970
00971
00972
00973 if (SafState() != 1)
00974 {
00975 Ret = saf78_SAF_RC_FAILURE;
00976 PBlock->RETCODES.DISCRETE.safpb_mgr_return = saf78_RC_DATABASE_ERROR;
00977 goto done;
00978 }
00979
00980
00981
00982 HandlePendingUpdates(NULL);
00983
00984
00985
00986 PBlock->RETCODES.DISCRETE.safpb_api_rc = saf78_SAF_RC_NOT_COMPLETE;
00987 PBlock->RETCODES.DISCRETE.safpb_mgr_return = 0;
00988 PBlock->RETCODES.DISCRETE.safpb_mgr_reason = 0;
00989
00990 Ret = saf78_SAF_RC_NOT_COMPLETE;
00991
00992 for (CurrEsm=0; CurrEsm < NumESMMods && !Resolved; CurrEsm++)
00993 {
00994 const char *ErrType = NULL;
00995
00996
00997 PBlock->safpb_safesm_index = (unsigned char) CurrEsm + 1;
00998
00999
01000 EsmRet = SafEsmCAuth(CurrEsm, PBlock);
01001
01002
01003 switch (EsmRet)
01004 {
01005
01006 case SafESMRC_OK:
01007
01008 if (PBlock->RETCODES.DISCRETE.safpb_api_rc !=
01009 saf78_SAF_RC_NOT_COMPLETE)
01010 {
01011 Ret = PBlock->RETCODES.DISCRETE.safpb_api_rc;
01012 Resolved = 1;
01013 }
01014
01015
01016 NumCalled++;
01017 break;
01018
01019 case SafESMRC_NOTIMPL:
01020
01021 break;
01022
01023
01024 case SafESMRC_PARAM:
01025 ErrType = "parameter error";
01026 break;
01027 case SafESMRC_RESOURCE:
01028 ErrType = "resource unavailable";
01029 break;
01030 case SafESMRC_EXTERNAL:
01031 ErrType = "ESM error";
01032 break;
01033 case SafESMRC_FAIL:
01034 ErrType = "miscellaneous failure";
01035 break;
01036 case SafESMRC_MGRFAIL:
01037 ErrType = "ESF Manager failure";
01038 break;
01039 default:
01040 ErrType = "unknown error";
01041 break;
01042 }
01043
01044
01045 if (ErrType)
01046 {
01047 mf_uns32 EsmNum = CurrEsm + 1;
01048 const char *EsmName = SafEsmName(CurrEsm);
01049
01050
01051 SafLog
01052 (
01053 111
01054 , SafMsgERR
01055 , "ESM Module %d (%s) returned error code %d (%s) from Auth"
01056 , EsmNum
01057 , EsmName
01058 , (int)EsmRet
01059 , ErrType
01060 );
01061
01062
01063 SafRaiseAuditEvent
01064 (
01065 AUDIT_EVENT_AUTH_ESM_ERROR
01066 , AUDIT_EVENT_CATEGORY_SEC_API_RES_ERROR
01067 , 4
01068 , SafEventData
01069 (
01070 AUDIT_RECORD_DATA_TYPE_COMP5
01071 , &EsmNum
01072 , sizeof EsmNum
01073 )
01074 , SafEventData
01075 (
01076 AUDIT_RECORD_DATA_TYPE_STRING
01077 , EsmName
01078 , (int)strlen(EsmName)
01079 )
01080 , SafEventData
01081 (
01082 AUDIT_RECORD_DATA_TYPE_COMP5
01083 , &EsmRet
01084 , sizeof EsmRet
01085 )
01086 , SafEventData
01087 (
01088 AUDIT_RECORD_DATA_TYPE_STRING
01089 , ErrType
01090 , (int)strlen(ErrType)
01091 )
01092 );
01093
01094
01095 Ret = saf78_SAF_RC_FAILURE;
01096 PBlock->RETCODES.DISCRETE.safpb_mgr_return = saf78_RC_DATABASE_ERROR;
01097 Resolved = 1;
01098 }
01099 }
01100
01101
01102
01103
01104
01105
01106
01107 if (! Resolved)
01108 {
01109
01110 PBlock->safpb_safesm_index = 0;
01111
01112 if (NumCalled == 0 || AllowUnknownResources)
01113 {
01114 Ret = saf78_SAF_RC_SUCCESS;
01115
01116
01117 if (PBlock->safpb_type == saf78_TYPE_ATTR_STATUS_ACC)
01118 {
01119 PBlock->RETCODES.DISCRETE.safpb_mgr_return = saf78_RC_ACCESS_INFO;
01120 PBlock->RETCODES.DISCRETE.safpb_mgr_reason = saf78_RS_ACCESS_ALTER;
01121 }
01122 else
01123 {
01124
01125 PBlock->RETCODES.DISCRETE.safpb_mgr_return = 0;
01126 PBlock->RETCODES.DISCRETE.safpb_mgr_reason = 0;
01127 }
01128 }
01129 else
01130 {
01131
01132 if (PBlock->safpb_type == saf78_TYPE_ATTR_STATUS_ACC)
01133 {
01134 Ret = saf78_SAF_RC_SUCCESS;
01135 PBlock->RETCODES.DISCRETE.safpb_mgr_return = saf78_RC_ACCESS_INFO;
01136 PBlock->RETCODES.DISCRETE.safpb_mgr_reason = saf78_RS_ACCESS_NONE;
01137 }
01138 else
01139 {
01140 Ret = saf78_SAF_RC_NOT_COMPLETE;
01141 PBlock->RETCODES.DISCRETE.safpb_mgr_return =
01142 saf78_RC_RESOURCE_NOT_PROT;
01143 PBlock->RETCODES.DISCRETE.safpb_mgr_reason =
01144 saf78_RS_NO_RESOURCE_PROF;
01145 }
01146 }
01147 }
01148
01149 if (Ret)
01150 {
01151 char UserBuf[9], ClassBuf[9], ResourceBuf[32];
01152 SafACEE *Acee;
01153 unsigned char *AceePtr;
01154 size_t Len;
01155
01156 AceePtr = (unsigned char *)PBlock->REQUESTS.AUTH.safpb_auth_ACEE_ptr;
01157 if (memcmp(AceePtr, SafACEE_NAME, 4) != 0) AceePtr += 8;
01158 Acee = (SafACEE *)AceePtr;
01159 memcpy(UserBuf, Acee->User, 8);
01160 UserBuf[Acee->UserLen] = '\0';
01161
01162 memcpy(ClassBuf, PBlock->REQUESTS.AUTH.safpb_auth_class, 8);
01163 ClassBuf[8] = '\0';
01164
01165 Len = PBlock->REQUESTS.AUTH.safpb_auth_ENTITY_len;
01166 if (Len > sizeof ResourceBuf - 1) Len = sizeof ResourceBuf - 1;
01167 memcpy(ResourceBuf, PBlock->REQUESTS.AUTH.safpb_auth_ENTITY_ptr, Len);
01168 ResourceBuf[Len] = '\0';
01169
01170
01171 SafRaiseAuditEvent
01172 (
01173 AUDIT_EVENT_AUTH_DENY
01174 , AUDIT_EVENT_CATEGORY_SEC_API_RES_DENY
01175 , 3
01176 , SafEventData
01177 (
01178 AUDIT_RECORD_DATA_TYPE_STRING
01179 , UserBuf
01180 , (int)strlen(UserBuf)
01181 )
01182 , SafEventData
01183 (
01184 AUDIT_RECORD_DATA_TYPE_STRING
01185 , ClassBuf
01186 , (int)strlen(ClassBuf)
01187 )
01188 , SafEventData
01189 (
01190 AUDIT_RECORD_DATA_TYPE_STRING
01191 , ResourceBuf
01192 , (int)strlen(ResourceBuf)
01193 )
01194 );
01195
01196 #if _DEBUG && SafLOG_ALL
01197 SafLog
01198 (
01199 2003
01200 , SafMsgINFO
01201 , "Auth failed for user \"%s\", class \"%s\", entity \"%s\""
01202 , UserBuf
01203 , ClassBuf
01204 , ResourceBuf
01205 );
01206 #endif
01207 }
01208
01209 done:
01210 if (PBlock) PBlock->RETCODES.DISCRETE.safpb_api_rc = Ret;
01211 return Ret;
01212 }
01213
01214
01215
01226 int SafXauth(struct safpb_parameter_block *PBlock)
01227 {
01228 int Ret;
01229 int Resolved = 0;
01230 mf_uns32 CurrEsm, EsmRet, NumCalled = 0;
01231
01232 unsigned char *AceePtr;
01233 if (!PBlock)
01234 return 0;
01235
01236 AceePtr = (unsigned char *)PBlock->REQUESTS.AUTH.safpb_auth_ACEE_ptr;
01237 if (memcmp(AceePtr, SafACEE_NAME, 4) != 0) AceePtr += 8;
01238
01239
01240 SafRaiseAuditEvent
01241 (
01242 AUDIT_EVENT_CHECK_XAUTH
01243 , AUDIT_EVENT_CATEGORY_SEC_API_REQ_CHECK
01244 , 3
01245 , SafEventData
01246 (
01247 AUDIT_RECORD_DATA_TYPE_STRING
01248 ,((SafACEE *)AceePtr)->User
01249 ,((SafACEE *)AceePtr)->UserLen
01250 )
01251 , SafEventData
01252 (
01253 AUDIT_RECORD_DATA_TYPE_STRING
01254 ,PBlock->REQUESTS.AUTH.safpb_auth_class
01255 ,sizeof(PBlock->REQUESTS.AUTH.safpb_auth_class)
01256 )
01257 , SafEventData
01258 (
01259 AUDIT_RECORD_DATA_TYPE_STRING
01260 ,PBlock->REQUESTS.AUTH.safpb_auth_ENTITY_ptr
01261 ,PBlock->REQUESTS.AUTH.safpb_auth_ENTITY_len
01262 )
01263 );
01264
01265
01266 if (SafState() != 1)
01267 {
01268 Ret = saf78_SAF_RC_FAILURE;
01269 PBlock->RETCODES.DISCRETE.safpb_mgr_return = saf78_RC_DATABASE_ERROR;
01270 goto done;
01271 }
01272
01273
01274
01275 HandlePendingUpdates(NULL);
01276
01277
01278
01279 PBlock->RETCODES.DISCRETE.safpb_api_rc = saf78_SAF_RC_NOT_COMPLETE;
01280 PBlock->RETCODES.DISCRETE.safpb_mgr_return = 0;
01281 PBlock->RETCODES.DISCRETE.safpb_mgr_reason = 0;
01282
01283 Ret = saf78_SAF_RC_NOT_COMPLETE;
01284
01285 for (CurrEsm=0; CurrEsm < NumESMMods && !Resolved; CurrEsm++)
01286 {
01287 const char *ErrType = NULL;
01288
01289
01290 PBlock->safpb_safesm_index = (unsigned char) CurrEsm + 1;
01291
01292
01293 EsmRet = SafEsmCXAuth(CurrEsm, PBlock);
01294
01295
01296 switch (EsmRet)
01297 {
01298
01299 case SafESMRC_OK:
01300
01301 if (PBlock->RETCODES.DISCRETE.safpb_api_rc !=
01302 saf78_SAF_RC_NOT_COMPLETE)
01303 {
01304 Ret = PBlock->RETCODES.DISCRETE.safpb_api_rc;
01305 Resolved = 1;
01306 }
01307
01308
01309 NumCalled++;
01310 break;
01311
01312 case SafESMRC_NOTIMPL:
01313
01314 break;
01315
01316
01317 case SafESMRC_PARAM:
01318 ErrType = "parameter error";
01319 break;
01320 case SafESMRC_RESOURCE:
01321 ErrType = "resource unavailable";
01322 break;
01323 case SafESMRC_EXTERNAL:
01324 ErrType = "ESM error";
01325 break;
01326 case SafESMRC_FAIL:
01327 ErrType = "miscellaneous failure";
01328 break;
01329 case SafESMRC_MGRFAIL:
01330 ErrType = "ESF Manager failure";
01331 break;
01332 default:
01333 ErrType = "unknown error";
01334 break;
01335 }
01336
01337
01338 if (ErrType)
01339 {
01340 mf_uns32 EsmNum = CurrEsm + 1;
01341 const char *EsmName = SafEsmName(CurrEsm);
01342
01343
01344 SafLog
01345 (
01346 112
01347 , SafMsgERR
01348 , "ESM Module %d (%s) returned error code %d (%s) from XAuth"
01349 , EsmNum
01350 , EsmName
01351 , (int)EsmRet
01352 , ErrType
01353 );
01354
01355
01356 SafRaiseAuditEvent
01357 (
01358 AUDIT_EVENT_XAUTH_ESM_ERROR
01359 , AUDIT_EVENT_CATEGORY_SEC_API_RES_ERROR
01360 , 4
01361 , SafEventData
01362 (
01363 AUDIT_RECORD_DATA_TYPE_COMP5
01364 , &EsmNum
01365 , sizeof EsmNum
01366 )
01367 , SafEventData
01368 (
01369 AUDIT_RECORD_DATA_TYPE_STRING
01370 , EsmName
01371 , (int)strlen(EsmName)
01372 )
01373 , SafEventData
01374 (
01375 AUDIT_RECORD_DATA_TYPE_COMP5
01376 , &EsmRet
01377 , sizeof EsmRet
01378 )
01379 , SafEventData
01380 (
01381 AUDIT_RECORD_DATA_TYPE_STRING
01382 , ErrType
01383 , (int)strlen(ErrType)
01384 )
01385 );
01386
01387
01388 Ret = saf78_SAF_RC_FAILURE;
01389 PBlock->RETCODES.DISCRETE.safpb_mgr_return =
01390 saf78_RC_DATABASE_ERROR;
01391 Resolved = 1;
01392 }
01393 }
01394
01395
01396
01397
01398
01399
01400
01401 if (! Resolved)
01402 {
01403
01404 PBlock->safpb_safesm_index = 0;
01405
01406 if (NumCalled == 0 || AllowUnknownResources)
01407 {
01408 Ret = saf78_SAF_RC_SUCCESS;
01409 PBlock->RETCODES.DISCRETE.safpb_mgr_return = 0;
01410 PBlock->RETCODES.DISCRETE.safpb_mgr_reason = 0;
01411
01412 if (PBlock->safpb_type == saf78_TYPE_ATTR_STATUS_ACC)
01413 {
01414 PBlock->REQUESTS.XAUTH.safpb_xauth_PERMISSIONS =
01415 saf78_PERM_READ
01416 | saf78_PERM_UPDATE
01417 | saf78_PERM_EXECUTE
01418 | saf78_PERM_CONTROL
01419 | saf78_PERM_ALTER;
01420 }
01421 }
01422 else
01423 {
01424
01425 if (PBlock->safpb_type == saf78_TYPE_ATTR_STATUS_ACC)
01426 {
01427 Ret = saf78_SAF_RC_SUCCESS;
01428 PBlock->RETCODES.DISCRETE.safpb_mgr_return = 0;
01429 PBlock->RETCODES.DISCRETE.safpb_mgr_reason = 0;
01430 PBlock->REQUESTS.XAUTH.safpb_xauth_PERMISSIONS = 0;
01431 }
01432 else
01433 {
01434 Ret = saf78_SAF_RC_NOT_COMPLETE;
01435 PBlock->RETCODES.DISCRETE.safpb_mgr_return =
01436 saf78_RC_RESOURCE_NOT_PROT;
01437 PBlock->RETCODES.DISCRETE.safpb_mgr_reason =
01438 saf78_RS_NO_RESOURCE_PROF;
01439 }
01440 }
01441 }
01442
01443 if (Ret)
01444 {
01445 char UserBuf[9], ClassBuf[40], ResourceBuf[40];
01446 SafACEE *Acee;
01447 unsigned char *AceePtr;
01448 size_t Len;
01449
01450 AceePtr = (unsigned char *)PBlock->REQUESTS.XAUTH.safpb_xauth_ACEE_ptr;
01451 if (memcmp(AceePtr, SafACEE_NAME, 4) != 0) AceePtr += 8;
01452 Acee = (SafACEE *)AceePtr;
01453 memcpy(UserBuf, Acee->User, 8);
01454 UserBuf[Acee->UserLen] = '\0';
01455
01456 Len = PBlock->REQUESTS.XAUTH.safpb_xauth_CLASS_len;
01457 if (Len > sizeof ClassBuf - 1) Len = sizeof ClassBuf - 1;
01458 memcpy(ClassBuf, PBlock->REQUESTS.XAUTH.safpb_xauth_CLASS_ptr, Len);
01459 ClassBuf[Len] = '\0';
01460
01461 Len = PBlock->REQUESTS.XAUTH.safpb_xauth_ENTITY_len;
01462 if (Len > sizeof ResourceBuf - 1) Len = sizeof ResourceBuf - 1;
01463 memcpy(ResourceBuf, PBlock->REQUESTS.XAUTH.safpb_xauth_ENTITY_ptr, Len);
01464 ResourceBuf[Len] = '\0';
01465
01466 #if _DEBUG && SafLOG_ALL
01467 SafLog
01468 (
01469 2003
01470 , SafMsgINFO
01471 , "XAuth failed for user \"%s\", class \"%s\", entity \"%s\""
01472 , UserBuf
01473 , ClassBuf
01474 , ResourceBuf
01475 );
01476 #endif
01477
01478
01479 SafRaiseAuditEvent
01480 (
01481 AUDIT_EVENT_XAUTH_DENY
01482 , AUDIT_EVENT_CATEGORY_SEC_API_RES_DENY
01483 , 3
01484 , SafEventData
01485 (
01486 AUDIT_RECORD_DATA_TYPE_STRING
01487 , UserBuf
01488 , (int)strlen(UserBuf)
01489 )
01490 , SafEventData
01491 (
01492 AUDIT_RECORD_DATA_TYPE_STRING
01493 , ClassBuf
01494 , (int)strlen(ClassBuf)
01495 )
01496 , SafEventData
01497 (
01498 AUDIT_RECORD_DATA_TYPE_STRING
01499 , ResourceBuf
01500 , (int)strlen(ResourceBuf)
01501 )
01502 );
01503
01504 }
01505
01506 done:
01507 if (PBlock) PBlock->RETCODES.DISCRETE.safpb_api_rc = Ret;
01508 return Ret;
01509 }
01510
01511
01512
01527 int SafStat(struct safpb_parameter_block *PBlock)
01528 {
01529 int Ret = saf78_SAF_RC_NOT_COMPLETE;
01530
01531 if (PBlock) PBlock->RETCODES.DISCRETE.safpb_api_rc = Ret;
01532 return Ret;
01533 }
01534
01535
01536
01551 int SafAudit(struct safpb_parameter_block *PBlock)
01552 {
01553 int Ret = saf78_SAF_RC_NOT_COMPLETE;
01554
01555 if (PBlock) PBlock->RETCODES.DISCRETE.safpb_api_rc = Ret;
01556 return Ret;
01557 }
01558
01559
01560
01561
01575 int SafAdmin(struct safpb_parameter_block *PBlock)
01576 {
01577 int Ret;
01578 mf_uns32 CurrEsm, EsmRet;
01579 const char *ErrType = NULL;
01580 int ReqType = -1, IsList = 0;
01581 SafACEE *AceePtr = NULL;
01582 const char *CmdName = "invalid";
01583 int CmdLen;
01584
01585
01586 if (!PBlock)
01587 return 0;
01588
01589
01590 AceePtr = PBlock->REQUESTS.ADMIN.safpb_admin_ACEE_ptr;
01591
01592 if (PBlock->safpb_type > 0 &&
01593 PBlock->safpb_type < sizeof sSafCommands / sizeof *sSafCommands)
01594 {
01595 CmdName = sSafCommands[PBlock->safpb_type-1].safadmin_cmdname;
01596 CmdLen = sSafCommands[PBlock->safpb_type-1].safadmin_cmdlen;
01597 }
01598 else
01599 {
01600 CmdLen = (int)strlen(CmdName);
01601 }
01602
01603
01604 if (SafState() != 1)
01605 {
01606 Ret = saf78_SAF_RC_FAILURE;
01607 PBlock->RETCODES.DISCRETE.safpb_mgr_return = saf78_RC_DATABASE_ERROR;
01608 goto done;
01609 }
01610
01611
01612 switch (PBlock->safpb_type)
01613 {
01614 case saf78_TYPE_ADMIN_LISTUSER:
01615 case saf78_TYPE_ADMIN_LISTGROUP:
01616 case saf78_TYPE_ADMIN_LISTRES:
01617 case saf78_TYPE_ADMIN_LISTCLASS:
01618 ReqType = AUDIT_EVENT_ADMIN_LIST;
01619 IsList = 1;
01620 break;
01621 case saf78_TYPE_ADMIN_ADDUSER:
01622 case saf78_TYPE_ADMIN_ADDGROUP:
01623 case saf78_TYPE_ADMIN_ADDRES:
01624 case saf78_TYPE_ADMIN_ADDCLASS:
01625 ReqType = AUDIT_EVENT_ADMIN_ADD;
01626 break;
01627 case saf78_TYPE_ADMIN_DELUSER:
01628 case saf78_TYPE_ADMIN_DELGROUP:
01629 case saf78_TYPE_ADMIN_DELRES:
01630 case saf78_TYPE_ADMIN_DELCLASS:
01631 ReqType = AUDIT_EVENT_ADMIN_DELETE;
01632 break;
01633 case saf78_TYPE_ADMIN_ALTUSER:
01634 case saf78_TYPE_ADMIN_ALTGROUP:
01635 case saf78_TYPE_ADMIN_ALTRES:
01636 case saf78_TYPE_ADMIN_ALTCLASS:
01637 ReqType = AUDIT_EVENT_ADMIN_ALTER;
01638 break;
01639 case saf78_TYPE_ADMIN_SETPSWD:
01640 ReqType = AUDIT_EVENT_ADMIN_SETPWD;
01641 break;
01642 case saf78_TYPE_ADMIN_SETOPTS:
01643 ReqType = AUDIT_EVENT_ADMIN_SETOPT;
01644 break;
01645 }
01646
01647 if (PBlock->safpb_type == saf78_TYPE_ADMIN_FREELIST) IsList = 1;
01648
01649
01650 if (ReqType >= 0)
01651 {
01652 Ret = AuditAdminReq(PBlock, ReqType, AceePtr, CmdName, CmdLen);
01653
01654 if (Ret)
01655 {
01656
01657 goto done;
01658 }
01659 }
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669 if (AceePtr && (AceePtr->Flag3 & SafACEE_F3_NPWR))
01670 {
01671 static int AllowList = -1;
01672 char *ALVal = NULL;
01673
01674 if (AllowList < 0)
01675 {
01676
01677
01678
01679
01680
01681 SafQueryCfg("Admin", "allow-list", &ALVal);
01682 AllowList = (ALVal && tolower((unsigned char)*ALVal) == 'y');
01683 }
01684
01685
01686
01687
01688
01689
01690 if (!IsList || !AllowList)
01691 {
01692 SafLog
01693 (
01694 106
01695 , SafMsgERR
01696 , "Admin request denied for unauthenticated user"
01697 );
01698 Ret = saf78_SAF_RC_FAILURE;
01699 PBlock->RETCODES.DISCRETE.safpb_mgr_return = saf78_RC_DENIED;
01700 goto done;
01701 }
01702 }
01703
01704
01705
01706
01707
01708
01709 if (ReqType == AUDIT_EVENT_ADMIN_LIST)
01710 {
01711 PBlock->REQUESTS.ADMIN.safpb_admin_LIST_ptr = malloc
01712 (
01713 SafESM_MAX * sizeof *PBlock->REQUESTS.ADMIN.safpb_admin_LIST_ptr
01714 );
01715
01716 if (! PBlock->REQUESTS.ADMIN.safpb_admin_LIST_ptr)
01717 {
01718 Ret = saf78_SAF_RC_FAILURE;
01719 PBlock->RETCODES.DISCRETE.safpb_mgr_return = saf78_RC_DATABASE_ERROR;
01720 goto done;
01721 }
01722 }
01723
01724
01725
01726 HandlePendingUpdates(NULL);
01727
01728
01729
01730 if (PBlock->safpb_safesm_index)
01731 {
01732
01733
01734
01735
01736
01737
01738
01739 CurrEsm = PBlock->safpb_safesm_index;
01740
01741
01742 EsmRet = SafEsmCAdmin(PBlock->safpb_safesm_index - 1, PBlock);
01743 if (! EsmRet)
01744 Ret = PBlock->RETCODES.DISCRETE.safpb_api_rc;
01745 }
01746
01747 else
01748 {
01749
01750 PBlock->RETCODES.DISCRETE.safpb_api_rc = saf78_SAF_RC_NOT_COMPLETE;
01751 PBlock->RETCODES.DISCRETE.safpb_mgr_return = 0;
01752 PBlock->RETCODES.DISCRETE.safpb_mgr_reason = 0;
01753
01754 Ret = saf78_SAF_RC_NOT_COMPLETE;
01755
01756 for (CurrEsm=0, EsmRet = 0;
01757 CurrEsm < NumESMMods && Ret <= saf78_SAF_RC_NOT_COMPLETE && !EsmRet;
01758 CurrEsm++)
01759 {
01760
01761
01762 PBlock->safpb_safesm_index = (unsigned char) CurrEsm + 1;
01763
01764
01765 EsmRet = SafEsmCAdmin(CurrEsm, PBlock);
01766
01767
01768 switch (EsmRet)
01769 {
01770
01771 case SafESMRC_OK:
01772
01773 Ret = PBlock->RETCODES.DISCRETE.safpb_api_rc;
01774 break;
01775
01776 case SafESMRC_NOTIMPL:
01777
01778 EsmRet = 0;
01779 break;
01780
01781
01782 default:
01783 break;
01784 }
01785 }
01786 }
01787
01788
01789 if (EsmRet > SafESMRC_NOTIMPL) ErrType = EsmrcToString(EsmRet);
01790 if (ErrType)
01791 {
01792
01793 SafLog
01794 (
01795 113
01796 , SafMsgERR
01797 , "ESM Module %d (%s) returned error code %d (%s) from Admin"
01798 , CurrEsm
01799 , SafEsmName(CurrEsm-1)
01800 , (int)EsmRet
01801 , ErrType
01802 );
01803
01804
01805 Ret = saf78_SAF_RC_FAILURE;
01806 PBlock->RETCODES.DISCRETE.safpb_mgr_return =
01807 saf78_RC_DATABASE_ERROR;
01808 }
01809
01810 done:
01811
01812 if (Ret && PBlock)
01813 {
01814 SafLog
01815 (
01816 103
01817 , SafMsgWARN
01818 , "Admin %.*s request failed: %d"
01819 , CmdLen
01820 , CmdName
01821 , (int) Ret
01822 );
01823
01824
01825 if (AceePtr) SafRaiseAuditEvent
01826 (
01827 AUDIT_EVENT_ADMIN_ESM_ERROR
01828 , AUDIT_EVENT_CATEGORY_SEC_API_RES_ERROR
01829 , 3
01830 , SafEventData
01831 (
01832 AUDIT_RECORD_DATA_TYPE_STRING
01833 , CmdName
01834 , CmdLen
01835 )
01836 , SafEventData
01837 (
01838 AUDIT_RECORD_DATA_TYPE_COMP5
01839 , & PBlock->safpb_type
01840 , sizeof PBlock->safpb_type
01841 )
01842 , SafEventData
01843 (
01844 AUDIT_RECORD_DATA_TYPE_STRING
01845 , AceePtr->User
01846 , AceePtr->UserLen
01847 )
01848 );
01849 }
01850
01851 if (! Ret)
01852 {
01853
01854 if (AceePtr) SafRaiseAuditEvent
01855 (
01856 AUDIT_EVENT_ADMIN_SUCCESS
01857 , AUDIT_EVENT_CATEGORY_SEC_API_RES_SUCCESS
01858 , 3
01859 , SafEventData
01860 (
01861 AUDIT_RECORD_DATA_TYPE_STRING
01862 , CmdName
01863 , CmdLen
01864 )
01865 , SafEventData
01866 (
01867 AUDIT_RECORD_DATA_TYPE_COMP5
01868 , & PBlock->safpb_type
01869 , sizeof PBlock->safpb_type
01870 )
01871 , SafEventData
01872 (
01873 AUDIT_RECORD_DATA_TYPE_STRING
01874 , AceePtr->User
01875 , AceePtr->UserLen
01876 )
01877 );
01878 }
01879
01880 if (PBlock) PBlock->RETCODES.DISCRETE.safpb_api_rc = Ret;
01881 return Ret;
01882 }
01883
01884
01885
01886
01887
01888
01889 static SafRet AddAuditParam(struct TEventData *AuditParams[],
01890 unsigned *IdxPtr,
01891 int Type, const void *Data, int Length)
01892 {
01893 AuditParams[*IdxPtr] = malloc(sizeof **AuditParams);
01894 if (! AuditParams[*IdxPtr]) return SafR_RESOURCE;
01895
01896 AuditParams[*IdxPtr]->data = Data;
01897 AuditParams[*IdxPtr]->datalen = Length;
01898 AuditParams[*IdxPtr]->datatype = Type;
01899
01900 *IdxPtr += 1;
01901
01902 return SafR_OK;
01903 }
01904
01905
01906
01907
01908
01909
01910
01911 static SafRet AuditAdminReq(struct safpb_parameter_block *PBlock,
01912 int ReqType, SafACEE *AceePtr,
01913 const char *CmdName, int CmdLen)
01914 {
01915 SafRet Ret = SafR_OK;
01916 struct TEventData **AuditParams = NULL;
01917 unsigned ParamIdx = 0, KVIdx = 0, TmpIdx;
01918 char **KeyValArray = NULL;
01919
01920
01921
01922
01923
01924
01925
01926 AuditParams = malloc
01927 (
01928 sizeof *AuditParams
01929 * (3 + PBlock->REQUESTS.ADMIN.safpb_admin_ARGTBL_count)
01930 );
01931 if (! AuditParams)
01932 {
01933 Ret = SafR_RESOURCE;
01934 goto done;
01935 }
01936
01937 KeyValArray = malloc
01938 (
01939 sizeof *KeyValArray * PBlock->REQUESTS.ADMIN.safpb_admin_ARGTBL_count
01940 );
01941 if (! KeyValArray)
01942 {
01943 Ret = SafR_RESOURCE;
01944 goto done;
01945 }
01946
01947
01948
01949 Ret = AddAuditParam
01950 (
01951 AuditParams
01952 , &ParamIdx
01953 , AUDIT_RECORD_DATA_TYPE_STRING
01954 , CmdName
01955 , CmdLen
01956 );
01957 if (Ret) goto done;
01958
01959
01960 Ret = AddAuditParam
01961 (
01962 AuditParams
01963 , &ParamIdx
01964 , AUDIT_RECORD_DATA_TYPE_COMP5
01965 , & PBlock->safpb_type
01966 , sizeof PBlock->safpb_type
01967 );
01968 if (Ret) goto done;
01969
01970
01971 Ret = AddAuditParam
01972 (
01973 AuditParams
01974 , &ParamIdx
01975 , AUDIT_RECORD_DATA_TYPE_STRING
01976 , AceePtr? AceePtr->User : "(anonymous)"
01977 , AceePtr? AceePtr->UserLen : 11
01978 );
01979 if (Ret) goto done;
01980
01981
01982
01983 for (KVIdx = 0;
01984 KVIdx < PBlock->REQUESTS.ADMIN.safpb_admin_ARGTBL_count;
01985 KVIdx++)
01986 {
01987 size_t KVStrLen;
01988 char *KVPtr;
01989
01990
01991 KVStrLen =
01992 PBlock->REQUESTS.ADMIN.safpb_admin_ARGTBL_ptr[KVIdx].KeyLen
01993 + 1
01994 + PBlock->REQUESTS.ADMIN.safpb_admin_ARGTBL_ptr[KVIdx].ValLen;
01995 KeyValArray[KVIdx] = malloc(KVStrLen);
01996 if (! KeyValArray[KVIdx])
01997 {
01998 Ret = SafR_RESOURCE;
01999 goto done;
02000 }
02001
02002
02003 KVPtr = KeyValArray[KVIdx];
02004 memcpy
02005 (
02006 KVPtr
02007 , PBlock->REQUESTS.ADMIN.safpb_admin_ARGTBL_ptr[KVIdx].KeyPtr
02008 , PBlock->REQUESTS.ADMIN.safpb_admin_ARGTBL_ptr[KVIdx].KeyLen
02009 );
02010 KVPtr += PBlock->REQUESTS.ADMIN.safpb_admin_ARGTBL_ptr[KVIdx].KeyLen;
02011 *KVPtr++ = '=';
02012
02013
02014 if (SafSTRCMP_CIN(KeyValArray[KVIdx], ==, "PASSWORD=", 9))
02015 {
02016 memset
02017 (
02018 KVPtr
02019 , '*'
02020 , PBlock->REQUESTS.ADMIN.safpb_admin_ARGTBL_ptr[KVIdx].ValLen
02021 );
02022 }
02023 else
02024 {
02025 memcpy
02026 (
02027 KVPtr
02028 , PBlock->REQUESTS.ADMIN.safpb_admin_ARGTBL_ptr[KVIdx].ValPtr
02029 , PBlock->REQUESTS.ADMIN.safpb_admin_ARGTBL_ptr[KVIdx].ValLen
02030 );
02031 }
02032
02033
02034 Ret = AddAuditParam
02035 (
02036 AuditParams
02037 , &ParamIdx
02038 , AUDIT_RECORD_DATA_TYPE_STRING
02039 , KeyValArray[KVIdx]
02040 , (int)KVStrLen
02041 );
02042 if (Ret) goto done;
02043 }
02044
02045
02046 Ret = SafRaiseAuditEventA
02047 (
02048 ReqType
02049 , AUDIT_EVENT_CATEGORY_SEC_API_REQ_DEFINE
02050 , ParamIdx
02051 , AuditParams
02052 );
02053
02054
02055 done:
02056 if (AuditParams)
02057 {
02058 for (TmpIdx = 0; TmpIdx < ParamIdx; TmpIdx++)
02059 free(AuditParams[TmpIdx]);
02060 free(AuditParams);
02061 }
02062
02063 if (KeyValArray)
02064 {
02065 for (TmpIdx = 0; TmpIdx < KVIdx; TmpIdx++)
02066 free(KeyValArray[TmpIdx]);
02067 free(KeyValArray);
02068 }
02069
02070 return Ret;
02071 }
02072
02073
02074
02075
02076
02077
02078
02079
02080 static const char *EsmrcToString(mf_uns32 EsmRet)
02081 {
02082 switch (EsmRet)
02083 {
02084 case SafESMRC_OK: return "no error";
02085 case SafESMRC_NOTIMPL: return "function not implemented";
02086 case SafESMRC_PARAM: return "parameter error";
02087 case SafESMRC_RESOURCE: return "resource unavailable";
02088 case SafESMRC_EXTERNAL: return "ESM error";
02089 case SafESMRC_FAIL: return "miscellaneous failure";
02090 case SafESMRC_MGRFAIL: return "ESF Manager failure";
02091 default: return "unknown error";
02092 }
02093 }
02094
02095
02096
02238
02239 static mf_uns32 UpdateSequenceNumber;
02240
02241
02242
02271 int SafUpdate(struct safpb_parameter_block *PBlock)
02272 {
02273 int Ret = saf78_SAF_RC_NOT_COMPLETE;
02274 int Locked = 0;
02275 struct UpdateCache *Cache = NULL;
02276 struct safpb_update *Update;
02277 mf_uns32 CurrEsm, EsmRet = 0;
02278 const char *ErrType = NULL;
02279 SafACEE *Acee;
02280
02281
02282 if (! PBlock) goto done;
02283
02284
02285 if (SafState() != 1)
02286 {
02287 Ret = saf78_SAF_RC_FAILURE;
02288 PBlock->RETCODES.DISCRETE.safpb_mgr_return = saf78_RC_DATABASE_ERROR;
02289 goto done;
02290 }
02291
02292
02293 Acee = PBlock->REQUESTS.UPDATE.safpb_update_ACEE_ptr;
02294 Update = &PBlock->REQUESTS.UPDATE;
02295
02296
02297 Locked = LockUpdateArea();
02298 if (Locked)
02299 {
02300 size_t Len;
02301
02302
02303 Cache = GetUpdateCache();
02304 if (! Cache) goto done;
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321 HandlePendingUpdates(Cache);
02322
02323
02324 Cache->PBlock = *PBlock;
02325 Cache->ACEE = *Acee;
02326 Cache->PBlock.REQUESTS.UPDATE.safpb_update_ACEE_ptr = &Cache->ACEE;
02327 if (Update->safpb_update_ENTITY_len > SafCACHE_MAX_ENTITY_LEN)
02328 Len = SafCACHE_MAX_ENTITY_LEN;
02329 else
02330 Len = Update->safpb_update_ENTITY_len;
02331 memcpy(Cache->Entity, Update->safpb_update_ENTITY_ptr, Len);
02332 Cache->PBlock.REQUESTS.UPDATE.safpb_update_ENTITY_len = Len;
02333
02334
02335 Cache->Sequence++;
02336 }
02337
02338
02339
02340
02341
02342
02343
02344 if (PBlock->safpb_safesm_index)
02345 {
02346
02347
02348
02349
02350
02351
02352
02353 CurrEsm = PBlock->safpb_safesm_index;
02354
02355
02356 EsmRet = SafEsmCUpdate
02357 (
02358 SafESM_UPDATE
02359 , PBlock->safpb_safesm_index - 1
02360 , PBlock
02361 );
02362
02363 if (! EsmRet) Ret = PBlock->RETCODES.DISCRETE.safpb_api_rc;
02364 }
02365 else
02366 {
02367
02368 PBlock->RETCODES.DISCRETE.safpb_api_rc = saf78_SAF_RC_NOT_COMPLETE;
02369 PBlock->RETCODES.DISCRETE.safpb_mgr_return = 0;
02370 PBlock->RETCODES.DISCRETE.safpb_mgr_reason = 0;
02371
02372 Ret = 0;
02373
02374 for (CurrEsm=0, EsmRet = 0;
02375 CurrEsm < NumESMMods && Ret <= saf78_SAF_RC_NOT_COMPLETE && !EsmRet;
02376 CurrEsm++)
02377 {
02378
02379 PBlock->safpb_safesm_index = (unsigned char) CurrEsm + 1;
02380
02381
02382 EsmRet = SafEsmCUpdate(SafESM_UPDATE, CurrEsm, PBlock);
02383
02384
02385 switch (EsmRet)
02386 {
02387 case SafESMRC_OK:
02388
02389 Ret = PBlock->RETCODES.DISCRETE.safpb_api_rc;
02390 break;
02391 case SafESMRC_NOTIMPL:
02392
02393 EsmRet = 0;
02394 break;
02395
02396 default:
02397 break;
02398 }
02399 }
02400 }
02401
02402
02403 if (Ret == saf78_SAF_RC_NOT_COMPLETE) Ret = 0;
02404
02405
02406 if (! Ret && Cache) UpdateSequenceNumber = Cache->Sequence;
02407
02408
02409
02410 done:
02411
02412
02413 if (EsmRet > SafESMRC_NOTIMPL) ErrType = EsmrcToString(EsmRet);
02414 if (ErrType)
02415 {
02416
02417 SafLog
02418 (
02419 114
02420 , SafMsgERR
02421 , "ESM Module %d (%s) returned error code %d (%s) from Update"
02422 , CurrEsm
02423 , SafEsmName(CurrEsm-1)
02424 , (int)EsmRet
02425 , ErrType
02426 );
02427
02428
02429 Ret = saf78_SAF_RC_FAILURE;
02430 PBlock->RETCODES.DISCRETE.safpb_mgr_return = saf78_RC_DATABASE_ERROR;
02431 }
02432
02433
02434 if (Locked) UnlockUpdateArea();
02435
02436
02437 if (PBlock)
02438 {
02439 char UserBuf[9], ResourceBuf[40];
02440 size_t Len;
02441 int Category, Event;
02442
02443
02444 PBlock->RETCODES.DISCRETE.safpb_api_rc = Ret;
02445
02446
02447 memcpy(UserBuf, Acee->User, 8);
02448 UserBuf[Acee->UserLen] = '\0';
02449
02450 Len = PBlock->REQUESTS.UPDATE.safpb_update_ENTITY_len;
02451 if (Len > sizeof ResourceBuf - 1) Len = sizeof ResourceBuf - 1;
02452 memcpy(ResourceBuf, PBlock->REQUESTS.UPDATE.safpb_update_ENTITY_ptr, Len);
02453 ResourceBuf[Len] = '\0';
02454
02455 if (Ret)
02456 {
02457 Category = AUDIT_EVENT_CATEGORY_SEC_API_RES_ERROR;
02458 Event = AUDIT_EVENT_UPDATE_ESM_ERROR;
02459
02460
02461 SafLog
02462 (
02463 104
02464 , SafMsgWARN
02465 , "Update (%s) request failed: %d"
02466 , UpdateTypeToString(PBlock->safpb_type)
02467 , (int) Ret
02468 );
02469 }
02470 else
02471 {
02472 Category = AUDIT_EVENT_CATEGORY_SEC_API_RES_SUCCESS;
02473 Event = AUDIT_EVENT_UPDATE_SUCCESS;
02474 }
02475
02476 SafRaiseAuditEvent
02477 (
02478 Event
02479 , Category
02480 , 4
02481 , SafEventData
02482 (
02483 AUDIT_RECORD_DATA_TYPE_STRING
02484 , UserBuf
02485 , (int)strlen(UserBuf)
02486 )
02487 , SafEventData
02488 (
02489 AUDIT_RECORD_DATA_TYPE_COMP5
02490 , &PBlock->safpb_safesm_index
02491 , (int)sizeof PBlock->safpb_safesm_index
02492 )
02493 , SafEventData
02494 (
02495 AUDIT_RECORD_DATA_TYPE_COMP5
02496 , &PBlock->REQUESTS.UPDATE.safpb_update_ACTION
02497 , (int)sizeof PBlock->REQUESTS.UPDATE.safpb_update_ACTION
02498 )
02499 , SafEventData
02500 (
02501 AUDIT_RECORD_DATA_TYPE_STRING
02502 , ResourceBuf
02503 , (int)strlen(ResourceBuf)
02504 )
02505 );
02506 }
02507
02508 #if _DEBUG && SafLOG_ALL
02509
02510 if (Ret) SafLog(2005, SafMsgINFO, "Update failed");
02511 #endif
02512
02513 return Ret;
02514 }
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541 static SafRet HandlePendingUpdates(struct UpdateCache *Cache)
02542 {
02543 SafRet Ret = SafR_OK;
02544 mf_uns32 PendingUpdates;
02545 int CallerLocked = (Cache != NULL);
02546 mf_uns32 CurrEsm, EsmRet = 0, MaxEsmRet = 0;
02547 const char *ErrType = NULL;
02548
02549
02550 if (! Cache)
02551 {
02552 if (LockUpdateArea()) Cache = GetUpdateCache();
02553 if (! Cache) goto done;
02554 }
02555
02556
02557 PendingUpdates = CheckForPendingSharedUpdate(Cache);
02558
02559 if (PendingUpdates == 1)
02560 {
02561
02562
02563
02564 if (Cache->PBlock.safpb_safesm_index)
02565 {
02566 EsmRet = SafEsmCUpdate
02567 (
02568 SafESM_UPDATED
02569 , Cache->PBlock.safpb_safesm_index - 1
02570 , & Cache->PBlock
02571 );
02572 if (! EsmRet) Ret = Cache->PBlock.RETCODES.DISCRETE.safpb_api_rc;
02573 }
02574 else
02575 {
02576 Cache->PBlock.RETCODES.DISCRETE.safpb_api_rc = 0;
02577
02578 for (CurrEsm=0, EsmRet = 0; CurrEsm < NumESMMods; CurrEsm++)
02579 {
02580 Cache->PBlock.safpb_safesm_index = (unsigned char) CurrEsm + 1;
02581 EsmRet = SafEsmCUpdate(SafESM_UPDATED, CurrEsm, &Cache->PBlock);
02582 switch (EsmRet)
02583 {
02584 case SafESMRC_OK:
02585
02586 if (Cache->PBlock.RETCODES.DISCRETE.safpb_api_rc >
02587 saf78_SAF_RC_NOT_COMPLETE)
02588 EsmRet = SafESMRC_FAIL;
02589 break;
02590 case SafESMRC_NOTIMPL:
02591
02592 EsmRet = 0;
02593 break;
02594
02595 default:
02596 break;
02597 }
02598 if (EsmRet > MaxEsmRet) MaxEsmRet = EsmRet;
02599 }
02600
02601 EsmRet = MaxEsmRet;
02602 }
02603 }
02604
02605 else if (PendingUpdates > 1)
02606 {
02607
02608
02609
02610 for (CurrEsm=0, EsmRet = 0; CurrEsm < NumESMMods; CurrEsm++)
02611 {
02612 EsmRet = SafEsmCUpdate(SafESM_REFRESH, CurrEsm, NULL);
02613 if (EsmRet == SafESMRC_NOTIMPL) EsmRet = 0;
02614 if (EsmRet > MaxEsmRet) MaxEsmRet = EsmRet;
02615 }
02616
02617 EsmRet = MaxEsmRet;
02618 }
02619
02620
02621 if (EsmRet > 0)
02622 {
02623 ErrType = EsmrcToString(EsmRet);
02624 SafLog
02625 (
02626 105
02627 , SafMsgWARN
02628 , "ESM Module %d (%s) returned error code %d (%s) from Update"
02629 " (%s)"
02630 , CurrEsm
02631 , SafEsmName(CurrEsm-1)
02632 , (int)EsmRet
02633 , ErrType
02634 , PendingUpdates == 1? "single update" : "refresh all"
02635 );
02636
02637
02638 switch (EsmRet)
02639 {
02640 case SafESMRC_PARAM: Ret = SafR_PARAM; break;
02641 case SafESMRC_RESOURCE: Ret = SafR_RESOURCE; break;
02642 case SafESMRC_EXTERNAL: Ret = SafR_EXFAIL; break;
02643 case SafESMRC_MGRFAIL: Ret = SafR_INTERNAL; break;
02644 case SafESMRC_FAIL: Ret = SafR_ESM; break;
02645 default: Ret = SafR_ESM; break;
02646 }
02647 }
02648
02649
02650 UpdateSequenceNumber = Cache->Sequence;
02651
02652 done:
02653
02654 if (! CallerLocked) UnlockUpdateArea();
02655 return Ret;
02656 }
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666 static int LockUpdateArea(void)
02667 {
02668 if (SafIsSharedMemory())
02669 {
02670 SafLockEnq
02671 (
02672 "#ESFMgr"
02673 , "AdminUpd"
02674 , SafESM_LCK_NONE
02675 , 1
02676 , SafESM_LCK_PROC
02677 );
02678 return 1;
02679 }
02680
02681 return 0;
02682 }
02683
02684 static int UnlockUpdateArea(void)
02685 {
02686 if (SafIsSharedMemory())
02687 {
02688 SafLockDeq("#ESFMgr", "AdminUpd");
02689 return 1;
02690 }
02691
02692 return 0;
02693 }
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711 static struct UpdateCache *GetUpdateCache(void)
02712 {
02713 struct UpdateCache *Cache = NULL;
02714 SafRet Ret;
02715 size_t CacheSize;
02716
02717 CacheSize = sizeof *Cache;
02718 Ret = SafShmOpen("#SafCache", &CacheSize, (void **)&Cache);
02719 if (Ret || !Cache || CacheSize != sizeof *Cache)
02720 {
02721
02722 Cache = NULL;
02723 }
02724
02725 return Cache;
02726 }
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747 static mf_uns32 CheckForPendingSharedUpdate(struct UpdateCache *Cache)
02748 {
02749 mf_uns32 Result = 0;
02750 int Locked = 0;
02751
02752
02753 if (! Cache)
02754 {
02755 Locked = LockUpdateArea();
02756
02757
02758 if (Locked) Cache = GetUpdateCache();
02759 }
02760
02761
02762 if (Cache)
02763 {
02764
02765 Result = Cache->Sequence - UpdateSequenceNumber;
02766
02767
02768 UpdateSequenceNumber = Cache->Sequence;
02769 }
02770
02771
02772 if (! Result && Locked) UnlockUpdateArea();
02773
02774
02775 return Result;
02776 }
02777
02778
02779
02780
02781
02782
02783 static const char *UpdateTypeToString(unsigned char Type)
02784 {
02785 static const char *Types[] =
02786 {
02787 "all"
02788 , "user"
02789 , "group"
02790 , "resource"
02791 , "users"
02792 , "groups"
02793 , "resources"
02794 };
02795
02796 if (Type < sizeof Types / sizeof *Types)
02797 return Types[Type];
02798 else
02799 return "unknown";
02800 }
02801
02802
02803
02804
02805