/* * ************************************************************************** ** * ** Copyright 2010 Hewlett-Packard Development Company, L.P. * ** * ** Confidential computer software. Valid license from HP and/or * ** its subsidiaries required for possession, use, or copying. * ** * ** Consistent with FAR 12.211 and 12.212, Commercial Computer Software, * ** Computer Software Documentation, and Technical Data for Commercial * ** Items are licensed to the U.S. Government under vendor's standard * ** commercial license. * ** * ** Neither HP nor any of its subsidiaries shall be liable for technical * ** or editorial errors or omissions contained herein. The information * ** in this document is provided "as is" without warranty of any kind and * ** is subject to change without notice. The warranties for HP products * ** are set forth in the express limited warranty statements accompanying * ** such products. Nothing herein should be construed as constituting an * ** additional warranty. * ** * ************************************************************************** * */ /* ** P1_EXT.C: Persona Extension Example 1 ** ** Author: Takaaki Shinagawa (takaaki.shinagawa@hp.com) ** ** Revision 1.0 Prasad SG 11-Feb-2010 ** - Changed Copyright to HP ** - Modified the persona structure (PXB_P1 and P1_CREDENT) ** to store the length of different fields. ** - Modified the p1_ext_create() to store the lengths ** obtained from structure P1_CREDENT to PXB_P1 ** - Changed logic in p1_ext_query(), to return ** correct query results in buf_addr ** */ #define __NEW_STARLET 1 #include #include #include #include #include #include #include #include #include #include #include #define P1_USERNAME_SIZE 32 #define P1_ACCOUNT_NAME_SIZE 32 #define P1_DOMAIN_NAME_SIZE 32 #define P1_DOI_NAME_SIZE 8 #define P1_PRINCIPAL_NAME_SIZE 32 #define P1_EXTENSION_NAME_SIZE 16 typedef struct pxb_p1 { struct pxb_p1 *pxb_p1$l_flink; struct pxb_p1 *pxb_p1$l_blink; unsigned short int pxb_p1$w_size; unsigned char pxb_p1$b_type; unsigned char pxb_p1$b_subtype; char pxb_p1$username[P1_USERNAME_SIZE]; /* USERNAME */ char pxb_p1$account[P1_ACCOUNT_NAME_SIZE]; /* ACCOUNT */ int pxb_p1$flags; /* FLAGS */ char pxb_p1$domain[P1_DOMAIN_NAME_SIZE]; /* DOMAIN */ char pxb_p1$doi[P1_DOI_NAME_SIZE]; /* DOI */ char pxb_p1$principal[P1_PRINCIPAL_NAME_SIZE]; /* PRINCIPAL */ char pxb_p1$extension[P1_EXTENSION_NAME_SIZE]; /* EXTENSION */ unsigned short pxb_p1$username_length; unsigned short pxb_p1$account_length; unsigned short pxb_p1$domain_length; unsigned short pxb_p1$doi_length; unsigned short pxb_p1$principal_length; unsigned short pxb_p1$extension_length; } PXB_P1; #define PXB_P1_SIZE sizeof(PXB_P1) typedef struct p1_credential { char pxb_p1$username[P1_USERNAME_SIZE]; /* USERNAME */ char pxb_p1$account[P1_ACCOUNT_NAME_SIZE]; /* ACCOUNT */ char pxb_p1$domain[P1_DOMAIN_NAME_SIZE]; /* DOMAIN */ char pxb_p1$doi[P1_DOI_NAME_SIZE]; /* DOI */ char pxb_p1$principal[P1_PRINCIPAL_NAME_SIZE]; /* PRINCIPAL */ char pxb_p1$extension[P1_EXTENSION_NAME_SIZE]; /* EXTENSION */ unsigned short pxb_p1$username_length; unsigned short pxb_p1$account_length; unsigned short pxb_p1$domain_length; unsigned short pxb_p1$doi_length; unsigned short pxb_p1$principal_length; unsigned short pxb_p1$extension_length; } P1_CREDENT; #define P1_CREDENT_SIZE sizeof(P1_CREDENT) /* ** QUERY & COMPARE are for queryflg of the query routine ** (It seems this flag's default value is 0 (QUERY)) */ #define QUERY 0 #define COMPARE 1 #define TRUE 1 #define FALSE 0 /* ** Declearing prototypes of entry points */ int p1_ext_create ( PSB *psb, PXB **pxb, P1_CREDENT *credential, unsigned int credential_size ); int p1_ext_clone ( PSB *psb, PXB *pxb, PXB **new_pxb ); int p1_ext_delegate ( PSB *psb, PXB *pxb, int unused, PXB **new_pxb, PSB *new_psb ); int p1_ext_delete ( PSB *psb, PXB *pxb ); int p1_ext_modify ( PSB *psb, PXB *pxb, int itemcode, char *buf_addr, int buf_len ); int p1_ext_query ( PSB *psb, PXB *pxb, int itemcode, char *buf_addr, int buf_len, int *ret_len, int queryflg, /* 0 by default and is not used */ struct dsc$descriptor_s *dsc ); int p1_ext_make_tlv ( PSB *psb, PXB *pxb, int itemcode, char *buf_addr, int buf_len, int *ret_len, int flags /* for future use */ ); extern int nsa$register_psb_extension(); /*====================================================================================*/ /* ** Initialize (calling NSA$REGISTER_PSB_EXTENSION) */ int p1_ext_initialize () { int status; PXDV p1_pxdv; $DESCRIPTOR (p1_desc, "P1"); p1_pxdv.pxdv$l_version = PXDV$K_VERSION; p1_pxdv.pxdv$a_create = (void *) p1_ext_create; /* required */ /* ** Setting unsupported functions will crash process/system ** If the function is not supported, just set 0 */ p1_pxdv.pxdv$a_clone = (void *) p1_ext_clone; /* optional */ p1_pxdv.pxdv$a_delegate = (void *) 0; /* optional */ p1_pxdv.pxdv$a_delete = (void *) p1_ext_delete; /* required */ p1_pxdv.pxdv$a_modify = (void *) p1_ext_modify; /* required */ p1_pxdv.pxdv$a_query = (void *) p1_ext_query; /* required */ p1_pxdv.pxdv$a_make_tlv = (void *) p1_ext_make_tlv; /* required */ status = nsa$register_psb_extension(&p1_desc, &p1_pxdv); return status ; } /* ** Create Routine (mandatory) */ int p1_ext_create ( PSB *psb, PXB **pxb, P1_CREDENT *credential, unsigned int credential_size ) { int status; PXB_P1 *pxb_p1_p; int alloc_size; /*----------------------------------------------------------------------*/ if (credential == NULL) return SS$_NODATA; /* ** Allocate a PXB (Persona Extension Block) in Non-Paged Pool */ status = exe_std$alononpaged(PXB_P1_SIZE, (__int32*) &alloc_size, (void*) &pxb_p1_p); if(status != SS$_NORMAL) { /* Allocation failed */ return status; } memset(pxb_p1_p, 0, alloc_size); /* Set values in P1_PXB */ pxb_p1_p->pxb_p1$w_size = alloc_size; pxb_p1_p->pxb_p1$b_type = DYN$C_SECURITY; pxb_p1_p->pxb_p1$b_subtype = DYN$C_SECURITY_PXB_GENERIC; /* this code is for extensions other than NT extension */ /* ** USERNAME */ if (credential->pxb_p1$username != NULL && credential->pxb_p1$username_length <= P1_USERNAME_SIZE) { strncpy (pxb_p1_p->pxb_p1$username, credential->pxb_p1$username, P1_USERNAME_SIZE); pxb_p1_p->pxb_p1$username_length = credential->pxb_p1$username_length; } /* ** ACCOUNT */ if (credential->pxb_p1$account != NULL && credential->pxb_p1$account_length <= P1_ACCOUNT_NAME_SIZE) { strncpy (pxb_p1_p->pxb_p1$account, credential->pxb_p1$account, P1_ACCOUNT_NAME_SIZE); pxb_p1_p->pxb_p1$account_length = credential->pxb_p1$account_length; } /* ** DOMAIN */ if (credential->pxb_p1$domain != NULL && credential->pxb_p1$domain_length <= P1_DOMAIN_NAME_SIZE) { strncpy (pxb_p1_p->pxb_p1$domain, credential->pxb_p1$domain, P1_DOMAIN_NAME_SIZE); pxb_p1_p->pxb_p1$domain_length = credential->pxb_p1$domain_length; } /* ** DOI */ if (credential->pxb_p1$doi != NULL && credential->pxb_p1$doi_length <= P1_DOI_NAME_SIZE) { memcpy (pxb_p1_p->pxb_p1$doi, credential->pxb_p1$doi, P1_DOI_NAME_SIZE); pxb_p1_p->pxb_p1$doi_length = credential->pxb_p1$doi_length; } /* ** PRINCIPAL */ if (credential->pxb_p1$principal != NULL && credential->pxb_p1$principal_length <= P1_PRINCIPAL_NAME_SIZE) { strncpy (pxb_p1_p->pxb_p1$principal, credential->pxb_p1$principal, P1_PRINCIPAL_NAME_SIZE); pxb_p1_p->pxb_p1$principal_length = credential->pxb_p1$principal_length; } /* ** EXTENSION */ if (credential->pxb_p1$extension != NULL && credential->pxb_p1$extension_length <= P1_EXTENSION_NAME_SIZE) { strncpy (pxb_p1_p->pxb_p1$extension, credential->pxb_p1$extension, P1_EXTENSION_NAME_SIZE); pxb_p1_p->pxb_p1$extension_length = credential->pxb_p1$extension_length; } *pxb = (struct _pxb*) pxb_p1_p; return SS$_NORMAL; } /* ** Clone Routine (optional) */ int p1_ext_clone ( PSB *psb, PXB *pxb, PXB **new_pxb ) { int status; PXB_P1 *pxb_p1_p; int alloc_size; /*----------------------------------------------------------------------*/ if ((psb == NULL) || (pxb == NULL) ) return SS$_BADPARAM; /* ** Allocate a PXB (Persona Extension Block) in Non-Paged Pool */ status = exe_std$alononpaged(PXB_P1_SIZE, (__int32*) &alloc_size, (void*) &pxb_p1_p); if(status != SS$_NORMAL) { /* Allocation failed */ return status; } memset(pxb_p1_p, 0, alloc_size); /* Copy contents of PXB into P1_PXB */ memcpy(pxb_p1_p, pxb, PXB_P1_SIZE); *new_pxb = (struct _pxb*) pxb_p1_p; return SS$_NORMAL; } /* ** Delegate Routine (optional) */ int p1_ext_delegate ( PSB *psb, PXB *pxb, int unused, PXB **new_pxb, PSB *new_psb ) { return SS$_UNSUPPORTED; } /* ** Delete Routine (mandatory) */ int p1_ext_delete ( PSB *psb, PXB *pxb ) { int status = SS$_NORMAL; if ((psb == NULL) || (pxb == NULL)) status = SS$_BADPARAM; else { exe_std$deanonpaged((void *)pxb); /* deallocate PXB */ } return status; } /* ** Modify Routine (mandatory) ** *** This routine is not fully implemented at this point *** */ int p1_ext_modify ( PSB *psb, PXB *pxb, int itemcode, char *buf_addr, int buf_len ) { int status = SS$_NORMAL; PXB_P1 *pxb_p1_p; if ((psb == NULL) || (pxb == NULL)) return SS$_BADPARAM; else pxb_p1_p = (struct pxb_p1*) pxb; /* ** The following part is a skelton-- it will be implemented ** by the SSB release */ switch (itemcode) { case ISS$_USERNAME: case ISS$_ACCOUNT: case ISS$_UIC: case ISS$_EXTENSION: case ISS$_DOI: case ISS$_COMMON_PRINCIPAL: case ISS$_DOMAIN: case ISS$_COMMON_USERNAME: default: status = SS$_BADITMCOD; } return status; } /* ** Query Routine (mandatory) */ int p1_ext_query ( PSB *psb, PXB *pxb, int itemcode, char *buf_addr, int buf_len, int *ret_len, int queryflg, /* Where does this flag come from? It seems 0 by default and is not used */ struct dsc$descriptor_s *dsc ) { int status = SS$_NORMAL; int ret; PXB_P1 *pxb_p1_p; char* srcBuffer=NULL; unsigned short srcBufferLength; pxb_p1_p = (struct pxb_p1*) pxb; switch (itemcode) { case ISS$_COMMON_FLAGS: if (psb) srcBuffer = (char*) &(psb->psb$l_flags); srcBufferLength = sizeof(psb->psb$l_flags); break; case ISS$_DOI: srcBuffer = (char*) pxb_p1_p->pxb_p1$doi; srcBufferLength = pxb_p1_p->pxb_p1$doi_length; break; case ISS$_COMMON_PRINCIPAL: srcBuffer = (char*) pxb_p1_p->pxb_p1$principal; srcBufferLength = pxb_p1_p->pxb_p1$principal_length; break; case ISS$_COMMON_USERNAME: srcBuffer = (char*) pxb_p1_p->pxb_p1$username; srcBufferLength = pxb_p1_p->pxb_p1$username_length; break; case ISS$_DOMAIN: srcBuffer = (char*) pxb_p1_p->pxb_p1$domain; srcBufferLength = pxb_p1_p->pxb_p1$domain_length; break; case ISS$_COMMON_ACCOUNT: srcBuffer = (char*) pxb_p1_p->pxb_p1$account; srcBufferLength = pxb_p1_p->pxb_p1$account_length; break; case ISS$_EXTENSION: srcBuffer = (char*) pxb_p1_p->pxb_p1$extension; srcBufferLength = pxb_p1_p->pxb_p1$extension_length; break; default: return SS$_BADITMCOD; } if (queryflg == COMPARE) { /* ** compare buffer */ if (memcmp(buf_addr, srcBuffer, srcBufferLength) != 0) status = FALSE; else status = TRUE; } else { /* Set the size of length required. */ if (ret_len != 0) { *ret_len = srcBufferLength; } /* Is there no space to copy the to buf_addr. */ if (buf_len == 0 || NULL == buf_addr || srcBuffer == NULL) { if (ret_len != 0) { /* This is a first time call by caller, to know ** how much size needs to get allocated in buf_addr. ** reutnr a Normal. */ status = SS$_NORMAL; } else { status = SS$_BADBUFLEN; } } else if (buf_len >= srcBufferLength) { /* Copy to buffer */ strncpy (buf_addr, srcBuffer, srcBufferLength); status = SS$_NORMAL; } else { status = SS$_BADBUFLEN; } } return status; } /* ** Make_TLV Routine (mandatory) */ int p1_ext_make_tlv ( PSB *psb, PXB *pxb, int itemcode, char *buf_addr, int buf_len, int *ret_len, int flags /* for future use */ ) { return SS$_UNSUPPORTED; } /* ** The following lines must be included at the end of the persona extension code ** (Don't move them to the beginning) */ #define INIT001_ROUTINE p1_ext_initialize #include