#ifndef __SECURITY_MACROS_LOADED #define __SECURITY_MACROS_LOADED 1 /* IDENT X-7 */ /***************************************************************************** * * * COPYRIGHT (c) 1996, 1997 BY * * DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. * * COPYRIGHT (c) 2000 Compaq Computer Corporation * * ALL RIGHTS RESERVED. * * * * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED * * ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE * * INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER * * COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY * * OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY * * TRANSFERRED. * * * * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE * * AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT * * CORPORATION. * * * * DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS * * SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. * * * *****************************************************************************/ /* *++ * FACILITY: * * VMS Executive (LIB_H) * * ABSTRACT: * * This header file provides macros and functions that are used * for security services. * * AUTHOR: * * Bill Davenport * * CREATION DATE: 17-Apr-1996 * * MODIFICATION HISTORY: * * X-7 JAH0453 John A Harney 12-Nov-2003 * Dereference the privilege pointers in $PSB$ENABLE_PRIVILEGES. * * X-2 Douglas Fyfe 28-Feb-2000 * Use new 32-bit defined pointers for persona structures * * X-1 AJM Andrew J. Moskal 25-Feb-1997 * Add FLAGS parameter to NSA_STD$ASSUME_PERSONA prototype. * * Shuan Lin 24-Jan-1997 * Mainline merge of Per-Thread Security support: (gen 4A3) * * X-3A7 Shuan Lin 13-Feb-1997 * Simplified GET_CURPSB code. * * X-3A6 Shuan Lin 7-Feb-1997 * Remove the paranoid stuff. * Rewrite macro get_curpsb to use nsa$get_current_psb routine. * * X-3A5 Shuan Lin 24-Jan-1997 * Fix the comment problem. * * X-3A4 Shuan Lin 23-Jan-1997 * Rewrite GET_CURPSB to support backward compatibility. * * X-3A3 Shuan Lin 31-Oct-1996 * Support backward compatibility. * * X-3A2 AJM96060 Andrew J. Moskal 30-Jun-1996 * In GET_CURPSB, don't check mode if persona is already active. * * X-3A1 WXD Bill Davenport 16-Jul-1996 * Rename min macro to avoid conflicts. * * X-3 JMM960A7 John M. Molloy 28-May-1996 * Incorporate comments from code review: * -- Add NEW_STARLET support. * * X-2 WXD Bill Davenport 8-May-1996 * Added additional macros and supporting documentation. * * X-1 WXD Bill Davenport 17-Apr-1996 * Created initial version. *-- */ /* * Include any header files we need to make these macros work */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ___TRUE___ (0 == 0) #define ___FALSE___ (0 == 1) #define JIB$K_SIZE_ACCOUNT sizeof(((JIB *) 0)->jib$t_account) #define JIB$K_SIZE_USERNAME sizeof(((JIB *) 0)->jib$t_username) #define $_$_$min$_$_$(e1,e2) (((e1) <= (e2)) ? (e1) : (e2)) #ifdef __INITIAL_POINTER_SIZE #pragma __required_pointer_size __save #pragma __required_pointer_size __short #endif /* global symbol */ extern int ctl$gl_persona_usercount; /* * Function prototypes for global functions */ extern int EXE$PERSONA_EXPORT_ARB (int level); extern int EXE$PERSONA_IMPORT_ARB (int level); extern int NSA_STD$GET_CURRENT_PSB (KTB *ktb, PSB_ps *Psb); extern int NSA_STD$ASSUME_PERSONA (int personaId, KTB *ktb, int previousMode, ISSSRVCFLG flags); extern int NSA_STD$CLONE_PSB (PSB_ps psb, int mode, PSB_ps *newPsb); extern void NSA_STD$DEREFERENCE_PSB (PSB_ps psb); extern void NSA_STD$FREE_PSB (PSB_ps psb); extern int NSA_STD$GET_PSB (int size, PSB_ps *psb); extern int NSA_STD$EXPAND_PERSONA_ARRAY (void); extern int NSA_STD$INIT_PERSONA_ARRAY (PSB_ps naturalPsb); extern int NSA_STD$LAZY_PERSONA_ASSUME (void); extern int NSA_STD$LOOKUP_PERSONA (int personaId, int previousMode, PSB_ps *psb); extern void NSA_STD$REFERENCE_PSB (PSB_ps psb); extern int NSA_STD$RELEASE_PERSONA_ARRAY (void); extern int NSA_STD$REMOVE_PERSONA (PSB_ps psb); extern int NSA_STD$STORE_PERSONA (PSB_ps psb, int *personaId); extern int NSA_STD$ADD_RIGHTS_IDENTIFIER (RIGHTS_ps rights, int identifier, int flags, int *prevFlags, RIGHTS_ps *clonedRights); extern int NSA_STD$CLONE_RIGHTS_CHAIN (RIGHTS_ps rights, RIGHTS_ps *clonedRights); extern void NSA_STD$DEREF_RIGHTS_CHAIN (RIGHTS_ps rights); extern void NSA_STD$FIND_RIGHTS_IDENTIFIER (RIGHTS_ps rights, int identifier, RIGHTS_ps *foundRights, int *foundIndex, RIGHTS_ps *freeRights); extern void NSA_STD$FREE_RIGHTS_CHAIN (RIGHTS_ps rights); extern int NSA_STD$GET_RIGHTS_BLOCK (int size, RIGHTS_ps *rights); extern void NSA_STD$REFERENCE_RIGHTS_CHAIN (RIGHTS_ps rights); extern int NSA_STD$REMOVE_RIGHTS_IDENT (RIGHTS_ps rights, int identifier, int *prevFlags, RIGHTS_ps *clonedRights); /* * Function prototypes for local functions */ static int get_curpsb (PSB_ps *u_psb, KTB *const u_ktb, const int u_acmode); #ifdef __NEW_STARLET #pragma inline (___internal___get_ps_prvmod) static int ___internal___get_ps_prvmod (void) { typedef union { PSLDEF fields; uint64 quad; } PS; PS ps; /* Read PS and return previous mode */ ps.quad = __PAL_RD_PS(); return (int) ps.fields.psl$v_prvmod; } #endif /* __NEW_STARLET */ #pragma inline (___memcpy_and_fill___) static void ___memcpy_and_fill___ (void *d, const int dSize, const void *s, const int sSize, const char f) { /* * First copy the data */ memcpy (d, s, $_$_$min$_$_$ (dSize, sSize)); /* * Now perform any needed fill */ if (dSize > sSize) { char *dc = (char *) d; memset (&dc[sSize], (int) f, (dSize - sSize)); } } #define ACMODE_PREVIOUS -1 #define CONTEXT_PERSONA 0 #define CONTEXT_PROCESS 1 #define ___success___(status) ((status & 0x1) == 1) #pragma inline (___setup_ktb___) static KTB * ___setup_ktb___(KTB *const u_ktb) { /* * If we didn't receive a ktb address as input then compute * our current ktb, otherwise use what was specified. */ if (u_ktb == (void *) 0) return get_curktb (); else return u_ktb; } #pragma inline (___setup_psb___) static int ___setup_psb___ (PSB_ps *psb, PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { int status; /* * If we didn't receive a psb address as input then compute * our current psb, otherwise use what was specified. */ if (u_psb == (void *) 0) { status = get_curpsb (psb, u_ktb, u_acmode); if (!___success___(status)) return status; } else *psb = u_psb; return SS$_NORMAL; } /*++ * D E S C R I P T I O N * ===================== * Audit control macros. These macros are used to temporarily disable * and enable security auditing for the current persona. The savedAudit * parameter can be used to capture the current audit state for later * restoration by the $RESTORE_AUDIT macro. These macros are usable * only from kernel mode. * * The following is the intended usage style for these macros: * * int savedAudit; * int status; * * status = $psb$disable_audit (&savedAudit, psb, ktb, acmode); * if (status) * { * ... * $psb$restore_audit (&savedAudit, psb, ktb, acmode); * } * else * persona assume error; * * N O T E S * ========= * These macros operate on the current persona. Failure to take * appropriate steps to localize this operation (such as first creating * a cloned persona) will result in leakage of the actions of this macro * to all other execution threads sharing this persona. * * Since these macros operate on the current persona, the most efficient * argument that can be supplied by a caller is the psb argument. * If the psb argument is omitted, then the next most efficient * argument is the ktb address. * * The acmode argument must be supplied if any lazy assume performed * by get_curpsb (used if psb is omitted) needs to be performed in the * context of a different mode other than the previous execution mode. * Specifying an access mode of ACMODE_PREVIOUS (-1) will cause the * previous mode to be fetched by the code. * * U S A G E * ========= * $psb$restore_audit Enable or restore NOAUDIT count * * savedAudit longword to restore current NOAUDIT value * psb optional PSB (default is current persona) * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * $psb$disable_audit Increment NOAUDIT count to disable audits * * savedAudit longword to store current NOAUDIT value * psb optional PSB (default is current persona) * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * $psb$enable_audit Decrement NOAUDIT count to enable audits * * savedAudit longword to store current NOAUDIT value * psb optional PSB (default is current persona) * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * If unknown, the psb and ktb arguments must be specified as NULL (0), and * the acmode argument must be specified as ACMODE_PREVIOUS (-1). *-- */ #pragma inline ($psb$restore_audit) static int $psb$restore_audit (int *u_savedAudit, PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { PCB *pcb; PSB_ps psb; KTB *ktb; int status; /* * Set up our ktb pointer (needed later to get pcb) */ ktb = ___setup_ktb___ (u_ktb); /* * Set up our psb pointer from user supplied information */ status = ___setup_psb___ (&psb, u_psb, u_ktb, u_acmode); if (!___success___(status)) return status; /* * The purpose of the following test is to allow only an enable * of auditing to take place if auditing is currently disabled, * and to allow a disable of auditing to take place anytime. */ if ((psb->psb$l_noaudit != 0) || (*u_savedAudit == -1)) { psb->psb$l_noaudit = psb->psb$l_noaudit - *u_savedAudit; *u_savedAudit = - *u_savedAudit; /* update pcb if it is the only user mode psb */ if ((ctl$gl_persona_usercount <= 1) && (psb->psb$l_mode == PSL$C_USER)) { /* * Pick up PCB address */ pcb = ktb->ktb$l_pcb; pcb->pcb$l_noaudit = psb->psb$l_noaudit; } } else *u_savedAudit = 0; return SS$_NORMAL; } #pragma inline ($psb$disable_audit) static int $psb$disable_audit (int *u_savedAudit, PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { PSB_ps psb; int status; /* * Set up our psb pointer from user supplied information */ status = ___setup_psb___ (&psb, u_psb, u_ktb, u_acmode); if (!___success___(status)) return status; /* Save direction for restoration */ *u_savedAudit = -1; /* Perform the modification to audit counter */ $psb$restore_audit (u_savedAudit, psb, 0, 0); return SS$_NORMAL; } #pragma inline ($psb$enable_audit) static int $psb$enable_audit (int *u_savedAudit, PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { PSB_ps psb; int status; /* * Set up our psb pointer from user supplied information */ status = ___setup_psb___ (&psb, u_psb, u_ktb, u_acmode); if (!___success___(status)) return status; /* Save direction for restoration */ *u_savedAudit = 1; /* Perform the modification to audit counter */ $psb$restore_audit (u_savedAudit, psb, 0, 0); return SS$_NORMAL; } /*++ * D E S C R I P T I O N * ===================== * Audit test macro. This macro is used to test the current state of * auditing for the current persona. Using this test for an invalid * persona is treated as if auditing were enabled. This macro is * usable only from kernel mode. * * The following is the intended usage style for this macro: * * if ($psb$audit_enabled (psb, ktb, acmode)) * { * ... * } * * N O T E S * ========= * These macros operate on the current persona. * * Since this macro operates on the current persona, the most efficient * argument that can be supplied by a caller is the psb argument. * If the psb argument is omitted, then the next most efficient * argument is the ktb address. * * The acmode argument must be supplied if any lazy assume performed * by get_curpsb (used if psb is omitted) needs to be performed in the * context of a different mode other than the previous execution mode. * Specifying an access mode of ACMODE_PREVIOUS (-1) will cause the * previous mode to be fetched by the code. * * U S A G E * ========= * $psb$audit_enabled Test for auditing enabled * * psb optional PSB (default is current persona) * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * If unknown, the psb and ktb arguments must be specified as NULL (0), and * the acmode argument must be specified as ACMODE_PREVIOUS (-1). *-- */ #pragma inline ($psb$audit_enabled) static int $psb$audit_enabled (PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { PSB_ps psb; int status; /* * Set up our psb pointer from user supplied information */ status = ___setup_psb___ (&psb, u_psb, u_ktb, u_acmode); if (!___success___(status)) return ___TRUE___; /* * Return the current state of auditing for this persona */ return (psb->psb$l_noaudit != 0); } /*++ * D E S C R I P T I O N * ===================== * Privilege control macros. These macros are used for temporary * enabling and disabling of privileges for the current persona. * These macros are usable only from kernel mode. * * The following is the intended usage style for these macros: * * PRVDEF savedPrivs; * PRVDEF privMask; * int status; * * status = $psb$enable_privileges (&privMask, &savedPrivs, psb, ktb, acmode); * if (status) * { * ... * $psb$restore_privileges (&savedPrivs, psb, ktb, acmode); * } * else * persona assume error; * * N O T E S * ========= * These macros operate on the current persona. Failure to take * appropriate steps to localize this operation (such as first creating * a cloned persona) will result in leakage of the actions of this macro * to all other execution threads sharing this persona. * * Since these macros operate on the current persona, the most efficient * argument that can be supplied by a caller is the psb argument. * If the psb argument is omitted, then the next most efficient * argument is the ktb address. * * The acmode argument must be supplied if any lazy assume performed * by get_curpsb (used if psb is omitted) needs to be performed in the * context of a different mode other than the previous execution mode. * Specifying an access mode of ACMODE_PREVIOUS (-1) will cause the * previous mode to be fetched by the code. * * The privMask argument is the address of a quadword privilege mask * containing bits to be enabled. * * The savedPriv argument is the address of a quadword in which to * save the current privilege bit settings for later restoration. * * U S A G E * ========= * $psb$enable_privileges Enable privileges * * privMask address of privileges mask * savedPriv address of quadword to store saved privileges * psb optional PSB (default is current persona) * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * $psb$restore_privileges Restore privileges * * savedPriv address of privileges being restored * psb optional PSB (default is current persona) * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * If unknown, the psb and ktb arguments must be specified as NULL (0), and * the acmode argument must be specified as ACMODE_PREVIOUS (-1). *-- */ #pragma inline ($psb$enable_privilege) static int $psb$enable_privilege (const PRVDEF *u_privMask, PRVDEF *savedPriv, PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { PSB_ps psb; PRVDEF *prv; int status; /* * Set up our psb pointer from user supplied information */ status = ___setup_psb___ (&psb, u_psb, u_ktb, u_acmode); if (!___success___(status)) return status; prv = &psb->psb$q_workpriv; /* * Save privs (if requested) */ if (savedPriv) *savedPriv = *prv; /* * Enable requested privs */ prv->prv$l_l1_bits |= u_privMask->prv$l_l1_bits; prv->prv$l_l2_bits |= u_privMask->prv$l_l2_bits; /* Export ARB if the current PSB is the only one in user node */ EXE$PERSONA_EXPORT_ARB (ISS$C_ARB_UNSPECIFIED); return SS$_NORMAL; } #pragma inline ($psb$restore_privilege) static int $psb$restore_privilege (const PRVDEF *u_savedPriv, PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { PSB_ps psb; PRVDEF *prv; int status; /* * Set up our psb pointer from user supplied information */ status = ___setup_psb___ (&psb, u_psb, u_ktb, u_acmode); if (!___success___(status)) return status; /* * Restore privilege mask */ prv = &psb->psb$q_workpriv; prv->prv$l_l1_bits = u_savedPriv->prv$l_l1_bits; prv->prv$l_l2_bits = u_savedPriv->prv$l_l2_bits; /* Export ARB if the current PSB is the only one in user node */ EXE$PERSONA_EXPORT_ARB (ISS$C_ARB_UNSPECIFIED); return SS$_NORMAL; } /*++ * D E S C R I P T I O N * ===================== * Privilege test macro. This macro is used to test the state of * privilege bits for the current persona. This macro is usable only * from kernel mode. * * This privilege testing macro does not perform auditing of the use * of privilege and should only be used in circumstances where an * audit would be inappropriate (which are few). * * If more than a single privilege bit is being tested, then this macro * will return TRUE if any of the privilege bits are enabled. * * The following is the intended usage style for this macro: * * PRVDEF privMask; * * if ($psb$privilege_enabled (&privMask, psb, ktb, acmode)) * { * ... * } * * N O T E S * ========= * These macros operate on the current persona. Failure to take * appropriate steps to localize this operation (such as first creating * a cloned persona) will result in leakage of the actions of this macro * to all other execution threads sharing this persona. * * Since these macros operate on the current persona, the most efficient * argument that can be supplied by a caller is the psb argument. * If the psb argument is omitted, then the next most efficient * argument is the ktb address. * * The acmode argument must be supplied if any lazy assume performed * by get_curpsb (used if psb is omitted) needs to be performed in the * context of a different mode other than the previous execution mode. * Specifying an access mode of ACMODE_PREVIOUS (-1) will cause the * previous mode to be fetched by the code. * * The privMask argument is the address of a quadword privilege mask * containing bits to be tested. * * U S A G E * ========= * $psb$privilege_enabled Privilege enabled test * * privMask address of privileges mask * psb optional PSB (default is current persona) * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * If unknown, the psb and ktb arguments must be specified as NULL (0), and * the acmode argument must be specified as ACMODE_PREVIOUS (-1). *-- */ #pragma inline ($psb$privilege_enabled) static int $psb$privilege_enabled (const PRVDEF *u_privMask, PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { PSB_ps psb; PRVDEF privs; PRVDEF *prv1; PRVDEF *prv2; int status; /* * Set up our psb pointer from user supplied information */ status = ___setup_psb___ (&psb, u_psb, u_ktb, u_acmode); if (!___success___(status)) return ___FALSE___; /* * Compute current active privileges */ prv1 = &psb->psb$q_workpriv; prv2 = &psb->psb$q_image_workpriv; privs.prv$l_l1_bits = prv1->prv$l_l1_bits | prv2->prv$l_l1_bits; privs.prv$l_l2_bits = prv1->prv$l_l2_bits | prv2->prv$l_l2_bits; /* * And requested privs against computed mask */ privs.prv$l_l1_bits &= u_privMask->prv$l_l1_bits; privs.prv$l_l2_bits &= u_privMask->prv$l_l2_bits; /* * If any bits are left in the mask then return true */ if ((privs.prv$l_l1_bits != 0) || (privs.prv$l_l2_bits != 0)) return ___TRUE___; else return ___FALSE___; } /*++ * Account access macros. This macro provides the ability to read * the account field of the persona block while hiding the overall * structure of the implementation. This macro is usable only from * kernel mode. * * The following is the intended usage style for this macro: * * char account [PSB$K_SIZE_ACCOUNT]; * * status = $psb$get_account (&account, sizeof(account), psb, ktb, acmode); * if (status) * { * ... * } * else * persona assume error; * * N O T E S * ========= * This macro operates on the current persona. * * Since this macro operates on the current persona, the most efficient * argument that can be supplied by a caller is the psb argument. * If the psb argument is omitted, then the next most efficient * argument is the ktb address. * * The acmode argument must be supplied if any lazy assume performed * by get_curpsb (used if psb is omitted) needs to be performed in the * context of a different mode other than the previous execution mode. * Specifying an access mode of ACMODE_PREVIOUS (-1) will cause the * previous mode to be fetched by the code. * * The account argument is the address of the buffer into which the * account string should be fetched. * * The size argument is the size of the account buffer. * * U S A G E * ========= * $PSB$GET_ACCOUNT Fetch account string * * account address of buffer to receive copy of account string * size size of buffer for account string * psb optional PSB (default is current persona) * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * If unknown, the psb and ktb arguments must be specified as NULL (0), and * the acmode argument must be specified as ACMODE_PREVIOUS (-1). *-- */ #pragma inline ($psb$get_account) static int $psb$get_account (char *u_account, const int size, PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { int i; PSB_ps psb; int status; /* * Set up our psb pointer from user supplied information */ status = ___setup_psb___ (&psb, u_psb, u_ktb, u_acmode); if (!___success___(status)) return status; /* * Copy the string into user's buffer */ ___memcpy_and_fill___ (u_account, size, &psb->psb$t_account, PSB$K_SIZE_ACCOUNT, ' '); return SS$_NORMAL; } /*++ * Account access macros. This macro provides the ability to write * the account field of the persona block while hiding the overall * structure of the implementation. This macro is usable only from * kernel mode. * * The following is the intended usage style for this macro: * * char account [PSB$K_SIZE_ACCOUNT]; * * status = $psb$set_account (&account, sizeof(account), context, psb, ktb, acmode); * if (status) * { * ... * } * else * persona assume error; * * N O T E S * ========= * This macro operates on the current persona. Failure to take * appropriate steps to localize this operation (such as first creating * a cloned persona) will result in leakage of the actions of this macro * to all other execution threads sharing this persona. * * Since this macro operates on the current persona, the most efficient * argument that can be supplied by a caller is the psb argument. * If the psb argument is omitted, then the next most efficient * argument is the ktb address. * * The acmode argument must be supplied if any lazy assume performed * by get_curpsb (used if psb is omitted) needs to be performed in the * context of a different mode other than the previous execution mode. * Specifying an access mode of ACMODE_PREVIOUS (-1) will cause the * previous mode to be fetched by the code. * * The account argument is the address of the buffer into which the * account string should be fetched. * * The size argument is the size of the account buffer. * * The context argument is an indication as to which fields should be * updated with the account string. If this argument is specified as * CONTEXT_PERSONA then only the persona block is updated; if specified * as CONTEXT_PROCESS then the JIB and CTL cells are updated in addition * to the persona block. * * U S A G E * ========= * $PSB$SET_ACCOUNT Set account string * * account address of buffer containing account string * size size of account string within the buffer * context context of operation (default is persona) * psb optional PSB (default is current persona) * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * If unknown, the psb and ktb arguments must be specified as NULL (0), and * the acmode argument must be specified as ACMODE_PREVIOUS (-1). *-- */ #pragma inline ($psb$set_account) static int $psb$set_account (const char *u_account, const int size, const int context, PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { int i; KTB *ktb; PSB_ps psb; int status; /* * If modifying process level data then make sure we know ktb and psb */ if (context == CONTEXT_PROCESS) { /* * Set up our ktb pointer (needed later to get jib) */ ktb = ___setup_ktb___ (u_ktb); /* * Set up our psb pointer from user supplied information (and ktb pointer) */ status = ___setup_psb___ (&psb, u_psb, ktb, u_acmode); if (!___success___(status)) return status; } /* * Otherwise just set up psb pointer */ else { /* * Set up our psb pointer from user supplied information */ status = ___setup_psb___ (&psb, u_psb, u_ktb, u_acmode); if (!___success___(status)) return status; } /* * Copy the string into the PSB */ ___memcpy_and_fill___ (&psb->psb$t_account, PSB$K_SIZE_ACCOUNT, u_account, size, ' '); /* * Performing modification for entire process? */ if (context == CONTEXT_PROCESS) { JIB *jib; extern char ctl$t_account [JIB$K_SIZE_ACCOUNT]; /* * Pick up current JIB address */ jib = ktb->ktb$l_jib; /* * Copy the string into the JIB */ ___memcpy_and_fill___ (&jib->jib$t_account, JIB$K_SIZE_ACCOUNT, &psb->psb$t_account, PSB$K_SIZE_ACCOUNT, ' '); /* * Copy the string into the CTL region */ ___memcpy_and_fill___ (ctl$t_account, JIB$K_SIZE_ACCOUNT, &psb->psb$t_account, PSB$K_SIZE_ACCOUNT, ' '); } return SS$_NORMAL; } /*++ * Username access macros. This macro provides the ability to read * the username field of the persona block while hiding the overall * structure of the implementation. This macro is usable only from * kernel mode. * * The following is the intended usage style for this macro: * * char username [PSB$K_SIZE_USERNAME]; * * status = $psb$get_username (&username, sizeof(username), psb, ktb, acmode); * if (status) * { * ... * } * else * persona assume error; * * N O T E S * ========= * This macro operates on the current persona. * * Since this macro operates on the current persona, the most efficient * argument that can be supplied by a caller is the psb argument. * If the psb argument is omitted, then the next most efficient * argument is the ktb address. * * The acmode argument must be supplied if any lazy assume performed * by get_curpsb (used if psb is omitted) needs to be performed in the * context of a different mode other than the previous execution mode. * Specifying an access mode of ACMODE_PREVIOUS (-1) will cause the * previous mode to be fetched by the code. * * The username argument is the address of the buffer into which the * username string should be fetched. * * The size argument is the size of the username buffer. * * U S A G E * ========= * $PSB$GET_USERNAME Fetch username string * * username address of buffer to receive copy of username string * size size of buffer for username string * psb optional PSB (default is current persona) * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * If unknown, the psb and ktb arguments must be specified as NULL (0), and * the acmode argument must be specified as ACMODE_PREVIOUS (-1). *-- */ #pragma inline ($psb$get_username) static int $psb$get_username (char *u_username, const int size, PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { int i; PSB_ps psb; int status; /* * Set up our psb pointer from user supplied information */ status = ___setup_psb___ (&psb, u_psb, u_ktb, u_acmode); if (!___success___(status)) return status; /* * Copy the string into user's buffer */ ___memcpy_and_fill___ (u_username, size, &psb->psb$t_username, PSB$K_SIZE_USERNAME, ' '); return SS$_NORMAL; } /*++ * Username access macros. This macro provides the ability to write * the username field of the persona block while hiding the overall * structure of the implementation. This macro is usable only from * kernel mode. * * The following is the intended usage style for this macro: * * char username [PSB$K_SIZE_USERNAME]; * * status = $psb$set_username (&username, sizeof(username), psb, ktb, acmode); * if (status) * { * ... * } * else * persona assume error; * * N O T E S * ========= * This macro operates on the current persona. Failure to take * appropriate steps to localize this operation (such as first creating * a cloned persona) will result in leakage of the actions of this macro * to all other execution threads sharing this persona. * * Since this macro operates on the current persona, the most efficient * argument that can be supplied by a caller is the psb argument. * If the psb argument is omitted, then the next most efficient * argument is the ktb address. * * The acmode argument must be supplied if any lazy assume performed * by get_curpsb (used if psb is omitted) needs to be performed in the * context of a different mode other than the previous execution mode. * Specifying an access mode of ACMODE_PREVIOUS (-1) will cause the * previous mode to be fetched by the code. * * The username argument is the address of the buffer into which the * username string should be fetched. * * The size argument is the size of the username buffer. * * The context argument is an indication as to which fields should be * updated with the username string. If this argument is specified as * CONTEXT_PERSONA then only the persona block is updated; if specified * as CONTEXT_PROCESS then the JIB and CTL cells are updated in addition * to the persona block. * * U S A G E * ========= * $PSB$SET_USERNAME Set username string * * username address of buffer containing username string * size size of username string within the buffer * context context of operation (default is persona) * psb optional PSB (default is current persona) * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * If unknown, the psb and ktb arguments must be specified as NULL (0), and * the acmode argument must be specified as ACMODE_PREVIOUS (-1). *-- */ #pragma inline ($psb$set_username) static int $psb$set_username (const char *u_username, const int size, const int context, PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { int i; KTB *ktb; PSB_ps psb; int status; /* * If modifying process level data then make sure we know ktb and psb */ if (context == CONTEXT_PROCESS) { /* * Set up our ktb pointer (needed later to get jib) */ ktb = ___setup_ktb___ (u_ktb); /* * Set up our psb pointer from user supplied information (and ktb pointer) */ status = ___setup_psb___ (&psb, u_psb, ktb, u_acmode); if (!___success___(status)) return status; } /* * Otherwise just set up psb pointer */ else { /* * Set up our psb pointer from user supplied information */ status = ___setup_psb___ (&psb, u_psb, u_ktb, u_acmode); if (!___success___(status)) return status; } /* * Copy the string into the PSB */ ___memcpy_and_fill___ (&psb->psb$t_username, PSB$K_SIZE_USERNAME, u_username, size, ' '); /* * Performing modification for entire process? */ if (context == CONTEXT_PROCESS) { JIB *jib; extern char ctl$t_username [JIB$K_SIZE_USERNAME]; /* * Pick up current JIB address */ jib = ktb->ktb$l_jib; /* * Copy the string into the JIB */ ___memcpy_and_fill___ (&jib->jib$t_username, JIB$K_SIZE_USERNAME, &psb->psb$t_username, PSB$K_SIZE_USERNAME, ' '); /* * Copy the string into the CTL region */ ___memcpy_and_fill___ (ctl$t_username, JIB$K_SIZE_USERNAME, &psb->psb$t_username, PSB$K_SIZE_USERNAME, ' '); } return SS$_NORMAL; } /*++ * Privs access macros. This macro provides the ability to read * the current privs of the persona block while hiding the overall * structure of the implementation. This macro is usable only from * kernel mode. * * The following is the intended usage style for this macro: * * PRVDEF privMask; * int status; * * status = $psb$get_privs (&privMask, psb, ktb, acmode); * if (status) * { * ... * } * else * persona assume error; * * N O T E S * ========= * This macro operates on the current persona. * * Since this macro operates on the current persona, the most efficient * argument that can be supplied by a caller is the psb argument. * If the psb argument is omitted, then the next most efficient * argument is the ktb address. * * The acmode argument must be supplied if any lazy assume performed * by get_curpsb (used if psb is omitted) needs to be performed in the * context of a different mode other than the previous execution mode. * Specifying an access mode of ACMODE_PREVIOUS (-1) will cause the * previous mode to be fetched by the code. * * The privMask argument is the address of a quadword into which the * privileges mask should be fetched. * * U S A G E * ========= * $psb$get_privs Fetch privileges * * privMask address of quadword to receive privileges mask * psb optional PSB (default is current persona) * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * If unknown, the psb and ktb arguments must be specified as NULL (0), and * the acmode argument must be specified as ACMODE_PREVIOUS (-1). *-- */ #pragma inline ($psb$get_privs) static int $psb$get_privs (PRVDEF *u_privMask, PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { PSB_ps psb; PRVDEF *prv1; PRVDEF *prv2; int status; /* * Set up our psb pointer from user supplied information */ status = ___setup_psb___ (&psb, u_psb, u_ktb, u_acmode); if (!___success___(status)) return status; /* * Calculate our privs to return */ prv1 = &psb->psb$q_workpriv; prv2 = &psb->psb$q_image_workpriv; u_privMask->prv$l_l1_bits = prv1->prv$l_l1_bits | prv2->prv$l_l1_bits; u_privMask->prv$l_l2_bits = prv1->prv$l_l2_bits | prv2->prv$l_l2_bits; return SS$_NORMAL; } /*++ * UIC access macros. This macro provides the ability to read * the UIC field of the persona block while hiding the overall * structure of the implementation. This macro is usable only * from kernel mode. * * The following is the intended usage style for this macro: * * int uic; * * status = $psb$get_uic (&uic, psb, ktb, acmode); * if (status) * { * ... * } * else * persona assume error; * * N O T E S * ========= * This macro operates on the current persona. * * Since this macro operates on the current persona, the most efficient * argument that can be supplied by a caller is the psb argument. * If the psb argument is omitted, then the next most efficient * argument is the ktb address. * * The acmode argument must be supplied if any lazy assume performed * by get_curpsb (used if psb is omitted) needs to be performed in the * context of a different mode other than the previous execution mode. * Specifying an access mode of ACMODE_PREVIOUS (-1) will cause the * previous mode to be fetched by the code. * * The uic argument is the address of a longword into which the uic * is stored. * * U S A G E * ========= * $psb$get_uic Fetch uic * * uic address of longword to receive the uic * psb optional PSB (default is current persona) * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * If unknown, the psb and ktb arguments must be specified as NULL (0), and * the acmode argument must be specified as ACMODE_PREVIOUS (-1). *-- */ #pragma inline ($psb$get_uic) static int $psb$get_uic (int *u_uic, PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { PSB_ps psb; int status; /* * Set up our psb pointer from user supplied information */ status = ___setup_psb___ (&psb, u_psb, u_ktb, u_acmode); if (!___success___(status)) return status; /* * Pick up uic from persona block */ *u_uic = psb->psb$l_uic; return SS$_NORMAL; } /*++ * UIC access macros. This macro provides the ability to write * the UIC field of the persona block while hiding the overall * structure of the implementation. This macro is usable only * from kernel mode. * * The following is the intended usage style for this macro: * * int uic; * * status = $psb$set_uic (uic, psb, ktb, acmode); * if (status) * { * ... * } * else * persona assume error; * * N O T E S * ========= * This macro operates on the current persona. * * Since this macro operates on the current persona, the most efficient * argument that can be supplied by a caller is the psb argument. * If the psb argument is omitted, then the next most efficient * argument is the ktb address. * * The acmode argument must be supplied if any lazy assume performed * by get_curpsb (used if psb is omitted) needs to be performed in the * context of a different mode other than the previous execution mode. * Specifying an access mode of ACMODE_PREVIOUS (-1) will cause the * previous mode to be fetched by the code. * * The uic argument is the address of a longword which contains the uic * to be set. * * U S A G E * ========= * $psb$set_uic Set uic * * uic address of longword containing the uic * psb optional PSB (default is current persona) * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * If unknown, the psb and ktb arguments must be specified as NULL (0), and * the acmode argument must be specified as ACMODE_PREVIOUS (-1). *-- */ #pragma inline ($psb$set_uic) static int $psb$set_uic (const int u_uic, PSB_ps const u_psb, KTB *const u_ktb, const int u_acmode) { PSB_ps psb; int status; /* * Set up our psb pointer from user supplied information */ status = ___setup_psb___ (&psb, u_psb, u_ktb, u_acmode); if (!___success___(status)) return status; /* * Store uic in persona block */ psb->psb$l_uic = u_uic; /* Export ARB if the current PSB is the only one in user node */ EXE$PERSONA_EXPORT_ARB (ISS$C_ARB_UNSPECIFIED); return SS$_NORMAL; } /*++ * Macro to get address of current persona block. This macro handles * the need to perform a lazy persona assume if the persona id in the * per-thread kernel area indicates an implicit persona context switch. * The value returned by the macro is an indication of a successful or * failed attempt to assume a persona. The invoker of this macro must * be in kernel mode. * * The following is the intended usage style for this macro: * * PSB *psb; * int status; * * status = get_curpsb (&psb, ktb, acmode); * if (status) * { * ...; * } * else * persona assume error; * * N O T E S * ========= * The psb argument is the address of a location into which the current * persona's persona block address will be written. * * If known, the ktb address should be supplied. Otherwise the macro * generates code to determine the current thread's ktb address. * * The acmode argument must be supplied if any lazy assume performed * by get_curpsb (used if psb is omitted) needs to be performed in the * context of a different mode other than the previous execution mode. * Specifying an access mode of ACMODE_PREVIOUS (-1) will cause the * previous mode to be fetched by the code. * * U S A G E * ========= * get_curpsb Get current psb * * psb address of longword to receive persona block address * ktb optional KTB (default is current kernel thread) * acmode optional access mode for lazy assume (default is PREVIOUS) * * If unknown, the ktb argument must be specified as NULL (0), and * the acmode argument must be specified as ACMODE_PREVIOUS (-1). *-- */ #pragma inline (get_curpsb) static int get_curpsb (PSB_ps *u_psb, KTB *const u_ktb, const int u_acmode) { /* * If we didn't receive a ktb address as input then pass 0, * otherwise use what was specified. */ if (u_ktb == (void *) 0) return NSA_STD$GET_CURRENT_PSB(0, u_psb ); else return NSA_STD$GET_CURRENT_PSB(u_ktb, u_psb ); } #ifdef __INITIAL_POINTER_SIZE #pragma __required_pointer_size __restore #endif #endif /* __SECURITY_MACROS_LOADED */ #if 0 $has_priv (priv, prvmsk, mask = current, message, msgcod, itmlst, altprv, flags, acmode = unknown) = #endif