saf-env.c File Reference

ES ESF Manager Processing Environment. More...

Defines

#define WIN32_LEAN_AND_MEAN
#define snprintf   SafSnprintf
#define vsnprintf   SafVSnprintf
#define SafCOB_VER   "4.0"
#define SafCOB_KEY   "Setup"
#define SafCOB_REG_VALUE   "RootDir"
#define SafCOB_REG_PATH
#define BUF_SPACE   sizeof MsgBuf - (BufPtr - MsgBuf)
#define SafRAND_MAX   139967UL

Typedefs

typedef void * cobdlhandle

Enumerations

enum  { SafMIXEDCASE = 0, SafUPPERCASE, SafLOWERCASE }

Functions

cobrtncode_t cobdlload (int, const char *, cobdlhandle *)
cobrtncode_t cobdlgetsym (int, cobdlhandle, const char *, PFI *)
cobrtncode_t cobdlunload (cobdlhandle)
mf_uns32 SafEnvInit (struct SafInit *Init)
 ESF Environment Initialization.
SafRet SafModLoad (const char *ModPath, struct SafPTab *(**Entry)(void))
 Load a module.
SafRet SafModUnload (const char *ModPath)
 Unload a module.
int SafStrcmpCI (const char *Str1, const char *Str2)
 Case-insensitive string comparison.
int SafStrcmpCIN (const char *Str1, const char *Str2, size_t Len)
 Case-insensitive string comparison (length-limited).
char * SafDupStr (const char *Str)
 Duplicate a string.
SafRet SafShmOpen (const char *Name, size_t *Size, void **Area)
 Open named "shared" memory.
SafRet SafGetInstPath (char *Path, size_t MaxLen)
 Get product installation base path.
int CBL_NLS_GET_MSG (const char *, const char *, const char *, cbl_nls_msg_params_t *, char *, cbl_nls_msg_ins_struct_t *)
SafRet SafLog (int Num, enum SafMsgLvl Level, const char *DefaultText,...)
 Log a message.
SafRet SafLogLit (int Num, enum SafMsgLvl Level, const char *Text)
 Log a literal message.
SafRet SafAceeAlloc (const char *Name, const char *Group, struct SafACEE **AceeP, int *IsNew)
 Allocate an ACEE.
SafRet SafAceeIterate (void *Data, int(*Callback)(struct SafACEE *Acee, void *Data))
 Iterate over ACEEs.
SafLockRet SafLockEnq (const char *QName, const char *RName, int Type, int Exclusive, int Lifetime, struct SafLockInfo *Info)
 Acquire a named lock (enqueue).
SafLockRet SafThrLock (const char *Name, int Exclusive)
 Acquire a named lock, if the environment is multithreaded.
SafLockRet SafShmLock (const char *Name, int Exclusive)
 Acquire a named lock, if the environment uses shared memory.
SafLockRet SafLockDeq (const char *QName, const char *RName, struct SafLockInfo *Info)
 Release a named lock (dequeue).
SafLockRet SafThrUnlock (const char *Name)
 Release a named lock, if the environment is multithreaded.
SafLockRet SafShmUnlock (const char *Name)
 Release a named lock, if the environment uses shared memory.
int SafIsMT (void)
 Identify multithreaded environments.
int SafIsSharedMemory (void)
 Identify multiprocess shared-memory environments.
unsigned long SafThreadId (void)
 Get the current thread ID.
const char * SafServerName (void)
 Get the server name.
SafRet SafGetEnvFunc (PFI *FuncP, const char *Name, const char *Env)
 Resolve environment functions.
SafRet SafIncreaseLockWaitTimeout (int Timeout)
 Increase lock wait time.
int SafVSnprintf (char *Buffer, size_t BufLen, const char *Format, va_list Args)
int SafSnprintf (char *Buffer, size_t BufLen, const char *Format,...)
mf_uns32 SafGetProcessID (void)
 Get a process ID.
unsigned long SafRandom (unsigned long Range)
 Simple pseudo-random number generator.

Variables

int SafCasOldAcee = 0
 Old ACEE Format Flag.

Detailed Description

ES ESF Manager Processing Environment.

The ESF Manager runs in two rather different environments: in ES SEP processes under CAS, and in MFDS. In the former it's running in a collection of single-threaded processes communicating via shared memory and with an extensive collection of support routines provided by the COBOL RTS and CAS. In the latter, it's running in a single multi-threaded process and mostly using low-level OS and CCI services (though here too it uses the COBOL RTS for some functions). There are also differences in logging mechanisms and so forth.

This module provides a set of cover routines that the Manager and the ESM Modules it loads can use for various environmental-specific functions.


Define Documentation

#define SafCOB_REG_PATH
Value:
"NetExpress\\" SafCOB_VER "\\COBOL\\" \
            SafCOB_VER "\\" SafCOB_KEY

Function Documentation

mf_uns32 SafEnvInit ( struct SafInit Init  ) 

ESF Environment Initialization.

For internal use only.

This function is invoked by the ESF Manager Initialization routine to set the processing environment.

Parameters:
[in] Init ESF Manager initialization area (see SafInit).
Returns:
An integer value, zero for success and non-zero if initialization failed. See ESF Manager Initialization Return Codes and ESF Manager Initialization Internal Return Codes.

References SafInit::Config, SafInit::Environment, SafDupStr(), SafENV_CAS, SafENV_MFDS, SafENV_MTOMASK, SafENV_SOLO, SafINIT_ENV, SafINIT_INTERNAL, SafINIT_OK, SafLog(), SafMsgINFO, SafMsgWARN, and SafInit::ServerName.

Referenced by safmgr().

SafRet SafModLoad ( const char *  ModPath,
struct SafPTab *(**)(void)  Entry 
)

Load a module.

Load the named module into the process. The module should be an OS loadable object (DLL on Windows, CSO on Unix); on Windows, it is also possible to use a loadable COBOL module (int code or gnt code), but this is discouraged (because of poor error reporting by cobgetfuncaddr and other issues).

All modules loaded by ESF Manager follow the same conventions: they export an initial entry point which takes no parameters and returns a pointer to an array of function pointers. See the ESM Module Interface.

Parameters:
[in] ModPath Pathname of module to load. Searching the load path is also supported, but unwise (since this is security-sensitive). Note that the ESM Interface always passes an absolute path.
[out] Entry Pointer to function pointer which will be set to the initial entry point exported by the module.
Returns:
Zero for success or a SafRet value for failure.

References SafDupStr(), SafR_EXFAIL, SafR_INTERNAL, SafR_INVALID, SafR_NOTFOUND, SafR_OK, SafR_PARAM, SafR_RESOURCE, SafSTRCMP, SafThrLock(), and SafThrUnlock().

SafRet SafModUnload ( const char *  ModPath  ) 

Unload a module.

Unload the named module, if it was previously loaded by SafModLoad. The ModPath parameter must match the path passed to SafModLoad.

Parameters:
[in] ModPath Pathname of module to unload.
Returns:
Zero for success or a SafRet value for failure.

References SafR_EXFAIL, SafR_NOTFOUND, SafR_OK, SafR_PARAM, SafSTRCMP, SafThrLock(), and SafThrUnlock().

Referenced by SafEsmUnload().

int SafStrcmpCI ( const char *  Str1,
const char *  Str2 
)

Case-insensitive string comparison.

Like strcmp, but case-insensitive (in the current locale). Can be used with the SafSTRCMP_CI macro.

Parameters:
[in] Str1 First string to be compared.
[in] Str2 Second string to be compared.
Returns:
One of {-1,0,1}, if Str1 is less than, equal to, or greater than Str2. Null pointers compare equal to each other and less than anything else (including an empty string).
int SafStrcmpCIN ( const char *  Str1,
const char *  Str2,
size_t  Len 
)

Case-insensitive string comparison (length-limited).

Like strncmp, but case-insensitive (in the current locale). Can be used with the SafSTRCMP_CIN macro.

Parameters:
[in] Str1 First string to be compared.
[in] Str2 Second string to be compared.
[in] Len Maximum number of characters to compare.
Returns:
One of {-1,0,1}, if Str1 is less than, equal to, or greater than Str2. Null pointers compare equal to each other and less than anything else (including an empty string).
char* SafDupStr ( const char *  Str  ) 

Duplicate a string.

Attempts to duplicate a string, allocating the new area and copying the source to it. Returns null if allocation fails. A null input is treated as the empty string.

Freeing the data is the caller's responsibility.

Parameters:
[in] Str String to be copied.
Returns:
New string or null.

Referenced by SafCacheInit(), SafEnvInit(), SafModLoad(), SafStoreAdd(), and SafStoreLoad().

SafRet SafShmOpen ( const char *  Name,
size_t *  Size,
void **  Area 
)

Open named "shared" memory.

Attach to an existing named memory area, or create it if it does not already exist. The area will be available to all ESF Manager and ESM Module instances in the current environment. In CAS, that means it's actually in the CAS shared memory segment; in MFDS, it's normal process-private memory.

Parameters:
[in] Name Name of the area being opened.
[in,out] Size Size of the area to create, if it does not already exist; actual size on return, if it does already exist.
[out] Area Returns a pointer to the area.
Returns:
Zero for success or a SafRet value for failure.

References SafR_PARAM, and SafR_STATE.

Referenced by EsmGetSharedMem().

SafRet SafGetInstPath ( char *  Path,
size_t  MaxLen 
)

Get product installation base path.

Determine the base path for the current product.

Parameters:
[out] Path Buffer for returned path, as a null-terminated string.
[in] MaxLen Maximum length of the returned path, including the terminating null.
Returns:
Zero for success or a SafRet value for failure.

References SafR_EXFAIL, SafR_NOTFOUND, SafR_OK, SafR_RESOURCE, and SafR_TRUNCATED.

SafRet SafLog ( int  Num,
enum SafMsgLvl  Level,
const char *  DefaultText,
  ... 
)

Log a message.

Log a message with an environment-specific logging facility. We attempt to get message text for the current language (using the COBOL RTS NLS routines); if that fails, we use the default text supplied by the caller. (This is also convenient for developers and maintainers, who can see what message is being logged without looking up the message number.) Messages are treated as snprintf format strings, but they're scanned and only message text with whitelisted substitutions are allowed through.

NLS implementation notes: CBL_NLS_GET_MSG is used to retrieve message text on all platforms. CBL_NLS_GET_MSG will do formatting, but we don't let it; all the messages in the catalog should have percent-signs doubled to prevent CBL_NLS_GET_MSG from trying to process them. See safmgr.err for examples; that's also where new messages should be added. safmgr.err is compiled into safmgr.lng, which should go in the same directory as the ESF Manager shared object.

Parameters:
[in] Num Message number (see ESF Manager Messages and Logging)
[in] Level Message level (see SafMsgLvl)
[in] DefaultText Default message text
[in] ... Substitution parameters
Returns:
Zero for success or a SafRet value for failure.

References SafR_EXFAIL, SafR_INTERNAL, SafR_OK, SafR_PARAM, and SafR_STATE.

Referenced by SafAdmin(), SafAuth(), SafCacheInit(), SafEnvInit(), SafEsmExit(), SafEsmInit(), SafGetEnvFunc(), safmgr(), SafRaiseAuditEvent(), SafUpdate(), SafVerify(), and SafXauth().

SafRet SafLogLit ( int  Num,
enum SafMsgLvl  Level,
const char *  Text 
)

Log a literal message.

This is similar to SafLog(), except that it does no formatting other than prefixing the message with the prefix, number, and level indicator. (Some of that may be environmentally specific, which is why it happens here.) Also, no NLS lookup is performed.

Parameters:
[in] Num Message number, as for SafLog().
[in] Level Message level, as for SafLog().
[in] Text Formatted message text.
Returns:
Zero for success or a SafRet value for failure.

References SafR_EXFAIL, SafR_PARAM, and SafR_STATE.

SafRet SafAceeAlloc ( const char *  Name,
const char *  Group,
struct SafACEE **  AceeP,
int *  IsNew 
)

Allocate an ACEE.

Allocate or find an ACEE structure. Every verified user has an ACEE; this function will locate the ACEE if it exists, or create one if it does not. In the CAS environment, ACEEs are shared and managed by the environment; in other environments, we fake them.

The full key for the ACEE is actually Name and Group, since users can sign in under different groups. (This has no effect under some ESMs, but others honor it.)

Parameters:
[in] Name The unique name for the ACEE, which should be the user's short name (max 8 characters).
[in] Group Optional group name (max 8 characters).
[out] AceeP The returned ACEE pointer.
[out] IsNew Optional flag for whether this ACEE was created new (or an existing one was retrieved).
Returns:
Zero for success or a SafRet value for failure.

References SafR_PARAM, SafR_RESOURCE, and SafR_STATE.

Referenced by EsmGetAcee(), and SafVerify().

SafRet SafAceeIterate ( void *  Data,
int(*)(struct SafACEE *Acee, void *Data)  Callback 
)

Iterate over ACEEs.

Iterate over all existing ACEE structures. Every verified user has an ACEE; in all-groups mode, each verified {user, signon-group} pair will have a distinct ACEE. This function calls a callback supplied by the caller for each ACEE.

Iteration ends with the last ACEE, or when the callback returns a non-zero value.

Parameters:
[in] Data Pointer to any data the caller wishes to pass to the callback. (This could be an allocated area which the callback uses to pass data back to the caller, of course.)
[in] Callback A pointer to a function/procedure that takes a pointer to an ACEE and a pointer to arbitrary data (which will be the Data parameter described above), and returning an int.
Returns:
Zero for success or a SafRet value for failure. This will be the final value returned by the callback, unless an error occurs in the iterator itself. Typically, a callback will return 0 unless it wishes to end iteration (eg because it has found and processed the only ACEE it's interested in), which it can do by returning eg SafR_END. If there are no ACEEs, the function will return SafR_NOMORE.

References SafR_PARAM, and SafR_STATE.

Referenced by EsmAceeIterate().

SafLockRet SafLockEnq ( const char *  QName,
const char *  RName,
int  Type,
int  Exclusive,
int  Lifetime,
struct SafLockInfo Info 
)

Acquire a named lock (enqueue).

Enqueue on a named lock object. See EsmLockEnq() for more information.

Parameters:
[in] QName Queue (class) name of lock object, a nul-terminated string (max 8 characters, no spaces)
[in] RName Resource name of lock object, a nul-terminated string (max 255 characters)
[in] Type Operation type; see Lock Operation Types
[in] Exclusive Whether lock is shared (zero) or exclusive (non-zero); see Lock Exclusivity
[in] Lifetime Lock lifetime; see Lock Lifetimes
[in] Info Optional information about the request
Returns:
Zero for success or a SafLockRet value for error.

References SafESM_LCK_NONE, SafESM_LCK_PROC, SafLockERR, and SafLockPARAM.

Referenced by EsmLockEnq(), SafShmLock(), and SafThrLock().

SafLockRet SafThrLock ( const char *  Name,
int  Exclusive 
)

Acquire a named lock, if the environment is multithreaded.

If MultiThreaded is set, call the real locking function; otherwise a no-op. See EsmLockEnq() for more information. QName is always "#ESFMgr"; Type is always SafESM_LCK_NONE; Lifetime is always SafESM_LCK_PROC.

Parameters:
[in] Name Resource name of lock object, a nul-terminated string (max 255 characters)
[in] Exclusive Whether lock is shared (zero) or exclusive (non-zero); see Lock Exclusivity
Returns:
Zero for success or a SafLockRet value for error.

References SafESM_LCK_NONE, SafESM_LCK_PROC, and SafLockEnq().

Referenced by safmgr(), SafModLoad(), SafModUnload(), and safterm().

SafLockRet SafShmLock ( const char *  Name,
int  Exclusive 
)

Acquire a named lock, if the environment uses shared memory.

If SharedMemory is set, call the real locking function; otherwise a no-op. See EsmLockEnq() for more information. QName is always "#ESFMgr"; Type is always SafESM_LCK_NONE; Lifetime is always SafESM_LCK_PROC.

Parameters:
[in] Name Resource name of lock object, a nul-terminated string (max 255 characters)
[in] Exclusive Whether lock is shared (zero) or exclusive (non-zero); see Lock Exclusivity
Returns:
Zero for success or a SafLockRet value for error.

References SafESM_LCK_NONE, SafESM_LCK_PROC, and SafLockEnq().

SafLockRet SafLockDeq ( const char *  QName,
const char *  RName,
struct SafLockInfo Info 
)

Release a named lock (dequeue).

Dequeue on a named lock object. See EsmLockDeq() for more information.

Parameters:
[in] QName Queue (class) name of lock object, a nul-terminated string (max 8 characters, no spaces)
[in] RName Resource name of lock object, a nul-terminated string (max 255 characters)
[in] Info Optional information about the request
Returns:
Zero for success or a SafLockRet value for error.

References SafLockERR, and SafLockPARAM.

Referenced by EsmLockDeq(), SafShmUnlock(), and SafThrUnlock().

SafLockRet SafThrUnlock ( const char *  Name  ) 

Release a named lock, if the environment is multithreaded.

If MultiThreaded is set, call the real locking function; otherwise a no-op. See EsmLockDeq() for more information. QName is always "#ESFMgr".

Parameters:
[in] Name Resource name of lock object, a nul-terminated string (max 255 characters)
Returns:
Zero for success or a SafLockRet value for error.

References SafLockDeq().

Referenced by safmgr(), SafModLoad(), SafModUnload(), and safterm().

SafLockRet SafShmUnlock ( const char *  Name  ) 

Release a named lock, if the environment uses shared memory.

If SharedMemory is set, call the real locking function; otherwise a no-op. See EsmLockDeq() for more information. QName is always "#ESFMgr".

Parameters:
[in] Name Resource name of lock object, a nul-terminated string (max 255 characters)
Returns:
Zero for success or a SafLockRet value for error.

References SafLockDeq().

int SafIsMT ( void   ) 

Identify multithreaded environments.

Return the value of the MultiThreaded internal variable, which is non-zero if the environment is multithreaded.

Returns:
Zero for single-threaded environments, non-zero for multithreaded.

Referenced by EsmSafQuery(), and SafAllocStore().

int SafIsSharedMemory ( void   ) 

Identify multiprocess shared-memory environments.

Return the value of the SharedMemory internal variable, which is non-zero if the environment has multiple processes commmunicating with shared memory.

Returns:
Zero for non-shared-memory environments, non-zero for shared-memory environments.
unsigned long SafThreadId ( void   ) 

Get the current thread ID.

Return the current numerical OS thread ID, or 0 if the process is not multithreaded.

Returns:
A numerical thread ID or 0.

Referenced by EsmSafQuery().

const char* SafServerName ( void   ) 

Get the server name.

Return the name of the server (region) in CAS environments; the string "-MFDS-" in the MFDS environment; and the string "-SOLO-" in the solo environment.

Returns:
A const char string.

Referenced by EsmSafQuery().

SafRet SafGetEnvFunc ( PFI *  FuncP,
const char *  Name,
const char *  Env 
)

Resolve environment functions.

Search for a named function in the current process. This is used internally by ESF Manager for resolving functions in the MFDS environment, and possibly for other purposes.

Parameters:
[out] FuncP Returned function pointer, a pointer to the PFI (pointer to function returning int) type defined by the COBOL RTS
[in] Name Function name
[in] Env Environment name (eg "MFDS"), used for error logging
Returns:
Zero for success or a SafRet value for failure.

References SafLog(), SafMsgCRIT, SafR_NOTFOUND, and SafR_OK.

Referenced by SafInitAuditing().

SafRet SafIncreaseLockWaitTimeout ( int  Timeout  ) 

Increase lock wait time.

For internal use only.

If the lock wait time (see LockSem) is less than the supplied value (in seconds), increase it so it's at least as great as the supplied value. Note that the lock wait is now implemented with a ten-second granularity, so we'll round up to the nearest 10 seconds.This is used by the MLDAP ESM Module if an optional LDAP-request timeout is specified in the Security Manager configuration, and its value is greater than the four-minute default lock timeout. (Actually the MLDAP ESM Module will call this function, via EsmSafControl, regardless of the value, if one is configured; that way it doesn't have any dependency on the default value specified in this file.) It prevents a lock timeout while the module is still waiting for a slow LDAP function to complete.

Parameters:
[in] Timeout Requested lock timeout, in seconds.
Returns:
Zero for success or a SafRet value for failure. If the existing lock time is already greater than the requested time, SafR_STATE (4) is returned.

References SafR_OK, and SafR_STATE.

Referenced by EsmSafControl().

mf_uns32 SafGetProcessID ( void   ) 

Get a process ID.

Return some integer value representing a process ID. This is currently unused; it was initially implemented for use by saf-cache, but that uses SafRandom now.

unsigned long SafRandom ( unsigned long  Range  ) 

Simple pseudo-random number generator.

This is a simple LC-PRNG, similar to the C runtime library's rand, but we use our own implementation because a library shouldn't interfere with the state of rand (in case the caller is using it). This generator is basically copied from the one I implemented for MFCS/MFCC (see GkRandom in ossvc.c); its values come from /Numerical Recipies/ via /Applied Cryptography/.

Parameters:
Range The range for the returned value. This is clamped at 139966.
Returns:
An integer value in [0, Range).

Variable Documentation

int SafCasOldAcee = 0

Old ACEE Format Flag.

For internal use only.

This flag is set if CAS is using the old ACEE format, with the initial SAA structure included.

Referenced by SafVerify().